@graphql-eslint/eslint-plugin 4.1.0-alpha-20241129084707-436164c7c2041bfc29ccb7abed9a3c3fb4db5520 → 4.1.0-alpha-20241129085030-b075ada387ad44de7944517af78877c45bc8fd3b
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/cjs/index.d.cts +2 -2
- package/cjs/meta.js +1 -1
- package/cjs/rules/index.d.cts +2 -2
- package/cjs/rules/naming-convention/index.d.cts +2 -2
- package/cjs/rules/naming-convention/index.js +12 -14
- package/cjs/rules/no-unused-fields/index.js +3 -1
- package/cjs/rules/require-description/index.d.cts +2 -3
- package/cjs/rules/require-description/index.js +6 -60
- package/cjs/utils.d.cts +1 -2
- package/cjs/utils.js +1 -6
- package/esm/index.d.ts +2 -2
- package/esm/meta.js +1 -1
- package/esm/rules/index.d.ts +2 -2
- package/esm/rules/naming-convention/index.d.ts +2 -2
- package/esm/rules/naming-convention/index.js +12 -14
- package/esm/rules/no-unused-fields/index.js +4 -2
- package/esm/rules/require-description/index.d.ts +2 -3
- package/esm/rules/require-description/index.js +7 -61
- package/esm/utils.d.ts +1 -2
- package/esm/utils.js +0 -5
- package/index.browser.js +22 -73
- package/package.json +8 -2
package/cjs/index.d.cts
CHANGED
@@ -98,10 +98,10 @@ declare const _default: {
|
|
98
98
|
style?: ("camelCase" | "PascalCase" | "snake_case" | "UPPER_CASE") | undefined;
|
99
99
|
suffix?: string | undefined;
|
100
100
|
prefix?: string | undefined;
|
101
|
-
|
101
|
+
forbiddenPattern?: {
|
102
102
|
[x: string]: unknown;
|
103
103
|
}[] | undefined;
|
104
|
-
|
104
|
+
requiredPattern?: {
|
105
105
|
[x: string]: unknown;
|
106
106
|
}[] | undefined;
|
107
107
|
forbiddenPrefixes?: string[] | undefined;
|
package/cjs/meta.js
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
"use strict";Object.defineProperty(exports, "__esModule", {value: true});const version = "4.1.0-alpha-
|
1
|
+
"use strict";Object.defineProperty(exports, "__esModule", {value: true});const version = "4.1.0-alpha-20241129085030-b075ada387ad44de7944517af78877c45bc8fd3b";
|
2
2
|
|
3
3
|
|
4
4
|
exports.version = version;
|
package/cjs/rules/index.d.cts
CHANGED
@@ -61,10 +61,10 @@ declare const rules: {
|
|
61
61
|
style?: ("camelCase" | "PascalCase" | "snake_case" | "UPPER_CASE") | undefined;
|
62
62
|
suffix?: string | undefined;
|
63
63
|
prefix?: string | undefined;
|
64
|
-
|
64
|
+
forbiddenPattern?: {
|
65
65
|
[x: string]: unknown;
|
66
66
|
}[] | undefined;
|
67
|
-
|
67
|
+
requiredPattern?: {
|
68
68
|
[x: string]: unknown;
|
69
69
|
}[] | undefined;
|
70
70
|
forbiddenPrefixes?: string[] | undefined;
|
@@ -28,7 +28,7 @@ declare const schema: {
|
|
28
28
|
readonly suffix: {
|
29
29
|
readonly type: "string";
|
30
30
|
};
|
31
|
-
readonly
|
31
|
+
readonly forbiddenPattern: {
|
32
32
|
readonly items: {
|
33
33
|
readonly type: "object";
|
34
34
|
};
|
@@ -37,7 +37,7 @@ declare const schema: {
|
|
37
37
|
readonly uniqueItems: true;
|
38
38
|
readonly minItems: 1;
|
39
39
|
};
|
40
|
-
readonly
|
40
|
+
readonly requiredPattern: {
|
41
41
|
readonly items: {
|
42
42
|
readonly type: "object";
|
43
43
|
};
|
@@ -47,14 +47,14 @@ const KindToDisplayName = {
|
|
47
47
|
style: { enum: ALLOWED_STYLES },
|
48
48
|
prefix: { type: "string" },
|
49
49
|
suffix: { type: "string" },
|
50
|
-
|
50
|
+
forbiddenPattern: {
|
51
51
|
..._utilsjs.ARRAY_DEFAULT_OPTIONS,
|
52
52
|
items: {
|
53
53
|
type: "object"
|
54
54
|
},
|
55
55
|
description: "Should be of instance of `RegEx`"
|
56
56
|
},
|
57
|
-
|
57
|
+
requiredPattern: {
|
58
58
|
..._utilsjs.ARRAY_DEFAULT_OPTIONS,
|
59
59
|
items: {
|
60
60
|
type: "object"
|
@@ -63,19 +63,19 @@ const KindToDisplayName = {
|
|
63
63
|
},
|
64
64
|
forbiddenPrefixes: {
|
65
65
|
..._utilsjs.ARRAY_DEFAULT_OPTIONS,
|
66
|
-
description: descriptionPrefixesSuffixes("
|
66
|
+
description: descriptionPrefixesSuffixes("forbiddenPattern")
|
67
67
|
},
|
68
68
|
forbiddenSuffixes: {
|
69
69
|
..._utilsjs.ARRAY_DEFAULT_OPTIONS,
|
70
|
-
description: descriptionPrefixesSuffixes("
|
70
|
+
description: descriptionPrefixesSuffixes("forbiddenPattern")
|
71
71
|
},
|
72
72
|
requiredPrefixes: {
|
73
73
|
..._utilsjs.ARRAY_DEFAULT_OPTIONS,
|
74
|
-
description: descriptionPrefixesSuffixes("
|
74
|
+
description: descriptionPrefixesSuffixes("requiredPattern")
|
75
75
|
},
|
76
76
|
requiredSuffixes: {
|
77
77
|
..._utilsjs.ARRAY_DEFAULT_OPTIONS,
|
78
|
-
description: descriptionPrefixesSuffixes("
|
78
|
+
description: descriptionPrefixesSuffixes("requiredPattern")
|
79
79
|
},
|
80
80
|
ignorePattern: {
|
81
81
|
type: "string",
|
@@ -101,9 +101,7 @@ ${_utilsjs.TYPES_KINDS.map((kind) => `- \`${kind}\``).join(`
|
|
101
101
|
kind,
|
102
102
|
{
|
103
103
|
...schemaOption,
|
104
|
-
description:
|
105
|
-
>
|
106
|
-
> Read more about this kind on [spec.graphql.org](https://spec.graphql.org/October2021/#${kind}).`
|
104
|
+
description: `Read more about this kind on [spec.graphql.org](https://spec.graphql.org/October2021/#${kind}).`
|
107
105
|
}
|
108
106
|
])
|
109
107
|
),
|
@@ -358,8 +356,8 @@ ${_utilsjs.TYPES_KINDS.map((kind) => `- \`${kind}\``).join(`
|
|
358
356
|
ignorePattern,
|
359
357
|
requiredPrefixes,
|
360
358
|
requiredSuffixes,
|
361
|
-
|
362
|
-
|
359
|
+
forbiddenPattern,
|
360
|
+
requiredPattern
|
363
361
|
} = normalisePropertyOption(selector), nodeName = node.value, error = getError();
|
364
362
|
if (error) {
|
365
363
|
const { errorMessage, renameToNames } = error, [leadingUnderscores] = nodeName.match(/^_*/), [trailingUnderscores] = nodeName.match(/_*$/), suggestedNames = renameToNames.map(
|
@@ -385,15 +383,15 @@ ${_utilsjs.TYPES_KINDS.map((kind) => `- \`${kind}\``).join(`
|
|
385
383
|
errorMessage: `have "${suffix}" suffix`,
|
386
384
|
renameToNames: [name + suffix]
|
387
385
|
};
|
388
|
-
const forbidden = _optionalChain([
|
386
|
+
const forbidden = _optionalChain([forbiddenPattern, 'optionalAccess', _ => _.find, 'call', _2 => _2((pattern) => pattern.test(name))]);
|
389
387
|
if (forbidden)
|
390
388
|
return {
|
391
389
|
errorMessage: `not contain the forbidden pattern "${forbidden}"`,
|
392
390
|
renameToNames: [name.replace(forbidden, "")]
|
393
391
|
};
|
394
|
-
if (
|
392
|
+
if (requiredPattern && !requiredPattern.some((pattern) => pattern.test(name)))
|
395
393
|
return {
|
396
|
-
errorMessage: `contain the required pattern: ${_utilsjs.englishJoinWords.call(void 0,
|
394
|
+
errorMessage: `contain the required pattern: ${_utilsjs.englishJoinWords.call(void 0, requiredPattern.map((re) => re.source))}`,
|
397
395
|
renameToNames: []
|
398
396
|
};
|
399
397
|
const forbiddenPrefix = _optionalChain([forbiddenPrefixes, 'optionalAccess', _3 => _3.find, 'call', _4 => _4((prefix2) => name.startsWith(prefix2))]);
|
@@ -82,7 +82,9 @@ const RULE_ID = "no-unused-fields", RELAY_SCHEMA = (
|
|
82
82
|
"```json",
|
83
83
|
JSON.stringify(RELAY_DEFAULT_IGNORED_FIELD_SELECTORS, null, 2),
|
84
84
|
"```",
|
85
|
-
|
85
|
+
"",
|
86
|
+
"> These fields are defined by ESLint [`selectors`](https://eslint.org/docs/developer-guide/selectors).",
|
87
|
+
"> Paste or drop code into the editor in [ASTExplorer](https://astexplorer.net) and inspect the generated AST to compose your selector."
|
86
88
|
].join(`
|
87
89
|
`),
|
88
90
|
items: {
|
@@ -1,12 +1,5 @@
|
|
1
1
|
"use strict";Object.defineProperty(exports, "__esModule", {value: true}); function _optionalChain(ops) { let lastAccessLHS = undefined; let value = ops[0]; let i = 1; while (i < ops.length) { const op = ops[i]; const fn = ops[i + 1]; i += 2; if ((op === 'optionalAccess' || op === 'optionalCall') && value == null) { return undefined; } if (op === 'access' || op === 'optionalAccess') { lastAccessLHS = value; value = fn(value); } else if (op === 'call' || op === 'optionalCall') { value = fn((...args) => value.call(lastAccessLHS, ...args)); lastAccessLHS = undefined; } } return value; }var _graphql = require('graphql');
|
2
2
|
var _utils = require('@graphql-tools/utils');
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
3
|
var _utilsjs = require('../../utils.js');
|
11
4
|
const RULE_ID = "require-description", ALLOWED_KINDS = [
|
12
5
|
..._utilsjs.TYPES_KINDS,
|
@@ -26,34 +19,18 @@ const RULE_ID = "require-description", ALLOWED_KINDS = [
|
|
26
19
|
properties: {
|
27
20
|
types: {
|
28
21
|
type: "boolean",
|
29
|
-
enum: [!0],
|
30
22
|
description: `Includes:
|
31
23
|
${_utilsjs.TYPES_KINDS.map((kind) => `- \`${kind}\``).join(`
|
32
24
|
`)}`
|
33
25
|
},
|
34
26
|
rootField: {
|
35
27
|
type: "boolean",
|
36
|
-
enum: [!0],
|
37
28
|
description: "Definitions within `Query`, `Mutation`, and `Subscription` root types."
|
38
29
|
},
|
39
|
-
ignoredSelectors: {
|
40
|
-
..._utilsjs.ARRAY_DEFAULT_OPTIONS,
|
41
|
-
description: ["Ignore specific selectors", _utilsjs.eslintSelectorsTip].join(`
|
42
|
-
`)
|
43
|
-
},
|
44
30
|
...Object.fromEntries(
|
45
31
|
[...ALLOWED_KINDS].sort().map((kind) => {
|
46
|
-
let description =
|
47
|
-
>
|
48
|
-
> Read more about this kind on [spec.graphql.org](https://spec.graphql.org/October2021/#${kind}).`;
|
49
|
-
return kind === _graphql.Kind.OPERATION_DEFINITION && (description += [
|
50
|
-
"",
|
51
|
-
"",
|
52
|
-
"> [!WARNING]",
|
53
|
-
">",
|
54
|
-
'> You must use only comment syntax `#` and not description syntax `"""` or `"`.'
|
55
|
-
].join(`
|
56
|
-
`)), [kind, { type: "boolean", description }];
|
32
|
+
let description = `Read more about this kind on [spec.graphql.org](https://spec.graphql.org/October2021/#${kind}).`;
|
33
|
+
return kind === _graphql.Kind.OPERATION_DEFINITION && (description += '\n> You must use only comment syntax `#` and not description syntax `"""` or `"`.'), [kind, { type: "boolean", description }];
|
57
34
|
})
|
58
35
|
)
|
59
36
|
}
|
@@ -124,36 +101,6 @@ ${_utilsjs.TYPES_KINDS.map((kind) => `- \`${kind}\``).join(`
|
|
124
101
|
}
|
125
102
|
`
|
126
103
|
)
|
127
|
-
},
|
128
|
-
{
|
129
|
-
title: "Correct",
|
130
|
-
usage: [
|
131
|
-
{
|
132
|
-
ignoredSelectors: [
|
133
|
-
"[type=ObjectTypeDefinition][name.value=PageInfo]",
|
134
|
-
"[type=ObjectTypeDefinition][name.value=/(Connection|Edge)$/]"
|
135
|
-
]
|
136
|
-
}
|
137
|
-
],
|
138
|
-
code: (
|
139
|
-
/* GraphQL */
|
140
|
-
`
|
141
|
-
type FriendConnection {
|
142
|
-
edges: [FriendEdge]
|
143
|
-
pageInfo: PageInfo!
|
144
|
-
}
|
145
|
-
type FriendEdge {
|
146
|
-
cursor: String!
|
147
|
-
node: Friend!
|
148
|
-
}
|
149
|
-
type PageInfo {
|
150
|
-
hasPreviousPage: Boolean!
|
151
|
-
hasNextPage: Boolean!
|
152
|
-
startCursor: String
|
153
|
-
endCursor: String
|
154
|
-
}
|
155
|
-
`
|
156
|
-
)
|
157
104
|
}
|
158
105
|
],
|
159
106
|
configOptions: [
|
@@ -172,7 +119,7 @@ ${_utilsjs.TYPES_KINDS.map((kind) => `- \`${kind}\``).join(`
|
|
172
119
|
schema
|
173
120
|
},
|
174
121
|
create(context) {
|
175
|
-
const { types, rootField,
|
122
|
+
const { types, rootField, ...restOptions } = context.options[0] || {}, kinds = new Set(types ? _utilsjs.TYPES_KINDS : []);
|
176
123
|
for (const [kind, isEnabled] of Object.entries(restOptions))
|
177
124
|
isEnabled ? kinds.add(kind) : kinds.delete(kind);
|
178
125
|
if (rootField) {
|
@@ -183,11 +130,10 @@ ${_utilsjs.TYPES_KINDS.map((kind) => `- \`${kind}\``).join(`
|
|
183
130
|
].join(",")})$/] > FieldDefinition`
|
184
131
|
);
|
185
132
|
}
|
186
|
-
|
187
|
-
|
188
|
-
selector += `:not(${str})`;
|
133
|
+
if (!kinds.size)
|
134
|
+
throw new Error("At least one kind must be enabled");
|
189
135
|
return {
|
190
|
-
[
|
136
|
+
[[...kinds].join(",")](node) {
|
191
137
|
let description = "";
|
192
138
|
const isOperation = node.kind === _graphql.Kind.OPERATION_DEFINITION;
|
193
139
|
if (isOperation) {
|
package/cjs/utils.d.cts
CHANGED
@@ -41,6 +41,5 @@ type Truthy<T> = T extends '' | 0 | false | null | undefined ? never : T;
|
|
41
41
|
declare function truthy<T>(value: T): value is Truthy<T>;
|
42
42
|
declare function displayNodeName(node: GraphQLESTreeNode<ASTNode, boolean>): string;
|
43
43
|
declare function getNodeName(node: GraphQLESTreeNode<ASTNode>): string;
|
44
|
-
declare const eslintSelectorsTip = "> [!TIP]\n>\n> These fields are defined by ESLint [`selectors`](https://eslint.org/docs/developer-guide/selectors).\n> Paste or drop code into the editor in [ASTExplorer](https://astexplorer.net) and inspect the generated AST to compose your selector.";
|
45
44
|
|
46
|
-
export { ARRAY_DEFAULT_OPTIONS, CWD, type CaseStyle, REPORT_ON_FIRST_CHARACTER, TYPES_KINDS, VIRTUAL_DOCUMENT_REGEX, camelCase, convertCase, displayNodeName, englishJoinWords,
|
45
|
+
export { ARRAY_DEFAULT_OPTIONS, CWD, type CaseStyle, REPORT_ON_FIRST_CHARACTER, TYPES_KINDS, VIRTUAL_DOCUMENT_REGEX, camelCase, convertCase, displayNodeName, englishJoinWords, getLocation, getNodeName, getTypeName, logger, pascalCase, requireGraphQLOperations, requireGraphQLSchema, slash, truthy };
|
package/cjs/utils.js
CHANGED
@@ -144,10 +144,6 @@ function getNodeName(node) {
|
|
144
144
|
}
|
145
145
|
return "";
|
146
146
|
}
|
147
|
-
const eslintSelectorsTip = `> [!TIP]
|
148
|
-
>
|
149
|
-
> These fields are defined by ESLint [\`selectors\`](https://eslint.org/docs/developer-guide/selectors).
|
150
|
-
> Paste or drop code into the editor in [ASTExplorer](https://astexplorer.net) and inspect the generated AST to compose your selector.`;
|
151
147
|
|
152
148
|
|
153
149
|
|
@@ -167,5 +163,4 @@ const eslintSelectorsTip = `> [!TIP]
|
|
167
163
|
|
168
164
|
|
169
165
|
|
170
|
-
|
171
|
-
exports.ARRAY_DEFAULT_OPTIONS = ARRAY_DEFAULT_OPTIONS; exports.CWD = CWD; exports.REPORT_ON_FIRST_CHARACTER = REPORT_ON_FIRST_CHARACTER; exports.TYPES_KINDS = TYPES_KINDS; exports.VIRTUAL_DOCUMENT_REGEX = VIRTUAL_DOCUMENT_REGEX; exports.camelCase = camelCase; exports.convertCase = convertCase; exports.displayNodeName = displayNodeName; exports.englishJoinWords = englishJoinWords; exports.eslintSelectorsTip = eslintSelectorsTip; exports.getLocation = getLocation; exports.getNodeName = getNodeName; exports.getTypeName = getTypeName; exports.logger = logger; exports.pascalCase = pascalCase; exports.requireGraphQLOperations = requireGraphQLOperations; exports.requireGraphQLSchema = requireGraphQLSchema; exports.slash = slash; exports.truthy = truthy;
|
166
|
+
exports.ARRAY_DEFAULT_OPTIONS = ARRAY_DEFAULT_OPTIONS; exports.CWD = CWD; exports.REPORT_ON_FIRST_CHARACTER = REPORT_ON_FIRST_CHARACTER; exports.TYPES_KINDS = TYPES_KINDS; exports.VIRTUAL_DOCUMENT_REGEX = VIRTUAL_DOCUMENT_REGEX; exports.camelCase = camelCase; exports.convertCase = convertCase; exports.displayNodeName = displayNodeName; exports.englishJoinWords = englishJoinWords; exports.getLocation = getLocation; exports.getNodeName = getNodeName; exports.getTypeName = getTypeName; exports.logger = logger; exports.pascalCase = pascalCase; exports.requireGraphQLOperations = requireGraphQLOperations; exports.requireGraphQLSchema = requireGraphQLSchema; exports.slash = slash; exports.truthy = truthy;
|
package/esm/index.d.ts
CHANGED
@@ -98,10 +98,10 @@ declare const _default: {
|
|
98
98
|
style?: ("camelCase" | "PascalCase" | "snake_case" | "UPPER_CASE") | undefined;
|
99
99
|
suffix?: string | undefined;
|
100
100
|
prefix?: string | undefined;
|
101
|
-
|
101
|
+
forbiddenPattern?: {
|
102
102
|
[x: string]: unknown;
|
103
103
|
}[] | undefined;
|
104
|
-
|
104
|
+
requiredPattern?: {
|
105
105
|
[x: string]: unknown;
|
106
106
|
}[] | undefined;
|
107
107
|
forbiddenPrefixes?: string[] | undefined;
|
package/esm/meta.js
CHANGED
package/esm/rules/index.d.ts
CHANGED
@@ -61,10 +61,10 @@ declare const rules: {
|
|
61
61
|
style?: ("camelCase" | "PascalCase" | "snake_case" | "UPPER_CASE") | undefined;
|
62
62
|
suffix?: string | undefined;
|
63
63
|
prefix?: string | undefined;
|
64
|
-
|
64
|
+
forbiddenPattern?: {
|
65
65
|
[x: string]: unknown;
|
66
66
|
}[] | undefined;
|
67
|
-
|
67
|
+
requiredPattern?: {
|
68
68
|
[x: string]: unknown;
|
69
69
|
}[] | undefined;
|
70
70
|
forbiddenPrefixes?: string[] | undefined;
|
@@ -28,7 +28,7 @@ declare const schema: {
|
|
28
28
|
readonly suffix: {
|
29
29
|
readonly type: "string";
|
30
30
|
};
|
31
|
-
readonly
|
31
|
+
readonly forbiddenPattern: {
|
32
32
|
readonly items: {
|
33
33
|
readonly type: "object";
|
34
34
|
};
|
@@ -37,7 +37,7 @@ declare const schema: {
|
|
37
37
|
readonly uniqueItems: true;
|
38
38
|
readonly minItems: 1;
|
39
39
|
};
|
40
|
-
readonly
|
40
|
+
readonly requiredPattern: {
|
41
41
|
readonly items: {
|
42
42
|
readonly type: "object";
|
43
43
|
};
|
@@ -47,14 +47,14 @@ const KindToDisplayName = {
|
|
47
47
|
style: { enum: ALLOWED_STYLES },
|
48
48
|
prefix: { type: "string" },
|
49
49
|
suffix: { type: "string" },
|
50
|
-
|
50
|
+
forbiddenPattern: {
|
51
51
|
...ARRAY_DEFAULT_OPTIONS,
|
52
52
|
items: {
|
53
53
|
type: "object"
|
54
54
|
},
|
55
55
|
description: "Should be of instance of `RegEx`"
|
56
56
|
},
|
57
|
-
|
57
|
+
requiredPattern: {
|
58
58
|
...ARRAY_DEFAULT_OPTIONS,
|
59
59
|
items: {
|
60
60
|
type: "object"
|
@@ -63,19 +63,19 @@ const KindToDisplayName = {
|
|
63
63
|
},
|
64
64
|
forbiddenPrefixes: {
|
65
65
|
...ARRAY_DEFAULT_OPTIONS,
|
66
|
-
description: descriptionPrefixesSuffixes("
|
66
|
+
description: descriptionPrefixesSuffixes("forbiddenPattern")
|
67
67
|
},
|
68
68
|
forbiddenSuffixes: {
|
69
69
|
...ARRAY_DEFAULT_OPTIONS,
|
70
|
-
description: descriptionPrefixesSuffixes("
|
70
|
+
description: descriptionPrefixesSuffixes("forbiddenPattern")
|
71
71
|
},
|
72
72
|
requiredPrefixes: {
|
73
73
|
...ARRAY_DEFAULT_OPTIONS,
|
74
|
-
description: descriptionPrefixesSuffixes("
|
74
|
+
description: descriptionPrefixesSuffixes("requiredPattern")
|
75
75
|
},
|
76
76
|
requiredSuffixes: {
|
77
77
|
...ARRAY_DEFAULT_OPTIONS,
|
78
|
-
description: descriptionPrefixesSuffixes("
|
78
|
+
description: descriptionPrefixesSuffixes("requiredPattern")
|
79
79
|
},
|
80
80
|
ignorePattern: {
|
81
81
|
type: "string",
|
@@ -101,9 +101,7 @@ ${TYPES_KINDS.map((kind) => `- \`${kind}\``).join(`
|
|
101
101
|
kind,
|
102
102
|
{
|
103
103
|
...schemaOption,
|
104
|
-
description:
|
105
|
-
>
|
106
|
-
> Read more about this kind on [spec.graphql.org](https://spec.graphql.org/October2021/#${kind}).`
|
104
|
+
description: `Read more about this kind on [spec.graphql.org](https://spec.graphql.org/October2021/#${kind}).`
|
107
105
|
}
|
108
106
|
])
|
109
107
|
),
|
@@ -358,8 +356,8 @@ ${TYPES_KINDS.map((kind) => `- \`${kind}\``).join(`
|
|
358
356
|
ignorePattern,
|
359
357
|
requiredPrefixes,
|
360
358
|
requiredSuffixes,
|
361
|
-
|
362
|
-
|
359
|
+
forbiddenPattern,
|
360
|
+
requiredPattern
|
363
361
|
} = normalisePropertyOption(selector), nodeName = node.value, error = getError();
|
364
362
|
if (error) {
|
365
363
|
const { errorMessage, renameToNames } = error, [leadingUnderscores] = nodeName.match(/^_*/), [trailingUnderscores] = nodeName.match(/_*$/), suggestedNames = renameToNames.map(
|
@@ -385,15 +383,15 @@ ${TYPES_KINDS.map((kind) => `- \`${kind}\``).join(`
|
|
385
383
|
errorMessage: `have "${suffix}" suffix`,
|
386
384
|
renameToNames: [name + suffix]
|
387
385
|
};
|
388
|
-
const forbidden =
|
386
|
+
const forbidden = forbiddenPattern?.find((pattern) => pattern.test(name));
|
389
387
|
if (forbidden)
|
390
388
|
return {
|
391
389
|
errorMessage: `not contain the forbidden pattern "${forbidden}"`,
|
392
390
|
renameToNames: [name.replace(forbidden, "")]
|
393
391
|
};
|
394
|
-
if (
|
392
|
+
if (requiredPattern && !requiredPattern.some((pattern) => pattern.test(name)))
|
395
393
|
return {
|
396
|
-
errorMessage: `contain the required pattern: ${englishJoinWords(
|
394
|
+
errorMessage: `contain the required pattern: ${englishJoinWords(requiredPattern.map((re) => re.source))}`,
|
397
395
|
renameToNames: []
|
398
396
|
};
|
399
397
|
const forbiddenPrefix = forbiddenPrefixes?.find((prefix2) => name.startsWith(prefix2));
|
@@ -1,6 +1,6 @@
|
|
1
1
|
import { TypeInfo, visit, visitWithTypeInfo } from "graphql";
|
2
2
|
import { ModuleCache } from "../../cache.js";
|
3
|
-
import {
|
3
|
+
import { requireGraphQLOperations, requireGraphQLSchema } from "../../utils.js";
|
4
4
|
const RULE_ID = "no-unused-fields", RELAY_SCHEMA = (
|
5
5
|
/* GraphQL */
|
6
6
|
`
|
@@ -82,7 +82,9 @@ const RULE_ID = "no-unused-fields", RELAY_SCHEMA = (
|
|
82
82
|
"```json",
|
83
83
|
JSON.stringify(RELAY_DEFAULT_IGNORED_FIELD_SELECTORS, null, 2),
|
84
84
|
"```",
|
85
|
-
|
85
|
+
"",
|
86
|
+
"> These fields are defined by ESLint [`selectors`](https://eslint.org/docs/developer-guide/selectors).",
|
87
|
+
"> Paste or drop code into the editor in [ASTExplorer](https://astexplorer.net) and inspect the generated AST to compose your selector."
|
86
88
|
].join(`
|
87
89
|
`),
|
88
90
|
items: {
|
@@ -1,13 +1,6 @@
|
|
1
1
|
import { Kind, TokenKind } from "graphql";
|
2
2
|
import { getRootTypeNames } from "@graphql-tools/utils";
|
3
|
-
import {
|
4
|
-
ARRAY_DEFAULT_OPTIONS,
|
5
|
-
eslintSelectorsTip,
|
6
|
-
getLocation,
|
7
|
-
getNodeName,
|
8
|
-
requireGraphQLSchema,
|
9
|
-
TYPES_KINDS
|
10
|
-
} from "../../utils.js";
|
3
|
+
import { getLocation, getNodeName, requireGraphQLSchema, TYPES_KINDS } from "../../utils.js";
|
11
4
|
const RULE_ID = "require-description", ALLOWED_KINDS = [
|
12
5
|
...TYPES_KINDS,
|
13
6
|
Kind.DIRECTIVE_DEFINITION,
|
@@ -26,34 +19,18 @@ const RULE_ID = "require-description", ALLOWED_KINDS = [
|
|
26
19
|
properties: {
|
27
20
|
types: {
|
28
21
|
type: "boolean",
|
29
|
-
enum: [!0],
|
30
22
|
description: `Includes:
|
31
23
|
${TYPES_KINDS.map((kind) => `- \`${kind}\``).join(`
|
32
24
|
`)}`
|
33
25
|
},
|
34
26
|
rootField: {
|
35
27
|
type: "boolean",
|
36
|
-
enum: [!0],
|
37
28
|
description: "Definitions within `Query`, `Mutation`, and `Subscription` root types."
|
38
29
|
},
|
39
|
-
ignoredSelectors: {
|
40
|
-
...ARRAY_DEFAULT_OPTIONS,
|
41
|
-
description: ["Ignore specific selectors", eslintSelectorsTip].join(`
|
42
|
-
`)
|
43
|
-
},
|
44
30
|
...Object.fromEntries(
|
45
31
|
[...ALLOWED_KINDS].sort().map((kind) => {
|
46
|
-
let description =
|
47
|
-
>
|
48
|
-
> Read more about this kind on [spec.graphql.org](https://spec.graphql.org/October2021/#${kind}).`;
|
49
|
-
return kind === Kind.OPERATION_DEFINITION && (description += [
|
50
|
-
"",
|
51
|
-
"",
|
52
|
-
"> [!WARNING]",
|
53
|
-
">",
|
54
|
-
'> You must use only comment syntax `#` and not description syntax `"""` or `"`.'
|
55
|
-
].join(`
|
56
|
-
`)), [kind, { type: "boolean", description }];
|
32
|
+
let description = `Read more about this kind on [spec.graphql.org](https://spec.graphql.org/October2021/#${kind}).`;
|
33
|
+
return kind === Kind.OPERATION_DEFINITION && (description += '\n> You must use only comment syntax `#` and not description syntax `"""` or `"`.'), [kind, { type: "boolean", description }];
|
57
34
|
})
|
58
35
|
)
|
59
36
|
}
|
@@ -124,36 +101,6 @@ ${TYPES_KINDS.map((kind) => `- \`${kind}\``).join(`
|
|
124
101
|
}
|
125
102
|
`
|
126
103
|
)
|
127
|
-
},
|
128
|
-
{
|
129
|
-
title: "Correct",
|
130
|
-
usage: [
|
131
|
-
{
|
132
|
-
ignoredSelectors: [
|
133
|
-
"[type=ObjectTypeDefinition][name.value=PageInfo]",
|
134
|
-
"[type=ObjectTypeDefinition][name.value=/(Connection|Edge)$/]"
|
135
|
-
]
|
136
|
-
}
|
137
|
-
],
|
138
|
-
code: (
|
139
|
-
/* GraphQL */
|
140
|
-
`
|
141
|
-
type FriendConnection {
|
142
|
-
edges: [FriendEdge]
|
143
|
-
pageInfo: PageInfo!
|
144
|
-
}
|
145
|
-
type FriendEdge {
|
146
|
-
cursor: String!
|
147
|
-
node: Friend!
|
148
|
-
}
|
149
|
-
type PageInfo {
|
150
|
-
hasPreviousPage: Boolean!
|
151
|
-
hasNextPage: Boolean!
|
152
|
-
startCursor: String
|
153
|
-
endCursor: String
|
154
|
-
}
|
155
|
-
`
|
156
|
-
)
|
157
104
|
}
|
158
105
|
],
|
159
106
|
configOptions: [
|
@@ -172,7 +119,7 @@ ${TYPES_KINDS.map((kind) => `- \`${kind}\``).join(`
|
|
172
119
|
schema
|
173
120
|
},
|
174
121
|
create(context) {
|
175
|
-
const { types, rootField,
|
122
|
+
const { types, rootField, ...restOptions } = context.options[0] || {}, kinds = new Set(types ? TYPES_KINDS : []);
|
176
123
|
for (const [kind, isEnabled] of Object.entries(restOptions))
|
177
124
|
isEnabled ? kinds.add(kind) : kinds.delete(kind);
|
178
125
|
if (rootField) {
|
@@ -183,11 +130,10 @@ ${TYPES_KINDS.map((kind) => `- \`${kind}\``).join(`
|
|
183
130
|
].join(",")})$/] > FieldDefinition`
|
184
131
|
);
|
185
132
|
}
|
186
|
-
|
187
|
-
|
188
|
-
selector += `:not(${str})`;
|
133
|
+
if (!kinds.size)
|
134
|
+
throw new Error("At least one kind must be enabled");
|
189
135
|
return {
|
190
|
-
[
|
136
|
+
[[...kinds].join(",")](node) {
|
191
137
|
let description = "";
|
192
138
|
const isOperation = node.kind === Kind.OPERATION_DEFINITION;
|
193
139
|
if (isOperation) {
|
package/esm/utils.d.ts
CHANGED
@@ -41,6 +41,5 @@ type Truthy<T> = T extends '' | 0 | false | null | undefined ? never : T;
|
|
41
41
|
declare function truthy<T>(value: T): value is Truthy<T>;
|
42
42
|
declare function displayNodeName(node: GraphQLESTreeNode<ASTNode, boolean>): string;
|
43
43
|
declare function getNodeName(node: GraphQLESTreeNode<ASTNode>): string;
|
44
|
-
declare const eslintSelectorsTip = "> [!TIP]\n>\n> These fields are defined by ESLint [`selectors`](https://eslint.org/docs/developer-guide/selectors).\n> Paste or drop code into the editor in [ASTExplorer](https://astexplorer.net) and inspect the generated AST to compose your selector.";
|
45
44
|
|
46
|
-
export { ARRAY_DEFAULT_OPTIONS, CWD, type CaseStyle, REPORT_ON_FIRST_CHARACTER, TYPES_KINDS, VIRTUAL_DOCUMENT_REGEX, camelCase, convertCase, displayNodeName, englishJoinWords,
|
45
|
+
export { ARRAY_DEFAULT_OPTIONS, CWD, type CaseStyle, REPORT_ON_FIRST_CHARACTER, TYPES_KINDS, VIRTUAL_DOCUMENT_REGEX, camelCase, convertCase, displayNodeName, englishJoinWords, getLocation, getNodeName, getTypeName, logger, pascalCase, requireGraphQLOperations, requireGraphQLSchema, slash, truthy };
|
package/esm/utils.js
CHANGED
@@ -144,10 +144,6 @@ function getNodeName(node) {
|
|
144
144
|
}
|
145
145
|
return "";
|
146
146
|
}
|
147
|
-
const eslintSelectorsTip = `> [!TIP]
|
148
|
-
>
|
149
|
-
> These fields are defined by ESLint [\`selectors\`](https://eslint.org/docs/developer-guide/selectors).
|
150
|
-
> Paste or drop code into the editor in [ASTExplorer](https://astexplorer.net) and inspect the generated AST to compose your selector.`;
|
151
147
|
export {
|
152
148
|
ARRAY_DEFAULT_OPTIONS,
|
153
149
|
CWD,
|
@@ -158,7 +154,6 @@ export {
|
|
158
154
|
convertCase,
|
159
155
|
displayNodeName,
|
160
156
|
englishJoinWords,
|
161
|
-
eslintSelectorsTip,
|
162
157
|
getLocation,
|
163
158
|
getNodeName,
|
164
159
|
getTypeName,
|
package/index.browser.js
CHANGED
@@ -150,7 +150,7 @@ function convertToESTree(node, schema16) {
|
|
150
150
|
}
|
151
151
|
|
152
152
|
// src/meta.ts
|
153
|
-
var version = "4.1.0-alpha-
|
153
|
+
var version = "4.1.0-alpha-20241129085030-b075ada387ad44de7944517af78877c45bc8fd3b";
|
154
154
|
|
155
155
|
// src/siblings.ts
|
156
156
|
import {
|
@@ -305,10 +305,6 @@ function getNodeName(node) {
|
|
305
305
|
}
|
306
306
|
return "";
|
307
307
|
}
|
308
|
-
var eslintSelectorsTip = `> [!TIP]
|
309
|
-
>
|
310
|
-
> These fields are defined by ESLint [\`selectors\`](https://eslint.org/docs/developer-guide/selectors).
|
311
|
-
> Paste or drop code into the editor in [ASTExplorer](https://astexplorer.net) and inspect the generated AST to compose your selector.`;
|
312
308
|
|
313
309
|
// src/siblings.ts
|
314
310
|
var siblingOperationsCache = /* @__PURE__ */ new Map();
|
@@ -1938,14 +1934,14 @@ var KindToDisplayName = {
|
|
1938
1934
|
style: { enum: ALLOWED_STYLES },
|
1939
1935
|
prefix: { type: "string" },
|
1940
1936
|
suffix: { type: "string" },
|
1941
|
-
|
1937
|
+
forbiddenPattern: {
|
1942
1938
|
...ARRAY_DEFAULT_OPTIONS,
|
1943
1939
|
items: {
|
1944
1940
|
type: "object"
|
1945
1941
|
},
|
1946
1942
|
description: "Should be of instance of `RegEx`"
|
1947
1943
|
},
|
1948
|
-
|
1944
|
+
requiredPattern: {
|
1949
1945
|
...ARRAY_DEFAULT_OPTIONS,
|
1950
1946
|
items: {
|
1951
1947
|
type: "object"
|
@@ -1954,19 +1950,19 @@ var KindToDisplayName = {
|
|
1954
1950
|
},
|
1955
1951
|
forbiddenPrefixes: {
|
1956
1952
|
...ARRAY_DEFAULT_OPTIONS,
|
1957
|
-
description: descriptionPrefixesSuffixes("
|
1953
|
+
description: descriptionPrefixesSuffixes("forbiddenPattern")
|
1958
1954
|
},
|
1959
1955
|
forbiddenSuffixes: {
|
1960
1956
|
...ARRAY_DEFAULT_OPTIONS,
|
1961
|
-
description: descriptionPrefixesSuffixes("
|
1957
|
+
description: descriptionPrefixesSuffixes("forbiddenPattern")
|
1962
1958
|
},
|
1963
1959
|
requiredPrefixes: {
|
1964
1960
|
...ARRAY_DEFAULT_OPTIONS,
|
1965
|
-
description: descriptionPrefixesSuffixes("
|
1961
|
+
description: descriptionPrefixesSuffixes("requiredPattern")
|
1966
1962
|
},
|
1967
1963
|
requiredSuffixes: {
|
1968
1964
|
...ARRAY_DEFAULT_OPTIONS,
|
1969
|
-
description: descriptionPrefixesSuffixes("
|
1965
|
+
description: descriptionPrefixesSuffixes("requiredPattern")
|
1970
1966
|
},
|
1971
1967
|
ignorePattern: {
|
1972
1968
|
type: "string",
|
@@ -1992,9 +1988,7 @@ ${TYPES_KINDS.map((kind) => `- \`${kind}\``).join(`
|
|
1992
1988
|
kind,
|
1993
1989
|
{
|
1994
1990
|
...schemaOption2,
|
1995
|
-
description:
|
1996
|
-
>
|
1997
|
-
> Read more about this kind on [spec.graphql.org](https://spec.graphql.org/October2021/#${kind}).`
|
1991
|
+
description: `Read more about this kind on [spec.graphql.org](https://spec.graphql.org/October2021/#${kind}).`
|
1998
1992
|
}
|
1999
1993
|
])
|
2000
1994
|
),
|
@@ -2249,8 +2243,8 @@ ${TYPES_KINDS.map((kind) => `- \`${kind}\``).join(`
|
|
2249
2243
|
ignorePattern,
|
2250
2244
|
requiredPrefixes,
|
2251
2245
|
requiredSuffixes,
|
2252
|
-
|
2253
|
-
|
2246
|
+
forbiddenPattern,
|
2247
|
+
requiredPattern
|
2254
2248
|
} = normalisePropertyOption(selector), nodeName = node.value, error = getError();
|
2255
2249
|
if (error) {
|
2256
2250
|
let { errorMessage, renameToNames } = error, [leadingUnderscores] = nodeName.match(/^_*/), [trailingUnderscores] = nodeName.match(/_*$/), suggestedNames = renameToNames.map(
|
@@ -2276,15 +2270,15 @@ ${TYPES_KINDS.map((kind) => `- \`${kind}\``).join(`
|
|
2276
2270
|
errorMessage: `have "${suffix}" suffix`,
|
2277
2271
|
renameToNames: [name + suffix]
|
2278
2272
|
};
|
2279
|
-
let forbidden =
|
2273
|
+
let forbidden = forbiddenPattern?.find((pattern) => pattern.test(name));
|
2280
2274
|
if (forbidden)
|
2281
2275
|
return {
|
2282
2276
|
errorMessage: `not contain the forbidden pattern "${forbidden}"`,
|
2283
2277
|
renameToNames: [name.replace(forbidden, "")]
|
2284
2278
|
};
|
2285
|
-
if (
|
2279
|
+
if (requiredPattern && !requiredPattern.some((pattern) => pattern.test(name)))
|
2286
2280
|
return {
|
2287
|
-
errorMessage: `contain the required pattern: ${englishJoinWords(
|
2281
|
+
errorMessage: `contain the required pattern: ${englishJoinWords(requiredPattern.map((re) => re.source))}`,
|
2288
2282
|
renameToNames: []
|
2289
2283
|
};
|
2290
2284
|
let forbiddenPrefix = forbiddenPrefixes?.find((prefix2) => name.startsWith(prefix2));
|
@@ -3287,7 +3281,9 @@ var RULE_ID10 = "no-unused-fields", RELAY_SCHEMA = (
|
|
3287
3281
|
"```json",
|
3288
3282
|
JSON.stringify(RELAY_DEFAULT_IGNORED_FIELD_SELECTORS, null, 2),
|
3289
3283
|
"```",
|
3290
|
-
|
3284
|
+
"",
|
3285
|
+
"> These fields are defined by ESLint [`selectors`](https://eslint.org/docs/developer-guide/selectors).",
|
3286
|
+
"> Paste or drop code into the editor in [ASTExplorer](https://astexplorer.net) and inspect the generated AST to compose your selector."
|
3291
3287
|
].join(`
|
3292
3288
|
`),
|
3293
3289
|
items: {
|
@@ -4037,34 +4033,18 @@ var RULE_ID14 = "require-description", ALLOWED_KINDS2 = [
|
|
4037
4033
|
properties: {
|
4038
4034
|
types: {
|
4039
4035
|
type: "boolean",
|
4040
|
-
enum: [!0],
|
4041
4036
|
description: `Includes:
|
4042
4037
|
${TYPES_KINDS.map((kind) => `- \`${kind}\``).join(`
|
4043
4038
|
`)}`
|
4044
4039
|
},
|
4045
4040
|
rootField: {
|
4046
4041
|
type: "boolean",
|
4047
|
-
enum: [!0],
|
4048
4042
|
description: "Definitions within `Query`, `Mutation`, and `Subscription` root types."
|
4049
4043
|
},
|
4050
|
-
ignoredSelectors: {
|
4051
|
-
...ARRAY_DEFAULT_OPTIONS,
|
4052
|
-
description: ["Ignore specific selectors", eslintSelectorsTip].join(`
|
4053
|
-
`)
|
4054
|
-
},
|
4055
4044
|
...Object.fromEntries(
|
4056
4045
|
[...ALLOWED_KINDS2].sort().map((kind) => {
|
4057
|
-
let description =
|
4058
|
-
>
|
4059
|
-
> Read more about this kind on [spec.graphql.org](https://spec.graphql.org/October2021/#${kind}).`;
|
4060
|
-
return kind === Kind17.OPERATION_DEFINITION && (description += [
|
4061
|
-
"",
|
4062
|
-
"",
|
4063
|
-
"> [!WARNING]",
|
4064
|
-
">",
|
4065
|
-
'> You must use only comment syntax `#` and not description syntax `"""` or `"`.'
|
4066
|
-
].join(`
|
4067
|
-
`)), [kind, { type: "boolean", description }];
|
4046
|
+
let description = `Read more about this kind on [spec.graphql.org](https://spec.graphql.org/October2021/#${kind}).`;
|
4047
|
+
return kind === Kind17.OPERATION_DEFINITION && (description += '\n> You must use only comment syntax `#` and not description syntax `"""` or `"`.'), [kind, { type: "boolean", description }];
|
4068
4048
|
})
|
4069
4049
|
)
|
4070
4050
|
}
|
@@ -4135,36 +4115,6 @@ ${TYPES_KINDS.map((kind) => `- \`${kind}\``).join(`
|
|
4135
4115
|
}
|
4136
4116
|
`
|
4137
4117
|
)
|
4138
|
-
},
|
4139
|
-
{
|
4140
|
-
title: "Correct",
|
4141
|
-
usage: [
|
4142
|
-
{
|
4143
|
-
ignoredSelectors: [
|
4144
|
-
"[type=ObjectTypeDefinition][name.value=PageInfo]",
|
4145
|
-
"[type=ObjectTypeDefinition][name.value=/(Connection|Edge)$/]"
|
4146
|
-
]
|
4147
|
-
}
|
4148
|
-
],
|
4149
|
-
code: (
|
4150
|
-
/* GraphQL */
|
4151
|
-
`
|
4152
|
-
type FriendConnection {
|
4153
|
-
edges: [FriendEdge]
|
4154
|
-
pageInfo: PageInfo!
|
4155
|
-
}
|
4156
|
-
type FriendEdge {
|
4157
|
-
cursor: String!
|
4158
|
-
node: Friend!
|
4159
|
-
}
|
4160
|
-
type PageInfo {
|
4161
|
-
hasPreviousPage: Boolean!
|
4162
|
-
hasNextPage: Boolean!
|
4163
|
-
startCursor: String
|
4164
|
-
endCursor: String
|
4165
|
-
}
|
4166
|
-
`
|
4167
|
-
)
|
4168
4118
|
}
|
4169
4119
|
],
|
4170
4120
|
configOptions: [
|
@@ -4183,7 +4133,7 @@ ${TYPES_KINDS.map((kind) => `- \`${kind}\``).join(`
|
|
4183
4133
|
schema: schema12
|
4184
4134
|
},
|
4185
4135
|
create(context) {
|
4186
|
-
let { types, rootField,
|
4136
|
+
let { types, rootField, ...restOptions } = context.options[0] || {}, kinds = new Set(types ? TYPES_KINDS : []);
|
4187
4137
|
for (let [kind, isEnabled] of Object.entries(restOptions))
|
4188
4138
|
isEnabled ? kinds.add(kind) : kinds.delete(kind);
|
4189
4139
|
if (rootField) {
|
@@ -4194,11 +4144,10 @@ ${TYPES_KINDS.map((kind) => `- \`${kind}\``).join(`
|
|
4194
4144
|
].join(",")})$/] > FieldDefinition`
|
4195
4145
|
);
|
4196
4146
|
}
|
4197
|
-
|
4198
|
-
|
4199
|
-
selector += `:not(${str})`;
|
4147
|
+
if (!kinds.size)
|
4148
|
+
throw new Error("At least one kind must be enabled");
|
4200
4149
|
return {
|
4201
|
-
[
|
4150
|
+
[[...kinds].join(",")](node) {
|
4202
4151
|
let description = "", isOperation = node.kind === Kind17.OPERATION_DEFINITION;
|
4203
4152
|
if (isOperation) {
|
4204
4153
|
let rawNode = node.rawNode(), { prev, line } = rawNode.loc.startToken;
|
package/package.json
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
{
|
2
2
|
"name": "@graphql-eslint/eslint-plugin",
|
3
|
-
"version": "4.1.0-alpha-
|
3
|
+
"version": "4.1.0-alpha-20241129085030-b075ada387ad44de7944517af78877c45bc8fd3b",
|
4
4
|
"type": "module",
|
5
5
|
"description": "GraphQL plugin for ESLint",
|
6
6
|
"repository": "https://github.com/dimaMachina/graphql-eslint",
|
@@ -31,7 +31,13 @@
|
|
31
31
|
],
|
32
32
|
"peerDependencies": {
|
33
33
|
"eslint": ">=8.44.0",
|
34
|
-
"graphql": "^16"
|
34
|
+
"graphql": "^16",
|
35
|
+
"json-schema-to-ts": "^3"
|
36
|
+
},
|
37
|
+
"peerDependenciesMeta": {
|
38
|
+
"json-schema-to-ts": {
|
39
|
+
"optional": true
|
40
|
+
}
|
35
41
|
},
|
36
42
|
"dependencies": {
|
37
43
|
"@graphql-tools/code-file-loader": "^8.0.0",
|