@graphql-eslint/eslint-plugin 2.3.1 → 2.3.2-alpha-ace9d56.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.
@@ -58,7 +58,7 @@ This is useful if you wish to use other GraphQL tools that works with the origin
58
58
  Here's an example for using original `graphql-js` validate method to validate `OperationDefinition`:
59
59
 
60
60
  ```ts
61
- import { validate } from 'graphql-js';
61
+ import { validate } from 'graphql';
62
62
  import { requireGraphQLSchemaFromContext } from '@graphql-eslint/eslint-plugin';
63
63
 
64
64
  export const rule = {
package/index.js CHANGED
@@ -15,6 +15,8 @@ const depthLimit = _interopDefault(require('graphql-depth-limit'));
15
15
  const graphqlTagPluck = require('@graphql-tools/graphql-tag-pluck');
16
16
  const graphqlConfig$1 = require('graphql-config');
17
17
  const codeFileLoader = require('@graphql-tools/code-file-loader');
18
+ const eslint = require('eslint');
19
+ const codeFrame = require('@babel/code-frame');
18
20
 
19
21
  /*
20
22
  * 🚨 IMPORTANT! Do not manually modify this file. Run: `yarn generate-configs`
@@ -242,6 +244,24 @@ const convertCase = (style, str) => {
242
244
  return lowerCase(str).replace(/ /g, '-');
243
245
  }
244
246
  };
247
+ function getLocation(loc, fieldName = '', offset) {
248
+ const { start } = loc;
249
+ /*
250
+ * ESLint has 0-based column number
251
+ * https://eslint.org/docs/developer-guide/working-with-rules#contextreport
252
+ */
253
+ const { offsetStart = 1, offsetEnd = 1 } = offset !== null && offset !== void 0 ? offset : {};
254
+ return {
255
+ start: {
256
+ line: start.line,
257
+ column: start.column - offsetStart,
258
+ },
259
+ end: {
260
+ line: start.line,
261
+ column: start.column - offsetEnd + fieldName.length,
262
+ },
263
+ };
264
+ }
245
265
 
246
266
  function extractRuleName(stack) {
247
267
  const match = (stack || '').match(/validation[/\\\\]rules[/\\\\](.*?)\.js:/) || [];
@@ -968,16 +988,20 @@ const rule$3 = {
968
988
  if (!mutationType) {
969
989
  return {};
970
990
  }
971
- const selector = `:matches(${graphql.Kind.OBJECT_TYPE_DEFINITION}, ${graphql.Kind.OBJECT_TYPE_EXTENSION})[name.value=${mutationType.name}] > ${graphql.Kind.FIELD_DEFINITION}`;
991
+ const selector = [
992
+ `:matches(${graphql.Kind.OBJECT_TYPE_DEFINITION}, ${graphql.Kind.OBJECT_TYPE_EXTENSION})[name.value=${mutationType.name}]`,
993
+ '>',
994
+ graphql.Kind.FIELD_DEFINITION,
995
+ graphql.Kind.NAMED_TYPE,
996
+ ].join(' ');
972
997
  return {
973
998
  [selector](node) {
974
- const rawNode = node.rawNode();
975
- const typeName = getTypeName(rawNode);
999
+ const typeName = node.name.value;
976
1000
  const graphQLType = schema.getType(typeName);
977
1001
  if (graphql.isScalarType(graphQLType)) {
978
1002
  context.report({
979
- node,
980
- message: `Unexpected scalar result type "${typeName}".`,
1003
+ loc: getLocation(node.loc, typeName),
1004
+ message: `Unexpected scalar result type "${typeName}"`,
981
1005
  });
982
1006
  }
983
1007
  },
@@ -1370,7 +1394,8 @@ const rule$7 = {
1370
1394
  var _a;
1371
1395
  if (options.fileExtension && options.fileExtension !== fileExtension) {
1372
1396
  context.report({
1373
- node: documentNode,
1397
+ // Report on first character
1398
+ loc: { column: 0, line: 1 },
1374
1399
  messageId: MATCH_EXTENSION,
1375
1400
  data: {
1376
1401
  fileExtension,
@@ -1402,7 +1427,8 @@ const rule$7 = {
1402
1427
  const filenameWithExtension = filename + expectedExtension;
1403
1428
  if (expectedFilename !== filenameWithExtension) {
1404
1429
  context.report({
1405
- node: documentNode,
1430
+ // Report on first character
1431
+ loc: { column: 0, line: 1 },
1406
1432
  messageId: MATCH_STYLE,
1407
1433
  data: {
1408
1434
  expectedFilename,
@@ -1872,8 +1898,8 @@ const rule$b = {
1872
1898
  mutation {
1873
1899
  changeSomething(
1874
1900
  type: OLD # This is deprecated, so you'll get an error
1875
- ) {
1876
- ...
1901
+ ) {
1902
+ ...
1877
1903
  }
1878
1904
  }
1879
1905
  `,
@@ -1911,8 +1937,9 @@ const rule$b = {
1911
1937
  const typeInfo = node.typeInfo();
1912
1938
  if (typeInfo && typeInfo.enumValue) {
1913
1939
  if (typeInfo.enumValue.isDeprecated) {
1940
+ const enumValueName = node.value;
1914
1941
  context.report({
1915
- loc: node.loc,
1942
+ loc: getLocation(node.loc, enumValueName),
1916
1943
  messageId: NO_DEPRECATED,
1917
1944
  data: {
1918
1945
  type: 'enum value',
@@ -1927,8 +1954,9 @@ const rule$b = {
1927
1954
  const typeInfo = node.typeInfo();
1928
1955
  if (typeInfo && typeInfo.fieldDef) {
1929
1956
  if (typeInfo.fieldDef.isDeprecated) {
1957
+ const fieldName = node.name.value;
1930
1958
  context.report({
1931
- loc: node.loc,
1959
+ loc: getLocation(node.loc, fieldName),
1932
1960
  messageId: NO_DEPRECATED,
1933
1961
  data: {
1934
1962
  type: 'field',
@@ -3185,11 +3213,7 @@ const rule$m = {
3185
3213
  const RULE_NAME$3 = 'unique-fragment-name';
3186
3214
  const UNIQUE_FRAGMENT_NAME = 'UNIQUE_FRAGMENT_NAME';
3187
3215
  const checkNode = (context, node, ruleName, messageId) => {
3188
- var _a;
3189
- const documentName = (_a = node.name) === null || _a === void 0 ? void 0 : _a.value;
3190
- if (!documentName) {
3191
- return;
3192
- }
3216
+ const documentName = node.name.value;
3193
3217
  const siblings = requireSiblingsOperations(ruleName, context);
3194
3218
  const siblingDocuments = node.kind === graphql.Kind.FRAGMENT_DEFINITION ? siblings.getFragment(documentName) : siblings.getOperation(documentName);
3195
3219
  const filepath = context.getFilename();
@@ -3200,7 +3224,6 @@ const checkNode = (context, node, ruleName, messageId) => {
3200
3224
  return isSameName && !isSamePath;
3201
3225
  });
3202
3226
  if (conflictingDocuments.length > 0) {
3203
- const { start, end } = node.name.loc;
3204
3227
  context.report({
3205
3228
  messageId,
3206
3229
  data: {
@@ -3209,16 +3232,7 @@ const checkNode = (context, node, ruleName, messageId) => {
3209
3232
  .map(f => `\t${path.relative(process.cwd(), getOnDiskFilepath(f.filePath))}`)
3210
3233
  .join('\n'),
3211
3234
  },
3212
- loc: {
3213
- start: {
3214
- line: start.line,
3215
- column: start.column - 1,
3216
- },
3217
- end: {
3218
- line: end.line,
3219
- column: end.column - 1,
3220
- },
3221
- },
3235
+ loc: getLocation(node.name.loc, documentName),
3222
3236
  });
3223
3237
  }
3224
3238
  };
@@ -3335,7 +3349,7 @@ const rule$o = {
3335
3349
  },
3336
3350
  create(context) {
3337
3351
  return {
3338
- OperationDefinition(node) {
3352
+ 'OperationDefinition[name!=undefined]'(node) {
3339
3353
  checkNode(context, node, RULE_NAME$4, UNIQUE_OPERATION_NAME);
3340
3354
  },
3341
3355
  };
@@ -3765,23 +3779,93 @@ function parseForESLint(code, options = {}) {
3765
3779
  }
3766
3780
  }
3767
3781
 
3768
- class GraphQLRuleTester extends require('eslint').RuleTester {
3782
+ class GraphQLRuleTester extends eslint.RuleTester {
3769
3783
  constructor(parserOptions = {}) {
3770
- super({
3784
+ const config = {
3771
3785
  parser: require.resolve('@graphql-eslint/eslint-plugin'),
3772
3786
  parserOptions: {
3773
3787
  ...parserOptions,
3774
3788
  skipGraphQLConfig: true,
3775
3789
  },
3776
- });
3790
+ };
3791
+ super(config);
3792
+ this.config = config;
3777
3793
  }
3778
3794
  fromMockFile(path$1) {
3779
3795
  return fs.readFileSync(path.resolve(__dirname, `../tests/mocks/${path$1}`), 'utf-8');
3780
3796
  }
3781
3797
  runGraphQLTests(name, rule, tests) {
3782
3798
  super.run(name, rule, tests);
3799
+ // Skip snapshot testing if `expect` variable is not defined
3800
+ if (typeof expect === 'undefined') {
3801
+ return;
3802
+ }
3803
+ const linter = new eslint.Linter();
3804
+ linter.defineRule(name, rule);
3805
+ for (const testCase of tests.invalid) {
3806
+ const verifyConfig = getVerifyConfig(name, this.config, testCase);
3807
+ defineParser(linter, verifyConfig.parser);
3808
+ const { code, filename } = testCase;
3809
+ const messages = linter.verify(code, verifyConfig, { filename });
3810
+ for (const message of messages) {
3811
+ if (message.fatal) {
3812
+ throw new Error(message.message);
3813
+ }
3814
+ const messageForSnapshot = visualizeEslintMessage(code, message);
3815
+ // eslint-disable-next-line no-undef
3816
+ expect(messageForSnapshot).toMatchSnapshot();
3817
+ }
3818
+ }
3783
3819
  }
3784
3820
  }
3821
+ function getVerifyConfig(ruleId, testerConfig, testCase) {
3822
+ const { options, parserOptions, parser = testerConfig.parser } = testCase;
3823
+ return {
3824
+ ...testerConfig,
3825
+ parser,
3826
+ parserOptions: {
3827
+ ...testerConfig.parserOptions,
3828
+ ...parserOptions,
3829
+ },
3830
+ rules: {
3831
+ [ruleId]: ['error', ...(Array.isArray(options) ? options : [])],
3832
+ },
3833
+ };
3834
+ }
3835
+ const parsers = new WeakMap();
3836
+ function defineParser(linter, parser) {
3837
+ if (!parser) {
3838
+ return;
3839
+ }
3840
+ if (!parsers.has(linter)) {
3841
+ parsers.set(linter, new Set());
3842
+ }
3843
+ const defined = parsers.get(linter);
3844
+ if (!defined.has(parser)) {
3845
+ defined.add(parser);
3846
+ linter.defineParser(parser, require(parser));
3847
+ }
3848
+ }
3849
+ function visualizeEslintMessage(text, result) {
3850
+ const { line, column, endLine, endColumn, message } = result;
3851
+ const location = {
3852
+ start: {
3853
+ line,
3854
+ column,
3855
+ },
3856
+ };
3857
+ if (typeof endLine === 'number' && typeof endColumn === 'number') {
3858
+ location.end = {
3859
+ line: endLine,
3860
+ column: endColumn,
3861
+ };
3862
+ }
3863
+ return codeFrame.codeFrameColumns(text, location, {
3864
+ linesAbove: Number.POSITIVE_INFINITY,
3865
+ linesBelow: Number.POSITIVE_INFINITY,
3866
+ message,
3867
+ });
3868
+ }
3785
3869
 
3786
3870
  exports.GraphQLRuleTester = GraphQLRuleTester;
3787
3871
  exports.configs = configs;
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:/) || [];
@@ -962,16 +982,20 @@ const rule$3 = {
962
982
  if (!mutationType) {
963
983
  return {};
964
984
  }
965
- 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(' ');
966
991
  return {
967
992
  [selector](node) {
968
- const rawNode = node.rawNode();
969
- const typeName = getTypeName(rawNode);
993
+ const typeName = node.name.value;
970
994
  const graphQLType = schema.getType(typeName);
971
995
  if (isScalarType(graphQLType)) {
972
996
  context.report({
973
- node,
974
- message: `Unexpected scalar result type "${typeName}".`,
997
+ loc: getLocation(node.loc, typeName),
998
+ message: `Unexpected scalar result type "${typeName}"`,
975
999
  });
976
1000
  }
977
1001
  },
@@ -1364,7 +1388,8 @@ const rule$7 = {
1364
1388
  var _a;
1365
1389
  if (options.fileExtension && options.fileExtension !== fileExtension) {
1366
1390
  context.report({
1367
- node: documentNode,
1391
+ // Report on first character
1392
+ loc: { column: 0, line: 1 },
1368
1393
  messageId: MATCH_EXTENSION,
1369
1394
  data: {
1370
1395
  fileExtension,
@@ -1396,7 +1421,8 @@ const rule$7 = {
1396
1421
  const filenameWithExtension = filename + expectedExtension;
1397
1422
  if (expectedFilename !== filenameWithExtension) {
1398
1423
  context.report({
1399
- node: documentNode,
1424
+ // Report on first character
1425
+ loc: { column: 0, line: 1 },
1400
1426
  messageId: MATCH_STYLE,
1401
1427
  data: {
1402
1428
  expectedFilename,
@@ -1866,8 +1892,8 @@ const rule$b = {
1866
1892
  mutation {
1867
1893
  changeSomething(
1868
1894
  type: OLD # This is deprecated, so you'll get an error
1869
- ) {
1870
- ...
1895
+ ) {
1896
+ ...
1871
1897
  }
1872
1898
  }
1873
1899
  `,
@@ -1905,8 +1931,9 @@ const rule$b = {
1905
1931
  const typeInfo = node.typeInfo();
1906
1932
  if (typeInfo && typeInfo.enumValue) {
1907
1933
  if (typeInfo.enumValue.isDeprecated) {
1934
+ const enumValueName = node.value;
1908
1935
  context.report({
1909
- loc: node.loc,
1936
+ loc: getLocation(node.loc, enumValueName),
1910
1937
  messageId: NO_DEPRECATED,
1911
1938
  data: {
1912
1939
  type: 'enum value',
@@ -1921,8 +1948,9 @@ const rule$b = {
1921
1948
  const typeInfo = node.typeInfo();
1922
1949
  if (typeInfo && typeInfo.fieldDef) {
1923
1950
  if (typeInfo.fieldDef.isDeprecated) {
1951
+ const fieldName = node.name.value;
1924
1952
  context.report({
1925
- loc: node.loc,
1953
+ loc: getLocation(node.loc, fieldName),
1926
1954
  messageId: NO_DEPRECATED,
1927
1955
  data: {
1928
1956
  type: 'field',
@@ -3179,11 +3207,7 @@ const rule$m = {
3179
3207
  const RULE_NAME$3 = 'unique-fragment-name';
3180
3208
  const UNIQUE_FRAGMENT_NAME = 'UNIQUE_FRAGMENT_NAME';
3181
3209
  const checkNode = (context, node, ruleName, messageId) => {
3182
- var _a;
3183
- const documentName = (_a = node.name) === null || _a === void 0 ? void 0 : _a.value;
3184
- if (!documentName) {
3185
- return;
3186
- }
3210
+ const documentName = node.name.value;
3187
3211
  const siblings = requireSiblingsOperations(ruleName, context);
3188
3212
  const siblingDocuments = node.kind === Kind.FRAGMENT_DEFINITION ? siblings.getFragment(documentName) : siblings.getOperation(documentName);
3189
3213
  const filepath = context.getFilename();
@@ -3194,7 +3218,6 @@ const checkNode = (context, node, ruleName, messageId) => {
3194
3218
  return isSameName && !isSamePath;
3195
3219
  });
3196
3220
  if (conflictingDocuments.length > 0) {
3197
- const { start, end } = node.name.loc;
3198
3221
  context.report({
3199
3222
  messageId,
3200
3223
  data: {
@@ -3203,16 +3226,7 @@ const checkNode = (context, node, ruleName, messageId) => {
3203
3226
  .map(f => `\t${relative(process.cwd(), getOnDiskFilepath(f.filePath))}`)
3204
3227
  .join('\n'),
3205
3228
  },
3206
- loc: {
3207
- start: {
3208
- line: start.line,
3209
- column: start.column - 1,
3210
- },
3211
- end: {
3212
- line: end.line,
3213
- column: end.column - 1,
3214
- },
3215
- },
3229
+ loc: getLocation(node.name.loc, documentName),
3216
3230
  });
3217
3231
  }
3218
3232
  };
@@ -3329,7 +3343,7 @@ const rule$o = {
3329
3343
  },
3330
3344
  create(context) {
3331
3345
  return {
3332
- OperationDefinition(node) {
3346
+ 'OperationDefinition[name!=undefined]'(node) {
3333
3347
  checkNode(context, node, RULE_NAME$4, UNIQUE_OPERATION_NAME);
3334
3348
  },
3335
3349
  };
@@ -3759,22 +3773,92 @@ function parseForESLint(code, options = {}) {
3759
3773
  }
3760
3774
  }
3761
3775
 
3762
- class GraphQLRuleTester extends require('eslint').RuleTester {
3776
+ class GraphQLRuleTester extends RuleTester {
3763
3777
  constructor(parserOptions = {}) {
3764
- super({
3778
+ const config = {
3765
3779
  parser: require.resolve('@graphql-eslint/eslint-plugin'),
3766
3780
  parserOptions: {
3767
3781
  ...parserOptions,
3768
3782
  skipGraphQLConfig: true,
3769
3783
  },
3770
- });
3784
+ };
3785
+ super(config);
3786
+ this.config = config;
3771
3787
  }
3772
3788
  fromMockFile(path) {
3773
3789
  return readFileSync(resolve(__dirname, `../tests/mocks/${path}`), 'utf-8');
3774
3790
  }
3775
3791
  runGraphQLTests(name, rule, tests) {
3776
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
+ }
3777
3813
  }
3778
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
+ }
3779
3863
 
3780
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.1",
3
+ "version": "2.3.2-alpha-ace9d56.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/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 {};