svelte-vitals 0.48.0 → 0.49.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/bin.js +4 -4
- package/dist/{chunk-4LSRQXJ6.js → chunk-4FOGEXGH.js} +1 -1
- package/dist/{chunk-LJPABOWU.js → chunk-5YVVJMZM.js} +122 -23
- package/dist/{chunk-ZAHTKEJ5.js → chunk-K363W33X.js} +5 -1
- package/dist/{complete-IOAMJRBY.js → complete-ZQZGCJ5W.js} +3 -3
- package/dist/{explain-WOKUZJVY.js → explain-PRCEATL4.js} +1 -1
- package/dist/gunshi-registry.js +2 -2
- package/dist/index.d.ts +9 -1
- package/dist/index.js +1 -1
- package/package.json +2 -2
package/dist/bin.js
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import {
|
|
3
3
|
runAnalyzeCliGunshi
|
|
4
|
-
} from "./chunk-
|
|
4
|
+
} from "./chunk-4FOGEXGH.js";
|
|
5
5
|
import "./chunk-DZVXCUHG.js";
|
|
6
6
|
import {
|
|
7
7
|
realIO
|
|
8
8
|
} from "./chunk-RSSMIHIM.js";
|
|
9
|
-
import "./chunk-
|
|
9
|
+
import "./chunk-5YVVJMZM.js";
|
|
10
10
|
import "./chunk-WGFXFKBB.js";
|
|
11
11
|
import {
|
|
12
12
|
consoleIO
|
|
@@ -21,7 +21,7 @@ async function runCli(argv, io = consoleIO, env = process.env) {
|
|
|
21
21
|
try {
|
|
22
22
|
const locale = resolveLocale(env);
|
|
23
23
|
if (argv[0] === "complete") {
|
|
24
|
-
const { runCompleteCliGunshi } = await import("./complete-
|
|
24
|
+
const { runCompleteCliGunshi } = await import("./complete-ZQZGCJ5W.js");
|
|
25
25
|
return { code: await runCompleteCliGunshi(argv, io), exit: "natural" };
|
|
26
26
|
}
|
|
27
27
|
if (argv[0] === "docs") {
|
|
@@ -29,7 +29,7 @@ async function runCli(argv, io = consoleIO, env = process.env) {
|
|
|
29
29
|
return { code: await runDocsCliGunshi(argv.slice(1), io, locale), exit: "natural" };
|
|
30
30
|
}
|
|
31
31
|
if (argv[0] === "explain") {
|
|
32
|
-
const { runExplainCliGunshi } = await import("./explain-
|
|
32
|
+
const { runExplainCliGunshi } = await import("./explain-PRCEATL4.js");
|
|
33
33
|
return { code: await runExplainCliGunshi(argv.slice(1), io, locale), exit: "natural" };
|
|
34
34
|
}
|
|
35
35
|
if (argv[0] === "install") {
|
|
@@ -34,6 +34,8 @@ import {
|
|
|
34
34
|
selectRules,
|
|
35
35
|
applyRuleSeverities,
|
|
36
36
|
applyOverrides,
|
|
37
|
+
applyInlineDirectives,
|
|
38
|
+
unknownDirectiveIds,
|
|
37
39
|
settingSeverity,
|
|
38
40
|
withFailedRulesOff,
|
|
39
41
|
formatFailedRuleWarning,
|
|
@@ -75,6 +77,7 @@ import {
|
|
|
75
77
|
SITEMAP_SOURCE_PATHS,
|
|
76
78
|
SVELTE_CONFIG_FILES,
|
|
77
79
|
VITE_CONFIG_FILES,
|
|
80
|
+
collectSuppressions,
|
|
78
81
|
findMinifyDisabled,
|
|
79
82
|
resolveKitAliases,
|
|
80
83
|
resolveKitPathsBase
|
|
@@ -152,6 +155,18 @@ function detectHtmlLang(html) {
|
|
|
152
155
|
const value = match[1] ?? match[2] ?? match[3] ?? "";
|
|
153
156
|
return { presence: "own", value: value.trim().length > 0 ? "static" : "absent" };
|
|
154
157
|
}
|
|
158
|
+
function detectAppHtmlBodyTags(html) {
|
|
159
|
+
let markup = html.replace(/<!--[\s\S]*?-->/g, "").replace(/<script[\s\S]*?<\/script\s*>/gi, "").replace(/<style[\s\S]*?<\/style\s*>/gi, "");
|
|
160
|
+
const innermost = /<template\b[^>]*>(?:(?!<template\b)[\s\S])*?<\/template\s*>/gi;
|
|
161
|
+
for (let prev = ""; prev !== markup; ) {
|
|
162
|
+
prev = markup;
|
|
163
|
+
markup = markup.replace(innermost, "\0");
|
|
164
|
+
}
|
|
165
|
+
markup = markup.replaceAll("\0", "<template></template>");
|
|
166
|
+
const body = /<body\b[^>]*>([\s\S]*?)(?:<\/body\s*>|$)/i.exec(markup)?.[1];
|
|
167
|
+
if (body === void 0) return [];
|
|
168
|
+
return [...new Set([...body.matchAll(/<([a-zA-Z][a-zA-Z0-9-]*)\b/g)].map((m) => m[1].toLowerCase()))];
|
|
169
|
+
}
|
|
155
170
|
function detectAppHtmlIds(html) {
|
|
156
171
|
const markup = html.replace(/<!--[\s\S]*?-->/g, "").replace(/<script[\s\S]*?<\/script\s*>/gi, "").replace(/<style[\s\S]*?<\/style\s*>/gi, "");
|
|
157
172
|
const found = markup.matchAll(/(?<![\w-])id\s*=\s*(?:"([^"]*)"|'([^']*)'|([^\s"'>{][^\s"'>]*))/gi);
|
|
@@ -172,7 +187,8 @@ async function detectAppHtmlFacts(rt, cwd) {
|
|
|
172
187
|
// [\s\S]*? is ambiguous across iterations and backtracks exponentially on a comment run
|
|
173
188
|
// with no doctype (measured: ~45 leading comments hang the process).
|
|
174
189
|
appHtmlDoctype: /^\s*<!doctype\s+html/i.test(content.replace(/<!--[\s\S]*?-->/g, "")),
|
|
175
|
-
appHtmlIds: detectAppHtmlIds(content)
|
|
190
|
+
appHtmlIds: detectAppHtmlIds(content),
|
|
191
|
+
appHtmlBodyTags: detectAppHtmlBodyTags(content)
|
|
176
192
|
};
|
|
177
193
|
}
|
|
178
194
|
async function robotsRefsSitemap(rt, cwd) {
|
|
@@ -189,8 +205,9 @@ async function detectViteMinifyDisabled(rt, cwd) {
|
|
|
189
205
|
const file = VITE_CONFIG_FILES[exists.indexOf(true)];
|
|
190
206
|
if (!file) return void 0;
|
|
191
207
|
try {
|
|
192
|
-
const
|
|
193
|
-
|
|
208
|
+
const source = await rt.readFile(rt.join(cwd, file));
|
|
209
|
+
const hit = findMinifyDisabled(source);
|
|
210
|
+
return hit ? { file, line: hit.line, suppressions: collectSuppressions(source) } : void 0;
|
|
194
211
|
} catch {
|
|
195
212
|
return void 0;
|
|
196
213
|
}
|
|
@@ -243,7 +260,12 @@ import "@svelte-vitals/core";
|
|
|
243
260
|
import {
|
|
244
261
|
collectComponentFacts,
|
|
245
262
|
collectKitModuleFacts,
|
|
246
|
-
collectSourceFiles
|
|
263
|
+
collectSourceFiles,
|
|
264
|
+
compileOverrides,
|
|
265
|
+
ROBOTS_SOURCE_PATHS as ROBOTS_SOURCE_PATHS2,
|
|
266
|
+
SITEMAP_SOURCE_PATHS as SITEMAP_SOURCE_PATHS2,
|
|
267
|
+
SVELTE_CONFIG_FILES as SVELTE_CONFIG_FILES2,
|
|
268
|
+
VITE_CONFIG_FILES as VITE_CONFIG_FILES2
|
|
247
269
|
} from "@svelte-vitals/core/internal";
|
|
248
270
|
|
|
249
271
|
// src/providers/source/routes.ts
|
|
@@ -387,6 +409,7 @@ function findAdapter(info) {
|
|
|
387
409
|
|
|
388
410
|
// src/providers/source/parse.ts
|
|
389
411
|
import {
|
|
412
|
+
collectSuppressions as collectSuppressions2,
|
|
390
413
|
stripTextDirective,
|
|
391
414
|
parseSvelte,
|
|
392
415
|
CHILD_NODE_KEYS,
|
|
@@ -605,6 +628,8 @@ function collectA11y(fragment, source) {
|
|
|
605
628
|
let groups = 0;
|
|
606
629
|
let slotInLandmark;
|
|
607
630
|
let unknowableContent = false;
|
|
631
|
+
const elementTags = /* @__PURE__ */ new Set();
|
|
632
|
+
let elementsUnknowable = false;
|
|
608
633
|
const emit = (ctx, node) => {
|
|
609
634
|
const inLandmark = ctx.landmarks.at(-1);
|
|
610
635
|
nodes.push({ ...node, repeatable: ctx.repeatable, path: ctx.path, ...inLandmark ? { inLandmark } : {} });
|
|
@@ -627,6 +652,7 @@ function collectA11y(fragment, source) {
|
|
|
627
652
|
// head content never renders into the body
|
|
628
653
|
case "HtmlTag":
|
|
629
654
|
unknowableContent = true;
|
|
655
|
+
elementsUnknowable = true;
|
|
630
656
|
return;
|
|
631
657
|
case "IfBlock":
|
|
632
658
|
walkIfChain(node, ctx, groups++, 0);
|
|
@@ -649,6 +675,8 @@ function collectA11y(fragment, source) {
|
|
|
649
675
|
// attributes are real — dropping them would make no-missing-id-ref report phantom misses.
|
|
650
676
|
case "RegularElement":
|
|
651
677
|
case "SvelteElement":
|
|
678
|
+
if (node.type === "SvelteElement") elementsUnknowable = true;
|
|
679
|
+
else elementTags.add(node.name.toLowerCase());
|
|
652
680
|
walkElement(node, ctx);
|
|
653
681
|
return;
|
|
654
682
|
case "Component":
|
|
@@ -728,7 +756,13 @@ function collectA11y(fragment, source) {
|
|
|
728
756
|
});
|
|
729
757
|
};
|
|
730
758
|
walk(fragment, { path: [], repeatable: false, landmarks: [], elementDepth: 0, asideDemoting: 0 });
|
|
731
|
-
return {
|
|
759
|
+
return {
|
|
760
|
+
nodes,
|
|
761
|
+
...slotInLandmark ? { slotInLandmark } : {},
|
|
762
|
+
unknowableContent,
|
|
763
|
+
elementTags: [...elementTags],
|
|
764
|
+
elementsUnknowable
|
|
765
|
+
};
|
|
732
766
|
}
|
|
733
767
|
function isChildrenRender(node) {
|
|
734
768
|
const call = node.expression.type === "ChainExpression" ? node.expression.expression : node.expression;
|
|
@@ -750,7 +784,8 @@ function parseFile(source, filename) {
|
|
|
750
784
|
imports: collectImports(ast),
|
|
751
785
|
images,
|
|
752
786
|
headings,
|
|
753
|
-
a11y: collectA11y(ast.fragment, source)
|
|
787
|
+
a11y: collectA11y(ast.fragment, source),
|
|
788
|
+
suppressions: collectSuppressions2(source)
|
|
754
789
|
};
|
|
755
790
|
}
|
|
756
791
|
|
|
@@ -921,6 +956,8 @@ function offsetPath(path, base) {
|
|
|
921
956
|
async function composeA11y(ctx, fileRel, parsed, depth, visited, chain) {
|
|
922
957
|
const { rt, cwd, state } = ctx;
|
|
923
958
|
if (parsed.a11y.unknowableContent) state.fullyResolved = false;
|
|
959
|
+
for (const t of parsed.a11y.elementTags) state.elementTags.add(t);
|
|
960
|
+
if (parsed.a11y.elementsUnknowable) state.elementsClosed = false;
|
|
924
961
|
const base = state.nextGroup;
|
|
925
962
|
state.nextGroup += groupSpan(parsed.a11y.nodes);
|
|
926
963
|
const composed = [];
|
|
@@ -934,6 +971,7 @@ async function composeA11y(ctx, fileRel, parsed, depth, visited, chain) {
|
|
|
934
971
|
const childRel = info ? resolveComponentPath(info.source, fileRel, ctx.aliases) : void 0;
|
|
935
972
|
if (!childRel || depth <= 0 || visited.has(childRel) || !await rt.exists(rt.join(cwd, childRel))) {
|
|
936
973
|
state.fullyResolved = false;
|
|
974
|
+
state.elementsClosed = false;
|
|
937
975
|
continue;
|
|
938
976
|
}
|
|
939
977
|
const childParsed = await readAndParse(rt, cwd, childRel, ctx.cache);
|
|
@@ -963,7 +1001,7 @@ function representatives(nodes, chainOrder) {
|
|
|
963
1001
|
[...folded].map(([key, list]) => [key, list.sort(order).map(({ file, line }) => ({ file, line }))])
|
|
964
1002
|
);
|
|
965
1003
|
}
|
|
966
|
-
async function resolveRoute(rt, cwd, pageRel, config, layouts, cache, aliases, appHtmlIds) {
|
|
1004
|
+
async function resolveRoute(rt, cwd, pageRel, config, layouts, cache, aliases, appHtmlIds, appHtmlBodyTags) {
|
|
967
1005
|
const files = chainFiles(pageRel, layouts);
|
|
968
1006
|
const chainOrder = new Map(files.map((f, i) => [f.rel, i]));
|
|
969
1007
|
const composed = /* @__PURE__ */ new Map();
|
|
@@ -973,7 +1011,14 @@ async function resolveRoute(rt, cwd, pageRel, config, layouts, cache, aliases, a
|
|
|
973
1011
|
const images = [];
|
|
974
1012
|
const headings = [];
|
|
975
1013
|
const componentHeadings = [];
|
|
976
|
-
const a11yCtx = {
|
|
1014
|
+
const a11yCtx = {
|
|
1015
|
+
rt,
|
|
1016
|
+
cwd,
|
|
1017
|
+
config,
|
|
1018
|
+
cache,
|
|
1019
|
+
aliases,
|
|
1020
|
+
state: { nextGroup: 0, fullyResolved: true, elementTags: new Set(appHtmlBodyTags ?? []), elementsClosed: true }
|
|
1021
|
+
};
|
|
977
1022
|
const a11yNodes = [];
|
|
978
1023
|
const nestedLandmarks = [];
|
|
979
1024
|
let slotLandmark;
|
|
@@ -1033,14 +1078,17 @@ async function resolveRoute(rt, cwd, pageRel, config, layouts, cache, aliases, a
|
|
|
1033
1078
|
// never a missing reference (HTML's "top of the document" fragment).
|
|
1034
1079
|
idRefs: a11yNodes.filter((n) => n.kind === "idref" && !(n.attr === "href" && isTopFragment(n.key))).map((n) => ({ id: n.key, attr: n.attr ?? "", file: n.file, line: n.line })),
|
|
1035
1080
|
idCandidates: [.../* @__PURE__ */ new Set([...literalIds.map((n) => n.key), ...appHtmlIds ?? []])],
|
|
1036
|
-
fullyResolved: a11yCtx.state.fullyResolved
|
|
1081
|
+
fullyResolved: a11yCtx.state.fullyResolved,
|
|
1082
|
+
elementTags: [...a11yCtx.state.elementTags],
|
|
1083
|
+
elementsClosed: a11yCtx.state.elementsClosed,
|
|
1084
|
+
file: pageRel
|
|
1037
1085
|
}
|
|
1038
1086
|
};
|
|
1039
1087
|
}
|
|
1040
|
-
async function collectRoutes(rt, cwd, config = defaultConfig, cache = /* @__PURE__ */ new Map(), aliases, appHtmlIds) {
|
|
1088
|
+
async function collectRoutes(rt, cwd, config = defaultConfig, cache = /* @__PURE__ */ new Map(), aliases, appHtmlIds, appHtmlBodyTags) {
|
|
1041
1089
|
const [pages, layouts] = await Promise.all([enumerateRoutePages(rt, cwd), collectLayouts(rt, cwd)]);
|
|
1042
1090
|
const facts = await Promise.all(
|
|
1043
|
-
pages.map((page) => resolveRoute(rt, cwd, page, config, layouts, cache, aliases, appHtmlIds))
|
|
1091
|
+
pages.map((page) => resolveRoute(rt, cwd, page, config, layouts, cache, aliases, appHtmlIds, appHtmlBodyTags))
|
|
1044
1092
|
);
|
|
1045
1093
|
return {
|
|
1046
1094
|
heads: facts.map((f) => f.head),
|
|
@@ -1059,11 +1107,15 @@ function routeMatcher(glob) {
|
|
|
1059
1107
|
}
|
|
1060
1108
|
|
|
1061
1109
|
// src/collect-all.ts
|
|
1110
|
+
function globList(globs) {
|
|
1111
|
+
return globs === void 0 ? [] : Array.isArray(globs) ? globs : [globs];
|
|
1112
|
+
}
|
|
1062
1113
|
async function collectAll(rt, cwd, config, opts = {}) {
|
|
1063
1114
|
const matches = routeMatcher(opts.route);
|
|
1115
|
+
const parseCache = opts.parseCache ?? /* @__PURE__ */ new Map();
|
|
1064
1116
|
const project = await collectProjectFacts(rt, cwd);
|
|
1065
1117
|
const [collected, components, kitModules, sourceFiles] = await Promise.all([
|
|
1066
|
-
collectRoutes(rt, cwd, config,
|
|
1118
|
+
collectRoutes(rt, cwd, config, parseCache, project.kitAliases, project.appHtmlIds, project.appHtmlBodyTags),
|
|
1067
1119
|
// Component (Correctness) facts are file-scoped with no route attribution yet, so a
|
|
1068
1120
|
// route-filtered run skips them rather than reporting unrelated components (#68 review);
|
|
1069
1121
|
// kitModules is skipped for the same reason.
|
|
@@ -1079,7 +1131,45 @@ async function collectAll(rt, cwd, config, opts = {}) {
|
|
|
1079
1131
|
const images = collected.images.filter((i) => matches(i.route));
|
|
1080
1132
|
const headings = collected.headings.filter((h) => matches(h.route));
|
|
1081
1133
|
const a11y = collected.a11y.filter((a) => matches(a.route));
|
|
1082
|
-
|
|
1134
|
+
const directives = /* @__PURE__ */ new Map();
|
|
1135
|
+
for (const [file, parsed] of parseCache) {
|
|
1136
|
+
const suppressions = await parsed.then(
|
|
1137
|
+
(parsedFile) => parsedFile.suppressions,
|
|
1138
|
+
() => void 0
|
|
1139
|
+
);
|
|
1140
|
+
if (suppressions) directives.set(file, suppressions);
|
|
1141
|
+
}
|
|
1142
|
+
for (const c of components) directives.set(c.file, c.suppressions ?? []);
|
|
1143
|
+
for (const m of kitModules) directives.set(m.file, m.suppressions ?? []);
|
|
1144
|
+
const viteConfig = project.viteMinifyDisabled;
|
|
1145
|
+
if (viteConfig?.file) directives.set(viteConfig.file, viteConfig.suppressions ?? []);
|
|
1146
|
+
const routes = collected.heads.map((h) => h.route);
|
|
1147
|
+
const emptySelections = [];
|
|
1148
|
+
if (opts.route !== void 0 && routes.length > 0 && !routes.some(matches))
|
|
1149
|
+
emptySelections.push(`--route '${opts.route}' matched none of the ${routes.length} route(s) found.`);
|
|
1150
|
+
if (opts.route === void 0 && routes.length > 0) {
|
|
1151
|
+
const attributable = [
|
|
1152
|
+
...directives.keys(),
|
|
1153
|
+
...ROBOTS_SOURCE_PATHS2,
|
|
1154
|
+
...SITEMAP_SOURCE_PATHS2,
|
|
1155
|
+
...VITE_CONFIG_FILES2,
|
|
1156
|
+
...SVELTE_CONFIG_FILES2
|
|
1157
|
+
];
|
|
1158
|
+
const entries = config.overrides ?? [];
|
|
1159
|
+
const compiled = compileOverrides(config);
|
|
1160
|
+
entries.forEach((entry, i) => {
|
|
1161
|
+
globList(entry.route).forEach((glob) => {
|
|
1162
|
+
if (!routes.some(routeMatcher(glob)))
|
|
1163
|
+
emptySelections.push(`overrides entry for route '${glob}' matched no route.`);
|
|
1164
|
+
});
|
|
1165
|
+
globList(entry.files).forEach((glob, j) => {
|
|
1166
|
+
const pattern = compiled[i]?.files[j];
|
|
1167
|
+
if (pattern && !attributable.some((f) => pattern.test(f)))
|
|
1168
|
+
emptySelections.push(`overrides entry for files '${glob}' matched no file.`);
|
|
1169
|
+
});
|
|
1170
|
+
});
|
|
1171
|
+
}
|
|
1172
|
+
return { heads, images, headings, a11y, project, components, kitModules, sourceFiles, directives, emptySelections };
|
|
1083
1173
|
}
|
|
1084
1174
|
|
|
1085
1175
|
// src/changed-files.ts
|
|
@@ -1580,17 +1670,21 @@ async function analyzeProject(opts = {}) {
|
|
|
1580
1670
|
...await checkVersionFloor(rt, cwd),
|
|
1581
1671
|
...overridesOffWarnings(opts.allowRules, config.overrides)
|
|
1582
1672
|
];
|
|
1583
|
-
const { heads, images, headings, a11y, project, components, kitModules, sourceFiles } = await collectAll(
|
|
1584
|
-
|
|
1585
|
-
|
|
1586
|
-
|
|
1587
|
-
|
|
1588
|
-
|
|
1589
|
-
parseCache: opts.parseCache
|
|
1590
|
-
}
|
|
1591
|
-
);
|
|
1673
|
+
const { heads, images, headings, a11y, project, components, kitModules, sourceFiles, directives, emptySelections } = await collectAll(rt, cwd, config, {
|
|
1674
|
+
route: opts.route,
|
|
1675
|
+
parseCache: opts.parseCache
|
|
1676
|
+
});
|
|
1677
|
+
warnings.push(...emptySelections);
|
|
1678
|
+
if (opts.route === void 0) warnings.push(...unknownDirectiveIds(directives, allRules2));
|
|
1592
1679
|
const selected = selectRules(allRules2, config);
|
|
1593
1680
|
const rules = opts.categories ? selected.filter((r) => opts.categories.includes(r.category)) : selected;
|
|
1681
|
+
if (opts.route !== void 0 && opts.allowRules?.length) {
|
|
1682
|
+
const starved = rules.filter((r) => opts.allowRules.includes(r.id) && r.scope !== "route").map((r) => r.id);
|
|
1683
|
+
if (starved.length > 0)
|
|
1684
|
+
warnings.push(
|
|
1685
|
+
`--rules ${starved.map((id) => `'${id}'`).join(", ")} examined nothing: --route collects route facts only.`
|
|
1686
|
+
);
|
|
1687
|
+
}
|
|
1594
1688
|
const {
|
|
1595
1689
|
results: rawResults,
|
|
1596
1690
|
examined,
|
|
@@ -1606,7 +1700,12 @@ async function analyzeProject(opts = {}) {
|
|
|
1606
1700
|
kitModules,
|
|
1607
1701
|
sourceFiles
|
|
1608
1702
|
});
|
|
1609
|
-
const results =
|
|
1703
|
+
const results = applyInlineDirectives(
|
|
1704
|
+
applyOverrides(applyRuleSeverities(rawResults, config), config),
|
|
1705
|
+
directives,
|
|
1706
|
+
rules,
|
|
1707
|
+
config
|
|
1708
|
+
);
|
|
1610
1709
|
const failedRuleIds = failedRules.map((f) => f.id);
|
|
1611
1710
|
const scoringConfig = withFailedRulesOff(config, failedRuleIds);
|
|
1612
1711
|
return {
|
|
@@ -26,7 +26,11 @@ function describeOptions(id, options) {
|
|
|
26
26
|
"string-map": "merged over the default entries \u2014 a new key is added, a built-in key has its value overridden"
|
|
27
27
|
};
|
|
28
28
|
const lines = options.map((o) => {
|
|
29
|
-
const bounds = [
|
|
29
|
+
const bounds = [
|
|
30
|
+
o.min !== void 0 ? `>= ${o.min}` : "",
|
|
31
|
+
o.max !== void 0 ? `<= ${o.max}` : "",
|
|
32
|
+
o.pattern ? `each entry ${o.pattern}` : ""
|
|
33
|
+
].filter(Boolean).join(", ");
|
|
30
34
|
return `- ${o.name} (${o.kind}, default ${JSON.stringify(o.default)}${bounds ? `, ${bounds}` : ""}) \u2014 ${MERGE[o.kind]}`;
|
|
31
35
|
});
|
|
32
36
|
return `set in svelte-vitals.config.* as \`rules: { '${id}': { options: { \u2026 } } }\`, or per path in \`overrides\`:
|
|
@@ -8,14 +8,14 @@ import {
|
|
|
8
8
|
import "./chunk-CTMKTFST.js";
|
|
9
9
|
import {
|
|
10
10
|
ROOT_ARGS
|
|
11
|
-
} from "./chunk-
|
|
11
|
+
} from "./chunk-4FOGEXGH.js";
|
|
12
12
|
import {
|
|
13
13
|
CATEGORIES,
|
|
14
14
|
FAIL_ON_VALUES,
|
|
15
15
|
TREAT_DYNAMIC_AS_VALUES
|
|
16
16
|
} from "./chunk-DZVXCUHG.js";
|
|
17
17
|
import "./chunk-RSSMIHIM.js";
|
|
18
|
-
import "./chunk-
|
|
18
|
+
import "./chunk-5YVVJMZM.js";
|
|
19
19
|
import {
|
|
20
20
|
REPORTER_NAMES
|
|
21
21
|
} from "./chunk-WGFXFKBB.js";
|
|
@@ -27,7 +27,7 @@ import {
|
|
|
27
27
|
} from "./chunk-72ZLERW3.js";
|
|
28
28
|
import {
|
|
29
29
|
EXPLAIN_ARGS
|
|
30
|
-
} from "./chunk-
|
|
30
|
+
} from "./chunk-K363W33X.js";
|
|
31
31
|
import {
|
|
32
32
|
consoleIO
|
|
33
33
|
} from "./chunk-SLUMRYUD.js";
|
package/dist/gunshi-registry.js
CHANGED
|
@@ -4,10 +4,10 @@ import {
|
|
|
4
4
|
import "./chunk-CTMKTFST.js";
|
|
5
5
|
import {
|
|
6
6
|
ROOT_ARGS
|
|
7
|
-
} from "./chunk-
|
|
7
|
+
} from "./chunk-4FOGEXGH.js";
|
|
8
8
|
import "./chunk-DZVXCUHG.js";
|
|
9
9
|
import "./chunk-RSSMIHIM.js";
|
|
10
|
-
import "./chunk-
|
|
10
|
+
import "./chunk-5YVVJMZM.js";
|
|
11
11
|
import "./chunk-WGFXFKBB.js";
|
|
12
12
|
import "./chunk-MLIODPHZ.js";
|
|
13
13
|
import {
|
package/dist/index.d.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { Config, Severity, RuleSetting, Category, Result } from '@svelte-vitals/core';
|
|
2
2
|
export { defineConfig } from '@svelte-vitals/core';
|
|
3
3
|
import { AST } from 'svelte/compiler';
|
|
4
|
-
import { HeadTag, BranchStep, RuleOptionsSpec } from '@svelte-vitals/core/internal';
|
|
4
|
+
import { HeadTag, BranchStep, SuppressionDirective, RuleOptionsSpec } from '@svelte-vitals/core/internal';
|
|
5
5
|
|
|
6
6
|
/** A resolved import binding: which module, and which export ('default' for default imports). */
|
|
7
7
|
interface ImportInfo {
|
|
@@ -58,6 +58,10 @@ interface ParsedA11y {
|
|
|
58
58
|
slotInLandmark?: string;
|
|
59
59
|
/** file contains {@html} or a spread attribute — poisons the closed world for no-missing-id-ref */
|
|
60
60
|
unknowableContent: boolean;
|
|
61
|
+
/** Distinct lowercased tag names of the body's `RegularElement`s (a11y/required-element's presence set). */
|
|
62
|
+
elementTags: string[];
|
|
63
|
+
/** file contains `{@html}` or a `<svelte:element>` — either can render an element the walk cannot see */
|
|
64
|
+
elementsUnknowable: boolean;
|
|
61
65
|
}
|
|
62
66
|
interface ParsedFile {
|
|
63
67
|
headTags: ParsedTag[];
|
|
@@ -66,6 +70,10 @@ interface ParsedFile {
|
|
|
66
70
|
images: ParsedImage[];
|
|
67
71
|
headings: ParsedHeading[];
|
|
68
72
|
a11y: ParsedA11y;
|
|
73
|
+
/** Inline `svelte-vitals-disable-next-line` directives in this file, for the central
|
|
74
|
+
* suppression pass. Collected here because a route-scoped finding can be located in any file
|
|
75
|
+
* the composition reads, including ones no component-fact collection visited (`--route`). */
|
|
76
|
+
suppressions: SuppressionDirective[];
|
|
69
77
|
}
|
|
70
78
|
|
|
71
79
|
/**
|
package/dist/index.js
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "svelte-vitals",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.49.0",
|
|
4
4
|
"description": "A deterministic SvelteKit code-health scanner (SEO, performance, correctness, security, architecture, accessibility).",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"license": "MIT",
|
|
@@ -52,7 +52,7 @@
|
|
|
52
52
|
"magicast": "^0.5.4",
|
|
53
53
|
"svelte": "^5.56.9",
|
|
54
54
|
"tinyglobby": "^0.2.17",
|
|
55
|
-
"@svelte-vitals/core": "0.
|
|
55
|
+
"@svelte-vitals/core": "0.46.0"
|
|
56
56
|
},
|
|
57
57
|
"devDependencies": {
|
|
58
58
|
"@gunshi/docs": "0.37.1",
|