@fenge/eslint-config 0.6.2 → 0.6.3
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/dist/config/javascript.d.ts.map +1 -1
- package/dist/config/js/base.d.ts.map +1 -1
- package/dist/config/ts/base.d.ts.map +1 -1
- package/dist/config/typescript.d.ts.map +1 -1
- package/dist/eslint.config.d.ts +1 -1
- package/dist/eslint.config.d.ts.map +1 -1
- package/dist/eslint.config.js +1 -1
- package/package.json +7 -4
- package/CHANGELOG.md +0 -301
- package/src/config/base.ts +0 -56
- package/src/config/javascript.test.ts +0 -63
- package/src/config/javascript.ts +0 -8
- package/src/config/js/base.ts +0 -554
- package/src/config/js/cli.ts +0 -14
- package/src/config/js/config.ts +0 -11
- package/src/config/js/test.ts +0 -15
- package/src/config/packagejson.ts +0 -35
- package/src/config/ts/base.ts +0 -238
- package/src/config/ts/cli.ts +0 -13
- package/src/config/ts/config.ts +0 -13
- package/src/config/ts/declaration.ts +0 -13
- package/src/config/ts/test.ts +0 -18
- package/src/config/typescript.test.ts +0 -98
- package/src/config/typescript.ts +0 -15
- package/src/eslint.config.test.ts +0 -108
- package/src/eslint.config.ts +0 -99
- package/src/typing.d.ts +0 -8
- package/test/fixtures.test.ts +0 -101
- package/test/prettier.test.ts +0 -42
- package/tsconfig.json +0 -5
package/src/config/ts/base.ts
DELETED
|
@@ -1,238 +0,0 @@
|
|
|
1
|
-
import * as fengeTsPlugin from "@fenge/eslint-plugin-ts";
|
|
2
|
-
import tsParser from "@typescript-eslint/parser";
|
|
3
|
-
import { getJsBase } from "../js/base.ts";
|
|
4
|
-
|
|
5
|
-
export function getTsBase() {
|
|
6
|
-
const jsBase = getJsBase();
|
|
7
|
-
|
|
8
|
-
const getTsExtensionRules = () => {
|
|
9
|
-
// Key is js rule, value is ts rule
|
|
10
|
-
// https://typescript-eslint.io/rules/?=extension
|
|
11
|
-
const extensionRuleMap = {
|
|
12
|
-
"class-methods-use-this": "@typescript-eslint/class-methods-use-this",
|
|
13
|
-
"consistent-return": "@typescript-eslint/consistent-return",
|
|
14
|
-
"default-param-last": "@typescript-eslint/default-param-last",
|
|
15
|
-
"dot-notation": "@typescript-eslint/dot-notation",
|
|
16
|
-
"init-declarations": "@typescript-eslint/init-declarations",
|
|
17
|
-
"max-params": "@typescript-eslint/max-params",
|
|
18
|
-
"no-array-constructor": "@typescript-eslint/no-array-constructor",
|
|
19
|
-
"no-dupe-class-members": "@typescript-eslint/no-dupe-class-members",
|
|
20
|
-
"no-empty-function": "@typescript-eslint/no-empty-function",
|
|
21
|
-
"no-implied-eval": "@typescript-eslint/no-implied-eval",
|
|
22
|
-
"no-invalid-this": "@typescript-eslint/no-invalid-this",
|
|
23
|
-
"no-loop-func": "@typescript-eslint/no-loop-func",
|
|
24
|
-
// "no-loss-of-precision": "@typescript-eslint/no-loss-of-precision", // This rule has been deprecated
|
|
25
|
-
"no-magic-numbers": "@typescript-eslint/no-magic-numbers",
|
|
26
|
-
"no-redeclare": "@typescript-eslint/no-redeclare",
|
|
27
|
-
"no-restricted-imports": "@typescript-eslint/no-restricted-imports",
|
|
28
|
-
"no-shadow": "@typescript-eslint/no-shadow",
|
|
29
|
-
"no-unused-expressions": "@typescript-eslint/no-unused-expressions",
|
|
30
|
-
"no-unused-vars": "@typescript-eslint/no-unused-vars",
|
|
31
|
-
"no-use-before-define": "@typescript-eslint/no-use-before-define",
|
|
32
|
-
"no-useless-constructor": "@typescript-eslint/no-useless-constructor",
|
|
33
|
-
"no-throw-literal": "@typescript-eslint/only-throw-error",
|
|
34
|
-
"prefer-destructuring": "@typescript-eslint/prefer-destructuring",
|
|
35
|
-
"prefer-promise-reject-errors":
|
|
36
|
-
"@typescript-eslint/prefer-promise-reject-errors",
|
|
37
|
-
"require-await": "@typescript-eslint/require-await",
|
|
38
|
-
"no-return-await": "@typescript-eslint/return-await", // no-return-await has been deprecated
|
|
39
|
-
} as const;
|
|
40
|
-
|
|
41
|
-
type Js2TsRuleMap = typeof extensionRuleMap;
|
|
42
|
-
type Ts2JsRuleMap = {
|
|
43
|
-
[K in keyof Js2TsRuleMap as Js2TsRuleMap[K]]: K; // reverse
|
|
44
|
-
};
|
|
45
|
-
|
|
46
|
-
type JsExtensionKey = Extract<
|
|
47
|
-
keyof Js2TsRuleMap,
|
|
48
|
-
keyof typeof jsBase.rules
|
|
49
|
-
>; // Extract
|
|
50
|
-
type TsExtensionKey = Js2TsRuleMap[JsExtensionKey];
|
|
51
|
-
|
|
52
|
-
type JsResult = Record<JsExtensionKey, "off">;
|
|
53
|
-
type TsResult = {
|
|
54
|
-
[Key in TsExtensionKey]: (typeof jsBase.rules)[Ts2JsRuleMap[Key]];
|
|
55
|
-
};
|
|
56
|
-
type Result = JsResult & TsResult;
|
|
57
|
-
|
|
58
|
-
const isInExtensionRuleMap = (
|
|
59
|
-
key: string,
|
|
60
|
-
): key is keyof typeof extensionRuleMap => key in extensionRuleMap;
|
|
61
|
-
return Object.entries(jsBase.rules).reduce(
|
|
62
|
-
(result, [jsRuleKey, jsRuleValue]) =>
|
|
63
|
-
isInExtensionRuleMap(jsRuleKey)
|
|
64
|
-
? {
|
|
65
|
-
...result,
|
|
66
|
-
[jsRuleKey]: "off",
|
|
67
|
-
[extensionRuleMap[jsRuleKey]]: jsRuleValue,
|
|
68
|
-
}
|
|
69
|
-
: result,
|
|
70
|
-
{} as Result,
|
|
71
|
-
);
|
|
72
|
-
};
|
|
73
|
-
|
|
74
|
-
return {
|
|
75
|
-
...jsBase,
|
|
76
|
-
name: "fenge/typescript",
|
|
77
|
-
files: ["**/*.{ts,cts,mts,tsx}"],
|
|
78
|
-
languageOptions: {
|
|
79
|
-
...jsBase.languageOptions,
|
|
80
|
-
parser: tsParser, // Unfortunately parser cannot be a string. Eslint should support it. https://eslint.org/docs/latest/use/configure/configuration-files-new#configuring-a-custom-parser-and-its-options
|
|
81
|
-
parserOptions: {
|
|
82
|
-
...jsBase.languageOptions.parserOptions,
|
|
83
|
-
// Setting `projectService: true` or `project: true` is pretty slow when lint a monorepo with many tsconfig.json files in each sub-app.
|
|
84
|
-
// But setting `project: "tsconfig.json"` will cause parser error when the project root tsconfig.json is `{ extends: "fenge/tsconfig" }`
|
|
85
|
-
projectService: true,
|
|
86
|
-
},
|
|
87
|
-
},
|
|
88
|
-
plugins: {
|
|
89
|
-
...jsBase.plugins,
|
|
90
|
-
"@fenge-ts": fengeTsPlugin,
|
|
91
|
-
},
|
|
92
|
-
rules: {
|
|
93
|
-
...jsBase.rules,
|
|
94
|
-
...getTsExtensionRules(),
|
|
95
|
-
|
|
96
|
-
// fenge
|
|
97
|
-
"@fenge-ts/exact-map-set-type": "error",
|
|
98
|
-
"@fenge-ts/no-const-enum": "error",
|
|
99
|
-
"@fenge-ts/no-declares": "error",
|
|
100
|
-
"@fenge-ts/no-export-assignment": "error",
|
|
101
|
-
"@fenge-ts/no-misuse-spreading-parameter": "error",
|
|
102
|
-
"@fenge-ts/no-property-decorator": "error",
|
|
103
|
-
"@fenge-ts/no-untyped-empty-array": "error",
|
|
104
|
-
// typescript
|
|
105
|
-
"@typescript-eslint/adjacent-overload-signatures": "error",
|
|
106
|
-
// "@typescript-eslint/array-type": ["error", 'array-simple'], // The default option is 'array'. Not very sure if we need to change the option. So disabled it.
|
|
107
|
-
"@typescript-eslint/await-thenable": "error",
|
|
108
|
-
"@typescript-eslint/class-literal-property-style": "error",
|
|
109
|
-
"@typescript-eslint/consistent-generic-constructors": "error",
|
|
110
|
-
"@typescript-eslint/consistent-indexed-object-style": "error",
|
|
111
|
-
"@typescript-eslint/consistent-type-assertions": [
|
|
112
|
-
"error",
|
|
113
|
-
{
|
|
114
|
-
assertionStyle: "as",
|
|
115
|
-
objectLiteralTypeAssertions: "allow-as-parameter",
|
|
116
|
-
},
|
|
117
|
-
],
|
|
118
|
-
"@typescript-eslint/consistent-type-definitions": ["error", "interface"], // TODO should we change to 'type'?
|
|
119
|
-
"@typescript-eslint/consistent-type-exports": "error",
|
|
120
|
-
"@typescript-eslint/consistent-type-imports": "error",
|
|
121
|
-
"@typescript-eslint/dot-notation": ["error", { allowKeywords: true }],
|
|
122
|
-
"@typescript-eslint/method-signature-style": "error",
|
|
123
|
-
"@typescript-eslint/naming-convention": [
|
|
124
|
-
"error",
|
|
125
|
-
{
|
|
126
|
-
selector: "function",
|
|
127
|
-
format: ["camelCase", "PascalCase"],
|
|
128
|
-
},
|
|
129
|
-
{
|
|
130
|
-
selector: "variable",
|
|
131
|
-
types: ["function"],
|
|
132
|
-
format: ["camelCase", "PascalCase"], // decorators need PascalCase
|
|
133
|
-
},
|
|
134
|
-
{
|
|
135
|
-
selector: "class",
|
|
136
|
-
format: ["PascalCase"],
|
|
137
|
-
},
|
|
138
|
-
{
|
|
139
|
-
selector: "interface",
|
|
140
|
-
format: ["PascalCase"],
|
|
141
|
-
},
|
|
142
|
-
{
|
|
143
|
-
selector: "typeAlias",
|
|
144
|
-
format: ["PascalCase"],
|
|
145
|
-
},
|
|
146
|
-
{
|
|
147
|
-
selector: "typeParameter",
|
|
148
|
-
format: ["UPPER_CASE", "PascalCase"],
|
|
149
|
-
},
|
|
150
|
-
],
|
|
151
|
-
"@typescript-eslint/no-array-delete": "error",
|
|
152
|
-
"@typescript-eslint/no-base-to-string": [
|
|
153
|
-
"error",
|
|
154
|
-
{ ignoredTypeNames: [] },
|
|
155
|
-
],
|
|
156
|
-
"@typescript-eslint/no-confusing-non-null-assertion": "error",
|
|
157
|
-
"@typescript-eslint/no-deprecated": "error",
|
|
158
|
-
"@typescript-eslint/no-duplicate-enum-values": "error",
|
|
159
|
-
"@typescript-eslint/no-duplicate-type-constituents": "error",
|
|
160
|
-
"@typescript-eslint/no-empty-object-type": "error",
|
|
161
|
-
"@typescript-eslint/no-extra-non-null-assertion": "error",
|
|
162
|
-
// "@typescript-eslint/no-extraneous-class": "error", // Classes have only static member is reasonable sometimes. Nestjs modules use it a lot.
|
|
163
|
-
"@typescript-eslint/no-floating-promises": [
|
|
164
|
-
"error",
|
|
165
|
-
{
|
|
166
|
-
ignoreVoid: false,
|
|
167
|
-
},
|
|
168
|
-
],
|
|
169
|
-
"@typescript-eslint/no-for-in-array": "error",
|
|
170
|
-
"@typescript-eslint/no-import-type-side-effects": "error",
|
|
171
|
-
"@typescript-eslint/no-inferrable-types": "error",
|
|
172
|
-
"@typescript-eslint/no-invalid-void-type": "error",
|
|
173
|
-
"@typescript-eslint/no-misused-new": "error",
|
|
174
|
-
"@typescript-eslint/no-misused-promises": "error",
|
|
175
|
-
"@typescript-eslint/no-misused-spread": "error",
|
|
176
|
-
"@typescript-eslint/no-mixed-enums": "error",
|
|
177
|
-
"@typescript-eslint/no-namespace": "error", // consider to add option `{"allowDefinitionFiles": false}` to strictly forbid `namespace` keyword
|
|
178
|
-
"@typescript-eslint/no-non-null-asserted-nullish-coalescing": "error",
|
|
179
|
-
"@typescript-eslint/no-non-null-asserted-optional-chain": "error",
|
|
180
|
-
"@typescript-eslint/no-non-null-assertion": "error",
|
|
181
|
-
"@typescript-eslint/no-redundant-type-constituents": "error",
|
|
182
|
-
"@typescript-eslint/no-require-imports": "error",
|
|
183
|
-
"@typescript-eslint/no-unnecessary-boolean-literal-compare": "error",
|
|
184
|
-
"@typescript-eslint/no-unnecessary-condition": "error",
|
|
185
|
-
"@typescript-eslint/no-unnecessary-parameter-property-assignment":
|
|
186
|
-
"error",
|
|
187
|
-
"@typescript-eslint/no-unnecessary-template-expression": "error", // js also need this rule
|
|
188
|
-
"@typescript-eslint/no-unnecessary-type-arguments": "error",
|
|
189
|
-
"@typescript-eslint/no-unnecessary-type-assertion": "error",
|
|
190
|
-
"@typescript-eslint/no-unnecessary-type-constraint": "error",
|
|
191
|
-
"@typescript-eslint/no-unsafe-declaration-merging": "error",
|
|
192
|
-
"@typescript-eslint/no-unsafe-enum-comparison": "error",
|
|
193
|
-
"@typescript-eslint/no-unsafe-function-type": "error",
|
|
194
|
-
"@typescript-eslint/no-unsafe-return": "error", // This rule is not very perfect. See https://github.com/typescript-eslint/typescript-eslint/issues/10439
|
|
195
|
-
"@typescript-eslint/no-unsafe-unary-minus": "error",
|
|
196
|
-
"@typescript-eslint/no-wrapper-object-types": "error",
|
|
197
|
-
"@typescript-eslint/non-nullable-type-assertion-style": "error",
|
|
198
|
-
"@typescript-eslint/prefer-as-const": "error",
|
|
199
|
-
"@typescript-eslint/prefer-function-type": "error",
|
|
200
|
-
"@typescript-eslint/prefer-literal-enum-member": "error",
|
|
201
|
-
"@typescript-eslint/prefer-namespace-keyword": "error",
|
|
202
|
-
"@typescript-eslint/prefer-optional-chain": "error",
|
|
203
|
-
"@typescript-eslint/prefer-readonly": "error",
|
|
204
|
-
"@typescript-eslint/prefer-return-this-type": "error",
|
|
205
|
-
"@typescript-eslint/restrict-plus-operands": [
|
|
206
|
-
"error",
|
|
207
|
-
{
|
|
208
|
-
// allowAny: false,
|
|
209
|
-
allowBoolean: false,
|
|
210
|
-
allowNullish: false,
|
|
211
|
-
allowNumberAndString: false,
|
|
212
|
-
allowRegExp: false,
|
|
213
|
-
skipCompoundAssignments: false,
|
|
214
|
-
},
|
|
215
|
-
],
|
|
216
|
-
"@typescript-eslint/restrict-template-expressions": [
|
|
217
|
-
"error",
|
|
218
|
-
{
|
|
219
|
-
allow: [],
|
|
220
|
-
// allowAny: false,
|
|
221
|
-
allowBoolean: false,
|
|
222
|
-
allowNever: false,
|
|
223
|
-
allowNullish: false,
|
|
224
|
-
allowNumber: false,
|
|
225
|
-
allowRegExp: false,
|
|
226
|
-
},
|
|
227
|
-
],
|
|
228
|
-
"@typescript-eslint/related-getter-setter-pairs": "error",
|
|
229
|
-
"@typescript-eslint/return-await": ["error", "always"],
|
|
230
|
-
"@typescript-eslint/switch-exhaustiveness-check": [
|
|
231
|
-
"error",
|
|
232
|
-
{ requireDefaultForNonUnion: true },
|
|
233
|
-
],
|
|
234
|
-
"@typescript-eslint/unbound-method": "error",
|
|
235
|
-
"@typescript-eslint/unified-signatures": "error",
|
|
236
|
-
},
|
|
237
|
-
} as const;
|
|
238
|
-
}
|
package/src/config/ts/cli.ts
DELETED
package/src/config/ts/config.ts
DELETED
|
@@ -1,13 +0,0 @@
|
|
|
1
|
-
import { getJsConfig } from "../js/config.ts";
|
|
2
|
-
|
|
3
|
-
export function getTsConfig() {
|
|
4
|
-
const jsConfig = getJsConfig();
|
|
5
|
-
return {
|
|
6
|
-
...jsConfig,
|
|
7
|
-
name: "fenge/typescript/config",
|
|
8
|
-
files: ["**/*.config.{ts,cts,mts,tsx}"],
|
|
9
|
-
rules: {
|
|
10
|
-
...jsConfig.rules,
|
|
11
|
-
},
|
|
12
|
-
} as const;
|
|
13
|
-
}
|
|
@@ -1,13 +0,0 @@
|
|
|
1
|
-
export function getTsDeclaration() {
|
|
2
|
-
return {
|
|
3
|
-
name: "fenge/typescript/declaration",
|
|
4
|
-
files: ["**/*.d.{ts,cts,mts,tsx}"],
|
|
5
|
-
rules: {
|
|
6
|
-
"esm/no-declaration-file-imports": "off",
|
|
7
|
-
"esm/no-empty-exports": "off",
|
|
8
|
-
"esm/no-side-effect-imports": "off",
|
|
9
|
-
"esm/required-exports": "off",
|
|
10
|
-
"import/no-default-export": "off",
|
|
11
|
-
},
|
|
12
|
-
} as const;
|
|
13
|
-
}
|
package/src/config/ts/test.ts
DELETED
|
@@ -1,18 +0,0 @@
|
|
|
1
|
-
import { getJsTest } from "../js/test.ts";
|
|
2
|
-
|
|
3
|
-
export function getTsTest() {
|
|
4
|
-
const jsTest = getJsTest();
|
|
5
|
-
return {
|
|
6
|
-
...jsTest,
|
|
7
|
-
name: "fenge/typescript/test",
|
|
8
|
-
files: [
|
|
9
|
-
"**/__tests__/**/*.{ts,cts,mts,tsx}",
|
|
10
|
-
"**/*.{test,spec}.{ts,cts,mts,tsx}",
|
|
11
|
-
],
|
|
12
|
-
rules: {
|
|
13
|
-
...jsTest.rules,
|
|
14
|
-
"@typescript-eslint/no-floating-promises": "off",
|
|
15
|
-
"@typescript-eslint/unbound-method": "off",
|
|
16
|
-
},
|
|
17
|
-
} as const;
|
|
18
|
-
}
|
|
@@ -1,98 +0,0 @@
|
|
|
1
|
-
import assert from "node:assert";
|
|
2
|
-
import { describe, it } from "node:test";
|
|
3
|
-
import { typescript } from "./typescript.ts";
|
|
4
|
-
|
|
5
|
-
await describe("ts config", async () => {
|
|
6
|
-
await it("ts main config rules values should be error", () => {
|
|
7
|
-
Object.entries(typescript()[0].rules).forEach(([key, value]) => {
|
|
8
|
-
// Key is js rule, value is ts rule
|
|
9
|
-
// https://typescript-eslint.io/rules/?=extension
|
|
10
|
-
const extensionRuleMap = {
|
|
11
|
-
"class-methods-use-this": "@typescript-eslint/class-methods-use-this",
|
|
12
|
-
"consistent-return": "@typescript-eslint/consistent-return",
|
|
13
|
-
"default-param-last": "@typescript-eslint/default-param-last",
|
|
14
|
-
"dot-notation": "@typescript-eslint/dot-notation",
|
|
15
|
-
"init-declarations": "@typescript-eslint/init-declarations",
|
|
16
|
-
"max-params": "@typescript-eslint/max-params",
|
|
17
|
-
"no-array-constructor": "@typescript-eslint/no-array-constructor",
|
|
18
|
-
"no-dupe-class-members": "@typescript-eslint/no-dupe-class-members",
|
|
19
|
-
"no-empty-function": "@typescript-eslint/no-empty-function",
|
|
20
|
-
"no-implied-eval": "@typescript-eslint/no-implied-eval",
|
|
21
|
-
"no-invalid-this": "@typescript-eslint/no-invalid-this",
|
|
22
|
-
"no-loop-func": "@typescript-eslint/no-loop-func",
|
|
23
|
-
// "no-loss-of-precision": "@typescript-eslint/no-loss-of-precision", // This rule has been deprecated
|
|
24
|
-
"no-magic-numbers": "@typescript-eslint/no-magic-numbers",
|
|
25
|
-
"no-redeclare": "@typescript-eslint/no-redeclare",
|
|
26
|
-
"no-restricted-imports": "@typescript-eslint/no-restricted-imports",
|
|
27
|
-
"no-shadow": "@typescript-eslint/no-shadow",
|
|
28
|
-
"no-unused-expressions": "@typescript-eslint/no-unused-expressions",
|
|
29
|
-
"no-unused-vars": "@typescript-eslint/no-unused-vars",
|
|
30
|
-
"no-use-before-define": "@typescript-eslint/no-use-before-define",
|
|
31
|
-
"no-useless-constructor": "@typescript-eslint/no-useless-constructor",
|
|
32
|
-
"no-throw-literal": "@typescript-eslint/only-throw-error",
|
|
33
|
-
"prefer-destructuring": "@typescript-eslint/prefer-destructuring",
|
|
34
|
-
"prefer-promise-reject-errors":
|
|
35
|
-
"@typescript-eslint/prefer-promise-reject-errors",
|
|
36
|
-
"require-await": "@typescript-eslint/require-await",
|
|
37
|
-
"no-return-await": "@typescript-eslint/return-await", // no-return-await has been deprecated
|
|
38
|
-
} as const;
|
|
39
|
-
if (key in extensionRuleMap) {
|
|
40
|
-
assert.strictEqual(getValueString(value), "off");
|
|
41
|
-
} else {
|
|
42
|
-
assert.strictEqual(getValueString(value), "error");
|
|
43
|
-
}
|
|
44
|
-
});
|
|
45
|
-
});
|
|
46
|
-
|
|
47
|
-
await it("ts rest configs rules should exist in main rules", () => {
|
|
48
|
-
const [main, ...restConfigs] = typescript();
|
|
49
|
-
restConfigs.forEach((restConfig) => {
|
|
50
|
-
Object.entries(restConfig.rules).forEach(([key, value]) => {
|
|
51
|
-
assert.strictEqual(key in main.rules, true);
|
|
52
|
-
assert.notDeepStrictEqual(value, Reflect.get(main.rules, key));
|
|
53
|
-
});
|
|
54
|
-
});
|
|
55
|
-
});
|
|
56
|
-
|
|
57
|
-
await it("properties in ts main config should be valid", () => {
|
|
58
|
-
const tsMainConfig = typescript()[0];
|
|
59
|
-
assert.deepStrictEqual(Object.keys(tsMainConfig), [
|
|
60
|
-
"name",
|
|
61
|
-
"files",
|
|
62
|
-
"languageOptions",
|
|
63
|
-
"plugins",
|
|
64
|
-
"rules",
|
|
65
|
-
]);
|
|
66
|
-
assert.strictEqual(tsMainConfig.name.endsWith("/typescript"), true);
|
|
67
|
-
assert.strictEqual(
|
|
68
|
-
tsMainConfig.files.every((file) => file.endsWith(".{ts,cts,mts,tsx}")),
|
|
69
|
-
true,
|
|
70
|
-
);
|
|
71
|
-
});
|
|
72
|
-
|
|
73
|
-
await it("properties in ts rest configs should be valid", () => {
|
|
74
|
-
const [, ...restConfigs] = typescript();
|
|
75
|
-
for (const restConfig of restConfigs) {
|
|
76
|
-
assert.deepStrictEqual(Object.keys(restConfig), [
|
|
77
|
-
"name",
|
|
78
|
-
"files",
|
|
79
|
-
"rules",
|
|
80
|
-
]);
|
|
81
|
-
assert.strictEqual(restConfig.name.includes("/typescript/"), true);
|
|
82
|
-
assert.strictEqual(
|
|
83
|
-
restConfig.files.every((file) => file.endsWith(".{ts,cts,mts,tsx}")),
|
|
84
|
-
true,
|
|
85
|
-
);
|
|
86
|
-
}
|
|
87
|
-
});
|
|
88
|
-
});
|
|
89
|
-
|
|
90
|
-
function getValueString(value: unknown): string {
|
|
91
|
-
if (typeof value === "string") {
|
|
92
|
-
return value;
|
|
93
|
-
} else if (Array.isArray(value) && typeof value[0] === "string") {
|
|
94
|
-
return value[0];
|
|
95
|
-
} else {
|
|
96
|
-
throw new Error("unknown value");
|
|
97
|
-
}
|
|
98
|
-
}
|
package/src/config/typescript.ts
DELETED
|
@@ -1,15 +0,0 @@
|
|
|
1
|
-
import { getTsBase } from "./ts/base.ts";
|
|
2
|
-
import { getTsCli } from "./ts/cli.ts";
|
|
3
|
-
import { getTsConfig } from "./ts/config.ts";
|
|
4
|
-
import { getTsDeclaration } from "./ts/declaration.ts";
|
|
5
|
-
import { getTsTest } from "./ts/test.ts";
|
|
6
|
-
|
|
7
|
-
export function typescript() {
|
|
8
|
-
return [
|
|
9
|
-
getTsBase(),
|
|
10
|
-
getTsCli(),
|
|
11
|
-
getTsConfig(),
|
|
12
|
-
getTsTest(),
|
|
13
|
-
getTsDeclaration(),
|
|
14
|
-
] as const;
|
|
15
|
-
}
|
|
@@ -1,108 +0,0 @@
|
|
|
1
|
-
import assert from "node:assert";
|
|
2
|
-
import { describe, it } from "node:test";
|
|
3
|
-
import config from "./eslint.config.ts";
|
|
4
|
-
|
|
5
|
-
await describe("eslint.config", async () => {
|
|
6
|
-
await it("length of default export should be 13", () => {
|
|
7
|
-
assert.strictEqual(config.length, 13);
|
|
8
|
-
});
|
|
9
|
-
|
|
10
|
-
await it("no warns", () => {
|
|
11
|
-
config.forEach((configItem) => {
|
|
12
|
-
if (configItem.rules) {
|
|
13
|
-
Object.values(configItem.rules).forEach((value) => {
|
|
14
|
-
assert.notStrictEqual(getValueString(value), "warn");
|
|
15
|
-
});
|
|
16
|
-
}
|
|
17
|
-
});
|
|
18
|
-
});
|
|
19
|
-
|
|
20
|
-
await it("should not contain deprecated rules", () => {
|
|
21
|
-
// https://eslint.org/blog/2023/10/deprecating-formatting-rules/#the-deprecated-rules
|
|
22
|
-
const deprecatedRules = [
|
|
23
|
-
"array-bracket-newline",
|
|
24
|
-
"array-bracket-spacing",
|
|
25
|
-
"array-element-newline",
|
|
26
|
-
"arrow-parens",
|
|
27
|
-
"arrow-spacing",
|
|
28
|
-
"block-spacing",
|
|
29
|
-
"brace-style",
|
|
30
|
-
"comma-dangle",
|
|
31
|
-
"comma-spacing",
|
|
32
|
-
"comma-style",
|
|
33
|
-
"computed-property-spacing",
|
|
34
|
-
"dot-location",
|
|
35
|
-
"eol-last",
|
|
36
|
-
"func-call-spacing",
|
|
37
|
-
"function-call-argument-newline",
|
|
38
|
-
"function-paren-newline",
|
|
39
|
-
"generator-star-spacing",
|
|
40
|
-
"implicit-arrow-linebreak",
|
|
41
|
-
"indent",
|
|
42
|
-
"jsx-quotes",
|
|
43
|
-
"key-spacing",
|
|
44
|
-
"keyword-spacing",
|
|
45
|
-
"linebreak-style",
|
|
46
|
-
"lines-between-class-members",
|
|
47
|
-
"lines-around-comment",
|
|
48
|
-
"max-len",
|
|
49
|
-
"max-statements-per-line",
|
|
50
|
-
"multiline-ternary",
|
|
51
|
-
"new-parens",
|
|
52
|
-
"newline-per-chained-call",
|
|
53
|
-
"no-confusing-arrow",
|
|
54
|
-
"no-extra-parens",
|
|
55
|
-
"no-extra-semi",
|
|
56
|
-
"no-floating-decimal",
|
|
57
|
-
"no-mixed-operators",
|
|
58
|
-
"no-mixed-spaces-and-tabs",
|
|
59
|
-
"no-multi-spaces",
|
|
60
|
-
"no-multiple-empty-lines",
|
|
61
|
-
"no-tabs",
|
|
62
|
-
"no-trailing-spaces",
|
|
63
|
-
"no-whitespace-before-property",
|
|
64
|
-
"nonblock-statement-body-position",
|
|
65
|
-
"object-curly-newline",
|
|
66
|
-
"object-curly-spacing",
|
|
67
|
-
"object-property-newline",
|
|
68
|
-
"one-var-declaration-per-line",
|
|
69
|
-
"operator-linebreak",
|
|
70
|
-
"padded-blocks",
|
|
71
|
-
"padding-line-between-statements",
|
|
72
|
-
"quote-props",
|
|
73
|
-
"quotes",
|
|
74
|
-
"rest-spread-spacing",
|
|
75
|
-
"semi",
|
|
76
|
-
"semi-spacing",
|
|
77
|
-
"semi-style",
|
|
78
|
-
"space-before-blocks",
|
|
79
|
-
"space-before-function-paren",
|
|
80
|
-
"space-in-parens",
|
|
81
|
-
"space-infix-ops",
|
|
82
|
-
"space-unary-ops",
|
|
83
|
-
"spaced-comment",
|
|
84
|
-
"switch-colon-spacing",
|
|
85
|
-
"template-curly-spacing",
|
|
86
|
-
"template-tag-spacing",
|
|
87
|
-
"wrap-iife",
|
|
88
|
-
"wrap-regex",
|
|
89
|
-
"yield-star-spacing",
|
|
90
|
-
];
|
|
91
|
-
for (const configItem of config) {
|
|
92
|
-
const containingDeprecatedRules = Object.keys(
|
|
93
|
-
configItem.rules ?? {},
|
|
94
|
-
).filter((rule) => deprecatedRules.includes(rule));
|
|
95
|
-
assert.deepStrictEqual(containingDeprecatedRules, []);
|
|
96
|
-
}
|
|
97
|
-
});
|
|
98
|
-
});
|
|
99
|
-
|
|
100
|
-
function getValueString(value: unknown): string {
|
|
101
|
-
if (typeof value === "string") {
|
|
102
|
-
return value;
|
|
103
|
-
} else if (Array.isArray(value) && typeof value[0] === "string") {
|
|
104
|
-
return value[0];
|
|
105
|
-
} else {
|
|
106
|
-
throw new Error("unknown value");
|
|
107
|
-
}
|
|
108
|
-
}
|
package/src/eslint.config.ts
DELETED
|
@@ -1,99 +0,0 @@
|
|
|
1
|
-
import type { Linter } from "eslint";
|
|
2
|
-
import { base, type BaseOptions } from "./config/base.ts";
|
|
3
|
-
import { javascript } from "./config/javascript.ts";
|
|
4
|
-
import { packagejson } from "./config/packagejson.ts";
|
|
5
|
-
import { typescript } from "./config/typescript.ts";
|
|
6
|
-
|
|
7
|
-
type NoDuplicate<A extends unknown[]> = {
|
|
8
|
-
[I in keyof A]: true extends {
|
|
9
|
-
[J in keyof A]: J extends I ? false : A[J] extends A[I] ? true : false;
|
|
10
|
-
}[number]
|
|
11
|
-
? never
|
|
12
|
-
: A[I];
|
|
13
|
-
};
|
|
14
|
-
|
|
15
|
-
type JsRuleKey = keyof ReturnType<typeof javascript>[0]["rules"];
|
|
16
|
-
type TsRuleKey = keyof ReturnType<typeof typescript>[0]["rules"];
|
|
17
|
-
type PkgRuleKey = keyof ReturnType<typeof packagejson>[0]["rules"];
|
|
18
|
-
|
|
19
|
-
type RuleValue = "error" | "warn" | "off" | ["error" | "warn", ...unknown[]];
|
|
20
|
-
interface Options<T extends string[]> {
|
|
21
|
-
pick?: NoDuplicate<T>;
|
|
22
|
-
omit?: NoDuplicate<T>;
|
|
23
|
-
}
|
|
24
|
-
interface ConfigItem {
|
|
25
|
-
name: string;
|
|
26
|
-
files: string[];
|
|
27
|
-
plugins?: Record<string, object>;
|
|
28
|
-
rules:
|
|
29
|
-
| Partial<Record<PkgRuleKey | JsRuleKey | TsRuleKey, RuleValue>>
|
|
30
|
-
| Record<string, RuleValue>;
|
|
31
|
-
}
|
|
32
|
-
|
|
33
|
-
export type BuilderOptions = BaseOptions;
|
|
34
|
-
export class Builder {
|
|
35
|
-
private readonly configs: Linter.Config[] = [];
|
|
36
|
-
private readonly options: BuilderOptions;
|
|
37
|
-
|
|
38
|
-
private readonly enabled = new Set<"js" | "ts" | "pkg">();
|
|
39
|
-
|
|
40
|
-
constructor(options: BuilderOptions = {}) {
|
|
41
|
-
this.options = options;
|
|
42
|
-
}
|
|
43
|
-
|
|
44
|
-
toConfig() {
|
|
45
|
-
return [...base(this.options, this.enabled), ...this.configs];
|
|
46
|
-
}
|
|
47
|
-
|
|
48
|
-
private setup(
|
|
49
|
-
configItems: readonly { rules: object }[],
|
|
50
|
-
{ pick, omit }: Options<string[]>,
|
|
51
|
-
) {
|
|
52
|
-
const select = (ruleKey: string) => {
|
|
53
|
-
if (!pick && !omit) {
|
|
54
|
-
return true;
|
|
55
|
-
} else if (pick && !omit) {
|
|
56
|
-
return pick.includes(ruleKey);
|
|
57
|
-
} else if (!pick && omit) {
|
|
58
|
-
return !omit.includes(ruleKey);
|
|
59
|
-
} else {
|
|
60
|
-
throw new Error("You cannot specify both pick and omit");
|
|
61
|
-
}
|
|
62
|
-
};
|
|
63
|
-
const result = configItems.map((configItem) => ({
|
|
64
|
-
...configItem,
|
|
65
|
-
rules: Object.fromEntries(
|
|
66
|
-
Object.entries(configItem.rules).filter(([ruleKey]) => select(ruleKey)),
|
|
67
|
-
),
|
|
68
|
-
}));
|
|
69
|
-
this.configs.push(...result);
|
|
70
|
-
|
|
71
|
-
return this;
|
|
72
|
-
}
|
|
73
|
-
|
|
74
|
-
enableTypeScript<T extends TsRuleKey[]>(options: Options<T> = {}) {
|
|
75
|
-
this.enabled.add("ts");
|
|
76
|
-
return this.setup(typescript(), options);
|
|
77
|
-
}
|
|
78
|
-
|
|
79
|
-
enableJavaScript<T extends JsRuleKey[]>(options: Options<T> = {}) {
|
|
80
|
-
this.enabled.add("js");
|
|
81
|
-
return this.setup(javascript(), options);
|
|
82
|
-
}
|
|
83
|
-
|
|
84
|
-
enablePackageJson<T extends PkgRuleKey[]>(options: Options<T> = {}) {
|
|
85
|
-
this.enabled.add("pkg");
|
|
86
|
-
return this.setup(packagejson(), options);
|
|
87
|
-
}
|
|
88
|
-
|
|
89
|
-
append(config: ConfigItem) {
|
|
90
|
-
this.configs.push(config);
|
|
91
|
-
return this;
|
|
92
|
-
}
|
|
93
|
-
}
|
|
94
|
-
|
|
95
|
-
export default new Builder()
|
|
96
|
-
.enablePackageJson()
|
|
97
|
-
.enableJavaScript()
|
|
98
|
-
.enableTypeScript()
|
|
99
|
-
.toConfig();
|
package/src/typing.d.ts
DELETED
|
@@ -1,8 +0,0 @@
|
|
|
1
|
-
module "eslint-plugin-*" {
|
|
2
|
-
const plugin: unknown = {}; // TODO: Add initializer because of this issue https://github.com/IanVS/prettier-plugin-sort-imports/issues/196
|
|
3
|
-
export default plugin;
|
|
4
|
-
}
|
|
5
|
-
module "confusing-browser-globals" {
|
|
6
|
-
const keys: string[] = [];
|
|
7
|
-
export default keys;
|
|
8
|
-
}
|