eslint-plugin-th-rules 2.7.1 → 3.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/README.md +171 -11
- package/dist/configs/bundles/recommended-react.d.ts +199 -0
- package/dist/configs/bundles/recommended-react.js +11 -0
- package/dist/configs/bundles/recommended-typescript.d.ts +190 -0
- package/dist/configs/bundles/recommended-typescript.js +6 -0
- package/dist/configs/bundles/recommended.d.ts +190 -0
- package/dist/configs/bundles/recommended.js +8 -0
- package/dist/configs/core/base.d.ts +170 -0
- package/dist/configs/core/base.js +23 -0
- package/dist/configs/core/react.d.ts +6 -0
- package/dist/configs/core/react.js +8 -0
- package/dist/configs/core/typescript.d.ts +2 -0
- package/dist/configs/core/typescript.js +19 -0
- package/dist/configs/externals/base.d.ts +15 -0
- package/dist/configs/externals/base.js +16 -0
- package/dist/configs/externals/opinionated.d.ts +10 -0
- package/dist/configs/externals/opinionated.js +12 -0
- package/dist/index.d.ts +1170 -0
- package/dist/index.js +21 -0
- package/dist/plugin.d.ts +5 -0
- package/dist/plugin.js +14 -0
- package/dist/rules/no-boolean-coercion.d.ts +5 -0
- package/dist/rules/no-boolean-coercion.js +98 -0
- package/dist/rules/no-comments.d.ts +11 -0
- package/dist/rules/no-comments.js +83 -0
- package/dist/rules/no-default-export.d.ts +5 -0
- package/dist/rules/no-default-export.js +61 -0
- package/dist/rules/no-destructuring.d.ts +8 -0
- package/dist/rules/no-destructuring.js +121 -0
- package/dist/rules/prefer-is-empty.d.ts +5 -0
- package/dist/rules/prefer-is-empty.js +101 -0
- package/dist/rules/schemas-in-schemas-file.d.ts +9 -0
- package/dist/rules/schemas-in-schemas-file.js +141 -0
- package/dist/rules/top-level-functions.d.ts +5 -0
- package/dist/rules/top-level-functions.js +153 -0
- package/dist/rules/types-in-dts.d.ts +8 -0
- package/dist/rules/types-in-dts.js +76 -0
- package/package.json +25 -14
- package/.github/dependabot.yml +0 -15
- package/.github/workflows/codecov.yml +0 -26
- package/.github/workflows/codeql.yml +0 -82
- package/.github/workflows/dependency-review.yml +0 -20
- package/.github/workflows/main.yml +0 -43
- package/.github/workflows/scorecard.yml +0 -72
- package/.github/workflows/snyk-security.yml +0 -67
- package/.releaserc +0 -13
- package/.vscode/settings.json +0 -8
- package/.yarn/releases/yarn-4.12.0.cjs +0 -942
- package/.yarnrc.yml +0 -3
- package/CHANGELOG.md +0 -628
- package/SECURITY.md +0 -48
- package/docs/rules/no-boolean-coercion.md +0 -9
- package/docs/rules/no-comments.md +0 -50
- package/docs/rules/no-default-export.md +0 -26
- package/docs/rules/no-destructuring.md +0 -40
- package/docs/rules/prefer-is-empty.md +0 -9
- package/docs/rules/schemas-in-schemas-file.md +0 -170
- package/docs/rules/top-level-functions.md +0 -48
- package/docs/rules/types-in-dts.md +0 -112
- package/renovate.json +0 -3
- package/scripts/verify.mjs +0 -16
- package/src/index.js +0 -144
- package/src/rules/no-boolean-coercion.js +0 -124
- package/src/rules/no-comments.js +0 -94
- package/src/rules/no-default-export.js +0 -64
- package/src/rules/no-destructuring.js +0 -114
- package/src/rules/prefer-is-empty.js +0 -104
- package/src/rules/schemas-in-schemas-file.js +0 -191
- package/src/rules/top-level-functions.js +0 -200
- package/src/rules/types-in-dts.js +0 -94
- package/tests/no-boolean-coercion.test.ts +0 -83
- package/tests/prefer-is-empty.test.ts +0 -148
- package/tsconfig.json +0 -22
- package/xo.config.ts +0 -2
|
@@ -1,9 +0,0 @@
|
|
|
1
|
-
# th-rules/no-boolean-coercion
|
|
2
|
-
|
|
3
|
-
📝 Disallow Boolean(value) or !!value. Enforce _.isNil(value) for scalar values and _.isEmpty(value) for strings, arrays, and objects.
|
|
4
|
-
|
|
5
|
-
💼 This rule is enabled in the following configs: ✅ `recommended`, ⚛️ `recommended-react`, 🟦 `recommended-typescript`.
|
|
6
|
-
|
|
7
|
-
💡 This rule is manually fixable by [editor suggestions](https://eslint.org/docs/latest/use/core-concepts#rule-suggestions).
|
|
8
|
-
|
|
9
|
-
<!-- end auto-generated rule header -->
|
|
@@ -1,50 +0,0 @@
|
|
|
1
|
-
# th-rules/no-comments
|
|
2
|
-
|
|
3
|
-
📝 Disallow comments except for specified allowed patterns.
|
|
4
|
-
|
|
5
|
-
💼 This rule is enabled in the following configs: ✅ `recommended`, ⚛️ `recommended-react`, 🟦 `recommended-typescript`.
|
|
6
|
-
|
|
7
|
-
🔧 This rule is automatically fixable by the [`--fix` CLI option](https://eslint.org/docs/latest/user-guide/command-line-interface#--fix).
|
|
8
|
-
|
|
9
|
-
<!-- end auto-generated rule header -->
|
|
10
|
-
|
|
11
|
-
## Options
|
|
12
|
-
|
|
13
|
-
<!-- begin auto-generated rule options list -->
|
|
14
|
-
|
|
15
|
-
| Name | Description | Type |
|
|
16
|
-
| :--------- | :------------------------------------------- | :------- |
|
|
17
|
-
| `allow` | Additional patterns to allow in comments. | String[] |
|
|
18
|
-
| `disallow` | Additional patterns to disallow in comments. | String[] |
|
|
19
|
-
|
|
20
|
-
<!-- end auto-generated rule options list -->
|
|
21
|
-
|
|
22
|
-
## Description
|
|
23
|
-
|
|
24
|
-
This rule disallows comments unless they match specified allowed patterns. It ensures that only relevant and permitted comments are present in the codebase, such as TODOs, warnings, JSDoc comments, ESLint directives, etc.
|
|
25
|
-
|
|
26
|
-
## Rule Details
|
|
27
|
-
|
|
28
|
-
By default, the following comments are allowed:
|
|
29
|
-
|
|
30
|
-
- TODO, WARNING, ERROR, INFO (case-insensitive).
|
|
31
|
-
- ESLint directives like `/* eslint-disable */`.
|
|
32
|
-
- JSDoc comments (any comment starting with `/**`).
|
|
33
|
-
|
|
34
|
-
You can also configure additional patterns to allow or disallow specific types of comments.
|
|
35
|
-
|
|
36
|
-
## Usage
|
|
37
|
-
|
|
38
|
-
```json
|
|
39
|
-
{
|
|
40
|
-
"rules": {
|
|
41
|
-
"th-rules/no-comments": [
|
|
42
|
-
"error",
|
|
43
|
-
{
|
|
44
|
-
"allow": ["keep", "important"],
|
|
45
|
-
"disallow": ["deprecated", "hack"]
|
|
46
|
-
}
|
|
47
|
-
]
|
|
48
|
-
}
|
|
49
|
-
}
|
|
50
|
-
```
|
|
@@ -1,26 +0,0 @@
|
|
|
1
|
-
# th-rules/no-default-export
|
|
2
|
-
|
|
3
|
-
📝 Convert unnamed default exports to named default exports based on the file name.
|
|
4
|
-
|
|
5
|
-
💼 This rule is enabled in the following configs: ✅ `recommended`, ⚛️ `recommended-react`, 🟦 `recommended-typescript`.
|
|
6
|
-
|
|
7
|
-
🔧 This rule is automatically fixable by the [`--fix` CLI option](https://eslint.org/docs/latest/user-guide/command-line-interface#--fix).
|
|
8
|
-
|
|
9
|
-
<!-- end auto-generated rule header -->
|
|
10
|
-
|
|
11
|
-
## Description
|
|
12
|
-
|
|
13
|
-
Converts unnamed default exports to named default exports based on the file name. This rule helps maintain consistency in export names and facilitates easier identification of components or modules.
|
|
14
|
-
|
|
15
|
-
## Rule Details
|
|
16
|
-
|
|
17
|
-
This rule targets unnamed default exports and automatically generates a named export based on the file name.
|
|
18
|
-
|
|
19
|
-
## Usage
|
|
20
|
-
```json
|
|
21
|
-
{
|
|
22
|
-
"rules": {
|
|
23
|
-
"no-default-export": "error"
|
|
24
|
-
}
|
|
25
|
-
}
|
|
26
|
-
```
|
|
@@ -1,40 +0,0 @@
|
|
|
1
|
-
# th-rules/no-destructuring
|
|
2
|
-
|
|
3
|
-
📝 Disallow destructuring that does not meet certain conditions.
|
|
4
|
-
|
|
5
|
-
💼 This rule is enabled in the following configs: ✅ `recommended`, ⚛️ `recommended-react`, 🟦 `recommended-typescript`.
|
|
6
|
-
|
|
7
|
-
<!-- end auto-generated rule header -->
|
|
8
|
-
|
|
9
|
-
## Options
|
|
10
|
-
|
|
11
|
-
<!-- begin auto-generated rule options list -->
|
|
12
|
-
|
|
13
|
-
| Name | Type |
|
|
14
|
-
| :----------------------------- | :------ |
|
|
15
|
-
| `maximumDestructuredVariables` | Integer |
|
|
16
|
-
| `maximumLineLength` | Integer |
|
|
17
|
-
|
|
18
|
-
<!-- end auto-generated rule options list -->
|
|
19
|
-
|
|
20
|
-
## Description
|
|
21
|
-
|
|
22
|
-
This rule disallows destructuring that does not meet certain conditions, aiming to prevent overly complex destructuring patterns and ensure code readability.
|
|
23
|
-
|
|
24
|
-
## Rule Details
|
|
25
|
-
|
|
26
|
-
This rule checks for:
|
|
27
|
-
|
|
28
|
-
- Destructuring at a nesting level above 3.
|
|
29
|
-
- Destructuring of more than the specified maximum number of variables (default is 2).
|
|
30
|
-
- Destructuring on a line exceeding the specified maximum line length (default is 100 characters).
|
|
31
|
-
|
|
32
|
-
## Usage
|
|
33
|
-
|
|
34
|
-
```json
|
|
35
|
-
{
|
|
36
|
-
"rules": {
|
|
37
|
-
"th-rules/no-destructuring": ["error", { "maximumDestructuredVariables": 2, "maximumLineLength": 100 }]
|
|
38
|
-
}
|
|
39
|
-
}
|
|
40
|
-
```
|
|
@@ -1,9 +0,0 @@
|
|
|
1
|
-
# th-rules/prefer-is-empty
|
|
2
|
-
|
|
3
|
-
📝 Require _.isEmpty instead of length comparisons.
|
|
4
|
-
|
|
5
|
-
💼 This rule is enabled in the following configs: ✅ `recommended`, ⚛️ `recommended-react`, 🟦 `recommended-typescript`.
|
|
6
|
-
|
|
7
|
-
💡 This rule is manually fixable by [editor suggestions](https://eslint.org/docs/latest/use/core-concepts#rule-suggestions).
|
|
8
|
-
|
|
9
|
-
<!-- end auto-generated rule header -->
|
|
@@ -1,170 +0,0 @@
|
|
|
1
|
-
# th-rules/schemas-in-schemas-file
|
|
2
|
-
|
|
3
|
-
📝 Require Zod schema declarations to be placed in a .schemas.ts file.
|
|
4
|
-
|
|
5
|
-
💼 This rule is enabled in the following configs: ✅ `recommended`, ⚛️ `recommended-react`, 🟦 `recommended-typescript`.
|
|
6
|
-
|
|
7
|
-
<!-- end auto-generated rule header -->
|
|
8
|
-
|
|
9
|
-
💼 This rule is enabled in the following configs: ✅ `recommended`, `recommended-react`, `recommended-typescript`.
|
|
10
|
-
|
|
11
|
-
<!-- end auto-generated rule header -->
|
|
12
|
-
|
|
13
|
-
This rule enforces that Zod schema **declarations** are defined in dedicated schema files (by default: `.schemas.ts` / `.schemas.tsx`), rather than inside implementation/component files.
|
|
14
|
-
|
|
15
|
-
The intent is to keep business logic and UI code focused, while consolidating validation/contract definitions into a predictable location.
|
|
16
|
-
|
|
17
|
-
## Rationale
|
|
18
|
-
|
|
19
|
-
Keeping Zod schemas in dedicated files:
|
|
20
|
-
- reduces noise in implementation files (especially components and services),
|
|
21
|
-
- encourages reuse of validation contracts across the codebase,
|
|
22
|
-
- improves review quality by keeping diffs focused (schema changes vs logic changes),
|
|
23
|
-
- standardizes file layout in larger projects and monorepos.
|
|
24
|
-
|
|
25
|
-
## What the rule reports
|
|
26
|
-
|
|
27
|
-
The rule reports Zod “schema builder” calls (e.g. `z.object(...)`, `z.string()`, `z.enum(...)`, `z.coerce.number()`, etc.) in files that do **not** match one of the allowed suffixes.
|
|
28
|
-
|
|
29
|
-
By default, it identifies Zod usage by tracking imports from `'zod'` (e.g. `import { z } from 'zod'`, `import { z as zod } from 'zod'`, `import * as zod from 'zod'`).
|
|
30
|
-
|
|
31
|
-
## Examples
|
|
32
|
-
|
|
33
|
-
### ❌ Incorrect
|
|
34
|
-
|
|
35
|
-
```ts
|
|
36
|
-
// ArticleCard.tsx
|
|
37
|
-
import {z} from 'zod';
|
|
38
|
-
|
|
39
|
-
const articleSchema = z.object({
|
|
40
|
-
id: z.string(),
|
|
41
|
-
title: z.string().min(1),
|
|
42
|
-
});
|
|
43
|
-
```
|
|
44
|
-
|
|
45
|
-
```ts
|
|
46
|
-
// user.ts
|
|
47
|
-
import {z as zod} from 'zod';
|
|
48
|
-
|
|
49
|
-
export const userSchema = zod.object({
|
|
50
|
-
email: zod.string().email(),
|
|
51
|
-
});
|
|
52
|
-
```
|
|
53
|
-
|
|
54
|
-
### ✅ Correct
|
|
55
|
-
|
|
56
|
-
```ts
|
|
57
|
-
// ArticleCard.schemas.ts
|
|
58
|
-
import {z} from 'zod';
|
|
59
|
-
|
|
60
|
-
export const articleSchema = z.object({
|
|
61
|
-
id: z.string(),
|
|
62
|
-
title: z.string().min(1),
|
|
63
|
-
});
|
|
64
|
-
```
|
|
65
|
-
|
|
66
|
-
```ts
|
|
67
|
-
// ArticleCard.tsx
|
|
68
|
-
import {articleSchema} from './ArticleCard.schemas';
|
|
69
|
-
|
|
70
|
-
export function ArticleCard() {
|
|
71
|
-
// articleSchema is used here (validation, inference, etc.)
|
|
72
|
-
return null;
|
|
73
|
-
}
|
|
74
|
-
```
|
|
75
|
-
|
|
76
|
-
### Allowed usage (always allowed)
|
|
77
|
-
|
|
78
|
-
Using schemas and type inference is allowed anywhere:
|
|
79
|
-
|
|
80
|
-
```ts
|
|
81
|
-
import type {z} from 'zod';
|
|
82
|
-
import {articleSchema} from './ArticleCard.schemas';
|
|
83
|
-
|
|
84
|
-
export type Article = z.infer<typeof articleSchema>;
|
|
85
|
-
```
|
|
86
|
-
|
|
87
|
-
## Options
|
|
88
|
-
|
|
89
|
-
<!-- begin auto-generated rule options list -->
|
|
90
|
-
|
|
91
|
-
| Name | Type |
|
|
92
|
-
| :----------------- | :------- |
|
|
93
|
-
| `allowedSuffixes` | String[] |
|
|
94
|
-
| `allowInTests` | Boolean |
|
|
95
|
-
| `onlyWhenAssigned` | Boolean |
|
|
96
|
-
|
|
97
|
-
<!-- end auto-generated rule options list -->
|
|
98
|
-
|
|
99
|
-
### `allowedSuffixes`
|
|
100
|
-
|
|
101
|
-
An array of filename suffixes that are allowed to contain Zod schema declarations.
|
|
102
|
-
|
|
103
|
-
Default:
|
|
104
|
-
- `.schemas.ts`
|
|
105
|
-
- `.schemas.tsx`
|
|
106
|
-
|
|
107
|
-
Example:
|
|
108
|
-
|
|
109
|
-
```json
|
|
110
|
-
{
|
|
111
|
-
"rules": {
|
|
112
|
-
"th-rules/schemas-in-schemas-file": ["error", {
|
|
113
|
-
"allowedSuffixes": [".schemas.ts", ".schemas.tsx", ".validation.ts"]
|
|
114
|
-
}]
|
|
115
|
-
}
|
|
116
|
-
}
|
|
117
|
-
```
|
|
118
|
-
|
|
119
|
-
### `allowInTests`
|
|
120
|
-
|
|
121
|
-
When set to `true`, the rule allows Zod schema declarations in common test file patterns (e.g. `*.test.ts`, `*.spec.ts`, `*.test.tsx`, `*.spec.tsx`).
|
|
122
|
-
|
|
123
|
-
Default: `false`
|
|
124
|
-
|
|
125
|
-
Example:
|
|
126
|
-
|
|
127
|
-
```json
|
|
128
|
-
{
|
|
129
|
-
"rules": {
|
|
130
|
-
"th-rules/schemas-in-schemas-file": ["error", {
|
|
131
|
-
"allowInTests": true
|
|
132
|
-
}]
|
|
133
|
-
}
|
|
134
|
-
}
|
|
135
|
-
```
|
|
136
|
-
|
|
137
|
-
### `onlyWhenAssigned`
|
|
138
|
-
|
|
139
|
-
When set to `true`, the rule reports only Zod schema builder calls that are assigned to a variable (or assigned via `=`), for example:
|
|
140
|
-
|
|
141
|
-
```ts
|
|
142
|
-
const userSchema = z.object({ ... });
|
|
143
|
-
userSchema = z.object({ ... });
|
|
144
|
-
```
|
|
145
|
-
|
|
146
|
-
If set to `false` (default), the rule reports any Zod schema builder call found in a non-allowed file, including inline schemas:
|
|
147
|
-
|
|
148
|
-
```ts
|
|
149
|
-
foo(z.object({ ... }));
|
|
150
|
-
```
|
|
151
|
-
|
|
152
|
-
Default: `false`
|
|
153
|
-
|
|
154
|
-
Example:
|
|
155
|
-
|
|
156
|
-
```json
|
|
157
|
-
{
|
|
158
|
-
"rules": {
|
|
159
|
-
"th-rules/schemas-in-schemas-file": ["error", {
|
|
160
|
-
"onlyWhenAssigned": true
|
|
161
|
-
}]
|
|
162
|
-
}
|
|
163
|
-
}
|
|
164
|
-
```
|
|
165
|
-
|
|
166
|
-
## Notes
|
|
167
|
-
|
|
168
|
-
- This rule is filename-based; it enforces a convention rather than performing semantic analysis.
|
|
169
|
-
- The rule does not auto-fix, as moving schemas across files safely (and updating imports) is not generally safe to automate.
|
|
170
|
-
- If you define Zod builders through wrappers (e.g. `createSchema(...)` that internally calls Zod), this rule will not detect those unless extended to match your helper patterns.
|
|
@@ -1,48 +0,0 @@
|
|
|
1
|
-
# th-rules/top-level-functions
|
|
2
|
-
|
|
3
|
-
📝 Require all top-level functions to be named/regular functions.
|
|
4
|
-
|
|
5
|
-
💼 This rule is enabled in the following configs: ✅ `recommended`, ⚛️ `recommended-react`, 🟦 `recommended-typescript`.
|
|
6
|
-
|
|
7
|
-
🔧 This rule is automatically fixable by the [`--fix` CLI option](https://eslint.org/docs/latest/user-guide/command-line-interface#--fix).
|
|
8
|
-
|
|
9
|
-
<!-- end auto-generated rule header -->
|
|
10
|
-
|
|
11
|
-
## Description
|
|
12
|
-
|
|
13
|
-
This rule requires all top-level functions to be named/regular functions, preventing the use of arrow functions at the top level. This rule aims to improve code readability and maintainability by enforcing consistent function declaration styles.
|
|
14
|
-
|
|
15
|
-
## Rule Details
|
|
16
|
-
|
|
17
|
-
This rule checks for arrow functions at the top level and reports them as errors.
|
|
18
|
-
|
|
19
|
-
Examples of **incorrect** code for this rule:
|
|
20
|
-
|
|
21
|
-
```js
|
|
22
|
-
const myFunction = () => {
|
|
23
|
-
// Function body
|
|
24
|
-
};
|
|
25
|
-
```
|
|
26
|
-
|
|
27
|
-
Examples of **correct** code for this rule:
|
|
28
|
-
|
|
29
|
-
```js
|
|
30
|
-
function myFunction() {
|
|
31
|
-
// Function body
|
|
32
|
-
}
|
|
33
|
-
```
|
|
34
|
-
|
|
35
|
-
## Usage
|
|
36
|
-
|
|
37
|
-
```json
|
|
38
|
-
{
|
|
39
|
-
"rules": {
|
|
40
|
-
"th-rules/top-level-functions": "error"
|
|
41
|
-
}
|
|
42
|
-
}
|
|
43
|
-
```
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
## When Not To Use It
|
|
47
|
-
|
|
48
|
-
If you do not want to enforce consistent function declaration styles, you can disable this rule.
|
|
@@ -1,112 +0,0 @@
|
|
|
1
|
-
# th-rules/types-in-dts
|
|
2
|
-
|
|
3
|
-
📝 Require TypeScript type declarations (type/interface/enum) to be placed in .d.ts files.
|
|
4
|
-
|
|
5
|
-
💼 This rule is enabled in the following configs: ✅ `recommended`, ⚛️ `recommended-react`, 🟦 `recommended-typescript`.
|
|
6
|
-
|
|
7
|
-
<!-- end auto-generated rule header -->
|
|
8
|
-
|
|
9
|
-
💼 This rule is enabled in the following configs: ✅ `recommended`, `recommended-react`, `recommended-typescript`.
|
|
10
|
-
|
|
11
|
-
<!-- end auto-generated rule header -->
|
|
12
|
-
|
|
13
|
-
This rule enforces a strict separation between **runtime code** and **type declarations** by requiring all top-level TypeScript type declarations to be defined in `.d.ts` files.
|
|
14
|
-
|
|
15
|
-
The rule applies to:
|
|
16
|
-
- `type` aliases
|
|
17
|
-
- `interface` declarations
|
|
18
|
-
- `enum` declarations
|
|
19
|
-
|
|
20
|
-
Any of these constructs declared outside of a `.d.ts` file will be reported, unless explicitly allowed via configuration.
|
|
21
|
-
|
|
22
|
-
## Rationale
|
|
23
|
-
|
|
24
|
-
Keeping type declarations in `.d.ts` files provides several benefits:
|
|
25
|
-
|
|
26
|
-
- Enforces a clean architectural boundary between runtime logic and type definitions
|
|
27
|
-
- Improves file readability by reducing noise in implementation files
|
|
28
|
-
- Encourages intentional, centralized ownership of public and shared types
|
|
29
|
-
- Prevents accidental runtime coupling with type-only constructs
|
|
30
|
-
- Aligns well with library-oriented or API-driven codebases
|
|
31
|
-
|
|
32
|
-
This rule is especially useful in large TypeScript projects, shared packages, or monorepos where type contracts are meant to be consumed independently of implementation.
|
|
33
|
-
|
|
34
|
-
## Examples
|
|
35
|
-
|
|
36
|
-
### ❌ Incorrect
|
|
37
|
-
|
|
38
|
-
```ts
|
|
39
|
-
// user.ts
|
|
40
|
-
type UserId = string;
|
|
41
|
-
|
|
42
|
-
interface User {
|
|
43
|
-
id: UserId;
|
|
44
|
-
name: string;
|
|
45
|
-
}
|
|
46
|
-
|
|
47
|
-
enum Role {
|
|
48
|
-
Admin,
|
|
49
|
-
User,
|
|
50
|
-
}
|
|
51
|
-
```
|
|
52
|
-
|
|
53
|
-
### ✅ Correct
|
|
54
|
-
|
|
55
|
-
```ts
|
|
56
|
-
// user.d.ts
|
|
57
|
-
type UserId = string;
|
|
58
|
-
|
|
59
|
-
interface User {
|
|
60
|
-
id: UserId;
|
|
61
|
-
name: string;
|
|
62
|
-
}
|
|
63
|
-
|
|
64
|
-
enum Role {
|
|
65
|
-
Admin,
|
|
66
|
-
User,
|
|
67
|
-
}
|
|
68
|
-
```
|
|
69
|
-
|
|
70
|
-
```ts
|
|
71
|
-
// user.ts
|
|
72
|
-
import type { User, UserId, Role } from './user';
|
|
73
|
-
```
|
|
74
|
-
|
|
75
|
-
### Allowed usage
|
|
76
|
-
|
|
77
|
-
Using types, interfaces, or enums is always allowed in any file:
|
|
78
|
-
|
|
79
|
-
```ts
|
|
80
|
-
function getUser(id: UserId): User {
|
|
81
|
-
// ...
|
|
82
|
-
}
|
|
83
|
-
```
|
|
84
|
-
|
|
85
|
-
## Options
|
|
86
|
-
|
|
87
|
-
<!-- begin auto-generated rule options list -->
|
|
88
|
-
|
|
89
|
-
| Name | Type |
|
|
90
|
-
| :------------- | :------ |
|
|
91
|
-
| `allowDeclare` | Boolean |
|
|
92
|
-
| `allowEnums` | Boolean |
|
|
93
|
-
|
|
94
|
-
<!-- end auto-generated rule options list -->
|
|
95
|
-
|
|
96
|
-
### `allowDeclare`
|
|
97
|
-
|
|
98
|
-
When set to `true`, the rule allows `declare` type declarations in non-`.d.ts` files.
|
|
99
|
-
|
|
100
|
-
This is useful when working with ambient declarations, global augmentations, or compatibility shims that must live alongside implementation code.
|
|
101
|
-
|
|
102
|
-
### `allowEnums`
|
|
103
|
-
|
|
104
|
-
When set to `true`, the rule allows `enum` declarations in non-`.d.ts` files.
|
|
105
|
-
|
|
106
|
-
This can be helpful in codebases that rely on runtime enums while still wanting to enforce `.d.ts` placement for interfaces and type aliases.
|
|
107
|
-
|
|
108
|
-
## Notes
|
|
109
|
-
|
|
110
|
-
- This rule does not enforce how types are imported or re-exported.
|
|
111
|
-
- It does not attempt to auto-fix violations, as moving declarations across files is not safe to do automatically.
|
|
112
|
-
- The rule operates purely at the syntax level and does not require type information.
|
package/renovate.json
DELETED
package/scripts/verify.mjs
DELETED
|
@@ -1,16 +0,0 @@
|
|
|
1
|
-
import {ESLint} from 'eslint';
|
|
2
|
-
import thRules from '../src/index.js';
|
|
3
|
-
|
|
4
|
-
const run = async (name, config) => {
|
|
5
|
-
const eslint = new ESLint({
|
|
6
|
-
overrideConfigFile: true,
|
|
7
|
-
overrideConfig: config,
|
|
8
|
-
});
|
|
9
|
-
|
|
10
|
-
const results = await eslint.lintText('const x = 1;\n', {filePath: 'fixtures/test.js'});
|
|
11
|
-
console.log(`OK: ${name} (${results[0].messages.length} messages)`);
|
|
12
|
-
};
|
|
13
|
-
|
|
14
|
-
await run('recommended', thRules.configs.recommended);
|
|
15
|
-
await run('recommended-typescript', thRules.configs['recommended-typescript']);
|
|
16
|
-
await run('recommended-react', thRules.configs['recommended-react']);
|
package/src/index.js
DELETED
|
@@ -1,144 +0,0 @@
|
|
|
1
|
-
/* eslint-disable import-x/order */
|
|
2
|
-
/* eslint-disable n/no-path-concat */
|
|
3
|
-
/* eslint-disable unicorn/prefer-module */
|
|
4
|
-
|
|
5
|
-
'use strict';
|
|
6
|
-
|
|
7
|
-
const requireIndex = require('requireindex');
|
|
8
|
-
const globals = require('globals');
|
|
9
|
-
const {FlatCompat} = require('@eslint/eslintrc');
|
|
10
|
-
const reactPlugin = require('eslint-plugin-react');
|
|
11
|
-
const reactHooks = require('eslint-plugin-react-hooks');
|
|
12
|
-
const tseslint = require('typescript-eslint');
|
|
13
|
-
const lodashPlugin = require('eslint-plugin-lodash');
|
|
14
|
-
|
|
15
|
-
const nPlugin = require('eslint-plugin-n');
|
|
16
|
-
const sonarjsPlugin = require('eslint-plugin-sonarjs');
|
|
17
|
-
const securityPlugin = require('eslint-plugin-security');
|
|
18
|
-
|
|
19
|
-
const plugin = {
|
|
20
|
-
rules: requireIndex(`${__dirname}/rules`),
|
|
21
|
-
configs: {},
|
|
22
|
-
};
|
|
23
|
-
|
|
24
|
-
// Flattens configs so we never embed arrays inside arrays (avoids "Unexpected key '0'")
|
|
25
|
-
const asArray = value => (Array.isArray(value) ? value : [value]);
|
|
26
|
-
const flatConfigs = (...items) => items.flatMap(element => asArray(element));
|
|
27
|
-
|
|
28
|
-
// Converts legacy "extends"/eslintrc configs into flat config objects
|
|
29
|
-
const compat = new FlatCompat({
|
|
30
|
-
baseDirectory: __dirname,
|
|
31
|
-
});
|
|
32
|
-
|
|
33
|
-
const baseRecommended = {
|
|
34
|
-
plugins: {
|
|
35
|
-
// Local rules
|
|
36
|
-
'th-rules': plugin,
|
|
37
|
-
|
|
38
|
-
// Third-party plugins used by rule names below
|
|
39
|
-
n: nPlugin,
|
|
40
|
-
sonarjs: sonarjsPlugin,
|
|
41
|
-
security: securityPlugin,
|
|
42
|
-
lodash: lodashPlugin,
|
|
43
|
-
|
|
44
|
-
// Included so consumers can use react/react-hooks rules as well
|
|
45
|
-
react: reactPlugin,
|
|
46
|
-
'react-hooks': reactHooks,
|
|
47
|
-
},
|
|
48
|
-
languageOptions: {
|
|
49
|
-
ecmaVersion: 2024,
|
|
50
|
-
sourceType: 'module',
|
|
51
|
-
globals: {
|
|
52
|
-
...globals.node,
|
|
53
|
-
...globals.es2024,
|
|
54
|
-
...globals.jest,
|
|
55
|
-
},
|
|
56
|
-
},
|
|
57
|
-
settings: {
|
|
58
|
-
react: {version: 'detect'},
|
|
59
|
-
lodash: {version: 4, pragma: '_'},
|
|
60
|
-
},
|
|
61
|
-
rules: {
|
|
62
|
-
'th-rules/no-destructuring': 'error',
|
|
63
|
-
'th-rules/no-default-export': 'error',
|
|
64
|
-
'th-rules/no-comments': 'error',
|
|
65
|
-
'th-rules/top-level-functions': 'error',
|
|
66
|
-
'th-rules/schemas-in-schemas-file': 'error',
|
|
67
|
-
'th-rules/types-in-dts': 'error',
|
|
68
|
-
'th-rules/no-boolean-coercion': 'error',
|
|
69
|
-
'th-rules/prefer-is-empty': 'error',
|
|
70
|
-
'unicorn/filename-case': 'off',
|
|
71
|
-
'unicorn/no-array-callback-reference': 'off',
|
|
72
|
-
'import/extensions': 'off',
|
|
73
|
-
'unicorn/no-static-only-class': 'off',
|
|
74
|
-
'unicorn/no-await-expression-member': 'off',
|
|
75
|
-
'new-cap': 'off',
|
|
76
|
-
'no-await-in-loop': 'off',
|
|
77
|
-
'n/file-extension-in-import': 'off',
|
|
78
|
-
'n/prefer-global/buffer': 'off',
|
|
79
|
-
'n/prefer-global/process': 'off',
|
|
80
|
-
'import/no-cycle': 'off',
|
|
81
|
-
camelcase: 'warn',
|
|
82
|
-
'sonarjs/mouse-events-a11y': 'off',
|
|
83
|
-
'sonarjs/no-unstable-nested-components': 'off',
|
|
84
|
-
'unicorn/prefer-global-this': 'off',
|
|
85
|
-
'unicorn/no-thenable': 'off',
|
|
86
|
-
'sonarjs/no-clear-text-protocols': 'off',
|
|
87
|
-
'security/detect-unsafe-regex': 'off',
|
|
88
|
-
'lodash/import-scope': [2, 'full'],
|
|
89
|
-
'@typescript-eslint/ban-types': 'off',
|
|
90
|
-
'@typescript-eslint/naming-convention': 'off',
|
|
91
|
-
'@typescript-eslint/no-restricted-types': 'off',
|
|
92
|
-
'import-x/extensions': 'off',
|
|
93
|
-
'lodash/chaining': ['error', 'implicit'],
|
|
94
|
-
},
|
|
95
|
-
};
|
|
96
|
-
|
|
97
|
-
/** @type {import('eslint').Linter.FlatConfig[]} */
|
|
98
|
-
plugin.configs.recommended = flatConfigs(
|
|
99
|
-
// Legacy configs -> convert them
|
|
100
|
-
compat.extends('plugin:sonarjs/recommended-legacy', 'plugin:security/recommended-legacy', 'plugin:lodash/recommended'),
|
|
101
|
-
baseRecommended,
|
|
102
|
-
);
|
|
103
|
-
|
|
104
|
-
plugin.configs['recommended-typescript'] = flatConfigs(
|
|
105
|
-
plugin.configs.recommended,
|
|
106
|
-
|
|
107
|
-
// Typescript-eslint exports flat configs (arrays of flat config objects)
|
|
108
|
-
tseslint.configs.strictTypeChecked,
|
|
109
|
-
tseslint.configs.stylisticTypeChecked,
|
|
110
|
-
|
|
111
|
-
{
|
|
112
|
-
languageOptions: {
|
|
113
|
-
parserOptions: {
|
|
114
|
-
projectService: true,
|
|
115
|
-
},
|
|
116
|
-
},
|
|
117
|
-
rules: {
|
|
118
|
-
'@typescript-eslint/consistent-type-definitions': 'off',
|
|
119
|
-
'@typescript-eslint/no-extraneous-class': 'off',
|
|
120
|
-
'@typescript-eslint/no-duplicate-type-constituents': 'off',
|
|
121
|
-
'@typescript-eslint/no-non-null-assertion': 'off',
|
|
122
|
-
'@typescript-eslint/require-await': 'off',
|
|
123
|
-
'@typescript-eslint/no-unsafe-member-access': 'off',
|
|
124
|
-
'@typescript-eslint/no-unsafe-call': 'off',
|
|
125
|
-
'@typescript-eslint/no-unsafe-return': 'off',
|
|
126
|
-
'@typescript-eslint/no-unsafe-argument': 'off',
|
|
127
|
-
},
|
|
128
|
-
},
|
|
129
|
-
);
|
|
130
|
-
|
|
131
|
-
plugin.configs['recommended-react'] = flatConfigs(
|
|
132
|
-
plugin.configs.recommended,
|
|
133
|
-
compat.extends('plugin:react/recommended'),
|
|
134
|
-
compat.extends('plugin:react/jsx-runtime'),
|
|
135
|
-
compat.extends('plugin:react-hooks/recommended'),
|
|
136
|
-
{
|
|
137
|
-
rules: {
|
|
138
|
-
'n/prefer-global/process': 'off',
|
|
139
|
-
'react-hooks/set-state-in-effect': 'off',
|
|
140
|
-
},
|
|
141
|
-
},
|
|
142
|
-
);
|
|
143
|
-
|
|
144
|
-
module.exports = plugin;
|