graphbrainz/src/types/helpers.js
Brian Beck f095cd4de7
Modernize dependencies, syntax, imports (#93)
* wip: Modernize dependencies, syntax, imports

* Use final release of ava-nock v2

* Update Travis config

* Remove Node 13 from test matrix

* Replace errorClass with parseErrorMessage in subclasses

* define exports, apply updated lint rules

* Remove markdown eslint plugin

* Update README

* v9.0.0-beta.1

* Add gql tag to exports

* v9.0.0-beta.2

* Bump ava-nock, add test

* Update dataloader loadMany usage

* Add modules note to README

* Add retry option to got calls
2021-04-15 21:34:29 -07:00

156 lines
4.1 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

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 {
globalIdField,
connectionDefinitions,
forwardConnectionArgs,
} = GraphQLRelay;
const TYPE_NAMES = {
discid: 'Disc',
url: 'URL',
};
export function resolveType(value, context, info) {
const typeName = TYPE_NAMES[value._type] || toPascal(value._type);
const typeMap = info.schema.getTypeMap();
return typeMap[typeName];
}
export function resolveHyphenated(obj, args, context, info) {
const name = toDashed(info.fieldName);
return obj[name];
}
export function resolveWithFallback(keys) {
return (obj) => {
for (let i = 0; i < keys.length; i++) {
const key = keys[i];
if (key in obj) {
return obj[key];
}
}
};
}
export function fieldWithID(name, config = {}) {
config = {
type: GraphQLString,
resolve: resolveHyphenated,
...config,
};
const isPlural = config.type instanceof GraphQLList;
const singularName = isPlural ? toSingular(name) : name;
const idName = isPlural ? `${singularName}IDs` : `${name}ID`;
const s = isPlural ? 's' : '';
const idConfig = {
type: isPlural ? new GraphQLList(MBID) : MBID,
description: `The MBID${s} associated with the value${s} of the \`${name}\`
field.`,
resolve: (entity, args, { loaders }) => {
const fieldName = toDashed(idName);
if (fieldName in entity) {
return entity[fieldName];
}
return loaders.lookup
.load([entity._type, entity.id])
.then((data) => data[fieldName]);
},
};
return {
[name]: config,
[idName]: idConfig,
};
}
export function createCollectionField(config) {
const typeName = toPlural(toWords(config.type.name.slice(0, -10)));
return {
...config,
description: `The list of ${typeName} found in this collection.`,
};
}
export const id = globalIdField();
export const mbid = {
type: new GraphQLNonNull(MBID),
description: 'The MBID of the entity.',
resolve: (entity) => entity.id,
};
export const name = {
type: GraphQLString,
description: 'The official name of the entity.',
};
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 persons last name to
the front).`,
resolve: resolveHyphenated,
};
export const title = {
type: GraphQLString,
description: 'The official title of the entity.',
};
export const disambiguation = {
type: GraphQLString,
description:
'A comment used to help distinguish identically named entitites.',
};
export function linkedQuery(connectionType, { args, ...config } = {}) {
const typeName = toPlural(toWords(connectionType.name.slice(0, -10)));
return {
type: connectionType,
description: `A list of ${typeName} linked to this entity.`,
args: {
...args,
...forwardConnectionArgs,
},
resolve: resolveLinked,
...config,
};
}
export const totalCount = {
type: GraphQLInt,
description: `A count of the total number of items in this connection,
ignoring pagination.`,
};
export const score = {
type: GraphQLInt,
description: `The relevancy score (0100) assigned by the search engine, if
these results were found through a search.`,
};
export function connectionWithExtras(nodeType) {
return connectionDefinitions({
nodeType,
connectionFields: () => ({
nodes: {
type: new GraphQLList(nodeType),
description: `A list of nodes in the connection (without going through the
\`edges\` field).`,
},
totalCount,
}),
edgeFields: () => ({ score }),
}).connectionType;
}
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.',
};