@brandlab-digital/conformance 3.14.0 → 3.15.1
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/README.md +60 -3
- package/dist/current-release.js +5 -5
- package/dist/current-release.js.map +1 -1
- package/dist/engineering.d.ts.map +1 -1
- package/dist/engineering.js +18 -2
- package/dist/engineering.js.map +1 -1
- package/dist/estate-snapshot.d.ts +54 -0
- package/dist/estate-snapshot.d.ts.map +1 -0
- package/dist/estate-snapshot.js +164 -0
- package/dist/estate-snapshot.js.map +1 -0
- package/dist/estate.d.ts +10 -0
- package/dist/estate.d.ts.map +1 -1
- package/dist/estate.js +36 -16
- package/dist/estate.js.map +1 -1
- package/dist/media-snapshot.d.ts +53 -0
- package/dist/media-snapshot.d.ts.map +1 -0
- package/dist/media-snapshot.js +66 -0
- package/dist/media-snapshot.js.map +1 -0
- package/dist/site-system/checks.d.ts +2 -2
- package/dist/site-system/checks.js +2 -2
- package/dist/site-system/checks.js.map +1 -1
- package/dist/site-system/config.d.ts +13 -0
- package/dist/site-system/config.d.ts.map +1 -1
- package/dist/site-system/config.js +30 -1
- package/dist/site-system/config.js.map +1 -1
- package/dist/site-system/index.d.ts +1 -1
- package/dist/site-system/index.d.ts.map +1 -1
- package/dist/site-system/index.js +1 -1
- package/dist/site-system/index.js.map +1 -1
- package/dist/site-system/journeys/conversion.d.ts.map +1 -1
- package/dist/site-system/journeys/conversion.js +15 -2
- package/dist/site-system/journeys/conversion.js.map +1 -1
- package/dist/site-system/journeys/menu.d.ts.map +1 -1
- package/dist/site-system/journeys/menu.js +24 -1
- package/dist/site-system/journeys/menu.js.map +1 -1
- package/dist/site-system/journeys/page-helpers.d.ts.map +1 -1
- package/dist/site-system/journeys/page-helpers.js +1 -1
- package/dist/site-system/journeys/page-helpers.js.map +1 -1
- package/dist/site-system/journeys/plan.d.ts +13 -3
- package/dist/site-system/journeys/plan.d.ts.map +1 -1
- package/dist/site-system/journeys/plan.js +12 -2
- package/dist/site-system/journeys/plan.js.map +1 -1
- package/dist/site-system/journeys/shell.d.ts +1 -1
- package/dist/site-system/journeys/shell.js +2 -2
- package/dist/site-system/journeys/shell.js.map +1 -1
- package/dist/site-system/report.d.ts.map +1 -1
- package/dist/site-system/report.js +24 -4
- package/dist/site-system/report.js.map +1 -1
- package/dist/site-system/rules/form/c7-thank-you.d.ts +7 -1
- package/dist/site-system/rules/form/c7-thank-you.d.ts.map +1 -1
- package/dist/site-system/rules/form/c7-thank-you.js +26 -3
- package/dist/site-system/rules/form/c7-thank-you.js.map +1 -1
- package/dist/site-system/rules/form/index.d.ts.map +1 -1
- package/dist/site-system/rules/form/index.js +11 -1
- package/dist/site-system/rules/form/index.js.map +1 -1
- package/dist/site-system/rules/full/common.d.ts +2 -0
- package/dist/site-system/rules/full/common.d.ts.map +1 -1
- package/dist/site-system/rules/full/common.js.map +1 -1
- package/dist/site-system/rules/full/estate.d.ts +10 -2
- package/dist/site-system/rules/full/estate.d.ts.map +1 -1
- package/dist/site-system/rules/full/estate.js +35 -5
- package/dist/site-system/rules/full/estate.js.map +1 -1
- package/dist/site-system/rules/full/geography.d.ts +7 -0
- package/dist/site-system/rules/full/geography.d.ts.map +1 -1
- package/dist/site-system/rules/full/geography.js +9 -0
- package/dist/site-system/rules/full/geography.js.map +1 -1
- package/dist/site-system/rules/full/index.d.ts +2 -1
- package/dist/site-system/rules/full/index.d.ts.map +1 -1
- package/dist/site-system/rules/full/index.js +5 -1
- package/dist/site-system/rules/full/index.js.map +1 -1
- package/dist/site-system/rules/full/l10-location-copy.d.ts +1 -1
- package/dist/site-system/rules/full/l10-location-copy.d.ts.map +1 -1
- package/dist/site-system/rules/full/l10-location-copy.js +5 -2
- package/dist/site-system/rules/full/l10-location-copy.js.map +1 -1
- package/dist/site-system/rules/full/l3-neighbours.d.ts +3 -2
- package/dist/site-system/rules/full/l3-neighbours.d.ts.map +1 -1
- package/dist/site-system/rules/full/l3-neighbours.js +4 -1
- package/dist/site-system/rules/full/l3-neighbours.js.map +1 -1
- package/dist/site-system/rules/full/l4-local-copy.d.ts +2 -1
- package/dist/site-system/rules/full/l4-local-copy.d.ts.map +1 -1
- package/dist/site-system/rules/full/l4-local-copy.js +8 -3
- package/dist/site-system/rules/full/l4-local-copy.js.map +1 -1
- package/dist/site-system/rules/full/l9-data-contract.js +2 -2
- package/dist/site-system/rules/full/l9-data-contract.js.map +1 -1
- package/dist/site-system/rules/full/links.d.ts +3 -1
- package/dist/site-system/rules/full/links.d.ts.map +1 -1
- package/dist/site-system/rules/full/links.js +15 -5
- package/dist/site-system/rules/full/links.js.map +1 -1
- package/dist/site-system/rules/full/route-kinds.d.ts +15 -0
- package/dist/site-system/rules/full/route-kinds.d.ts.map +1 -0
- package/dist/site-system/rules/full/route-kinds.js +52 -0
- package/dist/site-system/rules/full/route-kinds.js.map +1 -0
- package/dist/site-system/rules/full/strategy.d.ts +2 -0
- package/dist/site-system/rules/full/strategy.d.ts.map +1 -1
- package/dist/site-system/rules/full/strategy.js +86 -14
- package/dist/site-system/rules/full/strategy.js.map +1 -1
- package/dist/site-system/rules/sections/k2-skin-coverage.d.ts +2 -2
- package/dist/site-system/rules/sections/k2-skin-coverage.d.ts.map +1 -1
- package/dist/site-system/rules/sections/k2-skin-coverage.js +9 -2
- package/dist/site-system/rules/sections/k2-skin-coverage.js.map +1 -1
- package/dist/site-system/rules/sections/t6-media-entries.d.ts.map +1 -1
- package/dist/site-system/rules/sections/t6-media-entries.js +69 -5
- package/dist/site-system/rules/sections/t6-media-entries.js.map +1 -1
- package/dist/site-system-e2e.d.ts +1 -1
- package/dist/site-system-e2e.d.ts.map +1 -1
- package/dist/site-system-e2e.js +17 -4
- package/dist/site-system-e2e.js.map +1 -1
- package/package.json +10 -2
|
@@ -71,7 +71,7 @@ export function buildSiteSystemReadyReport(input) {
|
|
|
71
71
|
};
|
|
72
72
|
const checks = SITE_SYSTEM_CHECKS.map((check) => {
|
|
73
73
|
const blocks = site ? siteSystemCheckBlocks(check, site) : false;
|
|
74
|
-
const merged = launchOnlyNotRun(check, blocks, input.launch === true, mergeFindings(findings.filter((finding) => finding.checkId === check.id), notRunMessage(check)));
|
|
74
|
+
const merged = launchOnlyNotRun(check, blocks, input.launch === true, mergeFindings(findings.filter((finding) => finding.checkId === check.id), notRunMessage(check, input.inputs, settings)));
|
|
75
75
|
const { status, messages } = applyException(check.id, blocks, merged.status, merged.messages);
|
|
76
76
|
return {
|
|
77
77
|
id: check.id,
|
|
@@ -179,10 +179,30 @@ function verifyStatus(family, findings) {
|
|
|
179
179
|
return { status: "not-applicable", messages: ["No brandlab-verify rule in this family applies to this project."], warnings };
|
|
180
180
|
return { status: "pass", messages: [`brandlab-verify found nothing to fix in ${family.title.toLowerCase()}.`], warnings };
|
|
181
181
|
}
|
|
182
|
-
|
|
182
|
+
/** What a site's site-system spec must pass for a journey to register, beyond its tier. */
|
|
183
|
+
const JOURNEY_PAGES = {
|
|
184
|
+
C1: "pages: { money: [...] }",
|
|
185
|
+
W9: "pages: { families: [...] }",
|
|
186
|
+
};
|
|
187
|
+
const JOURNEY_PAGES_WHY = {
|
|
188
|
+
C1: "pages.money names the service pages with the enquiry form",
|
|
189
|
+
W9: "pages.families names one built page per dynamic route family",
|
|
190
|
+
};
|
|
191
|
+
function notRunMessage(check, inputs, settings) {
|
|
183
192
|
switch (check.kind) {
|
|
184
|
-
case "journey":
|
|
185
|
-
|
|
193
|
+
case "journey": {
|
|
194
|
+
if (!inputs?.journeyReport || inputs.journeyTests === 0) {
|
|
195
|
+
return "No journey result: run the site-system journeys (npm run test:e2e) before brandlab-ready.";
|
|
196
|
+
}
|
|
197
|
+
// Other journeys ran, so this one did not register: the spec's tier or pages, or a conformance release before it.
|
|
198
|
+
const tier = settings?.tier ?? check.tier;
|
|
199
|
+
const pages = JOURNEY_PAGES[check.id];
|
|
200
|
+
const why = JOURNEY_PAGES_WHY[check.id];
|
|
201
|
+
return `No journey result: ${inputs.journeyReport} has ${plural(inputs.journeyTests, "site-system test run")} but none for ${check.id}. ` +
|
|
202
|
+
`The journeys register by tier and release: tests/e2e/site-system.spec.ts calls defineBrandlabSiteSystemTests({ tier: '${tier}'${pages ? `, ${pages}` : ""} }) ` +
|
|
203
|
+
`(${check.id} is a ${check.tier}-tier journey from ${check.from}${why ? `, and ${why}` : ""}), and @brandlab-digital/conformance must be ${check.from} or later; ` +
|
|
204
|
+
"then run npm run test:e2e with the JSON reporter before brandlab-ready.";
|
|
205
|
+
}
|
|
186
206
|
case "rendered":
|
|
187
207
|
return "No result: no rule module reported this check for the sampled pages.";
|
|
188
208
|
case "static":
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"report.js","sourceRoot":"","sources":["../../src/site-system/report.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * The ready report: every Site System check with its tier, whether it blocks for this site, its status and\n * messages; the existing brandlab-verify search, contact and analytics families (shell tier); the launch-day and\n * human steps; and the exceptions that apply. A blocking check that failed or did not run fails the gate.\n */\nimport type { BrandlabConformanceResult } from \"../project.js\";\nimport {\n SITE_SYSTEM_CHECKS,\n SITE_SYSTEM_TIERS,\n siteSystemCheckBlocks,\n type SiteSystemCheck,\n type SiteSystemCheckKind,\n type SiteSystemCheckScope,\n type SiteSystemFinding,\n type SiteSystemTier,\n} from \"./checks.js\";\nimport type { SiteSystemException, SiteSystemSettings } from \"./config.js\";\nimport { latestSiteSystemRecords, SITE_SYSTEM_RECORD_PATHS, type SiteSystemRecord } from \"./records.js\";\nimport {\n SITE_SYSTEM_HUMAN_STEPS,\n SITE_SYSTEM_LAUNCH_STEPS,\n SITE_SYSTEM_RECORDED_CHECK_IDS,\n type SiteSystemRecordFile,\n type SiteSystemStep,\n} from \"./steps.js\";\n\nexport const SITE_SYSTEM_READY_SCHEMA = \"brandlab.ready.v1\";\n\nexport const SITE_SYSTEM_READY_REPORT_PATHS = {\n markdown: \"docs/ready/ready-report.md\",\n json: \"docs/ready/ready-report.json\",\n} as const;\n\nexport type SiteSystemReadyStatus = \"pass\" | \"fail\" | \"not-run\" | \"excepted\" | \"not-applicable\";\n\nexport interface SiteSystemReadyCheck {\n readonly id: string;\n readonly summary: string;\n readonly tier: SiteSystemCheckScope;\n readonly from: string;\n /** A registry check kind, or `verify` for an existing brandlab-verify family. */\n readonly kind: SiteSystemCheckKind | \"verify\";\n readonly blocks: boolean;\n /** Why the check reports without blocking. */\n readonly reportsOnly?: string;\n readonly status: SiteSystemReadyStatus;\n readonly messages: readonly string[];\n /** Warnings never block; a passing check with warnings shows as \"pass (warning)\". */\n readonly warnings: readonly string[];\n}\n\nexport interface SiteSystemReadyStep {\n readonly id: string;\n readonly summary: string;\n readonly file: SiteSystemRecordFile;\n readonly recorded: boolean;\n readonly recordedAt?: string;\n readonly evidence?: string;\n readonly note?: string;\n}\n\nexport interface SiteSystemReadyException extends SiteSystemException {\n readonly expired: boolean;\n /** True when it turned a failing or unrun blocking check into `excepted`. */\n readonly applied: boolean;\n readonly state: \"applied\" | \"expired\" | \"not-needed\";\n /** Why an exception is not needed: the check passes, does not apply or does not block. */\n readonly reason?: string;\n}\n\nexport interface SiteSystemReadyVerdict {\n /** The declared tier's blocking checks all pass or are excepted. */\n readonly ready: boolean;\n /** Ready, and every launch-day and human step recorded. */\n readonly launchReady: boolean;\n readonly exitCode: 0 | 1;\n readonly summary: string;\n readonly failed: readonly string[];\n readonly notRun: readonly string[];\n readonly excepted: readonly string[];\n /** Reasons the run is not ready besides the checks (an unreadable config, a missing home or contact page). */\n readonly blockers: readonly string[];\n readonly stepsToRecord: readonly string[];\n}\n\nexport interface SiteSystemReadyInputs {\n /** The Playwright JSON report read, relative to the project, or null when there was none. */\n readonly journeyReport: string | null;\n readonly journeyTests: number;\n readonly pageSource: \"base-url\" | \"build\" | \"none\";\n readonly pages: readonly string[];\n readonly runners: number;\n readonly findingFiles: readonly string[];\n}\n\nexport interface SiteSystemReadyReport {\n readonly schemaVersion: typeof SITE_SYSTEM_READY_SCHEMA;\n readonly generatedAt: string;\n readonly projectId: string | null;\n readonly release: string | null;\n readonly tier: SiteSystemTier | null;\n readonly newBuild: boolean;\n /** Whether the run required every step to be recorded (`--launch`). */\n readonly launch: boolean;\n readonly verdict: SiteSystemReadyVerdict;\n readonly checks: readonly SiteSystemReadyCheck[];\n readonly steps: readonly SiteSystemReadyStep[];\n readonly exceptions: readonly SiteSystemReadyException[];\n readonly inputs: SiteSystemReadyInputs;\n readonly problems: readonly string[];\n}\n\n/** The brandlab-verify result the shell tier carries: its search, contact and analytics families. */\nexport type SiteSystemVerifyResult = Pick<BrandlabConformanceResult, \"verification\" | \"operationalFindings\">;\n\nexport interface BuildSiteSystemReadyReportInput {\n readonly projectId: string | null;\n readonly siteSystem: SiteSystemSettings | null;\n readonly release: string | null;\n /** Journey, rule-module and supplied findings. */\n readonly findings: readonly SiteSystemFinding[];\n /** Null when brandlab-verify could not run: its families then did not run. */\n readonly verify: SiteSystemVerifyResult | null;\n readonly launchRecords: readonly SiteSystemRecord[];\n readonly humanRecords: readonly SiteSystemRecord[];\n readonly exceptions: readonly SiteSystemException[];\n readonly inputs: SiteSystemReadyInputs;\n readonly problems: readonly string[];\n readonly now: Date;\n /** Require every launch-day and human step (`brandlab-ready --launch`). */\n readonly launch?: boolean;\n /** Reasons the run is not ready whatever the checks say, as short clauses (\"the home page could not be read\"). */\n readonly blockers?: readonly string[];\n}\n\nconst VERIFY_FAMILIES = [\"search-output\", \"contact-delivery\", \"analytics\"] as const;\nconst VERIFY_SCOPE = { tier: \"shell\", from: \"3.8.0\" } as const;\n\nexport function buildSiteSystemReadyReport(input: BuildSiteSystemReadyReportInput): SiteSystemReadyReport {\n const problems = [...input.problems];\n const settings = input.siteSystem;\n const site = settings && input.release\n ? { tier: settings.tier, release: input.release, newBuild: settings.newBuild }\n : null;\n if (settings && !input.release) problems.push(\"The installed Brandlab release is unknown, so no check could block.\");\n\n const launchLatest = latestSiteSystemRecords(input.launchRecords);\n const humanLatest = latestSiteSystemRecords(input.humanRecords);\n const launchIds = new Set<string>([...SITE_SYSTEM_LAUNCH_STEPS.map((step) => step.id), ...SITE_SYSTEM_RECORDED_CHECK_IDS]);\n const humanIds = new Set<string>(SITE_SYSTEM_HUMAN_STEPS.map((step) => step.id));\n for (const id of launchLatest.keys()) {\n if (!launchIds.has(id)) problems.push(`${SITE_SYSTEM_RECORD_PATHS.launch} records ${id}, which is not a launch-day step or recorded check, so it was ignored.`);\n }\n for (const id of humanLatest.keys()) {\n if (!humanIds.has(id)) problems.push(`${SITE_SYSTEM_RECORD_PATHS.human} records ${id}, which is not a human step, so it was ignored.`);\n }\n\n const findings: SiteSystemFinding[] = [...input.findings];\n for (const id of SITE_SYSTEM_RECORDED_CHECK_IDS) {\n const record = launchLatest.get(id);\n if (record) findings.push({ checkId: id as SiteSystemFinding[\"checkId\"], status: \"pass\", message: `Recorded ${recordLine(record)}` });\n }\n\n const exceptionsByRule = new Map<string, SiteSystemException>();\n for (const exception of input.exceptions) {\n if (!exceptionsByRule.has(exception.ruleId)) exceptionsByRule.set(exception.ruleId, exception);\n }\n const knownIds = new Set<string>([...SITE_SYSTEM_CHECKS.map((check) => check.id), ...VERIFY_FAMILIES.map((id) => `verify:${id}`)]);\n for (const ruleId of exceptionsByRule.keys()) {\n if (!knownIds.has(ruleId)) problems.push(`The exception for ${ruleId} names no ready-gate check, so the gate ignored it.`);\n }\n const usedExceptions: SiteSystemReadyException[] = [];\n const applyException = (id: string, blocks: boolean, status: SiteSystemReadyStatus, messages: string[]) => {\n const exception = exceptionsByRule.get(id);\n if (!exception) return { status, messages };\n const expired = isExceptionExpired(exception.expiresAt, input.now);\n const unresolved = status === \"fail\" || status === \"not-run\";\n const applied = blocks && unresolved && !expired;\n const reason = !blocks ? \"the check does not block\" : status === \"not-applicable\" ? \"the check does not apply\" : \"the check passes\";\n usedExceptions.push({\n ...exception,\n expired,\n applied,\n state: expired ? \"expired\" : applied ? \"applied\" : \"not-needed\",\n ...(expired || applied ? {} : { reason }),\n });\n if (!unresolved) return { status, messages };\n if (expired) return { status, messages: [`The exception expired on ${exception.expiresAt}, so it no longer counts.`, ...messages] };\n if (!applied) return { status, messages };\n const until = exception.expiresAt ? ` until ${exception.expiresAt}` : \"\";\n return { status: \"excepted\" as const, messages: [`Excepted by Romie${until}: ${exception.rationale}`, ...messages] };\n };\n\n const checks: SiteSystemReadyCheck[] = SITE_SYSTEM_CHECKS.map((check: SiteSystemCheck) => {\n const blocks = site ? siteSystemCheckBlocks(check, site) : false;\n const merged = launchOnlyNotRun(\n check,\n blocks,\n input.launch === true,\n mergeFindings(findings.filter((finding) => finding.checkId === check.id), notRunMessage(check)),\n );\n const { status, messages } = applyException(check.id, blocks, merged.status, merged.messages);\n return {\n id: check.id,\n summary: check.summary,\n tier: check.tier,\n from: check.from,\n kind: check.kind,\n blocks,\n ...(blocks ? {} : { reportsOnly: reportsOnlyReason(check, settings) }),\n status,\n messages,\n warnings: merged.warnings,\n };\n });\n\n for (const familyId of VERIFY_FAMILIES) {\n const id = `verify:${familyId}`;\n const family = input.verify?.verification.families.find((candidate) => candidate.id === familyId);\n const blocks = site ? siteSystemCheckBlocks({ id, ...VERIFY_SCOPE }, site) : false;\n const merged = verifyStatus(family, input.verify?.operationalFindings ?? []);\n const { status, messages } = applyException(id, blocks, merged.status, merged.messages);\n checks.push({\n id,\n summary: family ? `${family.title} (brandlab-verify): ${family.purpose}` : `The brandlab-verify ${familyId} checks.`,\n tier: VERIFY_SCOPE.tier,\n from: VERIFY_SCOPE.from,\n kind: \"verify\",\n blocks,\n ...(blocks ? {} : { reportsOnly: reportsOnlyReason(VERIFY_SCOPE, settings) }),\n status,\n messages,\n warnings: merged.warnings,\n });\n }\n\n const steps: SiteSystemReadyStep[] = [\n ...SITE_SYSTEM_LAUNCH_STEPS.map((step) => readyStep(step, \"launch\", launchLatest.get(step.id))),\n ...SITE_SYSTEM_HUMAN_STEPS.map((step) => readyStep(step, \"human\", humanLatest.get(step.id))),\n ];\n\n const verdict = readyVerdict({\n settings,\n release: input.release,\n checks,\n steps,\n launch: input.launch === true,\n blockers: input.blockers ?? [],\n });\n return {\n schemaVersion: SITE_SYSTEM_READY_SCHEMA,\n generatedAt: input.now.toISOString(),\n projectId: input.projectId,\n release: input.release,\n tier: settings?.tier ?? null,\n newBuild: settings?.newBuild ?? false,\n launch: input.launch === true,\n verdict,\n checks,\n steps,\n exceptions: usedExceptions,\n inputs: input.inputs,\n problems,\n };\n}\n\n/**\n * A check whose not-run blocks only at launch (H13): under `--launch` a blocking not-run is a failure; otherwise it\n * stays not run with a note, and the verdict does not count it.\n */\nfunction launchOnlyNotRun(\n check: SiteSystemCheck,\n blocks: boolean,\n launch: boolean,\n merged: { status: SiteSystemReadyStatus; messages: string[]; warnings: string[] },\n): { status: SiteSystemReadyStatus; messages: string[]; warnings: string[] } {\n if (check.notRunBlocks !== \"launch\" || merged.status !== \"not-run\" || !blocks) return merged;\n if (launch) return { ...merged, status: \"fail\", messages: merged.messages.map((message) => `Launch needs this check to run. ${message}`) };\n return { ...merged, messages: [...merged.messages, \"It blocks only at launch (brandlab-ready --launch).\"] };\n}\n\n/**\n * Any fail fails the check; otherwise a rule's own not-run result (naming what it needed) leaves it not run; otherwise\n * any pass passes it; only not-applicable results make it not applicable. A warning is a pass that carries its message\n * as a warning, whatever status it names.\n */\nfunction mergeFindings(\n findings: readonly SiteSystemFinding[],\n notRun: string,\n): { status: SiteSystemReadyStatus; messages: string[]; warnings: string[] } {\n const warnings = [...new Set(findings.filter((finding) => finding.severity === \"warning\").map((finding) => finding.message))];\n const results = findings.filter((finding) => finding.severity !== \"warning\");\n if (warnings.length > 0 && !results.some((finding) => finding.status !== \"not-applicable\")) {\n return { status: \"pass\", messages: [], warnings };\n }\n for (const status of [\"fail\", \"not-run\", \"pass\", \"not-applicable\"] as const) {\n const scoped = results.filter((finding) => finding.status === status);\n if (scoped.length > 0) return { status, messages: [...new Set(scoped.map((finding) => finding.message))], warnings };\n }\n return { status: \"not-run\", messages: [notRun], warnings };\n}\n\nfunction verifyStatus(\n family: SiteSystemVerifyResult[\"verification\"][\"families\"][number] | undefined,\n findings: SiteSystemVerifyResult[\"operationalFindings\"],\n): { status: SiteSystemReadyStatus; messages: string[]; warnings: string[] } {\n if (!family) return { status: \"not-run\", messages: [\"brandlab-verify did not run, so these checks have no result.\"], warnings: [] };\n const scoped = findings\n .filter((finding) => finding.familyId === family.id)\n .map((finding) => {\n const location = finding.path ? ` (${finding.path}${finding.line ? `:${finding.line}` : \"\"})` : \"\";\n return { severity: finding.severity, message: `${finding.ruleId}${location}: ${finding.actual}` };\n });\n const warnings = scoped.filter((finding) => finding.severity === \"warning\").map((finding) => finding.message);\n if (family.status === \"blocked\") {\n return { status: \"fail\", messages: scoped.filter((finding) => finding.severity === \"blocker\").map((finding) => finding.message), warnings };\n }\n if (family.status === \"not_run\") return { status: \"not-applicable\", messages: [\"No brandlab-verify rule in this family applies to this project.\"], warnings };\n return { status: \"pass\", messages: [`brandlab-verify found nothing to fix in ${family.title.toLowerCase()}.`], warnings };\n}\n\nfunction notRunMessage(check: SiteSystemCheck): string {\n switch (check.kind) {\n case \"journey\":\n return \"No journey result: run the site-system journeys (npm run test:e2e) before brandlab-ready.\";\n case \"rendered\":\n return \"No result: no rule module reported this check for the sampled pages.\";\n case \"static\":\n return \"No result: no rule module reported this check.\";\n case \"record\":\n return `Not recorded: run brandlab-ready record ${check.id} --evidence <where the proof is>.`;\n }\n}\n\nfunction reportsOnlyReason(check: Pick<SiteSystemCheck, \"tier\" | \"from\">, settings: SiteSystemSettings | null): string {\n if (!settings) return \"no tier declared\";\n if (check.tier === \"new-build\") return settings.newBuild ? \"blocks new builds from 3.9.0\" : \"new builds and redesigns only\";\n return SITE_SYSTEM_TIERS.indexOf(check.tier) <= SITE_SYSTEM_TIERS.indexOf(settings.tier)\n ? `blocks from ${check.from}`\n : `${check.tier} tier`;\n}\n\nfunction readyStep(step: SiteSystemStep, file: SiteSystemRecordFile, record: SiteSystemRecord | undefined): SiteSystemReadyStep {\n return {\n id: step.id,\n summary: step.summary,\n file,\n recorded: Boolean(record),\n ...(record\n ? { recordedAt: record.recordedAt, evidence: record.evidence, ...(record.note ? { note: record.note } : {}) }\n : {}),\n };\n}\n\nfunction readyVerdict(input: {\n settings: SiteSystemSettings | null;\n release: string | null;\n checks: readonly SiteSystemReadyCheck[];\n steps: readonly SiteSystemReadyStep[];\n launch: boolean;\n blockers: readonly string[];\n}): SiteSystemReadyVerdict {\n const blocking = input.checks.filter((check) => check.blocks);\n const failed = blocking.filter((check) => check.status === \"fail\").map((check) => check.id);\n const launchOnly = new Set<string>((SITE_SYSTEM_CHECKS as readonly SiteSystemCheck[]).filter((check) => check.notRunBlocks === \"launch\").map((check) => check.id));\n // A launch-only check that did not run is reported, not counted: under --launch it is already a failure.\n const notRun = blocking.filter((check) => check.status === \"not-run\" && !launchOnly.has(check.id)).map((check) => check.id);\n const excepted = blocking.filter((check) => check.status === \"excepted\").map((check) => check.id);\n const stepsToRecord = input.steps.filter((step) => !step.recorded).map((step) => step.id);\n const adopted = input.settings !== null;\n const ready = adopted && input.release !== null && blocking.length > 0 && failed.length === 0 &&\n notRun.length === 0 && input.blockers.length === 0;\n const launchReady = ready && stepsToRecord.length === 0;\n const launchSteps = input.steps.filter((step) => !step.recorded && step.file === \"launch\").length;\n const humanSteps = input.steps.filter((step) => !step.recorded && step.file === \"human\").length;\n const stepCount = joinParts([\n launchSteps > 0 ? `${launchSteps} launch-day` : \"\",\n humanSteps > 0 ? `${humanSteps} human` : \"\",\n ]);\n const stepNoun = launchSteps + humanSteps === 1 ? \"step\" : \"steps\";\n const reasons = [\n failed.length > 0 ? `${plural(failed.length, \"blocking check\")} failed` : \"\",\n notRun.length > 0 ? (failed.length > 0 ? `${notRun.length} did not run` : `${plural(notRun.length, \"blocking check\")} did not run`) : \"\",\n ...input.blockers,\n ].filter(Boolean);\n\n let summary: string;\n let exitCode: 0 | 1 = 1;\n if (input.blockers.length > 0 || (adopted && reasons.length > 0)) {\n summary = `Not ready: ${joinParts(reasons)}`;\n } else if (!adopted) {\n summary = \"Not adopted: brandlab.config.ts declares no siteSystem tier, so no check blocks yet\";\n exitCode = 0;\n } else if (input.release === null) {\n summary = \"Not ready: the installed Brandlab release is unknown\";\n } else if (input.launch && stepsToRecord.length > 0) {\n summary = `Not ready: ${stepCount} ${stepNoun} not recorded`;\n } else if (blocking.length === 0) {\n summary = `No check blocks on release ${input.release}`;\n exitCode = 0;\n } else {\n summary = launchReady\n ? `Ready at ${input.settings!.tier} tier`\n : `Checks pass at ${input.settings!.tier} tier; before launch, record ${stepCount} ${stepNoun}`;\n if (excepted.length > 0) summary += ` (${plural(excepted.length, \"check\")} excepted)`;\n exitCode = 0;\n }\n return { ready, launchReady, exitCode, summary, failed, notRun, excepted, blockers: input.blockers, stepsToRecord };\n}\n\n/** Date-only expiries last to the end of that day in Sydney; timestamps expire at that instant. */\nexport function isExceptionExpired(expiresAt: string | undefined, now: Date): boolean {\n if (!expiresAt) return false;\n if (/^\\d{4}-\\d{2}-\\d{2}$/.test(expiresAt)) return sydneyDate(now) > expiresAt;\n const time = Date.parse(expiresAt);\n return Number.isNaN(time) || time <= now.getTime();\n}\n\nconst SYDNEY_DATE = new Intl.DateTimeFormat(\"en-CA\", {\n timeZone: \"Australia/Sydney\",\n year: \"numeric\",\n month: \"2-digit\",\n day: \"2-digit\",\n});\n\n/** YYYY-MM-DD in Sydney. */\nexport function sydneyDate(date: Date): string {\n return SYDNEY_DATE.format(date);\n}\n\nfunction recordLine(record: SiteSystemRecord): string {\n return `${sydneyDate(new Date(record.recordedAt))}: ${record.evidence}${record.note ? ` (${record.note})` : \"\"}`;\n}\n\nfunction plural(count: number, noun: string): string {\n return `${count} ${noun}${count === 1 ? \"\" : \"s\"}`;\n}\n\n/** \"a\", \"a and b\", \"a, b and c\". */\nfunction joinParts(parts: readonly string[]): string {\n const kept = parts.filter(Boolean);\n return kept.length <= 1 ? (kept[0] ?? \"\") : `${kept.slice(0, -1).join(\", \")} and ${kept.at(-1)}`;\n}\n\nconst STATUS_LABELS: Record<SiteSystemReadyStatus, string> = {\n pass: \"pass\",\n fail: \"fail\",\n \"not-run\": \"not run\",\n excepted: \"excepted\",\n \"not-applicable\": \"n/a\",\n};\n\n/** Plain English for Romie and agents: the verdict first, then the tables. */\nexport function renderSiteSystemReadyMarkdown(report: SiteSystemReadyReport): string {\n const blocking = report.checks.filter((check) => check.blocks);\n const reportsOnly = report.checks.filter((check) => !check.blocks);\n const lines = [\n `# Ready report${report.projectId ? `: ${report.projectId}` : \"\"}`,\n \"\",\n `**${report.verdict.summary}.**`,\n \"\",\n `Tier: ${report.tier ?? \"none declared\"} · Release: ${report.release ?? \"unknown\"} · New build or redesign: ${report.newBuild ? \"yes\" : \"no\"} · ${sydneyDate(new Date(report.generatedAt))}`,\n \"\",\n ];\n const { failed, notRun, blockers, stepsToRecord } = report.verdict;\n const todo = [\n // \"The home page …\", but \"brandlab.config.ts …\" keeps its file name as written.\n ...blockers.map((blocker) => `- ${/^[a-z]+\\s/.test(blocker) ? blocker.charAt(0).toUpperCase() + blocker.slice(1) : blocker}.`),\n failed.length > 0 ? `- Failed: ${failed.join(\", \")}.` : \"\",\n notRun.length > 0 ? `- Did not run: ${notRun.join(\", \")}.` : \"\",\n report.verdict.ready && stepsToRecord.length > 0 ? `- To record before launch: ${stepsToRecord.join(\", \")}.` : \"\",\n ].filter(Boolean);\n if ((report.tier || blockers.length > 0) && todo.length > 0) lines.push(...todo, \"\");\n lines.push(\"## Blocking checks\", \"\");\n if (blocking.length === 0) {\n lines.push(report.tier ? \"No check blocks on this release.\" : \"Nothing blocks until brandlab.config.ts declares siteSystem: { tier }.\");\n } else {\n lines.push(\"| Check | Status | What it checks | Result |\", \"| --- | --- | --- | --- |\");\n for (const check of blocking) {\n lines.push(row([check.id, statusLabel(check), check.summary, resultCell(check)]));\n }\n }\n lines.push(\"\", \"## Reported only\", \"\", \"| Check | Status | Reports only because | Result |\", \"| --- | --- | --- | --- |\");\n for (const check of reportsOnly) {\n lines.push(row([check.id, statusLabel(check), check.reportsOnly ?? \"\", check.status === \"not-run\" ? \"\" : resultCell(check)]));\n }\n\n for (const [file, title] of [[\"launch\", \"Launch-day steps\"], [\"human\", \"Human steps\"]] as const) {\n lines.push(\"\", `## ${title}`, \"\", \"| Step | Recorded | Evidence | What it covers |\", \"| --- | --- | --- | --- |\");\n for (const step of report.steps.filter((candidate) => candidate.file === file)) {\n const evidence = step.recorded ? `${step.evidence}${step.note ? ` (${step.note})` : \"\"}` : \"\";\n lines.push(row([step.id, step.recordedAt ? sydneyDate(new Date(step.recordedAt)) : \"not yet\", evidence, step.summary]));\n }\n }\n\n if (report.exceptions.length > 0) {\n lines.push(\"\", \"## Exceptions\", \"\", \"| Check | State | Expires | Rationale | Review trigger |\", \"| --- | --- | --- | --- | --- |\");\n for (const exception of report.exceptions) {\n const state = exception.state === \"not-needed\" ? `not needed (${exception.reason})` : exception.state;\n lines.push(row([exception.ruleId, state, exception.expiresAt ?? \"no date\", exception.rationale, exception.reviewTrigger]));\n }\n }\n\n const inputs = report.inputs;\n const pageList = inputs.pages.length > 12\n ? `${inputs.pages.slice(0, 12).join(\", \")} and ${inputs.pages.length - 12} more`\n : inputs.pages.join(\", \");\n lines.push(\n \"\",\n \"## Inputs\",\n \"\",\n `- Journeys: ${inputs.journeyReport ? `${inputs.journeyReport} (${plural(inputs.journeyTests, \"test run\")})` : \"no Playwright report\"}.`,\n `- Pages: ${inputs.pages.length === 0 ? \"none\" : `${inputs.pages.length} ${inputs.pageSource === \"base-url\" ? \"fetched from the running site\" : \"read from the build\"} (${pageList})`}.`,\n `- Rule modules: ${inputs.runners}.`,\n ...(inputs.findingFiles.length > 0 ? [`- Supplied findings: ${inputs.findingFiles.join(\", \")}.`] : []),\n );\n if (report.problems.length > 0) {\n lines.push(\"\", \"## Problems\", \"\", ...report.problems.map((problem) => `- ${inline(problem)}`));\n }\n lines.push(\"\", \"Record a step with `npx brandlab-ready record <id> --evidence <where the proof is>`.\", \"\");\n return lines.join(\"\\n\");\n}\n\nfunction statusLabel(check: SiteSystemReadyCheck): string {\n return check.status === \"pass\" && check.warnings.length > 0 ? \"pass (warning)\" : STATUS_LABELS[check.status];\n}\n\n/** The first message (the first warning for a pass with warnings) and how many more there are. */\nfunction resultCell(check: SiteSystemReadyCheck): string {\n const [first = \"\", ...rest] = check.status === \"pass\" && check.warnings.length > 0 ? check.warnings : check.messages;\n return rest.length > 0 ? `${first} (and ${rest.length} more)` : first;\n}\n\nfunction row(cells: readonly string[]): string {\n return `| ${cells.map((cell) => inline(cell).replace(/\\|/g, \"\\\\|\")).join(\" | \")} |`;\n}\n\n/** One line of text that GitHub shows as written: no raw HTML, so \"<a href>\" stays visible. */\nfunction inline(text: string): string {\n return text.replace(/\\s*\\r?\\n\\s*/g, \" \").replace(/&/g, \"&\").replace(/</g, \"<\").replace(/>/g, \">\");\n}\n"]}
|
|
1
|
+
{"version":3,"file":"report.js","sourceRoot":"","sources":["../../src/site-system/report.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * The ready report: every Site System check with its tier, whether it blocks for this site, its status and\n * messages; the existing brandlab-verify search, contact and analytics families (shell tier); the launch-day and\n * human steps; and the exceptions that apply. A blocking check that failed or did not run fails the gate.\n */\nimport type { BrandlabConformanceResult } from \"../project.js\";\nimport {\n SITE_SYSTEM_CHECKS,\n SITE_SYSTEM_TIERS,\n siteSystemCheckBlocks,\n type SiteSystemCheck,\n type SiteSystemCheckKind,\n type SiteSystemCheckScope,\n type SiteSystemFinding,\n type SiteSystemTier,\n} from \"./checks.js\";\nimport type { SiteSystemException, SiteSystemSettings } from \"./config.js\";\nimport { latestSiteSystemRecords, SITE_SYSTEM_RECORD_PATHS, type SiteSystemRecord } from \"./records.js\";\nimport {\n SITE_SYSTEM_HUMAN_STEPS,\n SITE_SYSTEM_LAUNCH_STEPS,\n SITE_SYSTEM_RECORDED_CHECK_IDS,\n type SiteSystemRecordFile,\n type SiteSystemStep,\n} from \"./steps.js\";\n\nexport const SITE_SYSTEM_READY_SCHEMA = \"brandlab.ready.v1\";\n\nexport const SITE_SYSTEM_READY_REPORT_PATHS = {\n markdown: \"docs/ready/ready-report.md\",\n json: \"docs/ready/ready-report.json\",\n} as const;\n\nexport type SiteSystemReadyStatus = \"pass\" | \"fail\" | \"not-run\" | \"excepted\" | \"not-applicable\";\n\nexport interface SiteSystemReadyCheck {\n readonly id: string;\n readonly summary: string;\n readonly tier: SiteSystemCheckScope;\n readonly from: string;\n /** A registry check kind, or `verify` for an existing brandlab-verify family. */\n readonly kind: SiteSystemCheckKind | \"verify\";\n readonly blocks: boolean;\n /** Why the check reports without blocking. */\n readonly reportsOnly?: string;\n readonly status: SiteSystemReadyStatus;\n readonly messages: readonly string[];\n /** Warnings never block; a passing check with warnings shows as \"pass (warning)\". */\n readonly warnings: readonly string[];\n}\n\nexport interface SiteSystemReadyStep {\n readonly id: string;\n readonly summary: string;\n readonly file: SiteSystemRecordFile;\n readonly recorded: boolean;\n readonly recordedAt?: string;\n readonly evidence?: string;\n readonly note?: string;\n}\n\nexport interface SiteSystemReadyException extends SiteSystemException {\n readonly expired: boolean;\n /** True when it turned a failing or unrun blocking check into `excepted`. */\n readonly applied: boolean;\n readonly state: \"applied\" | \"expired\" | \"not-needed\";\n /** Why an exception is not needed: the check passes, does not apply or does not block. */\n readonly reason?: string;\n}\n\nexport interface SiteSystemReadyVerdict {\n /** The declared tier's blocking checks all pass or are excepted. */\n readonly ready: boolean;\n /** Ready, and every launch-day and human step recorded. */\n readonly launchReady: boolean;\n readonly exitCode: 0 | 1;\n readonly summary: string;\n readonly failed: readonly string[];\n readonly notRun: readonly string[];\n readonly excepted: readonly string[];\n /** Reasons the run is not ready besides the checks (an unreadable config, a missing home or contact page). */\n readonly blockers: readonly string[];\n readonly stepsToRecord: readonly string[];\n}\n\nexport interface SiteSystemReadyInputs {\n /** The Playwright JSON report read, relative to the project, or null when there was none. */\n readonly journeyReport: string | null;\n readonly journeyTests: number;\n readonly pageSource: \"base-url\" | \"build\" | \"none\";\n readonly pages: readonly string[];\n readonly runners: number;\n readonly findingFiles: readonly string[];\n}\n\nexport interface SiteSystemReadyReport {\n readonly schemaVersion: typeof SITE_SYSTEM_READY_SCHEMA;\n readonly generatedAt: string;\n readonly projectId: string | null;\n readonly release: string | null;\n readonly tier: SiteSystemTier | null;\n readonly newBuild: boolean;\n /** Whether the run required every step to be recorded (`--launch`). */\n readonly launch: boolean;\n readonly verdict: SiteSystemReadyVerdict;\n readonly checks: readonly SiteSystemReadyCheck[];\n readonly steps: readonly SiteSystemReadyStep[];\n readonly exceptions: readonly SiteSystemReadyException[];\n readonly inputs: SiteSystemReadyInputs;\n readonly problems: readonly string[];\n}\n\n/** The brandlab-verify result the shell tier carries: its search, contact and analytics families. */\nexport type SiteSystemVerifyResult = Pick<BrandlabConformanceResult, \"verification\" | \"operationalFindings\">;\n\nexport interface BuildSiteSystemReadyReportInput {\n readonly projectId: string | null;\n readonly siteSystem: SiteSystemSettings | null;\n readonly release: string | null;\n /** Journey, rule-module and supplied findings. */\n readonly findings: readonly SiteSystemFinding[];\n /** Null when brandlab-verify could not run: its families then did not run. */\n readonly verify: SiteSystemVerifyResult | null;\n readonly launchRecords: readonly SiteSystemRecord[];\n readonly humanRecords: readonly SiteSystemRecord[];\n readonly exceptions: readonly SiteSystemException[];\n readonly inputs: SiteSystemReadyInputs;\n readonly problems: readonly string[];\n readonly now: Date;\n /** Require every launch-day and human step (`brandlab-ready --launch`). */\n readonly launch?: boolean;\n /** Reasons the run is not ready whatever the checks say, as short clauses (\"the home page could not be read\"). */\n readonly blockers?: readonly string[];\n}\n\nconst VERIFY_FAMILIES = [\"search-output\", \"contact-delivery\", \"analytics\"] as const;\nconst VERIFY_SCOPE = { tier: \"shell\", from: \"3.8.0\" } as const;\n\nexport function buildSiteSystemReadyReport(input: BuildSiteSystemReadyReportInput): SiteSystemReadyReport {\n const problems = [...input.problems];\n const settings = input.siteSystem;\n const site = settings && input.release\n ? { tier: settings.tier, release: input.release, newBuild: settings.newBuild }\n : null;\n if (settings && !input.release) problems.push(\"The installed Brandlab release is unknown, so no check could block.\");\n\n const launchLatest = latestSiteSystemRecords(input.launchRecords);\n const humanLatest = latestSiteSystemRecords(input.humanRecords);\n const launchIds = new Set<string>([...SITE_SYSTEM_LAUNCH_STEPS.map((step) => step.id), ...SITE_SYSTEM_RECORDED_CHECK_IDS]);\n const humanIds = new Set<string>(SITE_SYSTEM_HUMAN_STEPS.map((step) => step.id));\n for (const id of launchLatest.keys()) {\n if (!launchIds.has(id)) problems.push(`${SITE_SYSTEM_RECORD_PATHS.launch} records ${id}, which is not a launch-day step or recorded check, so it was ignored.`);\n }\n for (const id of humanLatest.keys()) {\n if (!humanIds.has(id)) problems.push(`${SITE_SYSTEM_RECORD_PATHS.human} records ${id}, which is not a human step, so it was ignored.`);\n }\n\n const findings: SiteSystemFinding[] = [...input.findings];\n for (const id of SITE_SYSTEM_RECORDED_CHECK_IDS) {\n const record = launchLatest.get(id);\n if (record) findings.push({ checkId: id as SiteSystemFinding[\"checkId\"], status: \"pass\", message: `Recorded ${recordLine(record)}` });\n }\n\n const exceptionsByRule = new Map<string, SiteSystemException>();\n for (const exception of input.exceptions) {\n if (!exceptionsByRule.has(exception.ruleId)) exceptionsByRule.set(exception.ruleId, exception);\n }\n const knownIds = new Set<string>([...SITE_SYSTEM_CHECKS.map((check) => check.id), ...VERIFY_FAMILIES.map((id) => `verify:${id}`)]);\n for (const ruleId of exceptionsByRule.keys()) {\n if (!knownIds.has(ruleId)) problems.push(`The exception for ${ruleId} names no ready-gate check, so the gate ignored it.`);\n }\n const usedExceptions: SiteSystemReadyException[] = [];\n const applyException = (id: string, blocks: boolean, status: SiteSystemReadyStatus, messages: string[]) => {\n const exception = exceptionsByRule.get(id);\n if (!exception) return { status, messages };\n const expired = isExceptionExpired(exception.expiresAt, input.now);\n const unresolved = status === \"fail\" || status === \"not-run\";\n const applied = blocks && unresolved && !expired;\n const reason = !blocks ? \"the check does not block\" : status === \"not-applicable\" ? \"the check does not apply\" : \"the check passes\";\n usedExceptions.push({\n ...exception,\n expired,\n applied,\n state: expired ? \"expired\" : applied ? \"applied\" : \"not-needed\",\n ...(expired || applied ? {} : { reason }),\n });\n if (!unresolved) return { status, messages };\n if (expired) return { status, messages: [`The exception expired on ${exception.expiresAt}, so it no longer counts.`, ...messages] };\n if (!applied) return { status, messages };\n const until = exception.expiresAt ? ` until ${exception.expiresAt}` : \"\";\n return { status: \"excepted\" as const, messages: [`Excepted by Romie${until}: ${exception.rationale}`, ...messages] };\n };\n\n const checks: SiteSystemReadyCheck[] = SITE_SYSTEM_CHECKS.map((check: SiteSystemCheck) => {\n const blocks = site ? siteSystemCheckBlocks(check, site) : false;\n const merged = launchOnlyNotRun(\n check,\n blocks,\n input.launch === true,\n mergeFindings(findings.filter((finding) => finding.checkId === check.id), notRunMessage(check, input.inputs, settings)),\n );\n const { status, messages } = applyException(check.id, blocks, merged.status, merged.messages);\n return {\n id: check.id,\n summary: check.summary,\n tier: check.tier,\n from: check.from,\n kind: check.kind,\n blocks,\n ...(blocks ? {} : { reportsOnly: reportsOnlyReason(check, settings) }),\n status,\n messages,\n warnings: merged.warnings,\n };\n });\n\n for (const familyId of VERIFY_FAMILIES) {\n const id = `verify:${familyId}`;\n const family = input.verify?.verification.families.find((candidate) => candidate.id === familyId);\n const blocks = site ? siteSystemCheckBlocks({ id, ...VERIFY_SCOPE }, site) : false;\n const merged = verifyStatus(family, input.verify?.operationalFindings ?? []);\n const { status, messages } = applyException(id, blocks, merged.status, merged.messages);\n checks.push({\n id,\n summary: family ? `${family.title} (brandlab-verify): ${family.purpose}` : `The brandlab-verify ${familyId} checks.`,\n tier: VERIFY_SCOPE.tier,\n from: VERIFY_SCOPE.from,\n kind: \"verify\",\n blocks,\n ...(blocks ? {} : { reportsOnly: reportsOnlyReason(VERIFY_SCOPE, settings) }),\n status,\n messages,\n warnings: merged.warnings,\n });\n }\n\n const steps: SiteSystemReadyStep[] = [\n ...SITE_SYSTEM_LAUNCH_STEPS.map((step) => readyStep(step, \"launch\", launchLatest.get(step.id))),\n ...SITE_SYSTEM_HUMAN_STEPS.map((step) => readyStep(step, \"human\", humanLatest.get(step.id))),\n ];\n\n const verdict = readyVerdict({\n settings,\n release: input.release,\n checks,\n steps,\n launch: input.launch === true,\n blockers: input.blockers ?? [],\n });\n return {\n schemaVersion: SITE_SYSTEM_READY_SCHEMA,\n generatedAt: input.now.toISOString(),\n projectId: input.projectId,\n release: input.release,\n tier: settings?.tier ?? null,\n newBuild: settings?.newBuild ?? false,\n launch: input.launch === true,\n verdict,\n checks,\n steps,\n exceptions: usedExceptions,\n inputs: input.inputs,\n problems,\n };\n}\n\n/**\n * A check whose not-run blocks only at launch (H13): under `--launch` a blocking not-run is a failure; otherwise it\n * stays not run with a note, and the verdict does not count it.\n */\nfunction launchOnlyNotRun(\n check: SiteSystemCheck,\n blocks: boolean,\n launch: boolean,\n merged: { status: SiteSystemReadyStatus; messages: string[]; warnings: string[] },\n): { status: SiteSystemReadyStatus; messages: string[]; warnings: string[] } {\n if (check.notRunBlocks !== \"launch\" || merged.status !== \"not-run\" || !blocks) return merged;\n if (launch) return { ...merged, status: \"fail\", messages: merged.messages.map((message) => `Launch needs this check to run. ${message}`) };\n return { ...merged, messages: [...merged.messages, \"It blocks only at launch (brandlab-ready --launch).\"] };\n}\n\n/**\n * Any fail fails the check; otherwise a rule's own not-run result (naming what it needed) leaves it not run; otherwise\n * any pass passes it; only not-applicable results make it not applicable. A warning is a pass that carries its message\n * as a warning, whatever status it names.\n */\nfunction mergeFindings(\n findings: readonly SiteSystemFinding[],\n notRun: string,\n): { status: SiteSystemReadyStatus; messages: string[]; warnings: string[] } {\n const warnings = [...new Set(findings.filter((finding) => finding.severity === \"warning\").map((finding) => finding.message))];\n const results = findings.filter((finding) => finding.severity !== \"warning\");\n if (warnings.length > 0 && !results.some((finding) => finding.status !== \"not-applicable\")) {\n return { status: \"pass\", messages: [], warnings };\n }\n for (const status of [\"fail\", \"not-run\", \"pass\", \"not-applicable\"] as const) {\n const scoped = results.filter((finding) => finding.status === status);\n if (scoped.length > 0) return { status, messages: [...new Set(scoped.map((finding) => finding.message))], warnings };\n }\n return { status: \"not-run\", messages: [notRun], warnings };\n}\n\nfunction verifyStatus(\n family: SiteSystemVerifyResult[\"verification\"][\"families\"][number] | undefined,\n findings: SiteSystemVerifyResult[\"operationalFindings\"],\n): { status: SiteSystemReadyStatus; messages: string[]; warnings: string[] } {\n if (!family) return { status: \"not-run\", messages: [\"brandlab-verify did not run, so these checks have no result.\"], warnings: [] };\n const scoped = findings\n .filter((finding) => finding.familyId === family.id)\n .map((finding) => {\n const location = finding.path ? ` (${finding.path}${finding.line ? `:${finding.line}` : \"\"})` : \"\";\n return { severity: finding.severity, message: `${finding.ruleId}${location}: ${finding.actual}` };\n });\n const warnings = scoped.filter((finding) => finding.severity === \"warning\").map((finding) => finding.message);\n if (family.status === \"blocked\") {\n return { status: \"fail\", messages: scoped.filter((finding) => finding.severity === \"blocker\").map((finding) => finding.message), warnings };\n }\n if (family.status === \"not_run\") return { status: \"not-applicable\", messages: [\"No brandlab-verify rule in this family applies to this project.\"], warnings };\n return { status: \"pass\", messages: [`brandlab-verify found nothing to fix in ${family.title.toLowerCase()}.`], warnings };\n}\n\n/** What a site's site-system spec must pass for a journey to register, beyond its tier. */\nconst JOURNEY_PAGES: Readonly<Record<string, string>> = {\n C1: \"pages: { money: [...] }\",\n W9: \"pages: { families: [...] }\",\n};\nconst JOURNEY_PAGES_WHY: Readonly<Record<string, string>> = {\n C1: \"pages.money names the service pages with the enquiry form\",\n W9: \"pages.families names one built page per dynamic route family\",\n};\n\nfunction notRunMessage(check: SiteSystemCheck, inputs?: SiteSystemReadyInputs, settings?: SiteSystemSettings | null): string {\n switch (check.kind) {\n case \"journey\": {\n if (!inputs?.journeyReport || inputs.journeyTests === 0) {\n return \"No journey result: run the site-system journeys (npm run test:e2e) before brandlab-ready.\";\n }\n // Other journeys ran, so this one did not register: the spec's tier or pages, or a conformance release before it.\n const tier = settings?.tier ?? check.tier;\n const pages = JOURNEY_PAGES[check.id];\n const why = JOURNEY_PAGES_WHY[check.id];\n return `No journey result: ${inputs.journeyReport} has ${plural(inputs.journeyTests, \"site-system test run\")} but none for ${check.id}. ` +\n `The journeys register by tier and release: tests/e2e/site-system.spec.ts calls defineBrandlabSiteSystemTests({ tier: '${tier}'${pages ? `, ${pages}` : \"\"} }) ` +\n `(${check.id} is a ${check.tier}-tier journey from ${check.from}${why ? `, and ${why}` : \"\"}), and @brandlab-digital/conformance must be ${check.from} or later; ` +\n \"then run npm run test:e2e with the JSON reporter before brandlab-ready.\";\n }\n case \"rendered\":\n return \"No result: no rule module reported this check for the sampled pages.\";\n case \"static\":\n return \"No result: no rule module reported this check.\";\n case \"record\":\n return `Not recorded: run brandlab-ready record ${check.id} --evidence <where the proof is>.`;\n }\n}\n\nfunction reportsOnlyReason(check: Pick<SiteSystemCheck, \"tier\" | \"from\">, settings: SiteSystemSettings | null): string {\n if (!settings) return \"no tier declared\";\n if (check.tier === \"new-build\") return settings.newBuild ? \"blocks new builds from 3.9.0\" : \"new builds and redesigns only\";\n return SITE_SYSTEM_TIERS.indexOf(check.tier) <= SITE_SYSTEM_TIERS.indexOf(settings.tier)\n ? `blocks from ${check.from}`\n : `${check.tier} tier`;\n}\n\nfunction readyStep(step: SiteSystemStep, file: SiteSystemRecordFile, record: SiteSystemRecord | undefined): SiteSystemReadyStep {\n return {\n id: step.id,\n summary: step.summary,\n file,\n recorded: Boolean(record),\n ...(record\n ? { recordedAt: record.recordedAt, evidence: record.evidence, ...(record.note ? { note: record.note } : {}) }\n : {}),\n };\n}\n\nfunction readyVerdict(input: {\n settings: SiteSystemSettings | null;\n release: string | null;\n checks: readonly SiteSystemReadyCheck[];\n steps: readonly SiteSystemReadyStep[];\n launch: boolean;\n blockers: readonly string[];\n}): SiteSystemReadyVerdict {\n const blocking = input.checks.filter((check) => check.blocks);\n const failed = blocking.filter((check) => check.status === \"fail\").map((check) => check.id);\n const launchOnly = new Set<string>((SITE_SYSTEM_CHECKS as readonly SiteSystemCheck[]).filter((check) => check.notRunBlocks === \"launch\").map((check) => check.id));\n // A launch-only check that did not run is reported, not counted: under --launch it is already a failure.\n const notRun = blocking.filter((check) => check.status === \"not-run\" && !launchOnly.has(check.id)).map((check) => check.id);\n const excepted = blocking.filter((check) => check.status === \"excepted\").map((check) => check.id);\n const stepsToRecord = input.steps.filter((step) => !step.recorded).map((step) => step.id);\n const adopted = input.settings !== null;\n const ready = adopted && input.release !== null && blocking.length > 0 && failed.length === 0 &&\n notRun.length === 0 && input.blockers.length === 0;\n const launchReady = ready && stepsToRecord.length === 0;\n const launchSteps = input.steps.filter((step) => !step.recorded && step.file === \"launch\").length;\n const humanSteps = input.steps.filter((step) => !step.recorded && step.file === \"human\").length;\n const stepCount = joinParts([\n launchSteps > 0 ? `${launchSteps} launch-day` : \"\",\n humanSteps > 0 ? `${humanSteps} human` : \"\",\n ]);\n const stepNoun = launchSteps + humanSteps === 1 ? \"step\" : \"steps\";\n const reasons = [\n failed.length > 0 ? `${plural(failed.length, \"blocking check\")} failed` : \"\",\n notRun.length > 0 ? (failed.length > 0 ? `${notRun.length} did not run` : `${plural(notRun.length, \"blocking check\")} did not run`) : \"\",\n ...input.blockers,\n ].filter(Boolean);\n\n let summary: string;\n let exitCode: 0 | 1 = 1;\n if (input.blockers.length > 0 || (adopted && reasons.length > 0)) {\n summary = `Not ready: ${joinParts(reasons)}`;\n } else if (!adopted) {\n summary = \"Not adopted: brandlab.config.ts declares no siteSystem tier, so no check blocks yet\";\n exitCode = 0;\n } else if (input.release === null) {\n summary = \"Not ready: the installed Brandlab release is unknown\";\n } else if (input.launch && stepsToRecord.length > 0) {\n summary = `Not ready: ${stepCount} ${stepNoun} not recorded`;\n } else if (blocking.length === 0) {\n summary = `No check blocks on release ${input.release}`;\n exitCode = 0;\n } else {\n summary = launchReady\n ? `Ready at ${input.settings!.tier} tier`\n : `Checks pass at ${input.settings!.tier} tier; before launch, record ${stepCount} ${stepNoun}`;\n if (excepted.length > 0) summary += ` (${plural(excepted.length, \"check\")} excepted)`;\n exitCode = 0;\n }\n return { ready, launchReady, exitCode, summary, failed, notRun, excepted, blockers: input.blockers, stepsToRecord };\n}\n\n/** Date-only expiries last to the end of that day in Sydney; timestamps expire at that instant. */\nexport function isExceptionExpired(expiresAt: string | undefined, now: Date): boolean {\n if (!expiresAt) return false;\n if (/^\\d{4}-\\d{2}-\\d{2}$/.test(expiresAt)) return sydneyDate(now) > expiresAt;\n const time = Date.parse(expiresAt);\n return Number.isNaN(time) || time <= now.getTime();\n}\n\nconst SYDNEY_DATE = new Intl.DateTimeFormat(\"en-CA\", {\n timeZone: \"Australia/Sydney\",\n year: \"numeric\",\n month: \"2-digit\",\n day: \"2-digit\",\n});\n\n/** YYYY-MM-DD in Sydney. */\nexport function sydneyDate(date: Date): string {\n return SYDNEY_DATE.format(date);\n}\n\nfunction recordLine(record: SiteSystemRecord): string {\n return `${sydneyDate(new Date(record.recordedAt))}: ${record.evidence}${record.note ? ` (${record.note})` : \"\"}`;\n}\n\nfunction plural(count: number, noun: string): string {\n return `${count} ${noun}${count === 1 ? \"\" : \"s\"}`;\n}\n\n/** \"a\", \"a and b\", \"a, b and c\". */\nfunction joinParts(parts: readonly string[]): string {\n const kept = parts.filter(Boolean);\n return kept.length <= 1 ? (kept[0] ?? \"\") : `${kept.slice(0, -1).join(\", \")} and ${kept.at(-1)}`;\n}\n\nconst STATUS_LABELS: Record<SiteSystemReadyStatus, string> = {\n pass: \"pass\",\n fail: \"fail\",\n \"not-run\": \"not run\",\n excepted: \"excepted\",\n \"not-applicable\": \"n/a\",\n};\n\n/** Plain English for Romie and agents: the verdict first, then the tables. */\nexport function renderSiteSystemReadyMarkdown(report: SiteSystemReadyReport): string {\n const blocking = report.checks.filter((check) => check.blocks);\n const reportsOnly = report.checks.filter((check) => !check.blocks);\n const lines = [\n `# Ready report${report.projectId ? `: ${report.projectId}` : \"\"}`,\n \"\",\n `**${report.verdict.summary}.**`,\n \"\",\n `Tier: ${report.tier ?? \"none declared\"} · Release: ${report.release ?? \"unknown\"} · New build or redesign: ${report.newBuild ? \"yes\" : \"no\"} · ${sydneyDate(new Date(report.generatedAt))}`,\n \"\",\n ];\n const { failed, notRun, blockers, stepsToRecord } = report.verdict;\n const todo = [\n // \"The home page …\", but \"brandlab.config.ts …\" keeps its file name as written.\n ...blockers.map((blocker) => `- ${/^[a-z]+\\s/.test(blocker) ? blocker.charAt(0).toUpperCase() + blocker.slice(1) : blocker}.`),\n failed.length > 0 ? `- Failed: ${failed.join(\", \")}.` : \"\",\n notRun.length > 0 ? `- Did not run: ${notRun.join(\", \")}.` : \"\",\n report.verdict.ready && stepsToRecord.length > 0 ? `- To record before launch: ${stepsToRecord.join(\", \")}.` : \"\",\n ].filter(Boolean);\n if ((report.tier || blockers.length > 0) && todo.length > 0) lines.push(...todo, \"\");\n lines.push(\"## Blocking checks\", \"\");\n if (blocking.length === 0) {\n lines.push(report.tier ? \"No check blocks on this release.\" : \"Nothing blocks until brandlab.config.ts declares siteSystem: { tier }.\");\n } else {\n lines.push(\"| Check | Status | What it checks | Result |\", \"| --- | --- | --- | --- |\");\n for (const check of blocking) {\n lines.push(row([check.id, statusLabel(check), check.summary, resultCell(check)]));\n }\n }\n lines.push(\"\", \"## Reported only\", \"\", \"| Check | Status | Reports only because | Result |\", \"| --- | --- | --- | --- |\");\n for (const check of reportsOnly) {\n lines.push(row([check.id, statusLabel(check), check.reportsOnly ?? \"\", check.status === \"not-run\" ? \"\" : resultCell(check)]));\n }\n\n for (const [file, title] of [[\"launch\", \"Launch-day steps\"], [\"human\", \"Human steps\"]] as const) {\n lines.push(\"\", `## ${title}`, \"\", \"| Step | Recorded | Evidence | What it covers |\", \"| --- | --- | --- | --- |\");\n for (const step of report.steps.filter((candidate) => candidate.file === file)) {\n const evidence = step.recorded ? `${step.evidence}${step.note ? ` (${step.note})` : \"\"}` : \"\";\n lines.push(row([step.id, step.recordedAt ? sydneyDate(new Date(step.recordedAt)) : \"not yet\", evidence, step.summary]));\n }\n }\n\n if (report.exceptions.length > 0) {\n lines.push(\"\", \"## Exceptions\", \"\", \"| Check | State | Expires | Rationale | Review trigger |\", \"| --- | --- | --- | --- | --- |\");\n for (const exception of report.exceptions) {\n const state = exception.state === \"not-needed\" ? `not needed (${exception.reason})` : exception.state;\n lines.push(row([exception.ruleId, state, exception.expiresAt ?? \"no date\", exception.rationale, exception.reviewTrigger]));\n }\n }\n\n const inputs = report.inputs;\n const pageList = inputs.pages.length > 12\n ? `${inputs.pages.slice(0, 12).join(\", \")} and ${inputs.pages.length - 12} more`\n : inputs.pages.join(\", \");\n lines.push(\n \"\",\n \"## Inputs\",\n \"\",\n `- Journeys: ${inputs.journeyReport ? `${inputs.journeyReport} (${plural(inputs.journeyTests, \"test run\")})` : \"no Playwright report\"}.`,\n `- Pages: ${inputs.pages.length === 0 ? \"none\" : `${inputs.pages.length} ${inputs.pageSource === \"base-url\" ? \"fetched from the running site\" : \"read from the build\"} (${pageList})`}.`,\n `- Rule modules: ${inputs.runners}.`,\n ...(inputs.findingFiles.length > 0 ? [`- Supplied findings: ${inputs.findingFiles.join(\", \")}.`] : []),\n );\n if (report.problems.length > 0) {\n lines.push(\"\", \"## Problems\", \"\", ...report.problems.map((problem) => `- ${inline(problem)}`));\n }\n lines.push(\"\", \"Record a step with `npx brandlab-ready record <id> --evidence <where the proof is>`.\", \"\");\n return lines.join(\"\\n\");\n}\n\nfunction statusLabel(check: SiteSystemReadyCheck): string {\n return check.status === \"pass\" && check.warnings.length > 0 ? \"pass (warning)\" : STATUS_LABELS[check.status];\n}\n\n/** The first message (the first warning for a pass with warnings) and how many more there are. */\nfunction resultCell(check: SiteSystemReadyCheck): string {\n const [first = \"\", ...rest] = check.status === \"pass\" && check.warnings.length > 0 ? check.warnings : check.messages;\n return rest.length > 0 ? `${first} (and ${rest.length} more)` : first;\n}\n\nfunction row(cells: readonly string[]): string {\n return `| ${cells.map((cell) => inline(cell).replace(/\\|/g, \"\\\\|\")).join(\" | \")} |`;\n}\n\n/** One line of text that GitHub shows as written: no raw HTML, so \"<a href>\" stays visible. */\nfunction inline(text: string): string {\n return text.replace(/\\s*\\r?\\n\\s*/g, \" \").replace(/&/g, \"&\").replace(/</g, \"<\").replace(/>/g, \">\");\n}\n"]}
|
|
@@ -5,8 +5,13 @@
|
|
|
5
5
|
* anything urgent, and keeps itself out of search (`noindex, follow`) so it never ranks and never counts as a lead.
|
|
6
6
|
* The library's `ThankYou` block and `thankYouMetadata()` do all three. A site with a quote form but no thank-you page
|
|
7
7
|
* among the sampled pages fails: the form has nowhere to send an accepted enquiry.
|
|
8
|
+
*
|
|
9
|
+
* A site whose owner decided to promise no reply time records it in `siteSystem.replyTime` (3.15.0): the page then
|
|
10
|
+
* carries the recorded wording instead of a time, and must not promise a time anyway. Without the record, vague
|
|
11
|
+
* words such as "shortly" or "as soon as we can" still fail.
|
|
8
12
|
*/
|
|
9
13
|
import type { SiteSystemFinding } from "../../checks.js";
|
|
14
|
+
import type { SiteSystemReplyTime } from "../../config.js";
|
|
10
15
|
import { type ParsedPage } from "../enquiry/common.js";
|
|
11
16
|
import { type HtmlElement } from "../enquiry/html.js";
|
|
12
17
|
/** A sentence that says how soon the business replies: "within one business day", "in 1 to 2 hours", "within the hour". */
|
|
@@ -16,5 +21,6 @@ export declare const C7_REPLY_TIME: RegExp;
|
|
|
16
21
|
* leaves Bing and every other crawler free to index the page, which is why `thankYouMetadata()` writes both.
|
|
17
22
|
*/
|
|
18
23
|
export declare function robotsDirectives(root: HtmlElement): string[];
|
|
19
|
-
|
|
24
|
+
/** C7 over the sampled pages. `replyTime` is the site's `siteSystem.replyTime` record, when it has one. */
|
|
25
|
+
export declare function checkC7(pages: readonly ParsedPage[], missing?: readonly string[], replyTime?: SiteSystemReplyTime | null): SiteSystemFinding[];
|
|
20
26
|
//# sourceMappingURL=c7-thank-you.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"c7-thank-you.d.ts","sourceRoot":"","sources":["../../../../src/site-system/rules/form/c7-thank-you.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"c7-thank-you.d.ts","sourceRoot":"","sources":["../../../../src/site-system/rules/form/c7-thank-you.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AACH,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,iBAAiB,CAAC;AACzD,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,iBAAiB,CAAC;AAC3D,OAAO,EAAyC,KAAK,UAAU,EAAE,MAAM,sBAAsB,CAAC;AAE9F,OAAO,EAA6B,KAAK,WAAW,EAAE,MAAM,oBAAoB,CAAC;AAMjF,2HAA2H;AAC3H,eAAO,MAAM,aAAa,QASzB,CAAC;AAEF;;;GAGG;AACH,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,WAAW,GAAG,MAAM,EAAE,CAK5D;AA6BD,2GAA2G;AAC3G,wBAAgB,OAAO,CAAC,KAAK,EAAE,SAAS,UAAU,EAAE,EAAE,OAAO,GAAE,SAAS,MAAM,EAAO,EAAE,SAAS,GAAE,mBAAmB,GAAG,IAAW,GAAG,iBAAiB,EAAE,CAwCxJ"}
|
|
@@ -31,7 +31,20 @@ function telLinks(scope) {
|
|
|
31
31
|
function isThankYouPage(page) {
|
|
32
32
|
return isThankYouPath(page.path) || byHook(page.root, "thank-you").length > 0;
|
|
33
33
|
}
|
|
34
|
-
|
|
34
|
+
/** Lower case, curly quotes straightened, apostrophes dropped, other punctuation and runs of space as one space. */
|
|
35
|
+
function normalised(text) {
|
|
36
|
+
return text
|
|
37
|
+
.toLowerCase()
|
|
38
|
+
.replace(/[\u2018\u2019']/g, "")
|
|
39
|
+
.replace(/[^\p{L}\p{N}]+/gu, " ")
|
|
40
|
+
.trim();
|
|
41
|
+
}
|
|
42
|
+
function decision(record) {
|
|
43
|
+
return record.decidedBy === "owner" ? `the owner recorded on ${record.decidedOn}` : `Romie recorded for the owner on ${record.decidedOn}`;
|
|
44
|
+
}
|
|
45
|
+
/** C7 over the sampled pages. `replyTime` is the site's `siteSystem.replyTime` record, when it has one. */
|
|
46
|
+
export function checkC7(pages, missing = [], replyTime = null) {
|
|
47
|
+
const noPromise = replyTime?.promise === false ? replyTime : null;
|
|
35
48
|
const thankYouPages = pages.filter(isThankYouPage);
|
|
36
49
|
if (thankYouPages.length === 0) {
|
|
37
50
|
const named = missing.find((path) => isThankYouPath(path));
|
|
@@ -48,7 +61,16 @@ export function checkC7(pages, missing = []) {
|
|
|
48
61
|
const scope = block ?? mainOf(page.root);
|
|
49
62
|
const reply = descendants(scope).find((element) => attr(element, "data-slot") === "reply");
|
|
50
63
|
const replyText = reply ? textOf(reply) : textOf(scope);
|
|
51
|
-
if (
|
|
64
|
+
if (noPromise) {
|
|
65
|
+
if (!` ${normalised(replyText)} `.includes(` ${normalised(noPromise.wording)} `)) {
|
|
66
|
+
failures.push(fail("C7", page.path, `The thank-you page ${page.path} does not use the reply wording ${decision(noPromise)} ("${noPromise.wording}").`));
|
|
67
|
+
}
|
|
68
|
+
else if (C7_REPLY_TIME.test(replyText)) {
|
|
69
|
+
const by = noPromise.decidedBy === "owner" ? "the owner" : "Romie, for the owner,";
|
|
70
|
+
failures.push(fail("C7", page.path, `The thank-you page ${page.path} promises a reply time although ${by} decided on ${noPromise.decidedOn} to promise none; use "${noPromise.wording}".`));
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
else if (!C7_REPLY_TIME.test(replyText)) {
|
|
52
74
|
failures.push(fail("C7", page.path, `The thank-you page ${page.path} does not say when the business will reply (for example "within one business day").`));
|
|
53
75
|
}
|
|
54
76
|
if (telLinks(scope).length === 0) {
|
|
@@ -62,6 +84,7 @@ export function checkC7(pages, missing = []) {
|
|
|
62
84
|
failures.push(fail("C7", page.path, `The thank-you page ${page.path} is noindex but also nofollow; its links should still be followed ("noindex, follow").`));
|
|
63
85
|
}
|
|
64
86
|
}
|
|
65
|
-
|
|
87
|
+
const reply = noPromise ? `the reply wording ${decision(noPromise)} instead of a reply time ("${noPromise.wording}")` : "a reply time";
|
|
88
|
+
return resultOf("C7", failures, `Checked ${plural(thankYouPages.length, "thank-you page")}: each gives ${reply} and a tel: link and is noindex, follow.`);
|
|
66
89
|
}
|
|
67
90
|
//# sourceMappingURL=c7-thank-you.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"c7-thank-you.js","sourceRoot":"","sources":["../../../../src/site-system/rules/form/c7-thank-you.ts"],"names":[],"mappings":"AASA,OAAO,EAAE,IAAI,EAAE,aAAa,EAAE,MAAM,EAAE,QAAQ,EAAmB,MAAM,sBAAsB,CAAC;AAC9F,OAAO,EAAE,WAAW,EAAE,MAAM,6BAA6B,CAAC;AAC1D,OAAO,EAAE,IAAI,EAAE,WAAW,EAAE,MAAM,EAAoB,MAAM,oBAAoB,CAAC;AACjF,OAAO,EAAE,MAAM,EAAE,cAAc,EAAE,MAAM,EAAE,MAAM,sBAAsB,CAAC;AAEtE,MAAM,MAAM,GAAG,MAAM,CAAC,GAAG,CAAA,sHAAsH,CAAC;AAChJ,MAAM,IAAI,GAAG,MAAM,CAAC,GAAG,CAAA,uEAAuE,CAAC;AAE/F,2HAA2H;AAC3H,MAAM,CAAC,MAAM,aAAa,GAAG,IAAI,MAAM,CACrC;IACE,MAAM,CAAC,GAAG,CAAA,yDAAyD,MAAM,yBAAyB,MAAM,QAAQ,IAAI,IAAI;IACxH,MAAM,CAAC,GAAG,CAAA,sEAAsE;IAChF,MAAM,CAAC,GAAG,CAAA,yFAAyF;IACnG,MAAM,CAAC,GAAG,CAAA,+CAA+C;IACzD,MAAM,CAAC,GAAG,CAAA,+DAA+D;CAC1E,CAAC,IAAI,CAAC,GAAG,CAAC,EACX,GAAG,CACJ,CAAC;AAEF;;;GAGG;AACH,MAAM,UAAU,gBAAgB,CAAC,IAAiB;IAChD,OAAO,WAAW,CAAC,IAAI,CAAC;SACrB,MAAM,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,OAAO,CAAC,GAAG,KAAK,MAAM,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,MAAM,CAAC,IAAI,EAAE,CAAC,CAAC,WAAW,EAAE,KAAK,QAAQ,CAAC;SACvG,OAAO,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC,IAAI,CAAC,OAAO,EAAE,SAAS,CAAC,IAAI,EAAE,CAAC,CAAC,WAAW,EAAE,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC;SACpF,MAAM,CAAC,OAAO,CAAC,CAAC;AACrB,CAAC;AAED,SAAS,YAAY,CAAC,IAAgB;IACpC,OAAO,WAAW,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,OAAO,CAAC,GAAG,KAAK,MAAM,IAAI,WAAW,CAAC,OAAO,CAAC,CAAC,CAAC;AAClG,CAAC;AAED,SAAS,QAAQ,CAAC,KAAkB;IAClC,OAAO,WAAW,CAAC,KAAK,CAAC,CAAC,MAAM,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,OAAO,CAAC,GAAG,KAAK,GAAG,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,MAAM,CAAC,IAAI,EAAE,CAAC,CAAC,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC,UAAU,CAAC,MAAM,CAAC,CAAC,CAAC;AAC9I,CAAC;AAED,SAAS,cAAc,CAAC,IAAgB;IACtC,OAAO,cAAc,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,MAAM,CAAC,IAAI,CAAC,IAAI,EAAE,WAAW,CAAC,CAAC,MAAM,GAAG,CAAC,CAAC;AAChF,CAAC;AAED,MAAM,UAAU,OAAO,CAAC,KAA4B,EAAE,UAA6B,EAAE;IACnF,MAAM,aAAa,GAAG,KAAK,CAAC,MAAM,CAAC,cAAc,CAAC,CAAC;IACnD,IAAI,aAAa,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QAC/B,MAAM,KAAK,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,cAAc,CAAC,IAAI,CAAC,CAAC,CAAC;QAC3D,IAAI,KAAK,KAAK,SAAS,EAAE,CAAC;YACxB,OAAO,CAAC,IAAI,CAAC,IAAI,EAAE,KAAK,EAAE,sBAAsB,KAAK,gFAAgF,CAAC,CAAC,CAAC;QAC1I,CAAC;QACD,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,YAAY,CAAC;YAAE,OAAO,CAAC,aAAa,CAAC,IAAI,EAAE,iEAAiE,CAAC,CAAC,CAAC;QAC/H,OAAO,CAAC,IAAI,CAAC,IAAI,EAAE,SAAS,EAAE,kFAAkF,CAAC,CAAC,CAAC;IACrH,CAAC;IAED,MAAM,QAAQ,GAAwB,EAAE,CAAC;IACzC,KAAK,MAAM,IAAI,IAAI,aAAa,EAAE,CAAC;QACjC,MAAM,KAAK,GAAG,MAAM,CAAC,IAAI,CAAC,IAAI,EAAE,WAAW,CAAC,CAAC,CAAC,CAAC,CAAC;QAChD,MAAM,KAAK,GAAG,KAAK,IAAI,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QACzC,MAAM,KAAK,GAAG,WAAW,CAAC,KAAK,CAAC,CAAC,IAAI,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,IAAI,CAAC,OAAO,EAAE,WAAW,CAAC,KAAK,OAAO,CAAC,CAAC;QAC3F,MAAM,SAAS,GAAG,KAAK,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;QACxD,IAAI,CAAC,aAAa,CAAC,IAAI,CAAC,SAAS,CAAC,EAAE,CAAC;YACnC,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,IAAI,CAAC,IAAI,EAAE,sBAAsB,IAAI,CAAC,IAAI,qFAAqF,CAAC,CAAC,CAAC;QAC7J,CAAC;QACD,IAAI,QAAQ,CAAC,KAAK,CAAC,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YACjC,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,IAAI,CAAC,IAAI,EAAE,sBAAsB,IAAI,CAAC,IAAI,wCAAwC,CAAC,CAAC,CAAC;QAChH,CAAC;QACD,MAAM,UAAU,GAAG,gBAAgB,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QAC/C,IAAI,CAAC,UAAU,CAAC,QAAQ,CAAC,SAAS,CAAC,IAAI,CAAC,UAAU,CAAC,QAAQ,CAAC,MAAM,CAAC,EAAE,CAAC;YACpE,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,IAAI,CAAC,IAAI,EAAE,sBAAsB,IAAI,CAAC,IAAI,uCAAuC,UAAU,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,MAAM,iCAAiC,CAAC,CAAC,CAAC;QAC/K,CAAC;aAAM,IAAI,UAAU,CAAC,QAAQ,CAAC,UAAU,CAAC,IAAI,UAAU,CAAC,QAAQ,CAAC,MAAM,CAAC,EAAE,CAAC;YAC1E,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,IAAI,CAAC,IAAI,EAAE,sBAAsB,IAAI,CAAC,IAAI,wFAAwF,CAAC,CAAC,CAAC;QAChK,CAAC;IACH,CAAC;IACD,OAAO,QAAQ,CAAC,IAAI,EAAE,QAAQ,EAAE,WAAW,MAAM,CAAC,aAAa,CAAC,MAAM,EAAE,gBAAgB,CAAC,mEAAmE,CAAC,CAAC;AAChK,CAAC","sourcesContent":["/**\n * C7: the thank-you page (Site System v2 §13.2, CONV §14 item 10).\n *\n * After an accepted enquiry the visitor lands on a page that says when they will hear back, offers a `tel:` link for\n * anything urgent, and keeps itself out of search (`noindex, follow`) so it never ranks and never counts as a lead.\n * The library's `ThankYou` block and `thankYouMetadata()` do all three. A site with a quote form but no thank-you page\n * among the sampled pages fails: the form has nowhere to send an accepted enquiry.\n */\nimport type { SiteSystemFinding } from \"../../checks.js\";\nimport { fail, notApplicable, plural, resultOf, type ParsedPage } from \"../enquiry/common.js\";\nimport { isQuoteForm } from \"../enquiry/c2-quote-form.js\";\nimport { attr, descendants, textOf, type HtmlElement } from \"../enquiry/html.js\";\nimport { byHook, isThankYouPath, mainOf } from \"../library/common.js\";\n\nconst NUMBER = String.raw`(?:(?:a\\s+)?(?:few|couple(?:\\s+of)?|half(?:\\s+an)?)|one|two|three|four|five|six|seven|eight|nine|ten|twelve|an?|\\d+)`;\nconst UNIT = String.raw`(?:minutes?|mins?|hours?|hrs?|business\\s+days?|working\\s+days?|days?)`;\n\n/** A sentence that says how soon the business replies: \"within one business day\", \"in 1 to 2 hours\", \"within the hour\". */\nexport const C7_REPLY_TIME = new RegExp(\n [\n String.raw`\\b(?:within|in|inside|under)\\s+(?:the\\s+)?(?:next\\s+)?${NUMBER}(?:\\s*(?:-|–|to|or)\\s*${NUMBER})?\\s+${UNIT}\\b`,\n String.raw`\\b(?:within|in|inside|under)\\s+(?:the\\s+)?(?:next\\s+)?(?:hour|day)\\b`,\n String.raw`\\b(?:within|during|in)\\s+(?:our\\s+)?(?:normal\\s+)?(?:business|working|office)\\s+hours\\b`,\n String.raw`\\b(?:same|next)(?:[-\\s]+business)?[-\\s]+day\\b`,\n String.raw`\\bby\\s+(?:the\\s+)?end\\s+of\\s+(?:the\\s+)?(?:business\\s+)?day\\b`,\n ].join(\"|\"),\n \"i\",\n);\n\n/**\n * The robots directives of a page, from every `<meta name=\"robots\">` tag. A `googlebot` tag alone does not count: it\n * leaves Bing and every other crawler free to index the page, which is why `thankYouMetadata()` writes both.\n */\nexport function robotsDirectives(root: HtmlElement): string[] {\n return descendants(root)\n .filter((element) => element.tag === \"meta\" && (attr(element, \"name\") ?? \"\").toLowerCase() === \"robots\")\n .flatMap((element) => (attr(element, \"content\") ?? \"\").toLowerCase().split(/[,\\s]+/))\n .filter(Boolean);\n}\n\nfunction hasQuoteForm(page: ParsedPage): boolean {\n return descendants(page.root).some((element) => element.tag === \"form\" && isQuoteForm(element));\n}\n\nfunction telLinks(scope: HtmlElement): HtmlElement[] {\n return descendants(scope).filter((element) => element.tag === \"a\" && (attr(element, \"href\") ?? \"\").trim().toLowerCase().startsWith(\"tel:\"));\n}\n\nfunction isThankYouPage(page: ParsedPage): boolean {\n return isThankYouPath(page.path) || byHook(page.root, \"thank-you\").length > 0;\n}\n\nexport function checkC7(pages: readonly ParsedPage[], missing: readonly string[] = []): SiteSystemFinding[] {\n const thankYouPages = pages.filter(isThankYouPage);\n if (thankYouPages.length === 0) {\n const named = missing.find((path) => isThankYouPath(path));\n if (named !== undefined) {\n return [fail(\"C7\", named, `The thank-you page ${named} could not be read, so its reply time, call link and noindex were not checked.`)];\n }\n if (!pages.some(hasQuoteForm)) return [notApplicable(\"C7\", \"None of the sampled pages has a quote form or a thank-you page.\")];\n return [fail(\"C7\", undefined, \"The site has a quote form but no thank-you page for an accepted enquiry to open.\")];\n }\n\n const failures: SiteSystemFinding[] = [];\n for (const page of thankYouPages) {\n const block = byHook(page.root, \"thank-you\")[0];\n const scope = block ?? mainOf(page.root);\n const reply = descendants(scope).find((element) => attr(element, \"data-slot\") === \"reply\");\n const replyText = reply ? textOf(reply) : textOf(scope);\n if (!C7_REPLY_TIME.test(replyText)) {\n failures.push(fail(\"C7\", page.path, `The thank-you page ${page.path} does not say when the business will reply (for example \"within one business day\").`));\n }\n if (telLinks(scope).length === 0) {\n failures.push(fail(\"C7\", page.path, `The thank-you page ${page.path} has no tel: link for anything urgent.`));\n }\n const directives = robotsDirectives(page.root);\n if (!directives.includes(\"noindex\") && !directives.includes(\"none\")) {\n failures.push(fail(\"C7\", page.path, `The thank-you page ${page.path} is not noindex; it carries robots \"${directives.join(\", \") || \"none\"}\" instead of \"noindex, follow\".`));\n } else if (directives.includes(\"nofollow\") || directives.includes(\"none\")) {\n failures.push(fail(\"C7\", page.path, `The thank-you page ${page.path} is noindex but also nofollow; its links should still be followed (\"noindex, follow\").`));\n }\n }\n return resultOf(\"C7\", failures, `Checked ${plural(thankYouPages.length, \"thank-you page\")}: each gives a reply time and a tel: link and is noindex, follow.`);\n}\n"]}
|
|
1
|
+
{"version":3,"file":"c7-thank-you.js","sourceRoot":"","sources":["../../../../src/site-system/rules/form/c7-thank-you.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * C7: the thank-you page (Site System v2 §13.2, CONV §14 item 10).\n *\n * After an accepted enquiry the visitor lands on a page that says when they will hear back, offers a `tel:` link for\n * anything urgent, and keeps itself out of search (`noindex, follow`) so it never ranks and never counts as a lead.\n * The library's `ThankYou` block and `thankYouMetadata()` do all three. A site with a quote form but no thank-you page\n * among the sampled pages fails: the form has nowhere to send an accepted enquiry.\n *\n * A site whose owner decided to promise no reply time records it in `siteSystem.replyTime` (3.15.0): the page then\n * carries the recorded wording instead of a time, and must not promise a time anyway. Without the record, vague\n * words such as \"shortly\" or \"as soon as we can\" still fail.\n */\nimport type { SiteSystemFinding } from \"../../checks.js\";\nimport type { SiteSystemReplyTime } from \"../../config.js\";\nimport { fail, notApplicable, plural, resultOf, type ParsedPage } from \"../enquiry/common.js\";\nimport { isQuoteForm } from \"../enquiry/c2-quote-form.js\";\nimport { attr, descendants, textOf, type HtmlElement } from \"../enquiry/html.js\";\nimport { byHook, isThankYouPath, mainOf } from \"../library/common.js\";\n\nconst NUMBER = String.raw`(?:(?:a\\s+)?(?:few|couple(?:\\s+of)?|half(?:\\s+an)?)|one|two|three|four|five|six|seven|eight|nine|ten|twelve|an?|\\d+)`;\nconst UNIT = String.raw`(?:minutes?|mins?|hours?|hrs?|business\\s+days?|working\\s+days?|days?)`;\n\n/** A sentence that says how soon the business replies: \"within one business day\", \"in 1 to 2 hours\", \"within the hour\". */\nexport const C7_REPLY_TIME = new RegExp(\n [\n String.raw`\\b(?:within|in|inside|under)\\s+(?:the\\s+)?(?:next\\s+)?${NUMBER}(?:\\s*(?:-|–|to|or)\\s*${NUMBER})?\\s+${UNIT}\\b`,\n String.raw`\\b(?:within|in|inside|under)\\s+(?:the\\s+)?(?:next\\s+)?(?:hour|day)\\b`,\n String.raw`\\b(?:within|during|in)\\s+(?:our\\s+)?(?:normal\\s+)?(?:business|working|office)\\s+hours\\b`,\n String.raw`\\b(?:same|next)(?:[-\\s]+business)?[-\\s]+day\\b`,\n String.raw`\\bby\\s+(?:the\\s+)?end\\s+of\\s+(?:the\\s+)?(?:business\\s+)?day\\b`,\n ].join(\"|\"),\n \"i\",\n);\n\n/**\n * The robots directives of a page, from every `<meta name=\"robots\">` tag. A `googlebot` tag alone does not count: it\n * leaves Bing and every other crawler free to index the page, which is why `thankYouMetadata()` writes both.\n */\nexport function robotsDirectives(root: HtmlElement): string[] {\n return descendants(root)\n .filter((element) => element.tag === \"meta\" && (attr(element, \"name\") ?? \"\").toLowerCase() === \"robots\")\n .flatMap((element) => (attr(element, \"content\") ?? \"\").toLowerCase().split(/[,\\s]+/))\n .filter(Boolean);\n}\n\nfunction hasQuoteForm(page: ParsedPage): boolean {\n return descendants(page.root).some((element) => element.tag === \"form\" && isQuoteForm(element));\n}\n\nfunction telLinks(scope: HtmlElement): HtmlElement[] {\n return descendants(scope).filter((element) => element.tag === \"a\" && (attr(element, \"href\") ?? \"\").trim().toLowerCase().startsWith(\"tel:\"));\n}\n\nfunction isThankYouPage(page: ParsedPage): boolean {\n return isThankYouPath(page.path) || byHook(page.root, \"thank-you\").length > 0;\n}\n\n/** Lower case, curly quotes straightened, apostrophes dropped, other punctuation and runs of space as one space. */\nfunction normalised(text: string): string {\n return text\n .toLowerCase()\n .replace(/[\\u2018\\u2019']/g, \"\")\n .replace(/[^\\p{L}\\p{N}]+/gu, \" \")\n .trim();\n}\n\ntype NoPromise = Extract<SiteSystemReplyTime, { promise: false }>;\n\nfunction decision(record: NoPromise): string {\n return record.decidedBy === \"owner\" ? `the owner recorded on ${record.decidedOn}` : `Romie recorded for the owner on ${record.decidedOn}`;\n}\n\n/** C7 over the sampled pages. `replyTime` is the site's `siteSystem.replyTime` record, when it has one. */\nexport function checkC7(pages: readonly ParsedPage[], missing: readonly string[] = [], replyTime: SiteSystemReplyTime | null = null): SiteSystemFinding[] {\n const noPromise = replyTime?.promise === false ? replyTime : null;\n const thankYouPages = pages.filter(isThankYouPage);\n if (thankYouPages.length === 0) {\n const named = missing.find((path) => isThankYouPath(path));\n if (named !== undefined) {\n return [fail(\"C7\", named, `The thank-you page ${named} could not be read, so its reply time, call link and noindex were not checked.`)];\n }\n if (!pages.some(hasQuoteForm)) return [notApplicable(\"C7\", \"None of the sampled pages has a quote form or a thank-you page.\")];\n return [fail(\"C7\", undefined, \"The site has a quote form but no thank-you page for an accepted enquiry to open.\")];\n }\n\n const failures: SiteSystemFinding[] = [];\n for (const page of thankYouPages) {\n const block = byHook(page.root, \"thank-you\")[0];\n const scope = block ?? mainOf(page.root);\n const reply = descendants(scope).find((element) => attr(element, \"data-slot\") === \"reply\");\n const replyText = reply ? textOf(reply) : textOf(scope);\n if (noPromise) {\n if (!` ${normalised(replyText)} `.includes(` ${normalised(noPromise.wording)} `)) {\n failures.push(fail(\"C7\", page.path, `The thank-you page ${page.path} does not use the reply wording ${decision(noPromise)} (\"${noPromise.wording}\").`));\n } else if (C7_REPLY_TIME.test(replyText)) {\n const by = noPromise.decidedBy === \"owner\" ? \"the owner\" : \"Romie, for the owner,\";\n failures.push(fail(\"C7\", page.path, `The thank-you page ${page.path} promises a reply time although ${by} decided on ${noPromise.decidedOn} to promise none; use \"${noPromise.wording}\".`));\n }\n } else if (!C7_REPLY_TIME.test(replyText)) {\n failures.push(fail(\"C7\", page.path, `The thank-you page ${page.path} does not say when the business will reply (for example \"within one business day\").`));\n }\n if (telLinks(scope).length === 0) {\n failures.push(fail(\"C7\", page.path, `The thank-you page ${page.path} has no tel: link for anything urgent.`));\n }\n const directives = robotsDirectives(page.root);\n if (!directives.includes(\"noindex\") && !directives.includes(\"none\")) {\n failures.push(fail(\"C7\", page.path, `The thank-you page ${page.path} is not noindex; it carries robots \"${directives.join(\", \") || \"none\"}\" instead of \"noindex, follow\".`));\n } else if (directives.includes(\"nofollow\") || directives.includes(\"none\")) {\n failures.push(fail(\"C7\", page.path, `The thank-you page ${page.path} is noindex but also nofollow; its links should still be followed (\"noindex, follow\").`));\n }\n }\n const reply = noPromise ? `the reply wording ${decision(noPromise)} instead of a reply time (\"${noPromise.wording}\")` : \"a reply time\";\n return resultOf(\"C7\", failures, `Checked ${plural(thankYouPages.length, \"thank-you page\")}: each gives ${reply} and a tel: link and is noindex, follow.`);\n}\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/site-system/rules/form/index.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,iBAAiB,CAAC;AAEzD,OAAO,KAAK,EAAE,uBAAuB,EAAE,MAAM,kBAAkB,CAAC;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/site-system/rules/form/index.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,iBAAiB,CAAC;AAEzD,OAAO,KAAK,EAAE,uBAAuB,EAAE,MAAM,kBAAkB,CAAC;AAMhE,OAAO,EAAE,oBAAoB,EAAE,QAAQ,EAAE,MAAM,wBAAwB,CAAC;AACxE,OAAO,EAAE,aAAa,EAAE,OAAO,EAAE,gBAAgB,EAAE,MAAM,mBAAmB,CAAC;AAC7E,OAAO,EAAE,gBAAgB,EAAE,OAAO,EAAE,YAAY,EAAE,kBAAkB,EAAE,MAAM,wBAAwB,CAAC;AAErG,2BAA2B;AAC3B,wBAAsB,YAAY,CAAC,KAAK,EAAE,IAAI,CAAC,uBAAuB,EAAE,SAAS,GAAG,OAAO,GAAG,aAAa,CAAC,GAAG;IAAE,QAAQ,CAAC,OAAO,CAAC,EAAE,SAAS,MAAM,EAAE,CAAA;CAAE,GAAG,OAAO,CAAC,SAAS,iBAAiB,EAAE,CAAC,CAG9L"}
|
|
@@ -2,12 +2,22 @@ import { parsePages } from "../enquiry/common.js";
|
|
|
2
2
|
import { checkC11 } from "./c11-contact-route.js";
|
|
3
3
|
import { checkC7 } from "./c7-thank-you.js";
|
|
4
4
|
import { checkC8 } from "./c8-forgiving-form.js";
|
|
5
|
+
import { readSiteSystemProjectConfig } from "../../config.js";
|
|
5
6
|
export { C11_ROUTE_CANDIDATES, checkC11 } from "./c11-contact-route.js";
|
|
6
7
|
export { C7_REPLY_TIME, checkC7, robotsDirectives } from "./c7-thank-you.js";
|
|
7
8
|
export { C8_PHONE_SAMPLES, checkC8, formProblems, phoneInputProblems } from "./c8-forgiving-form.js";
|
|
8
9
|
/** Runs C7, C8 and C11. */
|
|
9
10
|
export async function runFormRules(input) {
|
|
10
11
|
const pages = parsePages(input.pages);
|
|
11
|
-
return [...checkC7(pages, input.missing ?? []), ...checkC8(pages), ...checkC11(input.projectRoot, pages)];
|
|
12
|
+
return [...checkC7(pages, input.missing ?? [], recordedReplyTime(input.projectRoot)), ...checkC8(pages), ...checkC11(input.projectRoot, pages)];
|
|
13
|
+
}
|
|
14
|
+
/** The site's `siteSystem.replyTime` record; null when there is none or the config cannot be read (C7 then needs a time). */
|
|
15
|
+
function recordedReplyTime(projectRoot) {
|
|
16
|
+
try {
|
|
17
|
+
return readSiteSystemProjectConfig(projectRoot).siteSystem?.replyTime ?? null;
|
|
18
|
+
}
|
|
19
|
+
catch {
|
|
20
|
+
return null;
|
|
21
|
+
}
|
|
12
22
|
}
|
|
13
23
|
//# sourceMappingURL=index.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../src/site-system/rules/form/index.ts"],"names":[],"mappings":"AAKA,OAAO,EAAE,UAAU,EAAE,MAAM,sBAAsB,CAAC;AAElD,OAAO,EAAE,QAAQ,EAAE,MAAM,wBAAwB,CAAC;AAClD,OAAO,EAAE,OAAO,EAAE,MAAM,mBAAmB,CAAC;AAC5C,OAAO,EAAE,OAAO,EAAE,MAAM,wBAAwB,CAAC;
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../src/site-system/rules/form/index.ts"],"names":[],"mappings":"AAKA,OAAO,EAAE,UAAU,EAAE,MAAM,sBAAsB,CAAC;AAElD,OAAO,EAAE,QAAQ,EAAE,MAAM,wBAAwB,CAAC;AAClD,OAAO,EAAE,OAAO,EAAE,MAAM,mBAAmB,CAAC;AAC5C,OAAO,EAAE,OAAO,EAAE,MAAM,wBAAwB,CAAC;AACjD,OAAO,EAAE,2BAA2B,EAA4B,MAAM,iBAAiB,CAAC;AAExF,OAAO,EAAE,oBAAoB,EAAE,QAAQ,EAAE,MAAM,wBAAwB,CAAC;AACxE,OAAO,EAAE,aAAa,EAAE,OAAO,EAAE,gBAAgB,EAAE,MAAM,mBAAmB,CAAC;AAC7E,OAAO,EAAE,gBAAgB,EAAE,OAAO,EAAE,YAAY,EAAE,kBAAkB,EAAE,MAAM,wBAAwB,CAAC;AAErG,2BAA2B;AAC3B,MAAM,CAAC,KAAK,UAAU,YAAY,CAAC,KAAoH;IACrJ,MAAM,KAAK,GAAG,UAAU,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;IACtC,OAAO,CAAC,GAAG,OAAO,CAAC,KAAK,EAAE,KAAK,CAAC,OAAO,IAAI,EAAE,EAAE,iBAAiB,CAAC,KAAK,CAAC,WAAW,CAAC,CAAC,EAAE,GAAG,OAAO,CAAC,KAAK,CAAC,EAAE,GAAG,QAAQ,CAAC,KAAK,CAAC,WAAW,EAAE,KAAK,CAAC,CAAC,CAAC;AAClJ,CAAC;AAED,6HAA6H;AAC7H,SAAS,iBAAiB,CAAC,WAAmB;IAC5C,IAAI,CAAC;QACH,OAAO,2BAA2B,CAAC,WAAW,CAAC,CAAC,UAAU,EAAE,SAAS,IAAI,IAAI,CAAC;IAChF,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,IAAI,CAAC;IACd,CAAC;AACH,CAAC","sourcesContent":["/**\n * The form rule module (release 3.10.0): C7 the thank-you page, C8 the forgiving form and C11 the contact route's\n * protections. C7 and C8 read the sampled pages' server HTML; C11 reads the project's `/api/contact` route.\n */\nimport type { SiteSystemFinding } from \"../../checks.js\";\nimport { parsePages } from \"../enquiry/common.js\";\nimport type { SiteSystemRenderedInput } from \"../../runners.js\";\nimport { checkC11 } from \"./c11-contact-route.js\";\nimport { checkC7 } from \"./c7-thank-you.js\";\nimport { checkC8 } from \"./c8-forgiving-form.js\";\nimport { readSiteSystemProjectConfig, type SiteSystemReplyTime } from \"../../config.js\";\n\nexport { C11_ROUTE_CANDIDATES, checkC11 } from \"./c11-contact-route.js\";\nexport { C7_REPLY_TIME, checkC7, robotsDirectives } from \"./c7-thank-you.js\";\nexport { C8_PHONE_SAMPLES, checkC8, formProblems, phoneInputProblems } from \"./c8-forgiving-form.js\";\n\n/** Runs C7, C8 and C11. */\nexport async function runFormRules(input: Pick<SiteSystemRenderedInput, \"baseUrl\" | \"pages\" | \"projectRoot\"> & { readonly missing?: readonly string[] }): Promise<readonly SiteSystemFinding[]> {\n const pages = parsePages(input.pages);\n return [...checkC7(pages, input.missing ?? [], recordedReplyTime(input.projectRoot)), ...checkC8(pages), ...checkC11(input.projectRoot, pages)];\n}\n\n/** The site's `siteSystem.replyTime` record; null when there is none or the config cannot be read (C7 then needs a time). */\nfunction recordedReplyTime(projectRoot: string): SiteSystemReplyTime | null {\n try {\n return readSiteSystemProjectConfig(projectRoot).siteSystem?.replyTime ?? null;\n } catch {\n return null;\n }\n}\n"]}
|
|
@@ -12,6 +12,8 @@ export interface FullContext {
|
|
|
12
12
|
readonly geographyProblem: string;
|
|
13
13
|
readonly strategy: FullStrategy;
|
|
14
14
|
readonly projectRoot: string;
|
|
15
|
+
/** Path → kind for the route catalogue's literal entries (`src/data/routes.ts`); absent or empty when unread. */
|
|
16
|
+
readonly catalogueKinds?: ReadonlyMap<string, string>;
|
|
15
17
|
/** Estate families brandlab.config.ts allows to refresh more often than weekly (W3); absent when none. */
|
|
16
18
|
readonly refreshExceptions?: readonly SiteSystemRefreshException[];
|
|
17
19
|
/** Today in Sydney, YYYY-MM-DD: the day waves are judged on. */
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"common.d.ts","sourceRoot":"","sources":["../../../../src/site-system/rules/full/common.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,iBAAiB,EAAE,iBAAiB,EAAE,MAAM,iBAAiB,CAAC;AAE5E,OAAO,KAAK,EAAE,0BAA0B,EAAE,MAAM,iBAAiB,CAAC;AAClE,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AAC1C,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,gBAAgB,CAAC;AACpD,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,eAAe,CAAC;AAElD,OAAO,EAAE,IAAI,EAAE,aAAa,EAAE,IAAI,EAAE,MAAM,EAAE,MAAM,sBAAsB,CAAC;AAEzE,yCAAyC;AACzC,MAAM,WAAW,WAAW;IAC1B,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,0FAA0F;IAC1F,QAAQ,CAAC,SAAS,EAAE,aAAa,GAAG,IAAI,CAAC;IACzC,QAAQ,CAAC,gBAAgB,EAAE,MAAM,CAAC;IAClC,QAAQ,CAAC,QAAQ,EAAE,YAAY,CAAC;IAChC,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IAC7B,0GAA0G;IAC1G,QAAQ,CAAC,iBAAiB,CAAC,EAAE,SAAS,0BAA0B,EAAE,CAAC;IACnE,gEAAgE;IAChE,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,wHAAwH;IACxH,QAAQ,CAAC,YAAY,EACjB,CAAC,CAAC,MAAM,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,MAAM,KAAK;QAAE,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;QAAC,QAAQ,CAAC,OAAO,EAAE,SAAS;YAAE,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAC;YAAC,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAA;SAAE,EAAE,CAAA;KAAE,GAAG,SAAS,CAAC,GAC9J,MAAM,CAAC;CACZ;AAED,4FAA4F;AAC5F,eAAO,MAAM,oBAAoB,KAAK,CAAC;AAEvC,4FAA4F;AAC5F,wBAAgB,OAAO,CAAC,OAAO,EAAE,iBAAiB,EAAE,QAAQ,EAAE,SAAS,iBAAiB,EAAE,EAAE,WAAW,EAAE,MAAM,GAAG,iBAAiB,EAAE,CAkBpI;AAED,sFAAsF;AACtF,wBAAgB,OAAO,CAAC,OAAO,EAAE,iBAAiB,EAAE,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,iBAAiB,CAEtG;AAED,2HAA2H;AAC3H,wBAAgB,UAAU,CAAC,OAAO,EAAE,iBAAiB,EAAE,MAAM,EAAE,MAAM,GAAG,iBAAiB,GAAG,IAAI,CAG/F;AAED,oBAAoB;AACpB,wBAAgB,MAAM,CAAC,KAAK,EAAE,SAAS,MAAM,EAAE,EAAE,KAAK,SAAI,GAAG,MAAM,CAKlE;AAED,mEAAmE;AACnE,eAAO,MAAM,aAAa,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAI1D,CAAC"}
|
|
1
|
+
{"version":3,"file":"common.d.ts","sourceRoot":"","sources":["../../../../src/site-system/rules/full/common.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,iBAAiB,EAAE,iBAAiB,EAAE,MAAM,iBAAiB,CAAC;AAE5E,OAAO,KAAK,EAAE,0BAA0B,EAAE,MAAM,iBAAiB,CAAC;AAClE,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AAC1C,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,gBAAgB,CAAC;AACpD,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,eAAe,CAAC;AAElD,OAAO,EAAE,IAAI,EAAE,aAAa,EAAE,IAAI,EAAE,MAAM,EAAE,MAAM,sBAAsB,CAAC;AAEzE,yCAAyC;AACzC,MAAM,WAAW,WAAW;IAC1B,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,0FAA0F;IAC1F,QAAQ,CAAC,SAAS,EAAE,aAAa,GAAG,IAAI,CAAC;IACzC,QAAQ,CAAC,gBAAgB,EAAE,MAAM,CAAC;IAClC,QAAQ,CAAC,QAAQ,EAAE,YAAY,CAAC;IAChC,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IAC7B,iHAAiH;IACjH,QAAQ,CAAC,cAAc,CAAC,EAAE,WAAW,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACtD,0GAA0G;IAC1G,QAAQ,CAAC,iBAAiB,CAAC,EAAE,SAAS,0BAA0B,EAAE,CAAC;IACnE,gEAAgE;IAChE,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,wHAAwH;IACxH,QAAQ,CAAC,YAAY,EACjB,CAAC,CAAC,MAAM,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,MAAM,KAAK;QAAE,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;QAAC,QAAQ,CAAC,OAAO,EAAE,SAAS;YAAE,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAC;YAAC,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAA;SAAE,EAAE,CAAA;KAAE,GAAG,SAAS,CAAC,GAC9J,MAAM,CAAC;CACZ;AAED,4FAA4F;AAC5F,eAAO,MAAM,oBAAoB,KAAK,CAAC;AAEvC,4FAA4F;AAC5F,wBAAgB,OAAO,CAAC,OAAO,EAAE,iBAAiB,EAAE,QAAQ,EAAE,SAAS,iBAAiB,EAAE,EAAE,WAAW,EAAE,MAAM,GAAG,iBAAiB,EAAE,CAkBpI;AAED,sFAAsF;AACtF,wBAAgB,OAAO,CAAC,OAAO,EAAE,iBAAiB,EAAE,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,iBAAiB,CAEtG;AAED,2HAA2H;AAC3H,wBAAgB,UAAU,CAAC,OAAO,EAAE,iBAAiB,EAAE,MAAM,EAAE,MAAM,GAAG,iBAAiB,GAAG,IAAI,CAG/F;AAED,oBAAoB;AACpB,wBAAgB,MAAM,CAAC,KAAK,EAAE,SAAS,MAAM,EAAE,EAAE,KAAK,SAAI,GAAG,MAAM,CAKlE;AAED,mEAAmE;AACnE,eAAO,MAAM,aAAa,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAI1D,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"common.js","sourceRoot":"","sources":["../../../../src/site-system/rules/full/common.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,IAAI,EAAE,IAAI,EAAE,MAAM,sBAAsB,CAAC;AAMlD,OAAO,EAAE,IAAI,EAAE,aAAa,EAAE,IAAI,EAAE,MAAM,EAAE,MAAM,sBAAsB,CAAC;
|
|
1
|
+
{"version":3,"file":"common.js","sourceRoot":"","sources":["../../../../src/site-system/rules/full/common.ts"],"names":[],"mappings":"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","sourcesContent":["import type { SiteSystemCheckId, SiteSystemFinding } from \"../../checks.js\";\nimport { fail, pass } from \"../enquiry/common.js\";\nimport type { SiteSystemRefreshException } from \"../../config.js\";\nimport type { Estate } from \"./estate.js\";\nimport type { FullGeography } from \"./geography.js\";\nimport type { FullStrategy } from \"./strategy.js\";\n\nexport { fail, notApplicable, pass, plural } from \"../enquiry/common.js\";\n\n/** Everything a full-tier rule reads. */\nexport interface FullContext {\n readonly estate: Estate;\n /** Null when the site-core geography could not be loaded; `geographyProblem` says why. */\n readonly geography: FullGeography | null;\n readonly geographyProblem: string;\n readonly strategy: FullStrategy;\n readonly projectRoot: string;\n /** Path → kind for the route catalogue's literal entries (`src/data/routes.ts`); absent or empty when unread. */\n readonly catalogueKinds?: ReadonlyMap<string, string>;\n /** Estate families brandlab.config.ts allows to refresh more often than weekly (W3); absent when none. */\n readonly refreshExceptions?: readonly SiteSystemRefreshException[];\n /** Today in Sydney, YYYY-MM-DD: the day waves are judged on. */\n readonly today: string;\n /** A family's canonical sections and cap (site-core `defaultSectionOrder`), or a string saying why they are unknown. */\n readonly defaultOrder:\n | ((family: string, trade?: string) => { readonly cap: number; readonly entries: readonly { readonly id: string; readonly requirement: string }[] } | undefined)\n | string;\n}\n\n/** The most failures one check lists one by one; the rest are counted in a last finding. */\nexport const FULL_LISTED_FAILURES = 25;\n\n/** The failures (at most `FULL_LISTED_FAILURES`, then a count of the rest), or one pass. */\nexport function outcome(checkId: SiteSystemCheckId, failures: readonly SiteSystemFinding[], passMessage: string): SiteSystemFinding[] {\n const failed = failures.filter((finding) => finding.status === \"fail\");\n const allWarnings = failures.filter((finding) => finding.status !== \"fail\");\n const warnings = allWarnings.length <= FULL_LISTED_FAILURES\n ? allWarnings\n : [\n ...allWarnings.slice(0, FULL_LISTED_FAILURES),\n { checkId, status: \"pass\" as const, severity: \"warning\" as const, message: `${allWarnings.length - FULL_LISTED_FAILURES} more warnings of the same kind.` },\n ];\n if (failed.length === 0) return [...warnings, pass(checkId, passMessage)];\n if (failed.length <= FULL_LISTED_FAILURES) return [...failed, ...warnings];\n const rest = failed.slice(FULL_LISTED_FAILURES);\n const examples = [...new Set(rest.flatMap((finding) => finding.target ?? []))].slice(0, 3);\n return [\n ...failed.slice(0, FULL_LISTED_FAILURES),\n fail(checkId, undefined, `${rest.length} more ${rest.length === 1 ? \"problem\" : \"problems\"} of the same kind${examples.length > 0 ? `, for example on ${examples.join(\", \")}` : \"\"}.`),\n ...warnings,\n ];\n}\n\n/** A finding that never blocks: the check passes and the report shows the warning. */\nexport function warning(checkId: SiteSystemCheckId, target: string, message: string): SiteSystemFinding {\n return { checkId, status: \"pass\", target, message, severity: \"warning\" };\n}\n\n/** The estate-wide checks need the whole build, not a sample: without it they fail, so the gate never passes unchecked. */\nexport function needsBuild(checkId: SiteSystemCheckId, estate: Estate): SiteSystemFinding | null {\n if (estate.complete) return null;\n return fail(checkId, undefined, \"The production build could not be read (no .next/prerender-manifest.json), so the whole estate could not be checked; run next build first.\");\n}\n\n/** \"a, b and c\". */\nexport function listOf(items: readonly string[], limit = 4): string {\n const shown = items.slice(0, limit);\n const more = items.length - shown.length;\n if (more > 0) return `${shown.join(\", \")} and ${more} more`;\n return shown.length <= 1 ? shown.join(\"\") : `${shown.slice(0, -1).join(\", \")} and ${shown.at(-1)}`;\n}\n\n/** \"the suburb page /locations/ryde\" style labels for a family. */\nexport const FAMILY_LABELS: Readonly<Record<string, string>> = {\n suburb: \"suburb page\",\n \"service-in-suburb\": \"service-in-suburb page\",\n region: \"region page\",\n};\n"]}
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import type { SiteSystemPage } from "../../samples.js";
|
|
2
|
+
import type { SiteEstatePaths } from "@brandlab-digital/site-core/strategy";
|
|
2
3
|
import { type FullGeography, type PathAliases, type PathPlace } from "./geography.js";
|
|
3
4
|
/** The section manifest as SectionSequence writes it (site-core `BrandlabSectionManifest`). */
|
|
4
5
|
export interface ManifestData {
|
|
@@ -53,7 +54,7 @@ export interface LocationCopy {
|
|
|
53
54
|
readonly answer: string;
|
|
54
55
|
}[];
|
|
55
56
|
/** The job cards of the nearby-jobs section; null when the page has none. */
|
|
56
|
-
readonly jobs: readonly
|
|
57
|
+
readonly jobs: readonly LocationJobCard[] | null;
|
|
57
58
|
/** The price-guide section's text; null when the page has none. */
|
|
58
59
|
readonly prices: string | null;
|
|
59
60
|
readonly reviews: {
|
|
@@ -68,6 +69,11 @@ export interface LocationCopy {
|
|
|
68
69
|
readonly telLink: boolean;
|
|
69
70
|
readonly callBar: boolean;
|
|
70
71
|
}
|
|
72
|
+
/** A nearby-job card: its text, and the job's suburb slug from the card's `data-suburb` (NearbyJobs) when it carries one. */
|
|
73
|
+
export interface LocationJobCard {
|
|
74
|
+
readonly text: string;
|
|
75
|
+
readonly place?: string;
|
|
76
|
+
}
|
|
71
77
|
export interface EstatePage {
|
|
72
78
|
readonly path: string;
|
|
73
79
|
/** The app route Next built the page from (`/locations/[suburb]`), when known. */
|
|
@@ -101,7 +107,7 @@ export interface EstatePage {
|
|
|
101
107
|
readonly title?: string;
|
|
102
108
|
readonly place: PathPlace | undefined;
|
|
103
109
|
family: string | undefined;
|
|
104
|
-
familySource: "manifest" | "sitemap" | "route" | "stem" | "path" | undefined;
|
|
110
|
+
familySource: "manifest" | "plan" | "sitemap" | "route" | "stem" | "path" | undefined;
|
|
105
111
|
copy: LocationCopy | undefined;
|
|
106
112
|
}
|
|
107
113
|
export interface Estate {
|
|
@@ -131,6 +137,8 @@ export declare function readEstate(input: {
|
|
|
131
137
|
readonly seeds?: Readonly<Record<string, string>>;
|
|
132
138
|
/** The estate plan's public slugs (3.14.0). */
|
|
133
139
|
readonly aliases?: PathAliases;
|
|
140
|
+
/** The estate plan's family paths (3.14.0): they type region, suburb and service-in-suburb pages without a manifest. */
|
|
141
|
+
readonly paths?: SiteEstatePaths;
|
|
134
142
|
}): Estate;
|
|
135
143
|
/** An internal link's normalised path, or null for other sites, anchors on the same page, mail and phone links. */
|
|
136
144
|
export declare function internalPath(href: string, from: string, hosts: ReadonlySet<string>): string | null;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"estate.d.ts","sourceRoot":"","sources":["../../../../src/site-system/rules/full/estate.ts"],"names":[],"mappings":"AAeA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAC;AAIvD,OAAO,EAAe,KAAK,aAAa,EAAE,KAAK,WAAW,EAAE,KAAK,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAEnG,+FAA+F;AAC/F,MAAM,WAAW,YAAY;IAC3B,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,IAAI,CAAC,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;IACrB,QAAQ,CAAC,KAAK,EAAE,SAAS,GAAG,UAAU,CAAC;IACvC,QAAQ,CAAC,OAAO,EAAE,SAAS;QAAE,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAC;QAAC,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAA;KAAE,EAAE,CAAC;IACnF,QAAQ,CAAC,QAAQ,EAAE,SAAS;QAAE,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAC;QAAC,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;QAAC,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;QAAC,QAAQ,CAAC,IAAI,CAAC,EAAE,MAAM,CAAA;KAAE,EAAE,CAAC;IACtI,QAAQ,CAAC,OAAO,EAAE,SAAS;QAAE,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAC;QAAC,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;QAAC,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;QAAC,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAA;KAAE,EAAE,CAAC;IACtI,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,KAAK,EAAE,SAAS,MAAM,EAAE,CAAC;CACnC;AAED,MAAM,MAAM,aAAa,GACrB;IAAE,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;CAAE,GACzB;IAAE,QAAQ,CAAC,IAAI,EAAE,SAAS,CAAC;IAAC,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAA;CAAE,GACrD;IAAE,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAA;CAAE,GACjD;IAAE,QAAQ,CAAC,IAAI,EAAE,KAAK,CAAC;IAAC,QAAQ,CAAC,QAAQ,EAAE,YAAY,CAAA;CAAE,CAAC;AAE9D,eAAO,MAAM,iBAAiB,oDAAqD,CAAC;AACpF,MAAM,MAAM,cAAc,GAAG,CAAC,OAAO,iBAAiB,CAAC,CAAC,MAAM,CAAC,CAAC;AAEhE,wBAAgB,gBAAgB,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,GAAG,MAAM,IAAI,cAAc,CAErF;AAED,2EAA2E;AAC3E,MAAM,WAAW,YAAY;IAC3B,qGAAqG;IACrG,QAAQ,CAAC,KAAK,EAAE,SAAS;QAAE,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;QAAC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;KAAE,EAAE,CAAC;IAC/E,QAAQ,CAAC,IAAI,EAAE,SAAS;QAAE,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;QAAC,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAA;KAAE,EAAE,CAAC;IACjF,6EAA6E;IAC7E,QAAQ,CAAC,IAAI,EAAE,SAAS,
|
|
1
|
+
{"version":3,"file":"estate.d.ts","sourceRoot":"","sources":["../../../../src/site-system/rules/full/estate.ts"],"names":[],"mappings":"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"}
|