emdash 0.29.0 → 0.31.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 (876) hide show
  1. package/dist/{adapters-DPAkL6QF.d.mts → adapters-C0ONzkUP.d.mts} +10 -1
  2. package/dist/adapters-C0ONzkUP.d.mts.map +1 -0
  3. package/dist/{allowed-origins-FXB-FplB.mjs → allowed-origins-CCEi9bPI.mjs} +2 -2
  4. package/dist/{allowed-origins-FXB-FplB.mjs.map → allowed-origins-CCEi9bPI.mjs.map} +1 -1
  5. package/dist/api/route-utils.d.mts +3 -3
  6. package/dist/api/route-utils.d.mts.map +1 -1
  7. package/dist/api/route-utils.mjs +19 -19
  8. package/dist/api/schemas/index.d.mts +2 -2
  9. package/dist/api/schemas/index.mjs +5 -4
  10. package/dist/{api-DVbHNApo.mjs → api-EibxGP-V.mjs} +260 -160
  11. package/dist/api-EibxGP-V.mjs.map +1 -0
  12. package/dist/api-tokens-Cvmixds7.mjs +3 -0
  13. package/dist/{api-tokens-UYBkl17d.mjs → api-tokens-uPt8UDpx.mjs} +2 -2
  14. package/dist/{api-tokens-UYBkl17d.mjs.map → api-tokens-uPt8UDpx.mjs.map} +1 -1
  15. package/dist/{apply-D23iUV4q.mjs → apply-fGHCAwWN.mjs} +42 -44
  16. package/dist/apply-fGHCAwWN.mjs.map +1 -0
  17. package/dist/astro/index.d.mts +12 -13
  18. package/dist/astro/index.d.mts.map +1 -1
  19. package/dist/astro/index.mjs +90 -11
  20. package/dist/astro/index.mjs.map +1 -1
  21. package/dist/astro/middleware/auth.d.mts +10 -11
  22. package/dist/astro/middleware/auth.d.mts.map +1 -1
  23. package/dist/astro/middleware/auth.mjs +56 -107
  24. package/dist/astro/middleware/auth.mjs.map +1 -1
  25. package/dist/astro/middleware/redirect.mjs +7 -7
  26. package/dist/astro/middleware/request-context.mjs +4 -4
  27. package/dist/astro/middleware/request-context.mjs.map +1 -1
  28. package/dist/astro/middleware/setup.mjs +1 -1
  29. package/dist/astro/middleware.d.mts +47 -3
  30. package/dist/astro/middleware.d.mts.map +1 -1
  31. package/dist/astro/middleware.mjs +410 -123
  32. package/dist/astro/middleware.mjs.map +1 -1
  33. package/dist/astro/routes/PluginRegistry.d.mts +5 -1
  34. package/dist/astro/routes/PluginRegistry.d.mts.map +1 -1
  35. package/dist/astro/routes/PluginRegistry.mjs +2 -1
  36. package/dist/astro/routes/PluginRegistry.mjs.map +1 -1
  37. package/dist/astro/routes/api/admin/allowed-domains/_domain_.mjs +9 -8
  38. package/dist/astro/routes/api/admin/allowed-domains/_domain_.mjs.map +1 -1
  39. package/dist/astro/routes/api/admin/allowed-domains/index.mjs +9 -8
  40. package/dist/astro/routes/api/admin/allowed-domains/index.mjs.map +1 -1
  41. package/dist/astro/routes/api/admin/api-tokens/_id_.mjs +5 -5
  42. package/dist/astro/routes/api/admin/api-tokens/index.mjs +7 -7
  43. package/dist/astro/routes/api/admin/api-tokens/index.mjs.map +1 -1
  44. package/dist/astro/routes/api/admin/byline-fields/_slug_/usage.mjs +5 -5
  45. package/dist/astro/routes/api/admin/byline-fields/_slug_.mjs +10 -9
  46. package/dist/astro/routes/api/admin/byline-fields/_slug_.mjs.map +1 -1
  47. package/dist/astro/routes/api/admin/byline-fields/index.mjs +10 -9
  48. package/dist/astro/routes/api/admin/byline-fields/index.mjs.map +1 -1
  49. package/dist/astro/routes/api/admin/byline-fields/reorder.mjs +10 -9
  50. package/dist/astro/routes/api/admin/byline-fields/reorder.mjs.map +1 -1
  51. package/dist/astro/routes/api/admin/bylines/_id_/index.mjs +16 -15
  52. package/dist/astro/routes/api/admin/bylines/_id_/index.mjs.map +1 -1
  53. package/dist/astro/routes/api/admin/bylines/_id_/translations.mjs +17 -22
  54. package/dist/astro/routes/api/admin/bylines/_id_/translations.mjs.map +1 -1
  55. package/dist/astro/routes/api/admin/bylines/index.d.mts.map +1 -1
  56. package/dist/astro/routes/api/admin/bylines/index.mjs +20 -18
  57. package/dist/astro/routes/api/admin/bylines/index.mjs.map +1 -1
  58. package/dist/astro/routes/api/admin/comments/_id_/status.mjs +13 -12
  59. package/dist/astro/routes/api/admin/comments/_id_/status.mjs.map +1 -1
  60. package/dist/astro/routes/api/admin/comments/_id_.mjs +6 -6
  61. package/dist/astro/routes/api/admin/comments/bulk.mjs +11 -10
  62. package/dist/astro/routes/api/admin/comments/bulk.mjs.map +1 -1
  63. package/dist/astro/routes/api/admin/comments/counts.mjs +6 -6
  64. package/dist/astro/routes/api/admin/comments/index.mjs +11 -10
  65. package/dist/astro/routes/api/admin/comments/index.mjs.map +1 -1
  66. package/dist/astro/routes/api/admin/hooks/exclusive/_hookName_.mjs +5 -5
  67. package/dist/astro/routes/api/admin/hooks/exclusive/index.mjs +4 -4
  68. package/dist/astro/routes/api/admin/media-usage/repair.mjs +12 -10
  69. package/dist/astro/routes/api/admin/media-usage/repair.mjs.map +1 -1
  70. package/dist/astro/routes/api/admin/oauth-clients/_id_.mjs +5 -5
  71. package/dist/astro/routes/api/admin/oauth-clients/index.mjs +5 -5
  72. package/dist/astro/routes/api/admin/plugins/_id_/disable.mjs +41 -40
  73. package/dist/astro/routes/api/admin/plugins/_id_/disable.mjs.map +1 -1
  74. package/dist/astro/routes/api/admin/plugins/_id_/enable.mjs +41 -40
  75. package/dist/astro/routes/api/admin/plugins/_id_/enable.mjs.map +1 -1
  76. package/dist/astro/routes/api/admin/plugins/_id_/index.mjs +46 -40
  77. package/dist/astro/routes/api/admin/plugins/_id_/index.mjs.map +1 -1
  78. package/dist/astro/routes/api/admin/plugins/_id_/mcp.d.mts +8 -0
  79. package/dist/astro/routes/api/admin/plugins/_id_/mcp.d.mts.map +1 -0
  80. package/dist/astro/routes/api/admin/plugins/_id_/mcp.mjs +39 -0
  81. package/dist/astro/routes/api/admin/plugins/_id_/mcp.mjs.map +1 -0
  82. package/dist/astro/routes/api/admin/plugins/_id_/settings.d.mts +9 -0
  83. package/dist/astro/routes/api/admin/plugins/_id_/settings.d.mts.map +1 -0
  84. package/dist/astro/routes/api/admin/plugins/_id_/settings.mjs +78 -0
  85. package/dist/astro/routes/api/admin/plugins/_id_/settings.mjs.map +1 -0
  86. package/dist/astro/routes/api/admin/plugins/_id_/uninstall.mjs +40 -39
  87. package/dist/astro/routes/api/admin/plugins/_id_/uninstall.mjs.map +1 -1
  88. package/dist/astro/routes/api/admin/plugins/_id_/update.d.mts.map +1 -1
  89. package/dist/astro/routes/api/admin/plugins/_id_/update.mjs +43 -40
  90. package/dist/astro/routes/api/admin/plugins/_id_/update.mjs.map +1 -1
  91. package/dist/astro/routes/api/admin/plugins/index.mjs +46 -40
  92. package/dist/astro/routes/api/admin/plugins/index.mjs.map +1 -1
  93. package/dist/astro/routes/api/admin/plugins/marketplace/_id_/icon.mjs +4 -4
  94. package/dist/astro/routes/api/admin/plugins/marketplace/_id_/index.mjs +40 -39
  95. package/dist/astro/routes/api/admin/plugins/marketplace/_id_/index.mjs.map +1 -1
  96. package/dist/astro/routes/api/admin/plugins/marketplace/_id_/install.d.mts.map +1 -1
  97. package/dist/astro/routes/api/admin/plugins/marketplace/_id_/install.mjs +46 -41
  98. package/dist/astro/routes/api/admin/plugins/marketplace/_id_/install.mjs.map +1 -1
  99. package/dist/astro/routes/api/admin/plugins/marketplace/index.mjs +40 -39
  100. package/dist/astro/routes/api/admin/plugins/marketplace/index.mjs.map +1 -1
  101. package/dist/astro/routes/api/admin/plugins/registry/_id_/uninstall.mjs +40 -39
  102. package/dist/astro/routes/api/admin/plugins/registry/_id_/uninstall.mjs.map +1 -1
  103. package/dist/astro/routes/api/admin/plugins/registry/_id_/update.d.mts.map +1 -1
  104. package/dist/astro/routes/api/admin/plugins/registry/_id_/update.mjs +44 -41
  105. package/dist/astro/routes/api/admin/plugins/registry/_id_/update.mjs.map +1 -1
  106. package/dist/astro/routes/api/admin/plugins/registry/artifact.mjs +40 -39
  107. package/dist/astro/routes/api/admin/plugins/registry/artifact.mjs.map +1 -1
  108. package/dist/astro/routes/api/admin/plugins/registry/install.d.mts.map +1 -1
  109. package/dist/astro/routes/api/admin/plugins/registry/install.mjs +45 -42
  110. package/dist/astro/routes/api/admin/plugins/registry/install.mjs.map +1 -1
  111. package/dist/astro/routes/api/admin/plugins/updates.mjs +41 -40
  112. package/dist/astro/routes/api/admin/plugins/updates.mjs.map +1 -1
  113. package/dist/astro/routes/api/admin/themes/marketplace/_id_/index.mjs +40 -39
  114. package/dist/astro/routes/api/admin/themes/marketplace/_id_/index.mjs.map +1 -1
  115. package/dist/astro/routes/api/admin/themes/marketplace/_id_/thumbnail.mjs +4 -4
  116. package/dist/astro/routes/api/admin/themes/marketplace/index.mjs +40 -39
  117. package/dist/astro/routes/api/admin/themes/marketplace/index.mjs.map +1 -1
  118. package/dist/astro/routes/api/admin/users/_id_/disable.mjs +4 -4
  119. package/dist/astro/routes/api/admin/users/_id_/enable.mjs +4 -4
  120. package/dist/astro/routes/api/admin/users/_id_/index.mjs +9 -8
  121. package/dist/astro/routes/api/admin/users/_id_/index.mjs.map +1 -1
  122. package/dist/astro/routes/api/admin/users/_id_/send-recovery.mjs +5 -5
  123. package/dist/astro/routes/api/admin/users/index.mjs +9 -8
  124. package/dist/astro/routes/api/admin/users/index.mjs.map +1 -1
  125. package/dist/astro/routes/api/auth/dev-bypass.mjs +7 -7
  126. package/dist/astro/routes/api/auth/invite/accept.mjs +4 -4
  127. package/dist/astro/routes/api/auth/invite/complete.mjs +13 -12
  128. package/dist/astro/routes/api/auth/invite/complete.mjs.map +1 -1
  129. package/dist/astro/routes/api/auth/invite/index.mjs +10 -9
  130. package/dist/astro/routes/api/auth/invite/index.mjs.map +1 -1
  131. package/dist/astro/routes/api/auth/invite/register-options.mjs +12 -11
  132. package/dist/astro/routes/api/auth/invite/register-options.mjs.map +1 -1
  133. package/dist/astro/routes/api/auth/logout.mjs +4 -4
  134. package/dist/astro/routes/api/auth/magic-link/send.mjs +12 -11
  135. package/dist/astro/routes/api/auth/magic-link/send.mjs.map +1 -1
  136. package/dist/astro/routes/api/auth/magic-link/verify.mjs +5 -5
  137. package/dist/astro/routes/api/auth/me.mjs +9 -8
  138. package/dist/astro/routes/api/auth/me.mjs.map +1 -1
  139. package/dist/astro/routes/api/auth/mode.d.mts.map +1 -1
  140. package/dist/astro/routes/api/auth/mode.mjs +6 -3
  141. package/dist/astro/routes/api/auth/mode.mjs.map +1 -1
  142. package/dist/astro/routes/api/auth/oauth/_provider_/callback.mjs +15 -5
  143. package/dist/astro/routes/api/auth/oauth/_provider_/callback.mjs.map +1 -1
  144. package/dist/astro/routes/api/auth/oauth/_provider_.d.mts.map +1 -1
  145. package/dist/astro/routes/api/auth/oauth/_provider_.mjs +11 -5
  146. package/dist/astro/routes/api/auth/oauth/_provider_.mjs.map +1 -1
  147. package/dist/astro/routes/api/auth/passkey/_id_.mjs +8 -7
  148. package/dist/astro/routes/api/auth/passkey/_id_.mjs.map +1 -1
  149. package/dist/astro/routes/api/auth/passkey/index.mjs +3 -3
  150. package/dist/astro/routes/api/auth/passkey/options.mjs +13 -12
  151. package/dist/astro/routes/api/auth/passkey/options.mjs.map +1 -1
  152. package/dist/astro/routes/api/auth/passkey/register/options.mjs +11 -10
  153. package/dist/astro/routes/api/auth/passkey/register/options.mjs.map +1 -1
  154. package/dist/astro/routes/api/auth/passkey/register/verify.mjs +12 -11
  155. package/dist/astro/routes/api/auth/passkey/register/verify.mjs.map +1 -1
  156. package/dist/astro/routes/api/auth/passkey/verify.mjs +12 -11
  157. package/dist/astro/routes/api/auth/passkey/verify.mjs.map +1 -1
  158. package/dist/astro/routes/api/auth/signup/complete.mjs +13 -12
  159. package/dist/astro/routes/api/auth/signup/complete.mjs.map +1 -1
  160. package/dist/astro/routes/api/auth/signup/request.mjs +12 -11
  161. package/dist/astro/routes/api/auth/signup/request.mjs.map +1 -1
  162. package/dist/astro/routes/api/auth/signup/verify.mjs +4 -4
  163. package/dist/astro/routes/api/comments/_collection_/_contentId_/index.mjs +14 -13
  164. package/dist/astro/routes/api/comments/_collection_/_contentId_/index.mjs.map +1 -1
  165. package/dist/astro/routes/api/comments/_collection_/_contentId_/reactions.mjs +13 -12
  166. package/dist/astro/routes/api/comments/_collection_/_contentId_/reactions.mjs.map +1 -1
  167. package/dist/astro/routes/api/content/_collection_/_id_/compare.mjs +5 -5
  168. package/dist/astro/routes/api/content/_collection_/_id_/compare.mjs.map +1 -1
  169. package/dist/astro/routes/api/content/_collection_/_id_/discard-draft.mjs +5 -4
  170. package/dist/astro/routes/api/content/_collection_/_id_/discard-draft.mjs.map +1 -1
  171. package/dist/astro/routes/api/content/_collection_/_id_/duplicate.mjs +6 -5
  172. package/dist/astro/routes/api/content/_collection_/_id_/duplicate.mjs.map +1 -1
  173. package/dist/astro/routes/api/content/_collection_/_id_/permanent.mjs +5 -5
  174. package/dist/astro/routes/api/content/_collection_/_id_/permanent.mjs.map +1 -1
  175. package/dist/astro/routes/api/content/_collection_/_id_/preview-url.mjs +14 -13
  176. package/dist/astro/routes/api/content/_collection_/_id_/preview-url.mjs.map +1 -1
  177. package/dist/astro/routes/api/content/_collection_/_id_/publish.mjs +10 -8
  178. package/dist/astro/routes/api/content/_collection_/_id_/publish.mjs.map +1 -1
  179. package/dist/astro/routes/api/content/_collection_/_id_/references/_relation_/children.d.mts.map +1 -1
  180. package/dist/astro/routes/api/content/_collection_/_id_/references/_relation_/children.mjs +20 -19
  181. package/dist/astro/routes/api/content/_collection_/_id_/references/_relation_/children.mjs.map +1 -1
  182. package/dist/astro/routes/api/content/_collection_/_id_/references/_relation_/parents.mjs +18 -17
  183. package/dist/astro/routes/api/content/_collection_/_id_/references/_relation_/parents.mjs.map +1 -1
  184. package/dist/astro/routes/api/content/_collection_/_id_/restore.mjs +5 -4
  185. package/dist/astro/routes/api/content/_collection_/_id_/restore.mjs.map +1 -1
  186. package/dist/astro/routes/api/content/_collection_/_id_/revisions.mjs +5 -5
  187. package/dist/astro/routes/api/content/_collection_/_id_/revisions.mjs.map +1 -1
  188. package/dist/astro/routes/api/content/_collection_/_id_/schedule.mjs +10 -8
  189. package/dist/astro/routes/api/content/_collection_/_id_/schedule.mjs.map +1 -1
  190. package/dist/astro/routes/api/content/_collection_/_id_/terms/_taxonomy_.d.mts.map +1 -1
  191. package/dist/astro/routes/api/content/_collection_/_id_/terms/_taxonomy_.mjs +19 -18
  192. package/dist/astro/routes/api/content/_collection_/_id_/terms/_taxonomy_.mjs.map +1 -1
  193. package/dist/astro/routes/api/content/_collection_/_id_/translations.mjs +5 -5
  194. package/dist/astro/routes/api/content/_collection_/_id_/translations.mjs.map +1 -1
  195. package/dist/astro/routes/api/content/_collection_/_id_/unpublish.mjs +5 -4
  196. package/dist/astro/routes/api/content/_collection_/_id_/unpublish.mjs.map +1 -1
  197. package/dist/astro/routes/api/content/_collection_/_id_.d.mts.map +1 -1
  198. package/dist/astro/routes/api/content/_collection_/_id_.mjs +11 -9
  199. package/dist/astro/routes/api/content/_collection_/_id_.mjs.map +1 -1
  200. package/dist/astro/routes/api/content/_collection_/authors.mjs +5 -5
  201. package/dist/astro/routes/api/content/_collection_/authors.mjs.map +1 -1
  202. package/dist/astro/routes/api/content/_collection_/index.d.mts.map +1 -1
  203. package/dist/astro/routes/api/content/_collection_/index.mjs +12 -10
  204. package/dist/astro/routes/api/content/_collection_/index.mjs.map +1 -1
  205. package/dist/astro/routes/api/content/_collection_/trash.mjs +10 -9
  206. package/dist/astro/routes/api/content/_collection_/trash.mjs.map +1 -1
  207. package/dist/astro/routes/api/dashboard.mjs +8 -8
  208. package/dist/astro/routes/api/dev/emails.mjs +4 -4
  209. package/dist/astro/routes/api/import/probe.d.mts +3 -3
  210. package/dist/astro/routes/api/import/probe.mjs +17 -16
  211. package/dist/astro/routes/api/import/probe.mjs.map +1 -1
  212. package/dist/astro/routes/api/import/wordpress/analyze.mjs +4 -4
  213. package/dist/astro/routes/api/import/wordpress/execute.d.mts +11 -12
  214. package/dist/astro/routes/api/import/wordpress/execute.d.mts.map +1 -1
  215. package/dist/astro/routes/api/import/wordpress/execute.mjs +13 -13
  216. package/dist/astro/routes/api/import/wordpress/media.d.mts +10 -11
  217. package/dist/astro/routes/api/import/wordpress/media.d.mts.map +1 -1
  218. package/dist/astro/routes/api/import/wordpress/media.mjs +11 -10
  219. package/dist/astro/routes/api/import/wordpress/media.mjs.map +1 -1
  220. package/dist/astro/routes/api/import/wordpress/prepare.mjs +11 -10
  221. package/dist/astro/routes/api/import/wordpress/prepare.mjs.map +1 -1
  222. package/dist/astro/routes/api/import/wordpress/rewrite-urls.d.mts +11 -12
  223. package/dist/astro/routes/api/import/wordpress/rewrite-urls.d.mts.map +1 -1
  224. package/dist/astro/routes/api/import/wordpress/rewrite-urls.mjs +11 -10
  225. package/dist/astro/routes/api/import/wordpress/rewrite-urls.mjs.map +1 -1
  226. package/dist/astro/routes/api/import/wordpress-plugin/analyze.d.mts +1 -1
  227. package/dist/astro/routes/api/import/wordpress-plugin/analyze.mjs +17 -16
  228. package/dist/astro/routes/api/import/wordpress-plugin/analyze.mjs.map +1 -1
  229. package/dist/astro/routes/api/import/wordpress-plugin/callback.mjs +1 -1
  230. package/dist/astro/routes/api/import/wordpress-plugin/execute.d.mts +11 -12
  231. package/dist/astro/routes/api/import/wordpress-plugin/execute.d.mts.map +1 -1
  232. package/dist/astro/routes/api/import/wordpress-plugin/execute.mjs +24 -23
  233. package/dist/astro/routes/api/import/wordpress-plugin/execute.mjs.map +1 -1
  234. package/dist/astro/routes/api/manifest.mjs +7 -8
  235. package/dist/astro/routes/api/manifest.mjs.map +1 -1
  236. package/dist/astro/routes/api/mcp.d.mts.map +1 -1
  237. package/dist/astro/routes/api/mcp.mjs +149 -45
  238. package/dist/astro/routes/api/mcp.mjs.map +1 -1
  239. package/dist/astro/routes/api/media/_id_/confirm.mjs +9 -8
  240. package/dist/astro/routes/api/media/_id_/confirm.mjs.map +1 -1
  241. package/dist/astro/routes/api/media/_id_/usage.d.mts +8 -0
  242. package/dist/astro/routes/api/media/_id_/usage.d.mts.map +1 -0
  243. package/dist/astro/routes/api/media/_id_/usage.mjs +37 -0
  244. package/dist/astro/routes/api/media/_id_/usage.mjs.map +1 -0
  245. package/dist/astro/routes/api/media/_id_.d.mts.map +1 -1
  246. package/dist/astro/routes/api/media/_id_.mjs +26 -10
  247. package/dist/astro/routes/api/media/_id_.mjs.map +1 -1
  248. package/dist/astro/routes/api/media/file/_...key_.mjs +4 -3
  249. package/dist/astro/routes/api/media/file/_...key_.mjs.map +1 -1
  250. package/dist/astro/routes/api/media/providers/_providerId_/_itemId_.mjs +4 -4
  251. package/dist/astro/routes/api/media/providers/_providerId_/index.mjs +4 -4
  252. package/dist/astro/routes/api/media/providers/index.mjs +4 -4
  253. package/dist/astro/routes/api/media/upload-url.mjs +10 -9
  254. package/dist/astro/routes/api/media/upload-url.mjs.map +1 -1
  255. package/dist/astro/routes/api/media.d.mts.map +1 -1
  256. package/dist/astro/routes/api/media.mjs +31 -11
  257. package/dist/astro/routes/api/media.mjs.map +1 -1
  258. package/dist/astro/routes/api/menus/_name_/items/_id_.mjs +10 -9
  259. package/dist/astro/routes/api/menus/_name_/items/_id_.mjs.map +1 -1
  260. package/dist/astro/routes/api/menus/_name_/items.mjs +10 -9
  261. package/dist/astro/routes/api/menus/_name_/items.mjs.map +1 -1
  262. package/dist/astro/routes/api/menus/_name_/reorder.mjs +10 -9
  263. package/dist/astro/routes/api/menus/_name_/reorder.mjs.map +1 -1
  264. package/dist/astro/routes/api/menus/_name_/translations.mjs +10 -9
  265. package/dist/astro/routes/api/menus/_name_/translations.mjs.map +1 -1
  266. package/dist/astro/routes/api/menus/_name_.mjs +10 -9
  267. package/dist/astro/routes/api/menus/_name_.mjs.map +1 -1
  268. package/dist/astro/routes/api/menus/index.mjs +10 -9
  269. package/dist/astro/routes/api/menus/index.mjs.map +1 -1
  270. package/dist/astro/routes/api/oauth/authorize.d.mts.map +1 -1
  271. package/dist/astro/routes/api/oauth/authorize.mjs +29 -16
  272. package/dist/astro/routes/api/oauth/authorize.mjs.map +1 -1
  273. package/dist/astro/routes/api/oauth/device/authorize.mjs +7 -7
  274. package/dist/astro/routes/api/oauth/device/code.mjs +10 -10
  275. package/dist/astro/routes/api/oauth/device/token.mjs +9 -9
  276. package/dist/astro/routes/api/oauth/register.mjs +4 -4
  277. package/dist/astro/routes/api/oauth/token/refresh.mjs +7 -7
  278. package/dist/astro/routes/api/oauth/token/revoke.mjs +7 -7
  279. package/dist/astro/routes/api/oauth/token.mjs +7 -7
  280. package/dist/astro/routes/api/openapi.json.mjs +52 -24
  281. package/dist/astro/routes/api/openapi.json.mjs.map +1 -1
  282. package/dist/astro/routes/api/plugins/_pluginId_/_...path_.d.mts.map +1 -1
  283. package/dist/astro/routes/api/plugins/_pluginId_/_...path_.mjs +20 -32
  284. package/dist/astro/routes/api/plugins/_pluginId_/_...path_.mjs.map +1 -1
  285. package/dist/astro/routes/api/redirects/404s/index.mjs +12 -11
  286. package/dist/astro/routes/api/redirects/404s/index.mjs.map +1 -1
  287. package/dist/astro/routes/api/redirects/404s/summary.mjs +12 -11
  288. package/dist/astro/routes/api/redirects/404s/summary.mjs.map +1 -1
  289. package/dist/astro/routes/api/redirects/_id_.mjs +13 -12
  290. package/dist/astro/routes/api/redirects/_id_.mjs.map +1 -1
  291. package/dist/astro/routes/api/redirects/index.mjs +13 -12
  292. package/dist/astro/routes/api/redirects/index.mjs.map +1 -1
  293. package/dist/astro/routes/api/relations/_id_/index.mjs +16 -15
  294. package/dist/astro/routes/api/relations/_id_/index.mjs.map +1 -1
  295. package/dist/astro/routes/api/relations/_id_/translations.mjs +11 -11
  296. package/dist/astro/routes/api/relations/index.mjs +16 -15
  297. package/dist/astro/routes/api/relations/index.mjs.map +1 -1
  298. package/dist/astro/routes/api/revisions/_revisionId_/index.mjs +4 -4
  299. package/dist/astro/routes/api/revisions/_revisionId_/restore.mjs +5 -4
  300. package/dist/astro/routes/api/revisions/_revisionId_/restore.mjs.map +1 -1
  301. package/dist/astro/routes/api/schema/collections/_slug_/fields/_fieldSlug_.mjs +40 -39
  302. package/dist/astro/routes/api/schema/collections/_slug_/fields/_fieldSlug_.mjs.map +1 -1
  303. package/dist/astro/routes/api/schema/collections/_slug_/fields/index.mjs +40 -39
  304. package/dist/astro/routes/api/schema/collections/_slug_/fields/index.mjs.map +1 -1
  305. package/dist/astro/routes/api/schema/collections/_slug_/fields/reorder.mjs +40 -39
  306. package/dist/astro/routes/api/schema/collections/_slug_/fields/reorder.mjs.map +1 -1
  307. package/dist/astro/routes/api/schema/collections/_slug_/index.mjs +40 -39
  308. package/dist/astro/routes/api/schema/collections/_slug_/index.mjs.map +1 -1
  309. package/dist/astro/routes/api/schema/collections/index.mjs +40 -39
  310. package/dist/astro/routes/api/schema/collections/index.mjs.map +1 -1
  311. package/dist/astro/routes/api/schema/index.mjs +9 -9
  312. package/dist/astro/routes/api/schema/orphans/_slug_.mjs +40 -39
  313. package/dist/astro/routes/api/schema/orphans/_slug_.mjs.map +1 -1
  314. package/dist/astro/routes/api/schema/orphans/index.mjs +40 -39
  315. package/dist/astro/routes/api/schema/orphans/index.mjs.map +1 -1
  316. package/dist/astro/routes/api/search/enable.mjs +13 -12
  317. package/dist/astro/routes/api/search/enable.mjs.map +1 -1
  318. package/dist/astro/routes/api/search/index.mjs +12 -11
  319. package/dist/astro/routes/api/search/index.mjs.map +1 -1
  320. package/dist/astro/routes/api/search/rebuild.mjs +13 -12
  321. package/dist/astro/routes/api/search/rebuild.mjs.map +1 -1
  322. package/dist/astro/routes/api/search/stats.mjs +8 -8
  323. package/dist/astro/routes/api/search/suggest.mjs +12 -11
  324. package/dist/astro/routes/api/search/suggest.mjs.map +1 -1
  325. package/dist/astro/routes/api/sections/_slug_.mjs +12 -11
  326. package/dist/astro/routes/api/sections/_slug_.mjs.map +1 -1
  327. package/dist/astro/routes/api/sections/index.mjs +12 -11
  328. package/dist/astro/routes/api/sections/index.mjs.map +1 -1
  329. package/dist/astro/routes/api/settings/backups/archives/_name_.d.mts +9 -0
  330. package/dist/astro/routes/api/settings/backups/archives/_name_.d.mts.map +1 -0
  331. package/dist/astro/routes/api/settings/backups/archives/_name_.mjs +48 -0
  332. package/dist/astro/routes/api/settings/backups/archives/_name_.mjs.map +1 -0
  333. package/dist/astro/routes/api/settings/backups/archives/index.d.mts +8 -0
  334. package/dist/astro/routes/api/settings/backups/archives/index.d.mts.map +1 -0
  335. package/dist/astro/routes/api/settings/backups/archives/index.mjs +23 -0
  336. package/dist/astro/routes/api/settings/backups/archives/index.mjs.map +1 -0
  337. package/dist/astro/routes/api/settings/backups/export.d.mts +8 -0
  338. package/dist/astro/routes/api/settings/backups/export.d.mts.map +1 -0
  339. package/dist/astro/routes/api/settings/backups/export.mjs +35 -0
  340. package/dist/astro/routes/api/settings/backups/export.mjs.map +1 -0
  341. package/dist/astro/routes/api/settings/backups/index.d.mts +9 -0
  342. package/dist/astro/routes/api/settings/backups/index.d.mts.map +1 -0
  343. package/dist/astro/routes/api/settings/backups/index.mjs +52 -0
  344. package/dist/astro/routes/api/settings/backups/index.mjs.map +1 -0
  345. package/dist/astro/routes/api/settings/email.mjs +5 -5
  346. package/dist/astro/routes/api/settings.mjs +14 -13
  347. package/dist/astro/routes/api/settings.mjs.map +1 -1
  348. package/dist/astro/routes/api/setup/admin-verify.mjs +19 -15
  349. package/dist/astro/routes/api/setup/admin-verify.mjs.map +1 -1
  350. package/dist/astro/routes/api/setup/admin.mjs +18 -14
  351. package/dist/astro/routes/api/setup/admin.mjs.map +1 -1
  352. package/dist/astro/routes/api/setup/dev-bypass.mjs +26 -26
  353. package/dist/astro/routes/api/setup/dev-reset.mjs +3 -3
  354. package/dist/astro/routes/api/setup/index.mjs +28 -27
  355. package/dist/astro/routes/api/setup/index.mjs.map +1 -1
  356. package/dist/astro/routes/api/setup/status.mjs +5 -5
  357. package/dist/astro/routes/api/snapshot.mjs +8 -215
  358. package/dist/astro/routes/api/snapshot.mjs.map +1 -1
  359. package/dist/astro/routes/api/taxonomies/_name_/terms/_slug_/translations.mjs +15 -14
  360. package/dist/astro/routes/api/taxonomies/_name_/terms/_slug_/translations.mjs.map +1 -1
  361. package/dist/astro/routes/api/taxonomies/_name_/terms/_slug_.mjs +15 -14
  362. package/dist/astro/routes/api/taxonomies/_name_/terms/_slug_.mjs.map +1 -1
  363. package/dist/astro/routes/api/taxonomies/_name_/terms/index.mjs +15 -14
  364. package/dist/astro/routes/api/taxonomies/_name_/terms/index.mjs.map +1 -1
  365. package/dist/astro/routes/api/taxonomies/index.mjs +15 -14
  366. package/dist/astro/routes/api/taxonomies/index.mjs.map +1 -1
  367. package/dist/astro/routes/api/themes/preview.mjs +6 -6
  368. package/dist/astro/routes/api/typegen.mjs +6 -6
  369. package/dist/astro/routes/api/well-known/auth.mjs +1 -1
  370. package/dist/astro/routes/api/well-known/oauth-authorization-server.d.mts.map +1 -1
  371. package/dist/astro/routes/api/well-known/oauth-authorization-server.mjs +4 -3
  372. package/dist/astro/routes/api/well-known/oauth-authorization-server.mjs.map +1 -1
  373. package/dist/astro/routes/api/well-known/oauth-protected-resource.d.mts.map +1 -1
  374. package/dist/astro/routes/api/well-known/oauth-protected-resource.mjs +4 -3
  375. package/dist/astro/routes/api/well-known/oauth-protected-resource.mjs.map +1 -1
  376. package/dist/astro/routes/api/widget-areas/_name_/reorder.mjs +9 -8
  377. package/dist/astro/routes/api/widget-areas/_name_/reorder.mjs.map +1 -1
  378. package/dist/astro/routes/api/widget-areas/_name_/widgets/_id_.mjs +12 -11
  379. package/dist/astro/routes/api/widget-areas/_name_/widgets/_id_.mjs.map +1 -1
  380. package/dist/astro/routes/api/widget-areas/_name_/widgets.mjs +12 -11
  381. package/dist/astro/routes/api/widget-areas/_name_/widgets.mjs.map +1 -1
  382. package/dist/astro/routes/api/widget-areas/_name_.mjs +7 -7
  383. package/dist/astro/routes/api/widget-areas/index.mjs +12 -11
  384. package/dist/astro/routes/api/widget-areas/index.mjs.map +1 -1
  385. package/dist/astro/routes/api/widget-components.mjs +4 -4
  386. package/dist/astro/routes/robots.txt.mjs +7 -7
  387. package/dist/astro/routes/sitemap-_collection_.xml.mjs +11 -11
  388. package/dist/astro/routes/sitemap.xml.mjs +8 -8
  389. package/dist/astro/types.d.mts +38 -17
  390. package/dist/astro/types.d.mts.map +1 -1
  391. package/dist/auth/providers/github.d.mts +1 -1
  392. package/dist/auth/providers/google.d.mts +1 -1
  393. package/dist/{authorize-BmCwQCib.mjs → authorize-6WPZa1xZ.mjs} +7 -4
  394. package/dist/authorize-6WPZa1xZ.mjs.map +1 -0
  395. package/dist/backup-Qr9PaGUo.mjs +241 -0
  396. package/dist/backup-Qr9PaGUo.mjs.map +1 -0
  397. package/dist/{base64-C74Msx8h.mjs → base64-B-PsqheR.mjs} +8 -4
  398. package/dist/base64-B-PsqheR.mjs.map +1 -0
  399. package/dist/{byline-BWb5H-65.mjs → byline-BTOxUlFF.mjs} +6 -6
  400. package/dist/{byline-BWb5H-65.mjs.map → byline-BTOxUlFF.mjs.map} +1 -1
  401. package/dist/{byline-fields-DO6bAYK8.mjs → byline-fields-CdU_LTF1.mjs} +1 -1
  402. package/dist/{byline-fields-DO6bAYK8.mjs.map → byline-fields-CdU_LTF1.mjs.map} +1 -1
  403. package/dist/{bylines-CHojDMpj.mjs → bylines-FyZu6TbJ.mjs} +7 -7
  404. package/dist/{bylines-CHojDMpj.mjs.map → bylines-FyZu6TbJ.mjs.map} +1 -1
  405. package/dist/{bylines-BGuKFaBy.mjs → bylines-oVN0iPwX.mjs} +12 -8
  406. package/dist/bylines-oVN0iPwX.mjs.map +1 -0
  407. package/dist/{cache-BeR7RfN8.mjs → cache-DDwy3JDW.mjs} +2 -2
  408. package/dist/{cache-BeR7RfN8.mjs.map → cache-DDwy3JDW.mjs.map} +1 -1
  409. package/dist/{challenge-store-B426wQ6O.mjs → challenge-store-BFzgFRog.mjs} +1 -1
  410. package/dist/{challenge-store-B426wQ6O.mjs.map → challenge-store-BFzgFRog.mjs.map} +1 -1
  411. package/dist/{chunks-BU5_nrAC.mjs → chunks-Bq-5DPrD.mjs} +2 -2
  412. package/dist/{chunks-BU5_nrAC.mjs.map → chunks-Bq-5DPrD.mjs.map} +1 -1
  413. package/dist/cli/index.mjs +139 -32
  414. package/dist/cli/index.mjs.map +1 -1
  415. package/dist/client/cf-access.d.mts +1 -1
  416. package/dist/client/index.d.mts +54 -3
  417. package/dist/client/index.d.mts.map +1 -1
  418. package/dist/client/index.mjs +16 -4
  419. package/dist/client/index.mjs.map +1 -1
  420. package/dist/{comment-SWh31kS0.mjs → comment-B9cUud8H.mjs} +2 -2
  421. package/dist/{comment-SWh31kS0.mjs.map → comment-B9cUud8H.mjs.map} +1 -1
  422. package/dist/{comment-reaction-DgcpziXI.mjs → comment-reaction-VUXO981F.mjs} +2 -2
  423. package/dist/{comment-reaction-DgcpziXI.mjs.map → comment-reaction-VUXO981F.mjs.map} +1 -1
  424. package/dist/{comments-kZYGppMS.mjs → comments-PXj1E9Si.mjs} +3 -3
  425. package/dist/{comments-kZYGppMS.mjs.map → comments-PXj1E9Si.mjs.map} +1 -1
  426. package/dist/{components-CliOkZAs.mjs → components-DZkL4Fx0.mjs} +1 -1
  427. package/dist/{components-CliOkZAs.mjs.map → components-DZkL4Fx0.mjs.map} +1 -1
  428. package/dist/{config-CVssduLe.mjs → config-B6b_BobR.mjs} +6 -2
  429. package/dist/config-B6b_BobR.mjs.map +1 -0
  430. package/dist/{content-BO61Sx4j.mjs → content-BC43pICM.mjs} +53 -19
  431. package/dist/content-BC43pICM.mjs.map +1 -0
  432. package/dist/{content-refresh-BkkApzeS.mjs → content-refresh-CPMSauD3.mjs} +96 -4
  433. package/dist/content-refresh-CPMSauD3.mjs.map +1 -0
  434. package/dist/{context-DtSFYFuS.mjs → context-DOurRIrb.mjs} +97 -74
  435. package/dist/context-DOurRIrb.mjs.map +1 -0
  436. package/dist/{cron-YFJ7uNVA.mjs → cron-BlKIMD_e.mjs} +1 -1
  437. package/dist/{cron-YFJ7uNVA.mjs.map → cron-BlKIMD_e.mjs.map} +1 -1
  438. package/dist/{dashboard-xo_gPs_D.mjs → dashboard-CBm4zhc3.mjs} +4 -4
  439. package/dist/{dashboard-xo_gPs_D.mjs.map → dashboard-CBm4zhc3.mjs.map} +1 -1
  440. package/dist/database/pg-migration-lock.d.mts.map +1 -1
  441. package/dist/database/pg-migration-lock.mjs +1 -4
  442. package/dist/database/pg-migration-lock.mjs.map +1 -1
  443. package/dist/db/index.d.mts +3 -3
  444. package/dist/db/index.mjs +2 -2
  445. package/dist/db/index.mjs.map +1 -1
  446. package/dist/db/libsql.d.mts +1 -1
  447. package/dist/db/postgres.d.mts +1 -1
  448. package/dist/db/sqlite.d.mts +1 -1
  449. package/dist/{db-errors-BKuXh_fi.mjs → db-errors-CcWLaRiR.mjs} +4 -2
  450. package/dist/db-errors-CcWLaRiR.mjs.map +1 -0
  451. package/dist/{default-DY5ovGUG.mjs → default-C4v9KP56.mjs} +1 -1
  452. package/dist/{default-DY5ovGUG.mjs.map → default-C4v9KP56.mjs.map} +1 -1
  453. package/dist/{device-flow-CPXQ_QfW.mjs → device-flow-BeA6lUS1.mjs} +5 -6
  454. package/dist/device-flow-BeA6lUS1.mjs.map +1 -0
  455. package/dist/{dialect-helpers-Cue7QQOR.mjs → dialect-helpers-BtOwo2us.mjs} +60 -14
  456. package/dist/dialect-helpers-BtOwo2us.mjs.map +1 -0
  457. package/dist/{email-console-CjkQc7oY.mjs → email-console-C-9Ng8DM.mjs} +1 -1
  458. package/dist/{email-console-CjkQc7oY.mjs.map → email-console-C-9Ng8DM.mjs.map} +1 -1
  459. package/dist/error-DJ98TRbQ.mjs +90 -0
  460. package/dist/error-DJ98TRbQ.mjs.map +1 -0
  461. package/dist/{error-CfJMLSkd.mjs → errors-DtEXIQQV.mjs} +15 -84
  462. package/dist/errors-DtEXIQQV.mjs.map +1 -0
  463. package/dist/{escape-r8_GbEU2.mjs → escape-CFedIB1C.mjs} +1 -1
  464. package/dist/{escape-r8_GbEU2.mjs.map → escape-CFedIB1C.mjs.map} +1 -1
  465. package/dist/{field-defs-cache-BVrNCgSj.mjs → field-defs-cache-KfNJ_qLQ.mjs} +2 -2
  466. package/dist/{field-defs-cache-BVrNCgSj.mjs.map → field-defs-cache-KfNJ_qLQ.mjs.map} +1 -1
  467. package/dist/{fts-manager-BD9s77qh.mjs → fts-manager-hyCU9OOp.mjs} +3 -3
  468. package/dist/{fts-manager-BD9s77qh.mjs.map → fts-manager-hyCU9OOp.mjs.map} +1 -1
  469. package/dist/{hreflang-CgIxhH4k.d.mts → hreflang-CIxH_LKz.d.mts} +2 -2
  470. package/dist/{hreflang-CgIxhH4k.d.mts.map → hreflang-CIxH_LKz.d.mts.map} +1 -1
  471. package/dist/{hreflang-pAWUiPd_.mjs → hreflang-CbYeCzl9.mjs} +7 -7
  472. package/dist/{hreflang-pAWUiPd_.mjs.map → hreflang-CbYeCzl9.mjs.map} +1 -1
  473. package/dist/{import-2jHtLzsO.mjs → import-oDYCgNYQ.mjs} +4 -4
  474. package/dist/{import-2jHtLzsO.mjs.map → import-oDYCgNYQ.mjs.map} +1 -1
  475. package/dist/{index-DxjWLKGT.d.mts → index-BEui-cRd.d.mts} +3 -3
  476. package/dist/{index-DxjWLKGT.d.mts.map → index-BEui-cRd.d.mts.map} +1 -1
  477. package/dist/{index-BXOCyLj0.d.mts → index-BcEH_FfS.d.mts} +812 -16
  478. package/dist/index-BcEH_FfS.d.mts.map +1 -0
  479. package/dist/index.d.mts +18 -19
  480. package/dist/index.mjs +61 -60
  481. package/dist/{load-DgoWMdRX.mjs → load-Dg5gtWma.mjs} +2 -2
  482. package/dist/{load-DgoWMdRX.mjs.map → load-Dg5gtWma.mjs.map} +1 -1
  483. package/dist/{loader-Rb8QlGZp.mjs → loader-D4rigvjR.mjs} +170 -6
  484. package/dist/loader-D4rigvjR.mjs.map +1 -0
  485. package/dist/{manifest-schema-DeGNma2O.mjs → manifest-schema-bCq54i7F.mjs} +16 -2
  486. package/dist/manifest-schema-bCq54i7F.mjs.map +1 -0
  487. package/dist/media/image-endpoint.d.mts +30 -2
  488. package/dist/media/image-endpoint.d.mts.map +1 -1
  489. package/dist/media/image-endpoint.mjs +29 -3
  490. package/dist/media/image-endpoint.mjs.map +1 -1
  491. package/dist/media/index.d.mts +1 -1
  492. package/dist/media/local-runtime.d.mts +12 -13
  493. package/dist/media/local-runtime.d.mts.map +1 -1
  494. package/dist/media/local-runtime.mjs +6 -6
  495. package/dist/media-BJ6SRY3g.mjs +247 -0
  496. package/dist/media-BJ6SRY3g.mjs.map +1 -0
  497. package/dist/{media-allowlist-Dc05vKtt.mjs → media-allowlist-jUppPWFy.mjs} +1 -1
  498. package/dist/{media-allowlist-Dc05vKtt.mjs.map → media-allowlist-jUppPWFy.mjs.map} +1 -1
  499. package/dist/{media-D2ZFowpn.mjs → media-its1WLYv.mjs} +2 -2
  500. package/dist/{media-D2ZFowpn.mjs.map → media-its1WLYv.mjs.map} +1 -1
  501. package/dist/media-upload-DNu3QySc.mjs +145 -0
  502. package/dist/media-upload-DNu3QySc.mjs.map +1 -0
  503. package/dist/{media-url-DgIEYZr4.mjs → media-url-BCm5vBn6.mjs} +1 -1
  504. package/dist/{media-url-DgIEYZr4.mjs.map → media-url-BCm5vBn6.mjs.map} +1 -1
  505. package/dist/{media-usage-B__v9NMm.mjs → media-usage-DPQ3K4xB.mjs} +138 -5
  506. package/dist/{media-usage-B__v9NMm.mjs.map → media-usage-DPQ3K4xB.mjs.map} +1 -1
  507. package/dist/{menus-BpfevlJD.mjs → menus-BMGzWyWH.mjs} +15 -8
  508. package/dist/menus-BMGzWyWH.mjs.map +1 -0
  509. package/dist/{menus-BtvH7Z7t.mjs → menus-CPf_SW7u.mjs} +234 -13
  510. package/dist/menus-CPf_SW7u.mjs.map +1 -0
  511. package/dist/{mode-BVnhGZ2o.mjs → mode-fiXRMfeA.mjs} +1 -1
  512. package/dist/{mode-BVnhGZ2o.mjs.map → mode-fiXRMfeA.mjs.map} +1 -1
  513. package/dist/{oauth-authorization-BWqWTHBK.mjs → oauth-authorization-oqfbBuMH.mjs} +5 -6
  514. package/dist/oauth-authorization-oqfbBuMH.mjs.map +1 -0
  515. package/dist/{oauth-clients-43_XADoa.mjs → oauth-clients-BlrUHAsf.mjs} +1 -1
  516. package/dist/{oauth-clients-43_XADoa.mjs.map → oauth-clients-BlrUHAsf.mjs.map} +1 -1
  517. package/dist/{oauth-state-store-BRSUEkmx.mjs → oauth-state-store-DnvjRMy6.mjs} +2 -1
  518. package/dist/{oauth-state-store-BRSUEkmx.mjs.map → oauth-state-store-DnvjRMy6.mjs.map} +1 -1
  519. package/dist/{oauth-user-lookup-Ctgemb0k.mjs → oauth-user-lookup-oUllxvAv.mjs} +1 -1
  520. package/dist/{oauth-user-lookup-Ctgemb0k.mjs.map → oauth-user-lookup-oUllxvAv.mjs.map} +1 -1
  521. package/dist/object-cache/memory.d.mts +1 -1
  522. package/dist/{options-COXGTtqd.d.mts → options-BqMkWfYa.d.mts} +6 -6
  523. package/dist/{options-COXGTtqd.d.mts.map → options-BqMkWfYa.d.mts.map} +1 -1
  524. package/dist/page/index.d.mts +2 -2
  525. package/dist/page/index.d.mts.map +1 -1
  526. package/dist/page/index.mjs.map +1 -1
  527. package/dist/{parse-GLksnn-B.mjs → parse-53zyxlpv.mjs} +4 -12
  528. package/dist/{parse-GLksnn-B.mjs.map → parse-53zyxlpv.mjs.map} +1 -1
  529. package/dist/{passkey-config-CjA1UbDj.mjs → passkey-config-C-SKpc0-.mjs} +1 -1
  530. package/dist/{passkey-config-CjA1UbDj.mjs.map → passkey-config-C-SKpc0-.mjs.map} +1 -1
  531. package/dist/{placeholder-DR-eeZr-.d.mts → placeholder-Dop47JMM.d.mts} +1 -1
  532. package/dist/{placeholder-DR-eeZr-.d.mts.map → placeholder-Dop47JMM.d.mts.map} +1 -1
  533. package/dist/plugin-types.d.mts +21 -2
  534. package/dist/plugin-types.d.mts.map +1 -1
  535. package/dist/plugin-utils.d.mts +18 -17
  536. package/dist/plugin-utils.d.mts.map +1 -1
  537. package/dist/plugin-utils.mjs +8 -6
  538. package/dist/plugin-utils.mjs.map +1 -1
  539. package/dist/plugins/adapt-sandbox-entry.d.mts +10 -11
  540. package/dist/plugins/adapt-sandbox-entry.d.mts.map +1 -1
  541. package/dist/plugins/adapt-sandbox-entry.mjs +15 -3
  542. package/dist/plugins/adapt-sandbox-entry.mjs.map +1 -1
  543. package/dist/{portable-text-BAkgEKcv.mjs → portable-text-sDj92Kxv.mjs} +1 -1
  544. package/dist/{portable-text-BAkgEKcv.mjs.map → portable-text-sDj92Kxv.mjs.map} +1 -1
  545. package/dist/{preview-Rloa09Wp.mjs → preview-D4Jnbfx7.mjs} +2 -2
  546. package/dist/{preview-Rloa09Wp.mjs.map → preview-D4Jnbfx7.mjs.map} +1 -1
  547. package/dist/{public-url-C0cEvrRu.mjs → public-url-DSGTnJFw.mjs} +5 -3
  548. package/dist/public-url-DSGTnJFw.mjs.map +1 -0
  549. package/dist/{query-ZzvXyxWq.mjs → query-BbJQ-dGg.mjs} +15 -15
  550. package/dist/{query-ZzvXyxWq.mjs.map → query-BbJQ-dGg.mjs.map} +1 -1
  551. package/dist/{query-BxT95opY.mjs → query-DdFGHzQF.mjs} +3 -3
  552. package/dist/{query-BxT95opY.mjs.map → query-DdFGHzQF.mjs.map} +1 -1
  553. package/dist/{rate-limit-Cg4Rvc_-.mjs → rate-limit-D3IEiUi2.mjs} +2 -2
  554. package/dist/{rate-limit-Cg4Rvc_-.mjs.map → rate-limit-D3IEiUi2.mjs.map} +1 -1
  555. package/dist/{redirect-Ch3E98qZ.mjs → redirect-BoUac4NT.mjs} +10 -4
  556. package/dist/redirect-BoUac4NT.mjs.map +1 -0
  557. package/dist/{redirect-Ce_6Yb6z.mjs → redirect-Botom7X6.mjs} +1 -1
  558. package/dist/{redirect-Ce_6Yb6z.mjs.map → redirect-Botom7X6.mjs.map} +1 -1
  559. package/dist/{redirects-CXmVGRNZ.mjs → redirects-ChbpqKiS.mjs} +4 -4
  560. package/dist/{redirects-CXmVGRNZ.mjs.map → redirects-ChbpqKiS.mjs.map} +1 -1
  561. package/dist/{redirects-CeD7K7EX.mjs → redirects-D457qwt0.mjs} +10 -181
  562. package/dist/redirects-D457qwt0.mjs.map +1 -0
  563. package/dist/{registry-CyIXPi4E.mjs → registry-y21kjhfG.mjs} +97 -8
  564. package/dist/registry-y21kjhfG.mjs.map +1 -0
  565. package/dist/{relation-Ba68Tm4Z.mjs → relation-Du0r04E0.mjs} +3 -3
  566. package/dist/{relation-Ba68Tm4Z.mjs.map → relation-Du0r04E0.mjs.map} +1 -1
  567. package/dist/{relations-CbBpoOys.d.mts → relations-BKybBoOX.d.mts} +315 -9
  568. package/dist/relations-BKybBoOX.d.mts.map +1 -0
  569. package/dist/{relations-BmBmX4Eb.mjs → relations-CZMpBqEd.mjs} +3 -3
  570. package/dist/{relations-BmBmX4Eb.mjs.map → relations-CZMpBqEd.mjs.map} +1 -1
  571. package/dist/{relations-C8hVyEy0.mjs → relations-DtX1UMBH.mjs} +13 -7
  572. package/dist/relations-DtX1UMBH.mjs.map +1 -0
  573. package/dist/{request-meta-DCwktC5P.mjs → request-meta-DzXYYI-n.mjs} +2 -2
  574. package/dist/{request-meta-DCwktC5P.mjs.map → request-meta-DzXYYI-n.mjs.map} +1 -1
  575. package/dist/{resolve-Cd9dzclN.mjs → resolve-DFr4kq72.mjs} +2 -2
  576. package/dist/{resolve-Cd9dzclN.mjs.map → resolve-DFr4kq72.mjs.map} +1 -1
  577. package/dist/{runner-jt65bF7F.mjs → runner-BdeLEgad.mjs} +334 -200
  578. package/dist/runner-BdeLEgad.mjs.map +1 -0
  579. package/dist/{runner-CiNdIk3y.d.mts → runner-Dd8m8k9F.d.mts} +2 -2
  580. package/dist/{runner-CiNdIk3y.d.mts.map → runner-Dd8m8k9F.d.mts.map} +1 -1
  581. package/dist/runtime.d.mts +11 -12
  582. package/dist/runtime.d.mts.map +1 -1
  583. package/dist/runtime.mjs +4 -4
  584. package/dist/{schema-DwjufZ1S.mjs → schema-BH8P8vaC.mjs} +3 -3
  585. package/dist/{schema-DwjufZ1S.mjs.map → schema-BH8P8vaC.mjs.map} +1 -1
  586. package/dist/scopes-DTIkIaGA.mjs +27 -0
  587. package/dist/scopes-DTIkIaGA.mjs.map +1 -0
  588. package/dist/{search-Cl875CVE.mjs → search-D-Yhpmvs.mjs} +8 -7
  589. package/dist/search-D-Yhpmvs.mjs.map +1 -0
  590. package/dist/{secrets-CO_bEmII.mjs → secrets-CQ-69kF9.mjs} +25 -19
  591. package/dist/secrets-CQ-69kF9.mjs.map +1 -0
  592. package/dist/{sections-DTKzgoiS.mjs → sections-CzVBAKjw.mjs} +3 -3
  593. package/dist/{sections-DTKzgoiS.mjs.map → sections-CzVBAKjw.mjs.map} +1 -1
  594. package/dist/seed/index.d.mts +2 -2
  595. package/dist/seed/index.mjs +20 -20
  596. package/dist/seo/index.d.mts +14 -3
  597. package/dist/seo/index.d.mts.map +1 -1
  598. package/dist/seo/index.mjs +17 -17
  599. package/dist/seo/index.mjs.map +1 -1
  600. package/dist/{seo-BjrbXAd_.mjs → seo-C3GDfT0V.mjs} +1 -1
  601. package/dist/{seo-BjrbXAd_.mjs.map → seo-C3GDfT0V.mjs.map} +1 -1
  602. package/dist/{seo-BLm6SXzS.mjs → seo-kJzVAmmu.mjs} +2 -2
  603. package/dist/{seo-BLm6SXzS.mjs.map → seo-kJzVAmmu.mjs.map} +1 -1
  604. package/dist/{service-D6zDmKXy.mjs → service-CQnc276a.mjs} +3 -3
  605. package/dist/{service-D6zDmKXy.mjs.map → service-CQnc276a.mjs.map} +1 -1
  606. package/dist/{session-user-DoSs6YM8.mjs → session-user-DbHqKDKe.mjs} +1 -1
  607. package/dist/{session-user-DoSs6YM8.mjs.map → session-user-DbHqKDKe.mjs.map} +1 -1
  608. package/dist/{settings-BuQYvLfy.mjs → settings-C2PaBS49.mjs} +4 -4
  609. package/dist/{settings-BuQYvLfy.mjs.map → settings-C2PaBS49.mjs.map} +1 -1
  610. package/dist/{settings-CmS3TwXf.mjs → settings-Dtc0DU31.mjs} +3 -3
  611. package/dist/{settings-CmS3TwXf.mjs.map → settings-Dtc0DU31.mjs.map} +1 -1
  612. package/dist/{setup-complete-BPNgLHlU.mjs → setup-complete-CdIlqloh.mjs} +1 -1
  613. package/dist/{setup-complete-BPNgLHlU.mjs.map → setup-complete-CdIlqloh.mjs.map} +1 -1
  614. package/dist/{setup-nonce-DEPZX96T.mjs → setup-nonce-DqiIPr-J.mjs} +1 -1
  615. package/dist/{setup-nonce-DEPZX96T.mjs.map → setup-nonce-DqiIPr-J.mjs.map} +1 -1
  616. package/dist/{single-flight-cache-DEtW-OEG.mjs → single-flight-cache-C2exrGAi.mjs} +1 -1
  617. package/dist/{single-flight-cache-DEtW-OEG.mjs.map → single-flight-cache-C2exrGAi.mjs.map} +1 -1
  618. package/dist/{site-url-CcLy5D5s.mjs → site-url-NGJT6NTU.mjs} +1 -1
  619. package/dist/{site-url-CcLy5D5s.mjs.map → site-url-NGJT6NTU.mjs.map} +1 -1
  620. package/dist/snapshot-BdpUJKD-.mjs +216 -0
  621. package/dist/snapshot-BdpUJKD-.mjs.map +1 -0
  622. package/dist/{ssrf-TrKYJAy0.mjs → ssrf-CviKqWmq.mjs} +1 -1
  623. package/dist/{ssrf-TrKYJAy0.mjs.map → ssrf-CviKqWmq.mjs.map} +1 -1
  624. package/dist/state-xxv6ZTMv.mjs +128 -0
  625. package/dist/state-xxv6ZTMv.mjs.map +1 -0
  626. package/dist/{status-D3Gy1Zc6.mjs → status-COfycGIU.mjs} +1 -1
  627. package/dist/{status-D3Gy1Zc6.mjs.map → status-COfycGIU.mjs.map} +1 -1
  628. package/dist/storage/local.d.mts +1 -1
  629. package/dist/storage/local.mjs +1 -1
  630. package/dist/storage/s3.d.mts +1 -1
  631. package/dist/storage/s3.mjs +1 -1
  632. package/dist/{taxonomies-pUkuD6nj.mjs → taxonomies-HI9fnTdp.mjs} +8 -8
  633. package/dist/{taxonomies-pUkuD6nj.mjs.map → taxonomies-HI9fnTdp.mjs.map} +1 -1
  634. package/dist/{taxonomies-ClS4RKaZ.mjs → taxonomies-rMeBzOjX.mjs} +26 -17
  635. package/dist/taxonomies-rMeBzOjX.mjs.map +1 -0
  636. package/dist/{taxonomy-BkxbUMSw.mjs → taxonomy-0mCI25HN.mjs} +51 -13
  637. package/dist/taxonomy-0mCI25HN.mjs.map +1 -0
  638. package/dist/{tokens-BV6fgl5A.mjs → tokens-DVltpO2D.mjs} +2 -2
  639. package/dist/{tokens-BV6fgl5A.mjs.map → tokens-DVltpO2D.mjs.map} +1 -1
  640. package/dist/{transport-DTFhhPOg.mjs → transport-CKrlqSpD.mjs} +1 -1
  641. package/dist/{transport-DTFhhPOg.mjs.map → transport-CKrlqSpD.mjs.map} +1 -1
  642. package/dist/{transport-DmlmzD2U.d.mts → transport-Vd7VdqHv.d.mts} +1 -1
  643. package/dist/{transport-DmlmzD2U.d.mts.map → transport-Vd7VdqHv.d.mts.map} +1 -1
  644. package/dist/{trusted-proxy-CSgZVESw.mjs → trusted-proxy-CwjQj0YG.mjs} +1 -1
  645. package/dist/{trusted-proxy-CSgZVESw.mjs.map → trusted-proxy-CwjQj0YG.mjs.map} +1 -1
  646. package/dist/{types-B6-N9cBB.d.mts → types-B4vm81VH.d.mts} +1 -1
  647. package/dist/{types-B6-N9cBB.d.mts.map → types-B4vm81VH.d.mts.map} +1 -1
  648. package/dist/{types-Cm4Cz-8M.d.mts → types-B97jg3aW.d.mts} +6 -1
  649. package/dist/{types-Cm4Cz-8M.d.mts.map → types-B97jg3aW.d.mts.map} +1 -1
  650. package/dist/{types-BNZsPL9z.mjs → types-BD40g7zz.mjs} +1 -1
  651. package/dist/{types-BNZsPL9z.mjs.map → types-BD40g7zz.mjs.map} +1 -1
  652. package/dist/{types-QnlQIyPE.d.mts → types-BNfPHfay.d.mts} +1 -1
  653. package/dist/{types-QnlQIyPE.d.mts.map → types-BNfPHfay.d.mts.map} +1 -1
  654. package/dist/{types-DLIrNtv5.d.mts → types-BfYUPJdP.d.mts} +2 -2
  655. package/dist/{types-DLIrNtv5.d.mts.map → types-BfYUPJdP.d.mts.map} +1 -1
  656. package/dist/{types-CtDVagM4.d.mts → types-BvB7gDOD.d.mts} +38 -4
  657. package/dist/types-BvB7gDOD.d.mts.map +1 -0
  658. package/dist/{types-B_pmP7Yq.d.mts → types-C7U0HlEr.d.mts} +1 -1
  659. package/dist/{types-B_pmP7Yq.d.mts.map → types-C7U0HlEr.d.mts.map} +1 -1
  660. package/dist/{types-Ch8pFMEm.mjs → types-CrRUFdej.mjs} +3 -3
  661. package/dist/{types-Ch8pFMEm.mjs.map → types-CrRUFdej.mjs.map} +1 -1
  662. package/dist/{types-momGysZk.d.mts → types-DPKhI5ib.d.mts} +9 -1
  663. package/dist/types-DPKhI5ib.d.mts.map +1 -0
  664. package/dist/{types-BCVuUPrL.d.mts → types-Kmaxdarz.d.mts} +1 -1
  665. package/dist/{types-BCVuUPrL.d.mts.map → types-Kmaxdarz.d.mts.map} +1 -1
  666. package/dist/{types-qljd1hsL.d.mts → types-iVeZ5g6N.d.mts} +1 -1
  667. package/dist/{types-qljd1hsL.d.mts.map → types-iVeZ5g6N.d.mts.map} +1 -1
  668. package/dist/{user-DTxX_Fha.mjs → user-aTXqmXBz.mjs} +3 -3
  669. package/dist/{user-DTxX_Fha.mjs.map → user-aTXqmXBz.mjs.map} +1 -1
  670. package/dist/{utils-Cz8PVrl4.mjs → utils-BbUgmeZG.mjs} +1 -1
  671. package/dist/{utils-Cz8PVrl4.mjs.map → utils-BbUgmeZG.mjs.map} +1 -1
  672. package/dist/{validate-C3CpWlNt.mjs → validate-CDT1jl6_.mjs} +11 -6
  673. package/dist/validate-CDT1jl6_.mjs.map +1 -0
  674. package/dist/{validate-9jLuE301.d.mts → validate-DULfgpJP.d.mts} +5 -5
  675. package/dist/{validate-9jLuE301.d.mts.map → validate-DULfgpJP.d.mts.map} +1 -1
  676. package/dist/{validation-DM2K_NJC.mjs → validation-DlD0E35W.mjs} +10 -10
  677. package/dist/{validation-DM2K_NJC.mjs.map → validation-DlD0E35W.mjs.map} +1 -1
  678. package/dist/version-Ci6bw6YK.mjs +7 -0
  679. package/dist/{version-BlIJvNAZ.mjs.map → version-Ci6bw6YK.mjs.map} +1 -1
  680. package/dist/{widgets-B_X6_UXJ.mjs → widgets-5fipNkMT.mjs} +3 -3
  681. package/dist/{widgets-B_X6_UXJ.mjs.map → widgets-5fipNkMT.mjs.map} +1 -1
  682. package/dist/{wxr-taxonomies-tADW4KTa.d.mts → wxr-taxonomies-B4tMuN5T.d.mts} +1 -1
  683. package/dist/{wxr-taxonomies-tADW4KTa.d.mts.map → wxr-taxonomies-B4tMuN5T.d.mts.map} +1 -1
  684. package/dist/{wxr-taxonomies-oNJB2S81.mjs → wxr-taxonomies-BmUnBNgz.mjs} +4 -4
  685. package/dist/{wxr-taxonomies-oNJB2S81.mjs.map → wxr-taxonomies-BmUnBNgz.mjs.map} +1 -1
  686. package/dist/{zod-generator-CrfV79De.mjs → zod-generator-CwkHWz4f.mjs} +2 -2
  687. package/dist/{zod-generator-CrfV79De.mjs.map → zod-generator-CwkHWz4f.mjs.map} +1 -1
  688. package/package.json +8 -8
  689. package/src/api/authorize.ts +10 -1
  690. package/src/api/error.ts +5 -5
  691. package/src/api/errors.ts +14 -0
  692. package/src/api/handlers/backup.ts +312 -0
  693. package/src/api/handlers/bylines.ts +5 -4
  694. package/src/api/handlers/content.ts +61 -9
  695. package/src/api/handlers/device-flow.ts +2 -3
  696. package/src/api/handlers/index.ts +16 -0
  697. package/src/api/handlers/marketplace.ts +38 -0
  698. package/src/api/handlers/media-upload.ts +210 -0
  699. package/src/api/handlers/media-usage.ts +211 -2
  700. package/src/api/handlers/menus.ts +11 -6
  701. package/src/api/handlers/oauth-authorization.ts +2 -6
  702. package/src/api/handlers/plugin-settings.ts +218 -0
  703. package/src/api/handlers/plugins.ts +41 -0
  704. package/src/api/handlers/registry.ts +39 -0
  705. package/src/api/handlers/relations.ts +7 -2
  706. package/src/api/handlers/snapshot.ts +21 -3
  707. package/src/api/handlers/taxonomies.ts +22 -14
  708. package/src/api/openapi/document.ts +48 -6
  709. package/src/api/parse.ts +1 -15
  710. package/src/api/public-url.ts +4 -2
  711. package/src/api/schemas/bylines.ts +4 -4
  712. package/src/api/schemas/common.ts +13 -8
  713. package/src/api/schemas/media-usage.ts +72 -0
  714. package/src/api/schemas/media.ts +32 -1
  715. package/src/api/schemas/menus.ts +2 -1
  716. package/src/api/schemas/relations.ts +3 -1
  717. package/src/api/schemas/taxonomies.ts +4 -2
  718. package/src/astro/integration/index.ts +38 -0
  719. package/src/astro/integration/routes.ts +35 -0
  720. package/src/astro/integration/runtime.ts +6 -0
  721. package/src/astro/integration/virtual-modules.ts +41 -7
  722. package/src/astro/integration/vite-config.ts +17 -1
  723. package/src/astro/middleware/auth.ts +70 -78
  724. package/src/astro/middleware/csp.ts +5 -2
  725. package/src/astro/middleware.ts +86 -31
  726. package/src/astro/public-plugin-api-routes.ts +2 -1
  727. package/src/astro/routes/PluginRegistry.tsx +5 -2
  728. package/src/astro/routes/admin.astro +56 -16
  729. package/src/astro/routes/api/admin/api-tokens/index.ts +2 -2
  730. package/src/astro/routes/api/admin/bylines/[id]/translations.ts +2 -5
  731. package/src/astro/routes/api/admin/bylines/index.ts +5 -8
  732. package/src/astro/routes/api/admin/plugins/[id]/index.ts +6 -0
  733. package/src/astro/routes/api/admin/plugins/[id]/mcp.ts +42 -0
  734. package/src/astro/routes/api/admin/plugins/[id]/settings.ts +80 -0
  735. package/src/astro/routes/api/admin/plugins/[id]/update.ts +2 -0
  736. package/src/astro/routes/api/admin/plugins/index.ts +9 -0
  737. package/src/astro/routes/api/admin/plugins/marketplace/[id]/install.ts +2 -0
  738. package/src/astro/routes/api/admin/plugins/registry/[id]/update.ts +2 -0
  739. package/src/astro/routes/api/admin/plugins/registry/install.ts +2 -0
  740. package/src/astro/routes/api/admin/plugins/updates.ts +2 -4
  741. package/src/astro/routes/api/auth/mode.ts +6 -14
  742. package/src/astro/routes/api/auth/oauth/[provider]/callback.ts +21 -4
  743. package/src/astro/routes/api/auth/oauth/[provider].ts +24 -6
  744. package/src/astro/routes/api/content/[collection]/[id]/compare.ts +3 -4
  745. package/src/astro/routes/api/content/[collection]/[id]/duplicate.ts +2 -3
  746. package/src/astro/routes/api/content/[collection]/[id]/permanent.ts +2 -3
  747. package/src/astro/routes/api/content/[collection]/[id]/preview-url.ts +3 -4
  748. package/src/astro/routes/api/content/[collection]/[id]/references/[relation]/children.ts +4 -6
  749. package/src/astro/routes/api/content/[collection]/[id]/references/[relation]/parents.ts +2 -3
  750. package/src/astro/routes/api/content/[collection]/[id]/revisions.ts +3 -4
  751. package/src/astro/routes/api/content/[collection]/[id]/terms/[taxonomy].ts +4 -6
  752. package/src/astro/routes/api/content/[collection]/[id]/translations.ts +3 -4
  753. package/src/astro/routes/api/content/[collection]/[id].ts +3 -4
  754. package/src/astro/routes/api/content/[collection]/authors.ts +2 -3
  755. package/src/astro/routes/api/content/[collection]/index.ts +6 -8
  756. package/src/astro/routes/api/content/[collection]/trash.ts +2 -3
  757. package/src/astro/routes/api/manifest.ts +2 -9
  758. package/src/astro/routes/api/mcp.ts +2 -1
  759. package/src/astro/routes/api/media/[id]/usage.ts +30 -0
  760. package/src/astro/routes/api/media/[id].ts +17 -6
  761. package/src/astro/routes/api/media/file/[...key].ts +8 -0
  762. package/src/astro/routes/api/media.ts +21 -2
  763. package/src/astro/routes/api/oauth/authorize.ts +43 -15
  764. package/src/astro/routes/api/plugins/[pluginId]/[...path].ts +17 -3
  765. package/src/astro/routes/api/settings/backups/archives/[name].ts +78 -0
  766. package/src/astro/routes/api/settings/backups/archives/index.ts +33 -0
  767. package/src/astro/routes/api/settings/backups/export.ts +43 -0
  768. package/src/astro/routes/api/settings/backups/index.ts +76 -0
  769. package/src/astro/routes/api/setup/admin-verify.ts +8 -4
  770. package/src/astro/routes/api/setup/admin.ts +11 -4
  771. package/src/astro/routes/api/well-known/oauth-authorization-server.ts +4 -1
  772. package/src/astro/routes/api/well-known/oauth-protected-resource.ts +5 -1
  773. package/src/astro/types.ts +48 -2
  774. package/src/auth/api-tokens.ts +1 -0
  775. package/src/auth/oauth-state-store.ts +3 -0
  776. package/src/auth/providers/github-admin.tsx +5 -6
  777. package/src/auth/providers/google-admin.tsx +5 -6
  778. package/src/auth/scopes.ts +3 -9
  779. package/src/cli/client-factory.ts +0 -1
  780. package/src/cli/commands/bundle-utils.ts +50 -1
  781. package/src/cli/commands/bundle.ts +9 -2
  782. package/src/cli/commands/media.ts +127 -0
  783. package/src/client/index.ts +84 -2
  784. package/src/client/transport.ts +1 -1
  785. package/src/components/EmDashHead.astro +4 -8
  786. package/src/components/Gallery.astro +141 -26
  787. package/src/components/InlinePortableTextEditor.tsx +56 -35
  788. package/src/components/marks/Link.astro +5 -1
  789. package/src/config/secrets.ts +25 -19
  790. package/src/content/converters/gallery.ts +61 -0
  791. package/src/content/converters/portable-text-to-prosemirror.ts +19 -0
  792. package/src/content/converters/prosemirror-to-portable-text.ts +18 -0
  793. package/src/content/converters/types.ts +36 -0
  794. package/src/database/dialect-helpers.ts +80 -7
  795. package/src/database/migrations/051_content_taxonomies_denorm.ts +120 -0
  796. package/src/database/migrations/052_media_usage_read_index.ts +26 -0
  797. package/src/database/migrations/053_plugin_mcp_tools.ts +21 -0
  798. package/src/database/migrations/runner.ts +6 -0
  799. package/src/database/pg-migration-lock.ts +1 -4
  800. package/src/database/repositories/audit.ts +2 -1
  801. package/src/database/repositories/content.ts +98 -16
  802. package/src/database/repositories/media-usage.ts +250 -1
  803. package/src/database/repositories/plugin-storage.ts +29 -32
  804. package/src/database/repositories/redirect.ts +14 -2
  805. package/src/database/repositories/taxonomy.ts +57 -8
  806. package/src/database/types.ts +23 -0
  807. package/src/db/adapters.ts +9 -0
  808. package/src/emdash-runtime.ts +365 -83
  809. package/src/i18n/config.ts +8 -0
  810. package/src/i18n/repair-locale-casing.ts +51 -0
  811. package/src/loader.ts +292 -1
  812. package/src/mcp/server.ts +222 -5
  813. package/src/media/image-endpoint.ts +38 -2
  814. package/src/page/metadata.ts +27 -0
  815. package/src/plugin-types.ts +19 -0
  816. package/src/plugin-utils.ts +8 -6
  817. package/src/plugins/adapt-sandbox-entry.ts +30 -1
  818. package/src/plugins/context.ts +7 -0
  819. package/src/plugins/define-plugin.ts +16 -0
  820. package/src/plugins/manifest-schema.ts +28 -1
  821. package/src/plugins/routes.ts +27 -1
  822. package/src/plugins/sandbox/runner-options.ts +16 -0
  823. package/src/plugins/sandbox/types.ts +6 -1
  824. package/src/plugins/state.ts +17 -1
  825. package/src/plugins/storage-query.ts +67 -33
  826. package/src/plugins/types.ts +41 -0
  827. package/src/schema/registry.ts +141 -5
  828. package/src/search/query.ts +3 -2
  829. package/src/seed/apply.ts +37 -36
  830. package/src/seed/validate.ts +15 -4
  831. package/src/seo/index.ts +19 -4
  832. package/src/storage/types.ts +6 -0
  833. package/src/utils/base64.ts +7 -2
  834. package/src/utils/db-errors.ts +3 -1
  835. package/src/virtual-modules.d.ts +13 -0
  836. package/src/visual-editing/toolbar.ts +1 -1
  837. package/dist/adapters-DPAkL6QF.d.mts.map +0 -1
  838. package/dist/api-DVbHNApo.mjs.map +0 -1
  839. package/dist/api-tokens-Dk2GrJMY.mjs +0 -3
  840. package/dist/apply-D23iUV4q.mjs.map +0 -1
  841. package/dist/authorize-BmCwQCib.mjs.map +0 -1
  842. package/dist/base64-C74Msx8h.mjs.map +0 -1
  843. package/dist/bylines-BGuKFaBy.mjs.map +0 -1
  844. package/dist/config-CVssduLe.mjs.map +0 -1
  845. package/dist/content-BO61Sx4j.mjs.map +0 -1
  846. package/dist/content-refresh-BkkApzeS.mjs.map +0 -1
  847. package/dist/context-DtSFYFuS.mjs.map +0 -1
  848. package/dist/db-errors-BKuXh_fi.mjs.map +0 -1
  849. package/dist/device-flow-CPXQ_QfW.mjs.map +0 -1
  850. package/dist/dialect-helpers-Cue7QQOR.mjs.map +0 -1
  851. package/dist/error-CfJMLSkd.mjs.map +0 -1
  852. package/dist/index-BXOCyLj0.d.mts.map +0 -1
  853. package/dist/loader-Rb8QlGZp.mjs.map +0 -1
  854. package/dist/manifest-schema-DeGNma2O.mjs.map +0 -1
  855. package/dist/menus-BpfevlJD.mjs.map +0 -1
  856. package/dist/menus-BtvH7Z7t.mjs.map +0 -1
  857. package/dist/oauth-authorization-BWqWTHBK.mjs.map +0 -1
  858. package/dist/public-url-C0cEvrRu.mjs.map +0 -1
  859. package/dist/redirect-Ch3E98qZ.mjs.map +0 -1
  860. package/dist/redirects-CeD7K7EX.mjs.map +0 -1
  861. package/dist/registry-CyIXPi4E.mjs.map +0 -1
  862. package/dist/relations-C8hVyEy0.mjs.map +0 -1
  863. package/dist/relations-CbBpoOys.d.mts.map +0 -1
  864. package/dist/runner-jt65bF7F.mjs.map +0 -1
  865. package/dist/scheduled-publish-DlJHGcuL.d.mts +0 -11
  866. package/dist/scheduled-publish-DlJHGcuL.d.mts.map +0 -1
  867. package/dist/search-Cl875CVE.mjs.map +0 -1
  868. package/dist/secrets-CO_bEmII.mjs.map +0 -1
  869. package/dist/taxonomies-ClS4RKaZ.mjs.map +0 -1
  870. package/dist/taxonomy-BkxbUMSw.mjs.map +0 -1
  871. package/dist/types-CtDVagM4.d.mts.map +0 -1
  872. package/dist/types-momGysZk.d.mts.map +0 -1
  873. package/dist/validate-C3CpWlNt.mjs.map +0 -1
  874. package/dist/version-BlIJvNAZ.mjs +0 -7
  875. /package/dist/{ssrf-B5DOv5E5.mjs → ssrf-BB__xfNM.mjs} +0 -0
  876. /package/dist/{types-DeCZBZxn.mjs → types-CK0LxPUQ.mjs} +0 -0
@@ -7,9 +7,11 @@
7
7
  * Created once per worker lifetime, cached and reused across requests.
8
8
  */
9
9
 
10
+ import { Permissions } from "@emdash-cms/auth";
10
11
  import type { Element } from "@emdash-cms/blocks";
11
12
  import { Kysely, sql, type Dialect } from "kysely";
12
13
  import virtualConfig from "virtual:emdash/config";
14
+ import { z } from "zod";
13
15
 
14
16
  import { validateRev } from "./api/rev.js";
15
17
  import type {
@@ -27,12 +29,15 @@ import {
27
29
  MIGRATION_RACE_WAIT_MS,
28
30
  runMigrations,
29
31
  } from "./database/migrations/runner.js";
32
+ import { AuditRepository } from "./database/repositories/audit.js";
30
33
  import { RevisionRepository } from "./database/repositories/revision.js";
31
34
  import type {
32
35
  ContentItem as ContentItemInternal,
33
36
  ContentDateField,
34
37
  } from "./database/repositories/types.js";
35
38
  import { validateIdentifier } from "./database/validate.js";
39
+ import { getI18nConfig } from "./i18n/config.js";
40
+ import { repairLocaleCasing } from "./i18n/repair-locale-casing.js";
36
41
  import { normalizeMediaValue } from "./media/normalize.js";
37
42
  import type { MediaProvider, MediaProviderCapabilities } from "./media/types.js";
38
43
  import {
@@ -41,18 +46,25 @@ import {
41
46
  markContentMediaUsageCollectionStale,
42
47
  refreshContentMediaUsageAfterWrite,
43
48
  } from "./media/usage/content-refresh.js";
44
- import type { SandboxedPluginInstance, SandboxRunner } from "./plugins/sandbox/types.js";
49
+ import { createSandboxRunnerOptions } from "./plugins/sandbox/runner-options.js";
50
+ import type {
51
+ SandboxedPluginInstance,
52
+ SandboxRunner,
53
+ SandboxRunnerFactory,
54
+ } from "./plugins/sandbox/types.js";
45
55
  import type {
46
56
  ResolvedPlugin,
47
57
  MediaItem,
48
58
  PluginManifest,
49
59
  PluginCapability,
50
60
  PluginStorageConfig,
61
+ PluginMcpManifestConfig,
51
62
  PublicPageContext,
52
63
  PageMetadataContribution,
53
64
  PageFragmentContribution,
54
65
  PortableTextBlockConfig,
55
66
  FieldWidgetConfig,
67
+ SettingField,
56
68
  } from "./plugins/types.js";
57
69
  import type { FieldType } from "./schema/types.js";
58
70
  import { hashString } from "./utils/hash.js";
@@ -61,6 +73,12 @@ import { createSingleFlightCache, singleFlightCached } from "./utils/single-flig
61
73
  import { COMMIT, VERSION } from "./version.js";
62
74
 
63
75
  const LEADING_SLASH_PATTERN = /^\//;
76
+ const LOCALE_CASING_REPAIR_OPTION = "emdash:repair_locale_casing";
77
+
78
+ function getLocaleCasingRepairVersion(locales: readonly string[]): string | null {
79
+ if (locales.length === 0) return null;
80
+ return `1:${locales.toSorted().join(",")}`;
81
+ }
64
82
 
65
83
  /**
66
84
  * Parse a JSON column expected to contain an array of strings.
@@ -121,6 +139,7 @@ function isValidMetadataContribution(c: unknown): c is PageMetadataContribution
121
139
  }
122
140
 
123
141
  import { after } from "./after.js";
142
+ import { maybeRunScheduledBackup } from "./api/handlers/backup.js";
124
143
  import { loadBundleFromR2 } from "./api/handlers/marketplace.js";
125
144
  import { runSystemCleanup } from "./cleanup.js";
126
145
  import {
@@ -174,7 +193,7 @@ import {
174
193
  } from "./plugins/hooks.js";
175
194
  import { normalizeManifestRoute } from "./plugins/manifest-schema.js";
176
195
  import { extractRequestMeta, sanitizeHeadersForSandbox } from "./plugins/request-meta.js";
177
- import { PluginRouteRegistry, type RouteMeta } from "./plugins/routes.js";
196
+ import { buildRouteMeta, PluginRouteRegistry, type RouteMeta } from "./plugins/routes.js";
178
197
  import type { CronScheduler } from "./plugins/scheduler/types.js";
179
198
  import { PluginStateRepository } from "./plugins/state.js";
180
199
  import { normalizeRegistryConfig } from "./registry/config.js";
@@ -220,10 +239,14 @@ export interface SandboxedPluginEntry {
220
239
  allowedHosts: string[];
221
240
  /** Declared storage collections */
222
241
  storage: PluginStorageConfig;
242
+ /** Serialized MCP declarations emitted at plugin build time. */
243
+ mcp?: PluginMcpManifestConfig;
223
244
  /** Admin pages */
224
245
  adminPages?: Array<{ path: string; label?: string; icon?: string }>;
225
246
  /** Dashboard widgets */
226
247
  adminWidgets?: Array<{ id: string; title?: string; size?: string }>;
248
+ /** Settings schema for the auto-generated admin settings form */
249
+ settingsSchema?: Record<string, SettingField>;
227
250
  /** Portable Text block types contributed to the editor (declarative Block Kit) */
228
251
  portableTextBlocks?: PortableTextBlockConfig[];
229
252
  /** Field widget types contributed for schema-field editing UIs */
@@ -309,16 +332,8 @@ export interface RuntimeDependencies {
309
332
  /** Media provider entries from virtual module */
310
333
  mediaProviderEntries?: MediaProviderEntry[];
311
334
  sandboxedPluginEntries: SandboxedPluginEntry[];
312
- /** Factory function matching SandboxRunnerFactory signature */
313
- createSandboxRunner:
314
- | ((opts: {
315
- db: Kysely<Database>;
316
- mediaStorage?: {
317
- upload(options: { key: string; body: Uint8Array; contentType: string }): Promise<unknown>;
318
- delete(key: string): Promise<unknown>;
319
- };
320
- }) => SandboxRunner)
321
- | null;
335
+ /** Factory function supplied by the active platform adapter. */
336
+ createSandboxRunner: SandboxRunnerFactory | null;
322
337
  }
323
338
 
324
339
  /**
@@ -354,7 +369,12 @@ export interface EmDashRuntimeParts {
354
369
  db: Kysely<Database>;
355
370
  getDb?: () => Kysely<Database>;
356
371
  storage?: Storage;
357
- siteInfo?: { siteName?: string; siteUrl?: string; locale?: string };
372
+ siteInfo?: {
373
+ siteName?: string;
374
+ siteUrl?: string;
375
+ locale?: string;
376
+ trailingSlash?: "always" | "never" | "ignore";
377
+ };
358
378
  };
359
379
  runtimeDeps: RuntimeDependencies;
360
380
  pipelineRef: { current: HookPipeline };
@@ -469,7 +489,9 @@ const marketplaceManifestCache = new Map<
469
489
  admin?: {
470
490
  pages?: PluginAdminPage[];
471
491
  widgets?: PluginDashboardWidget[];
492
+ settingsSchema?: Record<string, SettingField>;
472
493
  };
494
+ mcp?: PluginMcpManifestConfig;
473
495
  }
474
496
  >();
475
497
  /** Route metadata for sandboxed plugins: pluginId -> routeName -> RouteMeta */
@@ -536,7 +558,12 @@ export class EmDashRuntime {
536
558
  db: Kysely<Database>;
537
559
  getDb?: () => Kysely<Database>;
538
560
  storage?: Storage;
539
- siteInfo?: { siteName?: string; siteUrl?: string; locale?: string };
561
+ siteInfo?: {
562
+ siteName?: string;
563
+ siteUrl?: string;
564
+ locale?: string;
565
+ trailingSlash?: "always" | "never" | "ignore";
566
+ };
540
567
  };
541
568
  /** Dependencies needed for exclusive hook resolution */
542
569
  private runtimeDeps: RuntimeDependencies;
@@ -656,6 +683,9 @@ export class EmDashRuntime {
656
683
  console.error("[cleanup] System cleanup failed:", error);
657
684
  }
658
685
 
686
+ // Never throws; no-op unless scheduled backups are enabled and due.
687
+ await maybeRunScheduledBackup(this.db, this.storage ?? undefined);
688
+
659
689
  return { published };
660
690
  }
661
691
 
@@ -714,12 +744,11 @@ export class EmDashRuntime {
714
744
  // pipelineFactoryOptions), so the merge only adds emailPipeline.
715
745
  newPipeline.setContextFactory({ emailPipeline: this.email });
716
746
  }
717
- if (this.cronScheduler) {
718
- const scheduler = this.cronScheduler;
719
- newPipeline.setContextFactory({
720
- cronReschedule: () => scheduler.reschedule(),
721
- });
722
- }
747
+ newPipeline.setContextFactory({
748
+ // Plugin schedules remain database-backed when no in-process scheduler
749
+ // exists; an external trigger is responsible for invoking due tasks.
750
+ cronReschedule: () => this.cronScheduler?.reschedule(),
751
+ });
723
752
 
724
753
  // Update the email pipeline to use the new hook pipeline
725
754
  if (this.email) {
@@ -866,6 +895,7 @@ export class EmDashRuntime {
866
895
  id: bundle.manifest.id,
867
896
  version: bundle.manifest.version,
868
897
  admin: bundle.manifest.admin,
898
+ mcp: bundle.manifest.mcp,
869
899
  });
870
900
 
871
901
  // Cache route metadata from manifest for auth decisions
@@ -873,7 +903,7 @@ export class EmDashRuntime {
873
903
  const routeMetaMap = new Map<string, RouteMeta>();
874
904
  for (const entry of bundle.manifest.routes) {
875
905
  const normalized = normalizeManifestRoute(entry);
876
- routeMetaMap.set(normalized.name, { public: normalized.public === true });
906
+ routeMetaMap.set(normalized.name, buildRouteMeta(normalized));
877
907
  }
878
908
  sandboxedRouteMetaCache.set(pluginId, routeMetaMap);
879
909
  } else {
@@ -980,12 +1010,13 @@ export class EmDashRuntime {
980
1010
  id: bundle.manifest.id,
981
1011
  version: bundle.manifest.version,
982
1012
  admin: bundle.manifest.admin,
1013
+ mcp: bundle.manifest.mcp,
983
1014
  });
984
1015
  if (bundle.manifest.routes.length > 0) {
985
1016
  const routeMetaMap = new Map<string, RouteMeta>();
986
1017
  for (const entry of bundle.manifest.routes) {
987
1018
  const normalized = normalizeManifestRoute(entry);
988
- routeMetaMap.set(normalized.name, { public: normalized.public === true });
1019
+ routeMetaMap.set(normalized.name, buildRouteMeta(normalized));
989
1020
  }
990
1021
  sandboxedRouteMetaCache.set(pluginId, routeMetaMap);
991
1022
  } else {
@@ -1029,6 +1060,7 @@ export class EmDashRuntime {
1029
1060
  size:
1030
1061
  w.size === "full" || w.size === "half" || w.size === "third" ? w.size : undefined,
1031
1062
  })),
1063
+ settingsSchema: bundle.manifest.admin?.settingsSchema,
1032
1064
  });
1033
1065
  newPlugins.push(adapted);
1034
1066
  this.allPipelinePlugins.push(adapted);
@@ -1106,7 +1138,18 @@ export class EmDashRuntime {
1106
1138
  const storage = EmDashRuntime.getStorage(deps);
1107
1139
 
1108
1140
  let pluginStates: Map<string, string> = new Map();
1109
- let siteInfo: { siteName?: string; siteUrl?: string; locale?: string } | undefined;
1141
+ const configuredLocales: string[] =
1142
+ virtualConfig?.i18n?.locales ?? getI18nConfig()?.locales ?? [];
1143
+ const localeCasingRepairVersion = getLocaleCasingRepairVersion(configuredLocales);
1144
+ let storedLocaleCasingRepairVersion: string | undefined;
1145
+ let siteInfo:
1146
+ | {
1147
+ siteName?: string;
1148
+ siteUrl?: string;
1149
+ locale?: string;
1150
+ trailingSlash?: "always" | "never" | "ignore";
1151
+ }
1152
+ | undefined;
1110
1153
  // "Already set up" by default so a read failure (e.g. tables absent on a
1111
1154
  // pre-migration db) skips seeding rather than seeding a half-built db.
1112
1155
  let seedGate = { collectionCount: 1, setupDone: true };
@@ -1144,11 +1187,17 @@ export class EmDashRuntime {
1144
1187
  "emdash:site_title",
1145
1188
  "emdash:site_url",
1146
1189
  "emdash:locale",
1190
+ LOCALE_CASING_REPAIR_OPTION,
1147
1191
  ]);
1192
+ storedLocaleCasingRepairVersion = siteOpts.get(LOCALE_CASING_REPAIR_OPTION);
1148
1193
  return {
1149
1194
  siteName: siteOpts.get("emdash:site_title") ?? undefined,
1150
1195
  siteUrl: siteOpts.get("emdash:site_url") ?? undefined,
1151
1196
  locale: siteOpts.get("emdash:locale") ?? undefined,
1197
+ // trailingSlash is a build-time Astro routing decision, not a
1198
+ // user-editable setting, so it comes from the Astro config
1199
+ // (virtual:emdash/config), not the options table.
1200
+ trailingSlash: virtualConfig?.trailingSlash,
1152
1201
  };
1153
1202
  };
1154
1203
 
@@ -1206,6 +1255,20 @@ export class EmDashRuntime {
1206
1255
 
1207
1256
  await Promise.all(coldStartReads);
1208
1257
 
1258
+ if (
1259
+ localeCasingRepairVersion &&
1260
+ (configuredLocales.some(
1261
+ (locale) => locale.includes("-") || locale !== locale.toLowerCase(),
1262
+ ) ||
1263
+ storedLocaleCasingRepairVersion !== undefined) &&
1264
+ storedLocaleCasingRepairVersion !== localeCasingRepairVersion
1265
+ ) {
1266
+ await phase("rt.locale", "Repair locale casing", async () => {
1267
+ await repairLocaleCasing(db, configuredLocales);
1268
+ await new OptionsRepository(db).set(LOCALE_CASING_REPAIR_OPTION, localeCasingRepairVersion);
1269
+ });
1270
+ }
1271
+
1209
1272
  // Auto-seed the default schema for a first load that skipped the setup
1210
1273
  // wizard (the wizard and dev-bypass apply seeds explicitly). Run under a
1211
1274
  // per-isolate lock keyed by the configured db so a reclaimed-and-rerun
@@ -1386,7 +1449,7 @@ export class EmDashRuntime {
1386
1449
 
1387
1450
  // Load sandboxed plugins (build-time, sandbox runner path)
1388
1451
  const sandboxedPlugins = await phase("rt.sandbox", "Sandboxed plugins", () =>
1389
- EmDashRuntime.loadSandboxedPlugins(deps, db, storage),
1452
+ EmDashRuntime.loadSandboxedPlugins(deps, db, storage, siteInfo),
1390
1453
  );
1391
1454
 
1392
1455
  // Cold-start: load marketplace- and registry-installed plugins from
@@ -1404,6 +1467,7 @@ export class EmDashRuntime {
1404
1467
  storage,
1405
1468
  deps,
1406
1469
  sandboxedPlugins,
1470
+ siteInfo,
1407
1471
  ),
1408
1472
  ),
1409
1473
  );
@@ -1419,6 +1483,7 @@ export class EmDashRuntime {
1419
1483
  storage,
1420
1484
  deps,
1421
1485
  sandboxedPlugins,
1486
+ siteInfo,
1422
1487
  ),
1423
1488
  ),
1424
1489
  );
@@ -1487,6 +1552,12 @@ export class EmDashRuntime {
1487
1552
  await phase("rt.cron", "Cron init (recovery deferred post-response)", async () => {
1488
1553
  try {
1489
1554
  cronExecutor = new CronExecutor(resolveDb, invokeCronHook);
1555
+ // Plugin schedules are always database-backed. On long-lived runtimes this
1556
+ // callback also wakes the timer; on Cloudflare the external Cron Trigger
1557
+ // drives execution, so rescheduling is intentionally a no-op.
1558
+ pipeline.setContextFactory({
1559
+ cronReschedule: () => cronScheduler?.reschedule(),
1560
+ });
1490
1561
 
1491
1562
  // Recover stale locks from previous crashes. Pure bookkeeping
1492
1563
  // against the _emdash_cron_tasks table — no request needs the
@@ -1541,11 +1612,8 @@ export class EmDashRuntime {
1541
1612
  // by runSystemCleanup. This catches unexpected errors.
1542
1613
  console.error("[cleanup] System cleanup failed:", error);
1543
1614
  }
1544
- });
1545
-
1546
- // Add cron reschedule callback (merges with existing factory options)
1547
- pipeline.setContextFactory({
1548
- cronReschedule: () => cronScheduler?.reschedule(),
1615
+ // Never throws; no-op unless scheduled backups are enabled and due.
1616
+ await maybeRunScheduledBackup(db, storage ?? undefined);
1549
1617
  });
1550
1618
 
1551
1619
  // start() is void on the timer scheduler but the interface
@@ -1805,6 +1873,7 @@ export class EmDashRuntime {
1805
1873
  storage: entry.storage as never,
1806
1874
  adminPages,
1807
1875
  adminWidgets,
1876
+ settingsSchema: entry.settingsSchema,
1808
1877
  portableTextBlocks: entry.portableTextBlocks,
1809
1878
  fieldWidgets: entry.fieldWidgets,
1810
1879
  });
@@ -1826,6 +1895,12 @@ export class EmDashRuntime {
1826
1895
  deps: RuntimeDependencies,
1827
1896
  db: Kysely<Database>,
1828
1897
  mediaStorage?: Storage | null,
1898
+ siteInfo?: {
1899
+ siteName?: string;
1900
+ siteUrl?: string;
1901
+ locale?: string;
1902
+ trailingSlash?: "always" | "never" | "ignore";
1903
+ },
1829
1904
  ): Promise<Map<string, SandboxedPluginInstance>> {
1830
1905
  // Return cached plugins if already loaded
1831
1906
  if (sandboxedPluginCache.size > 0) {
@@ -1839,20 +1914,25 @@ export class EmDashRuntime {
1839
1914
 
1840
1915
  // Create sandbox runner if not exists
1841
1916
  if (!sandboxRunner && deps.createSandboxRunner) {
1842
- sandboxRunner = deps.createSandboxRunner({
1843
- db,
1844
- mediaStorage: mediaStorage
1845
- ? {
1846
- upload: (opts) =>
1847
- mediaStorage.upload({
1848
- key: opts.key,
1849
- body: opts.body,
1850
- contentType: opts.contentType,
1851
- }),
1852
- delete: (key) => mediaStorage.delete(key),
1853
- }
1854
- : undefined,
1855
- });
1917
+ sandboxRunner = deps.createSandboxRunner(
1918
+ createSandboxRunnerOptions(
1919
+ {
1920
+ db,
1921
+ mediaStorage: mediaStorage
1922
+ ? {
1923
+ upload: (opts) =>
1924
+ mediaStorage.upload({
1925
+ key: opts.key,
1926
+ body: opts.body,
1927
+ contentType: opts.contentType,
1928
+ }),
1929
+ delete: (key) => mediaStorage.delete(key),
1930
+ }
1931
+ : undefined,
1932
+ },
1933
+ siteInfo,
1934
+ ),
1935
+ );
1856
1936
  }
1857
1937
 
1858
1938
  if (!sandboxRunner) {
@@ -1900,6 +1980,7 @@ export class EmDashRuntime {
1900
1980
  hooks: [],
1901
1981
  routes: [],
1902
1982
  admin: {},
1983
+ mcp: entry.mcp,
1903
1984
  };
1904
1985
 
1905
1986
  const plugin = await sandboxRunner.load(manifest, entry.code);
@@ -1935,22 +2016,33 @@ export class EmDashRuntime {
1935
2016
  storage: Storage,
1936
2017
  deps: RuntimeDependencies,
1937
2018
  cache: Map<string, SandboxedPluginInstance>,
2019
+ siteInfo?: {
2020
+ siteName?: string;
2021
+ siteUrl?: string;
2022
+ locale?: string;
2023
+ trailingSlash?: "always" | "never" | "ignore";
2024
+ },
1938
2025
  ): Promise<void> {
1939
2026
  // Ensure sandbox runner exists with media storage wired up.
1940
2027
  // (storage here is the media Storage adapter from the runtime.)
1941
2028
  if (!sandboxRunner && deps.createSandboxRunner) {
1942
- sandboxRunner = deps.createSandboxRunner({
1943
- db,
1944
- mediaStorage: {
1945
- upload: (opts) =>
1946
- storage.upload({
1947
- key: opts.key,
1948
- body: opts.body,
1949
- contentType: opts.contentType,
1950
- }),
1951
- delete: (key) => storage.delete(key),
1952
- },
1953
- });
2029
+ sandboxRunner = deps.createSandboxRunner(
2030
+ createSandboxRunnerOptions(
2031
+ {
2032
+ db,
2033
+ mediaStorage: {
2034
+ upload: (opts) =>
2035
+ storage.upload({
2036
+ key: opts.key,
2037
+ body: opts.body,
2038
+ contentType: opts.contentType,
2039
+ }),
2040
+ delete: (key) => storage.delete(key),
2041
+ },
2042
+ },
2043
+ siteInfo,
2044
+ ),
2045
+ );
1954
2046
  }
1955
2047
  // In sandbox bypass mode, marketplace plugins are loaded in-process
1956
2048
  // BEFORE pipeline creation by EmDashRuntime.create(). Skip here.
@@ -1997,6 +2089,7 @@ export class EmDashRuntime {
1997
2089
  id: bundle.manifest.id,
1998
2090
  version: bundle.manifest.version,
1999
2091
  admin: bundle.manifest.admin,
2092
+ mcp: bundle.manifest.mcp,
2000
2093
  });
2001
2094
 
2002
2095
  // Cache route metadata from manifest for auth decisions
@@ -2004,7 +2097,7 @@ export class EmDashRuntime {
2004
2097
  const routeMeta = new Map<string, RouteMeta>();
2005
2098
  for (const entry of bundle.manifest.routes) {
2006
2099
  const normalized = normalizeManifestRoute(entry);
2007
- routeMeta.set(normalized.name, { public: normalized.public === true });
2100
+ routeMeta.set(normalized.name, buildRouteMeta(normalized));
2008
2101
  }
2009
2102
  sandboxedRouteMetaCache.set(plugin.pluginId, routeMeta);
2010
2103
  }
@@ -2068,12 +2161,13 @@ export class EmDashRuntime {
2068
2161
  id: bundle.manifest.id,
2069
2162
  version: bundle.manifest.version,
2070
2163
  admin: bundle.manifest.admin,
2164
+ mcp: bundle.manifest.mcp,
2071
2165
  });
2072
2166
  if (bundle.manifest.routes.length > 0) {
2073
2167
  const routeMeta = new Map<string, RouteMeta>();
2074
2168
  for (const entry of bundle.manifest.routes) {
2075
2169
  const normalized = normalizeManifestRoute(entry);
2076
- routeMeta.set(normalized.name, { public: normalized.public === true });
2170
+ routeMeta.set(normalized.name, buildRouteMeta(normalized));
2077
2171
  }
2078
2172
  sandboxedRouteMetaCache.set(plugin.pluginId, routeMeta);
2079
2173
  }
@@ -2103,6 +2197,7 @@ export class EmDashRuntime {
2103
2197
  size:
2104
2198
  w.size === "full" || w.size === "half" || w.size === "third" ? w.size : undefined,
2105
2199
  })),
2200
+ settingsSchema: bundle.manifest.admin?.settingsSchema,
2106
2201
  });
2107
2202
  resolved.push(adapted);
2108
2203
  console.log(
@@ -2781,13 +2876,14 @@ export class EmDashRuntime {
2781
2876
  authorId: bodyWithoutRev.authorId ?? undefined,
2782
2877
  });
2783
2878
 
2784
- // Update entry to point to new draft (metadata only, not data columns)
2879
+ // Update entry to point to new draft (metadata only, not data columns).
2880
+ // No updated_at stamp: draft staging leaves live content untouched,
2881
+ // so public "last modified" consumers must not see a change (#2143).
2785
2882
  validateIdentifier(collection, "collection");
2786
2883
  const tableName = `ec_${collection}`;
2787
2884
  await sql`
2788
2885
  UPDATE ${sql.ref(tableName)}
2789
- SET draft_revision_id = ${revision.id},
2790
- updated_at = ${new Date().toISOString()}
2886
+ SET draft_revision_id = ${revision.id}
2791
2887
  WHERE id = ${resolvedId}
2792
2888
  `.execute(this.db);
2793
2889
  draftStorageChanged = true;
@@ -2897,7 +2993,7 @@ export class EmDashRuntime {
2897
2993
  await this.refreshContentUsageAfterSuccessfulWrite(collection, [result.data.id]);
2898
2994
  }
2899
2995
 
2900
- // Run afterDelete hooks (fire-and-forget)
2996
+ // Run afterDelete hooks (deferred past the response via after())
2901
2997
  if (result.success) {
2902
2998
  this.runAfterDeleteHooks(id, collection, false);
2903
2999
  }
@@ -2984,7 +3080,7 @@ export class EmDashRuntime {
2984
3080
  await this.refreshContentUsageAfterSuccessfulWrite(collection, [result.data.item.id]);
2985
3081
  }
2986
3082
 
2987
- // Run afterUnpublish hooks (fire-and-forget)
3083
+ // Run afterUnpublish hooks (deferred past the response via after())
2988
3084
  if (result.success && result.data) {
2989
3085
  this.runAfterUnpublishHooks(contentItemToRecord(result.data.item), collection);
2990
3086
  }
@@ -3179,7 +3275,10 @@ export class EmDashRuntime {
3179
3275
 
3180
3276
  // Revision-capable collections: restore is "make this revision the
3181
3277
  // current draft". The live row's data columns are left untouched
3182
- // (only `draft_revision_id` and `updated_at` change). The caller
3278
+ // (only `draft_revision_id` changes — no `updated_at` stamp, since
3279
+ // restoring to draft is the same kind of draft-only staging as
3280
+ // Save/Autosave and must not register a phantom modification for
3281
+ // sitemap <lastmod> / JSON-LD dateModified, #2143). The caller
3183
3282
  // must then `content_publish` to promote the restored draft to
3184
3283
  // live, matching the documented tool contract.
3185
3284
  try {
@@ -3194,8 +3293,7 @@ export class EmDashRuntime {
3194
3293
  const tableName = `ec_${revision.collection}`;
3195
3294
  await sql`
3196
3295
  UPDATE ${sql.ref(tableName)}
3197
- SET draft_revision_id = ${newDraft.id},
3198
- updated_at = ${new Date().toISOString()}
3296
+ SET draft_revision_id = ${newDraft.id}
3199
3297
  WHERE id = ${revision.entryId}
3200
3298
  `.execute(this.db);
3201
3299
 
@@ -3280,7 +3378,7 @@ export class EmDashRuntime {
3280
3378
  if (trustedPlugin) {
3281
3379
  const route = trustedPlugin.routes[routeKey];
3282
3380
  if (!route) return null;
3283
- return { public: route.public === true };
3381
+ return buildRouteMeta(route);
3284
3382
  }
3285
3383
 
3286
3384
  // Check sandboxed plugin route metadata cache
@@ -3314,6 +3412,18 @@ export class EmDashRuntime {
3314
3412
  return null;
3315
3413
  }
3316
3414
 
3415
+ /**
3416
+ * Resolve the settings schema for a runtime-installed (marketplace or
3417
+ * registry) plugin from its cached manifest. Returns `{}` for a known
3418
+ * plugin without a schema and `null` for unknown plugins, matching the
3419
+ * contract of `getPluginSettingsSchema` for build-time plugins.
3420
+ */
3421
+ getRuntimePluginSettingsSchema(pluginId: string): Record<string, SettingField> | null {
3422
+ const meta = marketplaceManifestCache.get(pluginId);
3423
+ if (!meta) return null;
3424
+ return meta.admin?.settingsSchema ?? {};
3425
+ }
3426
+
3317
3427
  async handlePluginApiRoute(pluginId: string, _method: string, path: string, request: Request) {
3318
3428
  if (!this.isPluginEnabled(pluginId)) {
3319
3429
  return {
@@ -3327,9 +3437,9 @@ export class EmDashRuntime {
3327
3437
  const trustedPlugin = this.configuredPlugins.find((p) => p.id === pluginId);
3328
3438
  if (trustedPlugin && this.enabledPlugins.has(trustedPlugin.id)) {
3329
3439
  const routeRegistry = new PluginRouteRegistry({
3330
- db: this.db,
3331
- storage: this.storage ?? undefined,
3440
+ ...this.pipelineFactoryOptions,
3332
3441
  emailPipeline: this.email ?? undefined,
3442
+ cronReschedule: () => this.cronScheduler?.reschedule(),
3333
3443
  trustedProxyHeaders: getTrustedProxyHeaders(this.config),
3334
3444
  });
3335
3445
  routeRegistry.register(trustedPlugin);
@@ -3358,6 +3468,168 @@ export class EmDashRuntime {
3358
3468
  };
3359
3469
  }
3360
3470
 
3471
+ async getPluginMcpTools(pluginId?: string) {
3472
+ const tools: Array<{
3473
+ pluginId: string;
3474
+ name: string;
3475
+ description: string;
3476
+ route: string;
3477
+ permission: string;
3478
+ destructive: boolean;
3479
+ inputSchema: z.ZodType;
3480
+ outputSchema?: z.ZodType;
3481
+ }> = [];
3482
+ const seen = new Set<string>();
3483
+
3484
+ for (const plugin of this.configuredPlugins) {
3485
+ if (pluginId && plugin.id !== pluginId) continue;
3486
+ for (const [name, tool] of Object.entries(plugin.mcp?.tools ?? {})) {
3487
+ const route = plugin.routes[tool.route];
3488
+ if (!route || route.public || !route.permission || !(route.permission in Permissions))
3489
+ continue;
3490
+ const key = `${plugin.id}__${name}`;
3491
+ if (seen.has(key)) continue;
3492
+ seen.add(key);
3493
+ tools.push({
3494
+ pluginId: plugin.id,
3495
+ name,
3496
+ description: tool.description,
3497
+ route: tool.route,
3498
+ permission: route.permission,
3499
+ destructive: tool.destructive ?? false,
3500
+ inputSchema: tool.input,
3501
+ outputSchema: tool.output,
3502
+ });
3503
+ }
3504
+ }
3505
+
3506
+ const addManifestTools = (id: string, mcp: PluginMcpManifestConfig | undefined) => {
3507
+ if (pluginId && id !== pluginId) return;
3508
+ for (const tool of mcp?.tools ?? []) {
3509
+ const key = `${id}__${tool.name}`;
3510
+ const routeMeta = this.getPluginRouteMeta(id, tool.route);
3511
+ if (
3512
+ seen.has(key) ||
3513
+ !routeMeta ||
3514
+ routeMeta.public ||
3515
+ routeMeta.permission !== tool.permission ||
3516
+ !(tool.permission in Permissions)
3517
+ ) {
3518
+ continue;
3519
+ }
3520
+ seen.add(key);
3521
+ tools.push({
3522
+ pluginId: id,
3523
+ name: tool.name,
3524
+ description: tool.description,
3525
+ route: tool.route,
3526
+ permission: tool.permission,
3527
+ destructive: tool.destructive,
3528
+ inputSchema: z.fromJSONSchema({ ...tool.inputSchema }),
3529
+ outputSchema: tool.outputSchema ? z.fromJSONSchema({ ...tool.outputSchema }) : undefined,
3530
+ });
3531
+ }
3532
+ };
3533
+
3534
+ for (const entry of this.sandboxedPluginEntries) addManifestTools(entry.id, entry.mcp);
3535
+ for (const [id, manifest] of marketplaceManifestCache) addManifestTools(id, manifest.mcp);
3536
+
3537
+ return tools;
3538
+ }
3539
+
3540
+ async getEnabledPluginMcpTools() {
3541
+ const [tools, states] = await Promise.all([
3542
+ this.getPluginMcpTools(),
3543
+ new PluginStateRepository(this.db).getAll(),
3544
+ ]);
3545
+ const stateByPlugin = new Map(states.map((state) => [state.pluginId, state]));
3546
+ return tools.filter((tool) => {
3547
+ const state = stateByPlugin.get(tool.pluginId);
3548
+ if (
3549
+ !state?.mcpToolsEnabled ||
3550
+ state.status !== "active" ||
3551
+ !this.isPluginEnabled(tool.pluginId)
3552
+ ) {
3553
+ return false;
3554
+ }
3555
+ const consented = state.mcpToolsConsent;
3556
+ return consented === this.serializePluginMcpConsent(tools, tool.pluginId);
3557
+ });
3558
+ }
3559
+
3560
+ serializePluginMcpConsent(
3561
+ tools: Awaited<ReturnType<EmDashRuntime["getPluginMcpTools"]>>,
3562
+ pluginId: string,
3563
+ ): string {
3564
+ return JSON.stringify(
3565
+ tools
3566
+ .filter((tool) => tool.pluginId === pluginId)
3567
+ .map((tool) => ({
3568
+ name: tool.name,
3569
+ description: tool.description,
3570
+ route: tool.route,
3571
+ permission: tool.permission,
3572
+ destructive: tool.destructive,
3573
+ inputSchema: z.toJSONSchema(tool.inputSchema, { target: "draft-7" }),
3574
+ ...(tool.outputSchema
3575
+ ? { outputSchema: z.toJSONSchema(tool.outputSchema, { target: "draft-7" }) }
3576
+ : {}),
3577
+ }))
3578
+ .toSorted((a, b) => a.name.localeCompare(b.name)),
3579
+ );
3580
+ }
3581
+
3582
+ async handlePluginMcpTool(
3583
+ pluginId: string,
3584
+ toolName: string,
3585
+ route: string,
3586
+ input: unknown,
3587
+ actorId: string,
3588
+ request: Request,
3589
+ ) {
3590
+ const requestMeta = extractRequestMeta(request, getTrustedProxyHeaders(this.config));
3591
+ const audit = new AuditRepository(this.db);
3592
+ const headers = new Headers(request.headers);
3593
+ headers.delete("content-length");
3594
+ headers.delete("content-encoding");
3595
+ const internalRequest = new Request(request.url, {
3596
+ method: "POST",
3597
+ headers,
3598
+ body: JSON.stringify(input),
3599
+ });
3600
+ const result = await this.handlePluginApiRoute(pluginId, "POST", route, internalRequest);
3601
+ await audit.log({
3602
+ actorId,
3603
+ actorIp: requestMeta.ip ?? undefined,
3604
+ action: "plugin_tool_invoke",
3605
+ resourceType: "plugin_mcp_tool",
3606
+ resourceId: `${pluginId}__${toolName}`,
3607
+ details: { pluginId, tool: toolName, route },
3608
+ status: result.success ? "success" : "failure",
3609
+ });
3610
+ return result;
3611
+ }
3612
+
3613
+ async handlePluginMcpDenied(
3614
+ pluginId: string,
3615
+ toolName: string,
3616
+ route: string,
3617
+ actorId: string,
3618
+ request: Request,
3619
+ reason: string,
3620
+ ): Promise<void> {
3621
+ const requestMeta = extractRequestMeta(request, getTrustedProxyHeaders(this.config));
3622
+ await new AuditRepository(this.db).log({
3623
+ actorId,
3624
+ actorIp: requestMeta.ip ?? undefined,
3625
+ action: "plugin_tool_invoke",
3626
+ resourceType: "plugin_mcp_tool",
3627
+ resourceId: `${pluginId}__${toolName}`,
3628
+ details: { pluginId, tool: toolName, route, reason },
3629
+ status: "denied",
3630
+ });
3631
+ }
3632
+
3361
3633
  // =========================================================================
3362
3634
  // Sandboxed Plugin Helpers
3363
3635
  // =========================================================================
@@ -3502,24 +3774,34 @@ export class EmDashRuntime {
3502
3774
  }
3503
3775
 
3504
3776
  private runAfterDeleteHooks(id: string, collection: string, permanent: boolean): void {
3505
- // Trusted plugins
3506
- if (this.hooks.hasHooks("content:afterDelete")) {
3507
- this.hooks
3508
- .runContentAfterDelete(id, collection, permanent)
3509
- .catch((err) => console.error("EmDash afterDelete hook error:", err));
3510
- }
3777
+ after(async () => {
3778
+ // Trusted plugins
3779
+ if (this.hooks.hasHooks("content:afterDelete")) {
3780
+ try {
3781
+ await this.hooks.runContentAfterDelete(id, collection, permanent);
3782
+ } catch (err) {
3783
+ console.error("EmDash afterDelete hook error:", err);
3784
+ }
3785
+ }
3511
3786
 
3512
- // Sandboxed plugins
3513
- for (const [pluginKey, plugin] of this.sandboxedPlugins) {
3514
- const [pluginId] = pluginKey.split(":");
3515
- if (!pluginId || !this.isPluginEnabled(pluginId)) continue;
3787
+ // Sandboxed plugins
3788
+ const tasks: Promise<void>[] = [];
3789
+ for (const [pluginKey, plugin] of this.sandboxedPlugins) {
3790
+ const [pluginId] = pluginKey.split(":");
3791
+ if (!pluginId || !this.isPluginEnabled(pluginId)) continue;
3516
3792
 
3517
- plugin
3518
- .invokeHook("content:afterDelete", { id, collection, permanent })
3519
- .catch((err) =>
3520
- console.error(`EmDash: Sandboxed plugin ${pluginId} afterDelete error:`, err),
3793
+ tasks.push(
3794
+ (async () => {
3795
+ try {
3796
+ await plugin.invokeHook("content:afterDelete", { id, collection, permanent });
3797
+ } catch (err) {
3798
+ console.error(`EmDash: Sandboxed plugin ${pluginId} afterDelete error:`, err);
3799
+ }
3800
+ })(),
3521
3801
  );
3522
- }
3802
+ }
3803
+ await Promise.allSettled(tasks);
3804
+ });
3523
3805
  }
3524
3806
 
3525
3807
  private runDeferredContentHook(