emdash 0.29.0 → 0.31.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (876) hide show
  1. package/dist/{adapters-DPAkL6QF.d.mts → adapters-C0ONzkUP.d.mts} +10 -1
  2. package/dist/adapters-C0ONzkUP.d.mts.map +1 -0
  3. package/dist/{allowed-origins-FXB-FplB.mjs → allowed-origins-CCEi9bPI.mjs} +2 -2
  4. package/dist/{allowed-origins-FXB-FplB.mjs.map → allowed-origins-CCEi9bPI.mjs.map} +1 -1
  5. package/dist/api/route-utils.d.mts +3 -3
  6. package/dist/api/route-utils.d.mts.map +1 -1
  7. package/dist/api/route-utils.mjs +19 -19
  8. package/dist/api/schemas/index.d.mts +2 -2
  9. package/dist/api/schemas/index.mjs +5 -4
  10. package/dist/{api-DVbHNApo.mjs → api-EibxGP-V.mjs} +260 -160
  11. package/dist/api-EibxGP-V.mjs.map +1 -0
  12. package/dist/api-tokens-Cvmixds7.mjs +3 -0
  13. package/dist/{api-tokens-UYBkl17d.mjs → api-tokens-uPt8UDpx.mjs} +2 -2
  14. package/dist/{api-tokens-UYBkl17d.mjs.map → api-tokens-uPt8UDpx.mjs.map} +1 -1
  15. package/dist/{apply-D23iUV4q.mjs → apply-fGHCAwWN.mjs} +42 -44
  16. package/dist/apply-fGHCAwWN.mjs.map +1 -0
  17. package/dist/astro/index.d.mts +12 -13
  18. package/dist/astro/index.d.mts.map +1 -1
  19. package/dist/astro/index.mjs +90 -11
  20. package/dist/astro/index.mjs.map +1 -1
  21. package/dist/astro/middleware/auth.d.mts +10 -11
  22. package/dist/astro/middleware/auth.d.mts.map +1 -1
  23. package/dist/astro/middleware/auth.mjs +56 -107
  24. package/dist/astro/middleware/auth.mjs.map +1 -1
  25. package/dist/astro/middleware/redirect.mjs +7 -7
  26. package/dist/astro/middleware/request-context.mjs +4 -4
  27. package/dist/astro/middleware/request-context.mjs.map +1 -1
  28. package/dist/astro/middleware/setup.mjs +1 -1
  29. package/dist/astro/middleware.d.mts +47 -3
  30. package/dist/astro/middleware.d.mts.map +1 -1
  31. package/dist/astro/middleware.mjs +410 -123
  32. package/dist/astro/middleware.mjs.map +1 -1
  33. package/dist/astro/routes/PluginRegistry.d.mts +5 -1
  34. package/dist/astro/routes/PluginRegistry.d.mts.map +1 -1
  35. package/dist/astro/routes/PluginRegistry.mjs +2 -1
  36. package/dist/astro/routes/PluginRegistry.mjs.map +1 -1
  37. package/dist/astro/routes/api/admin/allowed-domains/_domain_.mjs +9 -8
  38. package/dist/astro/routes/api/admin/allowed-domains/_domain_.mjs.map +1 -1
  39. package/dist/astro/routes/api/admin/allowed-domains/index.mjs +9 -8
  40. package/dist/astro/routes/api/admin/allowed-domains/index.mjs.map +1 -1
  41. package/dist/astro/routes/api/admin/api-tokens/_id_.mjs +5 -5
  42. package/dist/astro/routes/api/admin/api-tokens/index.mjs +7 -7
  43. package/dist/astro/routes/api/admin/api-tokens/index.mjs.map +1 -1
  44. package/dist/astro/routes/api/admin/byline-fields/_slug_/usage.mjs +5 -5
  45. package/dist/astro/routes/api/admin/byline-fields/_slug_.mjs +10 -9
  46. package/dist/astro/routes/api/admin/byline-fields/_slug_.mjs.map +1 -1
  47. package/dist/astro/routes/api/admin/byline-fields/index.mjs +10 -9
  48. package/dist/astro/routes/api/admin/byline-fields/index.mjs.map +1 -1
  49. package/dist/astro/routes/api/admin/byline-fields/reorder.mjs +10 -9
  50. package/dist/astro/routes/api/admin/byline-fields/reorder.mjs.map +1 -1
  51. package/dist/astro/routes/api/admin/bylines/_id_/index.mjs +16 -15
  52. package/dist/astro/routes/api/admin/bylines/_id_/index.mjs.map +1 -1
  53. package/dist/astro/routes/api/admin/bylines/_id_/translations.mjs +17 -22
  54. package/dist/astro/routes/api/admin/bylines/_id_/translations.mjs.map +1 -1
  55. package/dist/astro/routes/api/admin/bylines/index.d.mts.map +1 -1
  56. package/dist/astro/routes/api/admin/bylines/index.mjs +20 -18
  57. package/dist/astro/routes/api/admin/bylines/index.mjs.map +1 -1
  58. package/dist/astro/routes/api/admin/comments/_id_/status.mjs +13 -12
  59. package/dist/astro/routes/api/admin/comments/_id_/status.mjs.map +1 -1
  60. package/dist/astro/routes/api/admin/comments/_id_.mjs +6 -6
  61. package/dist/astro/routes/api/admin/comments/bulk.mjs +11 -10
  62. package/dist/astro/routes/api/admin/comments/bulk.mjs.map +1 -1
  63. package/dist/astro/routes/api/admin/comments/counts.mjs +6 -6
  64. package/dist/astro/routes/api/admin/comments/index.mjs +11 -10
  65. package/dist/astro/routes/api/admin/comments/index.mjs.map +1 -1
  66. package/dist/astro/routes/api/admin/hooks/exclusive/_hookName_.mjs +5 -5
  67. package/dist/astro/routes/api/admin/hooks/exclusive/index.mjs +4 -4
  68. package/dist/astro/routes/api/admin/media-usage/repair.mjs +12 -10
  69. package/dist/astro/routes/api/admin/media-usage/repair.mjs.map +1 -1
  70. package/dist/astro/routes/api/admin/oauth-clients/_id_.mjs +5 -5
  71. package/dist/astro/routes/api/admin/oauth-clients/index.mjs +5 -5
  72. package/dist/astro/routes/api/admin/plugins/_id_/disable.mjs +41 -40
  73. package/dist/astro/routes/api/admin/plugins/_id_/disable.mjs.map +1 -1
  74. package/dist/astro/routes/api/admin/plugins/_id_/enable.mjs +41 -40
  75. package/dist/astro/routes/api/admin/plugins/_id_/enable.mjs.map +1 -1
  76. package/dist/astro/routes/api/admin/plugins/_id_/index.mjs +46 -40
  77. package/dist/astro/routes/api/admin/plugins/_id_/index.mjs.map +1 -1
  78. package/dist/astro/routes/api/admin/plugins/_id_/mcp.d.mts +8 -0
  79. package/dist/astro/routes/api/admin/plugins/_id_/mcp.d.mts.map +1 -0
  80. package/dist/astro/routes/api/admin/plugins/_id_/mcp.mjs +39 -0
  81. package/dist/astro/routes/api/admin/plugins/_id_/mcp.mjs.map +1 -0
  82. package/dist/astro/routes/api/admin/plugins/_id_/settings.d.mts +9 -0
  83. package/dist/astro/routes/api/admin/plugins/_id_/settings.d.mts.map +1 -0
  84. package/dist/astro/routes/api/admin/plugins/_id_/settings.mjs +78 -0
  85. package/dist/astro/routes/api/admin/plugins/_id_/settings.mjs.map +1 -0
  86. package/dist/astro/routes/api/admin/plugins/_id_/uninstall.mjs +40 -39
  87. package/dist/astro/routes/api/admin/plugins/_id_/uninstall.mjs.map +1 -1
  88. package/dist/astro/routes/api/admin/plugins/_id_/update.d.mts.map +1 -1
  89. package/dist/astro/routes/api/admin/plugins/_id_/update.mjs +43 -40
  90. package/dist/astro/routes/api/admin/plugins/_id_/update.mjs.map +1 -1
  91. package/dist/astro/routes/api/admin/plugins/index.mjs +46 -40
  92. package/dist/astro/routes/api/admin/plugins/index.mjs.map +1 -1
  93. package/dist/astro/routes/api/admin/plugins/marketplace/_id_/icon.mjs +4 -4
  94. package/dist/astro/routes/api/admin/plugins/marketplace/_id_/index.mjs +40 -39
  95. package/dist/astro/routes/api/admin/plugins/marketplace/_id_/index.mjs.map +1 -1
  96. package/dist/astro/routes/api/admin/plugins/marketplace/_id_/install.d.mts.map +1 -1
  97. package/dist/astro/routes/api/admin/plugins/marketplace/_id_/install.mjs +46 -41
  98. package/dist/astro/routes/api/admin/plugins/marketplace/_id_/install.mjs.map +1 -1
  99. package/dist/astro/routes/api/admin/plugins/marketplace/index.mjs +40 -39
  100. package/dist/astro/routes/api/admin/plugins/marketplace/index.mjs.map +1 -1
  101. package/dist/astro/routes/api/admin/plugins/registry/_id_/uninstall.mjs +40 -39
  102. package/dist/astro/routes/api/admin/plugins/registry/_id_/uninstall.mjs.map +1 -1
  103. package/dist/astro/routes/api/admin/plugins/registry/_id_/update.d.mts.map +1 -1
  104. package/dist/astro/routes/api/admin/plugins/registry/_id_/update.mjs +44 -41
  105. package/dist/astro/routes/api/admin/plugins/registry/_id_/update.mjs.map +1 -1
  106. package/dist/astro/routes/api/admin/plugins/registry/artifact.mjs +40 -39
  107. package/dist/astro/routes/api/admin/plugins/registry/artifact.mjs.map +1 -1
  108. package/dist/astro/routes/api/admin/plugins/registry/install.d.mts.map +1 -1
  109. package/dist/astro/routes/api/admin/plugins/registry/install.mjs +45 -42
  110. package/dist/astro/routes/api/admin/plugins/registry/install.mjs.map +1 -1
  111. package/dist/astro/routes/api/admin/plugins/updates.mjs +41 -40
  112. package/dist/astro/routes/api/admin/plugins/updates.mjs.map +1 -1
  113. package/dist/astro/routes/api/admin/themes/marketplace/_id_/index.mjs +40 -39
  114. package/dist/astro/routes/api/admin/themes/marketplace/_id_/index.mjs.map +1 -1
  115. package/dist/astro/routes/api/admin/themes/marketplace/_id_/thumbnail.mjs +4 -4
  116. package/dist/astro/routes/api/admin/themes/marketplace/index.mjs +40 -39
  117. package/dist/astro/routes/api/admin/themes/marketplace/index.mjs.map +1 -1
  118. package/dist/astro/routes/api/admin/users/_id_/disable.mjs +4 -4
  119. package/dist/astro/routes/api/admin/users/_id_/enable.mjs +4 -4
  120. package/dist/astro/routes/api/admin/users/_id_/index.mjs +9 -8
  121. package/dist/astro/routes/api/admin/users/_id_/index.mjs.map +1 -1
  122. package/dist/astro/routes/api/admin/users/_id_/send-recovery.mjs +5 -5
  123. package/dist/astro/routes/api/admin/users/index.mjs +9 -8
  124. package/dist/astro/routes/api/admin/users/index.mjs.map +1 -1
  125. package/dist/astro/routes/api/auth/dev-bypass.mjs +7 -7
  126. package/dist/astro/routes/api/auth/invite/accept.mjs +4 -4
  127. package/dist/astro/routes/api/auth/invite/complete.mjs +13 -12
  128. package/dist/astro/routes/api/auth/invite/complete.mjs.map +1 -1
  129. package/dist/astro/routes/api/auth/invite/index.mjs +10 -9
  130. package/dist/astro/routes/api/auth/invite/index.mjs.map +1 -1
  131. package/dist/astro/routes/api/auth/invite/register-options.mjs +12 -11
  132. package/dist/astro/routes/api/auth/invite/register-options.mjs.map +1 -1
  133. package/dist/astro/routes/api/auth/logout.mjs +4 -4
  134. package/dist/astro/routes/api/auth/magic-link/send.mjs +12 -11
  135. package/dist/astro/routes/api/auth/magic-link/send.mjs.map +1 -1
  136. package/dist/astro/routes/api/auth/magic-link/verify.mjs +5 -5
  137. package/dist/astro/routes/api/auth/me.mjs +9 -8
  138. package/dist/astro/routes/api/auth/me.mjs.map +1 -1
  139. package/dist/astro/routes/api/auth/mode.d.mts.map +1 -1
  140. package/dist/astro/routes/api/auth/mode.mjs +6 -3
  141. package/dist/astro/routes/api/auth/mode.mjs.map +1 -1
  142. package/dist/astro/routes/api/auth/oauth/_provider_/callback.mjs +15 -5
  143. package/dist/astro/routes/api/auth/oauth/_provider_/callback.mjs.map +1 -1
  144. package/dist/astro/routes/api/auth/oauth/_provider_.d.mts.map +1 -1
  145. package/dist/astro/routes/api/auth/oauth/_provider_.mjs +11 -5
  146. package/dist/astro/routes/api/auth/oauth/_provider_.mjs.map +1 -1
  147. package/dist/astro/routes/api/auth/passkey/_id_.mjs +8 -7
  148. package/dist/astro/routes/api/auth/passkey/_id_.mjs.map +1 -1
  149. package/dist/astro/routes/api/auth/passkey/index.mjs +3 -3
  150. package/dist/astro/routes/api/auth/passkey/options.mjs +13 -12
  151. package/dist/astro/routes/api/auth/passkey/options.mjs.map +1 -1
  152. package/dist/astro/routes/api/auth/passkey/register/options.mjs +11 -10
  153. package/dist/astro/routes/api/auth/passkey/register/options.mjs.map +1 -1
  154. package/dist/astro/routes/api/auth/passkey/register/verify.mjs +12 -11
  155. package/dist/astro/routes/api/auth/passkey/register/verify.mjs.map +1 -1
  156. package/dist/astro/routes/api/auth/passkey/verify.mjs +12 -11
  157. package/dist/astro/routes/api/auth/passkey/verify.mjs.map +1 -1
  158. package/dist/astro/routes/api/auth/signup/complete.mjs +13 -12
  159. package/dist/astro/routes/api/auth/signup/complete.mjs.map +1 -1
  160. package/dist/astro/routes/api/auth/signup/request.mjs +12 -11
  161. package/dist/astro/routes/api/auth/signup/request.mjs.map +1 -1
  162. package/dist/astro/routes/api/auth/signup/verify.mjs +4 -4
  163. package/dist/astro/routes/api/comments/_collection_/_contentId_/index.mjs +14 -13
  164. package/dist/astro/routes/api/comments/_collection_/_contentId_/index.mjs.map +1 -1
  165. package/dist/astro/routes/api/comments/_collection_/_contentId_/reactions.mjs +13 -12
  166. package/dist/astro/routes/api/comments/_collection_/_contentId_/reactions.mjs.map +1 -1
  167. package/dist/astro/routes/api/content/_collection_/_id_/compare.mjs +5 -5
  168. package/dist/astro/routes/api/content/_collection_/_id_/compare.mjs.map +1 -1
  169. package/dist/astro/routes/api/content/_collection_/_id_/discard-draft.mjs +5 -4
  170. package/dist/astro/routes/api/content/_collection_/_id_/discard-draft.mjs.map +1 -1
  171. package/dist/astro/routes/api/content/_collection_/_id_/duplicate.mjs +6 -5
  172. package/dist/astro/routes/api/content/_collection_/_id_/duplicate.mjs.map +1 -1
  173. package/dist/astro/routes/api/content/_collection_/_id_/permanent.mjs +5 -5
  174. package/dist/astro/routes/api/content/_collection_/_id_/permanent.mjs.map +1 -1
  175. package/dist/astro/routes/api/content/_collection_/_id_/preview-url.mjs +14 -13
  176. package/dist/astro/routes/api/content/_collection_/_id_/preview-url.mjs.map +1 -1
  177. package/dist/astro/routes/api/content/_collection_/_id_/publish.mjs +10 -8
  178. package/dist/astro/routes/api/content/_collection_/_id_/publish.mjs.map +1 -1
  179. package/dist/astro/routes/api/content/_collection_/_id_/references/_relation_/children.d.mts.map +1 -1
  180. package/dist/astro/routes/api/content/_collection_/_id_/references/_relation_/children.mjs +20 -19
  181. package/dist/astro/routes/api/content/_collection_/_id_/references/_relation_/children.mjs.map +1 -1
  182. package/dist/astro/routes/api/content/_collection_/_id_/references/_relation_/parents.mjs +18 -17
  183. package/dist/astro/routes/api/content/_collection_/_id_/references/_relation_/parents.mjs.map +1 -1
  184. package/dist/astro/routes/api/content/_collection_/_id_/restore.mjs +5 -4
  185. package/dist/astro/routes/api/content/_collection_/_id_/restore.mjs.map +1 -1
  186. package/dist/astro/routes/api/content/_collection_/_id_/revisions.mjs +5 -5
  187. package/dist/astro/routes/api/content/_collection_/_id_/revisions.mjs.map +1 -1
  188. package/dist/astro/routes/api/content/_collection_/_id_/schedule.mjs +10 -8
  189. package/dist/astro/routes/api/content/_collection_/_id_/schedule.mjs.map +1 -1
  190. package/dist/astro/routes/api/content/_collection_/_id_/terms/_taxonomy_.d.mts.map +1 -1
  191. package/dist/astro/routes/api/content/_collection_/_id_/terms/_taxonomy_.mjs +19 -18
  192. package/dist/astro/routes/api/content/_collection_/_id_/terms/_taxonomy_.mjs.map +1 -1
  193. package/dist/astro/routes/api/content/_collection_/_id_/translations.mjs +5 -5
  194. package/dist/astro/routes/api/content/_collection_/_id_/translations.mjs.map +1 -1
  195. package/dist/astro/routes/api/content/_collection_/_id_/unpublish.mjs +5 -4
  196. package/dist/astro/routes/api/content/_collection_/_id_/unpublish.mjs.map +1 -1
  197. package/dist/astro/routes/api/content/_collection_/_id_.d.mts.map +1 -1
  198. package/dist/astro/routes/api/content/_collection_/_id_.mjs +11 -9
  199. package/dist/astro/routes/api/content/_collection_/_id_.mjs.map +1 -1
  200. package/dist/astro/routes/api/content/_collection_/authors.mjs +5 -5
  201. package/dist/astro/routes/api/content/_collection_/authors.mjs.map +1 -1
  202. package/dist/astro/routes/api/content/_collection_/index.d.mts.map +1 -1
  203. package/dist/astro/routes/api/content/_collection_/index.mjs +12 -10
  204. package/dist/astro/routes/api/content/_collection_/index.mjs.map +1 -1
  205. package/dist/astro/routes/api/content/_collection_/trash.mjs +10 -9
  206. package/dist/astro/routes/api/content/_collection_/trash.mjs.map +1 -1
  207. package/dist/astro/routes/api/dashboard.mjs +8 -8
  208. package/dist/astro/routes/api/dev/emails.mjs +4 -4
  209. package/dist/astro/routes/api/import/probe.d.mts +3 -3
  210. package/dist/astro/routes/api/import/probe.mjs +17 -16
  211. package/dist/astro/routes/api/import/probe.mjs.map +1 -1
  212. package/dist/astro/routes/api/import/wordpress/analyze.mjs +4 -4
  213. package/dist/astro/routes/api/import/wordpress/execute.d.mts +11 -12
  214. package/dist/astro/routes/api/import/wordpress/execute.d.mts.map +1 -1
  215. package/dist/astro/routes/api/import/wordpress/execute.mjs +13 -13
  216. package/dist/astro/routes/api/import/wordpress/media.d.mts +10 -11
  217. package/dist/astro/routes/api/import/wordpress/media.d.mts.map +1 -1
  218. package/dist/astro/routes/api/import/wordpress/media.mjs +11 -10
  219. package/dist/astro/routes/api/import/wordpress/media.mjs.map +1 -1
  220. package/dist/astro/routes/api/import/wordpress/prepare.mjs +11 -10
  221. package/dist/astro/routes/api/import/wordpress/prepare.mjs.map +1 -1
  222. package/dist/astro/routes/api/import/wordpress/rewrite-urls.d.mts +11 -12
  223. package/dist/astro/routes/api/import/wordpress/rewrite-urls.d.mts.map +1 -1
  224. package/dist/astro/routes/api/import/wordpress/rewrite-urls.mjs +11 -10
  225. package/dist/astro/routes/api/import/wordpress/rewrite-urls.mjs.map +1 -1
  226. package/dist/astro/routes/api/import/wordpress-plugin/analyze.d.mts +1 -1
  227. package/dist/astro/routes/api/import/wordpress-plugin/analyze.mjs +17 -16
  228. package/dist/astro/routes/api/import/wordpress-plugin/analyze.mjs.map +1 -1
  229. package/dist/astro/routes/api/import/wordpress-plugin/callback.mjs +1 -1
  230. package/dist/astro/routes/api/import/wordpress-plugin/execute.d.mts +11 -12
  231. package/dist/astro/routes/api/import/wordpress-plugin/execute.d.mts.map +1 -1
  232. package/dist/astro/routes/api/import/wordpress-plugin/execute.mjs +24 -23
  233. package/dist/astro/routes/api/import/wordpress-plugin/execute.mjs.map +1 -1
  234. package/dist/astro/routes/api/manifest.mjs +7 -8
  235. package/dist/astro/routes/api/manifest.mjs.map +1 -1
  236. package/dist/astro/routes/api/mcp.d.mts.map +1 -1
  237. package/dist/astro/routes/api/mcp.mjs +149 -45
  238. package/dist/astro/routes/api/mcp.mjs.map +1 -1
  239. package/dist/astro/routes/api/media/_id_/confirm.mjs +9 -8
  240. package/dist/astro/routes/api/media/_id_/confirm.mjs.map +1 -1
  241. package/dist/astro/routes/api/media/_id_/usage.d.mts +8 -0
  242. package/dist/astro/routes/api/media/_id_/usage.d.mts.map +1 -0
  243. package/dist/astro/routes/api/media/_id_/usage.mjs +37 -0
  244. package/dist/astro/routes/api/media/_id_/usage.mjs.map +1 -0
  245. package/dist/astro/routes/api/media/_id_.d.mts.map +1 -1
  246. package/dist/astro/routes/api/media/_id_.mjs +26 -10
  247. package/dist/astro/routes/api/media/_id_.mjs.map +1 -1
  248. package/dist/astro/routes/api/media/file/_...key_.mjs +4 -3
  249. package/dist/astro/routes/api/media/file/_...key_.mjs.map +1 -1
  250. package/dist/astro/routes/api/media/providers/_providerId_/_itemId_.mjs +4 -4
  251. package/dist/astro/routes/api/media/providers/_providerId_/index.mjs +4 -4
  252. package/dist/astro/routes/api/media/providers/index.mjs +4 -4
  253. package/dist/astro/routes/api/media/upload-url.mjs +10 -9
  254. package/dist/astro/routes/api/media/upload-url.mjs.map +1 -1
  255. package/dist/astro/routes/api/media.d.mts.map +1 -1
  256. package/dist/astro/routes/api/media.mjs +31 -11
  257. package/dist/astro/routes/api/media.mjs.map +1 -1
  258. package/dist/astro/routes/api/menus/_name_/items/_id_.mjs +10 -9
  259. package/dist/astro/routes/api/menus/_name_/items/_id_.mjs.map +1 -1
  260. package/dist/astro/routes/api/menus/_name_/items.mjs +10 -9
  261. package/dist/astro/routes/api/menus/_name_/items.mjs.map +1 -1
  262. package/dist/astro/routes/api/menus/_name_/reorder.mjs +10 -9
  263. package/dist/astro/routes/api/menus/_name_/reorder.mjs.map +1 -1
  264. package/dist/astro/routes/api/menus/_name_/translations.mjs +10 -9
  265. package/dist/astro/routes/api/menus/_name_/translations.mjs.map +1 -1
  266. package/dist/astro/routes/api/menus/_name_.mjs +10 -9
  267. package/dist/astro/routes/api/menus/_name_.mjs.map +1 -1
  268. package/dist/astro/routes/api/menus/index.mjs +10 -9
  269. package/dist/astro/routes/api/menus/index.mjs.map +1 -1
  270. package/dist/astro/routes/api/oauth/authorize.d.mts.map +1 -1
  271. package/dist/astro/routes/api/oauth/authorize.mjs +29 -16
  272. package/dist/astro/routes/api/oauth/authorize.mjs.map +1 -1
  273. package/dist/astro/routes/api/oauth/device/authorize.mjs +7 -7
  274. package/dist/astro/routes/api/oauth/device/code.mjs +10 -10
  275. package/dist/astro/routes/api/oauth/device/token.mjs +9 -9
  276. package/dist/astro/routes/api/oauth/register.mjs +4 -4
  277. package/dist/astro/routes/api/oauth/token/refresh.mjs +7 -7
  278. package/dist/astro/routes/api/oauth/token/revoke.mjs +7 -7
  279. package/dist/astro/routes/api/oauth/token.mjs +7 -7
  280. package/dist/astro/routes/api/openapi.json.mjs +52 -24
  281. package/dist/astro/routes/api/openapi.json.mjs.map +1 -1
  282. package/dist/astro/routes/api/plugins/_pluginId_/_...path_.d.mts.map +1 -1
  283. package/dist/astro/routes/api/plugins/_pluginId_/_...path_.mjs +20 -32
  284. package/dist/astro/routes/api/plugins/_pluginId_/_...path_.mjs.map +1 -1
  285. package/dist/astro/routes/api/redirects/404s/index.mjs +12 -11
  286. package/dist/astro/routes/api/redirects/404s/index.mjs.map +1 -1
  287. package/dist/astro/routes/api/redirects/404s/summary.mjs +12 -11
  288. package/dist/astro/routes/api/redirects/404s/summary.mjs.map +1 -1
  289. package/dist/astro/routes/api/redirects/_id_.mjs +13 -12
  290. package/dist/astro/routes/api/redirects/_id_.mjs.map +1 -1
  291. package/dist/astro/routes/api/redirects/index.mjs +13 -12
  292. package/dist/astro/routes/api/redirects/index.mjs.map +1 -1
  293. package/dist/astro/routes/api/relations/_id_/index.mjs +16 -15
  294. package/dist/astro/routes/api/relations/_id_/index.mjs.map +1 -1
  295. package/dist/astro/routes/api/relations/_id_/translations.mjs +11 -11
  296. package/dist/astro/routes/api/relations/index.mjs +16 -15
  297. package/dist/astro/routes/api/relations/index.mjs.map +1 -1
  298. package/dist/astro/routes/api/revisions/_revisionId_/index.mjs +4 -4
  299. package/dist/astro/routes/api/revisions/_revisionId_/restore.mjs +5 -4
  300. package/dist/astro/routes/api/revisions/_revisionId_/restore.mjs.map +1 -1
  301. package/dist/astro/routes/api/schema/collections/_slug_/fields/_fieldSlug_.mjs +40 -39
  302. package/dist/astro/routes/api/schema/collections/_slug_/fields/_fieldSlug_.mjs.map +1 -1
  303. package/dist/astro/routes/api/schema/collections/_slug_/fields/index.mjs +40 -39
  304. package/dist/astro/routes/api/schema/collections/_slug_/fields/index.mjs.map +1 -1
  305. package/dist/astro/routes/api/schema/collections/_slug_/fields/reorder.mjs +40 -39
  306. package/dist/astro/routes/api/schema/collections/_slug_/fields/reorder.mjs.map +1 -1
  307. package/dist/astro/routes/api/schema/collections/_slug_/index.mjs +40 -39
  308. package/dist/astro/routes/api/schema/collections/_slug_/index.mjs.map +1 -1
  309. package/dist/astro/routes/api/schema/collections/index.mjs +40 -39
  310. package/dist/astro/routes/api/schema/collections/index.mjs.map +1 -1
  311. package/dist/astro/routes/api/schema/index.mjs +9 -9
  312. package/dist/astro/routes/api/schema/orphans/_slug_.mjs +40 -39
  313. package/dist/astro/routes/api/schema/orphans/_slug_.mjs.map +1 -1
  314. package/dist/astro/routes/api/schema/orphans/index.mjs +40 -39
  315. package/dist/astro/routes/api/schema/orphans/index.mjs.map +1 -1
  316. package/dist/astro/routes/api/search/enable.mjs +13 -12
  317. package/dist/astro/routes/api/search/enable.mjs.map +1 -1
  318. package/dist/astro/routes/api/search/index.mjs +12 -11
  319. package/dist/astro/routes/api/search/index.mjs.map +1 -1
  320. package/dist/astro/routes/api/search/rebuild.mjs +13 -12
  321. package/dist/astro/routes/api/search/rebuild.mjs.map +1 -1
  322. package/dist/astro/routes/api/search/stats.mjs +8 -8
  323. package/dist/astro/routes/api/search/suggest.mjs +12 -11
  324. package/dist/astro/routes/api/search/suggest.mjs.map +1 -1
  325. package/dist/astro/routes/api/sections/_slug_.mjs +12 -11
  326. package/dist/astro/routes/api/sections/_slug_.mjs.map +1 -1
  327. package/dist/astro/routes/api/sections/index.mjs +12 -11
  328. package/dist/astro/routes/api/sections/index.mjs.map +1 -1
  329. package/dist/astro/routes/api/settings/backups/archives/_name_.d.mts +9 -0
  330. package/dist/astro/routes/api/settings/backups/archives/_name_.d.mts.map +1 -0
  331. package/dist/astro/routes/api/settings/backups/archives/_name_.mjs +48 -0
  332. package/dist/astro/routes/api/settings/backups/archives/_name_.mjs.map +1 -0
  333. package/dist/astro/routes/api/settings/backups/archives/index.d.mts +8 -0
  334. package/dist/astro/routes/api/settings/backups/archives/index.d.mts.map +1 -0
  335. package/dist/astro/routes/api/settings/backups/archives/index.mjs +23 -0
  336. package/dist/astro/routes/api/settings/backups/archives/index.mjs.map +1 -0
  337. package/dist/astro/routes/api/settings/backups/export.d.mts +8 -0
  338. package/dist/astro/routes/api/settings/backups/export.d.mts.map +1 -0
  339. package/dist/astro/routes/api/settings/backups/export.mjs +35 -0
  340. package/dist/astro/routes/api/settings/backups/export.mjs.map +1 -0
  341. package/dist/astro/routes/api/settings/backups/index.d.mts +9 -0
  342. package/dist/astro/routes/api/settings/backups/index.d.mts.map +1 -0
  343. package/dist/astro/routes/api/settings/backups/index.mjs +52 -0
  344. package/dist/astro/routes/api/settings/backups/index.mjs.map +1 -0
  345. package/dist/astro/routes/api/settings/email.mjs +5 -5
  346. package/dist/astro/routes/api/settings.mjs +14 -13
  347. package/dist/astro/routes/api/settings.mjs.map +1 -1
  348. package/dist/astro/routes/api/setup/admin-verify.mjs +19 -15
  349. package/dist/astro/routes/api/setup/admin-verify.mjs.map +1 -1
  350. package/dist/astro/routes/api/setup/admin.mjs +18 -14
  351. package/dist/astro/routes/api/setup/admin.mjs.map +1 -1
  352. package/dist/astro/routes/api/setup/dev-bypass.mjs +26 -26
  353. package/dist/astro/routes/api/setup/dev-reset.mjs +3 -3
  354. package/dist/astro/routes/api/setup/index.mjs +28 -27
  355. package/dist/astro/routes/api/setup/index.mjs.map +1 -1
  356. package/dist/astro/routes/api/setup/status.mjs +5 -5
  357. package/dist/astro/routes/api/snapshot.mjs +8 -215
  358. package/dist/astro/routes/api/snapshot.mjs.map +1 -1
  359. package/dist/astro/routes/api/taxonomies/_name_/terms/_slug_/translations.mjs +15 -14
  360. package/dist/astro/routes/api/taxonomies/_name_/terms/_slug_/translations.mjs.map +1 -1
  361. package/dist/astro/routes/api/taxonomies/_name_/terms/_slug_.mjs +15 -14
  362. package/dist/astro/routes/api/taxonomies/_name_/terms/_slug_.mjs.map +1 -1
  363. package/dist/astro/routes/api/taxonomies/_name_/terms/index.mjs +15 -14
  364. package/dist/astro/routes/api/taxonomies/_name_/terms/index.mjs.map +1 -1
  365. package/dist/astro/routes/api/taxonomies/index.mjs +15 -14
  366. package/dist/astro/routes/api/taxonomies/index.mjs.map +1 -1
  367. package/dist/astro/routes/api/themes/preview.mjs +6 -6
  368. package/dist/astro/routes/api/typegen.mjs +6 -6
  369. package/dist/astro/routes/api/well-known/auth.mjs +1 -1
  370. package/dist/astro/routes/api/well-known/oauth-authorization-server.d.mts.map +1 -1
  371. package/dist/astro/routes/api/well-known/oauth-authorization-server.mjs +4 -3
  372. package/dist/astro/routes/api/well-known/oauth-authorization-server.mjs.map +1 -1
  373. package/dist/astro/routes/api/well-known/oauth-protected-resource.d.mts.map +1 -1
  374. package/dist/astro/routes/api/well-known/oauth-protected-resource.mjs +4 -3
  375. package/dist/astro/routes/api/well-known/oauth-protected-resource.mjs.map +1 -1
  376. package/dist/astro/routes/api/widget-areas/_name_/reorder.mjs +9 -8
  377. package/dist/astro/routes/api/widget-areas/_name_/reorder.mjs.map +1 -1
  378. package/dist/astro/routes/api/widget-areas/_name_/widgets/_id_.mjs +12 -11
  379. package/dist/astro/routes/api/widget-areas/_name_/widgets/_id_.mjs.map +1 -1
  380. package/dist/astro/routes/api/widget-areas/_name_/widgets.mjs +12 -11
  381. package/dist/astro/routes/api/widget-areas/_name_/widgets.mjs.map +1 -1
  382. package/dist/astro/routes/api/widget-areas/_name_.mjs +7 -7
  383. package/dist/astro/routes/api/widget-areas/index.mjs +12 -11
  384. package/dist/astro/routes/api/widget-areas/index.mjs.map +1 -1
  385. package/dist/astro/routes/api/widget-components.mjs +4 -4
  386. package/dist/astro/routes/robots.txt.mjs +7 -7
  387. package/dist/astro/routes/sitemap-_collection_.xml.mjs +11 -11
  388. package/dist/astro/routes/sitemap.xml.mjs +8 -8
  389. package/dist/astro/types.d.mts +38 -17
  390. package/dist/astro/types.d.mts.map +1 -1
  391. package/dist/auth/providers/github.d.mts +1 -1
  392. package/dist/auth/providers/google.d.mts +1 -1
  393. package/dist/{authorize-BmCwQCib.mjs → authorize-6WPZa1xZ.mjs} +7 -4
  394. package/dist/authorize-6WPZa1xZ.mjs.map +1 -0
  395. package/dist/backup-Qr9PaGUo.mjs +241 -0
  396. package/dist/backup-Qr9PaGUo.mjs.map +1 -0
  397. package/dist/{base64-C74Msx8h.mjs → base64-B-PsqheR.mjs} +8 -4
  398. package/dist/base64-B-PsqheR.mjs.map +1 -0
  399. package/dist/{byline-BWb5H-65.mjs → byline-BTOxUlFF.mjs} +6 -6
  400. package/dist/{byline-BWb5H-65.mjs.map → byline-BTOxUlFF.mjs.map} +1 -1
  401. package/dist/{byline-fields-DO6bAYK8.mjs → byline-fields-CdU_LTF1.mjs} +1 -1
  402. package/dist/{byline-fields-DO6bAYK8.mjs.map → byline-fields-CdU_LTF1.mjs.map} +1 -1
  403. package/dist/{bylines-CHojDMpj.mjs → bylines-FyZu6TbJ.mjs} +7 -7
  404. package/dist/{bylines-CHojDMpj.mjs.map → bylines-FyZu6TbJ.mjs.map} +1 -1
  405. package/dist/{bylines-BGuKFaBy.mjs → bylines-oVN0iPwX.mjs} +12 -8
  406. package/dist/bylines-oVN0iPwX.mjs.map +1 -0
  407. package/dist/{cache-BeR7RfN8.mjs → cache-DDwy3JDW.mjs} +2 -2
  408. package/dist/{cache-BeR7RfN8.mjs.map → cache-DDwy3JDW.mjs.map} +1 -1
  409. package/dist/{challenge-store-B426wQ6O.mjs → challenge-store-BFzgFRog.mjs} +1 -1
  410. package/dist/{challenge-store-B426wQ6O.mjs.map → challenge-store-BFzgFRog.mjs.map} +1 -1
  411. package/dist/{chunks-BU5_nrAC.mjs → chunks-Bq-5DPrD.mjs} +2 -2
  412. package/dist/{chunks-BU5_nrAC.mjs.map → chunks-Bq-5DPrD.mjs.map} +1 -1
  413. package/dist/cli/index.mjs +139 -32
  414. package/dist/cli/index.mjs.map +1 -1
  415. package/dist/client/cf-access.d.mts +1 -1
  416. package/dist/client/index.d.mts +54 -3
  417. package/dist/client/index.d.mts.map +1 -1
  418. package/dist/client/index.mjs +16 -4
  419. package/dist/client/index.mjs.map +1 -1
  420. package/dist/{comment-SWh31kS0.mjs → comment-B9cUud8H.mjs} +2 -2
  421. package/dist/{comment-SWh31kS0.mjs.map → comment-B9cUud8H.mjs.map} +1 -1
  422. package/dist/{comment-reaction-DgcpziXI.mjs → comment-reaction-VUXO981F.mjs} +2 -2
  423. package/dist/{comment-reaction-DgcpziXI.mjs.map → comment-reaction-VUXO981F.mjs.map} +1 -1
  424. package/dist/{comments-kZYGppMS.mjs → comments-PXj1E9Si.mjs} +3 -3
  425. package/dist/{comments-kZYGppMS.mjs.map → comments-PXj1E9Si.mjs.map} +1 -1
  426. package/dist/{components-CliOkZAs.mjs → components-DZkL4Fx0.mjs} +1 -1
  427. package/dist/{components-CliOkZAs.mjs.map → components-DZkL4Fx0.mjs.map} +1 -1
  428. package/dist/{config-CVssduLe.mjs → config-B6b_BobR.mjs} +6 -2
  429. package/dist/config-B6b_BobR.mjs.map +1 -0
  430. package/dist/{content-BO61Sx4j.mjs → content-BC43pICM.mjs} +53 -19
  431. package/dist/content-BC43pICM.mjs.map +1 -0
  432. package/dist/{content-refresh-BkkApzeS.mjs → content-refresh-CPMSauD3.mjs} +96 -4
  433. package/dist/content-refresh-CPMSauD3.mjs.map +1 -0
  434. package/dist/{context-DtSFYFuS.mjs → context-DOurRIrb.mjs} +97 -74
  435. package/dist/context-DOurRIrb.mjs.map +1 -0
  436. package/dist/{cron-YFJ7uNVA.mjs → cron-BlKIMD_e.mjs} +1 -1
  437. package/dist/{cron-YFJ7uNVA.mjs.map → cron-BlKIMD_e.mjs.map} +1 -1
  438. package/dist/{dashboard-xo_gPs_D.mjs → dashboard-CBm4zhc3.mjs} +4 -4
  439. package/dist/{dashboard-xo_gPs_D.mjs.map → dashboard-CBm4zhc3.mjs.map} +1 -1
  440. package/dist/database/pg-migration-lock.d.mts.map +1 -1
  441. package/dist/database/pg-migration-lock.mjs +1 -4
  442. package/dist/database/pg-migration-lock.mjs.map +1 -1
  443. package/dist/db/index.d.mts +3 -3
  444. package/dist/db/index.mjs +2 -2
  445. package/dist/db/index.mjs.map +1 -1
  446. package/dist/db/libsql.d.mts +1 -1
  447. package/dist/db/postgres.d.mts +1 -1
  448. package/dist/db/sqlite.d.mts +1 -1
  449. package/dist/{db-errors-BKuXh_fi.mjs → db-errors-CcWLaRiR.mjs} +4 -2
  450. package/dist/db-errors-CcWLaRiR.mjs.map +1 -0
  451. package/dist/{default-DY5ovGUG.mjs → default-C4v9KP56.mjs} +1 -1
  452. package/dist/{default-DY5ovGUG.mjs.map → default-C4v9KP56.mjs.map} +1 -1
  453. package/dist/{device-flow-CPXQ_QfW.mjs → device-flow-BeA6lUS1.mjs} +5 -6
  454. package/dist/device-flow-BeA6lUS1.mjs.map +1 -0
  455. package/dist/{dialect-helpers-Cue7QQOR.mjs → dialect-helpers-BtOwo2us.mjs} +60 -14
  456. package/dist/dialect-helpers-BtOwo2us.mjs.map +1 -0
  457. package/dist/{email-console-CjkQc7oY.mjs → email-console-C-9Ng8DM.mjs} +1 -1
  458. package/dist/{email-console-CjkQc7oY.mjs.map → email-console-C-9Ng8DM.mjs.map} +1 -1
  459. package/dist/error-DJ98TRbQ.mjs +90 -0
  460. package/dist/error-DJ98TRbQ.mjs.map +1 -0
  461. package/dist/{error-CfJMLSkd.mjs → errors-DtEXIQQV.mjs} +15 -84
  462. package/dist/errors-DtEXIQQV.mjs.map +1 -0
  463. package/dist/{escape-r8_GbEU2.mjs → escape-CFedIB1C.mjs} +1 -1
  464. package/dist/{escape-r8_GbEU2.mjs.map → escape-CFedIB1C.mjs.map} +1 -1
  465. package/dist/{field-defs-cache-BVrNCgSj.mjs → field-defs-cache-KfNJ_qLQ.mjs} +2 -2
  466. package/dist/{field-defs-cache-BVrNCgSj.mjs.map → field-defs-cache-KfNJ_qLQ.mjs.map} +1 -1
  467. package/dist/{fts-manager-BD9s77qh.mjs → fts-manager-hyCU9OOp.mjs} +3 -3
  468. package/dist/{fts-manager-BD9s77qh.mjs.map → fts-manager-hyCU9OOp.mjs.map} +1 -1
  469. package/dist/{hreflang-CgIxhH4k.d.mts → hreflang-CIxH_LKz.d.mts} +2 -2
  470. package/dist/{hreflang-CgIxhH4k.d.mts.map → hreflang-CIxH_LKz.d.mts.map} +1 -1
  471. package/dist/{hreflang-pAWUiPd_.mjs → hreflang-CbYeCzl9.mjs} +7 -7
  472. package/dist/{hreflang-pAWUiPd_.mjs.map → hreflang-CbYeCzl9.mjs.map} +1 -1
  473. package/dist/{import-2jHtLzsO.mjs → import-oDYCgNYQ.mjs} +4 -4
  474. package/dist/{import-2jHtLzsO.mjs.map → import-oDYCgNYQ.mjs.map} +1 -1
  475. package/dist/{index-DxjWLKGT.d.mts → index-BEui-cRd.d.mts} +3 -3
  476. package/dist/{index-DxjWLKGT.d.mts.map → index-BEui-cRd.d.mts.map} +1 -1
  477. package/dist/{index-BXOCyLj0.d.mts → index-BcEH_FfS.d.mts} +812 -16
  478. package/dist/index-BcEH_FfS.d.mts.map +1 -0
  479. package/dist/index.d.mts +18 -19
  480. package/dist/index.mjs +61 -60
  481. package/dist/{load-DgoWMdRX.mjs → load-Dg5gtWma.mjs} +2 -2
  482. package/dist/{load-DgoWMdRX.mjs.map → load-Dg5gtWma.mjs.map} +1 -1
  483. package/dist/{loader-Rb8QlGZp.mjs → loader-D4rigvjR.mjs} +170 -6
  484. package/dist/loader-D4rigvjR.mjs.map +1 -0
  485. package/dist/{manifest-schema-DeGNma2O.mjs → manifest-schema-bCq54i7F.mjs} +16 -2
  486. package/dist/manifest-schema-bCq54i7F.mjs.map +1 -0
  487. package/dist/media/image-endpoint.d.mts +30 -2
  488. package/dist/media/image-endpoint.d.mts.map +1 -1
  489. package/dist/media/image-endpoint.mjs +29 -3
  490. package/dist/media/image-endpoint.mjs.map +1 -1
  491. package/dist/media/index.d.mts +1 -1
  492. package/dist/media/local-runtime.d.mts +12 -13
  493. package/dist/media/local-runtime.d.mts.map +1 -1
  494. package/dist/media/local-runtime.mjs +6 -6
  495. package/dist/media-BJ6SRY3g.mjs +247 -0
  496. package/dist/media-BJ6SRY3g.mjs.map +1 -0
  497. package/dist/{media-allowlist-Dc05vKtt.mjs → media-allowlist-jUppPWFy.mjs} +1 -1
  498. package/dist/{media-allowlist-Dc05vKtt.mjs.map → media-allowlist-jUppPWFy.mjs.map} +1 -1
  499. package/dist/{media-D2ZFowpn.mjs → media-its1WLYv.mjs} +2 -2
  500. package/dist/{media-D2ZFowpn.mjs.map → media-its1WLYv.mjs.map} +1 -1
  501. package/dist/media-upload-DNu3QySc.mjs +145 -0
  502. package/dist/media-upload-DNu3QySc.mjs.map +1 -0
  503. package/dist/{media-url-DgIEYZr4.mjs → media-url-BCm5vBn6.mjs} +1 -1
  504. package/dist/{media-url-DgIEYZr4.mjs.map → media-url-BCm5vBn6.mjs.map} +1 -1
  505. package/dist/{media-usage-B__v9NMm.mjs → media-usage-DPQ3K4xB.mjs} +138 -5
  506. package/dist/{media-usage-B__v9NMm.mjs.map → media-usage-DPQ3K4xB.mjs.map} +1 -1
  507. package/dist/{menus-BpfevlJD.mjs → menus-BMGzWyWH.mjs} +15 -8
  508. package/dist/menus-BMGzWyWH.mjs.map +1 -0
  509. package/dist/{menus-BtvH7Z7t.mjs → menus-CPf_SW7u.mjs} +234 -13
  510. package/dist/menus-CPf_SW7u.mjs.map +1 -0
  511. package/dist/{mode-BVnhGZ2o.mjs → mode-fiXRMfeA.mjs} +1 -1
  512. package/dist/{mode-BVnhGZ2o.mjs.map → mode-fiXRMfeA.mjs.map} +1 -1
  513. package/dist/{oauth-authorization-BWqWTHBK.mjs → oauth-authorization-oqfbBuMH.mjs} +5 -6
  514. package/dist/oauth-authorization-oqfbBuMH.mjs.map +1 -0
  515. package/dist/{oauth-clients-43_XADoa.mjs → oauth-clients-BlrUHAsf.mjs} +1 -1
  516. package/dist/{oauth-clients-43_XADoa.mjs.map → oauth-clients-BlrUHAsf.mjs.map} +1 -1
  517. package/dist/{oauth-state-store-BRSUEkmx.mjs → oauth-state-store-DnvjRMy6.mjs} +2 -1
  518. package/dist/{oauth-state-store-BRSUEkmx.mjs.map → oauth-state-store-DnvjRMy6.mjs.map} +1 -1
  519. package/dist/{oauth-user-lookup-Ctgemb0k.mjs → oauth-user-lookup-oUllxvAv.mjs} +1 -1
  520. package/dist/{oauth-user-lookup-Ctgemb0k.mjs.map → oauth-user-lookup-oUllxvAv.mjs.map} +1 -1
  521. package/dist/object-cache/memory.d.mts +1 -1
  522. package/dist/{options-COXGTtqd.d.mts → options-BqMkWfYa.d.mts} +6 -6
  523. package/dist/{options-COXGTtqd.d.mts.map → options-BqMkWfYa.d.mts.map} +1 -1
  524. package/dist/page/index.d.mts +2 -2
  525. package/dist/page/index.d.mts.map +1 -1
  526. package/dist/page/index.mjs.map +1 -1
  527. package/dist/{parse-GLksnn-B.mjs → parse-53zyxlpv.mjs} +4 -12
  528. package/dist/{parse-GLksnn-B.mjs.map → parse-53zyxlpv.mjs.map} +1 -1
  529. package/dist/{passkey-config-CjA1UbDj.mjs → passkey-config-C-SKpc0-.mjs} +1 -1
  530. package/dist/{passkey-config-CjA1UbDj.mjs.map → passkey-config-C-SKpc0-.mjs.map} +1 -1
  531. package/dist/{placeholder-DR-eeZr-.d.mts → placeholder-Dop47JMM.d.mts} +1 -1
  532. package/dist/{placeholder-DR-eeZr-.d.mts.map → placeholder-Dop47JMM.d.mts.map} +1 -1
  533. package/dist/plugin-types.d.mts +21 -2
  534. package/dist/plugin-types.d.mts.map +1 -1
  535. package/dist/plugin-utils.d.mts +18 -17
  536. package/dist/plugin-utils.d.mts.map +1 -1
  537. package/dist/plugin-utils.mjs +8 -6
  538. package/dist/plugin-utils.mjs.map +1 -1
  539. package/dist/plugins/adapt-sandbox-entry.d.mts +10 -11
  540. package/dist/plugins/adapt-sandbox-entry.d.mts.map +1 -1
  541. package/dist/plugins/adapt-sandbox-entry.mjs +15 -3
  542. package/dist/plugins/adapt-sandbox-entry.mjs.map +1 -1
  543. package/dist/{portable-text-BAkgEKcv.mjs → portable-text-sDj92Kxv.mjs} +1 -1
  544. package/dist/{portable-text-BAkgEKcv.mjs.map → portable-text-sDj92Kxv.mjs.map} +1 -1
  545. package/dist/{preview-Rloa09Wp.mjs → preview-D4Jnbfx7.mjs} +2 -2
  546. package/dist/{preview-Rloa09Wp.mjs.map → preview-D4Jnbfx7.mjs.map} +1 -1
  547. package/dist/{public-url-C0cEvrRu.mjs → public-url-DSGTnJFw.mjs} +5 -3
  548. package/dist/public-url-DSGTnJFw.mjs.map +1 -0
  549. package/dist/{query-ZzvXyxWq.mjs → query-BbJQ-dGg.mjs} +15 -15
  550. package/dist/{query-ZzvXyxWq.mjs.map → query-BbJQ-dGg.mjs.map} +1 -1
  551. package/dist/{query-BxT95opY.mjs → query-DdFGHzQF.mjs} +3 -3
  552. package/dist/{query-BxT95opY.mjs.map → query-DdFGHzQF.mjs.map} +1 -1
  553. package/dist/{rate-limit-Cg4Rvc_-.mjs → rate-limit-D3IEiUi2.mjs} +2 -2
  554. package/dist/{rate-limit-Cg4Rvc_-.mjs.map → rate-limit-D3IEiUi2.mjs.map} +1 -1
  555. package/dist/{redirect-Ch3E98qZ.mjs → redirect-BoUac4NT.mjs} +10 -4
  556. package/dist/redirect-BoUac4NT.mjs.map +1 -0
  557. package/dist/{redirect-Ce_6Yb6z.mjs → redirect-Botom7X6.mjs} +1 -1
  558. package/dist/{redirect-Ce_6Yb6z.mjs.map → redirect-Botom7X6.mjs.map} +1 -1
  559. package/dist/{redirects-CXmVGRNZ.mjs → redirects-ChbpqKiS.mjs} +4 -4
  560. package/dist/{redirects-CXmVGRNZ.mjs.map → redirects-ChbpqKiS.mjs.map} +1 -1
  561. package/dist/{redirects-CeD7K7EX.mjs → redirects-D457qwt0.mjs} +10 -181
  562. package/dist/redirects-D457qwt0.mjs.map +1 -0
  563. package/dist/{registry-CyIXPi4E.mjs → registry-y21kjhfG.mjs} +97 -8
  564. package/dist/registry-y21kjhfG.mjs.map +1 -0
  565. package/dist/{relation-Ba68Tm4Z.mjs → relation-Du0r04E0.mjs} +3 -3
  566. package/dist/{relation-Ba68Tm4Z.mjs.map → relation-Du0r04E0.mjs.map} +1 -1
  567. package/dist/{relations-CbBpoOys.d.mts → relations-BKybBoOX.d.mts} +315 -9
  568. package/dist/relations-BKybBoOX.d.mts.map +1 -0
  569. package/dist/{relations-BmBmX4Eb.mjs → relations-CZMpBqEd.mjs} +3 -3
  570. package/dist/{relations-BmBmX4Eb.mjs.map → relations-CZMpBqEd.mjs.map} +1 -1
  571. package/dist/{relations-C8hVyEy0.mjs → relations-DtX1UMBH.mjs} +13 -7
  572. package/dist/relations-DtX1UMBH.mjs.map +1 -0
  573. package/dist/{request-meta-DCwktC5P.mjs → request-meta-DzXYYI-n.mjs} +2 -2
  574. package/dist/{request-meta-DCwktC5P.mjs.map → request-meta-DzXYYI-n.mjs.map} +1 -1
  575. package/dist/{resolve-Cd9dzclN.mjs → resolve-DFr4kq72.mjs} +2 -2
  576. package/dist/{resolve-Cd9dzclN.mjs.map → resolve-DFr4kq72.mjs.map} +1 -1
  577. package/dist/{runner-jt65bF7F.mjs → runner-BdeLEgad.mjs} +334 -200
  578. package/dist/runner-BdeLEgad.mjs.map +1 -0
  579. package/dist/{runner-CiNdIk3y.d.mts → runner-Dd8m8k9F.d.mts} +2 -2
  580. package/dist/{runner-CiNdIk3y.d.mts.map → runner-Dd8m8k9F.d.mts.map} +1 -1
  581. package/dist/runtime.d.mts +11 -12
  582. package/dist/runtime.d.mts.map +1 -1
  583. package/dist/runtime.mjs +4 -4
  584. package/dist/{schema-DwjufZ1S.mjs → schema-BH8P8vaC.mjs} +3 -3
  585. package/dist/{schema-DwjufZ1S.mjs.map → schema-BH8P8vaC.mjs.map} +1 -1
  586. package/dist/scopes-DTIkIaGA.mjs +27 -0
  587. package/dist/scopes-DTIkIaGA.mjs.map +1 -0
  588. package/dist/{search-Cl875CVE.mjs → search-D-Yhpmvs.mjs} +8 -7
  589. package/dist/search-D-Yhpmvs.mjs.map +1 -0
  590. package/dist/{secrets-CO_bEmII.mjs → secrets-CQ-69kF9.mjs} +25 -19
  591. package/dist/secrets-CQ-69kF9.mjs.map +1 -0
  592. package/dist/{sections-DTKzgoiS.mjs → sections-CzVBAKjw.mjs} +3 -3
  593. package/dist/{sections-DTKzgoiS.mjs.map → sections-CzVBAKjw.mjs.map} +1 -1
  594. package/dist/seed/index.d.mts +2 -2
  595. package/dist/seed/index.mjs +20 -20
  596. package/dist/seo/index.d.mts +14 -3
  597. package/dist/seo/index.d.mts.map +1 -1
  598. package/dist/seo/index.mjs +17 -17
  599. package/dist/seo/index.mjs.map +1 -1
  600. package/dist/{seo-BjrbXAd_.mjs → seo-C3GDfT0V.mjs} +1 -1
  601. package/dist/{seo-BjrbXAd_.mjs.map → seo-C3GDfT0V.mjs.map} +1 -1
  602. package/dist/{seo-BLm6SXzS.mjs → seo-kJzVAmmu.mjs} +2 -2
  603. package/dist/{seo-BLm6SXzS.mjs.map → seo-kJzVAmmu.mjs.map} +1 -1
  604. package/dist/{service-D6zDmKXy.mjs → service-CQnc276a.mjs} +3 -3
  605. package/dist/{service-D6zDmKXy.mjs.map → service-CQnc276a.mjs.map} +1 -1
  606. package/dist/{session-user-DoSs6YM8.mjs → session-user-DbHqKDKe.mjs} +1 -1
  607. package/dist/{session-user-DoSs6YM8.mjs.map → session-user-DbHqKDKe.mjs.map} +1 -1
  608. package/dist/{settings-BuQYvLfy.mjs → settings-C2PaBS49.mjs} +4 -4
  609. package/dist/{settings-BuQYvLfy.mjs.map → settings-C2PaBS49.mjs.map} +1 -1
  610. package/dist/{settings-CmS3TwXf.mjs → settings-Dtc0DU31.mjs} +3 -3
  611. package/dist/{settings-CmS3TwXf.mjs.map → settings-Dtc0DU31.mjs.map} +1 -1
  612. package/dist/{setup-complete-BPNgLHlU.mjs → setup-complete-CdIlqloh.mjs} +1 -1
  613. package/dist/{setup-complete-BPNgLHlU.mjs.map → setup-complete-CdIlqloh.mjs.map} +1 -1
  614. package/dist/{setup-nonce-DEPZX96T.mjs → setup-nonce-DqiIPr-J.mjs} +1 -1
  615. package/dist/{setup-nonce-DEPZX96T.mjs.map → setup-nonce-DqiIPr-J.mjs.map} +1 -1
  616. package/dist/{single-flight-cache-DEtW-OEG.mjs → single-flight-cache-C2exrGAi.mjs} +1 -1
  617. package/dist/{single-flight-cache-DEtW-OEG.mjs.map → single-flight-cache-C2exrGAi.mjs.map} +1 -1
  618. package/dist/{site-url-CcLy5D5s.mjs → site-url-NGJT6NTU.mjs} +1 -1
  619. package/dist/{site-url-CcLy5D5s.mjs.map → site-url-NGJT6NTU.mjs.map} +1 -1
  620. package/dist/snapshot-BdpUJKD-.mjs +216 -0
  621. package/dist/snapshot-BdpUJKD-.mjs.map +1 -0
  622. package/dist/{ssrf-TrKYJAy0.mjs → ssrf-CviKqWmq.mjs} +1 -1
  623. package/dist/{ssrf-TrKYJAy0.mjs.map → ssrf-CviKqWmq.mjs.map} +1 -1
  624. package/dist/state-xxv6ZTMv.mjs +128 -0
  625. package/dist/state-xxv6ZTMv.mjs.map +1 -0
  626. package/dist/{status-D3Gy1Zc6.mjs → status-COfycGIU.mjs} +1 -1
  627. package/dist/{status-D3Gy1Zc6.mjs.map → status-COfycGIU.mjs.map} +1 -1
  628. package/dist/storage/local.d.mts +1 -1
  629. package/dist/storage/local.mjs +1 -1
  630. package/dist/storage/s3.d.mts +1 -1
  631. package/dist/storage/s3.mjs +1 -1
  632. package/dist/{taxonomies-pUkuD6nj.mjs → taxonomies-HI9fnTdp.mjs} +8 -8
  633. package/dist/{taxonomies-pUkuD6nj.mjs.map → taxonomies-HI9fnTdp.mjs.map} +1 -1
  634. package/dist/{taxonomies-ClS4RKaZ.mjs → taxonomies-rMeBzOjX.mjs} +26 -17
  635. package/dist/taxonomies-rMeBzOjX.mjs.map +1 -0
  636. package/dist/{taxonomy-BkxbUMSw.mjs → taxonomy-0mCI25HN.mjs} +51 -13
  637. package/dist/taxonomy-0mCI25HN.mjs.map +1 -0
  638. package/dist/{tokens-BV6fgl5A.mjs → tokens-DVltpO2D.mjs} +2 -2
  639. package/dist/{tokens-BV6fgl5A.mjs.map → tokens-DVltpO2D.mjs.map} +1 -1
  640. package/dist/{transport-DTFhhPOg.mjs → transport-CKrlqSpD.mjs} +1 -1
  641. package/dist/{transport-DTFhhPOg.mjs.map → transport-CKrlqSpD.mjs.map} +1 -1
  642. package/dist/{transport-DmlmzD2U.d.mts → transport-Vd7VdqHv.d.mts} +1 -1
  643. package/dist/{transport-DmlmzD2U.d.mts.map → transport-Vd7VdqHv.d.mts.map} +1 -1
  644. package/dist/{trusted-proxy-CSgZVESw.mjs → trusted-proxy-CwjQj0YG.mjs} +1 -1
  645. package/dist/{trusted-proxy-CSgZVESw.mjs.map → trusted-proxy-CwjQj0YG.mjs.map} +1 -1
  646. package/dist/{types-B6-N9cBB.d.mts → types-B4vm81VH.d.mts} +1 -1
  647. package/dist/{types-B6-N9cBB.d.mts.map → types-B4vm81VH.d.mts.map} +1 -1
  648. package/dist/{types-Cm4Cz-8M.d.mts → types-B97jg3aW.d.mts} +6 -1
  649. package/dist/{types-Cm4Cz-8M.d.mts.map → types-B97jg3aW.d.mts.map} +1 -1
  650. package/dist/{types-BNZsPL9z.mjs → types-BD40g7zz.mjs} +1 -1
  651. package/dist/{types-BNZsPL9z.mjs.map → types-BD40g7zz.mjs.map} +1 -1
  652. package/dist/{types-QnlQIyPE.d.mts → types-BNfPHfay.d.mts} +1 -1
  653. package/dist/{types-QnlQIyPE.d.mts.map → types-BNfPHfay.d.mts.map} +1 -1
  654. package/dist/{types-DLIrNtv5.d.mts → types-BfYUPJdP.d.mts} +2 -2
  655. package/dist/{types-DLIrNtv5.d.mts.map → types-BfYUPJdP.d.mts.map} +1 -1
  656. package/dist/{types-CtDVagM4.d.mts → types-BvB7gDOD.d.mts} +38 -4
  657. package/dist/types-BvB7gDOD.d.mts.map +1 -0
  658. package/dist/{types-B_pmP7Yq.d.mts → types-C7U0HlEr.d.mts} +1 -1
  659. package/dist/{types-B_pmP7Yq.d.mts.map → types-C7U0HlEr.d.mts.map} +1 -1
  660. package/dist/{types-Ch8pFMEm.mjs → types-CrRUFdej.mjs} +3 -3
  661. package/dist/{types-Ch8pFMEm.mjs.map → types-CrRUFdej.mjs.map} +1 -1
  662. package/dist/{types-momGysZk.d.mts → types-DPKhI5ib.d.mts} +9 -1
  663. package/dist/types-DPKhI5ib.d.mts.map +1 -0
  664. package/dist/{types-BCVuUPrL.d.mts → types-Kmaxdarz.d.mts} +1 -1
  665. package/dist/{types-BCVuUPrL.d.mts.map → types-Kmaxdarz.d.mts.map} +1 -1
  666. package/dist/{types-qljd1hsL.d.mts → types-iVeZ5g6N.d.mts} +1 -1
  667. package/dist/{types-qljd1hsL.d.mts.map → types-iVeZ5g6N.d.mts.map} +1 -1
  668. package/dist/{user-DTxX_Fha.mjs → user-aTXqmXBz.mjs} +3 -3
  669. package/dist/{user-DTxX_Fha.mjs.map → user-aTXqmXBz.mjs.map} +1 -1
  670. package/dist/{utils-Cz8PVrl4.mjs → utils-BbUgmeZG.mjs} +1 -1
  671. package/dist/{utils-Cz8PVrl4.mjs.map → utils-BbUgmeZG.mjs.map} +1 -1
  672. package/dist/{validate-C3CpWlNt.mjs → validate-CDT1jl6_.mjs} +11 -6
  673. package/dist/validate-CDT1jl6_.mjs.map +1 -0
  674. package/dist/{validate-9jLuE301.d.mts → validate-DULfgpJP.d.mts} +5 -5
  675. package/dist/{validate-9jLuE301.d.mts.map → validate-DULfgpJP.d.mts.map} +1 -1
  676. package/dist/{validation-DM2K_NJC.mjs → validation-DlD0E35W.mjs} +10 -10
  677. package/dist/{validation-DM2K_NJC.mjs.map → validation-DlD0E35W.mjs.map} +1 -1
  678. package/dist/version-Ci6bw6YK.mjs +7 -0
  679. package/dist/{version-BlIJvNAZ.mjs.map → version-Ci6bw6YK.mjs.map} +1 -1
  680. package/dist/{widgets-B_X6_UXJ.mjs → widgets-5fipNkMT.mjs} +3 -3
  681. package/dist/{widgets-B_X6_UXJ.mjs.map → widgets-5fipNkMT.mjs.map} +1 -1
  682. package/dist/{wxr-taxonomies-tADW4KTa.d.mts → wxr-taxonomies-B4tMuN5T.d.mts} +1 -1
  683. package/dist/{wxr-taxonomies-tADW4KTa.d.mts.map → wxr-taxonomies-B4tMuN5T.d.mts.map} +1 -1
  684. package/dist/{wxr-taxonomies-oNJB2S81.mjs → wxr-taxonomies-BmUnBNgz.mjs} +4 -4
  685. package/dist/{wxr-taxonomies-oNJB2S81.mjs.map → wxr-taxonomies-BmUnBNgz.mjs.map} +1 -1
  686. package/dist/{zod-generator-CrfV79De.mjs → zod-generator-CwkHWz4f.mjs} +2 -2
  687. package/dist/{zod-generator-CrfV79De.mjs.map → zod-generator-CwkHWz4f.mjs.map} +1 -1
  688. package/package.json +8 -8
  689. package/src/api/authorize.ts +10 -1
  690. package/src/api/error.ts +5 -5
  691. package/src/api/errors.ts +14 -0
  692. package/src/api/handlers/backup.ts +312 -0
  693. package/src/api/handlers/bylines.ts +5 -4
  694. package/src/api/handlers/content.ts +61 -9
  695. package/src/api/handlers/device-flow.ts +2 -3
  696. package/src/api/handlers/index.ts +16 -0
  697. package/src/api/handlers/marketplace.ts +38 -0
  698. package/src/api/handlers/media-upload.ts +210 -0
  699. package/src/api/handlers/media-usage.ts +211 -2
  700. package/src/api/handlers/menus.ts +11 -6
  701. package/src/api/handlers/oauth-authorization.ts +2 -6
  702. package/src/api/handlers/plugin-settings.ts +218 -0
  703. package/src/api/handlers/plugins.ts +41 -0
  704. package/src/api/handlers/registry.ts +39 -0
  705. package/src/api/handlers/relations.ts +7 -2
  706. package/src/api/handlers/snapshot.ts +21 -3
  707. package/src/api/handlers/taxonomies.ts +22 -14
  708. package/src/api/openapi/document.ts +48 -6
  709. package/src/api/parse.ts +1 -15
  710. package/src/api/public-url.ts +4 -2
  711. package/src/api/schemas/bylines.ts +4 -4
  712. package/src/api/schemas/common.ts +13 -8
  713. package/src/api/schemas/media-usage.ts +72 -0
  714. package/src/api/schemas/media.ts +32 -1
  715. package/src/api/schemas/menus.ts +2 -1
  716. package/src/api/schemas/relations.ts +3 -1
  717. package/src/api/schemas/taxonomies.ts +4 -2
  718. package/src/astro/integration/index.ts +38 -0
  719. package/src/astro/integration/routes.ts +35 -0
  720. package/src/astro/integration/runtime.ts +6 -0
  721. package/src/astro/integration/virtual-modules.ts +41 -7
  722. package/src/astro/integration/vite-config.ts +17 -1
  723. package/src/astro/middleware/auth.ts +70 -78
  724. package/src/astro/middleware/csp.ts +5 -2
  725. package/src/astro/middleware.ts +86 -31
  726. package/src/astro/public-plugin-api-routes.ts +2 -1
  727. package/src/astro/routes/PluginRegistry.tsx +5 -2
  728. package/src/astro/routes/admin.astro +56 -16
  729. package/src/astro/routes/api/admin/api-tokens/index.ts +2 -2
  730. package/src/astro/routes/api/admin/bylines/[id]/translations.ts +2 -5
  731. package/src/astro/routes/api/admin/bylines/index.ts +5 -8
  732. package/src/astro/routes/api/admin/plugins/[id]/index.ts +6 -0
  733. package/src/astro/routes/api/admin/plugins/[id]/mcp.ts +42 -0
  734. package/src/astro/routes/api/admin/plugins/[id]/settings.ts +80 -0
  735. package/src/astro/routes/api/admin/plugins/[id]/update.ts +2 -0
  736. package/src/astro/routes/api/admin/plugins/index.ts +9 -0
  737. package/src/astro/routes/api/admin/plugins/marketplace/[id]/install.ts +2 -0
  738. package/src/astro/routes/api/admin/plugins/registry/[id]/update.ts +2 -0
  739. package/src/astro/routes/api/admin/plugins/registry/install.ts +2 -0
  740. package/src/astro/routes/api/admin/plugins/updates.ts +2 -4
  741. package/src/astro/routes/api/auth/mode.ts +6 -14
  742. package/src/astro/routes/api/auth/oauth/[provider]/callback.ts +21 -4
  743. package/src/astro/routes/api/auth/oauth/[provider].ts +24 -6
  744. package/src/astro/routes/api/content/[collection]/[id]/compare.ts +3 -4
  745. package/src/astro/routes/api/content/[collection]/[id]/duplicate.ts +2 -3
  746. package/src/astro/routes/api/content/[collection]/[id]/permanent.ts +2 -3
  747. package/src/astro/routes/api/content/[collection]/[id]/preview-url.ts +3 -4
  748. package/src/astro/routes/api/content/[collection]/[id]/references/[relation]/children.ts +4 -6
  749. package/src/astro/routes/api/content/[collection]/[id]/references/[relation]/parents.ts +2 -3
  750. package/src/astro/routes/api/content/[collection]/[id]/revisions.ts +3 -4
  751. package/src/astro/routes/api/content/[collection]/[id]/terms/[taxonomy].ts +4 -6
  752. package/src/astro/routes/api/content/[collection]/[id]/translations.ts +3 -4
  753. package/src/astro/routes/api/content/[collection]/[id].ts +3 -4
  754. package/src/astro/routes/api/content/[collection]/authors.ts +2 -3
  755. package/src/astro/routes/api/content/[collection]/index.ts +6 -8
  756. package/src/astro/routes/api/content/[collection]/trash.ts +2 -3
  757. package/src/astro/routes/api/manifest.ts +2 -9
  758. package/src/astro/routes/api/mcp.ts +2 -1
  759. package/src/astro/routes/api/media/[id]/usage.ts +30 -0
  760. package/src/astro/routes/api/media/[id].ts +17 -6
  761. package/src/astro/routes/api/media/file/[...key].ts +8 -0
  762. package/src/astro/routes/api/media.ts +21 -2
  763. package/src/astro/routes/api/oauth/authorize.ts +43 -15
  764. package/src/astro/routes/api/plugins/[pluginId]/[...path].ts +17 -3
  765. package/src/astro/routes/api/settings/backups/archives/[name].ts +78 -0
  766. package/src/astro/routes/api/settings/backups/archives/index.ts +33 -0
  767. package/src/astro/routes/api/settings/backups/export.ts +43 -0
  768. package/src/astro/routes/api/settings/backups/index.ts +76 -0
  769. package/src/astro/routes/api/setup/admin-verify.ts +8 -4
  770. package/src/astro/routes/api/setup/admin.ts +11 -4
  771. package/src/astro/routes/api/well-known/oauth-authorization-server.ts +4 -1
  772. package/src/astro/routes/api/well-known/oauth-protected-resource.ts +5 -1
  773. package/src/astro/types.ts +48 -2
  774. package/src/auth/api-tokens.ts +1 -0
  775. package/src/auth/oauth-state-store.ts +3 -0
  776. package/src/auth/providers/github-admin.tsx +5 -6
  777. package/src/auth/providers/google-admin.tsx +5 -6
  778. package/src/auth/scopes.ts +3 -9
  779. package/src/cli/client-factory.ts +0 -1
  780. package/src/cli/commands/bundle-utils.ts +50 -1
  781. package/src/cli/commands/bundle.ts +9 -2
  782. package/src/cli/commands/media.ts +127 -0
  783. package/src/client/index.ts +84 -2
  784. package/src/client/transport.ts +1 -1
  785. package/src/components/EmDashHead.astro +4 -8
  786. package/src/components/Gallery.astro +141 -26
  787. package/src/components/InlinePortableTextEditor.tsx +56 -35
  788. package/src/components/marks/Link.astro +5 -1
  789. package/src/config/secrets.ts +25 -19
  790. package/src/content/converters/gallery.ts +61 -0
  791. package/src/content/converters/portable-text-to-prosemirror.ts +19 -0
  792. package/src/content/converters/prosemirror-to-portable-text.ts +18 -0
  793. package/src/content/converters/types.ts +36 -0
  794. package/src/database/dialect-helpers.ts +80 -7
  795. package/src/database/migrations/051_content_taxonomies_denorm.ts +120 -0
  796. package/src/database/migrations/052_media_usage_read_index.ts +26 -0
  797. package/src/database/migrations/053_plugin_mcp_tools.ts +21 -0
  798. package/src/database/migrations/runner.ts +6 -0
  799. package/src/database/pg-migration-lock.ts +1 -4
  800. package/src/database/repositories/audit.ts +2 -1
  801. package/src/database/repositories/content.ts +98 -16
  802. package/src/database/repositories/media-usage.ts +250 -1
  803. package/src/database/repositories/plugin-storage.ts +29 -32
  804. package/src/database/repositories/redirect.ts +14 -2
  805. package/src/database/repositories/taxonomy.ts +57 -8
  806. package/src/database/types.ts +23 -0
  807. package/src/db/adapters.ts +9 -0
  808. package/src/emdash-runtime.ts +365 -83
  809. package/src/i18n/config.ts +8 -0
  810. package/src/i18n/repair-locale-casing.ts +51 -0
  811. package/src/loader.ts +292 -1
  812. package/src/mcp/server.ts +222 -5
  813. package/src/media/image-endpoint.ts +38 -2
  814. package/src/page/metadata.ts +27 -0
  815. package/src/plugin-types.ts +19 -0
  816. package/src/plugin-utils.ts +8 -6
  817. package/src/plugins/adapt-sandbox-entry.ts +30 -1
  818. package/src/plugins/context.ts +7 -0
  819. package/src/plugins/define-plugin.ts +16 -0
  820. package/src/plugins/manifest-schema.ts +28 -1
  821. package/src/plugins/routes.ts +27 -1
  822. package/src/plugins/sandbox/runner-options.ts +16 -0
  823. package/src/plugins/sandbox/types.ts +6 -1
  824. package/src/plugins/state.ts +17 -1
  825. package/src/plugins/storage-query.ts +67 -33
  826. package/src/plugins/types.ts +41 -0
  827. package/src/schema/registry.ts +141 -5
  828. package/src/search/query.ts +3 -2
  829. package/src/seed/apply.ts +37 -36
  830. package/src/seed/validate.ts +15 -4
  831. package/src/seo/index.ts +19 -4
  832. package/src/storage/types.ts +6 -0
  833. package/src/utils/base64.ts +7 -2
  834. package/src/utils/db-errors.ts +3 -1
  835. package/src/virtual-modules.d.ts +13 -0
  836. package/src/visual-editing/toolbar.ts +1 -1
  837. package/dist/adapters-DPAkL6QF.d.mts.map +0 -1
  838. package/dist/api-DVbHNApo.mjs.map +0 -1
  839. package/dist/api-tokens-Dk2GrJMY.mjs +0 -3
  840. package/dist/apply-D23iUV4q.mjs.map +0 -1
  841. package/dist/authorize-BmCwQCib.mjs.map +0 -1
  842. package/dist/base64-C74Msx8h.mjs.map +0 -1
  843. package/dist/bylines-BGuKFaBy.mjs.map +0 -1
  844. package/dist/config-CVssduLe.mjs.map +0 -1
  845. package/dist/content-BO61Sx4j.mjs.map +0 -1
  846. package/dist/content-refresh-BkkApzeS.mjs.map +0 -1
  847. package/dist/context-DtSFYFuS.mjs.map +0 -1
  848. package/dist/db-errors-BKuXh_fi.mjs.map +0 -1
  849. package/dist/device-flow-CPXQ_QfW.mjs.map +0 -1
  850. package/dist/dialect-helpers-Cue7QQOR.mjs.map +0 -1
  851. package/dist/error-CfJMLSkd.mjs.map +0 -1
  852. package/dist/index-BXOCyLj0.d.mts.map +0 -1
  853. package/dist/loader-Rb8QlGZp.mjs.map +0 -1
  854. package/dist/manifest-schema-DeGNma2O.mjs.map +0 -1
  855. package/dist/menus-BpfevlJD.mjs.map +0 -1
  856. package/dist/menus-BtvH7Z7t.mjs.map +0 -1
  857. package/dist/oauth-authorization-BWqWTHBK.mjs.map +0 -1
  858. package/dist/public-url-C0cEvrRu.mjs.map +0 -1
  859. package/dist/redirect-Ch3E98qZ.mjs.map +0 -1
  860. package/dist/redirects-CeD7K7EX.mjs.map +0 -1
  861. package/dist/registry-CyIXPi4E.mjs.map +0 -1
  862. package/dist/relations-C8hVyEy0.mjs.map +0 -1
  863. package/dist/relations-CbBpoOys.d.mts.map +0 -1
  864. package/dist/runner-jt65bF7F.mjs.map +0 -1
  865. package/dist/scheduled-publish-DlJHGcuL.d.mts +0 -11
  866. package/dist/scheduled-publish-DlJHGcuL.d.mts.map +0 -1
  867. package/dist/search-Cl875CVE.mjs.map +0 -1
  868. package/dist/secrets-CO_bEmII.mjs.map +0 -1
  869. package/dist/taxonomies-ClS4RKaZ.mjs.map +0 -1
  870. package/dist/taxonomy-BkxbUMSw.mjs.map +0 -1
  871. package/dist/types-CtDVagM4.d.mts.map +0 -1
  872. package/dist/types-momGysZk.d.mts.map +0 -1
  873. package/dist/validate-C3CpWlNt.mjs.map +0 -1
  874. package/dist/version-BlIJvNAZ.mjs +0 -7
  875. /package/dist/{ssrf-B5DOv5E5.mjs → ssrf-BB__xfNM.mjs} +0 -0
  876. /package/dist/{types-DeCZBZxn.mjs → types-CK0LxPUQ.mjs} +0 -0
@@ -0,0 +1 @@
1
+ {"version":3,"file":"_name_.mjs","names":[],"sources":["../../../../../../../src/astro/routes/api/settings/backups/archives/[name].ts"],"sourcesContent":["/**\n * Backup archives — download / delete\n *\n * GET /_emdash/api/settings/backups/archives/:name — download an archive.\n * DELETE /_emdash/api/settings/backups/archives/:name — delete an archive.\n *\n * `name` is validated against the strict archive-filename pattern before it\n * touches a storage key, so path traversal into other prefixes is impossible.\n */\n\nimport type { APIRoute } from \"astro\";\n\nimport { requirePerm } from \"#api/authorize.js\";\nimport { apiError, handleError, unwrapResult } from \"#api/error.js\";\nimport { ErrorCode } from \"#api/errors.js\";\nimport {\n\tBACKUP_STORAGE_PREFIX,\n\tdeleteBackupArchive,\n\tisValidArchiveName,\n} from \"#api/handlers/backup.js\";\n\nexport const prerender = false;\n\nexport const GET: APIRoute = async ({ params, locals }) => {\n\tconst { emdash, user } = locals;\n\tconst name = params.name ?? \"\";\n\n\tif (!emdash?.db) {\n\t\treturn apiError(\"NOT_CONFIGURED\", \"EmDash is not initialized\", 500);\n\t}\n\n\tconst denied = requirePerm(user, \"backups:manage\");\n\tif (denied) return denied;\n\n\tif (!emdash.storage) {\n\t\treturn apiError(\"STORAGE_NOT_CONFIGURED\", \"No storage backend is configured\", 503);\n\t}\n\n\tif (!isValidArchiveName(name)) {\n\t\treturn apiError(\"VALIDATION_ERROR\", \"Invalid archive name\", 400);\n\t}\n\n\ttry {\n\t\tconst result = await emdash.storage.download(`${BACKUP_STORAGE_PREFIX}${name}`);\n\t\treturn new Response(result.body, {\n\t\t\tstatus: 200,\n\t\t\theaders: {\n\t\t\t\t\"Content-Type\": \"application/json\",\n\t\t\t\t\"Content-Disposition\": `attachment; filename=\"${name}\"`,\n\t\t\t\t\"Cache-Control\": \"private, no-store\",\n\t\t\t\t\"X-Content-Type-Options\": \"nosniff\",\n\t\t\t},\n\t\t});\n\t} catch (error) {\n\t\tif (error instanceof Error && error.message.toLowerCase().includes(\"not found\")) {\n\t\t\treturn apiError(\"NOT_FOUND\", \"Archive not found\", 404);\n\t\t}\n\t\treturn handleError(error, \"Failed to download archive\", ErrorCode.BACKUP_DOWNLOAD_ERROR);\n\t}\n};\n\nexport const DELETE: APIRoute = async ({ params, locals }) => {\n\tconst { emdash, user } = locals;\n\tconst name = params.name ?? \"\";\n\n\tif (!emdash?.db) {\n\t\treturn apiError(\"NOT_CONFIGURED\", \"EmDash is not initialized\", 500);\n\t}\n\n\tconst denied = requirePerm(user, \"backups:manage\");\n\tif (denied) return denied;\n\n\tif (!emdash.storage) {\n\t\treturn apiError(\"STORAGE_NOT_CONFIGURED\", \"No storage backend is configured\", 503);\n\t}\n\n\treturn unwrapResult(await deleteBackupArchive(emdash.storage, name));\n};\n"],"mappings":";;;;;;;;;;AAqBA,MAAa,YAAY;AAEzB,MAAa,MAAgB,OAAO,EAAE,QAAQ,aAAa;CAC1D,MAAM,EAAE,QAAQ,SAAS;CACzB,MAAM,OAAO,OAAO,QAAQ;AAE5B,KAAI,CAAC,QAAQ,GACZ,QAAO,SAAS,kBAAkB,6BAA6B,IAAI;CAGpE,MAAM,SAAS,YAAY,MAAM,iBAAiB;AAClD,KAAI,OAAQ,QAAO;AAEnB,KAAI,CAAC,OAAO,QACX,QAAO,SAAS,0BAA0B,oCAAoC,IAAI;AAGnF,KAAI,CAAC,mBAAmB,KAAK,CAC5B,QAAO,SAAS,oBAAoB,wBAAwB,IAAI;AAGjE,KAAI;EACH,MAAM,SAAS,MAAM,OAAO,QAAQ,SAAS,GAAG,wBAAwB,OAAO;AAC/E,SAAO,IAAI,SAAS,OAAO,MAAM;GAChC,QAAQ;GACR,SAAS;IACR,gBAAgB;IAChB,uBAAuB,yBAAyB,KAAK;IACrD,iBAAiB;IACjB,0BAA0B;IAC1B;GACD,CAAC;UACM,OAAO;AACf,MAAI,iBAAiB,SAAS,MAAM,QAAQ,aAAa,CAAC,SAAS,YAAY,CAC9E,QAAO,SAAS,aAAa,qBAAqB,IAAI;AAEvD,SAAO,YAAY,OAAO,8BAA8B,UAAU,sBAAsB;;;AAI1F,MAAa,SAAmB,OAAO,EAAE,QAAQ,aAAa;CAC7D,MAAM,EAAE,QAAQ,SAAS;CACzB,MAAM,OAAO,OAAO,QAAQ;AAE5B,KAAI,CAAC,QAAQ,GACZ,QAAO,SAAS,kBAAkB,6BAA6B,IAAI;CAGpE,MAAM,SAAS,YAAY,MAAM,iBAAiB;AAClD,KAAI,OAAQ,QAAO;AAEnB,KAAI,CAAC,OAAO,QACX,QAAO,SAAS,0BAA0B,oCAAoC,IAAI;AAGnF,QAAO,aAAa,MAAM,oBAAoB,OAAO,SAAS,KAAK,CAAC"}
@@ -0,0 +1,8 @@
1
+ import { APIRoute } from "astro";
2
+
3
+ //#region src/astro/routes/api/settings/backups/archives/index.d.ts
4
+ declare const prerender = false;
5
+ declare const POST: APIRoute;
6
+ //#endregion
7
+ export { POST, prerender };
8
+ //# sourceMappingURL=index.d.mts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.mts","names":[],"sources":["../../../../../../../src/astro/routes/api/settings/backups/archives/index.ts"],"mappings":";;;cAca,SAAA;AAAA,cAEA,IAAA,EAAM,QAAA"}
@@ -0,0 +1,23 @@
1
+ import "../../../../../../base64-B-PsqheR.mjs";
2
+ import "../../../../../../types-CrRUFdej.mjs";
3
+ import "../../../../../../options-BlmBHTvX.mjs";
4
+ import { a as unwrapResult, t as apiError } from "../../../../../../error-DJ98TRbQ.mjs";
5
+ import "../../../../../../snapshot-BdpUJKD-.mjs";
6
+ import { d as runBackupToStorage, s as getBackupSettings } from "../../../../../../backup-Qr9PaGUo.mjs";
7
+ import { r as requirePerm } from "../../../../../../authorize-6WPZa1xZ.mjs";
8
+
9
+ //#region src/astro/routes/api/settings/backups/archives/index.ts
10
+ const prerender = false;
11
+ const POST = async ({ locals }) => {
12
+ const { emdash, user } = locals;
13
+ if (!emdash?.db) return apiError("NOT_CONFIGURED", "EmDash is not initialized", 500);
14
+ const denied = requirePerm(user, "backups:manage");
15
+ if (denied) return denied;
16
+ if (!emdash.storage) return apiError("STORAGE_NOT_CONFIGURED", "No storage backend is configured", 503);
17
+ const settings = await getBackupSettings(emdash.db);
18
+ return unwrapResult(await runBackupToStorage(emdash.db, emdash.storage, settings.retention), 201);
19
+ };
20
+
21
+ //#endregion
22
+ export { POST, prerender };
23
+ //# sourceMappingURL=index.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.mjs","names":[],"sources":["../../../../../../../src/astro/routes/api/settings/backups/archives/index.ts"],"sourcesContent":["/**\n * Backup archives — create\n *\n * POST /_emdash/api/settings/backups/archives — generate a backup and store\n * it in the storage backend under `backups/`, pruning archives beyond the\n * configured retention.\n */\n\nimport type { APIRoute } from \"astro\";\n\nimport { requirePerm } from \"#api/authorize.js\";\nimport { apiError, unwrapResult } from \"#api/error.js\";\nimport { getBackupSettings, runBackupToStorage } from \"#api/handlers/backup.js\";\n\nexport const prerender = false;\n\nexport const POST: APIRoute = async ({ locals }) => {\n\tconst { emdash, user } = locals;\n\n\tif (!emdash?.db) {\n\t\treturn apiError(\"NOT_CONFIGURED\", \"EmDash is not initialized\", 500);\n\t}\n\n\tconst denied = requirePerm(user, \"backups:manage\");\n\tif (denied) return denied;\n\n\tif (!emdash.storage) {\n\t\treturn apiError(\"STORAGE_NOT_CONFIGURED\", \"No storage backend is configured\", 503);\n\t}\n\n\tconst settings = await getBackupSettings(emdash.db);\n\treturn unwrapResult(await runBackupToStorage(emdash.db, emdash.storage, settings.retention), 201);\n};\n"],"mappings":";;;;;;;;;AAcA,MAAa,YAAY;AAEzB,MAAa,OAAiB,OAAO,EAAE,aAAa;CACnD,MAAM,EAAE,QAAQ,SAAS;AAEzB,KAAI,CAAC,QAAQ,GACZ,QAAO,SAAS,kBAAkB,6BAA6B,IAAI;CAGpE,MAAM,SAAS,YAAY,MAAM,iBAAiB;AAClD,KAAI,OAAQ,QAAO;AAEnB,KAAI,CAAC,OAAO,QACX,QAAO,SAAS,0BAA0B,oCAAoC,IAAI;CAGnF,MAAM,WAAW,MAAM,kBAAkB,OAAO,GAAG;AACnD,QAAO,aAAa,MAAM,mBAAmB,OAAO,IAAI,OAAO,SAAS,SAAS,UAAU,EAAE,IAAI"}
@@ -0,0 +1,8 @@
1
+ import { APIRoute } from "astro";
2
+
3
+ //#region src/astro/routes/api/settings/backups/export.d.ts
4
+ declare const prerender = false;
5
+ declare const GET: APIRoute;
6
+ //#endregion
7
+ export { GET, prerender };
8
+ //# sourceMappingURL=export.d.mts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"export.d.mts","names":[],"sources":["../../../../../../src/astro/routes/api/settings/backups/export.ts"],"mappings":";;;cAea,SAAA;AAAA,cAEA,GAAA,EAAK,QAAA"}
@@ -0,0 +1,35 @@
1
+ import "../../../../../base64-B-PsqheR.mjs";
2
+ import "../../../../../types-CrRUFdej.mjs";
3
+ import "../../../../../options-BlmBHTvX.mjs";
4
+ import { t as ErrorCode } from "../../../../../errors-DtEXIQQV.mjs";
5
+ import { r as handleError, t as apiError } from "../../../../../error-DJ98TRbQ.mjs";
6
+ import "../../../../../snapshot-BdpUJKD-.mjs";
7
+ import { i as archiveNameForDate, o as generateBackupJson } from "../../../../../backup-Qr9PaGUo.mjs";
8
+ import { r as requirePerm } from "../../../../../authorize-6WPZa1xZ.mjs";
9
+
10
+ //#region src/astro/routes/api/settings/backups/export.ts
11
+ const prerender = false;
12
+ const GET = async ({ locals }) => {
13
+ const { emdash, user } = locals;
14
+ if (!emdash?.db) return apiError("NOT_CONFIGURED", "EmDash is not initialized", 500);
15
+ const denied = requirePerm(user, "backups:manage");
16
+ if (denied) return denied;
17
+ try {
18
+ const json = await generateBackupJson(emdash.db);
19
+ return new Response(json, {
20
+ status: 200,
21
+ headers: {
22
+ "Content-Type": "application/json",
23
+ "Content-Disposition": `attachment; filename="${archiveNameForDate(/* @__PURE__ */ new Date())}"`,
24
+ "Cache-Control": "private, no-store",
25
+ "X-Content-Type-Options": "nosniff"
26
+ }
27
+ });
28
+ } catch (error) {
29
+ return handleError(error, "Failed to generate backup", ErrorCode.BACKUP_EXPORT_ERROR);
30
+ }
31
+ };
32
+
33
+ //#endregion
34
+ export { GET, prerender };
35
+ //# sourceMappingURL=export.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"export.mjs","names":[],"sources":["../../../../../../src/astro/routes/api/settings/backups/export.ts"],"sourcesContent":["/**\n * One-click backup download\n *\n * GET /_emdash/api/settings/backups/export — generate a fresh backup and\n * stream it as a JSON download. Read-only (nothing is stored), so GET is\n * appropriate despite the cost of generating the payload.\n */\n\nimport type { APIRoute } from \"astro\";\n\nimport { requirePerm } from \"#api/authorize.js\";\nimport { apiError, handleError } from \"#api/error.js\";\nimport { ErrorCode } from \"#api/errors.js\";\nimport { archiveNameForDate, generateBackupJson } from \"#api/handlers/backup.js\";\n\nexport const prerender = false;\n\nexport const GET: APIRoute = async ({ locals }) => {\n\tconst { emdash, user } = locals;\n\n\tif (!emdash?.db) {\n\t\treturn apiError(\"NOT_CONFIGURED\", \"EmDash is not initialized\", 500);\n\t}\n\n\tconst denied = requirePerm(user, \"backups:manage\");\n\tif (denied) return denied;\n\n\ttry {\n\t\tconst json = await generateBackupJson(emdash.db);\n\t\treturn new Response(json, {\n\t\t\tstatus: 200,\n\t\t\theaders: {\n\t\t\t\t\"Content-Type\": \"application/json\",\n\t\t\t\t\"Content-Disposition\": `attachment; filename=\"${archiveNameForDate(new Date())}\"`,\n\t\t\t\t// Session-specific full-content export — never cacheable anywhere.\n\t\t\t\t\"Cache-Control\": \"private, no-store\",\n\t\t\t\t\"X-Content-Type-Options\": \"nosniff\",\n\t\t\t},\n\t\t});\n\t} catch (error) {\n\t\treturn handleError(error, \"Failed to generate backup\", ErrorCode.BACKUP_EXPORT_ERROR);\n\t}\n};\n"],"mappings":";;;;;;;;;;AAeA,MAAa,YAAY;AAEzB,MAAa,MAAgB,OAAO,EAAE,aAAa;CAClD,MAAM,EAAE,QAAQ,SAAS;AAEzB,KAAI,CAAC,QAAQ,GACZ,QAAO,SAAS,kBAAkB,6BAA6B,IAAI;CAGpE,MAAM,SAAS,YAAY,MAAM,iBAAiB;AAClD,KAAI,OAAQ,QAAO;AAEnB,KAAI;EACH,MAAM,OAAO,MAAM,mBAAmB,OAAO,GAAG;AAChD,SAAO,IAAI,SAAS,MAAM;GACzB,QAAQ;GACR,SAAS;IACR,gBAAgB;IAChB,uBAAuB,yBAAyB,mCAAmB,IAAI,MAAM,CAAC,CAAC;IAE/E,iBAAiB;IACjB,0BAA0B;IAC1B;GACD,CAAC;UACM,OAAO;AACf,SAAO,YAAY,OAAO,6BAA6B,UAAU,oBAAoB"}
@@ -0,0 +1,9 @@
1
+ import { APIRoute } from "astro";
2
+
3
+ //#region src/astro/routes/api/settings/backups/index.d.ts
4
+ declare const prerender = false;
5
+ declare const GET: APIRoute;
6
+ declare const PUT: APIRoute;
7
+ //#endregion
8
+ export { GET, PUT, prerender };
9
+ //# sourceMappingURL=index.d.mts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.mts","names":[],"sources":["../../../../../../src/astro/routes/api/settings/backups/index.ts"],"mappings":";;;cAwBa,SAAA;AAAA,cAEA,GAAA,EAAK,QAAA;AAAA,cAmCL,GAAA,EAAK,QAAA"}
@@ -0,0 +1,52 @@
1
+ import "../../../../../base64-B-PsqheR.mjs";
2
+ import "../../../../../types-CrRUFdej.mjs";
3
+ import "../../../../../options-BlmBHTvX.mjs";
4
+ import { t as ErrorCode } from "../../../../../errors-DtEXIQQV.mjs";
5
+ import { a as unwrapResult, n as apiSuccess, r as handleError, t as apiError } from "../../../../../error-DJ98TRbQ.mjs";
6
+ import { n as parseBody, t as isParseError } from "../../../../../parse-53zyxlpv.mjs";
7
+ import "../../../../../snapshot-BdpUJKD-.mjs";
8
+ import { f as updateBackupSettings, l as listBackupArchives, n as BACKUP_RETENTION_MIN, s as getBackupSettings, t as BACKUP_RETENTION_MAX } from "../../../../../backup-Qr9PaGUo.mjs";
9
+ import { r as requirePerm } from "../../../../../authorize-6WPZa1xZ.mjs";
10
+ import { z } from "zod";
11
+
12
+ //#region src/astro/routes/api/settings/backups/index.ts
13
+ const prerender = false;
14
+ const GET = async ({ locals }) => {
15
+ const { emdash, user } = locals;
16
+ if (!emdash?.db) return apiError("NOT_CONFIGURED", "EmDash is not initialized", 500);
17
+ const denied = requirePerm(user, "backups:manage");
18
+ if (denied) return denied;
19
+ try {
20
+ const settings = await getBackupSettings(emdash.db);
21
+ let archives = [];
22
+ const storageAvailable = !!emdash.storage;
23
+ if (emdash.storage) {
24
+ const listed = await listBackupArchives(emdash.storage);
25
+ if (listed.success) archives = listed.data;
26
+ }
27
+ return apiSuccess({
28
+ settings,
29
+ archives,
30
+ storageAvailable
31
+ });
32
+ } catch (error) {
33
+ return handleError(error, "Failed to load backup settings", ErrorCode.BACKUP_SETTINGS_READ_ERROR);
34
+ }
35
+ };
36
+ const settingsBody = z.object({
37
+ enabled: z.boolean(),
38
+ retention: z.number().int().min(BACKUP_RETENTION_MIN).max(BACKUP_RETENTION_MAX)
39
+ });
40
+ const PUT = async ({ request, locals }) => {
41
+ const { emdash, user } = locals;
42
+ if (!emdash?.db) return apiError("NOT_CONFIGURED", "EmDash is not initialized", 500);
43
+ const denied = requirePerm(user, "backups:manage");
44
+ if (denied) return denied;
45
+ const body = await parseBody(request, settingsBody);
46
+ if (isParseError(body)) return body;
47
+ return unwrapResult(await updateBackupSettings(emdash.db, body));
48
+ };
49
+
50
+ //#endregion
51
+ export { GET, PUT, prerender };
52
+ //# sourceMappingURL=index.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.mjs","names":[],"sources":["../../../../../../src/astro/routes/api/settings/backups/index.ts"],"sourcesContent":["/**\n * Backup settings + archive listing\n *\n * GET /_emdash/api/settings/backups — scheduled-backup settings, stored\n * archives, and whether a storage backend is available.\n * PUT /_emdash/api/settings/backups — update scheduled-backup settings.\n */\n\nimport type { APIRoute } from \"astro\";\nimport { z } from \"zod\";\n\nimport { requirePerm } from \"#api/authorize.js\";\nimport { apiError, apiSuccess, handleError, unwrapResult } from \"#api/error.js\";\nimport { ErrorCode } from \"#api/errors.js\";\nimport {\n\tBACKUP_RETENTION_MAX,\n\tBACKUP_RETENTION_MIN,\n\tgetBackupSettings,\n\tlistBackupArchives,\n\tupdateBackupSettings,\n\ttype BackupArchive,\n} from \"#api/handlers/backup.js\";\nimport { isParseError, parseBody } from \"#api/parse.js\";\n\nexport const prerender = false;\n\nexport const GET: APIRoute = async ({ locals }) => {\n\tconst { emdash, user } = locals;\n\n\tif (!emdash?.db) {\n\t\treturn apiError(\"NOT_CONFIGURED\", \"EmDash is not initialized\", 500);\n\t}\n\n\tconst denied = requirePerm(user, \"backups:manage\");\n\tif (denied) return denied;\n\n\ttry {\n\t\tconst settings = await getBackupSettings(emdash.db);\n\n\t\tlet archives: BackupArchive[] = [];\n\t\tconst storageAvailable = !!emdash.storage;\n\t\tif (emdash.storage) {\n\t\t\tconst listed = await listBackupArchives(emdash.storage);\n\t\t\tif (listed.success) archives = listed.data;\n\t\t}\n\n\t\treturn apiSuccess({ settings, archives, storageAvailable });\n\t} catch (error) {\n\t\treturn handleError(\n\t\t\terror,\n\t\t\t\"Failed to load backup settings\",\n\t\t\tErrorCode.BACKUP_SETTINGS_READ_ERROR,\n\t\t);\n\t}\n};\n\nconst settingsBody = z.object({\n\tenabled: z.boolean(),\n\tretention: z.number().int().min(BACKUP_RETENTION_MIN).max(BACKUP_RETENTION_MAX),\n});\n\nexport const PUT: APIRoute = async ({ request, locals }) => {\n\tconst { emdash, user } = locals;\n\n\tif (!emdash?.db) {\n\t\treturn apiError(\"NOT_CONFIGURED\", \"EmDash is not initialized\", 500);\n\t}\n\n\tconst denied = requirePerm(user, \"backups:manage\");\n\tif (denied) return denied;\n\n\tconst body = await parseBody(request, settingsBody);\n\tif (isParseError(body)) return body;\n\n\treturn unwrapResult(await updateBackupSettings(emdash.db, body));\n};\n"],"mappings":";;;;;;;;;;;;AAwBA,MAAa,YAAY;AAEzB,MAAa,MAAgB,OAAO,EAAE,aAAa;CAClD,MAAM,EAAE,QAAQ,SAAS;AAEzB,KAAI,CAAC,QAAQ,GACZ,QAAO,SAAS,kBAAkB,6BAA6B,IAAI;CAGpE,MAAM,SAAS,YAAY,MAAM,iBAAiB;AAClD,KAAI,OAAQ,QAAO;AAEnB,KAAI;EACH,MAAM,WAAW,MAAM,kBAAkB,OAAO,GAAG;EAEnD,IAAI,WAA4B,EAAE;EAClC,MAAM,mBAAmB,CAAC,CAAC,OAAO;AAClC,MAAI,OAAO,SAAS;GACnB,MAAM,SAAS,MAAM,mBAAmB,OAAO,QAAQ;AACvD,OAAI,OAAO,QAAS,YAAW,OAAO;;AAGvC,SAAO,WAAW;GAAE;GAAU;GAAU;GAAkB,CAAC;UACnD,OAAO;AACf,SAAO,YACN,OACA,kCACA,UAAU,2BACV;;;AAIH,MAAM,eAAe,EAAE,OAAO;CAC7B,SAAS,EAAE,SAAS;CACpB,WAAW,EAAE,QAAQ,CAAC,KAAK,CAAC,IAAI,qBAAqB,CAAC,IAAI,qBAAqB;CAC/E,CAAC;AAEF,MAAa,MAAgB,OAAO,EAAE,SAAS,aAAa;CAC3D,MAAM,EAAE,QAAQ,SAAS;AAEzB,KAAI,CAAC,QAAQ,GACZ,QAAO,SAAS,kBAAkB,6BAA6B,IAAI;CAGpE,MAAM,SAAS,YAAY,MAAM,iBAAiB;AAClD,KAAI,OAAQ,QAAO;CAEnB,MAAM,OAAO,MAAM,UAAU,SAAS,aAAa;AACnD,KAAI,aAAa,KAAK,CAAE,QAAO;AAE/B,QAAO,aAAa,MAAM,qBAAqB,OAAO,IAAI,KAAK,CAAC"}
@@ -1,9 +1,9 @@
1
- import "../../../../base64-C74Msx8h.mjs";
2
- import "../../../../types-Ch8pFMEm.mjs";
1
+ import "../../../../base64-B-PsqheR.mjs";
2
+ import "../../../../types-CrRUFdej.mjs";
3
3
  import { t as OptionsRepository } from "../../../../options-BlmBHTvX.mjs";
4
- import { n as apiSuccess, r as handleError, t as apiError } from "../../../../error-CfJMLSkd.mjs";
5
- import { n as parseBody, t as isParseError } from "../../../../parse-GLksnn-B.mjs";
6
- import { n as requirePerm } from "../../../../authorize-BmCwQCib.mjs";
4
+ import { n as apiSuccess, r as handleError, t as apiError } from "../../../../error-DJ98TRbQ.mjs";
5
+ import { n as parseBody, t as isParseError } from "../../../../parse-53zyxlpv.mjs";
6
+ import { r as requirePerm } from "../../../../authorize-6WPZa1xZ.mjs";
7
7
  import { z } from "zod";
8
8
  import { escapeHtml } from "@emdash-cms/auth";
9
9
 
@@ -1,21 +1,22 @@
1
- import "../../../dialect-helpers-Cue7QQOR.mjs";
1
+ import "../../../dialect-helpers-BtOwo2us.mjs";
2
2
  import "../../../after-B1IIdH3Y.mjs";
3
3
  import "../../../object-cache-Bok5j2ae.mjs";
4
- import "../../../base64-C74Msx8h.mjs";
5
- import "../../../types-Ch8pFMEm.mjs";
6
- import "../../../media-D2ZFowpn.mjs";
4
+ import "../../../base64-B-PsqheR.mjs";
5
+ import "../../../types-CrRUFdej.mjs";
6
+ import "../../../media-its1WLYv.mjs";
7
7
  import "../../../options-BlmBHTvX.mjs";
8
8
  import "../../../request-cache-BSUptuJR.mjs";
9
- import "../../../loader-Rb8QlGZp.mjs";
10
- import { a as unwrapResult, r as handleError, t as apiError } from "../../../error-CfJMLSkd.mjs";
11
- import "../../../settings-BuQYvLfy.mjs";
12
- import { n as handleSettingsUpdate, t as handleSettingsGet } from "../../../settings-CmS3TwXf.mjs";
13
- import { n as parseBody, t as isParseError } from "../../../parse-GLksnn-B.mjs";
14
- import { P as settingsUpdateBody } from "../../../redirects-CeD7K7EX.mjs";
15
- import "../../../relations-BmBmX4Eb.mjs";
16
- import "../../../status-D3Gy1Zc6.mjs";
9
+ import "../../../loader-D4rigvjR.mjs";
10
+ import "../../../settings-C2PaBS49.mjs";
11
+ import { n as handleSettingsUpdate, t as handleSettingsGet } from "../../../settings-Dtc0DU31.mjs";
12
+ import { a as unwrapResult, r as handleError, t as apiError } from "../../../error-DJ98TRbQ.mjs";
13
+ import { n as parseBody, t as isParseError } from "../../../parse-53zyxlpv.mjs";
14
+ import "../../../media-BJ6SRY3g.mjs";
15
+ import { P as settingsUpdateBody } from "../../../redirects-D457qwt0.mjs";
16
+ import "../../../relations-CZMpBqEd.mjs";
17
+ import "../../../status-COfycGIU.mjs";
17
18
  import "../../../api/schemas/index.mjs";
18
- import { n as requirePerm } from "../../../authorize-BmCwQCib.mjs";
19
+ import { r as requirePerm } from "../../../authorize-6WPZa1xZ.mjs";
19
20
 
20
21
  //#region src/astro/routes/api/settings.ts
21
22
  const prerender = false;
@@ -1 +1 @@
1
- {"version":3,"file":"settings.mjs","names":[],"sources":["../../../../src/astro/routes/api/settings.ts"],"sourcesContent":["/**\n * Site Settings API endpoint\n *\n * GET /_emdash/api/settings - Get all site settings\n * POST /_emdash/api/settings - Update site settings\n */\n\nimport type { APIRoute } from \"astro\";\n\nimport { requirePerm } from \"#api/authorize.js\";\nimport { apiError, handleError, unwrapResult } from \"#api/error.js\";\nimport { handleSettingsGet, handleSettingsUpdate } from \"#api/handlers/settings.js\";\nimport { isParseError, parseBody } from \"#api/parse.js\";\nimport { settingsUpdateBody } from \"#api/schemas.js\";\n\nexport const prerender = false;\n\n/**\n * GET /_emdash/api/settings\n *\n * Returns all site settings as a JSON object.\n * Unset values are undefined. Media references include resolved URLs.\n */\nexport const GET: APIRoute = async ({ locals }) => {\n\tconst { emdash, user } = locals;\n\n\tif (!emdash?.db) {\n\t\treturn apiError(\"NOT_CONFIGURED\", \"EmDash is not initialized\", 500);\n\t}\n\n\tconst denied = requirePerm(user, \"settings:read\");\n\tif (denied) return denied;\n\n\ttry {\n\t\tconst result = await handleSettingsGet(emdash.db, emdash.storage);\n\t\treturn unwrapResult(result);\n\t} catch (error) {\n\t\treturn handleError(error, \"Failed to get settings\", \"SETTINGS_READ_ERROR\");\n\t}\n};\n\n/**\n * POST /_emdash/api/settings\n *\n * Updates site settings. Accepts a partial settings object.\n * Merges with existing settings and returns the updated settings.\n */\nexport const POST: APIRoute = async ({ request, locals }) => {\n\tconst { emdash, user } = locals;\n\n\tif (!emdash?.db) {\n\t\treturn apiError(\"NOT_CONFIGURED\", \"EmDash is not initialized\", 500);\n\t}\n\n\tconst denied = requirePerm(user, \"settings:manage\");\n\tif (denied) return denied;\n\n\ttry {\n\t\tconst body = await parseBody(request, settingsUpdateBody);\n\t\tif (isParseError(body)) return body;\n\n\t\tconst result = await handleSettingsUpdate(emdash.db, emdash.storage, body);\n\t\treturn unwrapResult(result);\n\t} catch (error) {\n\t\treturn handleError(error, \"Failed to update settings\", \"SETTINGS_UPDATE_ERROR\");\n\t}\n};\n"],"mappings":";;;;;;;;;;;;;;;;;;;;AAeA,MAAa,YAAY;;;;;;;AAQzB,MAAa,MAAgB,OAAO,EAAE,aAAa;CAClD,MAAM,EAAE,QAAQ,SAAS;AAEzB,KAAI,CAAC,QAAQ,GACZ,QAAO,SAAS,kBAAkB,6BAA6B,IAAI;CAGpE,MAAM,SAAS,YAAY,MAAM,gBAAgB;AACjD,KAAI,OAAQ,QAAO;AAEnB,KAAI;AAEH,SAAO,aADQ,MAAM,kBAAkB,OAAO,IAAI,OAAO,QAAQ,CACtC;UACnB,OAAO;AACf,SAAO,YAAY,OAAO,0BAA0B,sBAAsB;;;;;;;;;AAU5E,MAAa,OAAiB,OAAO,EAAE,SAAS,aAAa;CAC5D,MAAM,EAAE,QAAQ,SAAS;AAEzB,KAAI,CAAC,QAAQ,GACZ,QAAO,SAAS,kBAAkB,6BAA6B,IAAI;CAGpE,MAAM,SAAS,YAAY,MAAM,kBAAkB;AACnD,KAAI,OAAQ,QAAO;AAEnB,KAAI;EACH,MAAM,OAAO,MAAM,UAAU,SAAS,mBAAmB;AACzD,MAAI,aAAa,KAAK,CAAE,QAAO;AAG/B,SAAO,aADQ,MAAM,qBAAqB,OAAO,IAAI,OAAO,SAAS,KAAK,CAC/C;UACnB,OAAO;AACf,SAAO,YAAY,OAAO,6BAA6B,wBAAwB"}
1
+ {"version":3,"file":"settings.mjs","names":[],"sources":["../../../../src/astro/routes/api/settings.ts"],"sourcesContent":["/**\n * Site Settings API endpoint\n *\n * GET /_emdash/api/settings - Get all site settings\n * POST /_emdash/api/settings - Update site settings\n */\n\nimport type { APIRoute } from \"astro\";\n\nimport { requirePerm } from \"#api/authorize.js\";\nimport { apiError, handleError, unwrapResult } from \"#api/error.js\";\nimport { handleSettingsGet, handleSettingsUpdate } from \"#api/handlers/settings.js\";\nimport { isParseError, parseBody } from \"#api/parse.js\";\nimport { settingsUpdateBody } from \"#api/schemas.js\";\n\nexport const prerender = false;\n\n/**\n * GET /_emdash/api/settings\n *\n * Returns all site settings as a JSON object.\n * Unset values are undefined. Media references include resolved URLs.\n */\nexport const GET: APIRoute = async ({ locals }) => {\n\tconst { emdash, user } = locals;\n\n\tif (!emdash?.db) {\n\t\treturn apiError(\"NOT_CONFIGURED\", \"EmDash is not initialized\", 500);\n\t}\n\n\tconst denied = requirePerm(user, \"settings:read\");\n\tif (denied) return denied;\n\n\ttry {\n\t\tconst result = await handleSettingsGet(emdash.db, emdash.storage);\n\t\treturn unwrapResult(result);\n\t} catch (error) {\n\t\treturn handleError(error, \"Failed to get settings\", \"SETTINGS_READ_ERROR\");\n\t}\n};\n\n/**\n * POST /_emdash/api/settings\n *\n * Updates site settings. Accepts a partial settings object.\n * Merges with existing settings and returns the updated settings.\n */\nexport const POST: APIRoute = async ({ request, locals }) => {\n\tconst { emdash, user } = locals;\n\n\tif (!emdash?.db) {\n\t\treturn apiError(\"NOT_CONFIGURED\", \"EmDash is not initialized\", 500);\n\t}\n\n\tconst denied = requirePerm(user, \"settings:manage\");\n\tif (denied) return denied;\n\n\ttry {\n\t\tconst body = await parseBody(request, settingsUpdateBody);\n\t\tif (isParseError(body)) return body;\n\n\t\tconst result = await handleSettingsUpdate(emdash.db, emdash.storage, body);\n\t\treturn unwrapResult(result);\n\t} catch (error) {\n\t\treturn handleError(error, \"Failed to update settings\", \"SETTINGS_UPDATE_ERROR\");\n\t}\n};\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;AAeA,MAAa,YAAY;;;;;;;AAQzB,MAAa,MAAgB,OAAO,EAAE,aAAa;CAClD,MAAM,EAAE,QAAQ,SAAS;AAEzB,KAAI,CAAC,QAAQ,GACZ,QAAO,SAAS,kBAAkB,6BAA6B,IAAI;CAGpE,MAAM,SAAS,YAAY,MAAM,gBAAgB;AACjD,KAAI,OAAQ,QAAO;AAEnB,KAAI;AAEH,SAAO,aADQ,MAAM,kBAAkB,OAAO,IAAI,OAAO,QAAQ,CACtC;UACnB,OAAO;AACf,SAAO,YAAY,OAAO,0BAA0B,sBAAsB;;;;;;;;;AAU5E,MAAa,OAAiB,OAAO,EAAE,SAAS,aAAa;CAC5D,MAAM,EAAE,QAAQ,SAAS;AAEzB,KAAI,CAAC,QAAQ,GACZ,QAAO,SAAS,kBAAkB,6BAA6B,IAAI;CAGpE,MAAM,SAAS,YAAY,MAAM,kBAAkB;AACnD,KAAI,OAAQ,QAAO;AAEnB,KAAI;EACH,MAAM,OAAO,MAAM,UAAU,SAAS,mBAAmB;AACzD,MAAI,aAAa,KAAK,CAAE,QAAO;AAG/B,SAAO,aADQ,MAAM,qBAAqB,OAAO,IAAI,OAAO,SAAS,KAAK,CAC/C;UACnB,OAAO;AACf,SAAO,YAAY,OAAO,6BAA6B,wBAAwB"}
@@ -1,19 +1,20 @@
1
- import "../../../../base64-C74Msx8h.mjs";
2
- import "../../../../types-Ch8pFMEm.mjs";
1
+ import "../../../../base64-B-PsqheR.mjs";
2
+ import "../../../../types-CrRUFdej.mjs";
3
3
  import { t as OptionsRepository } from "../../../../options-BlmBHTvX.mjs";
4
- import { n as apiSuccess, r as handleError, t as apiError } from "../../../../error-CfJMLSkd.mjs";
5
- import { n as parseBody, t as isParseError } from "../../../../parse-GLksnn-B.mjs";
6
- import "../../../../redirects-CeD7K7EX.mjs";
7
- import { y as setupAdminVerifyBody } from "../../../../relations-BmBmX4Eb.mjs";
8
- import "../../../../status-D3Gy1Zc6.mjs";
4
+ import { n as apiSuccess, r as handleError, t as apiError } from "../../../../error-DJ98TRbQ.mjs";
5
+ import { n as parseBody, t as isParseError } from "../../../../parse-53zyxlpv.mjs";
6
+ import "../../../../media-BJ6SRY3g.mjs";
7
+ import "../../../../redirects-D457qwt0.mjs";
8
+ import { y as setupAdminVerifyBody } from "../../../../relations-CZMpBqEd.mjs";
9
+ import "../../../../status-COfycGIU.mjs";
9
10
  import "../../../../api/schemas/index.mjs";
10
- import { n as getPublicOrigin } from "../../../../public-url-C0cEvrRu.mjs";
11
- import { n as validateAllowedOrigins, t as getConfiguredAllowedOrigins } from "../../../../allowed-origins-FXB-FplB.mjs";
12
- import { n as createChallengeStore } from "../../../../challenge-store-B426wQ6O.mjs";
13
- import { t as getPasskeyConfig } from "../../../../passkey-config-CjA1UbDj.mjs";
14
- import { t as SETUP_NONCE_COOKIE } from "../../../../setup-nonce-DEPZX96T.mjs";
15
- import { createKyselyAdapter } from "@emdash-cms/auth/adapters/kysely";
11
+ import { n as getPublicOrigin } from "../../../../public-url-DSGTnJFw.mjs";
12
+ import { n as validateAllowedOrigins, t as getConfiguredAllowedOrigins } from "../../../../allowed-origins-CCEi9bPI.mjs";
13
+ import { n as createChallengeStore } from "../../../../challenge-store-BFzgFRog.mjs";
14
+ import { t as getPasskeyConfig } from "../../../../passkey-config-C-SKpc0-.mjs";
15
+ import { t as SETUP_NONCE_COOKIE } from "../../../../setup-nonce-DqiIPr-J.mjs";
16
16
  import { Role, secureCompare } from "@emdash-cms/auth";
17
+ import { createKyselyAdapter } from "@emdash-cms/auth/adapters/kysely";
17
18
  import { registerPasskey, verifyRegistrationResponse } from "@emdash-cms/auth/passkey";
18
19
 
19
20
  //#region src/astro/routes/api/setup/admin-verify.ts
@@ -24,9 +25,12 @@ const POST = async ({ cookies, request, locals }) => {
24
25
  try {
25
26
  const options = new OptionsRepository(emdash.db);
26
27
  const setupComplete = await options.get("emdash:setup_complete");
27
- if (setupComplete === true || setupComplete === "true") return apiError("SETUP_COMPLETE", "Setup already complete", 400);
28
+ const isComplete = setupComplete === true || setupComplete === "true";
28
29
  const adapter = createKyselyAdapter(emdash.db);
29
- if (await adapter.countUsers() > 0) return apiError("ADMIN_EXISTS", "Admin user already exists", 400);
30
+ if (await adapter.countUsers() > 0) {
31
+ if (isComplete) return apiError("SETUP_COMPLETE", "Setup already complete", 400);
32
+ return apiError("ADMIN_EXISTS", "Admin user already exists", 400);
33
+ }
30
34
  const setupState = await options.get("emdash:setup_state");
31
35
  if (!setupState || setupState.step !== "admin") return apiError("INVALID_STATE", "Invalid setup state. Please restart setup.", 400);
32
36
  const cookieNonce = cookies.get(SETUP_NONCE_COOKIE)?.value;
@@ -1 +1 @@
1
- {"version":3,"file":"admin-verify.mjs","names":[],"sources":["../../../../../src/astro/routes/api/setup/admin-verify.ts"],"sourcesContent":["/**\n * POST /_emdash/api/setup/admin/verify\n *\n * Complete admin creation by verifying the passkey registration\n */\n\nimport type { APIRoute } from \"astro\";\n\nexport const prerender = false;\n\nimport { Role, secureCompare } from \"@emdash-cms/auth\";\nimport { createKyselyAdapter } from \"@emdash-cms/auth/adapters/kysely\";\nimport { verifyRegistrationResponse, registerPasskey } from \"@emdash-cms/auth/passkey\";\n\nimport { apiError, apiSuccess, handleError } from \"#api/error.js\";\nimport { isParseError, parseBody } from \"#api/parse.js\";\nimport { getPublicOrigin } from \"#api/public-url.js\";\nimport { setupAdminVerifyBody } from \"#api/schemas.js\";\nimport { getConfiguredAllowedOrigins, validateAllowedOrigins } from \"#auth/allowed-origins.js\";\nimport { createChallengeStore } from \"#auth/challenge-store.js\";\nimport { getPasskeyConfig } from \"#auth/passkey-config.js\";\nimport { SETUP_NONCE_COOKIE } from \"#auth/setup-nonce.js\";\nimport { OptionsRepository } from \"#db/repositories/options.js\";\n\nexport const POST: APIRoute = async ({ cookies, request, locals }) => {\n\tconst { emdash } = locals;\n\n\tif (!emdash?.db) {\n\t\treturn apiError(\"NOT_CONFIGURED\", \"EmDash is not initialized\", 500);\n\t}\n\n\ttry {\n\t\t// Check if setup is already complete\n\t\tconst options = new OptionsRepository(emdash.db);\n\t\tconst setupComplete = await options.get(\"emdash:setup_complete\");\n\n\t\tif (setupComplete === true || setupComplete === \"true\") {\n\t\t\treturn apiError(\"SETUP_COMPLETE\", \"Setup already complete\", 400);\n\t\t}\n\n\t\t// Check if any users exist\n\t\tconst adapter = createKyselyAdapter(emdash.db);\n\t\tconst userCount = await adapter.countUsers();\n\n\t\tif (userCount > 0) {\n\t\t\treturn apiError(\"ADMIN_EXISTS\", \"Admin user already exists\", 400);\n\t\t}\n\n\t\t// Get setup state\n\t\tconst setupState = await options.get<{\n\t\t\tstep?: string;\n\t\t\temail?: string;\n\t\t\tname?: string | null;\n\t\t\tnonce?: string;\n\t\t}>(\"emdash:setup_state\");\n\n\t\tif (!setupState || setupState.step !== \"admin\") {\n\t\t\treturn apiError(\"INVALID_STATE\", \"Invalid setup state. Please restart setup.\", 400);\n\t\t}\n\n\t\t// Verify the session nonce. The cookie was minted by POST /setup/admin\n\t\t// and stored alongside setup_state; presenting a matching cookie is\n\t\t// proof that this verify call comes from the same browser that\n\t\t// started the admin step. Constant-time compare to avoid leaking the\n\t\t// stored value through timing.\n\t\tconst cookieNonce = cookies.get(SETUP_NONCE_COOKIE)?.value;\n\t\tif (!setupState.nonce || !cookieNonce || !secureCompare(cookieNonce, setupState.nonce)) {\n\t\t\treturn apiError(\n\t\t\t\t\"INVALID_STATE\",\n\t\t\t\t\"Setup session expired or tampered with. Please restart the admin step.\",\n\t\t\t\t400,\n\t\t\t);\n\t\t}\n\n\t\tif (!setupState.email) {\n\t\t\treturn apiError(\"INVALID_STATE\", \"Invalid setup state. Please restart setup.\", 400);\n\t\t}\n\n\t\t// Parse request body\n\t\tconst body = await parseBody(request, setupAdminVerifyBody);\n\t\tif (isParseError(body)) return body;\n\n\t\t// Get passkey config\n\t\tconst url = new URL(request.url);\n\t\tconst siteName = (await options.get<string>(\"emdash:site_title\")) ?? undefined;\n\t\tconst siteUrl = getPublicOrigin(url, emdash?.config);\n\t\tconst allowedOrigins = validateAllowedOrigins(\n\t\t\tsiteUrl,\n\t\t\tgetConfiguredAllowedOrigins(emdash?.config),\n\t\t);\n\t\tconst passkeyConfig = getPasskeyConfig(url, siteName, siteUrl, allowedOrigins);\n\n\t\t// Verify the registration response\n\t\tconst challengeStore = createChallengeStore(emdash.db);\n\n\t\tconst verified = await verifyRegistrationResponse(\n\t\t\tpasskeyConfig,\n\t\t\tbody.credential,\n\t\t\tchallengeStore,\n\t\t);\n\n\t\t// Create the admin user\n\t\tconst user = await adapter.createUser({\n\t\t\temail: setupState.email,\n\t\t\tname: setupState.name ?? null,\n\t\t\trole: Role.ADMIN,\n\t\t\temailVerified: false, // No email verification for first user\n\t\t});\n\n\t\t// Register the passkey\n\t\tawait registerPasskey(adapter, user.id, verified, \"Setup passkey\");\n\n\t\t// Mark setup as complete\n\t\tawait options.set(\"emdash:setup_complete\", true);\n\n\t\t// Clean up setup state and the session nonce cookie\n\t\tawait options.delete(\"emdash:setup_state\");\n\t\tcookies.delete(SETUP_NONCE_COOKIE, { path: \"/_emdash/\" });\n\n\t\treturn apiSuccess({\n\t\t\tsuccess: true,\n\t\t\tuser: {\n\t\t\t\tid: user.id,\n\t\t\t\temail: user.email,\n\t\t\t\tname: user.name,\n\t\t\t\trole: user.role,\n\t\t\t},\n\t\t});\n\t} catch (error) {\n\t\treturn handleError(error, \"Failed to verify admin setup\", \"SETUP_VERIFY_ERROR\");\n\t}\n};\n"],"mappings":";;;;;;;;;;;;;;;;;;;AAQA,MAAa,YAAY;AAgBzB,MAAa,OAAiB,OAAO,EAAE,SAAS,SAAS,aAAa;CACrE,MAAM,EAAE,WAAW;AAEnB,KAAI,CAAC,QAAQ,GACZ,QAAO,SAAS,kBAAkB,6BAA6B,IAAI;AAGpE,KAAI;EAEH,MAAM,UAAU,IAAI,kBAAkB,OAAO,GAAG;EAChD,MAAM,gBAAgB,MAAM,QAAQ,IAAI,wBAAwB;AAEhE,MAAI,kBAAkB,QAAQ,kBAAkB,OAC/C,QAAO,SAAS,kBAAkB,0BAA0B,IAAI;EAIjE,MAAM,UAAU,oBAAoB,OAAO,GAAG;AAG9C,MAFkB,MAAM,QAAQ,YAAY,GAE5B,EACf,QAAO,SAAS,gBAAgB,6BAA6B,IAAI;EAIlE,MAAM,aAAa,MAAM,QAAQ,IAK9B,qBAAqB;AAExB,MAAI,CAAC,cAAc,WAAW,SAAS,QACtC,QAAO,SAAS,iBAAiB,8CAA8C,IAAI;EAQpF,MAAM,cAAc,QAAQ,IAAI,mBAAmB,EAAE;AACrD,MAAI,CAAC,WAAW,SAAS,CAAC,eAAe,CAAC,cAAc,aAAa,WAAW,MAAM,CACrF,QAAO,SACN,iBACA,0EACA,IACA;AAGF,MAAI,CAAC,WAAW,MACf,QAAO,SAAS,iBAAiB,8CAA8C,IAAI;EAIpF,MAAM,OAAO,MAAM,UAAU,SAAS,qBAAqB;AAC3D,MAAI,aAAa,KAAK,CAAE,QAAO;EAG/B,MAAM,MAAM,IAAI,IAAI,QAAQ,IAAI;EAChC,MAAM,WAAY,MAAM,QAAQ,IAAY,oBAAoB,IAAK;EACrE,MAAM,UAAU,gBAAgB,KAAK,QAAQ,OAAO;EAKpD,MAAM,gBAAgB,iBAAiB,KAAK,UAAU,SAJ/B,uBACtB,SACA,4BAA4B,QAAQ,OAAO,CAC3C,CAC6E;EAG9E,MAAM,iBAAiB,qBAAqB,OAAO,GAAG;EAEtD,MAAM,WAAW,MAAM,2BACtB,eACA,KAAK,YACL,eACA;EAGD,MAAM,OAAO,MAAM,QAAQ,WAAW;GACrC,OAAO,WAAW;GAClB,MAAM,WAAW,QAAQ;GACzB,MAAM,KAAK;GACX,eAAe;GACf,CAAC;AAGF,QAAM,gBAAgB,SAAS,KAAK,IAAI,UAAU,gBAAgB;AAGlE,QAAM,QAAQ,IAAI,yBAAyB,KAAK;AAGhD,QAAM,QAAQ,OAAO,qBAAqB;AAC1C,UAAQ,OAAO,oBAAoB,EAAE,MAAM,aAAa,CAAC;AAEzD,SAAO,WAAW;GACjB,SAAS;GACT,MAAM;IACL,IAAI,KAAK;IACT,OAAO,KAAK;IACZ,MAAM,KAAK;IACX,MAAM,KAAK;IACX;GACD,CAAC;UACM,OAAO;AACf,SAAO,YAAY,OAAO,gCAAgC,qBAAqB"}
1
+ {"version":3,"file":"admin-verify.mjs","names":[],"sources":["../../../../../src/astro/routes/api/setup/admin-verify.ts"],"sourcesContent":["/**\n * POST /_emdash/api/setup/admin/verify\n *\n * Complete admin creation by verifying the passkey registration\n */\n\nimport type { APIRoute } from \"astro\";\n\nexport const prerender = false;\n\nimport { Role, secureCompare } from \"@emdash-cms/auth\";\nimport { createKyselyAdapter } from \"@emdash-cms/auth/adapters/kysely\";\nimport { verifyRegistrationResponse, registerPasskey } from \"@emdash-cms/auth/passkey\";\n\nimport { apiError, apiSuccess, handleError } from \"#api/error.js\";\nimport { isParseError, parseBody } from \"#api/parse.js\";\nimport { getPublicOrigin } from \"#api/public-url.js\";\nimport { setupAdminVerifyBody } from \"#api/schemas.js\";\nimport { getConfiguredAllowedOrigins, validateAllowedOrigins } from \"#auth/allowed-origins.js\";\nimport { createChallengeStore } from \"#auth/challenge-store.js\";\nimport { getPasskeyConfig } from \"#auth/passkey-config.js\";\nimport { SETUP_NONCE_COOKIE } from \"#auth/setup-nonce.js\";\nimport { OptionsRepository } from \"#db/repositories/options.js\";\n\nexport const POST: APIRoute = async ({ cookies, request, locals }) => {\n\tconst { emdash } = locals;\n\n\tif (!emdash?.db) {\n\t\treturn apiError(\"NOT_CONFIGURED\", \"EmDash is not initialized\", 500);\n\t}\n\n\ttry {\n\t\t// Check if setup is already complete\n\t\tconst options = new OptionsRepository(emdash.db);\n\t\tconst setupComplete = await options.get(\"emdash:setup_complete\");\n\t\tconst isComplete = setupComplete === true || setupComplete === \"true\";\n\n\t\t// Check if any users exist\n\t\tconst adapter = createKyselyAdapter(emdash.db);\n\t\tconst userCount = await adapter.countUsers();\n\n\t\tif (userCount > 0) {\n\t\t\tif (isComplete) {\n\t\t\t\treturn apiError(\"SETUP_COMPLETE\", \"Setup already complete\", 400);\n\t\t\t}\n\t\t\treturn apiError(\"ADMIN_EXISTS\", \"Admin user already exists\", 400);\n\t\t}\n\n\t\t// `setup_complete` with ZERO users is a recoverable half-state —\n\t\t// see the matching guard in ./admin.ts. The verify step must\n\t\t// accept it too, or the wizard dies between its two calls.\n\n\t\t// Get setup state\n\t\tconst setupState = await options.get<{\n\t\t\tstep?: string;\n\t\t\temail?: string;\n\t\t\tname?: string | null;\n\t\t\tnonce?: string;\n\t\t}>(\"emdash:setup_state\");\n\n\t\tif (!setupState || setupState.step !== \"admin\") {\n\t\t\treturn apiError(\"INVALID_STATE\", \"Invalid setup state. Please restart setup.\", 400);\n\t\t}\n\n\t\t// Verify the session nonce. The cookie was minted by POST /setup/admin\n\t\t// and stored alongside setup_state; presenting a matching cookie is\n\t\t// proof that this verify call comes from the same browser that\n\t\t// started the admin step. Constant-time compare to avoid leaking the\n\t\t// stored value through timing.\n\t\tconst cookieNonce = cookies.get(SETUP_NONCE_COOKIE)?.value;\n\t\tif (!setupState.nonce || !cookieNonce || !secureCompare(cookieNonce, setupState.nonce)) {\n\t\t\treturn apiError(\n\t\t\t\t\"INVALID_STATE\",\n\t\t\t\t\"Setup session expired or tampered with. Please restart the admin step.\",\n\t\t\t\t400,\n\t\t\t);\n\t\t}\n\n\t\tif (!setupState.email) {\n\t\t\treturn apiError(\"INVALID_STATE\", \"Invalid setup state. Please restart setup.\", 400);\n\t\t}\n\n\t\t// Parse request body\n\t\tconst body = await parseBody(request, setupAdminVerifyBody);\n\t\tif (isParseError(body)) return body;\n\n\t\t// Get passkey config\n\t\tconst url = new URL(request.url);\n\t\tconst siteName = (await options.get<string>(\"emdash:site_title\")) ?? undefined;\n\t\tconst siteUrl = getPublicOrigin(url, emdash?.config);\n\t\tconst allowedOrigins = validateAllowedOrigins(\n\t\t\tsiteUrl,\n\t\t\tgetConfiguredAllowedOrigins(emdash?.config),\n\t\t);\n\t\tconst passkeyConfig = getPasskeyConfig(url, siteName, siteUrl, allowedOrigins);\n\n\t\t// Verify the registration response\n\t\tconst challengeStore = createChallengeStore(emdash.db);\n\n\t\tconst verified = await verifyRegistrationResponse(\n\t\t\tpasskeyConfig,\n\t\t\tbody.credential,\n\t\t\tchallengeStore,\n\t\t);\n\n\t\t// Create the admin user\n\t\tconst user = await adapter.createUser({\n\t\t\temail: setupState.email,\n\t\t\tname: setupState.name ?? null,\n\t\t\trole: Role.ADMIN,\n\t\t\temailVerified: false, // No email verification for first user\n\t\t});\n\n\t\t// Register the passkey\n\t\tawait registerPasskey(adapter, user.id, verified, \"Setup passkey\");\n\n\t\t// Mark setup as complete\n\t\tawait options.set(\"emdash:setup_complete\", true);\n\n\t\t// Clean up setup state and the session nonce cookie\n\t\tawait options.delete(\"emdash:setup_state\");\n\t\tcookies.delete(SETUP_NONCE_COOKIE, { path: \"/_emdash/\" });\n\n\t\treturn apiSuccess({\n\t\t\tsuccess: true,\n\t\t\tuser: {\n\t\t\t\tid: user.id,\n\t\t\t\temail: user.email,\n\t\t\t\tname: user.name,\n\t\t\t\trole: user.role,\n\t\t\t},\n\t\t});\n\t} catch (error) {\n\t\treturn handleError(error, \"Failed to verify admin setup\", \"SETUP_VERIFY_ERROR\");\n\t}\n};\n"],"mappings":";;;;;;;;;;;;;;;;;;;;AAQA,MAAa,YAAY;AAgBzB,MAAa,OAAiB,OAAO,EAAE,SAAS,SAAS,aAAa;CACrE,MAAM,EAAE,WAAW;AAEnB,KAAI,CAAC,QAAQ,GACZ,QAAO,SAAS,kBAAkB,6BAA6B,IAAI;AAGpE,KAAI;EAEH,MAAM,UAAU,IAAI,kBAAkB,OAAO,GAAG;EAChD,MAAM,gBAAgB,MAAM,QAAQ,IAAI,wBAAwB;EAChE,MAAM,aAAa,kBAAkB,QAAQ,kBAAkB;EAG/D,MAAM,UAAU,oBAAoB,OAAO,GAAG;AAG9C,MAFkB,MAAM,QAAQ,YAAY,GAE5B,GAAG;AAClB,OAAI,WACH,QAAO,SAAS,kBAAkB,0BAA0B,IAAI;AAEjE,UAAO,SAAS,gBAAgB,6BAA6B,IAAI;;EAQlE,MAAM,aAAa,MAAM,QAAQ,IAK9B,qBAAqB;AAExB,MAAI,CAAC,cAAc,WAAW,SAAS,QACtC,QAAO,SAAS,iBAAiB,8CAA8C,IAAI;EAQpF,MAAM,cAAc,QAAQ,IAAI,mBAAmB,EAAE;AACrD,MAAI,CAAC,WAAW,SAAS,CAAC,eAAe,CAAC,cAAc,aAAa,WAAW,MAAM,CACrF,QAAO,SACN,iBACA,0EACA,IACA;AAGF,MAAI,CAAC,WAAW,MACf,QAAO,SAAS,iBAAiB,8CAA8C,IAAI;EAIpF,MAAM,OAAO,MAAM,UAAU,SAAS,qBAAqB;AAC3D,MAAI,aAAa,KAAK,CAAE,QAAO;EAG/B,MAAM,MAAM,IAAI,IAAI,QAAQ,IAAI;EAChC,MAAM,WAAY,MAAM,QAAQ,IAAY,oBAAoB,IAAK;EACrE,MAAM,UAAU,gBAAgB,KAAK,QAAQ,OAAO;EAKpD,MAAM,gBAAgB,iBAAiB,KAAK,UAAU,SAJ/B,uBACtB,SACA,4BAA4B,QAAQ,OAAO,CAC3C,CAC6E;EAG9E,MAAM,iBAAiB,qBAAqB,OAAO,GAAG;EAEtD,MAAM,WAAW,MAAM,2BACtB,eACA,KAAK,YACL,eACA;EAGD,MAAM,OAAO,MAAM,QAAQ,WAAW;GACrC,OAAO,WAAW;GAClB,MAAM,WAAW,QAAQ;GACzB,MAAM,KAAK;GACX,eAAe;GACf,CAAC;AAGF,QAAM,gBAAgB,SAAS,KAAK,IAAI,UAAU,gBAAgB;AAGlE,QAAM,QAAQ,IAAI,yBAAyB,KAAK;AAGhD,QAAM,QAAQ,OAAO,qBAAqB;AAC1C,UAAQ,OAAO,oBAAoB,EAAE,MAAM,aAAa,CAAC;AAEzD,SAAO,WAAW;GACjB,SAAS;GACT,MAAM;IACL,IAAI,KAAK;IACT,OAAO,KAAK;IACZ,MAAM,KAAK;IACX,MAAM,KAAK;IACX;GACD,CAAC;UACM,OAAO;AACf,SAAO,YAAY,OAAO,gCAAgC,qBAAqB"}
@@ -1,18 +1,19 @@
1
- import "../../../../base64-C74Msx8h.mjs";
2
- import "../../../../types-Ch8pFMEm.mjs";
1
+ import "../../../../base64-B-PsqheR.mjs";
2
+ import "../../../../types-CrRUFdej.mjs";
3
3
  import { t as OptionsRepository } from "../../../../options-BlmBHTvX.mjs";
4
- import { n as apiSuccess, r as handleError, t as apiError } from "../../../../error-CfJMLSkd.mjs";
5
- import { n as parseBody, t as isParseError } from "../../../../parse-GLksnn-B.mjs";
6
- import "../../../../redirects-CeD7K7EX.mjs";
7
- import { v as setupAdminBody } from "../../../../relations-BmBmX4Eb.mjs";
8
- import "../../../../status-D3Gy1Zc6.mjs";
4
+ import { n as apiSuccess, r as handleError, t as apiError } from "../../../../error-DJ98TRbQ.mjs";
5
+ import { n as parseBody, t as isParseError } from "../../../../parse-53zyxlpv.mjs";
6
+ import "../../../../media-BJ6SRY3g.mjs";
7
+ import "../../../../redirects-D457qwt0.mjs";
8
+ import { v as setupAdminBody } from "../../../../relations-CZMpBqEd.mjs";
9
+ import "../../../../status-COfycGIU.mjs";
9
10
  import "../../../../api/schemas/index.mjs";
10
- import { n as getPublicOrigin } from "../../../../public-url-C0cEvrRu.mjs";
11
- import { n as createChallengeStore } from "../../../../challenge-store-B426wQ6O.mjs";
12
- import { t as getPasskeyConfig } from "../../../../passkey-config-CjA1UbDj.mjs";
13
- import { n as SETUP_NONCE_MAX_AGE_SECONDS, t as SETUP_NONCE_COOKIE } from "../../../../setup-nonce-DEPZX96T.mjs";
14
- import { createKyselyAdapter } from "@emdash-cms/auth/adapters/kysely";
11
+ import { n as getPublicOrigin } from "../../../../public-url-DSGTnJFw.mjs";
12
+ import { n as createChallengeStore } from "../../../../challenge-store-BFzgFRog.mjs";
13
+ import { t as getPasskeyConfig } from "../../../../passkey-config-C-SKpc0-.mjs";
14
+ import { n as SETUP_NONCE_MAX_AGE_SECONDS, t as SETUP_NONCE_COOKIE } from "../../../../setup-nonce-DqiIPr-J.mjs";
15
15
  import { generateToken } from "@emdash-cms/auth";
16
+ import { createKyselyAdapter } from "@emdash-cms/auth/adapters/kysely";
16
17
  import { generateRegistrationOptions } from "@emdash-cms/auth/passkey";
17
18
 
18
19
  //#region src/astro/routes/api/setup/admin.ts
@@ -23,8 +24,11 @@ const POST = async ({ cookies, request, locals }) => {
23
24
  try {
24
25
  const options = new OptionsRepository(emdash.db);
25
26
  const setupComplete = await options.get("emdash:setup_complete");
26
- if (setupComplete === true || setupComplete === "true") return apiError("SETUP_COMPLETE", "Setup already complete", 400);
27
- if (await createKyselyAdapter(emdash.db).countUsers() > 0) return apiError("ADMIN_EXISTS", "Admin user already exists", 400);
27
+ const isComplete = setupComplete === true || setupComplete === "true";
28
+ if (await createKyselyAdapter(emdash.db).countUsers() > 0) {
29
+ if (isComplete) return apiError("SETUP_COMPLETE", "Setup already complete", 400);
30
+ return apiError("ADMIN_EXISTS", "Admin user already exists", 400);
31
+ }
28
32
  const body = await parseBody(request, setupAdminBody);
29
33
  if (isParseError(body)) return body;
30
34
  const existingState = await options.get("emdash:setup_state");
@@ -1 +1 @@
1
- {"version":3,"file":"admin.mjs","names":[],"sources":["../../../../../src/astro/routes/api/setup/admin.ts"],"sourcesContent":["/**\n * POST /_emdash/api/setup/admin\n *\n * Step 3 of setup: Start admin creation by returning passkey registration options\n */\n\nimport type { APIRoute } from \"astro\";\n\nexport const prerender = false;\n\nimport { generateToken } from \"@emdash-cms/auth\";\nimport { createKyselyAdapter } from \"@emdash-cms/auth/adapters/kysely\";\nimport { generateRegistrationOptions } from \"@emdash-cms/auth/passkey\";\n\nimport { apiError, apiSuccess, handleError } from \"#api/error.js\";\nimport { isParseError, parseBody } from \"#api/parse.js\";\nimport { getPublicOrigin } from \"#api/public-url.js\";\nimport { setupAdminBody } from \"#api/schemas.js\";\nimport { createChallengeStore } from \"#auth/challenge-store.js\";\nimport { getPasskeyConfig } from \"#auth/passkey-config.js\";\nimport { SETUP_NONCE_COOKIE, SETUP_NONCE_MAX_AGE_SECONDS } from \"#auth/setup-nonce.js\";\nimport { OptionsRepository } from \"#db/repositories/options.js\";\n\nexport const POST: APIRoute = async ({ cookies, request, locals }) => {\n\tconst { emdash } = locals;\n\n\tif (!emdash?.db) {\n\t\treturn apiError(\"NOT_CONFIGURED\", \"EmDash is not initialized\", 500);\n\t}\n\n\ttry {\n\t\t// Check if setup is already complete\n\t\tconst options = new OptionsRepository(emdash.db);\n\t\tconst setupComplete = await options.get(\"emdash:setup_complete\");\n\n\t\tif (setupComplete === true || setupComplete === \"true\") {\n\t\t\treturn apiError(\"SETUP_COMPLETE\", \"Setup already complete\", 400);\n\t\t}\n\n\t\t// Check if any users exist\n\t\tconst adapter = createKyselyAdapter(emdash.db);\n\t\tconst userCount = await adapter.countUsers();\n\n\t\tif (userCount > 0) {\n\t\t\treturn apiError(\"ADMIN_EXISTS\", \"Admin user already exists\", 400);\n\t\t}\n\n\t\t// Parse request body\n\t\tconst body = await parseBody(request, setupAdminBody);\n\t\tif (isParseError(body)) return body;\n\n\t\t// Preserve title/tagline from step 1 by reading existing setup state\n\t\t// before we overwrite it below.\n\t\tconst existingState = await options.get<Record<string, unknown>>(\"emdash:setup_state\");\n\n\t\t// Mint a fresh session nonce. This binds the follow-up\n\t\t// /setup/admin/verify call to the same browser that made this\n\t\t// request, so an unauthenticated attacker on another host cannot\n\t\t// substitute their own email into the setup state during the\n\t\t// setup window. Rotates on every call so a legitimate retry\n\t\t// always gets a working session.\n\t\tconst nonce = generateToken();\n\n\t\t// Get passkey config\n\t\tconst url = new URL(request.url);\n\t\tconst siteName = (await options.get<string>(\"emdash:site_title\")) ?? undefined;\n\t\tconst siteUrl = getPublicOrigin(url, emdash?.config);\n\t\tconst passkeyConfig = getPasskeyConfig(url, siteName, siteUrl);\n\n\t\t// Generate registration options\n\t\tconst challengeStore = createChallengeStore(emdash.db);\n\n\t\t// Create a temporary user object for registration options\n\t\t// (not persisted until passkey is verified)\n\t\tconst tempUser = {\n\t\t\tid: `setup-${Date.now()}`, // Temporary ID\n\t\t\temail: body.email.toLowerCase(),\n\t\t\tname: body.name || null,\n\t\t};\n\n\t\tconst registrationOptions = await generateRegistrationOptions(\n\t\t\tpasskeyConfig,\n\t\t\ttempUser,\n\t\t\t[], // No existing credentials\n\t\t\tchallengeStore,\n\t\t);\n\n\t\t// Store the nonce alongside the rest of the setup state, preserving\n\t\t// title/tagline from step 1. The verify endpoint will constant-time\n\t\t// compare the nonce with the incoming cookie.\n\t\tawait options.set(\"emdash:setup_state\", {\n\t\t\t...existingState,\n\t\t\tstep: \"admin\",\n\t\t\temail: body.email.toLowerCase(),\n\t\t\tname: body.name || null,\n\t\t\ttempUserId: tempUser.id,\n\t\t\tnonce,\n\t\t});\n\n\t\t// HttpOnly + SameSite=Strict + path-scoped. The cookie must not be\n\t\t// accessible to JS (nothing in the admin UI needs to read it) and\n\t\t// must not be sent on cross-site navigations. The /_emdash/ path\n\t\t// scope keeps it away from user-authored frontend code.\n\t\t//\n\t\t// Derive `secure` from the public origin, not the internal request\n\t\t// URL. Behind a TLS-terminating reverse proxy the internal hop is\n\t\t// often `http:` while the browser-facing origin is `https:` —\n\t\t// using `url.protocol` there would drop the Secure flag on a\n\t\t// sensitive cookie over the public HTTPS connection.\n\t\tconst publicOrigin = new URL(siteUrl);\n\t\tcookies.set(SETUP_NONCE_COOKIE, nonce, {\n\t\t\tpath: \"/_emdash/\",\n\t\t\thttpOnly: true,\n\t\t\tsameSite: \"strict\",\n\t\t\tsecure: publicOrigin.protocol === \"https:\",\n\t\t\tmaxAge: SETUP_NONCE_MAX_AGE_SECONDS,\n\t\t});\n\n\t\treturn apiSuccess({\n\t\t\tsuccess: true,\n\t\t\toptions: registrationOptions,\n\t\t});\n\t} catch (error) {\n\t\treturn handleError(error, \"Failed to create admin\", \"SETUP_ADMIN_ERROR\");\n\t}\n};\n"],"mappings":";;;;;;;;;;;;;;;;;;AAQA,MAAa,YAAY;AAezB,MAAa,OAAiB,OAAO,EAAE,SAAS,SAAS,aAAa;CACrE,MAAM,EAAE,WAAW;AAEnB,KAAI,CAAC,QAAQ,GACZ,QAAO,SAAS,kBAAkB,6BAA6B,IAAI;AAGpE,KAAI;EAEH,MAAM,UAAU,IAAI,kBAAkB,OAAO,GAAG;EAChD,MAAM,gBAAgB,MAAM,QAAQ,IAAI,wBAAwB;AAEhE,MAAI,kBAAkB,QAAQ,kBAAkB,OAC/C,QAAO,SAAS,kBAAkB,0BAA0B,IAAI;AAOjE,MAFkB,MADF,oBAAoB,OAAO,GAAG,CACd,YAAY,GAE5B,EACf,QAAO,SAAS,gBAAgB,6BAA6B,IAAI;EAIlE,MAAM,OAAO,MAAM,UAAU,SAAS,eAAe;AACrD,MAAI,aAAa,KAAK,CAAE,QAAO;EAI/B,MAAM,gBAAgB,MAAM,QAAQ,IAA6B,qBAAqB;EAQtF,MAAM,QAAQ,eAAe;EAG7B,MAAM,MAAM,IAAI,IAAI,QAAQ,IAAI;EAChC,MAAM,WAAY,MAAM,QAAQ,IAAY,oBAAoB,IAAK;EACrE,MAAM,UAAU,gBAAgB,KAAK,QAAQ,OAAO;EACpD,MAAM,gBAAgB,iBAAiB,KAAK,UAAU,QAAQ;EAG9D,MAAM,iBAAiB,qBAAqB,OAAO,GAAG;EAItD,MAAM,WAAW;GAChB,IAAI,SAAS,KAAK,KAAK;GACvB,OAAO,KAAK,MAAM,aAAa;GAC/B,MAAM,KAAK,QAAQ;GACnB;EAED,MAAM,sBAAsB,MAAM,4BACjC,eACA,UACA,EAAE,EACF,eACA;AAKD,QAAM,QAAQ,IAAI,sBAAsB;GACvC,GAAG;GACH,MAAM;GACN,OAAO,KAAK,MAAM,aAAa;GAC/B,MAAM,KAAK,QAAQ;GACnB,YAAY,SAAS;GACrB;GACA,CAAC;EAYF,MAAM,eAAe,IAAI,IAAI,QAAQ;AACrC,UAAQ,IAAI,oBAAoB,OAAO;GACtC,MAAM;GACN,UAAU;GACV,UAAU;GACV,QAAQ,aAAa,aAAa;GAClC,QAAQ;GACR,CAAC;AAEF,SAAO,WAAW;GACjB,SAAS;GACT,SAAS;GACT,CAAC;UACM,OAAO;AACf,SAAO,YAAY,OAAO,0BAA0B,oBAAoB"}
1
+ {"version":3,"file":"admin.mjs","names":[],"sources":["../../../../../src/astro/routes/api/setup/admin.ts"],"sourcesContent":["/**\n * POST /_emdash/api/setup/admin\n *\n * Step 3 of setup: Start admin creation by returning passkey registration options\n */\n\nimport type { APIRoute } from \"astro\";\n\nexport const prerender = false;\n\nimport { generateToken } from \"@emdash-cms/auth\";\nimport { createKyselyAdapter } from \"@emdash-cms/auth/adapters/kysely\";\nimport { generateRegistrationOptions } from \"@emdash-cms/auth/passkey\";\n\nimport { apiError, apiSuccess, handleError } from \"#api/error.js\";\nimport { isParseError, parseBody } from \"#api/parse.js\";\nimport { getPublicOrigin } from \"#api/public-url.js\";\nimport { setupAdminBody } from \"#api/schemas.js\";\nimport { createChallengeStore } from \"#auth/challenge-store.js\";\nimport { getPasskeyConfig } from \"#auth/passkey-config.js\";\nimport { SETUP_NONCE_COOKIE, SETUP_NONCE_MAX_AGE_SECONDS } from \"#auth/setup-nonce.js\";\nimport { OptionsRepository } from \"#db/repositories/options.js\";\n\nexport const POST: APIRoute = async ({ cookies, request, locals }) => {\n\tconst { emdash } = locals;\n\n\tif (!emdash?.db) {\n\t\treturn apiError(\"NOT_CONFIGURED\", \"EmDash is not initialized\", 500);\n\t}\n\n\ttry {\n\t\t// Check if setup is already complete\n\t\tconst options = new OptionsRepository(emdash.db);\n\t\tconst setupComplete = await options.get(\"emdash:setup_complete\");\n\t\tconst isComplete = setupComplete === true || setupComplete === \"true\";\n\n\t\t// Check if any users exist\n\t\tconst adapter = createKyselyAdapter(emdash.db);\n\t\tconst userCount = await adapter.countUsers();\n\n\t\tif (userCount > 0) {\n\t\t\tif (isComplete) {\n\t\t\t\treturn apiError(\"SETUP_COMPLETE\", \"Setup already complete\", 400);\n\t\t\t}\n\t\t\treturn apiError(\"ADMIN_EXISTS\", \"Admin user already exists\", 400);\n\t\t}\n\n\t\t// `setup_complete` with ZERO users is a recoverable half-state (a\n\t\t// wiped/sanitised users table — e.g. a DB copied between\n\t\t// environments). /api/setup/status already resumes the wizard at\n\t\t// the admin step for exactly this state, so admin creation must be\n\t\t// allowed here too — rejecting on the stale flag alone leaves the\n\t\t// instance with no UI path to an admin account.\n\n\t\t// Parse request body\n\t\tconst body = await parseBody(request, setupAdminBody);\n\t\tif (isParseError(body)) return body;\n\n\t\t// Preserve title/tagline from step 1 by reading existing setup state\n\t\t// before we overwrite it below.\n\t\tconst existingState = await options.get<Record<string, unknown>>(\"emdash:setup_state\");\n\n\t\t// Mint a fresh session nonce. This binds the follow-up\n\t\t// /setup/admin/verify call to the same browser that made this\n\t\t// request, so an unauthenticated attacker on another host cannot\n\t\t// substitute their own email into the setup state during the\n\t\t// setup window. Rotates on every call so a legitimate retry\n\t\t// always gets a working session.\n\t\tconst nonce = generateToken();\n\n\t\t// Get passkey config\n\t\tconst url = new URL(request.url);\n\t\tconst siteName = (await options.get<string>(\"emdash:site_title\")) ?? undefined;\n\t\tconst siteUrl = getPublicOrigin(url, emdash?.config);\n\t\tconst passkeyConfig = getPasskeyConfig(url, siteName, siteUrl);\n\n\t\t// Generate registration options\n\t\tconst challengeStore = createChallengeStore(emdash.db);\n\n\t\t// Create a temporary user object for registration options\n\t\t// (not persisted until passkey is verified)\n\t\tconst tempUser = {\n\t\t\tid: `setup-${Date.now()}`, // Temporary ID\n\t\t\temail: body.email.toLowerCase(),\n\t\t\tname: body.name || null,\n\t\t};\n\n\t\tconst registrationOptions = await generateRegistrationOptions(\n\t\t\tpasskeyConfig,\n\t\t\ttempUser,\n\t\t\t[], // No existing credentials\n\t\t\tchallengeStore,\n\t\t);\n\n\t\t// Store the nonce alongside the rest of the setup state, preserving\n\t\t// title/tagline from step 1. The verify endpoint will constant-time\n\t\t// compare the nonce with the incoming cookie.\n\t\tawait options.set(\"emdash:setup_state\", {\n\t\t\t...existingState,\n\t\t\tstep: \"admin\",\n\t\t\temail: body.email.toLowerCase(),\n\t\t\tname: body.name || null,\n\t\t\ttempUserId: tempUser.id,\n\t\t\tnonce,\n\t\t});\n\n\t\t// HttpOnly + SameSite=Strict + path-scoped. The cookie must not be\n\t\t// accessible to JS (nothing in the admin UI needs to read it) and\n\t\t// must not be sent on cross-site navigations. The /_emdash/ path\n\t\t// scope keeps it away from user-authored frontend code.\n\t\t//\n\t\t// Derive `secure` from the public origin, not the internal request\n\t\t// URL. Behind a TLS-terminating reverse proxy the internal hop is\n\t\t// often `http:` while the browser-facing origin is `https:` —\n\t\t// using `url.protocol` there would drop the Secure flag on a\n\t\t// sensitive cookie over the public HTTPS connection.\n\t\tconst publicOrigin = new URL(siteUrl);\n\t\tcookies.set(SETUP_NONCE_COOKIE, nonce, {\n\t\t\tpath: \"/_emdash/\",\n\t\t\thttpOnly: true,\n\t\t\tsameSite: \"strict\",\n\t\t\tsecure: publicOrigin.protocol === \"https:\",\n\t\t\tmaxAge: SETUP_NONCE_MAX_AGE_SECONDS,\n\t\t});\n\n\t\treturn apiSuccess({\n\t\t\tsuccess: true,\n\t\t\toptions: registrationOptions,\n\t\t});\n\t} catch (error) {\n\t\treturn handleError(error, \"Failed to create admin\", \"SETUP_ADMIN_ERROR\");\n\t}\n};\n"],"mappings":";;;;;;;;;;;;;;;;;;;AAQA,MAAa,YAAY;AAezB,MAAa,OAAiB,OAAO,EAAE,SAAS,SAAS,aAAa;CACrE,MAAM,EAAE,WAAW;AAEnB,KAAI,CAAC,QAAQ,GACZ,QAAO,SAAS,kBAAkB,6BAA6B,IAAI;AAGpE,KAAI;EAEH,MAAM,UAAU,IAAI,kBAAkB,OAAO,GAAG;EAChD,MAAM,gBAAgB,MAAM,QAAQ,IAAI,wBAAwB;EAChE,MAAM,aAAa,kBAAkB,QAAQ,kBAAkB;AAM/D,MAFkB,MADF,oBAAoB,OAAO,GAAG,CACd,YAAY,GAE5B,GAAG;AAClB,OAAI,WACH,QAAO,SAAS,kBAAkB,0BAA0B,IAAI;AAEjE,UAAO,SAAS,gBAAgB,6BAA6B,IAAI;;EAWlE,MAAM,OAAO,MAAM,UAAU,SAAS,eAAe;AACrD,MAAI,aAAa,KAAK,CAAE,QAAO;EAI/B,MAAM,gBAAgB,MAAM,QAAQ,IAA6B,qBAAqB;EAQtF,MAAM,QAAQ,eAAe;EAG7B,MAAM,MAAM,IAAI,IAAI,QAAQ,IAAI;EAChC,MAAM,WAAY,MAAM,QAAQ,IAAY,oBAAoB,IAAK;EACrE,MAAM,UAAU,gBAAgB,KAAK,QAAQ,OAAO;EACpD,MAAM,gBAAgB,iBAAiB,KAAK,UAAU,QAAQ;EAG9D,MAAM,iBAAiB,qBAAqB,OAAO,GAAG;EAItD,MAAM,WAAW;GAChB,IAAI,SAAS,KAAK,KAAK;GACvB,OAAO,KAAK,MAAM,aAAa;GAC/B,MAAM,KAAK,QAAQ;GACnB;EAED,MAAM,sBAAsB,MAAM,4BACjC,eACA,UACA,EAAE,EACF,eACA;AAKD,QAAM,QAAQ,IAAI,sBAAsB;GACvC,GAAG;GACH,MAAM;GACN,OAAO,KAAK,MAAM,aAAa;GAC/B,MAAM,KAAK,QAAQ;GACnB,YAAY,SAAS;GACrB;GACA,CAAC;EAYF,MAAM,eAAe,IAAI,IAAI,QAAQ;AACrC,UAAQ,IAAI,oBAAoB,OAAO;GACtC,MAAM;GACN,UAAU;GACV,UAAU;GACV,QAAQ,aAAa,aAAa;GAClC,QAAQ;GACR,CAAC;AAEF,SAAO,WAAW;GACjB,SAAS;GACT,SAAS;GACT,CAAC;UACM,OAAO;AACf,SAAO,YAAY,OAAO,0BAA0B,oBAAoB"}
@@ -1,34 +1,34 @@
1
- import { a as runMigrations } from "../../../../runner-jt65bF7F.mjs";
2
- import "../../../../dialect-helpers-Cue7QQOR.mjs";
1
+ import { a as runMigrations } from "../../../../runner-BdeLEgad.mjs";
2
+ import "../../../../dialect-helpers-BtOwo2us.mjs";
3
3
  import "../../../../after-B1IIdH3Y.mjs";
4
4
  import "../../../../object-cache-Bok5j2ae.mjs";
5
- import "../../../../content-BO61Sx4j.mjs";
6
- import "../../../../base64-C74Msx8h.mjs";
7
- import "../../../../types-Ch8pFMEm.mjs";
8
- import "../../../../media-D2ZFowpn.mjs";
9
- import "../../../../taxonomy-BkxbUMSw.mjs";
5
+ import "../../../../content-BC43pICM.mjs";
6
+ import "../../../../base64-B-PsqheR.mjs";
7
+ import "../../../../types-CrRUFdej.mjs";
8
+ import "../../../../media-its1WLYv.mjs";
9
+ import "../../../../taxonomy-0mCI25HN.mjs";
10
10
  import { t as OptionsRepository } from "../../../../options-BlmBHTvX.mjs";
11
- import "../../../../redirect-Ch3E98qZ.mjs";
11
+ import "../../../../redirect-BoUac4NT.mjs";
12
12
  import "../../../../request-cache-BSUptuJR.mjs";
13
13
  import "../../../../byline-registry-BCuOp4UF.mjs";
14
- import "../../../../field-defs-cache-BVrNCgSj.mjs";
15
- import "../../../../byline-BWb5H-65.mjs";
16
- import "../../../../fts-manager-BD9s77qh.mjs";
17
- import "../../../../loader-Rb8QlGZp.mjs";
18
- import "../../../../content-refresh-BkkApzeS.mjs";
19
- import { n as apiSuccess, r as handleError, t as apiError } from "../../../../error-CfJMLSkd.mjs";
20
- import "../../../../registry-CyIXPi4E.mjs";
21
- import "../../../../settings-BuQYvLfy.mjs";
22
- import "../../../../ssrf-TrKYJAy0.mjs";
23
- import "../../../../ssrf-B5DOv5E5.mjs";
24
- import { t as validateSeed } from "../../../../validate-C3CpWlNt.mjs";
25
- import { t as applySeed } from "../../../../apply-D23iUV4q.mjs";
26
- import { t as loadSeed } from "../../../../load-DgoWMdRX.mjs";
27
- import { n as getPublicOrigin } from "../../../../public-url-C0cEvrRu.mjs";
28
- import "../../../../api-tokens-Dk2GrJMY.mjs";
29
- import { n as handleApiTokenCreate, t as deleteApiTokensByName } from "../../../../api-tokens-UYBkl17d.mjs";
30
- import { t as escapeHtml } from "../../../../escape-r8_GbEU2.mjs";
31
- import { t as isSafeRedirect } from "../../../../redirect-Ce_6Yb6z.mjs";
14
+ import "../../../../field-defs-cache-KfNJ_qLQ.mjs";
15
+ import "../../../../byline-BTOxUlFF.mjs";
16
+ import "../../../../fts-manager-hyCU9OOp.mjs";
17
+ import "../../../../loader-D4rigvjR.mjs";
18
+ import "../../../../content-refresh-CPMSauD3.mjs";
19
+ import "../../../../registry-y21kjhfG.mjs";
20
+ import "../../../../settings-C2PaBS49.mjs";
21
+ import "../../../../ssrf-CviKqWmq.mjs";
22
+ import { n as apiSuccess, r as handleError, t as apiError } from "../../../../error-DJ98TRbQ.mjs";
23
+ import "../../../../ssrf-BB__xfNM.mjs";
24
+ import { t as validateSeed } from "../../../../validate-CDT1jl6_.mjs";
25
+ import { t as applySeed } from "../../../../apply-fGHCAwWN.mjs";
26
+ import { t as loadSeed } from "../../../../load-Dg5gtWma.mjs";
27
+ import { n as getPublicOrigin } from "../../../../public-url-DSGTnJFw.mjs";
28
+ import "../../../../api-tokens-Cvmixds7.mjs";
29
+ import { n as handleApiTokenCreate, t as deleteApiTokensByName } from "../../../../api-tokens-uPt8UDpx.mjs";
30
+ import { t as escapeHtml } from "../../../../escape-CFedIB1C.mjs";
31
+ import { t as isSafeRedirect } from "../../../../redirect-Botom7X6.mjs";
32
32
  import { ulid } from "ulidx";
33
33
 
34
34
  //#region src/astro/routes/api/setup/dev-bypass.ts
@@ -1,7 +1,7 @@
1
- import "../../../../base64-C74Msx8h.mjs";
2
- import "../../../../types-Ch8pFMEm.mjs";
1
+ import "../../../../base64-B-PsqheR.mjs";
2
+ import "../../../../types-CrRUFdej.mjs";
3
3
  import { t as OptionsRepository } from "../../../../options-BlmBHTvX.mjs";
4
- import { n as apiSuccess, r as handleError, t as apiError } from "../../../../error-CfJMLSkd.mjs";
4
+ import { n as apiSuccess, r as handleError, t as apiError } from "../../../../error-DJ98TRbQ.mjs";
5
5
 
6
6
  //#region src/astro/routes/api/setup/dev-reset.ts
7
7
  const prerender = false;
@@ -1,36 +1,37 @@
1
- import { a as runMigrations } from "../../../../runner-jt65bF7F.mjs";
2
- import "../../../../dialect-helpers-Cue7QQOR.mjs";
1
+ import { a as runMigrations } from "../../../../runner-BdeLEgad.mjs";
2
+ import "../../../../dialect-helpers-BtOwo2us.mjs";
3
3
  import "../../../../after-B1IIdH3Y.mjs";
4
4
  import "../../../../object-cache-Bok5j2ae.mjs";
5
- import "../../../../content-BO61Sx4j.mjs";
6
- import "../../../../base64-C74Msx8h.mjs";
7
- import "../../../../types-Ch8pFMEm.mjs";
8
- import "../../../../media-D2ZFowpn.mjs";
9
- import "../../../../taxonomy-BkxbUMSw.mjs";
5
+ import "../../../../content-BC43pICM.mjs";
6
+ import "../../../../base64-B-PsqheR.mjs";
7
+ import "../../../../types-CrRUFdej.mjs";
8
+ import "../../../../media-its1WLYv.mjs";
9
+ import "../../../../taxonomy-0mCI25HN.mjs";
10
10
  import { t as OptionsRepository } from "../../../../options-BlmBHTvX.mjs";
11
- import "../../../../redirect-Ch3E98qZ.mjs";
11
+ import "../../../../redirect-BoUac4NT.mjs";
12
12
  import "../../../../request-cache-BSUptuJR.mjs";
13
13
  import "../../../../byline-registry-BCuOp4UF.mjs";
14
- import "../../../../field-defs-cache-BVrNCgSj.mjs";
15
- import "../../../../byline-BWb5H-65.mjs";
16
- import "../../../../fts-manager-BD9s77qh.mjs";
17
- import "../../../../loader-Rb8QlGZp.mjs";
18
- import "../../../../content-refresh-BkkApzeS.mjs";
19
- import { n as apiSuccess, r as handleError, t as apiError } from "../../../../error-CfJMLSkd.mjs";
20
- import "../../../../registry-CyIXPi4E.mjs";
21
- import "../../../../settings-BuQYvLfy.mjs";
22
- import "../../../../ssrf-TrKYJAy0.mjs";
23
- import { n as parseBody, t as isParseError } from "../../../../parse-GLksnn-B.mjs";
24
- import "../../../../redirects-CeD7K7EX.mjs";
25
- import { x as setupBody } from "../../../../relations-BmBmX4Eb.mjs";
26
- import "../../../../status-D3Gy1Zc6.mjs";
14
+ import "../../../../field-defs-cache-KfNJ_qLQ.mjs";
15
+ import "../../../../byline-BTOxUlFF.mjs";
16
+ import "../../../../fts-manager-hyCU9OOp.mjs";
17
+ import "../../../../loader-D4rigvjR.mjs";
18
+ import "../../../../content-refresh-CPMSauD3.mjs";
19
+ import "../../../../registry-y21kjhfG.mjs";
20
+ import "../../../../settings-C2PaBS49.mjs";
21
+ import "../../../../ssrf-CviKqWmq.mjs";
22
+ import { n as apiSuccess, r as handleError, t as apiError } from "../../../../error-DJ98TRbQ.mjs";
23
+ import { n as parseBody, t as isParseError } from "../../../../parse-53zyxlpv.mjs";
24
+ import "../../../../media-BJ6SRY3g.mjs";
25
+ import "../../../../redirects-D457qwt0.mjs";
26
+ import { x as setupBody } from "../../../../relations-CZMpBqEd.mjs";
27
+ import "../../../../status-COfycGIU.mjs";
27
28
  import "../../../../api/schemas/index.mjs";
28
- import "../../../../ssrf-B5DOv5E5.mjs";
29
- import { t as validateSeed } from "../../../../validate-C3CpWlNt.mjs";
30
- import { t as applySeed } from "../../../../apply-D23iUV4q.mjs";
31
- import { t as loadSeed } from "../../../../load-DgoWMdRX.mjs";
32
- import { n as getPublicOrigin } from "../../../../public-url-C0cEvrRu.mjs";
33
- import { t as getAuthMode } from "../../../../mode-BVnhGZ2o.mjs";
29
+ import "../../../../ssrf-BB__xfNM.mjs";
30
+ import { t as validateSeed } from "../../../../validate-CDT1jl6_.mjs";
31
+ import { t as applySeed } from "../../../../apply-fGHCAwWN.mjs";
32
+ import { t as loadSeed } from "../../../../load-Dg5gtWma.mjs";
33
+ import { n as getPublicOrigin } from "../../../../public-url-DSGTnJFw.mjs";
34
+ import { t as getAuthMode } from "../../../../mode-fiXRMfeA.mjs";
34
35
 
35
36
  //#region src/astro/routes/api/setup/index.ts
36
37
  const prerender = false;