@svelte-vitals/core 0.34.0 → 0.36.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 +33 -1
- package/dist/index.js +227 -45
- package/package.json +1 -1
package/dist/index.d.ts
CHANGED
|
@@ -1269,6 +1269,24 @@ declare const architectureDirectoryNaming: Rule;
|
|
|
1269
1269
|
*/
|
|
1270
1270
|
declare const architectureReservedDirectoryNames: Rule;
|
|
1271
1271
|
|
|
1272
|
+
/**
|
|
1273
|
+
* architecture/reserved-name-placement — a reserved directory name may appear only in the places
|
|
1274
|
+
* declared for it (design 2026-08-06). L3: inert until a placement is declared.
|
|
1275
|
+
*
|
|
1276
|
+
* The sibling `architecture/reserved-directory-names` says "at this position, only these names"; it
|
|
1277
|
+
* cannot say "this name, only at these positions", which for a name appearing in several kinds of
|
|
1278
|
+
* place is what a convention actually states.
|
|
1279
|
+
*
|
|
1280
|
+
* All three maps match the same directory — the reserved-name directory's parent — and differ only in
|
|
1281
|
+
* what else they require of it: nothing, that it is a capitalised unit, that it is a unit of either
|
|
1282
|
+
* case. A name's permitted positions are the UNION of its entries across the three, because a real
|
|
1283
|
+
* convention permits one name under a unit, under a grouping and under a route directory at once.
|
|
1284
|
+
*
|
|
1285
|
+
* There are no pass results, for the reason the sibling records: `computeScore` seeds every distinct
|
|
1286
|
+
* `route` at 100 and averages, and a directory has no pre-existing score key.
|
|
1287
|
+
*/
|
|
1288
|
+
declare const architectureReservedNamePlacement: Rule;
|
|
1289
|
+
|
|
1272
1290
|
declare const architectureRouteComponentImport: Rule;
|
|
1273
1291
|
|
|
1274
1292
|
declare const architectureDocLinkTarget: Rule;
|
|
@@ -1462,6 +1480,10 @@ interface ScoreResult {
|
|
|
1462
1480
|
*/
|
|
1463
1481
|
rawScore: number;
|
|
1464
1482
|
scoreModel: ScoreModel;
|
|
1483
|
+
/** Keys this result set touched. */
|
|
1484
|
+
keys: number;
|
|
1485
|
+
/** Keys carrying at least one penalized finding. */
|
|
1486
|
+
affectedKeys: number;
|
|
1465
1487
|
}
|
|
1466
1488
|
interface ScoreOptions {
|
|
1467
1489
|
applyCriticalCap?: boolean;
|
|
@@ -1512,6 +1534,8 @@ interface JsonReport {
|
|
|
1512
1534
|
categories: Record<string, {
|
|
1513
1535
|
score: number;
|
|
1514
1536
|
scoreModel: ScoreModel;
|
|
1537
|
+
keys: number;
|
|
1538
|
+
affectedKeys: number;
|
|
1515
1539
|
}>;
|
|
1516
1540
|
summary: Summary;
|
|
1517
1541
|
rules: Record<string, RuleEvidence>;
|
|
@@ -1522,6 +1546,14 @@ interface JsonReport {
|
|
|
1522
1546
|
issues: JsonIssue[];
|
|
1523
1547
|
}>;
|
|
1524
1548
|
siteIssues: JsonIssue[];
|
|
1549
|
+
/**
|
|
1550
|
+
* Floored severity weight per `"<category>::<scope>"` pair. Reproduces a `routes[].categories` entry
|
|
1551
|
+
* (`100 - 100 * failed / inventories[pair]`): a key is either a route id or a source file path, and
|
|
1552
|
+
* those two key spaces never overlap, so a category's results on one key always draw on a single scope.
|
|
1553
|
+
* It does not reproduce `routes[].score`: a route spanning more than one pair sums their *raw* weights
|
|
1554
|
+
* and floors that sum once, so adding this map's already-floored entries and re-dividing can disagree.
|
|
1555
|
+
*/
|
|
1556
|
+
inventories: Record<string, number>;
|
|
1525
1557
|
}
|
|
1526
1558
|
/** Build the structured JSON report object (design §7). The shape the `json` reporter emits (issue #24). */
|
|
1527
1559
|
declare function buildJsonReport(results: Result[], config: Config, meta: {
|
|
@@ -1622,4 +1654,4 @@ declare function escapeHtml(s: string): string;
|
|
|
1622
1654
|
*/
|
|
1623
1655
|
declare function safeHref(url: string): string | null;
|
|
1624
1656
|
|
|
1625
|
-
export { APP_SCRIPT, APP_STYLE, type AppSnapshot, BAND_COLOR, CATEGORIES, CHILD_NODE_KEYS, type Category, type Classification, type CompiledOverride, 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 KitAlias, type KitModuleFacts, type OrphanEffectFact, type Palette, type Presence, type Project, ROBOTS_SOURCE_PATHS, type RawKitAliases, type ResolvedHead, type ResolvedHeadings, type ResolvedImages, type Result, type RouteBadge, type Rule, type RuleContext, type RuleEvidence, type RuleInfo, type RuleOptionInfo, type RuleOptionSpec, type RuleOptions, type RuleOptionsSpec, type RuleOverride, type RuleSetting, type RuleSettingObject, type Runtime, SITEMAP_SOURCE_PATHS, SVELTE_CONFIG_FILES, type Scope, type ScoreModel, type ScoreOptions, type ScoreResult, type Severity, type SourceSpan, type Summary, type SuppressionDirective, type TreatDynamicAs, VITE_CONFIG_FILES, type Value, type ViteKitConfigResult, allRules, applyOverrides, applyRuleSeverities, architectureComponentSize, architectureDirectoryNaming, architectureDocLinkTarget, architecturePrivateScopeImport, architecturePropCount, architectureReservedDirectoryNames, architectureRouteComponentImport, architectureUnitEntryFile, attrText, attrTextOf, attrValue, attrValueOf, buildHtmlDocument, buildJsonReport, classify, collectComponentFacts, collectKitModuleFacts, collectSourceFiles, compileOverrides, computeHealth, computeScore, correctnessBasePathNavigation, correctnessCheckableBindValue, correctnessEachIndexKey, correctnessEachKey, correctnessEffectAsDerived, correctnessEffectAsOnMount, correctnessInstanceBrowserGlobal, correctnessNonreactiveBuiltinState, correctnessOrphanEffect, correctnessOrphanLifecycle, correctnessPropMutation, correctnessServerBrowserGlobal, correctnessStalePropDerivation, correctnessUnmutatedState, defaultConfig, defaultProject, defineConfig, docsUrlFor, effectiveSeverity, emptyComponentFacts, emptyKitModuleFacts, escapeHtml, explainRule, findAttr, findKitAliasesInSvelteConfig, findKitPathsBaseInSvelteConfig, findKitPathsBaseInViteConfig, findMinifyDisabled, formatAgentReport, formatConsoleReport, formatGithubReport, formatHtmlReport, formatJsonReport, formatMarkdownReport, formatSarifReport, hasFailureAtOrAbove, headTagRule, imageRule, intOption, isMentionedAnywhere, isPenalized, lineOf, linkRule, listOption, mapOption, noColorPalette, overrideMatches, parseComponentFacts, parseKitModuleFacts, performanceFontPreloadCrossorigin, performanceHeavyImport, performanceImageDimensions, performanceImageLoadingHint, performanceLcpImage, performanceLoadWaterfall, performanceMinifyDisabled, performanceNamespaceImport, performancePreconnect, performancePreloadMissingAs, performanceRenderBlockingScript, performanceResponsiveImage, performanceSequentialAwaits, performanceStateRaw, renderAppShell, resolveKitAliases, resolveKitPathsBase, resolveRuleOptions, resolveRunesModuleSpecifier, runRules, safeHref, scoreBand, scoreColor, scoresByCategory, securityHandlerStateWrite, securityJavascriptUrl, securityRawHtml, securityServerModuleState, securitySharedStateImport, selectRules, seoCanonicalUrl, seoCharset, seoDescriptionLength, seoDescriptionPresence, seoDuplicateDescription, seoDuplicateTitle, seoHeadingLevelSkip, seoHreflang, seoHtmlLang, seoImageAlt, seoIndexability, seoJsonLd, seoJsonLdDateFormat, seoJsonLdDeprecatedType, seoJsonLdPlaceholder, seoJsonLdRelativeUrl, seoJsonLdRequiredProps, seoJsonLdValidity, seoOgDescription, seoOgImage, seoOgTitle, seoOgUrl, seoRobotsTxt, seoSingleH1, seoSitemapInRobots, seoSitemapXml, seoSsrDisabled, seoTitleLength, seoTitlePresence, seoTwitterCard, seoViewport, settingOptions, settingSeverity, shouldSkipRangeCheck, summarize, textFromNodes, validateRuleOptions, validateRuleSetting, valueFromNodes };
|
|
1657
|
+
export { APP_SCRIPT, APP_STYLE, type AppSnapshot, BAND_COLOR, CATEGORIES, CHILD_NODE_KEYS, type Category, type Classification, type CompiledOverride, 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 KitAlias, type KitModuleFacts, type OrphanEffectFact, type Palette, type Presence, type Project, ROBOTS_SOURCE_PATHS, type RawKitAliases, type ResolvedHead, type ResolvedHeadings, type ResolvedImages, type Result, type RouteBadge, type Rule, type RuleContext, type RuleEvidence, type RuleInfo, type RuleOptionInfo, type RuleOptionSpec, type RuleOptions, type RuleOptionsSpec, type RuleOverride, type RuleSetting, type RuleSettingObject, type Runtime, SITEMAP_SOURCE_PATHS, SVELTE_CONFIG_FILES, type Scope, type ScoreModel, type ScoreOptions, type ScoreResult, type Severity, type SourceSpan, type Summary, type SuppressionDirective, type TreatDynamicAs, VITE_CONFIG_FILES, type Value, type ViteKitConfigResult, allRules, applyOverrides, applyRuleSeverities, architectureComponentSize, architectureDirectoryNaming, architectureDocLinkTarget, architecturePrivateScopeImport, architecturePropCount, architectureReservedDirectoryNames, architectureReservedNamePlacement, architectureRouteComponentImport, architectureUnitEntryFile, attrText, attrTextOf, attrValue, attrValueOf, buildHtmlDocument, buildJsonReport, classify, collectComponentFacts, collectKitModuleFacts, collectSourceFiles, compileOverrides, computeHealth, computeScore, correctnessBasePathNavigation, correctnessCheckableBindValue, correctnessEachIndexKey, correctnessEachKey, correctnessEffectAsDerived, correctnessEffectAsOnMount, correctnessInstanceBrowserGlobal, correctnessNonreactiveBuiltinState, correctnessOrphanEffect, correctnessOrphanLifecycle, correctnessPropMutation, correctnessServerBrowserGlobal, correctnessStalePropDerivation, correctnessUnmutatedState, defaultConfig, defaultProject, defineConfig, docsUrlFor, effectiveSeverity, emptyComponentFacts, emptyKitModuleFacts, escapeHtml, explainRule, findAttr, findKitAliasesInSvelteConfig, findKitPathsBaseInSvelteConfig, findKitPathsBaseInViteConfig, findMinifyDisabled, formatAgentReport, formatConsoleReport, formatGithubReport, formatHtmlReport, formatJsonReport, formatMarkdownReport, formatSarifReport, hasFailureAtOrAbove, headTagRule, imageRule, intOption, isMentionedAnywhere, isPenalized, lineOf, linkRule, listOption, mapOption, noColorPalette, overrideMatches, parseComponentFacts, parseKitModuleFacts, performanceFontPreloadCrossorigin, performanceHeavyImport, performanceImageDimensions, performanceImageLoadingHint, performanceLcpImage, performanceLoadWaterfall, performanceMinifyDisabled, performanceNamespaceImport, performancePreconnect, performancePreloadMissingAs, performanceRenderBlockingScript, performanceResponsiveImage, performanceSequentialAwaits, performanceStateRaw, renderAppShell, resolveKitAliases, resolveKitPathsBase, resolveRuleOptions, resolveRunesModuleSpecifier, runRules, safeHref, scoreBand, scoreColor, scoresByCategory, securityHandlerStateWrite, securityJavascriptUrl, securityRawHtml, securityServerModuleState, securitySharedStateImport, selectRules, seoCanonicalUrl, seoCharset, seoDescriptionLength, seoDescriptionPresence, seoDuplicateDescription, seoDuplicateTitle, seoHeadingLevelSkip, seoHreflang, seoHtmlLang, seoImageAlt, seoIndexability, seoJsonLd, seoJsonLdDateFormat, seoJsonLdDeprecatedType, seoJsonLdPlaceholder, seoJsonLdRelativeUrl, seoJsonLdRequiredProps, seoJsonLdValidity, seoOgDescription, seoOgImage, seoOgTitle, seoOgUrl, seoRobotsTxt, seoSingleH1, seoSitemapInRobots, seoSitemapXml, seoSsrDisabled, seoTitleLength, seoTitlePresence, seoTwitterCard, seoViewport, settingOptions, settingSeverity, shouldSkipRangeCheck, summarize, textFromNodes, validateRuleOptions, validateRuleSetting, valueFromNodes };
|
package/dist/index.js
CHANGED
|
@@ -2499,7 +2499,7 @@ function detect(head, match) {
|
|
|
2499
2499
|
return tag ? { presence: tag.presence, value: tag.value } : { presence: "none", value: "absent" };
|
|
2500
2500
|
}
|
|
2501
2501
|
function headTagRule(opts) {
|
|
2502
|
-
const
|
|
2502
|
+
const docsUrl12 = docsUrlFor(opts.id);
|
|
2503
2503
|
return {
|
|
2504
2504
|
id: opts.id,
|
|
2505
2505
|
title: opts.title,
|
|
@@ -2522,7 +2522,7 @@ function headTagRule(opts) {
|
|
|
2522
2522
|
location: head.file,
|
|
2523
2523
|
message,
|
|
2524
2524
|
recommendation: opts.recommendation,
|
|
2525
|
-
docsUrl:
|
|
2525
|
+
docsUrl: docsUrl12,
|
|
2526
2526
|
// Copy per finding: opts.fix is a rule-level template shared across all
|
|
2527
2527
|
// results this rule emits; a fresh object keeps findings independent.
|
|
2528
2528
|
...opts.fix ? { fix: { ...opts.fix } } : {}
|
|
@@ -2715,7 +2715,7 @@ var seoHtmlLang = {
|
|
|
2715
2715
|
|
|
2716
2716
|
// src/rules/perf/image-rule.ts
|
|
2717
2717
|
function imageRule(opts) {
|
|
2718
|
-
const
|
|
2718
|
+
const docsUrl12 = docsUrlFor(opts.id);
|
|
2719
2719
|
const category = opts.category ?? "performance";
|
|
2720
2720
|
return {
|
|
2721
2721
|
id: opts.id,
|
|
@@ -2739,7 +2739,7 @@ function imageRule(opts) {
|
|
|
2739
2739
|
route: route.route,
|
|
2740
2740
|
message: opts.label,
|
|
2741
2741
|
recommendation: opts.recommendation,
|
|
2742
|
-
docsUrl:
|
|
2742
|
+
docsUrl: docsUrl12
|
|
2743
2743
|
});
|
|
2744
2744
|
continue;
|
|
2745
2745
|
}
|
|
@@ -2754,7 +2754,7 @@ function imageRule(opts) {
|
|
|
2754
2754
|
...img.line > 0 ? { line: img.line } : {},
|
|
2755
2755
|
message: `Missing ${opts.label}`,
|
|
2756
2756
|
recommendation: opts.recommendation,
|
|
2757
|
-
docsUrl:
|
|
2757
|
+
docsUrl: docsUrl12,
|
|
2758
2758
|
...opts.fix ? { fix: { ...opts.fix } } : {}
|
|
2759
2759
|
});
|
|
2760
2760
|
}
|
|
@@ -2814,7 +2814,7 @@ var performanceResponsiveImage = imageRule({
|
|
|
2814
2814
|
|
|
2815
2815
|
// src/rules/perf/link-rule.ts
|
|
2816
2816
|
function linkRule(opts) {
|
|
2817
|
-
const
|
|
2817
|
+
const docsUrl12 = docsUrlFor(opts.id);
|
|
2818
2818
|
return {
|
|
2819
2819
|
id: opts.id,
|
|
2820
2820
|
title: opts.title,
|
|
@@ -2838,7 +2838,7 @@ function linkRule(opts) {
|
|
|
2838
2838
|
route: head.route,
|
|
2839
2839
|
message: opts.label,
|
|
2840
2840
|
recommendation: opts.recommendation,
|
|
2841
|
-
docsUrl:
|
|
2841
|
+
docsUrl: docsUrl12
|
|
2842
2842
|
});
|
|
2843
2843
|
continue;
|
|
2844
2844
|
}
|
|
@@ -2855,7 +2855,7 @@ function linkRule(opts) {
|
|
|
2855
2855
|
location: tag.file ?? head.file,
|
|
2856
2856
|
message: `Missing ${opts.label}`,
|
|
2857
2857
|
recommendation: opts.recommendation,
|
|
2858
|
-
docsUrl:
|
|
2858
|
+
docsUrl: docsUrl12,
|
|
2859
2859
|
...opts.fix ? { fix: { ...opts.fix } } : {}
|
|
2860
2860
|
});
|
|
2861
2861
|
}
|
|
@@ -3287,7 +3287,7 @@ var seoIndexability = {
|
|
|
3287
3287
|
rationale: "A noindex directive removes the page from search results; an accidental noindex on a public route silently deindexes it.",
|
|
3288
3288
|
fix: FIX5,
|
|
3289
3289
|
async check(ctx) {
|
|
3290
|
-
const
|
|
3290
|
+
const docsUrl12 = docsUrlFor("seo/indexability");
|
|
3291
3291
|
const out = [];
|
|
3292
3292
|
for (const head of ctx.heads) {
|
|
3293
3293
|
const noindexed = head.tags.some((t) => t.kind === "meta" && t.name === "robots" && t.noindex === true);
|
|
@@ -3302,7 +3302,7 @@ var seoIndexability = {
|
|
|
3302
3302
|
location: head.file,
|
|
3303
3303
|
message: "Route is noindex \u2014 verify this is intentional",
|
|
3304
3304
|
recommendation: 'If this route should be indexed, remove noindex from its <meta name="robots">.',
|
|
3305
|
-
docsUrl:
|
|
3305
|
+
docsUrl: docsUrl12,
|
|
3306
3306
|
fix: { ...FIX5 }
|
|
3307
3307
|
});
|
|
3308
3308
|
}
|
|
@@ -3553,7 +3553,7 @@ function jsonldTags(head) {
|
|
|
3553
3553
|
return head.tags.filter((t) => t.kind === "jsonld" && typeof t.jsonld === "string");
|
|
3554
3554
|
}
|
|
3555
3555
|
function jsonldRule(opts) {
|
|
3556
|
-
const
|
|
3556
|
+
const docsUrl12 = docsUrlFor(opts.id);
|
|
3557
3557
|
return {
|
|
3558
3558
|
id: opts.id,
|
|
3559
3559
|
title: opts.title,
|
|
@@ -3581,7 +3581,7 @@ function jsonldRule(opts) {
|
|
|
3581
3581
|
location: head.file,
|
|
3582
3582
|
message: problem,
|
|
3583
3583
|
recommendation: opts.recommendation,
|
|
3584
|
-
docsUrl:
|
|
3584
|
+
docsUrl: docsUrl12,
|
|
3585
3585
|
...opts.fix ? { fix: { ...opts.fix } } : {}
|
|
3586
3586
|
} : {
|
|
3587
3587
|
id: opts.id,
|
|
@@ -3591,7 +3591,7 @@ function jsonldRule(opts) {
|
|
|
3591
3591
|
route: head.route,
|
|
3592
3592
|
message: opts.label,
|
|
3593
3593
|
recommendation: opts.recommendation,
|
|
3594
|
-
docsUrl:
|
|
3594
|
+
docsUrl: docsUrl12
|
|
3595
3595
|
}
|
|
3596
3596
|
);
|
|
3597
3597
|
}
|
|
@@ -3615,7 +3615,7 @@ var seoJsonLdValidity = {
|
|
|
3615
3615
|
lang: "svelte"
|
|
3616
3616
|
},
|
|
3617
3617
|
async check(ctx) {
|
|
3618
|
-
const
|
|
3618
|
+
const docsUrl12 = docsUrlFor("seo/json-ld-validity");
|
|
3619
3619
|
const out = [];
|
|
3620
3620
|
for (const head of ctx.heads) {
|
|
3621
3621
|
for (const tag of jsonldTags(head)) {
|
|
@@ -3634,7 +3634,7 @@ var seoJsonLdValidity = {
|
|
|
3634
3634
|
location: head.file,
|
|
3635
3635
|
message: problem,
|
|
3636
3636
|
recommendation: "Make the JSON-LD valid JSON with both @context and @type.",
|
|
3637
|
-
docsUrl:
|
|
3637
|
+
docsUrl: docsUrl12,
|
|
3638
3638
|
fix: { ...seoJsonLdValidity.fix }
|
|
3639
3639
|
} : {
|
|
3640
3640
|
id: "seo/json-ld-validity",
|
|
@@ -3644,7 +3644,7 @@ var seoJsonLdValidity = {
|
|
|
3644
3644
|
route: head.route,
|
|
3645
3645
|
message: "JSON-LD validity",
|
|
3646
3646
|
recommendation: "Make the JSON-LD valid JSON with both @context and @type.",
|
|
3647
|
-
docsUrl:
|
|
3647
|
+
docsUrl: docsUrl12
|
|
3648
3648
|
}
|
|
3649
3649
|
);
|
|
3650
3650
|
}
|
|
@@ -3755,7 +3755,7 @@ function visibleLength(s) {
|
|
|
3755
3755
|
|
|
3756
3756
|
// src/rules/seo/length-rule.ts
|
|
3757
3757
|
function lengthRule(opts) {
|
|
3758
|
-
const
|
|
3758
|
+
const docsUrl12 = docsUrlFor(opts.id);
|
|
3759
3759
|
const spec = {
|
|
3760
3760
|
min: { kind: "integer", default: opts.min, min: 0 },
|
|
3761
3761
|
max: { kind: "integer", default: opts.max, min: 1 }
|
|
@@ -3778,7 +3778,7 @@ function lengthRule(opts) {
|
|
|
3778
3778
|
const o = resolveRuleOptions(opts.id, spec, ctx.config, { route: head.route, file: location }, compiled);
|
|
3779
3779
|
const min = intOption(o, "min", opts.min);
|
|
3780
3780
|
const max = intOption(o, "max", opts.max);
|
|
3781
|
-
const
|
|
3781
|
+
const recommendation12 = typeof opts.recommendation === "function" ? opts.recommendation(o) : opts.recommendation;
|
|
3782
3782
|
const len = visibleLength(tag.text);
|
|
3783
3783
|
let problem;
|
|
3784
3784
|
if (len < min) problem = `${opts.noun} is too short (${len} chars; aim for ${min}\u2013${max})`;
|
|
@@ -3792,8 +3792,8 @@ function lengthRule(opts) {
|
|
|
3792
3792
|
route: head.route,
|
|
3793
3793
|
location,
|
|
3794
3794
|
message: problem,
|
|
3795
|
-
recommendation:
|
|
3796
|
-
docsUrl:
|
|
3795
|
+
recommendation: recommendation12,
|
|
3796
|
+
docsUrl: docsUrl12
|
|
3797
3797
|
} : {
|
|
3798
3798
|
id: opts.id,
|
|
3799
3799
|
category: "seo",
|
|
@@ -3801,8 +3801,8 @@ function lengthRule(opts) {
|
|
|
3801
3801
|
detection: PASS,
|
|
3802
3802
|
route: head.route,
|
|
3803
3803
|
message: opts.label,
|
|
3804
|
-
recommendation:
|
|
3805
|
-
docsUrl:
|
|
3804
|
+
recommendation: recommendation12,
|
|
3805
|
+
docsUrl: docsUrl12
|
|
3806
3806
|
}
|
|
3807
3807
|
);
|
|
3808
3808
|
}
|
|
@@ -3987,7 +3987,7 @@ var seoSingleH1 = {
|
|
|
3987
3987
|
|
|
3988
3988
|
// src/rules/seo/uniqueness-rule.ts
|
|
3989
3989
|
function uniquenessRule(opts) {
|
|
3990
|
-
const
|
|
3990
|
+
const docsUrl12 = docsUrlFor(opts.id);
|
|
3991
3991
|
return {
|
|
3992
3992
|
id: opts.id,
|
|
3993
3993
|
title: opts.title,
|
|
@@ -4017,7 +4017,7 @@ function uniquenessRule(opts) {
|
|
|
4017
4017
|
location: e.file,
|
|
4018
4018
|
message: `${opts.noun} is duplicated across ${n} routes`,
|
|
4019
4019
|
recommendation: opts.recommendation,
|
|
4020
|
-
docsUrl:
|
|
4020
|
+
docsUrl: docsUrl12
|
|
4021
4021
|
} : {
|
|
4022
4022
|
id: opts.id,
|
|
4023
4023
|
category: "seo",
|
|
@@ -4026,7 +4026,7 @@ function uniquenessRule(opts) {
|
|
|
4026
4026
|
route: e.route,
|
|
4027
4027
|
message: opts.label,
|
|
4028
4028
|
recommendation: opts.recommendation,
|
|
4029
|
-
docsUrl:
|
|
4029
|
+
docsUrl: docsUrl12
|
|
4030
4030
|
};
|
|
4031
4031
|
});
|
|
4032
4032
|
}
|
|
@@ -4114,7 +4114,7 @@ function isSuppressed(m, ruleId, line) {
|
|
|
4114
4114
|
return (m.suppressions ?? []).some((s) => s.line === line && (!s.ruleIds || s.ruleIds.includes(ruleId)));
|
|
4115
4115
|
}
|
|
4116
4116
|
function kitModuleRule(opts) {
|
|
4117
|
-
const
|
|
4117
|
+
const docsUrl12 = docsUrlFor(opts.id);
|
|
4118
4118
|
const severity = opts.severity ?? "warning";
|
|
4119
4119
|
return {
|
|
4120
4120
|
id: opts.id,
|
|
@@ -4138,7 +4138,7 @@ function kitModuleRule(opts) {
|
|
|
4138
4138
|
route: m.file,
|
|
4139
4139
|
message: opts.label,
|
|
4140
4140
|
recommendation: opts.recommendation,
|
|
4141
|
-
docsUrl:
|
|
4141
|
+
docsUrl: docsUrl12
|
|
4142
4142
|
});
|
|
4143
4143
|
continue;
|
|
4144
4144
|
}
|
|
@@ -4153,7 +4153,7 @@ function kitModuleRule(opts) {
|
|
|
4153
4153
|
...b.line > 0 ? { line: b.line } : {},
|
|
4154
4154
|
message: b.message,
|
|
4155
4155
|
recommendation: opts.recommendation,
|
|
4156
|
-
docsUrl:
|
|
4156
|
+
docsUrl: docsUrl12,
|
|
4157
4157
|
...opts.fix ? { fix: { ...opts.fix } } : {}
|
|
4158
4158
|
});
|
|
4159
4159
|
}
|
|
@@ -4189,7 +4189,7 @@ function isSuppressed2(c, ruleId, line) {
|
|
|
4189
4189
|
return (c.suppressions ?? []).some((s) => s.line === line && (!s.ruleIds || s.ruleIds.includes(ruleId)));
|
|
4190
4190
|
}
|
|
4191
4191
|
function componentRule(opts) {
|
|
4192
|
-
const
|
|
4192
|
+
const docsUrl12 = docsUrlFor(opts.id);
|
|
4193
4193
|
const severity = opts.severity ?? "warning";
|
|
4194
4194
|
return {
|
|
4195
4195
|
id: opts.id,
|
|
@@ -4205,7 +4205,7 @@ function componentRule(opts) {
|
|
|
4205
4205
|
const compiled = compileOverrides(ctx.config);
|
|
4206
4206
|
for (const c of ctx.components ?? []) {
|
|
4207
4207
|
const o = resolveRuleOptions(opts.id, opts.options, ctx.config, { route: c.file, file: c.file }, compiled);
|
|
4208
|
-
const
|
|
4208
|
+
const recommendation12 = typeof opts.recommendation === "function" ? opts.recommendation(o) : opts.recommendation;
|
|
4209
4209
|
if (!opts.applies(c, o, ctx)) continue;
|
|
4210
4210
|
const bad = opts.bad(c, o, ctx).filter((b) => !(b.line > 0 && isSuppressed2(c, opts.id, b.line)));
|
|
4211
4211
|
if (bad.length === 0) {
|
|
@@ -4216,8 +4216,8 @@ function componentRule(opts) {
|
|
|
4216
4216
|
detection: PASS3,
|
|
4217
4217
|
route: c.file,
|
|
4218
4218
|
message: opts.label,
|
|
4219
|
-
recommendation:
|
|
4220
|
-
docsUrl:
|
|
4219
|
+
recommendation: recommendation12,
|
|
4220
|
+
docsUrl: docsUrl12
|
|
4221
4221
|
});
|
|
4222
4222
|
continue;
|
|
4223
4223
|
}
|
|
@@ -4231,8 +4231,8 @@ function componentRule(opts) {
|
|
|
4231
4231
|
location: c.file,
|
|
4232
4232
|
...b.line > 0 ? { line: b.line } : {},
|
|
4233
4233
|
message: b.message,
|
|
4234
|
-
recommendation:
|
|
4235
|
-
docsUrl:
|
|
4234
|
+
recommendation: recommendation12,
|
|
4235
|
+
docsUrl: docsUrl12,
|
|
4236
4236
|
...opts.fix ? { fix: { ...opts.fix } } : {}
|
|
4237
4237
|
});
|
|
4238
4238
|
}
|
|
@@ -5265,9 +5265,11 @@ function stem(file) {
|
|
|
5265
5265
|
return dot === -1 ? file : file.slice(0, dot);
|
|
5266
5266
|
}
|
|
5267
5267
|
function isUnitDir(dir, filesIn) {
|
|
5268
|
+
const first = baseName(dir).charCodeAt(0);
|
|
5269
|
+
return first >= 65 && first <= 90 && isAnyCaseUnitDir(dir, filesIn);
|
|
5270
|
+
}
|
|
5271
|
+
function isAnyCaseUnitDir(dir, filesIn) {
|
|
5268
5272
|
const name = baseName(dir);
|
|
5269
|
-
const first = name.charCodeAt(0);
|
|
5270
|
-
if (!(first >= 65 && first <= 90)) return false;
|
|
5271
5273
|
const own = filesIn.get(dir);
|
|
5272
5274
|
return own !== void 0 && own.some((f) => stem(f) === name);
|
|
5273
5275
|
}
|
|
@@ -5415,8 +5417,171 @@ var architectureReservedDirectoryNames = {
|
|
|
5415
5417
|
}
|
|
5416
5418
|
};
|
|
5417
5419
|
|
|
5420
|
+
// src/rules/architecture/reserved-name-placement.ts
|
|
5421
|
+
var ID7 = "architecture/reserved-name-placement";
|
|
5422
|
+
var docsUrl11 = docsUrlFor(ID7);
|
|
5423
|
+
var recommendation11 = "Move it to one of the places declared for this name, or declare this place for it.";
|
|
5424
|
+
var fixDescription = "Move the directory to one of the places declared for its name, rename it, or declare this place for the name.";
|
|
5425
|
+
var OPTIONS6 = {
|
|
5426
|
+
placements: { kind: "string-map", default: {} },
|
|
5427
|
+
capitalisedUnitPlacements: { kind: "string-map", default: {} },
|
|
5428
|
+
anyCaseUnitPlacements: { kind: "string-map", default: {} },
|
|
5429
|
+
exclude: { kind: "string-list", default: [] }
|
|
5430
|
+
};
|
|
5431
|
+
function parentOf(dir) {
|
|
5432
|
+
const cut = dir.lastIndexOf("/");
|
|
5433
|
+
return cut === -1 ? void 0 : dir.slice(0, cut);
|
|
5434
|
+
}
|
|
5435
|
+
var architectureReservedNamePlacement = {
|
|
5436
|
+
id: ID7,
|
|
5437
|
+
title: "Reserved name placement",
|
|
5438
|
+
category: "architecture",
|
|
5439
|
+
severity: "info",
|
|
5440
|
+
scope: "component",
|
|
5441
|
+
rationale: "A name reserved for one kind of place stops carrying that meaning the moment it appears somewhere else: a reader who has met one exception has to open the directory to learn what it holds.",
|
|
5442
|
+
fix: {
|
|
5443
|
+
description: fixDescription
|
|
5444
|
+
},
|
|
5445
|
+
options: OPTIONS6,
|
|
5446
|
+
async check(ctx) {
|
|
5447
|
+
const files = ctx.sourceFiles;
|
|
5448
|
+
if (files === void 0) return [];
|
|
5449
|
+
if (!isMentionedAnywhere(ctx.config, ID7)) return [];
|
|
5450
|
+
const compiledOverrides = compileOverrides(ctx.config);
|
|
5451
|
+
const dirs = /* @__PURE__ */ new Set();
|
|
5452
|
+
for (const f of files) for (const d of ancestorDirs2(f)) dirs.add(d);
|
|
5453
|
+
const filesIn = childFiles(files);
|
|
5454
|
+
const compile = createKeyCompiler();
|
|
5455
|
+
const parsed = /* @__PURE__ */ new Map();
|
|
5456
|
+
const globsOf = (value) => {
|
|
5457
|
+
let g = parsed.get(value);
|
|
5458
|
+
if (g === void 0) parsed.set(value, g = splitNames(value));
|
|
5459
|
+
return g;
|
|
5460
|
+
};
|
|
5461
|
+
const out = [];
|
|
5462
|
+
const label = (map, name, glob) => `${map}.${name} \u2192 ${glob}`;
|
|
5463
|
+
const globalOptions = resolveRuleOptions(ID7, OPTIONS6, ctx.config);
|
|
5464
|
+
const globalMaps = {
|
|
5465
|
+
placements: mapOption(globalOptions, "placements"),
|
|
5466
|
+
capitalisedUnitPlacements: mapOption(globalOptions, "capitalisedUnitPlacements"),
|
|
5467
|
+
anyCaseUnitPlacements: mapOption(globalOptions, "anyCaseUnitPlacements")
|
|
5468
|
+
};
|
|
5469
|
+
const globalAlternatives = /* @__PURE__ */ new Map();
|
|
5470
|
+
const emptyNames = /* @__PURE__ */ new Map();
|
|
5471
|
+
for (const map of Object.keys(globalMaps)) {
|
|
5472
|
+
for (const [name, value] of Object.entries(globalMaps[map])) {
|
|
5473
|
+
const globs2 = globsOf(value);
|
|
5474
|
+
if (globs2.length === 0) {
|
|
5475
|
+
emptyNames.set(`${map}.${name}`, "names no position at all");
|
|
5476
|
+
continue;
|
|
5477
|
+
}
|
|
5478
|
+
for (const glob of globs2) globalAlternatives.set(label(map, name, glob), { map, glob });
|
|
5479
|
+
}
|
|
5480
|
+
}
|
|
5481
|
+
const usedAlternatives = /* @__PURE__ */ new Set();
|
|
5482
|
+
const excludedDirs = [];
|
|
5483
|
+
const nonUnitParents = {
|
|
5484
|
+
capitalisedUnitPlacements: [],
|
|
5485
|
+
anyCaseUnitPlacements: []
|
|
5486
|
+
};
|
|
5487
|
+
const allDirs = [...dirs].sort();
|
|
5488
|
+
for (const dir of allDirs) {
|
|
5489
|
+
const o = resolveRuleOptions(ID7, OPTIONS6, ctx.config, { route: dir, file: dir }, compiledOverrides);
|
|
5490
|
+
const placements = mapOption(o, "placements");
|
|
5491
|
+
const capUnits = mapOption(o, "capitalisedUnitPlacements");
|
|
5492
|
+
const anyUnits = mapOption(o, "anyCaseUnitPlacements");
|
|
5493
|
+
if (Object.keys(placements).length === 0 && Object.keys(capUnits).length === 0 && Object.keys(anyUnits).length === 0) {
|
|
5494
|
+
continue;
|
|
5495
|
+
}
|
|
5496
|
+
const name = baseName(dir);
|
|
5497
|
+
const inPlacements = Object.hasOwn(placements, name);
|
|
5498
|
+
const inCapUnits = Object.hasOwn(capUnits, name);
|
|
5499
|
+
const inAnyUnits = Object.hasOwn(anyUnits, name);
|
|
5500
|
+
if (!inPlacements && !inCapUnits && !inAnyUnits) continue;
|
|
5501
|
+
const emptyValue = (present3, value) => present3 && globsOf(value ?? "").length === 0;
|
|
5502
|
+
if (emptyValue(inPlacements, placements[name]) || emptyValue(inCapUnits, capUnits[name]) || emptyValue(inAnyUnits, anyUnits[name])) {
|
|
5503
|
+
continue;
|
|
5504
|
+
}
|
|
5505
|
+
const excluded = compile(listOption(o, "exclude"));
|
|
5506
|
+
const parent = parentOf(dir);
|
|
5507
|
+
if (parent === void 0) continue;
|
|
5508
|
+
if (isExcluded(dir, ancestorDirs2(dir), excluded)) {
|
|
5509
|
+
if (isExcluded(parent, ancestorDirs2(parent), excluded)) excludedDirs.push(parent);
|
|
5510
|
+
continue;
|
|
5511
|
+
}
|
|
5512
|
+
const record = (map, value, qualifies) => {
|
|
5513
|
+
if (value === void 0) return false;
|
|
5514
|
+
const { matched } = matchKeys(parent, compile(globsOf(value), true));
|
|
5515
|
+
if (matched.length === 0) return false;
|
|
5516
|
+
if (!qualifies) {
|
|
5517
|
+
if (map !== "placements") nonUnitParents[map].push(parent);
|
|
5518
|
+
return false;
|
|
5519
|
+
}
|
|
5520
|
+
for (const glob of matched) usedAlternatives.add(label(map, name, glob));
|
|
5521
|
+
return true;
|
|
5522
|
+
};
|
|
5523
|
+
const byPlacement = record("placements", placements[name], true);
|
|
5524
|
+
const byCapUnit = record("capitalisedUnitPlacements", capUnits[name], isUnitDir(parent, filesIn));
|
|
5525
|
+
const byAnyUnit = record("anyCaseUnitPlacements", anyUnits[name], isAnyCaseUnitDir(parent, filesIn));
|
|
5526
|
+
if (byPlacement || byCapUnit || byAnyUnit) continue;
|
|
5527
|
+
const at = reportAt(dir, files);
|
|
5528
|
+
if (at === void 0) continue;
|
|
5529
|
+
out.push({
|
|
5530
|
+
id: ID7,
|
|
5531
|
+
category: "architecture",
|
|
5532
|
+
severity: "info",
|
|
5533
|
+
detection: { presence: "none", value: "absent" },
|
|
5534
|
+
route: dir,
|
|
5535
|
+
location: at,
|
|
5536
|
+
message: `${dir} is not one of the places declared for '${name}'.`,
|
|
5537
|
+
recommendation: recommendation11,
|
|
5538
|
+
docsUrl: docsUrl11,
|
|
5539
|
+
fix: {
|
|
5540
|
+
description: fixDescription
|
|
5541
|
+
}
|
|
5542
|
+
});
|
|
5543
|
+
}
|
|
5544
|
+
const notes = new Map(emptyNames);
|
|
5545
|
+
const unusedLabels = [...globalAlternatives.keys()].filter((k) => !usedAlternatives.has(k));
|
|
5546
|
+
const globOf = (key) => globalAlternatives.get(key)?.glob;
|
|
5547
|
+
for (const map of ["capitalisedUnitPlacements", "anyCaseUnitPlacements"]) {
|
|
5548
|
+
const inMap = unusedLabels.filter((k) => globalAlternatives.get(k)?.map === map);
|
|
5549
|
+
const hit = keysMatchingAny(inMap.map(globOf), nonUnitParents[map], compile);
|
|
5550
|
+
for (const k of inMap) {
|
|
5551
|
+
if (hit.has(globOf(k))) notes.set(k, "matched directories but never a unit");
|
|
5552
|
+
}
|
|
5553
|
+
}
|
|
5554
|
+
const stillUnused = unusedLabels.filter((k) => !notes.has(k));
|
|
5555
|
+
const globs = [...new Set(stillUnused.map(globOf))];
|
|
5556
|
+
const reasons = classifyUnusedKeys(globs, excludedDirs, compile);
|
|
5557
|
+
const reachable = keysMatchingAny(globs, allDirs, compile);
|
|
5558
|
+
for (const k of stillUnused) {
|
|
5559
|
+
const glob = globOf(k);
|
|
5560
|
+
if (reasons.get(glob) === "only-excluded") {
|
|
5561
|
+
notes.set(k, "matched only excluded directories");
|
|
5562
|
+
} else if (!reachable.has(glob)) {
|
|
5563
|
+
notes.set(k, "matched no directory");
|
|
5564
|
+
}
|
|
5565
|
+
}
|
|
5566
|
+
const reported = [...notes.keys()].sort();
|
|
5567
|
+
if (reported.length > 0) {
|
|
5568
|
+
const message = reported.length === 1 ? `The declaration '${reported[0]}' does not check what it says: ${notes.get(reported[0])}.` : `These declarations do not check what they say: ${reported.map((k) => `'${k}' (${notes.get(k)})`).join(", ")}.`;
|
|
5569
|
+
out.push({
|
|
5570
|
+
id: ID7,
|
|
5571
|
+
category: "architecture",
|
|
5572
|
+
severity: "info",
|
|
5573
|
+
detection: { presence: "none", value: "absent" },
|
|
5574
|
+
message,
|
|
5575
|
+
recommendation: "Correct the glob or the name, or remove the declaration.",
|
|
5576
|
+
docsUrl: docsUrl11
|
|
5577
|
+
});
|
|
5578
|
+
}
|
|
5579
|
+
return out;
|
|
5580
|
+
}
|
|
5581
|
+
};
|
|
5582
|
+
|
|
5418
5583
|
// src/rules/architecture/route-component-import.ts
|
|
5419
|
-
var
|
|
5584
|
+
var ID8 = "architecture/route-component-import";
|
|
5420
5585
|
var EXEMPT_IMPORTERS = ["**/*.stories.svelte", "**/*.test.svelte", "**/*.spec.svelte"];
|
|
5421
5586
|
var ROUTES_DIR = "src/routes/";
|
|
5422
5587
|
var ROUTE_ENTRY = /^\+(page|layout)(@.*)?\.svelte$/;
|
|
@@ -5443,7 +5608,7 @@ function cachedRouteEntryImports(c, ctx) {
|
|
|
5443
5608
|
return result;
|
|
5444
5609
|
}
|
|
5445
5610
|
var architectureRouteComponentImport = componentRule({
|
|
5446
|
-
id:
|
|
5611
|
+
id: ID8,
|
|
5447
5612
|
title: "Route component import",
|
|
5448
5613
|
category: "architecture",
|
|
5449
5614
|
severity: "info",
|
|
@@ -5467,7 +5632,7 @@ var architectureRouteComponentImport = componentRule({
|
|
|
5467
5632
|
});
|
|
5468
5633
|
|
|
5469
5634
|
// src/rules/architecture/doc-link-target.ts
|
|
5470
|
-
var
|
|
5635
|
+
var ID9 = "architecture/doc-link-target";
|
|
5471
5636
|
function stripFragment(url) {
|
|
5472
5637
|
const i = url.search(/[#?]/);
|
|
5473
5638
|
return i === -1 ? url : url.slice(0, i);
|
|
@@ -5508,7 +5673,7 @@ function references(links, roots) {
|
|
|
5508
5673
|
return out;
|
|
5509
5674
|
}
|
|
5510
5675
|
var architectureDocLinkTarget = componentRule({
|
|
5511
|
-
id:
|
|
5676
|
+
id: ID9,
|
|
5512
5677
|
title: "Documentation link target",
|
|
5513
5678
|
category: "architecture",
|
|
5514
5679
|
severity: "info",
|
|
@@ -5735,6 +5900,7 @@ var allRules = [
|
|
|
5735
5900
|
architectureUnitEntryFile,
|
|
5736
5901
|
architectureDirectoryNaming,
|
|
5737
5902
|
architectureReservedDirectoryNames,
|
|
5903
|
+
architectureReservedNamePlacement,
|
|
5738
5904
|
architectureRouteComponentImport,
|
|
5739
5905
|
architectureDocLinkTarget,
|
|
5740
5906
|
performanceHeavyImport,
|
|
@@ -5823,6 +5989,7 @@ function ruleScopes(rules) {
|
|
|
5823
5989
|
|
|
5824
5990
|
// src/scoring/score.ts
|
|
5825
5991
|
var CRITICAL_CAP = 79;
|
|
5992
|
+
var INVENTORY_FLOOR = 25;
|
|
5826
5993
|
function clamp(n) {
|
|
5827
5994
|
return Math.max(0, Math.min(100, n));
|
|
5828
5995
|
}
|
|
@@ -5848,14 +6015,16 @@ function computeScore(results, config, options = {}) {
|
|
|
5848
6015
|
const prev = perRule.get(r.id) ?? 0;
|
|
5849
6016
|
if (DEDUCTION[sev] > prev) perRule.set(r.id, DEDUCTION[sev]);
|
|
5850
6017
|
}
|
|
6018
|
+
let affectedKeys = 0;
|
|
5851
6019
|
let totalDeficit = 0;
|
|
5852
6020
|
for (const [key, pairs] of observed) {
|
|
5853
6021
|
let failed = 0;
|
|
5854
6022
|
for (const d of ruleMax.get(key)?.values() ?? []) failed += d;
|
|
6023
|
+
if (failed > 0) affectedKeys += 1;
|
|
5855
6024
|
let inventoryWeight = 0;
|
|
5856
6025
|
for (const p of pairs) inventoryWeight += inventory.get(p) ?? 0;
|
|
5857
|
-
inventoryWeight = Math.max(inventoryWeight, failed);
|
|
5858
|
-
totalDeficit +=
|
|
6026
|
+
inventoryWeight = Math.max(inventoryWeight, failed, INVENTORY_FLOOR);
|
|
6027
|
+
totalDeficit += 100 * failed / inventoryWeight;
|
|
5859
6028
|
}
|
|
5860
6029
|
const keyCount = observed.size;
|
|
5861
6030
|
const rawRouteAverage = keyCount === 0 ? 100 : 100 - totalDeficit / keyCount;
|
|
@@ -5875,7 +6044,13 @@ function computeScore(results, config, options = {}) {
|
|
|
5875
6044
|
const capBinds = applyCap && anyCritical && rawUncapped > CRITICAL_CAP;
|
|
5876
6045
|
const criticalCap = capBinds ? CRITICAL_CAP : null;
|
|
5877
6046
|
const rawScore = clamp(capBinds ? CRITICAL_CAP : rawUncapped);
|
|
5878
|
-
return {
|
|
6047
|
+
return {
|
|
6048
|
+
score: Math.floor(rawScore),
|
|
6049
|
+
rawScore,
|
|
6050
|
+
scoreModel: { routeAverage, sitePenalty, criticalCap },
|
|
6051
|
+
keys: keyCount,
|
|
6052
|
+
affectedKeys
|
|
6053
|
+
};
|
|
5879
6054
|
}
|
|
5880
6055
|
function scoresByCategory(results, config, options = {}) {
|
|
5881
6056
|
const byCat = /* @__PURE__ */ new Map();
|
|
@@ -6093,7 +6268,10 @@ function buildJsonReport(results, config, meta, ruleIds) {
|
|
|
6093
6268
|
const summary = summarize(results, config);
|
|
6094
6269
|
const rules = ruleEvidence(results, config, ruleIds);
|
|
6095
6270
|
const categories = Object.fromEntries(
|
|
6096
|
-
Object.entries(byCat).map(([cat, sr]) => [
|
|
6271
|
+
Object.entries(byCat).map(([cat, sr]) => [
|
|
6272
|
+
cat,
|
|
6273
|
+
{ score: sr.score, scoreModel: sr.scoreModel, keys: sr.keys, affectedKeys: sr.affectedKeys }
|
|
6274
|
+
])
|
|
6097
6275
|
);
|
|
6098
6276
|
const routeMap = /* @__PURE__ */ new Map();
|
|
6099
6277
|
for (const r of results) {
|
|
@@ -6112,7 +6290,10 @@ function buildJsonReport(results, config, meta, ruleIds) {
|
|
|
6112
6290
|
issues: rs.filter((r) => isPenalized(r.detection, config.treatDynamicAs)).map((r) => ({ ...issueOf(r), severity: effectiveSeverity(r, config) }))
|
|
6113
6291
|
}));
|
|
6114
6292
|
const siteIssues = results.filter((r) => r.route === void 0 && isPenalized(r.detection, config.treatDynamicAs)).map((r) => ({ ...issueOf(r), severity: effectiveSeverity(r, config) }));
|
|
6115
|
-
|
|
6293
|
+
const inventories = Object.fromEntries(
|
|
6294
|
+
[...buildInventory(config)].map(([pair, weight]) => [pair, Math.max(weight, INVENTORY_FLOOR)])
|
|
6295
|
+
);
|
|
6296
|
+
return { version: meta.version, score: health, weights, categories, summary, rules, routes, siteIssues, inventories };
|
|
6116
6297
|
}
|
|
6117
6298
|
function formatJsonReport(results, config, meta, ruleIds) {
|
|
6118
6299
|
return JSON.stringify(buildJsonReport(results, config, meta, ruleIds), null, 2);
|
|
@@ -7053,6 +7234,7 @@ export {
|
|
|
7053
7234
|
architecturePrivateScopeImport,
|
|
7054
7235
|
architecturePropCount,
|
|
7055
7236
|
architectureReservedDirectoryNames,
|
|
7237
|
+
architectureReservedNamePlacement,
|
|
7056
7238
|
architectureRouteComponentImport,
|
|
7057
7239
|
architectureUnitEntryFile,
|
|
7058
7240
|
attrText,
|