UNPKG

9.37 kBJavaScriptView Raw
1"use strict";
2Object.defineProperty(exports, "__esModule", { value: true });
3exports.GraphQLFactory = void 0;
4const tslib_1 = require("tslib");
5const common_1 = require("@nestjs/common");
6const apollo_server_core_1 = require("apollo-server-core");
7const fs_1 = require("fs");
8const graphql_1 = require("graphql");
9const merge_1 = require("@graphql-tools/merge");
10const schema_1 = require("@graphql-tools/schema");
11const utils_1 = require("@graphql-tools/utils");
12const lodash_1 = require("lodash");
13const graphql_ast_explorer_1 = require("./graphql-ast.explorer");
14const graphql_schema_builder_1 = require("./graphql-schema.builder");
15const graphql_schema_host_1 = require("./graphql-schema.host");
16const services_1 = require("./services");
17const utils_2 = require("./utils");
18let GraphQLFactory = class GraphQLFactory {
19 constructor(resolversExplorerService, scalarsExplorerService, pluginsExplorerService, graphqlAstExplorer, gqlSchemaBuilder, gqlSchemaHost) {
20 this.resolversExplorerService = resolversExplorerService;
21 this.scalarsExplorerService = scalarsExplorerService;
22 this.pluginsExplorerService = pluginsExplorerService;
23 this.graphqlAstExplorer = graphqlAstExplorer;
24 this.gqlSchemaBuilder = gqlSchemaBuilder;
25 this.gqlSchemaHost = gqlSchemaHost;
26 }
27 mergeOptions(options = { typeDefs: [] }) {
28 return tslib_1.__awaiter(this, void 0, void 0, function* () {
29 const resolvers = this.resolversExplorerService.explore();
30 const typesResolvers = utils_2.extend(this.scalarsExplorerService.explore(), resolvers);
31 options.plugins = utils_2.extend(options.plugins || [], this.pluginsExplorerService.explore());
32 const transformSchema = (schema) => tslib_1.__awaiter(this, void 0, void 0, function* () { return options.transformSchema ? yield options.transformSchema(schema) : schema; });
33 if (options.autoSchemaFile) {
34 const autoGeneratedSchema = yield this.gqlSchemaBuilder.build(options.autoSchemaFile, options, this.resolversExplorerService.getAllCtors());
35 const executableSchema = schema_1.makeExecutableSchema({
36 resolvers: utils_2.extend(typesResolvers, options.resolvers),
37 typeDefs: apollo_server_core_1.gql `
38 ${graphql_1.printSchema(autoGeneratedSchema)}
39 `,
40 resolverValidationOptions: Object.assign(Object.assign({}, (options.resolverValidationOptions || {})), { requireResolversForResolveType: false }),
41 });
42 let schema = options.schema
43 ? merge_1.mergeSchemas({
44 schemas: [options.schema, executableSchema],
45 })
46 : executableSchema;
47 const autoGeneratedSchemaConfig = autoGeneratedSchema.toConfig();
48 const schemaConfig = this.overrideOrExtendResolvers(schema.toConfig(), autoGeneratedSchemaConfig);
49 schema = new graphql_1.GraphQLSchema(schemaConfig);
50 if (options.schemaDirectives) {
51 utils_1.SchemaDirectiveVisitor.visitSchemaDirectives(schema, options.schemaDirectives);
52 }
53 schema = yield transformSchema(schema);
54 schema = options.sortSchema ? graphql_1.lexicographicSortSchema(schema) : schema;
55 this.gqlSchemaHost.schema = schema;
56 return Object.assign(Object.assign({}, options), { typeDefs: undefined, schema });
57 }
58 if (lodash_1.isEmpty(options.typeDefs)) {
59 const schema = yield transformSchema(options.schema);
60 this.gqlSchemaHost.schema = schema;
61 return Object.assign(Object.assign({}, options), { typeDefs: undefined, schema });
62 }
63 const executableSchema = schema_1.makeExecutableSchema({
64 resolvers: utils_2.extend(typesResolvers, options.resolvers),
65 directiveResolvers: options.directiveResolvers,
66 schemaDirectives: options.schemaDirectives,
67 typeDefs: apollo_server_core_1.gql `
68 ${options.typeDefs}
69 `,
70 resolverValidationOptions: options.resolverValidationOptions,
71 });
72 let schema = options.schema
73 ? merge_1.mergeSchemas({
74 schemas: [options.schema, executableSchema],
75 })
76 : executableSchema;
77 utils_2.removeTempField(schema);
78 schema = yield transformSchema(schema);
79 schema = options.sortSchema ? graphql_1.lexicographicSortSchema(schema) : schema;
80 this.gqlSchemaHost.schema = schema;
81 return Object.assign(Object.assign({}, options), { typeDefs: undefined, schema });
82 });
83 }
84 overrideOrExtendResolvers(executableSchemaConfig, autoGeneratedSchemaConfig) {
85 const schemaConfig = autoGeneratedSchemaConfig;
86 const rootResolverKeys = [
87 'mutation',
88 'query',
89 'subscription',
90 ];
91 rootResolverKeys
92 .filter((key) => executableSchemaConfig[key] && schemaConfig[key])
93 .forEach((key) => {
94 const executableSchemaFields = executableSchemaConfig[key].getFields();
95 const schemaFields = schemaConfig[key].getFields();
96 lodash_1.forEach(executableSchemaFields, (value, resolverName) => {
97 if (schemaFields[resolverName]) {
98 schemaFields[resolverName].resolve =
99 executableSchemaFields[resolverName].resolve;
100 schemaFields[resolverName].subscribe =
101 executableSchemaFields[resolverName].subscribe;
102 }
103 else {
104 schemaFields[resolverName] = executableSchemaFields[resolverName];
105 }
106 });
107 });
108 const getAutoGeneratedTypeByName = (name) => schemaConfig.types.find((type) => type.name === name);
109 executableSchemaConfig.types
110 .filter((type) => type instanceof graphql_1.GraphQLObjectType)
111 .forEach((type) => {
112 const fields = type.getFields();
113 const autoGeneratedType = getAutoGeneratedTypeByName(type.name);
114 if (!autoGeneratedType) {
115 return;
116 }
117 const implementedInterfaces = autoGeneratedType.getInterfaces() || [];
118 if (implementedInterfaces.length > 0) {
119 implementedInterfaces.forEach((interfaceRef) => {
120 const interfaceInExecutableSchema = executableSchemaConfig.types.find((type) => type.name === interfaceRef.name);
121 lodash_1.forEach(interfaceRef.getFields(), (value, key) => {
122 const fieldInExecutableSchema = interfaceInExecutableSchema.getFields()[key];
123 if (!fieldInExecutableSchema) {
124 return;
125 }
126 if (!fieldInExecutableSchema.resolve) {
127 return;
128 }
129 const baseClassField = autoGeneratedType.getFields()[key];
130 baseClassField &&
131 (baseClassField.resolve = fieldInExecutableSchema.resolve);
132 });
133 });
134 }
135 lodash_1.forEach(fields, (value, key) => {
136 if (!value.resolve) {
137 return;
138 }
139 const field = autoGeneratedType.getFields()[key];
140 field && (field.resolve = value.resolve);
141 });
142 });
143 return schemaConfig;
144 }
145 generateDefinitions(typeDefs, options) {
146 return tslib_1.__awaiter(this, void 0, void 0, function* () {
147 if (lodash_1.isEmpty(typeDefs) || !options.definitions) {
148 return;
149 }
150 const definitionsGeneratorOptions = {
151 emitTypenameField: options.definitions.emitTypenameField,
152 skipResolverArgs: options.definitions.skipResolverArgs,
153 defaultScalarType: options.definitions.defaultScalarType,
154 customScalarTypeMapping: options.definitions.customScalarTypeMapping,
155 additionalHeader: options.definitions.additionalHeader,
156 };
157 const tsFile = yield this.graphqlAstExplorer.explore(apollo_server_core_1.gql `
158 ${typeDefs}
159 `, options.definitions.path, options.definitions.outputAs, definitionsGeneratorOptions);
160 if (!fs_1.existsSync(options.definitions.path) ||
161 !fs_1.lstatSync(options.definitions.path).isFile() ||
162 fs_1.readFileSync(options.definitions.path, 'utf8') !== tsFile.getFullText()) {
163 yield tsFile.save();
164 }
165 });
166 }
167};
168GraphQLFactory = tslib_1.__decorate([
169 common_1.Injectable(),
170 tslib_1.__metadata("design:paramtypes", [services_1.ResolversExplorerService,
171 services_1.ScalarsExplorerService,
172 services_1.PluginsExplorerService,
173 graphql_ast_explorer_1.GraphQLAstExplorer,
174 graphql_schema_builder_1.GraphQLSchemaBuilder,
175 graphql_schema_host_1.GraphQLSchemaHost])
176], GraphQLFactory);
177exports.GraphQLFactory = GraphQLFactory;