1 | var __assign = (this && this.__assign) || function () {
|
2 | __assign = Object.assign || function(t) {
|
3 | for (var s, i = 1, n = arguments.length; i < n; i++) {
|
4 | s = arguments[i];
|
5 | for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
|
6 | t[p] = s[p];
|
7 | }
|
8 | return t;
|
9 | };
|
10 | return __assign.apply(this, arguments);
|
11 | };
|
12 | Object.defineProperty(exports, "__esModule", { value: true });
|
13 | var graphql_1 = require("graphql");
|
14 | var makeExecutableSchema_1 = require("../makeExecutableSchema");
|
15 | var schemaRecreation_1 = require("./schemaRecreation");
|
16 | var delegateToSchema_1 = require("./delegateToSchema");
|
17 | var typeFromAST_1 = require("./typeFromAST");
|
18 | var transforms_1 = require("../transforms");
|
19 | var mergeDeep_1 = require("../mergeDeep");
|
20 | var schemaVisitor_1 = require("../schemaVisitor");
|
21 | function mergeSchemas(_a) {
|
22 | var schemas = _a.schemas, onTypeConflict = _a.onTypeConflict, resolvers = _a.resolvers, schemaDirectives = _a.schemaDirectives, inheritResolversFromInterfaces = _a.inheritResolversFromInterfaces, mergeDirectives = _a.mergeDirectives;
|
23 | return mergeSchemasImplementation({
|
24 | schemas: schemas,
|
25 | resolvers: resolvers,
|
26 | schemaDirectives: schemaDirectives,
|
27 | inheritResolversFromInterfaces: inheritResolversFromInterfaces,
|
28 | mergeDirectives: mergeDirectives,
|
29 | });
|
30 | }
|
31 | exports.default = mergeSchemas;
|
32 | function mergeSchemasImplementation(_a) {
|
33 | var schemas = _a.schemas, resolvers = _a.resolvers, schemaDirectives = _a.schemaDirectives, inheritResolversFromInterfaces = _a.inheritResolversFromInterfaces, mergeDirectives = _a.mergeDirectives;
|
34 | var allSchemas = [];
|
35 | var typeCandidates = {};
|
36 | var types = {};
|
37 | var extensions = [];
|
38 | var directives = [];
|
39 | var fragments = [];
|
40 | var resolveType = schemaRecreation_1.createResolveType(function (name) {
|
41 | if (types[name] === undefined) {
|
42 | throw new Error("Can't find type " + name + ".");
|
43 | }
|
44 | return types[name];
|
45 | });
|
46 | schemas.forEach(function (schema) {
|
47 | if (schema instanceof graphql_1.GraphQLSchema) {
|
48 | allSchemas.push(schema);
|
49 | var queryType_1 = schema.getQueryType();
|
50 | var mutationType_1 = schema.getMutationType();
|
51 | var subscriptionType_1 = schema.getSubscriptionType();
|
52 | if (queryType_1) {
|
53 | addTypeCandidate(typeCandidates, 'Query', {
|
54 | schema: schema,
|
55 | type: queryType_1,
|
56 | });
|
57 | }
|
58 | if (mutationType_1) {
|
59 | addTypeCandidate(typeCandidates, 'Mutation', {
|
60 | schema: schema,
|
61 | type: mutationType_1,
|
62 | });
|
63 | }
|
64 | if (subscriptionType_1) {
|
65 | addTypeCandidate(typeCandidates, 'Subscription', {
|
66 | schema: schema,
|
67 | type: subscriptionType_1,
|
68 | });
|
69 | }
|
70 | if (mergeDirectives) {
|
71 | var directiveInstances = schema.getDirectives();
|
72 | directiveInstances.forEach(function (directive) {
|
73 | directives.push(directive);
|
74 | });
|
75 | }
|
76 | var typeMap_1 = schema.getTypeMap();
|
77 | Object.keys(typeMap_1).forEach(function (typeName) {
|
78 | var type = typeMap_1[typeName];
|
79 | if (graphql_1.isNamedType(type) &&
|
80 | graphql_1.getNamedType(type).name.slice(0, 2) !== '__' &&
|
81 | type !== queryType_1 &&
|
82 | type !== mutationType_1 &&
|
83 | type !== subscriptionType_1) {
|
84 | addTypeCandidate(typeCandidates, type.name, {
|
85 | schema: schema,
|
86 | type: type,
|
87 | });
|
88 | }
|
89 | });
|
90 | }
|
91 | else if (typeof schema === 'string' ||
|
92 | (schema && schema.kind === graphql_1.Kind.DOCUMENT)) {
|
93 | var parsedSchemaDocument = typeof schema === 'string' ? graphql_1.parse(schema) : schema;
|
94 | parsedSchemaDocument.definitions.forEach(function (def) {
|
95 | var type = typeFromAST_1.default(def);
|
96 | if (type instanceof graphql_1.GraphQLDirective && mergeDirectives) {
|
97 | directives.push(type);
|
98 | }
|
99 | else if (type && !(type instanceof graphql_1.GraphQLDirective)) {
|
100 | addTypeCandidate(typeCandidates, type.name, {
|
101 | type: type,
|
102 | });
|
103 | }
|
104 | });
|
105 | var extensionsDocument = makeExecutableSchema_1.extractExtensionDefinitions(parsedSchemaDocument);
|
106 | if (extensionsDocument.definitions.length > 0) {
|
107 | extensions.push(extensionsDocument);
|
108 | }
|
109 | }
|
110 | else if (Array.isArray(schema)) {
|
111 | schema.forEach(function (type) {
|
112 | addTypeCandidate(typeCandidates, type.name, {
|
113 | type: type,
|
114 | });
|
115 | });
|
116 | }
|
117 | else {
|
118 | throw new Error("Invalid schema passed");
|
119 | }
|
120 | });
|
121 | var mergeInfo = createMergeInfo(allSchemas, fragments);
|
122 | if (!resolvers) {
|
123 | resolvers = {};
|
124 | }
|
125 | else if (typeof resolvers === 'function') {
|
126 | console.warn('Passing functions as resolver parameter is deprecated. Use `info.mergeInfo` instead.');
|
127 | resolvers = resolvers(mergeInfo);
|
128 | }
|
129 | else if (Array.isArray(resolvers)) {
|
130 | resolvers = resolvers.reduce(function (left, right) {
|
131 | if (typeof right === 'function') {
|
132 | console.warn('Passing functions as resolver parameter is deprecated. Use `info.mergeInfo` instead.');
|
133 | right = right(mergeInfo);
|
134 | }
|
135 | return mergeDeep_1.default(left, right);
|
136 | }, {});
|
137 | }
|
138 | var generatedResolvers = {};
|
139 | Object.keys(typeCandidates).forEach(function (typeName) {
|
140 | var resultType = defaultVisitType(typeName, typeCandidates[typeName]);
|
141 | if (resultType === null) {
|
142 | types[typeName] = null;
|
143 | }
|
144 | else {
|
145 | var type = void 0;
|
146 | var typeResolvers = void 0;
|
147 | if (graphql_1.isNamedType(resultType)) {
|
148 | type = resultType;
|
149 | }
|
150 | else if (resultType.type) {
|
151 | type = resultType.type;
|
152 | typeResolvers = resultType.resolvers;
|
153 | }
|
154 | else {
|
155 | throw new Error("Invalid visitType result for type " + typeName);
|
156 | }
|
157 | types[typeName] = schemaRecreation_1.recreateType(type, resolveType, false);
|
158 | if (typeResolvers) {
|
159 | generatedResolvers[typeName] = typeResolvers;
|
160 | }
|
161 | }
|
162 | });
|
163 | var mergedSchema = new graphql_1.GraphQLSchema({
|
164 | query: types.Query,
|
165 | mutation: types.Mutation,
|
166 | subscription: types.Subscription,
|
167 | types: Object.keys(types).map(function (key) { return types[key]; }),
|
168 | directives: directives.map(function (directive) { return schemaRecreation_1.recreateDirective(directive, resolveType); })
|
169 | });
|
170 | extensions.forEach(function (extension) {
|
171 | mergedSchema = graphql_1.extendSchema(mergedSchema, extension, {
|
172 | commentDescriptions: true,
|
173 | });
|
174 | });
|
175 | if (!resolvers) {
|
176 | resolvers = {};
|
177 | }
|
178 | else if (Array.isArray(resolvers)) {
|
179 | resolvers = resolvers.reduce(mergeDeep_1.default, {});
|
180 | }
|
181 | Object.keys(resolvers).forEach(function (typeName) {
|
182 | var type = resolvers[typeName];
|
183 | if (type instanceof graphql_1.GraphQLScalarType) {
|
184 | return;
|
185 | }
|
186 | Object.keys(type).forEach(function (fieldName) {
|
187 | var field = type[fieldName];
|
188 | if (field.fragment) {
|
189 | fragments.push({
|
190 | field: fieldName,
|
191 | fragment: field.fragment,
|
192 | });
|
193 | }
|
194 | });
|
195 | });
|
196 | mergedSchema = makeExecutableSchema_1.addResolveFunctionsToSchema({
|
197 | schema: mergedSchema,
|
198 | resolvers: mergeDeep_1.default(generatedResolvers, resolvers),
|
199 | inheritResolversFromInterfaces: inheritResolversFromInterfaces
|
200 | });
|
201 | forEachField(mergedSchema, function (field) {
|
202 | if (field.resolve) {
|
203 | var fieldResolver_1 = field.resolve;
|
204 | field.resolve = function (parent, args, context, info) {
|
205 | var newInfo = __assign({}, info, { mergeInfo: mergeInfo });
|
206 | return fieldResolver_1(parent, args, context, newInfo);
|
207 | };
|
208 | }
|
209 | if (field.subscribe) {
|
210 | var fieldResolver_2 = field.subscribe;
|
211 | field.subscribe = function (parent, args, context, info) {
|
212 | var newInfo = __assign({}, info, { mergeInfo: mergeInfo });
|
213 | return fieldResolver_2(parent, args, context, newInfo);
|
214 | };
|
215 | }
|
216 | });
|
217 | if (schemaDirectives) {
|
218 | schemaVisitor_1.SchemaDirectiveVisitor.visitSchemaDirectives(mergedSchema, schemaDirectives);
|
219 | }
|
220 | return mergedSchema;
|
221 | }
|
222 | function createMergeInfo(allSchemas, fragments) {
|
223 | return {
|
224 | delegate: function (operation, fieldName, args, context, info, transforms) {
|
225 | console.warn('`mergeInfo.delegate` is deprecated. ' +
|
226 | 'Use `mergeInfo.delegateToSchema and pass explicit schema instances.');
|
227 | var schema = guessSchemaByRootField(allSchemas, operation, fieldName);
|
228 | var expandTransforms = new transforms_1.ExpandAbstractTypes(info.schema, schema);
|
229 | var fragmentTransform = new transforms_1.ReplaceFieldWithFragment(schema, fragments);
|
230 | return delegateToSchema_1.default({
|
231 | schema: schema,
|
232 | operation: operation,
|
233 | fieldName: fieldName,
|
234 | args: args,
|
235 | context: context,
|
236 | info: info,
|
237 | transforms: (transforms || []).concat([
|
238 | expandTransforms,
|
239 | fragmentTransform,
|
240 | ]),
|
241 | });
|
242 | },
|
243 | delegateToSchema: function (options) {
|
244 | return delegateToSchema_1.default(__assign({}, options, { transforms: options.transforms }));
|
245 | },
|
246 | fragments: fragments
|
247 | };
|
248 | }
|
249 | function guessSchemaByRootField(schemas, operation, fieldName) {
|
250 | for (var _i = 0, schemas_1 = schemas; _i < schemas_1.length; _i++) {
|
251 | var schema = schemas_1[_i];
|
252 | var rootObject = void 0;
|
253 | if (operation === 'subscription') {
|
254 | rootObject = schema.getSubscriptionType();
|
255 | }
|
256 | else if (operation === 'mutation') {
|
257 | rootObject = schema.getMutationType();
|
258 | }
|
259 | else {
|
260 | rootObject = schema.getQueryType();
|
261 | }
|
262 | if (rootObject) {
|
263 | var fields = rootObject.getFields();
|
264 | if (fields[fieldName]) {
|
265 | return schema;
|
266 | }
|
267 | }
|
268 | }
|
269 | throw new Error("Could not find subschema with field `" + operation + "." + fieldName + "`");
|
270 | }
|
271 | function createDelegatingResolver(schema, operation, fieldName) {
|
272 | return function (root, args, context, info) {
|
273 | return info.mergeInfo.delegateToSchema({
|
274 | schema: schema,
|
275 | operation: operation,
|
276 | fieldName: fieldName,
|
277 | args: args,
|
278 | context: context,
|
279 | info: info,
|
280 | });
|
281 | };
|
282 | }
|
283 | function forEachField(schema, fn) {
|
284 | var typeMap = schema.getTypeMap();
|
285 | Object.keys(typeMap).forEach(function (typeName) {
|
286 | var type = typeMap[typeName];
|
287 | if (!graphql_1.getNamedType(type).name.startsWith('__') &&
|
288 | type instanceof graphql_1.GraphQLObjectType) {
|
289 | var fields_1 = type.getFields();
|
290 | Object.keys(fields_1).forEach(function (fieldName) {
|
291 | var field = fields_1[fieldName];
|
292 | fn(field, typeName, fieldName);
|
293 | });
|
294 | }
|
295 | });
|
296 | }
|
297 | function addTypeCandidate(typeCandidates, name, typeCandidate) {
|
298 | if (!typeCandidates[name]) {
|
299 | typeCandidates[name] = [];
|
300 | }
|
301 | typeCandidates[name].push(typeCandidate);
|
302 | }
|
303 | function defaultVisitType(name, candidates, candidateSelector) {
|
304 | if (!candidateSelector) {
|
305 | candidateSelector = function (cands) { return cands[cands.length - 1]; };
|
306 | }
|
307 | var resolveType = schemaRecreation_1.createResolveType(function (_, type) { return type; });
|
308 | if (name === 'Query' || name === 'Mutation' || name === 'Subscription') {
|
309 | var fields_2 = {};
|
310 | var operationName_1;
|
311 | switch (name) {
|
312 | case 'Query':
|
313 | operationName_1 = 'query';
|
314 | break;
|
315 | case 'Mutation':
|
316 | operationName_1 = 'mutation';
|
317 | break;
|
318 | case 'Subscription':
|
319 | operationName_1 = 'subscription';
|
320 | break;
|
321 | default:
|
322 | break;
|
323 | }
|
324 | var resolvers_1 = {};
|
325 | var resolverKey_1 = operationName_1 === 'subscription' ? 'subscribe' : 'resolve';
|
326 | candidates.forEach(function (_a) {
|
327 | var candidateType = _a.type, schema = _a.schema;
|
328 | var candidateFields = candidateType.getFields();
|
329 | fields_2 = __assign({}, fields_2, candidateFields);
|
330 | Object.keys(candidateFields).forEach(function (fieldName) {
|
331 | var _a;
|
332 | resolvers_1[fieldName] = (_a = {},
|
333 | _a[resolverKey_1] = createDelegatingResolver(schema, operationName_1, fieldName),
|
334 | _a);
|
335 | });
|
336 | });
|
337 | var type = new graphql_1.GraphQLObjectType({
|
338 | name: name,
|
339 | fields: schemaRecreation_1.fieldMapToFieldConfigMap(fields_2, resolveType, false),
|
340 | });
|
341 | return {
|
342 | type: type,
|
343 | resolvers: resolvers_1,
|
344 | };
|
345 | }
|
346 | else {
|
347 | var candidate = candidateSelector(candidates);
|
348 | return candidate.type;
|
349 | }
|
350 | }
|
351 |
|
\ | No newline at end of file |