emdash 0.28.1 → 0.30.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 (946) hide show
  1. package/dist/{adapters-hUy8vOB-.d.mts → adapters-C0ONzkUP.d.mts} +10 -1
  2. package/dist/adapters-C0ONzkUP.d.mts.map +1 -0
  3. package/dist/{allowed-origins-CRsJ6BPM.mjs → allowed-origins-CCEi9bPI.mjs} +2 -2
  4. package/dist/{allowed-origins-CRsJ6BPM.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 +22 -21
  8. package/dist/api/route-utils.mjs.map +1 -1
  9. package/dist/api/schemas/index.d.mts +2 -2
  10. package/dist/api/schemas/index.mjs +5 -4
  11. package/dist/{api-DxFSorgk.mjs → api-b8WIiGU4.mjs} +306 -154
  12. package/dist/api-b8WIiGU4.mjs.map +1 -0
  13. package/dist/api-tokens-Cvmixds7.mjs +3 -0
  14. package/dist/{api-tokens-DvqeZmVq.mjs → api-tokens-uPt8UDpx.mjs} +2 -2
  15. package/dist/{api-tokens-DvqeZmVq.mjs.map → api-tokens-uPt8UDpx.mjs.map} +1 -1
  16. package/dist/{apply-CDJqIjPU.mjs → apply-CmIJK9j8.mjs} +35 -38
  17. package/dist/apply-CmIJK9j8.mjs.map +1 -0
  18. package/dist/astro/index.d.mts +12 -12
  19. package/dist/astro/index.d.mts.map +1 -1
  20. package/dist/astro/index.mjs +97 -13
  21. package/dist/astro/index.mjs.map +1 -1
  22. package/dist/astro/middleware/auth.d.mts +10 -10
  23. package/dist/astro/middleware/auth.d.mts.map +1 -1
  24. package/dist/astro/middleware/auth.mjs +56 -107
  25. package/dist/astro/middleware/auth.mjs.map +1 -1
  26. package/dist/astro/middleware/redirect.mjs +7 -7
  27. package/dist/astro/middleware/request-context.d.mts +3 -0
  28. package/dist/astro/middleware/request-context.d.mts.map +1 -1
  29. package/dist/astro/middleware/request-context.mjs +258 -31
  30. package/dist/astro/middleware/request-context.mjs.map +1 -1
  31. package/dist/astro/middleware/setup.mjs +1 -1
  32. package/dist/astro/middleware.d.mts +47 -3
  33. package/dist/astro/middleware.d.mts.map +1 -1
  34. package/dist/astro/middleware.mjs +379 -117
  35. package/dist/astro/middleware.mjs.map +1 -1
  36. package/dist/astro/routes/PluginRegistry.d.mts +5 -1
  37. package/dist/astro/routes/PluginRegistry.d.mts.map +1 -1
  38. package/dist/astro/routes/PluginRegistry.mjs +2 -1
  39. package/dist/astro/routes/PluginRegistry.mjs.map +1 -1
  40. package/dist/astro/routes/api/admin/allowed-domains/_domain_.mjs +9 -8
  41. package/dist/astro/routes/api/admin/allowed-domains/_domain_.mjs.map +1 -1
  42. package/dist/astro/routes/api/admin/allowed-domains/index.mjs +9 -8
  43. package/dist/astro/routes/api/admin/allowed-domains/index.mjs.map +1 -1
  44. package/dist/astro/routes/api/admin/api-tokens/_id_.mjs +5 -5
  45. package/dist/astro/routes/api/admin/api-tokens/index.mjs +7 -7
  46. package/dist/astro/routes/api/admin/api-tokens/index.mjs.map +1 -1
  47. package/dist/astro/routes/api/admin/byline-fields/_slug_/usage.mjs +6 -6
  48. package/dist/astro/routes/api/admin/byline-fields/_slug_.mjs +11 -10
  49. package/dist/astro/routes/api/admin/byline-fields/_slug_.mjs.map +1 -1
  50. package/dist/astro/routes/api/admin/byline-fields/index.mjs +11 -10
  51. package/dist/astro/routes/api/admin/byline-fields/index.mjs.map +1 -1
  52. package/dist/astro/routes/api/admin/byline-fields/reorder.mjs +11 -10
  53. package/dist/astro/routes/api/admin/byline-fields/reorder.mjs.map +1 -1
  54. package/dist/astro/routes/api/admin/bylines/_id_/index.mjs +18 -17
  55. package/dist/astro/routes/api/admin/bylines/_id_/index.mjs.map +1 -1
  56. package/dist/astro/routes/api/admin/bylines/_id_/translations.mjs +19 -24
  57. package/dist/astro/routes/api/admin/bylines/_id_/translations.mjs.map +1 -1
  58. package/dist/astro/routes/api/admin/bylines/index.mjs +18 -17
  59. package/dist/astro/routes/api/admin/bylines/index.mjs.map +1 -1
  60. package/dist/astro/routes/api/admin/comments/_id_/status.d.mts.map +1 -1
  61. package/dist/astro/routes/api/admin/comments/_id_/status.mjs +14 -13
  62. package/dist/astro/routes/api/admin/comments/_id_/status.mjs.map +1 -1
  63. package/dist/astro/routes/api/admin/comments/_id_.mjs +6 -6
  64. package/dist/astro/routes/api/admin/comments/bulk.mjs +11 -10
  65. package/dist/astro/routes/api/admin/comments/bulk.mjs.map +1 -1
  66. package/dist/astro/routes/api/admin/comments/counts.mjs +6 -6
  67. package/dist/astro/routes/api/admin/comments/index.d.mts.map +1 -1
  68. package/dist/astro/routes/api/admin/comments/index.mjs +11 -10
  69. package/dist/astro/routes/api/admin/comments/index.mjs.map +1 -1
  70. package/dist/astro/routes/api/admin/hooks/exclusive/_hookName_.mjs +6 -6
  71. package/dist/astro/routes/api/admin/hooks/exclusive/index.mjs +5 -5
  72. package/dist/astro/routes/api/admin/media-usage/repair.d.mts +8 -0
  73. package/dist/astro/routes/api/admin/media-usage/repair.d.mts.map +1 -0
  74. package/dist/astro/routes/api/admin/media-usage/repair.mjs +30 -0
  75. package/dist/astro/routes/api/admin/media-usage/repair.mjs.map +1 -0
  76. package/dist/astro/routes/api/admin/oauth-clients/_id_.mjs +5 -5
  77. package/dist/astro/routes/api/admin/oauth-clients/index.mjs +5 -5
  78. package/dist/astro/routes/api/admin/plugins/_id_/disable.mjs +44 -41
  79. package/dist/astro/routes/api/admin/plugins/_id_/disable.mjs.map +1 -1
  80. package/dist/astro/routes/api/admin/plugins/_id_/enable.mjs +44 -41
  81. package/dist/astro/routes/api/admin/plugins/_id_/enable.mjs.map +1 -1
  82. package/dist/astro/routes/api/admin/plugins/_id_/index.mjs +49 -41
  83. package/dist/astro/routes/api/admin/plugins/_id_/index.mjs.map +1 -1
  84. package/dist/astro/routes/api/admin/plugins/_id_/mcp.d.mts +8 -0
  85. package/dist/astro/routes/api/admin/plugins/_id_/mcp.d.mts.map +1 -0
  86. package/dist/astro/routes/api/admin/plugins/_id_/mcp.mjs +39 -0
  87. package/dist/astro/routes/api/admin/plugins/_id_/mcp.mjs.map +1 -0
  88. package/dist/astro/routes/api/admin/plugins/_id_/settings.d.mts +9 -0
  89. package/dist/astro/routes/api/admin/plugins/_id_/settings.d.mts.map +1 -0
  90. package/dist/astro/routes/api/admin/plugins/_id_/settings.mjs +78 -0
  91. package/dist/astro/routes/api/admin/plugins/_id_/settings.mjs.map +1 -0
  92. package/dist/astro/routes/api/admin/plugins/_id_/uninstall.mjs +43 -40
  93. package/dist/astro/routes/api/admin/plugins/_id_/uninstall.mjs.map +1 -1
  94. package/dist/astro/routes/api/admin/plugins/_id_/update.d.mts.map +1 -1
  95. package/dist/astro/routes/api/admin/plugins/_id_/update.mjs +46 -41
  96. package/dist/astro/routes/api/admin/plugins/_id_/update.mjs.map +1 -1
  97. package/dist/astro/routes/api/admin/plugins/index.mjs +49 -41
  98. package/dist/astro/routes/api/admin/plugins/index.mjs.map +1 -1
  99. package/dist/astro/routes/api/admin/plugins/marketplace/_id_/icon.mjs +4 -4
  100. package/dist/astro/routes/api/admin/plugins/marketplace/_id_/index.mjs +43 -40
  101. package/dist/astro/routes/api/admin/plugins/marketplace/_id_/index.mjs.map +1 -1
  102. package/dist/astro/routes/api/admin/plugins/marketplace/_id_/install.d.mts.map +1 -1
  103. package/dist/astro/routes/api/admin/plugins/marketplace/_id_/install.mjs +49 -42
  104. package/dist/astro/routes/api/admin/plugins/marketplace/_id_/install.mjs.map +1 -1
  105. package/dist/astro/routes/api/admin/plugins/marketplace/index.mjs +43 -40
  106. package/dist/astro/routes/api/admin/plugins/marketplace/index.mjs.map +1 -1
  107. package/dist/astro/routes/api/admin/plugins/registry/_id_/uninstall.mjs +43 -40
  108. package/dist/astro/routes/api/admin/plugins/registry/_id_/uninstall.mjs.map +1 -1
  109. package/dist/astro/routes/api/admin/plugins/registry/_id_/update.d.mts.map +1 -1
  110. package/dist/astro/routes/api/admin/plugins/registry/_id_/update.mjs +47 -42
  111. package/dist/astro/routes/api/admin/plugins/registry/_id_/update.mjs.map +1 -1
  112. package/dist/astro/routes/api/admin/plugins/registry/artifact.mjs +43 -40
  113. package/dist/astro/routes/api/admin/plugins/registry/artifact.mjs.map +1 -1
  114. package/dist/astro/routes/api/admin/plugins/registry/install.d.mts.map +1 -1
  115. package/dist/astro/routes/api/admin/plugins/registry/install.mjs +48 -43
  116. package/dist/astro/routes/api/admin/plugins/registry/install.mjs.map +1 -1
  117. package/dist/astro/routes/api/admin/plugins/updates.mjs +44 -41
  118. package/dist/astro/routes/api/admin/plugins/updates.mjs.map +1 -1
  119. package/dist/astro/routes/api/admin/themes/marketplace/_id_/index.mjs +43 -40
  120. package/dist/astro/routes/api/admin/themes/marketplace/_id_/index.mjs.map +1 -1
  121. package/dist/astro/routes/api/admin/themes/marketplace/_id_/thumbnail.mjs +4 -4
  122. package/dist/astro/routes/api/admin/themes/marketplace/index.mjs +43 -40
  123. package/dist/astro/routes/api/admin/themes/marketplace/index.mjs.map +1 -1
  124. package/dist/astro/routes/api/admin/users/_id_/disable.mjs +5 -5
  125. package/dist/astro/routes/api/admin/users/_id_/enable.mjs +4 -4
  126. package/dist/astro/routes/api/admin/users/_id_/index.mjs +10 -9
  127. package/dist/astro/routes/api/admin/users/_id_/index.mjs.map +1 -1
  128. package/dist/astro/routes/api/admin/users/_id_/send-recovery.mjs +6 -6
  129. package/dist/astro/routes/api/admin/users/index.mjs +9 -8
  130. package/dist/astro/routes/api/admin/users/index.mjs.map +1 -1
  131. package/dist/astro/routes/api/auth/dev-bypass.mjs +7 -7
  132. package/dist/astro/routes/api/auth/invite/accept.mjs +4 -4
  133. package/dist/astro/routes/api/auth/invite/complete.mjs +14 -13
  134. package/dist/astro/routes/api/auth/invite/complete.mjs.map +1 -1
  135. package/dist/astro/routes/api/auth/invite/index.mjs +11 -10
  136. package/dist/astro/routes/api/auth/invite/index.mjs.map +1 -1
  137. package/dist/astro/routes/api/auth/invite/register-options.mjs +13 -12
  138. package/dist/astro/routes/api/auth/invite/register-options.mjs.map +1 -1
  139. package/dist/astro/routes/api/auth/logout.mjs +4 -4
  140. package/dist/astro/routes/api/auth/magic-link/send.mjs +13 -12
  141. package/dist/astro/routes/api/auth/magic-link/send.mjs.map +1 -1
  142. package/dist/astro/routes/api/auth/magic-link/verify.mjs +5 -5
  143. package/dist/astro/routes/api/auth/me.mjs +9 -8
  144. package/dist/astro/routes/api/auth/me.mjs.map +1 -1
  145. package/dist/astro/routes/api/auth/mode.d.mts.map +1 -1
  146. package/dist/astro/routes/api/auth/mode.mjs +6 -3
  147. package/dist/astro/routes/api/auth/mode.mjs.map +1 -1
  148. package/dist/astro/routes/api/auth/oauth/_provider_/callback.mjs +16 -6
  149. package/dist/astro/routes/api/auth/oauth/_provider_/callback.mjs.map +1 -1
  150. package/dist/astro/routes/api/auth/oauth/_provider_.d.mts.map +1 -1
  151. package/dist/astro/routes/api/auth/oauth/_provider_.mjs +11 -5
  152. package/dist/astro/routes/api/auth/oauth/_provider_.mjs.map +1 -1
  153. package/dist/astro/routes/api/auth/passkey/_id_.mjs +8 -7
  154. package/dist/astro/routes/api/auth/passkey/_id_.mjs.map +1 -1
  155. package/dist/astro/routes/api/auth/passkey/index.mjs +3 -3
  156. package/dist/astro/routes/api/auth/passkey/options.mjs +14 -13
  157. package/dist/astro/routes/api/auth/passkey/options.mjs.map +1 -1
  158. package/dist/astro/routes/api/auth/passkey/register/options.mjs +12 -11
  159. package/dist/astro/routes/api/auth/passkey/register/options.mjs.map +1 -1
  160. package/dist/astro/routes/api/auth/passkey/register/verify.mjs +13 -12
  161. package/dist/astro/routes/api/auth/passkey/register/verify.mjs.map +1 -1
  162. package/dist/astro/routes/api/auth/passkey/verify.mjs +13 -12
  163. package/dist/astro/routes/api/auth/passkey/verify.mjs.map +1 -1
  164. package/dist/astro/routes/api/auth/signup/complete.mjs +14 -13
  165. package/dist/astro/routes/api/auth/signup/complete.mjs.map +1 -1
  166. package/dist/astro/routes/api/auth/signup/request.mjs +13 -12
  167. package/dist/astro/routes/api/auth/signup/request.mjs.map +1 -1
  168. package/dist/astro/routes/api/auth/signup/verify.mjs +4 -4
  169. package/dist/astro/routes/api/comments/_collection_/_contentId_/index.d.mts.map +1 -1
  170. package/dist/astro/routes/api/comments/_collection_/_contentId_/index.mjs +70 -14
  171. package/dist/astro/routes/api/comments/_collection_/_contentId_/index.mjs.map +1 -1
  172. package/dist/astro/routes/api/comments/_collection_/_contentId_/reactions.mjs +14 -13
  173. package/dist/astro/routes/api/comments/_collection_/_contentId_/reactions.mjs.map +1 -1
  174. package/dist/astro/routes/api/content/_collection_/_id_/compare.mjs +5 -5
  175. package/dist/astro/routes/api/content/_collection_/_id_/compare.mjs.map +1 -1
  176. package/dist/astro/routes/api/content/_collection_/_id_/discard-draft.mjs +5 -4
  177. package/dist/astro/routes/api/content/_collection_/_id_/discard-draft.mjs.map +1 -1
  178. package/dist/astro/routes/api/content/_collection_/_id_/duplicate.mjs +6 -5
  179. package/dist/astro/routes/api/content/_collection_/_id_/duplicate.mjs.map +1 -1
  180. package/dist/astro/routes/api/content/_collection_/_id_/permanent.mjs +5 -5
  181. package/dist/astro/routes/api/content/_collection_/_id_/permanent.mjs.map +1 -1
  182. package/dist/astro/routes/api/content/_collection_/_id_/preview-url.mjs +14 -13
  183. package/dist/astro/routes/api/content/_collection_/_id_/preview-url.mjs.map +1 -1
  184. package/dist/astro/routes/api/content/_collection_/_id_/publish.mjs +10 -8
  185. package/dist/astro/routes/api/content/_collection_/_id_/publish.mjs.map +1 -1
  186. package/dist/astro/routes/api/content/_collection_/_id_/references/_relation_/children.d.mts +9 -0
  187. package/dist/astro/routes/api/content/_collection_/_id_/references/_relation_/children.d.mts.map +1 -0
  188. package/dist/astro/routes/api/content/_collection_/_id_/references/_relation_/children.mjs +72 -0
  189. package/dist/astro/routes/api/content/_collection_/_id_/references/_relation_/children.mjs.map +1 -0
  190. package/dist/astro/routes/api/content/_collection_/_id_/references/_relation_/parents.d.mts +8 -0
  191. package/dist/astro/routes/api/content/_collection_/_id_/references/_relation_/parents.d.mts.map +1 -0
  192. package/dist/astro/routes/api/content/_collection_/_id_/references/_relation_/parents.mjs +51 -0
  193. package/dist/astro/routes/api/content/_collection_/_id_/references/_relation_/parents.mjs.map +1 -0
  194. package/dist/astro/routes/api/content/_collection_/_id_/restore.mjs +5 -4
  195. package/dist/astro/routes/api/content/_collection_/_id_/restore.mjs.map +1 -1
  196. package/dist/astro/routes/api/content/_collection_/_id_/revisions.mjs +5 -5
  197. package/dist/astro/routes/api/content/_collection_/_id_/revisions.mjs.map +1 -1
  198. package/dist/astro/routes/api/content/_collection_/_id_/schedule.mjs +10 -8
  199. package/dist/astro/routes/api/content/_collection_/_id_/schedule.mjs.map +1 -1
  200. package/dist/astro/routes/api/content/_collection_/_id_/terms/_taxonomy_.d.mts.map +1 -1
  201. package/dist/astro/routes/api/content/_collection_/_id_/terms/_taxonomy_.mjs +20 -19
  202. package/dist/astro/routes/api/content/_collection_/_id_/terms/_taxonomy_.mjs.map +1 -1
  203. package/dist/astro/routes/api/content/_collection_/_id_/translations.mjs +5 -5
  204. package/dist/astro/routes/api/content/_collection_/_id_/translations.mjs.map +1 -1
  205. package/dist/astro/routes/api/content/_collection_/_id_/unpublish.mjs +5 -4
  206. package/dist/astro/routes/api/content/_collection_/_id_/unpublish.mjs.map +1 -1
  207. package/dist/astro/routes/api/content/_collection_/_id_.d.mts.map +1 -1
  208. package/dist/astro/routes/api/content/_collection_/_id_.mjs +11 -9
  209. package/dist/astro/routes/api/content/_collection_/_id_.mjs.map +1 -1
  210. package/dist/astro/routes/api/content/_collection_/authors.mjs +5 -5
  211. package/dist/astro/routes/api/content/_collection_/authors.mjs.map +1 -1
  212. package/dist/astro/routes/api/content/_collection_/index.d.mts.map +1 -1
  213. package/dist/astro/routes/api/content/_collection_/index.mjs +12 -10
  214. package/dist/astro/routes/api/content/_collection_/index.mjs.map +1 -1
  215. package/dist/astro/routes/api/content/_collection_/trash.mjs +10 -9
  216. package/dist/astro/routes/api/content/_collection_/trash.mjs.map +1 -1
  217. package/dist/astro/routes/api/dashboard.mjs +8 -8
  218. package/dist/astro/routes/api/dev/emails.mjs +4 -4
  219. package/dist/astro/routes/api/import/probe.d.mts +3 -3
  220. package/dist/astro/routes/api/import/probe.mjs +19 -18
  221. package/dist/astro/routes/api/import/probe.mjs.map +1 -1
  222. package/dist/astro/routes/api/import/wordpress/analyze.mjs +5 -5
  223. package/dist/astro/routes/api/import/wordpress/execute.d.mts +11 -11
  224. package/dist/astro/routes/api/import/wordpress/execute.mjs +16 -16
  225. package/dist/astro/routes/api/import/wordpress/media.d.mts +10 -10
  226. package/dist/astro/routes/api/import/wordpress/media.mjs +12 -11
  227. package/dist/astro/routes/api/import/wordpress/media.mjs.map +1 -1
  228. package/dist/astro/routes/api/import/wordpress/prepare.mjs +12 -11
  229. package/dist/astro/routes/api/import/wordpress/prepare.mjs.map +1 -1
  230. package/dist/astro/routes/api/import/wordpress/rewrite-urls.d.mts +11 -16
  231. package/dist/astro/routes/api/import/wordpress/rewrite-urls.d.mts.map +1 -1
  232. package/dist/astro/routes/api/import/wordpress/rewrite-urls.mjs +12 -11
  233. package/dist/astro/routes/api/import/wordpress/rewrite-urls.mjs.map +1 -1
  234. package/dist/astro/routes/api/import/wordpress-plugin/analyze.d.mts +1 -1
  235. package/dist/astro/routes/api/import/wordpress-plugin/analyze.mjs +19 -18
  236. package/dist/astro/routes/api/import/wordpress-plugin/analyze.mjs.map +1 -1
  237. package/dist/astro/routes/api/import/wordpress-plugin/callback.mjs +1 -1
  238. package/dist/astro/routes/api/import/wordpress-plugin/execute.d.mts +11 -11
  239. package/dist/astro/routes/api/import/wordpress-plugin/execute.mjs +29 -28
  240. package/dist/astro/routes/api/import/wordpress-plugin/execute.mjs.map +1 -1
  241. package/dist/astro/routes/api/manifest.mjs +8 -9
  242. package/dist/astro/routes/api/manifest.mjs.map +1 -1
  243. package/dist/astro/routes/api/mcp.d.mts.map +1 -1
  244. package/dist/astro/routes/api/mcp.mjs +165 -52
  245. package/dist/astro/routes/api/mcp.mjs.map +1 -1
  246. package/dist/astro/routes/api/media/_id_/confirm.mjs +10 -9
  247. package/dist/astro/routes/api/media/_id_/confirm.mjs.map +1 -1
  248. package/dist/astro/routes/api/media/_id_/usage.d.mts +8 -0
  249. package/dist/astro/routes/api/media/_id_/usage.d.mts.map +1 -0
  250. package/dist/astro/routes/api/media/_id_/usage.mjs +37 -0
  251. package/dist/astro/routes/api/media/_id_/usage.mjs.map +1 -0
  252. package/dist/astro/routes/api/media/_id_.d.mts.map +1 -1
  253. package/dist/astro/routes/api/media/_id_.mjs +26 -10
  254. package/dist/astro/routes/api/media/_id_.mjs.map +1 -1
  255. package/dist/astro/routes/api/media/file/_...key_.mjs +4 -3
  256. package/dist/astro/routes/api/media/file/_...key_.mjs.map +1 -1
  257. package/dist/astro/routes/api/media/providers/_providerId_/_itemId_.mjs +4 -4
  258. package/dist/astro/routes/api/media/providers/_providerId_/index.mjs +4 -4
  259. package/dist/astro/routes/api/media/providers/index.mjs +4 -4
  260. package/dist/astro/routes/api/media/upload-url.mjs +11 -10
  261. package/dist/astro/routes/api/media/upload-url.mjs.map +1 -1
  262. package/dist/astro/routes/api/media.d.mts.map +1 -1
  263. package/dist/astro/routes/api/media.mjs +34 -14
  264. package/dist/astro/routes/api/media.mjs.map +1 -1
  265. package/dist/astro/routes/api/menus/_name_/items/_id_.mjs +10 -9
  266. package/dist/astro/routes/api/menus/_name_/items/_id_.mjs.map +1 -1
  267. package/dist/astro/routes/api/menus/_name_/items.mjs +10 -9
  268. package/dist/astro/routes/api/menus/_name_/items.mjs.map +1 -1
  269. package/dist/astro/routes/api/menus/_name_/reorder.mjs +10 -9
  270. package/dist/astro/routes/api/menus/_name_/reorder.mjs.map +1 -1
  271. package/dist/astro/routes/api/menus/_name_/translations.mjs +10 -9
  272. package/dist/astro/routes/api/menus/_name_/translations.mjs.map +1 -1
  273. package/dist/astro/routes/api/menus/_name_.mjs +10 -9
  274. package/dist/astro/routes/api/menus/_name_.mjs.map +1 -1
  275. package/dist/astro/routes/api/menus/index.mjs +10 -9
  276. package/dist/astro/routes/api/menus/index.mjs.map +1 -1
  277. package/dist/astro/routes/api/oauth/authorize.d.mts.map +1 -1
  278. package/dist/astro/routes/api/oauth/authorize.mjs +7 -8
  279. package/dist/astro/routes/api/oauth/authorize.mjs.map +1 -1
  280. package/dist/astro/routes/api/oauth/device/authorize.mjs +7 -7
  281. package/dist/astro/routes/api/oauth/device/code.mjs +10 -10
  282. package/dist/astro/routes/api/oauth/device/token.mjs +9 -9
  283. package/dist/astro/routes/api/oauth/register.mjs +4 -4
  284. package/dist/astro/routes/api/oauth/token/refresh.mjs +7 -7
  285. package/dist/astro/routes/api/oauth/token/revoke.mjs +7 -7
  286. package/dist/astro/routes/api/oauth/token.mjs +7 -7
  287. package/dist/astro/routes/api/openapi.json.mjs +71 -24
  288. package/dist/astro/routes/api/openapi.json.mjs.map +1 -1
  289. package/dist/astro/routes/api/plugins/_pluginId_/_...path_.d.mts.map +1 -1
  290. package/dist/astro/routes/api/plugins/_pluginId_/_...path_.mjs +20 -32
  291. package/dist/astro/routes/api/plugins/_pluginId_/_...path_.mjs.map +1 -1
  292. package/dist/astro/routes/api/redirects/404s/index.mjs +13 -12
  293. package/dist/astro/routes/api/redirects/404s/index.mjs.map +1 -1
  294. package/dist/astro/routes/api/redirects/404s/summary.mjs +13 -12
  295. package/dist/astro/routes/api/redirects/404s/summary.mjs.map +1 -1
  296. package/dist/astro/routes/api/redirects/_id_.mjs +14 -13
  297. package/dist/astro/routes/api/redirects/_id_.mjs.map +1 -1
  298. package/dist/astro/routes/api/redirects/index.mjs +14 -13
  299. package/dist/astro/routes/api/redirects/index.mjs.map +1 -1
  300. package/dist/astro/routes/api/relations/_id_/index.d.mts +10 -0
  301. package/dist/astro/routes/api/relations/_id_/index.d.mts.map +1 -0
  302. package/dist/astro/routes/api/relations/_id_/index.mjs +70 -0
  303. package/dist/astro/routes/api/relations/_id_/index.mjs.map +1 -0
  304. package/dist/astro/routes/api/relations/_id_/translations.d.mts +8 -0
  305. package/dist/astro/routes/api/relations/_id_/translations.d.mts.map +1 -0
  306. package/dist/astro/routes/api/relations/_id_/translations.mjs +34 -0
  307. package/dist/astro/routes/api/relations/_id_/translations.mjs.map +1 -0
  308. package/dist/astro/routes/api/relations/index.d.mts +9 -0
  309. package/dist/astro/routes/api/relations/index.d.mts.map +1 -0
  310. package/dist/astro/routes/api/relations/index.mjs +54 -0
  311. package/dist/astro/routes/api/relations/index.mjs.map +1 -0
  312. package/dist/astro/routes/api/revisions/_revisionId_/index.mjs +4 -4
  313. package/dist/astro/routes/api/revisions/_revisionId_/restore.mjs +5 -4
  314. package/dist/astro/routes/api/revisions/_revisionId_/restore.mjs.map +1 -1
  315. package/dist/astro/routes/api/schema/collections/_slug_/fields/_fieldSlug_.d.mts.map +1 -1
  316. package/dist/astro/routes/api/schema/collections/_slug_/fields/_fieldSlug_.mjs +43 -40
  317. package/dist/astro/routes/api/schema/collections/_slug_/fields/_fieldSlug_.mjs.map +1 -1
  318. package/dist/astro/routes/api/schema/collections/_slug_/fields/index.d.mts.map +1 -1
  319. package/dist/astro/routes/api/schema/collections/_slug_/fields/index.mjs +43 -40
  320. package/dist/astro/routes/api/schema/collections/_slug_/fields/index.mjs.map +1 -1
  321. package/dist/astro/routes/api/schema/collections/_slug_/fields/reorder.mjs +43 -40
  322. package/dist/astro/routes/api/schema/collections/_slug_/fields/reorder.mjs.map +1 -1
  323. package/dist/astro/routes/api/schema/collections/_slug_/index.mjs +43 -40
  324. package/dist/astro/routes/api/schema/collections/_slug_/index.mjs.map +1 -1
  325. package/dist/astro/routes/api/schema/collections/index.mjs +43 -40
  326. package/dist/astro/routes/api/schema/collections/index.mjs.map +1 -1
  327. package/dist/astro/routes/api/schema/index.mjs +9 -9
  328. package/dist/astro/routes/api/schema/orphans/_slug_.mjs +43 -40
  329. package/dist/astro/routes/api/schema/orphans/_slug_.mjs.map +1 -1
  330. package/dist/astro/routes/api/schema/orphans/index.mjs +43 -40
  331. package/dist/astro/routes/api/schema/orphans/index.mjs.map +1 -1
  332. package/dist/astro/routes/api/search/enable.mjs +13 -12
  333. package/dist/astro/routes/api/search/enable.mjs.map +1 -1
  334. package/dist/astro/routes/api/search/index.mjs +14 -12
  335. package/dist/astro/routes/api/search/index.mjs.map +1 -1
  336. package/dist/astro/routes/api/search/rebuild.mjs +13 -12
  337. package/dist/astro/routes/api/search/rebuild.mjs.map +1 -1
  338. package/dist/astro/routes/api/search/stats.mjs +8 -8
  339. package/dist/astro/routes/api/search/suggest.mjs +12 -11
  340. package/dist/astro/routes/api/search/suggest.mjs.map +1 -1
  341. package/dist/astro/routes/api/sections/_slug_.mjs +12 -11
  342. package/dist/astro/routes/api/sections/_slug_.mjs.map +1 -1
  343. package/dist/astro/routes/api/sections/index.mjs +12 -11
  344. package/dist/astro/routes/api/sections/index.mjs.map +1 -1
  345. package/dist/astro/routes/api/settings/backups/archives/_name_.d.mts +9 -0
  346. package/dist/astro/routes/api/settings/backups/archives/_name_.d.mts.map +1 -0
  347. package/dist/astro/routes/api/settings/backups/archives/_name_.mjs +48 -0
  348. package/dist/astro/routes/api/settings/backups/archives/_name_.mjs.map +1 -0
  349. package/dist/astro/routes/api/settings/backups/archives/index.d.mts +8 -0
  350. package/dist/astro/routes/api/settings/backups/archives/index.d.mts.map +1 -0
  351. package/dist/astro/routes/api/settings/backups/archives/index.mjs +23 -0
  352. package/dist/astro/routes/api/settings/backups/archives/index.mjs.map +1 -0
  353. package/dist/astro/routes/api/settings/backups/export.d.mts +8 -0
  354. package/dist/astro/routes/api/settings/backups/export.d.mts.map +1 -0
  355. package/dist/astro/routes/api/settings/backups/export.mjs +35 -0
  356. package/dist/astro/routes/api/settings/backups/export.mjs.map +1 -0
  357. package/dist/astro/routes/api/settings/backups/index.d.mts +9 -0
  358. package/dist/astro/routes/api/settings/backups/index.d.mts.map +1 -0
  359. package/dist/astro/routes/api/settings/backups/index.mjs +52 -0
  360. package/dist/astro/routes/api/settings/backups/index.mjs.map +1 -0
  361. package/dist/astro/routes/api/settings/email.mjs +6 -6
  362. package/dist/astro/routes/api/settings.mjs +16 -15
  363. package/dist/astro/routes/api/settings.mjs.map +1 -1
  364. package/dist/astro/routes/api/setup/admin-verify.mjs +20 -16
  365. package/dist/astro/routes/api/setup/admin-verify.mjs.map +1 -1
  366. package/dist/astro/routes/api/setup/admin.mjs +19 -15
  367. package/dist/astro/routes/api/setup/admin.mjs.map +1 -1
  368. package/dist/astro/routes/api/setup/dev-bypass.mjs +29 -29
  369. package/dist/astro/routes/api/setup/dev-reset.mjs +4 -4
  370. package/dist/astro/routes/api/setup/index.mjs +31 -30
  371. package/dist/astro/routes/api/setup/index.mjs.map +1 -1
  372. package/dist/astro/routes/api/setup/status.mjs +5 -5
  373. package/dist/astro/routes/api/snapshot.mjs +9 -216
  374. package/dist/astro/routes/api/snapshot.mjs.map +1 -1
  375. package/dist/astro/routes/api/taxonomies/_name_/terms/_slug_/translations.mjs +16 -15
  376. package/dist/astro/routes/api/taxonomies/_name_/terms/_slug_/translations.mjs.map +1 -1
  377. package/dist/astro/routes/api/taxonomies/_name_/terms/_slug_.mjs +16 -15
  378. package/dist/astro/routes/api/taxonomies/_name_/terms/_slug_.mjs.map +1 -1
  379. package/dist/astro/routes/api/taxonomies/_name_/terms/index.mjs +16 -15
  380. package/dist/astro/routes/api/taxonomies/_name_/terms/index.mjs.map +1 -1
  381. package/dist/astro/routes/api/taxonomies/index.mjs +16 -15
  382. package/dist/astro/routes/api/taxonomies/index.mjs.map +1 -1
  383. package/dist/astro/routes/api/themes/preview.mjs +7 -7
  384. package/dist/astro/routes/api/typegen.mjs +6 -6
  385. package/dist/astro/routes/api/well-known/auth.mjs +2 -2
  386. package/dist/astro/routes/api/well-known/oauth-authorization-server.d.mts.map +1 -1
  387. package/dist/astro/routes/api/well-known/oauth-authorization-server.mjs +4 -3
  388. package/dist/astro/routes/api/well-known/oauth-authorization-server.mjs.map +1 -1
  389. package/dist/astro/routes/api/well-known/oauth-protected-resource.d.mts.map +1 -1
  390. package/dist/astro/routes/api/well-known/oauth-protected-resource.mjs +4 -3
  391. package/dist/astro/routes/api/well-known/oauth-protected-resource.mjs.map +1 -1
  392. package/dist/astro/routes/api/widget-areas/_name_/reorder.mjs +9 -8
  393. package/dist/astro/routes/api/widget-areas/_name_/reorder.mjs.map +1 -1
  394. package/dist/astro/routes/api/widget-areas/_name_/widgets/_id_.mjs +13 -12
  395. package/dist/astro/routes/api/widget-areas/_name_/widgets/_id_.mjs.map +1 -1
  396. package/dist/astro/routes/api/widget-areas/_name_/widgets.mjs +13 -12
  397. package/dist/astro/routes/api/widget-areas/_name_/widgets.mjs.map +1 -1
  398. package/dist/astro/routes/api/widget-areas/_name_.mjs +8 -8
  399. package/dist/astro/routes/api/widget-areas/index.mjs +13 -12
  400. package/dist/astro/routes/api/widget-areas/index.mjs.map +1 -1
  401. package/dist/astro/routes/api/widget-components.mjs +4 -4
  402. package/dist/astro/routes/robots.txt.mjs +9 -9
  403. package/dist/astro/routes/sitemap-_collection_.xml.mjs +12 -12
  404. package/dist/astro/routes/sitemap.xml.mjs +10 -10
  405. package/dist/astro/types.d.mts +40 -16
  406. package/dist/astro/types.d.mts.map +1 -1
  407. package/dist/auth/providers/github.d.mts +1 -1
  408. package/dist/auth/providers/google.d.mts +1 -1
  409. package/dist/{authorize-Dz88F_Fw.mjs → authorize-WxsiePzy.mjs} +7 -4
  410. package/dist/authorize-WxsiePzy.mjs.map +1 -0
  411. package/dist/backup-S8kFWtwD.mjs +241 -0
  412. package/dist/backup-S8kFWtwD.mjs.map +1 -0
  413. package/dist/{base64-CmWvODNW.mjs → base64-B-PsqheR.mjs} +8 -4
  414. package/dist/base64-B-PsqheR.mjs.map +1 -0
  415. package/dist/{byline-Bm8ZgUP9.mjs → byline-XEjchwzZ.mjs} +8 -8
  416. package/dist/{byline-Bm8ZgUP9.mjs.map → byline-XEjchwzZ.mjs.map} +1 -1
  417. package/dist/{byline-fields-CIx_GuN4.mjs → byline-fields-CdU_LTF1.mjs} +2 -2
  418. package/dist/{byline-fields-CIx_GuN4.mjs.map → byline-fields-CdU_LTF1.mjs.map} +1 -1
  419. package/dist/{byline-registry-BOjqDOim.mjs → byline-registry-BCuOp4UF.mjs} +3 -3
  420. package/dist/{byline-registry-BOjqDOim.mjs.map → byline-registry-BCuOp4UF.mjs.map} +1 -1
  421. package/dist/{bylines-6tm9mgQb.mjs → bylines-BJbT4gKS.mjs} +4 -4
  422. package/dist/{bylines-6tm9mgQb.mjs.map → bylines-BJbT4gKS.mjs.map} +1 -1
  423. package/dist/{bylines-CAZxGSrm.mjs → bylines-czseViYo.mjs} +8 -8
  424. package/dist/{bylines-CAZxGSrm.mjs.map → bylines-czseViYo.mjs.map} +1 -1
  425. package/dist/{cache-CEBAZjir.mjs → cache-CGCd6AVM.mjs} +3 -3
  426. package/dist/{cache-CEBAZjir.mjs.map → cache-CGCd6AVM.mjs.map} +1 -1
  427. package/dist/{challenge-store-anhwVER0.mjs → challenge-store-BFzgFRog.mjs} +1 -1
  428. package/dist/{challenge-store-anhwVER0.mjs.map → challenge-store-BFzgFRog.mjs.map} +1 -1
  429. package/dist/{chunks-B2isWQhr.mjs → chunks-BxXyunY-.mjs} +2 -2
  430. package/dist/{chunks-B2isWQhr.mjs.map → chunks-BxXyunY-.mjs.map} +1 -1
  431. package/dist/cli/index.mjs +142 -35
  432. package/dist/cli/index.mjs.map +1 -1
  433. package/dist/client/cf-access.d.mts +1 -1
  434. package/dist/client/index.d.mts +86 -3
  435. package/dist/client/index.d.mts.map +1 -1
  436. package/dist/client/index.mjs +20 -4
  437. package/dist/client/index.mjs.map +1 -1
  438. package/dist/{comment-CzeatwBV.mjs → comment-DPT0WKyd.mjs} +2 -2
  439. package/dist/{comment-CzeatwBV.mjs.map → comment-DPT0WKyd.mjs.map} +1 -1
  440. package/dist/{comment-reaction-Cj9QJY7I.mjs → comment-reaction-C65MldIB.mjs} +2 -2
  441. package/dist/{comment-reaction-Cj9QJY7I.mjs.map → comment-reaction-C65MldIB.mjs.map} +1 -1
  442. package/dist/{comments-BLE-jv5k.mjs → comments-Bz6sCbgD.mjs} +3 -3
  443. package/dist/{comments-BLE-jv5k.mjs.map → comments-Bz6sCbgD.mjs.map} +1 -1
  444. package/dist/{components-B_sATNUc.mjs → components-DZkL4Fx0.mjs} +1 -1
  445. package/dist/{components-B_sATNUc.mjs.map → components-DZkL4Fx0.mjs.map} +1 -1
  446. package/dist/{content-DhgEth4k.mjs → content-Ci04z2z-.mjs} +227 -34
  447. package/dist/content-Ci04z2z-.mjs.map +1 -0
  448. package/dist/{content-refresh-Br4gMzh8.mjs → content-refresh-D4khvC0R.mjs} +100 -8
  449. package/dist/content-refresh-D4khvC0R.mjs.map +1 -0
  450. package/dist/{context-BRIpHARC.mjs → context-B6hc7zJL.mjs} +156 -76
  451. package/dist/context-B6hc7zJL.mjs.map +1 -0
  452. package/dist/{cron-v4FTEFR_.mjs → cron-BlKIMD_e.mjs} +1 -1
  453. package/dist/{cron-v4FTEFR_.mjs.map → cron-BlKIMD_e.mjs.map} +1 -1
  454. package/dist/{dashboard-EvEKF5en.mjs → dashboard-C5NkXFbi.mjs} +6 -5
  455. package/dist/dashboard-C5NkXFbi.mjs.map +1 -0
  456. package/dist/database/pg-migration-lock.d.mts +21 -0
  457. package/dist/database/pg-migration-lock.d.mts.map +1 -0
  458. package/dist/database/pg-migration-lock.mjs +45 -0
  459. package/dist/database/pg-migration-lock.mjs.map +1 -0
  460. package/dist/db/index.d.mts +3 -3
  461. package/dist/db/index.mjs +2 -2
  462. package/dist/db/index.mjs.map +1 -1
  463. package/dist/db/libsql.d.mts +1 -1
  464. package/dist/db/postgres.d.mts +1 -1
  465. package/dist/db/postgres.d.mts.map +1 -1
  466. package/dist/db/postgres.mjs +2 -8
  467. package/dist/db/postgres.mjs.map +1 -1
  468. package/dist/db/sqlite.d.mts +1 -1
  469. package/dist/{db-errors-CK46D-ly.mjs → db-errors-CcWLaRiR.mjs} +4 -2
  470. package/dist/db-errors-CcWLaRiR.mjs.map +1 -0
  471. package/dist/{default-CM_D83Mg.mjs → default-C4v9KP56.mjs} +1 -1
  472. package/dist/{default-CM_D83Mg.mjs.map → default-C4v9KP56.mjs.map} +1 -1
  473. package/dist/{device-flow-CfGP18Uw.mjs → device-flow-BeA6lUS1.mjs} +6 -7
  474. package/dist/device-flow-BeA6lUS1.mjs.map +1 -0
  475. package/dist/dialect-helpers-HxEQGl_1.mjs +175 -0
  476. package/dist/dialect-helpers-HxEQGl_1.mjs.map +1 -0
  477. package/dist/{email-console-CIf4Lfvv.mjs → email-console-C-9Ng8DM.mjs} +1 -1
  478. package/dist/{email-console-CIf4Lfvv.mjs.map → email-console-C-9Ng8DM.mjs.map} +1 -1
  479. package/dist/{enrich-BQ0mxJRs.mjs → enrich-CFJJgxs_.mjs} +2 -2
  480. package/dist/{enrich-BQ0mxJRs.mjs.map → enrich-CFJJgxs_.mjs.map} +1 -1
  481. package/dist/error-CEGF6UZb.mjs +90 -0
  482. package/dist/error-CEGF6UZb.mjs.map +1 -0
  483. package/dist/{error-CkAseSqZ.mjs → errors-DtEXIQQV.mjs} +24 -84
  484. package/dist/errors-DtEXIQQV.mjs.map +1 -0
  485. package/dist/{escape-DqD0aCKu.mjs → escape-CFedIB1C.mjs} +1 -1
  486. package/dist/{escape-DqD0aCKu.mjs.map → escape-CFedIB1C.mjs.map} +1 -1
  487. package/dist/{field-defs-cache-WUI88LX5.mjs → field-defs-cache-DvmlgP-D.mjs} +5 -5
  488. package/dist/{field-defs-cache-WUI88LX5.mjs.map → field-defs-cache-DvmlgP-D.mjs.map} +1 -1
  489. package/dist/{fts-manager-BbFaF_V8.mjs → fts-manager-DzqIBrrW.mjs} +27 -3
  490. package/dist/{fts-manager-BbFaF_V8.mjs.map → fts-manager-DzqIBrrW.mjs.map} +1 -1
  491. package/dist/{hash-DrvzIXcz.mjs → hash-DFFrkivP.mjs} +1 -1
  492. package/dist/{hash-DrvzIXcz.mjs.map → hash-DFFrkivP.mjs.map} +1 -1
  493. package/dist/hreflang-CIxH_LKz.d.mts +48 -0
  494. package/dist/hreflang-CIxH_LKz.d.mts.map +1 -0
  495. package/dist/hreflang-db2Tpb2o.mjs +102 -0
  496. package/dist/hreflang-db2Tpb2o.mjs.map +1 -0
  497. package/dist/{import-fYLf14Co.mjs → import-Dmkm8S1W.mjs} +6 -6
  498. package/dist/{import-fYLf14Co.mjs.map → import-Dmkm8S1W.mjs.map} +1 -1
  499. package/dist/{index-Bm-Gy8Mh.d.mts → index-BEui-cRd.d.mts} +3 -3
  500. package/dist/{index-Bm-Gy8Mh.d.mts.map → index-BEui-cRd.d.mts.map} +1 -1
  501. package/dist/{index-B9sIxwe4.d.mts → index-wYnC6u4o.d.mts} +881 -22
  502. package/dist/index-wYnC6u4o.d.mts.map +1 -0
  503. package/dist/index.d.mts +19 -19
  504. package/dist/index.mjs +69 -64
  505. package/dist/{init-lock-6b309ZrF.mjs → init-lock-DJkX6Hto.mjs} +1 -1
  506. package/dist/{init-lock-6b309ZrF.mjs.map → init-lock-DJkX6Hto.mjs.map} +1 -1
  507. package/dist/{load-Djn3HWQS.mjs → load-Cx27ki1l.mjs} +2 -2
  508. package/dist/{load-Djn3HWQS.mjs.map → load-Cx27ki1l.mjs.map} +1 -1
  509. package/dist/{loader-CB6YHeul.mjs → loader-Be3ouI5L.mjs} +170 -21
  510. package/dist/loader-Be3ouI5L.mjs.map +1 -0
  511. package/dist/{manifest-schema-BHlgZM1W.mjs → manifest-schema-bCq54i7F.mjs} +18 -2
  512. package/dist/manifest-schema-bCq54i7F.mjs.map +1 -0
  513. package/dist/media/image-endpoint.d.mts +30 -2
  514. package/dist/media/image-endpoint.d.mts.map +1 -1
  515. package/dist/media/image-endpoint.mjs +30 -4
  516. package/dist/media/image-endpoint.mjs.map +1 -1
  517. package/dist/media/index.d.mts +1 -1
  518. package/dist/media/index.mjs +2 -2
  519. package/dist/media/local-runtime.d.mts +12 -12
  520. package/dist/media/local-runtime.mjs +8 -8
  521. package/dist/{media-BrXIaMFN.mjs → media-BjhhENaJ.mjs} +2 -2
  522. package/dist/media-BjhhENaJ.mjs.map +1 -0
  523. package/dist/{media-allowlist-CRHEeJ_i.mjs → media-allowlist-jUppPWFy.mjs} +2 -2
  524. package/dist/{media-allowlist-CRHEeJ_i.mjs.map → media-allowlist-jUppPWFy.mjs.map} +1 -1
  525. package/dist/media-kIV1IxFf.mjs +243 -0
  526. package/dist/media-kIV1IxFf.mjs.map +1 -0
  527. package/dist/media-upload-D2wk3EIt.mjs +145 -0
  528. package/dist/media-upload-D2wk3EIt.mjs.map +1 -0
  529. package/dist/{media-url-CKi5XSw4.mjs → media-url-BCm5vBn6.mjs} +1 -1
  530. package/dist/{media-url-CKi5XSw4.mjs.map → media-url-BCm5vBn6.mjs.map} +1 -1
  531. package/dist/media-usage-CljdO1mc.mjs +554 -0
  532. package/dist/media-usage-CljdO1mc.mjs.map +1 -0
  533. package/dist/{menus-b2T4clbO.mjs → menus-BcyElFtI.mjs} +177 -15
  534. package/dist/menus-BcyElFtI.mjs.map +1 -0
  535. package/dist/{menus-Cfivc2Ad.mjs → menus-CZyG6rvx.mjs} +3 -3
  536. package/dist/{menus-Cfivc2Ad.mjs.map → menus-CZyG6rvx.mjs.map} +1 -1
  537. package/dist/{mime-CCEzze7W.mjs → mime-DfIVjNkr.mjs} +1 -1
  538. package/dist/{mime-CCEzze7W.mjs.map → mime-DfIVjNkr.mjs.map} +1 -1
  539. package/dist/{mode-BM9QgEmt.mjs → mode-fiXRMfeA.mjs} +1 -1
  540. package/dist/{mode-BM9QgEmt.mjs.map → mode-fiXRMfeA.mjs.map} +1 -1
  541. package/dist/{normalize-CeglrBT9.mjs → normalize-C-SHXmra.mjs} +1 -1
  542. package/dist/{normalize-CeglrBT9.mjs.map → normalize-C-SHXmra.mjs.map} +1 -1
  543. package/dist/{oauth-authorization-CXWkIGT4.mjs → oauth-authorization-oqfbBuMH.mjs} +6 -7
  544. package/dist/oauth-authorization-oqfbBuMH.mjs.map +1 -0
  545. package/dist/{oauth-clients-BmTI5rsl.mjs → oauth-clients-BlrUHAsf.mjs} +1 -1
  546. package/dist/{oauth-clients-BmTI5rsl.mjs.map → oauth-clients-BlrUHAsf.mjs.map} +1 -1
  547. package/dist/{oauth-state-store-YLFLcH5F.mjs → oauth-state-store-DnvjRMy6.mjs} +2 -1
  548. package/dist/{oauth-state-store-YLFLcH5F.mjs.map → oauth-state-store-DnvjRMy6.mjs.map} +1 -1
  549. package/dist/{oauth-user-lookup-Bsc_GsX-.mjs → oauth-user-lookup-oUllxvAv.mjs} +1 -1
  550. package/dist/{oauth-user-lookup-Bsc_GsX-.mjs.map → oauth-user-lookup-oUllxvAv.mjs.map} +1 -1
  551. package/dist/object-cache/memory.d.mts +1 -1
  552. package/dist/{options-DTTML-Tx.mjs → options-BlmBHTvX.mjs} +1 -1
  553. package/dist/{options-DTTML-Tx.mjs.map → options-BlmBHTvX.mjs.map} +1 -1
  554. package/dist/{options-iMpRRxIe.d.mts → options-BqMkWfYa.d.mts} +6 -6
  555. package/dist/{options-iMpRRxIe.d.mts.map → options-BqMkWfYa.d.mts.map} +1 -1
  556. package/dist/page/index.d.mts +2 -2
  557. package/dist/page/index.d.mts.map +1 -1
  558. package/dist/page/index.mjs.map +1 -1
  559. package/dist/{parse-GmjecGct.mjs → parse-C_-6klII.mjs} +4 -12
  560. package/dist/{parse-GmjecGct.mjs.map → parse-C_-6klII.mjs.map} +1 -1
  561. package/dist/{passkey-config-De0ahnRg.mjs → passkey-config-C-SKpc0-.mjs} +1 -1
  562. package/dist/{passkey-config-De0ahnRg.mjs.map → passkey-config-C-SKpc0-.mjs.map} +1 -1
  563. package/dist/{patterns-BKmjvM7K.mjs → patterns-CiyXeDgr.mjs} +1 -1
  564. package/dist/{patterns-BKmjvM7K.mjs.map → patterns-CiyXeDgr.mjs.map} +1 -1
  565. package/dist/{placeholder-BSKwzRe4.d.mts → placeholder-Dop47JMM.d.mts} +1 -1
  566. package/dist/{placeholder-BSKwzRe4.d.mts.map → placeholder-Dop47JMM.d.mts.map} +1 -1
  567. package/dist/plugin-types.d.mts +21 -2
  568. package/dist/plugin-types.d.mts.map +1 -1
  569. package/dist/plugin-utils.d.mts +18 -16
  570. package/dist/plugin-utils.d.mts.map +1 -1
  571. package/dist/plugin-utils.mjs +8 -6
  572. package/dist/plugin-utils.mjs.map +1 -1
  573. package/dist/plugins/adapt-sandbox-entry.d.mts +10 -10
  574. package/dist/plugins/adapt-sandbox-entry.d.mts.map +1 -1
  575. package/dist/plugins/adapt-sandbox-entry.mjs +15 -3
  576. package/dist/plugins/adapt-sandbox-entry.mjs.map +1 -1
  577. package/dist/{portable-text-cCa0cGV6.mjs → portable-text-sDj92Kxv.mjs} +1 -1
  578. package/dist/{portable-text-cCa0cGV6.mjs.map → portable-text-sDj92Kxv.mjs.map} +1 -1
  579. package/dist/{preview-SSXNVPAC.mjs → preview-D4Jnbfx7.mjs} +2 -2
  580. package/dist/{preview-SSXNVPAC.mjs.map → preview-D4Jnbfx7.mjs.map} +1 -1
  581. package/dist/{public-url-Danv47cS.mjs → public-url-DSGTnJFw.mjs} +5 -3
  582. package/dist/public-url-DSGTnJFw.mjs.map +1 -0
  583. package/dist/{query-1Cp6U9oo.mjs → query-DR73ZNfm.mjs} +15 -15
  584. package/dist/query-DR73ZNfm.mjs.map +1 -0
  585. package/dist/{schema-CX9cfNkZ.mjs → query-Di7DOmPV.mjs} +5 -10
  586. package/dist/query-Di7DOmPV.mjs.map +1 -0
  587. package/dist/{rate-limit-C_Lf63Dd.mjs → rate-limit-CMj83JNW.mjs} +2 -2
  588. package/dist/{rate-limit-C_Lf63Dd.mjs.map → rate-limit-CMj83JNW.mjs.map} +1 -1
  589. package/dist/{redirect-CoW3G-0U.mjs → redirect-Botom7X6.mjs} +1 -1
  590. package/dist/{redirect-CoW3G-0U.mjs.map → redirect-Botom7X6.mjs.map} +1 -1
  591. package/dist/{redirect-IyfNirgS.mjs → redirect-CgLPYflR.mjs} +11 -5
  592. package/dist/redirect-CgLPYflR.mjs.map +1 -0
  593. package/dist/{redirects-Bs1g42Ri.mjs → redirects-B7t9bKsL.mjs} +6 -6
  594. package/dist/{redirects-Bs1g42Ri.mjs.map → redirects-B7t9bKsL.mjs.map} +1 -1
  595. package/dist/{redirects-DXEXBAII.mjs → redirects-BBq3n2Rj.mjs} +10 -143
  596. package/dist/redirects-BBq3n2Rj.mjs.map +1 -0
  597. package/dist/{registry-B57vp_X9.mjs → registry-FV15nLge.mjs} +99 -10
  598. package/dist/registry-FV15nLge.mjs.map +1 -0
  599. package/dist/relation-9M9j_UWo.mjs +334 -0
  600. package/dist/relation-9M9j_UWo.mjs.map +1 -0
  601. package/dist/{byline-fields-2Lp5Hbgf.mjs → relations-5_avdrN_.mjs} +60 -4
  602. package/dist/relations-5_avdrN_.mjs.map +1 -0
  603. package/dist/relations-BKvO39-9.mjs +397 -0
  604. package/dist/relations-BKvO39-9.mjs.map +1 -0
  605. package/dist/{byline-fields-CHE8UStY.d.mts → relations-Bh8jlFsU.d.mts} +486 -31
  606. package/dist/relations-Bh8jlFsU.d.mts.map +1 -0
  607. package/dist/{request-cache-KCNHp_RJ.mjs → request-cache-BSUptuJR.mjs} +1 -1
  608. package/dist/{request-cache-KCNHp_RJ.mjs.map → request-cache-BSUptuJR.mjs.map} +1 -1
  609. package/dist/{request-meta-DbvXaAvU.mjs → request-meta-DzXYYI-n.mjs} +2 -2
  610. package/dist/{request-meta-DbvXaAvU.mjs.map → request-meta-DzXYYI-n.mjs.map} +1 -1
  611. package/dist/{resolve-DR3wqMTy.mjs → resolve-Cd9dzclN.mjs} +1 -1
  612. package/dist/{resolve-DR3wqMTy.mjs.map → resolve-Cd9dzclN.mjs.map} +1 -1
  613. package/dist/{runner-DvFWoz8-.d.mts → runner-Dd8m8k9F.d.mts} +8 -2
  614. package/dist/runner-Dd8m8k9F.d.mts.map +1 -0
  615. package/dist/{runner-K8XK101B.mjs → runner-DfnZ5eUr.mjs} +355 -204
  616. package/dist/runner-DfnZ5eUr.mjs.map +1 -0
  617. package/dist/runtime.d.mts +11 -11
  618. package/dist/runtime.mjs +4 -4
  619. package/dist/schema-BXxlHeAf.mjs +9 -0
  620. package/dist/schema-BXxlHeAf.mjs.map +1 -0
  621. package/dist/scopes-Bl4IwHA-.mjs +27 -0
  622. package/dist/scopes-Bl4IwHA-.mjs.map +1 -0
  623. package/dist/{search-DZN2HZ-V.mjs → search-Bff-7jFt.mjs} +62 -12
  624. package/dist/search-Bff-7jFt.mjs.map +1 -0
  625. package/dist/{secrets-kp760LlD.mjs → secrets-CSwQIl4q.mjs} +4 -4
  626. package/dist/{secrets-kp760LlD.mjs.map → secrets-CSwQIl4q.mjs.map} +1 -1
  627. package/dist/{sections-CpF5SaGr.mjs → sections-CwW4s1al.mjs} +3 -3
  628. package/dist/{sections-CpF5SaGr.mjs.map → sections-CwW4s1al.mjs.map} +1 -1
  629. package/dist/seed/index.d.mts +2 -2
  630. package/dist/seed/index.mjs +23 -23
  631. package/dist/seo/index.d.mts +15 -2
  632. package/dist/seo/index.d.mts.map +1 -1
  633. package/dist/seo/index.mjs +22 -5
  634. package/dist/seo/index.mjs.map +1 -1
  635. package/dist/{seo-DXu2UQnC.mjs → seo-2cmFHZns.mjs} +2 -2
  636. package/dist/{seo-DXu2UQnC.mjs.map → seo-2cmFHZns.mjs.map} +1 -1
  637. package/dist/{seo-89-53DDs.mjs → seo-C3GDfT0V.mjs} +1 -1
  638. package/dist/{seo-89-53DDs.mjs.map → seo-C3GDfT0V.mjs.map} +1 -1
  639. package/dist/{service-DQmiBMzt.mjs → service-DkGTWGIi.mjs} +3 -3
  640. package/dist/{service-DQmiBMzt.mjs.map → service-DkGTWGIi.mjs.map} +1 -1
  641. package/dist/{session-user-Cascbax7.mjs → session-user-DbHqKDKe.mjs} +1 -1
  642. package/dist/{session-user-Cascbax7.mjs.map → session-user-DbHqKDKe.mjs.map} +1 -1
  643. package/dist/{settings-rZyHEcNT.mjs → settings-C4s8hFQm.mjs} +3 -3
  644. package/dist/{settings-rZyHEcNT.mjs.map → settings-C4s8hFQm.mjs.map} +1 -1
  645. package/dist/{settings-zhmdKyJQ.mjs → settings-CpA4lQFt.mjs} +6 -6
  646. package/dist/{settings-zhmdKyJQ.mjs.map → settings-CpA4lQFt.mjs.map} +1 -1
  647. package/dist/{setup-complete-Cb3LRyzy.mjs → setup-complete-CdIlqloh.mjs} +2 -2
  648. package/dist/{setup-complete-Cb3LRyzy.mjs.map → setup-complete-CdIlqloh.mjs.map} +1 -1
  649. package/dist/{setup-nonce-Z8x0tHf8.mjs → setup-nonce-DqiIPr-J.mjs} +1 -1
  650. package/dist/{setup-nonce-Z8x0tHf8.mjs.map → setup-nonce-DqiIPr-J.mjs.map} +1 -1
  651. package/dist/{single-flight-cache-BG3B_GhN.mjs → single-flight-cache-C2exrGAi.mjs} +2 -2
  652. package/dist/{single-flight-cache-BG3B_GhN.mjs.map → single-flight-cache-C2exrGAi.mjs.map} +1 -1
  653. package/dist/{site-url-BBfDTgZB.mjs → site-url-NGJT6NTU.mjs} +2 -2
  654. package/dist/{site-url-BBfDTgZB.mjs.map → site-url-NGJT6NTU.mjs.map} +1 -1
  655. package/dist/{slugify-Cce3dTdg.mjs → slugify-C_tqlU4G.mjs} +1 -1
  656. package/dist/{slugify-Cce3dTdg.mjs.map → slugify-C_tqlU4G.mjs.map} +1 -1
  657. package/dist/snapshot-BdpUJKD-.mjs +216 -0
  658. package/dist/snapshot-BdpUJKD-.mjs.map +1 -0
  659. package/dist/{ssrf-1g7usGBg.mjs → ssrf-CviKqWmq.mjs} +1 -1
  660. package/dist/{ssrf-1g7usGBg.mjs.map → ssrf-CviKqWmq.mjs.map} +1 -1
  661. package/dist/state-xxv6ZTMv.mjs +128 -0
  662. package/dist/state-xxv6ZTMv.mjs.map +1 -0
  663. package/dist/{status-CqJQX1QN.mjs → status-COfycGIU.mjs} +1 -1
  664. package/dist/{status-CqJQX1QN.mjs.map → status-COfycGIU.mjs.map} +1 -1
  665. package/dist/storage/local.d.mts +1 -1
  666. package/dist/storage/local.mjs +1 -1
  667. package/dist/storage/s3.d.mts +1 -1
  668. package/dist/storage/s3.mjs +1 -1
  669. package/dist/{taxonomies-Bs13SN-F.mjs → taxonomies-Ce49uIzY.mjs} +13 -9
  670. package/dist/taxonomies-Ce49uIzY.mjs.map +1 -0
  671. package/dist/{taxonomies-kH9ABDUF.mjs → taxonomies-DjSKBZpq.mjs} +115 -36
  672. package/dist/taxonomies-DjSKBZpq.mjs.map +1 -0
  673. package/dist/{taxonomy-BxGxZZdu.mjs → taxonomy-DfVooU4W.mjs} +60 -13
  674. package/dist/taxonomy-DfVooU4W.mjs.map +1 -0
  675. package/dist/{tokens-BGT0TUUo.mjs → tokens-DVltpO2D.mjs} +2 -2
  676. package/dist/{tokens-BGT0TUUo.mjs.map → tokens-DVltpO2D.mjs.map} +1 -1
  677. package/dist/{transaction-qfqpPVpu.mjs → transaction-D0FOsb3X.mjs} +1 -1
  678. package/dist/{transaction-qfqpPVpu.mjs.map → transaction-D0FOsb3X.mjs.map} +1 -1
  679. package/dist/{transport-DPefPMcz.mjs → transport-CKrlqSpD.mjs} +1 -1
  680. package/dist/{transport-DPefPMcz.mjs.map → transport-CKrlqSpD.mjs.map} +1 -1
  681. package/dist/{transport-BMDWHSgZ.d.mts → transport-Vd7VdqHv.d.mts} +1 -1
  682. package/dist/{transport-BMDWHSgZ.d.mts.map → transport-Vd7VdqHv.d.mts.map} +1 -1
  683. package/dist/{trusted-proxy-VTPRiX2s.mjs → trusted-proxy-CwjQj0YG.mjs} +1 -1
  684. package/dist/{trusted-proxy-VTPRiX2s.mjs.map → trusted-proxy-CwjQj0YG.mjs.map} +1 -1
  685. package/dist/{types-CgvhU-hF.d.mts → types-B4vm81VH.d.mts} +1 -1
  686. package/dist/{types-CgvhU-hF.d.mts.map → types-B4vm81VH.d.mts.map} +1 -1
  687. package/dist/{types-ea9sAPck.d.mts → types-B97jg3aW.d.mts} +6 -1
  688. package/dist/{types-ea9sAPck.d.mts.map → types-B97jg3aW.d.mts.map} +1 -1
  689. package/dist/{types-Jo3UYd6b.mjs → types-BD40g7zz.mjs} +1 -1
  690. package/dist/{types-Jo3UYd6b.mjs.map → types-BD40g7zz.mjs.map} +1 -1
  691. package/dist/{types-DmHk7vAt.d.mts → types-BNfPHfay.d.mts} +1 -1
  692. package/dist/{types-DmHk7vAt.d.mts.map → types-BNfPHfay.d.mts.map} +1 -1
  693. package/dist/{types-BcLUUbbR.d.mts → types-BfYUPJdP.d.mts} +11 -3
  694. package/dist/{types-BcLUUbbR.d.mts.map → types-BfYUPJdP.d.mts.map} +1 -1
  695. package/dist/{types-CGbYowGQ.d.mts → types-BvB7gDOD.d.mts} +90 -4
  696. package/dist/types-BvB7gDOD.d.mts.map +1 -0
  697. package/dist/{types-vgEWF18A.d.mts → types-C7U0HlEr.d.mts} +1 -1
  698. package/dist/{types-vgEWF18A.d.mts.map → types-C7U0HlEr.d.mts.map} +1 -1
  699. package/dist/{types-CuW0zWDA.mjs → types-D1iJ3DpO.mjs} +3 -3
  700. package/dist/{types-CuW0zWDA.mjs.map → types-D1iJ3DpO.mjs.map} +1 -1
  701. package/dist/{types-_HFLRzTn.d.mts → types-DPKhI5ib.d.mts} +9 -1
  702. package/dist/types-DPKhI5ib.d.mts.map +1 -0
  703. package/dist/{types-g_aFIdW0.d.mts → types-Kmaxdarz.d.mts} +1 -1
  704. package/dist/{types-g_aFIdW0.d.mts.map → types-Kmaxdarz.d.mts.map} +1 -1
  705. package/dist/{types-ClUkdbWb.d.mts → types-iVeZ5g6N.d.mts} +1 -1
  706. package/dist/{types-ClUkdbWb.d.mts.map → types-iVeZ5g6N.d.mts.map} +1 -1
  707. package/dist/{types-tM44hEcf.mjs → types-o7xo7VgH.mjs} +1 -1
  708. package/dist/{types-tM44hEcf.mjs.map → types-o7xo7VgH.mjs.map} +1 -1
  709. package/dist/{user-BjAOvU3Z.mjs → user-Bh-L1qo6.mjs} +3 -3
  710. package/dist/{user-BjAOvU3Z.mjs.map → user-Bh-L1qo6.mjs.map} +1 -1
  711. package/dist/{utils-BJXElxdw.mjs → utils-BbUgmeZG.mjs} +3 -3
  712. package/dist/{utils-BJXElxdw.mjs.map → utils-BbUgmeZG.mjs.map} +1 -1
  713. package/dist/{validate-Z1b86_3B.d.mts → validate-DULfgpJP.d.mts} +5 -5
  714. package/dist/{validate-Z1b86_3B.d.mts.map → validate-DULfgpJP.d.mts.map} +1 -1
  715. package/dist/{validate-CWSnKVIJ.mjs → validate-V9nCwq_-.mjs} +3 -3
  716. package/dist/{validate-CWSnKVIJ.mjs.map → validate-V9nCwq_-.mjs.map} +1 -1
  717. package/dist/{validation-0l8-RYj4.mjs → validation-BsVUJfsP.mjs} +10 -10
  718. package/dist/{validation-0l8-RYj4.mjs.map → validation-BsVUJfsP.mjs.map} +1 -1
  719. package/dist/version-907opKac.mjs +7 -0
  720. package/dist/{version-qmeO1XZY.mjs.map → version-907opKac.mjs.map} +1 -1
  721. package/dist/{widgets-hWcIicX8.mjs → widgets-DGv1Z04V.mjs} +4 -4
  722. package/dist/{widgets-hWcIicX8.mjs.map → widgets-DGv1Z04V.mjs.map} +1 -1
  723. package/dist/{wxr-taxonomies-0_uxSrmf.d.mts → wxr-taxonomies-B4tMuN5T.d.mts} +1 -1
  724. package/dist/{wxr-taxonomies-0_uxSrmf.d.mts.map → wxr-taxonomies-B4tMuN5T.d.mts.map} +1 -1
  725. package/dist/{wxr-taxonomies-CNFcsNCr.mjs → wxr-taxonomies-Cs1N6O8z.mjs} +4 -4
  726. package/dist/{wxr-taxonomies-CNFcsNCr.mjs.map → wxr-taxonomies-Cs1N6O8z.mjs.map} +1 -1
  727. package/dist/{zod-generator-CacrR-i8.mjs → zod-generator-B5prQ5M4.mjs} +3 -3
  728. package/dist/{zod-generator-CacrR-i8.mjs.map → zod-generator-B5prQ5M4.mjs.map} +1 -1
  729. package/package.json +12 -8
  730. package/src/api/authorize.ts +10 -1
  731. package/src/api/error.ts +5 -5
  732. package/src/api/errors.ts +25 -0
  733. package/src/api/handlers/backup.ts +312 -0
  734. package/src/api/handlers/content.ts +147 -3
  735. package/src/api/handlers/dashboard.ts +2 -0
  736. package/src/api/handlers/device-flow.ts +2 -3
  737. package/src/api/handlers/index.ts +22 -0
  738. package/src/api/handlers/marketplace.ts +38 -0
  739. package/src/api/handlers/media-upload.ts +210 -0
  740. package/src/api/handlers/media-usage.ts +289 -0
  741. package/src/api/handlers/oauth-authorization.ts +2 -6
  742. package/src/api/handlers/plugin-settings.ts +218 -0
  743. package/src/api/handlers/plugins.ts +41 -0
  744. package/src/api/handlers/registry.ts +39 -0
  745. package/src/api/handlers/relations.ts +474 -0
  746. package/src/api/handlers/snapshot.ts +21 -3
  747. package/src/api/handlers/taxonomies.ts +26 -4
  748. package/src/api/handlers/validate-media-fields.ts +1 -1
  749. package/src/api/openapi/document.ts +72 -5
  750. package/src/api/parse.ts +2 -16
  751. package/src/api/public-url.ts +4 -2
  752. package/src/api/schemas/comments.ts +6 -0
  753. package/src/api/schemas/common.ts +6 -2
  754. package/src/api/schemas/content.ts +8 -0
  755. package/src/api/schemas/index.ts +2 -0
  756. package/src/api/schemas/media-usage.ts +120 -0
  757. package/src/api/schemas/media.ts +32 -1
  758. package/src/api/schemas/relations.ts +109 -0
  759. package/src/api/schemas/search.ts +1 -0
  760. package/src/astro/integration/index.ts +39 -0
  761. package/src/astro/integration/routes.ts +40 -0
  762. package/src/astro/integration/runtime.ts +30 -0
  763. package/src/astro/integration/virtual-modules.ts +41 -7
  764. package/src/astro/integration/vite-config.ts +17 -1
  765. package/src/astro/middleware/auth.ts +70 -78
  766. package/src/astro/middleware/csp.ts +5 -2
  767. package/src/astro/middleware/request-context.ts +162 -20
  768. package/src/astro/middleware.ts +108 -40
  769. package/src/astro/public-plugin-api-routes.ts +2 -1
  770. package/src/astro/routes/PluginRegistry.tsx +5 -2
  771. package/src/astro/routes/admin.astro +56 -16
  772. package/src/astro/routes/api/admin/api-tokens/index.ts +2 -2
  773. package/src/astro/routes/api/admin/bylines/[id]/translations.ts +2 -5
  774. package/src/astro/routes/api/admin/comments/[id]/status.ts +1 -2
  775. package/src/astro/routes/api/admin/comments/index.ts +1 -2
  776. package/src/astro/routes/api/admin/media-usage/repair.ts +24 -0
  777. package/src/astro/routes/api/admin/plugins/[id]/index.ts +6 -0
  778. package/src/astro/routes/api/admin/plugins/[id]/mcp.ts +42 -0
  779. package/src/astro/routes/api/admin/plugins/[id]/settings.ts +80 -0
  780. package/src/astro/routes/api/admin/plugins/[id]/update.ts +2 -0
  781. package/src/astro/routes/api/admin/plugins/index.ts +9 -0
  782. package/src/astro/routes/api/admin/plugins/marketplace/[id]/install.ts +2 -0
  783. package/src/astro/routes/api/admin/plugins/registry/[id]/update.ts +2 -0
  784. package/src/astro/routes/api/admin/plugins/registry/install.ts +2 -0
  785. package/src/astro/routes/api/admin/plugins/updates.ts +2 -4
  786. package/src/astro/routes/api/auth/mode.ts +6 -14
  787. package/src/astro/routes/api/auth/oauth/[provider]/callback.ts +21 -5
  788. package/src/astro/routes/api/auth/oauth/[provider].ts +24 -7
  789. package/src/astro/routes/api/comments/[collection]/[contentId]/index.ts +13 -0
  790. package/src/astro/routes/api/content/[collection]/[id]/compare.ts +3 -4
  791. package/src/astro/routes/api/content/[collection]/[id]/duplicate.ts +2 -3
  792. package/src/astro/routes/api/content/[collection]/[id]/permanent.ts +2 -3
  793. package/src/astro/routes/api/content/[collection]/[id]/preview-url.ts +3 -4
  794. package/src/astro/routes/api/content/[collection]/[id]/references/[relation]/children.ts +95 -0
  795. package/src/astro/routes/api/content/[collection]/[id]/references/[relation]/parents.ts +47 -0
  796. package/src/astro/routes/api/content/[collection]/[id]/revisions.ts +3 -4
  797. package/src/astro/routes/api/content/[collection]/[id]/terms/[taxonomy].ts +4 -6
  798. package/src/astro/routes/api/content/[collection]/[id]/translations.ts +3 -4
  799. package/src/astro/routes/api/content/[collection]/[id].ts +3 -4
  800. package/src/astro/routes/api/content/[collection]/authors.ts +2 -3
  801. package/src/astro/routes/api/content/[collection]/index.ts +6 -8
  802. package/src/astro/routes/api/content/[collection]/trash.ts +2 -3
  803. package/src/astro/routes/api/manifest.ts +2 -9
  804. package/src/astro/routes/api/mcp.ts +2 -1
  805. package/src/astro/routes/api/media/[id]/usage.ts +30 -0
  806. package/src/astro/routes/api/media/[id].ts +17 -6
  807. package/src/astro/routes/api/media/file/[...key].ts +8 -0
  808. package/src/astro/routes/api/media.ts +21 -2
  809. package/src/astro/routes/api/oauth/authorize.ts +2 -6
  810. package/src/astro/routes/api/plugins/[pluginId]/[...path].ts +17 -3
  811. package/src/astro/routes/api/relations/[id]/index.ts +84 -0
  812. package/src/astro/routes/api/relations/[id]/translations.ts +33 -0
  813. package/src/astro/routes/api/relations/index.ts +56 -0
  814. package/src/astro/routes/api/schema/collections/[slug]/fields/[fieldSlug].ts +1 -7
  815. package/src/astro/routes/api/schema/collections/[slug]/fields/index.ts +1 -2
  816. package/src/astro/routes/api/search/index.ts +2 -0
  817. package/src/astro/routes/api/settings/backups/archives/[name].ts +78 -0
  818. package/src/astro/routes/api/settings/backups/archives/index.ts +33 -0
  819. package/src/astro/routes/api/settings/backups/export.ts +43 -0
  820. package/src/astro/routes/api/settings/backups/index.ts +76 -0
  821. package/src/astro/routes/api/setup/admin-verify.ts +8 -4
  822. package/src/astro/routes/api/setup/admin.ts +11 -4
  823. package/src/astro/routes/api/well-known/oauth-authorization-server.ts +4 -1
  824. package/src/astro/routes/api/well-known/oauth-protected-resource.ts +5 -1
  825. package/src/astro/types.ts +50 -2
  826. package/src/auth/api-tokens.ts +1 -0
  827. package/src/auth/oauth-state-store.ts +3 -0
  828. package/src/auth/providers/github-admin.tsx +5 -6
  829. package/src/auth/providers/google-admin.tsx +5 -6
  830. package/src/auth/scopes.ts +3 -9
  831. package/src/cli/client-factory.ts +0 -1
  832. package/src/cli/commands/bundle-utils.ts +50 -1
  833. package/src/cli/commands/bundle.ts +9 -2
  834. package/src/cli/commands/export-seed.ts +1 -10
  835. package/src/cli/commands/media.ts +127 -0
  836. package/src/client/index.ts +123 -2
  837. package/src/client/transport.ts +1 -1
  838. package/src/comments/service.ts +1 -1
  839. package/src/comments/turnstile.ts +64 -0
  840. package/src/components/BlockquoteGroup.astro +34 -0
  841. package/src/components/CommentForm.astro +12 -5
  842. package/src/components/EmDashHead.astro +31 -9
  843. package/src/components/InlinePortableTextEditor.tsx +88 -33
  844. package/src/components/PortableText.astro +7 -1
  845. package/src/components/index.ts +2 -0
  846. package/src/components/marks/Link.astro +5 -1
  847. package/src/components/portable-text-blockquote-group.ts +68 -0
  848. package/src/content/converters/portable-text-to-prosemirror.ts +32 -1
  849. package/src/database/dialect-helpers.ts +111 -3
  850. package/src/database/migrations/039_fix_fts5_triggers.ts +1 -1
  851. package/src/database/migrations/051_content_taxonomies_denorm.ts +120 -0
  852. package/src/database/migrations/052_media_usage_read_index.ts +26 -0
  853. package/src/database/migrations/053_plugin_mcp_tools.ts +21 -0
  854. package/src/database/migrations/runner.ts +52 -6
  855. package/src/database/pg-migration-lock.ts +72 -0
  856. package/src/database/repositories/audit.ts +2 -1
  857. package/src/database/repositories/comment.ts +1 -1
  858. package/src/database/repositories/content.ts +270 -37
  859. package/src/database/repositories/media-usage.ts +250 -1
  860. package/src/database/repositories/media.ts +1 -1
  861. package/src/database/repositories/plugin-storage.ts +29 -32
  862. package/src/database/repositories/redirect.ts +14 -2
  863. package/src/database/repositories/relation.ts +130 -5
  864. package/src/database/repositories/taxonomy.ts +66 -8
  865. package/src/database/repositories/types.ts +8 -0
  866. package/src/database/types.ts +23 -0
  867. package/src/db/adapters.ts +9 -0
  868. package/src/db/postgres.ts +5 -2
  869. package/src/emdash-runtime.ts +382 -70
  870. package/src/index.ts +6 -2
  871. package/src/loader.ts +293 -32
  872. package/src/mcp/server.ts +251 -8
  873. package/src/media/image-endpoint.ts +38 -2
  874. package/src/page/metadata.ts +27 -0
  875. package/src/plugin-types.ts +19 -0
  876. package/src/plugin-utils.ts +8 -6
  877. package/src/plugins/adapt-sandbox-entry.ts +30 -1
  878. package/src/plugins/context.ts +92 -0
  879. package/src/plugins/define-plugin.ts +17 -0
  880. package/src/plugins/index.ts +4 -0
  881. package/src/plugins/manifest-schema.ts +30 -1
  882. package/src/plugins/routes.ts +27 -1
  883. package/src/plugins/sandbox/runner-options.ts +16 -0
  884. package/src/plugins/sandbox/types.ts +6 -1
  885. package/src/plugins/state.ts +17 -1
  886. package/src/plugins/storage-query.ts +67 -33
  887. package/src/plugins/types.ts +100 -0
  888. package/src/schema/byline-registry.ts +1 -1
  889. package/src/schema/registry.ts +141 -5
  890. package/src/search/fts-manager.ts +34 -0
  891. package/src/search/match.ts +50 -0
  892. package/src/search/query.ts +94 -9
  893. package/src/seed/apply.ts +28 -29
  894. package/src/seo/hreflang.ts +192 -0
  895. package/src/seo/index.ts +22 -4
  896. package/src/storage/types.ts +6 -0
  897. package/src/taxonomies/index.ts +62 -45
  898. package/src/taxonomies/term-counts.ts +117 -0
  899. package/src/utils/base64.ts +7 -2
  900. package/src/utils/db-errors.ts +3 -1
  901. package/src/virtual-modules.d.ts +14 -0
  902. package/src/visual-editing/editable.ts +41 -35
  903. package/src/visual-editing/toolbar-bootstrap.ts +120 -0
  904. package/src/visual-editing/toolbar.ts +47 -1
  905. package/dist/adapters-hUy8vOB-.d.mts.map +0 -1
  906. package/dist/api-DxFSorgk.mjs.map +0 -1
  907. package/dist/api-tokens-DsvvCtdh.mjs +0 -3
  908. package/dist/apply-CDJqIjPU.mjs.map +0 -1
  909. package/dist/authorize-Dz88F_Fw.mjs.map +0 -1
  910. package/dist/base64-CmWvODNW.mjs.map +0 -1
  911. package/dist/byline-fields-2Lp5Hbgf.mjs.map +0 -1
  912. package/dist/byline-fields-CHE8UStY.d.mts.map +0 -1
  913. package/dist/content-DhgEth4k.mjs.map +0 -1
  914. package/dist/content-refresh-Br4gMzh8.mjs.map +0 -1
  915. package/dist/context-BRIpHARC.mjs.map +0 -1
  916. package/dist/dashboard-EvEKF5en.mjs.map +0 -1
  917. package/dist/db-errors-CK46D-ly.mjs.map +0 -1
  918. package/dist/device-flow-CfGP18Uw.mjs.map +0 -1
  919. package/dist/dialect-helpers-DRI5pyY3.mjs +0 -110
  920. package/dist/dialect-helpers-DRI5pyY3.mjs.map +0 -1
  921. package/dist/error-CkAseSqZ.mjs.map +0 -1
  922. package/dist/index-B9sIxwe4.d.mts.map +0 -1
  923. package/dist/loader-CB6YHeul.mjs.map +0 -1
  924. package/dist/manifest-schema-BHlgZM1W.mjs.map +0 -1
  925. package/dist/media-BrXIaMFN.mjs.map +0 -1
  926. package/dist/menus-b2T4clbO.mjs.map +0 -1
  927. package/dist/oauth-authorization-CXWkIGT4.mjs.map +0 -1
  928. package/dist/public-url-Danv47cS.mjs.map +0 -1
  929. package/dist/query-1Cp6U9oo.mjs.map +0 -1
  930. package/dist/redirect-IyfNirgS.mjs.map +0 -1
  931. package/dist/redirects-DXEXBAII.mjs.map +0 -1
  932. package/dist/registry-B57vp_X9.mjs.map +0 -1
  933. package/dist/runner-DvFWoz8-.d.mts.map +0 -1
  934. package/dist/runner-K8XK101B.mjs.map +0 -1
  935. package/dist/scheduled-publish-Drffrf2a.d.mts +0 -11
  936. package/dist/scheduled-publish-Drffrf2a.d.mts.map +0 -1
  937. package/dist/schema-CX9cfNkZ.mjs.map +0 -1
  938. package/dist/search-DZN2HZ-V.mjs.map +0 -1
  939. package/dist/taxonomies-Bs13SN-F.mjs.map +0 -1
  940. package/dist/taxonomies-kH9ABDUF.mjs.map +0 -1
  941. package/dist/taxonomy-BxGxZZdu.mjs.map +0 -1
  942. package/dist/types-CGbYowGQ.d.mts.map +0 -1
  943. package/dist/types-_HFLRzTn.d.mts.map +0 -1
  944. package/dist/version-qmeO1XZY.mjs +0 -7
  945. /package/dist/{ssrf-CmuGgCq3.mjs → ssrf-BB__xfNM.mjs} +0 -0
  946. /package/dist/{types-DROWRxYV.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 {
@@ -22,7 +24,12 @@ import { getAuthMode } from "./auth/mode.js";
22
24
  import { getTrustedProxyHeaders } from "./auth/trusted-proxy.js";
23
25
  import { isSqlite } from "./database/dialect-helpers.js";
24
26
  import { kyselyLogOption } from "./database/instrumentation.js";
25
- import { MIGRATION_RACE_WAIT_MS, runMigrations } from "./database/migrations/runner.js";
27
+ import {
28
+ ConcurrentMigrationTimeoutError,
29
+ MIGRATION_RACE_WAIT_MS,
30
+ runMigrations,
31
+ } from "./database/migrations/runner.js";
32
+ import { AuditRepository } from "./database/repositories/audit.js";
26
33
  import { RevisionRepository } from "./database/repositories/revision.js";
27
34
  import type {
28
35
  ContentItem as ContentItemInternal,
@@ -37,18 +44,25 @@ import {
37
44
  markContentMediaUsageCollectionStale,
38
45
  refreshContentMediaUsageAfterWrite,
39
46
  } from "./media/usage/content-refresh.js";
40
- import type { SandboxedPluginInstance, SandboxRunner } from "./plugins/sandbox/types.js";
47
+ import { createSandboxRunnerOptions } from "./plugins/sandbox/runner-options.js";
48
+ import type {
49
+ SandboxedPluginInstance,
50
+ SandboxRunner,
51
+ SandboxRunnerFactory,
52
+ } from "./plugins/sandbox/types.js";
41
53
  import type {
42
54
  ResolvedPlugin,
43
55
  MediaItem,
44
56
  PluginManifest,
45
57
  PluginCapability,
46
58
  PluginStorageConfig,
59
+ PluginMcpManifestConfig,
47
60
  PublicPageContext,
48
61
  PageMetadataContribution,
49
62
  PageFragmentContribution,
50
63
  PortableTextBlockConfig,
51
64
  FieldWidgetConfig,
65
+ SettingField,
52
66
  } from "./plugins/types.js";
53
67
  import type { FieldType } from "./schema/types.js";
54
68
  import { hashString } from "./utils/hash.js";
@@ -117,6 +131,7 @@ function isValidMetadataContribution(c: unknown): c is PageMetadataContribution
117
131
  }
118
132
 
119
133
  import { after } from "./after.js";
134
+ import { maybeRunScheduledBackup } from "./api/handlers/backup.js";
120
135
  import { loadBundleFromR2 } from "./api/handlers/marketplace.js";
121
136
  import { runSystemCleanup } from "./cleanup.js";
122
137
  import {
@@ -170,7 +185,7 @@ import {
170
185
  } from "./plugins/hooks.js";
171
186
  import { normalizeManifestRoute } from "./plugins/manifest-schema.js";
172
187
  import { extractRequestMeta, sanitizeHeadersForSandbox } from "./plugins/request-meta.js";
173
- import { PluginRouteRegistry, type RouteMeta } from "./plugins/routes.js";
188
+ import { buildRouteMeta, PluginRouteRegistry, type RouteMeta } from "./plugins/routes.js";
174
189
  import type { CronScheduler } from "./plugins/scheduler/types.js";
175
190
  import { PluginStateRepository } from "./plugins/state.js";
176
191
  import { normalizeRegistryConfig } from "./registry/config.js";
@@ -216,10 +231,14 @@ export interface SandboxedPluginEntry {
216
231
  allowedHosts: string[];
217
232
  /** Declared storage collections */
218
233
  storage: PluginStorageConfig;
234
+ /** Serialized MCP declarations emitted at plugin build time. */
235
+ mcp?: PluginMcpManifestConfig;
219
236
  /** Admin pages */
220
237
  adminPages?: Array<{ path: string; label?: string; icon?: string }>;
221
238
  /** Dashboard widgets */
222
239
  adminWidgets?: Array<{ id: string; title?: string; size?: string }>;
240
+ /** Settings schema for the auto-generated admin settings form */
241
+ settingsSchema?: Record<string, SettingField>;
223
242
  /** Portable Text block types contributed to the editor (declarative Block Kit) */
224
243
  portableTextBlocks?: PortableTextBlockConfig[];
225
244
  /** Field widget types contributed for schema-field editing UIs */
@@ -305,16 +324,8 @@ export interface RuntimeDependencies {
305
324
  /** Media provider entries from virtual module */
306
325
  mediaProviderEntries?: MediaProviderEntry[];
307
326
  sandboxedPluginEntries: SandboxedPluginEntry[];
308
- /** Factory function matching SandboxRunnerFactory signature */
309
- createSandboxRunner:
310
- | ((opts: {
311
- db: Kysely<Database>;
312
- mediaStorage?: {
313
- upload(options: { key: string; body: Uint8Array; contentType: string }): Promise<unknown>;
314
- delete(key: string): Promise<unknown>;
315
- };
316
- }) => SandboxRunner)
317
- | null;
327
+ /** Factory function supplied by the active platform adapter. */
328
+ createSandboxRunner: SandboxRunnerFactory | null;
318
329
  }
319
330
 
320
331
  /**
@@ -350,7 +361,12 @@ export interface EmDashRuntimeParts {
350
361
  db: Kysely<Database>;
351
362
  getDb?: () => Kysely<Database>;
352
363
  storage?: Storage;
353
- siteInfo?: { siteName?: string; siteUrl?: string; locale?: string };
364
+ siteInfo?: {
365
+ siteName?: string;
366
+ siteUrl?: string;
367
+ locale?: string;
368
+ trailingSlash?: "always" | "never" | "ignore";
369
+ };
354
370
  };
355
371
  runtimeDeps: RuntimeDependencies;
356
372
  pipelineRef: { current: HookPipeline };
@@ -385,18 +401,42 @@ const DB_HOLDER_KEY = Symbol.for("emdash:db-cache");
385
401
  interface DbHolder {
386
402
  cache: Map<string, Kysely<Database>>;
387
403
  lock: InitLock;
404
+ /**
405
+ * Recent migration failures, keyed like `cache`. A failed migration is
406
+ * near-certain to fail again immediately (schema conflict, broken
407
+ * migration), and without this every request in a warm isolate would
408
+ * re-attempt it — on Workers with Postgres that stampedes the database
409
+ * through the migration advisory lock (#1744). Entries expire after
410
+ * DB_INIT_FAILURE_BACKOFF_MS; a successful init clears them.
411
+ */
412
+ failures: Map<string, { at: number; message: string }>;
388
413
  }
389
414
  const globalSymbolStore = globalThis as Record<symbol, unknown>;
390
415
  function getDbHolder(): DbHolder {
391
416
  // eslint-disable-next-line typescript/no-unsafe-type-assertion -- globalThis symbol slot, written only below
392
417
  let holder = globalSymbolStore[DB_HOLDER_KEY] as DbHolder | undefined;
393
418
  if (!holder) {
394
- holder = { cache: new Map<string, Kysely<Database>>(), lock: createInitLock() };
419
+ holder = {
420
+ cache: new Map<string, Kysely<Database>>(),
421
+ lock: createInitLock(),
422
+ failures: new Map(),
423
+ };
395
424
  globalSymbolStore[DB_HOLDER_KEY] = holder;
396
425
  }
426
+ // A holder created by an older copy of this module (dev-server HMR keeps
427
+ // globalThis across reloads) may predate the failures map.
428
+ holder.failures ??= new Map();
397
429
  return holder;
398
430
  }
399
431
 
432
+ /**
433
+ * After a database init fails (migrations threw), skip re-attempting for
434
+ * this long. Cold isolates still get one attempt each, so a transient
435
+ * failure heals on its own; a persistently failing migration is retried at
436
+ * most once per backoff window per isolate instead of on every request.
437
+ */
438
+ const DB_INIT_FAILURE_BACKOFF_MS = 30_000;
439
+
400
440
  /**
401
441
  * Auto-seed runs at most once per isolate per database. Its lock + "done" set
402
442
  * live on globalThis (same bundler-duplication reasoning as the db cache) so a
@@ -441,7 +481,9 @@ const marketplaceManifestCache = new Map<
441
481
  admin?: {
442
482
  pages?: PluginAdminPage[];
443
483
  widgets?: PluginDashboardWidget[];
484
+ settingsSchema?: Record<string, SettingField>;
444
485
  };
486
+ mcp?: PluginMcpManifestConfig;
445
487
  }
446
488
  >();
447
489
  /** Route metadata for sandboxed plugins: pluginId -> routeName -> RouteMeta */
@@ -508,7 +550,12 @@ export class EmDashRuntime {
508
550
  db: Kysely<Database>;
509
551
  getDb?: () => Kysely<Database>;
510
552
  storage?: Storage;
511
- siteInfo?: { siteName?: string; siteUrl?: string; locale?: string };
553
+ siteInfo?: {
554
+ siteName?: string;
555
+ siteUrl?: string;
556
+ locale?: string;
557
+ trailingSlash?: "always" | "never" | "ignore";
558
+ };
512
559
  };
513
560
  /** Dependencies needed for exclusive hook resolution */
514
561
  private runtimeDeps: RuntimeDependencies;
@@ -628,6 +675,9 @@ export class EmDashRuntime {
628
675
  console.error("[cleanup] System cleanup failed:", error);
629
676
  }
630
677
 
678
+ // Never throws; no-op unless scheduled backups are enabled and due.
679
+ await maybeRunScheduledBackup(this.db, this.storage ?? undefined);
680
+
631
681
  return { published };
632
682
  }
633
683
 
@@ -686,12 +736,11 @@ export class EmDashRuntime {
686
736
  // pipelineFactoryOptions), so the merge only adds emailPipeline.
687
737
  newPipeline.setContextFactory({ emailPipeline: this.email });
688
738
  }
689
- if (this.cronScheduler) {
690
- const scheduler = this.cronScheduler;
691
- newPipeline.setContextFactory({
692
- cronReschedule: () => scheduler.reschedule(),
693
- });
694
- }
739
+ newPipeline.setContextFactory({
740
+ // Plugin schedules remain database-backed when no in-process scheduler
741
+ // exists; an external trigger is responsible for invoking due tasks.
742
+ cronReschedule: () => this.cronScheduler?.reschedule(),
743
+ });
695
744
 
696
745
  // Update the email pipeline to use the new hook pipeline
697
746
  if (this.email) {
@@ -838,6 +887,7 @@ export class EmDashRuntime {
838
887
  id: bundle.manifest.id,
839
888
  version: bundle.manifest.version,
840
889
  admin: bundle.manifest.admin,
890
+ mcp: bundle.manifest.mcp,
841
891
  });
842
892
 
843
893
  // Cache route metadata from manifest for auth decisions
@@ -845,7 +895,7 @@ export class EmDashRuntime {
845
895
  const routeMetaMap = new Map<string, RouteMeta>();
846
896
  for (const entry of bundle.manifest.routes) {
847
897
  const normalized = normalizeManifestRoute(entry);
848
- routeMetaMap.set(normalized.name, { public: normalized.public === true });
898
+ routeMetaMap.set(normalized.name, buildRouteMeta(normalized));
849
899
  }
850
900
  sandboxedRouteMetaCache.set(pluginId, routeMetaMap);
851
901
  } else {
@@ -952,12 +1002,13 @@ export class EmDashRuntime {
952
1002
  id: bundle.manifest.id,
953
1003
  version: bundle.manifest.version,
954
1004
  admin: bundle.manifest.admin,
1005
+ mcp: bundle.manifest.mcp,
955
1006
  });
956
1007
  if (bundle.manifest.routes.length > 0) {
957
1008
  const routeMetaMap = new Map<string, RouteMeta>();
958
1009
  for (const entry of bundle.manifest.routes) {
959
1010
  const normalized = normalizeManifestRoute(entry);
960
- routeMetaMap.set(normalized.name, { public: normalized.public === true });
1011
+ routeMetaMap.set(normalized.name, buildRouteMeta(normalized));
961
1012
  }
962
1013
  sandboxedRouteMetaCache.set(pluginId, routeMetaMap);
963
1014
  } else {
@@ -1001,6 +1052,7 @@ export class EmDashRuntime {
1001
1052
  size:
1002
1053
  w.size === "full" || w.size === "half" || w.size === "third" ? w.size : undefined,
1003
1054
  })),
1055
+ settingsSchema: bundle.manifest.admin?.settingsSchema,
1004
1056
  });
1005
1057
  newPlugins.push(adapted);
1006
1058
  this.allPipelinePlugins.push(adapted);
@@ -1078,7 +1130,14 @@ export class EmDashRuntime {
1078
1130
  const storage = EmDashRuntime.getStorage(deps);
1079
1131
 
1080
1132
  let pluginStates: Map<string, string> = new Map();
1081
- let siteInfo: { siteName?: string; siteUrl?: string; locale?: string } | undefined;
1133
+ let siteInfo:
1134
+ | {
1135
+ siteName?: string;
1136
+ siteUrl?: string;
1137
+ locale?: string;
1138
+ trailingSlash?: "always" | "never" | "ignore";
1139
+ }
1140
+ | undefined;
1082
1141
  // "Already set up" by default so a read failure (e.g. tables absent on a
1083
1142
  // pre-migration db) skips seeding rather than seeding a half-built db.
1084
1143
  let seedGate = { collectionCount: 1, setupDone: true };
@@ -1121,6 +1180,10 @@ export class EmDashRuntime {
1121
1180
  siteName: siteOpts.get("emdash:site_title") ?? undefined,
1122
1181
  siteUrl: siteOpts.get("emdash:site_url") ?? undefined,
1123
1182
  locale: siteOpts.get("emdash:locale") ?? undefined,
1183
+ // trailingSlash is a build-time Astro routing decision, not a
1184
+ // user-editable setting, so it comes from the Astro config
1185
+ // (virtual:emdash/config), not the options table.
1186
+ trailingSlash: virtualConfig?.trailingSlash,
1124
1187
  };
1125
1188
  };
1126
1189
 
@@ -1358,7 +1421,7 @@ export class EmDashRuntime {
1358
1421
 
1359
1422
  // Load sandboxed plugins (build-time, sandbox runner path)
1360
1423
  const sandboxedPlugins = await phase("rt.sandbox", "Sandboxed plugins", () =>
1361
- EmDashRuntime.loadSandboxedPlugins(deps, db, storage),
1424
+ EmDashRuntime.loadSandboxedPlugins(deps, db, storage, siteInfo),
1362
1425
  );
1363
1426
 
1364
1427
  // Cold-start: load marketplace- and registry-installed plugins from
@@ -1376,6 +1439,7 @@ export class EmDashRuntime {
1376
1439
  storage,
1377
1440
  deps,
1378
1441
  sandboxedPlugins,
1442
+ siteInfo,
1379
1443
  ),
1380
1444
  ),
1381
1445
  );
@@ -1391,6 +1455,7 @@ export class EmDashRuntime {
1391
1455
  storage,
1392
1456
  deps,
1393
1457
  sandboxedPlugins,
1458
+ siteInfo,
1394
1459
  ),
1395
1460
  ),
1396
1461
  );
@@ -1459,6 +1524,12 @@ export class EmDashRuntime {
1459
1524
  await phase("rt.cron", "Cron init (recovery deferred post-response)", async () => {
1460
1525
  try {
1461
1526
  cronExecutor = new CronExecutor(resolveDb, invokeCronHook);
1527
+ // Plugin schedules are always database-backed. On long-lived runtimes this
1528
+ // callback also wakes the timer; on Cloudflare the external Cron Trigger
1529
+ // drives execution, so rescheduling is intentionally a no-op.
1530
+ pipeline.setContextFactory({
1531
+ cronReschedule: () => cronScheduler?.reschedule(),
1532
+ });
1462
1533
 
1463
1534
  // Recover stale locks from previous crashes. Pure bookkeeping
1464
1535
  // against the _emdash_cron_tasks table — no request needs the
@@ -1513,11 +1584,8 @@ export class EmDashRuntime {
1513
1584
  // by runSystemCleanup. This catches unexpected errors.
1514
1585
  console.error("[cleanup] System cleanup failed:", error);
1515
1586
  }
1516
- });
1517
-
1518
- // Add cron reschedule callback (merges with existing factory options)
1519
- pipeline.setContextFactory({
1520
- cronReschedule: () => cronScheduler?.reschedule(),
1587
+ // Never throws; no-op unless scheduled backups are enabled and due.
1588
+ await maybeRunScheduledBackup(db, storage ?? undefined);
1521
1589
  });
1522
1590
 
1523
1591
  // start() is void on the timer scheduler but the interface
@@ -1623,14 +1691,52 @@ export class EmDashRuntime {
1623
1691
  // owner's init still completes and populates the cache. Net: a stale
1624
1692
  // lock is reclaimed after a deadline.
1625
1693
  const holder = getDbHolder();
1694
+
1695
+ const throwIfBackingOff = () => {
1696
+ const failure = holder.failures.get(cacheKey);
1697
+ if (!failure) return;
1698
+ if (Date.now() - failure.at < DB_INIT_FAILURE_BACKOFF_MS) {
1699
+ throw new Error(
1700
+ `Database initialization is backing off after a recent migration failure: ${failure.message}`,
1701
+ );
1702
+ }
1703
+ // Expired — drop it so the map only ever holds active backoffs.
1704
+ holder.failures.delete(cacheKey);
1705
+ };
1706
+ throwIfBackingOff();
1707
+
1626
1708
  return initWithLock(
1627
1709
  holder.lock,
1628
1710
  () => holder.cache.get(cacheKey),
1629
1711
  async (isCurrentClaim) => {
1712
+ // Re-check under the lock: a request that entered the wait loop
1713
+ // before the failure was recorded must not immediately re-run
1714
+ // the failing migration when the lock frees up.
1715
+ throwIfBackingOff();
1716
+
1630
1717
  const dialect = deps.createDialect(dbConfig.config);
1631
1718
  const db = new Kysely<Database>({ dialect, log: kyselyLogOption() });
1632
1719
 
1633
- await runMigrations(db);
1720
+ try {
1721
+ await runMigrations(db);
1722
+ } catch (error) {
1723
+ // Timing out behind another instance's in-flight migrations
1724
+ // is not a failure of OUR migration — the holder may just be
1725
+ // slow. Don't back off for it: the next request waits again
1726
+ // and init recovers the moment the holder finishes.
1727
+ if (!(error instanceof ConcurrentMigrationTimeoutError)) {
1728
+ holder.failures.set(cacheKey, {
1729
+ at: Date.now(),
1730
+ message: error instanceof Error ? error.message : String(error),
1731
+ });
1732
+ }
1733
+ // Every attempt builds a fresh dialect/pool; close it or each
1734
+ // failed init leaks its connection(s) (#1744 observed these
1735
+ // piling up as idle Postgres connections).
1736
+ await db.destroy().catch(() => {});
1737
+ throw error;
1738
+ }
1739
+ holder.failures.delete(cacheKey);
1634
1740
 
1635
1741
  // Note: legacy installs may carry a stray `emdash:manifest_cache`
1636
1742
  // row in the options table from versions that persisted a JSON
@@ -1739,6 +1845,7 @@ export class EmDashRuntime {
1739
1845
  storage: entry.storage as never,
1740
1846
  adminPages,
1741
1847
  adminWidgets,
1848
+ settingsSchema: entry.settingsSchema,
1742
1849
  portableTextBlocks: entry.portableTextBlocks,
1743
1850
  fieldWidgets: entry.fieldWidgets,
1744
1851
  });
@@ -1760,6 +1867,12 @@ export class EmDashRuntime {
1760
1867
  deps: RuntimeDependencies,
1761
1868
  db: Kysely<Database>,
1762
1869
  mediaStorage?: Storage | null,
1870
+ siteInfo?: {
1871
+ siteName?: string;
1872
+ siteUrl?: string;
1873
+ locale?: string;
1874
+ trailingSlash?: "always" | "never" | "ignore";
1875
+ },
1763
1876
  ): Promise<Map<string, SandboxedPluginInstance>> {
1764
1877
  // Return cached plugins if already loaded
1765
1878
  if (sandboxedPluginCache.size > 0) {
@@ -1773,20 +1886,25 @@ export class EmDashRuntime {
1773
1886
 
1774
1887
  // Create sandbox runner if not exists
1775
1888
  if (!sandboxRunner && deps.createSandboxRunner) {
1776
- sandboxRunner = deps.createSandboxRunner({
1777
- db,
1778
- mediaStorage: mediaStorage
1779
- ? {
1780
- upload: (opts) =>
1781
- mediaStorage.upload({
1782
- key: opts.key,
1783
- body: opts.body,
1784
- contentType: opts.contentType,
1785
- }),
1786
- delete: (key) => mediaStorage.delete(key),
1787
- }
1788
- : undefined,
1789
- });
1889
+ sandboxRunner = deps.createSandboxRunner(
1890
+ createSandboxRunnerOptions(
1891
+ {
1892
+ db,
1893
+ mediaStorage: mediaStorage
1894
+ ? {
1895
+ upload: (opts) =>
1896
+ mediaStorage.upload({
1897
+ key: opts.key,
1898
+ body: opts.body,
1899
+ contentType: opts.contentType,
1900
+ }),
1901
+ delete: (key) => mediaStorage.delete(key),
1902
+ }
1903
+ : undefined,
1904
+ },
1905
+ siteInfo,
1906
+ ),
1907
+ );
1790
1908
  }
1791
1909
 
1792
1910
  if (!sandboxRunner) {
@@ -1834,6 +1952,7 @@ export class EmDashRuntime {
1834
1952
  hooks: [],
1835
1953
  routes: [],
1836
1954
  admin: {},
1955
+ mcp: entry.mcp,
1837
1956
  };
1838
1957
 
1839
1958
  const plugin = await sandboxRunner.load(manifest, entry.code);
@@ -1869,22 +1988,33 @@ export class EmDashRuntime {
1869
1988
  storage: Storage,
1870
1989
  deps: RuntimeDependencies,
1871
1990
  cache: Map<string, SandboxedPluginInstance>,
1991
+ siteInfo?: {
1992
+ siteName?: string;
1993
+ siteUrl?: string;
1994
+ locale?: string;
1995
+ trailingSlash?: "always" | "never" | "ignore";
1996
+ },
1872
1997
  ): Promise<void> {
1873
1998
  // Ensure sandbox runner exists with media storage wired up.
1874
1999
  // (storage here is the media Storage adapter from the runtime.)
1875
2000
  if (!sandboxRunner && deps.createSandboxRunner) {
1876
- sandboxRunner = deps.createSandboxRunner({
1877
- db,
1878
- mediaStorage: {
1879
- upload: (opts) =>
1880
- storage.upload({
1881
- key: opts.key,
1882
- body: opts.body,
1883
- contentType: opts.contentType,
1884
- }),
1885
- delete: (key) => storage.delete(key),
1886
- },
1887
- });
2001
+ sandboxRunner = deps.createSandboxRunner(
2002
+ createSandboxRunnerOptions(
2003
+ {
2004
+ db,
2005
+ mediaStorage: {
2006
+ upload: (opts) =>
2007
+ storage.upload({
2008
+ key: opts.key,
2009
+ body: opts.body,
2010
+ contentType: opts.contentType,
2011
+ }),
2012
+ delete: (key) => storage.delete(key),
2013
+ },
2014
+ },
2015
+ siteInfo,
2016
+ ),
2017
+ );
1888
2018
  }
1889
2019
  // In sandbox bypass mode, marketplace plugins are loaded in-process
1890
2020
  // BEFORE pipeline creation by EmDashRuntime.create(). Skip here.
@@ -1931,6 +2061,7 @@ export class EmDashRuntime {
1931
2061
  id: bundle.manifest.id,
1932
2062
  version: bundle.manifest.version,
1933
2063
  admin: bundle.manifest.admin,
2064
+ mcp: bundle.manifest.mcp,
1934
2065
  });
1935
2066
 
1936
2067
  // Cache route metadata from manifest for auth decisions
@@ -1938,7 +2069,7 @@ export class EmDashRuntime {
1938
2069
  const routeMeta = new Map<string, RouteMeta>();
1939
2070
  for (const entry of bundle.manifest.routes) {
1940
2071
  const normalized = normalizeManifestRoute(entry);
1941
- routeMeta.set(normalized.name, { public: normalized.public === true });
2072
+ routeMeta.set(normalized.name, buildRouteMeta(normalized));
1942
2073
  }
1943
2074
  sandboxedRouteMetaCache.set(plugin.pluginId, routeMeta);
1944
2075
  }
@@ -2002,12 +2133,13 @@ export class EmDashRuntime {
2002
2133
  id: bundle.manifest.id,
2003
2134
  version: bundle.manifest.version,
2004
2135
  admin: bundle.manifest.admin,
2136
+ mcp: bundle.manifest.mcp,
2005
2137
  });
2006
2138
  if (bundle.manifest.routes.length > 0) {
2007
2139
  const routeMeta = new Map<string, RouteMeta>();
2008
2140
  for (const entry of bundle.manifest.routes) {
2009
2141
  const normalized = normalizeManifestRoute(entry);
2010
- routeMeta.set(normalized.name, { public: normalized.public === true });
2142
+ routeMeta.set(normalized.name, buildRouteMeta(normalized));
2011
2143
  }
2012
2144
  sandboxedRouteMetaCache.set(plugin.pluginId, routeMeta);
2013
2145
  }
@@ -2037,6 +2169,7 @@ export class EmDashRuntime {
2037
2169
  size:
2038
2170
  w.size === "full" || w.size === "half" || w.size === "third" ? w.size : undefined,
2039
2171
  })),
2172
+ settingsSchema: bundle.manifest.admin?.settingsSchema,
2040
2173
  });
2041
2174
  resolved.push(adapted);
2042
2175
  console.log(
@@ -2520,7 +2653,7 @@ export class EmDashRuntime {
2520
2653
  ...r.data,
2521
2654
  item: { ...item, data: mergedData, liveData },
2522
2655
  },
2523
- } as T;
2656
+ };
2524
2657
  } catch (error) {
2525
2658
  // Non-fatal — fall back to the unhydrated response. Log so the
2526
2659
  // failure isn't completely silent (the response will look stale
@@ -2540,6 +2673,7 @@ export class EmDashRuntime {
2540
2673
  bylines?: Array<{ bylineId: string; roleLabel?: string | null }>;
2541
2674
  locale?: string;
2542
2675
  translationOf?: string;
2676
+ taxonomies?: Record<string, string[]>;
2543
2677
  },
2544
2678
  ) {
2545
2679
  // Run beforeSave hooks (trusted plugins)
@@ -2604,6 +2738,7 @@ export class EmDashRuntime {
2604
2738
  canonical?: string | null;
2605
2739
  noIndex?: boolean;
2606
2740
  };
2741
+ taxonomies?: Record<string, string[]>;
2607
2742
  publishedAt?: string | null;
2608
2743
  locale?: string;
2609
2744
  /** Skip revision creation (used by autosave) */
@@ -2713,13 +2848,14 @@ export class EmDashRuntime {
2713
2848
  authorId: bodyWithoutRev.authorId ?? undefined,
2714
2849
  });
2715
2850
 
2716
- // Update entry to point to new draft (metadata only, not data columns)
2851
+ // Update entry to point to new draft (metadata only, not data columns).
2852
+ // No updated_at stamp: draft staging leaves live content untouched,
2853
+ // so public "last modified" consumers must not see a change (#2143).
2717
2854
  validateIdentifier(collection, "collection");
2718
2855
  const tableName = `ec_${collection}`;
2719
2856
  await sql`
2720
2857
  UPDATE ${sql.ref(tableName)}
2721
- SET draft_revision_id = ${revision.id},
2722
- updated_at = ${new Date().toISOString()}
2858
+ SET draft_revision_id = ${revision.id}
2723
2859
  WHERE id = ${resolvedId}
2724
2860
  `.execute(this.db);
2725
2861
  draftStorageChanged = true;
@@ -3111,7 +3247,10 @@ export class EmDashRuntime {
3111
3247
 
3112
3248
  // Revision-capable collections: restore is "make this revision the
3113
3249
  // current draft". The live row's data columns are left untouched
3114
- // (only `draft_revision_id` and `updated_at` change). The caller
3250
+ // (only `draft_revision_id` changes — no `updated_at` stamp, since
3251
+ // restoring to draft is the same kind of draft-only staging as
3252
+ // Save/Autosave and must not register a phantom modification for
3253
+ // sitemap <lastmod> / JSON-LD dateModified, #2143). The caller
3115
3254
  // must then `content_publish` to promote the restored draft to
3116
3255
  // live, matching the documented tool contract.
3117
3256
  try {
@@ -3126,8 +3265,7 @@ export class EmDashRuntime {
3126
3265
  const tableName = `ec_${revision.collection}`;
3127
3266
  await sql`
3128
3267
  UPDATE ${sql.ref(tableName)}
3129
- SET draft_revision_id = ${newDraft.id},
3130
- updated_at = ${new Date().toISOString()}
3268
+ SET draft_revision_id = ${newDraft.id}
3131
3269
  WHERE id = ${revision.entryId}
3132
3270
  `.execute(this.db);
3133
3271
 
@@ -3212,7 +3350,7 @@ export class EmDashRuntime {
3212
3350
  if (trustedPlugin) {
3213
3351
  const route = trustedPlugin.routes[routeKey];
3214
3352
  if (!route) return null;
3215
- return { public: route.public === true };
3353
+ return buildRouteMeta(route);
3216
3354
  }
3217
3355
 
3218
3356
  // Check sandboxed plugin route metadata cache
@@ -3246,6 +3384,18 @@ export class EmDashRuntime {
3246
3384
  return null;
3247
3385
  }
3248
3386
 
3387
+ /**
3388
+ * Resolve the settings schema for a runtime-installed (marketplace or
3389
+ * registry) plugin from its cached manifest. Returns `{}` for a known
3390
+ * plugin without a schema and `null` for unknown plugins, matching the
3391
+ * contract of `getPluginSettingsSchema` for build-time plugins.
3392
+ */
3393
+ getRuntimePluginSettingsSchema(pluginId: string): Record<string, SettingField> | null {
3394
+ const meta = marketplaceManifestCache.get(pluginId);
3395
+ if (!meta) return null;
3396
+ return meta.admin?.settingsSchema ?? {};
3397
+ }
3398
+
3249
3399
  async handlePluginApiRoute(pluginId: string, _method: string, path: string, request: Request) {
3250
3400
  if (!this.isPluginEnabled(pluginId)) {
3251
3401
  return {
@@ -3259,9 +3409,9 @@ export class EmDashRuntime {
3259
3409
  const trustedPlugin = this.configuredPlugins.find((p) => p.id === pluginId);
3260
3410
  if (trustedPlugin && this.enabledPlugins.has(trustedPlugin.id)) {
3261
3411
  const routeRegistry = new PluginRouteRegistry({
3262
- db: this.db,
3263
- storage: this.storage ?? undefined,
3412
+ ...this.pipelineFactoryOptions,
3264
3413
  emailPipeline: this.email ?? undefined,
3414
+ cronReschedule: () => this.cronScheduler?.reschedule(),
3265
3415
  trustedProxyHeaders: getTrustedProxyHeaders(this.config),
3266
3416
  });
3267
3417
  routeRegistry.register(trustedPlugin);
@@ -3290,6 +3440,168 @@ export class EmDashRuntime {
3290
3440
  };
3291
3441
  }
3292
3442
 
3443
+ async getPluginMcpTools(pluginId?: string) {
3444
+ const tools: Array<{
3445
+ pluginId: string;
3446
+ name: string;
3447
+ description: string;
3448
+ route: string;
3449
+ permission: string;
3450
+ destructive: boolean;
3451
+ inputSchema: z.ZodType;
3452
+ outputSchema?: z.ZodType;
3453
+ }> = [];
3454
+ const seen = new Set<string>();
3455
+
3456
+ for (const plugin of this.configuredPlugins) {
3457
+ if (pluginId && plugin.id !== pluginId) continue;
3458
+ for (const [name, tool] of Object.entries(plugin.mcp?.tools ?? {})) {
3459
+ const route = plugin.routes[tool.route];
3460
+ if (!route || route.public || !route.permission || !(route.permission in Permissions))
3461
+ continue;
3462
+ const key = `${plugin.id}__${name}`;
3463
+ if (seen.has(key)) continue;
3464
+ seen.add(key);
3465
+ tools.push({
3466
+ pluginId: plugin.id,
3467
+ name,
3468
+ description: tool.description,
3469
+ route: tool.route,
3470
+ permission: route.permission,
3471
+ destructive: tool.destructive ?? false,
3472
+ inputSchema: tool.input,
3473
+ outputSchema: tool.output,
3474
+ });
3475
+ }
3476
+ }
3477
+
3478
+ const addManifestTools = (id: string, mcp: PluginMcpManifestConfig | undefined) => {
3479
+ if (pluginId && id !== pluginId) return;
3480
+ for (const tool of mcp?.tools ?? []) {
3481
+ const key = `${id}__${tool.name}`;
3482
+ const routeMeta = this.getPluginRouteMeta(id, tool.route);
3483
+ if (
3484
+ seen.has(key) ||
3485
+ !routeMeta ||
3486
+ routeMeta.public ||
3487
+ routeMeta.permission !== tool.permission ||
3488
+ !(tool.permission in Permissions)
3489
+ ) {
3490
+ continue;
3491
+ }
3492
+ seen.add(key);
3493
+ tools.push({
3494
+ pluginId: id,
3495
+ name: tool.name,
3496
+ description: tool.description,
3497
+ route: tool.route,
3498
+ permission: tool.permission,
3499
+ destructive: tool.destructive,
3500
+ inputSchema: z.fromJSONSchema({ ...tool.inputSchema }),
3501
+ outputSchema: tool.outputSchema ? z.fromJSONSchema({ ...tool.outputSchema }) : undefined,
3502
+ });
3503
+ }
3504
+ };
3505
+
3506
+ for (const entry of this.sandboxedPluginEntries) addManifestTools(entry.id, entry.mcp);
3507
+ for (const [id, manifest] of marketplaceManifestCache) addManifestTools(id, manifest.mcp);
3508
+
3509
+ return tools;
3510
+ }
3511
+
3512
+ async getEnabledPluginMcpTools() {
3513
+ const [tools, states] = await Promise.all([
3514
+ this.getPluginMcpTools(),
3515
+ new PluginStateRepository(this.db).getAll(),
3516
+ ]);
3517
+ const stateByPlugin = new Map(states.map((state) => [state.pluginId, state]));
3518
+ return tools.filter((tool) => {
3519
+ const state = stateByPlugin.get(tool.pluginId);
3520
+ if (
3521
+ !state?.mcpToolsEnabled ||
3522
+ state.status !== "active" ||
3523
+ !this.isPluginEnabled(tool.pluginId)
3524
+ ) {
3525
+ return false;
3526
+ }
3527
+ const consented = state.mcpToolsConsent;
3528
+ return consented === this.serializePluginMcpConsent(tools, tool.pluginId);
3529
+ });
3530
+ }
3531
+
3532
+ serializePluginMcpConsent(
3533
+ tools: Awaited<ReturnType<EmDashRuntime["getPluginMcpTools"]>>,
3534
+ pluginId: string,
3535
+ ): string {
3536
+ return JSON.stringify(
3537
+ tools
3538
+ .filter((tool) => tool.pluginId === pluginId)
3539
+ .map((tool) => ({
3540
+ name: tool.name,
3541
+ description: tool.description,
3542
+ route: tool.route,
3543
+ permission: tool.permission,
3544
+ destructive: tool.destructive,
3545
+ inputSchema: z.toJSONSchema(tool.inputSchema, { target: "draft-7" }),
3546
+ ...(tool.outputSchema
3547
+ ? { outputSchema: z.toJSONSchema(tool.outputSchema, { target: "draft-7" }) }
3548
+ : {}),
3549
+ }))
3550
+ .toSorted((a, b) => a.name.localeCompare(b.name)),
3551
+ );
3552
+ }
3553
+
3554
+ async handlePluginMcpTool(
3555
+ pluginId: string,
3556
+ toolName: string,
3557
+ route: string,
3558
+ input: unknown,
3559
+ actorId: string,
3560
+ request: Request,
3561
+ ) {
3562
+ const requestMeta = extractRequestMeta(request, getTrustedProxyHeaders(this.config));
3563
+ const audit = new AuditRepository(this.db);
3564
+ const headers = new Headers(request.headers);
3565
+ headers.delete("content-length");
3566
+ headers.delete("content-encoding");
3567
+ const internalRequest = new Request(request.url, {
3568
+ method: "POST",
3569
+ headers,
3570
+ body: JSON.stringify(input),
3571
+ });
3572
+ const result = await this.handlePluginApiRoute(pluginId, "POST", route, internalRequest);
3573
+ await audit.log({
3574
+ actorId,
3575
+ actorIp: requestMeta.ip ?? undefined,
3576
+ action: "plugin_tool_invoke",
3577
+ resourceType: "plugin_mcp_tool",
3578
+ resourceId: `${pluginId}__${toolName}`,
3579
+ details: { pluginId, tool: toolName, route },
3580
+ status: result.success ? "success" : "failure",
3581
+ });
3582
+ return result;
3583
+ }
3584
+
3585
+ async handlePluginMcpDenied(
3586
+ pluginId: string,
3587
+ toolName: string,
3588
+ route: string,
3589
+ actorId: string,
3590
+ request: Request,
3591
+ reason: string,
3592
+ ): Promise<void> {
3593
+ const requestMeta = extractRequestMeta(request, getTrustedProxyHeaders(this.config));
3594
+ await new AuditRepository(this.db).log({
3595
+ actorId,
3596
+ actorIp: requestMeta.ip ?? undefined,
3597
+ action: "plugin_tool_invoke",
3598
+ resourceType: "plugin_mcp_tool",
3599
+ resourceId: `${pluginId}__${toolName}`,
3600
+ details: { pluginId, tool: toolName, route, reason },
3601
+ status: "denied",
3602
+ });
3603
+ }
3604
+
3293
3605
  // =========================================================================
3294
3606
  // Sandboxed Plugin Helpers
3295
3607
  // =========================================================================