@graphql-eslint/eslint-plugin 3.12.0-alpha-20220929104135-4ef9ac0 → 3.12.0-alpha-20221009002505-ace0694

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,4 +1,4 @@
1
1
  import { GraphQLConfig } from 'graphql-config';
2
2
  import { ParserOptions } from './types';
3
3
  export declare function loadOnDiskGraphQLConfig(filePath: string): GraphQLConfig;
4
- export declare function loadGraphQLConfig(options?: ParserOptions): GraphQLConfig;
4
+ export declare function loadGraphQLConfig(options: ParserOptions): GraphQLConfig;
package/index.js CHANGED
@@ -24,15 +24,24 @@ const codeFrame = require('@babel/code-frame');
24
24
  const debug = debugFactory('graphql-eslint:graphql-config');
25
25
  let graphQLConfig;
26
26
  function loadOnDiskGraphQLConfig(filePath) {
27
- return graphqlConfig.loadConfigSync({
27
+ const rootDir = path.dirname(filePath);
28
+ const config = graphqlConfig.loadConfigSync({
28
29
  // load config relative to the file being linted
29
- rootDir: filePath ? path.dirname(filePath) : undefined,
30
+ rootDir,
30
31
  throwOnEmpty: false,
31
32
  throwOnMissing: false,
32
- extensions: [addCodeFileLoaderExtension],
33
+ });
34
+ if (!config) {
35
+ return null;
36
+ }
37
+ const project = config.getProjectForFile(filePath);
38
+ return graphqlConfig.loadConfigSync({
39
+ rootDir,
40
+ extensions: [codeFileLoaderExtension(project.extensions.pluckConfig)],
33
41
  });
34
42
  }
35
- function loadGraphQLConfig(options = {}) {
43
+ function loadGraphQLConfig(options) {
44
+ var _a;
36
45
  // We don't want cache config on test environment
37
46
  // Otherwise schema and documents will be same for all tests
38
47
  if (process.env.NODE_ENV !== 'test' && graphQLConfig) {
@@ -57,53 +66,57 @@ function loadGraphQLConfig(options = {}) {
57
66
  new graphqlConfig.GraphQLConfig({
58
67
  config: configOptions,
59
68
  filepath: 'virtual-config',
60
- }, [addCodeFileLoaderExtension]);
69
+ }, [codeFileLoaderExtension((_a = options.extensions) === null || _a === void 0 ? void 0 : _a.pluckConfig)]);
61
70
  return graphQLConfig;
62
71
  }
63
- const addCodeFileLoaderExtension = api => {
64
- api.loaders.schema.register(new codeFileLoader.CodeFileLoader());
65
- api.loaders.documents.register(new codeFileLoader.CodeFileLoader());
72
+ const codeFileLoaderExtension = (pluckConfig) => api => {
73
+ const { schema, documents } = api.loaders;
74
+ schema.register(new codeFileLoader.CodeFileLoader({ pluckConfig }));
75
+ documents.register(new codeFileLoader.CodeFileLoader({ pluckConfig }));
66
76
  return { name: 'graphql-eslint-loaders' };
67
77
  };
68
78
 
69
79
  const blocksMap = new Map();
70
80
  let onDiskConfig;
81
+ let pluckConfig;
82
+ let RELEVANT_KEYWORDS;
71
83
  const processor = {
72
84
  supportsAutofix: true,
73
85
  preprocess(code, filePath) {
74
- var _a, _b, _c;
75
- onDiskConfig || (onDiskConfig = loadOnDiskGraphQLConfig(filePath));
76
- const graphQLTagPluckOptions = (_c = (_b = (_a = onDiskConfig === null || onDiskConfig === void 0 ? void 0 : onDiskConfig.getProjectForFile) === null || _a === void 0 ? void 0 : _a.call(onDiskConfig, filePath)) === null || _b === void 0 ? void 0 : _b.extensions) === null || _c === void 0 ? void 0 : _c.graphqlTagPluck;
77
- const { modules = [], globalGqlIdentifierName = ['gql', 'graphql'], gqlMagicComment = 'GraphQL', } = graphQLTagPluckOptions || {};
78
- const RELEVANT_KEYWORDS = [
79
- ...new Set([
80
- ...modules.map(({ identifier }) => identifier),
81
- ...utils.asArray(globalGqlIdentifierName),
86
+ if (!pluckConfig) {
87
+ onDiskConfig = loadOnDiskGraphQLConfig(filePath);
88
+ const { modules = [], globalGqlIdentifierName = ['gql', 'graphql'], gqlMagicComment = 'GraphQL', } = (onDiskConfig === null || onDiskConfig === void 0 ? void 0 : onDiskConfig.getProjectForFile(filePath).extensions.pluckConfig) || {};
89
+ pluckConfig = {
90
+ skipIndent: true,
91
+ modules,
92
+ globalGqlIdentifierName,
82
93
  gqlMagicComment,
83
- ].filter(Boolean)),
84
- ];
94
+ };
95
+ RELEVANT_KEYWORDS = [
96
+ ...new Set([
97
+ ...modules.map(({ identifier }) => identifier),
98
+ ...utils.asArray(globalGqlIdentifierName),
99
+ gqlMagicComment,
100
+ ].filter(Boolean)),
101
+ ];
102
+ }
85
103
  if (RELEVANT_KEYWORDS.every(keyword => !code.includes(keyword))) {
86
104
  return [code];
87
105
  }
88
106
  try {
89
- const extractedDocuments = graphqlTagPluck.parseCode({
90
- code,
91
- filePath,
92
- options: {
93
- skipIndent: true,
94
- ...graphQLTagPluckOptions,
95
- },
96
- });
97
- const blocks = extractedDocuments.map(item => ({
107
+ const sources = graphqlTagPluck.gqlPluckFromCodeStringSync(filePath, code, pluckConfig);
108
+ const isSvelte = filePath.endsWith('.svelte');
109
+ const blocks = sources.map(item => ({
98
110
  filename: 'document.graphql',
99
- text: item.content,
100
- lineOffset: item.loc.start.line - 1,
101
- offset: item.start + 1,
111
+ text: item.body,
112
+ lineOffset: item.locationOffset.line - (isSvelte ? 3 : 1),
113
+ // @ts-expect-error -- `index` field exist but show ts error
114
+ offset: item.locationOffset.index + (isSvelte ? -52 : 1),
102
115
  }));
103
116
  blocksMap.set(filePath, blocks);
104
117
  return [...blocks, code /* source code must be provided and be last */];
105
118
  }
106
- catch (_d) {
119
+ catch (_a) {
107
120
  // in case of parsing error return code as is
108
121
  return [code];
109
122
  }
@@ -776,14 +789,6 @@ const rule = {
776
789
  description: 'Definitions – `type`, `interface`, `enum`, `scalar`, `input`, `union` and `directive`.',
777
790
  default: false,
778
791
  },
779
- ignorePrefix: {
780
- type: 'array',
781
- default: [],
782
- },
783
- ignoreSuffix: {
784
- type: 'array',
785
- default: [],
786
- },
787
792
  },
788
793
  },
789
794
  },
@@ -842,18 +847,6 @@ const rule = {
842
847
  const prevName = ('alias' in prevNode && ((_c = prevNode.alias) === null || _c === void 0 ? void 0 : _c.value)) ||
843
848
  ('name' in prevNode && ((_d = prevNode.name) === null || _d === void 0 ? void 0 : _d.value));
844
849
  if (prevName) {
845
- if ((opts.ignorePrefix || []).length > 0) {
846
- const shouldSkipIgnorePrefix = opts.ignorePrefix.some(prefix => prefix === prevName || prefix === currName || prevName.startsWith(prefix) || currName.startsWith(prefix));
847
- if (shouldSkipIgnorePrefix) {
848
- continue;
849
- }
850
- }
851
- if ((opts.ignoreSuffix || []).length > 0) {
852
- const shouldSkipIgnoreSuffix = opts.ignoreSuffix.some(suffix => suffix === prevName || suffix === currName || prevName.endsWith(suffix) || currName.endsWith(suffix));
853
- if (shouldSkipIgnoreSuffix) {
854
- continue;
855
- }
856
- }
857
850
  // Compare with lexicographic order
858
851
  const compareResult = prevName.localeCompare(currName);
859
852
  const shouldSort = compareResult === 1;
@@ -4461,10 +4454,10 @@ function getSiblingOperations(projectForFile) {
4461
4454
 
4462
4455
  const debug$3 = debugFactory('graphql-eslint:parser');
4463
4456
  debug$3('cwd %o', process.cwd());
4464
- function parseForESLint(code, options = {}) {
4457
+ function parseForESLint(code, options) {
4465
4458
  try {
4466
- const filePath = options.filePath || '';
4467
- const realFilepath = filePath && getOnDiskFilepath(filePath);
4459
+ const { filePath } = options;
4460
+ const realFilepath = getOnDiskFilepath(filePath);
4468
4461
  const gqlConfig = loadGraphQLConfig(options);
4469
4462
  const projectForFile = realFilepath
4470
4463
  ? gqlConfig.getProjectForFile(realFilepath)
package/index.mjs CHANGED
@@ -1,8 +1,8 @@
1
- import { parseCode } from '@graphql-tools/graphql-tag-pluck';
1
+ import { gqlPluckFromCodeStringSync } from '@graphql-tools/graphql-tag-pluck';
2
2
  import { asArray, getDocumentNodeFromSchema, parseGraphQLSDL } from '@graphql-tools/utils';
3
3
  import { dirname, extname, basename, relative, resolve } from 'path';
4
4
  import debugFactory from 'debug';
5
- import { loadConfigSync, GraphQLConfig } from 'graphql-config';
5
+ import { GraphQLConfig, loadConfigSync } from 'graphql-config';
6
6
  import { CodeFileLoader } from '@graphql-tools/code-file-loader';
7
7
  import { Kind, visit, validate, TokenKind, isScalarType, DirectiveLocation, isInterfaceType, TypeInfo, visitWithTypeInfo, isObjectType as isObjectType$1, Source, isNonNullType, isListType, GraphQLObjectType, GraphQLInterfaceType, GraphQLSchema, GraphQLError } from 'graphql';
8
8
  import { validateSDL } from 'graphql/validation/validate';
@@ -18,15 +18,24 @@ import { codeFrameColumns } from '@babel/code-frame';
18
18
  const debug = debugFactory('graphql-eslint:graphql-config');
19
19
  let graphQLConfig;
20
20
  function loadOnDiskGraphQLConfig(filePath) {
21
- return loadConfigSync({
21
+ const rootDir = dirname(filePath);
22
+ const config = loadConfigSync({
22
23
  // load config relative to the file being linted
23
- rootDir: filePath ? dirname(filePath) : undefined,
24
+ rootDir,
24
25
  throwOnEmpty: false,
25
26
  throwOnMissing: false,
26
- extensions: [addCodeFileLoaderExtension],
27
+ });
28
+ if (!config) {
29
+ return null;
30
+ }
31
+ const project = config.getProjectForFile(filePath);
32
+ return loadConfigSync({
33
+ rootDir,
34
+ extensions: [codeFileLoaderExtension(project.extensions.pluckConfig)],
27
35
  });
28
36
  }
29
- function loadGraphQLConfig(options = {}) {
37
+ function loadGraphQLConfig(options) {
38
+ var _a;
30
39
  // We don't want cache config on test environment
31
40
  // Otherwise schema and documents will be same for all tests
32
41
  if (process.env.NODE_ENV !== 'test' && graphQLConfig) {
@@ -51,53 +60,57 @@ function loadGraphQLConfig(options = {}) {
51
60
  new GraphQLConfig({
52
61
  config: configOptions,
53
62
  filepath: 'virtual-config',
54
- }, [addCodeFileLoaderExtension]);
63
+ }, [codeFileLoaderExtension((_a = options.extensions) === null || _a === void 0 ? void 0 : _a.pluckConfig)]);
55
64
  return graphQLConfig;
56
65
  }
57
- const addCodeFileLoaderExtension = api => {
58
- api.loaders.schema.register(new CodeFileLoader());
59
- api.loaders.documents.register(new CodeFileLoader());
66
+ const codeFileLoaderExtension = (pluckConfig) => api => {
67
+ const { schema, documents } = api.loaders;
68
+ schema.register(new CodeFileLoader({ pluckConfig }));
69
+ documents.register(new CodeFileLoader({ pluckConfig }));
60
70
  return { name: 'graphql-eslint-loaders' };
61
71
  };
62
72
 
63
73
  const blocksMap = new Map();
64
74
  let onDiskConfig;
75
+ let pluckConfig;
76
+ let RELEVANT_KEYWORDS;
65
77
  const processor = {
66
78
  supportsAutofix: true,
67
79
  preprocess(code, filePath) {
68
- var _a, _b, _c;
69
- onDiskConfig || (onDiskConfig = loadOnDiskGraphQLConfig(filePath));
70
- const graphQLTagPluckOptions = (_c = (_b = (_a = onDiskConfig === null || onDiskConfig === void 0 ? void 0 : onDiskConfig.getProjectForFile) === null || _a === void 0 ? void 0 : _a.call(onDiskConfig, filePath)) === null || _b === void 0 ? void 0 : _b.extensions) === null || _c === void 0 ? void 0 : _c.graphqlTagPluck;
71
- const { modules = [], globalGqlIdentifierName = ['gql', 'graphql'], gqlMagicComment = 'GraphQL', } = graphQLTagPluckOptions || {};
72
- const RELEVANT_KEYWORDS = [
73
- ...new Set([
74
- ...modules.map(({ identifier }) => identifier),
75
- ...asArray(globalGqlIdentifierName),
80
+ if (!pluckConfig) {
81
+ onDiskConfig = loadOnDiskGraphQLConfig(filePath);
82
+ const { modules = [], globalGqlIdentifierName = ['gql', 'graphql'], gqlMagicComment = 'GraphQL', } = (onDiskConfig === null || onDiskConfig === void 0 ? void 0 : onDiskConfig.getProjectForFile(filePath).extensions.pluckConfig) || {};
83
+ pluckConfig = {
84
+ skipIndent: true,
85
+ modules,
86
+ globalGqlIdentifierName,
76
87
  gqlMagicComment,
77
- ].filter(Boolean)),
78
- ];
88
+ };
89
+ RELEVANT_KEYWORDS = [
90
+ ...new Set([
91
+ ...modules.map(({ identifier }) => identifier),
92
+ ...asArray(globalGqlIdentifierName),
93
+ gqlMagicComment,
94
+ ].filter(Boolean)),
95
+ ];
96
+ }
79
97
  if (RELEVANT_KEYWORDS.every(keyword => !code.includes(keyword))) {
80
98
  return [code];
81
99
  }
82
100
  try {
83
- const extractedDocuments = parseCode({
84
- code,
85
- filePath,
86
- options: {
87
- skipIndent: true,
88
- ...graphQLTagPluckOptions,
89
- },
90
- });
91
- const blocks = extractedDocuments.map(item => ({
101
+ const sources = gqlPluckFromCodeStringSync(filePath, code, pluckConfig);
102
+ const isSvelte = filePath.endsWith('.svelte');
103
+ const blocks = sources.map(item => ({
92
104
  filename: 'document.graphql',
93
- text: item.content,
94
- lineOffset: item.loc.start.line - 1,
95
- offset: item.start + 1,
105
+ text: item.body,
106
+ lineOffset: item.locationOffset.line - (isSvelte ? 3 : 1),
107
+ // @ts-expect-error -- `index` field exist but show ts error
108
+ offset: item.locationOffset.index + (isSvelte ? -52 : 1),
96
109
  }));
97
110
  blocksMap.set(filePath, blocks);
98
111
  return [...blocks, code /* source code must be provided and be last */];
99
112
  }
100
- catch (_d) {
113
+ catch (_a) {
101
114
  // in case of parsing error return code as is
102
115
  return [code];
103
116
  }
@@ -770,14 +783,6 @@ const rule = {
770
783
  description: 'Definitions – `type`, `interface`, `enum`, `scalar`, `input`, `union` and `directive`.',
771
784
  default: false,
772
785
  },
773
- ignorePrefix: {
774
- type: 'array',
775
- default: [],
776
- },
777
- ignoreSuffix: {
778
- type: 'array',
779
- default: [],
780
- },
781
786
  },
782
787
  },
783
788
  },
@@ -836,18 +841,6 @@ const rule = {
836
841
  const prevName = ('alias' in prevNode && ((_c = prevNode.alias) === null || _c === void 0 ? void 0 : _c.value)) ||
837
842
  ('name' in prevNode && ((_d = prevNode.name) === null || _d === void 0 ? void 0 : _d.value));
838
843
  if (prevName) {
839
- if ((opts.ignorePrefix || []).length > 0) {
840
- const shouldSkipIgnorePrefix = opts.ignorePrefix.some(prefix => prefix === prevName || prefix === currName || prevName.startsWith(prefix) || currName.startsWith(prefix));
841
- if (shouldSkipIgnorePrefix) {
842
- continue;
843
- }
844
- }
845
- if ((opts.ignoreSuffix || []).length > 0) {
846
- const shouldSkipIgnoreSuffix = opts.ignoreSuffix.some(suffix => suffix === prevName || suffix === currName || prevName.endsWith(suffix) || currName.endsWith(suffix));
847
- if (shouldSkipIgnoreSuffix) {
848
- continue;
849
- }
850
- }
851
844
  // Compare with lexicographic order
852
845
  const compareResult = prevName.localeCompare(currName);
853
846
  const shouldSort = compareResult === 1;
@@ -4455,10 +4448,10 @@ function getSiblingOperations(projectForFile) {
4455
4448
 
4456
4449
  const debug$3 = debugFactory('graphql-eslint:parser');
4457
4450
  debug$3('cwd %o', process.cwd());
4458
- function parseForESLint(code, options = {}) {
4451
+ function parseForESLint(code, options) {
4459
4452
  try {
4460
- const filePath = options.filePath || '';
4461
- const realFilepath = filePath && getOnDiskFilepath(filePath);
4453
+ const { filePath } = options;
4454
+ const realFilepath = getOnDiskFilepath(filePath);
4462
4455
  const gqlConfig = loadGraphQLConfig(options);
4463
4456
  const projectForFile = realFilepath
4464
4457
  ? gqlConfig.getProjectForFile(realFilepath)
package/package.json CHANGED
@@ -1,20 +1,20 @@
1
1
  {
2
2
  "name": "@graphql-eslint/eslint-plugin",
3
- "version": "3.12.0-alpha-20220929104135-4ef9ac0",
3
+ "version": "3.12.0-alpha-20221009002505-ace0694",
4
4
  "description": "GraphQL plugin for ESLint",
5
5
  "sideEffects": false,
6
6
  "peerDependencies": {
7
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"
8
8
  },
9
9
  "dependencies": {
10
- "@babel/code-frame": "^7.16.7",
11
- "@graphql-tools/code-file-loader": "^7.2.14",
12
- "@graphql-tools/graphql-tag-pluck": "^7.2.6",
13
- "@graphql-tools/utils": "^8.6.9",
10
+ "@babel/code-frame": "^7.18.6",
11
+ "@graphql-tools/code-file-loader": "^7.3.6",
12
+ "@graphql-tools/graphql-tag-pluck": "^7.3.6",
13
+ "@graphql-tools/utils": "^8.12.0",
14
14
  "chalk": "^4.1.2",
15
15
  "debug": "^4.3.4",
16
- "fast-glob": "^3.2.11",
17
- "graphql-config": "^4.3.0",
16
+ "fast-glob": "^3.2.12",
17
+ "graphql-config": "^4.3.5",
18
18
  "graphql-depth-limit": "^1.1.0",
19
19
  "lodash.lowercase": "^4.3.0"
20
20
  },
package/parser.d.ts CHANGED
@@ -1,2 +1,2 @@
1
1
  import { GraphQLESLintParseResult, ParserOptions } from './types';
2
- export declare function parseForESLint(code: string, options?: ParserOptions): GraphQLESLintParseResult;
2
+ export declare function parseForESLint(code: string, options: ParserOptions): GraphQLESLintParseResult;
@@ -11,8 +11,6 @@ export declare type AlphabetizeConfig = {
11
11
  variables?: typeof variablesEnum;
12
12
  arguments?: typeof argumentsEnum;
13
13
  definitions?: boolean;
14
- ignorePrefix?: string[];
15
- ignoreSuffix?: string[];
16
14
  };
17
15
  declare const rule: GraphQLESLintRule<[AlphabetizeConfig]>;
18
16
  export default rule;
package/schema.d.ts CHANGED
@@ -1,3 +1,3 @@
1
1
  import { GraphQLProjectConfig } from 'graphql-config';
2
2
  import type { ParserOptions, Schema } from './types';
3
- export declare function getSchema(projectForFile: GraphQLProjectConfig, options?: ParserOptions): Schema;
3
+ export declare function getSchema(projectForFile: GraphQLProjectConfig, options?: Omit<ParserOptions, 'filePath'>): Schema;
package/testkit.d.ts CHANGED
@@ -16,9 +16,9 @@ export declare type GraphQLInvalidTestCase<T> = GraphQLValidTestCase<T> & {
16
16
  export declare class GraphQLRuleTester extends RuleTester {
17
17
  config: {
18
18
  parser: string;
19
- parserOptions: ParserOptions;
19
+ parserOptions: Omit<ParserOptions, 'filePath'>;
20
20
  };
21
- constructor(parserOptions?: ParserOptions);
21
+ constructor(parserOptions?: Omit<ParserOptions, 'filePath'>);
22
22
  fromMockFile(path: string): string;
23
23
  runGraphQLTests<Options, WithTypeInfo extends boolean = false>(ruleId: string, rule: GraphQLESLintRule<Options, WithTypeInfo>, tests: {
24
24
  valid: (string | GraphQLValidTestCase<Options>)[];
package/types.d.ts CHANGED
@@ -22,7 +22,7 @@ export interface ParserOptions {
22
22
  };
23
23
  graphQLParserOptions?: Omit<GraphQLParseOptions, 'noLocation'>;
24
24
  skipGraphQLConfig?: boolean;
25
- filePath?: string;
25
+ filePath: string;
26
26
  }
27
27
  export declare type ParserServices = {
28
28
  schema: Schema;