@netlify/content-engine
Version:
214 lines • 8.13 kB
JavaScript
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
;