@svelte-vitals/core 0.26.0 → 0.27.0

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/index.d.ts CHANGED
@@ -60,6 +60,26 @@ type Category = 'seo' | 'performance' | 'correctness' | 'security' | 'architectu
60
60
  type TreatDynamicAs = 'pass' | 'warn' | 'fail';
61
61
  /** Per-rule override: disable, or change severity. */
62
62
  type RuleSetting = 'off' | Severity;
63
+ /**
64
+ * Scoped rule override (design 2026-07-18), applied to results after analysis.
65
+ * An entry matches a finding when any `route` glob matches its route id or any
66
+ * `files` glob matches its source location; at least one of the two must be
67
+ * set. Glob syntax: `*` matches within a segment, `**` across segments, a
68
+ * trailing `/**` also matches the bare prefix, and all other characters
69
+ * (including SvelteKit's `(`, `)`, `[`, `]`) are literal.
70
+ */
71
+ interface RuleOverride {
72
+ /**
73
+ * Route-id glob(s), e.g. '/admin/**'. Note route ids drop `(group)` segments
74
+ * (`src/routes/(app)/dashboard` reports as '/dashboard') — target a group
75
+ * via `files` instead.
76
+ */
77
+ route?: string | string[];
78
+ /** Source-path glob(s) matched against a finding's location, e.g. 'src/routes/(app)/**'. */
79
+ files?: string | string[];
80
+ /** Keys are rule ids ('SEO001') or category names ('seo'). Rule id beats category within an entry. */
81
+ rules: Record<string, RuleSetting>;
82
+ }
63
83
  interface Config {
64
84
  treatDynamicAs: TreatDynamicAs;
65
85
  /** Component names treated as meta sources of unknown content (design §11 layer 4). */
@@ -70,6 +90,8 @@ interface Config {
70
90
  failOn: Severity;
71
91
  /** Per-category weights for the combined Health score (default: equal, 1 each) (#10). */
72
92
  weights?: Partial<Record<Category, number>>;
93
+ /** Route-/file-scoped rule overrides, applied to results after analysis (later entries win). */
94
+ overrides?: RuleOverride[];
73
95
  }
74
96
  declare const defaultConfig: Config;
75
97
  /** Merge user config over defaults. Identity helper for config files (design §6). */
@@ -939,5 +961,15 @@ declare function safeHref(url: string): string | null;
939
961
  declare function selectRules(rules: Rule[], config: Config): Rule[];
940
962
  /** Apply per-rule severity overrides to results (design §6). */
941
963
  declare function applyRuleSeverities(results: Result[], config: Config): Result[];
964
+ /**
965
+ * Apply route-/file-scoped overrides to results (design 2026-07-18). An entry
966
+ * matches when any `route` glob matches the finding's route id or any `files`
967
+ * glob matches its location (OR). `'off'` removes a matched result entirely —
968
+ * passing seeds included, so scoring and "checks passed" counts behave as if
969
+ * the rule never ran there. A severity value rewrites the result's severity.
970
+ * Entries are evaluated in order (later entries win); within one entry a
971
+ * rule-id key beats a category key.
972
+ */
973
+ declare function applyOverrides(results: Result[], config: Config): Result[];
942
974
 
943
- export { APP_SCRIPT, APP_STYLE, type AppSnapshot, BAND_COLOR, CHILD_NODE_KEYS, type Category, type Classification, type ComponentFacts, type Config, type ConsoleReportOptions, type Detection, type EachBlockFact, type EffectFact, type Fix, type HeadProvider, type HeadTag, type HeadingInfo, type HealthResult, type ImageInfo, type JsonReport, type KitModuleFacts, type OrphanEffectFact, type Palette, type Presence, type Project, ROBOTS_SOURCE_PATHS, type ResolvedHead, type ResolvedHeadings, type ResolvedImages, type Result, type RouteBadge, type Rule, type RuleContext, type RuleInfo, type RuleSetting, type Runtime, SITEMAP_SOURCE_PATHS, type Scope, type ScoreModel, type ScoreOptions, type ScoreResult, type Severity, type SourceSpan, type Summary, type SuppressionDirective, type TreatDynamicAs, type Value, allRules, applyRuleSeverities, arch001ComponentSize, arch002PropCount, attrText, attrTextOf, attrValue, attrValueOf, buildHtmlDocument, buildJsonReport, classify, collectComponentFacts, collectKitModuleFacts, computeHealth, computeScore, correct001EachKey, correct002EffectDerived, correct003EffectAsOnMount, correct004UnmutatedState, correct005PropMutation, correct006OrphanEffect, correct007OrphanLifecycle, correct008BrowserGlobals, correct009InstanceBrowserGlobals, defaultConfig, defaultProject, defineConfig, docsUrlFor, effectiveSeverity, emptyComponentFacts, emptyKitModuleFacts, escapeHtml, explainRule, findAttr, formatAgentReport, formatConsoleReport, formatGithubReport, formatHtmlReport, formatJsonReport, formatMarkdownReport, formatSarifReport, hasFailureAtOrAbove, headTagRule, imageRule, isPenalized, lineOf, linkRule, noColorPalette, parseComponentFacts, parseKitModuleFacts, perf001ImageDimensions, perf002ImageLoading, perf003PreloadAs, perf004FontPreloadCrossorigin, perf005LcpImage, perf006ResponsiveImage, perf007RenderBlockingScript, perf008Preconnect, perf009HeavyImport, perf010NamespaceImport, renderAppShell, resolveRunesModuleSpecifier, runRules, safeHref, scoreBand, scoreColor, scoresByCategory, sec001Html, sec002JavascriptUrl, sec003LoadStateWrite, sec004ServerModuleState, sec005SharedStateImport, selectRules, seo001Title, seo002Description, seo003Canonical, seo004OgImage, seo005OgTitle, seo006Robots, seo007Sitemap, seo008JsonLd, seo009HtmlLang, seo010Indexability, seo011TwitterCard, seo012OgDescription, seo013OgUrl, seo014Viewport, seo015SitemapInRobots, seo016JsonLdValidity, seo017DeprecatedType, seo018RelativeUrl, seo019DateFormat, seo020Placeholder, seo021RequiredProps, seo022TitleLength, seo023DescriptionLength, seo024Charset, seo025ImageAlt, seo026Hreflang, seo027Heading, seo028TitleUnique, seo029DescriptionUnique, seo030HeadingOrder, summarize, textFromNodes, valueFromNodes };
975
+ export { APP_SCRIPT, APP_STYLE, type AppSnapshot, BAND_COLOR, CHILD_NODE_KEYS, type Category, type Classification, type ComponentFacts, type Config, type ConsoleReportOptions, type Detection, type EachBlockFact, type EffectFact, type Fix, type HeadProvider, type HeadTag, type HeadingInfo, type HealthResult, type ImageInfo, type JsonReport, type KitModuleFacts, type OrphanEffectFact, type Palette, type Presence, type Project, ROBOTS_SOURCE_PATHS, type ResolvedHead, type ResolvedHeadings, type ResolvedImages, type Result, type RouteBadge, type Rule, type RuleContext, type RuleInfo, type RuleOverride, type RuleSetting, type Runtime, SITEMAP_SOURCE_PATHS, type Scope, type ScoreModel, type ScoreOptions, type ScoreResult, type Severity, type SourceSpan, type Summary, type SuppressionDirective, type TreatDynamicAs, type Value, allRules, applyOverrides, applyRuleSeverities, arch001ComponentSize, arch002PropCount, attrText, attrTextOf, attrValue, attrValueOf, buildHtmlDocument, buildJsonReport, classify, collectComponentFacts, collectKitModuleFacts, computeHealth, computeScore, correct001EachKey, correct002EffectDerived, correct003EffectAsOnMount, correct004UnmutatedState, correct005PropMutation, correct006OrphanEffect, correct007OrphanLifecycle, correct008BrowserGlobals, correct009InstanceBrowserGlobals, defaultConfig, defaultProject, defineConfig, docsUrlFor, effectiveSeverity, emptyComponentFacts, emptyKitModuleFacts, escapeHtml, explainRule, findAttr, formatAgentReport, formatConsoleReport, formatGithubReport, formatHtmlReport, formatJsonReport, formatMarkdownReport, formatSarifReport, hasFailureAtOrAbove, headTagRule, imageRule, isPenalized, lineOf, linkRule, noColorPalette, parseComponentFacts, parseKitModuleFacts, perf001ImageDimensions, perf002ImageLoading, perf003PreloadAs, perf004FontPreloadCrossorigin, perf005LcpImage, perf006ResponsiveImage, perf007RenderBlockingScript, perf008Preconnect, perf009HeavyImport, perf010NamespaceImport, renderAppShell, resolveRunesModuleSpecifier, runRules, safeHref, scoreBand, scoreColor, scoresByCategory, sec001Html, sec002JavascriptUrl, sec003LoadStateWrite, sec004ServerModuleState, sec005SharedStateImport, selectRules, seo001Title, seo002Description, seo003Canonical, seo004OgImage, seo005OgTitle, seo006Robots, seo007Sitemap, seo008JsonLd, seo009HtmlLang, seo010Indexability, seo011TwitterCard, seo012OgDescription, seo013OgUrl, seo014Viewport, seo015SitemapInRobots, seo016JsonLdValidity, seo017DeprecatedType, seo018RelativeUrl, seo019DateFormat, seo020Placeholder, seo021RequiredProps, seo022TitleLength, seo023DescriptionLength, seo024Charset, seo025ImageAlt, seo026Hreflang, seo027Heading, seo028TitleUnique, seo029DescriptionUnique, seo030HeadingOrder, summarize, textFromNodes, valueFromNodes };
package/dist/index.js CHANGED
@@ -3874,6 +3874,10 @@ function formatMarkdownReport(results, config, meta) {
3874
3874
  lines.push("");
3875
3875
  lines.push(`\u2026and ${findings.length - MAX_FINDINGS} more (run \`npx svelte-vitals\` locally for the full report)`);
3876
3876
  }
3877
+ lines.push("");
3878
+ lines.push(
3879
+ "_Expected findings (e.g. routes behind auth)? See [Excluding routes or rules](https://oekazuma.github.io/svelte-vitals/guides/ci/#excluding-routes-or-rules)._"
3880
+ );
3877
3881
  }
3878
3882
  return lines.join("\n");
3879
3883
  }
@@ -4575,6 +4579,38 @@ function applyRuleSeverities(results, config) {
4575
4579
  return setting && setting !== "off" ? { ...result, severity: setting } : result;
4576
4580
  });
4577
4581
  }
4582
+ function routeGlobToRegExp(pattern) {
4583
+ const body = pattern.replace(/[.+?^${}()|[\]\\]/g, "\\$&").replace(/\*\*/g, "\0").replace(/\*/g, "[^/]*").split("\0").join(".*");
4584
+ const source = body.endsWith("/.*") ? `${body.slice(0, -3)}(/.*)?` : body;
4585
+ return new RegExp(`^${source}$`);
4586
+ }
4587
+ function toPatterns(globs) {
4588
+ if (globs === void 0) return [];
4589
+ return (Array.isArray(globs) ? globs : [globs]).map(routeGlobToRegExp);
4590
+ }
4591
+ function applyOverrides(results, config) {
4592
+ const overrides = config.overrides;
4593
+ if (!overrides || overrides.length === 0) return results;
4594
+ const compiled = overrides.map((o) => ({
4595
+ routes: toPatterns(o.route),
4596
+ files: toPatterns(o.files),
4597
+ rules: o.rules
4598
+ }));
4599
+ const out = [];
4600
+ for (const result of results) {
4601
+ const { route, location } = result;
4602
+ let setting;
4603
+ for (const o of compiled) {
4604
+ const matched = route !== void 0 && o.routes.some((p) => p.test(route)) || location !== void 0 && o.files.some((p) => p.test(location));
4605
+ if (!matched) continue;
4606
+ const s = o.rules[result.id] ?? o.rules[result.category ?? "seo"];
4607
+ if (s !== void 0) setting = s;
4608
+ }
4609
+ if (setting === void 0) out.push(result);
4610
+ else if (setting !== "off") out.push({ ...result, severity: setting });
4611
+ }
4612
+ return out;
4613
+ }
4578
4614
  export {
4579
4615
  APP_SCRIPT,
4580
4616
  APP_STYLE,
@@ -4583,6 +4619,7 @@ export {
4583
4619
  ROBOTS_SOURCE_PATHS,
4584
4620
  SITEMAP_SOURCE_PATHS,
4585
4621
  allRules,
4622
+ applyOverrides,
4586
4623
  applyRuleSeverities,
4587
4624
  arch001ComponentSize,
4588
4625
  arch002PropCount,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@svelte-vitals/core",
3
- "version": "0.26.0",
3
+ "version": "0.27.0",
4
4
  "description": "Shared, runtime-agnostic core for svelte-vitals (types, rule engine, scorer, reporter).",
5
5
  "type": "module",
6
6
  "license": "MIT",