/** * Copyright (c) Facebook, Inc. and its affiliates. * * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. * * */ import find from '../polyfills/find'; import inspect from '../jsutils/inspect'; import { isScalarType, isObjectType, isInterfaceType, isUnionType, isEnumType, isInputObjectType, isNonNullType, isListType, isNamedType, isRequiredArgument, isRequiredInputField } from '../type/definition'; import keyMap from '../jsutils/keyMap'; export var BreakingChangeType = { FIELD_CHANGED_KIND: 'FIELD_CHANGED_KIND', FIELD_REMOVED: 'FIELD_REMOVED', TYPE_CHANGED_KIND: 'TYPE_CHANGED_KIND', TYPE_REMOVED: 'TYPE_REMOVED', TYPE_REMOVED_FROM_UNION: 'TYPE_REMOVED_FROM_UNION', VALUE_REMOVED_FROM_ENUM: 'VALUE_REMOVED_FROM_ENUM', ARG_REMOVED: 'ARG_REMOVED', ARG_CHANGED_KIND: 'ARG_CHANGED_KIND', REQUIRED_ARG_ADDED: 'REQUIRED_ARG_ADDED', REQUIRED_INPUT_FIELD_ADDED: 'REQUIRED_INPUT_FIELD_ADDED', INTERFACE_REMOVED_FROM_OBJECT: 'INTERFACE_REMOVED_FROM_OBJECT', DIRECTIVE_REMOVED: 'DIRECTIVE_REMOVED', DIRECTIVE_ARG_REMOVED: 'DIRECTIVE_ARG_REMOVED', DIRECTIVE_LOCATION_REMOVED: 'DIRECTIVE_LOCATION_REMOVED', REQUIRED_DIRECTIVE_ARG_ADDED: 'REQUIRED_DIRECTIVE_ARG_ADDED' }; export var DangerousChangeType = { ARG_DEFAULT_VALUE_CHANGE: 'ARG_DEFAULT_VALUE_CHANGE', VALUE_ADDED_TO_ENUM: 'VALUE_ADDED_TO_ENUM', INTERFACE_ADDED_TO_OBJECT: 'INTERFACE_ADDED_TO_OBJECT', TYPE_ADDED_TO_UNION: 'TYPE_ADDED_TO_UNION', OPTIONAL_INPUT_FIELD_ADDED: 'OPTIONAL_INPUT_FIELD_ADDED', OPTIONAL_ARG_ADDED: 'OPTIONAL_ARG_ADDED' }; /** * Given two schemas, returns an Array containing descriptions of all the types * of breaking changes covered by the other functions down below. */ export function findBreakingChanges(oldSchema, newSchema) { 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)); } /** * Given two schemas, returns an Array containing descriptions of all the types * of potentially dangerous changes covered by the other functions down below. */ export function findDangerousChanges(oldSchema, newSchema) { return [].concat(findArgChanges(oldSchema, newSchema).dangerousChanges, findValuesAddedToEnums(oldSchema, newSchema), findInterfacesAddedToObjectTypes(oldSchema, newSchema), findTypesAddedToUnions(oldSchema, newSchema), findFieldsThatChangedTypeOnInputObjectTypes(oldSchema, newSchema).dangerousChanges); } /** * Given two schemas, returns an Array containing descriptions of any breaking * changes in the newSchema related to removing an entire type. */ function findRemovedTypes(oldSchema, newSchema) { var oldTypeMap = oldSchema.getTypeMap(); var newTypeMap = newSchema.getTypeMap(); var breakingChanges = []; for (var _i = 0, _Object$keys = Object.keys(oldTypeMap); _i < _Object$keys.length; _i++) { var typeName = _Object$keys[_i]; if (!newTypeMap[typeName]) { breakingChanges.push({ type: BreakingChangeType.TYPE_REMOVED, description: "".concat(typeName, " was removed.") }); } } return breakingChanges; } /** * Given two schemas, returns an Array containing descriptions of any breaking * changes in the newSchema related to changing the type of a type. */ function findTypesThatChangedKind(oldSchema, newSchema) { var oldTypeMap = oldSchema.getTypeMap(); var newTypeMap = newSchema.getTypeMap(); var breakingChanges = []; for (var _i2 = 0, _Object$keys2 = Object.keys(oldTypeMap); _i2 < _Object$keys2.length; _i2++) { var typeName = _Object$keys2[_i2]; if (!newTypeMap[typeName]) { continue; } var oldType = oldTypeMap[typeName]; var newType = newTypeMap[typeName]; if (oldType.constructor !== newType.constructor) { breakingChanges.push({ type: BreakingChangeType.TYPE_CHANGED_KIND, description: "".concat(typeName, " changed from ") + "".concat(typeKindName(oldType), " to ").concat(typeKindName(newType), ".") }); } } return breakingChanges; } /** * Given two schemas, returns an Array containing descriptions of any * breaking or dangerous changes in the newSchema related to arguments * (such as removal or change of type of an argument, or a change in an * argument's default value). */ function findArgChanges(oldSchema, newSchema) { var oldTypeMap = oldSchema.getTypeMap(); var newTypeMap = newSchema.getTypeMap(); var breakingChanges = []; var dangerousChanges = []; for (var _i3 = 0, _Object$keys3 = Object.keys(oldTypeMap); _i3 < _Object$keys3.length; _i3++) { var typeName = _Object$keys3[_i3]; var oldType = oldTypeMap[typeName]; var newType = newTypeMap[typeName]; if (!(isObjectType(oldType) || isInterfaceType(oldType)) || !(isObjectType(newType) || isInterfaceType(newType)) || newType.constructor !== oldType.constructor) { continue; } var oldTypeFields = oldType.getFields(); var newTypeFields = newType.getFields(); for (var _i4 = 0, _Object$keys4 = Object.keys(oldTypeFields); _i4 < _Object$keys4.length; _i4++) { var fieldName = _Object$keys4[_i4]; if (!newTypeFields[fieldName]) { continue; } var _iteratorNormalCompletion = true; var _didIteratorError = false; var _iteratorError = undefined; try { var _loop = function _loop() { var oldArgDef = _step.value; var newArgs = newTypeFields[fieldName].args; var newArgDef = find(newArgs, function (arg) { return arg.name === oldArgDef.name; }); // Arg not present if (!newArgDef) { breakingChanges.push({ type: BreakingChangeType.ARG_REMOVED, description: "".concat(oldType.name, ".").concat(fieldName, " arg ") + "".concat(oldArgDef.name, " was removed") }); } else { var isSafe = isChangeSafeForInputObjectFieldOrFieldArg(oldArgDef.type, newArgDef.type); if (!isSafe) { breakingChanges.push({ type: BreakingChangeType.ARG_CHANGED_KIND, description: "".concat(oldType.name, ".").concat(fieldName, " arg ") + "".concat(oldArgDef.name, " has changed type from ") + "".concat(oldArgDef.type.toString(), " to ").concat(newArgDef.type.toString()) }); } else if (oldArgDef.defaultValue !== undefined && oldArgDef.defaultValue !== newArgDef.defaultValue) { dangerousChanges.push({ type: DangerousChangeType.ARG_DEFAULT_VALUE_CHANGE, description: "".concat(oldType.name, ".").concat(fieldName, " arg ") + "".concat(oldArgDef.name, " has changed defaultValue") }); } } }; for (var _iterator = oldTypeFields[fieldName].args[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) { _loop(); } // Check if arg was added to the field } catch (err) { _didIteratorError = true; _iteratorError = err; } finally { try { if (!_iteratorNormalCompletion && _iterator.return != null) { _iterator.return(); } } finally { if (_didIteratorError) { throw _iteratorError; } } } var _iteratorNormalCompletion2 = true; var _didIteratorError2 = false; var _iteratorError2 = undefined; try { var _loop2 = function _loop2() { var newArgDef = _step2.value; var oldArgs = oldTypeFields[fieldName].args; var oldArgDef = find(oldArgs, function (arg) { return arg.name === newArgDef.name; }); if (!oldArgDef) { var argName = newArgDef.name; if (isRequiredArgument(newArgDef)) { breakingChanges.push({ type: BreakingChangeType.REQUIRED_ARG_ADDED, description: "A required arg ".concat(argName, " on ") + "".concat(typeName, ".").concat(fieldName, " was added") }); } else { dangerousChanges.push({ type: DangerousChangeType.OPTIONAL_ARG_ADDED, description: "An optional arg ".concat(argName, " on ") + "".concat(typeName, ".").concat(fieldName, " was added") }); } } }; for (var _iterator2 = newTypeFields[fieldName].args[Symbol.iterator](), _step2; !(_iteratorNormalCompletion2 = (_step2 = _iterator2.next()).done); _iteratorNormalCompletion2 = true) { _loop2(); } } catch (err) { _didIteratorError2 = true; _iteratorError2 = err; } finally { try { if (!_iteratorNormalCompletion2 && _iterator2.return != null) { _iterator2.return(); } } finally { if (_didIteratorError2) { throw _iteratorError2; } } } } } return { breakingChanges: breakingChanges, dangerousChanges: dangerousChanges }; } function typeKindName(type) { if (isScalarType(type)) { return 'a Scalar type'; } if (isObjectType(type)) { return 'an Object type'; } if (isInterfaceType(type)) { return 'an Interface type'; } if (isUnionType(type)) { return 'a Union type'; } if (isEnumType(type)) { return 'an Enum type'; } if (isInputObjectType(type)) { return 'an Input type'; } // Not reachable. All possible named types have been considered. /* istanbul ignore next */ throw new TypeError("Unexpected type: ".concat(inspect(type), ".")); } function findFieldsThatChangedTypeOnObjectOrInterfaceTypes(oldSchema, newSchema) { var oldTypeMap = oldSchema.getTypeMap(); var newTypeMap = newSchema.getTypeMap(); var breakingChanges = []; for (var _i5 = 0, _Object$keys5 = Object.keys(oldTypeMap); _i5 < _Object$keys5.length; _i5++) { var typeName = _Object$keys5[_i5]; var oldType = oldTypeMap[typeName]; var newType = newTypeMap[typeName]; if (!(isObjectType(oldType) || isInterfaceType(oldType)) || !(isObjectType(newType) || isInterfaceType(newType)) || newType.constructor !== oldType.constructor) { continue; } var oldTypeFieldsDef = oldType.getFields(); var newTypeFieldsDef = newType.getFields(); for (var _i6 = 0, _Object$keys6 = Object.keys(oldTypeFieldsDef); _i6 < _Object$keys6.length; _i6++) { var fieldName = _Object$keys6[_i6]; // Check if the field is missing on the type in the new schema. if (!(fieldName in newTypeFieldsDef)) { breakingChanges.push({ type: BreakingChangeType.FIELD_REMOVED, description: "".concat(typeName, ".").concat(fieldName, " was removed.") }); } else { var oldFieldType = oldTypeFieldsDef[fieldName].type; var newFieldType = newTypeFieldsDef[fieldName].type; var isSafe = isChangeSafeForObjectOrInterfaceField(oldFieldType, newFieldType); if (!isSafe) { var oldFieldTypeString = isNamedType(oldFieldType) ? oldFieldType.name : oldFieldType.toString(); var newFieldTypeString = isNamedType(newFieldType) ? newFieldType.name : newFieldType.toString(); breakingChanges.push({ type: BreakingChangeType.FIELD_CHANGED_KIND, description: "".concat(typeName, ".").concat(fieldName, " changed type from ") + "".concat(oldFieldTypeString, " to ").concat(newFieldTypeString, ".") }); } } } } return breakingChanges; } function findFieldsThatChangedTypeOnInputObjectTypes(oldSchema, newSchema) { var oldTypeMap = oldSchema.getTypeMap(); var newTypeMap = newSchema.getTypeMap(); var breakingChanges = []; var dangerousChanges = []; for (var _i7 = 0, _Object$keys7 = Object.keys(oldTypeMap); _i7 < _Object$keys7.length; _i7++) { var typeName = _Object$keys7[_i7]; var oldType = oldTypeMap[typeName]; var newType = newTypeMap[typeName]; if (!isInputObjectType(oldType) || !isInputObjectType(newType)) { continue; } var oldTypeFieldsDef = oldType.getFields(); var newTypeFieldsDef = newType.getFields(); for (var _i8 = 0, _Object$keys8 = Object.keys(oldTypeFieldsDef); _i8 < _Object$keys8.length; _i8++) { var fieldName = _Object$keys8[_i8]; // Check if the field is missing on the type in the new schema. if (!(fieldName in newTypeFieldsDef)) { breakingChanges.push({ type: BreakingChangeType.FIELD_REMOVED, description: "".concat(typeName, ".").concat(fieldName, " was removed.") }); } else { var oldFieldType = oldTypeFieldsDef[fieldName].type; var newFieldType = newTypeFieldsDef[fieldName].type; var isSafe = isChangeSafeForInputObjectFieldOrFieldArg(oldFieldType, newFieldType); if (!isSafe) { var oldFieldTypeString = isNamedType(oldFieldType) ? oldFieldType.name : oldFieldType.toString(); var newFieldTypeString = isNamedType(newFieldType) ? newFieldType.name : newFieldType.toString(); breakingChanges.push({ type: BreakingChangeType.FIELD_CHANGED_KIND, description: "".concat(typeName, ".").concat(fieldName, " changed type from ") + "".concat(oldFieldTypeString, " to ").concat(newFieldTypeString, ".") }); } } } // Check if a field was added to the input object type for (var _i9 = 0, _Object$keys9 = Object.keys(newTypeFieldsDef); _i9 < _Object$keys9.length; _i9++) { var _fieldName = _Object$keys9[_i9]; if (!(_fieldName in oldTypeFieldsDef)) { if (isRequiredInputField(newTypeFieldsDef[_fieldName])) { breakingChanges.push({ type: BreakingChangeType.REQUIRED_INPUT_FIELD_ADDED, description: "A required field ".concat(_fieldName, " on ") + "input type ".concat(typeName, " was added.") }); } else { dangerousChanges.push({ type: DangerousChangeType.OPTIONAL_INPUT_FIELD_ADDED, description: "An optional field ".concat(_fieldName, " on ") + "input type ".concat(typeName, " was added.") }); } } } } return { breakingChanges: breakingChanges, dangerousChanges: dangerousChanges }; } function isChangeSafeForObjectOrInterfaceField(oldType, newType) { if (isListType(oldType)) { return (// if they're both lists, make sure the underlying types are compatible isListType(newType) && isChangeSafeForObjectOrInterfaceField(oldType.ofType, newType.ofType) || // moving from nullable to non-null of the same underlying type is safe isNonNullType(newType) && isChangeSafeForObjectOrInterfaceField(oldType, newType.ofType) ); } if (isNonNullType(oldType)) { // if they're both non-null, make sure the underlying types are compatible return isNonNullType(newType) && isChangeSafeForObjectOrInterfaceField(oldType.ofType, newType.ofType); } return (// if they're both named types, see if their names are equivalent isNamedType(newType) && oldType.name === newType.name || // moving from nullable to non-null of the same underlying type is safe isNonNullType(newType) && isChangeSafeForObjectOrInterfaceField(oldType, newType.ofType) ); } function isChangeSafeForInputObjectFieldOrFieldArg(oldType, newType) { if (isListType(oldType)) { // if they're both lists, make sure the underlying types are compatible return isListType(newType) && isChangeSafeForInputObjectFieldOrFieldArg(oldType.ofType, newType.ofType); } if (isNonNullType(oldType)) { return (// if they're both non-null, make sure the underlying types are // compatible isNonNullType(newType) && isChangeSafeForInputObjectFieldOrFieldArg(oldType.ofType, newType.ofType) || // moving from non-null to nullable of the same underlying type is safe !isNonNullType(newType) && isChangeSafeForInputObjectFieldOrFieldArg(oldType.ofType, newType) ); } // if they're both named types, see if their names are equivalent return isNamedType(newType) && oldType.name === newType.name; } /** * Given two schemas, returns an Array containing descriptions of any breaking * changes in the newSchema related to removing types from a union type. */ function findTypesRemovedFromUnions(oldSchema, newSchema) { var oldTypeMap = oldSchema.getTypeMap(); var newTypeMap = newSchema.getTypeMap(); var typesRemovedFromUnion = []; for (var _i10 = 0, _Object$keys10 = Object.keys(oldTypeMap); _i10 < _Object$keys10.length; _i10++) { var typeName = _Object$keys10[_i10]; var oldType = oldTypeMap[typeName]; var newType = newTypeMap[typeName]; if (!isUnionType(oldType) || !isUnionType(newType)) { continue; } var typeNamesInNewUnion = Object.create(null); var _iteratorNormalCompletion3 = true; var _didIteratorError3 = false; var _iteratorError3 = undefined; try { for (var _iterator3 = newType.getTypes()[Symbol.iterator](), _step3; !(_iteratorNormalCompletion3 = (_step3 = _iterator3.next()).done); _iteratorNormalCompletion3 = true) { var type = _step3.value; typeNamesInNewUnion[type.name] = true; } } catch (err) { _didIteratorError3 = true; _iteratorError3 = err; } finally { try { if (!_iteratorNormalCompletion3 && _iterator3.return != null) { _iterator3.return(); } } finally { if (_didIteratorError3) { throw _iteratorError3; } } } var _iteratorNormalCompletion4 = true; var _didIteratorError4 = false; var _iteratorError4 = undefined; try { for (var _iterator4 = oldType.getTypes()[Symbol.iterator](), _step4; !(_iteratorNormalCompletion4 = (_step4 = _iterator4.next()).done); _iteratorNormalCompletion4 = true) { var _type = _step4.value; if (!typeNamesInNewUnion[_type.name]) { typesRemovedFromUnion.push({ type: BreakingChangeType.TYPE_REMOVED_FROM_UNION, description: "".concat(_type.name, " was removed from union type ").concat(typeName, ".") }); } } } catch (err) { _didIteratorError4 = true; _iteratorError4 = err; } finally { try { if (!_iteratorNormalCompletion4 && _iterator4.return != null) { _iterator4.return(); } } finally { if (_didIteratorError4) { throw _iteratorError4; } } } } return typesRemovedFromUnion; } /** * Given two schemas, returns an Array containing descriptions of any dangerous * changes in the newSchema related to adding types to a union type. */ function findTypesAddedToUnions(oldSchema, newSchema) { var oldTypeMap = oldSchema.getTypeMap(); var newTypeMap = newSchema.getTypeMap(); var typesAddedToUnion = []; for (var _i11 = 0, _Object$keys11 = Object.keys(newTypeMap); _i11 < _Object$keys11.length; _i11++) { var typeName = _Object$keys11[_i11]; var oldType = oldTypeMap[typeName]; var newType = newTypeMap[typeName]; if (!isUnionType(oldType) || !isUnionType(newType)) { continue; } var typeNamesInOldUnion = Object.create(null); var _iteratorNormalCompletion5 = true; var _didIteratorError5 = false; var _iteratorError5 = undefined; try { for (var _iterator5 = oldType.getTypes()[Symbol.iterator](), _step5; !(_iteratorNormalCompletion5 = (_step5 = _iterator5.next()).done); _iteratorNormalCompletion5 = true) { var type = _step5.value; typeNamesInOldUnion[type.name] = true; } } catch (err) { _didIteratorError5 = true; _iteratorError5 = err; } finally { try { if (!_iteratorNormalCompletion5 && _iterator5.return != null) { _iterator5.return(); } } finally { if (_didIteratorError5) { throw _iteratorError5; } } } var _iteratorNormalCompletion6 = true; var _didIteratorError6 = false; var _iteratorError6 = undefined; try { for (var _iterator6 = newType.getTypes()[Symbol.iterator](), _step6; !(_iteratorNormalCompletion6 = (_step6 = _iterator6.next()).done); _iteratorNormalCompletion6 = true) { var _type2 = _step6.value; if (!typeNamesInOldUnion[_type2.name]) { typesAddedToUnion.push({ type: DangerousChangeType.TYPE_ADDED_TO_UNION, description: "".concat(_type2.name, " was added to union type ").concat(typeName, ".") }); } } } catch (err) { _didIteratorError6 = true; _iteratorError6 = err; } finally { try { if (!_iteratorNormalCompletion6 && _iterator6.return != null) { _iterator6.return(); } } finally { if (_didIteratorError6) { throw _iteratorError6; } } } } return typesAddedToUnion; } /** * Given two schemas, returns an Array containing descriptions of any breaking * changes in the newSchema related to removing values from an enum type. */ function findValuesRemovedFromEnums(oldSchema, newSchema) { var oldTypeMap = oldSchema.getTypeMap(); var newTypeMap = newSchema.getTypeMap(); var valuesRemovedFromEnums = []; for (var _i12 = 0, _Object$keys12 = Object.keys(oldTypeMap); _i12 < _Object$keys12.length; _i12++) { var typeName = _Object$keys12[_i12]; var oldType = oldTypeMap[typeName]; var newType = newTypeMap[typeName]; if (!isEnumType(oldType) || !isEnumType(newType)) { continue; } var valuesInNewEnum = Object.create(null); var _iteratorNormalCompletion7 = true; var _didIteratorError7 = false; var _iteratorError7 = undefined; try { for (var _iterator7 = newType.getValues()[Symbol.iterator](), _step7; !(_iteratorNormalCompletion7 = (_step7 = _iterator7.next()).done); _iteratorNormalCompletion7 = true) { var value = _step7.value; valuesInNewEnum[value.name] = true; } } catch (err) { _didIteratorError7 = true; _iteratorError7 = err; } finally { try { if (!_iteratorNormalCompletion7 && _iterator7.return != null) { _iterator7.return(); } } finally { if (_didIteratorError7) { throw _iteratorError7; } } } var _iteratorNormalCompletion8 = true; var _didIteratorError8 = false; var _iteratorError8 = undefined; try { for (var _iterator8 = oldType.getValues()[Symbol.iterator](), _step8; !(_iteratorNormalCompletion8 = (_step8 = _iterator8.next()).done); _iteratorNormalCompletion8 = true) { var _value = _step8.value; if (!valuesInNewEnum[_value.name]) { valuesRemovedFromEnums.push({ type: BreakingChangeType.VALUE_REMOVED_FROM_ENUM, description: "".concat(_value.name, " was removed from enum type ").concat(typeName, ".") }); } } } catch (err) { _didIteratorError8 = true; _iteratorError8 = err; } finally { try { if (!_iteratorNormalCompletion8 && _iterator8.return != null) { _iterator8.return(); } } finally { if (_didIteratorError8) { throw _iteratorError8; } } } } return valuesRemovedFromEnums; } /** * Given two schemas, returns an Array containing descriptions of any dangerous * changes in the newSchema related to adding values to an enum type. */ function findValuesAddedToEnums(oldSchema, newSchema) { var oldTypeMap = oldSchema.getTypeMap(); var newTypeMap = newSchema.getTypeMap(); var valuesAddedToEnums = []; for (var _i13 = 0, _Object$keys13 = Object.keys(oldTypeMap); _i13 < _Object$keys13.length; _i13++) { var typeName = _Object$keys13[_i13]; var oldType = oldTypeMap[typeName]; var newType = newTypeMap[typeName]; if (!isEnumType(oldType) || !isEnumType(newType)) { continue; } var valuesInOldEnum = Object.create(null); var _iteratorNormalCompletion9 = true; var _didIteratorError9 = false; var _iteratorError9 = undefined; try { for (var _iterator9 = oldType.getValues()[Symbol.iterator](), _step9; !(_iteratorNormalCompletion9 = (_step9 = _iterator9.next()).done); _iteratorNormalCompletion9 = true) { var value = _step9.value; valuesInOldEnum[value.name] = true; } } catch (err) { _didIteratorError9 = true; _iteratorError9 = err; } finally { try { if (!_iteratorNormalCompletion9 && _iterator9.return != null) { _iterator9.return(); } } finally { if (_didIteratorError9) { throw _iteratorError9; } } } var _iteratorNormalCompletion10 = true; var _didIteratorError10 = false; var _iteratorError10 = undefined; try { for (var _iterator10 = newType.getValues()[Symbol.iterator](), _step10; !(_iteratorNormalCompletion10 = (_step10 = _iterator10.next()).done); _iteratorNormalCompletion10 = true) { var _value2 = _step10.value; if (!valuesInOldEnum[_value2.name]) { valuesAddedToEnums.push({ type: DangerousChangeType.VALUE_ADDED_TO_ENUM, description: "".concat(_value2.name, " was added to enum type ").concat(typeName, ".") }); } } } catch (err) { _didIteratorError10 = true; _iteratorError10 = err; } finally { try { if (!_iteratorNormalCompletion10 && _iterator10.return != null) { _iterator10.return(); } } finally { if (_didIteratorError10) { throw _iteratorError10; } } } } return valuesAddedToEnums; } function findInterfacesRemovedFromObjectTypes(oldSchema, newSchema) { var oldTypeMap = oldSchema.getTypeMap(); var newTypeMap = newSchema.getTypeMap(); var breakingChanges = []; for (var _i14 = 0, _Object$keys14 = Object.keys(oldTypeMap); _i14 < _Object$keys14.length; _i14++) { var typeName = _Object$keys14[_i14]; var oldType = oldTypeMap[typeName]; var newType = newTypeMap[typeName]; if (!isObjectType(oldType) || !isObjectType(newType)) { continue; } var oldInterfaces = oldType.getInterfaces(); var newInterfaces = newType.getInterfaces(); var _iteratorNormalCompletion11 = true; var _didIteratorError11 = false; var _iteratorError11 = undefined; try { var _loop3 = function _loop3() { var oldInterface = _step11.value; if (!newInterfaces.some(function (int) { return int.name === oldInterface.name; })) { breakingChanges.push({ type: BreakingChangeType.INTERFACE_REMOVED_FROM_OBJECT, description: "".concat(typeName, " no longer implements interface ") + "".concat(oldInterface.name, ".") }); } }; for (var _iterator11 = oldInterfaces[Symbol.iterator](), _step11; !(_iteratorNormalCompletion11 = (_step11 = _iterator11.next()).done); _iteratorNormalCompletion11 = true) { _loop3(); } } catch (err) { _didIteratorError11 = true; _iteratorError11 = err; } finally { try { if (!_iteratorNormalCompletion11 && _iterator11.return != null) { _iterator11.return(); } } finally { if (_didIteratorError11) { throw _iteratorError11; } } } } return breakingChanges; } function findInterfacesAddedToObjectTypes(oldSchema, newSchema) { var oldTypeMap = oldSchema.getTypeMap(); var newTypeMap = newSchema.getTypeMap(); var interfacesAddedToObjectTypes = []; for (var _i15 = 0, _Object$keys15 = Object.keys(newTypeMap); _i15 < _Object$keys15.length; _i15++) { var typeName = _Object$keys15[_i15]; var oldType = oldTypeMap[typeName]; var newType = newTypeMap[typeName]; if (!isObjectType(oldType) || !isObjectType(newType)) { continue; } var oldInterfaces = oldType.getInterfaces(); var newInterfaces = newType.getInterfaces(); var _iteratorNormalCompletion12 = true; var _didIteratorError12 = false; var _iteratorError12 = undefined; try { var _loop4 = function _loop4() { var newInterface = _step12.value; if (!oldInterfaces.some(function (int) { return int.name === newInterface.name; })) { interfacesAddedToObjectTypes.push({ type: DangerousChangeType.INTERFACE_ADDED_TO_OBJECT, description: "".concat(newInterface.name, " added to interfaces implemented ") + "by ".concat(typeName, ".") }); } }; for (var _iterator12 = newInterfaces[Symbol.iterator](), _step12; !(_iteratorNormalCompletion12 = (_step12 = _iterator12.next()).done); _iteratorNormalCompletion12 = true) { _loop4(); } } catch (err) { _didIteratorError12 = true; _iteratorError12 = err; } finally { try { if (!_iteratorNormalCompletion12 && _iterator12.return != null) { _iterator12.return(); } } finally { if (_didIteratorError12) { throw _iteratorError12; } } } } return interfacesAddedToObjectTypes; } function findRemovedDirectives(oldSchema, newSchema) { var removedDirectives = []; var newSchemaDirectiveMap = getDirectiveMapForSchema(newSchema); var _iteratorNormalCompletion13 = true; var _didIteratorError13 = false; var _iteratorError13 = undefined; try { for (var _iterator13 = oldSchema.getDirectives()[Symbol.iterator](), _step13; !(_iteratorNormalCompletion13 = (_step13 = _iterator13.next()).done); _iteratorNormalCompletion13 = true) { var directive = _step13.value; if (!newSchemaDirectiveMap[directive.name]) { removedDirectives.push({ type: BreakingChangeType.DIRECTIVE_REMOVED, description: "".concat(directive.name, " was removed") }); } } } catch (err) { _didIteratorError13 = true; _iteratorError13 = err; } finally { try { if (!_iteratorNormalCompletion13 && _iterator13.return != null) { _iterator13.return(); } } finally { if (_didIteratorError13) { throw _iteratorError13; } } } return removedDirectives; } function findRemovedArgsForDirective(oldDirective, newDirective) { var removedArgs = []; var newArgMap = getArgumentMapForDirective(newDirective); var _iteratorNormalCompletion14 = true; var _didIteratorError14 = false; var _iteratorError14 = undefined; try { for (var _iterator14 = oldDirective.args[Symbol.iterator](), _step14; !(_iteratorNormalCompletion14 = (_step14 = _iterator14.next()).done); _iteratorNormalCompletion14 = true) { var arg = _step14.value; if (!newArgMap[arg.name]) { removedArgs.push(arg); } } } catch (err) { _didIteratorError14 = true; _iteratorError14 = err; } finally { try { if (!_iteratorNormalCompletion14 && _iterator14.return != null) { _iterator14.return(); } } finally { if (_didIteratorError14) { throw _iteratorError14; } } } return removedArgs; } function findRemovedDirectiveArgs(oldSchema, newSchema) { var removedDirectiveArgs = []; var oldSchemaDirectiveMap = getDirectiveMapForSchema(oldSchema); var _iteratorNormalCompletion15 = true; var _didIteratorError15 = false; var _iteratorError15 = undefined; try { for (var _iterator15 = newSchema.getDirectives()[Symbol.iterator](), _step15; !(_iteratorNormalCompletion15 = (_step15 = _iterator15.next()).done); _iteratorNormalCompletion15 = true) { var newDirective = _step15.value; var oldDirective = oldSchemaDirectiveMap[newDirective.name]; if (!oldDirective) { continue; } var _iteratorNormalCompletion16 = true; var _didIteratorError16 = false; var _iteratorError16 = undefined; try { for (var _iterator16 = findRemovedArgsForDirective(oldDirective, newDirective)[Symbol.iterator](), _step16; !(_iteratorNormalCompletion16 = (_step16 = _iterator16.next()).done); _iteratorNormalCompletion16 = true) { var arg = _step16.value; removedDirectiveArgs.push({ type: BreakingChangeType.DIRECTIVE_ARG_REMOVED, description: "".concat(arg.name, " was removed from ").concat(newDirective.name) }); } } catch (err) { _didIteratorError16 = true; _iteratorError16 = err; } finally { try { if (!_iteratorNormalCompletion16 && _iterator16.return != null) { _iterator16.return(); } } finally { if (_didIteratorError16) { throw _iteratorError16; } } } } } catch (err) { _didIteratorError15 = true; _iteratorError15 = err; } finally { try { if (!_iteratorNormalCompletion15 && _iterator15.return != null) { _iterator15.return(); } } finally { if (_didIteratorError15) { throw _iteratorError15; } } } return removedDirectiveArgs; } function findAddedArgsForDirective(oldDirective, newDirective) { var addedArgs = []; var oldArgMap = getArgumentMapForDirective(oldDirective); var _iteratorNormalCompletion17 = true; var _didIteratorError17 = false; var _iteratorError17 = undefined; try { for (var _iterator17 = newDirective.args[Symbol.iterator](), _step17; !(_iteratorNormalCompletion17 = (_step17 = _iterator17.next()).done); _iteratorNormalCompletion17 = true) { var arg = _step17.value; if (!oldArgMap[arg.name]) { addedArgs.push(arg); } } } catch (err) { _didIteratorError17 = true; _iteratorError17 = err; } finally { try { if (!_iteratorNormalCompletion17 && _iterator17.return != null) { _iterator17.return(); } } finally { if (_didIteratorError17) { throw _iteratorError17; } } } return addedArgs; } function findAddedNonNullDirectiveArgs(oldSchema, newSchema) { var addedNonNullableArgs = []; var oldSchemaDirectiveMap = getDirectiveMapForSchema(oldSchema); var _iteratorNormalCompletion18 = true; var _didIteratorError18 = false; var _iteratorError18 = undefined; try { for (var _iterator18 = newSchema.getDirectives()[Symbol.iterator](), _step18; !(_iteratorNormalCompletion18 = (_step18 = _iterator18.next()).done); _iteratorNormalCompletion18 = true) { var newDirective = _step18.value; var oldDirective = oldSchemaDirectiveMap[newDirective.name]; if (!oldDirective) { continue; } var _iteratorNormalCompletion19 = true; var _didIteratorError19 = false; var _iteratorError19 = undefined; try { for (var _iterator19 = findAddedArgsForDirective(oldDirective, newDirective)[Symbol.iterator](), _step19; !(_iteratorNormalCompletion19 = (_step19 = _iterator19.next()).done); _iteratorNormalCompletion19 = true) { var arg = _step19.value; if (isRequiredArgument(arg)) { addedNonNullableArgs.push({ type: BreakingChangeType.REQUIRED_DIRECTIVE_ARG_ADDED, description: "A required arg ".concat(arg.name, " on directive ") + "".concat(newDirective.name, " was added") }); } } } catch (err) { _didIteratorError19 = true; _iteratorError19 = err; } finally { try { if (!_iteratorNormalCompletion19 && _iterator19.return != null) { _iterator19.return(); } } finally { if (_didIteratorError19) { throw _iteratorError19; } } } } } catch (err) { _didIteratorError18 = true; _iteratorError18 = err; } finally { try { if (!_iteratorNormalCompletion18 && _iterator18.return != null) { _iterator18.return(); } } finally { if (_didIteratorError18) { throw _iteratorError18; } } } return addedNonNullableArgs; } function findRemovedLocationsForDirective(oldDirective, newDirective) { var removedLocations = []; var newLocationSet = new Set(newDirective.locations); var _iteratorNormalCompletion20 = true; var _didIteratorError20 = false; var _iteratorError20 = undefined; try { for (var _iterator20 = oldDirective.locations[Symbol.iterator](), _step20; !(_iteratorNormalCompletion20 = (_step20 = _iterator20.next()).done); _iteratorNormalCompletion20 = true) { var oldLocation = _step20.value; if (!newLocationSet.has(oldLocation)) { removedLocations.push(oldLocation); } } } catch (err) { _didIteratorError20 = true; _iteratorError20 = err; } finally { try { if (!_iteratorNormalCompletion20 && _iterator20.return != null) { _iterator20.return(); } } finally { if (_didIteratorError20) { throw _iteratorError20; } } } return removedLocations; } function findRemovedDirectiveLocations(oldSchema, newSchema) { var removedLocations = []; var oldSchemaDirectiveMap = getDirectiveMapForSchema(oldSchema); var _iteratorNormalCompletion21 = true; var _didIteratorError21 = false; var _iteratorError21 = undefined; try { for (var _iterator21 = newSchema.getDirectives()[Symbol.iterator](), _step21; !(_iteratorNormalCompletion21 = (_step21 = _iterator21.next()).done); _iteratorNormalCompletion21 = true) { var newDirective = _step21.value; var oldDirective = oldSchemaDirectiveMap[newDirective.name]; if (!oldDirective) { continue; } var _iteratorNormalCompletion22 = true; var _didIteratorError22 = false; var _iteratorError22 = undefined; try { for (var _iterator22 = findRemovedLocationsForDirective(oldDirective, newDirective)[Symbol.iterator](), _step22; !(_iteratorNormalCompletion22 = (_step22 = _iterator22.next()).done); _iteratorNormalCompletion22 = true) { var location = _step22.value; removedLocations.push({ type: BreakingChangeType.DIRECTIVE_LOCATION_REMOVED, description: "".concat(location, " was removed from ").concat(newDirective.name) }); } } catch (err) { _didIteratorError22 = true; _iteratorError22 = err; } finally { try { if (!_iteratorNormalCompletion22 && _iterator22.return != null) { _iterator22.return(); } } finally { if (_didIteratorError22) { throw _iteratorError22; } } } } } catch (err) { _didIteratorError21 = true; _iteratorError21 = err; } finally { try { if (!_iteratorNormalCompletion21 && _iterator21.return != null) { _iterator21.return(); } } finally { if (_didIteratorError21) { throw _iteratorError21; } } } return removedLocations; } function getDirectiveMapForSchema(schema) { return keyMap(schema.getDirectives(), function (dir) { return dir.name; }); } function getArgumentMapForDirective(directive) { return keyMap(directive.args, function (arg) { return arg.name; }); }