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.
@@ -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 {import("type-fest").JsonObject} The cached value or null.
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 {import("type-fest").JsonObject} value The value to set.
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 {import("type-fest").JsonObject | null} The read `package.json` data, or null.
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 {import("type-fest").JsonObject | null} A found `package.json` data or `null`.
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
- const recommendedWebpackSpecialConfig = {
4
- ...configs.recommended,
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 {Record<string, string>} javascript configuration
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).major;
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 (minVersion) {
24
+ switch (minMajorVersion) {
26
25
  case 6: {
27
- const config = { ...configs["javascript/es2016"] };
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
- ...configs["javascript/es2019"].languageOptions,
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
- typescriptJSDocConfig,
175
- typescriptConfig,
176
- reactConfig,
177
- jestConfig,
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
- typescriptJSDocConfig,
193
- typescriptConfig,
194
- reactConfig,
195
- jestConfig,
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
- typescriptJSDocConfig,
211
- typescriptConfig,
212
- reactConfig,
213
- jestConfig,
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
- typescriptJSDocConfig,
229
- typescriptConfig,
230
- reactConfig,
231
- jestConfig,
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
- typescriptJSDocConfig,
246
- typescriptConfig,
247
- reactConfig,
248
- jestConfig,
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
- typescriptJSDocConfig,
261
- typescriptConfig,
262
- reactConfig,
263
- jestConfig,
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
- typescriptJSDocConfig,
277
- typescriptConfig,
278
- reactConfig,
279
- jestConfig,
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
- typescriptJSDocConfig,
298
- typescriptConfig,
299
- reactConfig,
300
- jestConfig,
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
- typescriptJSDocConfig,
320
- typescriptConfig,
321
- reactConfig,
322
- jestConfig,
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.2",
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
- "release": "standard-version"
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.7.0",
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.12.1",
47
- "eslint-plugin-jsdoc": "^62.4.1",
48
- "eslint-plugin-n": "^17.23.2",
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": "^62.0.0",
53
- "globals": "^17.0.0",
54
- "jsonc-eslint-parser": "^2.4.2",
55
- "semver": "^7.7.3",
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.53.1"
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.2.0",
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
- "standard-version": "^9.5.0",
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 <6.0.0"
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.docs?.recommended)
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
- // eslint-disable-next-line jsdoc/reject-any-type
34
- /** @typedef {Record<string, any>} ObjectToSort */
37
+ /** @typedef {import("type-fest").PackageJson} PackageJson */
35
38
 
36
39
  /**
37
- * @param {ObjectToSort} object object to sort
38
- * @param {(a: number, b: number) => number} sortWith function to sort
39
- * @returns {ObjectToSort} object with sorted properties
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
- const objectKeys = Object.keys(object);
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" ? sortOrder : options.order;
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 } = ast.body[0].expression;
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]) {
@@ -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.docs?.recommended)
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 = comments.find(
12
- (comment) =>
13
- comment.type === "Block" &&
14
- /\n\s*MIT License http:\/\/www\.opensource\.org\/licenses\/mit-license\.php\n\s*(?:(Authors? .+)\n)?\s*/g.test(
15
- comment.value,
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
  }