@forkpoint/agent-lighthouse-core 4.0.0 → 4.1.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.mts +82 -4
- package/dist/index.d.ts +82 -4
- package/dist/index.js +156 -18
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +152 -18
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -72,9 +72,11 @@ __export(index_exports, {
|
|
|
72
72
|
TAG_SCAN_ERROR: () => TAG_SCAN_ERROR,
|
|
73
73
|
TAG_SKIPPED_NO_EVIDENCE: () => TAG_SKIPPED_NO_EVIDENCE,
|
|
74
74
|
TAG_SKIPPED_PAGE_TYPE: () => TAG_SKIPPED_PAGE_TYPE,
|
|
75
|
+
TAG_SKIPPED_SCAN_BUDGET: () => TAG_SKIPPED_SCAN_BUDGET,
|
|
75
76
|
allEvidenceMet: () => allEvidenceMet,
|
|
76
77
|
allJsonLdNodes: () => allJsonLdNodes,
|
|
77
78
|
boundedDispatcher: () => boundedDispatcher,
|
|
79
|
+
budgetReason: () => budgetReason,
|
|
78
80
|
buildCategoryResult: () => buildCategoryResult,
|
|
79
81
|
buildScanEvidence: () => buildScanEvidence,
|
|
80
82
|
calculateCategoryScore: () => calculateCategoryScore,
|
|
@@ -106,6 +108,7 @@ __export(index_exports, {
|
|
|
106
108
|
extractStylesheetUrls: () => extractStylesheetUrls,
|
|
107
109
|
filterConfig: () => filterConfig,
|
|
108
110
|
flattenJsonLd: () => flattenJsonLd,
|
|
111
|
+
formatBudget: () => formatBudget,
|
|
109
112
|
formatTrace: () => formatTrace,
|
|
110
113
|
getMainContentText: () => getMainContentText,
|
|
111
114
|
getPreset: () => getPreset,
|
|
@@ -143,6 +146,7 @@ __export(index_exports, {
|
|
|
143
146
|
runScan: () => runScan,
|
|
144
147
|
sampleEntries: () => sampleEntries,
|
|
145
148
|
shouldBypassOriginCache: () => shouldBypassOriginCache,
|
|
149
|
+
skippedMassShare: () => skippedMassShare,
|
|
146
150
|
stripBom: () => stripBom,
|
|
147
151
|
topLevelJsonLd: () => topLevelJsonLd,
|
|
148
152
|
traceFromCheck: () => traceFromCheck,
|
|
@@ -157,13 +161,14 @@ var ORIGIN_EVIDENCE_VERSION = "v1";
|
|
|
157
161
|
var DEFAULT_ORIGIN_CACHE_TTL_MS = 60 * 60 * 1e3;
|
|
158
162
|
var DEFAULT_ORIGIN_CACHE_MAX_ENTRIES = 256;
|
|
159
163
|
var REQUEST_TIMEOUT_MS = 1e4;
|
|
160
|
-
var SCAN_TIMEOUT_MS =
|
|
164
|
+
var SCAN_TIMEOUT_MS = 18e4;
|
|
161
165
|
var MAX_RESPONSE_BODY_BYTES = 5 * 1024 * 1024;
|
|
162
166
|
var MAX_CONCURRENT_REQUESTS = 10;
|
|
163
167
|
var SCANNER_USER_AGENT = "AgentLighthouse/1.0 (+https://github.com/ForkPoint/agent-lighthouse)";
|
|
164
168
|
var TAG_SKIPPED_PAGE_TYPE = "skipped:page-type";
|
|
165
169
|
var TAG_SCAN_ERROR = "scan-error";
|
|
166
170
|
var TAG_SKIPPED_NO_EVIDENCE = "skipped:no-evidence";
|
|
171
|
+
var TAG_SKIPPED_SCAN_BUDGET = "skipped:scan-budget";
|
|
167
172
|
var CATEGORY_NAMES = {
|
|
168
173
|
"access-crawl-control": "Access & Crawl Control",
|
|
169
174
|
"content-extraction": "Content Extraction",
|
|
@@ -1252,7 +1257,14 @@ var ScanConditionsSchema = import_zod.z.object({
|
|
|
1252
1257
|
informativeCount: import_zod.z.number().int().nonnegative(),
|
|
1253
1258
|
gatedCount: import_zod.z.number().int().nonnegative(),
|
|
1254
1259
|
reasons: import_zod.z.record(import_zod.z.string(), import_zod.z.number().int().nonnegative())
|
|
1255
|
-
})
|
|
1260
|
+
}),
|
|
1261
|
+
// Optional: reports written before the budget existed carry no block.
|
|
1262
|
+
budget: import_zod.z.object({
|
|
1263
|
+
limitMs: import_zod.z.number().nonnegative(),
|
|
1264
|
+
elapsedMs: import_zod.z.number().nonnegative(),
|
|
1265
|
+
exhausted: import_zod.z.boolean(),
|
|
1266
|
+
skippedCount: import_zod.z.number().int().nonnegative()
|
|
1267
|
+
}).optional()
|
|
1256
1268
|
});
|
|
1257
1269
|
|
|
1258
1270
|
// src/audit.ts
|
|
@@ -1463,16 +1475,19 @@ function calculateOverallScore(categories) {
|
|
|
1463
1475
|
}
|
|
1464
1476
|
var GATED_MASS_UNSCORED_THRESHOLD = 0.35;
|
|
1465
1477
|
function gatedMassShare(checks2) {
|
|
1466
|
-
|
|
1478
|
+
return skippedMassShare(checks2, TAG_SKIPPED_NO_EVIDENCE);
|
|
1479
|
+
}
|
|
1480
|
+
function skippedMassShare(checks2, tag2) {
|
|
1481
|
+
let skipped = 0;
|
|
1467
1482
|
let total = 0;
|
|
1468
1483
|
for (const check of checks2) {
|
|
1469
1484
|
if (isInformative(check)) continue;
|
|
1470
1485
|
const mass = check.weight ?? 0;
|
|
1471
1486
|
if (mass <= 0) continue;
|
|
1472
1487
|
total += mass;
|
|
1473
|
-
if (check.tags?.includes(
|
|
1488
|
+
if (check.tags?.includes(tag2)) skipped += mass;
|
|
1474
1489
|
}
|
|
1475
|
-
return total === 0 ? 0 :
|
|
1490
|
+
return total === 0 ? 0 : skipped / total;
|
|
1476
1491
|
}
|
|
1477
1492
|
|
|
1478
1493
|
// src/audits/access-crawl-control/no-nofollow.ts
|
|
@@ -40776,6 +40791,7 @@ function outcomeOf(check) {
|
|
|
40776
40791
|
if (tags.includes(TAG_SCAN_ERROR)) return "error";
|
|
40777
40792
|
if (tags.includes(TAG_SKIPPED_PAGE_TYPE)) return "skipped";
|
|
40778
40793
|
if (tags.includes(TAG_SKIPPED_NO_EVIDENCE)) return "gated";
|
|
40794
|
+
if (tags.includes(TAG_SKIPPED_SCAN_BUDGET)) return "budget";
|
|
40779
40795
|
return "ran";
|
|
40780
40796
|
}
|
|
40781
40797
|
function traceFromCheck(check, durationMs) {
|
|
@@ -40928,9 +40944,28 @@ function planAudits(ctx, config, options = {}) {
|
|
|
40928
40944
|
}
|
|
40929
40945
|
return { runnable, skipped };
|
|
40930
40946
|
}
|
|
40931
|
-
|
|
40947
|
+
function formatBudget(ms) {
|
|
40948
|
+
return ms >= 1e3 ? `${Math.round(ms / 1e3)} s` : `${ms} ms`;
|
|
40949
|
+
}
|
|
40950
|
+
function budgetReason(signal) {
|
|
40951
|
+
const reason = signal.reason;
|
|
40952
|
+
if (reason instanceof Error && !(reason instanceof DOMException) && reason.message)
|
|
40953
|
+
return reason.message;
|
|
40954
|
+
return "The scan budget ran out.";
|
|
40955
|
+
}
|
|
40956
|
+
async function runAudits(ctx, config, onEvent, plan, onTrace, budget) {
|
|
40932
40957
|
const { runnable, skipped } = plan ?? planAudits(ctx, config);
|
|
40933
40958
|
const allChecks = [...skipped];
|
|
40959
|
+
const budgetStub = (reg2) => {
|
|
40960
|
+
const label3 = `${reg2.meta.id} ${reg2.meta.title}`;
|
|
40961
|
+
const stub = stubCheck(
|
|
40962
|
+
reg2.meta,
|
|
40963
|
+
TAG_SKIPPED_SCAN_BUDGET,
|
|
40964
|
+
`Not assessed: ${budgetReason(budget)} This audit had not started.`
|
|
40965
|
+
);
|
|
40966
|
+
if (typeof onEvent === "function") onEvent({ type: "unit:done", label: label3 });
|
|
40967
|
+
return stub;
|
|
40968
|
+
};
|
|
40934
40969
|
const tracing = Boolean(onTrace) || logger.level === "debug";
|
|
40935
40970
|
const trace = (check, durationMs) => {
|
|
40936
40971
|
if (!tracing) return;
|
|
@@ -40941,9 +40976,22 @@ async function runAudits(ctx, config, onEvent, plan, onTrace) {
|
|
|
40941
40976
|
for (const stub of skipped) trace(stub, 0);
|
|
40942
40977
|
const batchSize = 20;
|
|
40943
40978
|
for (let i = 0; i < runnable.length; i += batchSize) {
|
|
40979
|
+
if (budget?.aborted) {
|
|
40980
|
+
for (const { reg: reg2 } of runnable.slice(i)) {
|
|
40981
|
+
const stub = budgetStub(reg2);
|
|
40982
|
+
trace(stub, 0);
|
|
40983
|
+
allChecks.push(stub);
|
|
40984
|
+
}
|
|
40985
|
+
break;
|
|
40986
|
+
}
|
|
40944
40987
|
const batch = runnable.slice(i, i + batchSize);
|
|
40945
40988
|
const batchResults = await Promise.all(
|
|
40946
40989
|
batch.map(async ({ reg: reg2, scopedPages, scoreDisplayMode }) => {
|
|
40990
|
+
if (budget?.aborted) {
|
|
40991
|
+
const stub = budgetStub(reg2);
|
|
40992
|
+
trace(stub, 0);
|
|
40993
|
+
return stub;
|
|
40994
|
+
}
|
|
40947
40995
|
const label3 = `${reg2.meta.id} ${reg2.meta.title}`;
|
|
40948
40996
|
const startedAt = tracing ? performance.now() : 0;
|
|
40949
40997
|
const elapsed = () => tracing ? Math.round(performance.now() - startedAt) : 0;
|
|
@@ -40951,6 +40999,17 @@ async function runAudits(ctx, config, onEvent, plan, onTrace) {
|
|
|
40951
40999
|
const instance = reg2.create();
|
|
40952
41000
|
const scopedCtx = scopedPages && scopedPages !== ctx.pages ? { ...ctx, pages: scopedPages, cacheOwner: cacheOwner(ctx) } : ctx;
|
|
40953
41001
|
const result = await instance.audit(scopedCtx);
|
|
41002
|
+
if (budget?.aborted) {
|
|
41003
|
+
const stub = stubCheck(
|
|
41004
|
+
reg2.meta,
|
|
41005
|
+
TAG_SKIPPED_SCAN_BUDGET,
|
|
41006
|
+
`Not assessed: ${budgetReason(budget)} This audit was still running.`
|
|
41007
|
+
);
|
|
41008
|
+
if (typeof onEvent === "function")
|
|
41009
|
+
onEvent({ type: "unit:done", label: label3 });
|
|
41010
|
+
trace(stub, elapsed());
|
|
41011
|
+
return stub;
|
|
41012
|
+
}
|
|
40954
41013
|
const check = instance.toCheckResult(result, scoreDisplayMode);
|
|
40955
41014
|
if (typeof onEvent === "function")
|
|
40956
41015
|
onEvent({ type: "unit:done", label: label3 });
|
|
@@ -41280,8 +41339,22 @@ var A11Y_MAX_PAGES = Math.max(
|
|
|
41280
41339
|
);
|
|
41281
41340
|
var RATE_LIMIT_BACKOFF_MS = 5e3;
|
|
41282
41341
|
var MAX_RETRY_AFTER_MS = 3e4;
|
|
41283
|
-
|
|
41284
|
-
|
|
41342
|
+
function unsentResult(url, error) {
|
|
41343
|
+
return {
|
|
41344
|
+
url,
|
|
41345
|
+
finalUrl: url,
|
|
41346
|
+
status: 0,
|
|
41347
|
+
headers: {},
|
|
41348
|
+
body: "",
|
|
41349
|
+
ttfbMs: 0,
|
|
41350
|
+
totalMs: 0,
|
|
41351
|
+
contentType: "",
|
|
41352
|
+
contentLength: 0,
|
|
41353
|
+
error
|
|
41354
|
+
};
|
|
41355
|
+
}
|
|
41356
|
+
async function fetchPageWithRetry(fetcher, url, fetchSignal, cancel) {
|
|
41357
|
+
const first5 = await fetcher.fetch({ url, signal: fetchSignal });
|
|
41285
41358
|
if (first5.status !== 429) return first5;
|
|
41286
41359
|
const header = Number(first5.headers["retry-after"]);
|
|
41287
41360
|
const waitMs = Number.isFinite(header) && header > 0 ? Math.min(header * 1e3, MAX_RETRY_AFTER_MS) : RATE_LIMIT_BACKOFF_MS;
|
|
@@ -41289,14 +41362,46 @@ async function fetchPageWithRetry(fetcher, url, signal) {
|
|
|
41289
41362
|
{ url, waitMs },
|
|
41290
41363
|
`[orchestrator] Page answered 429; retrying once in ${waitMs}ms`
|
|
41291
41364
|
);
|
|
41292
|
-
|
|
41293
|
-
|
|
41294
|
-
|
|
41365
|
+
if (!fetchSignal?.aborted)
|
|
41366
|
+
await new Promise((resolve4) => {
|
|
41367
|
+
const timer = setTimeout(done, waitMs);
|
|
41368
|
+
function done() {
|
|
41369
|
+
clearTimeout(timer);
|
|
41370
|
+
fetchSignal?.removeEventListener("abort", done);
|
|
41371
|
+
resolve4();
|
|
41372
|
+
}
|
|
41373
|
+
fetchSignal?.addEventListener("abort", done, { once: true });
|
|
41374
|
+
});
|
|
41375
|
+
cancel?.throwIfAborted();
|
|
41376
|
+
if (fetchSignal?.aborted) return first5;
|
|
41377
|
+
return fetcher.fetch({ url, signal: fetchSignal });
|
|
41295
41378
|
}
|
|
41296
41379
|
async function runScan(url, options) {
|
|
41380
|
+
const limitMs = options?.timeoutMs ?? SCAN_TIMEOUT_MS;
|
|
41381
|
+
if (!Number.isFinite(limitMs) || limitMs < 0)
|
|
41382
|
+
throw new RangeError(
|
|
41383
|
+
`timeoutMs must be a non-negative number of milliseconds, got ${String(options?.timeoutMs)}`
|
|
41384
|
+
);
|
|
41385
|
+
const budget = new AbortController();
|
|
41386
|
+
const timer = limitMs > 0 ? setTimeout(() => {
|
|
41387
|
+
const message = `The scan budget of ${formatBudget(limitMs)} ran out.`;
|
|
41388
|
+
logger.warn(`[orchestrator] ${message} ${splitCredentials(url).url}`);
|
|
41389
|
+
budget.abort(new Error(message));
|
|
41390
|
+
}, limitMs) : void 0;
|
|
41391
|
+
try {
|
|
41392
|
+
return await scanWithinBudget(url, options, {
|
|
41393
|
+
signal: budget.signal,
|
|
41394
|
+
limitMs
|
|
41395
|
+
});
|
|
41396
|
+
} finally {
|
|
41397
|
+
if (timer !== void 0) clearTimeout(timer);
|
|
41398
|
+
}
|
|
41399
|
+
}
|
|
41400
|
+
async function scanWithinBudget(url, options, budget) {
|
|
41297
41401
|
const onEvent = options?.onEvent;
|
|
41298
41402
|
const pageOverrides = options?.pages;
|
|
41299
41403
|
const signal = options?.signal;
|
|
41404
|
+
const fetchSignal = signal ? AbortSignal.any([signal, budget.signal]) : budget.signal;
|
|
41300
41405
|
const tracker = new ProgressTracker((event) => onEvent?.(event));
|
|
41301
41406
|
const start = performance.now();
|
|
41302
41407
|
const fetcher = createFetcher({
|
|
@@ -41394,7 +41499,7 @@ async function runScan(url, options) {
|
|
|
41394
41499
|
tracker.unitDone(path);
|
|
41395
41500
|
return Promise.resolve(prefetchedRobots);
|
|
41396
41501
|
}
|
|
41397
|
-
return fetcher.fetch({ url: `${baseUrl}${path}`, signal }).then((result) => {
|
|
41502
|
+
return fetcher.fetch({ url: `${baseUrl}${path}`, signal: fetchSignal }).then((result) => {
|
|
41398
41503
|
tracker.unitDone(path);
|
|
41399
41504
|
return result;
|
|
41400
41505
|
});
|
|
@@ -41405,7 +41510,7 @@ async function runScan(url, options) {
|
|
|
41405
41510
|
rootFiles[path] = rootResults[i];
|
|
41406
41511
|
});
|
|
41407
41512
|
const isHomepageScan = url === `${baseUrl}/` || url === baseUrl;
|
|
41408
|
-
originHomepageResult = isHomepageScan ? void 0 : await fetchPageWithRetry(fetcher, `${baseUrl}/`, signal);
|
|
41513
|
+
originHomepageResult = isHomepageScan ? void 0 : await fetchPageWithRetry(fetcher, `${baseUrl}/`, fetchSignal, signal);
|
|
41409
41514
|
originReadAt = (/* @__PURE__ */ new Date()).toISOString();
|
|
41410
41515
|
originFresh = true;
|
|
41411
41516
|
tracker.phaseDone();
|
|
@@ -41414,7 +41519,12 @@ async function runScan(url, options) {
|
|
|
41414
41519
|
signal?.throwIfAborted();
|
|
41415
41520
|
logger.debug("[orchestrator] Phase 2: Fetching page");
|
|
41416
41521
|
tracker.phaseStart("fetch-pages", 1 + overrideUrls.length);
|
|
41417
|
-
const pageResult = await fetchPageWithRetry(
|
|
41522
|
+
const pageResult = await fetchPageWithRetry(
|
|
41523
|
+
fetcher,
|
|
41524
|
+
url,
|
|
41525
|
+
fetchSignal,
|
|
41526
|
+
signal
|
|
41527
|
+
);
|
|
41418
41528
|
tracker.unitDone(displayUrl);
|
|
41419
41529
|
if (!originHomepageResult && (url === `${baseUrl}/` || url === baseUrl)) {
|
|
41420
41530
|
originHomepageResult = pageResult;
|
|
@@ -41430,7 +41540,7 @@ async function runScan(url, options) {
|
|
|
41430
41540
|
}
|
|
41431
41541
|
const extraResults = await Promise.all(
|
|
41432
41542
|
overrideUrls.map(
|
|
41433
|
-
(pageUrl) => fetcher.fetch({ url: pageUrl, signal }).then((result) => {
|
|
41543
|
+
(pageUrl) => fetcher.fetch({ url: pageUrl, signal: fetchSignal }).then((result) => {
|
|
41434
41544
|
tracker.unitDone(pageUrl);
|
|
41435
41545
|
return result;
|
|
41436
41546
|
})
|
|
@@ -41508,7 +41618,11 @@ async function runScan(url, options) {
|
|
|
41508
41618
|
pages,
|
|
41509
41619
|
domain,
|
|
41510
41620
|
baseUrl,
|
|
41511
|
-
|
|
41621
|
+
// Once the budget is gone no request leaves: the audit reads an error
|
|
41622
|
+
// result at once, the same shape a refused connection gives it.
|
|
41623
|
+
fetch: (options2) => budget.signal.aborted ? Promise.resolve(
|
|
41624
|
+
unsentResult(options2.url, budgetReason(budget.signal))
|
|
41625
|
+
) : fetcher.fetch({ ...options2, signal: fetchSignal }),
|
|
41512
41626
|
wafProtection: wafProtection ?? void 0,
|
|
41513
41627
|
evidence,
|
|
41514
41628
|
originEvidence: {
|
|
@@ -41539,9 +41653,12 @@ async function runScan(url, options) {
|
|
|
41539
41653
|
else tracker.unitFail(event.label, event.error);
|
|
41540
41654
|
},
|
|
41541
41655
|
auditPlan,
|
|
41542
|
-
options?.onAuditTrace
|
|
41656
|
+
options?.onAuditTrace,
|
|
41657
|
+
budget.signal
|
|
41543
41658
|
);
|
|
41544
41659
|
tracker.phaseDone();
|
|
41660
|
+
signal?.throwIfAborted();
|
|
41661
|
+
const budgetExhausted = budget.signal.aborted;
|
|
41545
41662
|
logger.debug("[orchestrator] Phase 3 complete: Audits finished");
|
|
41546
41663
|
tracker.phaseStart("report", 1);
|
|
41547
41664
|
logger.debug("[orchestrator] Phase 4: Building final report");
|
|
@@ -41567,7 +41684,11 @@ async function runScan(url, options) {
|
|
|
41567
41684
|
);
|
|
41568
41685
|
const gatedShare = gatedMassShare(allChecks);
|
|
41569
41686
|
const escalated = gatedShare > GATED_MASS_UNSCORED_THRESHOLD;
|
|
41570
|
-
const
|
|
41687
|
+
const budgetShare = skippedMassShare(allChecks, TAG_SKIPPED_SCAN_BUDGET);
|
|
41688
|
+
const unassessedShare = gatedShare + budgetShare;
|
|
41689
|
+
const cut = !escalated && budgetShare > 0 && unassessedShare > GATED_MASS_UNSCORED_THRESHOLD;
|
|
41690
|
+
const budgetSentence = budgetExhausted ? budgetReason(budget.signal) : "";
|
|
41691
|
+
const unscoredReason = !evidence.judgeable ? budgetExhausted ? `${budgetSentence} ${unjudgeableReason(evidence)}` : unjudgeableReason(evidence) : escalated ? `The scan could not feed ${Math.round(gatedShare * 100)}% of the registry's evidence mass, so what remains is not a reading of this site.` : cut ? `${budgetSentence} ${Math.round(unassessedShare * 100)}% of the registry's evidence mass was never assessed, so what remains is not a reading of this site.` : void 0;
|
|
41571
41692
|
const scored = unscoredReason === void 0;
|
|
41572
41693
|
const allScoredAudits = Object.values(config.audits).flat().filter((a) => a.meta.tier === "scored");
|
|
41573
41694
|
let registryMass = 0;
|
|
@@ -41602,6 +41723,8 @@ async function runScan(url, options) {
|
|
|
41602
41723
|
unscoredReasons["skipped-no-evidence"] = (unscoredReasons["skipped-no-evidence"] ?? 0) + 1;
|
|
41603
41724
|
} else if (check.tags?.includes(TAG_SKIPPED_PAGE_TYPE)) {
|
|
41604
41725
|
unscoredReasons["skipped-page-type"] = (unscoredReasons["skipped-page-type"] ?? 0) + 1;
|
|
41726
|
+
} else if (check.tags?.includes(TAG_SKIPPED_SCAN_BUDGET)) {
|
|
41727
|
+
unscoredReasons["skipped-scan-budget"] = (unscoredReasons["skipped-scan-budget"] ?? 0) + 1;
|
|
41605
41728
|
} else {
|
|
41606
41729
|
unscoredReasons["not-applicable"] = (unscoredReasons["not-applicable"] ?? 0) + 1;
|
|
41607
41730
|
}
|
|
@@ -41639,6 +41762,17 @@ async function runScan(url, options) {
|
|
|
41639
41762
|
informativeCount,
|
|
41640
41763
|
gatedCount,
|
|
41641
41764
|
reasons: unscoredReasons
|
|
41765
|
+
},
|
|
41766
|
+
// Counted over every check, advisory ones included: the reasons map
|
|
41767
|
+
// files an informative stub under `informative`, but the budget cut it
|
|
41768
|
+
// all the same.
|
|
41769
|
+
budget: {
|
|
41770
|
+
limitMs: budget.limitMs,
|
|
41771
|
+
elapsedMs: durationMs,
|
|
41772
|
+
exhausted: budgetExhausted,
|
|
41773
|
+
skippedCount: allChecks.filter(
|
|
41774
|
+
(c) => c.tags?.includes(TAG_SKIPPED_SCAN_BUDGET)
|
|
41775
|
+
).length
|
|
41642
41776
|
}
|
|
41643
41777
|
};
|
|
41644
41778
|
const report = {
|
|
@@ -41875,9 +42009,11 @@ function loadConfigFile(customPath) {
|
|
|
41875
42009
|
TAG_SCAN_ERROR,
|
|
41876
42010
|
TAG_SKIPPED_NO_EVIDENCE,
|
|
41877
42011
|
TAG_SKIPPED_PAGE_TYPE,
|
|
42012
|
+
TAG_SKIPPED_SCAN_BUDGET,
|
|
41878
42013
|
allEvidenceMet,
|
|
41879
42014
|
allJsonLdNodes,
|
|
41880
42015
|
boundedDispatcher,
|
|
42016
|
+
budgetReason,
|
|
41881
42017
|
buildCategoryResult,
|
|
41882
42018
|
buildScanEvidence,
|
|
41883
42019
|
calculateCategoryScore,
|
|
@@ -41909,6 +42045,7 @@ function loadConfigFile(customPath) {
|
|
|
41909
42045
|
extractStylesheetUrls,
|
|
41910
42046
|
filterConfig,
|
|
41911
42047
|
flattenJsonLd,
|
|
42048
|
+
formatBudget,
|
|
41912
42049
|
formatTrace,
|
|
41913
42050
|
getMainContentText,
|
|
41914
42051
|
getPreset,
|
|
@@ -41946,6 +42083,7 @@ function loadConfigFile(customPath) {
|
|
|
41946
42083
|
runScan,
|
|
41947
42084
|
sampleEntries,
|
|
41948
42085
|
shouldBypassOriginCache,
|
|
42086
|
+
skippedMassShare,
|
|
41949
42087
|
stripBom,
|
|
41950
42088
|
topLevelJsonLd,
|
|
41951
42089
|
traceFromCheck,
|