eslint-config-webpack 4.9.2 → 4.9.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/configs/browser.js +4 -0
- package/configs/index.js +38 -12
- package/configs/javascript.js +57 -37
- package/configs/jest.js +31 -9
- package/configs/markdown.js +2 -9
- package/configs/node.js +19 -40
- package/configs/package-json.js +2 -3
- package/configs/react.js +26 -20
- package/configs/stylistic.js +1 -0
- package/configs/typescript.js +378 -344
- package/configs/utils/get-json-file.js +10 -4
- package/configs/utils/is-typescript-installed.js +4 -3
- package/configs/webpack-special.js +2 -3
- package/configs.js +54 -133
- package/package.json +20 -15
- package/plugins/package-json/index.js +4 -1
- package/plugins/package-json/rules/order-properties.js +27 -26
- package/plugins/webpack/index.js +3 -1
- package/plugins/webpack/rules/require-license-comment.js +17 -10
|
@@ -3,18 +3,22 @@ import path from "node:path";
|
|
|
3
3
|
|
|
4
4
|
const SKIP_TIME = 5000;
|
|
5
5
|
|
|
6
|
+
/**
|
|
7
|
+
* @template T [T=import("type-fest").JsonObject]
|
|
8
|
+
*/
|
|
6
9
|
class Cache {
|
|
7
10
|
/**
|
|
8
11
|
* Initialize this cache instance.
|
|
9
12
|
*/
|
|
10
13
|
constructor() {
|
|
14
|
+
/** @type {Map<string, { expire: number, value: T | null }>} */
|
|
11
15
|
this.map = new Map();
|
|
12
16
|
}
|
|
13
17
|
|
|
14
18
|
/**
|
|
15
19
|
* Get the cached value of the given key.
|
|
16
20
|
* @param {string} key The key to get.
|
|
17
|
-
* @returns {
|
|
21
|
+
* @returns {T | null} The cached value or null.
|
|
18
22
|
*/
|
|
19
23
|
get(key) {
|
|
20
24
|
const entry = this.map.get(key);
|
|
@@ -33,7 +37,7 @@ class Cache {
|
|
|
33
37
|
/**
|
|
34
38
|
* Set the value of the given key.
|
|
35
39
|
* @param {string} key The key to set.
|
|
36
|
-
* @param {
|
|
40
|
+
* @param {T | null} value The value to set.
|
|
37
41
|
* @returns {void}
|
|
38
42
|
*/
|
|
39
43
|
set(key, value) {
|
|
@@ -55,9 +59,10 @@ const cache = new Cache();
|
|
|
55
59
|
* Reads the `package.json` data in a given path.
|
|
56
60
|
*
|
|
57
61
|
* Don't cache the data.
|
|
62
|
+
* @template T [T=import("type-fest").JsonObject]
|
|
58
63
|
* @param {string} dir The path to a directory to read.
|
|
59
64
|
* @param {string} filename The filename.
|
|
60
|
-
* @returns {
|
|
65
|
+
* @returns {T | null} The read `package.json` data, or null.
|
|
61
66
|
*/
|
|
62
67
|
function readJsonFile(dir, filename) {
|
|
63
68
|
const filePath = path.join(dir, filename);
|
|
@@ -84,9 +89,10 @@ function readJsonFile(dir, filename) {
|
|
|
84
89
|
/**
|
|
85
90
|
* Gets a `package.json` data.
|
|
86
91
|
* The data is cached if found, then it's used after.
|
|
92
|
+
* @template T [T=import("type-fest").JsonObject]
|
|
87
93
|
* @param {string} filename The filename.
|
|
88
94
|
* @param {string=} startPath A file path to lookup.
|
|
89
|
-
* @returns {
|
|
95
|
+
* @returns {T | null} A found `package.json` data or `null`.
|
|
90
96
|
* This object have additional property `filePath`.
|
|
91
97
|
*/
|
|
92
98
|
function getJsonFile(filename, startPath = "a.js") {
|
|
@@ -4,14 +4,15 @@ import getJsonFile from "./get-json-file.js";
|
|
|
4
4
|
* @returns {boolean} true when typescript is supported by project, otherwise false
|
|
5
5
|
*/
|
|
6
6
|
function isTypescriptInstalled() {
|
|
7
|
+
/** @type {import("type-fest").PackageJson | null} */
|
|
7
8
|
const packageJson = getJsonFile("package.json");
|
|
8
9
|
|
|
9
10
|
if (packageJson === null) {
|
|
10
|
-
return
|
|
11
|
+
return false;
|
|
11
12
|
}
|
|
12
13
|
|
|
13
|
-
const dependencies = packageJson.dependencies ||
|
|
14
|
-
const devDependencies = packageJson.devDependencies ||
|
|
14
|
+
const dependencies = packageJson.dependencies || {};
|
|
15
|
+
const devDependencies = packageJson.devDependencies || {};
|
|
15
16
|
|
|
16
17
|
return Boolean(
|
|
17
18
|
typeof dependencies.typescript !== "undefined" ||
|
|
@@ -1,8 +1,7 @@
|
|
|
1
1
|
import { configs } from "../plugins/webpack/index.js";
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
};
|
|
3
|
+
/** @type {import("eslint").Linter.Config} */
|
|
4
|
+
const recommendedWebpackSpecialConfig = configs.recommended;
|
|
6
5
|
|
|
7
6
|
export default {
|
|
8
7
|
"webpack/special": recommendedWebpackSpecialConfig,
|
package/configs.js
CHANGED
|
@@ -1,9 +1,7 @@
|
|
|
1
1
|
import { globalIgnores } from "eslint/config";
|
|
2
2
|
import semver from "semver";
|
|
3
3
|
import configs from "./configs/index.js";
|
|
4
|
-
import { typescriptExtensions } from "./configs/utils/extensions.js";
|
|
5
4
|
import getJsonFile from "./configs/utils/get-json-file.js";
|
|
6
|
-
import isTypescriptInstalled from "./configs/utils/is-typescript-installed.js";
|
|
7
5
|
import ignorePaths from "./ignore-paths.js";
|
|
8
6
|
|
|
9
7
|
const packageJson = getJsonFile("package.json");
|
|
@@ -14,17 +12,21 @@ const isModule =
|
|
|
14
12
|
packageJson.type === "module";
|
|
15
13
|
|
|
16
14
|
/**
|
|
17
|
-
* @returns {
|
|
15
|
+
* @returns {import("eslint").Linter.Config} javascript configuration
|
|
18
16
|
*/
|
|
19
17
|
function getJavascriptConfig() {
|
|
20
18
|
if (packageJson.engines && packageJson.engines.node) {
|
|
21
|
-
const minVersion = semver.minVersion(packageJson.engines.node)
|
|
19
|
+
const minVersion = semver.minVersion(packageJson.engines.node);
|
|
20
|
+
const minMajorVersion = minVersion ? minVersion.major : undefined;
|
|
22
21
|
|
|
23
22
|
// https://node.green/
|
|
24
23
|
// https://github.com/microsoft/TypeScript/wiki/Node-Target-Mapping
|
|
25
|
-
switch (
|
|
24
|
+
switch (minMajorVersion) {
|
|
26
25
|
case 6: {
|
|
27
|
-
const config = {
|
|
26
|
+
const config = {
|
|
27
|
+
...configs["javascript/es2016"],
|
|
28
|
+
rules: { ...configs["javascript/es2016"].rules },
|
|
29
|
+
};
|
|
28
30
|
|
|
29
31
|
config.rules["prefer-exponentiation-operator"] = "off";
|
|
30
32
|
|
|
@@ -40,13 +42,19 @@ function getJavascriptConfig() {
|
|
|
40
42
|
return configs["javascript/es2018"];
|
|
41
43
|
case 12:
|
|
42
44
|
case 13: {
|
|
45
|
+
/** @type {import("eslint").Linter.Config["languageOptions"]} */
|
|
46
|
+
const original = configs["javascript/es2019"].languageOptions;
|
|
47
|
+
/** @type {import("eslint").Linter.Config["languageOptions"]} */
|
|
43
48
|
const languageOptions = {
|
|
44
|
-
...
|
|
49
|
+
...original,
|
|
50
|
+
globals: {
|
|
51
|
+
// @ts-expect-error always exist
|
|
52
|
+
...original.globals,
|
|
53
|
+
Promise: false,
|
|
54
|
+
BigInt: false,
|
|
55
|
+
},
|
|
45
56
|
};
|
|
46
57
|
|
|
47
|
-
languageOptions.globals.Promise = false;
|
|
48
|
-
languageOptions.globals.BigInt = false;
|
|
49
|
-
|
|
50
58
|
return { ...configs["javascript/es2019"], languageOptions };
|
|
51
59
|
}
|
|
52
60
|
case 14:
|
|
@@ -76,94 +84,7 @@ function getJavascriptConfig() {
|
|
|
76
84
|
return configs["javascript/recommended"];
|
|
77
85
|
}
|
|
78
86
|
|
|
79
|
-
/**
|
|
80
|
-
* @returns {Promise<Record<string, string>>} config
|
|
81
|
-
*/
|
|
82
|
-
function getTypescriptJSdocConfig() {
|
|
83
|
-
return isTypescriptInstalled() ? configs["typescript/jsdoc"] : [];
|
|
84
|
-
}
|
|
85
|
-
|
|
86
|
-
/**
|
|
87
|
-
* @returns {Promise<Record<string, string>>} config
|
|
88
|
-
*/
|
|
89
|
-
function getTypescriptConfig() {
|
|
90
|
-
if (!isTypescriptInstalled()) {
|
|
91
|
-
return {};
|
|
92
|
-
}
|
|
93
|
-
|
|
94
|
-
const tsconfigJson = getJsonFile("tsconfig.json");
|
|
95
|
-
|
|
96
|
-
const isNoEmitEnabled =
|
|
97
|
-
(tsconfigJson &&
|
|
98
|
-
tsconfigJson.compilerOptions &&
|
|
99
|
-
tsconfigJson.compilerOptions.noEmit) ||
|
|
100
|
-
false;
|
|
101
|
-
|
|
102
|
-
if (isNoEmitEnabled) {
|
|
103
|
-
return {};
|
|
104
|
-
}
|
|
105
|
-
|
|
106
|
-
const isStrict =
|
|
107
|
-
(tsconfigJson &&
|
|
108
|
-
tsconfigJson.compilerOptions &&
|
|
109
|
-
tsconfigJson.compilerOptions.strict) ||
|
|
110
|
-
true;
|
|
111
|
-
|
|
112
|
-
return [
|
|
113
|
-
configs["typescript/recommended"],
|
|
114
|
-
isStrict
|
|
115
|
-
? {
|
|
116
|
-
files: [
|
|
117
|
-
`**/*.{${typescriptExtensions.map((item) => item.slice(1)).join(",")}}`,
|
|
118
|
-
],
|
|
119
|
-
ignores: ["**/*.d.ts"],
|
|
120
|
-
rules: { strict: "off" },
|
|
121
|
-
}
|
|
122
|
-
: {},
|
|
123
|
-
];
|
|
124
|
-
}
|
|
125
|
-
|
|
126
|
-
/**
|
|
127
|
-
* @returns {Promise<Record<string, string>>} config
|
|
128
|
-
*/
|
|
129
|
-
function getReactConfig() {
|
|
130
|
-
if (packageJson === null) {
|
|
131
|
-
return [];
|
|
132
|
-
}
|
|
133
|
-
|
|
134
|
-
const dependencies = packageJson.dependencies || [];
|
|
135
|
-
const devDependencies = packageJson.devDependencies || [];
|
|
136
|
-
|
|
137
|
-
return typeof dependencies.react !== "undefined" ||
|
|
138
|
-
typeof dependencies.preact !== "undefined" ||
|
|
139
|
-
typeof devDependencies.react !== "undefined" ||
|
|
140
|
-
typeof devDependencies.preact !== "undefined"
|
|
141
|
-
? configs["react/recommended"]
|
|
142
|
-
: [];
|
|
143
|
-
}
|
|
144
|
-
|
|
145
|
-
/**
|
|
146
|
-
* @returns {Promise<Record<string, string>>} config
|
|
147
|
-
*/
|
|
148
|
-
function getJestConfig() {
|
|
149
|
-
if (packageJson === null) {
|
|
150
|
-
return [];
|
|
151
|
-
}
|
|
152
|
-
|
|
153
|
-
const dependencies = packageJson.dependencies || [];
|
|
154
|
-
const devDependencies = packageJson.devDependencies || [];
|
|
155
|
-
|
|
156
|
-
return typeof dependencies.jest !== "undefined" ||
|
|
157
|
-
typeof devDependencies.jest !== "undefined"
|
|
158
|
-
? configs["jest/recommended"]
|
|
159
|
-
: [];
|
|
160
|
-
}
|
|
161
|
-
|
|
162
87
|
const javascriptConfig = getJavascriptConfig();
|
|
163
|
-
const typescriptJSDocConfig = getTypescriptJSdocConfig();
|
|
164
|
-
const typescriptConfig = getTypescriptConfig();
|
|
165
|
-
const reactConfig = getReactConfig();
|
|
166
|
-
const jestConfig = getJestConfig();
|
|
167
88
|
|
|
168
89
|
const recommended = [
|
|
169
90
|
globalIgnores(ignorePaths),
|
|
@@ -171,10 +92,10 @@ const recommended = [
|
|
|
171
92
|
? configs["node/mixed-module-and-commonjs"]
|
|
172
93
|
: configs["node/mixed-commonjs-and-module"],
|
|
173
94
|
javascriptConfig,
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
95
|
+
configs["typescript/jsdoc"],
|
|
96
|
+
configs["typescript/recommended"],
|
|
97
|
+
configs["react/recommended"],
|
|
98
|
+
configs["jest/recommended"],
|
|
178
99
|
configs["markdown/recommended"],
|
|
179
100
|
configs["stylistic/recommended"],
|
|
180
101
|
configs["package-json/recommended"],
|
|
@@ -189,10 +110,10 @@ const nodeRecommendedModule = [
|
|
|
189
110
|
globalIgnores(ignorePaths),
|
|
190
111
|
configs["node/mixed-module-and-commonjs"],
|
|
191
112
|
javascriptConfig,
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
113
|
+
configs["typescript/jsdoc"],
|
|
114
|
+
configs["typescript/recommended"],
|
|
115
|
+
configs["react/recommended"],
|
|
116
|
+
configs["jest/recommended"],
|
|
196
117
|
configs["markdown/recommended"],
|
|
197
118
|
configs["stylistic/recommended"],
|
|
198
119
|
configs["package-json/recommended"],
|
|
@@ -207,10 +128,10 @@ const nodeRecommendedCommonJS = [
|
|
|
207
128
|
globalIgnores(ignorePaths),
|
|
208
129
|
configs["node/mixed-commonjs-and-module"],
|
|
209
130
|
javascriptConfig,
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
131
|
+
configs["typescript/jsdoc"],
|
|
132
|
+
configs["typescript/recommended"],
|
|
133
|
+
configs["react/recommended"],
|
|
134
|
+
configs["jest/recommended"],
|
|
214
135
|
configs["markdown/recommended"],
|
|
215
136
|
configs["stylistic/recommended"],
|
|
216
137
|
configs["package-json/recommended"],
|
|
@@ -225,10 +146,10 @@ const nodeRecommendedDirty = [
|
|
|
225
146
|
globalIgnores(ignorePaths),
|
|
226
147
|
configs["node/mixed-dirty"],
|
|
227
148
|
javascriptConfig,
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
149
|
+
configs["typescript/jsdoc"],
|
|
150
|
+
configs["typescript/recommended"],
|
|
151
|
+
configs["react/recommended"],
|
|
152
|
+
configs["jest/recommended"],
|
|
232
153
|
configs["markdown/recommended"],
|
|
233
154
|
configs["stylistic/recommended"],
|
|
234
155
|
configs["package-json/recommended"],
|
|
@@ -242,10 +163,10 @@ const browserRecommended = [
|
|
|
242
163
|
globalIgnores(ignorePaths),
|
|
243
164
|
configs["browser/recommended"],
|
|
244
165
|
javascriptConfig,
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
166
|
+
configs["typescript/jsdoc"],
|
|
167
|
+
configs["typescript/recommended"],
|
|
168
|
+
configs["react/recommended"],
|
|
169
|
+
configs["jest/recommended"],
|
|
249
170
|
configs["markdown/recommended"],
|
|
250
171
|
configs["stylistic/recommended"],
|
|
251
172
|
configs["package-json/recommended"],
|
|
@@ -257,10 +178,10 @@ const browserOutdatedRecommendedScript = [
|
|
|
257
178
|
globalIgnores(ignorePaths),
|
|
258
179
|
configs["browser/recommended-outdated-script"],
|
|
259
180
|
configs["javascript/es5"],
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
181
|
+
configs["typescript/jsdoc"],
|
|
182
|
+
configs["typescript/recommended"],
|
|
183
|
+
configs["react/recommended"],
|
|
184
|
+
configs["jest/recommended"],
|
|
264
185
|
configs["markdown/recommended"],
|
|
265
186
|
configs["stylistic/recommended"],
|
|
266
187
|
configs["package-json/recommended"],
|
|
@@ -273,10 +194,10 @@ const browserOutdatedRecommendedCommonjs = [
|
|
|
273
194
|
globalIgnores(ignorePaths),
|
|
274
195
|
configs["browser/recommended-outdated-commonjs"],
|
|
275
196
|
configs["javascript/es5"],
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
197
|
+
configs["typescript/jsdoc"],
|
|
198
|
+
configs["typescript/recommended"],
|
|
199
|
+
configs["react/recommended"],
|
|
200
|
+
configs["jest/recommended"],
|
|
280
201
|
configs["markdown/recommended"],
|
|
281
202
|
configs["stylistic/recommended"],
|
|
282
203
|
configs["package-json/recommended"],
|
|
@@ -294,10 +215,10 @@ const browserOutdatedRecommendedModule = [
|
|
|
294
215
|
ecmaVersion: "latest",
|
|
295
216
|
},
|
|
296
217
|
},
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
218
|
+
configs["typescript/jsdoc"],
|
|
219
|
+
configs["typescript/recommended"],
|
|
220
|
+
configs["react/recommended"],
|
|
221
|
+
configs["jest/recommended"],
|
|
301
222
|
configs["markdown/recommended"],
|
|
302
223
|
configs["stylistic/recommended"],
|
|
303
224
|
configs["package-json/recommended"],
|
|
@@ -316,10 +237,10 @@ const universalRecommended = [
|
|
|
316
237
|
? configs["node/mixed-module-and-commonjs"]
|
|
317
238
|
: configs["node/mixed-commonjs-and-module"],
|
|
318
239
|
javascriptConfig,
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
240
|
+
configs["typescript/jsdoc"],
|
|
241
|
+
configs["typescript/recommended"],
|
|
242
|
+
configs["react/recommended"],
|
|
243
|
+
configs["jest/recommended"],
|
|
323
244
|
configs["markdown/recommended"],
|
|
324
245
|
configs["stylistic/recommended"],
|
|
325
246
|
configs["package-json/recommended"],
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "eslint-config-webpack",
|
|
3
|
-
"version": "4.9.
|
|
3
|
+
"version": "4.9.4",
|
|
4
4
|
"description": "Provides Webpack's eslint rules as an extensible shared config",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"eslint",
|
|
@@ -32,43 +32,48 @@
|
|
|
32
32
|
"configs"
|
|
33
33
|
],
|
|
34
34
|
"scripts": {
|
|
35
|
-
"lint": "npm run lint:code",
|
|
35
|
+
"lint": "npm run lint:code && npm run lint:types",
|
|
36
36
|
"lint:code": "eslint --cache .",
|
|
37
|
-
"
|
|
37
|
+
"lint:types": "tsc -p tsconfig.internal.json",
|
|
38
|
+
"version": "changeset version",
|
|
39
|
+
"release": "changeset publish"
|
|
38
40
|
},
|
|
39
41
|
"dependencies": {
|
|
40
42
|
"@eslint/js": "^9.39.2",
|
|
41
43
|
"@eslint/markdown": "^7.5.1",
|
|
42
|
-
"@stylistic/eslint-plugin": "^5.
|
|
44
|
+
"@stylistic/eslint-plugin": "^5.10.0",
|
|
43
45
|
"detect-indent": "^7.0.2",
|
|
44
46
|
"eslint-config-prettier": "^10.1.8",
|
|
45
47
|
"eslint-plugin-import": "^2.32.0",
|
|
46
|
-
"eslint-plugin-jest": "^29.
|
|
47
|
-
"eslint-plugin-jsdoc": "^62.
|
|
48
|
-
"eslint-plugin-n": "^17.
|
|
48
|
+
"eslint-plugin-jest": "^29.15.0",
|
|
49
|
+
"eslint-plugin-jsdoc": "^62.8.0",
|
|
50
|
+
"eslint-plugin-n": "^17.24.0",
|
|
49
51
|
"eslint-plugin-prettier": "^5.5.5",
|
|
50
52
|
"eslint-plugin-react": "^7.37.5",
|
|
51
53
|
"eslint-plugin-react-hooks": "^7.0.1",
|
|
52
|
-
"eslint-plugin-unicorn": "^
|
|
53
|
-
"globals": "^17.
|
|
54
|
-
"jsonc-eslint-parser": "^
|
|
55
|
-
"semver": "^7.7.
|
|
54
|
+
"eslint-plugin-unicorn": "^63.0.0",
|
|
55
|
+
"globals": "^17.4.0",
|
|
56
|
+
"jsonc-eslint-parser": "^3.1.0",
|
|
57
|
+
"semver": "^7.7.4",
|
|
56
58
|
"sort-package-json": "^3.6.0",
|
|
57
|
-
"typescript-eslint": "^8.
|
|
59
|
+
"typescript-eslint": "^8.57.2"
|
|
58
60
|
},
|
|
59
61
|
"devDependencies": {
|
|
62
|
+
"@changesets/cli": "^2.30.0",
|
|
63
|
+
"@changesets/get-github-info": "^0.8.0",
|
|
64
|
+
"@types/semver": "^7.7.1",
|
|
60
65
|
"eslint": "^9.39.2",
|
|
61
66
|
"eslint-find-rules": "^5.0.0",
|
|
62
|
-
"jest": "^30.
|
|
67
|
+
"jest": "^30.3.0",
|
|
63
68
|
"prettier": "^3.8.1",
|
|
64
69
|
"react": "^19.2.3",
|
|
65
70
|
"react-dom": "^19.2.3",
|
|
66
|
-
"
|
|
71
|
+
"type-fest": "^5.5.0",
|
|
67
72
|
"typescript": "^5.9.3"
|
|
68
73
|
},
|
|
69
74
|
"peerDependencies": {
|
|
70
75
|
"eslint": ">= 9.28.0",
|
|
71
|
-
"typescript": ">=4.8.4 <
|
|
76
|
+
"typescript": ">=4.8.4 <7.0.0"
|
|
72
77
|
},
|
|
73
78
|
"peerDependenciesMeta": {
|
|
74
79
|
"typescript": {
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { createRequire } from "node:module";
|
|
2
|
+
// eslint-disable-next-line import/no-unresolved
|
|
2
3
|
import * as parserJsonc from "jsonc-eslint-parser";
|
|
3
4
|
import { rule as orderProperties } from "./rules/order-properties.js";
|
|
4
5
|
|
|
@@ -10,14 +11,16 @@ const rules = {
|
|
|
10
11
|
"order-properties": orderProperties,
|
|
11
12
|
};
|
|
12
13
|
|
|
14
|
+
/** @type {import("eslint").Linter.Config["rules"]} */
|
|
13
15
|
const recommendedRules = {
|
|
14
16
|
...Object.fromEntries(
|
|
15
17
|
Object.entries(rules)
|
|
16
|
-
.filter(([, rule]) => rule.meta
|
|
18
|
+
.filter(([, rule]) => rule.meta?.docs?.recommended)
|
|
17
19
|
.map(([name]) => [`package-json/${name}`, "error"]),
|
|
18
20
|
),
|
|
19
21
|
};
|
|
20
22
|
|
|
23
|
+
/** @type {Record<"recommended", import("eslint").Linter.Config>} */
|
|
21
24
|
const configs = {
|
|
22
25
|
recommended: {
|
|
23
26
|
name: "package-json/recommended",
|
|
@@ -1,9 +1,13 @@
|
|
|
1
1
|
import detectIndent from "detect-indent";
|
|
2
2
|
import { sortOrder } from "sort-package-json";
|
|
3
3
|
|
|
4
|
+
/** @typedef {import("jsonc-eslint-parser").AST.JSONProgram} JSONProgram */
|
|
5
|
+
/** @typedef {import("jsonc-eslint-parser").AST.JSONExpression} JSONExpression */
|
|
6
|
+
/** @typedef {import("jsonc-eslint-parser").AST.JSONObjectExpression} JSONObjectExpression */
|
|
7
|
+
|
|
4
8
|
/**
|
|
5
9
|
* @param {string} string string
|
|
6
|
-
* @returns {"\r\n" | "\n"} detected newline
|
|
10
|
+
* @returns {"\r\n" | "\n" | undefined} detected newline
|
|
7
11
|
*/
|
|
8
12
|
function detectNewline(string) {
|
|
9
13
|
if (typeof string !== "string") {
|
|
@@ -30,13 +34,12 @@ function detectNewlineGraceful(string) {
|
|
|
30
34
|
return detectNewline(string) || "\n";
|
|
31
35
|
}
|
|
32
36
|
|
|
33
|
-
|
|
34
|
-
/** @typedef {Record<string, any>} ObjectToSort */
|
|
37
|
+
/** @typedef {import("type-fest").PackageJson} PackageJson */
|
|
35
38
|
|
|
36
39
|
/**
|
|
37
|
-
* @param {
|
|
38
|
-
* @param {(a:
|
|
39
|
-
* @returns {
|
|
40
|
+
* @param {PackageJson} object object to sort
|
|
41
|
+
* @param {string[] | ((a: string, b: string) => number)} sortWith function to sort
|
|
42
|
+
* @returns {PackageJson} object with sorted properties
|
|
40
43
|
*/
|
|
41
44
|
function sortObjectKeys(object, sortWith) {
|
|
42
45
|
let keys;
|
|
@@ -47,8 +50,9 @@ function sortObjectKeys(object, sortWith) {
|
|
|
47
50
|
} else {
|
|
48
51
|
keys = sortWith;
|
|
49
52
|
}
|
|
50
|
-
|
|
51
|
-
|
|
53
|
+
const objectKeys =
|
|
54
|
+
/** @type {(keyof PackageJson)[]} */
|
|
55
|
+
(Object.keys(object));
|
|
52
56
|
|
|
53
57
|
return (keys || objectKeys.toSorted(sortFn)).reduce((total, key) => {
|
|
54
58
|
if (Object.hasOwn(object, key)) {
|
|
@@ -56,7 +60,7 @@ function sortObjectKeys(object, sortWith) {
|
|
|
56
60
|
}
|
|
57
61
|
|
|
58
62
|
return total;
|
|
59
|
-
}, Object.create(null));
|
|
63
|
+
}, /** @type {PackageJson} */ (Object.create(null)));
|
|
60
64
|
}
|
|
61
65
|
|
|
62
66
|
/**
|
|
@@ -66,21 +70,9 @@ function sortObjectKeys(object, sortWith) {
|
|
|
66
70
|
export const isPackageJson = (filePath) =>
|
|
67
71
|
/(?:^|[/\\])package.json$/.test(filePath);
|
|
68
72
|
|
|
69
|
-
/* eslint-disable jsdoc/reject-any-type */
|
|
70
|
-
/**
|
|
71
|
-
* @typedef {import("eslint").AST.Program} PackageJsonAst
|
|
72
|
-
* @property {[any]} body body
|
|
73
|
-
*/
|
|
74
|
-
/* eslint-enable jsdoc/reject-any-type */
|
|
75
|
-
|
|
76
|
-
/**
|
|
77
|
-
* @typedef {import("eslint").SourceCode} PackageJsonSourceCode
|
|
78
|
-
* @property {PackageJsonAst} ast ast
|
|
79
|
-
*/
|
|
80
|
-
|
|
81
73
|
/**
|
|
82
74
|
* @template {unknown[]} [Options=unknown[]]
|
|
83
|
-
* @typedef {import("eslint").RuleContext} PackageJsonRuleContext
|
|
75
|
+
* @typedef {import("eslint").Rule.RuleContext} PackageJsonRuleContext
|
|
84
76
|
* @property {Options} options options
|
|
85
77
|
* @property {PackageJsonSourceCode} sourceCode source code
|
|
86
78
|
*/
|
|
@@ -89,11 +81,11 @@ export const isPackageJson = (filePath) =>
|
|
|
89
81
|
* @template {unknown[]} Options
|
|
90
82
|
* @typedef {object} PackageJsonRuleModule
|
|
91
83
|
* @property {import("eslint").Rule.RuleMetaData} meta meta
|
|
92
|
-
* @property {(context: PackageJsonRuleContext<Options>) => import("eslint").RuleListener} create function to create
|
|
84
|
+
* @property {(context: PackageJsonRuleContext<Options>) => import("eslint").Rule.RuleListener} create function to create
|
|
93
85
|
*/
|
|
94
86
|
|
|
95
87
|
/**
|
|
96
|
-
* @type {import("eslint").Rule} rule
|
|
88
|
+
* @type {import("eslint").Rule.RuleModule} rule rule
|
|
97
89
|
*/
|
|
98
90
|
export const rule = {
|
|
99
91
|
create(context) {
|
|
@@ -111,8 +103,11 @@ export const rule = {
|
|
|
111
103
|
};
|
|
112
104
|
|
|
113
105
|
const requiredOrder =
|
|
114
|
-
options.order === "sort-package-json"
|
|
106
|
+
options.order === "sort-package-json"
|
|
107
|
+
? sortOrder
|
|
108
|
+
: /** @type {string[]} */ (options.order);
|
|
115
109
|
|
|
110
|
+
/** @type {import("type-fest").PackageJson} */
|
|
116
111
|
const json = JSON.parse(text);
|
|
117
112
|
const orderedSource = sortObjectKeys(json, [
|
|
118
113
|
...requiredOrder,
|
|
@@ -120,10 +115,16 @@ export const rule = {
|
|
|
120
115
|
]);
|
|
121
116
|
const orderedKeys = Object.keys(orderedSource);
|
|
122
117
|
|
|
123
|
-
const { properties } =
|
|
118
|
+
const { properties } =
|
|
119
|
+
/** @type {JSONObjectExpression} */
|
|
120
|
+
(
|
|
121
|
+
/** @type {JSONProgram} */ (/** @type {unknown} */ (ast)).body[0]
|
|
122
|
+
.expression
|
|
123
|
+
);
|
|
124
124
|
|
|
125
125
|
for (let i = 0; i < properties.length; i += 1) {
|
|
126
126
|
const property = properties[i].key;
|
|
127
|
+
// @ts-expect-error need improve types
|
|
127
128
|
const { value } = property;
|
|
128
129
|
|
|
129
130
|
if (value === orderedKeys[i]) {
|
package/plugins/webpack/index.js
CHANGED
|
@@ -10,14 +10,16 @@ const rules = {
|
|
|
10
10
|
"require-license-comment": requireLicenseComment,
|
|
11
11
|
};
|
|
12
12
|
|
|
13
|
+
/** @type {import("eslint").Linter.Config["rules"]} */
|
|
13
14
|
const recommendedRules = {
|
|
14
15
|
...Object.fromEntries(
|
|
15
16
|
Object.entries(rules)
|
|
16
|
-
.filter(([, rule]) => rule.meta
|
|
17
|
+
.filter(([, rule]) => rule.meta?.docs?.recommended)
|
|
17
18
|
.map(([name]) => [`webpack/${name}`, "error"]),
|
|
18
19
|
),
|
|
19
20
|
};
|
|
20
21
|
|
|
22
|
+
/** @type {Record<"recommended", import("eslint").Linter.Config>} */
|
|
21
23
|
const configs = {
|
|
22
24
|
recommended: {
|
|
23
25
|
name: "webpack/recommended",
|
|
@@ -1,5 +1,8 @@
|
|
|
1
|
+
/** @typedef {import("estree").Comment} Comment */
|
|
2
|
+
/** @typedef {import("eslint").AST.SourceLocation} SourceLocation */
|
|
3
|
+
|
|
1
4
|
/**
|
|
2
|
-
* @type {import("eslint").Rule} rule
|
|
5
|
+
* @type {import("eslint").Rule.RuleModule} rule rule
|
|
3
6
|
*/
|
|
4
7
|
export const rule = {
|
|
5
8
|
create(context) {
|
|
@@ -8,13 +11,17 @@ export const rule = {
|
|
|
8
11
|
return {
|
|
9
12
|
"Program:exit"(program) {
|
|
10
13
|
const comments = sourceCode.getAllComments();
|
|
11
|
-
const licenseComment =
|
|
12
|
-
(
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
comment
|
|
16
|
-
|
|
17
|
-
|
|
14
|
+
const licenseComment =
|
|
15
|
+
/** @type {(Comment & { start: number, end: number }) | undefined} */
|
|
16
|
+
(
|
|
17
|
+
comments.find(
|
|
18
|
+
(comment) =>
|
|
19
|
+
comment.type === "Block" &&
|
|
20
|
+
/\n\s*MIT License http:\/\/www\.opensource\.org\/licenses\/mit-license\.php\n\s*(?:(Authors? .+)\n)?\s*/g.test(
|
|
21
|
+
comment.value,
|
|
22
|
+
),
|
|
23
|
+
)
|
|
24
|
+
);
|
|
18
25
|
|
|
19
26
|
if (!licenseComment) {
|
|
20
27
|
context.report({
|
|
@@ -29,7 +36,7 @@ export const rule = {
|
|
|
29
36
|
|
|
30
37
|
if (afterComment !== "\n") {
|
|
31
38
|
context.report({
|
|
32
|
-
loc: licenseComment.loc,
|
|
39
|
+
loc: /** @type {SourceLocation} */ (licenseComment.loc),
|
|
33
40
|
message: "Expected newline after license comment.",
|
|
34
41
|
});
|
|
35
42
|
|
|
@@ -40,7 +47,7 @@ export const rule = {
|
|
|
40
47
|
|
|
41
48
|
if (afterAfterComment !== "\n") {
|
|
42
49
|
context.report({
|
|
43
|
-
loc: licenseComment.loc,
|
|
50
|
+
loc: /** @type {SourceLocation} */ (licenseComment.loc),
|
|
44
51
|
message: "Expected newline after license comment.",
|
|
45
52
|
});
|
|
46
53
|
}
|