@josundt/eslint-config 4.9.6 → 5.0.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +12 -11
- package/rules/eslint.js +90 -74
- package/rules/{import-typescript.js → import-typescript-node.js} +1 -1
- package/rules/import-typescript-web.js +8 -0
- package/rules/no-lookahead-lookbehind-regexp.js +14 -0
- package/rules/typescript-eslint/extensionrules.js +139 -0
- package/rules/typescript-eslint/rules.js +309 -0
- package/rules/typescript-eslint.js +4 -415
- package/typescript-node-jest.js +6 -2
- package/typescript-node.js +3 -1
- package/typescript-web-jest.js +6 -2
- package/typescript-web.js +3 -1
- package/rules/typescript-eslint-tslint.js +0 -85
package/package.json
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
{
|
2
2
|
"name": "@josundt/eslint-config",
|
3
|
-
"version": "
|
3
|
+
"version": "5.0.4",
|
4
4
|
"description": "ESLint ruleset with required plugins for josundt TypeScript projects",
|
5
5
|
"main": "index.js",
|
6
6
|
"scripts": {
|
@@ -27,19 +27,20 @@
|
|
27
27
|
"utils/**/*.js"
|
28
28
|
],
|
29
29
|
"peerDependencies": {
|
30
|
-
"typescript": ">=
|
30
|
+
"typescript": ">=5.0.4"
|
31
31
|
},
|
32
32
|
"dependencies": {
|
33
|
-
"@typescript-eslint/eslint-plugin": "5.
|
34
|
-
"@typescript-eslint/parser": "5.
|
35
|
-
"eslint": "8.
|
36
|
-
"eslint-import-resolver-typescript": "3.5.
|
37
|
-
"eslint-plugin-deprecation": "1.
|
33
|
+
"@typescript-eslint/eslint-plugin": "5.58.0",
|
34
|
+
"@typescript-eslint/parser": "5.58.0",
|
35
|
+
"eslint": "8.38.0",
|
36
|
+
"eslint-import-resolver-typescript": "3.5.5",
|
37
|
+
"eslint-plugin-deprecation": "1.4.1",
|
38
38
|
"eslint-plugin-eslint-comments": "3.2.0",
|
39
|
-
"eslint-plugin-import": "2.
|
39
|
+
"eslint-plugin-import": "2.27.5",
|
40
40
|
"eslint-plugin-jasmine": "4.1.3",
|
41
|
-
"eslint-plugin-jest": "27.1
|
42
|
-
"eslint-plugin-jsdoc": "
|
43
|
-
"eslint-plugin-
|
41
|
+
"eslint-plugin-jest": "27.2.1",
|
42
|
+
"eslint-plugin-jsdoc": "40.3.0",
|
43
|
+
"eslint-plugin-no-lookahead-lookbehind-regexp": "0.1.0",
|
44
|
+
"eslint-plugin-unicorn": "46.0.0"
|
44
45
|
}
|
45
46
|
}
|
package/rules/eslint.js
CHANGED
@@ -3,40 +3,19 @@ module.exports = {
|
|
3
3
|
"eslint:recommended"
|
4
4
|
],
|
5
5
|
"rules": {
|
6
|
-
|
7
|
-
|
6
|
+
|
7
|
+
// ================== Formatting rules ==================
|
8
|
+
|
8
9
|
"arrow-spacing": ["error", { "before": true, "after": true }],
|
10
|
+
"block-spacing": "off",
|
9
11
|
"brace-style": ["error", "1tbs"],
|
10
|
-
"
|
12
|
+
"comma-dangle": "off",
|
11
13
|
"comma-spacing": ["error", {"before": false, "after": true }],
|
12
14
|
"comma-style": ["error", "last"],
|
13
15
|
"computed-property-spacing": ["error", "never"],
|
14
|
-
"complexity": ["warn", { "max": 20 }],
|
15
|
-
"curly": "error",
|
16
|
-
"default-case-last": "error",
|
17
|
-
"default-param-last": "error",
|
18
|
-
"dot-location": ["error", "property"],
|
19
|
-
"eqeqeq": ["error", "always"],
|
20
16
|
"func-call-spacing": ["error", "never"],
|
21
17
|
"function-call-argument-newline": ["warn", "consistent"],
|
22
18
|
"function-paren-newline": ["warn", "multiline-arguments"],
|
23
|
-
"guard-for-in": "error",
|
24
|
-
"grouped-accessor-pairs": "error",
|
25
|
-
"handle-callback-err": "error",
|
26
|
-
"id-denylist": [
|
27
|
-
"error",
|
28
|
-
"any",
|
29
|
-
"Number",
|
30
|
-
"number",
|
31
|
-
"String",
|
32
|
-
"string",
|
33
|
-
"Boolean",
|
34
|
-
"boolean",
|
35
|
-
"Function",
|
36
|
-
"Undefined"
|
37
|
-
//"undefined"
|
38
|
-
],
|
39
|
-
"id-match": "error",
|
40
19
|
"indent": [
|
41
20
|
"warn",
|
42
21
|
4,
|
@@ -60,6 +39,87 @@ module.exports = {
|
|
60
39
|
],
|
61
40
|
"key-spacing": ["error", { "beforeColon": false, "afterColon": true, "mode": "strict" }],
|
62
41
|
"keyword-spacing": "error",
|
42
|
+
"lines-arround-comment": "off",
|
43
|
+
"lines-between-class-members": "off",
|
44
|
+
"member-delimiter-style": "off",
|
45
|
+
"no-extra-parens": "off",
|
46
|
+
"no-multi-spaces": "warn",
|
47
|
+
"no-multiple-empty-lines": "warn",
|
48
|
+
"object-curly-newline": ["warn", { "consistent": true }],
|
49
|
+
"object-curly-spacing": ["error", "always"],
|
50
|
+
"object-property-newline": ["warn", { "allowAllPropertiesOnSameLine": true }],
|
51
|
+
"padding-line-between-statements": [
|
52
|
+
"error",
|
53
|
+
{ "blankLine": "always", "prev": ["directive", "import"], "next": "*" },
|
54
|
+
{ "blankLine": "any", "prev": ["directive", "import"], "next": ["directive", "import"] },
|
55
|
+
|
56
|
+
{ "blankLine": "always", "prev": "*", "next": ["export", "class", "function", "iife"] },
|
57
|
+
{ "blankLine": "always", "prev": ["export", "class", "function", "iife"], "next": "*" },
|
58
|
+
|
59
|
+
// { "blankLine": "always", "prev": "*", "next": "return" }, // Newline before return
|
60
|
+
|
61
|
+
// { "blankLine": "always", "prev": "*", "next": "multiline-block-like" }, // Newline BEFORE multiline block
|
62
|
+
// { "blankLine": "always", "prev": "multiline-block-like", "next": "*" } // Newline AFTER multiline block
|
63
|
+
],
|
64
|
+
"quotes": [
|
65
|
+
"error",
|
66
|
+
"double"
|
67
|
+
],
|
68
|
+
"rest-spread-spacing": ["error", "never"],
|
69
|
+
"semi": [
|
70
|
+
"error",
|
71
|
+
"always"
|
72
|
+
],
|
73
|
+
"semi-spacing": ["error", {"before": false, "after": true}],
|
74
|
+
"semi-style": ["error", "last"],
|
75
|
+
"space-before-blocks": [
|
76
|
+
"warn",
|
77
|
+
"always"
|
78
|
+
],
|
79
|
+
"space-before-function-paren": [
|
80
|
+
"warn",
|
81
|
+
{
|
82
|
+
"anonymous": "always",
|
83
|
+
"asyncArrow": "always",
|
84
|
+
"named": "never"
|
85
|
+
}
|
86
|
+
],
|
87
|
+
"space-in-parens": [
|
88
|
+
"warn",
|
89
|
+
"never"
|
90
|
+
],
|
91
|
+
"space-infix-ops": "warn",
|
92
|
+
"switch-colon-spacing": ["error", {"after": true, "before": false}],
|
93
|
+
"template-curly-spacing": ["error", "never"],
|
94
|
+
|
95
|
+
// =================== Other rules ===================
|
96
|
+
|
97
|
+
"arrow-body-style": "error",
|
98
|
+
"arrow-parens": ["error", "as-needed"],
|
99
|
+
"class-methods-use-this": "off", // Warn when methods could be static
|
100
|
+
"complexity": ["warn", { "max": 20 }],
|
101
|
+
"curly": "error",
|
102
|
+
"default-case-last": "error",
|
103
|
+
"default-param-last": "error",
|
104
|
+
"dot-location": ["error", "property"],
|
105
|
+
"eqeqeq": ["error", "always"],
|
106
|
+
"guard-for-in": "error",
|
107
|
+
"grouped-accessor-pairs": "error",
|
108
|
+
"handle-callback-err": "error",
|
109
|
+
"id-denylist": [
|
110
|
+
"error",
|
111
|
+
"any",
|
112
|
+
"Number",
|
113
|
+
"number",
|
114
|
+
"String",
|
115
|
+
"string",
|
116
|
+
"Boolean",
|
117
|
+
"boolean",
|
118
|
+
"Function",
|
119
|
+
"Undefined"
|
120
|
+
//"undefined"
|
121
|
+
],
|
122
|
+
"id-match": "error",
|
63
123
|
"max-classes-per-file": ["off", 5],
|
64
124
|
"max-depth": ["warn", { "max": 5 }], // default 4
|
65
125
|
"max-params": ["off", { "max": 6 }], // default 3 - SWITCHED OFF - does not work well with constructor injection
|
@@ -90,14 +150,16 @@ module.exports = {
|
|
90
150
|
"no-implied-eval": "error",
|
91
151
|
"no-inner-declarations": "off", // Switched off from recommended rules, gave too many issues
|
92
152
|
"no-invalid-this": "error",
|
93
|
-
"no-multi-spaces": "warn",
|
94
153
|
"no-multi-str": "error",
|
95
154
|
"no-lone-blocks": "error",
|
96
155
|
"no-lonely-if": "error",
|
97
|
-
"no-multiple-empty-lines": "warn",
|
98
156
|
"no-new-func": "error",
|
99
157
|
"no-new-wrappers": "error",
|
100
158
|
"no-octal-escape": "error",
|
159
|
+
"no-redeclare": "error",
|
160
|
+
"no-restricted-imports": ["off", {
|
161
|
+
"paths": []
|
162
|
+
}],
|
101
163
|
"no-restricted-syntax": [
|
102
164
|
"off", // Below - rules to require Async suffix on async methods - not good enough
|
103
165
|
// {
|
@@ -170,9 +232,6 @@ module.exports = {
|
|
170
232
|
"no-var": "error",
|
171
233
|
"no-void": "error",
|
172
234
|
"no-warning-comments": ["warn", { "terms": ["todo"] }],
|
173
|
-
"object-curly-newline": ["warn", { "consistent": true }],
|
174
|
-
"object-curly-spacing": ["error", "always"],
|
175
|
-
"object-property-newline": ["warn", { "allowAllPropertiesOnSameLine": true }],
|
176
235
|
"object-shorthand": [
|
177
236
|
"error",
|
178
237
|
"never"
|
@@ -181,29 +240,12 @@ module.exports = {
|
|
181
240
|
"error",
|
182
241
|
"never"
|
183
242
|
],
|
184
|
-
"padding-line-between-statements": [
|
185
|
-
"error",
|
186
|
-
{ "blankLine": "always", "prev": ["directive", "import"], "next": "*" },
|
187
|
-
{ "blankLine": "any", "prev": ["directive", "import"], "next": ["directive", "import"] },
|
188
|
-
|
189
|
-
{ "blankLine": "always", "prev": "*", "next": ["export", "class", "function", "iife"] },
|
190
|
-
{ "blankLine": "always", "prev": ["export", "class", "function", "iife"], "next": "*" },
|
191
|
-
|
192
|
-
// { "blankLine": "always", "prev": "*", "next": "return" }, // Newline before return
|
193
|
-
|
194
|
-
// { "blankLine": "always", "prev": "*", "next": "multiline-block-like" }, // Newline BEFORE multiline block
|
195
|
-
// { "blankLine": "always", "prev": "multiline-block-like", "next": "*" } // Newline AFTER multiline block
|
196
|
-
],
|
197
243
|
"prefer-arrow-callback": "error",
|
198
244
|
"prefer-const": "error",
|
199
245
|
"prefer-exponentiation-operator": "error",
|
200
246
|
"prefer-object-spread": "error",
|
201
247
|
"prefer-promise-reject-errors": "error",
|
202
248
|
"prefer-template": "error",
|
203
|
-
"quotes": [
|
204
|
-
"error",
|
205
|
-
"double"
|
206
|
-
],
|
207
249
|
"quote-props": [
|
208
250
|
"error",
|
209
251
|
"consistent-as-needed"
|
@@ -211,33 +253,7 @@ module.exports = {
|
|
211
253
|
"radix": "error",
|
212
254
|
"require-await": "error",
|
213
255
|
"require-unicode-regexp": "error",
|
214
|
-
"rest-spread-spacing": ["error", "never"],
|
215
256
|
"return-await": "error",
|
216
|
-
"semi": [
|
217
|
-
"error",
|
218
|
-
"always"
|
219
|
-
],
|
220
|
-
"semi-spacing": ["error", {"before": false, "after": true}],
|
221
|
-
"semi-style": ["error", "last"],
|
222
|
-
"space-before-blocks": [
|
223
|
-
"warn",
|
224
|
-
"always"
|
225
|
-
],
|
226
|
-
"space-before-function-paren": [
|
227
|
-
"warn",
|
228
|
-
{
|
229
|
-
"anonymous": "always",
|
230
|
-
"asyncArrow": "always",
|
231
|
-
"named": "never"
|
232
|
-
}
|
233
|
-
],
|
234
|
-
"space-in-parens": [
|
235
|
-
"warn",
|
236
|
-
"never"
|
237
|
-
],
|
238
|
-
"space-infix-ops": "warn",
|
239
|
-
"switch-colon-spacing": ["error", {"after": true, "before": false}],
|
240
|
-
"template-curly-spacing": ["error", "never"],
|
241
257
|
"unicode-bom": ["error", "never"],
|
242
258
|
"yoda": "error"
|
243
259
|
}
|
@@ -11,12 +11,12 @@ module.exports = {
|
|
11
11
|
"ignorePackages"
|
12
12
|
],
|
13
13
|
"import/no-commonjs": "error", // Disallow require() syntax - only esm syntax allowed
|
14
|
-
"import/no-nodejs-modules": "error", // Disallowed: import * as path from "path"; Allowed: import * as path from "node:path";
|
15
14
|
"import/no-default-export": "off",
|
16
15
|
"import/no-deprecated": "error",
|
17
16
|
"import/no-duplicates": "error",
|
18
17
|
"import/no-extraneous-dependencies": "off",
|
19
18
|
"import/no-internal-modules": "off",
|
19
|
+
"import/no-nodejs-modules": "off",
|
20
20
|
"import/no-unassigned-import": "error",
|
21
21
|
"import/order": "off"
|
22
22
|
}
|
@@ -0,0 +1,14 @@
|
|
1
|
+
module.exports = {
|
2
|
+
"plugins": [
|
3
|
+
"no-lookahead-lookbehind-regexp",
|
4
|
+
],
|
5
|
+
"rules": {
|
6
|
+
"no-lookahead-lookbehind-regexp/no-lookahead-lookbehind-regexp": [
|
7
|
+
"error",
|
8
|
+
"no-lookahead",
|
9
|
+
"no-lookbehind",
|
10
|
+
"no-negative-lookahead",
|
11
|
+
"no-negative-lookbehind"
|
12
|
+
]
|
13
|
+
}
|
14
|
+
};
|
@@ -0,0 +1,139 @@
|
|
1
|
+
const eslintRuleSet = require("../eslint.js");
|
2
|
+
const { deepMergeObjects } = require("../../utils/merge.js");
|
3
|
+
|
4
|
+
const eslintRules = eslintRuleSet.rules;
|
5
|
+
|
6
|
+
// Map of all the typescript-eslint extensions.
|
7
|
+
// If extension rule has additional properties compared to standard eslint rule:
|
8
|
+
// If the map value is null:
|
9
|
+
// The options from the standard rule will be used as is.
|
10
|
+
// If the map value is an object:
|
11
|
+
// The object will be merged merged with standard rule (rule object 1).
|
12
|
+
// If the map value is an array:
|
13
|
+
// The items of the array will be added as a new rule options object.
|
14
|
+
// If the map value is a function:
|
15
|
+
// The standard eslint options object will be passed as parameters, the return statement will be added as options.
|
16
|
+
|
17
|
+
const extensions = new Map([
|
18
|
+
|
19
|
+
// ================== Formatting rules ==================
|
20
|
+
|
21
|
+
["block-spacing", true],
|
22
|
+
["brace-style", true],
|
23
|
+
["camelcase", false],
|
24
|
+
["comma-dangle", true],
|
25
|
+
["comma-spacing", true],
|
26
|
+
["func-call-spacing", true],
|
27
|
+
["indent", true],
|
28
|
+
["key-spacing", true],
|
29
|
+
["keyword-spacing", true],
|
30
|
+
["lines-arround-comment", true],
|
31
|
+
["lines-between-class-members", true],
|
32
|
+
["member-delimiter-style", true],
|
33
|
+
["no-extra-parens", true],
|
34
|
+
["object-curly-spacing", true],
|
35
|
+
["padding-line-between-statements", [
|
36
|
+
{ "blankLine": "always", "prev": "*", "next": ["interface", "type"] },
|
37
|
+
{ "blankLine": "always", "prev": ["interface", "type"], "next": "*" }
|
38
|
+
]],
|
39
|
+
["quotes", true],
|
40
|
+
["semi", true],
|
41
|
+
["space-before-blocks", true],
|
42
|
+
["space-before-function-paren", true],
|
43
|
+
["space-infix-ops", false],
|
44
|
+
// ["space-infix-ops", true] // buggy with typescript (as of 5.27.0) -- switched off below
|
45
|
+
|
46
|
+
|
47
|
+
// =================== Other rules ===================
|
48
|
+
|
49
|
+
["default-param-last", true],
|
50
|
+
["dot-notation", {
|
51
|
+
"allowPrivateClassPropertyAccess": false,
|
52
|
+
"allowProtectedClassPropertyAccess": false,
|
53
|
+
"allowIndexSignaturePropertyAccess": false
|
54
|
+
}],
|
55
|
+
["init-declarations", true],
|
56
|
+
["lines-between-class-members", {
|
57
|
+
"exceptAfterOverload": true
|
58
|
+
}],
|
59
|
+
["no-array-constructor", true],
|
60
|
+
["no-dupe-class-members", true],
|
61
|
+
["no-duplicate-imports", true],
|
62
|
+
["no-empty-function", {
|
63
|
+
allow: ["private-constructors", "protected-constructors" /* "decoratedFunctions", "overrideMethods" */ ]
|
64
|
+
}],
|
65
|
+
["no-extra-semi", true],
|
66
|
+
["no-implied-eval", true],
|
67
|
+
["no-invalid-this", false],
|
68
|
+
["no-loop-func", true],
|
69
|
+
["no-loss-of-precision", true],
|
70
|
+
["no-magic-numbers", true],
|
71
|
+
["no-redeclare", true],
|
72
|
+
["no-restricted-imports", true],
|
73
|
+
["no-shadow", v => {
|
74
|
+
const o = {
|
75
|
+
...v,
|
76
|
+
"ignoreTypeValueShadow": true,
|
77
|
+
"ignoreFunctionTypeParameterNameValueShadow": true
|
78
|
+
};
|
79
|
+
delete o["ignoreOnInitialization"]; // Temporary bug in @typescript/eslint "no-shadow" extension rule - "ignoreOnInitialization" property considered invalid
|
80
|
+
return o;
|
81
|
+
}],
|
82
|
+
["no-throw-literal", true],
|
83
|
+
["no-unused-expressions", true],
|
84
|
+
["no-unused-vars", false],
|
85
|
+
["no-use-before-define", false],
|
86
|
+
["no-useless-constructor", false],
|
87
|
+
["require-await", true],
|
88
|
+
["return-await", true],
|
89
|
+
]);
|
90
|
+
|
91
|
+
// console.log(extensionRules);
|
92
|
+
// console.log(`Converted ${Object.keys(extensionRules).filter(k => !k.startsWith("@typescript")).length} of ${extensions.size} available extension rules`);
|
93
|
+
// console.log("Not converted:", Array.from(extensions.keys()).filter(k => !Object.keys(extensionRules).filter(k => !k.startsWith("@typescript")).includes(k)));
|
94
|
+
|
95
|
+
// Building eslint-typescript rules for existsing eslint rules and switching off original eslint rule
|
96
|
+
module.exports.typescriptEslintExtensionrules = Object.entries(eslintRules).reduce((extRules, [key, value]) => {
|
97
|
+
|
98
|
+
// Try to get from known extensions map
|
99
|
+
const extension = extensions.get(key);
|
100
|
+
|
101
|
+
// If found in known typescript eslint extension rules map
|
102
|
+
if (extension !== undefined) {
|
103
|
+
|
104
|
+
// Switch off standard eslint rule
|
105
|
+
extRules[key] = "off";
|
106
|
+
|
107
|
+
// Special handling of certain extension rules that need to be switched off:
|
108
|
+
if (extension === false) {
|
109
|
+
extRules[`@typescript-eslint/${key}`] = "off";
|
110
|
+
} else {
|
111
|
+
// If extension rule has extended options, merge with standard eslint rule options:
|
112
|
+
if (extension !== true) {
|
113
|
+
// Ensure value is array if only severity string:
|
114
|
+
value = Array.isArray(value) ? [...value] : [value];
|
115
|
+
if (Array.isArray(extension)) {
|
116
|
+
value.push(...extension);
|
117
|
+
} else if (typeof extension === "object") {
|
118
|
+
// If array only contains severity string, push object
|
119
|
+
if (value.length === 1) {
|
120
|
+
value.push(extension);
|
121
|
+
// Else merge object
|
122
|
+
} else {
|
123
|
+
value[value.length - 1] = deepMergeObjects(value[value.length - 1], extension);
|
124
|
+
}
|
125
|
+
} else if (typeof extension === "function") {
|
126
|
+
const [, ...options] = value;
|
127
|
+
value[value.length - 1] = { ...extension(...options) };
|
128
|
+
}
|
129
|
+
}
|
130
|
+
// Add extension rule value with the @typescript-eslint key prefix
|
131
|
+
extRules[`@typescript-eslint/${key}`] = value;
|
132
|
+
}
|
133
|
+
|
134
|
+
|
135
|
+
}
|
136
|
+
// else: if no extension rule exists, the standard eslint rule will be used through the "extends" configuration below
|
137
|
+
|
138
|
+
return extRules;
|
139
|
+
}, {});
|