@yasainet/eslint 0.0.3 → 0.0.4
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 +14 -12
- 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.4",
|
|
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,26 @@ 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
120
|
ignores: ["src/lib/**", "src/proxy.ts", "src/app/sitemap.ts"],
|
|
122
121
|
rules: {
|
|
123
122
|
"no-restricted-imports": ["error", { patterns: LIB_BOUNDARY_PATTERNS }],
|
|
124
123
|
},
|
|
125
|
-
}
|
|
124
|
+
},
|
|
125
|
+
];
|
|
126
|
+
|
|
127
|
+
/** @description Scope import restriction rules to the given feature root */
|
|
128
|
+
export function createImportsConfigs(featureRoot) {
|
|
129
|
+
const configs = [];
|
|
126
130
|
|
|
127
131
|
configs.push(
|
|
128
132
|
makeConfig(
|
|
129
133
|
"repositories",
|
|
130
|
-
[
|
|
134
|
+
[`${featureRoot}/**/repositories/*.ts`],
|
|
131
135
|
LAYER_PATTERNS.repositories,
|
|
132
136
|
LATERAL_PATTERNS.repositories,
|
|
133
137
|
),
|
|
@@ -139,7 +143,7 @@ function generateImportConfigs() {
|
|
|
139
143
|
configs.push(
|
|
140
144
|
makeConfig(
|
|
141
145
|
`repositories/${prefix}`,
|
|
142
|
-
[
|
|
146
|
+
[`${featureRoot}/**/repositories/${prefix}.repo.ts`],
|
|
143
147
|
LAYER_PATTERNS.repositories,
|
|
144
148
|
LATERAL_PATTERNS.repositories,
|
|
145
149
|
patterns,
|
|
@@ -150,7 +154,7 @@ function generateImportConfigs() {
|
|
|
150
154
|
configs.push(
|
|
151
155
|
makeConfig(
|
|
152
156
|
"services",
|
|
153
|
-
[
|
|
157
|
+
[`${featureRoot}/**/services/*.ts`],
|
|
154
158
|
LAYER_PATTERNS.services,
|
|
155
159
|
LATERAL_PATTERNS.services,
|
|
156
160
|
LIB_BOUNDARY_PATTERNS,
|
|
@@ -160,7 +164,7 @@ function generateImportConfigs() {
|
|
|
160
164
|
configs.push(
|
|
161
165
|
makeConfig(
|
|
162
166
|
"actions",
|
|
163
|
-
[
|
|
167
|
+
[`${featureRoot}/**/actions/*.ts`],
|
|
164
168
|
LAYER_PATTERNS.actions,
|
|
165
169
|
LATERAL_PATTERNS.actions,
|
|
166
170
|
LIB_BOUNDARY_PATTERNS,
|
|
@@ -171,7 +175,7 @@ function generateImportConfigs() {
|
|
|
171
175
|
configs.push(
|
|
172
176
|
makeConfig(
|
|
173
177
|
`actions/${prefix}`,
|
|
174
|
-
[
|
|
178
|
+
[`${featureRoot}/**/actions/${prefix}.action.ts`],
|
|
175
179
|
LAYER_PATTERNS.actions,
|
|
176
180
|
LATERAL_PATTERNS.actions,
|
|
177
181
|
CARDINALITY_PATTERNS[prefix],
|
|
@@ -182,5 +186,3 @@ function generateImportConfigs() {
|
|
|
182
186
|
|
|
183
187
|
return configs.filter(Boolean);
|
|
184
188
|
}
|
|
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")];
|