emdash 0.40.0 → 0.41.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (1258) hide show
  1. package/dist/action-token-CbKDcPJi.mjs +26 -0
  2. package/dist/action-token-CbKDcPJi.mjs.map +1 -0
  3. package/dist/activation-PtniBLt9.mjs +382 -0
  4. package/dist/activation-PtniBLt9.mjs.map +1 -0
  5. package/dist/adapters-C_Tf5x90.d.mts +171 -0
  6. package/dist/adapters-C_Tf5x90.d.mts.map +1 -0
  7. package/dist/allowed-origins-U1z4TdEZ.mjs +116 -0
  8. package/dist/allowed-origins-U1z4TdEZ.mjs.map +1 -0
  9. package/dist/api/route-utils.d.mts +4 -4
  10. package/dist/api/route-utils.mjs +46 -45
  11. package/dist/api/route-utils.mjs.map +1 -1
  12. package/dist/api/schemas/index.d.mts +2 -2
  13. package/dist/api/schemas/index.mjs +10 -10
  14. package/dist/api-CXwQkV_m.mjs +5122 -0
  15. package/dist/api-CXwQkV_m.mjs.map +1 -0
  16. package/dist/api-tokens-89WlohEN.mjs +166 -0
  17. package/dist/api-tokens-89WlohEN.mjs.map +1 -0
  18. package/dist/apply-Do3KNnUk.mjs +1659 -0
  19. package/dist/apply-Do3KNnUk.mjs.map +1 -0
  20. package/dist/approvals-CAX9Yw33.mjs +460 -0
  21. package/dist/approvals-CAX9Yw33.mjs.map +1 -0
  22. package/dist/artifact-fetch-B9W4CEST.mjs +659 -0
  23. package/dist/artifact-fetch-B9W4CEST.mjs.map +1 -0
  24. package/dist/astro/index.d.mts +14 -14
  25. package/dist/astro/index.mjs +26 -30
  26. package/dist/astro/index.mjs.map +1 -1
  27. package/dist/astro/middleware/auth.d.mts +12 -12
  28. package/dist/astro/middleware/auth.mjs +10 -10
  29. package/dist/astro/middleware/media-usage-write-fence.mjs +5 -5
  30. package/dist/astro/middleware/redirect.mjs +7 -7
  31. package/dist/astro/middleware/request-context.mjs +3 -3
  32. package/dist/astro/middleware/setup.mjs +1 -1
  33. package/dist/astro/middleware.d.mts +12 -12
  34. package/dist/astro/middleware.d.mts.map +1 -1
  35. package/dist/astro/middleware.mjs +110 -106
  36. package/dist/astro/middleware.mjs.map +1 -1
  37. package/dist/astro/routes/api/admin/allowed-domains/_domain_.mjs +14 -14
  38. package/dist/astro/routes/api/admin/allowed-domains/index.mjs +14 -14
  39. package/dist/astro/routes/api/admin/api-tokens/_id_.mjs +6 -6
  40. package/dist/astro/routes/api/admin/api-tokens/index.mjs +7 -7
  41. package/dist/astro/routes/api/admin/byline-fields/_slug_/usage.mjs +7 -7
  42. package/dist/astro/routes/api/admin/byline-fields/_slug_.mjs +17 -17
  43. package/dist/astro/routes/api/admin/byline-fields/index.mjs +17 -17
  44. package/dist/astro/routes/api/admin/byline-fields/reorder.mjs +17 -17
  45. package/dist/astro/routes/api/admin/bylines/_id_/index.mjs +23 -23
  46. package/dist/astro/routes/api/admin/bylines/_id_/translations.mjs +23 -23
  47. package/dist/astro/routes/api/admin/bylines/index.mjs +23 -23
  48. package/dist/astro/routes/api/admin/comments/_id_/status.mjs +18 -18
  49. package/dist/astro/routes/api/admin/comments/_id_.mjs +7 -7
  50. package/dist/astro/routes/api/admin/comments/bulk.mjs +17 -17
  51. package/dist/astro/routes/api/admin/comments/counts.mjs +7 -7
  52. package/dist/astro/routes/api/admin/comments/index.mjs +17 -17
  53. package/dist/astro/routes/api/admin/hooks/exclusive/_hookName_.mjs +6 -6
  54. package/dist/astro/routes/api/admin/hooks/exclusive/index.mjs +5 -5
  55. package/dist/astro/routes/api/admin/media-usage/activation.mjs +20 -20
  56. package/dist/astro/routes/api/admin/media-usage/collection-deletions/index.mjs +22 -22
  57. package/dist/astro/routes/api/admin/media-usage/collection-deletions/retry.mjs +22 -22
  58. package/dist/astro/routes/api/admin/media-usage/progress.mjs +25 -25
  59. package/dist/astro/routes/api/admin/media-usage/repair.mjs +31 -31
  60. package/dist/astro/routes/api/admin/media-usage/work/index.mjs +22 -22
  61. package/dist/astro/routes/api/admin/media-usage/work/retry.mjs +22 -22
  62. package/dist/astro/routes/api/admin/oauth-clients/_id_.mjs +6 -6
  63. package/dist/astro/routes/api/admin/oauth-clients/index.mjs +6 -6
  64. package/dist/astro/routes/api/admin/plugins/_id_/disable.mjs +8 -8
  65. package/dist/astro/routes/api/admin/plugins/_id_/enable.mjs +8 -8
  66. package/dist/astro/routes/api/admin/plugins/_id_/index.mjs +72 -68
  67. package/dist/astro/routes/api/admin/plugins/_id_/index.mjs.map +1 -1
  68. package/dist/astro/routes/api/admin/plugins/_id_/mcp.mjs +7 -7
  69. package/dist/astro/routes/api/admin/plugins/_id_/settings.mjs +71 -67
  70. package/dist/astro/routes/api/admin/plugins/_id_/settings.mjs.map +1 -1
  71. package/dist/astro/routes/api/admin/plugins/_id_/uninstall.mjs +72 -68
  72. package/dist/astro/routes/api/admin/plugins/_id_/uninstall.mjs.map +1 -1
  73. package/dist/astro/routes/api/admin/plugins/_id_/update.mjs +82 -78
  74. package/dist/astro/routes/api/admin/plugins/_id_/update.mjs.map +1 -1
  75. package/dist/astro/routes/api/admin/plugins/index.mjs +72 -68
  76. package/dist/astro/routes/api/admin/plugins/index.mjs.map +1 -1
  77. package/dist/astro/routes/api/admin/plugins/marketplace/_id_/icon.mjs +5 -5
  78. package/dist/astro/routes/api/admin/plugins/marketplace/_id_/index.mjs +71 -67
  79. package/dist/astro/routes/api/admin/plugins/marketplace/_id_/index.mjs.map +1 -1
  80. package/dist/astro/routes/api/admin/plugins/marketplace/_id_/install.mjs +81 -77
  81. package/dist/astro/routes/api/admin/plugins/marketplace/_id_/install.mjs.map +1 -1
  82. package/dist/astro/routes/api/admin/plugins/marketplace/index.mjs +71 -67
  83. package/dist/astro/routes/api/admin/plugins/marketplace/index.mjs.map +1 -1
  84. package/dist/astro/routes/api/admin/plugins/registry/_id_/uninstall.mjs +72 -68
  85. package/dist/astro/routes/api/admin/plugins/registry/_id_/uninstall.mjs.map +1 -1
  86. package/dist/astro/routes/api/admin/plugins/registry/_id_/update.mjs +83 -79
  87. package/dist/astro/routes/api/admin/plugins/registry/_id_/update.mjs.map +1 -1
  88. package/dist/astro/routes/api/admin/plugins/registry/artifact.mjs +9 -9
  89. package/dist/astro/routes/api/admin/plugins/registry/install.mjs +74 -70
  90. package/dist/astro/routes/api/admin/plugins/registry/install.mjs.map +1 -1
  91. package/dist/astro/routes/api/admin/plugins/registry/publisher-handle.mjs +7 -7
  92. package/dist/astro/routes/api/admin/plugins/registry/verify.mjs +72 -68
  93. package/dist/astro/routes/api/admin/plugins/registry/verify.mjs.map +1 -1
  94. package/dist/astro/routes/api/admin/plugins/updates.mjs +71 -67
  95. package/dist/astro/routes/api/admin/plugins/updates.mjs.map +1 -1
  96. package/dist/astro/routes/api/admin/scheduled-policy-rejections/_collection_/_id_.mjs +6 -6
  97. package/dist/astro/routes/api/admin/themes/marketplace/_id_/index.mjs +71 -67
  98. package/dist/astro/routes/api/admin/themes/marketplace/_id_/index.mjs.map +1 -1
  99. package/dist/astro/routes/api/admin/themes/marketplace/_id_/thumbnail.mjs +5 -5
  100. package/dist/astro/routes/api/admin/themes/marketplace/index.mjs +71 -67
  101. package/dist/astro/routes/api/admin/themes/marketplace/index.mjs.map +1 -1
  102. package/dist/astro/routes/api/admin/transfer/_...path_.mjs +4 -4
  103. package/dist/astro/routes/api/admin/transfer/approvals/_id_/approve.mjs +40 -40
  104. package/dist/astro/routes/api/admin/transfer/approvals/_id_/deny.mjs +40 -40
  105. package/dist/astro/routes/api/admin/transfer/approvals/index.mjs +42 -42
  106. package/dist/astro/routes/api/admin/transfer/capabilities.mjs +42 -42
  107. package/dist/astro/routes/api/admin/transfer/exports/_id_/advance.mjs +42 -42
  108. package/dist/astro/routes/api/admin/transfer/exports/_id_/archive.mjs +43 -43
  109. package/dist/astro/routes/api/admin/transfer/exports/_id_/files/_...path_.mjs +43 -43
  110. package/dist/astro/routes/api/admin/transfer/exports/_id_/index.mjs +42 -42
  111. package/dist/astro/routes/api/admin/transfer/exports/_id_/manifest.mjs +43 -43
  112. package/dist/astro/routes/api/admin/transfer/exports/index.mjs +44 -44
  113. package/dist/astro/routes/api/admin/transfer/imports/_id_/abandon.mjs +42 -42
  114. package/dist/astro/routes/api/admin/transfer/imports/_id_/advance.mjs +42 -42
  115. package/dist/astro/routes/api/admin/transfer/imports/_id_/analyze.mjs +44 -44
  116. package/dist/astro/routes/api/admin/transfer/imports/_id_/cancel.mjs +42 -42
  117. package/dist/astro/routes/api/admin/transfer/imports/_id_/execute.mjs +44 -44
  118. package/dist/astro/routes/api/admin/transfer/imports/_id_/files/_...path_.mjs +42 -42
  119. package/dist/astro/routes/api/admin/transfer/imports/_id_/index.mjs +42 -42
  120. package/dist/astro/routes/api/admin/transfer/imports/_id_/missing.mjs +44 -44
  121. package/dist/astro/routes/api/admin/transfer/imports/_id_/plan.mjs +42 -42
  122. package/dist/astro/routes/api/admin/transfer/imports/_id_/receipt.mjs +42 -42
  123. package/dist/astro/routes/api/admin/transfer/imports/index.mjs +44 -44
  124. package/dist/astro/routes/api/admin/users/_id_/disable.mjs +5 -5
  125. package/dist/astro/routes/api/admin/users/_id_/enable.mjs +4 -4
  126. package/dist/astro/routes/api/admin/users/_id_/index.mjs +15 -15
  127. package/dist/astro/routes/api/admin/users/_id_/send-recovery.mjs +6 -6
  128. package/dist/astro/routes/api/admin/users/index.mjs +14 -14
  129. package/dist/astro/routes/api/auth/dev-bypass.mjs +6 -6
  130. package/dist/astro/routes/api/auth/invite/accept.mjs +4 -4
  131. package/dist/astro/routes/api/auth/invite/complete.mjs +18 -18
  132. package/dist/astro/routes/api/auth/invite/index.mjs +16 -16
  133. package/dist/astro/routes/api/auth/invite/register-options.mjs +17 -17
  134. package/dist/astro/routes/api/auth/logout.mjs +5 -5
  135. package/dist/astro/routes/api/auth/magic-link/send.mjs +18 -18
  136. package/dist/astro/routes/api/auth/magic-link/verify.mjs +14 -14
  137. package/dist/astro/routes/api/auth/me.mjs +15 -15
  138. package/dist/astro/routes/api/auth/mode.mjs +5 -5
  139. package/dist/astro/routes/api/auth/oauth/_provider_/callback.mjs +3 -3
  140. package/dist/astro/routes/api/auth/oauth/_provider_.mjs +2 -2
  141. package/dist/astro/routes/api/auth/passkey/_id_.mjs +14 -14
  142. package/dist/astro/routes/api/auth/passkey/index.mjs +4 -4
  143. package/dist/astro/routes/api/auth/passkey/options.mjs +19 -19
  144. package/dist/astro/routes/api/auth/passkey/register/options.mjs +17 -17
  145. package/dist/astro/routes/api/auth/passkey/register/verify.mjs +18 -18
  146. package/dist/astro/routes/api/auth/passkey/verify.mjs +18 -18
  147. package/dist/astro/routes/api/auth/signup/complete.mjs +18 -18
  148. package/dist/astro/routes/api/auth/signup/request.mjs +17 -17
  149. package/dist/astro/routes/api/auth/signup/verify.mjs +4 -4
  150. package/dist/astro/routes/api/comments/_collection_/_contentId_/index.mjs +12 -12
  151. package/dist/astro/routes/api/comments/_collection_/_contentId_/reactions.mjs +18 -18
  152. package/dist/astro/routes/api/content/_collection_/_id_/compare.mjs +5 -5
  153. package/dist/astro/routes/api/content/_collection_/_id_/discard-draft.mjs +17 -17
  154. package/dist/astro/routes/api/content/_collection_/_id_/duplicate.mjs +5 -5
  155. package/dist/astro/routes/api/content/_collection_/_id_/lock.mjs +17 -17
  156. package/dist/astro/routes/api/content/_collection_/_id_/permanent.mjs +5 -5
  157. package/dist/astro/routes/api/content/_collection_/_id_/plugin-extensions/_pluginId_/_kind_/_extensionId_.mjs +11 -11
  158. package/dist/astro/routes/api/content/_collection_/_id_/preview-url.mjs +31 -31
  159. package/dist/astro/routes/api/content/_collection_/_id_/publish.mjs +17 -17
  160. package/dist/astro/routes/api/content/_collection_/_id_/references/_relation_/children.d.mts +1 -2
  161. package/dist/astro/routes/api/content/_collection_/_id_/references/_relation_/children.d.mts.map +1 -1
  162. package/dist/astro/routes/api/content/_collection_/_id_/references/_relation_/children.mjs +42 -53
  163. package/dist/astro/routes/api/content/_collection_/_id_/references/_relation_/children.mjs.map +1 -1
  164. package/dist/astro/routes/api/content/_collection_/_id_/references/_relation_/parents.mjs +34 -29
  165. package/dist/astro/routes/api/content/_collection_/_id_/references/_relation_/parents.mjs.map +1 -1
  166. package/dist/astro/routes/api/content/_collection_/_id_/restore.mjs +5 -5
  167. package/dist/astro/routes/api/content/_collection_/_id_/revisions.mjs +5 -5
  168. package/dist/astro/routes/api/content/_collection_/_id_/schedule.mjs +17 -17
  169. package/dist/astro/routes/api/content/_collection_/_id_/terms/_taxonomy_.mjs +25 -24
  170. package/dist/astro/routes/api/content/_collection_/_id_/terms/_taxonomy_.mjs.map +1 -1
  171. package/dist/astro/routes/api/content/_collection_/_id_/translations.mjs +5 -5
  172. package/dist/astro/routes/api/content/_collection_/_id_/unpublish.mjs +17 -17
  173. package/dist/astro/routes/api/content/_collection_/_id_.d.mts.map +1 -1
  174. package/dist/astro/routes/api/content/_collection_/_id_.mjs +18 -18
  175. package/dist/astro/routes/api/content/_collection_/_id_.mjs.map +1 -1
  176. package/dist/astro/routes/api/content/_collection_/authors.mjs +5 -5
  177. package/dist/astro/routes/api/content/_collection_/index.mjs +15 -15
  178. package/dist/astro/routes/api/content/_collection_/trash.mjs +15 -15
  179. package/dist/astro/routes/api/dashboard.mjs +10 -9
  180. package/dist/astro/routes/api/dashboard.mjs.map +1 -1
  181. package/dist/astro/routes/api/dev/emails.mjs +5 -5
  182. package/dist/astro/routes/api/health.mjs +6 -6
  183. package/dist/astro/routes/api/import/probe.d.mts +3 -3
  184. package/dist/astro/routes/api/import/probe.mjs +23 -23
  185. package/dist/astro/routes/api/import/wordpress/analyze.mjs +6 -6
  186. package/dist/astro/routes/api/import/wordpress/execute.d.mts +13 -13
  187. package/dist/astro/routes/api/import/wordpress/execute.mjs +16 -16
  188. package/dist/astro/routes/api/import/wordpress/media.d.mts +12 -12
  189. package/dist/astro/routes/api/import/wordpress/media.mjs +19 -19
  190. package/dist/astro/routes/api/import/wordpress/prepare.mjs +18 -18
  191. package/dist/astro/routes/api/import/wordpress/rewrite-urls.d.mts +13 -13
  192. package/dist/astro/routes/api/import/wordpress/rewrite-urls.mjs +28 -28
  193. package/dist/astro/routes/api/import/wordpress-plugin/analyze.d.mts +1 -1
  194. package/dist/astro/routes/api/import/wordpress-plugin/analyze.mjs +23 -23
  195. package/dist/astro/routes/api/import/wordpress-plugin/execute.d.mts +13 -13
  196. package/dist/astro/routes/api/import/wordpress-plugin/execute.mjs +34 -34
  197. package/dist/astro/routes/api/manifest.mjs +6 -6
  198. package/dist/astro/routes/api/mcp.mjs +98 -118
  199. package/dist/astro/routes/api/mcp.mjs.map +1 -1
  200. package/dist/astro/routes/api/media/_id_/confirm.mjs +19 -19
  201. package/dist/astro/routes/api/media/_id_/replace.mjs +16 -16
  202. package/dist/astro/routes/api/media/_id_/upload.mjs +9 -9
  203. package/dist/astro/routes/api/media/_id_/usage.mjs +33 -33
  204. package/dist/astro/routes/api/media/_id_.mjs +31 -31
  205. package/dist/astro/routes/api/media/asset/_id_/_filename_.mjs +6 -6
  206. package/dist/astro/routes/api/media/file/_...key_.mjs +9 -9
  207. package/dist/astro/routes/api/media/folders/_id_.mjs +16 -16
  208. package/dist/astro/routes/api/media/folders/index.mjs +16 -16
  209. package/dist/astro/routes/api/media/providers/_providerId_/_itemId_.mjs +5 -5
  210. package/dist/astro/routes/api/media/providers/_providerId_/index.mjs +5 -5
  211. package/dist/astro/routes/api/media/providers/index.mjs +5 -5
  212. package/dist/astro/routes/api/media/upload-url.mjs +18 -18
  213. package/dist/astro/routes/api/media.mjs +35 -35
  214. package/dist/astro/routes/api/menus/_name_/items/_id_.mjs +17 -17
  215. package/dist/astro/routes/api/menus/_name_/items.mjs +17 -17
  216. package/dist/astro/routes/api/menus/_name_/reorder.mjs +17 -17
  217. package/dist/astro/routes/api/menus/_name_/translations.mjs +17 -17
  218. package/dist/astro/routes/api/menus/_name_.mjs +17 -17
  219. package/dist/astro/routes/api/menus/index.mjs +17 -17
  220. package/dist/astro/routes/api/oauth/authorize.mjs +6 -6
  221. package/dist/astro/routes/api/oauth/device/authorize.d.mts +2 -1
  222. package/dist/astro/routes/api/oauth/device/authorize.d.mts.map +1 -1
  223. package/dist/astro/routes/api/oauth/device/authorize.mjs +23 -9
  224. package/dist/astro/routes/api/oauth/device/authorize.mjs.map +1 -1
  225. package/dist/astro/routes/api/oauth/device/code.mjs +11 -11
  226. package/dist/astro/routes/api/oauth/device/token.mjs +10 -10
  227. package/dist/astro/routes/api/oauth/register.mjs +5 -5
  228. package/dist/astro/routes/api/oauth/token/refresh.mjs +8 -8
  229. package/dist/astro/routes/api/oauth/token/revoke.mjs +8 -8
  230. package/dist/astro/routes/api/oauth/token.mjs +8 -8
  231. package/dist/astro/routes/api/openapi.json.mjs +20 -20
  232. package/dist/astro/routes/api/plugins/_pluginId_/_...path_.mjs +11 -11
  233. package/dist/astro/routes/api/redirects/404s/index.mjs +19 -19
  234. package/dist/astro/routes/api/redirects/404s/summary.mjs +19 -19
  235. package/dist/astro/routes/api/redirects/_id_.mjs +19 -19
  236. package/dist/astro/routes/api/redirects/index.mjs +19 -19
  237. package/dist/astro/routes/api/relations/_id_/index.mjs +34 -29
  238. package/dist/astro/routes/api/relations/_id_/index.mjs.map +1 -1
  239. package/dist/astro/routes/api/relations/index.mjs +36 -31
  240. package/dist/astro/routes/api/relations/index.mjs.map +1 -1
  241. package/dist/astro/routes/api/revisions/_revisionId_/index.mjs +5 -5
  242. package/dist/astro/routes/api/revisions/_revisionId_/restore.mjs +5 -5
  243. package/dist/astro/routes/api/schema/block-types/_slug_/index.mjs +71 -67
  244. package/dist/astro/routes/api/schema/block-types/_slug_/index.mjs.map +1 -1
  245. package/dist/astro/routes/api/schema/block-types/_slug_/versions/_version_/activate.mjs +71 -67
  246. package/dist/astro/routes/api/schema/block-types/_slug_/versions/_version_/activate.mjs.map +1 -1
  247. package/dist/astro/routes/api/schema/block-types/index.mjs +71 -67
  248. package/dist/astro/routes/api/schema/block-types/index.mjs.map +1 -1
  249. package/dist/astro/routes/api/schema/collections/_slug_/fields/_fieldSlug_.mjs +73 -69
  250. package/dist/astro/routes/api/schema/collections/_slug_/fields/_fieldSlug_.mjs.map +1 -1
  251. package/dist/astro/routes/api/schema/collections/_slug_/fields/index.mjs +71 -67
  252. package/dist/astro/routes/api/schema/collections/_slug_/fields/index.mjs.map +1 -1
  253. package/dist/astro/routes/api/schema/collections/_slug_/fields/reorder.mjs +71 -67
  254. package/dist/astro/routes/api/schema/collections/_slug_/fields/reorder.mjs.map +1 -1
  255. package/dist/astro/routes/api/schema/collections/_slug_/index.mjs +71 -67
  256. package/dist/astro/routes/api/schema/collections/_slug_/index.mjs.map +1 -1
  257. package/dist/astro/routes/api/schema/collections/index.mjs +71 -67
  258. package/dist/astro/routes/api/schema/collections/index.mjs.map +1 -1
  259. package/dist/astro/routes/api/schema/collections/reorder.mjs +71 -67
  260. package/dist/astro/routes/api/schema/collections/reorder.mjs.map +1 -1
  261. package/dist/astro/routes/api/schema/index.mjs +16 -16
  262. package/dist/astro/routes/api/schema/orphans/_slug_.mjs +71 -67
  263. package/dist/astro/routes/api/schema/orphans/_slug_.mjs.map +1 -1
  264. package/dist/astro/routes/api/schema/orphans/index.mjs +71 -67
  265. package/dist/astro/routes/api/schema/orphans/index.mjs.map +1 -1
  266. package/dist/astro/routes/api/search/enable.mjs +19 -19
  267. package/dist/astro/routes/api/search/index.mjs +18 -18
  268. package/dist/astro/routes/api/search/rebuild.mjs +19 -19
  269. package/dist/astro/routes/api/search/stats.mjs +9 -9
  270. package/dist/astro/routes/api/search/suggest.mjs +18 -18
  271. package/dist/astro/routes/api/sections/_slug_.mjs +18 -18
  272. package/dist/astro/routes/api/sections/index.mjs +18 -18
  273. package/dist/astro/routes/api/settings/backups/archives/_name_.mjs +7 -7
  274. package/dist/astro/routes/api/settings/backups/archives/index.mjs +7 -7
  275. package/dist/astro/routes/api/settings/backups/export.mjs +7 -7
  276. package/dist/astro/routes/api/settings/backups/index.mjs +8 -8
  277. package/dist/astro/routes/api/settings/email.mjs +6 -6
  278. package/dist/astro/routes/api/settings.mjs +21 -21
  279. package/dist/astro/routes/api/setup/admin-verify.mjs +19 -19
  280. package/dist/astro/routes/api/setup/admin.mjs +18 -18
  281. package/dist/astro/routes/api/setup/dev-bypass.mjs +45 -39
  282. package/dist/astro/routes/api/setup/dev-bypass.mjs.map +1 -1
  283. package/dist/astro/routes/api/setup/dev-reset.mjs +4 -4
  284. package/dist/astro/routes/api/setup/index.d.mts.map +1 -1
  285. package/dist/astro/routes/api/setup/index.mjs +80 -49
  286. package/dist/astro/routes/api/setup/index.mjs.map +1 -1
  287. package/dist/astro/routes/api/setup/status.mjs +6 -6
  288. package/dist/astro/routes/api/snapshot.mjs +9 -9
  289. package/dist/astro/routes/api/snapshot.mjs.map +1 -1
  290. package/dist/astro/routes/api/taxonomies/_name_/reorder.mjs +23 -23
  291. package/dist/astro/routes/api/taxonomies/_name_/terms/_slug_/translations.mjs +23 -23
  292. package/dist/astro/routes/api/taxonomies/_name_/terms/_slug_.mjs +23 -23
  293. package/dist/astro/routes/api/taxonomies/_name_/terms/index.mjs +23 -23
  294. package/dist/astro/routes/api/taxonomies/_name_/translations.mjs +22 -22
  295. package/dist/astro/routes/api/taxonomies/_name_.mjs +23 -23
  296. package/dist/astro/routes/api/taxonomies/bulk-tag.mjs +36 -35
  297. package/dist/astro/routes/api/taxonomies/bulk-tag.mjs.map +1 -1
  298. package/dist/astro/routes/api/taxonomies/index.mjs +23 -23
  299. package/dist/astro/routes/api/themes/preview.mjs +6 -6
  300. package/dist/astro/routes/api/typegen.mjs +8 -8
  301. package/dist/astro/routes/api/visual-editing/action-token.mjs +6 -6
  302. package/dist/astro/routes/api/visual-editing/content/_collection_/_id_/publish.mjs +19 -19
  303. package/dist/astro/routes/api/visual-editing/toolbar-labels.mjs +4 -4
  304. package/dist/astro/routes/api/well-known/auth.mjs +1 -1
  305. package/dist/astro/routes/api/well-known/oauth-authorization-server.mjs +2 -2
  306. package/dist/astro/routes/api/well-known/oauth-protected-resource.mjs +2 -2
  307. package/dist/astro/routes/api/widget-areas/_name_/reorder.mjs +16 -16
  308. package/dist/astro/routes/api/widget-areas/_name_/widgets/_id_.mjs +19 -19
  309. package/dist/astro/routes/api/widget-areas/_name_/widgets.mjs +19 -19
  310. package/dist/astro/routes/api/widget-areas/_name_.mjs +9 -9
  311. package/dist/astro/routes/api/widget-areas/index.mjs +19 -19
  312. package/dist/astro/routes/api/widget-components.mjs +5 -5
  313. package/dist/astro/routes/robots.txt.mjs +6 -6
  314. package/dist/astro/routes/sitemap-_collection_.xml.mjs +9 -9
  315. package/dist/astro/routes/sitemap.xml.mjs +7 -7
  316. package/dist/astro/types.d.mts +28 -18
  317. package/dist/astro/types.d.mts.map +1 -1
  318. package/dist/audit-CrgmE9LE.mjs +127 -0
  319. package/dist/audit-CrgmE9LE.mjs.map +1 -0
  320. package/dist/auth/providers/github.d.mts +1 -1
  321. package/dist/auth/providers/google.d.mts +1 -1
  322. package/dist/authoritative-records-C2YzIdbu.mjs +5172 -0
  323. package/dist/authoritative-records-C2YzIdbu.mjs.map +1 -0
  324. package/dist/authorize-WgdKF8QY.mjs +49 -0
  325. package/dist/authorize-WgdKF8QY.mjs.map +1 -0
  326. package/dist/backup-Ck8_lMO3.mjs +246 -0
  327. package/dist/backup-Ck8_lMO3.mjs.map +1 -0
  328. package/dist/block-types-BQ90asVI.mjs +132 -0
  329. package/dist/block-types-BQ90asVI.mjs.map +1 -0
  330. package/dist/block-values-ACFqgB1D.mjs +175 -0
  331. package/dist/block-values-ACFqgB1D.mjs.map +1 -0
  332. package/dist/bundle-Db1iNMv_.mjs +667 -0
  333. package/dist/bundle-Db1iNMv_.mjs.map +1 -0
  334. package/dist/byline-BayaYGoj.mjs +909 -0
  335. package/dist/byline-BayaYGoj.mjs.map +1 -0
  336. package/dist/byline-fields-B8HH-35f.mjs +254 -0
  337. package/dist/byline-fields-B8HH-35f.mjs.map +1 -0
  338. package/dist/byline-fields-hMPjf6Eu.mjs +123 -0
  339. package/dist/byline-fields-hMPjf6Eu.mjs.map +1 -0
  340. package/dist/byline-registry-B_EK_TQf.mjs +406 -0
  341. package/dist/byline-registry-B_EK_TQf.mjs.map +1 -0
  342. package/dist/bylines-DFAaFXWi.mjs +214 -0
  343. package/dist/bylines-DFAaFXWi.mjs.map +1 -0
  344. package/dist/bylines-DkIxUxmr.mjs +232 -0
  345. package/dist/bylines-DkIxUxmr.mjs.map +1 -0
  346. package/dist/cache-DkvhQ8XE.mjs +108 -0
  347. package/dist/cache-DkvhQ8XE.mjs.map +1 -0
  348. package/dist/canonical-CcSuuTlH.mjs +174 -0
  349. package/dist/canonical-CcSuuTlH.mjs.map +1 -0
  350. package/dist/capture-triggers-DJEoOTOq.mjs +362 -0
  351. package/dist/capture-triggers-DJEoOTOq.mjs.map +1 -0
  352. package/dist/challenge-store-CvBl81AQ.mjs +51 -0
  353. package/dist/challenge-store-CvBl81AQ.mjs.map +1 -0
  354. package/dist/checksum-CClweQzI.mjs +162 -0
  355. package/dist/checksum-CClweQzI.mjs.map +1 -0
  356. package/dist/chrome-tags-D5caJwwp.mjs +24 -0
  357. package/dist/chrome-tags-D5caJwwp.mjs.map +1 -0
  358. package/dist/chunks-DwBaj8aT.mjs +25 -0
  359. package/dist/chunks-DwBaj8aT.mjs.map +1 -0
  360. package/dist/cli/index.mjs +374 -761
  361. package/dist/cli/index.mjs.map +1 -1
  362. package/dist/client/cf-access.d.mts +1 -1
  363. package/dist/client/index.d.mts +18 -18
  364. package/dist/client/index.mjs +2 -2
  365. package/dist/collection-deletion-CLCdXsnV.mjs +436 -0
  366. package/dist/collection-deletion-CLCdXsnV.mjs.map +1 -0
  367. package/dist/collection-deletion-processor-hNw8x01F.mjs +217 -0
  368. package/dist/collection-deletion-processor-hNw8x01F.mjs.map +1 -0
  369. package/dist/collection-slugs-cache-CUuiduLq.mjs +85 -0
  370. package/dist/collection-slugs-cache-CUuiduLq.mjs.map +1 -0
  371. package/dist/comment-D2uvL63j.mjs +313 -0
  372. package/dist/comment-D2uvL63j.mjs.map +1 -0
  373. package/dist/comment-reaction-DevUuzg4.mjs +85 -0
  374. package/dist/comment-reaction-DevUuzg4.mjs.map +1 -0
  375. package/dist/comments-Cq0s7_hO.mjs +195 -0
  376. package/dist/comments-Cq0s7_hO.mjs.map +1 -0
  377. package/dist/comments-M4EDYAHw.mjs +99 -0
  378. package/dist/comments-M4EDYAHw.mjs.map +1 -0
  379. package/dist/components-CuIGwXMs.mjs +108 -0
  380. package/dist/components-CuIGwXMs.mjs.map +1 -0
  381. package/dist/config-52Ea5IWt.d.mts +39 -0
  382. package/dist/config-52Ea5IWt.d.mts.map +1 -0
  383. package/dist/config-CCz3xOLc.mjs +242 -0
  384. package/dist/config-CCz3xOLc.mjs.map +1 -0
  385. package/dist/config-D3d5Qudq.d.mts +6669 -0
  386. package/dist/config-D3d5Qudq.d.mts.map +1 -0
  387. package/dist/content-CbnufDsM.mjs +2018 -0
  388. package/dist/content-CbnufDsM.mjs.map +1 -0
  389. package/dist/content-list-query-D_7B1FE5.d.mts +26 -0
  390. package/dist/content-list-query-D_7B1FE5.d.mts.map +1 -0
  391. package/dist/content-policy-CYu6K1KB.mjs +46 -0
  392. package/dist/content-policy-CYu6K1KB.mjs.map +1 -0
  393. package/dist/content-repair-DlDUgFGp.mjs +442 -0
  394. package/dist/content-repair-DlDUgFGp.mjs.map +1 -0
  395. package/dist/context-CGQLA1-a.mjs +1922 -0
  396. package/dist/context-CGQLA1-a.mjs.map +1 -0
  397. package/dist/cron-c4D5C5Fx.mjs +284 -0
  398. package/dist/cron-c4D5C5Fx.mjs.map +1 -0
  399. package/dist/dashboard-CBq9kmOn.mjs +151 -0
  400. package/dist/dashboard-CBq9kmOn.mjs.map +1 -0
  401. package/dist/db/index.d.mts +3 -3
  402. package/dist/db/index.mjs +1 -1
  403. package/dist/db/libsql-migrations.d.mts +1 -1
  404. package/dist/db/libsql-migrations.mjs +4 -4
  405. package/dist/db/libsql.d.mts +1 -1
  406. package/dist/db/postgres-migrations.d.mts +1 -1
  407. package/dist/db/postgres-migrations.mjs +4 -4
  408. package/dist/db/postgres.d.mts +1 -1
  409. package/dist/db/sqlite-migrations.d.mts +1 -1
  410. package/dist/db/sqlite-migrations.mjs +4 -4
  411. package/dist/db/sqlite.d.mts +1 -1
  412. package/dist/db/sqlite.mjs +1 -1
  413. package/dist/default-DPsys51U.mjs +81 -0
  414. package/dist/default-DPsys51U.mjs.map +1 -0
  415. package/dist/deferred-tasks-CZ7rzBdo.d.mts +9 -0
  416. package/dist/deferred-tasks-CZ7rzBdo.d.mts.map +1 -0
  417. package/dist/dev-typegen-HRxwLRcT.mjs +29 -0
  418. package/dist/dev-typegen-HRxwLRcT.mjs.map +1 -0
  419. package/dist/device-flow-OcSqE9uY.mjs +521 -0
  420. package/dist/device-flow-OcSqE9uY.mjs.map +1 -0
  421. package/dist/digest-DVZ--cE9.mjs +194 -0
  422. package/dist/digest-DVZ--cE9.mjs.map +1 -0
  423. package/dist/direct-executor-DyjAqkpT.mjs +104 -0
  424. package/dist/direct-executor-DyjAqkpT.mjs.map +1 -0
  425. package/dist/dist-FPR93_xf.mjs +810 -0
  426. package/dist/dist-FPR93_xf.mjs.map +1 -0
  427. package/dist/email-console-DyQIgEnz.mjs +50 -0
  428. package/dist/email-console-DyQIgEnz.mjs.map +1 -0
  429. package/dist/email-locale-BYb16rVd.mjs +25 -0
  430. package/dist/email-locale-BYb16rVd.mjs.map +1 -0
  431. package/dist/emdash-runtime-CrzxJFmF.mjs +4214 -0
  432. package/dist/emdash-runtime-CrzxJFmF.mjs.map +1 -0
  433. package/dist/enrich-DBtCncE2.mjs +194 -0
  434. package/dist/enrich-DBtCncE2.mjs.map +1 -0
  435. package/dist/entry-lock-BN5y4YbO.d.mts +4481 -0
  436. package/dist/entry-lock-BN5y4YbO.d.mts.map +1 -0
  437. package/dist/entry-lock-BaRBHCsH.mjs +1173 -0
  438. package/dist/entry-lock-BaRBHCsH.mjs.map +1 -0
  439. package/dist/entry-lock-C6NcnZPV.mjs +163 -0
  440. package/dist/entry-lock-C6NcnZPV.mjs.map +1 -0
  441. package/dist/entry-locks-BTyQLdbC.mjs +167 -0
  442. package/dist/entry-locks-BTyQLdbC.mjs.map +1 -0
  443. package/dist/error-BfsNNrIE.mjs +90 -0
  444. package/dist/error-BfsNNrIE.mjs.map +1 -0
  445. package/dist/errors-BN1QAnEY.mjs +460 -0
  446. package/dist/errors-BN1QAnEY.mjs.map +1 -0
  447. package/dist/errors-Bt3goF8I.mjs +120 -0
  448. package/dist/errors-Bt3goF8I.mjs.map +1 -0
  449. package/dist/escape-BveidMa2.mjs +9 -0
  450. package/dist/escape-BveidMa2.mjs.map +1 -0
  451. package/dist/fence-Bb_IbCxI.mjs +162 -0
  452. package/dist/fence-Bb_IbCxI.mjs.map +1 -0
  453. package/dist/field-defs-cache-CsZctvbu.mjs +77 -0
  454. package/dist/field-defs-cache-CsZctvbu.mjs.map +1 -0
  455. package/dist/field-map-6m9rF49t.mjs +83 -0
  456. package/dist/field-map-6m9rF49t.mjs.map +1 -0
  457. package/dist/focal-point-CZ3d1wK5.mjs +23 -0
  458. package/dist/focal-point-CZ3d1wK5.mjs.map +1 -0
  459. package/dist/fts-manager-CCaZTp8y.mjs +443 -0
  460. package/dist/fts-manager-CCaZTp8y.mjs.map +1 -0
  461. package/dist/gc-xowRjczI.mjs +75 -0
  462. package/dist/gc-xowRjczI.mjs.map +1 -0
  463. package/dist/hash-COVK27Pc.mjs +37 -0
  464. package/dist/hash-COVK27Pc.mjs.map +1 -0
  465. package/dist/hook-result-CYSk0XFe.d.mts +31 -0
  466. package/dist/hook-result-CYSk0XFe.d.mts.map +1 -0
  467. package/dist/hreflang-CChPV7jx.mjs +105 -0
  468. package/dist/hreflang-CChPV7jx.mjs.map +1 -0
  469. package/dist/hreflang-DRslq3QI.d.mts +50 -0
  470. package/dist/hreflang-DRslq3QI.d.mts.map +1 -0
  471. package/dist/http-route-dispatch-CAdp2onn.mjs +339 -0
  472. package/dist/http-route-dispatch-CAdp2onn.mjs.map +1 -0
  473. package/dist/identity-NVTOOQyq.mjs +35 -0
  474. package/dist/identity-NVTOOQyq.mjs.map +1 -0
  475. package/dist/import-wpSO2N0x.mjs +2020 -0
  476. package/dist/import-wpSO2N0x.mjs.map +1 -0
  477. package/dist/index-CDs2wq4X.d.mts +623 -0
  478. package/dist/index-CDs2wq4X.d.mts.map +1 -0
  479. package/dist/index.d.mts +24 -24
  480. package/dist/index.mjs +103 -101
  481. package/dist/install-finalization-D9R9R-W8.mjs +58 -0
  482. package/dist/install-finalization-D9R9R-W8.mjs.map +1 -0
  483. package/dist/keys-Bck6LBfF.mjs +61 -0
  484. package/dist/keys-Bck6LBfF.mjs.map +1 -0
  485. package/dist/kinds-CYmRESWj.mjs +974 -0
  486. package/dist/kinds-CYmRESWj.mjs.map +1 -0
  487. package/dist/lifecycle-C815ZQfV.mjs +25 -0
  488. package/dist/lifecycle-C815ZQfV.mjs.map +1 -0
  489. package/dist/load-D99axixL.mjs +28 -0
  490. package/dist/load-D99axixL.mjs.map +1 -0
  491. package/dist/loader-CrRPfkHS.mjs +1197 -0
  492. package/dist/loader-CrRPfkHS.mjs.map +1 -0
  493. package/dist/loops-DMKlygqX.mjs +203 -0
  494. package/dist/loops-DMKlygqX.mjs.map +1 -0
  495. package/dist/manifest-builder-BQzCHNgB.mjs +189 -0
  496. package/dist/manifest-builder-BQzCHNgB.mjs.map +1 -0
  497. package/dist/manifest-schema-Ci2gmd0u.mjs +492 -0
  498. package/dist/manifest-schema-Ci2gmd0u.mjs.map +1 -0
  499. package/dist/media/image-endpoint.mjs +1 -1
  500. package/dist/media/index.d.mts +1 -1
  501. package/dist/media/index.mjs +4 -4
  502. package/dist/media/local-runtime.d.mts +14 -14
  503. package/dist/media/local-runtime.mjs +6 -6
  504. package/dist/media-BUQePMxP.mjs +373 -0
  505. package/dist/media-BUQePMxP.mjs.map +1 -0
  506. package/dist/media-DH8ibNlY.mjs +294 -0
  507. package/dist/media-DH8ibNlY.mjs.map +1 -0
  508. package/dist/media-OEIQ3bVc.mjs +408 -0
  509. package/dist/media-OEIQ3bVc.mjs.map +1 -0
  510. package/dist/media-allowlist-pYtaBA95.mjs +44 -0
  511. package/dist/media-allowlist-pYtaBA95.mjs.map +1 -0
  512. package/dist/media-folders-Bf8_s4de.mjs +210 -0
  513. package/dist/media-folders-Bf8_s4de.mjs.map +1 -0
  514. package/dist/media-url-C6klEuNd.mjs +43 -0
  515. package/dist/media-url-C6klEuNd.mjs.map +1 -0
  516. package/dist/media-usage-D7Y64m6v.mjs +1629 -0
  517. package/dist/media-usage-D7Y64m6v.mjs.map +1 -0
  518. package/dist/media-usage-activation-DrqbmgLA.mjs +78 -0
  519. package/dist/media-usage-activation-DrqbmgLA.mjs.map +1 -0
  520. package/dist/media-usage-work-DommYhYA.mjs +152 -0
  521. package/dist/media-usage-work-DommYhYA.mjs.map +1 -0
  522. package/dist/media-usage-work-HU63hNDu.mjs +586 -0
  523. package/dist/media-usage-work-HU63hNDu.mjs.map +1 -0
  524. package/dist/menus-BQfusWEC.mjs +3608 -0
  525. package/dist/menus-BQfusWEC.mjs.map +1 -0
  526. package/dist/menus-BtwjQt5s.mjs +753 -0
  527. package/dist/menus-BtwjQt5s.mjs.map +1 -0
  528. package/dist/menus-p_M1V7J_.mjs +139 -0
  529. package/dist/menus-p_M1V7J_.mjs.map +1 -0
  530. package/dist/migrations/index.d.mts +1 -1
  531. package/dist/migrations/index.mjs +3 -3
  532. package/dist/mime-C94qBG-P.mjs +36 -0
  533. package/dist/mime-C94qBG-P.mjs.map +1 -0
  534. package/dist/mode-DpYW3w6U.mjs +23 -0
  535. package/dist/mode-DpYW3w6U.mjs.map +1 -0
  536. package/dist/node-sqlite-compat-pWFw0lcc.mjs +46 -0
  537. package/dist/node-sqlite-compat-pWFw0lcc.mjs.map +1 -0
  538. package/dist/normalize-DduyxBjf.mjs +191 -0
  539. package/dist/normalize-DduyxBjf.mjs.map +1 -0
  540. package/dist/oauth-authorization-DAXsH1H9.mjs +274 -0
  541. package/dist/oauth-authorization-DAXsH1H9.mjs.map +1 -0
  542. package/dist/oauth-clients-DENiDQri.mjs +266 -0
  543. package/dist/oauth-clients-DENiDQri.mjs.map +1 -0
  544. package/dist/oauth-state-store-y8mEYVq9.mjs +50 -0
  545. package/dist/oauth-state-store-y8mEYVq9.mjs.map +1 -0
  546. package/dist/oauth-user-lookup-CtTYAy-O.mjs +26 -0
  547. package/dist/oauth-user-lookup-CtTYAy-O.mjs.map +1 -0
  548. package/dist/object-cache/memory.d.mts +1 -1
  549. package/dist/options-BYa1FgIM.d.mts +81 -0
  550. package/dist/options-BYa1FgIM.d.mts.map +1 -0
  551. package/dist/page/index.d.mts +2 -2
  552. package/dist/page/index.mjs +5 -5
  553. package/dist/parse-CORGGhHf.mjs +81 -0
  554. package/dist/parse-CORGGhHf.mjs.map +1 -0
  555. package/dist/parse-avNM1xWV.d.mts +168 -0
  556. package/dist/parse-avNM1xWV.d.mts.map +1 -0
  557. package/dist/passkey-config-Dih5YeIS.mjs +46 -0
  558. package/dist/passkey-config-Dih5YeIS.mjs.map +1 -0
  559. package/dist/paths-d51RFm8M.mjs +77 -0
  560. package/dist/paths-d51RFm8M.mjs.map +1 -0
  561. package/dist/patterns-CoqlXUvk.mjs +145 -0
  562. package/dist/patterns-CoqlXUvk.mjs.map +1 -0
  563. package/dist/placeholder-D2aksPMF.d.mts +306 -0
  564. package/dist/placeholder-D2aksPMF.d.mts.map +1 -0
  565. package/dist/plan-DqeZKuaR.mjs +135 -0
  566. package/dist/plan-DqeZKuaR.mjs.map +1 -0
  567. package/dist/plugin-test-runtime.d.mts +14 -14
  568. package/dist/plugin-test-runtime.mjs +110 -107
  569. package/dist/plugin-types.d.mts +2 -2
  570. package/dist/plugin-utils.d.mts +12 -12
  571. package/dist/plugins/adapt-sandbox-entry.d.mts +12 -12
  572. package/dist/plugins/adapt-sandbox-entry.mjs +3 -3
  573. package/dist/plugins/host.d.mts +5 -5
  574. package/dist/plugins/host.mjs +42 -41
  575. package/dist/plugins-Bb7oqjQA.mjs +277 -0
  576. package/dist/plugins-Bb7oqjQA.mjs.map +1 -0
  577. package/dist/policy-BcEqut3n.mjs +45 -0
  578. package/dist/policy-BcEqut3n.mjs.map +1 -0
  579. package/dist/portable-text-DXE8ymtD.mjs +307 -0
  580. package/dist/portable-text-DXE8ymtD.mjs.map +1 -0
  581. package/dist/preview-DEDWbwA_.mjs +107 -0
  582. package/dist/preview-DEDWbwA_.mjs.map +1 -0
  583. package/dist/protocol-BJbTzvwl.d.mts +61 -0
  584. package/dist/protocol-BJbTzvwl.d.mts.map +1 -0
  585. package/dist/public-submission-D9c9S14m.mjs +250 -0
  586. package/dist/public-submission-D9c9S14m.mjs.map +1 -0
  587. package/dist/public-url-CIRe-2T6.mjs +101 -0
  588. package/dist/public-url-CIRe-2T6.mjs.map +1 -0
  589. package/dist/query-BzifXlPS.mjs +1156 -0
  590. package/dist/query-BzifXlPS.mjs.map +1 -0
  591. package/dist/query-OzMJ6vJP.mjs +41 -0
  592. package/dist/query-OzMJ6vJP.mjs.map +1 -0
  593. package/dist/rate-limit-Csp60Vik.mjs +120 -0
  594. package/dist/rate-limit-Csp60Vik.mjs.map +1 -0
  595. package/dist/receipt-B-aU4hpJ.mjs +43 -0
  596. package/dist/receipt-B-aU4hpJ.mjs.map +1 -0
  597. package/dist/redirect-CDSw1sU3.mjs +17 -0
  598. package/dist/redirect-CDSw1sU3.mjs.map +1 -0
  599. package/dist/redirect-D1ArbO85.mjs +411 -0
  600. package/dist/redirect-D1ArbO85.mjs.map +1 -0
  601. package/dist/redirects-BjTwDTsV.mjs +148 -0
  602. package/dist/redirects-BjTwDTsV.mjs.map +1 -0
  603. package/dist/redirects-Ck50kH3n.mjs +446 -0
  604. package/dist/redirects-Ck50kH3n.mjs.map +1 -0
  605. package/dist/registry/testing.mjs +3 -3
  606. package/dist/registry-CFcNCayZ.mjs +6754 -0
  607. package/dist/registry-CFcNCayZ.mjs.map +1 -0
  608. package/dist/relations-Cfaa1fDl.mjs +776 -0
  609. package/dist/relations-Cfaa1fDl.mjs.map +1 -0
  610. package/dist/request-cache-iHRlHx1d.mjs +104 -0
  611. package/dist/request-cache-iHRlHx1d.mjs.map +1 -0
  612. package/dist/request-context.d.mts +1 -1
  613. package/dist/request-meta-D47mqyev.mjs +141 -0
  614. package/dist/request-meta-D47mqyev.mjs.map +1 -0
  615. package/dist/resolve-BPE8sMvx.mjs +99 -0
  616. package/dist/resolve-BPE8sMvx.mjs.map +1 -0
  617. package/dist/resolve-C0s1E_fH.mjs +199 -0
  618. package/dist/resolve-C0s1E_fH.mjs.map +1 -0
  619. package/dist/revision-j1p4-bOj.mjs +302 -0
  620. package/dist/revision-j1p4-bOj.mjs.map +1 -0
  621. package/dist/route-wire-C9PJV9aL.mjs +197 -0
  622. package/dist/route-wire-C9PJV9aL.mjs.map +1 -0
  623. package/dist/routes-lyYw0mMf.mjs +272 -0
  624. package/dist/routes-lyYw0mMf.mjs.map +1 -0
  625. package/dist/runner-B3eyB9Gb.mjs +6121 -0
  626. package/dist/runner-B3eyB9Gb.mjs.map +1 -0
  627. package/dist/runner-DoYH2Jcu.d.mts +68 -0
  628. package/dist/runner-DoYH2Jcu.d.mts.map +1 -0
  629. package/dist/runtime.d.mts +13 -13
  630. package/dist/runtime.mjs +3 -3
  631. package/dist/schema-BAayK46S.mjs +13 -0
  632. package/dist/schema-BAayK46S.mjs.map +1 -0
  633. package/dist/schema-Gqcl-8G4.mjs +815 -0
  634. package/dist/schema-Gqcl-8G4.mjs.map +1 -0
  635. package/dist/scopes-BqPOKoKf.mjs +34 -0
  636. package/dist/scopes-BqPOKoKf.mjs.map +1 -0
  637. package/dist/search-YJKPIEV6.mjs +448 -0
  638. package/dist/search-YJKPIEV6.mjs.map +1 -0
  639. package/dist/sections-BR_e-wK5.mjs +346 -0
  640. package/dist/sections-BR_e-wK5.mjs.map +1 -0
  641. package/dist/seed/index.d.mts +2 -2
  642. package/dist/seed/index.mjs +37 -31
  643. package/dist/seo/index.d.mts +3 -3
  644. package/dist/seo/index.mjs +22 -21
  645. package/dist/seo/index.mjs.map +1 -1
  646. package/dist/seo-Dsj8hy3j.mjs +114 -0
  647. package/dist/seo-Dsj8hy3j.mjs.map +1 -0
  648. package/dist/seo-XvH4LNNp.mjs +133 -0
  649. package/dist/seo-XvH4LNNp.mjs.map +1 -0
  650. package/dist/service-BsVG05gS.mjs +150 -0
  651. package/dist/service-BsVG05gS.mjs.map +1 -0
  652. package/dist/session-user-DgKbYrlj.mjs +51 -0
  653. package/dist/session-user-DgKbYrlj.mjs.map +1 -0
  654. package/dist/settings-CNPUntkh.mjs +51 -0
  655. package/dist/settings-CNPUntkh.mjs.map +1 -0
  656. package/dist/settings-D5EHi0Tk.mjs +439 -0
  657. package/dist/settings-D5EHi0Tk.mjs.map +1 -0
  658. package/dist/settings-DSfE7wOa.mjs +61 -0
  659. package/dist/settings-DSfE7wOa.mjs.map +1 -0
  660. package/dist/setup-complete-B8W8sJ9v.mjs +26 -0
  661. package/dist/setup-complete-B8W8sJ9v.mjs.map +1 -0
  662. package/dist/setup-nonce-DnSBP260.mjs +25 -0
  663. package/dist/setup-nonce-DnSBP260.mjs.map +1 -0
  664. package/dist/site-settings-NGzdrt7O.mjs +50 -0
  665. package/dist/site-settings-NGzdrt7O.mjs.map +1 -0
  666. package/dist/site-url-D6JB7tLW.mjs +16 -0
  667. package/dist/site-url-D6JB7tLW.mjs.map +1 -0
  668. package/dist/snapshot-CdcwwWAf.mjs +414 -0
  669. package/dist/snapshot-CdcwwWAf.mjs.map +1 -0
  670. package/dist/ssrf-Dv0_tRpo.mjs +406 -0
  671. package/dist/ssrf-Dv0_tRpo.mjs.map +1 -0
  672. package/dist/stage-CUjhED3P.mjs +662 -0
  673. package/dist/stage-CUjhED3P.mjs.map +1 -0
  674. package/dist/staged-C36IWXff.mjs +659 -0
  675. package/dist/staged-C36IWXff.mjs.map +1 -0
  676. package/dist/state-CKouMCSY.mjs +153 -0
  677. package/dist/state-CKouMCSY.mjs.map +1 -0
  678. package/dist/status-lzyj4Uu7.mjs +30 -0
  679. package/dist/status-lzyj4Uu7.mjs.map +1 -0
  680. package/dist/storage/local.d.mts +1 -1
  681. package/dist/storage/local.mjs +1 -1
  682. package/dist/storage/s3.d.mts +1 -1
  683. package/dist/storage/s3.mjs +1 -1
  684. package/dist/storage-query-B-cWcTjJ.d.mts +1594 -0
  685. package/dist/storage-query-B-cWcTjJ.d.mts.map +1 -0
  686. package/dist/tar-DsTXX6ch.mjs +449 -0
  687. package/dist/tar-DsTXX6ch.mjs.map +1 -0
  688. package/dist/target-DLQCwp_Z.mjs +27 -0
  689. package/dist/target-DLQCwp_Z.mjs.map +1 -0
  690. package/dist/taxonomies-BlAjr4BL.mjs +697 -0
  691. package/dist/taxonomies-BlAjr4BL.mjs.map +1 -0
  692. package/dist/taxonomies-Byyo7LOZ.mjs +939 -0
  693. package/dist/taxonomies-Byyo7LOZ.mjs.map +1 -0
  694. package/dist/taxonomy-CKDwM61Y.mjs +525 -0
  695. package/dist/taxonomy-CKDwM61Y.mjs.map +1 -0
  696. package/dist/tokens-BojXlk49.mjs +171 -0
  697. package/dist/tokens-BojXlk49.mjs.map +1 -0
  698. package/dist/transaction-DLPQWik1.mjs +29 -0
  699. package/dist/transaction-DLPQWik1.mjs.map +1 -0
  700. package/dist/transfer-XSTh2BCr.mjs +8706 -0
  701. package/dist/transfer-XSTh2BCr.mjs.map +1 -0
  702. package/dist/transfer-download-DkoCDA9d.mjs +33 -0
  703. package/dist/transfer-download-DkoCDA9d.mjs.map +1 -0
  704. package/dist/transfer-iQ26J-RT.mjs +166 -0
  705. package/dist/transfer-iQ26J-RT.mjs.map +1 -0
  706. package/dist/transformations-C7RQabKQ.mjs +196 -0
  707. package/dist/transformations-C7RQabKQ.mjs.map +1 -0
  708. package/dist/transport-D3RulfD6.mjs +136 -0
  709. package/dist/transport-D3RulfD6.mjs.map +1 -0
  710. package/dist/transport-DhlZlf4D.d.mts +42 -0
  711. package/dist/transport-DhlZlf4D.d.mts.map +1 -0
  712. package/dist/trusted-proxy-B6ECOZJc.mjs +51 -0
  713. package/dist/trusted-proxy-B6ECOZJc.mjs.map +1 -0
  714. package/dist/turnstile-lqUiY7lP.mjs +53 -0
  715. package/dist/turnstile-lqUiY7lP.mjs.map +1 -0
  716. package/dist/types-4Dn9bZhu.mjs +77 -0
  717. package/dist/types-4Dn9bZhu.mjs.map +1 -0
  718. package/dist/types-5LSo7PPx.d.mts +85 -0
  719. package/dist/types-5LSo7PPx.d.mts.map +1 -0
  720. package/dist/types-BQ3hwYJT.d.mts +896 -0
  721. package/dist/types-BQ3hwYJT.d.mts.map +1 -0
  722. package/dist/types-BYEk7qo3.d.mts +198 -0
  723. package/dist/types-BYEk7qo3.d.mts.map +1 -0
  724. package/dist/types-CJKsWVFR.mjs +199 -0
  725. package/dist/types-CJKsWVFR.mjs.map +1 -0
  726. package/dist/types-Ca_w8mmY.d.mts +363 -0
  727. package/dist/types-Ca_w8mmY.d.mts.map +1 -0
  728. package/dist/types-CkE41ZAG.mjs +18 -0
  729. package/dist/types-CkE41ZAG.mjs.map +1 -0
  730. package/dist/types-D0aJW2uR.d.mts +1641 -0
  731. package/dist/types-D0aJW2uR.d.mts.map +1 -0
  732. package/dist/types-DbpN4Qto.d.mts +372 -0
  733. package/dist/types-DbpN4Qto.d.mts.map +1 -0
  734. package/dist/types-ILDI1sdY.mjs +16 -0
  735. package/dist/types-ILDI1sdY.mjs.map +1 -0
  736. package/dist/types-OC5c-edM.mjs +22 -0
  737. package/dist/types-OC5c-edM.mjs.map +1 -0
  738. package/dist/types-aOOxRSx6.mjs +103 -0
  739. package/dist/types-aOOxRSx6.mjs.map +1 -0
  740. package/dist/types-m1WbUffD.d.mts +198 -0
  741. package/dist/types-m1WbUffD.d.mts.map +1 -0
  742. package/dist/types-uxLoPBio.d.mts +124 -0
  743. package/dist/types-uxLoPBio.d.mts.map +1 -0
  744. package/dist/types-we5uR-tV.d.mts +287 -0
  745. package/dist/types-we5uR-tV.d.mts.map +1 -0
  746. package/dist/upload-attempts-DduMy6B0.mjs +32 -0
  747. package/dist/upload-attempts-DduMy6B0.mjs.map +1 -0
  748. package/dist/url-pattern-B3EwxAAk.mjs +33 -0
  749. package/dist/url-pattern-B3EwxAAk.mjs.map +1 -0
  750. package/dist/user-ElwQjTQT.mjs +171 -0
  751. package/dist/user-ElwQjTQT.mjs.map +1 -0
  752. package/dist/utils-BlAXmfOG.mjs +439 -0
  753. package/dist/utils-BlAXmfOG.mjs.map +1 -0
  754. package/dist/validate-CH0X5b2c.d.mts +468 -0
  755. package/dist/validate-CH0X5b2c.d.mts.map +1 -0
  756. package/dist/validate-CfgRpcjA.mjs +492 -0
  757. package/dist/validate-CfgRpcjA.mjs.map +1 -0
  758. package/dist/validation-DvYJtv4k.mjs +218 -0
  759. package/dist/validation-DvYJtv4k.mjs.map +1 -0
  760. package/dist/version-DgYjhTud.mjs +9 -0
  761. package/dist/version-DgYjhTud.mjs.map +1 -0
  762. package/dist/version-Dq71scUb.mjs +7 -0
  763. package/dist/version-Dq71scUb.mjs.map +1 -0
  764. package/dist/widgets-ChFIj0be.mjs +126 -0
  765. package/dist/widgets-ChFIj0be.mjs.map +1 -0
  766. package/dist/wxr-taxonomies-CBZMp2YX.mjs +372 -0
  767. package/dist/wxr-taxonomies-CBZMp2YX.mjs.map +1 -0
  768. package/dist/wxr-taxonomies-DlKDpWN1.d.mts +34 -0
  769. package/dist/wxr-taxonomies-DlKDpWN1.d.mts.map +1 -0
  770. package/dist/zod-generator-DmTKI-Ig.mjs +426 -0
  771. package/dist/zod-generator-DmTKI-Ig.mjs.map +1 -0
  772. package/package.json +7 -6
  773. package/src/api/handlers/content.ts +593 -16
  774. package/src/api/handlers/device-flow.ts +74 -21
  775. package/src/api/handlers/index.ts +1 -0
  776. package/src/api/handlers/manifest.ts +79 -5
  777. package/src/api/handlers/media-upload.ts +17 -71
  778. package/src/api/handlers/media.ts +97 -3
  779. package/src/api/handlers/relations.ts +638 -157
  780. package/src/api/handlers/revision.ts +30 -0
  781. package/src/api/handlers/schema.ts +403 -1
  782. package/src/api/handlers/snapshot.ts +257 -3
  783. package/src/api/handlers/staged-references.ts +142 -0
  784. package/src/api/handlers/validate-references.ts +146 -0
  785. package/src/api/schemas/content.ts +13 -0
  786. package/src/api/schemas/relations.ts +54 -44
  787. package/src/api/schemas/schema.ts +14 -0
  788. package/src/astro/integration/routes.ts +15 -19
  789. package/src/astro/integration/vite-config.ts +10 -4
  790. package/src/astro/middleware.ts +1 -0
  791. package/src/astro/routes/api/content/[collection]/[id]/references/[relation]/children.ts +11 -54
  792. package/src/astro/routes/api/content/[collection]/[id].ts +3 -1
  793. package/src/astro/routes/api/oauth/device/authorize.ts +33 -4
  794. package/src/astro/routes/api/relations/index.ts +4 -4
  795. package/src/astro/routes/api/schema/collections/[slug]/fields/[fieldSlug].ts +6 -2
  796. package/src/astro/routes/api/setup/index.ts +66 -23
  797. package/src/astro/routes/api/snapshot.ts +2 -1
  798. package/src/astro/types.ts +10 -0
  799. package/src/cleanup.ts +10 -0
  800. package/src/cli/commands/export-seed.ts +510 -89
  801. package/src/components/Columns.astro +3 -1
  802. package/src/components/Cover.astro +3 -1
  803. package/src/components/WidgetArea.astro +3 -2
  804. package/src/database/migrations/086_relations_structural.ts +197 -0
  805. package/src/database/migrations/087_reference_field_relations.ts +407 -0
  806. package/src/database/migrations/runner.ts +4 -0
  807. package/src/database/reference-backfill.ts +141 -0
  808. package/src/database/repositories/content.ts +43 -8
  809. package/src/database/repositories/media.ts +40 -1
  810. package/src/database/repositories/redirect.ts +17 -34
  811. package/src/database/repositories/relation.ts +620 -208
  812. package/src/database/repositories/revision.ts +16 -0
  813. package/src/database/repositories/types.ts +38 -0
  814. package/src/database/transaction.ts +12 -1
  815. package/src/database/types.ts +14 -5
  816. package/src/emdash-runtime.ts +114 -11
  817. package/src/index.ts +11 -0
  818. package/src/loader.ts +169 -22
  819. package/src/mcp/server.ts +13 -48
  820. package/src/query.ts +455 -25
  821. package/src/references/field-map.ts +115 -0
  822. package/src/references/resolve.ts +160 -0
  823. package/src/references/staged.ts +117 -0
  824. package/src/references/types.ts +16 -0
  825. package/src/registry/artifact-fetch.ts +45 -271
  826. package/src/schema/registry.ts +99 -24
  827. package/src/schema/types.ts +58 -0
  828. package/src/schema/zod-generator.ts +67 -1
  829. package/src/seed/apply.ts +841 -103
  830. package/src/seed/types.ts +36 -2
  831. package/src/seed/validate.ts +78 -2
  832. package/src/transfer/analyze/unique-keys.ts +3 -12
  833. package/src/transfer/analyze/validate.ts +65 -39
  834. package/src/transfer/analyze/values.ts +12 -1
  835. package/src/transfer/export/readers.ts +12 -8
  836. package/src/transfer/format/columns.ts +26 -6
  837. package/src/transfer/format/kinds.ts +21 -5
  838. package/src/transfer/import/context.ts +8 -1
  839. package/src/transfer/ops/package-index.ts +1 -1
  840. package/dist/action-token-DYwe4Pk0.mjs +0 -26
  841. package/dist/action-token-DYwe4Pk0.mjs.map +0 -1
  842. package/dist/activation-LOkDM5WT.mjs +0 -382
  843. package/dist/activation-LOkDM5WT.mjs.map +0 -1
  844. package/dist/adapters-B64LbYcB.d.mts +0 -171
  845. package/dist/adapters-B64LbYcB.d.mts.map +0 -1
  846. package/dist/allowed-origins-CHB8oZNM.mjs +0 -116
  847. package/dist/allowed-origins-CHB8oZNM.mjs.map +0 -1
  848. package/dist/api-cFFZpyS0.mjs +0 -4718
  849. package/dist/api-cFFZpyS0.mjs.map +0 -1
  850. package/dist/api-tokens-s4i4aUp_.mjs +0 -166
  851. package/dist/api-tokens-s4i4aUp_.mjs.map +0 -1
  852. package/dist/apply-CoT603H3.mjs +0 -1163
  853. package/dist/apply-CoT603H3.mjs.map +0 -1
  854. package/dist/approvals-CqMfNxak.mjs +0 -460
  855. package/dist/approvals-CqMfNxak.mjs.map +0 -1
  856. package/dist/artifact-fetch-DZMOGZ3-.mjs +0 -818
  857. package/dist/artifact-fetch-DZMOGZ3-.mjs.map +0 -1
  858. package/dist/astro/routes/api/relations/_id_/translations.d.mts +0 -8
  859. package/dist/astro/routes/api/relations/_id_/translations.d.mts.map +0 -1
  860. package/dist/astro/routes/api/relations/_id_/translations.mjs +0 -47
  861. package/dist/astro/routes/api/relations/_id_/translations.mjs.map +0 -1
  862. package/dist/audit-RfCugiSB.mjs +0 -127
  863. package/dist/audit-RfCugiSB.mjs.map +0 -1
  864. package/dist/authoritative-records-CoJvBXAD.mjs +0 -5172
  865. package/dist/authoritative-records-CoJvBXAD.mjs.map +0 -1
  866. package/dist/authorize-seCifOMJ.mjs +0 -49
  867. package/dist/authorize-seCifOMJ.mjs.map +0 -1
  868. package/dist/backup-CBu0LrXf.mjs +0 -246
  869. package/dist/backup-CBu0LrXf.mjs.map +0 -1
  870. package/dist/block-type-registry-DUI_3KxT.mjs +0 -6709
  871. package/dist/block-type-registry-DUI_3KxT.mjs.map +0 -1
  872. package/dist/block-types-BmZmLmAD.mjs +0 -132
  873. package/dist/block-types-BmZmLmAD.mjs.map +0 -1
  874. package/dist/block-values-C_VIPr5t.mjs +0 -175
  875. package/dist/block-values-C_VIPr5t.mjs.map +0 -1
  876. package/dist/byline-DYmkXqvo.mjs +0 -909
  877. package/dist/byline-DYmkXqvo.mjs.map +0 -1
  878. package/dist/byline-fields-D28AT-Fh.mjs +0 -123
  879. package/dist/byline-fields-D28AT-Fh.mjs.map +0 -1
  880. package/dist/byline-registry-gnKscbQX.mjs +0 -406
  881. package/dist/byline-registry-gnKscbQX.mjs.map +0 -1
  882. package/dist/bylines-BPwJqoYH.mjs +0 -232
  883. package/dist/bylines-BPwJqoYH.mjs.map +0 -1
  884. package/dist/bylines-ukLaYpVZ.mjs +0 -214
  885. package/dist/bylines-ukLaYpVZ.mjs.map +0 -1
  886. package/dist/cache-m7UEkRFV.mjs +0 -108
  887. package/dist/cache-m7UEkRFV.mjs.map +0 -1
  888. package/dist/canonical-YhEQezjg.mjs +0 -174
  889. package/dist/canonical-YhEQezjg.mjs.map +0 -1
  890. package/dist/capture-triggers-kJyl_yyM.mjs +0 -362
  891. package/dist/capture-triggers-kJyl_yyM.mjs.map +0 -1
  892. package/dist/challenge-store-ppU6Uv13.mjs +0 -51
  893. package/dist/challenge-store-ppU6Uv13.mjs.map +0 -1
  894. package/dist/checksum-B2IINIlN.mjs +0 -162
  895. package/dist/checksum-B2IINIlN.mjs.map +0 -1
  896. package/dist/chrome-tags-DApCQSIk.mjs +0 -24
  897. package/dist/chrome-tags-DApCQSIk.mjs.map +0 -1
  898. package/dist/chunks-Dms7Uxbt.mjs +0 -25
  899. package/dist/chunks-Dms7Uxbt.mjs.map +0 -1
  900. package/dist/collection-deletion-BIm28mo3.mjs +0 -436
  901. package/dist/collection-deletion-BIm28mo3.mjs.map +0 -1
  902. package/dist/collection-deletion-processor-Br6rxs3u.mjs +0 -217
  903. package/dist/collection-deletion-processor-Br6rxs3u.mjs.map +0 -1
  904. package/dist/collection-slugs-cache-CjGk__zp.mjs +0 -85
  905. package/dist/collection-slugs-cache-CjGk__zp.mjs.map +0 -1
  906. package/dist/comment-CrBl22OF.mjs +0 -313
  907. package/dist/comment-CrBl22OF.mjs.map +0 -1
  908. package/dist/comment-reaction-JEQ2Fpd8.mjs +0 -85
  909. package/dist/comment-reaction-JEQ2Fpd8.mjs.map +0 -1
  910. package/dist/comments-2ah9du9y.mjs +0 -195
  911. package/dist/comments-2ah9du9y.mjs.map +0 -1
  912. package/dist/comments-fHZ8ON9O.mjs +0 -99
  913. package/dist/comments-fHZ8ON9O.mjs.map +0 -1
  914. package/dist/components-CXbq7CSM.mjs +0 -108
  915. package/dist/components-CXbq7CSM.mjs.map +0 -1
  916. package/dist/config-5ii2haYu.d.mts +0 -6528
  917. package/dist/config-5ii2haYu.d.mts.map +0 -1
  918. package/dist/config-IhybvkIQ.mjs +0 -242
  919. package/dist/config-IhybvkIQ.mjs.map +0 -1
  920. package/dist/config-Py43JK9r.d.mts +0 -39
  921. package/dist/config-Py43JK9r.d.mts.map +0 -1
  922. package/dist/content-DFaIEDj9.mjs +0 -2281
  923. package/dist/content-DFaIEDj9.mjs.map +0 -1
  924. package/dist/content-list-query-Dra4Dalc.d.mts +0 -26
  925. package/dist/content-list-query-Dra4Dalc.d.mts.map +0 -1
  926. package/dist/content-policy-DFNw91-d.mjs +0 -46
  927. package/dist/content-policy-DFNw91-d.mjs.map +0 -1
  928. package/dist/content-repair-Q8IUrpLL.mjs +0 -442
  929. package/dist/content-repair-Q8IUrpLL.mjs.map +0 -1
  930. package/dist/context-BeGccdUX.mjs +0 -1921
  931. package/dist/context-BeGccdUX.mjs.map +0 -1
  932. package/dist/cron-7DCJwPXq.mjs +0 -284
  933. package/dist/cron-7DCJwPXq.mjs.map +0 -1
  934. package/dist/dashboard-DjrB-xxZ.mjs +0 -151
  935. package/dist/dashboard-DjrB-xxZ.mjs.map +0 -1
  936. package/dist/default-DQ6vsviu.mjs +0 -81
  937. package/dist/default-DQ6vsviu.mjs.map +0 -1
  938. package/dist/deferred-tasks-BPxXUB4x.d.mts +0 -9
  939. package/dist/deferred-tasks-BPxXUB4x.d.mts.map +0 -1
  940. package/dist/dev-typegen-CZaPLl3V.mjs +0 -29
  941. package/dist/dev-typegen-CZaPLl3V.mjs.map +0 -1
  942. package/dist/device-flow-CRd6DXmW.mjs +0 -466
  943. package/dist/device-flow-CRd6DXmW.mjs.map +0 -1
  944. package/dist/digest-BarSh-pN.mjs +0 -194
  945. package/dist/digest-BarSh-pN.mjs.map +0 -1
  946. package/dist/direct-executor-BmuFJJZV.mjs +0 -104
  947. package/dist/direct-executor-BmuFJJZV.mjs.map +0 -1
  948. package/dist/dist-BNwANFJR.mjs +0 -810
  949. package/dist/dist-BNwANFJR.mjs.map +0 -1
  950. package/dist/email-console-bJn3ctqA.mjs +0 -50
  951. package/dist/email-console-bJn3ctqA.mjs.map +0 -1
  952. package/dist/email-locale-CN6WAMx0.mjs +0 -25
  953. package/dist/email-locale-CN6WAMx0.mjs.map +0 -1
  954. package/dist/emdash-runtime-DAjghyEG.mjs +0 -4186
  955. package/dist/emdash-runtime-DAjghyEG.mjs.map +0 -1
  956. package/dist/enrich-Dl3kZ-lP.mjs +0 -194
  957. package/dist/enrich-Dl3kZ-lP.mjs.map +0 -1
  958. package/dist/entry-lock-BJYdBfXb.mjs +0 -1097
  959. package/dist/entry-lock-BJYdBfXb.mjs.map +0 -1
  960. package/dist/entry-lock-DHQOxN7R.mjs +0 -163
  961. package/dist/entry-lock-DHQOxN7R.mjs.map +0 -1
  962. package/dist/entry-lock-DVhCt49A.d.mts +0 -4368
  963. package/dist/entry-lock-DVhCt49A.d.mts.map +0 -1
  964. package/dist/entry-locks-D0foLdjQ.mjs +0 -167
  965. package/dist/entry-locks-D0foLdjQ.mjs.map +0 -1
  966. package/dist/error-CfvOHP0M.mjs +0 -90
  967. package/dist/error-CfvOHP0M.mjs.map +0 -1
  968. package/dist/errors-BF0_LFhW.mjs +0 -460
  969. package/dist/errors-BF0_LFhW.mjs.map +0 -1
  970. package/dist/errors-DgE1zJGG.mjs +0 -120
  971. package/dist/errors-DgE1zJGG.mjs.map +0 -1
  972. package/dist/escape-CuaZhZvL.mjs +0 -9
  973. package/dist/escape-CuaZhZvL.mjs.map +0 -1
  974. package/dist/fence-CMDXJYc_.mjs +0 -162
  975. package/dist/fence-CMDXJYc_.mjs.map +0 -1
  976. package/dist/field-defs-cache-HIgBbqZZ.mjs +0 -77
  977. package/dist/field-defs-cache-HIgBbqZZ.mjs.map +0 -1
  978. package/dist/focal-point-Gr34o-4o.mjs +0 -23
  979. package/dist/focal-point-Gr34o-4o.mjs.map +0 -1
  980. package/dist/fts-manager-S-K0laoS.mjs +0 -443
  981. package/dist/fts-manager-S-K0laoS.mjs.map +0 -1
  982. package/dist/gc-DjKY0Ay1.mjs +0 -75
  983. package/dist/gc-DjKY0Ay1.mjs.map +0 -1
  984. package/dist/hash-SDAW6zC-.mjs +0 -37
  985. package/dist/hash-SDAW6zC-.mjs.map +0 -1
  986. package/dist/hook-result-B5bXDgS2.d.mts +0 -31
  987. package/dist/hook-result-B5bXDgS2.d.mts.map +0 -1
  988. package/dist/hreflang-D5uNnsGJ.d.mts +0 -50
  989. package/dist/hreflang-D5uNnsGJ.d.mts.map +0 -1
  990. package/dist/hreflang-DMFBL2eb.mjs +0 -105
  991. package/dist/hreflang-DMFBL2eb.mjs.map +0 -1
  992. package/dist/http-route-dispatch-BitqzwMy.mjs +0 -339
  993. package/dist/http-route-dispatch-BitqzwMy.mjs.map +0 -1
  994. package/dist/identity-IyNWwXr6.mjs +0 -35
  995. package/dist/identity-IyNWwXr6.mjs.map +0 -1
  996. package/dist/import-C3JZplWq.mjs +0 -2020
  997. package/dist/import-C3JZplWq.mjs.map +0 -1
  998. package/dist/index-D-hdtLe8.d.mts +0 -623
  999. package/dist/index-D-hdtLe8.d.mts.map +0 -1
  1000. package/dist/install-finalization-DfM1fj5x.mjs +0 -58
  1001. package/dist/install-finalization-DfM1fj5x.mjs.map +0 -1
  1002. package/dist/keys-yxLm5l35.mjs +0 -61
  1003. package/dist/keys-yxLm5l35.mjs.map +0 -1
  1004. package/dist/kinds-CRu_T5T5.mjs +0 -961
  1005. package/dist/kinds-CRu_T5T5.mjs.map +0 -1
  1006. package/dist/lifecycle-BzeGPeQ-.mjs +0 -25
  1007. package/dist/lifecycle-BzeGPeQ-.mjs.map +0 -1
  1008. package/dist/load-XgJiE6_3.mjs +0 -28
  1009. package/dist/load-XgJiE6_3.mjs.map +0 -1
  1010. package/dist/loader-BzqeR1ZN.mjs +0 -1086
  1011. package/dist/loader-BzqeR1ZN.mjs.map +0 -1
  1012. package/dist/loops-BQSzv5Zn.mjs +0 -203
  1013. package/dist/loops-BQSzv5Zn.mjs.map +0 -1
  1014. package/dist/manifest-builder-B8zR-73J.mjs +0 -189
  1015. package/dist/manifest-builder-B8zR-73J.mjs.map +0 -1
  1016. package/dist/manifest-schema-CY3zng_M.mjs +0 -492
  1017. package/dist/manifest-schema-CY3zng_M.mjs.map +0 -1
  1018. package/dist/media-Pu1L6xir.mjs +0 -408
  1019. package/dist/media-Pu1L6xir.mjs.map +0 -1
  1020. package/dist/media-Qp5S3eH3.mjs +0 -355
  1021. package/dist/media-Qp5S3eH3.mjs.map +0 -1
  1022. package/dist/media-allowlist-BSoa9Vvm.mjs +0 -44
  1023. package/dist/media-allowlist-BSoa9Vvm.mjs.map +0 -1
  1024. package/dist/media-folders-BE0oo2eX.mjs +0 -210
  1025. package/dist/media-folders-BE0oo2eX.mjs.map +0 -1
  1026. package/dist/media-h7tOiDLj.mjs +0 -221
  1027. package/dist/media-h7tOiDLj.mjs.map +0 -1
  1028. package/dist/media-url-jArBpzIG.mjs +0 -43
  1029. package/dist/media-url-jArBpzIG.mjs.map +0 -1
  1030. package/dist/media-usage-My-Vi-ex.mjs +0 -1629
  1031. package/dist/media-usage-My-Vi-ex.mjs.map +0 -1
  1032. package/dist/media-usage-activation-HKp7zk7W.mjs +0 -78
  1033. package/dist/media-usage-activation-HKp7zk7W.mjs.map +0 -1
  1034. package/dist/media-usage-work-C2OZLCAd.mjs +0 -586
  1035. package/dist/media-usage-work-C2OZLCAd.mjs.map +0 -1
  1036. package/dist/media-usage-work-DwUNbgvS.mjs +0 -152
  1037. package/dist/media-usage-work-DwUNbgvS.mjs.map +0 -1
  1038. package/dist/menus-BM7BPLOb.mjs +0 -139
  1039. package/dist/menus-BM7BPLOb.mjs.map +0 -1
  1040. package/dist/menus-ITeAbcIF.mjs +0 -753
  1041. package/dist/menus-ITeAbcIF.mjs.map +0 -1
  1042. package/dist/menus-TsSGmSR4.mjs +0 -3608
  1043. package/dist/menus-TsSGmSR4.mjs.map +0 -1
  1044. package/dist/mime-ChLqYwDk.mjs +0 -36
  1045. package/dist/mime-ChLqYwDk.mjs.map +0 -1
  1046. package/dist/mode-CCuKXUci.mjs +0 -23
  1047. package/dist/mode-CCuKXUci.mjs.map +0 -1
  1048. package/dist/node-sqlite-compat-CONMsl-x.mjs +0 -46
  1049. package/dist/node-sqlite-compat-CONMsl-x.mjs.map +0 -1
  1050. package/dist/normalize-CO2P8-iE.mjs +0 -191
  1051. package/dist/normalize-CO2P8-iE.mjs.map +0 -1
  1052. package/dist/oauth-authorization-DlMIL5_h.mjs +0 -274
  1053. package/dist/oauth-authorization-DlMIL5_h.mjs.map +0 -1
  1054. package/dist/oauth-clients-Djq9r_KP.mjs +0 -266
  1055. package/dist/oauth-clients-Djq9r_KP.mjs.map +0 -1
  1056. package/dist/oauth-state-store-BbjnZXNC.mjs +0 -50
  1057. package/dist/oauth-state-store-BbjnZXNC.mjs.map +0 -1
  1058. package/dist/oauth-user-lookup-vue9a64A.mjs +0 -26
  1059. package/dist/oauth-user-lookup-vue9a64A.mjs.map +0 -1
  1060. package/dist/options-SQCHQCPH.d.mts +0 -81
  1061. package/dist/options-SQCHQCPH.d.mts.map +0 -1
  1062. package/dist/parse-CVgO-Qai.d.mts +0 -168
  1063. package/dist/parse-CVgO-Qai.d.mts.map +0 -1
  1064. package/dist/parse-DY6OD1j_.mjs +0 -81
  1065. package/dist/parse-DY6OD1j_.mjs.map +0 -1
  1066. package/dist/passkey-config-X_H8128a.mjs +0 -46
  1067. package/dist/passkey-config-X_H8128a.mjs.map +0 -1
  1068. package/dist/paths-JxokKIbr.mjs +0 -77
  1069. package/dist/paths-JxokKIbr.mjs.map +0 -1
  1070. package/dist/patterns-BhAvqO0S.mjs +0 -145
  1071. package/dist/patterns-BhAvqO0S.mjs.map +0 -1
  1072. package/dist/placeholder-MSEd8gty.d.mts +0 -306
  1073. package/dist/placeholder-MSEd8gty.d.mts.map +0 -1
  1074. package/dist/plan-xjcWrAah.mjs +0 -135
  1075. package/dist/plan-xjcWrAah.mjs.map +0 -1
  1076. package/dist/plugins-DUXUt8B9.mjs +0 -277
  1077. package/dist/plugins-DUXUt8B9.mjs.map +0 -1
  1078. package/dist/policy-CUvwAARc.mjs +0 -45
  1079. package/dist/policy-CUvwAARc.mjs.map +0 -1
  1080. package/dist/portable-text-5O_ZGUjB.mjs +0 -307
  1081. package/dist/portable-text-5O_ZGUjB.mjs.map +0 -1
  1082. package/dist/preview-CIUcPYr6.mjs +0 -107
  1083. package/dist/preview-CIUcPYr6.mjs.map +0 -1
  1084. package/dist/protocol-B97DZaFr.d.mts +0 -61
  1085. package/dist/protocol-B97DZaFr.d.mts.map +0 -1
  1086. package/dist/public-submission-BFBUrqst.mjs +0 -250
  1087. package/dist/public-submission-BFBUrqst.mjs.map +0 -1
  1088. package/dist/public-url-Bn7U0D7-.mjs +0 -101
  1089. package/dist/public-url-Bn7U0D7-.mjs.map +0 -1
  1090. package/dist/query-B48peoRT.mjs +0 -890
  1091. package/dist/query-B48peoRT.mjs.map +0 -1
  1092. package/dist/query-C4IH0uhR.mjs +0 -41
  1093. package/dist/query-C4IH0uhR.mjs.map +0 -1
  1094. package/dist/rate-limit-BZ6nybgc.mjs +0 -120
  1095. package/dist/rate-limit-BZ6nybgc.mjs.map +0 -1
  1096. package/dist/receipt-B4wJj5Jq.mjs +0 -43
  1097. package/dist/receipt-B4wJj5Jq.mjs.map +0 -1
  1098. package/dist/redirect-Cd1E7VUt.mjs +0 -17
  1099. package/dist/redirect-Cd1E7VUt.mjs.map +0 -1
  1100. package/dist/redirect-iJf5fltD.mjs +0 -415
  1101. package/dist/redirect-iJf5fltD.mjs.map +0 -1
  1102. package/dist/redirects-CYu1u1aK.mjs +0 -446
  1103. package/dist/redirects-CYu1u1aK.mjs.map +0 -1
  1104. package/dist/redirects-Cv9apQKj.mjs +0 -148
  1105. package/dist/redirects-Cv9apQKj.mjs.map +0 -1
  1106. package/dist/relation-M4NUCb0b.mjs +0 -334
  1107. package/dist/relation-M4NUCb0b.mjs.map +0 -1
  1108. package/dist/relations-CCif47Oq.mjs +0 -403
  1109. package/dist/relations-CCif47Oq.mjs.map +0 -1
  1110. package/dist/relations-CK9CYUyr.mjs +0 -310
  1111. package/dist/relations-CK9CYUyr.mjs.map +0 -1
  1112. package/dist/request-cache-DzLYKm_x.mjs +0 -104
  1113. package/dist/request-cache-DzLYKm_x.mjs.map +0 -1
  1114. package/dist/request-meta-sZXt3sRo.mjs +0 -141
  1115. package/dist/request-meta-sZXt3sRo.mjs.map +0 -1
  1116. package/dist/resolve-2WbQsCvT.mjs +0 -199
  1117. package/dist/resolve-2WbQsCvT.mjs.map +0 -1
  1118. package/dist/route-wire--1hLuACz.mjs +0 -197
  1119. package/dist/route-wire--1hLuACz.mjs.map +0 -1
  1120. package/dist/routes-CUsM40Cc.mjs +0 -272
  1121. package/dist/routes-CUsM40Cc.mjs.map +0 -1
  1122. package/dist/runner-1y4J9fJB.mjs +0 -5742
  1123. package/dist/runner-1y4J9fJB.mjs.map +0 -1
  1124. package/dist/runner-D5_LzKXI.d.mts +0 -68
  1125. package/dist/runner-D5_LzKXI.d.mts.map +0 -1
  1126. package/dist/schema-BABiRdsH.mjs +0 -13
  1127. package/dist/schema-BABiRdsH.mjs.map +0 -1
  1128. package/dist/schema-Du3MzCG0.mjs +0 -446
  1129. package/dist/schema-Du3MzCG0.mjs.map +0 -1
  1130. package/dist/scopes-Dbk-ElhT.mjs +0 -34
  1131. package/dist/scopes-Dbk-ElhT.mjs.map +0 -1
  1132. package/dist/search-Bt1PL1jf.mjs +0 -448
  1133. package/dist/search-Bt1PL1jf.mjs.map +0 -1
  1134. package/dist/sections-Ddptx_o9.mjs +0 -346
  1135. package/dist/sections-Ddptx_o9.mjs.map +0 -1
  1136. package/dist/seo-CZT2oLtT.mjs +0 -114
  1137. package/dist/seo-CZT2oLtT.mjs.map +0 -1
  1138. package/dist/seo-D5w3-Azy.mjs +0 -133
  1139. package/dist/seo-D5w3-Azy.mjs.map +0 -1
  1140. package/dist/service-DuykXPyW.mjs +0 -150
  1141. package/dist/service-DuykXPyW.mjs.map +0 -1
  1142. package/dist/session-user-BhaVp8w0.mjs +0 -51
  1143. package/dist/session-user-BhaVp8w0.mjs.map +0 -1
  1144. package/dist/settings-2xNYr90o.mjs +0 -51
  1145. package/dist/settings-2xNYr90o.mjs.map +0 -1
  1146. package/dist/settings-CgjRWGW9.mjs +0 -439
  1147. package/dist/settings-CgjRWGW9.mjs.map +0 -1
  1148. package/dist/settings-DYidIB26.mjs +0 -61
  1149. package/dist/settings-DYidIB26.mjs.map +0 -1
  1150. package/dist/setup-complete-bOogcHWG.mjs +0 -26
  1151. package/dist/setup-complete-bOogcHWG.mjs.map +0 -1
  1152. package/dist/setup-nonce-0EGuKM4s.mjs +0 -25
  1153. package/dist/setup-nonce-0EGuKM4s.mjs.map +0 -1
  1154. package/dist/site-settings-DOgRUoFX.mjs +0 -50
  1155. package/dist/site-settings-DOgRUoFX.mjs.map +0 -1
  1156. package/dist/site-url-BU_bbxwj.mjs +0 -16
  1157. package/dist/site-url-BU_bbxwj.mjs.map +0 -1
  1158. package/dist/snapshot-CugwUqKQ.mjs +0 -237
  1159. package/dist/snapshot-CugwUqKQ.mjs.map +0 -1
  1160. package/dist/ssrf-CJUnJymJ.mjs +0 -406
  1161. package/dist/ssrf-CJUnJymJ.mjs.map +0 -1
  1162. package/dist/stage-DgrBz_du.mjs +0 -662
  1163. package/dist/stage-DgrBz_du.mjs.map +0 -1
  1164. package/dist/state-DDiPySSG.mjs +0 -153
  1165. package/dist/state-DDiPySSG.mjs.map +0 -1
  1166. package/dist/status-DZKIG4a9.mjs +0 -30
  1167. package/dist/status-DZKIG4a9.mjs.map +0 -1
  1168. package/dist/storage-query-Bdv7A62k.d.mts +0 -1576
  1169. package/dist/storage-query-Bdv7A62k.d.mts.map +0 -1
  1170. package/dist/tar-_1AgTYFu.mjs +0 -449
  1171. package/dist/tar-_1AgTYFu.mjs.map +0 -1
  1172. package/dist/target-_7pn2Gbg.mjs +0 -27
  1173. package/dist/target-_7pn2Gbg.mjs.map +0 -1
  1174. package/dist/taxonomies-C1IwNe8Q.mjs +0 -697
  1175. package/dist/taxonomies-C1IwNe8Q.mjs.map +0 -1
  1176. package/dist/taxonomies-C_XMoRcX.mjs +0 -939
  1177. package/dist/taxonomies-C_XMoRcX.mjs.map +0 -1
  1178. package/dist/taxonomy-C3Fu1YeH.mjs +0 -525
  1179. package/dist/taxonomy-C3Fu1YeH.mjs.map +0 -1
  1180. package/dist/tokens-u78jETkX.mjs +0 -171
  1181. package/dist/tokens-u78jETkX.mjs.map +0 -1
  1182. package/dist/transaction-BcJO4Tmc.mjs +0 -29
  1183. package/dist/transaction-BcJO4Tmc.mjs.map +0 -1
  1184. package/dist/transfer-BhUCrgDc.mjs +0 -8675
  1185. package/dist/transfer-BhUCrgDc.mjs.map +0 -1
  1186. package/dist/transfer-DIGvR9Af.mjs +0 -166
  1187. package/dist/transfer-DIGvR9Af.mjs.map +0 -1
  1188. package/dist/transfer-download-Pml7RMio.mjs +0 -33
  1189. package/dist/transfer-download-Pml7RMio.mjs.map +0 -1
  1190. package/dist/transformations-9gfpwY65.mjs +0 -196
  1191. package/dist/transformations-9gfpwY65.mjs.map +0 -1
  1192. package/dist/transport-BIfH7_hx.d.mts +0 -42
  1193. package/dist/transport-BIfH7_hx.d.mts.map +0 -1
  1194. package/dist/transport-DKWIq53q.mjs +0 -136
  1195. package/dist/transport-DKWIq53q.mjs.map +0 -1
  1196. package/dist/trusted-proxy-tKiVtyTD.mjs +0 -51
  1197. package/dist/trusted-proxy-tKiVtyTD.mjs.map +0 -1
  1198. package/dist/turnstile-DpsoyOfg.mjs +0 -53
  1199. package/dist/turnstile-DpsoyOfg.mjs.map +0 -1
  1200. package/dist/types-B4sUC2p1.d.mts +0 -198
  1201. package/dist/types-B4sUC2p1.d.mts.map +0 -1
  1202. package/dist/types-B7Lmsh1E.d.mts +0 -887
  1203. package/dist/types-B7Lmsh1E.d.mts.map +0 -1
  1204. package/dist/types-BZakh7Ym.mjs +0 -22
  1205. package/dist/types-BZakh7Ym.mjs.map +0 -1
  1206. package/dist/types-B_CppEmv.d.mts +0 -264
  1207. package/dist/types-B_CppEmv.d.mts.map +0 -1
  1208. package/dist/types-BcrBrE6-.mjs +0 -159
  1209. package/dist/types-BcrBrE6-.mjs.map +0 -1
  1210. package/dist/types-BkUg2yHx.mjs +0 -92
  1211. package/dist/types-BkUg2yHx.mjs.map +0 -1
  1212. package/dist/types-CAZgq9fO.d.mts +0 -124
  1213. package/dist/types-CAZgq9fO.d.mts.map +0 -1
  1214. package/dist/types-Cd-O03VG.d.mts +0 -363
  1215. package/dist/types-Cd-O03VG.d.mts.map +0 -1
  1216. package/dist/types-Cr-Kg-3D.d.mts +0 -1641
  1217. package/dist/types-Cr-Kg-3D.d.mts.map +0 -1
  1218. package/dist/types-D2fvWd1i.d.mts +0 -359
  1219. package/dist/types-D2fvWd1i.d.mts.map +0 -1
  1220. package/dist/types-D7HUsguf.mjs +0 -77
  1221. package/dist/types-D7HUsguf.mjs.map +0 -1
  1222. package/dist/types-DA1Te3Oy.d.mts +0 -198
  1223. package/dist/types-DA1Te3Oy.d.mts.map +0 -1
  1224. package/dist/types-DhV6Q5bP.mjs +0 -18
  1225. package/dist/types-DhV6Q5bP.mjs.map +0 -1
  1226. package/dist/types-DnnVSl6Y.d.mts +0 -85
  1227. package/dist/types-DnnVSl6Y.d.mts.map +0 -1
  1228. package/dist/types-VT4-BugW.mjs +0 -16
  1229. package/dist/types-VT4-BugW.mjs.map +0 -1
  1230. package/dist/upload-attempts-B68ZGNu9.mjs +0 -32
  1231. package/dist/upload-attempts-B68ZGNu9.mjs.map +0 -1
  1232. package/dist/url-pattern-CCeZMGOh.mjs +0 -33
  1233. package/dist/url-pattern-CCeZMGOh.mjs.map +0 -1
  1234. package/dist/user-DDSL-sGw.mjs +0 -171
  1235. package/dist/user-DDSL-sGw.mjs.map +0 -1
  1236. package/dist/utils-DdhmO9w9.mjs +0 -439
  1237. package/dist/utils-DdhmO9w9.mjs.map +0 -1
  1238. package/dist/validate-CHosPEhs.mjs +0 -453
  1239. package/dist/validate-CHosPEhs.mjs.map +0 -1
  1240. package/dist/validate-CM79QXYE.d.mts +0 -432
  1241. package/dist/validate-CM79QXYE.d.mts.map +0 -1
  1242. package/dist/validation-BFecQczG.mjs +0 -218
  1243. package/dist/validation-BFecQczG.mjs.map +0 -1
  1244. package/dist/version-BRZXVifl.mjs +0 -9
  1245. package/dist/version-BRZXVifl.mjs.map +0 -1
  1246. package/dist/version-DUQDHgrf.mjs +0 -7
  1247. package/dist/version-DUQDHgrf.mjs.map +0 -1
  1248. package/dist/widgets-WdV72brA.mjs +0 -126
  1249. package/dist/widgets-WdV72brA.mjs.map +0 -1
  1250. package/dist/wxr-taxonomies-BHTdqkmZ.d.mts +0 -34
  1251. package/dist/wxr-taxonomies-BHTdqkmZ.d.mts.map +0 -1
  1252. package/dist/wxr-taxonomies-DP6ESgMN.mjs +0 -372
  1253. package/dist/wxr-taxonomies-DP6ESgMN.mjs.map +0 -1
  1254. package/dist/zod-generator-D6uE4WiS.mjs +0 -389
  1255. package/dist/zod-generator-D6uE4WiS.mjs.map +0 -1
  1256. package/src/astro/routes/api/relations/[id]/translations.ts +0 -33
  1257. /package/dist/{api-tokens-CE1ECIg0.mjs → api-tokens-FaG1zPsj.mjs} +0 -0
  1258. /package/dist/{ssrf-DpBH7aOt.mjs → ssrf-DZOt8Qof.mjs} +0 -0
@@ -0,0 +1 @@
1
+ {"version":3,"file":"query-BzifXlPS.mjs","names":[],"sources":["../src/visual-editing/editable.ts","../src/query.ts"],"sourcesContent":["/**\n * Visual editing annotation system\n *\n * Creates Proxy objects that emit data-emdash-ref attributes when spread onto elements.\n */\n\nexport interface CMSAnnotation {\n\tcollection: string;\n\tid: string;\n\tfield?: string;\n\t/** Entry status — only present on entry-level annotations (not field-level) */\n\tstatus?: string;\n\t/** Whether the entry has unpublished draft changes */\n\thasDraft?: boolean;\n}\n\n/** The shape returned when spreading an edit annotation onto an element */\nexport interface FieldAnnotation {\n\t\"data-emdash-ref\": string;\n}\n\nexport interface EditableOptions {\n\t/** Entry status: \"draft\", \"published\", \"scheduled\" */\n\tstatus?: string;\n\t/** true when draftRevisionId exists and differs from liveRevisionId */\n\thasDraft?: boolean;\n}\n\n/**\n * Create an editable proxy for an entry.\n *\n * Usage:\n * - `{...entry.edit}` - entry-level annotation (includes status/hasDraft)\n * - `{...entry.edit.title}` - field-level annotation\n * - `{...entry.edit['nested.field']}` - nested field (bracket notation)\n */\nexport function createEditable(\n\tcollection: string,\n\tid: string,\n\toptions?: EditableOptions,\n): EditProxy {\n\tconst base: CMSAnnotation = {\n\t\tcollection,\n\t\tid,\n\t\t...(options?.status && { status: options.status }),\n\t\t...(options?.hasDraft && { hasDraft: true }),\n\t};\n\n\treturn new Proxy(\n\t\t{},\n\t\t{\n\t\t\tget(_, prop) {\n\t\t\t\tif (prop === \"toJSON\") return () => ({ \"data-emdash-ref\": JSON.stringify(base) });\n\t\t\t\tif (typeof prop === \"symbol\") return undefined;\n\n\t\t\t\t// data-emdash-ref access returns the entry-level string\n\t\t\t\tif (prop === \"data-emdash-ref\") return JSON.stringify(base);\n\n\t\t\t\t// Field-level: return a FieldAnnotation for the specific field\n\t\t\t\treturn {\n\t\t\t\t\t\"data-emdash-ref\": JSON.stringify({ ...base, field: String(prop) }),\n\t\t\t\t} satisfies FieldAnnotation;\n\t\t\t},\n\t\t\townKeys() {\n\t\t\t\treturn [\"data-emdash-ref\"];\n\t\t\t},\n\t\t\tgetOwnPropertyDescriptor(_, prop) {\n\t\t\t\tif (prop === \"data-emdash-ref\") {\n\t\t\t\t\treturn {\n\t\t\t\t\t\tconfigurable: true,\n\t\t\t\t\t\tenumerable: true,\n\t\t\t\t\t\tvalue: JSON.stringify(base),\n\t\t\t\t\t};\n\t\t\t\t}\n\t\t\t\treturn undefined;\n\t\t\t},\n\t\t},\n\t);\n}\n\n/**\n * Create a noop proxy for production mode.\n * Spreading this produces no attributes.\n */\nexport function createNoop(): EditProxy {\n\treturn new Proxy(\n\t\t{},\n\t\t{\n\t\t\tget(_, prop) {\n\t\t\t\tif (typeof prop === \"symbol\") return undefined;\n\t\t\t\t// All property access returns undefined in noop mode\n\t\t\t\treturn undefined;\n\t\t\t},\n\t\t\townKeys() {\n\t\t\t\treturn [];\n\t\t\t},\n\t\t\tgetOwnPropertyDescriptor() {\n\t\t\t\treturn undefined;\n\t\t\t},\n\t\t},\n\t);\n}\n\n/**\n * Visual editing proxy type.\n *\n * Spread directly onto elements for entry-level annotations: `{...entry.edit}`\n * Access a field for field-level annotations: `{...entry.edit.title}`\n *\n * In production, spreading produces no attributes (noop).\n */\nexport type EditProxy = {\n\treadonly [field: string]: Partial<FieldAnnotation>;\n};\n","/// <reference types=\"astro/client\" />\n/**\n * Query functions for EmDash content\n *\n * These wrap Astro's getLiveCollection/getLiveEntry with type filtering.\n * Use these instead of calling Astro's functions directly.\n *\n * Error handling follows Astro's pattern - returns { entries/entry, error }\n * so callers can gracefully handle errors (including 404s).\n *\n * Preview mode is handled implicitly via ALS request context —\n * no parameters needed. The middleware verifies the preview token\n * and sets the context; query functions read it automatically.\n *\n * The triple-slash directive above pulls in the ambient declaration for\n * `astro:content` (used by the dynamic imports below) so this source\n * file typechecks even when reached transitively by a sibling package\n * whose tsconfig doesn't list `astro/client` in `compilerOptions.types`.\n *\n * Note: the directive is stripped from the compiled output (`dist/*`)\n * by tsdown, so it does not propagate to downstream consumers of the\n * published package. Consumers are Astro sites and already provide their\n * own `astro/client` ambient surface anyway, so the runtime dynamic\n * import resolves there at typecheck time without our help.\n */\n\nimport { encodeCursor, type ContentSeo } from \"./database/repositories/types.js\";\nimport { getFallbackChain, getI18nConfig, isI18nEnabled } from \"./i18n/config.js\";\nimport {\n\tcreditsFromFoldedBylines,\n\tCURSOR_RAW_VALUES,\n\tFOLDED_BYLINES,\n\tFOLDED_BYLINES_EXIST,\n\tFOLDED_TERMS,\n\tloadPublishedDates,\n\ttype WhereRange,\n\ttype WhereValue,\n} from \"./loader.js\";\nimport {\n\tcachedQuery,\n\tcontentCacheNamespaces,\n\tcontentNamespaces,\n\tinvalidateSchemaObjectCache,\n} from \"./object-cache/index.js\";\nimport { primeSeoPanel } from \"./page/seo-panel.js\";\nimport type { ReferenceQuery, ReferenceSelection } from \"./references/types.js\";\nimport { requestCached } from \"./request-cache.js\";\nimport { getRequestContext } from \"./request-context.js\";\nimport { resetRegisteredCollectionsCache } from \"./schema/collection-slugs-cache.js\";\nimport { compileUrlPattern } from \"./schema/url-pattern.js\";\nimport type { TaxonomyTerm } from \"./taxonomies/types.js\";\nimport { isMissingColumnError, isMissingTableError } from \"./utils/db-errors.js\";\nimport {\n\tcreateEditable,\n\tcreateNoop,\n\ttype EditProxy,\n\ttype EditableOptions,\n} from \"./visual-editing/editable.js\";\n\n/**\n * Collection type registry for type-safe queries.\n *\n * This interface is extended by the generated emdash-env.d.ts file\n * to provide type inference for collection names and their data shapes.\n *\n * @example\n * ```ts\n * // In emdash-env.d.ts (generated):\n * declare module \"emdash\" {\n * interface EmDashCollections {\n * posts: { title: string; content: PortableTextBlock[]; };\n * pages: { title: string; body: PortableTextBlock[]; };\n * }\n * }\n *\n * // Then in your code:\n * const { entries } = await getEmDashCollection(\"posts\");\n * // entries[0].data.title is typed as string\n * ```\n */\n// eslint-disable-next-line @typescript-eslint/no-empty-object-type\nexport interface EmDashCollections {}\n\n/**\n * Helper type to infer the data type for a collection.\n * Returns the registered type if known, otherwise falls back to Record<string, unknown>.\n */\nexport type InferCollectionData<T extends string> = T extends keyof EmDashCollections\n\t? EmDashCollections[T]\n\t: Record<string, unknown>;\n\n/**\n * Reference type registry, the counterpart to {@link EmDashCollections}.\n *\n * Extended by the generated emdash-env.d.ts for every collection that has at\n * least one reference field bound to a relation, so a selection resolves to the\n * target collection's own interface.\n *\n * @example\n * ```ts\n * // In emdash-env.d.ts (generated):\n * declare module \"emdash\" {\n * interface EmDashCollectionReferences {\n * posts: { author: ReferencePage<Author>; related_posts: ReferencePage<Post> };\n * }\n * }\n *\n * // Then in your code:\n * const { entry } = await getEmDashEntry(\"posts\", slug, { references: { author: true } });\n * // entry.references.author.entries[0].data.name is typed as string\n * ```\n */\n// eslint-disable-next-line @typescript-eslint/no-empty-object-type\nexport interface EmDashCollectionReferences {}\n\n/**\n * Helper type to infer the reference shapes for a collection.\n * Returns the registered type if known, otherwise falls back to one\n * un-narrowed page per field slug.\n */\nexport type InferCollectionReferences<T extends string> = T extends keyof EmDashCollectionReferences\n\t? EmDashCollectionReferences[T]\n\t: ReferencePages;\n\n/**\n * What `getEmDashEntry`'s `references` option accepts for a collection: any\n * subset of its reference fields, or any field slug at all for a collection\n * with no generated entry.\n */\nexport type SelectableReferences<T extends string> = Partial<\n\tRecord<keyof InferCollectionReferences<T> & string, ReferenceQuery>\n>;\n\n/**\n * The `references` a selection produces: one page per field it named, and no\n * key for a field it did not, so a render reads `entry.references.author`\n * without a second optional check.\n */\nexport type SelectedReferences<T extends string, S> = Pick<\n\tInferCollectionReferences<T>,\n\tExtract<keyof S, keyof InferCollectionReferences<T>>\n>;\n\n/**\n * Sort direction\n */\nexport type SortDirection = \"asc\" | \"desc\";\n\n/**\n * Order by specification - field name to direction\n * @example { created_at: \"desc\" } - Sort by created_at descending\n * @example { title: \"asc\" } - Sort by title ascending\n * @example { published_at: \"desc\", title: \"asc\" } - Multi-field sort\n */\nexport type OrderBySpec = Record<string, SortDirection>;\n\nexport type { WhereRange, WhereValue };\nexport type { ReferenceQuery, ReferenceSelection };\n\n/**\n * Fields shared by every collection query, independent of pagination mode.\n *\n * Cursor and offset pagination are mutually exclusive, so they live on the\n * `CursorCollectionFilter` / `OffsetCollectionFilter` variants rather than\n * here. Use the {@link CollectionFilter} union for any value that may be\n * either.\n */\nexport interface CollectionFilterBase {\n\tstatus?: \"draft\" | \"published\" | \"archived\";\n\tlimit?: number;\n\t/**\n\t * Filter by field values, taxonomy terms, byline credits, or ranges.\n\t *\n\t * Taxonomy names are detected automatically and filtered via JOIN.\n\t * The reserved `byline` key filters by byline credit (any credit, not\n\t * just the primary one) via the `_emdash_content_bylines` junction\n\t * table; its value is one or more byline translation groups. This\n\t * matches co-authored entries, which `primary_byline_id` alone misses.\n\t * Other keys are treated as column filters on the content table.\n\t *\n\t * @example { category: 'news' } - Filter by taxonomy term\n\t * @example { category: ['news', 'featured'] } - Filter by multiple terms (OR)\n\t * @example { byline: '01HXYZ...' } - Entries credited to a byline (any position)\n\t * @example { byline: ['01HXYZ...', '01HABC...'] } - Credited to any of these bylines (OR)\n\t * @example { series: 'main' } - Exact match on a content field\n\t * @example { published_at: { gte: '2024-01-01', lt: '2025-01-01' } } - Date range\n\t */\n\twhere?: Record<string, WhereValue>;\n\t/**\n\t * Order results by field(s)\n\t * @default { created_at: \"desc\" }\n\t * @example { created_at: \"desc\" } - Sort by created_at descending (default)\n\t * @example { title: \"asc\" } - Sort by title ascending\n\t * @example { published_at: \"desc\", title: \"asc\" } - Multi-field sort\n\t */\n\torderBy?: OrderBySpec;\n\t/**\n\t * Filter by locale. When set, only returns entries in this locale.\n\t * Only relevant when i18n is configured.\n\t * @example \"en\" — English entries only\n\t * @example \"fr\" — French entries only\n\t */\n\tlocale?: string;\n}\n\n/** Keyset-paginated query filter. Cannot also carry an `offset`. */\nexport interface CursorCollectionFilter extends CollectionFilterBase {\n\t/**\n\t * Opaque cursor for keyset pagination.\n\t * Pass the `nextCursor` value from a previous result to fetch the next page.\n\t * @example\n\t * ```ts\n\t * const cursor = Astro.url.searchParams.get(\"cursor\") ?? undefined;\n\t * const { entries, nextCursor } = await getEmDashCollection(\"posts\", {\n\t * limit: 10,\n\t * cursor,\n\t * });\n\t * ```\n\t */\n\tcursor?: string;\n\toffset?: never;\n}\n\n/** Offset-paginated query filter. Cannot also carry a `cursor`. */\nexport interface OffsetCollectionFilter extends CollectionFilterBase {\n\t/**\n\t * Skip this many entries before returning results (offset pagination).\n\t *\n\t * Use with `limit` to render numbered archive routes like `/page/2`\n\t * without walking cursors or over-fetching from the start:\n\t *\n\t * ```ts\n\t * const perPage = 20;\n\t * const { entries, hasMore } = await getEmDashCollection(\"posts\", {\n\t * limit: perPage,\n\t * offset: (page - 1) * perPage,\n\t * orderBy: { published_at: \"desc\" },\n\t * });\n\t * ```\n\t *\n\t * Only a positive integer applies.\n\t */\n\toffset?: number;\n\tcursor?: never;\n}\n\n/**\n * Filter for `getEmDashCollection`.\n *\n * A union of the cursor and offset pagination variants: supplying both\n * `cursor` and `offset` is a compile-time error, since they are mutually\n * exclusive ways to express \"the next page\" (cursor wins at runtime).\n */\nexport type CollectionFilter = CursorCollectionFilter | OffsetCollectionFilter;\n\nexport interface ContentEntry<T = Record<string, unknown>, R = ReferencePages> {\n\tid: string;\n\tdata: T;\n\t/**\n\t * One page of each reference field the caller opted into, by field slug.\n\t * Absent unless `references` was passed to {@link getEmDashEntry}.\n\t */\n\treferences?: R;\n\t/** Visual editing annotations. Spread onto elements: {...entry.edit.title} */\n\tedit: EditProxy;\n}\n\n/**\n * One page of a reference field's selection: the entries it points at, in the\n * order the editor chose, plus the cursor for the next page when the field\n * holds more than the limit asked for.\n */\nexport interface ReferencePage<T = Record<string, unknown>> {\n\tentries: ContentEntry<T>[];\n\tnextCursor?: string;\n}\n\n/** The un-narrowed shape of `entry.references` — one page per field slug. */\nexport type ReferencePages = Record<string, ReferencePage>;\n\n/** A reference page with the error channel the standalone query returns. */\nexport interface ReferenceResult<T = Record<string, unknown>> extends ReferencePage<T> {\n\t/** Set only for actual errors; an unknown field or entry is an empty page. */\n\terror?: Error;\n\t/**\n\t * The rows this page read, for a route that caches the page it renders.\n\t * `getEmDashEntry({ references })` folds the first page's hint into the\n\t * entry's; a route that walks past it has to tag what it reads itself.\n\t */\n\tcacheHint?: CacheHint;\n}\n\n/** Cache hint returned by the content loader for route caching */\nexport interface CacheHint {\n\ttags?: string[];\n\tlastModified?: Date;\n}\n\ninterface PublishedDatesResult {\n\tdates: Date[];\n\tcacheHint: CacheHint;\n\terror?: Error;\n}\n\n/** @internal Publication dates for the Archives widget. */\nexport async function getPublishedDates(\n\ttype: string,\n\toptions?: { locale?: string },\n): Promise<PublishedDatesResult> {\n\tconst locale = effectiveLocaleKey(options) || undefined;\n\tconst key = `publishedDates:${JSON.stringify([type, locale])}`;\n\ttry {\n\t\treturn await requestCached(key, () =>\n\t\t\tcachedQuery<PublishedDatesResult>({\n\t\t\t\tnamespace: contentCacheNamespaces(type),\n\t\t\t\tkey,\n\t\t\t\tload: async () => {\n\t\t\t\t\tconst rows = await loadPublishedDates(type, locale);\n\t\t\t\t\tconst dates: Date[] = [];\n\t\t\t\t\tlet lastModified: Date | undefined;\n\t\t\t\t\tfor (const row of rows) {\n\t\t\t\t\t\tif (row.published_at) {\n\t\t\t\t\t\t\tconst date = new Date(row.published_at);\n\t\t\t\t\t\t\tif (!Number.isNaN(date.getTime())) dates.push(date);\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif (row.updated_at) {\n\t\t\t\t\t\t\tconst modified = new Date(row.updated_at);\n\t\t\t\t\t\t\tif (!Number.isNaN(modified.getTime()) && (!lastModified || modified > lastModified)) {\n\t\t\t\t\t\t\t\tlastModified = modified;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\treturn { dates, cacheHint: { tags: [type], lastModified } };\n\t\t\t\t},\n\t\t\t}),\n\t\t);\n\t} catch (error) {\n\t\treturn {\n\t\t\tdates: [],\n\t\t\tcacheHint: {},\n\t\t\terror:\n\t\t\t\tisMissingTableError(error) || isMissingColumnError(error)\n\t\t\t\t\t? undefined\n\t\t\t\t\t: error instanceof Error\n\t\t\t\t\t\t? error\n\t\t\t\t\t\t: new Error(\"Failed to load publication dates\"),\n\t\t};\n\t}\n}\n\n/**\n * Result from getEmDashCollection\n */\nexport interface CollectionResult<T> {\n\t/** The entries (empty array if error or none found) */\n\tentries: ContentEntry<T>[];\n\t/** Error if the query failed */\n\terror?: Error;\n\t/** Cache hint for route caching (pass to Astro.cache.set()) */\n\tcacheHint: CacheHint;\n\t/**\n\t * Opaque cursor for the next page.\n\t * Undefined when there are no more results.\n\t * Pass this as `cursor` in the next query to get the next page.\n\t */\n\tnextCursor?: string;\n\t/**\n\t * Whether more entries exist beyond this page. Set whenever `limit` is\n\t * provided (cursor or offset pagination), so numbered archive routes can\n\t * render a \"next page\" link without computing a total count.\n\t */\n\thasMore?: boolean;\n}\n\n/**\n * Result from getEmDashEntry\n */\nexport interface EntryResult<T, R = ReferencePages> {\n\t/** The entry, or null if not found */\n\tentry: ContentEntry<T, R> | null;\n\t/** Error if the query failed (not set for \"not found\", only for actual errors) */\n\terror?: Error;\n\t/** Whether we're in preview mode (valid token was provided) */\n\tisPreview: boolean;\n\t/** Set when a fallback locale was used instead of the requested locale */\n\tfallbackLocale?: string;\n\t/** Cache hint for route caching (pass to Astro.cache.set()) */\n\tcacheHint: CacheHint;\n}\n\nconst COLLECTION_NAME = \"_emdash\";\n\n/** Symbol key for edit metadata on PT arrays — avoids collision with user data */\nconst EMDASH_EDIT = Symbol.for(\"__emdash\");\n\n/** Edit metadata attached to PT arrays in edit mode */\nexport interface EditFieldMeta {\n\tcollection: string;\n\tid: string;\n\tfield: string;\n}\n\n/** Type guard for EditFieldMeta */\nfunction isEditFieldMeta(value: unknown): value is EditFieldMeta {\n\tif (typeof value !== \"object\" || value === null) return false;\n\tif (!(\"collection\" in value) || !(\"id\" in value) || !(\"field\" in value)) return false;\n\t// After `in` checks, TS narrows to Record<\"collection\" | \"id\" | \"field\", unknown>\n\tconst { collection, id, field } = value;\n\treturn typeof collection === \"string\" && typeof id === \"string\" && typeof field === \"string\";\n}\n\n/**\n * Read edit metadata from a value (returns undefined if not tagged).\n * Uses Object.getOwnPropertyDescriptor to access Symbol-keyed property\n * without an unsafe type assertion.\n */\nexport function getEditMeta(value: unknown): EditFieldMeta | undefined {\n\tif (value && typeof value === \"object\") {\n\t\tconst desc = Object.getOwnPropertyDescriptor(value, EMDASH_EDIT);\n\t\tconst meta: unknown = desc?.value;\n\t\tif (isEditFieldMeta(meta)) {\n\t\t\treturn meta;\n\t\t}\n\t}\n\treturn undefined;\n}\n\n/**\n * Tag PT-like arrays in entry data with edit metadata (non-enumerable).\n * A PT array is identified by: is an array, first element has _type property.\n */\nfunction tagEditableFields(data: Record<string, unknown>, collection: string, id: string): void {\n\tfor (const [field, value] of Object.entries(data)) {\n\t\tif (\n\t\t\tArray.isArray(value) &&\n\t\t\tvalue.length > 0 &&\n\t\t\tvalue[0] &&\n\t\t\ttypeof value[0] === \"object\" &&\n\t\t\t\"_type\" in value[0]\n\t\t) {\n\t\t\tObject.defineProperty(value, EMDASH_EDIT, {\n\t\t\t\tvalue: { collection, id, field } satisfies EditFieldMeta,\n\t\t\t\tenumerable: false,\n\t\t\t\tconfigurable: true,\n\t\t\t});\n\t\t}\n\t}\n}\n\n/** Safely read a string field from a Record, with optional fallback */\nfunction dataStr(data: Record<string, unknown>, key: string, fallback = \"\"): string {\n\tconst val = data[key];\n\treturn typeof val === \"string\" ? val : fallback;\n}\n\n/** Type guard for Record<string, unknown> */\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n\treturn typeof value === \"object\" && value !== null && !Array.isArray(value);\n}\n\n/** Extract data as Record from an Astro entry (which is any-typed) */\nfunction entryData(entry: { data?: unknown }): Record<string, unknown> {\n\treturn isRecord(entry.data) ? entry.data : {};\n}\n\n/** Extract the database ID from entry data (data.id is the ULID, entry.id is the slug) */\nfunction entryDatabaseId(entry: { id: string; data?: unknown }): string {\n\tconst d = entryData(entry);\n\treturn dataStr(d, \"id\") || entry.id;\n}\n\n/** Extract edit options from entry data for the proxy */\nfunction entryEditOptions(entry: { data?: unknown }): EditableOptions {\n\tconst data = entryData(entry);\n\tconst status = dataStr(data, \"status\", \"draft\");\n\tconst draftRevisionId = dataStr(data, \"draftRevisionId\") || undefined;\n\tconst liveRevisionId = dataStr(data, \"liveRevisionId\") || undefined;\n\tconst hasDraft = !!draftRevisionId && draftRevisionId !== liveRevisionId;\n\treturn { status, hasDraft };\n}\n\nfunction stripRevisionMetadata(entry: { data?: unknown }): void {\n\tconst data = entryData(entry);\n\tdelete data.draftRevisionId;\n\tdelete data.liveRevisionId;\n}\n\nfunction canExposeRevisionMetadata(\n\tentry: { id: string; data?: unknown },\n\tcollection: string,\n): boolean {\n\tconst ctx = getRequestContext();\n\tif (ctx?.editMode) return true;\n\tif (ctx?.preview?.collection !== collection) return false;\n\tconst dbId = entryDatabaseId(entry);\n\treturn ctx.preview.id === dbId || ctx.preview.id === entry.id;\n}\n\n/**\n * Get all entries of a content type\n *\n * Returns { entries, error } for graceful error handling.\n *\n * When emdash-env.d.ts is generated, the collection name will be\n * type-checked and the return type will be inferred automatically.\n *\n * @example\n * ```ts\n * import { getEmDashCollection } from \"emdash\";\n *\n * const { entries: posts, error } = await getEmDashCollection(\"posts\");\n * if (error) {\n * console.error(\"Failed to load posts:\", error);\n * return;\n * }\n * // posts[0].data.title is typed (if emdash-env.d.ts exists)\n *\n * // With filters\n * const { entries: drafts } = await getEmDashCollection(\"posts\", { status: \"draft\" });\n * ```\n */\nexport async function getEmDashCollection<T extends string, D = InferCollectionData<T>>(\n\ttype: T,\n\tfilter?: CollectionFilter,\n): Promise<CollectionResult<D>> {\n\t// Cache per (type, filter) within a single request. Edit mode and\n\t// preview are request-scoped and stable, so they don't need to be\n\t// part of the key. Widgets and layouts frequently request the same\n\t// collection shape as the page itself (e.g. a \"recent posts\" list\n\t// appears on the home page AND in the sidebar) — caching collapses\n\t// those duplicate queries, along with the bylines and taxonomy-term\n\t// hydration each call would otherwise re-do.\n\t//\n\t// Bucket small limits to a shared minimum so a page with several\n\t// \"recent N posts\" widgets at slightly different limits (e.g. a\n\t// post-detail page asking for 4 in the body and 5 in the sidebar)\n\t// shares one fetch + hydration round-trip rather than running two.\n\t// Cursor-paginated calls are exempt: their limit is part of the\n\t// pagination contract.\n\tconst bucketed = bucketFilter(filter);\n\n\t// Preview and edit-mode requests skip `loadCollectionCached`. That path\n\t// reduces every entry to a JSON snapshot (`entrySnapshot`) and rebuilds it\n\t// with `reviveEntry`, which cannot carry the `edit` proxy and re-attaches\n\t// the no-op — so annotations spread as `{...entry.edit.title}` would render\n\t// nothing on list pages. `getEmDashEntry` has the same bypass for the same\n\t// reason (see its `serveDrafts` branch). The request-scoped cache still\n\t// collapses duplicate queries within the render.\n\tconst ctx = getRequestContext();\n\tconst serveDrafts = ctx?.editMode === true || ctx?.preview !== undefined;\n\n\tconst cached = await requestCached(collectionCacheKey(type, bucketed.fetchFilter), () =>\n\t\tserveDrafts\n\t\t\t? getEmDashCollectionUncached<T, D>(type, bucketed.fetchFilter)\n\t\t\t: loadCollectionCached<T, D>(type, bucketed.fetchFilter),\n\t);\n\treturn bucketed.requestedLimit === undefined\n\t\t? cached\n\t\t: sliceCollectionResult(cached, bucketed.requestedLimit, filter?.orderBy);\n}\n\n/** Shape of a cached collection snapshot (entries reduced to JSON-safe form). */\ninterface CachedCollectionValue {\n\tentries: unknown[];\n\tnextCursor?: string;\n\thasMore?: boolean;\n\tcacheHint: CacheHint;\n}\n\n/**\n * Distributed (L2) read-through around {@link getEmDashCollectionUncached}.\n *\n * Caches a JSON-safe snapshot keyed by collection + filter + effective locale,\n * folding the shared `bylines`/`taxonomies` epochs into the key so renaming an\n * author or term invalidates affected lists. Errors are never cached.\n */\nasync function loadCollectionCached<T extends string, D = InferCollectionData<T>>(\n\ttype: T,\n\tfilter?: CollectionFilter,\n): Promise<CollectionResult<D>> {\n\tconst snapshot = await cachedQuery<ContentSnapshot<CachedCollectionValue>>({\n\t\tnamespace: contentNamespaces(type),\n\t\tkey: `collection:${collectionCacheKey(type, filter)}|loc=${effectiveLocaleKey(filter)}`,\n\t\tload: async () => {\n\t\t\tconst result = await getEmDashCollectionUncached<T, D>(type, filter);\n\t\t\tif (result.error) {\n\t\t\t\treturn { ok: false, error: result.error, cacheHint: result.cacheHint };\n\t\t\t}\n\t\t\treturn {\n\t\t\t\tok: true,\n\t\t\t\tvalue: {\n\t\t\t\t\tentries: result.entries.map(entrySnapshot),\n\t\t\t\t\tnextCursor: result.nextCursor,\n\t\t\t\t\thasMore: result.hasMore,\n\t\t\t\t\tcacheHint: result.cacheHint,\n\t\t\t\t},\n\t\t\t};\n\t\t},\n\t\tcacheable: (snap) => snap.ok,\n\t});\n\n\tif (!snapshot.ok) {\n\t\treturn { entries: [], error: snapshot.error, cacheHint: snapshot.cacheHint };\n\t}\n\treturn {\n\t\tentries: snapshot.value.entries.map((entry) => {\n\t\t\tconst revived = reviveEntry<D>(entry);\n\t\t\tif (!canExposeRevisionMetadata(revived, type)) stripRevisionMetadata(revived);\n\t\t\treturn revived;\n\t\t}),\n\t\tnextCursor: snapshot.value.nextCursor,\n\t\thasMore: snapshot.value.hasMore,\n\t\tcacheHint: snapshot.value.cacheHint,\n\t};\n}\n\n/**\n * Threshold for limit bucketing. Page templates routinely render small\n * \"recent posts\" widgets at limits 3-8; rounding those up to a single\n * shared bucket lets one fetch satisfy several widgets within a request.\n * Above this, the requested limit is honoured exactly — bucketing limit:50\n * to limit:64 would waste hydration work for callers fetching real pages.\n */\nconst BUCKET_LIMIT_THRESHOLD = 10;\n\ninterface BucketedFilter {\n\t/** Filter to pass to the loader (with limit possibly raised). */\n\tfetchFilter: CollectionFilter | undefined;\n\t/** Original limit; defined only when bucketing was applied. */\n\trequestedLimit: number | undefined;\n}\n\n/** @internal exported for unit tests; not part of the public API. */\nexport function bucketFilter(filter: CollectionFilter | undefined): BucketedFilter {\n\tconst limit = filter?.limit;\n\tif (\n\t\tlimit === undefined ||\n\t\tlimit >= BUCKET_LIMIT_THRESHOLD ||\n\t\tlimit <= 0 ||\n\t\tfilter?.cursor !== undefined ||\n\t\t// Offset paginates a deliberate page window; its limit is part of the\n\t\t// pagination contract, so don't round it up the way \"recent N\" widgets get.\n\t\tfilter?.offset !== undefined\n\t) {\n\t\treturn { fetchFilter: filter, requestedLimit: undefined };\n\t}\n\treturn {\n\t\tfetchFilter: { ...filter, limit: BUCKET_LIMIT_THRESHOLD },\n\t\trequestedLimit: limit,\n\t};\n}\n\n/**\n * Slice a cached bucketed result down to the originally-requested limit\n * and recompute `nextCursor` from the row that would have been the\n * over-fetch detector for that limit. When truncation is needed, returns\n * a shallow-copied result with a new `entries` array; otherwise returns\n * the cached result unchanged (including error results and results\n * already within the requested limit).\n */\n/** @internal exported for unit tests; not part of the public API. */\nexport function sliceCollectionResult<D>(\n\tcached: CollectionResult<D>,\n\tlimit: number,\n\torderBy: OrderBySpec | undefined,\n): CollectionResult<D> {\n\tif (cached.error) return cached;\n\tif (cached.entries.length <= limit) return cached;\n\tconst sliced = cached.entries.slice(0, limit);\n\t// Mirror the loader's encoding: cursor points at the last returned row,\n\t// so \"next page\" picks up at the row immediately after it. See\n\t// buildCursorCondition in loader.ts — it filters strictly past this row.\n\tconst lastEntry = sliced.at(-1);\n\tconst nextCursor = lastEntry ? encodeEntryCursor(lastEntry, orderBy) : undefined;\n\t// Truncating to the requested limit means at least one more entry existed.\n\treturn { ...cached, entries: sliced, nextCursor, hasMore: true };\n}\n\n/** Map of database column names to camelCase keys present on entry.data. */\nconst ENTRY_DATA_KEY_MAP: Record<string, string> = {\n\tcreated_at: \"createdAt\",\n\tupdated_at: \"updatedAt\",\n\tpublished_at: \"publishedAt\",\n\tscheduled_at: \"scheduledAt\",\n\tauthor_id: \"authorId\",\n\tprimary_byline_id: \"primaryBylineId\",\n};\n\n// Mirror loader.ts FIELD_NAME_PATTERN. Kept in sync intentionally — diverging\n// would let the encoder accept a field name the loader's getPrimarySort then\n// rejected, producing a cursor that paginates against a different column.\nconst FIELD_NAME_PATTERN = /^[a-zA-Z_][a-zA-Z0-9_]*$/;\n\n/**\n * Encode a `nextCursor` from a content entry, mirroring the loader's\n * encoding scheme: `(orderValue, id)` where `orderValue` is the primary\n * sort field's stringified value. For date columns, reads the raw DB\n * string the loader stashed via CURSOR_RAW_VALUES — round-tripping the\n * parsed Date through `toISOString()` would lose precision for stored\n * values that aren't already ISO-with-milliseconds.\n */\nfunction encodeEntryCursor<D>(\n\tentry: ContentEntry<D>,\n\torderBy: OrderBySpec | undefined,\n): string | undefined {\n\tconst data = entryData(entry);\n\tconst id = dataStr(data, \"id\");\n\tif (!id) return undefined;\n\n\t// Match loader.ts getPrimarySort: take the first valid field, default to created_at.\n\tlet dbField = \"created_at\";\n\tif (orderBy) {\n\t\tfor (const field of Object.keys(orderBy)) {\n\t\t\tif (FIELD_NAME_PATTERN.test(field)) {\n\t\t\t\tdbField = field;\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\t}\n\n\t// Date columns: prefer the raw stored string captured by the loader so\n\t// the cursor matches what a direct loader fetch would emit, regardless\n\t// of how the DB stored the timestamp.\n\tconst rawDateValuesRaw = Reflect.get(data, CURSOR_RAW_VALUES);\n\tif (rawDateValuesRaw !== null && typeof rawDateValuesRaw === \"object\") {\n\t\tconst raw = Reflect.get(rawDateValuesRaw, dbField);\n\t\tif (typeof raw === \"string\") return encodeCursor(raw, id);\n\t}\n\n\tconst dataKey = ENTRY_DATA_KEY_MAP[dbField] ?? dbField;\n\tconst value = data[dataKey];\n\tlet orderValue: string;\n\tif (value instanceof Date) {\n\t\torderValue = value.toISOString();\n\t} else if (typeof value === \"string\" || typeof value === \"number\") {\n\t\torderValue = String(value);\n\t} else {\n\t\t// Match the loader's empty-string fallback for null/undefined order\n\t\t// values so cursor decoding stays valid even at the boundary.\n\t\torderValue = \"\";\n\t}\n\treturn encodeCursor(orderValue, id);\n}\n\n/**\n * Build a canonical cache key for `getEmDashCollection`.\n *\n * `JSON.stringify` is insertion-order-sensitive, so two callers passing\n * semantically identical filters with different key orders would miss\n * the cache. We fix the top-level field order and sort `where` keys\n * (order there is irrelevant), while preserving `orderBy` key order\n * because that's the sort priority.\n */\nfunction collectionCacheKey(type: string, filter?: CollectionFilter): string {\n\tif (!filter) return `collection:${type}:`;\n\tconst parts = [\n\t\tfilter.status ?? \"\",\n\t\tfilter.limit ?? \"\",\n\t\tfilter.cursor ?? \"\",\n\t\tfilter.offset ?? \"\",\n\t\tfilter.where ? stableStringify(filter.where) : \"\",\n\t\tfilter.orderBy ? JSON.stringify(filter.orderBy) : \"\",\n\t\tfilter.locale ?? \"\",\n\t];\n\treturn `collection:${type}:${parts.join(\"|\")}`;\n}\n\nfunction stableStringify(value: Record<string, unknown>): string {\n\treturn JSON.stringify(stableOrder(value));\n}\n\nfunction stableOrder(value: Record<string, unknown>): Record<string, unknown> {\n\tconst keys = Object.keys(value).toSorted();\n\tconst ordered: Record<string, unknown> = {};\n\tfor (const k of keys) {\n\t\tconst v = value[k];\n\t\tif (isRecord(v)) {\n\t\t\tordered[k] = stableOrder(v);\n\t\t} else {\n\t\t\tordered[k] = v;\n\t\t}\n\t}\n\treturn ordered;\n}\n\n// ── Object-cache (L2) serialization for content reads ───────────────────────\n//\n// Content entries can't be stored verbatim: each carries a non-serializable\n// `edit` proxy (a function) and a non-enumerable `CURSOR_RAW_VALUES` symbol on\n// `data` (raw date strings used to reproduce the loader's pagination cursor).\n// We reduce each entry to a JSON-safe snapshot before caching — copying the\n// cursor-raw values into an enumerable field and dropping `edit` — then rebuild\n// the symbol and re-attach a no-op `edit` on the way out. The object cache's\n// codec preserves `Date` instances, so timestamps survive the round-trip.\n//\n// L2 is only consulted for anonymous, non-preview, non-edit requests (see\n// `shouldBypass` in object-cache), where `edit` is always the no-op variant —\n// so dropping and recreating it is lossless.\n\n/** Enumerable field carrying the {@link CURSOR_RAW_VALUES} payload in snapshots. */\nconst CURSOR_RAW_FIELD = \"__emdashCursorRaw\";\n\n/** Result wrapper distinguishing a cached error from a cacheable success. */\ntype ContentSnapshot<S> =\n\t| { ok: true; value: S }\n\t| { ok: false; error?: Error; cacheHint: CacheHint };\n\nfunction dataSnapshot(data: Record<string, unknown>): Record<string, unknown> {\n\tconst rawCursor = Reflect.get(data, CURSOR_RAW_VALUES);\n\treturn { ...data, [CURSOR_RAW_FIELD]: rawCursor ?? {} };\n}\n\nfunction reviveData(raw: Record<string, unknown>): Record<string, unknown> {\n\tconst data: Record<string, unknown> = { ...raw };\n\t// eslint-disable-next-line typescript/no-unsafe-type-assertion -- snapshot field written by dataSnapshot\n\tconst rawCursor = (data[CURSOR_RAW_FIELD] as Record<string, string> | undefined) ?? {};\n\tdelete data[CURSOR_RAW_FIELD];\n\tObject.defineProperty(data, CURSOR_RAW_VALUES, {\n\t\tvalue: rawCursor,\n\t\tenumerable: false,\n\t\tconfigurable: false,\n\t\twritable: false,\n\t});\n\treturn data;\n}\n\nfunction entrySnapshot<D>(entry: ContentEntry<D>): Record<string, unknown> {\n\t// Drop the `edit` function; copy enumerable data + the cursor-raw values.\n\tconst { edit: _edit, references, ...rest } = entry as ContentEntry<D> & { edit?: unknown };\n\treturn {\n\t\t...rest,\n\t\tdata: dataSnapshot(entryData(entry)),\n\t\t...(references ? { references: referencesSnapshot(references) } : {}),\n\t};\n}\n\nfunction referencesSnapshot(references: ReferencePages): Record<string, unknown> {\n\tconst snapshot: Record<string, unknown> = {};\n\tfor (const [field, page] of Object.entries(references)) {\n\t\tsnapshot[field] = {\n\t\t\tentries: page.entries.map((child) => ({\n\t\t\t\tid: child.id,\n\t\t\t\tdata: dataSnapshot(entryData(child)),\n\t\t\t})),\n\t\t\t...(page.nextCursor === undefined ? {} : { nextCursor: page.nextCursor }),\n\t\t};\n\t}\n\treturn snapshot;\n}\n\n/**\n * Rebuild the reference pages a snapshot carried.\n *\n * Every child comes back with a no-op `edit` proxy and no revision metadata,\n * which is lossless: the object cache is bypassed for edit-mode and preview\n * requests, so a snapshot is only ever written — and read back — by a render\n * that had neither to begin with.\n */\nfunction reviveReferences(raw: unknown): ReferencePages | undefined {\n\tif (!isRecord(raw)) return undefined;\n\tconst references: ReferencePages = {};\n\tfor (const [field, page] of Object.entries(raw)) {\n\t\t// eslint-disable-next-line typescript/no-unsafe-type-assertion -- page shape produced by referencesSnapshot\n\t\tconst snapshot = page as { entries: Record<string, unknown>[]; nextCursor?: string };\n\t\treferences[field] = {\n\t\t\tentries: snapshot.entries.map((child) => ({\n\t\t\t\t// eslint-disable-next-line typescript/no-unsafe-type-assertion -- snapshot ids are always strings\n\t\t\t\tid: child.id as string,\n\t\t\t\t// eslint-disable-next-line typescript/no-unsafe-type-assertion -- snapshot `data` is always a record\n\t\t\t\tdata: reviveData(child.data as Record<string, unknown>),\n\t\t\t\tedit: createNoop(),\n\t\t\t})),\n\t\t\t...(snapshot.nextCursor === undefined ? {} : { nextCursor: snapshot.nextCursor }),\n\t\t};\n\t}\n\treturn references;\n}\n\nfunction reviveEntry<D>(raw: unknown): ContentEntry<D> {\n\t// eslint-disable-next-line typescript/no-unsafe-type-assertion -- snapshot shape produced by entrySnapshot\n\tconst entry = raw as Record<string, unknown>;\n\t// eslint-disable-next-line typescript/no-unsafe-type-assertion -- snapshot `data` is always a record\n\tconst data = reviveData(entry.data as Record<string, unknown>);\n\tconst references = reviveReferences(entry.references);\n\tconst revived = {\n\t\t...entry,\n\t\tdata,\n\t\t...(references ? { references } : {}),\n\t\tedit: createNoop(),\n\t};\n\t// eslint-disable-next-line typescript/no-unsafe-type-assertion -- rebuilt to the ContentEntry shape with a no-op edit proxy\n\treturn revived as ContentEntry<D>;\n}\n\n/** Resolve the effective locale used by content reads, for the L2 cache key. */\nfunction effectiveLocaleKey(filter?: { locale?: string }): string {\n\tconst ctx = getRequestContext();\n\tconst i18nConfig = getI18nConfig();\n\treturn (\n\t\tfilter?.locale ?? ctx?.locale ?? (isI18nEnabled() ? i18nConfig!.defaultLocale : undefined) ?? \"\"\n\t);\n}\n\nasync function getEmDashCollectionUncached<T extends string, D = InferCollectionData<T>>(\n\ttype: T,\n\tfilter?: CollectionFilter,\n): Promise<CollectionResult<D>> {\n\t// Dynamic import to avoid build-time issues\n\tconst { getLiveCollection } = await import(\"astro:content\");\n\n\t// Resolve locale: explicit filter > ALS context > defaultLocale (when i18n enabled)\n\t// Without this, queries return all locale rows, producing broken IDs\n\tconst ctx = getRequestContext();\n\tconst i18nConfig = getI18nConfig();\n\tconst resolvedLocale =\n\t\tfilter?.locale ?? ctx?.locale ?? (isI18nEnabled() ? i18nConfig!.defaultLocale : undefined);\n\n\tconst requestedLimit = filter?.limit;\n\t// cursor and offset are mutually exclusive on the loader filter union, so\n\t// spread only the one in play (cursor wins) rather than emitting both keys.\n\tconst pageParam =\n\t\tfilter?.cursor !== undefined\n\t\t\t? { cursor: filter.cursor }\n\t\t\t: filter?.offset !== undefined\n\t\t\t\t? { offset: filter.offset }\n\t\t\t\t: {};\n\tconst result = await getLiveCollection(COLLECTION_NAME, {\n\t\ttype,\n\t\tstatus: filter?.status,\n\t\tlimit: requestedLimit && requestedLimit > 0 ? requestedLimit + 1 : filter?.limit,\n\t\t...pageParam,\n\t\twhere: filter?.where,\n\t\torderBy: filter?.orderBy,\n\t\tlocale: resolvedLocale,\n\t});\n\n\tconst { entries, error, cacheHint } = result;\n\n\tif (error) {\n\t\treturn { entries: [], error, cacheHint: {} };\n\t}\n\n\tconst hasMore = requestedLimit != null && requestedLimit > 0 && entries.length > requestedLimit;\n\tconst pageEntries = hasMore ? entries.slice(0, requestedLimit) : entries;\n\tconst nextCursor = hasMore ? encodeEntryCursor(pageEntries.at(-1), filter?.orderBy) : undefined;\n\t// `hasMore` is only meaningful when a limit bounds the page; otherwise the\n\t// query returned everything and there is no \"next page\" to report.\n\tconst hasMoreResult = requestedLimit != null && requestedLimit > 0 ? hasMore : undefined;\n\n\tconst isEditMode = ctx?.editMode ?? false;\n\tconst entriesWithEdit = pageEntries.map((entry: ContentEntry<D>) => {\n\t\tconst dbId = entryDatabaseId(entry);\n\t\tif (isEditMode) {\n\t\t\ttagEditableFields(entryData(entry), type, dbId);\n\t\t}\n\t\tif (!canExposeRevisionMetadata(entry, type)) {\n\t\t\tstripRevisionMetadata(entry);\n\t\t}\n\t\treturn {\n\t\t\t...entry,\n\t\t\tedit: isEditMode ? createEditable(type, dbId, entryEditOptions(entry)) : createNoop(),\n\t\t};\n\t});\n\n\t// Eagerly hydrate bylines and taxonomy terms for all entries in parallel.\n\t// Both are independent queries, so running them concurrently halves the\n\t// round-trip cost on remote databases (D1 replicas, etc.).\n\tawait Promise.all([\n\t\thydrateEntryBylines(type, entriesWithEdit),\n\t\t// Use the content query locale as the preferred term locale; hydration\n\t\t// falls back only to the configured default when a group lacks that variant.\n\t\thydrateEntryTerms(type, entriesWithEdit, resolvedLocale),\n\t]);\n\n\treturn {\n\t\tentries: entriesWithEdit,\n\t\tnextCursor,\n\t\thasMore: hasMoreResult,\n\t\tcacheHint: cacheHint ?? {},\n\t};\n}\n\n/**\n * Get a single entry by type and ID/slug\n *\n * Returns { entry, error, isPreview } for graceful error handling.\n * - entry is null if not found (not an error)\n * - error is set only for actual errors (db issues, etc.)\n *\n * Preview mode is detected automatically from request context (ALS).\n * When the URL has a valid `_preview` token, the middleware sets preview\n * context and this function serves draft revision data if available.\n *\n * @example\n * ```ts\n * import { getEmDashEntry } from \"emdash\";\n *\n * // Simple usage — preview just works via middleware\n * const { entry: post, isPreview, error } = await getEmDashEntry(\"posts\", \"my-slug\");\n * if (!post) return Astro.redirect(\"/404\");\n * ```\n *\n * @example\n * ```ts\n * // Opt into reference fields, by field slug\n * const { entry: post } = await getEmDashEntry(\"posts\", slug, {\n * references: { author: true, related_posts: { limit: 6 } },\n * });\n * const author = post?.references?.author.entries[0];\n * ```\n */\nexport async function getEmDashEntry<\n\tT extends string,\n\tD = InferCollectionData<T>,\n\tS extends SelectableReferences<T> = {},\n>(\n\ttype: T,\n\tid: string,\n\toptions?: { locale?: string; references?: S },\n): Promise<EntryResult<D, SelectedReferences<T, S>>> {\n\t// eslint-disable-next-line typescript/no-unsafe-type-assertion -- the resolver returns one page per field the selection named, which is what SelectedReferences picks out\n\treturn resolveEmDashEntry<T, D>(type, id, options) as Promise<\n\t\tEntryResult<D, SelectedReferences<T, S>>\n\t>;\n}\n\n/**\n * Attach one page of each selected reference field to a resolved entry, and\n * report the cache hint its children contribute.\n *\n * An entry with no translation group predates i18n and has no links; there is\n * nothing to resolve, and `references` stays absent rather than becoming an\n * empty object that reads as \"this entry references nothing\".\n */\nasync function attachReferences<D>(\n\ttype: string,\n\tentry: ContentEntry<D>,\n\toptions: {\n\t\tselection: ReferenceSelection;\n\t\t/**\n\t\t * Whether this render may see drafts. It decides both whether a pending\n\t\t * selection replaces the published one and whether an unpublished target\n\t\t * resolves at all — a preview token that did not match served this entry\n\t\t * as public, and its children have to stay just as invisible.\n\t\t */\n\t\tserveDrafts: boolean;\n\t\t/** Read before `stripRevisionMetadata` removes it from a public render's data. */\n\t\tdraftRevisionId?: string;\n\t},\n): Promise<CacheHint> {\n\tconst data = entryData(entry);\n\tconst entryGroup = dataStr(data, \"translationGroup\");\n\tif (!entryGroup) return {};\n\n\tconst { resolveReferencePages } = await import(\"./references/resolve.js\");\n\tconst pages = await resolveReferencePages({\n\t\tcollection: type,\n\t\tentryGroup,\n\t\tlocale: dataStr(data, \"locale\") || null,\n\t\tdraftRevisionId: options.draftRevisionId,\n\t\tserveDrafts: options.serveDrafts,\n\t\tselection: options.selection,\n\t});\n\n\tconst references: ReferencePages = {};\n\tconst tags: string[] = [];\n\tlet lastModified: Date | undefined;\n\tfor (const [field, page] of Object.entries(pages)) {\n\t\tfor (const child of page.entries) {\n\t\t\ttags.push(...child.cacheHint.tags);\n\t\t\tconst modified = child.cacheHint.lastModified;\n\t\t\tif (modified && (!lastModified || modified > lastModified)) lastModified = modified;\n\t\t}\n\t\treferences[field] = {\n\t\t\tentries: page.entries.map((child) => wrapReferencedEntry(page.collection, child)),\n\t\t\t...(page.nextCursor === undefined ? {} : { nextCursor: page.nextCursor }),\n\t\t};\n\t}\n\tentry.references = references;\n\treturn { tags, ...(lastModified ? { lastModified } : {}) };\n}\n\n/**\n * Fold the children's cache hint into the entry's own.\n *\n * A render that shows a referenced entry has read that row, so the route's tags\n * have to name it and its `Last-Modified` has to move when it changes. Without\n * this the route cache's `invalidate({ tags: [collection, id] })` on a child\n * write would never reach the pages that render the child.\n */\nfunction mergeCacheHints(base: CacheHint, extra: CacheHint): CacheHint {\n\tif (!extra.tags?.length && !extra.lastModified) return base;\n\tconst tags = [...new Set([...(base.tags ?? []), ...(extra.tags ?? [])])];\n\tconst newest =\n\t\tbase.lastModified && extra.lastModified\n\t\t\t? base.lastModified > extra.lastModified\n\t\t\t\t? base.lastModified\n\t\t\t\t: extra.lastModified\n\t\t\t: (base.lastModified ?? extra.lastModified);\n\treturn {\n\t\t...(tags.length > 0 ? { tags } : {}),\n\t\t...(newest ? { lastModified: newest } : {}),\n\t};\n}\n\n/**\n * The object-cache namespaces a selection's targets live in.\n *\n * Without them a cached parent snapshot would outlive a write to the entries it\n * points at. Byline and taxonomy namespaces are deliberately absent: referenced\n * entries are loaded without either hydration. The targets are sorted so two\n * callers that name the same fields in a different order share one snapshot.\n */\nasync function referenceTargetNamespaces(\n\tcollection: string,\n\tselection: ReferenceSelection,\n): Promise<string[]> {\n\tconst { getReferenceFieldMap } = await import(\"./references/field-map.js\");\n\tconst fieldMap = await getReferenceFieldMap(collection);\n\tconst targets = new Set<string>();\n\tfor (const [slug, query] of Object.entries(selection)) {\n\t\tif (query === undefined) continue;\n\t\tconst binding = fieldMap.get(slug);\n\t\tif (binding) targets.add(binding.targetCollection);\n\t}\n\treturn [...targets].toSorted().flatMap((target) => [...contentCacheNamespaces(target)]);\n}\n\n/**\n * Wrap a referenced entry the way the collection paths wrap their own: an edit\n * proxy in edit mode, revision metadata stripped for anyone who may not see it.\n *\n * The proxy is scoped to the *referenced* entry's collection and row, so\n * clicking through from a card opens the entry the card is about.\n */\nfunction wrapReferencedEntry<D = Record<string, unknown>>(\n\tcollection: string,\n\tchild: { id: string; data: Record<string, unknown> },\n): ContentEntry<D> {\n\tconst isEditMode = getRequestContext()?.editMode ?? false;\n\tconst dbId = entryDatabaseId(child);\n\tif (isEditMode) tagEditableFields(child.data, collection, dbId);\n\tif (!canExposeRevisionMetadata(child, collection)) stripRevisionMetadata(child);\n\treturn {\n\t\tid: child.id,\n\t\t// eslint-disable-next-line typescript/no-unsafe-type-assertion -- row data is shaped by the target collection, which only generated types know\n\t\tdata: child.data as D,\n\t\tedit: isEditMode ? createEditable(collection, dbId, entryEditOptions(child)) : createNoop(),\n\t};\n}\n\nasync function resolveEmDashEntry<T extends string, D = InferCollectionData<T>>(\n\ttype: T,\n\tid: string,\n\toptions?: { locale?: string; references?: ReferenceSelection },\n): Promise<EntryResult<D>> {\n\t// Dynamic import to avoid build-time issues\n\tconst { getLiveEntry } = await import(\"astro:content\");\n\n\t// Check ALS for preview and edit mode context\n\tconst ctx = getRequestContext();\n\tconst preview = ctx?.preview;\n\tconst isEditMode = ctx?.editMode ?? false;\n\tconst isPreviewMode = !!preview && preview.collection === type;\n\t// Edit mode implies preview — editors should see draft content\n\tconst serveDrafts = isPreviewMode || isEditMode;\n\n\t// Resolve locale: explicit option > ALS context > undefined (no filter)\n\tconst requestedLocale = options?.locale ?? ctx?.locale;\n\tconst references = options?.references;\n\n\t/** Wrap a raw Astro entry with edit proxy, tagging editable fields if needed */\n\tfunction wrapEntry(raw: ContentEntry<D>): ContentEntry<D> {\n\t\tconst dbId = entryDatabaseId(raw);\n\t\tif (isEditMode) {\n\t\t\ttagEditableFields(entryData(raw), type, dbId);\n\t\t}\n\t\treturn {\n\t\t\t...raw,\n\t\t\tedit: isEditMode ? createEditable(type, dbId, entryEditOptions(raw)) : createNoop(),\n\t\t};\n\t}\n\n\t/** Check if an entry has completed publication. */\n\tfunction isVisible(entry: ContentEntry<D>): boolean {\n\t\treturn dataStr(entryData(entry), \"status\") === \"published\";\n\t}\n\n\t// Build the fallback chain: [requestedLocale, fallback1, ..., defaultLocale]\n\t// When i18n is disabled or no locale requested, just use a single-element chain\n\tconst localeChain =\n\t\trequestedLocale && isI18nEnabled() ? getFallbackChain(requestedLocale) : [requestedLocale];\n\n\t/** Return a successful EntryResult with bylines, taxonomy terms and references hydrated */\n\tasync function successResult(\n\t\twrapped: ContentEntry<D>,\n\t\topts: { isPreview: boolean; fallbackLocale?: string; cacheHint: CacheHint },\n\t): Promise<EntryResult<D>> {\n\t\t// Read the draft pointer before stripping it: a public render drops it\n\t\t// from `data`, and a staged selection is resolved from it.\n\t\tconst draftRevisionId = dataStr(entryData(wrapped), \"draftRevisionId\") || undefined;\n\t\tif (!opts.isPreview) stripRevisionMetadata(wrapped);\n\t\t// No-i18n callers use the legacy wildcard cache key. The query path still\n\t\t// resolves against the stored content-row locale when this is undefined.\n\t\tconst termLocale = isI18nEnabled()\n\t\t\t? dataStr(entryData(wrapped), \"locale\") || undefined\n\t\t\t: undefined;\n\t\t// References resolve alongside bylines and terms rather than after the\n\t\t// entry returns: all three are independent reads, and running them\n\t\t// together keeps an opted-in render to one extra round of queries.\n\t\tconst [, , referenceHint] = await Promise.all([\n\t\t\thydrateEntryBylines(type, [wrapped]),\n\t\t\thydrateEntryTerms(type, [wrapped], termLocale),\n\t\t\treferences\n\t\t\t\t? attachReferences(type, wrapped, {\n\t\t\t\t\t\tselection: references,\n\t\t\t\t\t\tserveDrafts: opts.isPreview,\n\t\t\t\t\t\tdraftRevisionId,\n\t\t\t\t\t})\n\t\t\t\t: Promise.resolve<CacheHint>({}),\n\t\t]);\n\t\treturn {\n\t\t\tentry: wrapped,\n\t\t\tisPreview: opts.isPreview,\n\t\t\tfallbackLocale: opts.fallbackLocale,\n\t\t\tcacheHint: mergeCacheHints(opts.cacheHint, referenceHint),\n\t\t};\n\t}\n\n\tif (serveDrafts) {\n\t\t// Draft mode: try each locale in the fallback chain\n\t\tfor (let i = 0; i < localeChain.length; i++) {\n\t\t\tconst locale = localeChain[i];\n\t\t\tconst fallbackLocale = i > 0 ? locale : undefined;\n\n\t\t\tconst {\n\t\t\t\tentry: baseEntry,\n\t\t\t\terror: baseError,\n\t\t\t\tcacheHint,\n\t\t\t} = await getLiveEntry(COLLECTION_NAME, {\n\t\t\t\ttype,\n\t\t\t\tid,\n\t\t\t\tlocale,\n\t\t\t});\n\n\t\t\tif (baseError) {\n\t\t\t\t// Astro reports a missing entry as an error; try the next locale.\n\t\t\t\tif (baseError.name === \"LiveEntryNotFoundError\") continue;\n\t\t\t\treturn { entry: null, error: baseError, isPreview: serveDrafts, cacheHint: {} };\n\t\t\t}\n\n\t\t\tif (!baseEntry) continue; // Try next locale in chain\n\n\t\t\t// Preview tokens are item-scoped: verify the resolved entry matches.\n\t\t\t// Edit mode (authenticated editors) has collection-wide draft access.\n\t\t\tif (isPreviewMode && !isEditMode) {\n\t\t\t\tconst dbId = entryDatabaseId(baseEntry);\n\t\t\t\tif (preview.id !== dbId && preview.id !== id) {\n\t\t\t\t\t// Token doesn't match — serve only if publicly visible, without draft access\n\t\t\t\t\tif (isVisible(baseEntry)) {\n\t\t\t\t\t\treturn successResult(wrapEntry(baseEntry), {\n\t\t\t\t\t\t\tisPreview: false,\n\t\t\t\t\t\t\tfallbackLocale,\n\t\t\t\t\t\t\tcacheHint: cacheHint ?? {},\n\t\t\t\t\t\t});\n\t\t\t\t\t}\n\t\t\t\t\t// Not visible — try next locale in fallback chain\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// Check if entry has a draft revision — if so, re-fetch with revision data\n\t\t\tconst baseData = entryData(baseEntry);\n\t\t\tconst draftRevisionId = dataStr(baseData, \"draftRevisionId\") || undefined;\n\n\t\t\tif (draftRevisionId) {\n\t\t\t\tconst { entry: draftEntry, error: draftError } = await getLiveEntry(COLLECTION_NAME, {\n\t\t\t\t\ttype,\n\t\t\t\t\tid,\n\t\t\t\t\trevisionId: draftRevisionId,\n\t\t\t\t\tlocale,\n\t\t\t\t});\n\n\t\t\t\tif (!draftError && draftEntry) {\n\t\t\t\t\treturn successResult(wrapEntry(draftEntry), {\n\t\t\t\t\t\tisPreview: serveDrafts,\n\t\t\t\t\t\tfallbackLocale,\n\t\t\t\t\t\tcacheHint: cacheHint ?? {},\n\t\t\t\t\t});\n\t\t\t\t}\n\t\t\t}\n\n\t\t\treturn successResult(wrapEntry(baseEntry), {\n\t\t\t\tisPreview: serveDrafts,\n\t\t\t\tfallbackLocale,\n\t\t\t\tcacheHint: cacheHint ?? {},\n\t\t\t});\n\t\t}\n\n\t\t// No entry found in any locale\n\t\treturn { entry: null, isPreview: serveDrafts, cacheHint: {} };\n\t}\n\n\t// Normal mode: try each locale in the fallback chain, only return published\n\t// content. The full resolution (fallback chain + visibility + byline/term\n\t// hydration) is wrapped in the distributed L2 cache, keyed by the requested\n\t// locale. Preview/edit requests took the `serveDrafts` branch above and\n\t// never reach here; the object cache additionally bypasses them.\n\n\tconst resolveNormal = async (): Promise<EntryResult<D>> => {\n\t\tfor (let i = 0; i < localeChain.length; i++) {\n\t\t\tconst locale = localeChain[i];\n\t\t\tconst fallbackLocale = i > 0 ? locale : undefined;\n\n\t\t\tconst { entry, error, cacheHint } = await getLiveEntry(COLLECTION_NAME, { type, id, locale });\n\t\t\tif (error) {\n\t\t\t\t// Astro reports a missing entry as an error; try the next locale.\n\t\t\t\tif (error.name === \"LiveEntryNotFoundError\") continue;\n\t\t\t\treturn { entry: null, error, isPreview: false, cacheHint: {} };\n\t\t\t}\n\n\t\t\tif (entry && isVisible(entry)) {\n\t\t\t\treturn successResult(wrapEntry(entry), {\n\t\t\t\t\tisPreview: false,\n\t\t\t\t\tfallbackLocale,\n\t\t\t\t\tcacheHint: cacheHint ?? {},\n\t\t\t\t});\n\t\t\t}\n\t\t\t// Entry not found or not visible in this locale — try next\n\t\t}\n\t\treturn { entry: null, isPreview: false, cacheHint: {} };\n\t};\n\n\t// A snapshot carries whatever references the caller asked for, so both the\n\t// key and the namespaces account for the selection: the key, or a render that\n\t// asked for references would be served one that did not; the namespaces, or\n\t// the snapshot would outlive a write to a child. A caller that asks for none\n\t// must keep the plain key and namespaces, which entries already in the cache\n\t// are stored under.\n\tconst namespaces = references\n\t\t? [...contentNamespaces(type), ...(await referenceTargetNamespaces(type, references))]\n\t\t: contentNamespaces(type);\n\tconst referenceKey = references ? `|refs=${stableStringify(references)}` : \"\";\n\n\tconst snapshot = await cachedQuery<ContentSnapshot<CachedEntryValue>>({\n\t\tnamespace: namespaces,\n\t\tkey: `entry:${id}|loc=${requestedLocale ?? \"\"}${referenceKey}`,\n\t\tload: async () => {\n\t\t\tconst result = await resolveNormal();\n\t\t\tif (result.error) {\n\t\t\t\treturn { ok: false, error: result.error, cacheHint: result.cacheHint };\n\t\t\t}\n\t\t\treturn {\n\t\t\t\tok: true,\n\t\t\t\tvalue: {\n\t\t\t\t\tentry: result.entry ? entrySnapshot(result.entry) : null,\n\t\t\t\t\tisPreview: result.isPreview,\n\t\t\t\t\tfallbackLocale: result.fallbackLocale,\n\t\t\t\t\tcacheHint: result.cacheHint,\n\t\t\t\t},\n\t\t\t};\n\t\t},\n\t\tcacheable: (snap) => snap.ok,\n\t});\n\n\tif (!snapshot.ok) {\n\t\treturn { entry: null, error: snapshot.error, isPreview: false, cacheHint: snapshot.cacheHint };\n\t}\n\tconst revived = snapshot.value.entry ? reviveEntry<D>(snapshot.value.entry) : null;\n\tif (revived && !canExposeRevisionMetadata(revived, type)) stripRevisionMetadata(revived);\n\tif (revived) {\n\t\t// On a warm object-cache hit the loader never runs, so prime the\n\t\t// SEO panel cache from the snapshot's data (a no-op after a miss,\n\t\t// where the loader already primed).\n\t\t// eslint-disable-next-line typescript/no-unsafe-type-assertion -- snapshot `data` is always a record\n\t\tconst { id: rowId, seo } = revived.data as Record<string, unknown>;\n\t\t// eslint-disable-next-line typescript/no-unsafe-type-assertion -- `data.seo` is written by the loader as ContentSeo\n\t\tif (seo && typeof rowId === \"string\") primeSeoPanel(type, rowId, seo as ContentSeo);\n\t}\n\treturn {\n\t\tentry: revived,\n\t\tisPreview: snapshot.value.isPreview,\n\t\tfallbackLocale: snapshot.value.fallbackLocale,\n\t\tcacheHint: snapshot.value.cacheHint,\n\t};\n}\n\n/**\n * Get one page of a single reference field, without re-reading the entry it\n * hangs off.\n *\n * `getEmDashEntry({ references })` returns the first page of each field it is\n * asked for; this is how a \"load more\" walks past it, using the `nextCursor`\n * that page carried. Draft visibility follows the same request context — a\n * preview token for this entry, or edit mode — so a walk started in preview\n * keeps seeing the pending selection.\n *\n * @example\n * ```ts\n * import { getEmDashReferences } from \"emdash\";\n *\n * const more = await getEmDashReferences(\"posts\", post.id, \"related_posts\", {\n * cursor,\n * limit: 20,\n * });\n * ```\n */\nexport async function getEmDashReferences<D = Record<string, unknown>>(\n\ttype: string,\n\tid: string,\n\tfield: string,\n\toptions?: { limit?: number; cursor?: string; locale?: string },\n): Promise<ReferenceResult<D>> {\n\tconst ctx = getRequestContext();\n\tconst preview = ctx?.preview;\n\tconst isEditMode = ctx?.editMode ?? false;\n\tconst locale = options?.locale ?? ctx?.locale;\n\n\ttry {\n\t\tconst { getDb } = await import(\"./loader.js\");\n\t\tconst { ContentRepository } = await import(\"./database/repositories/content.js\");\n\t\tconst { resolveReferencePages } = await import(\"./references/resolve.js\");\n\n\t\tconst db = await getDb();\n\t\tconst addressed = splitLocalePrefixedId(id, locale);\n\t\tconst entry = await new ContentRepository(db).findByIdOrSlug(\n\t\t\ttype,\n\t\t\taddressed.id,\n\t\t\taddressed.locale,\n\t\t);\n\t\tif (!entry?.translationGroup) return { entries: [] };\n\n\t\t// Preview tokens are entry-scoped, so a token minted for another entry\n\t\t// gives no draft access here; edit mode is collection-wide.\n\t\tconst previewMatches =\n\t\t\t!!preview && preview.collection === type && (preview.id === entry.id || preview.id === id);\n\t\tconst serveDrafts = isEditMode || previewMatches;\n\t\t// Anchoring on an entry the caller may not see would let its links be\n\t\t// probed. An unpublished anchor is simply empty, as a missing one is.\n\t\tif (!serveDrafts && entry.status !== \"published\") return { entries: [] };\n\n\t\tconst query: ReferenceQuery =\n\t\t\toptions?.limit === undefined && options?.cursor === undefined\n\t\t\t\t? true\n\t\t\t\t: { limit: options.limit, cursor: options.cursor };\n\n\t\tconst pages = await resolveReferencePages({\n\t\t\tcollection: type,\n\t\t\tentryGroup: entry.translationGroup,\n\t\t\tlocale: entry.locale,\n\t\t\tdraftRevisionId: entry.draftRevisionId ?? undefined,\n\t\t\tserveDrafts,\n\t\t\tselection: { [field]: query },\n\t\t});\n\n\t\tconst page = pages[field];\n\t\tif (!page) return { entries: [] };\n\n\t\tconst tags: string[] = [];\n\t\tlet lastModified: Date | undefined;\n\t\tfor (const child of page.entries) {\n\t\t\ttags.push(...child.cacheHint.tags);\n\t\t\tconst modified = child.cacheHint.lastModified;\n\t\t\tif (modified && (!lastModified || modified > lastModified)) lastModified = modified;\n\t\t}\n\n\t\treturn {\n\t\t\tentries: page.entries.map((child) => wrapReferencedEntry<D>(page.collection, child)),\n\t\t\t...(page.nextCursor === undefined ? {} : { nextCursor: page.nextCursor }),\n\t\t\tcacheHint: { tags, ...(lastModified ? { lastModified } : {}) },\n\t\t};\n\t} catch (error) {\n\t\treturn { entries: [], error: error instanceof Error ? error : new Error(String(error)) };\n\t}\n}\n\n/**\n * Take a locale prefix off an entry id, and read it as the locale to look in.\n *\n * Wherever i18n prefixes a locale's URLs, an entry is addressed as `fr/about`\n * rather than `about` — that is the id the loader builds and the id a render\n * holds, including for a referenced entry. Rows are stored under the bare slug,\n * so the prefix has to become the locale instead. A first segment that is not a\n * configured locale is part of the identifier and stays put.\n */\nfunction splitLocalePrefixedId(\n\tid: string,\n\tlocale: string | undefined,\n): { id: string; locale: string | undefined } {\n\tconst slash = id.indexOf(\"/\");\n\tif (slash === -1) return { id, locale };\n\n\tconst prefix = id.slice(0, slash);\n\tif (!getI18nConfig()?.locales.includes(prefix)) return { id, locale };\n\treturn { id: id.slice(slash + 1), locale: prefix };\n}\n\n/** Shape of a cached single-entry snapshot. */\ninterface CachedEntryValue {\n\tentry: Record<string, unknown> | null;\n\tisPreview: boolean;\n\tfallbackLocale?: string;\n\tcacheHint: CacheHint;\n}\n\n/**\n * Eagerly hydrate byline data onto entry.data for one or more entries.\n *\n * Attaches `bylines` (array of ContentBylineCredit) and `byline`\n * (primary BylineSummary or null) to each entry's data object.\n * Uses batch queries to avoid N+1.\n *\n * Fails silently if the byline tables don't exist yet (pre-migration).\n */\nasync function hydrateEntryBylines<D>(type: string, entries: ContentEntry<D>[]): Promise<void> {\n\tif (entries.length === 0) return;\n\n\t// Fast path: bylines were folded into the content query. Parse the JSON\n\t// (no extra round trip) for the common case — explicit credits, no byline\n\t// custom fields, no author fallback. The query path below handles the rest:\n\t// - author fallback (entry has authorId but no explicit credit), and\n\t// - custom byline fields (can't be expressed in the folded subquery).\n\tif (entries.every((e) => FOLDED_BYLINES in entryData(e))) {\n\t\tconst parsed = entries.map((entry) => {\n\t\t\tconst data = entryData(entry);\n\t\t\tconst folded = Reflect.get(data, FOLDED_BYLINES);\n\t\t\tconst rows = Array.isArray(folded) ? folded : [];\n\t\t\tconst credits = creditsFromFoldedBylines(rows);\n\t\t\treturn { data, credits };\n\t\t});\n\n\t\t// An empty `_emdash_bylines` table makes an empty fold authoritative: no\n\t\t// credit can exist in any locale and the author fallback has no byline\n\t\t// to resolve to, so skip the query path and the custom-fields probe\n\t\t// entirely. A missing marker (older cached rows) means \"unknown\" and\n\t\t// keeps the conservative fallback below.\n\t\tconst knownEmpty = entries.every(\n\t\t\t(e) => Reflect.get(entryData(e), FOLDED_BYLINES_EXIST) === false,\n\t\t);\n\n\t\t// Fall back to the full query path when the fold can't be trusted to be\n\t\t// complete: an entry with a byline reference (explicit primary, or an\n\t\t// author for the author-fallback) but no folded credits — e.g. a credit\n\t\t// in a different locale than the row, which the locale-correlated subquery\n\t\t// skips, or the author-fallback path which the fold doesn't express.\n\t\tlet needsQueryPath =\n\t\t\t!knownEmpty &&\n\t\t\tparsed.some(\n\t\t\t\t(p) =>\n\t\t\t\t\tp.credits.length === 0 &&\n\t\t\t\t\t(dataStr(p.data, \"authorId\") !== \"\" || dataStr(p.data, \"primaryBylineId\") !== \"\"),\n\t\t\t);\n\t\tlet hasCustomFields = false;\n\t\tif (!needsQueryPath && !knownEmpty) {\n\t\t\ttry {\n\t\t\t\tconst { getDb } = await import(\"./loader.js\");\n\t\t\t\tconst db = await getDb();\n\t\t\t\tconst { getBylineFieldDefs } = await import(\"./bylines/field-defs-cache.js\");\n\t\t\t\thasCustomFields = (await getBylineFieldDefs(db)).length > 0;\n\t\t\t} catch (error) {\n\t\t\t\t// A missing table is expected pre-migration and means there are no\n\t\t\t\t// custom fields — the fold's values are complete. Any other error\n\t\t\t\t// (lock-init failure, dialect error) means the probe can't be\n\t\t\t\t// trusted, so fall back to the query path rather than risk serving\n\t\t\t\t// folded bylines with empty customFields.\n\t\t\t\tif (!isMissingTableError(error)) needsQueryPath = true;\n\t\t\t}\n\t\t}\n\n\t\tif (!needsQueryPath && !hasCustomFields) {\n\t\t\tfor (const p of parsed) {\n\t\t\t\tp.data.bylines = p.credits;\n\t\t\t\tp.data.byline = p.credits[0]?.byline ?? null;\n\t\t\t}\n\t\t\treturn;\n\t\t}\n\t\t// Fall through to the full query path for fallback / custom-field cases.\n\t}\n\n\ttry {\n\t\tconst { getBylinesForEntries } = await import(\"./bylines/index.js\");\n\n\t\tconst refs = entries\n\t\t\t.map((e) => {\n\t\t\t\tconst data = entryData(e);\n\t\t\t\tconst id = dataStr(data, \"id\");\n\t\t\t\tif (!id) return null;\n\t\t\t\treturn {\n\t\t\t\t\tid,\n\t\t\t\t\tauthorId: dataStr(data, \"authorId\") || null,\n\t\t\t\t\tprimaryBylineId: dataStr(data, \"primaryBylineId\") || null,\n\t\t\t\t\tlocale: dataStr(data, \"locale\") || null,\n\t\t\t\t};\n\t\t\t})\n\t\t\t.filter(\n\t\t\t\t(\n\t\t\t\t\tr,\n\t\t\t\t): r is {\n\t\t\t\t\tid: string;\n\t\t\t\t\tauthorId: string | null;\n\t\t\t\t\tprimaryBylineId: string | null;\n\t\t\t\t\tlocale: string | null;\n\t\t\t\t} => r !== null,\n\t\t\t);\n\t\tif (refs.length === 0) return;\n\n\t\tconst bylinesMap = await getBylinesForEntries(type, refs);\n\n\t\tfor (const entry of entries) {\n\t\t\tconst data = entryData(entry);\n\t\t\tconst dbId = dataStr(data, \"id\");\n\t\t\tif (!dbId) continue;\n\n\t\t\tconst credits = bylinesMap.get(dbId) ?? [];\n\t\t\tdata.bylines = credits;\n\t\t\tdata.byline = credits[0]?.byline ?? null;\n\t\t}\n\t} catch (err) {\n\t\t// Only swallow \"table not found\" errors from pre-migration databases.\n\t\t// Matches SQLite/D1 (\"no such table\") and PostgreSQL (\"relation/table\n\t\t// ... does not exist\") via the shared helper.\n\t\tif (!isMissingTableError(err)) {\n\t\t\tconst msg = err instanceof Error ? err.message : String(err);\n\t\t\tconsole.warn(\"[emdash] Failed to hydrate bylines:\", msg);\n\t\t}\n\t}\n}\n\n/**\n * Eagerly hydrate taxonomy term data onto entry.data for one or more entries.\n *\n * Attaches `terms` (Record keyed by taxonomy name with an array of TaxonomyTerm\n * values) to each entry's data object. Uses a single batched JOIN query across\n * all taxonomies so the cost is O(1) regardless of the number of entries or\n * taxonomies on the site.\n *\n * This eliminates the common N+1 pattern where templates loop over list\n * results and call getEntryTerms() per entry. With hydration, the list page\n * stays at a single round-trip for term data.\n *\n * `locale` is the preferred locale the entries were resolved to. Each assigned\n * group resolves that variant first, then the configured default. When it is\n * omitted, the stored locale of each content row is preferred.\n *\n * Fails silently if the taxonomy tables don't exist yet (pre-migration).\n */\nasync function hydrateEntryTerms<D>(\n\ttype: string,\n\tentries: ContentEntry<D>[],\n\tlocale?: string,\n): Promise<void> {\n\tif (entries.length === 0) return;\n\n\t// Fast path: terms were folded into the content query. Group the JSON and\n\t// skip the separate content_taxonomies query.\n\tif (entries.every((e) => FOLDED_TERMS in entryData(e))) {\n\t\tconst perEntry: Array<{ entryId: string; byTaxonomy: Record<string, TaxonomyTerm[]> }> = [];\n\t\tfor (const entry of entries) {\n\t\t\tconst data = entryData(entry);\n\t\t\tconst folded = Reflect.get(data, FOLDED_TERMS);\n\t\t\tconst rows = Array.isArray(folded) ? folded : [];\n\t\t\tconst grouped: Record<string, TaxonomyTerm[]> = {};\n\t\t\tfor (const r of rows) {\n\t\t\t\tconst name = String(r?.name);\n\t\t\t\t(grouped[name] ??= []).push({\n\t\t\t\t\tid: r?.id,\n\t\t\t\t\tname,\n\t\t\t\t\tslug: r?.slug,\n\t\t\t\t\tlabel: r?.label,\n\t\t\t\t\tparentId: r?.parent_id ?? undefined,\n\t\t\t\t\tchildren: [],\n\t\t\t\t\tlocale: r?.locale,\n\t\t\t\t\ttranslationGroup: r?.translation_group,\n\t\t\t\t});\n\t\t\t}\n\t\t\t// Match getAllTermsForEntries' ORDER BY label (dropped from the\n\t\t\t// aggregate since SQLite and Postgres order it differently).\n\t\t\tfor (const [name, arr] of Object.entries(grouped)) {\n\t\t\t\tgrouped[name] = arr.toSorted((a, b) => String(a.label).localeCompare(String(b.label)));\n\t\t\t}\n\t\t\tdata.terms = grouped;\n\t\t\tconst entryId = dataStr(data, \"id\");\n\t\t\tif (entryId) perEntry.push({ entryId, byTaxonomy: grouped });\n\t\t}\n\t\t// Prime the per-entry request cache (wildcard + present taxonomies) so\n\t\t// subsequent getEntryTerms(...) calls in this render hit the cache instead\n\t\t// of issuing an N+1 query. No DB lookup — purely from the folded data.\n\t\tconst { primeFoldedEntryTerms } = await import(\"./taxonomies/index.js\");\n\t\tprimeFoldedEntryTerms(type, perEntry, { locale });\n\t\treturn;\n\t}\n\n\ttry {\n\t\tconst { getAllTermsForEntries } = await import(\"./taxonomies/index.js\");\n\n\t\tconst ids = entries.map((e) => dataStr(entryData(e), \"id\")).filter(Boolean);\n\t\tif (ids.length === 0) return;\n\n\t\tconst termsMap = await getAllTermsForEntries(type, ids, { locale });\n\n\t\tfor (const entry of entries) {\n\t\t\tconst data = entryData(entry);\n\t\t\tconst dbId = dataStr(data, \"id\");\n\t\t\tif (!dbId) continue;\n\n\t\t\tdata.terms = termsMap.get(dbId) ?? {};\n\t\t}\n\t} catch (err) {\n\t\t// Only swallow \"table not found\" errors from pre-migration databases.\n\t\t// Matches SQLite/D1 (\"no such table\") and PostgreSQL (\"relation/table\n\t\t// ... does not exist\") via the shared helper.\n\t\tif (!isMissingTableError(err)) {\n\t\t\tconst msg = err instanceof Error ? err.message : String(err);\n\t\t\tconsole.warn(\"[emdash] Failed to hydrate terms:\", msg);\n\t\t}\n\t}\n}\n\n/**\n * Translation summary for a single locale variant\n */\nexport interface TranslationSummary {\n\t/** Content item ID */\n\tid: string;\n\t/** Locale code (e.g. \"en\", \"fr\") */\n\tlocale: string;\n\t/** URL slug */\n\tslug: string | null;\n\t/** Current status */\n\tstatus: string;\n}\n\n/**\n * Result from getTranslations\n */\nexport interface TranslationsResult {\n\t/** The translation group ID (shared across locales) */\n\ttranslationGroup: string;\n\t/** All locale variants in this group */\n\ttranslations: TranslationSummary[];\n\t/** Error if the query failed */\n\terror?: Error;\n}\n\n/**\n * Get all translations of a content item.\n *\n * Given a content entry, returns all locale variants that share the same\n * translation group. This is useful for building language switcher UI.\n *\n * @example\n * ```ts\n * import { getEmDashEntry, getTranslations } from \"emdash\";\n *\n * const { entry: post } = await getEmDashEntry(\"posts\", \"hello-world\", { locale: \"en\" });\n * const { translations } = await getTranslations(\"posts\", post.data.id);\n * // translations = [{ id: \"...\", locale: \"en\", slug: \"hello-world\", status: \"published\" }, ...]\n * ```\n */\nexport async function getTranslations(type: string, id: string): Promise<TranslationsResult> {\n\ttry {\n\t\tconst db = (await import(\"./loader.js\")).getDb;\n\t\tconst dbInstance = await db();\n\t\tconst { ContentRepository } = await import(\"./database/repositories/content.js\");\n\t\tconst repo = new ContentRepository(dbInstance);\n\n\t\t// Find the item to get its translation group\n\t\tconst item = await repo.findByIdOrSlug(type, id);\n\t\tif (!item) {\n\t\t\treturn {\n\t\t\t\ttranslationGroup: \"\",\n\t\t\t\ttranslations: [],\n\t\t\t\terror: new Error(`Content item not found: ${id}`),\n\t\t\t};\n\t\t}\n\n\t\tconst group = item.translationGroup || item.id;\n\t\tconst translations = await repo.findTranslations(type, group);\n\n\t\treturn {\n\t\t\ttranslationGroup: group,\n\t\t\ttranslations: translations.map((t) => ({\n\t\t\t\tid: t.id,\n\t\t\t\tlocale: t.locale || \"en\",\n\t\t\t\tslug: t.slug,\n\t\t\t\tstatus: t.status,\n\t\t\t})),\n\t\t};\n\t} catch (error) {\n\t\treturn {\n\t\t\ttranslationGroup: \"\",\n\t\t\ttranslations: [],\n\t\t\terror: error instanceof Error ? error : new Error(String(error)),\n\t\t};\n\t}\n}\n\n/**\n * Result from resolveEmDashPath\n */\nexport interface ResolvePathResult<T = Record<string, unknown>> {\n\t/** The matched entry */\n\tentry: ContentEntry<T>;\n\t/** The collection slug that matched */\n\tcollection: string;\n\t/** Extracted parameters from the URL pattern (e.g. { slug: \"my-post\" }) */\n\tparams: Record<string, string>;\n}\n\n/** Cached compiled URL patterns for resolveEmDashPath */\ninterface CachedPattern {\n\tslug: string;\n\tregex: RegExp;\n\tparamNames: string[];\n}\n\ninterface UrlPatternCache {\n\tpatterns: CachedPattern[] | null;\n}\n\nconst URL_PATTERN_CACHE_KEY = Symbol.for(\"emdash:url-pattern-cache\");\nconst queryGlobal = globalThis as Record<symbol, unknown>;\nconst urlPatternCache: UrlPatternCache =\n\t// eslint-disable-next-line typescript/no-unsafe-type-assertion -- globalThis singleton pattern (see request-context.ts)\n\t(queryGlobal[URL_PATTERN_CACHE_KEY] as UrlPatternCache | undefined) ??\n\t(() => {\n\t\tconst cache: UrlPatternCache = { patterns: null };\n\t\tqueryGlobal[URL_PATTERN_CACHE_KEY] = cache;\n\t\treturn cache;\n\t})();\n\n/**\n * Invalidate the cached URL patterns used by resolveEmDashPath.\n * Call when collection URL patterns change (schema updates).\n *\n * Also busts the distributed schema cache (collection metadata such as\n * `commentsEnabled`, `supports`, fields read by `getCollectionInfo`) and the\n * per-isolate registered-collection-slugs cache used by term counting, since\n * every schema-mutation path already routes through here.\n */\nexport function invalidateUrlPatternCache(): void {\n\turlPatternCache.patterns = null;\n\tresetRegisteredCollectionsCache();\n\tinvalidateSchemaObjectCache();\n}\n\n/**\n * Resolve a URL path to a content entry by matching against collection URL patterns.\n *\n * Loads all collections with a `urlPattern` set, converts each pattern to a regex,\n * and tests the given path. On match, extracts the slug and fetches the entry.\n *\n * @example\n * ```ts\n * import { resolveEmDashPath } from \"emdash\";\n *\n * // Given pages with urlPattern \"/{slug}\" and posts with \"/blog/{slug}\":\n * const result = await resolveEmDashPath(\"/blog/hello-world\");\n * if (result) {\n * console.log(result.collection); // \"posts\"\n * console.log(result.params.slug); // \"hello-world\"\n * console.log(result.entry.data); // post data\n * }\n * ```\n */\nexport async function resolveEmDashPath<T = Record<string, unknown>>(\n\tpath: string,\n): Promise<ResolvePathResult<T> | null> {\n\t// Build and cache compiled patterns on first call\n\tlet cachedUrlPatterns = urlPatternCache.patterns;\n\tif (!cachedUrlPatterns) {\n\t\tconst { getDb } = await import(\"./loader.js\");\n\t\tconst { SchemaRegistry } = await import(\"./schema/registry.js\");\n\t\tconst db = await getDb();\n\t\tconst registry = new SchemaRegistry(db);\n\t\tconst collections = await registry.listCollections();\n\n\t\tcachedUrlPatterns = [];\n\t\tfor (const collection of collections) {\n\t\t\tif (!collection.urlPattern) continue;\n\t\t\tconst { regex, paramNames } = compileUrlPattern(collection.urlPattern);\n\t\t\tcachedUrlPatterns.push({ slug: collection.slug, regex, paramNames });\n\t\t}\n\t\turlPatternCache.patterns = cachedUrlPatterns;\n\t}\n\n\tfor (const pattern of cachedUrlPatterns) {\n\t\tconst match = path.match(pattern.regex);\n\t\tif (!match) continue;\n\n\t\t// Extract params\n\t\tconst params: Record<string, string> = {};\n\t\tfor (let i = 0; i < pattern.paramNames.length; i++) {\n\t\t\tparams[pattern.paramNames[i]] = match[i + 1];\n\t\t}\n\n\t\t// Look up entry by slug (most common pattern)\n\t\tconst slug = params.slug;\n\t\tif (!slug) continue;\n\n\t\tconst { entry } = await getEmDashEntry<string, T>(pattern.slug, slug);\n\t\tif (entry) {\n\t\t\treturn { entry, collection: pattern.slug, params };\n\t\t}\n\t}\n\n\treturn null;\n}\n"],"mappings":"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"}
@@ -0,0 +1,41 @@
1
+ import { n as cachedQuery, t as CacheNamespace } from "./object-cache-CqWNY5uP.mjs";
2
+ import { r as requestCached } from "./request-cache-iHRlHx1d.mjs";
3
+ import { s as getDb } from "./loader-CrRPfkHS.mjs";
4
+ import { n as SchemaRegistry } from "./registry-CFcNCayZ.mjs";
5
+
6
+ //#region src/schema/query.ts
7
+ /**
8
+ * Get collection metadata by slug.
9
+ *
10
+ * @example
11
+ * ```ts
12
+ * import { getCollectionInfo } from "emdash";
13
+ *
14
+ * const info = await getCollectionInfo("posts");
15
+ * if (info?.commentsEnabled) {
16
+ * // render comment UI
17
+ * }
18
+ * ```
19
+ */
20
+ async function getCollectionInfo(slug) {
21
+ return requestCached(`collection-info:${slug}`, () => cachedQuery({
22
+ namespace: CacheNamespace.SCHEMA,
23
+ key: `collection-info:${slug}`,
24
+ load: async () => {
25
+ return getCollectionInfoWithDb(await getDb(), slug);
26
+ }
27
+ }));
28
+ }
29
+ /**
30
+ * Get collection metadata with an explicit db handle.
31
+ *
32
+ * @internal Use `getCollectionInfo()` in templates. This variant is for
33
+ * routes that already have a database handle.
34
+ */
35
+ async function getCollectionInfoWithDb(db, slug) {
36
+ return new SchemaRegistry(db).getCollection(slug);
37
+ }
38
+
39
+ //#endregion
40
+ export { getCollectionInfoWithDb as n, getCollectionInfo as t };
41
+ //# sourceMappingURL=query-OzMJ6vJP.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"query-OzMJ6vJP.mjs","names":[],"sources":["../src/schema/query.ts"],"sourcesContent":["/**\n * Collection info query for Astro templates.\n *\n * Same pattern as getMenu() / getComments() — uses getDb() for ambient DB access.\n */\n\nimport type { Kysely } from \"kysely\";\n\nimport type { Database } from \"../database/types.js\";\nimport { getDb } from \"../loader.js\";\nimport { cachedQuery, CacheNamespace } from \"../object-cache/index.js\";\nimport { requestCached } from \"../request-cache.js\";\nimport { SchemaRegistry } from \"./registry.js\";\nimport type { Collection } from \"./types.js\";\n\n/**\n * Get collection metadata by slug.\n *\n * @example\n * ```ts\n * import { getCollectionInfo } from \"emdash\";\n *\n * const info = await getCollectionInfo(\"posts\");\n * if (info?.commentsEnabled) {\n * // render comment UI\n * }\n * ```\n */\nexport async function getCollectionInfo(slug: string): Promise<Collection | null> {\n\treturn requestCached(`collection-info:${slug}`, () =>\n\t\tcachedQuery({\n\t\t\tnamespace: CacheNamespace.SCHEMA,\n\t\t\tkey: `collection-info:${slug}`,\n\t\t\tload: async () => {\n\t\t\t\tconst db = await getDb();\n\t\t\t\treturn getCollectionInfoWithDb(db, slug);\n\t\t\t},\n\t\t}),\n\t);\n}\n\n/**\n * Get collection metadata with an explicit db handle.\n *\n * @internal Use `getCollectionInfo()` in templates. This variant is for\n * routes that already have a database handle.\n */\nexport async function getCollectionInfoWithDb(\n\tdb: Kysely<Database>,\n\tslug: string,\n): Promise<Collection | null> {\n\tconst registry = new SchemaRegistry(db);\n\treturn registry.getCollection(slug);\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;AA4BA,eAAsB,kBAAkB,MAA0C;AACjF,QAAO,cAAc,mBAAmB,cACvC,YAAY;EACX,WAAW,eAAe;EAC1B,KAAK,mBAAmB;EACxB,MAAM,YAAY;AAEjB,UAAO,wBADI,MAAM,OAAO,EACW,KAAK;;EAEzC,CAAC,CACF;;;;;;;;AASF,eAAsB,wBACrB,IACA,MAC6B;AAE7B,QADiB,IAAI,eAAe,GAAG,CACvB,cAAc,KAAK"}
@@ -0,0 +1,120 @@
1
+ import { t as apiError } from "./error-BfsNNrIE.mjs";
2
+ import { sql } from "kysely";
3
+
4
+ //#region src/auth/rate-limit.ts
5
+ /** Loose validation for IPv4 and IPv6 addresses. */
6
+ const IP_PATTERN = /^[\da-fA-F.:]+$/;
7
+ /**
8
+ * Check (and increment) the rate limit for a given IP + endpoint.
9
+ *
10
+ * If `ip` is null (no trusted IP available), rate limiting is skipped
11
+ * and the request is allowed. There's no meaningful key to rate limit
12
+ * on when the IP is unknown.
13
+ *
14
+ * Returns whether the request is allowed. The counter is always
15
+ * incremented — even when the limit is exceeded — so that repeated
16
+ * abuse doesn't reset the window.
17
+ *
18
+ * Piggybacks cleanup of expired entries with a 1% probability
19
+ * to prevent unbounded table growth.
20
+ */
21
+ async function checkRateLimit(db, ip, endpoint, maxRequests, windowSeconds) {
22
+ if (!ip) return {
23
+ allowed: true,
24
+ count: 0,
25
+ limit: maxRequests
26
+ };
27
+ const windowStart = (/* @__PURE__ */ new Date(Math.floor(Date.now() / (windowSeconds * 1e3)) * windowSeconds * 1e3)).toISOString();
28
+ const count = (await sql`
29
+ INSERT INTO _emdash_rate_limits (key, "window", count)
30
+ VALUES (${`${ip}:${endpoint}`}, ${windowStart}, 1)
31
+ ON CONFLICT (key, "window")
32
+ DO UPDATE SET count = _emdash_rate_limits.count + 1
33
+ RETURNING count
34
+ `.execute(db)).rows[0]?.count ?? 1;
35
+ if (Math.random() < .01) cleanupExpiredRateLimits(db).catch(() => {});
36
+ return {
37
+ allowed: count <= maxRequests,
38
+ count,
39
+ limit: maxRequests
40
+ };
41
+ }
42
+ /**
43
+ * Build a 429 Too Many Requests response with standard headers.
44
+ */
45
+ function rateLimitResponse(retryAfterSeconds) {
46
+ const response = apiError("RATE_LIMITED", "Too many requests. Please try again later.", 429);
47
+ response.headers.set("Retry-After", String(retryAfterSeconds));
48
+ return response;
49
+ }
50
+ /**
51
+ * Extract client IP from a Request.
52
+ *
53
+ * Resolution order:
54
+ * 1. `CF-Connecting-IP` — trusted only when the Cloudflare `cf` object is
55
+ * present. CF edge overwrites any client-supplied value, so this is the
56
+ * cryptographically trustworthy path on Workers. Operator-declared
57
+ * trusted headers cannot override it.
58
+ * 2. `X-Forwarded-For` (first entry) — trusted only when the `cf` object
59
+ * is present (CF sets this reliably).
60
+ * 3. Operator-declared trusted proxy headers (ordered list) — used as a
61
+ * fallback for non-CF deployments behind a reverse proxy the operator
62
+ * controls. Also applies as a fill-in on CF when the CF headers are
63
+ * absent (e.g. internal cron handlers).
64
+ * 4. `null` — no trusted IP available. Callers must handle this gracefully
65
+ * (e.g. skip rate limiting).
66
+ *
67
+ * Pass `trustedHeaders` from `getTrustedProxyHeaders(emdash.config)` so
68
+ * self-hosted non-CF deployments can opt into reading a specific header.
69
+ *
70
+ * Aligned with `extractRequestMeta` in `plugins/request-meta.ts`.
71
+ */
72
+ function getClientIp(request, trustedHeaders = []) {
73
+ const headers = request.headers;
74
+ if (request.cf) {
75
+ const cfIp = headers.get("cf-connecting-ip")?.trim();
76
+ if (cfIp && IP_PATTERN.test(cfIp)) return cfIp;
77
+ const xff = headers.get("x-forwarded-for");
78
+ if (xff) {
79
+ const first = xff.split(",")[0]?.trim();
80
+ if (first && IP_PATTERN.test(first)) return first;
81
+ }
82
+ }
83
+ for (const name of trustedHeaders) {
84
+ const value = readIpFromHeader(headers, name);
85
+ if (value) return value;
86
+ }
87
+ return null;
88
+ }
89
+ /**
90
+ * Read an IP from an operator-declared trusted header. XFF-style headers
91
+ * are parsed as comma-separated lists and the first entry is used.
92
+ */
93
+ function readIpFromHeader(headers, name) {
94
+ const value = headers.get(name);
95
+ if (!value) return null;
96
+ if (name.toLowerCase().endsWith("forwarded-for")) {
97
+ const first = value.split(",")[0]?.trim();
98
+ if (!first) return null;
99
+ return IP_PATTERN.test(first) ? first : null;
100
+ }
101
+ const trimmed = value.trim();
102
+ if (!trimmed) return null;
103
+ return IP_PATTERN.test(trimmed) ? trimmed : null;
104
+ }
105
+ /**
106
+ * Delete expired rate limit entries.
107
+ *
108
+ * Entries with a window timestamp older than `maxAgeSeconds` are removed.
109
+ * Safe to call periodically (e.g., from cron cleanup or on-request piggyback).
110
+ */
111
+ async function cleanupExpiredRateLimits(db, maxAgeSeconds = 3600) {
112
+ const result = await sql`
113
+ DELETE FROM _emdash_rate_limits WHERE "window" < ${(/* @__PURE__ */ new Date(Date.now() - maxAgeSeconds * 1e3)).toISOString()}
114
+ `.execute(db);
115
+ return Number(result.numAffectedRows ?? 0);
116
+ }
117
+
118
+ //#endregion
119
+ export { getClientIp as n, rateLimitResponse as r, checkRateLimit as t };
120
+ //# sourceMappingURL=rate-limit-Csp60Vik.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"rate-limit-Csp60Vik.mjs","names":[],"sources":["../src/auth/rate-limit.ts"],"sourcesContent":["/**\n * Database-backed rate limiter for unauthenticated endpoints.\n *\n * Uses a `_emdash_rate_limits` table with composite primary key (key, window).\n * Each call to `checkRateLimit` atomically upserts a counter and returns\n * whether the request is within the allowed limit.\n *\n * Key format: `{ip}:{endpoint}` — limits are per-IP, per-endpoint. Callers\n * may pass a salted IP hash instead of the raw address.\n * Window format: ISO timestamp truncated to the window size.\n */\n\nimport type { Kysely } from \"kysely\";\nimport { sql } from \"kysely\";\n\nimport { apiError } from \"../api/error.js\";\nimport type { Database } from \"../database/types.js\";\n\n/** Loose validation for IPv4 and IPv6 addresses. */\nconst IP_PATTERN = /^[\\da-fA-F.:]+$/;\n\n/**\n * Result of a rate limit check.\n */\nexport interface RateLimitResult {\n\t/** Whether the request is allowed (within limit). */\n\tallowed: boolean;\n\t/** Current request count in this window. */\n\tcount: number;\n\t/** Maximum requests allowed in this window. */\n\tlimit: number;\n}\n\n/**\n * Check (and increment) the rate limit for a given IP + endpoint.\n *\n * If `ip` is null (no trusted IP available), rate limiting is skipped\n * and the request is allowed. There's no meaningful key to rate limit\n * on when the IP is unknown.\n *\n * Returns whether the request is allowed. The counter is always\n * incremented — even when the limit is exceeded — so that repeated\n * abuse doesn't reset the window.\n *\n * Piggybacks cleanup of expired entries with a 1% probability\n * to prevent unbounded table growth.\n */\nexport async function checkRateLimit(\n\tdb: Kysely<Database>,\n\tip: string | null,\n\tendpoint: string,\n\tmaxRequests: number,\n\twindowSeconds: number,\n): Promise<RateLimitResult> {\n\t// No trusted IP — skip rate limiting entirely\n\tif (!ip) {\n\t\treturn { allowed: true, count: 0, limit: maxRequests };\n\t}\n\n\tconst windowStart = new Date(\n\t\tMath.floor(Date.now() / (windowSeconds * 1000)) * windowSeconds * 1000,\n\t).toISOString();\n\tconst key = `${ip}:${endpoint}`;\n\n\t// Atomic upsert: insert or increment, return current count\n\tconst result = await sql<{ count: number }>`\n\t\tINSERT INTO _emdash_rate_limits (key, \"window\", count)\n\t\tVALUES (${key}, ${windowStart}, 1)\n\t\tON CONFLICT (key, \"window\")\n\t\tDO UPDATE SET count = _emdash_rate_limits.count + 1\n\t\tRETURNING count\n\t`.execute(db);\n\n\tconst count = result.rows[0]?.count ?? 1;\n\n\t// Piggyback cleanup: 1% chance per request to clean expired entries\n\tif (Math.random() < 0.01) {\n\t\tcleanupExpiredRateLimits(db).catch(() => {\n\t\t\t// Swallow errors — cleanup is best-effort\n\t\t});\n\t}\n\n\treturn {\n\t\tallowed: count <= maxRequests,\n\t\tcount,\n\t\tlimit: maxRequests,\n\t};\n}\n\n/**\n * Build a 429 Too Many Requests response with standard headers.\n */\nexport function rateLimitResponse(retryAfterSeconds: number): Response {\n\tconst response = apiError(\"RATE_LIMITED\", \"Too many requests. Please try again later.\", 429);\n\tresponse.headers.set(\"Retry-After\", String(retryAfterSeconds));\n\treturn response;\n}\n\n/**\n * Extract client IP from a Request.\n *\n * Resolution order:\n * 1. `CF-Connecting-IP` — trusted only when the Cloudflare `cf` object is\n * present. CF edge overwrites any client-supplied value, so this is the\n * cryptographically trustworthy path on Workers. Operator-declared\n * trusted headers cannot override it.\n * 2. `X-Forwarded-For` (first entry) — trusted only when the `cf` object\n * is present (CF sets this reliably).\n * 3. Operator-declared trusted proxy headers (ordered list) — used as a\n * fallback for non-CF deployments behind a reverse proxy the operator\n * controls. Also applies as a fill-in on CF when the CF headers are\n * absent (e.g. internal cron handlers).\n * 4. `null` — no trusted IP available. Callers must handle this gracefully\n * (e.g. skip rate limiting).\n *\n * Pass `trustedHeaders` from `getTrustedProxyHeaders(emdash.config)` so\n * self-hosted non-CF deployments can opt into reading a specific header.\n *\n * Aligned with `extractRequestMeta` in `plugins/request-meta.ts`.\n */\nexport function getClientIp(request: Request, trustedHeaders: string[] = []): string | null {\n\tconst headers = request.headers;\n\t// eslint-disable-next-line typescript/no-unsafe-type-assertion -- CF Workers runtime shape\n\tconst cf = (request as unknown as { cf?: Record<string, unknown> }).cf;\n\n\t// On Cloudflare, prefer the cryptographically trustworthy headers. An\n\t// attacker can't spoof these — the CF edge strips/overwrites them.\n\tif (cf) {\n\t\tconst cfIp = headers.get(\"cf-connecting-ip\")?.trim();\n\t\tif (cfIp && IP_PATTERN.test(cfIp)) {\n\t\t\treturn cfIp;\n\t\t}\n\n\t\tconst xff = headers.get(\"x-forwarded-for\");\n\t\tif (xff) {\n\t\t\tconst first = xff.split(\",\")[0]?.trim();\n\t\t\tif (first && IP_PATTERN.test(first)) {\n\t\t\t\treturn first;\n\t\t\t}\n\t\t}\n\t}\n\n\t// Fall through to operator-declared trusted headers. On CF this fills\n\t// in when the CF headers are absent; off-CF it's the primary source.\n\tfor (const name of trustedHeaders) {\n\t\tconst value = readIpFromHeader(headers, name);\n\t\tif (value) return value;\n\t}\n\n\treturn null;\n}\n\n/**\n * Read an IP from an operator-declared trusted header. XFF-style headers\n * are parsed as comma-separated lists and the first entry is used.\n */\nfunction readIpFromHeader(headers: Headers, name: string): string | null {\n\tconst value = headers.get(name);\n\tif (!value) return null;\n\tif (name.toLowerCase().endsWith(\"forwarded-for\")) {\n\t\tconst first = value.split(\",\")[0]?.trim();\n\t\tif (!first) return null;\n\t\treturn IP_PATTERN.test(first) ? first : null;\n\t}\n\tconst trimmed = value.trim();\n\tif (!trimmed) return null;\n\treturn IP_PATTERN.test(trimmed) ? trimmed : null;\n}\n\n/**\n * Delete expired rate limit entries.\n *\n * Entries with a window timestamp older than `maxAgeSeconds` are removed.\n * Safe to call periodically (e.g., from cron cleanup or on-request piggyback).\n */\nexport async function cleanupExpiredRateLimits(\n\tdb: Kysely<Database>,\n\tmaxAgeSeconds = 3600,\n): Promise<number> {\n\tconst cutoff = new Date(Date.now() - maxAgeSeconds * 1000).toISOString();\n\n\tconst result = await sql`\n\t\tDELETE FROM _emdash_rate_limits WHERE \"window\" < ${cutoff}\n\t`.execute(db);\n\n\treturn Number(result.numAffectedRows ?? 0);\n}\n"],"mappings":";;;;;AAmBA,MAAM,aAAa;;;;;;;;;;;;;;;AA4BnB,eAAsB,eACrB,IACA,IACA,UACA,aACA,eAC2B;AAE3B,KAAI,CAAC,GACJ,QAAO;EAAE,SAAS;EAAM,OAAO;EAAG,OAAO;EAAa;CAGvD,MAAM,+BAAc,IAAI,KACvB,KAAK,MAAM,KAAK,KAAK,IAAI,gBAAgB,KAAM,GAAG,gBAAgB,IAClE,EAAC,aAAa;CAYf,MAAM,SARS,MAAM,GAAsB;;YAH/B,GAAG,GAAG,GAAG,WAKN,IAAI,YAAY;;;;GAI7B,QAAQ,GAAG,EAEQ,KAAK,IAAI,SAAS;AAGvC,KAAI,KAAK,QAAQ,GAAG,IACnB,0BAAyB,GAAG,CAAC,YAAY,GAEvC;AAGH,QAAO;EACN,SAAS,SAAS;EAClB;EACA,OAAO;EACP;;;;;AAMF,SAAgB,kBAAkB,mBAAqC;CACtE,MAAM,WAAW,SAAS,gBAAgB,8CAA8C,IAAI;AAC5F,UAAS,QAAQ,IAAI,eAAe,OAAO,kBAAkB,CAAC;AAC9D,QAAO;;;;;;;;;;;;;;;;;;;;;;;;AAyBR,SAAgB,YAAY,SAAkB,iBAA2B,EAAE,EAAiB;CAC3F,MAAM,UAAU,QAAQ;AAMxB,KAJY,QAAwD,IAI5D;EACP,MAAM,OAAO,QAAQ,IAAI,mBAAmB,EAAE,MAAM;AACpD,MAAI,QAAQ,WAAW,KAAK,KAAK,CAChC,QAAO;EAGR,MAAM,MAAM,QAAQ,IAAI,kBAAkB;AAC1C,MAAI,KAAK;GACR,MAAM,QAAQ,IAAI,MAAM,IAAI,CAAC,IAAI,MAAM;AACvC,OAAI,SAAS,WAAW,KAAK,MAAM,CAClC,QAAO;;;AAOV,MAAK,MAAM,QAAQ,gBAAgB;EAClC,MAAM,QAAQ,iBAAiB,SAAS,KAAK;AAC7C,MAAI,MAAO,QAAO;;AAGnB,QAAO;;;;;;AAOR,SAAS,iBAAiB,SAAkB,MAA6B;CACxE,MAAM,QAAQ,QAAQ,IAAI,KAAK;AAC/B,KAAI,CAAC,MAAO,QAAO;AACnB,KAAI,KAAK,aAAa,CAAC,SAAS,gBAAgB,EAAE;EACjD,MAAM,QAAQ,MAAM,MAAM,IAAI,CAAC,IAAI,MAAM;AACzC,MAAI,CAAC,MAAO,QAAO;AACnB,SAAO,WAAW,KAAK,MAAM,GAAG,QAAQ;;CAEzC,MAAM,UAAU,MAAM,MAAM;AAC5B,KAAI,CAAC,QAAS,QAAO;AACrB,QAAO,WAAW,KAAK,QAAQ,GAAG,UAAU;;;;;;;;AAS7C,eAAsB,yBACrB,IACA,gBAAgB,MACE;CAGlB,MAAM,SAAS,MAAM,GAAG;sEAFT,IAAI,KAAK,KAAK,KAAK,GAAG,gBAAgB,IAAK,EAAC,aAAa,CAGb;GACzD,QAAQ,GAAG;AAEb,QAAO,OAAO,OAAO,mBAAmB,EAAE"}
@@ -0,0 +1,43 @@
1
+ import { a as isSha256Digest, l as receiptDigest } from "./digest-DVZ--cE9.mjs";
2
+ import { h as portableIdSchema } from "./kinds-CYmRESWj.mjs";
3
+ import { n as SITE_PACKAGE_FORMAT_VERSION } from "./version-DgYjhTud.mjs";
4
+ import { z } from "zod";
5
+
6
+ //#region src/transfer/format/receipt.ts
7
+ /**
8
+ * Import receipts. A receipt exists only for a verified import; its
9
+ * `receiptDigest` is the digest of the receipt without that property
10
+ * (see `format/digest.ts`), so anyone holding the JSON can check it.
11
+ */
12
+ const digest = z.custom(isSha256Digest, "Expected a sha256: digest");
13
+ const siteImportReceiptSchema = z.strictObject({
14
+ operationId: portableIdSchema,
15
+ packageDigest: digest,
16
+ planDigest: digest,
17
+ targetSiteId: portableIdSchema,
18
+ originSiteId: portableIdSchema,
19
+ formatVersion: z.literal(SITE_PACKAGE_FORMAT_VERSION),
20
+ importerEmDashVersion: z.string().min(1).max(128),
21
+ completedAt: z.string().min(1).max(64),
22
+ logicalDigest: digest,
23
+ counts: z.record(z.string().max(64), z.number().int().nonnegative()),
24
+ warnings: z.array(z.strictObject({
25
+ code: z.string().max(64),
26
+ message: z.string().max(1024)
27
+ })).max(500),
28
+ verification: z.literal("verified"),
29
+ receiptDigest: digest
30
+ });
31
+ async function sealReceipt(receipt) {
32
+ return {
33
+ ...receipt,
34
+ receiptDigest: await receiptDigest(receipt)
35
+ };
36
+ }
37
+ async function verifyReceiptDigest(receipt) {
38
+ return await receiptDigest(receipt) === receipt.receiptDigest;
39
+ }
40
+
41
+ //#endregion
42
+ export { siteImportReceiptSchema as n, verifyReceiptDigest as r, sealReceipt as t };
43
+ //# sourceMappingURL=receipt-B-aU4hpJ.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"receipt-B-aU4hpJ.mjs","names":[],"sources":["../src/transfer/format/receipt.ts"],"sourcesContent":["/**\n * Import receipts. A receipt exists only for a verified import; its\n * `receiptDigest` is the digest of the receipt without that property\n * (see `format/digest.ts`), so anyone holding the JSON can check it.\n */\n\nimport { z } from \"zod\";\n\nimport { isSha256Digest, receiptDigest, type Sha256Digest } from \"./digest.js\";\nimport { portableIdSchema } from \"./kinds.js\";\nimport { SITE_PACKAGE_FORMAT_VERSION } from \"./version.js\";\n\nconst digest = z.custom<Sha256Digest>(isSha256Digest, \"Expected a sha256: digest\");\n\nexport const siteImportReceiptSchema = z.strictObject({\n\toperationId: portableIdSchema,\n\tpackageDigest: digest,\n\tplanDigest: digest,\n\ttargetSiteId: portableIdSchema,\n\toriginSiteId: portableIdSchema,\n\tformatVersion: z.literal(SITE_PACKAGE_FORMAT_VERSION),\n\timporterEmDashVersion: z.string().min(1).max(128),\n\tcompletedAt: z.string().min(1).max(64),\n\tlogicalDigest: digest,\n\tcounts: z.record(z.string().max(64), z.number().int().nonnegative()),\n\twarnings: z\n\t\t.array(z.strictObject({ code: z.string().max(64), message: z.string().max(1024) }))\n\t\t.max(500),\n\tverification: z.literal(\"verified\"),\n\treceiptDigest: digest,\n});\n\nexport type SiteImportReceipt = z.infer<typeof siteImportReceiptSchema>;\n\nexport type UnsignedSiteImportReceipt = Omit<SiteImportReceipt, \"receiptDigest\">;\n\nexport async function sealReceipt(receipt: UnsignedSiteImportReceipt): Promise<SiteImportReceipt> {\n\treturn { ...receipt, receiptDigest: await receiptDigest(receipt) };\n}\n\nexport async function verifyReceiptDigest(receipt: SiteImportReceipt): Promise<boolean> {\n\treturn (await receiptDigest(receipt)) === receipt.receiptDigest;\n}\n"],"mappings":";;;;;;;;;;;AAYA,MAAM,SAAS,EAAE,OAAqB,gBAAgB,4BAA4B;AAElF,MAAa,0BAA0B,EAAE,aAAa;CACrD,aAAa;CACb,eAAe;CACf,YAAY;CACZ,cAAc;CACd,cAAc;CACd,eAAe,EAAE,QAAQ,4BAA4B;CACrD,uBAAuB,EAAE,QAAQ,CAAC,IAAI,EAAE,CAAC,IAAI,IAAI;CACjD,aAAa,EAAE,QAAQ,CAAC,IAAI,EAAE,CAAC,IAAI,GAAG;CACtC,eAAe;CACf,QAAQ,EAAE,OAAO,EAAE,QAAQ,CAAC,IAAI,GAAG,EAAE,EAAE,QAAQ,CAAC,KAAK,CAAC,aAAa,CAAC;CACpE,UAAU,EACR,MAAM,EAAE,aAAa;EAAE,MAAM,EAAE,QAAQ,CAAC,IAAI,GAAG;EAAE,SAAS,EAAE,QAAQ,CAAC,IAAI,KAAK;EAAE,CAAC,CAAC,CAClF,IAAI,IAAI;CACV,cAAc,EAAE,QAAQ,WAAW;CACnC,eAAe;CACf,CAAC;AAMF,eAAsB,YAAY,SAAgE;AACjG,QAAO;EAAE,GAAG;EAAS,eAAe,MAAM,cAAc,QAAQ;EAAE;;AAGnE,eAAsB,oBAAoB,SAA8C;AACvF,QAAQ,MAAM,cAAc,QAAQ,KAAM,QAAQ"}
@@ -0,0 +1,17 @@
1
+ //#region src/api/redirect.ts
2
+ /**
3
+ * Validate that a redirect URL is a safe local path.
4
+ *
5
+ * Rejects:
6
+ * - Protocol-relative URLs (`//evil.com`)
7
+ * - Backslash bypass (`/\evil.com` — browsers normalize `\` to `/` in Location headers)
8
+ * - Absolute URLs (`https://evil.com`)
9
+ * - Empty / nullish values
10
+ */
11
+ function isSafeRedirect(url) {
12
+ return typeof url === "string" && url.startsWith("/") && !url.startsWith("//") && !url.includes("\\");
13
+ }
14
+
15
+ //#endregion
16
+ export { isSafeRedirect as t };
17
+ //# sourceMappingURL=redirect-CDSw1sU3.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"redirect-CDSw1sU3.mjs","names":[],"sources":["../src/api/redirect.ts"],"sourcesContent":["/**\n * Validate that a redirect URL is a safe local path.\n *\n * Rejects:\n * - Protocol-relative URLs (`//evil.com`)\n * - Backslash bypass (`/\\evil.com` — browsers normalize `\\` to `/` in Location headers)\n * - Absolute URLs (`https://evil.com`)\n * - Empty / nullish values\n */\nexport function isSafeRedirect(url: string | null | undefined): url is string {\n\treturn (\n\t\ttypeof url === \"string\" && url.startsWith(\"/\") && !url.startsWith(\"//\") && !url.includes(\"\\\\\")\n\t);\n}\n"],"mappings":";;;;;;;;;;AASA,SAAgB,eAAe,KAA+C;AAC7E,QACC,OAAO,QAAQ,YAAY,IAAI,WAAW,IAAI,IAAI,CAAC,IAAI,WAAW,KAAK,IAAI,CAAC,IAAI,SAAS,KAAK"}