svelte-vitals 0.44.2 → 0.44.3

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-EWDGS52A.js";
11
+ } from "./chunk-NIUYLAJK.js";
12
12
  import {
13
13
  consoleIO,
14
14
  parseCliArgs,
@@ -1429,7 +1429,9 @@ function realIO() {
1429
1429
  writeFileSync(path, content);
1430
1430
  },
1431
1431
  cwd: process.cwd(),
1432
- isTTY: Boolean(process.stdout.isTTY),
1432
+ // clack reads from stdin and renders to stdout, so both must be interactive —
1433
+ // a piped/redirected stdin would leave the prompt hanging for input that never comes.
1434
+ isTTY: Boolean(process.stdin.isTTY) && Boolean(process.stdout.isTTY),
1433
1435
  nodeVersion: process.version,
1434
1436
  log: (line) => console.log(line),
1435
1437
  errorLog: (line) => console.error(line),
@@ -773,7 +773,7 @@ async function collectRoutes(rt, cwd, config = defaultConfig, cache = /* @__PURE
773
773
  // src/route-matcher.ts
774
774
  function routeMatcher(glob2) {
775
775
  if (!glob2) return () => true;
776
- const body = glob2.replace(/[.+^${}()|[\]\\]/g, "\\$&").replace(/\*\*/g, " ").replace(/\*/g, "[^/]*").replace(/\/ $/g, "(?:/.*)?").replace(/^ \//g, "(?:.*/)?").replace(/ \//g, "(?:.*/)?").replace(/\/ /g, "(?:/.*)?").replace(/ /g, ".*");
776
+ const body = glob2.replace(/[.+^${}()|[\]\\]/g, "\\$&").replace(/\*\*/g, "\0").replace(/\*/g, "[^/]*").replace(/\/\0$/g, "(?:/.*)?").replace(/^\0\//g, "(?:.*/)?").replace(/\0\//g, "(?:.*/)?").replace(/\/\0/g, "(?:/.*)?").replace(/\0/g, ".*");
777
777
  const re = new RegExp(`^${body}$`);
778
778
  return (route) => re.test(route.replace(/^\//, ""));
779
779
  }
@@ -781,14 +781,23 @@ function routeMatcher(glob2) {
781
781
  // src/collect-all.ts
782
782
  async function collectAll(rt, cwd, config, opts = {}) {
783
783
  const matches = routeMatcher(opts.route);
784
- const collected = await collectRoutes(rt, cwd, config, opts.parseCache);
784
+ const project = await collectProjectFacts(rt, cwd);
785
+ const [collected, components, kitModules, sourceFiles] = await Promise.all([
786
+ collectRoutes(rt, cwd, config, opts.parseCache),
787
+ // Component (Correctness) facts are file-scoped with no route attribution yet, so a
788
+ // route-filtered run skips them rather than reporting unrelated components (#68 review);
789
+ // kitModules is skipped for the same reason.
790
+ opts.route ? [] : collectComponentFacts(rt, cwd),
791
+ opts.route ? [] : collectKitModuleFacts(rt, cwd, project.kitAliases),
792
+ // Unlike its two neighbours above, the --route branch gets `undefined` here, not `[]`: an empty
793
+ // inventory would tell architecture/unit-entry-file that the declared unit directories truly do
794
+ // not exist, so it would report every declaration as inert, whereas `undefined` means the mode
795
+ // never collected the fact at all, and the rule stays silent instead of raising a false alarm.
796
+ opts.route ? void 0 : collectSourceFiles(rt, cwd)
797
+ ]);
785
798
  const heads = collected.heads.filter((h) => matches(h.route));
786
799
  const images = collected.images.filter((i) => matches(i.route));
787
800
  const headings = collected.headings.filter((h) => matches(h.route));
788
- const project = await collectProjectFacts(rt, cwd);
789
- const components = opts.route ? [] : await collectComponentFacts(rt, cwd);
790
- const kitModules = opts.route ? [] : await collectKitModuleFacts(rt, cwd, project.kitAliases);
791
- const sourceFiles = opts.route ? void 0 : await collectSourceFiles(rt, cwd);
792
801
  return { heads, images, headings, project, components, kitModules, sourceFiles };
793
802
  }
794
803
 
@@ -978,7 +987,7 @@ function filterToNewFindings(results, baselineResults, config = defaultConfig3)
978
987
  }
979
988
 
980
989
  // src/suppressions.ts
981
- import { readFileSync as readFileSync2, writeFileSync } from "fs";
990
+ import { readFileSync as readFileSync2, renameSync, unlinkSync, writeFileSync } from "fs";
982
991
  import { join as join6 } from "path";
983
992
  import { isPenalized as isPenalized3 } from "@svelte-vitals/core";
984
993
 
@@ -1221,7 +1230,17 @@ function writeSuppressions(cwd, results, config) {
1221
1230
  }
1222
1231
  entries.sort(compareEntries);
1223
1232
  const path = join6(cwd, SUPPRESSIONS_FILE);
1224
- writeFileSync(path, JSON.stringify({ version: 1, suppressions: entries }, null, 2) + "\n");
1233
+ const tmpPath = `${path}.tmp`;
1234
+ try {
1235
+ writeFileSync(tmpPath, JSON.stringify({ version: 1, suppressions: entries }, null, 2) + "\n");
1236
+ renameSync(tmpPath, path);
1237
+ } catch (err) {
1238
+ try {
1239
+ unlinkSync(tmpPath);
1240
+ } catch {
1241
+ }
1242
+ throw err;
1243
+ }
1225
1244
  return entries.length;
1226
1245
  }
1227
1246
  function applySuppressions(results, entries, config, allResults) {
@@ -1540,6 +1559,16 @@ function overridesOffWarnings(allowRules, overrides) {
1540
1559
  }
1541
1560
  return warnings;
1542
1561
  }
1562
+ function skippedFileWarnings(facts) {
1563
+ const files = [...new Set(facts.filter((f) => f.parseFailed).map((f) => f.file))].sort();
1564
+ if (files.length === 0) return [];
1565
+ const shown = files.slice(0, 10);
1566
+ const list = files.length > shown.length ? `${shown.join(", ")}, \u2026 and ${files.length - shown.length} more` : shown.join(", ");
1567
+ return [
1568
+ `skipped ${files.length} file(s) that could not be parsed: ${list}`,
1569
+ "findings for these files are unavailable until they parse."
1570
+ ];
1571
+ }
1543
1572
  async function analyzeProject(opts = {}) {
1544
1573
  const cwd = opts.cwd ?? process.cwd();
1545
1574
  const rt = createNodeRuntime();
@@ -1588,7 +1617,7 @@ async function analyzeProject(opts = {}) {
1588
1617
  version: readPackageVersion(),
1589
1618
  ruleIds: rules.map((r) => r.id),
1590
1619
  examined,
1591
- warnings,
1620
+ warnings: [...warnings, ...skippedFileWarnings([...components, ...kitModules])],
1592
1621
  loadedConfig: loaded
1593
1622
  };
1594
1623
  }
package/dist/index.d.ts CHANGED
@@ -231,7 +231,7 @@ interface AnalyzeResult {
231
231
  ruleIds: string[];
232
232
  /** Per-rule, per-declaration counts of places examined, unfiltered by `--diff`/`--baseline`/suppressions. */
233
233
  examined: Record<string, Record<string, number>>;
234
- /** Non-fatal config-file issues (unknown top-level keys, invalid enum values). Empty when no config file or none found. */
234
+ /** Non-fatal issues surfaced during analysis: config-file problems (unknown top-level keys, invalid enum values), version-floor notices, `--rules`/overrides conflicts, and skipped-file notices. Empty when none apply. */
235
235
  warnings: string[];
236
236
  /**
237
237
  * This analysis's config-file load result (`undefined` when no config file exists at its
package/dist/index.js CHANGED
@@ -7,7 +7,7 @@ import {
7
7
  routeMatcher,
8
8
  run,
9
9
  spinnerEnabled
10
- } from "./chunk-EWDGS52A.js";
10
+ } from "./chunk-NIUYLAJK.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.2",
3
+ "version": "0.44.3",
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.0"
51
+ "@svelte-vitals/core": "0.40.1"
52
52
  },
53
53
  "devDependencies": {
54
54
  "@types/estree": "^1.0.9",