eslint-plugin-nextfriday 4.4.0 → 5.0.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 +28 -0
- package/README.md +2 -29
- package/docs/rules/BOOLEAN_NAMING_PREFIX.md +0 -1
- package/docs/rules/ENFORCE_CONSTANT_CASE.md +0 -2
- package/docs/rules/ENFORCE_READONLY_COMPONENT_PROPS.md +0 -1
- package/docs/rules/INDEX_EXPORT_ONLY.md +7 -0
- package/docs/rules/NO_GHOST_WRAPPER.md +0 -4
- package/docs/rules/NO_LAZY_IDENTIFIERS.md +1 -2
- package/docs/rules/NO_MISLEADING_CONSTANT_CASE.md +0 -1
- package/docs/rules/SORT_IMPORTS.md +24 -14
- package/lib/index.cjs +105 -624
- package/lib/index.cjs.map +1 -1
- package/lib/index.d.cts +28 -406
- package/lib/index.d.cts.map +1 -1
- package/lib/index.d.ts +28 -406
- package/lib/index.d.ts.map +1 -1
- package/lib/index.js +105 -624
- package/lib/index.js.map +1 -1
- package/package.json +1 -1
- package/docs/rules/ENFORCE_CAMEL_CASE.md +0 -68
- package/docs/rules/ENFORCE_PROPERTY_CASE.md +0 -63
- package/docs/rules/NO_INLINE_DEFAULT_EXPORT.md +0 -97
- package/docs/rules/NO_NESTED_TERNARY.md +0 -45
- package/docs/rules/NO_REDUNDANT_FRAGMENT.md +0 -56
- package/docs/rules/NO_SINGLE_CHAR_VARIABLES.md +0 -98
- package/docs/rules/PREFER_FUNCTION_DECLARATION.md +0 -118
- package/docs/rules/PREFER_JSX_TEMPLATE_LITERALS.md +0 -80
- package/docs/rules/REACT_PROPS_DESTRUCTURE.md +0 -99
package/lib/index.cjs
CHANGED
|
@@ -32,10 +32,10 @@ let emoji_regex = require("emoji-regex");
|
|
|
32
32
|
emoji_regex = __toESM(emoji_regex, 1);
|
|
33
33
|
//#region package.json
|
|
34
34
|
var name = "eslint-plugin-nextfriday";
|
|
35
|
-
var version = "
|
|
35
|
+
var version = "5.0.0";
|
|
36
36
|
//#endregion
|
|
37
37
|
//#region src/rules/boolean-naming-prefix.ts
|
|
38
|
-
const createRule$
|
|
38
|
+
const createRule$26 = _typescript_eslint_utils.ESLintUtils.RuleCreator((name) => `https://github.com/next-friday/eslint-plugin-nextfriday/blob/main/docs/rules/${name.replaceAll("-", "_").toUpperCase()}.md`);
|
|
39
39
|
const BOOLEAN_PREFIXES = [
|
|
40
40
|
"is",
|
|
41
41
|
"has",
|
|
@@ -84,7 +84,7 @@ const hasBooleanTypeAnnotation = (node) => {
|
|
|
84
84
|
}
|
|
85
85
|
return false;
|
|
86
86
|
};
|
|
87
|
-
const booleanNamingPrefix = createRule$
|
|
87
|
+
const booleanNamingPrefix = createRule$26({
|
|
88
88
|
name: "boolean-naming-prefix",
|
|
89
89
|
meta: {
|
|
90
90
|
type: "suggestion",
|
|
@@ -144,99 +144,6 @@ const booleanNamingPrefix = createRule$31({
|
|
|
144
144
|
}
|
|
145
145
|
});
|
|
146
146
|
//#endregion
|
|
147
|
-
//#region src/rules/enforce-camel-case.ts
|
|
148
|
-
const createRule$30 = _typescript_eslint_utils.ESLintUtils.RuleCreator((name) => `https://github.com/next-friday/eslint-plugin-nextfriday/blob/main/docs/rules/${name.replaceAll("-", "_").toUpperCase()}.md`);
|
|
149
|
-
const SNAKE_CASE_REGEX$2 = /^[a-z]+_[a-z0-9_]*$/;
|
|
150
|
-
const PASCAL_CASE_REGEX = /^[A-Z][a-zA-Z0-9]*$/;
|
|
151
|
-
const REACT_WRAPPERS = [
|
|
152
|
-
"memo",
|
|
153
|
-
"forwardRef",
|
|
154
|
-
"lazy"
|
|
155
|
-
];
|
|
156
|
-
const returnsJsx$1 = (node) => {
|
|
157
|
-
if (node.type === _typescript_eslint_utils.AST_NODE_TYPES.JSXElement || node.type === _typescript_eslint_utils.AST_NODE_TYPES.JSXFragment) return true;
|
|
158
|
-
if (node.type === _typescript_eslint_utils.AST_NODE_TYPES.ConditionalExpression) return returnsJsx$1(node.consequent) || returnsJsx$1(node.alternate);
|
|
159
|
-
if (node.type === _typescript_eslint_utils.AST_NODE_TYPES.LogicalExpression) return returnsJsx$1(node.left) || returnsJsx$1(node.right);
|
|
160
|
-
return false;
|
|
161
|
-
};
|
|
162
|
-
const bodyReturnsJsx$1 = (body) => {
|
|
163
|
-
if (body.type !== _typescript_eslint_utils.AST_NODE_TYPES.BlockStatement) return returnsJsx$1(body);
|
|
164
|
-
return body.body.some((stmt) => stmt.type === _typescript_eslint_utils.AST_NODE_TYPES.ReturnStatement && stmt.argument !== null && returnsJsx$1(stmt.argument));
|
|
165
|
-
};
|
|
166
|
-
const isComponentFunction$1 = (init) => {
|
|
167
|
-
if (init.type === _typescript_eslint_utils.AST_NODE_TYPES.ArrowFunctionExpression || init.type === _typescript_eslint_utils.AST_NODE_TYPES.FunctionExpression) return bodyReturnsJsx$1(init.body);
|
|
168
|
-
if (init.type === _typescript_eslint_utils.AST_NODE_TYPES.CallExpression) {
|
|
169
|
-
const { callee } = init;
|
|
170
|
-
if (callee.type === _typescript_eslint_utils.AST_NODE_TYPES.Identifier && REACT_WRAPPERS.includes(callee.name)) return true;
|
|
171
|
-
if (callee.type === _typescript_eslint_utils.AST_NODE_TYPES.MemberExpression && callee.object.type === _typescript_eslint_utils.AST_NODE_TYPES.Identifier && callee.object.name === "React" && callee.property.type === _typescript_eslint_utils.AST_NODE_TYPES.Identifier && REACT_WRAPPERS.includes(callee.property.name)) return true;
|
|
172
|
-
}
|
|
173
|
-
return false;
|
|
174
|
-
};
|
|
175
|
-
const isGlobalScope$2 = (node) => {
|
|
176
|
-
const declaration = node.parent;
|
|
177
|
-
if (!declaration || declaration.type !== _typescript_eslint_utils.AST_NODE_TYPES.VariableDeclaration) return false;
|
|
178
|
-
const { parent } = declaration;
|
|
179
|
-
if (parent.type === _typescript_eslint_utils.AST_NODE_TYPES.Program) return true;
|
|
180
|
-
if (parent.type === _typescript_eslint_utils.AST_NODE_TYPES.ExportNamedDeclaration && parent.parent?.type === _typescript_eslint_utils.AST_NODE_TYPES.Program) return true;
|
|
181
|
-
return false;
|
|
182
|
-
};
|
|
183
|
-
const isStaticValue$1 = (init) => {
|
|
184
|
-
if (init.type === _typescript_eslint_utils.AST_NODE_TYPES.Literal) return true;
|
|
185
|
-
if (init.type === _typescript_eslint_utils.AST_NODE_TYPES.UnaryExpression && init.argument.type === _typescript_eslint_utils.AST_NODE_TYPES.Literal) return true;
|
|
186
|
-
if (init.type === _typescript_eslint_utils.AST_NODE_TYPES.TemplateLiteral && init.expressions.length === 0) return true;
|
|
187
|
-
if (init.type === _typescript_eslint_utils.AST_NODE_TYPES.ArrayExpression) return init.elements.every((el) => el !== null && el.type !== _typescript_eslint_utils.AST_NODE_TYPES.SpreadElement && isStaticValue$1(el));
|
|
188
|
-
if (init.type === _typescript_eslint_utils.AST_NODE_TYPES.ObjectExpression) return init.properties.every((prop) => prop.type === _typescript_eslint_utils.AST_NODE_TYPES.Property && isStaticValue$1(prop.value));
|
|
189
|
-
if (init.type === _typescript_eslint_utils.AST_NODE_TYPES.TSAsExpression && init.typeAnnotation.type === _typescript_eslint_utils.AST_NODE_TYPES.TSTypeReference && init.typeAnnotation.typeName.type === _typescript_eslint_utils.AST_NODE_TYPES.Identifier && init.typeAnnotation.typeName.name === "const") return true;
|
|
190
|
-
return false;
|
|
191
|
-
};
|
|
192
|
-
const enforceCamelCase = createRule$30({
|
|
193
|
-
name: "enforce-camel-case",
|
|
194
|
-
meta: {
|
|
195
|
-
type: "suggestion",
|
|
196
|
-
docs: { description: "Enforce camelCase for variables and functions, ban snake_case, and restrict PascalCase to React components" },
|
|
197
|
-
messages: {
|
|
198
|
-
noSnakeCase: "Variable '{{ name }}' should not use snake_case. Use camelCase instead.",
|
|
199
|
-
pascalCaseReserved: "Variable '{{ name }}' uses PascalCase but is not a React component. PascalCase is reserved for components."
|
|
200
|
-
},
|
|
201
|
-
schema: []
|
|
202
|
-
},
|
|
203
|
-
defaultOptions: [],
|
|
204
|
-
create(context) {
|
|
205
|
-
return {
|
|
206
|
-
VariableDeclarator(node) {
|
|
207
|
-
if (node.id.type !== _typescript_eslint_utils.AST_NODE_TYPES.Identifier) return;
|
|
208
|
-
const { name } = node.id;
|
|
209
|
-
if (SNAKE_CASE_REGEX$2.test(name)) {
|
|
210
|
-
if (node.parent.kind === "const" && isGlobalScope$2(node) && node.init && isStaticValue$1(node.init)) return;
|
|
211
|
-
context.report({
|
|
212
|
-
node: node.id,
|
|
213
|
-
messageId: "noSnakeCase",
|
|
214
|
-
data: { name }
|
|
215
|
-
});
|
|
216
|
-
return;
|
|
217
|
-
}
|
|
218
|
-
if (!node.init || !PASCAL_CASE_REGEX.test(name)) return;
|
|
219
|
-
if (isComponentFunction$1(node.init)) return;
|
|
220
|
-
if (node.init.type !== _typescript_eslint_utils.AST_NODE_TYPES.ArrowFunctionExpression && node.init.type !== _typescript_eslint_utils.AST_NODE_TYPES.FunctionExpression && node.init.type !== _typescript_eslint_utils.AST_NODE_TYPES.CallExpression) return;
|
|
221
|
-
context.report({
|
|
222
|
-
node: node.id,
|
|
223
|
-
messageId: "pascalCaseReserved",
|
|
224
|
-
data: { name }
|
|
225
|
-
});
|
|
226
|
-
},
|
|
227
|
-
FunctionDeclaration(node) {
|
|
228
|
-
if (!node.id) return;
|
|
229
|
-
const { name } = node.id;
|
|
230
|
-
if (SNAKE_CASE_REGEX$2.test(name)) context.report({
|
|
231
|
-
node: node.id,
|
|
232
|
-
messageId: "noSnakeCase",
|
|
233
|
-
data: { name }
|
|
234
|
-
});
|
|
235
|
-
}
|
|
236
|
-
};
|
|
237
|
-
}
|
|
238
|
-
});
|
|
239
|
-
//#endregion
|
|
240
147
|
//#region src/utils.ts
|
|
241
148
|
const getFileExtension = (filename) => (0, node_path.extname)(filename).slice(1);
|
|
242
149
|
const getBaseName = (filename) => (0, node_path.basename)(filename, (0, node_path.extname)(filename));
|
|
@@ -250,9 +157,9 @@ const isConfigFile = (filename) => {
|
|
|
250
157
|
};
|
|
251
158
|
//#endregion
|
|
252
159
|
//#region src/rules/enforce-constant-case.ts
|
|
253
|
-
const createRule$
|
|
254
|
-
const SCREAMING_SNAKE_CASE_REGEX$
|
|
255
|
-
const SNAKE_CASE_REGEX
|
|
160
|
+
const createRule$25 = _typescript_eslint_utils.ESLintUtils.RuleCreator((name) => `https://github.com/next-friday/eslint-plugin-nextfriday/blob/main/docs/rules/${name.replaceAll("-", "_").toUpperCase()}.md`);
|
|
161
|
+
const SCREAMING_SNAKE_CASE_REGEX$1 = /^[A-Z][A-Z0-9]*(?:_[A-Z0-9]+)*$/;
|
|
162
|
+
const SNAKE_CASE_REGEX = /^[a-z]+_[a-z0-9_]*$/;
|
|
256
163
|
const toScreamingSnakeCase = (str) => str.replace(/([a-z])([A-Z])/g, "$1_$2").replace(/([A-Z])([A-Z][a-z])/g, "$1_$2").toUpperCase();
|
|
257
164
|
const isMagicLiteral = (init) => {
|
|
258
165
|
if (init.type === _typescript_eslint_utils.AST_NODE_TYPES.Literal) return typeof init.value === "string" || typeof init.value === "number";
|
|
@@ -268,7 +175,7 @@ const isGlobalScope$1 = (node) => {
|
|
|
268
175
|
if (parent.type === _typescript_eslint_utils.AST_NODE_TYPES.ExportNamedDeclaration && parent.parent?.type === _typescript_eslint_utils.AST_NODE_TYPES.Program) return true;
|
|
269
176
|
return false;
|
|
270
177
|
};
|
|
271
|
-
const enforceConstantCase = createRule$
|
|
178
|
+
const enforceConstantCase = createRule$25({
|
|
272
179
|
name: "enforce-constant-case",
|
|
273
180
|
meta: {
|
|
274
181
|
type: "suggestion",
|
|
@@ -288,7 +195,7 @@ const enforceConstantCase = createRule$29({
|
|
|
288
195
|
if (declarator.id.type !== _typescript_eslint_utils.AST_NODE_TYPES.Identifier || !declarator.init) return;
|
|
289
196
|
if (!isMagicLiteral(declarator.init)) return;
|
|
290
197
|
const { name } = declarator.id;
|
|
291
|
-
if (SNAKE_CASE_REGEX
|
|
198
|
+
if (SNAKE_CASE_REGEX.test(name)) {
|
|
292
199
|
context.report({
|
|
293
200
|
node: declarator.id,
|
|
294
201
|
messageId: "noSnakeCase",
|
|
@@ -299,7 +206,7 @@ const enforceConstantCase = createRule$29({
|
|
|
299
206
|
});
|
|
300
207
|
return;
|
|
301
208
|
}
|
|
302
|
-
if (!SCREAMING_SNAKE_CASE_REGEX$
|
|
209
|
+
if (!SCREAMING_SNAKE_CASE_REGEX$1.test(name)) context.report({
|
|
303
210
|
node: declarator.id,
|
|
304
211
|
messageId: "useScreamingSnakeCase",
|
|
305
212
|
data: {
|
|
@@ -391,44 +298,6 @@ const enforceHookNaming = _typescript_eslint_utils.ESLintUtils.RuleCreator((name
|
|
|
391
298
|
}
|
|
392
299
|
});
|
|
393
300
|
//#endregion
|
|
394
|
-
//#region src/rules/enforce-property-case.ts
|
|
395
|
-
const createRule$28 = _typescript_eslint_utils.ESLintUtils.RuleCreator((name) => `https://github.com/next-friday/eslint-plugin-nextfriday/blob/main/docs/rules/${name.replaceAll("-", "_").toUpperCase()}.md`);
|
|
396
|
-
const SNAKE_CASE_REGEX = /^[a-z]+_[a-z0-9_]*$/;
|
|
397
|
-
const SCREAMING_SNAKE_CASE_REGEX$1 = /^[A-Z][A-Z0-9]*(?:_[A-Z0-9]+)*$/;
|
|
398
|
-
const isInsideAsConst = (node) => {
|
|
399
|
-
const { parent } = node;
|
|
400
|
-
if (parent.type === _typescript_eslint_utils.AST_NODE_TYPES.TSAsExpression && parent.typeAnnotation.type === _typescript_eslint_utils.AST_NODE_TYPES.TSTypeReference && parent.typeAnnotation.typeName.type === _typescript_eslint_utils.AST_NODE_TYPES.Identifier && parent.typeAnnotation.typeName.name === "const") return true;
|
|
401
|
-
if (parent.type === _typescript_eslint_utils.AST_NODE_TYPES.ArrayExpression) {
|
|
402
|
-
const grandparent = parent.parent;
|
|
403
|
-
if (grandparent?.type === _typescript_eslint_utils.AST_NODE_TYPES.TSAsExpression && grandparent.typeAnnotation.type === _typescript_eslint_utils.AST_NODE_TYPES.TSTypeReference && grandparent.typeAnnotation.typeName.type === _typescript_eslint_utils.AST_NODE_TYPES.Identifier && grandparent.typeAnnotation.typeName.name === "const") return true;
|
|
404
|
-
}
|
|
405
|
-
return false;
|
|
406
|
-
};
|
|
407
|
-
const enforcePropertyCase = createRule$28({
|
|
408
|
-
name: "enforce-property-case",
|
|
409
|
-
meta: {
|
|
410
|
-
type: "suggestion",
|
|
411
|
-
docs: { description: "Enforce camelCase for unquoted object property keys" },
|
|
412
|
-
messages: { useCamelCase: "Property '{{ name }}' should use camelCase. Use camelCase for object properties, or wrap in quotes if required by an API." },
|
|
413
|
-
schema: []
|
|
414
|
-
},
|
|
415
|
-
defaultOptions: [],
|
|
416
|
-
create(context) {
|
|
417
|
-
return { Property(node) {
|
|
418
|
-
if (node.parent.type !== _typescript_eslint_utils.AST_NODE_TYPES.ObjectExpression) return;
|
|
419
|
-
if (isInsideAsConst(node.parent)) return;
|
|
420
|
-
if (node.computed) return;
|
|
421
|
-
if (node.key.type !== _typescript_eslint_utils.AST_NODE_TYPES.Identifier) return;
|
|
422
|
-
const { name } = node.key;
|
|
423
|
-
if (SNAKE_CASE_REGEX.test(name) || SCREAMING_SNAKE_CASE_REGEX$1.test(name)) context.report({
|
|
424
|
-
node: node.key,
|
|
425
|
-
messageId: "useCamelCase",
|
|
426
|
-
data: { name }
|
|
427
|
-
});
|
|
428
|
-
} };
|
|
429
|
-
}
|
|
430
|
-
});
|
|
431
|
-
//#endregion
|
|
432
301
|
//#region src/rules/enforce-props-suffix.ts
|
|
433
302
|
const enforcePropsSuffix = _typescript_eslint_utils.ESLintUtils.RuleCreator((name) => `https://github.com/next-friday/eslint-plugin-nextfriday/blob/main/docs/rules/${name.replaceAll("-", "_").toUpperCase()}.md`)({
|
|
434
303
|
name: "enforce-props-suffix",
|
|
@@ -537,7 +406,7 @@ const enforceReadonlyComponentProps = _typescript_eslint_utils.ESLintUtils.RuleC
|
|
|
537
406
|
});
|
|
538
407
|
//#endregion
|
|
539
408
|
//#region src/rules/enforce-render-naming.ts
|
|
540
|
-
const createRule$
|
|
409
|
+
const createRule$24 = _typescript_eslint_utils.ESLintUtils.RuleCreator((name) => `https://github.com/next-friday/eslint-plugin-nextfriday/blob/main/docs/rules/${name.replaceAll("-", "_").toUpperCase()}.md`);
|
|
541
410
|
const ARRAY_RETURNING_METHODS = new Set([
|
|
542
411
|
"map",
|
|
543
412
|
"flatMap",
|
|
@@ -586,7 +455,7 @@ function isComponentFunction(node) {
|
|
|
586
455
|
if (parent?.type === _typescript_eslint_utils.AST_NODE_TYPES.VariableDeclarator && parent.id.type === _typescript_eslint_utils.AST_NODE_TYPES.Identifier && isPascalCase$1(parent.id.name)) return true;
|
|
587
456
|
return false;
|
|
588
457
|
}
|
|
589
|
-
const enforceRenderNaming = createRule$
|
|
458
|
+
const enforceRenderNaming = createRule$24({
|
|
590
459
|
name: "enforce-render-naming",
|
|
591
460
|
meta: {
|
|
592
461
|
type: "problem",
|
|
@@ -638,7 +507,7 @@ const enforceRenderNaming = createRule$27({
|
|
|
638
507
|
});
|
|
639
508
|
//#endregion
|
|
640
509
|
//#region src/rules/enforce-service-naming.ts
|
|
641
|
-
const createRule$
|
|
510
|
+
const createRule$23 = _typescript_eslint_utils.ESLintUtils.RuleCreator((name) => `https://github.com/next-friday/eslint-plugin-nextfriday/blob/main/docs/rules/${name.replaceAll("-", "_").toUpperCase()}.md`);
|
|
642
511
|
const BANNED_PREFIXES = {
|
|
643
512
|
delete: ["remove", "archive"],
|
|
644
513
|
do: ["submit", "process"],
|
|
@@ -649,7 +518,7 @@ const BANNED_PREFIXES = {
|
|
|
649
518
|
"patch"
|
|
650
519
|
]
|
|
651
520
|
};
|
|
652
|
-
const enforceServiceNaming = createRule$
|
|
521
|
+
const enforceServiceNaming = createRule$23({
|
|
653
522
|
name: "enforce-service-naming",
|
|
654
523
|
meta: {
|
|
655
524
|
type: "suggestion",
|
|
@@ -687,7 +556,7 @@ const enforceServiceNaming = createRule$26({
|
|
|
687
556
|
});
|
|
688
557
|
//#endregion
|
|
689
558
|
//#region src/rules/enforce-test-filename.ts
|
|
690
|
-
const createRule$
|
|
559
|
+
const createRule$22 = _typescript_eslint_utils.ESLintUtils.RuleCreator((name) => `https://github.com/next-friday/eslint-plugin-nextfriday/blob/main/docs/rules/${name.replaceAll("-", "_").toUpperCase()}.md`);
|
|
691
560
|
const TEST_GLOBALS = new Set([
|
|
692
561
|
"describe",
|
|
693
562
|
"it",
|
|
@@ -697,7 +566,7 @@ const TEST_GLOBALS = new Set([
|
|
|
697
566
|
"afterEach",
|
|
698
567
|
"afterAll"
|
|
699
568
|
]);
|
|
700
|
-
const enforceTestFilename = createRule$
|
|
569
|
+
const enforceTestFilename = createRule$22({
|
|
701
570
|
name: "enforce-test-filename",
|
|
702
571
|
meta: {
|
|
703
572
|
type: "suggestion",
|
|
@@ -777,7 +646,7 @@ const enforceSortedDestructuring = _typescript_eslint_utils.ESLintUtils.RuleCrea
|
|
|
777
646
|
});
|
|
778
647
|
//#endregion
|
|
779
648
|
//#region src/rules/enforce-type-declaration-order.ts
|
|
780
|
-
const createRule$
|
|
649
|
+
const createRule$21 = _typescript_eslint_utils.ESLintUtils.RuleCreator((name) => `https://github.com/next-friday/eslint-plugin-nextfriday/blob/main/docs/rules/${name.replaceAll("-", "_").toUpperCase()}.md`);
|
|
781
650
|
function getTypeDeclarationName(node) {
|
|
782
651
|
if (node.type === _typescript_eslint_utils.AST_NODE_TYPES.TSInterfaceDeclaration && node.id.type === _typescript_eslint_utils.AST_NODE_TYPES.Identifier) return {
|
|
783
652
|
name: node.id.name,
|
|
@@ -789,7 +658,7 @@ function getTypeDeclarationName(node) {
|
|
|
789
658
|
};
|
|
790
659
|
return null;
|
|
791
660
|
}
|
|
792
|
-
const enforceTypeDeclarationOrder = createRule$
|
|
661
|
+
const enforceTypeDeclarationOrder = createRule$21({
|
|
793
662
|
name: "enforce-type-declaration-order",
|
|
794
663
|
meta: {
|
|
795
664
|
type: "suggestion",
|
|
@@ -844,7 +713,7 @@ const enforceTypeDeclarationOrder = createRule$24({
|
|
|
844
713
|
});
|
|
845
714
|
//#endregion
|
|
846
715
|
//#region src/rules/index-export-only.ts
|
|
847
|
-
const createRule$
|
|
716
|
+
const createRule$20 = _typescript_eslint_utils.ESLintUtils.RuleCreator((name) => `https://github.com/next-friday/eslint-plugin-nextfriday/blob/main/docs/rules/${name.replaceAll("-", "_").toUpperCase()}.md`);
|
|
848
717
|
const isIndexFile = (filename) => getBaseName(filename) === "index";
|
|
849
718
|
const isAllowedExportNamed = (node) => {
|
|
850
719
|
if (!node.declaration) return true;
|
|
@@ -858,12 +727,16 @@ const isAllowedTopLevel = (node) => {
|
|
|
858
727
|
case _typescript_eslint_utils.AST_NODE_TYPES.TSTypeAliasDeclaration:
|
|
859
728
|
case _typescript_eslint_utils.AST_NODE_TYPES.TSInterfaceDeclaration:
|
|
860
729
|
case _typescript_eslint_utils.AST_NODE_TYPES.TSImportEqualsDeclaration: return true;
|
|
730
|
+
case _typescript_eslint_utils.AST_NODE_TYPES.ExpressionStatement: {
|
|
731
|
+
const { expression } = node;
|
|
732
|
+
return expression.type === _typescript_eslint_utils.AST_NODE_TYPES.Literal && typeof expression.value === "string";
|
|
733
|
+
}
|
|
861
734
|
case _typescript_eslint_utils.AST_NODE_TYPES.ExportNamedDeclaration: return isAllowedExportNamed(node);
|
|
862
735
|
case _typescript_eslint_utils.AST_NODE_TYPES.ExportDefaultDeclaration: return isAllowedExportDefault(node);
|
|
863
736
|
default: return false;
|
|
864
737
|
}
|
|
865
738
|
};
|
|
866
|
-
const indexExportOnly = createRule$
|
|
739
|
+
const indexExportOnly = createRule$20({
|
|
867
740
|
name: "index-export-only",
|
|
868
741
|
meta: {
|
|
869
742
|
type: "suggestion",
|
|
@@ -937,7 +810,7 @@ const jsxNewlineBetweenElements = _typescript_eslint_utils.ESLintUtils.RuleCreat
|
|
|
937
810
|
});
|
|
938
811
|
//#endregion
|
|
939
812
|
//#region src/rules/jsx-no-data-array.ts
|
|
940
|
-
const createRule$
|
|
813
|
+
const createRule$19 = _typescript_eslint_utils.ESLintUtils.RuleCreator((name) => `https://github.com/next-friday/eslint-plugin-nextfriday/blob/main/docs/rules/${name.replaceAll("-", "_").toUpperCase()}.md`);
|
|
941
814
|
function isObjectLikeElement(node) {
|
|
942
815
|
if (!node) return false;
|
|
943
816
|
if (node.type === _typescript_eslint_utils.AST_NODE_TYPES.ObjectExpression) return true;
|
|
@@ -950,7 +823,7 @@ function getArrayInitializer(init) {
|
|
|
950
823
|
if (init.type === _typescript_eslint_utils.AST_NODE_TYPES.TSAsExpression || init.type === _typescript_eslint_utils.AST_NODE_TYPES.TSSatisfiesExpression) return getArrayInitializer(init.expression);
|
|
951
824
|
return null;
|
|
952
825
|
}
|
|
953
|
-
const jsxNoDataArray = createRule$
|
|
826
|
+
const jsxNoDataArray = createRule$19({
|
|
954
827
|
name: "jsx-no-data-array",
|
|
955
828
|
meta: {
|
|
956
829
|
type: "problem",
|
|
@@ -991,7 +864,7 @@ const jsxNoDataArray = createRule$22({
|
|
|
991
864
|
});
|
|
992
865
|
//#endregion
|
|
993
866
|
//#region src/rules/jsx-no-data-object.ts
|
|
994
|
-
const createRule$
|
|
867
|
+
const createRule$18 = _typescript_eslint_utils.ESLintUtils.RuleCreator((name) => `https://github.com/next-friday/eslint-plugin-nextfriday/blob/main/docs/rules/${name.replaceAll("-", "_").toUpperCase()}.md`);
|
|
995
868
|
function unwrapAssertion(node) {
|
|
996
869
|
if (!node) return null;
|
|
997
870
|
if (node.type === _typescript_eslint_utils.AST_NODE_TYPES.TSAsExpression || node.type === _typescript_eslint_utils.AST_NODE_TYPES.TSSatisfiesExpression) return unwrapAssertion(node.expression);
|
|
@@ -1021,7 +894,7 @@ function getObjectInitializer(init) {
|
|
|
1021
894
|
if (unwrapped.type === _typescript_eslint_utils.AST_NODE_TYPES.ObjectExpression) return unwrapped;
|
|
1022
895
|
return null;
|
|
1023
896
|
}
|
|
1024
|
-
const jsxNoDataObject = createRule$
|
|
897
|
+
const jsxNoDataObject = createRule$18({
|
|
1025
898
|
name: "jsx-no-data-object",
|
|
1026
899
|
meta: {
|
|
1027
900
|
type: "problem",
|
|
@@ -1074,14 +947,14 @@ const jsxNoInlineObjectProp = _typescript_eslint_utils.ESLintUtils.RuleCreator((
|
|
|
1074
947
|
});
|
|
1075
948
|
//#endregion
|
|
1076
949
|
//#region src/rules/jsx-no-newline-single-line-elements.ts
|
|
1077
|
-
const createRule$
|
|
950
|
+
const createRule$17 = _typescript_eslint_utils.ESLintUtils.RuleCreator((name) => `https://github.com/next-friday/eslint-plugin-nextfriday/blob/main/docs/rules/${name.replaceAll("-", "_").toUpperCase()}.md`);
|
|
1078
951
|
function isJSXElementOrFragment(node) {
|
|
1079
952
|
return node.type === _typescript_eslint_utils.AST_NODE_TYPES.JSXElement || node.type === _typescript_eslint_utils.AST_NODE_TYPES.JSXFragment;
|
|
1080
953
|
}
|
|
1081
954
|
function isSingleLine(node) {
|
|
1082
955
|
return node.loc.start.line === node.loc.end.line;
|
|
1083
956
|
}
|
|
1084
|
-
const jsxNoNewlineSingleLineElements = createRule$
|
|
957
|
+
const jsxNoNewlineSingleLineElements = createRule$17({
|
|
1085
958
|
name: "jsx-no-newline-single-line-elements",
|
|
1086
959
|
meta: {
|
|
1087
960
|
type: "layout",
|
|
@@ -1180,7 +1053,7 @@ const jsxNoNonComponentFunction = _typescript_eslint_utils.ESLintUtils.RuleCreat
|
|
|
1180
1053
|
});
|
|
1181
1054
|
//#endregion
|
|
1182
1055
|
//#region src/rules/jsx-no-sub-interface.ts
|
|
1183
|
-
const createRule$
|
|
1056
|
+
const createRule$16 = _typescript_eslint_utils.ESLintUtils.RuleCreator((name) => `https://github.com/next-friday/eslint-plugin-nextfriday/blob/main/docs/rules/${name.replaceAll("-", "_").toUpperCase()}.md`);
|
|
1184
1057
|
const PROPS_WRAPPER_NAMES = new Set([
|
|
1185
1058
|
"Readonly",
|
|
1186
1059
|
"Required",
|
|
@@ -1212,7 +1085,7 @@ function getDeclarationFromExportWrapper(node) {
|
|
|
1212
1085
|
if (node.type === _typescript_eslint_utils.AST_NODE_TYPES.ExportDefaultDeclaration) return node.declaration;
|
|
1213
1086
|
return node;
|
|
1214
1087
|
}
|
|
1215
|
-
const jsxNoSubInterface = createRule$
|
|
1088
|
+
const jsxNoSubInterface = createRule$16({
|
|
1216
1089
|
name: "jsx-no-sub-interface",
|
|
1217
1090
|
meta: {
|
|
1218
1091
|
type: "problem",
|
|
@@ -1279,13 +1152,13 @@ const jsxNoSubInterface = createRule$19({
|
|
|
1279
1152
|
});
|
|
1280
1153
|
//#endregion
|
|
1281
1154
|
//#region src/rules/jsx-no-ternary-null.ts
|
|
1282
|
-
const createRule$
|
|
1155
|
+
const createRule$15 = _typescript_eslint_utils.ESLintUtils.RuleCreator((name) => `https://github.com/next-friday/eslint-plugin-nextfriday/blob/main/docs/rules/${name.replaceAll("-", "_").toUpperCase()}.md`);
|
|
1283
1156
|
function isNullOrUndefined(node) {
|
|
1284
1157
|
if (node.type === _typescript_eslint_utils.AST_NODE_TYPES.Literal && node.value === null) return true;
|
|
1285
1158
|
if (node.type === _typescript_eslint_utils.AST_NODE_TYPES.Identifier && node.name === "undefined") return true;
|
|
1286
1159
|
return false;
|
|
1287
1160
|
}
|
|
1288
|
-
const jsxNoTernaryNull = createRule$
|
|
1161
|
+
const jsxNoTernaryNull = createRule$15({
|
|
1289
1162
|
name: "jsx-no-ternary-null",
|
|
1290
1163
|
meta: {
|
|
1291
1164
|
type: "suggestion",
|
|
@@ -1452,7 +1325,7 @@ const jsxSimpleProps = _typescript_eslint_utils.ESLintUtils.RuleCreator((name) =
|
|
|
1452
1325
|
});
|
|
1453
1326
|
//#endregion
|
|
1454
1327
|
//#region src/rules/jsx-sort-props.ts
|
|
1455
|
-
const createRule$
|
|
1328
|
+
const createRule$14 = _typescript_eslint_utils.ESLintUtils.RuleCreator((name) => `https://github.com/next-friday/eslint-plugin-nextfriday/blob/main/docs/rules/${name.replaceAll("-", "_").toUpperCase()}.md`);
|
|
1456
1329
|
const TYPE_GROUP = {
|
|
1457
1330
|
STRING: 1,
|
|
1458
1331
|
HYPHENATED_STRING: 2,
|
|
@@ -1535,7 +1408,7 @@ function getSegments(attributes) {
|
|
|
1535
1408
|
if (current.length > 0) result.push(current);
|
|
1536
1409
|
return result;
|
|
1537
1410
|
}
|
|
1538
|
-
const jsxSortProps = createRule$
|
|
1411
|
+
const jsxSortProps = createRule$14({
|
|
1539
1412
|
name: "jsx-sort-props",
|
|
1540
1413
|
meta: {
|
|
1541
1414
|
type: "suggestion",
|
|
@@ -1590,7 +1463,7 @@ const jsxSpreadPropsLast = _typescript_eslint_utils.ESLintUtils.RuleCreator((nam
|
|
|
1590
1463
|
});
|
|
1591
1464
|
//#endregion
|
|
1592
1465
|
//#region src/rules/newline-after-multiline-block.ts
|
|
1593
|
-
const createRule$
|
|
1466
|
+
const createRule$13 = _typescript_eslint_utils.ESLintUtils.RuleCreator((name) => `https://github.com/next-friday/eslint-plugin-nextfriday/blob/main/docs/rules/${name.replaceAll("-", "_").toUpperCase()}.md`);
|
|
1594
1467
|
function isImportDeclaration(node) {
|
|
1595
1468
|
return node.type === _typescript_eslint_utils.AST_NODE_TYPES.ImportDeclaration;
|
|
1596
1469
|
}
|
|
@@ -1615,7 +1488,7 @@ function checkStatements(statements, context) {
|
|
|
1615
1488
|
});
|
|
1616
1489
|
});
|
|
1617
1490
|
}
|
|
1618
|
-
const newlineAfterMultilineBlock = createRule$
|
|
1491
|
+
const newlineAfterMultilineBlock = createRule$13({
|
|
1619
1492
|
name: "newline-after-multiline-block",
|
|
1620
1493
|
meta: {
|
|
1621
1494
|
type: "layout",
|
|
@@ -1801,12 +1674,12 @@ const noEnvFallback = _typescript_eslint_utils.ESLintUtils.RuleCreator((name) =>
|
|
|
1801
1674
|
});
|
|
1802
1675
|
//#endregion
|
|
1803
1676
|
//#region src/rules/no-ghost-wrapper.ts
|
|
1804
|
-
const createRule$
|
|
1677
|
+
const createRule$12 = _typescript_eslint_utils.ESLintUtils.RuleCreator((name) => `https://github.com/next-friday/eslint-plugin-nextfriday/blob/main/docs/rules/${name.replaceAll("-", "_").toUpperCase()}.md`);
|
|
1805
1678
|
const GHOST_TAGS = new Set(["div", "span"]);
|
|
1806
1679
|
function isKeyAttribute(attribute) {
|
|
1807
1680
|
return attribute.type === _typescript_eslint_utils.AST_NODE_TYPES.JSXAttribute && attribute.name.type === _typescript_eslint_utils.AST_NODE_TYPES.JSXIdentifier && attribute.name.name === "key";
|
|
1808
1681
|
}
|
|
1809
|
-
const noGhostWrapper = createRule$
|
|
1682
|
+
const noGhostWrapper = createRule$12({
|
|
1810
1683
|
name: "no-ghost-wrapper",
|
|
1811
1684
|
meta: {
|
|
1812
1685
|
type: "problem",
|
|
@@ -1903,82 +1776,8 @@ const noHelperFunctionInTest = _typescript_eslint_utils.ESLintUtils.RuleCreator(
|
|
|
1903
1776
|
}
|
|
1904
1777
|
});
|
|
1905
1778
|
//#endregion
|
|
1906
|
-
//#region src/rules/no-inline-default-export.ts
|
|
1907
|
-
const noInlineDefaultExport = _typescript_eslint_utils.ESLintUtils.RuleCreator((name) => `https://github.com/next-friday/eslint-plugin-nextfriday/blob/main/docs/rules/${name.replaceAll("-", "_").toUpperCase()}.md`)({
|
|
1908
|
-
name: "no-inline-default-export",
|
|
1909
|
-
meta: {
|
|
1910
|
-
type: "suggestion",
|
|
1911
|
-
docs: { description: "Disallow inline exports. Prefer declaring first, then exporting separately." },
|
|
1912
|
-
messages: {
|
|
1913
|
-
noInlineDefaultExport: "Avoid inline default export. Declare the {{type}} first, then export it separately: `export default {{name}};`",
|
|
1914
|
-
noAnonymousDefaultExport: "Avoid anonymous default export. Declare a named {{type}} first, then export it separately.",
|
|
1915
|
-
noInlineNamedExport: "Avoid inline named export. Declare the {{type}} first, then export it separately: `export { {{name}} };`"
|
|
1916
|
-
},
|
|
1917
|
-
schema: []
|
|
1918
|
-
},
|
|
1919
|
-
defaultOptions: [],
|
|
1920
|
-
create(context) {
|
|
1921
|
-
return {
|
|
1922
|
-
ExportDefaultDeclaration(node) {
|
|
1923
|
-
const { declaration } = node;
|
|
1924
|
-
if (declaration.type === _typescript_eslint_utils.AST_NODE_TYPES.FunctionDeclaration) if (declaration.id) context.report({
|
|
1925
|
-
node,
|
|
1926
|
-
messageId: "noInlineDefaultExport",
|
|
1927
|
-
data: {
|
|
1928
|
-
type: "function",
|
|
1929
|
-
name: declaration.id.name
|
|
1930
|
-
}
|
|
1931
|
-
});
|
|
1932
|
-
else context.report({
|
|
1933
|
-
node,
|
|
1934
|
-
messageId: "noAnonymousDefaultExport",
|
|
1935
|
-
data: { type: "function" }
|
|
1936
|
-
});
|
|
1937
|
-
if (declaration.type === _typescript_eslint_utils.AST_NODE_TYPES.ClassDeclaration) if (declaration.id) context.report({
|
|
1938
|
-
node,
|
|
1939
|
-
messageId: "noInlineDefaultExport",
|
|
1940
|
-
data: {
|
|
1941
|
-
type: "class",
|
|
1942
|
-
name: declaration.id.name
|
|
1943
|
-
}
|
|
1944
|
-
});
|
|
1945
|
-
else context.report({
|
|
1946
|
-
node,
|
|
1947
|
-
messageId: "noAnonymousDefaultExport",
|
|
1948
|
-
data: { type: "class" }
|
|
1949
|
-
});
|
|
1950
|
-
if (declaration.type === _typescript_eslint_utils.AST_NODE_TYPES.ArrowFunctionExpression || declaration.type === _typescript_eslint_utils.AST_NODE_TYPES.FunctionExpression) context.report({
|
|
1951
|
-
node,
|
|
1952
|
-
messageId: "noAnonymousDefaultExport",
|
|
1953
|
-
data: { type: "function" }
|
|
1954
|
-
});
|
|
1955
|
-
},
|
|
1956
|
-
ExportNamedDeclaration(node) {
|
|
1957
|
-
const { declaration } = node;
|
|
1958
|
-
if (!declaration) return;
|
|
1959
|
-
if (declaration.type === _typescript_eslint_utils.AST_NODE_TYPES.FunctionDeclaration && declaration.id) context.report({
|
|
1960
|
-
node,
|
|
1961
|
-
messageId: "noInlineNamedExport",
|
|
1962
|
-
data: {
|
|
1963
|
-
type: "function",
|
|
1964
|
-
name: declaration.id.name
|
|
1965
|
-
}
|
|
1966
|
-
});
|
|
1967
|
-
if (declaration.type === _typescript_eslint_utils.AST_NODE_TYPES.ClassDeclaration && declaration.id) context.report({
|
|
1968
|
-
node,
|
|
1969
|
-
messageId: "noInlineNamedExport",
|
|
1970
|
-
data: {
|
|
1971
|
-
type: "class",
|
|
1972
|
-
name: declaration.id.name
|
|
1973
|
-
}
|
|
1974
|
-
});
|
|
1975
|
-
}
|
|
1976
|
-
};
|
|
1977
|
-
}
|
|
1978
|
-
});
|
|
1979
|
-
//#endregion
|
|
1980
1779
|
//#region src/rules/no-inline-nested-object.ts
|
|
1981
|
-
const createRule$
|
|
1780
|
+
const createRule$11 = _typescript_eslint_utils.ESLintUtils.RuleCreator((name) => `https://github.com/next-friday/eslint-plugin-nextfriday/blob/main/docs/rules/${name.replaceAll("-", "_").toUpperCase()}.md`);
|
|
1982
1781
|
function isObjectOrArray(node) {
|
|
1983
1782
|
return node.type === _typescript_eslint_utils.AST_NODE_TYPES.ObjectExpression || node.type === _typescript_eslint_utils.AST_NODE_TYPES.ArrayExpression || node.type === _typescript_eslint_utils.AST_NODE_TYPES.TSAsExpression;
|
|
1984
1783
|
}
|
|
@@ -2000,7 +1799,7 @@ function containsNestedStructure(node) {
|
|
|
2000
1799
|
return isNestedStructure(el);
|
|
2001
1800
|
});
|
|
2002
1801
|
}
|
|
2003
|
-
const noInlineNestedObject = createRule$
|
|
1802
|
+
const noInlineNestedObject = createRule$11({
|
|
2004
1803
|
name: "no-inline-nested-object",
|
|
2005
1804
|
meta: {
|
|
2006
1805
|
type: "layout",
|
|
@@ -2042,13 +1841,13 @@ const noInlineNestedObject = createRule$14({
|
|
|
2042
1841
|
});
|
|
2043
1842
|
//#endregion
|
|
2044
1843
|
//#region src/rules/no-inline-return-properties.ts
|
|
2045
|
-
const createRule$
|
|
1844
|
+
const createRule$10 = _typescript_eslint_utils.ESLintUtils.RuleCreator((name) => `https://github.com/next-friday/eslint-plugin-nextfriday/blob/main/docs/rules/${name.replaceAll("-", "_").toUpperCase()}.md`);
|
|
2046
1845
|
const isShorthandProperty = (property) => {
|
|
2047
1846
|
if (property.type === _typescript_eslint_utils.AST_NODE_TYPES.SpreadElement) return true;
|
|
2048
1847
|
if (property.type !== _typescript_eslint_utils.AST_NODE_TYPES.Property) return false;
|
|
2049
1848
|
return property.shorthand;
|
|
2050
1849
|
};
|
|
2051
|
-
const noInlineReturnProperties = createRule$
|
|
1850
|
+
const noInlineReturnProperties = createRule$10({
|
|
2052
1851
|
name: "no-inline-return-properties",
|
|
2053
1852
|
meta: {
|
|
2054
1853
|
type: "suggestion",
|
|
@@ -2077,9 +1876,9 @@ const noInlineReturnProperties = createRule$13({
|
|
|
2077
1876
|
});
|
|
2078
1877
|
//#endregion
|
|
2079
1878
|
//#region src/rules/no-inline-type-import.ts
|
|
2080
|
-
const createRule$
|
|
1879
|
+
const createRule$9 = _typescript_eslint_utils.ESLintUtils.RuleCreator((name) => `https://github.com/next-friday/eslint-plugin-nextfriday/blob/main/docs/rules/${name.replaceAll("-", "_").toUpperCase()}.md`);
|
|
2081
1880
|
const isInlineTypeSpecifier = (specifier) => specifier.type === _typescript_eslint_utils.AST_NODE_TYPES.ImportSpecifier && specifier.importKind === "type";
|
|
2082
|
-
const noInlineTypeImport = createRule$
|
|
1881
|
+
const noInlineTypeImport = createRule$9({
|
|
2083
1882
|
name: "no-inline-type-import",
|
|
2084
1883
|
meta: {
|
|
2085
1884
|
type: "suggestion",
|
|
@@ -2121,7 +1920,7 @@ const noInlineTypeImport = createRule$12({
|
|
|
2121
1920
|
});
|
|
2122
1921
|
//#endregion
|
|
2123
1922
|
//#region src/rules/no-lazy-identifiers.ts
|
|
2124
|
-
const createRule$
|
|
1923
|
+
const createRule$8 = _typescript_eslint_utils.ESLintUtils.RuleCreator((name) => `https://github.com/next-friday/eslint-plugin-nextfriday/blob/main/docs/rules/${name.replaceAll("-", "_").toUpperCase()}.md`);
|
|
2125
1924
|
const KEYBOARD_ROWS = [
|
|
2126
1925
|
"qwertyuiop",
|
|
2127
1926
|
"asdfghjkl",
|
|
@@ -2152,7 +1951,7 @@ const isLazyIdentifier = (name) => {
|
|
|
2152
1951
|
if (hasKeyboardSequence(name)) return true;
|
|
2153
1952
|
return false;
|
|
2154
1953
|
};
|
|
2155
|
-
const noLazyIdentifiers = createRule$
|
|
1954
|
+
const noLazyIdentifiers = createRule$8({
|
|
2156
1955
|
name: "no-lazy-identifiers",
|
|
2157
1956
|
meta: {
|
|
2158
1957
|
type: "problem",
|
|
@@ -2271,7 +2070,7 @@ const noLogicInParams = _typescript_eslint_utils.ESLintUtils.RuleCreator((name)
|
|
|
2271
2070
|
});
|
|
2272
2071
|
//#endregion
|
|
2273
2072
|
//#region src/rules/no-misleading-constant-case.ts
|
|
2274
|
-
const createRule$
|
|
2073
|
+
const createRule$7 = _typescript_eslint_utils.ESLintUtils.RuleCreator((name) => `https://github.com/next-friday/eslint-plugin-nextfriday/blob/main/docs/rules/${name.replaceAll("-", "_").toUpperCase()}.md`);
|
|
2275
2074
|
const SCREAMING_SNAKE_CASE_REGEX = /^[A-Z][A-Z0-9]*(?:_[A-Z0-9]+)*$/;
|
|
2276
2075
|
const isAsConstAssertion = (node) => node.type === _typescript_eslint_utils.AST_NODE_TYPES.TSAsExpression && node.typeAnnotation.type === _typescript_eslint_utils.AST_NODE_TYPES.TSTypeReference && node.typeAnnotation.typeName.type === _typescript_eslint_utils.AST_NODE_TYPES.Identifier && node.typeAnnotation.typeName.name === "const";
|
|
2277
2076
|
const isStaticValue = (init) => {
|
|
@@ -2289,7 +2088,7 @@ const isGlobalScope = (node) => {
|
|
|
2289
2088
|
if (parent.type === _typescript_eslint_utils.AST_NODE_TYPES.ExportNamedDeclaration && parent.parent?.type === _typescript_eslint_utils.AST_NODE_TYPES.Program) return true;
|
|
2290
2089
|
return false;
|
|
2291
2090
|
};
|
|
2292
|
-
const noMisleadingConstantCase = createRule$
|
|
2091
|
+
const noMisleadingConstantCase = createRule$7({
|
|
2293
2092
|
name: "no-misleading-constant-case",
|
|
2294
2093
|
meta: {
|
|
2295
2094
|
type: "suggestion",
|
|
@@ -2377,82 +2176,6 @@ const noNestedInterfaceDeclaration = _typescript_eslint_utils.ESLintUtils.RuleCr
|
|
|
2377
2176
|
}
|
|
2378
2177
|
});
|
|
2379
2178
|
//#endregion
|
|
2380
|
-
//#region src/rules/no-nested-ternary.ts
|
|
2381
|
-
const noNestedTernary = _typescript_eslint_utils.ESLintUtils.RuleCreator((name) => `https://github.com/next-friday/eslint-plugin-nextfriday/blob/main/docs/rules/${name.replaceAll("-", "_").toUpperCase()}.md`)({
|
|
2382
|
-
name: "no-nested-ternary",
|
|
2383
|
-
meta: {
|
|
2384
|
-
type: "suggestion",
|
|
2385
|
-
docs: { description: "Disallow nested ternary expressions" },
|
|
2386
|
-
messages: { noNestedTernary: "Nested ternary expressions are not allowed. Use a function with early returns instead." },
|
|
2387
|
-
schema: []
|
|
2388
|
-
},
|
|
2389
|
-
defaultOptions: [],
|
|
2390
|
-
create(context) {
|
|
2391
|
-
return { ConditionalExpression(node) {
|
|
2392
|
-
const { consequent, alternate } = node;
|
|
2393
|
-
if (consequent.type === _typescript_eslint_utils.AST_NODE_TYPES.ConditionalExpression) context.report({
|
|
2394
|
-
node: consequent,
|
|
2395
|
-
messageId: "noNestedTernary"
|
|
2396
|
-
});
|
|
2397
|
-
if (alternate.type === _typescript_eslint_utils.AST_NODE_TYPES.ConditionalExpression) context.report({
|
|
2398
|
-
node: alternate,
|
|
2399
|
-
messageId: "noNestedTernary"
|
|
2400
|
-
});
|
|
2401
|
-
} };
|
|
2402
|
-
}
|
|
2403
|
-
});
|
|
2404
|
-
//#endregion
|
|
2405
|
-
//#region src/rules/no-redundant-fragment.ts
|
|
2406
|
-
const createRule$9 = _typescript_eslint_utils.ESLintUtils.RuleCreator((name) => `https://github.com/next-friday/eslint-plugin-nextfriday/blob/main/docs/rules/${name.replaceAll("-", "_").toUpperCase()}.md`);
|
|
2407
|
-
function isFragmentName(name) {
|
|
2408
|
-
if (name.type === _typescript_eslint_utils.AST_NODE_TYPES.JSXIdentifier && name.name === "Fragment") return true;
|
|
2409
|
-
if (name.type === _typescript_eslint_utils.AST_NODE_TYPES.JSXMemberExpression && name.object.type === _typescript_eslint_utils.AST_NODE_TYPES.JSXIdentifier && name.object.name === "React" && name.property.type === _typescript_eslint_utils.AST_NODE_TYPES.JSXIdentifier && name.property.name === "Fragment") return true;
|
|
2410
|
-
return false;
|
|
2411
|
-
}
|
|
2412
|
-
function hasKeyAttribute(attributes) {
|
|
2413
|
-
return attributes.some((attribute) => attribute.type === _typescript_eslint_utils.AST_NODE_TYPES.JSXAttribute && attribute.name.type === _typescript_eslint_utils.AST_NODE_TYPES.JSXIdentifier && attribute.name.name === "key");
|
|
2414
|
-
}
|
|
2415
|
-
function countMeaningfulChildren(children) {
|
|
2416
|
-
return children.filter((child) => {
|
|
2417
|
-
if (child.type === _typescript_eslint_utils.AST_NODE_TYPES.JSXText) return child.value.trim() !== "";
|
|
2418
|
-
return true;
|
|
2419
|
-
}).length;
|
|
2420
|
-
}
|
|
2421
|
-
const noRedundantFragment = createRule$9({
|
|
2422
|
-
name: "no-redundant-fragment",
|
|
2423
|
-
meta: {
|
|
2424
|
-
type: "problem",
|
|
2425
|
-
docs: { description: "Disallow Fragments that wrap zero or one child (unless a key prop is needed)" },
|
|
2426
|
-
schema: [],
|
|
2427
|
-
messages: { redundantFragment: "Fragment is redundant when wrapping {{ count }} child. Remove the Fragment or replace it with the child directly." }
|
|
2428
|
-
},
|
|
2429
|
-
defaultOptions: [],
|
|
2430
|
-
create(context) {
|
|
2431
|
-
if (!isJsxFile(context.filename)) return {};
|
|
2432
|
-
return {
|
|
2433
|
-
JSXFragment(node) {
|
|
2434
|
-
const count = countMeaningfulChildren(node.children);
|
|
2435
|
-
if (count <= 1) context.report({
|
|
2436
|
-
node,
|
|
2437
|
-
messageId: "redundantFragment",
|
|
2438
|
-
data: { count: String(count) }
|
|
2439
|
-
});
|
|
2440
|
-
},
|
|
2441
|
-
JSXElement(node) {
|
|
2442
|
-
const opening = node.openingElement;
|
|
2443
|
-
if (!isFragmentName(opening.name)) return;
|
|
2444
|
-
if (hasKeyAttribute(opening.attributes)) return;
|
|
2445
|
-
const count = countMeaningfulChildren(node.children);
|
|
2446
|
-
if (count <= 1) context.report({
|
|
2447
|
-
node,
|
|
2448
|
-
messageId: "redundantFragment",
|
|
2449
|
-
data: { count: String(count) }
|
|
2450
|
-
});
|
|
2451
|
-
}
|
|
2452
|
-
};
|
|
2453
|
-
}
|
|
2454
|
-
});
|
|
2455
|
-
//#endregion
|
|
2456
2179
|
//#region src/rules/no-relative-imports.ts
|
|
2457
2180
|
const noRelativeImports = _typescript_eslint_utils.ESLintUtils.RuleCreator((name) => `https://github.com/next-friday/eslint-plugin-nextfriday/blob/main/docs/rules/${name.replaceAll("-", "_").toUpperCase()}.md`)({
|
|
2458
2181
|
name: "no-relative-imports",
|
|
@@ -2487,88 +2210,6 @@ const noRelativeImports = _typescript_eslint_utils.ESLintUtils.RuleCreator((name
|
|
|
2487
2210
|
}
|
|
2488
2211
|
});
|
|
2489
2212
|
//#endregion
|
|
2490
|
-
//#region src/rules/no-single-char-variables.ts
|
|
2491
|
-
const createRule$8 = _typescript_eslint_utils.ESLintUtils.RuleCreator((name) => `https://github.com/next-friday/eslint-plugin-nextfriday/blob/main/docs/rules/${name.replaceAll("-", "_").toUpperCase()}.md`);
|
|
2492
|
-
const ALLOWED_IN_FOR_LOOPS = new Set([
|
|
2493
|
-
"i",
|
|
2494
|
-
"j",
|
|
2495
|
-
"k",
|
|
2496
|
-
"n"
|
|
2497
|
-
]);
|
|
2498
|
-
const ALLOWED_UNDERSCORE = "_";
|
|
2499
|
-
const isForLoopInit = (node) => {
|
|
2500
|
-
let current = node;
|
|
2501
|
-
while (current) {
|
|
2502
|
-
const parentNode = current.parent;
|
|
2503
|
-
if (!parentNode) return false;
|
|
2504
|
-
if (parentNode.type === _typescript_eslint_utils.AST_NODE_TYPES.ForStatement) {
|
|
2505
|
-
const { init } = parentNode;
|
|
2506
|
-
if (init && init === current) return true;
|
|
2507
|
-
}
|
|
2508
|
-
current = parentNode;
|
|
2509
|
-
}
|
|
2510
|
-
return false;
|
|
2511
|
-
};
|
|
2512
|
-
const isAllowedInContext = (name, node) => {
|
|
2513
|
-
if (name === ALLOWED_UNDERSCORE) return true;
|
|
2514
|
-
if (ALLOWED_IN_FOR_LOOPS.has(name) && isForLoopInit(node)) return true;
|
|
2515
|
-
return false;
|
|
2516
|
-
};
|
|
2517
|
-
const noSingleCharVariables = createRule$8({
|
|
2518
|
-
name: "no-single-char-variables",
|
|
2519
|
-
meta: {
|
|
2520
|
-
type: "suggestion",
|
|
2521
|
-
docs: { description: "Disallow single character variable and parameter names for better code readability" },
|
|
2522
|
-
messages: { noSingleChar: "Avoid single character variable name '{{name}}'. Use a descriptive name that clearly indicates the purpose." },
|
|
2523
|
-
schema: []
|
|
2524
|
-
},
|
|
2525
|
-
defaultOptions: [],
|
|
2526
|
-
create(context) {
|
|
2527
|
-
const checkIdentifier = (node, declarationNode) => {
|
|
2528
|
-
const { name } = node;
|
|
2529
|
-
if (name.length !== 1) return;
|
|
2530
|
-
if (isAllowedInContext(name, declarationNode)) return;
|
|
2531
|
-
context.report({
|
|
2532
|
-
node,
|
|
2533
|
-
messageId: "noSingleChar",
|
|
2534
|
-
data: { name }
|
|
2535
|
-
});
|
|
2536
|
-
};
|
|
2537
|
-
const checkPattern = (pattern, declarationNode) => {
|
|
2538
|
-
if (pattern.type === _typescript_eslint_utils.AST_NODE_TYPES.Identifier) checkIdentifier(pattern, declarationNode);
|
|
2539
|
-
else if (pattern.type === _typescript_eslint_utils.AST_NODE_TYPES.ObjectPattern) pattern.properties.forEach((prop) => {
|
|
2540
|
-
if (prop.type === _typescript_eslint_utils.AST_NODE_TYPES.Property && prop.value.type === _typescript_eslint_utils.AST_NODE_TYPES.Identifier) checkIdentifier(prop.value, declarationNode);
|
|
2541
|
-
else if (prop.type === _typescript_eslint_utils.AST_NODE_TYPES.RestElement && prop.argument.type === _typescript_eslint_utils.AST_NODE_TYPES.Identifier) checkIdentifier(prop.argument, declarationNode);
|
|
2542
|
-
});
|
|
2543
|
-
else if (pattern.type === _typescript_eslint_utils.AST_NODE_TYPES.ArrayPattern) pattern.elements.forEach((element) => {
|
|
2544
|
-
if (element?.type === _typescript_eslint_utils.AST_NODE_TYPES.Identifier) checkIdentifier(element, declarationNode);
|
|
2545
|
-
else if (element?.type === _typescript_eslint_utils.AST_NODE_TYPES.RestElement && element.argument.type === _typescript_eslint_utils.AST_NODE_TYPES.Identifier) checkIdentifier(element.argument, declarationNode);
|
|
2546
|
-
});
|
|
2547
|
-
else if (pattern.type === _typescript_eslint_utils.AST_NODE_TYPES.AssignmentPattern && pattern.left.type === _typescript_eslint_utils.AST_NODE_TYPES.Identifier) checkIdentifier(pattern.left, declarationNode);
|
|
2548
|
-
else if (pattern.type === _typescript_eslint_utils.AST_NODE_TYPES.RestElement && pattern.argument.type === _typescript_eslint_utils.AST_NODE_TYPES.Identifier) checkIdentifier(pattern.argument, declarationNode);
|
|
2549
|
-
};
|
|
2550
|
-
return {
|
|
2551
|
-
VariableDeclarator(node) {
|
|
2552
|
-
checkPattern(node.id, node);
|
|
2553
|
-
},
|
|
2554
|
-
FunctionDeclaration(node) {
|
|
2555
|
-
if (node.id) checkIdentifier(node.id, node);
|
|
2556
|
-
node.params.forEach((param) => checkPattern(param, node));
|
|
2557
|
-
},
|
|
2558
|
-
FunctionExpression(node) {
|
|
2559
|
-
if (node.id) checkIdentifier(node.id, node);
|
|
2560
|
-
node.params.forEach((param) => checkPattern(param, node));
|
|
2561
|
-
},
|
|
2562
|
-
ArrowFunctionExpression(node) {
|
|
2563
|
-
node.params.forEach((param) => checkPattern(param, node));
|
|
2564
|
-
},
|
|
2565
|
-
CatchClause(node) {
|
|
2566
|
-
if (node.param) checkPattern(node.param, node);
|
|
2567
|
-
}
|
|
2568
|
-
};
|
|
2569
|
-
}
|
|
2570
|
-
});
|
|
2571
|
-
//#endregion
|
|
2572
2213
|
//#region src/rules/prefer-async-await.ts
|
|
2573
2214
|
const preferAsyncAwait = _typescript_eslint_utils.ESLintUtils.RuleCreator((name) => `https://github.com/next-friday/eslint-plugin-nextfriday/blob/main/docs/rules/${name.replaceAll("-", "_").toUpperCase()}.md`)({
|
|
2574
2215
|
name: "prefer-async-await",
|
|
@@ -2635,61 +2276,6 @@ const preferDestructuringParams = _typescript_eslint_utils.ESLintUtils.RuleCreat
|
|
|
2635
2276
|
}
|
|
2636
2277
|
});
|
|
2637
2278
|
//#endregion
|
|
2638
|
-
//#region src/rules/prefer-function-declaration.ts
|
|
2639
|
-
const createRule$7 = _typescript_eslint_utils.ESLintUtils.RuleCreator((name) => `https://github.com/next-friday/eslint-plugin-nextfriday/blob/main/docs/rules/${name.replaceAll("-", "_").toUpperCase()}.md`);
|
|
2640
|
-
const isTsFile = (filename) => filename.endsWith(".ts") && !filename.endsWith(".d.ts");
|
|
2641
|
-
const isCallbackContext = (node) => {
|
|
2642
|
-
const { parent } = node;
|
|
2643
|
-
if (!parent) return false;
|
|
2644
|
-
if (parent.type === _typescript_eslint_utils.AST_NODE_TYPES.CallExpression && parent.arguments.includes(node)) return true;
|
|
2645
|
-
if (parent.type === _typescript_eslint_utils.AST_NODE_TYPES.NewExpression && parent.arguments.includes(node)) return true;
|
|
2646
|
-
if (parent.type === _typescript_eslint_utils.AST_NODE_TYPES.ReturnStatement) return true;
|
|
2647
|
-
if (parent.type === _typescript_eslint_utils.AST_NODE_TYPES.Property) return true;
|
|
2648
|
-
if (parent.type === _typescript_eslint_utils.AST_NODE_TYPES.ArrayExpression) return true;
|
|
2649
|
-
if (parent.type === _typescript_eslint_utils.AST_NODE_TYPES.ConditionalExpression) return true;
|
|
2650
|
-
if (parent.type === _typescript_eslint_utils.AST_NODE_TYPES.LogicalExpression) return true;
|
|
2651
|
-
if (parent.type === _typescript_eslint_utils.AST_NODE_TYPES.AssignmentExpression && parent.left !== node) return true;
|
|
2652
|
-
return false;
|
|
2653
|
-
};
|
|
2654
|
-
const preferFunctionDeclaration = createRule$7({
|
|
2655
|
-
name: "prefer-function-declaration",
|
|
2656
|
-
meta: {
|
|
2657
|
-
type: "suggestion",
|
|
2658
|
-
docs: { description: "Enforce function declarations over arrow functions assigned to variables in .ts files for better readability and hoisting" },
|
|
2659
|
-
messages: {
|
|
2660
|
-
preferDeclaration: "Use function declaration instead of arrow function. Replace 'const {{name}} = () => ...' with 'function {{name}}() ...'",
|
|
2661
|
-
preferDeclarationExpr: "Use function declaration instead of function expression. Replace 'const {{name}} = function() ...' with 'function {{name}}() ...'"
|
|
2662
|
-
},
|
|
2663
|
-
schema: []
|
|
2664
|
-
},
|
|
2665
|
-
defaultOptions: [],
|
|
2666
|
-
create(context) {
|
|
2667
|
-
const { filename } = context;
|
|
2668
|
-
if (!isTsFile(filename)) return {};
|
|
2669
|
-
return { VariableDeclarator(node) {
|
|
2670
|
-
if (node.id.type !== _typescript_eslint_utils.AST_NODE_TYPES.Identifier) return;
|
|
2671
|
-
const { init } = node;
|
|
2672
|
-
if (!init) return;
|
|
2673
|
-
if (init.type === _typescript_eslint_utils.AST_NODE_TYPES.ArrowFunctionExpression) {
|
|
2674
|
-
if (isCallbackContext(init)) return;
|
|
2675
|
-
context.report({
|
|
2676
|
-
node: init,
|
|
2677
|
-
messageId: "preferDeclaration",
|
|
2678
|
-
data: { name: node.id.name }
|
|
2679
|
-
});
|
|
2680
|
-
}
|
|
2681
|
-
if (init.type === _typescript_eslint_utils.AST_NODE_TYPES.FunctionExpression) {
|
|
2682
|
-
if (isCallbackContext(init)) return;
|
|
2683
|
-
context.report({
|
|
2684
|
-
node: init,
|
|
2685
|
-
messageId: "preferDeclarationExpr",
|
|
2686
|
-
data: { name: node.id.name }
|
|
2687
|
-
});
|
|
2688
|
-
}
|
|
2689
|
-
} };
|
|
2690
|
-
}
|
|
2691
|
-
});
|
|
2692
|
-
//#endregion
|
|
2693
2279
|
//#region src/rules/prefer-guard-clause.ts
|
|
2694
2280
|
const preferGuardClause = _typescript_eslint_utils.ESLintUtils.RuleCreator((name) => `https://github.com/next-friday/eslint-plugin-nextfriday/blob/main/docs/rules/${name.replaceAll("-", "_").toUpperCase()}.md`)({
|
|
2695
2281
|
name: "prefer-guard-clause",
|
|
@@ -2963,64 +2549,6 @@ const preferInterfaceOverInlineTypes = _typescript_eslint_utils.ESLintUtils.Rule
|
|
|
2963
2549
|
}
|
|
2964
2550
|
});
|
|
2965
2551
|
//#endregion
|
|
2966
|
-
//#region src/rules/prefer-jsx-template-literals.ts
|
|
2967
|
-
const preferJSXTemplateLiterals = _typescript_eslint_utils.ESLintUtils.RuleCreator((name) => `https://github.com/next-friday/eslint-plugin-nextfriday/blob/main/docs/rules/${name.replaceAll("-", "_").toUpperCase()}.md`)({
|
|
2968
|
-
name: "prefer-jsx-template-literals",
|
|
2969
|
-
meta: {
|
|
2970
|
-
type: "suggestion",
|
|
2971
|
-
docs: { description: "Enforce using template literals instead of mixing text and JSX expressions" },
|
|
2972
|
-
fixable: "code",
|
|
2973
|
-
schema: [],
|
|
2974
|
-
messages: { preferTemplate: "Use template literal instead of mixing text with JSX expressions" }
|
|
2975
|
-
},
|
|
2976
|
-
defaultOptions: [],
|
|
2977
|
-
create(context) {
|
|
2978
|
-
if (!isJsxFile(context.filename)) return {};
|
|
2979
|
-
function handleTextBeforeExpression(textNode, exprNode) {
|
|
2980
|
-
const textValue = textNode.value;
|
|
2981
|
-
const trimmedText = textValue.trim();
|
|
2982
|
-
if (!trimmedText) return;
|
|
2983
|
-
const hasTextContent = trimmedText.length > 0 && textValue !== trimmedText;
|
|
2984
|
-
const hasNoTrailingSpace = trimmedText.length > 0 && /\S$/.test(textValue);
|
|
2985
|
-
if (!hasTextContent && !hasNoTrailingSpace) return;
|
|
2986
|
-
context.report({
|
|
2987
|
-
node: textNode,
|
|
2988
|
-
messageId: "preferTemplate",
|
|
2989
|
-
fix(fixer) {
|
|
2990
|
-
const templateLiteral = `{\`${textValue.trimEnd()}\${${context.sourceCode.getText(exprNode.expression)}}\`}`;
|
|
2991
|
-
return [fixer.replaceText(textNode, templateLiteral), fixer.remove(exprNode)];
|
|
2992
|
-
}
|
|
2993
|
-
});
|
|
2994
|
-
}
|
|
2995
|
-
function handleExpressionBeforeText(exprNode, textNode) {
|
|
2996
|
-
const textValue = textNode.value;
|
|
2997
|
-
const trimmedText = textValue.trim();
|
|
2998
|
-
if (!trimmedText) return;
|
|
2999
|
-
if (!/^\S/.test(trimmedText)) return;
|
|
3000
|
-
context.report({
|
|
3001
|
-
node: textNode,
|
|
3002
|
-
messageId: "preferTemplate",
|
|
3003
|
-
fix(fixer) {
|
|
3004
|
-
const templateLiteral = `{\`\${${context.sourceCode.getText(exprNode.expression)}}${textValue.trim()}\`}`;
|
|
3005
|
-
return [fixer.replaceText(exprNode, templateLiteral), fixer.remove(textNode)];
|
|
3006
|
-
}
|
|
3007
|
-
});
|
|
3008
|
-
}
|
|
3009
|
-
function checkJSXElement(node) {
|
|
3010
|
-
const { children } = node;
|
|
3011
|
-
if (children.length < 2) return;
|
|
3012
|
-
for (let i = 0; i < children.length - 1; i += 1) {
|
|
3013
|
-
const child = children[i];
|
|
3014
|
-
const nextChild = children[i + 1];
|
|
3015
|
-
if (!child || !nextChild) return;
|
|
3016
|
-
if (child.type === _typescript_eslint_utils.AST_NODE_TYPES.JSXText && nextChild.type === _typescript_eslint_utils.AST_NODE_TYPES.JSXExpressionContainer) handleTextBeforeExpression(child, nextChild);
|
|
3017
|
-
else if (child.type === _typescript_eslint_utils.AST_NODE_TYPES.JSXExpressionContainer && nextChild.type === _typescript_eslint_utils.AST_NODE_TYPES.JSXText) handleExpressionBeforeText(child, nextChild);
|
|
3018
|
-
}
|
|
3019
|
-
}
|
|
3020
|
-
return { JSXElement: checkJSXElement };
|
|
3021
|
-
}
|
|
3022
|
-
});
|
|
3023
|
-
//#endregion
|
|
3024
2552
|
//#region src/rules/prefer-named-param-types.ts
|
|
3025
2553
|
const createRule$5 = _typescript_eslint_utils.ESLintUtils.RuleCreator((name) => `https://github.com/next-friday/eslint-plugin-nextfriday/blob/main/docs/rules/${name.replaceAll("-", "_").toUpperCase()}.md`);
|
|
3026
2554
|
const returnsJsx = (node) => {
|
|
@@ -3237,65 +2765,6 @@ const preferReactImportTypes = _typescript_eslint_utils.ESLintUtils.RuleCreator(
|
|
|
3237
2765
|
}
|
|
3238
2766
|
});
|
|
3239
2767
|
//#endregion
|
|
3240
|
-
//#region src/rules/react-props-destructure.ts
|
|
3241
|
-
const reactPropsDestructure = _typescript_eslint_utils.ESLintUtils.RuleCreator((name) => `https://github.com/next-friday/eslint-plugin-nextfriday/blob/main/docs/rules/${name.replaceAll("-", "_").toUpperCase()}.md`)({
|
|
3242
|
-
name: "react-props-destructure",
|
|
3243
|
-
meta: {
|
|
3244
|
-
type: "suggestion",
|
|
3245
|
-
docs: { description: "Enforce destructuring props inside React component body instead of parameters" },
|
|
3246
|
-
fixable: void 0,
|
|
3247
|
-
schema: [],
|
|
3248
|
-
messages: { noParameterDestructuring: "Destructure props inside component body instead of parameters. Use 'const { {{properties}} } = props;'" }
|
|
3249
|
-
},
|
|
3250
|
-
defaultOptions: [],
|
|
3251
|
-
create(context) {
|
|
3252
|
-
if (!isJsxFile(context.filename)) return {};
|
|
3253
|
-
function hasJSXInConditional(node) {
|
|
3254
|
-
return node.consequent.type === _typescript_eslint_utils.AST_NODE_TYPES.JSXElement || node.consequent.type === _typescript_eslint_utils.AST_NODE_TYPES.JSXFragment || node.alternate.type === _typescript_eslint_utils.AST_NODE_TYPES.JSXElement || node.alternate.type === _typescript_eslint_utils.AST_NODE_TYPES.JSXFragment;
|
|
3255
|
-
}
|
|
3256
|
-
function hasJSXInLogical(node) {
|
|
3257
|
-
return node.right.type === _typescript_eslint_utils.AST_NODE_TYPES.JSXElement || node.right.type === _typescript_eslint_utils.AST_NODE_TYPES.JSXFragment;
|
|
3258
|
-
}
|
|
3259
|
-
function hasJSXReturn(block) {
|
|
3260
|
-
return block.body.some((stmt) => {
|
|
3261
|
-
if (stmt.type === _typescript_eslint_utils.AST_NODE_TYPES.ReturnStatement && stmt.argument) return stmt.argument.type === _typescript_eslint_utils.AST_NODE_TYPES.JSXElement || stmt.argument.type === _typescript_eslint_utils.AST_NODE_TYPES.JSXFragment || stmt.argument.type === _typescript_eslint_utils.AST_NODE_TYPES.ConditionalExpression && hasJSXInConditional(stmt.argument) || stmt.argument.type === _typescript_eslint_utils.AST_NODE_TYPES.LogicalExpression && hasJSXInLogical(stmt.argument);
|
|
3262
|
-
return false;
|
|
3263
|
-
});
|
|
3264
|
-
}
|
|
3265
|
-
function isReactComponent(node) {
|
|
3266
|
-
if (node.type === _typescript_eslint_utils.AST_NODE_TYPES.ArrowFunctionExpression) {
|
|
3267
|
-
if (node.body.type === _typescript_eslint_utils.AST_NODE_TYPES.JSXElement || node.body.type === _typescript_eslint_utils.AST_NODE_TYPES.JSXFragment) return true;
|
|
3268
|
-
if (node.body.type === _typescript_eslint_utils.AST_NODE_TYPES.BlockStatement) return hasJSXReturn(node.body);
|
|
3269
|
-
} else if (node.type === _typescript_eslint_utils.AST_NODE_TYPES.FunctionExpression || node.type === _typescript_eslint_utils.AST_NODE_TYPES.FunctionDeclaration) {
|
|
3270
|
-
if (node.body && node.body.type === _typescript_eslint_utils.AST_NODE_TYPES.BlockStatement) return hasJSXReturn(node.body);
|
|
3271
|
-
}
|
|
3272
|
-
return false;
|
|
3273
|
-
}
|
|
3274
|
-
function checkFunction(node) {
|
|
3275
|
-
if (!isReactComponent(node)) return;
|
|
3276
|
-
if (node.params.length !== 1) return;
|
|
3277
|
-
const param = node.params[0];
|
|
3278
|
-
if (param.type === _typescript_eslint_utils.AST_NODE_TYPES.ObjectPattern) {
|
|
3279
|
-
const properties = param.properties.filter((prop) => prop.type === _typescript_eslint_utils.AST_NODE_TYPES.Property).map((prop) => {
|
|
3280
|
-
if (prop.key.type === _typescript_eslint_utils.AST_NODE_TYPES.Identifier) return prop.key.name;
|
|
3281
|
-
return null;
|
|
3282
|
-
}).filter((name) => name !== null);
|
|
3283
|
-
if (properties.length === 0) return;
|
|
3284
|
-
context.report({
|
|
3285
|
-
node: param,
|
|
3286
|
-
messageId: "noParameterDestructuring",
|
|
3287
|
-
data: { properties: properties.join(", ") }
|
|
3288
|
-
});
|
|
3289
|
-
}
|
|
3290
|
-
}
|
|
3291
|
-
return {
|
|
3292
|
-
ArrowFunctionExpression: checkFunction,
|
|
3293
|
-
FunctionExpression: checkFunction,
|
|
3294
|
-
FunctionDeclaration: checkFunction
|
|
3295
|
-
};
|
|
3296
|
-
}
|
|
3297
|
-
});
|
|
3298
|
-
//#endregion
|
|
3299
2768
|
//#region src/rules/require-explicit-return-type.ts
|
|
3300
2769
|
const createRule$4 = _typescript_eslint_utils.ESLintUtils.RuleCreator((name) => `https://github.com/next-friday/eslint-plugin-nextfriday/blob/main/docs/rules/${name.replaceAll("-", "_").toUpperCase()}.md`);
|
|
3301
2770
|
const isReactComponent = (node) => {
|
|
@@ -3472,21 +2941,29 @@ const GROUP_NAMES = [
|
|
|
3472
2941
|
"",
|
|
3473
2942
|
"side-effect",
|
|
3474
2943
|
"builtin",
|
|
2944
|
+
"builtin type",
|
|
3475
2945
|
"external",
|
|
2946
|
+
"external type",
|
|
3476
2947
|
"internal alias",
|
|
3477
|
-
"
|
|
2948
|
+
"internal alias type",
|
|
2949
|
+
"parent relative",
|
|
2950
|
+
"parent relative type",
|
|
2951
|
+
"relative",
|
|
2952
|
+
"relative type"
|
|
3478
2953
|
];
|
|
3479
|
-
function getImportGroup(node) {
|
|
3480
|
-
const source = node.source.value;
|
|
3481
|
-
if (node.specifiers.length === 0 && node.importKind !== "type") return 1;
|
|
3482
|
-
if (source.startsWith("node:") || NODE_BUILTINS.has(source.split("/")[0])) return 2;
|
|
3483
|
-
if (source.startsWith("@/") || source.startsWith("~/") || source.startsWith("#")) return 4;
|
|
3484
|
-
if (source.startsWith(".")) return 5;
|
|
3485
|
-
return 3;
|
|
3486
|
-
}
|
|
3487
2954
|
function isTypeOnlyImport(node) {
|
|
3488
2955
|
return node.importKind === "type" && node.specifiers.length > 0;
|
|
3489
2956
|
}
|
|
2957
|
+
function getImportGroup(node) {
|
|
2958
|
+
const source = node.source.value;
|
|
2959
|
+
const isType = isTypeOnlyImport(node);
|
|
2960
|
+
if (node.specifiers.length === 0 && !isType) return 1;
|
|
2961
|
+
if (source.startsWith("node:") || NODE_BUILTINS.has(source.split("/")[0])) return isType ? 3 : 2;
|
|
2962
|
+
if (source.startsWith("@/") || source.startsWith("~/") || source.startsWith("#")) return isType ? 7 : 6;
|
|
2963
|
+
if (source.startsWith("../")) return isType ? 9 : 8;
|
|
2964
|
+
if (source.startsWith(".")) return isType ? 11 : 10;
|
|
2965
|
+
return isType ? 5 : 4;
|
|
2966
|
+
}
|
|
3490
2967
|
const sortImports = createRule$2({
|
|
3491
2968
|
name: "sort-imports",
|
|
3492
2969
|
meta: {
|
|
@@ -3494,14 +2971,43 @@ const sortImports = createRule$2({
|
|
|
3494
2971
|
docs: { description: "Enforce a consistent ordering of import groups" },
|
|
3495
2972
|
fixable: "code",
|
|
3496
2973
|
schema: [],
|
|
3497
|
-
messages: {
|
|
2974
|
+
messages: {
|
|
2975
|
+
unsortedImports: "Import group '{{current}}' should come before '{{previous}}'. Expected order: side-effect, builtin, external, internal alias, parent relative, relative — each followed by its type imports.",
|
|
2976
|
+
missingBlankLine: "Expected a blank line before '{{current}}' imports (new group after '{{previous}}')."
|
|
2977
|
+
}
|
|
3498
2978
|
},
|
|
3499
2979
|
defaultOptions: [],
|
|
3500
2980
|
create(context) {
|
|
2981
|
+
function getMainGroup(group) {
|
|
2982
|
+
if (group === 1) return 1;
|
|
2983
|
+
return Math.floor((group - 2) / 2) + 2;
|
|
2984
|
+
}
|
|
2985
|
+
function checkBlankLines(imports) {
|
|
2986
|
+
const { sourceCode } = context;
|
|
2987
|
+
for (let i = 1; i < imports.length; i++) {
|
|
2988
|
+
const prev = imports[i - 1];
|
|
2989
|
+
const curr = imports[i];
|
|
2990
|
+
if (getMainGroup(prev.group) === getMainGroup(curr.group)) continue;
|
|
2991
|
+
if (curr.node.loc.start.line - prev.node.loc.end.line > 1) continue;
|
|
2992
|
+
context.report({
|
|
2993
|
+
node: curr.node,
|
|
2994
|
+
messageId: "missingBlankLine",
|
|
2995
|
+
data: {
|
|
2996
|
+
current: GROUP_NAMES[curr.group],
|
|
2997
|
+
previous: GROUP_NAMES[prev.group]
|
|
2998
|
+
},
|
|
2999
|
+
fix(fixer) {
|
|
3000
|
+
const firstToken = sourceCode.getFirstToken(curr.node);
|
|
3001
|
+
if (!firstToken) return null;
|
|
3002
|
+
return fixer.insertTextBefore(firstToken, "\n");
|
|
3003
|
+
}
|
|
3004
|
+
});
|
|
3005
|
+
}
|
|
3006
|
+
}
|
|
3501
3007
|
function checkOrder(imports) {
|
|
3502
|
-
if (imports.every((entry, index) => index === 0 || entry.group >= imports[index - 1].group)) return;
|
|
3008
|
+
if (imports.every((entry, index) => index === 0 || entry.group >= imports[index - 1].group)) return false;
|
|
3503
3009
|
const firstUnsorted = imports.find((entry, index) => index > 0 && entry.group < imports[index - 1].group);
|
|
3504
|
-
if (!firstUnsorted) return;
|
|
3010
|
+
if (!firstUnsorted) return false;
|
|
3505
3011
|
const previous = imports[imports.indexOf(firstUnsorted) - 1];
|
|
3506
3012
|
context.report({
|
|
3507
3013
|
node: firstUnsorted.node,
|
|
@@ -3516,24 +3022,26 @@ const sortImports = createRule$2({
|
|
|
3516
3022
|
return imports.map((entry, index) => fixer.replaceText(entry.node, sortedTexts[index]));
|
|
3517
3023
|
}
|
|
3518
3024
|
});
|
|
3025
|
+
return true;
|
|
3519
3026
|
}
|
|
3520
3027
|
return { Program(node) {
|
|
3521
3028
|
const importGroups = [];
|
|
3522
3029
|
node.body.forEach((statement) => {
|
|
3523
3030
|
if (statement.type !== _typescript_eslint_utils.AST_NODE_TYPES.ImportDeclaration) {
|
|
3524
3031
|
if (importGroups.length > 0) {
|
|
3525
|
-
checkOrder(importGroups);
|
|
3032
|
+
if (!checkOrder(importGroups)) checkBlankLines(importGroups);
|
|
3526
3033
|
importGroups.length = 0;
|
|
3527
3034
|
}
|
|
3528
3035
|
return;
|
|
3529
3036
|
}
|
|
3530
|
-
if (isTypeOnlyImport(statement)) return;
|
|
3531
3037
|
importGroups.push({
|
|
3532
3038
|
node: statement,
|
|
3533
3039
|
group: getImportGroup(statement)
|
|
3534
3040
|
});
|
|
3535
3041
|
});
|
|
3536
|
-
if (importGroups.length > 0)
|
|
3042
|
+
if (importGroups.length > 0) {
|
|
3043
|
+
if (!checkOrder(importGroups)) checkBlankLines(importGroups);
|
|
3044
|
+
}
|
|
3537
3045
|
} };
|
|
3538
3046
|
}
|
|
3539
3047
|
});
|
|
@@ -3666,11 +3174,9 @@ const meta = {
|
|
|
3666
3174
|
};
|
|
3667
3175
|
const rules = {
|
|
3668
3176
|
"boolean-naming-prefix": booleanNamingPrefix,
|
|
3669
|
-
"enforce-camel-case": enforceCamelCase,
|
|
3670
3177
|
"enforce-constant-case": enforceConstantCase,
|
|
3671
3178
|
"enforce-hook-filename": enforceHookFilename,
|
|
3672
3179
|
"enforce-hook-naming": enforceHookNaming,
|
|
3673
|
-
"enforce-property-case": enforcePropertyCase,
|
|
3674
3180
|
"enforce-props-suffix": enforcePropsSuffix,
|
|
3675
3181
|
"enforce-readonly-component-props": enforceReadonlyComponentProps,
|
|
3676
3182
|
"enforce-render-naming": enforceRenderNaming,
|
|
@@ -3701,7 +3207,6 @@ const rules = {
|
|
|
3701
3207
|
"no-ghost-wrapper": noGhostWrapper,
|
|
3702
3208
|
"no-helper-function-in-hook": noHelperFunctionInHook,
|
|
3703
3209
|
"no-helper-function-in-test": noHelperFunctionInTest,
|
|
3704
|
-
"no-inline-default-export": noInlineDefaultExport,
|
|
3705
3210
|
"no-inline-nested-object": noInlineNestedObject,
|
|
3706
3211
|
"no-inline-return-properties": noInlineReturnProperties,
|
|
3707
3212
|
"no-inline-type-import": noInlineTypeImport,
|
|
@@ -3709,23 +3214,17 @@ const rules = {
|
|
|
3709
3214
|
"no-logic-in-params": noLogicInParams,
|
|
3710
3215
|
"no-misleading-constant-case": noMisleadingConstantCase,
|
|
3711
3216
|
"no-nested-interface-declaration": noNestedInterfaceDeclaration,
|
|
3712
|
-
"no-nested-ternary": noNestedTernary,
|
|
3713
|
-
"no-redundant-fragment": noRedundantFragment,
|
|
3714
3217
|
"no-relative-imports": noRelativeImports,
|
|
3715
|
-
"no-single-char-variables": noSingleCharVariables,
|
|
3716
3218
|
"prefer-async-await": preferAsyncAwait,
|
|
3717
3219
|
"prefer-destructuring-params": preferDestructuringParams,
|
|
3718
|
-
"prefer-function-declaration": preferFunctionDeclaration,
|
|
3719
3220
|
"prefer-guard-clause": preferGuardClause,
|
|
3720
3221
|
"prefer-import-type": preferImportType,
|
|
3721
3222
|
"prefer-inline-literal-union": preferInlineLiteralUnion,
|
|
3722
3223
|
"prefer-interface-for-component-props": preferInterfaceForComponentProps,
|
|
3723
3224
|
"prefer-interface-over-inline-types": preferInterfaceOverInlineTypes,
|
|
3724
|
-
"prefer-jsx-template-literals": preferJSXTemplateLiterals,
|
|
3725
3225
|
"prefer-named-param-types": preferNamedParamTypes,
|
|
3726
3226
|
"prefer-props-with-children": preferPropsWithChildren,
|
|
3727
3227
|
"prefer-react-import-types": preferReactImportTypes,
|
|
3728
|
-
"react-props-destructure": reactPropsDestructure,
|
|
3729
3228
|
"require-explicit-return-type": requireExplicitReturnType,
|
|
3730
3229
|
"sort-exports": sortExports,
|
|
3731
3230
|
"sort-imports": sortImports,
|
|
@@ -3738,11 +3237,9 @@ const plugin = {
|
|
|
3738
3237
|
};
|
|
3739
3238
|
const baseRules = {
|
|
3740
3239
|
"nextfriday/boolean-naming-prefix": "warn",
|
|
3741
|
-
"nextfriday/enforce-camel-case": "warn",
|
|
3742
3240
|
"nextfriday/enforce-constant-case": "warn",
|
|
3743
3241
|
"nextfriday/enforce-hook-filename": "warn",
|
|
3744
3242
|
"nextfriday/enforce-hook-naming": "warn",
|
|
3745
|
-
"nextfriday/enforce-property-case": "warn",
|
|
3746
3243
|
"nextfriday/enforce-service-naming": "warn",
|
|
3747
3244
|
"nextfriday/enforce-test-filename": "warn",
|
|
3748
3245
|
"nextfriday/enforce-sorted-destructuring": "warn",
|
|
@@ -3756,7 +3253,6 @@ const baseRules = {
|
|
|
3756
3253
|
"nextfriday/no-env-fallback": "warn",
|
|
3757
3254
|
"nextfriday/no-helper-function-in-hook": "warn",
|
|
3758
3255
|
"nextfriday/no-helper-function-in-test": "warn",
|
|
3759
|
-
"nextfriday/no-inline-default-export": "warn",
|
|
3760
3256
|
"nextfriday/no-inline-nested-object": "warn",
|
|
3761
3257
|
"nextfriday/no-inline-return-properties": "warn",
|
|
3762
3258
|
"nextfriday/no-inline-type-import": "warn",
|
|
@@ -3764,12 +3260,9 @@ const baseRules = {
|
|
|
3764
3260
|
"nextfriday/no-logic-in-params": "warn",
|
|
3765
3261
|
"nextfriday/no-misleading-constant-case": "warn",
|
|
3766
3262
|
"nextfriday/no-nested-interface-declaration": "warn",
|
|
3767
|
-
"nextfriday/no-nested-ternary": "warn",
|
|
3768
3263
|
"nextfriday/no-relative-imports": "warn",
|
|
3769
|
-
"nextfriday/no-single-char-variables": "warn",
|
|
3770
3264
|
"nextfriday/prefer-async-await": "warn",
|
|
3771
3265
|
"nextfriday/prefer-destructuring-params": "warn",
|
|
3772
|
-
"nextfriday/prefer-function-declaration": "warn",
|
|
3773
3266
|
"nextfriday/prefer-guard-clause": "warn",
|
|
3774
3267
|
"nextfriday/prefer-import-type": "warn",
|
|
3775
3268
|
"nextfriday/prefer-inline-literal-union": "warn",
|
|
@@ -3783,11 +3276,9 @@ const baseRules = {
|
|
|
3783
3276
|
};
|
|
3784
3277
|
const baseRecommendedRules = {
|
|
3785
3278
|
"nextfriday/boolean-naming-prefix": "error",
|
|
3786
|
-
"nextfriday/enforce-camel-case": "error",
|
|
3787
3279
|
"nextfriday/enforce-constant-case": "error",
|
|
3788
3280
|
"nextfriday/enforce-hook-filename": "error",
|
|
3789
3281
|
"nextfriday/enforce-hook-naming": "error",
|
|
3790
|
-
"nextfriday/enforce-property-case": "error",
|
|
3791
3282
|
"nextfriday/enforce-service-naming": "error",
|
|
3792
3283
|
"nextfriday/enforce-test-filename": "error",
|
|
3793
3284
|
"nextfriday/enforce-sorted-destructuring": "error",
|
|
@@ -3801,7 +3292,6 @@ const baseRecommendedRules = {
|
|
|
3801
3292
|
"nextfriday/no-env-fallback": "error",
|
|
3802
3293
|
"nextfriday/no-helper-function-in-hook": "error",
|
|
3803
3294
|
"nextfriday/no-helper-function-in-test": "error",
|
|
3804
|
-
"nextfriday/no-inline-default-export": "error",
|
|
3805
3295
|
"nextfriday/no-inline-nested-object": "error",
|
|
3806
3296
|
"nextfriday/no-inline-return-properties": "error",
|
|
3807
3297
|
"nextfriday/no-inline-type-import": "error",
|
|
@@ -3809,12 +3299,9 @@ const baseRecommendedRules = {
|
|
|
3809
3299
|
"nextfriday/no-logic-in-params": "error",
|
|
3810
3300
|
"nextfriday/no-misleading-constant-case": "error",
|
|
3811
3301
|
"nextfriday/no-nested-interface-declaration": "error",
|
|
3812
|
-
"nextfriday/no-nested-ternary": "error",
|
|
3813
3302
|
"nextfriday/no-relative-imports": "error",
|
|
3814
|
-
"nextfriday/no-single-char-variables": "error",
|
|
3815
3303
|
"nextfriday/prefer-async-await": "error",
|
|
3816
3304
|
"nextfriday/prefer-destructuring-params": "error",
|
|
3817
|
-
"nextfriday/prefer-function-declaration": "error",
|
|
3818
3305
|
"nextfriday/prefer-guard-clause": "error",
|
|
3819
3306
|
"nextfriday/prefer-import-type": "error",
|
|
3820
3307
|
"nextfriday/prefer-inline-literal-union": "error",
|
|
@@ -3844,12 +3331,9 @@ const jsxRules = {
|
|
|
3844
3331
|
"nextfriday/jsx-sort-props": "warn",
|
|
3845
3332
|
"nextfriday/jsx-spread-props-last": "warn",
|
|
3846
3333
|
"nextfriday/no-ghost-wrapper": "warn",
|
|
3847
|
-
"nextfriday/no-redundant-fragment": "warn",
|
|
3848
3334
|
"nextfriday/prefer-interface-for-component-props": "warn",
|
|
3849
3335
|
"nextfriday/prefer-interface-over-inline-types": "warn",
|
|
3850
|
-
"nextfriday/prefer-
|
|
3851
|
-
"nextfriday/prefer-props-with-children": "warn",
|
|
3852
|
-
"nextfriday/react-props-destructure": "warn"
|
|
3336
|
+
"nextfriday/prefer-props-with-children": "warn"
|
|
3853
3337
|
};
|
|
3854
3338
|
const jsxRecommendedRules = {
|
|
3855
3339
|
"nextfriday/enforce-props-suffix": "error",
|
|
@@ -3869,12 +3353,9 @@ const jsxRecommendedRules = {
|
|
|
3869
3353
|
"nextfriday/jsx-sort-props": "error",
|
|
3870
3354
|
"nextfriday/jsx-spread-props-last": "error",
|
|
3871
3355
|
"nextfriday/no-ghost-wrapper": "error",
|
|
3872
|
-
"nextfriday/no-redundant-fragment": "error",
|
|
3873
3356
|
"nextfriday/prefer-interface-for-component-props": "error",
|
|
3874
3357
|
"nextfriday/prefer-interface-over-inline-types": "error",
|
|
3875
|
-
"nextfriday/prefer-
|
|
3876
|
-
"nextfriday/prefer-props-with-children": "error",
|
|
3877
|
-
"nextfriday/react-props-destructure": "error"
|
|
3358
|
+
"nextfriday/prefer-props-with-children": "error"
|
|
3878
3359
|
};
|
|
3879
3360
|
const createConfig = (configRules) => ({
|
|
3880
3361
|
plugins: { nextfriday: plugin },
|