svelte-vitals 0.44.3 → 0.44.4

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/bin.js CHANGED
@@ -8,7 +8,7 @@ import {
8
8
  readPackageVersion,
9
9
  readPkg,
10
10
  run
11
- } from "./chunk-NIUYLAJK.js";
11
+ } from "./chunk-YY567AYV.js";
12
12
  import {
13
13
  consoleIO,
14
14
  parseCliArgs,
@@ -1486,15 +1486,15 @@ ${planText}` });
1486
1486
  }
1487
1487
  };
1488
1488
  }
1489
- async function runInstallCli(args) {
1489
+ async function runInstallCli(args, io = consoleIO) {
1490
1490
  const argv = parseInstallArgs(args);
1491
1491
  if (argv.help) {
1492
- console.log(INSTALL_HELP);
1492
+ io.log(INSTALL_HELP);
1493
1493
  return 0;
1494
1494
  }
1495
1495
  const { flags, warnings, errors } = resolveInstallArgs(argv);
1496
- for (const w of warnings) console.error(w);
1497
- for (const e of errors) console.error(e);
1496
+ for (const w of warnings) io.errorLog(w);
1497
+ for (const e of errors) io.errorLog(e);
1498
1498
  if (!flags) return 2;
1499
1499
  return runInstall(flags, realIO(), clackPrompts(), readPackageVersion());
1500
1500
  }
@@ -1722,7 +1722,7 @@ function runExplainCli(args, io = consoleIO) {
1722
1722
  return 0;
1723
1723
  }
1724
1724
 
1725
- // src/bin.ts
1725
+ // src/cli.ts
1726
1726
  var HELP = `svelte-vitals \u2014 a deterministic SvelteKit code-health scanner (SEO \xB7 performance \xB7 correctness \xB7 security \xB7 architecture)
1727
1727
 
1728
1728
  Usage:
@@ -1786,45 +1786,53 @@ var VERSION = readPackageVersion();
1786
1786
  function selectApp(apps) {
1787
1787
  return selectAppPrompt(apps, "Multiple SvelteKit apps found \u2014 which one should svelte-vitals analyze?");
1788
1788
  }
1789
- async function main() {
1790
- const rawArgs = process.argv.slice(2);
1791
- if (rawArgs[0] === "docs") {
1792
- const { runDocsCli } = await import("./cli-L2HHOZDN.js");
1793
- process.exitCode = runDocsCli(rawArgs.slice(1));
1794
- return;
1795
- }
1796
- if (rawArgs[0] === "explain") {
1797
- process.exitCode = runExplainCli(rawArgs.slice(1));
1798
- return;
1799
- }
1800
- if (rawArgs[0] === "install") {
1801
- const code2 = await runInstallCli(rawArgs.slice(1));
1802
- process.exit(code2);
1803
- }
1804
- if (rawArgs[0] === "ci") {
1805
- const code2 = await runCiCli(rawArgs.slice(1));
1806
- process.exit(code2);
1807
- }
1808
- const argv = parseRunArgs(rawArgs);
1809
- if (argv.help) {
1810
- console.log(HELP);
1811
- return;
1812
- }
1813
- if (argv.version) {
1814
- console.log(`${VERSION} (core ${readCoreVersion()})`);
1815
- console.error("svelte-vitals: run `svelte-vitals docs list` for the bundled guides.");
1816
- return;
1817
- }
1818
- const { options, warnings, errors, minHealth } = resolveArgs(argv);
1819
- for (const w of warnings) console.error(w);
1820
- for (const e of errors) console.error(e);
1821
- if (!options) process.exit(2);
1789
+ async function runCli(argv, io = consoleIO) {
1790
+ if (argv[0] === "docs") {
1791
+ const { runDocsCli } = await import("./cli-KH6FL5V7.js");
1792
+ return { code: runDocsCli(argv.slice(1), io), exit: "natural" };
1793
+ }
1794
+ if (argv[0] === "explain") {
1795
+ return { code: runExplainCli(argv.slice(1), io), exit: "natural" };
1796
+ }
1797
+ if (argv[0] === "install") {
1798
+ return { code: await runInstallCli(argv.slice(1), io), exit: "immediate" };
1799
+ }
1800
+ if (argv[0] === "ci") {
1801
+ const code2 = await runCiCli(argv.slice(1), { ...realIO(), log: io.log, errorLog: io.errorLog });
1802
+ return { code: code2, exit: "immediate" };
1803
+ }
1804
+ const parsed = parseRunArgs(argv);
1805
+ if (parsed.help) {
1806
+ io.log(HELP);
1807
+ return { code: 0, exit: "natural" };
1808
+ }
1809
+ if (parsed.version) {
1810
+ io.log(`${VERSION} (core ${readCoreVersion()})`);
1811
+ io.errorLog("svelte-vitals: run `svelte-vitals docs list` for the bundled guides.");
1812
+ return { code: 0, exit: "natural" };
1813
+ }
1814
+ const { options, warnings, errors, minHealth } = resolveArgs(parsed);
1815
+ for (const w of warnings) io.errorLog(w);
1816
+ for (const e of errors) io.errorLog(e);
1817
+ if (!options) return { code: 2, exit: "immediate" };
1822
1818
  const code = await run({
1823
1819
  ...options,
1824
1820
  minHealth,
1825
- selectApp
1821
+ selectApp,
1822
+ log: io.log,
1823
+ errorLog: io.errorLog
1826
1824
  });
1827
1825
  await new Promise((resolve) => process.stdout.write("", resolve));
1828
- process.exit(code);
1826
+ return { code, exit: "immediate" };
1827
+ }
1828
+
1829
+ // src/bin.ts
1830
+ async function main() {
1831
+ const { code, exit } = await runCli(process.argv.slice(2));
1832
+ if (exit === "immediate") {
1833
+ process.exit(code);
1834
+ } else {
1835
+ process.exitCode = code;
1836
+ }
1829
1837
  }
1830
1838
  void main();
@@ -723,6 +723,7 @@ function chainFiles(pageRel, layouts) {
723
723
  async function resolveRoute(rt, cwd, pageRel, config, layouts, cache) {
724
724
  const files = chainFiles(pageRel, layouts);
725
725
  const composed = /* @__PURE__ */ new Map();
726
+ const jsonldTags = [];
726
727
  let broadOwn = false;
727
728
  let broadInherited = false;
728
729
  const images = [];
@@ -738,7 +739,9 @@ async function resolveRoute(rt, cwd, pageRel, config, layouts, cache) {
738
739
  }
739
740
  const resolved = await resolveFileTags(rt, cwd, rel, parsed, config, MAX_DEPTH, /* @__PURE__ */ new Set([rel]), cache);
740
741
  for (const tag of resolved.tags) {
741
- composed.set(tagKey(tag), { ...tag, presence: isPage ? "own" : "inherited", file: rel });
742
+ const stamped = { ...tag, presence: isPage ? "own" : "inherited", file: rel };
743
+ if (tag.kind === "jsonld") jsonldTags.push(stamped);
744
+ else composed.set(tagKey(tag), stamped);
742
745
  }
743
746
  if (resolved.broad) {
744
747
  if (isPage) broadOwn = true;
@@ -755,7 +758,7 @@ async function resolveRoute(rt, cwd, pageRel, config, layouts, cache) {
755
758
  }
756
759
  const route = deriveRoute(pageRel);
757
760
  return {
758
- head: { route, source: "static", tags: [...composed.values()], file: pageRel },
761
+ head: { route, source: "static", tags: [...composed.values(), ...jsonldTags], file: pageRel },
759
762
  images: { route, images },
760
763
  headings: { route, headings, componentHeadings }
761
764
  };
@@ -39,7 +39,7 @@ var EMBEDDED_DOCS = [
39
39
  name: "scoping",
40
40
  title: "Scoping findings to a change",
41
41
  description: "Use --diff, --staged, --baseline and the suppressions file so only what a change introduced is reported, instead of a legacy backlog.",
42
- body: "# Scoping findings to a change\n\nAn existing project usually has a backlog nobody is about to fix. Scope the report rather than\ndisabling rules.\n\n## Scope by file\n\n- **`--diff [ref]`** \u2014 only findings in files changed versus `ref` (default `HEAD`).\n- **`--staged`** \u2014 only findings in staged files. The pre-commit gate.\n\n```bash\nsvelte-vitals . --diff --reporter agent # after editing: what did I just break?\nsvelte-vitals . --staged # before committing\n```\n\nBoth work when the project is not at the git repo root.\n\n## Scope by finding (`--baseline <ref>`)\n\nReports only findings **not already present** at `ref`. Scopes by finding identity rather than by\nfile, so a pre-existing problem in a file you touched does not fail the gate. No default ref.\n\n```bash\nsvelte-vitals --diff origin/main --baseline origin/main --fail-on warning # PR gate\n```\n\nIt checks `ref` out into a temporary worktree and subtracts those findings. On failure (no git,\nbad ref) it warns and reports everything rather than failing the run.\n\n## Accept a backlog once (`svelte-vitals-suppressions.json`)\n\n`--baseline` handles the transient case. For a persistent ramp, record today's findings once:\n\n```bash\nsvelte-vitals --update-suppressions\ngit add svelte-vitals-suppressions.json\n```\n\nThis analyzes the whole project (`--diff`/`--staged`/`--baseline` are ignored), writes every\npenalized finding, and exits `0` without a report.\n\nThe file then applies automatically on every run, after `--diff`/`--staged` and `--baseline`.\nFixing an accepted finding leaves a **stale** entry, reported on stderr but never failing the run.\n`--no-suppressions` ignores the file for one run.\n\nA malformed suppressions file is a hard error (exit `2`), not a silent skip.\n\n## Which one\n\n| Situation | Use |\n| -------------------------------------- | ---------------------------------------- |\n| Checking an edit you just made | `--diff` |\n| Pre-commit hook | `--staged` |\n| PR gate against a base branch | `--diff <base> --baseline <base>` |\n| Adopting on a legacy project, for good | `--update-suppressions`, commit the file |\n\nMatching ignores line numbers in both `--baseline` and the suppressions file, so a second\nviolation of the same rule lower in the same file does not surface as new.\n\n## Related\n\n- `svelte-vitals docs show ci` \u2014 the generated PR gate already does the `--diff`/`--baseline` pairing\n- `svelte-vitals docs show config` \u2014 turning a rule off for good, when that is genuinely right"
42
+ body: "# Scoping findings to a change\n\nAn existing project usually has a backlog nobody is about to fix. Scope the report rather than\ndisabling rules.\n\n## Scope by file\n\n- **`--diff [ref]`** \u2014 only findings in files changed versus `ref` (default `HEAD`).\n- **`--staged`** \u2014 only findings in staged files. The pre-commit gate.\n\n```bash\nsvelte-vitals . --diff --reporter agent # after editing: what did I just break?\nsvelte-vitals . --staged # before committing\n```\n\nBoth work when the project is not at the git repo root.\n\n## Scope by finding (`--baseline <ref>`)\n\nReports only findings **not already present** at `ref`. Scopes by finding identity rather than by\nfile, so a pre-existing problem in a file you touched does not fail the gate. No default ref.\n\n```bash\nsvelte-vitals --diff origin/main --baseline origin/main --fail-on warning # PR gate\n```\n\nIt checks `ref` out into a temporary worktree and subtracts those findings. On failure (no git,\nbad ref) it warns and reports everything rather than failing the run.\n\n## Accept a backlog once (`svelte-vitals-suppressions.json`)\n\n`--baseline` handles the transient case. For a persistent ramp, record today's findings once:\n\n```bash\nsvelte-vitals --update-suppressions\ngit add svelte-vitals-suppressions.json\n```\n\nThis analyzes the whole project (`--diff`/`--staged`/`--baseline` are ignored), writes every\npenalized finding, and exits `0` without a report.\n\nThe file then applies automatically on every run, after `--diff`/`--staged` and `--baseline`.\nFixing an accepted finding leaves a **stale** entry, reported on stderr but never failing the run.\n`--no-suppressions` ignores the file for one run.\n\nAn entry covers whatever its rule reports at that route and location, not just the message\nrecorded when written \u2014 a different finding from the same rule at the same spot still matches\nand stays suppressed (and not stale).\n\nA malformed suppressions file is a hard error (exit `2`), not a silent skip.\n\n## Which one\n\n| Situation | Use |\n| -------------------------------------- | ---------------------------------------- |\n| Checking an edit you just made | `--diff` |\n| Pre-commit hook | `--staged` |\n| PR gate against a base branch | `--diff <base> --baseline <base>` |\n| Adopting on a legacy project, for good | `--update-suppressions`, commit the file |\n\nMatching ignores line numbers in both `--baseline` and the suppressions file, so a second\nviolation of the same rule lower in the same file does not surface as new.\n\n## Related\n\n- `svelte-vitals docs show ci` \u2014 the generated PR gate already does the `--diff`/`--baseline` pairing\n- `svelte-vitals docs show config` \u2014 turning a rule off for good, when that is genuinely right"
43
43
  }
44
44
  ];
45
45
 
package/dist/index.js CHANGED
@@ -7,7 +7,7 @@ import {
7
7
  routeMatcher,
8
8
  run,
9
9
  spinnerEnabled
10
- } from "./chunk-NIUYLAJK.js";
10
+ } from "./chunk-YY567AYV.js";
11
11
  import {
12
12
  findUnknownRuleIds,
13
13
  knownRuleIds,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "svelte-vitals",
3
- "version": "0.44.3",
3
+ "version": "0.44.4",
4
4
  "description": "A deterministic SvelteKit code-health scanner (SEO, performance, correctness, security, architecture) — not a runtime Web Vitals reporter.",
5
5
  "type": "module",
6
6
  "license": "MIT",
@@ -48,7 +48,7 @@
48
48
  "magicast": "^0.5.4",
49
49
  "svelte": "^5.56.8",
50
50
  "tinyglobby": "^0.2.17",
51
- "@svelte-vitals/core": "0.40.1"
51
+ "@svelte-vitals/core": "0.41.0"
52
52
  },
53
53
  "devDependencies": {
54
54
  "@types/estree": "^1.0.9",