From e3083d79d635518b631f8814100a5fd59ca48808 Mon Sep 17 00:00:00 2001 From: Yaacov Rydzinski Date: Fri, 2 Oct 2020 00:33:55 +0300 Subject: [PATCH] fix(HoistField): allow hoisting to root requires passing additional parameters to each transformSchema call beyond the subschemaConfig: the transforms, and the transformedSchema. Because transformSchema may need to create additional proxying resolvers, it needs all the parameters that would be passed to delegateToSchema. It is NOT a catch-22 that transformSchema requires the transformed schema as a parameter, because it does NOT require an executable transformedSchema as a parameter, only the non-executable version for type comparisions performed ultimately by delegateToSchema within the proxying process. --- .changeset/weak-peaches-count.md | 2 +- packages/delegate/src/Subschema.ts | 2 +- .../delegate/src/applySchemaTransforms.ts | 21 +++++++-- packages/delegate/src/types.ts | 4 +- .../tests/alternateStitchSchemas.test.ts | 18 ++++++++ .../wrap/src/generateProxyingResolvers.ts | 10 +---- .../src/transforms/FilterInputObjectFields.ts | 9 +++- .../src/transforms/FilterInterfaceFields.ts | 9 +++- .../transforms/FilterObjectFieldDirectives.ts | 9 +++- .../wrap/src/transforms/FilterObjectFields.ts | 9 +++- .../wrap/src/transforms/FilterRootFields.ts | 9 +++- packages/wrap/src/transforms/FilterTypes.ts | 11 +++-- packages/wrap/src/transforms/HoistField.ts | 43 +++++++++++++++---- packages/wrap/src/transforms/MapFields.ts | 9 +++- packages/wrap/src/transforms/MapLeafValues.ts | 7 ++- packages/wrap/src/transforms/PruneSchema.ts | 11 +++-- .../RemoveObjectFieldDeprecations.ts | 11 ++++- .../transforms/RemoveObjectFieldDirectives.ts | 9 +++- .../RemoveObjectFieldsWithDeprecation.ts | 9 +++- .../RemoveObjectFieldsWithDirective.ts | 7 ++- .../src/transforms/RenameInputObjectFields.ts | 9 +++- .../src/transforms/RenameInterfaceFields.ts | 9 +++- .../wrap/src/transforms/RenameObjectFields.ts | 9 +++- .../wrap/src/transforms/RenameRootFields.ts | 9 +++- .../wrap/src/transforms/RenameRootTypes.ts | 7 ++- packages/wrap/src/transforms/RenameTypes.ts | 7 ++- .../transforms/TransformCompositeFields.ts | 7 ++- .../src/transforms/TransformEnumValues.ts | 16 +++++-- .../transforms/TransformInputObjectFields.ts | 7 ++- .../transforms/TransformInterfaceFields.ts | 9 +++- .../src/transforms/TransformObjectFields.ts | 9 +++- .../src/transforms/TransformRootFields.ts | 9 +++- packages/wrap/src/transforms/WrapFields.ts | 13 ++++-- packages/wrap/src/transforms/WrapType.ts | 9 +++- packages/wrap/src/wrapSchema.ts | 12 ++---- 35 files changed, 273 insertions(+), 87 deletions(-) diff --git a/.changeset/weak-peaches-count.md b/.changeset/weak-peaches-count.md index 9d2fc3e48ea..0858e2b4c7e 100644 --- a/.changeset/weak-peaches-count.md +++ b/.changeset/weak-peaches-count.md @@ -11,7 +11,7 @@ Breaking Changes: - Delegation result: ExternalObject concept formalized and matured, resulting in deprecation of slicedError, getErrors, getErrorsByPathSegment functions, see new getUnpathedErrors function for errors that cannot be merged into the ExternalObject. See as well new annotateExternalObject and mergeExternalObjects functions. Rename handleResult to resolveExternalValue. -- Transforms: transforms now take delegationContext and transformationContext arguments within their transformRequest/Result methods and take an optional subschemaConfig as the second argument for transformSchema. Transform types and applySchemaTransforms now within delegate package; applyRequest/ResultTransforms functions deprecated. +- Transforms: transforms now take delegationContext and transformationContext arguments within their transformRequest/Result methods. the transformSchema method may wish to create additional delegating resolvers and so it takes the subschemaConfig, transforms, and (non-executable) transformed schema as optional parameters. Transform types and applySchemaTransforms now within delegate package; applyRequest/ResultTransforms functions deprecated. - Wrapping schema standardization: remove support for createMergedResolver and non-standard transforms where resolvers do not use defaultMergedResolver. This is still possible, but not supported out of the box due to conflicts with type merging, where resolvers expected to be identical across subschemas. diff --git a/packages/delegate/src/Subschema.ts b/packages/delegate/src/Subschema.ts index 2627b46b8b3..2bbdd98be48 100644 --- a/packages/delegate/src/Subschema.ts +++ b/packages/delegate/src/Subschema.ts @@ -89,7 +89,7 @@ export class Subschema { this.createProxyingResolver = config.createProxyingResolver; this.transforms = config.transforms ?? []; - this.transformedSchema = applySchemaTransforms(this.schema, this.transforms, config); + this.transformedSchema = applySchemaTransforms(this.schema, config); this.merge = config.merge; } diff --git a/packages/delegate/src/applySchemaTransforms.ts b/packages/delegate/src/applySchemaTransforms.ts index e0ac2f69fa1..fa23c55a17d 100644 --- a/packages/delegate/src/applySchemaTransforms.ts +++ b/packages/delegate/src/applySchemaTransforms.ts @@ -6,12 +6,25 @@ import { SubschemaConfig, Transform } from './types'; export function applySchemaTransforms( originalWrappingSchema: GraphQLSchema, - transforms: Array, - subschema: SubschemaConfig + subschemaConfig?: SubschemaConfig, + transforms?: Array, + transformedSchema?: GraphQLSchema ): GraphQLSchema { - return transforms.reduce( + let schemaTransforms: Array = []; + + if (subschemaConfig?.transforms != null) { + schemaTransforms = schemaTransforms.concat(subschemaConfig.transforms); + } + + if (transforms) { + schemaTransforms = schemaTransforms.concat(transforms); + } + + return schemaTransforms.reduce( (schema: GraphQLSchema, transform: Transform) => - transform.transformSchema != null ? transform.transformSchema(cloneSchema(schema), subschema) : schema, + transform.transformSchema != null + ? transform.transformSchema(cloneSchema(schema), subschemaConfig, transforms, transformedSchema) + : schema, originalWrappingSchema ); } diff --git a/packages/delegate/src/types.ts b/packages/delegate/src/types.ts index 22bed698510..a26435529f9 100644 --- a/packages/delegate/src/types.ts +++ b/packages/delegate/src/types.ts @@ -23,7 +23,9 @@ import { OBJECT_SUBSCHEMA_SYMBOL, FIELD_SUBSCHEMA_MAP_SYMBOL, UNPATHED_ERRORS_SY export type SchemaTransform = ( originalWrappingSchema: GraphQLSchema, - subschemaConfig?: SubschemaConfig + subschemaConfig?: SubschemaConfig, + transforms?: Array, + transformedSchema?: GraphQLSchema ) => GraphQLSchema; export type RequestTransform> = ( originalRequest: Request, diff --git a/packages/stitch/tests/alternateStitchSchemas.test.ts b/packages/stitch/tests/alternateStitchSchemas.test.ts index 84e8990658c..e57d08ebcc8 100644 --- a/packages/stitch/tests/alternateStitchSchemas.test.ts +++ b/packages/stitch/tests/alternateStitchSchemas.test.ts @@ -1176,6 +1176,7 @@ describe('schema transformation with extraction of nested fields', () => { }, }); }); + }); describe('HoistField transform', () => { @@ -1270,6 +1271,23 @@ describe('HoistField transform', () => { expect(result).toEqual(expectedResult); }); + + test('should work to hoist fields to new root fields', async () => { + const wrappedSchema = wrapSchema({ + schema, + transforms: [new HoistField('Query', ['query', 'inner', 'test'], 'hoisted'), new PruneSchema({})], + }) + + const result = await graphql(wrappedSchema, '{ hoisted }'); + + const expectedResult = { + data: { + hoisted: 'test', + }, + }; + + expect(result).toEqual(expectedResult); + }); }); describe('schema transformation with wrapping of object fields', () => { diff --git a/packages/wrap/src/generateProxyingResolvers.ts b/packages/wrap/src/generateProxyingResolvers.ts index 9491c6e1009..d55c5f71fe6 100644 --- a/packages/wrap/src/generateProxyingResolvers.ts +++ b/packages/wrap/src/generateProxyingResolvers.ts @@ -20,7 +20,6 @@ export function generateProxyingResolvers( transforms: Array ): Record>> { let targetSchema: GraphQLSchema; - let schemaTransforms: Array = []; let createProxyingResolver: CreateProxyingResolverFn; let subschemaConfig: SubschemaConfig; @@ -28,19 +27,12 @@ export function generateProxyingResolvers( targetSchema = subschemaOrSubschemaConfig.schema; subschemaConfig = subschemaOrSubschemaConfig; createProxyingResolver = subschemaOrSubschemaConfig.createProxyingResolver ?? defaultCreateProxyingResolver; - if (subschemaOrSubschemaConfig.transforms != null) { - schemaTransforms = schemaTransforms.concat(subschemaOrSubschemaConfig.transforms); - } } else { targetSchema = subschemaOrSubschemaConfig; createProxyingResolver = defaultCreateProxyingResolver; } - if (transforms != null) { - schemaTransforms = schemaTransforms.concat(transforms); - } - - const transformedSchema = applySchemaTransforms(targetSchema, schemaTransforms, subschemaConfig); + const transformedSchema = applySchemaTransforms(targetSchema, subschemaConfig, transforms); const operationTypes: Record = { query: targetSchema.getQueryType(), diff --git a/packages/wrap/src/transforms/FilterInputObjectFields.ts b/packages/wrap/src/transforms/FilterInputObjectFields.ts index 5bbd414cc8a..3b89d18aa02 100644 --- a/packages/wrap/src/transforms/FilterInputObjectFields.ts +++ b/packages/wrap/src/transforms/FilterInputObjectFields.ts @@ -20,8 +20,13 @@ export default class FilterInputObjectFields implements Transform { ); } - public transformSchema(originalWrappingSchema: GraphQLSchema, subschemaConfig?: SubschemaConfig): GraphQLSchema { - return this.transformer.transformSchema(originalWrappingSchema, subschemaConfig); + public transformSchema( + originalWrappingSchema: GraphQLSchema, + subschemaConfig?: SubschemaConfig, + transforms?: Array, + transformedSchema?: GraphQLSchema + ): GraphQLSchema { + return this.transformer.transformSchema(originalWrappingSchema, subschemaConfig, transforms, transformedSchema); } public transformRequest( diff --git a/packages/wrap/src/transforms/FilterInterfaceFields.ts b/packages/wrap/src/transforms/FilterInterfaceFields.ts index d5b11895826..a6d1fe975c4 100644 --- a/packages/wrap/src/transforms/FilterInterfaceFields.ts +++ b/packages/wrap/src/transforms/FilterInterfaceFields.ts @@ -16,7 +16,12 @@ export default class FilterInterfaceFields implements Transform { ); } - public transformSchema(originalWrappingSchema: GraphQLSchema, subschemaConfig?: SubschemaConfig): GraphQLSchema { - return this.transformer.transformSchema(originalWrappingSchema, subschemaConfig); + public transformSchema( + originalWrappingSchema: GraphQLSchema, + subschemaConfig?: SubschemaConfig, + transforms?: Array, + transformedSchema?: GraphQLSchema + ): GraphQLSchema { + return this.transformer.transformSchema(originalWrappingSchema, subschemaConfig, transforms, transformedSchema); } } diff --git a/packages/wrap/src/transforms/FilterObjectFieldDirectives.ts b/packages/wrap/src/transforms/FilterObjectFieldDirectives.ts index 4f206c3a313..47c814fb13d 100644 --- a/packages/wrap/src/transforms/FilterObjectFieldDirectives.ts +++ b/packages/wrap/src/transforms/FilterObjectFieldDirectives.ts @@ -13,7 +13,12 @@ export default class FilterObjectFieldDirectives implements Transform { this.filter = filter; } - public transformSchema(originalWrappingSchema: GraphQLSchema, _subschemaConfig?: SubschemaConfig): GraphQLSchema { + public transformSchema( + originalWrappingSchema: GraphQLSchema, + subschemaConfig?: SubschemaConfig, + transforms?: Array, + transformedSchema?: GraphQLSchema + ): GraphQLSchema { const transformer = new TransformObjectFields( (_typeName: string, _fieldName: string, fieldConfig: GraphQLFieldConfig) => { const keepDirectives = fieldConfig.astNode.directives.filter(dir => { @@ -35,6 +40,6 @@ export default class FilterObjectFieldDirectives implements Transform { } ); - return transformer.transformSchema(originalWrappingSchema); + return transformer.transformSchema(originalWrappingSchema, subschemaConfig, transforms, transformedSchema); } } diff --git a/packages/wrap/src/transforms/FilterObjectFields.ts b/packages/wrap/src/transforms/FilterObjectFields.ts index 7d0c0e6e876..294218ead44 100644 --- a/packages/wrap/src/transforms/FilterObjectFields.ts +++ b/packages/wrap/src/transforms/FilterObjectFields.ts @@ -16,7 +16,12 @@ export default class FilterObjectFields implements Transform { ); } - public transformSchema(originalWrappingSchema: GraphQLSchema, subschemaConfig?: SubschemaConfig): GraphQLSchema { - return this.transformer.transformSchema(originalWrappingSchema, subschemaConfig); + public transformSchema( + originalWrappingSchema: GraphQLSchema, + subschemaConfig?: SubschemaConfig, + transforms?: Array, + transformedSchema?: GraphQLSchema + ): GraphQLSchema { + return this.transformer.transformSchema(originalWrappingSchema, subschemaConfig, transforms, transformedSchema); } } diff --git a/packages/wrap/src/transforms/FilterRootFields.ts b/packages/wrap/src/transforms/FilterRootFields.ts index f61f5646170..b2dd0acc246 100644 --- a/packages/wrap/src/transforms/FilterRootFields.ts +++ b/packages/wrap/src/transforms/FilterRootFields.ts @@ -25,7 +25,12 @@ export default class FilterRootFields implements Transform { ); } - public transformSchema(originalWrappingSchema: GraphQLSchema, subschemaConfig?: SubschemaConfig): GraphQLSchema { - return this.transformer.transformSchema(originalWrappingSchema, subschemaConfig); + public transformSchema( + originalWrappingSchema: GraphQLSchema, + subschemaConfig?: SubschemaConfig, + transforms?: Array, + transformedSchema?: GraphQLSchema + ): GraphQLSchema { + return this.transformer.transformSchema(originalWrappingSchema, subschemaConfig, transforms, transformedSchema); } } diff --git a/packages/wrap/src/transforms/FilterTypes.ts b/packages/wrap/src/transforms/FilterTypes.ts index 255bb0b98ef..955af5228c8 100644 --- a/packages/wrap/src/transforms/FilterTypes.ts +++ b/packages/wrap/src/transforms/FilterTypes.ts @@ -2,7 +2,7 @@ import { GraphQLSchema, GraphQLNamedType } from 'graphql'; import { mapSchema, MapperKind } from '@graphql-tools/utils'; -import { Transform } from '@graphql-tools/delegate'; +import { SubschemaConfig, Transform } from '@graphql-tools/delegate'; export default class FilterTypes implements Transform { private readonly filter: (type: GraphQLNamedType) => boolean; @@ -11,8 +11,13 @@ export default class FilterTypes implements Transform { this.filter = filter; } - public transformSchema(schema: GraphQLSchema): GraphQLSchema { - return mapSchema(schema, { + public transformSchema( + originalWrappingSchema: GraphQLSchema, + _subschemaConfig?: SubschemaConfig, + _transforms?: Array, + _transformedSchema?: GraphQLSchema + ): GraphQLSchema { + return mapSchema(originalWrappingSchema, { [MapperKind.TYPE]: (type: GraphQLNamedType) => { if (this.filter(type)) { return undefined; diff --git a/packages/wrap/src/transforms/HoistField.ts b/packages/wrap/src/transforms/HoistField.ts index 35483fb73ae..8ef58ee41ab 100644 --- a/packages/wrap/src/transforms/HoistField.ts +++ b/packages/wrap/src/transforms/HoistField.ts @@ -6,11 +6,14 @@ import { Kind, GraphQLError, GraphQLArgument, + GraphQLFieldConfig, } from 'graphql'; import { appendObjectFields, removeObjectFields, Request, ExecutionResult, relocatedError } from '@graphql-tools/utils'; -import { Transform, defaultMergedResolver, DelegationContext } from '@graphql-tools/delegate'; +import { Transform, defaultMergedResolver, DelegationContext, SubschemaConfig } from '@graphql-tools/delegate'; + +import { defaultCreateProxyingResolver } from '../generateProxyingResolvers'; import MapFields from './MapFields'; @@ -61,7 +64,12 @@ export default class HoistField implements Transform { this.argLevels = argLevels; } - public transformSchema(schema: GraphQLSchema): GraphQLSchema { + public transformSchema( + originalWrappingSchema: GraphQLSchema, + subschemaConfig: SubschemaConfig, + transforms: Array, + transformedSchema: GraphQLSchema + ): GraphQLSchema { const argsMap: Record = Object.create(null); const innerType: GraphQLObjectType = this.pathToField.reduce((acc, pathSegment, index) => { const field = acc.getFields()[pathSegment]; @@ -72,21 +80,38 @@ export default class HoistField implements Transform { } }); return getNullableType(field.type) as GraphQLObjectType; - }, schema.getType(this.typeName) as GraphQLObjectType); + }, originalWrappingSchema.getType(this.typeName) as GraphQLObjectType); let [newSchema, targetFieldConfigMap] = removeObjectFields( - schema, + originalWrappingSchema, innerType.name, fieldName => fieldName === this.oldFieldName ); const targetField = targetFieldConfigMap[this.oldFieldName]; - const newTargetField = { - ...targetField, - resolve: defaultMergedResolver, - }; - + const hoistingToRootField = + this.typeName === originalWrappingSchema.getQueryType()?.name || originalWrappingSchema.getMutationType()?.name; + + let newTargetField: GraphQLFieldConfig; + if (hoistingToRootField) { + const createProxyingResolver = subschemaConfig.createProxyingResolver ?? defaultCreateProxyingResolver; + newTargetField = { + ...targetField, + resolve: createProxyingResolver({ + schema: subschemaConfig, + transforms, + transformedSchema, + operation: this.typeName === originalWrappingSchema.getQueryType().name ? 'query' : 'mutation', + fieldName: this.newFieldName, + }), + }; + } else { + newTargetField = { + ...targetField, + resolve: defaultMergedResolver, + }; + } const level = this.pathToField.length; Object.keys(targetField.args).forEach(argName => { diff --git a/packages/wrap/src/transforms/MapFields.ts b/packages/wrap/src/transforms/MapFields.ts index d4d73ccdd9b..2a5dd6a50cb 100644 --- a/packages/wrap/src/transforms/MapFields.ts +++ b/packages/wrap/src/transforms/MapFields.ts @@ -54,8 +54,13 @@ export default class MapFields implements Transform { ); } - public transformSchema(originalWrappingSchema: GraphQLSchema, subschemaConfig?: SubschemaConfig): GraphQLSchema { - return this.transformer.transformSchema(originalWrappingSchema, subschemaConfig); + public transformSchema( + originalWrappingSchema: GraphQLSchema, + subschemaConfig?: SubschemaConfig, + transforms?: Array, + transformedSchema?: GraphQLSchema + ): GraphQLSchema { + return this.transformer.transformSchema(originalWrappingSchema, subschemaConfig, transforms, transformedSchema); } public transformRequest( diff --git a/packages/wrap/src/transforms/MapLeafValues.ts b/packages/wrap/src/transforms/MapLeafValues.ts index 38c21023314..e9e4a142f17 100644 --- a/packages/wrap/src/transforms/MapLeafValues.ts +++ b/packages/wrap/src/transforms/MapLeafValues.ts @@ -44,7 +44,12 @@ export default class MapLeafValues implements Transform, + _transformedSchema?: GraphQLSchema + ): GraphQLSchema { this.originalWrappingSchema = originalWrappingSchema; const typeMap = originalWrappingSchema.getTypeMap(); Object.keys(typeMap).forEach(typeName => { diff --git a/packages/wrap/src/transforms/PruneSchema.ts b/packages/wrap/src/transforms/PruneSchema.ts index 73efde73572..cc1534f6c62 100644 --- a/packages/wrap/src/transforms/PruneSchema.ts +++ b/packages/wrap/src/transforms/PruneSchema.ts @@ -2,7 +2,7 @@ import { GraphQLSchema } from 'graphql'; import { PruneSchemaOptions, pruneSchema } from '@graphql-tools/utils'; -import { Transform } from '@graphql-tools/delegate'; +import { SubschemaConfig, Transform } from '@graphql-tools/delegate'; export default class PruneTypes implements Transform { private readonly options: PruneSchemaOptions; @@ -11,7 +11,12 @@ export default class PruneTypes implements Transform { this.options = options; } - public transformSchema(schema: GraphQLSchema): GraphQLSchema { - return pruneSchema(schema, this.options); + public transformSchema( + originalWrappingSchema: GraphQLSchema, + _subschemaConfig?: SubschemaConfig, + _transforms?: Array, + _transformedSchema?: GraphQLSchema + ): GraphQLSchema { + return pruneSchema(originalWrappingSchema, this.options); } } diff --git a/packages/wrap/src/transforms/RemoveObjectFieldDeprecations.ts b/packages/wrap/src/transforms/RemoveObjectFieldDeprecations.ts index e6ee6abb518..4be1078d6e4 100644 --- a/packages/wrap/src/transforms/RemoveObjectFieldDeprecations.ts +++ b/packages/wrap/src/transforms/RemoveObjectFieldDeprecations.ts @@ -27,10 +27,17 @@ export default class RemoveObjectFieldDeprecations implements Transform { ); } - public transformSchema(originalWrappingSchema: GraphQLSchema, subschemaConfig?: SubschemaConfig): GraphQLSchema { + public transformSchema( + originalWrappingSchema: GraphQLSchema, + subschemaConfig?: SubschemaConfig, + transforms?: Array, + transformedSchema?: GraphQLSchema + ): GraphQLSchema { return this.removeDeprecations.transformSchema( this.removeDirectives.transformSchema(originalWrappingSchema, subschemaConfig), - subschemaConfig + subschemaConfig, + transforms, + transformedSchema ); } } diff --git a/packages/wrap/src/transforms/RemoveObjectFieldDirectives.ts b/packages/wrap/src/transforms/RemoveObjectFieldDirectives.ts index a0413e88285..49d1e9140a6 100644 --- a/packages/wrap/src/transforms/RemoveObjectFieldDirectives.ts +++ b/packages/wrap/src/transforms/RemoveObjectFieldDirectives.ts @@ -15,7 +15,12 @@ export default class RemoveObjectFieldDirectives implements Transform { }); } - public transformSchema(originalWrappingSchema: GraphQLSchema, subschemaConfig?: SubschemaConfig): GraphQLSchema { - return this.transformer.transformSchema(originalWrappingSchema, subschemaConfig); + public transformSchema( + originalWrappingSchema: GraphQLSchema, + subschemaConfig?: SubschemaConfig, + transforms?: Array, + transformedSchema?: GraphQLSchema + ): GraphQLSchema { + return this.transformer.transformSchema(originalWrappingSchema, subschemaConfig, transforms, transformedSchema); } } diff --git a/packages/wrap/src/transforms/RemoveObjectFieldsWithDeprecation.ts b/packages/wrap/src/transforms/RemoveObjectFieldsWithDeprecation.ts index 94724df7521..baa0f81cd37 100644 --- a/packages/wrap/src/transforms/RemoveObjectFieldsWithDeprecation.ts +++ b/packages/wrap/src/transforms/RemoveObjectFieldsWithDeprecation.ts @@ -20,7 +20,12 @@ export default class RemoveObjectFieldsWithDeprecation implements Transform { ); } - public transformSchema(originalWrappingSchema: GraphQLSchema, subschemaConfig?: SubschemaConfig): GraphQLSchema { - return this.transformer.transformSchema(originalWrappingSchema, subschemaConfig); + public transformSchema( + originalWrappingSchema: GraphQLSchema, + subschemaConfig?: SubschemaConfig, + transforms?: Array, + transformedSchema?: GraphQLSchema + ): GraphQLSchema { + return this.transformer.transformSchema(originalWrappingSchema, subschemaConfig, transforms, transformedSchema); } } diff --git a/packages/wrap/src/transforms/RemoveObjectFieldsWithDirective.ts b/packages/wrap/src/transforms/RemoveObjectFieldsWithDirective.ts index eac176e5d55..32a1159fb15 100644 --- a/packages/wrap/src/transforms/RemoveObjectFieldsWithDirective.ts +++ b/packages/wrap/src/transforms/RemoveObjectFieldsWithDirective.ts @@ -15,7 +15,12 @@ export default class RemoveObjectFieldsWithDirective implements Transform { this.args = args; } - public transformSchema(originalWrappingSchema: GraphQLSchema, subschemaConfig?: SubschemaConfig): GraphQLSchema { + public transformSchema( + originalWrappingSchema: GraphQLSchema, + subschemaConfig?: SubschemaConfig, + transforms?: Array, + transformedSchema?: GraphQLSchema + ): GraphQLSchema { const transformer = new FilterObjectFields( (_typeName: string, _fieldName: string, fieldConfig: GraphQLFieldConfig) => { const valueMap = getDirectives(originalWrappingSchema, fieldConfig); diff --git a/packages/wrap/src/transforms/RenameInputObjectFields.ts b/packages/wrap/src/transforms/RenameInputObjectFields.ts index 4a61b963577..1a7d46c3cb5 100644 --- a/packages/wrap/src/transforms/RenameInputObjectFields.ts +++ b/packages/wrap/src/transforms/RenameInputObjectFields.ts @@ -42,7 +42,12 @@ export default class RenameInputObjectFields implements Transform { this.reverseMap = Object.create(null); } - public transformSchema(originalWrappingSchema: GraphQLSchema, subschemaConfig?: SubschemaConfig): GraphQLSchema { + public transformSchema( + originalWrappingSchema: GraphQLSchema, + subschemaConfig?: SubschemaConfig, + transforms?: Array, + transformedSchema?: GraphQLSchema + ): GraphQLSchema { mapSchema(originalWrappingSchema, { [MapperKind.INPUT_OBJECT_FIELD]: ( inputFieldConfig: GraphQLInputFieldConfig, @@ -64,7 +69,7 @@ export default class RenameInputObjectFields implements Transform { }, }); - return this.transformer.transformSchema(originalWrappingSchema, subschemaConfig); + return this.transformer.transformSchema(originalWrappingSchema, subschemaConfig, transforms, transformedSchema); } public transformRequest( diff --git a/packages/wrap/src/transforms/RenameInterfaceFields.ts b/packages/wrap/src/transforms/RenameInterfaceFields.ts index 8ec7031b111..a71cd86a55e 100644 --- a/packages/wrap/src/transforms/RenameInterfaceFields.ts +++ b/packages/wrap/src/transforms/RenameInterfaceFields.ts @@ -18,8 +18,13 @@ export default class RenameInterfaceFields implements Transform { ); } - public transformSchema(originalWrappingSchema: GraphQLSchema, subschemaConfig?: SubschemaConfig): GraphQLSchema { - return this.transformer.transformSchema(originalWrappingSchema, subschemaConfig); + public transformSchema( + originalWrappingSchema: GraphQLSchema, + subschemaConfig?: SubschemaConfig, + transforms?: Array, + transformedSchema?: GraphQLSchema + ): GraphQLSchema { + return this.transformer.transformSchema(originalWrappingSchema, subschemaConfig, transforms, transformedSchema); } public transformRequest( diff --git a/packages/wrap/src/transforms/RenameObjectFields.ts b/packages/wrap/src/transforms/RenameObjectFields.ts index 9c153cdf4b8..b7df19cd13c 100644 --- a/packages/wrap/src/transforms/RenameObjectFields.ts +++ b/packages/wrap/src/transforms/RenameObjectFields.ts @@ -18,8 +18,13 @@ export default class RenameObjectFields implements Transform { ); } - public transformSchema(originalWrappingSchema: GraphQLSchema, subschemaConfig?: SubschemaConfig): GraphQLSchema { - return this.transformer.transformSchema(originalWrappingSchema, subschemaConfig); + public transformSchema( + originalWrappingSchema: GraphQLSchema, + subschemaConfig?: SubschemaConfig, + transforms?: Array, + transformedSchema?: GraphQLSchema + ): GraphQLSchema { + return this.transformer.transformSchema(originalWrappingSchema, subschemaConfig, transforms, transformedSchema); } public transformRequest( diff --git a/packages/wrap/src/transforms/RenameRootFields.ts b/packages/wrap/src/transforms/RenameRootFields.ts index b55669edd32..ce6dee1b659 100644 --- a/packages/wrap/src/transforms/RenameRootFields.ts +++ b/packages/wrap/src/transforms/RenameRootFields.ts @@ -25,8 +25,13 @@ export default class RenameRootFields implements Transform { ); } - public transformSchema(originalWrappingSchema: GraphQLSchema, subschemaConfig?: SubschemaConfig): GraphQLSchema { - return this.transformer.transformSchema(originalWrappingSchema, subschemaConfig); + public transformSchema( + originalWrappingSchema: GraphQLSchema, + subschemaConfig?: SubschemaConfig, + transforms?: Array, + transformedSchema?: GraphQLSchema + ): GraphQLSchema { + return this.transformer.transformSchema(originalWrappingSchema, subschemaConfig, transforms, transformedSchema); } public transformRequest( diff --git a/packages/wrap/src/transforms/RenameRootTypes.ts b/packages/wrap/src/transforms/RenameRootTypes.ts index 2a64fa692d8..2343911fa24 100644 --- a/packages/wrap/src/transforms/RenameRootTypes.ts +++ b/packages/wrap/src/transforms/RenameRootTypes.ts @@ -15,7 +15,12 @@ export default class RenameRootTypes implements Transform { this.reverseMap = Object.create(null); } - public transformSchema(originalWrappingSchema: GraphQLSchema, _subschemaConfig?: SubschemaConfig): GraphQLSchema { + public transformSchema( + originalWrappingSchema: GraphQLSchema, + _subschemaConfig?: SubschemaConfig, + _transforms?: Array, + _transformedSchema?: GraphQLSchema + ): GraphQLSchema { return mapSchema(originalWrappingSchema, { [MapperKind.ROOT_OBJECT]: type => { const oldName = type.name; diff --git a/packages/wrap/src/transforms/RenameTypes.ts b/packages/wrap/src/transforms/RenameTypes.ts index ece9a2d4668..2cd135d3852 100644 --- a/packages/wrap/src/transforms/RenameTypes.ts +++ b/packages/wrap/src/transforms/RenameTypes.ts @@ -36,7 +36,12 @@ export default class RenameTypes implements Transform { this.renameScalars = renameScalars; } - public transformSchema(originalWrappingSchema: GraphQLSchema, _subschemaConfig?: SubschemaConfig): GraphQLSchema { + public transformSchema( + originalWrappingSchema: GraphQLSchema, + _subschemaConfig?: SubschemaConfig, + _transforms?: Array, + _transformedSchema?: GraphQLSchema + ): GraphQLSchema { return mapSchema(originalWrappingSchema, { [MapperKind.TYPE]: (type: GraphQLNamedType) => { if (isSpecifiedScalarType(type) && !this.renameBuiltins) { diff --git a/packages/wrap/src/transforms/TransformCompositeFields.ts b/packages/wrap/src/transforms/TransformCompositeFields.ts index f7cffba359d..3dbb022510c 100644 --- a/packages/wrap/src/transforms/TransformCompositeFields.ts +++ b/packages/wrap/src/transforms/TransformCompositeFields.ts @@ -39,7 +39,12 @@ export default class TransformCompositeFields implements Transform { this.mapping = {}; } - public transformSchema(originalWrappingSchema: GraphQLSchema, _subschemaConfig: SubschemaConfig): GraphQLSchema { + public transformSchema( + originalWrappingSchema: GraphQLSchema, + _subschemaConfig?: SubschemaConfig, + _transforms?: Array, + _transformedSchema?: GraphQLSchema + ): GraphQLSchema { this.transformedSchema = mapSchema(originalWrappingSchema, { [MapperKind.COMPOSITE_FIELD]: (fieldConfig, fieldName, typeName) => { const transformedField = this.fieldTransformer(typeName, fieldName, fieldConfig); diff --git a/packages/wrap/src/transforms/TransformEnumValues.ts b/packages/wrap/src/transforms/TransformEnumValues.ts index 776933c346d..2812aed58fd 100644 --- a/packages/wrap/src/transforms/TransformEnumValues.ts +++ b/packages/wrap/src/transforms/TransformEnumValues.ts @@ -29,9 +29,19 @@ export default class TransformEnumValues implements Transform, + transformedSchema?: GraphQLSchema + ): GraphQLSchema { + const mappingSchema = this.transformer.transformSchema( + originalWrappingSchema, + subschemaConfig, + transforms, + transformedSchema + ); + this.transformedSchema = mapSchema(mappingSchema, { [MapperKind.ENUM_VALUE]: (valueConfig, typeName, _schema, externalValue) => this.transformEnumValue(typeName, externalValue, valueConfig), }); diff --git a/packages/wrap/src/transforms/TransformInputObjectFields.ts b/packages/wrap/src/transforms/TransformInputObjectFields.ts index 43ca588cd13..ea2a35d973c 100644 --- a/packages/wrap/src/transforms/TransformInputObjectFields.ts +++ b/packages/wrap/src/transforms/TransformInputObjectFields.ts @@ -36,7 +36,12 @@ export default class TransformInputObjectFields implements Transform { this.mapping = {}; } - public transformSchema(originalWrappingSchema: GraphQLSchema, _subschemaConfig?: SubschemaConfig): GraphQLSchema { + public transformSchema( + originalWrappingSchema: GraphQLSchema, + _subschemaConfig?: SubschemaConfig, + _transforms?: Array, + _transformedSchema?: GraphQLSchema + ): GraphQLSchema { this.transformedSchema = mapSchema(originalWrappingSchema, { [MapperKind.INPUT_OBJECT_FIELD]: (inputFieldConfig, fieldName, typeName) => { const transformedInputField = this.inputFieldTransformer(typeName, fieldName, inputFieldConfig); diff --git a/packages/wrap/src/transforms/TransformInterfaceFields.ts b/packages/wrap/src/transforms/TransformInterfaceFields.ts index 2ab1c7ff2ea..9f7f2aa6b4e 100644 --- a/packages/wrap/src/transforms/TransformInterfaceFields.ts +++ b/packages/wrap/src/transforms/TransformInterfaceFields.ts @@ -18,7 +18,12 @@ export default class TransformInterfaceFields implements Transform { this.fieldNodeTransformer = fieldNodeTransformer; } - public transformSchema(originalWrappingSchema: GraphQLSchema, subschemaConfig?: SubschemaConfig): GraphQLSchema { + public transformSchema( + originalWrappingSchema: GraphQLSchema, + subschemaConfig?: SubschemaConfig, + transforms?: Array, + transformedSchema?: GraphQLSchema + ): GraphQLSchema { const compositeToObjectFieldTransformer = ( typeName: string, fieldName: string, @@ -33,7 +38,7 @@ export default class TransformInterfaceFields implements Transform { this.transformer = new TransformCompositeFields(compositeToObjectFieldTransformer, this.fieldNodeTransformer); - return this.transformer.transformSchema(originalWrappingSchema, subschemaConfig); + return this.transformer.transformSchema(originalWrappingSchema, subschemaConfig, transforms, transformedSchema); } public transformRequest( diff --git a/packages/wrap/src/transforms/TransformObjectFields.ts b/packages/wrap/src/transforms/TransformObjectFields.ts index cc3258d8970..0405a25ab10 100644 --- a/packages/wrap/src/transforms/TransformObjectFields.ts +++ b/packages/wrap/src/transforms/TransformObjectFields.ts @@ -18,7 +18,12 @@ export default class TransformObjectFields implements Transform { this.fieldNodeTransformer = fieldNodeTransformer; } - public transformSchema(originalWrappingSchema: GraphQLSchema, subschemaConfig?: SubschemaConfig): GraphQLSchema { + public transformSchema( + originalWrappingSchema: GraphQLSchema, + subschemaConfig?: SubschemaConfig, + transforms?: Array, + transformedSchema?: GraphQLSchema + ): GraphQLSchema { const compositeToObjectFieldTransformer = ( typeName: string, fieldName: string, @@ -33,7 +38,7 @@ export default class TransformObjectFields implements Transform { this.transformer = new TransformCompositeFields(compositeToObjectFieldTransformer, this.fieldNodeTransformer); - return this.transformer.transformSchema(originalWrappingSchema, subschemaConfig); + return this.transformer.transformSchema(originalWrappingSchema, subschemaConfig, transforms, transformedSchema); } public transformRequest( diff --git a/packages/wrap/src/transforms/TransformRootFields.ts b/packages/wrap/src/transforms/TransformRootFields.ts index 781ed459424..5a6cdbc3eb8 100644 --- a/packages/wrap/src/transforms/TransformRootFields.ts +++ b/packages/wrap/src/transforms/TransformRootFields.ts @@ -18,7 +18,12 @@ export default class TransformRootFields implements Transform { this.fieldNodeTransformer = fieldNodeTransformer; } - public transformSchema(originalWrappingSchema: GraphQLSchema, subschemaConfig?: SubschemaConfig): GraphQLSchema { + public transformSchema( + originalWrappingSchema: GraphQLSchema, + subschemaConfig?: SubschemaConfig, + transforms?: Array, + transformedSchema?: GraphQLSchema + ): GraphQLSchema { const queryTypeName = originalWrappingSchema.getQueryType()?.name; const mutationTypeName = originalWrappingSchema.getMutationType()?.name; const subscriptionTypeName = originalWrappingSchema.getSubscriptionType()?.name; @@ -45,7 +50,7 @@ export default class TransformRootFields implements Transform { this.transformer = new TransformObjectFields(rootToObjectFieldTransformer, this.fieldNodeTransformer); - return this.transformer.transformSchema(originalWrappingSchema, subschemaConfig); + return this.transformer.transformSchema(originalWrappingSchema, subschemaConfig, transforms, transformedSchema); } public transformRequest( diff --git a/packages/wrap/src/transforms/WrapFields.ts b/packages/wrap/src/transforms/WrapFields.ts index c85b2b7400a..dce65f8fbcc 100644 --- a/packages/wrap/src/transforms/WrapFields.ts +++ b/packages/wrap/src/transforms/WrapFields.ts @@ -19,7 +19,7 @@ import { relocatedError, } from '@graphql-tools/utils'; -import { Transform, defaultMergedResolver, DelegationContext } from '@graphql-tools/delegate'; +import { Transform, defaultMergedResolver, DelegationContext, SubschemaConfig } from '@graphql-tools/delegate'; import MapFields from './MapFields'; @@ -92,9 +92,14 @@ export default class WrapFields implements Transform, + _transformedSchema?: GraphQLSchema + ): GraphQLSchema { const targetFieldConfigMap = selectObjectFields( - schema, + originalWrappingSchema, this.outerTypeName, !this.fieldNames ? () => true : fieldName => this.fieldNames.includes(fieldName) ); @@ -103,7 +108,7 @@ export default class WrapFields implements Transform -1; wrapIndex--) { const nextWrappingTypeName = this.wrappingTypeNames[wrapIndex]; diff --git a/packages/wrap/src/transforms/WrapType.ts b/packages/wrap/src/transforms/WrapType.ts index 55e8b3852b6..36e1061b243 100644 --- a/packages/wrap/src/transforms/WrapType.ts +++ b/packages/wrap/src/transforms/WrapType.ts @@ -13,8 +13,13 @@ export default class WrapType implements Transform { this.transformer = new WrapFields(outerTypeName, [fieldName], [innerTypeName]); } - public transformSchema(originalWrappingSchema: GraphQLSchema, subschemaConfig?: SubschemaConfig): GraphQLSchema { - return this.transformer.transformSchema(originalWrappingSchema, subschemaConfig); + public transformSchema( + originalWrappingSchema: GraphQLSchema, + subschemaConfig?: SubschemaConfig, + transforms?: Array, + transformedSchema?: GraphQLSchema + ): GraphQLSchema { + return this.transformer.transformSchema(originalWrappingSchema, subschemaConfig, transforms, transformedSchema); } public transformRequest( diff --git a/packages/wrap/src/wrapSchema.ts b/packages/wrap/src/wrapSchema.ts index 48fff9bd215..0b51cdd97af 100644 --- a/packages/wrap/src/wrapSchema.ts +++ b/packages/wrap/src/wrapSchema.ts @@ -22,27 +22,21 @@ export function wrapSchema( transforms?: Array ): GraphQLSchema { let targetSchema: GraphQLSchema; - let schemaTransforms: Array = []; let subschemaConfig: SubschemaConfig; if (isSubschemaConfig(subschemaOrSubschemaConfig)) { targetSchema = subschemaOrSubschemaConfig.schema; subschemaConfig = subschemaOrSubschemaConfig; - if (subschemaOrSubschemaConfig.transforms != null) { - schemaTransforms = schemaTransforms.concat(subschemaOrSubschemaConfig.transforms); - } } else { targetSchema = subschemaOrSubschemaConfig; } - if (transforms != null) { - schemaTransforms = schemaTransforms.concat(transforms); - } - const proxyingResolvers = generateProxyingResolvers(subschemaOrSubschemaConfig, transforms); const schema = createWrappingSchema(targetSchema, proxyingResolvers); - return applySchemaTransforms(schema, schemaTransforms, subschemaConfig); + const transformedSchema = applySchemaTransforms(schema, subschemaConfig, transforms); + + return applySchemaTransforms(schema, subschemaConfig, transforms, transformedSchema); } function createWrappingSchema(