diff --git a/src/utilities/__tests__/findBreakingChanges-test.js b/src/utilities/__tests__/findBreakingChanges-test.js index 32d969a193..066a3f4344 100644 --- a/src/utilities/__tests__/findBreakingChanges-test.js +++ b/src/utilities/__tests__/findBreakingChanges-test.js @@ -35,6 +35,7 @@ import { findAddedNonNullDirectiveArgs, findRemovedLocationsForDirective, findRemovedDirectiveLocations, + findRemovedDirectiveRepeatable, } from '../findBreakingChanges'; import { @@ -1007,6 +1008,23 @@ describe('findBreakingChanges', () => { }, ]); }); + + it('should detect removal of repeatable flag', () => { + const oldSchema = buildSchema(` + directive @foo repeatable on OBJECT + `); + + const newSchema = buildSchema(` + directive @foo on OBJECT + `); + + expect(findRemovedDirectiveRepeatable(oldSchema, newSchema)).to.eql([ + { + type: BreakingChangeType.DIRECTIVE_REPEATABLE_REMOVED, + description: 'Repeatable flag was removed from foo', + }, + ]); + }); }); describe('findDangerousChanges', () => { diff --git a/src/utilities/findBreakingChanges.js b/src/utilities/findBreakingChanges.js index 9f7962138f..6a77981a4b 100644 --- a/src/utilities/findBreakingChanges.js +++ b/src/utilities/findBreakingChanges.js @@ -50,6 +50,7 @@ export const BreakingChangeType = { DIRECTIVE_REMOVED: 'DIRECTIVE_REMOVED', DIRECTIVE_ARG_REMOVED: 'DIRECTIVE_ARG_REMOVED', DIRECTIVE_LOCATION_REMOVED: 'DIRECTIVE_LOCATION_REMOVED', + DIRECTIVE_REPEATABLE_REMOVED: 'DIRECTIVE_REPEATABLE_REMOVED', REQUIRED_DIRECTIVE_ARG_ADDED: 'REQUIRED_DIRECTIVE_ARG_ADDED', }; @@ -94,6 +95,7 @@ export function findBreakingChanges( ...findRemovedDirectiveArgs(oldSchema, newSchema), ...findAddedNonNullDirectiveArgs(oldSchema, newSchema), ...findRemovedDirectiveLocations(oldSchema, newSchema), + ...findRemovedDirectiveRepeatable(oldSchema, newSchema), ]; } @@ -840,6 +842,31 @@ export function findRemovedDirectiveLocations( return removedLocations; } +export function findRemovedDirectiveRepeatable( + oldSchema: GraphQLSchema, + newSchema: GraphQLSchema, +): Array { + const removedRepeatable = []; + const oldSchemaDirectiveMap = getDirectiveMapForSchema(oldSchema); + + for (const newDirective of newSchema.getDirectives()) { + const oldDirective = oldSchemaDirectiveMap[newDirective.name]; + + if (!oldDirective) { + continue; + } + + if (oldDirective.repeatable && !newDirective.repeatable) { + removedRepeatable.push({ + type: BreakingChangeType.DIRECTIVE_REPEATABLE_REMOVED, + description: `Repeatable flag was removed from ${newDirective.name}`, + }); + } + } + + return removedRepeatable; +} + function getDirectiveMapForSchema( schema: GraphQLSchema, ): ObjMap {