@goflag/cli 0.2.11 → 0.2.13

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/dist/cli.js CHANGED
@@ -9,11 +9,12 @@ import {
9
9
  SITE_PROSE_RULES,
10
10
  SITE_RULES,
11
11
  exitCode,
12
+ renderPreview,
12
13
  renderSummaryTerminal,
13
14
  renderTerminal,
14
15
  runAudit,
15
16
  summarize
16
- } from "./chunk-CWEJ6EXT.js";
17
+ } from "./chunk-57NVXEJS.js";
17
18
 
18
19
  // src/report/diff.ts
19
20
  function collectFindings(report) {
@@ -313,7 +314,9 @@ var FLAGS = [
313
314
  group: "output",
314
315
  help: [
315
316
  "Roll findings up (dedup by link/rule/code). Pairs",
316
- "with --json for a compact, agent-friendly payload."
317
+ "with --json for a compact, agent-friendly payload.",
318
+ "Not available with --baseline: there the diff is the",
319
+ "answer, and --report writes the full report."
317
320
  ],
318
321
  takesValue: false,
319
322
  apply: ({ parsed }) => {
@@ -754,6 +757,16 @@ var COMMANDS = [
754
757
  "table this help is rendered from, so the two cannot",
755
758
  "disagree."
756
759
  ]
760
+ },
761
+ {
762
+ name: "preview",
763
+ usage: "preview <url>",
764
+ help: [
765
+ "Write .goflag/preview.html \u2014 the page's share cards",
766
+ "as Google, Open Graph, X, LinkedIn, Slack, Discord",
767
+ "and WhatsApp make them, each with the rigor of its",
768
+ "source. Never gates: exits 0 unless the run failed."
769
+ ]
757
770
  }
758
771
  ];
759
772
  var DESCRIPTION_COLUMN = 25;
@@ -772,8 +785,9 @@ function renderHelp() {
772
785
  ];
773
786
  for (const command of COMMANDS) {
774
787
  const pad = " ".repeat(28);
788
+ const label = command.usage ?? command.name;
775
789
  command.help.forEach((line, i) => {
776
- lines.push(i === 0 ? ` goflag ${command.name.padEnd(19)}${line}` : `${pad}${line}`);
790
+ lines.push(i === 0 ? ` goflag ${label.padEnd(19)}${line}` : `${pad}${line}`);
777
791
  });
778
792
  }
779
793
  lines.push("", "Options:");
@@ -787,6 +801,9 @@ function renderHelp() {
787
801
  // src/cli-args.ts
788
802
  var HELP = renderHelp();
789
803
  var COMMAND_NAMES = COMMANDS.map((c) => c.name);
804
+ function isCommand(arg) {
805
+ return COMMAND_NAMES.includes(arg);
806
+ }
790
807
  function parseArgs(argv) {
791
808
  const parsed = {
792
809
  json: false,
@@ -819,10 +836,25 @@ function parseArgs(argv) {
819
836
  continue;
820
837
  }
821
838
  if (arg && arg.startsWith("-")) throw new Error(`unknown option: ${arg}`);
822
- if (arg && COMMAND_NAMES.includes(arg) && i === 0) parsed.command = arg;
839
+ if (arg && isCommand(arg) && !parsed.url && !parsed.command) parsed.command = arg;
823
840
  else if (arg && !parsed.url) parsed.url = arg;
824
841
  else if (arg) throw new Error(`unexpected argument: ${arg}`);
825
842
  }
843
+ if (parsed.command === "preview") {
844
+ const inert = [
845
+ parsed.json && "--json",
846
+ parsed.summary && "--summary",
847
+ parsed.baseline && "--baseline",
848
+ parsed.updateBaseline && "--update-baseline",
849
+ parsed.regressionsOnly && "--regressions-only",
850
+ parsed.maxDebt !== void 0 && "--max-debt"
851
+ ].filter((flag) => typeof flag === "string");
852
+ if (inert.length > 0) {
853
+ throw new Error(
854
+ `preview renders what the crawl saw, it does not gate or reformat, so ${inert.join(", ")} would change nothing: drop them, or ask for the JSON with --report <file>`
855
+ );
856
+ }
857
+ }
826
858
  if (parsed.updateBaseline && !parsed.baseline) {
827
859
  throw new Error("--update-baseline needs a --baseline <file> to write to");
828
860
  }
@@ -834,6 +866,11 @@ function parseArgs(argv) {
834
866
  if (parsed.regressionsOnly && !parsed.baseline) {
835
867
  throw new Error("--regressions-only needs a --baseline <file> to compare against");
836
868
  }
869
+ if (parsed.summary && parsed.baseline) {
870
+ throw new Error(
871
+ "--summary cannot summarise a diff, and --baseline prints the diff: drop --summary, or use --report <file> to keep the full report"
872
+ );
873
+ }
837
874
  return parsed;
838
875
  }
839
876
 
@@ -1370,13 +1407,17 @@ async function readVersion() {
1370
1407
  return "0.0.0";
1371
1408
  }
1372
1409
  }
1373
- async function writeJson(path, value) {
1410
+ async function writeText(path, contents) {
1374
1411
  const { mkdirSync, writeFileSync } = await import("fs");
1375
1412
  const { dirname } = await import("path");
1376
1413
  mkdirSync(dirname(path), { recursive: true });
1377
- writeFileSync(path, `${JSON.stringify(value, null, 2)}
1378
- `, "utf8");
1414
+ writeFileSync(path, contents, "utf8");
1415
+ }
1416
+ async function writeJson(path, value) {
1417
+ await writeText(path, `${JSON.stringify(value, null, 2)}
1418
+ `);
1379
1419
  }
1420
+ var PREVIEW_PATH = ".goflag/preview.html";
1380
1421
  async function main() {
1381
1422
  let args;
1382
1423
  try {
@@ -1433,7 +1474,14 @@ ${HELP}
1433
1474
  });
1434
1475
  }
1435
1476
  logger.note(`goflag: auditing ${args.url} \u2026`);
1436
- report = await runAudit(args.url, { ...args.options, onProgress: logger.onProgress });
1477
+ report = await runAudit(args.url, {
1478
+ ...args.options,
1479
+ // The preview is drawn from what the pages declared, and only this
1480
+ // section carries that. Nothing else asks for it, so nothing else pays
1481
+ // for it.
1482
+ ...args.command === "preview" ? { extractions: true } : {},
1483
+ onProgress: logger.onProgress
1484
+ });
1437
1485
  logger.stop();
1438
1486
  } catch (err) {
1439
1487
  logger.stop();
@@ -1453,6 +1501,22 @@ goflag: retry, or pass --no-sitemap to audit by crawling on purpose.
1453
1501
  );
1454
1502
  return 2;
1455
1503
  }
1504
+ if (args.command === "preview") {
1505
+ if (args.report) {
1506
+ await writeJson(args.report, report);
1507
+ process.stderr.write(`goflag: report written to ${args.report}
1508
+ `);
1509
+ }
1510
+ await writeText(PREVIEW_PATH, renderPreview(report));
1511
+ const pages = report.extractions?.length ?? 0;
1512
+ process.stderr.write(
1513
+ `goflag: preview written to ${PREVIEW_PATH} \u2014 ${pages} page${pages === 1 ? "" : "s"}
1514
+ `
1515
+ );
1516
+ process.stdout.write(`${PREVIEW_PATH}
1517
+ `);
1518
+ return 0;
1519
+ }
1456
1520
  if (args.baseline) {
1457
1521
  const { existsSync, readFileSync } = await import("fs");
1458
1522
  if (existsSync(args.baseline) || !args.updateBaseline) {
@@ -1468,6 +1532,11 @@ goflag: retry, or pass --no-sitemap to audit by crawling on purpose.
1468
1532
  }
1469
1533
  }
1470
1534
  }
1535
+ if (args.report) {
1536
+ await writeJson(args.report, report);
1537
+ process.stderr.write(`goflag: report written to ${args.report}
1538
+ `);
1539
+ }
1471
1540
  if (args.updateBaseline && args.baseline) {
1472
1541
  await writeJson(args.baseline, report);
1473
1542
  const total2 = totalFindings(report);
@@ -1493,11 +1562,6 @@ goflag: retry, or pass --no-sitemap to audit by crawling on purpose.
1493
1562
  );
1494
1563
  return 0;
1495
1564
  }
1496
- if (args.report) {
1497
- await writeJson(args.report, report);
1498
- process.stderr.write(`goflag: report written to ${args.report}
1499
- `);
1500
- }
1501
1565
  if (report.diff && !args.json) {
1502
1566
  process.stdout.write(`${renderDiffTerminal(report.diff, { color: args.color })}
1503
1567
  `);
@@ -1537,9 +1601,25 @@ goflag: retry, or pass --no-sitemap to audit by crawling on purpose.
1537
1601
  }
1538
1602
  return exitCode(report, args.failOn);
1539
1603
  }
1540
- main().then((code) => process.exit(code)).catch((err) => {
1604
+ function flush(stream) {
1605
+ return new Promise((resolve) => {
1606
+ if (stream.writableEnded || stream.destroyed) return resolve();
1607
+ stream.write("", () => resolve());
1608
+ });
1609
+ }
1610
+ var undelivered = false;
1611
+ for (const stream of [process.stdout, process.stderr]) {
1612
+ stream.on("error", (err) => {
1613
+ if (err.code !== "EPIPE") undelivered = true;
1614
+ });
1615
+ }
1616
+ main().then(async (code) => {
1617
+ await Promise.all([flush(process.stdout), flush(process.stderr)]);
1618
+ process.exit(undelivered ? 2 : code);
1619
+ }).catch(async (err) => {
1541
1620
  process.stderr.write(`goflag: unexpected error: ${err.stack ?? err}
1542
1621
  `);
1622
+ await flush(process.stderr);
1543
1623
  process.exit(2);
1544
1624
  });
1545
1625
  //# sourceMappingURL=cli.js.map