@@ -65,6 +65,20 @@ enum DangerousChangeType {
65
65
}
66
66
export { DangerousChangeType } ;
67
67
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
+
68
82
export interface BreakingChange {
69
83
type : BreakingChangeType ;
70
84
description : string ;
@@ -75,9 +89,18 @@ export interface DangerousChange {
75
89
description : string ;
76
90
}
77
91
92
+ export interface SafeChange {
93
+ type : SafeChangeType ;
94
+ description : string ;
95
+ }
96
+
97
+ export type SchemaChange = SafeChange | DangerousChange | BreakingChange ;
98
+
78
99
/**
79
100
* Given two schemas, returns an Array containing descriptions of all the types
80
101
* of breaking changes covered by the other functions down below.
102
+ *
103
+ * @deprecated Please use `findSchemaChanges` instead. Will be removed in v18.
81
104
*/
82
105
export function findBreakingChanges (
83
106
oldSchema : GraphQLSchema ,
@@ -92,6 +115,8 @@ export function findBreakingChanges(
92
115
/**
93
116
* Given two schemas, returns an Array containing descriptions of all the types
94
117
* of potentially dangerous changes covered by the other functions down below.
118
+ *
119
+ * @deprecated Please use `findSchemaChanges` instead. Will be removed in v18.
95
120
*/
96
121
export function findDangerousChanges (
97
122
oldSchema : GraphQLSchema ,
@@ -103,10 +128,10 @@ export function findDangerousChanges(
103
128
) ;
104
129
}
105
130
106
- function findSchemaChanges (
131
+ export function findSchemaChanges (
107
132
oldSchema : GraphQLSchema ,
108
133
newSchema : GraphQLSchema ,
109
- ) : Array < BreakingChange | DangerousChange > {
134
+ ) : Array < SchemaChange > {
110
135
return [
111
136
...findTypeChanges ( oldSchema , newSchema ) ,
112
137
...findDirectiveChanges ( oldSchema , newSchema ) ,
@@ -116,7 +141,7 @@ function findSchemaChanges(
116
141
function findDirectiveChanges (
117
142
oldSchema : GraphQLSchema ,
118
143
newSchema : GraphQLSchema ,
119
- ) : Array < BreakingChange | DangerousChange > {
144
+ ) : Array < SchemaChange > {
120
145
const schemaChanges = [ ] ;
121
146
122
147
const directivesDiff = diff (
@@ -131,6 +156,13 @@ function findDirectiveChanges(
131
156
} ) ;
132
157
}
133
158
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
+
134
166
for ( const [ oldDirective , newDirective ] of directivesDiff . persisted ) {
135
167
const argsDiff = diff ( oldDirective . args , newDirective . args ) ;
136
168
@@ -140,6 +172,11 @@ function findDirectiveChanges(
140
172
type : BreakingChangeType . REQUIRED_DIRECTIVE_ARG_ADDED ,
141
173
description : `A required argument @${ oldDirective . name } (${ newArg . name } :) was added.` ,
142
174
} ) ;
175
+ } else {
176
+ schemaChanges . push ( {
177
+ type : SafeChangeType . OPTIONAL_DIRECTIVE_ARG_ADDED ,
178
+ description : `An optional argument @${ oldDirective . name } (${ newArg . name } :) was added.` ,
179
+ } ) ;
143
180
}
144
181
}
145
182
@@ -155,6 +192,11 @@ function findDirectiveChanges(
155
192
type : BreakingChangeType . DIRECTIVE_REPEATABLE_REMOVED ,
156
193
description : `Repeatable flag was removed from @${ oldDirective . name } .` ,
157
194
} ) ;
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
+ } ) ;
158
200
}
159
201
160
202
for ( const location of oldDirective . locations ) {
@@ -165,6 +207,15 @@ function findDirectiveChanges(
165
207
} ) ;
166
208
}
167
209
}
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
+ }
168
219
}
169
220
170
221
return schemaChanges ;
@@ -173,7 +224,7 @@ function findDirectiveChanges(
173
224
function findTypeChanges (
174
225
oldSchema : GraphQLSchema ,
175
226
newSchema : GraphQLSchema ,
176
- ) : Array < BreakingChange | DangerousChange > {
227
+ ) : Array < SchemaChange > {
177
228
const schemaChanges = [ ] ;
178
229
179
230
const typesDiff = diff (
@@ -190,6 +241,13 @@ function findTypeChanges(
190
241
} ) ;
191
242
}
192
243
244
+ for ( const newType of typesDiff . added ) {
245
+ schemaChanges . push ( {
246
+ type : SafeChangeType . TYPE_ADDED ,
247
+ description : `${ newType } was added.` ,
248
+ } ) ;
249
+ }
250
+
193
251
for ( const [ oldType , newType ] of typesDiff . persisted ) {
194
252
if ( isEnumType ( oldType ) && isEnumType ( newType ) ) {
195
253
schemaChanges . push ( ...findEnumTypeChanges ( oldType , newType ) ) ;
@@ -223,7 +281,7 @@ function findTypeChanges(
223
281
function findInputObjectTypeChanges (
224
282
oldType : GraphQLInputObjectType ,
225
283
newType : GraphQLInputObjectType ,
226
- ) : Array < BreakingChange | DangerousChange > {
284
+ ) : Array < SchemaChange > {
227
285
const schemaChanges = [ ] ;
228
286
const fieldsDiff = diff (
229
287
Object . values ( oldType . getFields ( ) ) ,
@@ -263,6 +321,13 @@ function findInputObjectTypeChanges(
263
321
`Field ${ oldType } .${ oldField . name } changed type from ` +
264
322
`${ String ( oldField . type ) } to ${ String ( newField . type ) } .` ,
265
323
} ) ;
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
+ } ) ;
266
331
}
267
332
}
268
333
@@ -344,7 +409,7 @@ function findImplementedInterfacesChanges(
344
409
function findFieldChanges (
345
410
oldType : GraphQLObjectType | GraphQLInterfaceType ,
346
411
newType : GraphQLObjectType | GraphQLInterfaceType ,
347
- ) : Array < BreakingChange | DangerousChange > {
412
+ ) : Array < SchemaChange > {
348
413
const schemaChanges = [ ] ;
349
414
const fieldsDiff = diff (
350
415
Object . values ( oldType . getFields ( ) ) ,
@@ -358,6 +423,13 @@ function findFieldChanges(
358
423
} ) ;
359
424
}
360
425
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
+
361
433
for ( const [ oldField , newField ] of fieldsDiff . persisted ) {
362
434
schemaChanges . push ( ...findArgChanges ( oldType , oldField , newField ) ) ;
363
435
@@ -372,6 +444,13 @@ function findFieldChanges(
372
444
`Field ${ oldType } .${ oldField . name } changed type from ` +
373
445
`${ String ( oldField . type ) } to ${ String ( newField . type ) } .` ,
374
446
} ) ;
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
+ } ) ;
375
454
}
376
455
}
377
456
@@ -425,6 +504,9 @@ function findArgChanges(
425
504
} ) ;
426
505
}
427
506
}
507
+ } else {
508
+ // TODO: add default value added
509
+ // TODO: add safe change
428
510
}
429
511
}
430
512
0 commit comments