@graphql-eslint/eslint-plugin 2.3.0 → 2.3.2-alpha-13a11c2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (65) hide show
  1. package/README.md +1 -1
  2. package/docs/README.md +1 -1
  3. package/docs/custom-rules.md +3 -3
  4. package/docs/rules/alphabetize.md +6 -1
  5. package/docs/rules/avoid-duplicate-fields.md +6 -1
  6. package/docs/rules/avoid-operation-name-prefix.md +5 -1
  7. package/docs/rules/avoid-scalar-result-type-on-mutation.md +6 -1
  8. package/docs/rules/avoid-typename-prefix.md +6 -1
  9. package/docs/rules/description-style.md +6 -1
  10. package/docs/rules/executable-definitions.md +6 -1
  11. package/docs/rules/fields-on-correct-type.md +6 -1
  12. package/docs/rules/fragments-on-composite-type.md +6 -1
  13. package/docs/rules/input-name.md +6 -1
  14. package/docs/rules/known-argument-names.md +6 -1
  15. package/docs/rules/known-directives.md +6 -1
  16. package/docs/rules/known-fragment-names.md +6 -1
  17. package/docs/rules/known-type-names.md +6 -1
  18. package/docs/rules/lone-anonymous-operation.md +6 -1
  19. package/docs/rules/lone-schema-definition.md +6 -1
  20. package/docs/rules/match-document-filename.md +6 -1
  21. package/docs/rules/naming-convention.md +6 -1
  22. package/docs/rules/no-anonymous-operations.md +6 -1
  23. package/docs/rules/no-case-insensitive-enum-values-duplicates.md +5 -1
  24. package/docs/rules/no-deprecated.md +6 -1
  25. package/docs/rules/no-fragment-cycles.md +6 -1
  26. package/docs/rules/no-hashtag-description.md +6 -1
  27. package/docs/rules/no-operation-name-suffix.md +5 -1
  28. package/docs/rules/no-undefined-variables.md +6 -1
  29. package/docs/rules/no-unreachable-types.md +6 -1
  30. package/docs/rules/no-unused-fields.md +6 -1
  31. package/docs/rules/no-unused-fragments.md +6 -1
  32. package/docs/rules/no-unused-variables.md +6 -1
  33. package/docs/rules/one-field-subscriptions.md +6 -1
  34. package/docs/rules/overlapping-fields-can-be-merged.md +6 -1
  35. package/docs/rules/possible-fragment-spread.md +6 -1
  36. package/docs/rules/possible-type-extension.md +6 -1
  37. package/docs/rules/provided-required-arguments.md +6 -1
  38. package/docs/rules/require-deprecation-date.md +6 -1
  39. package/docs/rules/require-deprecation-reason.md +6 -1
  40. package/docs/rules/require-description.md +6 -1
  41. package/docs/rules/require-field-of-type-query-in-mutation-result.md +6 -1
  42. package/docs/rules/require-id-when-available.md +6 -1
  43. package/docs/rules/scalar-leafs.md +6 -1
  44. package/docs/rules/selection-set-depth.md +6 -1
  45. package/docs/rules/strict-id-in-types.md +6 -1
  46. package/docs/rules/unique-argument-names.md +6 -1
  47. package/docs/rules/unique-directive-names-per-location.md +6 -1
  48. package/docs/rules/unique-directive-names.md +6 -1
  49. package/docs/rules/unique-enum-value-names.md +6 -1
  50. package/docs/rules/unique-field-definition-names.md +6 -1
  51. package/docs/rules/unique-fragment-name.md +6 -1
  52. package/docs/rules/unique-input-field-names.md +6 -1
  53. package/docs/rules/unique-operation-name.md +6 -1
  54. package/docs/rules/unique-operation-types.md +6 -1
  55. package/docs/rules/unique-type-names.md +6 -1
  56. package/docs/rules/unique-variable-names.md +6 -1
  57. package/docs/rules/value-literals-of-correct-type.md +6 -1
  58. package/docs/rules/variables-are-input-types.md +6 -1
  59. package/docs/rules/variables-in-allowed-position.md +6 -1
  60. package/index.js +183 -58
  61. package/index.mjs +183 -58
  62. package/package.json +1 -1
  63. package/testkit.d.ts +5 -3
  64. package/types.d.ts +2 -0
  65. package/utils.d.ts +4 -0
package/index.mjs CHANGED
@@ -9,6 +9,8 @@ import depthLimit from 'graphql-depth-limit';
9
9
  import { parseCode } from '@graphql-tools/graphql-tag-pluck';
10
10
  import { loadConfigSync, GraphQLConfig } from 'graphql-config';
11
11
  import { CodeFileLoader } from '@graphql-tools/code-file-loader';
12
+ import { RuleTester, Linter } from 'eslint';
13
+ import { codeFrameColumns } from '@babel/code-frame';
12
14
 
13
15
  /*
14
16
  * 🚨 IMPORTANT! Do not manually modify this file. Run: `yarn generate-configs`
@@ -236,6 +238,24 @@ const convertCase = (style, str) => {
236
238
  return lowerCase(str).replace(/ /g, '-');
237
239
  }
238
240
  };
241
+ function getLocation(loc, fieldName = '', offset) {
242
+ const { start } = loc;
243
+ /*
244
+ * ESLint has 0-based column number
245
+ * https://eslint.org/docs/developer-guide/working-with-rules#contextreport
246
+ */
247
+ const { offsetStart = 1, offsetEnd = 1 } = offset !== null && offset !== void 0 ? offset : {};
248
+ return {
249
+ start: {
250
+ line: start.line,
251
+ column: start.column - offsetStart,
252
+ },
253
+ end: {
254
+ line: start.line,
255
+ column: start.column - offsetEnd + fieldName.length,
256
+ },
257
+ };
258
+ }
239
259
 
240
260
  function extractRuleName(stack) {
241
261
  const match = (stack || '').match(/validation[/\\\\]rules[/\\\\](.*?)\.js:/) || [];
@@ -286,6 +306,7 @@ const validationToRule = (name, ruleName, docs, getDocumentNode) => {
286
306
  meta: {
287
307
  docs: {
288
308
  ...docs,
309
+ graphQLJSRuleName: ruleName,
289
310
  category: 'Validation',
290
311
  recommended: true,
291
312
  requiresSchema,
@@ -650,10 +671,7 @@ const rule = {
650
671
  line: start.line,
651
672
  column: start.column - (isVariableNode ? 2 : 1),
652
673
  },
653
- end: {
654
- line: end.line,
655
- column: end.column,
656
- },
674
+ end,
657
675
  },
658
676
  messageId: ALPHABETIZE,
659
677
  data: isVariableNode
@@ -784,6 +802,7 @@ const rule$1 = {
784
802
  messages: {
785
803
  [AVOID_DUPLICATE_FIELDS]: `{{ type }} "{{ fieldName }}" defined multiple times.`,
786
804
  },
805
+ schema: [],
787
806
  },
788
807
  create(context) {
789
808
  return {
@@ -903,15 +922,16 @@ const rule$2 = {
903
922
  const testKeyword = caseSensitive ? keyword : keyword.toLowerCase();
904
923
  const testName = caseSensitive ? node.name.value : node.name.value.toLowerCase();
905
924
  if (testName.startsWith(testKeyword)) {
925
+ const { start } = node.name.loc;
906
926
  context.report({
907
927
  loc: {
908
928
  start: {
909
- line: node.name.loc.start.line,
910
- column: node.name.loc.start.column - 1,
929
+ line: start.line,
930
+ column: start.column - 1,
911
931
  },
912
932
  end: {
913
- line: node.name.loc.start.line,
914
- column: node.name.loc.start.column + testKeyword.length - 1,
933
+ line: start.line,
934
+ column: start.column - 1 + testKeyword.length,
915
935
  },
916
936
  },
917
937
  data: {
@@ -954,6 +974,7 @@ const rule$3 = {
954
974
  },
955
975
  ],
956
976
  },
977
+ schema: [],
957
978
  },
958
979
  create(context) {
959
980
  const schema = requireGraphQLSchemaFromContext('avoid-scalar-result-type-on-mutation', context);
@@ -961,16 +982,20 @@ const rule$3 = {
961
982
  if (!mutationType) {
962
983
  return {};
963
984
  }
964
- const selector = `:matches(${Kind.OBJECT_TYPE_DEFINITION}, ${Kind.OBJECT_TYPE_EXTENSION})[name.value=${mutationType.name}] > ${Kind.FIELD_DEFINITION}`;
985
+ const selector = [
986
+ `:matches(${Kind.OBJECT_TYPE_DEFINITION}, ${Kind.OBJECT_TYPE_EXTENSION})[name.value=${mutationType.name}]`,
987
+ '>',
988
+ Kind.FIELD_DEFINITION,
989
+ Kind.NAMED_TYPE,
990
+ ].join(' ');
965
991
  return {
966
992
  [selector](node) {
967
- const rawNode = node.rawNode();
968
- const typeName = getTypeName(rawNode);
993
+ const typeName = node.name.value;
969
994
  const graphQLType = schema.getType(typeName);
970
995
  if (isScalarType(graphQLType)) {
971
996
  context.report({
972
- node,
973
- message: `Unexpected scalar result type "${typeName}".`,
997
+ loc: getLocation(node.loc, typeName),
998
+ message: `Unexpected scalar result type "${typeName}"`,
974
999
  });
975
1000
  }
976
1001
  },
@@ -1009,22 +1034,33 @@ const rule$4 = {
1009
1034
  messages: {
1010
1035
  [AVOID_TYPENAME_PREFIX]: `Field "{{ fieldName }}" starts with the name of the parent type "{{ typeName }}"`,
1011
1036
  },
1037
+ schema: [],
1012
1038
  },
1013
1039
  create(context) {
1014
1040
  return {
1015
1041
  'ObjectTypeDefinition, ObjectTypeExtension, InterfaceTypeDefinition, InterfaceTypeExtension'(node) {
1016
1042
  const typeName = node.name.value;
1017
- const lowerTypeName = (typeName || '').toLowerCase();
1043
+ const lowerTypeName = typeName.toLowerCase();
1018
1044
  for (const field of node.fields) {
1019
- const fieldName = field.name.value || '';
1020
- if (fieldName && lowerTypeName && fieldName.toLowerCase().startsWith(lowerTypeName)) {
1045
+ const fieldName = field.name.value;
1046
+ if (fieldName.toLowerCase().startsWith(lowerTypeName)) {
1047
+ const { start } = field.loc;
1021
1048
  context.report({
1022
- node: field.name,
1023
1049
  data: {
1024
1050
  fieldName,
1025
1051
  typeName,
1026
1052
  },
1027
1053
  messageId: AVOID_TYPENAME_PREFIX,
1054
+ loc: {
1055
+ start: {
1056
+ line: start.line,
1057
+ column: start.column - 1,
1058
+ },
1059
+ end: {
1060
+ line: start.line,
1061
+ column: start.column - 1 + lowerTypeName.length,
1062
+ },
1063
+ },
1028
1064
  });
1029
1065
  }
1030
1066
  }
@@ -1171,10 +1207,11 @@ const rule$6 = {
1171
1207
  const shouldCheckType = node => (options.checkMutations && isMutationType(node)) || (options.checkQueries && isQueryType(node));
1172
1208
  const listeners = {
1173
1209
  'FieldDefinition > InputValueDefinition': node => {
1174
- if (node.name.value !== 'input' && shouldCheckType(node.parent.parent)) {
1210
+ const name = node.name.value;
1211
+ if (name !== 'input' && shouldCheckType(node.parent.parent)) {
1175
1212
  context.report({
1176
- node: node.name,
1177
- message: `Input "${node.name.value}" should be called "input"`,
1213
+ loc: getLocation(node.loc, name),
1214
+ message: `Input "${name}" should be called "input"`,
1178
1215
  });
1179
1216
  }
1180
1217
  },
@@ -1191,11 +1228,12 @@ const rule$6 = {
1191
1228
  const inputValueNode = findInputType(node);
1192
1229
  if (shouldCheckType(inputValueNode.parent.parent)) {
1193
1230
  const mutationName = `${inputValueNode.parent.name.value}Input`;
1231
+ const name = node.name.value;
1194
1232
  if ((options.caseSensitiveInputType && node.name.value !== mutationName) ||
1195
- node.name.value.toLowerCase() !== mutationName.toLowerCase()) {
1233
+ name.toLowerCase() !== mutationName.toLowerCase()) {
1196
1234
  context.report({
1197
- node,
1198
- message: `InputType "${node.name.value}" name should be "${mutationName}"`,
1235
+ loc: getLocation(node.loc, name),
1236
+ message: `InputType "${name}" name should be "${mutationName}"`,
1199
1237
  });
1200
1238
  }
1201
1239
  }
@@ -1352,7 +1390,8 @@ const rule$7 = {
1352
1390
  var _a;
1353
1391
  if (options.fileExtension && options.fileExtension !== fileExtension) {
1354
1392
  context.report({
1355
- node: documentNode,
1393
+ // Report on first character
1394
+ loc: { column: 0, line: 1 },
1356
1395
  messageId: MATCH_EXTENSION,
1357
1396
  data: {
1358
1397
  fileExtension,
@@ -1384,7 +1423,8 @@ const rule$7 = {
1384
1423
  const filenameWithExtension = filename + expectedExtension;
1385
1424
  if (expectedFilename !== filenameWithExtension) {
1386
1425
  context.report({
1387
- node: documentNode,
1426
+ // Report on first character
1427
+ loc: { column: 0, line: 1 },
1388
1428
  messageId: MATCH_STYLE,
1389
1429
  data: {
1390
1430
  expectedFilename,
@@ -1722,20 +1762,24 @@ const rule$9 = {
1722
1762
  messages: {
1723
1763
  [NO_ANONYMOUS_OPERATIONS]: `Anonymous GraphQL operations are forbidden. Please make sure to name your {{ operation }}!`,
1724
1764
  },
1765
+ schema: [],
1725
1766
  },
1726
1767
  create(context) {
1727
1768
  return {
1728
1769
  OperationDefinition(node) {
1729
- if (node && (!node.name || node.name.value === '')) {
1770
+ var _a;
1771
+ const isAnonymous = (((_a = node.name) === null || _a === void 0 ? void 0 : _a.value) || '').length === 0;
1772
+ if (isAnonymous) {
1773
+ const { start } = node.loc;
1730
1774
  context.report({
1731
1775
  loc: {
1732
1776
  start: {
1733
- column: node.loc.start.column - 1,
1734
- line: node.loc.start.line,
1777
+ column: start.column - 1,
1778
+ line: start.line,
1735
1779
  },
1736
1780
  end: {
1737
- column: node.loc.start.column + node.operation.length,
1738
- line: node.loc.start.line,
1781
+ column: start.column - 1 + node.operation.length,
1782
+ line: start.line,
1739
1783
  },
1740
1784
  },
1741
1785
  data: {
@@ -1785,6 +1829,7 @@ const rule$a = {
1785
1829
  messages: {
1786
1830
  [ERROR_MESSAGE_ID]: `Case-insensitive enum values duplicates are not allowed! Found: "{{ found }}"`,
1787
1831
  },
1832
+ schema: [],
1788
1833
  },
1789
1834
  create(context) {
1790
1835
  return {
@@ -1879,6 +1924,7 @@ const rule$b = {
1879
1924
  messages: {
1880
1925
  [NO_DEPRECATED]: `This {{ type }} is marked as deprecated in your GraphQL schema {{ reason }}`,
1881
1926
  },
1927
+ schema: [],
1882
1928
  },
1883
1929
  create(context) {
1884
1930
  return {
@@ -1965,6 +2011,7 @@ const rule$c = {
1965
2011
  ],
1966
2012
  },
1967
2013
  type: 'suggestion',
2014
+ schema: [],
1968
2015
  },
1969
2016
  create(context) {
1970
2017
  return {
@@ -2025,15 +2072,28 @@ const rule$d = {
2025
2072
  messages: {
2026
2073
  [NO_OPERATION_NAME_SUFFIX]: `Unnecessary "{{ invalidSuffix }}" suffix in your operation name!`,
2027
2074
  },
2075
+ schema: [],
2028
2076
  },
2029
2077
  create(context) {
2030
2078
  return {
2031
2079
  'OperationDefinition, FragmentDefinition'(node) {
2032
- if (node && node.name && node.name.value !== '') {
2033
- const invalidSuffix = (node.type === 'OperationDefinition' ? node.operation : 'fragment').toLowerCase();
2034
- if (node.name.value.toLowerCase().endsWith(invalidSuffix)) {
2080
+ var _a;
2081
+ const name = ((_a = node.name) === null || _a === void 0 ? void 0 : _a.value) || '';
2082
+ if (name.length > 0) {
2083
+ const invalidSuffix = 'operation' in node ? node.operation : 'fragment';
2084
+ if (name.toLowerCase().endsWith(invalidSuffix)) {
2085
+ const { start, end } = node.name.loc;
2035
2086
  context.report({
2036
- node: node.name,
2087
+ loc: {
2088
+ start: {
2089
+ column: start.column - 1 + name.length - invalidSuffix.length,
2090
+ line: start.line,
2091
+ },
2092
+ end: {
2093
+ column: end.column - 1 + name.length,
2094
+ line: end.line,
2095
+ },
2096
+ },
2037
2097
  data: {
2038
2098
  invalidSuffix,
2039
2099
  },
@@ -2090,6 +2150,7 @@ const rule$e = {
2090
2150
  },
2091
2151
  fixable: 'code',
2092
2152
  type: 'suggestion',
2153
+ schema: [],
2093
2154
  },
2094
2155
  create(context) {
2095
2156
  const reachableTypes = requireReachableTypesFromContext(RULE_NAME, context);
@@ -2181,6 +2242,7 @@ const rule$f = {
2181
2242
  },
2182
2243
  fixable: 'code',
2183
2244
  type: 'suggestion',
2245
+ schema: [],
2184
2246
  },
2185
2247
  create(context) {
2186
2248
  const usedFields = requireUsedFieldsFromContext(RULE_NAME$1, context);
@@ -2446,6 +2508,7 @@ const rule$h = {
2446
2508
  ],
2447
2509
  },
2448
2510
  type: 'suggestion',
2511
+ schema: [],
2449
2512
  },
2450
2513
  create(context) {
2451
2514
  return {
@@ -2482,15 +2545,18 @@ const DESCRIBABLE_NODES = [
2482
2545
  function verifyRule(context, node) {
2483
2546
  if (node) {
2484
2547
  if (!node.description || !node.description.value || node.description.value.trim().length === 0) {
2548
+ const { start, end } = ('name' in node ? node.name : node).loc;
2485
2549
  context.report({
2486
2550
  loc: {
2487
2551
  start: {
2488
- line: node.loc.start.line,
2489
- column: node.loc.start.column - 1,
2552
+ line: start.line,
2553
+ column: start.column - 1,
2490
2554
  },
2491
2555
  end: {
2492
- line: node.loc.end.line,
2493
- column: node.loc.end.column,
2556
+ line: end.line,
2557
+ column:
2558
+ // node.name don't exist on SchemaDefinition
2559
+ 'name' in node ? end.column - 1 + node.name.value.length : end.column,
2494
2560
  },
2495
2561
  },
2496
2562
  messageId: REQUIRE_DESCRIPTION_ERROR,
@@ -2604,6 +2670,7 @@ const rule$j = {
2604
2670
  },
2605
2671
  ],
2606
2672
  },
2673
+ schema: [],
2607
2674
  },
2608
2675
  create(context) {
2609
2676
  const schema = requireGraphQLSchemaFromContext(RULE_NAME$2, context);
@@ -3140,11 +3207,7 @@ const rule$m = {
3140
3207
  const RULE_NAME$3 = 'unique-fragment-name';
3141
3208
  const UNIQUE_FRAGMENT_NAME = 'UNIQUE_FRAGMENT_NAME';
3142
3209
  const checkNode = (context, node, ruleName, messageId) => {
3143
- var _a;
3144
- const documentName = (_a = node.name) === null || _a === void 0 ? void 0 : _a.value;
3145
- if (!documentName) {
3146
- return;
3147
- }
3210
+ const documentName = node.name.value;
3148
3211
  const siblings = requireSiblingsOperations(ruleName, context);
3149
3212
  const siblingDocuments = node.kind === Kind.FRAGMENT_DEFINITION ? siblings.getFragment(documentName) : siblings.getOperation(documentName);
3150
3213
  const filepath = context.getFilename();
@@ -3155,7 +3218,6 @@ const checkNode = (context, node, ruleName, messageId) => {
3155
3218
  return isSameName && !isSamePath;
3156
3219
  });
3157
3220
  if (conflictingDocuments.length > 0) {
3158
- const { start, end } = node.name.loc;
3159
3221
  context.report({
3160
3222
  messageId,
3161
3223
  data: {
@@ -3164,16 +3226,7 @@ const checkNode = (context, node, ruleName, messageId) => {
3164
3226
  .map(f => `\t${relative(process.cwd(), getOnDiskFilepath(f.filePath))}`)
3165
3227
  .join('\n'),
3166
3228
  },
3167
- loc: {
3168
- start: {
3169
- line: start.line,
3170
- column: start.column - 1,
3171
- },
3172
- end: {
3173
- line: end.line,
3174
- column: end.column - 1,
3175
- },
3176
- },
3229
+ loc: getLocation(node.name.loc, documentName),
3177
3230
  });
3178
3231
  }
3179
3232
  };
@@ -3223,6 +3276,7 @@ const rule$n = {
3223
3276
  messages: {
3224
3277
  [UNIQUE_FRAGMENT_NAME]: 'Fragment named "{{ documentName }}" already defined in:\n{{ summary }}',
3225
3278
  },
3279
+ schema: [],
3226
3280
  },
3227
3281
  create(context) {
3228
3282
  return {
@@ -3285,10 +3339,11 @@ const rule$o = {
3285
3339
  messages: {
3286
3340
  [UNIQUE_OPERATION_NAME]: 'Operation named "{{ documentName }}" already defined in:\n{{ summary }}',
3287
3341
  },
3342
+ schema: [],
3288
3343
  },
3289
3344
  create(context) {
3290
3345
  return {
3291
- OperationDefinition(node) {
3346
+ 'OperationDefinition[name!=undefined]'(node) {
3292
3347
  checkNode(context, node, RULE_NAME$4, UNIQUE_OPERATION_NAME);
3293
3348
  },
3294
3349
  };
@@ -3718,22 +3773,92 @@ function parseForESLint(code, options = {}) {
3718
3773
  }
3719
3774
  }
3720
3775
 
3721
- class GraphQLRuleTester extends require('eslint').RuleTester {
3776
+ class GraphQLRuleTester extends RuleTester {
3722
3777
  constructor(parserOptions = {}) {
3723
- super({
3778
+ const config = {
3724
3779
  parser: require.resolve('@graphql-eslint/eslint-plugin'),
3725
3780
  parserOptions: {
3726
3781
  ...parserOptions,
3727
3782
  skipGraphQLConfig: true,
3728
3783
  },
3729
- });
3784
+ };
3785
+ super(config);
3786
+ this.config = config;
3730
3787
  }
3731
3788
  fromMockFile(path) {
3732
3789
  return readFileSync(resolve(__dirname, `../tests/mocks/${path}`), 'utf-8');
3733
3790
  }
3734
3791
  runGraphQLTests(name, rule, tests) {
3735
3792
  super.run(name, rule, tests);
3793
+ // Skip snapshot testing if `expect` variable is not defined
3794
+ if (typeof expect === 'undefined') {
3795
+ return;
3796
+ }
3797
+ const linter = new Linter();
3798
+ linter.defineRule(name, rule);
3799
+ for (const testCase of tests.invalid) {
3800
+ const verifyConfig = getVerifyConfig(name, this.config, testCase);
3801
+ defineParser(linter, verifyConfig.parser);
3802
+ const { code, filename } = testCase;
3803
+ const messages = linter.verify(code, verifyConfig, { filename });
3804
+ for (const message of messages) {
3805
+ if (message.fatal) {
3806
+ throw new Error(message.message);
3807
+ }
3808
+ const messageForSnapshot = visualizeEslintMessage(code, message);
3809
+ // eslint-disable-next-line no-undef
3810
+ expect(messageForSnapshot).toMatchSnapshot();
3811
+ }
3812
+ }
3736
3813
  }
3737
3814
  }
3815
+ function getVerifyConfig(ruleId, testerConfig, testCase) {
3816
+ const { options, parserOptions, parser = testerConfig.parser } = testCase;
3817
+ return {
3818
+ ...testerConfig,
3819
+ parser,
3820
+ parserOptions: {
3821
+ ...testerConfig.parserOptions,
3822
+ ...parserOptions,
3823
+ },
3824
+ rules: {
3825
+ [ruleId]: ['error', ...(Array.isArray(options) ? options : [])],
3826
+ },
3827
+ };
3828
+ }
3829
+ const parsers = new WeakMap();
3830
+ function defineParser(linter, parser) {
3831
+ if (!parser) {
3832
+ return;
3833
+ }
3834
+ if (!parsers.has(linter)) {
3835
+ parsers.set(linter, new Set());
3836
+ }
3837
+ const defined = parsers.get(linter);
3838
+ if (!defined.has(parser)) {
3839
+ defined.add(parser);
3840
+ linter.defineParser(parser, require(parser));
3841
+ }
3842
+ }
3843
+ function visualizeEslintMessage(text, result) {
3844
+ const { line, column, endLine, endColumn, message } = result;
3845
+ const location = {
3846
+ start: {
3847
+ line,
3848
+ column,
3849
+ },
3850
+ };
3851
+ if (typeof endLine === 'number' && typeof endColumn === 'number') {
3852
+ location.end = {
3853
+ line: endLine,
3854
+ column: endColumn,
3855
+ };
3856
+ }
3857
+ return codeFrameColumns(text, location, {
3858
+ linesAbove: Number.POSITIVE_INFINITY,
3859
+ linesBelow: Number.POSITIVE_INFINITY,
3860
+ message,
3861
+ });
3862
+ }
3738
3863
 
3739
3864
  export { GraphQLRuleTester, configs, convertDescription, convertLocation, convertRange, convertToESTree, extractCommentsFromAst, getBaseType, isNodeWithDescription, parse, parseForESLint, processors, rules, valueFromNode };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@graphql-eslint/eslint-plugin",
3
- "version": "2.3.0",
3
+ "version": "2.3.2-alpha-13a11c2.0",
4
4
  "sideEffects": false,
5
5
  "peerDependencies": {
6
6
  "graphql": "^0.8.0 || ^0.9.0 || ^0.10.0 || ^0.11.0 || ^0.12.0 || ^0.13.0 || ^14.0.0 || ^15.0.0"
package/testkit.d.ts CHANGED
@@ -13,8 +13,11 @@ export declare type GraphQLInvalidTestCase<T> = GraphQLValidTestCase<T> & {
13
13
  errors: number | Array<RuleTester.TestCaseError | string>;
14
14
  output?: string | null;
15
15
  };
16
- declare const GraphQLRuleTester_base: any;
17
- export declare class GraphQLRuleTester extends GraphQLRuleTester_base {
16
+ export declare class GraphQLRuleTester extends RuleTester {
17
+ config: {
18
+ parser: string;
19
+ parserOptions: ParserOptions;
20
+ };
18
21
  constructor(parserOptions?: ParserOptions);
19
22
  fromMockFile(path: string): string;
20
23
  runGraphQLTests<Config>(name: string, rule: GraphQLESLintRule, tests: {
@@ -22,4 +25,3 @@ export declare class GraphQLRuleTester extends GraphQLRuleTester_base {
22
25
  invalid: GraphQLInvalidTestCase<Config>[];
23
26
  }): void;
24
27
  }
25
- export {};
package/types.d.ts CHANGED
@@ -56,9 +56,11 @@ export declare type RuleDocsInfo<T> = Rule.RuleMetaData & {
56
56
  usage?: T;
57
57
  }[];
58
58
  optionsForConfig?: T;
59
+ graphQLJSRuleName?: string;
59
60
  };
60
61
  };
61
62
  export declare type GraphQLESLintRule<Options = any[], WithTypeInfo extends boolean = false> = {
62
63
  create(context: GraphQLESLintRuleContext<Options>): GraphQLESLintRuleListener<WithTypeInfo>;
63
64
  meta: Rule.RuleMetaData & RuleDocsInfo<Options>;
64
65
  };
66
+ export declare type ValueOf<T> = T[keyof T];
package/utils.d.ts CHANGED
@@ -33,4 +33,8 @@ export declare enum CaseStyle {
33
33
  }
34
34
  export declare const camelCase: (str: string) => string;
35
35
  export declare const convertCase: (style: CaseStyle, str: string) => string;
36
+ export declare function getLocation(loc: Partial<AST.SourceLocation>, fieldName?: string, offset?: {
37
+ offsetStart?: number;
38
+ offsetEnd?: number;
39
+ }): AST.SourceLocation;
36
40
  export {};