eslint-plugin-nextfriday 1.5.3 → 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 +15 -0
- package/README.md +120 -70
- package/docs/rules/BOOLEAN_NAMING_PREFIX.md +102 -0
- package/docs/rules/ENFORCE_SORTED_DESTRUCTURING.md +122 -0
- package/docs/rules/JSX_NO_NON_COMPONENT_FUNCTION.md +114 -0
- package/docs/rules/JSX_NO_VARIABLE_IN_CALLBACK.md +144 -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/PREFER_JSX_TEMPLATE_LITERALS.md +78 -0
- package/docs/rules/REQUIRE_EXPLICIT_RETURN_TYPE.md +130 -0
- package/lib/index.cjs +1078 -172
- package/lib/index.cjs.map +1 -1
- package/lib/index.d.cts +126 -14
- package/lib/index.d.ts +126 -14
- package/lib/index.js +1079 -173
- 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.cjs
CHANGED
|
@@ -40,7 +40,7 @@ module.exports = __toCommonJS(index_exports);
|
|
|
40
40
|
// package.json
|
|
41
41
|
var package_default = {
|
|
42
42
|
name: "eslint-plugin-nextfriday",
|
|
43
|
-
version: "1.
|
|
43
|
+
version: "1.7.0",
|
|
44
44
|
description: "A comprehensive ESLint plugin providing custom rules and configurations for Next Friday development workflows.",
|
|
45
45
|
keywords: [
|
|
46
46
|
"eslint",
|
|
@@ -154,12 +154,143 @@ var package_default = {
|
|
|
154
154
|
}
|
|
155
155
|
};
|
|
156
156
|
|
|
157
|
-
// src/rules/
|
|
157
|
+
// src/rules/boolean-naming-prefix.ts
|
|
158
158
|
var import_utils = require("@typescript-eslint/utils");
|
|
159
159
|
var createRule = import_utils.ESLintUtils.RuleCreator(
|
|
160
|
-
(name) => `https://github.com/next-friday/eslint-plugin-nextfriday/blob/main/docs/rules/${name.
|
|
160
|
+
(name) => `https://github.com/next-friday/eslint-plugin-nextfriday/blob/main/docs/rules/${name.replaceAll("-", "_").toUpperCase()}.md`
|
|
161
|
+
);
|
|
162
|
+
var BOOLEAN_PREFIXES = ["is", "has", "should", "can", "did", "will", "was", "are", "does", "had"];
|
|
163
|
+
var startsWithBooleanPrefix = (name) => {
|
|
164
|
+
const lowerName = name.toLowerCase();
|
|
165
|
+
return BOOLEAN_PREFIXES.some((prefix) => {
|
|
166
|
+
if (!lowerName.startsWith(prefix)) {
|
|
167
|
+
return false;
|
|
168
|
+
}
|
|
169
|
+
if (name.length === prefix.length) {
|
|
170
|
+
return true;
|
|
171
|
+
}
|
|
172
|
+
const nextChar = name.charAt(prefix.length);
|
|
173
|
+
return nextChar === nextChar.toUpperCase();
|
|
174
|
+
});
|
|
175
|
+
};
|
|
176
|
+
var isBooleanLiteral = (node) => node.type === import_utils.AST_NODE_TYPES.Literal && typeof node.value === "boolean";
|
|
177
|
+
var isBooleanExpression = (node) => {
|
|
178
|
+
if (isBooleanLiteral(node)) {
|
|
179
|
+
return true;
|
|
180
|
+
}
|
|
181
|
+
if (node.type === import_utils.AST_NODE_TYPES.UnaryExpression && node.operator === "!") {
|
|
182
|
+
return true;
|
|
183
|
+
}
|
|
184
|
+
if (node.type === import_utils.AST_NODE_TYPES.BinaryExpression) {
|
|
185
|
+
const comparisonOperators = ["===", "!==", "==", "!=", "<", ">", "<=", ">=", "in", "instanceof"];
|
|
186
|
+
return comparisonOperators.includes(node.operator);
|
|
187
|
+
}
|
|
188
|
+
if (node.type === import_utils.AST_NODE_TYPES.LogicalExpression) {
|
|
189
|
+
return node.operator === "&&" || node.operator === "||";
|
|
190
|
+
}
|
|
191
|
+
return false;
|
|
192
|
+
};
|
|
193
|
+
var hasBooleanTypeAnnotation = (node) => {
|
|
194
|
+
if (node.type === import_utils.AST_NODE_TYPES.Identifier) {
|
|
195
|
+
const { typeAnnotation } = node;
|
|
196
|
+
if (typeAnnotation?.typeAnnotation.type === import_utils.AST_NODE_TYPES.TSBooleanKeyword) {
|
|
197
|
+
return true;
|
|
198
|
+
}
|
|
199
|
+
}
|
|
200
|
+
if ("id" in node && node.id.type === import_utils.AST_NODE_TYPES.Identifier) {
|
|
201
|
+
const { typeAnnotation } = node.id;
|
|
202
|
+
if (typeAnnotation?.typeAnnotation.type === import_utils.AST_NODE_TYPES.TSBooleanKeyword) {
|
|
203
|
+
return true;
|
|
204
|
+
}
|
|
205
|
+
}
|
|
206
|
+
return false;
|
|
207
|
+
};
|
|
208
|
+
var booleanNamingPrefix = createRule({
|
|
209
|
+
name: "boolean-naming-prefix",
|
|
210
|
+
meta: {
|
|
211
|
+
type: "suggestion",
|
|
212
|
+
docs: {
|
|
213
|
+
description: "Enforce boolean variables and parameters to have a prefix like is, has, should, can, did, will for better readability"
|
|
214
|
+
},
|
|
215
|
+
messages: {
|
|
216
|
+
missingPrefix: "Boolean variable '{{name}}' should have a prefix like is, has, should, can, did, or will. Example: 'is{{suggestedName}}' or 'has{{suggestedName}}'."
|
|
217
|
+
},
|
|
218
|
+
schema: []
|
|
219
|
+
},
|
|
220
|
+
defaultOptions: [],
|
|
221
|
+
create(context) {
|
|
222
|
+
const checkBooleanNaming = (name, node) => {
|
|
223
|
+
if (startsWithBooleanPrefix(name)) {
|
|
224
|
+
return;
|
|
225
|
+
}
|
|
226
|
+
const suggestedName = name.charAt(0).toUpperCase() + name.slice(1);
|
|
227
|
+
context.report({
|
|
228
|
+
node,
|
|
229
|
+
messageId: "missingPrefix",
|
|
230
|
+
data: { name, suggestedName }
|
|
231
|
+
});
|
|
232
|
+
};
|
|
233
|
+
return {
|
|
234
|
+
VariableDeclarator(node) {
|
|
235
|
+
if (node.id.type !== import_utils.AST_NODE_TYPES.Identifier) {
|
|
236
|
+
return;
|
|
237
|
+
}
|
|
238
|
+
const { name } = node.id;
|
|
239
|
+
if (hasBooleanTypeAnnotation(node)) {
|
|
240
|
+
checkBooleanNaming(name, node.id);
|
|
241
|
+
return;
|
|
242
|
+
}
|
|
243
|
+
if (node.init && isBooleanExpression(node.init)) {
|
|
244
|
+
checkBooleanNaming(name, node.id);
|
|
245
|
+
}
|
|
246
|
+
},
|
|
247
|
+
FunctionDeclaration(node) {
|
|
248
|
+
node.params.forEach((param) => {
|
|
249
|
+
if (param.type === import_utils.AST_NODE_TYPES.Identifier && hasBooleanTypeAnnotation(param)) {
|
|
250
|
+
checkBooleanNaming(param.name, param);
|
|
251
|
+
}
|
|
252
|
+
if (param.type === import_utils.AST_NODE_TYPES.AssignmentPattern) {
|
|
253
|
+
if (param.left.type === import_utils.AST_NODE_TYPES.Identifier && param.right && isBooleanLiteral(param.right)) {
|
|
254
|
+
checkBooleanNaming(param.left.name, param.left);
|
|
255
|
+
}
|
|
256
|
+
}
|
|
257
|
+
});
|
|
258
|
+
},
|
|
259
|
+
FunctionExpression(node) {
|
|
260
|
+
node.params.forEach((param) => {
|
|
261
|
+
if (param.type === import_utils.AST_NODE_TYPES.Identifier && hasBooleanTypeAnnotation(param)) {
|
|
262
|
+
checkBooleanNaming(param.name, param);
|
|
263
|
+
}
|
|
264
|
+
if (param.type === import_utils.AST_NODE_TYPES.AssignmentPattern) {
|
|
265
|
+
if (param.left.type === import_utils.AST_NODE_TYPES.Identifier && param.right && isBooleanLiteral(param.right)) {
|
|
266
|
+
checkBooleanNaming(param.left.name, param.left);
|
|
267
|
+
}
|
|
268
|
+
}
|
|
269
|
+
});
|
|
270
|
+
},
|
|
271
|
+
ArrowFunctionExpression(node) {
|
|
272
|
+
node.params.forEach((param) => {
|
|
273
|
+
if (param.type === import_utils.AST_NODE_TYPES.Identifier && hasBooleanTypeAnnotation(param)) {
|
|
274
|
+
checkBooleanNaming(param.name, param);
|
|
275
|
+
}
|
|
276
|
+
if (param.type === import_utils.AST_NODE_TYPES.AssignmentPattern) {
|
|
277
|
+
if (param.left.type === import_utils.AST_NODE_TYPES.Identifier && param.right && isBooleanLiteral(param.right)) {
|
|
278
|
+
checkBooleanNaming(param.left.name, param.left);
|
|
279
|
+
}
|
|
280
|
+
}
|
|
281
|
+
});
|
|
282
|
+
}
|
|
283
|
+
};
|
|
284
|
+
}
|
|
285
|
+
});
|
|
286
|
+
var boolean_naming_prefix_default = booleanNamingPrefix;
|
|
287
|
+
|
|
288
|
+
// src/rules/enforce-readonly-component-props.ts
|
|
289
|
+
var import_utils2 = require("@typescript-eslint/utils");
|
|
290
|
+
var createRule2 = import_utils2.ESLintUtils.RuleCreator(
|
|
291
|
+
(name) => `https://github.com/next-friday/eslint-plugin-nextfriday/blob/main/docs/rules/${name.replaceAll("-", "_").toUpperCase()}.md`
|
|
161
292
|
);
|
|
162
|
-
var enforceReadonlyComponentProps =
|
|
293
|
+
var enforceReadonlyComponentProps = createRule2({
|
|
163
294
|
name: "enforce-readonly-component-props",
|
|
164
295
|
meta: {
|
|
165
296
|
type: "suggestion",
|
|
@@ -175,54 +306,54 @@ var enforceReadonlyComponentProps = createRule({
|
|
|
175
306
|
defaultOptions: [],
|
|
176
307
|
create(context) {
|
|
177
308
|
function hasJSXInConditional(node) {
|
|
178
|
-
return node.consequent.type ===
|
|
309
|
+
return node.consequent.type === import_utils2.AST_NODE_TYPES.JSXElement || node.consequent.type === import_utils2.AST_NODE_TYPES.JSXFragment || node.alternate.type === import_utils2.AST_NODE_TYPES.JSXElement || node.alternate.type === import_utils2.AST_NODE_TYPES.JSXFragment;
|
|
179
310
|
}
|
|
180
311
|
function hasJSXInLogical(node) {
|
|
181
|
-
return node.right.type ===
|
|
312
|
+
return node.right.type === import_utils2.AST_NODE_TYPES.JSXElement || node.right.type === import_utils2.AST_NODE_TYPES.JSXFragment;
|
|
182
313
|
}
|
|
183
314
|
function hasJSXReturn(block) {
|
|
184
315
|
return block.body.some((stmt) => {
|
|
185
|
-
if (stmt.type ===
|
|
186
|
-
return stmt.argument.type ===
|
|
316
|
+
if (stmt.type === import_utils2.AST_NODE_TYPES.ReturnStatement && stmt.argument) {
|
|
317
|
+
return stmt.argument.type === import_utils2.AST_NODE_TYPES.JSXElement || stmt.argument.type === import_utils2.AST_NODE_TYPES.JSXFragment || stmt.argument.type === import_utils2.AST_NODE_TYPES.ConditionalExpression && hasJSXInConditional(stmt.argument) || stmt.argument.type === import_utils2.AST_NODE_TYPES.LogicalExpression && hasJSXInLogical(stmt.argument);
|
|
187
318
|
}
|
|
188
319
|
return false;
|
|
189
320
|
});
|
|
190
321
|
}
|
|
191
|
-
function
|
|
192
|
-
if (node.type ===
|
|
193
|
-
if (node.body.type ===
|
|
322
|
+
function isReactComponent2(node) {
|
|
323
|
+
if (node.type === import_utils2.AST_NODE_TYPES.ArrowFunctionExpression) {
|
|
324
|
+
if (node.body.type === import_utils2.AST_NODE_TYPES.JSXElement || node.body.type === import_utils2.AST_NODE_TYPES.JSXFragment) {
|
|
194
325
|
return true;
|
|
195
326
|
}
|
|
196
|
-
if (node.body.type ===
|
|
327
|
+
if (node.body.type === import_utils2.AST_NODE_TYPES.BlockStatement) {
|
|
197
328
|
return hasJSXReturn(node.body);
|
|
198
329
|
}
|
|
199
|
-
} else if (node.type ===
|
|
200
|
-
if (node.body && node.body.type ===
|
|
330
|
+
} else if (node.type === import_utils2.AST_NODE_TYPES.FunctionExpression || node.type === import_utils2.AST_NODE_TYPES.FunctionDeclaration) {
|
|
331
|
+
if (node.body && node.body.type === import_utils2.AST_NODE_TYPES.BlockStatement) {
|
|
201
332
|
return hasJSXReturn(node.body);
|
|
202
333
|
}
|
|
203
334
|
}
|
|
204
335
|
return false;
|
|
205
336
|
}
|
|
206
337
|
function isNamedType(node) {
|
|
207
|
-
return node.type ===
|
|
338
|
+
return node.type === import_utils2.AST_NODE_TYPES.TSTypeReference;
|
|
208
339
|
}
|
|
209
340
|
function isAlreadyReadonly(node) {
|
|
210
|
-
if (node.type ===
|
|
211
|
-
if (node.typeName.type ===
|
|
341
|
+
if (node.type === import_utils2.AST_NODE_TYPES.TSTypeReference && node.typeName) {
|
|
342
|
+
if (node.typeName.type === import_utils2.AST_NODE_TYPES.Identifier && node.typeName.name === "Readonly") {
|
|
212
343
|
return true;
|
|
213
344
|
}
|
|
214
345
|
}
|
|
215
346
|
return false;
|
|
216
347
|
}
|
|
217
348
|
function checkFunction(node) {
|
|
218
|
-
if (!
|
|
349
|
+
if (!isReactComponent2(node)) {
|
|
219
350
|
return;
|
|
220
351
|
}
|
|
221
352
|
if (node.params.length !== 1) {
|
|
222
353
|
return;
|
|
223
354
|
}
|
|
224
355
|
const param = node.params[0];
|
|
225
|
-
if (param.type ===
|
|
356
|
+
if (param.type === import_utils2.AST_NODE_TYPES.Identifier && param.typeAnnotation) {
|
|
226
357
|
const { typeAnnotation } = param.typeAnnotation;
|
|
227
358
|
if (isNamedType(typeAnnotation) && !isAlreadyReadonly(typeAnnotation)) {
|
|
228
359
|
const { sourceCode } = context;
|
|
@@ -246,11 +377,132 @@ var enforceReadonlyComponentProps = createRule({
|
|
|
246
377
|
});
|
|
247
378
|
var enforce_readonly_component_props_default = enforceReadonlyComponentProps;
|
|
248
379
|
|
|
380
|
+
// src/rules/enforce-sorted-destructuring.ts
|
|
381
|
+
var import_utils3 = require("@typescript-eslint/utils");
|
|
382
|
+
var createRule3 = import_utils3.ESLintUtils.RuleCreator(
|
|
383
|
+
(name) => `https://github.com/next-friday/eslint-plugin-nextfriday/blob/main/docs/rules/${name.replaceAll("-", "_").toUpperCase()}.md`
|
|
384
|
+
);
|
|
385
|
+
var enforceSortedDestructuring = createRule3({
|
|
386
|
+
name: "enforce-sorted-destructuring",
|
|
387
|
+
meta: {
|
|
388
|
+
type: "suggestion",
|
|
389
|
+
docs: {
|
|
390
|
+
description: "Enforce alphabetical sorting of destructured properties with defaults first"
|
|
391
|
+
},
|
|
392
|
+
schema: [],
|
|
393
|
+
messages: {
|
|
394
|
+
unsortedDestructuring: "Destructured properties should be sorted alphabetically. Properties with defaults should come first, sorted by type (string, number, boolean, object) then alphabetically."
|
|
395
|
+
}
|
|
396
|
+
},
|
|
397
|
+
defaultOptions: [],
|
|
398
|
+
create(context) {
|
|
399
|
+
function getPropertyName(property) {
|
|
400
|
+
if (property.type === import_utils3.AST_NODE_TYPES.RestElement) {
|
|
401
|
+
return null;
|
|
402
|
+
}
|
|
403
|
+
if (property.key.type === import_utils3.AST_NODE_TYPES.Identifier) {
|
|
404
|
+
return property.key.name;
|
|
405
|
+
}
|
|
406
|
+
return null;
|
|
407
|
+
}
|
|
408
|
+
function hasDefaultValue(property) {
|
|
409
|
+
return property.value.type === import_utils3.AST_NODE_TYPES.AssignmentPattern && Boolean(property.value.right);
|
|
410
|
+
}
|
|
411
|
+
function getDefaultValueType(property) {
|
|
412
|
+
if (!hasDefaultValue(property)) {
|
|
413
|
+
return "none";
|
|
414
|
+
}
|
|
415
|
+
const assignmentPattern = property.value;
|
|
416
|
+
const { right } = assignmentPattern;
|
|
417
|
+
if (!right) {
|
|
418
|
+
return "none";
|
|
419
|
+
}
|
|
420
|
+
switch (right.type) {
|
|
421
|
+
case import_utils3.AST_NODE_TYPES.Literal:
|
|
422
|
+
if (typeof right.value === "string") {
|
|
423
|
+
return "string";
|
|
424
|
+
}
|
|
425
|
+
if (typeof right.value === "number") {
|
|
426
|
+
return "number";
|
|
427
|
+
}
|
|
428
|
+
if (typeof right.value === "boolean") {
|
|
429
|
+
return "boolean";
|
|
430
|
+
}
|
|
431
|
+
return "other";
|
|
432
|
+
case import_utils3.AST_NODE_TYPES.TemplateLiteral:
|
|
433
|
+
return "string";
|
|
434
|
+
case import_utils3.AST_NODE_TYPES.ObjectExpression:
|
|
435
|
+
case import_utils3.AST_NODE_TYPES.ArrayExpression:
|
|
436
|
+
return "object";
|
|
437
|
+
default:
|
|
438
|
+
return "other";
|
|
439
|
+
}
|
|
440
|
+
}
|
|
441
|
+
function getTypeSortOrder(type) {
|
|
442
|
+
const order = {
|
|
443
|
+
string: 0,
|
|
444
|
+
number: 1,
|
|
445
|
+
boolean: 2,
|
|
446
|
+
object: 3,
|
|
447
|
+
other: 4,
|
|
448
|
+
none: 5
|
|
449
|
+
};
|
|
450
|
+
return order[type] ?? 5;
|
|
451
|
+
}
|
|
452
|
+
function checkVariableDeclarator(node) {
|
|
453
|
+
if (node.id.type !== import_utils3.AST_NODE_TYPES.ObjectPattern) {
|
|
454
|
+
return;
|
|
455
|
+
}
|
|
456
|
+
const { properties } = node.id;
|
|
457
|
+
if (properties.length < 2) {
|
|
458
|
+
return;
|
|
459
|
+
}
|
|
460
|
+
const propertyInfo = properties.map((prop) => {
|
|
461
|
+
if (prop.type === import_utils3.AST_NODE_TYPES.RestElement) {
|
|
462
|
+
return null;
|
|
463
|
+
}
|
|
464
|
+
return {
|
|
465
|
+
property: prop,
|
|
466
|
+
name: getPropertyName(prop),
|
|
467
|
+
hasDefault: hasDefaultValue(prop),
|
|
468
|
+
defaultType: getDefaultValueType(prop)
|
|
469
|
+
};
|
|
470
|
+
}).filter((info) => info !== null && info.name !== null);
|
|
471
|
+
const sorted = [...propertyInfo].sort((a, b) => {
|
|
472
|
+
if (a.hasDefault && !b.hasDefault) {
|
|
473
|
+
return -1;
|
|
474
|
+
}
|
|
475
|
+
if (!a.hasDefault && b.hasDefault) {
|
|
476
|
+
return 1;
|
|
477
|
+
}
|
|
478
|
+
if (a.hasDefault && b.hasDefault) {
|
|
479
|
+
const typeComparison = getTypeSortOrder(a.defaultType) - getTypeSortOrder(b.defaultType);
|
|
480
|
+
if (typeComparison !== 0) {
|
|
481
|
+
return typeComparison;
|
|
482
|
+
}
|
|
483
|
+
}
|
|
484
|
+
return a.name.localeCompare(b.name);
|
|
485
|
+
});
|
|
486
|
+
const isSorted = propertyInfo.every((info, index) => info.name === sorted[index].name);
|
|
487
|
+
if (!isSorted) {
|
|
488
|
+
context.report({
|
|
489
|
+
node: node.id,
|
|
490
|
+
messageId: "unsortedDestructuring"
|
|
491
|
+
});
|
|
492
|
+
}
|
|
493
|
+
}
|
|
494
|
+
return {
|
|
495
|
+
VariableDeclarator: checkVariableDeclarator
|
|
496
|
+
};
|
|
497
|
+
}
|
|
498
|
+
});
|
|
499
|
+
var enforce_sorted_destructuring_default = enforceSortedDestructuring;
|
|
500
|
+
|
|
249
501
|
// src/rules/file-kebab-case.ts
|
|
250
502
|
var import_path = __toESM(require("path"), 1);
|
|
251
|
-
var
|
|
252
|
-
var
|
|
253
|
-
(name) => `https://github.com/next-friday/eslint-plugin-nextfriday/blob/main/docs/rules/${name.
|
|
503
|
+
var import_utils4 = require("@typescript-eslint/utils");
|
|
504
|
+
var createRule4 = import_utils4.ESLintUtils.RuleCreator(
|
|
505
|
+
(name) => `https://github.com/next-friday/eslint-plugin-nextfriday/blob/main/docs/rules/${name.replaceAll("-", "_").toUpperCase()}.md`
|
|
254
506
|
);
|
|
255
507
|
var isKebabCase = (str) => {
|
|
256
508
|
if (/\.(config|rc|setup|spec|test)$/.test(str) || /^[a-z0-9]+(?:-[a-z0-9]+)*\.[a-z0-9]+(?:-[a-z0-9]+)*$/.test(str)) {
|
|
@@ -258,7 +510,7 @@ var isKebabCase = (str) => {
|
|
|
258
510
|
}
|
|
259
511
|
return /^[a-z0-9]+(?:-[a-z0-9]+)*$/.test(str);
|
|
260
512
|
};
|
|
261
|
-
var fileKebabCase =
|
|
513
|
+
var fileKebabCase = createRule4({
|
|
262
514
|
name: "file-kebab-case",
|
|
263
515
|
meta: {
|
|
264
516
|
type: "problem",
|
|
@@ -279,8 +531,8 @@ var fileKebabCase = createRule2({
|
|
|
279
531
|
if (ext !== ".ts" && ext !== ".js") {
|
|
280
532
|
return;
|
|
281
533
|
}
|
|
282
|
-
const
|
|
283
|
-
if (!isKebabCase(
|
|
534
|
+
const basename2 = import_path.default.basename(filename, ext);
|
|
535
|
+
if (!isKebabCase(basename2)) {
|
|
284
536
|
context.report({
|
|
285
537
|
loc: { line: 1, column: 0 },
|
|
286
538
|
messageId: "fileKebabCase"
|
|
@@ -294,12 +546,12 @@ var file_kebab_case_default = fileKebabCase;
|
|
|
294
546
|
|
|
295
547
|
// src/rules/jsx-pascal-case.ts
|
|
296
548
|
var import_path2 = __toESM(require("path"), 1);
|
|
297
|
-
var
|
|
298
|
-
var
|
|
299
|
-
(name) => `https://github.com/next-friday/eslint-plugin-nextfriday/blob/main/docs/rules/${name.
|
|
549
|
+
var import_utils5 = require("@typescript-eslint/utils");
|
|
550
|
+
var createRule5 = import_utils5.ESLintUtils.RuleCreator(
|
|
551
|
+
(name) => `https://github.com/next-friday/eslint-plugin-nextfriday/blob/main/docs/rules/${name.replaceAll("-", "_").toUpperCase()}.md`
|
|
300
552
|
);
|
|
301
553
|
var isPascalCase = (str) => /^[A-Z][a-zA-Z0-9]*$/.test(str) && !/^[A-Z]+$/.test(str);
|
|
302
|
-
var jsxPascalCase =
|
|
554
|
+
var jsxPascalCase = createRule5({
|
|
303
555
|
name: "jsx-pascal-case",
|
|
304
556
|
meta: {
|
|
305
557
|
type: "problem",
|
|
@@ -320,8 +572,8 @@ var jsxPascalCase = createRule3({
|
|
|
320
572
|
if (ext !== ".jsx" && ext !== ".tsx") {
|
|
321
573
|
return;
|
|
322
574
|
}
|
|
323
|
-
const
|
|
324
|
-
if (!isPascalCase(
|
|
575
|
+
const basename2 = import_path2.default.basename(filename, ext);
|
|
576
|
+
if (!isPascalCase(basename2)) {
|
|
325
577
|
context.report({
|
|
326
578
|
loc: { line: 1, column: 0 },
|
|
327
579
|
messageId: "jsxPascalCase"
|
|
@@ -333,13 +585,136 @@ var jsxPascalCase = createRule3({
|
|
|
333
585
|
});
|
|
334
586
|
var jsx_pascal_case_default = jsxPascalCase;
|
|
335
587
|
|
|
588
|
+
// src/rules/no-direct-date.ts
|
|
589
|
+
var import_utils6 = require("@typescript-eslint/utils");
|
|
590
|
+
var createRule6 = import_utils6.ESLintUtils.RuleCreator(
|
|
591
|
+
(name) => `https://github.com/next-friday/eslint-plugin-nextfriday/blob/main/docs/rules/${name.replaceAll("-", "_").toUpperCase()}.md`
|
|
592
|
+
);
|
|
593
|
+
var noDirectDate = createRule6({
|
|
594
|
+
name: "no-direct-date",
|
|
595
|
+
meta: {
|
|
596
|
+
type: "problem",
|
|
597
|
+
docs: {
|
|
598
|
+
description: "Disallow direct usage of Date constructor and methods to enforce centralized date utilities"
|
|
599
|
+
},
|
|
600
|
+
messages: {
|
|
601
|
+
noNewDate: "Avoid using 'new Date()'. Use a centralized date utility like dayjs instead.",
|
|
602
|
+
noDateNow: "Avoid using 'Date.now()'. Use a centralized date utility like dayjs instead.",
|
|
603
|
+
noDateParse: "Avoid using 'Date.parse()'. Use a centralized date utility like dayjs instead."
|
|
604
|
+
},
|
|
605
|
+
schema: []
|
|
606
|
+
},
|
|
607
|
+
defaultOptions: [],
|
|
608
|
+
create(context) {
|
|
609
|
+
return {
|
|
610
|
+
NewExpression(node) {
|
|
611
|
+
if (node.callee.type === import_utils6.AST_NODE_TYPES.Identifier && node.callee.name === "Date") {
|
|
612
|
+
context.report({
|
|
613
|
+
node,
|
|
614
|
+
messageId: "noNewDate"
|
|
615
|
+
});
|
|
616
|
+
}
|
|
617
|
+
},
|
|
618
|
+
CallExpression(node) {
|
|
619
|
+
if (node.callee.type === import_utils6.AST_NODE_TYPES.MemberExpression && node.callee.object.type === import_utils6.AST_NODE_TYPES.Identifier && node.callee.object.name === "Date" && node.callee.property.type === import_utils6.AST_NODE_TYPES.Identifier) {
|
|
620
|
+
const methodName = node.callee.property.name;
|
|
621
|
+
if (methodName === "now") {
|
|
622
|
+
context.report({
|
|
623
|
+
node,
|
|
624
|
+
messageId: "noDateNow"
|
|
625
|
+
});
|
|
626
|
+
}
|
|
627
|
+
if (methodName === "parse") {
|
|
628
|
+
context.report({
|
|
629
|
+
node,
|
|
630
|
+
messageId: "noDateParse"
|
|
631
|
+
});
|
|
632
|
+
}
|
|
633
|
+
}
|
|
634
|
+
}
|
|
635
|
+
};
|
|
636
|
+
}
|
|
637
|
+
});
|
|
638
|
+
var no_direct_date_default = noDirectDate;
|
|
639
|
+
|
|
640
|
+
// src/rules/jsx-no-variable-in-callback.ts
|
|
641
|
+
var import_utils7 = require("@typescript-eslint/utils");
|
|
642
|
+
var createRule7 = import_utils7.ESLintUtils.RuleCreator(
|
|
643
|
+
(name) => `https://github.com/next-friday/eslint-plugin-nextfriday/blob/main/docs/rules/${name.replaceAll("-", "_").toUpperCase()}.md`
|
|
644
|
+
);
|
|
645
|
+
var jsxNoVariableInCallback = createRule7({
|
|
646
|
+
name: "jsx-no-variable-in-callback",
|
|
647
|
+
meta: {
|
|
648
|
+
type: "suggestion",
|
|
649
|
+
docs: {
|
|
650
|
+
description: "Disallow variable declarations inside callback functions within JSX"
|
|
651
|
+
},
|
|
652
|
+
schema: [],
|
|
653
|
+
messages: {
|
|
654
|
+
noVariableInCallback: "Variable declarations should not be inside callback functions within JSX. Extract the logic to a separate function outside the JSX."
|
|
655
|
+
}
|
|
656
|
+
},
|
|
657
|
+
defaultOptions: [],
|
|
658
|
+
create(context) {
|
|
659
|
+
function isInsideJSX(node) {
|
|
660
|
+
let current = node.parent;
|
|
661
|
+
while (current) {
|
|
662
|
+
if (current.type === import_utils7.AST_NODE_TYPES.JSXElement || current.type === import_utils7.AST_NODE_TYPES.JSXFragment) {
|
|
663
|
+
return true;
|
|
664
|
+
}
|
|
665
|
+
current = current.parent;
|
|
666
|
+
}
|
|
667
|
+
return false;
|
|
668
|
+
}
|
|
669
|
+
function isCallbackInJSX(node) {
|
|
670
|
+
if (!node.parent) {
|
|
671
|
+
return false;
|
|
672
|
+
}
|
|
673
|
+
if (!isInsideJSX(node)) {
|
|
674
|
+
return false;
|
|
675
|
+
}
|
|
676
|
+
if (node.parent.type === import_utils7.AST_NODE_TYPES.CallExpression || node.parent.type === import_utils7.AST_NODE_TYPES.JSXExpressionContainer) {
|
|
677
|
+
return true;
|
|
678
|
+
}
|
|
679
|
+
if (node.parent.type === import_utils7.AST_NODE_TYPES.ArrayExpression && node.parent.parent) {
|
|
680
|
+
if (node.parent.parent.type === import_utils7.AST_NODE_TYPES.CallExpression || node.parent.parent.type === import_utils7.AST_NODE_TYPES.JSXExpressionContainer) {
|
|
681
|
+
return true;
|
|
682
|
+
}
|
|
683
|
+
}
|
|
684
|
+
return false;
|
|
685
|
+
}
|
|
686
|
+
function checkFunctionBody(node) {
|
|
687
|
+
if (!isCallbackInJSX(node)) {
|
|
688
|
+
return;
|
|
689
|
+
}
|
|
690
|
+
const { body } = node;
|
|
691
|
+
if (body.type !== import_utils7.AST_NODE_TYPES.BlockStatement) {
|
|
692
|
+
return;
|
|
693
|
+
}
|
|
694
|
+
body.body.forEach((statement) => {
|
|
695
|
+
if (statement.type === import_utils7.AST_NODE_TYPES.VariableDeclaration) {
|
|
696
|
+
context.report({
|
|
697
|
+
node: statement,
|
|
698
|
+
messageId: "noVariableInCallback"
|
|
699
|
+
});
|
|
700
|
+
}
|
|
701
|
+
});
|
|
702
|
+
}
|
|
703
|
+
return {
|
|
704
|
+
ArrowFunctionExpression: checkFunctionBody,
|
|
705
|
+
FunctionExpression: checkFunctionBody
|
|
706
|
+
};
|
|
707
|
+
}
|
|
708
|
+
});
|
|
709
|
+
var jsx_no_variable_in_callback_default = jsxNoVariableInCallback;
|
|
710
|
+
|
|
336
711
|
// src/rules/md-filename-case-restriction.ts
|
|
337
712
|
var import_path3 = __toESM(require("path"), 1);
|
|
338
|
-
var
|
|
339
|
-
var
|
|
340
|
-
(name) => `https://github.com/next-friday/eslint-plugin-nextfriday/blob/main/docs/rules/${name.
|
|
713
|
+
var import_utils8 = require("@typescript-eslint/utils");
|
|
714
|
+
var createRule8 = import_utils8.ESLintUtils.RuleCreator(
|
|
715
|
+
(name) => `https://github.com/next-friday/eslint-plugin-nextfriday/blob/main/docs/rules/${name.replaceAll("-", "_").toUpperCase()}.md`
|
|
341
716
|
);
|
|
342
|
-
var mdFilenameCaseRestriction =
|
|
717
|
+
var mdFilenameCaseRestriction = createRule8({
|
|
343
718
|
name: "md-filename-case-restriction",
|
|
344
719
|
meta: {
|
|
345
720
|
type: "problem",
|
|
@@ -359,18 +734,18 @@ var mdFilenameCaseRestriction = createRule4({
|
|
|
359
734
|
if (!filename.endsWith(".md")) {
|
|
360
735
|
return;
|
|
361
736
|
}
|
|
362
|
-
const
|
|
737
|
+
const basename2 = import_path3.default.basename(filename, ".md");
|
|
363
738
|
function isSnakeCase(text) {
|
|
364
739
|
return /^[A-Z][A-Z0-9_]*$/.test(text);
|
|
365
740
|
}
|
|
366
741
|
function isValidCase(text) {
|
|
367
742
|
return isSnakeCase(text);
|
|
368
743
|
}
|
|
369
|
-
if (!isValidCase(
|
|
744
|
+
if (!isValidCase(basename2)) {
|
|
370
745
|
context.report({
|
|
371
746
|
node: context.sourceCode.ast,
|
|
372
747
|
messageId: "invalidFilenameCase",
|
|
373
|
-
data: { filename:
|
|
748
|
+
data: { filename: basename2 }
|
|
374
749
|
});
|
|
375
750
|
}
|
|
376
751
|
}
|
|
@@ -380,11 +755,11 @@ var mdFilenameCaseRestriction = createRule4({
|
|
|
380
755
|
var md_filename_case_restriction_default = mdFilenameCaseRestriction;
|
|
381
756
|
|
|
382
757
|
// src/rules/no-complex-inline-return.ts
|
|
383
|
-
var
|
|
384
|
-
var
|
|
385
|
-
(name) => `https://github.com/next-friday/eslint-plugin-nextfriday/blob/main/docs/rules/${name.
|
|
758
|
+
var import_utils9 = require("@typescript-eslint/utils");
|
|
759
|
+
var createRule9 = import_utils9.ESLintUtils.RuleCreator(
|
|
760
|
+
(name) => `https://github.com/next-friday/eslint-plugin-nextfriday/blob/main/docs/rules/${name.replaceAll("-", "_").toUpperCase()}.md`
|
|
386
761
|
);
|
|
387
|
-
var noComplexInlineReturn =
|
|
762
|
+
var noComplexInlineReturn = createRule9({
|
|
388
763
|
name: "no-complex-inline-return",
|
|
389
764
|
meta: {
|
|
390
765
|
type: "suggestion",
|
|
@@ -400,13 +775,13 @@ var noComplexInlineReturn = createRule5({
|
|
|
400
775
|
create(context) {
|
|
401
776
|
const isComplexExpression = (node) => {
|
|
402
777
|
if (!node) return false;
|
|
403
|
-
if (node.type ===
|
|
778
|
+
if (node.type === import_utils9.AST_NODE_TYPES.ConditionalExpression) {
|
|
404
779
|
return true;
|
|
405
780
|
}
|
|
406
|
-
if (node.type ===
|
|
781
|
+
if (node.type === import_utils9.AST_NODE_TYPES.LogicalExpression) {
|
|
407
782
|
return true;
|
|
408
783
|
}
|
|
409
|
-
if (node.type ===
|
|
784
|
+
if (node.type === import_utils9.AST_NODE_TYPES.NewExpression) {
|
|
410
785
|
return true;
|
|
411
786
|
}
|
|
412
787
|
return false;
|
|
@@ -427,11 +802,11 @@ var no_complex_inline_return_default = noComplexInlineReturn;
|
|
|
427
802
|
|
|
428
803
|
// src/rules/no-emoji.ts
|
|
429
804
|
var import_emoji_regex = __toESM(require("emoji-regex"), 1);
|
|
430
|
-
var
|
|
431
|
-
var
|
|
432
|
-
(name) => `https://github.com/next-friday/eslint-plugin-nextfriday/blob/main/docs/rules/${name.
|
|
805
|
+
var import_utils10 = require("@typescript-eslint/utils");
|
|
806
|
+
var createRule10 = import_utils10.ESLintUtils.RuleCreator(
|
|
807
|
+
(name) => `https://github.com/next-friday/eslint-plugin-nextfriday/blob/main/docs/rules/${name.replaceAll("-", "_").toUpperCase()}.md`
|
|
433
808
|
);
|
|
434
|
-
var noEmoji =
|
|
809
|
+
var noEmoji = createRule10({
|
|
435
810
|
name: "no-emoji",
|
|
436
811
|
meta: {
|
|
437
812
|
type: "problem",
|
|
@@ -465,11 +840,11 @@ var noEmoji = createRule6({
|
|
|
465
840
|
var no_emoji_default = noEmoji;
|
|
466
841
|
|
|
467
842
|
// src/rules/no-env-fallback.ts
|
|
468
|
-
var
|
|
469
|
-
var
|
|
470
|
-
(name) => `https://github.com/next-friday/eslint-plugin-nextfriday/blob/main/docs/rules/${name.
|
|
843
|
+
var import_utils11 = require("@typescript-eslint/utils");
|
|
844
|
+
var createRule11 = import_utils11.ESLintUtils.RuleCreator(
|
|
845
|
+
(name) => `https://github.com/next-friday/eslint-plugin-nextfriday/blob/main/docs/rules/${name.replaceAll("-", "_").toUpperCase()}.md`
|
|
471
846
|
);
|
|
472
|
-
var noEnvFallback =
|
|
847
|
+
var noEnvFallback = createRule11({
|
|
473
848
|
name: "no-env-fallback",
|
|
474
849
|
meta: {
|
|
475
850
|
type: "problem",
|
|
@@ -484,16 +859,16 @@ var noEnvFallback = createRule7({
|
|
|
484
859
|
defaultOptions: [],
|
|
485
860
|
create(context) {
|
|
486
861
|
const isProcessEnvAccess = (node) => {
|
|
487
|
-
if (node.type !==
|
|
862
|
+
if (node.type !== import_utils11.AST_NODE_TYPES.MemberExpression) {
|
|
488
863
|
return false;
|
|
489
864
|
}
|
|
490
865
|
const { object } = node;
|
|
491
|
-
if (object.type !==
|
|
866
|
+
if (object.type !== import_utils11.AST_NODE_TYPES.MemberExpression) {
|
|
492
867
|
return false;
|
|
493
868
|
}
|
|
494
869
|
const processNode = object.object;
|
|
495
870
|
const envNode = object.property;
|
|
496
|
-
return processNode.type ===
|
|
871
|
+
return processNode.type === import_utils11.AST_NODE_TYPES.Identifier && processNode.name === "process" && envNode.type === import_utils11.AST_NODE_TYPES.Identifier && envNode.name === "env";
|
|
497
872
|
};
|
|
498
873
|
return {
|
|
499
874
|
LogicalExpression(node) {
|
|
@@ -517,38 +892,93 @@ var noEnvFallback = createRule7({
|
|
|
517
892
|
});
|
|
518
893
|
var no_env_fallback_default = noEnvFallback;
|
|
519
894
|
|
|
520
|
-
// src/rules/
|
|
521
|
-
var
|
|
522
|
-
var
|
|
523
|
-
(name) => `https://github.com/next-friday/eslint-plugin-nextfriday/blob/main/docs/rules/${name.
|
|
895
|
+
// src/rules/require-explicit-return-type.ts
|
|
896
|
+
var import_utils12 = require("@typescript-eslint/utils");
|
|
897
|
+
var createRule12 = import_utils12.ESLintUtils.RuleCreator(
|
|
898
|
+
(name) => `https://github.com/next-friday/eslint-plugin-nextfriday/blob/main/docs/rules/${name.replaceAll("-", "_").toUpperCase()}.md`
|
|
524
899
|
);
|
|
525
|
-
var
|
|
526
|
-
|
|
900
|
+
var isReactComponent = (node) => {
|
|
901
|
+
if (node.type === import_utils12.AST_NODE_TYPES.ArrowFunctionExpression) {
|
|
902
|
+
const { parent } = node;
|
|
903
|
+
if (parent?.type === import_utils12.AST_NODE_TYPES.VariableDeclarator) {
|
|
904
|
+
const { id } = parent;
|
|
905
|
+
if (id.type === import_utils12.AST_NODE_TYPES.Identifier) {
|
|
906
|
+
return /^[A-Z]/.test(id.name);
|
|
907
|
+
}
|
|
908
|
+
}
|
|
909
|
+
}
|
|
910
|
+
if (node.type === import_utils12.AST_NODE_TYPES.FunctionDeclaration && node.id) {
|
|
911
|
+
return /^[A-Z]/.test(node.id.name);
|
|
912
|
+
}
|
|
913
|
+
return false;
|
|
914
|
+
};
|
|
915
|
+
var isCallbackFunction = (node) => {
|
|
916
|
+
if (node.type === import_utils12.AST_NODE_TYPES.FunctionDeclaration) {
|
|
917
|
+
return false;
|
|
918
|
+
}
|
|
919
|
+
const { parent } = node;
|
|
920
|
+
if (!parent) {
|
|
921
|
+
return false;
|
|
922
|
+
}
|
|
923
|
+
if (parent.type === import_utils12.AST_NODE_TYPES.CallExpression && parent.arguments.includes(node)) {
|
|
924
|
+
return true;
|
|
925
|
+
}
|
|
926
|
+
if (parent.type === import_utils12.AST_NODE_TYPES.Property) {
|
|
927
|
+
return true;
|
|
928
|
+
}
|
|
929
|
+
if (parent.type === import_utils12.AST_NODE_TYPES.ArrayExpression) {
|
|
930
|
+
return true;
|
|
931
|
+
}
|
|
932
|
+
return false;
|
|
933
|
+
};
|
|
934
|
+
var getFunctionName = (node) => {
|
|
935
|
+
if (node.type === import_utils12.AST_NODE_TYPES.FunctionDeclaration && node.id) {
|
|
936
|
+
return node.id.name;
|
|
937
|
+
}
|
|
938
|
+
if (node.type === import_utils12.AST_NODE_TYPES.FunctionExpression && node.id) {
|
|
939
|
+
return node.id.name;
|
|
940
|
+
}
|
|
941
|
+
if ((node.type === import_utils12.AST_NODE_TYPES.ArrowFunctionExpression || node.type === import_utils12.AST_NODE_TYPES.FunctionExpression) && node.parent?.type === import_utils12.AST_NODE_TYPES.VariableDeclarator && node.parent.id.type === import_utils12.AST_NODE_TYPES.Identifier) {
|
|
942
|
+
return node.parent.id.name;
|
|
943
|
+
}
|
|
944
|
+
return null;
|
|
945
|
+
};
|
|
946
|
+
var requireExplicitReturnType = createRule12({
|
|
947
|
+
name: "require-explicit-return-type",
|
|
527
948
|
meta: {
|
|
528
949
|
type: "suggestion",
|
|
529
950
|
docs: {
|
|
530
|
-
description: "
|
|
951
|
+
description: "Require explicit return types on functions for better code documentation and type safety"
|
|
531
952
|
},
|
|
532
|
-
fixable: "code",
|
|
533
|
-
schema: [],
|
|
534
953
|
messages: {
|
|
535
|
-
|
|
536
|
-
|
|
954
|
+
missingReturnType: "Function '{{name}}' is missing an explicit return type. Add a return type annotation for better documentation.",
|
|
955
|
+
missingReturnTypeAnonymous: "Function is missing an explicit return type. Add a return type annotation for better documentation."
|
|
956
|
+
},
|
|
957
|
+
schema: []
|
|
537
958
|
},
|
|
538
959
|
defaultOptions: [],
|
|
539
960
|
create(context) {
|
|
540
961
|
const checkFunction = (node) => {
|
|
541
962
|
if (node.returnType) {
|
|
542
|
-
|
|
963
|
+
return;
|
|
964
|
+
}
|
|
965
|
+
if (isCallbackFunction(node)) {
|
|
966
|
+
return;
|
|
967
|
+
}
|
|
968
|
+
if (isReactComponent(node)) {
|
|
969
|
+
return;
|
|
970
|
+
}
|
|
971
|
+
const functionName = getFunctionName(node);
|
|
972
|
+
if (functionName) {
|
|
543
973
|
context.report({
|
|
544
|
-
node
|
|
545
|
-
messageId: "
|
|
546
|
-
data: {
|
|
547
|
-
|
|
548
|
-
|
|
549
|
-
|
|
550
|
-
|
|
551
|
-
|
|
974
|
+
node,
|
|
975
|
+
messageId: "missingReturnType",
|
|
976
|
+
data: { name: functionName }
|
|
977
|
+
});
|
|
978
|
+
} else {
|
|
979
|
+
context.report({
|
|
980
|
+
node,
|
|
981
|
+
messageId: "missingReturnTypeAnonymous"
|
|
552
982
|
});
|
|
553
983
|
}
|
|
554
984
|
};
|
|
@@ -559,14 +989,99 @@ var noExplicitReturnType = createRule8({
|
|
|
559
989
|
};
|
|
560
990
|
}
|
|
561
991
|
});
|
|
562
|
-
var
|
|
992
|
+
var require_explicit_return_type_default = requireExplicitReturnType;
|
|
993
|
+
|
|
994
|
+
// src/rules/jsx-no-non-component-function.ts
|
|
995
|
+
var import_utils14 = require("@typescript-eslint/utils");
|
|
996
|
+
|
|
997
|
+
// src/utils.ts
|
|
998
|
+
var import_node_path = require("path");
|
|
999
|
+
var import_utils13 = require("@typescript-eslint/utils");
|
|
1000
|
+
var getFileExtension = (filename) => (0, import_node_path.extname)(filename).slice(1);
|
|
1001
|
+
|
|
1002
|
+
// src/rules/jsx-no-non-component-function.ts
|
|
1003
|
+
var createRule13 = import_utils14.ESLintUtils.RuleCreator(
|
|
1004
|
+
(name) => `https://github.com/next-friday/eslint-plugin-nextfriday/blob/main/docs/rules/${name.replaceAll("-", "_").toUpperCase()}.md`
|
|
1005
|
+
);
|
|
1006
|
+
var jsxNoNonComponentFunction = createRule13({
|
|
1007
|
+
name: "jsx-no-non-component-function",
|
|
1008
|
+
meta: {
|
|
1009
|
+
type: "problem",
|
|
1010
|
+
docs: {
|
|
1011
|
+
description: "Disallow non-component functions defined at top level in .tsx and .jsx files"
|
|
1012
|
+
},
|
|
1013
|
+
schema: [],
|
|
1014
|
+
messages: {
|
|
1015
|
+
noTopLevelFunction: "Non-component functions should not be defined at top level in .tsx/.jsx files. Either move it inside the component or extract it to a separate file."
|
|
1016
|
+
}
|
|
1017
|
+
},
|
|
1018
|
+
defaultOptions: [],
|
|
1019
|
+
create(context) {
|
|
1020
|
+
const { filename } = context;
|
|
1021
|
+
const extension = getFileExtension(filename);
|
|
1022
|
+
if (extension !== "tsx" && extension !== "jsx") {
|
|
1023
|
+
return {};
|
|
1024
|
+
}
|
|
1025
|
+
function isReactComponent2(node) {
|
|
1026
|
+
const functionName = node.type === import_utils14.AST_NODE_TYPES.FunctionDeclaration && node.id ? node.id.name : null;
|
|
1027
|
+
if (functionName && /^[A-Z]/.test(functionName)) {
|
|
1028
|
+
return true;
|
|
1029
|
+
}
|
|
1030
|
+
if (node.returnType?.typeAnnotation) {
|
|
1031
|
+
const returnTypeNode = node.returnType.typeAnnotation;
|
|
1032
|
+
if (returnTypeNode.type === import_utils14.AST_NODE_TYPES.TSTypeReference && returnTypeNode.typeName.type === import_utils14.AST_NODE_TYPES.Identifier) {
|
|
1033
|
+
const typeName = returnTypeNode.typeName.name;
|
|
1034
|
+
if (typeName === "JSX" || typeName === "ReactElement" || typeName === "ReactNode") {
|
|
1035
|
+
return true;
|
|
1036
|
+
}
|
|
1037
|
+
}
|
|
1038
|
+
}
|
|
1039
|
+
return false;
|
|
1040
|
+
}
|
|
1041
|
+
function checkTopLevelFunction(node, declaratorNode) {
|
|
1042
|
+
if (isReactComponent2(node)) {
|
|
1043
|
+
return;
|
|
1044
|
+
}
|
|
1045
|
+
const { parent } = node;
|
|
1046
|
+
if (!parent) {
|
|
1047
|
+
return;
|
|
1048
|
+
}
|
|
1049
|
+
if (parent.type === import_utils14.AST_NODE_TYPES.ExportDefaultDeclaration || parent.type === import_utils14.AST_NODE_TYPES.ExportNamedDeclaration) {
|
|
1050
|
+
return;
|
|
1051
|
+
}
|
|
1052
|
+
if (declaratorNode?.parent?.parent?.type === import_utils14.AST_NODE_TYPES.ExportNamedDeclaration) {
|
|
1053
|
+
return;
|
|
1054
|
+
}
|
|
1055
|
+
if (declaratorNode?.id.type === import_utils14.AST_NODE_TYPES.Identifier) {
|
|
1056
|
+
const varName = declaratorNode.id.name;
|
|
1057
|
+
if (/^[A-Z]/.test(varName)) {
|
|
1058
|
+
return;
|
|
1059
|
+
}
|
|
1060
|
+
}
|
|
1061
|
+
context.report({
|
|
1062
|
+
node: declaratorNode || node,
|
|
1063
|
+
messageId: "noTopLevelFunction"
|
|
1064
|
+
});
|
|
1065
|
+
}
|
|
1066
|
+
return {
|
|
1067
|
+
"Program > VariableDeclaration > VariableDeclarator > ArrowFunctionExpression": function checkArrowFunction(node) {
|
|
1068
|
+
const declarator = node.parent;
|
|
1069
|
+
checkTopLevelFunction(node, declarator);
|
|
1070
|
+
},
|
|
1071
|
+
"Program > FunctionDeclaration": function checkFunctionDeclaration(node) {
|
|
1072
|
+
checkTopLevelFunction(node);
|
|
1073
|
+
}
|
|
1074
|
+
};
|
|
1075
|
+
}
|
|
1076
|
+
});
|
|
1077
|
+
var jsx_no_non_component_function_default = jsxNoNonComponentFunction;
|
|
563
1078
|
|
|
564
1079
|
// src/rules/no-logic-in-params.ts
|
|
565
|
-
var
|
|
566
|
-
var
|
|
567
|
-
(name) => `https://github.com/next-friday/eslint-plugin-nextfriday/blob/main/docs/rules/${name.
|
|
1080
|
+
var import_utils16 = require("@typescript-eslint/utils");
|
|
1081
|
+
var createRule14 = import_utils16.ESLintUtils.RuleCreator(
|
|
1082
|
+
(name) => `https://github.com/next-friday/eslint-plugin-nextfriday/blob/main/docs/rules/${name.replaceAll("-", "_").toUpperCase()}.md`
|
|
568
1083
|
);
|
|
569
|
-
var noLogicInParams =
|
|
1084
|
+
var noLogicInParams = createRule14({
|
|
570
1085
|
name: "no-logic-in-params",
|
|
571
1086
|
meta: {
|
|
572
1087
|
type: "suggestion",
|
|
@@ -581,20 +1096,20 @@ var noLogicInParams = createRule9({
|
|
|
581
1096
|
defaultOptions: [],
|
|
582
1097
|
create(context) {
|
|
583
1098
|
const isComplexExpression = (node) => {
|
|
584
|
-
if (node.type ===
|
|
1099
|
+
if (node.type === import_utils16.AST_NODE_TYPES.SpreadElement) {
|
|
585
1100
|
return false;
|
|
586
1101
|
}
|
|
587
|
-
if (node.type ===
|
|
1102
|
+
if (node.type === import_utils16.AST_NODE_TYPES.ConditionalExpression) {
|
|
588
1103
|
return true;
|
|
589
1104
|
}
|
|
590
|
-
if (node.type ===
|
|
1105
|
+
if (node.type === import_utils16.AST_NODE_TYPES.LogicalExpression) {
|
|
591
1106
|
return true;
|
|
592
1107
|
}
|
|
593
|
-
if (node.type ===
|
|
1108
|
+
if (node.type === import_utils16.AST_NODE_TYPES.BinaryExpression) {
|
|
594
1109
|
const logicalOperators = ["==", "===", "!=", "!==", "<", ">", "<=", ">=", "in", "instanceof"];
|
|
595
1110
|
return logicalOperators.includes(node.operator);
|
|
596
1111
|
}
|
|
597
|
-
if (node.type ===
|
|
1112
|
+
if (node.type === import_utils16.AST_NODE_TYPES.UnaryExpression) {
|
|
598
1113
|
return node.operator === "!";
|
|
599
1114
|
}
|
|
600
1115
|
return false;
|
|
@@ -625,12 +1140,127 @@ var noLogicInParams = createRule9({
|
|
|
625
1140
|
});
|
|
626
1141
|
var no_logic_in_params_default = noLogicInParams;
|
|
627
1142
|
|
|
1143
|
+
// src/rules/no-single-char-variables.ts
|
|
1144
|
+
var import_utils17 = require("@typescript-eslint/utils");
|
|
1145
|
+
var createRule15 = import_utils17.ESLintUtils.RuleCreator(
|
|
1146
|
+
(name) => `https://github.com/next-friday/eslint-plugin-nextfriday/blob/main/docs/rules/${name.replaceAll("-", "_").toUpperCase()}.md`
|
|
1147
|
+
);
|
|
1148
|
+
var ALLOWED_IN_FOR_LOOPS = /* @__PURE__ */ new Set(["i", "j", "k", "n"]);
|
|
1149
|
+
var ALLOWED_UNDERSCORE = "_";
|
|
1150
|
+
var isForLoopInit = (node) => {
|
|
1151
|
+
let current = node;
|
|
1152
|
+
while (current) {
|
|
1153
|
+
const parentNode = current.parent;
|
|
1154
|
+
if (!parentNode) {
|
|
1155
|
+
return false;
|
|
1156
|
+
}
|
|
1157
|
+
if (parentNode.type === import_utils17.AST_NODE_TYPES.ForStatement) {
|
|
1158
|
+
const { init } = parentNode;
|
|
1159
|
+
if (init && init === current) {
|
|
1160
|
+
return true;
|
|
1161
|
+
}
|
|
1162
|
+
}
|
|
1163
|
+
current = parentNode;
|
|
1164
|
+
}
|
|
1165
|
+
return false;
|
|
1166
|
+
};
|
|
1167
|
+
var isAllowedInContext = (name, node) => {
|
|
1168
|
+
if (name === ALLOWED_UNDERSCORE) {
|
|
1169
|
+
return true;
|
|
1170
|
+
}
|
|
1171
|
+
if (ALLOWED_IN_FOR_LOOPS.has(name) && isForLoopInit(node)) {
|
|
1172
|
+
return true;
|
|
1173
|
+
}
|
|
1174
|
+
return false;
|
|
1175
|
+
};
|
|
1176
|
+
var noSingleCharVariables = createRule15({
|
|
1177
|
+
name: "no-single-char-variables",
|
|
1178
|
+
meta: {
|
|
1179
|
+
type: "suggestion",
|
|
1180
|
+
docs: {
|
|
1181
|
+
description: "Disallow single character variable and parameter names for better code readability"
|
|
1182
|
+
},
|
|
1183
|
+
messages: {
|
|
1184
|
+
noSingleChar: "Avoid single character variable name '{{name}}'. Use a descriptive name that clearly indicates the purpose."
|
|
1185
|
+
},
|
|
1186
|
+
schema: []
|
|
1187
|
+
},
|
|
1188
|
+
defaultOptions: [],
|
|
1189
|
+
create(context) {
|
|
1190
|
+
const checkIdentifier = (node, declarationNode) => {
|
|
1191
|
+
const { name } = node;
|
|
1192
|
+
if (name.length !== 1) {
|
|
1193
|
+
return;
|
|
1194
|
+
}
|
|
1195
|
+
if (isAllowedInContext(name, declarationNode)) {
|
|
1196
|
+
return;
|
|
1197
|
+
}
|
|
1198
|
+
context.report({
|
|
1199
|
+
node,
|
|
1200
|
+
messageId: "noSingleChar",
|
|
1201
|
+
data: { name }
|
|
1202
|
+
});
|
|
1203
|
+
};
|
|
1204
|
+
const checkPattern = (pattern, declarationNode) => {
|
|
1205
|
+
if (pattern.type === import_utils17.AST_NODE_TYPES.Identifier) {
|
|
1206
|
+
checkIdentifier(pattern, declarationNode);
|
|
1207
|
+
} else if (pattern.type === import_utils17.AST_NODE_TYPES.ObjectPattern) {
|
|
1208
|
+
pattern.properties.forEach((prop) => {
|
|
1209
|
+
if (prop.type === import_utils17.AST_NODE_TYPES.Property && prop.value.type === import_utils17.AST_NODE_TYPES.Identifier) {
|
|
1210
|
+
checkIdentifier(prop.value, declarationNode);
|
|
1211
|
+
} else if (prop.type === import_utils17.AST_NODE_TYPES.RestElement && prop.argument.type === import_utils17.AST_NODE_TYPES.Identifier) {
|
|
1212
|
+
checkIdentifier(prop.argument, declarationNode);
|
|
1213
|
+
}
|
|
1214
|
+
});
|
|
1215
|
+
} else if (pattern.type === import_utils17.AST_NODE_TYPES.ArrayPattern) {
|
|
1216
|
+
pattern.elements.forEach((element) => {
|
|
1217
|
+
if (element?.type === import_utils17.AST_NODE_TYPES.Identifier) {
|
|
1218
|
+
checkIdentifier(element, declarationNode);
|
|
1219
|
+
} else if (element?.type === import_utils17.AST_NODE_TYPES.RestElement && element.argument.type === import_utils17.AST_NODE_TYPES.Identifier) {
|
|
1220
|
+
checkIdentifier(element.argument, declarationNode);
|
|
1221
|
+
}
|
|
1222
|
+
});
|
|
1223
|
+
} else if (pattern.type === import_utils17.AST_NODE_TYPES.AssignmentPattern && pattern.left.type === import_utils17.AST_NODE_TYPES.Identifier) {
|
|
1224
|
+
checkIdentifier(pattern.left, declarationNode);
|
|
1225
|
+
} else if (pattern.type === import_utils17.AST_NODE_TYPES.RestElement && pattern.argument.type === import_utils17.AST_NODE_TYPES.Identifier) {
|
|
1226
|
+
checkIdentifier(pattern.argument, declarationNode);
|
|
1227
|
+
}
|
|
1228
|
+
};
|
|
1229
|
+
return {
|
|
1230
|
+
VariableDeclarator(node) {
|
|
1231
|
+
checkPattern(node.id, node);
|
|
1232
|
+
},
|
|
1233
|
+
FunctionDeclaration(node) {
|
|
1234
|
+
if (node.id) {
|
|
1235
|
+
checkIdentifier(node.id, node);
|
|
1236
|
+
}
|
|
1237
|
+
node.params.forEach((param) => checkPattern(param, node));
|
|
1238
|
+
},
|
|
1239
|
+
FunctionExpression(node) {
|
|
1240
|
+
if (node.id) {
|
|
1241
|
+
checkIdentifier(node.id, node);
|
|
1242
|
+
}
|
|
1243
|
+
node.params.forEach((param) => checkPattern(param, node));
|
|
1244
|
+
},
|
|
1245
|
+
ArrowFunctionExpression(node) {
|
|
1246
|
+
node.params.forEach((param) => checkPattern(param, node));
|
|
1247
|
+
},
|
|
1248
|
+
CatchClause(node) {
|
|
1249
|
+
if (node.param) {
|
|
1250
|
+
checkPattern(node.param, node);
|
|
1251
|
+
}
|
|
1252
|
+
}
|
|
1253
|
+
};
|
|
1254
|
+
}
|
|
1255
|
+
});
|
|
1256
|
+
var no_single_char_variables_default = noSingleCharVariables;
|
|
1257
|
+
|
|
628
1258
|
// src/rules/prefer-destructuring-params.ts
|
|
629
|
-
var
|
|
630
|
-
var
|
|
631
|
-
(name) => `https://github.com/next-friday/eslint-plugin-nextfriday/blob/main/docs/rules/${name.
|
|
1259
|
+
var import_utils18 = require("@typescript-eslint/utils");
|
|
1260
|
+
var createRule16 = import_utils18.ESLintUtils.RuleCreator(
|
|
1261
|
+
(name) => `https://github.com/next-friday/eslint-plugin-nextfriday/blob/main/docs/rules/${name.replaceAll("-", "_").toUpperCase()}.md`
|
|
632
1262
|
);
|
|
633
|
-
var preferDestructuringParams =
|
|
1263
|
+
var preferDestructuringParams = createRule16({
|
|
634
1264
|
name: "prefer-destructuring-params",
|
|
635
1265
|
meta: {
|
|
636
1266
|
type: "suggestion",
|
|
@@ -644,20 +1274,20 @@ var preferDestructuringParams = createRule10({
|
|
|
644
1274
|
},
|
|
645
1275
|
defaultOptions: [],
|
|
646
1276
|
create(context) {
|
|
647
|
-
const
|
|
1277
|
+
const isCallbackFunction2 = (node) => {
|
|
648
1278
|
const { parent } = node;
|
|
649
|
-
return parent?.type ===
|
|
1279
|
+
return parent?.type === import_utils18.AST_NODE_TYPES.CallExpression;
|
|
650
1280
|
};
|
|
651
1281
|
const isDeveloperFunction = (node) => {
|
|
652
|
-
if (node.type ===
|
|
1282
|
+
if (node.type === import_utils18.AST_NODE_TYPES.FunctionDeclaration) {
|
|
653
1283
|
return true;
|
|
654
1284
|
}
|
|
655
|
-
if (node.type ===
|
|
656
|
-
if (
|
|
1285
|
+
if (node.type === import_utils18.AST_NODE_TYPES.FunctionExpression || node.type === import_utils18.AST_NODE_TYPES.ArrowFunctionExpression) {
|
|
1286
|
+
if (isCallbackFunction2(node)) {
|
|
657
1287
|
return false;
|
|
658
1288
|
}
|
|
659
1289
|
const { parent } = node;
|
|
660
|
-
return parent?.type ===
|
|
1290
|
+
return parent?.type === import_utils18.AST_NODE_TYPES.VariableDeclarator || parent?.type === import_utils18.AST_NODE_TYPES.AssignmentExpression || parent?.type === import_utils18.AST_NODE_TYPES.Property || parent?.type === import_utils18.AST_NODE_TYPES.MethodDefinition;
|
|
661
1291
|
}
|
|
662
1292
|
return false;
|
|
663
1293
|
};
|
|
@@ -669,7 +1299,7 @@ var preferDestructuringParams = createRule10({
|
|
|
669
1299
|
if (!isDeveloperFunction(node)) {
|
|
670
1300
|
return;
|
|
671
1301
|
}
|
|
672
|
-
if (node.type ===
|
|
1302
|
+
if (node.type === import_utils18.AST_NODE_TYPES.FunctionDeclaration && node.id) {
|
|
673
1303
|
const functionName = node.id.name;
|
|
674
1304
|
if (functionName.startsWith("_") || functionName.includes("$") || /^[A-Z][a-zA-Z]*$/.test(functionName)) {
|
|
675
1305
|
return;
|
|
@@ -679,7 +1309,7 @@ var preferDestructuringParams = createRule10({
|
|
|
679
1309
|
return;
|
|
680
1310
|
}
|
|
681
1311
|
const hasNonDestructuredParams = node.params.some(
|
|
682
|
-
(param) => param.type !==
|
|
1312
|
+
(param) => param.type !== import_utils18.AST_NODE_TYPES.ObjectPattern && param.type !== import_utils18.AST_NODE_TYPES.RestElement
|
|
683
1313
|
);
|
|
684
1314
|
if (hasNonDestructuredParams) {
|
|
685
1315
|
context.report({
|
|
@@ -697,12 +1327,103 @@ var preferDestructuringParams = createRule10({
|
|
|
697
1327
|
});
|
|
698
1328
|
var prefer_destructuring_params_default = preferDestructuringParams;
|
|
699
1329
|
|
|
1330
|
+
// src/rules/prefer-function-declaration.ts
|
|
1331
|
+
var import_utils19 = require("@typescript-eslint/utils");
|
|
1332
|
+
var createRule17 = import_utils19.ESLintUtils.RuleCreator(
|
|
1333
|
+
(name) => `https://github.com/next-friday/eslint-plugin-nextfriday/blob/main/docs/rules/${name.replaceAll("-", "_").toUpperCase()}.md`
|
|
1334
|
+
);
|
|
1335
|
+
var isTsFile = (filename) => filename.endsWith(".ts") && !filename.endsWith(".d.ts");
|
|
1336
|
+
var isCallbackContext = (node) => {
|
|
1337
|
+
const { parent } = node;
|
|
1338
|
+
if (!parent) {
|
|
1339
|
+
return false;
|
|
1340
|
+
}
|
|
1341
|
+
if (parent.type === import_utils19.AST_NODE_TYPES.CallExpression && parent.arguments.includes(node)) {
|
|
1342
|
+
return true;
|
|
1343
|
+
}
|
|
1344
|
+
if (parent.type === import_utils19.AST_NODE_TYPES.NewExpression && parent.arguments.includes(node)) {
|
|
1345
|
+
return true;
|
|
1346
|
+
}
|
|
1347
|
+
if (parent.type === import_utils19.AST_NODE_TYPES.ReturnStatement) {
|
|
1348
|
+
return true;
|
|
1349
|
+
}
|
|
1350
|
+
if (parent.type === import_utils19.AST_NODE_TYPES.Property) {
|
|
1351
|
+
return true;
|
|
1352
|
+
}
|
|
1353
|
+
if (parent.type === import_utils19.AST_NODE_TYPES.ArrayExpression) {
|
|
1354
|
+
return true;
|
|
1355
|
+
}
|
|
1356
|
+
if (parent.type === import_utils19.AST_NODE_TYPES.ConditionalExpression) {
|
|
1357
|
+
return true;
|
|
1358
|
+
}
|
|
1359
|
+
if (parent.type === import_utils19.AST_NODE_TYPES.LogicalExpression) {
|
|
1360
|
+
return true;
|
|
1361
|
+
}
|
|
1362
|
+
if (parent.type === import_utils19.AST_NODE_TYPES.AssignmentExpression && parent.left !== node) {
|
|
1363
|
+
return true;
|
|
1364
|
+
}
|
|
1365
|
+
return false;
|
|
1366
|
+
};
|
|
1367
|
+
var preferFunctionDeclaration = createRule17({
|
|
1368
|
+
name: "prefer-function-declaration",
|
|
1369
|
+
meta: {
|
|
1370
|
+
type: "suggestion",
|
|
1371
|
+
docs: {
|
|
1372
|
+
description: "Enforce function declarations over arrow functions assigned to variables in .ts files for better readability and hoisting"
|
|
1373
|
+
},
|
|
1374
|
+
messages: {
|
|
1375
|
+
preferDeclaration: "Use function declaration instead of arrow function. Replace 'const {{name}} = () => ...' with 'function {{name}}() ...'",
|
|
1376
|
+
preferDeclarationExpr: "Use function declaration instead of function expression. Replace 'const {{name}} = function() ...' with 'function {{name}}() ...'"
|
|
1377
|
+
},
|
|
1378
|
+
schema: []
|
|
1379
|
+
},
|
|
1380
|
+
defaultOptions: [],
|
|
1381
|
+
create(context) {
|
|
1382
|
+
const { filename } = context;
|
|
1383
|
+
if (!isTsFile(filename)) {
|
|
1384
|
+
return {};
|
|
1385
|
+
}
|
|
1386
|
+
return {
|
|
1387
|
+
VariableDeclarator(node) {
|
|
1388
|
+
if (node.id.type !== import_utils19.AST_NODE_TYPES.Identifier) {
|
|
1389
|
+
return;
|
|
1390
|
+
}
|
|
1391
|
+
const { init } = node;
|
|
1392
|
+
if (!init) {
|
|
1393
|
+
return;
|
|
1394
|
+
}
|
|
1395
|
+
if (init.type === import_utils19.AST_NODE_TYPES.ArrowFunctionExpression) {
|
|
1396
|
+
if (isCallbackContext(init)) {
|
|
1397
|
+
return;
|
|
1398
|
+
}
|
|
1399
|
+
context.report({
|
|
1400
|
+
node: init,
|
|
1401
|
+
messageId: "preferDeclaration",
|
|
1402
|
+
data: { name: node.id.name }
|
|
1403
|
+
});
|
|
1404
|
+
}
|
|
1405
|
+
if (init.type === import_utils19.AST_NODE_TYPES.FunctionExpression) {
|
|
1406
|
+
if (isCallbackContext(init)) {
|
|
1407
|
+
return;
|
|
1408
|
+
}
|
|
1409
|
+
context.report({
|
|
1410
|
+
node: init,
|
|
1411
|
+
messageId: "preferDeclarationExpr",
|
|
1412
|
+
data: { name: node.id.name }
|
|
1413
|
+
});
|
|
1414
|
+
}
|
|
1415
|
+
}
|
|
1416
|
+
};
|
|
1417
|
+
}
|
|
1418
|
+
});
|
|
1419
|
+
var prefer_function_declaration_default = preferFunctionDeclaration;
|
|
1420
|
+
|
|
700
1421
|
// src/rules/prefer-import-type.ts
|
|
701
|
-
var
|
|
702
|
-
var
|
|
703
|
-
(name) => `https://github.com/next-friday/eslint-plugin-nextfriday/blob/main/docs/rules/${name.
|
|
1422
|
+
var import_utils20 = require("@typescript-eslint/utils");
|
|
1423
|
+
var createRule18 = import_utils20.ESLintUtils.RuleCreator(
|
|
1424
|
+
(name) => `https://github.com/next-friday/eslint-plugin-nextfriday/blob/main/docs/rules/${name.replaceAll("-", "_").toUpperCase()}.md`
|
|
704
1425
|
);
|
|
705
|
-
var preferImportType =
|
|
1426
|
+
var preferImportType = createRule18({
|
|
706
1427
|
name: "prefer-import-type",
|
|
707
1428
|
meta: {
|
|
708
1429
|
type: "suggestion",
|
|
@@ -717,6 +1438,81 @@ var preferImportType = createRule11({
|
|
|
717
1438
|
},
|
|
718
1439
|
defaultOptions: [],
|
|
719
1440
|
create(context) {
|
|
1441
|
+
function isInTypeContext(node) {
|
|
1442
|
+
let current = node;
|
|
1443
|
+
while (current) {
|
|
1444
|
+
switch (current.type) {
|
|
1445
|
+
case import_utils20.AST_NODE_TYPES.TSTypeReference:
|
|
1446
|
+
case import_utils20.AST_NODE_TYPES.TSTypeAnnotation:
|
|
1447
|
+
case import_utils20.AST_NODE_TYPES.TSTypeParameterInstantiation:
|
|
1448
|
+
case import_utils20.AST_NODE_TYPES.TSInterfaceHeritage:
|
|
1449
|
+
case import_utils20.AST_NODE_TYPES.TSClassImplements:
|
|
1450
|
+
case import_utils20.AST_NODE_TYPES.TSTypeQuery:
|
|
1451
|
+
case import_utils20.AST_NODE_TYPES.TSTypeAssertion:
|
|
1452
|
+
case import_utils20.AST_NODE_TYPES.TSAsExpression:
|
|
1453
|
+
case import_utils20.AST_NODE_TYPES.TSSatisfiesExpression:
|
|
1454
|
+
case import_utils20.AST_NODE_TYPES.TSTypeAliasDeclaration:
|
|
1455
|
+
case import_utils20.AST_NODE_TYPES.TSInterfaceDeclaration:
|
|
1456
|
+
case import_utils20.AST_NODE_TYPES.TSTypeParameter:
|
|
1457
|
+
case import_utils20.AST_NODE_TYPES.TSQualifiedName:
|
|
1458
|
+
return true;
|
|
1459
|
+
case import_utils20.AST_NODE_TYPES.MemberExpression:
|
|
1460
|
+
case import_utils20.AST_NODE_TYPES.Identifier:
|
|
1461
|
+
current = current.parent;
|
|
1462
|
+
break;
|
|
1463
|
+
default:
|
|
1464
|
+
return false;
|
|
1465
|
+
}
|
|
1466
|
+
}
|
|
1467
|
+
return false;
|
|
1468
|
+
}
|
|
1469
|
+
function isUsedAsValue(localName, scope) {
|
|
1470
|
+
const variable = scope.set.get(localName);
|
|
1471
|
+
if (!variable) {
|
|
1472
|
+
return false;
|
|
1473
|
+
}
|
|
1474
|
+
if (variable.references.length === 0) {
|
|
1475
|
+
return false;
|
|
1476
|
+
}
|
|
1477
|
+
return variable.references.some((ref) => {
|
|
1478
|
+
if (ref.isWrite()) {
|
|
1479
|
+
return false;
|
|
1480
|
+
}
|
|
1481
|
+
const { identifier } = ref;
|
|
1482
|
+
const { parent } = identifier;
|
|
1483
|
+
if (!parent) {
|
|
1484
|
+
return false;
|
|
1485
|
+
}
|
|
1486
|
+
if (isInTypeContext(parent)) {
|
|
1487
|
+
return false;
|
|
1488
|
+
}
|
|
1489
|
+
switch (parent.type) {
|
|
1490
|
+
case import_utils20.AST_NODE_TYPES.CallExpression:
|
|
1491
|
+
case import_utils20.AST_NODE_TYPES.NewExpression:
|
|
1492
|
+
case import_utils20.AST_NODE_TYPES.JSXOpeningElement:
|
|
1493
|
+
case import_utils20.AST_NODE_TYPES.JSXClosingElement:
|
|
1494
|
+
case import_utils20.AST_NODE_TYPES.MemberExpression:
|
|
1495
|
+
case import_utils20.AST_NODE_TYPES.VariableDeclarator:
|
|
1496
|
+
case import_utils20.AST_NODE_TYPES.TaggedTemplateExpression:
|
|
1497
|
+
case import_utils20.AST_NODE_TYPES.SpreadElement:
|
|
1498
|
+
case import_utils20.AST_NODE_TYPES.ExportSpecifier:
|
|
1499
|
+
case import_utils20.AST_NODE_TYPES.ArrayExpression:
|
|
1500
|
+
case import_utils20.AST_NODE_TYPES.ObjectExpression:
|
|
1501
|
+
case import_utils20.AST_NODE_TYPES.BinaryExpression:
|
|
1502
|
+
case import_utils20.AST_NODE_TYPES.LogicalExpression:
|
|
1503
|
+
case import_utils20.AST_NODE_TYPES.UnaryExpression:
|
|
1504
|
+
case import_utils20.AST_NODE_TYPES.ReturnStatement:
|
|
1505
|
+
case import_utils20.AST_NODE_TYPES.ArrowFunctionExpression:
|
|
1506
|
+
case import_utils20.AST_NODE_TYPES.ConditionalExpression:
|
|
1507
|
+
case import_utils20.AST_NODE_TYPES.AwaitExpression:
|
|
1508
|
+
case import_utils20.AST_NODE_TYPES.YieldExpression:
|
|
1509
|
+
case import_utils20.AST_NODE_TYPES.Property:
|
|
1510
|
+
return true;
|
|
1511
|
+
default:
|
|
1512
|
+
return false;
|
|
1513
|
+
}
|
|
1514
|
+
});
|
|
1515
|
+
}
|
|
720
1516
|
function checkImportDeclaration(node) {
|
|
721
1517
|
if (node.importKind === "type") {
|
|
722
1518
|
return;
|
|
@@ -732,19 +1528,17 @@ var preferImportType = createRule11({
|
|
|
732
1528
|
if (isRuntimeImport) {
|
|
733
1529
|
return;
|
|
734
1530
|
}
|
|
1531
|
+
const scope = context.sourceCode.getScope(node);
|
|
735
1532
|
const isTypeOnlyImport = node.specifiers.every((specifier) => {
|
|
736
|
-
if (specifier.type ===
|
|
1533
|
+
if (specifier.type === import_utils20.AST_NODE_TYPES.ImportDefaultSpecifier) {
|
|
737
1534
|
return false;
|
|
738
1535
|
}
|
|
739
|
-
if (specifier.type ===
|
|
1536
|
+
if (specifier.type === import_utils20.AST_NODE_TYPES.ImportNamespaceSpecifier) {
|
|
740
1537
|
return false;
|
|
741
1538
|
}
|
|
742
|
-
if (specifier.type ===
|
|
743
|
-
const
|
|
744
|
-
|
|
745
|
-
importedName
|
|
746
|
-
) || importedName.endsWith("Type") || importedName.endsWith("Interface") || importedName.endsWith("Props");
|
|
747
|
-
return isKnownTypeOnly;
|
|
1539
|
+
if (specifier.type === import_utils20.AST_NODE_TYPES.ImportSpecifier) {
|
|
1540
|
+
const localName = specifier.local.name;
|
|
1541
|
+
return !isUsedAsValue(localName, scope);
|
|
748
1542
|
}
|
|
749
1543
|
return false;
|
|
750
1544
|
});
|
|
@@ -768,11 +1562,11 @@ var preferImportType = createRule11({
|
|
|
768
1562
|
var prefer_import_type_default = preferImportType;
|
|
769
1563
|
|
|
770
1564
|
// src/rules/prefer-interface-over-inline-types.ts
|
|
771
|
-
var
|
|
772
|
-
var
|
|
773
|
-
(name) => `https://github.com/next-friday/eslint-plugin-nextfriday/blob/main/docs/rules/${name.
|
|
1565
|
+
var import_utils21 = require("@typescript-eslint/utils");
|
|
1566
|
+
var createRule19 = import_utils21.ESLintUtils.RuleCreator(
|
|
1567
|
+
(name) => `https://github.com/next-friday/eslint-plugin-nextfriday/blob/main/docs/rules/${name.replaceAll("-", "_").toUpperCase()}.md`
|
|
774
1568
|
);
|
|
775
|
-
var preferInterfaceOverInlineTypes =
|
|
1569
|
+
var preferInterfaceOverInlineTypes = createRule19({
|
|
776
1570
|
name: "prefer-interface-over-inline-types",
|
|
777
1571
|
meta: {
|
|
778
1572
|
type: "suggestion",
|
|
@@ -788,67 +1582,67 @@ var preferInterfaceOverInlineTypes = createRule12({
|
|
|
788
1582
|
defaultOptions: [],
|
|
789
1583
|
create(context) {
|
|
790
1584
|
function hasJSXInConditional(node) {
|
|
791
|
-
return node.consequent.type ===
|
|
1585
|
+
return node.consequent.type === import_utils21.AST_NODE_TYPES.JSXElement || node.consequent.type === import_utils21.AST_NODE_TYPES.JSXFragment || node.alternate.type === import_utils21.AST_NODE_TYPES.JSXElement || node.alternate.type === import_utils21.AST_NODE_TYPES.JSXFragment;
|
|
792
1586
|
}
|
|
793
1587
|
function hasJSXInLogical(node) {
|
|
794
|
-
return node.right.type ===
|
|
1588
|
+
return node.right.type === import_utils21.AST_NODE_TYPES.JSXElement || node.right.type === import_utils21.AST_NODE_TYPES.JSXFragment;
|
|
795
1589
|
}
|
|
796
1590
|
function hasJSXReturn(block) {
|
|
797
1591
|
return block.body.some((stmt) => {
|
|
798
|
-
if (stmt.type ===
|
|
799
|
-
return stmt.argument.type ===
|
|
1592
|
+
if (stmt.type === import_utils21.AST_NODE_TYPES.ReturnStatement && stmt.argument) {
|
|
1593
|
+
return stmt.argument.type === import_utils21.AST_NODE_TYPES.JSXElement || stmt.argument.type === import_utils21.AST_NODE_TYPES.JSXFragment || stmt.argument.type === import_utils21.AST_NODE_TYPES.ConditionalExpression && hasJSXInConditional(stmt.argument) || stmt.argument.type === import_utils21.AST_NODE_TYPES.LogicalExpression && hasJSXInLogical(stmt.argument);
|
|
800
1594
|
}
|
|
801
1595
|
return false;
|
|
802
1596
|
});
|
|
803
1597
|
}
|
|
804
|
-
function
|
|
805
|
-
if (node.type ===
|
|
806
|
-
if (node.body.type ===
|
|
1598
|
+
function isReactComponent2(node) {
|
|
1599
|
+
if (node.type === import_utils21.AST_NODE_TYPES.ArrowFunctionExpression) {
|
|
1600
|
+
if (node.body.type === import_utils21.AST_NODE_TYPES.JSXElement || node.body.type === import_utils21.AST_NODE_TYPES.JSXFragment) {
|
|
807
1601
|
return true;
|
|
808
1602
|
}
|
|
809
|
-
if (node.body.type ===
|
|
1603
|
+
if (node.body.type === import_utils21.AST_NODE_TYPES.BlockStatement) {
|
|
810
1604
|
return hasJSXReturn(node.body);
|
|
811
1605
|
}
|
|
812
|
-
} else if (node.type ===
|
|
813
|
-
if (node.body && node.body.type ===
|
|
1606
|
+
} else if (node.type === import_utils21.AST_NODE_TYPES.FunctionExpression || node.type === import_utils21.AST_NODE_TYPES.FunctionDeclaration) {
|
|
1607
|
+
if (node.body && node.body.type === import_utils21.AST_NODE_TYPES.BlockStatement) {
|
|
814
1608
|
return hasJSXReturn(node.body);
|
|
815
1609
|
}
|
|
816
1610
|
}
|
|
817
1611
|
return false;
|
|
818
1612
|
}
|
|
819
1613
|
function isInlineTypeAnnotation(node) {
|
|
820
|
-
if (node.type ===
|
|
1614
|
+
if (node.type === import_utils21.AST_NODE_TYPES.TSTypeLiteral) {
|
|
821
1615
|
return true;
|
|
822
1616
|
}
|
|
823
|
-
if (node.type ===
|
|
824
|
-
return node.typeArguments.params.some((param) => param.type ===
|
|
1617
|
+
if (node.type === import_utils21.AST_NODE_TYPES.TSTypeReference && node.typeArguments) {
|
|
1618
|
+
return node.typeArguments.params.some((param) => param.type === import_utils21.AST_NODE_TYPES.TSTypeLiteral);
|
|
825
1619
|
}
|
|
826
|
-
if (node.type ===
|
|
1620
|
+
if (node.type === import_utils21.AST_NODE_TYPES.TSUnionType) {
|
|
827
1621
|
return node.types.some((type) => isInlineTypeAnnotation(type));
|
|
828
1622
|
}
|
|
829
1623
|
return false;
|
|
830
1624
|
}
|
|
831
1625
|
function hasInlineObjectType(node) {
|
|
832
|
-
if (node.type ===
|
|
1626
|
+
if (node.type === import_utils21.AST_NODE_TYPES.TSTypeLiteral) {
|
|
833
1627
|
return true;
|
|
834
1628
|
}
|
|
835
|
-
if (node.type ===
|
|
836
|
-
return node.typeArguments.params.some((param) => param.type ===
|
|
1629
|
+
if (node.type === import_utils21.AST_NODE_TYPES.TSTypeReference && node.typeArguments) {
|
|
1630
|
+
return node.typeArguments.params.some((param) => param.type === import_utils21.AST_NODE_TYPES.TSTypeLiteral);
|
|
837
1631
|
}
|
|
838
|
-
if (node.type ===
|
|
1632
|
+
if (node.type === import_utils21.AST_NODE_TYPES.TSUnionType) {
|
|
839
1633
|
return node.types.some((type) => hasInlineObjectType(type));
|
|
840
1634
|
}
|
|
841
1635
|
return false;
|
|
842
1636
|
}
|
|
843
1637
|
function checkFunction(node) {
|
|
844
|
-
if (!
|
|
1638
|
+
if (!isReactComponent2(node)) {
|
|
845
1639
|
return;
|
|
846
1640
|
}
|
|
847
1641
|
if (node.params.length !== 1) {
|
|
848
1642
|
return;
|
|
849
1643
|
}
|
|
850
1644
|
const param = node.params[0];
|
|
851
|
-
if (param.type ===
|
|
1645
|
+
if (param.type === import_utils21.AST_NODE_TYPES.Identifier && param.typeAnnotation) {
|
|
852
1646
|
const { typeAnnotation } = param.typeAnnotation;
|
|
853
1647
|
if (isInlineTypeAnnotation(typeAnnotation) && hasInlineObjectType(typeAnnotation)) {
|
|
854
1648
|
context.report({
|
|
@@ -867,12 +1661,100 @@ var preferInterfaceOverInlineTypes = createRule12({
|
|
|
867
1661
|
});
|
|
868
1662
|
var prefer_interface_over_inline_types_default = preferInterfaceOverInlineTypes;
|
|
869
1663
|
|
|
1664
|
+
// src/rules/prefer-jsx-template-literals.ts
|
|
1665
|
+
var import_utils22 = require("@typescript-eslint/utils");
|
|
1666
|
+
var createRule20 = import_utils22.ESLintUtils.RuleCreator(
|
|
1667
|
+
(name) => `https://github.com/next-friday/eslint-plugin-nextfriday/blob/main/docs/rules/${name.replaceAll("-", "_").toUpperCase()}.md`
|
|
1668
|
+
);
|
|
1669
|
+
var preferJSXTemplateLiterals = createRule20({
|
|
1670
|
+
name: "prefer-jsx-template-literals",
|
|
1671
|
+
meta: {
|
|
1672
|
+
type: "suggestion",
|
|
1673
|
+
docs: {
|
|
1674
|
+
description: "Enforce using template literals instead of mixing text and JSX expressions"
|
|
1675
|
+
},
|
|
1676
|
+
fixable: "code",
|
|
1677
|
+
schema: [],
|
|
1678
|
+
messages: {
|
|
1679
|
+
preferTemplate: "Use template literal instead of mixing text with JSX expressions"
|
|
1680
|
+
}
|
|
1681
|
+
},
|
|
1682
|
+
defaultOptions: [],
|
|
1683
|
+
create(context) {
|
|
1684
|
+
function handleTextBeforeExpression(textNode, exprNode) {
|
|
1685
|
+
const textValue = textNode.value;
|
|
1686
|
+
const trimmedText = textValue.trim();
|
|
1687
|
+
if (!trimmedText) {
|
|
1688
|
+
return;
|
|
1689
|
+
}
|
|
1690
|
+
const hasTextContent = trimmedText.length > 0 && textValue !== trimmedText;
|
|
1691
|
+
const hasNoTrailingSpace = trimmedText.length > 0 && /\S$/.test(textValue);
|
|
1692
|
+
if (!hasTextContent && !hasNoTrailingSpace) {
|
|
1693
|
+
return;
|
|
1694
|
+
}
|
|
1695
|
+
context.report({
|
|
1696
|
+
node: textNode,
|
|
1697
|
+
messageId: "preferTemplate",
|
|
1698
|
+
fix(fixer) {
|
|
1699
|
+
const textPart = textValue.trimEnd();
|
|
1700
|
+
const exprText = context.sourceCode.getText(exprNode.expression);
|
|
1701
|
+
const templateLiteral = `{\`${textPart}\${${exprText}}\`}`;
|
|
1702
|
+
return [fixer.replaceText(textNode, templateLiteral), fixer.remove(exprNode)];
|
|
1703
|
+
}
|
|
1704
|
+
});
|
|
1705
|
+
}
|
|
1706
|
+
function handleExpressionBeforeText(exprNode, textNode) {
|
|
1707
|
+
const textValue = textNode.value;
|
|
1708
|
+
const trimmedText = textValue.trim();
|
|
1709
|
+
if (!trimmedText) {
|
|
1710
|
+
return;
|
|
1711
|
+
}
|
|
1712
|
+
const startsWithNonWhitespace = /^\S/.test(trimmedText);
|
|
1713
|
+
if (!startsWithNonWhitespace) {
|
|
1714
|
+
return;
|
|
1715
|
+
}
|
|
1716
|
+
context.report({
|
|
1717
|
+
node: textNode,
|
|
1718
|
+
messageId: "preferTemplate",
|
|
1719
|
+
fix(fixer) {
|
|
1720
|
+
const exprText = context.sourceCode.getText(exprNode.expression);
|
|
1721
|
+
const textPart = textValue.trim();
|
|
1722
|
+
const templateLiteral = `{\`\${${exprText}}${textPart}\`}`;
|
|
1723
|
+
return [fixer.replaceText(exprNode, templateLiteral), fixer.remove(textNode)];
|
|
1724
|
+
}
|
|
1725
|
+
});
|
|
1726
|
+
}
|
|
1727
|
+
function checkJSXElement(node) {
|
|
1728
|
+
const { children } = node;
|
|
1729
|
+
if (children.length < 2) {
|
|
1730
|
+
return;
|
|
1731
|
+
}
|
|
1732
|
+
for (let i = 0; i < children.length - 1; i += 1) {
|
|
1733
|
+
const child = children[i];
|
|
1734
|
+
const nextChild = children[i + 1];
|
|
1735
|
+
if (!child || !nextChild) {
|
|
1736
|
+
return;
|
|
1737
|
+
}
|
|
1738
|
+
if (child.type === import_utils22.AST_NODE_TYPES.JSXText && nextChild.type === import_utils22.AST_NODE_TYPES.JSXExpressionContainer) {
|
|
1739
|
+
handleTextBeforeExpression(child, nextChild);
|
|
1740
|
+
} else if (child.type === import_utils22.AST_NODE_TYPES.JSXExpressionContainer && nextChild.type === import_utils22.AST_NODE_TYPES.JSXText) {
|
|
1741
|
+
handleExpressionBeforeText(child, nextChild);
|
|
1742
|
+
}
|
|
1743
|
+
}
|
|
1744
|
+
}
|
|
1745
|
+
return {
|
|
1746
|
+
JSXElement: checkJSXElement
|
|
1747
|
+
};
|
|
1748
|
+
}
|
|
1749
|
+
});
|
|
1750
|
+
var prefer_jsx_template_literals_default = preferJSXTemplateLiterals;
|
|
1751
|
+
|
|
870
1752
|
// src/rules/prefer-named-param-types.ts
|
|
871
|
-
var
|
|
872
|
-
var
|
|
873
|
-
(name) => `https://github.com/next-friday/eslint-plugin-nextfriday/blob/main/docs/rules/${name.
|
|
1753
|
+
var import_utils23 = require("@typescript-eslint/utils");
|
|
1754
|
+
var createRule21 = import_utils23.ESLintUtils.RuleCreator(
|
|
1755
|
+
(name) => `https://github.com/next-friday/eslint-plugin-nextfriday/blob/main/docs/rules/${name.replaceAll("-", "_").toUpperCase()}.md`
|
|
874
1756
|
);
|
|
875
|
-
var preferNamedParamTypes =
|
|
1757
|
+
var preferNamedParamTypes = createRule21({
|
|
876
1758
|
name: "prefer-named-param-types",
|
|
877
1759
|
meta: {
|
|
878
1760
|
type: "suggestion",
|
|
@@ -887,16 +1769,16 @@ var preferNamedParamTypes = createRule13({
|
|
|
887
1769
|
defaultOptions: [],
|
|
888
1770
|
create(context) {
|
|
889
1771
|
function hasInlineObjectType(param) {
|
|
890
|
-
if (param.type ===
|
|
1772
|
+
if (param.type === import_utils23.AST_NODE_TYPES.AssignmentPattern) {
|
|
891
1773
|
return hasInlineObjectType(param.left);
|
|
892
1774
|
}
|
|
893
|
-
if (param.type ===
|
|
894
|
-
if (param.typeAnnotation?.typeAnnotation.type ===
|
|
1775
|
+
if (param.type === import_utils23.AST_NODE_TYPES.ObjectPattern) {
|
|
1776
|
+
if (param.typeAnnotation?.typeAnnotation.type === import_utils23.AST_NODE_TYPES.TSTypeLiteral) {
|
|
895
1777
|
return true;
|
|
896
1778
|
}
|
|
897
1779
|
}
|
|
898
|
-
if (param.type ===
|
|
899
|
-
if (param.typeAnnotation?.typeAnnotation.type ===
|
|
1780
|
+
if (param.type === import_utils23.AST_NODE_TYPES.Identifier) {
|
|
1781
|
+
if (param.typeAnnotation?.typeAnnotation.type === import_utils23.AST_NODE_TYPES.TSTypeLiteral) {
|
|
900
1782
|
return true;
|
|
901
1783
|
}
|
|
902
1784
|
}
|
|
@@ -930,11 +1812,11 @@ var preferNamedParamTypes = createRule13({
|
|
|
930
1812
|
var prefer_named_param_types_default = preferNamedParamTypes;
|
|
931
1813
|
|
|
932
1814
|
// src/rules/prefer-react-import-types.ts
|
|
933
|
-
var
|
|
934
|
-
var
|
|
935
|
-
(name) => `https://github.com/next-friday/eslint-plugin-nextfriday/blob/main/docs/rules/${name.
|
|
1815
|
+
var import_utils24 = require("@typescript-eslint/utils");
|
|
1816
|
+
var createRule22 = import_utils24.ESLintUtils.RuleCreator(
|
|
1817
|
+
(name) => `https://github.com/next-friday/eslint-plugin-nextfriday/blob/main/docs/rules/${name.replaceAll("-", "_").toUpperCase()}.md`
|
|
936
1818
|
);
|
|
937
|
-
var preferReactImportTypes =
|
|
1819
|
+
var preferReactImportTypes = createRule22({
|
|
938
1820
|
name: "prefer-react-import-types",
|
|
939
1821
|
meta: {
|
|
940
1822
|
type: "suggestion",
|
|
@@ -1010,7 +1892,7 @@ var preferReactImportTypes = createRule14({
|
|
|
1010
1892
|
]);
|
|
1011
1893
|
const allReactExports = /* @__PURE__ */ new Set([...reactTypes, ...reactRuntimeExports]);
|
|
1012
1894
|
function checkMemberExpression(node) {
|
|
1013
|
-
if (node.object.type ===
|
|
1895
|
+
if (node.object.type === import_utils24.AST_NODE_TYPES.Identifier && node.object.name === "React" && node.property.type === import_utils24.AST_NODE_TYPES.Identifier && allReactExports.has(node.property.name)) {
|
|
1014
1896
|
const typeName = node.property.name;
|
|
1015
1897
|
const isType = reactTypes.has(typeName);
|
|
1016
1898
|
const importStatement = isType ? `import type { ${typeName} } from "react"` : `import { ${typeName} } from "react"`;
|
|
@@ -1027,7 +1909,7 @@ var preferReactImportTypes = createRule14({
|
|
|
1027
1909
|
return {
|
|
1028
1910
|
MemberExpression: checkMemberExpression,
|
|
1029
1911
|
"TSTypeReference > TSQualifiedName": (node) => {
|
|
1030
|
-
if (node.left.type ===
|
|
1912
|
+
if (node.left.type === import_utils24.AST_NODE_TYPES.Identifier && node.left.name === "React" && node.right.type === import_utils24.AST_NODE_TYPES.Identifier && allReactExports.has(node.right.name)) {
|
|
1031
1913
|
const typeName = node.right.name;
|
|
1032
1914
|
const isType = reactTypes.has(typeName);
|
|
1033
1915
|
const importStatement = isType ? `import type { ${typeName} } from "react"` : `import { ${typeName} } from "react"`;
|
|
@@ -1047,11 +1929,11 @@ var preferReactImportTypes = createRule14({
|
|
|
1047
1929
|
var prefer_react_import_types_default = preferReactImportTypes;
|
|
1048
1930
|
|
|
1049
1931
|
// src/rules/react-props-destructure.ts
|
|
1050
|
-
var
|
|
1051
|
-
var
|
|
1052
|
-
(name) => `https://github.com/next-friday/eslint-plugin-nextfriday/blob/main/docs/rules/${name.
|
|
1932
|
+
var import_utils25 = require("@typescript-eslint/utils");
|
|
1933
|
+
var createRule23 = import_utils25.ESLintUtils.RuleCreator(
|
|
1934
|
+
(name) => `https://github.com/next-friday/eslint-plugin-nextfriday/blob/main/docs/rules/${name.replaceAll("-", "_").toUpperCase()}.md`
|
|
1053
1935
|
);
|
|
1054
|
-
var reactPropsDestructure =
|
|
1936
|
+
var reactPropsDestructure = createRule23({
|
|
1055
1937
|
name: "react-props-destructure",
|
|
1056
1938
|
meta: {
|
|
1057
1939
|
type: "suggestion",
|
|
@@ -1067,45 +1949,45 @@ var reactPropsDestructure = createRule15({
|
|
|
1067
1949
|
defaultOptions: [],
|
|
1068
1950
|
create(context) {
|
|
1069
1951
|
function hasJSXInConditional(node) {
|
|
1070
|
-
return node.consequent.type ===
|
|
1952
|
+
return node.consequent.type === import_utils25.AST_NODE_TYPES.JSXElement || node.consequent.type === import_utils25.AST_NODE_TYPES.JSXFragment || node.alternate.type === import_utils25.AST_NODE_TYPES.JSXElement || node.alternate.type === import_utils25.AST_NODE_TYPES.JSXFragment;
|
|
1071
1953
|
}
|
|
1072
1954
|
function hasJSXInLogical(node) {
|
|
1073
|
-
return node.right.type ===
|
|
1955
|
+
return node.right.type === import_utils25.AST_NODE_TYPES.JSXElement || node.right.type === import_utils25.AST_NODE_TYPES.JSXFragment;
|
|
1074
1956
|
}
|
|
1075
1957
|
function hasJSXReturn(block) {
|
|
1076
1958
|
return block.body.some((stmt) => {
|
|
1077
|
-
if (stmt.type ===
|
|
1078
|
-
return stmt.argument.type ===
|
|
1959
|
+
if (stmt.type === import_utils25.AST_NODE_TYPES.ReturnStatement && stmt.argument) {
|
|
1960
|
+
return stmt.argument.type === import_utils25.AST_NODE_TYPES.JSXElement || stmt.argument.type === import_utils25.AST_NODE_TYPES.JSXFragment || stmt.argument.type === import_utils25.AST_NODE_TYPES.ConditionalExpression && hasJSXInConditional(stmt.argument) || stmt.argument.type === import_utils25.AST_NODE_TYPES.LogicalExpression && hasJSXInLogical(stmt.argument);
|
|
1079
1961
|
}
|
|
1080
1962
|
return false;
|
|
1081
1963
|
});
|
|
1082
1964
|
}
|
|
1083
|
-
function
|
|
1084
|
-
if (node.type ===
|
|
1085
|
-
if (node.body.type ===
|
|
1965
|
+
function isReactComponent2(node) {
|
|
1966
|
+
if (node.type === import_utils25.AST_NODE_TYPES.ArrowFunctionExpression) {
|
|
1967
|
+
if (node.body.type === import_utils25.AST_NODE_TYPES.JSXElement || node.body.type === import_utils25.AST_NODE_TYPES.JSXFragment) {
|
|
1086
1968
|
return true;
|
|
1087
1969
|
}
|
|
1088
|
-
if (node.body.type ===
|
|
1970
|
+
if (node.body.type === import_utils25.AST_NODE_TYPES.BlockStatement) {
|
|
1089
1971
|
return hasJSXReturn(node.body);
|
|
1090
1972
|
}
|
|
1091
|
-
} else if (node.type ===
|
|
1092
|
-
if (node.body && node.body.type ===
|
|
1973
|
+
} else if (node.type === import_utils25.AST_NODE_TYPES.FunctionExpression || node.type === import_utils25.AST_NODE_TYPES.FunctionDeclaration) {
|
|
1974
|
+
if (node.body && node.body.type === import_utils25.AST_NODE_TYPES.BlockStatement) {
|
|
1093
1975
|
return hasJSXReturn(node.body);
|
|
1094
1976
|
}
|
|
1095
1977
|
}
|
|
1096
1978
|
return false;
|
|
1097
1979
|
}
|
|
1098
1980
|
function checkFunction(node) {
|
|
1099
|
-
if (!
|
|
1981
|
+
if (!isReactComponent2(node)) {
|
|
1100
1982
|
return;
|
|
1101
1983
|
}
|
|
1102
1984
|
if (node.params.length !== 1) {
|
|
1103
1985
|
return;
|
|
1104
1986
|
}
|
|
1105
1987
|
const param = node.params[0];
|
|
1106
|
-
if (param.type ===
|
|
1107
|
-
const properties = param.properties.filter((prop) => prop.type ===
|
|
1108
|
-
if (prop.key.type ===
|
|
1988
|
+
if (param.type === import_utils25.AST_NODE_TYPES.ObjectPattern) {
|
|
1989
|
+
const properties = param.properties.filter((prop) => prop.type === import_utils25.AST_NODE_TYPES.Property).map((prop) => {
|
|
1990
|
+
if (prop.key.type === import_utils25.AST_NODE_TYPES.Identifier) {
|
|
1109
1991
|
return prop.key.name;
|
|
1110
1992
|
}
|
|
1111
1993
|
return null;
|
|
@@ -1137,18 +2019,26 @@ var meta = {
|
|
|
1137
2019
|
version: package_default.version
|
|
1138
2020
|
};
|
|
1139
2021
|
var rules = {
|
|
2022
|
+
"boolean-naming-prefix": boolean_naming_prefix_default,
|
|
1140
2023
|
"enforce-readonly-component-props": enforce_readonly_component_props_default,
|
|
2024
|
+
"enforce-sorted-destructuring": enforce_sorted_destructuring_default,
|
|
1141
2025
|
"file-kebab-case": file_kebab_case_default,
|
|
1142
2026
|
"jsx-pascal-case": jsx_pascal_case_default,
|
|
2027
|
+
"jsx-no-non-component-function": jsx_no_non_component_function_default,
|
|
2028
|
+
"jsx-no-variable-in-callback": jsx_no_variable_in_callback_default,
|
|
1143
2029
|
"md-filename-case-restriction": md_filename_case_restriction_default,
|
|
1144
2030
|
"no-complex-inline-return": no_complex_inline_return_default,
|
|
2031
|
+
"no-direct-date": no_direct_date_default,
|
|
1145
2032
|
"no-emoji": no_emoji_default,
|
|
1146
2033
|
"no-env-fallback": no_env_fallback_default,
|
|
1147
|
-
"
|
|
2034
|
+
"require-explicit-return-type": require_explicit_return_type_default,
|
|
1148
2035
|
"no-logic-in-params": no_logic_in_params_default,
|
|
2036
|
+
"no-single-char-variables": no_single_char_variables_default,
|
|
1149
2037
|
"prefer-destructuring-params": prefer_destructuring_params_default,
|
|
2038
|
+
"prefer-function-declaration": prefer_function_declaration_default,
|
|
1150
2039
|
"prefer-import-type": prefer_import_type_default,
|
|
1151
2040
|
"prefer-interface-over-inline-types": prefer_interface_over_inline_types_default,
|
|
2041
|
+
"prefer-jsx-template-literals": prefer_jsx_template_literals_default,
|
|
1152
2042
|
"prefer-named-param-types": prefer_named_param_types_default,
|
|
1153
2043
|
"prefer-react-import-types": prefer_react_import_types_default,
|
|
1154
2044
|
"react-props-destructure": react_props_destructure_default
|
|
@@ -1158,40 +2048,56 @@ var plugin = {
|
|
|
1158
2048
|
rules
|
|
1159
2049
|
};
|
|
1160
2050
|
var baseRules = {
|
|
2051
|
+
"nextfriday/boolean-naming-prefix": "warn",
|
|
1161
2052
|
"nextfriday/no-emoji": "warn",
|
|
2053
|
+
"nextfriday/enforce-sorted-destructuring": "warn",
|
|
1162
2054
|
"nextfriday/file-kebab-case": "warn",
|
|
1163
2055
|
"nextfriday/md-filename-case-restriction": "warn",
|
|
1164
2056
|
"nextfriday/prefer-destructuring-params": "warn",
|
|
1165
|
-
"nextfriday/
|
|
2057
|
+
"nextfriday/prefer-function-declaration": "warn",
|
|
2058
|
+
"nextfriday/require-explicit-return-type": "warn",
|
|
1166
2059
|
"nextfriday/prefer-import-type": "warn",
|
|
1167
2060
|
"nextfriday/prefer-named-param-types": "warn",
|
|
1168
2061
|
"nextfriday/prefer-react-import-types": "warn",
|
|
1169
2062
|
"nextfriday/no-complex-inline-return": "warn",
|
|
2063
|
+
"nextfriday/no-direct-date": "warn",
|
|
1170
2064
|
"nextfriday/no-logic-in-params": "warn",
|
|
1171
|
-
"nextfriday/no-env-fallback": "warn"
|
|
2065
|
+
"nextfriday/no-env-fallback": "warn",
|
|
2066
|
+
"nextfriday/no-single-char-variables": "warn"
|
|
1172
2067
|
};
|
|
1173
2068
|
var baseRecommendedRules = {
|
|
2069
|
+
"nextfriday/boolean-naming-prefix": "error",
|
|
1174
2070
|
"nextfriday/no-emoji": "error",
|
|
2071
|
+
"nextfriday/enforce-sorted-destructuring": "error",
|
|
1175
2072
|
"nextfriday/file-kebab-case": "error",
|
|
1176
2073
|
"nextfriday/md-filename-case-restriction": "error",
|
|
1177
2074
|
"nextfriday/prefer-destructuring-params": "error",
|
|
1178
|
-
"nextfriday/
|
|
2075
|
+
"nextfriday/prefer-function-declaration": "error",
|
|
2076
|
+
"nextfriday/require-explicit-return-type": "error",
|
|
1179
2077
|
"nextfriday/prefer-import-type": "error",
|
|
1180
2078
|
"nextfriday/prefer-named-param-types": "error",
|
|
1181
2079
|
"nextfriday/prefer-react-import-types": "error",
|
|
1182
2080
|
"nextfriday/no-complex-inline-return": "error",
|
|
2081
|
+
"nextfriday/no-direct-date": "error",
|
|
1183
2082
|
"nextfriday/no-logic-in-params": "error",
|
|
1184
|
-
"nextfriday/no-env-fallback": "error"
|
|
2083
|
+
"nextfriday/no-env-fallback": "error",
|
|
2084
|
+
"nextfriday/no-single-char-variables": "error"
|
|
1185
2085
|
};
|
|
1186
2086
|
var jsxRules = {
|
|
1187
2087
|
"nextfriday/jsx-pascal-case": "warn",
|
|
2088
|
+
"nextfriday/jsx-no-non-component-function": "warn",
|
|
2089
|
+
"nextfriday/jsx-no-variable-in-callback": "warn",
|
|
1188
2090
|
"nextfriday/prefer-interface-over-inline-types": "warn",
|
|
2091
|
+
"nextfriday/prefer-jsx-template-literals": "warn",
|
|
1189
2092
|
"nextfriday/react-props-destructure": "warn",
|
|
1190
2093
|
"nextfriday/enforce-readonly-component-props": "warn"
|
|
1191
2094
|
};
|
|
1192
2095
|
var jsxRecommendedRules = {
|
|
1193
2096
|
"nextfriday/jsx-pascal-case": "error",
|
|
2097
|
+
"nextfriday/jsx-no-non-component-function": "error",
|
|
2098
|
+
"nextfriday/jsx-no-variable-in-callback": "error",
|
|
1194
2099
|
"nextfriday/prefer-interface-over-inline-types": "error",
|
|
2100
|
+
"nextfriday/prefer-jsx-template-literals": "error",
|
|
1195
2101
|
"nextfriday/react-props-destructure": "error",
|
|
1196
2102
|
"nextfriday/enforce-readonly-component-props": "error"
|
|
1197
2103
|
};
|