@zgeoff/oxlint-config 0.0.3 → 0.0.5
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/README.md +23 -2
- package/function-verb.js +218 -0
- package/oxlintrc.json +4 -1
- package/package.json +9 -1
- package/plugin.js +94 -13
package/README.md
CHANGED
|
@@ -2,9 +2,11 @@
|
|
|
2
2
|
|
|
3
3
|
Shareable [oxlint](https://oxc.rs/docs/guide/usage/linter.html) config: every category at `error`,
|
|
4
4
|
restriction-rule cherry-picks, comment-style enforcement via `@stylistic`, and a bundled JS plugin
|
|
5
|
-
(`zgeoff/*` rules) banning
|
|
5
|
+
(`zgeoff/*` rules) banning shapes no native oxlint rule can express — top-level arrows, nested
|
|
6
6
|
function declarations, bare named exports, destructured and inline-typed parameters, ternary and
|
|
7
|
-
await arguments,
|
|
7
|
+
await arguments, awaits hidden inside a control-flow condition or a `&&`/`||`/`??` chain, and
|
|
8
|
+
single-line `/** … */` blocks (auto-fixed to multi-line; inline `@type`/`@lends` casts exempt).
|
|
9
|
+
`zgeoff/function-verb` enforces the function-naming taxonomy from the shared agent guidelines.
|
|
8
10
|
|
|
9
11
|
## Usage
|
|
10
12
|
|
|
@@ -33,6 +35,25 @@ import config from '@zgeoff/oxlint-config';
|
|
|
33
35
|
The plugin is addressable on its own at `@zgeoff/oxlint-config/plugin` for configs that want the
|
|
34
36
|
`zgeoff/*` rules without the rest.
|
|
35
37
|
|
|
38
|
+
## `zgeoff/function-verb`
|
|
39
|
+
|
|
40
|
+
Every function declaration, function-valued variable, and class method must start with a verb from
|
|
41
|
+
the function-naming taxonomy. Banned verbs report their taxonomy replacement (`fetchUser` → use
|
|
42
|
+
`read`). Object-literal properties are exempt — they overwhelmingly implement externally-defined
|
|
43
|
+
shapes whose names the author doesn't choose — as are names not starting with a lowercase letter.
|
|
44
|
+
Exempt an algorithm-native name (`walk`, `backtrack`) with a disable comment in the module
|
|
45
|
+
implementing that algorithm.
|
|
46
|
+
|
|
47
|
+
Options extend the shipped set per repo:
|
|
48
|
+
|
|
49
|
+
```jsonc
|
|
50
|
+
{
|
|
51
|
+
"rules": {
|
|
52
|
+
"zgeoff/function-verb": ["error", { "verbs": ["walk"], "exemptNames": ["main"] }],
|
|
53
|
+
},
|
|
54
|
+
}
|
|
55
|
+
```
|
|
56
|
+
|
|
36
57
|
## Notes
|
|
37
58
|
|
|
38
59
|
- The config enables the `typescript`, `unicorn`, `oxc`, `import`, and `promise` plugins and loads
|
package/function-verb.js
ADDED
|
@@ -0,0 +1,218 @@
|
|
|
1
|
+
// the closed verb list from the shared function-naming taxonomy, one entry
|
|
2
|
+
// per table row; extending it here without the matching taxonomy edit fails
|
|
3
|
+
// the drift-guard test
|
|
4
|
+
const taxonomyVerbs = [
|
|
5
|
+
'is',
|
|
6
|
+
'has',
|
|
7
|
+
'can',
|
|
8
|
+
'should',
|
|
9
|
+
'needs',
|
|
10
|
+
'build',
|
|
11
|
+
'define',
|
|
12
|
+
'parse',
|
|
13
|
+
'encode',
|
|
14
|
+
'decode',
|
|
15
|
+
'derive',
|
|
16
|
+
'plan',
|
|
17
|
+
'pick',
|
|
18
|
+
'find',
|
|
19
|
+
'get',
|
|
20
|
+
'collect',
|
|
21
|
+
'count',
|
|
22
|
+
'split',
|
|
23
|
+
'merge',
|
|
24
|
+
'sort',
|
|
25
|
+
'format',
|
|
26
|
+
'render',
|
|
27
|
+
'normalize',
|
|
28
|
+
'resolve',
|
|
29
|
+
'expand',
|
|
30
|
+
'compress',
|
|
31
|
+
'decompress',
|
|
32
|
+
'to',
|
|
33
|
+
'transform',
|
|
34
|
+
'apply',
|
|
35
|
+
'create',
|
|
36
|
+
'claim',
|
|
37
|
+
'read',
|
|
38
|
+
'load',
|
|
39
|
+
'write',
|
|
40
|
+
'remove',
|
|
41
|
+
'update',
|
|
42
|
+
'upsert',
|
|
43
|
+
'set',
|
|
44
|
+
'toggle',
|
|
45
|
+
'reset',
|
|
46
|
+
'print',
|
|
47
|
+
'run',
|
|
48
|
+
'check',
|
|
49
|
+
'try',
|
|
50
|
+
'register',
|
|
51
|
+
'subscribe',
|
|
52
|
+
'unsubscribe',
|
|
53
|
+
'assert',
|
|
54
|
+
'require',
|
|
55
|
+
'verify',
|
|
56
|
+
'emit',
|
|
57
|
+
'send',
|
|
58
|
+
'wait',
|
|
59
|
+
'setup',
|
|
60
|
+
'teardown',
|
|
61
|
+
'start',
|
|
62
|
+
'stop',
|
|
63
|
+
'drain',
|
|
64
|
+
'with',
|
|
65
|
+
'make',
|
|
66
|
+
'use',
|
|
67
|
+
'on',
|
|
68
|
+
'handle',
|
|
69
|
+
];
|
|
70
|
+
|
|
71
|
+
// the templated taxonomy entries (`with<X>`, `handle<Event>`, …): the verb is
|
|
72
|
+
// only valid with a suffix, so the bare word is not a function name
|
|
73
|
+
const suffixRequiredVerbs = new Set([
|
|
74
|
+
'build',
|
|
75
|
+
'define',
|
|
76
|
+
'to',
|
|
77
|
+
'toggle',
|
|
78
|
+
'try',
|
|
79
|
+
'with',
|
|
80
|
+
'make',
|
|
81
|
+
'use',
|
|
82
|
+
'on',
|
|
83
|
+
'handle',
|
|
84
|
+
]);
|
|
85
|
+
|
|
86
|
+
// banned verb → the taxonomy verb to use instead; null means the verb is too
|
|
87
|
+
// vague to map and the name should say what the function does
|
|
88
|
+
const bannedVerbs = new Map([
|
|
89
|
+
['process', null],
|
|
90
|
+
['manage', null],
|
|
91
|
+
['do', null],
|
|
92
|
+
['perform', null],
|
|
93
|
+
['execute', 'run'],
|
|
94
|
+
['compute', 'build'],
|
|
95
|
+
['fetch', 'read'],
|
|
96
|
+
['save', 'write'],
|
|
97
|
+
['store', 'write'],
|
|
98
|
+
['delete', 'remove'],
|
|
99
|
+
['search', 'find'],
|
|
100
|
+
['lookup', 'find'],
|
|
101
|
+
]);
|
|
102
|
+
|
|
103
|
+
function isVerbMatch(name, verb, bareAllowed) {
|
|
104
|
+
if (name === verb) {
|
|
105
|
+
return bareAllowed;
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
return name.startsWith(verb) && /[A-Z]/u.test(name.charAt(verb.length));
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
function findAllowedVerb(name, verbs) {
|
|
112
|
+
return verbs.find((verb) => isVerbMatch(name, verb, !suffixRequiredVerbs.has(verb))) ?? null;
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
function findBannedVerb(name) {
|
|
116
|
+
for (const [verb, replacement] of bannedVerbs) {
|
|
117
|
+
if (isVerbMatch(name, verb, true)) {
|
|
118
|
+
return { verb, replacement };
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
return null;
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
function planReport(name, verbs, exemptNames) {
|
|
126
|
+
if (exemptNames.has(name) || !/^[a-z]/u.test(name)) {
|
|
127
|
+
return null;
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
if (findAllowedVerb(name, verbs) !== null) {
|
|
131
|
+
return null;
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
const banned = findBannedVerb(name);
|
|
135
|
+
|
|
136
|
+
if (banned === null) {
|
|
137
|
+
return { messageId: 'unknownVerb', data: { name } };
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
if (banned.replacement === null) {
|
|
141
|
+
return { messageId: 'vagueVerb', data: { name, verb: banned.verb } };
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
return {
|
|
145
|
+
messageId: 'bannedVerb',
|
|
146
|
+
data: { name, verb: banned.verb, replacement: banned.replacement },
|
|
147
|
+
};
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
/**
|
|
151
|
+
* Enforces the function-naming taxonomy on function declarations,
|
|
152
|
+
* function-valued variables, and class methods. Object-literal properties are
|
|
153
|
+
* exempt — they overwhelmingly implement externally-defined shapes (rule
|
|
154
|
+
* visitors, route tables) whose names the author doesn't choose — as are
|
|
155
|
+
* names not starting with a lowercase letter (components, classes).
|
|
156
|
+
* Options: `verbs` appends repo-local verbs to the shipped taxonomy;
|
|
157
|
+
* `exemptNames` skips exact names.
|
|
158
|
+
*/
|
|
159
|
+
const functionVerb = {
|
|
160
|
+
meta: {
|
|
161
|
+
type: 'suggestion',
|
|
162
|
+
messages: {
|
|
163
|
+
unknownVerb:
|
|
164
|
+
"'{{name}}' does not start with a taxonomy verb — pick one, or extend the taxonomy and the `verbs` option in the same PR.",
|
|
165
|
+
bannedVerb: "'{{name}}' starts with the banned verb '{{verb}}' — use `{{replacement}}`.",
|
|
166
|
+
vagueVerb: "'{{name}}' starts with the banned verb '{{verb}}' — name what the function does.",
|
|
167
|
+
},
|
|
168
|
+
schema: [
|
|
169
|
+
{
|
|
170
|
+
type: 'object',
|
|
171
|
+
properties: {
|
|
172
|
+
verbs: { type: 'array', items: { type: 'string' }, uniqueItems: true },
|
|
173
|
+
exemptNames: { type: 'array', items: { type: 'string' }, uniqueItems: true },
|
|
174
|
+
},
|
|
175
|
+
additionalProperties: false,
|
|
176
|
+
},
|
|
177
|
+
],
|
|
178
|
+
},
|
|
179
|
+
create(context) {
|
|
180
|
+
const options = context.options[0] ?? {};
|
|
181
|
+
const verbs =
|
|
182
|
+
options.verbs === undefined ? taxonomyVerbs : [...taxonomyVerbs, ...options.verbs];
|
|
183
|
+
const exemptNames = new Set(options.exemptNames);
|
|
184
|
+
|
|
185
|
+
const checkName = (id) => {
|
|
186
|
+
const report = planReport(id.name, verbs, exemptNames);
|
|
187
|
+
|
|
188
|
+
if (report !== null) {
|
|
189
|
+
context.report({ node: id, messageId: report.messageId, data: report.data });
|
|
190
|
+
}
|
|
191
|
+
};
|
|
192
|
+
|
|
193
|
+
return {
|
|
194
|
+
FunctionDeclaration(node) {
|
|
195
|
+
if (node.id !== null) {
|
|
196
|
+
checkName(node.id);
|
|
197
|
+
}
|
|
198
|
+
},
|
|
199
|
+
VariableDeclarator(node) {
|
|
200
|
+
const isFunctionInit =
|
|
201
|
+
node.init !== null &&
|
|
202
|
+
node.init !== undefined &&
|
|
203
|
+
(node.init.type === 'ArrowFunctionExpression' || node.init.type === 'FunctionExpression');
|
|
204
|
+
|
|
205
|
+
if (isFunctionInit && node.id.type === 'Identifier') {
|
|
206
|
+
checkName(node.id);
|
|
207
|
+
}
|
|
208
|
+
},
|
|
209
|
+
MethodDefinition(node) {
|
|
210
|
+
if (node.kind === 'method' && !node.computed && node.key.type === 'Identifier') {
|
|
211
|
+
checkName(node.key);
|
|
212
|
+
}
|
|
213
|
+
},
|
|
214
|
+
};
|
|
215
|
+
},
|
|
216
|
+
};
|
|
217
|
+
|
|
218
|
+
export default functionVerb;
|
package/oxlintrc.json
CHANGED
|
@@ -25,6 +25,8 @@
|
|
|
25
25
|
"zgeoff/no-await-args": "error",
|
|
26
26
|
"zgeoff/no-await-in-condition": "error",
|
|
27
27
|
"zgeoff/no-await-in-logical": "error",
|
|
28
|
+
"zgeoff/no-single-line-jsdoc": "error",
|
|
29
|
+
"zgeoff/function-verb": "error",
|
|
28
30
|
|
|
29
31
|
// enforced comment style — line comments unless JSDoc or exclamation
|
|
30
32
|
"@stylistic/multiline-comment-style": [
|
|
@@ -142,8 +144,9 @@
|
|
|
142
144
|
{
|
|
143
145
|
"files": ["**/*.js", "**/*.cjs", "**/*.mjs"],
|
|
144
146
|
// untyped JS is `any` end to end, so the unsafe-* rules flag every
|
|
145
|
-
// expression
|
|
147
|
+
// expression and strict-boolean-expressions every conditional
|
|
146
148
|
"rules": {
|
|
149
|
+
"typescript/strict-boolean-expressions": "off",
|
|
147
150
|
"typescript/no-unsafe-argument": "off",
|
|
148
151
|
"typescript/no-unsafe-assignment": "off",
|
|
149
152
|
"typescript/no-unsafe-call": "off",
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@zgeoff/oxlint-config",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.5",
|
|
4
4
|
"description": "Shareable oxlint config: strict categories, house-style rules, and a custom JS plugin",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"repository": {
|
|
@@ -11,6 +11,7 @@
|
|
|
11
11
|
"files": [
|
|
12
12
|
"oxlintrc.json",
|
|
13
13
|
"plugin.js",
|
|
14
|
+
"function-verb.js",
|
|
14
15
|
"index.js"
|
|
15
16
|
],
|
|
16
17
|
"type": "module",
|
|
@@ -22,9 +23,16 @@
|
|
|
22
23
|
"publishConfig": {
|
|
23
24
|
"access": "public"
|
|
24
25
|
},
|
|
26
|
+
"scripts": {
|
|
27
|
+
"typecheck": "tsc"
|
|
28
|
+
},
|
|
25
29
|
"dependencies": {
|
|
26
30
|
"@stylistic/eslint-plugin": "5.10.0"
|
|
27
31
|
},
|
|
32
|
+
"devDependencies": {
|
|
33
|
+
"@types/bun": "1.3.14",
|
|
34
|
+
"typescript": "7.0.1-rc"
|
|
35
|
+
},
|
|
28
36
|
"peerDependencies": {
|
|
29
37
|
"oxlint": ">=1.71.0"
|
|
30
38
|
}
|
package/plugin.js
CHANGED
|
@@ -1,8 +1,11 @@
|
|
|
1
|
+
import functionVerb from './function-verb.js';
|
|
2
|
+
|
|
1
3
|
// Custom lint rules, loaded through oxlint's jsPlugins (ESLint v9 rule API).
|
|
2
|
-
// Each rule bans
|
|
3
|
-
//
|
|
4
|
+
// Each rule bans a shape no native oxlint rule can express — esquery selectors
|
|
5
|
+
// for AST shapes, a source-comment scan where the target isn't
|
|
6
|
+
// esquery-selectable.
|
|
4
7
|
|
|
5
|
-
function
|
|
8
|
+
function buildBanRule(type, message, selectors) {
|
|
6
9
|
return {
|
|
7
10
|
meta: { type, messages: { banned: message }, schema: [] },
|
|
8
11
|
create(context) {
|
|
@@ -16,10 +19,86 @@ function banSelectors(type, message, selectors) {
|
|
|
16
19
|
};
|
|
17
20
|
}
|
|
18
21
|
|
|
22
|
+
// mirrors eslint-plugin-jsdoc's default singleLineTags: blocks that exist to
|
|
23
|
+
// cast inline (`/** @type {Foo} */ (bar)`) stay single-line by design
|
|
24
|
+
const inlineTagPattern = /^@(?:type|lends)\b/u;
|
|
25
|
+
|
|
26
|
+
function isSingleLineJSDoc(comment) {
|
|
27
|
+
return (
|
|
28
|
+
comment.type === 'Block' &&
|
|
29
|
+
comment.value.startsWith('*') &&
|
|
30
|
+
comment.loc.start.line === comment.loc.end.line
|
|
31
|
+
);
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
/**
|
|
35
|
+
* Builds the multi-line replacement for a single-line JSDoc comment, or null
|
|
36
|
+
* when the comment shares its line with code — expanding those in place would
|
|
37
|
+
* scramble the surrounding statement, so they are reported without a fix.
|
|
38
|
+
*/
|
|
39
|
+
function planExpansion(text, comment) {
|
|
40
|
+
if (!isOwnLine(text, comment)) {
|
|
41
|
+
return null;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
const lineStart = text.lastIndexOf('\n', comment.range[0] - 1) + 1;
|
|
45
|
+
const indent = text.slice(lineStart, comment.range[0]);
|
|
46
|
+
const body = comment.value.slice(1).trim();
|
|
47
|
+
const bodyLine = body === '' ? `${indent} *` : `${indent} * ${body}`;
|
|
48
|
+
|
|
49
|
+
return `/**\n${bodyLine}\n${indent} */`;
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
function isOwnLine(text, comment) {
|
|
53
|
+
const [start, end] = comment.range;
|
|
54
|
+
const lineStart = text.lastIndexOf('\n', start - 1) + 1;
|
|
55
|
+
const lineEnd = text.indexOf('\n', end);
|
|
56
|
+
const sliceEnd = lineEnd === -1 ? text.length : lineEnd;
|
|
57
|
+
|
|
58
|
+
return /^[ \t]*$/u.test(text.slice(lineStart, start)) && text.slice(end, sliceEnd).trim() === '';
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
const noSingleLineJSDoc = {
|
|
62
|
+
meta: {
|
|
63
|
+
type: 'layout',
|
|
64
|
+
fixable: 'whitespace',
|
|
65
|
+
messages: {
|
|
66
|
+
singleLine:
|
|
67
|
+
'Write JSDoc blocks multi-line: `/**` alone, one `*`-prefixed line per point, `*/` alone.',
|
|
68
|
+
},
|
|
69
|
+
schema: [],
|
|
70
|
+
},
|
|
71
|
+
create(context) {
|
|
72
|
+
return {
|
|
73
|
+
Program() {
|
|
74
|
+
const offenders = context.sourceCode
|
|
75
|
+
.getAllComments()
|
|
76
|
+
.filter(
|
|
77
|
+
(comment) =>
|
|
78
|
+
isSingleLineJSDoc(comment) && !inlineTagPattern.test(comment.value.slice(1).trim()),
|
|
79
|
+
);
|
|
80
|
+
|
|
81
|
+
for (const comment of offenders) {
|
|
82
|
+
const replacement = planExpansion(context.sourceCode.text, comment);
|
|
83
|
+
|
|
84
|
+
context.report({
|
|
85
|
+
loc: comment.loc,
|
|
86
|
+
messageId: 'singleLine',
|
|
87
|
+
fix:
|
|
88
|
+
replacement === null
|
|
89
|
+
? undefined
|
|
90
|
+
: (fixer) => fixer.replaceTextRange(comment.range, replacement),
|
|
91
|
+
});
|
|
92
|
+
}
|
|
93
|
+
},
|
|
94
|
+
};
|
|
95
|
+
},
|
|
96
|
+
};
|
|
97
|
+
|
|
19
98
|
const plugin = {
|
|
20
99
|
meta: { name: 'zgeoff' },
|
|
21
100
|
rules: {
|
|
22
|
-
'no-top-level-arrow':
|
|
101
|
+
'no-top-level-arrow': buildBanRule(
|
|
23
102
|
'problem',
|
|
24
103
|
'Declare top-level functions with the `function` keyword instead of assigning an arrow function.',
|
|
25
104
|
[
|
|
@@ -29,19 +108,19 @@ const plugin = {
|
|
|
29
108
|
"Program > ExpressionStatement > AssignmentExpression[right.type='ArrowFunctionExpression']",
|
|
30
109
|
],
|
|
31
110
|
),
|
|
32
|
-
'no-nested-function-declaration':
|
|
111
|
+
'no-nested-function-declaration': buildBanRule(
|
|
33
112
|
'problem',
|
|
34
113
|
'Use an arrow function here; reserve the `function` keyword for top-level declarations.',
|
|
35
114
|
[
|
|
36
115
|
'FunctionDeclaration:not(Program > FunctionDeclaration):not(Program > ExportNamedDeclaration > FunctionDeclaration):not(Program > ExportDefaultDeclaration > FunctionDeclaration)',
|
|
37
116
|
],
|
|
38
117
|
),
|
|
39
|
-
'no-bare-named-exports':
|
|
118
|
+
'no-bare-named-exports': buildBanRule(
|
|
40
119
|
'problem',
|
|
41
120
|
'Export declarations inline instead of listing names in `export { ... }`.',
|
|
42
121
|
['ExportNamedDeclaration[specifiers.length>0][declaration=null][source=null]'],
|
|
43
122
|
),
|
|
44
|
-
'no-inline-param-object-types':
|
|
123
|
+
'no-inline-param-object-types': buildBanRule(
|
|
45
124
|
'problem',
|
|
46
125
|
'Give this parameter a named interface or type alias instead of an inline object-literal type.',
|
|
47
126
|
[
|
|
@@ -49,7 +128,7 @@ const plugin = {
|
|
|
49
128
|
'TSMethodSignature > Identifier.params > TSTypeAnnotation > TSTypeLiteral',
|
|
50
129
|
],
|
|
51
130
|
),
|
|
52
|
-
'no-destructured-params':
|
|
131
|
+
'no-destructured-params': buildBanRule(
|
|
53
132
|
'suggestion',
|
|
54
133
|
'Accept the parameter whole instead of destructuring it in the signature.',
|
|
55
134
|
[
|
|
@@ -57,12 +136,12 @@ const plugin = {
|
|
|
57
136
|
':matches(FunctionDeclaration, FunctionExpression, ArrowFunctionExpression) > AssignmentPattern.params > ObjectPattern',
|
|
58
137
|
],
|
|
59
138
|
),
|
|
60
|
-
'no-pick-destructuring':
|
|
139
|
+
'no-pick-destructuring': buildBanRule(
|
|
61
140
|
'suggestion',
|
|
62
141
|
'Use direct member access; destructure an object only with a rest element to omit properties.',
|
|
63
142
|
['VariableDeclarator > ObjectPattern:not(:has(> RestElement))'],
|
|
64
143
|
),
|
|
65
|
-
'no-ternary-args':
|
|
144
|
+
'no-ternary-args': buildBanRule(
|
|
66
145
|
'suggestion',
|
|
67
146
|
'Extract this ternary to a named const instead of passing it as an argument.',
|
|
68
147
|
[
|
|
@@ -70,12 +149,12 @@ const plugin = {
|
|
|
70
149
|
'NewExpression > ConditionalExpression.arguments',
|
|
71
150
|
],
|
|
72
151
|
),
|
|
73
|
-
'no-await-args':
|
|
152
|
+
'no-await-args': buildBanRule(
|
|
74
153
|
'suggestion',
|
|
75
154
|
'Await into a named const instead of awaiting inside an argument list.',
|
|
76
155
|
['CallExpression > AwaitExpression.arguments', 'NewExpression > AwaitExpression.arguments'],
|
|
77
156
|
),
|
|
78
|
-
'no-await-in-condition':
|
|
157
|
+
'no-await-in-condition': buildBanRule(
|
|
79
158
|
'suggestion',
|
|
80
159
|
'Await into a named const before the statement instead of inside a control-flow condition.',
|
|
81
160
|
[
|
|
@@ -83,11 +162,13 @@ const plugin = {
|
|
|
83
162
|
'SwitchStatement > AwaitExpression.discriminant',
|
|
84
163
|
],
|
|
85
164
|
),
|
|
86
|
-
'no-await-in-logical':
|
|
165
|
+
'no-await-in-logical': buildBanRule(
|
|
87
166
|
'suggestion',
|
|
88
167
|
'Await into a named const instead of chaining it after a && / || / ?? operator.',
|
|
89
168
|
['LogicalExpression > AwaitExpression'],
|
|
90
169
|
),
|
|
170
|
+
'no-single-line-jsdoc': noSingleLineJSDoc,
|
|
171
|
+
'function-verb': functionVerb,
|
|
91
172
|
},
|
|
92
173
|
};
|
|
93
174
|
|