@yasainet/eslint 0.0.3 → 0.0.5
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 +22 -14
- package/package.json +5 -1
- package/src/common/constants.mjs +3 -8
- package/src/common/imports.mjs +20 -13
- package/src/common/index.mjs +14 -11
- package/src/common/jsdoc.mjs +36 -33
- package/src/common/layers.mjs +36 -33
- package/src/common/naming.mjs +137 -132
- package/src/deno/index.d.mts +3 -0
- package/src/deno/index.mjs +5 -0
- package/src/next/index.mjs +4 -2
- package/src/next/naming.mjs +2 -3
- package/src/node/index.mjs +2 -2
package/README.md
CHANGED
|
@@ -8,34 +8,42 @@ Shared ESLint configuration for feature-based architecture.
|
|
|
8
8
|
npm install -D @yasainet/eslint eslint
|
|
9
9
|
```
|
|
10
10
|
|
|
11
|
-
##
|
|
11
|
+
## Entry Points
|
|
12
|
+
|
|
13
|
+
| Entry | Feature Root | Description |
|
|
14
|
+
| ----------------------- | ------------------------------ | ----------------------------------------------------------------------------------- |
|
|
15
|
+
| `@yasainet/eslint/next` | `src/features/` | Common rules + Next.js-specific rules (hooks, components, directives, lib-boundary) |
|
|
16
|
+
| `@yasainet/eslint/node` | `scripts/features/` | Common rules only |
|
|
17
|
+
| `@yasainet/eslint/deno` | `supabase/functions/features/` | Common rules only |
|
|
12
18
|
|
|
13
|
-
|
|
19
|
+
## Usage
|
|
14
20
|
|
|
15
21
|
```js
|
|
16
22
|
// eslint.config.mjs
|
|
23
|
+
import { eslintConfig as nextEslintConfig } from "@yasainet/eslint/next";
|
|
24
|
+
import { eslintConfig as nodeEslintConfig } from "@yasainet/eslint/node";
|
|
25
|
+
import { eslintConfig as denoEslintConfig } from "@yasainet/eslint/deno";
|
|
17
26
|
import { defineConfig, globalIgnores } from "eslint/config";
|
|
18
27
|
import nextVitals from "eslint-config-next/core-web-vitals";
|
|
19
28
|
import nextTs from "eslint-config-next/typescript";
|
|
20
|
-
import { eslintConfig } from "@yasainet/eslint/next";
|
|
21
29
|
|
|
22
30
|
export default defineConfig([
|
|
23
31
|
...nextVitals,
|
|
24
32
|
...nextTs,
|
|
25
|
-
|
|
26
|
-
|
|
33
|
+
// Override default ignores of eslint-config-next.
|
|
34
|
+
globalIgnores([
|
|
35
|
+
// Default ignores of eslint-config-next:
|
|
36
|
+
".next/**",
|
|
37
|
+
"out/**",
|
|
38
|
+
"build/**",
|
|
39
|
+
"next-env.d.ts",
|
|
40
|
+
]),
|
|
41
|
+
...nextEslintConfig,
|
|
42
|
+
...nodeEslintConfig,
|
|
43
|
+
...denoEslintConfig,
|
|
27
44
|
]);
|
|
28
45
|
```
|
|
29
46
|
|
|
30
|
-
### Node.js
|
|
31
|
-
|
|
32
|
-
```js
|
|
33
|
-
// eslint.config.mjs
|
|
34
|
-
import { eslintConfig } from "@yasainet/eslint/node";
|
|
35
|
-
|
|
36
|
-
export default eslintConfig;
|
|
37
|
-
```
|
|
38
|
-
|
|
39
47
|
## Release
|
|
40
48
|
|
|
41
49
|
1. Update `version` in `package.json`
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@yasainet/eslint",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.5",
|
|
4
4
|
"description": "ESLint",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"exports": {
|
|
@@ -11,6 +11,10 @@
|
|
|
11
11
|
"./node": {
|
|
12
12
|
"types": "./src/node/index.d.mts",
|
|
13
13
|
"default": "./src/node/index.mjs"
|
|
14
|
+
},
|
|
15
|
+
"./deno": {
|
|
16
|
+
"types": "./src/deno/index.d.mts",
|
|
17
|
+
"default": "./src/deno/index.mjs"
|
|
14
18
|
}
|
|
15
19
|
},
|
|
16
20
|
"files": [
|
package/src/common/constants.mjs
CHANGED
|
@@ -20,12 +20,6 @@ function findProjectRoot() {
|
|
|
20
20
|
|
|
21
21
|
const PROJECT_ROOT = findProjectRoot();
|
|
22
22
|
|
|
23
|
-
export const FEATURE_ROOTS = [
|
|
24
|
-
"src/features",
|
|
25
|
-
"scripts/features",
|
|
26
|
-
"supabase/functions/features",
|
|
27
|
-
];
|
|
28
|
-
|
|
29
23
|
const EXCLUDE_LIST = ["proxy.ts", "types"];
|
|
30
24
|
|
|
31
25
|
function generatePrefixLibMapping() {
|
|
@@ -68,5 +62,6 @@ function generatePrefixLibMapping() {
|
|
|
68
62
|
|
|
69
63
|
export const PREFIX_LIB_MAPPING = generatePrefixLibMapping();
|
|
70
64
|
|
|
71
|
-
export const featuresGlob = (subpath) =>
|
|
72
|
-
|
|
65
|
+
export const featuresGlob = (featureRoot, subpath) => [
|
|
66
|
+
`${featureRoot}/${subpath}`,
|
|
67
|
+
];
|
package/src/common/imports.mjs
CHANGED
|
@@ -112,22 +112,31 @@ function makeConfig(name, files, ...patternArrays) {
|
|
|
112
112
|
};
|
|
113
113
|
}
|
|
114
114
|
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
configs.push({
|
|
115
|
+
/** @description Next.js-only: restrict @/lib imports to repositories */
|
|
116
|
+
export const libBoundaryConfigs = [
|
|
117
|
+
{
|
|
119
118
|
name: "imports/lib-boundary",
|
|
120
119
|
files: ["src/**/*.{ts,tsx}"],
|
|
121
|
-
ignores: [
|
|
120
|
+
ignores: [
|
|
121
|
+
"src/lib/**",
|
|
122
|
+
"src/proxy.ts",
|
|
123
|
+
"src/app/sitemap.ts",
|
|
124
|
+
"src/features/**/repositories/**",
|
|
125
|
+
],
|
|
122
126
|
rules: {
|
|
123
127
|
"no-restricted-imports": ["error", { patterns: LIB_BOUNDARY_PATTERNS }],
|
|
124
128
|
},
|
|
125
|
-
}
|
|
129
|
+
},
|
|
130
|
+
];
|
|
131
|
+
|
|
132
|
+
/** @description Scope import restriction rules to the given feature root */
|
|
133
|
+
export function createImportsConfigs(featureRoot) {
|
|
134
|
+
const configs = [];
|
|
126
135
|
|
|
127
136
|
configs.push(
|
|
128
137
|
makeConfig(
|
|
129
138
|
"repositories",
|
|
130
|
-
[
|
|
139
|
+
[`${featureRoot}/**/repositories/*.ts`],
|
|
131
140
|
LAYER_PATTERNS.repositories,
|
|
132
141
|
LATERAL_PATTERNS.repositories,
|
|
133
142
|
),
|
|
@@ -139,7 +148,7 @@ function generateImportConfigs() {
|
|
|
139
148
|
configs.push(
|
|
140
149
|
makeConfig(
|
|
141
150
|
`repositories/${prefix}`,
|
|
142
|
-
[
|
|
151
|
+
[`${featureRoot}/**/repositories/${prefix}.repo.ts`],
|
|
143
152
|
LAYER_PATTERNS.repositories,
|
|
144
153
|
LATERAL_PATTERNS.repositories,
|
|
145
154
|
patterns,
|
|
@@ -150,7 +159,7 @@ function generateImportConfigs() {
|
|
|
150
159
|
configs.push(
|
|
151
160
|
makeConfig(
|
|
152
161
|
"services",
|
|
153
|
-
[
|
|
162
|
+
[`${featureRoot}/**/services/*.ts`],
|
|
154
163
|
LAYER_PATTERNS.services,
|
|
155
164
|
LATERAL_PATTERNS.services,
|
|
156
165
|
LIB_BOUNDARY_PATTERNS,
|
|
@@ -160,7 +169,7 @@ function generateImportConfigs() {
|
|
|
160
169
|
configs.push(
|
|
161
170
|
makeConfig(
|
|
162
171
|
"actions",
|
|
163
|
-
[
|
|
172
|
+
[`${featureRoot}/**/actions/*.ts`],
|
|
164
173
|
LAYER_PATTERNS.actions,
|
|
165
174
|
LATERAL_PATTERNS.actions,
|
|
166
175
|
LIB_BOUNDARY_PATTERNS,
|
|
@@ -171,7 +180,7 @@ function generateImportConfigs() {
|
|
|
171
180
|
configs.push(
|
|
172
181
|
makeConfig(
|
|
173
182
|
`actions/${prefix}`,
|
|
174
|
-
[
|
|
183
|
+
[`${featureRoot}/**/actions/${prefix}.action.ts`],
|
|
175
184
|
LAYER_PATTERNS.actions,
|
|
176
185
|
LATERAL_PATTERNS.actions,
|
|
177
186
|
CARDINALITY_PATTERNS[prefix],
|
|
@@ -182,5 +191,3 @@ function generateImportConfigs() {
|
|
|
182
191
|
|
|
183
192
|
return configs.filter(Boolean);
|
|
184
193
|
}
|
|
185
|
-
|
|
186
|
-
export const importsConfigs = generateImportConfigs();
|
package/src/common/index.mjs
CHANGED
|
@@ -1,13 +1,16 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
1
|
+
import { createImportsConfigs } from "./imports.mjs";
|
|
2
|
+
import { createJsdocConfigs } from "./jsdoc.mjs";
|
|
3
|
+
import { createLayersConfigs } from "./layers.mjs";
|
|
4
|
+
import { createNamingConfigs } from "./naming.mjs";
|
|
5
5
|
import { rulesConfigs } from "./rules.mjs";
|
|
6
6
|
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
7
|
+
/** @description Build common configs scoped to the given feature root */
|
|
8
|
+
export function createCommonConfigs(featureRoot) {
|
|
9
|
+
return [
|
|
10
|
+
...rulesConfigs,
|
|
11
|
+
...createNamingConfigs(featureRoot),
|
|
12
|
+
...createLayersConfigs(featureRoot),
|
|
13
|
+
...createImportsConfigs(featureRoot),
|
|
14
|
+
...createJsdocConfigs(featureRoot),
|
|
15
|
+
];
|
|
16
|
+
}
|
package/src/common/jsdoc.mjs
CHANGED
|
@@ -2,38 +2,41 @@ import jsdocPlugin from "eslint-plugin-jsdoc";
|
|
|
2
2
|
|
|
3
3
|
import { featuresGlob } from "./constants.mjs";
|
|
4
4
|
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
jsdoc: jsdocPlugin,
|
|
15
|
-
},
|
|
16
|
-
rules: {
|
|
17
|
-
"jsdoc/require-jsdoc": [
|
|
18
|
-
"warn",
|
|
19
|
-
{
|
|
20
|
-
publicOnly: true,
|
|
21
|
-
require: {
|
|
22
|
-
FunctionDeclaration: true,
|
|
23
|
-
ArrowFunctionExpression: true,
|
|
24
|
-
FunctionExpression: true,
|
|
25
|
-
},
|
|
26
|
-
checkGetters: false,
|
|
27
|
-
checkSetters: false,
|
|
28
|
-
checkConstructors: false,
|
|
29
|
-
},
|
|
30
|
-
],
|
|
31
|
-
"jsdoc/require-description": [
|
|
32
|
-
"warn",
|
|
33
|
-
{
|
|
34
|
-
contexts: ["any"],
|
|
35
|
-
},
|
|
5
|
+
/** @description Scope JSDoc rules to the given feature root */
|
|
6
|
+
export function createJsdocConfigs(featureRoot) {
|
|
7
|
+
return [
|
|
8
|
+
{
|
|
9
|
+
name: "jsdoc",
|
|
10
|
+
files: [
|
|
11
|
+
...featuresGlob(featureRoot, "**/repositories/*.ts"),
|
|
12
|
+
...featuresGlob(featureRoot, "**/services*/*.ts"),
|
|
13
|
+
...featuresGlob(featureRoot, "**/utils*/*.ts"),
|
|
36
14
|
],
|
|
15
|
+
plugins: {
|
|
16
|
+
jsdoc: jsdocPlugin,
|
|
17
|
+
},
|
|
18
|
+
rules: {
|
|
19
|
+
"jsdoc/require-jsdoc": [
|
|
20
|
+
"warn",
|
|
21
|
+
{
|
|
22
|
+
publicOnly: true,
|
|
23
|
+
require: {
|
|
24
|
+
FunctionDeclaration: true,
|
|
25
|
+
ArrowFunctionExpression: true,
|
|
26
|
+
FunctionExpression: true,
|
|
27
|
+
},
|
|
28
|
+
checkGetters: false,
|
|
29
|
+
checkSetters: false,
|
|
30
|
+
checkConstructors: false,
|
|
31
|
+
},
|
|
32
|
+
],
|
|
33
|
+
"jsdoc/require-description": [
|
|
34
|
+
"warn",
|
|
35
|
+
{
|
|
36
|
+
contexts: ["any"],
|
|
37
|
+
},
|
|
38
|
+
],
|
|
39
|
+
},
|
|
37
40
|
},
|
|
38
|
-
|
|
39
|
-
|
|
41
|
+
];
|
|
42
|
+
}
|
package/src/common/layers.mjs
CHANGED
|
@@ -1,35 +1,38 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
1
|
+
/** @description Scope layer rules to the given feature root */
|
|
2
|
+
export function createLayersConfigs(featureRoot) {
|
|
3
|
+
return [
|
|
4
|
+
{
|
|
5
|
+
name: "layers/repositories",
|
|
6
|
+
files: [`${featureRoot}/**/repositories/*.ts`],
|
|
7
|
+
rules: {
|
|
8
|
+
"no-restricted-syntax": [
|
|
9
|
+
"error",
|
|
10
|
+
{
|
|
11
|
+
selector: "TryStatement",
|
|
12
|
+
message:
|
|
13
|
+
"try-catch is not allowed in repositories. Error handling belongs in actions.",
|
|
14
|
+
},
|
|
15
|
+
{
|
|
16
|
+
selector: "IfStatement",
|
|
17
|
+
message:
|
|
18
|
+
"if statements are not allowed in repositories. Conditional logic belongs in services.",
|
|
19
|
+
},
|
|
20
|
+
],
|
|
21
|
+
},
|
|
19
22
|
},
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
23
|
+
{
|
|
24
|
+
name: "layers/services",
|
|
25
|
+
files: [`${featureRoot}/**/services/*.ts`],
|
|
26
|
+
rules: {
|
|
27
|
+
"no-restricted-syntax": [
|
|
28
|
+
"error",
|
|
29
|
+
{
|
|
30
|
+
selector: "TryStatement",
|
|
31
|
+
message:
|
|
32
|
+
"try-catch is not allowed in services. Error handling belongs in actions.",
|
|
33
|
+
},
|
|
34
|
+
],
|
|
35
|
+
},
|
|
33
36
|
},
|
|
34
|
-
|
|
35
|
-
|
|
37
|
+
];
|
|
38
|
+
}
|
package/src/common/naming.mjs
CHANGED
|
@@ -4,147 +4,152 @@ import { actionHandleServiceRule } from "./local-plugins/action-handle-service.m
|
|
|
4
4
|
|
|
5
5
|
const prefixPattern = `@(${Object.keys(PREFIX_LIB_MAPPING).join("|")})`;
|
|
6
6
|
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
"check-file
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
7
|
+
/** @description Scope naming rules to the given feature root */
|
|
8
|
+
export function createNamingConfigs(featureRoot) {
|
|
9
|
+
return [
|
|
10
|
+
{
|
|
11
|
+
name: "naming/services",
|
|
12
|
+
files: featuresGlob(featureRoot, "**/services/*.ts"),
|
|
13
|
+
plugins: { "check-file": checkFile },
|
|
14
|
+
rules: {
|
|
15
|
+
"check-file/filename-naming-convention": [
|
|
16
|
+
"error",
|
|
17
|
+
{ "**/*.ts": `${prefixPattern}.service` },
|
|
18
|
+
],
|
|
19
|
+
},
|
|
17
20
|
},
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
21
|
+
{
|
|
22
|
+
name: "naming/repositories",
|
|
23
|
+
files: featuresGlob(featureRoot, "**/repositories/*.ts"),
|
|
24
|
+
plugins: { "check-file": checkFile },
|
|
25
|
+
rules: {
|
|
26
|
+
"check-file/filename-naming-convention": [
|
|
27
|
+
"error",
|
|
28
|
+
{ "**/*.ts": `${prefixPattern}.repo` },
|
|
29
|
+
],
|
|
30
|
+
},
|
|
28
31
|
},
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
32
|
+
{
|
|
33
|
+
name: "naming/types",
|
|
34
|
+
files: featuresGlob(featureRoot, "*/types/*.type.ts"),
|
|
35
|
+
ignores: featuresGlob(featureRoot, "shared/types/*.ts"),
|
|
36
|
+
plugins: { "check-file": checkFile },
|
|
37
|
+
rules: {
|
|
38
|
+
"check-file/filename-naming-convention": [
|
|
39
|
+
"error",
|
|
40
|
+
{ "**/*/types/*.ts": "<1>" },
|
|
41
|
+
{ ignoreMiddleExtensions: true },
|
|
42
|
+
],
|
|
43
|
+
},
|
|
41
44
|
},
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
45
|
+
{
|
|
46
|
+
name: "naming/types-shared",
|
|
47
|
+
files: featuresGlob(featureRoot, "shared/types/*.ts"),
|
|
48
|
+
plugins: { "check-file": checkFile },
|
|
49
|
+
rules: {
|
|
50
|
+
"check-file/filename-naming-convention": [
|
|
51
|
+
"error",
|
|
52
|
+
{ "**/*.ts": "+([a-z0-9_-]).type" },
|
|
53
|
+
],
|
|
54
|
+
},
|
|
52
55
|
},
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
56
|
+
{
|
|
57
|
+
name: "naming/schemas",
|
|
58
|
+
files: featuresGlob(featureRoot, "**/schemas/*.ts"),
|
|
59
|
+
plugins: { "check-file": checkFile },
|
|
60
|
+
rules: {
|
|
61
|
+
"check-file/filename-naming-convention": [
|
|
62
|
+
"error",
|
|
63
|
+
{ "**/*.ts": "+([a-z0-9-]).schema" },
|
|
64
|
+
],
|
|
65
|
+
},
|
|
63
66
|
},
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
67
|
+
{
|
|
68
|
+
name: "naming/utils",
|
|
69
|
+
files: featuresGlob(featureRoot, "*/utils/*.util.ts"),
|
|
70
|
+
ignores: featuresGlob(featureRoot, "shared/utils/*.ts"),
|
|
71
|
+
plugins: { "check-file": checkFile },
|
|
72
|
+
rules: {
|
|
73
|
+
"check-file/filename-naming-convention": [
|
|
74
|
+
"error",
|
|
75
|
+
{ "**/*/utils/*.ts": "<1>" },
|
|
76
|
+
{ ignoreMiddleExtensions: true },
|
|
77
|
+
],
|
|
78
|
+
},
|
|
76
79
|
},
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
80
|
+
{
|
|
81
|
+
name: "naming/utils-shared",
|
|
82
|
+
files: featuresGlob(featureRoot, "shared/utils/*.ts"),
|
|
83
|
+
plugins: { "check-file": checkFile },
|
|
84
|
+
rules: {
|
|
85
|
+
"check-file/filename-naming-convention": [
|
|
86
|
+
"error",
|
|
87
|
+
{ "**/*.ts": "+([a-z0-9_-]).util" },
|
|
88
|
+
],
|
|
89
|
+
},
|
|
87
90
|
},
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
91
|
+
{
|
|
92
|
+
name: "naming/constants",
|
|
93
|
+
files: featuresGlob(featureRoot, "**/constants/*.ts"),
|
|
94
|
+
plugins: { "check-file": checkFile },
|
|
95
|
+
rules: {
|
|
96
|
+
"check-file/filename-naming-convention": [
|
|
97
|
+
"error",
|
|
98
|
+
{ "**/*.ts": "+([a-z0-9-]).constant" },
|
|
99
|
+
],
|
|
100
|
+
},
|
|
98
101
|
},
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
102
|
+
{
|
|
103
|
+
name: "naming/actions",
|
|
104
|
+
files: featuresGlob(featureRoot, "**/actions/*.ts"),
|
|
105
|
+
plugins: { "check-file": checkFile },
|
|
106
|
+
rules: {
|
|
107
|
+
"check-file/filename-naming-convention": [
|
|
108
|
+
"error",
|
|
109
|
+
{ "**/*.ts": `${prefixPattern}.action` },
|
|
110
|
+
],
|
|
111
|
+
},
|
|
109
112
|
},
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
},
|
|
125
|
-
},
|
|
126
|
-
{
|
|
127
|
-
name: "naming/actions-handle-service",
|
|
128
|
-
files: featuresGlob("**/actions/*.ts"),
|
|
129
|
-
plugins: {
|
|
130
|
-
local: { rules: { "action-handle-service": actionHandleServiceRule } },
|
|
113
|
+
{
|
|
114
|
+
name: "naming/actions-export",
|
|
115
|
+
files: featuresGlob(featureRoot, "**/actions/*.ts"),
|
|
116
|
+
rules: {
|
|
117
|
+
"no-restricted-syntax": [
|
|
118
|
+
"error",
|
|
119
|
+
{
|
|
120
|
+
selector:
|
|
121
|
+
"ExportNamedDeclaration > FunctionDeclaration[id.name!=/^handle[A-Z]/]",
|
|
122
|
+
message:
|
|
123
|
+
"Exported functions in actions must start with 'handle' (e.g., handleGetComics).",
|
|
124
|
+
},
|
|
125
|
+
],
|
|
126
|
+
},
|
|
131
127
|
},
|
|
132
|
-
|
|
133
|
-
"
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
files: featuresGlob("**/*.tsx"),
|
|
139
|
-
rules: {
|
|
140
|
-
"no-restricted-syntax": [
|
|
141
|
-
"error",
|
|
142
|
-
{
|
|
143
|
-
selector: "Program",
|
|
144
|
-
message:
|
|
145
|
-
"features/ must only contain .ts files. Components belong in src/components/.",
|
|
128
|
+
{
|
|
129
|
+
name: "naming/actions-handle-service",
|
|
130
|
+
files: featuresGlob(featureRoot, "**/actions/*.ts"),
|
|
131
|
+
plugins: {
|
|
132
|
+
local: {
|
|
133
|
+
rules: { "action-handle-service": actionHandleServiceRule },
|
|
146
134
|
},
|
|
147
|
-
|
|
135
|
+
},
|
|
136
|
+
rules: {
|
|
137
|
+
"local/action-handle-service": "error",
|
|
138
|
+
},
|
|
139
|
+
},
|
|
140
|
+
{
|
|
141
|
+
name: "naming/features-ts-only",
|
|
142
|
+
files: featuresGlob(featureRoot, "**/*.tsx"),
|
|
143
|
+
rules: {
|
|
144
|
+
"no-restricted-syntax": [
|
|
145
|
+
"error",
|
|
146
|
+
{
|
|
147
|
+
selector: "Program",
|
|
148
|
+
message:
|
|
149
|
+
"features/ must only contain .ts files. Components belong in src/components/.",
|
|
150
|
+
},
|
|
151
|
+
],
|
|
152
|
+
},
|
|
148
153
|
},
|
|
149
|
-
|
|
150
|
-
|
|
154
|
+
];
|
|
155
|
+
}
|
package/src/next/index.mjs
CHANGED
|
@@ -1,10 +1,12 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { createCommonConfigs } from "../common/index.mjs";
|
|
2
|
+
import { libBoundaryConfigs } from "../common/imports.mjs";
|
|
2
3
|
|
|
3
4
|
import { directivesConfigs } from "./directives.mjs";
|
|
4
5
|
import { namingConfigs } from "./naming.mjs";
|
|
5
6
|
|
|
6
7
|
export const eslintConfig = [
|
|
7
|
-
...
|
|
8
|
+
...createCommonConfigs("src/features"),
|
|
9
|
+
...libBoundaryConfigs,
|
|
8
10
|
...namingConfigs,
|
|
9
11
|
...directivesConfigs,
|
|
10
12
|
];
|
package/src/next/naming.mjs
CHANGED
|
@@ -1,10 +1,9 @@
|
|
|
1
|
-
import { featuresGlob } from "../common/constants.mjs";
|
|
2
1
|
import { checkFile } from "../common/plugins.mjs";
|
|
3
2
|
|
|
4
3
|
export const namingConfigs = [
|
|
5
4
|
{
|
|
6
5
|
name: "naming/hooks",
|
|
7
|
-
files:
|
|
6
|
+
files: ["src/features/**/hooks/*.ts"],
|
|
8
7
|
plugins: { "check-file": checkFile },
|
|
9
8
|
rules: {
|
|
10
9
|
"check-file/filename-naming-convention": [
|
|
@@ -16,7 +15,7 @@ export const namingConfigs = [
|
|
|
16
15
|
},
|
|
17
16
|
{
|
|
18
17
|
name: "naming/hooks-export",
|
|
19
|
-
files:
|
|
18
|
+
files: ["src/features/**/hooks/*.ts"],
|
|
20
19
|
rules: {
|
|
21
20
|
"no-restricted-syntax": [
|
|
22
21
|
"error",
|
package/src/node/index.mjs
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { createCommonConfigs } from "../common/index.mjs";
|
|
2
2
|
|
|
3
|
-
export const eslintConfig = [...
|
|
3
|
+
export const eslintConfig = [...createCommonConfigs("scripts/features")];
|