1 | "use strict";
|
2 | Object.defineProperty(exports, "__esModule", { value: true });
|
3 | exports.addResolversToSchema = void 0;
|
4 | const graphql_1 = require("graphql");
|
5 | const utils_1 = require("@graphql-tools/utils");
|
6 | const checkForResolveTypeResolver_js_1 = require("./checkForResolveTypeResolver.js");
|
7 | const extendResolversFromInterfaces_js_1 = require("./extendResolversFromInterfaces.js");
|
8 | function addResolversToSchema({ schema, resolvers: inputResolvers, defaultFieldResolver, resolverValidationOptions = {}, inheritResolversFromInterfaces = false, updateResolversInPlace = false, }) {
|
9 | const { requireResolversToMatchSchema = 'error', requireResolversForResolveType } = resolverValidationOptions;
|
10 | const resolvers = inheritResolversFromInterfaces
|
11 | ? (0, extendResolversFromInterfaces_js_1.extendResolversFromInterfaces)(schema, inputResolvers)
|
12 | : inputResolvers;
|
13 | for (const typeName in resolvers) {
|
14 | const resolverValue = resolvers[typeName];
|
15 | const resolverType = typeof resolverValue;
|
16 | if (resolverType !== 'object') {
|
17 | throw new Error(`"${typeName}" defined in resolvers, but has invalid value "${resolverValue}". The resolver's value must be of type object.`);
|
18 | }
|
19 | const type = schema.getType(typeName);
|
20 | if (type == null) {
|
21 | if (requireResolversToMatchSchema === 'ignore') {
|
22 | continue;
|
23 | }
|
24 | throw new Error(`"${typeName}" defined in resolvers, but not in schema`);
|
25 | }
|
26 | else if ((0, graphql_1.isSpecifiedScalarType)(type)) {
|
27 |
|
28 | for (const fieldName in resolverValue) {
|
29 | if (fieldName.startsWith('__')) {
|
30 | type[fieldName.substring(2)] = resolverValue[fieldName];
|
31 | }
|
32 | else {
|
33 | type[fieldName] = resolverValue[fieldName];
|
34 | }
|
35 | }
|
36 | }
|
37 | else if ((0, graphql_1.isEnumType)(type)) {
|
38 | const values = type.getValues();
|
39 | for (const fieldName in resolverValue) {
|
40 | if (!fieldName.startsWith('__') &&
|
41 | !values.some(value => value.name === fieldName) &&
|
42 | requireResolversToMatchSchema &&
|
43 | requireResolversToMatchSchema !== 'ignore') {
|
44 | throw new Error(`${type.name}.${fieldName} was defined in resolvers, but not present within ${type.name}`);
|
45 | }
|
46 | }
|
47 | }
|
48 | else if ((0, graphql_1.isUnionType)(type)) {
|
49 | for (const fieldName in resolverValue) {
|
50 | if (!fieldName.startsWith('__') &&
|
51 | requireResolversToMatchSchema &&
|
52 | requireResolversToMatchSchema !== 'ignore') {
|
53 | throw new Error(`${type.name}.${fieldName} was defined in resolvers, but ${type.name} is not an object or interface type`);
|
54 | }
|
55 | }
|
56 | }
|
57 | else if ((0, graphql_1.isObjectType)(type) || (0, graphql_1.isInterfaceType)(type)) {
|
58 | for (const fieldName in resolverValue) {
|
59 | if (!fieldName.startsWith('__')) {
|
60 | const fields = type.getFields();
|
61 | const field = fields[fieldName];
|
62 | if (field == null) {
|
63 |
|
64 | if (requireResolversToMatchSchema && requireResolversToMatchSchema !== 'ignore') {
|
65 | throw new Error(`${typeName}.${fieldName} defined in resolvers, but not in schema`);
|
66 | }
|
67 | }
|
68 | else {
|
69 |
|
70 | const fieldResolve = resolverValue[fieldName];
|
71 | if (typeof fieldResolve !== 'function' && typeof fieldResolve !== 'object') {
|
72 | throw new Error(`Resolver ${typeName}.${fieldName} must be object or function`);
|
73 | }
|
74 | }
|
75 | }
|
76 | }
|
77 | }
|
78 | }
|
79 | schema = updateResolversInPlace
|
80 | ? addResolversToExistingSchema(schema, resolvers, defaultFieldResolver)
|
81 | : createNewSchemaWithResolvers(schema, resolvers, defaultFieldResolver);
|
82 | if (requireResolversForResolveType && requireResolversForResolveType !== 'ignore') {
|
83 | (0, checkForResolveTypeResolver_js_1.checkForResolveTypeResolver)(schema, requireResolversForResolveType);
|
84 | }
|
85 | return schema;
|
86 | }
|
87 | exports.addResolversToSchema = addResolversToSchema;
|
88 | function addResolversToExistingSchema(schema, resolvers, defaultFieldResolver) {
|
89 | var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m;
|
90 | const typeMap = schema.getTypeMap();
|
91 | for (const typeName in resolvers) {
|
92 | const type = schema.getType(typeName);
|
93 | const resolverValue = resolvers[typeName];
|
94 | if ((0, graphql_1.isScalarType)(type)) {
|
95 | for (const fieldName in resolverValue) {
|
96 | if (fieldName.startsWith('__')) {
|
97 | type[fieldName.substring(2)] = resolverValue[fieldName];
|
98 | }
|
99 | else if (fieldName === 'astNode' && type.astNode != null) {
|
100 | type.astNode = {
|
101 | ...type.astNode,
|
102 | description: (_b = (_a = resolverValue === null || resolverValue === void 0 ? void 0 : resolverValue.astNode) === null || _a === void 0 ? void 0 : _a.description) !== null && _b !== void 0 ? _b : type.astNode.description,
|
103 | directives: ((_c = type.astNode.directives) !== null && _c !== void 0 ? _c : []).concat((_e = (_d = resolverValue === null || resolverValue === void 0 ? void 0 : resolverValue.astNode) === null || _d === void 0 ? void 0 : _d.directives) !== null && _e !== void 0 ? _e : []),
|
104 | };
|
105 | }
|
106 | else if (fieldName === 'extensionASTNodes' && type.extensionASTNodes != null) {
|
107 | type.extensionASTNodes = type.extensionASTNodes.concat((_f = resolverValue === null || resolverValue === void 0 ? void 0 : resolverValue.extensionASTNodes) !== null && _f !== void 0 ? _f : []);
|
108 | }
|
109 | else if (fieldName === 'extensions' &&
|
110 | type.extensions != null &&
|
111 | resolverValue.extensions != null) {
|
112 | type.extensions = Object.assign(Object.create(null), type.extensions, resolverValue.extensions);
|
113 | }
|
114 | else {
|
115 | type[fieldName] = resolverValue[fieldName];
|
116 | }
|
117 | }
|
118 | }
|
119 | else if ((0, graphql_1.isEnumType)(type)) {
|
120 | const config = type.toConfig();
|
121 | const enumValueConfigMap = config.values;
|
122 | for (const fieldName in resolverValue) {
|
123 | if (fieldName.startsWith('__')) {
|
124 | config[fieldName.substring(2)] = resolverValue[fieldName];
|
125 | }
|
126 | else if (fieldName === 'astNode' && config.astNode != null) {
|
127 | config.astNode = {
|
128 | ...config.astNode,
|
129 | description: (_h = (_g = resolverValue === null || resolverValue === void 0 ? void 0 : resolverValue.astNode) === null || _g === void 0 ? void 0 : _g.description) !== null && _h !== void 0 ? _h : config.astNode.description,
|
130 | directives: ((_j = config.astNode.directives) !== null && _j !== void 0 ? _j : []).concat((_l = (_k = resolverValue === null || resolverValue === void 0 ? void 0 : resolverValue.astNode) === null || _k === void 0 ? void 0 : _k.directives) !== null && _l !== void 0 ? _l : []),
|
131 | };
|
132 | }
|
133 | else if (fieldName === 'extensionASTNodes' && config.extensionASTNodes != null) {
|
134 | config.extensionASTNodes = config.extensionASTNodes.concat((_m = resolverValue === null || resolverValue === void 0 ? void 0 : resolverValue.extensionASTNodes) !== null && _m !== void 0 ? _m : []);
|
135 | }
|
136 | else if (fieldName === 'extensions' &&
|
137 | type.extensions != null &&
|
138 | resolverValue.extensions != null) {
|
139 | type.extensions = Object.assign(Object.create(null), type.extensions, resolverValue.extensions);
|
140 | }
|
141 | else if (enumValueConfigMap[fieldName]) {
|
142 | enumValueConfigMap[fieldName].value = resolverValue[fieldName];
|
143 | }
|
144 | }
|
145 | typeMap[typeName] = new graphql_1.GraphQLEnumType(config);
|
146 | }
|
147 | else if ((0, graphql_1.isUnionType)(type)) {
|
148 | for (const fieldName in resolverValue) {
|
149 | if (fieldName.startsWith('__')) {
|
150 | type[fieldName.substring(2)] = resolverValue[fieldName];
|
151 | }
|
152 | }
|
153 | }
|
154 | else if ((0, graphql_1.isObjectType)(type) || (0, graphql_1.isInterfaceType)(type)) {
|
155 | for (const fieldName in resolverValue) {
|
156 | if (fieldName.startsWith('__')) {
|
157 |
|
158 | type[fieldName.substring(2)] = resolverValue[fieldName];
|
159 | continue;
|
160 | }
|
161 | const fields = type.getFields();
|
162 | const field = fields[fieldName];
|
163 | if (field != null) {
|
164 | const fieldResolve = resolverValue[fieldName];
|
165 | if (typeof fieldResolve === 'function') {
|
166 |
|
167 | field.resolve = fieldResolve.bind(resolverValue);
|
168 | }
|
169 | else {
|
170 | setFieldProperties(field, fieldResolve);
|
171 | }
|
172 | }
|
173 | }
|
174 | }
|
175 | }
|
176 |
|
177 | (0, utils_1.forEachDefaultValue)(schema, utils_1.serializeInputValue);
|
178 |
|
179 | (0, utils_1.healSchema)(schema);
|
180 |
|
181 | (0, utils_1.forEachDefaultValue)(schema, utils_1.parseInputValue);
|
182 | if (defaultFieldResolver != null) {
|
183 | (0, utils_1.forEachField)(schema, field => {
|
184 | if (!field.resolve) {
|
185 | field.resolve = defaultFieldResolver;
|
186 | }
|
187 | });
|
188 | }
|
189 | return schema;
|
190 | }
|
191 | function createNewSchemaWithResolvers(schema, resolvers, defaultFieldResolver) {
|
192 | schema = (0, utils_1.mapSchema)(schema, {
|
193 | [utils_1.MapperKind.SCALAR_TYPE]: type => {
|
194 | var _a, _b, _c, _d, _e, _f;
|
195 | const config = type.toConfig();
|
196 | const resolverValue = resolvers[type.name];
|
197 | if (!(0, graphql_1.isSpecifiedScalarType)(type) && resolverValue != null) {
|
198 | for (const fieldName in resolverValue) {
|
199 | if (fieldName.startsWith('__')) {
|
200 | config[fieldName.substring(2)] = resolverValue[fieldName];
|
201 | }
|
202 | else if (fieldName === 'astNode' && config.astNode != null) {
|
203 | config.astNode = {
|
204 | ...config.astNode,
|
205 | description: (_b = (_a = resolverValue === null || resolverValue === void 0 ? void 0 : resolverValue.astNode) === null || _a === void 0 ? void 0 : _a.description) !== null && _b !== void 0 ? _b : config.astNode.description,
|
206 | directives: ((_c = config.astNode.directives) !== null && _c !== void 0 ? _c : []).concat((_e = (_d = resolverValue === null || resolverValue === void 0 ? void 0 : resolverValue.astNode) === null || _d === void 0 ? void 0 : _d.directives) !== null && _e !== void 0 ? _e : []),
|
207 | };
|
208 | }
|
209 | else if (fieldName === 'extensionASTNodes' && config.extensionASTNodes != null) {
|
210 | config.extensionASTNodes = config.extensionASTNodes.concat((_f = resolverValue === null || resolverValue === void 0 ? void 0 : resolverValue.extensionASTNodes) !== null && _f !== void 0 ? _f : []);
|
211 | }
|
212 | else if (fieldName === 'extensions' &&
|
213 | config.extensions != null &&
|
214 | resolverValue.extensions != null) {
|
215 | config.extensions = Object.assign(Object.create(null), type.extensions, resolverValue.extensions);
|
216 | }
|
217 | else {
|
218 | config[fieldName] = resolverValue[fieldName];
|
219 | }
|
220 | }
|
221 | return new graphql_1.GraphQLScalarType(config);
|
222 | }
|
223 | },
|
224 | [utils_1.MapperKind.ENUM_TYPE]: type => {
|
225 | var _a, _b, _c, _d, _e, _f;
|
226 | const resolverValue = resolvers[type.name];
|
227 | const config = type.toConfig();
|
228 | const enumValueConfigMap = config.values;
|
229 | if (resolverValue != null) {
|
230 | for (const fieldName in resolverValue) {
|
231 | if (fieldName.startsWith('__')) {
|
232 | config[fieldName.substring(2)] = resolverValue[fieldName];
|
233 | }
|
234 | else if (fieldName === 'astNode' && config.astNode != null) {
|
235 | config.astNode = {
|
236 | ...config.astNode,
|
237 | description: (_b = (_a = resolverValue === null || resolverValue === void 0 ? void 0 : resolverValue.astNode) === null || _a === void 0 ? void 0 : _a.description) !== null && _b !== void 0 ? _b : config.astNode.description,
|
238 | directives: ((_c = config.astNode.directives) !== null && _c !== void 0 ? _c : []).concat((_e = (_d = resolverValue === null || resolverValue === void 0 ? void 0 : resolverValue.astNode) === null || _d === void 0 ? void 0 : _d.directives) !== null && _e !== void 0 ? _e : []),
|
239 | };
|
240 | }
|
241 | else if (fieldName === 'extensionASTNodes' && config.extensionASTNodes != null) {
|
242 | config.extensionASTNodes = config.extensionASTNodes.concat((_f = resolverValue === null || resolverValue === void 0 ? void 0 : resolverValue.extensionASTNodes) !== null && _f !== void 0 ? _f : []);
|
243 | }
|
244 | else if (fieldName === 'extensions' &&
|
245 | config.extensions != null &&
|
246 | resolverValue.extensions != null) {
|
247 | config.extensions = Object.assign(Object.create(null), type.extensions, resolverValue.extensions);
|
248 | }
|
249 | else if (enumValueConfigMap[fieldName]) {
|
250 | enumValueConfigMap[fieldName].value = resolverValue[fieldName];
|
251 | }
|
252 | }
|
253 | return new graphql_1.GraphQLEnumType(config);
|
254 | }
|
255 | },
|
256 | [utils_1.MapperKind.UNION_TYPE]: type => {
|
257 | const resolverValue = resolvers[type.name];
|
258 | if (resolverValue != null) {
|
259 | const config = type.toConfig();
|
260 | if (resolverValue['__resolveType']) {
|
261 | config.resolveType = resolverValue['__resolveType'];
|
262 | }
|
263 | return new graphql_1.GraphQLUnionType(config);
|
264 | }
|
265 | },
|
266 | [utils_1.MapperKind.OBJECT_TYPE]: type => {
|
267 | const resolverValue = resolvers[type.name];
|
268 | if (resolverValue != null) {
|
269 | const config = type.toConfig();
|
270 | if (resolverValue['__isTypeOf']) {
|
271 | config.isTypeOf = resolverValue['__isTypeOf'];
|
272 | }
|
273 | return new graphql_1.GraphQLObjectType(config);
|
274 | }
|
275 | },
|
276 | [utils_1.MapperKind.INTERFACE_TYPE]: type => {
|
277 | const resolverValue = resolvers[type.name];
|
278 | if (resolverValue != null) {
|
279 | const config = type.toConfig();
|
280 | if (resolverValue['__resolveType']) {
|
281 | config.resolveType = resolverValue['__resolveType'];
|
282 | }
|
283 | return new graphql_1.GraphQLInterfaceType(config);
|
284 | }
|
285 | },
|
286 | [utils_1.MapperKind.COMPOSITE_FIELD]: (fieldConfig, fieldName, typeName) => {
|
287 | const resolverValue = resolvers[typeName];
|
288 | if (resolverValue != null) {
|
289 | const fieldResolve = resolverValue[fieldName];
|
290 | if (fieldResolve != null) {
|
291 | const newFieldConfig = { ...fieldConfig };
|
292 | if (typeof fieldResolve === 'function') {
|
293 |
|
294 | newFieldConfig.resolve = fieldResolve.bind(resolverValue);
|
295 | }
|
296 | else {
|
297 | setFieldProperties(newFieldConfig, fieldResolve);
|
298 | }
|
299 | return newFieldConfig;
|
300 | }
|
301 | }
|
302 | },
|
303 | });
|
304 | if (defaultFieldResolver != null) {
|
305 | schema = (0, utils_1.mapSchema)(schema, {
|
306 | [utils_1.MapperKind.OBJECT_FIELD]: fieldConfig => ({
|
307 | ...fieldConfig,
|
308 | resolve: fieldConfig.resolve != null ? fieldConfig.resolve : defaultFieldResolver,
|
309 | }),
|
310 | });
|
311 | }
|
312 | return schema;
|
313 | }
|
314 | function setFieldProperties(field, propertiesObj) {
|
315 | for (const propertyName in propertiesObj) {
|
316 | field[propertyName] = propertiesObj[propertyName];
|
317 | }
|
318 | }
|