apex-auditor 0.3.7 → 0.3.8
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/README.md +41 -0
- package/dist/bin.js +44 -14
- package/dist/clear-screenshots-cli.js +97 -0
- package/dist/cli.js +689 -29
- package/dist/config.js +2 -0
- package/dist/lighthouse-capture.js +265 -0
- package/dist/lighthouse-runner.js +58 -34
- package/dist/lighthouse-worker.js +11 -1
- package/dist/measure-cli.js +32 -1
- package/dist/route-detectors.js +12 -2
- package/dist/shell-cli.js +243 -28
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -16,6 +16,8 @@ From your web project root:
|
|
|
16
16
|
pnpm dlx apex-auditor@latest
|
|
17
17
|
```
|
|
18
18
|
|
|
19
|
+
This is the recommended way to run ApexAuditor because it always uses the latest published version.
|
|
20
|
+
|
|
19
21
|
Notes:
|
|
20
22
|
|
|
21
23
|
- `init` can auto-detect your stack from `package.json` (Next.js, Nuxt, Remix/React Router, SvelteKit, SPA).
|
|
@@ -34,9 +36,15 @@ Inside the interactive shell:
|
|
|
34
36
|
- **headers** (security headers check; writes `.apex-auditor/headers.json`)
|
|
35
37
|
- **console** (console errors + runtime exceptions; writes `.apex-auditor/console.json`)
|
|
36
38
|
- **open** (open the latest HTML report)
|
|
39
|
+
- **open-triage** (open `.apex-auditor/triage.md`)
|
|
40
|
+
- **open-screenshots** (open `.apex-auditor/screenshots/`)
|
|
41
|
+
- **open-diagnostics** (open `.apex-auditor/lighthouse-artifacts/diagnostics/`)
|
|
42
|
+
- **open-lhr** (open `.apex-auditor/lighthouse-artifacts/lhr/`)
|
|
43
|
+
- **open-artifacts** (open `.apex-auditor/lighthouse-artifacts/`)
|
|
37
44
|
- **pages** / **routes** (print configured pages/routes from the current config)
|
|
38
45
|
- **add-page** (interactive: append a page to `apex.config.json`)
|
|
39
46
|
- **rm-page** (interactive: remove a page from `apex.config.json`)
|
|
47
|
+
- **clear-screenshots** (remove `.apex-auditor/screenshots/`)
|
|
40
48
|
- **init** (launch config wizard)
|
|
41
49
|
- **config <path>** (switch config file)
|
|
42
50
|
|
|
@@ -52,6 +60,10 @@ Install as a dev dependency (recommended):
|
|
|
52
60
|
pnpm add -D apex-auditor
|
|
53
61
|
```
|
|
54
62
|
|
|
63
|
+
Note: `pnpm apex-auditor` runs the version installed in your current project, which may be older than the latest release.
|
|
64
|
+
|
|
65
|
+
To always run the latest published version without installing:
|
|
66
|
+
|
|
55
67
|
Or run without installing:
|
|
56
68
|
|
|
57
69
|
```bash
|
|
@@ -65,8 +77,15 @@ All outputs are written under `.apex-auditor/` in your project.
|
|
|
65
77
|
### `audit` outputs
|
|
66
78
|
|
|
67
79
|
- `summary.json`
|
|
80
|
+
- `summary-lite.json`
|
|
68
81
|
- `summary.md`
|
|
82
|
+
- `triage.md`
|
|
83
|
+
- `issues.json`
|
|
69
84
|
- `report.html`
|
|
85
|
+
- `screenshots/` (when `audit --diagnostics` or `audit --lhr` is used)
|
|
86
|
+
- `lighthouse-artifacts/diagnostics/` (when `audit --diagnostics` or `audit --lhr` is used)
|
|
87
|
+
- `lighthouse-artifacts/diagnostics-lite/` (when `audit --diagnostics` or `audit --lhr` is used)
|
|
88
|
+
- `lighthouse-artifacts/lhr/` (when `audit --lhr` is used)
|
|
70
89
|
- `accessibility-summary.json`
|
|
71
90
|
- `accessibility/` (axe-core artifacts per page/device)
|
|
72
91
|
|
|
@@ -75,10 +94,12 @@ Notes:
|
|
|
75
94
|
- **Runs-per-combo is always 1**. Re-run the same command to compare results.
|
|
76
95
|
- During an audit you will see a runtime progress line like `page X/Y — /path [device] | ETA ...`.
|
|
77
96
|
- After `audit` completes, type `open` to open the latest HTML report.
|
|
97
|
+
- Large JSON files may also be written as gzip copies (`*.json.gz`) to reduce disk size.
|
|
78
98
|
|
|
79
99
|
### `measure` outputs
|
|
80
100
|
|
|
81
101
|
- `measure-summary.json`
|
|
102
|
+
- `measure-summary-lite.json`
|
|
82
103
|
- `measure/` (screenshots and artifacts)
|
|
83
104
|
|
|
84
105
|
### `bundle` outputs
|
|
@@ -105,6 +126,19 @@ Notes:
|
|
|
105
126
|
|
|
106
127
|
ApexAuditor reads `apex.config.json` by default.
|
|
107
128
|
|
|
129
|
+
Common fields:
|
|
130
|
+
|
|
131
|
+
- `baseUrl`
|
|
132
|
+
- `pages` (routes + devices)
|
|
133
|
+
- `throttlingMethod` (`simulate` or `devtools`)
|
|
134
|
+
- `cpuSlowdownMultiplier`
|
|
135
|
+
- `parallel`
|
|
136
|
+
- `warmUp`
|
|
137
|
+
- `auditTimeoutMs`
|
|
138
|
+
- `incremental` + `buildId`
|
|
139
|
+
- `gitIgnoreApexAuditorDir` (auto-add `.apex-auditor/` to `.gitignore`)
|
|
140
|
+
- `budgets`
|
|
141
|
+
|
|
108
142
|
Example:
|
|
109
143
|
|
|
110
144
|
```json
|
|
@@ -125,6 +159,13 @@ Example:
|
|
|
125
159
|
}
|
|
126
160
|
```
|
|
127
161
|
|
|
162
|
+
## CLI tips
|
|
163
|
+
|
|
164
|
+
- Use `pnpm dlx apex-auditor@latest` to avoid running an older installed version.
|
|
165
|
+
- Use `audit --flags` to print all audit flags/options.
|
|
166
|
+
- Use `audit --diagnostics` or `audit --lhr` when you want per-combo JSON artifacts and screenshots.
|
|
167
|
+
- Start with `triage.md` and `issues.json` when the suite is large.
|
|
168
|
+
|
|
128
169
|
## Documentation
|
|
129
170
|
|
|
130
171
|
The docs in `docs/` reflect the current shell-based workflow:
|
package/dist/bin.js
CHANGED
|
@@ -11,6 +11,7 @@ import { runHeadersCli } from "./headers-cli.js";
|
|
|
11
11
|
import { runConsoleCli } from "./console-cli.js";
|
|
12
12
|
import { runCleanCli } from "./clean-cli.js";
|
|
13
13
|
import { runUninstallCli } from "./uninstall-cli.js";
|
|
14
|
+
import { runClearScreenshotsCli } from "./clear-screenshots-cli.js";
|
|
14
15
|
function parseBinArgs(argv) {
|
|
15
16
|
const rawCommand = argv[2];
|
|
16
17
|
if (rawCommand === undefined) {
|
|
@@ -32,6 +33,7 @@ function parseBinArgs(argv) {
|
|
|
32
33
|
rawCommand === "console" ||
|
|
33
34
|
rawCommand === "clean" ||
|
|
34
35
|
rawCommand === "uninstall" ||
|
|
36
|
+
rawCommand === "clear-screenshots" ||
|
|
35
37
|
rawCommand === "wizard" ||
|
|
36
38
|
rawCommand === "quickstart" ||
|
|
37
39
|
rawCommand === "guide" ||
|
|
@@ -107,31 +109,47 @@ function printHelp(topic) {
|
|
|
107
109
|
console.log([
|
|
108
110
|
"ApexAuditor CLI",
|
|
109
111
|
"",
|
|
112
|
+
"Recommended run (always latest):",
|
|
113
|
+
" pnpm dlx apex-auditor@latest",
|
|
114
|
+
"",
|
|
115
|
+
"Note:",
|
|
116
|
+
" pnpm apex-auditor runs the version installed in the current project, which may be older.",
|
|
117
|
+
"",
|
|
110
118
|
"Usage:",
|
|
111
119
|
" apex-auditor # interactive shell (default)",
|
|
112
120
|
" apex-auditor quickstart --base-url <url> [--project-root <path>]",
|
|
113
121
|
" apex-auditor wizard [--config <path>]",
|
|
114
122
|
" apex-auditor audit [--config <path>] [--ci] [--no-color|--color] [--log-level <level>]",
|
|
123
|
+
" apex-auditor audit --flags # print audit flags/options and exit",
|
|
115
124
|
" apex-auditor guide (alias of wizard) interactive flow with tips for non-technical users",
|
|
116
125
|
" apex-auditor shell # same as default entrypoint",
|
|
117
126
|
"",
|
|
118
127
|
"Commands:",
|
|
119
|
-
"
|
|
120
|
-
"
|
|
121
|
-
"
|
|
122
|
-
"
|
|
123
|
-
"
|
|
124
|
-
"
|
|
125
|
-
"
|
|
126
|
-
"
|
|
127
|
-
"
|
|
128
|
-
"
|
|
129
|
-
"
|
|
130
|
-
"
|
|
131
|
-
"
|
|
132
|
-
"
|
|
128
|
+
" Interactive:",
|
|
129
|
+
" shell Start interactive shell (default)",
|
|
130
|
+
" wizard Run interactive config wizard",
|
|
131
|
+
" guide Same as wizard, with inline tips for non-technical users",
|
|
132
|
+
" quickstart Detect routes and run a one-off audit with sensible defaults",
|
|
133
|
+
"",
|
|
134
|
+
" Audits and checks:",
|
|
135
|
+
" measure Fast batch metrics (CDP-based, non-Lighthouse)",
|
|
136
|
+
" audit Run Lighthouse audits using apex.config.json",
|
|
137
|
+
" bundle Bundle size audit (Next.js .next/ or dist/ build output)",
|
|
138
|
+
" health HTTP status + latency checks for configured routes",
|
|
139
|
+
" links Broken links audit (sitemap + HTML link extraction)",
|
|
140
|
+
" headers Security headers audit",
|
|
141
|
+
" console Console errors + runtime exceptions audit (headless Chrome)",
|
|
142
|
+
"",
|
|
143
|
+
" Maintenance:",
|
|
144
|
+
" clean Remove ApexAuditor artifacts (reports/cache and optionally config)",
|
|
145
|
+
" uninstall One-click uninstall (removes .apex-auditor/ and apex.config.json)",
|
|
146
|
+
" clear-screenshots Remove .apex-auditor/screenshots/",
|
|
147
|
+
"",
|
|
148
|
+
" Help:",
|
|
149
|
+
" help Show this help message",
|
|
133
150
|
"",
|
|
134
151
|
"Options (audit):",
|
|
152
|
+
" --flags Print audit flags/options and exit",
|
|
135
153
|
" --ci Enable CI mode with budgets and non-zero exit code on failure",
|
|
136
154
|
" --fail-on-budget Exit non-zero if budgets fail even outside CI",
|
|
137
155
|
" --no-color Disable ANSI colours in console output (default in CI mode)",
|
|
@@ -142,6 +160,8 @@ function printHelp(topic) {
|
|
|
142
160
|
" --desktop-only Run audits only for 'desktop' devices defined in the config",
|
|
143
161
|
" --parallel <n> Override parallel workers (1-10). Default auto-tunes from CPU/memory.",
|
|
144
162
|
" --audit-timeout-ms <ms> Per-audit timeout in milliseconds (prevents hung runs from stalling)",
|
|
163
|
+
" --diagnostics Capture DevTools-like Lighthouse tables + screenshots (writes .apex-auditor/...)",
|
|
164
|
+
" --lhr Also capture full Lighthouse result JSON per combo (implies --diagnostics)",
|
|
145
165
|
" --plan Print resolved settings + run size estimate and exit without auditing",
|
|
146
166
|
" --max-steps <n> Safety limit: refuse/prompt if planned Lighthouse runs exceed this (default 120)",
|
|
147
167
|
" --max-combos <n> Safety limit: refuse/prompt if planned page/device combos exceed this (default 60)",
|
|
@@ -217,6 +237,12 @@ function printHelp(topic) {
|
|
|
217
237
|
" --yes, -y Skip confirmation prompt",
|
|
218
238
|
" --json Print JSON report to stdout",
|
|
219
239
|
"",
|
|
240
|
+
"Options (clear-screenshots):",
|
|
241
|
+
" --project-root <path> Project root (default cwd)",
|
|
242
|
+
" --dry-run Print planned removals without deleting",
|
|
243
|
+
" --yes, -y Skip confirmation prompt",
|
|
244
|
+
" --json Print JSON report to stdout",
|
|
245
|
+
"",
|
|
220
246
|
"Outputs:",
|
|
221
247
|
" - Writes .apex-auditor/summary.json, summary.md, report.html",
|
|
222
248
|
" - Prints a file:// link to the HTML report after completion",
|
|
@@ -296,6 +322,10 @@ export async function runBin(argv) {
|
|
|
296
322
|
await runUninstallCli(parsed.argv);
|
|
297
323
|
return;
|
|
298
324
|
}
|
|
325
|
+
if (parsed.command === "clear-screenshots") {
|
|
326
|
+
await runClearScreenshotsCli(parsed.argv);
|
|
327
|
+
return;
|
|
328
|
+
}
|
|
299
329
|
if (parsed.command === "init" || parsed.command === "wizard" || parsed.command === "guide") {
|
|
300
330
|
await runWizardCli(parsed.argv);
|
|
301
331
|
return;
|
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
import { rm } from "node:fs/promises";
|
|
2
|
+
import { resolve } from "node:path";
|
|
3
|
+
import readline from "node:readline";
|
|
4
|
+
function parseArgs(argv) {
|
|
5
|
+
let projectRoot = process.cwd();
|
|
6
|
+
let dryRun = false;
|
|
7
|
+
let yes = false;
|
|
8
|
+
let jsonOutput = false;
|
|
9
|
+
for (let i = 2; i < argv.length; i += 1) {
|
|
10
|
+
const arg = argv[i] ?? "";
|
|
11
|
+
if (arg === "--project-root" && i + 1 < argv.length) {
|
|
12
|
+
projectRoot = argv[i + 1] ?? projectRoot;
|
|
13
|
+
i += 1;
|
|
14
|
+
continue;
|
|
15
|
+
}
|
|
16
|
+
if (arg === "--dry-run") {
|
|
17
|
+
dryRun = true;
|
|
18
|
+
continue;
|
|
19
|
+
}
|
|
20
|
+
if (arg === "--yes" || arg === "-y") {
|
|
21
|
+
yes = true;
|
|
22
|
+
continue;
|
|
23
|
+
}
|
|
24
|
+
if (arg === "--json") {
|
|
25
|
+
jsonOutput = true;
|
|
26
|
+
continue;
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
return { projectRoot: resolve(projectRoot), dryRun, yes, jsonOutput };
|
|
30
|
+
}
|
|
31
|
+
async function confirmPrompt(question) {
|
|
32
|
+
if (!process.stdin.isTTY) {
|
|
33
|
+
return false;
|
|
34
|
+
}
|
|
35
|
+
process.stdin.resume();
|
|
36
|
+
const rl = readline.createInterface({ input: process.stdin, output: process.stdout });
|
|
37
|
+
try {
|
|
38
|
+
const answer = await new Promise((resolvePromise) => {
|
|
39
|
+
rl.question(question, (value) => resolvePromise(value));
|
|
40
|
+
});
|
|
41
|
+
const text = answer.trim().toLowerCase();
|
|
42
|
+
return text === "y" || text === "yes";
|
|
43
|
+
}
|
|
44
|
+
finally {
|
|
45
|
+
rl.close();
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
function buildPlan(args) {
|
|
49
|
+
const screenshotsDir = resolve(args.projectRoot, ".apex-auditor", "screenshots");
|
|
50
|
+
return [{ kind: "rm", path: screenshotsDir, existsByAssumption: true }];
|
|
51
|
+
}
|
|
52
|
+
async function executePlan(plan, dryRun) {
|
|
53
|
+
if (dryRun) {
|
|
54
|
+
return [];
|
|
55
|
+
}
|
|
56
|
+
const executed = [];
|
|
57
|
+
for (const action of plan) {
|
|
58
|
+
await rm(action.path, { recursive: true, force: true });
|
|
59
|
+
executed.push(action);
|
|
60
|
+
}
|
|
61
|
+
return executed;
|
|
62
|
+
}
|
|
63
|
+
export async function runClearScreenshotsCli(argv) {
|
|
64
|
+
const startedAtMs = Date.now();
|
|
65
|
+
const args = parseArgs(argv);
|
|
66
|
+
const planned = buildPlan(args);
|
|
67
|
+
if (!args.yes && process.stdin.isTTY) {
|
|
68
|
+
const targets = planned.map((p) => p.path).join("\n");
|
|
69
|
+
const ok = await confirmPrompt(`This will remove:\n${targets}\nContinue? (y/N) `);
|
|
70
|
+
if (!ok) {
|
|
71
|
+
console.log("Cancelled.");
|
|
72
|
+
return;
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
const executed = await executePlan(planned, args.dryRun);
|
|
76
|
+
const completedAtMs = Date.now();
|
|
77
|
+
const report = {
|
|
78
|
+
meta: {
|
|
79
|
+
projectRoot: args.projectRoot,
|
|
80
|
+
dryRun: args.dryRun,
|
|
81
|
+
startedAt: new Date(startedAtMs).toISOString(),
|
|
82
|
+
completedAt: new Date(completedAtMs).toISOString(),
|
|
83
|
+
elapsedMs: completedAtMs - startedAtMs,
|
|
84
|
+
},
|
|
85
|
+
planned,
|
|
86
|
+
executed,
|
|
87
|
+
};
|
|
88
|
+
if (args.jsonOutput) {
|
|
89
|
+
console.log(JSON.stringify(report, null, 2));
|
|
90
|
+
return;
|
|
91
|
+
}
|
|
92
|
+
if (args.dryRun) {
|
|
93
|
+
console.log(`Planned removals: ${planned.length} (dry-run).`);
|
|
94
|
+
return;
|
|
95
|
+
}
|
|
96
|
+
console.log(`Removed: ${executed.length}/${planned.length}.`);
|
|
97
|
+
}
|