UNPKG

76.8 kBJavaScriptView Raw
1import { GraphQLObjectType, GraphQLInterfaceType, GraphQLUnionType, isSpecifiedScalarType, isScalarType, visit, Kind, TypeInfo, visitWithTypeInfo, isObjectType, isInterfaceType, typeFromAST, isInputType, isLeafType, valueFromAST, getNullableType, BREAK, parse, getIntrospectionQuery, buildClientSchema } from 'graphql';
2import { getRootTypeMap, getResponseKeyFromInfo, mapSchema, MapperKind, renameType, visitData, transformInputValue, visitResult, createVariableNameGenerator, updateArgument, relocatedError, getArgumentValues, valueMatchesCriteria, getDirectives, pruneSchema, selectObjectFields, appendObjectFields, modifyObjectFields, removeObjectFields, isAsyncIterable, AggregateError } from '@graphql-tools/utils';
3import { applySchemaTransforms, delegateToSchema, isExternalObject, getUnpathedErrors, getSubschema, resolveExternalValue, defaultMergedResolver } from '@graphql-tools/delegate';
4import { ValueOrPromise } from 'value-or-promise';
5
6function generateProxyingResolvers(subschemaConfig) {
7 var _a;
8 const targetSchema = subschemaConfig.schema;
9 const createProxyingResolver = (_a = subschemaConfig.createProxyingResolver) !== null && _a !== void 0 ? _a : defaultCreateProxyingResolver;
10 const transformedSchema = applySchemaTransforms(targetSchema, subschemaConfig);
11 const rootTypeMap = getRootTypeMap(targetSchema);
12 const resolvers = {};
13 for (const [operation, rootType] of rootTypeMap.entries()) {
14 const typeName = rootType.name;
15 const fields = rootType.getFields();
16 resolvers[typeName] = {};
17 for (const fieldName in fields) {
18 const proxyingResolver = createProxyingResolver({
19 subschemaConfig,
20 transformedSchema,
21 operation,
22 fieldName,
23 });
24 const finalResolver = createPossiblyNestedProxyingResolver(subschemaConfig, proxyingResolver);
25 if (operation === 'subscription') {
26 resolvers[typeName][fieldName] = {
27 subscribe: finalResolver,
28 resolve: identical,
29 };
30 }
31 else {
32 resolvers[typeName][fieldName] = {
33 resolve: finalResolver,
34 };
35 }
36 }
37 }
38 return resolvers;
39}
40function identical(value) {
41 return value;
42}
43function createPossiblyNestedProxyingResolver(subschemaConfig, proxyingResolver) {
44 return function possiblyNestedProxyingResolver(parent, args, context, info) {
45 if (parent != null) {
46 const responseKey = getResponseKeyFromInfo(info);
47 // Check to see if the parent contains a proxied result
48 if (isExternalObject(parent)) {
49 const unpathedErrors = getUnpathedErrors(parent);
50 const subschema = getSubschema(parent, responseKey);
51 // If there is a proxied result from this subschema, return it
52 // This can happen even for a root field when the root type ia
53 // also nested as a field within a different type.
54 if (subschemaConfig === subschema && parent[responseKey] !== undefined) {
55 return resolveExternalValue(parent[responseKey], unpathedErrors, subschema, context, info);
56 }
57 }
58 }
59 return proxyingResolver(parent, args, context, info);
60 };
61}
62function defaultCreateProxyingResolver({ subschemaConfig, operation, transformedSchema, }) {
63 return function proxyingResolver(_parent, _args, context, info) {
64 return delegateToSchema({
65 schema: subschemaConfig,
66 operation,
67 context,
68 info,
69 transformedSchema,
70 });
71 };
72}
73
74function wrapSchema(subschemaConfig) {
75 const targetSchema = subschemaConfig.schema;
76 const proxyingResolvers = generateProxyingResolvers(subschemaConfig);
77 const schema = createWrappingSchema(targetSchema, proxyingResolvers);
78 const transformedSchema = applySchemaTransforms(schema, subschemaConfig);
79 return applySchemaTransforms(schema, subschemaConfig, transformedSchema);
80}
81function createWrappingSchema(schema, proxyingResolvers) {
82 return mapSchema(schema, {
83 [MapperKind.ROOT_OBJECT]: type => {
84 var _a;
85 const config = type.toConfig();
86 const fieldConfigMap = config.fields;
87 for (const fieldName in fieldConfigMap) {
88 const field = fieldConfigMap[fieldName];
89 if (field == null) {
90 continue;
91 }
92 fieldConfigMap[fieldName] = {
93 ...field,
94 ...(_a = proxyingResolvers[type.name]) === null || _a === void 0 ? void 0 : _a[fieldName],
95 };
96 }
97 return new GraphQLObjectType(config);
98 },
99 [MapperKind.OBJECT_TYPE]: type => {
100 const config = type.toConfig();
101 config.isTypeOf = undefined;
102 for (const fieldName in config.fields) {
103 const field = config.fields[fieldName];
104 if (field == null) {
105 continue;
106 }
107 field.resolve = defaultMergedResolver;
108 field.subscribe = undefined;
109 }
110 return new GraphQLObjectType(config);
111 },
112 [MapperKind.INTERFACE_TYPE]: type => {
113 const config = type.toConfig();
114 delete config.resolveType;
115 return new GraphQLInterfaceType(config);
116 },
117 [MapperKind.UNION_TYPE]: type => {
118 const config = type.toConfig();
119 delete config.resolveType;
120 return new GraphQLUnionType(config);
121 },
122 });
123}
124
125class RenameTypes {
126 constructor(renamer, options) {
127 this.renamer = renamer;
128 this.map = Object.create(null);
129 this.reverseMap = Object.create(null);
130 const { renameBuiltins = false, renameScalars = true } = options != null ? options : {};
131 this.renameBuiltins = renameBuiltins;
132 this.renameScalars = renameScalars;
133 }
134 transformSchema(originalWrappingSchema, _subschemaConfig, _transformedSchema) {
135 return mapSchema(originalWrappingSchema, {
136 [MapperKind.TYPE]: (type) => {
137 if (isSpecifiedScalarType(type) && !this.renameBuiltins) {
138 return undefined;
139 }
140 if (isScalarType(type) && !this.renameScalars) {
141 return undefined;
142 }
143 const oldName = type.name;
144 const newName = this.renamer(oldName);
145 if (newName !== undefined && newName !== oldName) {
146 this.map[oldName] = newName;
147 this.reverseMap[newName] = oldName;
148 return renameType(type, newName);
149 }
150 },
151 [MapperKind.ROOT_OBJECT]() {
152 return undefined;
153 },
154 });
155 }
156 transformRequest(originalRequest, _delegationContext, _transformationContext) {
157 const document = visit(originalRequest.document, {
158 [Kind.NAMED_TYPE]: (node) => {
159 const name = node.name.value;
160 if (name in this.reverseMap) {
161 return {
162 ...node,
163 name: {
164 kind: Kind.NAME,
165 value: this.reverseMap[name],
166 },
167 };
168 }
169 },
170 });
171 return {
172 ...originalRequest,
173 document,
174 };
175 }
176 transformResult(originalResult, _delegationContext, _transformationContext) {
177 return {
178 ...originalResult,
179 data: visitData(originalResult.data, object => {
180 const typeName = object === null || object === void 0 ? void 0 : object.__typename;
181 if (typeName != null && typeName in this.map) {
182 object.__typename = this.map[typeName];
183 }
184 return object;
185 }),
186 };
187 }
188}
189
190class FilterTypes {
191 constructor(filter) {
192 this.filter = filter;
193 }
194 transformSchema(originalWrappingSchema, _subschemaConfig, _transformedSchema) {
195 return mapSchema(originalWrappingSchema, {
196 [MapperKind.TYPE]: (type) => {
197 if (this.filter(type)) {
198 return undefined;
199 }
200 return null;
201 },
202 });
203 }
204}
205
206class RenameRootTypes {
207 constructor(renamer) {
208 this.renamer = renamer;
209 this.map = Object.create(null);
210 this.reverseMap = Object.create(null);
211 }
212 transformSchema(originalWrappingSchema, _subschemaConfig, _transformedSchema) {
213 return mapSchema(originalWrappingSchema, {
214 [MapperKind.ROOT_OBJECT]: type => {
215 const oldName = type.name;
216 const newName = this.renamer(oldName);
217 if (newName !== undefined && newName !== oldName) {
218 this.map[oldName] = newName;
219 this.reverseMap[newName] = oldName;
220 return renameType(type, newName);
221 }
222 },
223 });
224 }
225 transformRequest(originalRequest, _delegationContext, _transformationContext) {
226 const document = visit(originalRequest.document, {
227 [Kind.NAMED_TYPE]: (node) => {
228 const name = node.name.value;
229 if (name in this.reverseMap) {
230 return {
231 ...node,
232 name: {
233 kind: Kind.NAME,
234 value: this.reverseMap[name],
235 },
236 };
237 }
238 },
239 });
240 return {
241 ...originalRequest,
242 document,
243 };
244 }
245 transformResult(originalResult, _delegationContext, _transformationContext) {
246 return {
247 ...originalResult,
248 data: visitData(originalResult.data, object => {
249 const typeName = object === null || object === void 0 ? void 0 : object.__typename;
250 if (typeName != null && typeName in this.map) {
251 object.__typename = this.map[typeName];
252 }
253 return object;
254 }),
255 };
256 }
257}
258
259class TransformCompositeFields {
260 constructor(fieldTransformer, fieldNodeTransformer, dataTransformer, errorsTransformer) {
261 this.fieldTransformer = fieldTransformer;
262 this.fieldNodeTransformer = fieldNodeTransformer;
263 this.dataTransformer = dataTransformer;
264 this.errorsTransformer = errorsTransformer;
265 this.mapping = {};
266 }
267 _getTypeInfo() {
268 const typeInfo = this.typeInfo;
269 if (typeInfo === undefined) {
270 throw new Error(`The TransformCompositeFields transform's "transformRequest" and "transformResult" methods cannot be used without first calling "transformSchema".`);
271 }
272 return typeInfo;
273 }
274 transformSchema(originalWrappingSchema, _subschemaConfig, _transformedSchema) {
275 var _a;
276 this.transformedSchema = mapSchema(originalWrappingSchema, {
277 [MapperKind.COMPOSITE_FIELD]: (fieldConfig, fieldName, typeName) => {
278 const transformedField = this.fieldTransformer(typeName, fieldName, fieldConfig);
279 if (Array.isArray(transformedField)) {
280 const newFieldName = transformedField[0];
281 if (newFieldName !== fieldName) {
282 if (!(typeName in this.mapping)) {
283 this.mapping[typeName] = {};
284 }
285 this.mapping[typeName][newFieldName] = fieldName;
286 }
287 }
288 return transformedField;
289 },
290 });
291 this.typeInfo = new TypeInfo(this.transformedSchema);
292 this.subscriptionTypeName = (_a = originalWrappingSchema.getSubscriptionType()) === null || _a === void 0 ? void 0 : _a.name;
293 return this.transformedSchema;
294 }
295 transformRequest(originalRequest, _delegationContext, transformationContext) {
296 const document = originalRequest.document;
297 return {
298 ...originalRequest,
299 document: this.transformDocument(document, transformationContext),
300 };
301 }
302 transformResult(result, _delegationContext, transformationContext) {
303 const dataTransformer = this.dataTransformer;
304 if (dataTransformer != null) {
305 result.data = visitData(result.data, value => dataTransformer(value, transformationContext));
306 }
307 if (this.errorsTransformer != null && Array.isArray(result.errors)) {
308 result.errors = this.errorsTransformer(result.errors, transformationContext);
309 }
310 return result;
311 }
312 transformDocument(document, transformationContext) {
313 const fragments = Object.create(null);
314 for (const def of document.definitions) {
315 if (def.kind === Kind.FRAGMENT_DEFINITION) {
316 fragments[def.name.value] = def;
317 }
318 }
319 return visit(document, visitWithTypeInfo(this._getTypeInfo(), {
320 leave: {
321 [Kind.SELECTION_SET]: node => this.transformSelectionSet(node, this._getTypeInfo(), fragments, transformationContext),
322 },
323 }));
324 }
325 transformSelectionSet(node, typeInfo, fragments, transformationContext) {
326 var _a, _b;
327 const parentType = typeInfo.getParentType();
328 if (parentType == null) {
329 return undefined;
330 }
331 const parentTypeName = parentType.name;
332 let newSelections = [];
333 for (const selection of node.selections) {
334 if (selection.kind !== Kind.FIELD) {
335 newSelections.push(selection);
336 continue;
337 }
338 const newName = selection.name.value;
339 // See https://github.com/ardatan/graphql-tools/issues/2282
340 if ((this.dataTransformer != null || this.errorsTransformer != null) &&
341 (this.subscriptionTypeName == null || parentTypeName !== this.subscriptionTypeName)) {
342 newSelections.push({
343 kind: Kind.FIELD,
344 name: {
345 kind: Kind.NAME,
346 value: '__typename',
347 },
348 });
349 }
350 let transformedSelection;
351 if (this.fieldNodeTransformer == null) {
352 transformedSelection = selection;
353 }
354 else {
355 transformedSelection = this.fieldNodeTransformer(parentTypeName, newName, selection, fragments, transformationContext);
356 transformedSelection = transformedSelection === undefined ? selection : transformedSelection;
357 }
358 if (transformedSelection == null) {
359 continue;
360 }
361 else if (Array.isArray(transformedSelection)) {
362 newSelections = newSelections.concat(transformedSelection);
363 continue;
364 }
365 else if (transformedSelection.kind !== Kind.FIELD) {
366 newSelections.push(transformedSelection);
367 continue;
368 }
369 const typeMapping = this.mapping[parentTypeName];
370 if (typeMapping == null) {
371 newSelections.push(transformedSelection);
372 continue;
373 }
374 const oldName = this.mapping[parentTypeName][newName];
375 if (oldName == null) {
376 newSelections.push(transformedSelection);
377 continue;
378 }
379 newSelections.push({
380 ...transformedSelection,
381 name: {
382 kind: Kind.NAME,
383 value: oldName,
384 },
385 alias: {
386 kind: Kind.NAME,
387 value: (_b = (_a = transformedSelection.alias) === null || _a === void 0 ? void 0 : _a.value) !== null && _b !== void 0 ? _b : newName,
388 },
389 });
390 }
391 return {
392 ...node,
393 selections: newSelections,
394 };
395 }
396}
397
398class TransformObjectFields {
399 constructor(objectFieldTransformer, fieldNodeTransformer) {
400 this.objectFieldTransformer = objectFieldTransformer;
401 this.fieldNodeTransformer = fieldNodeTransformer;
402 }
403 _getTransformer() {
404 const transformer = this.transformer;
405 if (transformer === undefined) {
406 throw new Error(`The TransformObjectFields transform's "transformRequest" and "transformResult" methods cannot be used without first calling "transformSchema".`);
407 }
408 return transformer;
409 }
410 transformSchema(originalWrappingSchema, subschemaConfig, transformedSchema) {
411 const compositeToObjectFieldTransformer = (typeName, fieldName, fieldConfig) => {
412 if (isObjectType(originalWrappingSchema.getType(typeName))) {
413 return this.objectFieldTransformer(typeName, fieldName, fieldConfig);
414 }
415 return undefined;
416 };
417 this.transformer = new TransformCompositeFields(compositeToObjectFieldTransformer, this.fieldNodeTransformer);
418 return this.transformer.transformSchema(originalWrappingSchema, subschemaConfig, transformedSchema);
419 }
420 transformRequest(originalRequest, delegationContext, transformationContext) {
421 return this._getTransformer().transformRequest(originalRequest, delegationContext, transformationContext);
422 }
423 transformResult(originalResult, delegationContext, transformationContext) {
424 return this._getTransformer().transformResult(originalResult, delegationContext, transformationContext);
425 }
426}
427
428class TransformRootFields {
429 constructor(rootFieldTransformer, fieldNodeTransformer) {
430 this.rootFieldTransformer = rootFieldTransformer;
431 this.fieldNodeTransformer = fieldNodeTransformer;
432 }
433 _getTransformer() {
434 const transformer = this.transformer;
435 if (transformer === undefined) {
436 throw new Error(`The TransformRootFields transform's "transformRequest" and "transformResult" methods cannot be used without first calling "transformSchema".`);
437 }
438 return transformer;
439 }
440 transformSchema(originalWrappingSchema, subschemaConfig, transformedSchema) {
441 const rootToObjectFieldTransformer = (typeName, fieldName, fieldConfig) => {
442 var _a, _b, _c;
443 if (typeName === ((_a = originalWrappingSchema.getQueryType()) === null || _a === void 0 ? void 0 : _a.name)) {
444 return this.rootFieldTransformer('Query', fieldName, fieldConfig);
445 }
446 if (typeName === ((_b = originalWrappingSchema.getMutationType()) === null || _b === void 0 ? void 0 : _b.name)) {
447 return this.rootFieldTransformer('Mutation', fieldName, fieldConfig);
448 }
449 if (typeName === ((_c = originalWrappingSchema.getSubscriptionType()) === null || _c === void 0 ? void 0 : _c.name)) {
450 return this.rootFieldTransformer('Subscription', fieldName, fieldConfig);
451 }
452 return undefined;
453 };
454 this.transformer = new TransformObjectFields(rootToObjectFieldTransformer, this.fieldNodeTransformer);
455 return this.transformer.transformSchema(originalWrappingSchema, subschemaConfig, transformedSchema);
456 }
457 transformRequest(originalRequest, delegationContext, transformationContext) {
458 return this._getTransformer().transformRequest(originalRequest, delegationContext, transformationContext);
459 }
460 transformResult(originalResult, delegationContext, transformationContext) {
461 return this._getTransformer().transformResult(originalResult, delegationContext, transformationContext);
462 }
463}
464
465class RenameRootFields {
466 constructor(renamer) {
467 this.transformer = new TransformRootFields((operation, fieldName, fieldConfig) => [renamer(operation, fieldName, fieldConfig), fieldConfig]);
468 }
469 transformSchema(originalWrappingSchema, subschemaConfig, transformedSchema) {
470 return this.transformer.transformSchema(originalWrappingSchema, subschemaConfig, transformedSchema);
471 }
472 transformRequest(originalRequest, delegationContext, transformationContext) {
473 return this.transformer.transformRequest(originalRequest, delegationContext, transformationContext);
474 }
475}
476
477class FilterRootFields {
478 constructor(filter) {
479 this.transformer = new TransformRootFields((operation, fieldName, fieldConfig) => {
480 if (filter(operation, fieldName, fieldConfig)) {
481 return undefined;
482 }
483 return null;
484 });
485 }
486 transformSchema(originalWrappingSchema, subschemaConfig, transformedSchema) {
487 return this.transformer.transformSchema(originalWrappingSchema, subschemaConfig, transformedSchema);
488 }
489}
490
491class RenameObjectFields {
492 constructor(renamer) {
493 this.transformer = new TransformObjectFields((typeName, fieldName, fieldConfig) => [
494 renamer(typeName, fieldName, fieldConfig),
495 fieldConfig,
496 ]);
497 }
498 transformSchema(originalWrappingSchema, subschemaConfig, transformedSchema) {
499 return this.transformer.transformSchema(originalWrappingSchema, subschemaConfig, transformedSchema);
500 }
501 transformRequest(originalRequest, delegationContext, transformationContext) {
502 return this.transformer.transformRequest(originalRequest, delegationContext, transformationContext);
503 }
504}
505
506class FilterObjectFields {
507 constructor(filter) {
508 this.transformer = new TransformObjectFields((typeName, fieldName, fieldConfig) => filter(typeName, fieldName, fieldConfig) ? undefined : null);
509 }
510 transformSchema(originalWrappingSchema, subschemaConfig, transformedSchema) {
511 return this.transformer.transformSchema(originalWrappingSchema, subschemaConfig, transformedSchema);
512 }
513}
514
515class TransformInterfaceFields {
516 constructor(interfaceFieldTransformer, fieldNodeTransformer) {
517 this.interfaceFieldTransformer = interfaceFieldTransformer;
518 this.fieldNodeTransformer = fieldNodeTransformer;
519 }
520 _getTransformer() {
521 const transformer = this.transformer;
522 if (transformer === undefined) {
523 throw new Error(`The TransformInterfaceFields transform's "transformRequest" and "transformResult" methods cannot be used without first calling "transformSchema".`);
524 }
525 return transformer;
526 }
527 transformSchema(originalWrappingSchema, subschemaConfig, transformedSchema) {
528 const compositeToObjectFieldTransformer = (typeName, fieldName, fieldConfig) => {
529 if (isInterfaceType(originalWrappingSchema.getType(typeName))) {
530 return this.interfaceFieldTransformer(typeName, fieldName, fieldConfig);
531 }
532 return undefined;
533 };
534 this.transformer = new TransformCompositeFields(compositeToObjectFieldTransformer, this.fieldNodeTransformer);
535 return this.transformer.transformSchema(originalWrappingSchema, subschemaConfig, transformedSchema);
536 }
537 transformRequest(originalRequest, delegationContext, transformationContext) {
538 return this._getTransformer().transformRequest(originalRequest, delegationContext, transformationContext);
539 }
540 transformResult(originalResult, delegationContext, transformationContext) {
541 return this._getTransformer().transformResult(originalResult, delegationContext, transformationContext);
542 }
543}
544
545class RenameInterfaceFields {
546 constructor(renamer) {
547 this.transformer = new TransformInterfaceFields((typeName, fieldName, fieldConfig) => [
548 renamer(typeName, fieldName, fieldConfig),
549 fieldConfig,
550 ]);
551 }
552 transformSchema(originalWrappingSchema, subschemaConfig, transformedSchema) {
553 return this.transformer.transformSchema(originalWrappingSchema, subschemaConfig, transformedSchema);
554 }
555 transformRequest(originalRequest, delegationContext, transformationContext) {
556 return this.transformer.transformRequest(originalRequest, delegationContext, transformationContext);
557 }
558}
559
560class FilterInterfaceFields {
561 constructor(filter) {
562 this.transformer = new TransformInterfaceFields((typeName, fieldName, fieldConfig) => filter(typeName, fieldName, fieldConfig) ? undefined : null);
563 }
564 transformSchema(originalWrappingSchema, subschemaConfig, transformedSchema) {
565 return this.transformer.transformSchema(originalWrappingSchema, subschemaConfig, transformedSchema);
566 }
567}
568
569class TransformInputObjectFields {
570 constructor(inputFieldTransformer, inputFieldNodeTransformer, inputObjectNodeTransformer) {
571 this.inputFieldTransformer = inputFieldTransformer;
572 this.inputFieldNodeTransformer = inputFieldNodeTransformer;
573 this.inputObjectNodeTransformer = inputObjectNodeTransformer;
574 this.mapping = {};
575 }
576 _getTransformedSchema() {
577 const transformedSchema = this.transformedSchema;
578 if (transformedSchema === undefined) {
579 throw new Error(`The TransformInputObjectFields transform's "transformRequest" and "transformResult" methods cannot be used without first calling "transformSchema".`);
580 }
581 return transformedSchema;
582 }
583 transformSchema(originalWrappingSchema, _subschemaConfig, _transformedSchema) {
584 this.transformedSchema = mapSchema(originalWrappingSchema, {
585 [MapperKind.INPUT_OBJECT_FIELD]: (inputFieldConfig, fieldName, typeName) => {
586 const transformedInputField = this.inputFieldTransformer(typeName, fieldName, inputFieldConfig);
587 if (Array.isArray(transformedInputField)) {
588 const newFieldName = transformedInputField[0];
589 if (newFieldName !== fieldName) {
590 if (!(typeName in this.mapping)) {
591 this.mapping[typeName] = {};
592 }
593 this.mapping[typeName][newFieldName] = fieldName;
594 }
595 }
596 return transformedInputField;
597 },
598 });
599 return this.transformedSchema;
600 }
601 transformRequest(originalRequest, delegationContext, _transformationContext) {
602 var _a;
603 const variableValues = (_a = originalRequest.variables) !== null && _a !== void 0 ? _a : {};
604 const fragments = Object.create(null);
605 const operations = [];
606 for (const def of originalRequest.document.definitions) {
607 if (def.kind === Kind.OPERATION_DEFINITION) {
608 operations.push(def);
609 }
610 else if (def.kind === Kind.FRAGMENT_DEFINITION) {
611 fragments[def.name.value] = def;
612 }
613 }
614 for (const def of operations) {
615 const variableDefs = def.variableDefinitions;
616 if (variableDefs != null) {
617 for (const variableDef of variableDefs) {
618 const varName = variableDef.variable.name.value;
619 if (variableDef.type.kind !== Kind.NAMED_TYPE) {
620 throw new Error(`Expected ${variableDef.type} to be a named type`);
621 }
622 // requirement for 'as NamedTypeNode' appears to be a bug within types, as function should take any TypeNode
623 const varType = typeFromAST(delegationContext.transformedSchema, variableDef.type);
624 if (!isInputType(varType)) {
625 throw new Error(`Expected ${varType} to be an input type`);
626 }
627 variableValues[varName] = transformInputValue(varType, variableValues[varName], undefined, (type, originalValue) => {
628 var _a;
629 const newValue = Object.create(null);
630 const fields = type.getFields();
631 for (const key in originalValue) {
632 const field = fields[key];
633 if (field != null) {
634 const newFieldName = (_a = this.mapping[type.name]) === null || _a === void 0 ? void 0 : _a[field.name];
635 if (newFieldName != null) {
636 newValue[newFieldName] = originalValue[field.name];
637 }
638 else {
639 newValue[field.name] = originalValue[field.name];
640 }
641 }
642 }
643 return newValue;
644 });
645 }
646 }
647 }
648 for (const def of originalRequest.document.definitions.filter(def => def.kind === Kind.FRAGMENT_DEFINITION)) {
649 fragments[def.name.value] = def;
650 }
651 const document = this.transformDocument(originalRequest.document, this.mapping, this.inputFieldNodeTransformer, this.inputObjectNodeTransformer, originalRequest, delegationContext);
652 return {
653 ...originalRequest,
654 document,
655 variables: variableValues,
656 };
657 }
658 transformDocument(document, mapping, inputFieldNodeTransformer, inputObjectNodeTransformer, request, delegationContext) {
659 const typeInfo = new TypeInfo(this._getTransformedSchema());
660 const newDocument = visit(document, visitWithTypeInfo(typeInfo, {
661 leave: {
662 [Kind.OBJECT]: (node) => {
663 // The casting is kind of legit here as we are in a visitor
664 const parentType = typeInfo.getInputType();
665 if (parentType != null) {
666 const parentTypeName = parentType.name;
667 const newInputFields = [];
668 for (const inputField of node.fields) {
669 const newName = inputField.name.value;
670 const transformedInputField = inputFieldNodeTransformer != null
671 ? inputFieldNodeTransformer(parentTypeName, newName, inputField, request, delegationContext)
672 : inputField;
673 if (Array.isArray(transformedInputField)) {
674 for (const individualTransformedInputField of transformedInputField) {
675 const typeMapping = mapping[parentTypeName];
676 if (typeMapping == null) {
677 newInputFields.push(individualTransformedInputField);
678 continue;
679 }
680 const oldName = typeMapping[newName];
681 if (oldName == null) {
682 newInputFields.push(individualTransformedInputField);
683 continue;
684 }
685 newInputFields.push({
686 ...individualTransformedInputField,
687 name: {
688 ...individualTransformedInputField.name,
689 value: oldName,
690 },
691 });
692 }
693 continue;
694 }
695 const typeMapping = mapping[parentTypeName];
696 if (typeMapping == null) {
697 newInputFields.push(transformedInputField);
698 continue;
699 }
700 const oldName = typeMapping[newName];
701 if (oldName == null) {
702 newInputFields.push(transformedInputField);
703 continue;
704 }
705 newInputFields.push({
706 ...transformedInputField,
707 name: {
708 ...transformedInputField.name,
709 value: oldName,
710 },
711 });
712 }
713 const newNode = {
714 ...node,
715 fields: newInputFields,
716 };
717 return inputObjectNodeTransformer != null
718 ? inputObjectNodeTransformer(parentTypeName, newNode, request, delegationContext)
719 : newNode;
720 }
721 },
722 },
723 }));
724 return newDocument;
725 }
726}
727
728class RenameInputObjectFields {
729 constructor(renamer) {
730 this.renamer = renamer;
731 this.transformer = new TransformInputObjectFields((typeName, inputFieldName, inputFieldConfig) => {
732 const newName = renamer(typeName, inputFieldName, inputFieldConfig);
733 if (newName !== undefined && newName !== inputFieldName) {
734 const value = renamer(typeName, inputFieldName, inputFieldConfig);
735 if (value != null) {
736 return [value, inputFieldConfig];
737 }
738 }
739 }, (typeName, inputFieldName, inputFieldNode) => {
740 if (!(typeName in this.reverseMap)) {
741 return inputFieldNode;
742 }
743 const inputFieldNameMap = this.reverseMap[typeName];
744 if (!(inputFieldName in inputFieldNameMap)) {
745 return inputFieldNode;
746 }
747 return {
748 ...inputFieldNode,
749 name: {
750 ...inputFieldNode.name,
751 value: inputFieldNameMap[inputFieldName],
752 },
753 };
754 });
755 this.reverseMap = Object.create(null);
756 }
757 transformSchema(originalWrappingSchema, subschemaConfig, transformedSchema) {
758 mapSchema(originalWrappingSchema, {
759 [MapperKind.INPUT_OBJECT_FIELD]: (inputFieldConfig, fieldName, typeName) => {
760 const newName = this.renamer(typeName, fieldName, inputFieldConfig);
761 if (newName !== undefined && newName !== fieldName) {
762 if (this.reverseMap[typeName] == null) {
763 this.reverseMap[typeName] = Object.create(null);
764 }
765 this.reverseMap[typeName][newName] = fieldName;
766 }
767 return undefined;
768 },
769 [MapperKind.ROOT_OBJECT]() {
770 return undefined;
771 },
772 });
773 return this.transformer.transformSchema(originalWrappingSchema, subschemaConfig, transformedSchema);
774 }
775 transformRequest(originalRequest, delegationContext, transformationContext) {
776 return this.transformer.transformRequest(originalRequest, delegationContext, transformationContext);
777 }
778}
779
780class FilterInputObjectFields {
781 constructor(filter, inputObjectNodeTransformer) {
782 this.transformer = new TransformInputObjectFields((typeName, fieldName, inputFieldConfig) => filter(typeName, fieldName, inputFieldConfig) ? undefined : null, undefined, inputObjectNodeTransformer);
783 }
784 transformSchema(originalWrappingSchema, subschemaConfig, transformedSchema) {
785 return this.transformer.transformSchema(originalWrappingSchema, subschemaConfig, transformedSchema);
786 }
787 transformRequest(originalRequest, delegationContext, transformationContext) {
788 return this.transformer.transformRequest(originalRequest, delegationContext, transformationContext);
789 }
790}
791
792class MapLeafValues {
793 constructor(inputValueTransformer, outputValueTransformer) {
794 this.inputValueTransformer = inputValueTransformer;
795 this.outputValueTransformer = outputValueTransformer;
796 this.resultVisitorMap = Object.create(null);
797 }
798 _getTypeInfo() {
799 const typeInfo = this.typeInfo;
800 if (typeInfo === undefined) {
801 throw new Error(`The MapLeafValues transform's "transformRequest" and "transformResult" methods cannot be used without first calling "transformSchema".`);
802 }
803 return typeInfo;
804 }
805 _getOriginalWrappingSchema() {
806 const originalWrappingSchema = this.originalWrappingSchema;
807 if (originalWrappingSchema === undefined) {
808 throw new Error(`The MapLeafValues transform's "transformRequest" and "transformResult" methods cannot be used without first calling "transformSchema".`);
809 }
810 return originalWrappingSchema;
811 }
812 transformSchema(originalWrappingSchema, _subschemaConfig, _transformedSchema) {
813 this.originalWrappingSchema = originalWrappingSchema;
814 const typeMap = originalWrappingSchema.getTypeMap();
815 for (const typeName in typeMap) {
816 const type = typeMap[typeName];
817 if (!typeName.startsWith('__')) {
818 if (isLeafType(type)) {
819 this.resultVisitorMap[typeName] = (value) => this.outputValueTransformer(typeName, value);
820 }
821 }
822 }
823 this.typeInfo = new TypeInfo(originalWrappingSchema);
824 return originalWrappingSchema;
825 }
826 transformRequest(originalRequest, _delegationContext, transformationContext) {
827 const document = originalRequest.document;
828 const variableValues = (originalRequest.variables = {});
829 const operations = document.definitions.filter(def => def.kind === Kind.OPERATION_DEFINITION);
830 const fragments = document.definitions.filter(def => def.kind === Kind.FRAGMENT_DEFINITION);
831 const newOperations = this.transformOperations(operations, variableValues);
832 const transformedRequest = {
833 ...originalRequest,
834 document: {
835 ...document,
836 definitions: [...newOperations, ...fragments],
837 },
838 variables: variableValues,
839 };
840 transformationContext.transformedRequest = transformedRequest;
841 return transformedRequest;
842 }
843 transformResult(originalResult, _delegationContext, transformationContext) {
844 return visitResult(originalResult, transformationContext.transformedRequest, this._getOriginalWrappingSchema(), this.resultVisitorMap);
845 }
846 transformOperations(operations, variableValues) {
847 return operations.map((operation) => {
848 var _a;
849 const variableDefinitionMap = ((_a = operation.variableDefinitions) !== null && _a !== void 0 ? _a : []).reduce((prev, def) => ({
850 ...prev,
851 [def.variable.name.value]: def,
852 }), {});
853 const newOperation = visit(operation, visitWithTypeInfo(this._getTypeInfo(), {
854 [Kind.FIELD]: node => this.transformFieldNode(node, variableDefinitionMap, variableValues),
855 }));
856 return {
857 ...newOperation,
858 variableDefinitions: Object.values(variableDefinitionMap),
859 };
860 });
861 }
862 transformFieldNode(field, variableDefinitionMap, variableValues) {
863 const targetField = this._getTypeInfo().getFieldDef();
864 const generateVariableName = createVariableNameGenerator(variableDefinitionMap);
865 if (!targetField.name.startsWith('__')) {
866 const argumentNodes = field.arguments;
867 if (argumentNodes != null) {
868 const argumentNodeMap = argumentNodes.reduce((prev, argument) => ({
869 ...prev,
870 [argument.name.value]: argument,
871 }), Object.create(null));
872 for (const argument of targetField.args) {
873 const argName = argument.name;
874 const argType = argument.type;
875 const argumentNode = argumentNodeMap[argName];
876 const argValue = argumentNode === null || argumentNode === void 0 ? void 0 : argumentNode.value;
877 let value;
878 if (argValue != null) {
879 value = valueFromAST(argValue, argType, variableValues);
880 }
881 updateArgument(argumentNodeMap, variableDefinitionMap, variableValues, argName, generateVariableName(argName), argType, transformInputValue(argType, value, (t, v) => {
882 const newValue = this.inputValueTransformer(t.name, v);
883 return newValue === undefined ? v : newValue;
884 }));
885 }
886 return {
887 ...field,
888 arguments: Object.values(argumentNodeMap),
889 };
890 }
891 }
892 }
893}
894
895class TransformEnumValues {
896 constructor(enumValueTransformer, inputValueTransformer, outputValueTransformer) {
897 this.enumValueTransformer = enumValueTransformer;
898 this.mapping = Object.create(null);
899 this.reverseMapping = Object.create(null);
900 this.transformer = new MapLeafValues(generateValueTransformer(inputValueTransformer, this.reverseMapping), generateValueTransformer(outputValueTransformer, this.mapping));
901 }
902 transformSchema(originalWrappingSchema, subschemaConfig, transformedSchema) {
903 const mappingSchema = this.transformer.transformSchema(originalWrappingSchema, subschemaConfig, transformedSchema);
904 this.transformedSchema = mapSchema(mappingSchema, {
905 [MapperKind.ENUM_VALUE]: (valueConfig, typeName, _schema, externalValue) => this.transformEnumValue(typeName, externalValue, valueConfig),
906 });
907 return this.transformedSchema;
908 }
909 transformRequest(originalRequest, delegationContext, transformationContext) {
910 return this.transformer.transformRequest(originalRequest, delegationContext, transformationContext);
911 }
912 transformResult(originalResult, delegationContext, transformationContext) {
913 return this.transformer.transformResult(originalResult, delegationContext, transformationContext);
914 }
915 transformEnumValue(typeName, externalValue, enumValueConfig) {
916 const transformedEnumValue = this.enumValueTransformer(typeName, externalValue, enumValueConfig);
917 if (Array.isArray(transformedEnumValue)) {
918 const newExternalValue = transformedEnumValue[0];
919 if (newExternalValue !== externalValue) {
920 if (!(typeName in this.mapping)) {
921 this.mapping[typeName] = Object.create(null);
922 this.reverseMapping[typeName] = Object.create(null);
923 }
924 this.mapping[typeName][externalValue] = newExternalValue;
925 this.reverseMapping[typeName][newExternalValue] = externalValue;
926 }
927 }
928 return transformedEnumValue;
929 }
930}
931function mapEnumValues(typeName, value, mapping) {
932 var _a;
933 const newExternalValue = (_a = mapping[typeName]) === null || _a === void 0 ? void 0 : _a[value];
934 return newExternalValue != null ? newExternalValue : value;
935}
936function generateValueTransformer(valueTransformer, mapping) {
937 if (valueTransformer == null) {
938 return (typeName, value) => mapEnumValues(typeName, value, mapping);
939 }
940 else {
941 return (typeName, value) => mapEnumValues(typeName, valueTransformer(typeName, value), mapping);
942 }
943}
944
945class TransformQuery {
946 constructor({ path, queryTransformer, resultTransformer = result => result, errorPathTransformer = errorPath => [...errorPath], fragments = {}, }) {
947 this.path = path;
948 this.queryTransformer = queryTransformer;
949 this.resultTransformer = resultTransformer;
950 this.errorPathTransformer = errorPathTransformer;
951 this.fragments = fragments;
952 }
953 transformRequest(originalRequest, delegationContext, transformationContext) {
954 const pathLength = this.path.length;
955 let index = 0;
956 const document = visit(originalRequest.document, {
957 [Kind.FIELD]: {
958 enter: node => {
959 if (index === pathLength || node.name.value !== this.path[index] || node.selectionSet == null) {
960 return false;
961 }
962 index++;
963 if (index === pathLength) {
964 const selectionSet = this.queryTransformer(node.selectionSet, this.fragments, delegationContext, transformationContext);
965 return {
966 ...node,
967 selectionSet,
968 };
969 }
970 },
971 leave: () => {
972 index--;
973 },
974 },
975 });
976 return {
977 ...originalRequest,
978 document,
979 };
980 }
981 transformResult(originalResult, delegationContext, transformationContext) {
982 const data = this.transformData(originalResult.data, delegationContext, transformationContext);
983 const errors = originalResult.errors;
984 return {
985 data,
986 errors: errors != null ? this.transformErrors(errors) : undefined,
987 };
988 }
989 transformData(data, delegationContext, transformationContext) {
990 const leafIndex = this.path.length - 1;
991 let index = 0;
992 let newData = data;
993 if (newData) {
994 let next = this.path[index];
995 while (index < leafIndex) {
996 if (data[next]) {
997 newData = newData[next];
998 }
999 else {
1000 break;
1001 }
1002 index++;
1003 next = this.path[index];
1004 }
1005 newData[next] = this.resultTransformer(newData[next], delegationContext, transformationContext);
1006 }
1007 return newData;
1008 }
1009 transformErrors(errors) {
1010 return errors.map(error => {
1011 const path = error.path;
1012 if (path == null) {
1013 return error;
1014 }
1015 let match = true;
1016 let index = 0;
1017 while (index < this.path.length) {
1018 if (path[index] !== this.path[index]) {
1019 match = false;
1020 break;
1021 }
1022 index++;
1023 }
1024 const newPath = match ? path.slice(0, index).concat(this.errorPathTransformer(path.slice(index))) : path;
1025 return relocatedError(error, newPath);
1026 });
1027 }
1028}
1029
1030class FilterObjectFieldDirectives {
1031 constructor(filter) {
1032 this.filter = filter;
1033 }
1034 transformSchema(originalWrappingSchema, subschemaConfig, transformedSchema) {
1035 const transformer = new TransformObjectFields((_typeName, _fieldName, fieldConfig) => {
1036 var _a, _b, _c, _d;
1037 const keepDirectives = (_c = (_b = (_a = fieldConfig.astNode) === null || _a === void 0 ? void 0 : _a.directives) === null || _b === void 0 ? void 0 : _b.filter(dir => {
1038 const directiveDef = originalWrappingSchema.getDirective(dir.name.value);
1039 const directiveValue = directiveDef ? getArgumentValues(directiveDef, dir) : undefined;
1040 return this.filter(dir.name.value, directiveValue);
1041 })) !== null && _c !== void 0 ? _c : [];
1042 if (((_d = fieldConfig.astNode) === null || _d === void 0 ? void 0 : _d.directives) != null &&
1043 keepDirectives.length !== fieldConfig.astNode.directives.length) {
1044 fieldConfig = {
1045 ...fieldConfig,
1046 astNode: {
1047 ...fieldConfig.astNode,
1048 directives: keepDirectives,
1049 },
1050 };
1051 return fieldConfig;
1052 }
1053 });
1054 return transformer.transformSchema(originalWrappingSchema, subschemaConfig, transformedSchema);
1055 }
1056}
1057
1058class RemoveObjectFieldDirectives {
1059 constructor(directiveName, args = {}) {
1060 this.transformer = new FilterObjectFieldDirectives((dirName, dirValue) => {
1061 return !(valueMatchesCriteria(dirName, directiveName) && valueMatchesCriteria(dirValue, args));
1062 });
1063 }
1064 transformSchema(originalWrappingSchema, subschemaConfig, transformedSchema) {
1065 return this.transformer.transformSchema(originalWrappingSchema, subschemaConfig, transformedSchema);
1066 }
1067}
1068
1069class RemoveObjectFieldsWithDirective {
1070 constructor(directiveName, args = {}) {
1071 this.directiveName = directiveName;
1072 this.args = args;
1073 }
1074 transformSchema(originalWrappingSchema, subschemaConfig, transformedSchema) {
1075 const transformer = new FilterObjectFields((_typeName, _fieldName, fieldConfig) => {
1076 const directives = getDirectives(originalWrappingSchema, fieldConfig);
1077 return !directives.some(directive => valueMatchesCriteria(directive.name, this.directiveName) && valueMatchesCriteria(directive.args, this.args));
1078 });
1079 return transformer.transformSchema(originalWrappingSchema, subschemaConfig, transformedSchema);
1080 }
1081}
1082
1083class RemoveObjectFieldDeprecations {
1084 constructor(reason) {
1085 const args = { reason };
1086 this.removeDirectives = new FilterObjectFieldDirectives((dirName, dirValue) => {
1087 return !(dirName === 'deprecated' && valueMatchesCriteria(dirValue, args));
1088 });
1089 this.removeDeprecations = new TransformObjectFields((_typeName, _fieldName, fieldConfig) => {
1090 if (fieldConfig.deprecationReason && valueMatchesCriteria(fieldConfig.deprecationReason, reason)) {
1091 fieldConfig = { ...fieldConfig };
1092 delete fieldConfig.deprecationReason;
1093 }
1094 return fieldConfig;
1095 });
1096 }
1097 transformSchema(originalWrappingSchema, subschemaConfig, transformedSchema) {
1098 return this.removeDeprecations.transformSchema(this.removeDirectives.transformSchema(originalWrappingSchema, subschemaConfig, transformedSchema), subschemaConfig, transformedSchema);
1099 }
1100}
1101
1102class RemoveObjectFieldsWithDeprecation {
1103 constructor(reason) {
1104 this.transformer = new FilterObjectFields((_typeName, _fieldName, fieldConfig) => {
1105 if (fieldConfig.deprecationReason) {
1106 return !valueMatchesCriteria(fieldConfig.deprecationReason, reason);
1107 }
1108 return true;
1109 });
1110 }
1111 transformSchema(originalWrappingSchema, subschemaConfig, transformedSchema) {
1112 return this.transformer.transformSchema(originalWrappingSchema, subschemaConfig, transformedSchema);
1113 }
1114}
1115
1116class PruneTypes {
1117 constructor(options = {}) {
1118 this.options = options;
1119 }
1120 transformSchema(originalWrappingSchema, _subschemaConfig, _transformedSchema) {
1121 return pruneSchema(originalWrappingSchema, this.options);
1122 }
1123}
1124
1125class MapFields {
1126 constructor(fieldNodeTransformerMap, objectValueTransformerMap, errorsTransformer) {
1127 this.fieldNodeTransformerMap = fieldNodeTransformerMap;
1128 this.objectValueTransformerMap = objectValueTransformerMap;
1129 this.errorsTransformer = errorsTransformer;
1130 }
1131 _getTransformer() {
1132 const transformer = this.transformer;
1133 if (transformer === undefined) {
1134 throw new Error(`The MapFields transform's "transformRequest" and "transformResult" methods cannot be used without first calling "transformSchema".`);
1135 }
1136 return transformer;
1137 }
1138 transformSchema(originalWrappingSchema, subschemaConfig, transformedSchema) {
1139 var _a;
1140 const subscriptionTypeName = (_a = originalWrappingSchema.getSubscriptionType()) === null || _a === void 0 ? void 0 : _a.name;
1141 const objectValueTransformerMap = this.objectValueTransformerMap;
1142 this.transformer = new TransformCompositeFields(() => undefined, (typeName, fieldName, fieldNode, fragments, transformationContext) => {
1143 const typeTransformers = this.fieldNodeTransformerMap[typeName];
1144 if (typeTransformers == null) {
1145 return undefined;
1146 }
1147 const fieldNodeTransformer = typeTransformers[fieldName];
1148 if (fieldNodeTransformer == null) {
1149 return undefined;
1150 }
1151 return fieldNodeTransformer(fieldNode, fragments, transformationContext);
1152 }, objectValueTransformerMap != null
1153 ? (data, transformationContext) => {
1154 if (data == null) {
1155 return data;
1156 }
1157 let typeName = data.__typename;
1158 if (typeName == null) {
1159 // see https://github.com/ardatan/graphql-tools/issues/2282
1160 typeName = subscriptionTypeName;
1161 if (typeName == null) {
1162 return data;
1163 }
1164 }
1165 const transformer = objectValueTransformerMap[typeName];
1166 if (transformer == null) {
1167 return data;
1168 }
1169 return transformer(data, transformationContext);
1170 }
1171 : undefined, this.errorsTransformer != null ? this.errorsTransformer : undefined);
1172 return this.transformer.transformSchema(originalWrappingSchema, subschemaConfig, transformedSchema);
1173 }
1174 transformRequest(originalRequest, delegationContext, transformationContext) {
1175 return this._getTransformer().transformRequest(originalRequest, delegationContext, transformationContext);
1176 }
1177 transformResult(originalResult, delegationContext, transformationContext) {
1178 return this._getTransformer().transformResult(originalResult, delegationContext, transformationContext);
1179 }
1180}
1181
1182class WrapFields {
1183 constructor(outerTypeName, wrappingFieldNames, wrappingTypeNames, fieldNames, prefix = 'gqtld') {
1184 this.outerTypeName = outerTypeName;
1185 this.wrappingFieldNames = wrappingFieldNames;
1186 this.wrappingTypeNames = wrappingTypeNames;
1187 this.numWraps = wrappingFieldNames.length;
1188 this.fieldNames = fieldNames;
1189 const remainingWrappingFieldNames = this.wrappingFieldNames.slice();
1190 const outerMostWrappingFieldName = remainingWrappingFieldNames.shift();
1191 if (outerMostWrappingFieldName == null) {
1192 throw new Error(`Cannot wrap fields, no wrapping field name provided.`);
1193 }
1194 this.transformer = new MapFields({
1195 [outerTypeName]: {
1196 [outerMostWrappingFieldName]: (fieldNode, fragments, transformationContext) => hoistFieldNodes({
1197 fieldNode,
1198 path: remainingWrappingFieldNames,
1199 fieldNames,
1200 fragments,
1201 transformationContext: transformationContext,
1202 prefix,
1203 }),
1204 },
1205 }, {
1206 [outerTypeName]: (value, context) => dehoistValue(value, context),
1207 }, (errors, context) => dehoistErrors(errors, context));
1208 }
1209 transformSchema(originalWrappingSchema, subschemaConfig, transformedSchema) {
1210 var _a, _b, _c, _d;
1211 const fieldNames = this.fieldNames;
1212 const targetFieldConfigMap = selectObjectFields(originalWrappingSchema, this.outerTypeName, !fieldNames ? () => true : fieldName => fieldNames.includes(fieldName));
1213 const newTargetFieldConfigMap = Object.create(null);
1214 for (const fieldName in targetFieldConfigMap) {
1215 const field = targetFieldConfigMap[fieldName];
1216 const newField = {
1217 ...field,
1218 resolve: defaultMergedResolver,
1219 };
1220 newTargetFieldConfigMap[fieldName] = newField;
1221 }
1222 let wrapIndex = this.numWraps - 1;
1223 let wrappingTypeName = this.wrappingTypeNames[wrapIndex];
1224 let wrappingFieldName = this.wrappingFieldNames[wrapIndex];
1225 let newSchema = appendObjectFields(originalWrappingSchema, wrappingTypeName, newTargetFieldConfigMap);
1226 for (wrapIndex--; wrapIndex > -1; wrapIndex--) {
1227 const nextWrappingTypeName = this.wrappingTypeNames[wrapIndex];
1228 newSchema = appendObjectFields(newSchema, nextWrappingTypeName, {
1229 [wrappingFieldName]: {
1230 type: newSchema.getType(wrappingTypeName),
1231 resolve: defaultMergedResolver,
1232 },
1233 });
1234 wrappingTypeName = nextWrappingTypeName;
1235 wrappingFieldName = this.wrappingFieldNames[wrapIndex];
1236 }
1237 const wrappingRootField = this.outerTypeName === ((_a = originalWrappingSchema.getQueryType()) === null || _a === void 0 ? void 0 : _a.name) ||
1238 this.outerTypeName === ((_b = originalWrappingSchema.getMutationType()) === null || _b === void 0 ? void 0 : _b.name);
1239 let resolve;
1240 if (transformedSchema) {
1241 if (wrappingRootField) {
1242 const targetSchema = subschemaConfig.schema;
1243 const operation = this.outerTypeName === ((_c = targetSchema.getQueryType()) === null || _c === void 0 ? void 0 : _c.name) ? 'query' : 'mutation';
1244 const createProxyingResolver = (_d = subschemaConfig.createProxyingResolver) !== null && _d !== void 0 ? _d : defaultCreateProxyingResolver;
1245 resolve = createProxyingResolver({
1246 subschemaConfig,
1247 transformedSchema,
1248 operation,
1249 fieldName: wrappingFieldName,
1250 });
1251 }
1252 else {
1253 resolve = defaultMergedResolver;
1254 }
1255 }
1256 [newSchema] = modifyObjectFields(newSchema, this.outerTypeName, fieldName => !!newTargetFieldConfigMap[fieldName], {
1257 [wrappingFieldName]: {
1258 type: newSchema.getType(wrappingTypeName),
1259 resolve,
1260 },
1261 });
1262 return this.transformer.transformSchema(newSchema, subschemaConfig, transformedSchema);
1263 }
1264 transformRequest(originalRequest, delegationContext, transformationContext) {
1265 transformationContext.nextIndex = 0;
1266 transformationContext.paths = Object.create(null);
1267 return this.transformer.transformRequest(originalRequest, delegationContext, transformationContext);
1268 }
1269 transformResult(originalResult, delegationContext, transformationContext) {
1270 return this.transformer.transformResult(originalResult, delegationContext, transformationContext);
1271 }
1272}
1273function collectFields(selectionSet, fragments, fields = [], visitedFragmentNames = {}) {
1274 if (selectionSet != null) {
1275 for (const selection of selectionSet.selections) {
1276 switch (selection.kind) {
1277 case Kind.FIELD:
1278 fields.push(selection);
1279 break;
1280 case Kind.INLINE_FRAGMENT:
1281 collectFields(selection.selectionSet, fragments, fields, visitedFragmentNames);
1282 break;
1283 case Kind.FRAGMENT_SPREAD: {
1284 const fragmentName = selection.name.value;
1285 if (!visitedFragmentNames[fragmentName]) {
1286 visitedFragmentNames[fragmentName] = true;
1287 collectFields(fragments[fragmentName].selectionSet, fragments, fields, visitedFragmentNames);
1288 }
1289 break;
1290 }
1291 }
1292 }
1293 }
1294 return fields;
1295}
1296function aliasFieldNode(fieldNode, str) {
1297 return {
1298 ...fieldNode,
1299 alias: {
1300 kind: Kind.NAME,
1301 value: str,
1302 },
1303 };
1304}
1305function hoistFieldNodes({ fieldNode, fieldNames, path, fragments, transformationContext, prefix, index = 0, wrappingPath = [], }) {
1306 const alias = fieldNode.alias != null ? fieldNode.alias.value : fieldNode.name.value;
1307 let newFieldNodes = [];
1308 if (index < path.length) {
1309 const pathSegment = path[index];
1310 for (const possibleFieldNode of collectFields(fieldNode.selectionSet, fragments)) {
1311 if (possibleFieldNode.name.value === pathSegment) {
1312 const newWrappingPath = wrappingPath.concat([alias]);
1313 newFieldNodes = newFieldNodes.concat(hoistFieldNodes({
1314 fieldNode: possibleFieldNode,
1315 fieldNames,
1316 path,
1317 fragments,
1318 transformationContext,
1319 prefix,
1320 index: index + 1,
1321 wrappingPath: newWrappingPath,
1322 }));
1323 }
1324 }
1325 }
1326 else {
1327 for (const possibleFieldNode of collectFields(fieldNode.selectionSet, fragments)) {
1328 if (!fieldNames || fieldNames.includes(possibleFieldNode.name.value)) {
1329 const nextIndex = transformationContext.nextIndex;
1330 transformationContext.nextIndex++;
1331 const indexingAlias = `__${prefix}${nextIndex}__`;
1332 transformationContext.paths[indexingAlias] = {
1333 pathToField: wrappingPath.concat([alias]),
1334 alias: possibleFieldNode.alias != null ? possibleFieldNode.alias.value : possibleFieldNode.name.value,
1335 };
1336 newFieldNodes.push(aliasFieldNode(possibleFieldNode, indexingAlias));
1337 }
1338 }
1339 }
1340 return newFieldNodes;
1341}
1342function dehoistValue(originalValue, context) {
1343 if (originalValue == null) {
1344 return originalValue;
1345 }
1346 const newValue = Object.create(null);
1347 for (const alias in originalValue) {
1348 let obj = newValue;
1349 const path = context.paths[alias];
1350 if (path == null) {
1351 newValue[alias] = originalValue[alias];
1352 continue;
1353 }
1354 const pathToField = path.pathToField;
1355 const fieldAlias = path.alias;
1356 for (const key of pathToField) {
1357 obj = obj[key] = obj[key] || Object.create(null);
1358 }
1359 obj[fieldAlias] = originalValue[alias];
1360 }
1361 return newValue;
1362}
1363function dehoistErrors(errors, context) {
1364 if (errors === undefined) {
1365 return undefined;
1366 }
1367 return errors.map(error => {
1368 const originalPath = error.path;
1369 if (originalPath == null) {
1370 return error;
1371 }
1372 let newPath = [];
1373 for (const pathSegment of originalPath) {
1374 if (typeof pathSegment !== 'string') {
1375 newPath.push(pathSegment);
1376 continue;
1377 }
1378 const path = context.paths[pathSegment];
1379 if (path == null) {
1380 newPath.push(pathSegment);
1381 continue;
1382 }
1383 newPath = newPath.concat(path.pathToField, [path.alias]);
1384 }
1385 return relocatedError(error, newPath);
1386 });
1387}
1388
1389class WrapType {
1390 constructor(outerTypeName, innerTypeName, fieldName) {
1391 this.transformer = new WrapFields(outerTypeName, [fieldName], [innerTypeName]);
1392 }
1393 transformSchema(originalWrappingSchema, subschemaConfig, transformedSchema) {
1394 return this.transformer.transformSchema(originalWrappingSchema, subschemaConfig, transformedSchema);
1395 }
1396 transformRequest(originalRequest, delegationContext, transformationContext) {
1397 return this.transformer.transformRequest(originalRequest, delegationContext, transformationContext);
1398 }
1399 transformResult(originalResult, delegationContext, transformationContext) {
1400 return this.transformer.transformResult(originalResult, delegationContext, transformationContext);
1401 }
1402}
1403
1404class HoistField {
1405 constructor(typeName, pathConfig, newFieldName, alias = '__gqtlw__') {
1406 this.typeName = typeName;
1407 this.newFieldName = newFieldName;
1408 const path = pathConfig.map(segment => (typeof segment === 'string' ? segment : segment.fieldName));
1409 this.argFilters = pathConfig.map((segment, index) => {
1410 if (typeof segment === 'string' || segment.argFilter == null) {
1411 return index === pathConfig.length - 1 ? () => true : () => false;
1412 }
1413 return segment.argFilter;
1414 });
1415 const pathToField = path.slice();
1416 const oldFieldName = pathToField.pop();
1417 if (oldFieldName == null) {
1418 throw new Error(`Cannot hoist field to ${newFieldName} on type ${typeName}, no path provided.`);
1419 }
1420 this.oldFieldName = oldFieldName;
1421 this.pathToField = pathToField;
1422 const argLevels = Object.create(null);
1423 this.transformer = new MapFields({
1424 [typeName]: {
1425 [newFieldName]: fieldNode => wrapFieldNode(renameFieldNode(fieldNode, oldFieldName), pathToField, alias, argLevels),
1426 },
1427 }, {
1428 [typeName]: value => unwrapValue(value, alias),
1429 }, errors => (errors != null ? unwrapErrors(errors, alias) : undefined));
1430 this.argLevels = argLevels;
1431 }
1432 transformSchema(originalWrappingSchema, subschemaConfig, transformedSchema) {
1433 var _a, _b, _c, _d;
1434 const argsMap = Object.create(null);
1435 const innerType = this.pathToField.reduce((acc, pathSegment, index) => {
1436 const field = acc.getFields()[pathSegment];
1437 for (const arg of field.args) {
1438 if (this.argFilters[index](arg)) {
1439 argsMap[arg.name] = arg;
1440 this.argLevels[arg.name] = index;
1441 }
1442 }
1443 return getNullableType(field.type);
1444 }, originalWrappingSchema.getType(this.typeName));
1445 let [newSchema, targetFieldConfigMap] = removeObjectFields(originalWrappingSchema, innerType.name, fieldName => fieldName === this.oldFieldName);
1446 const targetField = targetFieldConfigMap[this.oldFieldName];
1447 let resolve;
1448 if (transformedSchema) {
1449 const hoistingToRootField = this.typeName === ((_a = originalWrappingSchema.getQueryType()) === null || _a === void 0 ? void 0 : _a.name) ||
1450 this.typeName === ((_b = originalWrappingSchema.getMutationType()) === null || _b === void 0 ? void 0 : _b.name);
1451 if (hoistingToRootField) {
1452 const targetSchema = subschemaConfig.schema;
1453 const operation = this.typeName === ((_c = targetSchema.getQueryType()) === null || _c === void 0 ? void 0 : _c.name) ? 'query' : 'mutation';
1454 const createProxyingResolver = (_d = subschemaConfig.createProxyingResolver) !== null && _d !== void 0 ? _d : defaultCreateProxyingResolver;
1455 resolve = createProxyingResolver({
1456 subschemaConfig,
1457 transformedSchema,
1458 operation,
1459 fieldName: this.newFieldName,
1460 });
1461 }
1462 else {
1463 resolve = defaultMergedResolver;
1464 }
1465 }
1466 const newTargetField = {
1467 ...targetField,
1468 resolve: resolve,
1469 };
1470 const level = this.pathToField.length;
1471 const args = targetField.args;
1472 if (args != null) {
1473 for (const argName in args) {
1474 const argConfig = args[argName];
1475 if (argConfig == null) {
1476 continue;
1477 }
1478 const arg = {
1479 ...argConfig,
1480 name: argName,
1481 description: argConfig.description,
1482 defaultValue: argConfig.defaultValue,
1483 extensions: argConfig.extensions,
1484 astNode: argConfig.astNode,
1485 };
1486 if (this.argFilters[level](arg)) {
1487 argsMap[argName] = arg;
1488 this.argLevels[arg.name] = level;
1489 }
1490 }
1491 }
1492 newTargetField.args = argsMap;
1493 newSchema = appendObjectFields(newSchema, this.typeName, {
1494 [this.newFieldName]: newTargetField,
1495 });
1496 return this.transformer.transformSchema(newSchema, subschemaConfig, transformedSchema);
1497 }
1498 transformRequest(originalRequest, delegationContext, transformationContext) {
1499 return this.transformer.transformRequest(originalRequest, delegationContext, transformationContext);
1500 }
1501 transformResult(originalResult, delegationContext, transformationContext) {
1502 return this.transformer.transformResult(originalResult, delegationContext, transformationContext);
1503 }
1504}
1505function wrapFieldNode(fieldNode, path, alias, argLevels) {
1506 return path.reduceRight((acc, fieldName, index) => ({
1507 kind: Kind.FIELD,
1508 alias: {
1509 kind: Kind.NAME,
1510 value: alias,
1511 },
1512 name: {
1513 kind: Kind.NAME,
1514 value: fieldName,
1515 },
1516 selectionSet: {
1517 kind: Kind.SELECTION_SET,
1518 selections: [acc],
1519 },
1520 arguments: fieldNode.arguments != null
1521 ? fieldNode.arguments.filter(arg => argLevels[arg.name.value] === index)
1522 : undefined,
1523 }), {
1524 ...fieldNode,
1525 arguments: fieldNode.arguments != null
1526 ? fieldNode.arguments.filter(arg => argLevels[arg.name.value] === path.length)
1527 : undefined,
1528 });
1529}
1530function renameFieldNode(fieldNode, name) {
1531 return {
1532 ...fieldNode,
1533 alias: {
1534 kind: Kind.NAME,
1535 value: fieldNode.alias != null ? fieldNode.alias.value : fieldNode.name.value,
1536 },
1537 name: {
1538 kind: Kind.NAME,
1539 value: name,
1540 },
1541 };
1542}
1543function unwrapValue(originalValue, alias) {
1544 let newValue = originalValue;
1545 let object = newValue[alias];
1546 while (object != null) {
1547 newValue = object;
1548 object = newValue[alias];
1549 }
1550 delete originalValue[alias];
1551 Object.assign(originalValue, newValue);
1552 return originalValue;
1553}
1554function unwrapErrors(errors, alias) {
1555 if (errors === undefined) {
1556 return undefined;
1557 }
1558 return errors.map(error => {
1559 const originalPath = error.path;
1560 if (originalPath == null) {
1561 return error;
1562 }
1563 const newPath = originalPath.filter(pathSegment => pathSegment !== alias);
1564 return relocatedError(error, newPath);
1565 });
1566}
1567
1568class WrapQuery {
1569 constructor(path, wrapper, extractor) {
1570 this.path = path;
1571 this.wrapper = wrapper;
1572 this.extractor = extractor;
1573 }
1574 transformRequest(originalRequest, _delegationContext, _transformationContext) {
1575 const fieldPath = [];
1576 const ourPath = JSON.stringify(this.path);
1577 const document = visit(originalRequest.document, {
1578 [Kind.FIELD]: {
1579 enter: (node) => {
1580 fieldPath.push(node.name.value);
1581 if (node.selectionSet != null && ourPath === JSON.stringify(fieldPath)) {
1582 const wrapResult = this.wrapper(node.selectionSet);
1583 // Selection can be either a single selection or a selection set. If it's just one selection,
1584 // let's wrap it in a selection set. Otherwise, keep it as is.
1585 const selectionSet = wrapResult != null && wrapResult.kind === Kind.SELECTION_SET
1586 ? wrapResult
1587 : {
1588 kind: Kind.SELECTION_SET,
1589 selections: [wrapResult],
1590 };
1591 return {
1592 ...node,
1593 selectionSet,
1594 };
1595 }
1596 },
1597 leave: () => {
1598 fieldPath.pop();
1599 },
1600 },
1601 });
1602 return {
1603 ...originalRequest,
1604 document,
1605 };
1606 }
1607 transformResult(originalResult, _delegationContext, _transformationContext) {
1608 const rootData = originalResult.data;
1609 if (rootData != null) {
1610 let data = rootData;
1611 const path = [...this.path];
1612 while (path.length > 1) {
1613 const next = path.shift();
1614 if (data[next]) {
1615 data = data[next];
1616 }
1617 }
1618 data[path[0]] = this.extractor(data[path[0]]);
1619 }
1620 return {
1621 data: rootData,
1622 errors: originalResult.errors,
1623 };
1624 }
1625}
1626
1627class ExtractField {
1628 constructor({ from, to }) {
1629 this.from = from;
1630 this.to = to;
1631 }
1632 transformRequest(originalRequest, _delegationContext, _transformationContext) {
1633 let fromSelection;
1634 const ourPathFrom = JSON.stringify(this.from);
1635 const ourPathTo = JSON.stringify(this.to);
1636 let fieldPath = [];
1637 visit(originalRequest.document, {
1638 [Kind.FIELD]: {
1639 enter: (node) => {
1640 fieldPath.push(node.name.value);
1641 if (ourPathFrom === JSON.stringify(fieldPath)) {
1642 fromSelection = node.selectionSet;
1643 return BREAK;
1644 }
1645 },
1646 leave: () => {
1647 fieldPath.pop();
1648 },
1649 },
1650 });
1651 fieldPath = [];
1652 const document = visit(originalRequest.document, {
1653 [Kind.FIELD]: {
1654 enter: (node) => {
1655 fieldPath.push(node.name.value);
1656 if (ourPathTo === JSON.stringify(fieldPath) && fromSelection != null) {
1657 return {
1658 ...node,
1659 selectionSet: fromSelection,
1660 };
1661 }
1662 },
1663 leave: () => {
1664 fieldPath.pop();
1665 },
1666 },
1667 });
1668 return {
1669 ...originalRequest,
1670 document,
1671 };
1672 }
1673}
1674
1675function getSchemaFromIntrospection(introspectionResult, options) {
1676 var _a, _b;
1677 if ((_a = introspectionResult === null || introspectionResult === void 0 ? void 0 : introspectionResult.data) === null || _a === void 0 ? void 0 : _a.__schema) {
1678 return buildClientSchema(introspectionResult.data, options);
1679 }
1680 else if ((_b = introspectionResult === null || introspectionResult === void 0 ? void 0 : introspectionResult.errors) === null || _b === void 0 ? void 0 : _b.length) {
1681 if (introspectionResult.errors.length > 1) {
1682 const combinedError = new AggregateError(introspectionResult.errors, 'Could not obtain introspection result');
1683 throw combinedError;
1684 }
1685 const error = introspectionResult.errors[0];
1686 throw error.originalError || error;
1687 }
1688 else {
1689 throw new Error('Could not obtain introspection result, received: ' + JSON.stringify(introspectionResult));
1690 }
1691}
1692function introspectSchema(executor, context, options) {
1693 const parsedIntrospectionQuery = parse(getIntrospectionQuery(options), options);
1694 return new ValueOrPromise(() => executor({
1695 document: parsedIntrospectionQuery,
1696 operationType: 'query',
1697 context,
1698 }))
1699 .then(introspection => {
1700 if (isAsyncIterable(introspection)) {
1701 return introspection.next().then(({ value }) => value);
1702 }
1703 return introspection;
1704 })
1705 .then(introspection => getSchemaFromIntrospection(introspection, options))
1706 .resolve();
1707}
1708
1709export { ExtractField, FilterInputObjectFields, FilterInterfaceFields, FilterObjectFieldDirectives, FilterObjectFields, FilterRootFields, FilterTypes, HoistField, MapFields, MapLeafValues, PruneTypes as PruneSchema, RemoveObjectFieldDeprecations, RemoveObjectFieldDirectives, RemoveObjectFieldsWithDeprecation, RemoveObjectFieldsWithDirective, RenameInputObjectFields, RenameInterfaceFields, RenameObjectFields, RenameRootFields, RenameRootTypes, RenameTypes, TransformCompositeFields, TransformEnumValues, TransformInputObjectFields, TransformInterfaceFields, TransformObjectFields, TransformQuery, TransformRootFields, WrapFields, WrapQuery, WrapType, defaultCreateProxyingResolver, generateProxyingResolvers, introspectSchema, wrapSchema };