@graphql-eslint/eslint-plugin 4.0.0-alpha.10 → 4.0.0-alpha.12

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/cjs/index.d.cts CHANGED
@@ -117,7 +117,9 @@ declare const _default: {
117
117
  'no-scalar-result-type-on-mutation': GraphQLESLintRule;
118
118
  'no-typename-prefix': GraphQLESLintRule;
119
119
  'no-unreachable-types': GraphQLESLintRule;
120
- 'no-unused-fields': GraphQLESLintRule;
120
+ 'no-unused-fields': GraphQLESLintRule<{
121
+ ignoredFieldSelectors?: string[] | undefined;
122
+ }[]>;
121
123
  'relay-arguments': GraphQLESLintRule<{
122
124
  includeBoth: boolean;
123
125
  }[], true>;
package/cjs/meta.js CHANGED
@@ -1,5 +1,5 @@
1
1
  "use strict";Object.defineProperty(exports, "__esModule", {value: true});require('./chunk-UIAXBAMD.js');
2
- const version = "4.0.0-alpha.10";
2
+ const version = "4.0.0-alpha.12";
3
3
 
4
4
 
5
5
  exports.version = version;
@@ -81,7 +81,9 @@ declare const rules: {
81
81
  'no-scalar-result-type-on-mutation': GraphQLESLintRule;
82
82
  'no-typename-prefix': GraphQLESLintRule;
83
83
  'no-unreachable-types': GraphQLESLintRule;
84
- 'no-unused-fields': GraphQLESLintRule;
84
+ 'no-unused-fields': GraphQLESLintRule<{
85
+ ignoredFieldSelectors?: string[] | undefined;
86
+ }[]>;
85
87
  'relay-arguments': GraphQLESLintRule<{
86
88
  includeBoth: boolean;
87
89
  }[], true>;
@@ -384,12 +384,14 @@ ${_utilsjs.TYPES_KINDS.map((kind) => `- \`${kind}\``).join(`
384
384
  };
385
385
  }
386
386
  }, checkUnderscore = (isLeading) => (node) => {
387
+ if (node.parent.kind === "Field" && node.parent.alias !== node)
388
+ return;
387
389
  const suggestedName = node.value.replace(isLeading ? /^_+/ : /_+$/, "");
388
390
  report(node, `${isLeading ? "Leading" : "Trailing"} underscores are not allowed`, [
389
391
  suggestedName
390
392
  ]);
391
393
  }, listeners = {};
392
- allowLeadingUnderscore || (listeners["Name[value=/^_/]:matches([parent.kind!=Field], [parent.kind=Field][parent.alias])"] = checkUnderscore(!0)), allowTrailingUnderscore || (listeners["Name[value=/_$/]:matches([parent.kind!=Field], [parent.kind=Field][parent.alias])"] = checkUnderscore(!1));
394
+ allowLeadingUnderscore || (listeners["Name[value=/^_/]"] = checkUnderscore(!0)), allowTrailingUnderscore || (listeners["Name[value=/_$/]"] = checkUnderscore(!1));
393
395
  const selectors = new Set(
394
396
  [types && _utilsjs.TYPES_KINDS, Object.keys(restOptions)].flat().filter(_utilsjs.truthy)
395
397
  );
@@ -1,13 +1,34 @@
1
+ import { FromSchema } from 'json-schema-to-ts';
1
2
  import { GraphQLESLintRule } from '../../types.cjs';
2
3
  import 'eslint';
3
4
  import 'estree';
4
5
  import 'graphql';
5
6
  import 'graphql-config';
6
- import 'json-schema-to-ts';
7
7
  import '../../estree-converter/types.cjs';
8
8
  import '../../siblings.cjs';
9
9
  import '@graphql-tools/utils';
10
10
 
11
- declare const rule: GraphQLESLintRule;
11
+ declare const schema: {
12
+ readonly type: "array";
13
+ readonly maxItems: 1;
14
+ readonly items: {
15
+ readonly type: "object";
16
+ readonly additionalProperties: false;
17
+ readonly properties: {
18
+ readonly ignoredFieldSelectors: {
19
+ readonly type: "array";
20
+ readonly uniqueItems: true;
21
+ readonly minItems: 1;
22
+ readonly description: string;
23
+ readonly items: {
24
+ readonly type: "string";
25
+ readonly pattern: "^\\[(.+)]$";
26
+ };
27
+ };
28
+ };
29
+ };
30
+ };
31
+ type RuleOptions = FromSchema<typeof schema>;
32
+ declare const rule: GraphQLESLintRule<RuleOptions>;
12
33
 
13
- export { rule };
34
+ export { type RuleOptions, rule };
@@ -2,12 +2,105 @@
2
2
  var _graphql = require('graphql');
3
3
  var _cachejs = require('../../cache.js');
4
4
  var _utilsjs = require('../../utils.js');
5
- const RULE_ID = "no-unused-fields", usedFieldsCache = new (0, _cachejs.ModuleCache)();
6
- function getUsedFields(schema, operations) {
7
- const cachedValue = usedFieldsCache.get(schema);
5
+ const RULE_ID = "no-unused-fields", RELAY_SCHEMA = (
6
+ /* GraphQL */
7
+ `
8
+ # Root Query Type
9
+ type Query {
10
+ user: User
11
+ }
12
+
13
+ # User Type
14
+ type User {
15
+ id: ID!
16
+ name: String!
17
+ friends(first: Int, after: String): FriendConnection!
18
+ }
19
+
20
+ # FriendConnection Type (Relay Connection)
21
+ type FriendConnection {
22
+ edges: [FriendEdge]
23
+ pageInfo: PageInfo!
24
+ }
25
+
26
+ # FriendEdge Type
27
+ type FriendEdge {
28
+ cursor: String!
29
+ node: Friend!
30
+ }
31
+
32
+ # Friend Type
33
+ type Friend {
34
+ id: ID!
35
+ name: String!
36
+ }
37
+
38
+ # PageInfo Type (Relay Pagination)
39
+ type PageInfo {
40
+ hasPreviousPage: Boolean!
41
+ hasNextPage: Boolean!
42
+ startCursor: String
43
+ endCursor: String
44
+ }
45
+ `
46
+ ), RELAY_QUERY = (
47
+ /* GraphQL */
48
+ `
49
+ query {
50
+ user {
51
+ id
52
+ name
53
+ friends(first: 10) {
54
+ edges {
55
+ node {
56
+ id
57
+ name
58
+ }
59
+ }
60
+ }
61
+ }
62
+ }
63
+ `
64
+ ), RELAY_DEFAULT_IGNORED_FIELD_SELECTORS = [
65
+ "[parent.name.value=PageInfo][name.value=/(endCursor|startCursor|hasNextPage|hasPreviousPage)/]",
66
+ "[parent.name.value=/Edge$/][name.value=cursor]",
67
+ "[parent.name.value=/Connection$/][name.value=pageInfo]"
68
+ ], schema = {
69
+ type: "array",
70
+ maxItems: 1,
71
+ items: {
72
+ type: "object",
73
+ additionalProperties: !1,
74
+ properties: {
75
+ ignoredFieldSelectors: {
76
+ type: "array",
77
+ uniqueItems: !0,
78
+ minItems: 1,
79
+ description: [
80
+ "Fields that will be ignored and are allowed to be unused.",
81
+ "",
82
+ "E.g. The following selector will ignore all the relay pagination fields for every connection exposed in the schema:",
83
+ "```json",
84
+ JSON.stringify(RELAY_DEFAULT_IGNORED_FIELD_SELECTORS, null, 2),
85
+ "```",
86
+ "",
87
+ "> These fields are defined by ESLint [`selectors`](https://eslint.org/docs/developer-guide/selectors).",
88
+ "> Paste or drop code into the editor in [ASTExplorer](https://astexplorer.net) and inspect the generated AST to compose your selector."
89
+ ].join(`
90
+ `),
91
+ items: {
92
+ type: "string",
93
+ pattern: "^\\[(.+)]$"
94
+ }
95
+ }
96
+ }
97
+ }
98
+ }, usedFieldsCache = new (0, _cachejs.ModuleCache)();
99
+ function getUsedFields(schema2, operations) {
100
+ const cachedValue = usedFieldsCache.get(schema2);
8
101
  if (process.env.NODE_ENV !== "test" && cachedValue)
9
102
  return cachedValue;
10
- const usedFields = /* @__PURE__ */ Object.create(null), typeInfo = new (0, _graphql.TypeInfo)(schema), visitor = _graphql.visitWithTypeInfo.call(void 0, typeInfo, {
103
+ const usedFields = /* @__PURE__ */ Object.create(null), typeInfo = new (0, _graphql.TypeInfo)(schema2), visitor = _graphql.visitWithTypeInfo.call(void 0, typeInfo, {
11
104
  Field(node) {
12
105
  if (!typeInfo.getFieldDef())
13
106
  return !1;
@@ -17,7 +110,7 @@ function getUsedFields(schema, operations) {
17
110
  }), allDocuments = [...operations.getOperations(), ...operations.getFragments()];
18
111
  for (const { document } of allDocuments)
19
112
  _graphql.visit.call(void 0, document, visitor);
20
- return usedFieldsCache.set(schema, usedFields), usedFields;
113
+ return usedFieldsCache.set(schema2, usedFields), usedFields;
21
114
  }
22
115
  const rule = {
23
116
  meta: {
@@ -79,17 +172,34 @@ const rule = {
79
172
  }
80
173
  `
81
174
  )
175
+ },
176
+ {
177
+ title: "Correct (ignoring fields)",
178
+ usage: [{ ignoredFieldSelectors: RELAY_DEFAULT_IGNORED_FIELD_SELECTORS }],
179
+ code: (
180
+ /* GraphQL */
181
+ `
182
+ ### 1\uFE0F\u20E3 YOUR SCHEMA
183
+ ${RELAY_SCHEMA}
184
+
185
+ ### 2\uFE0F\u20E3 YOUR QUERY
186
+ ${RELAY_QUERY}
187
+ `
188
+ )
82
189
  }
83
190
  ]
84
191
  },
85
192
  type: "suggestion",
86
- schema: [],
193
+ schema,
87
194
  hasSuggestions: !0
88
195
  },
89
196
  create(context) {
90
- const schema = _utilsjs.requireGraphQLSchemaFromContext.call(void 0, RULE_ID, context), siblingsOperations = _utilsjs.requireSiblingsOperations.call(void 0, RULE_ID, context), usedFields = getUsedFields(schema, siblingsOperations);
197
+ const schema2 = _utilsjs.requireGraphQLSchemaFromContext.call(void 0, RULE_ID, context), siblingsOperations = _utilsjs.requireSiblingsOperations.call(void 0, RULE_ID, context), usedFields = getUsedFields(schema2, siblingsOperations), { ignoredFieldSelectors } = context.options[0] || {};
91
198
  return {
92
- FieldDefinition(node) {
199
+ [(ignoredFieldSelectors || []).reduce(
200
+ (acc, selector2) => `${acc}:not(${selector2})`,
201
+ "FieldDefinition"
202
+ )](node) {
93
203
  const fieldName = node.name.value, parentTypeName = node.parent.name.value;
94
204
  _optionalChain([usedFields, 'access', _ => _[parentTypeName], 'optionalAccess', _2 => _2.has, 'call', _3 => _3(fieldName)]) || context.report({
95
205
  node: node.name,
@@ -104,7 +104,7 @@ Include it in your selection set{{ addition }}.`
104
104
  schema
105
105
  },
106
106
  create(context) {
107
- const schema2 = _utilsjs.requireGraphQLSchemaFromContext.call(void 0, RULE_ID, context), siblings = _utilsjs.requireSiblingsOperations.call(void 0, RULE_ID, context), { fieldName = DEFAULT_ID_FIELD_NAME } = context.options[0] || {}, idNames = _utils.asArray.call(void 0, fieldName), selector = "OperationDefinition SelectionSet[parent.kind!=/(^OperationDefinition|InlineFragment)$/]", typeInfo = new (0, _graphql.TypeInfo)(schema2);
107
+ const schema2 = _utilsjs.requireGraphQLSchemaFromContext.call(void 0, RULE_ID, context), siblings = _utilsjs.requireSiblingsOperations.call(void 0, RULE_ID, context), { fieldName = DEFAULT_ID_FIELD_NAME } = context.options[0] || {}, idNames = _utils.asArray.call(void 0, fieldName), selector = "SelectionSet[parent.kind!=/(^OperationDefinition|InlineFragment)$/]", typeInfo = new (0, _graphql.TypeInfo)(schema2);
108
108
  function checkFragments(node) {
109
109
  for (const selection of node.selections) {
110
110
  if (selection.kind !== _graphql.Kind.FRAGMENT_SPREAD)
package/esm/index.d.ts CHANGED
@@ -117,7 +117,9 @@ declare const _default: {
117
117
  'no-scalar-result-type-on-mutation': GraphQLESLintRule;
118
118
  'no-typename-prefix': GraphQLESLintRule;
119
119
  'no-unreachable-types': GraphQLESLintRule;
120
- 'no-unused-fields': GraphQLESLintRule;
120
+ 'no-unused-fields': GraphQLESLintRule<{
121
+ ignoredFieldSelectors?: string[] | undefined;
122
+ }[]>;
121
123
  'relay-arguments': GraphQLESLintRule<{
122
124
  includeBoth: boolean;
123
125
  }[], true>;
package/esm/meta.js CHANGED
@@ -1,5 +1,5 @@
1
1
  import "./chunk-UIAXBAMD.js";
2
- const version = "4.0.0-alpha.10";
2
+ const version = "4.0.0-alpha.12";
3
3
  export {
4
4
  version
5
5
  };
@@ -81,7 +81,9 @@ declare const rules: {
81
81
  'no-scalar-result-type-on-mutation': GraphQLESLintRule;
82
82
  'no-typename-prefix': GraphQLESLintRule;
83
83
  'no-unreachable-types': GraphQLESLintRule;
84
- 'no-unused-fields': GraphQLESLintRule;
84
+ 'no-unused-fields': GraphQLESLintRule<{
85
+ ignoredFieldSelectors?: string[] | undefined;
86
+ }[]>;
85
87
  'relay-arguments': GraphQLESLintRule<{
86
88
  includeBoth: boolean;
87
89
  }[], true>;
@@ -384,12 +384,14 @@ ${TYPES_KINDS.map((kind) => `- \`${kind}\``).join(`
384
384
  };
385
385
  }
386
386
  }, checkUnderscore = (isLeading) => (node) => {
387
+ if (node.parent.kind === "Field" && node.parent.alias !== node)
388
+ return;
387
389
  const suggestedName = node.value.replace(isLeading ? /^_+/ : /_+$/, "");
388
390
  report(node, `${isLeading ? "Leading" : "Trailing"} underscores are not allowed`, [
389
391
  suggestedName
390
392
  ]);
391
393
  }, listeners = {};
392
- allowLeadingUnderscore || (listeners["Name[value=/^_/]:matches([parent.kind!=Field], [parent.kind=Field][parent.alias])"] = checkUnderscore(!0)), allowTrailingUnderscore || (listeners["Name[value=/_$/]:matches([parent.kind!=Field], [parent.kind=Field][parent.alias])"] = checkUnderscore(!1));
394
+ allowLeadingUnderscore || (listeners["Name[value=/^_/]"] = checkUnderscore(!0)), allowTrailingUnderscore || (listeners["Name[value=/_$/]"] = checkUnderscore(!1));
393
395
  const selectors = new Set(
394
396
  [types && TYPES_KINDS, Object.keys(restOptions)].flat().filter(truthy)
395
397
  );
@@ -1,13 +1,34 @@
1
+ import { FromSchema } from 'json-schema-to-ts';
1
2
  import { GraphQLESLintRule } from '../../types.js';
2
3
  import 'eslint';
3
4
  import 'estree';
4
5
  import 'graphql';
5
6
  import 'graphql-config';
6
- import 'json-schema-to-ts';
7
7
  import '../../estree-converter/types.js';
8
8
  import '../../siblings.js';
9
9
  import '@graphql-tools/utils';
10
10
 
11
- declare const rule: GraphQLESLintRule;
11
+ declare const schema: {
12
+ readonly type: "array";
13
+ readonly maxItems: 1;
14
+ readonly items: {
15
+ readonly type: "object";
16
+ readonly additionalProperties: false;
17
+ readonly properties: {
18
+ readonly ignoredFieldSelectors: {
19
+ readonly type: "array";
20
+ readonly uniqueItems: true;
21
+ readonly minItems: 1;
22
+ readonly description: string;
23
+ readonly items: {
24
+ readonly type: "string";
25
+ readonly pattern: "^\\[(.+)]$";
26
+ };
27
+ };
28
+ };
29
+ };
30
+ };
31
+ type RuleOptions = FromSchema<typeof schema>;
32
+ declare const rule: GraphQLESLintRule<RuleOptions>;
12
33
 
13
- export { rule };
34
+ export { type RuleOptions, rule };
@@ -2,12 +2,105 @@ import "../../chunk-UIAXBAMD.js";
2
2
  import { TypeInfo, visit, visitWithTypeInfo } from "graphql";
3
3
  import { ModuleCache } from "../../cache.js";
4
4
  import { requireGraphQLSchemaFromContext, requireSiblingsOperations } from "../../utils.js";
5
- const RULE_ID = "no-unused-fields", usedFieldsCache = new ModuleCache();
6
- function getUsedFields(schema, operations) {
7
- const cachedValue = usedFieldsCache.get(schema);
5
+ const RULE_ID = "no-unused-fields", RELAY_SCHEMA = (
6
+ /* GraphQL */
7
+ `
8
+ # Root Query Type
9
+ type Query {
10
+ user: User
11
+ }
12
+
13
+ # User Type
14
+ type User {
15
+ id: ID!
16
+ name: String!
17
+ friends(first: Int, after: String): FriendConnection!
18
+ }
19
+
20
+ # FriendConnection Type (Relay Connection)
21
+ type FriendConnection {
22
+ edges: [FriendEdge]
23
+ pageInfo: PageInfo!
24
+ }
25
+
26
+ # FriendEdge Type
27
+ type FriendEdge {
28
+ cursor: String!
29
+ node: Friend!
30
+ }
31
+
32
+ # Friend Type
33
+ type Friend {
34
+ id: ID!
35
+ name: String!
36
+ }
37
+
38
+ # PageInfo Type (Relay Pagination)
39
+ type PageInfo {
40
+ hasPreviousPage: Boolean!
41
+ hasNextPage: Boolean!
42
+ startCursor: String
43
+ endCursor: String
44
+ }
45
+ `
46
+ ), RELAY_QUERY = (
47
+ /* GraphQL */
48
+ `
49
+ query {
50
+ user {
51
+ id
52
+ name
53
+ friends(first: 10) {
54
+ edges {
55
+ node {
56
+ id
57
+ name
58
+ }
59
+ }
60
+ }
61
+ }
62
+ }
63
+ `
64
+ ), RELAY_DEFAULT_IGNORED_FIELD_SELECTORS = [
65
+ "[parent.name.value=PageInfo][name.value=/(endCursor|startCursor|hasNextPage|hasPreviousPage)/]",
66
+ "[parent.name.value=/Edge$/][name.value=cursor]",
67
+ "[parent.name.value=/Connection$/][name.value=pageInfo]"
68
+ ], schema = {
69
+ type: "array",
70
+ maxItems: 1,
71
+ items: {
72
+ type: "object",
73
+ additionalProperties: !1,
74
+ properties: {
75
+ ignoredFieldSelectors: {
76
+ type: "array",
77
+ uniqueItems: !0,
78
+ minItems: 1,
79
+ description: [
80
+ "Fields that will be ignored and are allowed to be unused.",
81
+ "",
82
+ "E.g. The following selector will ignore all the relay pagination fields for every connection exposed in the schema:",
83
+ "```json",
84
+ JSON.stringify(RELAY_DEFAULT_IGNORED_FIELD_SELECTORS, null, 2),
85
+ "```",
86
+ "",
87
+ "> These fields are defined by ESLint [`selectors`](https://eslint.org/docs/developer-guide/selectors).",
88
+ "> Paste or drop code into the editor in [ASTExplorer](https://astexplorer.net) and inspect the generated AST to compose your selector."
89
+ ].join(`
90
+ `),
91
+ items: {
92
+ type: "string",
93
+ pattern: "^\\[(.+)]$"
94
+ }
95
+ }
96
+ }
97
+ }
98
+ }, usedFieldsCache = new ModuleCache();
99
+ function getUsedFields(schema2, operations) {
100
+ const cachedValue = usedFieldsCache.get(schema2);
8
101
  if (process.env.NODE_ENV !== "test" && cachedValue)
9
102
  return cachedValue;
10
- const usedFields = /* @__PURE__ */ Object.create(null), typeInfo = new TypeInfo(schema), visitor = visitWithTypeInfo(typeInfo, {
103
+ const usedFields = /* @__PURE__ */ Object.create(null), typeInfo = new TypeInfo(schema2), visitor = visitWithTypeInfo(typeInfo, {
11
104
  Field(node) {
12
105
  if (!typeInfo.getFieldDef())
13
106
  return !1;
@@ -17,7 +110,7 @@ function getUsedFields(schema, operations) {
17
110
  }), allDocuments = [...operations.getOperations(), ...operations.getFragments()];
18
111
  for (const { document } of allDocuments)
19
112
  visit(document, visitor);
20
- return usedFieldsCache.set(schema, usedFields), usedFields;
113
+ return usedFieldsCache.set(schema2, usedFields), usedFields;
21
114
  }
22
115
  const rule = {
23
116
  meta: {
@@ -79,17 +172,34 @@ const rule = {
79
172
  }
80
173
  `
81
174
  )
175
+ },
176
+ {
177
+ title: "Correct (ignoring fields)",
178
+ usage: [{ ignoredFieldSelectors: RELAY_DEFAULT_IGNORED_FIELD_SELECTORS }],
179
+ code: (
180
+ /* GraphQL */
181
+ `
182
+ ### 1\uFE0F\u20E3 YOUR SCHEMA
183
+ ${RELAY_SCHEMA}
184
+
185
+ ### 2\uFE0F\u20E3 YOUR QUERY
186
+ ${RELAY_QUERY}
187
+ `
188
+ )
82
189
  }
83
190
  ]
84
191
  },
85
192
  type: "suggestion",
86
- schema: [],
193
+ schema,
87
194
  hasSuggestions: !0
88
195
  },
89
196
  create(context) {
90
- const schema = requireGraphQLSchemaFromContext(RULE_ID, context), siblingsOperations = requireSiblingsOperations(RULE_ID, context), usedFields = getUsedFields(schema, siblingsOperations);
197
+ const schema2 = requireGraphQLSchemaFromContext(RULE_ID, context), siblingsOperations = requireSiblingsOperations(RULE_ID, context), usedFields = getUsedFields(schema2, siblingsOperations), { ignoredFieldSelectors } = context.options[0] || {};
91
198
  return {
92
- FieldDefinition(node) {
199
+ [(ignoredFieldSelectors || []).reduce(
200
+ (acc, selector2) => `${acc}:not(${selector2})`,
201
+ "FieldDefinition"
202
+ )](node) {
93
203
  const fieldName = node.name.value, parentTypeName = node.parent.name.value;
94
204
  usedFields[parentTypeName]?.has(fieldName) || context.report({
95
205
  node: node.name,
@@ -104,7 +104,7 @@ Include it in your selection set{{ addition }}.`
104
104
  schema
105
105
  },
106
106
  create(context) {
107
- const schema2 = requireGraphQLSchemaFromContext(RULE_ID, context), siblings = requireSiblingsOperations(RULE_ID, context), { fieldName = DEFAULT_ID_FIELD_NAME } = context.options[0] || {}, idNames = asArray(fieldName), selector = "OperationDefinition SelectionSet[parent.kind!=/(^OperationDefinition|InlineFragment)$/]", typeInfo = new TypeInfo(schema2);
107
+ const schema2 = requireGraphQLSchemaFromContext(RULE_ID, context), siblings = requireSiblingsOperations(RULE_ID, context), { fieldName = DEFAULT_ID_FIELD_NAME } = context.options[0] || {}, idNames = asArray(fieldName), selector = "SelectionSet[parent.kind!=/(^OperationDefinition|InlineFragment)$/]", typeInfo = new TypeInfo(schema2);
108
108
  function checkFragments(node) {
109
109
  for (const selection of node.selections) {
110
110
  if (selection.kind !== Kind.FRAGMENT_SPREAD)
package/index.browser.js CHANGED
@@ -341,8 +341,8 @@ function convertLocation(location) {
341
341
  }
342
342
 
343
343
  // src/estree-converter/converter.ts
344
- function convertToESTree(node, schema15) {
345
- let typeInfo = schema15 && new TypeInfo(schema15), visitor = {
344
+ function convertToESTree(node, schema16) {
345
+ let typeInfo = schema16 && new TypeInfo(schema16), visitor = {
346
346
  leave(node2, key, parent) {
347
347
  let leadingComments = "description" in node2 && node2.description ? [
348
348
  {
@@ -408,12 +408,12 @@ function requireSiblingsOperations(ruleId, context) {
408
408
  return siblingOperations;
409
409
  }
410
410
  function requireGraphQLSchemaFromContext(ruleId, context) {
411
- let { schema: schema15 } = context.sourceCode.parserServices;
412
- if (!schema15)
411
+ let { schema: schema16 } = context.sourceCode.parserServices;
412
+ if (!schema16)
413
413
  throw new Error(
414
414
  `Rule \`${ruleId}\` requires graphql-config \`schema\` field to be set and loaded. See https://the-guild.dev/graphql/config/docs/user/schema for more info`
415
415
  );
416
- return schema15;
416
+ return schema16;
417
417
  }
418
418
  var chalk = {
419
419
  red: (str) => `\x1B[31m${str}\x1B[39m`,
@@ -635,7 +635,7 @@ function parseForESLint(code, options) {
635
635
  `\`parserOptions.${key}\` was removed in graphql-eslint@4. Use physical graphql-config for setting schema and documents or \`parserOptions.graphQLConfig\` for programmatic usage.`
636
636
  );
637
637
  try {
638
- let { filePath } = options, { document } = parseGraphQLSDL(filePath, code, { noLocation: !1 }), project, schema15, documents;
638
+ let { filePath } = options, { document } = parseGraphQLSDL(filePath, code, { noLocation: !1 }), project, schema16, documents;
639
639
  documents = [
640
640
  parseGraphQLSDL(
641
641
  "operation.graphql",
@@ -644,14 +644,14 @@ function parseForESLint(code, options) {
644
644
  )
645
645
  ];
646
646
  try {
647
- schema15 = buildSchema(options.graphQLConfig.schema);
647
+ schema16 = buildSchema(options.graphQLConfig.schema);
648
648
  } catch (error) {
649
649
  throw error instanceof Error && (error.message = `Error while loading schema: ${error.message}`), error;
650
650
  }
651
- let rootTree = convertToESTree(document, schema15);
651
+ let rootTree = convertToESTree(document, schema16);
652
652
  return {
653
653
  services: {
654
- schema: schema15,
654
+ schema: schema16,
655
655
  siblingOperations: getSiblings(documents)
656
656
  },
657
657
  ast: {
@@ -1118,14 +1118,14 @@ import {
1118
1118
  import { validateSDL } from "graphql/validation/validate.js";
1119
1119
  function validateDocument({
1120
1120
  context,
1121
- schema: schema15 = null,
1121
+ schema: schema16 = null,
1122
1122
  documentNode,
1123
1123
  rule: rule35,
1124
1124
  hasDidYouMeanSuggestions
1125
1125
  }) {
1126
1126
  if (documentNode.definitions.length !== 0)
1127
1127
  try {
1128
- let validationErrors = schema15 ? validate(schema15, documentNode, [rule35]) : validateSDL(documentNode, null, [rule35]);
1128
+ let validationErrors = schema16 ? validate(schema16, documentNode, [rule35]) : validateSDL(documentNode, null, [rule35]);
1129
1129
  for (let error of validationErrors) {
1130
1130
  let { line, column } = error.locations[0], sourceCode = context.getSourceCode(), { tokens } = sourceCode.ast, token = tokens.find(
1131
1131
  (token2) => token2.loc.start.line === line && token2.loc.start.column === column - 1
@@ -1191,7 +1191,7 @@ var getFragmentDefsAndFragmentSpreads = (node) => {
1191
1191
  ruleId,
1192
1192
  rule: rule35,
1193
1193
  getDocumentNode,
1194
- schema: schema15 = [],
1194
+ schema: schema16 = [],
1195
1195
  hasDidYouMeanSuggestions
1196
1196
  }, docs) => ({
1197
1197
  [ruleId]: {
@@ -1204,16 +1204,16 @@ var getFragmentDefsAndFragmentSpreads = (node) => {
1204
1204
  description: `${docs.description}
1205
1205
  > This rule is a wrapper around a \`graphql-js\` validation function.`
1206
1206
  },
1207
- schema: schema15,
1207
+ schema: schema16,
1208
1208
  hasSuggestions: hasDidYouMeanSuggestions
1209
1209
  },
1210
1210
  create(context) {
1211
1211
  return {
1212
1212
  Document(node) {
1213
- let schema16 = docs.requiresSchema ? requireGraphQLSchemaFromContext(ruleId, context) : null, documentNode = getDocumentNode ? getDocumentNode({ ruleId, context, node: node.rawNode() }) : node.rawNode();
1213
+ let schema17 = docs.requiresSchema ? requireGraphQLSchemaFromContext(ruleId, context) : null, documentNode = getDocumentNode ? getDocumentNode({ ruleId, context, node: node.rawNode() }) : node.rawNode();
1214
1214
  validateDocument({
1215
1215
  context,
1216
- schema: schema16,
1216
+ schema: schema17,
1217
1217
  documentNode,
1218
1218
  rule: rule35,
1219
1219
  hasDidYouMeanSuggestions
@@ -2509,12 +2509,14 @@ ${TYPES_KINDS.map((kind) => `- \`${kind}\``).join(`
2509
2509
  };
2510
2510
  }
2511
2511
  }, checkUnderscore = (isLeading) => (node) => {
2512
+ if (node.parent.kind === "Field" && node.parent.alias !== node)
2513
+ return;
2512
2514
  let suggestedName = node.value.replace(isLeading ? /^_+/ : /_+$/, "");
2513
2515
  report(node, `${isLeading ? "Leading" : "Trailing"} underscores are not allowed`, [
2514
2516
  suggestedName
2515
2517
  ]);
2516
2518
  }, listeners = {};
2517
- allowLeadingUnderscore || (listeners["Name[value=/^_/]:matches([parent.kind!=Field], [parent.kind=Field][parent.alias])"] = checkUnderscore(!0)), allowTrailingUnderscore || (listeners["Name[value=/_$/]:matches([parent.kind!=Field], [parent.kind=Field][parent.alias])"] = checkUnderscore(!1));
2519
+ allowLeadingUnderscore || (listeners["Name[value=/^_/]"] = checkUnderscore(!0)), allowTrailingUnderscore || (listeners["Name[value=/_$/]"] = checkUnderscore(!1));
2518
2520
  let selectors = new Set(
2519
2521
  [types && TYPES_KINDS, Object.keys(restOptions)].flat().filter(truthy)
2520
2522
  );
@@ -3069,9 +3071,9 @@ var schema7 = {
3069
3071
  schema: schema7
3070
3072
  },
3071
3073
  create(context) {
3072
- let schema15 = requireGraphQLSchemaFromContext("no-root-type", context), disallow = new Set(context.options[0].disallow), rootTypeNames = [
3073
- disallow.has("mutation") && schema15.getMutationType(),
3074
- disallow.has("subscription") && schema15.getSubscriptionType()
3074
+ let schema16 = requireGraphQLSchemaFromContext("no-root-type", context), disallow = new Set(context.options[0].disallow), rootTypeNames = [
3075
+ disallow.has("mutation") && schema16.getMutationType(),
3076
+ disallow.has("subscription") && schema16.getSubscriptionType()
3075
3077
  ].filter(truthy).map((type) => type.name).join("|");
3076
3078
  return rootTypeNames ? {
3077
3079
  [`:matches(ObjectTypeDefinition, ObjectTypeExtension) > .name[value=/^(${rootTypeNames})$/]`](node) {
@@ -3130,13 +3132,13 @@ var RULE_ID8 = "no-scalar-result-type-on-mutation", rule13 = {
3130
3132
  schema: []
3131
3133
  },
3132
3134
  create(context) {
3133
- let schema15 = requireGraphQLSchemaFromContext(RULE_ID8, context), mutationType = schema15.getMutationType();
3135
+ let schema16 = requireGraphQLSchemaFromContext(RULE_ID8, context), mutationType = schema16.getMutationType();
3134
3136
  return mutationType ? {
3135
3137
  [[
3136
3138
  `:matches(ObjectTypeDefinition, ObjectTypeExtension)[name.value=${mutationType.name}]`,
3137
3139
  "> FieldDefinition > .gqlType Name"
3138
3140
  ].join(" ")](node) {
3139
- let typeName = node.value, graphQLType = schema15.getType(typeName);
3141
+ let typeName = node.value, graphQLType = schema16.getType(typeName);
3140
3142
  if (isScalarType(graphQLType)) {
3141
3143
  let fieldDef = node.parent;
3142
3144
  for (; fieldDef.kind !== Kind12.FIELD_DEFINITION; )
@@ -3258,8 +3260,8 @@ var RULE_ID9 = "no-unreachable-types", KINDS = [
3258
3260
  DirectiveLocation.INLINE_FRAGMENT,
3259
3261
  DirectiveLocation.VARIABLE_DEFINITION
3260
3262
  ]);
3261
- function getReachableTypes(schema15) {
3262
- let cachedValue = reachableTypesCache.get(schema15);
3263
+ function getReachableTypes(schema16) {
3264
+ let cachedValue = reachableTypesCache.get(schema16);
3263
3265
  if (cachedValue)
3264
3266
  return cachedValue;
3265
3267
  let reachableTypes = /* @__PURE__ */ new Set(), collect = (node) => {
@@ -3267,9 +3269,9 @@ function getReachableTypes(schema15) {
3267
3269
  if (reachableTypes.has(typeName))
3268
3270
  return;
3269
3271
  reachableTypes.add(typeName);
3270
- let type = schema15.getType(typeName) || schema15.getDirective(typeName);
3272
+ let type = schema16.getType(typeName) || schema16.getDirective(typeName);
3271
3273
  if (isInterfaceType(type)) {
3272
- let { objects, interfaces } = schema15.getImplementations(type);
3274
+ let { objects, interfaces } = schema16.getImplementations(type);
3273
3275
  for (let { astNode } of [...objects, ...interfaces])
3274
3276
  visit5(astNode, visitor);
3275
3277
  } else type?.astNode && visit5(type.astNode, visitor);
@@ -3283,14 +3285,14 @@ function getReachableTypes(schema15) {
3283
3285
  NamedType: collect
3284
3286
  };
3285
3287
  for (let type of [
3286
- schema15,
3288
+ schema16,
3287
3289
  // visiting SchemaDefinition node
3288
- schema15.getQueryType(),
3289
- schema15.getMutationType(),
3290
- schema15.getSubscriptionType()
3290
+ schema16.getQueryType(),
3291
+ schema16.getMutationType(),
3292
+ schema16.getSubscriptionType()
3291
3293
  ])
3292
3294
  type?.astNode && visit5(type.astNode, visitor);
3293
- for (let node of schema15.getDirectives())
3295
+ for (let node of schema16.getDirectives())
3294
3296
  if (node.locations.some((location) => RequestDirectiveLocations.has(location))) {
3295
3297
  reachableTypes.add(node.name);
3296
3298
  for (let arg of node.args) {
@@ -3298,7 +3300,7 @@ function getReachableTypes(schema15) {
3298
3300
  argTypeName && reachableTypes.add(argTypeName);
3299
3301
  }
3300
3302
  }
3301
- return reachableTypesCache.set(schema15, reachableTypes), reachableTypes;
3303
+ return reachableTypesCache.set(schema16, reachableTypes), reachableTypes;
3302
3304
  }
3303
3305
  var rule15 = {
3304
3306
  meta: {
@@ -3351,7 +3353,7 @@ var rule15 = {
3351
3353
  hasSuggestions: !0
3352
3354
  },
3353
3355
  create(context) {
3354
- let schema15 = requireGraphQLSchemaFromContext(RULE_ID9, context), reachableTypes = getReachableTypes(schema15);
3356
+ let schema16 = requireGraphQLSchemaFromContext(RULE_ID9, context), reachableTypes = getReachableTypes(schema16);
3355
3357
  return {
3356
3358
  [`:matches(${KINDS}) > .name`](node) {
3357
3359
  let typeName = node.value;
@@ -3379,12 +3381,105 @@ var rule15 = {
3379
3381
 
3380
3382
  // src/rules/no-unused-fields/index.ts
3381
3383
  import { TypeInfo as TypeInfo2, visit as visit6, visitWithTypeInfo as visitWithTypeInfo2 } from "graphql";
3382
- var RULE_ID10 = "no-unused-fields", usedFieldsCache = new ModuleCache();
3383
- function getUsedFields(schema15, operations) {
3384
- let cachedValue = usedFieldsCache.get(schema15);
3384
+ var RULE_ID10 = "no-unused-fields", RELAY_SCHEMA = (
3385
+ /* GraphQL */
3386
+ `
3387
+ # Root Query Type
3388
+ type Query {
3389
+ user: User
3390
+ }
3391
+
3392
+ # User Type
3393
+ type User {
3394
+ id: ID!
3395
+ name: String!
3396
+ friends(first: Int, after: String): FriendConnection!
3397
+ }
3398
+
3399
+ # FriendConnection Type (Relay Connection)
3400
+ type FriendConnection {
3401
+ edges: [FriendEdge]
3402
+ pageInfo: PageInfo!
3403
+ }
3404
+
3405
+ # FriendEdge Type
3406
+ type FriendEdge {
3407
+ cursor: String!
3408
+ node: Friend!
3409
+ }
3410
+
3411
+ # Friend Type
3412
+ type Friend {
3413
+ id: ID!
3414
+ name: String!
3415
+ }
3416
+
3417
+ # PageInfo Type (Relay Pagination)
3418
+ type PageInfo {
3419
+ hasPreviousPage: Boolean!
3420
+ hasNextPage: Boolean!
3421
+ startCursor: String
3422
+ endCursor: String
3423
+ }
3424
+ `
3425
+ ), RELAY_QUERY = (
3426
+ /* GraphQL */
3427
+ `
3428
+ query {
3429
+ user {
3430
+ id
3431
+ name
3432
+ friends(first: 10) {
3433
+ edges {
3434
+ node {
3435
+ id
3436
+ name
3437
+ }
3438
+ }
3439
+ }
3440
+ }
3441
+ }
3442
+ `
3443
+ ), RELAY_DEFAULT_IGNORED_FIELD_SELECTORS = [
3444
+ "[parent.name.value=PageInfo][name.value=/(endCursor|startCursor|hasNextPage|hasPreviousPage)/]",
3445
+ "[parent.name.value=/Edge$/][name.value=cursor]",
3446
+ "[parent.name.value=/Connection$/][name.value=pageInfo]"
3447
+ ], schema8 = {
3448
+ type: "array",
3449
+ maxItems: 1,
3450
+ items: {
3451
+ type: "object",
3452
+ additionalProperties: !1,
3453
+ properties: {
3454
+ ignoredFieldSelectors: {
3455
+ type: "array",
3456
+ uniqueItems: !0,
3457
+ minItems: 1,
3458
+ description: [
3459
+ "Fields that will be ignored and are allowed to be unused.",
3460
+ "",
3461
+ "E.g. The following selector will ignore all the relay pagination fields for every connection exposed in the schema:",
3462
+ "```json",
3463
+ JSON.stringify(RELAY_DEFAULT_IGNORED_FIELD_SELECTORS, null, 2),
3464
+ "```",
3465
+ "",
3466
+ "> These fields are defined by ESLint [`selectors`](https://eslint.org/docs/developer-guide/selectors).",
3467
+ "> Paste or drop code into the editor in [ASTExplorer](https://astexplorer.net) and inspect the generated AST to compose your selector."
3468
+ ].join(`
3469
+ `),
3470
+ items: {
3471
+ type: "string",
3472
+ pattern: "^\\[(.+)]$"
3473
+ }
3474
+ }
3475
+ }
3476
+ }
3477
+ }, usedFieldsCache = new ModuleCache();
3478
+ function getUsedFields(schema16, operations) {
3479
+ let cachedValue = usedFieldsCache.get(schema16);
3385
3480
  if (cachedValue)
3386
3481
  return cachedValue;
3387
- let usedFields = /* @__PURE__ */ Object.create(null), typeInfo = new TypeInfo2(schema15), visitor = visitWithTypeInfo2(typeInfo, {
3482
+ let usedFields = /* @__PURE__ */ Object.create(null), typeInfo = new TypeInfo2(schema16), visitor = visitWithTypeInfo2(typeInfo, {
3388
3483
  Field(node) {
3389
3484
  if (!typeInfo.getFieldDef())
3390
3485
  return !1;
@@ -3394,7 +3489,7 @@ function getUsedFields(schema15, operations) {
3394
3489
  }), allDocuments = [...operations.getOperations(), ...operations.getFragments()];
3395
3490
  for (let { document } of allDocuments)
3396
3491
  visit6(document, visitor);
3397
- return usedFieldsCache.set(schema15, usedFields), usedFields;
3492
+ return usedFieldsCache.set(schema16, usedFields), usedFields;
3398
3493
  }
3399
3494
  var rule16 = {
3400
3495
  meta: {
@@ -3456,17 +3551,34 @@ var rule16 = {
3456
3551
  }
3457
3552
  `
3458
3553
  )
3554
+ },
3555
+ {
3556
+ title: "Correct (ignoring fields)",
3557
+ usage: [{ ignoredFieldSelectors: RELAY_DEFAULT_IGNORED_FIELD_SELECTORS }],
3558
+ code: (
3559
+ /* GraphQL */
3560
+ `
3561
+ ### 1\uFE0F\u20E3 YOUR SCHEMA
3562
+ ${RELAY_SCHEMA}
3563
+
3564
+ ### 2\uFE0F\u20E3 YOUR QUERY
3565
+ ${RELAY_QUERY}
3566
+ `
3567
+ )
3459
3568
  }
3460
3569
  ]
3461
3570
  },
3462
3571
  type: "suggestion",
3463
- schema: [],
3572
+ schema: schema8,
3464
3573
  hasSuggestions: !0
3465
3574
  },
3466
3575
  create(context) {
3467
- let schema15 = requireGraphQLSchemaFromContext(RULE_ID10, context), siblingsOperations = requireSiblingsOperations(RULE_ID10, context), usedFields = getUsedFields(schema15, siblingsOperations);
3576
+ let schema16 = requireGraphQLSchemaFromContext(RULE_ID10, context), siblingsOperations = requireSiblingsOperations(RULE_ID10, context), usedFields = getUsedFields(schema16, siblingsOperations), { ignoredFieldSelectors } = context.options[0] || {};
3468
3577
  return {
3469
- FieldDefinition(node) {
3578
+ [(ignoredFieldSelectors || []).reduce(
3579
+ (acc, selector2) => `${acc}:not(${selector2})`,
3580
+ "FieldDefinition"
3581
+ )](node) {
3470
3582
  let fieldName = node.name.value, parentTypeName = node.parent.name.value;
3471
3583
  usedFields[parentTypeName]?.has(fieldName) || context.report({
3472
3584
  node: node.name,
@@ -3489,7 +3601,7 @@ var rule16 = {
3489
3601
 
3490
3602
  // src/rules/relay-arguments/index.ts
3491
3603
  import { isScalarType as isScalarType2, Kind as Kind14 } from "graphql";
3492
- var RULE_ID11 = "relay-arguments", MISSING_ARGUMENTS = "MISSING_ARGUMENTS", schema8 = {
3604
+ var RULE_ID11 = "relay-arguments", MISSING_ARGUMENTS = "MISSING_ARGUMENTS", schema9 = {
3493
3605
  type: "array",
3494
3606
  maxItems: 1,
3495
3607
  items: {
@@ -3555,10 +3667,10 @@ var RULE_ID11 = "relay-arguments", MISSING_ARGUMENTS = "MISSING_ARGUMENTS", sche
3555
3667
  messages: {
3556
3668
  [MISSING_ARGUMENTS]: "A field that returns a Connection type must include forward pagination arguments (`first` and `after`), backward pagination arguments (`last` and `before`), or both."
3557
3669
  },
3558
- schema: schema8
3670
+ schema: schema9
3559
3671
  },
3560
3672
  create(context) {
3561
- let schema15 = requireGraphQLSchemaFromContext(RULE_ID11, context), { includeBoth = !0 } = context.options[0] || {};
3673
+ let schema16 = requireGraphQLSchemaFromContext(RULE_ID11, context), { includeBoth = !0 } = context.options[0] || {};
3562
3674
  return {
3563
3675
  "FieldDefinition > .gqlType Name[value=/Connection$/]"(node) {
3564
3676
  let fieldNode = node.parent;
@@ -3576,7 +3688,7 @@ var RULE_ID11 = "relay-arguments", MISSING_ARGUMENTS = "MISSING_ARGUMENTS", sche
3576
3688
  }
3577
3689
  function checkField(typeName, argumentName) {
3578
3690
  let argument = args[argumentName], hasArgument = !!argument, type = argument;
3579
- if (hasArgument && type.gqlType.kind === Kind14.NON_NULL_TYPE && (type = type.gqlType), !(hasArgument && type.gqlType.kind === Kind14.NAMED_TYPE && (type.gqlType.name.value === typeName || typeName === "String" && isScalarType2(schema15.getType(type.gqlType.name.value))))) {
3691
+ if (hasArgument && type.gqlType.kind === Kind14.NON_NULL_TYPE && (type = type.gqlType), !(hasArgument && type.gqlType.kind === Kind14.NAMED_TYPE && (type.gqlType.name.value === typeName || typeName === "String" && isScalarType2(schema16.getType(type.gqlType.name.value))))) {
3580
3692
  let returnType = typeName === "String" ? "String or Scalar" : typeName;
3581
3693
  context.report({
3582
3694
  node: (argument || fieldNode).name,
@@ -3686,7 +3798,7 @@ import {
3686
3798
  } from "graphql";
3687
3799
  import { getDocumentNodeFromSchema } from "@graphql-tools/utils";
3688
3800
  var RULE_ID12 = "relay-edge-types", MESSAGE_MUST_BE_OBJECT_TYPE = "MESSAGE_MUST_BE_OBJECT_TYPE", MESSAGE_MISSING_EDGE_SUFFIX = "MESSAGE_MISSING_EDGE_SUFFIX", MESSAGE_LIST_TYPE_ONLY_EDGE_TYPE = "MESSAGE_LIST_TYPE_ONLY_EDGE_TYPE", MESSAGE_SHOULD_IMPLEMENTS_NODE = "MESSAGE_SHOULD_IMPLEMENTS_NODE", edgeTypesCache;
3689
- function getEdgeTypes(schema15) {
3801
+ function getEdgeTypes(schema16) {
3690
3802
  if (edgeTypesCache)
3691
3803
  return edgeTypesCache;
3692
3804
  let edgeTypes = /* @__PURE__ */ new Set(), visitor = {
@@ -3695,14 +3807,14 @@ function getEdgeTypes(schema15) {
3695
3807
  return;
3696
3808
  let edges = node.fields?.find((field) => field.name.value === "edges");
3697
3809
  if (edges) {
3698
- let edgesTypeName = getTypeName(edges), edgesType = schema15.getType(edgesTypeName);
3810
+ let edgesTypeName = getTypeName(edges), edgesType = schema16.getType(edgesTypeName);
3699
3811
  isObjectType2(edgesType) && edgeTypes.add(edgesTypeName);
3700
3812
  }
3701
3813
  }
3702
- }, astNode = getDocumentNodeFromSchema(schema15);
3814
+ }, astNode = getDocumentNodeFromSchema(schema16);
3703
3815
  return visit7(astNode, visitor), edgeTypesCache = edgeTypes, edgeTypesCache;
3704
3816
  }
3705
- var schema9 = {
3817
+ var schema10 = {
3706
3818
  type: "array",
3707
3819
  maxItems: 1,
3708
3820
  items: {
@@ -3768,10 +3880,10 @@ var schema9 = {
3768
3880
  [MESSAGE_LIST_TYPE_ONLY_EDGE_TYPE]: "A list type should only wrap an edge type.",
3769
3881
  [MESSAGE_SHOULD_IMPLEMENTS_NODE]: "Edge type's field `node` must implement `Node` interface."
3770
3882
  },
3771
- schema: schema9
3883
+ schema: schema10
3772
3884
  },
3773
3885
  create(context) {
3774
- let schema15 = requireGraphQLSchemaFromContext(RULE_ID12, context), edgeTypes = getEdgeTypes(schema15), options = {
3886
+ let schema16 = requireGraphQLSchemaFromContext(RULE_ID12, context), edgeTypes = getEdgeTypes(schema16), options = {
3775
3887
  withEdgeSuffix: !0,
3776
3888
  shouldImplementNode: !0,
3777
3889
  listTypeCanWrapOnlyEdgeType: !0,
@@ -3786,7 +3898,7 @@ var schema9 = {
3786
3898
  else if (!isNamedOrNonNullNamed(nodeField.gqlType))
3787
3899
  context.report({ node: nodeField.name, message: `Field \`node\` must ${message}` });
3788
3900
  else if (options.shouldImplementNode) {
3789
- let nodeReturnTypeName = getTypeName(nodeField.gqlType.rawNode()), type = schema15.getType(nodeReturnTypeName);
3901
+ let nodeReturnTypeName = getTypeName(nodeField.gqlType.rawNode()), type = schema16.getType(nodeReturnTypeName);
3790
3902
  if (!isObjectType2(type))
3791
3903
  return;
3792
3904
  type.astNode.interfaces?.some((n) => n.name.value === "Node") || context.report({ node: node.name, messageId: MESSAGE_SHOULD_IMPLEMENTS_NODE });
@@ -3801,10 +3913,10 @@ var schema9 = {
3801
3913
  return;
3802
3914
  }
3803
3915
  let typeName = getTypeName(cursorField.rawNode());
3804
- (!isNamedOrNonNullNamed(cursorField.gqlType) || typeName !== "String" && !isScalarType3(schema15.getType(typeName))) && context.report({ node: cursorField.name, message: `Field \`cursor\` must ${message}` });
3916
+ (!isNamedOrNonNullNamed(cursorField.gqlType) || typeName !== "String" && !isScalarType3(schema16.getType(typeName))) && context.report({ node: cursorField.name, message: `Field \`cursor\` must ${message}` });
3805
3917
  }, listeners = {
3806
3918
  ":matches(ObjectTypeDefinition, ObjectTypeExtension)[name.value=/Connection$/] > FieldDefinition[name.value=edges] > .gqlType Name"(node) {
3807
- let type = schema15.getType(node.value);
3919
+ let type = schema16.getType(node.value);
3808
3920
  isObjectType2(type) || context.report({ node, messageId: MESSAGE_MUST_BE_OBJECT_TYPE });
3809
3921
  },
3810
3922
  ":matches(ObjectTypeDefinition, ObjectTypeExtension)"(node) {
@@ -3863,8 +3975,8 @@ var RULE_ID13 = "relay-page-info", MESSAGE_MUST_EXIST = "MESSAGE_MUST_EXIST", ME
3863
3975
  schema: []
3864
3976
  },
3865
3977
  create(context) {
3866
- let schema15 = requireGraphQLSchemaFromContext(RULE_ID13, context);
3867
- return hasPageInfoChecked || (schema15.getType("PageInfo") || context.report({
3978
+ let schema16 = requireGraphQLSchemaFromContext(RULE_ID13, context);
3979
+ return hasPageInfoChecked || (schema16.getType("PageInfo") || context.report({
3868
3980
  loc: REPORT_ON_FIRST_CHARACTER,
3869
3981
  messageId: MESSAGE_MUST_EXIST
3870
3982
  }), hasPageInfoChecked = !0), {
@@ -3878,7 +3990,7 @@ var RULE_ID13 = "relay-page-info", MESSAGE_MUST_EXIST = "MESSAGE_MUST_EXIST", ME
3878
3990
  let field = fieldMap[fieldName], isAllowedType = !1;
3879
3991
  if (field) {
3880
3992
  let type = field.gqlType;
3881
- typeName === "Boolean" ? isAllowedType = type.kind === Kind17.NON_NULL_TYPE && type.gqlType.kind === Kind17.NAMED_TYPE && type.gqlType.name.value === "Boolean" : type.kind === Kind17.NAMED_TYPE && (isAllowedType = type.name.value === "String" || isScalarType4(schema15.getType(type.name.value)));
3993
+ typeName === "Boolean" ? isAllowedType = type.kind === Kind17.NON_NULL_TYPE && type.gqlType.kind === Kind17.NAMED_TYPE && type.gqlType.name.value === "Boolean" : type.kind === Kind17.NAMED_TYPE && (isAllowedType = type.name.value === "String" || isScalarType4(schema16.getType(type.name.value)));
3882
3994
  }
3883
3995
  if (!isAllowedType) {
3884
3996
  let returnType = typeName === "Boolean" ? "non-null Boolean" : "either String or Scalar, which can be null if there are no results";
@@ -3895,7 +4007,7 @@ var RULE_ID13 = "relay-page-info", MESSAGE_MUST_EXIST = "MESSAGE_MUST_EXIST", ME
3895
4007
  };
3896
4008
 
3897
4009
  // src/rules/require-deprecation-date/index.ts
3898
- var DATE_REGEX = /^\d{2}\/\d{2}\/\d{4}$/, MESSAGE_REQUIRE_DATE = "MESSAGE_REQUIRE_DATE", MESSAGE_INVALID_FORMAT = "MESSAGE_INVALID_FORMAT", MESSAGE_INVALID_DATE = "MESSAGE_INVALID_DATE", MESSAGE_CAN_BE_REMOVED = "MESSAGE_CAN_BE_REMOVED", schema10 = {
4010
+ var DATE_REGEX = /^\d{2}\/\d{2}\/\d{4}$/, MESSAGE_REQUIRE_DATE = "MESSAGE_REQUIRE_DATE", MESSAGE_INVALID_FORMAT = "MESSAGE_INVALID_FORMAT", MESSAGE_INVALID_DATE = "MESSAGE_INVALID_DATE", MESSAGE_CAN_BE_REMOVED = "MESSAGE_CAN_BE_REMOVED", schema11 = {
3899
4011
  type: "array",
3900
4012
  maxItems: 1,
3901
4013
  items: {
@@ -3961,7 +4073,7 @@ var DATE_REGEX = /^\d{2}\/\d{2}\/\d{4}$/, MESSAGE_REQUIRE_DATE = "MESSAGE_REQUIR
3961
4073
  [MESSAGE_INVALID_DATE]: 'Invalid "{{ deletionDate }}" deletion date for {{ nodeName }}',
3962
4074
  [MESSAGE_CAN_BE_REMOVED]: "{{ nodeName }} \u0441an be removed"
3963
4075
  },
3964
- schema: schema10
4076
+ schema: schema11
3965
4077
  },
3966
4078
  create(context) {
3967
4079
  return {
@@ -4091,7 +4203,7 @@ var RULE_ID14 = "require-description", ALLOWED_KINDS2 = [
4091
4203
  Kind18.INPUT_VALUE_DEFINITION,
4092
4204
  Kind18.ENUM_VALUE_DEFINITION,
4093
4205
  Kind18.OPERATION_DEFINITION
4094
- ], schema11 = {
4206
+ ], schema12 = {
4095
4207
  type: "array",
4096
4208
  minItems: 1,
4097
4209
  maxItems: 1,
@@ -4199,14 +4311,14 @@ ${TYPES_KINDS.map((kind) => `- \`${kind}\``).join(`
4199
4311
  messages: {
4200
4312
  [RULE_ID14]: "Description is required for {{ nodeName }}"
4201
4313
  },
4202
- schema: schema11
4314
+ schema: schema12
4203
4315
  },
4204
4316
  create(context) {
4205
4317
  let { types, rootField, ...restOptions } = context.options[0] || {}, kinds = new Set(types ? TYPES_KINDS : []);
4206
4318
  for (let [kind, isEnabled] of Object.entries(restOptions))
4207
4319
  isEnabled ? kinds.add(kind) : kinds.delete(kind);
4208
4320
  if (rootField) {
4209
- let schema15 = requireGraphQLSchemaFromContext(RULE_ID14, context), rootTypeNames = getRootTypeNames(schema15);
4321
+ let schema16 = requireGraphQLSchemaFromContext(RULE_ID14, context), rootTypeNames = getRootTypeNames(schema16);
4210
4322
  kinds.add(
4211
4323
  `:matches(ObjectTypeDefinition, ObjectTypeExtension)[name.value=/^(${[
4212
4324
  ...rootTypeNames
@@ -4285,10 +4397,10 @@ var RULE_ID15 = "require-field-of-type-query-in-mutation-result", rule24 = {
4285
4397
  schema: []
4286
4398
  },
4287
4399
  create(context) {
4288
- let schema15 = requireGraphQLSchemaFromContext(RULE_ID15, context), mutationType = schema15.getMutationType(), queryType = schema15.getQueryType();
4400
+ let schema16 = requireGraphQLSchemaFromContext(RULE_ID15, context), mutationType = schema16.getMutationType(), queryType = schema16.getQueryType();
4289
4401
  return !mutationType || !queryType ? {} : {
4290
4402
  [`:matches(ObjectTypeDefinition, ObjectTypeExtension)[name.value=${mutationType.name}] > FieldDefinition > .gqlType Name`](node) {
4291
- let typeName = node.value, graphQLType = schema15.getType(typeName);
4403
+ let typeName = node.value, graphQLType = schema16.getType(typeName);
4292
4404
  if (isObjectType3(graphQLType)) {
4293
4405
  let { fields } = graphQLType.astNode;
4294
4406
  fields?.some((field) => getTypeName(field) === queryType.name) || context.report({
@@ -4523,8 +4635,8 @@ var RULE_ID18 = "require-nullable-result-in-root", rule27 = {
4523
4635
  schema: []
4524
4636
  },
4525
4637
  create(context) {
4526
- let schema15 = requireGraphQLSchemaFromContext(RULE_ID18, context), rootTypeNames = new Set(
4527
- [schema15.getQueryType(), schema15.getMutationType()].filter(truthy).map((type) => type.name)
4638
+ let schema16 = requireGraphQLSchemaFromContext(RULE_ID18, context), rootTypeNames = new Set(
4639
+ [schema16.getQueryType(), schema16.getMutationType()].filter(truthy).map((type) => type.name)
4528
4640
  ), sourceCode = context.getSourceCode();
4529
4641
  return {
4530
4642
  "ObjectTypeDefinition,ObjectTypeExtension"(node) {
@@ -4532,7 +4644,7 @@ var RULE_ID18 = "require-nullable-result-in-root", rule27 = {
4532
4644
  for (let field of node.fields || []) {
4533
4645
  if (field.gqlType.type !== Kind20.NON_NULL_TYPE || field.gqlType.gqlType.type !== Kind20.NAMED_TYPE)
4534
4646
  continue;
4535
- let name = field.gqlType.gqlType.name.value, type = schema15.getType(name), resultType = type?.astNode ? getNodeName(type.astNode) : type?.name;
4647
+ let name = field.gqlType.gqlType.name.value, type = schema16.getType(name), resultType = type?.astNode ? getNodeName(type.astNode) : type?.name;
4536
4648
  context.report({
4537
4649
  node: field.gqlType,
4538
4650
  messageId: RULE_ID18,
@@ -4567,7 +4679,7 @@ import {
4567
4679
  visitWithTypeInfo as visitWithTypeInfo3
4568
4680
  } from "graphql";
4569
4681
  import { asArray } from "@graphql-tools/utils";
4570
- var RULE_ID19 = "require-selections", DEFAULT_ID_FIELD_NAME = "id", schema12 = {
4682
+ var RULE_ID19 = "require-selections", DEFAULT_ID_FIELD_NAME = "id", schema13 = {
4571
4683
  definitions: {
4572
4684
  asString: {
4573
4685
  type: "string"
@@ -4652,10 +4764,10 @@ var RULE_ID19 = "require-selections", DEFAULT_ID_FIELD_NAME = "id", schema12 = {
4652
4764
  [RULE_ID19]: `Field{{ pluralSuffix }} {{ fieldName }} must be selected when it's available on a type.
4653
4765
  Include it in your selection set{{ addition }}.`
4654
4766
  },
4655
- schema: schema12
4767
+ schema: schema13
4656
4768
  },
4657
4769
  create(context) {
4658
- let schema15 = requireGraphQLSchemaFromContext(RULE_ID19, context), siblings = requireSiblingsOperations(RULE_ID19, context), { fieldName = DEFAULT_ID_FIELD_NAME } = context.options[0] || {}, idNames = asArray(fieldName), selector = "OperationDefinition SelectionSet[parent.kind!=/(^OperationDefinition|InlineFragment)$/]", typeInfo = new TypeInfo3(schema15);
4770
+ let schema16 = requireGraphQLSchemaFromContext(RULE_ID19, context), siblings = requireSiblingsOperations(RULE_ID19, context), { fieldName = DEFAULT_ID_FIELD_NAME } = context.options[0] || {}, idNames = asArray(fieldName), selector = "SelectionSet[parent.kind!=/(^OperationDefinition|InlineFragment)$/]", typeInfo = new TypeInfo3(schema16);
4659
4771
  function checkFragments(node) {
4660
4772
  for (let selection of node.selections) {
4661
4773
  if (selection.kind !== Kind21.FRAGMENT_SPREAD)
@@ -4810,7 +4922,7 @@ var RULE_ID20 = "require-type-pattern-with-oneof", rule29 = {
4810
4922
  // src/rules/selection-set-depth/index.ts
4811
4923
  import { Kind as Kind22 } from "graphql";
4812
4924
  import depthLimit from "graphql-depth-limit";
4813
- var RULE_ID21 = "selection-set-depth", schema13 = {
4925
+ var RULE_ID21 = "selection-set-depth", schema14 = {
4814
4926
  type: "array",
4815
4927
  minItems: 1,
4816
4928
  maxItems: 1,
@@ -4878,7 +4990,7 @@ var RULE_ID21 = "selection-set-depth", schema13 = {
4878
4990
  recommended: !0,
4879
4991
  configOptions: [{ maxDepth: 7 }]
4880
4992
  },
4881
- schema: schema13
4993
+ schema: schema14
4882
4994
  },
4883
4995
  create(context) {
4884
4996
  let siblings = null;
@@ -4939,7 +5051,7 @@ var RULE_ID21 = "selection-set-depth", schema13 = {
4939
5051
 
4940
5052
  // src/rules/strict-id-in-types/index.ts
4941
5053
  import { Kind as Kind23 } from "graphql";
4942
- var RULE_ID22 = "strict-id-in-types", schema14 = {
5054
+ var RULE_ID22 = "strict-id-in-types", schema15 = {
4943
5055
  type: "array",
4944
5056
  maxItems: 1,
4945
5057
  items: {
@@ -5047,7 +5159,7 @@ var RULE_ID22 = "strict-id-in-types", schema14 = {
5047
5159
  }
5048
5160
  ]
5049
5161
  },
5050
- schema: schema14
5162
+ schema: schema15
5051
5163
  },
5052
5164
  create(context) {
5053
5165
  let options = {
@@ -5055,12 +5167,12 @@ var RULE_ID22 = "strict-id-in-types", schema14 = {
5055
5167
  acceptedIdTypes: ["ID"],
5056
5168
  exceptions: {},
5057
5169
  ...context.options[0]
5058
- }, schema15 = requireGraphQLSchemaFromContext(RULE_ID22, context);
5170
+ }, schema16 = requireGraphQLSchemaFromContext(RULE_ID22, context);
5059
5171
  return {
5060
5172
  [`ObjectTypeDefinition[name.value!=/^(${[
5061
- schema15.getQueryType(),
5062
- schema15.getMutationType(),
5063
- schema15.getSubscriptionType()
5173
+ schema16.getQueryType(),
5174
+ schema16.getMutationType(),
5175
+ schema16.getSubscriptionType()
5064
5176
  ].filter(truthy).map((type) => type.name).join("|")})$/]`](node) {
5065
5177
  let typeName = node.name.value;
5066
5178
  if (options.exceptions.types?.includes(typeName) || options.exceptions.suffixes?.some((suffix) => typeName.endsWith(suffix)))
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@graphql-eslint/eslint-plugin",
3
- "version": "4.0.0-alpha.10",
3
+ "version": "4.0.0-alpha.12",
4
4
  "type": "module",
5
5
  "description": "GraphQL plugin for ESLint",
6
6
  "repository": "https://github.com/B2o5T/graphql-eslint",