UNPKG

@netlify/content-engine

Version:
214 lines 8.13 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.dontInferExtensionName = exports.inferExtensionName = exports.reservedExtensionNames = exports.processFieldExtensions = exports.internalExtensionNames = exports.builtInFieldExtensions = exports.addDirectives = void 0; const graphql_1 = require("graphql"); const resolvers_1 = require("../resolvers"); const date_1 = require("../types/date"); const inferExtensionName = `infer`; exports.inferExtensionName = inferExtensionName; const dontInferExtensionName = `dontInfer`; exports.dontInferExtensionName = dontInferExtensionName; const typeExtensions = { [inferExtensionName]: { description: `Infer field types from field values.`, }, [dontInferExtensionName]: { description: `Do not infer field types from field values.`, }, 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*\` and \`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.`, }, }, }, nodeInterface: { description: `DEPRECATED: Use interface inheritance instead, i.e. "interface Foo implements Node".\n\n` + `Adds root query fields for an interface. All implementing types ` + `must also implement the Node interface.`, locations: [graphql_1.DirectiveLocation.INTERFACE], }, authorization: { description: `Define authorization rules for this type.`, args: { labels: { type: `[String!]!`, defaultValue: [], description: `A list of auth scopes that are allowed to access this type.`, }, }, locations: [graphql_1.DirectiveLocation.OBJECT, graphql_1.DirectiveLocation.FIELD_DEFINITION], }, runtime: { description: `Sets whether a type is resolved at runtime.`, locations: [graphql_1.DirectiveLocation.OBJECT], }, }; const builtInFieldExtensions = { dateformat: { name: `dateformat`, description: `Add date formatting options.`, args: { formatString: `String`, locale: `String`, fromNow: `Boolean`, difference: `String`, }, extend(args, fieldConfig) { return (0, date_1.getDateResolver)(args, fieldConfig); }, }, locale: { description: "Select which field locale to resolve this and child fields in", args: { code: { description: "The locale code to resolve this field and all localized child fields in", type: `String!`, }, }, locations: [graphql_1.DirectiveLocation.FIELD], }, link: { name: `link`, description: `Link to node by foreign-key relation.`, args: { by: { type: `String!`, defaultValue: `id`, }, from: `String`, on: `String`, keepObjects: `Boolean`, }, extend(args, fieldConfig, schemaComposer) { const type = args.on && schemaComposer.typeMapper.convertSDLWrappedTypeName(args.on)?.getType(); return { resolve: (0, resolvers_1.link)({ ...args, type }, fieldConfig), }; }, }, fileByRelativePath: { name: `fileByRelativePath`, description: `Link to File node by relative path.`, args: { from: `String`, }, extend(args, fieldConfig) { return { resolve: (0, resolvers_1.fileByPath)(args, fieldConfig), }; }, }, proxy: { name: `proxy`, description: `Proxy resolver from another field.`, args: { from: `String!`, }, extend(options, fieldConfig) { return { resolve(source, args, context, info) { const resolver = fieldConfig.resolve || context.defaultFieldResolver; return resolver(source, args, context, { ...info, from: options.from || info.from, }); }, }; }, }, }; exports.builtInFieldExtensions = builtInFieldExtensions; // Reserved for internal use const internalExtensionNames = [ `createdFrom`, `default`, `directives`, `infer`, `plugin`, ...graphql_1.specifiedDirectives.map((directive) => directive.name), ]; exports.internalExtensionNames = internalExtensionNames; const reservedExtensionNames = [ ...internalExtensionNames, ...Object.keys(builtInFieldExtensions), ]; exports.reservedExtensionNames = reservedExtensionNames; 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); // arg.type is a composer that needs to be converted to graphql-js type Object.keys(normalizedArgs).forEach((argName) => { normalizedArgs[argName].type = normalizedArgs[argName].type.getType(); }); return new graphql_1.GraphQLDirective({ name, args: normalizedArgs, description, locations: locations || defaultLocations, }); }); // @ts-ignore const addDirectives = ({ schemaComposer, fieldExtensions = {}, }) => { const fieldDirectives = toDirectives({ schemaComposer, extensions: fieldExtensions, locations: [graphql_1.DirectiveLocation.FIELD_DEFINITION], }); fieldDirectives.forEach((directive) => schemaComposer.addDirective(directive)); const typeDirectives = toDirectives({ schemaComposer, extensions: typeExtensions, locations: [graphql_1.DirectiveLocation.OBJECT], }); typeDirectives.forEach((directive) => schemaComposer.addDirective(directive)); }; exports.addDirectives = addDirectives; const processFieldExtensions = ({ fieldExtensions = {}, schemaComposer, typeComposer, // @ts-ignore 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)); } }); }); }; exports.processFieldExtensions = processFieldExtensions; //# sourceMappingURL=index.js.map