@graphql-tools/wrap
Version:
A set of utils for faster development of GraphQL tools
1,530 lines (1,507 loc) • 77.9 kB
JavaScript
import { isExternalObject, getUnpathedErrors, getSubschema, resolveExternalValue, delegateToSchema, applySchemaTransforms, defaultMergedResolver, getTypeInfo as getTypeInfo$1, isPrototypePollutingKey } from '@graphql-tools/delegate';
import { getRootTypeMap, getResponseKeyFromInfo, memoize1, mapSchema, MapperKind, renameType, visitData, transformInputValue, getDefinedRootType, memoize2, visitResult, astFromValueUntyped, getOperationASTFromRequest, relocatedError, getArgumentValues, valueMatchesCriteria, getDirectives, pruneSchema, selectObjectFields, appendObjectFields, modifyObjectFields, removeObjectFields, isAsyncIterable, createGraphQLError, inspect } from '@graphql-tools/utils';
import { GraphQLUnionType, GraphQLInterfaceType, GraphQLObjectType, isSpecifiedScalarType, isScalarType, visit, Kind, visitWithTypeInfo, isObjectType, isInterfaceType, typeFromAST, isInputType, getNamedType, TypeInfo, versionInfo, isLeafType, valueFromAST, valueFromASTUntyped, astFromValue, GraphQLNonNull, getNullableType, isListType, GraphQLList, BREAK, parse, getIntrospectionQuery, buildClientSchema } from 'graphql';
import { handleMaybePromise } from '@whatwg-node/promise-helpers';
function generateProxyingResolvers(subschemaConfig) {
const targetSchema = subschemaConfig.schema;
const createProxyingResolver = subschemaConfig.createProxyingResolver ?? defaultCreateProxyingResolver;
const rootTypeMap = getRootTypeMap(targetSchema);
const resolvers = {};
for (const [operation, rootType] of rootTypeMap.entries()) {
const typeName = rootType.name;
const fields = rootType.getFields();
resolvers[typeName] = {};
for (const fieldName in fields) {
const proxyingResolver = createProxyingResolver({
subschemaConfig,
operation,
fieldName
});
const finalResolver = createPossiblyNestedProxyingResolver(
subschemaConfig,
proxyingResolver
);
if (operation === "subscription") {
resolvers[typeName][fieldName] = {
subscribe: finalResolver,
resolve: identical
};
} else {
resolvers[typeName][fieldName] = {
resolve: finalResolver
};
}
}
}
return resolvers;
}
function identical(value) {
return value;
}
function createPossiblyNestedProxyingResolver(subschemaConfig, proxyingResolver) {
return function possiblyNestedProxyingResolver(parent, args, context, info) {
if (parent != null) {
const responseKey = getResponseKeyFromInfo(info);
if (isExternalObject(parent)) {
const unpathedErrors = getUnpathedErrors(parent);
const subschema = getSubschema(parent, responseKey);
if (subschemaConfig === subschema && parent[responseKey] !== void 0) {
return resolveExternalValue(
parent[responseKey],
unpathedErrors,
subschema,
context,
info
);
}
}
}
return proxyingResolver(parent, args, context, info);
};
}
function defaultCreateProxyingResolver({
subschemaConfig,
operation
}) {
return function proxyingResolver(_parent, _args, context, info) {
return delegateToSchema({
schema: subschemaConfig,
operation,
context,
info
});
};
}
const wrapSchema = memoize1(function wrapSchema2(subschemaConfig) {
const targetSchema = subschemaConfig.schema;
const proxyingResolvers = generateProxyingResolvers(subschemaConfig);
const schema = createWrappingSchema(targetSchema, proxyingResolvers);
const transformed = applySchemaTransforms(schema, subschemaConfig);
return transformed;
});
function createWrappingSchema(schema, proxyingResolvers) {
return mapSchema(schema, {
[MapperKind.ROOT_FIELD]: (fieldConfig, fieldName, typeName) => {
return {
...fieldConfig,
...proxyingResolvers[typeName]?.[fieldName]
};
},
[MapperKind.OBJECT_FIELD]: (fieldConfig) => {
return {
...fieldConfig,
resolve: defaultMergedResolver,
subscribe: void 0
};
},
[MapperKind.OBJECT_TYPE]: (type) => {
const config = type.toConfig();
return new GraphQLObjectType({
...config,
isTypeOf: void 0
});
},
[MapperKind.INTERFACE_TYPE]: (type) => {
const config = type.toConfig();
return new GraphQLInterfaceType({
...config,
resolveType: void 0
});
},
[MapperKind.UNION_TYPE]: (type) => {
const config = type.toConfig();
return new GraphQLUnionType({
...config,
resolveType: void 0
});
},
[MapperKind.ENUM_VALUE]: (valueConfig) => {
return {
...valueConfig,
value: void 0
};
}
});
}
class RenameTypes {
renamer;
map;
reverseMap;
renameBuiltins;
renameScalars;
constructor(renamer, options) {
this.renamer = renamer;
this.map = /* @__PURE__ */ Object.create(null);
this.reverseMap = /* @__PURE__ */ Object.create(null);
const { renameBuiltins = false, renameScalars = true } = options != null ? options : {};
this.renameBuiltins = renameBuiltins;
this.renameScalars = renameScalars;
}
transformSchema(originalWrappingSchema, _subschemaConfig) {
const typeNames = new Set(
Object.keys(originalWrappingSchema.getTypeMap())
);
return mapSchema(originalWrappingSchema, {
[MapperKind.TYPE]: (type) => {
if (isSpecifiedScalarType(type) && !this.renameBuiltins) {
return void 0;
}
if (isScalarType(type) && !this.renameScalars) {
return void 0;
}
const oldName = type.name;
const newName = this.renamer(oldName);
if (newName !== void 0 && newName !== oldName) {
if (typeNames.has(newName)) {
console.warn(
`New type name ${newName} for ${oldName} already exists in the schema. Skip renaming.`
);
return;
}
this.map[oldName] = newName;
this.reverseMap[newName] = oldName;
typeNames.delete(oldName);
typeNames.add(newName);
return renameType(type, newName);
}
return void 0;
},
[MapperKind.ROOT_OBJECT]() {
return void 0;
}
});
}
transformRequest(originalRequest, _delegationContext, _transformationContext) {
const document = visit(originalRequest.document, {
[Kind.NAMED_TYPE]: (node) => {
const name = node.name.value;
if (name in this.reverseMap) {
return {
...node,
name: {
kind: Kind.NAME,
value: this.reverseMap[name]
}
};
}
return void 0;
}
});
return {
...originalRequest,
document
};
}
transformResult(originalResult, _delegationContext, _transformationContext) {
return {
...originalResult,
data: visitData(originalResult.data, (object) => {
const typeName = object?.__typename;
if (typeName != null && typeName in this.map) {
object.__typename = this.map[typeName];
}
return object;
})
};
}
}
class FilterTypes {
filter;
constructor(filter) {
this.filter = filter;
}
transformSchema(originalWrappingSchema, _subschemaConfig) {
return mapSchema(originalWrappingSchema, {
[MapperKind.TYPE]: (type) => {
if (this.filter(type)) {
return void 0;
}
return null;
}
});
}
}
class RenameRootTypes {
renamer;
map;
reverseMap;
constructor(renamer) {
this.renamer = renamer;
this.map = /* @__PURE__ */ Object.create(null);
this.reverseMap = /* @__PURE__ */ Object.create(null);
}
transformSchema(originalWrappingSchema, _subschemaConfig) {
return mapSchema(originalWrappingSchema, {
[MapperKind.ROOT_OBJECT]: (type) => {
const oldName = type.name;
const newName = this.renamer(oldName);
if (newName !== void 0 && newName !== oldName) {
this.map[oldName] = newName;
this.reverseMap[newName] = oldName;
return renameType(type, newName);
}
return void 0;
}
});
}
transformRequest(originalRequest, _delegationContext, _transformationContext) {
const document = visit(originalRequest.document, {
[Kind.NAMED_TYPE]: (node) => {
const name = node.name.value;
if (name in this.reverseMap) {
return {
...node,
name: {
kind: Kind.NAME,
value: this.reverseMap[name]
}
};
}
return void 0;
}
});
return {
...originalRequest,
document
};
}
transformResult(originalResult, _delegationContext, _transformationContext) {
return {
...originalResult,
data: visitData(originalResult.data, (object) => {
const typeName = object?.__typename;
if (typeName != null && typeName in this.map) {
object.__typename = this.map[typeName];
}
return object;
})
};
}
}
class TransformCompositeFields {
fieldTransformer;
fieldNodeTransformer;
dataTransformer;
errorsTransformer;
transformedSchema;
typeInfo;
mapping;
subscriptionTypeName;
constructor(fieldTransformer, fieldNodeTransformer, dataTransformer, errorsTransformer) {
this.fieldTransformer = fieldTransformer;
this.fieldNodeTransformer = fieldNodeTransformer;
this.dataTransformer = dataTransformer;
this.errorsTransformer = errorsTransformer;
this.mapping = {};
}
_getTypeInfo() {
const typeInfo = this.typeInfo;
if (typeInfo === void 0) {
throw new Error(
`The TransformCompositeFields transform's "transformRequest" and "transformResult" methods cannot be used without first calling "transformSchema".`
);
}
return typeInfo;
}
transformSchema(originalWrappingSchema, _subschemaConfig) {
this.transformedSchema = mapSchema(originalWrappingSchema, {
[MapperKind.COMPOSITE_FIELD]: (fieldConfig, fieldName, typeName) => {
const transformedField = this.fieldTransformer(
typeName,
fieldName,
fieldConfig
);
if (Array.isArray(transformedField)) {
const newFieldName = transformedField[0];
if (newFieldName !== fieldName) {
if (!this.mapping[typeName]) {
this.mapping[typeName] = {};
}
this.mapping[typeName][newFieldName] = fieldName;
}
}
return transformedField;
}
});
this.typeInfo = getTypeInfo$1(this.transformedSchema);
this.subscriptionTypeName = originalWrappingSchema.getSubscriptionType()?.name;
return this.transformedSchema;
}
transformRequest(originalRequest, _delegationContext, transformationContext) {
const document = originalRequest.document;
return {
...originalRequest,
document: this.transformDocument(document, transformationContext)
};
}
transformResult(result, _delegationContext, transformationContext) {
const dataTransformer = this.dataTransformer;
if (dataTransformer != null) {
result.data = visitData(
result.data,
(value) => dataTransformer(value, transformationContext)
);
}
if (this.errorsTransformer != null && Array.isArray(result.errors)) {
result.errors = this.errorsTransformer(
result.errors,
transformationContext
);
}
return result;
}
transformDocument(document, transformationContext) {
const fragments = /* @__PURE__ */ Object.create(null);
for (const def of document.definitions) {
if (def.kind === Kind.FRAGMENT_DEFINITION) {
fragments[def.name.value] = def;
}
}
return visit(
document,
visitWithTypeInfo(this._getTypeInfo(), {
[Kind.SELECTION_SET]: {
leave: (node) => this.transformSelectionSet(
node,
this._getTypeInfo(),
fragments,
transformationContext
)
}
})
);
}
transformSelectionSet(node, typeInfo, fragments, transformationContext) {
const parentType = typeInfo.getParentType();
if (parentType == null) {
return void 0;
}
const parentTypeName = parentType.name;
let newSelections = [];
let isTypenameSelected = false;
for (const selection of node.selections) {
if (selection.kind !== Kind.FIELD) {
newSelections.push(selection);
continue;
}
if (selection.name.value === "__typename" && (!selection.alias || selection.alias.value === "__typename")) {
isTypenameSelected = true;
}
const newName = selection.name.value;
let transformedSelection;
if (this.fieldNodeTransformer == null) {
transformedSelection = selection;
} else {
transformedSelection = this.fieldNodeTransformer(
parentTypeName,
newName,
selection,
fragments,
transformationContext
);
transformedSelection = transformedSelection === void 0 ? selection : transformedSelection;
}
if (transformedSelection == null) {
continue;
} else if (Array.isArray(transformedSelection)) {
newSelections = newSelections.concat(transformedSelection);
continue;
} else if (transformedSelection.kind !== Kind.FIELD) {
newSelections.push(transformedSelection);
continue;
}
const typeMapping = this.mapping[parentTypeName];
if (typeMapping == null) {
newSelections.push(transformedSelection);
continue;
}
const oldName = this.mapping[parentTypeName][newName];
if (oldName == null) {
newSelections.push(transformedSelection);
continue;
}
newSelections.push({
...transformedSelection,
name: {
kind: Kind.NAME,
value: oldName
},
alias: {
kind: Kind.NAME,
value: transformedSelection.alias?.value ?? newName
}
});
}
if (!isTypenameSelected && (this.dataTransformer != null || this.errorsTransformer != null) && (this.subscriptionTypeName == null || parentTypeName !== this.subscriptionTypeName)) {
newSelections.push({
kind: Kind.FIELD,
name: {
kind: Kind.NAME,
value: "__typename"
}
});
}
return {
...node,
selections: newSelections
};
}
}
class TransformObjectFields {
objectFieldTransformer;
fieldNodeTransformer;
transformer;
constructor(objectFieldTransformer, fieldNodeTransformer) {
this.objectFieldTransformer = objectFieldTransformer;
this.fieldNodeTransformer = fieldNodeTransformer;
}
_getTransformer() {
const transformer = this.transformer;
if (transformer === void 0) {
throw new Error(
`The TransformObjectFields transform's "transformRequest" and "transformResult" methods cannot be used without first calling "transformSchema".`
);
}
return transformer;
}
transformSchema(originalWrappingSchema, subschemaConfig) {
const compositeToObjectFieldTransformer = (typeName, fieldName, fieldConfig) => {
if (isObjectType(originalWrappingSchema.getType(typeName))) {
return this.objectFieldTransformer(typeName, fieldName, fieldConfig);
}
return void 0;
};
this.transformer = new TransformCompositeFields(
compositeToObjectFieldTransformer,
this.fieldNodeTransformer
);
return this.transformer.transformSchema(
originalWrappingSchema,
subschemaConfig
);
}
transformRequest(originalRequest, delegationContext, transformationContext) {
return this._getTransformer().transformRequest(
originalRequest,
delegationContext,
transformationContext
);
}
transformResult(originalResult, delegationContext, transformationContext) {
return this._getTransformer().transformResult(
originalResult,
delegationContext,
transformationContext
);
}
}
class TransformRootFields {
rootFieldTransformer;
fieldNodeTransformer;
transformer;
constructor(rootFieldTransformer, fieldNodeTransformer) {
this.rootFieldTransformer = rootFieldTransformer;
this.fieldNodeTransformer = fieldNodeTransformer;
}
_getTransformer() {
const transformer = this.transformer;
if (transformer === void 0) {
throw new Error(
`The TransformRootFields transform's "transformRequest" and "transformResult" methods cannot be used without first calling "transformSchema".`
);
}
return transformer;
}
transformSchema(originalWrappingSchema, subschemaConfig) {
const rootToObjectFieldTransformer = (typeName, fieldName, fieldConfig) => {
if (typeName === originalWrappingSchema.getQueryType()?.name) {
return this.rootFieldTransformer("Query", fieldName, fieldConfig);
}
if (typeName === originalWrappingSchema.getMutationType()?.name) {
return this.rootFieldTransformer("Mutation", fieldName, fieldConfig);
}
if (typeName === originalWrappingSchema.getSubscriptionType()?.name) {
return this.rootFieldTransformer(
"Subscription",
fieldName,
fieldConfig
);
}
return void 0;
};
this.transformer = new TransformObjectFields(
rootToObjectFieldTransformer,
this.fieldNodeTransformer
);
return this.transformer.transformSchema(
originalWrappingSchema,
subschemaConfig
);
}
transformRequest(originalRequest, delegationContext, transformationContext) {
return this._getTransformer().transformRequest(
originalRequest,
delegationContext,
transformationContext
);
}
transformResult(originalResult, delegationContext, transformationContext) {
return this._getTransformer().transformResult(
originalResult,
delegationContext,
transformationContext
);
}
}
class RenameRootFields {
transformer;
constructor(renamer) {
this.transformer = new TransformRootFields(
(operation, fieldName, fieldConfig) => [renamer(operation, fieldName, fieldConfig), fieldConfig]
);
}
transformSchema(originalWrappingSchema, subschemaConfig) {
return this.transformer.transformSchema(
originalWrappingSchema,
subschemaConfig
);
}
transformRequest(originalRequest, delegationContext, transformationContext) {
return this.transformer.transformRequest(
originalRequest,
delegationContext,
transformationContext
);
}
}
class FilterRootFields {
transformer;
constructor(filter) {
this.transformer = new TransformRootFields(
(operation, fieldName, fieldConfig) => {
if (filter(operation, fieldName, fieldConfig)) {
return void 0;
}
return null;
}
);
}
transformSchema(originalWrappingSchema, subschemaConfig) {
return this.transformer.transformSchema(
originalWrappingSchema,
subschemaConfig
);
}
}
class RenameObjectFields {
transformer;
constructor(renamer) {
this.transformer = new TransformObjectFields(
(typeName, fieldName, fieldConfig) => [renamer(typeName, fieldName, fieldConfig), fieldConfig]
);
}
transformSchema(originalWrappingSchema, subschemaConfig) {
return this.transformer.transformSchema(
originalWrappingSchema,
subschemaConfig
);
}
transformRequest(originalRequest, delegationContext, transformationContext) {
return this.transformer.transformRequest(
originalRequest,
delegationContext,
transformationContext
);
}
}
class RenameObjectFieldArguments {
renamer;
transformer;
reverseMap;
transformedSchema;
constructor(renamer) {
this.renamer = renamer;
this.transformer = new TransformObjectFields(
(typeName, fieldName, fieldConfig) => {
const argsConfig = Object.fromEntries(
Object.entries(fieldConfig.args || []).map(([argName, conf]) => {
const newName = renamer(typeName, fieldName, argName);
if (newName !== void 0 && newName !== argName) {
if (newName != null) {
return [newName, conf];
}
}
return [argName, conf];
})
);
return [fieldName, { ...fieldConfig, args: argsConfig }];
},
(typeName, fieldName, inputFieldNode) => {
if (!(typeName in this.reverseMap)) {
return inputFieldNode;
}
if (!(fieldName in this.reverseMap[typeName])) {
return inputFieldNode;
}
const fieldNameMap = this.reverseMap[typeName][fieldName];
return {
...inputFieldNode,
arguments: (inputFieldNode.arguments || []).map((argNode) => {
return argNode.name.value in fieldNameMap ? {
...argNode,
name: {
...argNode.name,
value: fieldNameMap[argNode.name.value]
}
} : argNode;
})
};
}
);
this.reverseMap = /* @__PURE__ */ Object.create(null);
}
transformSchema(originalWrappingSchema, subschemaConfig) {
mapSchema(originalWrappingSchema, {
[MapperKind.OBJECT_FIELD]: (fieldConfig, fieldName, typeName) => {
Object.entries(fieldConfig.args || {}).forEach(([argName]) => {
const newName = this.renamer(typeName, fieldName, argName);
if (newName !== void 0 && newName !== fieldName) {
if (this.reverseMap[typeName] == null) {
this.reverseMap[typeName] = /* @__PURE__ */ Object.create(null);
}
if (this.reverseMap[typeName][fieldName] == null) {
this.reverseMap[typeName][fieldName] = /* @__PURE__ */ Object.create(null);
}
this.reverseMap[typeName][fieldName][newName] = argName;
}
});
return void 0;
},
[MapperKind.ROOT_OBJECT]() {
return void 0;
}
});
this.transformedSchema = this.transformer.transformSchema(
originalWrappingSchema,
subschemaConfig
);
return this.transformedSchema;
}
transformRequest(originalRequest, delegationContext, transformationContext) {
if (delegationContext.args != null) {
const operationType = (this.transformedSchema || delegationContext.transformedSchema).getRootType(delegationContext.operation);
if (operationType != null) {
const reverseFieldsMap = this.reverseMap[operationType.name];
if (reverseFieldsMap != null) {
const reverseArgsMap = reverseFieldsMap[delegationContext.fieldName];
if (reverseArgsMap) {
const newArgs = /* @__PURE__ */ Object.create(null);
for (const argName in delegationContext.args) {
const argument = delegationContext.args[argName];
const newArgName = reverseArgsMap[argName];
if (newArgName != null) {
newArgs[newArgName] = argument;
} else {
newArgs[argName] = argument;
}
}
delegationContext.args = newArgs;
}
}
}
}
return this.transformer.transformRequest(
originalRequest,
delegationContext,
transformationContext
);
}
}
class FilterObjectFields {
transformer;
constructor(filter) {
this.transformer = new TransformObjectFields(
(typeName, fieldName, fieldConfig) => filter(typeName, fieldName, fieldConfig) ? void 0 : null
);
}
transformSchema(originalWrappingSchema, subschemaConfig) {
return this.transformer.transformSchema(
originalWrappingSchema,
subschemaConfig
);
}
}
class TransformInterfaceFields {
interfaceFieldTransformer;
fieldNodeTransformer;
transformer;
constructor(interfaceFieldTransformer, fieldNodeTransformer) {
this.interfaceFieldTransformer = interfaceFieldTransformer;
this.fieldNodeTransformer = fieldNodeTransformer;
}
_getTransformer() {
const transformer = this.transformer;
if (transformer === void 0) {
throw new Error(
`The TransformInterfaceFields transform's "transformRequest" and "transformResult" methods cannot be used without first calling "transformSchema".`
);
}
return transformer;
}
transformSchema(originalWrappingSchema, subschemaConfig) {
const compositeToObjectFieldTransformer = (typeName, fieldName, fieldConfig) => {
if (isInterfaceType(originalWrappingSchema.getType(typeName))) {
return this.interfaceFieldTransformer(typeName, fieldName, fieldConfig);
}
return void 0;
};
this.transformer = new TransformCompositeFields(
compositeToObjectFieldTransformer,
this.fieldNodeTransformer
);
return this.transformer.transformSchema(
originalWrappingSchema,
subschemaConfig
);
}
transformRequest(originalRequest, delegationContext, transformationContext) {
return this._getTransformer().transformRequest(
originalRequest,
delegationContext,
transformationContext
);
}
transformResult(originalResult, delegationContext, transformationContext) {
return this._getTransformer().transformResult(
originalResult,
delegationContext,
transformationContext
);
}
}
class RenameInterfaceFields {
transformer;
constructor(renamer) {
this.transformer = new TransformInterfaceFields(
(typeName, fieldName, fieldConfig) => [renamer(typeName, fieldName, fieldConfig), fieldConfig]
);
}
transformSchema(originalWrappingSchema, subschemaConfig) {
return this.transformer.transformSchema(
originalWrappingSchema,
subschemaConfig
);
}
transformRequest(originalRequest, delegationContext, transformationContext) {
return this.transformer.transformRequest(
originalRequest,
delegationContext,
transformationContext
);
}
}
class FilterInterfaceFields {
transformer;
constructor(filter) {
this.transformer = new TransformInterfaceFields(
(typeName, fieldName, fieldConfig) => filter(typeName, fieldName, fieldConfig) ? void 0 : null
);
}
transformSchema(originalWrappingSchema, subschemaConfig) {
return this.transformer.transformSchema(
originalWrappingSchema,
subschemaConfig
);
}
}
class TransformInputObjectFields {
inputFieldTransformer;
inputFieldNodeTransformer;
inputObjectNodeTransformer;
transformedSchema;
mapping;
constructor(inputFieldTransformer, inputFieldNodeTransformer, inputObjectNodeTransformer) {
this.inputFieldTransformer = inputFieldTransformer;
this.inputFieldNodeTransformer = inputFieldNodeTransformer;
this.inputObjectNodeTransformer = inputObjectNodeTransformer;
this.mapping = {};
}
_getTransformedSchema() {
const transformedSchema = this.transformedSchema;
if (transformedSchema === void 0) {
throw new Error(
`The TransformInputObjectFields transform's "transformRequest" and "transformResult" methods cannot be used without first calling "transformSchema".`
);
}
return transformedSchema;
}
transformSchema(originalWrappingSchema, _subschemaConfig) {
this.transformedSchema = mapSchema(originalWrappingSchema, {
[MapperKind.INPUT_OBJECT_FIELD]: (inputFieldConfig, fieldName, typeName) => {
const transformedInputField = this.inputFieldTransformer(
typeName,
fieldName,
inputFieldConfig
);
if (Array.isArray(transformedInputField)) {
const newFieldName = transformedInputField[0];
if (newFieldName !== fieldName) {
if (!this.mapping[typeName]) {
this.mapping[typeName] = {};
}
this.mapping[typeName][newFieldName] = fieldName;
}
}
return transformedInputField;
}
});
return this.transformedSchema;
}
transformRequest(originalRequest, delegationContext, _transformationContext) {
const variableValues = originalRequest.variables ?? {};
const fragments = /* @__PURE__ */ Object.create(null);
const operations = [];
for (const def of originalRequest.document.definitions) {
if (def.kind === Kind.OPERATION_DEFINITION) {
operations.push(def);
} else if (def.kind === Kind.FRAGMENT_DEFINITION) {
fragments[def.name.value] = def;
}
}
for (const def of operations) {
const variableDefs = def.variableDefinitions;
if (variableDefs != null) {
for (const variableDef of variableDefs) {
const varName = variableDef.variable.name.value;
const varType = typeFromAST(
delegationContext.transformedSchema,
variableDef.type
);
if (!isInputType(varType)) {
continue;
}
variableValues[varName] = transformInputValue(
varType,
variableValues[varName],
void 0,
(type, originalValue) => {
const newValue = /* @__PURE__ */ Object.create(null);
const fields = type.getFields();
for (const key in originalValue) {
const field = fields[key];
if (field != null) {
const newFieldName = this.mapping[type.name]?.[field.name];
if (newFieldName != null) {
newValue[newFieldName] = originalValue[field.name];
} else {
newValue[field.name] = originalValue[field.name];
}
}
}
return newValue;
}
);
}
}
}
for (const def of originalRequest.document.definitions.filter(
(def2) => def2.kind === Kind.FRAGMENT_DEFINITION
)) {
fragments[def.name.value] = def;
}
const document = this.transformDocument(
originalRequest.document,
this.mapping,
this.inputFieldNodeTransformer,
this.inputObjectNodeTransformer,
originalRequest,
delegationContext
);
if (delegationContext.args != null) {
const targetRootType = getDefinedRootType(
delegationContext.transformedSchema,
delegationContext.operation
);
if (targetRootType) {
const targetField = targetRootType.getFields()[delegationContext.fieldName];
if (targetField) {
const newArgs = /* @__PURE__ */ Object.create(null);
for (const targetArg of targetField.args) {
if (targetArg.name in delegationContext.args) {
newArgs[targetArg.name] = transformInputValue(
targetArg.type,
delegationContext.args[targetArg.name],
void 0,
(type, originalValue) => {
const newValue = /* @__PURE__ */ Object.create(null);
const fields = type.getFields();
for (const key in originalValue) {
const field = fields[key];
if (field != null) {
const newFieldName = this.mapping[type.name]?.[field.name];
if (newFieldName != null) {
newValue[newFieldName] = originalValue[field.name];
} else {
newValue[field.name] = originalValue[field.name];
}
}
}
return newValue;
}
);
}
}
delegationContext.args = newArgs;
}
}
}
return {
...originalRequest,
document,
variables: variableValues
};
}
transformDocument(document, mapping, inputFieldNodeTransformer, inputObjectNodeTransformer, request, delegationContext) {
const typeInfo = getTypeInfo$1(this._getTransformedSchema());
const newDocument = visit(
document,
visitWithTypeInfo(typeInfo, {
[Kind.OBJECT]: {
leave: (node) => {
const parentType = typeInfo.getInputType();
if (parentType != null) {
const parentTypeName = getNamedType(parentType).name;
const newInputFields = [];
for (const inputField of node.fields) {
const newName = inputField.name.value;
const transformedInputField = inputFieldNodeTransformer != null ? inputFieldNodeTransformer(
parentTypeName,
newName,
inputField,
request,
delegationContext
) : inputField;
if (Array.isArray(transformedInputField)) {
for (const individualTransformedInputField of transformedInputField) {
const typeMapping2 = mapping[parentTypeName];
if (typeMapping2 == null) {
newInputFields.push(individualTransformedInputField);
continue;
}
const oldName2 = typeMapping2[newName];
if (oldName2 == null) {
newInputFields.push(individualTransformedInputField);
continue;
}
newInputFields.push({
...individualTransformedInputField,
name: {
...individualTransformedInputField.name,
value: oldName2
}
});
}
continue;
}
const typeMapping = mapping[parentTypeName];
if (typeMapping == null) {
newInputFields.push(transformedInputField);
continue;
}
const oldName = typeMapping[newName];
if (oldName == null) {
newInputFields.push(transformedInputField);
continue;
}
newInputFields.push({
...transformedInputField,
name: {
...transformedInputField.name,
value: oldName
}
});
}
const newNode = {
...node,
fields: newInputFields
};
return inputObjectNodeTransformer != null ? inputObjectNodeTransformer(
parentTypeName,
newNode,
request,
delegationContext
) : newNode;
}
}
}
})
);
return newDocument;
}
}
class RenameInputObjectFields {
renamer;
transformer;
reverseMap;
constructor(renamer) {
this.renamer = renamer;
this.transformer = new TransformInputObjectFields(
(typeName, inputFieldName, inputFieldConfig) => {
const newName = renamer(typeName, inputFieldName, inputFieldConfig);
if (newName !== void 0 && newName !== inputFieldName) {
const value = renamer(typeName, inputFieldName, inputFieldConfig);
if (value != null) {
return [value, inputFieldConfig];
}
}
return void 0;
},
(typeName, inputFieldName, inputFieldNode) => {
if (!(typeName in this.reverseMap)) {
return inputFieldNode;
}
const inputFieldNameMap = this.reverseMap[typeName];
if (!(inputFieldName in inputFieldNameMap)) {
return inputFieldNode;
}
return {
...inputFieldNode,
name: {
...inputFieldNode.name,
value: inputFieldNameMap[inputFieldName]
}
};
}
);
this.reverseMap = /* @__PURE__ */ Object.create(null);
}
transformSchema(originalWrappingSchema, subschemaConfig) {
mapSchema(originalWrappingSchema, {
[MapperKind.INPUT_OBJECT_FIELD]: (inputFieldConfig, fieldName, typeName) => {
const newName = this.renamer(typeName, fieldName, inputFieldConfig);
if (newName !== void 0 && newName !== fieldName) {
if (this.reverseMap[typeName] == null) {
this.reverseMap[typeName] = /* @__PURE__ */ Object.create(null);
}
this.reverseMap[typeName][newName] = fieldName;
}
return void 0;
},
[MapperKind.ROOT_OBJECT]() {
return void 0;
}
});
return this.transformer.transformSchema(
originalWrappingSchema,
subschemaConfig
);
}
transformRequest(originalRequest, delegationContext, transformationContext) {
return this.transformer.transformRequest(
originalRequest,
delegationContext,
transformationContext
);
}
}
class FilterInputObjectFields {
transformer;
constructor(filter, inputObjectNodeTransformer) {
this.transformer = new TransformInputObjectFields(
(typeName, fieldName, inputFieldConfig) => filter(typeName, fieldName, inputFieldConfig) ? void 0 : null,
void 0,
inputObjectNodeTransformer
);
}
transformSchema(originalWrappingSchema, subschemaConfig) {
return this.transformer.transformSchema(
originalWrappingSchema,
subschemaConfig
);
}
transformRequest(originalRequest, delegationContext, transformationContext) {
return this.transformer.transformRequest(
originalRequest,
delegationContext,
transformationContext
);
}
}
const getTypeInfo = memoize1(function getTypeInfo2(schema) {
return new TypeInfo(schema);
});
memoize2(function getTypeInfoWithType2(schema, type) {
return versionInfo.major < 16 ? new TypeInfo(schema, void 0, type) : new TypeInfo(schema, type);
});
class MapLeafValues {
inputValueTransformer;
outputValueTransformer;
resultVisitorMap;
typeInfo;
constructor(inputValueTransformer, outputValueTransformer) {
this.inputValueTransformer = inputValueTransformer;
this.outputValueTransformer = outputValueTransformer;
this.resultVisitorMap = /* @__PURE__ */ Object.create(null);
}
originalWrappingSchema;
transformSchema(originalWrappingSchema, _subschemaConfig) {
this.originalWrappingSchema = originalWrappingSchema;
const typeMap = originalWrappingSchema.getTypeMap();
for (const typeName in typeMap) {
const type = typeMap[typeName];
if (!typeName.startsWith("__")) {
if (isLeafType(type)) {
this.resultVisitorMap[typeName] = (value) => this.outputValueTransformer(typeName, value);
}
}
}
this.typeInfo = getTypeInfo(originalWrappingSchema);
return originalWrappingSchema;
}
transformRequest(originalRequest, delegationContext, transformationContext) {
const document = originalRequest.document;
const variableValues = originalRequest.variables ?? {};
const operations = document.definitions.filter(
(def) => def.kind === Kind.OPERATION_DEFINITION
);
const fragments = document.definitions.filter(
(def) => def.kind === Kind.FRAGMENT_DEFINITION
);
const newOperations = this.transformOperations(
operations,
variableValues,
delegationContext.args
);
const transformedRequest = {
...originalRequest,
document: {
...document,
definitions: [...newOperations, ...fragments]
},
variables: variableValues
};
transformationContext.transformedRequest = transformedRequest;
return transformedRequest;
}
transformResult(originalResult, _delegationContext, transformationContext) {
if (!this.originalWrappingSchema) {
throw new Error(
`The MapLeafValues transform's "transformRequest" and "transformResult" methods cannot be used without first calling "transformSchema".`
);
}
return visitResult(
originalResult,
transformationContext.transformedRequest,
this.originalWrappingSchema,
this.resultVisitorMap
);
}
transformOperations(operations, variableValues, args) {
if (this.typeInfo == null) {
throw new Error(
`The MapLeafValues transform's "transformRequest" and "transformResult" methods cannot be used without first calling "transformSchema".`
);
}
return operations.map((operation) => {
return visit(
operation,
visitWithTypeInfo(this.typeInfo, {
[Kind.FIELD]: (node) => this.transformFieldNode(node, variableValues, args)
})
);
});
}
transformFieldNode(field, variableValues, args) {
if (this.typeInfo == null) {
throw new Error(
`The MapLeafValues transform's "transformRequest" and "transformResult" methods cannot be used without first calling "transformSchema".`
);
}
const targetField = this.typeInfo.getFieldDef();
if (!targetField) {
return;
}
if (!targetField.name.startsWith("__")) {
const argumentNodes = field.arguments;
if (argumentNodes != null) {
const argumentNodeMap = argumentNodes.reduce(
(prev, argument) => ({
...prev,
[argument.name.value]: argument
}),
/* @__PURE__ */ Object.create(null)
);
for (const argument of targetField.args) {
const argName = argument.name;
const argType = argument.type;
if (args?.[argName] != null) {
args[argName] = transformInputValue(
argType,
args[argName],
(t, v) => {
const newValue = this.inputValueTransformer(t.name, v);
return newValue === void 0 ? v : newValue;
}
);
}
const argumentNode = argumentNodeMap[argName];
let value;
const argValue = argumentNode?.value;
if (argValue != null) {
value = valueFromAST(argValue, argType, variableValues);
if (value == null) {
value = valueFromASTUntyped(argValue, variableValues);
}
}
const transformedValue = transformInputValue(
argType,
value,
(t, v) => {
const newValue = this.inputValueTransformer(t.name, v);
return newValue === void 0 ? v : newValue;
}
);
if (argValue?.kind === Kind.VARIABLE) {
variableValues[argValue.name.value] = transformedValue;
} else {
let newValueNode;
try {
newValueNode = astFromValue(transformedValue, argType);
} catch (e) {
newValueNode = astFromValueUntyped(transformedValue);
}
if (newValueNode != null) {
argumentNodeMap[argName] = {
...argumentNode,
value: newValueNode
};
}
}
}
return {
...field,
arguments: Object.values(argumentNodeMap)
};
}
}
return void 0;
}
}
class TransformEnumValues {
enumValueTransformer;
transformer;
transformedSchema;
mapping;
reverseMapping;
noTransformation = true;
constructor(enumValueTransformer, inputValueTransformer, outputValueTransformer) {
this.enumValueTransformer = enumValueTransformer;
this.mapping = /* @__PURE__ */ Object.create(null);
this.reverseMapping = /* @__PURE__ */ Object.create(null);
this.transformer = new MapLeafValues(
generateValueTransformer(inputValueTransformer, this.reverseMapping),
generateValueTransformer(outputValueTransformer, this.mapping)
);
}
transformSchema(originalWrappingSchema, subschemaConfig) {
const mappingSchema = this.transformer.transformSchema(
originalWrappingSchema,
subschemaConfig
);
this.transformedSchema = mapSchema(mappingSchema, {
[MapperKind.ENUM_VALUE]: (valueConfig, typeName, _schema, externalValue) => this.transformEnumValue(typeName, externalValue, valueConfig),
[MapperKind.ARGUMENT]: (argConfig) => {
if (argConfig.defaultValue != null) {
const newValue = transformInputValue(
argConfig.type,
argConfig.defaultValue,
(type, value) => {
return this.mapping[type.name]?.[value] ?? value;
}
);
return {
...argConfig,
defaultValue: newValue
};
}
return void 0;
}
});
return this.transformedSchema;
}
transformRequest(originalRequest, delegationContext, transformationContext) {
if (this.noTransformation) {
return originalRequest;
}
return this.transformer.transformRequest(
originalRequest,
delegationContext,
transformationContext
);
}
transformResult(originalResult, delegationContext, transformationContext) {
if (this.noTransformation) {
return originalResult;
}
return this.transformer.transformResult(
originalResult,
delegationContext,
transformationContext
);
}
transformEnumValue(typeName, externalValue, enumValueConfig) {
const transformedEnumValue = this.enumValueTransformer(
typeName,
externalValue,
enumValueConfig
);
if (Array.isArray(transformedEnumValue)) {
const newExternalValue = transformedEnumValue[0];
if (newExternalValue !== externalValue) {
if (!this.mapping[typeName]) {
this.mapping[typeName] = /* @__PURE__ */ Object.create(null);
this.reverseMapping[typeName] = /* @__PURE__ */ Object.create(null);
}
this.mapping[typeName][externalValue] = newExternalValue;
this.reverseMapping[typeName][newExternalValue] = externalValue;
this.noTransformation = false;
}
return [
newExternalValue,
{
...transformedEnumValue[1],
value: void 0
}
];
}
return {
...transformedEnumValue,
value: void 0
};
}
}
function mapEnumValues(typeName, value, mapping) {
const newExternalValue = mapping[typeName]?.[value];
return newExternalValue != null ? newExternalValue : value;
}
function generateValueTransformer(valueTransformer, mapping) {
if (valueTransformer == null) {
return (typeName, value) => mapEnumValues(typeName, value, mapping);
} else {
return (typeName, value) => mapEnumValues(typeName, valueTransformer(typeName, value), mapping);
}
}
class TransformQuery {
path;
queryTransformer;
resultTransformer;
errorPathTransformer;
fragments;
constructor({
path,
queryTransformer,
resultTransformer = (result) => result,
errorPathTransformer = (errorPath) => [...errorPath],
fragments = {}
}) {
this.path = path;
const pollutingKeys = this.path.filter(isPrototypePollutingKey);
if (pollutingKeys.length > 0) {
throw new TypeError(
`Invalid path - cannot be a prototype polluting keys: ${pollutingKeys.join(".")}`
);
}
this.queryTransformer = queryTransformer;
this.resultTransformer = resultTransformer;
this.errorPathTransformer = errorPathTransformer;
this.fragments = fragments;
}
transformRequest(originalRequest, delegationContext, transformationContext) {
const pathLength = this.path.length;
let index = 0;
const operationAst = getOperationASTFromRequest(originalRequest);
const document = {
kind: Kind.DOCUMENT,
definitions: originalRequest.document.definitions.map((def) => {
if (def === operationAst) {
return visit(def, {
[Kind.FIELD]: {
enter: (node) => {
if (index === pathLength || node.name.value !== this.path[index]) {
return false;
}
index++;
if (index === pathLength) {
const selectionSet = this.queryTransformer(
node.selectionSet,
this.fragments,
delegationContext,
transformationContext
);
return {
...node,
selectionSet
};
}
return void 0;
},
leave: () => {
index--;
}
}
});
}
return def;
})
};
return {
...originalRequest,
document
};
}
transformResult(originalResult, delegationContext, transformationContext) {
const data = this.transformData(
originalResult.data,
delegationContext,
transformationContext
);
const errors = originalResult.errors;
return {
data,
errors: errors != null ? this.transformErrors(errors) : void 0
};
}
transformData(data, delegationContext, transformationContext) {
const leafIndex = this.path.length - 1;
let index = 0;
let newData = data;
if (newData) {
let next = this.path[index];
while (index < leafIndex) {
if (data[next]) {
newData = newData[next];
} else {
break;
}
index++;
next = this.path[index];
}
newData[next] = this.resultTransformer(
newData[next],
delegationContext,
transformationContext
);
}
return data;
}
transformErrors(errors) {
return errors.map((error) => {
const path = error.path;
if (path == null) {
return error;
}
let match = true;
let index = 0;
while (index < this.path.length) {
if (path[index] !== this.path[index]) {
matc