@vida0905/eslint-config 2.8.0 → 2.10.0

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.
File without changes
@@ -6,7 +6,7 @@ import path from "node:path";
6
6
  import { styleText } from "node:util";
7
7
 
8
8
  //#region package.json
9
- var version = "2.8.0";
9
+ var version = "2.10.0";
10
10
 
11
11
  //#endregion
12
12
  //#region src/cli/constants.ts
package/dist/index.d.mts CHANGED
@@ -15,6 +15,79 @@ interface RuleOptions {
15
15
  * @see https://github.com/azat-io/eslint-plugin-de-morgan/blob/main/docs/no-negated-disjunction.md
16
16
  */
17
17
  'de-morgan/no-negated-disjunction'?: Linter.RuleEntry<[]>;
18
+ /**
19
+ * Bans a list of dependencies from being used
20
+ * @see https://github.com/es-tooling/eslint-plugin-depend/blob/main/docs/rules/ban-dependencies.md
21
+ */
22
+ 'e18e/ban-dependencies'?: Linter.RuleEntry<E18EBanDependencies>;
23
+ /**
24
+ * Prefer optimized alternatives to `indexOf()` equality checks
25
+ */
26
+ 'e18e/no-indexof-equality'?: Linter.RuleEntry<[]>;
27
+ /**
28
+ * Prefer Array.prototype.at() over length-based indexing
29
+ */
30
+ 'e18e/prefer-array-at'?: Linter.RuleEntry<[]>;
31
+ /**
32
+ * Prefer Array.prototype.fill() over Array.from or map with constant values
33
+ */
34
+ 'e18e/prefer-array-fill'?: Linter.RuleEntry<[]>;
35
+ /**
36
+ * Prefer Array.from(iterable, mapper) over [...iterable].map(mapper) to avoid intermediate array allocation
37
+ */
38
+ 'e18e/prefer-array-from-map'?: Linter.RuleEntry<[]>;
39
+ /**
40
+ * Prefer Array.some() over Array.find() when checking for element existence
41
+ */
42
+ 'e18e/prefer-array-some'?: Linter.RuleEntry<[]>;
43
+ /**
44
+ * Prefer Array.prototype.toReversed() over copying and reversing arrays
45
+ */
46
+ 'e18e/prefer-array-to-reversed'?: Linter.RuleEntry<[]>;
47
+ /**
48
+ * Prefer Array.prototype.toSorted() over copying and sorting arrays
49
+ */
50
+ 'e18e/prefer-array-to-sorted'?: Linter.RuleEntry<[]>;
51
+ /**
52
+ * Prefer Array.prototype.toSpliced() over copying and splicing arrays
53
+ */
54
+ 'e18e/prefer-array-to-spliced'?: Linter.RuleEntry<[]>;
55
+ /**
56
+ * Prefer Date.now() over new Date().getTime() and +new Date()
57
+ */
58
+ 'e18e/prefer-date-now'?: Linter.RuleEntry<[]>;
59
+ /**
60
+ * Prefer the exponentiation operator ** over Math.pow()
61
+ */
62
+ 'e18e/prefer-exponentiation-operator'?: Linter.RuleEntry<[]>;
63
+ /**
64
+ * Prefer .includes() over indexOf() comparisons for arrays and strings
65
+ */
66
+ 'e18e/prefer-includes'?: Linter.RuleEntry<[]>;
67
+ /**
68
+ * Prefer nullish coalescing operator (?? and ??=) over verbose null checks
69
+ */
70
+ 'e18e/prefer-nullish-coalescing'?: Linter.RuleEntry<[]>;
71
+ /**
72
+ * Prefer Object.hasOwn() over Object.prototype.hasOwnProperty.call() and obj.hasOwnProperty()
73
+ */
74
+ 'e18e/prefer-object-has-own'?: Linter.RuleEntry<[]>;
75
+ /**
76
+ * prefer `RegExp.test()` over `String.match()` and `RegExp.exec()` when only checking for match existence
77
+ */
78
+ 'e18e/prefer-regex-test'?: Linter.RuleEntry<[]>;
79
+ /**
80
+ * Prefer spread syntax over Array.concat(), Array.from(), Object.assign({}, ...), and Function.apply()
81
+ */
82
+ 'e18e/prefer-spread-syntax'?: Linter.RuleEntry<[]>;
83
+ /**
84
+ * Prefer passing function and arguments directly to setTimeout/setInterval instead of wrapping in an arrow function or using bind
85
+ */
86
+ 'e18e/prefer-timer-args'?: Linter.RuleEntry<[]>;
87
+ /**
88
+ * Prefer URL.canParse() over try-catch blocks for URL validation
89
+ */
90
+ 'e18e/prefer-url-canparse'?: Linter.RuleEntry<[]>;
18
91
  /**
19
92
  * Prefer recommended order of Nuxt config properties
20
93
  * @see https://eslint.nuxt.com/packages/plugin#nuxtnuxt-config-keys-order
@@ -26,6 +99,13 @@ interface RuleOptions {
26
99
  */
27
100
  'nuxt/prefer-import-meta'?: Linter.RuleEntry<[]>;
28
101
  }
102
+ /* ======= Declarations ======= */
103
+ // ----- e18e/ban-dependencies -----
104
+ type E18EBanDependencies = [] | [{
105
+ presets?: string[];
106
+ modules?: string[];
107
+ allowed?: string[];
108
+ }]; // Names of all the configs
29
109
  //#endregion
30
110
  //#region src/types.d.ts
31
111
  interface Rules extends RuleOptions {}
@@ -49,6 +129,13 @@ type OptionsConfig$1 = Omit<OptionsConfig, "overrides"> & {
49
129
  */
50
130
  deMorgan?: boolean | OptionsFiles;
51
131
  /**
132
+ * Enable e18e rules.
133
+ *
134
+ * @see https://github.com/e18e/eslint-plugin
135
+ * @default true
136
+ */
137
+ e18e?: boolean | OptionsOverrides & OptionsFiles;
138
+ /**
52
139
  * Enable Nuxt.js rules.
53
140
  *
54
141
  * Requires installing:
@@ -59,11 +146,8 @@ type OptionsConfig$1 = Omit<OptionsConfig, "overrides"> & {
59
146
  nuxt?: boolean | OptionsOverrides & OptionsFiles;
60
147
  };
61
148
  //#endregion
62
- //#region src/utils.d.ts
63
- declare function deepMerge<T extends object>(target: T, source: T): T;
64
- //#endregion
65
149
  //#region src/index.d.ts
66
150
  declare function defineConfig(options?: OptionsConfig$1, ...userConfigs: Awaitable<TypedFlatConfigItem>[]): FlatConfigComposer<TypedFlatConfigItem, ConfigNames>;
67
151
  declare function applyOptions(options: OptionsConfig$1): OptionsConfig$1;
68
152
  //#endregion
69
- export { applyOptions, deepMerge, defineConfig as default, defineConfig };
153
+ export { applyOptions, defineConfig as default, defineConfig };
package/dist/index.mjs CHANGED
@@ -1,9 +1,77 @@
1
1
  import antfu, { GLOB_SRC, ensurePackages, interopDefault } from "@antfu/eslint-config";
2
2
  import { isPackageExists } from "local-pkg";
3
-
4
- export * from "@antfu/eslint-config"
5
-
6
- //#region src/configs/de-morgan.ts
3
+ export * from "@antfu/eslint-config";
4
+ function isPrimitive(value) {
5
+ return value == null || typeof value !== "object" && typeof value !== "function";
6
+ }
7
+ function isTypedArray(x) {
8
+ return ArrayBuffer.isView(x) && !(x instanceof DataView);
9
+ }
10
+ function clone(obj) {
11
+ if (isPrimitive(obj)) return obj;
12
+ if (Array.isArray(obj) || isTypedArray(obj) || obj instanceof ArrayBuffer || typeof SharedArrayBuffer !== "undefined" && obj instanceof SharedArrayBuffer) return obj.slice(0);
13
+ const prototype = Object.getPrototypeOf(obj);
14
+ if (prototype == null) return Object.assign(Object.create(prototype), obj);
15
+ const Constructor = prototype.constructor;
16
+ if (obj instanceof Date || obj instanceof Map || obj instanceof Set) return new Constructor(obj);
17
+ if (obj instanceof RegExp) {
18
+ const newRegExp = new Constructor(obj);
19
+ newRegExp.lastIndex = obj.lastIndex;
20
+ return newRegExp;
21
+ }
22
+ if (obj instanceof DataView) return new Constructor(obj.buffer.slice(0));
23
+ if (obj instanceof Error) {
24
+ let newError;
25
+ if (obj instanceof AggregateError) newError = new Constructor(obj.errors, obj.message, { cause: obj.cause });
26
+ else newError = new Constructor(obj.message, { cause: obj.cause });
27
+ newError.stack = obj.stack;
28
+ Object.assign(newError, obj);
29
+ return newError;
30
+ }
31
+ if (typeof File !== "undefined" && obj instanceof File) return new Constructor([obj], obj.name, {
32
+ type: obj.type,
33
+ lastModified: obj.lastModified
34
+ });
35
+ if (typeof obj === "object") {
36
+ const newObject = Object.create(prototype);
37
+ return Object.assign(newObject, obj);
38
+ }
39
+ return obj;
40
+ }
41
+ function isPlainObject(value) {
42
+ if (!value || typeof value !== "object") return false;
43
+ const proto = Object.getPrototypeOf(value);
44
+ if (!(proto === null || proto === Object.prototype || Object.getPrototypeOf(proto) === null)) return false;
45
+ return Object.prototype.toString.call(value) === "[object Object]";
46
+ }
47
+ function isUnsafeProperty(key) {
48
+ return key === "__proto__";
49
+ }
50
+ function mergeWith(target, source, merge) {
51
+ const sourceKeys = Object.keys(source);
52
+ for (let i = 0; i < sourceKeys.length; i++) {
53
+ const key = sourceKeys[i];
54
+ if (isUnsafeProperty(key)) continue;
55
+ const sourceValue = source[key];
56
+ const targetValue = target[key];
57
+ const merged = merge(targetValue, sourceValue, key, target, source);
58
+ if (merged !== void 0) target[key] = merged;
59
+ else if (Array.isArray(sourceValue)) if (Array.isArray(targetValue)) target[key] = mergeWith(targetValue, sourceValue, merge);
60
+ else target[key] = mergeWith([], sourceValue, merge);
61
+ else if (isPlainObject(sourceValue)) if (isPlainObject(targetValue)) target[key] = mergeWith(targetValue, sourceValue, merge);
62
+ else target[key] = mergeWith({}, sourceValue, merge);
63
+ else if (targetValue === void 0 || sourceValue !== void 0) target[key] = sourceValue;
64
+ }
65
+ return target;
66
+ }
67
+ function toMerged(target, source) {
68
+ return mergeWith(clone(target), source, function mergeRecursively(targetValue, sourceValue) {
69
+ if (Array.isArray(sourceValue)) if (Array.isArray(targetValue)) return mergeWith(clone(targetValue), sourceValue, mergeRecursively);
70
+ else return mergeWith([], sourceValue, mergeRecursively);
71
+ else if (isPlainObject(sourceValue)) if (isPlainObject(targetValue)) return mergeWith(clone(targetValue), sourceValue, mergeRecursively);
72
+ else return mergeWith({}, sourceValue, mergeRecursively);
73
+ });
74
+ }
7
75
  async function deMorgan(options = {}) {
8
76
  const { files = [GLOB_SRC] } = options;
9
77
  return [{
@@ -12,9 +80,19 @@ async function deMorgan(options = {}) {
12
80
  ...(await interopDefault(import("eslint-plugin-de-morgan"))).configs.recommended
13
81
  }];
14
82
  }
15
-
16
- //#endregion
17
- //#region src/configs/nuxt.ts
83
+ async function e18e(options = {}) {
84
+ const { files = [GLOB_SRC], overrides } = options;
85
+ const recommendedConfig = (await interopDefault(import("@e18e/eslint-plugin"))).configs.recommended;
86
+ return [{
87
+ name: "vida/e18e/rules",
88
+ files,
89
+ ...recommendedConfig,
90
+ rules: {
91
+ ...recommendedConfig.rules,
92
+ ...overrides
93
+ }
94
+ }];
95
+ }
18
96
  async function nuxt(options = {}) {
19
97
  const { files = [GLOB_SRC], overrides = {} } = options;
20
98
  await ensurePackages(["@nuxt/eslint-plugin"]);
@@ -32,111 +110,84 @@ async function nuxt(options = {}) {
32
110
  }
33
111
  }];
34
112
  }
35
-
36
- //#endregion
37
- //#region src/overrides/javascript.ts
38
- const javascript = { overrides: {
39
- "arrow-body-style": ["error", "as-needed"],
40
- "no-unused-private-class-members": "error",
41
- "require-atomic-updates": ["error", { allowProperties: true }]
42
- } };
43
-
44
- //#endregion
45
- //#region src/overrides/stylistic.ts
46
- const stylistic = {
47
- indent: 2,
48
- quotes: "single",
49
- semi: false,
50
- overrides: {
51
- "style/indent": [
52
- "error",
53
- 2,
54
- {
55
- SwitchCase: 1,
56
- VariableDeclarator: "first",
57
- outerIIFEBody: 1,
58
- MemberExpression: 1,
59
- FunctionDeclaration: {
60
- parameters: 1,
61
- body: 1
62
- },
63
- FunctionExpression: {
64
- parameters: 1,
65
- body: 1
66
- },
67
- StaticBlock: { body: 1 },
68
- CallExpression: { arguments: 1 },
69
- ArrayExpression: 1,
70
- ObjectExpression: 1,
71
- ImportDeclaration: 1,
72
- flatTernaryExpressions: true,
73
- offsetTernaryExpressions: true,
74
- ignoreComments: false,
75
- tabLength: 2
76
- }
77
- ],
78
- "style/quotes": [
79
- "error",
80
- "single",
81
- {
82
- avoidEscape: true,
83
- allowTemplateLiterals: "avoidEscape"
84
- }
85
- ],
86
- "style/arrow-parens": ["error", "always"],
87
- "style/brace-style": [
88
- "error",
89
- "1tbs",
90
- { allowSingleLine: true }
91
- ]
92
- }
93
- };
94
-
95
- //#endregion
96
- //#region src/overrides/typescript.ts
97
- const typescript = { overrides: { "ts/array-type": "error" } };
98
-
99
- //#endregion
100
- //#region src/overrides/vue.ts
101
- const vue = { overrides: {
102
- "vue/max-attributes-per-line": ["error", { multiline: 1 }],
103
- "vue/prefer-use-template-ref": ["error"]
104
- } };
105
-
106
- //#endregion
107
- //#region src/overrides/index.ts
108
113
  const antfuOverrides = Object.freeze({
109
- javascript,
110
- stylistic,
111
- typescript,
112
- vue
114
+ javascript: { overrides: {
115
+ "arrow-body-style": ["error", "as-needed"],
116
+ "no-unused-private-class-members": "error",
117
+ "require-atomic-updates": ["error", { allowProperties: true }]
118
+ } },
119
+ stylistic: {
120
+ indent: 2,
121
+ quotes: "single",
122
+ semi: false,
123
+ overrides: {
124
+ "style/indent": [
125
+ "error",
126
+ 2,
127
+ {
128
+ SwitchCase: 1,
129
+ VariableDeclarator: "first",
130
+ outerIIFEBody: 1,
131
+ MemberExpression: 1,
132
+ FunctionDeclaration: {
133
+ parameters: 1,
134
+ body: 1
135
+ },
136
+ FunctionExpression: {
137
+ parameters: 1,
138
+ body: 1
139
+ },
140
+ StaticBlock: { body: 1 },
141
+ CallExpression: { arguments: 1 },
142
+ ArrayExpression: 1,
143
+ ObjectExpression: 1,
144
+ ImportDeclaration: 1,
145
+ flatTernaryExpressions: true,
146
+ offsetTernaryExpressions: true,
147
+ ignoreComments: false,
148
+ tabLength: 2
149
+ }
150
+ ],
151
+ "style/quotes": [
152
+ "error",
153
+ "single",
154
+ {
155
+ avoidEscape: true,
156
+ allowTemplateLiterals: "avoidEscape"
157
+ }
158
+ ],
159
+ "style/arrow-parens": ["error", "always"],
160
+ "style/brace-style": [
161
+ "error",
162
+ "1tbs",
163
+ { allowSingleLine: true }
164
+ ]
165
+ }
166
+ },
167
+ typescript: { overrides: { "ts/array-type": "error" } },
168
+ vue: { overrides: {
169
+ "vue/max-attributes-per-line": ["error", { multiline: 1 }],
170
+ "vue/prefer-use-template-ref": ["error"]
171
+ } }
113
172
  });
114
-
115
- //#endregion
116
- //#region src/utils.ts
117
- function deepMerge(target, source) {
118
- for (const key in source) if (Object.hasOwn(source, key)) if (source[key] instanceof Object && target[key] instanceof Object) target[key] = deepMerge(target[key], source[key]);
119
- else target[key] = source[key];
120
- return target;
121
- }
122
-
123
- //#endregion
124
- //#region src/index.ts
125
- const VuePackages = [
126
- "vue",
127
- "nuxt",
128
- "vitepress",
129
- "@slidev/cli"
130
- ];
131
- function defineConfig(options = {
173
+ const defaultOptions = {
132
174
  deMorgan: true,
175
+ e18e: true,
133
176
  nuxt: isPackageExists("nuxt"),
134
- vue: VuePackages.some((i) => isPackageExists(i)),
135
- typescript: isPackageExists("typescript")
136
- }, ...userConfigs) {
137
- const { deMorgan: enableDeMorgan, nuxt: enableNuxt } = options;
177
+ typescript: isPackageExists("typescript"),
178
+ vue: [
179
+ "vue",
180
+ "nuxt",
181
+ "vitepress",
182
+ "@slidev/cli"
183
+ ].some((i) => isPackageExists(i))
184
+ };
185
+ function defineConfig(options = {}, ...userConfigs) {
186
+ options = toMerged(defaultOptions, options);
187
+ const { deMorgan: enableDeMorgan, e18e: enableE18e, nuxt: enableNuxt } = options;
138
188
  const configs = [];
139
189
  if (enableDeMorgan) configs.push(deMorgan());
190
+ if (enableE18e) configs.push(e18e());
140
191
  if (enableNuxt) configs.push(nuxt());
141
192
  return antfu(applyOptions(options), ...configs, ...userConfigs);
142
193
  }
@@ -145,11 +196,9 @@ function applyOptions(options) {
145
196
  const optionVal = options[key];
146
197
  const defaultVal = antfuOverrides[key];
147
198
  if (optionVal === true) options[key] = defaultVal;
148
- else if (optionVal !== false) options[key] = optionVal ? deepMerge(defaultVal, optionVal) : defaultVal;
199
+ else if (optionVal !== false) options[key] = optionVal ? toMerged(defaultVal, optionVal) : defaultVal;
149
200
  }
150
201
  return options;
151
202
  }
152
203
  var src_default = defineConfig;
153
-
154
- //#endregion
155
- export { applyOptions, deepMerge, src_default as default, defineConfig };
204
+ export { applyOptions, src_default as default, defineConfig };
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@vida0905/eslint-config",
3
3
  "type": "module",
4
- "version": "2.8.0",
4
+ "version": "2.10.0",
5
5
  "description": "Vida Xie's ESLint Config",
6
6
  "author": "Vida Xie <vida_2020@163.com> (https://github.com/9romise/)",
7
7
  "license": "MIT",
@@ -17,9 +17,9 @@
17
17
  "eslint-config"
18
18
  ],
19
19
  "exports": {
20
- ".": "./dist/index.mjs"
20
+ ".": "./dist/index.mjs",
21
+ "./package.json": "./package.json"
21
22
  },
22
- "main": "./dits/index.mjs",
23
23
  "types": "./dist/index.d.mts",
24
24
  "bin": "./bin/index.mjs",
25
25
  "files": [
@@ -40,22 +40,24 @@
40
40
  }
41
41
  },
42
42
  "dependencies": {
43
- "@antfu/eslint-config": "^6.7.3",
43
+ "@antfu/eslint-config": "^7.2.0",
44
+ "@e18e/eslint-plugin": "^0.1.4",
44
45
  "cac": "^6.7.14",
45
- "eslint-flat-config-utils": "^2.1.4",
46
+ "eslint-flat-config-utils": "^3.0.0",
46
47
  "eslint-plugin-de-morgan": "^2.0.0",
47
48
  "local-pkg": "^1.1.2"
48
49
  },
49
50
  "devDependencies": {
50
- "@types/node": "^25.0.3",
51
+ "@types/node": "^25.2.0",
52
+ "es-toolkit": "^1.44.0",
51
53
  "eslint": "^9.39.2",
52
54
  "eslint-typegen": "^2.3.0",
53
55
  "husky": "^9.1.7",
54
56
  "nano-staged": "^0.9.0",
55
- "tsdown": "^0.18.3",
57
+ "tsdown": "^0.20.1",
56
58
  "tsx": "^4.21.0",
57
59
  "typescript": "^5.9.3",
58
- "vitest": "^4.0.16"
60
+ "vitest": "^4.0.18"
59
61
  },
60
62
  "nano-staged": {
61
63
  "*": "eslint --fix"
@@ -68,6 +70,7 @@
68
70
  "test": "vitest",
69
71
  "lint": "eslint .",
70
72
  "check": "npm run typecheck && npm run lint",
71
- "inspect": "npx eslint --inspect-config --config eslint-inspector.config.ts"
73
+ "inspect": "npx eslint --inspect-config --config eslint-inspector.config.ts",
74
+ "release": "npx bumpp"
72
75
  }
73
76
  }