UNPKG

39.9 kBJavaScriptView Raw
1/**
2 * Copyright (c) 2016-present, Facebook, Inc.
3 *
4 * This source code is licensed under the MIT license found in the
5 * LICENSE file in the root directory of this source tree.
6 *
7 *
8 */
9import find from '../polyfills/find';
10import { isScalarType, isObjectType, isInterfaceType, isUnionType, isEnumType, isInputObjectType, isNonNullType, isListType, isNamedType, isRequiredArgument, isRequiredInputField } from '../type/definition';
11import keyMap from '../jsutils/keyMap';
12export var BreakingChangeType = {
13 FIELD_CHANGED_KIND: 'FIELD_CHANGED_KIND',
14 FIELD_REMOVED: 'FIELD_REMOVED',
15 TYPE_CHANGED_KIND: 'TYPE_CHANGED_KIND',
16 TYPE_REMOVED: 'TYPE_REMOVED',
17 TYPE_REMOVED_FROM_UNION: 'TYPE_REMOVED_FROM_UNION',
18 VALUE_REMOVED_FROM_ENUM: 'VALUE_REMOVED_FROM_ENUM',
19 ARG_REMOVED: 'ARG_REMOVED',
20 ARG_CHANGED_KIND: 'ARG_CHANGED_KIND',
21 REQUIRED_ARG_ADDED: 'REQUIRED_ARG_ADDED',
22 REQUIRED_INPUT_FIELD_ADDED: 'REQUIRED_INPUT_FIELD_ADDED',
23 INTERFACE_REMOVED_FROM_OBJECT: 'INTERFACE_REMOVED_FROM_OBJECT',
24 DIRECTIVE_REMOVED: 'DIRECTIVE_REMOVED',
25 DIRECTIVE_ARG_REMOVED: 'DIRECTIVE_ARG_REMOVED',
26 DIRECTIVE_LOCATION_REMOVED: 'DIRECTIVE_LOCATION_REMOVED',
27 REQUIRED_DIRECTIVE_ARG_ADDED: 'REQUIRED_DIRECTIVE_ARG_ADDED'
28};
29export var DangerousChangeType = {
30 ARG_DEFAULT_VALUE_CHANGE: 'ARG_DEFAULT_VALUE_CHANGE',
31 VALUE_ADDED_TO_ENUM: 'VALUE_ADDED_TO_ENUM',
32 INTERFACE_ADDED_TO_OBJECT: 'INTERFACE_ADDED_TO_OBJECT',
33 TYPE_ADDED_TO_UNION: 'TYPE_ADDED_TO_UNION',
34 OPTIONAL_INPUT_FIELD_ADDED: 'OPTIONAL_INPUT_FIELD_ADDED',
35 OPTIONAL_ARG_ADDED: 'OPTIONAL_ARG_ADDED'
36};
37
38/**
39 * Given two schemas, returns an Array containing descriptions of all the types
40 * of breaking changes covered by the other functions down below.
41 */
42export function findBreakingChanges(oldSchema, newSchema) {
43 return [].concat(findRemovedTypes(oldSchema, newSchema), findTypesThatChangedKind(oldSchema, newSchema), findFieldsThatChangedTypeOnObjectOrInterfaceTypes(oldSchema, newSchema), findFieldsThatChangedTypeOnInputObjectTypes(oldSchema, newSchema).breakingChanges, findTypesRemovedFromUnions(oldSchema, newSchema), findValuesRemovedFromEnums(oldSchema, newSchema), findArgChanges(oldSchema, newSchema).breakingChanges, findInterfacesRemovedFromObjectTypes(oldSchema, newSchema), findRemovedDirectives(oldSchema, newSchema), findRemovedDirectiveArgs(oldSchema, newSchema), findAddedNonNullDirectiveArgs(oldSchema, newSchema), findRemovedDirectiveLocations(oldSchema, newSchema));
44}
45/**
46 * Given two schemas, returns an Array containing descriptions of all the types
47 * of potentially dangerous changes covered by the other functions down below.
48 */
49
50export function findDangerousChanges(oldSchema, newSchema) {
51 return [].concat(findArgChanges(oldSchema, newSchema).dangerousChanges, findValuesAddedToEnums(oldSchema, newSchema), findInterfacesAddedToObjectTypes(oldSchema, newSchema), findTypesAddedToUnions(oldSchema, newSchema), findFieldsThatChangedTypeOnInputObjectTypes(oldSchema, newSchema).dangerousChanges);
52}
53/**
54 * Given two schemas, returns an Array containing descriptions of any breaking
55 * changes in the newSchema related to removing an entire type.
56 */
57
58export function findRemovedTypes(oldSchema, newSchema) {
59 var oldTypeMap = oldSchema.getTypeMap();
60 var newTypeMap = newSchema.getTypeMap();
61 var breakingChanges = [];
62
63 var _arr = Object.keys(oldTypeMap);
64
65 for (var _i = 0; _i < _arr.length; _i++) {
66 var typeName = _arr[_i];
67
68 if (!newTypeMap[typeName]) {
69 breakingChanges.push({
70 type: BreakingChangeType.TYPE_REMOVED,
71 description: "".concat(typeName, " was removed.")
72 });
73 }
74 }
75
76 return breakingChanges;
77}
78/**
79 * Given two schemas, returns an Array containing descriptions of any breaking
80 * changes in the newSchema related to changing the type of a type.
81 */
82
83export function findTypesThatChangedKind(oldSchema, newSchema) {
84 var oldTypeMap = oldSchema.getTypeMap();
85 var newTypeMap = newSchema.getTypeMap();
86 var breakingChanges = [];
87
88 var _arr2 = Object.keys(oldTypeMap);
89
90 for (var _i2 = 0; _i2 < _arr2.length; _i2++) {
91 var typeName = _arr2[_i2];
92
93 if (!newTypeMap[typeName]) {
94 continue;
95 }
96
97 var oldType = oldTypeMap[typeName];
98 var newType = newTypeMap[typeName];
99
100 if (oldType.constructor !== newType.constructor) {
101 breakingChanges.push({
102 type: BreakingChangeType.TYPE_CHANGED_KIND,
103 description: "".concat(typeName, " changed from ") + "".concat(typeKindName(oldType), " to ").concat(typeKindName(newType), ".")
104 });
105 }
106 }
107
108 return breakingChanges;
109}
110/**
111 * Given two schemas, returns an Array containing descriptions of any
112 * breaking or dangerous changes in the newSchema related to arguments
113 * (such as removal or change of type of an argument, or a change in an
114 * argument's default value).
115 */
116
117export function findArgChanges(oldSchema, newSchema) {
118 var oldTypeMap = oldSchema.getTypeMap();
119 var newTypeMap = newSchema.getTypeMap();
120 var breakingChanges = [];
121 var dangerousChanges = [];
122
123 var _arr3 = Object.keys(oldTypeMap);
124
125 for (var _i3 = 0; _i3 < _arr3.length; _i3++) {
126 var typeName = _arr3[_i3];
127 var oldType = oldTypeMap[typeName];
128 var newType = newTypeMap[typeName];
129
130 if (!(isObjectType(oldType) || isInterfaceType(oldType)) || !(isObjectType(newType) || isInterfaceType(newType)) || newType.constructor !== oldType.constructor) {
131 continue;
132 }
133
134 var oldTypeFields = oldType.getFields();
135 var newTypeFields = newType.getFields();
136
137 var _arr4 = Object.keys(oldTypeFields);
138
139 for (var _i4 = 0; _i4 < _arr4.length; _i4++) {
140 var fieldName = _arr4[_i4];
141
142 if (!newTypeFields[fieldName]) {
143 continue;
144 }
145
146 var _iteratorNormalCompletion = true;
147 var _didIteratorError = false;
148 var _iteratorError = undefined;
149
150 try {
151 var _loop = function _loop() {
152 var oldArgDef = _step.value;
153 var newArgs = newTypeFields[fieldName].args;
154 var newArgDef = find(newArgs, function (arg) {
155 return arg.name === oldArgDef.name;
156 }); // Arg not present
157
158 if (!newArgDef) {
159 breakingChanges.push({
160 type: BreakingChangeType.ARG_REMOVED,
161 description: "".concat(oldType.name, ".").concat(fieldName, " arg ") + "".concat(oldArgDef.name, " was removed")
162 });
163 } else {
164 var isSafe = isChangeSafeForInputObjectFieldOrFieldArg(oldArgDef.type, newArgDef.type);
165
166 if (!isSafe) {
167 breakingChanges.push({
168 type: BreakingChangeType.ARG_CHANGED_KIND,
169 description: "".concat(oldType.name, ".").concat(fieldName, " arg ") + "".concat(oldArgDef.name, " has changed type from ") + "".concat(oldArgDef.type.toString(), " to ").concat(newArgDef.type.toString())
170 });
171 } else if (oldArgDef.defaultValue !== undefined && oldArgDef.defaultValue !== newArgDef.defaultValue) {
172 dangerousChanges.push({
173 type: DangerousChangeType.ARG_DEFAULT_VALUE_CHANGE,
174 description: "".concat(oldType.name, ".").concat(fieldName, " arg ") + "".concat(oldArgDef.name, " has changed defaultValue")
175 });
176 }
177 }
178 };
179
180 for (var _iterator = oldTypeFields[fieldName].args[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) {
181 _loop();
182 } // Check if arg was added to the field
183
184 } catch (err) {
185 _didIteratorError = true;
186 _iteratorError = err;
187 } finally {
188 try {
189 if (!_iteratorNormalCompletion && _iterator.return != null) {
190 _iterator.return();
191 }
192 } finally {
193 if (_didIteratorError) {
194 throw _iteratorError;
195 }
196 }
197 }
198
199 var _iteratorNormalCompletion2 = true;
200 var _didIteratorError2 = false;
201 var _iteratorError2 = undefined;
202
203 try {
204 var _loop2 = function _loop2() {
205 var newArgDef = _step2.value;
206 var oldArgs = oldTypeFields[fieldName].args;
207 var oldArgDef = find(oldArgs, function (arg) {
208 return arg.name === newArgDef.name;
209 });
210
211 if (!oldArgDef) {
212 var argName = newArgDef.name;
213
214 if (isRequiredArgument(newArgDef)) {
215 breakingChanges.push({
216 type: BreakingChangeType.REQUIRED_ARG_ADDED,
217 description: "A required arg ".concat(argName, " on ") + "".concat(typeName, ".").concat(fieldName, " was added")
218 });
219 } else {
220 dangerousChanges.push({
221 type: DangerousChangeType.OPTIONAL_ARG_ADDED,
222 description: "An optional arg ".concat(argName, " on ") + "".concat(typeName, ".").concat(fieldName, " was added")
223 });
224 }
225 }
226 };
227
228 for (var _iterator2 = newTypeFields[fieldName].args[Symbol.iterator](), _step2; !(_iteratorNormalCompletion2 = (_step2 = _iterator2.next()).done); _iteratorNormalCompletion2 = true) {
229 _loop2();
230 }
231 } catch (err) {
232 _didIteratorError2 = true;
233 _iteratorError2 = err;
234 } finally {
235 try {
236 if (!_iteratorNormalCompletion2 && _iterator2.return != null) {
237 _iterator2.return();
238 }
239 } finally {
240 if (_didIteratorError2) {
241 throw _iteratorError2;
242 }
243 }
244 }
245 }
246 }
247
248 return {
249 breakingChanges: breakingChanges,
250 dangerousChanges: dangerousChanges
251 };
252}
253
254function typeKindName(type) {
255 if (isScalarType(type)) {
256 return 'a Scalar type';
257 }
258
259 if (isObjectType(type)) {
260 return 'an Object type';
261 }
262
263 if (isInterfaceType(type)) {
264 return 'an Interface type';
265 }
266
267 if (isUnionType(type)) {
268 return 'a Union type';
269 }
270
271 if (isEnumType(type)) {
272 return 'an Enum type';
273 }
274
275 if (isInputObjectType(type)) {
276 return 'an Input type';
277 }
278
279 throw new TypeError('Unknown type ' + type.constructor.name);
280}
281
282export function findFieldsThatChangedTypeOnObjectOrInterfaceTypes(oldSchema, newSchema) {
283 var oldTypeMap = oldSchema.getTypeMap();
284 var newTypeMap = newSchema.getTypeMap();
285 var breakingChanges = [];
286
287 var _arr5 = Object.keys(oldTypeMap);
288
289 for (var _i5 = 0; _i5 < _arr5.length; _i5++) {
290 var typeName = _arr5[_i5];
291 var oldType = oldTypeMap[typeName];
292 var newType = newTypeMap[typeName];
293
294 if (!(isObjectType(oldType) || isInterfaceType(oldType)) || !(isObjectType(newType) || isInterfaceType(newType)) || newType.constructor !== oldType.constructor) {
295 continue;
296 }
297
298 var oldTypeFieldsDef = oldType.getFields();
299 var newTypeFieldsDef = newType.getFields();
300
301 var _arr6 = Object.keys(oldTypeFieldsDef);
302
303 for (var _i6 = 0; _i6 < _arr6.length; _i6++) {
304 var fieldName = _arr6[_i6];
305
306 // Check if the field is missing on the type in the new schema.
307 if (!(fieldName in newTypeFieldsDef)) {
308 breakingChanges.push({
309 type: BreakingChangeType.FIELD_REMOVED,
310 description: "".concat(typeName, ".").concat(fieldName, " was removed.")
311 });
312 } else {
313 var oldFieldType = oldTypeFieldsDef[fieldName].type;
314 var newFieldType = newTypeFieldsDef[fieldName].type;
315 var isSafe = isChangeSafeForObjectOrInterfaceField(oldFieldType, newFieldType);
316
317 if (!isSafe) {
318 var oldFieldTypeString = isNamedType(oldFieldType) ? oldFieldType.name : oldFieldType.toString();
319 var newFieldTypeString = isNamedType(newFieldType) ? newFieldType.name : newFieldType.toString();
320 breakingChanges.push({
321 type: BreakingChangeType.FIELD_CHANGED_KIND,
322 description: "".concat(typeName, ".").concat(fieldName, " changed type from ") + "".concat(oldFieldTypeString, " to ").concat(newFieldTypeString, ".")
323 });
324 }
325 }
326 }
327 }
328
329 return breakingChanges;
330}
331export function findFieldsThatChangedTypeOnInputObjectTypes(oldSchema, newSchema) {
332 var oldTypeMap = oldSchema.getTypeMap();
333 var newTypeMap = newSchema.getTypeMap();
334 var breakingChanges = [];
335 var dangerousChanges = [];
336
337 var _arr7 = Object.keys(oldTypeMap);
338
339 for (var _i7 = 0; _i7 < _arr7.length; _i7++) {
340 var typeName = _arr7[_i7];
341 var oldType = oldTypeMap[typeName];
342 var newType = newTypeMap[typeName];
343
344 if (!isInputObjectType(oldType) || !isInputObjectType(newType)) {
345 continue;
346 }
347
348 var oldTypeFieldsDef = oldType.getFields();
349 var newTypeFieldsDef = newType.getFields();
350
351 var _arr8 = Object.keys(oldTypeFieldsDef);
352
353 for (var _i8 = 0; _i8 < _arr8.length; _i8++) {
354 var fieldName = _arr8[_i8];
355
356 // Check if the field is missing on the type in the new schema.
357 if (!(fieldName in newTypeFieldsDef)) {
358 breakingChanges.push({
359 type: BreakingChangeType.FIELD_REMOVED,
360 description: "".concat(typeName, ".").concat(fieldName, " was removed.")
361 });
362 } else {
363 var oldFieldType = oldTypeFieldsDef[fieldName].type;
364 var newFieldType = newTypeFieldsDef[fieldName].type;
365 var isSafe = isChangeSafeForInputObjectFieldOrFieldArg(oldFieldType, newFieldType);
366
367 if (!isSafe) {
368 var oldFieldTypeString = isNamedType(oldFieldType) ? oldFieldType.name : oldFieldType.toString();
369 var newFieldTypeString = isNamedType(newFieldType) ? newFieldType.name : newFieldType.toString();
370 breakingChanges.push({
371 type: BreakingChangeType.FIELD_CHANGED_KIND,
372 description: "".concat(typeName, ".").concat(fieldName, " changed type from ") + "".concat(oldFieldTypeString, " to ").concat(newFieldTypeString, ".")
373 });
374 }
375 }
376 } // Check if a field was added to the input object type
377
378
379 var _arr9 = Object.keys(newTypeFieldsDef);
380
381 for (var _i9 = 0; _i9 < _arr9.length; _i9++) {
382 var _fieldName = _arr9[_i9];
383
384 if (!(_fieldName in oldTypeFieldsDef)) {
385 if (isRequiredInputField(newTypeFieldsDef[_fieldName])) {
386 breakingChanges.push({
387 type: BreakingChangeType.REQUIRED_INPUT_FIELD_ADDED,
388 description: "A required field ".concat(_fieldName, " on ") + "input type ".concat(typeName, " was added.")
389 });
390 } else {
391 dangerousChanges.push({
392 type: DangerousChangeType.OPTIONAL_INPUT_FIELD_ADDED,
393 description: "An optional field ".concat(_fieldName, " on ") + "input type ".concat(typeName, " was added.")
394 });
395 }
396 }
397 }
398 }
399
400 return {
401 breakingChanges: breakingChanges,
402 dangerousChanges: dangerousChanges
403 };
404}
405
406function isChangeSafeForObjectOrInterfaceField(oldType, newType) {
407 if (isNamedType(oldType)) {
408 return (// if they're both named types, see if their names are equivalent
409 isNamedType(newType) && oldType.name === newType.name || // moving from nullable to non-null of the same underlying type is safe
410 isNonNullType(newType) && isChangeSafeForObjectOrInterfaceField(oldType, newType.ofType)
411 );
412 } else if (isListType(oldType)) {
413 return (// if they're both lists, make sure the underlying types are compatible
414 isListType(newType) && isChangeSafeForObjectOrInterfaceField(oldType.ofType, newType.ofType) || // moving from nullable to non-null of the same underlying type is safe
415 isNonNullType(newType) && isChangeSafeForObjectOrInterfaceField(oldType, newType.ofType)
416 );
417 } else if (isNonNullType(oldType)) {
418 // if they're both non-null, make sure the underlying types are compatible
419 return isNonNullType(newType) && isChangeSafeForObjectOrInterfaceField(oldType.ofType, newType.ofType);
420 }
421
422 return false;
423}
424
425function isChangeSafeForInputObjectFieldOrFieldArg(oldType, newType) {
426 if (isNamedType(oldType)) {
427 // if they're both named types, see if their names are equivalent
428 return isNamedType(newType) && oldType.name === newType.name;
429 } else if (isListType(oldType)) {
430 // if they're both lists, make sure the underlying types are compatible
431 return isListType(newType) && isChangeSafeForInputObjectFieldOrFieldArg(oldType.ofType, newType.ofType);
432 } else if (isNonNullType(oldType)) {
433 return (// if they're both non-null, make sure the underlying types are
434 // compatible
435 isNonNullType(newType) && isChangeSafeForInputObjectFieldOrFieldArg(oldType.ofType, newType.ofType) || // moving from non-null to nullable of the same underlying type is safe
436 !isNonNullType(newType) && isChangeSafeForInputObjectFieldOrFieldArg(oldType.ofType, newType)
437 );
438 }
439
440 return false;
441}
442/**
443 * Given two schemas, returns an Array containing descriptions of any breaking
444 * changes in the newSchema related to removing types from a union type.
445 */
446
447
448export function findTypesRemovedFromUnions(oldSchema, newSchema) {
449 var oldTypeMap = oldSchema.getTypeMap();
450 var newTypeMap = newSchema.getTypeMap();
451 var typesRemovedFromUnion = [];
452
453 var _arr10 = Object.keys(oldTypeMap);
454
455 for (var _i10 = 0; _i10 < _arr10.length; _i10++) {
456 var typeName = _arr10[_i10];
457 var oldType = oldTypeMap[typeName];
458 var newType = newTypeMap[typeName];
459
460 if (!isUnionType(oldType) || !isUnionType(newType)) {
461 continue;
462 }
463
464 var typeNamesInNewUnion = Object.create(null);
465 var _iteratorNormalCompletion3 = true;
466 var _didIteratorError3 = false;
467 var _iteratorError3 = undefined;
468
469 try {
470 for (var _iterator3 = newType.getTypes()[Symbol.iterator](), _step3; !(_iteratorNormalCompletion3 = (_step3 = _iterator3.next()).done); _iteratorNormalCompletion3 = true) {
471 var type = _step3.value;
472 typeNamesInNewUnion[type.name] = true;
473 }
474 } catch (err) {
475 _didIteratorError3 = true;
476 _iteratorError3 = err;
477 } finally {
478 try {
479 if (!_iteratorNormalCompletion3 && _iterator3.return != null) {
480 _iterator3.return();
481 }
482 } finally {
483 if (_didIteratorError3) {
484 throw _iteratorError3;
485 }
486 }
487 }
488
489 var _iteratorNormalCompletion4 = true;
490 var _didIteratorError4 = false;
491 var _iteratorError4 = undefined;
492
493 try {
494 for (var _iterator4 = oldType.getTypes()[Symbol.iterator](), _step4; !(_iteratorNormalCompletion4 = (_step4 = _iterator4.next()).done); _iteratorNormalCompletion4 = true) {
495 var _type = _step4.value;
496
497 if (!typeNamesInNewUnion[_type.name]) {
498 typesRemovedFromUnion.push({
499 type: BreakingChangeType.TYPE_REMOVED_FROM_UNION,
500 description: "".concat(_type.name, " was removed from union type ").concat(typeName, ".")
501 });
502 }
503 }
504 } catch (err) {
505 _didIteratorError4 = true;
506 _iteratorError4 = err;
507 } finally {
508 try {
509 if (!_iteratorNormalCompletion4 && _iterator4.return != null) {
510 _iterator4.return();
511 }
512 } finally {
513 if (_didIteratorError4) {
514 throw _iteratorError4;
515 }
516 }
517 }
518 }
519
520 return typesRemovedFromUnion;
521}
522/**
523 * Given two schemas, returns an Array containing descriptions of any dangerous
524 * changes in the newSchema related to adding types to a union type.
525 */
526
527export function findTypesAddedToUnions(oldSchema, newSchema) {
528 var oldTypeMap = oldSchema.getTypeMap();
529 var newTypeMap = newSchema.getTypeMap();
530 var typesAddedToUnion = [];
531
532 var _arr11 = Object.keys(newTypeMap);
533
534 for (var _i11 = 0; _i11 < _arr11.length; _i11++) {
535 var typeName = _arr11[_i11];
536 var oldType = oldTypeMap[typeName];
537 var newType = newTypeMap[typeName];
538
539 if (!isUnionType(oldType) || !isUnionType(newType)) {
540 continue;
541 }
542
543 var typeNamesInOldUnion = Object.create(null);
544 var _iteratorNormalCompletion5 = true;
545 var _didIteratorError5 = false;
546 var _iteratorError5 = undefined;
547
548 try {
549 for (var _iterator5 = oldType.getTypes()[Symbol.iterator](), _step5; !(_iteratorNormalCompletion5 = (_step5 = _iterator5.next()).done); _iteratorNormalCompletion5 = true) {
550 var type = _step5.value;
551 typeNamesInOldUnion[type.name] = true;
552 }
553 } catch (err) {
554 _didIteratorError5 = true;
555 _iteratorError5 = err;
556 } finally {
557 try {
558 if (!_iteratorNormalCompletion5 && _iterator5.return != null) {
559 _iterator5.return();
560 }
561 } finally {
562 if (_didIteratorError5) {
563 throw _iteratorError5;
564 }
565 }
566 }
567
568 var _iteratorNormalCompletion6 = true;
569 var _didIteratorError6 = false;
570 var _iteratorError6 = undefined;
571
572 try {
573 for (var _iterator6 = newType.getTypes()[Symbol.iterator](), _step6; !(_iteratorNormalCompletion6 = (_step6 = _iterator6.next()).done); _iteratorNormalCompletion6 = true) {
574 var _type2 = _step6.value;
575
576 if (!typeNamesInOldUnion[_type2.name]) {
577 typesAddedToUnion.push({
578 type: DangerousChangeType.TYPE_ADDED_TO_UNION,
579 description: "".concat(_type2.name, " was added to union type ").concat(typeName, ".")
580 });
581 }
582 }
583 } catch (err) {
584 _didIteratorError6 = true;
585 _iteratorError6 = err;
586 } finally {
587 try {
588 if (!_iteratorNormalCompletion6 && _iterator6.return != null) {
589 _iterator6.return();
590 }
591 } finally {
592 if (_didIteratorError6) {
593 throw _iteratorError6;
594 }
595 }
596 }
597 }
598
599 return typesAddedToUnion;
600}
601/**
602 * Given two schemas, returns an Array containing descriptions of any breaking
603 * changes in the newSchema related to removing values from an enum type.
604 */
605
606export function findValuesRemovedFromEnums(oldSchema, newSchema) {
607 var oldTypeMap = oldSchema.getTypeMap();
608 var newTypeMap = newSchema.getTypeMap();
609 var valuesRemovedFromEnums = [];
610
611 var _arr12 = Object.keys(oldTypeMap);
612
613 for (var _i12 = 0; _i12 < _arr12.length; _i12++) {
614 var typeName = _arr12[_i12];
615 var oldType = oldTypeMap[typeName];
616 var newType = newTypeMap[typeName];
617
618 if (!isEnumType(oldType) || !isEnumType(newType)) {
619 continue;
620 }
621
622 var valuesInNewEnum = Object.create(null);
623 var _iteratorNormalCompletion7 = true;
624 var _didIteratorError7 = false;
625 var _iteratorError7 = undefined;
626
627 try {
628 for (var _iterator7 = newType.getValues()[Symbol.iterator](), _step7; !(_iteratorNormalCompletion7 = (_step7 = _iterator7.next()).done); _iteratorNormalCompletion7 = true) {
629 var value = _step7.value;
630 valuesInNewEnum[value.name] = true;
631 }
632 } catch (err) {
633 _didIteratorError7 = true;
634 _iteratorError7 = err;
635 } finally {
636 try {
637 if (!_iteratorNormalCompletion7 && _iterator7.return != null) {
638 _iterator7.return();
639 }
640 } finally {
641 if (_didIteratorError7) {
642 throw _iteratorError7;
643 }
644 }
645 }
646
647 var _iteratorNormalCompletion8 = true;
648 var _didIteratorError8 = false;
649 var _iteratorError8 = undefined;
650
651 try {
652 for (var _iterator8 = oldType.getValues()[Symbol.iterator](), _step8; !(_iteratorNormalCompletion8 = (_step8 = _iterator8.next()).done); _iteratorNormalCompletion8 = true) {
653 var _value = _step8.value;
654
655 if (!valuesInNewEnum[_value.name]) {
656 valuesRemovedFromEnums.push({
657 type: BreakingChangeType.VALUE_REMOVED_FROM_ENUM,
658 description: "".concat(_value.name, " was removed from enum type ").concat(typeName, ".")
659 });
660 }
661 }
662 } catch (err) {
663 _didIteratorError8 = true;
664 _iteratorError8 = err;
665 } finally {
666 try {
667 if (!_iteratorNormalCompletion8 && _iterator8.return != null) {
668 _iterator8.return();
669 }
670 } finally {
671 if (_didIteratorError8) {
672 throw _iteratorError8;
673 }
674 }
675 }
676 }
677
678 return valuesRemovedFromEnums;
679}
680/**
681 * Given two schemas, returns an Array containing descriptions of any dangerous
682 * changes in the newSchema related to adding values to an enum type.
683 */
684
685export function findValuesAddedToEnums(oldSchema, newSchema) {
686 var oldTypeMap = oldSchema.getTypeMap();
687 var newTypeMap = newSchema.getTypeMap();
688 var valuesAddedToEnums = [];
689
690 var _arr13 = Object.keys(oldTypeMap);
691
692 for (var _i13 = 0; _i13 < _arr13.length; _i13++) {
693 var typeName = _arr13[_i13];
694 var oldType = oldTypeMap[typeName];
695 var newType = newTypeMap[typeName];
696
697 if (!isEnumType(oldType) || !isEnumType(newType)) {
698 continue;
699 }
700
701 var valuesInOldEnum = Object.create(null);
702 var _iteratorNormalCompletion9 = true;
703 var _didIteratorError9 = false;
704 var _iteratorError9 = undefined;
705
706 try {
707 for (var _iterator9 = oldType.getValues()[Symbol.iterator](), _step9; !(_iteratorNormalCompletion9 = (_step9 = _iterator9.next()).done); _iteratorNormalCompletion9 = true) {
708 var value = _step9.value;
709 valuesInOldEnum[value.name] = true;
710 }
711 } catch (err) {
712 _didIteratorError9 = true;
713 _iteratorError9 = err;
714 } finally {
715 try {
716 if (!_iteratorNormalCompletion9 && _iterator9.return != null) {
717 _iterator9.return();
718 }
719 } finally {
720 if (_didIteratorError9) {
721 throw _iteratorError9;
722 }
723 }
724 }
725
726 var _iteratorNormalCompletion10 = true;
727 var _didIteratorError10 = false;
728 var _iteratorError10 = undefined;
729
730 try {
731 for (var _iterator10 = newType.getValues()[Symbol.iterator](), _step10; !(_iteratorNormalCompletion10 = (_step10 = _iterator10.next()).done); _iteratorNormalCompletion10 = true) {
732 var _value2 = _step10.value;
733
734 if (!valuesInOldEnum[_value2.name]) {
735 valuesAddedToEnums.push({
736 type: DangerousChangeType.VALUE_ADDED_TO_ENUM,
737 description: "".concat(_value2.name, " was added to enum type ").concat(typeName, ".")
738 });
739 }
740 }
741 } catch (err) {
742 _didIteratorError10 = true;
743 _iteratorError10 = err;
744 } finally {
745 try {
746 if (!_iteratorNormalCompletion10 && _iterator10.return != null) {
747 _iterator10.return();
748 }
749 } finally {
750 if (_didIteratorError10) {
751 throw _iteratorError10;
752 }
753 }
754 }
755 }
756
757 return valuesAddedToEnums;
758}
759export function findInterfacesRemovedFromObjectTypes(oldSchema, newSchema) {
760 var oldTypeMap = oldSchema.getTypeMap();
761 var newTypeMap = newSchema.getTypeMap();
762 var breakingChanges = [];
763
764 var _arr14 = Object.keys(oldTypeMap);
765
766 for (var _i14 = 0; _i14 < _arr14.length; _i14++) {
767 var typeName = _arr14[_i14];
768 var oldType = oldTypeMap[typeName];
769 var newType = newTypeMap[typeName];
770
771 if (!isObjectType(oldType) || !isObjectType(newType)) {
772 continue;
773 }
774
775 var oldInterfaces = oldType.getInterfaces();
776 var newInterfaces = newType.getInterfaces();
777 var _iteratorNormalCompletion11 = true;
778 var _didIteratorError11 = false;
779 var _iteratorError11 = undefined;
780
781 try {
782 var _loop3 = function _loop3() {
783 var oldInterface = _step11.value;
784
785 if (!newInterfaces.some(function (int) {
786 return int.name === oldInterface.name;
787 })) {
788 breakingChanges.push({
789 type: BreakingChangeType.INTERFACE_REMOVED_FROM_OBJECT,
790 description: "".concat(typeName, " no longer implements interface ") + "".concat(oldInterface.name, ".")
791 });
792 }
793 };
794
795 for (var _iterator11 = oldInterfaces[Symbol.iterator](), _step11; !(_iteratorNormalCompletion11 = (_step11 = _iterator11.next()).done); _iteratorNormalCompletion11 = true) {
796 _loop3();
797 }
798 } catch (err) {
799 _didIteratorError11 = true;
800 _iteratorError11 = err;
801 } finally {
802 try {
803 if (!_iteratorNormalCompletion11 && _iterator11.return != null) {
804 _iterator11.return();
805 }
806 } finally {
807 if (_didIteratorError11) {
808 throw _iteratorError11;
809 }
810 }
811 }
812 }
813
814 return breakingChanges;
815}
816export function findInterfacesAddedToObjectTypes(oldSchema, newSchema) {
817 var oldTypeMap = oldSchema.getTypeMap();
818 var newTypeMap = newSchema.getTypeMap();
819 var interfacesAddedToObjectTypes = [];
820
821 var _arr15 = Object.keys(newTypeMap);
822
823 for (var _i15 = 0; _i15 < _arr15.length; _i15++) {
824 var typeName = _arr15[_i15];
825 var oldType = oldTypeMap[typeName];
826 var newType = newTypeMap[typeName];
827
828 if (!isObjectType(oldType) || !isObjectType(newType)) {
829 continue;
830 }
831
832 var oldInterfaces = oldType.getInterfaces();
833 var newInterfaces = newType.getInterfaces();
834 var _iteratorNormalCompletion12 = true;
835 var _didIteratorError12 = false;
836 var _iteratorError12 = undefined;
837
838 try {
839 var _loop4 = function _loop4() {
840 var newInterface = _step12.value;
841
842 if (!oldInterfaces.some(function (int) {
843 return int.name === newInterface.name;
844 })) {
845 interfacesAddedToObjectTypes.push({
846 type: DangerousChangeType.INTERFACE_ADDED_TO_OBJECT,
847 description: "".concat(newInterface.name, " added to interfaces implemented ") + "by ".concat(typeName, ".")
848 });
849 }
850 };
851
852 for (var _iterator12 = newInterfaces[Symbol.iterator](), _step12; !(_iteratorNormalCompletion12 = (_step12 = _iterator12.next()).done); _iteratorNormalCompletion12 = true) {
853 _loop4();
854 }
855 } catch (err) {
856 _didIteratorError12 = true;
857 _iteratorError12 = err;
858 } finally {
859 try {
860 if (!_iteratorNormalCompletion12 && _iterator12.return != null) {
861 _iterator12.return();
862 }
863 } finally {
864 if (_didIteratorError12) {
865 throw _iteratorError12;
866 }
867 }
868 }
869 }
870
871 return interfacesAddedToObjectTypes;
872}
873export function findRemovedDirectives(oldSchema, newSchema) {
874 var removedDirectives = [];
875 var newSchemaDirectiveMap = getDirectiveMapForSchema(newSchema);
876 var _iteratorNormalCompletion13 = true;
877 var _didIteratorError13 = false;
878 var _iteratorError13 = undefined;
879
880 try {
881 for (var _iterator13 = oldSchema.getDirectives()[Symbol.iterator](), _step13; !(_iteratorNormalCompletion13 = (_step13 = _iterator13.next()).done); _iteratorNormalCompletion13 = true) {
882 var directive = _step13.value;
883
884 if (!newSchemaDirectiveMap[directive.name]) {
885 removedDirectives.push({
886 type: BreakingChangeType.DIRECTIVE_REMOVED,
887 description: "".concat(directive.name, " was removed")
888 });
889 }
890 }
891 } catch (err) {
892 _didIteratorError13 = true;
893 _iteratorError13 = err;
894 } finally {
895 try {
896 if (!_iteratorNormalCompletion13 && _iterator13.return != null) {
897 _iterator13.return();
898 }
899 } finally {
900 if (_didIteratorError13) {
901 throw _iteratorError13;
902 }
903 }
904 }
905
906 return removedDirectives;
907}
908
909function findRemovedArgsForDirective(oldDirective, newDirective) {
910 var removedArgs = [];
911 var newArgMap = getArgumentMapForDirective(newDirective);
912 var _iteratorNormalCompletion14 = true;
913 var _didIteratorError14 = false;
914 var _iteratorError14 = undefined;
915
916 try {
917 for (var _iterator14 = oldDirective.args[Symbol.iterator](), _step14; !(_iteratorNormalCompletion14 = (_step14 = _iterator14.next()).done); _iteratorNormalCompletion14 = true) {
918 var arg = _step14.value;
919
920 if (!newArgMap[arg.name]) {
921 removedArgs.push(arg);
922 }
923 }
924 } catch (err) {
925 _didIteratorError14 = true;
926 _iteratorError14 = err;
927 } finally {
928 try {
929 if (!_iteratorNormalCompletion14 && _iterator14.return != null) {
930 _iterator14.return();
931 }
932 } finally {
933 if (_didIteratorError14) {
934 throw _iteratorError14;
935 }
936 }
937 }
938
939 return removedArgs;
940}
941
942export function findRemovedDirectiveArgs(oldSchema, newSchema) {
943 var removedDirectiveArgs = [];
944 var oldSchemaDirectiveMap = getDirectiveMapForSchema(oldSchema);
945 var _iteratorNormalCompletion15 = true;
946 var _didIteratorError15 = false;
947 var _iteratorError15 = undefined;
948
949 try {
950 for (var _iterator15 = newSchema.getDirectives()[Symbol.iterator](), _step15; !(_iteratorNormalCompletion15 = (_step15 = _iterator15.next()).done); _iteratorNormalCompletion15 = true) {
951 var newDirective = _step15.value;
952 var oldDirective = oldSchemaDirectiveMap[newDirective.name];
953
954 if (!oldDirective) {
955 continue;
956 }
957
958 var _iteratorNormalCompletion16 = true;
959 var _didIteratorError16 = false;
960 var _iteratorError16 = undefined;
961
962 try {
963 for (var _iterator16 = findRemovedArgsForDirective(oldDirective, newDirective)[Symbol.iterator](), _step16; !(_iteratorNormalCompletion16 = (_step16 = _iterator16.next()).done); _iteratorNormalCompletion16 = true) {
964 var arg = _step16.value;
965 removedDirectiveArgs.push({
966 type: BreakingChangeType.DIRECTIVE_ARG_REMOVED,
967 description: "".concat(arg.name, " was removed from ").concat(newDirective.name)
968 });
969 }
970 } catch (err) {
971 _didIteratorError16 = true;
972 _iteratorError16 = err;
973 } finally {
974 try {
975 if (!_iteratorNormalCompletion16 && _iterator16.return != null) {
976 _iterator16.return();
977 }
978 } finally {
979 if (_didIteratorError16) {
980 throw _iteratorError16;
981 }
982 }
983 }
984 }
985 } catch (err) {
986 _didIteratorError15 = true;
987 _iteratorError15 = err;
988 } finally {
989 try {
990 if (!_iteratorNormalCompletion15 && _iterator15.return != null) {
991 _iterator15.return();
992 }
993 } finally {
994 if (_didIteratorError15) {
995 throw _iteratorError15;
996 }
997 }
998 }
999
1000 return removedDirectiveArgs;
1001}
1002
1003function findAddedArgsForDirective(oldDirective, newDirective) {
1004 var addedArgs = [];
1005 var oldArgMap = getArgumentMapForDirective(oldDirective);
1006 var _iteratorNormalCompletion17 = true;
1007 var _didIteratorError17 = false;
1008 var _iteratorError17 = undefined;
1009
1010 try {
1011 for (var _iterator17 = newDirective.args[Symbol.iterator](), _step17; !(_iteratorNormalCompletion17 = (_step17 = _iterator17.next()).done); _iteratorNormalCompletion17 = true) {
1012 var arg = _step17.value;
1013
1014 if (!oldArgMap[arg.name]) {
1015 addedArgs.push(arg);
1016 }
1017 }
1018 } catch (err) {
1019 _didIteratorError17 = true;
1020 _iteratorError17 = err;
1021 } finally {
1022 try {
1023 if (!_iteratorNormalCompletion17 && _iterator17.return != null) {
1024 _iterator17.return();
1025 }
1026 } finally {
1027 if (_didIteratorError17) {
1028 throw _iteratorError17;
1029 }
1030 }
1031 }
1032
1033 return addedArgs;
1034}
1035
1036export function findAddedNonNullDirectiveArgs(oldSchema, newSchema) {
1037 var addedNonNullableArgs = [];
1038 var oldSchemaDirectiveMap = getDirectiveMapForSchema(oldSchema);
1039 var _iteratorNormalCompletion18 = true;
1040 var _didIteratorError18 = false;
1041 var _iteratorError18 = undefined;
1042
1043 try {
1044 for (var _iterator18 = newSchema.getDirectives()[Symbol.iterator](), _step18; !(_iteratorNormalCompletion18 = (_step18 = _iterator18.next()).done); _iteratorNormalCompletion18 = true) {
1045 var newDirective = _step18.value;
1046 var oldDirective = oldSchemaDirectiveMap[newDirective.name];
1047
1048 if (!oldDirective) {
1049 continue;
1050 }
1051
1052 var _iteratorNormalCompletion19 = true;
1053 var _didIteratorError19 = false;
1054 var _iteratorError19 = undefined;
1055
1056 try {
1057 for (var _iterator19 = findAddedArgsForDirective(oldDirective, newDirective)[Symbol.iterator](), _step19; !(_iteratorNormalCompletion19 = (_step19 = _iterator19.next()).done); _iteratorNormalCompletion19 = true) {
1058 var arg = _step19.value;
1059
1060 if (isRequiredArgument(arg)) {
1061 addedNonNullableArgs.push({
1062 type: BreakingChangeType.REQUIRED_DIRECTIVE_ARG_ADDED,
1063 description: "A required arg ".concat(arg.name, " on directive ") + "".concat(newDirective.name, " was added")
1064 });
1065 }
1066 }
1067 } catch (err) {
1068 _didIteratorError19 = true;
1069 _iteratorError19 = err;
1070 } finally {
1071 try {
1072 if (!_iteratorNormalCompletion19 && _iterator19.return != null) {
1073 _iterator19.return();
1074 }
1075 } finally {
1076 if (_didIteratorError19) {
1077 throw _iteratorError19;
1078 }
1079 }
1080 }
1081 }
1082 } catch (err) {
1083 _didIteratorError18 = true;
1084 _iteratorError18 = err;
1085 } finally {
1086 try {
1087 if (!_iteratorNormalCompletion18 && _iterator18.return != null) {
1088 _iterator18.return();
1089 }
1090 } finally {
1091 if (_didIteratorError18) {
1092 throw _iteratorError18;
1093 }
1094 }
1095 }
1096
1097 return addedNonNullableArgs;
1098}
1099export function findRemovedLocationsForDirective(oldDirective, newDirective) {
1100 var removedLocations = [];
1101 var newLocationSet = new Set(newDirective.locations);
1102 var _iteratorNormalCompletion20 = true;
1103 var _didIteratorError20 = false;
1104 var _iteratorError20 = undefined;
1105
1106 try {
1107 for (var _iterator20 = oldDirective.locations[Symbol.iterator](), _step20; !(_iteratorNormalCompletion20 = (_step20 = _iterator20.next()).done); _iteratorNormalCompletion20 = true) {
1108 var oldLocation = _step20.value;
1109
1110 if (!newLocationSet.has(oldLocation)) {
1111 removedLocations.push(oldLocation);
1112 }
1113 }
1114 } catch (err) {
1115 _didIteratorError20 = true;
1116 _iteratorError20 = err;
1117 } finally {
1118 try {
1119 if (!_iteratorNormalCompletion20 && _iterator20.return != null) {
1120 _iterator20.return();
1121 }
1122 } finally {
1123 if (_didIteratorError20) {
1124 throw _iteratorError20;
1125 }
1126 }
1127 }
1128
1129 return removedLocations;
1130}
1131export function findRemovedDirectiveLocations(oldSchema, newSchema) {
1132 var removedLocations = [];
1133 var oldSchemaDirectiveMap = getDirectiveMapForSchema(oldSchema);
1134 var _iteratorNormalCompletion21 = true;
1135 var _didIteratorError21 = false;
1136 var _iteratorError21 = undefined;
1137
1138 try {
1139 for (var _iterator21 = newSchema.getDirectives()[Symbol.iterator](), _step21; !(_iteratorNormalCompletion21 = (_step21 = _iterator21.next()).done); _iteratorNormalCompletion21 = true) {
1140 var newDirective = _step21.value;
1141 var oldDirective = oldSchemaDirectiveMap[newDirective.name];
1142
1143 if (!oldDirective) {
1144 continue;
1145 }
1146
1147 var _iteratorNormalCompletion22 = true;
1148 var _didIteratorError22 = false;
1149 var _iteratorError22 = undefined;
1150
1151 try {
1152 for (var _iterator22 = findRemovedLocationsForDirective(oldDirective, newDirective)[Symbol.iterator](), _step22; !(_iteratorNormalCompletion22 = (_step22 = _iterator22.next()).done); _iteratorNormalCompletion22 = true) {
1153 var location = _step22.value;
1154 removedLocations.push({
1155 type: BreakingChangeType.DIRECTIVE_LOCATION_REMOVED,
1156 description: "".concat(location, " was removed from ").concat(newDirective.name)
1157 });
1158 }
1159 } catch (err) {
1160 _didIteratorError22 = true;
1161 _iteratorError22 = err;
1162 } finally {
1163 try {
1164 if (!_iteratorNormalCompletion22 && _iterator22.return != null) {
1165 _iterator22.return();
1166 }
1167 } finally {
1168 if (_didIteratorError22) {
1169 throw _iteratorError22;
1170 }
1171 }
1172 }
1173 }
1174 } catch (err) {
1175 _didIteratorError21 = true;
1176 _iteratorError21 = err;
1177 } finally {
1178 try {
1179 if (!_iteratorNormalCompletion21 && _iterator21.return != null) {
1180 _iterator21.return();
1181 }
1182 } finally {
1183 if (_didIteratorError21) {
1184 throw _iteratorError21;
1185 }
1186 }
1187 }
1188
1189 return removedLocations;
1190}
1191
1192function getDirectiveMapForSchema(schema) {
1193 return keyMap(schema.getDirectives(), function (dir) {
1194 return dir.name;
1195 });
1196}
1197
1198function getArgumentMapForDirective(directive) {
1199 return keyMap(directive.args, function (arg) {
1200 return arg.name;
1201 });
1202}
\No newline at end of file