Skip to content

Commit afcd663

Browse files
committed
Alternative approach for findSchemaChanges
1 parent 0254e5f commit afcd663

File tree

3 files changed

+90
-6
lines changed

3 files changed

+90
-6
lines changed

src/index.ts

+1
Original file line numberDiff line numberDiff line change
@@ -474,6 +474,7 @@ export {
474474
DangerousChangeType,
475475
findBreakingChanges,
476476
findDangerousChanges,
477+
findSchemaChanges,
477478
} from './utilities/index.js';
478479

479480
export type {

src/utilities/findBreakingChanges.ts

+88-6
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,20 @@ enum DangerousChangeType {
6565
}
6666
export { DangerousChangeType };
6767

68+
enum SafeChangeType {
69+
TYPE_ADDED = 'TYPE_ADDED',
70+
OPTIONAL_INPUT_FIELD_ADDED = 'OPTIONAL_INPUT_FIELD_ADDED',
71+
OPTIONAL_ARG_ADDED = 'OPTIONAL_ARG_ADDED',
72+
DIRECTIVE_ADDED = 'DIRECTIVE_ADDED',
73+
FIELD_ADDED = 'FIELD_ADDED',
74+
DIRECTIVE_REPEATABLE_ADDED = 'DIRECTIVE_REPEATABLE_ADDED',
75+
DIRECTIVE_LOCATION_ADDED = 'DIRECTIVE_LOCATION_ADDED',
76+
OPTIONAL_DIRECTIVE_ARG_ADDED = 'OPTIONAL_DIRECTIVE_ARG_ADDED',
77+
FIELD_CHANGED_KIND_SAFE = 'FIELD_CHANGED_KIND_SAFE',
78+
ARG_CHANGED_KIND_SAFE = 'ARG_CHANGED_KIND_SAFE',
79+
}
80+
export { SafeChangeType };
81+
6882
export interface BreakingChange {
6983
type: BreakingChangeType;
7084
description: string;
@@ -75,9 +89,18 @@ export interface DangerousChange {
7589
description: string;
7690
}
7791

92+
export interface SafeChange {
93+
type: SafeChangeType;
94+
description: string;
95+
}
96+
97+
export type SchemaChange = SafeChange | DangerousChange | BreakingChange;
98+
7899
/**
79100
* Given two schemas, returns an Array containing descriptions of all the types
80101
* of breaking changes covered by the other functions down below.
102+
*
103+
* @deprecated Please use `findSchemaChanges` instead. Will be removed in v18.
81104
*/
82105
export function findBreakingChanges(
83106
oldSchema: GraphQLSchema,
@@ -92,6 +115,8 @@ export function findBreakingChanges(
92115
/**
93116
* Given two schemas, returns an Array containing descriptions of all the types
94117
* of potentially dangerous changes covered by the other functions down below.
118+
*
119+
* @deprecated Please use `findSchemaChanges` instead. Will be removed in v18.
95120
*/
96121
export function findDangerousChanges(
97122
oldSchema: GraphQLSchema,
@@ -103,10 +128,10 @@ export function findDangerousChanges(
103128
);
104129
}
105130

106-
function findSchemaChanges(
131+
export function findSchemaChanges(
107132
oldSchema: GraphQLSchema,
108133
newSchema: GraphQLSchema,
109-
): Array<BreakingChange | DangerousChange> {
134+
): Array<SchemaChange> {
110135
return [
111136
...findTypeChanges(oldSchema, newSchema),
112137
...findDirectiveChanges(oldSchema, newSchema),
@@ -116,7 +141,7 @@ function findSchemaChanges(
116141
function findDirectiveChanges(
117142
oldSchema: GraphQLSchema,
118143
newSchema: GraphQLSchema,
119-
): Array<BreakingChange | DangerousChange> {
144+
): Array<SchemaChange> {
120145
const schemaChanges = [];
121146

122147
const directivesDiff = diff(
@@ -131,6 +156,13 @@ function findDirectiveChanges(
131156
});
132157
}
133158

159+
for (const newDirective of directivesDiff.added) {
160+
schemaChanges.push({
161+
type: SafeChangeType.DIRECTIVE_ADDED,
162+
description: `Directive @${newDirective.name} was added.`,
163+
});
164+
}
165+
134166
for (const [oldDirective, newDirective] of directivesDiff.persisted) {
135167
const argsDiff = diff(oldDirective.args, newDirective.args);
136168

@@ -140,6 +172,11 @@ function findDirectiveChanges(
140172
type: BreakingChangeType.REQUIRED_DIRECTIVE_ARG_ADDED,
141173
description: `A required argument @${oldDirective.name}(${newArg.name}:) was added.`,
142174
});
175+
} else {
176+
schemaChanges.push({
177+
type: SafeChangeType.OPTIONAL_DIRECTIVE_ARG_ADDED,
178+
description: `An optional argument @${oldDirective.name}(${newArg.name}:) was added.`,
179+
});
143180
}
144181
}
145182

@@ -155,6 +192,11 @@ function findDirectiveChanges(
155192
type: BreakingChangeType.DIRECTIVE_REPEATABLE_REMOVED,
156193
description: `Repeatable flag was removed from @${oldDirective.name}.`,
157194
});
195+
} else if (newDirective.isRepeatable && !oldDirective.isRepeatable) {
196+
schemaChanges.push({
197+
type: SafeChangeType.DIRECTIVE_REPEATABLE_ADDED,
198+
description: `Repeatable flag was added to @${oldDirective.name}.`,
199+
});
158200
}
159201

160202
for (const location of oldDirective.locations) {
@@ -165,6 +207,15 @@ function findDirectiveChanges(
165207
});
166208
}
167209
}
210+
211+
for (const location of newDirective.locations) {
212+
if (!oldDirective.locations.includes(location)) {
213+
schemaChanges.push({
214+
type: SafeChangeType.DIRECTIVE_LOCATION_ADDED,
215+
description: `${location} was added to @${oldDirective.name}.`,
216+
});
217+
}
218+
}
168219
}
169220

170221
return schemaChanges;
@@ -173,7 +224,7 @@ function findDirectiveChanges(
173224
function findTypeChanges(
174225
oldSchema: GraphQLSchema,
175226
newSchema: GraphQLSchema,
176-
): Array<BreakingChange | DangerousChange> {
227+
): Array<SchemaChange> {
177228
const schemaChanges = [];
178229

179230
const typesDiff = diff(
@@ -190,6 +241,13 @@ function findTypeChanges(
190241
});
191242
}
192243

244+
for (const newType of typesDiff.added) {
245+
schemaChanges.push({
246+
type: SafeChangeType.TYPE_ADDED,
247+
description: `${newType} was added.`,
248+
});
249+
}
250+
193251
for (const [oldType, newType] of typesDiff.persisted) {
194252
if (isEnumType(oldType) && isEnumType(newType)) {
195253
schemaChanges.push(...findEnumTypeChanges(oldType, newType));
@@ -223,7 +281,7 @@ function findTypeChanges(
223281
function findInputObjectTypeChanges(
224282
oldType: GraphQLInputObjectType,
225283
newType: GraphQLInputObjectType,
226-
): Array<BreakingChange | DangerousChange> {
284+
): Array<SchemaChange> {
227285
const schemaChanges = [];
228286
const fieldsDiff = diff(
229287
Object.values(oldType.getFields()),
@@ -263,6 +321,13 @@ function findInputObjectTypeChanges(
263321
`Field ${oldType}.${oldField.name} changed type from ` +
264322
`${String(oldField.type)} to ${String(newField.type)}.`,
265323
});
324+
} else {
325+
schemaChanges.push({
326+
type: SafeChangeType.FIELD_CHANGED_KIND_SAFE,
327+
description:
328+
`Field ${oldType}.${oldField.name} changed type from ` +
329+
`${String(oldField.type)} to ${String(newField.type)}.`,
330+
});
266331
}
267332
}
268333

@@ -344,7 +409,7 @@ function findImplementedInterfacesChanges(
344409
function findFieldChanges(
345410
oldType: GraphQLObjectType | GraphQLInterfaceType,
346411
newType: GraphQLObjectType | GraphQLInterfaceType,
347-
): Array<BreakingChange | DangerousChange> {
412+
): Array<SchemaChange> {
348413
const schemaChanges = [];
349414
const fieldsDiff = diff(
350415
Object.values(oldType.getFields()),
@@ -358,6 +423,13 @@ function findFieldChanges(
358423
});
359424
}
360425

426+
for (const newField of fieldsDiff.added) {
427+
schemaChanges.push({
428+
type: SafeChangeType.FIELD_ADDED,
429+
description: `Field ${oldType}.${newField.name} was removed.`,
430+
});
431+
}
432+
361433
for (const [oldField, newField] of fieldsDiff.persisted) {
362434
schemaChanges.push(...findArgChanges(oldType, oldField, newField));
363435

@@ -372,6 +444,13 @@ function findFieldChanges(
372444
`Field ${oldType}.${oldField.name} changed type from ` +
373445
`${String(oldField.type)} to ${String(newField.type)}.`,
374446
});
447+
} else {
448+
schemaChanges.push({
449+
type: SafeChangeType.FIELD_CHANGED_KIND_SAFE,
450+
description:
451+
`Field ${oldType}.${oldField.name} changed type from ` +
452+
`${String(oldField.type)} to ${String(newField.type)}.`,
453+
});
375454
}
376455
}
377456

@@ -425,6 +504,9 @@ function findArgChanges(
425504
});
426505
}
427506
}
507+
} else {
508+
// TODO: add default value added
509+
// TODO: add safe change
428510
}
429511
}
430512

src/utilities/index.ts

+1
Original file line numberDiff line numberDiff line change
@@ -106,6 +106,7 @@ export {
106106
DangerousChangeType,
107107
findBreakingChanges,
108108
findDangerousChanges,
109+
findSchemaChanges,
109110
} from './findBreakingChanges.js';
110111
export type { BreakingChange, DangerousChange } from './findBreakingChanges.js';
111112

0 commit comments

Comments
 (0)