2021-04-16 04:34:29 +00:00
|
|
|
|
import GraphQL from 'graphql';
|
|
|
|
|
|
import GraphQLRelay from 'graphql-relay';
|
|
|
|
|
|
import { MBID } from './scalars.js';
|
|
|
|
|
|
import { ReleaseGroupType, ReleaseStatus } from './enums.js';
|
|
|
|
|
|
import { resolveLinked } from '../resolvers.js';
|
|
|
|
|
|
import { toDashed, toPascal, toSingular, toPlural, toWords } from '../util.js';
|
|
|
|
|
|
|
|
|
|
|
|
const { GraphQLString, GraphQLInt, GraphQLList, GraphQLNonNull } = GraphQL;
|
|
|
|
|
|
const {
|
2016-09-01 08:39:27 +00:00
|
|
|
|
globalIdField,
|
2016-11-28 13:49:04 +00:00
|
|
|
|
connectionDefinitions,
|
2021-04-16 04:34:29 +00:00
|
|
|
|
forwardConnectionArgs,
|
|
|
|
|
|
} = GraphQLRelay;
|
2016-08-20 05:59:32 +00:00
|
|
|
|
|
2021-04-16 04:34:29 +00:00
|
|
|
|
const TYPE_NAMES = {
|
|
|
|
|
|
discid: 'Disc',
|
|
|
|
|
|
url: 'URL',
|
|
|
|
|
|
};
|
2016-11-26 01:38:32 +00:00
|
|
|
|
|
2021-04-16 04:34:29 +00:00
|
|
|
|
export function resolveType(value, context, info) {
|
|
|
|
|
|
const typeName = TYPE_NAMES[value._type] || toPascal(value._type);
|
|
|
|
|
|
const typeMap = info.schema.getTypeMap();
|
|
|
|
|
|
return typeMap[typeName];
|
2016-11-26 01:38:32 +00:00
|
|
|
|
}
|
2016-08-31 06:33:29 +00:00
|
|
|
|
|
2017-11-07 05:54:56 +00:00
|
|
|
|
export function resolveHyphenated(obj, args, context, info) {
|
2021-04-16 04:34:29 +00:00
|
|
|
|
const name = toDashed(info.fieldName);
|
|
|
|
|
|
return obj[name];
|
2016-12-11 20:32:58 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
2017-11-07 05:54:56 +00:00
|
|
|
|
export function resolveWithFallback(keys) {
|
2021-04-16 04:34:29 +00:00
|
|
|
|
return (obj) => {
|
2016-12-11 20:32:58 +00:00
|
|
|
|
for (let i = 0; i < keys.length; i++) {
|
2021-04-16 04:34:29 +00:00
|
|
|
|
const key = keys[i];
|
2016-12-11 20:32:58 +00:00
|
|
|
|
if (key in obj) {
|
2021-04-16 04:34:29 +00:00
|
|
|
|
return obj[key];
|
2016-12-11 20:32:58 +00:00
|
|
|
|
}
|
|
|
|
|
|
}
|
2021-04-16 04:34:29 +00:00
|
|
|
|
};
|
2016-12-11 20:32:58 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
2017-11-07 05:54:56 +00:00
|
|
|
|
export function fieldWithID(name, config = {}) {
|
2016-08-08 07:54:06 +00:00
|
|
|
|
config = {
|
|
|
|
|
|
type: GraphQLString,
|
2016-12-02 08:21:10 +00:00
|
|
|
|
resolve: resolveHyphenated,
|
2021-04-16 04:34:29 +00:00
|
|
|
|
...config,
|
|
|
|
|
|
};
|
|
|
|
|
|
const isPlural = config.type instanceof GraphQLList;
|
|
|
|
|
|
const singularName = isPlural ? toSingular(name) : name;
|
|
|
|
|
|
const idName = isPlural ? `${singularName}IDs` : `${name}ID`;
|
|
|
|
|
|
const s = isPlural ? 's' : '';
|
2016-08-08 07:54:06 +00:00
|
|
|
|
const idConfig = {
|
|
|
|
|
|
type: isPlural ? new GraphQLList(MBID) : MBID,
|
2016-11-26 10:37:23 +00:00
|
|
|
|
description: `The MBID${s} associated with the value${s} of the \`${name}\`
|
|
|
|
|
|
field.`,
|
2017-11-04 22:32:05 +00:00
|
|
|
|
resolve: (entity, args, { loaders }) => {
|
2021-04-16 04:34:29 +00:00
|
|
|
|
const fieldName = toDashed(idName);
|
2017-11-04 22:32:05 +00:00
|
|
|
|
if (fieldName in entity) {
|
2021-04-16 04:34:29 +00:00
|
|
|
|
return entity[fieldName];
|
2017-11-04 22:32:05 +00:00
|
|
|
|
}
|
2017-11-07 05:54:56 +00:00
|
|
|
|
return loaders.lookup
|
|
|
|
|
|
.load([entity._type, entity.id])
|
2021-04-16 04:34:29 +00:00
|
|
|
|
.then((data) => data[fieldName]);
|
|
|
|
|
|
},
|
|
|
|
|
|
};
|
2016-08-08 07:54:06 +00:00
|
|
|
|
return {
|
|
|
|
|
|
[name]: config,
|
2021-04-16 04:34:29 +00:00
|
|
|
|
[idName]: idConfig,
|
|
|
|
|
|
};
|
2016-08-08 07:54:06 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
2017-11-07 05:54:56 +00:00
|
|
|
|
export function createCollectionField(config) {
|
2021-04-16 04:34:29 +00:00
|
|
|
|
const typeName = toPlural(toWords(config.type.name.slice(0, -10)));
|
2016-12-15 07:18:53 +00:00
|
|
|
|
return {
|
|
|
|
|
|
...config,
|
2021-04-16 04:34:29 +00:00
|
|
|
|
description: `The list of ${typeName} found in this collection.`,
|
|
|
|
|
|
};
|
2016-12-15 07:18:53 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
2021-04-16 04:34:29 +00:00
|
|
|
|
export const id = globalIdField();
|
2016-09-01 04:31:48 +00:00
|
|
|
|
export const mbid = {
|
|
|
|
|
|
type: new GraphQLNonNull(MBID),
|
2016-09-01 08:39:27 +00:00
|
|
|
|
description: 'The MBID of the entity.',
|
2021-04-16 04:34:29 +00:00
|
|
|
|
resolve: (entity) => entity.id,
|
|
|
|
|
|
};
|
2016-11-26 01:38:32 +00:00
|
|
|
|
export const name = {
|
|
|
|
|
|
type: GraphQLString,
|
2021-04-16 04:34:29 +00:00
|
|
|
|
description: 'The official name of the entity.',
|
|
|
|
|
|
};
|
2016-11-26 01:38:32 +00:00
|
|
|
|
export const sortName = {
|
|
|
|
|
|
type: GraphQLString,
|
|
|
|
|
|
description: `The string to use for the purpose of ordering by name (for
|
|
|
|
|
|
example, by moving articles like ‘the’ to the end or a person’s last name to
|
|
|
|
|
|
the front).`,
|
2021-04-16 04:34:29 +00:00
|
|
|
|
resolve: resolveHyphenated,
|
|
|
|
|
|
};
|
2016-11-26 01:38:32 +00:00
|
|
|
|
export const title = {
|
|
|
|
|
|
type: GraphQLString,
|
2021-04-16 04:34:29 +00:00
|
|
|
|
description: 'The official title of the entity.',
|
|
|
|
|
|
};
|
2016-11-26 01:38:32 +00:00
|
|
|
|
export const disambiguation = {
|
|
|
|
|
|
type: GraphQLString,
|
2021-04-16 04:34:29 +00:00
|
|
|
|
description:
|
|
|
|
|
|
'A comment used to help distinguish identically named entitites.',
|
|
|
|
|
|
};
|
2016-08-20 05:59:32 +00:00
|
|
|
|
|
2021-04-16 04:34:29 +00:00
|
|
|
|
export function linkedQuery(connectionType, { args, ...config } = {}) {
|
|
|
|
|
|
const typeName = toPlural(toWords(connectionType.name.slice(0, -10)));
|
2016-09-01 08:39:27 +00:00
|
|
|
|
return {
|
|
|
|
|
|
type: connectionType,
|
2016-11-28 13:49:04 +00:00
|
|
|
|
description: `A list of ${typeName} linked to this entity.`,
|
2016-09-01 08:39:27 +00:00
|
|
|
|
args: {
|
2016-12-12 05:09:37 +00:00
|
|
|
|
...args,
|
2021-04-16 04:34:29 +00:00
|
|
|
|
...forwardConnectionArgs,
|
2016-09-01 08:39:27 +00:00
|
|
|
|
},
|
2016-12-02 08:21:10 +00:00
|
|
|
|
resolve: resolveLinked,
|
2021-04-16 04:34:29 +00:00
|
|
|
|
...config,
|
|
|
|
|
|
};
|
2016-12-10 02:55:41 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
2016-11-28 13:49:04 +00:00
|
|
|
|
export const totalCount = {
|
|
|
|
|
|
type: GraphQLInt,
|
|
|
|
|
|
description: `A count of the total number of items in this connection,
|
2021-04-16 04:34:29 +00:00
|
|
|
|
ignoring pagination.`,
|
|
|
|
|
|
};
|
2016-11-28 13:49:04 +00:00
|
|
|
|
|
2016-11-28 14:43:32 +00:00
|
|
|
|
export const score = {
|
|
|
|
|
|
type: GraphQLInt,
|
|
|
|
|
|
description: `The relevancy score (0–100) assigned by the search engine, if
|
2021-04-16 04:34:29 +00:00
|
|
|
|
these results were found through a search.`,
|
|
|
|
|
|
};
|
2016-11-28 14:43:32 +00:00
|
|
|
|
|
2017-11-07 05:54:56 +00:00
|
|
|
|
export function connectionWithExtras(nodeType) {
|
2016-11-28 13:49:04 +00:00
|
|
|
|
return connectionDefinitions({
|
|
|
|
|
|
nodeType,
|
2017-10-07 02:43:15 +00:00
|
|
|
|
connectionFields: () => ({
|
|
|
|
|
|
nodes: {
|
|
|
|
|
|
type: new GraphQLList(nodeType),
|
|
|
|
|
|
description: `A list of nodes in the connection (without going through the
|
2021-04-16 04:34:29 +00:00
|
|
|
|
\`edges\` field).`,
|
2017-10-07 02:43:15 +00:00
|
|
|
|
},
|
2021-04-16 04:34:29 +00:00
|
|
|
|
totalCount,
|
2017-10-07 02:43:15 +00:00
|
|
|
|
}),
|
2021-04-16 04:34:29 +00:00
|
|
|
|
edgeFields: () => ({ score }),
|
|
|
|
|
|
}).connectionType;
|
2016-11-28 13:49:04 +00:00
|
|
|
|
}
|
2021-04-16 04:34:29 +00:00
|
|
|
|
|
|
|
|
|
|
export const releaseGroupType = {
|
|
|
|
|
|
type: new GraphQLList(ReleaseGroupType),
|
|
|
|
|
|
description: 'Filter by one or more release group types.',
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
export const releaseStatus = {
|
|
|
|
|
|
type: new GraphQLList(ReleaseStatus),
|
|
|
|
|
|
description: 'Filter by one or more release statuses.',
|
|
|
|
|
|
};
|