@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
JavaScript
;
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