UNPKG

@nestjs/graphql

Version:

Nest - modern, fast, powerful node.js web framework (@graphql)

192 lines (191 loc) 9.32 kB
"use strict"; 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;