@graphql-inspector/core 3.0.2 → 3.1.2

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/README.md CHANGED
@@ -36,17 +36,17 @@ import {
36
36
  Change,
37
37
  InvalidDocument,
38
38
  SimilarMap,
39
- SchemaCoverage,
40
- } from '@graphql-inspector/core';
39
+ SchemaCoverage
40
+ } from '@graphql-inspector/core'
41
41
 
42
42
  // diff
43
- const changes: Change[] = diff(schemaA, schemaB);
43
+ const changes: Change[] = diff(schemaA, schemaB)
44
44
  // validate
45
- const invalid: InvalidDocument[] = validate(documentsGlob, schema);
45
+ const invalid: InvalidDocument[] = validate(documentsGlob, schema)
46
46
  // similar
47
- const similar: SimilarMap = similar(schema, typename, threshold);
47
+ const similar: SimilarMap = similar(schema, typename, threshold)
48
48
  // coverage
49
- const schemaCoverage: SchemaCoverage = coverage(schema, documents);
49
+ const schemaCoverage: SchemaCoverage = coverage(schema, documents)
50
50
  // ...
51
51
  ```
52
52
 
package/index.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- export { diff, DiffRule, Rule, CompletionArgs, CompletionHandler, UsageHandler } from './diff';
1
+ export { diff, DiffRule, Rule, CompletionArgs, CompletionHandler, UsageHandler, } from './diff';
2
2
  export { validate, InvalidDocument } from './validate';
3
3
  export { similar, SimilarMap } from './similar';
4
4
  export * from './coverage';
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.isDeprecated) {
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.isDeprecated) {
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.isDeprecated ? '(deprecated) ' : ''}was removed from enum '${oldEnum.name}'`,
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
  }
@@ -559,7 +573,7 @@ function changesInEnum(oldEnum, newEnum, addChange) {
559
573
  addChange(enumValueDeprecationReasonChanged(newEnum, oldValue, newValue));
560
574
  }
561
575
  }
562
- }
576
+ },
563
577
  });
564
578
  }
565
579
 
@@ -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.isDeprecated ? '(deprecated) ' : ''}was removed from ${entity} '${type.name}'`,
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
  }
@@ -956,10 +970,7 @@ function wordLetterPairs(str) {
956
970
  return flattenDeep(pairs);
957
971
  }
958
972
  function safeString(obj) {
959
- if (obj != null && typeof obj.toString === 'function') {
960
- return `${obj}`;
961
- }
962
- return inspect(obj);
973
+ return inspect(obj).replace(/\[Object\: null prototype\] /g, '');
963
974
  }
964
975
 
965
976
  function fieldArgumentDescriptionChanged(type, field, oldArg, newArg) {
@@ -1036,8 +1047,8 @@ function changesInField(type, oldField, newField, addChange) {
1036
1047
  addChange(fieldDescriptionChanged(type, oldField, newField));
1037
1048
  }
1038
1049
  }
1039
- if (isNotEqual(oldField.isDeprecated, newField.isDeprecated)) {
1040
- if (newField.isDeprecated) {
1050
+ if (isNotEqual(isDeprecated(oldField), isDeprecated(newField))) {
1051
+ if (isDeprecated(newField)) {
1041
1052
  addChange(fieldDeprecationAdded(type, newField));
1042
1053
  }
1043
1054
  else {
@@ -1067,7 +1078,7 @@ function changesInField(type, oldField, newField, addChange) {
1067
1078
  },
1068
1079
  onMutual(arg) {
1069
1080
  changesInArgument(type, oldField, arg.oldVersion, arg.newVersion, addChange);
1070
- }
1081
+ },
1071
1082
  });
1072
1083
  }
1073
1084
 
@@ -1259,7 +1270,7 @@ const suppressRemovalOfDeprecatedField = ({ changes, oldSchema, }) => {
1259
1270
  const type = oldSchema.getType(typeName);
1260
1271
  if (graphql.isObjectType(type) || graphql.isInterfaceType(type)) {
1261
1272
  const field = type.getFields()[fieldName];
1262
- if (field.isDeprecated) {
1273
+ if (isDeprecated(field)) {
1263
1274
  return Object.assign(Object.assign({}, change), { criticality: Object.assign(Object.assign({}, change.criticality), { level: exports.CriticalityLevel.Dangerous }) });
1264
1275
  }
1265
1276
  }
@@ -1271,7 +1282,7 @@ const suppressRemovalOfDeprecatedField = ({ changes, oldSchema, }) => {
1271
1282
  const type = oldSchema.getType(enumName);
1272
1283
  if (graphql.isEnumType(type)) {
1273
1284
  const item = type.getValue(enumItem);
1274
- if (item && item.isDeprecated) {
1285
+ if (item && isDeprecated(item)) {
1275
1286
  return Object.assign(Object.assign({}, change), { criticality: Object.assign(Object.assign({}, change.criticality), { level: exports.CriticalityLevel.Dangerous }) });
1276
1287
  }
1277
1288
  }
@@ -1513,7 +1524,7 @@ function validate(schema, sources, options) {
1513
1524
  .filter((doc) => doc.hasOperations)
1514
1525
  .forEach((doc) => {
1515
1526
  const docWithOperations = {
1516
- kind: 'Document',
1527
+ kind: graphql.Kind.DOCUMENT,
1517
1528
  definitions: doc.operations.map((d) => d.node),
1518
1529
  };
1519
1530
  const extractedFragments = (extractFragments(graphql.print(docWithOperations)) || [])
@@ -1524,7 +1535,7 @@ function validate(schema, sources, options) {
1524
1535
  // remove duplicates
1525
1536
  .filter((def, i, all) => all.findIndex((item) => item.name.value === def.name.value) === i);
1526
1537
  const merged = {
1527
- kind: 'Document',
1538
+ kind: graphql.Kind.DOCUMENT,
1528
1539
  definitions: [...docWithOperations.definitions, ...extractedFragments],
1529
1540
  };
1530
1541
  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.isDeprecated) {
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.isDeprecated) {
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.isDeprecated ? '(deprecated) ' : ''}was removed from enum '${oldEnum.name}'`,
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
  }
@@ -555,7 +569,7 @@ function changesInEnum(oldEnum, newEnum, addChange) {
555
569
  addChange(enumValueDeprecationReasonChanged(newEnum, oldValue, newValue));
556
570
  }
557
571
  }
558
- }
572
+ },
559
573
  });
560
574
  }
561
575
 
@@ -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.isDeprecated ? '(deprecated) ' : ''}was removed from ${entity} '${type.name}'`,
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
  }
@@ -952,10 +966,7 @@ function wordLetterPairs(str) {
952
966
  return flattenDeep(pairs);
953
967
  }
954
968
  function safeString(obj) {
955
- if (obj != null && typeof obj.toString === 'function') {
956
- return `${obj}`;
957
- }
958
- return inspect(obj);
969
+ return inspect(obj).replace(/\[Object\: null prototype\] /g, '');
959
970
  }
960
971
 
961
972
  function fieldArgumentDescriptionChanged(type, field, oldArg, newArg) {
@@ -1032,8 +1043,8 @@ function changesInField(type, oldField, newField, addChange) {
1032
1043
  addChange(fieldDescriptionChanged(type, oldField, newField));
1033
1044
  }
1034
1045
  }
1035
- if (isNotEqual(oldField.isDeprecated, newField.isDeprecated)) {
1036
- if (newField.isDeprecated) {
1046
+ if (isNotEqual(isDeprecated(oldField), isDeprecated(newField))) {
1047
+ if (isDeprecated(newField)) {
1037
1048
  addChange(fieldDeprecationAdded(type, newField));
1038
1049
  }
1039
1050
  else {
@@ -1063,7 +1074,7 @@ function changesInField(type, oldField, newField, addChange) {
1063
1074
  },
1064
1075
  onMutual(arg) {
1065
1076
  changesInArgument(type, oldField, arg.oldVersion, arg.newVersion, addChange);
1066
- }
1077
+ },
1067
1078
  });
1068
1079
  }
1069
1080
 
@@ -1255,7 +1266,7 @@ const suppressRemovalOfDeprecatedField = ({ changes, oldSchema, }) => {
1255
1266
  const type = oldSchema.getType(typeName);
1256
1267
  if (isObjectType(type) || isInterfaceType(type)) {
1257
1268
  const field = type.getFields()[fieldName];
1258
- if (field.isDeprecated) {
1269
+ if (isDeprecated(field)) {
1259
1270
  return Object.assign(Object.assign({}, change), { criticality: Object.assign(Object.assign({}, change.criticality), { level: CriticalityLevel.Dangerous }) });
1260
1271
  }
1261
1272
  }
@@ -1267,7 +1278,7 @@ const suppressRemovalOfDeprecatedField = ({ changes, oldSchema, }) => {
1267
1278
  const type = oldSchema.getType(enumName);
1268
1279
  if (isEnumType(type)) {
1269
1280
  const item = type.getValue(enumItem);
1270
- if (item && item.isDeprecated) {
1281
+ if (item && isDeprecated(item)) {
1271
1282
  return Object.assign(Object.assign({}, change), { criticality: Object.assign(Object.assign({}, change.criticality), { level: CriticalityLevel.Dangerous }) });
1272
1283
  }
1273
1284
  }
@@ -1509,7 +1520,7 @@ function validate(schema, sources, options) {
1509
1520
  .filter((doc) => doc.hasOperations)
1510
1521
  .forEach((doc) => {
1511
1522
  const docWithOperations = {
1512
- kind: 'Document',
1523
+ kind: Kind.DOCUMENT,
1513
1524
  definitions: doc.operations.map((d) => d.node),
1514
1525
  };
1515
1526
  const extractedFragments = (extractFragments(print(docWithOperations)) || [])
@@ -1520,7 +1531,7 @@ function validate(schema, sources, options) {
1520
1531
  // remove duplicates
1521
1532
  .filter((def, i, all) => all.findIndex((item) => item.name.value === def.name.value) === i);
1522
1533
  const merged = {
1523
- kind: 'Document',
1534
+ kind: Kind.DOCUMENT,
1524
1535
  definitions: [...docWithOperations.definitions, ...extractedFragments],
1525
1536
  };
1526
1537
  let transformedSchema = config.apollo
package/package.json CHANGED
@@ -1,10 +1,10 @@
1
1
  {
2
2
  "name": "@graphql-inspector/core",
3
- "version": "3.0.2",
3
+ "version": "3.1.2",
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",
@@ -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: string[], b: string[]): string[];
6
- export declare function unionArrays(a: string[], b: string[]): string[];
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?: {
@@ -0,0 +1,2 @@
1
+ import { GraphQLEnumValue, GraphQLField } from 'graphql';
2
+ export declare function isDeprecated(fieldOrEnumValue: GraphQLField<any, any> | GraphQLEnumValue): boolean;