apex-auditor 0.2.6 → 0.2.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 CHANGED
@@ -2,144 +2,90 @@
2
2
 
3
3
  ApexAuditor is a small, framework-agnostic Lighthouse runner that gives you **fast, structured insights** across multiple pages and devices.
4
4
 
5
- It is designed to:
5
+ It focuses on:
6
6
 
7
- - **Run anywhere**: attach to an existing Chrome instance (remote debugging) on Windows, macOS, or Linux.
8
- - **Work with any web stack**: Next.js, Vite, Rails, static sites, etc. – as long as there is an HTTP server.
9
- - **Summarize multiple pages at once**: homepage, blog, auth, search, and more.
10
- - **Output developer-friendly reports**: one Markdown table + JSON, ready to paste into PRs or chat.
11
-
12
- > V1 focuses on a solid, single-project core. Route auto-detection and monorepo orchestration will land in later versions.
7
+ - **Multi-page, multi-device audits**: run Lighthouse across your key flows in one shot.
8
+ - **Framework flexibility**: works with any stack that serves HTTP (Next.js, Remix, Vite/React, SvelteKit, Rails, static sites, etc.).
9
+ - **Smart route discovery**: auto-detects routes for Next.js (App/Pages), Remix, SvelteKit, and can crawl generic SPAs.
10
+ - **Developer-friendly reports**: readable console output, Markdown tables, and JSON summaries for CI.
13
11
 
14
12
  ---
15
13
 
16
- ## Quick start (single project)
14
+ ## Example output
17
15
 
18
- ### 1. Install dependencies
16
+ Terminal summary:
19
17
 
20
- From the `apex-auditor` directory:
18
+ ![Example terminal output 1](./public/example_output_1.png)
21
19
 
22
- ```bash
23
- pnpm install
24
- ```
20
+ ![Example terminal output 2](./public/example_output_2.png)
25
21
 
26
- ### 2. Start your web app
22
+ Wizard route selection:
27
23
 
28
- In your application repo (for example, a Next.js app running on port 3000):
24
+ ![Wizard screenshot](./public/wizard_1.png)
29
25
 
30
- ```bash
31
- pnpm start
32
- # or: pnpm dev, npm run dev, etc.
33
- ```
34
-
35
- Make sure the app is reachable at the `baseUrl` you will configure (default example: `http://localhost:3000`).
26
+ ---
36
27
 
37
- ### 3. Start Chrome with remote debugging
28
+ ## Installation
38
29
 
39
- ApexAuditor connects to an existing Chrome instance instead of launching its own. Start Chrome once with a debugging port (example for Windows):
30
+ Install as a dev dependency (recommended):
40
31
 
41
32
  ```bash
42
- "C:\\Program Files\\Google\\Chrome\\Application\\chrome.exe" \
43
- --remote-debugging-port=9222 \
44
- --user-data-dir="%LOCALAPPDATA%\\ChromeApex"
33
+ pnpm add -D apex-auditor
34
+ # or
35
+ npm install --save-dev apex-auditor
45
36
  ```
46
37
 
47
- On macOS or Linux the flags are the same; only the Chrome path changes.
48
-
49
- ### 4. Configure pages (wizard-friendly)
50
-
51
- Run the guided wizard to scaffold `apex.config.json` and optionally auto-discover routes:
38
+ You can also run it without installing by using your package manager's "dlx"/"npx" style command, for example:
52
39
 
53
40
  ```bash
54
- pnpm wizard
41
+ pnpm dlx apex-auditor@latest wizard
55
42
  ```
56
43
 
57
- The wizard asks for the base URL, optional query string, desired Chrome port, run count, and can crawl popular frameworks (Next.js app/pages) to prefill routes before you fine-tune the list. You can still edit the file manually afterwards:
58
-
59
- ```jsonc
60
- {
61
- "baseUrl": "http://localhost:3000",
62
- "query": "?lhci=1",
63
- "chromePort": 9222,
64
- "runs": 1,
65
- "pages": [
66
- { "path": "/", "label": "home", "devices": ["mobile", "desktop"] },
67
- { "path": "/blog", "label": "blog", "devices": ["mobile", "desktop"] },
68
- { "path": "/contact", "label": "contact", "devices": ["mobile"] }
69
- ]
70
- }
71
- ```
44
+ ---
72
45
 
73
- > Tip: rerun `pnpm wizard -- --config custom/path.json` to regenerate configs for multiple projects, or pass a different `--project-root` when prompted to detect routes from another app.
46
+ ## Common commands
74
47
 
75
- - `baseUrl`: root URL of your running app.
76
- - `query` (optional): query string appended to every URL (for example `?lhci=1` to disable analytics).
77
- - `chromePort` (optional): remote debugging port (defaults to `9222`).
78
- - `runs` (optional): how many times to run Lighthouse per page/device (results are averaged).
79
- - `pages`: list of paths and devices to audit.
48
+ All commands are available as a CLI named `apex-auditor` once installed.
80
49
 
81
- ### 5. Run an audit
50
+ ### Quickstart (auto-detect routes and run a one-off audit)
82
51
 
83
52
  ```bash
84
- pnpm audit
53
+ apex-auditor quickstart --base-url http://localhost:3000
85
54
  ```
86
55
 
87
- This will:
88
-
89
- - Run Lighthouse for every `page × device` defined in `apex.config.json`.
90
- - Write structured results to `.apex-auditor/summary.json`.
91
- - Write a human-readable table to `.apex-auditor/summary.md`.
92
- - Print the same table to the terminal.
56
+ ### Wizard (interactive config with route auto-detection)
93
57
 
94
- Example output:
95
-
96
- ```text
97
- | Label | Path | Device | P | A | BP | SEO | LCP (s) | FCP (s) | TBT (ms) | CLS | Top issues |
98
- |-------|------|---------|----|----|----|-----|---------|---------|----------|-------|-----------|
99
- | home | / | mobile | 95 |100 |100 |100 | 2.9 | 0.9 | 160 | 0.002 | render-blocking-resources (140ms); unused-javascript (55KB) |
100
- | home | / | desktop |100 |100 |100 |100 | 0.6 | 0.4 | 0 | 0.016 | unused-javascript (55KB) |
58
+ ```bash
59
+ apex-auditor wizard
101
60
  ```
102
61
 
103
- You can paste this table directly into PRs, tickets, or chat to discuss optimizations.
62
+ The wizard can detect routes for:
104
63
 
105
- ---
64
+ - Next.js (App Router / Pages Router)
65
+ - Remix
66
+ - SvelteKit
67
+ - Single Page Apps (Vite/CRA/etc., via HTML crawl)
68
+
69
+ ### Audit (run using an existing config)
106
70
 
107
- ## Configuration reference (V1)
108
-
109
- ```ts
110
- // apex.config.json (TypeScript shape)
111
- interface ApexPageConfig {
112
- path: string; // URL path, must start with "/"
113
- label: string; // short label for reports
114
- devices: ("mobile" | "desktop")[];
115
- }
116
-
117
- interface ApexConfig {
118
- baseUrl: string; // e.g. "http://localhost:3000"
119
- query?: string; // e.g. "?lhci=1"
120
- chromePort?: number; // default: 9222
121
- runs?: number; // default: 1
122
- pages: ApexPageConfig[];
123
- }
71
+ ```bash
72
+ apex-auditor audit --config apex.config.json
124
73
  ```
125
74
 
126
- Future versions will add:
75
+ Useful flags:
127
76
 
128
- - Automatic route discovery (for example, from Next.js `app/` routes or a crawler).
129
- - Workspace-level configs for monorepos.
130
- - CI integration recipes and HTML dashboards.
77
+ - `--ci` enable CI mode with budgets and non-zero exit codes.
78
+ - `--no-color` / `--color` – control ANSI colours in console output.
79
+ - `--log-level <silent|error|info|verbose>` override Lighthouse log level.
131
80
 
132
81
  ---
133
82
 
134
- ## Code structure (V1)
135
-
136
- The codebase is intentionally small and modular:
83
+ ## Further documentation
137
84
 
138
- - `src/types.ts` shared type definitions for config and results.
139
- - `src/config.ts` – loads and validates `apex.config.json`.
140
- - `src/lighthouse-runner.ts` – runs Lighthouse for each page/device and normalises results.
141
- - `src/cli.ts` – CLI entry point; orchestrates config + runner, writes JSON/Markdown.
85
+ For detailed guides, configuration options, and CI examples, see the `docs/` directory:
142
86
 
143
- All public modules use explicit TypeScript types and are written to be reusable in future integrations (route detectors, monorepo orchestration, CI adapters).
87
+ - `docs/getting-started.md` installation, quickstart, wizard, and audit flows.
88
+ - `docs/configuration-and-routes.md` – `apex.config.json` schema and route detection details.
89
+ - `docs/cli-and-ci.md` – CLI flags, CI mode, budgets, and example workflows.
144
90
 
145
- See `ROADMAP.md` for planned features and phases.
91
+ For the longer-term vision and planned features, see `ROADMAP.md`.
@@ -6,11 +6,13 @@ const DEFAULT_LIMIT = 200;
6
6
  const SOURCE_NEXT_APP = "next-app";
7
7
  const SOURCE_NEXT_PAGES = "next-pages";
8
8
  const SOURCE_REMIX = "remix-routes";
9
+ const SOURCE_SVELTEKIT = "sveltekit-routes";
9
10
  const SOURCE_SPA = "spa-html";
10
11
  const ROUTE_DETECTORS = [
11
12
  createNextAppDetector(),
12
13
  createNextPagesDetector(),
13
14
  createRemixRoutesDetector(),
15
+ createSvelteKitRoutesDetector(),
14
16
  createSpaHtmlDetector(),
15
17
  ];
16
18
  export async function detectRoutes(options) {
@@ -60,6 +62,19 @@ function createNextAppDetector() {
60
62
  },
61
63
  };
62
64
  }
65
+ function createSvelteKitRoutesDetector() {
66
+ return {
67
+ id: SOURCE_SVELTEKIT,
68
+ canDetect: async (options) => {
69
+ const routesRoot = join(options.projectRoot, "src", "routes");
70
+ return pathExists(routesRoot);
71
+ },
72
+ detect: async (options) => {
73
+ const routesRoot = join(options.projectRoot, "src", "routes");
74
+ return detectSvelteKitRoutes(routesRoot, options.limit);
75
+ },
76
+ };
77
+ }
63
78
  function createNextPagesDetector() {
64
79
  return {
65
80
  id: SOURCE_NEXT_PAGES,
@@ -191,6 +206,10 @@ async function detectRemixRoutes(routesRoot, limit) {
191
206
  const files = await collectRouteFiles(routesRoot, limit, isRemixRouteFile);
192
207
  return files.map((file) => buildRoute(file, routesRoot, formatRemixRoutePath, SOURCE_REMIX));
193
208
  }
209
+ async function detectSvelteKitRoutes(routesRoot, limit) {
210
+ const files = await collectRouteFiles(routesRoot, limit, isSvelteKitPageFile);
211
+ return files.map((file) => buildRoute(file, routesRoot, formatSvelteKitRoutePath, SOURCE_SVELTEKIT));
212
+ }
194
213
  async function detectSpaRoutes(projectRoot, limit) {
195
214
  const htmlPath = await findSpaHtml(projectRoot);
196
215
  if (!htmlPath) {
@@ -270,6 +289,17 @@ function isRemixRouteFile(entry, relativePath) {
270
289
  }
271
290
  return !posixPath.split("/").some((segment) => segment.startsWith("__"));
272
291
  }
292
+ function isSvelteKitPageFile(entry, relativePath) {
293
+ if (!entry.isFile()) {
294
+ return false;
295
+ }
296
+ const posixPath = normalisePath(relativePath);
297
+ return (posixPath.endsWith("+page.svelte") ||
298
+ posixPath.endsWith("+page.ts") ||
299
+ posixPath.endsWith("+page.js") ||
300
+ posixPath.endsWith("+page.tsx") ||
301
+ posixPath.endsWith("+page.jsx"));
302
+ }
273
303
  function hasAllowedExtension(path) {
274
304
  return PAGE_EXTENSIONS.some((extension) => path.endsWith(extension));
275
305
  }
@@ -329,6 +359,28 @@ function formatRemixRoutePath(relativePath) {
329
359
  .filter((segment) => segment.length > 0);
330
360
  return parts.length === 0 ? "/" : normaliseRoute(parts.join("/"));
331
361
  }
362
+ function formatSvelteKitRoutePath(relativePath) {
363
+ const cleanPath = relativePath.replace(/\\/g, "/");
364
+ const withoutFile = cleanPath.replace(/\/?\+page\.[^/]+$/, "");
365
+ const segments = withoutFile.split("/").filter((segment) => segment.length > 0);
366
+ const parts = segments
367
+ .filter((segment) => !(segment.startsWith("(") && segment.endsWith(")")))
368
+ .map((segment) => {
369
+ if (segment.startsWith("[") && segment.endsWith("]")) {
370
+ const inner = segment.slice(1, -1);
371
+ const name = inner.replace(/^\.\.\./, "");
372
+ if (name.length === 0) {
373
+ return ":param";
374
+ }
375
+ return `:${name}`;
376
+ }
377
+ return segment;
378
+ });
379
+ if (parts.length === 0) {
380
+ return "/";
381
+ }
382
+ return normaliseRoute(parts.join("/"));
383
+ }
332
384
  function normaliseRoute(path) {
333
385
  const trimmed = path.replace(/^\/+/, "");
334
386
  if (trimmed.length === 0) {
@@ -9,6 +9,7 @@ const PROFILE_TO_DETECTOR = {
9
9
  "next-pages": "next-pages",
10
10
  spa: "spa-html",
11
11
  remix: "remix-routes",
12
+ sveltekit: "sveltekit-routes",
12
13
  custom: undefined,
13
14
  };
14
15
  const DEFAULT_BASE_URL = "http://localhost:3000";
@@ -25,6 +26,7 @@ const profileQuestion = {
25
26
  { title: "Next.js (App Router)", value: "next-app" },
26
27
  { title: "Next.js (Pages Router)", value: "next-pages" },
27
28
  { title: "Remix", value: "remix" },
29
+ { title: "SvelteKit", value: "sveltekit" },
28
30
  { title: "Single Page App (Vite/CRA/etc.)", value: "spa" },
29
31
  { title: "Custom/manual", value: "custom" },
30
32
  ],
@@ -113,6 +115,7 @@ const detectorChoiceQuestion = {
113
115
  { title: "Next.js (App Router)", value: "next-app" },
114
116
  { title: "Next.js (Pages Router)", value: "next-pages" },
115
117
  { title: "Remix", value: "remix-routes" },
118
+ { title: "SvelteKit", value: "sveltekit-routes" },
116
119
  { title: "SPA Crawl", value: "spa-html" },
117
120
  ],
118
121
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "apex-auditor",
3
- "version": "0.2.6",
3
+ "version": "0.2.8",
4
4
  "private": false,
5
5
  "description": "CLI to run structured Lighthouse audits (Performance, Accessibility, Best Practices, SEO) across routes.",
6
6
  "type": "module",