@danielsitek/eslint-stats 0.1.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/LICENSE +21 -0
- package/README.md +118 -0
- package/dist/formatters/by-error-and-warning-stacked.d.ts +4 -0
- package/dist/formatters/by-error-and-warning-stacked.d.ts.map +1 -0
- package/dist/formatters/by-error-and-warning-stacked.js +8 -0
- package/dist/formatters/by-error-and-warning-stacked.js.map +1 -0
- package/dist/formatters/by-error-and-warning.d.ts +4 -0
- package/dist/formatters/by-error-and-warning.d.ts.map +1 -0
- package/dist/formatters/by-error-and-warning.js +8 -0
- package/dist/formatters/by-error-and-warning.js.map +1 -0
- package/dist/formatters/by-error.d.ts +4 -0
- package/dist/formatters/by-error.d.ts.map +1 -0
- package/dist/formatters/by-error.js +8 -0
- package/dist/formatters/by-error.js.map +1 -0
- package/dist/formatters/by-folder.d.ts +4 -0
- package/dist/formatters/by-folder.d.ts.map +1 -0
- package/dist/formatters/by-folder.js +8 -0
- package/dist/formatters/by-folder.js.map +1 -0
- package/dist/formatters/by-warning.d.ts +4 -0
- package/dist/formatters/by-warning.d.ts.map +1 -0
- package/dist/formatters/by-warning.js +8 -0
- package/dist/formatters/by-warning.js.map +1 -0
- package/dist/index.d.ts +14 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +17 -0
- package/dist/index.js.map +1 -0
- package/dist/types/types.d.ts +15 -0
- package/dist/types/types.d.ts.map +1 -0
- package/dist/types/types.js +2 -0
- package/dist/types/types.js.map +1 -0
- package/dist/utils/bar.d.ts +2 -0
- package/dist/utils/bar.d.ts.map +1 -0
- package/dist/utils/bar.js +6 -0
- package/dist/utils/bar.js.map +1 -0
- package/dist/utils/chart.d.ts +5 -0
- package/dist/utils/chart.d.ts.map +1 -0
- package/dist/utils/chart.js +98 -0
- package/dist/utils/chart.js.map +1 -0
- package/dist/utils/colors.d.ts +10 -0
- package/dist/utils/colors.d.ts.map +1 -0
- package/dist/utils/colors.js +11 -0
- package/dist/utils/colors.js.map +1 -0
- package/dist/utils/severities.d.ts +4 -0
- package/dist/utils/severities.d.ts.map +1 -0
- package/dist/utils/severities.js +8 -0
- package/dist/utils/severities.js.map +1 -0
- package/dist/utils/stats.d.ts +4 -0
- package/dist/utils/stats.d.ts.map +1 -0
- package/dist/utils/stats.js +48 -0
- package/dist/utils/stats.js.map +1 -0
- package/package.json +105 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Daniel Sitek
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,118 @@
|
|
|
1
|
+

|
|
2
|
+
[](https://app.codacy.com/gh/danielsitek/eslint-stats/dashboard?utm_source=gh&utm_medium=referral&utm_content=&utm_campaign=Badge_grade)
|
|
3
|
+
[](https://app.codacy.com/gh/danielsitek/eslint-stats/dashboard?utm_source=gh&utm_medium=referral&utm_content=&utm_campaign=Badge_coverage)
|
|
4
|
+
[](https://qlty.sh/gh/danielsitek/projects/eslint-stats)
|
|
5
|
+
|
|
6
|
+
# Statistic Reporter for ESLint
|
|
7
|
+
|
|
8
|
+
Modern TypeScript formatters for ESLint with aggregated error and warning statistics. Analyzes files by error frequency rather than location, making it easier to prioritize fixes when introducing ESLint to existing projects.
|
|
9
|
+
|
|
10
|
+

|
|
11
|
+
|
|
12
|
+
## Features
|
|
13
|
+
|
|
14
|
+
- Multiple aggregation views (by error, warning, folder)
|
|
15
|
+
- Color-coded output with visual graphs
|
|
16
|
+
- ESLint 8 and 9 compatible
|
|
17
|
+
- Full TypeScript support with type definitions
|
|
18
|
+
- Zero runtime dependencies
|
|
19
|
+
- Modern Node.js (20+)
|
|
20
|
+
|
|
21
|
+
## Installation
|
|
22
|
+
|
|
23
|
+
```bash
|
|
24
|
+
npm install --save-dev @danielsitek/eslint-stats
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
## Usage
|
|
28
|
+
|
|
29
|
+
### With ESLint CLI
|
|
30
|
+
|
|
31
|
+
```bash
|
|
32
|
+
# Using specific formatters
|
|
33
|
+
eslint src/ -f ./node_modules/@danielsitek/eslint-stats/dist/formatters/by-error.js
|
|
34
|
+
eslint src/ -f ./node_modules/@danielsitek/eslint-stats/dist/formatters/by-error-and-warning.js
|
|
35
|
+
eslint src/ -f ./node_modules/@danielsitek/eslint-stats/dist/formatters/by-folder.js
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
### Programmatic Usage
|
|
39
|
+
|
|
40
|
+
```typescript
|
|
41
|
+
import {
|
|
42
|
+
byError,
|
|
43
|
+
byWarning,
|
|
44
|
+
byErrorAndWarning,
|
|
45
|
+
} from "@danielsitek/eslint-stats";
|
|
46
|
+
import { ESLint } from "eslint";
|
|
47
|
+
|
|
48
|
+
const eslint = new ESLint({
|
|
49
|
+
// your config
|
|
50
|
+
});
|
|
51
|
+
|
|
52
|
+
const results = await eslint.lintFiles(["src/**/*.ts"]);
|
|
53
|
+
const formatter = await eslint.loadFormatter(byError);
|
|
54
|
+
|
|
55
|
+
console.log(formatter.format(results));
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
## Available Formatters
|
|
59
|
+
|
|
60
|
+
### by-error
|
|
61
|
+
|
|
62
|
+
Displays aggregated error statistics without file separation. Only shows rules with errors; warnings are not displayed.
|
|
63
|
+
|
|
64
|
+
### by-warning
|
|
65
|
+
|
|
66
|
+
Displays aggregated warning statistics without file separation. Only shows rules with warnings; errors are not displayed.
|
|
67
|
+
|
|
68
|
+
### by-error-and-warning
|
|
69
|
+
|
|
70
|
+
Displays aggregated statistics for both errors and warnings without file separation. Errors are shown in red, warnings in yellow.
|
|
71
|
+
|
|
72
|
+
### by-error-and-warning-stacked
|
|
73
|
+
|
|
74
|
+
Similar to by-error-and-warning but displays errors and warnings stacked together when a rule has both severities across different files.
|
|
75
|
+
|
|
76
|
+
### by-folder
|
|
77
|
+
|
|
78
|
+
Displays aggregated statistics grouped by folder. Errors are shown in red, warnings in yellow.
|
|
79
|
+
|
|
80
|
+
## Demo
|
|
81
|
+
|
|
82
|
+
The package includes demo scripts for testing formatters:
|
|
83
|
+
|
|
84
|
+
```bash
|
|
85
|
+
npm run demo:error
|
|
86
|
+
npm run demo:warning
|
|
87
|
+
npm run demo:both
|
|
88
|
+
npm run demo:stacked
|
|
89
|
+
npm run demo:folder
|
|
90
|
+
```
|
|
91
|
+
|
|
92
|
+
## Requirements
|
|
93
|
+
|
|
94
|
+
- Node.js >= 20.0.0
|
|
95
|
+
- ESLint >= 8.0.0
|
|
96
|
+
|
|
97
|
+
## Migration from `ganimomer/eslint-stats` v1.x
|
|
98
|
+
|
|
99
|
+
If you're upgrading from the original `eslint-stats` package:
|
|
100
|
+
|
|
101
|
+
1. Update package name:
|
|
102
|
+
|
|
103
|
+
```bash
|
|
104
|
+
npm uninstall eslint-stats
|
|
105
|
+
npm install --save-dev @danielsitek/eslint-stats
|
|
106
|
+
```
|
|
107
|
+
|
|
108
|
+
2. Update formatter paths in your ESLint configuration or CLI commands to use the new scoped package name.
|
|
109
|
+
|
|
110
|
+
3. For programmatic usage, update imports to use the scoped package name.
|
|
111
|
+
|
|
112
|
+
## Credits
|
|
113
|
+
|
|
114
|
+
Modernized fork of [eslint-stats](https://github.com/ganimomer/eslint-stats) by [Omer Ganim](https://github.com/ganimomer).
|
|
115
|
+
|
|
116
|
+
## License
|
|
117
|
+
|
|
118
|
+
MIT
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"by-error-and-warning-stacked.d.ts","sourceRoot":"","sources":["../../src/formatters/by-error-and-warning-stacked.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAC;AAIpD,eAAO,MAAM,wBAAwB,GAAI,SAAS,UAAU,EAAE,KAAG,MAGhE,CAAC;AAEF,eAAe,wBAAwB,CAAC"}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { byRule } from "../utils/stats.js";
|
|
2
|
+
import { getStackedOutput } from "../utils/chart.js";
|
|
3
|
+
export const byErrorAndWarningStacked = (results) => {
|
|
4
|
+
const obj = byRule(results);
|
|
5
|
+
return getStackedOutput(obj, process.stdout.columns || 80);
|
|
6
|
+
};
|
|
7
|
+
export default byErrorAndWarningStacked;
|
|
8
|
+
//# sourceMappingURL=by-error-and-warning-stacked.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"by-error-and-warning-stacked.js","sourceRoot":"","sources":["../../src/formatters/by-error-and-warning-stacked.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,MAAM,EAAE,MAAM,mBAAmB,CAAC;AAC3C,OAAO,EAAE,gBAAgB,EAAE,MAAM,mBAAmB,CAAC;AAErD,MAAM,CAAC,MAAM,wBAAwB,GAAG,CAAC,OAAqB,EAAU,EAAE;IACxE,MAAM,GAAG,GAAG,MAAM,CAAC,OAAO,CAAC,CAAC;IAC5B,OAAO,gBAAgB,CAAC,GAAG,EAAE,OAAO,CAAC,MAAM,CAAC,OAAO,IAAI,EAAE,CAAC,CAAC;AAC7D,CAAC,CAAC;AAEF,eAAe,wBAAwB,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"by-error-and-warning.d.ts","sourceRoot":"","sources":["../../src/formatters/by-error-and-warning.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAC;AAIpD,eAAO,MAAM,iBAAiB,GAAI,SAAS,UAAU,EAAE,KAAG,MAGzD,CAAC;AAEF,eAAe,iBAAiB,CAAC"}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { byRule } from "../utils/stats.js";
|
|
2
|
+
import { getObjectOutput } from "../utils/chart.js";
|
|
3
|
+
export const byErrorAndWarning = (results) => {
|
|
4
|
+
const obj = byRule(results);
|
|
5
|
+
return getObjectOutput(obj, process.stdout.columns || 80);
|
|
6
|
+
};
|
|
7
|
+
export default byErrorAndWarning;
|
|
8
|
+
//# sourceMappingURL=by-error-and-warning.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"by-error-and-warning.js","sourceRoot":"","sources":["../../src/formatters/by-error-and-warning.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,MAAM,EAAE,MAAM,mBAAmB,CAAC;AAC3C,OAAO,EAAE,eAAe,EAAE,MAAM,mBAAmB,CAAC;AAEpD,MAAM,CAAC,MAAM,iBAAiB,GAAG,CAAC,OAAqB,EAAU,EAAE;IACjE,MAAM,GAAG,GAAG,MAAM,CAAC,OAAO,CAAC,CAAC;IAC5B,OAAO,eAAe,CAAC,GAAG,EAAE,OAAO,CAAC,MAAM,CAAC,OAAO,IAAI,EAAE,CAAC,CAAC;AAC5D,CAAC,CAAC;AAEF,eAAe,iBAAiB,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"by-error.d.ts","sourceRoot":"","sources":["../../src/formatters/by-error.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAC;AAIpD,eAAO,MAAM,OAAO,GAAI,SAAS,UAAU,EAAE,KAAG,MAG/C,CAAC;AAEF,eAAe,OAAO,CAAC"}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { byRule } from "../utils/stats.js";
|
|
2
|
+
import { getObjectOutput } from "../utils/chart.js";
|
|
3
|
+
export const byError = (results) => {
|
|
4
|
+
const errorObj = byRule(results, 2);
|
|
5
|
+
return getObjectOutput(errorObj, process.stdout.columns || 80);
|
|
6
|
+
};
|
|
7
|
+
export default byError;
|
|
8
|
+
//# sourceMappingURL=by-error.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"by-error.js","sourceRoot":"","sources":["../../src/formatters/by-error.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,MAAM,EAAE,MAAM,mBAAmB,CAAC;AAC3C,OAAO,EAAE,eAAe,EAAE,MAAM,mBAAmB,CAAC;AAEpD,MAAM,CAAC,MAAM,OAAO,GAAG,CAAC,OAAqB,EAAU,EAAE;IACvD,MAAM,QAAQ,GAAG,MAAM,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC;IACpC,OAAO,eAAe,CAAC,QAAQ,EAAE,OAAO,CAAC,MAAM,CAAC,OAAO,IAAI,EAAE,CAAC,CAAC;AACjE,CAAC,CAAC;AAEF,eAAe,OAAO,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"by-folder.d.ts","sourceRoot":"","sources":["../../src/formatters/by-folder.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAC;AAIpD,eAAO,MAAM,QAAQ,GAAI,SAAS,UAAU,EAAE,KAAG,MAGhD,CAAC;AAEF,eAAe,QAAQ,CAAC"}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { byFolderAndRule } from "../utils/stats.js";
|
|
2
|
+
import { getOutputByFolder } from "../utils/chart.js";
|
|
3
|
+
export const byFolder = (results) => {
|
|
4
|
+
const obj = byFolderAndRule(results);
|
|
5
|
+
return getOutputByFolder(obj, process.stdout.columns || 80);
|
|
6
|
+
};
|
|
7
|
+
export default byFolder;
|
|
8
|
+
//# sourceMappingURL=by-folder.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"by-folder.js","sourceRoot":"","sources":["../../src/formatters/by-folder.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,eAAe,EAAE,MAAM,mBAAmB,CAAC;AACpD,OAAO,EAAE,iBAAiB,EAAE,MAAM,mBAAmB,CAAC;AAEtD,MAAM,CAAC,MAAM,QAAQ,GAAG,CAAC,OAAqB,EAAU,EAAE;IACxD,MAAM,GAAG,GAAG,eAAe,CAAC,OAAO,CAAC,CAAC;IACrC,OAAO,iBAAiB,CAAC,GAAG,EAAE,OAAO,CAAC,MAAM,CAAC,OAAO,IAAI,EAAE,CAAC,CAAC;AAC9D,CAAC,CAAC;AAEF,eAAe,QAAQ,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"by-warning.d.ts","sourceRoot":"","sources":["../../src/formatters/by-warning.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAC;AAIpD,eAAO,MAAM,SAAS,GAAI,SAAS,UAAU,EAAE,KAAG,MAGjD,CAAC;AAEF,eAAe,SAAS,CAAC"}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { byRule } from "../utils/stats.js";
|
|
2
|
+
import { getObjectOutput } from "../utils/chart.js";
|
|
3
|
+
export const byWarning = (results) => {
|
|
4
|
+
const warningObj = byRule(results, 1);
|
|
5
|
+
return getObjectOutput(warningObj, process.stdout.columns || 80);
|
|
6
|
+
};
|
|
7
|
+
export default byWarning;
|
|
8
|
+
//# sourceMappingURL=by-warning.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"by-warning.js","sourceRoot":"","sources":["../../src/formatters/by-warning.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,MAAM,EAAE,MAAM,mBAAmB,CAAC;AAC3C,OAAO,EAAE,eAAe,EAAE,MAAM,mBAAmB,CAAC;AAEpD,MAAM,CAAC,MAAM,SAAS,GAAG,CAAC,OAAqB,EAAU,EAAE;IACzD,MAAM,UAAU,GAAG,MAAM,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC;IACtC,OAAO,eAAe,CAAC,UAAU,EAAE,OAAO,CAAC,MAAM,CAAC,OAAO,IAAI,EAAE,CAAC,CAAC;AACnE,CAAC,CAAC;AAEF,eAAe,SAAS,CAAC"}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
export declare const byError: string;
|
|
2
|
+
export declare const byWarning: string;
|
|
3
|
+
export declare const byErrorAndWarning: string;
|
|
4
|
+
export declare const byErrorAndWarningStacked: string;
|
|
5
|
+
export declare const byFolder: string;
|
|
6
|
+
declare const _default: {
|
|
7
|
+
byError: string;
|
|
8
|
+
byWarning: string;
|
|
9
|
+
byErrorAndWarning: string;
|
|
10
|
+
byErrorAndWarningStacked: string;
|
|
11
|
+
byFolder: string;
|
|
12
|
+
};
|
|
13
|
+
export default _default;
|
|
14
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAYA,eAAO,MAAM,OAAO,QAA+B,CAAC;AACpD,eAAO,MAAM,SAAS,QAAiC,CAAC;AACxD,eAAO,MAAM,iBAAiB,QAA2C,CAAC;AAC1E,eAAO,MAAM,wBAAwB,QAEpC,CAAC;AACF,eAAO,MAAM,QAAQ,QAAgC,CAAC;;;;;;;;AAEtD,wBAME"}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { dirname, join } from "node:path";
|
|
2
|
+
const getFormatterPath = (formatter) => {
|
|
3
|
+
return join(dirname(new URL(import.meta.url).pathname), "formatters", `${formatter}.js`);
|
|
4
|
+
};
|
|
5
|
+
export const byError = getFormatterPath("by-error");
|
|
6
|
+
export const byWarning = getFormatterPath("by-warning");
|
|
7
|
+
export const byErrorAndWarning = getFormatterPath("by-error-and-warning");
|
|
8
|
+
export const byErrorAndWarningStacked = getFormatterPath("by-error-and-warning-stacked");
|
|
9
|
+
export const byFolder = getFormatterPath("by-folder");
|
|
10
|
+
export default {
|
|
11
|
+
byError,
|
|
12
|
+
byWarning,
|
|
13
|
+
byErrorAndWarning,
|
|
14
|
+
byErrorAndWarningStacked,
|
|
15
|
+
byFolder,
|
|
16
|
+
};
|
|
17
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAG1C,MAAM,gBAAgB,GAAG,CAAC,SAAiB,EAAU,EAAE;IAErD,OAAO,IAAI,CACT,OAAO,CAAC,IAAI,GAAG,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,QAAQ,CAAC,EAC1C,YAAY,EACZ,GAAG,SAAS,KAAK,CAClB,CAAC;AACJ,CAAC,CAAC;AAEF,MAAM,CAAC,MAAM,OAAO,GAAG,gBAAgB,CAAC,UAAU,CAAC,CAAC;AACpD,MAAM,CAAC,MAAM,SAAS,GAAG,gBAAgB,CAAC,YAAY,CAAC,CAAC;AACxD,MAAM,CAAC,MAAM,iBAAiB,GAAG,gBAAgB,CAAC,sBAAsB,CAAC,CAAC;AAC1E,MAAM,CAAC,MAAM,wBAAwB,GAAG,gBAAgB,CACtD,8BAA8B,CAC/B,CAAC;AACF,MAAM,CAAC,MAAM,QAAQ,GAAG,gBAAgB,CAAC,WAAW,CAAC,CAAC;AAEtD,eAAe;IACb,OAAO;IACP,SAAS;IACT,iBAAiB;IACjB,wBAAwB;IACxB,QAAQ;CACT,CAAC"}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import type { ESLint, Linter } from "eslint";
|
|
2
|
+
export type LintResult = ESLint.LintResult;
|
|
3
|
+
export type LintMessage = Linter.LintMessage;
|
|
4
|
+
export type Formatter = ESLint.Formatter["format"];
|
|
5
|
+
export interface SeverityStats {
|
|
6
|
+
Error?: number;
|
|
7
|
+
Warning?: number;
|
|
8
|
+
}
|
|
9
|
+
export type RuleStats = Record<string, SeverityStats>;
|
|
10
|
+
export type FolderStats = Record<string, RuleStats>;
|
|
11
|
+
export type SeverityLevel = 0 | 1 | 2;
|
|
12
|
+
export interface SeverityMap {
|
|
13
|
+
names: Record<number, "Warning" | "Error">;
|
|
14
|
+
}
|
|
15
|
+
//# sourceMappingURL=types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/types/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAC;AAE7C,MAAM,MAAM,UAAU,GAAG,MAAM,CAAC,UAAU,CAAC;AAC3C,MAAM,MAAM,WAAW,GAAG,MAAM,CAAC,WAAW,CAAC;AAC7C,MAAM,MAAM,SAAS,GAAG,MAAM,CAAC,SAAS,CAAC,QAAQ,CAAC,CAAC;AAEnD,MAAM,WAAW,aAAa;IAC5B,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED,MAAM,MAAM,SAAS,GAAG,MAAM,CAAC,MAAM,EAAE,aAAa,CAAC,CAAC;AAEtD,MAAM,MAAM,WAAW,GAAG,MAAM,CAAC,MAAM,EAAE,SAAS,CAAC,CAAC;AAEpD,MAAM,MAAM,aAAa,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;AAEtC,MAAM,WAAW,WAAW;IAC1B,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,SAAS,GAAG,OAAO,CAAC,CAAC;CAC5C"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/types/types.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"bar.d.ts","sourceRoot":"","sources":["../../src/utils/bar.ts"],"names":[],"mappings":"AAEA,eAAO,MAAM,SAAS,GAAI,QAAQ,MAAM,EAAE,OAAO,KAAK,GAAG,QAAQ,KAAG,MAInE,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"bar.js","sourceRoot":"","sources":["../../src/utils/bar.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC;AAE9C,MAAM,CAAC,MAAM,SAAS,GAAG,CAAC,MAAc,EAAE,KAAuB,EAAU,EAAE;IAC3E,MAAM,OAAO,GAAG,KAAK,KAAK,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,QAAQ,CAAC;IAEnD,OAAO,OAAO,CAAC,GAAG,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC;AACrC,CAAC,CAAC"}
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import type { RuleStats, FolderStats } from "../types/types.js";
|
|
2
|
+
export declare function getObjectOutput(stats: RuleStats, maxWidth: number): string;
|
|
3
|
+
export declare function getStackedOutput(stats: RuleStats, maxWidth: number): string;
|
|
4
|
+
export declare function getOutputByFolder(stats: FolderStats, maxWidth: number): string;
|
|
5
|
+
//# sourceMappingURL=chart.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"chart.d.ts","sourceRoot":"","sources":["../../src/utils/chart.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,SAAS,EAAE,WAAW,EAAiB,MAAM,mBAAmB,CAAC;AAiC/E,wBAAgB,eAAe,CAAC,KAAK,EAAE,SAAS,EAAE,QAAQ,EAAE,MAAM,GAAG,MAAM,CAyC1E;AAQD,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,SAAS,EAAE,QAAQ,EAAE,MAAM,GAAG,MAAM,CAmE3E;AAOD,wBAAgB,iBAAiB,CAC/B,KAAK,EAAE,WAAW,EAClB,QAAQ,EAAE,MAAM,GACf,MAAM,CAUR"}
|
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
import { magenta, underline } from "./colors.js";
|
|
2
|
+
import { getString } from "./bar.js";
|
|
3
|
+
const barColors = {
|
|
4
|
+
Error: "red",
|
|
5
|
+
Warning: "yellow",
|
|
6
|
+
};
|
|
7
|
+
const allSeverities = ["Error", "Warning"];
|
|
8
|
+
function getMaxRuleLength(stats) {
|
|
9
|
+
return Math.max(...Object.keys(stats).map((key) => key.length));
|
|
10
|
+
}
|
|
11
|
+
function getStringLength(num) {
|
|
12
|
+
return String(num).length;
|
|
13
|
+
}
|
|
14
|
+
const getBarRatio = (usedColumns, maxResult, maxWidth) => {
|
|
15
|
+
const maxBarLength = maxWidth - usedColumns;
|
|
16
|
+
return maxResult <= maxBarLength ? 1 : maxBarLength / maxResult;
|
|
17
|
+
};
|
|
18
|
+
const sortByKey = (obj) => {
|
|
19
|
+
return Object.entries(obj)
|
|
20
|
+
.sort(([a], [b]) => a.localeCompare(b))
|
|
21
|
+
.map(([, value]) => value);
|
|
22
|
+
};
|
|
23
|
+
export function getObjectOutput(stats, maxWidth) {
|
|
24
|
+
const maxRuleLength = getMaxRuleLength(stats);
|
|
25
|
+
const maxResult = Math.max(...Object.values(stats).flatMap((ruleStats) => [
|
|
26
|
+
ruleStats.Error ?? 0,
|
|
27
|
+
ruleStats.Warning ?? 0,
|
|
28
|
+
]));
|
|
29
|
+
const maxResultLength = String(maxResult).length;
|
|
30
|
+
const barRatio = getBarRatio(maxRuleLength + maxResultLength + 3, maxResult, maxWidth);
|
|
31
|
+
const getRuleOutput = (ruleStats, ruleName) => {
|
|
32
|
+
const ruleCell = `${ruleName}: `.padEnd(maxRuleLength + 2);
|
|
33
|
+
return Object.entries(ruleStats)
|
|
34
|
+
.map(([severity, count]) => {
|
|
35
|
+
const countCell = magenta(String(count).padStart(maxResultLength));
|
|
36
|
+
const barCell = getString(Math.floor(barRatio * count), barColors[severity]);
|
|
37
|
+
return `${ruleCell}${countCell}|${barCell}`;
|
|
38
|
+
})
|
|
39
|
+
.join("\n");
|
|
40
|
+
};
|
|
41
|
+
const mappedStats = Object.fromEntries(Object.entries(stats).map(([ruleName, ruleStats]) => [
|
|
42
|
+
ruleName,
|
|
43
|
+
getRuleOutput(ruleStats, ruleName),
|
|
44
|
+
]));
|
|
45
|
+
return `${sortByKey(mappedStats).join("\n")}\n`;
|
|
46
|
+
}
|
|
47
|
+
function isAnyRuleStacked(stats) {
|
|
48
|
+
return Object.values(stats).some((ruleData) => Object.keys(ruleData).length > 1);
|
|
49
|
+
}
|
|
50
|
+
export function getStackedOutput(stats, maxWidth) {
|
|
51
|
+
if (!isAnyRuleStacked(stats)) {
|
|
52
|
+
return getObjectOutput(stats, maxWidth);
|
|
53
|
+
}
|
|
54
|
+
const normalizedStats = Object.fromEntries(Object.entries(stats).map(([key, value]) => [
|
|
55
|
+
key,
|
|
56
|
+
{ Error: 0, Warning: 0, ...value },
|
|
57
|
+
]));
|
|
58
|
+
const maxRuleLength = getMaxRuleLength(normalizedStats);
|
|
59
|
+
const maxResults = {};
|
|
60
|
+
for (const severity of allSeverities) {
|
|
61
|
+
maxResults[severity] = Math.max(...Object.values(stats).map((s) => {
|
|
62
|
+
const val = severity === "Error" ? s.Error : s.Warning;
|
|
63
|
+
return val ?? 0;
|
|
64
|
+
}));
|
|
65
|
+
}
|
|
66
|
+
const maxResultLengths = Object.fromEntries(Object.entries(maxResults).map(([key, value]) => [
|
|
67
|
+
key,
|
|
68
|
+
getStringLength(value),
|
|
69
|
+
]));
|
|
70
|
+
const maxRuleSum = Math.max(...Object.values(normalizedStats).map((x) => x.Error + x.Warning));
|
|
71
|
+
const barRatio = getBarRatio(maxRuleLength +
|
|
72
|
+
Object.values(maxResultLengths).reduce((a, b) => a + b, 0) +
|
|
73
|
+
4, maxRuleSum, maxWidth);
|
|
74
|
+
const getStackedBar = (ruleStats) => {
|
|
75
|
+
return (getString(Math.floor(barRatio * ruleStats.Error), barColors.Error) +
|
|
76
|
+
getString(Math.floor(barRatio * ruleStats.Warning), barColors.Warning));
|
|
77
|
+
};
|
|
78
|
+
return `${Object.entries(normalizedStats)
|
|
79
|
+
.map(([ruleId, ruleStats]) => {
|
|
80
|
+
const ruleCell = `${ruleId}: `.padEnd(maxRuleLength + 2);
|
|
81
|
+
const errorLength = maxResultLengths.Error ?? 0;
|
|
82
|
+
const warningLength = maxResultLengths.Warning ?? 0;
|
|
83
|
+
const errorCountCell = String(ruleStats.Error).padStart(errorLength);
|
|
84
|
+
const warningCountCell = String(ruleStats.Warning).padStart(warningLength);
|
|
85
|
+
const countCell = magenta(`${errorCountCell},${warningCountCell}`);
|
|
86
|
+
const barCell = getStackedBar(ruleStats);
|
|
87
|
+
return `${ruleCell}${countCell}|${barCell}`;
|
|
88
|
+
})
|
|
89
|
+
.join("\n")}\n`;
|
|
90
|
+
}
|
|
91
|
+
const getFolderOutput = (maxWidth) => (folderStats, folderName) => `${underline(`${folderName}:`)}\n${getObjectOutput(folderStats, maxWidth)}`;
|
|
92
|
+
export function getOutputByFolder(stats, maxWidth) {
|
|
93
|
+
const filteredStats = Object.fromEntries(Object.entries(stats).filter(([, value]) => Object.keys(value).length > 0));
|
|
94
|
+
return Object.entries(filteredStats)
|
|
95
|
+
.map(([folderName, folderStats]) => getFolderOutput(maxWidth)(folderStats, folderName))
|
|
96
|
+
.join("");
|
|
97
|
+
}
|
|
98
|
+
//# sourceMappingURL=chart.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"chart.js","sourceRoot":"","sources":["../../src/utils/chart.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
type Color = "red" | "yellow" | "magenta" | "underline" | "bgRed" | "bgYellow";
|
|
2
|
+
export declare const color: (text: string, style: Color) => string;
|
|
3
|
+
export declare const red: (text: string) => string;
|
|
4
|
+
export declare const yellow: (text: string) => string;
|
|
5
|
+
export declare const magenta: (text: string) => string;
|
|
6
|
+
export declare const underline: (text: string) => string;
|
|
7
|
+
export declare const bgRed: (text: string) => string;
|
|
8
|
+
export declare const bgYellow: (text: string) => string;
|
|
9
|
+
export {};
|
|
10
|
+
//# sourceMappingURL=colors.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"colors.d.ts","sourceRoot":"","sources":["../../src/utils/colors.ts"],"names":[],"mappings":"AAOA,KAAK,KAAK,GAAG,KAAK,GAAG,QAAQ,GAAG,SAAS,GAAG,WAAW,GAAG,OAAO,GAAG,UAAU,CAAC;AAE/E,eAAO,MAAM,KAAK,GAAI,MAAM,MAAM,EAAE,OAAO,KAAK,KAAG,MAElD,CAAC;AAEF,eAAO,MAAM,GAAG,GAAI,MAAM,MAAM,KAAG,MAA4B,CAAC;AAEhE,eAAO,MAAM,MAAM,GAAI,MAAM,MAAM,KAAG,MAA+B,CAAC;AAEtE,eAAO,MAAM,OAAO,GAAI,MAAM,MAAM,KAAG,MAAgC,CAAC;AAExE,eAAO,MAAM,SAAS,GAAI,MAAM,MAAM,KAAG,MAAkC,CAAC;AAE5E,eAAO,MAAM,KAAK,GAAI,MAAM,MAAM,KAAG,MAA8B,CAAC;AAEpE,eAAO,MAAM,QAAQ,GAAI,MAAM,MAAM,KAAG,MAAiC,CAAC"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { styleText } from "node:util";
|
|
2
|
+
export const color = (text, style) => {
|
|
3
|
+
return styleText(style, text);
|
|
4
|
+
};
|
|
5
|
+
export const red = (text) => color(text, "red");
|
|
6
|
+
export const yellow = (text) => color(text, "yellow");
|
|
7
|
+
export const magenta = (text) => color(text, "magenta");
|
|
8
|
+
export const underline = (text) => color(text, "underline");
|
|
9
|
+
export const bgRed = (text) => color(text, "bgRed");
|
|
10
|
+
export const bgYellow = (text) => color(text, "bgYellow");
|
|
11
|
+
//# sourceMappingURL=colors.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"colors.js","sourceRoot":"","sources":["../../src/utils/colors.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,WAAW,CAAC;AAStC,MAAM,CAAC,MAAM,KAAK,GAAG,CAAC,IAAY,EAAE,KAAY,EAAU,EAAE;IAC1D,OAAO,SAAS,CAAC,KAAK,EAAE,IAAI,CAAC,CAAC;AAChC,CAAC,CAAC;AAEF,MAAM,CAAC,MAAM,GAAG,GAAG,CAAC,IAAY,EAAU,EAAE,CAAC,KAAK,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC;AAEhE,MAAM,CAAC,MAAM,MAAM,GAAG,CAAC,IAAY,EAAU,EAAE,CAAC,KAAK,CAAC,IAAI,EAAE,QAAQ,CAAC,CAAC;AAEtE,MAAM,CAAC,MAAM,OAAO,GAAG,CAAC,IAAY,EAAU,EAAE,CAAC,KAAK,CAAC,IAAI,EAAE,SAAS,CAAC,CAAC;AAExE,MAAM,CAAC,MAAM,SAAS,GAAG,CAAC,IAAY,EAAU,EAAE,CAAC,KAAK,CAAC,IAAI,EAAE,WAAW,CAAC,CAAC;AAE5E,MAAM,CAAC,MAAM,KAAK,GAAG,CAAC,IAAY,EAAU,EAAE,CAAC,KAAK,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC;AAEpE,MAAM,CAAC,MAAM,QAAQ,GAAG,CAAC,IAAY,EAAU,EAAE,CAAC,KAAK,CAAC,IAAI,EAAE,UAAU,CAAC,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"severities.d.ts","sourceRoot":"","sources":["../../src/utils/severities.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAEpE,eAAO,MAAM,KAAK,EAAE,WAAW,CAAC,OAAO,CAGtC,CAAC;AAEF,eAAO,MAAM,SAAS,GAAI,WAAW,aAAa,KAAG,aAAa,EAEjE,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"severities.js","sourceRoot":"","sources":["../../src/utils/severities.ts"],"names":[],"mappings":"AAEA,MAAM,CAAC,MAAM,KAAK,GAAyB;IACzC,CAAC,EAAE,SAAS;IACZ,CAAC,EAAE,OAAO;CACX,CAAC;AAEF,MAAM,CAAC,MAAM,SAAS,GAAG,CAAC,QAAwB,EAAmB,EAAE;IACrE,OAAO,QAAQ,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;AACxC,CAAC,CAAC"}
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import type { LintResult, RuleStats, FolderStats, SeverityLevel } from "../types/types.js";
|
|
2
|
+
export declare function byRule(results: LintResult[], severity?: SeverityLevel): RuleStats;
|
|
3
|
+
export declare function byFolderAndRule(results: LintResult[], severity?: SeverityLevel): FolderStats;
|
|
4
|
+
//# sourceMappingURL=stats.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"stats.d.ts","sourceRoot":"","sources":["../../src/utils/stats.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EACV,UAAU,EAEV,SAAS,EACT,WAAW,EACX,aAAa,EAEd,MAAM,mBAAmB,CAAC;AA2D3B,wBAAgB,MAAM,CACpB,OAAO,EAAE,UAAU,EAAE,EACrB,QAAQ,CAAC,EAAE,aAAa,GACvB,SAAS,CAaX;AAQD,wBAAgB,eAAe,CAC7B,OAAO,EAAE,UAAU,EAAE,EACrB,QAAQ,CAAC,EAAE,aAAa,GACvB,WAAW,CAIb"}
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
import path from "node:path";
|
|
2
|
+
import { names } from "./severities.js";
|
|
3
|
+
const countBy = (array, iterate) => {
|
|
4
|
+
return array.reduce((result, item) => {
|
|
5
|
+
const key = String(iterate(item));
|
|
6
|
+
if (key === "__proto__" || key === "constructor" || key === "prototype") {
|
|
7
|
+
return result;
|
|
8
|
+
}
|
|
9
|
+
result[key] = (result[key] ?? 0) + 1;
|
|
10
|
+
return result;
|
|
11
|
+
}, {});
|
|
12
|
+
};
|
|
13
|
+
const groupBy = (array, iterate) => {
|
|
14
|
+
return array.reduce((result, item) => {
|
|
15
|
+
const key = String(iterate(item));
|
|
16
|
+
if (key === "__proto__" || key === "constructor" || key === "prototype") {
|
|
17
|
+
return result;
|
|
18
|
+
}
|
|
19
|
+
if (!Array.isArray(result[key])) {
|
|
20
|
+
result[key] = [];
|
|
21
|
+
}
|
|
22
|
+
result[key].push(item);
|
|
23
|
+
return result;
|
|
24
|
+
}, {});
|
|
25
|
+
};
|
|
26
|
+
const mapValues = (obj, iterate) => {
|
|
27
|
+
return Object.fromEntries(Object.entries(obj).map(([key, value]) => [key, iterate(value)]));
|
|
28
|
+
};
|
|
29
|
+
const getStatsForRule = (ruleMessages) => {
|
|
30
|
+
return countBy(ruleMessages, (message) => names[message.severity]);
|
|
31
|
+
};
|
|
32
|
+
export function byRule(results, severity) {
|
|
33
|
+
const allMessages = results.flatMap((result) => result.messages);
|
|
34
|
+
const messagesInSeverities = severity
|
|
35
|
+
? allMessages.filter((message) => message.severity === severity)
|
|
36
|
+
: allMessages;
|
|
37
|
+
const messagesByRuleId = groupBy(messagesInSeverities, (message) => message.ruleId ?? "unknown");
|
|
38
|
+
return mapValues(messagesByRuleId, getStatsForRule);
|
|
39
|
+
}
|
|
40
|
+
const getDirName = (result) => {
|
|
41
|
+
const dirname = path.dirname(result.filePath);
|
|
42
|
+
return dirname === "." ? "Base Folder" : dirname;
|
|
43
|
+
};
|
|
44
|
+
export function byFolderAndRule(results, severity) {
|
|
45
|
+
const byDirName = groupBy(results, getDirName);
|
|
46
|
+
return mapValues(byDirName, (messages) => byRule(messages, severity));
|
|
47
|
+
}
|
|
48
|
+
//# sourceMappingURL=stats.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"stats.js","sourceRoot":"","sources":["../../src/utils/stats.ts"],"names":[],"mappings":"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"}
|
package/package.json
ADDED
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@danielsitek/eslint-stats",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "Modern TypeScript formatters for ESLint with aggregated error/warning statistics and visual graphs - Zero dependencies",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"main": "./dist/index.js",
|
|
7
|
+
"types": "./dist/index.d.ts",
|
|
8
|
+
"exports": {
|
|
9
|
+
".": {
|
|
10
|
+
"types": "./dist/index.d.ts",
|
|
11
|
+
"import": "./dist/index.js"
|
|
12
|
+
},
|
|
13
|
+
"./by-error": {
|
|
14
|
+
"types": "./dist/formatters/by-error.d.ts",
|
|
15
|
+
"import": "./dist/formatters/by-error.js"
|
|
16
|
+
},
|
|
17
|
+
"./by-warning": {
|
|
18
|
+
"types": "./dist/formatters/by-warning.d.ts",
|
|
19
|
+
"import": "./dist/formatters/by-warning.js"
|
|
20
|
+
},
|
|
21
|
+
"./by-error-and-warning": {
|
|
22
|
+
"types": "./dist/formatters/by-error-and-warning.d.ts",
|
|
23
|
+
"import": "./dist/formatters/by-error-and-warning.js"
|
|
24
|
+
},
|
|
25
|
+
"./by-error-and-warning-stacked": {
|
|
26
|
+
"types": "./dist/formatters/by-error-and-warning-stacked.d.ts",
|
|
27
|
+
"import": "./dist/formatters/by-error-and-warning-stacked.js"
|
|
28
|
+
},
|
|
29
|
+
"./by-folder": {
|
|
30
|
+
"types": "./dist/formatters/by-folder.d.ts",
|
|
31
|
+
"import": "./dist/formatters/by-folder.js"
|
|
32
|
+
}
|
|
33
|
+
},
|
|
34
|
+
"files": [
|
|
35
|
+
"dist",
|
|
36
|
+
"README.md",
|
|
37
|
+
"LICENSE"
|
|
38
|
+
],
|
|
39
|
+
"keywords": [
|
|
40
|
+
"eslint",
|
|
41
|
+
"formatter",
|
|
42
|
+
"statistics",
|
|
43
|
+
"stats",
|
|
44
|
+
"aggregated",
|
|
45
|
+
"visualization",
|
|
46
|
+
"typescript",
|
|
47
|
+
"zero-dependencies",
|
|
48
|
+
"eslint9"
|
|
49
|
+
],
|
|
50
|
+
"scripts": {
|
|
51
|
+
"build": "tsc -p tsconfig.build.json",
|
|
52
|
+
"clean": "rm -rf dist",
|
|
53
|
+
"prebuild": "npm run clean",
|
|
54
|
+
"typecheck": "tsc --noEmit",
|
|
55
|
+
"lint": "eslint .",
|
|
56
|
+
"format": "prettier --write .",
|
|
57
|
+
"format:check": "prettier --check .",
|
|
58
|
+
"test": "tsx --test test/**/*.test.ts",
|
|
59
|
+
"test:watch": "tsx --test --watch test/**/*.test.ts",
|
|
60
|
+
"test:coverage": "tsx --experimental-test-coverage --test-reporter=lcov --test-reporter-destination=lcov.info --test test/**/*.test.ts",
|
|
61
|
+
"prepublishOnly": "npm run build && npm test",
|
|
62
|
+
"demo:error": "eslint .demo/test.js -f ./dist/formatters/by-error.js -c .demo/eslint.config.mjs",
|
|
63
|
+
"demo:warning": "eslint .demo/test.js -f ./dist/formatters/by-warning.js -c .demo/eslint.config.mjs",
|
|
64
|
+
"demo:both": "eslint .demo/test.js -f ./dist/formatters/by-error-and-warning.js -c .demo/eslint.config.mjs",
|
|
65
|
+
"demo:stacked": "eslint .demo/test.js -f ./dist/formatters/by-error-and-warning-stacked.js -c .demo/eslint.config.mjs",
|
|
66
|
+
"demo:folder": "eslint .demo/test.js -f ./dist/formatters/by-folder.js -c .demo/eslint.config.mjs"
|
|
67
|
+
},
|
|
68
|
+
"repository": {
|
|
69
|
+
"type": "git",
|
|
70
|
+
"url": "git+https://github.com/danielsitek/eslint-stats.git"
|
|
71
|
+
},
|
|
72
|
+
"bugs": {
|
|
73
|
+
"url": "https://github.com/danielsitek/eslint-stats/issues"
|
|
74
|
+
},
|
|
75
|
+
"homepage": "https://github.com/danielsitek/eslint-stats#readme",
|
|
76
|
+
"author": {
|
|
77
|
+
"name": "Daniel Sitek",
|
|
78
|
+
"email": "me@danielsitek.com",
|
|
79
|
+
"url": "https://github.com/danielsitek"
|
|
80
|
+
},
|
|
81
|
+
"contributors": [
|
|
82
|
+
{
|
|
83
|
+
"name": "Omer Ganim",
|
|
84
|
+
"email": "ganimomer@gmail.com",
|
|
85
|
+
"url": "http://github.com/ganimomer"
|
|
86
|
+
}
|
|
87
|
+
],
|
|
88
|
+
"engines": {
|
|
89
|
+
"node": ">=20.0.0"
|
|
90
|
+
},
|
|
91
|
+
"peerDependencies": {
|
|
92
|
+
"eslint": ">=8.0.0"
|
|
93
|
+
},
|
|
94
|
+
"license": "MIT",
|
|
95
|
+
"devDependencies": {
|
|
96
|
+
"@types/node": "^25.0.10",
|
|
97
|
+
"@typescript-eslint/eslint-plugin": "^8.53.1",
|
|
98
|
+
"@typescript-eslint/parser": "^8.53.1",
|
|
99
|
+
"eslint": "^9.39.2",
|
|
100
|
+
"eslint-config-prettier": "^10.1.8",
|
|
101
|
+
"prettier": "^3.8.1",
|
|
102
|
+
"tsx": "^4.21.0",
|
|
103
|
+
"typescript": "^5.9.3"
|
|
104
|
+
}
|
|
105
|
+
}
|