diff --git a/src/index.js b/src/index.js index 46133b23db..5a2c79eb96 100644 --- a/src/index.js +++ b/src/index.js @@ -403,8 +403,7 @@ export { // Compares two GraphQLSchemas and detects breaking changes. BreakingChangeType, DangerousChangeType, - findBreakingChanges, - findDangerousChanges, + findSchemaChanges, // Report all deprecated usage within a GraphQL document. findDeprecatedUsages, } from './utilities'; @@ -433,6 +432,5 @@ export type { IntrospectionEnumValue, IntrospectionDirective, BuildSchemaOptions, - BreakingChange, - DangerousChange, + SchemaChange, } from './utilities'; diff --git a/src/utilities/__tests__/findBreakingChanges-test.js b/src/utilities/__tests__/findBreakingChanges-test.js index ddb0cf9c1a..5eaafdba5b 100644 --- a/src/utilities/__tests__/findBreakingChanges-test.js +++ b/src/utilities/__tests__/findBreakingChanges-test.js @@ -14,11 +14,10 @@ import { buildSchema } from '../buildASTSchema'; import { BreakingChangeType, DangerousChangeType, - findBreakingChanges, - findDangerousChanges, + findSchemaChanges, } from '../findBreakingChanges'; -describe('findBreakingChanges', () => { +describe('findSchemaChanges', () => { it('should detect if a type was removed or not', () => { const oldSchema = buildSchema(` type Type1 @@ -28,13 +27,13 @@ describe('findBreakingChanges', () => { const newSchema = buildSchema(` type Type2 `); - expect(findBreakingChanges(oldSchema, newSchema)).to.deep.equal([ + expect(findSchemaChanges(oldSchema, newSchema)).to.deep.equal([ { type: BreakingChangeType.TYPE_REMOVED, description: 'Type1 was removed.', }, ]); - expect(findBreakingChanges(oldSchema, oldSchema)).to.deep.equal([]); + expect(findSchemaChanges(oldSchema, oldSchema)).to.deep.equal([]); }); it('should detect if a type changed its type', () => { @@ -49,7 +48,7 @@ describe('findBreakingChanges', () => { union TypeWasInterfaceBecomesUnion input TypeWasObjectBecomesInputObject `); - expect(findBreakingChanges(oldSchema, newSchema)).to.deep.equal([ + expect(findSchemaChanges(oldSchema, newSchema)).to.deep.equal([ { type: BreakingChangeType.TYPE_CHANGED_KIND, description: @@ -119,7 +118,7 @@ describe('findBreakingChanges', () => { } `); - const changes = findBreakingChanges(oldSchema, newSchema); + const changes = findSchemaChanges(oldSchema, newSchema); expect(changes).to.deep.equal([ { type: BreakingChangeType.FIELD_REMOVED, @@ -216,7 +215,7 @@ describe('findBreakingChanges', () => { } `); - expect(findBreakingChanges(oldSchema, newSchema)).to.deep.equal([ + expect(findSchemaChanges(oldSchema, newSchema)).to.deep.equal([ { type: BreakingChangeType.FIELD_REMOVED, description: 'InputType1.field2 was removed.', @@ -281,12 +280,22 @@ describe('findBreakingChanges', () => { } `); - expect(findBreakingChanges(oldSchema, newSchema)).to.deep.equal([ + expect(findSchemaChanges(oldSchema, newSchema)).to.deep.equal([ { type: BreakingChangeType.REQUIRED_INPUT_FIELD_ADDED, description: 'A required field requiredField on input type InputType1 was added.', }, + { + description: + 'An optional field optionalField1 on input type InputType1 was added.', + type: 'OPTIONAL_INPUT_FIELD_ADDED', + }, + { + description: + 'An optional field optionalField2 on input type InputType1 was added.', + type: 'OPTIONAL_INPUT_FIELD_ADDED', + }, ]); }); @@ -306,7 +315,11 @@ describe('findBreakingChanges', () => { union UnionType1 = Type1 | Type3 `); - expect(findBreakingChanges(oldSchema, newSchema)).to.deep.equal([ + expect(findSchemaChanges(oldSchema, newSchema)).to.deep.equal([ + { + description: 'Type3 was added to union type UnionType1.', + type: 'TYPE_ADDED_TO_UNION', + }, { type: BreakingChangeType.TYPE_REMOVED_FROM_UNION, description: 'Type2 was removed from union type UnionType1.', @@ -331,7 +344,11 @@ describe('findBreakingChanges', () => { } `); - expect(findBreakingChanges(oldSchema, newSchema)).to.deep.equal([ + expect(findSchemaChanges(oldSchema, newSchema)).to.deep.equal([ + { + description: 'VALUE3 was added to enum type EnumType1.', + type: 'VALUE_ADDED_TO_ENUM', + }, { type: BreakingChangeType.VALUE_REMOVED_FROM_ENUM, description: 'VALUE1 was removed from enum type EnumType1.', @@ -360,7 +377,7 @@ describe('findBreakingChanges', () => { } `); - expect(findBreakingChanges(oldSchema, newSchema)).to.deep.equal([ + expect(findSchemaChanges(oldSchema, newSchema)).to.deep.equal([ { type: BreakingChangeType.ARG_REMOVED, description: 'Interface1.field1 arg arg1 was removed.', @@ -421,7 +438,7 @@ describe('findBreakingChanges', () => { } `); - expect(findBreakingChanges(oldSchema, newSchema)).to.deep.equal([ + expect(findSchemaChanges(oldSchema, newSchema)).to.deep.equal([ { type: BreakingChangeType.ARG_CHANGED_KIND, description: @@ -503,11 +520,21 @@ describe('findBreakingChanges', () => { } `); - expect(findBreakingChanges(oldSchema, newSchema)).to.deep.equal([ + expect(findSchemaChanges(oldSchema, newSchema)).to.deep.equal([ { type: BreakingChangeType.REQUIRED_ARG_ADDED, description: 'A required arg newRequiredArg on Type1.field1 was added.', }, + { + description: + 'An optional arg newOptionalArg1 on Type1.field1 was added.', + type: 'OPTIONAL_ARG_ADDED', + }, + { + description: + 'An optional arg newOptionalArg2 on Type1.field1 was added.', + type: 'OPTIONAL_ARG_ADDED', + }, ]); }); @@ -532,7 +559,7 @@ describe('findBreakingChanges', () => { } `); - expect(findBreakingChanges(oldSchema, newSchema)).to.deep.equal([]); + expect(findSchemaChanges(oldSchema, newSchema)).to.deep.equal([]); }); it('should consider args that move away from NonNull as non-breaking', () => { @@ -548,7 +575,7 @@ describe('findBreakingChanges', () => { } `); - expect(findBreakingChanges(oldSchema, newSchema)).to.deep.equal([]); + expect(findSchemaChanges(oldSchema, newSchema)).to.deep.equal([]); }); it('should detect interfaces removed from types', () => { @@ -564,7 +591,7 @@ describe('findBreakingChanges', () => { type Type1 `); - expect(findBreakingChanges(oldSchema, newSchema)).to.deep.equal([ + expect(findSchemaChanges(oldSchema, newSchema)).to.deep.equal([ { type: BreakingChangeType.INTERFACE_REMOVED_FROM_OBJECT, description: 'Type1 no longer implements interface Interface1.', @@ -587,7 +614,7 @@ describe('findBreakingChanges', () => { type Type1 implements SecondInterface & FirstInterface `); - expect(findBreakingChanges(oldSchema, newSchema)).to.deep.equal([]); + expect(findSchemaChanges(oldSchema, newSchema)).to.deep.equal([]); }); it('should detect all breaking changes', () => { @@ -657,7 +684,7 @@ describe('findBreakingChanges', () => { } `); - expect(findBreakingChanges(oldSchema, newSchema)).to.deep.equal([ + expect(findSchemaChanges(oldSchema, newSchema)).to.deep.equal([ { type: BreakingChangeType.TYPE_REMOVED, description: 'Int was removed.', @@ -730,7 +757,7 @@ describe('findBreakingChanges', () => { directive @DirectiveThatStays on FIELD_DEFINITION `); - expect(findBreakingChanges(oldSchema, newSchema)).to.deep.equal([ + expect(findSchemaChanges(oldSchema, newSchema)).to.deep.equal([ { type: BreakingChangeType.DIRECTIVE_REMOVED, description: 'DirectiveThatIsRemoved was removed.', @@ -745,7 +772,7 @@ describe('findBreakingChanges', () => { directives: [GraphQLSkipDirective, GraphQLIncludeDirective], }); - expect(findBreakingChanges(oldSchema, newSchema)).to.deep.equal([ + expect(findSchemaChanges(oldSchema, newSchema)).to.deep.equal([ { type: BreakingChangeType.DIRECTIVE_REMOVED, description: `${GraphQLDeprecatedDirective.name} was removed.`, @@ -762,7 +789,7 @@ describe('findBreakingChanges', () => { directive @DirectiveWithArg on FIELD_DEFINITION `); - expect(findBreakingChanges(oldSchema, newSchema)).to.deep.equal([ + expect(findSchemaChanges(oldSchema, newSchema)).to.deep.equal([ { type: BreakingChangeType.DIRECTIVE_ARG_REMOVED, description: 'arg1 was removed from DirectiveWithArg.', @@ -783,7 +810,7 @@ describe('findBreakingChanges', () => { ) on FIELD_DEFINITION `); - expect(findBreakingChanges(oldSchema, newSchema)).to.deep.equal([ + expect(findSchemaChanges(oldSchema, newSchema)).to.deep.equal([ { type: BreakingChangeType.REQUIRED_DIRECTIVE_ARG_ADDED, description: @@ -801,7 +828,7 @@ describe('findBreakingChanges', () => { directive @DirectiveName on FIELD_DEFINITION `); - expect(findBreakingChanges(oldSchema, newSchema)).to.deep.equal([ + expect(findSchemaChanges(oldSchema, newSchema)).to.deep.equal([ { type: BreakingChangeType.DIRECTIVE_LOCATION_REMOVED, description: 'QUERY was removed from DirectiveName.', @@ -810,7 +837,7 @@ describe('findBreakingChanges', () => { }); }); -describe('findDangerousChanges', () => { +describe('findSchemaChanges', () => { it('should detect if a defaultValue changed on an argument', () => { const oldSDL = ` input Input1 { @@ -836,7 +863,7 @@ describe('findDangerousChanges', () => { const oldSchema = buildSchema(oldSDL); const copyOfOldSchema = buildSchema(oldSDL); - expect(findDangerousChanges(oldSchema, copyOfOldSchema)).to.deep.equal([]); + expect(findSchemaChanges(oldSchema, copyOfOldSchema)).to.deep.equal([]); const newSchema = buildSchema(` input Input1 { @@ -860,7 +887,7 @@ describe('findDangerousChanges', () => { } `); - expect(findDangerousChanges(oldSchema, newSchema)).to.deep.equal([ + expect(findSchemaChanges(oldSchema, newSchema)).to.deep.equal([ { type: DangerousChangeType.ARG_DEFAULT_VALUE_CHANGE, description: @@ -918,7 +945,7 @@ describe('findDangerousChanges', () => { } `); - expect(findDangerousChanges(oldSchema, newSchema)).to.deep.equal([]); + expect(findSchemaChanges(oldSchema, newSchema)).to.deep.equal([]); }); it('should ignore changes in field definitions order', () => { @@ -950,7 +977,7 @@ describe('findDangerousChanges', () => { } `); - expect(findDangerousChanges(oldSchema, newSchema)).to.deep.equal([]); + expect(findSchemaChanges(oldSchema, newSchema)).to.deep.equal([]); }); it('should detect if a value was added to an enum type', () => { @@ -969,7 +996,7 @@ describe('findDangerousChanges', () => { } `); - expect(findDangerousChanges(oldSchema, newSchema)).to.deep.equal([ + expect(findSchemaChanges(oldSchema, newSchema)).to.deep.equal([ { type: DangerousChangeType.VALUE_ADDED_TO_ENUM, description: 'VALUE2 was added to enum type EnumType1.', @@ -992,7 +1019,7 @@ describe('findDangerousChanges', () => { type Type1 implements OldInterface & NewInterface `); - expect(findDangerousChanges(oldSchema, newSchema)).to.deep.equal([ + expect(findSchemaChanges(oldSchema, newSchema)).to.deep.equal([ { type: DangerousChangeType.INTERFACE_ADDED_TO_OBJECT, description: 'NewInterface added to interfaces implemented by Type1.', @@ -1015,7 +1042,7 @@ describe('findDangerousChanges', () => { union UnionType1 = Type1 | Type2 `); - expect(findDangerousChanges(oldSchema, newSchema)).to.deep.equal([ + expect(findSchemaChanges(oldSchema, newSchema)).to.deep.equal([ { type: DangerousChangeType.TYPE_ADDED_TO_UNION, description: 'Type2 was added to union type UnionType1.', @@ -1037,7 +1064,7 @@ describe('findDangerousChanges', () => { } `); - expect(findDangerousChanges(oldSchema, newSchema)).to.deep.equal([ + expect(findSchemaChanges(oldSchema, newSchema)).to.deep.equal([ { type: DangerousChangeType.OPTIONAL_INPUT_FIELD_ADDED, description: @@ -1083,7 +1110,7 @@ describe('findDangerousChanges', () => { union UnionTypeThatGainsAType = TypeInUnion1 | TypeInUnion2 `); - expect(findDangerousChanges(oldSchema, newSchema)).to.deep.equal([ + expect(findSchemaChanges(oldSchema, newSchema)).to.deep.equal([ { type: DangerousChangeType.VALUE_ADDED_TO_ENUM, description: 'VALUE2 was added to enum type EnumType1.', @@ -1119,7 +1146,7 @@ describe('findDangerousChanges', () => { } `); - expect(findDangerousChanges(oldSchema, newSchema)).to.deep.equal([ + expect(findSchemaChanges(oldSchema, newSchema)).to.deep.equal([ { type: DangerousChangeType.OPTIONAL_ARG_ADDED, description: 'An optional arg arg2 on Type1.field1 was added.', diff --git a/src/utilities/findBreakingChanges.js b/src/utilities/findBreakingChanges.js index d53b107dd7..6885905c88 100644 --- a/src/utilities/findBreakingChanges.js +++ b/src/utilities/findBreakingChanges.js @@ -62,50 +62,20 @@ export const DangerousChangeType = Object.freeze({ ARG_DEFAULT_VALUE_CHANGE: 'ARG_DEFAULT_VALUE_CHANGE', }); -export type BreakingChange = { - type: $Keys, - description: string, - ... -}; - -export type DangerousChange = { - type: $Keys, +export type SchemaChange = { + type: $Keys | $Keys, description: string, ... }; /** * Given two schemas, returns an Array containing descriptions of all the types - * of breaking changes covered by the other functions down below. + * of potentially breaking and dangerous changes. */ -export function findBreakingChanges( - oldSchema: GraphQLSchema, - newSchema: GraphQLSchema, -): Array { - const breakingChanges = findSchemaChanges(oldSchema, newSchema).filter( - change => change.type in BreakingChangeType, - ); - return ((breakingChanges: any): Array); -} - -/** - * 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: GraphQLSchema, - newSchema: GraphQLSchema, -): Array { - const dangerousChanges = findSchemaChanges(oldSchema, newSchema).filter( - change => change.type in DangerousChangeType, - ); - return ((dangerousChanges: any): Array); -} - -function findSchemaChanges( +export function findSchemaChanges( oldSchema: GraphQLSchema, newSchema: GraphQLSchema, -): Array { +): Array { return [ ...findTypeChanges(oldSchema, newSchema), ...findDirectiveChanges(oldSchema, newSchema), @@ -115,7 +85,7 @@ function findSchemaChanges( function findDirectiveChanges( oldSchema: GraphQLSchema, newSchema: GraphQLSchema, -): Array { +): Array { const schemaChanges = []; const directivesDiff = diff( @@ -165,7 +135,7 @@ function findDirectiveChanges( function findTypeChanges( oldSchema: GraphQLSchema, newSchema: GraphQLSchema, -): Array { +): Array { const schemaChanges = []; const typesDiff = diff( @@ -207,7 +177,7 @@ function findTypeChanges( function findInputObjectTypeChanges( oldType: GraphQLInputObjectType, newType: GraphQLInputObjectType, -): Array { +): Array { const schemaChanges = []; const fieldsDiff = diff( objectValues(oldType.getFields()), @@ -256,7 +226,7 @@ function findInputObjectTypeChanges( function findUnionTypeChanges( oldType: GraphQLUnionType, newType: GraphQLUnionType, -): Array { +): Array { const schemaChanges = []; const possibleTypesDiff = diff(oldType.getTypes(), newType.getTypes()); @@ -280,7 +250,7 @@ function findUnionTypeChanges( function findEnumTypeChanges( oldType: GraphQLEnumType, newType: GraphQLEnumType, -): Array { +): Array { const schemaChanges = []; const valuesDiff = diff(oldType.getValues(), newType.getValues()); @@ -304,7 +274,7 @@ function findEnumTypeChanges( function findObjectTypeChanges( oldType: GraphQLObjectType, newType: GraphQLObjectType, -): Array { +): Array { const schemaChanges = findFieldChanges(oldType, newType); const interfacesDiff = diff(oldType.getInterfaces(), newType.getInterfaces()); @@ -328,7 +298,7 @@ function findObjectTypeChanges( function findFieldChanges( oldType: GraphQLObjectType | GraphQLInterfaceType, newType: GraphQLObjectType | GraphQLInterfaceType, -): Array { +): Array { const schemaChanges = []; const fieldsDiff = diff( objectValues(oldType.getFields()), @@ -366,7 +336,7 @@ function findArgChanges( oldType: GraphQLObjectType | GraphQLInterfaceType, oldField: GraphQLField, newField: GraphQLField, -): Array { +): Array { const schemaChanges = []; const argsDiff = diff(oldField.args, newField.args); diff --git a/src/utilities/index.js b/src/utilities/index.js index 02bc9382bc..7f8ae863a7 100644 --- a/src/utilities/index.js +++ b/src/utilities/index.js @@ -107,10 +107,9 @@ export { assertValidName, isValidNameError } from './assertValidName'; export { BreakingChangeType, DangerousChangeType, - findBreakingChanges, - findDangerousChanges, + findSchemaChanges, } from './findBreakingChanges'; -export type { BreakingChange, DangerousChange } from './findBreakingChanges'; +export type { SchemaChange } from './findBreakingChanges'; // Report all deprecated usage within a GraphQL document. export { findDeprecatedUsages } from './findDeprecatedUsages'; diff --git a/tstypes/index.d.ts b/tstypes/index.d.ts index b5c614bcda..fca0440caa 100644 --- a/tstypes/index.d.ts +++ b/tstypes/index.d.ts @@ -403,8 +403,7 @@ export { // Compares two GraphQLSchemas and detects breaking changes. BreakingChangeType, DangerousChangeType, - findBreakingChanges, - findDangerousChanges, + findSchemaChanges, // Report all deprecated usage within a GraphQL document. findDeprecatedUsages, } from './utilities'; @@ -433,6 +432,5 @@ export { IntrospectionEnumValue, IntrospectionDirective, BuildSchemaOptions, - BreakingChange, - DangerousChange, + SchemaChange, } from './utilities'; diff --git a/tstypes/utilities/findBreakingChanges.d.ts b/tstypes/utilities/findBreakingChanges.d.ts index 87fa0c028e..0eb2a12ece 100644 --- a/tstypes/utilities/findBreakingChanges.d.ts +++ b/tstypes/utilities/findBreakingChanges.d.ts @@ -35,30 +35,16 @@ type _DangerousChangeType = { ARG_DEFAULT_VALUE_CHANGE: 'ARG_DEFAULT_VALUE_CHANGE'; }; -export interface BreakingChange { - type: keyof _BreakingChangeType; +export interface SchemaChange { + type: keyof _BreakingChangeType | keyof _DangerousChangeType; description: string; } -export interface DangerousChange { - type: keyof _DangerousChangeType; - description: string; -} - -/** - * 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: GraphQLSchema, - newSchema: GraphQLSchema, -): Array; - /** * Given two schemas, returns an Array containing descriptions of all the types - * of potentially dangerous changes covered by the other functions down below. + * of breaking and dangerous changes covered by the other functions down below. */ -export function findDangerousChanges( +export function findSchemaChanges( oldSchema: GraphQLSchema, newSchema: GraphQLSchema, -): Array; +): Array; diff --git a/tstypes/utilities/index.d.ts b/tstypes/utilities/index.d.ts index 8480b8541a..f924402770 100644 --- a/tstypes/utilities/index.d.ts +++ b/tstypes/utilities/index.d.ts @@ -104,10 +104,8 @@ export { assertValidName, isValidNameError } from './assertValidName'; export { BreakingChangeType, DangerousChangeType, - findBreakingChanges, - findDangerousChanges, - BreakingChange, - DangerousChange, + SchemaChange, + findSchemaChanges, } from './findBreakingChanges'; // Report all deprecated usage within a GraphQL document.