@weatherboard/cms 0.8.0 → 0.10.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +11 -5
- package/dist/contracts/facts.d.cts +163 -0
- package/dist/contracts/facts.d.mts +163 -0
- package/dist/contracts/facts.d.ts +163 -0
- package/dist/fact-guard.cjs +2 -0
- package/dist/fact-guard.cjs.map +7 -0
- package/dist/fact-guard.d.cts +19 -0
- package/dist/fact-guard.d.mts +19 -0
- package/dist/fact-guard.d.ts +19 -0
- package/dist/fact-guard.mjs +2 -0
- package/dist/fact-guard.mjs.map +7 -0
- package/dist/facts.cjs +2 -0
- package/dist/facts.cjs.map +7 -0
- package/dist/facts.d.cts +1 -0
- package/dist/facts.d.mts +1 -0
- package/dist/facts.d.ts +1 -0
- package/dist/facts.mjs +2 -0
- package/dist/facts.mjs.map +7 -0
- package/dist/next.cjs +4 -4
- package/dist/next.cjs.map +3 -3
- package/dist/next.mjs +4 -4
- package/dist/next.mjs.map +3 -3
- package/dist/runtime/site-readers.d.cts +7 -1
- package/dist/runtime/site-readers.d.mts +7 -1
- package/dist/runtime/site-readers.d.ts +7 -1
- package/dist/runtime/test-fixtures/saved-documents.d.cts +4 -0
- package/dist/runtime/test-fixtures/saved-documents.d.mts +4 -0
- package/dist/runtime/test-fixtures/saved-documents.d.ts +4 -0
- package/dist/server.cjs +3 -3
- package/dist/server.cjs.map +3 -3
- package/dist/server.mjs +2 -2
- package/dist/server.mjs.map +3 -3
- package/package.json +24 -2
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../src/facts.ts", "../src/contracts/facts.ts"],
|
|
4
|
+
"sourcesContent": ["// Dedicated entry reserved for the published snapshot reader; no runtime transport in this foundation.\nexport * from \"./contracts/facts.js\";\n", "/** Public contracts only. Evidence and approval identities never enter the CMS document. */\nexport const FACT_TYPES = [\"integer\", \"decimal\", \"boolean\", \"date\", \"string\", \"enum\", \"reference\"] as const;\nexport const FACT_DISPLAY_RULES = [\"identity/v1\", \"floorHundredsPlus/v1\"] as const;\nexport type FactDisplayRule = typeof FACT_DISPLAY_RULES[number];\nexport const FACT_KEY = /^[a-z][a-zA-Z0-9]*(?:\\.[a-zA-Z][a-zA-Z0-9]*)*$/;\nexport const FACT_ALIASES: Readonly<Record<string, string>> = { pubCount: \"coverage.pubCount\" };\nexport type FactValue =\n | { type: \"integer\"; value: number }\n // Decimal strings avoid binary floating-point loss; canonical form has no trailing fractional zeroes.\n | { type: \"decimal\"; value: string }\n | { type: \"boolean\"; value: boolean }\n | { type: \"date\" | \"string\"; value: string }\n | { type: \"enum\"; value: string; allowedValues: readonly string[] }\n | { type: \"reference\"; value: { documentId: string; documentRevision: string } };\nexport type FactSource = { kind: \"computed\" | \"observed\" | \"attested\"; definition: string; version: string };\nexport type BusinessFact = {\n key: string; publicValue: FactValue; unit: string | null; timezone: string | null;\n displayRule: FactDisplayRule; source: FactSource; accountableOwner: string;\n freshness: \"computed\" | \"operational\" | \"technical\"; optional: boolean;\n surfaces: readonly { id: string; semantics: \"current\" | \"historical\"; asOf: string | null }[];\n};\nexport const FACT_EXPIRY_MS = { computed: 72 * 3_600_000, operational: 30 * 86_400_000, technical: 90 * 86_400_000 } as const;\nexport type FactEvidence = { reference: string; digest: string; observedAt: string; expiresAt: string; complete: boolean; runId: string };\nexport type FactRevision = {\n projectId: string; revision: number; baseRevision: number | null; fact: BusinessFact;\n evidence: FactEvidence; effectiveAt: string; expiresAt: string;\n};\nexport type ApprovedFactRevision = FactRevision & {\n hash: string; approvedAt: string;\n approval: { kind: \"signer\"; signerId: string } | { kind: \"policy\"; policyVersion: string };\n};\nexport type FactPublicationReceipt = {\n intentId: string; projectId: string; revision: number; hash: string;\n destination: { projectId: string; dataset: string }; expectedDocumentRevision: string | null;\n cms: { transactionId: string; documentRevision: string; readBackHash: string; at: string } | null;\n invalidation: { deliveryKey: string; target: string; type: \"businessFact\"; id: string; at: string } | null;\n render: { url: string; deploymentId: string; revision: number; hash: string; at: string } | null;\n};\nexport type PublicBusinessFact = Pick<BusinessFact, \"key\" | \"publicValue\" | \"unit\" | \"timezone\" | \"displayRule\"> & {\n _type: \"businessFact\"; _id: string; approvedRevision: number; approvedHash: string;\n effectiveAt: string; expiresAt: string; provenanceSummary: string;\n};\n/** A request supplies one snapshot to every surface. Missing and unavailable are distinct from an empty snapshot. */\nexport type FactSnapshot = Readonly<Record<string, PublicBusinessFact>>;\nexport type FactReadResult = { status: \"available\"; snapshot: FactSnapshot } | { status: \"unavailable\"; reason: string };\nexport type FactReader = () => Promise<FactReadResult>;\nexport type FactPlaceholderContext = \"htmlText\" | \"htmlAttribute\" | \"json\";\n/** Stored Sanity projection: scalar unions use named slots, never private revision fields. */\nexport type StoredFactValue = { type: FactValue[\"type\"]; numberValue?: number; textValue?: string;\n booleanValue?: boolean; allowedValues?: readonly string[]; documentId?: string; documentRevision?: string };\nexport function parseStoredFactValue(input: unknown): FactValue {\n const entry = record(input);\n const value = entry.type === \"integer\" ? entry.numberValue : entry.type === \"boolean\" ? entry.booleanValue\n : entry.type === \"reference\" ? { documentId: entry.documentId, documentRevision: entry.documentRevision } : entry.textValue;\n return parseFactValue({ type: entry.type, value, allowedValues: entry.allowedValues });\n}\nexport function storeFactValue(input: FactValue): StoredFactValue {\n const entry = parseFactValue(input);\n if (entry.type === \"integer\") return { type: entry.type, numberValue: entry.value };\n if (entry.type === \"boolean\") return { type: entry.type, booleanValue: entry.value };\n if (entry.type === \"reference\") return { type: entry.type, ...entry.value };\n return entry.type === \"enum\" ? { type: entry.type, textValue: entry.value, allowedValues: entry.allowedValues }\n : { type: entry.type, textValue: entry.value };\n}\nexport type StoredBusinessFact = Omit<PublicBusinessFact, \"publicValue\"> & { publicValue: StoredFactValue };\n\nfunction invalid(): never { throw new Error(\"Invalid business fact contract\"); }\nfunction record(value: unknown): Record<string, unknown> {\n if (!value || typeof value !== \"object\" || Array.isArray(value)) return invalid();\n return value as Record<string, unknown>;\n}\nfunction text(value: unknown): string { return typeof value === \"string\" && value.trim() !== \"\" ? value : invalid(); }\nexport function assertFactKey(key: string): void {\n if (key.length > 48 || !FACT_KEY.test(key)) invalid();\n}\nexport function businessFactId(key: string): string {\n assertFactKey(key);\n // Dataset-local, injective encoding; never a draft ID or a key containing a path separator.\n return \"businessFact-\" + Array.from(new TextEncoder().encode(key), (byte) => byte.toString(16).padStart(2, \"0\")).join(\"\");\n}\nexport function parseFactValue(input: unknown): FactValue {\n const entry = record(input), value = entry.value;\n switch (entry.type) {\n case \"integer\": return Number.isSafeInteger(value) ? { type: \"integer\", value: value as number } : invalid();\n case \"decimal\": return typeof value === \"string\" && /^(?:0|-?[1-9]\\d*)(?:\\.\\d*[1-9])?$|^-0\\.\\d*[1-9]$/.test(value)\n ? { type: \"decimal\", value } : invalid();\n case \"boolean\": return typeof value === \"boolean\" ? { type: \"boolean\", value } : invalid();\n case \"string\": return typeof value === \"string\" ? { type: \"string\", value } : invalid();\n case \"date\": return typeof value === \"string\" && /^\\d{4}-\\d{2}-\\d{2}$/.test(value)\n && !Number.isNaN(Date.parse(value)) && new Date(value).toISOString().slice(0, 10) === value ? { type: \"date\", value } : invalid();\n case \"enum\": {\n const allowed = entry.allowedValues;\n if (!Array.isArray(allowed) || !allowed.length || !allowed.every((item) => typeof item === \"string\" && item !== \"\")\n || new Set(allowed).size !== allowed.length || !allowed.includes(value)) return invalid();\n return { type: \"enum\", value: text(value), allowedValues: [...allowed].sort() as string[] };\n }\n case \"reference\": {\n const ref = record(value);\n return { type: \"reference\", value: { documentId: text(ref.documentId), documentRevision: text(ref.documentRevision) } };\n }\n default: return invalid();\n }\n}\nexport function parseFactDisplayRule(input: unknown): FactDisplayRule {\n if (input !== \"identity/v1\" && input !== \"floorHundredsPlus/v1\") return invalid();\n return input;\n}\nexport function formatFact(input: FactValue, rule: FactDisplayRule): string {\n const value = parseFactValue(input);\n if (parseFactDisplayRule(rule) === \"floorHundredsPlus/v1\") {\n if (value.type !== \"integer\" || value.value < 0) return invalid();\n return value.value < 100 ? String(value.value) : `${(Math.floor(value.value / 100) * 100).toLocaleString(\"en-GB\")}+`;\n }\n return value.type === \"reference\" ? value.value.documentId : String(value.value);\n}\n/** Escape each replacement, not the surrounding trusted template. JSON returns string content without quotes;\n * callers serialize complete structured objects and keep numeric properties as exact values. Attributes must be quoted.\n * Raw text/React children use the formatter directly; never HTML-unescape an expanded string.\n */\nexport function expandFactPlaceholders(template: string, values: Readonly<Record<string, string>>, context: FactPlaceholderContext): string {\n if (![\"htmlText\", \"htmlAttribute\", \"json\"].includes(context)) return invalid();\n return template.replace(/\\{([^{}]*)\\}/g, (_match, key: string) => {\n assertFactKey(key);\n const resolved = Object.hasOwn(FACT_ALIASES, key) ? FACT_ALIASES[key]! : key;\n if (!Object.hasOwn(values, resolved)) throw new Error(`Unknown fact placeholder: ${key}`);\n const value = values[resolved]!;\n if (context === \"json\") return JSON.stringify(value).slice(1, -1)\n .replace(/</g, \"\\\\u003c\").replace(/>/g, \"\\\\u003e\").replace(/&/g, \"\\\\u0026\")\n .replace(/\\u2028/g, \"\\\\u2028\").replace(/\\u2029/g, \"\\\\u2029\");\n return value.replace(/[&<>\"']/g, (char) => ({ \"&\": \"&\", \"<\": \"<\", \">\": \">\", '\"': \""\", \"'\": \"'\" })[char]!);\n });\n}\n/** Fixed JSON domain, sorted object keys, array order preserved, finite numbers only. */\nexport function canonicalFactJson(value: unknown): string {\n if (value === null || typeof value === \"boolean\" || typeof value === \"string\") return JSON.stringify(value);\n if (typeof value === \"number\" && Number.isFinite(value)) return JSON.stringify(value);\n if (Array.isArray(value)) return `[${Array.from(value, canonicalFactJson).join(\",\")}]`;\n if (typeof value !== \"object\" || value === null || Object.getPrototypeOf(value) !== Object.prototype) return invalid();\n return `{${Object.entries(value).sort(([a], [b]) => a < b ? -1 : a > b ? 1 : 0)\n .map(([key, item]) => `${JSON.stringify(key)}:${canonicalFactJson(item)}`).join(\",\")}}`;\n}\n/** SHA-256 of contract fields only; unknown fields and approval are ignored. Instants use UTC milliseconds. */\nexport async function hashFactRevision(revision: FactRevision): Promise<string> {\n const fact = revision.fact;\n assertFactKey(fact.key);\n const publicValue = parseFactValue(fact.publicValue);\n formatFact(publicValue, fact.displayRule);\n if (!Number.isSafeInteger(revision.revision) || revision.revision < 1\n || (revision.baseRevision !== null && (!Number.isSafeInteger(revision.baseRevision) || revision.baseRevision < 1 || revision.baseRevision >= revision.revision))) invalid();\n text(revision.projectId); text(fact.accountableOwner); text(fact.source.definition); text(fact.source.version);\n if (![\"computed\", \"observed\", \"attested\"].includes(fact.source.kind) || !Object.hasOwn(FACT_EXPIRY_MS, fact.freshness)\n || typeof fact.optional !== \"boolean\" || (fact.unit !== null && typeof fact.unit !== \"string\")) invalid();\n if (fact.timezone !== null) new Intl.DateTimeFormat(\"en-GB\", { timeZone: text(fact.timezone) });\n const instant = (value: string) => {\n if (!/^\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}:\\d{2}(?:\\.\\d{3})?Z$/.test(value) || !Number.isFinite(Date.parse(value))\n || new Date(value).toISOString() !== value.replace(/(?<=:\\d{2})Z$/, \".000Z\")) invalid();\n return Date.parse(value);\n };\n if (instant(revision.expiresAt) <= instant(revision.effectiveAt)\n || instant(revision.evidence.expiresAt) <= instant(revision.evidence.observedAt)\n || !/^[0-9a-f]{64}$/.test(revision.evidence.digest) || typeof revision.evidence.complete !== \"boolean\") invalid();\n text(revision.evidence.reference); text(revision.evidence.runId);\n for (const surface of fact.surfaces) {\n text(surface.id);\n if (surface.semantics === \"historical\") parseFactValue({ type: \"date\", value: surface.asOf });\n else if (surface.semantics !== \"current\" || surface.asOf !== null) invalid();\n }\n const candidate: FactRevision = {\n projectId: revision.projectId, revision: revision.revision, baseRevision: revision.baseRevision,\n fact: {\n key: fact.key, publicValue, unit: fact.unit, timezone: fact.timezone, displayRule: fact.displayRule,\n source: { kind: fact.source.kind, definition: fact.source.definition, version: fact.source.version },\n accountableOwner: fact.accountableOwner, freshness: fact.freshness, optional: fact.optional,\n surfaces: fact.surfaces.map((surface) => ({ id: surface.id, semantics: surface.semantics, asOf: surface.asOf })),\n },\n evidence: {\n reference: revision.evidence.reference, digest: revision.evidence.digest, complete: revision.evidence.complete,\n runId: revision.evidence.runId, observedAt: new Date(instant(revision.evidence.observedAt)).toISOString(),\n expiresAt: new Date(instant(revision.evidence.expiresAt)).toISOString(),\n },\n effectiveAt: new Date(instant(revision.effectiveAt)).toISOString(),\n expiresAt: new Date(instant(revision.expiresAt)).toISOString(),\n };\n const digest = await crypto.subtle.digest(\"SHA-256\", new TextEncoder().encode(canonicalFactJson(candidate)));\n return Array.from(new Uint8Array(digest), (byte) => byte.toString(16).padStart(2, \"0\")).join(\"\");\n}\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
|
+
"names": ["facts_exports", "__export", "FACT_ALIASES", "FACT_DISPLAY_RULES", "FACT_EXPIRY_MS", "FACT_KEY", "FACT_TYPES", "assertFactKey", "businessFactId", "canonicalFactJson", "expandFactPlaceholders", "formatFact", "hashFactRevision", "parseFactDisplayRule", "parseFactValue", "parseStoredFactValue", "storeFactValue", "__toCommonJS", "FACT_TYPES", "FACT_DISPLAY_RULES", "FACT_KEY", "FACT_ALIASES", "FACT_EXPIRY_MS", "parseStoredFactValue", "input", "entry", "record", "value", "parseFactValue", "storeFactValue", "invalid", "text", "assertFactKey", "key", "businessFactId", "byte", "allowed", "item", "ref", "parseFactDisplayRule", "formatFact", "rule", "expandFactPlaceholders", "template", "values", "context", "_match", "resolved", "char", "canonicalFactJson", "a", "b", "hashFactRevision", "revision", "fact", "publicValue", "instant", "surface", "candidate", "digest"]
|
|
7
|
+
}
|
package/dist/facts.d.cts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from "./contracts/facts.cjs";
|
package/dist/facts.d.mts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from "./contracts/facts.mjs";
|
package/dist/facts.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from "./contracts/facts.js";
|
package/dist/facts.mjs
ADDED
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
var F=["integer","decimal","boolean","date","string","enum","reference"],x=["identity/v1","floorHundredsPlus/v1"],y=/^[a-z][a-zA-Z0-9]*(?:\.[a-zA-Z][a-zA-Z0-9]*)*$/,g={pubCount:"coverage.pubCount"},m={computed:72*36e5,operational:30*864e5,technical:90*864e5};function R(e){let t=l(e),n=t.type==="integer"?t.numberValue:t.type==="boolean"?t.booleanValue:t.type==="reference"?{documentId:t.documentId,documentRevision:t.documentRevision}:t.textValue;return c({type:t.type,value:n,allowedValues:t.allowedValues})}function A(e){let t=c(e);return t.type==="integer"?{type:t.type,numberValue:t.value}:t.type==="boolean"?{type:t.type,booleanValue:t.value}:t.type==="reference"?{type:t.type,...t.value}:t.type==="enum"?{type:t.type,textValue:t.value,allowedValues:t.allowedValues}:{type:t.type,textValue:t.value}}function s(){throw new Error("Invalid business fact contract")}function l(e){return!e||typeof e!="object"||Array.isArray(e)?s():e}function a(e){return typeof e=="string"&&e.trim()!==""?e:s()}function d(e){(e.length>48||!y.test(e))&&s()}function S(e){return d(e),"businessFact-"+Array.from(new TextEncoder().encode(e),t=>t.toString(16).padStart(2,"0")).join("")}function c(e){let t=l(e),n=t.value;switch(t.type){case"integer":return Number.isSafeInteger(n)?{type:"integer",value:n}:s();case"decimal":return typeof n=="string"&&/^(?:0|-?[1-9]\d*)(?:\.\d*[1-9])?$|^-0\.\d*[1-9]$/.test(n)?{type:"decimal",value:n}:s();case"boolean":return typeof n=="boolean"?{type:"boolean",value:n}:s();case"string":return typeof n=="string"?{type:"string",value:n}:s();case"date":return typeof n=="string"&&/^\d{4}-\d{2}-\d{2}$/.test(n)&&!Number.isNaN(Date.parse(n))&&new Date(n).toISOString().slice(0,10)===n?{type:"date",value:n}:s();case"enum":{let r=t.allowedValues;return!Array.isArray(r)||!r.length||!r.every(o=>typeof o=="string"&&o!=="")||new Set(r).size!==r.length||!r.includes(n)?s():{type:"enum",value:a(n),allowedValues:[...r].sort()}}case"reference":{let r=l(n);return{type:"reference",value:{documentId:a(r.documentId),documentRevision:a(r.documentRevision)}}}default:return s()}}function b(e){return e!=="identity/v1"&&e!=="floorHundredsPlus/v1"?s():e}function v(e,t){let n=c(e);return b(t)==="floorHundredsPlus/v1"?n.type!=="integer"||n.value<0?s():n.value<100?String(n.value):`${(Math.floor(n.value/100)*100).toLocaleString("en-GB")}+`:n.type==="reference"?n.value.documentId:String(n.value)}function w(e,t,n){return["htmlText","htmlAttribute","json"].includes(n)?e.replace(/\{([^{}]*)\}/g,(r,o)=>{d(o);let u=Object.hasOwn(g,o)?g[o]:o;if(!Object.hasOwn(t,u))throw new Error(`Unknown fact placeholder: ${o}`);let i=t[u];return n==="json"?JSON.stringify(i).slice(1,-1).replace(/</g,"\\u003c").replace(/>/g,"\\u003e").replace(/&/g,"\\u0026").replace(/\u2028/g,"\\u2028").replace(/\u2029/g,"\\u2029"):i.replace(/[&<>"']/g,f=>({"&":"&","<":"<",">":">",'"':""","'":"'"})[f])}):s()}function p(e){return e===null||typeof e=="boolean"||typeof e=="string"||typeof e=="number"&&Number.isFinite(e)?JSON.stringify(e):Array.isArray(e)?`[${Array.from(e,p).join(",")}]`:typeof e!="object"||e===null||Object.getPrototypeOf(e)!==Object.prototype?s():`{${Object.entries(e).sort(([t],[n])=>t<n?-1:t>n?1:0).map(([t,n])=>`${JSON.stringify(t)}:${p(n)}`).join(",")}}`}async function h(e){let t=e.fact;d(t.key);let n=c(t.publicValue);v(n,t.displayRule),(!Number.isSafeInteger(e.revision)||e.revision<1||e.baseRevision!==null&&(!Number.isSafeInteger(e.baseRevision)||e.baseRevision<1||e.baseRevision>=e.revision))&&s(),a(e.projectId),a(t.accountableOwner),a(t.source.definition),a(t.source.version),(!["computed","observed","attested"].includes(t.source.kind)||!Object.hasOwn(m,t.freshness)||typeof t.optional!="boolean"||t.unit!==null&&typeof t.unit!="string")&&s(),t.timezone!==null&&new Intl.DateTimeFormat("en-GB",{timeZone:a(t.timezone)});let r=i=>((!/^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}(?:\.\d{3})?Z$/.test(i)||!Number.isFinite(Date.parse(i))||new Date(i).toISOString()!==i.replace(/(?<=:\d{2})Z$/,".000Z"))&&s(),Date.parse(i));(r(e.expiresAt)<=r(e.effectiveAt)||r(e.evidence.expiresAt)<=r(e.evidence.observedAt)||!/^[0-9a-f]{64}$/.test(e.evidence.digest)||typeof e.evidence.complete!="boolean")&&s(),a(e.evidence.reference),a(e.evidence.runId);for(let i of t.surfaces)a(i.id),i.semantics==="historical"?c({type:"date",value:i.asOf}):(i.semantics!=="current"||i.asOf!==null)&&s();let o={projectId:e.projectId,revision:e.revision,baseRevision:e.baseRevision,fact:{key:t.key,publicValue:n,unit:t.unit,timezone:t.timezone,displayRule:t.displayRule,source:{kind:t.source.kind,definition:t.source.definition,version:t.source.version},accountableOwner:t.accountableOwner,freshness:t.freshness,optional:t.optional,surfaces:t.surfaces.map(i=>({id:i.id,semantics:i.semantics,asOf:i.asOf}))},evidence:{reference:e.evidence.reference,digest:e.evidence.digest,complete:e.evidence.complete,runId:e.evidence.runId,observedAt:new Date(r(e.evidence.observedAt)).toISOString(),expiresAt:new Date(r(e.evidence.expiresAt)).toISOString()},effectiveAt:new Date(r(e.effectiveAt)).toISOString(),expiresAt:new Date(r(e.expiresAt)).toISOString()},u=await crypto.subtle.digest("SHA-256",new TextEncoder().encode(p(o)));return Array.from(new Uint8Array(u),i=>i.toString(16).padStart(2,"0")).join("")}export{g as FACT_ALIASES,x as FACT_DISPLAY_RULES,m as FACT_EXPIRY_MS,y as FACT_KEY,F as FACT_TYPES,d as assertFactKey,S as businessFactId,p as canonicalFactJson,w as expandFactPlaceholders,v as formatFact,h as hashFactRevision,b as parseFactDisplayRule,c as parseFactValue,R as parseStoredFactValue,A as storeFactValue};
|
|
2
|
+
//# sourceMappingURL=facts.mjs.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../src/contracts/facts.ts"],
|
|
4
|
+
"sourcesContent": ["/** Public contracts only. Evidence and approval identities never enter the CMS document. */\nexport const FACT_TYPES = [\"integer\", \"decimal\", \"boolean\", \"date\", \"string\", \"enum\", \"reference\"] as const;\nexport const FACT_DISPLAY_RULES = [\"identity/v1\", \"floorHundredsPlus/v1\"] as const;\nexport type FactDisplayRule = typeof FACT_DISPLAY_RULES[number];\nexport const FACT_KEY = /^[a-z][a-zA-Z0-9]*(?:\\.[a-zA-Z][a-zA-Z0-9]*)*$/;\nexport const FACT_ALIASES: Readonly<Record<string, string>> = { pubCount: \"coverage.pubCount\" };\nexport type FactValue =\n | { type: \"integer\"; value: number }\n // Decimal strings avoid binary floating-point loss; canonical form has no trailing fractional zeroes.\n | { type: \"decimal\"; value: string }\n | { type: \"boolean\"; value: boolean }\n | { type: \"date\" | \"string\"; value: string }\n | { type: \"enum\"; value: string; allowedValues: readonly string[] }\n | { type: \"reference\"; value: { documentId: string; documentRevision: string } };\nexport type FactSource = { kind: \"computed\" | \"observed\" | \"attested\"; definition: string; version: string };\nexport type BusinessFact = {\n key: string; publicValue: FactValue; unit: string | null; timezone: string | null;\n displayRule: FactDisplayRule; source: FactSource; accountableOwner: string;\n freshness: \"computed\" | \"operational\" | \"technical\"; optional: boolean;\n surfaces: readonly { id: string; semantics: \"current\" | \"historical\"; asOf: string | null }[];\n};\nexport const FACT_EXPIRY_MS = { computed: 72 * 3_600_000, operational: 30 * 86_400_000, technical: 90 * 86_400_000 } as const;\nexport type FactEvidence = { reference: string; digest: string; observedAt: string; expiresAt: string; complete: boolean; runId: string };\nexport type FactRevision = {\n projectId: string; revision: number; baseRevision: number | null; fact: BusinessFact;\n evidence: FactEvidence; effectiveAt: string; expiresAt: string;\n};\nexport type ApprovedFactRevision = FactRevision & {\n hash: string; approvedAt: string;\n approval: { kind: \"signer\"; signerId: string } | { kind: \"policy\"; policyVersion: string };\n};\nexport type FactPublicationReceipt = {\n intentId: string; projectId: string; revision: number; hash: string;\n destination: { projectId: string; dataset: string }; expectedDocumentRevision: string | null;\n cms: { transactionId: string; documentRevision: string; readBackHash: string; at: string } | null;\n invalidation: { deliveryKey: string; target: string; type: \"businessFact\"; id: string; at: string } | null;\n render: { url: string; deploymentId: string; revision: number; hash: string; at: string } | null;\n};\nexport type PublicBusinessFact = Pick<BusinessFact, \"key\" | \"publicValue\" | \"unit\" | \"timezone\" | \"displayRule\"> & {\n _type: \"businessFact\"; _id: string; approvedRevision: number; approvedHash: string;\n effectiveAt: string; expiresAt: string; provenanceSummary: string;\n};\n/** A request supplies one snapshot to every surface. Missing and unavailable are distinct from an empty snapshot. */\nexport type FactSnapshot = Readonly<Record<string, PublicBusinessFact>>;\nexport type FactReadResult = { status: \"available\"; snapshot: FactSnapshot } | { status: \"unavailable\"; reason: string };\nexport type FactReader = () => Promise<FactReadResult>;\nexport type FactPlaceholderContext = \"htmlText\" | \"htmlAttribute\" | \"json\";\n/** Stored Sanity projection: scalar unions use named slots, never private revision fields. */\nexport type StoredFactValue = { type: FactValue[\"type\"]; numberValue?: number; textValue?: string;\n booleanValue?: boolean; allowedValues?: readonly string[]; documentId?: string; documentRevision?: string };\nexport function parseStoredFactValue(input: unknown): FactValue {\n const entry = record(input);\n const value = entry.type === \"integer\" ? entry.numberValue : entry.type === \"boolean\" ? entry.booleanValue\n : entry.type === \"reference\" ? { documentId: entry.documentId, documentRevision: entry.documentRevision } : entry.textValue;\n return parseFactValue({ type: entry.type, value, allowedValues: entry.allowedValues });\n}\nexport function storeFactValue(input: FactValue): StoredFactValue {\n const entry = parseFactValue(input);\n if (entry.type === \"integer\") return { type: entry.type, numberValue: entry.value };\n if (entry.type === \"boolean\") return { type: entry.type, booleanValue: entry.value };\n if (entry.type === \"reference\") return { type: entry.type, ...entry.value };\n return entry.type === \"enum\" ? { type: entry.type, textValue: entry.value, allowedValues: entry.allowedValues }\n : { type: entry.type, textValue: entry.value };\n}\nexport type StoredBusinessFact = Omit<PublicBusinessFact, \"publicValue\"> & { publicValue: StoredFactValue };\n\nfunction invalid(): never { throw new Error(\"Invalid business fact contract\"); }\nfunction record(value: unknown): Record<string, unknown> {\n if (!value || typeof value !== \"object\" || Array.isArray(value)) return invalid();\n return value as Record<string, unknown>;\n}\nfunction text(value: unknown): string { return typeof value === \"string\" && value.trim() !== \"\" ? value : invalid(); }\nexport function assertFactKey(key: string): void {\n if (key.length > 48 || !FACT_KEY.test(key)) invalid();\n}\nexport function businessFactId(key: string): string {\n assertFactKey(key);\n // Dataset-local, injective encoding; never a draft ID or a key containing a path separator.\n return \"businessFact-\" + Array.from(new TextEncoder().encode(key), (byte) => byte.toString(16).padStart(2, \"0\")).join(\"\");\n}\nexport function parseFactValue(input: unknown): FactValue {\n const entry = record(input), value = entry.value;\n switch (entry.type) {\n case \"integer\": return Number.isSafeInteger(value) ? { type: \"integer\", value: value as number } : invalid();\n case \"decimal\": return typeof value === \"string\" && /^(?:0|-?[1-9]\\d*)(?:\\.\\d*[1-9])?$|^-0\\.\\d*[1-9]$/.test(value)\n ? { type: \"decimal\", value } : invalid();\n case \"boolean\": return typeof value === \"boolean\" ? { type: \"boolean\", value } : invalid();\n case \"string\": return typeof value === \"string\" ? { type: \"string\", value } : invalid();\n case \"date\": return typeof value === \"string\" && /^\\d{4}-\\d{2}-\\d{2}$/.test(value)\n && !Number.isNaN(Date.parse(value)) && new Date(value).toISOString().slice(0, 10) === value ? { type: \"date\", value } : invalid();\n case \"enum\": {\n const allowed = entry.allowedValues;\n if (!Array.isArray(allowed) || !allowed.length || !allowed.every((item) => typeof item === \"string\" && item !== \"\")\n || new Set(allowed).size !== allowed.length || !allowed.includes(value)) return invalid();\n return { type: \"enum\", value: text(value), allowedValues: [...allowed].sort() as string[] };\n }\n case \"reference\": {\n const ref = record(value);\n return { type: \"reference\", value: { documentId: text(ref.documentId), documentRevision: text(ref.documentRevision) } };\n }\n default: return invalid();\n }\n}\nexport function parseFactDisplayRule(input: unknown): FactDisplayRule {\n if (input !== \"identity/v1\" && input !== \"floorHundredsPlus/v1\") return invalid();\n return input;\n}\nexport function formatFact(input: FactValue, rule: FactDisplayRule): string {\n const value = parseFactValue(input);\n if (parseFactDisplayRule(rule) === \"floorHundredsPlus/v1\") {\n if (value.type !== \"integer\" || value.value < 0) return invalid();\n return value.value < 100 ? String(value.value) : `${(Math.floor(value.value / 100) * 100).toLocaleString(\"en-GB\")}+`;\n }\n return value.type === \"reference\" ? value.value.documentId : String(value.value);\n}\n/** Escape each replacement, not the surrounding trusted template. JSON returns string content without quotes;\n * callers serialize complete structured objects and keep numeric properties as exact values. Attributes must be quoted.\n * Raw text/React children use the formatter directly; never HTML-unescape an expanded string.\n */\nexport function expandFactPlaceholders(template: string, values: Readonly<Record<string, string>>, context: FactPlaceholderContext): string {\n if (![\"htmlText\", \"htmlAttribute\", \"json\"].includes(context)) return invalid();\n return template.replace(/\\{([^{}]*)\\}/g, (_match, key: string) => {\n assertFactKey(key);\n const resolved = Object.hasOwn(FACT_ALIASES, key) ? FACT_ALIASES[key]! : key;\n if (!Object.hasOwn(values, resolved)) throw new Error(`Unknown fact placeholder: ${key}`);\n const value = values[resolved]!;\n if (context === \"json\") return JSON.stringify(value).slice(1, -1)\n .replace(/</g, \"\\\\u003c\").replace(/>/g, \"\\\\u003e\").replace(/&/g, \"\\\\u0026\")\n .replace(/\\u2028/g, \"\\\\u2028\").replace(/\\u2029/g, \"\\\\u2029\");\n return value.replace(/[&<>\"']/g, (char) => ({ \"&\": \"&\", \"<\": \"<\", \">\": \">\", '\"': \""\", \"'\": \"'\" })[char]!);\n });\n}\n/** Fixed JSON domain, sorted object keys, array order preserved, finite numbers only. */\nexport function canonicalFactJson(value: unknown): string {\n if (value === null || typeof value === \"boolean\" || typeof value === \"string\") return JSON.stringify(value);\n if (typeof value === \"number\" && Number.isFinite(value)) return JSON.stringify(value);\n if (Array.isArray(value)) return `[${Array.from(value, canonicalFactJson).join(\",\")}]`;\n if (typeof value !== \"object\" || value === null || Object.getPrototypeOf(value) !== Object.prototype) return invalid();\n return `{${Object.entries(value).sort(([a], [b]) => a < b ? -1 : a > b ? 1 : 0)\n .map(([key, item]) => `${JSON.stringify(key)}:${canonicalFactJson(item)}`).join(\",\")}}`;\n}\n/** SHA-256 of contract fields only; unknown fields and approval are ignored. Instants use UTC milliseconds. */\nexport async function hashFactRevision(revision: FactRevision): Promise<string> {\n const fact = revision.fact;\n assertFactKey(fact.key);\n const publicValue = parseFactValue(fact.publicValue);\n formatFact(publicValue, fact.displayRule);\n if (!Number.isSafeInteger(revision.revision) || revision.revision < 1\n || (revision.baseRevision !== null && (!Number.isSafeInteger(revision.baseRevision) || revision.baseRevision < 1 || revision.baseRevision >= revision.revision))) invalid();\n text(revision.projectId); text(fact.accountableOwner); text(fact.source.definition); text(fact.source.version);\n if (![\"computed\", \"observed\", \"attested\"].includes(fact.source.kind) || !Object.hasOwn(FACT_EXPIRY_MS, fact.freshness)\n || typeof fact.optional !== \"boolean\" || (fact.unit !== null && typeof fact.unit !== \"string\")) invalid();\n if (fact.timezone !== null) new Intl.DateTimeFormat(\"en-GB\", { timeZone: text(fact.timezone) });\n const instant = (value: string) => {\n if (!/^\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}:\\d{2}(?:\\.\\d{3})?Z$/.test(value) || !Number.isFinite(Date.parse(value))\n || new Date(value).toISOString() !== value.replace(/(?<=:\\d{2})Z$/, \".000Z\")) invalid();\n return Date.parse(value);\n };\n if (instant(revision.expiresAt) <= instant(revision.effectiveAt)\n || instant(revision.evidence.expiresAt) <= instant(revision.evidence.observedAt)\n || !/^[0-9a-f]{64}$/.test(revision.evidence.digest) || typeof revision.evidence.complete !== \"boolean\") invalid();\n text(revision.evidence.reference); text(revision.evidence.runId);\n for (const surface of fact.surfaces) {\n text(surface.id);\n if (surface.semantics === \"historical\") parseFactValue({ type: \"date\", value: surface.asOf });\n else if (surface.semantics !== \"current\" || surface.asOf !== null) invalid();\n }\n const candidate: FactRevision = {\n projectId: revision.projectId, revision: revision.revision, baseRevision: revision.baseRevision,\n fact: {\n key: fact.key, publicValue, unit: fact.unit, timezone: fact.timezone, displayRule: fact.displayRule,\n source: { kind: fact.source.kind, definition: fact.source.definition, version: fact.source.version },\n accountableOwner: fact.accountableOwner, freshness: fact.freshness, optional: fact.optional,\n surfaces: fact.surfaces.map((surface) => ({ id: surface.id, semantics: surface.semantics, asOf: surface.asOf })),\n },\n evidence: {\n reference: revision.evidence.reference, digest: revision.evidence.digest, complete: revision.evidence.complete,\n runId: revision.evidence.runId, observedAt: new Date(instant(revision.evidence.observedAt)).toISOString(),\n expiresAt: new Date(instant(revision.evidence.expiresAt)).toISOString(),\n },\n effectiveAt: new Date(instant(revision.effectiveAt)).toISOString(),\n expiresAt: new Date(instant(revision.expiresAt)).toISOString(),\n };\n const digest = await crypto.subtle.digest(\"SHA-256\", new TextEncoder().encode(canonicalFactJson(candidate)));\n return Array.from(new Uint8Array(digest), (byte) => byte.toString(16).padStart(2, \"0\")).join(\"\");\n}\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
|
+
"names": ["FACT_TYPES", "FACT_DISPLAY_RULES", "FACT_KEY", "FACT_ALIASES", "FACT_EXPIRY_MS", "parseStoredFactValue", "input", "entry", "record", "value", "parseFactValue", "storeFactValue", "invalid", "text", "assertFactKey", "key", "businessFactId", "byte", "allowed", "item", "ref", "parseFactDisplayRule", "formatFact", "rule", "expandFactPlaceholders", "template", "values", "context", "_match", "resolved", "char", "canonicalFactJson", "a", "b", "hashFactRevision", "revision", "fact", "publicValue", "instant", "surface", "candidate", "digest"]
|
|
7
|
+
}
|
package/dist/next.cjs
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
"use strict";var
|
|
1
|
+
"use strict";var P=Object.defineProperty;var Se=Object.getOwnPropertyDescriptor;var $e=Object.getOwnPropertyNames;var we=Object.prototype.hasOwnProperty;var _e=(e,n)=>{for(var t in n)P(e,t,{get:n[t],enumerable:!0})},Ce=(e,n,t,o)=>{if(n&&typeof n=="object"||typeof n=="function")for(let r of $e(n))!we.call(e,r)&&r!==t&&P(e,r,{get:()=>n[r],enumerable:!(o=Se(n,r))||o.enumerable});return e};var Te=e=>Ce(P({},"__esModule",{value:!0}),e);var Ke={};_e(Ke,{MENU_DECORATIONS:()=>M,MENU_LAYOUTS:()=>D,MENU_LAYOUT_DEFAULTS:()=>v,businessLocationsQuery:()=>ge,createNextCmsReader:()=>te,createRevalidateRoute:()=>le,locationTags:()=>pe,locationsQuery:()=>me,menuQuery:()=>X,menuTags:()=>V,openVacanciesQuery:()=>de,parseBusinessLocation:()=>B,parseLocationDocument:()=>H,parseMenuDocument:()=>I,parseScheduleDocument:()=>z,parseVacancies:()=>F,parseVacancyDocument:()=>U,resolveWithFallback:()=>ue,scheduleQuery:()=>be,scheduleTags:()=>he,vacancyTags:()=>ce});module.exports=Te(Ke);var An=require("server-only");function Q(e){if(!Array.isArray(e))return!1;for(let n=0;n<e.length;n+=1)if(!Object.hasOwn(e,n))return!1;return!0}var D=["stacked","columns"],M=["none","playful"],v={layout:"stacked",decoration:"none"},L=`_type, _id, _rev, _updatedAt, title, locationKeys, note, signOff,
|
|
2
2
|
variants[]{_key, label, note, sections[]{_key, title, service, items[]{
|
|
3
3
|
_key, name, description, priceNote, dietary, allergenNote, availability,
|
|
4
4
|
prices[]{_key, label, amount{minor, currency}}, extras[]{_key, name, amount{minor, currency}}
|
|
5
|
-
}}}`;function V(e,n){return S(e,{types:["menu"],...n===void 0?{}:{ids:[n]}})}function f(e,n){throw new R("menu",[`${e} ${n}`])}function Z(e,n,t=new Set,o){if(e===null||typeof e=="string"||typeof e=="boolean"||typeof e=="number"&&Number.isFinite(e))return e;if(typeof e!="object"||e===null)return f(n,"is not plain JSON data");try{if(t.has(e))return f(n,"is not acyclic JSON data");let r=Array.isArray(e),s=Object.getPrototypeOf(e);if(r?s!==Array.prototype:s!==Object.prototype&&s!==null)return f(n,"is not an ordinary saved object");t.add(e);let u=Reflect.ownKeys(e),y=r?[]:{},a=0,p=0;for(let i of u){if(typeof i!="string")return f(n,"has a symbol key");let c=r&&i!=="length"?`${n}[${i}]`:`${n}.${i}`,d;try{d=i==="_id"&&o!==void 0?o:Object.getOwnPropertyDescriptor(e,i)}catch{return f(c,"could not be snapshotted as plain JSON data")}if(!d||!Object.hasOwn(d,"value"))return f(c,"is not a saved data property");if(r&&i==="length"){let k=d.value;if(typeof k!="number"||!Number.isSafeInteger(k)||k<0)return f(c,"is not a saved list length");a=k;continue}if(!d.enumerable||r&&!/^(0|[1-9]\d*)$/.test(i))return f(c,"is not a JSON data property");let l=d.value,m=Z(l,c,t);Object.defineProperty(y,i,{value:m,enumerable:!0,writable:!0,configurable:!0}),p++}return r&&(p!==a||y.length!==a)?f(n,"is not a complete saved list"):y}catch(r){if(r instanceof R)throw r;return f(n,"could not be snapshotted as plain JSON data")}finally{t.delete(e)}}function A(e,n){return e===null||typeof e!="object"||Array.isArray(e)||Object.getPrototypeOf(e)!==Object.prototype&&Object.getPrototypeOf(e)!==null?f(n,"is not an ordinary saved object"):e}function g(e,n,t=!0){return typeof e!="string"||t&&e.trim()===""?f(n,"is not saved text"):e}function C(e,n,t){return e[n]===void 0||e[n]===null?{}:{[n]:g(e[n],`${t}.${n}`,!1)}}function T(e,n,t){return e==null?[]:Q(e)?e.map((o,r)=>t(o,`${n}[${String(r)}]`)):f(n,"is not a complete saved list")}function J(e,n){let t=A(e,n);if(typeof t.minor!="number"||!Number.isSafeInteger(t.minor)||t.minor<0)return f(`${n}.minor`,"is not a whole non-negative safe amount");let o=g(t.currency,`${n}.currency`);return/^[A-Z]{3}$/.test(o)?{minor:t.minor,currency:o}:f(`${n}.currency`,"is not a three-letter currency code")}function Ae(e,n){let t=A(e,n);return{_key:g(t._key,`${n}._key`),amount:J(t.amount,`${n}.amount`),...C(t,"label",n)}}function Re(e,n){let t=A(e,n);return{_key:g(t._key,`${n}._key`),name:g(t.name,`${n}.name`),amount:J(t.amount,`${n}.amount`)}}function Ee(e,n){let t=A(e,n),o=t.availability??"available";return o!=="available"&&o!=="sold-out"&&o!=="hidden"?f(`${n}.availability`,"is not an availability choice"):{_key:g(t._key,`${n}._key`),name:g(t.name,`${n}.name`),...C(t,"description",n),...C(t,"priceNote",n),...C(t,"allergenNote",n),prices:T(t.prices,`${n}.prices`,Ae),extras:T(t.extras,`${n}.extras`,Re),dietary:T(t.dietary,`${n}.dietary`,g),availability:o}}function xe(e,n){let t=A(e,n);return{_key:g(t._key,`${n}._key`),title:g(t.title,`${n}.title`),...C(t,"service",n),items:T(t.items,`${n}.items`,Ee)}}function Ie(e,n){let t=A(e,n);return{_key:g(t._key,`${n}._key`),label:g(t.label,`${n}.label`),...C(t,"note",n),sections:T(t.sections,`${n}.sections`,xe)}}function Oe(e){if(e===null||typeof e!="object"||Array.isArray(e))return!1;let n=e._id;return typeof n=="string"&&n.trim()!==""&&!/^(drafts|versions)\./.test(n)}function I(e,n="menu"){return De(Z(e,n),n)}function De(e,n){let t=A(e,n);if(t._type!=="menu")return f(`${n}._type`,"is not menu");if(!Oe(t))return f(`${n}._id`,"is not a published menu identity");let o=g(t._updatedAt,`${n}._updatedAt`);if(!/^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}(?:\.\d+)?(?:Z|[+-]\d{2}:\d{2})$/.test(o)||!Number.isFinite(Date.parse(o)))return f(`${n}._updatedAt`,"is not an update date");let r=T(t.variants,`${n}.variants`,Ie);return r.length===0?f(`${n}.variants`,"has no menu choices"):{_type:"menu",_id:g(t._id,`${n}._id`),_rev:g(t._rev,`${n}._rev`),_updatedAt:o,title:g(t.title,`${n}.title`),locationKeys:T(t.locationKeys,`${n}.locationKeys`,g),variants:r,...C(t,"note",n),...Object.hasOwn(t,"signOff")?{signOff:t.signOff}:{}}}function W(e){if(e===null)return!0;try{return I(e),!0}catch{return!1}}var Y="malformed-content",R=class extends Error{code=Y;documentId;problems;constructor(n,t){super(`${Y}: ${n}: ${t.join("; ")}`),this.name="MalformedContentError",this.documentId=n,this.problems=t}};var G=`{..., "sections": coalesce(sections[]{..., _type == "menuBlock" => {menu->{${j}}}, _type == "linkListBlock" => {links[]{..., "page": page->{title, "slug": slug.current}}}}, sections)}`,un=`*[_type == "page" && defined(slug.current)]|order(slug.current asc)${G}`,cn=`*[_type == "page" && slug.current == $slug][0]${G}`;var Me=/^[A-Za-z][A-Za-z0-9_]{0,63}$/,ve=/^[A-Za-z0-9][A-Za-z0-9._-]{0,127}$/,je=/^[a-z0-9]{6,12}\.[a-z][a-z0-9_-]{0,63}$/;function K(e){if(!e||!Array.isArray(e.types)||e.types.length===0)throw new TypeError("CMS dependencies require document types");let n=[...e.types];for(let o of n)if(typeof o!="string"||!Me.test(o))throw new TypeError("Invalid CMS document type");if(e.ids!==void 0&&!Array.isArray(e.ids))throw new TypeError("Invalid CMS document IDs");let t=e.ids===void 0?void 0:[...e.ids];for(let o of t??[])if(typeof o!="string"||!ve.test(o)||/^(drafts|versions)\./.test(o))throw new TypeError("Invalid CMS document ID");if(new Set(n).size+new Set(t).size>128)throw new TypeError("Too many CMS tags");return Object.freeze({types:Object.freeze(n),...t===void 0?{}:{ids:Object.freeze(t)}})}function E(e){if(!e||typeof e.name!="string"||!/^[A-Za-z][A-Za-z0-9_.-]{0,127}$/.test(e.name)||typeof e.query!="string"||e.query.trim()===""||typeof e.resolve!="function")throw new TypeError("Invalid CMS query configuration");let n=e.params;if(!n||typeof n!="object"||Object.getPrototypeOf(n)!==Object.prototype&&Object.getPrototypeOf(n)!==null)throw new TypeError("CMS params must be plain JSON scalars");let t={};for(let o of Reflect.ownKeys(n)){let r=Object.getOwnPropertyDescriptor(n,o);if(typeof o!="string"||!r||!Object.hasOwn(r,"value")||!r.enumerable)throw new TypeError("CMS params must be plain JSON scalars");let s=r.value;if(!(s===null||typeof s=="string"||typeof s=="boolean"||typeof s=="number"&&Number.isFinite(s)))throw new TypeError("CMS params must be plain JSON scalars");Object.defineProperty(t,o,{value:s,enumerable:!0})}return Object.freeze({name:e.name,query:e.query,params:Object.freeze(t),dependencies:K(e.dependencies),resolve:e.resolve})}function S(e,n){if(typeof e!="string"||e.length>77||!je.test(e))throw new TypeError("Invalid CMS scope");let t=K(n),o=[...[...new Set(t.types)].sort().map(r=>`cms:${e}:type:${r}`),...[...new Set(t.ids??[])].sort().map(r=>`cms:${e}:id:${r}`)];return Object.freeze(o)}function X(e){return E({name:"menu.v1",query:`*[_type == "menu" && _id == $id && !(_id in path("drafts.**")) && !(_id in path("versions.**"))][0]{${j}}`,params:{id:e},dependencies:{types:["menu"],ids:[e]},resolve:(n,t)=>{if(!W(t)||t!==null&&t._id!==e)throw new TypeError("Invalid CMS menu fallback");if(n==null)return{data:t,fallbackFields:["$"]};let o=I(n);if(o._id!==e)throw new R("menu",["menu._id does not match the requested document"]);return{data:o,fallbackFields:[]}}})}function ee(e){if(!e||!Object.hasOwn(e,"data")||!Array.isArray(e.fallbackFields)||![...e.fallbackFields].every(n=>typeof n=="string"&&(n==="$"||/^[A-Za-z][A-Za-z0-9_.[\]-]{0,127}$/.test(n))))throw new TypeError("Invalid CMS resolution");if(e.warnings!==void 0&&(!Array.isArray(e.warnings)||![...e.warnings].every(n=>n==="siteHero.layout.defaulted"||n==="siteHero.tagline.dropped"||n==="siteHero.taglines.defaulted")))throw new TypeError("Invalid CMS resolution warnings");return{data:e.data,fallbackFields:Object.freeze([...new Set(e.fallbackFields)]),...e.warnings?.length?{warnings:Object.freeze([...new Set(e.warnings)])}:{}}}function ne(e){let n=e?.revalidateSeconds??3600;if(!Number.isSafeInteger(n)||n<3600||!e?.adapter||typeof e.adapter.read!="function"||e.onDiagnostic!==void 0&&typeof e.onDiagnostic!="function")throw new TypeError("Invalid CMS reader configuration");let t=e.adapter;S(t.scope,{types:["ScopeValidation"]});let o=r=>{try{e.onDiagnostic?e.onDiagnostic(r):console.warn(JSON.stringify(r))}catch{}};return{async read(r,s){let u,y,a;try{if(u=E(r),a=S(t.scope,u.dependencies),!s||!Object.hasOwn(s,"fallback"))throw new TypeError;y=ee(u.resolve(null,s.fallback))}catch{throw new TypeError("Invalid CMS query or fallback configuration")}let p=(d,l,m)=>(o({event:"cms.fallback",query:u.name,reason:d,fields:["$"],...l===void 0?{}:{status:l},...m?{warnings:m}:{}}),{data:y.data,source:"fallback",fallbackFields:["$"],reason:d,...m?{warnings:m}:{}}),i;try{i=await t.read({name:u.name,query:u.query,params:u.params},{tags:a,revalidateSeconds:n})}catch{return p("network")}if(!i.ok){let l=["configuration","network","timeout","rate-limit","upstream","plan-limit","permission","malformed"].includes(i.reason)?i.reason:"malformed",m=Number.isInteger(i.status)&&(i.status??0)>=100&&(i.status??0)<=599?i.status:void 0;return p(l,m)}if(i.value===null||i.value===void 0)return p("missing");let c;try{c=ee(u.resolve(i.value,s.fallback))}catch{return p("malformed")}return c.fallbackFields.includes("$")?{...p("invalid-field",void 0,c.warnings),data:c.data}:c.fallbackFields.length>0?(o({event:"cms.partial-fallback",query:u.name,reason:"invalid-field",fields:c.fallbackFields,...c.warnings?{warnings:c.warnings}:{}}),{...c,source:"mixed",reason:"invalid-field"}):{...c,source:"cms"}}}}var te=ne;var ie=require("next/cache.js");var N="sanity-webhook-signature",Pe=/^t=(\d+)[, ]+v1=([^, ]+)$/;var oe=new TextEncoder;function Le(e){return crypto.subtle.importKey("raw",oe.encode(e),{name:"HMAC",hash:"SHA-256"},!1,["sign","verify"])}function Ne(e){if(!/^[A-Za-z0-9_-]+={0,2}$/.test(e))return null;let n=e.replace(/-/g,"+").replace(/_/g,"/");try{let t=atob(n),o=new Uint8Array(t.length);for(let r=0;r<t.length;r+=1)o[r]=t.charCodeAt(r);return o}catch{return null}}async function re(e){let{secret:n,rawBody:t,headers:o}=e,r=e.now??Date.now(),s=e.toleranceMs??3e5;if(!n||n.length===0)return{ok:!1,reason:"no-secret"};let u=o.get(N);if(!u)return{ok:!1,reason:"no-signature"};let y=Pe.exec(u.trim());if(y===null)return{ok:!1,reason:"malformed-signature"};let a=Number(y[1]),p=y[2]??"";if(!Number.isSafeInteger(a))return{ok:!1,reason:"malformed-signature"};if(a<16094592e5)return{ok:!1,reason:"stale-timestamp"};if(Math.abs(r-a)>s)return{ok:!1,reason:"stale-timestamp"};let i=Ne(p);if(i===null)return{ok:!1,reason:"malformed-signature"};let c=await Le(n);return await crypto.subtle.verify("HMAC",c,i,oe.encode(`${a}.${t}`))?{ok:!0}:{ok:!1,reason:"bad-signature"}}var Ue=16*1024,Fe=1500,qe=new TextEncoder;function b(e,n,t={},o=!1){return new Response(o?null:JSON.stringify(n),{status:e,headers:{"Content-Type":"application/json","Cache-Control":"no-store",...t}})}function He(e,n){if(!n||typeof n!="object"||Array.isArray(n)||Object.keys(n).length===0)throw new TypeError("Invalid CMS invalidation mapping");let t=Object.create(null);for(let o of Reflect.ownKeys(n)){let r=Object.getOwnPropertyDescriptor(n,o);if(typeof o!="string"||!r?.enumerable||!Object.hasOwn(r,"value"))throw new TypeError("Invalid CMS invalidation mapping");let s=r.value;if(!Array.isArray(s)||!s.includes(o))throw new TypeError("Invalid CMS invalidation mapping");S(e,{types:s,ids:["validation"]}),t[o]=Object.freeze([...s])}for(let o of Object.values(t))if(o.some(r=>!Object.hasOwn(t,r)))throw new TypeError("Invalid CMS invalidation mapping");return Object.freeze(t)}function se(e){return typeof e=="string"&&e.trim()!==""&&qe.encode(e).byteLength>=32}var O=class extends Error{constructor(t){super("Invalid CMS webhook body");this.status=t}status};async function Be(e){let n=e.body?.getReader();if(!n)return"";let t=new TextDecoder("utf-8",{fatal:!0,ignoreBOM:!0}),o,r=new Promise((s,u)=>{o=setTimeout(()=>u(new O(400)),Fe)});try{let s=0,u="";for(;;){let{done:y,value:a}=await Promise.race([n.read(),r]);if(y)return u+t.decode();if(s+=a.byteLength,s>Ue)throw new O(413);u+=t.decode(a,{stream:!0})}}catch(s){throw n.cancel().catch(()=>{}),s}finally{clearTimeout(o),n.releaseLock()}}function le(e){let n=e.scope,t=He(n,e.typeToTags),o=e.secretEnv??"SANITY_REVALIDATE_SECRET",r=e.previousSecretEnv??"SANITY_REVALIDATE_SECRET_PREVIOUS",s=e.env??(()=>process.env),u=e.now??Date.now,y=async a=>{if(a.method!=="POST")return b(405,{error:"Method not allowed"},{Allow:"POST"},a.method==="HEAD");let p,i;try{let $=s(),P=$[o],_=$[r];if(!se(P)||_!==void 0&&!se(_))throw new Error;p=P,i=_}catch{return b(503,{error:"COULD NOT ANSWER: revalidation configuration unavailable"})}let c=a.headers.get(N);if(!c||c.length>512||!/^t=\d+[, ]+v1=[A-Za-z0-9_-]+={0,2}$/.test(c.trim()))return b(401,{error:"Unauthorized"});let d;try{d=await Be(a)}catch($){return $ instanceof O&&$.status===413?b(413,{error:"Payload too large"}):b(400,{error:"Invalid body"})}try{let $=u();if(!Number.isFinite($))throw new Error;if(!(await Promise.all([p,...i===void 0?[]:[i]].map(_=>re({secret:_,rawBody:d,headers:a.headers,now:$})))).some(_=>_.ok))return b(401,{error:"Unauthorized"})}catch{return b(401,{error:"Unauthorized"})}let l;try{l=JSON.parse(d)}catch{return b(400,{error:"Invalid payload"})}if(!l||typeof l!="object"||Array.isArray(l)||Object.keys(l).length!==2||!Object.hasOwn(l,"_type")||!Object.hasOwn(l,"_id"))return b(400,{error:"Invalid payload"});let{_type:m,_id:k}=l;if(typeof m!="string"||!/^[A-Za-z][A-Za-z0-9_]{0,63}$/.test(m)||typeof k!="string"||!/^[A-Za-z0-9][A-Za-z0-9._-]{0,127}$/.test(k))return b(400,{error:"Invalid payload"});if(!Object.hasOwn(t,m)||/^(drafts|versions)\./.test(k))return b(400,{error:"Unsupported document"});let ke=S(n,{types:t[m],ids:[k]});try{for(let $ of ke)(0,ie.revalidateTag)($,{expire:0})}catch{return b(500,{error:"Could not revalidate"})}return b(200,{revalidated:!0})};return Object.freeze({POST:y,GET:y,HEAD:y,PUT:y,PATCH:y,DELETE:y,OPTIONS:y})}var w=e=>e!==null&&typeof e=="object"&&!Array.isArray(e),h=e=>typeof e=="string"&&e.trim()?e.trim():null,ze=(e,n)=>e._type===n&&typeof e._id=="string"&&e._id.length>0&&!/^(drafts|versions)\./.test(e._id),Qe=/^\d{4}-\d{2}-\d{2}$/,ae=/^([01]\d|2[0-3]):[0-5]\d$/,Ve=["mon","tue","wed","thu","fri","sat","sun"];async function ue(e,n,t){try{let o=await e.read(n,{fallback:t});return{...o,source:o.source==="cms"?"sanity":o.source}}catch{return{data:t,source:"fallback",fallbackFields:["$"],reason:"configuration"}}}var Ze=/^[A-Za-z0-9._+-]{1,64}@[A-Za-z0-9-]{1,63}(?:\.[A-Za-z0-9-]{1,63})*\.[A-Za-z]{2,63}$/;function Je(e){let n=h(e);if(!n)return null;try{let t=new URL(n);return t.protocol==="http:"||t.protocol==="https:"?t.href:null}catch{return null}}function x(e){if(typeof e!="function")throw new TypeError("A client validator is required")}function U(e,n,t){if(x(t),!w(e)||e.status!=="open")return null;let o=h(e.closingDate);if(o!==null&&o<n||t(e)!==null)return null;let r=h(e.title),s=e.location==="Other"?h(e.locationNote):h(e.location);if(!r||!s)return null;let u=h(e.pdfUrl);return{id:String(h(e._id)),title:r,location:s,summary:h(e.summary),pdfUrl:u?.startsWith("https://cdn.sanity.io/files/")?u:null,applyUrl:Je(e.applyUrl),applyEmail:typeof e.applyEmail=="string"&&e.applyEmail.length<=254&&Ze.test(e.applyEmail)?e.applyEmail:null}}function F(e,n,t){if(x(t),!Array.isArray(e))throw new TypeError("Sanity returned vacancies that are not a list");return e.map(o=>({value:U(o,n,t),order:w(o)&&typeof o.order=="number"&&Number.isFinite(o.order)?o.order:1e6})).filter(o=>o.value!==null).sort((o,r)=>o.order-r.order||o.value.title.toLowerCase().localeCompare(r.value.title.toLowerCase())).map(o=>o.value)}function ce(e){return S(e,{types:["vacancy"]})}function de(e,n){if(!Qe.test(e))throw new TypeError("Invalid calendar date");return x(n),E({name:"vacancy.open.v1",query:'*[_type == "vacancy" && status == "open" && !(_id in path("drafts.**")) && !(_id in path("versions.**")) && (!defined(closingDate) || closingDate >= $today)]|order(coalesce(order, 1000000) asc, lower(title) asc){_id, _type, title, location, locationNote, summary, "pdfUrl": jobDescriptionPdf.asset->url, applyUrl, applyEmail, status, closingDate, order}',params:{today:e},dependencies:{types:["vacancy"]},resolve:(t,o)=>({data:t==null?o:F(t,e,n),fallbackFields:t==null?["$"]:[]})})}var We=["monday","tuesday","wednesday","thursday","friday","saturday","sunday"],Ye=/^[a-z0-9]+(?:-[a-z0-9]+)*$/;function q(e){return!w(e)||typeof e._id!="string"||!w(e.slug)||typeof e.slug.current!="string"||!Ye.test(e.slug.current)||h(e.name)===null||e.addressLines!==void 0&&e.addressLines!==null&&(!Array.isArray(e.addressLines)||Array.from(e.addressLines).some(n=>h(n)===null))||e.postcode!==void 0&&e.postcode!==null&&h(e.postcode)===null||e.coordinates!==void 0&&e.coordinates!==null&&(!w(e.coordinates)||typeof e.coordinates.lat!="number"||!Number.isFinite(e.coordinates.lat)||typeof e.coordinates.lng!="number"||!Number.isFinite(e.coordinates.lng))||e.phone!==void 0&&e.phone!==null&&typeof e.phone!="string"||e.email!==void 0&&e.email!==null&&typeof e.email!="string"?null:{name:h(e.name),slug:e.slug.current,addressLines:e.addressLines==null?e.addressLines:e.addressLines.map(n=>n.trim()),postcode:e.postcode==null?e.postcode:String(e.postcode).trim(),coordinates:e.coordinates==null?e.coordinates:{lat:e.coordinates.lat,lng:e.coordinates.lng},phone:e.phone,email:e.email,hours:e.hours}}function ye(e){if(!w(e))return null;let n={};for(let t of We){let o=e[t];if(!Array.isArray(o)||!Array.from(o).every(r=>w(r)&&typeof r.opens=="string"&&typeof r.closes=="string"))return null;n[t]=o.map(r=>({opens:r.opens,closes:r.closes}))}return n}function H(e,n,t){x(t);let o=q(e);if(o===null||o.slug!==n.id)return{data:n,fallbackFields:["$"]};let r=ye(o.hours),s={id:n.id,label:o.name,addressLines:o.addressLines??n.addressLines,postcode:o.postcode??n.postcode,geo:o.coordinates==null?n.geo:{latitude:o.coordinates.lat,longitude:o.coordinates.lng},telephone:o.phone===void 0?n.telephone:o.phone,email:o.email===void 0?n.email:o.email,hours:r??n.hours};try{return{data:t(s),fallbackFields:r===null?["hours"]:[]}}catch{if(r!==null)try{return{data:t({...s,hours:n.hours}),fallbackFields:["hours"]}}catch{}return{data:n,fallbackFields:["$"]}}}function B(e,n,t){x(t);let o=q(e);if(o===null||o.slug!==n.id)return{data:n,fallbackFields:["$"]};let r=ye(o.hours),s={...n,label:o.name,address:n.address===null?null:{...n.address,streetAddress:o.addressLines??n.address.streetAddress,postalCode:o.postcode??n.address.postalCode},telephone:o.phone===void 0?n.telephone:o.phone,email:o.email===void 0?n.email:o.email,geo:o.coordinates==null?n.geo:{latitude:o.coordinates.lat,longitude:o.coordinates.lng},hours:r??n.hours};try{return{data:t(s),fallbackFields:r===null?["hours"]:[]}}catch{if(r!==null)try{return{data:t({...s,hours:n.hours}),fallbackFields:["hours"]}}catch{}return{data:n,fallbackFields:["$"]}}}function pe(e){return S(e,{types:["location"]})}function fe(e,n){return E({name:e,query:'*[_type == "location" && defined(slug.current) && !(_id in path("drafts.**")) && !(_id in path("versions.**"))]{_id, _type, name, slug, addressLines, postcode, coordinates, phone, email, hours}',params:{},dependencies:{types:["location"]},resolve:(t,o)=>{if(!Array.isArray(t))return{data:o,fallbackFields:["$"]};let r=new Map,s=new Set;for(let a of t){let p=q(a);p!==null&&(r.has(p.slug)?s.add(p.slug):r.set(p.slug,a))}let u=[];return{data:o.map((a,p)=>{let i=r.get(a.id),c=i===void 0||s.has(a.id)?{data:a,fallbackFields:["$"]}:n(i,a);return u.push(...c.fallbackFields.map(d=>d==="$"?`locations[${p}]`:`locations[${p}].${d}`)),c.data}),fallbackFields:o.length>0&&u.length===o.length&&u.every(a=>/^locations\[\d+\]$/.test(a))?["$"]:u}}})}function me(e){return x(e),fe("locations.v1",(n,t)=>H(n,t,e))}function ge(e){return x(e),fe("locations.business.v1",(n,t)=>B(n,t,e))}function Ge(e,n,t){let o=`${e}-${n.normalize("NFKD").toLowerCase().replace(/[^a-z0-9]+/g,"-").replace(/^-|-$/g,"")||"stop"}`,r=o;for(let s=2;t.has(r);s++)r=`${o}-${s}`;return t.add(r),r}function z(e,n){if(!w(e)||!ze(e,"schedule")||e._id!=="schedule"||e.timeZone!==n.timeZone||!Array.isArray(e.days)||e.days.length!==7)throw new TypeError("Invalid schedule document");let t=e.days.map((o,r)=>{if(!w(o)||o.day!==Ve[r]||typeof o.rest!="boolean"||!Array.isArray(o.stops))throw new TypeError("Invalid schedule day");let s=o.day,u=o.rest,y=o.stops,a=n.days.find(d=>d.day===s),p=new Set(a?.stops.map(d=>d.id)??[]),i=new Set,c=y.map(d=>{if(!w(d))throw new TypeError("Invalid schedule stop");let l=d;if(!h(l.name)||!ae.test(String(l.from??""))||!ae.test(String(l.to??""))||!h(l.address))throw new TypeError("Invalid schedule stop");let m=a?.stops.find(k=>k.name===l.name&&!i.has(k.id));return m?(i.add(m.id),{...m,name:String(l.name),from:String(l.from),to:String(l.to),address:String(l.address)}):{id:Ge(s,String(l.name),p),name:String(l.name),from:String(l.from),to:String(l.to),address:String(l.address),place:null,postcode:null,notes:null,lat:null,lng:null,coordinateSource:null,approximate:!1,needsConfirmation:null,captured:`${l.name}
|
|
6
|
-
${
|
|
7
|
-
${
|
|
5
|
+
}}}`;function V(e,n){return S(e,{types:["menu"],...n===void 0?{}:{ids:[n]}})}function f(e,n){throw new R("menu",[`${e} ${n}`])}function Z(e,n,t=new Set,o){if(e===null||typeof e=="string"||typeof e=="boolean"||typeof e=="number"&&Number.isFinite(e))return e;if(typeof e!="object"||e===null)return f(n,"is not plain JSON data");try{if(t.has(e))return f(n,"is not acyclic JSON data");let r=Array.isArray(e),s=Object.getPrototypeOf(e);if(r?s!==Array.prototype:s!==Object.prototype&&s!==null)return f(n,"is not an ordinary saved object");t.add(e);let u=Reflect.ownKeys(e),d=r?[]:{},i=0,p=0;for(let l of u){if(typeof l!="string")return f(n,"has a symbol key");let c=r&&l!=="length"?`${n}[${l}]`:`${n}.${l}`,y;try{y=l==="_id"&&o!==void 0?o:Object.getOwnPropertyDescriptor(e,l)}catch{return f(c,"could not be snapshotted as plain JSON data")}if(!y||!Object.hasOwn(y,"value"))return f(c,"is not a saved data property");if(r&&l==="length"){let k=y.value;if(typeof k!="number"||!Number.isSafeInteger(k)||k<0)return f(c,"is not a saved list length");i=k;continue}if(!y.enumerable||r&&!/^(0|[1-9]\d*)$/.test(l))return f(c,"is not a JSON data property");let a=y.value,m=Z(a,c,t);Object.defineProperty(d,l,{value:m,enumerable:!0,writable:!0,configurable:!0}),p++}return r&&(p!==i||d.length!==i)?f(n,"is not a complete saved list"):d}catch(r){if(r instanceof R)throw r;return f(n,"could not be snapshotted as plain JSON data")}finally{t.delete(e)}}function A(e,n){return e===null||typeof e!="object"||Array.isArray(e)||Object.getPrototypeOf(e)!==Object.prototype&&Object.getPrototypeOf(e)!==null?f(n,"is not an ordinary saved object"):e}function g(e,n,t=!0){return typeof e!="string"||t&&e.trim()===""?f(n,"is not saved text"):e}function C(e,n,t){return e[n]===void 0||e[n]===null?{}:{[n]:g(e[n],`${t}.${n}`,!1)}}function T(e,n,t){return e==null?[]:Q(e)?e.map((o,r)=>t(o,`${n}[${String(r)}]`)):f(n,"is not a complete saved list")}function J(e,n){let t=A(e,n);if(typeof t.minor!="number"||!Number.isSafeInteger(t.minor)||t.minor<0)return f(`${n}.minor`,"is not a whole non-negative safe amount");let o=g(t.currency,`${n}.currency`);return/^[A-Z]{3}$/.test(o)?{minor:t.minor,currency:o}:f(`${n}.currency`,"is not a three-letter currency code")}function Ae(e,n){let t=A(e,n);return{_key:g(t._key,`${n}._key`),amount:J(t.amount,`${n}.amount`),...C(t,"label",n)}}function Re(e,n){let t=A(e,n);return{_key:g(t._key,`${n}._key`),name:g(t.name,`${n}.name`),amount:J(t.amount,`${n}.amount`)}}function Ee(e,n){let t=A(e,n),o=t.availability??"available";return o!=="available"&&o!=="sold-out"&&o!=="hidden"?f(`${n}.availability`,"is not an availability choice"):{_key:g(t._key,`${n}._key`),name:g(t.name,`${n}.name`),...C(t,"description",n),...C(t,"priceNote",n),...C(t,"allergenNote",n),prices:T(t.prices,`${n}.prices`,Ae),extras:T(t.extras,`${n}.extras`,Re),dietary:T(t.dietary,`${n}.dietary`,g),availability:o}}function xe(e,n){let t=A(e,n);return{_key:g(t._key,`${n}._key`),title:g(t.title,`${n}.title`),...C(t,"service",n),items:T(t.items,`${n}.items`,Ee)}}function Ie(e,n){let t=A(e,n);return{_key:g(t._key,`${n}._key`),label:g(t.label,`${n}.label`),...C(t,"note",n),sections:T(t.sections,`${n}.sections`,xe)}}function Oe(e){if(e===null||typeof e!="object"||Array.isArray(e))return!1;let n=e._id;return typeof n=="string"&&n.trim()!==""&&!/^(drafts|versions)\./.test(n)}function I(e,n="menu"){return De(Z(e,n),n)}function De(e,n){let t=A(e,n);if(t._type!=="menu")return f(`${n}._type`,"is not menu");if(!Oe(t))return f(`${n}._id`,"is not a published menu identity");let o=g(t._updatedAt,`${n}._updatedAt`);if(!/^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}(?:\.\d+)?(?:Z|[+-]\d{2}:\d{2})$/.test(o)||!Number.isFinite(Date.parse(o)))return f(`${n}._updatedAt`,"is not an update date");let r=T(t.variants,`${n}.variants`,Ie);return r.length===0?f(`${n}.variants`,"has no menu choices"):{_type:"menu",_id:g(t._id,`${n}._id`),_rev:g(t._rev,`${n}._rev`),_updatedAt:o,title:g(t.title,`${n}.title`),locationKeys:T(t.locationKeys,`${n}.locationKeys`,g),variants:r,...C(t,"note",n),...Object.hasOwn(t,"signOff")?{signOff:t.signOff}:{}}}function W(e){if(e===null)return!0;try{return I(e),!0}catch{return!1}}var Y="malformed-content",R=class extends Error{code=Y;documentId;problems;constructor(n,t){super(`${Y}: ${n}: ${t.join("; ")}`),this.name="MalformedContentError",this.documentId=n,this.problems=t}};var G=`{..., "sections": coalesce(sections[]{..., _type == "menuBlock" => {menu->{${L}}}, _type == "linkListBlock" => {links[]{..., "page": page->{title, "slug": slug.current}}}}, sections)}`,un=`*[_type == "page" && defined(slug.current)]|order(slug.current asc)${G}`,cn=`*[_type == "page" && slug.current == $slug][0]${G}`;var Me=/^[A-Za-z][A-Za-z0-9_]{0,63}$/,ve=/^[A-Za-z0-9][A-Za-z0-9._-]{0,127}$/,Le=/^[a-z0-9]{6,12}\.[a-z][a-z0-9_-]{0,63}$/;function K(e){if(!e||!Array.isArray(e.types)||e.types.length===0)throw new TypeError("CMS dependencies require document types");let n=[...e.types];for(let o of n)if(typeof o!="string"||!Me.test(o))throw new TypeError("Invalid CMS document type");if(e.ids!==void 0&&!Array.isArray(e.ids))throw new TypeError("Invalid CMS document IDs");let t=e.ids===void 0?void 0:[...e.ids];for(let o of t??[])if(typeof o!="string"||!ve.test(o)||/^(drafts|versions)\./.test(o))throw new TypeError("Invalid CMS document ID");if(new Set(n).size+new Set(t).size>128)throw new TypeError("Too many CMS tags");return Object.freeze({types:Object.freeze(n),...t===void 0?{}:{ids:Object.freeze(t)}})}function E(e){if(!e||typeof e.name!="string"||!/^[A-Za-z][A-Za-z0-9_.-]{0,127}$/.test(e.name)||typeof e.query!="string"||e.query.trim()===""||typeof e.resolve!="function")throw new TypeError("Invalid CMS query configuration");let n=e.params;if(!n||typeof n!="object"||Object.getPrototypeOf(n)!==Object.prototype&&Object.getPrototypeOf(n)!==null)throw new TypeError("CMS params must be plain JSON scalars");let t={};for(let o of Reflect.ownKeys(n)){let r=Object.getOwnPropertyDescriptor(n,o);if(typeof o!="string"||!r||!Object.hasOwn(r,"value")||!r.enumerable)throw new TypeError("CMS params must be plain JSON scalars");let s=r.value;if(!(s===null||typeof s=="string"||typeof s=="boolean"||typeof s=="number"&&Number.isFinite(s)))throw new TypeError("CMS params must be plain JSON scalars");Object.defineProperty(t,o,{value:s,enumerable:!0})}return Object.freeze({name:e.name,query:e.query,params:Object.freeze(t),dependencies:K(e.dependencies),resolve:e.resolve})}function S(e,n){if(typeof e!="string"||e.length>77||!Le.test(e))throw new TypeError("Invalid CMS scope");let t=K(n),o=[...[...new Set(t.types)].sort().map(r=>`cms:${e}:type:${r}`),...[...new Set(t.ids??[])].sort().map(r=>`cms:${e}:id:${r}`)];return Object.freeze(o)}function X(e){return E({name:"menu.v1",query:`*[_type == "menu" && _id == $id && !(_id in path("drafts.**")) && !(_id in path("versions.**"))][0]{${L}}`,params:{id:e},dependencies:{types:["menu"],ids:[e]},resolve:(n,t)=>{if(!W(t)||t!==null&&t._id!==e)throw new TypeError("Invalid CMS menu fallback");if(n==null)return{data:t,fallbackFields:["$"]};let o=I(n);if(o._id!==e)throw new R("menu",["menu._id does not match the requested document"]);return{data:o,fallbackFields:[]}}})}function ee(e){if(!e||!Object.hasOwn(e,"data")||!Array.isArray(e.fallbackFields)||![...e.fallbackFields].every(n=>typeof n=="string"&&(n==="$"||/^[A-Za-z][A-Za-z0-9_.[\]-]{0,127}$/.test(n))))throw new TypeError("Invalid CMS resolution");if(e.warnings!==void 0&&(!Array.isArray(e.warnings)||![...e.warnings].every(n=>n==="siteHero.layout.defaulted"||n==="siteHero.tagline.dropped"||n==="siteHero.taglines.defaulted")))throw new TypeError("Invalid CMS resolution warnings");return{data:e.data,fallbackFields:Object.freeze([...new Set(e.fallbackFields)]),...e.warnings?.length?{warnings:Object.freeze([...new Set(e.warnings)])}:{}}}function ne(e){let n=e?.revalidateSeconds??3600;if(!Number.isSafeInteger(n)||n<3600||!e?.adapter||typeof e.adapter.read!="function"||e.onDiagnostic!==void 0&&typeof e.onDiagnostic!="function")throw new TypeError("Invalid CMS reader configuration");let t=e.adapter;S(t.scope,{types:["ScopeValidation"]});let o=r=>{try{e.onDiagnostic?e.onDiagnostic(r):console.warn(JSON.stringify(r))}catch{}};return{async read(r,s){let u,d,i;try{if(u=E(r),i=S(t.scope,u.dependencies),!s||!Object.hasOwn(s,"fallback"))throw new TypeError;d=ee(u.resolve(null,s.fallback))}catch{throw new TypeError("Invalid CMS query or fallback configuration")}let p=(y,a,m)=>(o({event:"cms.fallback",query:u.name,reason:y,fields:["$"],...a===void 0?{}:{status:a},...m?{warnings:m}:{}}),{data:d.data,source:"fallback",fallbackFields:["$"],reason:y,...m?{warnings:m}:{}}),l;try{l=await t.read({name:u.name,query:u.query,params:u.params},{tags:i,revalidateSeconds:n})}catch{return p("network")}if(!l.ok){let a=["configuration","network","timeout","rate-limit","upstream","plan-limit","permission","malformed"].includes(l.reason)?l.reason:"malformed",m=Number.isInteger(l.status)&&(l.status??0)>=100&&(l.status??0)<=599?l.status:void 0;return p(a,m)}if(l.value===null||l.value===void 0)return p("missing");let c;try{c=ee(u.resolve(l.value,s.fallback))}catch{return p("malformed")}return c.fallbackFields.includes("$")?{...p("invalid-field",void 0,c.warnings),data:c.data}:c.fallbackFields.length>0?(o({event:"cms.partial-fallback",query:u.name,reason:"invalid-field",fields:c.fallbackFields,...c.warnings?{warnings:c.warnings}:{}}),{...c,source:"mixed",reason:"invalid-field"}):{...c,source:"cms"}}}}var te=ne;var ie=require("next/cache.js");var N="sanity-webhook-signature",je=/^t=(\d+)[, ]+v1=([^, ]+)$/;var oe=new TextEncoder;function Pe(e){return crypto.subtle.importKey("raw",oe.encode(e),{name:"HMAC",hash:"SHA-256"},!1,["sign","verify"])}function Ne(e){if(!/^[A-Za-z0-9_-]+={0,2}$/.test(e))return null;let n=e.replace(/-/g,"+").replace(/_/g,"/");try{let t=atob(n),o=new Uint8Array(t.length);for(let r=0;r<t.length;r+=1)o[r]=t.charCodeAt(r);return o}catch{return null}}async function re(e){let{secret:n,rawBody:t,headers:o}=e,r=e.now??Date.now(),s=e.toleranceMs??3e5;if(!n||n.length===0)return{ok:!1,reason:"no-secret"};let u=o.get(N);if(!u)return{ok:!1,reason:"no-signature"};let d=je.exec(u.trim());if(d===null)return{ok:!1,reason:"malformed-signature"};let i=Number(d[1]),p=d[2]??"";if(!Number.isSafeInteger(i))return{ok:!1,reason:"malformed-signature"};if(i<16094592e5)return{ok:!1,reason:"stale-timestamp"};if(Math.abs(r-i)>s)return{ok:!1,reason:"stale-timestamp"};let l=Ne(p);if(l===null)return{ok:!1,reason:"malformed-signature"};let c=await Pe(n);return await crypto.subtle.verify("HMAC",c,l,oe.encode(`${i}.${t}`))?{ok:!0}:{ok:!1,reason:"bad-signature"}}var Ue=16*1024,Fe=1500,qe=new TextEncoder;function b(e,n,t={},o=!1){return new Response(o?null:JSON.stringify(n),{status:e,headers:{"Content-Type":"application/json","Cache-Control":"no-store",...t}})}function He(e,n){if(!n||typeof n!="object"||Array.isArray(n)||Object.keys(n).length===0)throw new TypeError("Invalid CMS invalidation mapping");let t=Object.create(null);for(let o of Reflect.ownKeys(n)){let r=Object.getOwnPropertyDescriptor(n,o);if(typeof o!="string"||!r?.enumerable||!Object.hasOwn(r,"value"))throw new TypeError("Invalid CMS invalidation mapping");let s=r.value;if(!Array.isArray(s)||!s.includes(o))throw new TypeError("Invalid CMS invalidation mapping");S(e,{types:s,ids:["validation"]}),t[o]=Object.freeze([...s])}for(let o of Object.values(t))if(o.some(r=>!Object.hasOwn(t,r)))throw new TypeError("Invalid CMS invalidation mapping");return Object.freeze(t)}function se(e){return typeof e=="string"&&e.trim()!==""&&qe.encode(e).byteLength>=32}var O=class extends Error{constructor(t){super("Invalid CMS webhook body");this.status=t}status};async function Be(e){let n=e.body?.getReader();if(!n)return"";let t=new TextDecoder("utf-8",{fatal:!0,ignoreBOM:!0}),o,r=new Promise((s,u)=>{o=setTimeout(()=>u(new O(400)),Fe)});try{let s=0,u="";for(;;){let{done:d,value:i}=await Promise.race([n.read(),r]);if(d)return u+t.decode();if(s+=i.byteLength,s>Ue)throw new O(413);u+=t.decode(i,{stream:!0})}}catch(s){throw n.cancel().catch(()=>{}),s}finally{clearTimeout(o),n.releaseLock()}}function le(e){let n=e.scope,t=He(n,e.typeToTags),o=e.secretEnv??"SANITY_REVALIDATE_SECRET",r=e.previousSecretEnv??"SANITY_REVALIDATE_SECRET_PREVIOUS",s=e.env??(()=>process.env),u=e.now??Date.now,d=async i=>{if(i.method!=="POST")return b(405,{error:"Method not allowed"},{Allow:"POST"},i.method==="HEAD");let p,l;try{let w=s(),j=w[o],_=w[r];if(!se(j)||_!==void 0&&!se(_))throw new Error;p=j,l=_}catch{return b(503,{error:"COULD NOT ANSWER: revalidation configuration unavailable"})}let c=i.headers.get(N);if(!c||c.length>512||!/^t=\d+[, ]+v1=[A-Za-z0-9_-]+={0,2}$/.test(c.trim()))return b(401,{error:"Unauthorized"});let y;try{y=await Be(i)}catch(w){return w instanceof O&&w.status===413?b(413,{error:"Payload too large"}):b(400,{error:"Invalid body"})}try{let w=u();if(!Number.isFinite(w))throw new Error;if(!(await Promise.all([p,...l===void 0?[]:[l]].map(_=>re({secret:_,rawBody:y,headers:i.headers,now:w})))).some(_=>_.ok))return b(401,{error:"Unauthorized"})}catch{return b(401,{error:"Unauthorized"})}let a;try{a=JSON.parse(y)}catch{return b(400,{error:"Invalid payload"})}if(!a||typeof a!="object"||Array.isArray(a)||Object.keys(a).length!==2||!Object.hasOwn(a,"_type")||!Object.hasOwn(a,"_id"))return b(400,{error:"Invalid payload"});let{_type:m,_id:k}=a;if(typeof m!="string"||!/^[A-Za-z][A-Za-z0-9_]{0,63}$/.test(m)||typeof k!="string"||!/^[A-Za-z0-9][A-Za-z0-9._-]{0,127}$/.test(k))return b(400,{error:"Invalid payload"});if(!Object.hasOwn(t,m)||/^(drafts|versions)\./.test(k))return b(400,{error:"Unsupported document"});let ke=S(n,{types:t[m],ids:[k]});try{for(let w of ke)(0,ie.revalidateTag)(w,{expire:0})}catch{return b(500,{error:"Could not revalidate"})}return b(200,{revalidated:!0})};return Object.freeze({POST:d,GET:d,HEAD:d,PUT:d,PATCH:d,DELETE:d,OPTIONS:d})}var $=e=>e!==null&&typeof e=="object"&&!Array.isArray(e),h=e=>typeof e=="string"&&e.trim()?e.trim():null,ze=(e,n)=>e._type===n&&typeof e._id=="string"&&e._id.length>0&&!/^(drafts|versions)\./.test(e._id),Qe=/^\d{4}-\d{2}-\d{2}$/,ae=/^([01]\d|2[0-3]):[0-5]\d$/,Ve=["mon","tue","wed","thu","fri","sat","sun"];async function ue(e,n,t){try{let o=await e.read(n,{fallback:t});return{...o,source:o.source==="cms"?"sanity":o.source}}catch{return{data:t,source:"fallback",fallbackFields:["$"],reason:"configuration"}}}var Ze=/^[A-Za-z0-9._+-]{1,64}@[A-Za-z0-9-]{1,63}(?:\.[A-Za-z0-9-]{1,63})*\.[A-Za-z]{2,63}$/;function Je(e){let n=h(e);if(!n)return null;try{let t=new URL(n);return t.protocol==="http:"||t.protocol==="https:"?t.href:null}catch{return null}}function x(e){if(typeof e!="function")throw new TypeError("A client validator is required")}function U(e,n,t){if(x(t),!$(e)||e.status!=="open")return null;let o=h(e.closingDate);if(o!==null&&o<n||t(e)!==null)return null;let r=h(e.title),s=$(e.workLocation)?e.workLocation:null,u=h(e.location),d=h(s?.name)??(u==="Other"?null:u)??h(e.locationNote);if(!r||!d)return null;let i=h(e.pdfUrl);return{id:String(h(e._id)),title:r,location:d,locationId:s===null?null:h(s._id),summary:h(e.summary),pdfUrl:i?.startsWith("https://cdn.sanity.io/files/")?i:null,applyUrl:Je(e.applyUrl),applyEmail:typeof e.applyEmail=="string"&&e.applyEmail.length<=254&&Ze.test(e.applyEmail)?e.applyEmail:null}}function F(e,n,t){if(x(t),!Array.isArray(e))throw new TypeError("Sanity returned vacancies that are not a list");return e.map(o=>({value:U(o,n,t),order:$(o)&&typeof o.order=="number"&&Number.isFinite(o.order)?o.order:1e6})).filter(o=>o.value!==null).sort((o,r)=>o.order-r.order||o.value.title.toLowerCase().localeCompare(r.value.title.toLowerCase())).map(o=>o.value)}function ce(e){return S(e,{types:["vacancy","location"]})}function de(e,n){if(!Qe.test(e))throw new TypeError("Invalid calendar date");return x(n),E({name:"vacancy.open.v2",query:'*[_type == "vacancy" && status == "open" && !(_id in path("drafts.**")) && !(_id in path("versions.**")) && (!defined(closingDate) || closingDate >= $today)]|order(coalesce(order, 1000000) asc, lower(title) asc){_id, _type, title, "workLocation": workLocation->{_id, name}, location, locationNote, summary, "pdfUrl": jobDescriptionPdf.asset->url, applyUrl, applyEmail, status, closingDate, order}',params:{today:e},dependencies:{types:["vacancy","location"]},resolve:(t,o)=>({data:t==null?o:F(t,e,n),fallbackFields:t==null?["$"]:[]})})}var We=["monday","tuesday","wednesday","thursday","friday","saturday","sunday"],Ye=/^[a-z0-9]+(?:-[a-z0-9]+)*$/;function q(e){return!$(e)||typeof e._id!="string"||!$(e.slug)||typeof e.slug.current!="string"||!Ye.test(e.slug.current)||h(e.name)===null||e.addressLines!==void 0&&e.addressLines!==null&&(!Array.isArray(e.addressLines)||Array.from(e.addressLines).some(n=>h(n)===null))||e.postcode!==void 0&&e.postcode!==null&&h(e.postcode)===null||e.coordinates!==void 0&&e.coordinates!==null&&(!$(e.coordinates)||typeof e.coordinates.lat!="number"||!Number.isFinite(e.coordinates.lat)||typeof e.coordinates.lng!="number"||!Number.isFinite(e.coordinates.lng))||e.phone!==void 0&&e.phone!==null&&typeof e.phone!="string"||e.email!==void 0&&e.email!==null&&typeof e.email!="string"?null:{name:h(e.name),slug:e.slug.current,addressLines:e.addressLines==null?e.addressLines:e.addressLines.map(n=>n.trim()),postcode:e.postcode==null?e.postcode:String(e.postcode).trim(),coordinates:e.coordinates==null?e.coordinates:{lat:e.coordinates.lat,lng:e.coordinates.lng},phone:e.phone,email:e.email,hours:e.hours}}function ye(e){if(!$(e))return null;let n={};for(let t of We){let o=e[t];if(!Array.isArray(o)||!Array.from(o).every(r=>$(r)&&typeof r.opens=="string"&&typeof r.closes=="string"))return null;n[t]=o.map(r=>({opens:r.opens,closes:r.closes}))}return n}function H(e,n,t){x(t);let o=q(e);if(o===null||o.slug!==n.id)return{data:n,fallbackFields:["$"]};let r=ye(o.hours),s={id:n.id,label:o.name,addressLines:o.addressLines??n.addressLines,postcode:o.postcode??n.postcode,geo:o.coordinates==null?n.geo:{latitude:o.coordinates.lat,longitude:o.coordinates.lng},telephone:o.phone===void 0?n.telephone:o.phone,email:o.email===void 0?n.email:o.email,hours:r??n.hours};try{return{data:t(s),fallbackFields:r===null?["hours"]:[]}}catch{if(r!==null)try{return{data:t({...s,hours:n.hours}),fallbackFields:["hours"]}}catch{}return{data:n,fallbackFields:["$"]}}}function B(e,n,t){x(t);let o=q(e);if(o===null||o.slug!==n.id)return{data:n,fallbackFields:["$"]};let r=ye(o.hours),s={...n,label:o.name,address:n.address===null?null:{...n.address,streetAddress:o.addressLines??n.address.streetAddress,postalCode:o.postcode??n.address.postalCode},telephone:o.phone===void 0?n.telephone:o.phone,email:o.email===void 0?n.email:o.email,geo:o.coordinates==null?n.geo:{latitude:o.coordinates.lat,longitude:o.coordinates.lng},hours:r??n.hours};try{return{data:t(s),fallbackFields:r===null?["hours"]:[]}}catch{if(r!==null)try{return{data:t({...s,hours:n.hours}),fallbackFields:["hours"]}}catch{}return{data:n,fallbackFields:["$"]}}}function pe(e){return S(e,{types:["location"]})}function fe(e,n){return E({name:e,query:'*[_type == "location" && defined(slug.current) && !(_id in path("drafts.**")) && !(_id in path("versions.**"))]{_id, _type, name, slug, addressLines, postcode, coordinates, phone, email, hours}',params:{},dependencies:{types:["location"]},resolve:(t,o)=>{if(!Array.isArray(t))return{data:o,fallbackFields:["$"]};let r=new Map,s=new Set;for(let i of t){let p=q(i);p!==null&&(r.has(p.slug)?s.add(p.slug):r.set(p.slug,i))}let u=[];return{data:o.map((i,p)=>{let l=r.get(i.id),c=l===void 0||s.has(i.id)?{data:i,fallbackFields:["$"]}:n(l,i);return u.push(...c.fallbackFields.map(y=>y==="$"?`locations[${p}]`:`locations[${p}].${y}`)),c.data}),fallbackFields:o.length>0&&u.length===o.length&&u.every(i=>/^locations\[\d+\]$/.test(i))?["$"]:u}}})}function me(e){return x(e),fe("locations.v1",(n,t)=>H(n,t,e))}function ge(e){return x(e),fe("locations.business.v1",(n,t)=>B(n,t,e))}function Ge(e,n,t){let o=`${e}-${n.normalize("NFKD").toLowerCase().replace(/[^a-z0-9]+/g,"-").replace(/^-|-$/g,"")||"stop"}`,r=o;for(let s=2;t.has(r);s++)r=`${o}-${s}`;return t.add(r),r}function z(e,n){if(!$(e)||!ze(e,"schedule")||e._id!=="schedule"||e.timeZone!==n.timeZone||!Array.isArray(e.days)||e.days.length!==7)throw new TypeError("Invalid schedule document");let t=e.days.map((o,r)=>{if(!$(o)||o.day!==Ve[r]||typeof o.rest!="boolean"||!Array.isArray(o.stops))throw new TypeError("Invalid schedule day");let s=o.day,u=o.rest,d=o.stops,i=n.days.find(y=>y.day===s),p=new Set(i?.stops.map(y=>y.id)??[]),l=new Set,c=d.map(y=>{if(!$(y))throw new TypeError("Invalid schedule stop");let a=y;if(!h(a.name)||!ae.test(String(a.from??""))||!ae.test(String(a.to??""))||!h(a.address))throw new TypeError("Invalid schedule stop");let m=i?.stops.find(k=>k.name===a.name&&!l.has(k.id));return m?(l.add(m.id),{...m,name:String(a.name),from:String(a.from),to:String(a.to),address:String(a.address)}):{id:Ge(s,String(a.name),p),name:String(a.name),from:String(a.from),to:String(a.to),address:String(a.address),place:null,postcode:null,notes:null,lat:null,lng:null,coordinateSource:null,approximate:!1,needsConfirmation:null,captured:`${a.name}
|
|
6
|
+
${a.from}-${a.to}
|
|
7
|
+
${a.address}`}});return{day:s,rest:u,stops:u?[]:c}});return{timeZone:n.timeZone,days:t}}function he(e){return S(e,{types:["schedule"],ids:["schedule"]})}function be(){return E({name:"schedule.v1",query:'*[_type == "schedule" && _id == "schedule" && !(_id in path("drafts.**")) && !(_id in path("versions.**"))][0]{_id, _type, timeZone, days}',params:{},dependencies:{types:["schedule"],ids:["schedule"]},resolve:(e,n)=>({data:e==null?n:z(e,n),fallbackFields:e==null?["$"]:[]})})}0&&(module.exports={MENU_DECORATIONS,MENU_LAYOUTS,MENU_LAYOUT_DEFAULTS,businessLocationsQuery,createNextCmsReader,createRevalidateRoute,locationTags,locationsQuery,menuQuery,menuTags,openVacanciesQuery,parseBusinessLocation,parseLocationDocument,parseMenuDocument,parseScheduleDocument,parseVacancies,parseVacancyDocument,resolveWithFallback,scheduleQuery,scheduleTags,vacancyTags});
|
|
8
8
|
//# sourceMappingURL=next.cjs.map
|