@graphql-eslint/eslint-plugin 3.3.0-alpha-db2c2cb.0 → 3.3.0-alpha-1c01242.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.
@@ -2,7 +2,7 @@
2
2
 
3
3
  - Category: `Schema`
4
4
  - Rule name: `@graphql-eslint/possible-type-extension`
5
- - Requires GraphQL Schema: `false` [ℹ️](../../README.md#extended-linting-rules-with-graphql-schema)
5
+ - Requires GraphQL Schema: `true` [ℹ️](../../README.md#extended-linting-rules-with-graphql-schema)
6
6
  - Requires GraphQL Operations: `false` [ℹ️](../../README.md#extended-linting-rules-with-siblings-operations)
7
7
 
8
8
  A type extension is only valid if the type is defined and has the same kind.
@@ -1,3 +1,3 @@
1
1
  import { GraphQLConfig } from 'graphql-config';
2
2
  import { ParserOptions } from './types';
3
- export declare function loadGraphqlConfig(options: ParserOptions): GraphQLConfig;
3
+ export declare function loadGraphQLConfig(options: ParserOptions): GraphQLConfig;
package/index.js CHANGED
@@ -12,7 +12,7 @@ const utils = require('@graphql-tools/utils');
12
12
  const lowerCase = _interopDefault(require('lodash.lowercase'));
13
13
  const depthLimit = _interopDefault(require('graphql-depth-limit'));
14
14
  const graphqlTagPluck = require('@graphql-tools/graphql-tag-pluck');
15
- const graphqlConfig$1 = require('graphql-config');
15
+ const graphqlConfig = require('graphql-config');
16
16
  const codeFileLoader = require('@graphql-tools/code-file-loader');
17
17
  const eslint = require('eslint');
18
18
  const codeFrame = require('@babel/code-frame');
@@ -326,14 +326,14 @@ function getLocation(loc, fieldName = '', offset) {
326
326
  };
327
327
  }
328
328
 
329
- function validateDocument(sourceNode, context, schema, documentNode, rule) {
329
+ function validateDocument(context, schema = null, documentNode, rule, isSchemaToExtend = false) {
330
330
  if (documentNode.definitions.length === 0) {
331
331
  return;
332
332
  }
333
333
  try {
334
- const validationErrors = schema
334
+ const validationErrors = schema && !isSchemaToExtend
335
335
  ? graphql.validate(schema, documentNode, [rule])
336
- : validate.validateSDL(documentNode, null, [rule]);
336
+ : validate.validateSDL(documentNode, schema, [rule]);
337
337
  for (const error of validationErrors) {
338
338
  /*
339
339
  * TODO: Fix ESTree-AST converter because currently it's incorrectly convert loc.end
@@ -358,7 +358,8 @@ function validateDocument(sourceNode, context, schema, documentNode, rule) {
358
358
  }
359
359
  catch (e) {
360
360
  context.report({
361
- node: sourceNode,
361
+ // Report on first character
362
+ loc: { column: 0, line: 1 },
362
363
  message: e.message,
363
364
  });
364
365
  }
@@ -440,18 +441,18 @@ const validationToRule = (ruleId, ruleName, docs, getDocumentNode) => {
440
441
  },
441
442
  },
442
443
  create(context) {
444
+ if (!ruleFn) {
445
+ // eslint-disable-next-line no-console
446
+ 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...`);
447
+ return {};
448
+ }
449
+ const schema = docs.requiresSchema ? requireGraphQLSchemaFromContext(ruleId, context) : null;
443
450
  return {
444
451
  Document(node) {
445
- if (!ruleFn) {
446
- // eslint-disable-next-line no-console
447
- 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...`);
448
- return;
449
- }
450
- const schema = docs.requiresSchema ? requireGraphQLSchemaFromContext(ruleId, context) : null;
451
452
  const documentNode = getDocumentNode
452
453
  ? getDocumentNode({ ruleId, context, schema, node: node.rawNode() })
453
454
  : node.rawNode();
454
- validateDocument(node, context, schema, documentNode, ruleFn);
455
+ validateDocument(context, schema, documentNode, ruleFn, docs.requiresSchemaToExtend);
455
456
  },
456
457
  };
457
458
  },
@@ -601,7 +602,9 @@ const GRAPHQL_JS_VALIDATIONS = Object.assign({}, validationToRule('executable-de
601
602
  }), validationToRule('possible-type-extension', 'PossibleTypeExtensions', {
602
603
  category: 'Schema',
603
604
  description: `A type extension is only valid if the type is defined and has the same kind.`,
604
- recommended: false, // TODO: enable after https://github.com/dotansimha/graphql-eslint/issues/787 will be fixed
605
+ recommended: false,
606
+ requiresSchema: true,
607
+ requiresSchemaToExtend: true,
605
608
  }), validationToRule('provided-required-arguments', 'ProvidedRequiredArguments', {
606
609
  category: ['Schema', 'Operations'],
607
610
  description: `A field or directive is only valid if all required (non-null without a default value) field arguments have been provided.`,
@@ -3701,35 +3704,36 @@ function getSiblingOperations(options, gqlConfig) {
3701
3704
  return siblingOperations;
3702
3705
  }
3703
3706
 
3704
- let graphqlConfig;
3705
- function loadGraphqlConfig(options) {
3707
+ let graphQLConfig;
3708
+ function loadGraphQLConfig(options) {
3706
3709
  // We don't want cache config on test environment
3707
3710
  // Otherwise schema and documents will be same for all tests
3708
- if (process.env.NODE_ENV !== 'test' && graphqlConfig) {
3709
- return graphqlConfig;
3711
+ if (process.env.NODE_ENV !== 'test' && graphQLConfig) {
3712
+ return graphQLConfig;
3710
3713
  }
3711
3714
  const onDiskConfig = options.skipGraphQLConfig
3712
3715
  ? null
3713
- : graphqlConfig$1.loadConfigSync({
3716
+ : graphqlConfig.loadConfigSync({
3714
3717
  throwOnEmpty: false,
3715
3718
  throwOnMissing: false,
3716
3719
  extensions: [addCodeFileLoaderExtension],
3717
3720
  });
3718
- graphqlConfig =
3721
+ const configOptions = options.projects
3722
+ ? { projects: options.projects }
3723
+ : {
3724
+ schema: (options.schema || ''),
3725
+ documents: options.documents || options.operations,
3726
+ extensions: options.extensions,
3727
+ include: options.include,
3728
+ exclude: options.exclude,
3729
+ };
3730
+ graphQLConfig =
3719
3731
  onDiskConfig ||
3720
- new graphqlConfig$1.GraphQLConfig({
3721
- config: options.projects
3722
- ? { projects: options.projects }
3723
- : {
3724
- schema: (options.schema || ''),
3725
- documents: options.documents || options.operations,
3726
- extensions: options.extensions,
3727
- include: options.include,
3728
- exclude: options.exclude,
3729
- },
3732
+ new graphqlConfig.GraphQLConfig({
3733
+ config: configOptions,
3730
3734
  filepath: 'virtual-config',
3731
3735
  }, [addCodeFileLoaderExtension]);
3732
- return graphqlConfig;
3736
+ return graphQLConfig;
3733
3737
  }
3734
3738
  const addCodeFileLoaderExtension = api => {
3735
3739
  api.loaders.schema.register(new codeFileLoader.CodeFileLoader());
@@ -3819,10 +3823,18 @@ function parse(code, options) {
3819
3823
  return parseForESLint(code, options).ast;
3820
3824
  }
3821
3825
  function parseForESLint(code, options = {}) {
3822
- const gqlConfig = loadGraphqlConfig(options);
3823
- const schema = getSchema(options, gqlConfig);
3826
+ const gqlConfig = loadGraphQLConfig(options);
3827
+ let schema;
3828
+ try {
3829
+ schema = getSchema(options, gqlConfig);
3830
+ }
3831
+ catch (e) {
3832
+ e.message = `[graphql-eslint] Error while loading schema: ${e.message}`;
3833
+ // eslint-disable-next-line no-console
3834
+ console.error(e);
3835
+ }
3824
3836
  const parserServices = {
3825
- hasTypeInfo: schema !== null,
3837
+ hasTypeInfo: Boolean(schema),
3826
3838
  schema,
3827
3839
  siblingOperations: getSiblingOperations(options, gqlConfig),
3828
3840
  reachableTypes: getReachableTypes,
@@ -3851,6 +3863,7 @@ function parseForESLint(code, options = {}) {
3851
3863
  };
3852
3864
  }
3853
3865
  catch (e) {
3866
+ e.message = `[graphql-eslint] ${e.message}`;
3854
3867
  // In case of GraphQL parser error, we report it to ESLint as a parser error that matches the requirements
3855
3868
  // of ESLint. This will make sure to display it correctly in IDEs and lint results.
3856
3869
  if (e instanceof graphql.GraphQLError) {
@@ -3858,11 +3871,10 @@ function parseForESLint(code, options = {}) {
3858
3871
  index: e.positions[0],
3859
3872
  lineNumber: e.locations[0].line,
3860
3873
  column: e.locations[0].column,
3861
- message: `[graphql-eslint]: ${e.message}`,
3874
+ message: e.message,
3862
3875
  };
3863
3876
  throw eslintError;
3864
3877
  }
3865
- e.message = `[graphql-eslint]: ${e.message}`;
3866
3878
  throw e;
3867
3879
  }
3868
3880
  }
package/index.mjs CHANGED
@@ -320,14 +320,14 @@ function getLocation(loc, fieldName = '', offset) {
320
320
  };
321
321
  }
322
322
 
323
- function validateDocument(sourceNode, context, schema, documentNode, rule) {
323
+ function validateDocument(context, schema = null, documentNode, rule, isSchemaToExtend = false) {
324
324
  if (documentNode.definitions.length === 0) {
325
325
  return;
326
326
  }
327
327
  try {
328
- const validationErrors = schema
328
+ const validationErrors = schema && !isSchemaToExtend
329
329
  ? validate(schema, documentNode, [rule])
330
- : validateSDL(documentNode, null, [rule]);
330
+ : validateSDL(documentNode, schema, [rule]);
331
331
  for (const error of validationErrors) {
332
332
  /*
333
333
  * TODO: Fix ESTree-AST converter because currently it's incorrectly convert loc.end
@@ -352,7 +352,8 @@ function validateDocument(sourceNode, context, schema, documentNode, rule) {
352
352
  }
353
353
  catch (e) {
354
354
  context.report({
355
- node: sourceNode,
355
+ // Report on first character
356
+ loc: { column: 0, line: 1 },
356
357
  message: e.message,
357
358
  });
358
359
  }
@@ -434,18 +435,18 @@ const validationToRule = (ruleId, ruleName, docs, getDocumentNode) => {
434
435
  },
435
436
  },
436
437
  create(context) {
438
+ if (!ruleFn) {
439
+ // eslint-disable-next-line no-console
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...`);
441
+ return {};
442
+ }
443
+ const schema = docs.requiresSchema ? requireGraphQLSchemaFromContext(ruleId, context) : null;
437
444
  return {
438
445
  Document(node) {
439
- if (!ruleFn) {
440
- // eslint-disable-next-line no-console
441
- 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...`);
442
- return;
443
- }
444
- const schema = docs.requiresSchema ? requireGraphQLSchemaFromContext(ruleId, context) : null;
445
446
  const documentNode = getDocumentNode
446
447
  ? getDocumentNode({ ruleId, context, schema, node: node.rawNode() })
447
448
  : node.rawNode();
448
- validateDocument(node, context, schema, documentNode, ruleFn);
449
+ validateDocument(context, schema, documentNode, ruleFn, docs.requiresSchemaToExtend);
449
450
  },
450
451
  };
451
452
  },
@@ -595,7 +596,9 @@ const GRAPHQL_JS_VALIDATIONS = Object.assign({}, validationToRule('executable-de
595
596
  }), validationToRule('possible-type-extension', 'PossibleTypeExtensions', {
596
597
  category: 'Schema',
597
598
  description: `A type extension is only valid if the type is defined and has the same kind.`,
598
- recommended: false, // TODO: enable after https://github.com/dotansimha/graphql-eslint/issues/787 will be fixed
599
+ recommended: false,
600
+ requiresSchema: true,
601
+ requiresSchemaToExtend: true,
599
602
  }), validationToRule('provided-required-arguments', 'ProvidedRequiredArguments', {
600
603
  category: ['Schema', 'Operations'],
601
604
  description: `A field or directive is only valid if all required (non-null without a default value) field arguments have been provided.`,
@@ -3695,12 +3698,12 @@ function getSiblingOperations(options, gqlConfig) {
3695
3698
  return siblingOperations;
3696
3699
  }
3697
3700
 
3698
- let graphqlConfig;
3699
- function loadGraphqlConfig(options) {
3701
+ let graphQLConfig;
3702
+ function loadGraphQLConfig(options) {
3700
3703
  // We don't want cache config on test environment
3701
3704
  // Otherwise schema and documents will be same for all tests
3702
- if (process.env.NODE_ENV !== 'test' && graphqlConfig) {
3703
- return graphqlConfig;
3705
+ if (process.env.NODE_ENV !== 'test' && graphQLConfig) {
3706
+ return graphQLConfig;
3704
3707
  }
3705
3708
  const onDiskConfig = options.skipGraphQLConfig
3706
3709
  ? null
@@ -3709,21 +3712,22 @@ function loadGraphqlConfig(options) {
3709
3712
  throwOnMissing: false,
3710
3713
  extensions: [addCodeFileLoaderExtension],
3711
3714
  });
3712
- graphqlConfig =
3715
+ const configOptions = options.projects
3716
+ ? { projects: options.projects }
3717
+ : {
3718
+ schema: (options.schema || ''),
3719
+ documents: options.documents || options.operations,
3720
+ extensions: options.extensions,
3721
+ include: options.include,
3722
+ exclude: options.exclude,
3723
+ };
3724
+ graphQLConfig =
3713
3725
  onDiskConfig ||
3714
3726
  new GraphQLConfig({
3715
- config: options.projects
3716
- ? { projects: options.projects }
3717
- : {
3718
- schema: (options.schema || ''),
3719
- documents: options.documents || options.operations,
3720
- extensions: options.extensions,
3721
- include: options.include,
3722
- exclude: options.exclude,
3723
- },
3727
+ config: configOptions,
3724
3728
  filepath: 'virtual-config',
3725
3729
  }, [addCodeFileLoaderExtension]);
3726
- return graphqlConfig;
3730
+ return graphQLConfig;
3727
3731
  }
3728
3732
  const addCodeFileLoaderExtension = api => {
3729
3733
  api.loaders.schema.register(new CodeFileLoader());
@@ -3813,10 +3817,18 @@ function parse(code, options) {
3813
3817
  return parseForESLint(code, options).ast;
3814
3818
  }
3815
3819
  function parseForESLint(code, options = {}) {
3816
- const gqlConfig = loadGraphqlConfig(options);
3817
- const schema = getSchema(options, gqlConfig);
3820
+ const gqlConfig = loadGraphQLConfig(options);
3821
+ let schema;
3822
+ try {
3823
+ schema = getSchema(options, gqlConfig);
3824
+ }
3825
+ catch (e) {
3826
+ e.message = `[graphql-eslint] Error while loading schema: ${e.message}`;
3827
+ // eslint-disable-next-line no-console
3828
+ console.error(e);
3829
+ }
3818
3830
  const parserServices = {
3819
- hasTypeInfo: schema !== null,
3831
+ hasTypeInfo: Boolean(schema),
3820
3832
  schema,
3821
3833
  siblingOperations: getSiblingOperations(options, gqlConfig),
3822
3834
  reachableTypes: getReachableTypes,
@@ -3845,6 +3857,7 @@ function parseForESLint(code, options = {}) {
3845
3857
  };
3846
3858
  }
3847
3859
  catch (e) {
3860
+ e.message = `[graphql-eslint] ${e.message}`;
3848
3861
  // In case of GraphQL parser error, we report it to ESLint as a parser error that matches the requirements
3849
3862
  // of ESLint. This will make sure to display it correctly in IDEs and lint results.
3850
3863
  if (e instanceof GraphQLError) {
@@ -3852,11 +3865,10 @@ function parseForESLint(code, options = {}) {
3852
3865
  index: e.positions[0],
3853
3866
  lineNumber: e.locations[0].line,
3854
3867
  column: e.locations[0].column,
3855
- message: `[graphql-eslint]: ${e.message}`,
3868
+ message: e.message,
3856
3869
  };
3857
3870
  throw eslintError;
3858
3871
  }
3859
- e.message = `[graphql-eslint]: ${e.message}`;
3860
3872
  throw e;
3861
3873
  }
3862
3874
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@graphql-eslint/eslint-plugin",
3
- "version": "3.3.0-alpha-db2c2cb.0",
3
+ "version": "3.3.0-alpha-1c01242.0",
4
4
  "description": "GraphQL plugin for ESLint",
5
5
  "sideEffects": false,
6
6
  "peerDependencies": {
@@ -10,7 +10,7 @@
10
10
  "@babel/code-frame": "7.16.0",
11
11
  "@graphql-tools/code-file-loader": "7.2.3",
12
12
  "@graphql-tools/graphql-tag-pluck": "7.1.4",
13
- "@graphql-tools/utils": "8.5.4",
13
+ "@graphql-tools/utils": "8.5.5",
14
14
  "graphql-config": "4.1.0",
15
15
  "graphql-depth-limit": "1.1.0",
16
16
  "lodash.lowercase": "4.3.0"
@@ -31,6 +31,7 @@
31
31
  "definition": "index.d.ts"
32
32
  },
33
33
  "exports": {
34
+ "./package.json": "./package.json",
34
35
  ".": {
35
36
  "require": "./index.js",
36
37
  "import": "./index.mjs"
package/types.d.ts CHANGED
@@ -51,6 +51,7 @@ export declare type RuleDocsInfo<T> = {
51
51
  category: CategoryType | CategoryType[];
52
52
  requiresSchema?: true;
53
53
  requiresSiblings?: true;
54
+ requiresSchemaToExtend?: true;
54
55
  examples?: {
55
56
  title: string;
56
57
  code: string;