@graphql-mesh/fusion-composition
Version:
Basic composition utility for Fusion spec
120 lines (119 loc) • 5.22 kB
JavaScript
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.resolveToDirective = exports.resolveToSourceArgsScalar = void 0;
exports.createEncapsulateTransform = createEncapsulateTransform;
const graphql_1 = require("graphql");
const filter_schema_js_1 = require("./filter-schema.js");
const OPERATION_TYPE_SUFFIX_MAP = {
query: 'Query',
mutation: 'Mutation',
subscription: 'Subscription',
};
const DEFAULT_APPLY_TO = {
query: true,
mutation: true,
subscription: true,
};
function createEncapsulateTransform(opts = {}) {
return function encapsulateTransform(schema, subgraphConfig) {
const groupName = opts.name || subgraphConfig.name;
const applyToMap = {
...DEFAULT_APPLY_TO,
...(opts.applyTo || {}),
};
const newRootTypes = {};
for (const opTypeString in applyToMap) {
const operationType = opTypeString;
const originalType = schema.getRootType(operationType);
if (originalType && applyToMap[operationType]) {
const originalTypeConfig = originalType.toConfig();
const wrappedTypeName = `${groupName}${OPERATION_TYPE_SUFFIX_MAP[operationType]}`;
const originalFieldMapWithHidden = {};
const wrappedFieldMap = {};
for (const fieldName in originalTypeConfig.fields) {
const originalFieldConfig = originalTypeConfig.fields[fieldName];
wrappedFieldMap[fieldName] = {
...originalFieldConfig,
extensions: {
directives: {
resolveTo: [
{
sourceName: subgraphConfig.name,
sourceTypeName: originalType.name,
sourceFieldName: fieldName,
},
],
},
},
};
const newOriginalFieldConfig = {
...originalFieldConfig,
astNode: undefined,
};
(0, filter_schema_js_1.addInaccessibleDirective)(newOriginalFieldConfig);
originalFieldMapWithHidden[fieldName] = newOriginalFieldConfig;
}
const wrappedType = new graphql_1.GraphQLObjectType({
name: wrappedTypeName,
fields: wrappedFieldMap,
});
newRootTypes[operationType] = new graphql_1.GraphQLObjectType({
...originalTypeConfig,
fields: {
...originalFieldMapWithHidden,
[groupName]: {
type: new graphql_1.GraphQLNonNull(wrappedType),
extensions: {
directives: {
resolveTo: [
{
sourceName: subgraphConfig.name,
sourceTypeName: originalType.name,
sourceFieldName: '__typename',
},
],
},
},
},
},
});
}
else {
newRootTypes[operationType] = originalType;
}
}
const schemaConfig = schema.toConfig();
const newDirectives = [...schemaConfig.directives];
if (!newDirectives.some(directive => directive.name === 'resolveTo')) {
newDirectives.push(exports.resolveToDirective);
}
return new graphql_1.GraphQLSchema({
...schemaConfig,
types: undefined,
directives: newDirectives,
...newRootTypes,
});
};
}
exports.resolveToSourceArgsScalar = new graphql_1.GraphQLScalarType({
name: 'ResolveToSourceArgs',
});
exports.resolveToDirective = new graphql_1.GraphQLDirective({
name: 'resolveTo',
locations: [graphql_1.DirectiveLocation.FIELD_DEFINITION],
args: {
additionalArgs: { type: exports.resolveToSourceArgsScalar },
filterBy: { type: graphql_1.GraphQLString },
keyField: { type: graphql_1.GraphQLString },
keysArg: { type: graphql_1.GraphQLString },
pubsubTopic: { type: graphql_1.GraphQLString },
requiredSelectionSet: { type: graphql_1.GraphQLString },
result: { type: graphql_1.GraphQLString },
resultType: { type: graphql_1.GraphQLString },
sourceArgs: { type: exports.resolveToSourceArgsScalar },
sourceFieldName: { type: graphql_1.GraphQLString },
sourceName: { type: graphql_1.GraphQLString },
sourceSelectionSet: { type: graphql_1.GraphQLString },
sourceTypeName: { type: graphql_1.GraphQLString },
},
});