lighthouse-badges 1.3.16 → 1.4.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.
Files changed (64) hide show
  1. package/README.md +0 -1
  2. package/__tests__/{argparser.js → argparser.ts} +1 -0
  3. package/__tests__/calculations.ts +105 -0
  4. package/__tests__/{lighthouse-badges.js → lighthouse-badges.ts} +36 -27
  5. package/__tests__/main.ts +66 -0
  6. package/__tests__/{util.js → util.ts} +4 -2
  7. package/dist/README.md +0 -1
  8. package/dist/package.json +21 -14
  9. package/dist/src/argparse.d.ts +27 -0
  10. package/dist/src/argparser.d.ts +6 -0
  11. package/dist/src/argparser.d.ts.map +1 -0
  12. package/dist/src/argparser.js +65 -50
  13. package/dist/src/argparser.js.map +1 -0
  14. package/dist/src/calculations.d.ts +5 -0
  15. package/dist/src/calculations.d.ts.map +1 -0
  16. package/dist/src/calculations.js +71 -25
  17. package/dist/src/calculations.js.map +1 -0
  18. package/dist/src/clui.d.ts +8 -0
  19. package/dist/src/index.d.ts +3 -0
  20. package/dist/src/index.d.ts.map +1 -0
  21. package/dist/src/index.js +4 -5
  22. package/dist/src/index.js.map +1 -0
  23. package/dist/src/lighthouse-badges.d.ts +9 -0
  24. package/dist/src/lighthouse-badges.d.ts.map +1 -0
  25. package/dist/src/lighthouse-badges.js +158 -98
  26. package/dist/src/lighthouse-badges.js.map +1 -0
  27. package/dist/src/main.d.ts +4 -0
  28. package/dist/src/main.d.ts.map +1 -0
  29. package/dist/src/main.js +43 -21
  30. package/dist/src/main.js.map +1 -0
  31. package/dist/src/ramda.d.ts +32 -0
  32. package/dist/src/types.d.ts +47 -0
  33. package/dist/src/types.d.ts.map +1 -0
  34. package/dist/src/types.js +2 -0
  35. package/dist/src/types.js.map +1 -0
  36. package/dist/src/util.d.ts +4 -0
  37. package/dist/src/util.d.ts.map +1 -0
  38. package/dist/src/util.js +16 -9
  39. package/dist/src/util.js.map +1 -0
  40. package/eslint.config.js +45 -2
  41. package/jest.config.cjs +20 -5
  42. package/package.json +21 -14
  43. package/src/argparse.d.ts +27 -0
  44. package/src/argparser.ts +82 -0
  45. package/src/calculations.ts +88 -0
  46. package/src/clui.d.ts +8 -0
  47. package/src/{index.js → index.ts} +3 -2
  48. package/src/lighthouse-badges.ts +281 -0
  49. package/src/main.ts +56 -0
  50. package/src/ramda.d.ts +32 -0
  51. package/src/types.ts +56 -0
  52. package/src/util.ts +23 -0
  53. package/tsconfig.json +25 -0
  54. package/__tests__/calculations.js +0 -87
  55. package/__tests__/main.js +0 -56
  56. package/babel.config.cjs +0 -9
  57. package/codecov.yml +0 -19
  58. package/dist/src/currentPath.cjs +0 -1
  59. package/src/argparser.js +0 -53
  60. package/src/calculations.js +0 -27
  61. package/src/currentPath.cjs +0 -1
  62. package/src/lighthouse-badges.js +0 -110
  63. package/src/main.js +0 -28
  64. package/src/util.js +0 -11
package/README.md CHANGED
@@ -1,5 +1,4 @@
1
1
  [![Build Status](https://github.com/emazzotta/lighthouse-badges/workflows/build/badge.svg)](https://github.com/emazzotta/lighthouse-badges/actions)
2
- [![Code Coverage](https://codecov.io/gh/emazzotta/lighthouse-badges/branch/master/graph/badge.svg)](https://github.com/emazzotta/lighthouse-badges/actions)
3
2
  [![NPM downloads](https://img.shields.io/npm/dt/lighthouse-badges?color=blue)](https://www.npmjs.org/package/lighthouse-badges)
4
3
  [![NPM version](https://img.shields.io/npm/v/lighthouse-badges.svg)](https://www.npmjs.org/package/lighthouse-badges)
5
4
  [![License](https://img.shields.io/:license-mit-blue.svg?style=flat)](https://emanuelemazzotta.com/mit-license)
@@ -25,3 +25,4 @@ describe('test argparser', () => {
25
25
  expect(actualArgs.url).toStrictEqual(baseUrl);
26
26
  });
27
27
  });
28
+
@@ -0,0 +1,105 @@
1
+ import { getAverageScore, getSquashedScore, percentageToColor } from '../src/calculations';
2
+
3
+ describe('calculations', () => {
4
+ describe('percentageToColor', () => {
5
+ it('should return brightgreen for very high number', () => {
6
+ expect(percentageToColor(97)).toBe('brightgreen');
7
+ });
8
+
9
+ it('should return green for high number', () => {
10
+ expect(percentageToColor(92)).toBe('green');
11
+ });
12
+
13
+ it('should return yellowgreen for medium high number', () => {
14
+ expect(percentageToColor(85)).toBe('yellowgreen');
15
+ });
16
+
17
+ it('should return yellow for medium number', () => {
18
+ expect(percentageToColor(62)).toBe('yellow');
19
+ });
20
+
21
+ it('should return orange for low number', () => {
22
+ expect(percentageToColor(45)).toBe('orange');
23
+ });
24
+
25
+ it('should return red for very low number', () => {
26
+ expect(percentageToColor(23)).toBe('red');
27
+ });
28
+ });
29
+
30
+ describe('getAverageScore', () => {
31
+ it('should calculate the expected average', () => {
32
+ const expectedResult = {
33
+ 'lighthouse accessibility': 60,
34
+ 'lighthouse performance': 51,
35
+ };
36
+ const input = [
37
+ { 'lighthouse accessibility': 100, 'lighthouse performance': 52 },
38
+ { 'lighthouse accessibility': 20, 'lighthouse performance': 50 },
39
+ ];
40
+ const actualResult = getAverageScore(input);
41
+ expect(expectedResult).toStrictEqual(actualResult);
42
+ });
43
+
44
+ it('should round the expected average correctly', () => {
45
+ const expectedResult = {
46
+ 'lighthouse accessibility': 99,
47
+ 'lighthouse performance': 99,
48
+ 'lighthouse progressive web app': 99,
49
+ 'lighthouse best practices': 99,
50
+ };
51
+ const input = [
52
+ {
53
+ 'lighthouse accessibility': 100,
54
+ 'lighthouse performance': 100,
55
+ 'lighthouse progressive web app': 100,
56
+ 'lighthouse best practices': 100,
57
+ },
58
+ {
59
+ 'lighthouse accessibility': 98.9,
60
+ 'lighthouse performance': 98.9,
61
+ 'lighthouse progressive web app': 98.9,
62
+ 'lighthouse best practices': 98.9,
63
+ },
64
+ ];
65
+ const actualResult = getAverageScore(input);
66
+ expect(expectedResult).toStrictEqual(actualResult);
67
+ });
68
+
69
+ it('should return empty object for empty input', () => {
70
+ const result = getAverageScore([]);
71
+ expect(result).toStrictEqual({});
72
+ });
73
+ });
74
+
75
+ describe('getSquashedScore', () => {
76
+ it('should calculate the expected squashed average', () => {
77
+ const expectedResult = { lighthouse: 50 };
78
+ const input = [
79
+ { 'lighthouse accessibility': 100, 'lighthouse performance': 60 },
80
+ { 'lighthouse accessibility': 20, 'lighthouse performance': 20 },
81
+ ];
82
+ const actualResult = getSquashedScore(input);
83
+ expect(expectedResult).toStrictEqual(actualResult);
84
+ });
85
+
86
+ it('should round the expected squashed average correctly', () => {
87
+ const expectedResult = { lighthouse: 83 };
88
+ const input = [
89
+ {
90
+ 'lighthouse accessibility': 100,
91
+ 'lighthouse performance': 100,
92
+ 'lighthouse progressive web app': 55,
93
+ 'lighthouse best practices': 75,
94
+ },
95
+ ];
96
+ const actualResult = getSquashedScore(input);
97
+ expect(expectedResult).toStrictEqual(actualResult);
98
+ });
99
+
100
+ it('should return zero score for empty input', () => {
101
+ const result = getSquashedScore([]);
102
+ expect(result).toStrictEqual({ lighthouse: 0 });
103
+ });
104
+ });
105
+ });
@@ -1,3 +1,4 @@
1
+ import { jest } from '@jest/globals';
1
2
  import fs from 'fs';
2
3
  import {
3
4
  htmlReportsToFile,
@@ -8,13 +9,14 @@ import {
8
9
  import { zip } from '../src/util';
9
10
  import parser from '../src/argparser';
10
11
  import reportFixture from '../assets/report/emanuelemazzotta.com.json';
12
+ import type { LighthouseLHR, LighthouseMetrics, LighthouseReport, ProcessedLighthouseResult, LighthouseConfig } from '../src/types';
11
13
 
12
14
  describe('test lighthouse badges', () => {
13
15
  describe('the lighthouse command results are processed as expected', () => {
14
16
  it('should return correct metrics and no report', async () => {
15
17
  const url = 'https://emanuelemazzotta.com';
16
18
  const shouldSaveReport = false;
17
- const result = await processRawLighthouseResult(reportFixture, '', url, shouldSaveReport);
19
+ const result = await processRawLighthouseResult(reportFixture as LighthouseLHR, '', url, shouldSaveReport);
18
20
  expect({
19
21
  metrics: {
20
22
  'lighthouse performance': 98,
@@ -34,7 +36,7 @@ describe('test lighthouse badges', () => {
34
36
  const url = 'https://emanuelemazzotta.com';
35
37
  const shouldSaveReport = true;
36
38
  const result = await processRawLighthouseResult(
37
- reportFixture,
39
+ reportFixture as LighthouseLHR,
38
40
  expectedHtmlReport,
39
41
  url,
40
42
  shouldSaveReport,
@@ -55,13 +57,14 @@ describe('test lighthouse badges', () => {
55
57
  });
56
58
 
57
59
  describe('the html reports are saved correctly', () => {
58
- let output;
60
+ let output: Array<Record<string, string>>;
59
61
  const { writeFile } = fs;
60
62
 
61
63
  beforeEach(() => {
62
64
  output = [];
63
- fs.writeFile = (path, content) => {
64
- output.push({ [path]: content });
65
+ (fs.writeFile as unknown) = (path: fs.PathLike, content: string | NodeJS.ArrayBufferView, callback?: (err: NodeJS.ErrnoException | null) => void) => {
66
+ output.push({ [path.toString()]: content.toString() });
67
+ if (callback) callback(null);
65
68
  };
66
69
  });
67
70
 
@@ -70,7 +73,7 @@ describe('test lighthouse badges', () => {
70
73
  });
71
74
 
72
75
  it('should save html report', async () => {
73
- const htmlReports = [
76
+ const htmlReports: LighthouseReport[] = [
74
77
  { 'https://emanuelemazzotta.com': 'a report' },
75
78
  { 'https://emanuelemazzotta.com/cv': 'another report' },
76
79
  ];
@@ -86,20 +89,24 @@ describe('test lighthouse badges', () => {
86
89
  });
87
90
 
88
91
  it('should not save html report if toggle is false', async () => {
89
- const htmlReports = [false, false];
90
- await htmlReportsToFile(htmlReports);
92
+ const htmlReports: LighthouseReport[] = [
93
+ { 'https://example.com': false },
94
+ { 'https://example2.com': false },
95
+ ];
96
+ await htmlReportsToFile(htmlReports, process.cwd());
91
97
  expect(output.length).toBe(0);
92
98
  });
93
99
  });
94
100
 
95
101
  describe('the svg files are saved correctly', () => {
96
- let output;
102
+ let output: Array<Record<string, string>>;
97
103
  const { writeFile } = fs;
98
104
 
99
105
  beforeEach(() => {
100
106
  output = [];
101
- fs.writeFile = (path, content) => {
102
- output.push({ [path]: content });
107
+ (fs.writeFile as unknown) = (path: fs.PathLike, content: string | NodeJS.ArrayBufferView, callback?: (err: NodeJS.ErrnoException | null) => void) => {
108
+ output.push({ [path.toString()]: content.toString() });
109
+ if (callback) callback(null);
103
110
  };
104
111
  });
105
112
 
@@ -108,7 +115,7 @@ describe('test lighthouse badges', () => {
108
115
  });
109
116
 
110
117
  it('should save all svg files', async () => {
111
- const lighthouseMetrics = {
118
+ const lighthouseMetrics: LighthouseMetrics = {
112
119
  'lighthouse performance': 100,
113
120
  'lighthouse pwa': 85,
114
121
  'lighthouse accessibility': 100,
@@ -125,13 +132,14 @@ describe('test lighthouse badges', () => {
125
132
  });
126
133
 
127
134
  describe('test the main process function', () => {
128
- let output;
135
+ let output: Array<Record<string, string>>;
129
136
  const { writeFile } = fs;
130
137
 
131
138
  beforeEach(() => {
132
139
  output = [];
133
- fs.writeFile = (path, content) => {
134
- output.push({ [path]: content });
140
+ (fs.writeFile as unknown) = (path: fs.PathLike, content: string | NodeJS.ArrayBufferView, callback?: (err: NodeJS.ErrnoException | null) => void) => {
141
+ output.push({ [path.toString()]: content.toString() });
142
+ if (callback) callback(null);
135
143
  };
136
144
  });
137
145
 
@@ -146,9 +154,9 @@ describe('test lighthouse badges', () => {
146
154
  '--url', 'https://example.org',
147
155
  ]);
148
156
 
149
- const calculateLighthouseMetrics = jest.fn();
150
- calculateLighthouseMetrics.mockReturnValue(await processRawLighthouseResult(reportFixture, '<html>Fake report</html>', 'https://example.org', args.save_report));
151
- await processParameters(args, calculateLighthouseMetrics);
157
+ const calculateLighthouseMetrics = jest.fn<() => Promise<ProcessedLighthouseResult>>();
158
+ calculateLighthouseMetrics.mockResolvedValue(await processRawLighthouseResult(reportFixture as LighthouseLHR, '<html>Fake report</html>', 'https://example.org', args.save_report));
159
+ await processParameters(args, calculateLighthouseMetrics as (url: string, shouldSaveReport: boolean, lighthouseParameters?: LighthouseConfig) => Promise<ProcessedLighthouseResult>);
152
160
 
153
161
  expect(output.length).toBe(2);
154
162
  });
@@ -159,9 +167,9 @@ describe('test lighthouse badges', () => {
159
167
  '--url', 'https://example.org',
160
168
  ]);
161
169
 
162
- const calculateLighthouseMetrics = jest.fn();
163
- calculateLighthouseMetrics.mockReturnValue(await processRawLighthouseResult(reportFixture, '<html>Fake report</html>', 'https://example.org', args.save_report));
164
- await processParameters(args, calculateLighthouseMetrics);
170
+ const calculateLighthouseMetrics = jest.fn<() => Promise<ProcessedLighthouseResult>>();
171
+ calculateLighthouseMetrics.mockResolvedValue(await processRawLighthouseResult(reportFixture as LighthouseLHR, '<html>Fake report</html>', 'https://example.org', args.save_report));
172
+ await processParameters(args, calculateLighthouseMetrics as (url: string, shouldSaveReport: boolean, lighthouseParameters?: LighthouseConfig) => Promise<ProcessedLighthouseResult>);
165
173
 
166
174
  expect(output.length).toBe(6);
167
175
  });
@@ -172,9 +180,9 @@ describe('test lighthouse badges', () => {
172
180
  '--url', 'https://example.org',
173
181
  ]);
174
182
 
175
- const calculateLighthouseMetrics = jest.fn();
176
- calculateLighthouseMetrics.mockReturnValue(await processRawLighthouseResult(reportFixture, null, 'https://example.org', args.save_report));
177
- await processParameters(args, calculateLighthouseMetrics);
183
+ const calculateLighthouseMetrics = jest.fn<() => Promise<ProcessedLighthouseResult>>();
184
+ calculateLighthouseMetrics.mockResolvedValue(await processRawLighthouseResult(reportFixture as LighthouseLHR, '', 'https://example.org', args.save_report));
185
+ await processParameters(args, calculateLighthouseMetrics as (url: string, shouldSaveReport: boolean, lighthouseParameters?: LighthouseConfig) => Promise<ProcessedLighthouseResult>);
178
186
 
179
187
  expect(output.length).toBe(1);
180
188
  });
@@ -184,11 +192,12 @@ describe('test lighthouse badges', () => {
184
192
  '--url', 'https://example.org',
185
193
  ]);
186
194
 
187
- const calculateLighthouseMetrics = jest.fn();
188
- calculateLighthouseMetrics.mockReturnValue(await processRawLighthouseResult(reportFixture, null, 'https://example.org', args.save_report));
189
- await processParameters(args, calculateLighthouseMetrics);
195
+ const calculateLighthouseMetrics = jest.fn<() => Promise<ProcessedLighthouseResult>>();
196
+ calculateLighthouseMetrics.mockResolvedValue(await processRawLighthouseResult(reportFixture as LighthouseLHR, '', 'https://example.org', args.save_report));
197
+ await processParameters(args, calculateLighthouseMetrics as (url: string, shouldSaveReport: boolean, lighthouseParameters?: LighthouseConfig) => Promise<ProcessedLighthouseResult>);
190
198
 
191
199
  expect(output.length).toBe(5);
192
200
  });
193
201
  });
194
202
  });
203
+
@@ -0,0 +1,66 @@
1
+ import { jest } from '@jest/globals';
2
+ import parser from '../src/argparser';
3
+ import type { Spinner } from '../src/types';
4
+
5
+ const mockProcessParameters = jest.fn<() => Promise<void>>();
6
+
7
+ jest.unstable_mockModule('../src/lighthouse-badges', () => ({
8
+ processParameters: mockProcessParameters,
9
+ calculateLighthouseMetrics: jest.fn(),
10
+ processRawLighthouseResult: jest.fn(),
11
+ metricsToSvg: jest.fn(),
12
+ htmlReportsToFile: jest.fn(),
13
+ }));
14
+
15
+ const handleUserInput = (await import('../src/main.js')).default;
16
+
17
+ describe('test index', () => {
18
+ let stderrOutput = '';
19
+ let parseMock: ReturnType<typeof jest.spyOn>;
20
+ const spinnerFake: Spinner = { start: () => null, stop: () => null };
21
+ const stderrWrite = process.stderr.write;
22
+ const processExit = process.exit;
23
+
24
+ beforeEach(() => {
25
+ parseMock = jest.spyOn(parser, 'parse_args');
26
+ process.stderr.write = (x: string | Uint8Array) => {
27
+ stderrOutput += `${x}\n`;
28
+ return true;
29
+ };
30
+ process.exit = (() => {
31
+ // Mock exit
32
+ }) as typeof process.exit;
33
+ stderrOutput = '';
34
+ });
35
+
36
+ afterEach(() => {
37
+ process.stderr.write = stderrWrite;
38
+ process.exit = processExit;
39
+ parseMock.mockRestore();
40
+ });
41
+
42
+ it('should invoke parse args and process parameters', async () => {
43
+ parseMock.mockReturnValue({ url: 'https://example.org', single_badge: false, badge_style: 'flat', save_report: false } as never);
44
+ mockProcessParameters.mockResolvedValue(undefined);
45
+
46
+ await handleUserInput(spinnerFake);
47
+
48
+ expect(parser.parse_args).toHaveBeenCalledTimes(1);
49
+ expect(mockProcessParameters).toHaveBeenCalledTimes(1);
50
+ expect(stderrOutput).toBe('');
51
+ });
52
+
53
+ it('should handle parse errors gracefully', async () => {
54
+ await handleUserInput(spinnerFake);
55
+ expect(stderrOutput.includes('the following arguments are required: -u/--url')).toBe(true);
56
+ });
57
+
58
+ it('should handle processing errors gracefully', async () => {
59
+ parseMock.mockReturnValue({ url: 'https://example.org', single_badge: false, badge_style: 'flat', save_report: false } as never);
60
+ mockProcessParameters.mockRejectedValue(new Error('Async error'));
61
+
62
+ await handleUserInput(spinnerFake);
63
+ expect(stderrOutput.includes('Error: Async error')).toBe(true);
64
+ });
65
+ });
66
+
@@ -26,8 +26,9 @@ describe('test util', () => {
26
26
  const stdoutWrite = process.stdout.write;
27
27
 
28
28
  beforeEach(() => {
29
- process.stdout.write = (x) => {
29
+ process.stdout.write = (x: string) => {
30
30
  stdoutOutput += x;
31
+ return true;
31
32
  };
32
33
  stdoutOutput = '';
33
34
  });
@@ -45,9 +46,10 @@ describe('test util', () => {
45
46
  it('should not write a success metric if error is thrown', () => {
46
47
  const expectedErrorMessage = 'error';
47
48
  expect(() => {
48
- statusMessage('success', expectedErrorMessage, 'error');
49
+ statusMessage('success', expectedErrorMessage, new Error('error'));
49
50
  }).toThrow(new Error(expectedErrorMessage));
50
51
  expect(stdoutOutput).toBe('');
51
52
  });
52
53
  });
53
54
  });
55
+
package/dist/README.md CHANGED
@@ -1,5 +1,4 @@
1
1
  [![Build Status](https://github.com/emazzotta/lighthouse-badges/workflows/build/badge.svg)](https://github.com/emazzotta/lighthouse-badges/actions)
2
- [![Code Coverage](https://codecov.io/gh/emazzotta/lighthouse-badges/branch/master/graph/badge.svg)](https://github.com/emazzotta/lighthouse-badges/actions)
3
2
  [![NPM downloads](https://img.shields.io/npm/dt/lighthouse-badges?color=blue)](https://www.npmjs.org/package/lighthouse-badges)
4
3
  [![NPM version](https://img.shields.io/npm/v/lighthouse-badges.svg)](https://www.npmjs.org/package/lighthouse-badges)
5
4
  [![License](https://img.shields.io/:license-mit-blue.svg?style=flat)](https://emanuelemazzotta.com/mit-license)
package/dist/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "lighthouse-badges",
3
- "version": "1.3.16",
3
+ "version": "1.4.0",
4
4
  "description": "🚦Generate gh-badges (shields.io) based on Lighthouse performance.",
5
5
  "main": "src/index.js",
6
6
  "bin": {
@@ -11,8 +11,10 @@
11
11
  "app:install": "npm run build && cd dist && npm i -g .",
12
12
  "app:reinstall": "npm-run-all app:uninstall app:install",
13
13
  "app:uninstall": "npm uninstall -g @emazzotta/lighthouse-badges; npm uninstall -g .; npm uninstall -g lighthouse-badges",
14
- "build": "npm run build:prepare && cp -r ./src ./dist/src",
15
- "build:prepare": "npm run clean && mkdir dist && sed 's#\"dist/src/index.js\"#\"src/index.js\"#' package.json > ./dist/package.json && cp README.md dist && cp LICENSE.md dist",
14
+ "build": "npm run build:prepare && npm run build:compile && npm run build:copy-declarations",
15
+ "build:compile": "tsc",
16
+ "build:copy-declarations": "cp src/*.d.ts dist/src/ 2>/dev/null || true",
17
+ "build:prepare": "npm run clean && mkdir -p dist && sed 's#\"dist/src/index.js\"#\"src/index.js\"#' package.json > ./dist/package.json && cp README.md dist && cp LICENSE.md dist",
16
18
  "ci:publish": "npm run build && npm publish --prefix dist",
17
19
  "clean": "rm -rf *.svg *.html coverage dist results",
18
20
  "docker:build": "npm run build && docker build --build-arg VCS_REF=`git rev-parse --short HEAD` --build-arg BUILD_DATE=`date -u +\"%Y-%m-%dT%H:%M:%SZ\"` --build-arg VERSION=latest -t emazzotta/lighthouse-badges .",
@@ -26,9 +28,10 @@
26
28
  "system-test:full-run": "npm-run-all clean build app:reinstall run:global-installation system-test:verify",
27
29
  "system-test:light-run": "npm-run-all clean build run:local-installation system-test:verify",
28
30
  "system-test:verify": "[ -z ${EXEC_PATH} ] && EXEC_PATH=$PWD/results ; grep -q '<svg xmlns' ${EXEC_PATH}/*.svg && grep -q '<title>Lighthouse Report</title>' ${EXEC_PATH}/*.html",
29
- "test": "jest",
31
+ "test": "NODE_OPTIONS=--experimental-vm-modules jest",
30
32
  "test:all": "npm-run-all test system-test:full-run",
31
- "test:related": "jest --findRelatedTests"
33
+ "test:related": "jest --findRelatedTests",
34
+ "upgrade": "npx npm-check-updates -i && npm install && npm upgrade && npm run pre-push"
32
35
  },
33
36
  "husky": {
34
37
  "hooks": {
@@ -36,7 +39,7 @@
36
39
  }
37
40
  },
38
41
  "lint-staged": {
39
- "*.js": [
42
+ "*.{js,ts}": [
40
43
  "npm run lint:fix",
41
44
  "npm run test:related"
42
45
  ]
@@ -50,25 +53,29 @@
50
53
  "badge-maker": "^5.0.2",
51
54
  "chrome-launcher": "1.2.1",
52
55
  "clui": "^0.3.6",
53
- "lighthouse": "^13.0.0",
56
+ "lighthouse": "^13.0.1",
54
57
  "ramda": "^0.32.0"
55
58
  },
56
59
  "devDependencies": {
57
- "@babel/core": "^7.28.0",
58
- "@babel/preset-env": "^7.28.0",
59
- "@eslint/js": "^9.32.0",
60
+ "@eslint/js": "^9.39.1",
61
+ "@jest/globals": "^30.2.0",
60
62
  "@types/jest": "^30.0.0",
61
- "eslint": "^9.32.0",
63
+ "@types/node": "^24.10.0",
64
+ "@typescript-eslint/eslint-plugin": "^8.46.3",
65
+ "@typescript-eslint/parser": "^8.46.3",
66
+ "eslint": "^9.39.1",
67
+ "globals": "^16.5.0",
62
68
  "husky": "^9.1.7",
63
- "jest": "^30.0.5",
69
+ "jest": "^30.2.0",
64
70
  "lint-staged": "^16.2.6",
65
- "npm-run-all": "^4.1.5"
71
+ "npm-run-all": "^4.1.5",
72
+ "ts-jest": "^29.4.5",
73
+ "typescript": "^5.9.3"
66
74
  },
67
75
  "engines": {
68
76
  "npm": ">=7.0.0",
69
77
  "node": ">=18.16"
70
78
  },
71
- "packageManager": "yarn@1.21.1",
72
79
  "private": false,
73
80
  "author": "Emanuele Mazzotta",
74
81
  "license": "MIT"
@@ -0,0 +1,27 @@
1
+ declare module 'argparse' {
2
+ export interface ArgumentParserOptions {
3
+ description?: string;
4
+ add_help?: boolean;
5
+ }
6
+
7
+ export class ArgumentGroup {
8
+ add_argument(name: string, longName: string, options?: ArgumentOptions): void;
9
+ }
10
+
11
+ export interface ArgumentOptions {
12
+ action?: string;
13
+ version?: string;
14
+ help?: string;
15
+ required?: boolean;
16
+ choices?: string[];
17
+ default?: string;
18
+ }
19
+
20
+ export class ArgumentParser {
21
+ constructor(options?: ArgumentParserOptions);
22
+ add_argument(name: string, longName: string, options?: ArgumentOptions): void;
23
+ add_argument_group(options: { title: string }): ArgumentGroup;
24
+ parse_args(args?: string[]): Record<string, unknown>;
25
+ }
26
+ }
27
+
@@ -0,0 +1,6 @@
1
+ import type { ParsedArgs } from './types.js';
2
+ declare const typedParser: {
3
+ parse_args: (args?: string[]) => ParsedArgs;
4
+ };
5
+ export default typedParser;
6
+ //# sourceMappingURL=argparser.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"argparser.d.ts","sourceRoot":"","sources":["../../src/argparser.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AAuE7C,QAAA,MAAM,WAAW;wBACK,MAAM,EAAE,KAAG,UAAU;CAG1C,CAAC;AAEF,eAAe,WAAW,CAAC"}
@@ -1,53 +1,68 @@
1
1
  import fs from 'fs';
2
2
  import path from 'path';
3
+ import { fileURLToPath } from 'url';
3
4
  import { ArgumentParser } from 'argparse';
4
- import * as currentPath from "./currentPath.cjs"
5
-
6
- const packageJsonPath = path.join(currentPath.default, '../package.json');
7
- const packageJson = JSON.parse(fs.readFileSync(packageJsonPath, 'utf8'));
8
-
9
- const parser = new ArgumentParser({
10
- description: 'Generate gh-badges (shields.io) based on lighthouse performance.',
11
- add_help: true
12
- });
13
-
14
- parser.add_argument('-v', '--version', {
15
- action: 'version',
16
- version: packageJson.version,
17
- help: 'Show the version of the tool'
18
- });
19
-
20
- parser.add_argument('-s', '--single-badge', {
21
- action: 'store_true',
22
- required: false,
23
- help: 'Output only one single badge averaging all lighthouse categories\' scores'
24
- });
25
-
26
- parser.add_argument('-b', '--badge-style', {
27
- action: 'store',
28
- required: false,
29
- choices: ['flat', 'flat-square', 'plastic', 'for-the-badge', 'social'],
30
- default: 'flat',
31
- help: 'Define look and feel for the badge'
32
- });
33
-
34
- parser.add_argument('-o', '--output-path', {
35
- action: 'store',
36
- required: false,
37
- help: 'Define output path for artifacts'
38
- });
39
-
40
- parser.add_argument('-r', '--save-report', {
41
- action: 'store_true',
42
- required: false,
43
- help: 'Save lighthouse report as html for every supplied url'
44
- });
45
-
46
- const requiredArgs = parser.add_argument_group({ title: 'Required arguments' });
47
- requiredArgs.add_argument('-u', '--url', {
48
- action: 'store',
49
- required: true,
50
- help: 'The lighthouse badge(s) will contain the score(s) of the supplied url'
51
- });
52
-
53
- export default parser;
5
+ const __filename = fileURLToPath(import.meta.url);
6
+ const __dirname = path.dirname(__filename);
7
+ const getPackageVersion = () => {
8
+ const packageJsonPath = path.join(__dirname, '../package.json');
9
+ const packageJson = JSON.parse(fs.readFileSync(packageJsonPath, 'utf8'));
10
+ return packageJson.version;
11
+ };
12
+ const createParser = () => {
13
+ const parser = new ArgumentParser({
14
+ description: 'Generate gh-badges (shields.io) based on lighthouse performance.',
15
+ add_help: true,
16
+ });
17
+ addVersionArgument(parser);
18
+ addOptionalArguments(parser);
19
+ addRequiredArguments(parser);
20
+ return parser;
21
+ };
22
+ const addVersionArgument = (parser) => {
23
+ parser.add_argument('-v', '--version', {
24
+ action: 'version',
25
+ version: getPackageVersion(),
26
+ help: 'Show the version of the tool',
27
+ });
28
+ };
29
+ const addOptionalArguments = (parser) => {
30
+ parser.add_argument('-s', '--single-badge', {
31
+ action: 'store_true',
32
+ required: false,
33
+ help: 'Output only one single badge averaging all lighthouse categories\' scores',
34
+ });
35
+ parser.add_argument('-b', '--badge-style', {
36
+ action: 'store',
37
+ required: false,
38
+ choices: ['flat', 'flat-square', 'plastic', 'for-the-badge', 'social'],
39
+ default: 'flat',
40
+ help: 'Define look and feel for the badge',
41
+ });
42
+ parser.add_argument('-o', '--output-path', {
43
+ action: 'store',
44
+ required: false,
45
+ help: 'Define output path for artifacts',
46
+ });
47
+ parser.add_argument('-r', '--save-report', {
48
+ action: 'store_true',
49
+ required: false,
50
+ help: 'Save lighthouse report as html for every supplied url',
51
+ });
52
+ };
53
+ const addRequiredArguments = (parser) => {
54
+ const requiredArgs = parser.add_argument_group({ title: 'Required arguments' });
55
+ requiredArgs.add_argument('-u', '--url', {
56
+ action: 'store',
57
+ required: true,
58
+ help: 'The lighthouse badge(s) will contain the score(s) of the supplied url',
59
+ });
60
+ };
61
+ const parser = createParser();
62
+ const typedParser = {
63
+ parse_args: (args) => {
64
+ return parser.parse_args(args);
65
+ },
66
+ };
67
+ export default typedParser;
68
+ //# sourceMappingURL=argparser.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"argparser.js","sourceRoot":"","sources":["../../src/argparser.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,IAAI,CAAC;AACpB,OAAO,IAAI,MAAM,MAAM,CAAC;AACxB,OAAO,EAAE,aAAa,EAAE,MAAM,KAAK,CAAC;AACpC,OAAO,EAAE,cAAc,EAAE,MAAM,UAAU,CAAC;AAG1C,MAAM,UAAU,GAAG,aAAa,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;AAClD,MAAM,SAAS,GAAG,IAAI,CAAC,OAAO,CAAC,UAAU,CAAC,CAAC;AAE3C,MAAM,iBAAiB,GAAG,GAAW,EAAE;IACrC,MAAM,eAAe,GAAG,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE,iBAAiB,CAAC,CAAC;IAChE,MAAM,WAAW,GAAG,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC,YAAY,CAAC,eAAe,EAAE,MAAM,CAAC,CAAwB,CAAC;IAChG,OAAO,WAAW,CAAC,OAAO,CAAC;AAC7B,CAAC,CAAC;AAEF,MAAM,YAAY,GAAG,GAAmB,EAAE;IACxC,MAAM,MAAM,GAAG,IAAI,cAAc,CAAC;QAChC,WAAW,EAAE,kEAAkE;QAC/E,QAAQ,EAAE,IAAI;KACf,CAAC,CAAC;IAEH,kBAAkB,CAAC,MAAM,CAAC,CAAC;IAC3B,oBAAoB,CAAC,MAAM,CAAC,CAAC;IAC7B,oBAAoB,CAAC,MAAM,CAAC,CAAC;IAE7B,OAAO,MAAM,CAAC;AAChB,CAAC,CAAC;AAEF,MAAM,kBAAkB,GAAG,CAAC,MAAsB,EAAQ,EAAE;IAC1D,MAAM,CAAC,YAAY,CAAC,IAAI,EAAE,WAAW,EAAE;QACrC,MAAM,EAAE,SAAS;QACjB,OAAO,EAAE,iBAAiB,EAAE;QAC5B,IAAI,EAAE,8BAA8B;KACrC,CAAC,CAAC;AACL,CAAC,CAAC;AAEF,MAAM,oBAAoB,GAAG,CAAC,MAAsB,EAAQ,EAAE;IAC5D,MAAM,CAAC,YAAY,CAAC,IAAI,EAAE,gBAAgB,EAAE;QAC1C,MAAM,EAAE,YAAY;QACpB,QAAQ,EAAE,KAAK;QACf,IAAI,EAAE,2EAA2E;KAClF,CAAC,CAAC;IAEH,MAAM,CAAC,YAAY,CAAC,IAAI,EAAE,eAAe,EAAE;QACzC,MAAM,EAAE,OAAO;QACf,QAAQ,EAAE,KAAK;QACf,OAAO,EAAE,CAAC,MAAM,EAAE,aAAa,EAAE,SAAS,EAAE,eAAe,EAAE,QAAQ,CAAC;QACtE,OAAO,EAAE,MAAM;QACf,IAAI,EAAE,oCAAoC;KAC3C,CAAC,CAAC;IAEH,MAAM,CAAC,YAAY,CAAC,IAAI,EAAE,eAAe,EAAE;QACzC,MAAM,EAAE,OAAO;QACf,QAAQ,EAAE,KAAK;QACf,IAAI,EAAE,kCAAkC;KACzC,CAAC,CAAC;IAEH,MAAM,CAAC,YAAY,CAAC,IAAI,EAAE,eAAe,EAAE;QACzC,MAAM,EAAE,YAAY;QACpB,QAAQ,EAAE,KAAK;QACf,IAAI,EAAE,uDAAuD;KAC9D,CAAC,CAAC;AACL,CAAC,CAAC;AAEF,MAAM,oBAAoB,GAAG,CAAC,MAAsB,EAAQ,EAAE;IAC5D,MAAM,YAAY,GAAG,MAAM,CAAC,kBAAkB,CAAC,EAAE,KAAK,EAAE,oBAAoB,EAAE,CAAC,CAAC;IAChF,YAAY,CAAC,YAAY,CAAC,IAAI,EAAE,OAAO,EAAE;QACvC,MAAM,EAAE,OAAO;QACf,QAAQ,EAAE,IAAI;QACd,IAAI,EAAE,uEAAuE;KAC9E,CAAC,CAAC;AACL,CAAC,CAAC;AAEF,MAAM,MAAM,GAAG,YAAY,EAAE,CAAC;AAE9B,MAAM,WAAW,GAAG;IAClB,UAAU,EAAE,CAAC,IAAe,EAAc,EAAE;QAC1C,OAAO,MAAM,CAAC,UAAU,CAAC,IAAI,CAA0B,CAAC;IAC1D,CAAC;CACF,CAAC;AAEF,eAAe,WAAW,CAAC"}
@@ -0,0 +1,5 @@
1
+ import type { LighthouseMetrics } from './types.js';
2
+ export declare const percentageToColor: (percentage: number) => string;
3
+ export declare const getAverageScore: (metrics: LighthouseMetrics[]) => LighthouseMetrics;
4
+ export declare const getSquashedScore: (metrics: LighthouseMetrics[]) => LighthouseMetrics;
5
+ //# sourceMappingURL=calculations.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"calculations.d.ts","sourceRoot":"","sources":["../../src/calculations.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,YAAY,CAAC;AAmBpD,eAAO,MAAM,iBAAiB,GAAI,YAAY,MAAM,KAAG,MAOtD,CAAC;AAYF,eAAO,MAAM,eAAe,GAAI,SAAS,iBAAiB,EAAE,KAAG,iBAgB9D,CAAC;AAcF,eAAO,MAAM,gBAAgB,GAAI,SAAS,iBAAiB,EAAE,KAAG,iBAkB/D,CAAC"}