@graphql-eslint/eslint-plugin 3.14.0-alpha-20221222211346-788e7eb → 3.14.0-alpha-20221223011223-bd3e820

Sign up to get free protection for your applications and to get access to all the features.
Files changed (185) hide show
  1. package/cjs/configs/index.js +10 -10
  2. package/cjs/documents.js +5 -5
  3. package/cjs/estree-converter/converter.js +2 -2
  4. package/cjs/estree-converter/index.js +3 -3
  5. package/cjs/estree-converter/utils.js +2 -2
  6. package/cjs/flat-configs.js +36 -0
  7. package/cjs/index.js +16 -14
  8. package/cjs/parser.js +13 -13
  9. package/cjs/processor.js +2 -2
  10. package/cjs/rules/alphabetize.js +7 -7
  11. package/cjs/rules/graphql-js-validation.js +9 -9
  12. package/cjs/rules/index.js +66 -66
  13. package/cjs/rules/lone-executable-definition.js +4 -4
  14. package/cjs/rules/match-document-filename.js +4 -4
  15. package/cjs/rules/naming-convention.js +6 -6
  16. package/cjs/rules/no-anonymous-operations.js +2 -2
  17. package/cjs/rules/no-deprecated.js +2 -2
  18. package/cjs/rules/no-one-place-fragments.js +3 -4
  19. package/cjs/rules/no-root-type.js +3 -3
  20. package/cjs/rules/no-scalar-result-type-on-mutation.js +2 -2
  21. package/cjs/rules/no-unreachable-types.js +3 -3
  22. package/cjs/rules/no-unused-fields.js +3 -3
  23. package/cjs/rules/relay-arguments.js +2 -2
  24. package/cjs/rules/relay-edge-types.js +6 -6
  25. package/cjs/rules/relay-page-info.js +5 -5
  26. package/cjs/rules/require-deprecation-date.js +2 -2
  27. package/cjs/rules/require-deprecation-reason.js +2 -2
  28. package/cjs/rules/require-description.js +8 -8
  29. package/cjs/rules/require-field-of-type-query-in-mutation-result.js +3 -3
  30. package/cjs/rules/require-id-when-available.js +8 -8
  31. package/cjs/rules/selection-set-depth.js +5 -5
  32. package/cjs/rules/strict-id-in-types.js +7 -7
  33. package/cjs/rules/unique-fragment-name.js +4 -4
  34. package/cjs/rules/unique-operation-name.js +2 -2
  35. package/cjs/schema.js +2 -2
  36. package/esm/cache.js +25 -0
  37. package/esm/configs/base.js +4 -0
  38. package/esm/configs/index.js +12 -0
  39. package/esm/configs/operations-all.js +29 -0
  40. package/esm/configs/operations-recommended.js +53 -0
  41. package/esm/configs/relay.js +9 -0
  42. package/esm/configs/schema-all.js +22 -0
  43. package/esm/configs/schema-recommended.js +49 -0
  44. package/esm/documents.js +144 -0
  45. package/esm/estree-converter/converter.js +58 -0
  46. package/esm/estree-converter/index.js +3 -0
  47. package/esm/estree-converter/types.js +1 -0
  48. package/esm/estree-converter/utils.js +102 -0
  49. package/esm/flat-configs.js +33 -0
  50. package/esm/graphql-config.js +49 -0
  51. package/esm/index.js +9 -0
  52. package/esm/package.json +1 -0
  53. package/esm/parser.js +56 -0
  54. package/esm/processor.js +75 -0
  55. package/esm/rules/alphabetize.js +344 -0
  56. package/esm/rules/description-style.js +75 -0
  57. package/esm/rules/graphql-js-validation.js +498 -0
  58. package/esm/rules/index.js +71 -0
  59. package/esm/rules/input-name.js +133 -0
  60. package/esm/rules/lone-executable-definition.js +85 -0
  61. package/esm/rules/match-document-filename.js +232 -0
  62. package/esm/rules/naming-convention.js +307 -0
  63. package/esm/rules/no-anonymous-operations.js +64 -0
  64. package/esm/rules/no-case-insensitive-enum-values-duplicates.js +58 -0
  65. package/esm/rules/no-deprecated.js +121 -0
  66. package/esm/rules/no-duplicate-fields.js +109 -0
  67. package/esm/rules/no-hashtag-description.js +86 -0
  68. package/esm/rules/no-one-place-fragments.js +80 -0
  69. package/esm/rules/no-root-type.js +83 -0
  70. package/esm/rules/no-scalar-result-type-on-mutation.js +63 -0
  71. package/esm/rules/no-typename-prefix.js +62 -0
  72. package/esm/rules/no-unreachable-types.js +154 -0
  73. package/esm/rules/no-unused-fields.js +127 -0
  74. package/esm/rules/relay-arguments.js +118 -0
  75. package/esm/rules/relay-connection-types.js +104 -0
  76. package/esm/rules/relay-edge-types.js +186 -0
  77. package/esm/rules/relay-page-info.js +97 -0
  78. package/esm/rules/require-deprecation-date.js +120 -0
  79. package/esm/rules/require-deprecation-reason.js +53 -0
  80. package/esm/rules/require-description.js +190 -0
  81. package/esm/rules/require-field-of-type-query-in-mutation-result.js +69 -0
  82. package/esm/rules/require-id-when-available.js +196 -0
  83. package/esm/rules/require-nullable-fields-with-oneof.js +58 -0
  84. package/esm/rules/require-type-pattern-with-oneof.js +57 -0
  85. package/esm/rules/selection-set-depth.js +131 -0
  86. package/esm/rules/strict-id-in-types.js +159 -0
  87. package/esm/rules/unique-fragment-name.js +86 -0
  88. package/esm/rules/unique-operation-name.js +62 -0
  89. package/esm/schema.js +37 -0
  90. package/esm/testkit.js +181 -0
  91. package/esm/types.js +1 -0
  92. package/esm/utils.js +83 -0
  93. package/package.json +10 -1
  94. package/typings/estree-converter/converter.d.cts +1 -1
  95. package/typings/estree-converter/converter.d.ts +1 -1
  96. package/typings/estree-converter/index.d.cts +3 -3
  97. package/typings/estree-converter/index.d.ts +3 -3
  98. package/typings/estree-converter/types.d.cts +3 -3
  99. package/typings/estree-converter/types.d.ts +3 -3
  100. package/typings/estree-converter/utils.d.cts +2 -2
  101. package/typings/estree-converter/utils.d.ts +2 -2
  102. package/typings/flat-configs.d.cts +248 -0
  103. package/typings/flat-configs.d.ts +248 -0
  104. package/typings/graphql-config.d.cts +1 -1
  105. package/typings/graphql-config.d.ts +1 -1
  106. package/typings/index.d.cts +8 -7
  107. package/typings/index.d.ts +8 -7
  108. package/typings/parser.d.cts +1 -1
  109. package/typings/parser.d.ts +1 -1
  110. package/typings/rules/alphabetize.d.cts +1 -1
  111. package/typings/rules/alphabetize.d.ts +1 -1
  112. package/typings/rules/description-style.d.cts +1 -1
  113. package/typings/rules/description-style.d.ts +1 -1
  114. package/typings/rules/graphql-js-validation.d.cts +1 -1
  115. package/typings/rules/graphql-js-validation.d.ts +1 -1
  116. package/typings/rules/index.d.cts +45 -45
  117. package/typings/rules/index.d.ts +45 -45
  118. package/typings/rules/input-name.d.cts +1 -1
  119. package/typings/rules/input-name.d.ts +1 -1
  120. package/typings/rules/lone-executable-definition.d.cts +1 -1
  121. package/typings/rules/lone-executable-definition.d.ts +1 -1
  122. package/typings/rules/match-document-filename.d.cts +2 -2
  123. package/typings/rules/match-document-filename.d.ts +2 -2
  124. package/typings/rules/naming-convention.d.cts +1 -1
  125. package/typings/rules/naming-convention.d.ts +1 -1
  126. package/typings/rules/no-anonymous-operations.d.cts +1 -1
  127. package/typings/rules/no-anonymous-operations.d.ts +1 -1
  128. package/typings/rules/no-case-insensitive-enum-values-duplicates.d.cts +1 -1
  129. package/typings/rules/no-case-insensitive-enum-values-duplicates.d.ts +1 -1
  130. package/typings/rules/no-deprecated.d.cts +1 -1
  131. package/typings/rules/no-deprecated.d.ts +1 -1
  132. package/typings/rules/no-duplicate-fields.d.cts +1 -1
  133. package/typings/rules/no-duplicate-fields.d.ts +1 -1
  134. package/typings/rules/no-hashtag-description.d.cts +1 -1
  135. package/typings/rules/no-hashtag-description.d.ts +1 -1
  136. package/typings/rules/no-one-place-fragments.d.cts +1 -1
  137. package/typings/rules/no-one-place-fragments.d.ts +1 -1
  138. package/typings/rules/no-root-type.d.cts +1 -1
  139. package/typings/rules/no-root-type.d.ts +1 -1
  140. package/typings/rules/no-scalar-result-type-on-mutation.d.cts +1 -1
  141. package/typings/rules/no-scalar-result-type-on-mutation.d.ts +1 -1
  142. package/typings/rules/no-typename-prefix.d.cts +1 -1
  143. package/typings/rules/no-typename-prefix.d.ts +1 -1
  144. package/typings/rules/no-unreachable-types.d.cts +1 -1
  145. package/typings/rules/no-unreachable-types.d.ts +1 -1
  146. package/typings/rules/no-unused-fields.d.cts +1 -1
  147. package/typings/rules/no-unused-fields.d.ts +1 -1
  148. package/typings/rules/relay-arguments.d.cts +1 -1
  149. package/typings/rules/relay-arguments.d.ts +1 -1
  150. package/typings/rules/relay-connection-types.d.cts +1 -1
  151. package/typings/rules/relay-connection-types.d.ts +1 -1
  152. package/typings/rules/relay-edge-types.d.cts +1 -1
  153. package/typings/rules/relay-edge-types.d.ts +1 -1
  154. package/typings/rules/relay-page-info.d.cts +1 -1
  155. package/typings/rules/relay-page-info.d.ts +1 -1
  156. package/typings/rules/require-deprecation-date.d.cts +1 -1
  157. package/typings/rules/require-deprecation-date.d.ts +1 -1
  158. package/typings/rules/require-deprecation-reason.d.cts +1 -1
  159. package/typings/rules/require-deprecation-reason.d.ts +1 -1
  160. package/typings/rules/require-description.d.cts +1 -1
  161. package/typings/rules/require-description.d.ts +1 -1
  162. package/typings/rules/require-field-of-type-query-in-mutation-result.d.cts +1 -1
  163. package/typings/rules/require-field-of-type-query-in-mutation-result.d.ts +1 -1
  164. package/typings/rules/require-id-when-available.d.cts +1 -1
  165. package/typings/rules/require-id-when-available.d.ts +1 -1
  166. package/typings/rules/require-nullable-fields-with-oneof.d.cts +1 -1
  167. package/typings/rules/require-nullable-fields-with-oneof.d.ts +1 -1
  168. package/typings/rules/require-type-pattern-with-oneof.d.cts +1 -1
  169. package/typings/rules/require-type-pattern-with-oneof.d.ts +1 -1
  170. package/typings/rules/selection-set-depth.d.cts +1 -1
  171. package/typings/rules/selection-set-depth.d.ts +1 -1
  172. package/typings/rules/strict-id-in-types.d.cts +1 -1
  173. package/typings/rules/strict-id-in-types.d.ts +1 -1
  174. package/typings/rules/unique-fragment-name.d.cts +2 -2
  175. package/typings/rules/unique-fragment-name.d.ts +2 -2
  176. package/typings/rules/unique-operation-name.d.cts +1 -1
  177. package/typings/rules/unique-operation-name.d.ts +1 -1
  178. package/typings/schema.d.cts +1 -1
  179. package/typings/schema.d.ts +1 -1
  180. package/typings/testkit.d.cts +3 -3
  181. package/typings/testkit.d.ts +3 -3
  182. package/typings/types.d.cts +2 -2
  183. package/typings/types.d.ts +2 -2
  184. package/typings/utils.d.cts +2 -2
  185. package/typings/utils.d.ts +2 -2
@@ -0,0 +1,498 @@
1
+ import { createRequire } from 'module';
2
+ const require = createRequire(import.meta.url);
3
+ import { Kind, visit, validate, } from 'graphql';
4
+ import { validateSDL } from 'graphql/validation/validate.js';
5
+ import { requireGraphQLSchemaFromContext, requireSiblingsOperations, logger, REPORT_ON_FIRST_CHARACTER, ARRAY_DEFAULT_OPTIONS, } from '../utils.js';
6
+ function validateDocument({ context, schema = null, documentNode, rule, hasDidYouMeanSuggestions, }) {
7
+ var _a;
8
+ if (documentNode.definitions.length === 0) {
9
+ return;
10
+ }
11
+ try {
12
+ const validationErrors = schema
13
+ ? validate(schema, documentNode, [rule])
14
+ : validateSDL(documentNode, null, [rule]);
15
+ for (const error of validationErrors) {
16
+ const { line, column } = error.locations[0];
17
+ const sourceCode = context.getSourceCode();
18
+ const { tokens } = sourceCode.ast;
19
+ const token = tokens.find(token => token.loc.start.line === line && token.loc.start.column === column - 1);
20
+ let loc = {
21
+ line,
22
+ column: column - 1,
23
+ };
24
+ if (token) {
25
+ loc =
26
+ // if cursor on `@` symbol than use next node
27
+ token.type === '@'
28
+ ? sourceCode.getNodeByRangeIndex(token.range[1] + 1).loc
29
+ : token.loc;
30
+ }
31
+ const didYouMeanContent = (_a = error.message.match(/Did you mean (?<content>.*)\?$/)) === null || _a === void 0 ? void 0 : _a.groups.content;
32
+ const matches = didYouMeanContent ? [...didYouMeanContent.matchAll(/"(?<name>[^"]*)"/g)] : [];
33
+ context.report({
34
+ loc,
35
+ message: error.message,
36
+ suggest: hasDidYouMeanSuggestions
37
+ ? matches.map(match => {
38
+ const { name } = match.groups;
39
+ return {
40
+ desc: `Rename to \`${name}\``,
41
+ fix: fixer => fixer.replaceText(token, name),
42
+ };
43
+ })
44
+ : [],
45
+ });
46
+ }
47
+ }
48
+ catch (e) {
49
+ context.report({
50
+ loc: REPORT_ON_FIRST_CHARACTER,
51
+ message: e.message,
52
+ });
53
+ }
54
+ }
55
+ const getFragmentDefsAndFragmentSpreads = (node) => {
56
+ const fragmentDefs = new Set();
57
+ const fragmentSpreads = new Set();
58
+ const visitor = {
59
+ FragmentDefinition(node) {
60
+ fragmentDefs.add(node.name.value);
61
+ },
62
+ FragmentSpread(node) {
63
+ fragmentSpreads.add(node.name.value);
64
+ },
65
+ };
66
+ visit(node, visitor);
67
+ return { fragmentDefs, fragmentSpreads };
68
+ };
69
+ const getMissingFragments = (node) => {
70
+ const { fragmentDefs, fragmentSpreads } = getFragmentDefsAndFragmentSpreads(node);
71
+ return [...fragmentSpreads].filter(name => !fragmentDefs.has(name));
72
+ };
73
+ const handleMissingFragments = ({ ruleId, context, node }) => {
74
+ const missingFragments = getMissingFragments(node);
75
+ if (missingFragments.length > 0) {
76
+ const siblings = requireSiblingsOperations(ruleId, context);
77
+ const fragmentsToAdd = [];
78
+ for (const fragmentName of missingFragments) {
79
+ const [foundFragment] = siblings.getFragment(fragmentName).map(source => source.document);
80
+ if (foundFragment) {
81
+ fragmentsToAdd.push(foundFragment);
82
+ }
83
+ }
84
+ if (fragmentsToAdd.length > 0) {
85
+ // recall fn to make sure to add fragments inside fragments
86
+ return handleMissingFragments({
87
+ ruleId,
88
+ context,
89
+ node: {
90
+ kind: Kind.DOCUMENT,
91
+ definitions: [...node.definitions, ...fragmentsToAdd],
92
+ },
93
+ });
94
+ }
95
+ }
96
+ return node;
97
+ };
98
+ const validationToRule = ({ ruleId, ruleName, getDocumentNode, schema = [], hasDidYouMeanSuggestions, }, docs) => {
99
+ let ruleFn = null;
100
+ try {
101
+ ruleFn = require(`graphql/validation/rules/${ruleName}Rule`)[`${ruleName}Rule`];
102
+ }
103
+ catch (_a) {
104
+ try {
105
+ ruleFn = require(`graphql/validation/rules/${ruleName}`)[`${ruleName}Rule`];
106
+ }
107
+ catch (_b) {
108
+ ruleFn = require('graphql/validation')[`${ruleName}Rule`];
109
+ }
110
+ }
111
+ return {
112
+ [ruleId]: {
113
+ meta: {
114
+ docs: {
115
+ recommended: true,
116
+ ...docs,
117
+ graphQLJSRuleName: ruleName,
118
+ url: `https://github.com/B2o5T/graphql-eslint/blob/master/docs/rules/${ruleId}.md`,
119
+ description: `${docs.description}\n> This rule is a wrapper around a \`graphql-js\` validation function.`,
120
+ },
121
+ schema,
122
+ hasSuggestions: hasDidYouMeanSuggestions,
123
+ },
124
+ create(context) {
125
+ if (!ruleFn) {
126
+ logger.warn(`Rule "${ruleId}" depends on a GraphQL validation rule "${ruleName}" but it's not available in the "graphql" version you are using. Skipping…`);
127
+ return {};
128
+ }
129
+ return {
130
+ Document(node) {
131
+ const schema = docs.requiresSchema
132
+ ? requireGraphQLSchemaFromContext(ruleId, context)
133
+ : null;
134
+ const documentNode = getDocumentNode
135
+ ? getDocumentNode({ ruleId, context, node: node.rawNode() })
136
+ : node.rawNode();
137
+ validateDocument({
138
+ context,
139
+ schema,
140
+ documentNode,
141
+ rule: ruleFn,
142
+ hasDidYouMeanSuggestions,
143
+ });
144
+ },
145
+ };
146
+ },
147
+ },
148
+ };
149
+ };
150
+ export const GRAPHQL_JS_VALIDATIONS = Object.assign({}, validationToRule({
151
+ ruleId: 'executable-definitions',
152
+ ruleName: 'ExecutableDefinitions',
153
+ }, {
154
+ category: 'Operations',
155
+ description: 'A GraphQL document is only valid for execution if all definitions are either operation or fragment definitions.',
156
+ requiresSchema: true,
157
+ }), validationToRule({
158
+ ruleId: 'fields-on-correct-type',
159
+ ruleName: 'FieldsOnCorrectType',
160
+ hasDidYouMeanSuggestions: true,
161
+ }, {
162
+ category: 'Operations',
163
+ description: 'A GraphQL document is only valid if all fields selected are defined by the parent type, or are an allowed meta field such as `__typename`.',
164
+ requiresSchema: true,
165
+ }), validationToRule({
166
+ ruleId: 'fragments-on-composite-type',
167
+ ruleName: 'FragmentsOnCompositeTypes',
168
+ }, {
169
+ category: 'Operations',
170
+ description: 'Fragments use a type condition to determine if they apply, since fragments can only be spread into a composite type (object, interface, or union), the type condition must also be a composite type.',
171
+ requiresSchema: true,
172
+ }), validationToRule({
173
+ ruleId: 'known-argument-names',
174
+ ruleName: 'KnownArgumentNames',
175
+ hasDidYouMeanSuggestions: true,
176
+ }, {
177
+ category: ['Schema', 'Operations'],
178
+ description: 'A GraphQL field is only valid if all supplied arguments are defined by that field.',
179
+ requiresSchema: true,
180
+ }), validationToRule({
181
+ ruleId: 'known-directives',
182
+ ruleName: 'KnownDirectives',
183
+ getDocumentNode({ context, node: documentNode }) {
184
+ const { ignoreClientDirectives = [] } = context.options[0] || {};
185
+ if (ignoreClientDirectives.length === 0) {
186
+ return documentNode;
187
+ }
188
+ const filterDirectives = (node) => ({
189
+ ...node,
190
+ directives: node.directives.filter(directive => !ignoreClientDirectives.includes(directive.name.value)),
191
+ });
192
+ return visit(documentNode, {
193
+ Field: filterDirectives,
194
+ OperationDefinition: filterDirectives,
195
+ });
196
+ },
197
+ schema: {
198
+ type: 'array',
199
+ maxItems: 1,
200
+ items: {
201
+ type: 'object',
202
+ additionalProperties: false,
203
+ required: ['ignoreClientDirectives'],
204
+ properties: {
205
+ ignoreClientDirectives: ARRAY_DEFAULT_OPTIONS,
206
+ },
207
+ },
208
+ },
209
+ }, {
210
+ category: ['Schema', 'Operations'],
211
+ description: 'A GraphQL document is only valid if all `@directive`s are known by the schema and legally positioned.',
212
+ requiresSchema: true,
213
+ examples: [
214
+ {
215
+ title: 'Valid',
216
+ usage: [{ ignoreClientDirectives: ['client'] }],
217
+ code: /* GraphQL */ `
218
+ {
219
+ product {
220
+ someClientField @client
221
+ }
222
+ }
223
+ `,
224
+ },
225
+ ],
226
+ }), validationToRule({
227
+ ruleId: 'known-fragment-names',
228
+ ruleName: 'KnownFragmentNames',
229
+ getDocumentNode: handleMissingFragments,
230
+ }, {
231
+ category: 'Operations',
232
+ description: 'A GraphQL document is only valid if all `...Fragment` fragment spreads refer to fragments defined in the same document.',
233
+ requiresSchema: true,
234
+ requiresSiblings: true,
235
+ examples: [
236
+ {
237
+ title: 'Incorrect',
238
+ code: /* GraphQL */ `
239
+ query {
240
+ user {
241
+ id
242
+ ...UserFields # fragment not defined in the document
243
+ }
244
+ }
245
+ `,
246
+ },
247
+ {
248
+ title: 'Correct',
249
+ code: /* GraphQL */ `
250
+ fragment UserFields on User {
251
+ firstName
252
+ lastName
253
+ }
254
+
255
+ query {
256
+ user {
257
+ id
258
+ ...UserFields
259
+ }
260
+ }
261
+ `,
262
+ },
263
+ {
264
+ title: 'Correct (`UserFields` fragment located in a separate file)',
265
+ code: /* GraphQL */ `
266
+ # user.gql
267
+ query {
268
+ user {
269
+ id
270
+ ...UserFields
271
+ }
272
+ }
273
+
274
+ # user-fields.gql
275
+ fragment UserFields on User {
276
+ id
277
+ }
278
+ `,
279
+ },
280
+ ],
281
+ }), validationToRule({
282
+ ruleId: 'known-type-names',
283
+ ruleName: 'KnownTypeNames',
284
+ hasDidYouMeanSuggestions: true,
285
+ }, {
286
+ category: ['Schema', 'Operations'],
287
+ description: 'A GraphQL document is only valid if referenced types (specifically variable definitions and fragment conditions) are defined by the type schema.',
288
+ requiresSchema: true,
289
+ }), validationToRule({
290
+ ruleId: 'lone-anonymous-operation',
291
+ ruleName: 'LoneAnonymousOperation',
292
+ }, {
293
+ category: 'Operations',
294
+ description: 'A GraphQL document that contains an anonymous operation (the `query` short-hand) is only valid if it contains only that one operation definition.',
295
+ requiresSchema: true,
296
+ }), validationToRule({
297
+ ruleId: 'lone-schema-definition',
298
+ ruleName: 'LoneSchemaDefinition',
299
+ }, {
300
+ category: 'Schema',
301
+ description: 'A GraphQL document is only valid if it contains only one schema definition.',
302
+ }), validationToRule({
303
+ ruleId: 'no-fragment-cycles',
304
+ ruleName: 'NoFragmentCycles',
305
+ }, {
306
+ category: 'Operations',
307
+ description: 'A GraphQL fragment is only valid when it does not have cycles in fragments usage.',
308
+ requiresSchema: true,
309
+ }), validationToRule({
310
+ ruleId: 'no-undefined-variables',
311
+ ruleName: 'NoUndefinedVariables',
312
+ getDocumentNode: handleMissingFragments,
313
+ }, {
314
+ category: 'Operations',
315
+ description: 'A GraphQL operation is only valid if all variables encountered, both directly and via fragment spreads, are defined by that operation.',
316
+ requiresSchema: true,
317
+ requiresSiblings: true,
318
+ }), validationToRule({
319
+ ruleId: 'no-unused-fragments',
320
+ ruleName: 'NoUnusedFragments',
321
+ getDocumentNode: ({ ruleId, context, node }) => {
322
+ const siblings = requireSiblingsOperations(ruleId, context);
323
+ const FilePathToDocumentsMap = [
324
+ ...siblings.getOperations(),
325
+ ...siblings.getFragments(),
326
+ ].reduce((map, { filePath, document }) => {
327
+ var _a;
328
+ (_a = map[filePath]) !== null && _a !== void 0 ? _a : (map[filePath] = []);
329
+ map[filePath].push(document);
330
+ return map;
331
+ }, Object.create(null));
332
+ const getParentNode = (currentFilePath, node) => {
333
+ const { fragmentDefs } = getFragmentDefsAndFragmentSpreads(node);
334
+ if (fragmentDefs.size === 0) {
335
+ return node;
336
+ }
337
+ // skip iteration over documents for current filepath
338
+ delete FilePathToDocumentsMap[currentFilePath];
339
+ for (const [filePath, documents] of Object.entries(FilePathToDocumentsMap)) {
340
+ const missingFragments = getMissingFragments({
341
+ kind: Kind.DOCUMENT,
342
+ definitions: documents,
343
+ });
344
+ const isCurrentFileImportFragment = missingFragments.some(fragment => fragmentDefs.has(fragment));
345
+ if (isCurrentFileImportFragment) {
346
+ return getParentNode(filePath, {
347
+ kind: Kind.DOCUMENT,
348
+ definitions: [...node.definitions, ...documents],
349
+ });
350
+ }
351
+ }
352
+ return node;
353
+ };
354
+ return getParentNode(context.getFilename(), node);
355
+ },
356
+ }, {
357
+ category: 'Operations',
358
+ description: 'A GraphQL document is only valid if all fragment definitions are spread within operations, or spread within other fragments spread within operations.',
359
+ requiresSchema: true,
360
+ requiresSiblings: true,
361
+ }), validationToRule({
362
+ ruleId: 'no-unused-variables',
363
+ ruleName: 'NoUnusedVariables',
364
+ getDocumentNode: handleMissingFragments,
365
+ }, {
366
+ category: 'Operations',
367
+ description: 'A GraphQL operation is only valid if all variables defined by an operation are used, either directly or within a spread fragment.',
368
+ requiresSchema: true,
369
+ requiresSiblings: true,
370
+ }), validationToRule({
371
+ ruleId: 'overlapping-fields-can-be-merged',
372
+ ruleName: 'OverlappingFieldsCanBeMerged',
373
+ }, {
374
+ category: 'Operations',
375
+ description: 'A selection set is only valid if all fields (including spreading any fragments) either correspond to distinct response names or can be merged without ambiguity.',
376
+ requiresSchema: true,
377
+ }), validationToRule({
378
+ ruleId: 'possible-fragment-spread',
379
+ ruleName: 'PossibleFragmentSpreads',
380
+ }, {
381
+ category: 'Operations',
382
+ description: 'A fragment spread is only valid if the type condition could ever possibly be true: if there is a non-empty intersection of the possible parent types, and possible types which pass the type condition.',
383
+ requiresSchema: true,
384
+ }), validationToRule({
385
+ ruleId: 'possible-type-extension',
386
+ ruleName: 'PossibleTypeExtensions',
387
+ hasDidYouMeanSuggestions: true,
388
+ }, {
389
+ category: 'Schema',
390
+ description: 'A type extension is only valid if the type is defined and has the same kind.',
391
+ // TODO: add in graphql-eslint v4
392
+ recommended: false,
393
+ requiresSchema: true,
394
+ isDisabledForAllConfig: true,
395
+ }), validationToRule({
396
+ ruleId: 'provided-required-arguments',
397
+ ruleName: 'ProvidedRequiredArguments',
398
+ }, {
399
+ category: ['Schema', 'Operations'],
400
+ description: 'A field or directive is only valid if all required (non-null without a default value) field arguments have been provided.',
401
+ requiresSchema: true,
402
+ }), validationToRule({
403
+ ruleId: 'scalar-leafs',
404
+ ruleName: 'ScalarLeafs',
405
+ hasDidYouMeanSuggestions: true,
406
+ }, {
407
+ category: 'Operations',
408
+ description: 'A GraphQL document is valid only if all leaf fields (fields without sub selections) are of scalar or enum types.',
409
+ requiresSchema: true,
410
+ }), validationToRule({
411
+ ruleId: 'one-field-subscriptions',
412
+ ruleName: 'SingleFieldSubscriptions',
413
+ }, {
414
+ category: 'Operations',
415
+ description: 'A GraphQL subscription is valid only if it contains a single root field.',
416
+ requiresSchema: true,
417
+ }), validationToRule({
418
+ ruleId: 'unique-argument-names',
419
+ ruleName: 'UniqueArgumentNames',
420
+ }, {
421
+ category: 'Operations',
422
+ description: 'A GraphQL field or directive is only valid if all supplied arguments are uniquely named.',
423
+ requiresSchema: true,
424
+ }), validationToRule({
425
+ ruleId: 'unique-directive-names',
426
+ ruleName: 'UniqueDirectiveNames',
427
+ }, {
428
+ category: 'Schema',
429
+ description: 'A GraphQL document is only valid if all defined directives have unique names.',
430
+ }), validationToRule({
431
+ ruleId: 'unique-directive-names-per-location',
432
+ ruleName: 'UniqueDirectivesPerLocation',
433
+ }, {
434
+ category: ['Schema', 'Operations'],
435
+ description: 'A GraphQL document is only valid if all non-repeatable directives at a given location are uniquely named.',
436
+ requiresSchema: true,
437
+ }), validationToRule({
438
+ ruleId: 'unique-enum-value-names',
439
+ ruleName: 'UniqueEnumValueNames',
440
+ }, {
441
+ category: 'Schema',
442
+ description: 'A GraphQL enum type is only valid if all its values are uniquely named.',
443
+ recommended: false,
444
+ isDisabledForAllConfig: true,
445
+ }), validationToRule({
446
+ ruleId: 'unique-field-definition-names',
447
+ ruleName: 'UniqueFieldDefinitionNames',
448
+ }, {
449
+ category: 'Schema',
450
+ description: 'A GraphQL complex type is only valid if all its fields are uniquely named.',
451
+ }), validationToRule({
452
+ ruleId: 'unique-input-field-names',
453
+ ruleName: 'UniqueInputFieldNames',
454
+ }, {
455
+ category: 'Operations',
456
+ description: 'A GraphQL input object value is only valid if all supplied fields are uniquely named.',
457
+ }), validationToRule({
458
+ ruleId: 'unique-operation-types',
459
+ ruleName: 'UniqueOperationTypes',
460
+ }, {
461
+ category: 'Schema',
462
+ description: 'A GraphQL document is only valid if it has only one type per operation.',
463
+ }), validationToRule({
464
+ ruleId: 'unique-type-names',
465
+ ruleName: 'UniqueTypeNames',
466
+ }, {
467
+ category: 'Schema',
468
+ description: 'A GraphQL document is only valid if all defined types have unique names.',
469
+ }), validationToRule({
470
+ ruleId: 'unique-variable-names',
471
+ ruleName: 'UniqueVariableNames',
472
+ }, {
473
+ category: 'Operations',
474
+ description: 'A GraphQL operation is only valid if all its variables are uniquely named.',
475
+ requiresSchema: true,
476
+ }), validationToRule({
477
+ ruleId: 'value-literals-of-correct-type',
478
+ ruleName: 'ValuesOfCorrectType',
479
+ hasDidYouMeanSuggestions: true,
480
+ }, {
481
+ category: 'Operations',
482
+ description: 'A GraphQL document is only valid if all value literals are of the type expected at their position.',
483
+ requiresSchema: true,
484
+ }), validationToRule({
485
+ ruleId: 'variables-are-input-types',
486
+ ruleName: 'VariablesAreInputTypes',
487
+ }, {
488
+ category: 'Operations',
489
+ description: 'A GraphQL operation is only valid if all the variables it defines are of input types (scalar, enum, or input object).',
490
+ requiresSchema: true,
491
+ }), validationToRule({
492
+ ruleId: 'variables-in-allowed-position',
493
+ ruleName: 'VariablesInAllowedPosition',
494
+ }, {
495
+ category: 'Operations',
496
+ description: 'Variables passed to field arguments conform to type.',
497
+ requiresSchema: true,
498
+ }));
@@ -0,0 +1,71 @@
1
+ /*
2
+ * 🚨 IMPORTANT! Do not manually modify this file. Run: `yarn generate-configs`
3
+ */
4
+ import { GRAPHQL_JS_VALIDATIONS } from './graphql-js-validation.js';
5
+ import { rule as alphabetize } from './alphabetize.js';
6
+ import { rule as descriptionStyle } from './description-style.js';
7
+ import { rule as inputName } from './input-name.js';
8
+ import { rule as loneExecutableDefinition } from './lone-executable-definition.js';
9
+ import { rule as matchDocumentFilename } from './match-document-filename.js';
10
+ import { rule as namingConvention } from './naming-convention.js';
11
+ import { rule as noAnonymousOperations } from './no-anonymous-operations.js';
12
+ import { rule as noCaseInsensitiveEnumValuesDuplicates } from './no-case-insensitive-enum-values-duplicates.js';
13
+ import { rule as noDeprecated } from './no-deprecated.js';
14
+ import { rule as noDuplicateFields } from './no-duplicate-fields.js';
15
+ import { rule as noHashtagDescription } from './no-hashtag-description.js';
16
+ import { rule as noOnePlaceFragments } from './no-one-place-fragments.js';
17
+ import { rule as noRootType } from './no-root-type.js';
18
+ import { rule as noScalarResultTypeOnMutation } from './no-scalar-result-type-on-mutation.js';
19
+ import { rule as noTypenamePrefix } from './no-typename-prefix.js';
20
+ import { rule as noUnreachableTypes } from './no-unreachable-types.js';
21
+ import { rule as noUnusedFields } from './no-unused-fields.js';
22
+ import { rule as relayArguments } from './relay-arguments.js';
23
+ import { rule as relayConnectionTypes } from './relay-connection-types.js';
24
+ import { rule as relayEdgeTypes } from './relay-edge-types.js';
25
+ import { rule as relayPageInfo } from './relay-page-info.js';
26
+ import { rule as requireDeprecationDate } from './require-deprecation-date.js';
27
+ import { rule as requireDeprecationReason } from './require-deprecation-reason.js';
28
+ import { rule as requireDescription } from './require-description.js';
29
+ import { rule as requireFieldOfTypeQueryInMutationResult } from './require-field-of-type-query-in-mutation-result.js';
30
+ import { rule as requireIdWhenAvailable } from './require-id-when-available.js';
31
+ import { rule as requireNullableFieldsWithOneof } from './require-nullable-fields-with-oneof.js';
32
+ import { rule as requireTypePatternWithOneof } from './require-type-pattern-with-oneof.js';
33
+ import { rule as selectionSetDepth } from './selection-set-depth.js';
34
+ import { rule as strictIdInTypes } from './strict-id-in-types.js';
35
+ import { rule as uniqueFragmentName } from './unique-fragment-name.js';
36
+ import { rule as uniqueOperationName } from './unique-operation-name.js';
37
+ export const rules = {
38
+ ...GRAPHQL_JS_VALIDATIONS,
39
+ alphabetize,
40
+ 'description-style': descriptionStyle,
41
+ 'input-name': inputName,
42
+ 'lone-executable-definition': loneExecutableDefinition,
43
+ 'match-document-filename': matchDocumentFilename,
44
+ 'naming-convention': namingConvention,
45
+ 'no-anonymous-operations': noAnonymousOperations,
46
+ 'no-case-insensitive-enum-values-duplicates': noCaseInsensitiveEnumValuesDuplicates,
47
+ 'no-deprecated': noDeprecated,
48
+ 'no-duplicate-fields': noDuplicateFields,
49
+ 'no-hashtag-description': noHashtagDescription,
50
+ 'no-one-place-fragments': noOnePlaceFragments,
51
+ 'no-root-type': noRootType,
52
+ 'no-scalar-result-type-on-mutation': noScalarResultTypeOnMutation,
53
+ 'no-typename-prefix': noTypenamePrefix,
54
+ 'no-unreachable-types': noUnreachableTypes,
55
+ 'no-unused-fields': noUnusedFields,
56
+ 'relay-arguments': relayArguments,
57
+ 'relay-connection-types': relayConnectionTypes,
58
+ 'relay-edge-types': relayEdgeTypes,
59
+ 'relay-page-info': relayPageInfo,
60
+ 'require-deprecation-date': requireDeprecationDate,
61
+ 'require-deprecation-reason': requireDeprecationReason,
62
+ 'require-description': requireDescription,
63
+ 'require-field-of-type-query-in-mutation-result': requireFieldOfTypeQueryInMutationResult,
64
+ 'require-id-when-available': requireIdWhenAvailable,
65
+ 'require-nullable-fields-with-oneof': requireNullableFieldsWithOneof,
66
+ 'require-type-pattern-with-oneof': requireTypePatternWithOneof,
67
+ 'selection-set-depth': selectionSetDepth,
68
+ 'strict-id-in-types': strictIdInTypes,
69
+ 'unique-fragment-name': uniqueFragmentName,
70
+ 'unique-operation-name': uniqueOperationName,
71
+ };