@comet/eslint-plugin 9.0.0-beta.3 → 9.0.0-beta.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/package.json +13 -11
- package/CHANGELOG.md +0 -265
- package/eslint.config.mjs +0 -81
- package/jest.config.js +0 -5
- package/lib/rules/no-other-module-relative-import.test.d.ts +0 -1
- package/lib/rules/no-other-module-relative-import.test.js +0 -37
- package/lib/rules/no-private-sibling-import.test.d.ts +0 -1
- package/lib/rules/no-private-sibling-import.test.js +0 -41
- package/lint-staged.config.mjs +0 -9
- package/src/index.ts +0 -12
- package/src/rules/no-other-module-relative-import.test.ts +0 -38
- package/src/rules/no-other-module-relative-import.ts +0 -68
- package/src/rules/no-private-sibling-import.test.ts +0 -44
- package/src/rules/no-private-sibling-import.ts +0 -57
- package/tsconfig.json +0 -9
package/package.json
CHANGED
|
@@ -1,28 +1,30 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@comet/eslint-plugin",
|
|
3
|
-
"version": "9.0.0-beta.
|
|
3
|
+
"version": "9.0.0-beta.4",
|
|
4
4
|
"description": "A set of ESLint rules and configurations for Comet projects",
|
|
5
5
|
"type": "commonjs",
|
|
6
6
|
"main": "lib/index.js",
|
|
7
7
|
"license": "BSD-2-Clause",
|
|
8
|
+
"sideEffects": false,
|
|
9
|
+
"files": [
|
|
10
|
+
"lib"
|
|
11
|
+
],
|
|
8
12
|
"devDependencies": {
|
|
9
13
|
"@eslint/js": "^9.39.4",
|
|
10
|
-
"
|
|
11
|
-
"eslint": "^9.39.2",
|
|
14
|
+
"eslint": "^9.39.4",
|
|
12
15
|
"eslint-config-prettier": "^10.1.8",
|
|
13
16
|
"eslint-plugin-import": "^2.32.0",
|
|
14
17
|
"eslint-plugin-jsonc": "^2.21.1",
|
|
15
|
-
"eslint-plugin-package-json": "^0.
|
|
18
|
+
"eslint-plugin-package-json": "^0.91.2",
|
|
16
19
|
"eslint-plugin-prettier": "^5.5.5",
|
|
17
20
|
"eslint-plugin-simple-import-sort": "^12.1.1",
|
|
18
21
|
"eslint-plugin-unused-imports": "^4.4.1",
|
|
19
22
|
"globals": "^15.15.0",
|
|
20
|
-
"jest": "^29.7.0",
|
|
21
23
|
"npm-run-all2": "^8.0.4",
|
|
22
24
|
"prettier": "^3.6.2",
|
|
23
|
-
"ts-jest": "^29.4.9",
|
|
24
25
|
"typescript": "^5.9.3",
|
|
25
|
-
"typescript-eslint": "^8.
|
|
26
|
+
"typescript-eslint": "^8.59.3",
|
|
27
|
+
"vitest": "^4.0.16"
|
|
26
28
|
},
|
|
27
29
|
"peerDependencies": {
|
|
28
30
|
"eslint": ">=9",
|
|
@@ -36,7 +38,7 @@
|
|
|
36
38
|
"registry": "https://registry.npmjs.org"
|
|
37
39
|
},
|
|
38
40
|
"scripts": {
|
|
39
|
-
"build": "pnpm run clean && tsc",
|
|
41
|
+
"build": "pnpm run clean && tsc --project ./tsconfig.build.json",
|
|
40
42
|
"clean": "rimraf lib",
|
|
41
43
|
"dev": "tsc --watch",
|
|
42
44
|
"lint": "run-p lint:prettier lint:eslint lint:tsc",
|
|
@@ -46,8 +48,8 @@
|
|
|
46
48
|
"lint:fix:eslint": "pnpm run lint:eslint --fix",
|
|
47
49
|
"lint:fix:prettier": "pnpm run lint:prettier --write",
|
|
48
50
|
"lint:prettier": "pnpm exec prettier --check '*.{ts,js,json,md,yml,yaml}'",
|
|
49
|
-
"lint:tsc": "tsc",
|
|
50
|
-
"test": "
|
|
51
|
-
"test:watch": "
|
|
51
|
+
"lint:tsc": "tsc --noEmit",
|
|
52
|
+
"test": "vitest --run",
|
|
53
|
+
"test:watch": "vitest --watch"
|
|
52
54
|
}
|
|
53
55
|
}
|
package/CHANGELOG.md
DELETED
|
@@ -1,265 +0,0 @@
|
|
|
1
|
-
# @comet/eslint-plugin
|
|
2
|
-
|
|
3
|
-
## 9.0.0-beta.3
|
|
4
|
-
|
|
5
|
-
## 9.0.0-beta.2
|
|
6
|
-
|
|
7
|
-
## 9.0.0-beta.1
|
|
8
|
-
|
|
9
|
-
## 9.0.0-beta.0
|
|
10
|
-
|
|
11
|
-
### Major Changes
|
|
12
|
-
|
|
13
|
-
- db6b83a: Prevent lib imports from `@comet/` packages
|
|
14
|
-
|
|
15
|
-
Use `no-restricted-imports` to prevent importing private files from `@comet/*/lib`. For example, the following import would be forbidden:
|
|
16
|
-
|
|
17
|
-
```ts
|
|
18
|
-
import { something } from "@comet/admin/lib/some/private/file";
|
|
19
|
-
```
|
|
20
|
-
|
|
21
|
-
## 8.20.0
|
|
22
|
-
|
|
23
|
-
## 8.19.0
|
|
24
|
-
|
|
25
|
-
## 8.18.0
|
|
26
|
-
|
|
27
|
-
## 8.17.1
|
|
28
|
-
|
|
29
|
-
## 8.17.0
|
|
30
|
-
|
|
31
|
-
## 8.16.0
|
|
32
|
-
|
|
33
|
-
## 8.15.0
|
|
34
|
-
|
|
35
|
-
## 8.14.0
|
|
36
|
-
|
|
37
|
-
## 8.13.0
|
|
38
|
-
|
|
39
|
-
## 8.12.0
|
|
40
|
-
|
|
41
|
-
## 8.11.1
|
|
42
|
-
|
|
43
|
-
## 8.11.0
|
|
44
|
-
|
|
45
|
-
## 8.10.0
|
|
46
|
-
|
|
47
|
-
## 8.9.0
|
|
48
|
-
|
|
49
|
-
## 8.8.0
|
|
50
|
-
|
|
51
|
-
## 8.7.1
|
|
52
|
-
|
|
53
|
-
## 8.7.0
|
|
54
|
-
|
|
55
|
-
## 8.6.0
|
|
56
|
-
|
|
57
|
-
## 8.5.2
|
|
58
|
-
|
|
59
|
-
## 8.5.1
|
|
60
|
-
|
|
61
|
-
## 8.5.0
|
|
62
|
-
|
|
63
|
-
## 8.4.2
|
|
64
|
-
|
|
65
|
-
## 8.4.1
|
|
66
|
-
|
|
67
|
-
## 8.4.0
|
|
68
|
-
|
|
69
|
-
## 8.3.0
|
|
70
|
-
|
|
71
|
-
## 8.2.0
|
|
72
|
-
|
|
73
|
-
## 8.1.1
|
|
74
|
-
|
|
75
|
-
## 8.1.0
|
|
76
|
-
|
|
77
|
-
## 8.0.0
|
|
78
|
-
|
|
79
|
-
### Major Changes
|
|
80
|
-
|
|
81
|
-
- f904b71: Require Node v22
|
|
82
|
-
|
|
83
|
-
The minimum required Node version is now v22.0.0.
|
|
84
|
-
See the migration guide for instructions on how to upgrade your project.
|
|
85
|
-
|
|
86
|
-
## 8.0.0-beta.6
|
|
87
|
-
|
|
88
|
-
## 8.0.0-beta.5
|
|
89
|
-
|
|
90
|
-
## 8.0.0-beta.4
|
|
91
|
-
|
|
92
|
-
## 8.0.0-beta.3
|
|
93
|
-
|
|
94
|
-
## 8.0.0-beta.2
|
|
95
|
-
|
|
96
|
-
### Major Changes
|
|
97
|
-
|
|
98
|
-
- f904b71: Require Node v22
|
|
99
|
-
|
|
100
|
-
The minimum required Node version is now v22.0.0.
|
|
101
|
-
See the migration guide for instructions on how to upgrade your project.
|
|
102
|
-
|
|
103
|
-
## 8.0.0-beta.1
|
|
104
|
-
|
|
105
|
-
## 8.0.0-beta.0
|
|
106
|
-
|
|
107
|
-
## 7.25.3
|
|
108
|
-
|
|
109
|
-
## 7.25.2
|
|
110
|
-
|
|
111
|
-
## 7.25.1
|
|
112
|
-
|
|
113
|
-
### Patch Changes
|
|
114
|
-
|
|
115
|
-
- 85e80218f: Support dot separated imports in no-private-sibling-import rule
|
|
116
|
-
|
|
117
|
-
This allows, for example, importing from MyBlock.loader.gql.ts in MyBlock.loader.ts
|
|
118
|
-
|
|
119
|
-
## 7.25.0
|
|
120
|
-
|
|
121
|
-
## 7.24.0
|
|
122
|
-
|
|
123
|
-
## 7.23.0
|
|
124
|
-
|
|
125
|
-
## 7.22.0
|
|
126
|
-
|
|
127
|
-
## 7.21.1
|
|
128
|
-
|
|
129
|
-
## 7.21.0
|
|
130
|
-
|
|
131
|
-
## 7.20.0
|
|
132
|
-
|
|
133
|
-
## 7.19.0
|
|
134
|
-
|
|
135
|
-
## 7.18.0
|
|
136
|
-
|
|
137
|
-
## 7.17.0
|
|
138
|
-
|
|
139
|
-
## 7.16.0
|
|
140
|
-
|
|
141
|
-
## 7.15.0
|
|
142
|
-
|
|
143
|
-
## 7.14.0
|
|
144
|
-
|
|
145
|
-
## 7.13.0
|
|
146
|
-
|
|
147
|
-
## 7.12.0
|
|
148
|
-
|
|
149
|
-
## 7.11.0
|
|
150
|
-
|
|
151
|
-
## 7.10.0
|
|
152
|
-
|
|
153
|
-
## 7.9.0
|
|
154
|
-
|
|
155
|
-
## 7.8.0
|
|
156
|
-
|
|
157
|
-
## 7.7.0
|
|
158
|
-
|
|
159
|
-
## 7.6.0
|
|
160
|
-
|
|
161
|
-
## 7.5.0
|
|
162
|
-
|
|
163
|
-
## 7.4.2
|
|
164
|
-
|
|
165
|
-
## 7.4.1
|
|
166
|
-
|
|
167
|
-
## 7.4.0
|
|
168
|
-
|
|
169
|
-
## 7.3.2
|
|
170
|
-
|
|
171
|
-
## 7.3.1
|
|
172
|
-
|
|
173
|
-
## 7.3.0
|
|
174
|
-
|
|
175
|
-
## 7.2.1
|
|
176
|
-
|
|
177
|
-
## 7.2.0
|
|
178
|
-
|
|
179
|
-
## 7.1.0
|
|
180
|
-
|
|
181
|
-
## 7.0.0
|
|
182
|
-
|
|
183
|
-
## 7.0.0-beta.6
|
|
184
|
-
|
|
185
|
-
## 7.0.0-beta.5
|
|
186
|
-
|
|
187
|
-
## 7.0.0-beta.4
|
|
188
|
-
|
|
189
|
-
## 7.0.0-beta.3
|
|
190
|
-
|
|
191
|
-
## 7.0.0-beta.2
|
|
192
|
-
|
|
193
|
-
## 7.0.0-beta.1
|
|
194
|
-
|
|
195
|
-
## 7.0.0-beta.0
|
|
196
|
-
|
|
197
|
-
## 6.17.1
|
|
198
|
-
|
|
199
|
-
## 6.17.0
|
|
200
|
-
|
|
201
|
-
## 6.16.0
|
|
202
|
-
|
|
203
|
-
## 6.15.1
|
|
204
|
-
|
|
205
|
-
## 6.15.0
|
|
206
|
-
|
|
207
|
-
## 6.14.1
|
|
208
|
-
|
|
209
|
-
## 6.14.0
|
|
210
|
-
|
|
211
|
-
## 6.13.0
|
|
212
|
-
|
|
213
|
-
## 6.12.0
|
|
214
|
-
|
|
215
|
-
## 6.11.0
|
|
216
|
-
|
|
217
|
-
## 6.10.0
|
|
218
|
-
|
|
219
|
-
## 6.9.0
|
|
220
|
-
|
|
221
|
-
## 6.8.0
|
|
222
|
-
|
|
223
|
-
## 6.7.0
|
|
224
|
-
|
|
225
|
-
## 6.6.2
|
|
226
|
-
|
|
227
|
-
## 6.6.1
|
|
228
|
-
|
|
229
|
-
## 6.6.0
|
|
230
|
-
|
|
231
|
-
## 6.5.0
|
|
232
|
-
|
|
233
|
-
## 6.4.0
|
|
234
|
-
|
|
235
|
-
## 6.3.0
|
|
236
|
-
|
|
237
|
-
## 6.2.1
|
|
238
|
-
|
|
239
|
-
## 6.2.0
|
|
240
|
-
|
|
241
|
-
## 6.1.0
|
|
242
|
-
|
|
243
|
-
## 6.0.0
|
|
244
|
-
|
|
245
|
-
## 5.6.0
|
|
246
|
-
|
|
247
|
-
## 5.5.0
|
|
248
|
-
|
|
249
|
-
## 5.4.0
|
|
250
|
-
|
|
251
|
-
## 5.3.0
|
|
252
|
-
|
|
253
|
-
## 5.2.0
|
|
254
|
-
|
|
255
|
-
## 5.1.0
|
|
256
|
-
|
|
257
|
-
### Minor Changes
|
|
258
|
-
|
|
259
|
-
- ec0582e6: Add new ESLint rule to enforce absolute imports when importing from other modules
|
|
260
|
-
|
|
261
|
-
For instance, an import `import { AThingInModuleA } from "../moduleA/AThingInModuleA"` in module `B` needs to be imported as `import { AThingInModuleA } from "@src/moduleA/AThingInModuleA"`.
|
|
262
|
-
The default source root `"./src"` and alias `"@src"` can be changed via the rule's `sourceRoot` and `sourceRootAlias` options.
|
|
263
|
-
This rule will be enforced by `@comet/eslint-config` in the next major release.
|
|
264
|
-
|
|
265
|
-
## 5.0.0
|
package/eslint.config.mjs
DELETED
|
@@ -1,81 +0,0 @@
|
|
|
1
|
-
import { defineConfig, globalIgnores } from "eslint/config";
|
|
2
|
-
import eslint from "@eslint/js";
|
|
3
|
-
import globals from "globals";
|
|
4
|
-
import tseslint from "typescript-eslint";
|
|
5
|
-
import prettierConfig from "eslint-config-prettier";
|
|
6
|
-
import prettierPlugin from "eslint-plugin-prettier/recommended";
|
|
7
|
-
import unusedImports from "eslint-plugin-unused-imports";
|
|
8
|
-
import simpleImportSort from "eslint-plugin-simple-import-sort";
|
|
9
|
-
import { configs as eslintPluginJsonc } from "eslint-plugin-jsonc";
|
|
10
|
-
import importPlugin from "eslint-plugin-import";
|
|
11
|
-
import packageJson from "eslint-plugin-package-json";
|
|
12
|
-
|
|
13
|
-
export default defineConfig([
|
|
14
|
-
globalIgnores(["lib/**/*", "bin/**/*"]),
|
|
15
|
-
eslint.configs.recommended,
|
|
16
|
-
...tseslint.configs.recommended,
|
|
17
|
-
prettierConfig,
|
|
18
|
-
prettierPlugin,
|
|
19
|
-
{
|
|
20
|
-
plugins: {
|
|
21
|
-
"unused-imports": unusedImports,
|
|
22
|
-
},
|
|
23
|
-
rules: {
|
|
24
|
-
"unused-imports/no-unused-imports": "error",
|
|
25
|
-
},
|
|
26
|
-
},
|
|
27
|
-
{
|
|
28
|
-
plugins: {
|
|
29
|
-
"simple-import-sort": simpleImportSort,
|
|
30
|
-
},
|
|
31
|
-
rules: {
|
|
32
|
-
"simple-import-sort/imports": "error",
|
|
33
|
-
"simple-import-sort/exports": "error",
|
|
34
|
-
},
|
|
35
|
-
},
|
|
36
|
-
{
|
|
37
|
-
...importPlugin.flatConfigs.recommended,
|
|
38
|
-
rules: {
|
|
39
|
-
"import/no-duplicates": "error",
|
|
40
|
-
"import/newline-after-import": "error",
|
|
41
|
-
"import/no-extraneous-dependencies": "error",
|
|
42
|
-
},
|
|
43
|
-
},
|
|
44
|
-
...eslintPluginJsonc["flat/recommended-with-json"],
|
|
45
|
-
{
|
|
46
|
-
ignores: ["package.json"],
|
|
47
|
-
rules: {
|
|
48
|
-
"jsonc/sort-keys": "error",
|
|
49
|
-
},
|
|
50
|
-
},
|
|
51
|
-
packageJson.configs.recommended,
|
|
52
|
-
{
|
|
53
|
-
ignores: ["*.json"],
|
|
54
|
-
languageOptions: {
|
|
55
|
-
globals: {
|
|
56
|
-
...globals.node,
|
|
57
|
-
...globals.jest,
|
|
58
|
-
},
|
|
59
|
-
|
|
60
|
-
parser: tseslint.parser,
|
|
61
|
-
parserOptions: {
|
|
62
|
-
projectService: true,
|
|
63
|
-
tsconfigRootDir: import.meta.dirname,
|
|
64
|
-
},
|
|
65
|
-
},
|
|
66
|
-
// Rules
|
|
67
|
-
rules: {
|
|
68
|
-
"prefer-template": "error",
|
|
69
|
-
"no-console": ["error", { allow: ["warn", "error", "info", "debug"] }],
|
|
70
|
-
"no-return-await": "error",
|
|
71
|
-
"@typescript-eslint/consistent-type-imports": [
|
|
72
|
-
"error",
|
|
73
|
-
{
|
|
74
|
-
prefer: "type-imports",
|
|
75
|
-
disallowTypeAnnotations: false,
|
|
76
|
-
fixStyle: "inline-type-imports",
|
|
77
|
-
},
|
|
78
|
-
],
|
|
79
|
-
},
|
|
80
|
-
},
|
|
81
|
-
]);
|
package/jest.config.js
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export {};
|
|
@@ -1,37 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
-
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
-
};
|
|
5
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
-
var eslint_1 = require("eslint");
|
|
7
|
-
var no_other_module_relative_import_1 = __importDefault(require("./no-other-module-relative-import"));
|
|
8
|
-
var ruleTester = new eslint_1.RuleTester();
|
|
9
|
-
var errors = [{ message: "Avoid relative import from other module" }];
|
|
10
|
-
var options = [{ sourceRoot: "./src", sourceRootAlias: "@src" }];
|
|
11
|
-
ruleTester.run("no-other-module-relative-import", no_other_module_relative_import_1.default, {
|
|
12
|
-
valid: [
|
|
13
|
-
{
|
|
14
|
-
code: "import Bar from \"@src/moduleb/Bar\";",
|
|
15
|
-
filename: "".concat(process.cwd(), "/src/modulea/Foo.ts"),
|
|
16
|
-
options: options,
|
|
17
|
-
},
|
|
18
|
-
{ code: "import Bar from \"../Bar\";", filename: "".concat(process.cwd(), "/src/modulea/sub/Foo.ts"), options: options },
|
|
19
|
-
{ code: "import Bar from \"xx/bar\";", filename: "".concat(process.cwd(), "/src/modulea/Foo.ts"), options: options },
|
|
20
|
-
],
|
|
21
|
-
invalid: [
|
|
22
|
-
{
|
|
23
|
-
code: "import Bar from \"../moduleb/Bar\";",
|
|
24
|
-
filename: "".concat(process.cwd(), "/src/modulea/Foo.ts"),
|
|
25
|
-
options: options,
|
|
26
|
-
errors: errors,
|
|
27
|
-
output: "import Bar from \"@src/moduleb/Bar\";",
|
|
28
|
-
},
|
|
29
|
-
{
|
|
30
|
-
code: "import Bar from \"../../Bar\";",
|
|
31
|
-
filename: "".concat(process.cwd(), "/src/modulea/sub/Foo.ts"),
|
|
32
|
-
options: options,
|
|
33
|
-
errors: errors,
|
|
34
|
-
output: "import Bar from \"@src/Bar\";",
|
|
35
|
-
},
|
|
36
|
-
],
|
|
37
|
-
});
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export {};
|
|
@@ -1,41 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
-
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
-
};
|
|
5
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
-
var eslint_1 = require("eslint");
|
|
7
|
-
var no_private_sibling_import_1 = __importDefault(require("./no-private-sibling-import"));
|
|
8
|
-
var ruleTester = new eslint_1.RuleTester();
|
|
9
|
-
var errors = [{ message: "Avoid private sibling import from other files" }];
|
|
10
|
-
var options = [["gql", "sc", "gql.generated"]];
|
|
11
|
-
ruleTester.run("can't import from private .gql.ts", no_private_sibling_import_1.default, {
|
|
12
|
-
valid: [
|
|
13
|
-
{ code: "import FooGql from \"./Foo.gql\";", filename: "/path/to/Foo.ts" },
|
|
14
|
-
{ code: "import FooGql from \"./Foo.gql\";", filename: "/path/to/Foo.tsx" },
|
|
15
|
-
],
|
|
16
|
-
invalid: [
|
|
17
|
-
{ code: "import BarGql from \"./Bar.gql\";", filename: "/path/to/Foo.ts", errors: errors },
|
|
18
|
-
{ code: "import BarGql from \"./Bar.gql\";", filename: "/path/to/Foo.tsx", errors: errors },
|
|
19
|
-
],
|
|
20
|
-
});
|
|
21
|
-
ruleTester.run("can't import from private .sc.ts", no_private_sibling_import_1.default, {
|
|
22
|
-
valid: [
|
|
23
|
-
{ code: "import FooSc from \"./Foo.sc\";", filename: "/path/to/Foo.ts" },
|
|
24
|
-
{ code: "import FooSc from \"./Foo.sc\";", filename: "/path/to/Foo.tsx" },
|
|
25
|
-
],
|
|
26
|
-
invalid: [
|
|
27
|
-
{ code: "import BarSc from \"./Bar.sc\";", filename: "/path/to/Foo.ts", errors: errors },
|
|
28
|
-
{ code: "import BarSc from \"./Bar.sc\";", filename: "/path/to/Foo.tsx", errors: errors },
|
|
29
|
-
],
|
|
30
|
-
});
|
|
31
|
-
ruleTester.run("can override extensions -> can't import from private .gql.generated.ts", no_private_sibling_import_1.default, {
|
|
32
|
-
valid: [{ code: "import FooGql from \"./Foo.gql.generated\";", filename: "/path/to/Foo.ts", options: options }],
|
|
33
|
-
invalid: [{ code: "import BarGql from \"./Bar.gql.generated\";", filename: "/path/to/Foo.ts", options: options, errors: errors }],
|
|
34
|
-
});
|
|
35
|
-
ruleTester.run("can't import from private .loader.gql.ts", no_private_sibling_import_1.default, {
|
|
36
|
-
valid: [{ code: "import FooGql from \"./FooBlock.loader.gql\";", filename: "/path/to/FooBlock.loader.ts" }],
|
|
37
|
-
invalid: [
|
|
38
|
-
{ code: "import BarGql from \"./BarBlock.loader.gql\";", filename: "/path/to/FooBlock.loader.ts", errors: errors },
|
|
39
|
-
{ code: "import BarGql from \"./FooBlock.loader.gql\";", filename: "/path/to/FooBlock.ts", errors: errors },
|
|
40
|
-
],
|
|
41
|
-
});
|
package/lint-staged.config.mjs
DELETED
|
@@ -1,9 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* @filename: lint-staged.config.mjs
|
|
3
|
-
* @type {import('lint-staged').Configuration}
|
|
4
|
-
*/
|
|
5
|
-
export default {
|
|
6
|
-
"src/**/*.{ts,tsx,js,jsx,json,css,scss,md}": () => "pnpm lint:eslint",
|
|
7
|
-
"src/**/*.{ts,tsx}": () => "pnpm lint:tsc",
|
|
8
|
-
"*.{ts,js,json,md,yml,yaml}": () => "pnpm lint:prettier",
|
|
9
|
-
};
|
package/src/index.ts
DELETED
|
@@ -1,12 +0,0 @@
|
|
|
1
|
-
import noOtherModuleRelativeImport from "./rules/no-other-module-relative-import";
|
|
2
|
-
import noPrivateSiblingImport from "./rules/no-private-sibling-import";
|
|
3
|
-
|
|
4
|
-
const plugin = {
|
|
5
|
-
rules: {
|
|
6
|
-
"no-private-sibling-import": noPrivateSiblingImport,
|
|
7
|
-
"no-other-module-relative-import": noOtherModuleRelativeImport,
|
|
8
|
-
},
|
|
9
|
-
};
|
|
10
|
-
export type Plugin = typeof plugin;
|
|
11
|
-
|
|
12
|
-
module.exports = plugin;
|
|
@@ -1,38 +0,0 @@
|
|
|
1
|
-
import { RuleTester } from "eslint";
|
|
2
|
-
|
|
3
|
-
import noOtherModuleRelativeImport from "./no-other-module-relative-import";
|
|
4
|
-
|
|
5
|
-
const ruleTester = new RuleTester();
|
|
6
|
-
|
|
7
|
-
const errors = [{ message: "Avoid relative import from other module" }];
|
|
8
|
-
|
|
9
|
-
const options = [{ sourceRoot: "./src", sourceRootAlias: "@src" }];
|
|
10
|
-
|
|
11
|
-
ruleTester.run("no-other-module-relative-import", noOtherModuleRelativeImport, {
|
|
12
|
-
valid: [
|
|
13
|
-
{
|
|
14
|
-
code: `import Bar from "@src/moduleb/Bar";`,
|
|
15
|
-
filename: `${process.cwd()}/src/modulea/Foo.ts`,
|
|
16
|
-
options,
|
|
17
|
-
},
|
|
18
|
-
{ code: `import Bar from "../Bar";`, filename: `${process.cwd()}/src/modulea/sub/Foo.ts`, options },
|
|
19
|
-
{ code: `import Bar from "xx/bar";`, filename: `${process.cwd()}/src/modulea/Foo.ts`, options },
|
|
20
|
-
],
|
|
21
|
-
|
|
22
|
-
invalid: [
|
|
23
|
-
{
|
|
24
|
-
code: `import Bar from "../moduleb/Bar";`,
|
|
25
|
-
filename: `${process.cwd()}/src/modulea/Foo.ts`,
|
|
26
|
-
options,
|
|
27
|
-
errors,
|
|
28
|
-
output: `import Bar from "@src/moduleb/Bar";`,
|
|
29
|
-
},
|
|
30
|
-
{
|
|
31
|
-
code: `import Bar from "../../Bar";`,
|
|
32
|
-
filename: `${process.cwd()}/src/modulea/sub/Foo.ts`,
|
|
33
|
-
options,
|
|
34
|
-
errors,
|
|
35
|
-
output: `import Bar from "@src/Bar";`,
|
|
36
|
-
},
|
|
37
|
-
],
|
|
38
|
-
});
|
|
@@ -1,68 +0,0 @@
|
|
|
1
|
-
import { type Rule } from "eslint";
|
|
2
|
-
import path from "path";
|
|
3
|
-
|
|
4
|
-
function parentDirCount(dir: string) {
|
|
5
|
-
const match = dir.match(/^(\.\.\/)*/);
|
|
6
|
-
return match[0].length / 3;
|
|
7
|
-
}
|
|
8
|
-
|
|
9
|
-
export default {
|
|
10
|
-
meta: {
|
|
11
|
-
type: "suggestion",
|
|
12
|
-
fixable: "code",
|
|
13
|
-
schema: [
|
|
14
|
-
{
|
|
15
|
-
type: "object",
|
|
16
|
-
properties: {
|
|
17
|
-
sourceRoot: {
|
|
18
|
-
type: "string",
|
|
19
|
-
},
|
|
20
|
-
sourceRootAlias: {
|
|
21
|
-
type: "string",
|
|
22
|
-
},
|
|
23
|
-
},
|
|
24
|
-
additionalProperties: false,
|
|
25
|
-
},
|
|
26
|
-
],
|
|
27
|
-
},
|
|
28
|
-
create(context) {
|
|
29
|
-
return {
|
|
30
|
-
ImportDeclaration: function (node) {
|
|
31
|
-
const options = context.options[0] ?? { sourceRoot: "./src", sourceRootAlias: "@src" };
|
|
32
|
-
|
|
33
|
-
const importParentDirCount = parentDirCount(node.source.value.toString());
|
|
34
|
-
if (!importParentDirCount) {
|
|
35
|
-
// import is not relative
|
|
36
|
-
return;
|
|
37
|
-
}
|
|
38
|
-
|
|
39
|
-
const filePath = context.getPhysicalFilename ? context.getPhysicalFilename() : context.getFilename();
|
|
40
|
-
if (filePath == "<text>") return; // If the input is from stdin, this test can't fail
|
|
41
|
-
const sourceDir = `${context.getCwd()}/${options.sourceRoot}`;
|
|
42
|
-
|
|
43
|
-
const fileDir = path.dirname(filePath);
|
|
44
|
-
|
|
45
|
-
const relativeFileToSourceDir = path.relative(sourceDir, fileDir);
|
|
46
|
-
if (!relativeFileToSourceDir || relativeFileToSourceDir.startsWith("..")) {
|
|
47
|
-
// file is not in source directory
|
|
48
|
-
return;
|
|
49
|
-
}
|
|
50
|
-
|
|
51
|
-
const fileSubdirectoriesCount = relativeFileToSourceDir.split(path.sep).length;
|
|
52
|
-
|
|
53
|
-
// importParentDirCount is the number of ../ parts in the import path
|
|
54
|
-
// fileSubdirectoriesCount is the number of subdirectories in the file path relative to the source directory
|
|
55
|
-
if (importParentDirCount >= fileSubdirectoriesCount) {
|
|
56
|
-
context.report({
|
|
57
|
-
node,
|
|
58
|
-
message: "Avoid relative import from other module",
|
|
59
|
-
fix: (fixer) => {
|
|
60
|
-
const importPathRelativeToSourceDir = path.relative(sourceDir, `${fileDir}/${node.source.value.toString()}`);
|
|
61
|
-
return fixer.replaceText(node.source, `"${options.sourceRootAlias}/${importPathRelativeToSourceDir}"`);
|
|
62
|
-
},
|
|
63
|
-
});
|
|
64
|
-
}
|
|
65
|
-
},
|
|
66
|
-
};
|
|
67
|
-
},
|
|
68
|
-
} as Rule.RuleModule;
|
|
@@ -1,44 +0,0 @@
|
|
|
1
|
-
import { RuleTester } from "eslint";
|
|
2
|
-
|
|
3
|
-
import noPrivateSiblingImport from "./no-private-sibling-import";
|
|
4
|
-
|
|
5
|
-
const ruleTester = new RuleTester();
|
|
6
|
-
|
|
7
|
-
const errors = [{ message: "Avoid private sibling import from other files" }];
|
|
8
|
-
|
|
9
|
-
const options = [["gql", "sc", "gql.generated"]];
|
|
10
|
-
|
|
11
|
-
ruleTester.run("can't import from private .gql.ts", noPrivateSiblingImport, {
|
|
12
|
-
valid: [
|
|
13
|
-
{ code: `import FooGql from "./Foo.gql";`, filename: "/path/to/Foo.ts" },
|
|
14
|
-
{ code: `import FooGql from "./Foo.gql";`, filename: "/path/to/Foo.tsx" },
|
|
15
|
-
],
|
|
16
|
-
invalid: [
|
|
17
|
-
{ code: `import BarGql from "./Bar.gql";`, filename: "/path/to/Foo.ts", errors },
|
|
18
|
-
{ code: `import BarGql from "./Bar.gql";`, filename: "/path/to/Foo.tsx", errors },
|
|
19
|
-
],
|
|
20
|
-
});
|
|
21
|
-
|
|
22
|
-
ruleTester.run("can't import from private .sc.ts", noPrivateSiblingImport, {
|
|
23
|
-
valid: [
|
|
24
|
-
{ code: `import FooSc from "./Foo.sc";`, filename: "/path/to/Foo.ts" },
|
|
25
|
-
{ code: `import FooSc from "./Foo.sc";`, filename: "/path/to/Foo.tsx" },
|
|
26
|
-
],
|
|
27
|
-
invalid: [
|
|
28
|
-
{ code: `import BarSc from "./Bar.sc";`, filename: "/path/to/Foo.ts", errors },
|
|
29
|
-
{ code: `import BarSc from "./Bar.sc";`, filename: "/path/to/Foo.tsx", errors },
|
|
30
|
-
],
|
|
31
|
-
});
|
|
32
|
-
|
|
33
|
-
ruleTester.run("can override extensions -> can't import from private .gql.generated.ts", noPrivateSiblingImport, {
|
|
34
|
-
valid: [{ code: `import FooGql from "./Foo.gql.generated";`, filename: "/path/to/Foo.ts", options }],
|
|
35
|
-
invalid: [{ code: `import BarGql from "./Bar.gql.generated";`, filename: "/path/to/Foo.ts", options, errors }],
|
|
36
|
-
});
|
|
37
|
-
|
|
38
|
-
ruleTester.run("can't import from private .loader.gql.ts", noPrivateSiblingImport, {
|
|
39
|
-
valid: [{ code: `import FooGql from "./FooBlock.loader.gql";`, filename: "/path/to/FooBlock.loader.ts" }],
|
|
40
|
-
invalid: [
|
|
41
|
-
{ code: `import BarGql from "./BarBlock.loader.gql";`, filename: "/path/to/FooBlock.loader.ts", errors },
|
|
42
|
-
{ code: `import BarGql from "./FooBlock.loader.gql";`, filename: "/path/to/FooBlock.ts", errors },
|
|
43
|
-
],
|
|
44
|
-
});
|
|
@@ -1,57 +0,0 @@
|
|
|
1
|
-
import { type Rule } from "eslint";
|
|
2
|
-
import path from "path";
|
|
3
|
-
|
|
4
|
-
export default {
|
|
5
|
-
meta: {
|
|
6
|
-
type: "suggestion",
|
|
7
|
-
schema: [
|
|
8
|
-
{
|
|
9
|
-
type: "array",
|
|
10
|
-
description: "List of private sibling file extensions, defaults to gql, sc",
|
|
11
|
-
items: {
|
|
12
|
-
type: "string",
|
|
13
|
-
},
|
|
14
|
-
},
|
|
15
|
-
],
|
|
16
|
-
},
|
|
17
|
-
create(context) {
|
|
18
|
-
return {
|
|
19
|
-
ImportDeclaration: function (node) {
|
|
20
|
-
const optionSiblingExtensions = context.options[0] ?? ["gql", "sc"];
|
|
21
|
-
const filePath = context.getPhysicalFilename ? context.getPhysicalFilename() : context.getFilename();
|
|
22
|
-
if (filePath == "<text>") return; // If the input is from stdin, this test can't fail
|
|
23
|
-
const isPrivateFileMatch = String(node.source.value).match(new RegExp(`^(.*)\\.(${optionSiblingExtensions.join("|")})$`));
|
|
24
|
-
if (isPrivateFileMatch) {
|
|
25
|
-
if (!isPrivateFileMatch[1].startsWith("./")) {
|
|
26
|
-
context.report({
|
|
27
|
-
node,
|
|
28
|
-
message: "Import private siblings always with relative imports",
|
|
29
|
-
});
|
|
30
|
-
} else {
|
|
31
|
-
let baseName = path.basename(filePath);
|
|
32
|
-
if (baseName.endsWith(".tsx")) {
|
|
33
|
-
baseName = baseName.slice(0, -4);
|
|
34
|
-
} else if (baseName.endsWith(".ts")) {
|
|
35
|
-
baseName = baseName.slice(0, -3);
|
|
36
|
-
}
|
|
37
|
-
|
|
38
|
-
for (const ext of optionSiblingExtensions) {
|
|
39
|
-
const suffix = `.${ext}`;
|
|
40
|
-
if (baseName.endsWith(suffix)) {
|
|
41
|
-
baseName = baseName.slice(0, -suffix.length);
|
|
42
|
-
break;
|
|
43
|
-
}
|
|
44
|
-
}
|
|
45
|
-
|
|
46
|
-
if (isPrivateFileMatch[1] != `./${baseName}`) {
|
|
47
|
-
context.report({
|
|
48
|
-
node,
|
|
49
|
-
message: "Avoid private sibling import from other files",
|
|
50
|
-
});
|
|
51
|
-
}
|
|
52
|
-
}
|
|
53
|
-
}
|
|
54
|
-
},
|
|
55
|
-
};
|
|
56
|
-
},
|
|
57
|
-
} as Rule.RuleModule;
|