@graphql-inspector/core 3.0.2 → 3.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/index.js +25 -11
- package/index.mjs +25 -11
- package/package.json +2 -2
- package/utils/compare.d.ts +2 -2
- package/utils/isDeprecated.d.ts +2 -0
package/index.js
CHANGED
|
@@ -78,6 +78,20 @@ function compareLists(oldList, newList, callbacks) {
|
|
|
78
78
|
};
|
|
79
79
|
}
|
|
80
80
|
|
|
81
|
+
function isDeprecated(fieldOrEnumValue) {
|
|
82
|
+
var _a, _b;
|
|
83
|
+
if ('isDeprecated' in fieldOrEnumValue) {
|
|
84
|
+
return fieldOrEnumValue['isDeprecated'];
|
|
85
|
+
}
|
|
86
|
+
if (fieldOrEnumValue.deprecationReason != null) {
|
|
87
|
+
return true;
|
|
88
|
+
}
|
|
89
|
+
if ((_b = (_a = fieldOrEnumValue.astNode) === null || _a === void 0 ? void 0 : _a.directives) === null || _b === void 0 ? void 0 : _b.some(directive => directive.name.value === "deprecated")) {
|
|
90
|
+
return true;
|
|
91
|
+
}
|
|
92
|
+
return false;
|
|
93
|
+
}
|
|
94
|
+
|
|
81
95
|
function safeChangeForField(oldType, newType) {
|
|
82
96
|
if (!graphql.isWrappingType(oldType) && !graphql.isWrappingType(newType)) {
|
|
83
97
|
return oldType.toString() === newType.toString();
|
|
@@ -120,7 +134,7 @@ function getTypePrefix(type) {
|
|
|
120
134
|
[graphql.Kind.ENUM_TYPE_DEFINITION]: 'enum',
|
|
121
135
|
[graphql.Kind.INPUT_OBJECT_TYPE_DEFINITION]: 'input',
|
|
122
136
|
};
|
|
123
|
-
return kindsMap[kind];
|
|
137
|
+
return kindsMap[kind.toString()];
|
|
124
138
|
}
|
|
125
139
|
function isPrimitive(type) {
|
|
126
140
|
return (['String', 'Int', 'Float', 'Boolean', 'ID'].indexOf(typeof type === 'string' ? type : type.name) !== -1);
|
|
@@ -155,7 +169,7 @@ function findDeprecatedUsages(schema, ast) {
|
|
|
155
169
|
},
|
|
156
170
|
Field(node) {
|
|
157
171
|
const fieldDef = typeInfo.getFieldDef();
|
|
158
|
-
if (fieldDef && fieldDef
|
|
172
|
+
if (fieldDef && isDeprecated(fieldDef)) {
|
|
159
173
|
const parentType = typeInfo.getParentType();
|
|
160
174
|
if (parentType) {
|
|
161
175
|
const reason = fieldDef.deprecationReason;
|
|
@@ -165,7 +179,7 @@ function findDeprecatedUsages(schema, ast) {
|
|
|
165
179
|
},
|
|
166
180
|
EnumValue(node) {
|
|
167
181
|
const enumVal = typeInfo.getEnumValue();
|
|
168
|
-
if (enumVal && enumVal
|
|
182
|
+
if (enumVal && isDeprecated(enumVal)) {
|
|
169
183
|
const type = graphql.getNamedType(typeInfo.getInputType());
|
|
170
184
|
if (type) {
|
|
171
185
|
const reason = enumVal.deprecationReason;
|
|
@@ -476,7 +490,7 @@ function enumValueRemoved(oldEnum, value) {
|
|
|
476
490
|
reason: `Removing an enum value will cause existing queries that use this enum value to error.`,
|
|
477
491
|
},
|
|
478
492
|
type: exports.ChangeType.EnumValueRemoved,
|
|
479
|
-
message: `Enum value '${value.name}' ${value
|
|
493
|
+
message: `Enum value '${value.name}' ${isDeprecated(value) ? '(deprecated) ' : ''}was removed from enum '${oldEnum.name}'`,
|
|
480
494
|
path: [oldEnum.name, value.name].join('.'),
|
|
481
495
|
};
|
|
482
496
|
}
|
|
@@ -760,7 +774,7 @@ function fieldRemoved(type, field) {
|
|
|
760
774
|
: `Removing a field is a breaking change. It is preferable to deprecate the field before removing it.`,
|
|
761
775
|
},
|
|
762
776
|
type: exports.ChangeType.FieldRemoved,
|
|
763
|
-
message: `Field '${field.name}' ${field
|
|
777
|
+
message: `Field '${field.name}' ${isDeprecated(field) ? '(deprecated) ' : ''}was removed from ${entity} '${type.name}'`,
|
|
764
778
|
path: [type.name, field.name].join('.'),
|
|
765
779
|
};
|
|
766
780
|
}
|
|
@@ -1036,8 +1050,8 @@ function changesInField(type, oldField, newField, addChange) {
|
|
|
1036
1050
|
addChange(fieldDescriptionChanged(type, oldField, newField));
|
|
1037
1051
|
}
|
|
1038
1052
|
}
|
|
1039
|
-
if (isNotEqual(oldField
|
|
1040
|
-
if (newField
|
|
1053
|
+
if (isNotEqual(isDeprecated(oldField), isDeprecated(newField))) {
|
|
1054
|
+
if (isDeprecated(newField)) {
|
|
1041
1055
|
addChange(fieldDeprecationAdded(type, newField));
|
|
1042
1056
|
}
|
|
1043
1057
|
else {
|
|
@@ -1259,7 +1273,7 @@ const suppressRemovalOfDeprecatedField = ({ changes, oldSchema, }) => {
|
|
|
1259
1273
|
const type = oldSchema.getType(typeName);
|
|
1260
1274
|
if (graphql.isObjectType(type) || graphql.isInterfaceType(type)) {
|
|
1261
1275
|
const field = type.getFields()[fieldName];
|
|
1262
|
-
if (field
|
|
1276
|
+
if (isDeprecated(field)) {
|
|
1263
1277
|
return Object.assign(Object.assign({}, change), { criticality: Object.assign(Object.assign({}, change.criticality), { level: exports.CriticalityLevel.Dangerous }) });
|
|
1264
1278
|
}
|
|
1265
1279
|
}
|
|
@@ -1271,7 +1285,7 @@ const suppressRemovalOfDeprecatedField = ({ changes, oldSchema, }) => {
|
|
|
1271
1285
|
const type = oldSchema.getType(enumName);
|
|
1272
1286
|
if (graphql.isEnumType(type)) {
|
|
1273
1287
|
const item = type.getValue(enumItem);
|
|
1274
|
-
if (item && item
|
|
1288
|
+
if (item && isDeprecated(item)) {
|
|
1275
1289
|
return Object.assign(Object.assign({}, change), { criticality: Object.assign(Object.assign({}, change.criticality), { level: exports.CriticalityLevel.Dangerous }) });
|
|
1276
1290
|
}
|
|
1277
1291
|
}
|
|
@@ -1513,7 +1527,7 @@ function validate(schema, sources, options) {
|
|
|
1513
1527
|
.filter((doc) => doc.hasOperations)
|
|
1514
1528
|
.forEach((doc) => {
|
|
1515
1529
|
const docWithOperations = {
|
|
1516
|
-
kind:
|
|
1530
|
+
kind: graphql.Kind.DOCUMENT,
|
|
1517
1531
|
definitions: doc.operations.map((d) => d.node),
|
|
1518
1532
|
};
|
|
1519
1533
|
const extractedFragments = (extractFragments(graphql.print(docWithOperations)) || [])
|
|
@@ -1524,7 +1538,7 @@ function validate(schema, sources, options) {
|
|
|
1524
1538
|
// remove duplicates
|
|
1525
1539
|
.filter((def, i, all) => all.findIndex((item) => item.name.value === def.name.value) === i);
|
|
1526
1540
|
const merged = {
|
|
1527
|
-
kind:
|
|
1541
|
+
kind: graphql.Kind.DOCUMENT,
|
|
1528
1542
|
definitions: [...docWithOperations.definitions, ...extractedFragments],
|
|
1529
1543
|
};
|
|
1530
1544
|
let transformedSchema = config.apollo
|
package/index.mjs
CHANGED
|
@@ -72,6 +72,20 @@ function compareLists(oldList, newList, callbacks) {
|
|
|
72
72
|
};
|
|
73
73
|
}
|
|
74
74
|
|
|
75
|
+
function isDeprecated(fieldOrEnumValue) {
|
|
76
|
+
var _a, _b;
|
|
77
|
+
if ('isDeprecated' in fieldOrEnumValue) {
|
|
78
|
+
return fieldOrEnumValue['isDeprecated'];
|
|
79
|
+
}
|
|
80
|
+
if (fieldOrEnumValue.deprecationReason != null) {
|
|
81
|
+
return true;
|
|
82
|
+
}
|
|
83
|
+
if ((_b = (_a = fieldOrEnumValue.astNode) === null || _a === void 0 ? void 0 : _a.directives) === null || _b === void 0 ? void 0 : _b.some(directive => directive.name.value === "deprecated")) {
|
|
84
|
+
return true;
|
|
85
|
+
}
|
|
86
|
+
return false;
|
|
87
|
+
}
|
|
88
|
+
|
|
75
89
|
function safeChangeForField(oldType, newType) {
|
|
76
90
|
if (!isWrappingType(oldType) && !isWrappingType(newType)) {
|
|
77
91
|
return oldType.toString() === newType.toString();
|
|
@@ -114,7 +128,7 @@ function getTypePrefix(type) {
|
|
|
114
128
|
[Kind.ENUM_TYPE_DEFINITION]: 'enum',
|
|
115
129
|
[Kind.INPUT_OBJECT_TYPE_DEFINITION]: 'input',
|
|
116
130
|
};
|
|
117
|
-
return kindsMap[kind];
|
|
131
|
+
return kindsMap[kind.toString()];
|
|
118
132
|
}
|
|
119
133
|
function isPrimitive(type) {
|
|
120
134
|
return (['String', 'Int', 'Float', 'Boolean', 'ID'].indexOf(typeof type === 'string' ? type : type.name) !== -1);
|
|
@@ -149,7 +163,7 @@ function findDeprecatedUsages(schema, ast) {
|
|
|
149
163
|
},
|
|
150
164
|
Field(node) {
|
|
151
165
|
const fieldDef = typeInfo.getFieldDef();
|
|
152
|
-
if (fieldDef && fieldDef
|
|
166
|
+
if (fieldDef && isDeprecated(fieldDef)) {
|
|
153
167
|
const parentType = typeInfo.getParentType();
|
|
154
168
|
if (parentType) {
|
|
155
169
|
const reason = fieldDef.deprecationReason;
|
|
@@ -159,7 +173,7 @@ function findDeprecatedUsages(schema, ast) {
|
|
|
159
173
|
},
|
|
160
174
|
EnumValue(node) {
|
|
161
175
|
const enumVal = typeInfo.getEnumValue();
|
|
162
|
-
if (enumVal && enumVal
|
|
176
|
+
if (enumVal && isDeprecated(enumVal)) {
|
|
163
177
|
const type = getNamedType(typeInfo.getInputType());
|
|
164
178
|
if (type) {
|
|
165
179
|
const reason = enumVal.deprecationReason;
|
|
@@ -472,7 +486,7 @@ function enumValueRemoved(oldEnum, value) {
|
|
|
472
486
|
reason: `Removing an enum value will cause existing queries that use this enum value to error.`,
|
|
473
487
|
},
|
|
474
488
|
type: ChangeType.EnumValueRemoved,
|
|
475
|
-
message: `Enum value '${value.name}' ${value
|
|
489
|
+
message: `Enum value '${value.name}' ${isDeprecated(value) ? '(deprecated) ' : ''}was removed from enum '${oldEnum.name}'`,
|
|
476
490
|
path: [oldEnum.name, value.name].join('.'),
|
|
477
491
|
};
|
|
478
492
|
}
|
|
@@ -756,7 +770,7 @@ function fieldRemoved(type, field) {
|
|
|
756
770
|
: `Removing a field is a breaking change. It is preferable to deprecate the field before removing it.`,
|
|
757
771
|
},
|
|
758
772
|
type: ChangeType.FieldRemoved,
|
|
759
|
-
message: `Field '${field.name}' ${field
|
|
773
|
+
message: `Field '${field.name}' ${isDeprecated(field) ? '(deprecated) ' : ''}was removed from ${entity} '${type.name}'`,
|
|
760
774
|
path: [type.name, field.name].join('.'),
|
|
761
775
|
};
|
|
762
776
|
}
|
|
@@ -1032,8 +1046,8 @@ function changesInField(type, oldField, newField, addChange) {
|
|
|
1032
1046
|
addChange(fieldDescriptionChanged(type, oldField, newField));
|
|
1033
1047
|
}
|
|
1034
1048
|
}
|
|
1035
|
-
if (isNotEqual(oldField
|
|
1036
|
-
if (newField
|
|
1049
|
+
if (isNotEqual(isDeprecated(oldField), isDeprecated(newField))) {
|
|
1050
|
+
if (isDeprecated(newField)) {
|
|
1037
1051
|
addChange(fieldDeprecationAdded(type, newField));
|
|
1038
1052
|
}
|
|
1039
1053
|
else {
|
|
@@ -1255,7 +1269,7 @@ const suppressRemovalOfDeprecatedField = ({ changes, oldSchema, }) => {
|
|
|
1255
1269
|
const type = oldSchema.getType(typeName);
|
|
1256
1270
|
if (isObjectType(type) || isInterfaceType(type)) {
|
|
1257
1271
|
const field = type.getFields()[fieldName];
|
|
1258
|
-
if (field
|
|
1272
|
+
if (isDeprecated(field)) {
|
|
1259
1273
|
return Object.assign(Object.assign({}, change), { criticality: Object.assign(Object.assign({}, change.criticality), { level: CriticalityLevel.Dangerous }) });
|
|
1260
1274
|
}
|
|
1261
1275
|
}
|
|
@@ -1267,7 +1281,7 @@ const suppressRemovalOfDeprecatedField = ({ changes, oldSchema, }) => {
|
|
|
1267
1281
|
const type = oldSchema.getType(enumName);
|
|
1268
1282
|
if (isEnumType(type)) {
|
|
1269
1283
|
const item = type.getValue(enumItem);
|
|
1270
|
-
if (item && item
|
|
1284
|
+
if (item && isDeprecated(item)) {
|
|
1271
1285
|
return Object.assign(Object.assign({}, change), { criticality: Object.assign(Object.assign({}, change.criticality), { level: CriticalityLevel.Dangerous }) });
|
|
1272
1286
|
}
|
|
1273
1287
|
}
|
|
@@ -1509,7 +1523,7 @@ function validate(schema, sources, options) {
|
|
|
1509
1523
|
.filter((doc) => doc.hasOperations)
|
|
1510
1524
|
.forEach((doc) => {
|
|
1511
1525
|
const docWithOperations = {
|
|
1512
|
-
kind:
|
|
1526
|
+
kind: Kind.DOCUMENT,
|
|
1513
1527
|
definitions: doc.operations.map((d) => d.node),
|
|
1514
1528
|
};
|
|
1515
1529
|
const extractedFragments = (extractFragments(print(docWithOperations)) || [])
|
|
@@ -1520,7 +1534,7 @@ function validate(schema, sources, options) {
|
|
|
1520
1534
|
// remove duplicates
|
|
1521
1535
|
.filter((def, i, all) => all.findIndex((item) => item.name.value === def.name.value) === i);
|
|
1522
1536
|
const merged = {
|
|
1523
|
-
kind:
|
|
1537
|
+
kind: Kind.DOCUMENT,
|
|
1524
1538
|
definitions: [...docWithOperations.definitions, ...extractedFragments],
|
|
1525
1539
|
};
|
|
1526
1540
|
let transformedSchema = config.apollo
|
package/package.json
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@graphql-inspector/core",
|
|
3
|
-
"version": "3.0
|
|
3
|
+
"version": "3.1.0",
|
|
4
4
|
"description": "Tooling for GraphQL. Compare GraphQL Schemas, check documents, find breaking changes, find similar types.",
|
|
5
5
|
"sideEffects": false,
|
|
6
6
|
"peerDependencies": {
|
|
7
|
-
"graphql": "^0.13.0 || ^14.0.0 || ^15.0.0"
|
|
7
|
+
"graphql": "^0.13.0 || ^14.0.0 || ^15.0.0 || ^16.0.0"
|
|
8
8
|
},
|
|
9
9
|
"dependencies": {
|
|
10
10
|
"dependency-graph": "0.11.0",
|
package/utils/compare.d.ts
CHANGED
|
@@ -2,8 +2,8 @@ export declare function keyMap<T>(list: readonly T[], keyFn: (item: T) => string
|
|
|
2
2
|
export declare function isEqual<T>(a: T, b: T): boolean;
|
|
3
3
|
export declare function isNotEqual<T>(a: T, b: T): boolean;
|
|
4
4
|
export declare function isVoid<T>(a: T): boolean;
|
|
5
|
-
export declare function diffArrays(a:
|
|
6
|
-
export declare function unionArrays(a:
|
|
5
|
+
export declare function diffArrays<T>(a: T[] | readonly T[], b: T[] | readonly T[]): T[];
|
|
6
|
+
export declare function unionArrays<T>(a: T[] | readonly T[], b: T[] | readonly T[]): T[];
|
|
7
7
|
export declare function compareLists<T extends {
|
|
8
8
|
name: string;
|
|
9
9
|
}>(oldList: readonly T[], newList: readonly T[], callbacks?: {
|