eslint-config-agent 1.1.4 → 1.2.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.
- package/CHANGELOG.md +11 -0
- package/index.js +14 -5
- package/package.json +2 -2
- package/rules/max-file-lines/examples/invalid/long-file.js +113 -0
- package/rules/max-file-lines/examples/invalid/medium-file.js +127 -0
- package/rules/max-file-lines/examples/invalid/very-long-file.ts +144 -0
- package/rules/max-file-lines/examples/valid/short-file.js +66 -0
- package/rules/max-file-lines/examples/valid/spec-file.spec.js +44 -0
- package/rules/max-file-lines/examples/valid/test-file.test.js +25 -0
- package/rules/plugin/import/group-exports/examples/invalid/mixed-declaration-styles.js +8 -0
- package/rules/plugin/import/group-exports/examples/invalid/multiple-export-statements.js +8 -0
- package/rules/plugin/import/group-exports/examples/invalid/scattered-exports.js +10 -0
- package/rules/plugin/import/group-exports/examples/valid/direct-exports.js +2 -0
- package/rules/plugin/import/group-exports/examples/valid/mixed-with-default.js +7 -0
- package/rules/plugin/import/group-exports/examples/valid/single-export-statement.js +6 -0
- package/rules/plugin/import/group-exports/index.js +3 -0
- package/rules/plugin/import/index.js +5 -1
- package/rules/plugin/import/no-unused-modules/examples/invalid/dead-code.js +2 -0
- package/rules/plugin/import/no-unused-modules/examples/invalid/unused-class.js +6 -0
- package/rules/plugin/import/no-unused-modules/examples/invalid/unused-export.js +2 -0
- package/rules/plugin/import/no-unused-modules/examples/invalid/unused-function.js +4 -0
- package/rules/plugin/import/no-unused-modules/examples/invalid/unused-module.js +4 -0
- package/rules/plugin/import/no-unused-modules/examples/valid/consumed-import.js +8 -0
- package/rules/plugin/import/no-unused-modules/examples/valid/entry-point.js +5 -0
- package/rules/plugin/import/no-unused-modules/examples/valid/used-class.js +6 -0
- package/rules/plugin/import/no-unused-modules/examples/valid/used-export.js +2 -0
- package/rules/plugin/import/no-unused-modules/examples/valid/used-function.js +4 -0
- package/rules/plugin/import/no-unused-modules/index.js +6 -0
- package/rules/plugin/typescript-eslint/index.js +3 -1
- package/rules/plugin/typescript-eslint/no-explicit-any/examples/invalid/any-array.ts +2 -0
- package/rules/plugin/typescript-eslint/no-explicit-any/examples/invalid/any-parameter.ts +4 -0
- package/rules/plugin/typescript-eslint/no-explicit-any/examples/invalid/any-return-type.ts +4 -0
- package/rules/plugin/typescript-eslint/no-explicit-any/examples/invalid/any-variable.ts +5 -0
- package/rules/plugin/typescript-eslint/no-explicit-any/examples/valid/generics.ts +16 -0
- package/rules/plugin/typescript-eslint/no-explicit-any/examples/valid/specific-types.ts +9 -0
- package/rules/plugin/typescript-eslint/no-explicit-any/examples/valid/unknown-type.ts +8 -0
- package/rules/plugin/typescript-eslint/no-explicit-any/index.js +3 -0
package/CHANGELOG.md
CHANGED
|
@@ -4,6 +4,17 @@ All notable changes to this project will be documented in this file. See [Conven
|
|
|
4
4
|
|
|
5
5
|
|
|
6
6
|
|
|
7
|
+
## [1.2.0](https://github.com/tupe12334/eslint-config/compare/v1.1.4...v1.2.0) (2025-09-11)
|
|
8
|
+
|
|
9
|
+
### Features
|
|
10
|
+
|
|
11
|
+
* add examples for valid and invalid export patterns and update import rules configuration ([a78e03d](https://github.com/tupe12334/eslint-config/commit/a78e03d201e335b423c1830593c015ddd0346028))
|
|
12
|
+
* add no-explicit-any rule configuration and examples for valid/invalid usage ([2bc0ad8](https://github.com/tupe12334/eslint-config/commit/2bc0ad836ff42199456ebc7ebd0b6948cca1a7b1))
|
|
13
|
+
* add no-unused-modules rule configuration and examples for unused exports ([336db1b](https://github.com/tupe12334/eslint-config/commit/336db1b26bf4ac0d3e9bd56c95817748bfda4799))
|
|
14
|
+
* refine ESLint configuration to include specific index.js files and update CI test command ([5693dbc](https://github.com/tupe12334/eslint-config/commit/5693dbc65dc37cbddb6a41498b4886d360c17684))
|
|
15
|
+
* update ESLint configuration to disable size limits for test/spec files and add examples for valid/invalid file lengths ([ac57e22](https://github.com/tupe12334/eslint-config/commit/ac57e223f7d1cedab32976cee5f305ca197ca0c8))
|
|
16
|
+
* update export statements in test files to use default export syntax ([c4a846b](https://github.com/tupe12334/eslint-config/commit/c4a846bc78105f287fafcb4248c8de334c84b0fb))
|
|
17
|
+
|
|
7
18
|
## [1.1.4](https://github.com/tupe12334/eslint-config/compare/v1.1.3...v1.1.4) (2025-09-10)
|
|
8
19
|
|
|
9
20
|
### Features
|
package/index.js
CHANGED
|
@@ -423,7 +423,7 @@ const config = [
|
|
|
423
423
|
"**/*.cjs",
|
|
424
424
|
"**/*.mjs",
|
|
425
425
|
"**/*.stories.{js,jsx,ts,tsx}",
|
|
426
|
-
"**/rules
|
|
426
|
+
"**/rules/**/index.js",
|
|
427
427
|
],
|
|
428
428
|
languageOptions: {
|
|
429
429
|
parserOptions: {
|
|
@@ -684,7 +684,7 @@ const config = [
|
|
|
684
684
|
},
|
|
685
685
|
},
|
|
686
686
|
|
|
687
|
-
// Disable function size limits for test and spec files
|
|
687
|
+
// Disable function and file size limits for test and spec files
|
|
688
688
|
{
|
|
689
689
|
files: [
|
|
690
690
|
"**/*.test.{js,jsx,ts,tsx}",
|
|
@@ -700,6 +700,7 @@ const config = [
|
|
|
700
700
|
],
|
|
701
701
|
rules: {
|
|
702
702
|
"max-lines-per-function": "off",
|
|
703
|
+
"max-lines": "off", // Ignore file length limits in test and spec files
|
|
703
704
|
// Allow multiple exports in test files for testing import/export patterns
|
|
704
705
|
"no-restricted-syntax": [
|
|
705
706
|
"warn",
|
|
@@ -805,7 +806,7 @@ const config = [
|
|
|
805
806
|
"**/test/**",
|
|
806
807
|
"!**/test/export/**",
|
|
807
808
|
"!**/test/required-exports/**",
|
|
808
|
-
"**/rules
|
|
809
|
+
"**/rules/**/index.js",
|
|
809
810
|
],
|
|
810
811
|
rules: {
|
|
811
812
|
"no-restricted-syntax": [
|
|
@@ -916,7 +917,14 @@ const config = [
|
|
|
916
917
|
// Function and file length rules - strict error thresholds
|
|
917
918
|
{
|
|
918
919
|
files: ["**/*.{ts,tsx,js,jsx}"],
|
|
919
|
-
ignores: [
|
|
920
|
+
ignores: [
|
|
921
|
+
"**/*.stories.{js,jsx,ts,tsx}",
|
|
922
|
+
"**/*.test.{js,jsx,ts,tsx}",
|
|
923
|
+
"**/*.spec.{js,jsx,ts,tsx}",
|
|
924
|
+
"**/test/**/*.{js,jsx,ts,tsx}",
|
|
925
|
+
"**/tests/**/*.{js,jsx,ts,tsx}",
|
|
926
|
+
"**/__tests__/**/*.{js,jsx,ts,tsx}",
|
|
927
|
+
],
|
|
920
928
|
rules: {
|
|
921
929
|
// Function length: error at 70+ lines
|
|
922
930
|
"max-lines-per-function": allRules.maxFunctionLinesError,
|
|
@@ -977,9 +985,10 @@ const config = [
|
|
|
977
985
|
},
|
|
978
986
|
},
|
|
979
987
|
|
|
980
|
-
// Rules directory configuration - allow export specifiers for API definitions
|
|
988
|
+
// Rules directory configuration - allow export specifiers for API definitions (but not examples)
|
|
981
989
|
{
|
|
982
990
|
files: ["**/rules/**/*.{js,ts}"],
|
|
991
|
+
ignores: ["**/rules/**/examples/**"],
|
|
983
992
|
languageOptions: {
|
|
984
993
|
globals: {
|
|
985
994
|
...globals.node,
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "eslint-config-agent",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.2.0",
|
|
4
4
|
"description": "ESLint configuration package with TypeScript support",
|
|
5
5
|
"main": "index.js",
|
|
6
6
|
"type": "module",
|
|
@@ -28,7 +28,7 @@
|
|
|
28
28
|
"test:edge": "eslint test/edge-cases.tsx",
|
|
29
29
|
"test:performance": "eslint test/performance-test.tsx",
|
|
30
30
|
"test:comprehensive": "node scripts/test-runner.js",
|
|
31
|
-
"test:ci": "eslint . --ignore-pattern 'test/**' --ignore-pattern 'scripts/**' --max-warnings 0",
|
|
31
|
+
"test:ci": "eslint . --ignore-pattern 'test/**' --ignore-pattern 'scripts/**' --ignore-pattern 'rules/**/examples/**' --max-warnings 0",
|
|
32
32
|
"validate": "node scripts/validate-config.js",
|
|
33
33
|
"release": "dotenv -e .env -- release-it",
|
|
34
34
|
"release:patch": "dotenv -e .env -- release-it patch",
|
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
// Invalid: File with more than 100 lines (should trigger max-lines error)
|
|
2
|
+
const line1 = 1;
|
|
3
|
+
const line2 = 2;
|
|
4
|
+
const line3 = 3;
|
|
5
|
+
const line4 = 4;
|
|
6
|
+
const line5 = 5;
|
|
7
|
+
const line6 = 6;
|
|
8
|
+
const line7 = 7;
|
|
9
|
+
const line8 = 8;
|
|
10
|
+
const line9 = 9;
|
|
11
|
+
const line10 = 10;
|
|
12
|
+
const line11 = 11;
|
|
13
|
+
const line12 = 12;
|
|
14
|
+
const line13 = 13;
|
|
15
|
+
const line14 = 14;
|
|
16
|
+
const line15 = 15;
|
|
17
|
+
const line16 = 16;
|
|
18
|
+
const line17 = 17;
|
|
19
|
+
const line18 = 18;
|
|
20
|
+
const line19 = 19;
|
|
21
|
+
const line20 = 20;
|
|
22
|
+
const line21 = 21;
|
|
23
|
+
const line22 = 22;
|
|
24
|
+
const line23 = 23;
|
|
25
|
+
const line24 = 24;
|
|
26
|
+
const line25 = 25;
|
|
27
|
+
const line26 = 26;
|
|
28
|
+
const line27 = 27;
|
|
29
|
+
const line28 = 28;
|
|
30
|
+
const line29 = 29;
|
|
31
|
+
const line30 = 30;
|
|
32
|
+
const line31 = 31;
|
|
33
|
+
const line32 = 32;
|
|
34
|
+
const line33 = 33;
|
|
35
|
+
const line34 = 34;
|
|
36
|
+
const line35 = 35;
|
|
37
|
+
const line36 = 36;
|
|
38
|
+
const line37 = 37;
|
|
39
|
+
const line38 = 38;
|
|
40
|
+
const line39 = 39;
|
|
41
|
+
const line40 = 40;
|
|
42
|
+
const line41 = 41;
|
|
43
|
+
const line42 = 42;
|
|
44
|
+
const line43 = 43;
|
|
45
|
+
const line44 = 44;
|
|
46
|
+
const line45 = 45;
|
|
47
|
+
const line46 = 46;
|
|
48
|
+
const line47 = 47;
|
|
49
|
+
const line48 = 48;
|
|
50
|
+
const line49 = 49;
|
|
51
|
+
const line50 = 50;
|
|
52
|
+
const line51 = 51;
|
|
53
|
+
const line52 = 52;
|
|
54
|
+
const line53 = 53;
|
|
55
|
+
const line54 = 54;
|
|
56
|
+
const line55 = 55;
|
|
57
|
+
const line56 = 56;
|
|
58
|
+
const line57 = 57;
|
|
59
|
+
const line58 = 58;
|
|
60
|
+
const line59 = 59;
|
|
61
|
+
const line60 = 60;
|
|
62
|
+
const line61 = 61;
|
|
63
|
+
const line62 = 62;
|
|
64
|
+
const line63 = 63;
|
|
65
|
+
const line64 = 64;
|
|
66
|
+
const line65 = 65;
|
|
67
|
+
const line66 = 66;
|
|
68
|
+
const line67 = 67;
|
|
69
|
+
const line68 = 68;
|
|
70
|
+
const line69 = 69;
|
|
71
|
+
const line70 = 70;
|
|
72
|
+
const line71 = 71;
|
|
73
|
+
const line72 = 72;
|
|
74
|
+
const line73 = 73;
|
|
75
|
+
const line74 = 74;
|
|
76
|
+
const line75 = 75;
|
|
77
|
+
const line76 = 76;
|
|
78
|
+
const line77 = 77;
|
|
79
|
+
const line78 = 78;
|
|
80
|
+
const line79 = 79;
|
|
81
|
+
const line80 = 80;
|
|
82
|
+
const line81 = 81;
|
|
83
|
+
const line82 = 82;
|
|
84
|
+
const line83 = 83;
|
|
85
|
+
const line84 = 84;
|
|
86
|
+
const line85 = 85;
|
|
87
|
+
const line86 = 86;
|
|
88
|
+
const line87 = 87;
|
|
89
|
+
const line88 = 88;
|
|
90
|
+
const line89 = 89;
|
|
91
|
+
const line90 = 90;
|
|
92
|
+
const line91 = 91;
|
|
93
|
+
const line92 = 92;
|
|
94
|
+
const line93 = 93;
|
|
95
|
+
const line94 = 94;
|
|
96
|
+
const line95 = 95;
|
|
97
|
+
const line96 = 96;
|
|
98
|
+
const line97 = 97;
|
|
99
|
+
const line98 = 98;
|
|
100
|
+
const line99 = 99;
|
|
101
|
+
const line100 = 100;
|
|
102
|
+
const line101 = 101;
|
|
103
|
+
const line102 = 102;
|
|
104
|
+
const line103 = 103;
|
|
105
|
+
const line104 = 104;
|
|
106
|
+
const line105 = 105;
|
|
107
|
+
const line106 = 106;
|
|
108
|
+
const line107 = 107;
|
|
109
|
+
const line108 = 108;
|
|
110
|
+
const line109 = 109;
|
|
111
|
+
const line110 = 110;
|
|
112
|
+
|
|
113
|
+
export default line1;
|
|
@@ -0,0 +1,127 @@
|
|
|
1
|
+
// Invalid: File with 70-100 lines (should trigger max-lines warning)
|
|
2
|
+
// This file demonstrates what happens when a file grows beyond the recommended size
|
|
3
|
+
|
|
4
|
+
class ExtendedNumberUtils {
|
|
5
|
+
constructor() {
|
|
6
|
+
this.cache = new Map();
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
calculateSum(numbers) {
|
|
10
|
+
const key = numbers.join(',');
|
|
11
|
+
if (this.cache.has(key)) {
|
|
12
|
+
return this.cache.get(key);
|
|
13
|
+
}
|
|
14
|
+
const sum = numbers.reduce((acc, num) => acc + num, 0);
|
|
15
|
+
this.cache.set(key, sum);
|
|
16
|
+
return sum;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
calculateAverage(numbers) {
|
|
20
|
+
if (numbers.length === 0) return 0;
|
|
21
|
+
return this.calculateSum(numbers) / numbers.length;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
findMaxValue(numbers) {
|
|
25
|
+
if (numbers.length === 0) return null;
|
|
26
|
+
return Math.max(...numbers);
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
findMinValue(numbers) {
|
|
30
|
+
if (numbers.length === 0) return null;
|
|
31
|
+
return Math.min(...numbers);
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
sortNumbers(numbers) {
|
|
35
|
+
return [...numbers].sort((a, b) => a - b);
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
filterEvenNumbers(numbers) {
|
|
39
|
+
return numbers.filter(num => num % 2 === 0);
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
filterOddNumbers(numbers) {
|
|
43
|
+
return numbers.filter(num => num % 2 !== 0);
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
multiplyByTwo(numbers) {
|
|
47
|
+
return numbers.map(num => num * 2);
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
containsNumber(numbers, target) {
|
|
51
|
+
return numbers.includes(target);
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
removeNumber(numbers, target) {
|
|
55
|
+
return numbers.filter(num => num !== target);
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
addNumber(numbers, newNumber) {
|
|
59
|
+
return [...numbers, newNumber];
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
getNumberAtIndex(numbers, index) {
|
|
63
|
+
if (index < 0 || index >= numbers.length) {
|
|
64
|
+
return undefined;
|
|
65
|
+
}
|
|
66
|
+
return numbers[index];
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
getLastNumber(numbers) {
|
|
70
|
+
return numbers.length > 0 ? numbers[numbers.length - 1] : undefined;
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
getFirstNumber(numbers) {
|
|
74
|
+
return numbers.length > 0 ? numbers[0] : undefined;
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
reverseNumbers(numbers) {
|
|
78
|
+
return [...numbers].reverse();
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
shuffleNumbers(numbers) {
|
|
82
|
+
const shuffled = [...numbers];
|
|
83
|
+
for (let i = shuffled.length - 1; i > 0; i--) {
|
|
84
|
+
const j = Math.floor(Math.random() * (i + 1));
|
|
85
|
+
const temp = shuffled[i];
|
|
86
|
+
shuffled[i] = shuffled[j];
|
|
87
|
+
shuffled[j] = temp;
|
|
88
|
+
}
|
|
89
|
+
return shuffled;
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
getUniqueNumbers(numbers) {
|
|
93
|
+
return [...new Set(numbers)];
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
getDuplicateNumbers(numbers) {
|
|
97
|
+
const seen = new Set();
|
|
98
|
+
const duplicates = new Set();
|
|
99
|
+
for (const num of numbers) {
|
|
100
|
+
if (seen.has(num)) {
|
|
101
|
+
duplicates.add(num);
|
|
102
|
+
} else {
|
|
103
|
+
seen.add(num);
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
return [...duplicates];
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
countOccurrences(numbers, target) {
|
|
110
|
+
return numbers.filter(num => num === target).length;
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
getNumbersInRange(numbers, min, max) {
|
|
114
|
+
return numbers.filter(num => num >= min && num <= max);
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
clearCache() {
|
|
118
|
+
this.cache.clear();
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
getCacheSize() {
|
|
122
|
+
return this.cache.size;
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
// This file has between 70-100 lines and should trigger a max-lines warning
|
|
127
|
+
export default ExtendedNumberUtils;
|
|
@@ -0,0 +1,144 @@
|
|
|
1
|
+
// Invalid: TypeScript file with way more than 100 lines (should trigger max-lines error)
|
|
2
|
+
interface User { id: number; name: string; email: string; }
|
|
3
|
+
interface Product { id: number; title: string; price: number; }
|
|
4
|
+
interface Order { id: number; userId: number; products: Product[]; }
|
|
5
|
+
|
|
6
|
+
const user1: User = { id: 1, name: 'John', email: 'john@example.com' };
|
|
7
|
+
const user2: User = { id: 2, name: 'Jane', email: 'jane@example.com' };
|
|
8
|
+
const user3: User = { id: 3, name: 'Bob', email: 'bob@example.com' };
|
|
9
|
+
const user4: User = { id: 4, name: 'Alice', email: 'alice@example.com' };
|
|
10
|
+
const user5: User = { id: 5, name: 'Charlie', email: 'charlie@example.com' };
|
|
11
|
+
const user6: User = { id: 6, name: 'Diana', email: 'diana@example.com' };
|
|
12
|
+
const user7: User = { id: 7, name: 'Eve', email: 'eve@example.com' };
|
|
13
|
+
const user8: User = { id: 8, name: 'Frank', email: 'frank@example.com' };
|
|
14
|
+
const user9: User = { id: 9, name: 'Grace', email: 'grace@example.com' };
|
|
15
|
+
const user10: User = { id: 10, name: 'Henry', email: 'henry@example.com' };
|
|
16
|
+
|
|
17
|
+
const product1: Product = { id: 1, title: 'Laptop', price: 999 };
|
|
18
|
+
const product2: Product = { id: 2, title: 'Mouse', price: 25 };
|
|
19
|
+
const product3: Product = { id: 3, title: 'Keyboard', price: 75 };
|
|
20
|
+
const product4: Product = { id: 4, title: 'Monitor', price: 300 };
|
|
21
|
+
const product5: Product = { id: 5, title: 'Headphones', price: 150 };
|
|
22
|
+
const product6: Product = { id: 6, title: 'Webcam', price: 80 };
|
|
23
|
+
const product7: Product = { id: 7, title: 'Speakers', price: 120 };
|
|
24
|
+
const product8: Product = { id: 8, title: 'Microphone', price: 200 };
|
|
25
|
+
const product9: Product = { id: 9, title: 'Tablet', price: 500 };
|
|
26
|
+
const product10: Product = { id: 10, title: 'Phone', price: 700 };
|
|
27
|
+
const product11: Product = { id: 11, title: 'Charger', price: 30 };
|
|
28
|
+
const product12: Product = { id: 12, title: 'Cable', price: 15 };
|
|
29
|
+
const product13: Product = { id: 13, title: 'Case', price: 40 };
|
|
30
|
+
const product14: Product = { id: 14, title: 'Stand', price: 60 };
|
|
31
|
+
const product15: Product = { id: 15, title: 'Bag', price: 90 };
|
|
32
|
+
|
|
33
|
+
const order1: Order = { id: 1, userId: 1, products: [product1, product2] };
|
|
34
|
+
const order2: Order = { id: 2, userId: 2, products: [product3] };
|
|
35
|
+
const order3: Order = { id: 3, userId: 3, products: [product4, product5, product6] };
|
|
36
|
+
const order4: Order = { id: 4, userId: 4, products: [product7, product8] };
|
|
37
|
+
const order5: Order = { id: 5, userId: 5, products: [product9] };
|
|
38
|
+
const order6: Order = { id: 6, userId: 6, products: [product10, product11] };
|
|
39
|
+
const order7: Order = { id: 7, userId: 7, products: [product12, product13, product14] };
|
|
40
|
+
const order8: Order = { id: 8, userId: 8, products: [product15] };
|
|
41
|
+
const order9: Order = { id: 9, userId: 9, products: [product1, product3, product5] };
|
|
42
|
+
const order10: Order = { id: 10, userId: 10, products: [product2, product4] };
|
|
43
|
+
|
|
44
|
+
export class OrderManagementService {
|
|
45
|
+
private users = [user1, user2, user3, user4, user5, user6, user7, user8, user9, user10];
|
|
46
|
+
private products = [product1, product2, product3, product4, product5, product6, product7, product8, product9, product10, product11, product12, product13, product14, product15];
|
|
47
|
+
private orders = [order1, order2, order3, order4, order5, order6, order7, order8, order9, order10];
|
|
48
|
+
|
|
49
|
+
getUserById(id: number): User | undefined {
|
|
50
|
+
return this.users.find(user => user.id === id);
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
getProductById(id: number): Product | undefined {
|
|
54
|
+
return this.products.find(product => product.id === id);
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
getOrderById(id: number): Order | undefined {
|
|
58
|
+
return this.orders.find(order => order.id === id);
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
getUserOrders(userId: number): Order[] {
|
|
62
|
+
return this.orders.filter(order => order.userId === userId);
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
calculateOrderTotal(order: Order): number {
|
|
66
|
+
return order.products.reduce((total, product) => total + product.price, 0);
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
getExpensiveProducts(minPrice: number): Product[] {
|
|
70
|
+
return this.products.filter(product => product.price >= minPrice);
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
getCheapProducts(maxPrice: number): Product[] {
|
|
74
|
+
return this.products.filter(product => product.price <= maxPrice);
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
searchProductsByTitle(query: string): Product[] {
|
|
78
|
+
return this.products.filter(product => product.title.toLowerCase().includes(query.toLowerCase()));
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
getUsersWithOrders(): User[] {
|
|
82
|
+
const userIdsWithOrders = new Set(this.orders.map(order => order.userId));
|
|
83
|
+
return this.users.filter(user => userIdsWithOrders.has(user.id));
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
getMostExpensiveOrder(): Order | undefined {
|
|
87
|
+
let maxOrder: Order | undefined;
|
|
88
|
+
let maxTotal = 0;
|
|
89
|
+
|
|
90
|
+
for (const order of this.orders) {
|
|
91
|
+
const total = this.calculateOrderTotal(order);
|
|
92
|
+
if (total > maxTotal) {
|
|
93
|
+
maxTotal = total;
|
|
94
|
+
maxOrder = order;
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
return maxOrder;
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
getOrdersByPriceRange(minPrice: number, maxPrice: number): Order[] {
|
|
102
|
+
return this.orders.filter(order => {
|
|
103
|
+
const total = this.calculateOrderTotal(order);
|
|
104
|
+
return total >= minPrice && total <= maxPrice;
|
|
105
|
+
});
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
getPopularProducts(): Product[] {
|
|
109
|
+
const productCount = new Map<number, number>();
|
|
110
|
+
|
|
111
|
+
for (const order of this.orders) {
|
|
112
|
+
for (const product of order.products) {
|
|
113
|
+
productCount.set(product.id, (productCount.get(product.id) || 0) + 1);
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
return this.products.filter(product => (productCount.get(product.id) || 0) > 1).sort((a, b) => (productCount.get(b.id) || 0) - (productCount.get(a.id) || 0));
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
getAverageOrderValue(): number {
|
|
121
|
+
const totalValue = this.orders.reduce((sum, order) => sum + this.calculateOrderTotal(order), 0);
|
|
122
|
+
return totalValue / this.orders.length;
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
getUserSpending(userId: number): number {
|
|
126
|
+
const userOrders = this.getUserOrders(userId);
|
|
127
|
+
return userOrders.reduce((total, order) => total + this.calculateOrderTotal(order), 0);
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
getTopSpendingUsers(limit: number = 5): Array<{ user: User; totalSpent: number }> {
|
|
131
|
+
const userSpending = this.users.map(user => ({
|
|
132
|
+
user,
|
|
133
|
+
totalSpent: this.getUserSpending(user.id)
|
|
134
|
+
}));
|
|
135
|
+
|
|
136
|
+
return userSpending.sort((a, b) => b.totalSpent - a.totalSpent).slice(0, limit);
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
const data1 = 'extra'; const data2 = 'data'; const data3 = 'to'; const data4 = 'make'; const data5 = 'file';
|
|
141
|
+
const data6 = 'longer'; const data7 = 'than'; const data8 = '100'; const data9 = 'lines'; const data10 = 'for';
|
|
142
|
+
const data11 = 'testing'; const data12 = 'max'; const data13 = 'lines'; const data14 = 'rule'; const data15 = 'error';
|
|
143
|
+
|
|
144
|
+
// This file has way more than 100 lines and should trigger a max-lines error
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
// Valid: Short file under 70 lines (no warnings or errors)
|
|
2
|
+
// This file demonstrates proper file length management
|
|
3
|
+
|
|
4
|
+
export class NumberUtils {
|
|
5
|
+
static calculateSum(numbers) {
|
|
6
|
+
return numbers.reduce((sum, num) => sum + num, 0);
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
static calculateAverage(numbers) {
|
|
10
|
+
if (numbers.length === 0) return 0;
|
|
11
|
+
return this.calculateSum(numbers) / numbers.length;
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
static findMaxValue(numbers) {
|
|
15
|
+
if (numbers.length === 0) return null;
|
|
16
|
+
return Math.max(...numbers);
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
static findMinValue(numbers) {
|
|
20
|
+
if (numbers.length === 0) return null;
|
|
21
|
+
return Math.min(...numbers);
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
static sortNumbers(numbers) {
|
|
25
|
+
return [...numbers].sort((a, b) => a - b);
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
static filterEvenNumbers(numbers) {
|
|
29
|
+
return numbers.filter((num) => num % 2 === 0);
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
static filterOddNumbers(numbers) {
|
|
33
|
+
return numbers.filter((num) => num % 2 !== 0);
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
static multiplyByTwo(numbers) {
|
|
37
|
+
return numbers.map((num) => num * 2);
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
static containsNumber(numbers, target) {
|
|
41
|
+
return numbers.includes(target);
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
static removeNumber(numbers, target) {
|
|
45
|
+
return numbers.filter((num) => num !== target);
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
static addNumber(numbers, newNumber) {
|
|
49
|
+
return [...numbers, newNumber];
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
static getUniqueNumbers(numbers) {
|
|
53
|
+
return [...new Set(numbers)];
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
static reverseNumbers(numbers) {
|
|
57
|
+
return [...numbers].reverse();
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
static getNumbersInRange(numbers, min, max) {
|
|
61
|
+
return numbers.filter((num) => num >= min && num <= max);
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
// This file has less than 70 lines and should not trigger any max-lines warnings or errors
|
|
66
|
+
export default NumberUtils;
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
// Valid: Spec file that ignores max-lines rule regardless of length
|
|
2
|
+
describe('Long spec file test', () => {
|
|
3
|
+
const testData1 = 'data1'; const testData2 = 'data2'; const testData3 = 'data3';
|
|
4
|
+
const testData4 = 'data4'; const testData5 = 'data5'; const testData6 = 'data6';
|
|
5
|
+
const testData7 = 'data7'; const testData8 = 'data8'; const testData9 = 'data9';
|
|
6
|
+
const testData10 = 'data10'; const testData11 = 'data11'; const testData12 = 'data12';
|
|
7
|
+
const testData13 = 'data13'; const testData14 = 'data14'; const testData15 = 'data15';
|
|
8
|
+
const testData16 = 'data16'; const testData17 = 'data17'; const testData18 = 'data18';
|
|
9
|
+
const testData19 = 'data19'; const testData20 = 'data20'; const testData21 = 'data21';
|
|
10
|
+
const testData22 = 'data22'; const testData23 = 'data23'; const testData24 = 'data24';
|
|
11
|
+
const testData25 = 'data25'; const testData26 = 'data26'; const testData27 = 'data27';
|
|
12
|
+
const testData28 = 'data28'; const testData29 = 'data29'; const testData30 = 'data30';
|
|
13
|
+
const testData31 = 'data31'; const testData32 = 'data32'; const testData33 = 'data33';
|
|
14
|
+
const testData34 = 'data34'; const testData35 = 'data35'; const testData36 = 'data36';
|
|
15
|
+
const testData37 = 'data37'; const testData38 = 'data38'; const testData39 = 'data39';
|
|
16
|
+
const testData40 = 'data40'; const testData41 = 'data41'; const testData42 = 'data42';
|
|
17
|
+
const testData43 = 'data43'; const testData44 = 'data44'; const testData45 = 'data45';
|
|
18
|
+
const testData46 = 'data46'; const testData47 = 'data47'; const testData48 = 'data48';
|
|
19
|
+
const testData49 = 'data49'; const testData50 = 'data50'; const testData51 = 'data51';
|
|
20
|
+
const testData52 = 'data52'; const testData53 = 'data53'; const testData54 = 'data54';
|
|
21
|
+
const testData55 = 'data55'; const testData56 = 'data56'; const testData57 = 'data57';
|
|
22
|
+
const testData58 = 'data58'; const testData59 = 'data59'; const testData60 = 'data60';
|
|
23
|
+
const testData61 = 'data61'; const testData62 = 'data62'; const testData63 = 'data63';
|
|
24
|
+
const testData64 = 'data64'; const testData65 = 'data65'; const testData66 = 'data66';
|
|
25
|
+
const testData67 = 'data67'; const testData68 = 'data68'; const testData69 = 'data69';
|
|
26
|
+
const testData70 = 'data70'; const testData71 = 'data71'; const testData72 = 'data72';
|
|
27
|
+
const testData73 = 'data73'; const testData74 = 'data74'; const testData75 = 'data75';
|
|
28
|
+
const testData76 = 'data76'; const testData77 = 'data77'; const testData78 = 'data78';
|
|
29
|
+
const testData79 = 'data79'; const testData80 = 'data80'; const testData81 = 'data81';
|
|
30
|
+
const testData82 = 'data82'; const testData83 = 'data83'; const testData84 = 'data84';
|
|
31
|
+
const testData85 = 'data85'; const testData86 = 'data86'; const testData87 = 'data87';
|
|
32
|
+
const testData88 = 'data88'; const testData89 = 'data89'; const testData90 = 'data90';
|
|
33
|
+
const testData91 = 'data91'; const testData92 = 'data92'; const testData93 = 'data93';
|
|
34
|
+
const testData94 = 'data94'; const testData95 = 'data95'; const testData96 = 'data96';
|
|
35
|
+
const testData97 = 'data97'; const testData98 = 'data98'; const testData99 = 'data99';
|
|
36
|
+
const testData100 = 'data100'; const testData101 = 'data101'; const testData102 = 'data102';
|
|
37
|
+
const testData103 = 'data103'; const testData104 = 'data104'; const testData105 = 'data105';
|
|
38
|
+
const testData106 = 'data106'; const testData107 = 'data107'; const testData108 = 'data108';
|
|
39
|
+
const testData109 = 'data109'; const testData110 = 'data110'; const testData111 = 'data111';
|
|
40
|
+
|
|
41
|
+
it('should handle long spec files without max-lines errors', () => {
|
|
42
|
+
expect(testData1).toBe('data1');
|
|
43
|
+
});
|
|
44
|
+
});
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
// Valid: Test file that ignores max-lines rule regardless of length
|
|
2
|
+
const line1 = 1; const line2 = 2; const line3 = 3; const line4 = 4; const line5 = 5;
|
|
3
|
+
const line6 = 6; const line7 = 7; const line8 = 8; const line9 = 9; const line10 = 10;
|
|
4
|
+
const line11 = 11; const line12 = 12; const line13 = 13; const line14 = 14; const line15 = 15;
|
|
5
|
+
const line16 = 16; const line17 = 17; const line18 = 18; const line19 = 19; const line20 = 20;
|
|
6
|
+
const line21 = 21; const line22 = 22; const line23 = 23; const line24 = 24; const line25 = 25;
|
|
7
|
+
const line26 = 26; const line27 = 27; const line28 = 28; const line29 = 29; const line30 = 30;
|
|
8
|
+
const line31 = 31; const line32 = 32; const line33 = 33; const line34 = 34; const line35 = 35;
|
|
9
|
+
const line36 = 36; const line37 = 37; const line38 = 38; const line39 = 39; const line40 = 40;
|
|
10
|
+
const line41 = 41; const line42 = 42; const line43 = 43; const line44 = 44; const line45 = 45;
|
|
11
|
+
const line46 = 46; const line47 = 47; const line48 = 48; const line49 = 49; const line50 = 50;
|
|
12
|
+
const line51 = 51; const line52 = 52; const line53 = 53; const line54 = 54; const line55 = 55;
|
|
13
|
+
const line56 = 56; const line57 = 57; const line58 = 58; const line59 = 59; const line60 = 60;
|
|
14
|
+
const line61 = 61; const line62 = 62; const line63 = 63; const line64 = 64; const line65 = 65;
|
|
15
|
+
const line66 = 66; const line67 = 67; const line68 = 68; const line69 = 69; const line70 = 70;
|
|
16
|
+
const line71 = 71; const line72 = 72; const line73 = 73; const line74 = 74; const line75 = 75;
|
|
17
|
+
const line76 = 76; const line77 = 77; const line78 = 78; const line79 = 79; const line80 = 80;
|
|
18
|
+
const line81 = 81; const line82 = 82; const line83 = 83; const line84 = 84; const line85 = 85;
|
|
19
|
+
const line86 = 86; const line87 = 87; const line88 = 88; const line89 = 89; const line90 = 90;
|
|
20
|
+
const line91 = 91; const line92 = 92; const line93 = 93; const line94 = 94; const line95 = 95;
|
|
21
|
+
const line96 = 96; const line97 = 97; const line98 = 98; const line99 = 99; const line100 = 100;
|
|
22
|
+
const line101 = 101; const line102 = 102; const line103 = 103; const line104 = 104; const line105 = 105;
|
|
23
|
+
const line106 = 106; const line107 = 107; const line108 = 108; const line109 = 109; const line110 = 110;
|
|
24
|
+
|
|
25
|
+
export default line1;
|
|
@@ -1,8 +1,12 @@
|
|
|
1
|
+
import { noUnusedModulesConfig } from "./no-unused-modules/index.js";
|
|
2
|
+
import { groupExportsConfig } from "./group-exports/index.js";
|
|
3
|
+
|
|
1
4
|
export const importRules = {
|
|
2
5
|
// Import/export organization and restrictions
|
|
3
|
-
|
|
6
|
+
...groupExportsConfig,
|
|
4
7
|
"import/no-default-export": "off", // Allow default exports
|
|
5
8
|
"import/no-namespace": "error",
|
|
9
|
+
...noUnusedModulesConfig,
|
|
6
10
|
// Disabled import rules (keep existing behavior)
|
|
7
11
|
"import/extensions": ["off"],
|
|
8
12
|
"import/no-extraneous-dependencies": ["off"],
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
// Valid: This module consumes exports from other modules
|
|
2
|
+
import { apiUrl } from './used-export.js';
|
|
3
|
+
import { fetchData } from './used-function.js';
|
|
4
|
+
import { DataProcessor } from './used-class.js';
|
|
5
|
+
|
|
6
|
+
const processor = new DataProcessor();
|
|
7
|
+
fetchData().then(data => processor.process(data));
|
|
8
|
+
console.log(`API URL: ${apiUrl}`);
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
// Note: import/no-unused-modules has compatibility issues with ESLint flat config
|
|
2
|
+
// It requires an .eslintrc file and has complex setup requirements
|
|
3
|
+
// For now, this rule is disabled to avoid configuration conflicts
|
|
4
|
+
export const noUnusedModulesConfig = {
|
|
5
|
+
// "import/no-unused-modules": "off", // Disabled due to flat config compatibility issues
|
|
6
|
+
};
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
// Valid: Using generics instead of any
|
|
2
|
+
export function identity<T>(value: T): T {
|
|
3
|
+
return value;
|
|
4
|
+
}
|
|
5
|
+
|
|
6
|
+
export class Container<T> {
|
|
7
|
+
private value: T;
|
|
8
|
+
|
|
9
|
+
constructor(value: T) {
|
|
10
|
+
this.value = value;
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
getValue(): T {
|
|
14
|
+
return this.value;
|
|
15
|
+
}
|
|
16
|
+
}
|