@graphql-mesh/transform-encapsulate
Version:
72 lines (71 loc) • 3.38 kB
JavaScript
import { Kind } from 'graphql';
import { applyRequestTransforms, applyResultTransforms, applySchemaTransforms, } from '@graphql-mesh/utils';
import { getRootTypeMap, selectObjectFields } from '@graphql-tools/utils';
import { WrapType } from '@graphql-tools/wrap';
const OPERATION_TYPE_SUFFIX_MAP = {
query: 'Query',
mutation: 'Mutation',
subscription: 'Subscription',
};
const DEFAULT_APPLY_TO = {
query: true,
mutation: true,
subscription: true,
};
export default class EncapsulateTransform {
constructor(options) {
this.transformMap = {};
this.transforms = [];
this.config = options.config;
this.name = this.config?.name || options.apiName;
if (!this.name) {
throw new Error(`Unable to execute encapsulate transform without a name. Please make sure to use it over a specific schema, or specify a name in your configuration!`);
}
}
*generateSchemaTransforms(originalWrappingSchema) {
const applyTo = { ...DEFAULT_APPLY_TO, ...(this.config?.applyTo || {}) };
const outerTypeNames = getRootTypeMap(originalWrappingSchema);
for (const operationType in applyTo) {
if (applyTo[operationType] === true) {
const outerTypeName = outerTypeNames.get(operationType)?.name;
if (outerTypeName) {
this.transformMap[outerTypeName] = new WrapType(outerTypeName, `${this.name}${OPERATION_TYPE_SUFFIX_MAP[operationType]}`, this.name);
}
}
}
for (const typeName of Object.keys(this.transformMap)) {
const fieldConfigMap = selectObjectFields(originalWrappingSchema, typeName, () => true);
if (Object.keys(fieldConfigMap).length) {
yield this.transformMap[typeName];
}
}
}
transformSchema(originalWrappingSchema, subschemaConfig, transformedSchema) {
this.transforms = [...this.generateSchemaTransforms(originalWrappingSchema)];
return applySchemaTransforms(originalWrappingSchema, subschemaConfig, transformedSchema, this.transforms);
}
transformRequest(originalRequest, delegationContext, transformationContext) {
const transformedRequest = applyRequestTransforms(originalRequest, delegationContext, transformationContext, this.transforms);
if (delegationContext.operation === 'subscription') {
transformedRequest.document = {
...transformedRequest.document,
definitions: transformedRequest.document.definitions.map(def => {
if (def.kind === Kind.OPERATION_DEFINITION) {
return {
...def,
selectionSet: {
...def.selectionSet,
selections: def.selectionSet.selections.filter(selection => selection.kind === Kind.FIELD && selection.name.value !== '__typename'),
},
};
}
return def;
}),
};
}
return transformedRequest;
}
transformResult(originalResult, delegationContext, transformationContext) {
return applyResultTransforms(originalResult, delegationContext, transformationContext, this.transforms);
}
}