@graphql-eslint/eslint-plugin 3.2.0-alpha-2e742a6.0 → 3.2.0-alpha-4ca7218.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 (4) hide show
  1. package/index.js +56 -45
  2. package/index.mjs +56 -45
  3. package/package.json +10 -3
  4. package/types.d.ts +2 -2
package/index.js CHANGED
@@ -334,7 +334,7 @@ function getLocation(loc, fieldName = '', offset) {
334
334
  };
335
335
  }
336
336
 
337
- function validateDoc(sourceNode, context, schema, documentNode, rule) {
337
+ function validateDocument(sourceNode, context, schema, documentNode, rule) {
338
338
  if (documentNode.definitions.length === 0) {
339
339
  return;
340
340
  }
@@ -365,9 +365,9 @@ const getFragmentDefsAndFragmentSpreads = (schema, node) => {
365
365
  fragmentDefs.add(`${node.name.value}:${node.typeCondition.name.value}`);
366
366
  },
367
367
  FragmentSpread(node) {
368
- const fieldDef = typeInfo.getFieldDef();
369
- if (fieldDef) {
370
- fragmentSpreads.add(`${node.name.value}:${typeInfo.getParentType().name}`);
368
+ const parentType = typeInfo.getParentType();
369
+ if (parentType) {
370
+ fragmentSpreads.add(`${node.name.value}:${parentType.name}`);
371
371
  }
372
372
  },
373
373
  });
@@ -378,56 +378,57 @@ const getMissingFragments = (schema, node) => {
378
378
  const { fragmentDefs, fragmentSpreads } = getFragmentDefsAndFragmentSpreads(schema, node);
379
379
  return [...fragmentSpreads].filter(name => !fragmentDefs.has(name));
380
380
  };
381
- const handleMissingFragments = ({ schema, node, ruleId, context }) => {
381
+ const handleMissingFragments = ({ ruleId, context, schema, node }) => {
382
382
  const missingFragments = getMissingFragments(schema, node);
383
383
  if (missingFragments.length > 0) {
384
384
  const siblings = requireSiblingsOperations(ruleId, context);
385
385
  const fragmentsToAdd = [];
386
386
  for (const missingFragment of missingFragments) {
387
387
  const [fragmentName, fragmentTypeName] = missingFragment.split(':');
388
- const fragments = siblings
388
+ const [foundFragment] = siblings
389
389
  .getFragment(fragmentName)
390
390
  .map(source => source.document)
391
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.`);
392
+ if (foundFragment) {
393
+ fragmentsToAdd.push(foundFragment);
395
394
  }
396
- fragmentsToAdd.push(fragments[0]);
397
395
  }
398
396
  if (fragmentsToAdd.length > 0) {
399
- return {
400
- kind: graphql.Kind.DOCUMENT,
401
- definitions: [...node.definitions, ...fragmentsToAdd],
402
- };
397
+ // recall fn to make sure to add fragments inside fragments
398
+ return handleMissingFragments({
399
+ ruleId,
400
+ context,
401
+ schema,
402
+ node: {
403
+ kind: graphql.Kind.DOCUMENT,
404
+ definitions: [...node.definitions, ...fragmentsToAdd],
405
+ },
406
+ });
403
407
  }
404
408
  }
405
409
  return node;
406
410
  };
407
- const validationToRule = (name, ruleName, docs, getDocumentNode) => {
408
- var _a;
411
+ const validationToRule = (ruleId, ruleName, docs, getDocumentNode) => {
409
412
  let ruleFn = null;
410
413
  try {
411
414
  ruleFn = require(`graphql/validation/rules/${ruleName}Rule`)[`${ruleName}Rule`];
412
415
  }
413
- catch (_b) {
416
+ catch (_a) {
414
417
  try {
415
418
  ruleFn = require(`graphql/validation/rules/${ruleName}`)[`${ruleName}Rule`];
416
419
  }
417
- catch (_c) {
420
+ catch (_b) {
418
421
  ruleFn = require('graphql/validation')[`${ruleName}Rule`];
419
422
  }
420
423
  }
421
- const requiresSchema = (_a = docs.requiresSchema) !== null && _a !== void 0 ? _a : true;
422
424
  return {
423
- [name]: {
425
+ [ruleId]: {
424
426
  meta: {
425
427
  docs: {
426
428
  recommended: true,
427
429
  ...docs,
428
430
  graphQLJSRuleName: ruleName,
429
- requiresSchema,
430
- url: `https://github.com/dotansimha/graphql-eslint/blob/master/docs/rules/${name}.md`,
431
+ url: `https://github.com/dotansimha/graphql-eslint/blob/master/docs/rules/${ruleId}.md`,
431
432
  description: `${docs.description}\n\n> This rule is a wrapper around a \`graphql-js\` validation function. [You can find its source code here](https://github.com/graphql/graphql-js/blob/main/src/validation/rules/${ruleName}Rule.ts).`,
432
433
  },
433
434
  },
@@ -436,19 +437,14 @@ const validationToRule = (name, ruleName, docs, getDocumentNode) => {
436
437
  Document(node) {
437
438
  if (!ruleFn) {
438
439
  // eslint-disable-next-line no-console
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...`);
440
+ console.warn(`You rule "${ruleId}" depends on a GraphQL validation rule "${ruleName}" but it's not available in the "graphql-js" version you are using. Skipping...`);
440
441
  return;
441
442
  }
442
- const schema = requiresSchema ? requireGraphQLSchemaFromContext(name, context) : null;
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);
443
+ const schema = docs.requiresSchema ? requireGraphQLSchemaFromContext(ruleId, context) : null;
444
+ const documentNode = getDocumentNode
445
+ ? getDocumentNode({ ruleId, context, schema, node: node.rawNode() })
446
+ : node.rawNode();
447
+ validateDocument(node, context, schema, documentNode, ruleFn);
452
448
  },
453
449
  };
454
450
  },
@@ -458,21 +454,27 @@ const validationToRule = (name, ruleName, docs, getDocumentNode) => {
458
454
  const GRAPHQL_JS_VALIDATIONS = Object.assign({}, validationToRule('executable-definitions', 'ExecutableDefinitions', {
459
455
  category: 'Operations',
460
456
  description: `A GraphQL document is only valid for execution if all definitions are either operation or fragment definitions.`,
457
+ requiresSchema: true,
461
458
  }), validationToRule('fields-on-correct-type', 'FieldsOnCorrectType', {
462
459
  category: 'Operations',
463
460
  description: 'A GraphQL document is only valid if all fields selected are defined by the parent type, or are an allowed meta field such as `__typename`.',
461
+ requiresSchema: true,
464
462
  }), validationToRule('fragments-on-composite-type', 'FragmentsOnCompositeTypes', {
465
463
  category: 'Operations',
466
464
  description: `Fragments use a type condition to determine if they apply, since fragments can only be spread into a composite type (object, interface, or union), the type condition must also be a composite type.`,
465
+ requiresSchema: true,
467
466
  }), validationToRule('known-argument-names', 'KnownArgumentNames', {
468
467
  category: ['Schema', 'Operations'],
469
468
  description: `A GraphQL field is only valid if all supplied arguments are defined by that field.`,
469
+ requiresSchema: true,
470
470
  }), validationToRule('known-directives', 'KnownDirectives', {
471
471
  category: ['Schema', 'Operations'],
472
472
  description: `A GraphQL document is only valid if all \`@directives\` are known by the schema and legally positioned.`,
473
+ requiresSchema: true,
473
474
  }), validationToRule('known-fragment-names', 'KnownFragmentNames', {
474
475
  category: 'Operations',
475
476
  description: `A GraphQL document is only valid if all \`...Fragment\` fragment spreads refer to fragments defined in the same document.`,
477
+ requiresSchema: true,
476
478
  requiresSiblings: true,
477
479
  examples: [
478
480
  {
@@ -523,27 +525,31 @@ const GRAPHQL_JS_VALIDATIONS = Object.assign({}, validationToRule('executable-de
523
525
  }, handleMissingFragments), validationToRule('known-type-names', 'KnownTypeNames', {
524
526
  category: ['Schema', 'Operations'],
525
527
  description: `A GraphQL document is only valid if referenced types (specifically variable definitions and fragment conditions) are defined by the type schema.`,
528
+ requiresSchema: true,
526
529
  }), validationToRule('lone-anonymous-operation', 'LoneAnonymousOperation', {
527
530
  category: 'Operations',
528
531
  description: `A GraphQL document is only valid if when it contains an anonymous operation (the query short-hand) that it contains only that one operation definition.`,
532
+ requiresSchema: true,
529
533
  }), validationToRule('lone-schema-definition', 'LoneSchemaDefinition', {
530
534
  category: 'Schema',
531
535
  description: `A GraphQL document is only valid if it contains only one schema definition.`,
532
- requiresSchema: false,
533
536
  }), validationToRule('no-fragment-cycles', 'NoFragmentCycles', {
534
537
  category: 'Operations',
535
538
  description: `A GraphQL fragment is only valid when it does not have cycles in fragments usage.`,
539
+ requiresSchema: true,
536
540
  }), validationToRule('no-undefined-variables', 'NoUndefinedVariables', {
537
541
  category: 'Operations',
538
542
  description: `A GraphQL operation is only valid if all variables encountered, both directly and via fragment spreads, are defined by that operation.`,
543
+ requiresSchema: true,
539
544
  requiresSiblings: true,
540
545
  }, handleMissingFragments), validationToRule('no-unused-fragments', 'NoUnusedFragments', {
541
546
  category: 'Operations',
542
547
  description: `A GraphQL document is only valid if all fragment definitions are spread within operations, or spread within other fragments spread within operations.`,
548
+ requiresSchema: true,
543
549
  requiresSiblings: true,
544
- }, ({ context, node, schema, ruleId }) => {
550
+ }, ({ ruleId, context, schema, node }) => {
545
551
  const siblings = requireSiblingsOperations(ruleId, context);
546
- const filePathForDocumentsMap = [...siblings.getOperations(), ...siblings.getFragments()].reduce((map, { filePath, document }) => {
552
+ const FilePathToDocumentsMap = [...siblings.getOperations(), ...siblings.getFragments()].reduce((map, { filePath, document }) => {
547
553
  var _a;
548
554
  (_a = map[filePath]) !== null && _a !== void 0 ? _a : (map[filePath] = []);
549
555
  map[filePath].push(document);
@@ -555,8 +561,8 @@ const GRAPHQL_JS_VALIDATIONS = Object.assign({}, validationToRule('executable-de
555
561
  return node;
556
562
  }
557
563
  // skip iteration over documents for current filepath
558
- delete filePathForDocumentsMap[currentFilePath];
559
- for (const [filePath, documents] of Object.entries(filePathForDocumentsMap)) {
564
+ delete FilePathToDocumentsMap[currentFilePath];
565
+ for (const [filePath, documents] of Object.entries(FilePathToDocumentsMap)) {
560
566
  const missingFragments = getMissingFragments(schema, {
561
567
  kind: graphql.Kind.DOCUMENT,
562
568
  definitions: documents,
@@ -575,70 +581,75 @@ const GRAPHQL_JS_VALIDATIONS = Object.assign({}, validationToRule('executable-de
575
581
  }), validationToRule('no-unused-variables', 'NoUnusedVariables', {
576
582
  category: 'Operations',
577
583
  description: `A GraphQL operation is only valid if all variables defined by an operation are used, either directly or within a spread fragment.`,
584
+ requiresSchema: true,
578
585
  requiresSiblings: true,
579
586
  }, handleMissingFragments), validationToRule('overlapping-fields-can-be-merged', 'OverlappingFieldsCanBeMerged', {
580
587
  category: 'Operations',
581
588
  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.`,
589
+ requiresSchema: true,
582
590
  }), validationToRule('possible-fragment-spread', 'PossibleFragmentSpreads', {
583
591
  category: 'Operations',
584
592
  description: `A fragment spread is only valid if the type condition could ever possibly be true: if there is a non-empty intersection of the possible parent types, and possible types which pass the type condition.`,
593
+ requiresSchema: true,
585
594
  }), validationToRule('possible-type-extension', 'PossibleTypeExtensions', {
586
595
  category: 'Schema',
587
596
  description: `A type extension is only valid if the type is defined and has the same kind.`,
588
- requiresSchema: false,
589
597
  recommended: false, // TODO: enable after https://github.com/dotansimha/graphql-eslint/issues/787 will be fixed
590
598
  }), validationToRule('provided-required-arguments', 'ProvidedRequiredArguments', {
591
599
  category: ['Schema', 'Operations'],
592
600
  description: `A field or directive is only valid if all required (non-null without a default value) field arguments have been provided.`,
601
+ requiresSchema: true,
593
602
  }), validationToRule('scalar-leafs', 'ScalarLeafs', {
594
603
  category: 'Operations',
595
604
  description: `A GraphQL document is valid only if all leaf fields (fields without sub selections) are of scalar or enum types.`,
605
+ requiresSchema: true,
596
606
  }), validationToRule('one-field-subscriptions', 'SingleFieldSubscriptions', {
597
607
  category: 'Operations',
598
608
  description: `A GraphQL subscription is valid only if it contains a single root field.`,
609
+ requiresSchema: true,
599
610
  }), validationToRule('unique-argument-names', 'UniqueArgumentNames', {
600
611
  category: 'Operations',
601
612
  description: `A GraphQL field or directive is only valid if all supplied arguments are uniquely named.`,
613
+ requiresSchema: true,
602
614
  }), validationToRule('unique-directive-names', 'UniqueDirectiveNames', {
603
615
  category: 'Schema',
604
616
  description: `A GraphQL document is only valid if all defined directives have unique names.`,
605
- requiresSchema: false,
606
617
  }), validationToRule('unique-directive-names-per-location', 'UniqueDirectivesPerLocation', {
607
618
  category: ['Schema', 'Operations'],
608
619
  description: `A GraphQL document is only valid if all non-repeatable directives at a given location are uniquely named.`,
620
+ requiresSchema: true,
609
621
  }), validationToRule('unique-enum-value-names', 'UniqueEnumValueNames', {
610
622
  category: 'Schema',
611
623
  description: `A GraphQL enum type is only valid if all its values are uniquely named.`,
612
- requiresSchema: false,
613
624
  recommended: false,
614
625
  }), validationToRule('unique-field-definition-names', 'UniqueFieldDefinitionNames', {
615
626
  category: 'Schema',
616
627
  description: `A GraphQL complex type is only valid if all its fields are uniquely named.`,
617
- requiresSchema: false,
618
628
  }), validationToRule('unique-input-field-names', 'UniqueInputFieldNames', {
619
629
  category: 'Operations',
620
630
  description: `A GraphQL input object value is only valid if all supplied fields are uniquely named.`,
621
- requiresSchema: false,
622
631
  }), validationToRule('unique-operation-types', 'UniqueOperationTypes', {
623
632
  category: 'Schema',
624
633
  description: `A GraphQL document is only valid if it has only one type per operation.`,
625
- requiresSchema: false,
626
634
  }), validationToRule('unique-type-names', 'UniqueTypeNames', {
627
635
  category: 'Schema',
628
636
  description: `A GraphQL document is only valid if all defined types have unique names.`,
629
- requiresSchema: false,
630
637
  }), validationToRule('unique-variable-names', 'UniqueVariableNames', {
631
638
  category: 'Operations',
632
639
  description: `A GraphQL operation is only valid if all its variables are uniquely named.`,
640
+ requiresSchema: true,
633
641
  }), validationToRule('value-literals-of-correct-type', 'ValuesOfCorrectType', {
634
642
  category: 'Operations',
635
643
  description: `A GraphQL document is only valid if all value literals are of the type expected at their position.`,
644
+ requiresSchema: true,
636
645
  }), validationToRule('variables-are-input-types', 'VariablesAreInputTypes', {
637
646
  category: 'Operations',
638
647
  description: `A GraphQL operation is only valid if all the variables it defines are of input types (scalar, enum, or input object).`,
648
+ requiresSchema: true,
639
649
  }), validationToRule('variables-in-allowed-position', 'VariablesInAllowedPosition', {
640
650
  category: 'Operations',
641
651
  description: `Variables passed to field arguments conform to type.`,
652
+ requiresSchema: true,
642
653
  }));
643
654
 
644
655
  const ALPHABETIZE = 'ALPHABETIZE';
package/index.mjs CHANGED
@@ -328,7 +328,7 @@ function getLocation(loc, fieldName = '', offset) {
328
328
  };
329
329
  }
330
330
 
331
- function validateDoc(sourceNode, context, schema, documentNode, rule) {
331
+ function validateDocument(sourceNode, context, schema, documentNode, rule) {
332
332
  if (documentNode.definitions.length === 0) {
333
333
  return;
334
334
  }
@@ -359,9 +359,9 @@ const getFragmentDefsAndFragmentSpreads = (schema, node) => {
359
359
  fragmentDefs.add(`${node.name.value}:${node.typeCondition.name.value}`);
360
360
  },
361
361
  FragmentSpread(node) {
362
- const fieldDef = typeInfo.getFieldDef();
363
- if (fieldDef) {
364
- fragmentSpreads.add(`${node.name.value}:${typeInfo.getParentType().name}`);
362
+ const parentType = typeInfo.getParentType();
363
+ if (parentType) {
364
+ fragmentSpreads.add(`${node.name.value}:${parentType.name}`);
365
365
  }
366
366
  },
367
367
  });
@@ -372,56 +372,57 @@ const getMissingFragments = (schema, node) => {
372
372
  const { fragmentDefs, fragmentSpreads } = getFragmentDefsAndFragmentSpreads(schema, node);
373
373
  return [...fragmentSpreads].filter(name => !fragmentDefs.has(name));
374
374
  };
375
- const handleMissingFragments = ({ schema, node, ruleId, context }) => {
375
+ const handleMissingFragments = ({ ruleId, context, schema, node }) => {
376
376
  const missingFragments = getMissingFragments(schema, node);
377
377
  if (missingFragments.length > 0) {
378
378
  const siblings = requireSiblingsOperations(ruleId, context);
379
379
  const fragmentsToAdd = [];
380
380
  for (const missingFragment of missingFragments) {
381
381
  const [fragmentName, fragmentTypeName] = missingFragment.split(':');
382
- const fragments = siblings
382
+ const [foundFragment] = siblings
383
383
  .getFragment(fragmentName)
384
384
  .map(source => source.document)
385
385
  .filter(fragment => fragment.typeCondition.name.value === fragmentTypeName);
386
- if (fragments.length > 1) {
387
- // eslint-disable-next-line no-console
388
- console.warn(`You have ${fragments.length} fragments that have same name ${fragmentName} and same type ${fragmentTypeName}. That can provoke unexpected result for "${ruleId}" rule.`);
386
+ if (foundFragment) {
387
+ fragmentsToAdd.push(foundFragment);
389
388
  }
390
- fragmentsToAdd.push(fragments[0]);
391
389
  }
392
390
  if (fragmentsToAdd.length > 0) {
393
- return {
394
- kind: Kind.DOCUMENT,
395
- definitions: [...node.definitions, ...fragmentsToAdd],
396
- };
391
+ // recall fn to make sure to add fragments inside fragments
392
+ return handleMissingFragments({
393
+ ruleId,
394
+ context,
395
+ schema,
396
+ node: {
397
+ kind: Kind.DOCUMENT,
398
+ definitions: [...node.definitions, ...fragmentsToAdd],
399
+ },
400
+ });
397
401
  }
398
402
  }
399
403
  return node;
400
404
  };
401
- const validationToRule = (name, ruleName, docs, getDocumentNode) => {
402
- var _a;
405
+ const validationToRule = (ruleId, ruleName, docs, getDocumentNode) => {
403
406
  let ruleFn = null;
404
407
  try {
405
408
  ruleFn = require(`graphql/validation/rules/${ruleName}Rule`)[`${ruleName}Rule`];
406
409
  }
407
- catch (_b) {
410
+ catch (_a) {
408
411
  try {
409
412
  ruleFn = require(`graphql/validation/rules/${ruleName}`)[`${ruleName}Rule`];
410
413
  }
411
- catch (_c) {
414
+ catch (_b) {
412
415
  ruleFn = require('graphql/validation')[`${ruleName}Rule`];
413
416
  }
414
417
  }
415
- const requiresSchema = (_a = docs.requiresSchema) !== null && _a !== void 0 ? _a : true;
416
418
  return {
417
- [name]: {
419
+ [ruleId]: {
418
420
  meta: {
419
421
  docs: {
420
422
  recommended: true,
421
423
  ...docs,
422
424
  graphQLJSRuleName: ruleName,
423
- requiresSchema,
424
- url: `https://github.com/dotansimha/graphql-eslint/blob/master/docs/rules/${name}.md`,
425
+ url: `https://github.com/dotansimha/graphql-eslint/blob/master/docs/rules/${ruleId}.md`,
425
426
  description: `${docs.description}\n\n> This rule is a wrapper around a \`graphql-js\` validation function. [You can find its source code here](https://github.com/graphql/graphql-js/blob/main/src/validation/rules/${ruleName}Rule.ts).`,
426
427
  },
427
428
  },
@@ -430,19 +431,14 @@ const validationToRule = (name, ruleName, docs, getDocumentNode) => {
430
431
  Document(node) {
431
432
  if (!ruleFn) {
432
433
  // eslint-disable-next-line no-console
433
- 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...`);
434
+ console.warn(`You rule "${ruleId}" depends on a GraphQL validation rule "${ruleName}" but it's not available in the "graphql-js" version you are using. Skipping...`);
434
435
  return;
435
436
  }
436
- const schema = requiresSchema ? requireGraphQLSchemaFromContext(name, context) : null;
437
- const documentNode = node.rawNode();
438
- validateDoc(node, context, schema, getDocumentNode
439
- ? getDocumentNode({
440
- schema,
441
- node: documentNode,
442
- ruleId: name,
443
- context,
444
- })
445
- : documentNode, ruleFn);
437
+ const schema = docs.requiresSchema ? requireGraphQLSchemaFromContext(ruleId, context) : null;
438
+ const documentNode = getDocumentNode
439
+ ? getDocumentNode({ ruleId, context, schema, node: node.rawNode() })
440
+ : node.rawNode();
441
+ validateDocument(node, context, schema, documentNode, ruleFn);
446
442
  },
447
443
  };
448
444
  },
@@ -452,21 +448,27 @@ const validationToRule = (name, ruleName, docs, getDocumentNode) => {
452
448
  const GRAPHQL_JS_VALIDATIONS = Object.assign({}, validationToRule('executable-definitions', 'ExecutableDefinitions', {
453
449
  category: 'Operations',
454
450
  description: `A GraphQL document is only valid for execution if all definitions are either operation or fragment definitions.`,
451
+ requiresSchema: true,
455
452
  }), validationToRule('fields-on-correct-type', 'FieldsOnCorrectType', {
456
453
  category: 'Operations',
457
454
  description: 'A GraphQL document is only valid if all fields selected are defined by the parent type, or are an allowed meta field such as `__typename`.',
455
+ requiresSchema: true,
458
456
  }), validationToRule('fragments-on-composite-type', 'FragmentsOnCompositeTypes', {
459
457
  category: 'Operations',
460
458
  description: `Fragments use a type condition to determine if they apply, since fragments can only be spread into a composite type (object, interface, or union), the type condition must also be a composite type.`,
459
+ requiresSchema: true,
461
460
  }), validationToRule('known-argument-names', 'KnownArgumentNames', {
462
461
  category: ['Schema', 'Operations'],
463
462
  description: `A GraphQL field is only valid if all supplied arguments are defined by that field.`,
463
+ requiresSchema: true,
464
464
  }), validationToRule('known-directives', 'KnownDirectives', {
465
465
  category: ['Schema', 'Operations'],
466
466
  description: `A GraphQL document is only valid if all \`@directives\` are known by the schema and legally positioned.`,
467
+ requiresSchema: true,
467
468
  }), validationToRule('known-fragment-names', 'KnownFragmentNames', {
468
469
  category: 'Operations',
469
470
  description: `A GraphQL document is only valid if all \`...Fragment\` fragment spreads refer to fragments defined in the same document.`,
471
+ requiresSchema: true,
470
472
  requiresSiblings: true,
471
473
  examples: [
472
474
  {
@@ -517,27 +519,31 @@ const GRAPHQL_JS_VALIDATIONS = Object.assign({}, validationToRule('executable-de
517
519
  }, handleMissingFragments), validationToRule('known-type-names', 'KnownTypeNames', {
518
520
  category: ['Schema', 'Operations'],
519
521
  description: `A GraphQL document is only valid if referenced types (specifically variable definitions and fragment conditions) are defined by the type schema.`,
522
+ requiresSchema: true,
520
523
  }), validationToRule('lone-anonymous-operation', 'LoneAnonymousOperation', {
521
524
  category: 'Operations',
522
525
  description: `A GraphQL document is only valid if when it contains an anonymous operation (the query short-hand) that it contains only that one operation definition.`,
526
+ requiresSchema: true,
523
527
  }), validationToRule('lone-schema-definition', 'LoneSchemaDefinition', {
524
528
  category: 'Schema',
525
529
  description: `A GraphQL document is only valid if it contains only one schema definition.`,
526
- requiresSchema: false,
527
530
  }), validationToRule('no-fragment-cycles', 'NoFragmentCycles', {
528
531
  category: 'Operations',
529
532
  description: `A GraphQL fragment is only valid when it does not have cycles in fragments usage.`,
533
+ requiresSchema: true,
530
534
  }), validationToRule('no-undefined-variables', 'NoUndefinedVariables', {
531
535
  category: 'Operations',
532
536
  description: `A GraphQL operation is only valid if all variables encountered, both directly and via fragment spreads, are defined by that operation.`,
537
+ requiresSchema: true,
533
538
  requiresSiblings: true,
534
539
  }, handleMissingFragments), validationToRule('no-unused-fragments', 'NoUnusedFragments', {
535
540
  category: 'Operations',
536
541
  description: `A GraphQL document is only valid if all fragment definitions are spread within operations, or spread within other fragments spread within operations.`,
542
+ requiresSchema: true,
537
543
  requiresSiblings: true,
538
- }, ({ context, node, schema, ruleId }) => {
544
+ }, ({ ruleId, context, schema, node }) => {
539
545
  const siblings = requireSiblingsOperations(ruleId, context);
540
- const filePathForDocumentsMap = [...siblings.getOperations(), ...siblings.getFragments()].reduce((map, { filePath, document }) => {
546
+ const FilePathToDocumentsMap = [...siblings.getOperations(), ...siblings.getFragments()].reduce((map, { filePath, document }) => {
541
547
  var _a;
542
548
  (_a = map[filePath]) !== null && _a !== void 0 ? _a : (map[filePath] = []);
543
549
  map[filePath].push(document);
@@ -549,8 +555,8 @@ const GRAPHQL_JS_VALIDATIONS = Object.assign({}, validationToRule('executable-de
549
555
  return node;
550
556
  }
551
557
  // skip iteration over documents for current filepath
552
- delete filePathForDocumentsMap[currentFilePath];
553
- for (const [filePath, documents] of Object.entries(filePathForDocumentsMap)) {
558
+ delete FilePathToDocumentsMap[currentFilePath];
559
+ for (const [filePath, documents] of Object.entries(FilePathToDocumentsMap)) {
554
560
  const missingFragments = getMissingFragments(schema, {
555
561
  kind: Kind.DOCUMENT,
556
562
  definitions: documents,
@@ -569,70 +575,75 @@ const GRAPHQL_JS_VALIDATIONS = Object.assign({}, validationToRule('executable-de
569
575
  }), validationToRule('no-unused-variables', 'NoUnusedVariables', {
570
576
  category: 'Operations',
571
577
  description: `A GraphQL operation is only valid if all variables defined by an operation are used, either directly or within a spread fragment.`,
578
+ requiresSchema: true,
572
579
  requiresSiblings: true,
573
580
  }, handleMissingFragments), validationToRule('overlapping-fields-can-be-merged', 'OverlappingFieldsCanBeMerged', {
574
581
  category: 'Operations',
575
582
  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.`,
583
+ requiresSchema: true,
576
584
  }), validationToRule('possible-fragment-spread', 'PossibleFragmentSpreads', {
577
585
  category: 'Operations',
578
586
  description: `A fragment spread is only valid if the type condition could ever possibly be true: if there is a non-empty intersection of the possible parent types, and possible types which pass the type condition.`,
587
+ requiresSchema: true,
579
588
  }), validationToRule('possible-type-extension', 'PossibleTypeExtensions', {
580
589
  category: 'Schema',
581
590
  description: `A type extension is only valid if the type is defined and has the same kind.`,
582
- requiresSchema: false,
583
591
  recommended: false, // TODO: enable after https://github.com/dotansimha/graphql-eslint/issues/787 will be fixed
584
592
  }), validationToRule('provided-required-arguments', 'ProvidedRequiredArguments', {
585
593
  category: ['Schema', 'Operations'],
586
594
  description: `A field or directive is only valid if all required (non-null without a default value) field arguments have been provided.`,
595
+ requiresSchema: true,
587
596
  }), validationToRule('scalar-leafs', 'ScalarLeafs', {
588
597
  category: 'Operations',
589
598
  description: `A GraphQL document is valid only if all leaf fields (fields without sub selections) are of scalar or enum types.`,
599
+ requiresSchema: true,
590
600
  }), validationToRule('one-field-subscriptions', 'SingleFieldSubscriptions', {
591
601
  category: 'Operations',
592
602
  description: `A GraphQL subscription is valid only if it contains a single root field.`,
603
+ requiresSchema: true,
593
604
  }), validationToRule('unique-argument-names', 'UniqueArgumentNames', {
594
605
  category: 'Operations',
595
606
  description: `A GraphQL field or directive is only valid if all supplied arguments are uniquely named.`,
607
+ requiresSchema: true,
596
608
  }), validationToRule('unique-directive-names', 'UniqueDirectiveNames', {
597
609
  category: 'Schema',
598
610
  description: `A GraphQL document is only valid if all defined directives have unique names.`,
599
- requiresSchema: false,
600
611
  }), validationToRule('unique-directive-names-per-location', 'UniqueDirectivesPerLocation', {
601
612
  category: ['Schema', 'Operations'],
602
613
  description: `A GraphQL document is only valid if all non-repeatable directives at a given location are uniquely named.`,
614
+ requiresSchema: true,
603
615
  }), validationToRule('unique-enum-value-names', 'UniqueEnumValueNames', {
604
616
  category: 'Schema',
605
617
  description: `A GraphQL enum type is only valid if all its values are uniquely named.`,
606
- requiresSchema: false,
607
618
  recommended: false,
608
619
  }), validationToRule('unique-field-definition-names', 'UniqueFieldDefinitionNames', {
609
620
  category: 'Schema',
610
621
  description: `A GraphQL complex type is only valid if all its fields are uniquely named.`,
611
- requiresSchema: false,
612
622
  }), validationToRule('unique-input-field-names', 'UniqueInputFieldNames', {
613
623
  category: 'Operations',
614
624
  description: `A GraphQL input object value is only valid if all supplied fields are uniquely named.`,
615
- requiresSchema: false,
616
625
  }), validationToRule('unique-operation-types', 'UniqueOperationTypes', {
617
626
  category: 'Schema',
618
627
  description: `A GraphQL document is only valid if it has only one type per operation.`,
619
- requiresSchema: false,
620
628
  }), validationToRule('unique-type-names', 'UniqueTypeNames', {
621
629
  category: 'Schema',
622
630
  description: `A GraphQL document is only valid if all defined types have unique names.`,
623
- requiresSchema: false,
624
631
  }), validationToRule('unique-variable-names', 'UniqueVariableNames', {
625
632
  category: 'Operations',
626
633
  description: `A GraphQL operation is only valid if all its variables are uniquely named.`,
634
+ requiresSchema: true,
627
635
  }), validationToRule('value-literals-of-correct-type', 'ValuesOfCorrectType', {
628
636
  category: 'Operations',
629
637
  description: `A GraphQL document is only valid if all value literals are of the type expected at their position.`,
638
+ requiresSchema: true,
630
639
  }), validationToRule('variables-are-input-types', 'VariablesAreInputTypes', {
631
640
  category: 'Operations',
632
641
  description: `A GraphQL operation is only valid if all the variables it defines are of input types (scalar, enum, or input object).`,
642
+ requiresSchema: true,
633
643
  }), validationToRule('variables-in-allowed-position', 'VariablesInAllowedPosition', {
634
644
  category: 'Operations',
635
645
  description: `Variables passed to field arguments conform to type.`,
646
+ requiresSchema: true,
636
647
  }));
637
648
 
638
649
  const ALPHABETIZE = 'ALPHABETIZE';
package/package.json CHANGED
@@ -1,20 +1,27 @@
1
1
  {
2
2
  "name": "@graphql-eslint/eslint-plugin",
3
- "version": "3.2.0-alpha-2e742a6.0",
3
+ "version": "3.2.0-alpha-4ca7218.0",
4
+ "description": "GraphQL plugin for ESLint",
4
5
  "sideEffects": false,
5
6
  "peerDependencies": {
6
7
  "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 || ^16.0.0"
7
8
  },
8
9
  "dependencies": {
9
10
  "@babel/code-frame": "7.16.0",
10
- "@graphql-tools/code-file-loader": "7.2.2",
11
+ "@graphql-tools/code-file-loader": "7.2.3",
11
12
  "@graphql-tools/graphql-tag-pluck": "7.1.4",
12
- "@graphql-tools/utils": "8.5.3",
13
+ "@graphql-tools/utils": "8.5.4",
13
14
  "graphql-config": "4.1.0",
14
15
  "graphql-depth-limit": "1.1.0",
15
16
  "lodash.lowercase": "4.3.0"
16
17
  },
17
18
  "repository": "https://github.com/dotansimha/graphql-eslint",
19
+ "keywords": [
20
+ "eslint",
21
+ "eslintplugin",
22
+ "eslint-plugin",
23
+ "graphql"
24
+ ],
18
25
  "author": "Dotan Simha <dotansimha@gmail.com>",
19
26
  "license": "MIT",
20
27
  "main": "index.js",
package/types.d.ts CHANGED
@@ -49,8 +49,8 @@ export declare type CategoryType = 'Schema' | 'Operations';
49
49
  export declare type RuleDocsInfo<T> = {
50
50
  docs: Omit<Rule.RuleMetaData['docs'], 'category'> & {
51
51
  category: CategoryType | CategoryType[];
52
- requiresSchema?: boolean;
53
- requiresSiblings?: boolean;
52
+ requiresSchema?: true;
53
+ requiresSiblings?: true;
54
54
  examples?: {
55
55
  title: string;
56
56
  code: string;