From c38125756db3ce7ccee1997ff55eeff8585c20e7 Mon Sep 17 00:00:00 2001 From: Arda TANRIKULU Date: Tue, 12 Feb 2019 17:02:21 -0500 Subject: [PATCH 01/17] Recursively merge schemas --- packages/core/package.json | 2 +- packages/core/src/graphql-module.ts | 155 +++++++++------------------- yarn.lock | 8 +- 3 files changed, 51 insertions(+), 114 deletions(-) diff --git a/packages/core/package.json b/packages/core/package.json index 6f774eda26..5b86583c77 100644 --- a/packages/core/package.json +++ b/packages/core/package.json @@ -31,7 +31,7 @@ }, "dependencies": { "@graphql-modules/di": "0.4.2", - "graphql-toolkit": "0.0.5", + "graphql-toolkit": "0.0.6-1630e8f.0", "graphql-tools": "4.0.4", "tslib": "1.9.3" }, diff --git a/packages/core/src/graphql-module.ts b/packages/core/src/graphql-module.ts index 7bb68f2266..7ad4cdb976 100644 --- a/packages/core/src/graphql-module.ts +++ b/packages/core/src/graphql-module.ts @@ -1,5 +1,5 @@ -import { IResolvers, SchemaDirectiveVisitor, mergeSchemas, IDirectiveResolvers, makeExecutableSchema, IResolverValidationOptions } from 'graphql-tools'; -import { mergeGraphQLSchemas, mergeResolvers, IResolversComposerMapping, composeResolvers , getSchemaDirectiveFromDirectiveResolver } from 'graphql-toolkit'; +import { IResolvers, SchemaDirectiveVisitor, IDirectiveResolvers, IResolverValidationOptions } from 'graphql-tools'; +import { mergeSchemas, mergeTypeDefs, mergeResolvers, IResolversComposerMapping, composeResolvers , getSchemaDirectiveFromDirectiveResolver } from 'graphql-toolkit'; import { Provider, Injector, ProviderScope, ServiceIdentifier } from '@graphql-modules/di'; import { DocumentNode, GraphQLSchema, parse, GraphQLScalarType } from 'graphql'; import { SchemaNotValidError, DependencyModuleUndefinedError, TypeDefNotFoundError, ModuleConfigRequiredError, IllegalResolverInvocationError, ContextBuilderError } from './errors'; @@ -218,109 +218,6 @@ export class GraphQLModule { return this._moduleConfig; } -/* - private buildSchemaWithMergeSchemas() { - const schemaSet = new Set(); - const selfImports = this.selfImports; - for (const module of selfImports) { - if (typeof module === 'undefined') { - throw new DependencyModuleUndefinedError(this.name); - } - const moduleSchema = module.schema; - if (moduleSchema) { - schemaSet.add(moduleSchema); - } - } - const selfTypeDefs = this.selfTypeDefs; - let resolvers = {}; - const schemaDirectives = this.schemaDirectives; - try { - if (selfTypeDefs) { - const localSchema = buildASTSchema(selfTypeDefs, { - assumeValid: true, - assumeValidSDL: true, - }); - schemaSet.add(localSchema); - } - const selfResolversComposition = this.selfResolversComposition; - if (Object.keys(selfResolversComposition).length) { - resolvers = this.resolvers; - } else { - resolvers = this.addSessionInjectorToSelfResolversContext(); - } - const selfExtraSchemas = this.selfExtraSchemas; - const schemas = [...selfExtraSchemas, ...schemaSet]; - if (schemas.length) { - this._cache.schema = mergeSchemas({ - schemas, - resolvers, - schemaDirectives, - }); - } else { - this._cache.schema = null; - } - } catch (e) { - if (e.message.includes(`Type "`) && e.message.includes(`" not found in document.`)) { - const typeDef = e.message.replace('Type "', '').replace('" not found in document.', ''); - throw new TypeDefNotFoundError(typeDef, this.name); - } else { - throw new SchemaNotValidError(this.name, e.message); - } - } - } - */ - buildSchemaWithMakeExecutableSchema() { - this.checkConfiguration(); - const selfImports = this.selfImports; - // Do iterations once - for ( const module of selfImports ) { - if (typeof module._cache.schema === 'undefined') { - module.buildSchemaWithMakeExecutableSchema(); - } - } - try { - const typeDefs = this.typeDefs; - const resolvers = this.resolvers; - const schemaDirectives = this.schemaDirectives; - const logger = this.selfLogger; - const resolverValidationOptions = this.selfResolverValidationOptions; - const extraSchemas = this.extraSchemas; - if (typeDefs) { - const localSchema = makeExecutableSchema>({ - typeDefs, - resolvers, - schemaDirectives, - logger: 'clientError' in logger ? { - log: message => logger.clientError(message), - } : undefined, - resolverValidationOptions, - }); - if (extraSchemas.length) { - this._cache.schema = mergeSchemas({ - schemas: [localSchema, ...extraSchemas], - }); - } else { - this._cache.schema = localSchema; - } - } else { - this._cache.schema = null; - } - } catch (e) { - if (e.message === 'Must provide typeDefs') { - this._cache.schema = null; - } else if (e.message.includes(`Type "`) && e.message.includes(`" not found in document.`)) { - const typeDef = e.message.replace('Type "', '').replace('" not found in document.', ''); - throw new TypeDefNotFoundError(typeDef, this.name); - } else { - throw new SchemaNotValidError(this.name, e.message); - } - } - if ('middleware' in this._options) { - const middlewareResult = this.injector.call(this._options.middleware, this); - Object.assign(this._cache, middlewareResult); - } - } - /** * Gets the application `GraphQLSchema` object. * If the schema object is not built yet, it compiles @@ -328,8 +225,48 @@ export class GraphQLModule { */ get schema() { if (typeof this._cache.schema === 'undefined') { - this.buildSchemaWithMakeExecutableSchema(); - // this.buildSchemaWithMergeSchemas(); + this.checkConfiguration(); + try { + const importsSchemas = this.selfImports.map(module => module.schema); + const selfTypeDefs = this.selfTypeDefs; + const selfEncapsulatedResolvers = this.addSessionInjectorToSelfResolversContext(); + const selfEncapsulatedResolversComposition = this.addSessionInjectorToSelfResolversCompositionContext(); + const selfLogger = this.selfLogger; + const selfResolverValidationOptions = this.selfResolverValidationOptions; + const selfExtraSchemas = this.selfExtraSchemas; + const schemaDirectives = this.schemaDirectives; + if (importsSchemas.length || selfTypeDefs || selfExtraSchemas.length) { + this._cache.schema = mergeSchemas({ + schemas: [ + ...importsSchemas, + ...selfExtraSchemas, + ], + typeDefs: selfTypeDefs, + resolvers: selfEncapsulatedResolvers, + resolversComposition: selfEncapsulatedResolversComposition, + schemaDirectives, + resolverValidationOptions: selfResolverValidationOptions, + logger: 'clientError' in selfLogger ? { + log: message => selfLogger.clientError(message), + } : undefined, + }); + } else { + this._cache.schema = null; + } + } catch (e) { + if (e.message === 'Must provide typeDefs') { + this._cache.schema = null; + } else if (e.message.includes(`Type "`) && e.message.includes(`" not found in document.`)) { + const typeDef = e.message.replace('Type "', '').replace('" not found in document.', ''); + throw new TypeDefNotFoundError(typeDef, this.name); + } else { + throw new SchemaNotValidError(this.name, e.message); + } + } + if ('middleware' in this._options) { + const middlewareResult = this.injector.call(this._options.middleware, this); + Object.assign(this._cache, middlewareResult); + } } return this._cache.schema; } @@ -405,7 +342,7 @@ export class GraphQLModule { } typeDefsArr = typeDefsArr.concat(this.extraSchemas); if (typeDefsArr.length) { - this._cache.typeDefs = mergeGraphQLSchemas(typeDefsArr, { + this._cache.typeDefs = mergeTypeDefs(typeDefsArr, { useSchemaDefinition: false, }); } else { @@ -568,7 +505,7 @@ export class GraphQLModule { if (typeof typeDefsDefinitions === 'string') { typeDefs = parse(typeDefsDefinitions); } else if (Array.isArray(typeDefsDefinitions)) { - typeDefs = mergeGraphQLSchemas(typeDefsDefinitions, { + typeDefs = mergeTypeDefs(typeDefsDefinitions, { useSchemaDefinition: false, }); } else if (typeDefsDefinitions) { diff --git a/yarn.lock b/yarn.lock index 5af8ea8ee9..d003b6fa02 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1919,10 +1919,10 @@ graphql-tag@2.10.1: resolved "https://registry.yarnpkg.com/graphql-tag/-/graphql-tag-2.10.1.tgz#10aa41f1cd8fae5373eaf11f1f67260a3cad5e02" integrity sha512-jApXqWBzNXQ8jYa/HLkZJaVw9jgwNqZkywa2zfFn16Iv1Zb7ELNHkJaXHR7Quvd5SIGsy6Ny7SUKATgnu05uEg== -graphql-toolkit@0.0.5: - version "0.0.5" - resolved "https://registry.yarnpkg.com/graphql-toolkit/-/graphql-toolkit-0.0.5.tgz#9e6ebe3d4b33fc329e5ee3b7775bfe7fba2f48a5" - integrity sha512-655RP1y8cn65mOa9EE/jnttczHE0lFXpOV1zYLTsE1A0b5j8RVuKWllSZBnnL2WHSAPPqLZ1oJEZV2uzSdV9VQ== +graphql-toolkit@0.0.6-1630e8f.0: + version "0.0.6-1630e8f.0" + resolved "https://registry.yarnpkg.com/graphql-toolkit/-/graphql-toolkit-0.0.6-1630e8f.0.tgz#9a2404a45ec45cdbbaa0d26348ce412e8f220ba5" + integrity sha512-EPwQYDjnq9nCImqJoPVzGx0gvyPzmn28VyvL9XE2BX2a7rTrVKO8VzRVFcoB4C506GAdCQZEHiz7l1w8X9DHxw== dependencies: deepmerge "3.1.0" glob "7.1.3" From c0bba1877e07e42af9cf0fdc9f46dacce89d0d83 Mon Sep 17 00:00:00 2001 From: Arda TANRIKULU Date: Tue, 12 Feb 2019 17:05:29 -0500 Subject: [PATCH 02/17] Throw error in correct place --- packages/core/src/graphql-module.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/core/src/graphql-module.ts b/packages/core/src/graphql-module.ts index 7ad4cdb976..07ec85911c 100644 --- a/packages/core/src/graphql-module.ts +++ b/packages/core/src/graphql-module.ts @@ -226,8 +226,8 @@ export class GraphQLModule { get schema() { if (typeof this._cache.schema === 'undefined') { this.checkConfiguration(); + const importsSchemas = this.selfImports.map(module => module.schema); try { - const importsSchemas = this.selfImports.map(module => module.schema); const selfTypeDefs = this.selfTypeDefs; const selfEncapsulatedResolvers = this.addSessionInjectorToSelfResolversContext(); const selfEncapsulatedResolversComposition = this.addSessionInjectorToSelfResolversCompositionContext(); From a8946b34c172b38b891de88e8f69530a5aeb3d25 Mon Sep 17 00:00:00 2001 From: Arda TANRIKULU Date: Tue, 12 Feb 2019 17:12:05 -0500 Subject: [PATCH 03/17] Null check for imports schemas --- packages/core/src/graphql-module.ts | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/packages/core/src/graphql-module.ts b/packages/core/src/graphql-module.ts index 07ec85911c..94c41bffa3 100644 --- a/packages/core/src/graphql-module.ts +++ b/packages/core/src/graphql-module.ts @@ -226,7 +226,14 @@ export class GraphQLModule { get schema() { if (typeof this._cache.schema === 'undefined') { this.checkConfiguration(); - const importsSchemas = this.selfImports.map(module => module.schema); + const importsSchemas = new Array(); + const selfImports = this.selfImports; + for (const module of selfImports) { + const moduleSchema = module.schema; + if (moduleSchema) { + importsSchemas.push(moduleSchema); + } + } try { const selfTypeDefs = this.selfTypeDefs; const selfEncapsulatedResolvers = this.addSessionInjectorToSelfResolversContext(); From abd9eefea025fdf2df3cfcc6ae569117b2187617 Mon Sep 17 00:00:00 2001 From: Arda TANRIKULU Date: Thu, 14 Feb 2019 03:05:27 -0500 Subject: [PATCH 04/17] test multiple visitSchema --- packages/core/package.json | 6 ++++-- packages/core/tests/graphql-module.spec.ts | 9 ++++++++- 2 files changed, 12 insertions(+), 3 deletions(-) diff --git a/packages/core/package.json b/packages/core/package.json index 5b86583c77..d7f5ab0bfe 100644 --- a/packages/core/package.json +++ b/packages/core/package.json @@ -32,15 +32,17 @@ "dependencies": { "@graphql-modules/di": "0.4.2", "graphql-toolkit": "0.0.6-1630e8f.0", - "graphql-tools": "4.0.4", "tslib": "1.9.3" }, + "peerDependencies": { + "graphql": "^14.1.1" + }, "devDependencies": { "apollo-cache-inmemory": "1.4.2", "apollo-client": "2.4.12", "apollo-link-schema": "1.1.6", "graphql-tag": "2.10.1", - "jest": "24.1.0", + "graphql-tools": "4.0.4", "tslint": "5.12.1", "typescript": "3.3.3" }, diff --git a/packages/core/tests/graphql-module.spec.ts b/packages/core/tests/graphql-module.spec.ts index 0bd0cd85a2..4dae0f35e6 100644 --- a/packages/core/tests/graphql-module.spec.ts +++ b/packages/core/tests/graphql-module.spec.ts @@ -760,7 +760,7 @@ describe('GraphQLModule', () => { }, }); - const { schema, context } = new GraphQLModule({ + const VisitedDateModule = new GraphQLModule({ typeDefs: gql` scalar Date @@ -778,6 +778,13 @@ describe('GraphQLModule', () => { ], }); + const { schema, context } = new GraphQLModule({ + imports: [ + DateDirectiveModule, + VisitedDateModule, + ], + }); + const contextValue = await context({ req: {} }); const result = await execute({ From 29f7dad68582875973f5ed7cfdb8692f47a3f71f Mon Sep 17 00:00:00 2001 From: Arda TANRIKULU Date: Thu, 21 Feb 2019 14:20:29 -0500 Subject: [PATCH 05/17] Fix schemaDirectives --- packages/core/src/graphql-module.ts | 58 +++++++++++++++++++++-------- 1 file changed, 43 insertions(+), 15 deletions(-) diff --git a/packages/core/src/graphql-module.ts b/packages/core/src/graphql-module.ts index 94c41bffa3..439e164baf 100644 --- a/packages/core/src/graphql-module.ts +++ b/packages/core/src/graphql-module.ts @@ -1,7 +1,7 @@ -import { IResolvers, SchemaDirectiveVisitor, IDirectiveResolvers, IResolverValidationOptions } from 'graphql-tools'; -import { mergeSchemas, mergeTypeDefs, mergeResolvers, IResolversComposerMapping, composeResolvers , getSchemaDirectiveFromDirectiveResolver } from 'graphql-toolkit'; +import { IResolvers, SchemaDirectiveVisitor, IDirectiveResolvers, IResolverValidationOptions, makeExecutableSchema } from 'graphql-tools'; +import { mergeSchemas, mergeTypeDefs, mergeResolvers, IResolversComposerMapping, composeResolvers , getSchemaDirectiveFromDirectiveResolver, extractResolversFromSchema } from 'graphql-toolkit'; import { Provider, Injector, ProviderScope, ServiceIdentifier } from '@graphql-modules/di'; -import { DocumentNode, GraphQLSchema, parse, GraphQLScalarType } from 'graphql'; +import { DocumentNode, GraphQLSchema, parse, GraphQLScalarType, printSchema } from 'graphql'; import { SchemaNotValidError, DependencyModuleUndefinedError, TypeDefNotFoundError, ModuleConfigRequiredError, IllegalResolverInvocationError, ContextBuilderError } from './errors'; import * as deepmerge from 'deepmerge'; import { ModuleSessionInfo } from './module-session-info'; @@ -243,20 +243,48 @@ export class GraphQLModule { const selfExtraSchemas = this.selfExtraSchemas; const schemaDirectives = this.schemaDirectives; if (importsSchemas.length || selfTypeDefs || selfExtraSchemas.length) { - this._cache.schema = mergeSchemas({ - schemas: [ + if (Object.keys(schemaDirectives).length) { + const schemas = [ ...importsSchemas, ...selfExtraSchemas, - ], - typeDefs: selfTypeDefs, - resolvers: selfEncapsulatedResolvers, - resolversComposition: selfEncapsulatedResolversComposition, - schemaDirectives, - resolverValidationOptions: selfResolverValidationOptions, - logger: 'clientError' in selfLogger ? { - log: message => selfLogger.clientError(message), - } : undefined, - }); + ]; + const schemaWithSelfResolvers = makeExecutableSchema({ + typeDefs: mergeTypeDefs(selfTypeDefs ? [ + ...schemas, + selfTypeDefs, + ] : schemas), + resolvers: selfEncapsulatedResolvers, + schemaDirectives, + }); + this._cache.schema = makeExecutableSchema({ + typeDefs: printSchema(schemaWithSelfResolvers), + resolvers: composeResolvers( + mergeResolvers([ + ...schemas.map(schema => extractResolversFromSchema(schema)), + extractResolversFromSchema(schemaWithSelfResolvers), + ]), + selfEncapsulatedResolversComposition, + ), + resolverValidationOptions: selfResolverValidationOptions, + logger: 'clientError' in selfLogger ? { + log: message => selfLogger.clientError(message), + } : undefined, + }); + } else { + this._cache.schema = mergeSchemas({ + schemas: [ + ...importsSchemas, + ...selfExtraSchemas, + ], + typeDefs: selfTypeDefs, + resolvers: selfEncapsulatedResolvers, + resolversComposition: selfEncapsulatedResolversComposition, + resolverValidationOptions: selfResolverValidationOptions, + logger: 'clientError' in selfLogger ? { + log: message => selfLogger.clientError(message), + } : undefined, + }); + } } else { this._cache.schema = null; } From c00381f8c65c45fa086c9c829e8d93a55a4475a8 Mon Sep 17 00:00:00 2001 From: Arda TANRIKULU Date: Thu, 21 Feb 2019 23:54:59 -0500 Subject: [PATCH 06/17] Fix Schema Directives with a workaround --- packages/core/package.json | 2 +- packages/core/src/graphql-module.ts | 11 ++++++++--- 2 files changed, 9 insertions(+), 4 deletions(-) diff --git a/packages/core/package.json b/packages/core/package.json index d7f5ab0bfe..9390beeb35 100644 --- a/packages/core/package.json +++ b/packages/core/package.json @@ -31,7 +31,7 @@ }, "dependencies": { "@graphql-modules/di": "0.4.2", - "graphql-toolkit": "0.0.6-1630e8f.0", + "graphql-toolkit": "0.0.6-582efa9.0", "tslib": "1.9.3" }, "peerDependencies": { diff --git a/packages/core/src/graphql-module.ts b/packages/core/src/graphql-module.ts index 439e164baf..ec41b9920c 100644 --- a/packages/core/src/graphql-module.ts +++ b/packages/core/src/graphql-module.ts @@ -1,7 +1,7 @@ import { IResolvers, SchemaDirectiveVisitor, IDirectiveResolvers, IResolverValidationOptions, makeExecutableSchema } from 'graphql-tools'; import { mergeSchemas, mergeTypeDefs, mergeResolvers, IResolversComposerMapping, composeResolvers , getSchemaDirectiveFromDirectiveResolver, extractResolversFromSchema } from 'graphql-toolkit'; import { Provider, Injector, ProviderScope, ServiceIdentifier } from '@graphql-modules/di'; -import { DocumentNode, GraphQLSchema, parse, GraphQLScalarType, printSchema } from 'graphql'; +import { DocumentNode, GraphQLSchema, parse, GraphQLScalarType } from 'graphql'; import { SchemaNotValidError, DependencyModuleUndefinedError, TypeDefNotFoundError, ModuleConfigRequiredError, IllegalResolverInvocationError, ContextBuilderError } from './errors'; import * as deepmerge from 'deepmerge'; import { ModuleSessionInfo } from './module-session-info'; @@ -242,12 +242,14 @@ export class GraphQLModule { const selfResolverValidationOptions = this.selfResolverValidationOptions; const selfExtraSchemas = this.selfExtraSchemas; const schemaDirectives = this.schemaDirectives; + // Workaround for schemaDirectives if (importsSchemas.length || selfTypeDefs || selfExtraSchemas.length) { if (Object.keys(schemaDirectives).length) { const schemas = [ ...importsSchemas, ...selfExtraSchemas, ]; + // It creates an executable schema to visit only this module's type definitions const schemaWithSelfResolvers = makeExecutableSchema({ typeDefs: mergeTypeDefs(selfTypeDefs ? [ ...schemas, @@ -257,11 +259,14 @@ export class GraphQLModule { schemaDirectives, }); this._cache.schema = makeExecutableSchema({ - typeDefs: printSchema(schemaWithSelfResolvers), + typeDefs: mergeTypeDefs([schemaWithSelfResolvers]), resolvers: composeResolvers( mergeResolvers([ ...schemas.map(schema => extractResolversFromSchema(schema)), - extractResolversFromSchema(schemaWithSelfResolvers), + // extracts only this module's type definitions' resolvers + extractResolversFromSchema(schemaWithSelfResolvers, { + selectedTypeDefs: selfTypeDefs, + }), ]), selfEncapsulatedResolversComposition, ), From b12e4322f653467f6eac1aabdf3b86cd303fa589 Mon Sep 17 00:00:00 2001 From: Arda TANRIKULU Date: Thu, 21 Feb 2019 23:54:59 -0500 Subject: [PATCH 07/17] Fix Schema Directives with a workaround --- packages/core/package.json | 2 +- packages/core/src/graphql-module.ts | 17 +++++++++++++++-- yarn.lock | 18 +++++++++--------- 3 files changed, 25 insertions(+), 12 deletions(-) diff --git a/packages/core/package.json b/packages/core/package.json index d7f5ab0bfe..71762df983 100644 --- a/packages/core/package.json +++ b/packages/core/package.json @@ -31,7 +31,7 @@ }, "dependencies": { "@graphql-modules/di": "0.4.2", - "graphql-toolkit": "0.0.6-1630e8f.0", + "graphql-toolkit": "0.0.6-67ccd2c.0", "tslib": "1.9.3" }, "peerDependencies": { diff --git a/packages/core/src/graphql-module.ts b/packages/core/src/graphql-module.ts index 439e164baf..0c66919f5d 100644 --- a/packages/core/src/graphql-module.ts +++ b/packages/core/src/graphql-module.ts @@ -1,7 +1,7 @@ import { IResolvers, SchemaDirectiveVisitor, IDirectiveResolvers, IResolverValidationOptions, makeExecutableSchema } from 'graphql-tools'; import { mergeSchemas, mergeTypeDefs, mergeResolvers, IResolversComposerMapping, composeResolvers , getSchemaDirectiveFromDirectiveResolver, extractResolversFromSchema } from 'graphql-toolkit'; import { Provider, Injector, ProviderScope, ServiceIdentifier } from '@graphql-modules/di'; -import { DocumentNode, GraphQLSchema, parse, GraphQLScalarType, printSchema } from 'graphql'; +import { DocumentNode, GraphQLSchema, parse, GraphQLScalarType, printSchema, print } from 'graphql'; import { SchemaNotValidError, DependencyModuleUndefinedError, TypeDefNotFoundError, ModuleConfigRequiredError, IllegalResolverInvocationError, ContextBuilderError } from './errors'; import * as deepmerge from 'deepmerge'; import { ModuleSessionInfo } from './module-session-info'; @@ -242,12 +242,14 @@ export class GraphQLModule { const selfResolverValidationOptions = this.selfResolverValidationOptions; const selfExtraSchemas = this.selfExtraSchemas; const schemaDirectives = this.schemaDirectives; + // Workaround for schemaDirectives if (importsSchemas.length || selfTypeDefs || selfExtraSchemas.length) { if (Object.keys(schemaDirectives).length) { const schemas = [ ...importsSchemas, ...selfExtraSchemas, ]; + // It creates an executable schema to visit only this module's type definitions const schemaWithSelfResolvers = makeExecutableSchema({ typeDefs: mergeTypeDefs(selfTypeDefs ? [ ...schemas, @@ -261,7 +263,17 @@ export class GraphQLModule { resolvers: composeResolvers( mergeResolvers([ ...schemas.map(schema => extractResolversFromSchema(schema)), - extractResolversFromSchema(schemaWithSelfResolvers), + // extracts only this module's type definitions' resolvers + // but you need directives even for an invalid schema + extractResolversFromSchema(schemaWithSelfResolvers, { + selectedTypeDefs: selfTypeDefs && mergeTypeDefs([ + selfTypeDefs, + ...schemaWithSelfResolvers + .getDirectives() + .map(directive => directive.astNode ? print(directive.astNode) : null) + .filter(e => e), + ]), + }), ]), selfEncapsulatedResolversComposition, ), @@ -289,6 +301,7 @@ export class GraphQLModule { this._cache.schema = null; } } catch (e) { + throw e; if (e.message === 'Must provide typeDefs') { this._cache.schema = null; } else if (e.message.includes(`Type "`) && e.message.includes(`" not found in document.`)) { diff --git a/yarn.lock b/yarn.lock index d003b6fa02..7559b363bc 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1269,10 +1269,10 @@ deep-is@~0.1.3: resolved "https://registry.yarnpkg.com/deep-is/-/deep-is-0.1.3.tgz#b369d6fb5dbc13eecf524f91b070feedc357cf34" integrity sha1-s2nW+128E+7PUk+RsHD+7cNXzzQ= -deepmerge@3.1.0: - version "3.1.0" - resolved "https://registry.yarnpkg.com/deepmerge/-/deepmerge-3.1.0.tgz#a612626ce4803da410d77554bfd80361599c034d" - integrity sha512-/TnecbwXEdycfbsM2++O3eGiatEFHjjNciHEwJclM+T5Kd94qD1AP+2elP/Mq0L5b9VZJao5znR01Mz6eX8Seg== +deepmerge@3.2.0: + version "3.2.0" + resolved "https://registry.yarnpkg.com/deepmerge/-/deepmerge-3.2.0.tgz#58ef463a57c08d376547f8869fdc5bcee957f44e" + integrity sha512-6+LuZGU7QCNUnAJyX8cIrlzoEgggTM6B7mm+znKOX4t5ltluT9KLjN6g61ECMS0LTsLW7yDpNoxhix5FZcrIow== default-require-extensions@^2.0.0: version "2.0.0" @@ -1919,12 +1919,12 @@ graphql-tag@2.10.1: resolved "https://registry.yarnpkg.com/graphql-tag/-/graphql-tag-2.10.1.tgz#10aa41f1cd8fae5373eaf11f1f67260a3cad5e02" integrity sha512-jApXqWBzNXQ8jYa/HLkZJaVw9jgwNqZkywa2zfFn16Iv1Zb7ELNHkJaXHR7Quvd5SIGsy6Ny7SUKATgnu05uEg== -graphql-toolkit@0.0.6-1630e8f.0: - version "0.0.6-1630e8f.0" - resolved "https://registry.yarnpkg.com/graphql-toolkit/-/graphql-toolkit-0.0.6-1630e8f.0.tgz#9a2404a45ec45cdbbaa0d26348ce412e8f220ba5" - integrity sha512-EPwQYDjnq9nCImqJoPVzGx0gvyPzmn28VyvL9XE2BX2a7rTrVKO8VzRVFcoB4C506GAdCQZEHiz7l1w8X9DHxw== +graphql-toolkit@0.0.6-67ccd2c.0: + version "0.0.6-67ccd2c.0" + resolved "https://registry.yarnpkg.com/graphql-toolkit/-/graphql-toolkit-0.0.6-67ccd2c.0.tgz#14d57f02fa391f65d8b5618727b6f609083b7c85" + integrity sha512-FoZNSgLMwHQPhkRBIZ1pUJnI9oObXblHAVpCpGPyC7duMphmRkJvHludBEVS5I6KzxUyH8Ujm47ujjp62insPw== dependencies: - deepmerge "3.1.0" + deepmerge "3.2.0" glob "7.1.3" graphql-import "0.7.1" graphql-tag-pluck "0.5.0" From fa111fffaa3dcb4a5c1890dc090a9c0eb763c136 Mon Sep 17 00:00:00 2001 From: Arda TANRIKULU Date: Fri, 22 Feb 2019 08:19:37 -0500 Subject: [PATCH 08/17] Add test for child schema mutations --- packages/core/tests/graphql-module.spec.ts | 33 ++++++++++++++++++++-- 1 file changed, 30 insertions(+), 3 deletions(-) diff --git a/packages/core/tests/graphql-module.spec.ts b/packages/core/tests/graphql-module.spec.ts index 4dae0f35e6..ee45cfc894 100644 --- a/packages/core/tests/graphql-module.spec.ts +++ b/packages/core/tests/graphql-module.spec.ts @@ -992,18 +992,45 @@ describe('GraphQLModule', () => { `, resolvers: { Query: { - foo: (root, args, context, info) => !!info.schema['__DIRTY__'], + isDirty: (root, args, context, info) => !!info.schema['__DIRTY__'], }, }, middleware: ({schema}) => { schema['__DIRTY__'] = true; return { schema }; }, }); const result = await execute({ schema, - document: gql`query { foo }`, + document: gql`query { isDirty }`, + contextValue: await context({ req: {} }), + }); + expect(result.errors).toBeFalsy(); + expect(result.data['isDirty']).toBeTruthy(); + }); + it('should encapsulate the schema mutations using middleware', async () => { + const FooModule = new GraphQLModule({ + typeDefs: gql` + type Query { + isDirty: Boolean + } + `, + resolvers: { + Query: { + isDirty: (root, args, context, info) => !!info.schema['__DIRTY__'], + }, + }, + middleware: ({schema}) => { schema['__DIRTY__'] = true; return { schema }; }, + }); + const { schema, context } = new GraphQLModule({ + imports: [ + FooModule, + ], + }); + const result = await execute({ + schema, + document: gql`query { isDirty }`, contextValue: await context({ req: {} }), }); expect(result.errors).toBeFalsy(); - expect(result.data['foo']).toBeTruthy(); + expect(result.data['isDirty']).toBeTruthy(); }); it('should avoid getting non-configured module', async () => { const FOO = Symbol('FOO'); From 383ca0c2c2ecef93d99c69816f75735375864193 Mon Sep 17 00:00:00 2001 From: Arda TANRIKULU Date: Fri, 22 Feb 2019 08:27:23 -0500 Subject: [PATCH 09/17] Fix error handling --- packages/core/src/graphql-module.ts | 1 - packages/core/tests/graphql-module.spec.ts | 2 +- 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/packages/core/src/graphql-module.ts b/packages/core/src/graphql-module.ts index 8574ffabf7..900038d683 100644 --- a/packages/core/src/graphql-module.ts +++ b/packages/core/src/graphql-module.ts @@ -301,7 +301,6 @@ export class GraphQLModule { this._cache.schema = null; } } catch (e) { - throw e; if (e.message === 'Must provide typeDefs') { this._cache.schema = null; } else if (e.message.includes(`Type "`) && e.message.includes(`" not found in document.`)) { diff --git a/packages/core/tests/graphql-module.spec.ts b/packages/core/tests/graphql-module.spec.ts index ee45cfc894..b49f1a3b40 100644 --- a/packages/core/tests/graphql-module.spec.ts +++ b/packages/core/tests/graphql-module.spec.ts @@ -987,7 +987,7 @@ describe('GraphQLModule', () => { const { schema, context } = new GraphQLModule({ typeDefs: gql` type Query { - foo: Boolean + isDirty: Boolean } `, resolvers: { From 37e57ddcd55adcc17647d82229d845e7f2f51962 Mon Sep 17 00:00:00 2001 From: Arda TANRIKULU Date: Fri, 22 Feb 2019 08:32:07 -0500 Subject: [PATCH 10/17] Fix schema directives --- packages/core/src/graphql-module.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/core/src/graphql-module.ts b/packages/core/src/graphql-module.ts index 900038d683..c3396588b6 100644 --- a/packages/core/src/graphql-module.ts +++ b/packages/core/src/graphql-module.ts @@ -1,7 +1,7 @@ import { IResolvers, SchemaDirectiveVisitor, IDirectiveResolvers, IResolverValidationOptions, makeExecutableSchema } from 'graphql-tools'; import { mergeSchemas, mergeTypeDefs, mergeResolvers, IResolversComposerMapping, composeResolvers , getSchemaDirectiveFromDirectiveResolver, extractResolversFromSchema } from 'graphql-toolkit'; import { Provider, Injector, ProviderScope, ServiceIdentifier } from '@graphql-modules/di'; -import { DocumentNode, GraphQLSchema, parse, GraphQLScalarType, print } from 'graphql'; +import { DocumentNode, GraphQLSchema, parse, GraphQLScalarType, print, printSchema } from 'graphql'; import { SchemaNotValidError, DependencyModuleUndefinedError, TypeDefNotFoundError, ModuleConfigRequiredError, IllegalResolverInvocationError, ContextBuilderError } from './errors'; import * as deepmerge from 'deepmerge'; import { ModuleSessionInfo } from './module-session-info'; @@ -259,7 +259,7 @@ export class GraphQLModule { schemaDirectives, }); this._cache.schema = makeExecutableSchema({ - typeDefs: mergeTypeDefs([schemaWithSelfResolvers]), + typeDefs: printSchema(schemaWithSelfResolvers), resolvers: composeResolvers( mergeResolvers([ ...schemas.map(schema => extractResolversFromSchema(schema)), From 481818445c86fd3e611ac331dbef94a2754de836 Mon Sep 17 00:00:00 2001 From: Arda TANRIKULU Date: Thu, 28 Feb 2019 15:10:53 -0500 Subject: [PATCH 11/17] Use latest version of graphql-toolkit --- packages/core/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/core/package.json b/packages/core/package.json index 71762df983..6ec80baeb5 100644 --- a/packages/core/package.json +++ b/packages/core/package.json @@ -31,7 +31,7 @@ }, "dependencies": { "@graphql-modules/di": "0.4.2", - "graphql-toolkit": "0.0.6-67ccd2c.0", + "graphql-toolkit": "0.1.1", "tslib": "1.9.3" }, "peerDependencies": { From 20cb54a3053e4754ddc1ddc19cb6e59c32de4948 Mon Sep 17 00:00:00 2001 From: Arda TANRIKULU Date: Thu, 28 Feb 2019 15:21:12 -0500 Subject: [PATCH 12/17] Allow empty typeDefs --- packages/core/src/graphql-module.ts | 10 ++++++---- packages/core/tests/graphql-module.spec.ts | 17 +++++++++++++++++ 2 files changed, 23 insertions(+), 4 deletions(-) diff --git a/packages/core/src/graphql-module.ts b/packages/core/src/graphql-module.ts index c3396588b6..b2c4175b18 100644 --- a/packages/core/src/graphql-module.ts +++ b/packages/core/src/graphql-module.ts @@ -288,7 +288,7 @@ export class GraphQLModule { ...importsSchemas, ...selfExtraSchemas, ], - typeDefs: selfTypeDefs, + typeDefs: selfTypeDefs || undefined, resolvers: selfEncapsulatedResolvers, resolversComposition: selfEncapsulatedResolversComposition, resolverValidationOptions: selfResolverValidationOptions, @@ -552,9 +552,11 @@ export class GraphQLModule { if (typeof typeDefsDefinitions === 'string') { typeDefs = parse(typeDefsDefinitions); } else if (Array.isArray(typeDefsDefinitions)) { - typeDefs = mergeTypeDefs(typeDefsDefinitions, { - useSchemaDefinition: false, - }); + if (typeDefsDefinitions.length) { + typeDefs = mergeTypeDefs(typeDefsDefinitions, { + useSchemaDefinition: false, + }); + } } else if (typeDefsDefinitions) { typeDefs = typeDefsDefinitions; } diff --git a/packages/core/tests/graphql-module.spec.ts b/packages/core/tests/graphql-module.spec.ts index b49f1a3b40..9a05c773c4 100644 --- a/packages/core/tests/graphql-module.spec.ts +++ b/packages/core/tests/graphql-module.spec.ts @@ -1282,4 +1282,21 @@ describe('GraphQLModule', () => { }); expect(data.foo).toBe('FOO'); }); + it('should generate schemaless module if empty typeDefs and resolvers specified', async () => { + const { schema: schemaA } = new GraphQLModule({ + typeDefs: [], + resolvers: {}, + }); + expect(schemaA).toBeNull(); + const { schema: schemaB } = new GraphQLModule({ + typeDefs: '', + resolvers: {}, + }); + expect(schemaB).toBeNull(); + const { schema: schemaC } = new GraphQLModule({ + typeDefs: [''], + resolvers: {}, + }); + expect(schemaC).toBeNull(); + }); }); From e3142ba186dcf5ff924129e4a70015c6845b8956 Mon Sep 17 00:00:00 2001 From: Arda TANRIKULU Date: Thu, 28 Feb 2019 15:27:11 -0500 Subject: [PATCH 13/17] Enhance tests --- packages/core/tests/graphql-module.spec.ts | 18 +++++++++++------- 1 file changed, 11 insertions(+), 7 deletions(-) diff --git a/packages/core/tests/graphql-module.spec.ts b/packages/core/tests/graphql-module.spec.ts index 9a05c773c4..0b60e00910 100644 --- a/packages/core/tests/graphql-module.spec.ts +++ b/packages/core/tests/graphql-module.spec.ts @@ -1282,21 +1282,25 @@ describe('GraphQLModule', () => { }); expect(data.foo).toBe('FOO'); }); - it('should generate schemaless module if empty typeDefs and resolvers specified', async () => { - const { schema: schemaA } = new GraphQLModule({ + it('should generate schemaless module if an empty array typeDefs specified', async () => { + const { schema } = new GraphQLModule({ typeDefs: [], resolvers: {}, }); - expect(schemaA).toBeNull(); - const { schema: schemaB } = new GraphQLModule({ + expect(schema).toBeNull(); + }); + it('should generate schemaless module if empty string typeDefs specified', async () => { + const { schema } = new GraphQLModule({ typeDefs: '', resolvers: {}, }); - expect(schemaB).toBeNull(); - const { schema: schemaC } = new GraphQLModule({ + expect(schema).toBeNull(); + }); + it('should generate schemaless module if an array with an empty string typeDefs specified', async () => { + const { schema } = new GraphQLModule({ typeDefs: [''], resolvers: {}, }); - expect(schemaC).toBeNull(); + expect(schema).toBeNull(); }); }); From e7c10c53d97e7810136002f9676b1d6ec9c63e22 Mon Sep 17 00:00:00 2001 From: Arda TANRIKULU Date: Thu, 28 Feb 2019 15:31:28 -0500 Subject: [PATCH 14/17] Filter empty typeDefs --- packages/core/src/graphql-module.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/packages/core/src/graphql-module.ts b/packages/core/src/graphql-module.ts index b2c4175b18..3176a641e3 100644 --- a/packages/core/src/graphql-module.ts +++ b/packages/core/src/graphql-module.ts @@ -53,7 +53,7 @@ export interface GraphQLModuleOptions { * You can also pass a function that will get the module's config as argument, and should return * the type definitions. */ - typeDefs?: GraphQLModuleOption; + typeDefs?: GraphQLModuleOption, Config, Session, Context>; /** * Resolvers object, or a function will get the module's config as argument, and should * return the resolvers object. @@ -552,6 +552,7 @@ export class GraphQLModule { if (typeof typeDefsDefinitions === 'string') { typeDefs = parse(typeDefsDefinitions); } else if (Array.isArray(typeDefsDefinitions)) { + typeDefsDefinitions = typeDefsDefinitions.filter(typeDefsDefinition => typeDefsDefinition); if (typeDefsDefinitions.length) { typeDefs = mergeTypeDefs(typeDefsDefinitions, { useSchemaDefinition: false, From 43c10494d333c5ed72736debe785f7eeda7c48f4 Mon Sep 17 00:00:00 2001 From: Arda TANRIKULU Date: Mon, 4 Mar 2019 07:49:59 -0500 Subject: [PATCH 15/17] Update graphql-toolkit --- packages/core/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/core/package.json b/packages/core/package.json index 6ec80baeb5..a2111bb945 100644 --- a/packages/core/package.json +++ b/packages/core/package.json @@ -31,7 +31,7 @@ }, "dependencies": { "@graphql-modules/di": "0.4.2", - "graphql-toolkit": "0.1.1", + "graphql-toolkit": "0.0.6-61b862f.0", "tslib": "1.9.3" }, "peerDependencies": { From d2c77fa4d03d22fca6a4834cdbc20e0db6d06eb7 Mon Sep 17 00:00:00 2001 From: Arda TANRIKULU Date: Tue, 19 Mar 2019 02:10:28 -0400 Subject: [PATCH 16/17] Use canary of graphql-toolkit --- docs/guides/data-loader.md | 2 +- docs/introduction/dependency-injection.md | 16 ++++++++++------ packages/core/package.json | 2 +- packages/graphql-modules/package.json | 1 + yarn.lock | 9 +++++---- 5 files changed, 18 insertions(+), 12 deletions(-) diff --git a/docs/guides/data-loader.md b/docs/guides/data-loader.md index e7437769a3..73feef754b 100644 --- a/docs/guides/data-loader.md +++ b/docs/guides/data-loader.md @@ -39,7 +39,7 @@ You can see how to generate DataLoader in GraphQLModules using factory functions scope: ProviderScope.Session provide: MY_DATA_LOADER, useFactory: - Inject(ModuleSessionInfo)( + InjectFunction(ModuleSessionInfo)( // Use Dependency Injection to get ModuleSessionInfo to access network session ({ session }) => new DataLoader( ids => genUsers(session.req.authToken, ids) diff --git a/docs/introduction/dependency-injection.md b/docs/introduction/dependency-injection.md index 574e42d170..577ba2c1ee 100644 --- a/docs/introduction/dependency-injection.md +++ b/docs/introduction/dependency-injection.md @@ -228,7 +228,7 @@ Example; ```typescript import { Injectable } from '@graphql-modules/di'; -import { OnRequest } from '@graphql-modules/core'; +import { OnInit } from '@graphql-modules/core'; @Injectable() export class DatabaseProvider implements OnInit { constructor(private dbClient: DbClient) {} @@ -244,7 +244,8 @@ export class DatabaseProvider implements OnInit { You can get access to useful information: the top `GraphQLModule` instance, GraphQL Context, and the network session by defining this hook as a method in your class provider. ```typescript -import { Injectable, OnRequest } from '@graphql-modules/core'; +import { Injectable } from '@graphql-modules/di'; +import { OnRequest } from '@graphql-modules/core'; Example; @@ -273,7 +274,8 @@ It takes same parameter like `OnRequest` hook but it gets called even before the Example; ```typescript -import { Injectable, OnResponse } from '@graphql-modules/core'; +import { Injectable } from '@graphql-modules/di'; +import { OnResponse } from '@graphql-modules/core'; @Injectable() export class MyProvider implements OnResponse { @@ -314,7 +316,8 @@ This hook is similar to `OnRequest` hook, but this is called on the initializati Example; ```typescript -import { Injectable, OnConnect } from '@graphql-modules/core'; +import { Injectable } from '@graphql-modules/di'; +import { OnConnect } from '@graphql-modules/core'; @Injectable({ scope: ProviderScope.Session @@ -339,7 +342,8 @@ This hook is similar to `OnResponse` hook, but this is called on the termination [You can learn more from Apollo docs.](https://www.apollographql.com/docs/graphql-subscriptions/authentication.html) ```typescript -import { Injectable, OnDisconnect } from '@graphql-modules/core'; +import { Injectable } from '@graphql-modules/di'; +import { OnDisconnect } from '@graphql-modules/core'; @Injectable() export class MyProvider implements OnDisconnect { @@ -396,4 +400,4 @@ You can see more about scoped providers; ## Built-in `ModuleSessionInfo` Provider -Every GraphQL-Module creates a `ModuleSessionInfo` instance in each network request that contains raw Request from the GraphQL Server, `SessionInjector` that contains Session-scoped instances together with Application-scoped ones and `Context` object which is constructed with `contextBuilder` of the module. But, notice that you cannot use this built-in provider. +Every GraphQL-Module creates a `ModuleSessionInfo` instance in each network request that contains raw Request from the GraphQL Server, `SessionInjector` that contains Session-scoped instances together with Application-scoped ones and `Context` object which is constructed with `contextBuilder` of the module. But, notice that you cannot use this built-in provider in Application Scope. diff --git a/packages/core/package.json b/packages/core/package.json index 77644e6661..36a487ce16 100644 --- a/packages/core/package.json +++ b/packages/core/package.json @@ -32,7 +32,7 @@ }, "dependencies": { "@graphql-modules/di": "0.6.5", - "graphql-toolkit": "0.2.6", + "graphql-toolkit": "0.2.7-8431ebe.0", "graphql-tools": "4.0.4", "tslib": "1.9.3" }, diff --git a/packages/graphql-modules/package.json b/packages/graphql-modules/package.json index 3bcc849754..1bfd7338d8 100644 --- a/packages/graphql-modules/package.json +++ b/packages/graphql-modules/package.json @@ -43,6 +43,7 @@ "@graphql-modules/core": "0.6.5", "tslib": "1.9.3" }, + "sideEffects": false, "main": "dist/commonjs/index.js", "module": "dist/esnext/index.js", "typings": "dist/esnext/index.d.ts", diff --git a/yarn.lock b/yarn.lock index 7abba267a3..294d825a5f 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2230,16 +2230,17 @@ graphql-tag@2.10.1: resolved "https://registry.yarnpkg.com/graphql-tag/-/graphql-tag-2.10.1.tgz#10aa41f1cd8fae5373eaf11f1f67260a3cad5e02" integrity sha512-jApXqWBzNXQ8jYa/HLkZJaVw9jgwNqZkywa2zfFn16Iv1Zb7ELNHkJaXHR7Quvd5SIGsy6Ny7SUKATgnu05uEg== -graphql-toolkit@0.2.6: - version "0.2.6" - resolved "https://registry.yarnpkg.com/graphql-toolkit/-/graphql-toolkit-0.2.6.tgz#539f82450c85d81ecb81b5c825d0c7271b458ece" - integrity sha512-VqvsKHYxKW3/qoJIaO17JH6AfClHcPvZRMN2rG/y6fsTKCyCCS7P1+7aKu6RPUwFkW+reqxxrXjEGOG2bkCcMQ== +graphql-toolkit@0.2.7-c720d55.0: + version "0.2.7-c720d55.0" + resolved "https://registry.yarnpkg.com/graphql-toolkit/-/graphql-toolkit-0.2.7-c720d55.0.tgz#69719bcaad79502775f0519ba93df451c0137e93" + integrity sha512-bE1aZfmcFfH72fgZ1k8oZXBT6btB8NyZKeYU8KaR9LBLHdEC+8XaosivmBZtpoHOzltWycNuSJifYLLUlpog2g== dependencies: aggregate-error "2.2.0" deepmerge "3.2.0" glob "7.1.3" graphql-import "0.7.1" graphql-tag-pluck "0.7.0" + graphql-tools "4.0.4" is-glob "4.0.0" is-valid-path "0.1.1" lodash "4.17.11" From 6b72e71bc6a90ca25e21a02c7a75d50a6c49f1f9 Mon Sep 17 00:00:00 2001 From: Arda TANRIKULU Date: Wed, 20 Mar 2019 04:28:47 -0400 Subject: [PATCH 17/17] Fix resolvers composition encapsulation --- packages/core/package.json | 2 +- packages/core/src/graphql-module.ts | 20 ++++++++++++++++---- yarn.lock | 8 ++++---- 3 files changed, 21 insertions(+), 9 deletions(-) diff --git a/packages/core/package.json b/packages/core/package.json index 36a487ce16..81c22dd298 100644 --- a/packages/core/package.json +++ b/packages/core/package.json @@ -32,7 +32,7 @@ }, "dependencies": { "@graphql-modules/di": "0.6.5", - "graphql-toolkit": "0.2.7-8431ebe.0", + "graphql-toolkit": "0.2.7", "graphql-tools": "4.0.4", "tslib": "1.9.3" }, diff --git a/packages/core/src/graphql-module.ts b/packages/core/src/graphql-module.ts index 85e5a3a805..9f5fa939d3 100644 --- a/packages/core/src/graphql-module.ts +++ b/packages/core/src/graphql-module.ts @@ -11,6 +11,7 @@ import { mergeSchemas, getSchemaDirectiveFromDirectiveResolver, mergeTypeDefs, + ResolversCompositionFn, } from 'graphql-toolkit'; import { Provider, Injector, ProviderScope } from '@graphql-modules/di'; import { DocumentNode, GraphQLSchema, parse, GraphQLScalarType } from 'graphql'; @@ -699,10 +700,8 @@ export class GraphQLModule>) => { + return [ (next: any) => async (root: any, args: any, appContext: any, info: any) => { if (appContext instanceof Promise) { appContext = await appContext; @@ -725,6 +724,19 @@ export class GraphQLModule