@graphql-eslint/eslint-plugin 4.3.0 → 4.4.0-alpha-20241207210859-41eb4549764dc0314b5bd4f257ea6667b178540e

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 (110) hide show
  1. package/cjs/cache.js +6 -2
  2. package/cjs/configs/operations-all.js +2 -2
  3. package/cjs/configs/schema-all.js +2 -2
  4. package/cjs/configs/schema-recommended.js +1 -1
  5. package/cjs/documents.js +13 -7
  6. package/cjs/estree-converter/converter.js +17 -8
  7. package/cjs/estree-converter/utils.js +22 -9
  8. package/cjs/graphql-config.js +13 -6
  9. package/cjs/index.d.cts +18 -4
  10. package/cjs/meta.js +1 -1
  11. package/cjs/parser.js +36 -9
  12. package/cjs/processor.js +48 -20
  13. package/cjs/rules/alphabetize/index.js +99 -47
  14. package/cjs/rules/description-style/index.js +10 -6
  15. package/cjs/rules/graphql-js-validation.js +142 -108
  16. package/cjs/rules/index.d.cts +18 -4
  17. package/cjs/rules/input-name/index.js +51 -38
  18. package/cjs/rules/lone-executable-definition/index.js +15 -6
  19. package/cjs/rules/match-document-filename/index.d.cts +4 -3
  20. package/cjs/rules/match-document-filename/index.js +63 -37
  21. package/cjs/rules/naming-convention/index.d.cts +6 -10
  22. package/cjs/rules/naming-convention/index.js +179 -82
  23. package/cjs/rules/no-anonymous-operations/index.js +8 -5
  24. package/cjs/rules/no-deprecated/index.js +27 -13
  25. package/cjs/rules/no-duplicate-fields/index.js +15 -8
  26. package/cjs/rules/no-hashtag-description/index.js +18 -10
  27. package/cjs/rules/no-one-place-fragments/index.js +17 -10
  28. package/cjs/rules/no-root-type/index.js +15 -8
  29. package/cjs/rules/no-scalar-result-type-on-mutation/index.js +20 -12
  30. package/cjs/rules/no-typename-prefix/index.js +25 -21
  31. package/cjs/rules/no-unreachable-types/index.js +34 -17
  32. package/cjs/rules/no-unused-fields/index.js +56 -30
  33. package/cjs/rules/relay-arguments/index.js +31 -13
  34. package/cjs/rules/relay-connection-types/index.js +31 -9
  35. package/cjs/rules/relay-edge-types/index.js +84 -41
  36. package/cjs/rules/relay-page-info/index.js +31 -14
  37. package/cjs/rules/require-deprecation-date/index.js +20 -9
  38. package/cjs/rules/require-deprecation-reason/index.js +8 -5
  39. package/cjs/rules/require-description/index.d.cts +79 -13
  40. package/cjs/rules/require-description/index.js +67 -49
  41. package/cjs/rules/require-field-of-type-query-in-mutation-result/index.js +21 -10
  42. package/cjs/rules/require-import-fragment/index.js +20 -11
  43. package/cjs/rules/require-nullable-fields-with-oneof/index.js +12 -5
  44. package/cjs/rules/require-nullable-result-in-root/index.js +32 -27
  45. package/cjs/rules/require-selections/index.js +88 -46
  46. package/cjs/rules/require-type-pattern-with-oneof/index.js +14 -10
  47. package/cjs/rules/selection-set-depth/index.js +19 -10
  48. package/cjs/rules/strict-id-in-types/index.js +32 -19
  49. package/cjs/rules/unique-enum-value-names/index.js +4 -3
  50. package/cjs/rules/unique-fragment-name/index.js +25 -18
  51. package/cjs/rules/unique-operation-name/index.js +5 -5
  52. package/cjs/schema.js +14 -8
  53. package/cjs/siblings.js +60 -32
  54. package/cjs/utils.js +23 -9
  55. package/esm/cache.js +6 -2
  56. package/esm/configs/operations-all.js +2 -2
  57. package/esm/configs/schema-all.js +2 -2
  58. package/esm/configs/schema-recommended.js +1 -1
  59. package/esm/documents.js +13 -7
  60. package/esm/estree-converter/converter.js +17 -8
  61. package/esm/estree-converter/utils.js +22 -9
  62. package/esm/graphql-config.js +13 -6
  63. package/esm/index.d.ts +18 -4
  64. package/esm/meta.js +1 -1
  65. package/esm/parser.js +36 -9
  66. package/esm/processor.js +48 -20
  67. package/esm/rules/alphabetize/index.js +99 -47
  68. package/esm/rules/description-style/index.js +10 -6
  69. package/esm/rules/graphql-js-validation.js +142 -108
  70. package/esm/rules/index.d.ts +18 -4
  71. package/esm/rules/input-name/index.js +51 -38
  72. package/esm/rules/lone-executable-definition/index.js +15 -6
  73. package/esm/rules/match-document-filename/index.d.ts +4 -3
  74. package/esm/rules/match-document-filename/index.js +63 -37
  75. package/esm/rules/naming-convention/index.d.ts +6 -10
  76. package/esm/rules/naming-convention/index.js +179 -82
  77. package/esm/rules/no-anonymous-operations/index.js +8 -5
  78. package/esm/rules/no-deprecated/index.js +27 -13
  79. package/esm/rules/no-duplicate-fields/index.js +15 -8
  80. package/esm/rules/no-hashtag-description/index.js +18 -10
  81. package/esm/rules/no-one-place-fragments/index.js +17 -10
  82. package/esm/rules/no-root-type/index.js +15 -8
  83. package/esm/rules/no-scalar-result-type-on-mutation/index.js +20 -12
  84. package/esm/rules/no-typename-prefix/index.js +25 -21
  85. package/esm/rules/no-unreachable-types/index.js +34 -17
  86. package/esm/rules/no-unused-fields/index.js +56 -30
  87. package/esm/rules/relay-arguments/index.js +31 -13
  88. package/esm/rules/relay-connection-types/index.js +31 -9
  89. package/esm/rules/relay-edge-types/index.js +84 -41
  90. package/esm/rules/relay-page-info/index.js +31 -14
  91. package/esm/rules/require-deprecation-date/index.js +20 -9
  92. package/esm/rules/require-deprecation-reason/index.js +8 -5
  93. package/esm/rules/require-description/index.d.ts +79 -13
  94. package/esm/rules/require-description/index.js +67 -49
  95. package/esm/rules/require-field-of-type-query-in-mutation-result/index.js +21 -10
  96. package/esm/rules/require-import-fragment/index.js +20 -11
  97. package/esm/rules/require-nullable-fields-with-oneof/index.js +12 -5
  98. package/esm/rules/require-nullable-result-in-root/index.js +32 -27
  99. package/esm/rules/require-selections/index.js +88 -46
  100. package/esm/rules/require-type-pattern-with-oneof/index.js +14 -10
  101. package/esm/rules/selection-set-depth/index.js +19 -10
  102. package/esm/rules/strict-id-in-types/index.js +32 -19
  103. package/esm/rules/unique-enum-value-names/index.js +4 -3
  104. package/esm/rules/unique-fragment-name/index.js +25 -18
  105. package/esm/rules/unique-operation-name/index.js +5 -5
  106. package/esm/schema.js +15 -8
  107. package/esm/siblings.js +60 -32
  108. package/esm/utils.js +23 -9
  109. package/index.browser.js +1871 -1160
  110. package/package.json +1 -1
@@ -24,26 +24,33 @@ const KindToDisplayName = {
24
24
  [_graphql.Kind.OPERATION_DEFINITION]: "Operation",
25
25
  [_graphql.Kind.FRAGMENT_DEFINITION]: "Fragment",
26
26
  [_graphql.Kind.VARIABLE_DEFINITION]: "Variable"
27
- }, StyleToRegex = {
27
+ };
28
+ const StyleToRegex = {
28
29
  camelCase: /^[a-z][\dA-Za-z]*$/,
29
30
  PascalCase: /^[A-Z][\dA-Za-z]*$/,
30
31
  snake_case: /^[a-z][\d_a-z]*[\da-z]*$/,
31
32
  UPPER_CASE: /^[A-Z][\dA-Z_]*[\dA-Z]*$/
32
- }, ALLOWED_KINDS = Object.keys(KindToDisplayName).sort(), ALLOWED_STYLES = Object.keys(StyleToRegex), schemaOption = {
33
+ };
34
+ const ALLOWED_KINDS = Object.keys(KindToDisplayName).sort();
35
+ const ALLOWED_STYLES = Object.keys(StyleToRegex);
36
+ const schemaOption = {
33
37
  oneOf: [{ $ref: "#/definitions/asString" }, { $ref: "#/definitions/asObject" }]
34
- }, descriptionPrefixesSuffixes = (name) => `> [!WARNING]
38
+ };
39
+ const descriptionPrefixesSuffixes = (name, id) => `> [!WARNING]
35
40
  >
36
- > This option is deprecated and will be removed in the next major release. Use [\`${name}\`](#${name.toLowerCase()}-array) instead.`, schema = {
41
+ > This option is deprecated and will be removed in the next major release. Use [\`${name}\`](#${id}) instead.`;
42
+ const caseSchema = {
43
+ enum: ALLOWED_STYLES,
44
+ description: `One of: ${ALLOWED_STYLES.map((t) => `\`${t}\``).join(", ")}`
45
+ };
46
+ const schema = {
37
47
  definitions: {
38
- asString: {
39
- enum: ALLOWED_STYLES,
40
- description: `One of: ${ALLOWED_STYLES.map((t) => `\`${t}\``).join(", ")}`
41
- },
48
+ asString: caseSchema,
42
49
  asObject: {
43
50
  type: "object",
44
- additionalProperties: !1,
51
+ additionalProperties: false,
45
52
  properties: {
46
- style: { enum: ALLOWED_STYLES },
53
+ style: caseSchema,
47
54
  prefix: { type: "string" },
48
55
  suffix: { type: "string" },
49
56
  forbiddenPatterns: {
@@ -53,28 +60,25 @@ const KindToDisplayName = {
53
60
  },
54
61
  description: "Should be of instance of `RegEx`"
55
62
  },
56
- requiredPatterns: {
57
- ..._utilsjs.ARRAY_DEFAULT_OPTIONS,
58
- items: {
59
- type: "object"
60
- },
63
+ requiredPattern: {
64
+ type: "object",
61
65
  description: "Should be of instance of `RegEx`"
62
66
  },
63
67
  forbiddenPrefixes: {
64
68
  ..._utilsjs.ARRAY_DEFAULT_OPTIONS,
65
- description: descriptionPrefixesSuffixes("forbiddenPatterns")
69
+ description: descriptionPrefixesSuffixes("forbiddenPatterns", "forbiddenpatterns-array")
66
70
  },
67
71
  forbiddenSuffixes: {
68
72
  ..._utilsjs.ARRAY_DEFAULT_OPTIONS,
69
- description: descriptionPrefixesSuffixes("forbiddenPatterns")
73
+ description: descriptionPrefixesSuffixes("forbiddenPatterns", "forbiddenpatterns-array")
70
74
  },
71
75
  requiredPrefixes: {
72
76
  ..._utilsjs.ARRAY_DEFAULT_OPTIONS,
73
- description: descriptionPrefixesSuffixes("requiredPatterns")
77
+ description: descriptionPrefixesSuffixes("requiredPattern", "requiredpattern-object")
74
78
  },
75
79
  requiredSuffixes: {
76
80
  ..._utilsjs.ARRAY_DEFAULT_OPTIONS,
77
- description: descriptionPrefixesSuffixes("requiredPatterns")
81
+ description: descriptionPrefixesSuffixes("requiredPattern", "requiredpattern-object")
78
82
  },
79
83
  ignorePattern: {
80
84
  type: "string",
@@ -87,13 +91,12 @@ const KindToDisplayName = {
87
91
  maxItems: 1,
88
92
  items: {
89
93
  type: "object",
90
- additionalProperties: !1,
94
+ additionalProperties: false,
91
95
  properties: {
92
96
  types: {
93
97
  ...schemaOption,
94
98
  description: `Includes:
95
- ${_utilsjs.TYPES_KINDS.map((kind) => `- \`${kind}\``).join(`
96
- `)}`
99
+ ${_utilsjs.TYPES_KINDS.map((kind) => `- \`${kind}\``).join("\n")}`
97
100
  },
98
101
  ...Object.fromEntries(
99
102
  ALLOWED_KINDS.map((kind) => [
@@ -108,11 +111,11 @@ ${_utilsjs.TYPES_KINDS.map((kind) => `- \`${kind}\``).join(`
108
111
  ),
109
112
  allowLeadingUnderscore: {
110
113
  type: "boolean",
111
- default: !1
114
+ default: false
112
115
  },
113
116
  allowTrailingUnderscore: {
114
117
  type: "boolean",
115
- default: !1
118
+ default: false
116
119
  }
117
120
  },
118
121
  patternProperties: {
@@ -124,16 +127,16 @@ ${_utilsjs.TYPES_KINDS.map((kind) => `- \`${kind}\``).join(`
124
127
  "> Paste or drop code into the editor in [ASTExplorer](https://astexplorer.net) and inspect the generated AST to compose your selector.",
125
128
  ">",
126
129
  "> Example: pattern property `FieldDefinition[parent.name.value=Query]` will match only fields for type `Query`."
127
- ].join(`
128
- `)
130
+ ].join("\n")
129
131
  }
130
- }, rule = exports.rule = {
132
+ };
133
+ const rule = {
131
134
  meta: {
132
135
  type: "suggestion",
133
136
  docs: {
134
137
  description: "Require names to follow specified conventions.",
135
138
  category: ["Schema", "Operations"],
136
- recommended: !0,
139
+ recommended: true,
137
140
  url: "https://the-guild.dev/graphql/eslint/rules/naming-convention",
138
141
  examples: [
139
142
  {
@@ -150,7 +153,14 @@ ${_utilsjs.TYPES_KINDS.map((kind) => `- \`${kind}\``).join(`
150
153
  },
151
154
  {
152
155
  title: "Incorrect",
153
- usage: [{ FragmentDefinition: { style: "PascalCase", forbiddenSuffixes: ["Fragment"] } }],
156
+ usage: [
157
+ {
158
+ FragmentDefinition: {
159
+ style: "PascalCase",
160
+ forbiddenPatterns: [/(^fragment)|(fragment$)/i]
161
+ }
162
+ }
163
+ ],
154
164
  code: (
155
165
  /* GraphQL */
156
166
  `
@@ -162,7 +172,7 @@ ${_utilsjs.TYPES_KINDS.map((kind) => `- \`${kind}\``).join(`
162
172
  },
163
173
  {
164
174
  title: "Incorrect",
165
- usage: [{ "FieldDefinition[parent.name.value=Query]": { forbiddenPrefixes: ["get"] } }],
175
+ usage: [{ "FieldDefinition[parent.name.value=Query]": { forbiddenPatterns: [/^get/i] } }],
166
176
  code: (
167
177
  /* GraphQL */
168
178
  `
@@ -186,7 +196,14 @@ ${_utilsjs.TYPES_KINDS.map((kind) => `- \`${kind}\``).join(`
186
196
  },
187
197
  {
188
198
  title: "Correct",
189
- usage: [{ FragmentDefinition: { style: "PascalCase", forbiddenSuffixes: ["Fragment"] } }],
199
+ usage: [
200
+ {
201
+ FragmentDefinition: {
202
+ style: "PascalCase",
203
+ forbiddenPatterns: [/(^fragment)|(fragment$)/i]
204
+ }
205
+ }
206
+ ],
190
207
  code: (
191
208
  /* GraphQL */
192
209
  `
@@ -198,7 +215,7 @@ ${_utilsjs.TYPES_KINDS.map((kind) => `- \`${kind}\``).join(`
198
215
  },
199
216
  {
200
217
  title: "Correct",
201
- usage: [{ "FieldDefinition[parent.name.value=Query]": { forbiddenPrefixes: ["get"] } }],
218
+ usage: [{ "FieldDefinition[parent.name.value=Query]": { forbiddenPatterns: [/^get/i] } }],
202
219
  code: (
203
220
  /* GraphQL */
204
221
  `
@@ -228,11 +245,11 @@ ${_utilsjs.TYPES_KINDS.map((kind) => `- \`${kind}\``).join(`
228
245
  {
229
246
  "FieldDefinition[gqlType.name.value=Boolean]": {
230
247
  style: "camelCase",
231
- requiredPrefixes: ["is", "has"]
248
+ requiredPattern: /^(is|has)/
232
249
  },
233
250
  "FieldDefinition[gqlType.gqlType.name.value=Boolean]": {
234
251
  style: "camelCase",
235
- requiredPrefixes: ["is", "has"]
252
+ requiredPattern: /^(is|has)/
236
253
  }
237
254
  }
238
255
  ],
@@ -253,7 +270,7 @@ ${_utilsjs.TYPES_KINDS.map((kind) => `- \`${kind}\``).join(`
253
270
  {
254
271
  "FieldDefinition[gqlType.gqlType.name.value=SensitiveSecret]": {
255
272
  style: "camelCase",
256
- requiredSuffixes: ["SensitiveSecret"]
273
+ requiredPattern: /SensitiveSecret$/
257
274
  }
258
275
  }
259
276
  ],
@@ -267,6 +284,30 @@ ${_utilsjs.TYPES_KINDS.map((kind) => `- \`${kind}\``).join(`
267
284
  }
268
285
  `
269
286
  )
287
+ },
288
+ {
289
+ title: "Correct (Relay fragment convention `<module_name>_<property_name>`)",
290
+ usage: [
291
+ {
292
+ FragmentDefinition: {
293
+ style: "PascalCase",
294
+ requiredPattern: /_(?<camelCase>.+?)$/
295
+ }
296
+ }
297
+ ],
298
+ code: (
299
+ /* GraphQL */
300
+ `
301
+ # schema
302
+ type User {
303
+ # ...
304
+ }
305
+ # operations
306
+ fragment UserFields_data on User {
307
+ # ...
308
+ }
309
+ `
310
+ )
270
311
  }
271
312
  ],
272
313
  configOptions: {
@@ -279,32 +320,25 @@ ${_utilsjs.TYPES_KINDS.map((kind) => `- \`${kind}\``).join(`
279
320
  DirectiveDefinition: "camelCase",
280
321
  EnumValueDefinition: "UPPER_CASE",
281
322
  "FieldDefinition[parent.name.value=Query]": {
282
- forbiddenPrefixes: ["query", "get"],
283
- forbiddenSuffixes: ["Query"]
323
+ forbiddenPatterns: [/^(query|get)/i, /query$/i]
284
324
  },
285
325
  "FieldDefinition[parent.name.value=Mutation]": {
286
- forbiddenPrefixes: ["mutation"],
287
- forbiddenSuffixes: ["Mutation"]
326
+ forbiddenPatterns: [/(^mutation)|(mutation$)/i]
288
327
  },
289
328
  "FieldDefinition[parent.name.value=Subscription]": {
290
- forbiddenPrefixes: ["subscription"],
291
- forbiddenSuffixes: ["Subscription"]
329
+ forbiddenPatterns: [/(^subscription)|(subscription$)/i]
292
330
  },
293
331
  "EnumTypeDefinition,EnumTypeExtension": {
294
- forbiddenPrefixes: ["Enum"],
295
- forbiddenSuffixes: ["Enum"]
332
+ forbiddenPatterns: [/(^enum)|(enum$)/i]
296
333
  },
297
334
  "InterfaceTypeDefinition,InterfaceTypeExtension": {
298
- forbiddenPrefixes: ["Interface"],
299
- forbiddenSuffixes: ["Interface"]
335
+ forbiddenPatterns: [/(^interface)|(interface$)/i]
300
336
  },
301
337
  "UnionTypeDefinition,UnionTypeExtension": {
302
- forbiddenPrefixes: ["Union"],
303
- forbiddenSuffixes: ["Union"]
338
+ forbiddenPatterns: [/(^union)|(union$)/i]
304
339
  },
305
340
  "ObjectTypeDefinition,ObjectTypeExtension": {
306
- forbiddenPrefixes: ["Type"],
307
- forbiddenSuffixes: ["Type"]
341
+ forbiddenPatterns: [/(^type)|(type$)/i]
308
342
  }
309
343
  }
310
344
  ],
@@ -313,26 +347,29 @@ ${_utilsjs.TYPES_KINDS.map((kind) => `- \`${kind}\``).join(`
313
347
  VariableDefinition: "camelCase",
314
348
  OperationDefinition: {
315
349
  style: "PascalCase",
316
- forbiddenPrefixes: ["Query", "Mutation", "Subscription", "Get"],
317
- forbiddenSuffixes: ["Query", "Mutation", "Subscription"]
350
+ forbiddenPatterns: [
351
+ /^(query|mutation|subscription|get)/i,
352
+ /(query|mutation|subscription)$/i
353
+ ]
318
354
  },
319
355
  FragmentDefinition: {
320
356
  style: "PascalCase",
321
- forbiddenPrefixes: ["Fragment"],
322
- forbiddenSuffixes: ["Fragment"]
357
+ forbiddenPatterns: [/(^fragment)|(fragment$)/i]
323
358
  }
324
359
  }
325
360
  ]
326
361
  }
327
362
  },
328
- hasSuggestions: !0,
363
+ hasSuggestions: true,
329
364
  schema
330
365
  },
331
366
  create(context) {
332
- const options = context.options[0] || {}, { allowLeadingUnderscore, allowTrailingUnderscore, types, ...restOptions } = options, ignoredNodes = /* @__PURE__ */ new Set();
367
+ const options = context.options[0] || {};
368
+ const { allowLeadingUnderscore, allowTrailingUnderscore, types, ...restOptions } = options;
369
+ const ignoredNodes = /* @__PURE__ */ new Set();
333
370
  function normalisePropertyOption(kind) {
334
371
  const style = restOptions[kind] || types;
335
- return typeof style == "object" ? style : { style };
372
+ return typeof style === "object" ? style : { style };
336
373
  }
337
374
  function report(node, message, suggestedNames) {
338
375
  context.report({
@@ -346,8 +383,9 @@ ${_utilsjs.TYPES_KINDS.map((kind) => `- \`${kind}\``).join(`
346
383
  }
347
384
  const checkNode = (selector) => (n) => {
348
385
  const { name: node } = n.kind === _graphql.Kind.VARIABLE_DEFINITION ? n.variable : n;
349
- if (!node)
386
+ if (!node) {
350
387
  return;
388
+ }
351
389
  const {
352
390
  prefix,
353
391
  suffix,
@@ -358,12 +396,18 @@ ${_utilsjs.TYPES_KINDS.map((kind) => `- \`${kind}\``).join(`
358
396
  requiredPrefixes,
359
397
  requiredSuffixes,
360
398
  forbiddenPatterns,
361
- requiredPatterns
362
- } = normalisePropertyOption(selector), nodeName = node.value, error = getError();
399
+ requiredPattern
400
+ } = normalisePropertyOption(selector);
401
+ const nodeName = node.value;
402
+ const error = getError();
363
403
  if (error) {
364
- const { errorMessage, renameToNames } = error, [leadingUnderscores] = nodeName.match(/^_*/), [trailingUnderscores] = nodeName.match(/_*$/), suggestedNames = renameToNames.map(
404
+ const { errorMessage, renameToNames } = error;
405
+ const [leadingUnderscores] = nodeName.match(/^_*/);
406
+ const [trailingUnderscores] = nodeName.match(/_*$/);
407
+ const suggestedNames = renameToNames.map(
365
408
  (renameToName) => leadingUnderscores + renameToName + trailingUnderscores
366
- ), name = _utilsjs.displayNodeName.call(void 0, n);
409
+ );
410
+ const name = _utilsjs.displayNodeName.call(void 0, n);
367
411
  report(
368
412
  node,
369
413
  `${name[0].toUpperCase()}${name.slice(1)} should ${errorMessage}`,
@@ -371,80 +415,133 @@ ${_utilsjs.TYPES_KINDS.map((kind) => `- \`${kind}\``).join(`
371
415
  );
372
416
  }
373
417
  function getError() {
374
- const name = nodeName.replace(/(^_+)|(_+$)/g, "");
418
+ let name = nodeName;
419
+ if (allowLeadingUnderscore) name = name.replace(/^_+/, "");
420
+ if (allowTrailingUnderscore) name = name.replace(/_+$/, "");
375
421
  if (ignorePattern && new RegExp(ignorePattern, "u").test(name)) {
376
- "name" in n && ignoredNodes.add(n.name);
422
+ if ("name" in n) {
423
+ ignoredNodes.add(n.name);
424
+ }
377
425
  return;
378
426
  }
379
- if (prefix && !name.startsWith(prefix))
427
+ if (prefix && !name.startsWith(prefix)) {
380
428
  return {
381
429
  errorMessage: `have "${prefix}" prefix`,
382
430
  renameToNames: [prefix + name]
383
431
  };
384
- if (suffix && !name.endsWith(suffix))
432
+ }
433
+ if (suffix && !name.endsWith(suffix)) {
385
434
  return {
386
435
  errorMessage: `have "${suffix}" suffix`,
387
436
  renameToNames: [name + suffix]
388
437
  };
438
+ }
439
+ if (requiredPattern) {
440
+ if (requiredPattern.source.includes("(?<")) {
441
+ try {
442
+ name = name.replace(requiredPattern, (originalString, ...args) => {
443
+ const groups = args.at(-1);
444
+ for (const [styleName, value] of Object.entries(groups)) {
445
+ if (!(styleName in StyleToRegex)) {
446
+ throw new Error("Invalid case style in `requiredPatterns` option");
447
+ }
448
+ if (value === _utilsjs.convertCase.call(void 0, styleName, value)) {
449
+ return "";
450
+ }
451
+ throw new Error(`contain the required pattern: ${requiredPattern}`);
452
+ }
453
+ return originalString;
454
+ });
455
+ if (name === nodeName) {
456
+ throw new Error(`contain the required pattern: ${requiredPattern}`);
457
+ }
458
+ } catch (error2) {
459
+ return {
460
+ errorMessage: error2.message,
461
+ renameToNames: []
462
+ };
463
+ }
464
+ } else if (!requiredPattern.test(name)) {
465
+ return {
466
+ errorMessage: `contain the required pattern: ${requiredPattern}`,
467
+ renameToNames: []
468
+ };
469
+ }
470
+ }
389
471
  const forbidden = _optionalChain([forbiddenPatterns, 'optionalAccess', _ => _.find, 'call', _2 => _2((pattern) => pattern.test(name))]);
390
- if (forbidden)
472
+ if (forbidden) {
391
473
  return {
392
474
  errorMessage: `not contain the forbidden pattern "${forbidden}"`,
393
475
  renameToNames: [name.replace(forbidden, "")]
394
476
  };
395
- if (requiredPatterns && !requiredPatterns.some((pattern) => pattern.test(name)))
396
- return {
397
- errorMessage: `contain the required pattern: ${_utilsjs.englishJoinWords.call(void 0, requiredPatterns.map((re) => re.source))}`,
398
- renameToNames: []
399
- };
477
+ }
400
478
  const forbiddenPrefix = _optionalChain([forbiddenPrefixes, 'optionalAccess', _3 => _3.find, 'call', _4 => _4((prefix2) => name.startsWith(prefix2))]);
401
- if (forbiddenPrefix)
479
+ if (forbiddenPrefix) {
402
480
  return {
403
481
  errorMessage: `not have "${forbiddenPrefix}" prefix`,
404
482
  renameToNames: [name.replace(new RegExp(`^${forbiddenPrefix}`), "")]
405
483
  };
484
+ }
406
485
  const forbiddenSuffix = _optionalChain([forbiddenSuffixes, 'optionalAccess', _5 => _5.find, 'call', _6 => _6((suffix2) => name.endsWith(suffix2))]);
407
- if (forbiddenSuffix)
486
+ if (forbiddenSuffix) {
408
487
  return {
409
488
  errorMessage: `not have "${forbiddenSuffix}" suffix`,
410
489
  renameToNames: [name.replace(new RegExp(`${forbiddenSuffix}$`), "")]
411
490
  };
412
- if (requiredPrefixes && !requiredPrefixes.some((requiredPrefix) => name.startsWith(requiredPrefix)))
491
+ }
492
+ if (requiredPrefixes && !requiredPrefixes.some((requiredPrefix) => name.startsWith(requiredPrefix))) {
413
493
  return {
414
494
  errorMessage: `have one of the following prefixes: ${_utilsjs.englishJoinWords.call(void 0,
415
495
  requiredPrefixes
416
496
  )}`,
417
497
  renameToNames: style ? requiredPrefixes.map((prefix2) => _utilsjs.convertCase.call(void 0, style, `${prefix2} ${name}`)) : requiredPrefixes.map((prefix2) => `${prefix2}${name}`)
418
498
  };
419
- if (requiredSuffixes && !requiredSuffixes.some((requiredSuffix) => name.endsWith(requiredSuffix)))
499
+ }
500
+ if (requiredSuffixes && !requiredSuffixes.some((requiredSuffix) => name.endsWith(requiredSuffix))) {
420
501
  return {
421
502
  errorMessage: `have one of the following suffixes: ${_utilsjs.englishJoinWords.call(void 0,
422
503
  requiredSuffixes
423
504
  )}`,
424
505
  renameToNames: style ? requiredSuffixes.map((suffix2) => _utilsjs.convertCase.call(void 0, style, `${name} ${suffix2}`)) : requiredSuffixes.map((suffix2) => `${name}${suffix2}`)
425
506
  };
426
- if (!style)
507
+ }
508
+ if (!style) {
427
509
  return;
428
- if (!StyleToRegex[style].test(name))
510
+ }
511
+ const caseRegex = StyleToRegex[style];
512
+ if (!caseRegex.test(name)) {
429
513
  return {
430
514
  errorMessage: `be in ${style} format`,
431
515
  renameToNames: [_utilsjs.convertCase.call(void 0, style, name)]
432
516
  };
517
+ }
518
+ }
519
+ };
520
+ const checkUnderscore = (isLeading) => (node) => {
521
+ if (ignoredNodes.has(node)) {
522
+ return;
433
523
  }
434
- }, checkUnderscore = (isLeading) => (node) => {
435
- if (ignoredNodes.has(node) || node.parent.kind === "Field" && node.parent.alias !== node)
524
+ if (node.parent.kind === "Field" && node.parent.alias !== node) {
436
525
  return;
526
+ }
437
527
  const suggestedName = node.value.replace(isLeading ? /^_+/ : /_+$/, "");
438
528
  report(node, `${isLeading ? "Leading" : "Trailing"} underscores are not allowed`, [
439
529
  suggestedName
440
530
  ]);
441
- }, listeners = {};
442
- allowLeadingUnderscore || (listeners["Name[value=/^_/]"] = checkUnderscore(!0)), allowTrailingUnderscore || (listeners["Name[value=/_$/]"] = checkUnderscore(!1));
531
+ };
532
+ const listeners = {};
533
+ if (!allowLeadingUnderscore) {
534
+ listeners["Name[value=/^_/]"] = checkUnderscore(true);
535
+ }
536
+ if (!allowTrailingUnderscore) {
537
+ listeners["Name[value=/_$/]"] = checkUnderscore(false);
538
+ }
443
539
  const selectors = new Set(
444
540
  [types && _utilsjs.TYPES_KINDS, Object.keys(restOptions)].filter((v) => !!v).flat()
445
541
  );
446
- for (const selector of selectors)
542
+ for (const selector of selectors) {
447
543
  listeners[selector] = checkNode(selector);
544
+ }
448
545
  return listeners;
449
546
  }
450
547
  };
@@ -1,13 +1,14 @@
1
1
  "use strict";Object.defineProperty(exports, "__esModule", {value: true});var _graphql = require('graphql');
2
2
  var _utilsjs = require('../../utils.js');
3
- const RULE_ID = "no-anonymous-operations", rule = exports.rule = {
3
+ const RULE_ID = "no-anonymous-operations";
4
+ const rule = {
4
5
  meta: {
5
6
  type: "suggestion",
6
- hasSuggestions: !0,
7
+ hasSuggestions: true,
7
8
  docs: {
8
9
  category: "Operations",
9
10
  description: "Require name for your GraphQL operations. This is useful since most GraphQL client libraries are using the operation name for caching purposes.",
10
- recommended: !0,
11
+ recommended: true,
11
12
  url: `https://the-guild.dev/graphql/eslint/rules/${RULE_ID}`,
12
13
  examples: [
13
14
  {
@@ -42,7 +43,8 @@ const RULE_ID = "no-anonymous-operations", rule = exports.rule = {
42
43
  create(context) {
43
44
  return {
44
45
  "OperationDefinition[name=undefined]"(node) {
45
- const [firstSelection] = node.selectionSet.selections, suggestedName = firstSelection.kind === _graphql.Kind.FIELD ? (firstSelection.alias || firstSelection.name).value : node.operation;
46
+ const [firstSelection] = node.selectionSet.selections;
47
+ const suggestedName = firstSelection.kind === _graphql.Kind.FIELD ? (firstSelection.alias || firstSelection.name).value : node.operation;
46
48
  context.report({
47
49
  loc: _utilsjs.getLocation.call(void 0, node.loc.start, node.operation),
48
50
  messageId: RULE_ID,
@@ -53,7 +55,8 @@ const RULE_ID = "no-anonymous-operations", rule = exports.rule = {
53
55
  {
54
56
  desc: `Rename to \`${suggestedName}\``,
55
57
  fix(fixer) {
56
- const hasQueryKeyword = context.getSourceCode().getText({ range: [node.range[0], node.range[0] + 1] }) !== "{";
58
+ const sourceCode = context.getSourceCode();
59
+ const hasQueryKeyword = sourceCode.getText({ range: [node.range[0], node.range[0] + 1] }) !== "{";
57
60
  return fixer.insertTextAfterRange(
58
61
  [node.range[0], node.range[0] + (hasQueryKeyword ? node.operation.length : 0)],
59
62
  `${hasQueryKeyword ? "" : "query"} ${suggestedName}${hasQueryKeyword ? "" : " "}`
@@ -1,13 +1,14 @@
1
1
  "use strict";Object.defineProperty(exports, "__esModule", {value: true}); function _optionalChain(ops) { let lastAccessLHS = undefined; let value = ops[0]; let i = 1; while (i < ops.length) { const op = ops[i]; const fn = ops[i + 1]; i += 2; if ((op === 'optionalAccess' || op === 'optionalCall') && value == null) { return undefined; } if (op === 'access' || op === 'optionalAccess') { lastAccessLHS = value; value = fn(value); } else if (op === 'call' || op === 'optionalCall') { value = fn((...args) => value.call(lastAccessLHS, ...args)); lastAccessLHS = undefined; } } return value; }var _utilsjs = require('../../utils.js');
2
- const RULE_ID = "no-deprecated", rule = exports.rule = {
2
+ const RULE_ID = "no-deprecated";
3
+ const rule = {
3
4
  meta: {
4
5
  type: "suggestion",
5
- hasSuggestions: !0,
6
+ hasSuggestions: true,
6
7
  docs: {
7
8
  category: "Operations",
8
9
  description: "Enforce that deprecated fields or enum values are not in use by operations.",
9
10
  url: `https://the-guild.dev/graphql/eslint/rules/${RULE_ID}`,
10
- requiresSchema: !0,
11
+ requiresSchema: true,
11
12
  examples: [
12
13
  {
13
14
  title: "Incorrect (field)",
@@ -79,7 +80,7 @@ const RULE_ID = "no-deprecated", rule = exports.rule = {
79
80
  )
80
81
  }
81
82
  ],
82
- recommended: !0
83
+ recommended: true
83
84
  },
84
85
  messages: {
85
86
  [RULE_ID]: "{{ type }} is marked as deprecated in your GraphQL schema (reason: {{ reason }})"
@@ -107,24 +108,37 @@ const RULE_ID = "no-deprecated", rule = exports.rule = {
107
108
  }
108
109
  return {
109
110
  EnumValue(node) {
110
- const reason = _optionalChain([node, 'access', _ => _.typeInfo, 'call', _2 => _2(), 'access', _3 => _3.enumValue, 'optionalAccess', _4 => _4.deprecationReason]);
111
- reason && report(node, reason);
111
+ const typeInfo = node.typeInfo();
112
+ const reason = _optionalChain([typeInfo, 'access', _ => _.enumValue, 'optionalAccess', _2 => _2.deprecationReason]);
113
+ if (reason) {
114
+ report(node, reason);
115
+ }
112
116
  },
113
117
  Field(node) {
114
- const reason = _optionalChain([node, 'access', _5 => _5.typeInfo, 'call', _6 => _6(), 'access', _7 => _7.fieldDef, 'optionalAccess', _8 => _8.deprecationReason]);
115
- reason && report(node, reason);
118
+ const typeInfo = node.typeInfo();
119
+ const reason = _optionalChain([typeInfo, 'access', _3 => _3.fieldDef, 'optionalAccess', _4 => _4.deprecationReason]);
120
+ if (reason) {
121
+ report(node, reason);
122
+ }
116
123
  },
117
124
  Argument(node) {
118
- const reason = _optionalChain([node, 'access', _9 => _9.typeInfo, 'call', _10 => _10(), 'access', _11 => _11.argument, 'optionalAccess', _12 => _12.deprecationReason]);
119
- reason && report(node, reason);
125
+ const typeInfo = node.typeInfo();
126
+ const reason = _optionalChain([typeInfo, 'access', _5 => _5.argument, 'optionalAccess', _6 => _6.deprecationReason]);
127
+ if (reason) {
128
+ report(node, reason);
129
+ }
120
130
  },
121
131
  ObjectValue(node) {
122
132
  const { inputType } = node.typeInfo();
123
- if (inputType && "getFields" in inputType) {
133
+ if (!inputType) return;
134
+ if ("getFields" in inputType) {
124
135
  const fields = inputType.getFields();
125
136
  for (const field of node.fields) {
126
- const fieldName = field.name.value, reason = fields[fieldName].deprecationReason;
127
- reason && report(field, reason);
137
+ const fieldName = field.name.value;
138
+ const reason = fields[fieldName].deprecationReason;
139
+ if (reason) {
140
+ report(field, reason);
141
+ }
128
142
  }
129
143
  }
130
144
  }
@@ -1,13 +1,14 @@
1
1
  "use strict";Object.defineProperty(exports, "__esModule", {value: true});var _graphql = require('graphql');
2
- const RULE_ID = "no-duplicate-fields", rule = exports.rule = {
2
+ const RULE_ID = "no-duplicate-fields";
3
+ const rule = {
3
4
  meta: {
4
5
  type: "suggestion",
5
- hasSuggestions: !0,
6
+ hasSuggestions: true,
6
7
  docs: {
7
8
  description: "Checks for duplicate fields in selection set, variables in operation definition, or in arguments set of a field.",
8
9
  category: "Operations",
9
10
  url: `https://the-guild.dev/graphql/eslint/rules/${RULE_ID}`,
10
- recommended: !0,
11
+ recommended: true,
11
12
  examples: [
12
13
  {
13
14
  title: "Incorrect",
@@ -88,24 +89,30 @@ const RULE_ID = "no-duplicate-fields", rule = exports.rule = {
88
89
  }
89
90
  ]
90
91
  });
91
- } else
92
+ } else {
92
93
  usedFields.add(fieldName);
94
+ }
93
95
  }
94
96
  return {
95
97
  OperationDefinition(node) {
96
98
  const set = /* @__PURE__ */ new Set();
97
- for (const varDef of node.variableDefinitions || [])
99
+ for (const varDef of node.variableDefinitions || []) {
98
100
  checkNode(set, varDef.variable.name);
101
+ }
99
102
  },
100
103
  Field(node) {
101
104
  const set = /* @__PURE__ */ new Set();
102
- for (const arg of node.arguments || [])
105
+ for (const arg of node.arguments || []) {
103
106
  checkNode(set, arg.name);
107
+ }
104
108
  },
105
109
  SelectionSet(node) {
106
110
  const set = /* @__PURE__ */ new Set();
107
- for (const selection of node.selections)
108
- selection.kind === _graphql.Kind.FIELD && checkNode(set, selection.alias || selection.name);
111
+ for (const selection of node.selections) {
112
+ if (selection.kind === _graphql.Kind.FIELD) {
113
+ checkNode(set, selection.alias || selection.name);
114
+ }
115
+ }
109
116
  }
110
117
  };
111
118
  }