@graphql-tools/merge 6.2.17 → 8.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/index.js CHANGED
@@ -4,7 +4,6 @@ Object.defineProperty(exports, '__esModule', { value: true });
4
4
 
5
5
  const utils = require('@graphql-tools/utils');
6
6
  const graphql = require('graphql');
7
- const schema = require('@graphql-tools/schema');
8
7
 
9
8
  /**
10
9
  * Deep merges multiple resolver definition objects into a single definition.
@@ -86,289 +85,6 @@ function deduplicateArguments(args) {
86
85
  }, []);
87
86
  }
88
87
 
89
- const MAX_LINE_LENGTH = 80;
90
- let commentsRegistry = {};
91
- function resetComments() {
92
- commentsRegistry = {};
93
- }
94
- function collectComment(node) {
95
- var _a;
96
- const entityName = (_a = node.name) === null || _a === void 0 ? void 0 : _a.value;
97
- if (entityName == null) {
98
- return;
99
- }
100
- pushComment(node, entityName);
101
- switch (node.kind) {
102
- case 'EnumTypeDefinition':
103
- if (node.values) {
104
- for (const value of node.values) {
105
- pushComment(value, entityName, value.name.value);
106
- }
107
- }
108
- break;
109
- case 'ObjectTypeDefinition':
110
- case 'InputObjectTypeDefinition':
111
- case 'InterfaceTypeDefinition':
112
- if (node.fields) {
113
- for (const field of node.fields) {
114
- pushComment(field, entityName, field.name.value);
115
- if (isFieldDefinitionNode(field) && field.arguments) {
116
- for (const arg of field.arguments) {
117
- pushComment(arg, entityName, field.name.value, arg.name.value);
118
- }
119
- }
120
- }
121
- }
122
- break;
123
- }
124
- }
125
- function pushComment(node, entity, field, argument) {
126
- const comment = graphql.getDescription(node, { commentDescriptions: true });
127
- if (typeof comment !== 'string' || comment.length === 0) {
128
- return;
129
- }
130
- const keys = [entity];
131
- if (field) {
132
- keys.push(field);
133
- if (argument) {
134
- keys.push(argument);
135
- }
136
- }
137
- const path = keys.join('.');
138
- if (!commentsRegistry[path]) {
139
- commentsRegistry[path] = [];
140
- }
141
- commentsRegistry[path].push(comment);
142
- }
143
- function printComment(comment) {
144
- return '\n# ' + comment.replace(/\n/g, '\n# ');
145
- }
146
- /**
147
- * Copyright (c) 2015-present, Facebook, Inc.
148
- *
149
- * This source code is licensed under the MIT license found in the
150
- * LICENSE file in the root directory of this source tree.
151
- */
152
- /**
153
- * NOTE: ==> This file has been modified just to add comments to the printed AST
154
- * This is a temp measure, we will move to using the original non modified printer.js ASAP.
155
- */
156
- // import { visit, VisitFn } from 'graphql';
157
- /**
158
- * Given maybeArray, print an empty string if it is null or empty, otherwise
159
- * print all items together separated by separator if provided
160
- */
161
- function join(maybeArray, separator) {
162
- return maybeArray ? maybeArray.filter(x => x).join(separator || '') : '';
163
- }
164
- function hasMultilineItems(maybeArray) {
165
- var _a;
166
- return (_a = maybeArray === null || maybeArray === void 0 ? void 0 : maybeArray.some(str => str.includes('\n'))) !== null && _a !== void 0 ? _a : false;
167
- }
168
- function addDescription(cb) {
169
- return (node, _key, _parent, path, ancestors) => {
170
- var _a;
171
- const keys = [];
172
- const parent = path.reduce((prev, key) => {
173
- if (['fields', 'arguments', 'values'].includes(key) && prev.name) {
174
- keys.push(prev.name.value);
175
- }
176
- return prev[key];
177
- }, ancestors[0]);
178
- const key = [...keys, (_a = parent === null || parent === void 0 ? void 0 : parent.name) === null || _a === void 0 ? void 0 : _a.value].filter(Boolean).join('.');
179
- const items = [];
180
- if (node.kind.includes('Definition') && commentsRegistry[key]) {
181
- items.push(...commentsRegistry[key]);
182
- }
183
- return join([...items.map(printComment), node.description, cb(node)], '\n');
184
- };
185
- }
186
- function indent(maybeString) {
187
- return maybeString && ` ${maybeString.replace(/\n/g, '\n ')}`;
188
- }
189
- /**
190
- * Given array, print each item on its own line, wrapped in an
191
- * indented "{ }" block.
192
- */
193
- function block(array) {
194
- return array && array.length !== 0 ? `{\n${indent(join(array, '\n'))}\n}` : '';
195
- }
196
- /**
197
- * If maybeString is not null or empty, then wrap with start and end, otherwise
198
- * print an empty string.
199
- */
200
- function wrap(start, maybeString, end) {
201
- return maybeString ? start + maybeString + (end || '') : '';
202
- }
203
- /**
204
- * Print a block string in the indented block form by adding a leading and
205
- * trailing blank line. However, if a block string starts with whitespace and is
206
- * a single-line, adding a leading blank line would strip that whitespace.
207
- */
208
- function printBlockString(value, isDescription = false) {
209
- const escaped = value.replace(/"""/g, '\\"""');
210
- return (value[0] === ' ' || value[0] === '\t') && value.indexOf('\n') === -1
211
- ? `"""${escaped.replace(/"$/, '"\n')}"""`
212
- : `"""\n${isDescription ? escaped : indent(escaped)}\n"""`;
213
- }
214
- const printDocASTReducer = {
215
- Name: { leave: node => node.value },
216
- Variable: { leave: node => '$' + node.name },
217
- // Document
218
- Document: {
219
- leave: node => join(node.definitions, '\n\n'),
220
- },
221
- OperationDefinition: {
222
- leave: node => {
223
- const varDefs = wrap('(', join(node.variableDefinitions, ', '), ')');
224
- const prefix = join([node.operation, join([node.name, varDefs]), join(node.directives, ' ')], ' ');
225
- // the query short form.
226
- return prefix + ' ' + node.selectionSet;
227
- },
228
- },
229
- VariableDefinition: {
230
- leave: ({ variable, type, defaultValue, directives }) => variable + ': ' + type + wrap(' = ', defaultValue) + wrap(' ', join(directives, ' ')),
231
- },
232
- SelectionSet: { leave: ({ selections }) => block(selections) },
233
- Field: {
234
- leave({ alias, name, arguments: args, directives, selectionSet }) {
235
- const prefix = wrap('', alias, ': ') + name;
236
- let argsLine = prefix + wrap('(', join(args, ', '), ')');
237
- if (argsLine.length > MAX_LINE_LENGTH) {
238
- argsLine = prefix + wrap('(\n', indent(join(args, '\n')), '\n)');
239
- }
240
- return join([argsLine, join(directives, ' '), selectionSet], ' ');
241
- },
242
- },
243
- Argument: { leave: ({ name, value }) => name + ': ' + value },
244
- // Fragments
245
- FragmentSpread: {
246
- leave: ({ name, directives }) => '...' + name + wrap(' ', join(directives, ' ')),
247
- },
248
- InlineFragment: {
249
- leave: ({ typeCondition, directives, selectionSet }) => join(['...', wrap('on ', typeCondition), join(directives, ' '), selectionSet], ' '),
250
- },
251
- FragmentDefinition: {
252
- leave: ({ name, typeCondition, variableDefinitions, directives, selectionSet }) =>
253
- // Note: fragment variable definitions are experimental and may be changed
254
- // or removed in the future.
255
- `fragment ${name}${wrap('(', join(variableDefinitions, ', '), ')')} ` +
256
- `on ${typeCondition} ${wrap('', join(directives, ' '), ' ')}` +
257
- selectionSet,
258
- },
259
- // Value
260
- IntValue: { leave: ({ value }) => value },
261
- FloatValue: { leave: ({ value }) => value },
262
- StringValue: {
263
- leave: ({ value, block: isBlockString }) => (isBlockString ? printBlockString(value) : JSON.stringify(value)),
264
- },
265
- BooleanValue: { leave: ({ value }) => (value ? 'true' : 'false') },
266
- NullValue: { leave: () => 'null' },
267
- EnumValue: { leave: ({ value }) => value },
268
- ListValue: { leave: ({ values }) => '[' + join(values, ', ') + ']' },
269
- ObjectValue: { leave: ({ fields }) => '{' + join(fields, ', ') + '}' },
270
- ObjectField: { leave: ({ name, value }) => name + ': ' + value },
271
- // Directive
272
- Directive: {
273
- leave: ({ name, arguments: args }) => '@' + name + wrap('(', join(args, ', '), ')'),
274
- },
275
- // Type
276
- NamedType: { leave: ({ name }) => name },
277
- ListType: { leave: ({ type }) => '[' + type + ']' },
278
- NonNullType: { leave: ({ type }) => type + '!' },
279
- // Type System Definitions
280
- SchemaDefinition: {
281
- leave: ({ description, directives, operationTypes }) => wrap('', description, '\n') + join(['schema', join(directives, ' '), block(operationTypes)], ' '),
282
- },
283
- OperationTypeDefinition: {
284
- leave: ({ operation, type }) => operation + ': ' + type,
285
- },
286
- ScalarTypeDefinition: {
287
- leave: ({ description, name, directives }) => wrap('', description, '\n') + join(['scalar', name, join(directives, ' ')], ' '),
288
- },
289
- ObjectTypeDefinition: {
290
- leave: ({ description, name, interfaces, directives, fields }) => wrap('', description, '\n') +
291
- join(['type', name, wrap('implements ', join(interfaces, ' & ')), join(directives, ' '), block(fields)], ' '),
292
- },
293
- FieldDefinition: {
294
- leave: ({ description, name, arguments: args, type, directives }) => wrap('', description, '\n') +
295
- name +
296
- (hasMultilineItems(args)
297
- ? wrap('(\n', indent(join(args, '\n')), '\n)')
298
- : wrap('(', join(args, ', '), ')')) +
299
- ': ' +
300
- type +
301
- wrap(' ', join(directives, ' ')),
302
- },
303
- InputValueDefinition: {
304
- leave: ({ description, name, type, defaultValue, directives }) => wrap('', description, '\n') + join([name + ': ' + type, wrap('= ', defaultValue), join(directives, ' ')], ' '),
305
- },
306
- InterfaceTypeDefinition: {
307
- leave: ({ description, name, interfaces, directives, fields }) => wrap('', description, '\n') +
308
- join(['interface', name, wrap('implements ', join(interfaces, ' & ')), join(directives, ' '), block(fields)], ' '),
309
- },
310
- UnionTypeDefinition: {
311
- leave: ({ description, name, directives, types }) => wrap('', description, '\n') + join(['union', name, join(directives, ' '), wrap('= ', join(types, ' | '))], ' '),
312
- },
313
- EnumTypeDefinition: {
314
- leave: ({ description, name, directives, values }) => wrap('', description, '\n') + join(['enum', name, join(directives, ' '), block(values)], ' '),
315
- },
316
- EnumValueDefinition: {
317
- leave: ({ description, name, directives }) => wrap('', description, '\n') + join([name, join(directives, ' ')], ' '),
318
- },
319
- InputObjectTypeDefinition: {
320
- leave: ({ description, name, directives, fields }) => wrap('', description, '\n') + join(['input', name, join(directives, ' '), block(fields)], ' '),
321
- },
322
- DirectiveDefinition: {
323
- leave: ({ description, name, arguments: args, repeatable, locations }) => wrap('', description, '\n') +
324
- 'directive @' +
325
- name +
326
- (hasMultilineItems(args)
327
- ? wrap('(\n', indent(join(args, '\n')), '\n)')
328
- : wrap('(', join(args, ', '), ')')) +
329
- (repeatable ? ' repeatable' : '') +
330
- ' on ' +
331
- join(locations, ' | '),
332
- },
333
- SchemaExtension: {
334
- leave: ({ directives, operationTypes }) => join(['extend schema', join(directives, ' '), block(operationTypes)], ' '),
335
- },
336
- ScalarTypeExtension: {
337
- leave: ({ name, directives }) => join(['extend scalar', name, join(directives, ' ')], ' '),
338
- },
339
- ObjectTypeExtension: {
340
- leave: ({ name, interfaces, directives, fields }) => join(['extend type', name, wrap('implements ', join(interfaces, ' & ')), join(directives, ' '), block(fields)], ' '),
341
- },
342
- InterfaceTypeExtension: {
343
- leave: ({ name, interfaces, directives, fields }) => join(['extend interface', name, wrap('implements ', join(interfaces, ' & ')), join(directives, ' '), block(fields)], ' '),
344
- },
345
- UnionTypeExtension: {
346
- leave: ({ name, directives, types }) => join(['extend union', name, join(directives, ' '), wrap('= ', join(types, ' | '))], ' '),
347
- },
348
- EnumTypeExtension: {
349
- leave: ({ name, directives, values }) => join(['extend enum', name, join(directives, ' '), block(values)], ' '),
350
- },
351
- InputObjectTypeExtension: {
352
- leave: ({ name, directives, fields }) => join(['extend input', name, join(directives, ' '), block(fields)], ' '),
353
- },
354
- };
355
- const printDocASTReducerWithComments = Object.keys(printDocASTReducer).reduce((prev, key) => ({
356
- ...prev,
357
- [key]: {
358
- leave: addDescription(printDocASTReducer[key].leave),
359
- },
360
- }), {});
361
- /**
362
- * Converts an AST into a string, using one set of reasonable
363
- * formatting rules.
364
- */
365
- function printWithComments(ast) {
366
- return graphql.visit(ast, printDocASTReducerWithComments);
367
- }
368
- function isFieldDefinitionNode(node) {
369
- return node.kind === 'FieldDefinition';
370
- }
371
-
372
88
  function directiveAlreadyExists(directivesArr, otherDirective) {
373
89
  return !!directivesArr.find(directive => directive.name.value === otherDirective.name.value);
374
90
  }
@@ -431,8 +147,14 @@ function mergeDirectives(d1 = [], d2 = [], config) {
431
147
  return result;
432
148
  }
433
149
  function validateInputs(node, existingNode) {
434
- const printedNode = graphql.print(node);
435
- const printedExistingNode = graphql.print(existingNode);
150
+ const printedNode = graphql.print({
151
+ ...node,
152
+ description: undefined,
153
+ });
154
+ const printedExistingNode = graphql.print({
155
+ ...existingNode,
156
+ description: undefined,
157
+ });
436
158
  // eslint-disable-next-line
437
159
  const leaveInputs = new RegExp('(directive @w*d*)|( on .*$)', 'g');
438
160
  const sameArguments = printedNode.replace(leaveInputs, '') === printedExistingNode.replace(leaveInputs, '');
@@ -833,7 +555,7 @@ function mergeGraphQLNodes(nodes, config) {
833
555
  if (isNamedDefinitionNode(nodeDefinition)) {
834
556
  const name = (_a = nodeDefinition.name) === null || _a === void 0 ? void 0 : _a.value;
835
557
  if (config === null || config === void 0 ? void 0 : config.commentDescriptions) {
836
- collectComment(nodeDefinition);
558
+ utils.collectComment(nodeDefinition);
837
559
  }
838
560
  if (name == null) {
839
561
  continue;
@@ -881,7 +603,7 @@ function mergeGraphQLNodes(nodes, config) {
881
603
  }
882
604
 
883
605
  function mergeTypeDefs(typeSource, config) {
884
- resetComments();
606
+ utils.resetComments();
885
607
  const doc = {
886
608
  kind: graphql.Kind.DOCUMENT,
887
609
  definitions: mergeGraphQLTypes(typeSource, {
@@ -894,12 +616,12 @@ function mergeTypeDefs(typeSource, config) {
894
616
  };
895
617
  let result;
896
618
  if (config && config.commentDescriptions) {
897
- result = printWithComments(doc);
619
+ result = utils.printWithComments(doc);
898
620
  }
899
621
  else {
900
622
  result = doc;
901
623
  }
902
- resetComments();
624
+ utils.resetComments();
903
625
  return result;
904
626
  }
905
627
  function visitTypeSources(typeSource, options, allNodes = [], visitedTypeSources = new Set()) {
@@ -935,7 +657,7 @@ function visitTypeSources(typeSource, options, allNodes = [], visitedTypeSources
935
657
  }
936
658
  function mergeGraphQLTypes(typeSource, config) {
937
659
  var _a, _b, _c;
938
- resetComments();
660
+ utils.resetComments();
939
661
  const allNodes = visitTypeSources(typeSource, config);
940
662
  const mergedNodes = mergeGraphQLNodes(allNodes, config);
941
663
  if (config === null || config === void 0 ? void 0 : config.useSchemaDefinition) {
@@ -1116,65 +838,7 @@ function extractExtensionsFromSchema(schema) {
1116
838
  return result;
1117
839
  }
1118
840
 
1119
- const defaultResolverValidationOptions = {
1120
- requireResolversForArgs: 'ignore',
1121
- requireResolversForNonScalar: 'ignore',
1122
- requireResolversForAllFields: 'ignore',
1123
- requireResolversForResolveType: 'ignore',
1124
- requireResolversToMatchSchema: 'ignore',
1125
- };
1126
- /**
1127
- * Synchronously merges multiple schemas, typeDefinitions and/or resolvers into a single schema.
1128
- * @param config Configuration object
1129
- */
1130
- function mergeSchemas(config) {
1131
- const typeDefs = mergeTypeDefs([config.schemas, config.typeDefs || []], config);
1132
- const extractedResolvers = [];
1133
- const extractedExtensions = [];
1134
- for (const schema of config.schemas) {
1135
- extractedResolvers.push(utils.getResolversFromSchema(schema));
1136
- extractedExtensions.push(extractExtensionsFromSchema(schema));
1137
- }
1138
- extractedResolvers.push(...ensureResolvers(config));
1139
- const resolvers = mergeResolvers(extractedResolvers, config);
1140
- const extensions = mergeExtensions(extractedExtensions);
1141
- return makeSchema({ resolvers, typeDefs, extensions }, config);
1142
- }
1143
- /**
1144
- * Asynchronously merges multiple schemas, typeDefinitions and/or resolvers into a single schema.
1145
- * @param config Configuration object
1146
- */
1147
- async function mergeSchemasAsync(config) {
1148
- const [typeDefs, resolvers, extensions] = await Promise.all([
1149
- mergeTypeDefs([config.schemas, config.typeDefs || []], config),
1150
- Promise.all(config.schemas.map(async (schema) => utils.getResolversFromSchema(schema))).then(extractedResolvers => mergeResolvers([...extractedResolvers, ...ensureResolvers(config)], config)),
1151
- Promise.all(config.schemas.map(async (schema) => extractExtensionsFromSchema(schema))).then(extractedExtensions => mergeExtensions(extractedExtensions)),
1152
- ]);
1153
- return makeSchema({ resolvers, typeDefs, extensions }, config);
1154
- }
1155
- function ensureResolvers(config) {
1156
- return config.resolvers ? utils.asArray(config.resolvers) : [];
1157
- }
1158
- function makeSchema({ resolvers, typeDefs, extensions, }, config) {
1159
- let schema$1 = typeof typeDefs === 'string' ? graphql.buildSchema(typeDefs, config) : graphql.buildASTSchema(typeDefs, config);
1160
- // add resolvers
1161
- if (resolvers) {
1162
- schema$1 = schema.addResolversToSchema({
1163
- schema: schema$1,
1164
- resolvers,
1165
- resolverValidationOptions: {
1166
- ...defaultResolverValidationOptions,
1167
- ...(config.resolverValidationOptions || {}),
1168
- },
1169
- });
1170
- }
1171
- // extensions
1172
- applyExtensions(schema$1, extensions);
1173
- return schema$1;
1174
- }
1175
-
1176
841
  exports.applyExtensions = applyExtensions;
1177
- exports.collectComment = collectComment;
1178
842
  exports.defaultStringComparator = defaultStringComparator;
1179
843
  exports.extractExtensionsFromSchema = extractExtensionsFromSchema;
1180
844
  exports.extractType = extractType;
@@ -1198,15 +862,9 @@ exports.mergeInterface = mergeInterface;
1198
862
  exports.mergeNamedTypeArray = mergeNamedTypeArray;
1199
863
  exports.mergeResolvers = mergeResolvers;
1200
864
  exports.mergeScalar = mergeScalar;
1201
- exports.mergeSchemas = mergeSchemas;
1202
- exports.mergeSchemasAsync = mergeSchemasAsync;
1203
865
  exports.mergeType = mergeType;
1204
866
  exports.mergeTypeDefs = mergeTypeDefs;
1205
867
  exports.mergeUnion = mergeUnion;
1206
- exports.printComment = printComment;
1207
868
  exports.printTypeNode = printTypeNode;
1208
- exports.printWithComments = printWithComments;
1209
- exports.pushComment = pushComment;
1210
- exports.resetComments = resetComments;
1211
869
  exports.schemaDefSymbol = schemaDefSymbol;
1212
870
  exports.travelSchemaPossibleExtensions = travelSchemaPossibleExtensions;