sitelens 0.1.0 → 0.1.1
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 +1 -1
- package/dist/cli.js +44 -31
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -6,7 +6,7 @@ A website audit anyone can understand. One command checks performance, SEO, acce
|
|
|
6
6
|
npx sitelens
|
|
7
7
|
```
|
|
8
8
|
|
|
9
|
-
On its own, sitelens asks for the report language, the website address and the audit mode; pick with the arrow keys. To skip the questions, give the address and options straight away:
|
|
9
|
+
On its own, sitelens asks for the report language, the website address and the audit mode; pick with the arrow keys. When the report is ready, sitelens prints its full path and opens it when you press Enter. To skip the questions, give the address and options straight away:
|
|
10
10
|
|
|
11
11
|
```sh
|
|
12
12
|
npx sitelens https://yourwebsite.com --lang en --out report.pdf
|
package/dist/cli.js
CHANGED
|
@@ -607,7 +607,7 @@ var require_boolbase = __commonJS({
|
|
|
607
607
|
import { spawn, spawnSync } from "node:child_process";
|
|
608
608
|
import { writeFileSync } from "node:fs";
|
|
609
609
|
import { createRequire } from "node:module";
|
|
610
|
-
import { dirname, join as join2,
|
|
610
|
+
import { dirname, join as join2, resolve } from "node:path";
|
|
611
611
|
|
|
612
612
|
// ../collect-node/src/browser.ts
|
|
613
613
|
import { existsSync } from "node:fs";
|
|
@@ -2364,10 +2364,10 @@ function compareDocumentPosition(nodeA, nodeB) {
|
|
|
2364
2364
|
function uniqueSort(nodes) {
|
|
2365
2365
|
nodes = nodes.filter((node, i, arr) => !arr.includes(node, i + 1));
|
|
2366
2366
|
nodes.sort((a, b) => {
|
|
2367
|
-
const
|
|
2368
|
-
if (
|
|
2367
|
+
const relative = compareDocumentPosition(a, b);
|
|
2368
|
+
if (relative & DocumentPosition.PRECEDING) {
|
|
2369
2369
|
return -1;
|
|
2370
|
-
} else if (
|
|
2370
|
+
} else if (relative & DocumentPosition.FOLLOWING) {
|
|
2371
2371
|
return 1;
|
|
2372
2372
|
}
|
|
2373
2373
|
return 0;
|
|
@@ -7200,16 +7200,16 @@ var thresholds = {
|
|
|
7200
7200
|
cls: { good: 0.1, poor: 0.25 },
|
|
7201
7201
|
// Lab data has no INP; Total Blocking Time stands in for it with Lighthouse's own bands
|
|
7202
7202
|
tbt: { good: 200, poor: 600 },
|
|
7203
|
-
//
|
|
7203
|
+
// web.dev calls TTFB above 0.8 s "needs improvement"
|
|
7204
7204
|
ttfb: { poor: 800 },
|
|
7205
|
-
//
|
|
7205
|
+
// No standard exists for page weight; these bands are the owner's call (25.10.2026)
|
|
7206
7206
|
pageWeight: { minor: 3e6, important: 5e6 },
|
|
7207
7207
|
// Savings worth reporting, in bytes and milliseconds
|
|
7208
7208
|
imageSavings: 1e5,
|
|
7209
7209
|
renderBlockingMs: 300,
|
|
7210
7210
|
title: { min: 30, max: 60 },
|
|
7211
7211
|
description: { max: 160 },
|
|
7212
|
-
//
|
|
7212
|
+
// ACME clients such as certbot renew 30 days before expiry, so under 14 days usually means renewal failed
|
|
7213
7213
|
certificateWarningDays: 14,
|
|
7214
7214
|
hstsMinMaxAge: 15552e3,
|
|
7215
7215
|
thinTextLength: 300
|
|
@@ -12033,6 +12033,7 @@ Przyk\u0142ad:
|
|
|
12033
12033
|
warnings: (count) => `${count} ${plural(count, ["element nie da\u0142 si\u0119 sprawdzi\u0107", "elementy nie da\u0142y si\u0119 sprawdzi\u0107", "element\xF3w nie da\u0142o si\u0119 sprawdzi\u0107"], "pl")}; szczeg\xF3\u0142y w za\u0142\u0105czniku raportu.`,
|
|
12034
12034
|
failUnder: (score, limit) => `Wynik ${score} jest ni\u017Cszy ni\u017C wymagane ${limit} (--fail-under).`,
|
|
12035
12035
|
optionLater: (flag) => `Opcja ${flag} b\u0119dzie dost\u0119pna w kolejnej wersji. Audyt dzia\u0142a bez niej.`,
|
|
12036
|
+
openKey: "Naci\u015Bnij Enter, \u017Ceby otworzy\u0107 raport (Esc ko\u0144czy).",
|
|
12036
12037
|
wizard: {
|
|
12037
12038
|
language: "J\u0119zyk raportu",
|
|
12038
12039
|
address: "Adres strony",
|
|
@@ -12044,9 +12045,6 @@ Przyk\u0142ad:
|
|
|
12044
12045
|
standard: { label: "Standardowy", hint: (pages) => `do ${pages} podstron` },
|
|
12045
12046
|
thorough: { label: "Dok\u0142adny", hint: (pages) => `do ${pages} podstron, trwa d\u0142u\u017Cej` }
|
|
12046
12047
|
},
|
|
12047
|
-
open: "Otworzy\u0107 raport?",
|
|
12048
|
-
yes: "Tak",
|
|
12049
|
-
no: "Nie",
|
|
12050
12048
|
openFailed: (path) => `Nie uda\u0142o si\u0119 otworzy\u0107 raportu. Plik jest tutaj: ${path}`
|
|
12051
12049
|
},
|
|
12052
12050
|
errors: {
|
|
@@ -12107,6 +12105,7 @@ Example:
|
|
|
12107
12105
|
warnings: (count) => `${count} ${count === 1 ? "item" : "items"} could not be checked; details are in the report appendix.`,
|
|
12108
12106
|
failUnder: (score, limit) => `Score ${score} is below the required ${limit} (--fail-under).`,
|
|
12109
12107
|
optionLater: (flag) => `The ${flag} option arrives in a later version. The audit works without it.`,
|
|
12108
|
+
openKey: "Press Enter to open the report (Esc to quit).",
|
|
12110
12109
|
wizard: {
|
|
12111
12110
|
language: "Report language",
|
|
12112
12111
|
address: "Website address",
|
|
@@ -12118,9 +12117,6 @@ Example:
|
|
|
12118
12117
|
standard: { label: "Standard", hint: (pages) => `up to ${pages} pages` },
|
|
12119
12118
|
thorough: { label: "Thorough", hint: (pages) => `up to ${pages} pages, takes longer` }
|
|
12120
12119
|
},
|
|
12121
|
-
open: "Open the report?",
|
|
12122
|
-
yes: "Yes",
|
|
12123
|
-
no: "No",
|
|
12124
12120
|
openFailed: (path) => `Could not open the report. The file is here: ${path}`
|
|
12125
12121
|
},
|
|
12126
12122
|
errors: {
|
|
@@ -12225,9 +12221,19 @@ import { createInterface } from "node:readline/promises";
|
|
|
12225
12221
|
import { stripVTControlCharacters } from "node:util";
|
|
12226
12222
|
|
|
12227
12223
|
// src/ui.ts
|
|
12224
|
+
import { pathToFileURL } from "node:url";
|
|
12228
12225
|
import { styleText } from "node:util";
|
|
12229
12226
|
var paint = (style, text3, stream = process.stdout) => styleText(style, text3, { stream });
|
|
12230
12227
|
var FRAMES = ["\u280B", "\u2819", "\u2839", "\u2838", "\u283C", "\u2834", "\u2826", "\u2827", "\u2807", "\u280F"];
|
|
12228
|
+
function linksWork(stream) {
|
|
12229
|
+
const env = process.env;
|
|
12230
|
+
if (!stream.isTTY || env.CI) return false;
|
|
12231
|
+
if (env.WT_SESSION || Number(env.VTE_VERSION) >= 5e3) return true;
|
|
12232
|
+
return ["vscode", "iTerm.app", "WezTerm", "ghostty"].includes(env.TERM_PROGRAM ?? "");
|
|
12233
|
+
}
|
|
12234
|
+
function fileLink(path, stream = process.stdout) {
|
|
12235
|
+
return linksWork(stream) ? `\x1B]8;;${pathToFileURL(path).href}\x1B\\${path}\x1B]8;;\x1B\\` : path;
|
|
12236
|
+
}
|
|
12231
12237
|
function scoreStyle(score) {
|
|
12232
12238
|
return score >= 90 ? "green" : score >= 50 ? "yellow" : "red";
|
|
12233
12239
|
}
|
|
@@ -12343,6 +12349,23 @@ function select2(message, choices, { initial = 0, done = (choice) => `${message}
|
|
|
12343
12349
|
draw();
|
|
12344
12350
|
});
|
|
12345
12351
|
}
|
|
12352
|
+
function pressEnter(message, { io = terminal } = {}) {
|
|
12353
|
+
const { input, output } = io;
|
|
12354
|
+
return new Promise((resolve2) => {
|
|
12355
|
+
const onKey = (_text, key = {}) => {
|
|
12356
|
+
input.off("keypress", onKey);
|
|
12357
|
+
input.setRawMode(false);
|
|
12358
|
+
input.pause();
|
|
12359
|
+
output.write("\n");
|
|
12360
|
+
resolve2(key.name === "return" || key.name === "enter");
|
|
12361
|
+
};
|
|
12362
|
+
output.write(`${paint("cyan", "\u203A", output)} ${message} `);
|
|
12363
|
+
emitKeypressEvents(input);
|
|
12364
|
+
input.setRawMode(true);
|
|
12365
|
+
input.resume();
|
|
12366
|
+
input.on("keypress", onKey);
|
|
12367
|
+
});
|
|
12368
|
+
}
|
|
12346
12369
|
async function ask(message, check, { hint = "", io = terminal } = {}) {
|
|
12347
12370
|
const { input, output } = io;
|
|
12348
12371
|
const rl = createInterface({ input, output, terminal: true });
|
|
@@ -12371,7 +12394,7 @@ async function ask(message, check, { hint = "", io = terminal } = {}) {
|
|
|
12371
12394
|
}
|
|
12372
12395
|
|
|
12373
12396
|
// src/cli.ts
|
|
12374
|
-
var VERSION = true ? "0.1.
|
|
12397
|
+
var VERSION = true ? "0.1.1" : "0.0.0-dev";
|
|
12375
12398
|
var NODE_NEEDED = "22.19.0";
|
|
12376
12399
|
var MODES = [
|
|
12377
12400
|
{ mode: "quick", pages: 1 },
|
|
@@ -12470,19 +12493,7 @@ function openReport(path, m) {
|
|
|
12470
12493
|
}
|
|
12471
12494
|
async function offerToOpen(path, m) {
|
|
12472
12495
|
console.log("");
|
|
12473
|
-
|
|
12474
|
-
const open = await select2(
|
|
12475
|
-
m.wizard.open,
|
|
12476
|
-
[
|
|
12477
|
-
{ label: m.wizard.yes, value: true },
|
|
12478
|
-
{ label: m.wizard.no, value: false }
|
|
12479
|
-
],
|
|
12480
|
-
{ done: (choice) => `${m.wizard.open} ${choice.label}` }
|
|
12481
|
-
);
|
|
12482
|
-
if (open) openReport(path, m);
|
|
12483
|
-
} catch (error) {
|
|
12484
|
-
if (!(error instanceof PromptCancelled)) throw error;
|
|
12485
|
-
}
|
|
12496
|
+
if (await pressEnter(m.openKey)) openReport(path, m);
|
|
12486
12497
|
}
|
|
12487
12498
|
async function audit(options, outPath, m) {
|
|
12488
12499
|
const browserInfo = findBrowser();
|
|
@@ -12541,11 +12552,12 @@ async function audit(options, outPath, m) {
|
|
|
12541
12552
|
}
|
|
12542
12553
|
progress.stop();
|
|
12543
12554
|
printScores(scores.categories, scores.overall, m);
|
|
12544
|
-
|
|
12545
|
-
|
|
12555
|
+
console.log(`${paint("green", "\u2713")} ${m.saved}:
|
|
12556
|
+
${paint("cyan", fileLink(outPath))}`);
|
|
12546
12557
|
if (options.json)
|
|
12547
12558
|
console.log(
|
|
12548
|
-
`${paint("green", "\u2713")} ${
|
|
12559
|
+
`${paint("green", "\u2713")} ${m.savedJson}:
|
|
12560
|
+
${paint("cyan", fileLink(outPath.replace(/\.pdf$/i, "") + ".json"))}`
|
|
12549
12561
|
);
|
|
12550
12562
|
if (warnings.length) console.log(paint("dim", m.warnings(warnings.length)));
|
|
12551
12563
|
if (options.failUnder !== void 0 && scores.overall !== null && scores.overall < options.failUnder) {
|
|
@@ -12611,7 +12623,8 @@ async function main(argv) {
|
|
|
12611
12623
|
console.error(m.errors.unexpected(error instanceof Error ? error.message : String(error)));
|
|
12612
12624
|
return 4 /* Environment */;
|
|
12613
12625
|
}
|
|
12614
|
-
if (
|
|
12626
|
+
if ((exit === 0 /* Ok */ || exit === 1 /* BelowThreshold */) && canPrompt() && !process.env.CI)
|
|
12627
|
+
await offerToOpen(outPath, m);
|
|
12615
12628
|
return exit;
|
|
12616
12629
|
}
|
|
12617
12630
|
process.exitCode = await main(process.argv.slice(2));
|