@graphql-eslint/eslint-plugin 2.3.0-alpha-f7157af.0 → 2.3.2-alpha-2901045.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 +167 -55
  61. package/index.mjs +167 -55
  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,
@@ -585,7 +606,7 @@ const rule = {
585
606
  ],
586
607
  },
587
608
  messages: {
588
- [ALPHABETIZE]: '"{{ currName }}" should be before "{{ prevName }}".',
609
+ [ALPHABETIZE]: '"{{ currName }}" should be before "{{ prevName }}"',
589
610
  },
590
611
  schema: {
591
612
  type: 'array',
@@ -642,19 +663,9 @@ const rule = {
642
663
  for (const node of nodes) {
643
664
  const currName = node.name.value;
644
665
  if (prevName && prevName > currName) {
645
- const { start, end } = node.name.loc;
646
666
  const isVariableNode = node.kind === Kind.VARIABLE;
647
667
  context.report({
648
- loc: {
649
- start: {
650
- line: start.line,
651
- column: start.column - (isVariableNode ? 2 : 1),
652
- },
653
- end: {
654
- line: end.line,
655
- column: end.column,
656
- },
657
- },
668
+ loc: getLocation(node.loc, node.name.value, { offsetEnd: isVariableNode ? 0 : 1 }),
658
669
  messageId: ALPHABETIZE,
659
670
  data: isVariableNode
660
671
  ? {
@@ -784,6 +795,7 @@ const rule$1 = {
784
795
  messages: {
785
796
  [AVOID_DUPLICATE_FIELDS]: `{{ type }} "{{ fieldName }}" defined multiple times.`,
786
797
  },
798
+ schema: [],
787
799
  },
788
800
  create(context) {
789
801
  return {
@@ -903,15 +915,16 @@ const rule$2 = {
903
915
  const testKeyword = caseSensitive ? keyword : keyword.toLowerCase();
904
916
  const testName = caseSensitive ? node.name.value : node.name.value.toLowerCase();
905
917
  if (testName.startsWith(testKeyword)) {
918
+ const { start } = node.name.loc;
906
919
  context.report({
907
920
  loc: {
908
921
  start: {
909
- line: node.name.loc.start.line,
910
- column: node.name.loc.start.column - 1,
922
+ line: start.line,
923
+ column: start.column - 1,
911
924
  },
912
925
  end: {
913
- line: node.name.loc.start.line,
914
- column: node.name.loc.start.column + testKeyword.length - 1,
926
+ line: start.line,
927
+ column: start.column - 1 + testKeyword.length,
915
928
  },
916
929
  },
917
930
  data: {
@@ -954,6 +967,7 @@ const rule$3 = {
954
967
  },
955
968
  ],
956
969
  },
970
+ schema: [],
957
971
  },
958
972
  create(context) {
959
973
  const schema = requireGraphQLSchemaFromContext('avoid-scalar-result-type-on-mutation', context);
@@ -1009,22 +1023,33 @@ const rule$4 = {
1009
1023
  messages: {
1010
1024
  [AVOID_TYPENAME_PREFIX]: `Field "{{ fieldName }}" starts with the name of the parent type "{{ typeName }}"`,
1011
1025
  },
1026
+ schema: [],
1012
1027
  },
1013
1028
  create(context) {
1014
1029
  return {
1015
1030
  'ObjectTypeDefinition, ObjectTypeExtension, InterfaceTypeDefinition, InterfaceTypeExtension'(node) {
1016
1031
  const typeName = node.name.value;
1017
- const lowerTypeName = (typeName || '').toLowerCase();
1032
+ const lowerTypeName = typeName.toLowerCase();
1018
1033
  for (const field of node.fields) {
1019
- const fieldName = field.name.value || '';
1020
- if (fieldName && lowerTypeName && fieldName.toLowerCase().startsWith(lowerTypeName)) {
1034
+ const fieldName = field.name.value;
1035
+ if (fieldName.toLowerCase().startsWith(lowerTypeName)) {
1036
+ const { start } = field.loc;
1021
1037
  context.report({
1022
- node: field.name,
1023
1038
  data: {
1024
1039
  fieldName,
1025
1040
  typeName,
1026
1041
  },
1027
1042
  messageId: AVOID_TYPENAME_PREFIX,
1043
+ loc: {
1044
+ start: {
1045
+ line: start.line,
1046
+ column: start.column - 1,
1047
+ },
1048
+ end: {
1049
+ line: start.line,
1050
+ column: start.column - 1 + lowerTypeName.length,
1051
+ },
1052
+ },
1028
1053
  });
1029
1054
  }
1030
1055
  }
@@ -1352,7 +1377,8 @@ const rule$7 = {
1352
1377
  var _a;
1353
1378
  if (options.fileExtension && options.fileExtension !== fileExtension) {
1354
1379
  context.report({
1355
- node: documentNode,
1380
+ // Report on first character
1381
+ loc: { column: 0, line: 1 },
1356
1382
  messageId: MATCH_EXTENSION,
1357
1383
  data: {
1358
1384
  fileExtension,
@@ -1384,7 +1410,8 @@ const rule$7 = {
1384
1410
  const filenameWithExtension = filename + expectedExtension;
1385
1411
  if (expectedFilename !== filenameWithExtension) {
1386
1412
  context.report({
1387
- node: documentNode,
1413
+ // Report on first character
1414
+ loc: { column: 0, line: 1 },
1388
1415
  messageId: MATCH_STYLE,
1389
1416
  data: {
1390
1417
  expectedFilename,
@@ -1722,20 +1749,24 @@ const rule$9 = {
1722
1749
  messages: {
1723
1750
  [NO_ANONYMOUS_OPERATIONS]: `Anonymous GraphQL operations are forbidden. Please make sure to name your {{ operation }}!`,
1724
1751
  },
1752
+ schema: [],
1725
1753
  },
1726
1754
  create(context) {
1727
1755
  return {
1728
1756
  OperationDefinition(node) {
1729
- if (node && (!node.name || node.name.value === '')) {
1757
+ var _a;
1758
+ const isAnonymous = (((_a = node.name) === null || _a === void 0 ? void 0 : _a.value) || '').length === 0;
1759
+ if (isAnonymous) {
1760
+ const { start } = node.loc;
1730
1761
  context.report({
1731
1762
  loc: {
1732
1763
  start: {
1733
- column: node.loc.start.column - 1,
1734
- line: node.loc.start.line,
1764
+ column: start.column - 1,
1765
+ line: start.line,
1735
1766
  },
1736
1767
  end: {
1737
- column: node.loc.start.column + node.operation.length,
1738
- line: node.loc.start.line,
1768
+ column: start.column - 1 + node.operation.length,
1769
+ line: start.line,
1739
1770
  },
1740
1771
  },
1741
1772
  data: {
@@ -1785,6 +1816,7 @@ const rule$a = {
1785
1816
  messages: {
1786
1817
  [ERROR_MESSAGE_ID]: `Case-insensitive enum values duplicates are not allowed! Found: "{{ found }}"`,
1787
1818
  },
1819
+ schema: [],
1788
1820
  },
1789
1821
  create(context) {
1790
1822
  return {
@@ -1879,6 +1911,7 @@ const rule$b = {
1879
1911
  messages: {
1880
1912
  [NO_DEPRECATED]: `This {{ type }} is marked as deprecated in your GraphQL schema {{ reason }}`,
1881
1913
  },
1914
+ schema: [],
1882
1915
  },
1883
1916
  create(context) {
1884
1917
  return {
@@ -1965,6 +1998,7 @@ const rule$c = {
1965
1998
  ],
1966
1999
  },
1967
2000
  type: 'suggestion',
2001
+ schema: [],
1968
2002
  },
1969
2003
  create(context) {
1970
2004
  return {
@@ -2025,15 +2059,28 @@ const rule$d = {
2025
2059
  messages: {
2026
2060
  [NO_OPERATION_NAME_SUFFIX]: `Unnecessary "{{ invalidSuffix }}" suffix in your operation name!`,
2027
2061
  },
2062
+ schema: [],
2028
2063
  },
2029
2064
  create(context) {
2030
2065
  return {
2031
2066
  '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)) {
2067
+ var _a;
2068
+ const name = ((_a = node.name) === null || _a === void 0 ? void 0 : _a.value) || '';
2069
+ if (name.length > 0) {
2070
+ const invalidSuffix = 'operation' in node ? node.operation : 'fragment';
2071
+ if (name.toLowerCase().endsWith(invalidSuffix)) {
2072
+ const { start, end } = node.name.loc;
2035
2073
  context.report({
2036
- node: node.name,
2074
+ loc: {
2075
+ start: {
2076
+ column: start.column - 1 + name.length - invalidSuffix.length,
2077
+ line: start.line,
2078
+ },
2079
+ end: {
2080
+ column: end.column - 1 + name.length,
2081
+ line: end.line,
2082
+ },
2083
+ },
2037
2084
  data: {
2038
2085
  invalidSuffix,
2039
2086
  },
@@ -2090,6 +2137,7 @@ const rule$e = {
2090
2137
  },
2091
2138
  fixable: 'code',
2092
2139
  type: 'suggestion',
2140
+ schema: [],
2093
2141
  },
2094
2142
  create(context) {
2095
2143
  const reachableTypes = requireReachableTypesFromContext(RULE_NAME, context);
@@ -2181,6 +2229,7 @@ const rule$f = {
2181
2229
  },
2182
2230
  fixable: 'code',
2183
2231
  type: 'suggestion',
2232
+ schema: [],
2184
2233
  },
2185
2234
  create(context) {
2186
2235
  const usedFields = requireUsedFieldsFromContext(RULE_NAME$1, context);
@@ -2446,6 +2495,7 @@ const rule$h = {
2446
2495
  ],
2447
2496
  },
2448
2497
  type: 'suggestion',
2498
+ schema: [],
2449
2499
  },
2450
2500
  create(context) {
2451
2501
  return {
@@ -2482,15 +2532,18 @@ const DESCRIBABLE_NODES = [
2482
2532
  function verifyRule(context, node) {
2483
2533
  if (node) {
2484
2534
  if (!node.description || !node.description.value || node.description.value.trim().length === 0) {
2535
+ const { start, end } = ('name' in node ? node.name : node).loc;
2485
2536
  context.report({
2486
2537
  loc: {
2487
2538
  start: {
2488
- line: node.loc.start.line,
2489
- column: node.loc.start.column - 1,
2539
+ line: start.line,
2540
+ column: start.column - 1,
2490
2541
  },
2491
2542
  end: {
2492
- line: node.loc.end.line,
2493
- column: node.loc.end.column,
2543
+ line: end.line,
2544
+ column:
2545
+ // node.name don't exist on SchemaDefinition
2546
+ 'name' in node ? end.column - 1 + node.name.value.length : end.column,
2494
2547
  },
2495
2548
  },
2496
2549
  messageId: REQUIRE_DESCRIPTION_ERROR,
@@ -2604,6 +2657,7 @@ const rule$j = {
2604
2657
  },
2605
2658
  ],
2606
2659
  },
2660
+ schema: [],
2607
2661
  },
2608
2662
  create(context) {
2609
2663
  const schema = requireGraphQLSchemaFromContext(RULE_NAME$2, context);
@@ -3140,11 +3194,7 @@ const rule$m = {
3140
3194
  const RULE_NAME$3 = 'unique-fragment-name';
3141
3195
  const UNIQUE_FRAGMENT_NAME = 'UNIQUE_FRAGMENT_NAME';
3142
3196
  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
- }
3197
+ const documentName = node.name.value;
3148
3198
  const siblings = requireSiblingsOperations(ruleName, context);
3149
3199
  const siblingDocuments = node.kind === Kind.FRAGMENT_DEFINITION ? siblings.getFragment(documentName) : siblings.getOperation(documentName);
3150
3200
  const filepath = context.getFilename();
@@ -3155,7 +3205,6 @@ const checkNode = (context, node, ruleName, messageId) => {
3155
3205
  return isSameName && !isSamePath;
3156
3206
  });
3157
3207
  if (conflictingDocuments.length > 0) {
3158
- const { start, end } = node.name.loc;
3159
3208
  context.report({
3160
3209
  messageId,
3161
3210
  data: {
@@ -3164,16 +3213,7 @@ const checkNode = (context, node, ruleName, messageId) => {
3164
3213
  .map(f => `\t${relative(process.cwd(), getOnDiskFilepath(f.filePath))}`)
3165
3214
  .join('\n'),
3166
3215
  },
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
- },
3216
+ loc: getLocation(node.name.loc, documentName),
3177
3217
  });
3178
3218
  }
3179
3219
  };
@@ -3223,6 +3263,7 @@ const rule$n = {
3223
3263
  messages: {
3224
3264
  [UNIQUE_FRAGMENT_NAME]: 'Fragment named "{{ documentName }}" already defined in:\n{{ summary }}',
3225
3265
  },
3266
+ schema: [],
3226
3267
  },
3227
3268
  create(context) {
3228
3269
  return {
@@ -3285,10 +3326,11 @@ const rule$o = {
3285
3326
  messages: {
3286
3327
  [UNIQUE_OPERATION_NAME]: 'Operation named "{{ documentName }}" already defined in:\n{{ summary }}',
3287
3328
  },
3329
+ schema: [],
3288
3330
  },
3289
3331
  create(context) {
3290
3332
  return {
3291
- OperationDefinition(node) {
3333
+ 'OperationDefinition[name!=undefined]'(node) {
3292
3334
  checkNode(context, node, RULE_NAME$4, UNIQUE_OPERATION_NAME);
3293
3335
  },
3294
3336
  };
@@ -3718,22 +3760,92 @@ function parseForESLint(code, options = {}) {
3718
3760
  }
3719
3761
  }
3720
3762
 
3721
- class GraphQLRuleTester extends require('eslint').RuleTester {
3763
+ class GraphQLRuleTester extends RuleTester {
3722
3764
  constructor(parserOptions = {}) {
3723
- super({
3765
+ const config = {
3724
3766
  parser: require.resolve('@graphql-eslint/eslint-plugin'),
3725
3767
  parserOptions: {
3726
3768
  ...parserOptions,
3727
3769
  skipGraphQLConfig: true,
3728
3770
  },
3729
- });
3771
+ };
3772
+ super(config);
3773
+ this.config = config;
3730
3774
  }
3731
3775
  fromMockFile(path) {
3732
3776
  return readFileSync(resolve(__dirname, `../tests/mocks/${path}`), 'utf-8');
3733
3777
  }
3734
3778
  runGraphQLTests(name, rule, tests) {
3735
3779
  super.run(name, rule, tests);
3780
+ // Skip snapshot testing if `expect` variable is not defined
3781
+ if (typeof expect === 'undefined') {
3782
+ return;
3783
+ }
3784
+ const linter = new Linter();
3785
+ linter.defineRule(name, rule);
3786
+ for (const testCase of tests.invalid) {
3787
+ const verifyConfig = getVerifyConfig(name, this.config, testCase);
3788
+ defineParser(linter, verifyConfig.parser);
3789
+ const { code, filename } = testCase;
3790
+ const messages = linter.verify(code, verifyConfig, { filename });
3791
+ for (const message of messages) {
3792
+ if (message.fatal) {
3793
+ throw new Error(message.message);
3794
+ }
3795
+ const messageForSnapshot = visualizeEslintMessage(code, message);
3796
+ // eslint-disable-next-line no-undef
3797
+ expect(messageForSnapshot).toMatchSnapshot();
3798
+ }
3799
+ }
3800
+ }
3801
+ }
3802
+ function getVerifyConfig(ruleId, testerConfig, testCase) {
3803
+ const { options, parserOptions, parser = testerConfig.parser } = testCase;
3804
+ return {
3805
+ ...testerConfig,
3806
+ parser,
3807
+ parserOptions: {
3808
+ ...testerConfig.parserOptions,
3809
+ ...parserOptions,
3810
+ },
3811
+ rules: {
3812
+ [ruleId]: ['error', ...(Array.isArray(options) ? options : [])],
3813
+ },
3814
+ };
3815
+ }
3816
+ const parsers = new WeakMap();
3817
+ function defineParser(linter, parser) {
3818
+ if (!parser) {
3819
+ return;
3820
+ }
3821
+ if (!parsers.has(linter)) {
3822
+ parsers.set(linter, new Set());
3823
+ }
3824
+ const defined = parsers.get(linter);
3825
+ if (!defined.has(parser)) {
3826
+ defined.add(parser);
3827
+ linter.defineParser(parser, require(parser));
3736
3828
  }
3737
3829
  }
3830
+ function visualizeEslintMessage(text, result) {
3831
+ const { line, column, endLine, endColumn, message } = result;
3832
+ const location = {
3833
+ start: {
3834
+ line,
3835
+ column,
3836
+ },
3837
+ };
3838
+ if (typeof endLine === 'number' && typeof endColumn === 'number') {
3839
+ location.end = {
3840
+ line: endLine,
3841
+ column: endColumn,
3842
+ };
3843
+ }
3844
+ return codeFrameColumns(text, location, {
3845
+ linesAbove: Number.POSITIVE_INFINITY,
3846
+ linesBelow: Number.POSITIVE_INFINITY,
3847
+ message,
3848
+ });
3849
+ }
3738
3850
 
3739
3851
  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-alpha-f7157af.0",
3
+ "version": "2.3.2-alpha-2901045.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 {};