emdash 0.21.0 → 0.22.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 (620) hide show
  1. package/dist/{adapters-BxSmgtbF.d.mts → adapters-hUy8vOB-.d.mts} +1 -1
  2. package/dist/{adapters-BxSmgtbF.d.mts.map → adapters-hUy8vOB-.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-DjlhyfNN.mjs} +2 -2
  6. package/dist/{allowed-origins-BqC8cul8.mjs.map → allowed-origins-DjlhyfNN.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-BDuM4bEy.mjs} +31 -25
  13. package/dist/api-BDuM4bEy.mjs.map +1 -0
  14. package/dist/{api-tokens-BFFkB0jB.mjs → api-tokens-ViYKeIp9.mjs} +13 -3
  15. package/dist/api-tokens-ViYKeIp9.mjs.map +1 -0
  16. package/dist/{apply-CLjxheyb.mjs → apply-wDqQoxX4.mjs} +18 -18
  17. package/dist/{apply-CLjxheyb.mjs.map → apply-wDqQoxX4.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 +114 -24
  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.mjs +5 -5
  32. package/dist/astro/middleware/setup.mjs +1 -1
  33. package/dist/astro/middleware.d.mts +1 -1
  34. package/dist/astro/middleware.d.mts.map +1 -1
  35. package/dist/astro/middleware.mjs +153 -79
  36. package/dist/astro/middleware.mjs.map +1 -1
  37. package/dist/astro/routes/api/admin/allowed-domains/_domain_.mjs +7 -7
  38. package/dist/astro/routes/api/admin/allowed-domains/index.mjs +7 -7
  39. package/dist/astro/routes/api/admin/api-tokens/_id_.mjs +5 -5
  40. package/dist/astro/routes/api/admin/api-tokens/index.mjs +6 -6
  41. package/dist/astro/routes/api/admin/byline-fields/_slug_/usage.mjs +6 -6
  42. package/dist/astro/routes/api/admin/byline-fields/_slug_.mjs +10 -10
  43. package/dist/astro/routes/api/admin/byline-fields/index.mjs +10 -10
  44. package/dist/astro/routes/api/admin/byline-fields/reorder.mjs +10 -10
  45. package/dist/astro/routes/api/admin/bylines/_id_/index.mjs +17 -16
  46. package/dist/astro/routes/api/admin/bylines/_id_/index.mjs.map +1 -1
  47. package/dist/astro/routes/api/admin/bylines/_id_/translations.mjs +17 -16
  48. package/dist/astro/routes/api/admin/bylines/_id_/translations.mjs.map +1 -1
  49. package/dist/astro/routes/api/admin/bylines/index.mjs +17 -16
  50. package/dist/astro/routes/api/admin/bylines/index.mjs.map +1 -1
  51. package/dist/astro/routes/api/admin/comments/_id_/status.mjs +15 -13
  52. package/dist/astro/routes/api/admin/comments/_id_/status.mjs.map +1 -1
  53. package/dist/astro/routes/api/admin/comments/_id_.mjs +8 -6
  54. package/dist/astro/routes/api/admin/comments/_id_.mjs.map +1 -1
  55. package/dist/astro/routes/api/admin/comments/bulk.mjs +12 -10
  56. package/dist/astro/routes/api/admin/comments/bulk.mjs.map +1 -1
  57. package/dist/astro/routes/api/admin/comments/counts.mjs +8 -6
  58. package/dist/astro/routes/api/admin/comments/counts.mjs.map +1 -1
  59. package/dist/astro/routes/api/admin/comments/index.mjs +12 -10
  60. package/dist/astro/routes/api/admin/comments/index.mjs.map +1 -1
  61. package/dist/astro/routes/api/admin/hooks/exclusive/_hookName_.mjs +6 -6
  62. package/dist/astro/routes/api/admin/hooks/exclusive/index.mjs +5 -5
  63. package/dist/astro/routes/api/admin/oauth-clients/_id_.mjs +5 -5
  64. package/dist/astro/routes/api/admin/oauth-clients/index.mjs +5 -5
  65. package/dist/astro/routes/api/admin/plugins/_id_/disable.mjs +40 -39
  66. package/dist/astro/routes/api/admin/plugins/_id_/disable.mjs.map +1 -1
  67. package/dist/astro/routes/api/admin/plugins/_id_/enable.mjs +40 -39
  68. package/dist/astro/routes/api/admin/plugins/_id_/enable.mjs.map +1 -1
  69. package/dist/astro/routes/api/admin/plugins/_id_/index.mjs +39 -38
  70. package/dist/astro/routes/api/admin/plugins/_id_/index.mjs.map +1 -1
  71. package/dist/astro/routes/api/admin/plugins/_id_/uninstall.mjs +39 -38
  72. package/dist/astro/routes/api/admin/plugins/_id_/uninstall.mjs.map +1 -1
  73. package/dist/astro/routes/api/admin/plugins/_id_/update.mjs +39 -38
  74. package/dist/astro/routes/api/admin/plugins/_id_/update.mjs.map +1 -1
  75. package/dist/astro/routes/api/admin/plugins/index.mjs +39 -38
  76. package/dist/astro/routes/api/admin/plugins/index.mjs.map +1 -1
  77. package/dist/astro/routes/api/admin/plugins/marketplace/_id_/icon.mjs +4 -4
  78. package/dist/astro/routes/api/admin/plugins/marketplace/_id_/index.mjs +39 -38
  79. package/dist/astro/routes/api/admin/plugins/marketplace/_id_/index.mjs.map +1 -1
  80. package/dist/astro/routes/api/admin/plugins/marketplace/_id_/install.mjs +39 -38
  81. package/dist/astro/routes/api/admin/plugins/marketplace/_id_/install.mjs.map +1 -1
  82. package/dist/astro/routes/api/admin/plugins/marketplace/index.mjs +39 -38
  83. package/dist/astro/routes/api/admin/plugins/marketplace/index.mjs.map +1 -1
  84. package/dist/astro/routes/api/admin/plugins/registry/_id_/uninstall.mjs +39 -38
  85. package/dist/astro/routes/api/admin/plugins/registry/_id_/uninstall.mjs.map +1 -1
  86. package/dist/astro/routes/api/admin/plugins/registry/_id_/update.mjs +40 -39
  87. package/dist/astro/routes/api/admin/plugins/registry/_id_/update.mjs.map +1 -1
  88. package/dist/astro/routes/api/admin/plugins/registry/artifact.mjs +39 -38
  89. package/dist/astro/routes/api/admin/plugins/registry/artifact.mjs.map +1 -1
  90. package/dist/astro/routes/api/admin/plugins/registry/install.mjs +40 -39
  91. package/dist/astro/routes/api/admin/plugins/registry/install.mjs.map +1 -1
  92. package/dist/astro/routes/api/admin/plugins/updates.mjs +39 -38
  93. package/dist/astro/routes/api/admin/plugins/updates.mjs.map +1 -1
  94. package/dist/astro/routes/api/admin/themes/marketplace/_id_/index.mjs +39 -38
  95. package/dist/astro/routes/api/admin/themes/marketplace/_id_/index.mjs.map +1 -1
  96. package/dist/astro/routes/api/admin/themes/marketplace/_id_/thumbnail.mjs +4 -4
  97. package/dist/astro/routes/api/admin/themes/marketplace/index.mjs +39 -38
  98. package/dist/astro/routes/api/admin/themes/marketplace/index.mjs.map +1 -1
  99. package/dist/astro/routes/api/admin/users/_id_/disable.mjs +4 -4
  100. package/dist/astro/routes/api/admin/users/_id_/enable.mjs +3 -3
  101. package/dist/astro/routes/api/admin/users/_id_/index.mjs +8 -8
  102. package/dist/astro/routes/api/admin/users/_id_/send-recovery.mjs +5 -5
  103. package/dist/astro/routes/api/admin/users/index.mjs +7 -7
  104. package/dist/astro/routes/api/auth/dev-bypass.mjs +6 -6
  105. package/dist/astro/routes/api/auth/invite/accept.mjs +3 -3
  106. package/dist/astro/routes/api/auth/invite/complete.mjs +12 -12
  107. package/dist/astro/routes/api/auth/invite/index.mjs +9 -9
  108. package/dist/astro/routes/api/auth/invite/register-options.mjs +11 -11
  109. package/dist/astro/routes/api/auth/logout.mjs +4 -4
  110. package/dist/astro/routes/api/auth/magic-link/send.mjs +11 -11
  111. package/dist/astro/routes/api/auth/magic-link/verify.mjs +4 -4
  112. package/dist/astro/routes/api/auth/me.mjs +8 -8
  113. package/dist/astro/routes/api/auth/mode.mjs +1 -1
  114. package/dist/astro/routes/api/auth/oauth/_provider_/callback.mjs +4 -4
  115. package/dist/astro/routes/api/auth/oauth/_provider_.mjs +2 -2
  116. package/dist/astro/routes/api/auth/passkey/_id_.mjs +7 -7
  117. package/dist/astro/routes/api/auth/passkey/index.mjs +3 -3
  118. package/dist/astro/routes/api/auth/passkey/options.mjs +13 -13
  119. package/dist/astro/routes/api/auth/passkey/register/options.mjs +11 -11
  120. package/dist/astro/routes/api/auth/passkey/register/verify.mjs +12 -12
  121. package/dist/astro/routes/api/auth/passkey/verify.mjs +12 -12
  122. package/dist/astro/routes/api/auth/signup/complete.mjs +12 -12
  123. package/dist/astro/routes/api/auth/signup/request.mjs +11 -11
  124. package/dist/astro/routes/api/auth/signup/verify.mjs +3 -3
  125. package/dist/astro/routes/api/comments/_collection_/_contentId_/index.mjs +16 -15
  126. package/dist/astro/routes/api/comments/_collection_/_contentId_/index.mjs.map +1 -1
  127. package/dist/astro/routes/api/comments/_collection_/_contentId_/reactions.d.mts +9 -0
  128. package/dist/astro/routes/api/comments/_collection_/_contentId_/reactions.d.mts.map +1 -0
  129. package/dist/astro/routes/api/comments/_collection_/_contentId_/reactions.mjs +179 -0
  130. package/dist/astro/routes/api/comments/_collection_/_contentId_/reactions.mjs.map +1 -0
  131. package/dist/astro/routes/api/content/_collection_/_id_/compare.mjs +4 -4
  132. package/dist/astro/routes/api/content/_collection_/_id_/discard-draft.mjs +4 -4
  133. package/dist/astro/routes/api/content/_collection_/_id_/duplicate.mjs +4 -4
  134. package/dist/astro/routes/api/content/_collection_/_id_/permanent.mjs +4 -4
  135. package/dist/astro/routes/api/content/_collection_/_id_/preview-url.mjs +13 -13
  136. package/dist/astro/routes/api/content/_collection_/_id_/publish.mjs +8 -8
  137. package/dist/astro/routes/api/content/_collection_/_id_/restore.mjs +4 -4
  138. package/dist/astro/routes/api/content/_collection_/_id_/revisions.mjs +4 -4
  139. package/dist/astro/routes/api/content/_collection_/_id_/schedule.mjs +8 -8
  140. package/dist/astro/routes/api/content/_collection_/_id_/terms/_taxonomy_.mjs +17 -15
  141. package/dist/astro/routes/api/content/_collection_/_id_/terms/_taxonomy_.mjs.map +1 -1
  142. package/dist/astro/routes/api/content/_collection_/_id_/translations.mjs +4 -4
  143. package/dist/astro/routes/api/content/_collection_/_id_/unpublish.mjs +4 -4
  144. package/dist/astro/routes/api/content/_collection_/_id_.mjs +8 -8
  145. package/dist/astro/routes/api/content/_collection_/authors.mjs +4 -4
  146. package/dist/astro/routes/api/content/_collection_/index.mjs +8 -8
  147. package/dist/astro/routes/api/content/_collection_/trash.mjs +8 -8
  148. package/dist/astro/routes/api/dashboard.mjs +10 -8
  149. package/dist/astro/routes/api/dashboard.mjs.map +1 -1
  150. package/dist/astro/routes/api/dev/emails.mjs +4 -4
  151. package/dist/astro/routes/api/import/probe.d.mts +3 -3
  152. package/dist/astro/routes/api/import/probe.mjs +12 -12
  153. package/dist/astro/routes/api/import/wordpress/analyze.mjs +5 -5
  154. package/dist/astro/routes/api/import/wordpress/execute.d.mts +9 -9
  155. package/dist/astro/routes/api/import/wordpress/execute.mjs +16 -15
  156. package/dist/astro/routes/api/import/wordpress/execute.mjs.map +1 -1
  157. package/dist/astro/routes/api/import/wordpress/media.mjs +10 -10
  158. package/dist/astro/routes/api/import/wordpress/prepare.mjs +11 -11
  159. package/dist/astro/routes/api/import/wordpress/rewrite-urls.mjs +10 -10
  160. package/dist/astro/routes/api/import/wordpress-plugin/analyze.d.mts +1 -1
  161. package/dist/astro/routes/api/import/wordpress-plugin/analyze.mjs +12 -12
  162. package/dist/astro/routes/api/import/wordpress-plugin/callback.mjs +1 -1
  163. package/dist/astro/routes/api/import/wordpress-plugin/execute.d.mts +1 -1
  164. package/dist/astro/routes/api/import/wordpress-plugin/execute.mjs +18 -17
  165. package/dist/astro/routes/api/import/wordpress-plugin/execute.mjs.map +1 -1
  166. package/dist/astro/routes/api/manifest.mjs +5 -5
  167. package/dist/astro/routes/api/mcp.mjs +213 -46
  168. package/dist/astro/routes/api/mcp.mjs.map +1 -1
  169. package/dist/astro/routes/api/media/_id_/confirm.mjs +8 -8
  170. package/dist/astro/routes/api/media/_id_.mjs +8 -8
  171. package/dist/astro/routes/api/media/file/_...key_.mjs +3 -3
  172. package/dist/astro/routes/api/media/providers/_providerId_/_itemId_.mjs +4 -4
  173. package/dist/astro/routes/api/media/providers/_providerId_/index.mjs +4 -4
  174. package/dist/astro/routes/api/media/providers/index.mjs +4 -4
  175. package/dist/astro/routes/api/media/upload-url.mjs +10 -10
  176. package/dist/astro/routes/api/media.mjs +13 -13
  177. package/dist/astro/routes/api/menus/_name_/items/_id_.mjs +11 -9
  178. package/dist/astro/routes/api/menus/_name_/items/_id_.mjs.map +1 -1
  179. package/dist/astro/routes/api/menus/_name_/items.mjs +11 -9
  180. package/dist/astro/routes/api/menus/_name_/items.mjs.map +1 -1
  181. package/dist/astro/routes/api/menus/_name_/reorder.mjs +11 -9
  182. package/dist/astro/routes/api/menus/_name_/reorder.mjs.map +1 -1
  183. package/dist/astro/routes/api/menus/_name_/translations.mjs +11 -9
  184. package/dist/astro/routes/api/menus/_name_/translations.mjs.map +1 -1
  185. package/dist/astro/routes/api/menus/_name_.mjs +11 -9
  186. package/dist/astro/routes/api/menus/_name_.mjs.map +1 -1
  187. package/dist/astro/routes/api/menus/index.mjs +11 -9
  188. package/dist/astro/routes/api/menus/index.mjs.map +1 -1
  189. package/dist/astro/routes/api/oauth/authorize.mjs +6 -6
  190. package/dist/astro/routes/api/oauth/device/authorize.mjs +7 -7
  191. package/dist/astro/routes/api/oauth/device/code.mjs +10 -10
  192. package/dist/astro/routes/api/oauth/device/token.mjs +9 -9
  193. package/dist/astro/routes/api/oauth/register.mjs +4 -4
  194. package/dist/astro/routes/api/oauth/token/refresh.mjs +7 -7
  195. package/dist/astro/routes/api/oauth/token/revoke.mjs +7 -7
  196. package/dist/astro/routes/api/oauth/token.mjs +7 -7
  197. package/dist/astro/routes/api/openapi.json.mjs +5 -5
  198. package/dist/astro/routes/api/plugins/_pluginId_/_...path_.mjs +5 -5
  199. package/dist/astro/routes/api/redirects/404s/index.mjs +11 -11
  200. package/dist/astro/routes/api/redirects/404s/summary.mjs +11 -11
  201. package/dist/astro/routes/api/redirects/_id_.mjs +12 -12
  202. package/dist/astro/routes/api/redirects/index.mjs +12 -12
  203. package/dist/astro/routes/api/revisions/_revisionId_/index.mjs +4 -4
  204. package/dist/astro/routes/api/revisions/_revisionId_/restore.mjs +4 -4
  205. package/dist/astro/routes/api/schema/collections/_slug_/fields/_fieldSlug_.mjs +39 -38
  206. package/dist/astro/routes/api/schema/collections/_slug_/fields/_fieldSlug_.mjs.map +1 -1
  207. package/dist/astro/routes/api/schema/collections/_slug_/fields/index.mjs +39 -38
  208. package/dist/astro/routes/api/schema/collections/_slug_/fields/index.mjs.map +1 -1
  209. package/dist/astro/routes/api/schema/collections/_slug_/fields/reorder.mjs +39 -38
  210. package/dist/astro/routes/api/schema/collections/_slug_/fields/reorder.mjs.map +1 -1
  211. package/dist/astro/routes/api/schema/collections/_slug_/index.mjs +39 -38
  212. package/dist/astro/routes/api/schema/collections/_slug_/index.mjs.map +1 -1
  213. package/dist/astro/routes/api/schema/collections/index.mjs +39 -38
  214. package/dist/astro/routes/api/schema/collections/index.mjs.map +1 -1
  215. package/dist/astro/routes/api/schema/index.mjs +7 -7
  216. package/dist/astro/routes/api/schema/orphans/_slug_.mjs +39 -38
  217. package/dist/astro/routes/api/schema/orphans/_slug_.mjs.map +1 -1
  218. package/dist/astro/routes/api/schema/orphans/index.mjs +39 -38
  219. package/dist/astro/routes/api/schema/orphans/index.mjs.map +1 -1
  220. package/dist/astro/routes/api/search/enable.mjs +11 -11
  221. package/dist/astro/routes/api/search/index.mjs +10 -10
  222. package/dist/astro/routes/api/search/rebuild.mjs +11 -11
  223. package/dist/astro/routes/api/search/stats.mjs +7 -7
  224. package/dist/astro/routes/api/search/suggest.mjs +10 -10
  225. package/dist/astro/routes/api/sections/_slug_.mjs +10 -10
  226. package/dist/astro/routes/api/sections/index.mjs +10 -10
  227. package/dist/astro/routes/api/settings/email.mjs +6 -6
  228. package/dist/astro/routes/api/settings.mjs +16 -15
  229. package/dist/astro/routes/api/settings.mjs.map +1 -1
  230. package/dist/astro/routes/api/setup/admin-verify.mjs +13 -13
  231. package/dist/astro/routes/api/setup/admin.mjs +12 -12
  232. package/dist/astro/routes/api/setup/dev-bypass.d.mts.map +1 -1
  233. package/dist/astro/routes/api/setup/dev-bypass.mjs +29 -27
  234. package/dist/astro/routes/api/setup/dev-bypass.mjs.map +1 -1
  235. package/dist/astro/routes/api/setup/dev-reset.mjs +4 -4
  236. package/dist/astro/routes/api/setup/index.mjs +29 -28
  237. package/dist/astro/routes/api/setup/index.mjs.map +1 -1
  238. package/dist/astro/routes/api/setup/status.mjs +5 -5
  239. package/dist/astro/routes/api/snapshot.d.mts.map +1 -1
  240. package/dist/astro/routes/api/snapshot.mjs +10 -9
  241. package/dist/astro/routes/api/snapshot.mjs.map +1 -1
  242. package/dist/astro/routes/api/taxonomies/_name_/terms/_slug_/translations.mjs +16 -14
  243. package/dist/astro/routes/api/taxonomies/_name_/terms/_slug_/translations.mjs.map +1 -1
  244. package/dist/astro/routes/api/taxonomies/_name_/terms/_slug_.mjs +16 -14
  245. package/dist/astro/routes/api/taxonomies/_name_/terms/_slug_.mjs.map +1 -1
  246. package/dist/astro/routes/api/taxonomies/_name_/terms/index.mjs +16 -14
  247. package/dist/astro/routes/api/taxonomies/_name_/terms/index.mjs.map +1 -1
  248. package/dist/astro/routes/api/taxonomies/index.mjs +16 -14
  249. package/dist/astro/routes/api/taxonomies/index.mjs.map +1 -1
  250. package/dist/astro/routes/api/themes/preview.mjs +8 -8
  251. package/dist/astro/routes/api/typegen.mjs +6 -6
  252. package/dist/astro/routes/api/well-known/auth.mjs +2 -2
  253. package/dist/astro/routes/api/well-known/oauth-authorization-server.mjs +2 -2
  254. package/dist/astro/routes/api/well-known/oauth-protected-resource.mjs +2 -2
  255. package/dist/astro/routes/api/widget-areas/_name_/reorder.mjs +8 -8
  256. package/dist/astro/routes/api/widget-areas/_name_/widgets/_id_.mjs +11 -11
  257. package/dist/astro/routes/api/widget-areas/_name_/widgets.mjs +11 -11
  258. package/dist/astro/routes/api/widget-areas/_name_.mjs +7 -7
  259. package/dist/astro/routes/api/widget-areas/index.mjs +11 -11
  260. package/dist/astro/routes/api/widget-components.mjs +4 -4
  261. package/dist/astro/routes/robots.txt.mjs +10 -9
  262. package/dist/astro/routes/robots.txt.mjs.map +1 -1
  263. package/dist/astro/routes/sitemap-_collection_.xml.mjs +13 -12
  264. package/dist/astro/routes/sitemap-_collection_.xml.mjs.map +1 -1
  265. package/dist/astro/routes/sitemap.xml.mjs +11 -10
  266. package/dist/astro/routes/sitemap.xml.mjs.map +1 -1
  267. package/dist/astro/types.d.mts +16 -12
  268. package/dist/astro/types.d.mts.map +1 -1
  269. package/dist/auth/providers/github.d.mts +1 -1
  270. package/dist/auth/providers/google.d.mts +1 -1
  271. package/dist/{authorize-D5gfBVU5.mjs → authorize-C0EYoUeV.mjs} +2 -2
  272. package/dist/{authorize-D5gfBVU5.mjs.map → authorize-C0EYoUeV.mjs.map} +1 -1
  273. package/dist/{base64-CqR-7kqF.mjs → base64-CmWvODNW.mjs} +1 -1
  274. package/dist/{base64-CqR-7kqF.mjs.map → base64-CmWvODNW.mjs.map} +1 -1
  275. package/dist/{byline-V_Qp1Ziw.mjs → byline-CC0WS4Gu.mjs} +17 -8
  276. package/dist/byline-CC0WS4Gu.mjs.map +1 -0
  277. package/dist/{byline-fields-B0NO1yUB.mjs → byline-fields-53i9Et0x.mjs} +3 -3
  278. package/dist/{byline-fields-B0NO1yUB.mjs.map → byline-fields-53i9Et0x.mjs.map} +1 -1
  279. package/dist/{byline-fields-nBVqK_Ff.mjs → byline-fields-DNp0HNKc.mjs} +2 -2
  280. package/dist/{byline-fields-nBVqK_Ff.mjs.map → byline-fields-DNp0HNKc.mjs.map} +1 -1
  281. package/dist/{byline-fields-CQJRIQkn.d.mts → byline-fields-jy07PZJM.d.mts} +36 -31
  282. package/dist/byline-fields-jy07PZJM.d.mts.map +1 -0
  283. package/dist/{byline-registry-DedidtqC.mjs → byline-registry-BOjqDOim.mjs} +3 -3
  284. package/dist/{byline-registry-DedidtqC.mjs.map → byline-registry-BOjqDOim.mjs.map} +1 -1
  285. package/dist/{bylines-DfGDnred.mjs → bylines-CCO1CYnH.mjs} +8 -8
  286. package/dist/{bylines-DfGDnred.mjs.map → bylines-CCO1CYnH.mjs.map} +1 -1
  287. package/dist/{bylines-B2NWnIwS.mjs → bylines-DGekMGGm.mjs} +10 -4
  288. package/dist/{bylines-B2NWnIwS.mjs.map → bylines-DGekMGGm.mjs.map} +1 -1
  289. package/dist/{cache-DTTHWD8n.mjs → cache-pXTpun6s.mjs} +3 -3
  290. package/dist/{cache-DTTHWD8n.mjs.map → cache-pXTpun6s.mjs.map} +1 -1
  291. package/dist/{challenge-store-woE0bbCf.mjs → challenge-store-C6E_kWTs.mjs} +1 -1
  292. package/dist/{challenge-store-woE0bbCf.mjs.map → challenge-store-C6E_kWTs.mjs.map} +1 -1
  293. package/dist/{chunks-BerYVuve.mjs → chunks-SyjZaYwV.mjs} +2 -2
  294. package/dist/{chunks-BerYVuve.mjs.map → chunks-SyjZaYwV.mjs.map} +1 -1
  295. package/dist/cli/index.mjs +27 -26
  296. package/dist/cli/index.mjs.map +1 -1
  297. package/dist/client/cf-access.d.mts +1 -1
  298. package/dist/client/index.d.mts +1 -1
  299. package/dist/client/index.mjs +2 -1
  300. package/dist/client/index.mjs.map +1 -1
  301. package/dist/{comment-sqQxNpN3.mjs → comment-80UyJJUR.mjs} +11 -3
  302. package/dist/comment-80UyJJUR.mjs.map +1 -0
  303. package/dist/comment-reaction-B6AdcpXw.mjs +85 -0
  304. package/dist/comment-reaction-B6AdcpXw.mjs.map +1 -0
  305. package/dist/{comments-D2hNuxNa.mjs → comments-CtPkT2tp.mjs} +3 -3
  306. package/dist/{comments-D2hNuxNa.mjs.map → comments-CtPkT2tp.mjs.map} +1 -1
  307. package/dist/{components-DYKp2gmo.mjs → components-D6ZnrzbB.mjs} +1 -1
  308. package/dist/{components-DYKp2gmo.mjs.map → components-D6ZnrzbB.mjs.map} +1 -1
  309. package/dist/{content-BIlVx-RX.mjs → content-2PTDNnoh.mjs} +22 -7
  310. package/dist/content-2PTDNnoh.mjs.map +1 -0
  311. package/dist/{context-Cm4pt1Ws.mjs → context-f1__jpzF.mjs} +11 -11
  312. package/dist/{context-Cm4pt1Ws.mjs.map → context-f1__jpzF.mjs.map} +1 -1
  313. package/dist/{cron-DdEVrQ2Y.mjs → cron-CQPxBjYs.mjs} +1 -1
  314. package/dist/{cron-DdEVrQ2Y.mjs.map → cron-CQPxBjYs.mjs.map} +1 -1
  315. package/dist/{dashboard-C-UYpps0.mjs → dashboard-BOESNcwE.mjs} +4 -4
  316. package/dist/{dashboard-C-UYpps0.mjs.map → dashboard-BOESNcwE.mjs.map} +1 -1
  317. package/dist/database/instrumentation.d.mts +19 -0
  318. package/dist/database/instrumentation.d.mts.map +1 -1
  319. package/dist/database/instrumentation.mjs +8 -1
  320. package/dist/database/instrumentation.mjs.map +1 -1
  321. package/dist/db/index.d.mts +3 -3
  322. package/dist/db/index.mjs +1 -1
  323. package/dist/db/libsql.d.mts +1 -1
  324. package/dist/db/postgres.d.mts +1 -1
  325. package/dist/db/sqlite.d.mts +1 -1
  326. package/dist/{db-errors-BluWkwGI.mjs → db-errors-CrC5w3Jz.mjs} +1 -1
  327. package/dist/{db-errors-BluWkwGI.mjs.map → db-errors-CrC5w3Jz.mjs.map} +1 -1
  328. package/dist/{default-NHGuJzQ3.mjs → default-CpBEPn6a.mjs} +1 -1
  329. package/dist/{default-NHGuJzQ3.mjs.map → default-CpBEPn6a.mjs.map} +1 -1
  330. package/dist/{device-flow-BQApWgnW.mjs → device-flow-Bn-qiDrw.mjs} +5 -5
  331. package/dist/{device-flow-BQApWgnW.mjs.map → device-flow-Bn-qiDrw.mjs.map} +1 -1
  332. package/dist/{email-console-BbU3RbWv.mjs → email-console-B9VS6eN4.mjs} +1 -1
  333. package/dist/{email-console-BbU3RbWv.mjs.map → email-console-B9VS6eN4.mjs.map} +1 -1
  334. package/dist/{error-CNn_w7jf.mjs → error-BQ1pxs0L.mjs} +2 -2
  335. package/dist/{error-CNn_w7jf.mjs.map → error-BQ1pxs0L.mjs.map} +1 -1
  336. package/dist/{escape-DPgcxcpL.mjs → escape-BtbJWyaW.mjs} +1 -1
  337. package/dist/{escape-DPgcxcpL.mjs.map → escape-BtbJWyaW.mjs.map} +1 -1
  338. package/dist/{fts-manager-Cx5z8jdA.mjs → fts-manager-DtiWqwNJ.mjs} +2 -2
  339. package/dist/{fts-manager-Cx5z8jdA.mjs.map → fts-manager-DtiWqwNJ.mjs.map} +1 -1
  340. package/dist/{hash-DlvIFn0b.mjs → hash-BowcuPwv.mjs} +1 -1
  341. package/dist/{hash-DlvIFn0b.mjs.map → hash-BowcuPwv.mjs.map} +1 -1
  342. package/dist/{import-KyxT1Mbs.mjs → import-DqSGOlmR.mjs} +4 -4
  343. package/dist/{import-KyxT1Mbs.mjs.map → import-DqSGOlmR.mjs.map} +1 -1
  344. package/dist/{index-D2VAiumu.d.mts → index-C2dLNT6S.d.mts} +172 -17
  345. package/dist/index-C2dLNT6S.d.mts.map +1 -0
  346. package/dist/{index-uT2yR66F.d.mts → index-ZDEwR7qW.d.mts} +3 -3
  347. package/dist/{index-uT2yR66F.d.mts.map → index-ZDEwR7qW.d.mts.map} +1 -1
  348. package/dist/index.d.mts +18 -17
  349. package/dist/index.mjs +63 -61
  350. package/dist/{init-lock-DlBHjf9-.mjs → init-lock-6b309ZrF.mjs} +2 -29
  351. package/dist/init-lock-6b309ZrF.mjs.map +1 -0
  352. package/dist/{load-Dq91b_DK.mjs → load-Dtoo7KcJ.mjs} +2 -2
  353. package/dist/{load-Dq91b_DK.mjs.map → load-Dtoo7KcJ.mjs.map} +1 -1
  354. package/dist/{loader-BqWjcH3h.mjs → loader-C8Z48Uof.mjs} +4 -4
  355. package/dist/{loader-BqWjcH3h.mjs.map → loader-C8Z48Uof.mjs.map} +1 -1
  356. package/dist/{manifest-schema-DFPeqMAn.mjs → manifest-schema-DDSbwkAL.mjs} +1 -1
  357. package/dist/{manifest-schema-DFPeqMAn.mjs.map → manifest-schema-DDSbwkAL.mjs.map} +1 -1
  358. package/dist/media/image-endpoint.d.mts +74 -0
  359. package/dist/media/image-endpoint.d.mts.map +1 -0
  360. package/dist/media/image-endpoint.mjs +162 -0
  361. package/dist/media/image-endpoint.mjs.map +1 -0
  362. package/dist/media/index.d.mts +1 -1
  363. package/dist/media/index.mjs +2 -2
  364. package/dist/media/local-runtime.d.mts +11 -11
  365. package/dist/media/local-runtime.mjs +9 -8
  366. package/dist/media/local-runtime.mjs.map +1 -1
  367. package/dist/{media-JOf3pNkw.mjs → media-Bw0sA6rb.mjs} +2 -2
  368. package/dist/{media-JOf3pNkw.mjs.map → media-Bw0sA6rb.mjs.map} +1 -1
  369. package/dist/{media-allowlist-_A0SuDn4.mjs → media-allowlist-DunzrKFM.mjs} +2 -2
  370. package/dist/{media-allowlist-_A0SuDn4.mjs.map → media-allowlist-DunzrKFM.mjs.map} +1 -1
  371. package/dist/{media-url-CqLd69IO.mjs → media-url-S22B6aPr.mjs} +1 -1
  372. package/dist/{media-url-CqLd69IO.mjs.map → media-url-S22B6aPr.mjs.map} +1 -1
  373. package/dist/{menus-DX4_E01q.mjs → menus-CYs0WZoL.mjs} +20 -6
  374. package/dist/menus-CYs0WZoL.mjs.map +1 -0
  375. package/dist/{menus-Ryk9L7fT.mjs → menus-DOs1MQJg.mjs} +120 -20
  376. package/dist/menus-DOs1MQJg.mjs.map +1 -0
  377. package/dist/{mime-YbtlEtvS.mjs → mime-DYpsOAny.mjs} +1 -1
  378. package/dist/{mime-YbtlEtvS.mjs.map → mime-DYpsOAny.mjs.map} +1 -1
  379. package/dist/{mode-CGXzIbD8.mjs → mode-CFh8Dw8G.mjs} +1 -1
  380. package/dist/{mode-CGXzIbD8.mjs.map → mode-CFh8Dw8G.mjs.map} +1 -1
  381. package/dist/{normalize-DKsg36ty.mjs → normalize-Uam4_Vkr.mjs} +1 -1
  382. package/dist/{normalize-DKsg36ty.mjs.map → normalize-Uam4_Vkr.mjs.map} +1 -1
  383. package/dist/{oauth-authorization-C2kVyjXI.mjs → oauth-authorization-BN-t83Uy.mjs} +5 -5
  384. package/dist/{oauth-authorization-C2kVyjXI.mjs.map → oauth-authorization-BN-t83Uy.mjs.map} +1 -1
  385. package/dist/{oauth-clients-BC873NCV.mjs → oauth-clients-R6I_V0qz.mjs} +1 -1
  386. package/dist/{oauth-clients-BC873NCV.mjs.map → oauth-clients-R6I_V0qz.mjs.map} +1 -1
  387. package/dist/{oauth-state-store-Cd--TUaq.mjs → oauth-state-store-Csoc6kkR.mjs} +1 -1
  388. package/dist/{oauth-state-store-Cd--TUaq.mjs.map → oauth-state-store-Csoc6kkR.mjs.map} +1 -1
  389. package/dist/{oauth-user-lookup-e4wOvDud.mjs → oauth-user-lookup-d7VYjTpx.mjs} +1 -1
  390. package/dist/{oauth-user-lookup-e4wOvDud.mjs.map → oauth-user-lookup-d7VYjTpx.mjs.map} +1 -1
  391. package/dist/object-cache/memory.d.mts +15 -0
  392. package/dist/object-cache/memory.d.mts.map +1 -0
  393. package/dist/object-cache/memory.mjs +56 -0
  394. package/dist/object-cache/memory.mjs.map +1 -0
  395. package/dist/object-cache-SEb2IM4Z.mjs +373 -0
  396. package/dist/object-cache-SEb2IM4Z.mjs.map +1 -0
  397. package/dist/{options-9kLgkE8m.d.mts → options-DFFpvNJU.d.mts} +3 -3
  398. package/dist/{options-9kLgkE8m.d.mts.map → options-DFFpvNJU.d.mts.map} +1 -1
  399. package/dist/{options-BPCVnesz.mjs → options-DTTML-Tx.mjs} +1 -1
  400. package/dist/{options-BPCVnesz.mjs.map → options-DTTML-Tx.mjs.map} +1 -1
  401. package/dist/page/index.d.mts +2 -2
  402. package/dist/{parse-DzSrk1t8.mjs → parse-qrHlnzTy.mjs} +2 -2
  403. package/dist/{parse-DzSrk1t8.mjs.map → parse-qrHlnzTy.mjs.map} +1 -1
  404. package/dist/{passkey-config-BpjbE_Uv.mjs → passkey-config-BJTbcnI5.mjs} +1 -1
  405. package/dist/{passkey-config-BpjbE_Uv.mjs.map → passkey-config-BJTbcnI5.mjs.map} +1 -1
  406. package/dist/{patterns-p-RBdTbM.mjs → patterns-BKmjvM7K.mjs} +1 -1
  407. package/dist/{patterns-p-RBdTbM.mjs.map → patterns-BKmjvM7K.mjs.map} +1 -1
  408. package/dist/{placeholder-2xumZh4g.mjs → placeholder-CIDCpyEY.mjs} +1 -1
  409. package/dist/{placeholder-2xumZh4g.mjs.map → placeholder-CIDCpyEY.mjs.map} +1 -1
  410. package/dist/{placeholder-BevVKfay.d.mts → placeholder-CirPauNG.d.mts} +1 -1
  411. package/dist/{placeholder-BevVKfay.d.mts.map → placeholder-CirPauNG.d.mts.map} +1 -1
  412. package/dist/plugin-types.d.mts +1 -1
  413. package/dist/plugin-utils.d.mts +9 -9
  414. package/dist/plugins/adapt-sandbox-entry.d.mts +9 -9
  415. package/dist/plugins/adapt-sandbox-entry.mjs +4 -2
  416. package/dist/plugins/adapt-sandbox-entry.mjs.map +1 -1
  417. package/dist/{transport-1cIrOb1Y.mjs → portable-text-BIFhrU6T.mjs} +2 -135
  418. package/dist/portable-text-BIFhrU6T.mjs.map +1 -0
  419. package/dist/{preview-Dqv2hwXr.mjs → preview-IDye9SPQ.mjs} +2 -2
  420. package/dist/{preview-Dqv2hwXr.mjs.map → preview-IDye9SPQ.mjs.map} +1 -1
  421. package/dist/{public-url-D_zARuvZ.mjs → public-url-8lFyQ8ZF.mjs} +1 -1
  422. package/dist/{public-url-D_zARuvZ.mjs.map → public-url-8lFyQ8ZF.mjs.map} +1 -1
  423. package/dist/{query-Crm038Mc.mjs → query-B1RVFUNM.mjs} +159 -31
  424. package/dist/query-B1RVFUNM.mjs.map +1 -0
  425. package/dist/{rate-limit-hRTBqmw1.mjs → rate-limit-DfNAqIWW.mjs} +2 -2
  426. package/dist/{rate-limit-hRTBqmw1.mjs.map → rate-limit-DfNAqIWW.mjs.map} +1 -1
  427. package/dist/{redirect-C-OOkyku.mjs → redirect-B4wuX2A5.mjs} +1 -1
  428. package/dist/{redirect-C-OOkyku.mjs.map → redirect-B4wuX2A5.mjs.map} +1 -1
  429. package/dist/{redirect-CRWIt8Zj.mjs → redirect-Bifv_yHv.mjs} +3 -3
  430. package/dist/{redirect-CRWIt8Zj.mjs.map → redirect-Bifv_yHv.mjs.map} +1 -1
  431. package/dist/{redirects-CP3TnTLO.mjs → redirects-CT_vb3NV.mjs} +6 -6
  432. package/dist/{redirects-CP3TnTLO.mjs.map → redirects-CT_vb3NV.mjs.map} +1 -1
  433. package/dist/{redirects-6Zg2SoYo.mjs → redirects-DUvXgzCX.mjs} +8 -3
  434. package/dist/redirects-DUvXgzCX.mjs.map +1 -0
  435. package/dist/{registry-diMzD1Wf.mjs → registry-CjK96fHD.mjs} +6 -6
  436. package/dist/{registry-diMzD1Wf.mjs.map → registry-CjK96fHD.mjs.map} +1 -1
  437. package/dist/{request-cache-UwmBAiUK.mjs → request-cache-KCNHp_RJ.mjs} +1 -1
  438. package/dist/{request-cache-UwmBAiUK.mjs.map → request-cache-KCNHp_RJ.mjs.map} +1 -1
  439. package/dist/{request-meta-DPechd0W.mjs → request-meta-ei3ATilC.mjs} +2 -2
  440. package/dist/{request-meta-DPechd0W.mjs.map → request-meta-ei3ATilC.mjs.map} +1 -1
  441. package/dist/{resolve-B3NUUtVY.mjs → resolve-CpbBglV0.mjs} +1 -1
  442. package/dist/{resolve-B3NUUtVY.mjs.map → resolve-CpbBglV0.mjs.map} +1 -1
  443. package/dist/{runner--4wMWwKM.mjs → runner-DYYnW530.mjs} +201 -170
  444. package/dist/runner-DYYnW530.mjs.map +1 -0
  445. package/dist/{runner-C8vcbvCe.d.mts → runner-jdXtFEd3.d.mts} +2 -2
  446. package/dist/{runner-C8vcbvCe.d.mts.map → runner-jdXtFEd3.d.mts.map} +1 -1
  447. package/dist/runtime.d.mts +10 -10
  448. package/dist/runtime.mjs +3 -3
  449. package/dist/{schema-BDOkd3OU.mjs → schema-5z2Jfnbm.mjs} +13 -8
  450. package/dist/schema-5z2Jfnbm.mjs.map +1 -0
  451. package/dist/{search-Bs_J_EW-.mjs → search-D9FkoM-k.mjs} +4 -4
  452. package/dist/{search-Bs_J_EW-.mjs.map → search-D9FkoM-k.mjs.map} +1 -1
  453. package/dist/{secrets-C8xmE6mR.mjs → secrets-BUE5UQys.mjs} +5 -5
  454. package/dist/{secrets-C8xmE6mR.mjs.map → secrets-BUE5UQys.mjs.map} +1 -1
  455. package/dist/{sections-P0zuBlyz.mjs → sections-DWYZo6HK.mjs} +3 -3
  456. package/dist/{sections-P0zuBlyz.mjs.map → sections-DWYZo6HK.mjs.map} +1 -1
  457. package/dist/seed/index.d.mts +2 -2
  458. package/dist/seed/index.mjs +22 -21
  459. package/dist/seo/index.d.mts +1 -1
  460. package/dist/seo/index.mjs +1 -1
  461. package/dist/{seo-DpNgGQjF.mjs → seo-Cu47j3mJ.mjs} +5 -2
  462. package/dist/seo-Cu47j3mJ.mjs.map +1 -0
  463. package/dist/{seo-CLhm-Fmb.mjs → seo-DRnqnstF.mjs} +1 -1
  464. package/dist/{seo-CLhm-Fmb.mjs.map → seo-DRnqnstF.mjs.map} +1 -1
  465. package/dist/{service-CDQQnT8W.mjs → service-DTmtqCnw.mjs} +3 -3
  466. package/dist/{service-CDQQnT8W.mjs.map → service-DTmtqCnw.mjs.map} +1 -1
  467. package/dist/session-user-DmtPMNa1.mjs +51 -0
  468. package/dist/session-user-DmtPMNa1.mjs.map +1 -0
  469. package/dist/{settings-sO0Fif4p.mjs → settings-DUrVDN0c.mjs} +3 -3
  470. package/dist/{settings-sO0Fif4p.mjs.map → settings-DUrVDN0c.mjs.map} +1 -1
  471. package/dist/{settings-BjBsmVAo.mjs → settings-yaxu9mU-.mjs} +18 -10
  472. package/dist/settings-yaxu9mU-.mjs.map +1 -0
  473. package/dist/{setup-complete-CMMr-oZU.mjs → setup-complete-BWFHzgvZ.mjs} +2 -2
  474. package/dist/{setup-complete-CMMr-oZU.mjs.map → setup-complete-BWFHzgvZ.mjs.map} +1 -1
  475. package/dist/{setup-nonce-169xl4fV.mjs → setup-nonce-DFWG-J5c.mjs} +1 -1
  476. package/dist/{setup-nonce-169xl4fV.mjs.map → setup-nonce-DFWG-J5c.mjs.map} +1 -1
  477. package/dist/{single-flight-cache-C0UV1Npg.mjs → single-flight-cache-B5p5cNOL.mjs} +2 -2
  478. package/dist/{single-flight-cache-C0UV1Npg.mjs.map → single-flight-cache-B5p5cNOL.mjs.map} +1 -1
  479. package/dist/{site-url-vtsuOvSD.mjs → site-url-BOTPgmeM.mjs} +2 -2
  480. package/dist/{site-url-vtsuOvSD.mjs.map → site-url-BOTPgmeM.mjs.map} +1 -1
  481. package/dist/{slugify-Cjh1ssOZ.mjs → slugify-Cce3dTdg.mjs} +1 -1
  482. package/dist/{slugify-Cjh1ssOZ.mjs.map → slugify-Cce3dTdg.mjs.map} +1 -1
  483. package/dist/{ssrf-XO05Voq6.mjs → ssrf-B0VeRLrp.mjs} +1 -1
  484. package/dist/{ssrf-XO05Voq6.mjs.map → ssrf-B0VeRLrp.mjs.map} +1 -1
  485. package/dist/{status-2gZklYuj.mjs → status-CB2basWJ.mjs} +1 -1
  486. package/dist/{status-2gZklYuj.mjs.map → status-CB2basWJ.mjs.map} +1 -1
  487. package/dist/storage/local.d.mts +1 -1
  488. package/dist/storage/local.mjs +1 -1
  489. package/dist/storage/s3.d.mts +1 -1
  490. package/dist/storage/s3.mjs +1 -1
  491. package/dist/{taxonomies-BBxYA38v.mjs → taxonomies-Be9B1jEj.mjs} +156 -122
  492. package/dist/taxonomies-Be9B1jEj.mjs.map +1 -0
  493. package/dist/{taxonomies-DuESHWKI.mjs → taxonomies-CJmkEpdS.mjs} +7 -7
  494. package/dist/{taxonomies-DuESHWKI.mjs.map → taxonomies-CJmkEpdS.mjs.map} +1 -1
  495. package/dist/{taxonomy-CdllE4oq.mjs → taxonomy-B2HQuVf5.mjs} +19 -6
  496. package/dist/taxonomy-B2HQuVf5.mjs.map +1 -0
  497. package/dist/{tokens-DMkVjxrx.mjs → tokens-BvrJvIB6.mjs} +2 -2
  498. package/dist/{tokens-DMkVjxrx.mjs.map → tokens-BvrJvIB6.mjs.map} +1 -1
  499. package/dist/{transaction-x2tJQ-A1.mjs → transaction-qfqpPVpu.mjs} +1 -1
  500. package/dist/{transaction-x2tJQ-A1.mjs.map → transaction-qfqpPVpu.mjs.map} +1 -1
  501. package/dist/transport-B4rXnSTf.mjs +135 -0
  502. package/dist/transport-B4rXnSTf.mjs.map +1 -0
  503. package/dist/{transport-jdvsZEIt.d.mts → transport-k7YjfmEn.d.mts} +1 -1
  504. package/dist/{transport-jdvsZEIt.d.mts.map → transport-k7YjfmEn.d.mts.map} +1 -1
  505. package/dist/{trusted-proxy-CHp41Fjj.mjs → trusted-proxy-DY1_UqHr.mjs} +1 -1
  506. package/dist/{trusted-proxy-CHp41Fjj.mjs.map → trusted-proxy-DY1_UqHr.mjs.map} +1 -1
  507. package/dist/{types-DO7whVYU.d.mts → types-CIKX2HO5.d.mts} +2 -2
  508. package/dist/{types-DO7whVYU.d.mts.map → types-CIKX2HO5.d.mts.map} +1 -1
  509. package/dist/{types-u_XxjbS8.d.mts → types-CKNXt63n.d.mts} +1 -1
  510. package/dist/{types-u_XxjbS8.d.mts.map → types-CKNXt63n.d.mts.map} +1 -1
  511. package/dist/{types-BTnnBYVX.d.mts → types-CWGYDYqF.d.mts} +2 -2
  512. package/dist/{types-BTnnBYVX.d.mts.map → types-CWGYDYqF.d.mts.map} +1 -1
  513. package/dist/{types-CkEuk-Zr.d.mts → types-CgvhU-hF.d.mts} +1 -1
  514. package/dist/{types-CkEuk-Zr.d.mts.map → types-CgvhU-hF.d.mts.map} +1 -1
  515. package/dist/{types-BFgYtuKd.d.mts → types-CmivgZbp.d.mts} +1 -1
  516. package/dist/{types-BFgYtuKd.d.mts.map → types-CmivgZbp.d.mts.map} +1 -1
  517. package/dist/{types-Del0VMij.d.mts → types-Czg1S3gB.d.mts} +9 -1
  518. package/dist/{types-Del0VMij.d.mts.map → types-Czg1S3gB.d.mts.map} +1 -1
  519. package/dist/types-DCNNfeCv.d.mts +124 -0
  520. package/dist/types-DCNNfeCv.d.mts.map +1 -0
  521. package/dist/{types-Bzfk2yC8.d.mts → types-DPCpkzvS.d.mts} +1 -1
  522. package/dist/{types-Bzfk2yC8.d.mts.map → types-DPCpkzvS.d.mts.map} +1 -1
  523. package/dist/{types-DdkL6fyv.d.mts → types-DXLVzV2w.d.mts} +1 -1
  524. package/dist/{types-DdkL6fyv.d.mts.map → types-DXLVzV2w.d.mts.map} +1 -1
  525. package/dist/{types-BXSUSAjt.mjs → types-DXOIbece.mjs} +3 -3
  526. package/dist/{types-BXSUSAjt.mjs.map → types-DXOIbece.mjs.map} +1 -1
  527. package/dist/{types-DejCHqWT.mjs → types-DYF2_Vf4.mjs} +1 -1
  528. package/dist/{types-DejCHqWT.mjs.map → types-DYF2_Vf4.mjs.map} +1 -1
  529. package/dist/{types-BIduXPJk.mjs → types-tM44hEcf.mjs} +1 -1
  530. package/dist/{types-BIduXPJk.mjs.map → types-tM44hEcf.mjs.map} +1 -1
  531. package/dist/{user-C0um7wrg.mjs → user-Db-Rti_z.mjs} +3 -3
  532. package/dist/{user-C0um7wrg.mjs.map → user-Db-Rti_z.mjs.map} +1 -1
  533. package/dist/{utils-C4M981Br.mjs → utils-LbHcSRTj.mjs} +2 -2
  534. package/dist/{utils-C4M981Br.mjs.map → utils-LbHcSRTj.mjs.map} +1 -1
  535. package/dist/{validate-DGhQPXzI.mjs → validate-Bwl64sxv.mjs} +3 -3
  536. package/dist/{validate-DGhQPXzI.mjs.map → validate-Bwl64sxv.mjs.map} +1 -1
  537. package/dist/{validate-cJOiOvT2.d.mts → validate-CE2M0nvx.d.mts} +5 -5
  538. package/dist/{validate-cJOiOvT2.d.mts.map → validate-CE2M0nvx.d.mts.map} +1 -1
  539. package/dist/{validation-DVHjPM1M.mjs → validation-C_yOvFaO.mjs} +6 -6
  540. package/dist/{validation-DVHjPM1M.mjs.map → validation-C_yOvFaO.mjs.map} +1 -1
  541. package/dist/version-RnYXYjzD.mjs +7 -0
  542. package/dist/{version-BOjj_cfz.mjs.map → version-RnYXYjzD.mjs.map} +1 -1
  543. package/dist/{widgets-Ci6hLwfO.mjs → widgets-8GONuRHo.mjs} +4 -4
  544. package/dist/{widgets-Ci6hLwfO.mjs.map → widgets-8GONuRHo.mjs.map} +1 -1
  545. package/dist/{zod-generator-CarzgPAu.mjs → zod-generator-D481JjzD.mjs} +3 -3
  546. package/dist/{zod-generator-CarzgPAu.mjs.map → zod-generator-D481JjzD.mjs.map} +1 -1
  547. package/package.json +18 -6
  548. package/src/api/handlers/api-tokens.ts +19 -0
  549. package/src/api/handlers/comment-reactions.ts +165 -0
  550. package/src/api/handlers/schema.ts +8 -0
  551. package/src/api/schemas/comments.ts +10 -0
  552. package/src/astro/image-endpoint.ts +84 -0
  553. package/src/astro/index.ts +6 -0
  554. package/src/astro/integration/index.ts +83 -22
  555. package/src/astro/integration/routes.ts +5 -0
  556. package/src/astro/integration/runtime.ts +65 -1
  557. package/src/astro/integration/virtual-modules.ts +32 -0
  558. package/src/astro/integration/vite-config.ts +16 -0
  559. package/src/astro/middleware/auth.ts +4 -3
  560. package/src/astro/middleware/stream-end-metrics.ts +11 -1
  561. package/src/astro/middleware.ts +41 -3
  562. package/src/astro/object-cache/adapters.ts +50 -0
  563. package/src/astro/prefetch.ts +77 -0
  564. package/src/astro/routes/api/comments/[collection]/[contentId]/reactions.ts +97 -0
  565. package/src/astro/routes/api/setup/dev-bypass.ts +5 -1
  566. package/src/astro/routes/api/snapshot.ts +3 -1
  567. package/src/astro/session-user.ts +57 -0
  568. package/src/astro/types.ts +1 -0
  569. package/src/comments/query.ts +78 -7
  570. package/src/comments/ranking.ts +58 -0
  571. package/src/components/Comments.astro +136 -1
  572. package/src/database/instrumentation.ts +21 -1
  573. package/src/database/migrations/044_comment_reactions.ts +56 -0
  574. package/src/database/migrations/runner.ts +2 -0
  575. package/src/database/repositories/byline.ts +13 -0
  576. package/src/database/repositories/comment-reaction.ts +132 -0
  577. package/src/database/repositories/comment.ts +10 -0
  578. package/src/database/repositories/content.ts +25 -3
  579. package/src/database/repositories/menu.ts +13 -1
  580. package/src/database/repositories/seo.ts +3 -0
  581. package/src/database/repositories/taxonomy.ts +13 -1
  582. package/src/database/types.ts +9 -0
  583. package/src/emdash-runtime.ts +18 -4
  584. package/src/index.ts +22 -0
  585. package/src/mcp/server.ts +307 -20
  586. package/src/media/image-endpoint.ts +167 -0
  587. package/src/menus/index.ts +11 -4
  588. package/src/object-cache/codec.ts +73 -0
  589. package/src/object-cache/index.ts +495 -0
  590. package/src/object-cache/memory.ts +91 -0
  591. package/src/object-cache/types.ts +124 -0
  592. package/src/plugins/adapt-sandbox-entry.ts +11 -1
  593. package/src/query.ts +196 -17
  594. package/src/schema/query.ts +11 -4
  595. package/src/settings/index.ts +18 -5
  596. package/src/taxonomies/index.ts +237 -165
  597. package/src/virtual-modules.d.ts +11 -0
  598. package/dist/api-DxjIV2o8.mjs.map +0 -1
  599. package/dist/api-tokens-BFFkB0jB.mjs.map +0 -1
  600. package/dist/byline-V_Qp1Ziw.mjs.map +0 -1
  601. package/dist/byline-fields-CQJRIQkn.d.mts.map +0 -1
  602. package/dist/comment-sqQxNpN3.mjs.map +0 -1
  603. package/dist/content-BIlVx-RX.mjs.map +0 -1
  604. package/dist/index-D2VAiumu.d.mts.map +0 -1
  605. package/dist/init-lock-DlBHjf9-.mjs.map +0 -1
  606. package/dist/menus-DX4_E01q.mjs.map +0 -1
  607. package/dist/menus-Ryk9L7fT.mjs.map +0 -1
  608. package/dist/query-Crm038Mc.mjs.map +0 -1
  609. package/dist/redirects-6Zg2SoYo.mjs.map +0 -1
  610. package/dist/runner--4wMWwKM.mjs.map +0 -1
  611. package/dist/schema-BDOkd3OU.mjs.map +0 -1
  612. package/dist/seo-DpNgGQjF.mjs.map +0 -1
  613. package/dist/settings-BjBsmVAo.mjs.map +0 -1
  614. package/dist/taxonomies-BBxYA38v.mjs.map +0 -1
  615. package/dist/taxonomy-CdllE4oq.mjs.map +0 -1
  616. package/dist/transport-1cIrOb1Y.mjs.map +0 -1
  617. package/dist/version-BOjj_cfz.mjs +0 -7
  618. /package/dist/{api-tokens-C7ywRx7l.mjs → api-tokens-BVH-H8Z9.mjs} +0 -0
  619. /package/dist/{ssrf-CRZGzjdL.mjs → ssrf-Cz1e2QPn.mjs} +0 -0
  620. /package/dist/{types-BoRm8-pp.mjs → types-Bfr2Pj6z.mjs} +0 -0
@@ -70,26 +70,21 @@ interface ImageRemotePattern {
70
70
  /**
71
71
  * Build `image.remotePatterns` entries so Astro will optimize EmDash media.
72
72
  *
73
- * Astro's image services only transform **absolute** URLs whose host is
74
- * authorized; everything else is passed through unoptimized. We authorize the
75
- * media sources automatically:
73
+ * Astro's image services only build a transform URL for sources allowed via
74
+ * `image.domains` / `image.remotePatterns` (relative URLs are never optimized
75
+ * see `isRemoteAllowed`). We authorize the media sources automatically:
76
76
  *
77
- * 1. The storage adapter's public URL host (R2 custom domain, S3/CDN), so
78
- * media served directly from a public bucket is optimized.
77
+ * 1. The storage adapter's public URL host (R2 custom domain, S3/CDN).
79
78
  * 2. The site's own origin, scoped to the media proxy route
80
- * (`/_emdash/api/media/file/**`), so same-origin proxied media (local
81
- * storage, or R2 without a public URL) is optimized too. The pathname
82
- * scope keeps Astro's image endpoint from acting as an open proxy for the
83
- * whole origin. Only registered when `siteUrl` is known at build time;
84
- * `getPublicOrigin` resolves the matching origin at render time.
85
- * 3. In `astro dev` the dev-server origin (`localhost:<port>`) isn't known at
86
- * build time, so we register a host-agnostic pattern scoped to the media
87
- * route. This is dev-only — it never ships in a production build — so the
88
- * missing host check can't be abused on a deployed site.
79
+ * (`/_emdash/api/media/file/**`), so same-origin proxied media is optimized.
80
+ * The components absolutize the media URL against this origin; EmDash's
81
+ * wrapped image endpoint then serves the bytes from storage (so the absolute
82
+ * URL is never fetched). Only registered when `siteUrl` is known at build.
83
+ * 3. In `astro dev` the dev-server origin isn't known at build time, so we
84
+ * register a host-agnostic pattern scoped to the media route. Dev-only.
89
85
  *
90
- * Returns an empty array when no source is statically known (e.g. a production
91
- * build using local storage with no `siteUrl`), in which case media renders as
92
- * a plain `<img>`.
86
+ * Returns an empty array when no source is statically known (production build,
87
+ * local storage, no `siteUrl`), in which case media renders as a plain `<img>`.
93
88
  *
94
89
  * @internal Exported for unit testing.
95
90
  */
@@ -147,6 +142,59 @@ export function buildImageRemotePatterns(
147
142
  return patterns;
148
143
  }
149
144
 
145
+ /**
146
+ * Stock image endpoints EmDash may safely replace with its storage-backed
147
+ * wrapper. Our wrapper delegates non-EmDash images to the platform's transform
148
+ * endpoint, so we only override endpoints whose transform we can delegate to.
149
+ */
150
+ const OVERRIDABLE_IMAGE_ENDPOINTS = new Set([
151
+ "astro/assets/endpoint/generic",
152
+ "astro/assets/endpoint/node",
153
+ "astro/assets/endpoint/dev",
154
+ "@astrojs/cloudflare/image-transform-endpoint",
155
+ ]);
156
+
157
+ /**
158
+ * Stock endpoints that deliberately don't transform (the user opted into
159
+ * passthrough). We leave these untouched -- and without a warning, since it's a
160
+ * supported choice, not a custom endpoint. Overriding would route non-EmDash
161
+ * images through a transformer the passthrough setup doesn't provide.
162
+ */
163
+ const PASSTHROUGH_IMAGE_ENDPOINTS = new Set(["@astrojs/cloudflare/image-passthrough-endpoint"]);
164
+
165
+ /**
166
+ * Decide which image endpoint to install (if any). EmDash wraps Astro's image
167
+ * endpoint so EmDash media bytes load from storage; the wrapper delegates other
168
+ * images back to the platform's stock endpoint.
169
+ *
170
+ * Returns `{ entrypoint }` to install, `{ warn }` to skip with a warning (a
171
+ * custom endpoint we can't delegate to), or `{}` to skip silently (opted out).
172
+ *
173
+ * @internal Exported for unit testing.
174
+ */
175
+ export function resolveImageEndpoint(opts: {
176
+ imagesDisabled: boolean;
177
+ currentEntrypoint: string | undefined;
178
+ isCloudflare: boolean;
179
+ }): { entrypoint?: string; warn?: string } {
180
+ if (opts.imagesDisabled) return {};
181
+ const current = opts.currentEntrypoint;
182
+ if (current === undefined || OVERRIDABLE_IMAGE_ENDPOINTS.has(current)) {
183
+ return {
184
+ entrypoint: opts.isCloudflare
185
+ ? "@emdash-cms/cloudflare/image-endpoint"
186
+ : "emdash/image-endpoint",
187
+ };
188
+ }
189
+ // A deliberate passthrough setup: leave it alone, no warning.
190
+ if (PASSTHROUGH_IMAGE_ENDPOINTS.has(current)) return {};
191
+ return {
192
+ warn:
193
+ `A custom image.endpoint (${current}) is configured; EmDash will not wrap ` +
194
+ `it, so storage-backed media may render unoptimized.`,
195
+ };
196
+ }
197
+
150
198
  // Terminal formatting
151
199
  const dim = (s: string) => `\x1b[2m${s}\x1b[22m`;
152
200
  const bold = (s: string) => `\x1b[1m${s}\x1b[22m`;
@@ -402,19 +450,32 @@ export function emdash(config: EmDashConfig = {}): AstroIntegration {
402
450
  },
403
451
  ];
404
452
 
405
- // Authorize media sources for Astro image optimization so the
406
- // Image components can generate a responsive srcset for R2/S3 and
407
- // same-origin proxied media. `updateConfig` merges arrays, so any
408
- // user-configured remotePatterns are preserved.
453
+ // Authorize media sources so Astro's image service builds transform
454
+ // URLs for them (it won't optimize an un-allowed source). `updateConfig`
455
+ // merges arrays, so user-configured remotePatterns are preserved.
409
456
  const imageRemotePatterns = buildImageRemotePatterns(
410
457
  resolvedConfig.storage,
411
458
  resolvedConfig.siteUrl,
412
459
  command,
413
460
  );
414
461
 
462
+ // Wrap Astro's image endpoint so EmDash media bytes load straight from
463
+ // storage (Access-safe) instead of over HTTP. Skip when the user opts
464
+ // out or has a custom endpoint we can't delegate back to.
465
+ const { entrypoint: imageEndpoint, warn: imageEndpointWarning } = resolveImageEndpoint({
466
+ imagesDisabled: resolvedConfig.images === false,
467
+ currentEntrypoint: astroConfig.image?.endpoint?.entrypoint,
468
+ isCloudflare: astroConfig.adapter?.name === "@astrojs/cloudflare",
469
+ });
470
+ if (imageEndpointWarning) logger.warn(imageEndpointWarning);
471
+
472
+ const imageConfig: Record<string, unknown> = {};
473
+ if (imageRemotePatterns.length) imageConfig.remotePatterns = imageRemotePatterns;
474
+ if (imageEndpoint) imageConfig.endpoint = { entrypoint: imageEndpoint };
475
+
415
476
  updateConfig({
416
477
  security: securityConfig,
417
- ...(imageRemotePatterns.length ? { image: { remotePatterns: imageRemotePatterns } } : {}),
478
+ ...(Object.keys(imageConfig).length ? { image: imageConfig } : {}),
418
479
  // fonts is a valid AstroConfig key but may not be in the
419
480
  // type definition for the minimum supported Astro version
420
481
  ...({ fonts: emdashFonts } as Record<string, unknown>),
@@ -758,6 +758,11 @@ export function injectCoreRoutes(
758
758
  entrypoint: resolveRoute("api/comments/[collection]/[contentId]/index.ts"),
759
759
  });
760
760
 
761
+ injectRoute({
762
+ pattern: "/_emdash/api/comments/[collection]/[contentId]/reactions",
763
+ entrypoint: resolveRoute("api/comments/[collection]/[contentId]/reactions.ts"),
764
+ });
765
+
761
766
  // Comment routes (admin)
762
767
  injectRoute({
763
768
  pattern: "/_emdash/api/admin/comments",
@@ -10,7 +10,12 @@
10
10
  import type { AuthDescriptor, AuthProviderDescriptor } from "../../auth/types.js";
11
11
  import type { DatabaseDescriptor } from "../../db/adapters.js";
12
12
  import type { MediaProviderDescriptor } from "../../media/types.js";
13
- import type { ResolvedPlugin } from "../../plugins/types.js";
13
+ import type { ObjectCacheDescriptor } from "../../object-cache/types.js";
14
+ import type {
15
+ FieldWidgetConfig,
16
+ PortableTextBlockConfig,
17
+ ResolvedPlugin,
18
+ } from "../../plugins/types.js";
14
19
  import type { ExperimentalConfig } from "../../registry/types.js";
15
20
  import type { StorageDescriptor } from "../storage/types.js";
16
21
 
@@ -98,6 +103,15 @@ export interface PluginDescriptor<TOptions = Record<string, unknown>> {
98
103
  adminPages?: PluginAdminPage[];
99
104
  /** Dashboard widgets */
100
105
  adminWidgets?: PluginDashboardWidget[];
106
+ /**
107
+ * Portable Text block types this plugin contributes to the editor.
108
+ * Declarative (Block Kit) — surfaced in the admin slash menu and consumed
109
+ * from the manifest, so standard/sandboxed plugins can contribute blocks
110
+ * without a native render component.
111
+ */
112
+ portableTextBlocks?: PortableTextBlockConfig[];
113
+ /** Field widget types this plugin contributes for schema-field editing UIs. */
114
+ fieldWidgets?: FieldWidgetConfig[];
101
115
 
102
116
  // === Sandbox-specific fields (for sandboxed plugins) ===
103
117
 
@@ -151,6 +165,56 @@ export interface EmDashConfig {
151
165
  * Storage configuration (for media)
152
166
  */
153
167
  storage?: StorageDescriptor;
168
+
169
+ /**
170
+ * Optional distributed object cache for query results.
171
+ *
172
+ * Off by default. When configured, content and chrome (settings, menus,
173
+ * taxonomies) reads are cached in a fast key/value store and served without
174
+ * touching the database on repeat requests across isolates. This offloads
175
+ * read pressure from D1/SQLite, which is especially valuable on Cloudflare
176
+ * where D1 has far lower request capacity than KV.
177
+ *
178
+ * Use a backend adapter:
179
+ * - `memoryCache()` from `emdash/astro` — in-isolate (Node / local dev)
180
+ * - `kvCache({ binding: "CACHE" })` from `@emdash-cms/cloudflare` — KV
181
+ *
182
+ * Preview and visual-edit requests bypass the cache, so editors previewing
183
+ * see live content. All other reads — including authenticated browsing outside
184
+ * edit mode — are served from the cache, which only ever stores published
185
+ * content. After an edit, anonymous visitors may see stale content until other
186
+ * isolates pick up the bumped epoch: immediate with the memory backend, and on
187
+ * KV bounded by KV's edge-cache propagation (eventual consistency, up to ~60s)
188
+ * plus the isolate-local `revalidate` window (default 1s).
189
+ *
190
+ * Scheduled content becomes visible at query time (no write event fires when
191
+ * its publish time passes), so a cached list/entry won't surface a newly-due
192
+ * scheduled item until the next write to that collection or until the
193
+ * entry's TTL lapses (`defaultTtl`, default 1h). Sites that rely on precise
194
+ * scheduled publishing should lower `defaultTtl` accordingly.
195
+ *
196
+ * @example
197
+ * ```ts
198
+ * import { kvCache } from "@emdash-cms/cloudflare";
199
+ *
200
+ * emdash({
201
+ * database: d1({ binding: "DB" }),
202
+ * objectCache: kvCache({ binding: "CACHE" }),
203
+ * })
204
+ * ```
205
+ */
206
+ objectCache?: ObjectCacheDescriptor;
207
+ /**
208
+ * Image optimization.
209
+ *
210
+ * By default EmDash wraps Astro's image endpoint so media served from
211
+ * storage is optimized through the normal `<Image>` / `getImage` pipeline,
212
+ * loading source bytes directly from the storage adapter (works behind
213
+ * Cloudflare Access). Set to `false` to leave Astro's image endpoint
214
+ * untouched -- media then renders as a plain `<img>` unless your image
215
+ * service can fetch it over HTTP.
216
+ */
217
+ images?: boolean;
154
218
  /**
155
219
  * Trusted plugins to load (run in main isolate)
156
220
  *
@@ -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
 
@@ -128,6 +131,31 @@ export const createStorage = _createStorage;
128
131
  `;
129
132
  }
130
133
 
134
+ /**
135
+ * Generates the object-cache virtual module.
136
+ *
137
+ * Statically imports the configured object-cache backend's `createObjectCache`
138
+ * factory and embeds its serializable config. When no object cache is
139
+ * configured, exports `undefined` so the runtime read-through layer becomes a
140
+ * transparent passthrough (cache off by default).
141
+ */
142
+ export function generateObjectCacheModule(
143
+ entrypoint?: string,
144
+ config?: Record<string, unknown>,
145
+ ): string {
146
+ if (!entrypoint) {
147
+ return [
148
+ `export const createObjectCache = undefined;`,
149
+ `export const objectCacheConfig = undefined;`,
150
+ ].join("\n");
151
+ }
152
+ return `
153
+ import { createObjectCache as _createObjectCache } from "${entrypoint}";
154
+ export const createObjectCache = _createObjectCache;
155
+ export const objectCacheConfig = ${JSON.stringify(config ?? {})};
156
+ `;
157
+ }
158
+
131
159
  /**
132
160
  * Generates the auth virtual module.
133
161
  * Statically imports the configured auth provider.
@@ -220,6 +248,8 @@ export function generatePluginsModule(descriptors: PluginDescriptor[]): string {
220
248
  storage: descriptor.storage,
221
249
  adminPages: descriptor.adminPages,
222
250
  adminWidgets: descriptor.adminWidgets,
251
+ portableTextBlocks: descriptor.portableTextBlocks,
252
+ fieldWidgets: descriptor.fieldWidgets,
223
253
  })})`,
224
254
  );
225
255
  } else {
@@ -589,6 +619,8 @@ export const sandboxedPlugins = [];
589
619
  storage: ${JSON.stringify(descriptor.storage ?? {})},
590
620
  adminPages: ${JSON.stringify(descriptor.adminPages ?? [])},
591
621
  adminWidgets: ${JSON.stringify(descriptor.adminWidgets ?? [])},
622
+ portableTextBlocks: ${JSON.stringify(descriptor.portableTextBlocks ?? [])},
623
+ fieldWidgets: ${JSON.stringify(descriptor.fieldWidgets ?? [])},
592
624
  adminEntry: ${JSON.stringify(descriptor.adminEntry)},
593
625
  // Code read from: ${filePath}
594
626
  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);
@@ -435,6 +449,8 @@ export function createViteConfig(
435
449
  // Top-level deps (use astro > path for pnpm compat)
436
450
  "astro > zod/v4",
437
451
  "astro > zod/v4/core",
452
+ // zod-generator imports the bare `zod` entry, not `zod/v4`
453
+ "emdash > zod",
438
454
  "@emdash-cms/cloudflare > kysely-d1",
439
455
  // Astro internal deps not covered by @astrojs/cloudflare adapter
440
456
  "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) {
@@ -18,7 +18,7 @@
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
23
 
24
24
  export const STREAM_END_PREFIX = "[emdash-stream-end]";
@@ -64,6 +64,14 @@ export function wrapBodyForStreamMetrics(response: Response): Response {
64
64
  if (!metrics) return response;
65
65
  const recorder = ctx?.queryRecorder;
66
66
 
67
+ // Claim the per-query flush: the recorder is mutated in-place by the
68
+ // Kysely log hook for the whole request, including queries issued by
69
+ // components while the body streams. Flushing here (rather than when
70
+ // middleware returns) is what captures those streaming queries. The
71
+ // flag tells the middleware's fallback flush to leave this recorder
72
+ // to us.
73
+ if (recorder) recorder.deferredFlush = true;
74
+
67
75
  const transform = new TransformStream<Uint8Array, Uint8Array>({
68
76
  flush() {
69
77
  const snapshot: StreamEndSnapshot = {
@@ -79,6 +87,8 @@ export function wrapBodyForStreamMetrics(response: Response): Response {
79
87
  cacheMisses: metrics.cacheMisses,
80
88
  };
81
89
  console.log(`${STREAM_END_PREFIX} ${JSON.stringify(snapshot)}`);
90
+ // Emit the full per-query log now that streaming is complete.
91
+ if (recorder) flushRecorder(recorder);
82
92
  },
83
93
  });
84
94
 
@@ -60,7 +60,9 @@ import { isMissingTableError } from "../utils/db-errors.js";
60
60
  import { createInitLock, type InitLock, initWithLock } from "../utils/init-lock.js";
61
61
  import type { EmDashConfig } from "./integration/runtime.js";
62
62
  import { wrapBodyForStreamMetrics } from "./middleware/stream-end-metrics.js";
63
+ import { prefetchLayoutData } from "./prefetch.js";
63
64
  import { createPublicPluginApiRouteHandler } from "./public-plugin-api-routes.js";
65
+ import { resolveSessionUser } from "./session-user.js";
64
66
  import type { EmDashHandlers } from "./types.js";
65
67
 
66
68
  /**
@@ -415,7 +417,7 @@ export const onRequest = defineMiddleware(async (context, next) => {
415
417
  // turns normal traffic into a flood of KV read misses. See #733.
416
418
  const hasSessionCookie = cookies.get("astro-session") !== undefined;
417
419
  const sessionUser =
418
- context.isPrerendered || !hasSessionCookie ? null : await context.session?.get("user");
420
+ context.isPrerendered || !hasSessionCookie ? null : await resolveSessionUser(context.session);
419
421
 
420
422
  if (!isEmDashRoute && !isPublicRuntimeRoute && !hasEditCookie && !hasPreviewToken) {
421
423
  if (!sessionUser && !playgroundDb) {
@@ -428,7 +430,13 @@ export const onRequest = defineMiddleware(async (context, next) => {
428
430
  // Do a one-time lightweight probe using the same getDb() instance the
429
431
  // page will use: if the migrations table doesn't exist, no migrations
430
432
  // have ever run -- redirect to the setup wizard.
431
- if (!isSetupVerified()) {
433
+ // Skip the probe when prerendering: a prerendered route is built to
434
+ // static HTML, so returning context.redirect("/_emdash/admin/setup")
435
+ // below would bake that redirect into the page and ship it to
436
+ // production. The build database is legitimately empty in CI and there
437
+ // is no live visitor to send to the wizard at build time (session reads
438
+ // are already skipped for prerender above for the same reason).
439
+ if (!isSetupVerified() && !context.isPrerendered) {
432
440
  const t0 = performance.now();
433
441
  try {
434
442
  const { getDb } = await import("../loader.js");
@@ -475,6 +483,10 @@ export const onRequest = defineMiddleware(async (context, next) => {
475
483
  collectPageMetadata: runtime.collectPageMetadata.bind(runtime),
476
484
  collectPageFragments: runtime.collectPageFragments.bind(runtime),
477
485
  getPublicMediaUrl: createPublicMediaUrlResolver(runtime.storage),
486
+ // Exposed so the wrapped image endpoint (`/_image`) can read media
487
+ // bytes from storage on the anonymous fast path -- public `<img>`
488
+ // requests carry no session.
489
+ storage: runtime.storage,
478
490
  } as EmDashHandlers;
479
491
  } catch {
480
492
  // Non-fatal — EmDashHead will fall back to base SEO contributions
@@ -512,7 +524,28 @@ export const onRequest = defineMiddleware(async (context, next) => {
512
524
  const ctx = parent
513
525
  ? { ...parent, db: anonScoped.db }
514
526
  : { editMode: false, db: anonScoped.db, metrics };
527
+ // Eagerly warm site-global layout data (menus, widget areas,
528
+ // taxonomy terms, settings) concurrently so the layout's
529
+ // per-component reads overlap into ~one wall-clock round trip and
530
+ // hit a warm cache instead of serializing. Three guards:
531
+ // - request-scoped (remote) backend only -- this branch implies it;
532
+ // pointless on synchronous local SQLite.
533
+ // - HTML navigations only -- feeds/sitemaps/JSON don't render the
534
+ // layout, so prefetching their chrome is pure waste.
535
+ // - via after(): it runs immediately (still warms the render) but
536
+ // hands the promise to waitUntil, so the surplus warm-up (chrome a
537
+ // given page doesn't render) is kept alive past the response rather
538
+ // than erroring on workerd as orphaned request I/O.
539
+ // Gate on the CLIENT'S PREFERRED type (leading media range), not a
540
+ // substring -- browser navigations lead with `text/html`, while feed
541
+ // readers lead with `application/rss+xml` etc. and only list
542
+ // `text/html;q=0.8` later, so a substring match would leak onto feeds.
543
+ const acceptsHtml = (request.headers.get("accept") ?? "")
544
+ .split(",", 1)[0]!
545
+ .trim()
546
+ .startsWith("text/html");
515
547
  return runWithContext(ctx, async () => {
548
+ if (acceptsHtml) after(() => prefetchLayoutData());
516
549
  // commit() in finally: the write reached the primary independently
517
550
  // of render, so the bookmark cookie must be persisted even if
518
551
  // render throws -- otherwise a write-then-failed-render leaves the
@@ -723,7 +756,12 @@ export const onRequest = defineMiddleware(async (context, next) => {
723
756
  try {
724
757
  return await runWithContext({ editMode: false, queryRecorder, metrics }, run);
725
758
  } finally {
726
- if (queryRecorder) flushRecorder(queryRecorder);
759
+ // Streamed responses defer the flush to stream end (see
760
+ // wrapBodyForStreamMetrics) so the log captures queries issued while
761
+ // the body renders. Only flush here for responses that were not
762
+ // wrapped (no body: redirects, 304s, bodyless errors), where all
763
+ // queries have already run by the time middleware returns.
764
+ if (queryRecorder && !queryRecorder.deferredFlush) flushRecorder(queryRecorder);
727
765
  }
728
766
  });
729
767
 
@@ -0,0 +1,50 @@
1
+ /**
2
+ * Object-cache adapter functions (config time).
3
+ *
4
+ * These run in `astro.config.mjs` and return serializable
5
+ * {@link ObjectCacheDescriptor}s. The backend is instantiated at runtime by
6
+ * loading the descriptor's `entrypoint`.
7
+ *
8
+ * For Cloudflare KV, use `kvCache()` from `@emdash-cms/cloudflare`.
9
+ *
10
+ * @example
11
+ * ```ts
12
+ * // astro.config.mjs (Node / local)
13
+ * import emdash, { memoryCache } from "emdash/astro";
14
+ *
15
+ * export default defineConfig({
16
+ * integrations: [emdash({ objectCache: memoryCache() })],
17
+ * });
18
+ * ```
19
+ */
20
+
21
+ import type { ObjectCacheDescriptor, ObjectCacheRuntimeConfig } from "../../object-cache/types.js";
22
+
23
+ /** Options for {@link memoryCache}. */
24
+ export interface MemoryCacheOptions extends ObjectCacheRuntimeConfig {
25
+ /**
26
+ * Soft cap on the number of cached keys per isolate before FIFO eviction.
27
+ * @default 1000
28
+ */
29
+ maxEntries?: number;
30
+ }
31
+
32
+ /**
33
+ * In-isolate memory object cache.
34
+ *
35
+ * Caches query results across requests within a single isolate/process. On
36
+ * Node (one long-lived process) this is a genuine cross-request cache; on
37
+ * multi-isolate platforms (Cloudflare) prefer `kvCache()` so the cache is
38
+ * shared. Useful for local development regardless of target.
39
+ *
40
+ * @example
41
+ * ```ts
42
+ * emdash({ objectCache: memoryCache({ defaultTtl: 600 }) })
43
+ * ```
44
+ */
45
+ export function memoryCache(options: MemoryCacheOptions = {}): ObjectCacheDescriptor {
46
+ return {
47
+ entrypoint: "emdash/object-cache/memory",
48
+ config: { ...options },
49
+ };
50
+ }
@@ -0,0 +1,77 @@
1
+ /**
2
+ * Eager, transparent prefetch of site-global "chrome" data.
3
+ *
4
+ * On a public page render, the shared layout pulls the same site-global data on
5
+ * every request -- menus, widget areas, taxonomy term lists, site settings --
6
+ * but each is awaited inside a separately-rendered Astro component, so they
7
+ * execute as serial DB round trips. This fires them all CONCURRENTLY at the
8
+ * very start of the request, before `next()`:
9
+ *
10
+ * - On remote backends (D1, Durable Objects) the round trips overlap instead
11
+ * of serializing, collapsing ~N sequential RTTs into ~1 wall-clock RTT. On
12
+ * a coalescing backend they additionally batch into a single round trip.
13
+ * - The results land in the per-request `requestCached` store under the exact
14
+ * keys the layout helpers use, so when the components render they hit a warm
15
+ * (in-flight or resolved) cache entry instead of issuing their own query.
16
+ *
17
+ * Nothing here changes what templates call -- it warms the real helpers, so the
18
+ * cache keys and value shapes are guaranteed identical. The caller gates this to
19
+ * the public-page path on a request-scoped (remote) backend; it is a no-op-ish
20
+ * waste on synchronous local SQLite, so don't call it there.
21
+ *
22
+ * Fire-and-forget: never awaited by middleware, never throws (a prefetch failure
23
+ * must not affect the request -- the helpers will simply run on demand).
24
+ */
25
+
26
+ import { getDb } from "../loader.js";
27
+ import { getMenu } from "../menus/index.js";
28
+ import { setRequestCacheEntry } from "../request-cache.js";
29
+ import { getSiteSettings } from "../settings/index.js";
30
+ import { getTaxonomyDefs, getTaxonomyTerms } from "../taxonomies/index.js";
31
+ import { getWidgetAreas } from "../widgets/index.js";
32
+
33
+ /** Warm widget areas: one bulk load, primed under each per-area cache key. */
34
+ async function prefetchWidgetAreas(): Promise<void> {
35
+ const areas = await getWidgetAreas();
36
+ // getWidgetArea(name) caches under `widget-area:${name}` and returns the same
37
+ // WidgetArea shape getWidgetAreas yields, so priming here makes those calls hit.
38
+ for (const area of areas) {
39
+ setRequestCacheEntry(`widget-area:${area.name}`, area);
40
+ }
41
+ }
42
+
43
+ /** Warm every taxonomy's term list via the real helper (primes per-name keys). */
44
+ async function prefetchTaxonomyTerms(): Promise<void> {
45
+ const defs = await getTaxonomyDefs();
46
+ await Promise.allSettled(defs.map((def) => getTaxonomyTerms(def.name)));
47
+ }
48
+
49
+ /** Warm every menu via the real helper (primes `menu:${name}:${locale}`). */
50
+ async function prefetchMenus(): Promise<void> {
51
+ const db = await getDb();
52
+ // The layout calls getMenu(name) with hardcoded names; we can't know them, so
53
+ // discover every menu name and warm them all (small, bounded chrome table).
54
+ const rows = await db.selectFrom("_emdash_menus").select("name").distinct().execute();
55
+ const names = [...new Set(rows.map((r) => r.name))];
56
+ await Promise.allSettled(names.map((name) => getMenu(name)));
57
+ }
58
+
59
+ /**
60
+ * Concurrently warm the site-global layout data for the current request.
61
+ * Safe to call only inside the request ALS frame that owns the (remote)
62
+ * request-scoped db. Never throws.
63
+ */
64
+ export async function prefetchLayoutData(): Promise<void> {
65
+ try {
66
+ await Promise.allSettled([
67
+ getSiteSettings(),
68
+ prefetchMenus(),
69
+ prefetchWidgetAreas(),
70
+ prefetchTaxonomyTerms(),
71
+ ]);
72
+ } catch (error) {
73
+ // Defensive: Promise.allSettled shouldn't reject, but never let a prefetch
74
+ // failure surface to the request.
75
+ console.error("[emdash] layout prefetch failed (non-fatal):", error);
76
+ }
77
+ }