UNPKG

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