emdash 1.0.1 → 1.2.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 (1439) hide show
  1. package/dist/action-token-BdWad2YG.mjs +26 -0
  2. package/dist/action-token-BdWad2YG.mjs.map +1 -0
  3. package/dist/activation-xomsCMJg.mjs +387 -0
  4. package/dist/activation-xomsCMJg.mjs.map +1 -0
  5. package/dist/adapters-B4-nbElt.d.mts +173 -0
  6. package/dist/adapters-B4-nbElt.d.mts.map +1 -0
  7. package/dist/allowed-origins-CLpHGGlc.mjs +116 -0
  8. package/dist/allowed-origins-CLpHGGlc.mjs.map +1 -0
  9. package/dist/api/route-utils.d.mts +4 -4
  10. package/dist/api/route-utils.d.mts.map +1 -1
  11. package/dist/api/route-utils.mjs +49 -48
  12. package/dist/api/route-utils.mjs.map +1 -1
  13. package/dist/api/schemas/index.d.mts +2 -2
  14. package/dist/api/schemas/index.mjs +10 -10
  15. package/dist/api-DBw_IWoi.mjs +5024 -0
  16. package/dist/api-DBw_IWoi.mjs.map +1 -0
  17. package/dist/api-tokens-B0ZipcZ-.mjs +173 -0
  18. package/dist/api-tokens-B0ZipcZ-.mjs.map +1 -0
  19. package/dist/apply-Cx48saFC.mjs +1680 -0
  20. package/dist/apply-Cx48saFC.mjs.map +1 -0
  21. package/dist/approvals-BXgtXA2s.mjs +460 -0
  22. package/dist/approvals-BXgtXA2s.mjs.map +1 -0
  23. package/dist/artifact-fetch-DsRczRGG.mjs +659 -0
  24. package/dist/artifact-fetch-DsRczRGG.mjs.map +1 -0
  25. package/dist/artifacts-D-O-qj9C.mjs +307 -0
  26. package/dist/artifacts-D-O-qj9C.mjs.map +1 -0
  27. package/dist/astro/image-endpoint.d.mts.map +1 -1
  28. package/dist/astro/image-endpoint.mjs +26 -6
  29. package/dist/astro/image-endpoint.mjs.map +1 -1
  30. package/dist/astro/index.d.mts +14 -14
  31. package/dist/astro/index.d.mts.map +1 -1
  32. package/dist/astro/index.mjs +253 -17
  33. package/dist/astro/index.mjs.map +1 -1
  34. package/dist/astro/middleware/auth.d.mts +12 -12
  35. package/dist/astro/middleware/auth.d.mts.map +1 -1
  36. package/dist/astro/middleware/auth.mjs +18 -13
  37. package/dist/astro/middleware/auth.mjs.map +1 -1
  38. package/dist/astro/middleware/media-usage-write-fence.mjs +6 -6
  39. package/dist/astro/middleware/redirect.d.mts.map +1 -1
  40. package/dist/astro/middleware/redirect.mjs +34 -32
  41. package/dist/astro/middleware/redirect.mjs.map +1 -1
  42. package/dist/astro/middleware/request-context.d.mts.map +1 -1
  43. package/dist/astro/middleware/request-context.mjs +99 -60
  44. package/dist/astro/middleware/request-context.mjs.map +1 -1
  45. package/dist/astro/middleware/setup.mjs +1 -1
  46. package/dist/astro/middleware.d.mts +12 -12
  47. package/dist/astro/middleware.d.mts.map +1 -1
  48. package/dist/astro/middleware.mjs +233 -128
  49. package/dist/astro/middleware.mjs.map +1 -1
  50. package/dist/astro/routes/api/admin/allowed-domains/_domain_.mjs +15 -15
  51. package/dist/astro/routes/api/admin/allowed-domains/index.mjs +15 -15
  52. package/dist/astro/routes/api/admin/api-tokens/_id_.mjs +8 -7
  53. package/dist/astro/routes/api/admin/api-tokens/_id_.mjs.map +1 -1
  54. package/dist/astro/routes/api/admin/api-tokens/index.mjs +9 -8
  55. package/dist/astro/routes/api/admin/api-tokens/index.mjs.map +1 -1
  56. package/dist/astro/routes/api/admin/byline-fields/_slug_/usage.mjs +7 -7
  57. package/dist/astro/routes/api/admin/byline-fields/_slug_.mjs +17 -17
  58. package/dist/astro/routes/api/admin/byline-fields/index.mjs +17 -17
  59. package/dist/astro/routes/api/admin/byline-fields/reorder.mjs +17 -17
  60. package/dist/astro/routes/api/admin/bylines/_id_/index.mjs +22 -22
  61. package/dist/astro/routes/api/admin/bylines/_id_/translations.mjs +22 -23
  62. package/dist/astro/routes/api/admin/bylines/_id_/translations.mjs.map +1 -1
  63. package/dist/astro/routes/api/admin/bylines/index.mjs +23 -23
  64. package/dist/astro/routes/api/admin/bylines/index.mjs.map +1 -1
  65. package/dist/astro/routes/api/admin/comments/_id_/status.mjs +19 -19
  66. package/dist/astro/routes/api/admin/comments/_id_.mjs +8 -8
  67. package/dist/astro/routes/api/admin/comments/bulk.mjs +18 -18
  68. package/dist/astro/routes/api/admin/comments/counts.mjs +8 -8
  69. package/dist/astro/routes/api/admin/comments/index.mjs +18 -18
  70. package/dist/astro/routes/api/admin/core-update.mjs +8 -8
  71. package/dist/astro/routes/api/admin/hooks/exclusive/_hookName_.mjs +7 -7
  72. package/dist/astro/routes/api/admin/hooks/exclusive/index.mjs +6 -6
  73. package/dist/astro/routes/api/admin/media-usage/activation.mjs +21 -21
  74. package/dist/astro/routes/api/admin/media-usage/collection-deletions/index.mjs +22 -22
  75. package/dist/astro/routes/api/admin/media-usage/collection-deletions/retry.mjs +22 -22
  76. package/dist/astro/routes/api/admin/media-usage/progress.mjs +23 -23
  77. package/dist/astro/routes/api/admin/media-usage/repair.mjs +29 -29
  78. package/dist/astro/routes/api/admin/media-usage/work/index.mjs +22 -22
  79. package/dist/astro/routes/api/admin/media-usage/work/retry.mjs +22 -22
  80. package/dist/astro/routes/api/admin/oauth-clients/_id_.mjs +7 -7
  81. package/dist/astro/routes/api/admin/oauth-clients/index.mjs +7 -7
  82. package/dist/astro/routes/api/admin/plugins/_id_/disable.mjs +9 -9
  83. package/dist/astro/routes/api/admin/plugins/_id_/enable.mjs +9 -9
  84. package/dist/astro/routes/api/admin/plugins/_id_/index.mjs +73 -72
  85. package/dist/astro/routes/api/admin/plugins/_id_/index.mjs.map +1 -1
  86. package/dist/astro/routes/api/admin/plugins/_id_/mcp.mjs +8 -8
  87. package/dist/astro/routes/api/admin/plugins/_id_/settings.mjs +71 -70
  88. package/dist/astro/routes/api/admin/plugins/_id_/settings.mjs.map +1 -1
  89. package/dist/astro/routes/api/admin/plugins/_id_/uninstall.mjs +72 -71
  90. package/dist/astro/routes/api/admin/plugins/_id_/uninstall.mjs.map +1 -1
  91. package/dist/astro/routes/api/admin/plugins/_id_/update.mjs +82 -81
  92. package/dist/astro/routes/api/admin/plugins/_id_/update.mjs.map +1 -1
  93. package/dist/astro/routes/api/admin/plugins/index.mjs +72 -71
  94. package/dist/astro/routes/api/admin/plugins/index.mjs.map +1 -1
  95. package/dist/astro/routes/api/admin/plugins/marketplace/_id_/icon.mjs +8 -8
  96. package/dist/astro/routes/api/admin/plugins/marketplace/_id_/index.mjs +71 -70
  97. package/dist/astro/routes/api/admin/plugins/marketplace/_id_/index.mjs.map +1 -1
  98. package/dist/astro/routes/api/admin/plugins/marketplace/_id_/install.mjs +81 -80
  99. package/dist/astro/routes/api/admin/plugins/marketplace/_id_/install.mjs.map +1 -1
  100. package/dist/astro/routes/api/admin/plugins/marketplace/index.mjs +71 -70
  101. package/dist/astro/routes/api/admin/plugins/marketplace/index.mjs.map +1 -1
  102. package/dist/astro/routes/api/admin/plugins/registry/_id_/uninstall.mjs +72 -71
  103. package/dist/astro/routes/api/admin/plugins/registry/_id_/uninstall.mjs.map +1 -1
  104. package/dist/astro/routes/api/admin/plugins/registry/_id_/update.mjs +83 -82
  105. package/dist/astro/routes/api/admin/plugins/registry/_id_/update.mjs.map +1 -1
  106. package/dist/astro/routes/api/admin/plugins/registry/artifact.mjs +10 -10
  107. package/dist/astro/routes/api/admin/plugins/registry/install.mjs +74 -73
  108. package/dist/astro/routes/api/admin/plugins/registry/install.mjs.map +1 -1
  109. package/dist/astro/routes/api/admin/plugins/registry/publisher-handle.mjs +8 -8
  110. package/dist/astro/routes/api/admin/plugins/registry/verify.mjs +72 -71
  111. package/dist/astro/routes/api/admin/plugins/registry/verify.mjs.map +1 -1
  112. package/dist/astro/routes/api/admin/plugins/updates.mjs +71 -70
  113. package/dist/astro/routes/api/admin/plugins/updates.mjs.map +1 -1
  114. package/dist/astro/routes/api/admin/scheduled-policy-rejections/_collection_/_id_.mjs +6 -6
  115. package/dist/astro/routes/api/admin/themes/marketplace/_id_/index.mjs +71 -70
  116. package/dist/astro/routes/api/admin/themes/marketplace/_id_/index.mjs.map +1 -1
  117. package/dist/astro/routes/api/admin/themes/marketplace/_id_/thumbnail.mjs +8 -8
  118. package/dist/astro/routes/api/admin/themes/marketplace/index.mjs +71 -70
  119. package/dist/astro/routes/api/admin/themes/marketplace/index.mjs.map +1 -1
  120. package/dist/astro/routes/api/admin/transfer/_...path_.mjs +5 -5
  121. package/dist/astro/routes/api/admin/transfer/approvals/_id_/approve.mjs +39 -39
  122. package/dist/astro/routes/api/admin/transfer/approvals/_id_/deny.mjs +39 -39
  123. package/dist/astro/routes/api/admin/transfer/approvals/index.mjs +41 -41
  124. package/dist/astro/routes/api/admin/transfer/capabilities.mjs +41 -41
  125. package/dist/astro/routes/api/admin/transfer/exports/_id_/advance.mjs +41 -41
  126. package/dist/astro/routes/api/admin/transfer/exports/_id_/archive.mjs +42 -42
  127. package/dist/astro/routes/api/admin/transfer/exports/_id_/files/_...path_.mjs +42 -42
  128. package/dist/astro/routes/api/admin/transfer/exports/_id_/index.mjs +41 -41
  129. package/dist/astro/routes/api/admin/transfer/exports/_id_/manifest.mjs +42 -42
  130. package/dist/astro/routes/api/admin/transfer/exports/index.mjs +43 -43
  131. package/dist/astro/routes/api/admin/transfer/imports/_id_/abandon.mjs +41 -41
  132. package/dist/astro/routes/api/admin/transfer/imports/_id_/advance.mjs +41 -41
  133. package/dist/astro/routes/api/admin/transfer/imports/_id_/analyze.mjs +43 -43
  134. package/dist/astro/routes/api/admin/transfer/imports/_id_/cancel.mjs +41 -41
  135. package/dist/astro/routes/api/admin/transfer/imports/_id_/execute.mjs +43 -43
  136. package/dist/astro/routes/api/admin/transfer/imports/_id_/files/_...path_.mjs +41 -41
  137. package/dist/astro/routes/api/admin/transfer/imports/_id_/index.mjs +41 -41
  138. package/dist/astro/routes/api/admin/transfer/imports/_id_/missing.mjs +43 -43
  139. package/dist/astro/routes/api/admin/transfer/imports/_id_/plan.mjs +41 -41
  140. package/dist/astro/routes/api/admin/transfer/imports/_id_/receipt.mjs +41 -41
  141. package/dist/astro/routes/api/admin/transfer/imports/index.mjs +43 -43
  142. package/dist/astro/routes/api/admin/users/_id_/disable.mjs +5 -5
  143. package/dist/astro/routes/api/admin/users/_id_/enable.mjs +5 -5
  144. package/dist/astro/routes/api/admin/users/_id_/index.mjs +15 -15
  145. package/dist/astro/routes/api/admin/users/_id_/send-recovery.mjs +7 -7
  146. package/dist/astro/routes/api/admin/users/index.mjs +15 -15
  147. package/dist/astro/routes/api/auth/dev-bypass.mjs +7 -7
  148. package/dist/astro/routes/api/auth/handover.d.mts +8 -0
  149. package/dist/astro/routes/api/auth/handover.d.mts.map +1 -0
  150. package/dist/astro/routes/api/auth/handover.mjs +49 -0
  151. package/dist/astro/routes/api/auth/handover.mjs.map +1 -0
  152. package/dist/astro/routes/api/auth/invite/accept.mjs +5 -5
  153. package/dist/astro/routes/api/auth/invite/complete.mjs +20 -20
  154. package/dist/astro/routes/api/auth/invite/index.mjs +17 -17
  155. package/dist/astro/routes/api/auth/invite/register-options.mjs +18 -18
  156. package/dist/astro/routes/api/auth/logout.mjs +6 -6
  157. package/dist/astro/routes/api/auth/magic-link/send.mjs +20 -19
  158. package/dist/astro/routes/api/auth/magic-link/send.mjs.map +1 -1
  159. package/dist/astro/routes/api/auth/magic-link/verify.d.mts.map +1 -1
  160. package/dist/astro/routes/api/auth/magic-link/verify.mjs +24 -18
  161. package/dist/astro/routes/api/auth/magic-link/verify.mjs.map +1 -1
  162. package/dist/astro/routes/api/auth/me.mjs +16 -16
  163. package/dist/astro/routes/api/auth/mode.mjs +6 -6
  164. package/dist/astro/routes/api/auth/oauth/_provider_/callback.d.mts.map +1 -1
  165. package/dist/astro/routes/api/auth/oauth/_provider_/callback.mjs +36 -13
  166. package/dist/astro/routes/api/auth/oauth/_provider_/callback.mjs.map +1 -1
  167. package/dist/astro/routes/api/auth/oauth/_provider_.d.mts.map +1 -1
  168. package/dist/astro/routes/api/auth/oauth/_provider_.mjs +20 -5
  169. package/dist/astro/routes/api/auth/oauth/_provider_.mjs.map +1 -1
  170. package/dist/astro/routes/api/auth/passkey/_id_.mjs +15 -15
  171. package/dist/astro/routes/api/auth/passkey/index.mjs +5 -5
  172. package/dist/astro/routes/api/auth/passkey/options.d.mts.map +1 -1
  173. package/dist/astro/routes/api/auth/passkey/options.mjs +28 -21
  174. package/dist/astro/routes/api/auth/passkey/options.mjs.map +1 -1
  175. package/dist/astro/routes/api/auth/passkey/register/options.mjs +18 -18
  176. package/dist/astro/routes/api/auth/passkey/register/verify.mjs +19 -19
  177. package/dist/astro/routes/api/auth/passkey/verify.mjs +20 -20
  178. package/dist/astro/routes/api/auth/signup/complete.mjs +20 -20
  179. package/dist/astro/routes/api/auth/signup/request.mjs +19 -18
  180. package/dist/astro/routes/api/auth/signup/request.mjs.map +1 -1
  181. package/dist/astro/routes/api/auth/signup/verify.mjs +5 -5
  182. package/dist/astro/routes/api/calendar.d.mts +8 -0
  183. package/dist/astro/routes/api/calendar.d.mts.map +1 -0
  184. package/dist/astro/routes/api/calendar.mjs +204 -0
  185. package/dist/astro/routes/api/calendar.mjs.map +1 -0
  186. package/dist/astro/routes/api/comments/_collection_/_contentId_/index.mjs +14 -14
  187. package/dist/astro/routes/api/comments/_collection_/_contentId_/reactions.mjs +20 -20
  188. package/dist/astro/routes/api/content/_collection_/_id_/compare.mjs +6 -6
  189. package/dist/astro/routes/api/content/_collection_/_id_/discard-draft.mjs +17 -17
  190. package/dist/astro/routes/api/content/_collection_/_id_/duplicate.mjs +6 -6
  191. package/dist/astro/routes/api/content/_collection_/_id_/lock.mjs +17 -17
  192. package/dist/astro/routes/api/content/_collection_/_id_/permanent.mjs +6 -6
  193. package/dist/astro/routes/api/content/_collection_/_id_/plugin-extensions/_pluginId_/_kind_/_extensionId_.mjs +12 -12
  194. package/dist/astro/routes/api/content/_collection_/_id_/preview-url.mjs +31 -31
  195. package/dist/astro/routes/api/content/_collection_/_id_/publish.mjs +17 -17
  196. package/dist/astro/routes/api/content/_collection_/_id_/references/_relation_/children.mjs +35 -35
  197. package/dist/astro/routes/api/content/_collection_/_id_/references/_relation_/parents.mjs +35 -35
  198. package/dist/astro/routes/api/content/_collection_/_id_/restore.mjs +6 -6
  199. package/dist/astro/routes/api/content/_collection_/_id_/revisions.mjs +6 -6
  200. package/dist/astro/routes/api/content/_collection_/_id_/schedule.mjs +17 -17
  201. package/dist/astro/routes/api/content/_collection_/_id_/terms/_taxonomy_.mjs +25 -25
  202. package/dist/astro/routes/api/content/_collection_/_id_/translations.mjs +6 -6
  203. package/dist/astro/routes/api/content/_collection_/_id_/unpublish.mjs +17 -17
  204. package/dist/astro/routes/api/content/_collection_/_id_.mjs +17 -17
  205. package/dist/astro/routes/api/content/_collection_/authors.mjs +6 -6
  206. package/dist/astro/routes/api/content/_collection_/index.mjs +16 -16
  207. package/dist/astro/routes/api/content/_collection_/trash.mjs +16 -16
  208. package/dist/astro/routes/api/dashboard.mjs +12 -12
  209. package/dist/astro/routes/api/dev/emails.mjs +6 -6
  210. package/dist/astro/routes/api/health.mjs +7 -7
  211. package/dist/astro/routes/api/import/probe.d.mts +3 -3
  212. package/dist/astro/routes/api/import/probe.mjs +25 -25
  213. package/dist/astro/routes/api/import/wordpress/analyze.mjs +6 -6
  214. package/dist/astro/routes/api/import/wordpress/execute.d.mts +13 -13
  215. package/dist/astro/routes/api/import/wordpress/execute.mjs +31 -24
  216. package/dist/astro/routes/api/import/wordpress/execute.mjs.map +1 -1
  217. package/dist/astro/routes/api/import/wordpress/media.d.mts +12 -12
  218. package/dist/astro/routes/api/import/wordpress/media.mjs +20 -20
  219. package/dist/astro/routes/api/import/wordpress/prepare.mjs +18 -18
  220. package/dist/astro/routes/api/import/wordpress/rewrite-url-helpers.d.mts +8 -0
  221. package/dist/astro/routes/api/import/wordpress/rewrite-url-helpers.d.mts.map +1 -1
  222. package/dist/astro/routes/api/import/wordpress/rewrite-url-helpers.mjs +67 -31
  223. package/dist/astro/routes/api/import/wordpress/rewrite-url-helpers.mjs.map +1 -1
  224. package/dist/astro/routes/api/import/wordpress/rewrite-urls.d.mts +13 -13
  225. package/dist/astro/routes/api/import/wordpress/rewrite-urls.mjs +27 -27
  226. package/dist/astro/routes/api/import/wordpress-plugin/analyze.d.mts +1 -1
  227. package/dist/astro/routes/api/import/wordpress-plugin/analyze.mjs +25 -25
  228. package/dist/astro/routes/api/import/wordpress-plugin/callback.mjs +1 -1
  229. package/dist/astro/routes/api/import/wordpress-plugin/execute.d.mts +13 -13
  230. package/dist/astro/routes/api/import/wordpress-plugin/execute.mjs +40 -33
  231. package/dist/astro/routes/api/import/wordpress-plugin/execute.mjs.map +1 -1
  232. package/dist/astro/routes/api/manifest.mjs +10 -7
  233. package/dist/astro/routes/api/manifest.mjs.map +1 -1
  234. package/dist/astro/routes/api/mcp.mjs +94 -94
  235. package/dist/astro/routes/api/mcp.mjs.map +1 -1
  236. package/dist/astro/routes/api/media/_id_/confirm.d.mts.map +1 -1
  237. package/dist/astro/routes/api/media/_id_/confirm.mjs +36 -20
  238. package/dist/astro/routes/api/media/_id_/confirm.mjs.map +1 -1
  239. package/dist/astro/routes/api/media/_id_/replace.mjs +17 -17
  240. package/dist/astro/routes/api/media/_id_/upload.mjs +10 -10
  241. package/dist/astro/routes/api/media/_id_/usage.mjs +31 -31
  242. package/dist/astro/routes/api/media/_id_.mjs +29 -29
  243. package/dist/astro/routes/api/media/asset/_id_/_filename_.mjs +7 -7
  244. package/dist/astro/routes/api/media/file/_...key_.d.mts.map +1 -1
  245. package/dist/astro/routes/api/media/file/_...key_.mjs +46 -16
  246. package/dist/astro/routes/api/media/file/_...key_.mjs.map +1 -1
  247. package/dist/astro/routes/api/media/folders/_id_.mjs +17 -17
  248. package/dist/astro/routes/api/media/folders/index.mjs +17 -17
  249. package/dist/astro/routes/api/media/providers/_providerId_/_itemId_.mjs +6 -6
  250. package/dist/astro/routes/api/media/providers/_providerId_/index.mjs +6 -6
  251. package/dist/astro/routes/api/media/providers/index.mjs +6 -6
  252. package/dist/astro/routes/api/media/upload-url.mjs +45 -25
  253. package/dist/astro/routes/api/media/upload-url.mjs.map +1 -1
  254. package/dist/astro/routes/api/media.d.mts.map +1 -1
  255. package/dist/astro/routes/api/media.mjs +47 -36
  256. package/dist/astro/routes/api/media.mjs.map +1 -1
  257. package/dist/astro/routes/api/menus/_name_/items/_id_.mjs +18 -18
  258. package/dist/astro/routes/api/menus/_name_/items.mjs +18 -18
  259. package/dist/astro/routes/api/menus/_name_/reorder.mjs +18 -18
  260. package/dist/astro/routes/api/menus/_name_/translations.mjs +18 -18
  261. package/dist/astro/routes/api/menus/_name_.mjs +18 -18
  262. package/dist/astro/routes/api/menus/index.mjs +18 -18
  263. package/dist/astro/routes/api/oauth/authorize.mjs +6 -6
  264. package/dist/astro/routes/api/oauth/device/authorize.mjs +9 -9
  265. package/dist/astro/routes/api/oauth/device/code.mjs +13 -12
  266. package/dist/astro/routes/api/oauth/device/code.mjs.map +1 -1
  267. package/dist/astro/routes/api/oauth/device/token.mjs +12 -11
  268. package/dist/astro/routes/api/oauth/device/token.mjs.map +1 -1
  269. package/dist/astro/routes/api/oauth/register.mjs +9 -8
  270. package/dist/astro/routes/api/oauth/register.mjs.map +1 -1
  271. package/dist/astro/routes/api/oauth/token/refresh.mjs +9 -9
  272. package/dist/astro/routes/api/oauth/token/revoke.mjs +9 -9
  273. package/dist/astro/routes/api/oauth/token.mjs +9 -9
  274. package/dist/astro/routes/api/openapi.json.mjs +23 -23
  275. package/dist/astro/routes/api/openapi.json.mjs.map +1 -1
  276. package/dist/astro/routes/api/plugins/_pluginId_/_...path_.mjs +12 -12
  277. package/dist/astro/routes/api/redirects/404s/index.mjs +20 -19
  278. package/dist/astro/routes/api/redirects/404s/index.mjs.map +1 -1
  279. package/dist/astro/routes/api/redirects/404s/summary.mjs +20 -19
  280. package/dist/astro/routes/api/redirects/404s/summary.mjs.map +1 -1
  281. package/dist/astro/routes/api/redirects/_id_.mjs +20 -19
  282. package/dist/astro/routes/api/redirects/_id_.mjs.map +1 -1
  283. package/dist/astro/routes/api/redirects/index.mjs +20 -19
  284. package/dist/astro/routes/api/redirects/index.mjs.map +1 -1
  285. package/dist/astro/routes/api/relations/_id_/index.mjs +35 -35
  286. package/dist/astro/routes/api/relations/index.mjs +35 -35
  287. package/dist/astro/routes/api/revisions/_revisionId_/index.mjs +6 -6
  288. package/dist/astro/routes/api/revisions/_revisionId_/restore.mjs +17 -17
  289. package/dist/astro/routes/api/schema/block-types/_slug_/index.mjs +71 -70
  290. package/dist/astro/routes/api/schema/block-types/_slug_/index.mjs.map +1 -1
  291. package/dist/astro/routes/api/schema/block-types/_slug_/versions/_version_/activate.mjs +71 -70
  292. package/dist/astro/routes/api/schema/block-types/_slug_/versions/_version_/activate.mjs.map +1 -1
  293. package/dist/astro/routes/api/schema/block-types/index.mjs +71 -70
  294. package/dist/astro/routes/api/schema/block-types/index.mjs.map +1 -1
  295. package/dist/astro/routes/api/schema/collections/_slug_/fields/_fieldSlug_.mjs +71 -70
  296. package/dist/astro/routes/api/schema/collections/_slug_/fields/_fieldSlug_.mjs.map +1 -1
  297. package/dist/astro/routes/api/schema/collections/_slug_/fields/index.mjs +71 -70
  298. package/dist/astro/routes/api/schema/collections/_slug_/fields/index.mjs.map +1 -1
  299. package/dist/astro/routes/api/schema/collections/_slug_/fields/reorder.mjs +71 -70
  300. package/dist/astro/routes/api/schema/collections/_slug_/fields/reorder.mjs.map +1 -1
  301. package/dist/astro/routes/api/schema/collections/_slug_/index.mjs +71 -70
  302. package/dist/astro/routes/api/schema/collections/_slug_/index.mjs.map +1 -1
  303. package/dist/astro/routes/api/schema/collections/index.mjs +71 -70
  304. package/dist/astro/routes/api/schema/collections/index.mjs.map +1 -1
  305. package/dist/astro/routes/api/schema/collections/reorder.mjs +71 -70
  306. package/dist/astro/routes/api/schema/collections/reorder.mjs.map +1 -1
  307. package/dist/astro/routes/api/schema/index.mjs +17 -17
  308. package/dist/astro/routes/api/schema/index.mjs.map +1 -1
  309. package/dist/astro/routes/api/schema/orphans/_slug_.mjs +71 -70
  310. package/dist/astro/routes/api/schema/orphans/_slug_.mjs.map +1 -1
  311. package/dist/astro/routes/api/schema/orphans/index.mjs +71 -70
  312. package/dist/astro/routes/api/schema/orphans/index.mjs.map +1 -1
  313. package/dist/astro/routes/api/search/enable.mjs +19 -19
  314. package/dist/astro/routes/api/search/index.mjs +18 -18
  315. package/dist/astro/routes/api/search/rebuild.mjs +19 -19
  316. package/dist/astro/routes/api/search/stats.mjs +9 -9
  317. package/dist/astro/routes/api/search/suggest.mjs +18 -18
  318. package/dist/astro/routes/api/sections/_slug_.mjs +18 -18
  319. package/dist/astro/routes/api/sections/index.mjs +18 -18
  320. package/dist/astro/routes/api/settings/backups/archives/_name_.mjs +8 -8
  321. package/dist/astro/routes/api/settings/backups/archives/index.mjs +8 -8
  322. package/dist/astro/routes/api/settings/backups/export.mjs +8 -8
  323. package/dist/astro/routes/api/settings/backups/index.mjs +9 -9
  324. package/dist/astro/routes/api/settings/domain-notify.d.mts +8 -0
  325. package/dist/astro/routes/api/settings/domain-notify.d.mts.map +1 -0
  326. package/dist/astro/routes/api/settings/domain-notify.mjs +125 -0
  327. package/dist/astro/routes/api/settings/domain-notify.mjs.map +1 -0
  328. package/dist/astro/routes/api/settings/domain.d.mts +9 -0
  329. package/dist/astro/routes/api/settings/domain.d.mts.map +1 -0
  330. package/dist/astro/routes/api/settings/domain.mjs +61 -0
  331. package/dist/astro/routes/api/settings/domain.mjs.map +1 -0
  332. package/dist/astro/routes/api/settings/email.mjs +7 -7
  333. package/dist/astro/routes/api/settings.mjs +22 -22
  334. package/dist/astro/routes/api/setup/admin-verify.mjs +21 -21
  335. package/dist/astro/routes/api/setup/admin.mjs +19 -19
  336. package/dist/astro/routes/api/setup/dev-bypass.mjs +43 -43
  337. package/dist/astro/routes/api/setup/dev-reset.mjs +5 -5
  338. package/dist/astro/routes/api/setup/index.d.mts.map +1 -1
  339. package/dist/astro/routes/api/setup/index.mjs +59 -50
  340. package/dist/astro/routes/api/setup/index.mjs.map +1 -1
  341. package/dist/astro/routes/api/setup/status.mjs +7 -7
  342. package/dist/astro/routes/api/site/domain-proof.d.mts +8 -0
  343. package/dist/astro/routes/api/site/domain-proof.d.mts.map +1 -0
  344. package/dist/astro/routes/api/site/domain-proof.mjs +33 -0
  345. package/dist/astro/routes/api/site/domain-proof.mjs.map +1 -0
  346. package/dist/astro/routes/api/snapshot.mjs +10 -10
  347. package/dist/astro/routes/api/taxonomies/_name_/reorder.mjs +23 -23
  348. package/dist/astro/routes/api/taxonomies/_name_/terms/_slug_/translations.mjs +23 -23
  349. package/dist/astro/routes/api/taxonomies/_name_/terms/_slug_.mjs +23 -23
  350. package/dist/astro/routes/api/taxonomies/_name_/terms/index.mjs +23 -23
  351. package/dist/astro/routes/api/taxonomies/_name_/translations.mjs +22 -22
  352. package/dist/astro/routes/api/taxonomies/_name_.mjs +23 -23
  353. package/dist/astro/routes/api/taxonomies/bulk-tag.mjs +36 -36
  354. package/dist/astro/routes/api/taxonomies/index.mjs +23 -23
  355. package/dist/astro/routes/api/themes/preview.mjs +8 -8
  356. package/dist/astro/routes/api/typegen.mjs +7 -7
  357. package/dist/astro/routes/api/visual-editing/action-token.mjs +8 -8
  358. package/dist/astro/routes/api/visual-editing/content/_collection_/_id_/publish.mjs +20 -20
  359. package/dist/astro/routes/api/visual-editing/toolbar-labels.mjs +5 -5
  360. package/dist/astro/routes/api/well-known/auth.mjs +1 -1
  361. package/dist/astro/routes/api/well-known/oauth-authorization-server.mjs +2 -2
  362. package/dist/astro/routes/api/well-known/oauth-protected-resource.mjs +2 -2
  363. package/dist/astro/routes/api/widget-areas/_name_/reorder.mjs +17 -17
  364. package/dist/astro/routes/api/widget-areas/_name_/widgets/_id_.mjs +19 -19
  365. package/dist/astro/routes/api/widget-areas/_name_/widgets.mjs +19 -19
  366. package/dist/astro/routes/api/widget-areas/_name_.mjs +9 -9
  367. package/dist/astro/routes/api/widget-areas/index.mjs +19 -19
  368. package/dist/astro/routes/api/widget-components.mjs +6 -6
  369. package/dist/astro/routes/robots.txt.mjs +7 -7
  370. package/dist/astro/routes/sitemap-_collection_.xml.d.mts.map +1 -1
  371. package/dist/astro/routes/sitemap-_collection_.xml.mjs +30 -13
  372. package/dist/astro/routes/sitemap-_collection_.xml.mjs.map +1 -1
  373. package/dist/astro/routes/sitemap.xml.d.mts.map +1 -1
  374. package/dist/astro/routes/sitemap.xml.mjs +14 -13
  375. package/dist/astro/routes/sitemap.xml.mjs.map +1 -1
  376. package/dist/astro/types.d.mts +30 -18
  377. package/dist/astro/types.d.mts.map +1 -1
  378. package/dist/audit-CCH3MA4Y.mjs +127 -0
  379. package/dist/audit-CCH3MA4Y.mjs.map +1 -0
  380. package/dist/auth/providers/github.d.mts +1 -1
  381. package/dist/auth/providers/google.d.mts +1 -1
  382. package/dist/auth/providers/microsoft.d.mts +27 -0
  383. package/dist/auth/providers/microsoft.d.mts.map +1 -0
  384. package/dist/auth/providers/microsoft.mjs +20 -0
  385. package/dist/auth/providers/microsoft.mjs.map +1 -0
  386. package/dist/authoritative-records-Dcs7l2H5.mjs +5183 -0
  387. package/dist/authoritative-records-Dcs7l2H5.mjs.map +1 -0
  388. package/dist/authorize-TdIGpRSE.mjs +49 -0
  389. package/dist/authorize-TdIGpRSE.mjs.map +1 -0
  390. package/dist/backup-CZt5Mzwx.mjs +246 -0
  391. package/dist/backup-CZt5Mzwx.mjs.map +1 -0
  392. package/dist/base64-BQBZwXCx.mjs +63 -0
  393. package/dist/base64-BQBZwXCx.mjs.map +1 -0
  394. package/dist/block-types-DHnkzE6u.mjs +132 -0
  395. package/dist/block-types-DHnkzE6u.mjs.map +1 -0
  396. package/dist/block-values-C4N_F2-G.mjs +175 -0
  397. package/dist/block-values-C4N_F2-G.mjs.map +1 -0
  398. package/dist/byline-BmVKOQ8l.mjs +909 -0
  399. package/dist/byline-BmVKOQ8l.mjs.map +1 -0
  400. package/dist/byline-fields-B8SDs3M_.mjs +123 -0
  401. package/dist/byline-fields-B8SDs3M_.mjs.map +1 -0
  402. package/dist/byline-fields-Bze3ZdAw.mjs +280 -0
  403. package/dist/byline-fields-Bze3ZdAw.mjs.map +1 -0
  404. package/dist/bylines-CHhR28r9.mjs +150 -0
  405. package/dist/bylines-CHhR28r9.mjs.map +1 -0
  406. package/dist/bylines-DZS4OflA.mjs +234 -0
  407. package/dist/bylines-DZS4OflA.mjs.map +1 -0
  408. package/dist/cache-x0z8t_m9.mjs +133 -0
  409. package/dist/cache-x0z8t_m9.mjs.map +1 -0
  410. package/dist/canonical-BUcKRYpG.mjs +174 -0
  411. package/dist/canonical-BUcKRYpG.mjs.map +1 -0
  412. package/dist/capture-triggers-C9JKoIdT.mjs +362 -0
  413. package/dist/capture-triggers-C9JKoIdT.mjs.map +1 -0
  414. package/dist/challenge-store-BHgdPVze.mjs +51 -0
  415. package/dist/challenge-store-BHgdPVze.mjs.map +1 -0
  416. package/dist/checksum-BYR5i7qe.mjs +162 -0
  417. package/dist/checksum-BYR5i7qe.mjs.map +1 -0
  418. package/dist/chrome-tags-BIKBMZYO.mjs +24 -0
  419. package/dist/chrome-tags-BIKBMZYO.mjs.map +1 -0
  420. package/dist/chunks-Dr5Vr0zA.mjs +25 -0
  421. package/dist/chunks-Dr5Vr0zA.mjs.map +1 -0
  422. package/dist/cli/index.mjs +54 -52
  423. package/dist/cli/index.mjs.map +1 -1
  424. package/dist/client/cf-access.d.mts +1 -1
  425. package/dist/client/index.d.mts +34 -34
  426. package/dist/client/index.d.mts.map +1 -1
  427. package/dist/client/index.mjs +2 -2
  428. package/dist/client/index.mjs.map +1 -1
  429. package/dist/collection-slugs-cache-B2Gs9Jwx.mjs +85 -0
  430. package/dist/collection-slugs-cache-B2Gs9Jwx.mjs.map +1 -0
  431. package/dist/comment-CWla6OHV.mjs +325 -0
  432. package/dist/comment-CWla6OHV.mjs.map +1 -0
  433. package/dist/comment-reaction-RZrcs5cW.mjs +85 -0
  434. package/dist/comment-reaction-RZrcs5cW.mjs.map +1 -0
  435. package/dist/comments-BzmIKVb2.mjs +99 -0
  436. package/dist/comments-BzmIKVb2.mjs.map +1 -0
  437. package/dist/comments-Da_dI2O1.mjs +195 -0
  438. package/dist/comments-Da_dI2O1.mjs.map +1 -0
  439. package/dist/components-oFXumpf5.mjs +112 -0
  440. package/dist/components-oFXumpf5.mjs.map +1 -0
  441. package/dist/config--wamYxBW.d.mts +39 -0
  442. package/dist/config--wamYxBW.d.mts.map +1 -0
  443. package/dist/config-Bo4eOOdV.mjs +228 -0
  444. package/dist/config-Bo4eOOdV.mjs.map +1 -0
  445. package/dist/config-C4-UxIk7.d.mts +6790 -0
  446. package/dist/config-C4-UxIk7.d.mts.map +1 -0
  447. package/dist/connection-UpzYxtE2.mjs +36 -0
  448. package/dist/connection-UpzYxtE2.mjs.map +1 -0
  449. package/dist/content-CcHrqkgp.mjs +2072 -0
  450. package/dist/content-CcHrqkgp.mjs.map +1 -0
  451. package/dist/content-list-query-Bxxdd9fv.d.mts +26 -0
  452. package/dist/content-list-query-Bxxdd9fv.d.mts.map +1 -0
  453. package/dist/content-repair-havk1F0-.mjs +442 -0
  454. package/dist/content-repair-havk1F0-.mjs.map +1 -0
  455. package/dist/context-CvhgHgSH.mjs +2043 -0
  456. package/dist/context-CvhgHgSH.mjs.map +1 -0
  457. package/dist/credits-CygUrPOi.mjs +110 -0
  458. package/dist/credits-CygUrPOi.mjs.map +1 -0
  459. package/dist/cron-C6ytTOLw.mjs +306 -0
  460. package/dist/cron-C6ytTOLw.mjs.map +1 -0
  461. package/dist/dashboard-7_FYfafc.mjs +151 -0
  462. package/dist/dashboard-7_FYfafc.mjs.map +1 -0
  463. package/dist/db/index.d.mts +3 -3
  464. package/dist/db/index.mjs +1 -1
  465. package/dist/db/index.mjs.map +1 -1
  466. package/dist/db/libsql-migrations.d.mts +1 -1
  467. package/dist/db/libsql-migrations.mjs +5 -5
  468. package/dist/db/libsql.d.mts +1 -1
  469. package/dist/db/postgres-migrations.d.mts +1 -1
  470. package/dist/db/postgres-migrations.mjs +4 -4
  471. package/dist/db/postgres.d.mts +1 -1
  472. package/dist/db/sqlite-migrations.d.mts +1 -1
  473. package/dist/db/sqlite-migrations.mjs +4 -4
  474. package/dist/db/sqlite.d.mts +1 -1
  475. package/dist/db/sqlite.mjs +1 -1
  476. package/dist/default-CHCUkV4Z.mjs +81 -0
  477. package/dist/default-CHCUkV4Z.mjs.map +1 -0
  478. package/dist/deferred-tasks-G0xhcJTl.d.mts +9 -0
  479. package/dist/deferred-tasks-G0xhcJTl.d.mts.map +1 -0
  480. package/dist/dev-typegen-Dtl8AfS6.mjs +29 -0
  481. package/dist/dev-typegen-Dtl8AfS6.mjs.map +1 -0
  482. package/dist/device-flow-CzDJmQ1q.mjs +521 -0
  483. package/dist/device-flow-CzDJmQ1q.mjs.map +1 -0
  484. package/dist/digest-xJmyPv2r.mjs +194 -0
  485. package/dist/digest-xJmyPv2r.mjs.map +1 -0
  486. package/dist/direct-executor-BXiYIVJ9.mjs +104 -0
  487. package/dist/direct-executor-BXiYIVJ9.mjs.map +1 -0
  488. package/dist/email-console-7ZPApLlm.mjs +50 -0
  489. package/dist/email-console-7ZPApLlm.mjs.map +1 -0
  490. package/dist/email-locale-DFdUA6UF.mjs +25 -0
  491. package/dist/email-locale-DFdUA6UF.mjs.map +1 -0
  492. package/dist/emdash-runtime-C4oFeVpN.mjs +4363 -0
  493. package/dist/emdash-runtime-C4oFeVpN.mjs.map +1 -0
  494. package/dist/enrich-Duu4sV3a.mjs +194 -0
  495. package/dist/enrich-Duu4sV3a.mjs.map +1 -0
  496. package/dist/entry-lock-B4n0HdQ_.mjs +163 -0
  497. package/dist/entry-lock-B4n0HdQ_.mjs.map +1 -0
  498. package/dist/entry-lock-BAAlKYrz.d.mts +4566 -0
  499. package/dist/entry-lock-BAAlKYrz.d.mts.map +1 -0
  500. package/dist/entry-lock-Cjz0h45X.mjs +1209 -0
  501. package/dist/entry-lock-Cjz0h45X.mjs.map +1 -0
  502. package/dist/env-types-4bkF6Bqg.mjs +38 -0
  503. package/dist/env-types-4bkF6Bqg.mjs.map +1 -0
  504. package/dist/error-DxgQdaZ_.mjs +90 -0
  505. package/dist/error-DxgQdaZ_.mjs.map +1 -0
  506. package/dist/errors-CjtE5aWF.mjs +120 -0
  507. package/dist/errors-CjtE5aWF.mjs.map +1 -0
  508. package/dist/errors-hskQ0C8G.mjs +479 -0
  509. package/dist/errors-hskQ0C8G.mjs.map +1 -0
  510. package/dist/escape-ESFhYzwG.mjs +9 -0
  511. package/dist/escape-ESFhYzwG.mjs.map +1 -0
  512. package/dist/fence-vc3aHgRA.mjs +162 -0
  513. package/dist/fence-vc3aHgRA.mjs.map +1 -0
  514. package/dist/field-defs-cache-zoow36nz.mjs +77 -0
  515. package/dist/field-defs-cache-zoow36nz.mjs.map +1 -0
  516. package/dist/field-map-JD1wG0Tq.mjs +83 -0
  517. package/dist/field-map-JD1wG0Tq.mjs.map +1 -0
  518. package/dist/fts-manager-WJCN8uU6.mjs +443 -0
  519. package/dist/fts-manager-WJCN8uU6.mjs.map +1 -0
  520. package/dist/gc-CsGZiKdH.mjs +75 -0
  521. package/dist/gc-CsGZiKdH.mjs.map +1 -0
  522. package/dist/hash-C4DFoJ7Z.mjs +37 -0
  523. package/dist/hash-C4DFoJ7Z.mjs.map +1 -0
  524. package/dist/hook-result-CXjtMk7Q.d.mts +31 -0
  525. package/dist/hook-result-CXjtMk7Q.d.mts.map +1 -0
  526. package/dist/hreflang-BAma7iRr.mjs +105 -0
  527. package/dist/hreflang-BAma7iRr.mjs.map +1 -0
  528. package/dist/hreflang-BsYo4x_M.d.mts +50 -0
  529. package/dist/hreflang-BsYo4x_M.d.mts.map +1 -0
  530. package/dist/http-route-dispatch-C8G7hAK6.mjs +342 -0
  531. package/dist/http-route-dispatch-C8G7hAK6.mjs.map +1 -0
  532. package/dist/identity-BwBKM1fH.mjs +35 -0
  533. package/dist/identity-BwBKM1fH.mjs.map +1 -0
  534. package/dist/import-DJ3Z2wxE.mjs +2021 -0
  535. package/dist/import-DJ3Z2wxE.mjs.map +1 -0
  536. package/dist/index-DYsn97dY.d.mts +623 -0
  537. package/dist/index-DYsn97dY.d.mts.map +1 -0
  538. package/dist/index.d.mts +24 -24
  539. package/dist/index.mjs +99 -98
  540. package/dist/init-lock-BGmew3r1.mjs +56 -0
  541. package/dist/init-lock-BGmew3r1.mjs.map +1 -0
  542. package/dist/install-finalization-DCFnFSHv.mjs +58 -0
  543. package/dist/install-finalization-DCFnFSHv.mjs.map +1 -0
  544. package/dist/keys-CGvAndSp.mjs +61 -0
  545. package/dist/keys-CGvAndSp.mjs.map +1 -0
  546. package/dist/kinds-DT1W4T4Y.mjs +974 -0
  547. package/dist/kinds-DT1W4T4Y.mjs.map +1 -0
  548. package/dist/lifecycle-BzglCSY0.mjs +25 -0
  549. package/dist/lifecycle-BzglCSY0.mjs.map +1 -0
  550. package/dist/load-DjUqmf3s.mjs +28 -0
  551. package/dist/load-DjUqmf3s.mjs.map +1 -0
  552. package/dist/loader-CetY659y.mjs +1355 -0
  553. package/dist/loader-CetY659y.mjs.map +1 -0
  554. package/dist/loops-DkT1zkPH.mjs +205 -0
  555. package/dist/loops-DkT1zkPH.mjs.map +1 -0
  556. package/dist/manifest-builder-BOFCd9rX.mjs +189 -0
  557. package/dist/manifest-builder-BOFCd9rX.mjs.map +1 -0
  558. package/dist/manifest-schema-BiFBPEsp.mjs +497 -0
  559. package/dist/manifest-schema-BiFBPEsp.mjs.map +1 -0
  560. package/dist/marketplace-CUlenvZm.mjs +257 -0
  561. package/dist/marketplace-CUlenvZm.mjs.map +1 -0
  562. package/dist/media/image-endpoint.d.mts +26 -2
  563. package/dist/media/image-endpoint.d.mts.map +1 -1
  564. package/dist/media/image-endpoint.mjs +73 -3
  565. package/dist/media/image-endpoint.mjs.map +1 -1
  566. package/dist/media/index.d.mts +1 -1
  567. package/dist/media/index.mjs +1 -1
  568. package/dist/media/local-runtime.d.mts +14 -14
  569. package/dist/media/local-runtime.mjs +7 -7
  570. package/dist/media-CRKsKlfK.mjs +416 -0
  571. package/dist/media-CRKsKlfK.mjs.map +1 -0
  572. package/dist/media-C_z7sRuC.mjs +294 -0
  573. package/dist/media-C_z7sRuC.mjs.map +1 -0
  574. package/dist/media-IT8hQleU.mjs +373 -0
  575. package/dist/media-IT8hQleU.mjs.map +1 -0
  576. package/dist/media-allowlist-Ct6wvnT2.mjs +45 -0
  577. package/dist/media-allowlist-Ct6wvnT2.mjs.map +1 -0
  578. package/dist/media-folders-DtMt-vAA.mjs +210 -0
  579. package/dist/media-folders-DtMt-vAA.mjs.map +1 -0
  580. package/dist/media-url-BpXLqCmf.mjs +43 -0
  581. package/dist/media-url-BpXLqCmf.mjs.map +1 -0
  582. package/dist/media-usage-DEPHZZ9X.mjs +282 -0
  583. package/dist/media-usage-DEPHZZ9X.mjs.map +1 -0
  584. package/dist/media-usage-activation-V2Siabtw.mjs +78 -0
  585. package/dist/media-usage-activation-V2Siabtw.mjs.map +1 -0
  586. package/dist/media-usage-work-Cv1OE59F.mjs +151 -0
  587. package/dist/media-usage-work-Cv1OE59F.mjs.map +1 -0
  588. package/dist/media-usage-work-cgDYGvrt.mjs +1015 -0
  589. package/dist/media-usage-work-cgDYGvrt.mjs.map +1 -0
  590. package/dist/menus-CvVYfsuk.mjs +753 -0
  591. package/dist/menus-CvVYfsuk.mjs.map +1 -0
  592. package/dist/menus-D1HC8npj.mjs +92 -0
  593. package/dist/menus-D1HC8npj.mjs.map +1 -0
  594. package/dist/menus-DL8IPIcm.mjs +3721 -0
  595. package/dist/menus-DL8IPIcm.mjs.map +1 -0
  596. package/dist/migrations/index.d.mts +1 -1
  597. package/dist/migrations/index.mjs +3 -3
  598. package/dist/mime-B5M9R53H.mjs +81 -0
  599. package/dist/mime-B5M9R53H.mjs.map +1 -0
  600. package/dist/mode-eieqAWLe.mjs +23 -0
  601. package/dist/mode-eieqAWLe.mjs.map +1 -0
  602. package/dist/node-sqlite-compat-VuyzJw1b.mjs +63 -0
  603. package/dist/node-sqlite-compat-VuyzJw1b.mjs.map +1 -0
  604. package/dist/oauth-authorization-B6ZJbMd2.mjs +274 -0
  605. package/dist/oauth-authorization-B6ZJbMd2.mjs.map +1 -0
  606. package/dist/oauth-clients-DVjRc9v3.mjs +266 -0
  607. package/dist/oauth-clients-DVjRc9v3.mjs.map +1 -0
  608. package/dist/oauth-state-store-CnmYYsVQ.mjs +50 -0
  609. package/dist/oauth-state-store-CnmYYsVQ.mjs.map +1 -0
  610. package/dist/oauth-user-lookup-Dz1_R5vT.mjs +26 -0
  611. package/dist/oauth-user-lookup-Dz1_R5vT.mjs.map +1 -0
  612. package/dist/object-cache/memory.d.mts +1 -1
  613. package/dist/options-BR9XZl7h.d.mts +81 -0
  614. package/dist/options-BR9XZl7h.d.mts.map +1 -0
  615. package/dist/ownership-COPyVysP.mjs +12 -0
  616. package/dist/ownership-COPyVysP.mjs.map +1 -0
  617. package/dist/page/index.d.mts +2 -2
  618. package/dist/page/index.mjs +6 -6
  619. package/dist/parse-BOGhrwSq.d.mts +174 -0
  620. package/dist/parse-BOGhrwSq.d.mts.map +1 -0
  621. package/dist/parse-Cn5aSk1N.mjs +81 -0
  622. package/dist/parse-Cn5aSk1N.mjs.map +1 -0
  623. package/dist/passkey-config-mMFRQUCj.mjs +46 -0
  624. package/dist/passkey-config-mMFRQUCj.mjs.map +1 -0
  625. package/dist/paths-BmcAdBo9.mjs +77 -0
  626. package/dist/paths-BmcAdBo9.mjs.map +1 -0
  627. package/dist/patterns-CMNnYCgf.mjs +159 -0
  628. package/dist/patterns-CMNnYCgf.mjs.map +1 -0
  629. package/dist/placeholder-nOep3_Gn.d.mts +306 -0
  630. package/dist/placeholder-nOep3_Gn.d.mts.map +1 -0
  631. package/dist/plan-CDY4K8CH.mjs +135 -0
  632. package/dist/plan-CDY4K8CH.mjs.map +1 -0
  633. package/dist/plugin-test-runtime.d.mts +14 -14
  634. package/dist/plugin-test-runtime.d.mts.map +1 -1
  635. package/dist/plugin-test-runtime.mjs +111 -110
  636. package/dist/plugin-types.d.mts +2 -2
  637. package/dist/plugin-utils.d.mts +12 -12
  638. package/dist/plugin-utils.mjs +1 -1
  639. package/dist/plugin-utils.mjs.map +1 -1
  640. package/dist/plugins/adapt-sandbox-entry.d.mts +12 -12
  641. package/dist/plugins/adapt-sandbox-entry.mjs +3 -3
  642. package/dist/plugins/host.d.mts +5 -5
  643. package/dist/plugins/host.mjs +45 -44
  644. package/dist/plugins-DFBpfbO3.mjs +261 -0
  645. package/dist/plugins-DFBpfbO3.mjs.map +1 -0
  646. package/dist/policy-B_2qnHSy.mjs +45 -0
  647. package/dist/policy-B_2qnHSy.mjs.map +1 -0
  648. package/dist/portable-text-Dc2YAusw.mjs +307 -0
  649. package/dist/portable-text-Dc2YAusw.mjs.map +1 -0
  650. package/dist/preview-BtzikJ9O.mjs +107 -0
  651. package/dist/preview-BtzikJ9O.mjs.map +1 -0
  652. package/dist/protocol-M268ox8L.d.mts +61 -0
  653. package/dist/protocol-M268ox8L.d.mts.map +1 -0
  654. package/dist/public-submission-BQZavgZU.mjs +251 -0
  655. package/dist/public-submission-BQZavgZU.mjs.map +1 -0
  656. package/dist/public-url-uT1Ok2Tu.mjs +101 -0
  657. package/dist/public-url-uT1Ok2Tu.mjs.map +1 -0
  658. package/dist/query-BGG3sDEd.mjs +1127 -0
  659. package/dist/query-BGG3sDEd.mjs.map +1 -0
  660. package/dist/query-C_CWlifp.mjs +41 -0
  661. package/dist/query-C_CWlifp.mjs.map +1 -0
  662. package/dist/range-CXK_kDbI.mjs +51 -0
  663. package/dist/range-CXK_kDbI.mjs.map +1 -0
  664. package/dist/rate-limit-Dvamvay-.mjs +127 -0
  665. package/dist/rate-limit-Dvamvay-.mjs.map +1 -0
  666. package/dist/receipt-BmQGzquP.mjs +43 -0
  667. package/dist/receipt-BmQGzquP.mjs.map +1 -0
  668. package/dist/redirect-B39kTQ_0.mjs +423 -0
  669. package/dist/redirect-B39kTQ_0.mjs.map +1 -0
  670. package/dist/redirect-BguJ00Pv.mjs +19 -0
  671. package/dist/redirect-BguJ00Pv.mjs.map +1 -0
  672. package/dist/redirects-C8G4BsfP.mjs +446 -0
  673. package/dist/redirects-C8G4BsfP.mjs.map +1 -0
  674. package/dist/redirects-DFT7Wr-e.mjs +148 -0
  675. package/dist/redirects-DFT7Wr-e.mjs.map +1 -0
  676. package/dist/registry/testing.mjs +3 -3
  677. package/dist/registry-DeZ27gVi.mjs +8374 -0
  678. package/dist/registry-DeZ27gVi.mjs.map +1 -0
  679. package/dist/relations-DBB1bRJW.mjs +776 -0
  680. package/dist/relations-DBB1bRJW.mjs.map +1 -0
  681. package/dist/request-context.d.mts +2 -2
  682. package/dist/request-context.mjs.map +1 -1
  683. package/dist/request-meta-BSvkhIBX.mjs +141 -0
  684. package/dist/request-meta-BSvkhIBX.mjs.map +1 -0
  685. package/dist/resolve-BxH64HN9.mjs +100 -0
  686. package/dist/resolve-BxH64HN9.mjs.map +1 -0
  687. package/dist/revision-BWEH2qQB.mjs +368 -0
  688. package/dist/revision-BWEH2qQB.mjs.map +1 -0
  689. package/dist/route-wire-CwbWB_6O.mjs +197 -0
  690. package/dist/route-wire-CwbWB_6O.mjs.map +1 -0
  691. package/dist/routes-BfIxc7ft.mjs +272 -0
  692. package/dist/routes-BfIxc7ft.mjs.map +1 -0
  693. package/dist/runner-DkeafPBA.d.mts +68 -0
  694. package/dist/runner-DkeafPBA.d.mts.map +1 -0
  695. package/dist/runner-wqt4BrIW.mjs +6383 -0
  696. package/dist/runner-wqt4BrIW.mjs.map +1 -0
  697. package/dist/runtime.d.mts +13 -13
  698. package/dist/runtime.mjs +3 -3
  699. package/dist/schema/project-env-types.mjs +38 -38
  700. package/dist/schema-BXIW-JHi.mjs +815 -0
  701. package/dist/schema-BXIW-JHi.mjs.map +1 -0
  702. package/dist/schema-I74JwYte.mjs +13 -0
  703. package/dist/schema-I74JwYte.mjs.map +1 -0
  704. package/dist/scopes-RWZ5ft_Z.mjs +34 -0
  705. package/dist/scopes-RWZ5ft_Z.mjs.map +1 -0
  706. package/dist/search-DxwagyWS.mjs +450 -0
  707. package/dist/search-DxwagyWS.mjs.map +1 -0
  708. package/dist/secrets-Cc_O3Kp-.mjs +369 -0
  709. package/dist/secrets-Cc_O3Kp-.mjs.map +1 -0
  710. package/dist/sections-Ccq9ZgyD.mjs +346 -0
  711. package/dist/sections-Ccq9ZgyD.mjs.map +1 -0
  712. package/dist/seed/index.d.mts +2 -2
  713. package/dist/seed/index.mjs +36 -36
  714. package/dist/seo/index.d.mts +3 -3
  715. package/dist/seo/index.mjs +23 -23
  716. package/dist/seo-CCnfPWAQ.mjs +133 -0
  717. package/dist/seo-CCnfPWAQ.mjs.map +1 -0
  718. package/dist/seo-QCtJ1jjV.mjs +188 -0
  719. package/dist/seo-QCtJ1jjV.mjs.map +1 -0
  720. package/dist/service-DX84s2rw.mjs +150 -0
  721. package/dist/service-DX84s2rw.mjs.map +1 -0
  722. package/dist/session-user-1dtJc2zv.mjs +61 -0
  723. package/dist/session-user-1dtJc2zv.mjs.map +1 -0
  724. package/dist/settings-B1jOxAIl.mjs +443 -0
  725. package/dist/settings-B1jOxAIl.mjs.map +1 -0
  726. package/dist/settings-Bc1IBl1t.mjs +66 -0
  727. package/dist/settings-Bc1IBl1t.mjs.map +1 -0
  728. package/dist/settings-GaZ5sVgg.mjs +73 -0
  729. package/dist/settings-GaZ5sVgg.mjs.map +1 -0
  730. package/dist/setup-complete-DidMAWJS.mjs +65 -0
  731. package/dist/setup-complete-DidMAWJS.mjs.map +1 -0
  732. package/dist/setup-nonce-DKl4S4c6.mjs +25 -0
  733. package/dist/setup-nonce-DKl4S4c6.mjs.map +1 -0
  734. package/dist/single-flight-cache-D0EaGbN1.mjs +104 -0
  735. package/dist/single-flight-cache-D0EaGbN1.mjs.map +1 -0
  736. package/dist/site-domain-CbI51Pc2.mjs +113 -0
  737. package/dist/site-domain-CbI51Pc2.mjs.map +1 -0
  738. package/dist/site-settings-CDdT4mVm.mjs +50 -0
  739. package/dist/site-settings-CDdT4mVm.mjs.map +1 -0
  740. package/dist/site-url-CrDZaAvo.mjs +45 -0
  741. package/dist/site-url-CrDZaAvo.mjs.map +1 -0
  742. package/dist/sitemap-name-W3BTor6X.mjs +26 -0
  743. package/dist/sitemap-name-W3BTor6X.mjs.map +1 -0
  744. package/dist/slug-BJhHKoOH.mjs +16 -0
  745. package/dist/slug-BJhHKoOH.mjs.map +1 -0
  746. package/dist/slugify-bu2-jKia.mjs +22 -0
  747. package/dist/slugify-bu2-jKia.mjs.map +1 -0
  748. package/dist/snapshot-BuI_2uDe.mjs +414 -0
  749. package/dist/snapshot-BuI_2uDe.mjs.map +1 -0
  750. package/dist/ssrf-LM_0wpGA.mjs +406 -0
  751. package/dist/ssrf-LM_0wpGA.mjs.map +1 -0
  752. package/dist/stage-DhzZuYaT.mjs +662 -0
  753. package/dist/stage-DhzZuYaT.mjs.map +1 -0
  754. package/dist/staged-DboEaWsV.mjs +686 -0
  755. package/dist/staged-DboEaWsV.mjs.map +1 -0
  756. package/dist/state-DCXDzjHq.mjs +178 -0
  757. package/dist/state-DCXDzjHq.mjs.map +1 -0
  758. package/dist/status-Dl85BK39.mjs +30 -0
  759. package/dist/status-Dl85BK39.mjs.map +1 -0
  760. package/dist/storage/local.d.mts +2 -2
  761. package/dist/storage/local.d.mts.map +1 -1
  762. package/dist/storage/local.mjs +12 -5
  763. package/dist/storage/local.mjs.map +1 -1
  764. package/dist/storage/s3.d.mts +4 -2
  765. package/dist/storage/s3.d.mts.map +1 -1
  766. package/dist/storage/s3.mjs +56 -9
  767. package/dist/storage/s3.mjs.map +1 -1
  768. package/dist/storage-query-BOBmeDMD.d.mts +1615 -0
  769. package/dist/storage-query-BOBmeDMD.d.mts.map +1 -0
  770. package/dist/tar-K40edFMt.mjs +449 -0
  771. package/dist/tar-K40edFMt.mjs.map +1 -0
  772. package/dist/target-BOighEY1.mjs +27 -0
  773. package/dist/target-BOighEY1.mjs.map +1 -0
  774. package/dist/taxonomies-DQSywBvX.mjs +697 -0
  775. package/dist/taxonomies-DQSywBvX.mjs.map +1 -0
  776. package/dist/taxonomies-Dj5eaobC.mjs +939 -0
  777. package/dist/taxonomies-Dj5eaobC.mjs.map +1 -0
  778. package/dist/taxonomy-QrNmTfIZ.mjs +550 -0
  779. package/dist/taxonomy-QrNmTfIZ.mjs.map +1 -0
  780. package/dist/tokens-j5L0as2H.mjs +171 -0
  781. package/dist/tokens-j5L0as2H.mjs.map +1 -0
  782. package/dist/transfer-CYEw8Tu4.mjs +8873 -0
  783. package/dist/transfer-CYEw8Tu4.mjs.map +1 -0
  784. package/dist/transfer-DDX10hkD.mjs +166 -0
  785. package/dist/transfer-DDX10hkD.mjs.map +1 -0
  786. package/dist/transfer-download-BAqq6GJv.mjs +33 -0
  787. package/dist/transfer-download-BAqq6GJv.mjs.map +1 -0
  788. package/dist/transformations-De44wqV_.mjs +196 -0
  789. package/dist/transformations-De44wqV_.mjs.map +1 -0
  790. package/dist/transport-1QjUhCRO.d.mts +42 -0
  791. package/dist/transport-1QjUhCRO.d.mts.map +1 -0
  792. package/dist/transport-Ds5pVX7p.mjs +136 -0
  793. package/dist/transport-Ds5pVX7p.mjs.map +1 -0
  794. package/dist/trusted-proxy-d4Tk6biT.mjs +51 -0
  795. package/dist/trusted-proxy-d4Tk6biT.mjs.map +1 -0
  796. package/dist/turnstile-DaFLtyrs.mjs +58 -0
  797. package/dist/turnstile-DaFLtyrs.mjs.map +1 -0
  798. package/dist/types-B4-1P2DK.d.mts +227 -0
  799. package/dist/types-B4-1P2DK.d.mts.map +1 -0
  800. package/dist/types-BKXA0f-c.mjs +16 -0
  801. package/dist/types-BKXA0f-c.mjs.map +1 -0
  802. package/dist/types-BiHcpUoO.d.mts +374 -0
  803. package/dist/types-BiHcpUoO.d.mts.map +1 -0
  804. package/dist/types-BihhvkyN.d.mts +85 -0
  805. package/dist/types-BihhvkyN.d.mts.map +1 -0
  806. package/dist/types-Bq9Wohd7.d.mts +363 -0
  807. package/dist/types-Bq9Wohd7.d.mts.map +1 -0
  808. package/dist/types-C-Xp0CcN.mjs +103 -0
  809. package/dist/types-C-Xp0CcN.mjs.map +1 -0
  810. package/dist/types-C4P7F1Vq.d.mts +1741 -0
  811. package/dist/types-C4P7F1Vq.d.mts.map +1 -0
  812. package/dist/types-CGaqwHw4.mjs +37 -0
  813. package/dist/types-CGaqwHw4.mjs.map +1 -0
  814. package/dist/types-Cj0_yZkn.mjs +18 -0
  815. package/dist/types-Cj0_yZkn.mjs.map +1 -0
  816. package/dist/types-D4ECCE4X.mjs +77 -0
  817. package/dist/types-D4ECCE4X.mjs.map +1 -0
  818. package/dist/types-DcRJp0vS.d.mts +125 -0
  819. package/dist/types-DcRJp0vS.d.mts.map +1 -0
  820. package/dist/types-Ff85fTzU.d.mts +289 -0
  821. package/dist/types-Ff85fTzU.d.mts.map +1 -0
  822. package/dist/types-UKr5Sf4y.d.mts +916 -0
  823. package/dist/types-UKr5Sf4y.d.mts.map +1 -0
  824. package/dist/types-YpN8hZW7.d.mts +204 -0
  825. package/dist/types-YpN8hZW7.d.mts.map +1 -0
  826. package/dist/update-check-DrlsK-tt.mjs +161 -0
  827. package/dist/update-check-DrlsK-tt.mjs.map +1 -0
  828. package/dist/upload-attempts-D8CPPvRU.mjs +32 -0
  829. package/dist/upload-attempts-D8CPPvRU.mjs.map +1 -0
  830. package/dist/url-pattern-Di4Nn3vP.mjs +41 -0
  831. package/dist/url-pattern-Di4Nn3vP.mjs.map +1 -0
  832. package/dist/user-B-ZdGjhI.mjs +171 -0
  833. package/dist/user-B-ZdGjhI.mjs.map +1 -0
  834. package/dist/utils-D7wL3r6-.mjs +437 -0
  835. package/dist/utils-D7wL3r6-.mjs.map +1 -0
  836. package/dist/validate-BSZbSUDk.mjs +524 -0
  837. package/dist/validate-BSZbSUDk.mjs.map +1 -0
  838. package/dist/validate-Dfv0DpZi.d.mts +468 -0
  839. package/dist/validate-Dfv0DpZi.d.mts.map +1 -0
  840. package/dist/validation-DRyC_Vm5.mjs +219 -0
  841. package/dist/validation-DRyC_Vm5.mjs.map +1 -0
  842. package/dist/version-C4kz0PcO.mjs +7 -0
  843. package/dist/version-C4kz0PcO.mjs.map +1 -0
  844. package/dist/version-jhs2BRtl.mjs +9 -0
  845. package/dist/version-jhs2BRtl.mjs.map +1 -0
  846. package/dist/video-DReZ48Un.mjs +54 -0
  847. package/dist/video-DReZ48Un.mjs.map +1 -0
  848. package/dist/virtual-modules-D0e6VbEv.mjs +516 -0
  849. package/dist/virtual-modules-D0e6VbEv.mjs.map +1 -0
  850. package/dist/widgets-BkcMzKct.mjs +121 -0
  851. package/dist/widgets-BkcMzKct.mjs.map +1 -0
  852. package/dist/wxr-taxonomies-BxI0CbTg.mjs +453 -0
  853. package/dist/wxr-taxonomies-BxI0CbTg.mjs.map +1 -0
  854. package/dist/wxr-taxonomies-Dad33GJi.d.mts +34 -0
  855. package/dist/wxr-taxonomies-Dad33GJi.d.mts.map +1 -0
  856. package/dist/zod-generator-BQilAboC.mjs +424 -0
  857. package/dist/zod-generator-BQilAboC.mjs.map +1 -0
  858. package/package.json +19 -10
  859. package/src/api/errors.ts +12 -0
  860. package/src/api/handlers/api-tokens.ts +12 -6
  861. package/src/api/handlers/bylines.ts +24 -3
  862. package/src/api/handlers/calendar.ts +246 -0
  863. package/src/api/handlers/content.ts +69 -13
  864. package/src/api/handlers/domain-move-notice.ts +94 -0
  865. package/src/api/handlers/index.ts +2 -0
  866. package/src/api/handlers/manifest.ts +5 -0
  867. package/src/api/handlers/media-allowlist.ts +1 -0
  868. package/src/api/handlers/media-upload.ts +13 -10
  869. package/src/api/handlers/media-usage.ts +2 -1
  870. package/src/api/handlers/media.ts +1 -0
  871. package/src/api/handlers/plugins.ts +21 -29
  872. package/src/api/handlers/redirects.ts +6 -6
  873. package/src/api/handlers/seo.ts +155 -59
  874. package/src/api/handlers/settings.ts +31 -1
  875. package/src/api/handlers/site-domain.ts +143 -0
  876. package/src/api/openapi/document.ts +2 -2
  877. package/src/api/public-url.ts +1 -1
  878. package/src/api/schemas/bylines.ts +3 -1
  879. package/src/api/schemas/content.ts +36 -0
  880. package/src/api/schemas/media-usage.ts +7 -1
  881. package/src/api/schemas/media.ts +12 -0
  882. package/src/api/site-url.ts +53 -5
  883. package/src/api/types.ts +2 -0
  884. package/src/astro/image-endpoint.ts +46 -4
  885. package/src/astro/integration/admin-locales.ts +168 -0
  886. package/src/astro/integration/dev-env.ts +84 -0
  887. package/src/astro/integration/index.ts +67 -10
  888. package/src/astro/integration/routes.ts +25 -0
  889. package/src/astro/integration/runtime.ts +15 -0
  890. package/src/astro/integration/vite-config.ts +29 -1
  891. package/src/astro/middleware/auth.ts +16 -3
  892. package/src/astro/middleware/csp.ts +2 -0
  893. package/src/astro/middleware/redirect.ts +47 -21
  894. package/src/astro/middleware/request-context.ts +64 -31
  895. package/src/astro/middleware.ts +150 -26
  896. package/src/astro/prefetch.ts +10 -3
  897. package/src/astro/routes/api/admin/bylines/[id]/translations.ts +0 -5
  898. package/src/astro/routes/api/admin/bylines/index.ts +1 -1
  899. package/src/astro/routes/api/admin/plugins/[id]/index.ts +1 -0
  900. package/src/astro/routes/api/auth/handover.ts +58 -0
  901. package/src/astro/routes/api/auth/magic-link/verify.ts +11 -3
  902. package/src/astro/routes/api/auth/oauth/[provider]/callback.ts +56 -4
  903. package/src/astro/routes/api/auth/oauth/[provider].ts +37 -4
  904. package/src/astro/routes/api/auth/passkey/options.ts +10 -2
  905. package/src/astro/routes/api/calendar.ts +35 -0
  906. package/src/astro/routes/api/import/wordpress/execute.ts +19 -0
  907. package/src/astro/routes/api/import/wordpress/rewrite-url-helpers.ts +80 -42
  908. package/src/astro/routes/api/import/wordpress-plugin/execute.ts +15 -0
  909. package/src/astro/routes/api/manifest.ts +10 -0
  910. package/src/astro/routes/api/media/[id]/confirm.ts +19 -0
  911. package/src/astro/routes/api/media/file/[...key].ts +60 -12
  912. package/src/astro/routes/api/media/upload-url.ts +35 -7
  913. package/src/astro/routes/api/media.ts +24 -5
  914. package/src/astro/routes/api/schema/index.ts +1 -1
  915. package/src/astro/routes/api/settings/domain-notify.ts +76 -0
  916. package/src/astro/routes/api/settings/domain.ts +63 -0
  917. package/src/astro/routes/api/setup/index.ts +21 -2
  918. package/src/astro/routes/api/site/domain-proof.ts +28 -0
  919. package/src/astro/routes/sitemap-[collection].xml.ts +31 -8
  920. package/src/astro/routes/sitemap.xml.ts +12 -10
  921. package/src/astro/types.ts +13 -1
  922. package/src/auth/providers/microsoft-admin.tsx +31 -0
  923. package/src/auth/providers/microsoft.ts +47 -0
  924. package/src/auth/rate-limit.ts +18 -13
  925. package/src/auth/types.ts +7 -0
  926. package/src/aws-sdk.d.ts +2 -1
  927. package/src/cleanup.ts +26 -0
  928. package/src/cli/commands/export-seed.ts +2 -0
  929. package/src/cli/commands/seed.ts +5 -4
  930. package/src/client/index.ts +6 -1
  931. package/src/comments/public-submission.ts +15 -8
  932. package/src/comments/turnstile.ts +6 -1
  933. package/src/components/CommentForm.astro +48 -8
  934. package/src/components/Comments.astro +50 -28
  935. package/src/components/EmDashImage.astro +6 -4
  936. package/src/components/Gallery.astro +4 -3
  937. package/src/components/HtmlBlock.astro +17 -6
  938. package/src/components/HtmlBlockFrame.astro +63 -0
  939. package/src/components/Iframe.astro +141 -0
  940. package/src/components/Image.astro +4 -3
  941. package/src/components/InlinePortableTextEditor.tsx +156 -33
  942. package/src/components/Video.astro +100 -0
  943. package/src/components/WebMcpSearch.astro +80 -0
  944. package/src/components/index.ts +8 -2
  945. package/src/components/inline-code-block.tsx +8 -0
  946. package/src/components/webmcp-search.ts +138 -0
  947. package/src/components/widgets/RecentPosts.astro +57 -17
  948. package/src/config/secrets.ts +27 -15
  949. package/src/content/converters/mark-safety.ts +3 -3
  950. package/src/content/converters/portable-text-identity.ts +2 -0
  951. package/src/content/converters/portable-text-to-prosemirror.ts +43 -2
  952. package/src/content/converters/prosemirror-to-portable-text.ts +44 -2
  953. package/src/content/converters/types.ts +46 -0
  954. package/src/content/converters/video.ts +77 -0
  955. package/src/database/content-datetime.ts +11 -4
  956. package/src/database/datetime-storage.ts +1 -1
  957. package/src/database/migrations/090_redirect_enable_loop_guard.ts +70 -0
  958. package/src/database/migrations/091_redirect_artifacts.ts +141 -0
  959. package/src/database/migrations/runner.ts +17 -1
  960. package/src/database/repositories/comment.ts +17 -3
  961. package/src/database/repositories/content.ts +103 -29
  962. package/src/database/repositories/plugin-storage.ts +28 -19
  963. package/src/database/repositories/redirect.ts +30 -3
  964. package/src/database/repositories/taxonomy.ts +61 -46
  965. package/src/database/repositories/types.ts +2 -0
  966. package/src/database/request-scoped.ts +34 -0
  967. package/src/database/types.ts +23 -0
  968. package/src/db/adapters.ts +2 -0
  969. package/src/emdash-runtime.ts +245 -71
  970. package/src/import/menus.ts +3 -0
  971. package/src/import/sources/wordpress-plugin.ts +3 -2
  972. package/src/import/utils.ts +2 -3
  973. package/src/index.ts +4 -0
  974. package/src/loader.ts +360 -98
  975. package/src/mcp/server.ts +12 -4
  976. package/src/media/image-endpoint.ts +101 -1
  977. package/src/media/mime.ts +21 -0
  978. package/src/media/responsive.ts +14 -7
  979. package/src/media/usage/extractor.ts +19 -2
  980. package/src/media/usage/types.ts +5 -1
  981. package/src/menus/index.ts +30 -26
  982. package/src/plugin-utils.ts +1 -1
  983. package/src/plugins/context.ts +3 -7
  984. package/src/plugins/hooks.ts +11 -1
  985. package/src/plugins/http-route-dispatch.ts +5 -1
  986. package/src/plugins/manager.ts +12 -2
  987. package/src/plugins/manifest-schema.ts +1 -0
  988. package/src/plugins/route-error.ts +14 -0
  989. package/src/plugins/routes.ts +2 -2
  990. package/src/plugins/state.ts +36 -0
  991. package/src/plugins/types.ts +22 -0
  992. package/src/query.ts +20 -29
  993. package/src/redirects/artifacts.ts +460 -0
  994. package/src/redirects/cache.ts +76 -41
  995. package/src/redirects/patterns.ts +26 -2
  996. package/src/request-context.ts +1 -1
  997. package/src/schema/registry.ts +7 -4
  998. package/src/schema/slug.ts +19 -0
  999. package/src/search/text-extraction.ts +6 -1
  1000. package/src/seed/apply.ts +65 -57
  1001. package/src/seed/validate.ts +31 -0
  1002. package/src/seo/sitemap-name.ts +22 -0
  1003. package/src/settings/index.ts +17 -12
  1004. package/src/storage/index.ts +2 -0
  1005. package/src/storage/local.ts +10 -2
  1006. package/src/storage/range.ts +54 -0
  1007. package/src/storage/s3.ts +52 -8
  1008. package/src/storage/types.ts +30 -3
  1009. package/src/transfer/format/columns.ts +3 -0
  1010. package/src/transfer/import/rebuild.ts +17 -2
  1011. package/src/transfer/import/scaffold.ts +16 -9
  1012. package/src/ui.ts +2 -0
  1013. package/src/utils/sanitize.ts +14 -9
  1014. package/src/utils/slugify.ts +6 -1
  1015. package/src/virtual-modules.d.ts +3 -0
  1016. package/src/visual-editing/toolbar.ts +80 -35
  1017. package/src/widgets/components.ts +4 -0
  1018. package/src/widgets/index.ts +74 -82
  1019. package/src/widgets/recent-posts.ts +62 -0
  1020. package/dist/action-token-D2KE1Rqf.mjs +0 -26
  1021. package/dist/action-token-D2KE1Rqf.mjs.map +0 -1
  1022. package/dist/activation-DDuqAat2.mjs +0 -387
  1023. package/dist/activation-DDuqAat2.mjs.map +0 -1
  1024. package/dist/adapters-Ds-1Pmkm.d.mts +0 -171
  1025. package/dist/adapters-Ds-1Pmkm.d.mts.map +0 -1
  1026. package/dist/allowed-origins-D78QvbTO.mjs +0 -116
  1027. package/dist/allowed-origins-D78QvbTO.mjs.map +0 -1
  1028. package/dist/api-BBZlif0y.mjs +0 -4974
  1029. package/dist/api-BBZlif0y.mjs.map +0 -1
  1030. package/dist/api-tokens-BGbfWZVO.mjs +0 -166
  1031. package/dist/api-tokens-BGbfWZVO.mjs.map +0 -1
  1032. package/dist/apply-CDNV4JJ-.mjs +0 -1672
  1033. package/dist/apply-CDNV4JJ-.mjs.map +0 -1
  1034. package/dist/approvals-CVvJSEBF.mjs +0 -460
  1035. package/dist/approvals-CVvJSEBF.mjs.map +0 -1
  1036. package/dist/artifact-fetch-CGK0DQLj.mjs +0 -659
  1037. package/dist/artifact-fetch-CGK0DQLj.mjs.map +0 -1
  1038. package/dist/audit-BszbE_BP.mjs +0 -127
  1039. package/dist/audit-BszbE_BP.mjs.map +0 -1
  1040. package/dist/authoritative-records-ChM8dTeV.mjs +0 -5172
  1041. package/dist/authoritative-records-ChM8dTeV.mjs.map +0 -1
  1042. package/dist/authorize-CTGywswM.mjs +0 -49
  1043. package/dist/authorize-CTGywswM.mjs.map +0 -1
  1044. package/dist/backup-CDrPP8fI.mjs +0 -246
  1045. package/dist/backup-CDrPP8fI.mjs.map +0 -1
  1046. package/dist/base64-DvnNgP7e.mjs +0 -63
  1047. package/dist/base64-DvnNgP7e.mjs.map +0 -1
  1048. package/dist/block-types-nNEaPkvx.mjs +0 -132
  1049. package/dist/block-types-nNEaPkvx.mjs.map +0 -1
  1050. package/dist/block-values-Bho1nsZF.mjs +0 -175
  1051. package/dist/block-values-Bho1nsZF.mjs.map +0 -1
  1052. package/dist/byline-02tu_Uc-.mjs +0 -909
  1053. package/dist/byline-02tu_Uc-.mjs.map +0 -1
  1054. package/dist/byline-fields-BYbTptTU.mjs +0 -280
  1055. package/dist/byline-fields-BYbTptTU.mjs.map +0 -1
  1056. package/dist/byline-fields-BjQH-1z9.mjs +0 -123
  1057. package/dist/byline-fields-BjQH-1z9.mjs.map +0 -1
  1058. package/dist/bylines-VytjeHBI.mjs +0 -214
  1059. package/dist/bylines-VytjeHBI.mjs.map +0 -1
  1060. package/dist/bylines-gyWBWUUc.mjs +0 -150
  1061. package/dist/bylines-gyWBWUUc.mjs.map +0 -1
  1062. package/dist/cache-CPanL9IO.mjs +0 -114
  1063. package/dist/cache-CPanL9IO.mjs.map +0 -1
  1064. package/dist/canonical-CAecl1UQ.mjs +0 -174
  1065. package/dist/canonical-CAecl1UQ.mjs.map +0 -1
  1066. package/dist/capture-triggers-CdZfvHtF.mjs +0 -362
  1067. package/dist/capture-triggers-CdZfvHtF.mjs.map +0 -1
  1068. package/dist/challenge-store-VePApay4.mjs +0 -51
  1069. package/dist/challenge-store-VePApay4.mjs.map +0 -1
  1070. package/dist/checksum-BSIhEAYW.mjs +0 -162
  1071. package/dist/checksum-BSIhEAYW.mjs.map +0 -1
  1072. package/dist/chrome-tags-CKELm-bo.mjs +0 -24
  1073. package/dist/chrome-tags-CKELm-bo.mjs.map +0 -1
  1074. package/dist/chunks-DBmkKmBH.mjs +0 -25
  1075. package/dist/chunks-DBmkKmBH.mjs.map +0 -1
  1076. package/dist/collection-slugs-cache-BNRAPNiu.mjs +0 -85
  1077. package/dist/collection-slugs-cache-BNRAPNiu.mjs.map +0 -1
  1078. package/dist/comment-Cq1UYN8_.mjs +0 -313
  1079. package/dist/comment-Cq1UYN8_.mjs.map +0 -1
  1080. package/dist/comment-reaction-B5sZzSoA.mjs +0 -85
  1081. package/dist/comment-reaction-B5sZzSoA.mjs.map +0 -1
  1082. package/dist/comments-B3F-ETyh.mjs +0 -195
  1083. package/dist/comments-B3F-ETyh.mjs.map +0 -1
  1084. package/dist/comments-zrTgWBSg.mjs +0 -99
  1085. package/dist/comments-zrTgWBSg.mjs.map +0 -1
  1086. package/dist/components-Dbf4Eq16.mjs +0 -108
  1087. package/dist/components-Dbf4Eq16.mjs.map +0 -1
  1088. package/dist/config-BCM5sQP7.d.mts +0 -6688
  1089. package/dist/config-BCM5sQP7.d.mts.map +0 -1
  1090. package/dist/config-CXPcy2iY.mjs +0 -228
  1091. package/dist/config-CXPcy2iY.mjs.map +0 -1
  1092. package/dist/config-CZkZBuBK.d.mts +0 -39
  1093. package/dist/config-CZkZBuBK.d.mts.map +0 -1
  1094. package/dist/connection-C5GIciX9.mjs +0 -36
  1095. package/dist/connection-C5GIciX9.mjs.map +0 -1
  1096. package/dist/content-RzEXY3QX.mjs +0 -2020
  1097. package/dist/content-RzEXY3QX.mjs.map +0 -1
  1098. package/dist/content-list-query-B6P37Ug_.d.mts +0 -26
  1099. package/dist/content-list-query-B6P37Ug_.d.mts.map +0 -1
  1100. package/dist/content-repair-BDVsYXWK.mjs +0 -442
  1101. package/dist/content-repair-BDVsYXWK.mjs.map +0 -1
  1102. package/dist/context-BpTIzY5h.mjs +0 -2026
  1103. package/dist/context-BpTIzY5h.mjs.map +0 -1
  1104. package/dist/credits-JOE92Gr7.mjs +0 -110
  1105. package/dist/credits-JOE92Gr7.mjs.map +0 -1
  1106. package/dist/cron-ktyapbdB.mjs +0 -306
  1107. package/dist/cron-ktyapbdB.mjs.map +0 -1
  1108. package/dist/dashboard-BoV4pwPP.mjs +0 -151
  1109. package/dist/dashboard-BoV4pwPP.mjs.map +0 -1
  1110. package/dist/default-B7KnYwtQ.mjs +0 -81
  1111. package/dist/default-B7KnYwtQ.mjs.map +0 -1
  1112. package/dist/deferred-tasks-eaUIqXj8.d.mts +0 -9
  1113. package/dist/deferred-tasks-eaUIqXj8.d.mts.map +0 -1
  1114. package/dist/dev-typegen-8JlYYFno.mjs +0 -29
  1115. package/dist/dev-typegen-8JlYYFno.mjs.map +0 -1
  1116. package/dist/device-flow-BlV_z24g.mjs +0 -521
  1117. package/dist/device-flow-BlV_z24g.mjs.map +0 -1
  1118. package/dist/digest-DiYAoZpf.mjs +0 -194
  1119. package/dist/digest-DiYAoZpf.mjs.map +0 -1
  1120. package/dist/direct-executor-Db8xA3zg.mjs +0 -104
  1121. package/dist/direct-executor-Db8xA3zg.mjs.map +0 -1
  1122. package/dist/email-console-Dm78wSmg.mjs +0 -50
  1123. package/dist/email-console-Dm78wSmg.mjs.map +0 -1
  1124. package/dist/email-locale-B4X9LXe9.mjs +0 -25
  1125. package/dist/email-locale-B4X9LXe9.mjs.map +0 -1
  1126. package/dist/emdash-runtime-BakQ6io7.mjs +0 -4239
  1127. package/dist/emdash-runtime-BakQ6io7.mjs.map +0 -1
  1128. package/dist/enrich-BDdVNeDK.mjs +0 -194
  1129. package/dist/enrich-BDdVNeDK.mjs.map +0 -1
  1130. package/dist/entry-lock-DY8B-xcr.d.mts +0 -4544
  1131. package/dist/entry-lock-DY8B-xcr.d.mts.map +0 -1
  1132. package/dist/entry-lock-DrUAdTzf.mjs +0 -163
  1133. package/dist/entry-lock-DrUAdTzf.mjs.map +0 -1
  1134. package/dist/entry-lock-yIkBduqJ.mjs +0 -1180
  1135. package/dist/entry-lock-yIkBduqJ.mjs.map +0 -1
  1136. package/dist/env-types-DkHYR2pl.mjs +0 -38
  1137. package/dist/env-types-DkHYR2pl.mjs.map +0 -1
  1138. package/dist/error-DIYXAVk4.mjs +0 -90
  1139. package/dist/error-DIYXAVk4.mjs.map +0 -1
  1140. package/dist/errors-CNvATh_7.mjs +0 -469
  1141. package/dist/errors-CNvATh_7.mjs.map +0 -1
  1142. package/dist/errors-CjXd1LgH.mjs +0 -120
  1143. package/dist/errors-CjXd1LgH.mjs.map +0 -1
  1144. package/dist/escape-B1GM0yJU.mjs +0 -9
  1145. package/dist/escape-B1GM0yJU.mjs.map +0 -1
  1146. package/dist/fence-8MaKKWhp.mjs +0 -162
  1147. package/dist/fence-8MaKKWhp.mjs.map +0 -1
  1148. package/dist/field-defs-cache-DEkFYCDE.mjs +0 -77
  1149. package/dist/field-defs-cache-DEkFYCDE.mjs.map +0 -1
  1150. package/dist/field-map-D7ioN0r0.mjs +0 -83
  1151. package/dist/field-map-D7ioN0r0.mjs.map +0 -1
  1152. package/dist/fts-manager-DU03MxWu.mjs +0 -443
  1153. package/dist/fts-manager-DU03MxWu.mjs.map +0 -1
  1154. package/dist/gc-DMiE7ezk.mjs +0 -75
  1155. package/dist/gc-DMiE7ezk.mjs.map +0 -1
  1156. package/dist/hash-CY4QdeMJ.mjs +0 -37
  1157. package/dist/hash-CY4QdeMJ.mjs.map +0 -1
  1158. package/dist/hook-result-Cb67D3P3.d.mts +0 -31
  1159. package/dist/hook-result-Cb67D3P3.d.mts.map +0 -1
  1160. package/dist/hreflang-Bterc3b7.mjs +0 -105
  1161. package/dist/hreflang-Bterc3b7.mjs.map +0 -1
  1162. package/dist/hreflang-uIBOE5yg.d.mts +0 -50
  1163. package/dist/hreflang-uIBOE5yg.d.mts.map +0 -1
  1164. package/dist/http-route-dispatch-DubjTibD.mjs +0 -339
  1165. package/dist/http-route-dispatch-DubjTibD.mjs.map +0 -1
  1166. package/dist/identity-DJ-5AcdG.mjs +0 -35
  1167. package/dist/identity-DJ-5AcdG.mjs.map +0 -1
  1168. package/dist/import-DEfuIgRz.mjs +0 -2020
  1169. package/dist/import-DEfuIgRz.mjs.map +0 -1
  1170. package/dist/index-xCy3j0f6.d.mts +0 -623
  1171. package/dist/index-xCy3j0f6.d.mts.map +0 -1
  1172. package/dist/init-lock-4eRRB4Le.mjs +0 -56
  1173. package/dist/init-lock-4eRRB4Le.mjs.map +0 -1
  1174. package/dist/install-finalization-DeGRbaVa.mjs +0 -58
  1175. package/dist/install-finalization-DeGRbaVa.mjs.map +0 -1
  1176. package/dist/keys-DWwMxdZh.mjs +0 -61
  1177. package/dist/keys-DWwMxdZh.mjs.map +0 -1
  1178. package/dist/kinds-D1A-00-F.mjs +0 -974
  1179. package/dist/kinds-D1A-00-F.mjs.map +0 -1
  1180. package/dist/lifecycle-BWtBGNEn.mjs +0 -25
  1181. package/dist/lifecycle-BWtBGNEn.mjs.map +0 -1
  1182. package/dist/load-BR1NEa_3.mjs +0 -28
  1183. package/dist/load-BR1NEa_3.mjs.map +0 -1
  1184. package/dist/loader-D4edocWH.mjs +0 -1197
  1185. package/dist/loader-D4edocWH.mjs.map +0 -1
  1186. package/dist/loops-DLaHFrvI.mjs +0 -205
  1187. package/dist/loops-DLaHFrvI.mjs.map +0 -1
  1188. package/dist/manifest-builder-8jsSLR7s.mjs +0 -189
  1189. package/dist/manifest-builder-8jsSLR7s.mjs.map +0 -1
  1190. package/dist/manifest-schema-DcZjRNEv.mjs +0 -496
  1191. package/dist/manifest-schema-DcZjRNEv.mjs.map +0 -1
  1192. package/dist/marketplace-CNxjq10S.mjs +0 -257
  1193. package/dist/marketplace-CNxjq10S.mjs.map +0 -1
  1194. package/dist/media-3v7mqAVX.mjs +0 -294
  1195. package/dist/media-3v7mqAVX.mjs.map +0 -1
  1196. package/dist/media-Bs6qmlVl.mjs +0 -408
  1197. package/dist/media-Bs6qmlVl.mjs.map +0 -1
  1198. package/dist/media-CputjGE1.mjs +0 -373
  1199. package/dist/media-CputjGE1.mjs.map +0 -1
  1200. package/dist/media-allowlist-isqF1gAh.mjs +0 -44
  1201. package/dist/media-allowlist-isqF1gAh.mjs.map +0 -1
  1202. package/dist/media-folders-D2VdVBf6.mjs +0 -210
  1203. package/dist/media-folders-D2VdVBf6.mjs.map +0 -1
  1204. package/dist/media-url-DbkMY3y6.mjs +0 -43
  1205. package/dist/media-url-DbkMY3y6.mjs.map +0 -1
  1206. package/dist/media-usage-activation-BaT4AlNI.mjs +0 -78
  1207. package/dist/media-usage-activation-BaT4AlNI.mjs.map +0 -1
  1208. package/dist/media-usage-v43L0kR_.mjs +0 -282
  1209. package/dist/media-usage-v43L0kR_.mjs.map +0 -1
  1210. package/dist/media-usage-work-CY8gIeU-.mjs +0 -151
  1211. package/dist/media-usage-work-CY8gIeU-.mjs.map +0 -1
  1212. package/dist/media-usage-work-VO108Q9E.mjs +0 -1015
  1213. package/dist/media-usage-work-VO108Q9E.mjs.map +0 -1
  1214. package/dist/menus-BYyeRemR.mjs +0 -3647
  1215. package/dist/menus-BYyeRemR.mjs.map +0 -1
  1216. package/dist/menus-mC_XTxD7.mjs +0 -92
  1217. package/dist/menus-mC_XTxD7.mjs.map +0 -1
  1218. package/dist/menus-trvc6_fW.mjs +0 -753
  1219. package/dist/menus-trvc6_fW.mjs.map +0 -1
  1220. package/dist/mime-IZf-LHIS.mjs +0 -36
  1221. package/dist/mime-IZf-LHIS.mjs.map +0 -1
  1222. package/dist/mode-B9-gMXL9.mjs +0 -23
  1223. package/dist/mode-B9-gMXL9.mjs.map +0 -1
  1224. package/dist/node-sqlite-compat-DztcWs4y.mjs +0 -63
  1225. package/dist/node-sqlite-compat-DztcWs4y.mjs.map +0 -1
  1226. package/dist/oauth-authorization-BIHy9SGU.mjs +0 -274
  1227. package/dist/oauth-authorization-BIHy9SGU.mjs.map +0 -1
  1228. package/dist/oauth-clients-BZWZvKXa.mjs +0 -266
  1229. package/dist/oauth-clients-BZWZvKXa.mjs.map +0 -1
  1230. package/dist/oauth-state-store-CxXTjXdI.mjs +0 -50
  1231. package/dist/oauth-state-store-CxXTjXdI.mjs.map +0 -1
  1232. package/dist/oauth-user-lookup-GWojfxRl.mjs +0 -26
  1233. package/dist/oauth-user-lookup-GWojfxRl.mjs.map +0 -1
  1234. package/dist/options-DRF6dlXY.d.mts +0 -81
  1235. package/dist/options-DRF6dlXY.d.mts.map +0 -1
  1236. package/dist/ownership-Bd77AmJz.mjs +0 -12
  1237. package/dist/ownership-Bd77AmJz.mjs.map +0 -1
  1238. package/dist/parse-5Y0W39xR.mjs +0 -81
  1239. package/dist/parse-5Y0W39xR.mjs.map +0 -1
  1240. package/dist/parse-BPblgoa-.d.mts +0 -172
  1241. package/dist/parse-BPblgoa-.d.mts.map +0 -1
  1242. package/dist/passkey-config-PiQ5cBnt.mjs +0 -46
  1243. package/dist/passkey-config-PiQ5cBnt.mjs.map +0 -1
  1244. package/dist/paths-DkS74lBM.mjs +0 -77
  1245. package/dist/paths-DkS74lBM.mjs.map +0 -1
  1246. package/dist/patterns-DyZJ67I7.mjs +0 -140
  1247. package/dist/patterns-DyZJ67I7.mjs.map +0 -1
  1248. package/dist/placeholder-Bez2282x.d.mts +0 -306
  1249. package/dist/placeholder-Bez2282x.d.mts.map +0 -1
  1250. package/dist/plan-Lw7iGnGD.mjs +0 -135
  1251. package/dist/plan-Lw7iGnGD.mjs.map +0 -1
  1252. package/dist/plugins-D7xSh1Lu.mjs +0 -277
  1253. package/dist/plugins-D7xSh1Lu.mjs.map +0 -1
  1254. package/dist/policy-DMRiMdLn.mjs +0 -45
  1255. package/dist/policy-DMRiMdLn.mjs.map +0 -1
  1256. package/dist/portable-text-kcyN3F-a.mjs +0 -307
  1257. package/dist/portable-text-kcyN3F-a.mjs.map +0 -1
  1258. package/dist/preview--2VDLaND.mjs +0 -107
  1259. package/dist/preview--2VDLaND.mjs.map +0 -1
  1260. package/dist/protocol-FvwLA8P-.d.mts +0 -61
  1261. package/dist/protocol-FvwLA8P-.d.mts.map +0 -1
  1262. package/dist/public-submission-BRyK76U8.mjs +0 -250
  1263. package/dist/public-submission-BRyK76U8.mjs.map +0 -1
  1264. package/dist/public-url-7j0cpCFc.mjs +0 -101
  1265. package/dist/public-url-7j0cpCFc.mjs.map +0 -1
  1266. package/dist/query-BRNTde3V.mjs +0 -41
  1267. package/dist/query-BRNTde3V.mjs.map +0 -1
  1268. package/dist/query-DyYYWOKk.mjs +0 -1161
  1269. package/dist/query-DyYYWOKk.mjs.map +0 -1
  1270. package/dist/rate-limit-D0BcE76H.mjs +0 -120
  1271. package/dist/rate-limit-D0BcE76H.mjs.map +0 -1
  1272. package/dist/receipt-C4icyHlC.mjs +0 -43
  1273. package/dist/receipt-C4icyHlC.mjs.map +0 -1
  1274. package/dist/redirect-9DbtxSNG.mjs +0 -19
  1275. package/dist/redirect-9DbtxSNG.mjs.map +0 -1
  1276. package/dist/redirect-BvFKh8Sz.mjs +0 -416
  1277. package/dist/redirect-BvFKh8Sz.mjs.map +0 -1
  1278. package/dist/redirects-1nhdEaTq.mjs +0 -148
  1279. package/dist/redirects-1nhdEaTq.mjs.map +0 -1
  1280. package/dist/redirects-D1yMnSR9.mjs +0 -446
  1281. package/dist/redirects-D1yMnSR9.mjs.map +0 -1
  1282. package/dist/registry-CzPJNu3H.mjs +0 -8366
  1283. package/dist/registry-CzPJNu3H.mjs.map +0 -1
  1284. package/dist/relations-C8JpSkU6.mjs +0 -776
  1285. package/dist/relations-C8JpSkU6.mjs.map +0 -1
  1286. package/dist/request-meta-Bs60XW1m.mjs +0 -141
  1287. package/dist/request-meta-Bs60XW1m.mjs.map +0 -1
  1288. package/dist/resolve-BHWgMU_X.mjs +0 -100
  1289. package/dist/resolve-BHWgMU_X.mjs.map +0 -1
  1290. package/dist/revision-CGkQA0e5.mjs +0 -366
  1291. package/dist/revision-CGkQA0e5.mjs.map +0 -1
  1292. package/dist/route-wire-ClUVQduA.mjs +0 -197
  1293. package/dist/route-wire-ClUVQduA.mjs.map +0 -1
  1294. package/dist/routes-D2GFl3B7.mjs +0 -272
  1295. package/dist/routes-D2GFl3B7.mjs.map +0 -1
  1296. package/dist/runner-CLpxmhl8.mjs +0 -6197
  1297. package/dist/runner-CLpxmhl8.mjs.map +0 -1
  1298. package/dist/runner-CWl76CH3.d.mts +0 -68
  1299. package/dist/runner-CWl76CH3.d.mts.map +0 -1
  1300. package/dist/schema-27XefSYG.mjs +0 -13
  1301. package/dist/schema-27XefSYG.mjs.map +0 -1
  1302. package/dist/schema-Btvj3BMh.mjs +0 -815
  1303. package/dist/schema-Btvj3BMh.mjs.map +0 -1
  1304. package/dist/scopes-DGCj6K4p.mjs +0 -34
  1305. package/dist/scopes-DGCj6K4p.mjs.map +0 -1
  1306. package/dist/search-pZRRmWjh.mjs +0 -448
  1307. package/dist/search-pZRRmWjh.mjs.map +0 -1
  1308. package/dist/secrets-CIi0nFiR.mjs +0 -341
  1309. package/dist/secrets-CIi0nFiR.mjs.map +0 -1
  1310. package/dist/sections-CIhqs3Ao.mjs +0 -346
  1311. package/dist/sections-CIhqs3Ao.mjs.map +0 -1
  1312. package/dist/seo-DifeiGdl.mjs +0 -114
  1313. package/dist/seo-DifeiGdl.mjs.map +0 -1
  1314. package/dist/seo-DpYxmGaL.mjs +0 -133
  1315. package/dist/seo-DpYxmGaL.mjs.map +0 -1
  1316. package/dist/service-COVdVpSK.mjs +0 -150
  1317. package/dist/service-COVdVpSK.mjs.map +0 -1
  1318. package/dist/session-user-C6IEjuty.mjs +0 -61
  1319. package/dist/session-user-C6IEjuty.mjs.map +0 -1
  1320. package/dist/settings-CwcrX-Ay.mjs +0 -61
  1321. package/dist/settings-CwcrX-Ay.mjs.map +0 -1
  1322. package/dist/settings-D_cJtT48.mjs +0 -439
  1323. package/dist/settings-D_cJtT48.mjs.map +0 -1
  1324. package/dist/settings-tnPQN3Z2.mjs +0 -51
  1325. package/dist/settings-tnPQN3Z2.mjs.map +0 -1
  1326. package/dist/setup-complete-BOrI10UY.mjs +0 -65
  1327. package/dist/setup-complete-BOrI10UY.mjs.map +0 -1
  1328. package/dist/setup-nonce-0XTBLTsX.mjs +0 -25
  1329. package/dist/setup-nonce-0XTBLTsX.mjs.map +0 -1
  1330. package/dist/single-flight-cache-B5O2qhO1.mjs +0 -104
  1331. package/dist/single-flight-cache-B5O2qhO1.mjs.map +0 -1
  1332. package/dist/site-settings-B7vGFRDT.mjs +0 -50
  1333. package/dist/site-settings-B7vGFRDT.mjs.map +0 -1
  1334. package/dist/site-url-wEYRMHBv.mjs +0 -16
  1335. package/dist/site-url-wEYRMHBv.mjs.map +0 -1
  1336. package/dist/slugify-T5GHH42D.mjs +0 -17
  1337. package/dist/slugify-T5GHH42D.mjs.map +0 -1
  1338. package/dist/snapshot-W36KbLmc.mjs +0 -414
  1339. package/dist/snapshot-W36KbLmc.mjs.map +0 -1
  1340. package/dist/ssrf-CRJ-xom5.mjs +0 -406
  1341. package/dist/ssrf-CRJ-xom5.mjs.map +0 -1
  1342. package/dist/stage-DA0NrTRZ.mjs +0 -662
  1343. package/dist/stage-DA0NrTRZ.mjs.map +0 -1
  1344. package/dist/staged-Bw5eHbKS.mjs +0 -686
  1345. package/dist/staged-Bw5eHbKS.mjs.map +0 -1
  1346. package/dist/state-BTlprvUF.mjs +0 -153
  1347. package/dist/state-BTlprvUF.mjs.map +0 -1
  1348. package/dist/status-C6IrSLMT.mjs +0 -30
  1349. package/dist/status-C6IrSLMT.mjs.map +0 -1
  1350. package/dist/storage-query-CdVF2bng.d.mts +0 -1614
  1351. package/dist/storage-query-CdVF2bng.d.mts.map +0 -1
  1352. package/dist/tar-BGOZARjy.mjs +0 -449
  1353. package/dist/tar-BGOZARjy.mjs.map +0 -1
  1354. package/dist/target-YhYH_0uc.mjs +0 -27
  1355. package/dist/target-YhYH_0uc.mjs.map +0 -1
  1356. package/dist/taxonomies-DK_XBrmT.mjs +0 -697
  1357. package/dist/taxonomies-DK_XBrmT.mjs.map +0 -1
  1358. package/dist/taxonomies-S1M3rUC0.mjs +0 -939
  1359. package/dist/taxonomies-S1M3rUC0.mjs.map +0 -1
  1360. package/dist/taxonomy-BesdHIwi.mjs +0 -525
  1361. package/dist/taxonomy-BesdHIwi.mjs.map +0 -1
  1362. package/dist/tokens-B_ffPF1q.mjs +0 -171
  1363. package/dist/tokens-B_ffPF1q.mjs.map +0 -1
  1364. package/dist/transfer-9fVSxyrV.mjs +0 -166
  1365. package/dist/transfer-9fVSxyrV.mjs.map +0 -1
  1366. package/dist/transfer-B7LUTaYD.mjs +0 -8855
  1367. package/dist/transfer-B7LUTaYD.mjs.map +0 -1
  1368. package/dist/transfer-download-BdNq4VWN.mjs +0 -33
  1369. package/dist/transfer-download-BdNq4VWN.mjs.map +0 -1
  1370. package/dist/transformations-BtQdvyly.mjs +0 -196
  1371. package/dist/transformations-BtQdvyly.mjs.map +0 -1
  1372. package/dist/transport-CriYXY1c.mjs +0 -136
  1373. package/dist/transport-CriYXY1c.mjs.map +0 -1
  1374. package/dist/transport-SnhS6xku.d.mts +0 -42
  1375. package/dist/transport-SnhS6xku.d.mts.map +0 -1
  1376. package/dist/trusted-proxy-C0eHXPd-.mjs +0 -51
  1377. package/dist/trusted-proxy-C0eHXPd-.mjs.map +0 -1
  1378. package/dist/turnstile-BNPrWd1e.mjs +0 -53
  1379. package/dist/turnstile-BNPrWd1e.mjs.map +0 -1
  1380. package/dist/types-B8sF_kE5.d.mts +0 -287
  1381. package/dist/types-B8sF_kE5.d.mts.map +0 -1
  1382. package/dist/types-BYVIYOlD.d.mts +0 -1720
  1383. package/dist/types-BYVIYOlD.d.mts.map +0 -1
  1384. package/dist/types-Bs4bi95j.d.mts +0 -374
  1385. package/dist/types-Bs4bi95j.d.mts.map +0 -1
  1386. package/dist/types-CGuODCZi.d.mts +0 -198
  1387. package/dist/types-CGuODCZi.d.mts.map +0 -1
  1388. package/dist/types-CVsmpTcU.mjs +0 -18
  1389. package/dist/types-CVsmpTcU.mjs.map +0 -1
  1390. package/dist/types-ClFEExxn.mjs +0 -37
  1391. package/dist/types-ClFEExxn.mjs.map +0 -1
  1392. package/dist/types-D994zUWB.d.mts +0 -85
  1393. package/dist/types-D994zUWB.d.mts.map +0 -1
  1394. package/dist/types-DAj1ByJQ.d.mts +0 -125
  1395. package/dist/types-DAj1ByJQ.d.mts.map +0 -1
  1396. package/dist/types-Dlv6esp4.mjs +0 -77
  1397. package/dist/types-Dlv6esp4.mjs.map +0 -1
  1398. package/dist/types-Dr1LVwL7.d.mts +0 -363
  1399. package/dist/types-Dr1LVwL7.d.mts.map +0 -1
  1400. package/dist/types-MN9bOQ1g.d.mts +0 -198
  1401. package/dist/types-MN9bOQ1g.d.mts.map +0 -1
  1402. package/dist/types-d2Szb1oz.mjs +0 -16
  1403. package/dist/types-d2Szb1oz.mjs.map +0 -1
  1404. package/dist/types-ibtP7GEA.d.mts +0 -896
  1405. package/dist/types-ibtP7GEA.d.mts.map +0 -1
  1406. package/dist/types-j6MBDjlZ.mjs +0 -103
  1407. package/dist/types-j6MBDjlZ.mjs.map +0 -1
  1408. package/dist/update-check-D8No-E5s.mjs +0 -161
  1409. package/dist/update-check-D8No-E5s.mjs.map +0 -1
  1410. package/dist/upload-attempts-BodUoFBu.mjs +0 -32
  1411. package/dist/upload-attempts-BodUoFBu.mjs.map +0 -1
  1412. package/dist/url-pattern-DGAG6ZP2.mjs +0 -41
  1413. package/dist/url-pattern-DGAG6ZP2.mjs.map +0 -1
  1414. package/dist/user-BOvuF1sQ.mjs +0 -171
  1415. package/dist/user-BOvuF1sQ.mjs.map +0 -1
  1416. package/dist/utils-Dr01wRKt.mjs +0 -439
  1417. package/dist/utils-Dr01wRKt.mjs.map +0 -1
  1418. package/dist/validate-BttYU7NK.mjs +0 -516
  1419. package/dist/validate-BttYU7NK.mjs.map +0 -1
  1420. package/dist/validate-Df09inbC.d.mts +0 -468
  1421. package/dist/validate-Df09inbC.d.mts.map +0 -1
  1422. package/dist/validation-DH2WRwWO.mjs +0 -219
  1423. package/dist/validation-DH2WRwWO.mjs.map +0 -1
  1424. package/dist/version-BbygH8CT.mjs +0 -7
  1425. package/dist/version-BbygH8CT.mjs.map +0 -1
  1426. package/dist/version-CseoDDOd.mjs +0 -9
  1427. package/dist/version-CseoDDOd.mjs.map +0 -1
  1428. package/dist/virtual-modules-82GlnQyG.mjs +0 -516
  1429. package/dist/virtual-modules-82GlnQyG.mjs.map +0 -1
  1430. package/dist/widgets-DMAgGcQt.mjs +0 -126
  1431. package/dist/widgets-DMAgGcQt.mjs.map +0 -1
  1432. package/dist/wxr-taxonomies-Bi5kFSxQ.mjs +0 -453
  1433. package/dist/wxr-taxonomies-Bi5kFSxQ.mjs.map +0 -1
  1434. package/dist/wxr-taxonomies-y_FpYlDn.d.mts +0 -34
  1435. package/dist/wxr-taxonomies-y_FpYlDn.d.mts.map +0 -1
  1436. package/dist/zod-generator-DnfG5sGQ.mjs +0 -424
  1437. package/dist/zod-generator-DnfG5sGQ.mjs.map +0 -1
  1438. /package/dist/{api-tokens-B4COohsb.mjs → api-tokens-D2zgAIEt.mjs} +0 -0
  1439. /package/dist/{ssrf-sC4_5rxm.mjs → ssrf-BvNItdxk.mjs} +0 -0
@@ -1 +0,0 @@
1
- {"version":3,"file":"relations-C8JpSkU6.mjs","names":["isRecord"],"sources":["../src/api/handlers/validate-references.ts","../src/api/handlers/relations.ts"],"sourcesContent":["import type { Kysely } from \"kysely\";\n\nimport type { Database } from \"../../database/types.js\";\nimport { requestCached } from \"../../request-cache.js\";\nimport type { ApiResult } from \"../types.js\";\n\nexport interface ReferenceFieldConstraints {\n\t/** Field slug — how the entry API addresses the selection. */\n\tslug: string;\n\t/** Relation slug the field binds to. */\n\trelation: string;\n\t/** Relation id, for the reads that address the link table directly. */\n\trelationId: string | null;\n\t/** Which end of the relation the field's own collection sits on. */\n\trelationSide: \"parent\" | \"child\";\n\t/** How many entries this side of the relation may hold. `null` is unlimited. */\n\tmaxSelected: number | null;\n\t/** How many this field's selection may hand each entry it selects. */\n\tmaxOpposite: number | null;\n\trequired: boolean;\n}\n\nfunction validationError(message: string): ApiResult<never> {\n\treturn { success: false, error: { code: \"VALIDATION_ERROR\", message } };\n}\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n\treturn typeof value === \"object\" && value !== null;\n}\n\n/**\n * Every reference field on a collection that is bound to a relation, by field\n * slug — the key the entry API takes a selection under.\n */\nexport function referenceFieldConstraints(\n\tdb: Kysely<Database>,\n\tcollection: string,\n): Promise<Map<string, ReferenceFieldConstraints>> {\n\treturn requestCached(`reference-field-constraints:${collection}`, async () => {\n\t\tconst fields = await db\n\t\t\t.selectFrom(\"_emdash_fields\")\n\t\t\t.innerJoin(\"_emdash_collections\", \"_emdash_collections.id\", \"_emdash_fields.collection_id\")\n\t\t\t.select([\"_emdash_fields.slug\", \"_emdash_fields.required\", \"_emdash_fields.validation\"])\n\t\t\t.where(\"_emdash_collections.slug\", \"=\", collection)\n\t\t\t.where(\"_emdash_fields.type\", \"=\", \"reference\")\n\t\t\t.execute();\n\n\t\t// Cardinality lives on the relation, not the field: with both ends of a\n\t\t// relation bindable, two fields carrying their own limits could disagree\n\t\t// about one edge set. The field contributes only which end it views.\n\t\tconst relations = await db\n\t\t\t.selectFrom(\"_emdash_relations\")\n\t\t\t.select([\"id\", \"slug\", \"max_children_per_parent\", \"max_parents_per_child\"])\n\t\t\t.execute();\n\t\tconst limits = new Map(relations.map((r) => [r.slug, r]));\n\n\t\tconst constraints = new Map<string, ReferenceFieldConstraints>();\n\t\tfor (const field of fields) {\n\t\t\tif (!field.validation) continue;\n\n\t\t\tlet parsed: unknown;\n\t\t\ttry {\n\t\t\t\tparsed = JSON.parse(field.validation);\n\t\t\t} catch {\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\tif (!isRecord(parsed) || typeof parsed.relation !== \"string\") continue;\n\n\t\t\tconst relation = limits.get(parsed.relation);\n\t\t\tconst relationSide = parsed.relationSide === \"child\" ? \"child\" : \"parent\";\n\t\t\tconst onChildSide = relationSide === \"child\";\n\n\t\t\tconstraints.set(field.slug, {\n\t\t\t\tslug: field.slug,\n\t\t\t\trelation: parsed.relation,\n\t\t\t\trelationId: relation?.id ?? null,\n\t\t\t\trelationSide,\n\t\t\t\tmaxSelected: onChildSide\n\t\t\t\t\t? (relation?.max_parents_per_child ?? null)\n\t\t\t\t\t: (relation?.max_children_per_parent ?? null),\n\t\t\t\tmaxOpposite: onChildSide\n\t\t\t\t\t? (relation?.max_children_per_parent ?? null)\n\t\t\t\t\t: (relation?.max_parents_per_child ?? null),\n\t\t\t\trequired: field.required === 1,\n\t\t\t});\n\t\t}\n\t\treturn constraints;\n\t});\n}\n\n/**\n * The field viewing one end of a relation, for the relation-scoped routes, which\n * address a relation rather than a field. At most one field binds each\n * (relation, side), so this is unambiguous.\n */\nexport function constraintsForRelationSide(\n\tconstraints: Map<string, ReferenceFieldConstraints>,\n\trelation: string,\n\tside: \"parent\" | \"child\",\n): ReferenceFieldConstraints | undefined {\n\tfor (const field of constraints.values()) {\n\t\tif (field.relation === relation && field.relationSide === side) return field;\n\t}\n\treturn undefined;\n}\n\nexport function validateReferenceSelection(\n\tconstraints: ReferenceFieldConstraints,\n\tchildIds: string[],\n): ApiResult<true> {\n\tconst max = constraints.maxSelected;\n\tif (max !== null && childIds.length > max) {\n\t\treturn validationError(\n\t\t\tmax === 1\n\t\t\t\t? `Field '${constraints.slug}' accepts a single reference, received ${childIds.length}.`\n\t\t\t\t: `Field '${constraints.slug}' accepts at most ${max} references, received ${childIds.length}.`,\n\t\t);\n\t}\n\tif (constraints.required && childIds.length === 0) {\n\t\treturn validationError(\n\t\t\t`Field '${constraints.slug}' is required and must reference at least one entry.`,\n\t\t);\n\t}\n\treturn { success: true, data: true };\n}\n\nexport async function validateRequiredReferencesPresent(\n\tdb: Kysely<Database>,\n\tcollection: string,\n\treferences: Record<string, string[]> | undefined,\n\ttranslationOf: string | undefined,\n): Promise<ApiResult<true>> {\n\t// References belong to a translation group, so a new locale row inherits\n\t// the source group's existing edges when its payload omits them.\n\tif (translationOf) return { success: true, data: true };\n\n\tconst constraints = await referenceFieldConstraints(db, collection);\n\tfor (const field of constraints.values()) {\n\t\tif (!field.required) continue;\n\t\tif (references && Object.hasOwn(references, field.slug)) continue;\n\t\treturn validationError(\n\t\t\t`Field '${field.slug}' is required and must reference at least one entry.`,\n\t\t);\n\t}\n\treturn { success: true, data: true };\n}\n","import type { Kysely } from \"kysely\";\n\nimport { ContentRepository } from \"../../database/repositories/content.js\";\nimport {\n\tRelationRepository,\n\ttype ContentReference,\n\ttype CreateRelationInput,\n\ttype Relation,\n\ttype UpdateRelationInput,\n} from \"../../database/repositories/relation.js\";\nimport { RevisionRepository } from \"../../database/repositories/revision.js\";\nimport { InvalidCursorError } from \"../../database/repositories/types.js\";\nimport type { ContentItem } from \"../../database/repositories/types.js\";\nimport { withTransaction } from \"../../database/transaction.js\";\nimport type { Database } from \"../../database/types.js\";\nimport { invalidateCollectionCache } from \"../../object-cache/index.js\";\nimport {\n\tpageStagedGroups,\n\treadStagedReferences,\n\ttype PageOfGroups,\n} from \"../../references/staged.js\";\nimport { requestCached } from \"../../request-cache.js\";\nimport { invalidateSchemaCache } from \"../../schema/index.js\";\nimport { SchemaRegistry } from \"../../schema/registry.js\";\nimport type { ApiResult } from \"../types.js\";\nimport {\n\tconstraintsForRelationSide,\n\treferenceFieldConstraints,\n\tvalidateReferenceSelection,\n\ttype ReferenceFieldConstraints,\n} from \"./validate-references.js\";\n\n/** Map an edge-read failure: a bad pagination cursor is a 400 client error,\n * everything else is the generic 500-shaped reference-read error. */\nfunction referencesGetError(error: unknown): ApiResult<never> {\n\tif (error instanceof InvalidCursorError) {\n\t\treturn { success: false, error: { code: \"INVALID_CURSOR\", message: error.message } };\n\t}\n\treturn {\n\t\tsuccess: false,\n\t\terror: { code: \"REFERENCES_GET_ERROR\", message: \"Failed to get references\" },\n\t};\n}\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n\treturn typeof value === \"object\" && value !== null;\n}\n\n/** True for SQLite UNIQUE / Postgres unique_violation messages (matches the\n * fingerprint used in the content handlers). Narrow enough not to catch NOT\n * NULL / CHECK violations whose messages also say \"constraint\". */\nfunction isUniqueViolation(error: unknown): boolean {\n\tconst message = error instanceof Error ? error.message.toLowerCase() : \"\";\n\treturn message.includes(\"unique constraint failed\") || message.includes(\"duplicate key\");\n}\n\nexport async function handleRelationCreate(\n\tdb: Kysely<Database>,\n\tinput: CreateRelationInput,\n): Promise<ApiResult<{ relation: Relation }>> {\n\ttry {\n\t\tconst repo = new RelationRepository(db);\n\n\t\t// Invariant: a relation must point at collections that exist. There is no\n\t\t// SQL FK (the edge endpoints are content translation_groups, which\n\t\t// precludes one), so a ghost collection would yield a\n\t\t// structurally-valid-but-permanently-useless relation.\n\t\tconst registry = new SchemaRegistry(db);\n\t\tfor (const collection of [input.parentCollection, input.childCollection]) {\n\t\t\tif (!(await registry.getCollection(collection))) {\n\t\t\t\treturn {\n\t\t\t\t\tsuccess: false,\n\t\t\t\t\terror: {\n\t\t\t\t\t\tcode: \"COLLECTION_NOT_FOUND\",\n\t\t\t\t\t\tmessage: `Collection '${collection}' not found`,\n\t\t\t\t\t},\n\t\t\t\t};\n\t\t\t}\n\t\t}\n\n\t\tconst relation = await repo.create(input);\n\t\treturn { success: true, data: { relation } };\n\t} catch (error) {\n\t\tif (isUniqueViolation(error)) {\n\t\t\treturn {\n\t\t\t\tsuccess: false,\n\t\t\t\terror: {\n\t\t\t\t\tcode: \"CONFLICT\",\n\t\t\t\t\tmessage: \"A relation with this slug already exists\",\n\t\t\t\t},\n\t\t\t};\n\t\t}\n\t\treturn {\n\t\t\tsuccess: false,\n\t\t\terror: { code: \"RELATION_CREATE_ERROR\", message: \"Failed to create relation\" },\n\t\t};\n\t}\n}\n\n/**\n * A relation plus what deleting it would take with it: the reference fields\n * that view it, and how many links it holds. Both delete dialogs enumerate\n * these before the user confirms.\n */\nexport interface RelationWithUsage extends Relation {\n\tboundFields: BoundField[];\n\tlinkCount: number;\n}\n\nexport async function handleRelationGet(\n\tdb: Kysely<Database>,\n\tid: string,\n): Promise<ApiResult<{ relation: RelationWithUsage }>> {\n\ttry {\n\t\tconst repo = new RelationRepository(db);\n\t\tconst relation = await repo.findById(id);\n\t\tif (!relation) {\n\t\t\treturn { success: false, error: { code: \"NOT_FOUND\", message: \"Relation not found\" } };\n\t\t}\n\t\tconst [boundFields, edgeCounts] = await Promise.all([\n\t\t\tfieldsBoundToRelation(db, relation.slug),\n\t\t\trepo.countEdgesByRelation(),\n\t\t]);\n\t\treturn {\n\t\t\tsuccess: true,\n\t\t\tdata: { relation: { ...relation, boundFields, linkCount: edgeCounts.get(relation.id) ?? 0 } },\n\t\t};\n\t} catch {\n\t\treturn {\n\t\t\tsuccess: false,\n\t\t\terror: { code: \"RELATION_GET_ERROR\", message: \"Failed to get relation\" },\n\t\t};\n\t}\n}\n\n/**\n * List relations, optionally only those `collection` takes part in.\n *\n * The admin's relation picker filters this way: a reference field can only bind\n * to a relation with its own collection on one end.\n */\nexport async function handleRelationList(\n\tdb: Kysely<Database>,\n\topts: { collection?: string } = {},\n): Promise<ApiResult<{ relations: RelationWithUsage[] }>> {\n\ttry {\n\t\tconst repo = new RelationRepository(db);\n\t\tconst [relations, boundByRelation, edgeCounts] = await Promise.all([\n\t\t\topts.collection ? repo.findForCollection(opts.collection) : repo.list(),\n\t\t\tfieldsBoundByRelation(db),\n\t\t\trepo.countEdgesByRelation(),\n\t\t]);\n\t\treturn {\n\t\t\tsuccess: true,\n\t\t\tdata: {\n\t\t\t\trelations: relations.map((relation) => ({\n\t\t\t\t\t...relation,\n\t\t\t\t\tboundFields: boundByRelation.get(relation.slug) ?? [],\n\t\t\t\t\tlinkCount: edgeCounts.get(relation.id) ?? 0,\n\t\t\t\t})),\n\t\t\t},\n\t\t};\n\t} catch {\n\t\treturn {\n\t\t\tsuccess: false,\n\t\t\terror: { code: \"RELATION_LIST_ERROR\", message: \"Failed to list relations\" },\n\t\t};\n\t}\n}\n\nexport async function handleRelationUpdate(\n\tdb: Kysely<Database>,\n\tid: string,\n\tinput: UpdateRelationInput,\n): Promise<ApiResult<{ relation: Relation }>> {\n\ttry {\n\t\tconst repo = new RelationRepository(db);\n\t\tconst relation = await repo.update(id, input);\n\t\tif (!relation) {\n\t\t\treturn { success: false, error: { code: \"NOT_FOUND\", message: \"Relation not found\" } };\n\t\t}\n\t\treturn { success: true, data: { relation } };\n\t} catch {\n\t\treturn {\n\t\t\tsuccess: false,\n\t\t\terror: { code: \"RELATION_UPDATE_ERROR\", message: \"Failed to update relation\" },\n\t\t};\n\t}\n}\n\n/** A reference field that views a relation, and which end it views it from. */\nexport interface BoundField {\n\tcollectionSlug: string;\n\tfieldSlug: string;\n\tside: \"parent\" | \"child\";\n}\n\n/**\n * Every reference field on the site, grouped by the slug of the relation it\n * binds.\n *\n * Filtered in JS rather than through `json_extract`: `_emdash_fields` holds one\n * row per field on the whole site, and the reference-typed subset of that is\n * small enough that a scan beats a dialect-specific JSON path. Grouping the\n * whole set in one pass also keeps the relations list to a single scan instead\n * of one per row.\n */\nexport async function fieldsBoundByRelation(\n\tdb: Kysely<Database>,\n): Promise<Map<string, BoundField[]>> {\n\tconst rows = await db\n\t\t.selectFrom(\"_emdash_fields\")\n\t\t.innerJoin(\"_emdash_collections\", \"_emdash_collections.id\", \"_emdash_fields.collection_id\")\n\t\t.select([\n\t\t\t\"_emdash_fields.slug as fieldSlug\",\n\t\t\t\"_emdash_collections.slug as collectionSlug\",\n\t\t\t\"_emdash_fields.validation as validation\",\n\t\t])\n\t\t.where(\"_emdash_fields.type\", \"=\", \"reference\")\n\t\t.execute();\n\n\tconst byRelation = new Map<string, BoundField[]>();\n\tfor (const row of rows) {\n\t\tif (!row.validation) continue;\n\t\tlet parsed: unknown;\n\t\ttry {\n\t\t\tparsed = JSON.parse(row.validation);\n\t\t} catch {\n\t\t\tcontinue;\n\t\t}\n\t\tif (!isRecord(parsed) || typeof parsed.relation !== \"string\") continue;\n\t\tconst bound: BoundField = {\n\t\t\tcollectionSlug: row.collectionSlug,\n\t\t\tfieldSlug: row.fieldSlug,\n\t\t\tside: parsed.relationSide === \"child\" ? \"child\" : \"parent\",\n\t\t};\n\t\tconst list = byRelation.get(parsed.relation);\n\t\tif (list) list.push(bound);\n\t\telse byRelation.set(parsed.relation, [bound]);\n\t}\n\treturn byRelation;\n}\n\n/** Every reference field bound to one relation, across both of its ends. */\nexport async function fieldsBoundToRelation(\n\tdb: Kysely<Database>,\n\trelationSlug: string,\n): Promise<BoundField[]> {\n\treturn (await fieldsBoundByRelation(db)).get(relationSlug) ?? [];\n}\n\n/**\n * Delete a relation, the reference fields bound to it, and its edges.\n *\n * A relation is only ever deleted deliberately — from the relations admin page,\n * or by the checkbox on a field delete — and it cannot leave a field pointing at\n * nothing, so the fields go with it either way. Callers show the count first;\n * `deletedFields` reports what actually went.\n *\n * Order matters: fields first, then the relation row and its edges. On D1\n * `withTransaction` degrades to sequential statements, so an interrupted run\n * leaves a relation with fewer bound fields — visible on the relations page and\n * finishable — rather than fields pointing at a relation that no longer exists.\n */\nexport async function handleRelationDelete(\n\tdb: Kysely<Database>,\n\tid: string,\n): Promise<ApiResult<{ deleted: true; deletedFields: string[] }>> {\n\ttry {\n\t\tconst repo = new RelationRepository(db);\n\t\tconst relation = await repo.findById(id);\n\t\tif (!relation) {\n\t\t\treturn { success: false, error: { code: \"NOT_FOUND\", message: \"Relation not found\" } };\n\t\t}\n\n\t\tconst bound = await fieldsBoundToRelation(db, relation.slug);\n\n\t\tconst deleted = await withTransaction(db, async (trx) => {\n\t\t\tconst registry = new SchemaRegistry(trx);\n\t\t\tfor (const field of bound) {\n\t\t\t\tawait registry.deleteField(field.collectionSlug, field.fieldSlug);\n\t\t\t}\n\t\t\treturn new RelationRepository(trx).delete(id);\n\t\t});\n\n\t\tif (!deleted) {\n\t\t\treturn { success: false, error: { code: \"NOT_FOUND\", message: \"Relation not found\" } };\n\t\t}\n\n\t\tfor (const collection of new Set(bound.map((f) => f.collectionSlug))) {\n\t\t\tinvalidateCollectionCache(collection);\n\t\t\tinvalidateSchemaCache(collection);\n\t\t}\n\n\t\treturn {\n\t\t\tsuccess: true,\n\t\t\tdata: {\n\t\t\t\tdeleted: true,\n\t\t\t\tdeletedFields: bound.map((f) => `${f.collectionSlug}.${f.fieldSlug}`),\n\t\t\t},\n\t\t};\n\t} catch (error) {\n\t\tconsole.error(\"Relation delete error:\", error);\n\t\treturn {\n\t\t\tsuccess: false,\n\t\t\terror: { code: \"RELATION_DELETE_ERROR\", message: \"Failed to delete relation\" },\n\t\t};\n\t}\n}\n\nexport type EntryRef = {\n\tid: string;\n\tslug: string | null;\n\tcollection: string;\n\t/**\n\t * Display label sourced from the collection's configured `titleField`, then\n\t * `title`, then `name` — `null` when none is set, leaving the client to fall\n\t * back to slug/id. Mirrors the admin's `getEntryTitle`.\n\t */\n\ttitle: string | null;\n\t/** The actual locale of the resolved variant — see `pickVariant`. */\n\tlocale: string | null;\n\t/**\n\t * The edge's target: the translation group `id` was resolved from. Stable\n\t * across locales, unlike `id`, so callers comparing a ref against a content\n\t * row (the admin's picker) match the entry rather than one of its variants.\n\t */\n\ttranslationGroup: string | null;\n\tsortOrder?: number;\n};\n\n/**\n * Display title for a resolved entry: the collection's configured `titleField`,\n * then `title`, then `name`, else null.\n */\nfunction entryTitle(data: Record<string, unknown>, titleField?: string): string | null {\n\tif (titleField) {\n\t\tconst configured = data[titleField];\n\t\tif (typeof configured === \"string\" && configured.length > 0) return configured;\n\t}\n\tif (typeof data.title === \"string\" && data.title.length > 0) return data.title;\n\tif (typeof data.name === \"string\" && data.name.length > 0) return data.name;\n\treturn null;\n}\n\n/**\n * The collection's configured `titleField`, memoized for the request: a single\n * content read hydrates every reference field, and several of them commonly\n * target the same collection.\n */\nexport async function getReferenceTitleField(\n\tdb: Kysely<Database>,\n\tcollection: string,\n): Promise<string | undefined> {\n\treturn requestCached(`reference-title-field:${collection}`, async () => {\n\t\tconst row = await db\n\t\t\t.selectFrom(\"_emdash_collections\")\n\t\t\t.select(\"title_field\")\n\t\t\t.where(\"slug\", \"=\", collection)\n\t\t\t.executeTakeFirst();\n\t\treturn row?.title_field ?? undefined;\n\t});\n}\n\n/** Resolve a relation from an id OR its slug. */\nasync function resolveRelation(\n\trepo: RelationRepository,\n\tidOrSlug: string,\n): Promise<Relation | null> {\n\treturn (await repo.findById(idOrSlug)) ?? (await repo.findBySlug(idOrSlug));\n}\n\n/**\n * Pick the locale variant matching `locale`, falling back to the first entry\n * (lowest locale code). The fallback is intentional — an edge is keyed by\n * `translation_group`, so a referenced entry that exists only in another locale\n * is still a real reference — but the returned ref carries the variant's actual\n * `locale` so callers never mistake a fallback for the requested locale.\n */\nfunction pickVariant(items: ContentItem[], locale: string | null): ContentItem | undefined {\n\treturn items.find((i) => i.locale === locale) ?? items[0];\n}\n\n/**\n * Resolve edge groups to loadable entries in `collection` at `locale`.\n * Dangling groups (no surviving entry) are skipped — cleanup is a later slice.\n *\n * All groups are loaded in one batched query (chunked at `SQL_BATCH_SIZE`)\n * rather than a `findTranslations` per edge, so a parent with N children costs\n * a constant number of queries, not N+1. Edge order (the caller's `sort_order`)\n * is preserved by iterating `edges`.\n *\n * `includeDrafts` is false for callers without `content:read_drafts`: the load\n * is restricted to published entries so a draft/scheduled entry referenced by an\n * edge is skipped exactly like a dangling one, never leaking its id/slug/locale.\n */\nexport function resolveEntries(\n\tcontent: ContentRepository,\n\tcollection: string,\n\tedges: ContentReference[],\n\tpick: (e: ContentReference) => string,\n\tlocale: string | null,\n\tincludeDrafts: boolean,\n\ttitleField?: string,\n): Promise<EntryRef[]> {\n\treturn resolveGroupSelection(\n\t\tcontent,\n\t\tcollection,\n\t\tedges.map((edge) => ({ group: pick(edge), sortOrder: edge.sortOrder })),\n\t\tlocale,\n\t\tincludeDrafts,\n\t\ttitleField,\n\t);\n}\n\n/**\n * `resolveEntries` for a selection that has no links behind it yet — a pending\n * one staged in a draft revision, which is already a list of translation groups\n * in the order the editor chose. Position stands in for the `sort_order` the\n * links will carry once it is published.\n */\nexport function resolveEntryGroups(\n\tcontent: ContentRepository,\n\tcollection: string,\n\tgroups: string[],\n\tlocale: string | null,\n\tincludeDrafts: boolean,\n\ttitleField?: string,\n): Promise<EntryRef[]> {\n\treturn resolveGroupSelection(\n\t\tcontent,\n\t\tcollection,\n\t\tgroups.map((group, index) => ({ group, sortOrder: index })),\n\t\tlocale,\n\t\tincludeDrafts,\n\t\ttitleField,\n\t);\n}\n\nasync function resolveGroupSelection(\n\tcontent: ContentRepository,\n\tcollection: string,\n\tselection: Array<{ group: string; sortOrder: number }>,\n\tlocale: string | null,\n\tincludeDrafts: boolean,\n\ttitleField?: string,\n): Promise<EntryRef[]> {\n\tconst all = await content.findTranslationsForGroups(\n\t\tcollection,\n\t\tselection.map((entry) => entry.group),\n\t\t{ publishedOnly: !includeDrafts },\n\t);\n\n\t// Group the flat variant list by translation_group so each selected entry can\n\t// pick its own locale variant.\n\tconst variantsByGroup = new Map<string, ContentItem[]>();\n\tfor (const item of all) {\n\t\tif (item.translationGroup == null) continue;\n\t\tconst list = variantsByGroup.get(item.translationGroup);\n\t\tif (list) list.push(item);\n\t\telse variantsByGroup.set(item.translationGroup, [item]);\n\t}\n\n\tconst refs: EntryRef[] = [];\n\tfor (const selected of selection) {\n\t\tconst variants = variantsByGroup.get(selected.group);\n\t\tif (!variants) continue;\n\t\tconst entry = pickVariant(variants, locale);\n\t\tif (!entry) continue;\n\t\trefs.push({\n\t\t\tid: entry.id,\n\t\t\tslug: entry.slug,\n\t\t\tcollection,\n\t\t\ttitle: entryTitle(entry.data, titleField),\n\t\t\tlocale: entry.locale,\n\t\t\ttranslationGroup: entry.translationGroup,\n\t\t\tsortOrder: selected.sortOrder,\n\t\t});\n\t}\n\treturn refs;\n}\n\n/** Pagination inputs for the edge read endpoints. */\nexport type PageOptions = { limit?: number; cursor?: string };\n\n/**\n * The page of a pending selection this end stages, when there is one.\n *\n * These routes address a relation and a side; a staged selection is keyed by the\n * field slug the entry API takes it under, so the field viewing this end is what\n * connects them. Returns undefined when the caller may not see drafts, the entry\n * has no draft, or the draft stages nothing for this field — all of which mean\n * the published links are the answer.\n */\nasync function stagedPageFor(\n\tdb: Kysely<Database>,\n\toptions: {\n\t\tcollection: string;\n\t\trelationSlug: string;\n\t\tside: \"parent\" | \"child\";\n\t\tdraftRevisionId: string | null | undefined;\n\t\tincludeDrafts: boolean;\n\t\tpage: PageOptions;\n\t},\n): Promise<PageOfGroups | undefined> {\n\tif (!options.includeDrafts || !options.draftRevisionId) return undefined;\n\n\tconst field = constraintsForRelationSide(\n\t\tawait referenceFieldConstraints(db, options.collection),\n\t\toptions.relationSlug,\n\t\toptions.side,\n\t);\n\tif (!field) return undefined;\n\n\tconst revision = await new RevisionRepository(db).findById(options.draftRevisionId);\n\tconst groups = readStagedReferences(revision?.data)?.[field.slug];\n\tif (!groups) return undefined;\n\n\treturn pageStagedGroups(groups, options.page);\n}\n\nexport async function handleReferenceChildrenGet(\n\tdb: Kysely<Database>,\n\tcollection: string,\n\tentryId: string,\n\trelation: string,\n\tpage: PageOptions = {},\n\tincludeDrafts = false,\n): Promise<ApiResult<{ children: EntryRef[]; nextCursor?: string }>> {\n\ttry {\n\t\tconst repo = new RelationRepository(db);\n\t\tconst content = new ContentRepository(db);\n\n\t\tconst rel = await resolveRelation(repo, relation);\n\t\tif (!rel)\n\t\t\treturn { success: false, error: { code: \"NOT_FOUND\", message: \"Relation not found\" } };\n\t\tif (collection !== rel.parentCollection) {\n\t\t\treturn {\n\t\t\t\tsuccess: false,\n\t\t\t\terror: {\n\t\t\t\t\tcode: \"VALIDATION_ERROR\",\n\t\t\t\t\tmessage: \"Entry is not the parent side of this relation\",\n\t\t\t\t},\n\t\t\t};\n\t\t}\n\n\t\tconst entry = await content.findByIdOrSlug(collection, entryId);\n\t\t// A caller without draft access must not anchor on a non-published entry —\n\t\t// return NOT_FOUND (not 403) so they can't probe draft ids by status code,\n\t\t// mirroring the single-item content read.\n\t\tif (!entry?.translationGroup || (!includeDrafts && entry.status !== \"published\")) {\n\t\t\treturn { success: false, error: { code: \"NOT_FOUND\", message: \"Content entry not found\" } };\n\t\t}\n\n\t\tconst titleField = await getReferenceTitleField(db, rel.childCollection);\n\n\t\t// A pending selection replaces the published one for a caller that may see\n\t\t// it, page for page — the entry read answers the same way, and a walk that\n\t\t// started on one of them must not continue on the other.\n\t\tconst staged = await stagedPageFor(db, {\n\t\t\tcollection,\n\t\t\trelationSlug: rel.slug,\n\t\t\tside: \"parent\",\n\t\t\tdraftRevisionId: entry.draftRevisionId,\n\t\t\tincludeDrafts,\n\t\t\tpage,\n\t\t});\n\t\tif (staged) {\n\t\t\tconst children = await resolveEntryGroups(\n\t\t\t\tcontent,\n\t\t\t\trel.childCollection,\n\t\t\t\tstaged.groups,\n\t\t\t\tentry.locale,\n\t\t\t\tincludeDrafts,\n\t\t\t\ttitleField,\n\t\t\t);\n\t\t\treturn { success: true, data: { children, nextCursor: staged.nextCursor } };\n\t\t}\n\n\t\tconst edges = await repo.getChildrenPage(rel.id, entry.translationGroup, page);\n\t\tconst children = await resolveEntries(\n\t\t\tcontent,\n\t\t\trel.childCollection,\n\t\t\tedges.items,\n\t\t\t(e) => e.childGroup,\n\t\t\tentry.locale,\n\t\t\tincludeDrafts,\n\t\t\ttitleField,\n\t\t);\n\t\treturn { success: true, data: { children, nextCursor: edges.nextCursor } };\n\t} catch (error) {\n\t\treturn referencesGetError(error);\n\t}\n}\n\n/**\n * A selection expressed in the identifiers the link table actually stores:\n * `translation_group` on both ends, because an edge names a thing rather than\n * one locale's row of it.\n */\nexport interface ReferenceSelectionWrite extends ResolvedReferenceTargets {\n\t/** The selecting entry's own translation group. */\n\tentryGroup: string;\n}\n\n/**\n * The same selection, resolved before the entry it belongs to is known — which\n * is what a create has to do, since its row does not exist until it is written\n * and, on D1, writing it cannot be taken back.\n */\nexport interface ResolvedReferenceTargets {\n\t/** The relation, by id or slug — `setChildren` / `setParents` take either. */\n\trelation: string;\n\t/** The end of the relation the selecting entry sits on. */\n\tside: \"parent\" | \"child\";\n\t/** The selected entries' translation groups, in the caller's order. */\n\tgroups: string[];\n}\n\n/**\n * Resolve a bound field's selection to what the link table stores, without\n * writing anything and without needing the selecting entry to exist.\n *\n * The field decides the relation and the end it views: a field on the `parent`\n * end selects children, one on the `child` end selects the parents pointing at\n * it. `entryGroup` is the selecting entry's own translation group when it has\n * one — the far-side count discounts links it already holds, since replacing a\n * selection with itself adds nothing. A new entry passes `null`: it holds no\n * links yet.\n */\nasync function resolveReferenceTargets(\n\tdb: Kysely<Database>,\n\tcollection: string,\n\tconstraints: ReferenceFieldConstraints,\n\tselectedIds: string[],\n\tentryGroup: string | null,\n): Promise<ApiResult<ResolvedReferenceTargets>> {\n\tconst repo = new RelationRepository(db);\n\tconst content = new ContentRepository(db);\n\tconst side = constraints.relationSide;\n\n\tconst rel = await resolveRelation(repo, constraints.relation);\n\tif (!rel) return { success: false, error: { code: \"NOT_FOUND\", message: \"Relation not found\" } };\n\n\tconst ownCollection = side === \"parent\" ? rel.parentCollection : rel.childCollection;\n\tconst otherCollection = side === \"parent\" ? rel.childCollection : rel.parentCollection;\n\tif (collection !== ownCollection) {\n\t\treturn {\n\t\t\tsuccess: false,\n\t\t\terror: {\n\t\t\t\tcode: \"VALIDATION_ERROR\",\n\t\t\t\tmessage: `Entry is not the ${side} side of this relation`,\n\t\t\t},\n\t\t};\n\t}\n\n\tconst selection = validateReferenceSelection(constraints, selectedIds);\n\tif (!selection.success) return selection;\n\n\t// Resolve every selected entry within the relation's other collection in one\n\t// batch (constant queries, not an N+1 of point lookups for a set up to 1000).\n\t// An id that does not resolve there fails collection-agreement (invariant 3);\n\t// order is preserved by iterating the caller's ids.\n\tconst resolved = await content.findManyByIdOrSlug(otherCollection, selectedIds);\n\tconst groups: string[] = [];\n\tfor (const selectedId of selectedIds) {\n\t\tconst other = resolved.get(selectedId);\n\t\tif (!other?.translationGroup) {\n\t\t\treturn {\n\t\t\t\tsuccess: false,\n\t\t\t\terror: {\n\t\t\t\t\tcode: \"NOT_FOUND\",\n\t\t\t\t\tmessage: `${side === \"parent\" ? \"Child\" : \"Parent\"} entry '${selectedId}' not found in ${otherCollection}`,\n\t\t\t\t},\n\t\t\t};\n\t\t}\n\t\tgroups.push(other.translationGroup);\n\t}\n\n\tconst far = await validateOppositeSideLimit(db, {\n\t\trelationId: rel.id,\n\t\tfarLimit: side === \"parent\" ? rel.maxParentsPerChild : rel.maxChildrenPerParent,\n\t\tside,\n\t\tentryGroup,\n\t\tgroups,\n\t\tlabels: selectedIds,\n\t});\n\tif (!far.success) return far;\n\n\treturn { success: true, data: { relation: rel.id, side, groups } };\n}\n\n/**\n * Check what a selection does to the *other* end's cardinality.\n *\n * Cardinality binds both ends, but only one end ever selects: a field on the\n * parent side that hands a child its second parent breaks `maxParentsPerChild`\n * even though the parent's own limit is untouched. Links the selecting entry\n * already holds are discounted — replacing a selection with itself adds nothing.\n *\n * `labels` names each group the way the caller addressed it, so the message\n * quotes the id someone typed. Publication has only the groups, which it stages;\n * it quotes those.\n */\nexport async function validateOppositeSideLimit(\n\tdb: Kysely<Database>,\n\toptions: {\n\t\trelationId: string;\n\t\t/** The opposite end's limit. `null` is unlimited — nothing to check. */\n\t\tfarLimit: number | null;\n\t\t/** The end the selecting entry sits on. */\n\t\tside: \"parent\" | \"child\";\n\t\tentryGroup: string | null;\n\t\tgroups: string[];\n\t\tlabels?: string[];\n\t},\n): Promise<ApiResult<true>> {\n\tconst { farLimit, side, groups } = options;\n\tif (farLimit === null || groups.length === 0) return { success: true, data: true };\n\n\tconst counts = await new RelationRepository(db).countEdgesByGroup(\n\t\toptions.relationId,\n\t\tside === \"parent\" ? \"child\" : \"parent\",\n\t\tgroups,\n\t\toptions.entryGroup,\n\t);\n\tfor (const [index, group] of groups.entries()) {\n\t\tif ((counts.get(group) ?? 0) + 1 <= farLimit) continue;\n\t\tconst farSide = side === \"parent\" ? \"parent\" : \"child\";\n\t\tconst label = options.labels?.[index] ?? group;\n\t\treturn {\n\t\t\tsuccess: false,\n\t\t\terror: {\n\t\t\t\tcode: \"VALIDATION_ERROR\",\n\t\t\t\tmessage:\n\t\t\t\t\tfarLimit === 1\n\t\t\t\t\t\t? `Entry '${label}' already has a ${farSide} on this relation, which allows one.`\n\t\t\t\t\t\t: `Entry '${label}' already has the maximum of ${farLimit} ${farSide} entries on this relation.`,\n\t\t\t},\n\t\t};\n\t}\n\treturn { success: true, data: true };\n}\n\n/**\n * {@link resolveReferenceTargets} for an entry that already exists, anchoring the\n * selection on that entry's translation group.\n */\nasync function resolveReferenceSide(\n\tdb: Kysely<Database>,\n\tcollection: string,\n\tentryId: string,\n\tconstraints: ReferenceFieldConstraints,\n\tselectedIds: string[],\n): Promise<ApiResult<ReferenceSelectionWrite>> {\n\tconst entry = await new ContentRepository(db).findByIdOrSlug(collection, entryId);\n\tif (!entry?.translationGroup) {\n\t\treturn { success: false, error: { code: \"NOT_FOUND\", message: \"Content entry not found\" } };\n\t}\n\n\tconst resolved = await resolveReferenceTargets(\n\t\tdb,\n\t\tcollection,\n\t\tconstraints,\n\t\tselectedIds,\n\t\tentry.translationGroup,\n\t);\n\tif (!resolved.success) return resolved;\n\treturn { success: true, data: { ...resolved.data, entryGroup: entry.translationGroup } };\n}\n\n/**\n * Replace one end's links from an already-resolved selection.\n *\n * Resolution has already proved the relation, the entry and every selected entry\n * exist, so nothing here fails on the caller's input. What it can still hit is\n * the far end's limit closing between resolving and writing — a slot another\n * request took in that window. The write refuses the edge rather than exceeding\n * the limit, and throws so the save reports it; the throw carries an `apiError`\n * the content handlers map to a response.\n */\nexport async function writeReferenceSelection(\n\tdb: Kysely<Database>,\n\tselection: ReferenceSelectionWrite,\n): Promise<void> {\n\tconst repo = new RelationRepository(db);\n\tconst rel = await resolveRelation(repo, selection.relation);\n\tif (!rel) return;\n\n\tconst rejected =\n\t\tselection.side === \"parent\"\n\t\t\t? await repo.setChildren(rel.id, selection.entryGroup, selection.groups)\n\t\t\t: await repo.setParents(rel.id, selection.entryGroup, selection.groups);\n\tif (rejected.length > 0) {\n\t\tconst farSide = selection.side === \"parent\" ? \"parent\" : \"child\";\n\t\tthrow Object.assign(\n\t\t\tnew Error(\n\t\t\t\t`Entry '${rejected[0]}' already has the maximum number of ${farSide} entries on this relation.`,\n\t\t\t),\n\t\t\t{ apiError: { code: \"VALIDATION_ERROR\" } },\n\t\t);\n\t}\n\n\t// A link is part of what a cached entry renders on both ends — a parent's\n\t// selection and a child's backlinks — while no row of either collection has\n\t// changed. Nothing else here would tell those snapshots they are stale.\n\tinvalidateCollectionCache(rel.parentCollection);\n\tif (rel.childCollection !== rel.parentCollection) {\n\t\tinvalidateCollectionCache(rel.childCollection);\n\t}\n}\n\n/**\n * Replace a reference field's selection on one entry, addressed by field slug.\n *\n * The field decides which relation and which end: a field bound to the parent\n * end replaces that entry's children, one bound to the child end replaces the\n * parents pointing at it. This is what the entry create/update body writes\n * through, so a site addresses a selection the way it addresses any other field.\n */\nexport async function setReferenceSelection(\n\tdb: Kysely<Database>,\n\tcollection: string,\n\tentryId: string,\n\tfieldSlug: string,\n\tselectedIds: string[],\n): Promise<ApiResult<{ relationId: string; entryGroup: string }>> {\n\tconst resolved = await resolveReferenceSelection(db, collection, entryId, fieldSlug, selectedIds);\n\tif (!resolved.success) return resolved;\n\tawait writeReferenceSelection(db, resolved.data);\n\treturn {\n\t\tsuccess: true,\n\t\tdata: { relationId: resolved.data.relation, entryGroup: resolved.data.entryGroup },\n\t};\n}\n\n/**\n * `setReferenceSelection` up to but not including the write.\n *\n * A collection that keeps drafts stages the result in its draft revision instead\n * of writing links, so a save reports a bad id or an over-long selection exactly\n * as a direct write would, and publication has nothing left to resolve.\n */\nexport async function resolveReferenceSelection(\n\tdb: Kysely<Database>,\n\tcollection: string,\n\tentryId: string,\n\tfieldSlug: string,\n\tselectedIds: string[],\n): Promise<ApiResult<ReferenceSelectionWrite>> {\n\tconst constraints = (await referenceFieldConstraints(db, collection)).get(fieldSlug);\n\tif (!constraints) return notAReferenceField(fieldSlug, collection);\n\treturn resolveReferenceSide(db, collection, entryId, constraints, selectedIds);\n}\n\n/**\n * `resolveReferenceSelection` for an entry that does not exist yet.\n *\n * A create resolves its whole payload before it writes its row, because on D1\n * that row is committed the moment it is written: a selection that cannot be\n * resolved has to be refused while there is still nothing to take back.\n *\n * `entryGroup` is the group the new row will join — a new translation inherits\n * the source's — or null when the row starts a group of its own and so holds no\n * links yet.\n */\nexport async function resolveReferenceSelectionTargets(\n\tdb: Kysely<Database>,\n\tcollection: string,\n\tfieldSlug: string,\n\tselectedIds: string[],\n\tentryGroup: string | null,\n): Promise<ApiResult<ResolvedReferenceTargets>> {\n\tconst constraints = (await referenceFieldConstraints(db, collection)).get(fieldSlug);\n\tif (!constraints) return notAReferenceField(fieldSlug, collection);\n\treturn resolveReferenceTargets(db, collection, constraints, selectedIds, entryGroup);\n}\n\nfunction notAReferenceField(fieldSlug: string, collection: string): ApiResult<never> {\n\treturn {\n\t\tsuccess: false,\n\t\terror: {\n\t\t\tcode: \"VALIDATION_ERROR\",\n\t\t\tmessage: `Field '${fieldSlug}' is not a reference field on ${collection}`,\n\t\t},\n\t};\n}\n\nexport async function handleReferenceParentsGet(\n\tdb: Kysely<Database>,\n\tcollection: string,\n\tentryId: string,\n\trelation: string,\n\tpage: PageOptions = {},\n\tincludeDrafts = false,\n): Promise<ApiResult<{ parents: EntryRef[]; nextCursor?: string }>> {\n\ttry {\n\t\tconst repo = new RelationRepository(db);\n\t\tconst content = new ContentRepository(db);\n\n\t\tconst rel = await resolveRelation(repo, relation);\n\t\tif (!rel)\n\t\t\treturn { success: false, error: { code: \"NOT_FOUND\", message: \"Relation not found\" } };\n\t\tif (collection !== rel.childCollection) {\n\t\t\treturn {\n\t\t\t\tsuccess: false,\n\t\t\t\terror: {\n\t\t\t\t\tcode: \"VALIDATION_ERROR\",\n\t\t\t\t\tmessage: \"Entry is not the child side of this relation\",\n\t\t\t\t},\n\t\t\t};\n\t\t}\n\n\t\tconst entry = await content.findByIdOrSlug(collection, entryId);\n\t\t// Same draft-anchor guard as the children read: a non-draft-reader anchoring\n\t\t// on an unpublished entry gets NOT_FOUND, not its backlinks.\n\t\tif (!entry?.translationGroup || (!includeDrafts && entry.status !== \"published\")) {\n\t\t\treturn { success: false, error: { code: \"NOT_FOUND\", message: \"Content entry not found\" } };\n\t\t}\n\n\t\tconst titleField = await getReferenceTitleField(db, rel.parentCollection);\n\n\t\t// As on the children read: a field bound to this end stages its pending\n\t\t// selection in the entry's draft, and that is what a drafts-aware caller\n\t\t// pages through.\n\t\tconst staged = await stagedPageFor(db, {\n\t\t\tcollection,\n\t\t\trelationSlug: rel.slug,\n\t\t\tside: \"child\",\n\t\t\tdraftRevisionId: entry.draftRevisionId,\n\t\t\tincludeDrafts,\n\t\t\tpage,\n\t\t});\n\t\tif (staged) {\n\t\t\tconst parents = await resolveEntryGroups(\n\t\t\t\tcontent,\n\t\t\t\trel.parentCollection,\n\t\t\t\tstaged.groups,\n\t\t\t\tentry.locale,\n\t\t\t\tincludeDrafts,\n\t\t\t\ttitleField,\n\t\t\t);\n\t\t\treturn { success: true, data: { parents, nextCursor: staged.nextCursor } };\n\t\t}\n\n\t\tconst edges = await repo.getParentsPage(rel.id, entry.translationGroup, page);\n\t\tconst parents = await resolveEntries(\n\t\t\tcontent,\n\t\t\trel.parentCollection,\n\t\t\tedges.items,\n\t\t\t(e) => e.parentGroup,\n\t\t\tentry.locale,\n\t\t\tincludeDrafts,\n\t\t\ttitleField,\n\t\t);\n\t\treturn { success: true, data: { parents, nextCursor: edges.nextCursor } };\n\t} catch (error) {\n\t\treturn referencesGetError(error);\n\t}\n}\n"],"mappings":"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"}
@@ -1,141 +0,0 @@
1
- import { n as normalizeTrustedHeaders, t as getTrustedProxyHeaders } from "./trusted-proxy-C0eHXPd-.mjs";
2
-
3
- //#region src/plugins/request-meta.ts
4
- /**
5
- * Loose validation for IPv4 and IPv6 addresses.
6
- * Accepts digits, hex chars, dots, and colons — rejects anything else
7
- * (e.g. HTML tags, scripts, or other non-IP garbage in spoofed headers).
8
- */
9
- const IP_PATTERN = /^[\da-fA-F.:]+$/;
10
- /**
11
- * Extract the first IP from an X-Forwarded-For header value.
12
- * The header may contain a comma-separated list of IPs; the first
13
- * entry is the original client IP.
14
- *
15
- * Returns null if the extracted value doesn't look like an IP address.
16
- */
17
- function parseFirstForwardedIp(header) {
18
- const trimmed = header.split(",")[0]?.trim();
19
- if (!trimmed) return null;
20
- return IP_PATTERN.test(trimmed) ? trimmed : null;
21
- }
22
- /**
23
- * Read an IP from an operator-declared trusted header. XFF-style headers
24
- * (any name ending in `forwarded-for`) are parsed as comma-separated lists
25
- * and the first entry is used; everything else is treated as a single
26
- * trimmed value.
27
- */
28
- function readIpFromHeader(headers, name) {
29
- const value = headers.get(name);
30
- if (!value) return null;
31
- if (name.endsWith("forwarded-for")) return parseFirstForwardedIp(value);
32
- const trimmed = value.trim();
33
- if (!trimmed) return null;
34
- return IP_PATTERN.test(trimmed) ? trimmed : null;
35
- }
36
- /**
37
- * Get the Cloudflare `cf` object from the request, if present.
38
- * Returns undefined when not running on Cloudflare Workers.
39
- */
40
- function getCfObject(request) {
41
- return request.cf;
42
- }
43
- /**
44
- * Extract geographic information from the Cloudflare `cf` object
45
- * attached to the request. Returns null when not running on CF Workers.
46
- */
47
- function extractGeo(cf) {
48
- if (!cf) return null;
49
- const country = cf.country ?? null;
50
- const region = cf.region ?? null;
51
- const city = cf.city ?? null;
52
- if (country === null && region === null && city === null) return null;
53
- return {
54
- country,
55
- region,
56
- city
57
- };
58
- }
59
- /**
60
- * Extract normalized request metadata from a Request object.
61
- *
62
- * IP resolution order:
63
- * 1. `CF-Connecting-IP` — trusted only when a `cf` object is present on the
64
- * request. CF edge overwrites any client-supplied value, so this is the
65
- * cryptographically trustworthy path on Workers. Operator-declared
66
- * trusted headers cannot override it.
67
- * 2. `X-Forwarded-For` first entry — trusted only with a `cf` object.
68
- * 3. Operator-declared trusted proxy headers (from `config.trustedProxyHeaders`
69
- * or the `EMDASH_TRUSTED_PROXY_HEADERS` env var), tried in order. Used as
70
- * the primary source off-CF and as a fill-in on CF.
71
- * 4. `null`
72
- *
73
- * The second argument accepts either the EmDash config or a pre-resolved
74
- * list of trusted headers, so callers that already have the list don't have
75
- * to round-trip through the config every request.
76
- */
77
- function extractRequestMeta(request, configOrTrustedHeaders) {
78
- const headers = request.headers;
79
- const cf = getCfObject(request);
80
- const trusted = resolveTrustedHeaders(configOrTrustedHeaders);
81
- let ip = null;
82
- if (cf) {
83
- const cfIp = headers.get("cf-connecting-ip")?.trim();
84
- if (cfIp && IP_PATTERN.test(cfIp)) ip = cfIp;
85
- if (!ip) {
86
- const xff = headers.get("x-forwarded-for");
87
- ip = xff ? parseFirstForwardedIp(xff) : null;
88
- }
89
- }
90
- if (!ip) for (const name of trusted) {
91
- const value = readIpFromHeader(headers, name);
92
- if (value) {
93
- ip = value;
94
- break;
95
- }
96
- }
97
- const userAgent = headers.get("user-agent")?.trim() || null;
98
- const referer = headers.get("referer")?.trim() || null;
99
- const geo = extractGeo(cf);
100
- return {
101
- ip,
102
- userAgent,
103
- referer,
104
- geo
105
- };
106
- }
107
- function resolveTrustedHeaders(value) {
108
- if (Array.isArray(value)) return normalizeTrustedHeaders(value);
109
- return getTrustedProxyHeaders(value);
110
- }
111
- /**
112
- * Headers that must never cross the RPC boundary to sandboxed plugins.
113
- * Session tokens, auth credentials, and infrastructure headers are stripped
114
- * to prevent malicious plugins from exfiltrating sensitive data.
115
- */
116
- const SANDBOX_STRIPPED_HEADERS = new Set([
117
- "cookie",
118
- "set-cookie",
119
- "authorization",
120
- "proxy-authorization",
121
- "cf-access-jwt-assertion",
122
- "cf-access-client-id",
123
- "cf-access-client-secret",
124
- "x-emdash-request"
125
- ]);
126
- /**
127
- * Copy request headers into a plain object, stripping sensitive headers
128
- * that must not be exposed to sandboxed plugin code.
129
- */
130
- function sanitizeHeadersForSandbox(headers, allowedHeaders) {
131
- const safe = {};
132
- const allowed = allowedHeaders ? new Set(allowedHeaders.map((header) => header.toLowerCase())) : null;
133
- headers.forEach((value, key) => {
134
- if (!SANDBOX_STRIPPED_HEADERS.has(key) && !key.startsWith("cf-access-") && (allowed === null || allowed.has(key))) safe[key] = value;
135
- });
136
- return safe;
137
- }
138
-
139
- //#endregion
140
- export { sanitizeHeadersForSandbox as n, extractRequestMeta as t };
141
- //# sourceMappingURL=request-meta-Bs60XW1m.mjs.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"request-meta-Bs60XW1m.mjs","names":[],"sources":["../src/plugins/request-meta.ts"],"sourcesContent":["/**\n * Request Metadata Extraction\n *\n * Extracts normalized metadata (IP, user agent, referer, geo) from\n * incoming requests. Used by plugin route handlers to access request\n * context without touching raw headers.\n *\n */\n\nimport type { EmDashConfig } from \"../astro/integration/runtime.js\";\nimport { getTrustedProxyHeaders, normalizeTrustedHeaders } from \"../auth/trusted-proxy.js\";\nimport type { GeoInfo, RequestMeta } from \"./types.js\";\n\n/**\n * Cloudflare Workers `cf` object shape (subset we use).\n * Present on requests when running on Cloudflare Workers.\n */\ninterface CfProperties {\n\tcountry?: string;\n\tregion?: string;\n\tcity?: string;\n}\n\n/**\n * Loose validation for IPv4 and IPv6 addresses.\n * Accepts digits, hex chars, dots, and colons — rejects anything else\n * (e.g. HTML tags, scripts, or other non-IP garbage in spoofed headers).\n */\nconst IP_PATTERN = /^[\\da-fA-F.:]+$/;\n\n/**\n * Extract the first IP from an X-Forwarded-For header value.\n * The header may contain a comma-separated list of IPs; the first\n * entry is the original client IP.\n *\n * Returns null if the extracted value doesn't look like an IP address.\n */\nfunction parseFirstForwardedIp(header: string): string | null {\n\tconst first = header.split(\",\")[0];\n\tconst trimmed = first?.trim();\n\tif (!trimmed) return null;\n\treturn IP_PATTERN.test(trimmed) ? trimmed : null;\n}\n\n/**\n * Read an IP from an operator-declared trusted header. XFF-style headers\n * (any name ending in `forwarded-for`) are parsed as comma-separated lists\n * and the first entry is used; everything else is treated as a single\n * trimmed value.\n */\nfunction readIpFromHeader(headers: Headers, name: string): string | null {\n\tconst value = headers.get(name);\n\tif (!value) return null;\n\tif (name.endsWith(\"forwarded-for\")) {\n\t\treturn parseFirstForwardedIp(value);\n\t}\n\tconst trimmed = value.trim();\n\tif (!trimmed) return null;\n\treturn IP_PATTERN.test(trimmed) ? trimmed : null;\n}\n\n/**\n * Get the Cloudflare `cf` object from the request, if present.\n * Returns undefined when not running on Cloudflare Workers.\n */\nfunction getCfObject(request: Request): CfProperties | undefined {\n\treturn (request as unknown as { cf?: CfProperties }).cf;\n}\n\n/**\n * Extract geographic information from the Cloudflare `cf` object\n * attached to the request. Returns null when not running on CF Workers.\n */\nfunction extractGeo(cf: CfProperties | undefined): GeoInfo | null {\n\tif (!cf) return null;\n\n\tconst country = cf.country ?? null;\n\tconst region = cf.region ?? null;\n\tconst city = cf.city ?? null;\n\n\t// Only return geo if at least one field is populated\n\tif (country === null && region === null && city === null) return null;\n\n\treturn { country, region, city };\n}\n\n/**\n * Extract normalized request metadata from a Request object.\n *\n * IP resolution order:\n * 1. `CF-Connecting-IP` — trusted only when a `cf` object is present on the\n * request. 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 with a `cf` object.\n * 3. Operator-declared trusted proxy headers (from `config.trustedProxyHeaders`\n * or the `EMDASH_TRUSTED_PROXY_HEADERS` env var), tried in order. Used as\n * the primary source off-CF and as a fill-in on CF.\n * 4. `null`\n *\n * The second argument accepts either the EmDash config or a pre-resolved\n * list of trusted headers, so callers that already have the list don't have\n * to round-trip through the config every request.\n */\nexport function extractRequestMeta(\n\trequest: Request,\n\tconfigOrTrustedHeaders?: EmDashConfig | null | { trustedProxyHeaders?: string[] } | string[],\n): RequestMeta {\n\tconst headers = request.headers;\n\tconst cf = getCfObject(request);\n\tconst trusted = resolveTrustedHeaders(configOrTrustedHeaders);\n\n\tlet ip: string | null = null;\n\n\t// On Cloudflare, prefer the cryptographically trustworthy headers first.\n\tif (cf) {\n\t\tconst cfIp = headers.get(\"cf-connecting-ip\")?.trim();\n\t\tif (cfIp && IP_PATTERN.test(cfIp)) {\n\t\t\tip = cfIp;\n\t\t}\n\t\tif (!ip) {\n\t\t\tconst xff = headers.get(\"x-forwarded-for\");\n\t\t\tip = xff ? parseFirstForwardedIp(xff) : null;\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\tif (!ip) {\n\t\tfor (const name of trusted) {\n\t\t\tconst value = readIpFromHeader(headers, name);\n\t\t\tif (value) {\n\t\t\t\tip = value;\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\t}\n\n\tconst userAgent = headers.get(\"user-agent\")?.trim() || null;\n\tconst referer = headers.get(\"referer\")?.trim() || null;\n\tconst geo = extractGeo(cf);\n\n\treturn { ip, userAgent, referer, geo };\n}\n\nfunction resolveTrustedHeaders(\n\tvalue: EmDashConfig | null | { trustedProxyHeaders?: string[] } | string[] | undefined,\n): string[] {\n\tif (Array.isArray(value)) {\n\t\t// Apply the same RFC 7230 validation the config/env path does so a\n\t\t// caller passing a pre-resolved list with bad entries can't crash\n\t\t// `Headers.get()` downstream.\n\t\treturn normalizeTrustedHeaders(value);\n\t}\n\treturn getTrustedProxyHeaders(value);\n}\n\n// =============================================================================\n// Header Sanitization for Sandbox\n// =============================================================================\n\n/**\n * Headers that must never cross the RPC boundary to sandboxed plugins.\n * Session tokens, auth credentials, and infrastructure headers are stripped\n * to prevent malicious plugins from exfiltrating sensitive data.\n */\nconst SANDBOX_STRIPPED_HEADERS = new Set([\n\t\"cookie\",\n\t\"set-cookie\",\n\t\"authorization\",\n\t\"proxy-authorization\",\n\t\"cf-access-jwt-assertion\",\n\t\"cf-access-client-id\",\n\t\"cf-access-client-secret\",\n\t\"x-emdash-request\",\n]);\n\n/**\n * Copy request headers into a plain object, stripping sensitive headers\n * that must not be exposed to sandboxed plugin code.\n */\nexport function sanitizeHeadersForSandbox(\n\theaders: Headers,\n\tallowedHeaders?: readonly string[],\n): Record<string, string> {\n\tconst safe: Record<string, string> = {};\n\tconst allowed = allowedHeaders\n\t\t? new Set(allowedHeaders.map((header) => header.toLowerCase()))\n\t\t: null;\n\theaders.forEach((value, key) => {\n\t\tif (\n\t\t\t!SANDBOX_STRIPPED_HEADERS.has(key) &&\n\t\t\t!key.startsWith(\"cf-access-\") &&\n\t\t\t(allowed === null || allowed.has(key))\n\t\t) {\n\t\t\tsafe[key] = value;\n\t\t}\n\t});\n\treturn safe;\n}\n"],"mappings":";;;;;;;;AA4BA,MAAM,aAAa;;;;;;;;AASnB,SAAS,sBAAsB,QAA+B;CAE7D,MAAM,UADQ,OAAO,MAAM,IAAI,CAAC,IACT,MAAM;AAC7B,KAAI,CAAC,QAAS,QAAO;AACrB,QAAO,WAAW,KAAK,QAAQ,GAAG,UAAU;;;;;;;;AAS7C,SAAS,iBAAiB,SAAkB,MAA6B;CACxE,MAAM,QAAQ,QAAQ,IAAI,KAAK;AAC/B,KAAI,CAAC,MAAO,QAAO;AACnB,KAAI,KAAK,SAAS,gBAAgB,CACjC,QAAO,sBAAsB,MAAM;CAEpC,MAAM,UAAU,MAAM,MAAM;AAC5B,KAAI,CAAC,QAAS,QAAO;AACrB,QAAO,WAAW,KAAK,QAAQ,GAAG,UAAU;;;;;;AAO7C,SAAS,YAAY,SAA4C;AAChE,QAAQ,QAA6C;;;;;;AAOtD,SAAS,WAAW,IAA8C;AACjE,KAAI,CAAC,GAAI,QAAO;CAEhB,MAAM,UAAU,GAAG,WAAW;CAC9B,MAAM,SAAS,GAAG,UAAU;CAC5B,MAAM,OAAO,GAAG,QAAQ;AAGxB,KAAI,YAAY,QAAQ,WAAW,QAAQ,SAAS,KAAM,QAAO;AAEjE,QAAO;EAAE;EAAS;EAAQ;EAAM;;;;;;;;;;;;;;;;;;;;AAqBjC,SAAgB,mBACf,SACA,wBACc;CACd,MAAM,UAAU,QAAQ;CACxB,MAAM,KAAK,YAAY,QAAQ;CAC/B,MAAM,UAAU,sBAAsB,uBAAuB;CAE7D,IAAI,KAAoB;AAGxB,KAAI,IAAI;EACP,MAAM,OAAO,QAAQ,IAAI,mBAAmB,EAAE,MAAM;AACpD,MAAI,QAAQ,WAAW,KAAK,KAAK,CAChC,MAAK;AAEN,MAAI,CAAC,IAAI;GACR,MAAM,MAAM,QAAQ,IAAI,kBAAkB;AAC1C,QAAK,MAAM,sBAAsB,IAAI,GAAG;;;AAM1C,KAAI,CAAC,GACJ,MAAK,MAAM,QAAQ,SAAS;EAC3B,MAAM,QAAQ,iBAAiB,SAAS,KAAK;AAC7C,MAAI,OAAO;AACV,QAAK;AACL;;;CAKH,MAAM,YAAY,QAAQ,IAAI,aAAa,EAAE,MAAM,IAAI;CACvD,MAAM,UAAU,QAAQ,IAAI,UAAU,EAAE,MAAM,IAAI;CAClD,MAAM,MAAM,WAAW,GAAG;AAE1B,QAAO;EAAE;EAAI;EAAW;EAAS;EAAK;;AAGvC,SAAS,sBACR,OACW;AACX,KAAI,MAAM,QAAQ,MAAM,CAIvB,QAAO,wBAAwB,MAAM;AAEtC,QAAO,uBAAuB,MAAM;;;;;;;AAYrC,MAAM,2BAA2B,IAAI,IAAI;CACxC;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA,CAAC;;;;;AAMF,SAAgB,0BACf,SACA,gBACyB;CACzB,MAAM,OAA+B,EAAE;CACvC,MAAM,UAAU,iBACb,IAAI,IAAI,eAAe,KAAK,WAAW,OAAO,aAAa,CAAC,CAAC,GAC7D;AACH,SAAQ,SAAS,OAAO,QAAQ;AAC/B,MACC,CAAC,yBAAyB,IAAI,IAAI,IAClC,CAAC,IAAI,WAAW,aAAa,KAC5B,YAAY,QAAQ,QAAQ,IAAI,IAAI,EAErC,MAAK,OAAO;GAEZ;AACF,QAAO"}
@@ -1,100 +0,0 @@
1
- import "./dialect-helpers-7_IqPdh9.mjs";
2
- import { i as isI18nEnabled, n as getFallbackChain } from "./config-CvmjJcVw.mjs";
3
- import "./datetime-normalization-PeiEdcRY.mjs";
4
- import "./after-PcEvMY_6.mjs";
5
- import "./base64-DvnNgP7e.mjs";
6
- import "./object-cache-Bo6DGaC9.mjs";
7
- import "./request-cache-C4CIo5ad.mjs";
8
- import "./url-Dn3IStq8.mjs";
9
- import "./types-j6MBDjlZ.mjs";
10
- import { t as RevisionRepository } from "./revision-CGkQA0e5.mjs";
11
- import { d as RelationRepository, l as readStagedReferences, n as REFERENCE_PAGE_MAX_LIMIT, s as pageStagedGroups, t as REFERENCE_PAGE_LIMIT } from "./staged-Bw5eHbKS.mjs";
12
- import { c as loadEntriesByGroups, s as getDb } from "./loader-D4edocWH.mjs";
13
- import { n as getReferenceFieldMap } from "./field-map-D7ioN0r0.mjs";
14
-
15
- //#region src/references/resolve.ts
16
- /**
17
- * Resolve an entry's reference selections to loadable entries, for the public
18
- * query path.
19
- *
20
- * The cost is bounded and predictable: one link read per selected field, then
21
- * one entry read per *distinct* target collection — never one per link. A
22
- * caller that selects no fields issues nothing at all, which is what keeps
23
- * references off the logged-out hot path of every render that does not ask for
24
- * them.
25
- */
26
- function pageOptions(query) {
27
- if (query === true) return { limit: REFERENCE_PAGE_LIMIT };
28
- const requested = query.limit ?? REFERENCE_PAGE_LIMIT;
29
- return {
30
- limit: Math.min(Math.max(requested, 1), REFERENCE_PAGE_MAX_LIMIT),
31
- cursor: query.cursor
32
- };
33
- }
34
- function localeChainFor(locale) {
35
- if (locale === null) return [];
36
- return isI18nEnabled() ? getFallbackChain(locale) : [locale];
37
- }
38
- async function resolveReferencePages(options) {
39
- const fieldMap = await getReferenceFieldMap(options.collection);
40
- const requested = Object.entries(options.selection).filter((entry) => entry[1] !== void 0 && fieldMap.has(entry[0]));
41
- if (requested.length === 0) return {};
42
- const db = await getDb();
43
- const relations = new RelationRepository(db);
44
- const staged = options.serveDrafts && options.draftRevisionId ? readStagedReferences((await new RevisionRepository(db).findById(options.draftRevisionId))?.data) : void 0;
45
- const pages = new Map(await Promise.all(requested.map(async ([slug, query]) => {
46
- const binding = fieldMap.get(slug);
47
- const page = pageOptions(query);
48
- const stagedGroups = staged?.[slug];
49
- if (stagedGroups) return [slug, pageStagedGroups(stagedGroups, page)];
50
- const links = binding.side === "child" ? await relations.getParentsPageById(binding.relationId, options.entryGroup, page) : await relations.getChildrenPageById(binding.relationId, options.entryGroup, page);
51
- return [slug, {
52
- groups: links.items.map((link) => binding.side === "child" ? link.parentGroup : link.childGroup),
53
- nextCursor: links.nextCursor
54
- }];
55
- })));
56
- const groupsByCollection = /* @__PURE__ */ new Map();
57
- for (const [slug, page] of pages) {
58
- const target = fieldMap.get(slug).targetCollection;
59
- const groups = groupsByCollection.get(target) ?? /* @__PURE__ */ new Set();
60
- for (const group of page.groups) groups.add(group);
61
- groupsByCollection.set(target, groups);
62
- }
63
- const localeChain = localeChainFor(options.locale);
64
- const variantsByCollection = /* @__PURE__ */ new Map();
65
- await Promise.all(Array.from(groupsByCollection, async ([collection, groups]) => {
66
- const loaded = await loadEntriesByGroups(collection, [...groups], {
67
- publishedOnly: !options.serveDrafts,
68
- localeChain
69
- });
70
- const byGroup = /* @__PURE__ */ new Map();
71
- for (const entry of loaded) {
72
- const group = entry.data.translationGroup;
73
- if (typeof group === "string") byGroup.set(group, entry);
74
- }
75
- variantsByCollection.set(collection, byGroup);
76
- }));
77
- const resolved = {};
78
- for (const [slug, page] of pages) {
79
- const collection = fieldMap.get(slug).targetCollection;
80
- const byGroup = variantsByCollection.get(collection);
81
- const entries = [];
82
- for (const group of page.groups) {
83
- const variant = byGroup?.get(group);
84
- if (variant) entries.push(variant);
85
- }
86
- resolved[slug] = page.nextCursor ? {
87
- collection,
88
- entries,
89
- nextCursor: page.nextCursor
90
- } : {
91
- collection,
92
- entries
93
- };
94
- }
95
- return resolved;
96
- }
97
-
98
- //#endregion
99
- export { resolveReferencePages };
100
- //# sourceMappingURL=resolve-BHWgMU_X.mjs.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"resolve-BHWgMU_X.mjs","names":[],"sources":["../src/references/resolve.ts"],"sourcesContent":["/**\n * Resolve an entry's reference selections to loadable entries, for the public\n * query path.\n *\n * The cost is bounded and predictable: one link read per selected field, then\n * one entry read per *distinct* target collection — never one per link. A\n * caller that selects no fields issues nothing at all, which is what keeps\n * references off the logged-out hot path of every render that does not ask for\n * them.\n */\n\nimport { RelationRepository } from \"../database/repositories/relation.js\";\nimport { RevisionRepository } from \"../database/repositories/revision.js\";\nimport { getFallbackChain, isI18nEnabled } from \"../i18n/config.js\";\nimport { getDb, loadEntriesByGroups, type LoadedEntry } from \"../loader.js\";\nimport { getReferenceFieldMap } from \"./field-map.js\";\nimport {\n\tpageStagedGroups,\n\treadStagedReferences,\n\tREFERENCE_PAGE_LIMIT,\n\tREFERENCE_PAGE_MAX_LIMIT,\n\ttype PageOfGroups,\n} from \"./staged.js\";\nimport type { ReferenceQuery, ReferenceSelection } from \"./types.js\";\n\n/** One reference field's resolved page, before the query layer wraps the entries. */\nexport interface ResolvedReferencePage {\n\t/** The collection the entries belong to — what the `edit` proxy is scoped to. */\n\tcollection: string;\n\tentries: LoadedEntry[];\n\tnextCursor?: string;\n}\n\nexport interface ResolveReferencesOptions {\n\t/** The collection the selecting entry belongs to. */\n\tcollection: string;\n\t/** The selecting entry's own translation group. */\n\tentryGroup: string;\n\t/** The locale the parent resolved to, used to pick each target's variant. */\n\tlocale: string | null;\n\t/** The selecting entry's draft revision, when it has one. */\n\tdraftRevisionId?: string;\n\t/**\n\t * Whether this render may see unpublished content. It decides both halves of\n\t * draft visibility: whether a pending selection staged in the draft revision\n\t * replaces the published one, and whether an unpublished target resolves at\n\t * all.\n\t */\n\tserveDrafts: boolean;\n\t/** The fields to resolve, by field slug. */\n\tselection: ReferenceSelection;\n}\n\nfunction pageOptions(query: ReferenceQuery): { limit: number; cursor?: string } {\n\tif (query === true) return { limit: REFERENCE_PAGE_LIMIT };\n\tconst requested = query.limit ?? REFERENCE_PAGE_LIMIT;\n\treturn {\n\t\tlimit: Math.min(Math.max(requested, 1), REFERENCE_PAGE_MAX_LIMIT),\n\t\tcursor: query.cursor,\n\t};\n}\n\nfunction localeChainFor(locale: string | null): string[] {\n\tif (locale === null) return [];\n\treturn isI18nEnabled() ? getFallbackChain(locale) : [locale];\n}\n\nexport async function resolveReferencePages(\n\toptions: ResolveReferencesOptions,\n): Promise<Record<string, ResolvedReferencePage>> {\n\tconst fieldMap = await getReferenceFieldMap(options.collection);\n\tconst requested = Object.entries(options.selection).filter(\n\t\t(entry): entry is [string, ReferenceQuery] => entry[1] !== undefined && fieldMap.has(entry[0]),\n\t);\n\tif (requested.length === 0) return {};\n\n\tconst db = await getDb();\n\tconst relations = new RelationRepository(db);\n\n\tconst staged =\n\t\toptions.serveDrafts && options.draftRevisionId\n\t\t\t? readStagedReferences(\n\t\t\t\t\t(await new RevisionRepository(db).findById(options.draftRevisionId))?.data,\n\t\t\t\t)\n\t\t\t: undefined;\n\n\t// Phase one: each field's page of translation groups, in selection order.\n\t// Concurrent, like phase two — the fields are independent, and awaiting them\n\t// in turn would make N fields N sequential round trips.\n\tconst pages = new Map(\n\t\tawait Promise.all(\n\t\t\trequested.map(async ([slug, query]): Promise<[string, PageOfGroups]> => {\n\t\t\t\tconst binding = fieldMap.get(slug)!;\n\t\t\t\tconst page = pageOptions(query);\n\n\t\t\t\tconst stagedGroups = staged?.[slug];\n\t\t\t\tif (stagedGroups) return [slug, pageStagedGroups(stagedGroups, page)];\n\n\t\t\t\tconst links =\n\t\t\t\t\tbinding.side === \"child\"\n\t\t\t\t\t\t? await relations.getParentsPageById(binding.relationId, options.entryGroup, page)\n\t\t\t\t\t\t: await relations.getChildrenPageById(binding.relationId, options.entryGroup, page);\n\t\t\t\treturn [\n\t\t\t\t\tslug,\n\t\t\t\t\t{\n\t\t\t\t\t\tgroups: links.items.map((link) =>\n\t\t\t\t\t\t\tbinding.side === \"child\" ? link.parentGroup : link.childGroup,\n\t\t\t\t\t\t),\n\t\t\t\t\t\tnextCursor: links.nextCursor,\n\t\t\t\t\t},\n\t\t\t\t];\n\t\t\t}),\n\t\t),\n\t);\n\n\t// Phase two: one entry read per distinct target collection, however many\n\t// fields point at it.\n\tconst groupsByCollection = new Map<string, Set<string>>();\n\tfor (const [slug, page] of pages) {\n\t\tconst target = fieldMap.get(slug)!.targetCollection;\n\t\tconst groups = groupsByCollection.get(target) ?? new Set<string>();\n\t\tfor (const group of page.groups) groups.add(group);\n\t\tgroupsByCollection.set(target, groups);\n\t}\n\n\tconst localeChain = localeChainFor(options.locale);\n\tconst variantsByCollection = new Map<string, Map<string, LoadedEntry>>();\n\tawait Promise.all(\n\t\tArray.from(groupsByCollection, async ([collection, groups]) => {\n\t\t\tconst loaded = await loadEntriesByGroups(collection, [...groups], {\n\t\t\t\tpublishedOnly: !options.serveDrafts,\n\t\t\t\tlocaleChain,\n\t\t\t});\n\t\t\tconst byGroup = new Map<string, LoadedEntry>();\n\t\t\tfor (const entry of loaded) {\n\t\t\t\tconst group = entry.data.translationGroup;\n\t\t\t\tif (typeof group === \"string\") byGroup.set(group, entry);\n\t\t\t}\n\t\t\tvariantsByCollection.set(collection, byGroup);\n\t\t}),\n\t);\n\n\t// Phase three: rebuild each field in link order. A group with no surviving\n\t// variant — deleted, or unpublished for a render that may not see drafts —\n\t// drops out, exactly as a dangling link does.\n\tconst resolved: Record<string, ResolvedReferencePage> = {};\n\tfor (const [slug, page] of pages) {\n\t\tconst collection = fieldMap.get(slug)!.targetCollection;\n\t\tconst byGroup = variantsByCollection.get(collection);\n\t\tconst entries: LoadedEntry[] = [];\n\t\tfor (const group of page.groups) {\n\t\t\tconst variant = byGroup?.get(group);\n\t\t\tif (variant) entries.push(variant);\n\t\t}\n\t\tresolved[slug] = page.nextCursor\n\t\t\t? { collection, entries, nextCursor: page.nextCursor }\n\t\t\t: { collection, entries };\n\t}\n\treturn resolved;\n}\n"],"mappings":"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"}