eslint-plugin-nextfriday 4.2.0 → 4.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 +6 -0
- package/README.md +13 -7
- package/docs/rules/ENFORCE_HOOK_FILENAME.md +77 -0
- package/docs/rules/ENFORCE_TEST_FILENAME.md +61 -0
- package/docs/rules/NO_HELPER_FUNCTION_IN_HOOK.md +86 -0
- package/docs/rules/NO_HELPER_FUNCTION_IN_TEST.md +69 -0
- package/lib/index.cjs +729 -550
- package/lib/index.cjs.map +1 -1
- package/lib/index.d.cts +168 -0
- package/lib/index.d.ts +168 -0
- package/lib/index.js +729 -550
- package/lib/index.js.map +1 -1
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,11 @@
|
|
|
1
1
|
# eslint-plugin-nextfriday
|
|
2
2
|
|
|
3
|
+
## 4.3.0
|
|
4
|
+
|
|
5
|
+
### Minor Changes
|
|
6
|
+
|
|
7
|
+
- [#128](https://github.com/next-friday/eslint-plugin-nextfriday/pull/128) [`b165ec5`](https://github.com/next-friday/eslint-plugin-nextfriday/commit/b165ec51eb3ec870a546ab808821426186543356) Thanks [@joetakara](https://github.com/joetakara)! - add enforce-hook-filename, enforce-test-filename, no-helper-function-in-hook, no-helper-function-in-test rules
|
|
8
|
+
|
|
3
9
|
## 4.2.0
|
|
4
10
|
|
|
5
11
|
### Minor Changes
|
package/README.md
CHANGED
|
@@ -413,6 +413,8 @@ In practice: turn the high tier on as `"error"` first, leave the medium tier as
|
|
|
413
413
|
| [require-explicit-return-type](docs/rules/REQUIRE_EXPLICIT_RETURN_TYPE.md) | Require explicit return types on functions for better documentation | ❌ |
|
|
414
414
|
| [no-complex-inline-return](docs/rules/NO_COMPLEX_INLINE_RETURN.md) | Disallow complex inline expressions in return - extract to const first | ❌ |
|
|
415
415
|
| [no-logic-in-params](docs/rules/NO_LOGIC_IN_PARAMS.md) | Disallow logic/conditions in function parameters - extract to const | ❌ |
|
|
416
|
+
| [enforce-hook-filename](docs/rules/ENFORCE_HOOK_FILENAME.md) | Enforce that files exporting custom hooks are named \*.hook.ts | ❌ |
|
|
417
|
+
| [enforce-test-filename](docs/rules/ENFORCE_TEST_FILENAME.md) | Enforce that files containing test code are named \*.test.ts | ❌ |
|
|
416
418
|
| [enforce-hook-naming](docs/rules/ENFORCE_HOOK_NAMING.md) | Enforce 'use' prefix for functions in \*.hook.ts files | ❌ |
|
|
417
419
|
| [enforce-service-naming](docs/rules/ENFORCE_SERVICE_NAMING.md) | Enforce 'fetch' prefix for async functions in \*.service.ts files | ❌ |
|
|
418
420
|
| [enforce-sorted-destructuring](docs/rules/ENFORCE_SORTED_DESTRUCTURING.md) | Enforce alphabetical sorting of destructured properties | ✅ |
|
|
@@ -427,6 +429,8 @@ In practice: turn the high tier on as `"error"` first, leave the medium tier as
|
|
|
427
429
|
| [prefer-async-await](docs/rules/PREFER_ASYNC_AWAIT.md) | Enforce async/await over .then() promise chains | ❌ |
|
|
428
430
|
| [no-nested-ternary](docs/rules/NO_NESTED_TERNARY.md) | Disallow nested ternary expressions | ❌ |
|
|
429
431
|
| [prefer-guard-clause](docs/rules/PREFER_GUARD_CLAUSE.md) | Enforce guard clause pattern instead of nested if statements | ❌ |
|
|
432
|
+
| [no-helper-function-in-hook](docs/rules/NO_HELPER_FUNCTION_IN_HOOK.md) | Disallow non-hook helper function definitions in hook files | ❌ |
|
|
433
|
+
| [no-helper-function-in-test](docs/rules/NO_HELPER_FUNCTION_IN_TEST.md) | Disallow helper function definitions in test files | ❌ |
|
|
430
434
|
|
|
431
435
|
### Import Optimization Rules
|
|
432
436
|
|
|
@@ -485,23 +489,25 @@ In practice: turn the high tier on as `"error"` first, leave the medium tier as
|
|
|
485
489
|
|
|
486
490
|
| Preset | Severity | Base Rules | JSX Rules | Total Rules |
|
|
487
491
|
| -------------------- | -------- | ---------- | --------- | ----------- |
|
|
488
|
-
| `base` | warn |
|
|
489
|
-
| `base/recommended` | error |
|
|
490
|
-
| `react` | warn |
|
|
491
|
-
| `react/recommended` | error |
|
|
492
|
-
| `nextjs` | warn |
|
|
493
|
-
| `nextjs/recommended` | error |
|
|
492
|
+
| `base` | warn | 42 | 0 | 42 |
|
|
493
|
+
| `base/recommended` | error | 42 | 0 | 42 |
|
|
494
|
+
| `react` | warn | 42 | 23 | 65 |
|
|
495
|
+
| `react/recommended` | error | 42 | 23 | 65 |
|
|
496
|
+
| `nextjs` | warn | 42 | 23 | 65 |
|
|
497
|
+
| `nextjs/recommended` | error | 42 | 23 | 65 |
|
|
494
498
|
|
|
495
499
|
The `nextjs` and `nextjs/recommended` presets currently share the same rule set as `react` and `react/recommended`; they are kept as named aliases for ergonomics.
|
|
496
500
|
|
|
497
|
-
### Base Configuration Rules (
|
|
501
|
+
### Base Configuration Rules (42 rules)
|
|
498
502
|
|
|
499
503
|
Included in `base`, `base/recommended`, and all other presets:
|
|
500
504
|
|
|
501
505
|
- `nextfriday/boolean-naming-prefix`
|
|
502
506
|
- `nextfriday/enforce-camel-case`
|
|
503
507
|
- `nextfriday/enforce-constant-case`
|
|
508
|
+
- `nextfriday/enforce-hook-filename`
|
|
504
509
|
- `nextfriday/enforce-hook-naming`
|
|
510
|
+
- `nextfriday/enforce-test-filename`
|
|
505
511
|
- `nextfriday/enforce-property-case`
|
|
506
512
|
- `nextfriday/enforce-service-naming`
|
|
507
513
|
- `nextfriday/enforce-sorted-destructuring`
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
# enforce-hook-filename
|
|
2
|
+
|
|
3
|
+
Enforce that files exporting custom hooks are named `*.hook.ts` or `*.hooks.ts`.
|
|
4
|
+
|
|
5
|
+
## Rule Details
|
|
6
|
+
|
|
7
|
+
Any file that exports a custom hook (a function whose name starts with `use` followed by an uppercase letter) must have a `.hook.ts` or `.hooks.ts` suffix. This ensures hook files are consistently discoverable and that `no-helper-function-in-hook` can be reliably scoped to them.
|
|
8
|
+
|
|
9
|
+
### Why?
|
|
10
|
+
|
|
11
|
+
Without enforced naming, hooks can silently live inside service files, utility files, or component files — breaking the `files` glob that powers `no-helper-function-in-hook` and making codebases harder to navigate.
|
|
12
|
+
|
|
13
|
+
## Examples
|
|
14
|
+
|
|
15
|
+
### Incorrect
|
|
16
|
+
|
|
17
|
+
```ts
|
|
18
|
+
// use-user-data.ts ❌
|
|
19
|
+
export function useUserData() {
|
|
20
|
+
return null;
|
|
21
|
+
}
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
```ts
|
|
25
|
+
// user.service.ts ❌
|
|
26
|
+
export const useCurrentUser = () => null;
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
```ts
|
|
30
|
+
// UserCard.tsx ❌
|
|
31
|
+
export function useUserCard() {
|
|
32
|
+
return null;
|
|
33
|
+
}
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
### Correct
|
|
37
|
+
|
|
38
|
+
```ts
|
|
39
|
+
// use-user-data.hook.ts ✅
|
|
40
|
+
export function useUserData() {
|
|
41
|
+
return null;
|
|
42
|
+
}
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
```ts
|
|
46
|
+
// user.hooks.ts ✅
|
|
47
|
+
export const useCurrentUser = () => null;
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
Re-exporting from an index file is fine — only the file that defines the hook must follow the naming convention:
|
|
51
|
+
|
|
52
|
+
```ts
|
|
53
|
+
// index.ts ✅
|
|
54
|
+
export { useUserData } from "./use-user-data.hook";
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
## What This Rule Checks
|
|
58
|
+
|
|
59
|
+
- `export function useFoo()` — named function declaration export
|
|
60
|
+
- `export const useFoo = () =>` — arrow function export
|
|
61
|
+
- `export const useFoo = function()` — function expression export
|
|
62
|
+
- `export default function useFoo()` — default function declaration export
|
|
63
|
+
|
|
64
|
+
A name is treated as a hook only when it starts with `use` followed by an uppercase letter (e.g. `useData`, not `user` or `use`).
|
|
65
|
+
|
|
66
|
+
## Exceptions
|
|
67
|
+
|
|
68
|
+
Files already named `*.hook.ts` or `*.hooks.ts` are skipped entirely. Re-exports (`export { useFoo } from "..."`) are not flagged.
|
|
69
|
+
|
|
70
|
+
## When Not To Use It
|
|
71
|
+
|
|
72
|
+
Disable per-file if you intentionally co-locate a small hook with its only consumer and do not plan to reuse it.
|
|
73
|
+
|
|
74
|
+
## Related Rules
|
|
75
|
+
|
|
76
|
+
- [enforce-hook-naming](./ENFORCE_HOOK_NAMING.md) — enforces the `use` prefix on functions inside hook files
|
|
77
|
+
- [no-helper-function-in-hook](./NO_HELPER_FUNCTION_IN_HOOK.md) — disallows non-hook helpers inside hook files
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
# enforce-test-filename
|
|
2
|
+
|
|
3
|
+
Enforce that files containing test code are named `*.test.ts` or `*.test.tsx`.
|
|
4
|
+
|
|
5
|
+
## Rule Details
|
|
6
|
+
|
|
7
|
+
Any file that calls test runner globals (`describe`, `it`, `test`, `beforeEach`, `beforeAll`, `afterEach`, `afterAll`) must have a `.test.ts` or `.test.tsx` suffix. Files named `*.spec.ts` or any other pattern are not allowed.
|
|
8
|
+
|
|
9
|
+
### Why?
|
|
10
|
+
|
|
11
|
+
Consistent naming makes test files predictable to find and reliable to target with `files` globs in ESLint configs (e.g. `no-helper-function-in-test`). Mixing `.spec.ts` and `.test.ts` breaks glob-based scoping.
|
|
12
|
+
|
|
13
|
+
## Examples
|
|
14
|
+
|
|
15
|
+
### Incorrect
|
|
16
|
+
|
|
17
|
+
```ts
|
|
18
|
+
// user.spec.ts ❌
|
|
19
|
+
describe("user", () => {
|
|
20
|
+
it("works", () => {});
|
|
21
|
+
});
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
```ts
|
|
25
|
+
// user-tests.ts ❌
|
|
26
|
+
it("works", () => {});
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
### Correct
|
|
30
|
+
|
|
31
|
+
```ts
|
|
32
|
+
// user.test.ts ✅
|
|
33
|
+
describe("user", () => {
|
|
34
|
+
it("works", () => {});
|
|
35
|
+
});
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
```ts
|
|
39
|
+
// UserCard.test.tsx ✅
|
|
40
|
+
test("renders", () => {});
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
## What This Rule Checks
|
|
44
|
+
|
|
45
|
+
Files that contain calls to any of the following globals trigger the requirement:
|
|
46
|
+
|
|
47
|
+
`describe`, `it`, `test`, `beforeEach`, `beforeAll`, `afterEach`, `afterAll`
|
|
48
|
+
|
|
49
|
+
Only one error is reported per file regardless of how many test calls are present.
|
|
50
|
+
|
|
51
|
+
## Exceptions
|
|
52
|
+
|
|
53
|
+
Files already named `*.test.ts` or `*.test.tsx` are skipped entirely.
|
|
54
|
+
|
|
55
|
+
## When Not To Use It
|
|
56
|
+
|
|
57
|
+
Disable if your project intentionally uses `.spec.ts` as the test file convention.
|
|
58
|
+
|
|
59
|
+
## Related Rules
|
|
60
|
+
|
|
61
|
+
- [no-helper-function-in-test](./NO_HELPER_FUNCTION_IN_TEST.md) — disallows helper functions inside test files
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
# no-helper-function-in-hook
|
|
2
|
+
|
|
3
|
+
Disallow non-hook helper function definitions in hook files.
|
|
4
|
+
|
|
5
|
+
## Rule Details
|
|
6
|
+
|
|
7
|
+
Custom hook files should contain only the hook function itself (prefixed with `use`) and its supporting constants. Utility functions that are not hooks must be extracted to a separate file and imported.
|
|
8
|
+
|
|
9
|
+
### Why?
|
|
10
|
+
|
|
11
|
+
Helper functions defined inside a hook file are invisible to the rest of the codebase, cannot be tested independently, and are harder to reuse. Keeping hook files focused on a single hook makes them easier to read and maintain.
|
|
12
|
+
|
|
13
|
+
## Examples
|
|
14
|
+
|
|
15
|
+
### Incorrect
|
|
16
|
+
|
|
17
|
+
```ts
|
|
18
|
+
function buildQueryKey(id: string): string {
|
|
19
|
+
return `item-${id}`;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
export function useItemData(id: string) {
|
|
23
|
+
const key = buildQueryKey(id);
|
|
24
|
+
// ...
|
|
25
|
+
}
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
```ts
|
|
29
|
+
const formatResponse = (data: unknown) => data;
|
|
30
|
+
|
|
31
|
+
export const useItemData = (id: string) => {
|
|
32
|
+
// ...
|
|
33
|
+
};
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
### Correct
|
|
37
|
+
|
|
38
|
+
```ts
|
|
39
|
+
import { buildQueryKey } from "./item.utils";
|
|
40
|
+
|
|
41
|
+
export function useItemData(id: string) {
|
|
42
|
+
const key = buildQueryKey(id);
|
|
43
|
+
// ...
|
|
44
|
+
}
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
Functions defined inside the hook body are fine:
|
|
48
|
+
|
|
49
|
+
```ts
|
|
50
|
+
export function useItemData(id: string) {
|
|
51
|
+
function buildQueryKey() {
|
|
52
|
+
return `item-${id}`;
|
|
53
|
+
}
|
|
54
|
+
// ...
|
|
55
|
+
}
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
## What This Rule Checks
|
|
59
|
+
|
|
60
|
+
- Top-level `function` declarations whose name does not start with `use`
|
|
61
|
+
- Top-level `const`/`let`/`var` declarations assigned an arrow function or function expression whose name does not start with `use`
|
|
62
|
+
|
|
63
|
+
Both plain and `export`-prefixed declarations are checked.
|
|
64
|
+
|
|
65
|
+
## Exceptions
|
|
66
|
+
|
|
67
|
+
- Hook functions starting with `use` are allowed at the top level
|
|
68
|
+
- Functions defined inside a hook body are not flagged
|
|
69
|
+
- Non-function constants (strings, numbers, arrays, objects) are not flagged
|
|
70
|
+
|
|
71
|
+
## When Not To Use It
|
|
72
|
+
|
|
73
|
+
This rule should be scoped to hook files using the ESLint `files` glob:
|
|
74
|
+
|
|
75
|
+
```js
|
|
76
|
+
{
|
|
77
|
+
files: ["**/*.hook.ts", "**/*.hooks.ts"],
|
|
78
|
+
rules: {
|
|
79
|
+
"nextfriday/no-helper-function-in-hook": "error",
|
|
80
|
+
},
|
|
81
|
+
}
|
|
82
|
+
```
|
|
83
|
+
|
|
84
|
+
## Related Rules
|
|
85
|
+
|
|
86
|
+
- [enforce-hook-naming](./ENFORCE_HOOK_NAMING.md) — enforces the `use` prefix on all functions in hook files
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
# no-helper-function-in-test
|
|
2
|
+
|
|
3
|
+
Disallow helper function definitions in test files.
|
|
4
|
+
|
|
5
|
+
## Rule Details
|
|
6
|
+
|
|
7
|
+
Test files should contain only pure test code — `describe`, `it`, `test`, `beforeEach`, and similar test runner constructs. Helper functions defined at the top level of a test file are utility code that belongs in a separate file and should be imported.
|
|
8
|
+
|
|
9
|
+
### Why?
|
|
10
|
+
|
|
11
|
+
When helper functions are defined inside test files, they become invisible to other tests and are harder to maintain, test independently, and reuse. Keeping test files free of utility logic makes them easier to read and reason about.
|
|
12
|
+
|
|
13
|
+
## Examples
|
|
14
|
+
|
|
15
|
+
### Incorrect
|
|
16
|
+
|
|
17
|
+
```ts
|
|
18
|
+
function findTemplateFiles(directory: string): string[] {
|
|
19
|
+
// ...
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
const extractImports = (source: string): string[] => {
|
|
23
|
+
// ...
|
|
24
|
+
};
|
|
25
|
+
|
|
26
|
+
describe("template imports", () => {
|
|
27
|
+
it("must only import from allowed paths", () => {
|
|
28
|
+
// ...
|
|
29
|
+
});
|
|
30
|
+
});
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
### Correct
|
|
34
|
+
|
|
35
|
+
```ts
|
|
36
|
+
import { findTemplateFiles, extractImports } from "./test-utils";
|
|
37
|
+
|
|
38
|
+
describe("template imports", () => {
|
|
39
|
+
it("must only import from allowed paths", () => {
|
|
40
|
+
// ...
|
|
41
|
+
});
|
|
42
|
+
});
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
## What This Rule Checks
|
|
46
|
+
|
|
47
|
+
- Top-level `function` declarations
|
|
48
|
+
- Top-level `const`/`let`/`var` declarations assigned an arrow function or function expression
|
|
49
|
+
|
|
50
|
+
Constants that are not functions (regex patterns, arrays, objects) are allowed.
|
|
51
|
+
|
|
52
|
+
## Exceptions
|
|
53
|
+
|
|
54
|
+
Functions declared inside `describe`, `it`, `test`, `beforeEach`, or other callback bodies are not flagged.
|
|
55
|
+
|
|
56
|
+
## When Not To Use It
|
|
57
|
+
|
|
58
|
+
Disable this rule for files that are intentionally test utility modules (e.g., `test-utils.ts`, `helpers.ts`) rather than test suite files.
|
|
59
|
+
|
|
60
|
+
This rule should be scoped to test files using the ESLint `files` glob:
|
|
61
|
+
|
|
62
|
+
```js
|
|
63
|
+
{
|
|
64
|
+
files: ["**/*.test.ts", "**/*.spec.ts", "**/*.test.tsx", "**/*.spec.tsx"],
|
|
65
|
+
rules: {
|
|
66
|
+
"nextfriday/no-helper-function-in-test": "error",
|
|
67
|
+
},
|
|
68
|
+
}
|
|
69
|
+
```
|