"use strict"; const { GraphQLDirective, DirectiveLocation, specifiedDirectives } = require(`graphql`); const { link, fileByPath } = require(`../resolvers`); const { getDateResolver } = require(`../types/date`); const typeExtensions = { infer: { description: `Infer field types from field values.`, args: { noDefaultResolvers: { type: `Boolean`, description: `Don't add default resolvers to defined fields.`, deprecationReason: `noDefaultResolvers is deprecated, annotate individual fields.` } } }, dontInfer: { description: `Do not infer field types from field values.`, args: { noDefaultResolvers: { type: `Boolean`, description: `Don't add default resolvers to defined fields.`, deprecationReason: `noDefaultResolvers is deprecated, annotate individual fields.` } } }, mimeTypes: { description: `Define the mime-types handled by this type.`, args: { types: { type: `[String!]!`, defaultValue: [], description: `The mime-types handled by this type.` } } }, childOf: { description: `Define parent-child relations between types. This is used to add ` + `\`child*\` or \`children*\` convenience fields like \`childImageSharp\`.`, args: { mimeTypes: { type: `[String!]!`, defaultValue: [], description: `A list of mime-types this type is a child of. Usually these are ` + `the mime-types handled by a transformer plugin.` }, types: { type: `[String!]!`, defaultValue: [], description: `A list of types this type is a child of. Usually these are the ` + `types handled by a transformer plugin.` }, many: { type: `Boolean!`, defaultValue: false, description: `Specifies whether a parent can have multiple children of this type or not.` } } }, nodeInterface: { description: `Adds root query fields for an interface. All implementing types ` + `must also implement the Node interface.`, locations: [DirectiveLocation.INTERFACE] } }; const builtInFieldExtensions = { dateformat: { name: `dateformat`, description: `Add date formating options.`, args: { formatString: `String`, locale: `String`, fromNow: `Boolean`, difference: `String` }, extend(args, fieldConfig) { return getDateResolver(args, fieldConfig); } }, link: { name: `link`, description: `Link to node by foreign-key relation.`, args: { by: { type: `String!`, defaultValue: `id` }, from: `String`, on: `String` }, extend(args, fieldConfig, schemaComposer) { const type = args.on && schemaComposer.typeMapper.getWrapped(args.on); return { resolve: link(Object.assign({}, args, { type }), fieldConfig) }; } }, fileByRelativePath: { name: `fileByRelativePath`, description: `Link to File node by relative path.`, args: { from: `String` }, extend(args, fieldConfig) { return { resolve: fileByPath(args, fieldConfig) }; } }, proxy: { name: `proxy`, description: `Proxy resolver from another field.`, args: { from: `String!`, fromNode: { type: `Boolean!`, defaultValue: false } }, extend(options, fieldConfig) { return { resolve(source, args, context, info) { const resolver = fieldConfig.resolve || context.defaultFieldResolver; return resolver(source, args, context, Object.assign({}, info, { from: options.from || info.from, fromNode: options.from ? options.fromNode : info.fromNode })); } }; } } // Reserved for internal use }; const internalExtensionNames = [`createdFrom`, `default`, `directives`, `infer`, `plugin`, ...specifiedDirectives.map(directive => directive.name)]; const reservedExtensionNames = [...internalExtensionNames, ...Object.keys(builtInFieldExtensions)]; const toDirectives = ({ schemaComposer, extensions, locations: defaultLocations }) => Object.keys(extensions).map(name => { const extension = extensions[name]; const { args, description, locations, type } = extension; // Allow field extensions to register a return type if (type) { schemaComposer.createTC(type); } // Support the `graphql-compose` style of directly providing the field type as string const normalizedArgs = schemaComposer.typeMapper.convertArgConfigMap(args); return new GraphQLDirective({ name, args: normalizedArgs, description, locations: locations || defaultLocations }); }); const addDirectives = ({ schemaComposer, fieldExtensions = {} }) => { const fieldDirectives = toDirectives({ schemaComposer, extensions: fieldExtensions, locations: [DirectiveLocation.FIELD_DEFINITION] }); fieldDirectives.forEach(directive => schemaComposer.addDirective(directive)); const typeDirectives = toDirectives({ schemaComposer, extensions: typeExtensions, locations: [DirectiveLocation.OBJECT] }); typeDirectives.forEach(directive => schemaComposer.addDirective(directive)); }; const processFieldExtensions = ({ fieldExtensions = {}, schemaComposer, typeComposer, parentSpan }) => { typeComposer.getFieldNames().forEach(fieldName => { const extensions = typeComposer.getFieldExtensions(fieldName); Object.keys(extensions).filter(name => !internalExtensionNames.includes(name)).forEach(name => { const { extend } = fieldExtensions[name] || {}; if (typeof extend === `function`) { // Always get fresh field config as it will have been changed // by previous field extension const prevFieldConfig = typeComposer.getFieldConfig(fieldName); typeComposer.extendField(fieldName, extend(extensions[name], prevFieldConfig, schemaComposer)); } }); }); }; module.exports = { addDirectives, builtInFieldExtensions, internalExtensionNames, processFieldExtensions, reservedExtensionNames }; //# sourceMappingURL=index.js.map