@weatherboard/cms 0.0.0-stage → 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (100) hide show
  1. package/dist/adapters/next/reader.d.cts +2 -0
  2. package/dist/adapters/next/reader.d.mts +2 -0
  3. package/dist/adapters/next/reader.d.ts +2 -0
  4. package/dist/adapters/sanity/adapter.d.cts +15 -0
  5. package/dist/adapters/sanity/adapter.d.mts +15 -0
  6. package/dist/adapters/sanity/adapter.d.ts +15 -0
  7. package/dist/contracts/query.d.cts +19 -0
  8. package/dist/contracts/query.d.mts +19 -0
  9. package/dist/contracts/query.d.ts +19 -0
  10. package/dist/contracts/text.d.cts +40 -0
  11. package/dist/contracts/text.d.mts +40 -0
  12. package/dist/contracts/text.d.ts +40 -0
  13. package/dist/guard.cjs +3 -0
  14. package/dist/guard.cjs.map +7 -0
  15. package/dist/guard.d.cts +2 -0
  16. package/dist/guard.d.mts +2 -0
  17. package/dist/guard.d.ts +2 -0
  18. package/dist/guard.mjs +3 -0
  19. package/dist/guard.mjs.map +7 -0
  20. package/dist/index.cjs +2 -0
  21. package/dist/index.cjs.map +7 -0
  22. package/dist/index.d.cts +4 -0
  23. package/dist/index.d.mts +4 -0
  24. package/dist/index.d.ts +4 -0
  25. package/dist/index.mjs +2 -0
  26. package/dist/index.mjs.map +7 -0
  27. package/dist/invalidation/route.d.cts +12 -0
  28. package/dist/invalidation/route.d.mts +12 -0
  29. package/dist/invalidation/route.d.ts +12 -0
  30. package/dist/next.cjs +2 -0
  31. package/dist/next.cjs.map +7 -0
  32. package/dist/next.d.cts +4 -0
  33. package/dist/next.d.mts +4 -0
  34. package/dist/next.d.ts +4 -0
  35. package/dist/next.mjs +2 -0
  36. package/dist/next.mjs.map +7 -0
  37. package/dist/portable/array.d.cts +2 -0
  38. package/dist/portable/array.d.mts +2 -0
  39. package/dist/portable/array.d.ts +2 -0
  40. package/dist/portable/fallback.d.cts +4 -0
  41. package/dist/portable/fallback.d.mts +4 -0
  42. package/dist/portable/fallback.d.ts +4 -0
  43. package/dist/portable/site-content.d.cts +220 -0
  44. package/dist/portable/site-content.d.mts +220 -0
  45. package/dist/portable/site-content.d.ts +220 -0
  46. package/dist/portable/webhook.d.cts +133 -0
  47. package/dist/portable/webhook.d.mts +133 -0
  48. package/dist/portable/webhook.d.ts +133 -0
  49. package/dist/runtime/reader.d.cts +49 -0
  50. package/dist/runtime/reader.d.mts +49 -0
  51. package/dist/runtime/reader.d.ts +49 -0
  52. package/dist/sanity.cjs +2 -0
  53. package/dist/sanity.cjs.map +7 -0
  54. package/dist/sanity.d.cts +3 -0
  55. package/dist/sanity.d.mts +3 -0
  56. package/dist/sanity.d.ts +3 -0
  57. package/dist/sanity.mjs +2 -0
  58. package/dist/sanity.mjs.map +7 -0
  59. package/dist/server.cjs +2 -0
  60. package/dist/server.cjs.map +7 -0
  61. package/dist/server.d.cts +3 -0
  62. package/dist/server.d.mts +3 -0
  63. package/dist/server.d.ts +3 -0
  64. package/dist/server.mjs +2 -0
  65. package/dist/server.mjs.map +7 -0
  66. package/dist/site-content.cjs +7 -0
  67. package/dist/site-content.cjs.map +7 -0
  68. package/dist/site-content.d.cts +2 -0
  69. package/dist/site-content.d.mts +2 -0
  70. package/dist/site-content.d.ts +2 -0
  71. package/dist/site-content.mjs +7 -0
  72. package/dist/site-content.mjs.map +7 -0
  73. package/dist/testing.cjs +2 -0
  74. package/dist/testing.cjs.map +7 -0
  75. package/dist/testing.d.cts +2 -0
  76. package/dist/testing.d.mts +2 -0
  77. package/dist/testing.d.ts +2 -0
  78. package/dist/testing.mjs +2 -0
  79. package/dist/testing.mjs.map +7 -0
  80. package/dist/tooling/guard.d.cts +13 -0
  81. package/dist/tooling/guard.d.mts +13 -0
  82. package/dist/tooling/guard.d.ts +13 -0
  83. package/dist/tooling/test-fixtures/break-proof.d.cts +1 -0
  84. package/dist/tooling/test-fixtures/break-proof.d.mts +1 -0
  85. package/dist/tooling/test-fixtures/break-proof.d.ts +1 -0
  86. package/dist/tooling/test-fixtures/consumer.d.cts +9 -0
  87. package/dist/tooling/test-fixtures/consumer.d.mts +9 -0
  88. package/dist/tooling/test-fixtures/consumer.d.ts +9 -0
  89. package/dist/tooling/testing.d.cts +10 -0
  90. package/dist/tooling/testing.d.mts +10 -0
  91. package/dist/tooling/testing.d.ts +10 -0
  92. package/dist/webhook.cjs +2 -0
  93. package/dist/webhook.cjs.map +7 -0
  94. package/dist/webhook.d.cts +2 -0
  95. package/dist/webhook.d.mts +2 -0
  96. package/dist/webhook.d.ts +2 -0
  97. package/dist/webhook.mjs +2 -0
  98. package/dist/webhook.mjs.map +7 -0
  99. package/package.json +113 -3
  100. package/README.md +0 -3
@@ -0,0 +1,3 @@
1
+ import "server-only";
2
+ export { createCmsReader } from "./runtime/reader.js";
3
+ export type { CmsFailure, CmsDiagnostic, CmsFetch, CmsReadPolicy, CmsAdapterResult, CmsAdapter, CmsReadResult, CmsReaderOptions, CmsReader, } from "./runtime/reader.js";
@@ -0,0 +1,2 @@
1
+ import"server-only";var w=/^[A-Za-z][A-Za-z0-9_]{0,63}$/,T=/^[A-Za-z0-9][A-Za-z0-9._-]{0,127}$/,R=/^[a-z0-9]{6,12}\.[a-z][a-z0-9_-]{0,63}$/;function f(e){if(!e||!Array.isArray(e.types)||e.types.length===0)throw new TypeError("CMS dependencies require document types");let r=[...e.types];for(let t of r)if(typeof t!="string"||!w.test(t))throw new TypeError("Invalid CMS document type");if(e.ids!==void 0&&!Array.isArray(e.ids))throw new TypeError("Invalid CMS document IDs");let a=e.ids===void 0?void 0:[...e.ids];for(let t of a??[])if(typeof t!="string"||!T.test(t)||/^(drafts|versions)\./.test(t))throw new TypeError("Invalid CMS document ID");if(new Set(r).size+new Set(a).size>128)throw new TypeError("Too many CMS tags");return Object.freeze({types:Object.freeze(r),...a===void 0?{}:{ids:Object.freeze(a)}})}function C(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 r=e.params;if(!r||typeof r!="object"||Object.getPrototypeOf(r)!==Object.prototype&&Object.getPrototypeOf(r)!==null)throw new TypeError("CMS params must be plain JSON scalars");let a={};for(let t of Reflect.ownKeys(r)){let n=Object.getOwnPropertyDescriptor(r,t);if(typeof t!="string"||!n||!Object.hasOwn(n,"value")||!n.enumerable)throw new TypeError("CMS params must be plain JSON scalars");let s=n.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(a,t,{value:s,enumerable:!0})}return Object.freeze({name:e.name,query:e.query,params:Object.freeze(a),dependencies:f(e.dependencies),resolve:e.resolve})}function y(e,r){if(typeof e!="string"||e.length>77||!R.test(e))throw new TypeError("Invalid CMS scope");let a=f(r),t=[...[...new Set(a.types)].sort().map(n=>`cms:${e}:type:${n}`),...[...new Set(a.ids??[])].sort().map(n=>`cms:${e}:id:${n}`)];return Object.freeze(t)}function g(e){if(!e||!Object.hasOwn(e,"data")||!Array.isArray(e.fallbackFields)||![...e.fallbackFields].every(r=>typeof r=="string"&&(r==="$"||/^[A-Za-z][A-Za-z0-9_.[\]-]{0,127}$/.test(r))))throw new TypeError("Invalid CMS resolution");return{data:e.data,fallbackFields:Object.freeze([...new Set(e.fallbackFields)])}}function k(e){let r=e?.revalidateSeconds??3600;if(!Number.isSafeInteger(r)||r<3600||!e?.adapter||typeof e.adapter.read!="function"||e.onDiagnostic!==void 0&&typeof e.onDiagnostic!="function")throw new TypeError("Invalid CMS reader configuration");let a=e.adapter;y(a.scope,{types:["ScopeValidation"]});let t=n=>{try{e.onDiagnostic?e.onDiagnostic(n):console.warn(JSON.stringify(n))}catch{}};return{async read(n,s){let i,u,p;try{if(i=C(n),p=y(a.scope,i.dependencies),!s||!Object.hasOwn(s,"fallback"))throw new TypeError;u=g(i.resolve(null,s.fallback))}catch{throw new TypeError("Invalid CMS query or fallback configuration")}let d=(c,m)=>(t({event:"cms.fallback",query:i.name,reason:c,fields:["$"],...m===void 0?{}:{status:m}}),{data:u.data,source:"fallback",fallbackFields:["$"],reason:c}),o;try{o=await a.read({name:i.name,query:i.query,params:i.params},{tags:p,revalidateSeconds:r})}catch{return d("network")}if(!o.ok){let m=["configuration","network","timeout","rate-limit","upstream","plan-limit","permission","malformed"].includes(o.reason)?o.reason:"malformed",b=Number.isInteger(o.status)&&(o.status??0)>=100&&(o.status??0)<=599?o.status:void 0;return d(m,b)}if(o.value===null||o.value===void 0)return d("missing");let l;try{l=g(i.resolve(o.value,s.fallback))}catch{return d("malformed")}return l.fallbackFields.includes("$")?d("invalid-field"):l.fallbackFields.length>0?(t({event:"cms.partial-fallback",query:i.name,reason:"invalid-field",fields:l.fallbackFields}),{...l,source:"mixed",reason:"invalid-field"}):{...l,source:"cms"}}}}export{k as createCmsReader};
2
+ //# sourceMappingURL=server.mjs.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../src/server.ts", "../src/contracts/query.ts", "../src/runtime/reader.ts"],
4
+ "sourcesContent": ["import \"server-only\";\nexport { createCmsReader } from \"./runtime/reader.js\";\nexport type {\n CmsFailure, CmsDiagnostic, CmsFetch, CmsReadPolicy, CmsAdapterResult,\n CmsAdapter, CmsReadResult, CmsReaderOptions, CmsReader,\n} from \"./runtime/reader.js\";\n", "/** A-1822 S1 owns this implementation. S0 registers the public signatures. */\nexport type CmsParams = Readonly<Record<string, string | number | boolean | null>>;\nexport type CmsDependencies = {\n readonly types: readonly string[];\n readonly ids?: readonly string[];\n};\nexport type CmsResolution<T> = {\n readonly data: T;\n readonly fallbackFields: readonly string[];\n};\nexport type CmsQuery<T> = {\n readonly name: string;\n readonly query: string;\n readonly params: CmsParams;\n readonly dependencies: CmsDependencies;\n readonly resolve: (raw: unknown, fallback: T) => CmsResolution<T>;\n};\n\nconst TYPE = /^[A-Za-z][A-Za-z0-9_]{0,63}$/;\nconst ID = /^[A-Za-z0-9][A-Za-z0-9._-]{0,127}$/;\nconst SCOPE = /^[a-z0-9]{6,12}\\.[a-z][a-z0-9_-]{0,63}$/;\n\nfunction dependenciesCopy(dependencies: CmsDependencies): CmsDependencies {\n if (!dependencies || !Array.isArray(dependencies.types) || dependencies.types.length === 0) {\n throw new TypeError(\"CMS dependencies require document types\");\n }\n const types = [...dependencies.types];\n for (const type of types) {\n if (typeof type !== \"string\" || !TYPE.test(type)) throw new TypeError(\"Invalid CMS document type\");\n }\n if (dependencies.ids !== undefined && !Array.isArray(dependencies.ids)) throw new TypeError(\"Invalid CMS document IDs\");\n const ids = dependencies.ids === undefined ? undefined : [...dependencies.ids];\n for (const id of ids ?? []) {\n if (typeof id !== \"string\" || !ID.test(id) || /^(drafts|versions)\\./.test(id)) {\n throw new TypeError(\"Invalid CMS document ID\");\n }\n }\n if (new Set(types).size + new Set(ids).size > 128) throw new TypeError(\"Too many CMS tags\");\n return Object.freeze({ types: Object.freeze(types), ...(ids === undefined ? {} : { ids: Object.freeze(ids) }) });\n}\n\nexport function defineCmsQuery<T>(query: CmsQuery<T>): CmsQuery<T> {\n if (!query || typeof query.name !== \"string\" || !/^[A-Za-z][A-Za-z0-9_.-]{0,127}$/.test(query.name)\n || typeof query.query !== \"string\" || query.query.trim() === \"\" || typeof query.resolve !== \"function\") {\n throw new TypeError(\"Invalid CMS query configuration\");\n }\n const params = query.params;\n if (!params || typeof params !== \"object\" || (Object.getPrototypeOf(params) !== Object.prototype && Object.getPrototypeOf(params) !== null)) {\n throw new TypeError(\"CMS params must be plain JSON scalars\");\n }\n const copied: Record<string, string | number | boolean | null> = {};\n for (const key of Reflect.ownKeys(params)) {\n const descriptor = Object.getOwnPropertyDescriptor(params, key);\n if (typeof key !== \"string\" || !descriptor || !Object.hasOwn(descriptor, \"value\") || !descriptor.enumerable) {\n throw new TypeError(\"CMS params must be plain JSON scalars\");\n }\n const value: unknown = descriptor.value;\n if (!(value === null || typeof value === \"string\" || typeof value === \"boolean\" || (typeof value === \"number\" && Number.isFinite(value)))) {\n throw new TypeError(\"CMS params must be plain JSON scalars\");\n }\n Object.defineProperty(copied, key, { value, enumerable: true });\n }\n return Object.freeze({ name: query.name, query: query.query, params: Object.freeze(copied), dependencies: dependenciesCopy(query.dependencies), resolve: query.resolve });\n}\n\nexport function cmsTags(scope: string, dependencies: CmsDependencies): readonly string[] {\n if (typeof scope !== \"string\" || scope.length > 77 || !SCOPE.test(scope)) throw new TypeError(\"Invalid CMS scope\");\n const copied = dependenciesCopy(dependencies);\n const tags = [\n ...[...new Set(copied.types)].sort().map((type) => `cms:${scope}:type:${type}`),\n ...[...new Set(copied.ids ?? [])].sort().map((id) => `cms:${scope}:id:${id}`),\n ];\n return Object.freeze(tags);\n}\n", "import { cmsTags, defineCmsQuery, type CmsQuery, type CmsResolution } from \"../contracts/query.js\";\n\nexport type CmsFailure = \"configuration\" | \"network\" | \"timeout\" | \"rate-limit\"\n | \"upstream\" | \"plan-limit\" | \"permission\" | \"malformed\";\nexport type CmsDiagnostic = {\n readonly event: \"cms.fallback\" | \"cms.partial-fallback\" | \"cms.refused\";\n readonly query: string;\n readonly reason: CmsFailure | \"missing\" | \"invalid-field\";\n readonly status?: number;\n readonly fields: readonly string[];\n};\nexport type CmsFetch = (url: string, init: RequestInit & {\n next?: { revalidate: number; tags: string[] };\n}) => Promise<Response>;\nexport type CmsReadPolicy = {\n readonly tags: readonly string[];\n readonly revalidateSeconds: number;\n};\nexport type CmsAdapterResult =\n | { readonly ok: true; readonly value: unknown }\n | { readonly ok: false; readonly reason: CmsFailure; readonly status?: number };\nexport type CmsAdapter = {\n readonly scope: string;\n read(query: Pick<CmsQuery<unknown>, \"name\" | \"query\" | \"params\">,\n policy: CmsReadPolicy): Promise<CmsAdapterResult>;\n};\nexport type CmsReadResult<T> = {\n readonly data: T;\n readonly source: \"cms\" | \"mixed\" | \"fallback\";\n readonly fallbackFields: readonly string[];\n readonly reason?: CmsFailure | \"missing\" | \"invalid-field\";\n};\nexport type CmsReaderOptions = {\n readonly adapter: CmsAdapter;\n readonly revalidateSeconds?: number;\n readonly onDiagnostic?: (event: CmsDiagnostic) => void;\n};\nexport type CmsReader = {\n read<T>(query: CmsQuery<T>, options: { readonly fallback: T }): Promise<CmsReadResult<T>>;\n};\n\nfunction resolution<T>(value: CmsResolution<T>): CmsResolution<T> {\n if (!value || !Object.hasOwn(value, \"data\") || !Array.isArray(value.fallbackFields)\n || ![...value.fallbackFields].every((field: unknown) => typeof field === \"string\"\n && (field === \"$\" || /^[A-Za-z][A-Za-z0-9_.[\\]-]{0,127}$/.test(field)))) {\n throw new TypeError(\"Invalid CMS resolution\");\n }\n return { data: value.data, fallbackFields: Object.freeze([...new Set(value.fallbackFields)]) };\n}\n\n/** Forwards cache policy; persistence and rendered-output invalidation belong to the host. */\nexport function createCmsReader(options: CmsReaderOptions): CmsReader {\n const seconds = options?.revalidateSeconds ?? 3600;\n if (!Number.isSafeInteger(seconds) || seconds < 3600 || !options?.adapter\n || typeof options.adapter.read !== \"function\"\n || (options.onDiagnostic !== undefined && typeof options.onDiagnostic !== \"function\")) {\n throw new TypeError(\"Invalid CMS reader configuration\");\n }\n const adapter = options.adapter;\n // Validate the scope without assuming any particular shared content types.\n cmsTags(adapter.scope, { types: [\"ScopeValidation\"] });\n const notify = (event: CmsDiagnostic): void => {\n try {\n if (options.onDiagnostic) options.onDiagnostic(event);\n else console.warn(JSON.stringify(event));\n } catch { /* Reporting must not break visitor rendering. */ }\n };\n return {\n async read<T>(input: CmsQuery<T>, readOptions: { readonly fallback: T }): Promise<CmsReadResult<T>> {\n let query: CmsQuery<T>;\n let local: CmsResolution<T>;\n let tags: readonly string[];\n try {\n query = defineCmsQuery(input);\n tags = cmsTags(adapter.scope, query.dependencies);\n if (!readOptions || !Object.hasOwn(readOptions, \"fallback\")) throw new TypeError();\n // Built-in resolvers validate fallback here, before any I/O.\n local = resolution(query.resolve(null, readOptions.fallback));\n } catch {\n throw new TypeError(\"Invalid CMS query or fallback configuration\");\n }\n const fallback = (reason: CmsFailure | \"missing\" | \"invalid-field\", status?: number): CmsReadResult<T> => {\n notify({ event: \"cms.fallback\", query: query.name, reason, fields: [\"$\"],\n ...(status === undefined ? {} : { status }) });\n return { data: local.data, source: \"fallback\", fallbackFields: [\"$\"], reason };\n };\n let result: CmsAdapterResult;\n try {\n result = await adapter.read({ name: query.name, query: query.query, params: query.params },\n { tags, revalidateSeconds: seconds });\n } catch { return fallback(\"network\"); }\n if (!result.ok) {\n const reasons: readonly CmsFailure[] = [\"configuration\", \"network\", \"timeout\", \"rate-limit\", \"upstream\", \"plan-limit\", \"permission\", \"malformed\"];\n const reason = reasons.includes(result.reason) ? result.reason : \"malformed\";\n const status = Number.isInteger(result.status) && (result.status ?? 0) >= 100 && (result.status ?? 0) <= 599 ? result.status : undefined;\n return fallback(reason, status);\n }\n if (result.value === null || result.value === undefined) return fallback(\"missing\");\n let resolved: CmsResolution<T>;\n try { resolved = resolution(query.resolve(result.value, readOptions.fallback)); }\n catch { return fallback(\"malformed\"); }\n if (resolved.fallbackFields.includes(\"$\")) return fallback(\"invalid-field\");\n if (resolved.fallbackFields.length > 0) {\n notify({ event: \"cms.partial-fallback\", query: query.name, reason: \"invalid-field\", fields: resolved.fallbackFields });\n return { ...resolved, source: \"mixed\", reason: \"invalid-field\" };\n }\n return { ...resolved, source: \"cms\" };\n },\n };\n}\n"],
5
+ "mappings": "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",
6
+ "names": ["TYPE", "ID", "SCOPE", "dependenciesCopy", "dependencies", "types", "type", "ids", "id", "defineCmsQuery", "query", "params", "copied", "key", "descriptor", "value", "cmsTags", "scope", "tags", "resolution", "value", "field", "createCmsReader", "options", "seconds", "adapter", "cmsTags", "notify", "event", "input", "readOptions", "query", "local", "tags", "defineCmsQuery", "fallback", "reason", "status", "result", "resolved"]
7
+ }
@@ -0,0 +1,7 @@
1
+ "use strict";var F=Object.defineProperty;var cn=Object.getOwnPropertyDescriptor;var un=Object.getOwnPropertyNames;var dn=Object.prototype.hasOwnProperty;var yn=(e,n)=>{for(var t in n)F(e,t,{get:n[t],enumerable:!0})},fn=(e,n,t,o)=>{if(n&&typeof n=="object"||typeof n=="function")for(let r of un(n))!dn.call(e,r)&&r!==t&&F(e,r,{get:()=>n[r],enumerable:!(o=cn(n,r))||o.enumerable});return e};var gn=e=>fn(F({},"__esModule",{value:!0}),e);var $n={};yn($n,{CONTENT_PAGES_QUERY:()=>U,CONTENT_PAGE_BY_SLUG_QUERY:()=>J,HOME_PAGE_DOCUMENT_QUERY:()=>T,MALFORMED_CONTENT:()=>z,MalformedContentError:()=>h,READER_ACTION_HREF:()=>D,READER_HOME_PAGE_ID:()=>_,READER_JUMP_LINK:()=>j,READER_PHOTO_SLUG:()=>P,READER_SITE_SETTINGS_ID:()=>E,READER_STORY_LAYOUTS:()=>N,campaignState:()=>Z,contentPageQuery:()=>sn,contentPagesQuery:()=>an,createSiteContentReader:()=>on,homeContentQuery:()=>rn,parseContentPage:()=>I,parseHomePage:()=>Q,parseSiteSettings:()=>B,portableTextToMarkdown:()=>tn,siteSettingsQuery:()=>ln});module.exports=gn($n);function b(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 hn=/^[A-Za-z][A-Za-z0-9_]{0,63}$/,mn=/^[A-Za-z0-9][A-Za-z0-9._-]{0,127}$/;function wn(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"||!hn.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"||!mn.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 O(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 i=r.value;if(!(i===null||typeof i=="string"||typeof i=="boolean"||typeof i=="number"&&Number.isFinite(i)))throw new TypeError("CMS params must be plain JSON scalars");Object.defineProperty(t,o,{value:i,enumerable:!0})}return Object.freeze({name:e.name,query:e.query,params:Object.freeze(t),dependencies:wn(e.dependencies),resolve:e.resolve})}var w=e=>e!==null&&typeof e=="object"&&!Array.isArray(e),$=e=>typeof e=="string"&&e.trim()!=="",x=e=>e===null||typeof e=="string",A=e=>e===null||typeof e=="string"&&P.test(e),W=e=>typeof e=="string"&&D.test(e),k=e=>$(e)||w(e)&&$(e.text)&&(e.copySource==="captured"||e.copySource==="proposed"),H=e=>e===null||k(e),V=e=>w(e)&&k(e.label)&&W(e.href),q=e=>e===null||V(e);function X(e){if(!w(e)||!x(e.intro)||!A(e.photo)||!b(e.blocks))return!1;let n=e.hero;if(n!==null&&(!w(n)||!k(n.heading)||!H(n.subline)||!H(n.intro)||!A(n.image)||!A(n.inset)||!q(n.cta)||!q(n.secondaryCta))||!e.blocks.every(s=>{if(!w(s))return!1;switch(s.kind){case"campaign":return q(s.action)&&b(s.images)&&s.images.every(a=>typeof a=="string"&&A(a));case"locations":return(s.anchor===null||typeof s.anchor=="string"&&j.test(s.anchor))&&k(s.heading)&&H(s.tail)&&A(s.image);case"feature_stories":return k(s.heading)&&H(s.tail)&&b(s.items)&&s.items.length>0&&s.items.every(a=>w(a)&&k(a.heading)&&k(a.body)&&V(a.action)&&A(a.image)&&N.some(l=>l===a.shape)&&typeof a.card=="boolean");case"accent_band":return k(s.heading)&&k(s.body)&&q(s.action)&&A(s.image);case"cta":return $(s.heading)&&x(s.body)&&w(s.link)&&$(s.link.label)&&W(s.link.href);default:return!1}}))return!1;let o=e,r=o.blocks.flatMap(s=>s.kind==="locations"&&s.anchor!==null?[s.anchor]:[]);return new Set(r).size!==r.length?!1:[o.hero?.cta?.href,o.hero?.secondaryCta?.href,...o.blocks.flatMap(s=>{switch(s.kind){case"campaign":case"accent_band":return[s.action?.href];case"feature_stories":return s.items.map(a=>a.action.href);case"cta":return[s.link.href];default:return[]}})].every(s=>s===void 0||!s.startsWith("#")||r.includes(s.slice(1)))}function v(e){return b(e)&&e.every(n=>w(n)&&$(n.where)&&typeof n.text=="string")}function nn(e){return e===null||w(e)&&X(e.composition)&&typeof e.body=="string"&&v(e.proposedCopy)&&typeof e.campaign=="string"&&["shown","off","not-started","ended","none"].includes(e.campaign)}function G(e){return e===null||w(e)&&$(e.slug)&&$(e.title)&&X(e.composition)&&typeof e.body=="string"&&typeof e.migrated=="boolean"&&v(e.proposedCopy)}function en(e){return e===null||w(e)&&$(e.name)&&x(e.description)&&w(e.contact)&&x(e.contact.email)&&x(e.contact.phone)&&b(e.social)&&e.social.every(n=>w(n)&&$(n.network)&&typeof n.url=="string"&&/^https?:\/\//.test(n.url))}var z="malformed-content",h=class extends Error{code=z;documentId;problems;constructor(n,t){super(`${z}: ${n}: ${t.join("; ")}`),this.name="MalformedContentError",this.documentId=n,this.problems=t}},P=/^[a-z0-9]+(?:-[a-z0-9]+)*$/,D=/^(?:\/(?![/\\])[^\s]*|#[a-z][a-z0-9]*(?:-[a-z0-9]+)*|mailto:[^\s@]+@[^\s@]+|tel:\+?[0-9][0-9 ()-]*|https?:\/\/[^\s/]+[^\s]*)$/,j=/^[a-z][a-z0-9]*(?:-[a-z0-9]+)*$/,N=["wide","tall","round","free"],_="homePage",E="siteSettings",R=class{problems=[];proposed=[];fail(n,t){return this.problems.push(`${n} ${t}`),null}object(n,t){return typeof n=="object"&&n!==null&&!Array.isArray(n)?n:this.fail(t,"is not an object")}dense(n,t){return b(n)?!0:(this.fail(t,"contains missing entries"),!1)}optionalString(n,t){return n==null?null:typeof n=="string"?n.trim()===""?null:n:this.fail(t,"is not text")}copy(n,t){if(n==null)return null;let o=this.object(n,t);if(o===null)return null;let r=o.text,i=o.copySource;return r!==void 0&&typeof r!="string"?this.fail(`${t}.text`,"is not text"):i!==void 0&&i!=="captured"&&i!=="proposed"?this.fail(`${t}.copySource`,`is ${JSON.stringify(i)}, not captured or proposed`):typeof r!="string"||r.trim()===""?null:i==="proposed"?(this.proposed.push({where:t,text:r}),{text:r,copySource:"proposed"}):i==="captured"?{text:r,copySource:"captured"}:r}requiredCopy(n,t){let o=this.copy(n,t);return o===null&&!this.problems.some(r=>r.startsWith(t))&&this.fail(t,"is missing its words"),o}photo(n,t){return n==null?null:typeof n=="string"&&P.test(n)?n:this.fail(t,`is ${JSON.stringify(n)}, not a photo library slug`)}photos(n,t,o){return n==null?[]:Array.isArray(n)?this.dense(n,t)?(n.length>o&&this.fail(t,`holds ${String(n.length)} photos; at most ${String(o)}`),n.map((r,i)=>this.photo(r,`${t}[${String(i)}]`)).filter(r=>r!==null)):[]:(this.fail(t,"is not a list of photos"),[])}action(n,t){if(n==null)return null;let o=this.object(n,t);if(o===null)return null;let r=this.requiredCopy(o.label,`${t}.label`),i=o.href;return typeof i!="string"||!D.test(i)?this.fail(`${t}.href`,`is ${JSON.stringify(i)}, not a site path, #jump-link, mailto:, tel: or web address`):r===null?null:{label:r,href:i}}requiredAction(n,t){return n==null?this.fail(t,"is missing"):this.action(n,t)}};function M(e){return typeof e=="string"?e:e.text}function tn(e){let n=new R,t=Y(e,"body",n);if(n.problems.length>0)throw new h("body",n.problems);return t}function Y(e,n,t){if(e==null)return"";if(!Array.isArray(e))return t.fail(n,"is not rich text"),"";if(!t.dense(e,n))return"";let o=[],r=!1;return e.forEach((i,s)=>{let a=`${n}[${String(s)}]`,l=t.object(i,a);if(l===null)return;if(l._type!=="block"){t.fail(a,`is a ${JSON.stringify(l._type)}; only text is supported in rich text so far`);return}let p=bn(l,a,t),y=l.listItem,u=l.style??"normal",c;if(y==="bullet"||y==="number"){let d=typeof l.level=="number"&&l.level>1?l.level:1;c=`${" ".repeat(d-1)}${y==="bullet"?"-":"1."} ${p}`}else if(u==="h2")c=`## ${p}`;else if(u==="h3")c=`### ${p}`;else if(u==="blockquote")c=`> ${p}`;else if(u==="normal")c=p;else{t.fail(`${a}.style`,`is ${JSON.stringify(u)}, which the schema does not offer`);return}let f=y==="bullet"||y==="number";o.length>0&&o.push(f&&r?`
2
+ `:`
3
+
4
+ `),o.push(c),r=f}),o.join("")}var Cn={strong:"**",em:"*",code:"`"};function bn(e,n,t){let o=new Map,r=Array.isArray(e.markDefs)?e.markDefs:[];if(!t.dense(r,`${n}.markDefs`))return"";for(let s of r){let a=s;a._type==="link"&&typeof a._key=="string"&&typeof a.href=="string"&&o.set(a._key,a.href)}let i=Array.isArray(e.children)?e.children:[];return t.dense(i,`${n}.children`)?i.map((s,a)=>{let l=s;if(l._type!=="span"||typeof l.text!="string")return t.fail(`${n}.children[${String(a)}]`,"is not a text span"),"";let p=l.text,y=Array.isArray(l.marks)?l.marks:[];if(!t.dense(y,`${n}.children[${String(a)}].marks`))return"";let u=null;for(let c of y){if(typeof c!="string")continue;let f=Cn[c];f!==void 0?p=`${f}${p}${f}`:o.has(c)?u=o.get(c)??null:t.fail(`${n}.children[${String(a)}].marks`,`names ${JSON.stringify(c)}, which is neither a style nor a link`)}return u===null?p:`[${p}](${u})`}).join(""):""}function Z(e,n){if(typeof e!="object"||e===null)return"none";let t=e;if(t.enabled!==!0)return"off";let o=typeof t.startsAt=="string"?Date.parse(t.startsAt):null,r=typeof t.endsAt=="string"?Date.parse(t.endsAt):null;return o!==null&&n.getTime()<o?"not-started":r!==null&&n.getTime()>=r?"ended":"shown"}function K(e,n,t){return typeof n._key=="string"?`${e}[_key=="${n._key}"]`:`${e}[${String(t)}]`}function Q(e,n){let t=new R,o=t.object(e,"homePage");if(o===null)throw new h(_,t.problems);let r=typeof o._id=="string"?o._id:_;o._type!=="homePage"&&t.fail("_type",`is ${JSON.stringify(o._type)}, not homePage`);let i=null,s=o.hero===void 0?t.fail("hero","is missing"):t.object(o.hero,"hero");if(s!==null){let d=t.photos(s.photos,"hero.photos",2),g=t.requiredCopy(s.headline,"hero.headline"),C=t.copy(s.subline,"hero.subline"),S=t.copy(s.lead,"hero.lead"),m=t.action(s.primaryAction,"hero.primaryAction"),pn=t.action(s.secondaryAction,"hero.secondaryAction");g!==null&&(i={heading:g,subline:C,intro:S,image:d[0]??null,inset:d[1]??null,cta:m,secondaryCta:pn})}let a=[],l=[],p="",y=Z(o.campaign,n.now);if(y==="shown"){let d=t.object(o.campaign,"campaign");if(d!==null){let g=t.requiredCopy(d.title,"campaign.title"),C=t.photos(d.photos,"campaign.photos",3);C.length===0&&t.fail("campaign.photos","is empty; a shown campaign needs at least one photo");let S=Y(d.body,"campaign.body",t);S===""&&t.fail("campaign.body","is empty; a shown campaign needs its text"),d.bodyCopySource==="proposed"&&t.proposed.push({where:"campaign.body",text:S});let m=t.action(d.action,"campaign.action");m!==null&&l.push({where:"campaign.action.href",href:m.href}),g!==null&&(p=`# ${M(g)}
5
+
6
+ ${S}`),a.push({kind:"campaign",action:m,images:C})}}let u=[],c=o.blocks??[];Array.isArray(c)?t.dense(c,"blocks")&&c.forEach((d,g)=>{let C=t.object(d,`blocks[${String(g)}]`);if(C===null)return;let S=K("blocks",C,g),m=kn(C,S,t);m!==null&&(l.push(...Sn(m,C,S)),m.kind==="locations"&&m.anchor!==null&&(u.includes(m.anchor)&&t.fail(`${S}.jumpLink`,`repeats "${m.anchor}", already used by another section`),u.push(m.anchor)),a.push(m))}):t.fail("blocks","is not a list");let f=[];i?.cta&&f.push({where:"hero.primaryAction.href",href:i.cta.href}),i?.secondaryCta&&f.push({where:"hero.secondaryAction.href",href:i.secondaryCta.href}),f.push(...l);for(let{where:d,href:g}of f)g.startsWith("#")&&!u.includes(g.slice(1))&&t.fail(d,`jumps to ${g}, which no section on the page is named`);if(t.problems.length>0)throw new h(r,t.problems);return{composition:{intro:null,photo:null,hero:i,blocks:a},body:p,campaign:y,proposedCopy:t.proposed}}function Sn(e,n,t){switch(e.kind){case"feature_stories":{let o=Array.isArray(n.stories)?n.stories:[];return e.items.map((r,i)=>({where:`${K(`${t}.stories`,o[i]??{},i)}.action.href`,href:r.action.href}))}case"accent_band":return e.action===null?[]:[{where:`${t}.action.href`,href:e.action.href}];case"cta":return[{where:`${t}.action.href`,href:e.link.href}];default:return[]}}function kn(e,n,t){switch(e._type){case"featureStoriesBlock":{let o=t.requiredCopy(e.heading,`${n}.heading`),r=t.copy(e.tail,`${n}.tail`),i=e.stories;if(!Array.isArray(i)||i.length===0)return t.fail(`${n}.stories`,"has no stories");if(!t.dense(i,`${n}.stories`))return null;let s=[];return i.forEach((a,l)=>{let p=t.object(a,`${n}.stories[${String(l)}]`);if(p===null)return;let y=K(`${n}.stories`,p,l),u=t.requiredCopy(p.heading,`${y}.heading`),c=t.requiredCopy(p.body,`${y}.body`),f=t.requiredAction(p.action,`${y}.action`),d=t.photo(p.photo,`${y}.photo`),g=p.layout??"wide";if(!N.includes(g)){t.fail(`${y}.layout`,`is ${JSON.stringify(g)}, not wide, tall, round or free`);return}let C=p.onCard??!1;if(typeof C!="boolean"){t.fail(`${y}.onCard`,"is not on or off");return}u===null||c===null||f===null||s.push({heading:u,body:c,action:f,image:d,shape:g,card:C})}),o===null?null:{kind:"feature_stories",heading:o,tail:r,items:s}}case"surfaceCardBlock":{let o=t.requiredCopy(e.heading,`${n}.heading`),r=t.copy(e.body,`${n}.body`),i=t.requiredAction(e.action,`${n}.action`);return o===null||i===null?null:{kind:"cta",heading:M(o),body:r===null?null:M(r),link:{label:M(i.label),href:i.href}}}case"accentBandBlock":{let o=t.requiredCopy(e.heading,`${n}.heading`),r=t.requiredCopy(e.body,`${n}.body`),i=t.action(e.action,`${n}.action`),s=t.photo(e.photo,`${n}.photo`);return o===null||r===null?null:{kind:"accent_band",heading:o,body:r,action:i,image:s}}case"locationsBlock":{let o=e.jumpLink,r=null;o!=null&&o!==""&&(typeof o!="string"||!j.test(o)?t.fail(`${n}.jumpLink`,`is ${JSON.stringify(o)}, not lowercase words joined by hyphens`):r=o);let i=t.requiredCopy(e.heading,`${n}.heading`),s=t.copy(e.tail,`${n}.tail`),a=t.photo(e.photo,`${n}.photo`);return i===null?null:{kind:"locations",anchor:r,heading:i,tail:s,image:a}}default:return t.fail(`${n}._type`,`is ${JSON.stringify(e._type)}, not a section type this reader knows`)}}function I(e){let n=new R,t=n.object(e,"page");if(t===null)throw new h("page",n.problems);let o=typeof t._id=="string"?t._id:"page";t._type!=="page"&&n.fail("_type",`is ${JSON.stringify(t._type)}, not page`);let r=n.optionalString(t.title,"title");r===null&&n.fail("title","is missing"),t.titleCopySource==="proposed"&&r!==null&&n.proposed.push({where:"title",text:r});let i=t.slug,s=typeof i?.current=="string"&&i.current!==""?i.current:null;s===null&&n.fail("slug.current","is missing");let a=n.copy(t.lead,"lead"),l=n.photo(t.photo,"photo"),p=Y(t.body,"body",n);if(t.bodyCopySource==="proposed"&&n.proposed.push({where:"body",text:p}),n.problems.length>0||r===null||s===null)throw new h(o,n.problems);return{slug:s,title:r,composition:{intro:a===null?null:M(a),photo:l,hero:null,blocks:[]},body:p,migrated:t.migrated===!0,proposedCopy:n.proposed}}function B(e){let n=new R,t=n.object(e,"siteSettings");if(t===null)throw new h(E,n.problems);let o=n.optionalString(t.title,"title");o===null&&n.fail("title","is missing; a site needs its name");let r=n.optionalString(t.description,"description"),i=t.contact===void 0?{}:n.object(t.contact,"contact")??{},s=n.optionalString(i.email,"contact.email"),a=n.optionalString(i.phone,"contact.phone"),l=[],p=t.social??[];if(Array.isArray(p)?n.dense(p,"social")&&p.forEach((y,u)=>{let c=n.object(y,`social[${String(u)}]`);if(c===null)return;let f=n.optionalString(c.network,`social[${String(u)}].network`),d=n.optionalString(c.url,`social[${String(u)}].url`);if(f===null||d===null||!/^https?:\/\//.test(d)){n.fail(`social[${String(u)}]`,"needs a network and a web address");return}l.push({network:f,url:d})}):n.fail("social","is not a list"),n.problems.length>0||o===null)throw new h(E,n.problems);return{name:o,description:r,contact:{email:s,phone:a},social:l}}var T="*[_id == $id][0]",U='*[_type == "page" && defined(slug.current)]|order(slug.current asc)',J='*[_type == "page" && slug.current == $slug][0]';function on(e){return{home:async({now:n})=>{let t=await e.query(T,{params:{id:_}});return t==null?null:Q(t,{now:n})},pages:async()=>{let n=await e.query(U);if(!Array.isArray(n))throw new h("page",["the page query did not return a list"]);if(!b(n))throw new h("page",["the page query contains missing entries"]);return n.map(t=>I(t))},pageBySlug:async n=>{let t=await e.query(J,{params:{slug:n}});return t==null?null:I(t)},siteSettings:async()=>{let n=await e.query(T,{params:{id:E}});return n==null?null:B(n)}}}function L(e,n,t,o){if(!o(n))throw new TypeError("Invalid CMS content fallback");return e==null?{data:n,fallbackFields:["$"]}:{data:t(e),fallbackFields:[]}}function rn(e){if(!(e instanceof Date)||!Number.isFinite(e.getTime()))throw new TypeError("Invalid CMS campaign date");let n=e.getTime();return O({name:"homePage.v1",query:T,params:{id:_},dependencies:{types:["homePage"],ids:[_]},resolve:(t,o)=>L(t,o,r=>Q(r,{now:new Date(n)}),nn)})}function sn(e){if(typeof e!="string"||e==="")throw new TypeError("Invalid CMS page slug");return O({name:"page.v1",query:J,params:{slug:e},dependencies:{types:["page"]},resolve:(n,t)=>L(n,t,I,G)})}function an(){return O({name:"pages.v1",query:U,params:{},dependencies:{types:["page"]},resolve:(e,n)=>L(e,n,t=>{if(!Array.isArray(t))throw new h("page",["the page query did not return a list"]);if(!b(t))throw new h("page",["the page query contains missing entries"]);return t.map(o=>I(o))},t=>b(t)&&t.every(o=>o!==null&&G(o)))})}function ln(){return O({name:"siteSettings.v1",query:T,params:{id:E},dependencies:{types:["siteSettings"],ids:[E]},resolve:(e,n)=>L(e,n,B,en)})}0&&(module.exports={CONTENT_PAGES_QUERY,CONTENT_PAGE_BY_SLUG_QUERY,HOME_PAGE_DOCUMENT_QUERY,MALFORMED_CONTENT,MalformedContentError,READER_ACTION_HREF,READER_HOME_PAGE_ID,READER_JUMP_LINK,READER_PHOTO_SLUG,READER_SITE_SETTINGS_ID,READER_STORY_LAYOUTS,campaignState,contentPageQuery,contentPagesQuery,createSiteContentReader,homeContentQuery,parseContentPage,parseHomePage,parseSiteSettings,portableTextToMarkdown,siteSettingsQuery});
7
+ //# sourceMappingURL=site-content.cjs.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../src/site-content.ts", "../src/portable/array.ts", "../src/contracts/query.ts", "../src/portable/fallback.ts", "../src/portable/site-content.ts"],
4
+ "sourcesContent": ["export {\n MALFORMED_CONTENT, MalformedContentError, parseHomePage, parseContentPage,\n parseSiteSettings, portableTextToMarkdown, campaignState, HOME_PAGE_DOCUMENT_QUERY,\n CONTENT_PAGES_QUERY, CONTENT_PAGE_BY_SLUG_QUERY, createSiteContentReader,\n READER_PHOTO_SLUG, READER_ACTION_HREF, READER_JUMP_LINK, READER_STORY_LAYOUTS,\n READER_HOME_PAGE_ID, READER_SITE_SETTINGS_ID, homeContentQuery, contentPageQuery,\n contentPagesQuery, siteSettingsQuery,\n} from \"./portable/site-content.js\";\nexport type {\n CopyInput, ActionInput, HeroInput, StoryInput, CompositionBlockInput, CompositionInput,\n ProposedCopy, CampaignState, HomeContent, PageContent, SiteSettingsContent, SiteContentReader,\n} from \"./portable/site-content.js\";\n", "/** Content lists must contain an own entry at every index. */\nexport function isDenseArray(value: unknown): value is unknown[] {\n if (!Array.isArray(value)) return false;\n for (let index = 0; index < value.length; index += 1) {\n if (!Object.hasOwn(value, index)) return false;\n }\n return true;\n}\n", "/** A-1822 S1 owns this implementation. S0 registers the public signatures. */\nexport type CmsParams = Readonly<Record<string, string | number | boolean | null>>;\nexport type CmsDependencies = {\n readonly types: readonly string[];\n readonly ids?: readonly string[];\n};\nexport type CmsResolution<T> = {\n readonly data: T;\n readonly fallbackFields: readonly string[];\n};\nexport type CmsQuery<T> = {\n readonly name: string;\n readonly query: string;\n readonly params: CmsParams;\n readonly dependencies: CmsDependencies;\n readonly resolve: (raw: unknown, fallback: T) => CmsResolution<T>;\n};\n\nconst TYPE = /^[A-Za-z][A-Za-z0-9_]{0,63}$/;\nconst ID = /^[A-Za-z0-9][A-Za-z0-9._-]{0,127}$/;\nconst SCOPE = /^[a-z0-9]{6,12}\\.[a-z][a-z0-9_-]{0,63}$/;\n\nfunction dependenciesCopy(dependencies: CmsDependencies): CmsDependencies {\n if (!dependencies || !Array.isArray(dependencies.types) || dependencies.types.length === 0) {\n throw new TypeError(\"CMS dependencies require document types\");\n }\n const types = [...dependencies.types];\n for (const type of types) {\n if (typeof type !== \"string\" || !TYPE.test(type)) throw new TypeError(\"Invalid CMS document type\");\n }\n if (dependencies.ids !== undefined && !Array.isArray(dependencies.ids)) throw new TypeError(\"Invalid CMS document IDs\");\n const ids = dependencies.ids === undefined ? undefined : [...dependencies.ids];\n for (const id of ids ?? []) {\n if (typeof id !== \"string\" || !ID.test(id) || /^(drafts|versions)\\./.test(id)) {\n throw new TypeError(\"Invalid CMS document ID\");\n }\n }\n if (new Set(types).size + new Set(ids).size > 128) throw new TypeError(\"Too many CMS tags\");\n return Object.freeze({ types: Object.freeze(types), ...(ids === undefined ? {} : { ids: Object.freeze(ids) }) });\n}\n\nexport function defineCmsQuery<T>(query: CmsQuery<T>): CmsQuery<T> {\n if (!query || typeof query.name !== \"string\" || !/^[A-Za-z][A-Za-z0-9_.-]{0,127}$/.test(query.name)\n || typeof query.query !== \"string\" || query.query.trim() === \"\" || typeof query.resolve !== \"function\") {\n throw new TypeError(\"Invalid CMS query configuration\");\n }\n const params = query.params;\n if (!params || typeof params !== \"object\" || (Object.getPrototypeOf(params) !== Object.prototype && Object.getPrototypeOf(params) !== null)) {\n throw new TypeError(\"CMS params must be plain JSON scalars\");\n }\n const copied: Record<string, string | number | boolean | null> = {};\n for (const key of Reflect.ownKeys(params)) {\n const descriptor = Object.getOwnPropertyDescriptor(params, key);\n if (typeof key !== \"string\" || !descriptor || !Object.hasOwn(descriptor, \"value\") || !descriptor.enumerable) {\n throw new TypeError(\"CMS params must be plain JSON scalars\");\n }\n const value: unknown = descriptor.value;\n if (!(value === null || typeof value === \"string\" || typeof value === \"boolean\" || (typeof value === \"number\" && Number.isFinite(value)))) {\n throw new TypeError(\"CMS params must be plain JSON scalars\");\n }\n Object.defineProperty(copied, key, { value, enumerable: true });\n }\n return Object.freeze({ name: query.name, query: query.query, params: Object.freeze(copied), dependencies: dependenciesCopy(query.dependencies), resolve: query.resolve });\n}\n\nexport function cmsTags(scope: string, dependencies: CmsDependencies): readonly string[] {\n if (typeof scope !== \"string\" || scope.length > 77 || !SCOPE.test(scope)) throw new TypeError(\"Invalid CMS scope\");\n const copied = dependenciesCopy(dependencies);\n const tags = [\n ...[...new Set(copied.types)].sort().map((type) => `cms:${scope}:type:${type}`),\n ...[...new Set(copied.ids ?? [])].sort().map((id) => `cms:${scope}:id:${id}`),\n ];\n return Object.freeze(tags);\n}\n", "import { isDenseArray } from \"./array.js\";\nimport {\n READER_ACTION_HREF, READER_JUMP_LINK, READER_PHOTO_SLUG, READER_STORY_LAYOUTS,\n type CompositionInput, type HomeContent, type PageContent, type SiteSettingsContent,\n} from \"./site-content.js\";\n\nconst object = (value: unknown): value is Record<string, unknown> => value !== null && typeof value === \"object\" && !Array.isArray(value);\nconst words = (value: unknown): boolean => typeof value === \"string\" && value.trim() !== \"\";\nconst nullableText = (value: unknown): boolean => value === null || typeof value === \"string\";\nconst photo = (value: unknown): boolean => value === null || (typeof value === \"string\" && READER_PHOTO_SLUG.test(value));\nconst href = (value: unknown): boolean => typeof value === \"string\" && READER_ACTION_HREF.test(value);\nconst copy = (value: unknown): boolean => words(value) || (object(value) && words(value.text) && (value.copySource === \"captured\" || value.copySource === \"proposed\"));\nconst optionalCopy = (value: unknown): boolean => value === null || copy(value);\nconst action = (value: unknown): boolean => object(value) && copy(value.label) && href(value.href);\nconst optionalAction = (value: unknown): boolean => value === null || action(value);\n\nfunction composition(value: unknown): boolean {\n if (!object(value) || !nullableText(value.intro) || !photo(value.photo) || !isDenseArray(value.blocks)) return false;\n const hero = value.hero;\n if (hero !== null && (!object(hero) || !copy(hero.heading) || !optionalCopy(hero.subline) || !optionalCopy(hero.intro)\n || !photo(hero.image) || !photo(hero.inset) || !optionalAction(hero.cta) || !optionalAction(hero.secondaryCta))) return false;\n const validBlocks = value.blocks.every((block: unknown) => {\n if (!object(block)) return false;\n switch (block.kind) {\n case \"campaign\": return optionalAction(block.action) && isDenseArray(block.images) && block.images.every((image: unknown) => typeof image === \"string\" && photo(image));\n case \"locations\": return (block.anchor === null || (typeof block.anchor === \"string\" && READER_JUMP_LINK.test(block.anchor))) && copy(block.heading) && optionalCopy(block.tail) && photo(block.image);\n case \"feature_stories\": return copy(block.heading) && optionalCopy(block.tail) && isDenseArray(block.items) && block.items.length > 0 && block.items.every((item: unknown) => object(item) && copy(item.heading) && copy(item.body) && action(item.action) && photo(item.image) && READER_STORY_LAYOUTS.some((layout) => layout === item.shape) && typeof item.card === \"boolean\");\n case \"accent_band\": return copy(block.heading) && copy(block.body) && optionalAction(block.action) && photo(block.image);\n case \"cta\": return words(block.heading) && nullableText(block.body) && object(block.link) && words(block.link.label) && href(block.link.href);\n default: return false;\n }\n });\n if (!validBlocks) return false;\n const model = value as unknown as CompositionInput;\n const anchors = model.blocks.flatMap((block) => block.kind === \"locations\" && block.anchor !== null ? [block.anchor] : []);\n if (new Set(anchors).size !== anchors.length) return false;\n const links = [model.hero?.cta?.href, model.hero?.secondaryCta?.href, ...model.blocks.flatMap((block) => {\n switch (block.kind) {\n case \"campaign\": case \"accent_band\": return [block.action?.href];\n case \"feature_stories\": return block.items.map((item) => item.action.href);\n case \"cta\": return [block.link.href];\n default: return [];\n }\n })];\n return links.every((link) => link === undefined || !link.startsWith(\"#\") || anchors.includes(link.slice(1)));\n}\n\nfunction proposed(value: unknown): boolean {\n return isDenseArray(value) && value.every((line: unknown) => object(line) && words(line.where) && typeof line.text === \"string\");\n}\n\nexport function validHomeFallback(value: unknown): value is HomeContent | null {\n return value === null || (object(value) && composition(value.composition) && typeof value.body === \"string\" && proposed(value.proposedCopy)\n && typeof value.campaign === \"string\" && [\"shown\", \"off\", \"not-started\", \"ended\", \"none\"].includes(value.campaign));\n}\n\nexport function validPageFallback(value: unknown): value is PageContent | null {\n return value === null || (object(value) && words(value.slug) && words(value.title) && composition(value.composition)\n && typeof value.body === \"string\" && typeof value.migrated === \"boolean\" && proposed(value.proposedCopy));\n}\n\nexport function validSettingsFallback(value: unknown): value is SiteSettingsContent | null {\n return value === null || (object(value) && words(value.name) && nullableText(value.description) && object(value.contact)\n && nullableText(value.contact.email) && nullableText(value.contact.phone) && isDenseArray(value.social)\n && value.social.every((link: unknown) => object(link) && words(link.network) && typeof link.url === \"string\" && /^https?:\\/\\//.test(link.url)));\n}\n", "/**\n * A-1713. The site content model, read: the home page, content pages and site\n * settings, validated on read and returned in the shape a site's page\n * composition consumes.\n *\n * ===========================================================================\n * READ ONLY, BY CONSTRUCTION\n * ===========================================================================\n *\n * A client site reads its content with a read-only token. All editing goes\n * through the studio's dashboard, which writes to Sanity; nothing on a client\n * site writes, and this module has no write path to call. It is handed a\n * `ContentClient` (a `query` function) and nothing else.\n *\n * ===========================================================================\n * VALIDATED ON READ, BECAUSE SANITY VALIDATION ONLY ADVISES\n * ===========================================================================\n *\n * The schema's rules warn an editor; they do not refuse a publish, and\n * anything writing over the API skips them entirely. So every document is\n * checked here again, and a malformed one is refused BY NAME\n * (`MalformedContentError`, code `malformed-content`) listing every problem\n * with its path, rather than rendered half-empty. A page that renders with a\n * missing headline and a page whose content is broken look identical to a\n * visitor; a build that fails naming `hero.headline` does not.\n *\n * Absent is not malformed: `null` from `home()` means nobody has created the\n * home page yet, and a site decides what to do about that.\n *\n * ===========================================================================\n * THE SHAPE IT RETURNS\n * ===========================================================================\n *\n * The INPUT shape of a site's composition schema (the reference build's\n * frontmatter): a copy value is a plain string for the client's own words\n * with no claim about their source, `{ text, copySource: \"captured\" }` for\n * words claimed verbatim from the capture (the site checks every such claim\n * against its capture evidence, so the claim must survive Sanity), and\n * `{ text, copySource: \"proposed\" }` for studio-written words awaiting\n * approval. All three round-trip exactly; a photo is its library slug; every key a block declares is\n * present, `null` where there is nothing. So a site validates this with the\n * same schema it validates its Markdown frontmatter with, and its components\n * never know where the content came from.\n *\n * Mapping from the generic model to the composition's names:\n *\n * hero.headline / subline / lead hero.heading / subline / intro\n * hero.photos[0], [1] hero.image, hero.inset\n * hero.primaryAction / secondary... hero.cta / secondaryCta\n * campaign (when shown) the FIRST block, kind `campaign`, and\n * the page body (`# title` + its text)\n * featureStoriesBlock kind `feature_stories`\n * surfaceCardBlock kind `cta`\n * accentBandBlock kind `accent_band`\n * locationsBlock kind `locations` (jumpLink \u2192 anchor)\n *\n * Two places the composition cannot carry a proposed marker: a `cta` block's\n * plain strings, and the campaign's title and body (which travel as Markdown).\n * There the text is returned plain and the line is still listed in\n * `proposedCopy`, which is the list a dashboard and a site both read for\n * approval. Nothing is dropped silently.\n */\n\nimport { isDenseArray } from \"./array.js\";\nimport { defineCmsQuery, type CmsQuery, type CmsResolution } from \"../contracts/query.js\";\nimport { validHomeFallback, validPageFallback, validSettingsFallback } from \"./fallback.js\";\n\n// ---------------------------------------------------------------------------\n// Output types\n// ---------------------------------------------------------------------------\n\nexport type CopyInput = string | { readonly text: string; readonly copySource: \"captured\" | \"proposed\" };\nexport type ActionInput = { readonly label: CopyInput; readonly href: string };\n\nexport type HeroInput = {\n readonly heading: CopyInput;\n readonly subline: CopyInput | null;\n readonly intro: CopyInput | null;\n readonly image: string | null;\n readonly inset: string | null;\n readonly cta: ActionInput | null;\n readonly secondaryCta: ActionInput | null;\n};\n\nexport type StoryInput = {\n readonly heading: CopyInput;\n readonly body: CopyInput;\n readonly action: ActionInput;\n readonly image: string | null;\n readonly shape: \"wide\" | \"tall\" | \"round\" | \"free\";\n readonly card: boolean;\n};\n\nexport type CompositionBlockInput =\n | { readonly kind: \"campaign\"; readonly action: ActionInput | null; readonly images: readonly string[] }\n | {\n readonly kind: \"locations\";\n readonly anchor: string | null;\n readonly heading: CopyInput;\n readonly tail: CopyInput | null;\n readonly image: string | null;\n }\n | {\n readonly kind: \"feature_stories\";\n readonly heading: CopyInput;\n readonly tail: CopyInput | null;\n readonly items: readonly StoryInput[];\n }\n | {\n readonly kind: \"accent_band\";\n readonly heading: CopyInput;\n readonly body: CopyInput;\n readonly action: ActionInput | null;\n readonly image: string | null;\n }\n | {\n readonly kind: \"cta\";\n readonly heading: string;\n readonly body: string | null;\n readonly link: { readonly label: string; readonly href: string };\n };\n\nexport type CompositionInput = {\n readonly intro: string | null;\n readonly photo: string | null;\n readonly hero: HeroInput | null;\n readonly blocks: readonly CompositionBlockInput[];\n};\n\n/** One line of studio-written copy awaiting approval, and where it is in the document. */\nexport type ProposedCopy = { readonly where: string; readonly text: string };\n\nexport type CampaignState = \"shown\" | \"off\" | \"not-started\" | \"ended\" | \"none\";\n\nexport type HomeContent = {\n readonly composition: CompositionInput;\n /** The page body as Markdown: the campaign's title and text when it is shown, otherwise empty. */\n readonly body: string;\n readonly campaign: CampaignState;\n readonly proposedCopy: readonly ProposedCopy[];\n};\n\nexport type PageContent = {\n readonly slug: string;\n readonly title: string;\n readonly composition: CompositionInput;\n readonly body: string;\n readonly migrated: boolean;\n readonly proposedCopy: readonly ProposedCopy[];\n};\n\nexport type SiteSettingsContent = {\n readonly name: string;\n readonly description: string | null;\n readonly contact: { readonly email: string | null; readonly phone: string | null };\n readonly social: readonly { readonly network: string; readonly url: string }[];\n};\n\n// ---------------------------------------------------------------------------\n// The refusal\n// ---------------------------------------------------------------------------\n\nexport const MALFORMED_CONTENT = \"malformed-content\";\n\nexport class MalformedContentError extends Error {\n readonly code = MALFORMED_CONTENT;\n readonly documentId: string;\n readonly problems: readonly string[];\n\n constructor(documentId: string, problems: readonly string[]) {\n super(`${MALFORMED_CONTENT}: ${documentId}: ${problems.join(\"; \")}`);\n this.name = \"MalformedContentError\";\n this.documentId = documentId;\n this.problems = problems;\n }\n}\n\n// ---------------------------------------------------------------------------\n// The rules restated\n// ---------------------------------------------------------------------------\n\n/*\n * Runtime-free rules shared with schema-base. The schema adapter imports these\n * objects; content-client compatibility tests pin the shared references.\n */\nexport const READER_PHOTO_SLUG = /^[a-z0-9]+(?:-[a-z0-9]+)*$/;\nexport const READER_ACTION_HREF =\n /^(?:\\/(?![/\\\\])[^\\s]*|#[a-z][a-z0-9]*(?:-[a-z0-9]+)*|mailto:[^\\s@]+@[^\\s@]+|tel:\\+?[0-9][0-9 ()-]*|https?:\\/\\/[^\\s/]+[^\\s]*)$/;\nexport const READER_JUMP_LINK = /^[a-z][a-z0-9]*(?:-[a-z0-9]+)*$/;\nexport const READER_STORY_LAYOUTS = [\"wide\", \"tall\", \"round\", \"free\"] as const;\nexport const READER_HOME_PAGE_ID = \"homePage\";\nexport const READER_SITE_SETTINGS_ID = \"siteSettings\";\n\n// ---------------------------------------------------------------------------\n// A small path-aware reader\n// ---------------------------------------------------------------------------\n\ntype Raw = Record<string, unknown>;\n\nclass Reading {\n readonly problems: string[] = [];\n readonly proposed: ProposedCopy[] = [];\n\n fail(path: string, message: string): null {\n this.problems.push(`${path} ${message}`);\n return null;\n }\n\n object(value: unknown, path: string): Raw | null {\n if (typeof value === \"object\" && value !== null && !Array.isArray(value)) return value as Raw;\n return this.fail(path, \"is not an object\");\n }\n\n dense(value: unknown[], path: string): boolean {\n if (isDenseArray(value)) return true;\n this.fail(path, \"contains missing entries\");\n return false;\n }\n\n optionalString(value: unknown, path: string): string | null {\n if (value === undefined || value === null) return null;\n if (typeof value === \"string\") return value.trim() === \"\" ? null : value;\n return this.fail(path, \"is not text\");\n }\n\n /** A copy value, or null when absent or empty. Records a proposed line. */\n copy(value: unknown, path: string): CopyInput | null {\n if (value === undefined || value === null) return null;\n const raw = this.object(value, path);\n if (raw === null) return null;\n const text = raw[\"text\"];\n const source = raw[\"copySource\"];\n if (text !== undefined && typeof text !== \"string\") return this.fail(`${path}.text`, \"is not text\");\n if (source !== undefined && source !== \"captured\" && source !== \"proposed\") {\n return this.fail(`${path}.copySource`, `is ${JSON.stringify(source)}, not captured or proposed`);\n }\n if (typeof text !== \"string\" || text.trim() === \"\") return null;\n if (source === \"proposed\") {\n this.proposed.push({ where: path, text });\n return { text, copySource: \"proposed\" };\n }\n if (source === \"captured\") return { text, copySource: \"captured\" };\n return text;\n }\n\n requiredCopy(value: unknown, path: string): CopyInput | null {\n const copy = this.copy(value, path);\n if (copy === null && !this.problems.some((p) => p.startsWith(path))) this.fail(path, \"is missing its words\");\n return copy;\n }\n\n photo(value: unknown, path: string): string | null {\n if (value === undefined || value === null) return null;\n if (typeof value === \"string\" && READER_PHOTO_SLUG.test(value)) return value;\n return this.fail(path, `is ${JSON.stringify(value)}, not a photo library slug`);\n }\n\n photos(value: unknown, path: string, max: number): string[] {\n if (value === undefined || value === null) return [];\n if (!Array.isArray(value)) {\n this.fail(path, \"is not a list of photos\");\n return [];\n }\n if (!this.dense(value, path)) return [];\n if (value.length > max) this.fail(path, `holds ${String(value.length)} photos; at most ${String(max)}`);\n return value.map((entry, index) => this.photo(entry, `${path}[${String(index)}]`)).filter((p): p is string => p !== null);\n }\n\n action(value: unknown, path: string): ActionInput | null {\n if (value === undefined || value === null) return null;\n const raw = this.object(value, path);\n if (raw === null) return null;\n const label = this.requiredCopy(raw[\"label\"], `${path}.label`);\n const href = raw[\"href\"];\n if (typeof href !== \"string\" || !READER_ACTION_HREF.test(href)) {\n return this.fail(`${path}.href`, `is ${JSON.stringify(href)}, not a site path, #jump-link, mailto:, tel: or web address`);\n }\n return label === null ? null : { label, href };\n }\n\n requiredAction(value: unknown, path: string): ActionInput | null {\n if (value === undefined || value === null) return this.fail(path, \"is missing\");\n return this.action(value, path);\n }\n}\n\nfunction plain(copy: CopyInput): string {\n return typeof copy === \"string\" ? copy : copy.text;\n}\n\n// ---------------------------------------------------------------------------\n// Portable Text to Markdown\n// ---------------------------------------------------------------------------\n\n/**\n * The narrow Portable Text `portableText` declares, back to Markdown: normal,\n * h2, h3 and quote blocks, bullet and numbered lists, bold, italic, code and\n * links. It is the inverse of the seed package's Markdown mapper, and the\n * round-trip test holds the two to each other.\n *\n * An uploaded image inside rich text is REFUSED, not dropped: nothing can\n * upload one yet (the dashboard slice decides how), so one arriving means\n * something wrote the document by hand, and a page silently missing a picture\n * is the failure this reader exists to prevent.\n */\nexport function portableTextToMarkdown(value: unknown): string {\n const reading = new Reading();\n const markdown = richTextToMarkdown(value, \"body\", reading);\n if (reading.problems.length > 0) throw new MalformedContentError(\"body\", reading.problems);\n return markdown;\n}\n\nfunction richTextToMarkdown(value: unknown, path: string, reading: Reading): string {\n if (value === undefined || value === null) return \"\";\n if (!Array.isArray(value)) {\n reading.fail(path, \"is not rich text\");\n return \"\";\n }\n if (!reading.dense(value, path)) return \"\";\n const out: string[] = [];\n let previousWasList = false;\n value.forEach((member, index) => {\n const at = `${path}[${String(index)}]`;\n const block = reading.object(member, at);\n if (block === null) return;\n if (block[\"_type\"] !== \"block\") {\n reading.fail(at, `is a ${JSON.stringify(block[\"_type\"])}; only text is supported in rich text so far`);\n return;\n }\n const text = spansToMarkdown(block, at, reading);\n const listItem = block[\"listItem\"];\n const style = block[\"style\"] ?? \"normal\";\n let line: string;\n if (listItem === \"bullet\" || listItem === \"number\") {\n const level = typeof block[\"level\"] === \"number\" && block[\"level\"] > 1 ? block[\"level\"] : 1;\n line = `${\" \".repeat(level - 1)}${listItem === \"bullet\" ? \"-\" : \"1.\"} ${text}`;\n } else if (style === \"h2\") line = `## ${text}`;\n else if (style === \"h3\") line = `### ${text}`;\n else if (style === \"blockquote\") line = `> ${text}`;\n else if (style === \"normal\") line = text;\n else {\n reading.fail(`${at}.style`, `is ${JSON.stringify(style)}, which the schema does not offer`);\n return;\n }\n const isList = listItem === \"bullet\" || listItem === \"number\";\n if (out.length > 0) out.push(isList && previousWasList ? \"\\n\" : \"\\n\\n\");\n out.push(line);\n previousWasList = isList;\n });\n return out.join(\"\");\n}\n\nconst DECORATORS: Record<string, string> = { strong: \"**\", em: \"*\", code: \"`\" };\n\nfunction spansToMarkdown(block: Raw, path: string, reading: Reading): string {\n const links = new Map<string, string>();\n const markDefs = Array.isArray(block[\"markDefs\"]) ? (block[\"markDefs\"] as unknown[]) : [];\n if (!reading.dense(markDefs, `${path}.markDefs`)) return \"\";\n for (const def of markDefs) {\n const d = def as Raw;\n if (d[\"_type\"] === \"link\" && typeof d[\"_key\"] === \"string\" && typeof d[\"href\"] === \"string\") links.set(d[\"_key\"], d[\"href\"]);\n }\n const children = Array.isArray(block[\"children\"]) ? (block[\"children\"] as unknown[]) : [];\n if (!reading.dense(children, `${path}.children`)) return \"\";\n return children\n .map((child, index) => {\n const span = child as Raw;\n if (span[\"_type\"] !== \"span\" || typeof span[\"text\"] !== \"string\") {\n reading.fail(`${path}.children[${String(index)}]`, \"is not a text span\");\n return \"\";\n }\n let text = span[\"text\"];\n const marks = Array.isArray(span[\"marks\"]) ? (span[\"marks\"] as unknown[]) : [];\n if (!reading.dense(marks, `${path}.children[${String(index)}].marks`)) return \"\";\n let href: string | null = null;\n for (const mark of marks) {\n if (typeof mark !== \"string\") continue;\n const fence = DECORATORS[mark];\n if (fence !== undefined) text = `${fence}${text}${fence}`;\n else if (links.has(mark)) href = links.get(mark) ?? null;\n else reading.fail(`${path}.children[${String(index)}].marks`, `names ${JSON.stringify(mark)}, which is neither a style nor a link`);\n }\n return href === null ? text : `[${text}](${href})`;\n })\n .join(\"\");\n}\n\n// ---------------------------------------------------------------------------\n// The home page\n// ---------------------------------------------------------------------------\n\n/** Whether a campaign is shown at `now`, and if not, why not. */\nexport function campaignState(campaign: unknown, now: Date): CampaignState {\n if (typeof campaign !== \"object\" || campaign === null) return \"none\";\n const c = campaign as Raw;\n if (c[\"enabled\"] !== true) return \"off\";\n const starts = typeof c[\"startsAt\"] === \"string\" ? Date.parse(c[\"startsAt\"]) : null;\n const ends = typeof c[\"endsAt\"] === \"string\" ? Date.parse(c[\"endsAt\"]) : null;\n if (starts !== null && now.getTime() < starts) return \"not-started\";\n if (ends !== null && now.getTime() >= ends) return \"ended\";\n return \"shown\";\n}\n\nfunction keyed(path: string, raw: Raw, index: number): string {\n return typeof raw[\"_key\"] === \"string\" ? `${path}[_key==\"${raw[\"_key\"]}\"]` : `${path}[${String(index)}]`;\n}\n\n/**\n * A stored home page document, validated and mapped. Throws\n * `MalformedContentError` naming every problem. `now` decides whether a\n * scheduled campaign is shown, and is a parameter so a build, a preview and a\n * test each say which moment they mean.\n */\nexport function parseHomePage(document: unknown, options: { readonly now: Date }): HomeContent {\n const reading = new Reading();\n const doc = reading.object(document, \"homePage\");\n if (doc === null) throw new MalformedContentError(READER_HOME_PAGE_ID, reading.problems);\n const id = typeof doc[\"_id\"] === \"string\" ? doc[\"_id\"] : READER_HOME_PAGE_ID;\n if (doc[\"_type\"] !== \"homePage\") reading.fail(\"_type\", `is ${JSON.stringify(doc[\"_type\"])}, not homePage`);\n\n let hero: HeroInput | null = null;\n const rawHero = doc[\"hero\"] === undefined ? reading.fail(\"hero\", \"is missing\") : reading.object(doc[\"hero\"], \"hero\");\n if (rawHero !== null) {\n const photos = reading.photos(rawHero[\"photos\"], \"hero.photos\", 2);\n const heading = reading.requiredCopy(rawHero[\"headline\"], \"hero.headline\");\n const subline = reading.copy(rawHero[\"subline\"], \"hero.subline\");\n const intro = reading.copy(rawHero[\"lead\"], \"hero.lead\");\n const cta = reading.action(rawHero[\"primaryAction\"], \"hero.primaryAction\");\n const secondaryCta = reading.action(rawHero[\"secondaryAction\"], \"hero.secondaryAction\");\n if (heading !== null) {\n hero = { heading, subline, intro, image: photos[0] ?? null, inset: photos[1] ?? null, cta, secondaryCta };\n }\n }\n\n const blocks: CompositionBlockInput[] = [];\n const blockJumps: { where: string; href: string }[] = [];\n let body = \"\";\n const state = campaignState(doc[\"campaign\"], options.now);\n if (state === \"shown\") {\n const campaign = reading.object(doc[\"campaign\"], \"campaign\");\n if (campaign !== null) {\n const title = reading.requiredCopy(campaign[\"title\"], \"campaign.title\");\n const images = reading.photos(campaign[\"photos\"], \"campaign.photos\", 3);\n if (images.length === 0) reading.fail(\"campaign.photos\", \"is empty; a shown campaign needs at least one photo\");\n const text = richTextToMarkdown(campaign[\"body\"], \"campaign.body\", reading);\n if (text === \"\") reading.fail(\"campaign.body\", \"is empty; a shown campaign needs its text\");\n if (campaign[\"bodyCopySource\"] === \"proposed\") reading.proposed.push({ where: \"campaign.body\", text });\n const action = reading.action(campaign[\"action\"], \"campaign.action\");\n if (action !== null) blockJumps.push({ where: \"campaign.action.href\", href: action.href });\n if (title !== null) body = `# ${plain(title)}\\n\\n${text}`;\n blocks.push({ kind: \"campaign\", action, images });\n }\n }\n\n const anchors: string[] = [];\n const rawBlocks = doc[\"blocks\"] ?? [];\n if (!Array.isArray(rawBlocks)) reading.fail(\"blocks\", \"is not a list\");\n else if (reading.dense(rawBlocks, \"blocks\")) {\n rawBlocks.forEach((member, index) => {\n const raw = reading.object(member, `blocks[${String(index)}]`);\n if (raw === null) return;\n const at = keyed(\"blocks\", raw, index);\n const mapped = mapBlock(raw, at, reading);\n if (mapped === null) return;\n blockJumps.push(...buttonsOf(mapped, raw, at));\n if (mapped.kind === \"locations\" && mapped.anchor !== null) {\n if (anchors.includes(mapped.anchor)) reading.fail(`${at}.jumpLink`, `repeats \"${mapped.anchor}\", already used by another section`);\n anchors.push(mapped.anchor);\n }\n blocks.push(mapped);\n });\n }\n\n // A jump link on ANY button must land on a section of this page.\n const jumps: { where: string; href: string }[] = [];\n if (hero?.cta) jumps.push({ where: \"hero.primaryAction.href\", href: hero.cta.href });\n if (hero?.secondaryCta) jumps.push({ where: \"hero.secondaryAction.href\", href: hero.secondaryCta.href });\n jumps.push(...blockJumps);\n for (const { where, href } of jumps) {\n if (href.startsWith(\"#\") && !anchors.includes(href.slice(1))) {\n reading.fail(where, `jumps to ${href}, which no section on the page is named`);\n }\n }\n\n if (reading.problems.length > 0) throw new MalformedContentError(id, reading.problems);\n return {\n composition: { intro: null, photo: null, hero, blocks },\n body,\n campaign: state,\n proposedCopy: reading.proposed,\n };\n}\n\n/** Every button a mapped section carries, with its path in the stored document. */\nfunction buttonsOf(block: CompositionBlockInput, raw: Raw, at: string): { where: string; href: string }[] {\n switch (block.kind) {\n case \"feature_stories\": {\n const stories = Array.isArray(raw[\"stories\"]) ? (raw[\"stories\"] as Raw[]) : [];\n return block.items.map((item, index) => ({\n where: `${keyed(`${at}.stories`, stories[index] ?? {}, index)}.action.href`,\n href: item.action.href,\n }));\n }\n case \"accent_band\":\n return block.action === null ? [] : [{ where: `${at}.action.href`, href: block.action.href }];\n case \"cta\":\n return [{ where: `${at}.action.href`, href: block.link.href }];\n default:\n return [];\n }\n}\n\nfunction mapBlock(raw: Raw, at: string, reading: Reading): CompositionBlockInput | null {\n switch (raw[\"_type\"]) {\n case \"featureStoriesBlock\": {\n const heading = reading.requiredCopy(raw[\"heading\"], `${at}.heading`);\n const tail = reading.copy(raw[\"tail\"], `${at}.tail`);\n const stories = raw[\"stories\"];\n if (!Array.isArray(stories) || stories.length === 0) return reading.fail(`${at}.stories`, \"has no stories\");\n if (!reading.dense(stories, `${at}.stories`)) return null;\n const items: StoryInput[] = [];\n stories.forEach((member, index) => {\n const story = reading.object(member, `${at}.stories[${String(index)}]`);\n if (story === null) return;\n const sat = keyed(`${at}.stories`, story, index);\n const sHeading = reading.requiredCopy(story[\"heading\"], `${sat}.heading`);\n const sBody = reading.requiredCopy(story[\"body\"], `${sat}.body`);\n const action = reading.requiredAction(story[\"action\"], `${sat}.action`);\n const image = reading.photo(story[\"photo\"], `${sat}.photo`);\n const layout = story[\"layout\"] ?? \"wide\";\n if (!(READER_STORY_LAYOUTS as readonly unknown[]).includes(layout)) {\n reading.fail(`${sat}.layout`, `is ${JSON.stringify(layout)}, not wide, tall, round or free`);\n return;\n }\n const onCard = story[\"onCard\"] ?? false;\n if (typeof onCard !== \"boolean\") {\n reading.fail(`${sat}.onCard`, \"is not on or off\");\n return;\n }\n if (sHeading === null || sBody === null || action === null) return;\n items.push({ heading: sHeading, body: sBody, action, image, shape: layout as StoryInput[\"shape\"], card: onCard });\n });\n return heading === null ? null : { kind: \"feature_stories\", heading, tail, items };\n }\n case \"surfaceCardBlock\": {\n const heading = reading.requiredCopy(raw[\"heading\"], `${at}.heading`);\n const body = reading.copy(raw[\"body\"], `${at}.body`);\n const action = reading.requiredAction(raw[\"action\"], `${at}.action`);\n if (heading === null || action === null) return null;\n return {\n kind: \"cta\",\n heading: plain(heading),\n body: body === null ? null : plain(body),\n link: { label: plain(action.label), href: action.href },\n };\n }\n case \"accentBandBlock\": {\n const heading = reading.requiredCopy(raw[\"heading\"], `${at}.heading`);\n const body = reading.requiredCopy(raw[\"body\"], `${at}.body`);\n const action = reading.action(raw[\"action\"], `${at}.action`);\n const image = reading.photo(raw[\"photo\"], `${at}.photo`);\n if (heading === null || body === null) return null;\n return { kind: \"accent_band\", heading, body, action, image };\n }\n case \"locationsBlock\": {\n const jump = raw[\"jumpLink\"];\n let anchor: string | null = null;\n if (jump !== undefined && jump !== null && jump !== \"\") {\n if (typeof jump !== \"string\" || !READER_JUMP_LINK.test(jump)) reading.fail(`${at}.jumpLink`, `is ${JSON.stringify(jump)}, not lowercase words joined by hyphens`);\n else anchor = jump;\n }\n const heading = reading.requiredCopy(raw[\"heading\"], `${at}.heading`);\n const tail = reading.copy(raw[\"tail\"], `${at}.tail`);\n const image = reading.photo(raw[\"photo\"], `${at}.photo`);\n return heading === null ? null : { kind: \"locations\", anchor, heading, tail, image };\n }\n default:\n return reading.fail(`${at}._type`, `is ${JSON.stringify(raw[\"_type\"])}, not a section type this reader knows`);\n }\n}\n\n// ---------------------------------------------------------------------------\n// Content pages and settings\n// ---------------------------------------------------------------------------\n\nexport function parseContentPage(document: unknown): PageContent {\n const reading = new Reading();\n const doc = reading.object(document, \"page\");\n if (doc === null) throw new MalformedContentError(\"page\", reading.problems);\n const id = typeof doc[\"_id\"] === \"string\" ? doc[\"_id\"] : \"page\";\n if (doc[\"_type\"] !== \"page\") reading.fail(\"_type\", `is ${JSON.stringify(doc[\"_type\"])}, not page`);\n const title = reading.optionalString(doc[\"title\"], \"title\");\n if (title === null) reading.fail(\"title\", \"is missing\");\n if (doc[\"titleCopySource\"] === \"proposed\" && title !== null) reading.proposed.push({ where: \"title\", text: title });\n const slugObject = doc[\"slug\"] as Raw | undefined;\n const slug = typeof slugObject?.[\"current\"] === \"string\" && slugObject[\"current\"] !== \"\" ? slugObject[\"current\"] : null;\n if (slug === null) reading.fail(\"slug.current\", \"is missing\");\n const lead = reading.copy(doc[\"lead\"], \"lead\");\n const photo = reading.photo(doc[\"photo\"], \"photo\");\n const body = richTextToMarkdown(doc[\"body\"], \"body\", reading);\n if (doc[\"bodyCopySource\"] === \"proposed\") reading.proposed.push({ where: \"body\", text: body });\n if (reading.problems.length > 0 || title === null || slug === null) throw new MalformedContentError(id, reading.problems);\n return {\n slug,\n title,\n composition: { intro: lead === null ? null : plain(lead), photo, hero: null, blocks: [] },\n body,\n migrated: doc[\"migrated\"] === true,\n proposedCopy: reading.proposed,\n };\n}\n\nexport function parseSiteSettings(document: unknown): SiteSettingsContent {\n const reading = new Reading();\n const doc = reading.object(document, \"siteSettings\");\n if (doc === null) throw new MalformedContentError(READER_SITE_SETTINGS_ID, reading.problems);\n const name = reading.optionalString(doc[\"title\"], \"title\");\n if (name === null) reading.fail(\"title\", \"is missing; a site needs its name\");\n const description = reading.optionalString(doc[\"description\"], \"description\");\n const contact = doc[\"contact\"] === undefined ? {} : (reading.object(doc[\"contact\"], \"contact\") ?? {});\n const email = reading.optionalString(contact[\"email\"], \"contact.email\");\n const phone = reading.optionalString(contact[\"phone\"], \"contact.phone\");\n const social: { network: string; url: string }[] = [];\n const rawSocial = doc[\"social\"] ?? [];\n if (!Array.isArray(rawSocial)) reading.fail(\"social\", \"is not a list\");\n else if (reading.dense(rawSocial, \"social\"))\n rawSocial.forEach((member, index) => {\n const link = reading.object(member, `social[${String(index)}]`);\n if (link === null) return;\n const network = reading.optionalString(link[\"network\"], `social[${String(index)}].network`);\n const url = reading.optionalString(link[\"url\"], `social[${String(index)}].url`);\n if (network === null || url === null || !/^https?:\\/\\//.test(url)) {\n reading.fail(`social[${String(index)}]`, \"needs a network and a web address\");\n return;\n }\n social.push({ network, url });\n });\n if (reading.problems.length > 0 || name === null) throw new MalformedContentError(READER_SITE_SETTINGS_ID, reading.problems);\n return { name, description, contact: { email, phone }, social };\n}\n\n// ---------------------------------------------------------------------------\n// Queries\n// ---------------------------------------------------------------------------\n\n/** By fixed id: a second home page at a random id is never read. */\nexport const HOME_PAGE_DOCUMENT_QUERY = `*[_id == $id][0]`;\nexport const CONTENT_PAGES_QUERY = `*[_type == \"page\" && defined(slug.current)]|order(slug.current asc)`;\nexport const CONTENT_PAGE_BY_SLUG_QUERY = `*[_type == \"page\" && slug.current == $slug][0]`;\n\nexport interface SiteContentReader {\n /** `null` when no home page document exists yet. */\n home: (options: { readonly now: Date }) => Promise<HomeContent | null>;\n pages: () => Promise<PageContent[]>;\n /** `null` when no page has that slug. */\n pageBySlug: (slug: string) => Promise<PageContent | null>;\n /** `null` before anyone has filled in the site's details. */\n siteSettings: () => Promise<SiteSettingsContent | null>;\n}\n\nexport function createSiteContentReader(client: { query: <T>(groq: string, options?: { params?: Record<string, unknown>; tags?: readonly string[] }) => Promise<T> }): SiteContentReader {\n return {\n home: async ({ now }) => {\n const doc = await client.query<unknown>(HOME_PAGE_DOCUMENT_QUERY, { params: { id: READER_HOME_PAGE_ID } });\n return doc === null || doc === undefined ? null : parseHomePage(doc, { now });\n },\n pages: async () => {\n const docs = await client.query<unknown>(CONTENT_PAGES_QUERY);\n if (!Array.isArray(docs)) throw new MalformedContentError(\"page\", [\"the page query did not return a list\"]);\n if (!isDenseArray(docs)) throw new MalformedContentError(\"page\", [\"the page query contains missing entries\"]);\n return docs.map((doc) => parseContentPage(doc));\n },\n pageBySlug: async (slug) => {\n const doc = await client.query<unknown>(CONTENT_PAGE_BY_SLUG_QUERY, { params: { slug } });\n return doc === null || doc === undefined ? null : parseContentPage(doc);\n },\n siteSettings: async () => {\n const doc = await client.query<unknown>(HOME_PAGE_DOCUMENT_QUERY, { params: { id: READER_SITE_SETTINGS_ID } });\n return doc === null || doc === undefined ? null : parseSiteSettings(doc);\n },\n };\n}\n\nfunction atomic<T>(raw: unknown, fallback: T, parse: (value: unknown) => T, validFallback: (value: unknown) => boolean): CmsResolution<T> {\n if (!validFallback(fallback)) throw new TypeError(\"Invalid CMS content fallback\");\n if (raw === null || raw === undefined) return { data: fallback, fallbackFields: [\"$\"] };\n // The server reader catches parser errors and classifies the whole fallback\n // as malformed. Returning fallback here would lose that diagnostic reason.\n return { data: parse(raw), fallbackFields: [] };\n}\n\nexport function homeContentQuery(now: Date): CmsQuery<HomeContent | null> {\n if (!(now instanceof Date) || !Number.isFinite(now.getTime())) throw new TypeError(\"Invalid CMS campaign date\");\n const captured = now.getTime();\n return defineCmsQuery({\n name: \"homePage.v1\", query: HOME_PAGE_DOCUMENT_QUERY, params: { id: READER_HOME_PAGE_ID },\n dependencies: { types: [\"homePage\"], ids: [READER_HOME_PAGE_ID] },\n resolve: (raw, fallback) => atomic(raw, fallback, (value) => parseHomePage(value, { now: new Date(captured) }), validHomeFallback),\n });\n}\n\nexport function contentPageQuery(slug: string): CmsQuery<PageContent | null> {\n if (typeof slug !== \"string\" || slug === \"\") throw new TypeError(\"Invalid CMS page slug\");\n return defineCmsQuery({\n name: \"page.v1\", query: CONTENT_PAGE_BY_SLUG_QUERY, params: { slug }, dependencies: { types: [\"page\"] },\n resolve: (raw, fallback) => atomic(raw, fallback, parseContentPage, validPageFallback),\n });\n}\n\nexport function contentPagesQuery(): CmsQuery<readonly PageContent[]> {\n return defineCmsQuery({\n name: \"pages.v1\", query: CONTENT_PAGES_QUERY, params: {}, dependencies: { types: [\"page\"] },\n resolve: (raw, fallback) => atomic(raw, fallback, (value) => {\n if (!Array.isArray(value)) throw new MalformedContentError(\"page\", [\"the page query did not return a list\"]);\n if (!isDenseArray(value)) throw new MalformedContentError(\"page\", [\"the page query contains missing entries\"]);\n return value.map((document: unknown) => parseContentPage(document));\n }, (value) => isDenseArray(value) && value.every((page: unknown) => page !== null && validPageFallback(page))),\n });\n}\n\nexport function siteSettingsQuery(): CmsQuery<SiteSettingsContent | null> {\n return defineCmsQuery({\n name: \"siteSettings.v1\", query: HOME_PAGE_DOCUMENT_QUERY, params: { id: READER_SITE_SETTINGS_ID },\n dependencies: { types: [\"siteSettings\"], ids: [READER_SITE_SETTINGS_ID] },\n resolve: (raw, fallback) => atomic(raw, fallback, parseSiteSettings, validSettingsFallback),\n });\n}\n"],
5
+ "mappings": "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",
6
+ "names": ["site_content_exports", "__export", "CONTENT_PAGES_QUERY", "CONTENT_PAGE_BY_SLUG_QUERY", "HOME_PAGE_DOCUMENT_QUERY", "MALFORMED_CONTENT", "MalformedContentError", "READER_ACTION_HREF", "READER_HOME_PAGE_ID", "READER_JUMP_LINK", "READER_PHOTO_SLUG", "READER_SITE_SETTINGS_ID", "READER_STORY_LAYOUTS", "campaignState", "contentPageQuery", "contentPagesQuery", "createSiteContentReader", "homeContentQuery", "parseContentPage", "parseHomePage", "parseSiteSettings", "portableTextToMarkdown", "siteSettingsQuery", "__toCommonJS", "isDenseArray", "value", "index", "TYPE", "ID", "dependenciesCopy", "dependencies", "types", "type", "TYPE", "ids", "id", "ID", "defineCmsQuery", "query", "params", "copied", "key", "descriptor", "value", "object", "value", "words", "nullableText", "photo", "READER_PHOTO_SLUG", "href", "READER_ACTION_HREF", "copy", "optionalCopy", "action", "optionalAction", "composition", "isDenseArray", "hero", "block", "image", "READER_JUMP_LINK", "item", "READER_STORY_LAYOUTS", "layout", "model", "anchors", "link", "proposed", "line", "validHomeFallback", "validPageFallback", "validSettingsFallback", "MALFORMED_CONTENT", "MalformedContentError", "documentId", "problems", "READER_PHOTO_SLUG", "READER_ACTION_HREF", "READER_JUMP_LINK", "READER_STORY_LAYOUTS", "READER_HOME_PAGE_ID", "READER_SITE_SETTINGS_ID", "Reading", "path", "message", "value", "isDenseArray", "raw", "text", "source", "copy", "p", "max", "entry", "index", "label", "href", "plain", "portableTextToMarkdown", "reading", "markdown", "richTextToMarkdown", "out", "previousWasList", "member", "at", "block", "spansToMarkdown", "listItem", "style", "line", "level", "isList", "DECORATORS", "links", "markDefs", "def", "d", "children", "child", "span", "marks", "mark", "fence", "campaignState", "campaign", "now", "c", "starts", "ends", "keyed", "parseHomePage", "document", "options", "doc", "id", "hero", "rawHero", "photos", "heading", "subline", "intro", "cta", "secondaryCta", "blocks", "blockJumps", "body", "state", "title", "images", "action", "anchors", "rawBlocks", "mapped", "mapBlock", "buttonsOf", "jumps", "where", "stories", "item", "tail", "items", "story", "sat", "sHeading", "sBody", "image", "layout", "onCard", "jump", "anchor", "parseContentPage", "slugObject", "slug", "lead", "photo", "parseSiteSettings", "name", "description", "contact", "email", "phone", "social", "rawSocial", "link", "network", "url", "HOME_PAGE_DOCUMENT_QUERY", "CONTENT_PAGES_QUERY", "CONTENT_PAGE_BY_SLUG_QUERY", "createSiteContentReader", "client", "docs", "atomic", "fallback", "parse", "validFallback", "homeContentQuery", "captured", "defineCmsQuery", "validHomeFallback", "contentPageQuery", "validPageFallback", "contentPagesQuery", "page", "siteSettingsQuery", "validSettingsFallback"]
7
+ }
@@ -0,0 +1,2 @@
1
+ export { MALFORMED_CONTENT, MalformedContentError, parseHomePage, parseContentPage, parseSiteSettings, portableTextToMarkdown, campaignState, HOME_PAGE_DOCUMENT_QUERY, CONTENT_PAGES_QUERY, CONTENT_PAGE_BY_SLUG_QUERY, createSiteContentReader, READER_PHOTO_SLUG, READER_ACTION_HREF, READER_JUMP_LINK, READER_STORY_LAYOUTS, READER_HOME_PAGE_ID, READER_SITE_SETTINGS_ID, homeContentQuery, contentPageQuery, contentPagesQuery, siteSettingsQuery, } from "./portable/site-content.cjs";
2
+ export type { CopyInput, ActionInput, HeroInput, StoryInput, CompositionBlockInput, CompositionInput, ProposedCopy, CampaignState, HomeContent, PageContent, SiteSettingsContent, SiteContentReader, } from "./portable/site-content.cjs";
@@ -0,0 +1,2 @@
1
+ export { MALFORMED_CONTENT, MalformedContentError, parseHomePage, parseContentPage, parseSiteSettings, portableTextToMarkdown, campaignState, HOME_PAGE_DOCUMENT_QUERY, CONTENT_PAGES_QUERY, CONTENT_PAGE_BY_SLUG_QUERY, createSiteContentReader, READER_PHOTO_SLUG, READER_ACTION_HREF, READER_JUMP_LINK, READER_STORY_LAYOUTS, READER_HOME_PAGE_ID, READER_SITE_SETTINGS_ID, homeContentQuery, contentPageQuery, contentPagesQuery, siteSettingsQuery, } from "./portable/site-content.mjs";
2
+ export type { CopyInput, ActionInput, HeroInput, StoryInput, CompositionBlockInput, CompositionInput, ProposedCopy, CampaignState, HomeContent, PageContent, SiteSettingsContent, SiteContentReader, } from "./portable/site-content.mjs";
@@ -0,0 +1,2 @@
1
+ export { MALFORMED_CONTENT, MalformedContentError, parseHomePage, parseContentPage, parseSiteSettings, portableTextToMarkdown, campaignState, HOME_PAGE_DOCUMENT_QUERY, CONTENT_PAGES_QUERY, CONTENT_PAGE_BY_SLUG_QUERY, createSiteContentReader, READER_PHOTO_SLUG, READER_ACTION_HREF, READER_JUMP_LINK, READER_STORY_LAYOUTS, READER_HOME_PAGE_ID, READER_SITE_SETTINGS_ID, homeContentQuery, contentPageQuery, contentPagesQuery, siteSettingsQuery, } from "./portable/site-content.js";
2
+ export type { CopyInput, ActionInput, HeroInput, StoryInput, CompositionBlockInput, CompositionInput, ProposedCopy, CampaignState, HomeContent, PageContent, SiteSettingsContent, SiteContentReader, } from "./portable/site-content.js";
@@ -0,0 +1,7 @@
1
+ function b(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 tn=/^[A-Za-z][A-Za-z0-9_]{0,63}$/,on=/^[A-Za-z0-9][A-Za-z0-9._-]{0,127}$/;function rn(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"||!tn.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"||!on.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 I(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 s=Object.getOwnPropertyDescriptor(n,o);if(typeof o!="string"||!s||!Object.hasOwn(s,"value")||!s.enumerable)throw new TypeError("CMS params must be plain JSON scalars");let i=s.value;if(!(i===null||typeof i=="string"||typeof i=="boolean"||typeof i=="number"&&Number.isFinite(i)))throw new TypeError("CMS params must be plain JSON scalars");Object.defineProperty(t,o,{value:i,enumerable:!0})}return Object.freeze({name:e.name,query:e.query,params:Object.freeze(t),dependencies:rn(e.dependencies),resolve:e.resolve})}var w=e=>e!==null&&typeof e=="object"&&!Array.isArray(e),$=e=>typeof e=="string"&&e.trim()!=="",T=e=>e===null||typeof e=="string",A=e=>e===null||typeof e=="string"&&N.test(e),Z=e=>typeof e=="string"&&M.test(e),k=e=>$(e)||w(e)&&$(e.text)&&(e.copySource==="captured"||e.copySource==="proposed"),D=e=>e===null||k(e),K=e=>w(e)&&k(e.label)&&Z(e.href),j=e=>e===null||K(e);function W(e){if(!w(e)||!T(e.intro)||!A(e.photo)||!b(e.blocks))return!1;let n=e.hero;if(n!==null&&(!w(n)||!k(n.heading)||!D(n.subline)||!D(n.intro)||!A(n.image)||!A(n.inset)||!j(n.cta)||!j(n.secondaryCta))||!e.blocks.every(r=>{if(!w(r))return!1;switch(r.kind){case"campaign":return j(r.action)&&b(r.images)&&r.images.every(a=>typeof a=="string"&&A(a));case"locations":return(r.anchor===null||typeof r.anchor=="string"&&H.test(r.anchor))&&k(r.heading)&&D(r.tail)&&A(r.image);case"feature_stories":return k(r.heading)&&D(r.tail)&&b(r.items)&&r.items.length>0&&r.items.every(a=>w(a)&&k(a.heading)&&k(a.body)&&K(a.action)&&A(a.image)&&q.some(l=>l===a.shape)&&typeof a.card=="boolean");case"accent_band":return k(r.heading)&&k(r.body)&&j(r.action)&&A(r.image);case"cta":return $(r.heading)&&T(r.body)&&w(r.link)&&$(r.link.label)&&Z(r.link.href);default:return!1}}))return!1;let o=e,s=o.blocks.flatMap(r=>r.kind==="locations"&&r.anchor!==null?[r.anchor]:[]);return new Set(s).size!==s.length?!1:[o.hero?.cta?.href,o.hero?.secondaryCta?.href,...o.blocks.flatMap(r=>{switch(r.kind){case"campaign":case"accent_band":return[r.action?.href];case"feature_stories":return r.items.map(a=>a.action.href);case"cta":return[r.link.href];default:return[]}})].every(r=>r===void 0||!r.startsWith("#")||s.includes(r.slice(1)))}function V(e){return b(e)&&e.every(n=>w(n)&&$(n.where)&&typeof n.text=="string")}function X(e){return e===null||w(e)&&W(e.composition)&&typeof e.body=="string"&&V(e.proposedCopy)&&typeof e.campaign=="string"&&["shown","off","not-started","ended","none"].includes(e.campaign)}function Q(e){return e===null||w(e)&&$(e.slug)&&$(e.title)&&W(e.composition)&&typeof e.body=="string"&&typeof e.migrated=="boolean"&&V(e.proposedCopy)}function v(e){return e===null||w(e)&&$(e.name)&&T(e.description)&&w(e.contact)&&T(e.contact.email)&&T(e.contact.phone)&&b(e.social)&&e.social.every(n=>w(n)&&$(n.network)&&typeof n.url=="string"&&/^https?:\/\//.test(n.url))}var B="malformed-content",m=class extends Error{code=B;documentId;problems;constructor(n,t){super(`${B}: ${n}: ${t.join("; ")}`),this.name="MalformedContentError",this.documentId=n,this.problems=t}},N=/^[a-z0-9]+(?:-[a-z0-9]+)*$/,M=/^(?:\/(?![/\\])[^\s]*|#[a-z][a-z0-9]*(?:-[a-z0-9]+)*|mailto:[^\s@]+@[^\s@]+|tel:\+?[0-9][0-9 ()-]*|https?:\/\/[^\s/]+[^\s]*)$/,H=/^[a-z][a-z0-9]*(?:-[a-z0-9]+)*$/,q=["wide","tall","round","free"],_="homePage",E="siteSettings",R=class{problems=[];proposed=[];fail(n,t){return this.problems.push(`${n} ${t}`),null}object(n,t){return typeof n=="object"&&n!==null&&!Array.isArray(n)?n:this.fail(t,"is not an object")}dense(n,t){return b(n)?!0:(this.fail(t,"contains missing entries"),!1)}optionalString(n,t){return n==null?null:typeof n=="string"?n.trim()===""?null:n:this.fail(t,"is not text")}copy(n,t){if(n==null)return null;let o=this.object(n,t);if(o===null)return null;let s=o.text,i=o.copySource;return s!==void 0&&typeof s!="string"?this.fail(`${t}.text`,"is not text"):i!==void 0&&i!=="captured"&&i!=="proposed"?this.fail(`${t}.copySource`,`is ${JSON.stringify(i)}, not captured or proposed`):typeof s!="string"||s.trim()===""?null:i==="proposed"?(this.proposed.push({where:t,text:s}),{text:s,copySource:"proposed"}):i==="captured"?{text:s,copySource:"captured"}:s}requiredCopy(n,t){let o=this.copy(n,t);return o===null&&!this.problems.some(s=>s.startsWith(t))&&this.fail(t,"is missing its words"),o}photo(n,t){return n==null?null:typeof n=="string"&&N.test(n)?n:this.fail(t,`is ${JSON.stringify(n)}, not a photo library slug`)}photos(n,t,o){return n==null?[]:Array.isArray(n)?this.dense(n,t)?(n.length>o&&this.fail(t,`holds ${String(n.length)} photos; at most ${String(o)}`),n.map((s,i)=>this.photo(s,`${t}[${String(i)}]`)).filter(s=>s!==null)):[]:(this.fail(t,"is not a list of photos"),[])}action(n,t){if(n==null)return null;let o=this.object(n,t);if(o===null)return null;let s=this.requiredCopy(o.label,`${t}.label`),i=o.href;return typeof i!="string"||!M.test(i)?this.fail(`${t}.href`,`is ${JSON.stringify(i)}, not a site path, #jump-link, mailto:, tel: or web address`):s===null?null:{label:s,href:i}}requiredAction(n,t){return n==null?this.fail(t,"is missing"):this.action(n,t)}};function O(e){return typeof e=="string"?e:e.text}function sn(e){let n=new R,t=U(e,"body",n);if(n.problems.length>0)throw new m("body",n.problems);return t}function U(e,n,t){if(e==null)return"";if(!Array.isArray(e))return t.fail(n,"is not rich text"),"";if(!t.dense(e,n))return"";let o=[],s=!1;return e.forEach((i,r)=>{let a=`${n}[${String(r)}]`,l=t.object(i,a);if(l===null)return;if(l._type!=="block"){t.fail(a,`is a ${JSON.stringify(l._type)}; only text is supported in rich text so far`);return}let p=ln(l,a,t),y=l.listItem,u=l.style??"normal",c;if(y==="bullet"||y==="number"){let d=typeof l.level=="number"&&l.level>1?l.level:1;c=`${" ".repeat(d-1)}${y==="bullet"?"-":"1."} ${p}`}else if(u==="h2")c=`## ${p}`;else if(u==="h3")c=`### ${p}`;else if(u==="blockquote")c=`> ${p}`;else if(u==="normal")c=p;else{t.fail(`${a}.style`,`is ${JSON.stringify(u)}, which the schema does not offer`);return}let f=y==="bullet"||y==="number";o.length>0&&o.push(f&&s?`
2
+ `:`
3
+
4
+ `),o.push(c),s=f}),o.join("")}var an={strong:"**",em:"*",code:"`"};function ln(e,n,t){let o=new Map,s=Array.isArray(e.markDefs)?e.markDefs:[];if(!t.dense(s,`${n}.markDefs`))return"";for(let r of s){let a=r;a._type==="link"&&typeof a._key=="string"&&typeof a.href=="string"&&o.set(a._key,a.href)}let i=Array.isArray(e.children)?e.children:[];return t.dense(i,`${n}.children`)?i.map((r,a)=>{let l=r;if(l._type!=="span"||typeof l.text!="string")return t.fail(`${n}.children[${String(a)}]`,"is not a text span"),"";let p=l.text,y=Array.isArray(l.marks)?l.marks:[];if(!t.dense(y,`${n}.children[${String(a)}].marks`))return"";let u=null;for(let c of y){if(typeof c!="string")continue;let f=an[c];f!==void 0?p=`${f}${p}${f}`:o.has(c)?u=o.get(c)??null:t.fail(`${n}.children[${String(a)}].marks`,`names ${JSON.stringify(c)}, which is neither a style nor a link`)}return u===null?p:`[${p}](${u})`}).join(""):""}function nn(e,n){if(typeof e!="object"||e===null)return"none";let t=e;if(t.enabled!==!0)return"off";let o=typeof t.startsAt=="string"?Date.parse(t.startsAt):null,s=typeof t.endsAt=="string"?Date.parse(t.endsAt):null;return o!==null&&n.getTime()<o?"not-started":s!==null&&n.getTime()>=s?"ended":"shown"}function J(e,n,t){return typeof n._key=="string"?`${e}[_key=="${n._key}"]`:`${e}[${String(t)}]`}function L(e,n){let t=new R,o=t.object(e,"homePage");if(o===null)throw new m(_,t.problems);let s=typeof o._id=="string"?o._id:_;o._type!=="homePage"&&t.fail("_type",`is ${JSON.stringify(o._type)}, not homePage`);let i=null,r=o.hero===void 0?t.fail("hero","is missing"):t.object(o.hero,"hero");if(r!==null){let d=t.photos(r.photos,"hero.photos",2),g=t.requiredCopy(r.headline,"hero.headline"),C=t.copy(r.subline,"hero.subline"),S=t.copy(r.lead,"hero.lead"),h=t.action(r.primaryAction,"hero.primaryAction"),en=t.action(r.secondaryAction,"hero.secondaryAction");g!==null&&(i={heading:g,subline:C,intro:S,image:d[0]??null,inset:d[1]??null,cta:h,secondaryCta:en})}let a=[],l=[],p="",y=nn(o.campaign,n.now);if(y==="shown"){let d=t.object(o.campaign,"campaign");if(d!==null){let g=t.requiredCopy(d.title,"campaign.title"),C=t.photos(d.photos,"campaign.photos",3);C.length===0&&t.fail("campaign.photos","is empty; a shown campaign needs at least one photo");let S=U(d.body,"campaign.body",t);S===""&&t.fail("campaign.body","is empty; a shown campaign needs its text"),d.bodyCopySource==="proposed"&&t.proposed.push({where:"campaign.body",text:S});let h=t.action(d.action,"campaign.action");h!==null&&l.push({where:"campaign.action.href",href:h.href}),g!==null&&(p=`# ${O(g)}
5
+
6
+ ${S}`),a.push({kind:"campaign",action:h,images:C})}}let u=[],c=o.blocks??[];Array.isArray(c)?t.dense(c,"blocks")&&c.forEach((d,g)=>{let C=t.object(d,`blocks[${String(g)}]`);if(C===null)return;let S=J("blocks",C,g),h=cn(C,S,t);h!==null&&(l.push(...pn(h,C,S)),h.kind==="locations"&&h.anchor!==null&&(u.includes(h.anchor)&&t.fail(`${S}.jumpLink`,`repeats "${h.anchor}", already used by another section`),u.push(h.anchor)),a.push(h))}):t.fail("blocks","is not a list");let f=[];i?.cta&&f.push({where:"hero.primaryAction.href",href:i.cta.href}),i?.secondaryCta&&f.push({where:"hero.secondaryAction.href",href:i.secondaryCta.href}),f.push(...l);for(let{where:d,href:g}of f)g.startsWith("#")&&!u.includes(g.slice(1))&&t.fail(d,`jumps to ${g}, which no section on the page is named`);if(t.problems.length>0)throw new m(s,t.problems);return{composition:{intro:null,photo:null,hero:i,blocks:a},body:p,campaign:y,proposedCopy:t.proposed}}function pn(e,n,t){switch(e.kind){case"feature_stories":{let o=Array.isArray(n.stories)?n.stories:[];return e.items.map((s,i)=>({where:`${J(`${t}.stories`,o[i]??{},i)}.action.href`,href:s.action.href}))}case"accent_band":return e.action===null?[]:[{where:`${t}.action.href`,href:e.action.href}];case"cta":return[{where:`${t}.action.href`,href:e.link.href}];default:return[]}}function cn(e,n,t){switch(e._type){case"featureStoriesBlock":{let o=t.requiredCopy(e.heading,`${n}.heading`),s=t.copy(e.tail,`${n}.tail`),i=e.stories;if(!Array.isArray(i)||i.length===0)return t.fail(`${n}.stories`,"has no stories");if(!t.dense(i,`${n}.stories`))return null;let r=[];return i.forEach((a,l)=>{let p=t.object(a,`${n}.stories[${String(l)}]`);if(p===null)return;let y=J(`${n}.stories`,p,l),u=t.requiredCopy(p.heading,`${y}.heading`),c=t.requiredCopy(p.body,`${y}.body`),f=t.requiredAction(p.action,`${y}.action`),d=t.photo(p.photo,`${y}.photo`),g=p.layout??"wide";if(!q.includes(g)){t.fail(`${y}.layout`,`is ${JSON.stringify(g)}, not wide, tall, round or free`);return}let C=p.onCard??!1;if(typeof C!="boolean"){t.fail(`${y}.onCard`,"is not on or off");return}u===null||c===null||f===null||r.push({heading:u,body:c,action:f,image:d,shape:g,card:C})}),o===null?null:{kind:"feature_stories",heading:o,tail:s,items:r}}case"surfaceCardBlock":{let o=t.requiredCopy(e.heading,`${n}.heading`),s=t.copy(e.body,`${n}.body`),i=t.requiredAction(e.action,`${n}.action`);return o===null||i===null?null:{kind:"cta",heading:O(o),body:s===null?null:O(s),link:{label:O(i.label),href:i.href}}}case"accentBandBlock":{let o=t.requiredCopy(e.heading,`${n}.heading`),s=t.requiredCopy(e.body,`${n}.body`),i=t.action(e.action,`${n}.action`),r=t.photo(e.photo,`${n}.photo`);return o===null||s===null?null:{kind:"accent_band",heading:o,body:s,action:i,image:r}}case"locationsBlock":{let o=e.jumpLink,s=null;o!=null&&o!==""&&(typeof o!="string"||!H.test(o)?t.fail(`${n}.jumpLink`,`is ${JSON.stringify(o)}, not lowercase words joined by hyphens`):s=o);let i=t.requiredCopy(e.heading,`${n}.heading`),r=t.copy(e.tail,`${n}.tail`),a=t.photo(e.photo,`${n}.photo`);return i===null?null:{kind:"locations",anchor:s,heading:i,tail:r,image:a}}default:return t.fail(`${n}._type`,`is ${JSON.stringify(e._type)}, not a section type this reader knows`)}}function x(e){let n=new R,t=n.object(e,"page");if(t===null)throw new m("page",n.problems);let o=typeof t._id=="string"?t._id:"page";t._type!=="page"&&n.fail("_type",`is ${JSON.stringify(t._type)}, not page`);let s=n.optionalString(t.title,"title");s===null&&n.fail("title","is missing"),t.titleCopySource==="proposed"&&s!==null&&n.proposed.push({where:"title",text:s});let i=t.slug,r=typeof i?.current=="string"&&i.current!==""?i.current:null;r===null&&n.fail("slug.current","is missing");let a=n.copy(t.lead,"lead"),l=n.photo(t.photo,"photo"),p=U(t.body,"body",n);if(t.bodyCopySource==="proposed"&&n.proposed.push({where:"body",text:p}),n.problems.length>0||s===null||r===null)throw new m(o,n.problems);return{slug:r,title:s,composition:{intro:a===null?null:O(a),photo:l,hero:null,blocks:[]},body:p,migrated:t.migrated===!0,proposedCopy:n.proposed}}function F(e){let n=new R,t=n.object(e,"siteSettings");if(t===null)throw new m(E,n.problems);let o=n.optionalString(t.title,"title");o===null&&n.fail("title","is missing; a site needs its name");let s=n.optionalString(t.description,"description"),i=t.contact===void 0?{}:n.object(t.contact,"contact")??{},r=n.optionalString(i.email,"contact.email"),a=n.optionalString(i.phone,"contact.phone"),l=[],p=t.social??[];if(Array.isArray(p)?n.dense(p,"social")&&p.forEach((y,u)=>{let c=n.object(y,`social[${String(u)}]`);if(c===null)return;let f=n.optionalString(c.network,`social[${String(u)}].network`),d=n.optionalString(c.url,`social[${String(u)}].url`);if(f===null||d===null||!/^https?:\/\//.test(d)){n.fail(`social[${String(u)}]`,"needs a network and a web address");return}l.push({network:f,url:d})}):n.fail("social","is not a list"),n.problems.length>0||o===null)throw new m(E,n.problems);return{name:o,description:s,contact:{email:r,phone:a},social:l}}var P="*[_id == $id][0]",G='*[_type == "page" && defined(slug.current)]|order(slug.current asc)',Y='*[_type == "page" && slug.current == $slug][0]';function un(e){return{home:async({now:n})=>{let t=await e.query(P,{params:{id:_}});return t==null?null:L(t,{now:n})},pages:async()=>{let n=await e.query(G);if(!Array.isArray(n))throw new m("page",["the page query did not return a list"]);if(!b(n))throw new m("page",["the page query contains missing entries"]);return n.map(t=>x(t))},pageBySlug:async n=>{let t=await e.query(Y,{params:{slug:n}});return t==null?null:x(t)},siteSettings:async()=>{let n=await e.query(P,{params:{id:E}});return n==null?null:F(n)}}}function z(e,n,t,o){if(!o(n))throw new TypeError("Invalid CMS content fallback");return e==null?{data:n,fallbackFields:["$"]}:{data:t(e),fallbackFields:[]}}function dn(e){if(!(e instanceof Date)||!Number.isFinite(e.getTime()))throw new TypeError("Invalid CMS campaign date");let n=e.getTime();return I({name:"homePage.v1",query:P,params:{id:_},dependencies:{types:["homePage"],ids:[_]},resolve:(t,o)=>z(t,o,s=>L(s,{now:new Date(n)}),X)})}function yn(e){if(typeof e!="string"||e==="")throw new TypeError("Invalid CMS page slug");return I({name:"page.v1",query:Y,params:{slug:e},dependencies:{types:["page"]},resolve:(n,t)=>z(n,t,x,Q)})}function fn(){return I({name:"pages.v1",query:G,params:{},dependencies:{types:["page"]},resolve:(e,n)=>z(e,n,t=>{if(!Array.isArray(t))throw new m("page",["the page query did not return a list"]);if(!b(t))throw new m("page",["the page query contains missing entries"]);return t.map(o=>x(o))},t=>b(t)&&t.every(o=>o!==null&&Q(o)))})}function gn(){return I({name:"siteSettings.v1",query:P,params:{id:E},dependencies:{types:["siteSettings"],ids:[E]},resolve:(e,n)=>z(e,n,F,v)})}export{G as CONTENT_PAGES_QUERY,Y as CONTENT_PAGE_BY_SLUG_QUERY,P as HOME_PAGE_DOCUMENT_QUERY,B as MALFORMED_CONTENT,m as MalformedContentError,M as READER_ACTION_HREF,_ as READER_HOME_PAGE_ID,H as READER_JUMP_LINK,N as READER_PHOTO_SLUG,E as READER_SITE_SETTINGS_ID,q as READER_STORY_LAYOUTS,nn as campaignState,yn as contentPageQuery,fn as contentPagesQuery,un as createSiteContentReader,dn as homeContentQuery,x as parseContentPage,L as parseHomePage,F as parseSiteSettings,sn as portableTextToMarkdown,gn as siteSettingsQuery};
7
+ //# sourceMappingURL=site-content.mjs.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../src/portable/array.ts", "../src/contracts/query.ts", "../src/portable/fallback.ts", "../src/portable/site-content.ts"],
4
+ "sourcesContent": ["/** Content lists must contain an own entry at every index. */\nexport function isDenseArray(value: unknown): value is unknown[] {\n if (!Array.isArray(value)) return false;\n for (let index = 0; index < value.length; index += 1) {\n if (!Object.hasOwn(value, index)) return false;\n }\n return true;\n}\n", "/** A-1822 S1 owns this implementation. S0 registers the public signatures. */\nexport type CmsParams = Readonly<Record<string, string | number | boolean | null>>;\nexport type CmsDependencies = {\n readonly types: readonly string[];\n readonly ids?: readonly string[];\n};\nexport type CmsResolution<T> = {\n readonly data: T;\n readonly fallbackFields: readonly string[];\n};\nexport type CmsQuery<T> = {\n readonly name: string;\n readonly query: string;\n readonly params: CmsParams;\n readonly dependencies: CmsDependencies;\n readonly resolve: (raw: unknown, fallback: T) => CmsResolution<T>;\n};\n\nconst TYPE = /^[A-Za-z][A-Za-z0-9_]{0,63}$/;\nconst ID = /^[A-Za-z0-9][A-Za-z0-9._-]{0,127}$/;\nconst SCOPE = /^[a-z0-9]{6,12}\\.[a-z][a-z0-9_-]{0,63}$/;\n\nfunction dependenciesCopy(dependencies: CmsDependencies): CmsDependencies {\n if (!dependencies || !Array.isArray(dependencies.types) || dependencies.types.length === 0) {\n throw new TypeError(\"CMS dependencies require document types\");\n }\n const types = [...dependencies.types];\n for (const type of types) {\n if (typeof type !== \"string\" || !TYPE.test(type)) throw new TypeError(\"Invalid CMS document type\");\n }\n if (dependencies.ids !== undefined && !Array.isArray(dependencies.ids)) throw new TypeError(\"Invalid CMS document IDs\");\n const ids = dependencies.ids === undefined ? undefined : [...dependencies.ids];\n for (const id of ids ?? []) {\n if (typeof id !== \"string\" || !ID.test(id) || /^(drafts|versions)\\./.test(id)) {\n throw new TypeError(\"Invalid CMS document ID\");\n }\n }\n if (new Set(types).size + new Set(ids).size > 128) throw new TypeError(\"Too many CMS tags\");\n return Object.freeze({ types: Object.freeze(types), ...(ids === undefined ? {} : { ids: Object.freeze(ids) }) });\n}\n\nexport function defineCmsQuery<T>(query: CmsQuery<T>): CmsQuery<T> {\n if (!query || typeof query.name !== \"string\" || !/^[A-Za-z][A-Za-z0-9_.-]{0,127}$/.test(query.name)\n || typeof query.query !== \"string\" || query.query.trim() === \"\" || typeof query.resolve !== \"function\") {\n throw new TypeError(\"Invalid CMS query configuration\");\n }\n const params = query.params;\n if (!params || typeof params !== \"object\" || (Object.getPrototypeOf(params) !== Object.prototype && Object.getPrototypeOf(params) !== null)) {\n throw new TypeError(\"CMS params must be plain JSON scalars\");\n }\n const copied: Record<string, string | number | boolean | null> = {};\n for (const key of Reflect.ownKeys(params)) {\n const descriptor = Object.getOwnPropertyDescriptor(params, key);\n if (typeof key !== \"string\" || !descriptor || !Object.hasOwn(descriptor, \"value\") || !descriptor.enumerable) {\n throw new TypeError(\"CMS params must be plain JSON scalars\");\n }\n const value: unknown = descriptor.value;\n if (!(value === null || typeof value === \"string\" || typeof value === \"boolean\" || (typeof value === \"number\" && Number.isFinite(value)))) {\n throw new TypeError(\"CMS params must be plain JSON scalars\");\n }\n Object.defineProperty(copied, key, { value, enumerable: true });\n }\n return Object.freeze({ name: query.name, query: query.query, params: Object.freeze(copied), dependencies: dependenciesCopy(query.dependencies), resolve: query.resolve });\n}\n\nexport function cmsTags(scope: string, dependencies: CmsDependencies): readonly string[] {\n if (typeof scope !== \"string\" || scope.length > 77 || !SCOPE.test(scope)) throw new TypeError(\"Invalid CMS scope\");\n const copied = dependenciesCopy(dependencies);\n const tags = [\n ...[...new Set(copied.types)].sort().map((type) => `cms:${scope}:type:${type}`),\n ...[...new Set(copied.ids ?? [])].sort().map((id) => `cms:${scope}:id:${id}`),\n ];\n return Object.freeze(tags);\n}\n", "import { isDenseArray } from \"./array.js\";\nimport {\n READER_ACTION_HREF, READER_JUMP_LINK, READER_PHOTO_SLUG, READER_STORY_LAYOUTS,\n type CompositionInput, type HomeContent, type PageContent, type SiteSettingsContent,\n} from \"./site-content.js\";\n\nconst object = (value: unknown): value is Record<string, unknown> => value !== null && typeof value === \"object\" && !Array.isArray(value);\nconst words = (value: unknown): boolean => typeof value === \"string\" && value.trim() !== \"\";\nconst nullableText = (value: unknown): boolean => value === null || typeof value === \"string\";\nconst photo = (value: unknown): boolean => value === null || (typeof value === \"string\" && READER_PHOTO_SLUG.test(value));\nconst href = (value: unknown): boolean => typeof value === \"string\" && READER_ACTION_HREF.test(value);\nconst copy = (value: unknown): boolean => words(value) || (object(value) && words(value.text) && (value.copySource === \"captured\" || value.copySource === \"proposed\"));\nconst optionalCopy = (value: unknown): boolean => value === null || copy(value);\nconst action = (value: unknown): boolean => object(value) && copy(value.label) && href(value.href);\nconst optionalAction = (value: unknown): boolean => value === null || action(value);\n\nfunction composition(value: unknown): boolean {\n if (!object(value) || !nullableText(value.intro) || !photo(value.photo) || !isDenseArray(value.blocks)) return false;\n const hero = value.hero;\n if (hero !== null && (!object(hero) || !copy(hero.heading) || !optionalCopy(hero.subline) || !optionalCopy(hero.intro)\n || !photo(hero.image) || !photo(hero.inset) || !optionalAction(hero.cta) || !optionalAction(hero.secondaryCta))) return false;\n const validBlocks = value.blocks.every((block: unknown) => {\n if (!object(block)) return false;\n switch (block.kind) {\n case \"campaign\": return optionalAction(block.action) && isDenseArray(block.images) && block.images.every((image: unknown) => typeof image === \"string\" && photo(image));\n case \"locations\": return (block.anchor === null || (typeof block.anchor === \"string\" && READER_JUMP_LINK.test(block.anchor))) && copy(block.heading) && optionalCopy(block.tail) && photo(block.image);\n case \"feature_stories\": return copy(block.heading) && optionalCopy(block.tail) && isDenseArray(block.items) && block.items.length > 0 && block.items.every((item: unknown) => object(item) && copy(item.heading) && copy(item.body) && action(item.action) && photo(item.image) && READER_STORY_LAYOUTS.some((layout) => layout === item.shape) && typeof item.card === \"boolean\");\n case \"accent_band\": return copy(block.heading) && copy(block.body) && optionalAction(block.action) && photo(block.image);\n case \"cta\": return words(block.heading) && nullableText(block.body) && object(block.link) && words(block.link.label) && href(block.link.href);\n default: return false;\n }\n });\n if (!validBlocks) return false;\n const model = value as unknown as CompositionInput;\n const anchors = model.blocks.flatMap((block) => block.kind === \"locations\" && block.anchor !== null ? [block.anchor] : []);\n if (new Set(anchors).size !== anchors.length) return false;\n const links = [model.hero?.cta?.href, model.hero?.secondaryCta?.href, ...model.blocks.flatMap((block) => {\n switch (block.kind) {\n case \"campaign\": case \"accent_band\": return [block.action?.href];\n case \"feature_stories\": return block.items.map((item) => item.action.href);\n case \"cta\": return [block.link.href];\n default: return [];\n }\n })];\n return links.every((link) => link === undefined || !link.startsWith(\"#\") || anchors.includes(link.slice(1)));\n}\n\nfunction proposed(value: unknown): boolean {\n return isDenseArray(value) && value.every((line: unknown) => object(line) && words(line.where) && typeof line.text === \"string\");\n}\n\nexport function validHomeFallback(value: unknown): value is HomeContent | null {\n return value === null || (object(value) && composition(value.composition) && typeof value.body === \"string\" && proposed(value.proposedCopy)\n && typeof value.campaign === \"string\" && [\"shown\", \"off\", \"not-started\", \"ended\", \"none\"].includes(value.campaign));\n}\n\nexport function validPageFallback(value: unknown): value is PageContent | null {\n return value === null || (object(value) && words(value.slug) && words(value.title) && composition(value.composition)\n && typeof value.body === \"string\" && typeof value.migrated === \"boolean\" && proposed(value.proposedCopy));\n}\n\nexport function validSettingsFallback(value: unknown): value is SiteSettingsContent | null {\n return value === null || (object(value) && words(value.name) && nullableText(value.description) && object(value.contact)\n && nullableText(value.contact.email) && nullableText(value.contact.phone) && isDenseArray(value.social)\n && value.social.every((link: unknown) => object(link) && words(link.network) && typeof link.url === \"string\" && /^https?:\\/\\//.test(link.url)));\n}\n", "/**\n * A-1713. The site content model, read: the home page, content pages and site\n * settings, validated on read and returned in the shape a site's page\n * composition consumes.\n *\n * ===========================================================================\n * READ ONLY, BY CONSTRUCTION\n * ===========================================================================\n *\n * A client site reads its content with a read-only token. All editing goes\n * through the studio's dashboard, which writes to Sanity; nothing on a client\n * site writes, and this module has no write path to call. It is handed a\n * `ContentClient` (a `query` function) and nothing else.\n *\n * ===========================================================================\n * VALIDATED ON READ, BECAUSE SANITY VALIDATION ONLY ADVISES\n * ===========================================================================\n *\n * The schema's rules warn an editor; they do not refuse a publish, and\n * anything writing over the API skips them entirely. So every document is\n * checked here again, and a malformed one is refused BY NAME\n * (`MalformedContentError`, code `malformed-content`) listing every problem\n * with its path, rather than rendered half-empty. A page that renders with a\n * missing headline and a page whose content is broken look identical to a\n * visitor; a build that fails naming `hero.headline` does not.\n *\n * Absent is not malformed: `null` from `home()` means nobody has created the\n * home page yet, and a site decides what to do about that.\n *\n * ===========================================================================\n * THE SHAPE IT RETURNS\n * ===========================================================================\n *\n * The INPUT shape of a site's composition schema (the reference build's\n * frontmatter): a copy value is a plain string for the client's own words\n * with no claim about their source, `{ text, copySource: \"captured\" }` for\n * words claimed verbatim from the capture (the site checks every such claim\n * against its capture evidence, so the claim must survive Sanity), and\n * `{ text, copySource: \"proposed\" }` for studio-written words awaiting\n * approval. All three round-trip exactly; a photo is its library slug; every key a block declares is\n * present, `null` where there is nothing. So a site validates this with the\n * same schema it validates its Markdown frontmatter with, and its components\n * never know where the content came from.\n *\n * Mapping from the generic model to the composition's names:\n *\n * hero.headline / subline / lead hero.heading / subline / intro\n * hero.photos[0], [1] hero.image, hero.inset\n * hero.primaryAction / secondary... hero.cta / secondaryCta\n * campaign (when shown) the FIRST block, kind `campaign`, and\n * the page body (`# title` + its text)\n * featureStoriesBlock kind `feature_stories`\n * surfaceCardBlock kind `cta`\n * accentBandBlock kind `accent_band`\n * locationsBlock kind `locations` (jumpLink \u2192 anchor)\n *\n * Two places the composition cannot carry a proposed marker: a `cta` block's\n * plain strings, and the campaign's title and body (which travel as Markdown).\n * There the text is returned plain and the line is still listed in\n * `proposedCopy`, which is the list a dashboard and a site both read for\n * approval. Nothing is dropped silently.\n */\n\nimport { isDenseArray } from \"./array.js\";\nimport { defineCmsQuery, type CmsQuery, type CmsResolution } from \"../contracts/query.js\";\nimport { validHomeFallback, validPageFallback, validSettingsFallback } from \"./fallback.js\";\n\n// ---------------------------------------------------------------------------\n// Output types\n// ---------------------------------------------------------------------------\n\nexport type CopyInput = string | { readonly text: string; readonly copySource: \"captured\" | \"proposed\" };\nexport type ActionInput = { readonly label: CopyInput; readonly href: string };\n\nexport type HeroInput = {\n readonly heading: CopyInput;\n readonly subline: CopyInput | null;\n readonly intro: CopyInput | null;\n readonly image: string | null;\n readonly inset: string | null;\n readonly cta: ActionInput | null;\n readonly secondaryCta: ActionInput | null;\n};\n\nexport type StoryInput = {\n readonly heading: CopyInput;\n readonly body: CopyInput;\n readonly action: ActionInput;\n readonly image: string | null;\n readonly shape: \"wide\" | \"tall\" | \"round\" | \"free\";\n readonly card: boolean;\n};\n\nexport type CompositionBlockInput =\n | { readonly kind: \"campaign\"; readonly action: ActionInput | null; readonly images: readonly string[] }\n | {\n readonly kind: \"locations\";\n readonly anchor: string | null;\n readonly heading: CopyInput;\n readonly tail: CopyInput | null;\n readonly image: string | null;\n }\n | {\n readonly kind: \"feature_stories\";\n readonly heading: CopyInput;\n readonly tail: CopyInput | null;\n readonly items: readonly StoryInput[];\n }\n | {\n readonly kind: \"accent_band\";\n readonly heading: CopyInput;\n readonly body: CopyInput;\n readonly action: ActionInput | null;\n readonly image: string | null;\n }\n | {\n readonly kind: \"cta\";\n readonly heading: string;\n readonly body: string | null;\n readonly link: { readonly label: string; readonly href: string };\n };\n\nexport type CompositionInput = {\n readonly intro: string | null;\n readonly photo: string | null;\n readonly hero: HeroInput | null;\n readonly blocks: readonly CompositionBlockInput[];\n};\n\n/** One line of studio-written copy awaiting approval, and where it is in the document. */\nexport type ProposedCopy = { readonly where: string; readonly text: string };\n\nexport type CampaignState = \"shown\" | \"off\" | \"not-started\" | \"ended\" | \"none\";\n\nexport type HomeContent = {\n readonly composition: CompositionInput;\n /** The page body as Markdown: the campaign's title and text when it is shown, otherwise empty. */\n readonly body: string;\n readonly campaign: CampaignState;\n readonly proposedCopy: readonly ProposedCopy[];\n};\n\nexport type PageContent = {\n readonly slug: string;\n readonly title: string;\n readonly composition: CompositionInput;\n readonly body: string;\n readonly migrated: boolean;\n readonly proposedCopy: readonly ProposedCopy[];\n};\n\nexport type SiteSettingsContent = {\n readonly name: string;\n readonly description: string | null;\n readonly contact: { readonly email: string | null; readonly phone: string | null };\n readonly social: readonly { readonly network: string; readonly url: string }[];\n};\n\n// ---------------------------------------------------------------------------\n// The refusal\n// ---------------------------------------------------------------------------\n\nexport const MALFORMED_CONTENT = \"malformed-content\";\n\nexport class MalformedContentError extends Error {\n readonly code = MALFORMED_CONTENT;\n readonly documentId: string;\n readonly problems: readonly string[];\n\n constructor(documentId: string, problems: readonly string[]) {\n super(`${MALFORMED_CONTENT}: ${documentId}: ${problems.join(\"; \")}`);\n this.name = \"MalformedContentError\";\n this.documentId = documentId;\n this.problems = problems;\n }\n}\n\n// ---------------------------------------------------------------------------\n// The rules restated\n// ---------------------------------------------------------------------------\n\n/*\n * Runtime-free rules shared with schema-base. The schema adapter imports these\n * objects; content-client compatibility tests pin the shared references.\n */\nexport const READER_PHOTO_SLUG = /^[a-z0-9]+(?:-[a-z0-9]+)*$/;\nexport const READER_ACTION_HREF =\n /^(?:\\/(?![/\\\\])[^\\s]*|#[a-z][a-z0-9]*(?:-[a-z0-9]+)*|mailto:[^\\s@]+@[^\\s@]+|tel:\\+?[0-9][0-9 ()-]*|https?:\\/\\/[^\\s/]+[^\\s]*)$/;\nexport const READER_JUMP_LINK = /^[a-z][a-z0-9]*(?:-[a-z0-9]+)*$/;\nexport const READER_STORY_LAYOUTS = [\"wide\", \"tall\", \"round\", \"free\"] as const;\nexport const READER_HOME_PAGE_ID = \"homePage\";\nexport const READER_SITE_SETTINGS_ID = \"siteSettings\";\n\n// ---------------------------------------------------------------------------\n// A small path-aware reader\n// ---------------------------------------------------------------------------\n\ntype Raw = Record<string, unknown>;\n\nclass Reading {\n readonly problems: string[] = [];\n readonly proposed: ProposedCopy[] = [];\n\n fail(path: string, message: string): null {\n this.problems.push(`${path} ${message}`);\n return null;\n }\n\n object(value: unknown, path: string): Raw | null {\n if (typeof value === \"object\" && value !== null && !Array.isArray(value)) return value as Raw;\n return this.fail(path, \"is not an object\");\n }\n\n dense(value: unknown[], path: string): boolean {\n if (isDenseArray(value)) return true;\n this.fail(path, \"contains missing entries\");\n return false;\n }\n\n optionalString(value: unknown, path: string): string | null {\n if (value === undefined || value === null) return null;\n if (typeof value === \"string\") return value.trim() === \"\" ? null : value;\n return this.fail(path, \"is not text\");\n }\n\n /** A copy value, or null when absent or empty. Records a proposed line. */\n copy(value: unknown, path: string): CopyInput | null {\n if (value === undefined || value === null) return null;\n const raw = this.object(value, path);\n if (raw === null) return null;\n const text = raw[\"text\"];\n const source = raw[\"copySource\"];\n if (text !== undefined && typeof text !== \"string\") return this.fail(`${path}.text`, \"is not text\");\n if (source !== undefined && source !== \"captured\" && source !== \"proposed\") {\n return this.fail(`${path}.copySource`, `is ${JSON.stringify(source)}, not captured or proposed`);\n }\n if (typeof text !== \"string\" || text.trim() === \"\") return null;\n if (source === \"proposed\") {\n this.proposed.push({ where: path, text });\n return { text, copySource: \"proposed\" };\n }\n if (source === \"captured\") return { text, copySource: \"captured\" };\n return text;\n }\n\n requiredCopy(value: unknown, path: string): CopyInput | null {\n const copy = this.copy(value, path);\n if (copy === null && !this.problems.some((p) => p.startsWith(path))) this.fail(path, \"is missing its words\");\n return copy;\n }\n\n photo(value: unknown, path: string): string | null {\n if (value === undefined || value === null) return null;\n if (typeof value === \"string\" && READER_PHOTO_SLUG.test(value)) return value;\n return this.fail(path, `is ${JSON.stringify(value)}, not a photo library slug`);\n }\n\n photos(value: unknown, path: string, max: number): string[] {\n if (value === undefined || value === null) return [];\n if (!Array.isArray(value)) {\n this.fail(path, \"is not a list of photos\");\n return [];\n }\n if (!this.dense(value, path)) return [];\n if (value.length > max) this.fail(path, `holds ${String(value.length)} photos; at most ${String(max)}`);\n return value.map((entry, index) => this.photo(entry, `${path}[${String(index)}]`)).filter((p): p is string => p !== null);\n }\n\n action(value: unknown, path: string): ActionInput | null {\n if (value === undefined || value === null) return null;\n const raw = this.object(value, path);\n if (raw === null) return null;\n const label = this.requiredCopy(raw[\"label\"], `${path}.label`);\n const href = raw[\"href\"];\n if (typeof href !== \"string\" || !READER_ACTION_HREF.test(href)) {\n return this.fail(`${path}.href`, `is ${JSON.stringify(href)}, not a site path, #jump-link, mailto:, tel: or web address`);\n }\n return label === null ? null : { label, href };\n }\n\n requiredAction(value: unknown, path: string): ActionInput | null {\n if (value === undefined || value === null) return this.fail(path, \"is missing\");\n return this.action(value, path);\n }\n}\n\nfunction plain(copy: CopyInput): string {\n return typeof copy === \"string\" ? copy : copy.text;\n}\n\n// ---------------------------------------------------------------------------\n// Portable Text to Markdown\n// ---------------------------------------------------------------------------\n\n/**\n * The narrow Portable Text `portableText` declares, back to Markdown: normal,\n * h2, h3 and quote blocks, bullet and numbered lists, bold, italic, code and\n * links. It is the inverse of the seed package's Markdown mapper, and the\n * round-trip test holds the two to each other.\n *\n * An uploaded image inside rich text is REFUSED, not dropped: nothing can\n * upload one yet (the dashboard slice decides how), so one arriving means\n * something wrote the document by hand, and a page silently missing a picture\n * is the failure this reader exists to prevent.\n */\nexport function portableTextToMarkdown(value: unknown): string {\n const reading = new Reading();\n const markdown = richTextToMarkdown(value, \"body\", reading);\n if (reading.problems.length > 0) throw new MalformedContentError(\"body\", reading.problems);\n return markdown;\n}\n\nfunction richTextToMarkdown(value: unknown, path: string, reading: Reading): string {\n if (value === undefined || value === null) return \"\";\n if (!Array.isArray(value)) {\n reading.fail(path, \"is not rich text\");\n return \"\";\n }\n if (!reading.dense(value, path)) return \"\";\n const out: string[] = [];\n let previousWasList = false;\n value.forEach((member, index) => {\n const at = `${path}[${String(index)}]`;\n const block = reading.object(member, at);\n if (block === null) return;\n if (block[\"_type\"] !== \"block\") {\n reading.fail(at, `is a ${JSON.stringify(block[\"_type\"])}; only text is supported in rich text so far`);\n return;\n }\n const text = spansToMarkdown(block, at, reading);\n const listItem = block[\"listItem\"];\n const style = block[\"style\"] ?? \"normal\";\n let line: string;\n if (listItem === \"bullet\" || listItem === \"number\") {\n const level = typeof block[\"level\"] === \"number\" && block[\"level\"] > 1 ? block[\"level\"] : 1;\n line = `${\" \".repeat(level - 1)}${listItem === \"bullet\" ? \"-\" : \"1.\"} ${text}`;\n } else if (style === \"h2\") line = `## ${text}`;\n else if (style === \"h3\") line = `### ${text}`;\n else if (style === \"blockquote\") line = `> ${text}`;\n else if (style === \"normal\") line = text;\n else {\n reading.fail(`${at}.style`, `is ${JSON.stringify(style)}, which the schema does not offer`);\n return;\n }\n const isList = listItem === \"bullet\" || listItem === \"number\";\n if (out.length > 0) out.push(isList && previousWasList ? \"\\n\" : \"\\n\\n\");\n out.push(line);\n previousWasList = isList;\n });\n return out.join(\"\");\n}\n\nconst DECORATORS: Record<string, string> = { strong: \"**\", em: \"*\", code: \"`\" };\n\nfunction spansToMarkdown(block: Raw, path: string, reading: Reading): string {\n const links = new Map<string, string>();\n const markDefs = Array.isArray(block[\"markDefs\"]) ? (block[\"markDefs\"] as unknown[]) : [];\n if (!reading.dense(markDefs, `${path}.markDefs`)) return \"\";\n for (const def of markDefs) {\n const d = def as Raw;\n if (d[\"_type\"] === \"link\" && typeof d[\"_key\"] === \"string\" && typeof d[\"href\"] === \"string\") links.set(d[\"_key\"], d[\"href\"]);\n }\n const children = Array.isArray(block[\"children\"]) ? (block[\"children\"] as unknown[]) : [];\n if (!reading.dense(children, `${path}.children`)) return \"\";\n return children\n .map((child, index) => {\n const span = child as Raw;\n if (span[\"_type\"] !== \"span\" || typeof span[\"text\"] !== \"string\") {\n reading.fail(`${path}.children[${String(index)}]`, \"is not a text span\");\n return \"\";\n }\n let text = span[\"text\"];\n const marks = Array.isArray(span[\"marks\"]) ? (span[\"marks\"] as unknown[]) : [];\n if (!reading.dense(marks, `${path}.children[${String(index)}].marks`)) return \"\";\n let href: string | null = null;\n for (const mark of marks) {\n if (typeof mark !== \"string\") continue;\n const fence = DECORATORS[mark];\n if (fence !== undefined) text = `${fence}${text}${fence}`;\n else if (links.has(mark)) href = links.get(mark) ?? null;\n else reading.fail(`${path}.children[${String(index)}].marks`, `names ${JSON.stringify(mark)}, which is neither a style nor a link`);\n }\n return href === null ? text : `[${text}](${href})`;\n })\n .join(\"\");\n}\n\n// ---------------------------------------------------------------------------\n// The home page\n// ---------------------------------------------------------------------------\n\n/** Whether a campaign is shown at `now`, and if not, why not. */\nexport function campaignState(campaign: unknown, now: Date): CampaignState {\n if (typeof campaign !== \"object\" || campaign === null) return \"none\";\n const c = campaign as Raw;\n if (c[\"enabled\"] !== true) return \"off\";\n const starts = typeof c[\"startsAt\"] === \"string\" ? Date.parse(c[\"startsAt\"]) : null;\n const ends = typeof c[\"endsAt\"] === \"string\" ? Date.parse(c[\"endsAt\"]) : null;\n if (starts !== null && now.getTime() < starts) return \"not-started\";\n if (ends !== null && now.getTime() >= ends) return \"ended\";\n return \"shown\";\n}\n\nfunction keyed(path: string, raw: Raw, index: number): string {\n return typeof raw[\"_key\"] === \"string\" ? `${path}[_key==\"${raw[\"_key\"]}\"]` : `${path}[${String(index)}]`;\n}\n\n/**\n * A stored home page document, validated and mapped. Throws\n * `MalformedContentError` naming every problem. `now` decides whether a\n * scheduled campaign is shown, and is a parameter so a build, a preview and a\n * test each say which moment they mean.\n */\nexport function parseHomePage(document: unknown, options: { readonly now: Date }): HomeContent {\n const reading = new Reading();\n const doc = reading.object(document, \"homePage\");\n if (doc === null) throw new MalformedContentError(READER_HOME_PAGE_ID, reading.problems);\n const id = typeof doc[\"_id\"] === \"string\" ? doc[\"_id\"] : READER_HOME_PAGE_ID;\n if (doc[\"_type\"] !== \"homePage\") reading.fail(\"_type\", `is ${JSON.stringify(doc[\"_type\"])}, not homePage`);\n\n let hero: HeroInput | null = null;\n const rawHero = doc[\"hero\"] === undefined ? reading.fail(\"hero\", \"is missing\") : reading.object(doc[\"hero\"], \"hero\");\n if (rawHero !== null) {\n const photos = reading.photos(rawHero[\"photos\"], \"hero.photos\", 2);\n const heading = reading.requiredCopy(rawHero[\"headline\"], \"hero.headline\");\n const subline = reading.copy(rawHero[\"subline\"], \"hero.subline\");\n const intro = reading.copy(rawHero[\"lead\"], \"hero.lead\");\n const cta = reading.action(rawHero[\"primaryAction\"], \"hero.primaryAction\");\n const secondaryCta = reading.action(rawHero[\"secondaryAction\"], \"hero.secondaryAction\");\n if (heading !== null) {\n hero = { heading, subline, intro, image: photos[0] ?? null, inset: photos[1] ?? null, cta, secondaryCta };\n }\n }\n\n const blocks: CompositionBlockInput[] = [];\n const blockJumps: { where: string; href: string }[] = [];\n let body = \"\";\n const state = campaignState(doc[\"campaign\"], options.now);\n if (state === \"shown\") {\n const campaign = reading.object(doc[\"campaign\"], \"campaign\");\n if (campaign !== null) {\n const title = reading.requiredCopy(campaign[\"title\"], \"campaign.title\");\n const images = reading.photos(campaign[\"photos\"], \"campaign.photos\", 3);\n if (images.length === 0) reading.fail(\"campaign.photos\", \"is empty; a shown campaign needs at least one photo\");\n const text = richTextToMarkdown(campaign[\"body\"], \"campaign.body\", reading);\n if (text === \"\") reading.fail(\"campaign.body\", \"is empty; a shown campaign needs its text\");\n if (campaign[\"bodyCopySource\"] === \"proposed\") reading.proposed.push({ where: \"campaign.body\", text });\n const action = reading.action(campaign[\"action\"], \"campaign.action\");\n if (action !== null) blockJumps.push({ where: \"campaign.action.href\", href: action.href });\n if (title !== null) body = `# ${plain(title)}\\n\\n${text}`;\n blocks.push({ kind: \"campaign\", action, images });\n }\n }\n\n const anchors: string[] = [];\n const rawBlocks = doc[\"blocks\"] ?? [];\n if (!Array.isArray(rawBlocks)) reading.fail(\"blocks\", \"is not a list\");\n else if (reading.dense(rawBlocks, \"blocks\")) {\n rawBlocks.forEach((member, index) => {\n const raw = reading.object(member, `blocks[${String(index)}]`);\n if (raw === null) return;\n const at = keyed(\"blocks\", raw, index);\n const mapped = mapBlock(raw, at, reading);\n if (mapped === null) return;\n blockJumps.push(...buttonsOf(mapped, raw, at));\n if (mapped.kind === \"locations\" && mapped.anchor !== null) {\n if (anchors.includes(mapped.anchor)) reading.fail(`${at}.jumpLink`, `repeats \"${mapped.anchor}\", already used by another section`);\n anchors.push(mapped.anchor);\n }\n blocks.push(mapped);\n });\n }\n\n // A jump link on ANY button must land on a section of this page.\n const jumps: { where: string; href: string }[] = [];\n if (hero?.cta) jumps.push({ where: \"hero.primaryAction.href\", href: hero.cta.href });\n if (hero?.secondaryCta) jumps.push({ where: \"hero.secondaryAction.href\", href: hero.secondaryCta.href });\n jumps.push(...blockJumps);\n for (const { where, href } of jumps) {\n if (href.startsWith(\"#\") && !anchors.includes(href.slice(1))) {\n reading.fail(where, `jumps to ${href}, which no section on the page is named`);\n }\n }\n\n if (reading.problems.length > 0) throw new MalformedContentError(id, reading.problems);\n return {\n composition: { intro: null, photo: null, hero, blocks },\n body,\n campaign: state,\n proposedCopy: reading.proposed,\n };\n}\n\n/** Every button a mapped section carries, with its path in the stored document. */\nfunction buttonsOf(block: CompositionBlockInput, raw: Raw, at: string): { where: string; href: string }[] {\n switch (block.kind) {\n case \"feature_stories\": {\n const stories = Array.isArray(raw[\"stories\"]) ? (raw[\"stories\"] as Raw[]) : [];\n return block.items.map((item, index) => ({\n where: `${keyed(`${at}.stories`, stories[index] ?? {}, index)}.action.href`,\n href: item.action.href,\n }));\n }\n case \"accent_band\":\n return block.action === null ? [] : [{ where: `${at}.action.href`, href: block.action.href }];\n case \"cta\":\n return [{ where: `${at}.action.href`, href: block.link.href }];\n default:\n return [];\n }\n}\n\nfunction mapBlock(raw: Raw, at: string, reading: Reading): CompositionBlockInput | null {\n switch (raw[\"_type\"]) {\n case \"featureStoriesBlock\": {\n const heading = reading.requiredCopy(raw[\"heading\"], `${at}.heading`);\n const tail = reading.copy(raw[\"tail\"], `${at}.tail`);\n const stories = raw[\"stories\"];\n if (!Array.isArray(stories) || stories.length === 0) return reading.fail(`${at}.stories`, \"has no stories\");\n if (!reading.dense(stories, `${at}.stories`)) return null;\n const items: StoryInput[] = [];\n stories.forEach((member, index) => {\n const story = reading.object(member, `${at}.stories[${String(index)}]`);\n if (story === null) return;\n const sat = keyed(`${at}.stories`, story, index);\n const sHeading = reading.requiredCopy(story[\"heading\"], `${sat}.heading`);\n const sBody = reading.requiredCopy(story[\"body\"], `${sat}.body`);\n const action = reading.requiredAction(story[\"action\"], `${sat}.action`);\n const image = reading.photo(story[\"photo\"], `${sat}.photo`);\n const layout = story[\"layout\"] ?? \"wide\";\n if (!(READER_STORY_LAYOUTS as readonly unknown[]).includes(layout)) {\n reading.fail(`${sat}.layout`, `is ${JSON.stringify(layout)}, not wide, tall, round or free`);\n return;\n }\n const onCard = story[\"onCard\"] ?? false;\n if (typeof onCard !== \"boolean\") {\n reading.fail(`${sat}.onCard`, \"is not on or off\");\n return;\n }\n if (sHeading === null || sBody === null || action === null) return;\n items.push({ heading: sHeading, body: sBody, action, image, shape: layout as StoryInput[\"shape\"], card: onCard });\n });\n return heading === null ? null : { kind: \"feature_stories\", heading, tail, items };\n }\n case \"surfaceCardBlock\": {\n const heading = reading.requiredCopy(raw[\"heading\"], `${at}.heading`);\n const body = reading.copy(raw[\"body\"], `${at}.body`);\n const action = reading.requiredAction(raw[\"action\"], `${at}.action`);\n if (heading === null || action === null) return null;\n return {\n kind: \"cta\",\n heading: plain(heading),\n body: body === null ? null : plain(body),\n link: { label: plain(action.label), href: action.href },\n };\n }\n case \"accentBandBlock\": {\n const heading = reading.requiredCopy(raw[\"heading\"], `${at}.heading`);\n const body = reading.requiredCopy(raw[\"body\"], `${at}.body`);\n const action = reading.action(raw[\"action\"], `${at}.action`);\n const image = reading.photo(raw[\"photo\"], `${at}.photo`);\n if (heading === null || body === null) return null;\n return { kind: \"accent_band\", heading, body, action, image };\n }\n case \"locationsBlock\": {\n const jump = raw[\"jumpLink\"];\n let anchor: string | null = null;\n if (jump !== undefined && jump !== null && jump !== \"\") {\n if (typeof jump !== \"string\" || !READER_JUMP_LINK.test(jump)) reading.fail(`${at}.jumpLink`, `is ${JSON.stringify(jump)}, not lowercase words joined by hyphens`);\n else anchor = jump;\n }\n const heading = reading.requiredCopy(raw[\"heading\"], `${at}.heading`);\n const tail = reading.copy(raw[\"tail\"], `${at}.tail`);\n const image = reading.photo(raw[\"photo\"], `${at}.photo`);\n return heading === null ? null : { kind: \"locations\", anchor, heading, tail, image };\n }\n default:\n return reading.fail(`${at}._type`, `is ${JSON.stringify(raw[\"_type\"])}, not a section type this reader knows`);\n }\n}\n\n// ---------------------------------------------------------------------------\n// Content pages and settings\n// ---------------------------------------------------------------------------\n\nexport function parseContentPage(document: unknown): PageContent {\n const reading = new Reading();\n const doc = reading.object(document, \"page\");\n if (doc === null) throw new MalformedContentError(\"page\", reading.problems);\n const id = typeof doc[\"_id\"] === \"string\" ? doc[\"_id\"] : \"page\";\n if (doc[\"_type\"] !== \"page\") reading.fail(\"_type\", `is ${JSON.stringify(doc[\"_type\"])}, not page`);\n const title = reading.optionalString(doc[\"title\"], \"title\");\n if (title === null) reading.fail(\"title\", \"is missing\");\n if (doc[\"titleCopySource\"] === \"proposed\" && title !== null) reading.proposed.push({ where: \"title\", text: title });\n const slugObject = doc[\"slug\"] as Raw | undefined;\n const slug = typeof slugObject?.[\"current\"] === \"string\" && slugObject[\"current\"] !== \"\" ? slugObject[\"current\"] : null;\n if (slug === null) reading.fail(\"slug.current\", \"is missing\");\n const lead = reading.copy(doc[\"lead\"], \"lead\");\n const photo = reading.photo(doc[\"photo\"], \"photo\");\n const body = richTextToMarkdown(doc[\"body\"], \"body\", reading);\n if (doc[\"bodyCopySource\"] === \"proposed\") reading.proposed.push({ where: \"body\", text: body });\n if (reading.problems.length > 0 || title === null || slug === null) throw new MalformedContentError(id, reading.problems);\n return {\n slug,\n title,\n composition: { intro: lead === null ? null : plain(lead), photo, hero: null, blocks: [] },\n body,\n migrated: doc[\"migrated\"] === true,\n proposedCopy: reading.proposed,\n };\n}\n\nexport function parseSiteSettings(document: unknown): SiteSettingsContent {\n const reading = new Reading();\n const doc = reading.object(document, \"siteSettings\");\n if (doc === null) throw new MalformedContentError(READER_SITE_SETTINGS_ID, reading.problems);\n const name = reading.optionalString(doc[\"title\"], \"title\");\n if (name === null) reading.fail(\"title\", \"is missing; a site needs its name\");\n const description = reading.optionalString(doc[\"description\"], \"description\");\n const contact = doc[\"contact\"] === undefined ? {} : (reading.object(doc[\"contact\"], \"contact\") ?? {});\n const email = reading.optionalString(contact[\"email\"], \"contact.email\");\n const phone = reading.optionalString(contact[\"phone\"], \"contact.phone\");\n const social: { network: string; url: string }[] = [];\n const rawSocial = doc[\"social\"] ?? [];\n if (!Array.isArray(rawSocial)) reading.fail(\"social\", \"is not a list\");\n else if (reading.dense(rawSocial, \"social\"))\n rawSocial.forEach((member, index) => {\n const link = reading.object(member, `social[${String(index)}]`);\n if (link === null) return;\n const network = reading.optionalString(link[\"network\"], `social[${String(index)}].network`);\n const url = reading.optionalString(link[\"url\"], `social[${String(index)}].url`);\n if (network === null || url === null || !/^https?:\\/\\//.test(url)) {\n reading.fail(`social[${String(index)}]`, \"needs a network and a web address\");\n return;\n }\n social.push({ network, url });\n });\n if (reading.problems.length > 0 || name === null) throw new MalformedContentError(READER_SITE_SETTINGS_ID, reading.problems);\n return { name, description, contact: { email, phone }, social };\n}\n\n// ---------------------------------------------------------------------------\n// Queries\n// ---------------------------------------------------------------------------\n\n/** By fixed id: a second home page at a random id is never read. */\nexport const HOME_PAGE_DOCUMENT_QUERY = `*[_id == $id][0]`;\nexport const CONTENT_PAGES_QUERY = `*[_type == \"page\" && defined(slug.current)]|order(slug.current asc)`;\nexport const CONTENT_PAGE_BY_SLUG_QUERY = `*[_type == \"page\" && slug.current == $slug][0]`;\n\nexport interface SiteContentReader {\n /** `null` when no home page document exists yet. */\n home: (options: { readonly now: Date }) => Promise<HomeContent | null>;\n pages: () => Promise<PageContent[]>;\n /** `null` when no page has that slug. */\n pageBySlug: (slug: string) => Promise<PageContent | null>;\n /** `null` before anyone has filled in the site's details. */\n siteSettings: () => Promise<SiteSettingsContent | null>;\n}\n\nexport function createSiteContentReader(client: { query: <T>(groq: string, options?: { params?: Record<string, unknown>; tags?: readonly string[] }) => Promise<T> }): SiteContentReader {\n return {\n home: async ({ now }) => {\n const doc = await client.query<unknown>(HOME_PAGE_DOCUMENT_QUERY, { params: { id: READER_HOME_PAGE_ID } });\n return doc === null || doc === undefined ? null : parseHomePage(doc, { now });\n },\n pages: async () => {\n const docs = await client.query<unknown>(CONTENT_PAGES_QUERY);\n if (!Array.isArray(docs)) throw new MalformedContentError(\"page\", [\"the page query did not return a list\"]);\n if (!isDenseArray(docs)) throw new MalformedContentError(\"page\", [\"the page query contains missing entries\"]);\n return docs.map((doc) => parseContentPage(doc));\n },\n pageBySlug: async (slug) => {\n const doc = await client.query<unknown>(CONTENT_PAGE_BY_SLUG_QUERY, { params: { slug } });\n return doc === null || doc === undefined ? null : parseContentPage(doc);\n },\n siteSettings: async () => {\n const doc = await client.query<unknown>(HOME_PAGE_DOCUMENT_QUERY, { params: { id: READER_SITE_SETTINGS_ID } });\n return doc === null || doc === undefined ? null : parseSiteSettings(doc);\n },\n };\n}\n\nfunction atomic<T>(raw: unknown, fallback: T, parse: (value: unknown) => T, validFallback: (value: unknown) => boolean): CmsResolution<T> {\n if (!validFallback(fallback)) throw new TypeError(\"Invalid CMS content fallback\");\n if (raw === null || raw === undefined) return { data: fallback, fallbackFields: [\"$\"] };\n // The server reader catches parser errors and classifies the whole fallback\n // as malformed. Returning fallback here would lose that diagnostic reason.\n return { data: parse(raw), fallbackFields: [] };\n}\n\nexport function homeContentQuery(now: Date): CmsQuery<HomeContent | null> {\n if (!(now instanceof Date) || !Number.isFinite(now.getTime())) throw new TypeError(\"Invalid CMS campaign date\");\n const captured = now.getTime();\n return defineCmsQuery({\n name: \"homePage.v1\", query: HOME_PAGE_DOCUMENT_QUERY, params: { id: READER_HOME_PAGE_ID },\n dependencies: { types: [\"homePage\"], ids: [READER_HOME_PAGE_ID] },\n resolve: (raw, fallback) => atomic(raw, fallback, (value) => parseHomePage(value, { now: new Date(captured) }), validHomeFallback),\n });\n}\n\nexport function contentPageQuery(slug: string): CmsQuery<PageContent | null> {\n if (typeof slug !== \"string\" || slug === \"\") throw new TypeError(\"Invalid CMS page slug\");\n return defineCmsQuery({\n name: \"page.v1\", query: CONTENT_PAGE_BY_SLUG_QUERY, params: { slug }, dependencies: { types: [\"page\"] },\n resolve: (raw, fallback) => atomic(raw, fallback, parseContentPage, validPageFallback),\n });\n}\n\nexport function contentPagesQuery(): CmsQuery<readonly PageContent[]> {\n return defineCmsQuery({\n name: \"pages.v1\", query: CONTENT_PAGES_QUERY, params: {}, dependencies: { types: [\"page\"] },\n resolve: (raw, fallback) => atomic(raw, fallback, (value) => {\n if (!Array.isArray(value)) throw new MalformedContentError(\"page\", [\"the page query did not return a list\"]);\n if (!isDenseArray(value)) throw new MalformedContentError(\"page\", [\"the page query contains missing entries\"]);\n return value.map((document: unknown) => parseContentPage(document));\n }, (value) => isDenseArray(value) && value.every((page: unknown) => page !== null && validPageFallback(page))),\n });\n}\n\nexport function siteSettingsQuery(): CmsQuery<SiteSettingsContent | null> {\n return defineCmsQuery({\n name: \"siteSettings.v1\", query: HOME_PAGE_DOCUMENT_QUERY, params: { id: READER_SITE_SETTINGS_ID },\n dependencies: { types: [\"siteSettings\"], ids: [READER_SITE_SETTINGS_ID] },\n resolve: (raw, fallback) => atomic(raw, fallback, parseSiteSettings, validSettingsFallback),\n });\n}\n"],
5
+ "mappings": "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",
6
+ "names": ["isDenseArray", "value", "index", "TYPE", "ID", "dependenciesCopy", "dependencies", "types", "type", "TYPE", "ids", "id", "ID", "defineCmsQuery", "query", "params", "copied", "key", "descriptor", "value", "object", "value", "words", "nullableText", "photo", "READER_PHOTO_SLUG", "href", "READER_ACTION_HREF", "copy", "optionalCopy", "action", "optionalAction", "composition", "isDenseArray", "hero", "block", "image", "READER_JUMP_LINK", "item", "READER_STORY_LAYOUTS", "layout", "model", "anchors", "link", "proposed", "line", "validHomeFallback", "validPageFallback", "validSettingsFallback", "MALFORMED_CONTENT", "MalformedContentError", "documentId", "problems", "READER_PHOTO_SLUG", "READER_ACTION_HREF", "READER_JUMP_LINK", "READER_STORY_LAYOUTS", "READER_HOME_PAGE_ID", "READER_SITE_SETTINGS_ID", "Reading", "path", "message", "value", "isDenseArray", "raw", "text", "source", "copy", "p", "max", "entry", "index", "label", "href", "plain", "portableTextToMarkdown", "reading", "markdown", "richTextToMarkdown", "out", "previousWasList", "member", "at", "block", "spansToMarkdown", "listItem", "style", "line", "level", "isList", "DECORATORS", "links", "markDefs", "def", "d", "children", "child", "span", "marks", "mark", "fence", "campaignState", "campaign", "now", "c", "starts", "ends", "keyed", "parseHomePage", "document", "options", "doc", "id", "hero", "rawHero", "photos", "heading", "subline", "intro", "cta", "secondaryCta", "blocks", "blockJumps", "body", "state", "title", "images", "action", "anchors", "rawBlocks", "mapped", "mapBlock", "buttonsOf", "jumps", "where", "stories", "item", "tail", "items", "story", "sat", "sHeading", "sBody", "image", "layout", "onCard", "jump", "anchor", "parseContentPage", "slugObject", "slug", "lead", "photo", "parseSiteSettings", "name", "description", "contact", "email", "phone", "social", "rawSocial", "link", "network", "url", "HOME_PAGE_DOCUMENT_QUERY", "CONTENT_PAGES_QUERY", "CONTENT_PAGE_BY_SLUG_QUERY", "createSiteContentReader", "client", "docs", "atomic", "fallback", "parse", "validFallback", "homeContentQuery", "captured", "defineCmsQuery", "validHomeFallback", "contentPageQuery", "validPageFallback", "contentPagesQuery", "page", "siteSettingsQuery", "validSettingsFallback"]
7
+ }
@@ -0,0 +1,2 @@
1
+ "use strict";var p=Object.create;var o=Object.defineProperty;var g=Object.getOwnPropertyDescriptor;var y=Object.getOwnPropertyNames;var f=Object.getPrototypeOf,C=Object.prototype.hasOwnProperty;var x=(t,r)=>{for(var a in r)o(t,a,{get:r[a],enumerable:!0})},d=(t,r,a,e)=>{if(r&&typeof r=="object"||typeof r=="function")for(let s of y(r))!C.call(t,s)&&s!==a&&o(t,s,{get:()=>r[s],enumerable:!(e=g(r,s))||e.enumerable});return t};var S=(t,r,a)=>(a=t!=null?p(f(t)):{},d(r||!t||!t.__esModule?o(a,"default",{value:t,enumerable:!0}):a,t)),q=t=>d(o({},"__esModule",{value:!0}),t);var v={};x(v,{assertCmsReadContract:()=>u});module.exports=q(v);var n=S(require("node:assert/strict"),1);async function u(t){(0,n.default)(Array.isArray(t.cases)&&t.cases.length>0,"CMS contract requires at least one case");let r=t.revalidateSeconds??3600;(0,n.default)(Number.isInteger(r)&&r>=3600,"CMS contract requires an integer interval of at least 3600 seconds");let a=new Set;for(let e of t.cases){(0,n.default)(e&&typeof e.name=="string"&&e.name.trim()&&!a.has(e.name),"CMS contract requires unique named cases"),a.add(e.name),n.default.equal(typeof e.exercise,"function","CMS contract requires an exercise"),(0,n.default)(Array.isArray(e.expectedTags)&&e.expectedTags.length>0&&e.expectedTags.every(s=>typeof s=="string"&&s.length>0)&&new Set(e.expectedTags).size===e.expectedTags.length,"CMS contract requires nonempty unique expected tags");for(let s of[!1,!0]){let i=0,m=[],l=async(T,c)=>{i++;try{n.default.deepEqual(c?.next?.tags,e.expectedTags,`${e.name}: every fetch must carry exactly the expected tags`),n.default.equal(c?.next?.revalidate,r,`${e.name}: every fetch must carry the expected interval`),(0,n.default)(c.cache!=="no-store"&&c.cache!=="no-cache",`${e.name}: fetch must retain caching`),(0,n.default)(c.method===void 0||c.method==="GET",`${e.name}: read must use GET`)}catch(h){m.push(h)}return s?new Response(null,{status:503}):Response.json({result:{heading:"CMS contract heading",intro:"CMS contract intro"}})};if(await e.exercise(l),(0,n.default)(i>0,`${e.name}: ${s?"failure":"published"} exercise must fetch`),m.length)throw m[0]}}}0&&(module.exports={assertCmsReadContract});
2
+ //# sourceMappingURL=testing.cjs.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../src/testing.ts", "../src/tooling/testing.ts"],
4
+ "sourcesContent": ["export { assertCmsReadContract } from \"./tooling/testing.js\";\nexport type { CmsContractCase } from \"./tooling/testing.js\";\n", "import assert from \"node:assert/strict\";\nimport type { CmsFetch } from \"../runtime/reader.js\";\n\nexport type CmsContractCase = {\n readonly name: string;\n readonly exercise: (fetchImpl: CmsFetch) => Promise<unknown>;\n readonly expectedTags: readonly string[];\n};\n\nexport async function assertCmsReadContract(options: {\n cases: readonly CmsContractCase[];\n revalidateSeconds?: number;\n}): Promise<void> {\n assert(Array.isArray(options.cases) && options.cases.length > 0, \"CMS contract requires at least one case\");\n const interval = options.revalidateSeconds ?? 3600;\n assert(Number.isInteger(interval) && interval >= 3600, \"CMS contract requires an integer interval of at least 3600 seconds\");\n const names = new Set<string>();\n for (const entry of options.cases) {\n assert(entry && typeof entry.name === \"string\" && entry.name.trim() && !names.has(entry.name), \"CMS contract requires unique named cases\");\n names.add(entry.name);\n assert.equal(typeof entry.exercise, \"function\", \"CMS contract requires an exercise\");\n assert(Array.isArray(entry.expectedTags) && entry.expectedTags.length > 0\n && entry.expectedTags.every((tag: unknown) => typeof tag === \"string\" && tag.length > 0)\n && new Set(entry.expectedTags).size === entry.expectedTags.length, \"CMS contract requires nonempty unique expected tags\");\n for (const failure of [false, true]) {\n let calls = 0;\n const errors: unknown[] = [];\n const fetchImpl: CmsFetch = async (_url, init) => {\n calls++;\n try {\n assert.deepEqual(init?.next?.tags, entry.expectedTags, `${entry.name}: every fetch must carry exactly the expected tags`);\n assert.equal(init?.next?.revalidate, interval, `${entry.name}: every fetch must carry the expected interval`);\n assert(init.cache !== \"no-store\" && init.cache !== \"no-cache\", `${entry.name}: fetch must retain caching`);\n assert(init.method === undefined || init.method === \"GET\", `${entry.name}: read must use GET`);\n } catch (error) {\n // A production reader can catch fetch errors and fall back. Preserve\n // assertion failures out of band so that catch cannot turn a pass green.\n errors.push(error);\n }\n return failure ? new Response(null, { status: 503 })\n : Response.json({ result: { heading: \"CMS contract heading\", intro: \"CMS contract intro\" } });\n };\n // The consumer owns model/render assertions, including valid local fallback.\n // Custom models can adapt this scripted envelope inside their exercise.\n await entry.exercise(fetchImpl);\n assert(calls > 0, `${entry.name}: ${failure ? \"failure\" : \"published\"} exercise must fetch`);\n if (errors.length) throw errors[0];\n }\n }\n}\n"],
5
+ "mappings": "0jBAAA,IAAAA,EAAA,GAAAC,EAAAD,EAAA,2BAAAE,IAAA,eAAAC,EAAAH,GCAA,IAAAI,EAAmB,mCASnB,eAAsBC,EAAsBC,EAG1B,IAChB,EAAAC,SAAO,MAAM,QAAQD,EAAQ,KAAK,GAAKA,EAAQ,MAAM,OAAS,EAAG,yCAAyC,EAC1G,IAAME,EAAWF,EAAQ,mBAAqB,QAC9C,EAAAC,SAAO,OAAO,UAAUC,CAAQ,GAAKA,GAAY,KAAM,oEAAoE,EAC3H,IAAMC,EAAQ,IAAI,IAClB,QAAWC,KAASJ,EAAQ,MAAO,IACjC,EAAAC,SAAOG,GAAS,OAAOA,EAAM,MAAS,UAAYA,EAAM,KAAK,KAAK,GAAK,CAACD,EAAM,IAAIC,EAAM,IAAI,EAAG,0CAA0C,EACzID,EAAM,IAAIC,EAAM,IAAI,EACpB,EAAAH,QAAO,MAAM,OAAOG,EAAM,SAAU,WAAY,mCAAmC,KACnF,EAAAH,SAAO,MAAM,QAAQG,EAAM,YAAY,GAAKA,EAAM,aAAa,OAAS,GACnEA,EAAM,aAAa,MAAOC,GAAiB,OAAOA,GAAQ,UAAYA,EAAI,OAAS,CAAC,GACpF,IAAI,IAAID,EAAM,YAAY,EAAE,OAASA,EAAM,aAAa,OAAQ,qDAAqD,EAC1H,QAAWE,IAAW,CAAC,GAAO,EAAI,EAAG,CACnC,IAAIC,EAAQ,EACNC,EAAoB,CAAC,EACrBC,EAAsB,MAAOC,EAAMC,IAAS,CAChDJ,IACA,GAAI,CACF,EAAAN,QAAO,UAAUU,GAAM,MAAM,KAAMP,EAAM,aAAc,GAAGA,EAAM,IAAI,oDAAoD,EACxH,EAAAH,QAAO,MAAMU,GAAM,MAAM,WAAYT,EAAU,GAAGE,EAAM,IAAI,gDAAgD,KAC5G,EAAAH,SAAOU,EAAK,QAAU,YAAcA,EAAK,QAAU,WAAY,GAAGP,EAAM,IAAI,6BAA6B,KACzG,EAAAH,SAAOU,EAAK,SAAW,QAAaA,EAAK,SAAW,MAAO,GAAGP,EAAM,IAAI,qBAAqB,CAC/F,OAASQ,EAAO,CAGdJ,EAAO,KAAKI,CAAK,CACnB,CACA,OAAON,EAAU,IAAI,SAAS,KAAM,CAAE,OAAQ,GAAI,CAAC,EAC/C,SAAS,KAAK,CAAE,OAAQ,CAAE,QAAS,uBAAwB,MAAO,oBAAqB,CAAE,CAAC,CAChG,EAKA,GAFA,MAAMF,EAAM,SAASK,CAAS,KAC9B,EAAAR,SAAOM,EAAQ,EAAG,GAAGH,EAAM,IAAI,KAAKE,EAAU,UAAY,WAAW,sBAAsB,EACvFE,EAAO,OAAQ,MAAMA,EAAO,CAAC,CACnC,CACF,CACF",
6
+ "names": ["testing_exports", "__export", "assertCmsReadContract", "__toCommonJS", "import_strict", "assertCmsReadContract", "options", "assert", "interval", "names", "entry", "tag", "failure", "calls", "errors", "fetchImpl", "_url", "init", "error"]
7
+ }