eslint-plugin-nextfriday 1.6.0 → 1.7.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +6 -0
- package/README.md +120 -74
- package/docs/rules/BOOLEAN_NAMING_PREFIX.md +102 -0
- package/docs/rules/NO_DIRECT_DATE.md +36 -0
- package/docs/rules/NO_SINGLE_CHAR_VARIABLES.md +108 -0
- package/docs/rules/PREFER_FUNCTION_DECLARATION.md +139 -0
- package/docs/rules/REQUIRE_EXPLICIT_RETURN_TYPE.md +130 -0
- package/lib/index.cjs +673 -217
- package/lib/index.cjs.map +1 -1
- package/lib/index.d.cts +70 -14
- package/lib/index.d.ts +70 -14
- package/lib/index.js +674 -218
- package/lib/index.js.map +1 -1
- package/package.json +1 -1
- package/docs/rules/NO_EXPLICIT_RETURN_TYPE.md +0 -71
package/lib/index.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
// package.json
|
|
2
2
|
var package_default = {
|
|
3
3
|
name: "eslint-plugin-nextfriday",
|
|
4
|
-
version: "1.
|
|
4
|
+
version: "1.7.0",
|
|
5
5
|
description: "A comprehensive ESLint plugin providing custom rules and configurations for Next Friday development workflows.",
|
|
6
6
|
keywords: [
|
|
7
7
|
"eslint",
|
|
@@ -115,12 +115,143 @@ var package_default = {
|
|
|
115
115
|
}
|
|
116
116
|
};
|
|
117
117
|
|
|
118
|
-
// src/rules/
|
|
119
|
-
import {
|
|
118
|
+
// src/rules/boolean-naming-prefix.ts
|
|
119
|
+
import { ESLintUtils, AST_NODE_TYPES } from "@typescript-eslint/utils";
|
|
120
120
|
var createRule = ESLintUtils.RuleCreator(
|
|
121
121
|
(name) => `https://github.com/next-friday/eslint-plugin-nextfriday/blob/main/docs/rules/${name.replaceAll("-", "_").toUpperCase()}.md`
|
|
122
122
|
);
|
|
123
|
-
var
|
|
123
|
+
var BOOLEAN_PREFIXES = ["is", "has", "should", "can", "did", "will", "was", "are", "does", "had"];
|
|
124
|
+
var startsWithBooleanPrefix = (name) => {
|
|
125
|
+
const lowerName = name.toLowerCase();
|
|
126
|
+
return BOOLEAN_PREFIXES.some((prefix) => {
|
|
127
|
+
if (!lowerName.startsWith(prefix)) {
|
|
128
|
+
return false;
|
|
129
|
+
}
|
|
130
|
+
if (name.length === prefix.length) {
|
|
131
|
+
return true;
|
|
132
|
+
}
|
|
133
|
+
const nextChar = name.charAt(prefix.length);
|
|
134
|
+
return nextChar === nextChar.toUpperCase();
|
|
135
|
+
});
|
|
136
|
+
};
|
|
137
|
+
var isBooleanLiteral = (node) => node.type === AST_NODE_TYPES.Literal && typeof node.value === "boolean";
|
|
138
|
+
var isBooleanExpression = (node) => {
|
|
139
|
+
if (isBooleanLiteral(node)) {
|
|
140
|
+
return true;
|
|
141
|
+
}
|
|
142
|
+
if (node.type === AST_NODE_TYPES.UnaryExpression && node.operator === "!") {
|
|
143
|
+
return true;
|
|
144
|
+
}
|
|
145
|
+
if (node.type === AST_NODE_TYPES.BinaryExpression) {
|
|
146
|
+
const comparisonOperators = ["===", "!==", "==", "!=", "<", ">", "<=", ">=", "in", "instanceof"];
|
|
147
|
+
return comparisonOperators.includes(node.operator);
|
|
148
|
+
}
|
|
149
|
+
if (node.type === AST_NODE_TYPES.LogicalExpression) {
|
|
150
|
+
return node.operator === "&&" || node.operator === "||";
|
|
151
|
+
}
|
|
152
|
+
return false;
|
|
153
|
+
};
|
|
154
|
+
var hasBooleanTypeAnnotation = (node) => {
|
|
155
|
+
if (node.type === AST_NODE_TYPES.Identifier) {
|
|
156
|
+
const { typeAnnotation } = node;
|
|
157
|
+
if (typeAnnotation?.typeAnnotation.type === AST_NODE_TYPES.TSBooleanKeyword) {
|
|
158
|
+
return true;
|
|
159
|
+
}
|
|
160
|
+
}
|
|
161
|
+
if ("id" in node && node.id.type === AST_NODE_TYPES.Identifier) {
|
|
162
|
+
const { typeAnnotation } = node.id;
|
|
163
|
+
if (typeAnnotation?.typeAnnotation.type === AST_NODE_TYPES.TSBooleanKeyword) {
|
|
164
|
+
return true;
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
return false;
|
|
168
|
+
};
|
|
169
|
+
var booleanNamingPrefix = createRule({
|
|
170
|
+
name: "boolean-naming-prefix",
|
|
171
|
+
meta: {
|
|
172
|
+
type: "suggestion",
|
|
173
|
+
docs: {
|
|
174
|
+
description: "Enforce boolean variables and parameters to have a prefix like is, has, should, can, did, will for better readability"
|
|
175
|
+
},
|
|
176
|
+
messages: {
|
|
177
|
+
missingPrefix: "Boolean variable '{{name}}' should have a prefix like is, has, should, can, did, or will. Example: 'is{{suggestedName}}' or 'has{{suggestedName}}'."
|
|
178
|
+
},
|
|
179
|
+
schema: []
|
|
180
|
+
},
|
|
181
|
+
defaultOptions: [],
|
|
182
|
+
create(context) {
|
|
183
|
+
const checkBooleanNaming = (name, node) => {
|
|
184
|
+
if (startsWithBooleanPrefix(name)) {
|
|
185
|
+
return;
|
|
186
|
+
}
|
|
187
|
+
const suggestedName = name.charAt(0).toUpperCase() + name.slice(1);
|
|
188
|
+
context.report({
|
|
189
|
+
node,
|
|
190
|
+
messageId: "missingPrefix",
|
|
191
|
+
data: { name, suggestedName }
|
|
192
|
+
});
|
|
193
|
+
};
|
|
194
|
+
return {
|
|
195
|
+
VariableDeclarator(node) {
|
|
196
|
+
if (node.id.type !== AST_NODE_TYPES.Identifier) {
|
|
197
|
+
return;
|
|
198
|
+
}
|
|
199
|
+
const { name } = node.id;
|
|
200
|
+
if (hasBooleanTypeAnnotation(node)) {
|
|
201
|
+
checkBooleanNaming(name, node.id);
|
|
202
|
+
return;
|
|
203
|
+
}
|
|
204
|
+
if (node.init && isBooleanExpression(node.init)) {
|
|
205
|
+
checkBooleanNaming(name, node.id);
|
|
206
|
+
}
|
|
207
|
+
},
|
|
208
|
+
FunctionDeclaration(node) {
|
|
209
|
+
node.params.forEach((param) => {
|
|
210
|
+
if (param.type === AST_NODE_TYPES.Identifier && hasBooleanTypeAnnotation(param)) {
|
|
211
|
+
checkBooleanNaming(param.name, param);
|
|
212
|
+
}
|
|
213
|
+
if (param.type === AST_NODE_TYPES.AssignmentPattern) {
|
|
214
|
+
if (param.left.type === AST_NODE_TYPES.Identifier && param.right && isBooleanLiteral(param.right)) {
|
|
215
|
+
checkBooleanNaming(param.left.name, param.left);
|
|
216
|
+
}
|
|
217
|
+
}
|
|
218
|
+
});
|
|
219
|
+
},
|
|
220
|
+
FunctionExpression(node) {
|
|
221
|
+
node.params.forEach((param) => {
|
|
222
|
+
if (param.type === AST_NODE_TYPES.Identifier && hasBooleanTypeAnnotation(param)) {
|
|
223
|
+
checkBooleanNaming(param.name, param);
|
|
224
|
+
}
|
|
225
|
+
if (param.type === AST_NODE_TYPES.AssignmentPattern) {
|
|
226
|
+
if (param.left.type === AST_NODE_TYPES.Identifier && param.right && isBooleanLiteral(param.right)) {
|
|
227
|
+
checkBooleanNaming(param.left.name, param.left);
|
|
228
|
+
}
|
|
229
|
+
}
|
|
230
|
+
});
|
|
231
|
+
},
|
|
232
|
+
ArrowFunctionExpression(node) {
|
|
233
|
+
node.params.forEach((param) => {
|
|
234
|
+
if (param.type === AST_NODE_TYPES.Identifier && hasBooleanTypeAnnotation(param)) {
|
|
235
|
+
checkBooleanNaming(param.name, param);
|
|
236
|
+
}
|
|
237
|
+
if (param.type === AST_NODE_TYPES.AssignmentPattern) {
|
|
238
|
+
if (param.left.type === AST_NODE_TYPES.Identifier && param.right && isBooleanLiteral(param.right)) {
|
|
239
|
+
checkBooleanNaming(param.left.name, param.left);
|
|
240
|
+
}
|
|
241
|
+
}
|
|
242
|
+
});
|
|
243
|
+
}
|
|
244
|
+
};
|
|
245
|
+
}
|
|
246
|
+
});
|
|
247
|
+
var boolean_naming_prefix_default = booleanNamingPrefix;
|
|
248
|
+
|
|
249
|
+
// src/rules/enforce-readonly-component-props.ts
|
|
250
|
+
import { AST_NODE_TYPES as AST_NODE_TYPES2, ESLintUtils as ESLintUtils2 } from "@typescript-eslint/utils";
|
|
251
|
+
var createRule2 = ESLintUtils2.RuleCreator(
|
|
252
|
+
(name) => `https://github.com/next-friday/eslint-plugin-nextfriday/blob/main/docs/rules/${name.replaceAll("-", "_").toUpperCase()}.md`
|
|
253
|
+
);
|
|
254
|
+
var enforceReadonlyComponentProps = createRule2({
|
|
124
255
|
name: "enforce-readonly-component-props",
|
|
125
256
|
meta: {
|
|
126
257
|
type: "suggestion",
|
|
@@ -136,54 +267,54 @@ var enforceReadonlyComponentProps = createRule({
|
|
|
136
267
|
defaultOptions: [],
|
|
137
268
|
create(context) {
|
|
138
269
|
function hasJSXInConditional(node) {
|
|
139
|
-
return node.consequent.type ===
|
|
270
|
+
return node.consequent.type === AST_NODE_TYPES2.JSXElement || node.consequent.type === AST_NODE_TYPES2.JSXFragment || node.alternate.type === AST_NODE_TYPES2.JSXElement || node.alternate.type === AST_NODE_TYPES2.JSXFragment;
|
|
140
271
|
}
|
|
141
272
|
function hasJSXInLogical(node) {
|
|
142
|
-
return node.right.type ===
|
|
273
|
+
return node.right.type === AST_NODE_TYPES2.JSXElement || node.right.type === AST_NODE_TYPES2.JSXFragment;
|
|
143
274
|
}
|
|
144
275
|
function hasJSXReturn(block) {
|
|
145
276
|
return block.body.some((stmt) => {
|
|
146
|
-
if (stmt.type ===
|
|
147
|
-
return stmt.argument.type ===
|
|
277
|
+
if (stmt.type === AST_NODE_TYPES2.ReturnStatement && stmt.argument) {
|
|
278
|
+
return stmt.argument.type === AST_NODE_TYPES2.JSXElement || stmt.argument.type === AST_NODE_TYPES2.JSXFragment || stmt.argument.type === AST_NODE_TYPES2.ConditionalExpression && hasJSXInConditional(stmt.argument) || stmt.argument.type === AST_NODE_TYPES2.LogicalExpression && hasJSXInLogical(stmt.argument);
|
|
148
279
|
}
|
|
149
280
|
return false;
|
|
150
281
|
});
|
|
151
282
|
}
|
|
152
|
-
function
|
|
153
|
-
if (node.type ===
|
|
154
|
-
if (node.body.type ===
|
|
283
|
+
function isReactComponent2(node) {
|
|
284
|
+
if (node.type === AST_NODE_TYPES2.ArrowFunctionExpression) {
|
|
285
|
+
if (node.body.type === AST_NODE_TYPES2.JSXElement || node.body.type === AST_NODE_TYPES2.JSXFragment) {
|
|
155
286
|
return true;
|
|
156
287
|
}
|
|
157
|
-
if (node.body.type ===
|
|
288
|
+
if (node.body.type === AST_NODE_TYPES2.BlockStatement) {
|
|
158
289
|
return hasJSXReturn(node.body);
|
|
159
290
|
}
|
|
160
|
-
} else if (node.type ===
|
|
161
|
-
if (node.body && node.body.type ===
|
|
291
|
+
} else if (node.type === AST_NODE_TYPES2.FunctionExpression || node.type === AST_NODE_TYPES2.FunctionDeclaration) {
|
|
292
|
+
if (node.body && node.body.type === AST_NODE_TYPES2.BlockStatement) {
|
|
162
293
|
return hasJSXReturn(node.body);
|
|
163
294
|
}
|
|
164
295
|
}
|
|
165
296
|
return false;
|
|
166
297
|
}
|
|
167
298
|
function isNamedType(node) {
|
|
168
|
-
return node.type ===
|
|
299
|
+
return node.type === AST_NODE_TYPES2.TSTypeReference;
|
|
169
300
|
}
|
|
170
301
|
function isAlreadyReadonly(node) {
|
|
171
|
-
if (node.type ===
|
|
172
|
-
if (node.typeName.type ===
|
|
302
|
+
if (node.type === AST_NODE_TYPES2.TSTypeReference && node.typeName) {
|
|
303
|
+
if (node.typeName.type === AST_NODE_TYPES2.Identifier && node.typeName.name === "Readonly") {
|
|
173
304
|
return true;
|
|
174
305
|
}
|
|
175
306
|
}
|
|
176
307
|
return false;
|
|
177
308
|
}
|
|
178
309
|
function checkFunction(node) {
|
|
179
|
-
if (!
|
|
310
|
+
if (!isReactComponent2(node)) {
|
|
180
311
|
return;
|
|
181
312
|
}
|
|
182
313
|
if (node.params.length !== 1) {
|
|
183
314
|
return;
|
|
184
315
|
}
|
|
185
316
|
const param = node.params[0];
|
|
186
|
-
if (param.type ===
|
|
317
|
+
if (param.type === AST_NODE_TYPES2.Identifier && param.typeAnnotation) {
|
|
187
318
|
const { typeAnnotation } = param.typeAnnotation;
|
|
188
319
|
if (isNamedType(typeAnnotation) && !isAlreadyReadonly(typeAnnotation)) {
|
|
189
320
|
const { sourceCode } = context;
|
|
@@ -208,11 +339,11 @@ var enforceReadonlyComponentProps = createRule({
|
|
|
208
339
|
var enforce_readonly_component_props_default = enforceReadonlyComponentProps;
|
|
209
340
|
|
|
210
341
|
// src/rules/enforce-sorted-destructuring.ts
|
|
211
|
-
import { AST_NODE_TYPES as
|
|
212
|
-
var
|
|
342
|
+
import { AST_NODE_TYPES as AST_NODE_TYPES3, ESLintUtils as ESLintUtils3 } from "@typescript-eslint/utils";
|
|
343
|
+
var createRule3 = ESLintUtils3.RuleCreator(
|
|
213
344
|
(name) => `https://github.com/next-friday/eslint-plugin-nextfriday/blob/main/docs/rules/${name.replaceAll("-", "_").toUpperCase()}.md`
|
|
214
345
|
);
|
|
215
|
-
var enforceSortedDestructuring =
|
|
346
|
+
var enforceSortedDestructuring = createRule3({
|
|
216
347
|
name: "enforce-sorted-destructuring",
|
|
217
348
|
meta: {
|
|
218
349
|
type: "suggestion",
|
|
@@ -227,16 +358,16 @@ var enforceSortedDestructuring = createRule2({
|
|
|
227
358
|
defaultOptions: [],
|
|
228
359
|
create(context) {
|
|
229
360
|
function getPropertyName(property) {
|
|
230
|
-
if (property.type ===
|
|
361
|
+
if (property.type === AST_NODE_TYPES3.RestElement) {
|
|
231
362
|
return null;
|
|
232
363
|
}
|
|
233
|
-
if (property.key.type ===
|
|
364
|
+
if (property.key.type === AST_NODE_TYPES3.Identifier) {
|
|
234
365
|
return property.key.name;
|
|
235
366
|
}
|
|
236
367
|
return null;
|
|
237
368
|
}
|
|
238
369
|
function hasDefaultValue(property) {
|
|
239
|
-
return property.value.type ===
|
|
370
|
+
return property.value.type === AST_NODE_TYPES3.AssignmentPattern && Boolean(property.value.right);
|
|
240
371
|
}
|
|
241
372
|
function getDefaultValueType(property) {
|
|
242
373
|
if (!hasDefaultValue(property)) {
|
|
@@ -248,7 +379,7 @@ var enforceSortedDestructuring = createRule2({
|
|
|
248
379
|
return "none";
|
|
249
380
|
}
|
|
250
381
|
switch (right.type) {
|
|
251
|
-
case
|
|
382
|
+
case AST_NODE_TYPES3.Literal:
|
|
252
383
|
if (typeof right.value === "string") {
|
|
253
384
|
return "string";
|
|
254
385
|
}
|
|
@@ -259,10 +390,10 @@ var enforceSortedDestructuring = createRule2({
|
|
|
259
390
|
return "boolean";
|
|
260
391
|
}
|
|
261
392
|
return "other";
|
|
262
|
-
case
|
|
393
|
+
case AST_NODE_TYPES3.TemplateLiteral:
|
|
263
394
|
return "string";
|
|
264
|
-
case
|
|
265
|
-
case
|
|
395
|
+
case AST_NODE_TYPES3.ObjectExpression:
|
|
396
|
+
case AST_NODE_TYPES3.ArrayExpression:
|
|
266
397
|
return "object";
|
|
267
398
|
default:
|
|
268
399
|
return "other";
|
|
@@ -280,7 +411,7 @@ var enforceSortedDestructuring = createRule2({
|
|
|
280
411
|
return order[type] ?? 5;
|
|
281
412
|
}
|
|
282
413
|
function checkVariableDeclarator(node) {
|
|
283
|
-
if (node.id.type !==
|
|
414
|
+
if (node.id.type !== AST_NODE_TYPES3.ObjectPattern) {
|
|
284
415
|
return;
|
|
285
416
|
}
|
|
286
417
|
const { properties } = node.id;
|
|
@@ -288,7 +419,7 @@ var enforceSortedDestructuring = createRule2({
|
|
|
288
419
|
return;
|
|
289
420
|
}
|
|
290
421
|
const propertyInfo = properties.map((prop) => {
|
|
291
|
-
if (prop.type ===
|
|
422
|
+
if (prop.type === AST_NODE_TYPES3.RestElement) {
|
|
292
423
|
return null;
|
|
293
424
|
}
|
|
294
425
|
return {
|
|
@@ -330,8 +461,8 @@ var enforce_sorted_destructuring_default = enforceSortedDestructuring;
|
|
|
330
461
|
|
|
331
462
|
// src/rules/file-kebab-case.ts
|
|
332
463
|
import path from "path";
|
|
333
|
-
import { ESLintUtils as
|
|
334
|
-
var
|
|
464
|
+
import { ESLintUtils as ESLintUtils4 } from "@typescript-eslint/utils";
|
|
465
|
+
var createRule4 = ESLintUtils4.RuleCreator(
|
|
335
466
|
(name) => `https://github.com/next-friday/eslint-plugin-nextfriday/blob/main/docs/rules/${name.replaceAll("-", "_").toUpperCase()}.md`
|
|
336
467
|
);
|
|
337
468
|
var isKebabCase = (str) => {
|
|
@@ -340,7 +471,7 @@ var isKebabCase = (str) => {
|
|
|
340
471
|
}
|
|
341
472
|
return /^[a-z0-9]+(?:-[a-z0-9]+)*$/.test(str);
|
|
342
473
|
};
|
|
343
|
-
var fileKebabCase =
|
|
474
|
+
var fileKebabCase = createRule4({
|
|
344
475
|
name: "file-kebab-case",
|
|
345
476
|
meta: {
|
|
346
477
|
type: "problem",
|
|
@@ -376,12 +507,12 @@ var file_kebab_case_default = fileKebabCase;
|
|
|
376
507
|
|
|
377
508
|
// src/rules/jsx-pascal-case.ts
|
|
378
509
|
import path2 from "path";
|
|
379
|
-
import { ESLintUtils as
|
|
380
|
-
var
|
|
510
|
+
import { ESLintUtils as ESLintUtils5 } from "@typescript-eslint/utils";
|
|
511
|
+
var createRule5 = ESLintUtils5.RuleCreator(
|
|
381
512
|
(name) => `https://github.com/next-friday/eslint-plugin-nextfriday/blob/main/docs/rules/${name.replaceAll("-", "_").toUpperCase()}.md`
|
|
382
513
|
);
|
|
383
514
|
var isPascalCase = (str) => /^[A-Z][a-zA-Z0-9]*$/.test(str) && !/^[A-Z]+$/.test(str);
|
|
384
|
-
var jsxPascalCase =
|
|
515
|
+
var jsxPascalCase = createRule5({
|
|
385
516
|
name: "jsx-pascal-case",
|
|
386
517
|
meta: {
|
|
387
518
|
type: "problem",
|
|
@@ -415,12 +546,64 @@ var jsxPascalCase = createRule4({
|
|
|
415
546
|
});
|
|
416
547
|
var jsx_pascal_case_default = jsxPascalCase;
|
|
417
548
|
|
|
549
|
+
// src/rules/no-direct-date.ts
|
|
550
|
+
import { ESLintUtils as ESLintUtils6, AST_NODE_TYPES as AST_NODE_TYPES4 } from "@typescript-eslint/utils";
|
|
551
|
+
var createRule6 = ESLintUtils6.RuleCreator(
|
|
552
|
+
(name) => `https://github.com/next-friday/eslint-plugin-nextfriday/blob/main/docs/rules/${name.replaceAll("-", "_").toUpperCase()}.md`
|
|
553
|
+
);
|
|
554
|
+
var noDirectDate = createRule6({
|
|
555
|
+
name: "no-direct-date",
|
|
556
|
+
meta: {
|
|
557
|
+
type: "problem",
|
|
558
|
+
docs: {
|
|
559
|
+
description: "Disallow direct usage of Date constructor and methods to enforce centralized date utilities"
|
|
560
|
+
},
|
|
561
|
+
messages: {
|
|
562
|
+
noNewDate: "Avoid using 'new Date()'. Use a centralized date utility like dayjs instead.",
|
|
563
|
+
noDateNow: "Avoid using 'Date.now()'. Use a centralized date utility like dayjs instead.",
|
|
564
|
+
noDateParse: "Avoid using 'Date.parse()'. Use a centralized date utility like dayjs instead."
|
|
565
|
+
},
|
|
566
|
+
schema: []
|
|
567
|
+
},
|
|
568
|
+
defaultOptions: [],
|
|
569
|
+
create(context) {
|
|
570
|
+
return {
|
|
571
|
+
NewExpression(node) {
|
|
572
|
+
if (node.callee.type === AST_NODE_TYPES4.Identifier && node.callee.name === "Date") {
|
|
573
|
+
context.report({
|
|
574
|
+
node,
|
|
575
|
+
messageId: "noNewDate"
|
|
576
|
+
});
|
|
577
|
+
}
|
|
578
|
+
},
|
|
579
|
+
CallExpression(node) {
|
|
580
|
+
if (node.callee.type === AST_NODE_TYPES4.MemberExpression && node.callee.object.type === AST_NODE_TYPES4.Identifier && node.callee.object.name === "Date" && node.callee.property.type === AST_NODE_TYPES4.Identifier) {
|
|
581
|
+
const methodName = node.callee.property.name;
|
|
582
|
+
if (methodName === "now") {
|
|
583
|
+
context.report({
|
|
584
|
+
node,
|
|
585
|
+
messageId: "noDateNow"
|
|
586
|
+
});
|
|
587
|
+
}
|
|
588
|
+
if (methodName === "parse") {
|
|
589
|
+
context.report({
|
|
590
|
+
node,
|
|
591
|
+
messageId: "noDateParse"
|
|
592
|
+
});
|
|
593
|
+
}
|
|
594
|
+
}
|
|
595
|
+
}
|
|
596
|
+
};
|
|
597
|
+
}
|
|
598
|
+
});
|
|
599
|
+
var no_direct_date_default = noDirectDate;
|
|
600
|
+
|
|
418
601
|
// src/rules/jsx-no-variable-in-callback.ts
|
|
419
|
-
import { AST_NODE_TYPES as
|
|
420
|
-
var
|
|
602
|
+
import { AST_NODE_TYPES as AST_NODE_TYPES5, ESLintUtils as ESLintUtils7 } from "@typescript-eslint/utils";
|
|
603
|
+
var createRule7 = ESLintUtils7.RuleCreator(
|
|
421
604
|
(name) => `https://github.com/next-friday/eslint-plugin-nextfriday/blob/main/docs/rules/${name.replaceAll("-", "_").toUpperCase()}.md`
|
|
422
605
|
);
|
|
423
|
-
var jsxNoVariableInCallback =
|
|
606
|
+
var jsxNoVariableInCallback = createRule7({
|
|
424
607
|
name: "jsx-no-variable-in-callback",
|
|
425
608
|
meta: {
|
|
426
609
|
type: "suggestion",
|
|
@@ -437,7 +620,7 @@ var jsxNoVariableInCallback = createRule5({
|
|
|
437
620
|
function isInsideJSX(node) {
|
|
438
621
|
let current = node.parent;
|
|
439
622
|
while (current) {
|
|
440
|
-
if (current.type ===
|
|
623
|
+
if (current.type === AST_NODE_TYPES5.JSXElement || current.type === AST_NODE_TYPES5.JSXFragment) {
|
|
441
624
|
return true;
|
|
442
625
|
}
|
|
443
626
|
current = current.parent;
|
|
@@ -451,11 +634,11 @@ var jsxNoVariableInCallback = createRule5({
|
|
|
451
634
|
if (!isInsideJSX(node)) {
|
|
452
635
|
return false;
|
|
453
636
|
}
|
|
454
|
-
if (node.parent.type ===
|
|
637
|
+
if (node.parent.type === AST_NODE_TYPES5.CallExpression || node.parent.type === AST_NODE_TYPES5.JSXExpressionContainer) {
|
|
455
638
|
return true;
|
|
456
639
|
}
|
|
457
|
-
if (node.parent.type ===
|
|
458
|
-
if (node.parent.parent.type ===
|
|
640
|
+
if (node.parent.type === AST_NODE_TYPES5.ArrayExpression && node.parent.parent) {
|
|
641
|
+
if (node.parent.parent.type === AST_NODE_TYPES5.CallExpression || node.parent.parent.type === AST_NODE_TYPES5.JSXExpressionContainer) {
|
|
459
642
|
return true;
|
|
460
643
|
}
|
|
461
644
|
}
|
|
@@ -466,11 +649,11 @@ var jsxNoVariableInCallback = createRule5({
|
|
|
466
649
|
return;
|
|
467
650
|
}
|
|
468
651
|
const { body } = node;
|
|
469
|
-
if (body.type !==
|
|
652
|
+
if (body.type !== AST_NODE_TYPES5.BlockStatement) {
|
|
470
653
|
return;
|
|
471
654
|
}
|
|
472
655
|
body.body.forEach((statement) => {
|
|
473
|
-
if (statement.type ===
|
|
656
|
+
if (statement.type === AST_NODE_TYPES5.VariableDeclaration) {
|
|
474
657
|
context.report({
|
|
475
658
|
node: statement,
|
|
476
659
|
messageId: "noVariableInCallback"
|
|
@@ -488,11 +671,11 @@ var jsx_no_variable_in_callback_default = jsxNoVariableInCallback;
|
|
|
488
671
|
|
|
489
672
|
// src/rules/md-filename-case-restriction.ts
|
|
490
673
|
import path3 from "path";
|
|
491
|
-
import { ESLintUtils as
|
|
492
|
-
var
|
|
674
|
+
import { ESLintUtils as ESLintUtils8 } from "@typescript-eslint/utils";
|
|
675
|
+
var createRule8 = ESLintUtils8.RuleCreator(
|
|
493
676
|
(name) => `https://github.com/next-friday/eslint-plugin-nextfriday/blob/main/docs/rules/${name.replaceAll("-", "_").toUpperCase()}.md`
|
|
494
677
|
);
|
|
495
|
-
var mdFilenameCaseRestriction =
|
|
678
|
+
var mdFilenameCaseRestriction = createRule8({
|
|
496
679
|
name: "md-filename-case-restriction",
|
|
497
680
|
meta: {
|
|
498
681
|
type: "problem",
|
|
@@ -533,11 +716,11 @@ var mdFilenameCaseRestriction = createRule6({
|
|
|
533
716
|
var md_filename_case_restriction_default = mdFilenameCaseRestriction;
|
|
534
717
|
|
|
535
718
|
// src/rules/no-complex-inline-return.ts
|
|
536
|
-
import { ESLintUtils as
|
|
537
|
-
var
|
|
719
|
+
import { ESLintUtils as ESLintUtils9, AST_NODE_TYPES as AST_NODE_TYPES6 } from "@typescript-eslint/utils";
|
|
720
|
+
var createRule9 = ESLintUtils9.RuleCreator(
|
|
538
721
|
(name) => `https://github.com/next-friday/eslint-plugin-nextfriday/blob/main/docs/rules/${name.replaceAll("-", "_").toUpperCase()}.md`
|
|
539
722
|
);
|
|
540
|
-
var noComplexInlineReturn =
|
|
723
|
+
var noComplexInlineReturn = createRule9({
|
|
541
724
|
name: "no-complex-inline-return",
|
|
542
725
|
meta: {
|
|
543
726
|
type: "suggestion",
|
|
@@ -553,13 +736,13 @@ var noComplexInlineReturn = createRule7({
|
|
|
553
736
|
create(context) {
|
|
554
737
|
const isComplexExpression = (node) => {
|
|
555
738
|
if (!node) return false;
|
|
556
|
-
if (node.type ===
|
|
739
|
+
if (node.type === AST_NODE_TYPES6.ConditionalExpression) {
|
|
557
740
|
return true;
|
|
558
741
|
}
|
|
559
|
-
if (node.type ===
|
|
742
|
+
if (node.type === AST_NODE_TYPES6.LogicalExpression) {
|
|
560
743
|
return true;
|
|
561
744
|
}
|
|
562
|
-
if (node.type ===
|
|
745
|
+
if (node.type === AST_NODE_TYPES6.NewExpression) {
|
|
563
746
|
return true;
|
|
564
747
|
}
|
|
565
748
|
return false;
|
|
@@ -580,11 +763,11 @@ var no_complex_inline_return_default = noComplexInlineReturn;
|
|
|
580
763
|
|
|
581
764
|
// src/rules/no-emoji.ts
|
|
582
765
|
import emojiRegex from "emoji-regex";
|
|
583
|
-
import { ESLintUtils as
|
|
584
|
-
var
|
|
766
|
+
import { ESLintUtils as ESLintUtils10 } from "@typescript-eslint/utils";
|
|
767
|
+
var createRule10 = ESLintUtils10.RuleCreator(
|
|
585
768
|
(name) => `https://github.com/next-friday/eslint-plugin-nextfriday/blob/main/docs/rules/${name.replaceAll("-", "_").toUpperCase()}.md`
|
|
586
769
|
);
|
|
587
|
-
var noEmoji =
|
|
770
|
+
var noEmoji = createRule10({
|
|
588
771
|
name: "no-emoji",
|
|
589
772
|
meta: {
|
|
590
773
|
type: "problem",
|
|
@@ -618,11 +801,11 @@ var noEmoji = createRule8({
|
|
|
618
801
|
var no_emoji_default = noEmoji;
|
|
619
802
|
|
|
620
803
|
// src/rules/no-env-fallback.ts
|
|
621
|
-
import { ESLintUtils as
|
|
622
|
-
var
|
|
804
|
+
import { ESLintUtils as ESLintUtils11, AST_NODE_TYPES as AST_NODE_TYPES7 } from "@typescript-eslint/utils";
|
|
805
|
+
var createRule11 = ESLintUtils11.RuleCreator(
|
|
623
806
|
(name) => `https://github.com/next-friday/eslint-plugin-nextfriday/blob/main/docs/rules/${name.replaceAll("-", "_").toUpperCase()}.md`
|
|
624
807
|
);
|
|
625
|
-
var noEnvFallback =
|
|
808
|
+
var noEnvFallback = createRule11({
|
|
626
809
|
name: "no-env-fallback",
|
|
627
810
|
meta: {
|
|
628
811
|
type: "problem",
|
|
@@ -637,16 +820,16 @@ var noEnvFallback = createRule9({
|
|
|
637
820
|
defaultOptions: [],
|
|
638
821
|
create(context) {
|
|
639
822
|
const isProcessEnvAccess = (node) => {
|
|
640
|
-
if (node.type !==
|
|
823
|
+
if (node.type !== AST_NODE_TYPES7.MemberExpression) {
|
|
641
824
|
return false;
|
|
642
825
|
}
|
|
643
826
|
const { object } = node;
|
|
644
|
-
if (object.type !==
|
|
827
|
+
if (object.type !== AST_NODE_TYPES7.MemberExpression) {
|
|
645
828
|
return false;
|
|
646
829
|
}
|
|
647
830
|
const processNode = object.object;
|
|
648
831
|
const envNode = object.property;
|
|
649
|
-
return processNode.type ===
|
|
832
|
+
return processNode.type === AST_NODE_TYPES7.Identifier && processNode.name === "process" && envNode.type === AST_NODE_TYPES7.Identifier && envNode.name === "env";
|
|
650
833
|
};
|
|
651
834
|
return {
|
|
652
835
|
LogicalExpression(node) {
|
|
@@ -670,38 +853,93 @@ var noEnvFallback = createRule9({
|
|
|
670
853
|
});
|
|
671
854
|
var no_env_fallback_default = noEnvFallback;
|
|
672
855
|
|
|
673
|
-
// src/rules/
|
|
674
|
-
import { ESLintUtils as
|
|
675
|
-
var
|
|
856
|
+
// src/rules/require-explicit-return-type.ts
|
|
857
|
+
import { ESLintUtils as ESLintUtils12, AST_NODE_TYPES as AST_NODE_TYPES8 } from "@typescript-eslint/utils";
|
|
858
|
+
var createRule12 = ESLintUtils12.RuleCreator(
|
|
676
859
|
(name) => `https://github.com/next-friday/eslint-plugin-nextfriday/blob/main/docs/rules/${name.replaceAll("-", "_").toUpperCase()}.md`
|
|
677
860
|
);
|
|
678
|
-
var
|
|
679
|
-
|
|
861
|
+
var isReactComponent = (node) => {
|
|
862
|
+
if (node.type === AST_NODE_TYPES8.ArrowFunctionExpression) {
|
|
863
|
+
const { parent } = node;
|
|
864
|
+
if (parent?.type === AST_NODE_TYPES8.VariableDeclarator) {
|
|
865
|
+
const { id } = parent;
|
|
866
|
+
if (id.type === AST_NODE_TYPES8.Identifier) {
|
|
867
|
+
return /^[A-Z]/.test(id.name);
|
|
868
|
+
}
|
|
869
|
+
}
|
|
870
|
+
}
|
|
871
|
+
if (node.type === AST_NODE_TYPES8.FunctionDeclaration && node.id) {
|
|
872
|
+
return /^[A-Z]/.test(node.id.name);
|
|
873
|
+
}
|
|
874
|
+
return false;
|
|
875
|
+
};
|
|
876
|
+
var isCallbackFunction = (node) => {
|
|
877
|
+
if (node.type === AST_NODE_TYPES8.FunctionDeclaration) {
|
|
878
|
+
return false;
|
|
879
|
+
}
|
|
880
|
+
const { parent } = node;
|
|
881
|
+
if (!parent) {
|
|
882
|
+
return false;
|
|
883
|
+
}
|
|
884
|
+
if (parent.type === AST_NODE_TYPES8.CallExpression && parent.arguments.includes(node)) {
|
|
885
|
+
return true;
|
|
886
|
+
}
|
|
887
|
+
if (parent.type === AST_NODE_TYPES8.Property) {
|
|
888
|
+
return true;
|
|
889
|
+
}
|
|
890
|
+
if (parent.type === AST_NODE_TYPES8.ArrayExpression) {
|
|
891
|
+
return true;
|
|
892
|
+
}
|
|
893
|
+
return false;
|
|
894
|
+
};
|
|
895
|
+
var getFunctionName = (node) => {
|
|
896
|
+
if (node.type === AST_NODE_TYPES8.FunctionDeclaration && node.id) {
|
|
897
|
+
return node.id.name;
|
|
898
|
+
}
|
|
899
|
+
if (node.type === AST_NODE_TYPES8.FunctionExpression && node.id) {
|
|
900
|
+
return node.id.name;
|
|
901
|
+
}
|
|
902
|
+
if ((node.type === AST_NODE_TYPES8.ArrowFunctionExpression || node.type === AST_NODE_TYPES8.FunctionExpression) && node.parent?.type === AST_NODE_TYPES8.VariableDeclarator && node.parent.id.type === AST_NODE_TYPES8.Identifier) {
|
|
903
|
+
return node.parent.id.name;
|
|
904
|
+
}
|
|
905
|
+
return null;
|
|
906
|
+
};
|
|
907
|
+
var requireExplicitReturnType = createRule12({
|
|
908
|
+
name: "require-explicit-return-type",
|
|
680
909
|
meta: {
|
|
681
910
|
type: "suggestion",
|
|
682
911
|
docs: {
|
|
683
|
-
description: "
|
|
912
|
+
description: "Require explicit return types on functions for better code documentation and type safety"
|
|
684
913
|
},
|
|
685
|
-
fixable: "code",
|
|
686
|
-
schema: [],
|
|
687
914
|
messages: {
|
|
688
|
-
|
|
689
|
-
|
|
915
|
+
missingReturnType: "Function '{{name}}' is missing an explicit return type. Add a return type annotation for better documentation.",
|
|
916
|
+
missingReturnTypeAnonymous: "Function is missing an explicit return type. Add a return type annotation for better documentation."
|
|
917
|
+
},
|
|
918
|
+
schema: []
|
|
690
919
|
},
|
|
691
920
|
defaultOptions: [],
|
|
692
921
|
create(context) {
|
|
693
922
|
const checkFunction = (node) => {
|
|
694
923
|
if (node.returnType) {
|
|
695
|
-
|
|
924
|
+
return;
|
|
925
|
+
}
|
|
926
|
+
if (isCallbackFunction(node)) {
|
|
927
|
+
return;
|
|
928
|
+
}
|
|
929
|
+
if (isReactComponent(node)) {
|
|
930
|
+
return;
|
|
931
|
+
}
|
|
932
|
+
const functionName = getFunctionName(node);
|
|
933
|
+
if (functionName) {
|
|
696
934
|
context.report({
|
|
697
|
-
node
|
|
698
|
-
messageId: "
|
|
699
|
-
data: {
|
|
700
|
-
|
|
701
|
-
|
|
702
|
-
|
|
703
|
-
|
|
704
|
-
|
|
935
|
+
node,
|
|
936
|
+
messageId: "missingReturnType",
|
|
937
|
+
data: { name: functionName }
|
|
938
|
+
});
|
|
939
|
+
} else {
|
|
940
|
+
context.report({
|
|
941
|
+
node,
|
|
942
|
+
messageId: "missingReturnTypeAnonymous"
|
|
705
943
|
});
|
|
706
944
|
}
|
|
707
945
|
};
|
|
@@ -712,21 +950,21 @@ var noExplicitReturnType = createRule10({
|
|
|
712
950
|
};
|
|
713
951
|
}
|
|
714
952
|
});
|
|
715
|
-
var
|
|
953
|
+
var require_explicit_return_type_default = requireExplicitReturnType;
|
|
716
954
|
|
|
717
955
|
// src/rules/jsx-no-non-component-function.ts
|
|
718
|
-
import { AST_NODE_TYPES as
|
|
956
|
+
import { AST_NODE_TYPES as AST_NODE_TYPES10, ESLintUtils as ESLintUtils13 } from "@typescript-eslint/utils";
|
|
719
957
|
|
|
720
958
|
// src/utils.ts
|
|
721
959
|
import { basename, extname } from "path";
|
|
722
|
-
import { AST_NODE_TYPES as
|
|
960
|
+
import { AST_NODE_TYPES as AST_NODE_TYPES9 } from "@typescript-eslint/utils";
|
|
723
961
|
var getFileExtension = (filename) => extname(filename).slice(1);
|
|
724
962
|
|
|
725
963
|
// src/rules/jsx-no-non-component-function.ts
|
|
726
|
-
var
|
|
964
|
+
var createRule13 = ESLintUtils13.RuleCreator(
|
|
727
965
|
(name) => `https://github.com/next-friday/eslint-plugin-nextfriday/blob/main/docs/rules/${name.replaceAll("-", "_").toUpperCase()}.md`
|
|
728
966
|
);
|
|
729
|
-
var jsxNoNonComponentFunction =
|
|
967
|
+
var jsxNoNonComponentFunction = createRule13({
|
|
730
968
|
name: "jsx-no-non-component-function",
|
|
731
969
|
meta: {
|
|
732
970
|
type: "problem",
|
|
@@ -745,14 +983,14 @@ var jsxNoNonComponentFunction = createRule11({
|
|
|
745
983
|
if (extension !== "tsx" && extension !== "jsx") {
|
|
746
984
|
return {};
|
|
747
985
|
}
|
|
748
|
-
function
|
|
749
|
-
const functionName = node.type ===
|
|
986
|
+
function isReactComponent2(node) {
|
|
987
|
+
const functionName = node.type === AST_NODE_TYPES10.FunctionDeclaration && node.id ? node.id.name : null;
|
|
750
988
|
if (functionName && /^[A-Z]/.test(functionName)) {
|
|
751
989
|
return true;
|
|
752
990
|
}
|
|
753
991
|
if (node.returnType?.typeAnnotation) {
|
|
754
992
|
const returnTypeNode = node.returnType.typeAnnotation;
|
|
755
|
-
if (returnTypeNode.type ===
|
|
993
|
+
if (returnTypeNode.type === AST_NODE_TYPES10.TSTypeReference && returnTypeNode.typeName.type === AST_NODE_TYPES10.Identifier) {
|
|
756
994
|
const typeName = returnTypeNode.typeName.name;
|
|
757
995
|
if (typeName === "JSX" || typeName === "ReactElement" || typeName === "ReactNode") {
|
|
758
996
|
return true;
|
|
@@ -762,20 +1000,20 @@ var jsxNoNonComponentFunction = createRule11({
|
|
|
762
1000
|
return false;
|
|
763
1001
|
}
|
|
764
1002
|
function checkTopLevelFunction(node, declaratorNode) {
|
|
765
|
-
if (
|
|
1003
|
+
if (isReactComponent2(node)) {
|
|
766
1004
|
return;
|
|
767
1005
|
}
|
|
768
1006
|
const { parent } = node;
|
|
769
1007
|
if (!parent) {
|
|
770
1008
|
return;
|
|
771
1009
|
}
|
|
772
|
-
if (parent.type ===
|
|
1010
|
+
if (parent.type === AST_NODE_TYPES10.ExportDefaultDeclaration || parent.type === AST_NODE_TYPES10.ExportNamedDeclaration) {
|
|
773
1011
|
return;
|
|
774
1012
|
}
|
|
775
|
-
if (declaratorNode?.parent?.parent?.type ===
|
|
1013
|
+
if (declaratorNode?.parent?.parent?.type === AST_NODE_TYPES10.ExportNamedDeclaration) {
|
|
776
1014
|
return;
|
|
777
1015
|
}
|
|
778
|
-
if (declaratorNode?.id.type ===
|
|
1016
|
+
if (declaratorNode?.id.type === AST_NODE_TYPES10.Identifier) {
|
|
779
1017
|
const varName = declaratorNode.id.name;
|
|
780
1018
|
if (/^[A-Z]/.test(varName)) {
|
|
781
1019
|
return;
|
|
@@ -800,11 +1038,11 @@ var jsxNoNonComponentFunction = createRule11({
|
|
|
800
1038
|
var jsx_no_non_component_function_default = jsxNoNonComponentFunction;
|
|
801
1039
|
|
|
802
1040
|
// src/rules/no-logic-in-params.ts
|
|
803
|
-
import { ESLintUtils as
|
|
804
|
-
var
|
|
1041
|
+
import { ESLintUtils as ESLintUtils14, AST_NODE_TYPES as AST_NODE_TYPES11 } from "@typescript-eslint/utils";
|
|
1042
|
+
var createRule14 = ESLintUtils14.RuleCreator(
|
|
805
1043
|
(name) => `https://github.com/next-friday/eslint-plugin-nextfriday/blob/main/docs/rules/${name.replaceAll("-", "_").toUpperCase()}.md`
|
|
806
1044
|
);
|
|
807
|
-
var noLogicInParams =
|
|
1045
|
+
var noLogicInParams = createRule14({
|
|
808
1046
|
name: "no-logic-in-params",
|
|
809
1047
|
meta: {
|
|
810
1048
|
type: "suggestion",
|
|
@@ -819,20 +1057,20 @@ var noLogicInParams = createRule12({
|
|
|
819
1057
|
defaultOptions: [],
|
|
820
1058
|
create(context) {
|
|
821
1059
|
const isComplexExpression = (node) => {
|
|
822
|
-
if (node.type ===
|
|
1060
|
+
if (node.type === AST_NODE_TYPES11.SpreadElement) {
|
|
823
1061
|
return false;
|
|
824
1062
|
}
|
|
825
|
-
if (node.type ===
|
|
1063
|
+
if (node.type === AST_NODE_TYPES11.ConditionalExpression) {
|
|
826
1064
|
return true;
|
|
827
1065
|
}
|
|
828
|
-
if (node.type ===
|
|
1066
|
+
if (node.type === AST_NODE_TYPES11.LogicalExpression) {
|
|
829
1067
|
return true;
|
|
830
1068
|
}
|
|
831
|
-
if (node.type ===
|
|
1069
|
+
if (node.type === AST_NODE_TYPES11.BinaryExpression) {
|
|
832
1070
|
const logicalOperators = ["==", "===", "!=", "!==", "<", ">", "<=", ">=", "in", "instanceof"];
|
|
833
1071
|
return logicalOperators.includes(node.operator);
|
|
834
1072
|
}
|
|
835
|
-
if (node.type ===
|
|
1073
|
+
if (node.type === AST_NODE_TYPES11.UnaryExpression) {
|
|
836
1074
|
return node.operator === "!";
|
|
837
1075
|
}
|
|
838
1076
|
return false;
|
|
@@ -863,12 +1101,127 @@ var noLogicInParams = createRule12({
|
|
|
863
1101
|
});
|
|
864
1102
|
var no_logic_in_params_default = noLogicInParams;
|
|
865
1103
|
|
|
1104
|
+
// src/rules/no-single-char-variables.ts
|
|
1105
|
+
import { ESLintUtils as ESLintUtils15, AST_NODE_TYPES as AST_NODE_TYPES12 } from "@typescript-eslint/utils";
|
|
1106
|
+
var createRule15 = ESLintUtils15.RuleCreator(
|
|
1107
|
+
(name) => `https://github.com/next-friday/eslint-plugin-nextfriday/blob/main/docs/rules/${name.replaceAll("-", "_").toUpperCase()}.md`
|
|
1108
|
+
);
|
|
1109
|
+
var ALLOWED_IN_FOR_LOOPS = /* @__PURE__ */ new Set(["i", "j", "k", "n"]);
|
|
1110
|
+
var ALLOWED_UNDERSCORE = "_";
|
|
1111
|
+
var isForLoopInit = (node) => {
|
|
1112
|
+
let current = node;
|
|
1113
|
+
while (current) {
|
|
1114
|
+
const parentNode = current.parent;
|
|
1115
|
+
if (!parentNode) {
|
|
1116
|
+
return false;
|
|
1117
|
+
}
|
|
1118
|
+
if (parentNode.type === AST_NODE_TYPES12.ForStatement) {
|
|
1119
|
+
const { init } = parentNode;
|
|
1120
|
+
if (init && init === current) {
|
|
1121
|
+
return true;
|
|
1122
|
+
}
|
|
1123
|
+
}
|
|
1124
|
+
current = parentNode;
|
|
1125
|
+
}
|
|
1126
|
+
return false;
|
|
1127
|
+
};
|
|
1128
|
+
var isAllowedInContext = (name, node) => {
|
|
1129
|
+
if (name === ALLOWED_UNDERSCORE) {
|
|
1130
|
+
return true;
|
|
1131
|
+
}
|
|
1132
|
+
if (ALLOWED_IN_FOR_LOOPS.has(name) && isForLoopInit(node)) {
|
|
1133
|
+
return true;
|
|
1134
|
+
}
|
|
1135
|
+
return false;
|
|
1136
|
+
};
|
|
1137
|
+
var noSingleCharVariables = createRule15({
|
|
1138
|
+
name: "no-single-char-variables",
|
|
1139
|
+
meta: {
|
|
1140
|
+
type: "suggestion",
|
|
1141
|
+
docs: {
|
|
1142
|
+
description: "Disallow single character variable and parameter names for better code readability"
|
|
1143
|
+
},
|
|
1144
|
+
messages: {
|
|
1145
|
+
noSingleChar: "Avoid single character variable name '{{name}}'. Use a descriptive name that clearly indicates the purpose."
|
|
1146
|
+
},
|
|
1147
|
+
schema: []
|
|
1148
|
+
},
|
|
1149
|
+
defaultOptions: [],
|
|
1150
|
+
create(context) {
|
|
1151
|
+
const checkIdentifier = (node, declarationNode) => {
|
|
1152
|
+
const { name } = node;
|
|
1153
|
+
if (name.length !== 1) {
|
|
1154
|
+
return;
|
|
1155
|
+
}
|
|
1156
|
+
if (isAllowedInContext(name, declarationNode)) {
|
|
1157
|
+
return;
|
|
1158
|
+
}
|
|
1159
|
+
context.report({
|
|
1160
|
+
node,
|
|
1161
|
+
messageId: "noSingleChar",
|
|
1162
|
+
data: { name }
|
|
1163
|
+
});
|
|
1164
|
+
};
|
|
1165
|
+
const checkPattern = (pattern, declarationNode) => {
|
|
1166
|
+
if (pattern.type === AST_NODE_TYPES12.Identifier) {
|
|
1167
|
+
checkIdentifier(pattern, declarationNode);
|
|
1168
|
+
} else if (pattern.type === AST_NODE_TYPES12.ObjectPattern) {
|
|
1169
|
+
pattern.properties.forEach((prop) => {
|
|
1170
|
+
if (prop.type === AST_NODE_TYPES12.Property && prop.value.type === AST_NODE_TYPES12.Identifier) {
|
|
1171
|
+
checkIdentifier(prop.value, declarationNode);
|
|
1172
|
+
} else if (prop.type === AST_NODE_TYPES12.RestElement && prop.argument.type === AST_NODE_TYPES12.Identifier) {
|
|
1173
|
+
checkIdentifier(prop.argument, declarationNode);
|
|
1174
|
+
}
|
|
1175
|
+
});
|
|
1176
|
+
} else if (pattern.type === AST_NODE_TYPES12.ArrayPattern) {
|
|
1177
|
+
pattern.elements.forEach((element) => {
|
|
1178
|
+
if (element?.type === AST_NODE_TYPES12.Identifier) {
|
|
1179
|
+
checkIdentifier(element, declarationNode);
|
|
1180
|
+
} else if (element?.type === AST_NODE_TYPES12.RestElement && element.argument.type === AST_NODE_TYPES12.Identifier) {
|
|
1181
|
+
checkIdentifier(element.argument, declarationNode);
|
|
1182
|
+
}
|
|
1183
|
+
});
|
|
1184
|
+
} else if (pattern.type === AST_NODE_TYPES12.AssignmentPattern && pattern.left.type === AST_NODE_TYPES12.Identifier) {
|
|
1185
|
+
checkIdentifier(pattern.left, declarationNode);
|
|
1186
|
+
} else if (pattern.type === AST_NODE_TYPES12.RestElement && pattern.argument.type === AST_NODE_TYPES12.Identifier) {
|
|
1187
|
+
checkIdentifier(pattern.argument, declarationNode);
|
|
1188
|
+
}
|
|
1189
|
+
};
|
|
1190
|
+
return {
|
|
1191
|
+
VariableDeclarator(node) {
|
|
1192
|
+
checkPattern(node.id, node);
|
|
1193
|
+
},
|
|
1194
|
+
FunctionDeclaration(node) {
|
|
1195
|
+
if (node.id) {
|
|
1196
|
+
checkIdentifier(node.id, node);
|
|
1197
|
+
}
|
|
1198
|
+
node.params.forEach((param) => checkPattern(param, node));
|
|
1199
|
+
},
|
|
1200
|
+
FunctionExpression(node) {
|
|
1201
|
+
if (node.id) {
|
|
1202
|
+
checkIdentifier(node.id, node);
|
|
1203
|
+
}
|
|
1204
|
+
node.params.forEach((param) => checkPattern(param, node));
|
|
1205
|
+
},
|
|
1206
|
+
ArrowFunctionExpression(node) {
|
|
1207
|
+
node.params.forEach((param) => checkPattern(param, node));
|
|
1208
|
+
},
|
|
1209
|
+
CatchClause(node) {
|
|
1210
|
+
if (node.param) {
|
|
1211
|
+
checkPattern(node.param, node);
|
|
1212
|
+
}
|
|
1213
|
+
}
|
|
1214
|
+
};
|
|
1215
|
+
}
|
|
1216
|
+
});
|
|
1217
|
+
var no_single_char_variables_default = noSingleCharVariables;
|
|
1218
|
+
|
|
866
1219
|
// src/rules/prefer-destructuring-params.ts
|
|
867
|
-
import { AST_NODE_TYPES as
|
|
868
|
-
var
|
|
1220
|
+
import { AST_NODE_TYPES as AST_NODE_TYPES13, ESLintUtils as ESLintUtils16 } from "@typescript-eslint/utils";
|
|
1221
|
+
var createRule16 = ESLintUtils16.RuleCreator(
|
|
869
1222
|
(name) => `https://github.com/next-friday/eslint-plugin-nextfriday/blob/main/docs/rules/${name.replaceAll("-", "_").toUpperCase()}.md`
|
|
870
1223
|
);
|
|
871
|
-
var preferDestructuringParams =
|
|
1224
|
+
var preferDestructuringParams = createRule16({
|
|
872
1225
|
name: "prefer-destructuring-params",
|
|
873
1226
|
meta: {
|
|
874
1227
|
type: "suggestion",
|
|
@@ -882,20 +1235,20 @@ var preferDestructuringParams = createRule13({
|
|
|
882
1235
|
},
|
|
883
1236
|
defaultOptions: [],
|
|
884
1237
|
create(context) {
|
|
885
|
-
const
|
|
1238
|
+
const isCallbackFunction2 = (node) => {
|
|
886
1239
|
const { parent } = node;
|
|
887
|
-
return parent?.type ===
|
|
1240
|
+
return parent?.type === AST_NODE_TYPES13.CallExpression;
|
|
888
1241
|
};
|
|
889
1242
|
const isDeveloperFunction = (node) => {
|
|
890
|
-
if (node.type ===
|
|
1243
|
+
if (node.type === AST_NODE_TYPES13.FunctionDeclaration) {
|
|
891
1244
|
return true;
|
|
892
1245
|
}
|
|
893
|
-
if (node.type ===
|
|
894
|
-
if (
|
|
1246
|
+
if (node.type === AST_NODE_TYPES13.FunctionExpression || node.type === AST_NODE_TYPES13.ArrowFunctionExpression) {
|
|
1247
|
+
if (isCallbackFunction2(node)) {
|
|
895
1248
|
return false;
|
|
896
1249
|
}
|
|
897
1250
|
const { parent } = node;
|
|
898
|
-
return parent?.type ===
|
|
1251
|
+
return parent?.type === AST_NODE_TYPES13.VariableDeclarator || parent?.type === AST_NODE_TYPES13.AssignmentExpression || parent?.type === AST_NODE_TYPES13.Property || parent?.type === AST_NODE_TYPES13.MethodDefinition;
|
|
899
1252
|
}
|
|
900
1253
|
return false;
|
|
901
1254
|
};
|
|
@@ -907,7 +1260,7 @@ var preferDestructuringParams = createRule13({
|
|
|
907
1260
|
if (!isDeveloperFunction(node)) {
|
|
908
1261
|
return;
|
|
909
1262
|
}
|
|
910
|
-
if (node.type ===
|
|
1263
|
+
if (node.type === AST_NODE_TYPES13.FunctionDeclaration && node.id) {
|
|
911
1264
|
const functionName = node.id.name;
|
|
912
1265
|
if (functionName.startsWith("_") || functionName.includes("$") || /^[A-Z][a-zA-Z]*$/.test(functionName)) {
|
|
913
1266
|
return;
|
|
@@ -917,7 +1270,7 @@ var preferDestructuringParams = createRule13({
|
|
|
917
1270
|
return;
|
|
918
1271
|
}
|
|
919
1272
|
const hasNonDestructuredParams = node.params.some(
|
|
920
|
-
(param) => param.type !==
|
|
1273
|
+
(param) => param.type !== AST_NODE_TYPES13.ObjectPattern && param.type !== AST_NODE_TYPES13.RestElement
|
|
921
1274
|
);
|
|
922
1275
|
if (hasNonDestructuredParams) {
|
|
923
1276
|
context.report({
|
|
@@ -935,12 +1288,103 @@ var preferDestructuringParams = createRule13({
|
|
|
935
1288
|
});
|
|
936
1289
|
var prefer_destructuring_params_default = preferDestructuringParams;
|
|
937
1290
|
|
|
1291
|
+
// src/rules/prefer-function-declaration.ts
|
|
1292
|
+
import { ESLintUtils as ESLintUtils17, AST_NODE_TYPES as AST_NODE_TYPES14 } from "@typescript-eslint/utils";
|
|
1293
|
+
var createRule17 = ESLintUtils17.RuleCreator(
|
|
1294
|
+
(name) => `https://github.com/next-friday/eslint-plugin-nextfriday/blob/main/docs/rules/${name.replaceAll("-", "_").toUpperCase()}.md`
|
|
1295
|
+
);
|
|
1296
|
+
var isTsFile = (filename) => filename.endsWith(".ts") && !filename.endsWith(".d.ts");
|
|
1297
|
+
var isCallbackContext = (node) => {
|
|
1298
|
+
const { parent } = node;
|
|
1299
|
+
if (!parent) {
|
|
1300
|
+
return false;
|
|
1301
|
+
}
|
|
1302
|
+
if (parent.type === AST_NODE_TYPES14.CallExpression && parent.arguments.includes(node)) {
|
|
1303
|
+
return true;
|
|
1304
|
+
}
|
|
1305
|
+
if (parent.type === AST_NODE_TYPES14.NewExpression && parent.arguments.includes(node)) {
|
|
1306
|
+
return true;
|
|
1307
|
+
}
|
|
1308
|
+
if (parent.type === AST_NODE_TYPES14.ReturnStatement) {
|
|
1309
|
+
return true;
|
|
1310
|
+
}
|
|
1311
|
+
if (parent.type === AST_NODE_TYPES14.Property) {
|
|
1312
|
+
return true;
|
|
1313
|
+
}
|
|
1314
|
+
if (parent.type === AST_NODE_TYPES14.ArrayExpression) {
|
|
1315
|
+
return true;
|
|
1316
|
+
}
|
|
1317
|
+
if (parent.type === AST_NODE_TYPES14.ConditionalExpression) {
|
|
1318
|
+
return true;
|
|
1319
|
+
}
|
|
1320
|
+
if (parent.type === AST_NODE_TYPES14.LogicalExpression) {
|
|
1321
|
+
return true;
|
|
1322
|
+
}
|
|
1323
|
+
if (parent.type === AST_NODE_TYPES14.AssignmentExpression && parent.left !== node) {
|
|
1324
|
+
return true;
|
|
1325
|
+
}
|
|
1326
|
+
return false;
|
|
1327
|
+
};
|
|
1328
|
+
var preferFunctionDeclaration = createRule17({
|
|
1329
|
+
name: "prefer-function-declaration",
|
|
1330
|
+
meta: {
|
|
1331
|
+
type: "suggestion",
|
|
1332
|
+
docs: {
|
|
1333
|
+
description: "Enforce function declarations over arrow functions assigned to variables in .ts files for better readability and hoisting"
|
|
1334
|
+
},
|
|
1335
|
+
messages: {
|
|
1336
|
+
preferDeclaration: "Use function declaration instead of arrow function. Replace 'const {{name}} = () => ...' with 'function {{name}}() ...'",
|
|
1337
|
+
preferDeclarationExpr: "Use function declaration instead of function expression. Replace 'const {{name}} = function() ...' with 'function {{name}}() ...'"
|
|
1338
|
+
},
|
|
1339
|
+
schema: []
|
|
1340
|
+
},
|
|
1341
|
+
defaultOptions: [],
|
|
1342
|
+
create(context) {
|
|
1343
|
+
const { filename } = context;
|
|
1344
|
+
if (!isTsFile(filename)) {
|
|
1345
|
+
return {};
|
|
1346
|
+
}
|
|
1347
|
+
return {
|
|
1348
|
+
VariableDeclarator(node) {
|
|
1349
|
+
if (node.id.type !== AST_NODE_TYPES14.Identifier) {
|
|
1350
|
+
return;
|
|
1351
|
+
}
|
|
1352
|
+
const { init } = node;
|
|
1353
|
+
if (!init) {
|
|
1354
|
+
return;
|
|
1355
|
+
}
|
|
1356
|
+
if (init.type === AST_NODE_TYPES14.ArrowFunctionExpression) {
|
|
1357
|
+
if (isCallbackContext(init)) {
|
|
1358
|
+
return;
|
|
1359
|
+
}
|
|
1360
|
+
context.report({
|
|
1361
|
+
node: init,
|
|
1362
|
+
messageId: "preferDeclaration",
|
|
1363
|
+
data: { name: node.id.name }
|
|
1364
|
+
});
|
|
1365
|
+
}
|
|
1366
|
+
if (init.type === AST_NODE_TYPES14.FunctionExpression) {
|
|
1367
|
+
if (isCallbackContext(init)) {
|
|
1368
|
+
return;
|
|
1369
|
+
}
|
|
1370
|
+
context.report({
|
|
1371
|
+
node: init,
|
|
1372
|
+
messageId: "preferDeclarationExpr",
|
|
1373
|
+
data: { name: node.id.name }
|
|
1374
|
+
});
|
|
1375
|
+
}
|
|
1376
|
+
}
|
|
1377
|
+
};
|
|
1378
|
+
}
|
|
1379
|
+
});
|
|
1380
|
+
var prefer_function_declaration_default = preferFunctionDeclaration;
|
|
1381
|
+
|
|
938
1382
|
// src/rules/prefer-import-type.ts
|
|
939
|
-
import { AST_NODE_TYPES as
|
|
940
|
-
var
|
|
1383
|
+
import { AST_NODE_TYPES as AST_NODE_TYPES15, ESLintUtils as ESLintUtils18 } from "@typescript-eslint/utils";
|
|
1384
|
+
var createRule18 = ESLintUtils18.RuleCreator(
|
|
941
1385
|
(name) => `https://github.com/next-friday/eslint-plugin-nextfriday/blob/main/docs/rules/${name.replaceAll("-", "_").toUpperCase()}.md`
|
|
942
1386
|
);
|
|
943
|
-
var preferImportType =
|
|
1387
|
+
var preferImportType = createRule18({
|
|
944
1388
|
name: "prefer-import-type",
|
|
945
1389
|
meta: {
|
|
946
1390
|
type: "suggestion",
|
|
@@ -959,22 +1403,22 @@ var preferImportType = createRule14({
|
|
|
959
1403
|
let current = node;
|
|
960
1404
|
while (current) {
|
|
961
1405
|
switch (current.type) {
|
|
962
|
-
case
|
|
963
|
-
case
|
|
964
|
-
case
|
|
965
|
-
case
|
|
966
|
-
case
|
|
967
|
-
case
|
|
968
|
-
case
|
|
969
|
-
case
|
|
970
|
-
case
|
|
971
|
-
case
|
|
972
|
-
case
|
|
973
|
-
case
|
|
974
|
-
case
|
|
1406
|
+
case AST_NODE_TYPES15.TSTypeReference:
|
|
1407
|
+
case AST_NODE_TYPES15.TSTypeAnnotation:
|
|
1408
|
+
case AST_NODE_TYPES15.TSTypeParameterInstantiation:
|
|
1409
|
+
case AST_NODE_TYPES15.TSInterfaceHeritage:
|
|
1410
|
+
case AST_NODE_TYPES15.TSClassImplements:
|
|
1411
|
+
case AST_NODE_TYPES15.TSTypeQuery:
|
|
1412
|
+
case AST_NODE_TYPES15.TSTypeAssertion:
|
|
1413
|
+
case AST_NODE_TYPES15.TSAsExpression:
|
|
1414
|
+
case AST_NODE_TYPES15.TSSatisfiesExpression:
|
|
1415
|
+
case AST_NODE_TYPES15.TSTypeAliasDeclaration:
|
|
1416
|
+
case AST_NODE_TYPES15.TSInterfaceDeclaration:
|
|
1417
|
+
case AST_NODE_TYPES15.TSTypeParameter:
|
|
1418
|
+
case AST_NODE_TYPES15.TSQualifiedName:
|
|
975
1419
|
return true;
|
|
976
|
-
case
|
|
977
|
-
case
|
|
1420
|
+
case AST_NODE_TYPES15.MemberExpression:
|
|
1421
|
+
case AST_NODE_TYPES15.Identifier:
|
|
978
1422
|
current = current.parent;
|
|
979
1423
|
break;
|
|
980
1424
|
default:
|
|
@@ -1004,26 +1448,26 @@ var preferImportType = createRule14({
|
|
|
1004
1448
|
return false;
|
|
1005
1449
|
}
|
|
1006
1450
|
switch (parent.type) {
|
|
1007
|
-
case
|
|
1008
|
-
case
|
|
1009
|
-
case
|
|
1010
|
-
case
|
|
1011
|
-
case
|
|
1012
|
-
case
|
|
1013
|
-
case
|
|
1014
|
-
case
|
|
1015
|
-
case
|
|
1016
|
-
case
|
|
1017
|
-
case
|
|
1018
|
-
case
|
|
1019
|
-
case
|
|
1020
|
-
case
|
|
1021
|
-
case
|
|
1022
|
-
case
|
|
1023
|
-
case
|
|
1024
|
-
case
|
|
1025
|
-
case
|
|
1026
|
-
case
|
|
1451
|
+
case AST_NODE_TYPES15.CallExpression:
|
|
1452
|
+
case AST_NODE_TYPES15.NewExpression:
|
|
1453
|
+
case AST_NODE_TYPES15.JSXOpeningElement:
|
|
1454
|
+
case AST_NODE_TYPES15.JSXClosingElement:
|
|
1455
|
+
case AST_NODE_TYPES15.MemberExpression:
|
|
1456
|
+
case AST_NODE_TYPES15.VariableDeclarator:
|
|
1457
|
+
case AST_NODE_TYPES15.TaggedTemplateExpression:
|
|
1458
|
+
case AST_NODE_TYPES15.SpreadElement:
|
|
1459
|
+
case AST_NODE_TYPES15.ExportSpecifier:
|
|
1460
|
+
case AST_NODE_TYPES15.ArrayExpression:
|
|
1461
|
+
case AST_NODE_TYPES15.ObjectExpression:
|
|
1462
|
+
case AST_NODE_TYPES15.BinaryExpression:
|
|
1463
|
+
case AST_NODE_TYPES15.LogicalExpression:
|
|
1464
|
+
case AST_NODE_TYPES15.UnaryExpression:
|
|
1465
|
+
case AST_NODE_TYPES15.ReturnStatement:
|
|
1466
|
+
case AST_NODE_TYPES15.ArrowFunctionExpression:
|
|
1467
|
+
case AST_NODE_TYPES15.ConditionalExpression:
|
|
1468
|
+
case AST_NODE_TYPES15.AwaitExpression:
|
|
1469
|
+
case AST_NODE_TYPES15.YieldExpression:
|
|
1470
|
+
case AST_NODE_TYPES15.Property:
|
|
1027
1471
|
return true;
|
|
1028
1472
|
default:
|
|
1029
1473
|
return false;
|
|
@@ -1047,13 +1491,13 @@ var preferImportType = createRule14({
|
|
|
1047
1491
|
}
|
|
1048
1492
|
const scope = context.sourceCode.getScope(node);
|
|
1049
1493
|
const isTypeOnlyImport = node.specifiers.every((specifier) => {
|
|
1050
|
-
if (specifier.type ===
|
|
1494
|
+
if (specifier.type === AST_NODE_TYPES15.ImportDefaultSpecifier) {
|
|
1051
1495
|
return false;
|
|
1052
1496
|
}
|
|
1053
|
-
if (specifier.type ===
|
|
1497
|
+
if (specifier.type === AST_NODE_TYPES15.ImportNamespaceSpecifier) {
|
|
1054
1498
|
return false;
|
|
1055
1499
|
}
|
|
1056
|
-
if (specifier.type ===
|
|
1500
|
+
if (specifier.type === AST_NODE_TYPES15.ImportSpecifier) {
|
|
1057
1501
|
const localName = specifier.local.name;
|
|
1058
1502
|
return !isUsedAsValue(localName, scope);
|
|
1059
1503
|
}
|
|
@@ -1079,11 +1523,11 @@ var preferImportType = createRule14({
|
|
|
1079
1523
|
var prefer_import_type_default = preferImportType;
|
|
1080
1524
|
|
|
1081
1525
|
// src/rules/prefer-interface-over-inline-types.ts
|
|
1082
|
-
import { AST_NODE_TYPES as
|
|
1083
|
-
var
|
|
1526
|
+
import { AST_NODE_TYPES as AST_NODE_TYPES16, ESLintUtils as ESLintUtils19 } from "@typescript-eslint/utils";
|
|
1527
|
+
var createRule19 = ESLintUtils19.RuleCreator(
|
|
1084
1528
|
(name) => `https://github.com/next-friday/eslint-plugin-nextfriday/blob/main/docs/rules/${name.replaceAll("-", "_").toUpperCase()}.md`
|
|
1085
1529
|
);
|
|
1086
|
-
var preferInterfaceOverInlineTypes =
|
|
1530
|
+
var preferInterfaceOverInlineTypes = createRule19({
|
|
1087
1531
|
name: "prefer-interface-over-inline-types",
|
|
1088
1532
|
meta: {
|
|
1089
1533
|
type: "suggestion",
|
|
@@ -1099,67 +1543,67 @@ var preferInterfaceOverInlineTypes = createRule15({
|
|
|
1099
1543
|
defaultOptions: [],
|
|
1100
1544
|
create(context) {
|
|
1101
1545
|
function hasJSXInConditional(node) {
|
|
1102
|
-
return node.consequent.type ===
|
|
1546
|
+
return node.consequent.type === AST_NODE_TYPES16.JSXElement || node.consequent.type === AST_NODE_TYPES16.JSXFragment || node.alternate.type === AST_NODE_TYPES16.JSXElement || node.alternate.type === AST_NODE_TYPES16.JSXFragment;
|
|
1103
1547
|
}
|
|
1104
1548
|
function hasJSXInLogical(node) {
|
|
1105
|
-
return node.right.type ===
|
|
1549
|
+
return node.right.type === AST_NODE_TYPES16.JSXElement || node.right.type === AST_NODE_TYPES16.JSXFragment;
|
|
1106
1550
|
}
|
|
1107
1551
|
function hasJSXReturn(block) {
|
|
1108
1552
|
return block.body.some((stmt) => {
|
|
1109
|
-
if (stmt.type ===
|
|
1110
|
-
return stmt.argument.type ===
|
|
1553
|
+
if (stmt.type === AST_NODE_TYPES16.ReturnStatement && stmt.argument) {
|
|
1554
|
+
return stmt.argument.type === AST_NODE_TYPES16.JSXElement || stmt.argument.type === AST_NODE_TYPES16.JSXFragment || stmt.argument.type === AST_NODE_TYPES16.ConditionalExpression && hasJSXInConditional(stmt.argument) || stmt.argument.type === AST_NODE_TYPES16.LogicalExpression && hasJSXInLogical(stmt.argument);
|
|
1111
1555
|
}
|
|
1112
1556
|
return false;
|
|
1113
1557
|
});
|
|
1114
1558
|
}
|
|
1115
|
-
function
|
|
1116
|
-
if (node.type ===
|
|
1117
|
-
if (node.body.type ===
|
|
1559
|
+
function isReactComponent2(node) {
|
|
1560
|
+
if (node.type === AST_NODE_TYPES16.ArrowFunctionExpression) {
|
|
1561
|
+
if (node.body.type === AST_NODE_TYPES16.JSXElement || node.body.type === AST_NODE_TYPES16.JSXFragment) {
|
|
1118
1562
|
return true;
|
|
1119
1563
|
}
|
|
1120
|
-
if (node.body.type ===
|
|
1564
|
+
if (node.body.type === AST_NODE_TYPES16.BlockStatement) {
|
|
1121
1565
|
return hasJSXReturn(node.body);
|
|
1122
1566
|
}
|
|
1123
|
-
} else if (node.type ===
|
|
1124
|
-
if (node.body && node.body.type ===
|
|
1567
|
+
} else if (node.type === AST_NODE_TYPES16.FunctionExpression || node.type === AST_NODE_TYPES16.FunctionDeclaration) {
|
|
1568
|
+
if (node.body && node.body.type === AST_NODE_TYPES16.BlockStatement) {
|
|
1125
1569
|
return hasJSXReturn(node.body);
|
|
1126
1570
|
}
|
|
1127
1571
|
}
|
|
1128
1572
|
return false;
|
|
1129
1573
|
}
|
|
1130
1574
|
function isInlineTypeAnnotation(node) {
|
|
1131
|
-
if (node.type ===
|
|
1575
|
+
if (node.type === AST_NODE_TYPES16.TSTypeLiteral) {
|
|
1132
1576
|
return true;
|
|
1133
1577
|
}
|
|
1134
|
-
if (node.type ===
|
|
1135
|
-
return node.typeArguments.params.some((param) => param.type ===
|
|
1578
|
+
if (node.type === AST_NODE_TYPES16.TSTypeReference && node.typeArguments) {
|
|
1579
|
+
return node.typeArguments.params.some((param) => param.type === AST_NODE_TYPES16.TSTypeLiteral);
|
|
1136
1580
|
}
|
|
1137
|
-
if (node.type ===
|
|
1581
|
+
if (node.type === AST_NODE_TYPES16.TSUnionType) {
|
|
1138
1582
|
return node.types.some((type) => isInlineTypeAnnotation(type));
|
|
1139
1583
|
}
|
|
1140
1584
|
return false;
|
|
1141
1585
|
}
|
|
1142
1586
|
function hasInlineObjectType(node) {
|
|
1143
|
-
if (node.type ===
|
|
1587
|
+
if (node.type === AST_NODE_TYPES16.TSTypeLiteral) {
|
|
1144
1588
|
return true;
|
|
1145
1589
|
}
|
|
1146
|
-
if (node.type ===
|
|
1147
|
-
return node.typeArguments.params.some((param) => param.type ===
|
|
1590
|
+
if (node.type === AST_NODE_TYPES16.TSTypeReference && node.typeArguments) {
|
|
1591
|
+
return node.typeArguments.params.some((param) => param.type === AST_NODE_TYPES16.TSTypeLiteral);
|
|
1148
1592
|
}
|
|
1149
|
-
if (node.type ===
|
|
1593
|
+
if (node.type === AST_NODE_TYPES16.TSUnionType) {
|
|
1150
1594
|
return node.types.some((type) => hasInlineObjectType(type));
|
|
1151
1595
|
}
|
|
1152
1596
|
return false;
|
|
1153
1597
|
}
|
|
1154
1598
|
function checkFunction(node) {
|
|
1155
|
-
if (!
|
|
1599
|
+
if (!isReactComponent2(node)) {
|
|
1156
1600
|
return;
|
|
1157
1601
|
}
|
|
1158
1602
|
if (node.params.length !== 1) {
|
|
1159
1603
|
return;
|
|
1160
1604
|
}
|
|
1161
1605
|
const param = node.params[0];
|
|
1162
|
-
if (param.type ===
|
|
1606
|
+
if (param.type === AST_NODE_TYPES16.Identifier && param.typeAnnotation) {
|
|
1163
1607
|
const { typeAnnotation } = param.typeAnnotation;
|
|
1164
1608
|
if (isInlineTypeAnnotation(typeAnnotation) && hasInlineObjectType(typeAnnotation)) {
|
|
1165
1609
|
context.report({
|
|
@@ -1179,11 +1623,11 @@ var preferInterfaceOverInlineTypes = createRule15({
|
|
|
1179
1623
|
var prefer_interface_over_inline_types_default = preferInterfaceOverInlineTypes;
|
|
1180
1624
|
|
|
1181
1625
|
// src/rules/prefer-jsx-template-literals.ts
|
|
1182
|
-
import { AST_NODE_TYPES as
|
|
1183
|
-
var
|
|
1626
|
+
import { AST_NODE_TYPES as AST_NODE_TYPES17, ESLintUtils as ESLintUtils20 } from "@typescript-eslint/utils";
|
|
1627
|
+
var createRule20 = ESLintUtils20.RuleCreator(
|
|
1184
1628
|
(name) => `https://github.com/next-friday/eslint-plugin-nextfriday/blob/main/docs/rules/${name.replaceAll("-", "_").toUpperCase()}.md`
|
|
1185
1629
|
);
|
|
1186
|
-
var preferJSXTemplateLiterals =
|
|
1630
|
+
var preferJSXTemplateLiterals = createRule20({
|
|
1187
1631
|
name: "prefer-jsx-template-literals",
|
|
1188
1632
|
meta: {
|
|
1189
1633
|
type: "suggestion",
|
|
@@ -1252,9 +1696,9 @@ var preferJSXTemplateLiterals = createRule16({
|
|
|
1252
1696
|
if (!child || !nextChild) {
|
|
1253
1697
|
return;
|
|
1254
1698
|
}
|
|
1255
|
-
if (child.type ===
|
|
1699
|
+
if (child.type === AST_NODE_TYPES17.JSXText && nextChild.type === AST_NODE_TYPES17.JSXExpressionContainer) {
|
|
1256
1700
|
handleTextBeforeExpression(child, nextChild);
|
|
1257
|
-
} else if (child.type ===
|
|
1701
|
+
} else if (child.type === AST_NODE_TYPES17.JSXExpressionContainer && nextChild.type === AST_NODE_TYPES17.JSXText) {
|
|
1258
1702
|
handleExpressionBeforeText(child, nextChild);
|
|
1259
1703
|
}
|
|
1260
1704
|
}
|
|
@@ -1267,11 +1711,11 @@ var preferJSXTemplateLiterals = createRule16({
|
|
|
1267
1711
|
var prefer_jsx_template_literals_default = preferJSXTemplateLiterals;
|
|
1268
1712
|
|
|
1269
1713
|
// src/rules/prefer-named-param-types.ts
|
|
1270
|
-
import { AST_NODE_TYPES as
|
|
1271
|
-
var
|
|
1714
|
+
import { AST_NODE_TYPES as AST_NODE_TYPES18, ESLintUtils as ESLintUtils21 } from "@typescript-eslint/utils";
|
|
1715
|
+
var createRule21 = ESLintUtils21.RuleCreator(
|
|
1272
1716
|
(name) => `https://github.com/next-friday/eslint-plugin-nextfriday/blob/main/docs/rules/${name.replaceAll("-", "_").toUpperCase()}.md`
|
|
1273
1717
|
);
|
|
1274
|
-
var preferNamedParamTypes =
|
|
1718
|
+
var preferNamedParamTypes = createRule21({
|
|
1275
1719
|
name: "prefer-named-param-types",
|
|
1276
1720
|
meta: {
|
|
1277
1721
|
type: "suggestion",
|
|
@@ -1286,16 +1730,16 @@ var preferNamedParamTypes = createRule17({
|
|
|
1286
1730
|
defaultOptions: [],
|
|
1287
1731
|
create(context) {
|
|
1288
1732
|
function hasInlineObjectType(param) {
|
|
1289
|
-
if (param.type ===
|
|
1733
|
+
if (param.type === AST_NODE_TYPES18.AssignmentPattern) {
|
|
1290
1734
|
return hasInlineObjectType(param.left);
|
|
1291
1735
|
}
|
|
1292
|
-
if (param.type ===
|
|
1293
|
-
if (param.typeAnnotation?.typeAnnotation.type ===
|
|
1736
|
+
if (param.type === AST_NODE_TYPES18.ObjectPattern) {
|
|
1737
|
+
if (param.typeAnnotation?.typeAnnotation.type === AST_NODE_TYPES18.TSTypeLiteral) {
|
|
1294
1738
|
return true;
|
|
1295
1739
|
}
|
|
1296
1740
|
}
|
|
1297
|
-
if (param.type ===
|
|
1298
|
-
if (param.typeAnnotation?.typeAnnotation.type ===
|
|
1741
|
+
if (param.type === AST_NODE_TYPES18.Identifier) {
|
|
1742
|
+
if (param.typeAnnotation?.typeAnnotation.type === AST_NODE_TYPES18.TSTypeLiteral) {
|
|
1299
1743
|
return true;
|
|
1300
1744
|
}
|
|
1301
1745
|
}
|
|
@@ -1329,11 +1773,11 @@ var preferNamedParamTypes = createRule17({
|
|
|
1329
1773
|
var prefer_named_param_types_default = preferNamedParamTypes;
|
|
1330
1774
|
|
|
1331
1775
|
// src/rules/prefer-react-import-types.ts
|
|
1332
|
-
import { AST_NODE_TYPES as
|
|
1333
|
-
var
|
|
1776
|
+
import { AST_NODE_TYPES as AST_NODE_TYPES19, ESLintUtils as ESLintUtils22 } from "@typescript-eslint/utils";
|
|
1777
|
+
var createRule22 = ESLintUtils22.RuleCreator(
|
|
1334
1778
|
(name) => `https://github.com/next-friday/eslint-plugin-nextfriday/blob/main/docs/rules/${name.replaceAll("-", "_").toUpperCase()}.md`
|
|
1335
1779
|
);
|
|
1336
|
-
var preferReactImportTypes =
|
|
1780
|
+
var preferReactImportTypes = createRule22({
|
|
1337
1781
|
name: "prefer-react-import-types",
|
|
1338
1782
|
meta: {
|
|
1339
1783
|
type: "suggestion",
|
|
@@ -1409,7 +1853,7 @@ var preferReactImportTypes = createRule18({
|
|
|
1409
1853
|
]);
|
|
1410
1854
|
const allReactExports = /* @__PURE__ */ new Set([...reactTypes, ...reactRuntimeExports]);
|
|
1411
1855
|
function checkMemberExpression(node) {
|
|
1412
|
-
if (node.object.type ===
|
|
1856
|
+
if (node.object.type === AST_NODE_TYPES19.Identifier && node.object.name === "React" && node.property.type === AST_NODE_TYPES19.Identifier && allReactExports.has(node.property.name)) {
|
|
1413
1857
|
const typeName = node.property.name;
|
|
1414
1858
|
const isType = reactTypes.has(typeName);
|
|
1415
1859
|
const importStatement = isType ? `import type { ${typeName} } from "react"` : `import { ${typeName} } from "react"`;
|
|
@@ -1426,7 +1870,7 @@ var preferReactImportTypes = createRule18({
|
|
|
1426
1870
|
return {
|
|
1427
1871
|
MemberExpression: checkMemberExpression,
|
|
1428
1872
|
"TSTypeReference > TSQualifiedName": (node) => {
|
|
1429
|
-
if (node.left.type ===
|
|
1873
|
+
if (node.left.type === AST_NODE_TYPES19.Identifier && node.left.name === "React" && node.right.type === AST_NODE_TYPES19.Identifier && allReactExports.has(node.right.name)) {
|
|
1430
1874
|
const typeName = node.right.name;
|
|
1431
1875
|
const isType = reactTypes.has(typeName);
|
|
1432
1876
|
const importStatement = isType ? `import type { ${typeName} } from "react"` : `import { ${typeName} } from "react"`;
|
|
@@ -1446,11 +1890,11 @@ var preferReactImportTypes = createRule18({
|
|
|
1446
1890
|
var prefer_react_import_types_default = preferReactImportTypes;
|
|
1447
1891
|
|
|
1448
1892
|
// src/rules/react-props-destructure.ts
|
|
1449
|
-
import { AST_NODE_TYPES as
|
|
1450
|
-
var
|
|
1893
|
+
import { AST_NODE_TYPES as AST_NODE_TYPES20, ESLintUtils as ESLintUtils23 } from "@typescript-eslint/utils";
|
|
1894
|
+
var createRule23 = ESLintUtils23.RuleCreator(
|
|
1451
1895
|
(name) => `https://github.com/next-friday/eslint-plugin-nextfriday/blob/main/docs/rules/${name.replaceAll("-", "_").toUpperCase()}.md`
|
|
1452
1896
|
);
|
|
1453
|
-
var reactPropsDestructure =
|
|
1897
|
+
var reactPropsDestructure = createRule23({
|
|
1454
1898
|
name: "react-props-destructure",
|
|
1455
1899
|
meta: {
|
|
1456
1900
|
type: "suggestion",
|
|
@@ -1466,45 +1910,45 @@ var reactPropsDestructure = createRule19({
|
|
|
1466
1910
|
defaultOptions: [],
|
|
1467
1911
|
create(context) {
|
|
1468
1912
|
function hasJSXInConditional(node) {
|
|
1469
|
-
return node.consequent.type ===
|
|
1913
|
+
return node.consequent.type === AST_NODE_TYPES20.JSXElement || node.consequent.type === AST_NODE_TYPES20.JSXFragment || node.alternate.type === AST_NODE_TYPES20.JSXElement || node.alternate.type === AST_NODE_TYPES20.JSXFragment;
|
|
1470
1914
|
}
|
|
1471
1915
|
function hasJSXInLogical(node) {
|
|
1472
|
-
return node.right.type ===
|
|
1916
|
+
return node.right.type === AST_NODE_TYPES20.JSXElement || node.right.type === AST_NODE_TYPES20.JSXFragment;
|
|
1473
1917
|
}
|
|
1474
1918
|
function hasJSXReturn(block) {
|
|
1475
1919
|
return block.body.some((stmt) => {
|
|
1476
|
-
if (stmt.type ===
|
|
1477
|
-
return stmt.argument.type ===
|
|
1920
|
+
if (stmt.type === AST_NODE_TYPES20.ReturnStatement && stmt.argument) {
|
|
1921
|
+
return stmt.argument.type === AST_NODE_TYPES20.JSXElement || stmt.argument.type === AST_NODE_TYPES20.JSXFragment || stmt.argument.type === AST_NODE_TYPES20.ConditionalExpression && hasJSXInConditional(stmt.argument) || stmt.argument.type === AST_NODE_TYPES20.LogicalExpression && hasJSXInLogical(stmt.argument);
|
|
1478
1922
|
}
|
|
1479
1923
|
return false;
|
|
1480
1924
|
});
|
|
1481
1925
|
}
|
|
1482
|
-
function
|
|
1483
|
-
if (node.type ===
|
|
1484
|
-
if (node.body.type ===
|
|
1926
|
+
function isReactComponent2(node) {
|
|
1927
|
+
if (node.type === AST_NODE_TYPES20.ArrowFunctionExpression) {
|
|
1928
|
+
if (node.body.type === AST_NODE_TYPES20.JSXElement || node.body.type === AST_NODE_TYPES20.JSXFragment) {
|
|
1485
1929
|
return true;
|
|
1486
1930
|
}
|
|
1487
|
-
if (node.body.type ===
|
|
1931
|
+
if (node.body.type === AST_NODE_TYPES20.BlockStatement) {
|
|
1488
1932
|
return hasJSXReturn(node.body);
|
|
1489
1933
|
}
|
|
1490
|
-
} else if (node.type ===
|
|
1491
|
-
if (node.body && node.body.type ===
|
|
1934
|
+
} else if (node.type === AST_NODE_TYPES20.FunctionExpression || node.type === AST_NODE_TYPES20.FunctionDeclaration) {
|
|
1935
|
+
if (node.body && node.body.type === AST_NODE_TYPES20.BlockStatement) {
|
|
1492
1936
|
return hasJSXReturn(node.body);
|
|
1493
1937
|
}
|
|
1494
1938
|
}
|
|
1495
1939
|
return false;
|
|
1496
1940
|
}
|
|
1497
1941
|
function checkFunction(node) {
|
|
1498
|
-
if (!
|
|
1942
|
+
if (!isReactComponent2(node)) {
|
|
1499
1943
|
return;
|
|
1500
1944
|
}
|
|
1501
1945
|
if (node.params.length !== 1) {
|
|
1502
1946
|
return;
|
|
1503
1947
|
}
|
|
1504
1948
|
const param = node.params[0];
|
|
1505
|
-
if (param.type ===
|
|
1506
|
-
const properties = param.properties.filter((prop) => prop.type ===
|
|
1507
|
-
if (prop.key.type ===
|
|
1949
|
+
if (param.type === AST_NODE_TYPES20.ObjectPattern) {
|
|
1950
|
+
const properties = param.properties.filter((prop) => prop.type === AST_NODE_TYPES20.Property).map((prop) => {
|
|
1951
|
+
if (prop.key.type === AST_NODE_TYPES20.Identifier) {
|
|
1508
1952
|
return prop.key.name;
|
|
1509
1953
|
}
|
|
1510
1954
|
return null;
|
|
@@ -1536,6 +1980,7 @@ var meta = {
|
|
|
1536
1980
|
version: package_default.version
|
|
1537
1981
|
};
|
|
1538
1982
|
var rules = {
|
|
1983
|
+
"boolean-naming-prefix": boolean_naming_prefix_default,
|
|
1539
1984
|
"enforce-readonly-component-props": enforce_readonly_component_props_default,
|
|
1540
1985
|
"enforce-sorted-destructuring": enforce_sorted_destructuring_default,
|
|
1541
1986
|
"file-kebab-case": file_kebab_case_default,
|
|
@@ -1544,11 +1989,14 @@ var rules = {
|
|
|
1544
1989
|
"jsx-no-variable-in-callback": jsx_no_variable_in_callback_default,
|
|
1545
1990
|
"md-filename-case-restriction": md_filename_case_restriction_default,
|
|
1546
1991
|
"no-complex-inline-return": no_complex_inline_return_default,
|
|
1992
|
+
"no-direct-date": no_direct_date_default,
|
|
1547
1993
|
"no-emoji": no_emoji_default,
|
|
1548
1994
|
"no-env-fallback": no_env_fallback_default,
|
|
1549
|
-
"
|
|
1995
|
+
"require-explicit-return-type": require_explicit_return_type_default,
|
|
1550
1996
|
"no-logic-in-params": no_logic_in_params_default,
|
|
1997
|
+
"no-single-char-variables": no_single_char_variables_default,
|
|
1551
1998
|
"prefer-destructuring-params": prefer_destructuring_params_default,
|
|
1999
|
+
"prefer-function-declaration": prefer_function_declaration_default,
|
|
1552
2000
|
"prefer-import-type": prefer_import_type_default,
|
|
1553
2001
|
"prefer-interface-over-inline-types": prefer_interface_over_inline_types_default,
|
|
1554
2002
|
"prefer-jsx-template-literals": prefer_jsx_template_literals_default,
|
|
@@ -1561,32 +2009,40 @@ var plugin = {
|
|
|
1561
2009
|
rules
|
|
1562
2010
|
};
|
|
1563
2011
|
var baseRules = {
|
|
2012
|
+
"nextfriday/boolean-naming-prefix": "warn",
|
|
1564
2013
|
"nextfriday/no-emoji": "warn",
|
|
1565
2014
|
"nextfriday/enforce-sorted-destructuring": "warn",
|
|
1566
2015
|
"nextfriday/file-kebab-case": "warn",
|
|
1567
2016
|
"nextfriday/md-filename-case-restriction": "warn",
|
|
1568
2017
|
"nextfriday/prefer-destructuring-params": "warn",
|
|
1569
|
-
"nextfriday/
|
|
2018
|
+
"nextfriday/prefer-function-declaration": "warn",
|
|
2019
|
+
"nextfriday/require-explicit-return-type": "warn",
|
|
1570
2020
|
"nextfriday/prefer-import-type": "warn",
|
|
1571
2021
|
"nextfriday/prefer-named-param-types": "warn",
|
|
1572
2022
|
"nextfriday/prefer-react-import-types": "warn",
|
|
1573
2023
|
"nextfriday/no-complex-inline-return": "warn",
|
|
2024
|
+
"nextfriday/no-direct-date": "warn",
|
|
1574
2025
|
"nextfriday/no-logic-in-params": "warn",
|
|
1575
|
-
"nextfriday/no-env-fallback": "warn"
|
|
2026
|
+
"nextfriday/no-env-fallback": "warn",
|
|
2027
|
+
"nextfriday/no-single-char-variables": "warn"
|
|
1576
2028
|
};
|
|
1577
2029
|
var baseRecommendedRules = {
|
|
2030
|
+
"nextfriday/boolean-naming-prefix": "error",
|
|
1578
2031
|
"nextfriday/no-emoji": "error",
|
|
1579
2032
|
"nextfriday/enforce-sorted-destructuring": "error",
|
|
1580
2033
|
"nextfriday/file-kebab-case": "error",
|
|
1581
2034
|
"nextfriday/md-filename-case-restriction": "error",
|
|
1582
2035
|
"nextfriday/prefer-destructuring-params": "error",
|
|
1583
|
-
"nextfriday/
|
|
2036
|
+
"nextfriday/prefer-function-declaration": "error",
|
|
2037
|
+
"nextfriday/require-explicit-return-type": "error",
|
|
1584
2038
|
"nextfriday/prefer-import-type": "error",
|
|
1585
2039
|
"nextfriday/prefer-named-param-types": "error",
|
|
1586
2040
|
"nextfriday/prefer-react-import-types": "error",
|
|
1587
2041
|
"nextfriday/no-complex-inline-return": "error",
|
|
2042
|
+
"nextfriday/no-direct-date": "error",
|
|
1588
2043
|
"nextfriday/no-logic-in-params": "error",
|
|
1589
|
-
"nextfriday/no-env-fallback": "error"
|
|
2044
|
+
"nextfriday/no-env-fallback": "error",
|
|
2045
|
+
"nextfriday/no-single-char-variables": "error"
|
|
1590
2046
|
};
|
|
1591
2047
|
var jsxRules = {
|
|
1592
2048
|
"nextfriday/jsx-pascal-case": "warn",
|