UNPKG

@pothos/plugin-sub-graph

Version:

A Pothos plugin for creating multiple variants or sub-selections of the same graph

298 lines (297 loc) 15.8 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); function _export(target, all) { for(var name in all)Object.defineProperty(target, name, { enumerable: true, get: Object.getOwnPropertyDescriptor(all, name).get }); } _export(exports, { get PothosSubGraphPlugin () { return PothosSubGraphPlugin; }, get default () { return _default; } }); require("./global-types"); const _core = /*#__PURE__*/ _interop_require_wildcard(require("@pothos/core")); const _graphql = require("graphql"); const _util = require("./util"); function _getRequireWildcardCache(nodeInterop) { if (typeof WeakMap !== "function") return null; var cacheBabelInterop = new WeakMap(); var cacheNodeInterop = new WeakMap(); return (_getRequireWildcardCache = function(nodeInterop) { return nodeInterop ? cacheNodeInterop : cacheBabelInterop; })(nodeInterop); } function _interop_require_wildcard(obj, nodeInterop) { if (!nodeInterop && obj && obj.__esModule) { return obj; } if (obj === null || typeof obj !== "object" && typeof obj !== "function") { return { default: obj }; } var cache = _getRequireWildcardCache(nodeInterop); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = { __proto__: null }; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for(var key in obj){ if (key !== "default" && Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj.default = obj; if (cache) { cache.set(obj, newObj); } return newObj; } const pluginName = 'subGraph'; const _default = pluginName; function matchesSubGraphs(left, right, mode) { if (mode === 'all') { return right.every((entry)=>left.includes(entry)); } for (const entry of left){ if (right.includes(entry)) { return true; } } return false; } class PothosSubGraphPlugin extends _core.BasePlugin { static createSubGraph(schema, subGraph, builder) { var _schema_getQueryType, _schema_getMutationType, _schema_getSubscriptionType; const mode = Array.isArray(subGraph) ? 'any' : typeof subGraph === 'string' ? 'any' : 'all'; const subGraphs = Array.isArray(subGraph) ? subGraph : typeof subGraph === 'string' ? [ subGraph ] : subGraph.all; const config = schema.toConfig(); const newTypes = PothosSubGraphPlugin.filterTypes(config.types, subGraphs, mode); const returnedInterfaces = new Set(); for (const type of newTypes.values()){ if ((0, _graphql.isObjectType)(type) || (0, _graphql.isInterfaceType)(type)) { const fields = type.getFields(); for (const field of Object.values(fields)){ const namedType = (0, _graphql.getNamedType)(field.type); if ((0, _graphql.isInterfaceType)(namedType)) { returnedInterfaces.add(namedType.name); } } } } function hasReturnedInterface(type) { for (const iface of type.getInterfaces()){ if (returnedInterfaces.has(iface.name)) { return true; } if (hasReturnedInterface(iface)) { return true; } } return false; } var _schema_getQueryType_name, _schema_getMutationType_name, _schema_getSubscriptionType_name; return new _graphql.GraphQLSchema({ directives: config.directives, extensions: config.extensions, extensionASTNodes: config.extensionASTNodes, assumeValid: false, query: newTypes.get((_schema_getQueryType_name = (_schema_getQueryType = schema.getQueryType()) === null || _schema_getQueryType === void 0 ? void 0 : _schema_getQueryType.name) !== null && _schema_getQueryType_name !== void 0 ? _schema_getQueryType_name : 'Query'), mutation: newTypes.get((_schema_getMutationType_name = (_schema_getMutationType = schema.getMutationType()) === null || _schema_getMutationType === void 0 ? void 0 : _schema_getMutationType.name) !== null && _schema_getMutationType_name !== void 0 ? _schema_getMutationType_name : 'Mutation'), subscription: newTypes.get((_schema_getSubscriptionType_name = (_schema_getSubscriptionType = schema.getSubscriptionType()) === null || _schema_getSubscriptionType === void 0 ? void 0 : _schema_getSubscriptionType.name) !== null && _schema_getSubscriptionType_name !== void 0 ? _schema_getSubscriptionType_name : 'Subscription'), // Explicitly include types that implement an interface that can be resolved in the subGraph types: [ ...newTypes.values() ].filter((type)=>{ var _builder_options_subGraphs_explicitlyIncludeType, _builder_options_subGraphs; return ((_builder_options_subGraphs = builder.options.subGraphs) === null || _builder_options_subGraphs === void 0 ? void 0 : (_builder_options_subGraphs_explicitlyIncludeType = _builder_options_subGraphs.explicitlyIncludeType) === null || _builder_options_subGraphs_explicitlyIncludeType === void 0 ? void 0 : _builder_options_subGraphs_explicitlyIncludeType.call(_builder_options_subGraphs, type, subGraphs)) || ((0, _graphql.isObjectType)(type) || (0, _graphql.isInterfaceType)(type)) && hasReturnedInterface(type); }) }); } static filterTypes(types, subGraphs, mode) { const newTypes = new Map(); for (const type of types){ var _type_extensions; if (type.name.startsWith('__')) { continue; } if (type.name === 'String' || type.name === 'Int' || type.name === 'Float' || type.name === 'Boolean' || type.name === 'ID') { newTypes.set(type.name, type); } if (!matchesSubGraphs(((_type_extensions = type.extensions) === null || _type_extensions === void 0 ? void 0 : _type_extensions.subGraphs) || [], subGraphs, mode)) { continue; } if (type instanceof _graphql.GraphQLScalarType || type instanceof _graphql.GraphQLEnumType) { newTypes.set(type.name, type); } else if (type instanceof _graphql.GraphQLObjectType) { const typeConfig = type.toConfig(); newTypes.set(type.name, new _graphql.GraphQLObjectType({ ...typeConfig, interfaces: ()=>typeConfig.interfaces.filter((iface)=>newTypes.has(iface.name)).map((iface)=>(0, _util.replaceType)(iface, newTypes, typeConfig.name, subGraphs)), fields: PothosSubGraphPlugin.filterFields(type, newTypes, subGraphs, mode) })); } else if (type instanceof _graphql.GraphQLInterfaceType) { const typeConfig = type.toConfig(); newTypes.set(type.name, new _graphql.GraphQLInterfaceType({ ...typeConfig, interfaces: ()=>typeConfig.interfaces.map((iface)=>(0, _util.replaceType)(iface, newTypes, typeConfig.name, subGraphs)), fields: PothosSubGraphPlugin.filterFields(type, newTypes, subGraphs, mode) })); } else if (type instanceof _graphql.GraphQLUnionType) { const typeConfig = type.toConfig(); newTypes.set(type.name, new _graphql.GraphQLUnionType({ ...typeConfig, types: ()=>typeConfig.types.map((member)=>(0, _util.replaceType)(member, newTypes, typeConfig.name, subGraphs)) })); } else if (type instanceof _graphql.GraphQLInputObjectType) { const typeConfig = type.toConfig(); newTypes.set(type.name, new _graphql.GraphQLInputObjectType({ ...typeConfig, fields: PothosSubGraphPlugin.mapInputFields(type, newTypes, subGraphs, mode) })); } } return newTypes; } static filterFields(type, newTypes, subGraphs, mode) { const oldFields = type.getFields(); return ()=>{ const newFields = {}; for (const [fieldName, fieldConfig] of Object.entries(oldFields)){ var _fieldConfig_extensions; const newArguments = {}; var _fieldConfig_extensions_subGraphs; if (!matchesSubGraphs((_fieldConfig_extensions_subGraphs = (_fieldConfig_extensions = fieldConfig.extensions) === null || _fieldConfig_extensions === void 0 ? void 0 : _fieldConfig_extensions.subGraphs) !== null && _fieldConfig_extensions_subGraphs !== void 0 ? _fieldConfig_extensions_subGraphs : [], subGraphs, mode) || !newTypes.has((0, _graphql.getNamedType)(fieldConfig.type).name)) { continue; } for (const argConfig of fieldConfig.args){ var _argConfig_extensions; const argSubGraphs = (_argConfig_extensions = argConfig.extensions) === null || _argConfig_extensions === void 0 ? void 0 : _argConfig_extensions.subGraphs; if (argSubGraphs && !matchesSubGraphs(argSubGraphs, subGraphs, mode)) { if ((0, _graphql.isNonNullType)(argConfig.type)) { throw new _core.PothosSchemaError(`argument ${argConfig.name} of ${type.name}.${fieldName} is NonNull and must be in included in all sub-graphs that include ${type.name}.${fieldName}`); } continue; } newArguments[argConfig.name] = { description: argConfig.description, defaultValue: argConfig.defaultValue, extensions: argConfig.extensions, astNode: argConfig.astNode, deprecationReason: argConfig.deprecationReason, type: (0, _util.replaceType)(argConfig.type, newTypes, `${argConfig.name} argument of ${type.name}.${fieldConfig.name}`, subGraphs) }; } newFields[fieldName] = { description: fieldConfig.description, resolve: fieldConfig.resolve, subscribe: fieldConfig.subscribe, deprecationReason: fieldConfig.deprecationReason, extensions: fieldConfig.extensions, astNode: fieldConfig.astNode, type: (0, _util.replaceType)(fieldConfig.type, newTypes, `${type.name}.${fieldConfig.name}`, subGraphs), args: newArguments }; } return newFields; }; } static mapInputFields(type, newTypes, subGraphs, mode) { const oldFields = type.getFields(); return ()=>{ const newFields = {}; for (const [fieldName, fieldConfig] of Object.entries(oldFields)){ var _fieldConfig_extensions; const fieldSubGraphs = (_fieldConfig_extensions = fieldConfig.extensions) === null || _fieldConfig_extensions === void 0 ? void 0 : _fieldConfig_extensions.subGraphs; if (fieldSubGraphs && !matchesSubGraphs(fieldSubGraphs, subGraphs, mode)) { if ((0, _graphql.isNonNullType)(fieldConfig.type)) { throw new _core.PothosSchemaError(`${type.name}.${fieldName} is NonNull and must be in included in all sub-graphs that include ${type.name}`); } continue; } newFields[fieldName] = { description: fieldConfig.description, extensions: fieldConfig.extensions, astNode: fieldConfig.astNode, defaultValue: fieldConfig.defaultValue, deprecationReason: fieldConfig.deprecationReason, type: (0, _util.replaceType)(fieldConfig.type, newTypes, `${type.name}.${fieldConfig.name}`, subGraphs) }; } return newFields; }; } afterBuild(schema) { if (this.options.subGraph) { return PothosSubGraphPlugin.createSubGraph(schema, this.options.subGraph, this.builder); } return schema; } onTypeConfig(typeConfig) { var _this_builder_options_subGraphs; var _typeConfig_pothosOptions_subGraphs, _ref; return { ...typeConfig, extensions: { ...typeConfig.extensions, subGraphs: (_ref = (_typeConfig_pothosOptions_subGraphs = typeConfig.pothosOptions.subGraphs) !== null && _typeConfig_pothosOptions_subGraphs !== void 0 ? _typeConfig_pothosOptions_subGraphs : (_this_builder_options_subGraphs = this.builder.options.subGraphs) === null || _this_builder_options_subGraphs === void 0 ? void 0 : _this_builder_options_subGraphs.defaultForTypes) !== null && _ref !== void 0 ? _ref : [] } }; } onInputFieldConfig(fieldConfig) { if (fieldConfig.pothosOptions.subGraphs) { return { ...fieldConfig, extensions: { ...fieldConfig.extensions, subGraphs: fieldConfig.pothosOptions.subGraphs } }; } return fieldConfig; } onOutputFieldConfig(fieldConfig) { var _this_builder_options_subGraphs, _this_builder_options_subGraphs1; const typeConfig = this.buildCache.getTypeConfig(fieldConfig.parentType); if (typeConfig.graphqlKind !== 'Interface' && typeConfig.graphqlKind !== 'Object') { return fieldConfig; } let subGraphs = []; if (fieldConfig.pothosOptions.subGraphs) { subGraphs = fieldConfig.pothosOptions.subGraphs; } else if (typeConfig.pothosOptions.defaultSubGraphsForFields) { subGraphs = typeConfig.pothosOptions.defaultSubGraphsForFields; } else if ((_this_builder_options_subGraphs = this.builder.options.subGraphs) === null || _this_builder_options_subGraphs === void 0 ? void 0 : _this_builder_options_subGraphs.fieldsInheritFromTypes) { var _typeConfig_extensions; subGraphs = ((_typeConfig_extensions = typeConfig.extensions) === null || _typeConfig_extensions === void 0 ? void 0 : _typeConfig_extensions.subGraphs) || []; } else if ((_this_builder_options_subGraphs1 = this.builder.options.subGraphs) === null || _this_builder_options_subGraphs1 === void 0 ? void 0 : _this_builder_options_subGraphs1.defaultForFields) { var _this_builder_options_subGraphs2; subGraphs = (_this_builder_options_subGraphs2 = this.builder.options.subGraphs) === null || _this_builder_options_subGraphs2 === void 0 ? void 0 : _this_builder_options_subGraphs2.defaultForFields; } return { ...fieldConfig, extensions: { ...fieldConfig.extensions, subGraphs } }; } } _core.default.registerPlugin(pluginName, PothosSubGraphPlugin); //# sourceMappingURL=index.js.map