@josundt/eslint-config 4.6.1 → 4.7.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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@josundt/eslint-config",
3
- "version": "4.6.1",
3
+ "version": "4.7.3",
4
4
  "description": "ESLint ruleset with required plugins for josundt TypeScript projects",
5
5
  "main": "index.js",
6
6
  "scripts": {
@@ -23,20 +23,21 @@
23
23
  "license": "ISC",
24
24
  "files": [
25
25
  "*.js",
26
- "rules/**/*.js"
26
+ "rules/**/*.js",
27
+ "utils/**/*.js"
27
28
  ],
28
29
  "peerDependencies": {
29
- "typescript": ">=4.6.2"
30
+ "typescript": ">=4.7.2"
30
31
  },
31
32
  "dependencies": {
32
- "@typescript-eslint/eslint-plugin": "5.14.0",
33
- "@typescript-eslint/parser": "5.14.0",
34
- "eslint": "8.10.0",
35
- "eslint-import-resolver-typescript": "2.5.0",
33
+ "@typescript-eslint/eslint-plugin": "5.27.0",
34
+ "@typescript-eslint/parser": "5.27.0",
35
+ "eslint": "8.16.0",
36
+ "eslint-import-resolver-typescript": "2.7.1",
36
37
  "eslint-plugin-deprecation": "1.3.2",
37
- "eslint-plugin-import": "2.25.4",
38
+ "eslint-plugin-import": "2.26.0",
38
39
  "eslint-plugin-jasmine": "4.1.3",
39
- "eslint-plugin-jsdoc": "37.9.7",
40
- "eslint-plugin-unicorn": "41.0.0"
40
+ "eslint-plugin-jsdoc": "39.3.2",
41
+ "eslint-plugin-unicorn": "42.0.0"
41
42
  }
42
43
  }
package/rules/eslint.js CHANGED
@@ -141,7 +141,9 @@ module.exports = {
141
141
  "no-duplicate-imports": "error",
142
142
  "no-empty": "error",
143
143
  "no-empty-character-class": "error",
144
- "no-empty-function": "error",
144
+ "no-empty-function": ["error", {
145
+ //allow: [/*"functions", "arrowFunctions", "generatorFunctions", "methods", "generatorMethods", "getters", "setters", "constructors", "asyncFunctions", "asyncMethods"*/]
146
+ }],
145
147
  "no-eval": "error",
146
148
  "no-ex-assign": "error",
147
149
  "no-extra-bind": "error",
@@ -205,7 +207,10 @@ module.exports = {
205
207
  "no-shadow": [
206
208
  "error",
207
209
  {
208
- "hoist": "all"
210
+ "hoist": "all",
211
+ "builtinGlobals": false,
212
+ "ignoreOnInitialization": false,
213
+ "allow": [] // array of identifier names for which shadowing is allowed
209
214
  }
210
215
  ],
211
216
  "no-sparse-arrays": "error",
@@ -226,7 +231,8 @@ module.exports = {
226
231
  "error",
227
232
  {
228
233
  "vars": "all",
229
- "args": "none"
234
+ "args": "none",
235
+ "destructuredArrayIgnorePattern": "^_"
230
236
  }
231
237
  ],
232
238
  "no-use-before-define": "error",
@@ -8,12 +8,13 @@ module.exports = {
8
8
  "rules": {
9
9
  "import/extensions": [ // Ensure all local .ts file imports use .js extension
10
10
  "error",
11
- "always"
11
+ "ignorePackages"
12
12
  ],
13
13
  "import/no-commonjs": "error", // Disallow require() syntax - only esm syntax allowed
14
14
  "import/no-nodejs-modules": "error", // Disallowed: import * as path from "path"; Allowed: import * as path from "node:path";
15
15
  "import/no-default-export": "off",
16
16
  "import/no-deprecated": "error",
17
+ "import/no-duplicates": "error",
17
18
  "import/no-extraneous-dependencies": "off",
18
19
  "import/no-internal-modules": "off",
19
20
  "import/no-unassigned-import": "error",
@@ -1,4 +1,6 @@
1
- const eslintRuleSet = require("./eslint");
1
+ const eslintRuleSet = require("./eslint.js");
2
+ const { deepMergeObjects } = require("../utils/merge.js");
3
+
2
4
  const eslintRules = eslintRuleSet.rules;
3
5
 
4
6
  // Map of all the typescript-eslint extensions.
@@ -28,8 +30,9 @@ const extensions = new Map([
28
30
  }],
29
31
  ["no-array-constructor", null],
30
32
  ["no-dupe-class-members", null],
31
- ["no-duplicate-imports", null],
32
- ["no-empty-function", null],
33
+ ["no-empty-function", {
34
+ allow: ["private-constructors", "protected-constructors" /* "decoratedFunctions", "overrideMethods" */ ]
35
+ }],
33
36
  ["no-extra-parens", null],
34
37
  ["no-extra-semi", null],
35
38
  ["no-invalid-this", null],
@@ -60,16 +63,18 @@ const extensions = new Map([
60
63
  ["semi", null],
61
64
  ["space-before-blocks", null],
62
65
  ["space-before-function-paren", null],
63
- ["space-infix-ops", null]
66
+ // ["space-infix-ops", null] // buggy with typescript (as of 5.27.0) -- switched off below
64
67
  ]);
65
68
 
66
69
  switchOffExtensions = new Set([
67
70
  "no-unused-vars",
68
71
  "no-invalid-this",
69
72
  "no-use-before-define",
70
- "no-useless-constructor"
73
+ "no-useless-constructor",
74
+ "space-infix-ops"
71
75
  ]);
72
76
 
77
+
73
78
  // Building eslint-typescript rules for existsing eslint rules and switching off original eslint rule
74
79
  const extendedEslintRules = Object.entries(eslintRules).reduce((extRules, [key, value]) => {
75
80
 
@@ -88,13 +93,21 @@ const extendedEslintRules = Object.entries(eslintRules).reduce((extRules, [key,
88
93
  } else {
89
94
  // If extension rule has extended options, merge with standard eslint rule options:
90
95
  if (extension !== null) {
91
- value = [...value];
96
+ // Ensure value is array if only severity string:
97
+ value = Array.isArray(value) ? [...value] : [value];
92
98
  if (Array.isArray(extension)) {
93
99
  value.push(...extension);
94
100
  } else if (typeof extension === "object") {
95
- value[value.length - 1] = { ...value[value.length - 1], ...extension }
101
+ // If array only contains severity string, push object
102
+ if (value.length === 1) {
103
+ value.push(extension);
104
+ // Else merge object
105
+ } else {
106
+ value[value.length - 1] = deepMergeObjects(value[value.length - 1], extension);
107
+ }
96
108
  } else if (typeof extension === "function") {
97
- value[value.length - 1] = { ...extension(value[value.length - 1]) };
109
+ const [, ...options] = value;
110
+ value[value.length - 1] = { ...extension(...options) };
98
111
  }
99
112
  }
100
113
  // Add extension rule value with the @typescript-eslint key prefix
@@ -138,7 +151,17 @@ module.exports = {
138
151
  }
139
152
  ],
140
153
  "@typescript-eslint/await-thenable": "error",
141
- "@typescript-eslint/ban-ts-comment": "error",
154
+ "@typescript-eslint/ban-ts-comment": [
155
+ "error",
156
+ {
157
+ "ts-expect-error": "allow-with-description",
158
+ "ts-ignore": true,
159
+ "ts-nocheck": true,
160
+ "ts-check": false,
161
+ "minimumDescriptionLength": 10,
162
+ //"descriptionFormat": "someformathere"
163
+ }
164
+ ],
142
165
  "@typescript-eslint/ban-tslint-comment": "error", // No longer use tslint - remove rules
143
166
  "@typescript-eslint/ban-types": "off", // Can be used to ban certain types
144
167
  "@typescript-eslint/consistent-indexed-object-style": ["error", "record"],
@@ -256,6 +279,7 @@ module.exports = {
256
279
  "ignoreArrowShorthand": true
257
280
  }
258
281
  ],
282
+ "@typescript-eslint/no-duplicate-enum-values": "error",
259
283
  "@typescript-eslint/no-dynamic-delete": "error",
260
284
  "@typescript-eslint/no-empty-interface": "off",
261
285
  "@typescript-eslint/no-explicit-any": "off",
@@ -278,6 +302,7 @@ module.exports = {
278
302
  "error",
279
303
  {
280
304
  checksConditionals: true,
305
+ checksSpreads: true,
281
306
  checksVoidReturn: true // {
282
307
  // arguments: true, //Disables checking an asynchronous function passed as argument where the parameter type expects a function that returns void
283
308
  // attributes: true, //Disables checking an asynchronous function passed as a JSX attribute expected to be a function that returns void
@@ -291,12 +316,6 @@ module.exports = {
291
316
  "@typescript-eslint/no-non-null-asserted-nullish-coalescing": "error",
292
317
  "@typescript-eslint/no-non-null-asserted-optional-chain": "error",
293
318
  "@typescript-eslint/no-non-null-assertion": "off",
294
- "@typescript-eslint/no-parameter-properties": [
295
- "error",
296
- {
297
- "allows": ["private readonly", "private", "protected readonly"]
298
- }
299
- ],
300
319
  "@typescript-eslint/no-redundant-type-constituents": "error",
301
320
  "@typescript-eslint/no-require-imports": "error",
302
321
  "@typescript-eslint/no-this-alias": "error",
@@ -323,6 +342,13 @@ module.exports = {
323
342
  "@typescript-eslint/no-useless-empty-export": "error",
324
343
  "@typescript-eslint/no-var-requires": "error",
325
344
  "@typescript-eslint/non-nullable-type-assertion-style": "error",
345
+ "@typescript-eslint/parameter-properties": [
346
+ "error",
347
+ {
348
+ "prefer": "class-property", // or "parameter-property"
349
+ "allow": ["private readonly", "private", "protected readonly"]
350
+ }
351
+ ],
326
352
  "@typescript-eslint/prefer-as-const": "error",
327
353
  "@typescript-eslint/prefer-enum-initializers": "error",
328
354
  "@typescript-eslint/prefer-for-of": "error",
package/utils/merge.js ADDED
@@ -0,0 +1,93 @@
1
+ /**
2
+ *
3
+ * @param {any} o
4
+ * @returns o is {}
5
+ */
6
+ function isPlainObject(value) {
7
+ return !!value &&
8
+ !!(value = Object.getPrototypeOf(value)) &&
9
+ !Object.getPrototypeOf(value);
10
+ }
11
+
12
+ /**
13
+ *
14
+ * @param {any[]} first
15
+ * @param {any[]} second
16
+ * @param {boolean} insertBoth
17
+ * @returns {any[]}
18
+ */
19
+ function deepMergeArrays(first, second, insertBoth = true) {
20
+ let result = [];
21
+ for (let i = 0; i < Math.max(first.length, second.length); i++) {
22
+ if (i < second.length) {
23
+ if (i < first.length) {
24
+ if (Array.isArray(second[i])) {
25
+ if (Array.isArray(first[i])) {
26
+ result.push(deepMergeArrays(first[i], second[i]));
27
+ } else {
28
+ result.push(first[i]);
29
+ }
30
+ } else if (isPlainObject(second[i])) {
31
+ if (isPlainObject(first[i])) {
32
+ result.push(deepMergeObjects(first[i], second[i]));
33
+ } else {
34
+ result.push(first[i]);
35
+ }
36
+ } else {
37
+ if (first[i] === second[i] && !insertBoth) {
38
+ result.push(first[i]);
39
+ } else {
40
+ result.push(first[i], second[i]);
41
+ }
42
+ }
43
+ } else {
44
+ result.push(second[i]);
45
+ }
46
+ } else {
47
+ result.push(first[i]);
48
+ }
49
+ }
50
+ return result;
51
+ }
52
+
53
+ /**
54
+ *
55
+ * @param {{}} first
56
+ * @param {{}} second
57
+ * @returns {{}}
58
+ */
59
+ function deepMergeObjects(first, second) {
60
+ const result = {};
61
+ const remainingKeysFromSecond = new Set(Object.keys(second));
62
+ for (const key of Object.keys(first)) {
63
+ if (remainingKeysFromSecond.has(key)) {
64
+ if (Array.isArray(first[key])) {
65
+ if (Array.isArray(second[key])) {
66
+ result[key] = deepMergeArrays(first[key], second[key]);
67
+ } else {
68
+ result[key] = first[key];
69
+ }
70
+ } else if (isPlainObject(first[key])) {
71
+ if (isPlainObject(second[key])) {
72
+ result[key] = deepMergeObjects(first[key], second[key]);
73
+ } else {
74
+ result[key] = first[key];
75
+ }
76
+ } else {
77
+ result[key] = first[key];
78
+ }
79
+ remainingKeysFromSecond.delete(key);
80
+ } else {
81
+ result[key] = first[key];
82
+ }
83
+ }
84
+ for (const key of Array.from(remainingKeysFromSecond)) {
85
+ result[key] = second[key];
86
+ }
87
+ return result;
88
+ }
89
+
90
+ module.exports = {
91
+ deepMergeObjects,
92
+ deepMergeArrays
93
+ };