UNPKG

@digicat/cf-graphql

Version:

Generate a GraphQL schema out of your Contentful space

107 lines (89 loc) 3.13 kB
'use strict'; const _get = require('lodash.get'); const { GraphQLNonNull, GraphQLString, GraphQLInt, GraphQLFloat, GraphQLBoolean, GraphQLList } = require('graphql'); const {AssetType, EntryType, LocationType, DocumentType} = require('./base-types.js'); const NOTHING = {}; const is = type => entity => typeof entity === type; const isString = is('string'); const isObject = is('object'); module.exports = { String: field => createFieldConfig(GraphQLString, field), Int: field => createFieldConfig(GraphQLInt, field), Float: field => createFieldConfig(GraphQLFloat, field), Bool: field => createFieldConfig(GraphQLBoolean, field), Location: field => createFieldConfig(LocationType, field), Document: field => createFieldConfig(DocumentType, field), Object: createObjectFieldConfig, 'Array<String>': createArrayOfStringsFieldConfig, 'Link<Asset>': createAssetFieldConfig, 'Array<Link<Asset>>': createArrayOfAssetsFieldConfig, 'Link<Entry>': createEntryFieldConfig, 'Array<Link<Entry>>': createArrayOfEntriesFieldConfig }; function createFieldConfig (Type, field, resolveFn) { return { type: field.required && field.type !== 'Link<Entry>' ? new GraphQLNonNull(Type) : Type, resolve: (entity, _, ctx) => { const fieldValue = _get(entity, ['fields', field.id], NOTHING); if (fieldValue !== NOTHING) { return resolveFn ? resolveFn(fieldValue, ctx) : fieldValue; } } }; } function createObjectFieldConfig (field) { return createFieldConfig(GraphQLString, field, val => JSON.stringify(val)); } function createArrayOfStringsFieldConfig (field) { return createFieldConfig(new GraphQLList(new GraphQLNonNull(GraphQLString)), field); } function createAssetFieldConfig (field) { return createFieldConfig(AssetType, field, getAsset); } function createArrayOfAssetsFieldConfig (field) { return createFieldConfig(new GraphQLList(new GraphQLNonNull(AssetType)), field, (links, ctx) => { if (Array.isArray(links)) { return links.map(link => getAsset(link, ctx)).filter(isObject); } }); } function getAsset (link, ctx) { const linkedId = getLinkedId(link); if (isString(linkedId)) { return ctx.entryLoader.getIncludedAsset(linkedId); } } function createEntryFieldConfig (field, ctIdToType) { return createFieldConfig(typeFor(field, ctIdToType), field, (link, ctx) => { const linkedId = getLinkedId(link); if (isString(linkedId)) { return ctx.entryLoader.get(linkedId, field.linkedCt); } }); } function createArrayOfEntriesFieldConfig (field, ctIdToType) { const Type = new GraphQLList(new GraphQLNonNull(typeFor(field, ctIdToType))); return createFieldConfig(Type, field, (links, ctx) => { if (Array.isArray(links)) { const ids = links.map(getLinkedId).filter(isString); return ctx.entryLoader.getMany(ids).then(coll => coll.filter(isObject)); } }); } function getLinkedId (link) { return _get(link, ['sys', 'id']); } function typeFor ({linkedCt}, ctIdToType = {}) { if (linkedCt) { return ctIdToType[linkedCt] || EntryType; } else { return EntryType; } }