emdash 0.21.0 → 0.23.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 (655) hide show
  1. package/dist/{adapters-BxSmgtbF.d.mts → adapters-DAAjOID4.d.mts} +1 -1
  2. package/dist/{adapters-BxSmgtbF.d.mts.map → adapters-DAAjOID4.d.mts.map} +1 -1
  3. package/dist/after-B1IIdH3Y.mjs +29 -0
  4. package/dist/after-B1IIdH3Y.mjs.map +1 -0
  5. package/dist/{allowed-origins-BqC8cul8.mjs → allowed-origins-D5FxMUo8.mjs} +2 -2
  6. package/dist/{allowed-origins-BqC8cul8.mjs.map → allowed-origins-D5FxMUo8.mjs.map} +1 -1
  7. package/dist/api/route-utils.d.mts +3 -3
  8. package/dist/api/route-utils.mjs +20 -19
  9. package/dist/api/route-utils.mjs.map +1 -1
  10. package/dist/api/schemas/index.d.mts +2 -2
  11. package/dist/api/schemas/index.mjs +4 -4
  12. package/dist/{api-DxjIV2o8.mjs → api-BQ_yKRdG.mjs} +31 -25
  13. package/dist/api-BQ_yKRdG.mjs.map +1 -0
  14. package/dist/{api-tokens-BFFkB0jB.mjs → api-tokens-D6ppjIVi.mjs} +13 -3
  15. package/dist/api-tokens-D6ppjIVi.mjs.map +1 -0
  16. package/dist/{apply-CLjxheyb.mjs → apply-CWRyxIoO.mjs} +18 -18
  17. package/dist/{apply-CLjxheyb.mjs.map → apply-CWRyxIoO.mjs.map} +1 -1
  18. package/dist/astro/image-endpoint.d.mts +8 -0
  19. package/dist/astro/image-endpoint.d.mts.map +1 -0
  20. package/dist/astro/image-endpoint.mjs +55 -0
  21. package/dist/astro/image-endpoint.mjs.map +1 -0
  22. package/dist/astro/index.d.mts +36 -11
  23. package/dist/astro/index.d.mts.map +1 -1
  24. package/dist/astro/index.mjs +122 -26
  25. package/dist/astro/index.mjs.map +1 -1
  26. package/dist/astro/middleware/auth.d.mts +9 -9
  27. package/dist/astro/middleware/auth.d.mts.map +1 -1
  28. package/dist/astro/middleware/auth.mjs +12 -10
  29. package/dist/astro/middleware/auth.mjs.map +1 -1
  30. package/dist/astro/middleware/redirect.mjs +6 -6
  31. package/dist/astro/middleware/request-context.d.mts.map +1 -1
  32. package/dist/astro/middleware/request-context.mjs +8 -6
  33. package/dist/astro/middleware/request-context.mjs.map +1 -1
  34. package/dist/astro/middleware/setup.mjs +1 -1
  35. package/dist/astro/middleware.d.mts +1 -1
  36. package/dist/astro/middleware.d.mts.map +1 -1
  37. package/dist/astro/middleware.mjs +444 -149
  38. package/dist/astro/middleware.mjs.map +1 -1
  39. package/dist/astro/routes/api/admin/allowed-domains/_domain_.mjs +7 -7
  40. package/dist/astro/routes/api/admin/allowed-domains/index.mjs +7 -7
  41. package/dist/astro/routes/api/admin/api-tokens/_id_.mjs +5 -5
  42. package/dist/astro/routes/api/admin/api-tokens/index.mjs +6 -6
  43. package/dist/astro/routes/api/admin/byline-fields/_slug_/usage.mjs +6 -6
  44. package/dist/astro/routes/api/admin/byline-fields/_slug_.mjs +10 -10
  45. package/dist/astro/routes/api/admin/byline-fields/index.mjs +10 -10
  46. package/dist/astro/routes/api/admin/byline-fields/reorder.mjs +10 -10
  47. package/dist/astro/routes/api/admin/bylines/_id_/index.mjs +18 -16
  48. package/dist/astro/routes/api/admin/bylines/_id_/index.mjs.map +1 -1
  49. package/dist/astro/routes/api/admin/bylines/_id_/translations.mjs +18 -16
  50. package/dist/astro/routes/api/admin/bylines/_id_/translations.mjs.map +1 -1
  51. package/dist/astro/routes/api/admin/bylines/index.mjs +18 -16
  52. package/dist/astro/routes/api/admin/bylines/index.mjs.map +1 -1
  53. package/dist/astro/routes/api/admin/comments/_id_/status.mjs +15 -13
  54. package/dist/astro/routes/api/admin/comments/_id_/status.mjs.map +1 -1
  55. package/dist/astro/routes/api/admin/comments/_id_.mjs +8 -6
  56. package/dist/astro/routes/api/admin/comments/_id_.mjs.map +1 -1
  57. package/dist/astro/routes/api/admin/comments/bulk.mjs +12 -10
  58. package/dist/astro/routes/api/admin/comments/bulk.mjs.map +1 -1
  59. package/dist/astro/routes/api/admin/comments/counts.mjs +8 -6
  60. package/dist/astro/routes/api/admin/comments/counts.mjs.map +1 -1
  61. package/dist/astro/routes/api/admin/comments/index.mjs +12 -10
  62. package/dist/astro/routes/api/admin/comments/index.mjs.map +1 -1
  63. package/dist/astro/routes/api/admin/hooks/exclusive/_hookName_.mjs +6 -6
  64. package/dist/astro/routes/api/admin/hooks/exclusive/index.mjs +5 -5
  65. package/dist/astro/routes/api/admin/oauth-clients/_id_.mjs +5 -5
  66. package/dist/astro/routes/api/admin/oauth-clients/index.mjs +5 -5
  67. package/dist/astro/routes/api/admin/plugins/_id_/disable.mjs +41 -39
  68. package/dist/astro/routes/api/admin/plugins/_id_/disable.mjs.map +1 -1
  69. package/dist/astro/routes/api/admin/plugins/_id_/enable.mjs +41 -39
  70. package/dist/astro/routes/api/admin/plugins/_id_/enable.mjs.map +1 -1
  71. package/dist/astro/routes/api/admin/plugins/_id_/index.mjs +40 -38
  72. package/dist/astro/routes/api/admin/plugins/_id_/index.mjs.map +1 -1
  73. package/dist/astro/routes/api/admin/plugins/_id_/uninstall.mjs +40 -38
  74. package/dist/astro/routes/api/admin/plugins/_id_/uninstall.mjs.map +1 -1
  75. package/dist/astro/routes/api/admin/plugins/_id_/update.mjs +40 -38
  76. package/dist/astro/routes/api/admin/plugins/_id_/update.mjs.map +1 -1
  77. package/dist/astro/routes/api/admin/plugins/index.mjs +40 -38
  78. package/dist/astro/routes/api/admin/plugins/index.mjs.map +1 -1
  79. package/dist/astro/routes/api/admin/plugins/marketplace/_id_/icon.mjs +4 -4
  80. package/dist/astro/routes/api/admin/plugins/marketplace/_id_/index.mjs +40 -38
  81. package/dist/astro/routes/api/admin/plugins/marketplace/_id_/index.mjs.map +1 -1
  82. package/dist/astro/routes/api/admin/plugins/marketplace/_id_/install.mjs +40 -38
  83. package/dist/astro/routes/api/admin/plugins/marketplace/_id_/install.mjs.map +1 -1
  84. package/dist/astro/routes/api/admin/plugins/marketplace/index.mjs +40 -38
  85. package/dist/astro/routes/api/admin/plugins/marketplace/index.mjs.map +1 -1
  86. package/dist/astro/routes/api/admin/plugins/registry/_id_/uninstall.mjs +40 -38
  87. package/dist/astro/routes/api/admin/plugins/registry/_id_/uninstall.mjs.map +1 -1
  88. package/dist/astro/routes/api/admin/plugins/registry/_id_/update.mjs +41 -39
  89. package/dist/astro/routes/api/admin/plugins/registry/_id_/update.mjs.map +1 -1
  90. package/dist/astro/routes/api/admin/plugins/registry/artifact.mjs +40 -38
  91. package/dist/astro/routes/api/admin/plugins/registry/artifact.mjs.map +1 -1
  92. package/dist/astro/routes/api/admin/plugins/registry/install.mjs +41 -39
  93. package/dist/astro/routes/api/admin/plugins/registry/install.mjs.map +1 -1
  94. package/dist/astro/routes/api/admin/plugins/updates.mjs +40 -38
  95. package/dist/astro/routes/api/admin/plugins/updates.mjs.map +1 -1
  96. package/dist/astro/routes/api/admin/themes/marketplace/_id_/index.mjs +40 -38
  97. package/dist/astro/routes/api/admin/themes/marketplace/_id_/index.mjs.map +1 -1
  98. package/dist/astro/routes/api/admin/themes/marketplace/_id_/thumbnail.mjs +4 -4
  99. package/dist/astro/routes/api/admin/themes/marketplace/index.mjs +40 -38
  100. package/dist/astro/routes/api/admin/themes/marketplace/index.mjs.map +1 -1
  101. package/dist/astro/routes/api/admin/users/_id_/disable.mjs +4 -4
  102. package/dist/astro/routes/api/admin/users/_id_/enable.mjs +3 -3
  103. package/dist/astro/routes/api/admin/users/_id_/index.mjs +8 -8
  104. package/dist/astro/routes/api/admin/users/_id_/send-recovery.mjs +5 -5
  105. package/dist/astro/routes/api/admin/users/index.mjs +7 -7
  106. package/dist/astro/routes/api/auth/dev-bypass.mjs +6 -6
  107. package/dist/astro/routes/api/auth/invite/accept.mjs +3 -3
  108. package/dist/astro/routes/api/auth/invite/complete.mjs +12 -12
  109. package/dist/astro/routes/api/auth/invite/index.mjs +9 -9
  110. package/dist/astro/routes/api/auth/invite/register-options.mjs +11 -11
  111. package/dist/astro/routes/api/auth/logout.mjs +4 -4
  112. package/dist/astro/routes/api/auth/magic-link/send.mjs +11 -11
  113. package/dist/astro/routes/api/auth/magic-link/verify.mjs +4 -4
  114. package/dist/astro/routes/api/auth/me.mjs +8 -8
  115. package/dist/astro/routes/api/auth/mode.mjs +1 -1
  116. package/dist/astro/routes/api/auth/oauth/_provider_/callback.mjs +4 -4
  117. package/dist/astro/routes/api/auth/oauth/_provider_.mjs +2 -2
  118. package/dist/astro/routes/api/auth/passkey/_id_.mjs +7 -7
  119. package/dist/astro/routes/api/auth/passkey/index.mjs +3 -3
  120. package/dist/astro/routes/api/auth/passkey/options.mjs +13 -13
  121. package/dist/astro/routes/api/auth/passkey/register/options.mjs +11 -11
  122. package/dist/astro/routes/api/auth/passkey/register/verify.mjs +12 -12
  123. package/dist/astro/routes/api/auth/passkey/verify.mjs +12 -12
  124. package/dist/astro/routes/api/auth/signup/complete.mjs +12 -12
  125. package/dist/astro/routes/api/auth/signup/request.mjs +11 -11
  126. package/dist/astro/routes/api/auth/signup/verify.mjs +3 -3
  127. package/dist/astro/routes/api/comments/_collection_/_contentId_/index.mjs +16 -15
  128. package/dist/astro/routes/api/comments/_collection_/_contentId_/index.mjs.map +1 -1
  129. package/dist/astro/routes/api/comments/_collection_/_contentId_/reactions.d.mts +9 -0
  130. package/dist/astro/routes/api/comments/_collection_/_contentId_/reactions.d.mts.map +1 -0
  131. package/dist/astro/routes/api/comments/_collection_/_contentId_/reactions.mjs +179 -0
  132. package/dist/astro/routes/api/comments/_collection_/_contentId_/reactions.mjs.map +1 -0
  133. package/dist/astro/routes/api/content/_collection_/_id_/compare.mjs +4 -4
  134. package/dist/astro/routes/api/content/_collection_/_id_/discard-draft.mjs +4 -4
  135. package/dist/astro/routes/api/content/_collection_/_id_/duplicate.mjs +4 -4
  136. package/dist/astro/routes/api/content/_collection_/_id_/permanent.mjs +4 -4
  137. package/dist/astro/routes/api/content/_collection_/_id_/preview-url.mjs +13 -13
  138. package/dist/astro/routes/api/content/_collection_/_id_/publish.mjs +8 -8
  139. package/dist/astro/routes/api/content/_collection_/_id_/restore.mjs +4 -4
  140. package/dist/astro/routes/api/content/_collection_/_id_/revisions.mjs +4 -4
  141. package/dist/astro/routes/api/content/_collection_/_id_/schedule.mjs +8 -8
  142. package/dist/astro/routes/api/content/_collection_/_id_/terms/_taxonomy_.mjs +17 -15
  143. package/dist/astro/routes/api/content/_collection_/_id_/terms/_taxonomy_.mjs.map +1 -1
  144. package/dist/astro/routes/api/content/_collection_/_id_/translations.mjs +4 -4
  145. package/dist/astro/routes/api/content/_collection_/_id_/unpublish.mjs +4 -4
  146. package/dist/astro/routes/api/content/_collection_/_id_.mjs +8 -8
  147. package/dist/astro/routes/api/content/_collection_/authors.mjs +4 -4
  148. package/dist/astro/routes/api/content/_collection_/index.mjs +8 -8
  149. package/dist/astro/routes/api/content/_collection_/trash.mjs +8 -8
  150. package/dist/astro/routes/api/dashboard.mjs +10 -8
  151. package/dist/astro/routes/api/dashboard.mjs.map +1 -1
  152. package/dist/astro/routes/api/dev/emails.mjs +4 -4
  153. package/dist/astro/routes/api/import/probe.d.mts +3 -3
  154. package/dist/astro/routes/api/import/probe.mjs +12 -12
  155. package/dist/astro/routes/api/import/wordpress/analyze.mjs +5 -5
  156. package/dist/astro/routes/api/import/wordpress/execute.d.mts +9 -9
  157. package/dist/astro/routes/api/import/wordpress/execute.mjs +17 -15
  158. package/dist/astro/routes/api/import/wordpress/execute.mjs.map +1 -1
  159. package/dist/astro/routes/api/import/wordpress/media.mjs +10 -10
  160. package/dist/astro/routes/api/import/wordpress/prepare.mjs +11 -11
  161. package/dist/astro/routes/api/import/wordpress/rewrite-urls.mjs +10 -10
  162. package/dist/astro/routes/api/import/wordpress-plugin/analyze.d.mts +1 -1
  163. package/dist/astro/routes/api/import/wordpress-plugin/analyze.mjs +12 -12
  164. package/dist/astro/routes/api/import/wordpress-plugin/callback.mjs +1 -1
  165. package/dist/astro/routes/api/import/wordpress-plugin/execute.d.mts +1 -1
  166. package/dist/astro/routes/api/import/wordpress-plugin/execute.mjs +19 -17
  167. package/dist/astro/routes/api/import/wordpress-plugin/execute.mjs.map +1 -1
  168. package/dist/astro/routes/api/manifest.mjs +5 -5
  169. package/dist/astro/routes/api/mcp.mjs +213 -46
  170. package/dist/astro/routes/api/mcp.mjs.map +1 -1
  171. package/dist/astro/routes/api/media/_id_/confirm.mjs +8 -8
  172. package/dist/astro/routes/api/media/_id_.mjs +8 -8
  173. package/dist/astro/routes/api/media/file/_...key_.mjs +3 -3
  174. package/dist/astro/routes/api/media/providers/_providerId_/_itemId_.mjs +4 -4
  175. package/dist/astro/routes/api/media/providers/_providerId_/index.mjs +4 -4
  176. package/dist/astro/routes/api/media/providers/index.mjs +4 -4
  177. package/dist/astro/routes/api/media/upload-url.mjs +10 -10
  178. package/dist/astro/routes/api/media.mjs +13 -13
  179. package/dist/astro/routes/api/menus/_name_/items/_id_.mjs +11 -9
  180. package/dist/astro/routes/api/menus/_name_/items/_id_.mjs.map +1 -1
  181. package/dist/astro/routes/api/menus/_name_/items.mjs +11 -9
  182. package/dist/astro/routes/api/menus/_name_/items.mjs.map +1 -1
  183. package/dist/astro/routes/api/menus/_name_/reorder.mjs +11 -9
  184. package/dist/astro/routes/api/menus/_name_/reorder.mjs.map +1 -1
  185. package/dist/astro/routes/api/menus/_name_/translations.mjs +11 -9
  186. package/dist/astro/routes/api/menus/_name_/translations.mjs.map +1 -1
  187. package/dist/astro/routes/api/menus/_name_.mjs +11 -9
  188. package/dist/astro/routes/api/menus/_name_.mjs.map +1 -1
  189. package/dist/astro/routes/api/menus/index.mjs +11 -9
  190. package/dist/astro/routes/api/menus/index.mjs.map +1 -1
  191. package/dist/astro/routes/api/oauth/authorize.mjs +6 -6
  192. package/dist/astro/routes/api/oauth/device/authorize.mjs +7 -7
  193. package/dist/astro/routes/api/oauth/device/code.mjs +10 -10
  194. package/dist/astro/routes/api/oauth/device/token.mjs +9 -9
  195. package/dist/astro/routes/api/oauth/register.mjs +4 -4
  196. package/dist/astro/routes/api/oauth/token/refresh.mjs +7 -7
  197. package/dist/astro/routes/api/oauth/token/revoke.mjs +7 -7
  198. package/dist/astro/routes/api/oauth/token.mjs +7 -7
  199. package/dist/astro/routes/api/openapi.json.mjs +5 -5
  200. package/dist/astro/routes/api/plugins/_pluginId_/_...path_.mjs +5 -5
  201. package/dist/astro/routes/api/redirects/404s/index.mjs +11 -11
  202. package/dist/astro/routes/api/redirects/404s/summary.mjs +11 -11
  203. package/dist/astro/routes/api/redirects/_id_.mjs +12 -12
  204. package/dist/astro/routes/api/redirects/index.mjs +12 -12
  205. package/dist/astro/routes/api/revisions/_revisionId_/index.mjs +4 -4
  206. package/dist/astro/routes/api/revisions/_revisionId_/restore.mjs +4 -4
  207. package/dist/astro/routes/api/schema/collections/_slug_/fields/_fieldSlug_.mjs +40 -38
  208. package/dist/astro/routes/api/schema/collections/_slug_/fields/_fieldSlug_.mjs.map +1 -1
  209. package/dist/astro/routes/api/schema/collections/_slug_/fields/index.mjs +40 -38
  210. package/dist/astro/routes/api/schema/collections/_slug_/fields/index.mjs.map +1 -1
  211. package/dist/astro/routes/api/schema/collections/_slug_/fields/reorder.mjs +40 -38
  212. package/dist/astro/routes/api/schema/collections/_slug_/fields/reorder.mjs.map +1 -1
  213. package/dist/astro/routes/api/schema/collections/_slug_/index.mjs +40 -38
  214. package/dist/astro/routes/api/schema/collections/_slug_/index.mjs.map +1 -1
  215. package/dist/astro/routes/api/schema/collections/index.mjs +40 -38
  216. package/dist/astro/routes/api/schema/collections/index.mjs.map +1 -1
  217. package/dist/astro/routes/api/schema/index.mjs +9 -8
  218. package/dist/astro/routes/api/schema/index.mjs.map +1 -1
  219. package/dist/astro/routes/api/schema/orphans/_slug_.mjs +40 -38
  220. package/dist/astro/routes/api/schema/orphans/_slug_.mjs.map +1 -1
  221. package/dist/astro/routes/api/schema/orphans/index.mjs +40 -38
  222. package/dist/astro/routes/api/schema/orphans/index.mjs.map +1 -1
  223. package/dist/astro/routes/api/search/enable.mjs +11 -11
  224. package/dist/astro/routes/api/search/index.mjs +10 -10
  225. package/dist/astro/routes/api/search/rebuild.mjs +11 -11
  226. package/dist/astro/routes/api/search/stats.mjs +7 -7
  227. package/dist/astro/routes/api/search/suggest.mjs +10 -10
  228. package/dist/astro/routes/api/sections/_slug_.mjs +10 -10
  229. package/dist/astro/routes/api/sections/index.mjs +10 -10
  230. package/dist/astro/routes/api/settings/email.mjs +6 -6
  231. package/dist/astro/routes/api/settings.mjs +16 -15
  232. package/dist/astro/routes/api/settings.mjs.map +1 -1
  233. package/dist/astro/routes/api/setup/admin-verify.mjs +13 -13
  234. package/dist/astro/routes/api/setup/admin.mjs +12 -12
  235. package/dist/astro/routes/api/setup/dev-bypass.d.mts.map +1 -1
  236. package/dist/astro/routes/api/setup/dev-bypass.mjs +30 -27
  237. package/dist/astro/routes/api/setup/dev-bypass.mjs.map +1 -1
  238. package/dist/astro/routes/api/setup/dev-reset.mjs +4 -4
  239. package/dist/astro/routes/api/setup/index.mjs +30 -28
  240. package/dist/astro/routes/api/setup/index.mjs.map +1 -1
  241. package/dist/astro/routes/api/setup/status.mjs +5 -5
  242. package/dist/astro/routes/api/snapshot.d.mts.map +1 -1
  243. package/dist/astro/routes/api/snapshot.mjs +10 -9
  244. package/dist/astro/routes/api/snapshot.mjs.map +1 -1
  245. package/dist/astro/routes/api/taxonomies/_name_/terms/_slug_/translations.mjs +16 -14
  246. package/dist/astro/routes/api/taxonomies/_name_/terms/_slug_/translations.mjs.map +1 -1
  247. package/dist/astro/routes/api/taxonomies/_name_/terms/_slug_.mjs +16 -14
  248. package/dist/astro/routes/api/taxonomies/_name_/terms/_slug_.mjs.map +1 -1
  249. package/dist/astro/routes/api/taxonomies/_name_/terms/index.mjs +16 -14
  250. package/dist/astro/routes/api/taxonomies/_name_/terms/index.mjs.map +1 -1
  251. package/dist/astro/routes/api/taxonomies/index.mjs +16 -14
  252. package/dist/astro/routes/api/taxonomies/index.mjs.map +1 -1
  253. package/dist/astro/routes/api/themes/preview.mjs +8 -8
  254. package/dist/astro/routes/api/typegen.mjs +6 -6
  255. package/dist/astro/routes/api/well-known/auth.mjs +2 -2
  256. package/dist/astro/routes/api/well-known/oauth-authorization-server.mjs +2 -2
  257. package/dist/astro/routes/api/well-known/oauth-protected-resource.mjs +2 -2
  258. package/dist/astro/routes/api/widget-areas/_name_/reorder.mjs +8 -8
  259. package/dist/astro/routes/api/widget-areas/_name_/widgets/_id_.mjs +11 -11
  260. package/dist/astro/routes/api/widget-areas/_name_/widgets.mjs +11 -11
  261. package/dist/astro/routes/api/widget-areas/_name_.mjs +7 -7
  262. package/dist/astro/routes/api/widget-areas/index.mjs +11 -11
  263. package/dist/astro/routes/api/widget-components.mjs +4 -4
  264. package/dist/astro/routes/robots.txt.mjs +10 -9
  265. package/dist/astro/routes/robots.txt.mjs.map +1 -1
  266. package/dist/astro/routes/sitemap-_collection_.xml.mjs +13 -12
  267. package/dist/astro/routes/sitemap-_collection_.xml.mjs.map +1 -1
  268. package/dist/astro/routes/sitemap.xml.mjs +11 -10
  269. package/dist/astro/routes/sitemap.xml.mjs.map +1 -1
  270. package/dist/astro/types.d.mts +16 -12
  271. package/dist/astro/types.d.mts.map +1 -1
  272. package/dist/auth/providers/github.d.mts +1 -1
  273. package/dist/auth/providers/google.d.mts +1 -1
  274. package/dist/{authorize-D5gfBVU5.mjs → authorize-Cse0k7B0.mjs} +2 -2
  275. package/dist/{authorize-D5gfBVU5.mjs.map → authorize-Cse0k7B0.mjs.map} +1 -1
  276. package/dist/{base64-CqR-7kqF.mjs → base64-CmWvODNW.mjs} +1 -1
  277. package/dist/{base64-CqR-7kqF.mjs.map → base64-CmWvODNW.mjs.map} +1 -1
  278. package/dist/{byline-V_Qp1Ziw.mjs → byline-DVo-liaP.mjs} +27 -76
  279. package/dist/byline-DVo-liaP.mjs.map +1 -0
  280. package/dist/{byline-fields-B0NO1yUB.mjs → byline-fields-B-KXkg5R.mjs} +3 -3
  281. package/dist/{byline-fields-B0NO1yUB.mjs.map → byline-fields-B-KXkg5R.mjs.map} +1 -1
  282. package/dist/{byline-fields-nBVqK_Ff.mjs → byline-fields-DaMKzkhO.mjs} +2 -2
  283. package/dist/{byline-fields-nBVqK_Ff.mjs.map → byline-fields-DaMKzkhO.mjs.map} +1 -1
  284. package/dist/{byline-fields-CQJRIQkn.d.mts → byline-fields-RFPkDLRw.d.mts} +56 -31
  285. package/dist/byline-fields-RFPkDLRw.d.mts.map +1 -0
  286. package/dist/{byline-registry-DedidtqC.mjs → byline-registry-BOjqDOim.mjs} +3 -3
  287. package/dist/{byline-registry-DedidtqC.mjs.map → byline-registry-BOjqDOim.mjs.map} +1 -1
  288. package/dist/{bylines-DfGDnred.mjs → bylines-f5ppBpD5.mjs} +8 -8
  289. package/dist/{bylines-DfGDnred.mjs.map → bylines-f5ppBpD5.mjs.map} +1 -1
  290. package/dist/{bylines-B2NWnIwS.mjs → bylines-pIKgc_TL.mjs} +10 -4
  291. package/dist/{bylines-B2NWnIwS.mjs.map → bylines-pIKgc_TL.mjs.map} +1 -1
  292. package/dist/{cache-DTTHWD8n.mjs → cache-Q6V4U-Xz.mjs} +3 -3
  293. package/dist/{cache-DTTHWD8n.mjs.map → cache-Q6V4U-Xz.mjs.map} +1 -1
  294. package/dist/{challenge-store-woE0bbCf.mjs → challenge-store-LhiqMccz.mjs} +1 -1
  295. package/dist/{challenge-store-woE0bbCf.mjs.map → challenge-store-LhiqMccz.mjs.map} +1 -1
  296. package/dist/{chunks-BerYVuve.mjs → chunks-SyjZaYwV.mjs} +2 -2
  297. package/dist/{chunks-BerYVuve.mjs.map → chunks-SyjZaYwV.mjs.map} +1 -1
  298. package/dist/cli/index.mjs +29 -27
  299. package/dist/cli/index.mjs.map +1 -1
  300. package/dist/client/cf-access.d.mts +1 -1
  301. package/dist/client/index.d.mts +1 -1
  302. package/dist/client/index.mjs +2 -1
  303. package/dist/client/index.mjs.map +1 -1
  304. package/dist/{comment-sqQxNpN3.mjs → comment-80UyJJUR.mjs} +11 -3
  305. package/dist/comment-80UyJJUR.mjs.map +1 -0
  306. package/dist/comment-reaction-Dyb-AutY.mjs +85 -0
  307. package/dist/comment-reaction-Dyb-AutY.mjs.map +1 -0
  308. package/dist/{comments-D2hNuxNa.mjs → comments-Cczx7AvD.mjs} +3 -3
  309. package/dist/{comments-D2hNuxNa.mjs.map → comments-Cczx7AvD.mjs.map} +1 -1
  310. package/dist/{components-DYKp2gmo.mjs → components-CYt4uVK9.mjs} +1 -1
  311. package/dist/{components-DYKp2gmo.mjs.map → components-CYt4uVK9.mjs.map} +1 -1
  312. package/dist/{content-BIlVx-RX.mjs → content-2PTDNnoh.mjs} +22 -7
  313. package/dist/content-2PTDNnoh.mjs.map +1 -0
  314. package/dist/{context-Cm4pt1Ws.mjs → context-B1W8soLv.mjs} +64 -26
  315. package/dist/context-B1W8soLv.mjs.map +1 -0
  316. package/dist/{cron-DdEVrQ2Y.mjs → cron-C5LVoNmP.mjs} +14 -2
  317. package/dist/cron-C5LVoNmP.mjs.map +1 -0
  318. package/dist/{dashboard-C-UYpps0.mjs → dashboard-CYjpQZ6-.mjs} +4 -4
  319. package/dist/{dashboard-C-UYpps0.mjs.map → dashboard-CYjpQZ6-.mjs.map} +1 -1
  320. package/dist/database/instrumentation.d.mts +19 -0
  321. package/dist/database/instrumentation.d.mts.map +1 -1
  322. package/dist/database/instrumentation.mjs +8 -1
  323. package/dist/database/instrumentation.mjs.map +1 -1
  324. package/dist/db/index.d.mts +3 -3
  325. package/dist/db/index.mjs +1 -1
  326. package/dist/db/libsql.d.mts +1 -1
  327. package/dist/db/postgres.d.mts +1 -1
  328. package/dist/db/sqlite.d.mts +1 -1
  329. package/dist/{db-errors-BluWkwGI.mjs → db-errors-UXB1CK42.mjs} +1 -1
  330. package/dist/{db-errors-BluWkwGI.mjs.map → db-errors-UXB1CK42.mjs.map} +1 -1
  331. package/dist/{default-NHGuJzQ3.mjs → default-CeRG-Ot4.mjs} +1 -1
  332. package/dist/{default-NHGuJzQ3.mjs.map → default-CeRG-Ot4.mjs.map} +1 -1
  333. package/dist/{device-flow-BQApWgnW.mjs → device-flow-DENDCQ9F.mjs} +5 -5
  334. package/dist/{device-flow-BQApWgnW.mjs.map → device-flow-DENDCQ9F.mjs.map} +1 -1
  335. package/dist/{email-console-BbU3RbWv.mjs → email-console-DJP32ucW.mjs} +1 -1
  336. package/dist/{email-console-BbU3RbWv.mjs.map → email-console-DJP32ucW.mjs.map} +1 -1
  337. package/dist/{error-CNn_w7jf.mjs → error-Bl6kZgtt.mjs} +2 -2
  338. package/dist/{error-CNn_w7jf.mjs.map → error-Bl6kZgtt.mjs.map} +1 -1
  339. package/dist/{escape-DPgcxcpL.mjs → escape-Bjio4ZsM.mjs} +1 -1
  340. package/dist/{escape-DPgcxcpL.mjs.map → escape-Bjio4ZsM.mjs.map} +1 -1
  341. package/dist/field-defs-cache-ztrdzUGb.mjs +77 -0
  342. package/dist/field-defs-cache-ztrdzUGb.mjs.map +1 -0
  343. package/dist/{fts-manager-Cx5z8jdA.mjs → fts-manager-CQuHt-vS.mjs} +2 -2
  344. package/dist/{fts-manager-Cx5z8jdA.mjs.map → fts-manager-CQuHt-vS.mjs.map} +1 -1
  345. package/dist/{hash-DlvIFn0b.mjs → hash-DrvzIXcz.mjs} +1 -1
  346. package/dist/{hash-DlvIFn0b.mjs.map → hash-DrvzIXcz.mjs.map} +1 -1
  347. package/dist/{import-KyxT1Mbs.mjs → import-Bb1T9WJS.mjs} +4 -4
  348. package/dist/{import-KyxT1Mbs.mjs.map → import-Bb1T9WJS.mjs.map} +1 -1
  349. package/dist/{index-D2VAiumu.d.mts → index-BaIj5hIq.d.mts} +198 -21
  350. package/dist/index-BaIj5hIq.d.mts.map +1 -0
  351. package/dist/{index-uT2yR66F.d.mts → index-qbL02uhs.d.mts} +3 -3
  352. package/dist/{index-uT2yR66F.d.mts.map → index-qbL02uhs.d.mts.map} +1 -1
  353. package/dist/index.d.mts +18 -17
  354. package/dist/index.mjs +64 -61
  355. package/dist/{init-lock-DlBHjf9-.mjs → init-lock-6b309ZrF.mjs} +2 -29
  356. package/dist/init-lock-6b309ZrF.mjs.map +1 -0
  357. package/dist/{load-Dq91b_DK.mjs → load-BNo-ER8C.mjs} +2 -2
  358. package/dist/{load-Dq91b_DK.mjs.map → load-BNo-ER8C.mjs.map} +1 -1
  359. package/dist/{loader-BqWjcH3h.mjs → loader-Dn74CG1b.mjs} +70 -11
  360. package/dist/loader-Dn74CG1b.mjs.map +1 -0
  361. package/dist/{manifest-schema-DFPeqMAn.mjs → manifest-schema-BWKnQYQF.mjs} +1 -1
  362. package/dist/{manifest-schema-DFPeqMAn.mjs.map → manifest-schema-BWKnQYQF.mjs.map} +1 -1
  363. package/dist/media/image-endpoint.d.mts +74 -0
  364. package/dist/media/image-endpoint.d.mts.map +1 -0
  365. package/dist/media/image-endpoint.mjs +162 -0
  366. package/dist/media/image-endpoint.mjs.map +1 -0
  367. package/dist/media/index.d.mts +1 -1
  368. package/dist/media/index.mjs +2 -2
  369. package/dist/media/local-runtime.d.mts +19 -11
  370. package/dist/media/local-runtime.d.mts.map +1 -1
  371. package/dist/media/local-runtime.mjs +16 -13
  372. package/dist/media/local-runtime.mjs.map +1 -1
  373. package/dist/{media-JOf3pNkw.mjs → media-Bw0sA6rb.mjs} +2 -2
  374. package/dist/{media-JOf3pNkw.mjs.map → media-Bw0sA6rb.mjs.map} +1 -1
  375. package/dist/{media-allowlist-_A0SuDn4.mjs → media-allowlist-B77I5_bw.mjs} +2 -2
  376. package/dist/{media-allowlist-_A0SuDn4.mjs.map → media-allowlist-B77I5_bw.mjs.map} +1 -1
  377. package/dist/{media-url-CqLd69IO.mjs → media-url-O4rm9-SQ.mjs} +1 -1
  378. package/dist/{media-url-CqLd69IO.mjs.map → media-url-O4rm9-SQ.mjs.map} +1 -1
  379. package/dist/{menus-DX4_E01q.mjs → menus-CYs0WZoL.mjs} +20 -6
  380. package/dist/menus-CYs0WZoL.mjs.map +1 -0
  381. package/dist/{menus-Ryk9L7fT.mjs → menus-DS8VTZgo.mjs} +167 -24
  382. package/dist/menus-DS8VTZgo.mjs.map +1 -0
  383. package/dist/{mime-YbtlEtvS.mjs → mime-BTzvzJ8M.mjs} +1 -1
  384. package/dist/{mime-YbtlEtvS.mjs.map → mime-BTzvzJ8M.mjs.map} +1 -1
  385. package/dist/{mode-CGXzIbD8.mjs → mode-BB0F8xTC.mjs} +1 -1
  386. package/dist/{mode-CGXzIbD8.mjs.map → mode-BB0F8xTC.mjs.map} +1 -1
  387. package/dist/{normalize-DKsg36ty.mjs → normalize-ClbNIenm.mjs} +1 -1
  388. package/dist/{normalize-DKsg36ty.mjs.map → normalize-ClbNIenm.mjs.map} +1 -1
  389. package/dist/{oauth-authorization-C2kVyjXI.mjs → oauth-authorization-CsvzIp_F.mjs} +5 -5
  390. package/dist/{oauth-authorization-C2kVyjXI.mjs.map → oauth-authorization-CsvzIp_F.mjs.map} +1 -1
  391. package/dist/{oauth-clients-BC873NCV.mjs → oauth-clients-C9SYwEbZ.mjs} +1 -1
  392. package/dist/{oauth-clients-BC873NCV.mjs.map → oauth-clients-C9SYwEbZ.mjs.map} +1 -1
  393. package/dist/{oauth-state-store-Cd--TUaq.mjs → oauth-state-store---zrApfB.mjs} +1 -1
  394. package/dist/{oauth-state-store-Cd--TUaq.mjs.map → oauth-state-store---zrApfB.mjs.map} +1 -1
  395. package/dist/{oauth-user-lookup-e4wOvDud.mjs → oauth-user-lookup-SHsWRlG9.mjs} +1 -1
  396. package/dist/{oauth-user-lookup-e4wOvDud.mjs.map → oauth-user-lookup-SHsWRlG9.mjs.map} +1 -1
  397. package/dist/object-cache/memory.d.mts +15 -0
  398. package/dist/object-cache/memory.d.mts.map +1 -0
  399. package/dist/object-cache/memory.mjs +56 -0
  400. package/dist/object-cache/memory.mjs.map +1 -0
  401. package/dist/object-cache-SEb2IM4Z.mjs +373 -0
  402. package/dist/object-cache-SEb2IM4Z.mjs.map +1 -0
  403. package/dist/{options-9kLgkE8m.d.mts → options-CqECG0gM.d.mts} +3 -3
  404. package/dist/{options-9kLgkE8m.d.mts.map → options-CqECG0gM.d.mts.map} +1 -1
  405. package/dist/{options-BPCVnesz.mjs → options-DTTML-Tx.mjs} +1 -1
  406. package/dist/{options-BPCVnesz.mjs.map → options-DTTML-Tx.mjs.map} +1 -1
  407. package/dist/page/index.d.mts +2 -2
  408. package/dist/{parse-DzSrk1t8.mjs → parse-C9hpjUyY.mjs} +2 -2
  409. package/dist/{parse-DzSrk1t8.mjs.map → parse-C9hpjUyY.mjs.map} +1 -1
  410. package/dist/{passkey-config-BpjbE_Uv.mjs → passkey-config-C0YfSBko.mjs} +1 -1
  411. package/dist/{passkey-config-BpjbE_Uv.mjs.map → passkey-config-C0YfSBko.mjs.map} +1 -1
  412. package/dist/{patterns-p-RBdTbM.mjs → patterns-BKmjvM7K.mjs} +1 -1
  413. package/dist/{patterns-p-RBdTbM.mjs.map → patterns-BKmjvM7K.mjs.map} +1 -1
  414. package/dist/{placeholder-2xumZh4g.mjs → placeholder-B0s2mWu5.mjs} +1 -1
  415. package/dist/{placeholder-2xumZh4g.mjs.map → placeholder-B0s2mWu5.mjs.map} +1 -1
  416. package/dist/{placeholder-BevVKfay.d.mts → placeholder-QoI4gEzP.d.mts} +1 -1
  417. package/dist/{placeholder-BevVKfay.d.mts.map → placeholder-QoI4gEzP.d.mts.map} +1 -1
  418. package/dist/plugin-types.d.mts +1 -1
  419. package/dist/plugin-utils.d.mts +9 -9
  420. package/dist/plugins/adapt-sandbox-entry.d.mts +9 -9
  421. package/dist/plugins/adapt-sandbox-entry.mjs +4 -2
  422. package/dist/plugins/adapt-sandbox-entry.mjs.map +1 -1
  423. package/dist/{transport-1cIrOb1Y.mjs → portable-text-BICg8bTk.mjs} +2 -135
  424. package/dist/portable-text-BICg8bTk.mjs.map +1 -0
  425. package/dist/{preview-Dqv2hwXr.mjs → preview-DKGCt2_p.mjs} +2 -2
  426. package/dist/{preview-Dqv2hwXr.mjs.map → preview-DKGCt2_p.mjs.map} +1 -1
  427. package/dist/{public-url-D_zARuvZ.mjs → public-url-CTVqgMmg.mjs} +1 -1
  428. package/dist/{public-url-D_zARuvZ.mjs.map → public-url-CTVqgMmg.mjs.map} +1 -1
  429. package/dist/{query-Crm038Mc.mjs → query-DgUHZLWB.mjs} +230 -31
  430. package/dist/query-DgUHZLWB.mjs.map +1 -0
  431. package/dist/{rate-limit-hRTBqmw1.mjs → rate-limit-BuQ5d4X_.mjs} +2 -2
  432. package/dist/{rate-limit-hRTBqmw1.mjs.map → rate-limit-BuQ5d4X_.mjs.map} +1 -1
  433. package/dist/{redirect-CRWIt8Zj.mjs → redirect-Bifv_yHv.mjs} +3 -3
  434. package/dist/{redirect-CRWIt8Zj.mjs.map → redirect-Bifv_yHv.mjs.map} +1 -1
  435. package/dist/{redirect-C-OOkyku.mjs → redirect-CS-PHtNh.mjs} +1 -1
  436. package/dist/{redirect-C-OOkyku.mjs.map → redirect-CS-PHtNh.mjs.map} +1 -1
  437. package/dist/{redirects-CP3TnTLO.mjs → redirects-BZ8Mxn8H.mjs} +6 -6
  438. package/dist/{redirects-CP3TnTLO.mjs.map → redirects-BZ8Mxn8H.mjs.map} +1 -1
  439. package/dist/{redirects-6Zg2SoYo.mjs → redirects-x9eFPeyi.mjs} +10 -3
  440. package/dist/redirects-x9eFPeyi.mjs.map +1 -0
  441. package/dist/{registry-diMzD1Wf.mjs → registry-CK1SS6pi.mjs} +6 -6
  442. package/dist/{registry-diMzD1Wf.mjs.map → registry-CK1SS6pi.mjs.map} +1 -1
  443. package/dist/{request-cache-UwmBAiUK.mjs → request-cache-KCNHp_RJ.mjs} +1 -1
  444. package/dist/{request-cache-UwmBAiUK.mjs.map → request-cache-KCNHp_RJ.mjs.map} +1 -1
  445. package/dist/{request-meta-DPechd0W.mjs → request-meta-CmS1tDFf.mjs} +2 -2
  446. package/dist/{request-meta-DPechd0W.mjs.map → request-meta-CmS1tDFf.mjs.map} +1 -1
  447. package/dist/{resolve-B3NUUtVY.mjs → resolve-C7I0qiR0.mjs} +1 -1
  448. package/dist/{resolve-B3NUUtVY.mjs.map → resolve-C7I0qiR0.mjs.map} +1 -1
  449. package/dist/{runner-C8vcbvCe.d.mts → runner-CEtq-6Sm.d.mts} +2 -2
  450. package/dist/{runner-C8vcbvCe.d.mts.map → runner-CEtq-6Sm.d.mts.map} +1 -1
  451. package/dist/{runner--4wMWwKM.mjs → runner-DYYnW530.mjs} +201 -170
  452. package/dist/runner-DYYnW530.mjs.map +1 -0
  453. package/dist/runtime.d.mts +10 -10
  454. package/dist/runtime.mjs +3 -3
  455. package/dist/{schema-BDOkd3OU.mjs → schema-CbFRFoM7.mjs} +13 -8
  456. package/dist/schema-CbFRFoM7.mjs.map +1 -0
  457. package/dist/{search-Bs_J_EW-.mjs → search-C-waE_YW.mjs} +4 -4
  458. package/dist/{search-Bs_J_EW-.mjs.map → search-C-waE_YW.mjs.map} +1 -1
  459. package/dist/{secrets-C8xmE6mR.mjs → secrets-BSf9pRRY.mjs} +5 -5
  460. package/dist/{secrets-C8xmE6mR.mjs.map → secrets-BSf9pRRY.mjs.map} +1 -1
  461. package/dist/{sections-P0zuBlyz.mjs → sections-osX9U-YJ.mjs} +3 -3
  462. package/dist/{sections-P0zuBlyz.mjs.map → sections-osX9U-YJ.mjs.map} +1 -1
  463. package/dist/seed/index.d.mts +2 -2
  464. package/dist/seed/index.mjs +23 -21
  465. package/dist/seo/index.d.mts +1 -1
  466. package/dist/seo/index.mjs +1 -1
  467. package/dist/{seo-DpNgGQjF.mjs → seo-4FovMwNS.mjs} +5 -2
  468. package/dist/seo-4FovMwNS.mjs.map +1 -0
  469. package/dist/{seo-CLhm-Fmb.mjs → seo-DCEF-AVr.mjs} +1 -1
  470. package/dist/{seo-CLhm-Fmb.mjs.map → seo-DCEF-AVr.mjs.map} +1 -1
  471. package/dist/{service-CDQQnT8W.mjs → service-jby1RRmU.mjs} +3 -3
  472. package/dist/{service-CDQQnT8W.mjs.map → service-jby1RRmU.mjs.map} +1 -1
  473. package/dist/session-user-B8aLtKAH.mjs +51 -0
  474. package/dist/session-user-B8aLtKAH.mjs.map +1 -0
  475. package/dist/{settings-sO0Fif4p.mjs → settings-4bRT2NIf.mjs} +3 -3
  476. package/dist/{settings-sO0Fif4p.mjs.map → settings-4bRT2NIf.mjs.map} +1 -1
  477. package/dist/{settings-BjBsmVAo.mjs → settings-t-H2jPuJ.mjs} +18 -10
  478. package/dist/settings-t-H2jPuJ.mjs.map +1 -0
  479. package/dist/{setup-complete-CMMr-oZU.mjs → setup-complete-gEiySUc-.mjs} +2 -2
  480. package/dist/{setup-complete-CMMr-oZU.mjs.map → setup-complete-gEiySUc-.mjs.map} +1 -1
  481. package/dist/{setup-nonce-169xl4fV.mjs → setup-nonce-DzS50zme.mjs} +1 -1
  482. package/dist/{setup-nonce-169xl4fV.mjs.map → setup-nonce-DzS50zme.mjs.map} +1 -1
  483. package/dist/{single-flight-cache-C0UV1Npg.mjs → single-flight-cache-Cdfkic3t.mjs} +2 -2
  484. package/dist/{single-flight-cache-C0UV1Npg.mjs.map → single-flight-cache-Cdfkic3t.mjs.map} +1 -1
  485. package/dist/{site-url-vtsuOvSD.mjs → site-url-BLebyON8.mjs} +2 -2
  486. package/dist/{site-url-vtsuOvSD.mjs.map → site-url-BLebyON8.mjs.map} +1 -1
  487. package/dist/{slugify-Cjh1ssOZ.mjs → slugify-Cce3dTdg.mjs} +1 -1
  488. package/dist/{slugify-Cjh1ssOZ.mjs.map → slugify-Cce3dTdg.mjs.map} +1 -1
  489. package/dist/{ssrf-XO05Voq6.mjs → ssrf-BRKb343l.mjs} +1 -1
  490. package/dist/{ssrf-XO05Voq6.mjs.map → ssrf-BRKb343l.mjs.map} +1 -1
  491. package/dist/{status-2gZklYuj.mjs → status-vUK0SA17.mjs} +1 -1
  492. package/dist/{status-2gZklYuj.mjs.map → status-vUK0SA17.mjs.map} +1 -1
  493. package/dist/storage/local.d.mts +1 -1
  494. package/dist/storage/local.mjs +1 -1
  495. package/dist/storage/s3.d.mts +1 -1
  496. package/dist/storage/s3.mjs +1 -1
  497. package/dist/{taxonomies-DuESHWKI.mjs → taxonomies-BBB8O-CU.mjs} +7 -7
  498. package/dist/{taxonomies-DuESHWKI.mjs.map → taxonomies-BBB8O-CU.mjs.map} +1 -1
  499. package/dist/{taxonomies-BBxYA38v.mjs → taxonomies-Dxrc_szG.mjs} +177 -123
  500. package/dist/taxonomies-Dxrc_szG.mjs.map +1 -0
  501. package/dist/{taxonomy-CdllE4oq.mjs → taxonomy-B2HQuVf5.mjs} +19 -6
  502. package/dist/taxonomy-B2HQuVf5.mjs.map +1 -0
  503. package/dist/{tokens-DMkVjxrx.mjs → tokens-LeuXF9gG.mjs} +2 -2
  504. package/dist/{tokens-DMkVjxrx.mjs.map → tokens-LeuXF9gG.mjs.map} +1 -1
  505. package/dist/{transaction-x2tJQ-A1.mjs → transaction-qfqpPVpu.mjs} +1 -1
  506. package/dist/{transaction-x2tJQ-A1.mjs.map → transaction-qfqpPVpu.mjs.map} +1 -1
  507. package/dist/{transport-jdvsZEIt.d.mts → transport-BZ-03aFT.d.mts} +1 -1
  508. package/dist/{transport-jdvsZEIt.d.mts.map → transport-BZ-03aFT.d.mts.map} +1 -1
  509. package/dist/transport-_2nBz7e9.mjs +135 -0
  510. package/dist/transport-_2nBz7e9.mjs.map +1 -0
  511. package/dist/{trusted-proxy-CHp41Fjj.mjs → trusted-proxy-DZY5WCn2.mjs} +1 -1
  512. package/dist/{trusted-proxy-CHp41Fjj.mjs.map → trusted-proxy-DZY5WCn2.mjs.map} +1 -1
  513. package/dist/{types-Del0VMij.d.mts → types-B-gIxFCE.d.mts} +9 -1
  514. package/dist/{types-Del0VMij.d.mts.map → types-B-gIxFCE.d.mts.map} +1 -1
  515. package/dist/{types-DdkL6fyv.d.mts → types-BG8_XTLj.d.mts} +1 -1
  516. package/dist/{types-DdkL6fyv.d.mts.map → types-BG8_XTLj.d.mts.map} +1 -1
  517. package/dist/{types-BTnnBYVX.d.mts → types-BWh2MjmA.d.mts} +15 -2
  518. package/dist/types-BWh2MjmA.d.mts.map +1 -0
  519. package/dist/{types-CkEuk-Zr.d.mts → types-BWqGVhFn.d.mts} +1 -1
  520. package/dist/{types-CkEuk-Zr.d.mts.map → types-BWqGVhFn.d.mts.map} +1 -1
  521. package/dist/{types-DejCHqWT.mjs → types-CQAugunJ.mjs} +1 -1
  522. package/dist/{types-DejCHqWT.mjs.map → types-CQAugunJ.mjs.map} +1 -1
  523. package/dist/{types-Bzfk2yC8.d.mts → types-CTLJYMhN.d.mts} +1 -1
  524. package/dist/{types-Bzfk2yC8.d.mts.map → types-CTLJYMhN.d.mts.map} +1 -1
  525. package/dist/{types-BFgYtuKd.d.mts → types-CUsXGRVj.d.mts} +1 -1
  526. package/dist/{types-BFgYtuKd.d.mts.map → types-CUsXGRVj.d.mts.map} +1 -1
  527. package/dist/{types-BXSUSAjt.mjs → types-DXOIbece.mjs} +3 -3
  528. package/dist/types-DXOIbece.mjs.map +1 -0
  529. package/dist/{types-u_XxjbS8.d.mts → types-DrYMm9s5.d.mts} +1 -1
  530. package/dist/{types-u_XxjbS8.d.mts.map → types-DrYMm9s5.d.mts.map} +1 -1
  531. package/dist/{types-DO7whVYU.d.mts → types-TTx8uP7V.d.mts} +2 -2
  532. package/dist/{types-DO7whVYU.d.mts.map → types-TTx8uP7V.d.mts.map} +1 -1
  533. package/dist/types-fS7-VTdR.d.mts +124 -0
  534. package/dist/types-fS7-VTdR.d.mts.map +1 -0
  535. package/dist/{types-BIduXPJk.mjs → types-tM44hEcf.mjs} +1 -1
  536. package/dist/{types-BIduXPJk.mjs.map → types-tM44hEcf.mjs.map} +1 -1
  537. package/dist/{user-C0um7wrg.mjs → user-Db-Rti_z.mjs} +3 -3
  538. package/dist/{user-C0um7wrg.mjs.map → user-Db-Rti_z.mjs.map} +1 -1
  539. package/dist/{utils-C4M981Br.mjs → utils-B7A57fm9.mjs} +2 -2
  540. package/dist/{utils-C4M981Br.mjs.map → utils-B7A57fm9.mjs.map} +1 -1
  541. package/dist/{validate-DGhQPXzI.mjs → validate-0Utjspbs.mjs} +3 -3
  542. package/dist/{validate-DGhQPXzI.mjs.map → validate-0Utjspbs.mjs.map} +1 -1
  543. package/dist/{validate-cJOiOvT2.d.mts → validate-DOFrIb-c.d.mts} +5 -5
  544. package/dist/{validate-cJOiOvT2.d.mts.map → validate-DOFrIb-c.d.mts.map} +1 -1
  545. package/dist/{validation-DVHjPM1M.mjs → validation-D9EnzH1T.mjs} +6 -6
  546. package/dist/{validation-DVHjPM1M.mjs.map → validation-D9EnzH1T.mjs.map} +1 -1
  547. package/dist/version-BgVM_1MU.mjs +7 -0
  548. package/dist/{version-BOjj_cfz.mjs.map → version-BgVM_1MU.mjs.map} +1 -1
  549. package/dist/{widgets-Ci6hLwfO.mjs → widgets-BSTzPUYa.mjs} +4 -4
  550. package/dist/{widgets-Ci6hLwfO.mjs.map → widgets-BSTzPUYa.mjs.map} +1 -1
  551. package/dist/{zod-generator-CarzgPAu.mjs → zod-generator-ElVQOav7.mjs} +51 -15
  552. package/dist/zod-generator-ElVQOav7.mjs.map +1 -0
  553. package/package.json +19 -6
  554. package/src/api/handlers/api-tokens.ts +19 -0
  555. package/src/api/handlers/comment-reactions.ts +165 -0
  556. package/src/api/handlers/schema.ts +8 -0
  557. package/src/api/schemas/bylines.ts +8 -0
  558. package/src/api/schemas/comments.ts +10 -0
  559. package/src/astro/image-endpoint.ts +84 -0
  560. package/src/astro/index.ts +6 -0
  561. package/src/astro/integration/index.ts +83 -22
  562. package/src/astro/integration/routes.ts +5 -0
  563. package/src/astro/integration/runtime.ts +65 -1
  564. package/src/astro/integration/virtual-modules.ts +40 -0
  565. package/src/astro/integration/vite-config.ts +25 -1
  566. package/src/astro/middleware/auth.ts +4 -3
  567. package/src/astro/middleware/request-context.ts +6 -1
  568. package/src/astro/middleware/scoped-db.ts +131 -0
  569. package/src/astro/middleware/stream-end-metrics.ts +15 -9
  570. package/src/astro/middleware.ts +131 -31
  571. package/src/astro/object-cache/adapters.ts +50 -0
  572. package/src/astro/prefetch.ts +77 -0
  573. package/src/astro/routes/admin.astro +5 -1
  574. package/src/astro/routes/api/comments/[collection]/[contentId]/reactions.ts +97 -0
  575. package/src/astro/routes/api/schema/index.ts +9 -3
  576. package/src/astro/routes/api/setup/dev-bypass.ts +5 -1
  577. package/src/astro/routes/api/snapshot.ts +3 -1
  578. package/src/astro/session-user.ts +57 -0
  579. package/src/astro/types.ts +1 -0
  580. package/src/cli/commands/export-seed.ts +10 -7
  581. package/src/comments/query.ts +78 -7
  582. package/src/comments/ranking.ts +58 -0
  583. package/src/components/Block.astro +71 -0
  584. package/src/components/Comments.astro +136 -1
  585. package/src/components/EmDashMedia.astro +1 -2
  586. package/src/components/Image.astro +36 -2
  587. package/src/components/InlinePortableTextEditor.tsx +10 -2
  588. package/src/components/index.ts +5 -0
  589. package/src/components/portable-text-text-align.ts +38 -0
  590. package/src/content/converters/portable-text-to-prosemirror.ts +5 -1
  591. package/src/content/converters/prosemirror-to-portable-text.ts +8 -0
  592. package/src/content/converters/types.ts +1 -0
  593. package/src/database/instrumentation.ts +21 -1
  594. package/src/database/migrations/044_comment_reactions.ts +56 -0
  595. package/src/database/migrations/runner.ts +2 -0
  596. package/src/database/repositories/byline.ts +27 -0
  597. package/src/database/repositories/comment-reaction.ts +132 -0
  598. package/src/database/repositories/comment.ts +10 -0
  599. package/src/database/repositories/content.ts +25 -3
  600. package/src/database/repositories/menu.ts +13 -1
  601. package/src/database/repositories/seo.ts +3 -0
  602. package/src/database/repositories/taxonomy.ts +13 -1
  603. package/src/database/repositories/types.ts +13 -0
  604. package/src/database/types.ts +9 -0
  605. package/src/emdash-runtime.ts +244 -75
  606. package/src/index.ts +22 -0
  607. package/src/loader.ts +97 -5
  608. package/src/mcp/server.ts +307 -20
  609. package/src/media/image-endpoint.ts +167 -0
  610. package/src/media/local-runtime.ts +18 -5
  611. package/src/menus/index.ts +11 -4
  612. package/src/object-cache/codec.ts +73 -0
  613. package/src/object-cache/index.ts +495 -0
  614. package/src/object-cache/memory.ts +91 -0
  615. package/src/object-cache/types.ts +124 -0
  616. package/src/plugins/adapt-sandbox-entry.ts +11 -1
  617. package/src/plugins/context.ts +94 -22
  618. package/src/plugins/cron.ts +18 -2
  619. package/src/plugins/routes.ts +40 -1
  620. package/src/query.ts +304 -18
  621. package/src/schema/query.ts +11 -4
  622. package/src/schema/zod-generator.ts +53 -8
  623. package/src/settings/index.ts +18 -5
  624. package/src/taxonomies/index.ts +263 -165
  625. package/src/ui.ts +5 -0
  626. package/src/virtual-modules.d.ts +24 -0
  627. package/dist/api-DxjIV2o8.mjs.map +0 -1
  628. package/dist/api-tokens-BFFkB0jB.mjs.map +0 -1
  629. package/dist/byline-V_Qp1Ziw.mjs.map +0 -1
  630. package/dist/byline-fields-CQJRIQkn.d.mts.map +0 -1
  631. package/dist/comment-sqQxNpN3.mjs.map +0 -1
  632. package/dist/content-BIlVx-RX.mjs.map +0 -1
  633. package/dist/context-Cm4pt1Ws.mjs.map +0 -1
  634. package/dist/cron-DdEVrQ2Y.mjs.map +0 -1
  635. package/dist/index-D2VAiumu.d.mts.map +0 -1
  636. package/dist/init-lock-DlBHjf9-.mjs.map +0 -1
  637. package/dist/loader-BqWjcH3h.mjs.map +0 -1
  638. package/dist/menus-DX4_E01q.mjs.map +0 -1
  639. package/dist/menus-Ryk9L7fT.mjs.map +0 -1
  640. package/dist/query-Crm038Mc.mjs.map +0 -1
  641. package/dist/redirects-6Zg2SoYo.mjs.map +0 -1
  642. package/dist/runner--4wMWwKM.mjs.map +0 -1
  643. package/dist/schema-BDOkd3OU.mjs.map +0 -1
  644. package/dist/seo-DpNgGQjF.mjs.map +0 -1
  645. package/dist/settings-BjBsmVAo.mjs.map +0 -1
  646. package/dist/taxonomies-BBxYA38v.mjs.map +0 -1
  647. package/dist/taxonomy-CdllE4oq.mjs.map +0 -1
  648. package/dist/transport-1cIrOb1Y.mjs.map +0 -1
  649. package/dist/types-BTnnBYVX.d.mts.map +0 -1
  650. package/dist/types-BXSUSAjt.mjs.map +0 -1
  651. package/dist/version-BOjj_cfz.mjs +0 -7
  652. package/dist/zod-generator-CarzgPAu.mjs.map +0 -1
  653. /package/dist/{api-tokens-C7ywRx7l.mjs → api-tokens-B4BQybOp.mjs} +0 -0
  654. /package/dist/{ssrf-CRZGzjdL.mjs → ssrf-CcX9zvMK.mjs} +0 -0
  655. /package/dist/{types-BoRm8-pp.mjs → types-BvbeGEtr.mjs} +0 -0
@@ -33,6 +33,9 @@ export const RESOLVED_VIRTUAL_DIALECT_ID = "\0" + VIRTUAL_DIALECT_ID;
33
33
  export const VIRTUAL_STORAGE_ID = "virtual:emdash/storage";
34
34
  export const RESOLVED_VIRTUAL_STORAGE_ID = "\0" + VIRTUAL_STORAGE_ID;
35
35
 
36
+ export const VIRTUAL_OBJECT_CACHE_ID = "virtual:emdash/object-cache";
37
+ export const RESOLVED_VIRTUAL_OBJECT_CACHE_ID = "\0" + VIRTUAL_OBJECT_CACHE_ID;
38
+
36
39
  export const VIRTUAL_ADMIN_REGISTRY_ID = "virtual:emdash/admin-registry";
37
40
  export const RESOLVED_VIRTUAL_ADMIN_REGISTRY_ID = "\0" + VIRTUAL_ADMIN_REGISTRY_ID;
38
41
 
@@ -93,14 +96,21 @@ export function generateDialectModule(opts: {
93
96
  `export const createDialect = undefined;`,
94
97
  `export const dialectType = "sqlite";`,
95
98
  `export const createRequestScopedDb = (_opts) => null;`,
99
+ `export const createCoalescingDialect = undefined;`,
96
100
  ].join("\n");
97
101
  }
98
102
  const type = opts.type ?? "sqlite";
99
103
 
104
+ // Namespace access (not a named re-export) so backends that don't export
105
+ // createCoalescingDialect yield `undefined` rather than a build error.
106
+ const coalescingReExport = `import * as _dialectModule from "${entrypoint}";
107
+ export const createCoalescingDialect = _dialectModule.createCoalescingDialect;`;
108
+
100
109
  if (supportsRequestScope) {
101
110
  return `
102
111
  import { createDialect as _createDialect } from "${entrypoint}";
103
112
  export { createRequestScopedDb } from "${entrypoint}";
113
+ ${coalescingReExport}
104
114
  export const createDialect = _createDialect;
105
115
  export const dialectType = ${JSON.stringify(type)};
106
116
  `;
@@ -108,6 +118,7 @@ export const dialectType = ${JSON.stringify(type)};
108
118
 
109
119
  return `
110
120
  import { createDialect as _createDialect } from "${entrypoint}";
121
+ ${coalescingReExport}
111
122
  export const createDialect = _createDialect;
112
123
  export const dialectType = ${JSON.stringify(type)};
113
124
  export const createRequestScopedDb = (_opts) => null;
@@ -128,6 +139,31 @@ export const createStorage = _createStorage;
128
139
  `;
129
140
  }
130
141
 
142
+ /**
143
+ * Generates the object-cache virtual module.
144
+ *
145
+ * Statically imports the configured object-cache backend's `createObjectCache`
146
+ * factory and embeds its serializable config. When no object cache is
147
+ * configured, exports `undefined` so the runtime read-through layer becomes a
148
+ * transparent passthrough (cache off by default).
149
+ */
150
+ export function generateObjectCacheModule(
151
+ entrypoint?: string,
152
+ config?: Record<string, unknown>,
153
+ ): string {
154
+ if (!entrypoint) {
155
+ return [
156
+ `export const createObjectCache = undefined;`,
157
+ `export const objectCacheConfig = undefined;`,
158
+ ].join("\n");
159
+ }
160
+ return `
161
+ import { createObjectCache as _createObjectCache } from "${entrypoint}";
162
+ export const createObjectCache = _createObjectCache;
163
+ export const objectCacheConfig = ${JSON.stringify(config ?? {})};
164
+ `;
165
+ }
166
+
131
167
  /**
132
168
  * Generates the auth virtual module.
133
169
  * Statically imports the configured auth provider.
@@ -220,6 +256,8 @@ export function generatePluginsModule(descriptors: PluginDescriptor[]): string {
220
256
  storage: descriptor.storage,
221
257
  adminPages: descriptor.adminPages,
222
258
  adminWidgets: descriptor.adminWidgets,
259
+ portableTextBlocks: descriptor.portableTextBlocks,
260
+ fieldWidgets: descriptor.fieldWidgets,
223
261
  })})`,
224
262
  );
225
263
  } else {
@@ -589,6 +627,8 @@ export const sandboxedPlugins = [];
589
627
  storage: ${JSON.stringify(descriptor.storage ?? {})},
590
628
  adminPages: ${JSON.stringify(descriptor.adminPages ?? [])},
591
629
  adminWidgets: ${JSON.stringify(descriptor.adminWidgets ?? [])},
630
+ portableTextBlocks: ${JSON.stringify(descriptor.portableTextBlocks ?? [])},
631
+ fieldWidgets: ${JSON.stringify(descriptor.fieldWidgets ?? [])},
592
632
  adminEntry: ${JSON.stringify(descriptor.adminEntry)},
593
633
  // Code read from: ${filePath}
594
634
  code: ${JSON.stringify(code)},
@@ -22,6 +22,8 @@ import {
22
22
  RESOLVED_VIRTUAL_DIALECT_ID,
23
23
  VIRTUAL_STORAGE_ID,
24
24
  RESOLVED_VIRTUAL_STORAGE_ID,
25
+ VIRTUAL_OBJECT_CACHE_ID,
26
+ RESOLVED_VIRTUAL_OBJECT_CACHE_ID,
25
27
  VIRTUAL_ADMIN_REGISTRY_ID,
26
28
  RESOLVED_VIRTUAL_ADMIN_REGISTRY_ID,
27
29
  VIRTUAL_PLUGINS_ID,
@@ -50,6 +52,7 @@ import {
50
52
  generateConfigModule,
51
53
  generateDialectModule,
52
54
  generateStorageModule,
55
+ generateObjectCacheModule,
53
56
  generateAuthModule,
54
57
  generateAuthProvidersModule,
55
58
  generatePluginsModule,
@@ -176,6 +179,9 @@ export function createVirtualModulesPlugin(options: VitePluginOptions): Plugin {
176
179
  if (id === VIRTUAL_STORAGE_ID) {
177
180
  return RESOLVED_VIRTUAL_STORAGE_ID;
178
181
  }
182
+ if (id === VIRTUAL_OBJECT_CACHE_ID) {
183
+ return RESOLVED_VIRTUAL_OBJECT_CACHE_ID;
184
+ }
179
185
  if (id === VIRTUAL_ADMIN_REGISTRY_ID) {
180
186
  return RESOLVED_VIRTUAL_ADMIN_REGISTRY_ID;
181
187
  }
@@ -227,6 +233,14 @@ export function createVirtualModulesPlugin(options: VitePluginOptions): Plugin {
227
233
  if (id === RESOLVED_VIRTUAL_STORAGE_ID) {
228
234
  return generateStorageModule(resolvedConfig.storage?.entrypoint);
229
235
  }
236
+ // Generate the object-cache module — statically imports the
237
+ // configured backend factory, or exports undefined (cache off).
238
+ if (id === RESOLVED_VIRTUAL_OBJECT_CACHE_ID) {
239
+ return generateObjectCacheModule(
240
+ resolvedConfig.objectCache?.entrypoint,
241
+ resolvedConfig.objectCache?.config,
242
+ );
243
+ }
230
244
  // Generate plugins module that imports and instantiates all plugins
231
245
  if (id === RESOLVED_VIRTUAL_PLUGINS_ID) {
232
246
  return generatePluginsModule(pluginDescriptors);
@@ -293,6 +307,10 @@ export function createVirtualModulesPlugin(options: VitePluginOptions): Plugin {
293
307
  * On Cloudflare, the adapter handles its own externalization — setting
294
308
  * ssr.external there conflicts with @cloudflare/vite-plugin's validation.
295
309
  */
310
+ // Matches the admin stylesheet import with or without a trailing query (e.g.
311
+ // `?url`), so both forms resolve to dist rather than the source alias.
312
+ const ADMIN_STYLES_ALIAS = /^@emdash-cms\/admin\/styles\.css/;
313
+
296
314
  const NODE_NATIVE_EXTERNALS = [
297
315
  "better-sqlite3",
298
316
  "bindings",
@@ -339,8 +357,12 @@ export function createViteConfig(
339
357
  // The styles.css alias must come before the package alias, otherwise
340
358
  // Vite's prefix matching on "@emdash-cms/admin" would resolve
341
359
  // "@emdash-cms/admin/styles.css" through the source directory.
360
+ // Regex (not string) so the `?url` variant — admin.astro imports the
361
+ // stylesheet as `?url` to keep it out of the page CSS graph — also
362
+ // resolves to dist; a string `find` only matches on a `/` or end
363
+ // boundary, so `styles.css?url` would slip through to the source alias.
342
364
  alias: [
343
- { find: "@emdash-cms/admin/styles.css", replacement: resolve(adminDistPath, "styles.css") },
365
+ { find: ADMIN_STYLES_ALIAS, replacement: resolve(adminDistPath, "styles.css") },
344
366
  { find: "@emdash-cms/admin", replacement: useSource ? adminSourcePath : adminDistPath },
345
367
  // `use-sync-external-store/shim` is a React <18 polyfill that ships
346
368
  // only as CJS. It's pulled in transitively by `@tiptap/react`. With
@@ -435,6 +457,8 @@ export function createViteConfig(
435
457
  // Top-level deps (use astro > path for pnpm compat)
436
458
  "astro > zod/v4",
437
459
  "astro > zod/v4/core",
460
+ // zod-generator imports the bare `zod` entry, not `zod/v4`
461
+ "emdash > zod",
438
462
  "@emdash-cms/cloudflare > kysely-d1",
439
463
  // Astro internal deps not covered by @astrojs/cloudflare adapter
440
464
  "astro/virtual-modules/middleware.js",
@@ -32,6 +32,7 @@ import { resolveApiToken, resolveOAuthToken } from "../../api/handlers/api-token
32
32
  import { hasScope } from "../../auth/api-tokens.js";
33
33
  import { getAuthMode, type ExternalAuthMode } from "../../auth/mode.js";
34
34
  import type { ExternalAuthConfig } from "../../auth/types.js";
35
+ import { resolveSessionUser } from "../session-user.js";
35
36
  import type { EmDashHandlers } from "../types.js";
36
37
  import { buildEmDashCsp } from "./csp.js";
37
38
 
@@ -407,7 +408,7 @@ async function handlePluginRouteAuth(
407
408
  try {
408
409
  // Try session auth (sets locals.user if session exists)
409
410
  const { session } = context;
410
- const sessionUser = await session?.get("user");
411
+ const sessionUser = await resolveSessionUser(session);
411
412
  if (sessionUser?.id && emdash?.db) {
412
413
  const adapter = createKyselyAdapter(emdash.db);
413
414
  const user = await adapter.getUserById(sessionUser.id);
@@ -435,7 +436,7 @@ async function handlePublicRouteAuth(
435
436
  const { emdash } = locals;
436
437
 
437
438
  try {
438
- const sessionUser = await session?.get("user");
439
+ const sessionUser = await resolveSessionUser(session);
439
440
  if (sessionUser?.id && emdash?.db) {
440
441
  const adapter = createKyselyAdapter(emdash.db);
441
442
  const user = await adapter.getUserById(sessionUser.id);
@@ -650,7 +651,7 @@ async function handlePasskeyAuth(
650
651
 
651
652
  try {
652
653
  // Check session for user (session.get returns a Promise)
653
- const sessionUser = await session?.get("user");
654
+ const sessionUser = await resolveSessionUser(session);
654
655
 
655
656
  if (!sessionUser?.id) {
656
657
  if (isApiRoute) {
@@ -30,10 +30,15 @@ async function injectToolbar(response: Response, toolbarHtml: string): Promise<R
30
30
  if (!html.includes("</body>")) return new Response(html, response);
31
31
 
32
32
  const injected = html.replace("</body>", `${toolbarHtml}</body>`);
33
- return new Response(injected, {
33
+ const result = new Response(injected, {
34
34
  status: response.status,
35
35
  headers: response.headers,
36
36
  });
37
+ // Toolbar-injected HTML is session-specific (its presence reveals an active
38
+ // editor session); it must never be stored in a shared CDN cache and served
39
+ // to anonymous visitors. Mirrors the preview branch's guard (#1398).
40
+ result.headers.set("Cache-Control", "private, no-store");
41
+ return result;
37
42
  }
38
43
 
39
44
  export const onRequest = defineMiddleware(async (context, next) => {
@@ -0,0 +1,131 @@
1
+ /**
2
+ * Request-scoped database lifecycle helpers.
3
+ *
4
+ * Extracted from middleware.ts so they can be unit-tested without pulling in
5
+ * the virtual:emdash/* module graph. The middleware imports these to settle a
6
+ * request-scoped db adapter's lifecycle around the response.
7
+ */
8
+
9
+ /**
10
+ * Astro attaches AstroCookies to outgoing responses via a well-known global
11
+ * symbol. Cloning a Response (`new Response(body, init)`) drops non-header
12
+ * metadata, so any helper that wraps the response must explicitly forward this
13
+ * symbol or `cookies.set()` calls will be silently dropped. `Symbol.for`
14
+ * returns the same registry symbol everywhere, so this matches the copy in
15
+ * middleware.ts.
16
+ */
17
+ export const ASTRO_COOKIES_SYMBOL = Symbol.for("astro.cookies");
18
+
19
+ /**
20
+ * Run a request-scoped db's `close()` once the response body has finished
21
+ * streaming. Astro streams HTML and components issue DB queries during that
22
+ * stream, so a connection-backed adapter (e.g. Postgres over Hyperdrive) must
23
+ * not be torn down until the body is flushed. Bodyless responses (redirects,
24
+ * 304s, errors) close immediately. A guard makes close idempotent and a stream
25
+ * `cancel` (client disconnect) still triggers it so connections never leak.
26
+ *
27
+ * No-op for adapters without a `close` (D1): the response passes through.
28
+ */
29
+ export function wrapResponseForScopedClose(response: Response, close: () => void): Response {
30
+ let closed = false;
31
+ const runClose = () => {
32
+ if (closed) return;
33
+ closed = true;
34
+ try {
35
+ close();
36
+ } catch (error) {
37
+ console.error("[emdash] request-scoped db close failed:", error);
38
+ }
39
+ };
40
+
41
+ if (!response.body) {
42
+ runClose();
43
+ return response;
44
+ }
45
+
46
+ const transform = new TransformStream<Uint8Array, Uint8Array>({
47
+ flush: runClose,
48
+ cancel: runClose,
49
+ });
50
+ const wrapped = new Response(response.body.pipeThrough(transform), response);
51
+ const astroCookies = Reflect.get(response, ASTRO_COOKIES_SYMBOL);
52
+ if (astroCookies !== undefined) {
53
+ Reflect.set(wrapped, ASTRO_COOKIES_SYMBOL, astroCookies);
54
+ }
55
+ // Byte counts are preserved by the identity transform, but a stale
56
+ // Content-Length on a reconstructed streaming Response risks truncation.
57
+ wrapped.headers.delete("Content-Length");
58
+ return wrapped;
59
+ }
60
+
61
+ /**
62
+ * Run the request body under a request-scoped db, then settle its lifecycle:
63
+ * `commit()` runs before the response is returned (so per-request state like a
64
+ * D1 bookmark cookie is persisted in the headers, even if render throws), while
65
+ * `close()` (if any) is deferred to stream-end so a connection-backed adapter
66
+ * isn't torn down mid-render. On error the connection is closed immediately
67
+ * before rethrowing so it never leaks.
68
+ *
69
+ * On the error path both `commit()` and `close()` are defended: a throw from
70
+ * either is logged and swallowed so it can't replace the propagating render
71
+ * error (which is the one the caller needs to see). On the success path
72
+ * `commit()` is guarded too — if it throws, the connection is closed before the
73
+ * failure is surfaced, so it never leaks. For the current adapters `commit()`
74
+ * is a no-op (Hyperdrive) or a cookie write (D1, no `close`) and `close()` is
75
+ * fire-and-forget, so these guards only matter for a future connection-backed
76
+ * adapter with throwing teardown, but the helper is generic and must not leak
77
+ * or mask.
78
+ */
79
+ export async function finishScoped(
80
+ scoped: { commit: () => void; close?: () => void },
81
+ run: () => Promise<Response>,
82
+ ): Promise<Response> {
83
+ let response: Response;
84
+ try {
85
+ response = await run();
86
+ } catch (error) {
87
+ // A render error is already propagating; neither commit nor close may
88
+ // mask it, and close must still run so the connection doesn't leak.
89
+ commitSafely(scoped.commit);
90
+ closeSafely(scoped.close);
91
+ throw error;
92
+ }
93
+ try {
94
+ scoped.commit();
95
+ } catch (error) {
96
+ // commit() failed on the success path: close the connection now (the
97
+ // response won't be wrapped, so stream-end close would never run) and
98
+ // surface the failure. close is swallowed so it can't mask the commit
99
+ // error that the caller needs to see.
100
+ closeSafely(scoped.close);
101
+ throw error;
102
+ }
103
+ return scoped.close ? wrapResponseForScopedClose(response, scoped.close) : response;
104
+ }
105
+
106
+ /**
107
+ * Run commit() swallowing any error. Used where an exception is already
108
+ * propagating (or about to be thrown) and a commit failure must neither mask it
109
+ * nor skip the subsequent close().
110
+ */
111
+ function commitSafely(commit: () => void): void {
112
+ try {
113
+ commit();
114
+ } catch (error) {
115
+ console.error("[emdash] request-scoped db commit failed during error handling:", error);
116
+ }
117
+ }
118
+
119
+ /**
120
+ * Run close() swallowing any error. Used on the error/commit-failure paths
121
+ * where another exception is the one the caller must see; a throwing teardown
122
+ * must not replace it.
123
+ */
124
+ function closeSafely(close: (() => void) | undefined): void {
125
+ if (!close) return;
126
+ try {
127
+ close();
128
+ } catch (error) {
129
+ console.error("[emdash] request-scoped db close failed during error handling:", error);
130
+ }
131
+ }
@@ -18,19 +18,15 @@
18
18
  * in normal production traffic.
19
19
  */
20
20
 
21
- import { isInstrumentationEnabled } from "../../database/instrumentation.js";
21
+ import { flushRecorder, isInstrumentationEnabled } from "../../database/instrumentation.js";
22
22
  import { getRequestContext } from "../../request-context.js";
23
+ // Reuse the single source of truth for Astro's well-known cookies symbol
24
+ // rather than redefining `Symbol.for("astro.cookies")` here — it must stay in
25
+ // lockstep with the copy the rest of the middleware forwards.
26
+ import { ASTRO_COOKIES_SYMBOL } from "./scoped-db.js";
23
27
 
24
28
  export const STREAM_END_PREFIX = "[emdash-stream-end]";
25
29
 
26
- /**
27
- * Astro attaches AstroCookies to outgoing responses via a well-known global
28
- * symbol. Constructing a new Response drops non-header metadata, so the
29
- * symbol must be forwarded explicitly or `cookies.set()` calls are silently
30
- * dropped. Same pattern as finalizeResponse in ../middleware.ts.
31
- */
32
- const ASTRO_COOKIES_SYMBOL = Symbol.for("astro.cookies");
33
-
34
30
  /** Shape of the NDJSON snapshot emitted when the body finishes streaming. */
35
31
  export interface StreamEndSnapshot {
36
32
  route?: string;
@@ -64,6 +60,14 @@ export function wrapBodyForStreamMetrics(response: Response): Response {
64
60
  if (!metrics) return response;
65
61
  const recorder = ctx?.queryRecorder;
66
62
 
63
+ // Claim the per-query flush: the recorder is mutated in-place by the
64
+ // Kysely log hook for the whole request, including queries issued by
65
+ // components while the body streams. Flushing here (rather than when
66
+ // middleware returns) is what captures those streaming queries. The
67
+ // flag tells the middleware's fallback flush to leave this recorder
68
+ // to us.
69
+ if (recorder) recorder.deferredFlush = true;
70
+
67
71
  const transform = new TransformStream<Uint8Array, Uint8Array>({
68
72
  flush() {
69
73
  const snapshot: StreamEndSnapshot = {
@@ -79,6 +83,8 @@ export function wrapBodyForStreamMetrics(response: Response): Response {
79
83
  cacheMisses: metrics.cacheMisses,
80
84
  };
81
85
  console.log(`${STREAM_END_PREFIX} ${JSON.stringify(snapshot)}`);
86
+ // Emit the full per-query log now that streaming is complete.
87
+ if (recorder) flushRecorder(recorder);
82
88
  },
83
89
  });
84
90
 
@@ -12,6 +12,7 @@ import type { Kysely } from "kysely";
12
12
  import virtualConfig from "virtual:emdash/config";
13
13
  // @ts-ignore - virtual module
14
14
  import {
15
+ createCoalescingDialect as virtualCreateCoalescingDialect,
15
16
  createDialect as virtualCreateDialect,
16
17
  createRequestScopedDb as virtualCreateRequestScopedDb,
17
18
  } from "virtual:emdash/dialect";
@@ -59,8 +60,11 @@ import type { PublishedRef } from "../scheduled-publish.js";
59
60
  import { isMissingTableError } from "../utils/db-errors.js";
60
61
  import { createInitLock, type InitLock, initWithLock } from "../utils/init-lock.js";
61
62
  import type { EmDashConfig } from "./integration/runtime.js";
63
+ import { ASTRO_COOKIES_SYMBOL, finishScoped } from "./middleware/scoped-db.js";
62
64
  import { wrapBodyForStreamMetrics } from "./middleware/stream-end-metrics.js";
65
+ import { prefetchLayoutData } from "./prefetch.js";
63
66
  import { createPublicPluginApiRouteHandler } from "./public-plugin-api-routes.js";
67
+ import { resolveSessionUser } from "./session-user.js";
64
68
  import type { EmDashHandlers } from "./types.js";
65
69
 
66
70
  /**
@@ -177,6 +181,10 @@ function buildDependencies(config: EmDashConfig): RuntimeDependencies {
177
181
  config,
178
182
  plugins: getPlugins(),
179
183
  createDialect: virtualCreateDialect as (config: Record<string, unknown>) => unknown,
184
+ // Optional: only batching backends (D1, DO) export this; undefined otherwise.
185
+ createCoalescingDialect: virtualCreateCoalescingDialect as
186
+ | ((config: Record<string, unknown>) => unknown)
187
+ | undefined,
180
188
  createStorage: virtualCreateStorage as ((config: Record<string, unknown>) => Storage) | null,
181
189
  createScheduler: virtualCreateScheduler as CreateSchedulerFn | null,
182
190
  sandboxEnabled: sandboxModule.sandboxEnabled as boolean,
@@ -268,16 +276,71 @@ export async function runScheduledTasks(
268
276
  const config = getConfig();
269
277
  if (!config) return { published: [] };
270
278
  const runtime = await getRuntime(config);
271
- return runtime.runScheduledTasks(options);
279
+
280
+ // Connection-backed adapters (e.g. Postgres over Hyperdrive) cannot reuse
281
+ // the per-isolate singleton from a Cron Trigger: its socket belongs to the
282
+ // request that opened it, and workerd rejects cross-event I/O. Open an
283
+ // event-scoped connection for the sweep and run the batch under it in ALS —
284
+ // the runtime's db getter, the cron executor, and plugin cron contexts all
285
+ // resolve the connection from ALS — then close it. Gated on the adapter
286
+ // being connection-backed (it exposes `close()`); stateless adapters (D1,
287
+ // Node SQLite) return null or a close-less scope and keep using the
288
+ // singleton, so their cron path is unchanged.
289
+ const scoped = createRequestScopedDb({
290
+ config: config.database?.config,
291
+ isAuthenticated: false,
292
+ // The sweep publishes and cleans up — a write workload — so a
293
+ // connection-backed adapter routes it to the primary.
294
+ isWrite: true,
295
+ cookies: NOOP_COOKIE_JAR,
296
+ url: CRON_EVENT_URL,
297
+ });
298
+ if (!scoped?.close) {
299
+ // Stateless adapter (or no per-request scoping): the singleton is safe
300
+ // outside a request. Any close-less scope created above is discarded.
301
+ return runtime.runScheduledTasks(options);
302
+ }
303
+
304
+ const parent = getRequestContext();
305
+ const ctx = parent
306
+ ? { ...parent, db: scoped.db }
307
+ : { editMode: false, db: scoped.db, metrics: createRequestMetrics(performance.now()) };
308
+ try {
309
+ return await runWithContext(ctx, () => runtime.runScheduledTasks(options));
310
+ } finally {
311
+ // Guard both so a throw in teardown can't mask the sweep result or skip
312
+ // close() and leak the connection. Mirrors closeSafely() in scoped-db.ts.
313
+ try {
314
+ scoped.commit();
315
+ } catch (error) {
316
+ console.error("[scheduled] request-scoped db commit failed:", error);
317
+ }
318
+ try {
319
+ scoped.close();
320
+ } catch (error) {
321
+ console.error("[scheduled] request-scoped db close failed:", error);
322
+ }
323
+ }
272
324
  }
273
325
 
274
326
  /**
275
- * Astro attaches AstroCookies to outgoing responses via a well-known global
276
- * symbol. Cloning a Response (`new Response(body, init)`) drops non-header
277
- * metadata, so any middleware that wraps the response must explicitly forward
278
- * this symbol or `cookies.set()` calls will be silently dropped.
327
+ * A cookie jar that reads nothing and writes nothing, for request-scoped db
328
+ * adapters invoked outside an HTTP request (the Cron Trigger sweep). Connection
329
+ * adapters like Hyperdrive ignore cookies entirely; the D1 session adapter
330
+ * reads/writes a bookmark cookie, but cron never reaches that path (it has no
331
+ * `close()`), so the no-ops are never observed.
279
332
  */
280
- const ASTRO_COOKIES_SYMBOL = Symbol.for("astro.cookies");
333
+ const NOOP_COOKIE_JAR = {
334
+ get: () => undefined,
335
+ set: () => {},
336
+ };
337
+
338
+ /**
339
+ * Synthetic URL for the cron sweep's request-scoped db opts. Only the D1
340
+ * session adapter inspects `url` (for cookie `secure`), and cron doesn't take
341
+ * that path, so the value is never used — it exists to satisfy the contract.
342
+ */
343
+ const CRON_EVENT_URL = new URL("https://cron.emdash.internal/");
281
344
 
282
345
  /**
283
346
  * Baseline security headers applied to all responses.
@@ -354,12 +417,12 @@ const SITEMAP_COLLECTION_RE = /^\/sitemap-[a-z][a-z0-9_]*\.xml$/;
354
417
  */
355
418
  function createRequestScopedDb(
356
419
  opts: RequestScopedDbOpts,
357
- ): { db: Kysely<Database>; commit: () => void } | null {
420
+ ): { db: Kysely<Database>; commit: () => void; close?: () => void } | null {
358
421
  if (typeof virtualCreateRequestScopedDb !== "function") return null;
359
422
  // eslint-disable-next-line typescript/no-unsafe-type-assertion -- adapter returns Kysely<unknown>; cast to Database since core owns that type
360
423
  const fn = virtualCreateRequestScopedDb as (
361
424
  o: RequestScopedDbOpts,
362
- ) => { db: Kysely<Database>; commit: () => void } | null;
425
+ ) => { db: Kysely<Database>; commit: () => void; close?: () => void } | null;
363
426
  return fn(opts);
364
427
  }
365
428
 
@@ -415,7 +478,7 @@ export const onRequest = defineMiddleware(async (context, next) => {
415
478
  // turns normal traffic into a flood of KV read misses. See #733.
416
479
  const hasSessionCookie = cookies.get("astro-session") !== undefined;
417
480
  const sessionUser =
418
- context.isPrerendered || !hasSessionCookie ? null : await context.session?.get("user");
481
+ context.isPrerendered || !hasSessionCookie ? null : await resolveSessionUser(context.session);
419
482
 
420
483
  if (!isEmDashRoute && !isPublicRuntimeRoute && !hasEditCookie && !hasPreviewToken) {
421
484
  if (!sessionUser && !playgroundDb) {
@@ -428,7 +491,13 @@ export const onRequest = defineMiddleware(async (context, next) => {
428
491
  // Do a one-time lightweight probe using the same getDb() instance the
429
492
  // page will use: if the migrations table doesn't exist, no migrations
430
493
  // have ever run -- redirect to the setup wizard.
431
- if (!isSetupVerified()) {
494
+ // Skip the probe when prerendering: a prerendered route is built to
495
+ // static HTML, so returning context.redirect("/_emdash/admin/setup")
496
+ // below would bake that redirect into the page and ship it to
497
+ // production. The build database is legitimately empty in CI and there
498
+ // is no live visitor to send to the wizard at build time (session reads
499
+ // are already skipped for prerender above for the same reason).
500
+ if (!isSetupVerified() && !context.isPrerendered) {
432
501
  const t0 = performance.now();
433
502
  try {
434
503
  const { getDb } = await import("../loader.js");
@@ -475,6 +544,10 @@ export const onRequest = defineMiddleware(async (context, next) => {
475
544
  collectPageMetadata: runtime.collectPageMetadata.bind(runtime),
476
545
  collectPageFragments: runtime.collectPageFragments.bind(runtime),
477
546
  getPublicMediaUrl: createPublicMediaUrlResolver(runtime.storage),
547
+ // Exposed so the wrapped image endpoint (`/_image`) can read media
548
+ // bytes from storage on the anonymous fast path -- public `<img>`
549
+ // requests carry no session.
550
+ storage: runtime.storage,
478
551
  } as EmDashHandlers;
479
552
  } catch {
480
553
  // Non-fatal — EmDashHead will fall back to base SEO contributions
@@ -512,16 +585,32 @@ export const onRequest = defineMiddleware(async (context, next) => {
512
585
  const ctx = parent
513
586
  ? { ...parent, db: anonScoped.db }
514
587
  : { editMode: false, db: anonScoped.db, metrics };
588
+ // Eagerly warm site-global layout data (menus, widget areas,
589
+ // taxonomy terms, settings) concurrently so the layout's
590
+ // per-component reads overlap into ~one wall-clock round trip and
591
+ // hit a warm cache instead of serializing. Three guards:
592
+ // - request-scoped (remote) backend only -- this branch implies it;
593
+ // pointless on synchronous local SQLite.
594
+ // - HTML navigations only -- feeds/sitemaps/JSON don't render the
595
+ // layout, so prefetching their chrome is pure waste.
596
+ // - via after(): it runs immediately (still warms the render) but
597
+ // hands the promise to waitUntil, so the surplus warm-up (chrome a
598
+ // given page doesn't render) is kept alive past the response rather
599
+ // than erroring on workerd as orphaned request I/O.
600
+ // Gate on the CLIENT'S PREFERRED type (leading media range), not a
601
+ // substring -- browser navigations lead with `text/html`, while feed
602
+ // readers lead with `application/rss+xml` etc. and only list
603
+ // `text/html;q=0.8` later, so a substring match would leak onto feeds.
604
+ const acceptsHtml = (request.headers.get("accept") ?? "")
605
+ .split(",", 1)[0]!
606
+ .trim()
607
+ .startsWith("text/html");
515
608
  return runWithContext(ctx, async () => {
516
- // commit() in finally: the write reached the primary independently
517
- // of render, so the bookmark cookie must be persisted even if
518
- // render throws -- otherwise a write-then-failed-render leaves the
519
- // next request able to read pre-write state off a lagging replica.
520
- try {
521
- return await runAnon();
522
- } finally {
523
- anonScoped.commit();
524
- }
609
+ if (acceptsHtml) after(() => prefetchLayoutData());
610
+ // commit() persists per-request state (e.g. the D1 bookmark cookie)
611
+ // before the response is returned, even if render throws; close()
612
+ // (connection teardown) is deferred to stream-end. See finishScoped.
613
+ return finishScoped(anonScoped, runAnon);
525
614
  });
526
615
  }
527
616
  return runAnon();
@@ -625,7 +714,17 @@ export const onRequest = defineMiddleware(async (context, next) => {
625
714
 
626
715
  // Direct access (for advanced use cases)
627
716
  storage: runtime.storage,
628
- db: runtime.db,
717
+ // Lazy getter, not an eager snapshot: `locals.emdash` is built
718
+ // before the per-request scoped db is installed in ALS, so reading
719
+ // `runtime.db` here would capture the per-isolate singleton. Routes
720
+ // access `emdash.db` later, during the request, when the scoped db
721
+ // is active. For a stateless binding (D1) the two are equivalent,
722
+ // but for a request-bound connection (pg/Hyperdrive) the singleton
723
+ // belongs to the cold-start request and reusing it from a warm
724
+ // request hangs on workerd's cross-request I/O guard.
725
+ get db() {
726
+ return runtime.db;
727
+ },
629
728
  getPublicMediaUrl: createPublicMediaUrlResolver(runtime.storage),
630
729
  hooks: runtime.hooks,
631
730
  email: runtime.email,
@@ -689,16 +788,12 @@ export const onRequest = defineMiddleware(async (context, next) => {
689
788
  const ctx = parent
690
789
  ? { ...parent, db: scoped.db }
691
790
  : { editMode: false, db: scoped.db, metrics };
692
- return runWithContext(ctx, async () => {
693
- // commit() in finally: persist the bookmark cookie even if render
694
- // throws -- the write already reached the primary, so a failed
695
- // render must not strand the next request on a stale replica read.
696
- try {
697
- return await renderAndFinalize();
698
- } finally {
699
- scoped.commit();
700
- }
701
- });
791
+ return runWithContext(ctx, () =>
792
+ // commit() persists per-request state (e.g. the D1 bookmark cookie)
793
+ // before the response returns, even if render throws; close()
794
+ // (connection teardown) is deferred to stream-end. See finishScoped.
795
+ finishScoped(scoped, renderAndFinalize),
796
+ );
702
797
  }
703
798
 
704
799
  return renderAndFinalize();
@@ -723,7 +818,12 @@ export const onRequest = defineMiddleware(async (context, next) => {
723
818
  try {
724
819
  return await runWithContext({ editMode: false, queryRecorder, metrics }, run);
725
820
  } finally {
726
- if (queryRecorder) flushRecorder(queryRecorder);
821
+ // Streamed responses defer the flush to stream end (see
822
+ // wrapBodyForStreamMetrics) so the log captures queries issued while
823
+ // the body renders. Only flush here for responses that were not
824
+ // wrapped (no body: redirects, 304s, bodyless errors), where all
825
+ // queries have already run by the time middleware returns.
826
+ if (queryRecorder && !queryRecorder.deferredFlush) flushRecorder(queryRecorder);
727
827
  }
728
828
  });
729
829