Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feature/recursive merge schemas #335

Merged
merged 20 commits into from
Mar 20, 2019
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion packages/core/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -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"
},
Expand Down
162 changes: 53 additions & 109 deletions packages/core/src/graphql-module.ts
Original file line number Diff line number Diff line change
@@ -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';
Expand Down Expand Up @@ -218,118 +218,62 @@ export class GraphQLModule<Config = any, Session = any, Context = any> {
return this._moduleConfig;
}

/*
private buildSchemaWithMergeSchemas() {
const schemaSet = new Set<GraphQLSchema>();
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<ModuleContext<Context>>({
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
* the `typeDefs` and `resolvers` into `GraphQLSchema`
*/
get schema() {
if (typeof this._cache.schema === 'undefined') {
this.buildSchemaWithMakeExecutableSchema();
// this.buildSchemaWithMergeSchemas();
this.checkConfiguration();
const importsSchemas = new Array<GraphQLSchema>();
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();
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;
}
Expand Down Expand Up @@ -405,7 +349,7 @@ export class GraphQLModule<Config = any, Session = any, Context = any> {
}
typeDefsArr = typeDefsArr.concat(this.extraSchemas);
if (typeDefsArr.length) {
this._cache.typeDefs = mergeGraphQLSchemas(typeDefsArr, {
this._cache.typeDefs = mergeTypeDefs(typeDefsArr, {
useSchemaDefinition: false,
});
} else {
Expand Down Expand Up @@ -568,7 +512,7 @@ export class GraphQLModule<Config = any, Session = any, Context = any> {
if (typeof typeDefsDefinitions === 'string') {
typeDefs = parse(typeDefsDefinitions);
} else if (Array.isArray(typeDefsDefinitions)) {
typeDefs = mergeGraphQLSchemas(typeDefsDefinitions, {
typeDefs = mergeTypeDefs(typeDefsDefinitions, {
useSchemaDefinition: false,
});
} else if (typeDefsDefinitions) {
Expand Down
8 changes: 4 additions & 4 deletions yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -1919,10 +1919,10 @@ [email protected]:
resolved "https://registry.yarnpkg.com/graphql-tag/-/graphql-tag-2.10.1.tgz#10aa41f1cd8fae5373eaf11f1f67260a3cad5e02"
integrity sha512-jApXqWBzNXQ8jYa/HLkZJaVw9jgwNqZkywa2zfFn16Iv1Zb7ELNHkJaXHR7Quvd5SIGsy6Ny7SUKATgnu05uEg==

[email protected].5:
version "0.0.5"
resolved "https://registry.yarnpkg.com/graphql-toolkit/-/graphql-toolkit-0.0.5.tgz#9e6ebe3d4b33fc329e5ee3b7775bfe7fba2f48a5"
integrity sha512-655RP1y8cn65mOa9EE/jnttczHE0lFXpOV1zYLTsE1A0b5j8RVuKWllSZBnnL2WHSAPPqLZ1oJEZV2uzSdV9VQ==
[email protected].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"
Expand Down