@josundt/eslint-config 4.9.7 → 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 CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@josundt/eslint-config",
3
- "version": "4.9.7",
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": ">=4.9.3"
30
+ "typescript": ">=5.0.4"
31
31
  },
32
32
  "dependencies": {
33
- "@typescript-eslint/eslint-plugin": "5.45.0",
34
- "@typescript-eslint/parser": "5.45.0",
35
- "eslint": "8.28.0",
36
- "eslint-import-resolver-typescript": "3.5.2",
37
- "eslint-plugin-deprecation": "1.3.3",
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.26.0",
39
+ "eslint-plugin-import": "2.27.5",
40
40
  "eslint-plugin-jasmine": "4.1.3",
41
- "eslint-plugin-jest": "27.1.6",
42
- "eslint-plugin-jsdoc": "39.6.4",
43
- "eslint-plugin-unicorn": "45.0.1"
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
- "arrow-body-style": "error",
7
- "arrow-parens": ["error", "as-needed"],
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
- "class-methods-use-this": "off", // Warn when methods could be static
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,8 @@
1
+ module.exports = {
2
+ "extends": [
3
+ "./import-typescript-node.js"
4
+ ],
5
+ "rules": {
6
+ "import/no-nodejs-modules": "error" // Disallowed: import * as path from "path"; Allowed: import * as path from "node:path";
7
+ }
8
+ };
@@ -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
+ }, {});