@graphql-eslint/eslint-plugin 3.0.1 → 3.2.0-alpha-2e742a6.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.
package/index.js CHANGED
@@ -6,7 +6,6 @@ function _interopDefault (ex) { return (ex && (typeof ex === 'object') && 'defau
6
6
 
7
7
  const graphql = require('graphql');
8
8
  const validate = require('graphql/validation/validate');
9
- const _import = require('@graphql-tools/import');
10
9
  const fs = require('fs');
11
10
  const path = require('path');
12
11
  const utils = require('@graphql-tools/utils');
@@ -335,34 +334,75 @@ function getLocation(loc, fieldName = '', offset) {
335
334
  };
336
335
  }
337
336
 
338
- function extractRuleName(stack) {
339
- const match = (stack || '').match(/validation[/\\]rules[/\\](.*?)\.js:/) || [];
340
- return match[1] || null;
341
- }
342
- function validateDoc(sourceNode, context, schema, documentNode, rules, ruleName = null) {
343
- var _a;
344
- if (((_a = documentNode === null || documentNode === void 0 ? void 0 : documentNode.definitions) === null || _a === void 0 ? void 0 : _a.length) > 0) {
345
- try {
346
- const validationErrors = schema ? graphql.validate(schema, documentNode, rules) : validate.validateSDL(documentNode, null, rules);
347
- for (const error of validationErrors) {
348
- const validateRuleName = ruleName || `[${extractRuleName(error.stack)}]`;
349
- context.report({
350
- loc: getLocation({ start: error.locations[0] }),
351
- message: ruleName ? error.message : `${validateRuleName} ${error.message}`,
352
- });
353
- }
354
- }
355
- catch (e) {
337
+ function validateDoc(sourceNode, context, schema, documentNode, rule) {
338
+ if (documentNode.definitions.length === 0) {
339
+ return;
340
+ }
341
+ try {
342
+ const validationErrors = schema
343
+ ? graphql.validate(schema, documentNode, [rule])
344
+ : validate.validateSDL(documentNode, null, [rule]);
345
+ for (const error of validationErrors) {
356
346
  context.report({
357
- node: sourceNode,
358
- message: e.message,
347
+ loc: getLocation({ start: error.locations[0] }),
348
+ message: error.message,
359
349
  });
360
350
  }
361
351
  }
352
+ catch (e) {
353
+ context.report({
354
+ node: sourceNode,
355
+ message: e.message,
356
+ });
357
+ }
362
358
  }
363
- const isGraphQLImportFile = rawSDL => {
364
- const trimmedRawSDL = rawSDL.trimLeft();
365
- return trimmedRawSDL.startsWith('# import') || trimmedRawSDL.startsWith('#import');
359
+ const getFragmentDefsAndFragmentSpreads = (schema, node) => {
360
+ const typeInfo = new graphql.TypeInfo(schema);
361
+ const fragmentDefs = new Set();
362
+ const fragmentSpreads = new Set();
363
+ const visitor = graphql.visitWithTypeInfo(typeInfo, {
364
+ FragmentDefinition(node) {
365
+ fragmentDefs.add(`${node.name.value}:${node.typeCondition.name.value}`);
366
+ },
367
+ FragmentSpread(node) {
368
+ const fieldDef = typeInfo.getFieldDef();
369
+ if (fieldDef) {
370
+ fragmentSpreads.add(`${node.name.value}:${typeInfo.getParentType().name}`);
371
+ }
372
+ },
373
+ });
374
+ graphql.visit(node, visitor);
375
+ return { fragmentDefs, fragmentSpreads };
376
+ };
377
+ const getMissingFragments = (schema, node) => {
378
+ const { fragmentDefs, fragmentSpreads } = getFragmentDefsAndFragmentSpreads(schema, node);
379
+ return [...fragmentSpreads].filter(name => !fragmentDefs.has(name));
380
+ };
381
+ const handleMissingFragments = ({ schema, node, ruleId, context }) => {
382
+ const missingFragments = getMissingFragments(schema, node);
383
+ if (missingFragments.length > 0) {
384
+ const siblings = requireSiblingsOperations(ruleId, context);
385
+ const fragmentsToAdd = [];
386
+ for (const missingFragment of missingFragments) {
387
+ const [fragmentName, fragmentTypeName] = missingFragment.split(':');
388
+ const fragments = siblings
389
+ .getFragment(fragmentName)
390
+ .map(source => source.document)
391
+ .filter(fragment => fragment.typeCondition.name.value === fragmentTypeName);
392
+ if (fragments.length > 1) {
393
+ // eslint-disable-next-line no-console
394
+ console.warn(`You have ${fragments.length} fragments that have same name ${fragmentName} and same type ${fragmentTypeName}. That can provoke unexpected result for "${ruleId}" rule.`);
395
+ }
396
+ fragmentsToAdd.push(fragments[0]);
397
+ }
398
+ if (fragmentsToAdd.length > 0) {
399
+ return {
400
+ kind: graphql.Kind.DOCUMENT,
401
+ definitions: [...node.definitions, ...fragmentsToAdd],
402
+ };
403
+ }
404
+ }
405
+ return node;
366
406
  };
367
407
  const validationToRule = (name, ruleName, docs, getDocumentNode) => {
368
408
  var _a;
@@ -370,11 +410,11 @@ const validationToRule = (name, ruleName, docs, getDocumentNode) => {
370
410
  try {
371
411
  ruleFn = require(`graphql/validation/rules/${ruleName}Rule`)[`${ruleName}Rule`];
372
412
  }
373
- catch (e) {
413
+ catch (_b) {
374
414
  try {
375
415
  ruleFn = require(`graphql/validation/rules/${ruleName}`)[`${ruleName}Rule`];
376
416
  }
377
- catch (e) {
417
+ catch (_c) {
378
418
  ruleFn = require('graphql/validation')[`${ruleName}Rule`];
379
419
  }
380
420
  }
@@ -396,30 +436,25 @@ const validationToRule = (name, ruleName, docs, getDocumentNode) => {
396
436
  Document(node) {
397
437
  if (!ruleFn) {
398
438
  // eslint-disable-next-line no-console
399
- console.warn(`You rule "${name}" depends on a GraphQL validation rule ("${ruleName}") but it's not available in the "graphql-js" version you are using. Skipping...`);
439
+ console.warn(`You rule "${name}" depends on a GraphQL validation rule "${ruleName}" but it's not available in the "graphql-js" version you are using. Skipping...`);
400
440
  return;
401
441
  }
402
442
  const schema = requiresSchema ? requireGraphQLSchemaFromContext(name, context) : null;
403
- let documentNode;
404
- const isRealFile = fs.existsSync(context.getFilename());
405
- if (isRealFile && getDocumentNode) {
406
- documentNode = getDocumentNode(context);
407
- }
408
- validateDoc(node, context, schema, documentNode || node.rawNode(), [ruleFn], ruleName);
443
+ const documentNode = node.rawNode();
444
+ validateDoc(node, context, schema, getDocumentNode
445
+ ? getDocumentNode({
446
+ schema,
447
+ node: documentNode,
448
+ ruleId: name,
449
+ context,
450
+ })
451
+ : documentNode, ruleFn);
409
452
  },
410
453
  };
411
454
  },
412
455
  },
413
456
  };
414
457
  };
415
- const importFiles = (context) => {
416
- const code = context.getSourceCode().text;
417
- if (!isGraphQLImportFile(code)) {
418
- return null;
419
- }
420
- // Import documents because file contains '#import' comments
421
- return _import.processImport(context.getFilename());
422
- };
423
458
  const GRAPHQL_JS_VALIDATIONS = Object.assign({}, validationToRule('executable-definitions', 'ExecutableDefinitions', {
424
459
  category: 'Operations',
425
460
  description: `A GraphQL document is only valid for execution if all definitions are either operation or fragment definitions.`,
@@ -438,14 +473,15 @@ const GRAPHQL_JS_VALIDATIONS = Object.assign({}, validationToRule('executable-de
438
473
  }), validationToRule('known-fragment-names', 'KnownFragmentNames', {
439
474
  category: 'Operations',
440
475
  description: `A GraphQL document is only valid if all \`...Fragment\` fragment spreads refer to fragments defined in the same document.`,
476
+ requiresSiblings: true,
441
477
  examples: [
442
478
  {
443
- title: 'Incorrect (fragment not defined in the document)',
479
+ title: 'Incorrect',
444
480
  code: /* GraphQL */ `
445
481
  query {
446
482
  user {
447
483
  id
448
- ...UserFields
484
+ ...UserFields # fragment not defined in the document
449
485
  }
450
486
  }
451
487
  `,
@@ -467,42 +503,24 @@ const GRAPHQL_JS_VALIDATIONS = Object.assign({}, validationToRule('executable-de
467
503
  `,
468
504
  },
469
505
  {
470
- title: 'Correct (existing import to UserFields fragment)',
506
+ title: 'Correct (`UserFields` fragment located in a separate file)',
471
507
  code: /* GraphQL */ `
472
- #import '../UserFields.gql'
473
-
508
+ # user.gql
474
509
  query {
475
510
  user {
476
511
  id
477
512
  ...UserFields
478
513
  }
479
514
  }
480
- `,
481
- },
482
- {
483
- title: "False positive case\n\nFor extracting documents from code under the hood we use [graphql-tag-pluck](https://graphql-tools.com/docs/graphql-tag-pluck) that [don't support string interpolation](https://stackoverflow.com/questions/62749847/graphql-codegen-dynamic-fields-with-interpolation/62751311#62751311) for this moment.",
484
- code: `
485
- const USER_FIELDS = gql\`
486
- fragment UserFields on User {
487
- id
488
- }
489
- \`
490
-
491
- const GET_USER = /* GraphQL */ \`
492
- # eslint @graphql-eslint/known-fragment-names: 'error'
493
-
494
- query User {
495
- user {
496
- ...UserFields
497
- }
498
- }
499
515
 
500
- # Will give false positive error 'Unknown fragment "UserFields"'
501
- \${USER_FIELDS}
502
- \``,
516
+ # user-fields.gql
517
+ fragment UserFields on User {
518
+ id
519
+ }
520
+ `,
503
521
  },
504
522
  ],
505
- }, importFiles), validationToRule('known-type-names', 'KnownTypeNames', {
523
+ }, handleMissingFragments), validationToRule('known-type-names', 'KnownTypeNames', {
506
524
  category: ['Schema', 'Operations'],
507
525
  description: `A GraphQL document is only valid if referenced types (specifically variable definitions and fragment conditions) are defined by the type schema.`,
508
526
  }), validationToRule('lone-anonymous-operation', 'LoneAnonymousOperation', {
@@ -518,40 +536,47 @@ const GRAPHQL_JS_VALIDATIONS = Object.assign({}, validationToRule('executable-de
518
536
  }), validationToRule('no-undefined-variables', 'NoUndefinedVariables', {
519
537
  category: 'Operations',
520
538
  description: `A GraphQL operation is only valid if all variables encountered, both directly and via fragment spreads, are defined by that operation.`,
521
- }, importFiles), validationToRule('no-unused-fragments', 'NoUnusedFragments', {
539
+ requiresSiblings: true,
540
+ }, handleMissingFragments), validationToRule('no-unused-fragments', 'NoUnusedFragments', {
522
541
  category: 'Operations',
523
542
  description: `A GraphQL document is only valid if all fragment definitions are spread within operations, or spread within other fragments spread within operations.`,
524
543
  requiresSiblings: true,
525
- }, context => {
526
- const siblings = requireSiblingsOperations('no-unused-fragments', context);
527
- const documents = [...siblings.getOperations(), ...siblings.getFragments()]
528
- .filter(({ document }) => isGraphQLImportFile(document.loc.source.body))
529
- .map(({ filePath, document }) => ({
530
- filePath,
531
- code: document.loc.source.body,
532
- }));
533
- const getParentNode = (filePath) => {
534
- for (const { filePath: docFilePath, code } of documents) {
535
- const isFileImported = code
536
- .split('\n')
537
- .filter(isGraphQLImportFile)
538
- .map(line => _import.parseImportLine(line.replace('#', '')))
539
- .some(o => filePath === path.join(path.dirname(docFilePath), o.from));
540
- if (!isFileImported) {
541
- continue;
542
- }
543
- // Import first file that import this file
544
- const document = _import.processImport(docFilePath);
545
- // Import most top file that import this file
546
- return getParentNode(docFilePath) || document;
544
+ }, ({ context, node, schema, ruleId }) => {
545
+ const siblings = requireSiblingsOperations(ruleId, context);
546
+ const filePathForDocumentsMap = [...siblings.getOperations(), ...siblings.getFragments()].reduce((map, { filePath, document }) => {
547
+ var _a;
548
+ (_a = map[filePath]) !== null && _a !== void 0 ? _a : (map[filePath] = []);
549
+ map[filePath].push(document);
550
+ return map;
551
+ }, Object.create(null));
552
+ const getParentNode = (currentFilePath, node) => {
553
+ const { fragmentDefs } = getFragmentDefsAndFragmentSpreads(schema, node);
554
+ if (fragmentDefs.size === 0) {
555
+ return node;
547
556
  }
548
- return null;
557
+ // skip iteration over documents for current filepath
558
+ delete filePathForDocumentsMap[currentFilePath];
559
+ for (const [filePath, documents] of Object.entries(filePathForDocumentsMap)) {
560
+ const missingFragments = getMissingFragments(schema, {
561
+ kind: graphql.Kind.DOCUMENT,
562
+ definitions: documents,
563
+ });
564
+ const isCurrentFileImportFragment = missingFragments.some(fragment => fragmentDefs.has(fragment));
565
+ if (isCurrentFileImportFragment) {
566
+ return getParentNode(filePath, {
567
+ kind: graphql.Kind.DOCUMENT,
568
+ definitions: [...node.definitions, ...documents],
569
+ });
570
+ }
571
+ }
572
+ return node;
549
573
  };
550
- return getParentNode(context.getFilename());
574
+ return getParentNode(context.getFilename(), node);
551
575
  }), validationToRule('no-unused-variables', 'NoUnusedVariables', {
552
576
  category: 'Operations',
553
577
  description: `A GraphQL operation is only valid if all variables defined by an operation are used, either directly or within a spread fragment.`,
554
- }, importFiles), validationToRule('overlapping-fields-can-be-merged', 'OverlappingFieldsCanBeMerged', {
578
+ requiresSiblings: true,
579
+ }, handleMissingFragments), validationToRule('overlapping-fields-can-be-merged', 'OverlappingFieldsCanBeMerged', {
555
580
  category: 'Operations',
556
581
  description: `A selection set is only valid if all fields (including spreading any fragments) either correspond to distinct response names or can be merged without ambiguity.`,
557
582
  }), validationToRule('possible-fragment-spread', 'PossibleFragmentSpreads', {
@@ -1845,7 +1870,7 @@ const HASHTAG_COMMENT = 'HASHTAG_COMMENT';
1845
1870
  const rule$9 = {
1846
1871
  meta: {
1847
1872
  messages: {
1848
- [HASHTAG_COMMENT]: 'Using hashtag (#) for adding GraphQL descriptions is not allowed. Prefer using """ for multiline, or " for a single line description.',
1873
+ [HASHTAG_COMMENT]: `Using hashtag (#) for adding GraphQL descriptions is not allowed. Prefer using """ for multiline, or " for a single line description.`,
1849
1874
  },
1850
1875
  docs: {
1851
1876
  description: 'Requires to use `"""` or `"` for adding a GraphQL description instead of `#`.\nAllows to use hashtag for comments, as long as it\'s not attached to an AST definition.',
@@ -1892,14 +1917,15 @@ const rule$9 = {
1892
1917
  schema: [],
1893
1918
  },
1894
1919
  create(context) {
1920
+ const selector = `${graphql.Kind.DOCUMENT}[definitions.0.kind!=/^(${graphql.Kind.OPERATION_DEFINITION}|${graphql.Kind.FRAGMENT_DEFINITION})$/]`;
1895
1921
  return {
1896
- Document(node) {
1922
+ [selector](node) {
1897
1923
  const rawNode = node.rawNode();
1898
1924
  let token = rawNode.loc.startToken;
1899
1925
  while (token !== null) {
1900
1926
  const { kind, prev, next, value, line, column } = token;
1901
1927
  if (kind === graphql.TokenKind.COMMENT && prev && next) {
1902
- const isEslintComment = value.trimLeft().startsWith('eslint');
1928
+ const isEslintComment = value.trimStart().startsWith('eslint');
1903
1929
  const linesAfter = next.line - line;
1904
1930
  if (!isEslintComment && line !== prev.line && next.kind === graphql.TokenKind.NAME && linesAfter < 2) {
1905
1931
  context.report({
@@ -2106,7 +2132,22 @@ const rule$c = {
2106
2132
  };
2107
2133
 
2108
2134
  const UNREACHABLE_TYPE = 'UNREACHABLE_TYPE';
2109
- const RULE_NAME = 'no-unreachable-types';
2135
+ const RULE_ID = 'no-unreachable-types';
2136
+ const KINDS = [
2137
+ graphql.Kind.DIRECTIVE_DEFINITION,
2138
+ graphql.Kind.OBJECT_TYPE_DEFINITION,
2139
+ graphql.Kind.OBJECT_TYPE_EXTENSION,
2140
+ graphql.Kind.INTERFACE_TYPE_DEFINITION,
2141
+ graphql.Kind.INTERFACE_TYPE_EXTENSION,
2142
+ graphql.Kind.SCALAR_TYPE_DEFINITION,
2143
+ graphql.Kind.SCALAR_TYPE_EXTENSION,
2144
+ graphql.Kind.INPUT_OBJECT_TYPE_DEFINITION,
2145
+ graphql.Kind.INPUT_OBJECT_TYPE_EXTENSION,
2146
+ graphql.Kind.UNION_TYPE_DEFINITION,
2147
+ graphql.Kind.UNION_TYPE_EXTENSION,
2148
+ graphql.Kind.ENUM_TYPE_DEFINITION,
2149
+ graphql.Kind.ENUM_TYPE_EXTENSION,
2150
+ ];
2110
2151
  const rule$d = {
2111
2152
  meta: {
2112
2153
  messages: {
@@ -2115,7 +2156,7 @@ const rule$d = {
2115
2156
  docs: {
2116
2157
  description: `Requires all types to be reachable at some level by root level fields.`,
2117
2158
  category: 'Schema',
2118
- url: `https://github.com/dotansimha/graphql-eslint/blob/master/docs/rules/${RULE_NAME}.md`,
2159
+ url: `https://github.com/dotansimha/graphql-eslint/blob/master/docs/rules/${RULE_ID}.md`,
2119
2160
  requiresSchema: true,
2120
2161
  examples: [
2121
2162
  {
@@ -2147,43 +2188,36 @@ const rule$d = {
2147
2188
  ],
2148
2189
  recommended: true,
2149
2190
  },
2150
- fixable: 'code',
2151
2191
  type: 'suggestion',
2152
2192
  schema: [],
2193
+ hasSuggestions: true,
2153
2194
  },
2154
2195
  create(context) {
2155
- const reachableTypes = requireReachableTypesFromContext(RULE_NAME, context);
2156
- function ensureReachability(node) {
2157
- const typeName = node.name.value;
2158
- if (!reachableTypes.has(typeName)) {
2159
- context.report({
2160
- loc: getLocation(node.name.loc, typeName, { offsetStart: node.kind === graphql.Kind.DIRECTIVE_DEFINITION ? 2 : 1 }),
2161
- messageId: UNREACHABLE_TYPE,
2162
- data: { typeName },
2163
- fix: fixer => fixer.remove(node),
2164
- });
2165
- }
2166
- }
2196
+ const reachableTypes = requireReachableTypesFromContext(RULE_ID, context);
2197
+ const selector = KINDS.join(',');
2167
2198
  return {
2168
- DirectiveDefinition: ensureReachability,
2169
- ObjectTypeDefinition: ensureReachability,
2170
- ObjectTypeExtension: ensureReachability,
2171
- InterfaceTypeDefinition: ensureReachability,
2172
- InterfaceTypeExtension: ensureReachability,
2173
- ScalarTypeDefinition: ensureReachability,
2174
- ScalarTypeExtension: ensureReachability,
2175
- InputObjectTypeDefinition: ensureReachability,
2176
- InputObjectTypeExtension: ensureReachability,
2177
- UnionTypeDefinition: ensureReachability,
2178
- UnionTypeExtension: ensureReachability,
2179
- EnumTypeDefinition: ensureReachability,
2180
- EnumTypeExtension: ensureReachability,
2199
+ [selector](node) {
2200
+ const typeName = node.name.value;
2201
+ if (!reachableTypes.has(typeName)) {
2202
+ context.report({
2203
+ loc: getLocation(node.name.loc, typeName, { offsetStart: node.kind === graphql.Kind.DIRECTIVE_DEFINITION ? 2 : 1 }),
2204
+ messageId: UNREACHABLE_TYPE,
2205
+ data: { typeName },
2206
+ suggest: [
2207
+ {
2208
+ desc: `Remove ${typeName}`,
2209
+ fix: fixer => fixer.remove(node),
2210
+ },
2211
+ ],
2212
+ });
2213
+ }
2214
+ },
2181
2215
  };
2182
2216
  },
2183
2217
  };
2184
2218
 
2185
2219
  const UNUSED_FIELD = 'UNUSED_FIELD';
2186
- const RULE_NAME$1 = 'no-unused-fields';
2220
+ const RULE_ID$1 = 'no-unused-fields';
2187
2221
  const rule$e = {
2188
2222
  meta: {
2189
2223
  messages: {
@@ -2192,7 +2226,7 @@ const rule$e = {
2192
2226
  docs: {
2193
2227
  description: `Requires all fields to be used at some level by siblings operations.`,
2194
2228
  category: 'Schema',
2195
- url: `https://github.com/dotansimha/graphql-eslint/blob/master/docs/rules/${RULE_NAME$1}.md`,
2229
+ url: `https://github.com/dotansimha/graphql-eslint/blob/master/docs/rules/${RULE_ID$1}.md`,
2196
2230
  requiresSiblings: true,
2197
2231
  requiresSchema: true,
2198
2232
  examples: [
@@ -2239,12 +2273,12 @@ const rule$e = {
2239
2273
  },
2240
2274
  ],
2241
2275
  },
2242
- fixable: 'code',
2243
2276
  type: 'suggestion',
2244
2277
  schema: [],
2278
+ hasSuggestions: true,
2245
2279
  },
2246
2280
  create(context) {
2247
- const usedFields = requireUsedFieldsFromContext(RULE_NAME$1, context);
2281
+ const usedFields = requireUsedFieldsFromContext(RULE_ID$1, context);
2248
2282
  return {
2249
2283
  FieldDefinition(node) {
2250
2284
  var _a;
@@ -2258,22 +2292,18 @@ const rule$e = {
2258
2292
  loc: getLocation(node.loc, fieldName),
2259
2293
  messageId: UNUSED_FIELD,
2260
2294
  data: { fieldName },
2261
- fix(fixer) {
2262
- const sourceCode = context.getSourceCode();
2263
- const tokenBefore = sourceCode.getTokenBefore(node);
2264
- const tokenAfter = sourceCode.getTokenAfter(node);
2265
- const isEmptyType = tokenBefore.type === '{' && tokenAfter.type === '}';
2266
- if (isEmptyType) {
2267
- // Remove type
2268
- const { parent } = node;
2269
- const parentBeforeToken = sourceCode.getTokenBefore(parent);
2270
- return parentBeforeToken
2271
- ? fixer.removeRange([parentBeforeToken.range[1], parent.range[1]])
2272
- : fixer.remove(parent);
2273
- }
2274
- // Remove whitespace before token
2275
- return fixer.removeRange([tokenBefore.range[1], node.range[1]]);
2276
- },
2295
+ suggest: [
2296
+ {
2297
+ desc: `Remove "${fieldName}" field`,
2298
+ fix(fixer) {
2299
+ const sourceCode = context.getSourceCode();
2300
+ const tokenBefore = sourceCode.getTokenBefore(node);
2301
+ const tokenAfter = sourceCode.getTokenAfter(node);
2302
+ const isEmptyType = tokenBefore.type === '{' && tokenAfter.type === '}';
2303
+ return isEmptyType ? fixer.remove(node.parent) : fixer.remove(node);
2304
+ },
2305
+ },
2306
+ ],
2277
2307
  });
2278
2308
  },
2279
2309
  };
@@ -2636,14 +2666,14 @@ const rule$h = {
2636
2666
  },
2637
2667
  };
2638
2668
 
2639
- const RULE_NAME$2 = 'require-field-of-type-query-in-mutation-result';
2669
+ const RULE_NAME = 'require-field-of-type-query-in-mutation-result';
2640
2670
  const rule$i = {
2641
2671
  meta: {
2642
2672
  type: 'suggestion',
2643
2673
  docs: {
2644
2674
  category: 'Schema',
2645
2675
  description: 'Allow the client in one round-trip not only to call mutation but also to get a wagon of data to update their application.\n> Currently, no errors are reported for result type `union`, `interface` and `scalar`.',
2646
- url: `https://github.com/dotansimha/graphql-eslint/blob/master/docs/rules/${RULE_NAME$2}.md`,
2676
+ url: `https://github.com/dotansimha/graphql-eslint/blob/master/docs/rules/${RULE_NAME}.md`,
2647
2677
  requiresSchema: true,
2648
2678
  examples: [
2649
2679
  {
@@ -2678,7 +2708,7 @@ const rule$i = {
2678
2708
  schema: [],
2679
2709
  },
2680
2710
  create(context) {
2681
- const schema = requireGraphQLSchemaFromContext(RULE_NAME$2, context);
2711
+ const schema = requireGraphQLSchemaFromContext(RULE_NAME, context);
2682
2712
  const mutationType = schema.getMutationType();
2683
2713
  const queryType = schema.getQueryType();
2684
2714
  if (!mutationType || !queryType) {
@@ -3221,7 +3251,7 @@ const rule$l = {
3221
3251
  },
3222
3252
  };
3223
3253
 
3224
- const RULE_NAME$3 = 'unique-fragment-name';
3254
+ const RULE_NAME$1 = 'unique-fragment-name';
3225
3255
  const UNIQUE_FRAGMENT_NAME = 'UNIQUE_FRAGMENT_NAME';
3226
3256
  const checkNode = (context, node, ruleName, messageId) => {
3227
3257
  const documentName = node.name.value;
@@ -3253,7 +3283,7 @@ const rule$m = {
3253
3283
  docs: {
3254
3284
  category: 'Operations',
3255
3285
  description: `Enforce unique fragment names across your project.`,
3256
- url: `https://github.com/dotansimha/graphql-eslint/blob/master/docs/rules/${RULE_NAME$3}.md`,
3286
+ url: `https://github.com/dotansimha/graphql-eslint/blob/master/docs/rules/${RULE_NAME$1}.md`,
3257
3287
  requiresSiblings: true,
3258
3288
  examples: [
3259
3289
  {
@@ -3298,13 +3328,13 @@ const rule$m = {
3298
3328
  create(context) {
3299
3329
  return {
3300
3330
  FragmentDefinition(node) {
3301
- checkNode(context, node, RULE_NAME$3, UNIQUE_FRAGMENT_NAME);
3331
+ checkNode(context, node, RULE_NAME$1, UNIQUE_FRAGMENT_NAME);
3302
3332
  },
3303
3333
  };
3304
3334
  },
3305
3335
  };
3306
3336
 
3307
- const RULE_NAME$4 = 'unique-operation-name';
3337
+ const RULE_NAME$2 = 'unique-operation-name';
3308
3338
  const UNIQUE_OPERATION_NAME = 'UNIQUE_OPERATION_NAME';
3309
3339
  const rule$n = {
3310
3340
  meta: {
@@ -3312,7 +3342,7 @@ const rule$n = {
3312
3342
  docs: {
3313
3343
  category: 'Operations',
3314
3344
  description: `Enforce unique operation names across your project.`,
3315
- url: `https://github.com/dotansimha/graphql-eslint/blob/master/docs/rules/${RULE_NAME$4}.md`,
3345
+ url: `https://github.com/dotansimha/graphql-eslint/blob/master/docs/rules/${RULE_NAME$2}.md`,
3316
3346
  requiresSiblings: true,
3317
3347
  examples: [
3318
3348
  {
@@ -3361,7 +3391,7 @@ const rule$n = {
3361
3391
  create(context) {
3362
3392
  return {
3363
3393
  'OperationDefinition[name!=undefined]'(node) {
3364
- checkNode(context, node, RULE_NAME$4, UNIQUE_OPERATION_NAME);
3394
+ checkNode(context, node, RULE_NAME$2, UNIQUE_OPERATION_NAME);
3365
3395
  },
3366
3396
  };
3367
3397
  },