@nestjs/graphql
Version:
Nest - modern, fast, powerful node.js web framework (@graphql)
192 lines (191 loc) • 9.32 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.GraphQLFactory = void 0;
const tslib_1 = require("tslib");
const merge_1 = require("@graphql-tools/merge");
const schema_1 = require("@graphql-tools/schema");
const utils_1 = require("@graphql-tools/utils");
const common_1 = require("@nestjs/common");
const apollo_server_core_1 = require("apollo-server-core");
const fs_1 = require("fs");
const graphql_1 = require("graphql");
const lodash_1 = require("lodash");
const graphql_ast_explorer_1 = require("./graphql-ast.explorer");
const graphql_schema_builder_1 = require("./graphql-schema.builder");
const graphql_schema_host_1 = require("./graphql-schema.host");
const services_1 = require("./services");
const utils_2 = require("./utils");
let GraphQLFactory = class GraphQLFactory {
constructor(resolversExplorerService, scalarsExplorerService, pluginsExplorerService, graphqlAstExplorer, gqlSchemaBuilder, gqlSchemaHost) {
this.resolversExplorerService = resolversExplorerService;
this.scalarsExplorerService = scalarsExplorerService;
this.pluginsExplorerService = pluginsExplorerService;
this.graphqlAstExplorer = graphqlAstExplorer;
this.gqlSchemaBuilder = gqlSchemaBuilder;
this.gqlSchemaHost = gqlSchemaHost;
}
async mergeOptions(options = { typeDefs: [] }) {
const resolvers = this.resolversExplorerService.explore();
const typesResolvers = (0, utils_2.extend)(this.scalarsExplorerService.explore(), resolvers);
options.plugins = (0, utils_2.extend)(options.plugins || [], this.pluginsExplorerService.explore());
const transformSchema = async (schema) => options.transformSchema ? await options.transformSchema(schema) : schema;
if (options.autoSchemaFile) {
const autoGeneratedSchema = await this.gqlSchemaBuilder.build(options.autoSchemaFile, options, this.resolversExplorerService.getAllCtors());
const executableSchema = (0, schema_1.makeExecutableSchema)({
resolvers: (0, utils_2.extend)(typesResolvers, options.resolvers),
typeDefs: (0, apollo_server_core_1.gql) `
${(0, graphql_1.printSchema)(autoGeneratedSchema)}
`,
resolverValidationOptions: {
...(options.resolverValidationOptions || {}),
requireResolversForResolveType: 'ignore',
},
});
let schema = options.schema
? (0, merge_1.mergeSchemas)({
schemas: [options.schema, executableSchema],
})
: executableSchema;
const autoGeneratedSchemaConfig = autoGeneratedSchema.toConfig();
const schemaConfig = this.overrideOrExtendResolvers(schema.toConfig(), autoGeneratedSchemaConfig);
schema = new graphql_1.GraphQLSchema(schemaConfig);
if (options.schemaDirectives) {
utils_1.SchemaDirectiveVisitor.visitSchemaDirectives(schema, options.schemaDirectives);
}
schema = await transformSchema(schema);
schema = options.sortSchema ? (0, graphql_1.lexicographicSortSchema)(schema) : schema;
this.gqlSchemaHost.schema = schema;
return {
...options,
typeDefs: undefined,
schema,
};
}
if ((0, lodash_1.isEmpty)(options.typeDefs)) {
const schema = await transformSchema(options.schema);
this.gqlSchemaHost.schema = schema;
return {
...options,
typeDefs: undefined,
schema,
};
}
const executableSchema = (0, schema_1.makeExecutableSchema)({
resolvers: (0, utils_2.extend)(typesResolvers, options.resolvers),
directiveResolvers: options.directiveResolvers,
schemaDirectives: options.schemaDirectives,
schemaTransforms: options.schemaTransforms,
typeDefs: (0, apollo_server_core_1.gql) `
${options.typeDefs}
`,
resolverValidationOptions: options.resolverValidationOptions,
});
let schema = options.schema
? (0, merge_1.mergeSchemas)({
schemas: [options.schema, executableSchema],
})
: executableSchema;
(0, utils_2.removeTempField)(schema);
schema = await transformSchema(schema);
schema = options.sortSchema ? (0, graphql_1.lexicographicSortSchema)(schema) : schema;
this.gqlSchemaHost.schema = schema;
return {
...options,
typeDefs: undefined,
schema,
};
}
overrideOrExtendResolvers(executableSchemaConfig, autoGeneratedSchemaConfig) {
const schemaConfig = autoGeneratedSchemaConfig;
const rootResolverKeys = [
'mutation',
'query',
'subscription',
];
rootResolverKeys
.filter((key) => executableSchemaConfig[key] && schemaConfig[key])
.forEach((key) => {
const executableSchemaFields = executableSchemaConfig[key].getFields();
const schemaFields = schemaConfig[key].getFields();
(0, lodash_1.forEach)(executableSchemaFields, (value, resolverName) => {
if (schemaFields[resolverName]) {
schemaFields[resolverName].resolve =
executableSchemaFields[resolverName].resolve;
schemaFields[resolverName].subscribe =
executableSchemaFields[resolverName].subscribe;
}
else {
schemaFields[resolverName] = executableSchemaFields[resolverName];
}
});
});
const getAutoGeneratedTypeByName = (name) => schemaConfig.types.find((type) => type.name === name);
executableSchemaConfig.types
.filter((type) => type instanceof graphql_1.GraphQLObjectType)
.forEach((type) => {
const fields = type.getFields();
const autoGeneratedType = getAutoGeneratedTypeByName(type.name);
if (!autoGeneratedType) {
return;
}
const implementedInterfaces = autoGeneratedType.getInterfaces() || [];
if (implementedInterfaces.length > 0) {
implementedInterfaces.forEach((interfaceRef) => {
const interfaceInExecutableSchema = executableSchemaConfig.types.find((type) => type.name === interfaceRef.name);
(0, lodash_1.forEach)(interfaceRef.getFields(), (value, key) => {
const fieldInExecutableSchema = interfaceInExecutableSchema.getFields()[key];
if (!fieldInExecutableSchema) {
return;
}
if (!fieldInExecutableSchema.resolve) {
return;
}
const baseClassField = autoGeneratedType.getFields()[key];
baseClassField &&
(baseClassField.resolve = fieldInExecutableSchema.resolve);
});
});
}
(0, lodash_1.forEach)(fields, (value, key) => {
if (!value.resolve) {
return;
}
const field = autoGeneratedType.getFields()[key];
field && (field.resolve = value.resolve);
});
});
return schemaConfig;
}
async generateDefinitions(typeDefs, options) {
if ((0, lodash_1.isEmpty)(typeDefs) || !options.definitions) {
return;
}
const definitionsGeneratorOptions = {
emitTypenameField: options.definitions.emitTypenameField,
skipResolverArgs: options.definitions.skipResolverArgs,
defaultScalarType: options.definitions.defaultScalarType,
customScalarTypeMapping: options.definitions.customScalarTypeMapping,
additionalHeader: options.definitions.additionalHeader,
defaultTypeMapping: options.definitions.defaultTypeMapping,
enumsAsTypes: options.definitions.enumsAsTypes,
};
const tsFile = await this.graphqlAstExplorer.explore((0, apollo_server_core_1.gql) `
${typeDefs}
`, options.definitions.path, options.definitions.outputAs, definitionsGeneratorOptions);
if (!(0, fs_1.existsSync)(options.definitions.path) ||
!(0, fs_1.lstatSync)(options.definitions.path).isFile() ||
(0, fs_1.readFileSync)(options.definitions.path, 'utf8') !== tsFile.getFullText()) {
await tsFile.save();
}
}
};
GraphQLFactory = (0, tslib_1.__decorate)([
(0, common_1.Injectable)(),
(0, tslib_1.__metadata)("design:paramtypes", [services_1.ResolversExplorerService,
services_1.ScalarsExplorerService,
services_1.PluginsExplorerService,
graphql_ast_explorer_1.GraphQLAstExplorer,
graphql_schema_builder_1.GraphQLSchemaBuilder,
graphql_schema_host_1.GraphQLSchemaHost])
], GraphQLFactory);
exports.GraphQLFactory = GraphQLFactory;