@murumets-ee/content-api 0.94.0 → 0.95.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.d.mts CHANGED
@@ -1,5 +1,6 @@
1
1
  import { Entity } from "@murumets-ee/entity";
2
2
  import { PermissionChecker, RouteContext } from "@murumets-ee/core";
3
+ import { z } from "zod";
3
4
  import { RateLimitStore } from "@murumets-ee/core/limits";
4
5
 
5
6
  //#region src/cache-tags.d.ts
@@ -545,6 +546,11 @@ interface ResolvedDetail {
545
546
  readonly provider: string;
546
547
  readonly reference: string;
547
548
  };
549
+ /** The trail from the site's top to this page: ancestors (with a path), then the page itself. */
550
+ readonly breadcrumbs?: readonly {
551
+ readonly label: string;
552
+ readonly href?: string;
553
+ }[];
548
554
  }
549
555
  /**
550
556
  * One live source's PUBLIC metadata — structural mirror of
@@ -601,9 +607,14 @@ interface ResolvedLiveValues {
601
607
  }
602
608
  /** One resolved collection block — the structural mirror of `@murumets-ee/blocks`' `CollectionResult`. */
603
609
  interface ResolvedCollection {
604
- readonly status: 'ok' | 'unset' | 'unavailable' | 'over-budget';
610
+ readonly status: 'ok' | 'unset' | 'unavailable' | 'over-budget' | 'needs-document';
605
611
  readonly entity: string | null;
606
612
  readonly rows: readonly ResolvedCollectionRow[];
613
+ /** A PAGED collection's position (davatoidud-toolkit PR03) — absent otherwise. */
614
+ readonly page?: {
615
+ readonly number: number;
616
+ readonly hasNext: boolean;
617
+ } | undefined;
607
618
  }
608
619
  /** One row, projected onto a card's slots — never the entity row itself. */
609
620
  interface ResolvedCollectionRow {
@@ -700,6 +711,12 @@ interface ResolveBlocksOptions {
700
711
  * `@murumets-ee/content`'s resolver does; a host-supplied one must too.
701
712
  */
702
713
  rowIsForeign?: boolean | undefined;
714
+ /**
715
+ * The page a PAGED collection in this tree shows (davatoidud-toolkit PR03) —
716
+ * the request's `?page=`, already validated (`singleParamsSchema`). Absent
717
+ * for page 1, and on every list read: a page number belongs to ONE document.
718
+ */
719
+ page?: number | undefined;
703
720
  }
704
721
  /**
705
722
  * Is `value` a {@link ResolvedBlockTree}?
@@ -951,6 +968,53 @@ declare const ERROR_CODES: readonly ["NOT_FOUND", "VALIDATION_ERROR", "INTERNAL_
951
968
  /** One of {@link ERROR_CODES}. */
952
969
  type ContentApiErrorCode = (typeof ERROR_CODES)[number];
953
970
  //#endregion
971
+ //#region src/search.d.ts
972
+ /** Results returned when the caller sends no `?limit=`. */
973
+ declare const DEFAULT_SEARCH_RESULTS = 20;
974
+ /** Most results one search returns — in total, and per type. A 400 above it, never a clamp. */
975
+ declare const MAX_SEARCH_RESULTS = 50;
976
+ /** One search result, as it crosses the wire. */
977
+ interface SearchHit {
978
+ /** The entity type — a name a frontend may map to its own words. */
979
+ type: string;
980
+ /** The type's English singular label — the fallback for a frontend with no words of its own. */
981
+ typeLabel: string;
982
+ id: string;
983
+ title: string;
984
+ summary: string | null;
985
+ image: MediaProjection | null;
986
+ /** Locale-relative canonical path, or `null` when the document has none. */
987
+ path: string | null;
988
+ }
989
+ /**
990
+ * The header a site's own frontend forwards its VISITOR's address on.
991
+ *
992
+ * Honoured ONLY from a caller whose credential is bound to a site — the site
993
+ * key a frontend holds server-side. That is what makes it more than obscurity
994
+ * (`core/limits/client-ip.ts` rule 7): the guarantee that "nobody reaches this
995
+ * without passing through what writes it" is not a deploy-topology claim here,
996
+ * it is the credential. An anonymous caller sending it is ignored.
997
+ */
998
+ declare const VISITOR_ADDRESS_HEADER = "x-lumi-visitor-address";
999
+ /** Tuning for {@link SearchRateLimiter}. Every field optional. */
1000
+ interface ContentApiSearchConfig {
1001
+ /** Searches one visitor may run per window, PER INSTANCE. Default 30. */
1002
+ searchesPerVisitorPerInstance?: number;
1003
+ /** The window, in ms. Default 60 000. */
1004
+ intervalMs?: number;
1005
+ /** The counter's store. Defaults to an in-memory, per-instance one. */
1006
+ store?: RateLimitStore;
1007
+ /**
1008
+ * The client address of an ANONYMOUS caller — a browser fetching `_search`
1009
+ * itself, or a site that sends no key. Overrides `limits.getClientIp` for
1010
+ * the search budget only, so a mount can bound searches per address without
1011
+ * also turning on the surface-wide fairness limit. Use the toolkit's one
1012
+ * derivation (`proxyClientIp` from `@murumets-ee/search/admin`, or
1013
+ * `createClientIpResolver` from `@murumets-ee/core/limits`).
1014
+ */
1015
+ getClientIp?: (req: Request) => string | undefined;
1016
+ }
1017
+ //#endregion
954
1018
  //#region src/types.d.ts
955
1019
  /** CORS configuration — deny-by-default, explicit origin allowlist. */
956
1020
  interface CorsConfig {
@@ -1883,6 +1947,15 @@ interface ContentApiConfig {
1883
1947
  * onto one shared bucket.
1884
1948
  */
1885
1949
  limits?: ContentApiLimits;
1950
+ /**
1951
+ * TUNING for the visitor search's per-visitor budget (`GET /_search`,
1952
+ * davatoidud-toolkit D001). Optional in full — the limit is on by default.
1953
+ *
1954
+ * Which types a site searches is NOT here: it is the site's own
1955
+ * `searchTypes` (the Sites page), so a mount serving several sites cannot
1956
+ * give one site another's choice.
1957
+ */
1958
+ search?: ContentApiSearchConfig;
1886
1959
  }
1887
1960
  /**
1888
1961
  * What the monitoring seam receives: DERIVED FACTS ONLY.
@@ -2060,5 +2133,5 @@ declare function createContentApiHandler(config: ContentApiConfig): {
2060
2133
  invalidatePermissionCache: () => void;
2061
2134
  };
2062
2135
  //#endregion
2063
- export { API_VERSION, type BlockTreeRef, CACHE_TAG_NAMESPACE, type CacheTagsConfig, type ContentApiChrome, type ContentApiChromeRegion, type ContentApiChromeRegions, type ContentApiConfig, type ContentApiDetailTemplates, type ContentApiErrorCode, type ContentApiErrorReport, type ContentApiMenus, type ContentApiPrincipal, type ContentApiResolution, type ContentApiResolvedMenu, type ContentApiResolvedMenuItem, type ContentApiSite, type ContentApiSiteProvider, type ContentPathEntry, type ContentResolveResult, DETAIL_TEMPLATE_FIELD, ERROR_CODES, MAX_CACHE_TAGS_PER_RESPONSE, MAX_CACHE_TAG_HEADER_BYTES, MAX_CACHE_TAG_LENGTH, MAX_RESOLUTIONS_PER_DOCUMENT, MEDIA_TAG_ENTITY, type MediaProjection, type MediaSource, type ReferenceProjection, type ResolutionBudget, type ResolutionKind, type ResolveBlocks, type ResolveEntityHref, type ResolveMedia, type ResolvedBlockTree, SHARED_SITE_TAG_SEGMENT, type SchemaCacheTags, type UnresolvedBlockRef, createContentApiHandler, isResolvedBlockTree };
2136
+ export { API_VERSION, type BlockTreeRef, CACHE_TAG_NAMESPACE, type CacheTagsConfig, type ContentApiChrome, type ContentApiChromeRegion, type ContentApiChromeRegions, type ContentApiConfig, type ContentApiDetailTemplates, type ContentApiErrorCode, type ContentApiErrorReport, type ContentApiMenus, type ContentApiPrincipal, type ContentApiResolution, type ContentApiResolvedMenu, type ContentApiResolvedMenuItem, type ContentApiSearchConfig, type ContentApiSite, type ContentApiSiteProvider, type ContentPathEntry, type ContentResolveResult, DEFAULT_SEARCH_RESULTS, DETAIL_TEMPLATE_FIELD, ERROR_CODES, MAX_CACHE_TAGS_PER_RESPONSE, MAX_CACHE_TAG_HEADER_BYTES, MAX_CACHE_TAG_LENGTH, MAX_RESOLUTIONS_PER_DOCUMENT, MAX_SEARCH_RESULTS, MEDIA_TAG_ENTITY, type MediaProjection, type MediaSource, type ReferenceProjection, type ResolutionBudget, type ResolutionKind, type ResolveBlocks, type ResolveEntityHref, type ResolveMedia, type ResolvedBlockTree, SHARED_SITE_TAG_SEGMENT, type SchemaCacheTags, type SearchHit, type UnresolvedBlockRef, VISITOR_ADDRESS_HEADER, createContentApiHandler, isResolvedBlockTree };
2064
2137
  //# sourceMappingURL=index.d.mts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.mts","names":[],"sources":["../src/cache-tags.ts","../src/resolution-budget.ts","../src/blocks.ts","../src/detail-template.ts","../src/limits.ts","../src/media.ts","../src/references.ts","../src/response.ts","../src/types.ts","../src/handler.ts"],"mappings":"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"}
1
+ {"version":3,"file":"index.d.mts","names":[],"sources":["../src/cache-tags.ts","../src/resolution-budget.ts","../src/blocks.ts","../src/detail-template.ts","../src/limits.ts","../src/media.ts","../src/references.ts","../src/response.ts","../src/search.ts","../src/types.ts","../src/handler.ts"],"mappings":"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"}
package/dist/index.mjs CHANGED
@@ -1,2 +1,2 @@
1
- import{CountCache as e,SITE_COLUMN as t,SiteRequiredError as n,blockTreeFieldsOf as r,blockTreeTemplateOf as i,buildTranslationsSearchExists as a,decodeCursor as o,encodeCursor as s,filterTranslatableFields as c,getEntityTitleField as l,getSearchableConfig as u,isSiteBound as d,isSortOnlyInternalField as f,isTemplateDrawn as p,isValidSiteHandle as m}from"@murumets-ee/entity";import{LOCALE_PATTERN as h,REQUEST_ID_HEADER as g,escapeLikePattern as _,getApp as v,getAppOrUndefined as y,getContext as b,getCurrentSite as x,readSiteOriginIndex as S,readSiteRecord as C,requireSiteFor as w,resolveImplicitSite as T,resolveRequestId as E,runBounded as D,runWithContextAsync as O,siteSecurityFields as ee}from"@murumets-ee/core";import{schemaRegistry as k}from"@murumets-ee/db";import{QueryClient as A}from"@murumets-ee/entity/query";import{and as te,asc as ne,desc as j,eq as M,getTableColumns as re,gte as ie,ilike as ae,inArray as oe,lte as N,or as se,sql as P}from"drizzle-orm";import{z as F}from"zod";import{InMemoryRateLimitStore as ce,Semaphore as I,runWithDeadline as le}from"@murumets-ee/core/limits";const L=[`reference`,`populate`,`media`,`block`],ue=200;function de(e){if(!Number.isInteger(e)||e<0)throw Error(`content-api: resolution budget ceiling must be a non-negative integer, received ${String(e)}.`);let t=e,n=0,r=new Map;return{claim(e,i){if(!Number.isInteger(i)||i<=0)return 0;let a=Math.min(i,t);t-=a,n+=a;let o=i-a;return o>0&&r.set(e,(r.get(e)??0)+o),a},get remaining(){return t},get granted(){return n},get hasDrops(){return r.size>0},dropSummary(){let e={};for(let t of L){let n=r.get(t);n!==void 0&&n>0&&(e[t]=n)}return e},ceiling:e}}function fe(e){if(e===void 0)return 200;if(!Number.isInteger(e)||e<0)throw Error(`content-api: \`maxResolutionsPerDocument\` must be an integer >= 0, received ${String(e)}. If this came from an environment variable, it is probably unset — omit the option to get the package default (200).`);return Math.min(e,200)}function pe(e){return typeof e==`object`&&!!e&&!Array.isArray(e)}function me(e){if(!pe(e))return!1;let t=e=>e===void 0||typeof e==`string`&&e.length<=2e3,n=e=>e===void 0||typeof e==`number`&&Number.isFinite(e)&&e>=0;if(!t(e.title)||!t(e.text))return!1;let r=e.price;if(r!==void 0&&(!pe(r)||typeof r.amount!=`number`||!Number.isFinite(r.amount)||r.amount<0||!n(r.compareAt)||!t(r.unit)))return!1;let i=e.facts;if(i!==void 0){if(!Array.isArray(i)||i.length>12)return!1;for(let e of i)if(!pe(e)||typeof e.key!=`string`||typeof e.label!=`string`||typeof e.value!=`string`&&typeof e.value!=`number`||e.format!==void 0&&e.format!==`price`)return!1}let a=e.body;if(a!==void 0){if(!pe(a)||typeof a.html!=`string`||a.html.length>5e5||!Array.isArray(a.headings)||a.headings.length>100)return!1;for(let e of a.headings)if(!pe(e)||typeof e.id!=`string`||typeof e.text!=`string`||e.level!==2&&e.level!==3)return!1}let o=e.embed;return!(o!==void 0&&(!pe(o)||typeof o.provider!=`string`||typeof o.reference!=`string`))}const he=new Set([`price`,`number`,`text`]);function ge(e){if(typeof e!=`object`||!e||Array.isArray(e))return!1;let t=e;return R(t.name)&&R(t.label)&&he.has(t.format)&&(t.unit===void 0||R(t.unit))}function R(e){if(typeof e!=`string`||e.length>1200)return!1;for(let t=0;t<e.length;t++)if(e.charCodeAt(t)<32)return!1;return!0}function _e(e){if(typeof e!=`object`||!e||Array.isArray(e))return!1;let{sources:t,values:n}=e;if(typeof t!=`object`||!t||Array.isArray(t)||typeof n!=`object`||!n||Array.isArray(n))return!1;let r=Object.entries(t);if(r.length>32)return!1;for(let[,e]of r){if(typeof e!=`object`||!e||Array.isArray(e))return!1;let t=e;if(typeof t.label!=`string`||t.labelKey!==void 0&&typeof t.labelKey!=`string`||t.kind!==void 0&&t.kind!==`price`&&t.kind!==`text`&&t.kind!==`list`&&t.kind!==`facts`||t.facts!==void 0&&(!Array.isArray(t.facts)||t.facts.length>48||!t.facts.every(ge))||t.fields!==void 0&&(!Array.isArray(t.fields)||t.fields.length>64||!t.fields.every(e=>typeof e==`string`)))return!1}let i=Object.entries(n);if(i.length>32)return!1;for(let[,e]of i){if(typeof e!=`object`||!e||Array.isArray(e))return!1;let t=Object.entries(e);if(t.length>200)return!1;for(let[,e]of t){if(typeof e!=`object`||!e||Array.isArray(e))return!1;let t=e;if(t.amount!==void 0&&(typeof t.amount!=`number`||!Number.isFinite(t.amount))||t.compareAt!==void 0&&(typeof t.compareAt!=`number`||!Number.isFinite(t.compareAt))||t.unit!==void 0&&typeof t.unit!=`string`||t.text!==void 0&&!R(t.text)||t.items!==void 0&&(!Array.isArray(t.items)||t.items.length>100||!t.items.every(R)))return!1;if(t.facts!==void 0){if(typeof t.facts!=`object`||t.facts===null||Array.isArray(t.facts))return!1;let e=Object.entries(t.facts);if(e.length>48)return!1;for(let[,t]of e)if(!(typeof t==`number`&&Number.isFinite(t)||R(t)))return!1}}}return!0}const ve=new Set([`ok`,`unset`,`unavailable`,`over-budget`]);function ye(e){if(typeof e!=`object`||!e||Array.isArray(e))return!1;let t=e;if(typeof t.status!=`string`||!ve.has(t.status)||t.entity!==null&&(typeof t.entity!=`string`||t.entity===``)||!Array.isArray(t.rows)||t.rows.length>100||t.status===`ok`&&t.entity===null||t.status!==`ok`&&t.rows.length>0||(t.status===`unset`||t.status===`unavailable`)&&t.entity!==null)return!1;for(let e of t.rows){if(typeof e!=`object`||!e||Array.isArray(e))return!1;let t=e;if(typeof t.id!=`string`||t.id===``)return!1;for(let e of[t.title,t.text,t.href])if(e!==null&&typeof e!=`string`)return!1;if(t.image!==null){if(typeof t.image!=`object`||Array.isArray(t.image))return!1;let e=t.image;if(typeof e.url!=`string`||e.alt!==null&&typeof e.alt!=`string`)return!1;for(let t of[e.width,e.height])if(t!==null&&typeof t!=`number`)return!1}}return!0}function be(e){if(!Number.isInteger(e)||e<0)throw Error(`content-api: collection allowance must be a non-negative integer, received ${String(e)}.`);let t=e,n=0;return{claim:()=>t===0?(n+=1,!1):(--t,!0),refusedCount:()=>n}}function z(e){if(typeof e!=`object`||!e||Array.isArray(e))return!1;let t=e;if(t.resolved!==1||!Array.isArray(t.blocks))return!1;let n=t.links;if(typeof n!=`object`||!n||Array.isArray(n))return!1;for(let e of Object.values(n))if(e!==null&&typeof e!=`string`)return!1;let r=new Set,i=t.refs;if(i!==void 0){if(!Array.isArray(i))return!1;for(let e of i){if(typeof e!=`object`||!e||Array.isArray(e))return!1;let t=e;if(typeof t.entity!=`string`||t.entity===``||typeof t.id!=`string`||t.id===``)return!1;r.add(`${t.entity}\u0000${t.id}`)}}let a=t.collections;if(a!==void 0){if(typeof a!=`object`||!a||Array.isArray(a))return!1;let e=Object.entries(a);if(e.length>64)return!1;for(let[t,n]of e){if(t===``||!ye(n))return!1;if(!(n.status!==`ok`||n.entity===null)){for(let e of n.rows)if(!r.has(`${n.entity}\u0000${e.id}`))return!1}}}let o=t.unresolved;if(o!==void 0){if(!Array.isArray(o))return!1;for(let e of o)if(!B(e))return!1}return!(t.live!==void 0&&!_e(t.live)||t.currency!==void 0&&typeof t.currency!=`string`||t.detail!==void 0&&!me(t.detail))}function B(e){if(typeof e!=`object`||!e||Array.isArray(e))return!1;let t=e;return t.kind!==`media`&&t.kind!==`link`||typeof t.ref!=`string`?!1:t.reason===`unresolvable`||t.reason===`budget`}function xe(e){return r(e).filter(e=>!e.internal).map(e=>e.name)}const Se=Object.freeze({resolved:1,blocks:Object.freeze([]),links:Object.freeze({})});async function V(e,t,n){try{let r=await e(t,n.boundValues===void 0?n:{...n,boundValues:structuredClone(n.boundValues)});return z(r)?{ok:!0,envelope:r}:{ok:!1,failure:`malformed`}}catch(e){return{ok:!1,failure:`threw`,error:e}}}async function Ce(e,t,n){let r=await V(e,t,n);if(r.ok)return{envelope:r.envelope};let i=await V(e,t,{...n,budget:de(0),claimCollection:void 0});return i.ok?{envelope:i.envelope,failure:r.failure,error:r.error}:{envelope:Se,failure:r.failure,retryFailure:i.failure,error:r.error??i.error}}async function we(e,t,n){if(t.length===0)return;let r=n.resolveBlocks;if(!r)return;let a=xe(e);if(a.length===0)return;let o=0,s=0,c=0,l,u,d=new Set,f=new Set,p=new Set;for(let m of t)for(let t of a){let a=m[t],h=i(e,t);if(h!==void 0&&!Object.hasOwn(m,t)||h===void 0&&a==null)continue;let g=await Ce(r,h===void 0?a:[],{locale:n.locale,budget:n.budget,entity:e.name,field:t,...h!==void 0&&{template:h},boundValues:{...m},...n.canReadEntity!==void 0&&{canReadEntity:n.canReadEntity},...n.collectionAllowance!==void 0&&{claimCollection:n.collectionAllowance.claim}});if(g.failure===`threw`?(o+=1,d.add(t),l??=g.error):g.failure===`malformed`&&(s+=1,f.add(t)),g.retryFailure!==void 0&&(c+=1,p.add(t),u??=g.error,n.cacheTags?.markUncacheable()),m[t]=g.envelope,g.envelope.refs!==void 0)for(let e of g.envelope.refs)n.cacheTags?.addDocument(e.entity,e.id);if(g.envelope.collections!==void 0)for(let e of Object.values(g.envelope.collections))e.entity!==null&&n.cacheTags?.addCollection(e.entity)}o>0&&n.logger?.warn({entity:e.name,fields:[...d],rows:t.length,failures:o,err:l},`content-api: block resolver threw — no tree is served as stored; each was re-resolved with an exhausted budget, so its media refs and link hrefs are stripped rather than carrying the urls recorded when an editor picked them. Fields that failed that retry as well are reported separately, as empty.`),s>0&&n.logger?.warn({entity:e.name,fields:[...f],rows:t.length,failures:s},`content-api: block resolver returned a value that is not a ResolvedBlockTree — no tree is served as stored; each was re-resolved with an exhausted budget, so its media refs and link hrefs are stripped rather than carrying the urls recorded when an editor picked them. Fields that failed that retry as well are reported separately, as empty.`),c>0&&n.logger?.warn({entity:e.name,fields:[...p],rows:t.length,failures:c,err:u},`content-api: block resolver failed TWICE, including on the in-memory retry — those fields are served as an empty resolved tree, so that content is missing from the response. Serving the stored tree instead would put the media urls recorded when an editor picked them, which may be signed, on a cacheable anonymous response.`)}const H=`_template`;function Te(e){if(typeof e!=`string`)return;let t=e.trim();return t===``?void 0:t.slice(0,2e3)}async function Ee(e,t,n,r){let i={...t};for(let e of Object.keys(t))e!==`id`&&delete t[e];let a=n.detailTemplates;if(!a)return;let o=n.locale??n.defaultLocale;if(o===void 0)return;try{let n=await a.publicRow({entity:e.name,row:i,locale:o}),r=Te(n.title),s=Te(n.description);r!==void 0&&(t.title=r),s!==void 0&&(t.description=s)}catch(t){n.logger?.warn({entity:e.name,err:t},`content-api: detail-template provider failed to project a row — served with its id only`),n.cacheTags?.markUncacheable()}if(!r)return;let s=n.resolveBlocks;if(!s||(n.cacheTags?.addCollection(a.entity),n.budget.claim(`block`,1)<1))return;let c;try{c=await a.readTemplate({entity:e.name,locale:o})}catch(t){n.logger?.warn({entity:e.name,err:t},`content-api: detail-template provider failed to read the template — the row is served without one and the response is not cacheable`),n.cacheTags?.markUncacheable();return}if(c===null||typeof c.id!=`string`||!Array.isArray(c.blocks))return;n.cacheTags?.addDocument(a.entity,c.id);let l=await Ce(s,c.blocks,{locale:n.locale,budget:n.budget,entity:e.name,field:H,boundValues:i,rowIsForeign:!0,...n.canReadEntity!==void 0&&{canReadEntity:n.canReadEntity},...n.collectionAllowance!==void 0&&{claimCollection:n.collectionAllowance.claim}});l.failure!==void 0&&n.logger?.warn({entity:e.name,field:H,failure:l.failure,retryFailure:l.retryFailure,err:l.error},`content-api: block resolver failed on a detail template — served re-resolved with an exhausted budget, or empty if that failed as well`),l.retryFailure!==void 0&&n.cacheTags?.markUncacheable(),De(l.envelope,n),t[H]=l.envelope}function De(e,t){if(e.refs!==void 0)for(let n of e.refs)t.cacheTags?.addDocument(n.entity,n.id);if(e.collections!==void 0)for(let n of Object.values(e.collections))n.entity!==null&&t.cacheTags?.addCollection(n.entity)}const U=`lumi`,Oe=128,ke=128,Ae=3072,je=`media`,Me=/^[A-Za-z0-9_.-]+$/,Ne=`_`,W={enabled:!0,header:`Cache-Tag`,separator:`,`},Pe=/^[!#$%&'*+\-.^_`|~0-9A-Za-z]+$/,Fe=[`cache-control`,`vary`,`content-type`],Ie=[`access-control-`];function Le(e){if(e){if(e.enabled!==void 0&&typeof e.enabled!=`boolean`)throw Error(`content-api cache: \`cache.tags.enabled\` must be a boolean, received ${JSON.stringify(e.enabled)}.`);if(e.header!==void 0){if(typeof e.header!=`string`||!Pe.test(e.header))throw Error(`content-api cache: \`cache.tags.header\` must be a valid HTTP field name (RFC 9110 §5.1 token), received ${JSON.stringify(e.header)}. Common values: \`Cache-Tag\` (Cloudflare/Netlify, the default), \`Surrogate-Key\` (Fastly), \`Edge-Cache-Tag\` (Akamai).`);let t=e.header.toLowerCase();if(Fe.includes(t)||Ie.some(e=>t.startsWith(e)))throw Error(`content-api cache: \`cache.tags.header\` may not be ${JSON.stringify(e.header)} — this package writes that header itself on the same responses, so the tags would either overwrite it or be overwritten, silently and on every request.`)}if(e.separator!==void 0&&e.separator!==`,`&&e.separator!==` `)throw Error(`content-api cache: \`cache.tags.separator\` must be ',' or ' ', received ${JSON.stringify(e.separator)}. Cloudflare and Akamai parse comma-separated tags; Fastly parses space-separated ones. A third separator would not error at the CDN — it would parse as one giant unmatched key, which is the silent failure this refuses.`)}}function Re(e){return{enabled:e?.enabled??W.enabled,header:e?.header??W.header,separator:e?.separator??W.separator}}function ze(e){return typeof e==`string`&&e!==``&&Me.test(e)}function Be(e,t){function n(e){if(t===void 0)return U;let n=t(e);return ze(n)?`${U}:${n}`:void 0}let r=new Set,i=0,a=!1,o=e.header.length+4,s=!1;function c(e){if(r.has(e))return;if(e.length>128||r.size>=128){i+=1;return}let t=e.length+(r.size===0?0:1);if(s||o+t>3072){s=!0,i+=1;return}o+=t,r.add(e)}return{addDocument(e,t){if(!ze(e)||!ze(t)){i+=1;return}let r=n(e);if(r===void 0){i+=1;return}c(`${r}:${e}:${t}`)},addCollection(e){if(!ze(e)){i+=1;return}let t=n(e);if(t===void 0){i+=1;return}c(`${t}:${e}`)},get tags(){return[...r]},markUncacheable(){a=!0},get dropped(){return i},get uncacheable(){return a},headers(){return!e.enabled||r.size===0?{}:{[e.header]:[...r].join(e.separator)}}}}function Ve(e){let t=Math.ceil(e/6);return{maxAge:t,swr:e-t}}const He=[`defaultMaxAge`,`defaultStaleWhileRevalidate`,`maxAge`,`staleWhileRevalidate`];function Ue(e,t){if(e!==void 0&&(typeof e!=`number`||!Number.isInteger(e)||e<0))throw Error(`content-api cache: \`${t}.maxStaleSeconds\` must be a non-negative integer, received ${JSON.stringify(e)}. Use 0 for \`no-store\` if you need a published edit visible on the very next request.`)}function We(e,t){for(let n of He)if(n in e)throw Error(`content-api cache: \`${t}.${n}\` was removed (D036). Use \`maxStaleSeconds\` — ONE number naming the TOTAL staleness window in seconds. The old pair's real window was their SUM and nothing said so, which is the defect D036 exists to close: \`defaultMaxAge: 10\` bought a 310-second window, not a 10-second one. The max-age / stale-while-revalidate split is now derived, so what is emitted always sums to what you declared.`)}function Ge(e){if(e){We(e,`cache`),Ue(e.maxStaleSeconds,`cache`),Le(e.tags);for(let[t,n]of Object.entries(e.entities??{})){if(!n)continue;let e=`cache.entities.${t}`;We(n,e),Ue(n.maxStaleSeconds,e)}}}function Ke(e,t){let n=t?.entities?.[e];return n?.cacheable===!1?0:n?.maxStaleSeconds??t?.maxStaleSeconds??360}function qe(e,t){let n=Ke(e,t);if(n===0)return{"Cache-Control":`no-store`};let{maxAge:r,swr:i}=Ve(n);return{"Cache-Control":`public, max-age=${r}, stale-while-revalidate=${i}`}}const Je=[`Origin`];function G(e,t){let n=new Set,r=[];for(let i of[...e?.split(`,`)??[],...Je,...t]){let e=i.trim();if(e===``)continue;let t=e.toLowerCase();n.has(t)||(n.add(t),r.push(e))}return r.join(`, `)}function K(e,t,n,r,i,a){let o=(n!==`identified`&&i.kind!==`undeclared`&&a?.uncacheable!==!0?qe(e,r):{"Cache-Control":`no-store`})[`Cache-Control`]??`no-store`,s={"Cache-Control":n===`site-keyed`?o.replace(/^public\b/,`private`):o};return{...t,...s,...s[`Cache-Control`]===`no-store`?{}:a?.headers(),Vary:G(t.Vary,i.kind===`declared`?i.headers:[])}}function Ye(e,t,n,r){let i=r?.uncacheable===!0?{"Cache-Control":`no-store`}:qe(e,n);return{...t,...i,...i[`Cache-Control`]===`no-store`?{}:r?.headers(),Vary:G(void 0,[])}}function Xe(e,t){return{...e,Vary:G(e.Vary,t.kind===`declared`?t.headers:[])}}function Ze(e,t){if(!t)return{};let n=e.headers.get(`Origin`);return n!==null&&t.allowedOrigins.includes(n)?{"Access-Control-Allow-Origin":n,"Access-Control-Allow-Methods":`GET, OPTIONS`,"Access-Control-Allow-Headers":`Content-Type, Accept, Authorization`,"Access-Control-Max-Age":String(t.maxAge??3600),Vary:`Origin`}:{Vary:`Origin`}}function Qe(e,t,n){let r={...Ze(e,t),...qe(`_preflight`,n)};return new Response(null,{status:204,headers:r})}var $e=class extends Error{constructor(){super(`Service overloaded`),this.name=`ServiceOverloadedError`}},et=class extends Error{constructor(){super(`Request deadline exceeded`),this.name=`RequestDeadlineError`}};function tt(e,t,n){if(e===void 0)return t;if(!Number.isInteger(e)||e<0)throw Error(`content-api limits: \`${n}\` must be a non-negative integer (got ${e})`);return e}function nt(e,t,n){if(e===void 0)return t;if(!Number.isInteger(e)||e<1)throw Error(`content-api limits: \`${n}\` must be a positive integer (got ${e})`);return e}function rt(e){return{maxConcurrentRequests:nt(e?.maxConcurrentRequests,64,`maxConcurrentRequests`),maxQueuedRequests:tt(e?.maxQueuedRequests,128,`maxQueuedRequests`),requestTimeoutMs:nt(e?.requestTimeoutMs,1e4,`requestTimeoutMs`),anonymousTokensPerInstance:nt(e?.anonymousTokensPerInstance,120,`anonymousTokensPerInstance`),intervalMs:nt(e?.intervalMs,6e4,`intervalMs`),maxBudgetPerInstance:nt(e?.maxBudgetPerInstance,6e3,`maxBudgetPerInstance`)}}var it=class{semaphore;store;limits;getClientIp;constructor(e){this.getClientIp=e?.getClientIp,this.limits=rt(e),this.semaphore=new I(this.limits.maxConcurrentRequests,this.limits.maxQueuedRequests),this.store=e?.store??new ce}async acquire(e){await this.semaphore.acquire(()=>new $e,e)}release(){this.semaphore.release()}async runGuarded(e){return await le(e,this.limits.requestTimeoutMs,()=>new et)}consumeFairness(e,t,n){let r=this.resolveKey(e,t);if(r)return{decision:this.store.consume(r.key,{tokens:this.budgetFor(t),intervalMs:this.limits.intervalMs},n),keyClass:r.keyClass}}budgetFor(e){let t=e.budgetPerInstance??this.limits.anonymousTokensPerInstance;return Math.min(t,this.limits.maxBudgetPerInstance)}resolveKey(e,t){if(t.principalId!==void 0)return{key:`principal:${t.principalId}`,keyClass:`principal`};let n=this.getClientIp?.(e);if(n!==void 0&&n!==``)return{key:`ip:${n}`,keyClass:`client-ip`}}};const at=/[\u200B-\u200D\u2060\uFEFF]/g;function ot(e){return e.replace(at,``).trim()}const st=2048,ct=F.object({limit:F.coerce.number().int().min(1).max(100).default(20),offset:F.coerce.number().int().min(0).default(0),sort:F.string().regex(/^-?[a-zA-Z_]+$/).optional(),locale:F.string().regex(h).optional(),fields:F.string().optional(),search:F.string().max(200).refine(e=>{let t=ot(e);return t.length===0||t.length>=2},{message:`search must be at least 2 characters`}).optional(),cursor:F.string().max(500).optional(),populate:F.string().max(200).optional()}).strict(),lt=F.object({locale:F.string().regex(h).optional(),fields:F.string().optional(),populate:F.string().max(200).optional()}).strict(),ut=F.object({locale:F.string().regex(h).optional()}).strict(),dt=/^filter\[([a-zA-Z0-9_]+)\]$/;function q(e,t){let n={};for(let[r,i]of e.searchParams.entries())t?.allowFilters===!0&&dt.test(r)||(n[r]=i);return n}const ft=/^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i,pt=/^\d{4}-\d{2}-\d{2}(?:[Tt ]\d{2}:\d{2}(?::\d{2}(?:\.\d+)?)?(?:[Zz]|[+-]\d{2}:?\d{2})?)?$/;function mt(e){if(!pt.test(e))return!1;let t=Date.parse(e);return Number.isNaN(t)?!1:e.length===10?new Date(t).toISOString().slice(0,10)===e:!0}function ht(e){if(e.trim()===``)return!1;let t=Number(e);return Number.isFinite(t)}function gt(e){return ft.test(e)}function _t(e,t){switch(e.type){case`boolean`:return t===`true`?!0:t===`false`?!1:null;case`reference`:case`media`:return ft.test(t)?t:null;case`select`:return e.options.includes(t)?t:null;case`date`:return mt(t.startsWith(`gte:`)||t.startsWith(`lte:`)?t.slice(4):t)?t:null;case`number`:return ht(t)?Number(t):null;case`text`:return t.length<=200?t:null;default:return null}}function J(e,t){return e.startsWith(`_`)||t?.internal===!0||t?.adminOnly===!0}function vt(e,t){if(!e)return;let n=e.split(`,`).map(e=>e.trim()).filter(e=>{if(!Object.hasOwn(t,e))return!1;let n=t[e];return n!==void 0&&!J(e,n)&&n.type!==`blockTree`});return n.includes(`id`)||n.unshift(`id`),n}function yt(e,t){if(!e)return{fields:[],dropped:[],requested:0};let n=[...new Set(e.split(`,`).map(e=>e.trim()).filter(e=>e.length>0))],r=[],i=[];for(let e of n){if(!Object.hasOwn(t,e)){i.push(e);continue}let n=t[e];if(!n||J(e,n)||n.type!==`reference`){i.push(e);continue}r.push(e)}return{fields:r,dropped:i,requested:n.length}}function bt(e){let t=[];for(let[n,r]of Object.entries(e.allFields))r.type!==`media`||J(n,r)||t.push([n,r]);return t}async function xt(e,t,n){if(t.length===0)return;let r=bt(e);if(r.length===0)return;let i=new Set;for(let e of t)for(let[t]of r){if(!Object.hasOwn(e,t))continue;let n=e[t];typeof n==`string`&&n!==``&&i.add(n)}let a=new Map;if(i.size>0&&n.resolveMedia){let t=[...i],r=n.budget.claim(`media`,t.length),o=t.slice(0,r);if(o.length>0)try{a=await n.resolveMedia(o,{locale:n.locale})}catch(t){n.logger?.warn({entity:e.name,err:t},"content-api: media resolver threw — media fields resolve to null (if this is a ForbiddenError, the requesting role is missing `media:view`)")}}else i.size>0&&n.logger?.debug({entity:e.name,mediaFields:r.map(([e])=>e)},"content-api: no `resolveMedia` provider wired — media fields resolve to null");for(let[e,t]of a)i.has(e)&&t?.id===e&&n.cacheTags?.addDocument(je,e);for(let e of t)for(let[t]of r){if(!Object.hasOwn(e,t))continue;let n=e[t];e[t]=typeof n==`string`?a.get(n)??null:null}}function St(e){let t=[];for(let[n,r]of Object.entries(e.allFields))r.type!==`reference`||J(n,r)||t.push([n,r]);return t}function Ct(e){return typeof e==`string`&&e.length>0}function wt(e,t){return t===`many`?Array.isArray(e)?e.filter(Ct):[]:Ct(e)?[e]:[]}async function Tt(e,t,n,r,i=0){if(t.length===0)return;let a=St(e);if(a.length===0)return;let o=new Map,s=[];for(let e of t)for(let[t,c]of a){if(!Object.hasOwn(e,t))continue;let a=wt(e[t],c.cardinality),l=i===0&&n.has(t),u=r.reachableEntity(c.entity);if(!u||a.length===0){s.push({row:e,field:t,cardinality:c.cardinality,groupKey:null,ids:a});continue}let d=`${u.name}::${l?`full`:`projection`}`,f=o.get(d);f||(f={target:u,expand:l,ids:new Set},o.set(d,f));for(let e of a)f.ids.add(e);s.push({row:e,field:t,cardinality:c.cardinality,groupKey:d,ids:a})}let c=new Map;for(let[e,t]of o){let n=[...t.ids],a=r.budget.claim(t.expand?`populate`:`reference`,n.length),o=n.slice(0,a);if(o.length===0){c.set(e,new Map);continue}let s=l(t.target),u=p(t.target),d=u?r.templateDrawnTitle:void 0,f=t.expand||d!==void 0?void 0:u?[`id`]:Et([`id`,s]),m=await r.readRowsByIds(t.target,o,f),h=new Map;if(t.expand){for(let e of m){let t=e.id;Ct(t)&&h.set(t,e)}await Tt(t.target,m,new Set,r,i+1),await r.afterExpand?.(t.target,m)}else{let e=await Dt(t.target.name,m,r);for(let[n,r]of m.entries()){let i=r.id;if(!Ct(i))continue;let a=u?await d?.(t.target,r)??null:r[s];h.set(i,{id:i,entityType:t.target.name,title:typeof a==`string`?a:null,href:e[n]??null})}}for(let e of h.keys())r.cacheTags?.addDocument(t.target.name,e);c.set(e,h)}for(let e of s){let t=e.groupKey===null?void 0:c.get(e.groupKey);if(e.cardinality===`many`){e.row[e.field]=e.ids.map(e=>t?.get(e)).filter(e=>e!==void 0);continue}let n=e.ids[0];e.row[e.field]=n===void 0?null:t?.get(n)??null}}function Et(e){return[...new Set(e)]}async function Dt(e,t,n){let r=n.resolveEntityHref;return r?D(t,async t=>{let i=t.id;if(!Ct(i))return null;try{return await r({entity:e,id:i,...n.locale!==void 0&&{locale:n.locale}})??null}catch(t){return n.logger?.debug({entity:e,id:i,err:t},`content-api: resolveEntityHref threw — reference resolves without an href`),null}}):t.map(()=>null)}const Ot=[`NOT_FOUND`,`VALIDATION_ERROR`,`INTERNAL_ERROR`,`RATE_LIMITED`,`SERVICE_OVERLOADED`];function Y(e,t=200,n){return new Response(JSON.stringify(e),{status:t,headers:{"Content-Type":`application/json`,...n}})}const kt={"Cache-Control":`no-store`},At=new WeakMap;function jt(e){return At.get(e)}function X(e,t,n,r){let i=Y({error:{status:n,message:e,code:t}},n,{...r,...kt});return At.set(i,t),i}function Z(e){return X(`Not found`,`NOT_FOUND`,404,e)}function Mt(e,t){return X(`Rate limit exceeded`,`RATE_LIMITED`,429,{...t,"Retry-After":String(e)})}function Nt(e,t){return X(`Service overloaded`,`SERVICE_OVERLOADED`,503,{...t,"Retry-After":String(e)})}const Pt={referenceProjection:{fields:{id:`string`,entityType:`string`,title:`string`,href:`string`},nullableFields:[`title`,`href`],nullable:!0,arrayForCardinalityMany:!0},mediaProjection:{fields:{id:`string`,url:`string`,mimeType:`string`,width:`number`,height:`number`,alt:`string`,title:`string`,variants:`object`,sources:`object`,avifSources:`object`,focalPoint:`object`,blurDataUrl:`string`},nullableFields:[`mimeType`,`width`,`height`,`alt`,`title`,`blurDataUrl`],optionalFields:[`avifSources`],nullable:!0,arrayForCardinalityMany:!1}};function Ft(e,t){let n={type:e.type};return e.required&&(n.required=!0),e.translatable&&(n.translatable=!0),e.type===`select`&&(n.options=e.options),e.type===`blockTree`&&(n.selectable=!1),e.type===`media`&&(n.wire=`mediaProjection`),e.type===`reference`&&(n.cardinality=e.cardinality,n.wire=`referenceProjection`,t(e.entity)&&(n.entity=e.entity,n.populatable=!0)),n}function It(e,t){let n=e.allFields,r={},i=p(e);for(let[e,a]of Object.entries(n))J(e,a)||i&&e!==`id`||(r[e]=Ft(a,t));let a=u(e);for(let e of a?.fields??[]){let t=r[e];t&&(t.searchable=!0)}return{name:e.name,pluralName:`${e.name}s`,kind:e.kind??`collection`,...i&&{drawnBy:`template`},fields:r}}const Lt={type:`string`},Rt={type:`string`},zt={type:`string`,maxLength:200,maxItems:5};function Bt(e){let{maxLimit:t,maxOffset:n,hasResolution:r,hasMenus:i,hasChrome:a}=e,o=[{id:`list`,path:`/:entity`,data:`array`,entityKind:`collection`,params:{limit:{type:`number`,min:1,max:t,default:Math.min(20,t)},offset:{type:`number`,min:0,max:n,default:0},sort:{type:`string`},locale:Lt,fields:Rt,search:{type:`string`,maxLength:200,minLength:2},cursor:{type:`string`,maxLength:500},populate:zt,"filter[<field>]":{type:`string`}},meta:{total:{type:`number`,nullable:!0,suppressedBy:[`search`]},limit:{type:`number`},offset:{type:`number`},hasMore:{type:`boolean`},nextCursor:{type:`string`,optional:!0}}},{id:`singleton`,path:`/:entity`,data:`object`,entityKind:`singleton`,params:{locale:Lt,fields:Rt,populate:zt}},{id:`count`,path:`/:entity/count`,data:`object`,entityKind:`collection`,params:{locale:Lt}},{id:`byId`,path:`/:entity/:id`,data:`object`,entityKind:`collection`,params:{locale:Lt,fields:Rt,populate:zt}},{id:`bySlug`,path:`/:entity/slug/:slug`,data:`object`,entityKind:`collection`,params:{locale:Lt,fields:Rt,populate:zt}}];return r&&o.push({id:`resolve`,path:`/_resolve`,data:`object`,params:{path:{type:`string`,required:!0,maxLength:st},locale:{type:`string`,required:!0}}},{id:`paths`,path:`/_paths`,data:`array`,params:{locale:{type:`string`,required:!0},entity:{type:`string`,required:!0,maxLength:100},cursor:{type:`string`},limit:{type:`number`,min:1,max:t,default:Math.min(20,t)}},meta:{limit:{type:`number`},hasMore:{type:`boolean`},nextCursor:{type:`string`,optional:!0}}},{id:`alternates`,path:`/_alternates`,data:`array`,params:{entity:{type:`string`,required:!0,maxLength:100},id:{type:`string`,required:!0}}}),o.push({id:`site`,path:`/_site`,data:`object`,params:{}}),i&&o.push({id:`menu`,path:`/_menu`,data:`object`,params:{handle:{type:`string`,required:!0,maxLength:128},locale:{type:`string`,required:!0},currentPath:{type:`string`,maxLength:st}}}),a&&o.push({id:`chrome`,path:`/_chrome`,data:`object`,params:{locale:{type:`string`,required:!0},entity:{type:`string`,maxLength:100},id:{type:`string`}}}),o}function Vt(e,t){if(!e.enabled)return null;let n=t?`${U}:{site}`:U;return{header:e.header,separator:e.separator,document:`${n}:{entity}:{id}`,collection:`${n}:{entity}`,sharedSite:t?`_`:null,maxTagLength:128,maxTagsPerResponse:128,maxHeaderBytes:Ae,uncovered:[`menuTargets`,`crossEntityPathChanges`,`mediaVariantStyles`,`outOfBandPathChanges`]}}function Ht(e){let{entities:t,checkPermission:n,version:r}=e,i={maxResolutionsPerDocument:e.maxResolutionsPerDocument,anonymousRequestsPerInstance:e.limits.anonymousTokensPerInstance,rateLimitWindowMs:e.limits.intervalMs,maxRequestsPerInstance:e.limits.maxBudgetPerInstance,maxConcurrentRequests:e.limits.maxConcurrentRequests,requestTimeoutMs:e.limits.requestTimeoutMs},a=t.filter(e=>n(e.name)),o=new Set(a.map(e=>e.name)),s=e=>o.has(e);return{version:r,surface:Bt(e),envelopes:{dataKey:`data`,metaKey:`meta`,errorKey:`error`,errorCodes:Ot},limits:i,projections:Pt,cacheTags:Vt(e.cacheTags,e.siteScopedTags===!0),entities:a.map(e=>It(e,s))}}const Ut=`public`,Wt=new Set;function Gt(e){return typeof e==`string`&&e!==``}function Kt(e){return Array.isArray(e)}const qt=/^[A-Za-z0-9!#$%&'*+.^_`|~-]+$/;function Jt(e){let t=e.credentialHeaders;if(t!==void 0){if(!Kt(t))throw Error(`content-api: \`credentialHeaders\` must be an array of HTTP header names, received ${JSON.stringify(t)}.`);for(let e of t)if(!Gt(e)||e===`*`||!qt.test(e))throw Error(`content-api: \`credentialHeaders\` entry ${JSON.stringify(e)} is not a valid HTTP header name. Each entry is emitted verbatim in \`Vary\`, so it must be a bare field-name token (\`Cookie\`, \`Authorization\`, \`X-Preview-Token\`). \`*\` is refused: it means "never reuse this response", which is \`Cache-Control: no-store\` spelled obscurely — omit the option instead, which fails closed to exactly that.`)}if(!e.authenticate){if(t!==void 0&&t.length>0)throw Error("content-api: `credentialHeaders` was declared without an `authenticate` hook. This package parses no credential itself, so nothing reads those headers and listing them in `Vary` can only fragment a shared cache. Remove the option, or wire the `authenticate` hook it describes.");return{kind:`none`}}return t===void 0||t.length===0?{kind:`undeclared`}:{kind:`declared`,headers:t}}const Yt=F.object({path:F.string().min(1).max(st),locale:F.string().regex(h)}).strict(),Xt=F.object({locale:F.string().regex(h),entity:F.string().min(1).max(100),cursor:F.string().refine(e=>gt(e),`Invalid cursor`).optional(),limit:F.coerce.number().int().min(1).max(100).default(20)}).strict(),Zt=F.object({entity:F.string().min(1).max(100),id:F.string().refine(e=>gt(e),`Invalid id`)}).strict(),Qt=[`header`,`footer`],$t=F.object({locale:F.string().regex(h),entity:F.string().min(1).max(100).optional(),id:F.string().refine(e=>gt(e),`Invalid id`).optional()}).strict().refine(e=>e.entity===void 0==(e.id===void 0),`Both ?entity= and ?id= are required to name a document, or neither.`),en=F.object({}).strict();function tn(e){return e instanceof n||e instanceof Error&&e.name===`SiteRequiredError`}const nn=F.object({handle:F.string().min(1).max(128),locale:F.string().regex(h),currentPath:F.string().min(1).max(st).optional()}).strict(),rn=new Set([`_schema`,`_site`,`_resolve`,`_paths`,`_alternates`,`_menu`,`_chrome`]),an=`v1`,on=/^v\d+$/;function sn(e){let t=new Map;for(let n of e){let e=`${n.name}s`;if(rn.has(n.name)||rn.has(e))throw Error(`@murumets-ee/content-api: entity name "${n.name}" collides with a reserved route segment (${[...rn].join(`, `)}). Rename the entity — its API surface would otherwise be permanently unreachable, shadowed by the special dispatch that runs before entity-whitelist resolution.`);if(on.test(n.name)||on.test(e))throw Error(`@murumets-ee/content-api: entity name "${n.name}" is a reserved API-version segment. Every route is served under a version prefix (this instance mounts /v1/), and the prefix is matched as a PATTERN ("v" followed by digits) so that a future /v2/ can never be shadowed by an entity added in the meantime. Rename the entity.`);if(n.scope!==void 0&&n.scope!==`global`)throw Error(`@murumets-ee/content-api: entity "${n.name}" declares scope "${n.scope}", which this surface cannot serve. The public read path resolves no scope for a caller, so QueryClient would apply NO scope filter and return every tenant's rows to every caller. Remove it from the content-api whitelist, or serve it through a surface that establishes a scope in the request context.`);t.set(n.name,n),t.set(e,n)}return t}function cn(e,n){let r=e[t];if(!r)throw Error(`site-bound '${n}' translations have no ${t} column`);return r}function ln(e){let t=k.get(e);if(t)return{table:t,cols:re(t)}}function un(e,t,n){let r=u(e);if(!r)return;let i=t.trim();if(i.length===0)return;let o=ln(e.name);if(!o)return;let{cols:s}=o,l=[],d=`%${_(i)}%`,f=e.allFields,p=r.fields.filter(e=>!J(e,f[e])),m=r.fts?.fields.some(e=>J(e,f[e]))??!1,h=Wt;if(r.fts&&!m){let e=s._search_tsv;if(e){let t=r.fts.language??`simple`;l.push(P`${e} @@ websearch_to_tsquery(${t}, ${i})`),h=new Set(r.fts.fields)}}for(let e of p){if(h.has(e))continue;let t=s[e];t&&l.push(ae(t,d))}let g=c(e.allFields,p),v=s.id;if(n!==void 0&&g.length>0&&v){let t=k.get(`${e.name}_translations`);if(t){let e=a({idColumn:v,translationsTable:t,fields:g,locale:n,buildCondition:e=>ae(e,d)});e&&l.push(e)}}if(l.length===0)return;let y=l[0];if(y)return l.length===1?y:se(y,...l.slice(1))}function dn(e,t,n){let r=e.name;if(!t)return{orderBy:void 0};let i=t.startsWith(`-`),a=i?t.slice(1):t,o={orderBy:void 0,dropped:t};if(!Object.hasOwn(n,a))return o;let s=n[a];if(!s||s.type===`blockTree`||J(a,s)&&!f(e,a))return o;let c=ln(r);if(!c)return o;let l=c.cols[a];return l?{orderBy:i?j(l):ne(l),field:a}:o}function fn(e,t,n){let r=[],i=[],a=ln(e);if(!a)return{conditions:r,dropped:i};let{cols:o}=a;for(let[e,a]of t.searchParams.entries()){let t=e.match(dt);if(!t)continue;let s=t[1];if(s===void 0)continue;if(!Object.hasOwn(n,s)){i.push(s);continue}let c=n[s];if(!c||c.type===`blockTree`){i.push(s);continue}if(J(s,c)){i.push(s);continue}let l=o[s];if(!l){i.push(s);continue}let u=_t(c,a);if(u===null){i.push(s);continue}if(c.type===`date`&&typeof u==`string`){if(u.startsWith(`gte:`)){r.push(ie(l,u.slice(4)));continue}if(u.startsWith(`lte:`)){r.push(N(l,u.slice(4)));continue}}r.push(M(l,u))}return{conditions:r,dropped:i}}function pn(e,t,n,r,i=!0){if(!(!i||t<=n))return X(`?${e}=${t} exceeds the maximum of ${n}.${e===`offset`?` Use ?cursor= for deep pagination.`:``}`,`VALIDATION_ERROR`,400,r)}function mn(e,t,n){return n?e:Math.min(e,t)}function hn(e,t,{allowZero:n=!1}={}){if(t===void 0)return;let r=+!n;if(!Number.isInteger(t)||t<r)throw Error(`content-api: \`${e}\` must be an integer >= ${r}, received ${String(t)}. A ceiling below that does not tighten the bound, it removes it: the limit reaches the query layer falsy, no LIMIT clause is emitted, and the whole table is returned on a public route. If this came from an environment variable, it is probably unset.`)}function Q(e){return e.length<=256?e:`${e.slice(0,256)}…[truncated]`}const gn=new WeakMap,_n=new WeakMap;function vn(e){if(e.requestId)try{gn.set(e,v().logger.child({requestId:e.requestId,...e.user?.id!==void 0&&{principalId:e.user.id}}))}catch{}}async function yn(e,t){let n=y();if(!n)return{locales:[]};let r=e??await T(n).catch(()=>void 0);if(r===void 0)return{locales:[]};let i=await C(n,r);if(!i)return{locales:[]};let a=e=>e!==void 0&&(i.locales.length===0||i.locales.includes(e)),o=n.config.sites?.multiple===!0?i.defaultLocale:void 0,s=a(o)?o:a(t)?t:i.locales[0];return{locales:i.locales,...s!==void 0&&{defaultLocale:s}}}function $(){let e=b();return(e?gn.get(e):void 0)??v().logger}function bn(t){let{entities:n,defaultLocale:r,publicRole:i=`public`,cors:a,cache:c,onError:l,resolution:u,menus:h,chrome:_,site:D}=t,k=new Map;for(let[e,n]of Object.entries(t.siteForHost??{})){if(!m(n))throw Error(`content-api: \`siteForHost['${e}']\` is ${JSON.stringify(n)}, which is not a site handle.`);k.set(e.trim().toLowerCase(),n)}function ne(e){if(!e.multiSite)return;let t=y()?.entities;return n=>{let r=t?.get(n);return r!==void 0&&!d(r)?`_`:e.site??`_`}}let j=()=>{let e=b();return(e?_n.get(e):void 0)??r};hn(`maxLimit`,t.maxLimit),hn(`maxOffset`,t.maxOffset,{allowZero:!0}),Ge(c);let re=Re(c?.tags);if(!Gt(i))throw Error(`content-api: \`publicRole\` must be a non-empty string, received ${JSON.stringify(i)}. An empty public role matches no permission yet is not the anonymous role either, so every unauthenticated request reaches the read path with no groups and fails as a 500. If this came from an environment variable, it is probably unset — omit the option to get "public".`);let ie=Math.min(t.maxLimit??100,100),ae=Math.min(t.maxOffset??1e3,1e3),N=Jt(t),P=new it(t.limits),F=sn(n);if(Object.hasOwn(t,`exposeInternalFields`))throw Error("content-api: `exposeInternalFields` has been removed (plan/api D024). Its only sanctioned use was publishing `_overrides`, which D011 replaced by composing site chrome SERVER-side — so the field no longer needs to reach the wire, and no other internal field was ever safe to list (`_workflowStatus` and `_workflowAssignee` describe an editorial process and name a user; `_version`/`_versionedAt` expose revision cadence). Fetch composed chrome from `GET /_chrome` instead. Remove the option: it is refused rather than ignored, because silently dropping a field you configured is exactly the failure this package throws at construction to prevent.");let ce=new Set(h?.handles??[]),I=fe(t.maxResolutionsPerDocument),le=new e(5e3),L=null,ue=0;async function pe(){let e=Date.now();return(!L||e-ue>3e4)&&(L=await t.loadPermissions(),ue=e),L}function me(){L=null,ue=0}function he(){return{id:Ut,role:i,hasIdentity:!1}}function ge(e){try{$().warn({err:e},"content-api: `authenticate` hook threw — serving the anonymous principal")}catch{console.warn("[content-api] `authenticate` hook threw:",e)}}async function R(e){if(!t.authenticate)return he();let n;try{n=await t.authenticate(e)}catch(e){return ge(e),he()}if(!n||!Gt(n.role)||n.id!==void 0&&!Gt(n.id)||n.name!==void 0&&typeof n.name!=`string`||n.email!==void 0&&typeof n.email!=`string`||n.site!==void 0&&!(typeof n.site==`string`&&m(n.site)))return he();let r=n.rateBudgetPerInstance!==void 0&&Number.isSafeInteger(n.rateBudgetPerInstance)&&n.rateBudgetPerInstance>=1;return{id:n.id??Ut,hasIdentity:n.id!==void 0,role:n.role,...n.name!==void 0&&{name:n.name},...n.email!==void 0&&{email:n.email},...r&&{rateBudgetPerInstance:n.rateBudgetPerInstance},...n.site!==void 0&&{site:n.site}}}function _e(e){if(k.size===0)return;let t=(e.headers.get(`host`)??new URL(e.url).host).trim().toLowerCase();return k.get(t)}async function ve(e,t){let n=x();if(t.site!==void 0&&n!==void 0&&n!==t.site)return G({credentialSite:t.site,mountSite:n},`content-api: a credential bound to one site was presented to a mount running as another`),null;let r=t.site??n??_e(e),i=y();if(!i)return{...r!==void 0&&{site:r},multiSite:!1};let a=i.config.sites?.multiple===!0,o=r??await T(i).catch(()=>void 0);if(o===void 0)return{multiSite:a};let s=await C(i,o);return r!==void 0&&(s===void 0||s.status!==`active`)?null:{...r!==void 0&&{site:r},...s!==void 0&&{record:s},multiSite:a}}async function ye(e){let t=y(),n=t?.config.sites?.multiple===!0;if(!t||!n)return a;if(!e.headers.has(`Origin`))return a??{allowedOrigins:[]};try{let e=await S(t);return e.truncated&&Je(`site-origin-index-truncated`,{listed:e.byOrigin.size},`content-api: the site registry holds more active sites than the origin index reads — some sites’ CORS preflights will be refused`),{allowedOrigins:[...new Set([...a?.allowedOrigins??[],...e.byOrigin.keys()])],...a?.maxAge!==void 0&&{maxAge:a.maxAge}}}catch(e){return G({err:e},`content-api: could not read site origins for CORS`),a}}function z(e){return e.hasIdentity||e.role!==i?`identified`:e.site===void 0?`anonymous`:`site-keyed`}function B(e,t,n){return e(t,n,`view`)}function xe(e){let t=v();return new A({entity:e,db:t.db.readOnly,logger:$().child({entity:e.name}),countCache:le,contextResolver:()=>{let e=b();if(!(!e?.user||!e?.checker))return{user:e.user,checker:e.checker,...e.scope!==void 0&&{scope:e.scope},...ee(e,t)}}})}function Se(e,n,i,a){let o={budget:de(I),cacheTags:a,resolveMedia:t.resolveMedia,resolveBlocks:t.resolveBlocks,afterExpand:async(e,t)=>{if(p(e)){for(let n of t)await Ee(e,n,De(o),!1);return}await xt(e,t,o),await we(e,t,o)},locale:i,reachableEntity:t=>{let r=F.get(t);if(!(!r||r.name!==t))return B(e,n,r.name)?r:void 0},canReadEntity:t=>{let r=F.get(t);return r!==void 0&&r.name===t&&B(e,n,t)},collectionAllowance:be(12),templateDrawnTitle:async(e,n)=>{let s=t.detailTemplates,c=i??r;if(!s||c===void 0)return null;try{let t=await s.publicRow({entity:e.name,row:n,locale:c}),r=typeof t.title==`string`?t.title.trim():``;return r===``?null:r.slice(0,2e3)}catch(t){return o.logger?.warn({entity:e.name,err:t},`content-api: detail-template provider failed to project a reference title`),a.markUncacheable(),null}},readRowsByIds:async(e,t,n)=>{let a=ln(e.name)?.cols.id;return!a||t.length===0||I===0?[]:await xe(e).findMany({where:oe(a,[...t]),limit:Math.min(t.length,I),...n!==void 0&&{select:[...n]},...i!==void 0&&{locale:i},defaultLocale:r})},resolveEntityHref:t.resolveEntityHref,logger:V()};return o}function V(){try{return $()}catch{return}}function H(e,t,n){let r=e.collectionAllowance?.refusedCount()??0;if(r>0)try{$().warn({entity:t,path:Q(n),cap:12,refused:r},`content-api: per-response collection cap reached — the collection blocks past it rendered empty`)}catch{console.warn(`[content-api] collection cap reached for`,t,Q(n))}if(e.budget.hasDrops)try{$().warn({entity:t,path:Q(n),ceiling:e.budget.ceiling,resolved:e.budget.granted,dropped:e.budget.dropSummary()},`content-api: per-document resolution budget exhausted — response rendered with unresolved targets`)}catch{console.warn(`[content-api] resolution budget exhausted for`,t,Q(n))}}function Te(e,t,n,r){let i=yt(e,n);return i.requested>5?{response:X(`?populate= names ${i.requested} fields, which exceeds the maximum of 5.`,`VALIDATION_ERROR`,400,r)}:(i.dropped.length>0&&V()?.debug({entity:t.name,droppedPopulate:i.dropped},`content-api: rejected ?populate= fields (unknown, internal, or not a reference)`),{fields:new Set(i.fields)})}function De(e){return{...e,detailTemplates:t.detailTemplates,defaultLocale:r}}async function U(e,t,n,r,i){await Tt(e,t,n,r),await xt(e,t,r),await we(e,t,r),H(r,e.name,i)}async function Oe(e,t,n,i,a,l){let u=new URL(e.url),d=ct.safeParse(q(u,{allowFilters:!0}));if(!d.success)return X(`Invalid query parameters`,`VALIDATION_ERROR`,400,a);let{limit:p,offset:m,sort:h,locale:g,fields:_,search:v,cursor:y,populate:b}=d.data,x=u.searchParams.has(`limit`),S=pn(`limit`,p,ie,a,x);if(S)return S;let C=pn(`offset`,m,ae,a);if(C)return C;let w=mn(p,ie,x),T=t.allFields,E=Te(b,t,T,a);if(`response`in E)return E.response;let D;if(y){let e=o(y);if(!e)return X(`Invalid cursor`,`VALIDATION_ERROR`,400,a);if(!Object.hasOwn(T,e.field)&&e.field!==`id`||e.field!==`id`&&J(e.field,T[e.field]))return X(`Invalid cursor field`,`VALIDATION_ERROR`,400,a);D=e}let O=[],ee=!1;if(v){let e=un(t,v,g??j());e&&(O.push(e),ee=!0)}let k=fn(t.name,u,T);O.push(...k.conditions);let A=dn(t,h,T),ne=A.orderBy;if(D!==void 0&&A.field!==void 0&&f(t,A.field))return X(`Invalid cursor for this sort`,`VALIDATION_ERROR`,400,a);let M=vt(_,T);if(k.dropped.length>0||A.dropped!==void 0){let e=[...new Set(k.dropped)],n=e.slice(0,20).map(Q);$().info({entity:t.name,...k.dropped.length>0&&{droppedFilters:n,...e.length>n.length&&{droppedFiltersOmitted:e.length-n.length}},...A.dropped!==void 0&&{droppedSort:Q(A.dropped)}},`content-api: rejected query params (unknown, internal, or invalid)`)}let re=xe(t),oe=g??j(),se=ee,P={where:O.length>0?te(...O):void 0,limit:se?w+1:w,offset:m,orderBy:ne,select:M,locale:oe,defaultLocale:r,cursor:D},[F,ce]=await Promise.all([re.findMany(P),se?Promise.resolve(null):re.count({where:O.length>0?te(...O):void 0,locale:oe})]),I=se&&F.length>w?F.slice(0,w):F,le=se?F.length>w:m+w<(ce??0),L;if(I.length>0&&I.length===w){let e=I[I.length-1],t=D?.field??A.field,n=D?.direction??(h?.startsWith(`-`)?`desc`:`asc`);t&&e[t]!==void 0&&(L=s(e,t,n))}l.addCollection(t.name);for(let e of I)l.addDocument(t.name,e.id);let ue=Se(i,n.role,oe,l);return await U(t,I,E.fields,ue,u.pathname),Y({data:I,meta:{total:ce,limit:w,offset:m,hasMore:le,nextCursor:L}},200,K(t.name,a,z(n),c,N,l))}async function ke(e,t,n,r,i){let a=new URL(e.url),o=ut.safeParse(q(a));if(!o.success)return X(`Invalid query parameters`,`VALIDATION_ERROR`,400,r);let s=await xe(t).count({locale:o.data.locale??j()});return i.addCollection(t.name),Y({data:{count:s}},200,K(t.name,r,z(n),c,N,i))}async function je(e,t,n,i,a,o,s){if(!gt(n))return Z(o);let l=new URL(e.url),u=lt.safeParse(q(l));if(!u.success)return X(`Invalid query parameters`,`VALIDATION_ERROR`,400,o);let{locale:d,fields:f,populate:m}=u.data,h=t.allFields,g=p(t)?void 0:vt(f,h),_=d??j(),v=Te(m,t,h,o);if(`response`in v)return v.response;let y=await xe(t).findById(n,{...g!==void 0&&{select:g},..._!==void 0&&{locale:_},defaultLocale:r});if(!y)return Z(o);s.addDocument(t.name,n);let b=Se(a,i.role,_,s);return p(t)?(await Ee(t,y,De(b),!0),H(b,t.name,l.pathname)):await U(t,[y],v.fields,b,l.pathname),Y({data:y},200,K(t.name,o,z(i),c,N,s))}async function Me(e,t,n,i,a,o,s){let l=new URL(e.url),u=lt.safeParse(q(l));if(!u.success)return X(`Invalid query parameters`,`VALIDATION_ERROR`,400,o);let d=t.allFields;if(!d.slug)return Z(o);let{locale:f,fields:p,populate:m}=u.data,h=vt(p,d),g=f??j(),_=Te(m,t,d,o);if(`response`in _)return _.response;let y=ln(t.name);if(!y)return Z(o);let b=y.cols.slug,x=y.cols.id;if(!b||!x)return Z(o);let S=xe(t),C=d.slug,T=M(b,n);if(C.translatable&&g){let e=ln(`${t.name}_translations`);if(e){let r=e.cols.slug,i=e.cols.locale,a=e.cols.entityId;if(r&&i&&a){let o=v(),s=await w(t,o),c=te(M(r,n),M(i,g)),l=await o.db.readOnly.select({entityId:a}).from(e.table).where(s===void 0?c:te(c,M(cn(e.cols,t.name),s)));l.length>0&&(T=se(oe(x,l.map(e=>e.entityId)),M(b,n))??M(b,n))}}}let E=await S.findMany({where:T,limit:1,select:h,locale:g,defaultLocale:r});if(E.length===0)return Z(o);s.addCollection(t.name),s.addDocument(t.name,E[0]?.id);let D=Se(a,i.role,g,s);return await U(t,E,_.fields,D,l.pathname),Y({data:E[0]},200,K(t.name,o,z(i),c,N,s))}async function Ne(e,t,n,i,a,o){let s=new URL(e.url),l=lt.safeParse(q(s));if(!l.success)return X(`Invalid query parameters`,`VALIDATION_ERROR`,400,a);let{locale:u,fields:d,populate:f}=l.data,p=t.allFields,m=vt(d,p),h=u??j(),g=Te(f,t,p,a);if(`response`in g)return g.response;let _=(await xe(t).findMany({limit:1,select:m,locale:h,defaultLocale:r}))[0];if(!_)return Z(a);o.addCollection(t.name),o.addDocument(t.name,_.id);let v=Se(i,n.role,h,o);return await U(t,[_],g.fields,v,s.pathname),Y({data:_},200,K(t.name,a,z(n),c,N,o))}function W(e){return F.get(e)??F.get(e.endsWith(`s`)?e.slice(0,-1):e)}function Pe(e,t){if(process.env.NODE_ENV!==`development`)return;let n=JSON.stringify(e.slice(0,100)),r=t===void 0?`${n} is not in the content-api whitelist — add it to createContentApiHandler({ entities: [...] }) in your content route.`:`"${t.name}" is whitelisted but the requesting role lacks 'view' — grant it in the Permission Matrix, or seed it. Note that entity.access.view is advisory metadata the firewall never reads, so a restrictive value there is not the cause.`;console.warn(`[content-api] 404 for ${n}: ${r} (Both refusals are 404 by design — this line is the server-side disambiguation, and the response is unchanged.)`)}async function Fe(e,t,n,r,i){if(!u)return Z(r);let a=new URL(e.url),o=Yt.safeParse(q(a));if(!o.success)return X(`Invalid query parameters`,`VALIDATION_ERROR`,400,r);let{path:s,locale:l}=o.data,d=await u.resolvePath(s,l);if(d.kind===`none`)return Z(r);if(d.kind===`redirect`)return Y({data:d},200,{...r,"Cache-Control":`no-store`});let f=W(d.entityType);return!f||!B(n,t.role,f.name)?(Pe(d.entityType,f),Z(r)):(i.addCollection(f.name),i.addDocument(f.name,d.id),Y({data:d},200,K(f.name,r,z(t),c,N,i)))}async function Ie(e,t,n,r,i){if(!u)return Z(r);let a=new URL(e.url),o=Xt.safeParse(q(a));if(!o.success)return X(`Invalid query parameters`,`VALIDATION_ERROR`,400,r);let{locale:s,entity:l,cursor:d,limit:f}=o.data,p=a.searchParams.has(`limit`),m=pn(`limit`,f,ie,r,p);if(m)return m;let h=mn(f,ie,p),g=W(l);if(!g||!B(n,t.role,g.name))return Pe(l,g),Z(r);let _=u.enumeratePaths({locale:s,entityType:g.name,...d!==void 0&&{afterDocumentId:d}}),v=[];for await(let e of _)if(v.push(e),v.length===h)break;let y=v.length===h,b=y?v[v.length-1]?.id:void 0;i.addCollection(g.name);for(let e of v)i.addDocument(g.name,e.id);return Y({data:v,meta:{limit:h,hasMore:y,nextCursor:b}},200,K(g.name,r,z(t),c,N,i))}async function Le(e,t,n,r,i){if(!u)return Z(r);let a=new URL(e.url),o=Zt.safeParse(q(a));if(!o.success)return X(`Invalid query parameters`,`VALIDATION_ERROR`,400,r);let{entity:s,id:l}=o.data,d=W(s);if(!d||!B(n,t.role,d.name))return Pe(s,d),Z(r);let f=b()?.availableLocales,p=await u.getAlternates(d.name,l),m=f?p.filter(e=>f.includes(e.locale)):p;return i.addCollection(d.name),i.addDocument(d.name,l),Y({data:m},200,K(d.name,r,z(t),c,N,i))}async function ze(e,t,n,r){if(!h)return Z(n);let i=new URL(e.url),a=nn.safeParse(q(i));if(!a.success)return X(`Invalid query parameters`,`VALIDATION_ERROR`,400,n);let{handle:o,locale:s,currentPath:l}=a.data;if(!ce.has(o))return Z(n);let u=await h.getMenu(o,{locale:s,...l!==void 0&&{currentPath:l}});return u?(r.addDocument(`_menu`,o),Y({data:u},200,t.site===void 0?Ye(`_menu`,n,c,r):K(`_menu`,n,z(t),c,N,r))):Z(n)}async function Ve(e,t,n,r,i,a){if(!en.safeParse(q(new URL(e.url))).success)return X(`Invalid query parameters`,`VALIDATION_ERROR`,400,i);let o=n.record;if(!o)return Z(i);let s=await D?.getI18n(o.handle);if((s?.locales??o.locales).length===0)return Je(`site-i18n-unwired:${o.handle}`,{site:o.handle},"content-api: GET /_site cannot answer — this site serves every enabled locale and the mount wires no `site.getI18n` to say which those are. Wire it (see the content route the admin app ships), or give the site an explicit locale list."),Z(i);let l=s?.locales??o.locales,u=s?.defaultLocale??r.defaultLocale??l[0];if(u===void 0)return Z(i);let d={handle:o.handle,name:o.name,locales:l.length>0?[...l]:[u],defaultLocale:u,routingStrategy:s?.routingStrategy??o.routingStrategy??`no-prefix-default`,origins:[...o.origins]};return a.addDocument(`_site`,o.handle),Y({data:d},200,K(`_site`,i,z(t),c,N,a))}async function He(e,n,r,i,a){if(!_)return Z(i);let o=new URL(e.url),s=$t.safeParse(q(o));if(!s.success)return X(`Invalid query parameters`,`VALIDATION_ERROR`,400,i);let{locale:l,entity:u,id:d}=s.data;if(!B(r,n.role,_.entity))return Z(i);let f;if(u!==void 0&&d!==void 0){let e=W(u);e&&B(r,n.role,e.name)?f={entityType:e.name,id:d}:V()?.debug({entity:u,locale:l},`content-api: _chrome document is unreachable for this caller — serving the site default`)}a.addCollection(_.entity),f!==void 0&&a.addDocument(f.entityType,f.id);let p=Se(r,n.role,l,a),m=await _.getChrome({locale:l,...f!==void 0&&{document:f},budget:p.budget}),h=e=>e&&typeof e==`object`?{blocks:Array.isArray(e.blocks)?e.blocks:[],overridden:e.overridden===!0}:null,g=async(e,n)=>{if(n===null||!t.resolveBlocks||n.blocks.length===0)return n;let r=await Ce(t.resolveBlocks,n.blocks,{locale:l,budget:p.budget,entity:_.entity,field:e,...p.canReadEntity!==void 0&&{canReadEntity:p.canReadEntity},...p.collectionAllowance!==void 0&&{claimCollection:p.collectionAllowance.claim}});r.failure===`threw`?V()?.warn({entity:_.entity,region:e,err:r.error},`content-api: block resolver threw — this chrome region is not served as stored; it was re-resolved with an exhausted budget, so its media refs and link hrefs are stripped rather than carrying the urls recorded when an editor picked them`):r.failure===`malformed`&&V()?.warn({entity:_.entity,region:e},`content-api: block resolver returned a value that is not a ResolvedBlockTree — this chrome region is not served as stored; it was re-resolved with an exhausted budget, so its media refs and link hrefs are stripped rather than carrying the urls recorded when an editor picked them`),r.retryFailure!==void 0&&(a.markUncacheable(),V()?.warn({entity:_.entity,region:e,err:r.error},`content-api: block resolver failed TWICE, including on the in-memory retry — serving this chrome region EMPTY, so whatever it held is missing from every page render. Serving the stored region instead would put the media urls recorded when an editor picked them, which may be signed, on a cacheable anonymous response`));let i=r.envelope;if(i.refs!==void 0)for(let e of i.refs)a.addDocument(e.entity,e.id);if(i.collections!==void 0)for(let e of Object.values(i.collections))e.entity!==null&&a.addCollection(e.entity);return{blocks:[...i.blocks],overridden:n.overridden,resolved:i.resolved,links:i.links,...i.unresolved!==void 0&&i.unresolved.length>0&&{unresolved:i.unresolved},...i.refs!==void 0&&i.refs.length>0&&{refs:i.refs},...i.collections!==void 0&&{collections:i.collections},...i.live!==void 0&&{live:i.live},...i.currency!==void 0&&{currency:i.currency}}},v={};for(let e of Qt)v[e]=await g(e,h(m?.[e]));let y={header:v.header??null,footer:v.footer??null};return H(p,_.entity,o.pathname),Y({data:y},200,K(_.entity,i,z(n),c,N,a))}async function Ue(e,t){let n=E(e),r={},i=x(),a={requestId:n,...i!==void 0&&{site:i}};return vn(a),await O(a,async()=>{let i=await nt(e,t,n,r);return We(i,n),Ke(i,e,n,r),i})}function We(e,t){(e.headers.get(`Cache-Control`)??``).includes(`no-store`)&&e.headers.set(g,t)}function Ke(e,t,n,r){if(!l||e.status<400)return;let i=jt(e);if(i!==void 0)try{Promise.resolve(l({status:e.status,code:i,path:Q(new URL(t.url).pathname),...r.entity!==void 0&&{entity:r.entity},requestId:n,...r.principalId!==void 0&&{principalId:r.principalId}})).catch(tt)}catch(e){tt(e)}}let qe=new Set;function Je(e,t,n){qe.has(e)||(qe.add(e),G(t,n))}function G(e,t){try{$().warn(e,t)}catch{try{console.warn(`[content-api]`,t,e)}catch{}}}function tt(e){try{$().warn({err:e},"content-api: `onError` monitoring hook failed")}catch{}}async function nt(e,t,n,r){let i=Ze(e,await ye(e)),a=Xe(i,N);try{await P.acquire(e.signal)}catch(e){return e instanceof $e?(G({limit:`survival`,maxConcurrentRequests:P.limits.maxConcurrentRequests,maxQueuedRequests:P.limits.maxQueuedRequests},`content-api: shedding load — concurrency slots and wait queue both full`),Nt(1,a)):(G({err:e},`content-api: acquiring a concurrency slot failed`),X(`Internal server error`,`INTERNAL_ERROR`,500,a))}try{return await P.runGuarded(a=>rt(e,t,n,r,i,a))}catch(e){if(e instanceof et)return G({limit:`deadline`,requestTimeoutMs:P.limits.requestTimeoutMs},`content-api: request exceeded the wall clock`),Nt(1,a);throw e}finally{P.release()}}async function rt(e,t,i,o,s,c){let l=s;try{let d=t.path;if(!d||d.length===0||d[0]!==`v1`)return Z(s);let f=d.slice(1);if(f.length===0)return Z(s);if(new URL(e.url).searchParams.has(`site`))return X(`Invalid query parameters`,`VALIDATION_ERROR`,400,Xe(s,N));let m=await R(e),g=m.role,v=await ve(e,m);if(v===null)return Z(Xe(a?{Vary:`Origin`}:{},N));let y=v.multiSite?Ze(e,{allowedOrigins:v.record?.origins??[],...a?.maxAge!==void 0&&{maxAge:a.maxAge}}):s,b=P.consumeFairness(e,{principalId:m.hasIdentity?m.id:void 0,budgetPerInstance:m.rateBudgetPerInstance}),x=Xe(y,N);l=x;let S=Be(re,ne(v));if(b&&!b.decision.allowed)return G({limit:`fairness`,keyClass:b.keyClass},`content-api: caller exceeded its per-instance budget`),Mt(b.decision.retryAfterSeconds,x);let C=await pe();o.principalId=m.id;let w=v.site,T=await yn(w,r),E=new URL(e.url).searchParams.get(`locale`);if(E!==null&&E!==``&&T.locales.length>0&&!T.locales.includes(E))return X(`Locale '${E}' is not served by this site`,`VALIDATION_ERROR`,400,x);let D={user:{id:m.id,groups:g?[g]:[],...m.name!==void 0&&{name:m.name},...m.email!==void 0&&{email:m.email}},checker:C,requestId:i,...w!==void 0&&{site:w},...T.locales.length>0&&{availableLocales:T.locales}};T.defaultLocale!==void 0&&_n.set(D,T.defaultLocale),vn(D);let ee=await O(D,async()=>{if(c?.aborted)throw new et;if(f[0]===`_schema`)return Y(Ht({entities:n,checkPermission:e=>B(C,g,e),version:`v1`,maxLimit:ie,maxOffset:ae,maxResolutionsPerDocument:I,limits:P.limits,hasResolution:u!==void 0,hasMenus:h!==void 0,hasChrome:_!==void 0,cacheTags:re,siteScopedTags:v.multiSite}),200,{...x,"Cache-Control":`no-store`});if(f[0]===`_resolve`)return Fe(e,m,C,x,S);if(f[0]===`_paths`)return Ie(e,m,C,x,S);if(f[0]===`_alternates`)return Le(e,m,C,x,S);if(f[0]===`_menu`)return ze(e,m,x,S);if(f[0]===`_site`)return Ve(e,m,v,T,x,S);if(f[0]===`_chrome`)return He(e,m,C,x,S);let t=f[0];if(t===void 0)return Z(x);let r=W(t);if(!r||!B(C,g,r.name))return Pe(t,r),Z(x);if(o.entity=r.name,r.kind===`singleton`)return f.length===1?Ne(e,r,m,C,x,S):Z(x);if(p(r)){let t=f[1];return f.length===2&&t!==void 0?je(e,r,t,m,C,x,S):Z(x)}return f.length===1?Oe(e,r,m,C,x,S):f[1]===`count`?ke(e,r,m,x,S):f[1]===`slug`&&f[2]?Me(e,r,f[2],m,C,x,S):f.length===2&&f[1]!==void 0?je(e,r,f[1],m,C,x,S):Z(x)});return S.dropped>0&&ee.headers.has(re.header)&&G({dropped:S.dropped,emitted:S.tags.length,maxTags:128,maxHeaderBytes:Ae,...o.entity!==void 0&&{entity:o.entity},path:Q(new URL(e.url).pathname)},`content-api: cache tags refused — this response depends on documents it does not name, so a purge for them will not invalidate it`),ee}catch(t){if(t instanceof et)throw t;if(tn(t))return Z(l);let n=new URL(e.url).pathname;try{$().error({err:t,path:Q(n)},`content-api handler error`)}catch{console.error(`[content-api] handler error:`,t)}return X(`Internal server error`,`INTERNAL_ERROR`,500,l)}}return{GET:(e,t)=>Ue(e,t),OPTIONS:async e=>Qe(e,await ye(e),c),invalidatePermissionCache:me}}export{an as API_VERSION,U as CACHE_TAG_NAMESPACE,H as DETAIL_TEMPLATE_FIELD,Ot as ERROR_CODES,ke as MAX_CACHE_TAGS_PER_RESPONSE,Ae as MAX_CACHE_TAG_HEADER_BYTES,Oe as MAX_CACHE_TAG_LENGTH,ue as MAX_RESOLUTIONS_PER_DOCUMENT,je as MEDIA_TAG_ENTITY,Ne as SHARED_SITE_TAG_SEGMENT,bn as createContentApiHandler,z as isResolvedBlockTree};
1
+ import{CountCache as e,SITE_COLUMN as t,SiteRequiredError as n,blockTreeFieldsOf as r,blockTreeTemplateOf as i,buildTranslationsSearchExists as a,decodeCursor as o,encodeCursor as s,filterTranslatableFields as c,getEntityTitleField as l,getSearchableConfig as u,isSiteBound as d,isSortOnlyInternalField as f,isTemplateDrawn as p,isValidSiteHandle as m}from"@murumets-ee/entity";import{LOCALE_PATTERN as h,REQUEST_ID_HEADER as g,escapeLikePattern as _,getApp as v,getAppOrUndefined as y,getContext as b,getCurrentSite as x,readSiteOriginIndex as S,readSiteRecord as C,requireSiteFor as w,resolveImplicitSite as T,resolveRequestId as E,runBounded as D,runWithContextAsync as O,siteSecurityFields as ee}from"@murumets-ee/core";import{z as k}from"zod";import{schemaRegistry as A}from"@murumets-ee/db";import{QueryClient as te}from"@murumets-ee/entity/query";import{and as ne,asc as re,desc as ie,eq as j,getTableColumns as M,gte as N,ilike as P,inArray as ae,lte as oe,or as se,sql as F}from"drizzle-orm";import{InMemoryRateLimitStore as I,Semaphore as L,createClientIpResolver as ce,runWithDeadline as R}from"@murumets-ee/core/limits";const le=/[\u200B-\u200D\u2060\uFEFF]/g;function ue(e){return e.replace(le,``).trim()}const de=2048,fe=k.object({limit:k.coerce.number().int().min(1).max(100).default(20),offset:k.coerce.number().int().min(0).default(0),sort:k.string().regex(/^-?[a-zA-Z_]+$/).optional(),locale:k.string().regex(h).optional(),fields:k.string().optional(),search:k.string().max(200).refine(e=>{let t=ue(e);return t.length===0||t.length>=2},{message:`search must be at least 2 characters`}).optional(),cursor:k.string().max(500).optional(),populate:k.string().max(200).optional()}).strict(),pe=k.object({locale:k.string().regex(h).optional(),fields:k.string().optional(),populate:k.string().max(200).optional(),page:k.string().regex(/^(?:[1-9][0-9]?|100)$/).transform(Number).optional()}).strict(),me=k.object({locale:k.string().regex(h).optional()}).strict(),he=/^filter\[([a-zA-Z0-9_]+)\]$/;function z(e,t){let n={};for(let[r,i]of e.searchParams.entries())t?.allowFilters===!0&&he.test(r)||(n[r]=i);return n}const ge=/^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i,_e=/^\d{4}-\d{2}-\d{2}(?:[Tt ]\d{2}:\d{2}(?::\d{2}(?:\.\d+)?)?(?:[Zz]|[+-]\d{2}:?\d{2})?)?$/;function ve(e){if(!_e.test(e))return!1;let t=Date.parse(e);return Number.isNaN(t)?!1:e.length===10?new Date(t).toISOString().slice(0,10)===e:!0}function ye(e){if(e.trim()===``)return!1;let t=Number(e);return Number.isFinite(t)}function be(e){return ge.test(e)}function xe(e,t){switch(e.type){case`boolean`:return t===`true`?!0:t===`false`?!1:null;case`reference`:case`media`:return ge.test(t)?t:null;case`select`:return e.options.includes(t)?t:null;case`date`:return ve(t.startsWith(`gte:`)||t.startsWith(`lte:`)?t.slice(4):t)?t:null;case`number`:return ye(t)?Number(t):null;case`text`:return t.length<=200?t:null;default:return null}}function B(e,t){return e.startsWith(`_`)||t?.internal===!0||t?.adminOnly===!0}function Se(e,t){if(!e)return;let n=e.split(`,`).map(e=>e.trim()).filter(e=>{if(!Object.hasOwn(t,e))return!1;let n=t[e];return n!==void 0&&!B(e,n)&&n.type!==`blockTree`});return n.includes(`id`)||n.unshift(`id`),n}function Ce(e,t){if(!e)return{fields:[],dropped:[],requested:0};let n=[...new Set(e.split(`,`).map(e=>e.trim()).filter(e=>e.length>0))],r=[],i=[];for(let e of n){if(!Object.hasOwn(t,e)){i.push(e);continue}let n=t[e];if(!n||B(e,n)||n.type!==`reference`){i.push(e);continue}r.push(e)}return{fields:r,dropped:i,requested:n.length}}const we=[`reference`,`populate`,`media`,`block`],Te=200;function Ee(e){if(!Number.isInteger(e)||e<0)throw Error(`content-api: resolution budget ceiling must be a non-negative integer, received ${String(e)}.`);let t=e,n=0,r=new Map;return{claim(e,i){if(!Number.isInteger(i)||i<=0)return 0;let a=Math.min(i,t);t-=a,n+=a;let o=i-a;return o>0&&r.set(e,(r.get(e)??0)+o),a},get remaining(){return t},get granted(){return n},get hasDrops(){return r.size>0},dropSummary(){let e={};for(let t of we){let n=r.get(t);n!==void 0&&n>0&&(e[t]=n)}return e},ceiling:e}}function De(e){if(e===void 0)return 200;if(!Number.isInteger(e)||e<0)throw Error(`content-api: \`maxResolutionsPerDocument\` must be an integer >= 0, received ${String(e)}. If this came from an environment variable, it is probably unset — omit the option to get the package default (200).`);return Math.min(e,200)}const Oe=2e3;function V(e){return typeof e==`object`&&!!e&&!Array.isArray(e)}function H(e){if(!V(e))return!1;let t=e=>e===void 0||typeof e==`string`&&e.length<=Oe,n=e=>e===void 0||typeof e==`number`&&Number.isFinite(e)&&e>=0;if(!t(e.title)||!t(e.text))return!1;let r=e.price;if(r!==void 0&&(!V(r)||typeof r.amount!=`number`||!Number.isFinite(r.amount)||r.amount<0||!n(r.compareAt)||!t(r.unit)))return!1;let i=e.facts;if(i!==void 0){if(!Array.isArray(i)||i.length>12)return!1;for(let e of i)if(!V(e)||typeof e.key!=`string`||typeof e.label!=`string`||typeof e.value!=`string`&&typeof e.value!=`number`||e.format!==void 0&&e.format!==`price`)return!1}let a=e.body;if(a!==void 0){if(!V(a)||typeof a.html!=`string`||a.html.length>5e5||!Array.isArray(a.headings)||a.headings.length>100)return!1;for(let e of a.headings)if(!V(e)||typeof e.id!=`string`||typeof e.text!=`string`||e.level!==2&&e.level!==3)return!1}let o=e.embed;if(o!==void 0&&(!V(o)||typeof o.provider!=`string`||typeof o.reference!=`string`))return!1;let s=e.breadcrumbs;if(s!==void 0){if(!Array.isArray(s)||s.length>8)return!1;for(let e of s){if(!V(e)||typeof e.label!=`string`||e.label.length>Oe)return!1;if(e.href!==void 0){if(typeof e.href!=`string`||e.href.length>1e3||!e.href.startsWith(`/`)||e.href.startsWith(`//`))return!1;for(let t of e.href){let e=t.codePointAt(0)??0;if(e<=32||e===127||t===`\\`)return!1}}}}return!0}const U=new Set([`price`,`number`,`text`]);function W(e){if(typeof e!=`object`||!e||Array.isArray(e))return!1;let t=e;return G(t.name)&&G(t.label)&&U.has(t.format)&&(t.unit===void 0||G(t.unit))}function G(e){if(typeof e!=`string`||e.length>1200)return!1;for(let t=0;t<e.length;t++)if(e.charCodeAt(t)<32)return!1;return!0}function ke(e){if(typeof e!=`object`||!e||Array.isArray(e))return!1;let{sources:t,values:n}=e;if(typeof t!=`object`||!t||Array.isArray(t)||typeof n!=`object`||!n||Array.isArray(n))return!1;let r=Object.entries(t);if(r.length>32)return!1;for(let[,e]of r){if(typeof e!=`object`||!e||Array.isArray(e))return!1;let t=e;if(typeof t.label!=`string`||t.labelKey!==void 0&&typeof t.labelKey!=`string`||t.kind!==void 0&&t.kind!==`price`&&t.kind!==`text`&&t.kind!==`list`&&t.kind!==`facts`||t.facts!==void 0&&(!Array.isArray(t.facts)||t.facts.length>48||!t.facts.every(W))||t.fields!==void 0&&(!Array.isArray(t.fields)||t.fields.length>64||!t.fields.every(e=>typeof e==`string`)))return!1}let i=Object.entries(n);if(i.length>32)return!1;for(let[,e]of i){if(typeof e!=`object`||!e||Array.isArray(e))return!1;let t=Object.entries(e);if(t.length>200)return!1;for(let[,e]of t){if(typeof e!=`object`||!e||Array.isArray(e))return!1;let t=e;if(t.amount!==void 0&&(typeof t.amount!=`number`||!Number.isFinite(t.amount))||t.compareAt!==void 0&&(typeof t.compareAt!=`number`||!Number.isFinite(t.compareAt))||t.unit!==void 0&&typeof t.unit!=`string`||t.text!==void 0&&!G(t.text)||t.items!==void 0&&(!Array.isArray(t.items)||t.items.length>100||!t.items.every(G)))return!1;if(t.facts!==void 0){if(typeof t.facts!=`object`||t.facts===null||Array.isArray(t.facts))return!1;let e=Object.entries(t.facts);if(e.length>48)return!1;for(let[,t]of e)if(!(typeof t==`number`&&Number.isFinite(t)||G(t)))return!1}}}return!0}const Ae=new Set([`ok`,`unset`,`unavailable`,`over-budget`,`needs-document`]);function je(e){if(typeof e!=`object`||!e||Array.isArray(e))return!1;let t=e;if(typeof t.status!=`string`||!Ae.has(t.status)||t.entity!==null&&(typeof t.entity!=`string`||t.entity===``)||!Array.isArray(t.rows)||t.rows.length>100)return!1;if(t.page!==void 0){if(typeof t.page!=`object`||t.page===null||Array.isArray(t.page))return!1;let e=t.page;if(typeof e.number!=`number`||!Number.isInteger(e.number)||e.number<1||e.number>100||typeof e.hasNext!=`boolean`)return!1}if(t.status===`ok`&&t.entity===null||t.status!==`ok`&&t.rows.length>0||(t.status===`unset`||t.status===`unavailable`)&&t.entity!==null)return!1;for(let e of t.rows){if(typeof e!=`object`||!e||Array.isArray(e))return!1;let t=e;if(typeof t.id!=`string`||t.id===``)return!1;for(let e of[t.title,t.text,t.href])if(e!==null&&typeof e!=`string`)return!1;if(t.image!==null){if(typeof t.image!=`object`||Array.isArray(t.image))return!1;let e=t.image;if(typeof e.url!=`string`||e.alt!==null&&typeof e.alt!=`string`)return!1;for(let t of[e.width,e.height])if(t!==null&&typeof t!=`number`)return!1}}return!0}function Me(e){if(!Number.isInteger(e)||e<0)throw Error(`content-api: collection allowance must be a non-negative integer, received ${String(e)}.`);let t=e,n=0;return{claim:()=>t===0?(n+=1,!1):(--t,!0),refusedCount:()=>n}}function Ne(e){if(typeof e!=`object`||!e||Array.isArray(e))return!1;let t=e;if(t.resolved!==1||!Array.isArray(t.blocks))return!1;let n=t.links;if(typeof n!=`object`||!n||Array.isArray(n))return!1;for(let e of Object.values(n))if(e!==null&&typeof e!=`string`)return!1;let r=new Set,i=t.refs;if(i!==void 0){if(!Array.isArray(i))return!1;for(let e of i){if(typeof e!=`object`||!e||Array.isArray(e))return!1;let t=e;if(typeof t.entity!=`string`||t.entity===``||typeof t.id!=`string`||t.id===``)return!1;r.add(`${t.entity}\u0000${t.id}`)}}let a=t.collections;if(a!==void 0){if(typeof a!=`object`||!a||Array.isArray(a))return!1;let e=Object.entries(a);if(e.length>64)return!1;for(let[t,n]of e){if(t===``||!je(n))return!1;if(!(n.status!==`ok`||n.entity===null)){for(let e of n.rows)if(!r.has(`${n.entity}\u0000${e.id}`))return!1}}}let o=t.unresolved;if(o!==void 0){if(!Array.isArray(o))return!1;for(let e of o)if(!Pe(e))return!1}return!(t.live!==void 0&&!ke(t.live)||t.currency!==void 0&&typeof t.currency!=`string`||t.detail!==void 0&&!H(t.detail))}function Pe(e){if(typeof e!=`object`||!e||Array.isArray(e))return!1;let t=e;return t.kind!==`media`&&t.kind!==`link`||typeof t.ref!=`string`?!1:t.reason===`unresolvable`||t.reason===`budget`}function Fe(e){return r(e).filter(e=>!e.internal).map(e=>e.name)}const Ie=Object.freeze({resolved:1,blocks:Object.freeze([]),links:Object.freeze({})});async function Le(e,t,n){try{let r=await e(t,n.boundValues===void 0?n:{...n,boundValues:structuredClone(n.boundValues)});return Ne(r)?{ok:!0,envelope:r}:{ok:!1,failure:`malformed`}}catch(e){return{ok:!1,failure:`threw`,error:e}}}async function Re(e,t,n){let r=await Le(e,t,n);if(r.ok)return{envelope:r.envelope};let i=await Le(e,t,{...n,budget:Ee(0),claimCollection:void 0});return i.ok?{envelope:i.envelope,failure:r.failure,error:r.error}:{envelope:Ie,failure:r.failure,retryFailure:i.failure,error:r.error??i.error}}async function ze(e,t,n){if(t.length===0)return;let r=n.resolveBlocks;if(!r)return;let a=Fe(e);if(a.length===0)return;let o=0,s=0,c=0,l,u,d=new Set,f=new Set,p=new Set;for(let m of t)for(let t of a){let a=m[t],h=i(e,t);if(h!==void 0&&!Object.hasOwn(m,t)||h===void 0&&a==null)continue;let g=await Re(r,h===void 0?a:[],{locale:n.locale,budget:n.budget,entity:e.name,field:t,...h!==void 0&&{template:h},boundValues:{...m},...n.canReadEntity!==void 0&&{canReadEntity:n.canReadEntity},...n.collectionAllowance!==void 0&&{claimCollection:n.collectionAllowance.claim},...n.page!==void 0&&{page:n.page}});if(g.failure===`threw`?(o+=1,d.add(t),l??=g.error):g.failure===`malformed`&&(s+=1,f.add(t)),g.retryFailure!==void 0&&(c+=1,p.add(t),u??=g.error,n.cacheTags?.markUncacheable()),m[t]=g.envelope,g.envelope.refs!==void 0)for(let e of g.envelope.refs)n.cacheTags?.addDocument(e.entity,e.id);if(g.envelope.collections!==void 0)for(let e of Object.values(g.envelope.collections))e.entity!==null&&n.cacheTags?.addCollection(e.entity)}o>0&&n.logger?.warn({entity:e.name,fields:[...d],rows:t.length,failures:o,err:l},`content-api: block resolver threw — no tree is served as stored; each was re-resolved with an exhausted budget, so its media refs and link hrefs are stripped rather than carrying the urls recorded when an editor picked them. Fields that failed that retry as well are reported separately, as empty.`),s>0&&n.logger?.warn({entity:e.name,fields:[...f],rows:t.length,failures:s},`content-api: block resolver returned a value that is not a ResolvedBlockTree — no tree is served as stored; each was re-resolved with an exhausted budget, so its media refs and link hrefs are stripped rather than carrying the urls recorded when an editor picked them. Fields that failed that retry as well are reported separately, as empty.`),c>0&&n.logger?.warn({entity:e.name,fields:[...p],rows:t.length,failures:c,err:u},`content-api: block resolver failed TWICE, including on the in-memory retry — those fields are served as an empty resolved tree, so that content is missing from the response. Serving the stored tree instead would put the media urls recorded when an editor picked them, which may be signed, on a cacheable anonymous response.`)}const Be=`lumi`,Ve=128,He=128,Ue=3072,We=`media`,Ge=/^[A-Za-z0-9_.-]+$/,Ke=`_`,qe={enabled:!0,header:`Cache-Tag`,separator:`,`},Je=/^[!#$%&'*+\-.^_`|~0-9A-Za-z]+$/,Ye=[`cache-control`,`vary`,`content-type`],Xe=[`access-control-`];function Ze(e){if(e){if(e.enabled!==void 0&&typeof e.enabled!=`boolean`)throw Error(`content-api cache: \`cache.tags.enabled\` must be a boolean, received ${JSON.stringify(e.enabled)}.`);if(e.header!==void 0){if(typeof e.header!=`string`||!Je.test(e.header))throw Error(`content-api cache: \`cache.tags.header\` must be a valid HTTP field name (RFC 9110 §5.1 token), received ${JSON.stringify(e.header)}. Common values: \`Cache-Tag\` (Cloudflare/Netlify, the default), \`Surrogate-Key\` (Fastly), \`Edge-Cache-Tag\` (Akamai).`);let t=e.header.toLowerCase();if(Ye.includes(t)||Xe.some(e=>t.startsWith(e)))throw Error(`content-api cache: \`cache.tags.header\` may not be ${JSON.stringify(e.header)} — this package writes that header itself on the same responses, so the tags would either overwrite it or be overwritten, silently and on every request.`)}if(e.separator!==void 0&&e.separator!==`,`&&e.separator!==` `)throw Error(`content-api cache: \`cache.tags.separator\` must be ',' or ' ', received ${JSON.stringify(e.separator)}. Cloudflare and Akamai parse comma-separated tags; Fastly parses space-separated ones. A third separator would not error at the CDN — it would parse as one giant unmatched key, which is the silent failure this refuses.`)}}function Qe(e){return{enabled:e?.enabled??qe.enabled,header:e?.header??qe.header,separator:e?.separator??qe.separator}}function $e(e){return typeof e==`string`&&e!==``&&Ge.test(e)}function et(e,t){function n(e){if(t===void 0)return Be;let n=t(e);return $e(n)?`${Be}:${n}`:void 0}let r=new Set,i=0,a=!1,o=e.header.length+4,s=!1;function c(e){if(r.has(e))return;if(e.length>128||r.size>=128){i+=1;return}let t=e.length+(r.size===0?0:1);if(s||o+t>3072){s=!0,i+=1;return}o+=t,r.add(e)}return{addDocument(e,t){if(!$e(e)||!$e(t)){i+=1;return}let r=n(e);if(r===void 0){i+=1;return}c(`${r}:${e}:${t}`)},addCollection(e){if(!$e(e)){i+=1;return}let t=n(e);if(t===void 0){i+=1;return}c(`${t}:${e}`)},get tags(){return[...r]},markUncacheable(){a=!0},get dropped(){return i},get uncacheable(){return a},headers(){return!e.enabled||r.size===0?{}:{[e.header]:[...r].join(e.separator)}}}}const tt=`_template`;function nt(e){if(typeof e!=`string`)return;let t=e.trim();return t===``?void 0:t.slice(0,2e3)}async function rt(e,t,n,r){let i={...t};for(let e of Object.keys(t))e!==`id`&&delete t[e];let a=n.detailTemplates;if(!a)return;let o=n.locale??n.defaultLocale;if(o===void 0)return;try{let n=await a.publicRow({entity:e.name,row:i,locale:o}),r=nt(n.title),s=nt(n.description);r!==void 0&&(t.title=r),s!==void 0&&(t.description=s)}catch(t){n.logger?.warn({entity:e.name,err:t},`content-api: detail-template provider failed to project a row — served with its id only`),n.cacheTags?.markUncacheable()}if(!r)return;let s=n.resolveBlocks;if(!s||(n.cacheTags?.addCollection(a.entity),n.budget.claim(`block`,1)<1))return;let c;try{c=await a.readTemplate({entity:e.name,locale:o})}catch(t){n.logger?.warn({entity:e.name,err:t},`content-api: detail-template provider failed to read the template — the row is served without one and the response is not cacheable`),n.cacheTags?.markUncacheable();return}if(c===null||typeof c.id!=`string`||!Array.isArray(c.blocks))return;n.cacheTags?.addDocument(a.entity,c.id);let l=await Re(s,c.blocks,{locale:n.locale,budget:n.budget,entity:e.name,field:tt,boundValues:i,rowIsForeign:!0,...n.canReadEntity!==void 0&&{canReadEntity:n.canReadEntity},...n.collectionAllowance!==void 0&&{claimCollection:n.collectionAllowance.claim},...n.page!==void 0&&{page:n.page}});l.failure!==void 0&&n.logger?.warn({entity:e.name,field:tt,failure:l.failure,retryFailure:l.retryFailure,err:l.error},`content-api: block resolver failed on a detail template — served re-resolved with an exhausted budget, or empty if that failed as well`),l.retryFailure!==void 0&&n.cacheTags?.markUncacheable(),it(l.envelope,n),t[tt]=l.envelope}function it(e,t){if(e.refs!==void 0)for(let n of e.refs)t.cacheTags?.addDocument(n.entity,n.id);if(e.collections!==void 0)for(let n of Object.values(e.collections))n.entity!==null&&t.cacheTags?.addCollection(n.entity)}function at(e){let t=Math.ceil(e/6);return{maxAge:t,swr:e-t}}const K=[`defaultMaxAge`,`defaultStaleWhileRevalidate`,`maxAge`,`staleWhileRevalidate`];function ot(e,t){if(e!==void 0&&(typeof e!=`number`||!Number.isInteger(e)||e<0))throw Error(`content-api cache: \`${t}.maxStaleSeconds\` must be a non-negative integer, received ${JSON.stringify(e)}. Use 0 for \`no-store\` if you need a published edit visible on the very next request.`)}function st(e,t){for(let n of K)if(n in e)throw Error(`content-api cache: \`${t}.${n}\` was removed (D036). Use \`maxStaleSeconds\` — ONE number naming the TOTAL staleness window in seconds. The old pair's real window was their SUM and nothing said so, which is the defect D036 exists to close: \`defaultMaxAge: 10\` bought a 310-second window, not a 10-second one. The max-age / stale-while-revalidate split is now derived, so what is emitted always sums to what you declared.`)}function ct(e){if(e){st(e,`cache`),ot(e.maxStaleSeconds,`cache`),Ze(e.tags);for(let[t,n]of Object.entries(e.entities??{})){if(!n)continue;let e=`cache.entities.${t}`;st(n,e),ot(n.maxStaleSeconds,e)}}}function lt(e,t){let n=t?.entities?.[e];return n?.cacheable===!1?0:n?.maxStaleSeconds??t?.maxStaleSeconds??360}function ut(e,t){let n=lt(e,t);if(n===0)return{"Cache-Control":`no-store`};let{maxAge:r,swr:i}=at(n);return{"Cache-Control":`public, max-age=${r}, stale-while-revalidate=${i}`}}const dt=[`Origin`];function ft(e,t){let n=new Set,r=[];for(let i of[...e?.split(`,`)??[],...dt,...t]){let e=i.trim();if(e===``)continue;let t=e.toLowerCase();n.has(t)||(n.add(t),r.push(e))}return r.join(`, `)}function q(e,t,n,r,i,a){let o=(n!==`identified`&&i.kind!==`undeclared`&&a?.uncacheable!==!0?ut(e,r):{"Cache-Control":`no-store`})[`Cache-Control`]??`no-store`,s={"Cache-Control":n===`site-keyed`?o.replace(/^public\b/,`private`):o};return{...t,...s,...s[`Cache-Control`]===`no-store`?{}:a?.headers(),Vary:ft(t.Vary,i.kind===`declared`?i.headers:[])}}function pt(e,t,n,r){let i=r?.uncacheable===!0?{"Cache-Control":`no-store`}:ut(e,n);return{...t,...i,...i[`Cache-Control`]===`no-store`?{}:r?.headers(),Vary:ft(void 0,[])}}function mt(e,t){return{...e,Vary:ft(e.Vary,t.kind===`declared`?t.headers:[])}}function ht(e,t){if(!t)return{};let n=e.headers.get(`Origin`);return n!==null&&t.allowedOrigins.includes(n)?{"Access-Control-Allow-Origin":n,"Access-Control-Allow-Methods":`GET, OPTIONS`,"Access-Control-Allow-Headers":`Content-Type, Accept, Authorization`,"Access-Control-Max-Age":String(t.maxAge??3600),Vary:`Origin`}:{Vary:`Origin`}}function gt(e,t,n){let r={...ht(e,t),...ut(`_preflight`,n)};return new Response(null,{status:204,headers:r})}var _t=class extends Error{constructor(){super(`Service overloaded`),this.name=`ServiceOverloadedError`}},vt=class extends Error{constructor(){super(`Request deadline exceeded`),this.name=`RequestDeadlineError`}};function yt(e,t,n){if(e===void 0)return t;if(!Number.isInteger(e)||e<0)throw Error(`content-api limits: \`${n}\` must be a non-negative integer (got ${e})`);return e}function bt(e,t,n){if(e===void 0)return t;if(!Number.isInteger(e)||e<1)throw Error(`content-api limits: \`${n}\` must be a positive integer (got ${e})`);return e}function xt(e){return{maxConcurrentRequests:bt(e?.maxConcurrentRequests,64,`maxConcurrentRequests`),maxQueuedRequests:yt(e?.maxQueuedRequests,128,`maxQueuedRequests`),requestTimeoutMs:bt(e?.requestTimeoutMs,1e4,`requestTimeoutMs`),anonymousTokensPerInstance:bt(e?.anonymousTokensPerInstance,120,`anonymousTokensPerInstance`),intervalMs:bt(e?.intervalMs,6e4,`intervalMs`),maxBudgetPerInstance:bt(e?.maxBudgetPerInstance,6e3,`maxBudgetPerInstance`)}}var St=class{semaphore;store;limits;getClientIp;constructor(e){this.getClientIp=e?.getClientIp,this.limits=xt(e),this.semaphore=new L(this.limits.maxConcurrentRequests,this.limits.maxQueuedRequests),this.store=e?.store??new I}async acquire(e){await this.semaphore.acquire(()=>new _t,e)}release(){this.semaphore.release()}async runGuarded(e){return await R(e,this.limits.requestTimeoutMs,()=>new vt)}consumeFairness(e,t,n){let r=this.resolveKey(e,t);if(r)return{decision:this.store.consume(r.key,{tokens:this.budgetFor(t),intervalMs:this.limits.intervalMs},n),keyClass:r.keyClass}}budgetFor(e){let t=e.budgetPerInstance??this.limits.anonymousTokensPerInstance;return Math.min(t,this.limits.maxBudgetPerInstance)}resolveKey(e,t){if(t.principalId!==void 0)return{key:`principal:${t.principalId}`,keyClass:`principal`};let n=this.getClientIp?.(e);if(n!==void 0&&n!==``)return{key:`ip:${n}`,keyClass:`client-ip`}}};function Ct(e){let t=[];for(let[n,r]of Object.entries(e.allFields))r.type!==`media`||B(n,r)||t.push([n,r]);return t}async function wt(e,t,n){if(t.length===0)return;let r=Ct(e);if(r.length===0)return;let i=new Set;for(let e of t)for(let[t]of r){if(!Object.hasOwn(e,t))continue;let n=e[t];typeof n==`string`&&n!==``&&i.add(n)}let a=new Map;if(i.size>0&&n.resolveMedia){let t=[...i],r=n.budget.claim(`media`,t.length),o=t.slice(0,r);if(o.length>0)try{a=await n.resolveMedia(o,{locale:n.locale})}catch(t){n.logger?.warn({entity:e.name,err:t},"content-api: media resolver threw — media fields resolve to null (if this is a ForbiddenError, the requesting role is missing `media:view`)")}}else i.size>0&&n.logger?.debug({entity:e.name,mediaFields:r.map(([e])=>e)},"content-api: no `resolveMedia` provider wired — media fields resolve to null");for(let[e,t]of a)i.has(e)&&t?.id===e&&n.cacheTags?.addDocument(We,e);for(let e of t)for(let[t]of r){if(!Object.hasOwn(e,t))continue;let n=e[t];e[t]=typeof n==`string`?a.get(n)??null:null}}function Tt(e){let t=[];for(let[n,r]of Object.entries(e.allFields))r.type!==`reference`||B(n,r)||t.push([n,r]);return t}function Et(e){return typeof e==`string`&&e.length>0}function Dt(e,t){return t===`many`?Array.isArray(e)?e.filter(Et):[]:Et(e)?[e]:[]}async function Ot(e,t,n,r,i=0){if(t.length===0)return;let a=Tt(e);if(a.length===0)return;let o=new Map,s=[];for(let e of t)for(let[t,c]of a){if(!Object.hasOwn(e,t))continue;let a=Dt(e[t],c.cardinality),l=i===0&&n.has(t),u=r.reachableEntity(c.entity);if(!u||a.length===0){s.push({row:e,field:t,cardinality:c.cardinality,groupKey:null,ids:a});continue}let d=`${u.name}::${l?`full`:`projection`}`,f=o.get(d);f||(f={target:u,expand:l,ids:new Set},o.set(d,f));for(let e of a)f.ids.add(e);s.push({row:e,field:t,cardinality:c.cardinality,groupKey:d,ids:a})}let c=new Map;for(let[e,t]of o){let n=[...t.ids],a=r.budget.claim(t.expand?`populate`:`reference`,n.length),o=n.slice(0,a);if(o.length===0){c.set(e,new Map);continue}let s=l(t.target),u=p(t.target),d=u?r.templateDrawnTitle:void 0,f=t.expand||d!==void 0?void 0:u?[`id`]:kt([`id`,s]),m=await r.readRowsByIds(t.target,o,f),h=new Map;if(t.expand){for(let e of m){let t=e.id;Et(t)&&h.set(t,e)}await Ot(t.target,m,new Set,r,i+1),await r.afterExpand?.(t.target,m)}else{let e=await At(t.target.name,m,r);for(let[n,r]of m.entries()){let i=r.id;if(!Et(i))continue;let a=u?await d?.(t.target,r)??null:r[s];h.set(i,{id:i,entityType:t.target.name,title:typeof a==`string`?a:null,href:e[n]??null})}}for(let e of h.keys())r.cacheTags?.addDocument(t.target.name,e);c.set(e,h)}for(let e of s){let t=e.groupKey===null?void 0:c.get(e.groupKey);if(e.cardinality===`many`){e.row[e.field]=e.ids.map(e=>t?.get(e)).filter(e=>e!==void 0);continue}let n=e.ids[0];e.row[e.field]=n===void 0?null:t?.get(n)??null}}function kt(e){return[...new Set(e)]}async function At(e,t,n){let r=n.resolveEntityHref;return r?D(t,async t=>{let i=t.id;if(!Et(i))return null;try{return await r({entity:e,id:i,...n.locale!==void 0&&{locale:n.locale}})??null}catch(t){return n.logger?.debug({entity:e,id:i,err:t},`content-api: resolveEntityHref threw — reference resolves without an href`),null}}):t.map(()=>null)}const jt=[`NOT_FOUND`,`VALIDATION_ERROR`,`INTERNAL_ERROR`,`RATE_LIMITED`,`SERVICE_OVERLOADED`];function J(e,t=200,n){return new Response(JSON.stringify(e),{status:t,headers:{"Content-Type":`application/json`,...n}})}const Mt={"Cache-Control":`no-store`},Nt=new WeakMap;function Pt(e){return Nt.get(e)}function Y(e,t,n,r){let i=J({error:{status:n,message:e,code:t}},n,{...r,...Mt});return Nt.set(i,t),i}function X(e){return Y(`Not found`,`NOT_FOUND`,404,e)}function Ft(e,t){return Y(`Rate limit exceeded`,`RATE_LIMITED`,429,{...t,"Retry-After":String(e)})}function It(e,t){return Y(`Service overloaded`,`SERVICE_OVERLOADED`,503,{...t,"Retry-After":String(e)})}const Lt=20,Rt=50,zt=k.object({q:k.string().max(200).refine(e=>ue(e).length>=2,{message:`q must be at least 2 characters`}),types:k.string().max(808).optional(),limit:k.coerce.number().int().min(1).default(20),locale:k.string().regex(h).optional()}).strict();function Bt(e){return u(e)===void 0||p(e)?!1:e.kind!==`singleton`}function Vt(e,t){if(t===void 0)return[...e];let n=t.split(`,`).map(e=>e.trim()).filter(e=>e!==``);if(n.length===0)return null;for(let t of n)if(!e.includes(t))return null;return e.filter(e=>n.includes(e))}function Ht(e){for(let[t,n]of Ct(e)){let e=n.accept;if(e===void 0||e.length===0||e.some(e=>e===`*/*`||e.startsWith(`image/`)))return t}return null}function Ut(e){if(typeof e!=`object`||!e)return!1;let t=e;return typeof t.id==`string`&&typeof t.url==`string`}function Wt(e){let t=e.admin?.labelSingular;if(typeof t==`string`&&t.trim()!==``)return t.trim();let n=e.name.replace(/([a-z0-9])([A-Z])/g,`$1 $2`).replace(/[_-]+/g,` `).trim().toLowerCase();return n===``?e.name:`${n.charAt(0).toUpperCase()}${n.slice(1)}`}function Gt(e,t){if(typeof e!=`string`)return null;let n=e.replace(/\s+/g,` `).trim();return n===``?null:n.length>t?`${n.slice(0,t-1).trimEnd()}…`:n}const Kt=[`summary`,`excerpt`,`description`,`intro`,`lead`],qt=new Set([`text`]);function Jt(e,t,n){let r=null,i=e.allFields;for(let e of Kt){let n=i[e];if(!(n===void 0||!qt.has(n.type))&&(r=Gt(t[e],300),r!==null))break}let a=null,o=u(e);if(o)try{let e=o.projection({...t});r??=Gt(e.description,300),a=Gt(e.label,300)}catch{}return{title:Gt(t[n],300)??a??(typeof t.id==`string`?t.id:``),summary:r}}function Yt(e,t){let n=[];for(let r of[!0,!1]){let i=e.map(e=>e.hits.filter(e=>e.titleHit===r).map(e=>e.hit));for(let e=0;n.length<t;e++){let r=!1;for(let a of i){let i=a[e];if(i!==void 0&&(r=!0,n.push(i),n.length===t))break}if(!r)break}}return n}function Xt(e,t){let n=ue(t).toLocaleLowerCase();return n!==``&&e.toLocaleLowerCase().includes(n)}const Zt=`x-lumi-visitor-address`;function Qt(e,t,n){if(e===void 0)return t;if(!Number.isSafeInteger(e)||e<1)throw Error(`content-api search: \`${n}\` must be a positive integer (got ${e})`);return e}var $t=class{getClientIp;store;tokens;intervalMs;readVisitor=ce({header:Zt,trustedProxyHops:1,surface:`content-api visitor search`});constructor(e,t){this.getClientIp=t,this.tokens=Qt(e?.searchesPerVisitorPerInstance,30,`searchesPerVisitorPerInstance`),this.intervalMs=Qt(e?.intervalMs,6e4,`intervalMs`),this.store=e?.store??new I}consume(e,t,n){let r=this.keyFor(e,t);if(r!==void 0)return{decision:this.store.consume(`search:${r.key}`,{tokens:this.tokens,intervalMs:this.intervalMs},n),keyClass:r.keyClass}}keyFor(e,t){if(t.principalId!==void 0)return{key:`principal:${t.principalId}`,keyClass:`principal`};if(t.site!==void 0){let n=this.readVisitor(e.headers);if(n!==null)return{key:`visitor:${t.site}:${n}`,keyClass:`visitor`}}if(t.site!==void 0)return;let n=this.getClientIp?.(e);if(n!==void 0&&n!==``)return{key:`ip:${n}`,keyClass:`client-ip`}}};const en={referenceProjection:{fields:{id:`string`,entityType:`string`,title:`string`,href:`string`},nullableFields:[`title`,`href`],nullable:!0,arrayForCardinalityMany:!0},mediaProjection:{fields:{id:`string`,url:`string`,mimeType:`string`,width:`number`,height:`number`,alt:`string`,title:`string`,variants:`object`,sources:`object`,avifSources:`object`,focalPoint:`object`,blurDataUrl:`string`},nullableFields:[`mimeType`,`width`,`height`,`alt`,`title`,`blurDataUrl`],optionalFields:[`avifSources`],nullable:!0,arrayForCardinalityMany:!1}};function tn(e,t){let n={type:e.type};return e.required&&(n.required=!0),e.translatable&&(n.translatable=!0),e.type===`select`&&(n.options=e.options),e.type===`blockTree`&&(n.selectable=!1),e.type===`media`&&(n.wire=`mediaProjection`),e.type===`reference`&&(n.cardinality=e.cardinality,n.wire=`referenceProjection`,t(e.entity)&&(n.entity=e.entity,n.populatable=!0)),n}function nn(e,t){let n=e.allFields,r={},i=p(e);for(let[e,a]of Object.entries(n))B(e,a)||i&&e!==`id`||(r[e]=tn(a,t));let a=u(e);for(let e of a?.fields??[]){let t=r[e];t&&(t.searchable=!0)}return{name:e.name,pluralName:`${e.name}s`,kind:e.kind??`collection`,...i&&{drawnBy:`template`},fields:r}}const rn={type:`string`},an={type:`string`},on={type:`string`,maxLength:200,maxItems:5};function sn(e){let{maxLimit:t,maxOffset:n,hasResolution:r,hasMenus:i,hasChrome:a}=e,o=[{id:`list`,path:`/:entity`,data:`array`,entityKind:`collection`,params:{limit:{type:`number`,min:1,max:t,default:Math.min(20,t)},offset:{type:`number`,min:0,max:n,default:0},sort:{type:`string`},locale:rn,fields:an,search:{type:`string`,maxLength:200,minLength:2},cursor:{type:`string`,maxLength:500},populate:on,"filter[<field>]":{type:`string`}},meta:{total:{type:`number`,nullable:!0,suppressedBy:[`search`]},limit:{type:`number`},offset:{type:`number`},hasMore:{type:`boolean`},nextCursor:{type:`string`,optional:!0}}},{id:`singleton`,path:`/:entity`,data:`object`,entityKind:`singleton`,params:{locale:rn,fields:an,populate:on}},{id:`count`,path:`/:entity/count`,data:`object`,entityKind:`collection`,params:{locale:rn}},{id:`byId`,path:`/:entity/:id`,data:`object`,entityKind:`collection`,params:{locale:rn,fields:an,populate:on}},{id:`bySlug`,path:`/:entity/slug/:slug`,data:`object`,entityKind:`collection`,params:{locale:rn,fields:an,populate:on}}];return r&&o.push({id:`resolve`,path:`/_resolve`,data:`object`,params:{path:{type:`string`,required:!0,maxLength:de},locale:{type:`string`,required:!0}}},{id:`paths`,path:`/_paths`,data:`array`,params:{locale:{type:`string`,required:!0},entity:{type:`string`,required:!0,maxLength:100},cursor:{type:`string`},limit:{type:`number`,min:1,max:t,default:Math.min(20,t)}},meta:{limit:{type:`number`},hasMore:{type:`boolean`},nextCursor:{type:`string`,optional:!0}}},{id:`alternates`,path:`/_alternates`,data:`array`,params:{entity:{type:`string`,required:!0,maxLength:100},id:{type:`string`,required:!0}}}),o.push({id:`site`,path:`/_site`,data:`object`,params:{}}),o.push({id:`search`,path:`/_search`,data:`array`,params:{q:{type:`string`,required:!0,minLength:2,maxLength:200},types:{type:`string`,maxLength:808},limit:{type:`number`,default:20,min:1,max:50},locale:{type:`string`}},meta:{limit:{type:`number`}}}),i&&o.push({id:`menu`,path:`/_menu`,data:`object`,params:{handle:{type:`string`,required:!0,maxLength:128},locale:{type:`string`,required:!0},currentPath:{type:`string`,maxLength:de}}}),a&&o.push({id:`chrome`,path:`/_chrome`,data:`object`,params:{locale:{type:`string`,required:!0},entity:{type:`string`,maxLength:100},id:{type:`string`}}}),o}function cn(e,t){if(!e.enabled)return null;let n=t?`${Be}:{site}`:Be;return{header:e.header,separator:e.separator,document:`${n}:{entity}:{id}`,collection:`${n}:{entity}`,sharedSite:t?`_`:null,maxTagLength:128,maxTagsPerResponse:128,maxHeaderBytes:Ue,uncovered:[`menuTargets`,`crossEntityPathChanges`,`mediaVariantStyles`,`outOfBandPathChanges`]}}function ln(e){let{entities:t,checkPermission:n,version:r}=e,i={maxResolutionsPerDocument:e.maxResolutionsPerDocument,anonymousRequestsPerInstance:e.limits.anonymousTokensPerInstance,rateLimitWindowMs:e.limits.intervalMs,maxRequestsPerInstance:e.limits.maxBudgetPerInstance,maxConcurrentRequests:e.limits.maxConcurrentRequests,requestTimeoutMs:e.limits.requestTimeoutMs},a=t.filter(e=>n(e.name)),o=new Set(a.map(e=>e.name)),s=e=>o.has(e);return{version:r,surface:sn(e),envelopes:{dataKey:`data`,metaKey:`meta`,errorKey:`error`,errorCodes:jt},limits:i,projections:en,cacheTags:cn(e.cacheTags,e.siteScopedTags===!0),entities:a.map(e=>nn(e,s))}}const un=`public`,dn=new Set;function fn(e){return typeof e==`string`&&e!==``}function pn(e){return Array.isArray(e)}const mn=/^[A-Za-z0-9!#$%&'*+.^_`|~-]+$/;function hn(e){let t=e.credentialHeaders;if(t!==void 0){if(!pn(t))throw Error(`content-api: \`credentialHeaders\` must be an array of HTTP header names, received ${JSON.stringify(t)}.`);for(let e of t)if(!fn(e)||e===`*`||!mn.test(e))throw Error(`content-api: \`credentialHeaders\` entry ${JSON.stringify(e)} is not a valid HTTP header name. Each entry is emitted verbatim in \`Vary\`, so it must be a bare field-name token (\`Cookie\`, \`Authorization\`, \`X-Preview-Token\`). \`*\` is refused: it means "never reuse this response", which is \`Cache-Control: no-store\` spelled obscurely — omit the option instead, which fails closed to exactly that.`)}if(!e.authenticate){if(t!==void 0&&t.length>0)throw Error("content-api: `credentialHeaders` was declared without an `authenticate` hook. This package parses no credential itself, so nothing reads those headers and listing them in `Vary` can only fragment a shared cache. Remove the option, or wire the `authenticate` hook it describes.");return{kind:`none`}}return t===void 0||t.length===0?{kind:`undeclared`}:{kind:`declared`,headers:t}}const gn=k.object({path:k.string().min(1).max(de),locale:k.string().regex(h)}).strict(),_n=k.object({locale:k.string().regex(h),entity:k.string().min(1).max(100),cursor:k.string().refine(e=>be(e),`Invalid cursor`).optional(),limit:k.coerce.number().int().min(1).max(100).default(20)}).strict(),vn=k.object({entity:k.string().min(1).max(100),id:k.string().refine(e=>be(e),`Invalid id`)}).strict(),yn=[`header`,`footer`],bn=k.object({locale:k.string().regex(h),entity:k.string().min(1).max(100).optional(),id:k.string().refine(e=>be(e),`Invalid id`).optional()}).strict().refine(e=>e.entity===void 0==(e.id===void 0),`Both ?entity= and ?id= are required to name a document, or neither.`),xn=k.object({}).strict();function Sn(e){return e instanceof n||e instanceof Error&&e.name===`SiteRequiredError`}const Cn=k.object({handle:k.string().min(1).max(128),locale:k.string().regex(h),currentPath:k.string().min(1).max(de).optional()}).strict(),wn=new Set([`_schema`,`_site`,`_resolve`,`_paths`,`_alternates`,`_menu`,`_chrome`,`_search`]),Tn=`v1`,En=/^v\d+$/;function Dn(e){let t=new Map;for(let n of e){let e=`${n.name}s`;if(wn.has(n.name)||wn.has(e))throw Error(`@murumets-ee/content-api: entity name "${n.name}" collides with a reserved route segment (${[...wn].join(`, `)}). Rename the entity — its API surface would otherwise be permanently unreachable, shadowed by the special dispatch that runs before entity-whitelist resolution.`);if(En.test(n.name)||En.test(e))throw Error(`@murumets-ee/content-api: entity name "${n.name}" is a reserved API-version segment. Every route is served under a version prefix (this instance mounts /v1/), and the prefix is matched as a PATTERN ("v" followed by digits) so that a future /v2/ can never be shadowed by an entity added in the meantime. Rename the entity.`);if(n.scope!==void 0&&n.scope!==`global`)throw Error(`@murumets-ee/content-api: entity "${n.name}" declares scope "${n.scope}", which this surface cannot serve. The public read path resolves no scope for a caller, so QueryClient would apply NO scope filter and return every tenant's rows to every caller. Remove it from the content-api whitelist, or serve it through a surface that establishes a scope in the request context.`);t.set(n.name,n),t.set(e,n)}return t}function On(e,n){let r=e[t];if(!r)throw Error(`site-bound '${n}' translations have no ${t} column`);return r}function Z(e){let t=A.get(e);if(t)return{table:t,cols:M(t)}}const kn=new Set([`text`,`richtext`,`slug`,`select`]);function An(e,t,n){let r=u(e);if(!r)return;let i=t.trim();if(i.length===0)return;let o=Z(e.name);if(!o)return;let{cols:s}=o,l=[],d=`%${_(i)}%`,f=e.allFields,p=r.fields.filter(e=>{let t=Object.hasOwn(f,e)?f[e]:void 0;return t!==void 0&&kn.has(t.type)&&!B(e,t)}),m=r.fts?.fields.some(e=>B(e,f[e]))??!1,h=dn;if(r.fts&&!m){let e=s._search_tsv;if(e){let t=r.fts.language??`simple`;l.push(F`${e} @@ websearch_to_tsquery(${t}, ${i})`),h=new Set(r.fts.fields)}}for(let e of p){if(h.has(e))continue;let t=s[e];t&&l.push(P(t,d))}let g=c(e.allFields,p),v=s.id;if(n!==void 0&&g.length>0&&v){let t=A.get(`${e.name}_translations`);if(t){let e=a({idColumn:v,translationsTable:t,fields:g,locale:n,buildCondition:e=>P(e,d)});e&&l.push(e)}}if(l.length===0)return;let y=l[0];if(y)return l.length===1?y:se(y,...l.slice(1))}function jn(e,t,n){let r=Z(e.name);if(!r)return[];let{cols:i}=r,a=e.allFields,o=t.trim(),s=`%${_(o)}%`,c=[],d=l(e),f=Object.hasOwn(a,d)?a[d]:void 0,p,m=i[d];if(m&&f!==void 0&&kn.has(f.type)&&!B(d,f)){let t=n!==void 0&&f.translatable===!0?Z(`${e.name}_translations`):void 0,r=t?.cols[d],a=t?.cols.entityId,o=t?.cols.locale,c=i.id;p=t&&r&&a&&o&&c&&n!==void 0?F`COALESCE((SELECT ${r} FROM ${t.table} WHERE ${a} = ${c} AND ${o} = ${n} LIMIT 1), ${m}) ILIKE ${s}`:P(m,s)}p&&c.push(F`CASE WHEN ${p} THEN 0 ELSE 1 END`);let h=u(e),g=h?.fts?.fields.some(e=>B(e,a[e]))??!1,v=i._search_tsv;if(h?.fts&&!g&&v){let e=h.fts.language??`simple`;c.push(ie(F`ts_rank(${v}, websearch_to_tsquery(${e}, ${o}))`))}let y=i.updatedAt;y&&c.push(ie(y));let b=i.id;return b&&c.push(re(b)),c}function Mn(e,t,n){let r=e.name;if(!t)return{orderBy:void 0};let i=t.startsWith(`-`),a=i?t.slice(1):t,o={orderBy:void 0,dropped:t};if(!Object.hasOwn(n,a))return o;let s=n[a];if(!s||s.type===`blockTree`||B(a,s)&&!f(e,a))return o;let c=Z(r);if(!c)return o;let l=c.cols[a];return l?{orderBy:i?ie(l):re(l),field:a}:o}function Nn(e,t,n){let r=[],i=[],a=Z(e);if(!a)return{conditions:r,dropped:i};let{cols:o}=a;for(let[e,a]of t.searchParams.entries()){let t=e.match(he);if(!t)continue;let s=t[1];if(s===void 0)continue;if(!Object.hasOwn(n,s)){i.push(s);continue}let c=n[s];if(!c||c.type===`blockTree`){i.push(s);continue}if(B(s,c)){i.push(s);continue}let l=o[s];if(!l){i.push(s);continue}let u=xe(c,a);if(u===null){i.push(s);continue}if(c.type===`date`&&typeof u==`string`){if(u.startsWith(`gte:`)){r.push(N(l,u.slice(4)));continue}if(u.startsWith(`lte:`)){r.push(oe(l,u.slice(4)));continue}}r.push(j(l,u))}return{conditions:r,dropped:i}}function Pn(e,t,n,r,i=!0){if(!(!i||t<=n))return Y(`?${e}=${t} exceeds the maximum of ${n}.${e===`offset`?` Use ?cursor= for deep pagination.`:``}`,`VALIDATION_ERROR`,400,r)}function Fn(e,t,n){return n?e:Math.min(e,t)}function In(e,t,{allowZero:n=!1}={}){if(t===void 0)return;let r=+!n;if(!Number.isInteger(t)||t<r)throw Error(`content-api: \`${e}\` must be an integer >= ${r}, received ${String(t)}. A ceiling below that does not tighten the bound, it removes it: the limit reaches the query layer falsy, no LIMIT clause is emitted, and the whole table is returned on a public route. If this came from an environment variable, it is probably unset.`)}function Q(e){return e.length<=256?e:`${e.slice(0,256)}…[truncated]`}const Ln=new WeakMap,Rn=new WeakMap;function zn(e){if(e.requestId)try{Ln.set(e,v().logger.child({requestId:e.requestId,...e.user?.id!==void 0&&{principalId:e.user.id}}))}catch{}}async function Bn(e,t){let n=y();if(!n)return{locales:[]};let r=e??await T(n).catch(()=>void 0);if(r===void 0)return{locales:[]};let i=await C(n,r);if(!i)return{locales:[]};let a=e=>e!==void 0&&(i.locales.length===0||i.locales.includes(e)),o=n.config.sites?.multiple===!0?i.defaultLocale:void 0,s=a(o)?o:a(t)?t:i.locales[0];return{locales:i.locales,...s!==void 0&&{defaultLocale:s}}}function $(){let e=b();return(e?Ln.get(e):void 0)??v().logger}function Vn(t){let{entities:n,defaultLocale:r,publicRole:i=`public`,cors:a,cache:c,onError:u,resolution:h,menus:_,chrome:k,site:A}=t,re=new Map;for(let[e,n]of Object.entries(t.siteForHost??{})){if(!m(n))throw Error(`content-api: \`siteForHost['${e}']\` is ${JSON.stringify(n)}, which is not a site handle.`);re.set(e.trim().toLowerCase(),n)}function ie(e){if(!e.multiSite)return;let t=y()?.entities;return n=>{let r=t?.get(n);return r!==void 0&&!d(r)?`_`:e.site??`_`}}let M=()=>{let e=b();return(e?Rn.get(e):void 0)??r};In(`maxLimit`,t.maxLimit),In(`maxOffset`,t.maxOffset,{allowZero:!0}),ct(c);let N=Qe(c?.tags);if(!fn(i))throw Error(`content-api: \`publicRole\` must be a non-empty string, received ${JSON.stringify(i)}. An empty public role matches no permission yet is not the anonymous role either, so every unauthenticated request reaches the read path with no groups and fails as a 500. If this came from an environment variable, it is probably unset — omit the option to get "public".`);let P=Math.min(t.maxLimit??100,100),oe=Math.min(t.maxOffset??1e3,1e3),F=hn(t),I=new St(t.limits),L=new $t(t.search,t.search?.getClientIp??t.limits?.getClientIp);Dn(n);let ce;function R(){if(ce)return ce;let e=y(),t=n;if(e){t=[];for(let r of n){let n=e.entities.get(r.name);if(n===void 0){e.logger.error(`content-api: "${r.name}" is in createContentApiHandler({ entities }) but the app does not register an entity of that name — it is NOT served. Register it through lumi.config (entities or a plugin) or remove it from the whitelist.`);continue}t.push(n)}}let r={list:t,map:Dn(t)};return e&&(ce=r),r}if(Object.hasOwn(t,`exposeInternalFields`))throw Error("content-api: `exposeInternalFields` has been removed (plan/api D024). Its only sanctioned use was publishing `_overrides`, which D011 replaced by composing site chrome SERVER-side — so the field no longer needs to reach the wire, and no other internal field was ever safe to list (`_workflowStatus` and `_workflowAssignee` describe an editorial process and name a user; `_version`/`_versionedAt` expose revision cadence). Fetch composed chrome from `GET /_chrome` instead. Remove the option: it is refused rather than ignored, because silently dropping a field you configured is exactly the failure this package throws at construction to prevent.");let le=new Set(_?.handles??[]),ue=De(t.maxResolutionsPerDocument),de=new e(5e3),he=null,ge=0;async function _e(){let e=Date.now();return(!he||e-ge>3e4)&&(he=await t.loadPermissions(),ge=e),he}function ve(){he=null,ge=0}function ye(){return{id:un,role:i,hasIdentity:!1}}function xe(e){try{$().warn({err:e},"content-api: `authenticate` hook threw — serving the anonymous principal")}catch{console.warn("[content-api] `authenticate` hook threw:",e)}}async function we(e){if(!t.authenticate)return ye();let n;try{n=await t.authenticate(e)}catch(e){return xe(e),ye()}if(!n||!fn(n.role)||n.id!==void 0&&!fn(n.id)||n.name!==void 0&&typeof n.name!=`string`||n.email!==void 0&&typeof n.email!=`string`||n.site!==void 0&&!(typeof n.site==`string`&&m(n.site)))return ye();let r=n.rateBudgetPerInstance!==void 0&&Number.isSafeInteger(n.rateBudgetPerInstance)&&n.rateBudgetPerInstance>=1;return{id:n.id??un,hasIdentity:n.id!==void 0,role:n.role,...n.name!==void 0&&{name:n.name},...n.email!==void 0&&{email:n.email},...r&&{rateBudgetPerInstance:n.rateBudgetPerInstance},...n.site!==void 0&&{site:n.site}}}function Te(e){if(re.size===0)return;let t=(e.headers.get(`host`)??new URL(e.url).host).trim().toLowerCase();return re.get(t)}async function Oe(e,t){let n=x();if(t.site!==void 0&&n!==void 0&&n!==t.site)return K({credentialSite:t.site,mountSite:n},`content-api: a credential bound to one site was presented to a mount running as another`),null;let r=t.site??n??Te(e),i=y();if(!i)return{...r!==void 0&&{site:r},multiSite:!1};let a=i.config.sites?.multiple===!0,o=r??await T(i).catch(()=>void 0);if(o===void 0)return{multiSite:a};let s=await C(i,o);return r!==void 0&&(s===void 0||s.status!==`active`)?null:{...r!==void 0&&{site:r},...s!==void 0&&{record:s},multiSite:a}}async function V(e){let t=y(),n=t?.config.sites?.multiple===!0;if(!t||!n)return a;if(!e.headers.has(`Origin`))return a??{allowedOrigins:[]};try{let e=await S(t);return e.truncated&&at(`site-origin-index-truncated`,{listed:e.byOrigin.size},`content-api: the site registry holds more active sites than the origin index reads — some sites’ CORS preflights will be refused`),{allowedOrigins:[...new Set([...a?.allowedOrigins??[],...e.byOrigin.keys()])],...a?.maxAge!==void 0&&{maxAge:a.maxAge}}}catch(e){return K({err:e},`content-api: could not read site origins for CORS`),a}}function H(e){return e.hasIdentity||e.role!==i?`identified`:e.site===void 0?`anonymous`:`site-keyed`}function U(e,t,n){return e(t,n,`view`)}function W(e){let t=v();return new te({entity:e,db:t.db.readOnly,logger:$().child({entity:e.name}),countCache:de,contextResolver:()=>{let e=b();if(!(!e?.user||!e?.checker))return{user:e.user,checker:e.checker,...e.scope!==void 0&&{scope:e.scope},...ee(e,t)}}})}function G(e,n,i,a){let o={budget:Ee(ue),cacheTags:a,resolveMedia:t.resolveMedia,resolveBlocks:t.resolveBlocks,afterExpand:async(e,t)=>{if(p(e)){for(let n of t)await rt(e,n,Ne(o),!1);return}await wt(e,t,o),await ze(e,t,o)},locale:i,reachableEntity:t=>{let r=R().map.get(t);if(!(!r||r.name!==t))return U(e,n,r.name)?r:void 0},canReadEntity:t=>{let r=R().map.get(t);return r!==void 0&&r.name===t&&U(e,n,t)},collectionAllowance:Me(12),templateDrawnTitle:async(e,n)=>{let s=t.detailTemplates,c=i??r;if(!s||c===void 0)return null;try{let t=await s.publicRow({entity:e.name,row:n,locale:c}),r=typeof t.title==`string`?t.title.trim():``;return r===``?null:r.slice(0,2e3)}catch(t){return o.logger?.warn({entity:e.name,err:t},`content-api: detail-template provider failed to project a reference title`),a.markUncacheable(),null}},readRowsByIds:async(e,t,n)=>{let a=Z(e.name)?.cols.id;return!a||t.length===0||ue===0?[]:await W(e).findMany({where:ae(a,[...t]),limit:Math.min(t.length,ue),...n!==void 0&&{select:[...n]},...i!==void 0&&{locale:i},defaultLocale:r})},resolveEntityHref:t.resolveEntityHref,logger:ke()};return o}function ke(){try{return $()}catch{return}}function Ae(e,t,n){let r=e.collectionAllowance?.refusedCount()??0;if(r>0)try{$().warn({entity:t,path:Q(n),cap:12,refused:r},`content-api: per-response collection cap reached — the collection blocks past it rendered empty`)}catch{console.warn(`[content-api] collection cap reached for`,t,Q(n))}if(e.budget.hasDrops)try{$().warn({entity:t,path:Q(n),ceiling:e.budget.ceiling,resolved:e.budget.granted,dropped:e.budget.dropSummary()},`content-api: per-document resolution budget exhausted — response rendered with unresolved targets`)}catch{console.warn(`[content-api] resolution budget exhausted for`,t,Q(n))}}function je(e,t,n,r){let i=Ce(e,n);return i.requested>5?{response:Y(`?populate= names ${i.requested} fields, which exceeds the maximum of 5.`,`VALIDATION_ERROR`,400,r)}:(i.dropped.length>0&&ke()?.debug({entity:t.name,droppedPopulate:i.dropped},`content-api: rejected ?populate= fields (unknown, internal, or not a reference)`),{fields:new Set(i.fields)})}function Ne(e){return{...e,detailTemplates:t.detailTemplates,defaultLocale:r}}async function Pe(e,t,n,r,i){await Ot(e,t,n,r),await wt(e,t,r),await ze(e,t,r),Ae(r,e.name,i)}async function Fe(e,t,n,i,a,l){let u=new URL(e.url),d=fe.safeParse(z(u,{allowFilters:!0}));if(!d.success)return Y(`Invalid query parameters`,`VALIDATION_ERROR`,400,a);let{limit:p,offset:m,sort:h,locale:g,fields:_,search:v,cursor:y,populate:b}=d.data,x=u.searchParams.has(`limit`),S=Pn(`limit`,p,P,a,x);if(S)return S;let C=Pn(`offset`,m,oe,a);if(C)return C;let w=Fn(p,P,x),T=t.allFields,E=je(b,t,T,a);if(`response`in E)return E.response;let D;if(y){let e=o(y);if(!e)return Y(`Invalid cursor`,`VALIDATION_ERROR`,400,a);if(!Object.hasOwn(T,e.field)&&e.field!==`id`||e.field!==`id`&&B(e.field,T[e.field]))return Y(`Invalid cursor field`,`VALIDATION_ERROR`,400,a);D=e}let O=[],ee=!1;if(v){let e=An(t,v,g??M());e&&(O.push(e),ee=!0)}let k=Nn(t.name,u,T);O.push(...k.conditions);let A=Mn(t,h,T),te=A.orderBy;if(D!==void 0&&A.field!==void 0&&f(t,A.field))return Y(`Invalid cursor for this sort`,`VALIDATION_ERROR`,400,a);let re=Se(_,T);if(k.dropped.length>0||A.dropped!==void 0){let e=[...new Set(k.dropped)],n=e.slice(0,20).map(Q);$().info({entity:t.name,...k.dropped.length>0&&{droppedFilters:n,...e.length>n.length&&{droppedFiltersOmitted:e.length-n.length}},...A.dropped!==void 0&&{droppedSort:Q(A.dropped)}},`content-api: rejected query params (unknown, internal, or invalid)`)}let ie=W(t),j=g??M(),N=ee,ae={where:O.length>0?ne(...O):void 0,limit:N?w+1:w,offset:m,orderBy:te,select:re,locale:j,defaultLocale:r,cursor:D},[se,I]=await Promise.all([ie.findMany(ae),N?Promise.resolve(null):ie.count({where:O.length>0?ne(...O):void 0,locale:j})]),L=N&&se.length>w?se.slice(0,w):se,ce=N?se.length>w:m+w<(I??0),R;if(L.length>0&&L.length===w){let e=L[L.length-1],t=D?.field??A.field,n=D?.direction??(h?.startsWith(`-`)?`desc`:`asc`);t&&e[t]!==void 0&&(R=s(e,t,n))}l.addCollection(t.name);for(let e of L)l.addDocument(t.name,e.id);let le=G(i,n.role,j,l);return await Pe(t,L,E.fields,le,u.pathname),J({data:L,meta:{total:I,limit:w,offset:m,hasMore:ce,nextCursor:R}},200,q(t.name,a,H(n),c,F,l))}async function Ie(e,t,n,r,i){let a=new URL(e.url),o=me.safeParse(z(a));if(!o.success)return Y(`Invalid query parameters`,`VALIDATION_ERROR`,400,r);let s=await W(t).count({locale:o.data.locale??M()});return i.addCollection(t.name),J({data:{count:s}},200,q(t.name,r,H(n),c,F,i))}async function Le(e,t,n,i,a,o,s){if(!be(n))return X(o);let l=new URL(e.url),u=pe.safeParse(z(l));if(!u.success)return Y(`Invalid query parameters`,`VALIDATION_ERROR`,400,o);let{locale:d,fields:f,populate:m,page:h}=u.data,g=t.allFields,_=p(t)?void 0:Se(f,g),v=d??M(),y=je(m,t,g,o);if(`response`in y)return y.response;let b=await W(t).findById(n,{..._!==void 0&&{select:_},...v!==void 0&&{locale:v},defaultLocale:r});if(!b)return X(o);s.addDocument(t.name,n);let x={...G(a,i.role,v,s),...h!==void 0&&h>1&&{page:h}};return p(t)?(await rt(t,b,Ne(x),!0),Ae(x,t.name,l.pathname)):await Pe(t,[b],y.fields,x,l.pathname),J({data:b},200,q(t.name,o,H(i),c,F,s))}async function Be(e,t,n,i,a,o,s){let l=new URL(e.url),u=pe.safeParse(z(l));if(!u.success)return Y(`Invalid query parameters`,`VALIDATION_ERROR`,400,o);let d=t.allFields;if(!d.slug)return X(o);let{locale:f,fields:p,populate:m,page:h}=u.data,g=Se(p,d),_=f??M(),y=je(m,t,d,o);if(`response`in y)return y.response;let b=Z(t.name);if(!b)return X(o);let x=b.cols.slug,S=b.cols.id;if(!x||!S)return X(o);let C=W(t),T=d.slug,E=j(x,n);if(T.translatable&&_){let e=Z(`${t.name}_translations`);if(e){let r=e.cols.slug,i=e.cols.locale,a=e.cols.entityId;if(r&&i&&a){let o=v(),s=await w(t,o),c=ne(j(r,n),j(i,_)),l=await o.db.readOnly.select({entityId:a}).from(e.table).where(s===void 0?c:ne(c,j(On(e.cols,t.name),s)));l.length>0&&(E=se(ae(S,l.map(e=>e.entityId)),j(x,n))??j(x,n))}}}let D=await C.findMany({where:E,limit:1,select:g,locale:_,defaultLocale:r});if(D.length===0)return X(o);s.addCollection(t.name),s.addDocument(t.name,D[0]?.id);let O={...G(a,i.role,_,s),...h!==void 0&&h>1&&{page:h}};return await Pe(t,D,y.fields,O,l.pathname),J({data:D[0]},200,q(t.name,o,H(i),c,F,s))}async function Ve(e,t,n,i,a,o){let s=new URL(e.url),l=pe.safeParse(z(s));if(!l.success)return Y(`Invalid query parameters`,`VALIDATION_ERROR`,400,a);let{locale:u,fields:d,populate:f,page:p}=l.data,m=t.allFields,h=Se(d,m),g=u??M(),_=je(f,t,m,a);if(`response`in _)return _.response;let v=(await W(t).findMany({limit:1,select:h,locale:g,defaultLocale:r}))[0];if(!v)return X(a);o.addCollection(t.name),o.addDocument(t.name,v.id);let y={...G(i,n.role,g,o),...p!==void 0&&p>1&&{page:p}};return await Pe(t,[v],_.fields,y,s.pathname),J({data:v},200,q(t.name,a,H(n),c,F,o))}function He(e){return R().map.get(e)??R().map.get(e.endsWith(`s`)?e.slice(0,-1):e)}function We(e,t){if(process.env.NODE_ENV!==`development`)return;let n=JSON.stringify(e.slice(0,100)),r=t===void 0?`${n} is not in the content-api whitelist — add it to createContentApiHandler({ entities: [...] }) in your content route.`:`"${t.name}" is whitelisted but the requesting role lacks 'view' — grant it in the Permission Matrix, or seed it. Note that entity.access.view is advisory metadata the firewall never reads, so a restrictive value there is not the cause.`;console.warn(`[content-api] 404 for ${n}: ${r} (Both refusals are 404 by design — this line is the server-side disambiguation, and the response is unchanged.)`)}async function Ge(e,t,n,r,i){if(!h)return X(r);let a=new URL(e.url),o=gn.safeParse(z(a));if(!o.success)return Y(`Invalid query parameters`,`VALIDATION_ERROR`,400,r);let{path:s,locale:l}=o.data,u=await h.resolvePath(s,l);if(u.kind===`none`)return X(r);if(u.kind===`redirect`)return J({data:u},200,{...r,"Cache-Control":`no-store`});let d=He(u.entityType);return!d||!U(n,t.role,d.name)?(We(u.entityType,d),X(r)):(i.addCollection(d.name),i.addDocument(d.name,u.id),J({data:u},200,q(d.name,r,H(t),c,F,i)))}async function Ke(e,t,n,r,i){if(!h)return X(r);let a=new URL(e.url),o=_n.safeParse(z(a));if(!o.success)return Y(`Invalid query parameters`,`VALIDATION_ERROR`,400,r);let{locale:s,entity:l,cursor:u,limit:d}=o.data,f=a.searchParams.has(`limit`),p=Pn(`limit`,d,P,r,f);if(p)return p;let m=Fn(d,P,f),g=He(l);if(!g||!U(n,t.role,g.name))return We(l,g),X(r);let _=h.enumeratePaths({locale:s,entityType:g.name,...u!==void 0&&{afterDocumentId:u}}),v=[];for await(let e of _)if(v.push(e),v.length===m)break;let y=v.length===m,b=y?v[v.length-1]?.id:void 0;i.addCollection(g.name);for(let e of v)i.addDocument(g.name,e.id);return J({data:v,meta:{limit:m,hasMore:y,nextCursor:b}},200,q(g.name,r,H(t),c,F,i))}async function qe(e,t,n,r,i){if(!h)return X(r);let a=new URL(e.url),o=vn.safeParse(z(a));if(!o.success)return Y(`Invalid query parameters`,`VALIDATION_ERROR`,400,r);let{entity:s,id:l}=o.data,u=He(s);if(!u||!U(n,t.role,u.name))return We(s,u),X(r);let d=b()?.availableLocales,f=await h.getAlternates(u.name,l),p=d?f.filter(e=>d.includes(e.locale)):f;return i.addCollection(u.name),i.addDocument(u.name,l),J({data:p},200,q(u.name,r,H(t),c,F,i))}async function Je(e,t,n,r){if(!_)return X(n);let i=new URL(e.url),a=Cn.safeParse(z(i));if(!a.success)return Y(`Invalid query parameters`,`VALIDATION_ERROR`,400,n);let{handle:o,locale:s,currentPath:l}=a.data;if(!le.has(o))return X(n);let u=await _.getMenu(o,{locale:s,...l!==void 0&&{currentPath:l}});return u?(r.addDocument(`_menu`,o),J({data:u},200,t.site===void 0?pt(`_menu`,n,c,r):q(`_menu`,n,H(t),c,F,r))):X(n)}async function Ye(e,t,n,r,i,a){if(!xn.safeParse(z(new URL(e.url))).success)return Y(`Invalid query parameters`,`VALIDATION_ERROR`,400,i);let o=n.record;if(!o)return X(i);let s=await A?.getI18n(o.handle);if((s?.locales??o.locales).length===0)return at(`site-i18n-unwired:${o.handle}`,{site:o.handle},"content-api: GET /_site cannot answer — this site serves every enabled locale and the mount wires no `site.getI18n` to say which those are. Wire it (see the content route the admin app ships), or give the site an explicit locale list."),X(i);let l=s?.locales??o.locales,u=s?.defaultLocale??r.defaultLocale??l[0];if(u===void 0)return X(i);let d={handle:o.handle,name:o.name,locales:l.length>0?[...l]:[u],defaultLocale:u,routingStrategy:s?.routingStrategy??o.routingStrategy??`no-prefix-default`,origins:[...o.origins]};return a.addDocument(`_site`,o.handle),J({data:d},200,q(`_site`,i,H(t),c,F,a))}async function Xe(e,n,i,a,o,s){let u=L.consume(e,{principalId:n.hasIdentity?n.id:void 0,site:n.site});if(u&&!u.decision.allowed)return K({limit:`search`,keyClass:u.keyClass},`content-api: caller exceeded its visitor-search budget`),Ft(u.decision.retryAfterSeconds,o);let d=new URL(e.url),f=zt.safeParse(z(d));if(!f.success)return Y(`Invalid query parameters`,`VALIDATION_ERROR`,400,o);let{q:p,types:m,limit:h,locale:g}=f.data,_=Pn(`limit`,h,50,o);if(_)return _;let v=Vt(a.record?.searchTypes??[],m);if(v===null||v.length===0)return X(o);let y=[];for(let e of v){let t=R().map.get(e);if(t!==void 0&&t.name===e&&U(i,n.role,e)&&Bt(t)){y.push(t);continue}if(We(e,t),m!==void 0)return X(o);at(`search-type:${a.site??``}:${e}`,{site:a.site,type:e},`content-api: a type in the site's searchTypes cannot be searched by this caller — it is skipped`)}if(y.length===0)return X(o);let b=g??M(),x=[];for(let e of y){s.addCollection(e.name);let t=An(e,p,b);if(!t)continue;let n=await W(e).findMany({where:t,limit:h,orderBy:jn(e,p,b),locale:b,defaultLocale:r}),i=l(e),a=Object.hasOwn(e.allFields,i)?e.allFields[i]:void 0,o=a!==void 0&&kn.has(a.type),c=[];for(let t of n){let n=t.id;if(typeof n!=`string`)continue;let{title:r,summary:a}=Jt(e,t,i),s=t[i];c.push({hit:{entity:e,row:t,id:n,title:r,summary:a},titleHit:o&&typeof s==`string`&&Xt(s,p)})}c.length>0&&x.push({hits:c})}let S=Yt(x,h),C=G(i,n.role,b,s);for(let e of S)s.addDocument(e.entity.name,e.id);let w=new Map;for(let e of y){let t=S.filter(t=>t.entity===e);if(t.length===0)continue;let n=Ht(e);if(n===null)continue;let r=t.map(e=>({id:e.id,[n]:e.row[n]}));await wt(e,r,C),t.forEach((e,t)=>{w.set(e,r[t]?.[n]??null)})}let T=t.resolveEntityHref,E=await D(S,async e=>{if(!T)return null;try{return await T({entity:e.entity.name,id:e.id,...b!==void 0&&{locale:b}})??null}catch(t){return $().debug({entity:e.entity.name,id:e.id,err:t},`content-api: resolveEntityHref threw — search result served without a path`),null}});return Ae(C,`_search`,d.pathname),J({data:S.map((e,t)=>{let n=w.get(e);return{type:e.entity.name,typeLabel:Wt(e.entity),id:e.id,title:e.title,summary:e.summary,image:Ut(n)?n:null,path:E[t]??null}}),meta:{limit:h}},200,q(`_search`,o,H(n),c,F,s))}async function Ze(e,n,r,i,a){if(!k)return X(i);let o=new URL(e.url),s=bn.safeParse(z(o));if(!s.success)return Y(`Invalid query parameters`,`VALIDATION_ERROR`,400,i);let{locale:l,entity:u,id:d}=s.data;if(!U(r,n.role,k.entity))return X(i);let f;if(u!==void 0&&d!==void 0){let e=He(u);e&&U(r,n.role,e.name)?f={entityType:e.name,id:d}:ke()?.debug({entity:u,locale:l},`content-api: _chrome document is unreachable for this caller — serving the site default`)}a.addCollection(k.entity),f!==void 0&&a.addDocument(f.entityType,f.id);let p=G(r,n.role,l,a),m=await k.getChrome({locale:l,...f!==void 0&&{document:f},budget:p.budget}),h=e=>e&&typeof e==`object`?{blocks:Array.isArray(e.blocks)?e.blocks:[],overridden:e.overridden===!0}:null,g=async(e,n)=>{if(n===null||!t.resolveBlocks||n.blocks.length===0)return n;let r=await Re(t.resolveBlocks,n.blocks,{locale:l,budget:p.budget,entity:k.entity,field:e,...p.canReadEntity!==void 0&&{canReadEntity:p.canReadEntity},...p.collectionAllowance!==void 0&&{claimCollection:p.collectionAllowance.claim}});r.failure===`threw`?ke()?.warn({entity:k.entity,region:e,err:r.error},`content-api: block resolver threw — this chrome region is not served as stored; it was re-resolved with an exhausted budget, so its media refs and link hrefs are stripped rather than carrying the urls recorded when an editor picked them`):r.failure===`malformed`&&ke()?.warn({entity:k.entity,region:e},`content-api: block resolver returned a value that is not a ResolvedBlockTree — this chrome region is not served as stored; it was re-resolved with an exhausted budget, so its media refs and link hrefs are stripped rather than carrying the urls recorded when an editor picked them`),r.retryFailure!==void 0&&(a.markUncacheable(),ke()?.warn({entity:k.entity,region:e,err:r.error},`content-api: block resolver failed TWICE, including on the in-memory retry — serving this chrome region EMPTY, so whatever it held is missing from every page render. Serving the stored region instead would put the media urls recorded when an editor picked them, which may be signed, on a cacheable anonymous response`));let i=r.envelope;if(i.refs!==void 0)for(let e of i.refs)a.addDocument(e.entity,e.id);if(i.collections!==void 0)for(let e of Object.values(i.collections))e.entity!==null&&a.addCollection(e.entity);return{blocks:[...i.blocks],overridden:n.overridden,resolved:i.resolved,links:i.links,...i.unresolved!==void 0&&i.unresolved.length>0&&{unresolved:i.unresolved},...i.refs!==void 0&&i.refs.length>0&&{refs:i.refs},...i.collections!==void 0&&{collections:i.collections},...i.live!==void 0&&{live:i.live},...i.currency!==void 0&&{currency:i.currency}}},_={};for(let e of yn)_[e]=await g(e,h(m?.[e]));let v={header:_.header??null,footer:_.footer??null};return Ae(p,k.entity,o.pathname),J({data:v},200,q(k.entity,i,H(n),c,F,a))}async function $e(e,t){let n=E(e),r={},i=x(),a={requestId:n,...i!==void 0&&{site:i}};return zn(a),await O(a,async()=>{let i=await st(e,t,n,r);return tt(i,n),nt(i,e,n,r),i})}function tt(e,t){(e.headers.get(`Cache-Control`)??``).includes(`no-store`)&&e.headers.set(g,t)}function nt(e,t,n,r){if(!u||e.status<400)return;let i=Pt(e);if(i!==void 0)try{Promise.resolve(u({status:e.status,code:i,path:Q(new URL(t.url).pathname),...r.entity!==void 0&&{entity:r.entity},requestId:n,...r.principalId!==void 0&&{principalId:r.principalId}})).catch(ot)}catch(e){ot(e)}}let it=new Set;function at(e,t,n){it.has(e)||(it.add(e),K(t,n))}function K(e,t){try{$().warn(e,t)}catch{try{console.warn(`[content-api]`,t,e)}catch{}}}function ot(e){try{$().warn({err:e},"content-api: `onError` monitoring hook failed")}catch{}}async function st(e,t,n,r){let i=ht(e,await V(e)),a=mt(i,F);try{await I.acquire(e.signal)}catch(e){return e instanceof _t?(K({limit:`survival`,maxConcurrentRequests:I.limits.maxConcurrentRequests,maxQueuedRequests:I.limits.maxQueuedRequests},`content-api: shedding load — concurrency slots and wait queue both full`),It(1,a)):(K({err:e},`content-api: acquiring a concurrency slot failed`),Y(`Internal server error`,`INTERNAL_ERROR`,500,a))}try{return await I.runGuarded(a=>lt(e,t,n,r,i,a))}catch(e){if(e instanceof vt)return K({limit:`deadline`,requestTimeoutMs:I.limits.requestTimeoutMs},`content-api: request exceeded the wall clock`),It(1,a);throw e}finally{I.release()}}async function lt(e,t,n,i,o,s){let c=o;try{let l=t.path;if(!l||l.length===0||l[0]!==`v1`)return X(o);let u=l.slice(1);if(u.length===0)return X(o);if(new URL(e.url).searchParams.has(`site`))return Y(`Invalid query parameters`,`VALIDATION_ERROR`,400,mt(o,F));let d=await we(e),f=d.role,m=await Oe(e,d);if(m===null)return X(mt(a?{Vary:`Origin`}:{},F));let g=m.multiSite?ht(e,{allowedOrigins:m.record?.origins??[],...a?.maxAge!==void 0&&{maxAge:a.maxAge}}):o,v=I.consumeFairness(e,{principalId:d.hasIdentity?d.id:void 0,budgetPerInstance:d.rateBudgetPerInstance}),y=mt(g,F);c=y;let b=et(N,ie(m));if(v&&!v.decision.allowed)return K({limit:`fairness`,keyClass:v.keyClass},`content-api: caller exceeded its per-instance budget`),Ft(v.decision.retryAfterSeconds,y);let x=await _e();i.principalId=d.id;let S=m.site,C=await Bn(S,r),w=new URL(e.url).searchParams.get(`locale`);if(w!==null&&w!==``&&C.locales.length>0&&!C.locales.includes(w))return Y(`Locale '${w}' is not served by this site`,`VALIDATION_ERROR`,400,y);let T={user:{id:d.id,groups:f?[f]:[],...d.name!==void 0&&{name:d.name},...d.email!==void 0&&{email:d.email}},checker:x,requestId:n,...S!==void 0&&{site:S},...C.locales.length>0&&{availableLocales:C.locales}};C.defaultLocale!==void 0&&Rn.set(T,C.defaultLocale),zn(T);let E=await O(T,async()=>{if(s?.aborted)throw new vt;if(u[0]===`_schema`)return J(ln({entities:R().list,checkPermission:e=>U(x,f,e),version:`v1`,maxLimit:P,maxOffset:oe,maxResolutionsPerDocument:ue,limits:I.limits,hasResolution:h!==void 0,hasMenus:_!==void 0,hasChrome:k!==void 0,cacheTags:N,siteScopedTags:m.multiSite}),200,{...y,"Cache-Control":`no-store`});if(u[0]===`_resolve`)return Ge(e,d,x,y,b);if(u[0]===`_paths`)return Ke(e,d,x,y,b);if(u[0]===`_alternates`)return qe(e,d,x,y,b);if(u[0]===`_menu`)return Je(e,d,y,b);if(u[0]===`_site`)return Ye(e,d,m,C,y,b);if(u[0]===`_chrome`)return Ze(e,d,x,y,b);if(u[0]===`_search`&&u.length===1)return Xe(e,d,x,m,y,b);let t=u[0];if(t===void 0)return X(y);let n=He(t);if(!n||!U(x,f,n.name))return We(t,n),X(y);if(i.entity=n.name,n.kind===`singleton`)return u.length===1?Ve(e,n,d,x,y,b):X(y);if(p(n)){let t=u[1];return u.length===2&&t!==void 0?Le(e,n,t,d,x,y,b):X(y)}return u.length===1?Fe(e,n,d,x,y,b):u[1]===`count`?Ie(e,n,d,y,b):u[1]===`slug`&&u[2]?Be(e,n,u[2],d,x,y,b):u.length===2&&u[1]!==void 0?Le(e,n,u[1],d,x,y,b):X(y)});return b.dropped>0&&E.headers.has(N.header)&&K({dropped:b.dropped,emitted:b.tags.length,maxTags:128,maxHeaderBytes:Ue,...i.entity!==void 0&&{entity:i.entity},path:Q(new URL(e.url).pathname)},`content-api: cache tags refused — this response depends on documents it does not name, so a purge for them will not invalidate it`),E}catch(t){if(t instanceof vt)throw t;if(Sn(t))return X(c);let n=new URL(e.url).pathname;try{$().error({err:t,path:Q(n)},`content-api handler error`)}catch{console.error(`[content-api] handler error:`,t)}return Y(`Internal server error`,`INTERNAL_ERROR`,500,c)}}return{GET:(e,t)=>$e(e,t),OPTIONS:async e=>gt(e,await V(e),c),invalidatePermissionCache:ve}}export{Tn as API_VERSION,Be as CACHE_TAG_NAMESPACE,Lt as DEFAULT_SEARCH_RESULTS,tt as DETAIL_TEMPLATE_FIELD,jt as ERROR_CODES,He as MAX_CACHE_TAGS_PER_RESPONSE,Ue as MAX_CACHE_TAG_HEADER_BYTES,Ve as MAX_CACHE_TAG_LENGTH,Te as MAX_RESOLUTIONS_PER_DOCUMENT,Rt as MAX_SEARCH_RESULTS,We as MEDIA_TAG_ENTITY,Ke as SHARED_SITE_TAG_SEGMENT,Zt as VISITOR_ADDRESS_HEADER,Vn as createContentApiHandler,Ne as isResolvedBlockTree};
2
2
  //# sourceMappingURL=index.mjs.map