@graphql-eslint/eslint-plugin 3.12.0-alpha-20220929103858-c00a837 → 3.12.0-alpha-20221008232037-33da317

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.
@@ -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,56 @@ 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 blocks = sources.map(item => ({
98
109
  filename: 'document.graphql',
99
- text: item.content,
100
- lineOffset: item.loc.start.line - 1,
101
- offset: item.start + 1,
110
+ text: item.body,
111
+ lineOffset: item.locationOffset.line - 1,
112
+ // @ts-expect-error -- `index` field exist but show ts error
113
+ offset: item.locationOffset.index + 1,
102
114
  }));
103
115
  blocksMap.set(filePath, blocks);
104
116
  return [...blocks, code /* source code must be provided and be last */];
105
117
  }
106
- catch (_d) {
118
+ catch (_a) {
107
119
  // in case of parsing error return code as is
108
120
  return [code];
109
121
  }
@@ -1212,32 +1224,6 @@ const rule$3 = {
1212
1224
  fullName
1213
1225
  }
1214
1226
  }
1215
- `,
1216
- },
1217
- {
1218
- title: 'Correct',
1219
- usage: [{ fragment: { style: 'kebab-case', suffix: 'Mutation', prefix: 'mutation.' } }],
1220
- name: 'mutation.add-alert.graphql',
1221
- code: /* GraphQL */ `
1222
- # mutation.add-alert.graphql
1223
- mutation addAlert($input: AddAlertInput!) {
1224
- addAlert(input: $input) {
1225
- ...AlertFields
1226
- }
1227
- }
1228
- `,
1229
- },
1230
- {
1231
- title: 'Correct',
1232
- usage: [{ fragment: { prefix: 'query.' } }],
1233
- name: 'query.me.graphql',
1234
- code: /* GraphQL */ `
1235
- # query.me.graphql
1236
- query me {
1237
- me {
1238
- ...UserFields
1239
- }
1240
- }
1241
1227
  `,
1242
1228
  },
1243
1229
  ],
@@ -1267,7 +1253,6 @@ const rule$3 = {
1267
1253
  properties: {
1268
1254
  style: { enum: CASE_STYLES },
1269
1255
  suffix: { type: 'string' },
1270
- prefix: { type: 'string' },
1271
1256
  },
1272
1257
  },
1273
1258
  },
@@ -1333,13 +1318,13 @@ const rule$3 = {
1333
1318
  option = { style: option };
1334
1319
  }
1335
1320
  const expectedExtension = options.fileExtension || fileExtension;
1336
- let expectedFilename = option.prefix || '';
1321
+ let expectedFilename;
1337
1322
  if (option.style) {
1338
1323
  expectedFilename =
1339
1324
  option.style === 'matchDocumentStyle' ? docName : convertCase(option.style, docName);
1340
1325
  }
1341
1326
  else {
1342
- expectedFilename += filename;
1327
+ expectedFilename = filename;
1343
1328
  }
1344
1329
  expectedFilename += (option.suffix || '') + expectedExtension;
1345
1330
  const filenameWithExtension = filename + expectedExtension;
@@ -4468,10 +4453,10 @@ function getSiblingOperations(projectForFile) {
4468
4453
 
4469
4454
  const debug$3 = debugFactory('graphql-eslint:parser');
4470
4455
  debug$3('cwd %o', process.cwd());
4471
- function parseForESLint(code, options = {}) {
4456
+ function parseForESLint(code, options) {
4472
4457
  try {
4473
- const filePath = options.filePath || '';
4474
- const realFilepath = filePath && getOnDiskFilepath(filePath);
4458
+ const { filePath } = options;
4459
+ const realFilepath = getOnDiskFilepath(filePath);
4475
4460
  const gqlConfig = loadGraphQLConfig(options);
4476
4461
  const projectForFile = realFilepath
4477
4462
  ? 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,56 @@ 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 blocks = sources.map(item => ({
92
103
  filename: 'document.graphql',
93
- text: item.content,
94
- lineOffset: item.loc.start.line - 1,
95
- offset: item.start + 1,
104
+ text: item.body,
105
+ lineOffset: item.locationOffset.line - 1,
106
+ // @ts-expect-error -- `index` field exist but show ts error
107
+ offset: item.locationOffset.index + 1,
96
108
  }));
97
109
  blocksMap.set(filePath, blocks);
98
110
  return [...blocks, code /* source code must be provided and be last */];
99
111
  }
100
- catch (_d) {
112
+ catch (_a) {
101
113
  // in case of parsing error return code as is
102
114
  return [code];
103
115
  }
@@ -1206,32 +1218,6 @@ const rule$3 = {
1206
1218
  fullName
1207
1219
  }
1208
1220
  }
1209
- `,
1210
- },
1211
- {
1212
- title: 'Correct',
1213
- usage: [{ fragment: { style: 'kebab-case', suffix: 'Mutation', prefix: 'mutation.' } }],
1214
- name: 'mutation.add-alert.graphql',
1215
- code: /* GraphQL */ `
1216
- # mutation.add-alert.graphql
1217
- mutation addAlert($input: AddAlertInput!) {
1218
- addAlert(input: $input) {
1219
- ...AlertFields
1220
- }
1221
- }
1222
- `,
1223
- },
1224
- {
1225
- title: 'Correct',
1226
- usage: [{ fragment: { prefix: 'query.' } }],
1227
- name: 'query.me.graphql',
1228
- code: /* GraphQL */ `
1229
- # query.me.graphql
1230
- query me {
1231
- me {
1232
- ...UserFields
1233
- }
1234
- }
1235
1221
  `,
1236
1222
  },
1237
1223
  ],
@@ -1261,7 +1247,6 @@ const rule$3 = {
1261
1247
  properties: {
1262
1248
  style: { enum: CASE_STYLES },
1263
1249
  suffix: { type: 'string' },
1264
- prefix: { type: 'string' },
1265
1250
  },
1266
1251
  },
1267
1252
  },
@@ -1327,13 +1312,13 @@ const rule$3 = {
1327
1312
  option = { style: option };
1328
1313
  }
1329
1314
  const expectedExtension = options.fileExtension || fileExtension;
1330
- let expectedFilename = option.prefix || '';
1315
+ let expectedFilename;
1331
1316
  if (option.style) {
1332
1317
  expectedFilename =
1333
1318
  option.style === 'matchDocumentStyle' ? docName : convertCase(option.style, docName);
1334
1319
  }
1335
1320
  else {
1336
- expectedFilename += filename;
1321
+ expectedFilename = filename;
1337
1322
  }
1338
1323
  expectedFilename += (option.suffix || '') + expectedExtension;
1339
1324
  const filenameWithExtension = filename + expectedExtension;
@@ -4462,10 +4447,10 @@ function getSiblingOperations(projectForFile) {
4462
4447
 
4463
4448
  const debug$3 = debugFactory('graphql-eslint:parser');
4464
4449
  debug$3('cwd %o', process.cwd());
4465
- function parseForESLint(code, options = {}) {
4450
+ function parseForESLint(code, options) {
4466
4451
  try {
4467
- const filePath = options.filePath || '';
4468
- const realFilepath = filePath && getOnDiskFilepath(filePath);
4452
+ const { filePath } = options;
4453
+ const realFilepath = getOnDiskFilepath(filePath);
4469
4454
  const gqlConfig = loadGraphQLConfig(options);
4470
4455
  const projectForFile = realFilepath
4471
4456
  ? 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-20220929103858-c00a837",
3
+ "version": "3.12.0-alpha-20221008232037-33da317",
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;
@@ -5,7 +5,6 @@ declare const ACCEPTED_EXTENSIONS: ['.gql', '.graphql'];
5
5
  declare type PropertySchema = {
6
6
  style?: CaseStyle;
7
7
  suffix?: string;
8
- prefix?: string;
9
8
  };
10
9
  export declare type MatchDocumentFilenameRuleConfig = {
11
10
  fileExtension?: typeof ACCEPTED_EXTENSIONS[number];
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;