eslint-plugin-nextfriday 1.2.2 → 1.3.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 +12 -0
- package/README.md +3 -0
- package/docs/rules/PREFER_NAMED_PARAM_TYPES.md +172 -0
- package/lib/index.cjs +116 -31
- package/lib/index.cjs.map +1 -1
- package/lib/index.d.cts +14 -0
- package/lib/index.d.ts +14 -0
- package/lib/index.js +116 -31
- package/lib/index.js.map +1 -1
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,17 @@
|
|
|
1
1
|
# eslint-plugin-nextfriday
|
|
2
2
|
|
|
3
|
+
## 1.3.0
|
|
4
|
+
|
|
5
|
+
### Minor Changes
|
|
6
|
+
|
|
7
|
+
- [#24](https://github.com/next-friday/eslint-plugin-nextfriday/pull/24) [`59d1932`](https://github.com/next-friday/eslint-plugin-nextfriday/commit/59d193258d6ffd19d6fd90515626d826732e30b3) Thanks [@nextfridaydeveloper](https://github.com/nextfridaydeveloper)! - Add new prefer-named-param-types rule that enforces using named interfaces or type aliases instead of inline object type literals for function
|
|
8
|
+
|
|
9
|
+
## 1.2.3
|
|
10
|
+
|
|
11
|
+
### Patch Changes
|
|
12
|
+
|
|
13
|
+
- [#22](https://github.com/next-friday/eslint-plugin-nextfriday/pull/22) [`45d54ff`](https://github.com/next-friday/eslint-plugin-nextfriday/commit/45d54ffb7be27c762fbf57c40752a83a1fb1da32) Thanks [@nextfridaydeveloper](https://github.com/nextfridaydeveloper)! - Updated rule documentation links to use uppercase and underscores (SNAKE_CASE) for rule names to match the actual documentation file naming convention.
|
|
14
|
+
|
|
3
15
|
## 1.2.2
|
|
4
16
|
|
|
5
17
|
### Patch Changes
|
package/README.md
CHANGED
|
@@ -65,6 +65,7 @@ export default [
|
|
|
65
65
|
"nextfriday/prefer-destructuring-params": "error",
|
|
66
66
|
"nextfriday/no-explicit-return-type": "error",
|
|
67
67
|
"nextfriday/prefer-import-type": "error",
|
|
68
|
+
"nextfriday/prefer-named-param-types": "error",
|
|
68
69
|
"nextfriday/prefer-react-import-types": "error",
|
|
69
70
|
"nextfriday/jsx-pascal-case": "error",
|
|
70
71
|
"nextfriday/prefer-interface-over-inline-types": "error",
|
|
@@ -115,6 +116,7 @@ module.exports = {
|
|
|
115
116
|
| [prefer-destructuring-params](docs/rules/PREFER_DESTRUCTURING_PARAMS.md) | Enforce destructuring for functions with multiple parameters | ❌ |
|
|
116
117
|
| [no-explicit-return-type](docs/rules/NO_EXPLICIT_RETURN_TYPE.md) | Disallow explicit return types on functions | ✅ |
|
|
117
118
|
| [prefer-import-type](docs/rules/PREFER_IMPORT_TYPE.md) | Enforce using 'import type' for type-only imports | ✅ |
|
|
119
|
+
| [prefer-named-param-types](docs/rules/PREFER_NAMED_PARAM_TYPES.md) | Enforce named types for function parameters with object types | ❌ |
|
|
118
120
|
| [prefer-interface-over-inline-types](docs/rules/PREFER_INTERFACE_OVER_INLINE_TYPES.md) | Enforce interface declarations over inline types for React props | ❌ |
|
|
119
121
|
| [prefer-react-import-types](docs/rules/PREFER_REACT_IMPORT_TYPES.md) | Enforce direct imports from 'react' instead of React.X | ✅ |
|
|
120
122
|
| [react-props-destructure](docs/rules/REACT_PROPS_DESTRUCTURE.md) | Enforce destructuring props inside React component body | ❌ |
|
|
@@ -134,6 +136,7 @@ Basic configuration without JSX-specific rules:
|
|
|
134
136
|
- `nextfriday/prefer-destructuring-params`: `"error"`
|
|
135
137
|
- `nextfriday/no-explicit-return-type`: `"error"`
|
|
136
138
|
- `nextfriday/prefer-import-type`: `"error"`
|
|
139
|
+
- `nextfriday/prefer-named-param-types`: `"error"`
|
|
137
140
|
- `nextfriday/prefer-react-import-types`: `"error"`
|
|
138
141
|
|
|
139
142
|
#### `base/recommended`
|
|
@@ -0,0 +1,172 @@
|
|
|
1
|
+
# prefer-named-param-types
|
|
2
|
+
|
|
3
|
+
Enforce named interfaces or types instead of inline object types for function parameters.
|
|
4
|
+
|
|
5
|
+
## Rule Details
|
|
6
|
+
|
|
7
|
+
This rule enforces extracting inline object type annotations for function parameters into named interfaces or type aliases. This promotes better code organization, reusability, and readability across your codebase.
|
|
8
|
+
|
|
9
|
+
Examples of **incorrect** code for this rule:
|
|
10
|
+
|
|
11
|
+
```typescript
|
|
12
|
+
// Destructured parameter with inline type
|
|
13
|
+
const foo = ({ bar, baz }: { bar: string; baz: number }) => {
|
|
14
|
+
console.log(bar, baz);
|
|
15
|
+
};
|
|
16
|
+
|
|
17
|
+
// Regular parameter with inline type
|
|
18
|
+
const foo = (params: { bar: string; baz: number }) => {
|
|
19
|
+
const { bar, baz } = params;
|
|
20
|
+
console.log(bar, baz);
|
|
21
|
+
};
|
|
22
|
+
|
|
23
|
+
// Function declaration
|
|
24
|
+
function createUser(data: { name: string; email: string; role: "admin" | "user" }) {
|
|
25
|
+
return { ...data, createdAt: Date.now() };
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
// Function expression
|
|
29
|
+
const handler = function (data: { id: number; name: string }) {
|
|
30
|
+
return data.id;
|
|
31
|
+
};
|
|
32
|
+
|
|
33
|
+
// Multiple parameters with inline types
|
|
34
|
+
const foo = (first: { a: string; b: number }, second: { x: boolean; y: string }) => {
|
|
35
|
+
return { first, second };
|
|
36
|
+
};
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
Examples of **correct** code for this rule:
|
|
40
|
+
|
|
41
|
+
```typescript
|
|
42
|
+
// Using interface
|
|
43
|
+
interface Params {
|
|
44
|
+
bar: string;
|
|
45
|
+
baz: number;
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
const foo = (params: Params) => {
|
|
49
|
+
const { bar, baz } = params;
|
|
50
|
+
console.log(bar, baz);
|
|
51
|
+
};
|
|
52
|
+
|
|
53
|
+
// Using type alias
|
|
54
|
+
type UserData = {
|
|
55
|
+
name: string;
|
|
56
|
+
email: string;
|
|
57
|
+
role: "admin" | "user";
|
|
58
|
+
};
|
|
59
|
+
|
|
60
|
+
const createUser = (data: UserData) => {
|
|
61
|
+
return { ...data, createdAt: Date.now() };
|
|
62
|
+
};
|
|
63
|
+
|
|
64
|
+
// Primitive types are allowed
|
|
65
|
+
const foo = (value: string) => {
|
|
66
|
+
return value;
|
|
67
|
+
};
|
|
68
|
+
|
|
69
|
+
const bar = (count: number, enabled: boolean) => {
|
|
70
|
+
return count > 0 && enabled;
|
|
71
|
+
};
|
|
72
|
+
|
|
73
|
+
// Functions with no parameters
|
|
74
|
+
const baz = () => {
|
|
75
|
+
return "no params";
|
|
76
|
+
};
|
|
77
|
+
|
|
78
|
+
// Named types with destructuring
|
|
79
|
+
interface Config {
|
|
80
|
+
theme: string;
|
|
81
|
+
locale: string;
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
const setup = (config: Config) => {
|
|
85
|
+
const { theme, locale } = config;
|
|
86
|
+
console.log(theme, locale);
|
|
87
|
+
};
|
|
88
|
+
```
|
|
89
|
+
|
|
90
|
+
## Why?
|
|
91
|
+
|
|
92
|
+
### Benefits of named parameter types:
|
|
93
|
+
|
|
94
|
+
1. **Reusability**: Named types can be reused across multiple functions
|
|
95
|
+
2. **Better organization**: Separates type definitions from function logic
|
|
96
|
+
3. **Improved readability**: Makes function signatures cleaner and easier to understand
|
|
97
|
+
4. **Better IDE support**: Enhanced autocomplete, refactoring, and navigation
|
|
98
|
+
5. **Documentation**: Named types serve as clear documentation of function APIs
|
|
99
|
+
6. **Extensibility**: Types and interfaces can be extended and composed more easily
|
|
100
|
+
7. **Type inference**: Named types can improve TypeScript's type inference in complex scenarios
|
|
101
|
+
|
|
102
|
+
## Rule Scope
|
|
103
|
+
|
|
104
|
+
This rule applies to:
|
|
105
|
+
|
|
106
|
+
- All function types: arrow functions, function expressions, and function declarations
|
|
107
|
+
- Function parameters with inline object type literals
|
|
108
|
+
- Method definitions with inline object type parameters
|
|
109
|
+
- TypeScript method signatures
|
|
110
|
+
|
|
111
|
+
The rule triggers when:
|
|
112
|
+
|
|
113
|
+
- A parameter has an inline object type literal (e.g., `{ bar: string; baz: number }`)
|
|
114
|
+
- The parameter is destructured with an inline type (e.g., `({ bar, baz }: { bar: string; baz: number })`)
|
|
115
|
+
|
|
116
|
+
The rule allows:
|
|
117
|
+
|
|
118
|
+
- Primitive type annotations (string, number, boolean, etc.)
|
|
119
|
+
- Named types and interfaces
|
|
120
|
+
- Type aliases
|
|
121
|
+
- Functions with no parameters
|
|
122
|
+
- Array types (e.g., `string[]`)
|
|
123
|
+
- Union/intersection types without object literals
|
|
124
|
+
|
|
125
|
+
## When Not To Use It
|
|
126
|
+
|
|
127
|
+
This rule should not be used if you:
|
|
128
|
+
|
|
129
|
+
- Prefer inline types for simple, one-off function parameters
|
|
130
|
+
- Are working with very simple functions that don't benefit from type extraction
|
|
131
|
+
- Have specific code style requirements that favor inline types
|
|
132
|
+
- Are maintaining legacy code with established patterns
|
|
133
|
+
|
|
134
|
+
## Configuration
|
|
135
|
+
|
|
136
|
+
This rule is included in the following configurations:
|
|
137
|
+
|
|
138
|
+
- `nextfriday/base`
|
|
139
|
+
- `nextfriday/base/recommended`
|
|
140
|
+
- `nextfriday/react`
|
|
141
|
+
- `nextfriday/react/recommended`
|
|
142
|
+
- `nextfriday/nextjs`
|
|
143
|
+
- `nextfriday/nextjs/recommended`
|
|
144
|
+
|
|
145
|
+
To enable this rule manually:
|
|
146
|
+
|
|
147
|
+
```json
|
|
148
|
+
{
|
|
149
|
+
"rules": {
|
|
150
|
+
"nextfriday/prefer-named-param-types": "error"
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
```
|
|
154
|
+
|
|
155
|
+
## Relationship to Other Rules
|
|
156
|
+
|
|
157
|
+
This rule complements but differs from `prefer-interface-over-inline-types`:
|
|
158
|
+
|
|
159
|
+
- `prefer-interface-over-inline-types`: Focuses on React component props with complexity criteria
|
|
160
|
+
- `prefer-named-param-types`: Applies to ALL functions with inline object types, regardless of complexity
|
|
161
|
+
|
|
162
|
+
Both rules can be used together for comprehensive type organization.
|
|
163
|
+
|
|
164
|
+
## Compatibility
|
|
165
|
+
|
|
166
|
+
- TypeScript 3.0+ (interface and type alias declarations)
|
|
167
|
+
- ESLint 9+ with flat config
|
|
168
|
+
- Works with all function types in JavaScript/TypeScript
|
|
169
|
+
|
|
170
|
+
## Version
|
|
171
|
+
|
|
172
|
+
This rule was introduced in eslint-plugin-nextfriday v1.2.3.
|
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.3.0",
|
|
44
44
|
description: "A comprehensive ESLint plugin providing custom rules and configurations for Next Friday development workflows.",
|
|
45
45
|
keywords: [
|
|
46
46
|
"eslint",
|
|
@@ -158,7 +158,7 @@ var package_default = {
|
|
|
158
158
|
// src/rules/enforce-readonly-component-props.ts
|
|
159
159
|
var import_utils = require("@typescript-eslint/utils");
|
|
160
160
|
var createRule = import_utils.ESLintUtils.RuleCreator(
|
|
161
|
-
(name) => `https://github.com/next-friday/eslint-plugin-nextfriday/blob/main/docs/rules/${name}.md`
|
|
161
|
+
(name) => `https://github.com/next-friday/eslint-plugin-nextfriday/blob/main/docs/rules/${name.replace(/-/g, "_").toUpperCase()}.md`
|
|
162
162
|
);
|
|
163
163
|
var enforceReadonlyComponentProps = createRule({
|
|
164
164
|
name: "enforce-readonly-component-props",
|
|
@@ -251,7 +251,7 @@ var enforce_readonly_component_props_default = enforceReadonlyComponentProps;
|
|
|
251
251
|
var import_path = __toESM(require("path"), 1);
|
|
252
252
|
var import_utils2 = require("@typescript-eslint/utils");
|
|
253
253
|
var createRule2 = import_utils2.ESLintUtils.RuleCreator(
|
|
254
|
-
(name) => `https://github.com/next-friday/eslint-plugin-nextfriday/blob/main/docs/rules/${name}.md`
|
|
254
|
+
(name) => `https://github.com/next-friday/eslint-plugin-nextfriday/blob/main/docs/rules/${name.replace(/-/g, "_").toUpperCase()}.md`
|
|
255
255
|
);
|
|
256
256
|
var isKebabCase = (str) => {
|
|
257
257
|
if (/\.(config|rc|setup|spec|test)$/.test(str) || /^[a-z0-9]+(?:-[a-z0-9]+)*\.[a-z0-9]+(?:-[a-z0-9]+)*$/.test(str)) {
|
|
@@ -297,7 +297,7 @@ var file_kebab_case_default = fileKebabCase;
|
|
|
297
297
|
var import_path2 = __toESM(require("path"), 1);
|
|
298
298
|
var import_utils3 = require("@typescript-eslint/utils");
|
|
299
299
|
var createRule3 = import_utils3.ESLintUtils.RuleCreator(
|
|
300
|
-
(name) => `https://github.com/next-friday/eslint-plugin-nextfriday/blob/main/docs/rules/${name}.md`
|
|
300
|
+
(name) => `https://github.com/next-friday/eslint-plugin-nextfriday/blob/main/docs/rules/${name.replace(/-/g, "_").toUpperCase()}.md`
|
|
301
301
|
);
|
|
302
302
|
var isPascalCase = (str) => /^[A-Z][a-zA-Z0-9]*$/.test(str) && !/^[A-Z]+$/.test(str);
|
|
303
303
|
var jsxPascalCase = createRule3({
|
|
@@ -338,7 +338,7 @@ var jsx_pascal_case_default = jsxPascalCase;
|
|
|
338
338
|
var import_path3 = __toESM(require("path"), 1);
|
|
339
339
|
var import_utils4 = require("@typescript-eslint/utils");
|
|
340
340
|
var createRule4 = import_utils4.ESLintUtils.RuleCreator(
|
|
341
|
-
(name) => `https://github.com/next-friday/eslint-plugin-nextfriday/blob/main/docs/rules/${name}.md`
|
|
341
|
+
(name) => `https://github.com/next-friday/eslint-plugin-nextfriday/blob/main/docs/rules/${name.replace(/-/g, "_").toUpperCase()}.md`
|
|
342
342
|
);
|
|
343
343
|
var mdFilenameCaseRestriction = createRule4({
|
|
344
344
|
name: "md-filename-case-restriction",
|
|
@@ -384,7 +384,7 @@ var md_filename_case_restriction_default = mdFilenameCaseRestriction;
|
|
|
384
384
|
var import_emoji_regex = __toESM(require("emoji-regex"), 1);
|
|
385
385
|
var import_utils5 = require("@typescript-eslint/utils");
|
|
386
386
|
var createRule5 = import_utils5.ESLintUtils.RuleCreator(
|
|
387
|
-
(name) => `https://github.com/next-friday/eslint-plugin-nextfriday/blob/main/docs/rules/${name}.md`
|
|
387
|
+
(name) => `https://github.com/next-friday/eslint-plugin-nextfriday/blob/main/docs/rules/${name.replace(/-/g, "_").toUpperCase()}.md`
|
|
388
388
|
);
|
|
389
389
|
var noEmoji = createRule5({
|
|
390
390
|
name: "no-emoji",
|
|
@@ -422,7 +422,7 @@ var no_emoji_default = noEmoji;
|
|
|
422
422
|
// src/rules/no-explicit-return-type.ts
|
|
423
423
|
var import_utils6 = require("@typescript-eslint/utils");
|
|
424
424
|
var createRule6 = import_utils6.ESLintUtils.RuleCreator(
|
|
425
|
-
(name) => `https://github.com/next-friday/eslint-plugin-nextfriday/blob/main/docs/rules/${name}.md`
|
|
425
|
+
(name) => `https://github.com/next-friday/eslint-plugin-nextfriday/blob/main/docs/rules/${name.replace(/-/g, "_").toUpperCase()}.md`
|
|
426
426
|
);
|
|
427
427
|
var noExplicitReturnType = createRule6({
|
|
428
428
|
name: "no-explicit-return-type",
|
|
@@ -466,7 +466,7 @@ var no_explicit_return_type_default = noExplicitReturnType;
|
|
|
466
466
|
// src/rules/prefer-destructuring-params.ts
|
|
467
467
|
var import_utils7 = require("@typescript-eslint/utils");
|
|
468
468
|
var createRule7 = import_utils7.ESLintUtils.RuleCreator(
|
|
469
|
-
(name) => `https://github.com/next-friday/eslint-plugin-nextfriday/blob/main/docs/rules/${name}.md`
|
|
469
|
+
(name) => `https://github.com/next-friday/eslint-plugin-nextfriday/blob/main/docs/rules/${name.replace(/-/g, "_").toUpperCase()}.md`
|
|
470
470
|
);
|
|
471
471
|
var preferDestructuringParams = createRule7({
|
|
472
472
|
name: "prefer-destructuring-params",
|
|
@@ -482,11 +482,31 @@ var preferDestructuringParams = createRule7({
|
|
|
482
482
|
},
|
|
483
483
|
defaultOptions: [],
|
|
484
484
|
create(context) {
|
|
485
|
+
const isCallbackFunction = (node) => {
|
|
486
|
+
const { parent } = node;
|
|
487
|
+
return parent?.type === import_utils7.AST_NODE_TYPES.CallExpression;
|
|
488
|
+
};
|
|
489
|
+
const isDeveloperFunction = (node) => {
|
|
490
|
+
if (node.type === import_utils7.AST_NODE_TYPES.FunctionDeclaration) {
|
|
491
|
+
return true;
|
|
492
|
+
}
|
|
493
|
+
if (node.type === import_utils7.AST_NODE_TYPES.FunctionExpression || node.type === import_utils7.AST_NODE_TYPES.ArrowFunctionExpression) {
|
|
494
|
+
if (isCallbackFunction(node)) {
|
|
495
|
+
return false;
|
|
496
|
+
}
|
|
497
|
+
const { parent } = node;
|
|
498
|
+
return parent?.type === import_utils7.AST_NODE_TYPES.VariableDeclarator || parent?.type === import_utils7.AST_NODE_TYPES.AssignmentExpression || parent?.type === import_utils7.AST_NODE_TYPES.Property || parent?.type === import_utils7.AST_NODE_TYPES.MethodDefinition;
|
|
499
|
+
}
|
|
500
|
+
return false;
|
|
501
|
+
};
|
|
485
502
|
const checkFunction = (node) => {
|
|
486
503
|
const { filename } = context;
|
|
487
504
|
if (filename.includes("node_modules") || filename.includes(".d.ts")) {
|
|
488
505
|
return;
|
|
489
506
|
}
|
|
507
|
+
if (!isDeveloperFunction(node)) {
|
|
508
|
+
return;
|
|
509
|
+
}
|
|
490
510
|
if (node.type === import_utils7.AST_NODE_TYPES.FunctionDeclaration && node.id) {
|
|
491
511
|
const functionName = node.id.name;
|
|
492
512
|
if (functionName.startsWith("_") || functionName.includes("$") || /^[A-Z][a-zA-Z]*$/.test(functionName)) {
|
|
@@ -518,7 +538,7 @@ var prefer_destructuring_params_default = preferDestructuringParams;
|
|
|
518
538
|
// src/rules/prefer-import-type.ts
|
|
519
539
|
var import_utils8 = require("@typescript-eslint/utils");
|
|
520
540
|
var createRule8 = import_utils8.ESLintUtils.RuleCreator(
|
|
521
|
-
(name) => `https://github.com/next-friday/eslint-plugin-nextfriday/blob/main/docs/rules/${name}.md`
|
|
541
|
+
(name) => `https://github.com/next-friday/eslint-plugin-nextfriday/blob/main/docs/rules/${name.replace(/-/g, "_").toUpperCase()}.md`
|
|
522
542
|
);
|
|
523
543
|
var preferImportType = createRule8({
|
|
524
544
|
name: "prefer-import-type",
|
|
@@ -588,7 +608,7 @@ var prefer_import_type_default = preferImportType;
|
|
|
588
608
|
// src/rules/prefer-interface-over-inline-types.ts
|
|
589
609
|
var import_utils9 = require("@typescript-eslint/utils");
|
|
590
610
|
var createRule9 = import_utils9.ESLintUtils.RuleCreator(
|
|
591
|
-
(name) => `https://github.com/next-friday/eslint-plugin-nextfriday/blob/main/docs/rules/${name}.md`
|
|
611
|
+
(name) => `https://github.com/next-friday/eslint-plugin-nextfriday/blob/main/docs/rules/${name.replace(/-/g, "_").toUpperCase()}.md`
|
|
592
612
|
);
|
|
593
613
|
var preferInterfaceOverInlineTypes = createRule9({
|
|
594
614
|
name: "prefer-interface-over-inline-types",
|
|
@@ -685,12 +705,74 @@ var preferInterfaceOverInlineTypes = createRule9({
|
|
|
685
705
|
});
|
|
686
706
|
var prefer_interface_over_inline_types_default = preferInterfaceOverInlineTypes;
|
|
687
707
|
|
|
688
|
-
// src/rules/prefer-
|
|
708
|
+
// src/rules/prefer-named-param-types.ts
|
|
689
709
|
var import_utils10 = require("@typescript-eslint/utils");
|
|
690
710
|
var createRule10 = import_utils10.ESLintUtils.RuleCreator(
|
|
691
|
-
(name) => `https://github.com/next-friday/eslint-plugin-nextfriday/blob/main/docs/rules/${name}.md`
|
|
711
|
+
(name) => `https://github.com/next-friday/eslint-plugin-nextfriday/blob/main/docs/rules/${name.replace(/-/g, "_").toUpperCase()}.md`
|
|
692
712
|
);
|
|
693
|
-
var
|
|
713
|
+
var preferNamedParamTypes = createRule10({
|
|
714
|
+
name: "prefer-named-param-types",
|
|
715
|
+
meta: {
|
|
716
|
+
type: "suggestion",
|
|
717
|
+
docs: {
|
|
718
|
+
description: "Enforce named interfaces/types instead of inline object types for function parameters"
|
|
719
|
+
},
|
|
720
|
+
messages: {
|
|
721
|
+
preferNamedParamTypes: "Use a named interface or type for object parameter types instead of inline type annotations"
|
|
722
|
+
},
|
|
723
|
+
schema: []
|
|
724
|
+
},
|
|
725
|
+
defaultOptions: [],
|
|
726
|
+
create(context) {
|
|
727
|
+
function hasInlineObjectType(param) {
|
|
728
|
+
if (param.type === import_utils10.AST_NODE_TYPES.AssignmentPattern) {
|
|
729
|
+
return hasInlineObjectType(param.left);
|
|
730
|
+
}
|
|
731
|
+
if (param.type === import_utils10.AST_NODE_TYPES.ObjectPattern) {
|
|
732
|
+
if (param.typeAnnotation?.typeAnnotation.type === import_utils10.AST_NODE_TYPES.TSTypeLiteral) {
|
|
733
|
+
return true;
|
|
734
|
+
}
|
|
735
|
+
}
|
|
736
|
+
if (param.type === import_utils10.AST_NODE_TYPES.Identifier) {
|
|
737
|
+
if (param.typeAnnotation?.typeAnnotation.type === import_utils10.AST_NODE_TYPES.TSTypeLiteral) {
|
|
738
|
+
return true;
|
|
739
|
+
}
|
|
740
|
+
}
|
|
741
|
+
return false;
|
|
742
|
+
}
|
|
743
|
+
function checkFunction(node) {
|
|
744
|
+
let params = [];
|
|
745
|
+
if ("params" in node) {
|
|
746
|
+
params = node.params;
|
|
747
|
+
} else if ("value" in node && node.value) {
|
|
748
|
+
params = node.value.params;
|
|
749
|
+
}
|
|
750
|
+
params.forEach((param) => {
|
|
751
|
+
if (hasInlineObjectType(param)) {
|
|
752
|
+
context.report({
|
|
753
|
+
node: param,
|
|
754
|
+
messageId: "preferNamedParamTypes"
|
|
755
|
+
});
|
|
756
|
+
}
|
|
757
|
+
});
|
|
758
|
+
}
|
|
759
|
+
return {
|
|
760
|
+
FunctionDeclaration: checkFunction,
|
|
761
|
+
FunctionExpression: checkFunction,
|
|
762
|
+
ArrowFunctionExpression: checkFunction,
|
|
763
|
+
TSMethodSignature: checkFunction,
|
|
764
|
+
MethodDefinition: checkFunction
|
|
765
|
+
};
|
|
766
|
+
}
|
|
767
|
+
});
|
|
768
|
+
var prefer_named_param_types_default = preferNamedParamTypes;
|
|
769
|
+
|
|
770
|
+
// src/rules/prefer-react-import-types.ts
|
|
771
|
+
var import_utils11 = require("@typescript-eslint/utils");
|
|
772
|
+
var createRule11 = import_utils11.ESLintUtils.RuleCreator(
|
|
773
|
+
(name) => `https://github.com/next-friday/eslint-plugin-nextfriday/blob/main/docs/rules/${name.replace(/-/g, "_").toUpperCase()}.md`
|
|
774
|
+
);
|
|
775
|
+
var preferReactImportTypes = createRule11({
|
|
694
776
|
name: "prefer-react-import-types",
|
|
695
777
|
meta: {
|
|
696
778
|
type: "suggestion",
|
|
@@ -766,7 +848,7 @@ var preferReactImportTypes = createRule10({
|
|
|
766
848
|
]);
|
|
767
849
|
const allReactExports = /* @__PURE__ */ new Set([...reactTypes, ...reactRuntimeExports]);
|
|
768
850
|
function checkMemberExpression(node) {
|
|
769
|
-
if (node.object.type ===
|
|
851
|
+
if (node.object.type === import_utils11.AST_NODE_TYPES.Identifier && node.object.name === "React" && node.property.type === import_utils11.AST_NODE_TYPES.Identifier && allReactExports.has(node.property.name)) {
|
|
770
852
|
const typeName = node.property.name;
|
|
771
853
|
const isType = reactTypes.has(typeName);
|
|
772
854
|
const importStatement = isType ? `import type { ${typeName} } from "react"` : `import { ${typeName} } from "react"`;
|
|
@@ -783,7 +865,7 @@ var preferReactImportTypes = createRule10({
|
|
|
783
865
|
return {
|
|
784
866
|
MemberExpression: checkMemberExpression,
|
|
785
867
|
"TSTypeReference > TSQualifiedName": (node) => {
|
|
786
|
-
if (node.left.type ===
|
|
868
|
+
if (node.left.type === import_utils11.AST_NODE_TYPES.Identifier && node.left.name === "React" && node.right.type === import_utils11.AST_NODE_TYPES.Identifier && allReactExports.has(node.right.name)) {
|
|
787
869
|
const typeName = node.right.name;
|
|
788
870
|
const isType = reactTypes.has(typeName);
|
|
789
871
|
const importStatement = isType ? `import type { ${typeName} } from "react"` : `import { ${typeName} } from "react"`;
|
|
@@ -803,11 +885,11 @@ var preferReactImportTypes = createRule10({
|
|
|
803
885
|
var prefer_react_import_types_default = preferReactImportTypes;
|
|
804
886
|
|
|
805
887
|
// src/rules/react-props-destructure.ts
|
|
806
|
-
var
|
|
807
|
-
var
|
|
808
|
-
(name) => `https://github.com/next-friday/eslint-plugin-nextfriday/blob/main/docs/rules/${name}.md`
|
|
888
|
+
var import_utils12 = require("@typescript-eslint/utils");
|
|
889
|
+
var createRule12 = import_utils12.ESLintUtils.RuleCreator(
|
|
890
|
+
(name) => `https://github.com/next-friday/eslint-plugin-nextfriday/blob/main/docs/rules/${name.replace(/-/g, "_").toUpperCase()}.md`
|
|
809
891
|
);
|
|
810
|
-
var reactPropsDestructure =
|
|
892
|
+
var reactPropsDestructure = createRule12({
|
|
811
893
|
name: "react-props-destructure",
|
|
812
894
|
meta: {
|
|
813
895
|
type: "suggestion",
|
|
@@ -823,29 +905,29 @@ var reactPropsDestructure = createRule11({
|
|
|
823
905
|
defaultOptions: [],
|
|
824
906
|
create(context) {
|
|
825
907
|
function hasJSXInConditional(node) {
|
|
826
|
-
return node.consequent.type ===
|
|
908
|
+
return node.consequent.type === import_utils12.AST_NODE_TYPES.JSXElement || node.consequent.type === import_utils12.AST_NODE_TYPES.JSXFragment || node.alternate.type === import_utils12.AST_NODE_TYPES.JSXElement || node.alternate.type === import_utils12.AST_NODE_TYPES.JSXFragment;
|
|
827
909
|
}
|
|
828
910
|
function hasJSXInLogical(node) {
|
|
829
|
-
return node.right.type ===
|
|
911
|
+
return node.right.type === import_utils12.AST_NODE_TYPES.JSXElement || node.right.type === import_utils12.AST_NODE_TYPES.JSXFragment;
|
|
830
912
|
}
|
|
831
913
|
function hasJSXReturn(block) {
|
|
832
914
|
return block.body.some((stmt) => {
|
|
833
|
-
if (stmt.type ===
|
|
834
|
-
return stmt.argument.type ===
|
|
915
|
+
if (stmt.type === import_utils12.AST_NODE_TYPES.ReturnStatement && stmt.argument) {
|
|
916
|
+
return stmt.argument.type === import_utils12.AST_NODE_TYPES.JSXElement || stmt.argument.type === import_utils12.AST_NODE_TYPES.JSXFragment || stmt.argument.type === import_utils12.AST_NODE_TYPES.ConditionalExpression && hasJSXInConditional(stmt.argument) || stmt.argument.type === import_utils12.AST_NODE_TYPES.LogicalExpression && hasJSXInLogical(stmt.argument);
|
|
835
917
|
}
|
|
836
918
|
return false;
|
|
837
919
|
});
|
|
838
920
|
}
|
|
839
921
|
function isReactComponent(node) {
|
|
840
|
-
if (node.type ===
|
|
841
|
-
if (node.body.type ===
|
|
922
|
+
if (node.type === import_utils12.AST_NODE_TYPES.ArrowFunctionExpression) {
|
|
923
|
+
if (node.body.type === import_utils12.AST_NODE_TYPES.JSXElement || node.body.type === import_utils12.AST_NODE_TYPES.JSXFragment) {
|
|
842
924
|
return true;
|
|
843
925
|
}
|
|
844
|
-
if (node.body.type ===
|
|
926
|
+
if (node.body.type === import_utils12.AST_NODE_TYPES.BlockStatement) {
|
|
845
927
|
return hasJSXReturn(node.body);
|
|
846
928
|
}
|
|
847
|
-
} else if (node.type ===
|
|
848
|
-
if (node.body && node.body.type ===
|
|
929
|
+
} else if (node.type === import_utils12.AST_NODE_TYPES.FunctionExpression || node.type === import_utils12.AST_NODE_TYPES.FunctionDeclaration) {
|
|
930
|
+
if (node.body && node.body.type === import_utils12.AST_NODE_TYPES.BlockStatement) {
|
|
849
931
|
return hasJSXReturn(node.body);
|
|
850
932
|
}
|
|
851
933
|
}
|
|
@@ -859,9 +941,9 @@ var reactPropsDestructure = createRule11({
|
|
|
859
941
|
return;
|
|
860
942
|
}
|
|
861
943
|
const param = node.params[0];
|
|
862
|
-
if (param.type ===
|
|
863
|
-
const properties = param.properties.filter((prop) => prop.type ===
|
|
864
|
-
if (prop.key.type ===
|
|
944
|
+
if (param.type === import_utils12.AST_NODE_TYPES.ObjectPattern) {
|
|
945
|
+
const properties = param.properties.filter((prop) => prop.type === import_utils12.AST_NODE_TYPES.Property).map((prop) => {
|
|
946
|
+
if (prop.key.type === import_utils12.AST_NODE_TYPES.Identifier) {
|
|
865
947
|
return prop.key.name;
|
|
866
948
|
}
|
|
867
949
|
return null;
|
|
@@ -902,6 +984,7 @@ var rules = {
|
|
|
902
984
|
"prefer-destructuring-params": prefer_destructuring_params_default,
|
|
903
985
|
"prefer-import-type": prefer_import_type_default,
|
|
904
986
|
"prefer-interface-over-inline-types": prefer_interface_over_inline_types_default,
|
|
987
|
+
"prefer-named-param-types": prefer_named_param_types_default,
|
|
905
988
|
"prefer-react-import-types": prefer_react_import_types_default,
|
|
906
989
|
"react-props-destructure": react_props_destructure_default
|
|
907
990
|
};
|
|
@@ -916,6 +999,7 @@ var baseRules = {
|
|
|
916
999
|
"nextfriday/prefer-destructuring-params": "warn",
|
|
917
1000
|
"nextfriday/no-explicit-return-type": "warn",
|
|
918
1001
|
"nextfriday/prefer-import-type": "warn",
|
|
1002
|
+
"nextfriday/prefer-named-param-types": "warn",
|
|
919
1003
|
"nextfriday/prefer-react-import-types": "warn"
|
|
920
1004
|
};
|
|
921
1005
|
var baseRecommendedRules = {
|
|
@@ -925,6 +1009,7 @@ var baseRecommendedRules = {
|
|
|
925
1009
|
"nextfriday/prefer-destructuring-params": "error",
|
|
926
1010
|
"nextfriday/no-explicit-return-type": "error",
|
|
927
1011
|
"nextfriday/prefer-import-type": "error",
|
|
1012
|
+
"nextfriday/prefer-named-param-types": "error",
|
|
928
1013
|
"nextfriday/prefer-react-import-types": "error"
|
|
929
1014
|
};
|
|
930
1015
|
var jsxRules = {
|