@graphql-eslint/eslint-plugin 3.14.3 → 3.14.4-alpha-20221229152648-0a153c6

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.
Files changed (78) hide show
  1. package/cjs/cache.js +3 -2
  2. package/cjs/documents.js +8 -5
  3. package/cjs/estree-converter/converter.js +1 -1
  4. package/cjs/parser.js +4 -2
  5. package/cjs/processor.js +4 -2
  6. package/cjs/rules/alphabetize.js +5 -3
  7. package/cjs/rules/graphql-js-validation.js +9 -6
  8. package/cjs/rules/input-name.js +5 -4
  9. package/cjs/rules/naming-convention.js +2 -2
  10. package/cjs/rules/no-case-insensitive-enum-values-duplicates.js +3 -2
  11. package/cjs/rules/no-duplicate-fields.js +2 -2
  12. package/cjs/rules/no-hashtag-description.js +3 -0
  13. package/cjs/rules/no-root-type.js +1 -1
  14. package/cjs/rules/no-typename-prefix.js +1 -1
  15. package/cjs/rules/no-unreachable-types.js +1 -1
  16. package/cjs/rules/relay-arguments.js +2 -1
  17. package/cjs/rules/relay-connection-types.js +2 -2
  18. package/cjs/rules/relay-edge-types.js +7 -4
  19. package/cjs/rules/relay-page-info.js +2 -1
  20. package/cjs/rules/require-deprecation-date.js +2 -2
  21. package/cjs/rules/require-deprecation-reason.js +2 -1
  22. package/cjs/rules/require-description.js +1 -1
  23. package/cjs/rules/require-field-of-type-query-in-mutation-result.js +1 -1
  24. package/cjs/rules/require-id-when-available.js +2 -1
  25. package/cjs/rules/require-nullable-fields-with-oneof.js +2 -2
  26. package/cjs/rules/require-type-pattern-with-oneof.js +2 -1
  27. package/cjs/rules/strict-id-in-types.js +4 -4
  28. package/cjs/rules/unique-fragment-name.js +1 -0
  29. package/cjs/schema.js +3 -1
  30. package/cjs/testkit.js +4 -7
  31. package/cjs/utils.js +11 -5
  32. package/esm/cache.js +3 -2
  33. package/esm/documents.js +8 -5
  34. package/esm/estree-converter/converter.js +1 -1
  35. package/esm/graphql-config.js +1 -1
  36. package/esm/parser.js +4 -2
  37. package/esm/processor.js +5 -3
  38. package/esm/rules/alphabetize.js +6 -4
  39. package/esm/rules/graphql-js-validation.js +9 -6
  40. package/esm/rules/input-name.js +5 -4
  41. package/esm/rules/naming-convention.js +3 -3
  42. package/esm/rules/no-case-insensitive-enum-values-duplicates.js +3 -2
  43. package/esm/rules/no-duplicate-fields.js +2 -2
  44. package/esm/rules/no-hashtag-description.js +3 -0
  45. package/esm/rules/no-root-type.js +2 -2
  46. package/esm/rules/no-typename-prefix.js +1 -1
  47. package/esm/rules/no-unreachable-types.js +1 -1
  48. package/esm/rules/relay-arguments.js +2 -1
  49. package/esm/rules/relay-connection-types.js +2 -2
  50. package/esm/rules/relay-edge-types.js +7 -4
  51. package/esm/rules/relay-page-info.js +2 -1
  52. package/esm/rules/require-deprecation-date.js +2 -2
  53. package/esm/rules/require-deprecation-reason.js +2 -1
  54. package/esm/rules/require-description.js +1 -1
  55. package/esm/rules/require-field-of-type-query-in-mutation-result.js +1 -1
  56. package/esm/rules/require-id-when-available.js +2 -1
  57. package/esm/rules/require-nullable-fields-with-oneof.js +2 -2
  58. package/esm/rules/require-type-pattern-with-oneof.js +2 -1
  59. package/esm/rules/strict-id-in-types.js +5 -5
  60. package/esm/rules/unique-fragment-name.js +1 -0
  61. package/esm/schema.js +3 -1
  62. package/esm/testkit.js +4 -7
  63. package/esm/utils.js +9 -4
  64. package/package.json +1 -1
  65. package/typings/cache.d.cts +1 -1
  66. package/typings/cache.d.ts +1 -1
  67. package/typings/estree-converter/types.d.cts +4 -4
  68. package/typings/estree-converter/types.d.ts +4 -4
  69. package/typings/estree-converter/utils.d.cts +2 -2
  70. package/typings/estree-converter/utils.d.ts +2 -2
  71. package/typings/rules/index.d.cts +68 -68
  72. package/typings/rules/index.d.ts +68 -68
  73. package/typings/testkit.d.cts +6 -4
  74. package/typings/testkit.d.ts +6 -4
  75. package/typings/types.d.cts +4 -3
  76. package/typings/types.d.ts +4 -3
  77. package/typings/utils.d.cts +8 -5
  78. package/typings/utils.d.ts +8 -5
package/cjs/cache.js CHANGED
@@ -15,11 +15,12 @@ class ModuleCache {
15
15
  log('setting entry for', cacheKey);
16
16
  }
17
17
  get(cacheKey, settings = { lifetime: 10 /* seconds */ }) {
18
- if (!this.map.has(cacheKey)) {
18
+ const value = this.map.get(cacheKey);
19
+ if (!value) {
19
20
  log('cache miss for', cacheKey);
20
21
  return;
21
22
  }
22
- const { lastSeen, result } = this.map.get(cacheKey);
23
+ const { lastSeen, result } = value;
23
24
  // check freshness
24
25
  if (process.env.NODE /* don't check for ESLint CLI */ ||
25
26
  process.hrtime(lastSeen)[0] < settings.lifetime) {
package/cjs/documents.js CHANGED
@@ -13,7 +13,7 @@ const handleVirtualPath = (documents) => {
13
13
  const filepathMap = Object.create(null);
14
14
  return documents.map(source => {
15
15
  var _a;
16
- const { location } = source;
16
+ const location = source.location;
17
17
  if (['.gql', '.graphql'].some(extension => location.endsWith(extension))) {
18
18
  return source;
19
19
  }
@@ -74,15 +74,17 @@ function getDocuments(project) {
74
74
  // Since the siblings array is cached, we can use it as cache key.
75
75
  // We should get the same array reference each time we get
76
76
  // to this point for the same graphql project
77
- if (siblingOperationsCache.has(siblings)) {
78
- return siblingOperationsCache.get(siblings);
77
+ const value = siblingOperationsCache.get(siblings);
78
+ if (value) {
79
+ return value;
79
80
  }
80
81
  let fragmentsCache = null;
81
82
  const getFragments = () => {
83
+ var _a;
82
84
  if (fragmentsCache === null) {
83
85
  const result = [];
84
86
  for (const source of siblings) {
85
- for (const definition of source.document.definitions) {
87
+ for (const definition of ((_a = source.document) === null || _a === void 0 ? void 0 : _a.definitions) || []) {
86
88
  if (definition.kind === graphql_1.Kind.FRAGMENT_DEFINITION) {
87
89
  result.push({
88
90
  filePath: source.location,
@@ -97,10 +99,11 @@ function getDocuments(project) {
97
99
  };
98
100
  let cachedOperations = null;
99
101
  const getOperations = () => {
102
+ var _a;
100
103
  if (cachedOperations === null) {
101
104
  const result = [];
102
105
  for (const source of siblings) {
103
- for (const definition of source.document.definitions) {
106
+ for (const definition of ((_a = source.document) === null || _a === void 0 ? void 0 : _a.definitions) || []) {
104
107
  if (definition.kind === graphql_1.Kind.OPERATION_DEFINITION) {
105
108
  result.push({
106
109
  filePath: source.location,
@@ -4,7 +4,7 @@ exports.convertToESTree = void 0;
4
4
  const graphql_1 = require("graphql");
5
5
  const utils_js_1 = require("./utils.js");
6
6
  function convertToESTree(node, schema) {
7
- const typeInfo = schema ? new graphql_1.TypeInfo(schema) : null;
7
+ const typeInfo = schema && new graphql_1.TypeInfo(schema);
8
8
  const visitor = {
9
9
  leave(node, key, parent) {
10
10
  const leadingComments = 'description' in node && node.description
package/cjs/parser.js CHANGED
@@ -25,7 +25,7 @@ function parseForESLint(code, options) {
25
25
  const realFilepath = filePath.replace(utils_js_1.VIRTUAL_DOCUMENT_REGEX, '');
26
26
  const project = gqlConfig.getProjectForFile(realFilepath);
27
27
  const schema = (0, schema_js_1.getSchema)(project, options.schemaOptions);
28
- const rootTree = (0, index_js_1.convertToESTree)(document, schema instanceof graphql_1.GraphQLSchema ? schema : null);
28
+ const rootTree = (0, index_js_1.convertToESTree)(document, schema instanceof graphql_1.GraphQLSchema ? schema : undefined);
29
29
  return {
30
30
  services: {
31
31
  schema,
@@ -43,7 +43,9 @@ function parseForESLint(code, options) {
43
43
  };
44
44
  }
45
45
  catch (error) {
46
- error.message = `[graphql-eslint] ${error.message}`;
46
+ if (error instanceof Error) {
47
+ error.message = `[graphql-eslint] ${error.message}`;
48
+ }
47
49
  // In case of GraphQL parser error, we report it to ESLint as a parser error that matches the requirements
48
50
  // of ESLint. This will make sure to display it correctly in IDEs and lint results.
49
51
  if (error instanceof graphql_1.GraphQLError) {
package/cjs/processor.js CHANGED
@@ -26,7 +26,7 @@ exports.processor = {
26
26
  ...modules.map(({ identifier }) => identifier),
27
27
  ...(0, utils_1.asArray)(globalGqlIdentifierName),
28
28
  gqlMagicComment,
29
- ].filter(Boolean)),
29
+ ].filter(utils_js_1.truthy)),
30
30
  ];
31
31
  }
32
32
  if (keywords.every(keyword => !code.includes(keyword))) {
@@ -48,7 +48,9 @@ exports.processor = {
48
48
  return [...blocks, code /* source code must be provided and be last */];
49
49
  }
50
50
  catch (error) {
51
- error.message = `[graphql-eslint] Error while preprocessing "${(0, path_1.relative)(utils_js_1.CWD, filePath)}" file\n\n${error.message}`;
51
+ if (error instanceof Error) {
52
+ error.message = `[graphql-eslint] Error while preprocessing "${(0, path_1.relative)(utils_js_1.CWD, filePath)}" file\n\n${error.message}`;
53
+ }
52
54
  // eslint-disable-next-line no-console
53
55
  console.error(error);
54
56
  // in case of parsing error return code as is
@@ -228,7 +228,7 @@ exports.rule = {
228
228
  : node;
229
229
  return [from.range[0], to.range[1]];
230
230
  }
231
- function checkNodes(nodes) {
231
+ function checkNodes(nodes = []) {
232
232
  var _a, _b, _c, _d;
233
233
  // Starts from 1, ignore nodes.length <= 1
234
234
  for (let i = 1; i < nodes.length; i += 1) {
@@ -273,6 +273,7 @@ exports.rule = {
273
273
  }
274
274
  }
275
275
  context.report({
276
+ // @ts-expect-error can't be undefined
276
277
  node: ('alias' in currNode && currNode.alias) || currNode.name,
277
278
  messageId: RULE_ID,
278
279
  data: {
@@ -305,7 +306,7 @@ exports.rule = {
305
306
  graphql_1.Kind.INPUT_OBJECT_TYPE_EXTENSION,
306
307
  ],
307
308
  ]
308
- .filter(Boolean)
309
+ .filter(utils_js_1.truthy)
309
310
  .flat();
310
311
  const fieldsSelector = kinds.join(',');
311
312
  const hasEnumValues = ((_b = opts.values) === null || _b === void 0 ? void 0 : _b[0]) === graphql_1.Kind.ENUM_TYPE_DEFINITION;
@@ -330,7 +331,8 @@ exports.rule = {
330
331
  }
331
332
  if (hasVariables) {
332
333
  listeners.OperationDefinition = (node) => {
333
- checkNodes(node.variableDefinitions.map(varDef => varDef.variable));
334
+ var _a;
335
+ checkNodes((_a = node.variableDefinitions) === null || _a === void 0 ? void 0 : _a.map(varDef => varDef.variable));
334
336
  };
335
337
  }
336
338
  if (argumentsSelector) {
@@ -46,10 +46,10 @@ function validateDocument({ context, schema = null, documentNode, rule, hasDidYo
46
46
  });
47
47
  }
48
48
  }
49
- catch (e) {
49
+ catch (error) {
50
50
  context.report({
51
51
  loc: utils_js_1.REPORT_ON_FIRST_CHARACTER,
52
- message: e.message,
52
+ message: error.message,
53
53
  });
54
54
  }
55
55
  }
@@ -186,10 +186,13 @@ exports.GRAPHQL_JS_VALIDATIONS = Object.assign({}, validationToRule({
186
186
  if (ignoreClientDirectives.length === 0) {
187
187
  return documentNode;
188
188
  }
189
- const filterDirectives = (node) => ({
190
- ...node,
191
- directives: node.directives.filter(directive => !ignoreClientDirectives.includes(directive.name.value)),
192
- });
189
+ const filterDirectives = (node) => {
190
+ var _a;
191
+ return ({
192
+ ...node,
193
+ directives: (_a = node.directives) === null || _a === void 0 ? void 0 : _a.filter(directive => !ignoreClientDirectives.includes(directive.name.value)),
194
+ });
195
+ };
193
196
  return (0, graphql_1.visit)(documentNode, {
194
197
  Field: filterDirectives,
195
198
  OperationDefinition: filterDirectives,
@@ -79,12 +79,12 @@ exports.rule = {
79
79
  const options = {
80
80
  checkInputType: false,
81
81
  caseSensitiveInputType: true,
82
- checkQueries: false,
83
82
  checkMutations: true,
84
83
  ...context.options[0],
85
84
  };
86
- const shouldCheckType = node => (options.checkMutations && isMutationType(node)) ||
87
- (options.checkQueries && isQueryType(node));
85
+ const shouldCheckType = (node) => (options.checkMutations && isMutationType(node)) ||
86
+ (options.checkQueries && isQueryType(node)) ||
87
+ false;
88
88
  const listeners = {
89
89
  'FieldDefinition > InputValueDefinition[name.value!=input] > Name'(node) {
90
90
  if (shouldCheckType(node.parent.parent.parent)) {
@@ -104,9 +104,10 @@ exports.rule = {
104
104
  };
105
105
  if (options.checkInputType) {
106
106
  listeners['FieldDefinition > InputValueDefinition NamedType'] = (node) => {
107
- const findInputType = item => {
107
+ const findInputType = (item) => {
108
108
  let currentNode = item;
109
109
  while (currentNode.type !== graphql_1.Kind.INPUT_VALUE_DEFINITION) {
110
+ // @ts-expect-error TODO try fix type error
110
111
  currentNode = currentNode.parent;
111
112
  }
112
113
  return currentNode;
@@ -215,7 +215,7 @@ exports.rule = {
215
215
  const options = context.options[0] || {};
216
216
  const { allowLeadingUnderscore, allowTrailingUnderscore, types, ...restOptions } = options;
217
217
  function normalisePropertyOption(kind) {
218
- const style = restOptions[kind] || types;
218
+ const style = (restOptions[kind] || types);
219
219
  return typeof style === 'object' ? style : { style };
220
220
  }
221
221
  function report(node, message, suggestedName) {
@@ -301,7 +301,7 @@ exports.rule = {
301
301
  if (!allowTrailingUnderscore) {
302
302
  listeners['Name[value=/_$/]:matches([parent.kind!=Field], [parent.kind=Field][parent.alias])'] = checkUnderscore(false);
303
303
  }
304
- const selectors = new Set([types && utils_js_1.TYPES_KINDS, Object.keys(restOptions)].flat().filter(Boolean));
304
+ const selectors = new Set([types && utils_js_1.TYPES_KINDS, Object.keys(restOptions)].flat().filter(utils_js_1.truthy));
305
305
  for (const selector of selectors) {
306
306
  listeners[selector] = checkNode(selector);
307
307
  }
@@ -40,9 +40,10 @@ exports.rule = {
40
40
  const selector = [graphql_1.Kind.ENUM_TYPE_DEFINITION, graphql_1.Kind.ENUM_TYPE_EXTENSION].join(',');
41
41
  return {
42
42
  [selector](node) {
43
- const duplicates = node.values.filter((item, index, array) => array.findIndex(v => v.name.value.toLowerCase() === item.name.value.toLowerCase()) !==
43
+ var _a;
44
+ const duplicates = (_a = node.values) === null || _a === void 0 ? void 0 : _a.filter((item, index, array) => array.findIndex(v => v.name.value.toLowerCase() === item.name.value.toLowerCase()) !==
44
45
  index);
45
- for (const duplicate of duplicates) {
46
+ for (const duplicate of duplicates || []) {
46
47
  const enumName = duplicate.name.value;
47
48
  context.report({
48
49
  node: duplicate.name,
@@ -89,13 +89,13 @@ exports.rule = {
89
89
  return {
90
90
  OperationDefinition(node) {
91
91
  const set = new Set();
92
- for (const varDef of node.variableDefinitions) {
92
+ for (const varDef of node.variableDefinitions || []) {
93
93
  checkNode(set, varDef.variable.name);
94
94
  }
95
95
  },
96
96
  Field(node) {
97
97
  const set = new Set();
98
- for (const arg of node.arguments) {
98
+ for (const arg of node.arguments || []) {
99
99
  checkNode(set, arg.name);
100
100
  }
101
101
  },
@@ -81,6 +81,9 @@ exports.rule = {
81
81
  });
82
82
  }
83
83
  }
84
+ if (!next) {
85
+ break;
86
+ }
84
87
  token = next;
85
88
  }
86
89
  },
@@ -60,7 +60,7 @@ exports.rule = {
60
60
  disallow.has('mutation') && schema.getMutationType(),
61
61
  disallow.has('subscription') && schema.getSubscriptionType(),
62
62
  ]
63
- .filter(Boolean)
63
+ .filter(utils_js_1.truthy)
64
64
  .map(type => type.name)
65
65
  .join('|');
66
66
  if (!rootTypeNames) {
@@ -40,7 +40,7 @@ exports.rule = {
40
40
  'ObjectTypeDefinition, ObjectTypeExtension, InterfaceTypeDefinition, InterfaceTypeExtension'(node) {
41
41
  const typeName = node.name.value;
42
42
  const lowerTypeName = typeName.toLowerCase();
43
- for (const field of node.fields) {
43
+ for (const field of node.fields || []) {
44
44
  const fieldName = field.name.value;
45
45
  if (fieldName.toLowerCase().startsWith(lowerTypeName)) {
46
46
  context.report({
@@ -52,7 +52,7 @@ function getReachableTypes(schema) {
52
52
  (0, graphql_1.visit)(astNode, visitor);
53
53
  }
54
54
  }
55
- else if (type.astNode) {
55
+ else if (type === null || type === void 0 ? void 0 : type.astNode) {
56
56
  // astNode can be undefined for ID, String, Boolean
57
57
  (0, graphql_1.visit)(type.astNode, visitor);
58
58
  }
@@ -72,11 +72,12 @@ exports.rule = {
72
72
  const { includeBoth = true } = context.options[0] || {};
73
73
  return {
74
74
  'FieldDefinition > .gqlType Name[value=/Connection$/]'(node) {
75
+ var _a;
75
76
  let fieldNode = node.parent;
76
77
  while (fieldNode.kind !== graphql_1.Kind.FIELD_DEFINITION) {
77
78
  fieldNode = fieldNode.parent;
78
79
  }
79
- const args = Object.fromEntries(fieldNode.arguments.map(argument => [argument.name.value, argument]));
80
+ const args = Object.fromEntries(((_a = fieldNode.arguments) === null || _a === void 0 ? void 0 : _a.map(argument => [argument.name.value, argument])) || []);
80
81
  const hasForwardPagination = Boolean(args.first && args.after);
81
82
  const hasBackwardPagination = Boolean(args.last && args.before);
82
83
  if (!hasForwardPagination && !hasBackwardPagination) {
@@ -20,8 +20,8 @@ exports.NON_OBJECT_TYPES = [
20
20
  graphql_1.Kind.INTERFACE_TYPE_EXTENSION,
21
21
  ];
22
22
  const notConnectionTypesSelector = `:matches(${exports.NON_OBJECT_TYPES})[name.value=/Connection$/] > .name`;
23
- const hasEdgesField = (node) => node.fields.some(field => field.name.value === 'edges');
24
- const hasPageInfoField = (node) => node.fields.some(field => field.name.value === 'pageInfo');
23
+ const hasEdgesField = (node) => { var _a; return (_a = node.fields) === null || _a === void 0 ? void 0 : _a.some(field => field.name.value === 'edges'); };
24
+ const hasPageInfoField = (node) => { var _a; return (_a = node.fields) === null || _a === void 0 ? void 0 : _a.some(field => field.name.value === 'pageInfo'); };
25
25
  exports.rule = {
26
26
  meta: {
27
27
  type: 'problem',
@@ -19,12 +19,13 @@ function getEdgeTypes(schema) {
19
19
  const edgeTypes = new Set();
20
20
  const visitor = {
21
21
  ObjectTypeDefinition(node) {
22
+ var _a;
22
23
  const typeName = node.name.value;
23
24
  const hasConnectionSuffix = typeName.endsWith('Connection');
24
25
  if (!hasConnectionSuffix) {
25
26
  return;
26
27
  }
27
- const edges = node.fields.find(field => field.name.value === 'edges');
28
+ const edges = (_a = node.fields) === null || _a === void 0 ? void 0 : _a.find(field => field.name.value === 'edges');
28
29
  if (edges) {
29
30
  const edgesTypeName = (0, utils_js_1.getTypeName)(edges);
30
31
  const edgesType = schema.getType(edgesTypeName);
@@ -116,7 +117,8 @@ exports.rule = {
116
117
  const isNamedOrNonNullNamed = (node) => node.kind === graphql_1.Kind.NAMED_TYPE ||
117
118
  (node.kind === graphql_1.Kind.NON_NULL_TYPE && node.gqlType.kind === graphql_1.Kind.NAMED_TYPE);
118
119
  const checkNodeField = (node) => {
119
- const nodeField = node.fields.find(field => field.name.value === 'node');
120
+ var _a, _b;
121
+ const nodeField = (_a = node.fields) === null || _a === void 0 ? void 0 : _a.find(field => field.name.value === 'node');
120
122
  const message = 'return either a Scalar, Enum, Object, Interface, Union, or a non-null wrapper around one of those types.';
121
123
  if (!nodeField) {
122
124
  context.report({
@@ -133,14 +135,15 @@ exports.rule = {
133
135
  if (!(0, graphql_1.isObjectType)(type)) {
134
136
  return;
135
137
  }
136
- const implementsNode = type.astNode.interfaces.some(n => n.name.value === 'Node');
138
+ const implementsNode = (_b = type.astNode.interfaces) === null || _b === void 0 ? void 0 : _b.some(n => n.name.value === 'Node');
137
139
  if (!implementsNode) {
138
140
  context.report({ node: node.name, messageId: MESSAGE_SHOULD_IMPLEMENTS_NODE });
139
141
  }
140
142
  }
141
143
  };
142
144
  const checkCursorField = (node) => {
143
- const cursorField = node.fields.find(field => field.name.value === 'cursor');
145
+ var _a;
146
+ const cursorField = (_a = node.fields) === null || _a === void 0 ? void 0 : _a.find(field => field.name.value === 'cursor');
144
147
  const message = 'return either a String, Scalar, or a non-null wrapper wrapper around one of those types.';
145
148
  if (!cursorField) {
146
149
  context.report({
@@ -61,7 +61,8 @@ exports.rule = {
61
61
  context.report({ node, messageId: MESSAGE_MUST_BE_OBJECT_TYPE });
62
62
  },
63
63
  'ObjectTypeDefinition[name.value=PageInfo]'(node) {
64
- const fieldMap = Object.fromEntries(node.fields.map(field => [field.name.value, field]));
64
+ var _a;
65
+ const fieldMap = Object.fromEntries(((_a = node.fields) === null || _a === void 0 ? void 0 : _a.map(field => [field.name.value, field])) || []);
65
66
  const checkField = (fieldName, typeName) => {
66
67
  const field = fieldMap[fieldName];
67
68
  let isAllowedType = false;
@@ -71,9 +71,9 @@ exports.rule = {
71
71
  create(context) {
72
72
  return {
73
73
  'Directive[name.value=deprecated]'(node) {
74
- var _a;
74
+ var _a, _b;
75
75
  const argName = ((_a = context.options[0]) === null || _a === void 0 ? void 0 : _a.argumentName) || 'deletionDate';
76
- const deletionDateNode = node.arguments.find(arg => arg.name.value === argName);
76
+ const deletionDateNode = (_b = node.arguments) === null || _b === void 0 ? void 0 : _b.find(arg => arg.name.value === argName);
77
77
  if (!deletionDateNode) {
78
78
  context.report({
79
79
  node: node.name,
@@ -42,7 +42,8 @@ exports.rule = {
42
42
  create(context) {
43
43
  return {
44
44
  'Directive[name.value=deprecated]'(node) {
45
- const reasonArgument = node.arguments.find(arg => arg.name.value === 'reason');
45
+ var _a;
46
+ const reasonArgument = (_a = node.arguments) === null || _a === void 0 ? void 0 : _a.find(arg => arg.name.value === 'reason');
46
47
  const value = reasonArgument && String((0, index_js_1.valueFromNode)(reasonArgument.value)).trim();
47
48
  if (!value) {
48
49
  context.report({
@@ -167,7 +167,7 @@ exports.rule = {
167
167
  if (isOperation) {
168
168
  const rawNode = node.rawNode();
169
169
  const { prev, line } = rawNode.loc.startToken;
170
- if (prev.kind === graphql_1.TokenKind.COMMENT) {
170
+ if ((prev === null || prev === void 0 ? void 0 : prev.kind) === graphql_1.TokenKind.COMMENT) {
171
171
  const value = prev.value.trim();
172
172
  const linesBefore = line - prev.line;
173
173
  if (!value.startsWith('eslint') && linesBefore === 1) {
@@ -58,7 +58,7 @@ exports.rule = {
58
58
  const graphQLType = schema.getType(typeName);
59
59
  if ((0, graphql_1.isObjectType)(graphQLType)) {
60
60
  const { fields } = graphQLType.astNode;
61
- const hasQueryType = fields.some(field => (0, utils_js_1.getTypeName)(field) === queryType.name);
61
+ const hasQueryType = fields === null || fields === void 0 ? void 0 : fields.some(field => (0, utils_js_1.getTypeName)(field) === queryType.name);
62
62
  if (!hasQueryType) {
63
63
  context.report({
64
64
  node,
@@ -108,7 +108,8 @@ exports.rule = {
108
108
  }
109
109
  const checkedFragmentSpreads = new Set();
110
110
  const visitor = (0, graphql_1.visitWithTypeInfo)(typeInfo, {
111
- SelectionSet(node, key, parent) {
111
+ SelectionSet(node, key, _parent) {
112
+ const parent = _parent;
112
113
  if (parent.kind === graphql_1.Kind.FRAGMENT_DEFINITION) {
113
114
  checkedFragmentSpreads.add(parent.name.value);
114
115
  }
@@ -38,7 +38,7 @@ exports.rule = {
38
38
  },
39
39
  create(context) {
40
40
  return {
41
- 'Directive[name.value=oneOf]'({ parent, }) {
41
+ 'Directive[name.value=oneOf]'({ parent }) {
42
42
  const isTypeOrInput = [
43
43
  graphql_1.Kind.OBJECT_TYPE_DEFINITION,
44
44
  graphql_1.Kind.INPUT_OBJECT_TYPE_DEFINITION,
@@ -46,7 +46,7 @@ exports.rule = {
46
46
  if (!isTypeOrInput) {
47
47
  return;
48
48
  }
49
- for (const field of parent.fields) {
49
+ for (const field of parent.fields || []) {
50
50
  if (field.gqlType.kind === graphql_1.Kind.NON_NULL_TYPE) {
51
51
  context.report({
52
52
  node: field.name,
@@ -41,9 +41,10 @@ exports.rule = {
41
41
  create(context) {
42
42
  return {
43
43
  'Directive[name.value=oneOf][parent.kind=ObjectTypeDefinition]'({ parent, }) {
44
+ var _a;
44
45
  const requiredFields = ['error', 'ok'];
45
46
  for (const fieldName of requiredFields) {
46
- if (!parent.fields.some(field => field.name.value === fieldName)) {
47
+ if (!((_a = parent.fields) === null || _a === void 0 ? void 0 : _a.some(field => field.name.value === fieldName))) {
47
48
  context.report({
48
49
  node: parent.name,
49
50
  messageId: RULE_ID,
@@ -122,19 +122,19 @@ exports.rule = {
122
122
  schema.getMutationType(),
123
123
  schema.getSubscriptionType(),
124
124
  ]
125
- .filter(Boolean)
125
+ .filter(utils_js_1.truthy)
126
126
  .map(type => type.name);
127
127
  const selector = `ObjectTypeDefinition[name.value!=/^(${rootTypeNames.join('|')})$/]`;
128
128
  return {
129
129
  [selector](node) {
130
- var _a, _b;
130
+ var _a, _b, _c;
131
131
  const typeName = node.name.value;
132
132
  const shouldIgnoreNode = ((_a = options.exceptions.types) === null || _a === void 0 ? void 0 : _a.includes(typeName)) ||
133
133
  ((_b = options.exceptions.suffixes) === null || _b === void 0 ? void 0 : _b.some(suffix => typeName.endsWith(suffix)));
134
134
  if (shouldIgnoreNode) {
135
135
  return;
136
136
  }
137
- const validIds = node.fields.filter(field => {
137
+ const validIds = (_c = node.fields) === null || _c === void 0 ? void 0 : _c.filter(field => {
138
138
  const fieldNode = field.rawNode();
139
139
  const isValidIdName = options.acceptedIdNames.includes(fieldNode.name.value);
140
140
  // To be a valid type, it must be non-null and one of the accepted types.
@@ -148,7 +148,7 @@ exports.rule = {
148
148
  // Usually, there should be only one unique identifier field per type.
149
149
  // Some clients allow multiple fields to be used. If more people need this,
150
150
  // we can extend this rule later.
151
- if (validIds.length !== 1) {
151
+ if ((validIds === null || validIds === void 0 ? void 0 : validIds.length) !== 1) {
152
152
  const pluralNamesSuffix = options.acceptedIdNames.length > 1 ? 's' : '';
153
153
  const pluralTypesSuffix = options.acceptedIdTypes.length > 1 ? 's' : '';
154
154
  context.report({
@@ -27,6 +27,7 @@ const checkNode = (context, node, ruleId) => {
27
27
  .map(f => `\t${(0, path_1.relative)(utils_js_1.CWD, f.filePath.replace(utils_js_1.VIRTUAL_DOCUMENT_REGEX, ''))}`)
28
28
  .join('\n'),
29
29
  },
30
+ // @ts-expect-error name will exist
30
31
  node: node.name,
31
32
  });
32
33
  }
package/cjs/schema.js CHANGED
@@ -34,7 +34,9 @@ function getSchema(project, schemaOptions) {
34
34
  schemaCache.set(schemaKey, schema);
35
35
  }
36
36
  catch (error) {
37
- error.message = chalk_1.default.red(`Error while loading schema: ${error.message}`);
37
+ if (error instanceof Error) {
38
+ error.message = chalk_1.default.red(`Error while loading schema: ${error.message}`);
39
+ }
38
40
  schema = error;
39
41
  }
40
42
  return schema;
package/cjs/testkit.js CHANGED
@@ -1,7 +1,7 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.GraphQLRuleTester = void 0;
4
- /* eslint-env jest */
4
+ /* eslint-env vitest */
5
5
  const fs_1 = require("fs");
6
6
  const path_1 = require("path");
7
7
  const eslint_1 = require("eslint");
@@ -60,7 +60,7 @@ class GraphQLRuleTester extends eslint_1.RuleTester {
60
60
  // continue;
61
61
  // }
62
62
  //
63
- // const verifyConfig = getVerifyConfig(ruleId, this.config, testCase);
63
+ // const verifyConfig = getVerifyConfig<Options>(ruleId, this.config, testCase);
64
64
  // defineParser(linter, verifyConfig.parser);
65
65
  //
66
66
  // const messages = linter.verify(code, verifyConfig, { filename });
@@ -94,11 +94,10 @@ class GraphQLRuleTester extends eslint_1.RuleTester {
94
94
  }
95
95
  const codeWithMessage = printCode(code, message, 1);
96
96
  messageForSnapshot.push(printWithIndex('#### ❌ Error', index, messages.length), indentCode(codeWithMessage));
97
- const { suggestions } = message;
98
97
  // Don't print suggestions in snapshots for too big codes
99
- if (suggestions && (code.match(/\n/g) || '').length < 1000) {
98
+ if (message.suggestions && (code.match(/\n/g) || '').length < 1000) {
100
99
  for (const [i, suggestion] of message.suggestions.entries()) {
101
- const title = printWithIndex('#### 💡 Suggestion', i, suggestions.length, suggestion.desc);
100
+ const title = printWithIndex('#### 💡 Suggestion', i, message.suggestions.length, suggestion.desc);
102
101
  const output = applyFix(code, suggestion.fix);
103
102
  const codeFrame = printCode(output, { line: 0, column: 0 });
104
103
  messageForSnapshot.push(title, indentCode(codeFrame, 2));
@@ -111,9 +110,7 @@ class GraphQLRuleTester extends eslint_1.RuleTester {
111
110
  messageForSnapshot.push('#### 🔧 Autofix output', indentCode(printCode(output)));
112
111
  }
113
112
  }
114
- // @ts-expect-error -- we should import `vitest` but somebody could use globals from `jest`
115
113
  it(name || `Invalid #${idx + 1}`, () => {
116
- // @ts-expect-error -- ^ same
117
114
  expect(messageForSnapshot.join('\n\n')).toMatchSnapshot();
118
115
  });
119
116
  }
package/cjs/utils.js CHANGED
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.englishJoinWords = exports.ARRAY_DEFAULT_OPTIONS = exports.REPORT_ON_FIRST_CHARACTER = exports.getLocation = exports.convertCase = exports.camelCase = exports.pascalCase = exports.TYPES_KINDS = exports.getTypeName = exports.CWD = exports.VIRTUAL_DOCUMENT_REGEX = exports.normalizePath = exports.logger = exports.requireGraphQLSchemaFromContext = exports.requireSiblingsOperations = void 0;
3
+ exports.truthy = exports.englishJoinWords = exports.ARRAY_DEFAULT_OPTIONS = exports.REPORT_ON_FIRST_CHARACTER = exports.getLocation = exports.convertCase = exports.camelCase = exports.pascalCase = exports.TYPES_KINDS = exports.getTypeName = exports.CWD = exports.VIRTUAL_DOCUMENT_REGEX = exports.normalizePath = exports.logger = exports.requireGraphQLSchemaFromContext = exports.requireSiblingsOperations = void 0;
4
4
  const tslib_1 = require("tslib");
5
5
  const graphql_1 = require("graphql");
6
6
  const lodash_lowercase_1 = tslib_1.__importDefault(require("lodash.lowercase"));
@@ -25,16 +25,18 @@ function requireGraphQLSchemaFromContext(ruleId, context) {
25
25
  }
26
26
  exports.requireGraphQLSchemaFromContext = requireGraphQLSchemaFromContext;
27
27
  exports.logger = {
28
+ error: (...args) =>
28
29
  // eslint-disable-next-line no-console
29
- error: (...args) => console.error(chalk_1.default.red('error'), '[graphql-eslint]', (0, chalk_1.default)(...args)),
30
+ console.error(chalk_1.default.red('error'), '[graphql-eslint]', (0, chalk_1.default)(...args)),
31
+ warn: (...args) =>
30
32
  // eslint-disable-next-line no-console
31
- warn: (...args) => console.warn(chalk_1.default.yellow('warning'), '[graphql-eslint]', (0, chalk_1.default)(...args)),
33
+ console.warn(chalk_1.default.yellow('warning'), '[graphql-eslint]', (0, chalk_1.default)(...args)),
32
34
  };
33
35
  const normalizePath = (path) => (path || '').replace(/\\/g, '/');
34
36
  exports.normalizePath = normalizePath;
35
37
  exports.VIRTUAL_DOCUMENT_REGEX = /\/\d+_document.graphql$/;
36
38
  exports.CWD = process.cwd();
37
- const getTypeName = (node) => 'type' in node ? (0, exports.getTypeName)(node.type) : node.name.value;
39
+ const getTypeName = (node) => 'type' in node ? (0, exports.getTypeName)(node.type) : 'name' in node && node.name ? node.name.value : '';
38
40
  exports.getTypeName = getTypeName;
39
41
  exports.TYPES_KINDS = [
40
42
  graphql_1.Kind.OBJECT_TYPE_DEFINITION,
@@ -92,5 +94,9 @@ exports.ARRAY_DEFAULT_OPTIONS = {
92
94
  type: 'string',
93
95
  },
94
96
  };
95
- const englishJoinWords = words => new Intl.ListFormat('en-US', { type: 'disjunction' }).format(words);
97
+ const englishJoinWords = (words) => new Intl.ListFormat('en-US', { type: 'disjunction' }).format(words);
96
98
  exports.englishJoinWords = englishJoinWords;
99
+ function truthy(value) {
100
+ return Boolean(value);
101
+ }
102
+ exports.truthy = truthy;
package/esm/cache.js CHANGED
@@ -11,11 +11,12 @@ export class ModuleCache {
11
11
  log('setting entry for', cacheKey);
12
12
  }
13
13
  get(cacheKey, settings = { lifetime: 10 /* seconds */ }) {
14
- if (!this.map.has(cacheKey)) {
14
+ const value = this.map.get(cacheKey);
15
+ if (!value) {
15
16
  log('cache miss for', cacheKey);
16
17
  return;
17
18
  }
18
- const { lastSeen, result } = this.map.get(cacheKey);
19
+ const { lastSeen, result } = value;
19
20
  // check freshness
20
21
  if (process.env.NODE /* don't check for ESLint CLI */ ||
21
22
  process.hrtime(lastSeen)[0] < settings.lifetime) {