@graphql-eslint/eslint-plugin 3.11.0-alpha-20220828135635-ce6bf36 → 3.11.0-alpha-20220923192439-db921ff

Sign up to get free protection for your applications and to get access to all the features.
package/README.md CHANGED
@@ -9,7 +9,7 @@ This project integrates GraphQL and ESLint, for a better developer experience.
9
9
  ## Key Features
10
10
 
11
11
  - 🚀 Integrates with ESLint core (as a ESTree parser)
12
- - 🚀 Works on `.graphql` files, `gql` usages and `/* GraphQL */` magic comments
12
+ - 🚀 Works on `.graphql` files, `gql` usages and `/* GraphQL */` magic comments
13
13
  - 🚀 Lints both GraphQL schema and GraphQL operations
14
14
  - 🚀 Extended type info for more advanced usages
15
15
  - 🚀 Supports ESLint directives (for example: `eslint-disable-next-line`)
@@ -188,7 +188,7 @@ See [docs/deprecated-rules.md](docs/deprecated-rules.md).
188
188
  |[`relay`](packages/plugin/src/configs/relay.json)|enables rules from Relay specification for schema (SDL) development|
189
189
  <!-- prettier-ignore-end -->
190
190
 
191
- > If you are in a project that develops the GraphQL schema, you'll need `schema` rules.
191
+ > If you are in a project that develops the GraphQL schema, you'll need `schema` rules.
192
192
 
193
193
  > If you are in a project that develops GraphQL operations (query/mutation/subscription), you'll need `operations` rules.
194
194
 
@@ -4,18 +4,9 @@
4
4
  "@graphql-eslint/alphabetize": [
5
5
  "error",
6
6
  {
7
- "fields": [
8
- "ObjectTypeDefinition",
9
- "InterfaceTypeDefinition",
10
- "InputObjectTypeDefinition"
11
- ],
7
+ "fields": ["ObjectTypeDefinition", "InterfaceTypeDefinition", "InputObjectTypeDefinition"],
12
8
  "values": ["EnumTypeDefinition"],
13
- "arguments": [
14
- "FieldDefinition",
15
- "Field",
16
- "DirectiveDefinition",
17
- "Directive"
18
- ]
9
+ "arguments": ["FieldDefinition", "Field", "DirectiveDefinition", "Directive"]
19
10
  }
20
11
  ],
21
12
  "@graphql-eslint/input-name": "error",
package/docs/README.md CHANGED
@@ -71,5 +71,6 @@ Name&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbs
71
71
  [variables-are-input-types](rules/variables-are-input-types.md)|A GraphQL operation is only valid if all the variables it defines are of input types (scalar, enum, or input object).|![recommended][]|🔮|
72
72
  [variables-in-allowed-position](rules/variables-in-allowed-position.md)|Variables passed to field arguments conform to type.|![recommended][]|🔮|
73
73
  <!-- prettier-ignore-end -->
74
+
74
75
  [recommended]: https://img.shields.io/badge/-recommended-green.svg
75
76
  [all]: https://img.shields.io/badge/-all-blue.svg
@@ -141,7 +141,7 @@ ruleTester.runGraphQLTests('my-rule', rule, {
141
141
  invalid: [
142
142
  {
143
143
  code: 'query invalid { foo }',
144
- errors: [{ message: 'Your error message.' }],
144
+ errors: [{ message: 'Your error message.' }]
145
145
  }
146
146
  ]
147
147
  })
@@ -39,7 +39,8 @@ type User {
39
39
  # eslint @graphql-eslint/require-deprecation-date: 'error'
40
40
 
41
41
  type User {
42
- firstname: String @deprecated(reason: "Use 'firstName' instead", deletionDate: "25/12/2022")
42
+ firstname: String
43
+ @deprecated(reason: "Use 'firstName' instead", deletionDate: "25/12/2022")
43
44
  firstName: String
44
45
  }
45
46
  ```
package/index.js CHANGED
@@ -114,7 +114,7 @@ const getOnDiskFilepath = (filepath) => {
114
114
  }
115
115
  return filepath;
116
116
  };
117
- const getTypeName = (node) => ('type' in node ? getTypeName(node.type) : node.name.value);
117
+ const getTypeName = (node) => 'type' in node ? getTypeName(node.type) : node.name.value;
118
118
  const TYPES_KINDS = [
119
119
  graphql.Kind.OBJECT_TYPE_DEFINITION,
120
120
  graphql.Kind.INTERFACE_TYPE_DEFINITION,
@@ -189,7 +189,9 @@ function validateDocument(context, schema = null, documentNode, rule) {
189
189
  if (token) {
190
190
  loc =
191
191
  // if cursor on `@` symbol than use next node
192
- token.type === '@' ? sourceCode.getNodeByRangeIndex(token.range[1] + 1).loc : token.loc;
192
+ token.type === '@'
193
+ ? sourceCode.getNodeByRangeIndex(token.range[1] + 1).loc
194
+ : token.loc;
193
195
  }
194
196
  context.report({
195
197
  loc,
@@ -279,7 +281,9 @@ const validationToRule = (ruleId, ruleName, docs, getDocumentNode, schema = [])
279
281
  }
280
282
  return {
281
283
  Document(node) {
282
- const schema = docs.requiresSchema ? requireGraphQLSchemaFromContext(ruleId, context) : null;
284
+ const schema = docs.requiresSchema
285
+ ? requireGraphQLSchemaFromContext(ruleId, context)
286
+ : null;
283
287
  const documentNode = getDocumentNode
284
288
  ? getDocumentNode({ ruleId, context, node: node.rawNode() })
285
289
  : node.rawNode();
@@ -425,7 +429,10 @@ const GRAPHQL_JS_VALIDATIONS = Object.assign({}, validationToRule('executable-de
425
429
  requiresSiblings: true,
426
430
  }, ({ ruleId, context, node }) => {
427
431
  const siblings = requireSiblingsOperations(ruleId, context);
428
- const FilePathToDocumentsMap = [...siblings.getOperations(), ...siblings.getFragments()].reduce((map, { filePath, document }) => {
432
+ const FilePathToDocumentsMap = [
433
+ ...siblings.getOperations(),
434
+ ...siblings.getFragments(),
435
+ ].reduce((map, { filePath, document }) => {
429
436
  var _a;
430
437
  (_a = map[filePath]) !== null && _a !== void 0 ? _a : (map[filePath] = []);
431
438
  map[filePath].push(document);
@@ -705,14 +712,6 @@ const rule = {
705
712
  description: 'Definitions – `type`, `interface`, `enum`, `scalar`, `input`, `union` and `directive`.',
706
713
  default: false,
707
714
  },
708
- ignorePrefix: {
709
- type: 'array',
710
- default: [],
711
- },
712
- ignoreSuffix: {
713
- type: 'array',
714
- default: [],
715
- },
716
715
  },
717
716
  },
718
717
  },
@@ -751,7 +750,9 @@ const rule = {
751
750
  const [firstBeforeComment] = getBeforeComments(node);
752
751
  const [firstAfterComment] = sourceCode.getCommentsAfter(node);
753
752
  const from = firstBeforeComment || node;
754
- const to = firstAfterComment && isNodeAndCommentOnSameLine(node, firstAfterComment) ? firstAfterComment : node;
753
+ const to = firstAfterComment && isNodeAndCommentOnSameLine(node, firstAfterComment)
754
+ ? firstAfterComment
755
+ : node;
755
756
  return [from.range[0], to.range[1]];
756
757
  }
757
758
  function checkNodes(nodes) {
@@ -759,32 +760,24 @@ const rule = {
759
760
  // Starts from 1, ignore nodes.length <= 1
760
761
  for (let i = 1; i < nodes.length; i += 1) {
761
762
  const currNode = nodes[i];
762
- const currName = ('alias' in currNode && ((_a = currNode.alias) === null || _a === void 0 ? void 0 : _a.value)) || ('name' in currNode && ((_b = currNode.name) === null || _b === void 0 ? void 0 : _b.value));
763
+ const currName = ('alias' in currNode && ((_a = currNode.alias) === null || _a === void 0 ? void 0 : _a.value)) ||
764
+ ('name' in currNode && ((_b = currNode.name) === null || _b === void 0 ? void 0 : _b.value));
763
765
  if (!currName) {
764
766
  // we don't move unnamed current nodes
765
767
  continue;
766
768
  }
767
769
  const prevNode = nodes[i - 1];
768
- const prevName = ('alias' in prevNode && ((_c = prevNode.alias) === null || _c === void 0 ? void 0 : _c.value)) || ('name' in prevNode && ((_d = prevNode.name) === null || _d === void 0 ? void 0 : _d.value));
770
+ const prevName = ('alias' in prevNode && ((_c = prevNode.alias) === null || _c === void 0 ? void 0 : _c.value)) ||
771
+ ('name' in prevNode && ((_d = prevNode.name) === null || _d === void 0 ? void 0 : _d.value));
769
772
  if (prevName) {
770
- if ((opts.ignorePrefix || []).length > 0) {
771
- const shouldSkipIgnorePrefix = opts.ignorePrefix.some(prefix => prefix === prevName || prefix === currName || prevName.startsWith(prefix) || currName.startsWith(prefix));
772
- if (shouldSkipIgnorePrefix) {
773
- continue;
774
- }
775
- }
776
- if ((opts.ignoreSuffix || []).length > 0) {
777
- const shouldSkipIgnoreSuffix = opts.ignoreSuffix.some(suffix => suffix === prevName || suffix === currName || prevName.endsWith(suffix) || currName.endsWith(suffix));
778
- if (shouldSkipIgnoreSuffix) {
779
- continue;
780
- }
781
- }
782
773
  // Compare with lexicographic order
783
774
  const compareResult = prevName.localeCompare(currName);
784
775
  const shouldSort = compareResult === 1;
785
776
  if (!shouldSort) {
786
777
  const isSameName = compareResult === 0;
787
- if (!isSameName || !prevNode.kind.endsWith('Extension') || currNode.kind.endsWith('Extension')) {
778
+ if (!isSameName ||
779
+ !prevNode.kind.endsWith('Extension') ||
780
+ currNode.kind.endsWith('Extension')) {
788
781
  continue;
789
782
  }
790
783
  }
@@ -809,8 +802,14 @@ const rule = {
809
802
  const fields = new Set((_a = opts.fields) !== null && _a !== void 0 ? _a : []);
810
803
  const listeners = {};
811
804
  const kinds = [
812
- fields.has(graphql.Kind.OBJECT_TYPE_DEFINITION) && [graphql.Kind.OBJECT_TYPE_DEFINITION, graphql.Kind.OBJECT_TYPE_EXTENSION],
813
- fields.has(graphql.Kind.INTERFACE_TYPE_DEFINITION) && [graphql.Kind.INTERFACE_TYPE_DEFINITION, graphql.Kind.INTERFACE_TYPE_EXTENSION],
805
+ fields.has(graphql.Kind.OBJECT_TYPE_DEFINITION) && [
806
+ graphql.Kind.OBJECT_TYPE_DEFINITION,
807
+ graphql.Kind.OBJECT_TYPE_EXTENSION,
808
+ ],
809
+ fields.has(graphql.Kind.INTERFACE_TYPE_DEFINITION) && [
810
+ graphql.Kind.INTERFACE_TYPE_DEFINITION,
811
+ graphql.Kind.INTERFACE_TYPE_EXTENSION,
812
+ ],
814
813
  fields.has(graphql.Kind.INPUT_OBJECT_TYPE_DEFINITION) && [
815
814
  graphql.Kind.INPUT_OBJECT_TYPE_DEFINITION,
816
815
  graphql.Kind.INPUT_OBJECT_TYPE_EXTENSION,
@@ -1008,7 +1007,8 @@ const rule$2 = {
1008
1007
  checkMutations: true,
1009
1008
  ...context.options[0],
1010
1009
  };
1011
- const shouldCheckType = node => (options.checkMutations && isMutationType(node)) || (options.checkQueries && isQueryType(node));
1010
+ const shouldCheckType = node => (options.checkMutations && isMutationType(node)) ||
1011
+ (options.checkQueries && isQueryType(node));
1012
1012
  const listeners = {
1013
1013
  'FieldDefinition > InputValueDefinition[name.value!=input] > Name'(node) {
1014
1014
  if (shouldCheckType(node.parent.parent.parent)) {
@@ -1244,7 +1244,8 @@ const rule$3 = {
1244
1244
  const expectedExtension = options.fileExtension || fileExtension;
1245
1245
  let expectedFilename;
1246
1246
  if (option.style) {
1247
- expectedFilename = option.style === 'matchDocumentStyle' ? docName : convertCase(option.style, docName);
1247
+ expectedFilename =
1248
+ option.style === 'matchDocumentStyle' ? docName : convertCase(option.style, docName);
1248
1249
  }
1249
1250
  else {
1250
1251
  expectedFilename = filename;
@@ -1558,12 +1559,10 @@ const rule$4 = {
1558
1559
  };
1559
1560
  const listeners = {};
1560
1561
  if (!allowLeadingUnderscore) {
1561
- listeners['Name[value=/^_/]:matches([parent.kind!=Field], [parent.kind=Field][parent.alias])'] =
1562
- checkUnderscore(true);
1562
+ listeners['Name[value=/^_/]:matches([parent.kind!=Field], [parent.kind=Field][parent.alias])'] = checkUnderscore(true);
1563
1563
  }
1564
1564
  if (!allowTrailingUnderscore) {
1565
- listeners['Name[value=/_$/]:matches([parent.kind!=Field], [parent.kind=Field][parent.alias])'] =
1566
- checkUnderscore(false);
1565
+ listeners['Name[value=/_$/]:matches([parent.kind!=Field], [parent.kind=Field][parent.alias])'] = checkUnderscore(false);
1567
1566
  }
1568
1567
  const selectors = new Set([types && TYPES_KINDS, Object.keys(restOptions)].flat().filter(Boolean));
1569
1568
  for (const selector of selectors) {
@@ -1611,7 +1610,9 @@ const rule$5 = {
1611
1610
  return {
1612
1611
  'OperationDefinition[name=undefined]'(node) {
1613
1612
  const [firstSelection] = node.selectionSet.selections;
1614
- const suggestedName = firstSelection.kind === graphql.Kind.FIELD ? (firstSelection.alias || firstSelection.name).value : node.operation;
1613
+ const suggestedName = firstSelection.kind === graphql.Kind.FIELD
1614
+ ? (firstSelection.alias || firstSelection.name).value
1615
+ : node.operation;
1615
1616
  context.report({
1616
1617
  loc: getLocation(node.loc.start, node.operation),
1617
1618
  messageId: RULE_ID$1,
@@ -1672,7 +1673,8 @@ const rule$6 = {
1672
1673
  const selector = [graphql.Kind.ENUM_TYPE_DEFINITION, graphql.Kind.ENUM_TYPE_EXTENSION].join(',');
1673
1674
  return {
1674
1675
  [selector](node) {
1675
- const duplicates = node.values.filter((item, index, array) => array.findIndex(v => v.name.value.toLowerCase() === item.name.value.toLowerCase()) !== index);
1676
+ const duplicates = node.values.filter((item, index, array) => array.findIndex(v => v.name.value.toLowerCase() === item.name.value.toLowerCase()) !==
1677
+ index);
1676
1678
  for (const duplicate of duplicates) {
1677
1679
  const enumName = duplicate.name.value;
1678
1680
  context.report({
@@ -1982,7 +1984,10 @@ const rule$9 = {
1982
1984
  if (kind === graphql.TokenKind.COMMENT && prev && next) {
1983
1985
  const isEslintComment = value.trimStart().startsWith('eslint');
1984
1986
  const linesAfter = next.line - line;
1985
- if (!isEslintComment && line !== prev.line && next.kind === graphql.TokenKind.NAME && linesAfter < 2) {
1987
+ if (!isEslintComment &&
1988
+ line !== prev.line &&
1989
+ next.kind === graphql.TokenKind.NAME &&
1990
+ linesAfter < 2) {
1986
1991
  context.report({
1987
1992
  messageId: HASHTAG_COMMENT,
1988
1993
  loc: {
@@ -2691,7 +2696,8 @@ const rule$g = {
2691
2696
  }
2692
2697
  },
2693
2698
  ':matches(ObjectTypeDefinition, ObjectTypeExtension)[name.value=/Connection$/] > FieldDefinition[name.value=edges] > .gqlType'(node) {
2694
- const isListType = node.kind === graphql.Kind.LIST_TYPE || (node.kind === graphql.Kind.NON_NULL_TYPE && node.gqlType.kind === graphql.Kind.LIST_TYPE);
2699
+ const isListType = node.kind === graphql.Kind.LIST_TYPE ||
2700
+ (node.kind === graphql.Kind.NON_NULL_TYPE && node.gqlType.kind === graphql.Kind.LIST_TYPE);
2695
2701
  if (!isListType) {
2696
2702
  context.report({ node, messageId: EDGES_FIELD_MUST_RETURN_LIST_TYPE });
2697
2703
  }
@@ -2816,7 +2822,8 @@ const rule$h = {
2816
2822
  listTypeCanWrapOnlyEdgeType: true,
2817
2823
  ...context.options[0],
2818
2824
  };
2819
- const isNamedOrNonNullNamed = (node) => node.kind === graphql.Kind.NAMED_TYPE || (node.kind === graphql.Kind.NON_NULL_TYPE && node.gqlType.kind === graphql.Kind.NAMED_TYPE);
2825
+ const isNamedOrNonNullNamed = (node) => node.kind === graphql.Kind.NAMED_TYPE ||
2826
+ (node.kind === graphql.Kind.NON_NULL_TYPE && node.gqlType.kind === graphql.Kind.NAMED_TYPE);
2820
2827
  const checkNodeField = (node) => {
2821
2828
  const nodeField = node.fields.find(field => field.name.value === 'node');
2822
2829
  const message = 'return either a Scalar, Enum, Object, Interface, Union, or a non-null wrapper around one of those types.';
@@ -2960,7 +2967,8 @@ const rule$i = {
2960
2967
  type.gqlType.name.value === 'Boolean';
2961
2968
  }
2962
2969
  else if (type.kind === graphql.Kind.NAMED_TYPE) {
2963
- isAllowedType = type.name.value === 'String' || graphql.isScalarType(schema.getType(type.name.value));
2970
+ isAllowedType =
2971
+ type.name.value === 'String' || graphql.isScalarType(schema.getType(type.name.value));
2964
2972
  }
2965
2973
  }
2966
2974
  if (!isAllowedType) {
@@ -3177,7 +3185,8 @@ const rule$j = {
3177
3185
  title: 'Correct',
3178
3186
  code: /* GraphQL */ `
3179
3187
  type User {
3180
- firstname: String @deprecated(reason: "Use 'firstName' instead", deletionDate: "25/12/2022")
3188
+ firstname: String
3189
+ @deprecated(reason: "Use 'firstName' instead", deletionDate: "25/12/2022")
3181
3190
  firstName: String
3182
3191
  }
3183
3192
  `,
@@ -3416,7 +3425,8 @@ const rule$l = {
3416
3425
  ...Object.fromEntries([...ALLOWED_KINDS$1].sort().map(kind => {
3417
3426
  let description = `Read more about this kind on [spec.graphql.org](https://spec.graphql.org/October2021/#${kind}).`;
3418
3427
  if (kind === graphql.Kind.OPERATION_DEFINITION) {
3419
- description += '\n\n> You must use only comment syntax `#` and not description syntax `"""` or `"`.';
3428
+ description +=
3429
+ '\n\n> You must use only comment syntax `#` and not description syntax `"""` or `"`.';
3420
3430
  }
3421
3431
  return [kind, { type: 'boolean', description }];
3422
3432
  })),
@@ -3734,7 +3744,6 @@ const RULE_ID$d = 'selection-set-depth';
3734
3744
  const rule$o = {
3735
3745
  meta: {
3736
3746
  type: 'suggestion',
3737
- // eslint-disable-next-line eslint-plugin/require-meta-has-suggestions -- optional since we can't provide fixes for fragments located in separate files
3738
3747
  hasSuggestions: true,
3739
3748
  docs: {
3740
3749
  category: 'Operations',
@@ -3971,7 +3980,11 @@ const rule$p = {
3971
3980
  ...context.options[0],
3972
3981
  };
3973
3982
  const schema = requireGraphQLSchemaFromContext(RULE_ID$e, context);
3974
- const rootTypeNames = [schema.getQueryType(), schema.getMutationType(), schema.getSubscriptionType()]
3983
+ const rootTypeNames = [
3984
+ schema.getQueryType(),
3985
+ schema.getMutationType(),
3986
+ schema.getSubscriptionType(),
3987
+ ]
3975
3988
  .filter(Boolean)
3976
3989
  .map(type => type.name);
3977
3990
  const selector = `ObjectTypeDefinition[name.value!=/^(${rootTypeNames.join('|')})$/]`;
@@ -3989,7 +4002,8 @@ const rule$p = {
3989
4002
  const isValidIdName = options.acceptedIdNames.includes(fieldNode.name.value);
3990
4003
  // To be a valid type, it must be non-null and one of the accepted types.
3991
4004
  let isValidIdType = false;
3992
- if (fieldNode.type.kind === graphql.Kind.NON_NULL_TYPE && fieldNode.type.type.kind === graphql.Kind.NAMED_TYPE) {
4005
+ if (fieldNode.type.kind === graphql.Kind.NON_NULL_TYPE &&
4006
+ fieldNode.type.type.kind === graphql.Kind.NAMED_TYPE) {
3993
4007
  isValidIdType = options.acceptedIdTypes.includes(fieldNode.type.type.name.value);
3994
4008
  }
3995
4009
  return isValidIdName && isValidIdType;
@@ -4014,7 +4028,9 @@ const RULE_ID$f = 'unique-fragment-name';
4014
4028
  const checkNode = (context, node, ruleId) => {
4015
4029
  const documentName = node.name.value;
4016
4030
  const siblings = requireSiblingsOperations(ruleId, context);
4017
- const siblingDocuments = node.kind === graphql.Kind.FRAGMENT_DEFINITION ? siblings.getFragment(documentName) : siblings.getOperation(documentName);
4031
+ const siblingDocuments = node.kind === graphql.Kind.FRAGMENT_DEFINITION
4032
+ ? siblings.getFragment(documentName)
4033
+ : siblings.getOperation(documentName);
4018
4034
  const filepath = context.getFilename();
4019
4035
  const conflictingDocuments = siblingDocuments.filter(f => {
4020
4036
  var _a;
@@ -4410,7 +4426,9 @@ function parseForESLint(code, options = {}) {
4410
4426
  const filePath = options.filePath || '';
4411
4427
  const realFilepath = filePath && getOnDiskFilepath(filePath);
4412
4428
  const gqlConfig = loadGraphQLConfig(options);
4413
- const projectForFile = realFilepath ? gqlConfig.getProjectForFile(realFilepath) : gqlConfig.getDefault();
4429
+ const projectForFile = realFilepath
4430
+ ? gqlConfig.getProjectForFile(realFilepath)
4431
+ : gqlConfig.getDefault();
4414
4432
  const schema = getSchema(projectForFile, options);
4415
4433
  const siblingOperations = getSiblingOperations(projectForFile);
4416
4434
  const { document } = utils.parseGraphQLSDL(filePath, code, {
package/index.mjs CHANGED
@@ -108,7 +108,7 @@ const getOnDiskFilepath = (filepath) => {
108
108
  }
109
109
  return filepath;
110
110
  };
111
- const getTypeName = (node) => ('type' in node ? getTypeName(node.type) : node.name.value);
111
+ const getTypeName = (node) => 'type' in node ? getTypeName(node.type) : node.name.value;
112
112
  const TYPES_KINDS = [
113
113
  Kind.OBJECT_TYPE_DEFINITION,
114
114
  Kind.INTERFACE_TYPE_DEFINITION,
@@ -183,7 +183,9 @@ function validateDocument(context, schema = null, documentNode, rule) {
183
183
  if (token) {
184
184
  loc =
185
185
  // if cursor on `@` symbol than use next node
186
- token.type === '@' ? sourceCode.getNodeByRangeIndex(token.range[1] + 1).loc : token.loc;
186
+ token.type === '@'
187
+ ? sourceCode.getNodeByRangeIndex(token.range[1] + 1).loc
188
+ : token.loc;
187
189
  }
188
190
  context.report({
189
191
  loc,
@@ -273,7 +275,9 @@ const validationToRule = (ruleId, ruleName, docs, getDocumentNode, schema = [])
273
275
  }
274
276
  return {
275
277
  Document(node) {
276
- const schema = docs.requiresSchema ? requireGraphQLSchemaFromContext(ruleId, context) : null;
278
+ const schema = docs.requiresSchema
279
+ ? requireGraphQLSchemaFromContext(ruleId, context)
280
+ : null;
277
281
  const documentNode = getDocumentNode
278
282
  ? getDocumentNode({ ruleId, context, node: node.rawNode() })
279
283
  : node.rawNode();
@@ -419,7 +423,10 @@ const GRAPHQL_JS_VALIDATIONS = Object.assign({}, validationToRule('executable-de
419
423
  requiresSiblings: true,
420
424
  }, ({ ruleId, context, node }) => {
421
425
  const siblings = requireSiblingsOperations(ruleId, context);
422
- const FilePathToDocumentsMap = [...siblings.getOperations(), ...siblings.getFragments()].reduce((map, { filePath, document }) => {
426
+ const FilePathToDocumentsMap = [
427
+ ...siblings.getOperations(),
428
+ ...siblings.getFragments(),
429
+ ].reduce((map, { filePath, document }) => {
423
430
  var _a;
424
431
  (_a = map[filePath]) !== null && _a !== void 0 ? _a : (map[filePath] = []);
425
432
  map[filePath].push(document);
@@ -699,14 +706,6 @@ const rule = {
699
706
  description: 'Definitions – `type`, `interface`, `enum`, `scalar`, `input`, `union` and `directive`.',
700
707
  default: false,
701
708
  },
702
- ignorePrefix: {
703
- type: 'array',
704
- default: [],
705
- },
706
- ignoreSuffix: {
707
- type: 'array',
708
- default: [],
709
- },
710
709
  },
711
710
  },
712
711
  },
@@ -745,7 +744,9 @@ const rule = {
745
744
  const [firstBeforeComment] = getBeforeComments(node);
746
745
  const [firstAfterComment] = sourceCode.getCommentsAfter(node);
747
746
  const from = firstBeforeComment || node;
748
- const to = firstAfterComment && isNodeAndCommentOnSameLine(node, firstAfterComment) ? firstAfterComment : node;
747
+ const to = firstAfterComment && isNodeAndCommentOnSameLine(node, firstAfterComment)
748
+ ? firstAfterComment
749
+ : node;
749
750
  return [from.range[0], to.range[1]];
750
751
  }
751
752
  function checkNodes(nodes) {
@@ -753,32 +754,24 @@ const rule = {
753
754
  // Starts from 1, ignore nodes.length <= 1
754
755
  for (let i = 1; i < nodes.length; i += 1) {
755
756
  const currNode = nodes[i];
756
- const currName = ('alias' in currNode && ((_a = currNode.alias) === null || _a === void 0 ? void 0 : _a.value)) || ('name' in currNode && ((_b = currNode.name) === null || _b === void 0 ? void 0 : _b.value));
757
+ const currName = ('alias' in currNode && ((_a = currNode.alias) === null || _a === void 0 ? void 0 : _a.value)) ||
758
+ ('name' in currNode && ((_b = currNode.name) === null || _b === void 0 ? void 0 : _b.value));
757
759
  if (!currName) {
758
760
  // we don't move unnamed current nodes
759
761
  continue;
760
762
  }
761
763
  const prevNode = nodes[i - 1];
762
- const prevName = ('alias' in prevNode && ((_c = prevNode.alias) === null || _c === void 0 ? void 0 : _c.value)) || ('name' in prevNode && ((_d = prevNode.name) === null || _d === void 0 ? void 0 : _d.value));
764
+ const prevName = ('alias' in prevNode && ((_c = prevNode.alias) === null || _c === void 0 ? void 0 : _c.value)) ||
765
+ ('name' in prevNode && ((_d = prevNode.name) === null || _d === void 0 ? void 0 : _d.value));
763
766
  if (prevName) {
764
- if ((opts.ignorePrefix || []).length > 0) {
765
- const shouldSkipIgnorePrefix = opts.ignorePrefix.some(prefix => prefix === prevName || prefix === currName || prevName.startsWith(prefix) || currName.startsWith(prefix));
766
- if (shouldSkipIgnorePrefix) {
767
- continue;
768
- }
769
- }
770
- if ((opts.ignoreSuffix || []).length > 0) {
771
- const shouldSkipIgnoreSuffix = opts.ignoreSuffix.some(suffix => suffix === prevName || suffix === currName || prevName.endsWith(suffix) || currName.endsWith(suffix));
772
- if (shouldSkipIgnoreSuffix) {
773
- continue;
774
- }
775
- }
776
767
  // Compare with lexicographic order
777
768
  const compareResult = prevName.localeCompare(currName);
778
769
  const shouldSort = compareResult === 1;
779
770
  if (!shouldSort) {
780
771
  const isSameName = compareResult === 0;
781
- if (!isSameName || !prevNode.kind.endsWith('Extension') || currNode.kind.endsWith('Extension')) {
772
+ if (!isSameName ||
773
+ !prevNode.kind.endsWith('Extension') ||
774
+ currNode.kind.endsWith('Extension')) {
782
775
  continue;
783
776
  }
784
777
  }
@@ -803,8 +796,14 @@ const rule = {
803
796
  const fields = new Set((_a = opts.fields) !== null && _a !== void 0 ? _a : []);
804
797
  const listeners = {};
805
798
  const kinds = [
806
- fields.has(Kind.OBJECT_TYPE_DEFINITION) && [Kind.OBJECT_TYPE_DEFINITION, Kind.OBJECT_TYPE_EXTENSION],
807
- fields.has(Kind.INTERFACE_TYPE_DEFINITION) && [Kind.INTERFACE_TYPE_DEFINITION, Kind.INTERFACE_TYPE_EXTENSION],
799
+ fields.has(Kind.OBJECT_TYPE_DEFINITION) && [
800
+ Kind.OBJECT_TYPE_DEFINITION,
801
+ Kind.OBJECT_TYPE_EXTENSION,
802
+ ],
803
+ fields.has(Kind.INTERFACE_TYPE_DEFINITION) && [
804
+ Kind.INTERFACE_TYPE_DEFINITION,
805
+ Kind.INTERFACE_TYPE_EXTENSION,
806
+ ],
808
807
  fields.has(Kind.INPUT_OBJECT_TYPE_DEFINITION) && [
809
808
  Kind.INPUT_OBJECT_TYPE_DEFINITION,
810
809
  Kind.INPUT_OBJECT_TYPE_EXTENSION,
@@ -1002,7 +1001,8 @@ const rule$2 = {
1002
1001
  checkMutations: true,
1003
1002
  ...context.options[0],
1004
1003
  };
1005
- const shouldCheckType = node => (options.checkMutations && isMutationType(node)) || (options.checkQueries && isQueryType(node));
1004
+ const shouldCheckType = node => (options.checkMutations && isMutationType(node)) ||
1005
+ (options.checkQueries && isQueryType(node));
1006
1006
  const listeners = {
1007
1007
  'FieldDefinition > InputValueDefinition[name.value!=input] > Name'(node) {
1008
1008
  if (shouldCheckType(node.parent.parent.parent)) {
@@ -1238,7 +1238,8 @@ const rule$3 = {
1238
1238
  const expectedExtension = options.fileExtension || fileExtension;
1239
1239
  let expectedFilename;
1240
1240
  if (option.style) {
1241
- expectedFilename = option.style === 'matchDocumentStyle' ? docName : convertCase(option.style, docName);
1241
+ expectedFilename =
1242
+ option.style === 'matchDocumentStyle' ? docName : convertCase(option.style, docName);
1242
1243
  }
1243
1244
  else {
1244
1245
  expectedFilename = filename;
@@ -1552,12 +1553,10 @@ const rule$4 = {
1552
1553
  };
1553
1554
  const listeners = {};
1554
1555
  if (!allowLeadingUnderscore) {
1555
- listeners['Name[value=/^_/]:matches([parent.kind!=Field], [parent.kind=Field][parent.alias])'] =
1556
- checkUnderscore(true);
1556
+ listeners['Name[value=/^_/]:matches([parent.kind!=Field], [parent.kind=Field][parent.alias])'] = checkUnderscore(true);
1557
1557
  }
1558
1558
  if (!allowTrailingUnderscore) {
1559
- listeners['Name[value=/_$/]:matches([parent.kind!=Field], [parent.kind=Field][parent.alias])'] =
1560
- checkUnderscore(false);
1559
+ listeners['Name[value=/_$/]:matches([parent.kind!=Field], [parent.kind=Field][parent.alias])'] = checkUnderscore(false);
1561
1560
  }
1562
1561
  const selectors = new Set([types && TYPES_KINDS, Object.keys(restOptions)].flat().filter(Boolean));
1563
1562
  for (const selector of selectors) {
@@ -1605,7 +1604,9 @@ const rule$5 = {
1605
1604
  return {
1606
1605
  'OperationDefinition[name=undefined]'(node) {
1607
1606
  const [firstSelection] = node.selectionSet.selections;
1608
- const suggestedName = firstSelection.kind === Kind.FIELD ? (firstSelection.alias || firstSelection.name).value : node.operation;
1607
+ const suggestedName = firstSelection.kind === Kind.FIELD
1608
+ ? (firstSelection.alias || firstSelection.name).value
1609
+ : node.operation;
1609
1610
  context.report({
1610
1611
  loc: getLocation(node.loc.start, node.operation),
1611
1612
  messageId: RULE_ID$1,
@@ -1666,7 +1667,8 @@ const rule$6 = {
1666
1667
  const selector = [Kind.ENUM_TYPE_DEFINITION, Kind.ENUM_TYPE_EXTENSION].join(',');
1667
1668
  return {
1668
1669
  [selector](node) {
1669
- const duplicates = node.values.filter((item, index, array) => array.findIndex(v => v.name.value.toLowerCase() === item.name.value.toLowerCase()) !== index);
1670
+ const duplicates = node.values.filter((item, index, array) => array.findIndex(v => v.name.value.toLowerCase() === item.name.value.toLowerCase()) !==
1671
+ index);
1670
1672
  for (const duplicate of duplicates) {
1671
1673
  const enumName = duplicate.name.value;
1672
1674
  context.report({
@@ -1976,7 +1978,10 @@ const rule$9 = {
1976
1978
  if (kind === TokenKind.COMMENT && prev && next) {
1977
1979
  const isEslintComment = value.trimStart().startsWith('eslint');
1978
1980
  const linesAfter = next.line - line;
1979
- if (!isEslintComment && line !== prev.line && next.kind === TokenKind.NAME && linesAfter < 2) {
1981
+ if (!isEslintComment &&
1982
+ line !== prev.line &&
1983
+ next.kind === TokenKind.NAME &&
1984
+ linesAfter < 2) {
1980
1985
  context.report({
1981
1986
  messageId: HASHTAG_COMMENT,
1982
1987
  loc: {
@@ -2685,7 +2690,8 @@ const rule$g = {
2685
2690
  }
2686
2691
  },
2687
2692
  ':matches(ObjectTypeDefinition, ObjectTypeExtension)[name.value=/Connection$/] > FieldDefinition[name.value=edges] > .gqlType'(node) {
2688
- const isListType = node.kind === Kind.LIST_TYPE || (node.kind === Kind.NON_NULL_TYPE && node.gqlType.kind === Kind.LIST_TYPE);
2693
+ const isListType = node.kind === Kind.LIST_TYPE ||
2694
+ (node.kind === Kind.NON_NULL_TYPE && node.gqlType.kind === Kind.LIST_TYPE);
2689
2695
  if (!isListType) {
2690
2696
  context.report({ node, messageId: EDGES_FIELD_MUST_RETURN_LIST_TYPE });
2691
2697
  }
@@ -2810,7 +2816,8 @@ const rule$h = {
2810
2816
  listTypeCanWrapOnlyEdgeType: true,
2811
2817
  ...context.options[0],
2812
2818
  };
2813
- const isNamedOrNonNullNamed = (node) => node.kind === Kind.NAMED_TYPE || (node.kind === Kind.NON_NULL_TYPE && node.gqlType.kind === Kind.NAMED_TYPE);
2819
+ const isNamedOrNonNullNamed = (node) => node.kind === Kind.NAMED_TYPE ||
2820
+ (node.kind === Kind.NON_NULL_TYPE && node.gqlType.kind === Kind.NAMED_TYPE);
2814
2821
  const checkNodeField = (node) => {
2815
2822
  const nodeField = node.fields.find(field => field.name.value === 'node');
2816
2823
  const message = 'return either a Scalar, Enum, Object, Interface, Union, or a non-null wrapper around one of those types.';
@@ -2954,7 +2961,8 @@ const rule$i = {
2954
2961
  type.gqlType.name.value === 'Boolean';
2955
2962
  }
2956
2963
  else if (type.kind === Kind.NAMED_TYPE) {
2957
- isAllowedType = type.name.value === 'String' || isScalarType(schema.getType(type.name.value));
2964
+ isAllowedType =
2965
+ type.name.value === 'String' || isScalarType(schema.getType(type.name.value));
2958
2966
  }
2959
2967
  }
2960
2968
  if (!isAllowedType) {
@@ -3171,7 +3179,8 @@ const rule$j = {
3171
3179
  title: 'Correct',
3172
3180
  code: /* GraphQL */ `
3173
3181
  type User {
3174
- firstname: String @deprecated(reason: "Use 'firstName' instead", deletionDate: "25/12/2022")
3182
+ firstname: String
3183
+ @deprecated(reason: "Use 'firstName' instead", deletionDate: "25/12/2022")
3175
3184
  firstName: String
3176
3185
  }
3177
3186
  `,
@@ -3410,7 +3419,8 @@ const rule$l = {
3410
3419
  ...Object.fromEntries([...ALLOWED_KINDS$1].sort().map(kind => {
3411
3420
  let description = `Read more about this kind on [spec.graphql.org](https://spec.graphql.org/October2021/#${kind}).`;
3412
3421
  if (kind === Kind.OPERATION_DEFINITION) {
3413
- description += '\n\n> You must use only comment syntax `#` and not description syntax `"""` or `"`.';
3422
+ description +=
3423
+ '\n\n> You must use only comment syntax `#` and not description syntax `"""` or `"`.';
3414
3424
  }
3415
3425
  return [kind, { type: 'boolean', description }];
3416
3426
  })),
@@ -3728,7 +3738,6 @@ const RULE_ID$d = 'selection-set-depth';
3728
3738
  const rule$o = {
3729
3739
  meta: {
3730
3740
  type: 'suggestion',
3731
- // eslint-disable-next-line eslint-plugin/require-meta-has-suggestions -- optional since we can't provide fixes for fragments located in separate files
3732
3741
  hasSuggestions: true,
3733
3742
  docs: {
3734
3743
  category: 'Operations',
@@ -3965,7 +3974,11 @@ const rule$p = {
3965
3974
  ...context.options[0],
3966
3975
  };
3967
3976
  const schema = requireGraphQLSchemaFromContext(RULE_ID$e, context);
3968
- const rootTypeNames = [schema.getQueryType(), schema.getMutationType(), schema.getSubscriptionType()]
3977
+ const rootTypeNames = [
3978
+ schema.getQueryType(),
3979
+ schema.getMutationType(),
3980
+ schema.getSubscriptionType(),
3981
+ ]
3969
3982
  .filter(Boolean)
3970
3983
  .map(type => type.name);
3971
3984
  const selector = `ObjectTypeDefinition[name.value!=/^(${rootTypeNames.join('|')})$/]`;
@@ -3983,7 +3996,8 @@ const rule$p = {
3983
3996
  const isValidIdName = options.acceptedIdNames.includes(fieldNode.name.value);
3984
3997
  // To be a valid type, it must be non-null and one of the accepted types.
3985
3998
  let isValidIdType = false;
3986
- if (fieldNode.type.kind === Kind.NON_NULL_TYPE && fieldNode.type.type.kind === Kind.NAMED_TYPE) {
3999
+ if (fieldNode.type.kind === Kind.NON_NULL_TYPE &&
4000
+ fieldNode.type.type.kind === Kind.NAMED_TYPE) {
3987
4001
  isValidIdType = options.acceptedIdTypes.includes(fieldNode.type.type.name.value);
3988
4002
  }
3989
4003
  return isValidIdName && isValidIdType;
@@ -4008,7 +4022,9 @@ const RULE_ID$f = 'unique-fragment-name';
4008
4022
  const checkNode = (context, node, ruleId) => {
4009
4023
  const documentName = node.name.value;
4010
4024
  const siblings = requireSiblingsOperations(ruleId, context);
4011
- const siblingDocuments = node.kind === Kind.FRAGMENT_DEFINITION ? siblings.getFragment(documentName) : siblings.getOperation(documentName);
4025
+ const siblingDocuments = node.kind === Kind.FRAGMENT_DEFINITION
4026
+ ? siblings.getFragment(documentName)
4027
+ : siblings.getOperation(documentName);
4012
4028
  const filepath = context.getFilename();
4013
4029
  const conflictingDocuments = siblingDocuments.filter(f => {
4014
4030
  var _a;
@@ -4404,7 +4420,9 @@ function parseForESLint(code, options = {}) {
4404
4420
  const filePath = options.filePath || '';
4405
4421
  const realFilepath = filePath && getOnDiskFilepath(filePath);
4406
4422
  const gqlConfig = loadGraphQLConfig(options);
4407
- const projectForFile = realFilepath ? gqlConfig.getProjectForFile(realFilepath) : gqlConfig.getDefault();
4423
+ const projectForFile = realFilepath
4424
+ ? gqlConfig.getProjectForFile(realFilepath)
4425
+ : gqlConfig.getDefault();
4408
4426
  const schema = getSchema(projectForFile, options);
4409
4427
  const siblingOperations = getSiblingOperations(projectForFile);
4410
4428
  const { document } = parseGraphQLSDL(filePath, code, {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@graphql-eslint/eslint-plugin",
3
- "version": "3.11.0-alpha-20220828135635-ce6bf36",
3
+ "version": "3.11.0-alpha-20220923192439-db921ff",
4
4
  "description": "GraphQL plugin for ESLint",
5
5
  "sideEffects": false,
6
6
  "peerDependencies": {
@@ -11,8 +11,6 @@ export declare type AlphabetizeConfig = {
11
11
  variables?: typeof variablesEnum;
12
12
  arguments?: typeof argumentsEnum;
13
13
  definitions?: boolean;
14
- ignorePrefix?: string[];
15
- ignoreSuffix?: string[];
16
14
  };
17
15
  declare const rule: GraphQLESLintRule<[AlphabetizeConfig]>;
18
16
  export default rule;
package/types.d.ts CHANGED
@@ -47,26 +47,29 @@ export declare type GraphQLESLintRuleContext<Options = any[]> = Omit<Rule.RuleCo
47
47
  };
48
48
  export declare type CategoryType = 'Schema' | 'Operations';
49
49
  export declare type RuleDocsInfo<T> = {
50
- docs: Omit<Rule.RuleMetaData['docs'], 'category'> & {
51
- category: CategoryType | CategoryType[];
52
- requiresSchema?: true;
53
- requiresSiblings?: true;
54
- examples?: {
55
- title: string;
56
- code: string;
57
- usage?: T;
58
- }[];
59
- configOptions?: T | {
60
- schema?: T;
61
- operations?: T;
62
- };
63
- graphQLJSRuleName?: string;
64
- isDisabledForAllConfig?: true;
50
+ description: string;
51
+ category: CategoryType | CategoryType[];
52
+ recommended?: boolean;
53
+ url: string;
54
+ requiresSchema?: true;
55
+ requiresSiblings?: true;
56
+ examples?: {
57
+ title: string;
58
+ code: string;
59
+ usage?: T;
60
+ }[];
61
+ configOptions?: T | {
62
+ schema?: T;
63
+ operations?: T;
65
64
  };
65
+ graphQLJSRuleName?: string;
66
+ isDisabledForAllConfig?: true;
66
67
  };
67
68
  export declare type GraphQLESLintRule<Options = any[], WithTypeInfo extends boolean = false> = {
68
69
  create(context: GraphQLESLintRuleContext<Options>): GraphQLESLintRuleListener<WithTypeInfo>;
69
- meta: Omit<Rule.RuleMetaData, 'docs'> & RuleDocsInfo<Options>;
70
+ meta: Omit<Rule.RuleMetaData, 'docs'> & {
71
+ docs: RuleDocsInfo<Options>;
72
+ };
70
73
  };
71
74
  export declare type ValueOf<T> = T[keyof T];
72
75
  declare type Id<T> = {} & {