UNPKG

graphile-build

Version:

Build a GraphQL schema from plugins

133 lines 6.84 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.NodeAccessorPlugin = void 0; require("graphile-config"); const grafast_1 = require("grafast"); const utils_ts_1 = require("../utils.js"); const version_ts_1 = require("../version.js"); exports.NodeAccessorPlugin = { name: "NodeAccessorPlugin", description: "Adds accessors for the various types registered with the Global Unique Object Identification ID (Node ID) system", version: version_ts_1.version, inflection: { add: { nodeById(options, typeName) { return this.camelCase(typeName); }, }, }, schema: { hooks: { build(build) { const { EXPORTABLE } = build; const nodeFetcherByTypeNameCache = EXPORTABLE(() => new Map(), [], "nodeFetcherByTypeNameCache"); const specForHandlerCache = EXPORTABLE(() => new Map(), [], "specForHandlerCache"); return build.extend(build, { specForHandler: EXPORTABLE((markSyncAndSafe, specForHandlerCache) => function (handler) { const existing = specForHandlerCache.get(handler); if (existing) { return existing; } const spec = markSyncAndSafe(function spec(nodeId) { // We only want to return the specifier if it matches // this handler; otherwise return null. if (nodeId == null) return null; try { const specifier = handler.codec.decode(nodeId); if (handler.match(specifier)) { return specifier; } } catch { // Ignore errors } return null; }, `specifier_${handler.typeName}_${handler.codec.name}`); specForHandlerCache.set(handler, spec); return spec; }, [grafast_1.markSyncAndSafe, specForHandlerCache]), nodeFetcherByTypeName(typeName) { const existing = nodeFetcherByTypeNameCache.get(typeName); if (existing) return existing; const finalBuild = build; const { specForHandler } = finalBuild; if (!specForHandler) return null; const handler = finalBuild.getNodeIdHandler?.(typeName); if (!handler) return null; const fetcher = handler.deprecationReason ? EXPORTABLE((handler, lambda, specForHandler) => { const fn = ($nodeId) => { const $decoded = lambda($nodeId, specForHandler(handler)); return handler.get(handler.getSpec($decoded)); }; fn.deprecationReason = handler.deprecationReason; return fn; }, [handler, grafast_1.lambda, specForHandler]) : EXPORTABLE((handler, lambda, specForHandler) => ($nodeId) => { const $decoded = lambda($nodeId, specForHandler(handler)); return handler.get(handler.getSpec($decoded)); }, [handler, grafast_1.lambda, specForHandler]); (0, utils_ts_1.exportNameHint)(fetcher, `nodeFetcher_${typeName}`); nodeFetcherByTypeNameCache.set(typeName, fetcher); return fetcher; }, }, "Adding node accessor helpers"); }, GraphQLObjectType_fields(fields, build, context) { if (!build.getNodeTypeNames) { return fields; } const { graphql: { GraphQLNonNull, GraphQLID }, } = build; const { scope: { isRootQuery }, } = context; if (!isRootQuery) { return fields; } if (!build.nodeFetcherByTypeName) { return fields; } const typeNames = build.getNodeTypeNames(); const nodeIdFieldName = build.inflection.nodeIdFieldName(); const recoverableForEachType = (cb) => { for (const typeName of typeNames) { fields = build.recoverable(fields, () => cb(typeName)); } return fields; }; return recoverableForEachType((typeName) => { // Don't add a field for 'Query' if (typeName === build.inflection.builtin("Query")) { return fields; } const fetcher = build.nodeFetcherByTypeName(typeName); if (!fetcher) { return fields; } return build.extend(fields, { [build.inflection.nodeById(typeName)]: { args: { [nodeIdFieldName]: { description: `The globally unique \`ID\` to be used in selecting a single \`${typeName}\`.`, type: new GraphQLNonNull(GraphQLID), }, }, type: build.getOutputTypeByName(typeName), description: `Reads a single \`${typeName}\` using its globally unique \`ID\`.`, plan: (0, utils_ts_1.EXPORTABLE)((fetcher, nodeIdFieldName) => function plan(_$parent, args) { const $nodeId = args.getRaw(nodeIdFieldName); return fetcher($nodeId); }, [fetcher, nodeIdFieldName]), ...(fetcher.deprecationReason ? { deprecationReason: fetcher.deprecationReason } : null), }, }, `Adding ${typeName} by NodeId field`); }); }, }, }, }; //# sourceMappingURL=NodeAccessorPlugin.js.map