UNPKG

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