emdash 0.20.0 → 0.22.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (685) hide show
  1. package/dist/{adapters-BzIHV3sw.d.mts → adapters-hUy8vOB-.d.mts} +1 -1
  2. package/dist/{adapters-BzIHV3sw.d.mts.map → adapters-hUy8vOB-.d.mts.map} +1 -1
  3. package/dist/after-B1IIdH3Y.mjs +29 -0
  4. package/dist/after-B1IIdH3Y.mjs.map +1 -0
  5. package/dist/{allowed-origins-B1u7Qnvg.mjs → allowed-origins-DjlhyfNN.mjs} +2 -2
  6. package/dist/{allowed-origins-B1u7Qnvg.mjs.map → allowed-origins-DjlhyfNN.mjs.map} +1 -1
  7. package/dist/api/route-utils.d.mts +3 -3
  8. package/dist/api/route-utils.mjs +20 -18
  9. package/dist/api/route-utils.mjs.map +1 -1
  10. package/dist/api/schemas/index.d.mts +2 -2
  11. package/dist/api/schemas/index.mjs +4 -3
  12. package/dist/{api-DStv36ik.mjs → api-BDuM4bEy.mjs} +31 -25
  13. package/dist/api-BDuM4bEy.mjs.map +1 -0
  14. package/dist/{api-tokens-DPfhPu5V.mjs → api-tokens-ViYKeIp9.mjs} +13 -3
  15. package/dist/api-tokens-ViYKeIp9.mjs.map +1 -0
  16. package/dist/{apply-Dr7snAMT.mjs → apply-wDqQoxX4.mjs} +18 -18
  17. package/dist/{apply-Dr7snAMT.mjs.map → apply-wDqQoxX4.mjs.map} +1 -1
  18. package/dist/astro/image-endpoint.d.mts +8 -0
  19. package/dist/astro/image-endpoint.d.mts.map +1 -0
  20. package/dist/astro/image-endpoint.mjs +55 -0
  21. package/dist/astro/image-endpoint.mjs.map +1 -0
  22. package/dist/astro/index.d.mts +36 -11
  23. package/dist/astro/index.d.mts.map +1 -1
  24. package/dist/astro/index.mjs +160 -35
  25. package/dist/astro/index.mjs.map +1 -1
  26. package/dist/astro/middleware/auth.d.mts +9 -9
  27. package/dist/astro/middleware/auth.d.mts.map +1 -1
  28. package/dist/astro/middleware/auth.mjs +12 -10
  29. package/dist/astro/middleware/auth.mjs.map +1 -1
  30. package/dist/astro/middleware/redirect.d.mts.map +1 -1
  31. package/dist/astro/middleware/redirect.mjs +14 -5
  32. package/dist/astro/middleware/redirect.mjs.map +1 -1
  33. package/dist/astro/middleware/request-context.mjs +5 -4
  34. package/dist/astro/middleware/request-context.mjs.map +1 -1
  35. package/dist/astro/middleware/setup.mjs +1 -1
  36. package/dist/astro/middleware.d.mts +1 -1
  37. package/dist/astro/middleware.d.mts.map +1 -1
  38. package/dist/astro/middleware.mjs +157 -80
  39. package/dist/astro/middleware.mjs.map +1 -1
  40. package/dist/astro/routes/api/admin/allowed-domains/_domain_.mjs +7 -6
  41. package/dist/astro/routes/api/admin/allowed-domains/_domain_.mjs.map +1 -1
  42. package/dist/astro/routes/api/admin/allowed-domains/index.mjs +7 -6
  43. package/dist/astro/routes/api/admin/allowed-domains/index.mjs.map +1 -1
  44. package/dist/astro/routes/api/admin/api-tokens/_id_.mjs +5 -5
  45. package/dist/astro/routes/api/admin/api-tokens/index.mjs +6 -6
  46. package/dist/astro/routes/api/admin/byline-fields/_slug_/usage.mjs +6 -6
  47. package/dist/astro/routes/api/admin/byline-fields/_slug_.mjs +10 -9
  48. package/dist/astro/routes/api/admin/byline-fields/_slug_.mjs.map +1 -1
  49. package/dist/astro/routes/api/admin/byline-fields/index.mjs +10 -9
  50. package/dist/astro/routes/api/admin/byline-fields/index.mjs.map +1 -1
  51. package/dist/astro/routes/api/admin/byline-fields/reorder.mjs +10 -9
  52. package/dist/astro/routes/api/admin/byline-fields/reorder.mjs.map +1 -1
  53. package/dist/astro/routes/api/admin/bylines/_id_/index.mjs +17 -14
  54. package/dist/astro/routes/api/admin/bylines/_id_/index.mjs.map +1 -1
  55. package/dist/astro/routes/api/admin/bylines/_id_/translations.mjs +17 -14
  56. package/dist/astro/routes/api/admin/bylines/_id_/translations.mjs.map +1 -1
  57. package/dist/astro/routes/api/admin/bylines/index.mjs +17 -14
  58. package/dist/astro/routes/api/admin/bylines/index.mjs.map +1 -1
  59. package/dist/astro/routes/api/admin/comments/_id_/status.mjs +15 -12
  60. package/dist/astro/routes/api/admin/comments/_id_/status.mjs.map +1 -1
  61. package/dist/astro/routes/api/admin/comments/_id_.mjs +8 -6
  62. package/dist/astro/routes/api/admin/comments/_id_.mjs.map +1 -1
  63. package/dist/astro/routes/api/admin/comments/bulk.mjs +12 -9
  64. package/dist/astro/routes/api/admin/comments/bulk.mjs.map +1 -1
  65. package/dist/astro/routes/api/admin/comments/counts.mjs +8 -6
  66. package/dist/astro/routes/api/admin/comments/counts.mjs.map +1 -1
  67. package/dist/astro/routes/api/admin/comments/index.mjs +12 -9
  68. package/dist/astro/routes/api/admin/comments/index.mjs.map +1 -1
  69. package/dist/astro/routes/api/admin/hooks/exclusive/_hookName_.mjs +6 -6
  70. package/dist/astro/routes/api/admin/hooks/exclusive/index.mjs +5 -5
  71. package/dist/astro/routes/api/admin/oauth-clients/_id_.mjs +5 -5
  72. package/dist/astro/routes/api/admin/oauth-clients/index.mjs +5 -5
  73. package/dist/astro/routes/api/admin/plugins/_id_/disable.mjs +40 -37
  74. package/dist/astro/routes/api/admin/plugins/_id_/disable.mjs.map +1 -1
  75. package/dist/astro/routes/api/admin/plugins/_id_/enable.mjs +40 -37
  76. package/dist/astro/routes/api/admin/plugins/_id_/enable.mjs.map +1 -1
  77. package/dist/astro/routes/api/admin/plugins/_id_/index.mjs +39 -36
  78. package/dist/astro/routes/api/admin/plugins/_id_/index.mjs.map +1 -1
  79. package/dist/astro/routes/api/admin/plugins/_id_/uninstall.mjs +39 -36
  80. package/dist/astro/routes/api/admin/plugins/_id_/uninstall.mjs.map +1 -1
  81. package/dist/astro/routes/api/admin/plugins/_id_/update.mjs +39 -36
  82. package/dist/astro/routes/api/admin/plugins/_id_/update.mjs.map +1 -1
  83. package/dist/astro/routes/api/admin/plugins/index.mjs +39 -36
  84. package/dist/astro/routes/api/admin/plugins/index.mjs.map +1 -1
  85. package/dist/astro/routes/api/admin/plugins/marketplace/_id_/icon.mjs +4 -4
  86. package/dist/astro/routes/api/admin/plugins/marketplace/_id_/index.mjs +39 -36
  87. package/dist/astro/routes/api/admin/plugins/marketplace/_id_/index.mjs.map +1 -1
  88. package/dist/astro/routes/api/admin/plugins/marketplace/_id_/install.mjs +39 -36
  89. package/dist/astro/routes/api/admin/plugins/marketplace/_id_/install.mjs.map +1 -1
  90. package/dist/astro/routes/api/admin/plugins/marketplace/index.mjs +39 -36
  91. package/dist/astro/routes/api/admin/plugins/marketplace/index.mjs.map +1 -1
  92. package/dist/astro/routes/api/admin/plugins/registry/_id_/uninstall.mjs +39 -36
  93. package/dist/astro/routes/api/admin/plugins/registry/_id_/uninstall.mjs.map +1 -1
  94. package/dist/astro/routes/api/admin/plugins/registry/_id_/update.mjs +40 -37
  95. package/dist/astro/routes/api/admin/plugins/registry/_id_/update.mjs.map +1 -1
  96. package/dist/astro/routes/api/admin/plugins/registry/artifact.mjs +39 -36
  97. package/dist/astro/routes/api/admin/plugins/registry/artifact.mjs.map +1 -1
  98. package/dist/astro/routes/api/admin/plugins/registry/install.mjs +40 -37
  99. package/dist/astro/routes/api/admin/plugins/registry/install.mjs.map +1 -1
  100. package/dist/astro/routes/api/admin/plugins/updates.mjs +39 -36
  101. package/dist/astro/routes/api/admin/plugins/updates.mjs.map +1 -1
  102. package/dist/astro/routes/api/admin/themes/marketplace/_id_/index.mjs +39 -36
  103. package/dist/astro/routes/api/admin/themes/marketplace/_id_/index.mjs.map +1 -1
  104. package/dist/astro/routes/api/admin/themes/marketplace/_id_/thumbnail.mjs +4 -4
  105. package/dist/astro/routes/api/admin/themes/marketplace/index.mjs +39 -36
  106. package/dist/astro/routes/api/admin/themes/marketplace/index.mjs.map +1 -1
  107. package/dist/astro/routes/api/admin/users/_id_/disable.mjs +4 -4
  108. package/dist/astro/routes/api/admin/users/_id_/enable.mjs +3 -3
  109. package/dist/astro/routes/api/admin/users/_id_/index.mjs +8 -7
  110. package/dist/astro/routes/api/admin/users/_id_/index.mjs.map +1 -1
  111. package/dist/astro/routes/api/admin/users/_id_/send-recovery.mjs +5 -5
  112. package/dist/astro/routes/api/admin/users/index.mjs +7 -6
  113. package/dist/astro/routes/api/admin/users/index.mjs.map +1 -1
  114. package/dist/astro/routes/api/auth/dev-bypass.mjs +6 -6
  115. package/dist/astro/routes/api/auth/invite/accept.mjs +3 -3
  116. package/dist/astro/routes/api/auth/invite/complete.mjs +12 -11
  117. package/dist/astro/routes/api/auth/invite/complete.mjs.map +1 -1
  118. package/dist/astro/routes/api/auth/invite/index.mjs +9 -8
  119. package/dist/astro/routes/api/auth/invite/index.mjs.map +1 -1
  120. package/dist/astro/routes/api/auth/invite/register-options.mjs +11 -10
  121. package/dist/astro/routes/api/auth/invite/register-options.mjs.map +1 -1
  122. package/dist/astro/routes/api/auth/logout.mjs +4 -4
  123. package/dist/astro/routes/api/auth/magic-link/send.mjs +11 -10
  124. package/dist/astro/routes/api/auth/magic-link/send.mjs.map +1 -1
  125. package/dist/astro/routes/api/auth/magic-link/verify.mjs +4 -4
  126. package/dist/astro/routes/api/auth/me.mjs +8 -7
  127. package/dist/astro/routes/api/auth/me.mjs.map +1 -1
  128. package/dist/astro/routes/api/auth/mode.mjs +1 -1
  129. package/dist/astro/routes/api/auth/oauth/_provider_/callback.mjs +4 -4
  130. package/dist/astro/routes/api/auth/oauth/_provider_.mjs +2 -2
  131. package/dist/astro/routes/api/auth/passkey/_id_.mjs +7 -6
  132. package/dist/astro/routes/api/auth/passkey/_id_.mjs.map +1 -1
  133. package/dist/astro/routes/api/auth/passkey/index.mjs +3 -3
  134. package/dist/astro/routes/api/auth/passkey/options.mjs +13 -12
  135. package/dist/astro/routes/api/auth/passkey/options.mjs.map +1 -1
  136. package/dist/astro/routes/api/auth/passkey/register/options.mjs +11 -10
  137. package/dist/astro/routes/api/auth/passkey/register/options.mjs.map +1 -1
  138. package/dist/astro/routes/api/auth/passkey/register/verify.mjs +12 -11
  139. package/dist/astro/routes/api/auth/passkey/register/verify.mjs.map +1 -1
  140. package/dist/astro/routes/api/auth/passkey/verify.mjs +12 -11
  141. package/dist/astro/routes/api/auth/passkey/verify.mjs.map +1 -1
  142. package/dist/astro/routes/api/auth/signup/complete.mjs +12 -11
  143. package/dist/astro/routes/api/auth/signup/complete.mjs.map +1 -1
  144. package/dist/astro/routes/api/auth/signup/request.mjs +11 -10
  145. package/dist/astro/routes/api/auth/signup/request.mjs.map +1 -1
  146. package/dist/astro/routes/api/auth/signup/verify.mjs +3 -3
  147. package/dist/astro/routes/api/comments/_collection_/_contentId_/index.mjs +16 -13
  148. package/dist/astro/routes/api/comments/_collection_/_contentId_/index.mjs.map +1 -1
  149. package/dist/astro/routes/api/comments/_collection_/_contentId_/reactions.d.mts +9 -0
  150. package/dist/astro/routes/api/comments/_collection_/_contentId_/reactions.d.mts.map +1 -0
  151. package/dist/astro/routes/api/comments/_collection_/_contentId_/reactions.mjs +179 -0
  152. package/dist/astro/routes/api/comments/_collection_/_contentId_/reactions.mjs.map +1 -0
  153. package/dist/astro/routes/api/content/_collection_/_id_/compare.mjs +4 -4
  154. package/dist/astro/routes/api/content/_collection_/_id_/discard-draft.mjs +4 -4
  155. package/dist/astro/routes/api/content/_collection_/_id_/duplicate.mjs +4 -4
  156. package/dist/astro/routes/api/content/_collection_/_id_/permanent.mjs +4 -4
  157. package/dist/astro/routes/api/content/_collection_/_id_/preview-url.mjs +13 -11
  158. package/dist/astro/routes/api/content/_collection_/_id_/preview-url.mjs.map +1 -1
  159. package/dist/astro/routes/api/content/_collection_/_id_/publish.mjs +8 -7
  160. package/dist/astro/routes/api/content/_collection_/_id_/publish.mjs.map +1 -1
  161. package/dist/astro/routes/api/content/_collection_/_id_/restore.mjs +4 -4
  162. package/dist/astro/routes/api/content/_collection_/_id_/revisions.mjs +4 -4
  163. package/dist/astro/routes/api/content/_collection_/_id_/schedule.mjs +8 -7
  164. package/dist/astro/routes/api/content/_collection_/_id_/schedule.mjs.map +1 -1
  165. package/dist/astro/routes/api/content/_collection_/_id_/terms/_taxonomy_.mjs +17 -14
  166. package/dist/astro/routes/api/content/_collection_/_id_/terms/_taxonomy_.mjs.map +1 -1
  167. package/dist/astro/routes/api/content/_collection_/_id_/translations.mjs +4 -4
  168. package/dist/astro/routes/api/content/_collection_/_id_/unpublish.mjs +4 -4
  169. package/dist/astro/routes/api/content/_collection_/_id_.mjs +8 -7
  170. package/dist/astro/routes/api/content/_collection_/_id_.mjs.map +1 -1
  171. package/dist/astro/routes/api/content/_collection_/authors.mjs +4 -4
  172. package/dist/astro/routes/api/content/_collection_/index.mjs +8 -7
  173. package/dist/astro/routes/api/content/_collection_/index.mjs.map +1 -1
  174. package/dist/astro/routes/api/content/_collection_/trash.mjs +8 -7
  175. package/dist/astro/routes/api/content/_collection_/trash.mjs.map +1 -1
  176. package/dist/astro/routes/api/dashboard.mjs +10 -8
  177. package/dist/astro/routes/api/dashboard.mjs.map +1 -1
  178. package/dist/astro/routes/api/dev/emails.mjs +4 -4
  179. package/dist/astro/routes/api/import/probe.d.mts +3 -3
  180. package/dist/astro/routes/api/import/probe.mjs +12 -11
  181. package/dist/astro/routes/api/import/probe.mjs.map +1 -1
  182. package/dist/astro/routes/api/import/wordpress/analyze.mjs +5 -5
  183. package/dist/astro/routes/api/import/wordpress/execute.d.mts +9 -9
  184. package/dist/astro/routes/api/import/wordpress/execute.mjs +16 -14
  185. package/dist/astro/routes/api/import/wordpress/execute.mjs.map +1 -1
  186. package/dist/astro/routes/api/import/wordpress/media.mjs +10 -9
  187. package/dist/astro/routes/api/import/wordpress/media.mjs.map +1 -1
  188. package/dist/astro/routes/api/import/wordpress/prepare.mjs +11 -10
  189. package/dist/astro/routes/api/import/wordpress/prepare.mjs.map +1 -1
  190. package/dist/astro/routes/api/import/wordpress/rewrite-urls.mjs +10 -9
  191. package/dist/astro/routes/api/import/wordpress/rewrite-urls.mjs.map +1 -1
  192. package/dist/astro/routes/api/import/wordpress-plugin/analyze.d.mts +1 -1
  193. package/dist/astro/routes/api/import/wordpress-plugin/analyze.mjs +12 -11
  194. package/dist/astro/routes/api/import/wordpress-plugin/analyze.mjs.map +1 -1
  195. package/dist/astro/routes/api/import/wordpress-plugin/callback.mjs +1 -1
  196. package/dist/astro/routes/api/import/wordpress-plugin/execute.d.mts +1 -1
  197. package/dist/astro/routes/api/import/wordpress-plugin/execute.mjs +18 -15
  198. package/dist/astro/routes/api/import/wordpress-plugin/execute.mjs.map +1 -1
  199. package/dist/astro/routes/api/manifest.mjs +5 -5
  200. package/dist/astro/routes/api/mcp.mjs +213 -45
  201. package/dist/astro/routes/api/mcp.mjs.map +1 -1
  202. package/dist/astro/routes/api/media/_id_/confirm.mjs +8 -7
  203. package/dist/astro/routes/api/media/_id_/confirm.mjs.map +1 -1
  204. package/dist/astro/routes/api/media/_id_.mjs +8 -7
  205. package/dist/astro/routes/api/media/_id_.mjs.map +1 -1
  206. package/dist/astro/routes/api/media/file/_...key_.mjs +3 -3
  207. package/dist/astro/routes/api/media/providers/_providerId_/_itemId_.mjs +4 -4
  208. package/dist/astro/routes/api/media/providers/_providerId_/index.mjs +4 -4
  209. package/dist/astro/routes/api/media/providers/index.mjs +4 -4
  210. package/dist/astro/routes/api/media/upload-url.mjs +10 -9
  211. package/dist/astro/routes/api/media/upload-url.mjs.map +1 -1
  212. package/dist/astro/routes/api/media.mjs +13 -12
  213. package/dist/astro/routes/api/media.mjs.map +1 -1
  214. package/dist/astro/routes/api/menus/_name_/items/_id_.mjs +11 -8
  215. package/dist/astro/routes/api/menus/_name_/items/_id_.mjs.map +1 -1
  216. package/dist/astro/routes/api/menus/_name_/items.mjs +11 -8
  217. package/dist/astro/routes/api/menus/_name_/items.mjs.map +1 -1
  218. package/dist/astro/routes/api/menus/_name_/reorder.mjs +11 -8
  219. package/dist/astro/routes/api/menus/_name_/reorder.mjs.map +1 -1
  220. package/dist/astro/routes/api/menus/_name_/translations.mjs +11 -8
  221. package/dist/astro/routes/api/menus/_name_/translations.mjs.map +1 -1
  222. package/dist/astro/routes/api/menus/_name_.mjs +11 -8
  223. package/dist/astro/routes/api/menus/_name_.mjs.map +1 -1
  224. package/dist/astro/routes/api/menus/index.mjs +11 -8
  225. package/dist/astro/routes/api/menus/index.mjs.map +1 -1
  226. package/dist/astro/routes/api/oauth/authorize.mjs +6 -6
  227. package/dist/astro/routes/api/oauth/device/authorize.mjs +7 -7
  228. package/dist/astro/routes/api/oauth/device/code.mjs +10 -10
  229. package/dist/astro/routes/api/oauth/device/token.mjs +9 -9
  230. package/dist/astro/routes/api/oauth/register.mjs +4 -4
  231. package/dist/astro/routes/api/oauth/token/refresh.mjs +7 -7
  232. package/dist/astro/routes/api/oauth/token/revoke.mjs +7 -7
  233. package/dist/astro/routes/api/oauth/token.mjs +7 -7
  234. package/dist/astro/routes/api/openapi.json.mjs +5 -4
  235. package/dist/astro/routes/api/openapi.json.mjs.map +1 -1
  236. package/dist/astro/routes/api/plugins/_pluginId_/_...path_.mjs +5 -5
  237. package/dist/astro/routes/api/redirects/404s/index.mjs +11 -10
  238. package/dist/astro/routes/api/redirects/404s/index.mjs.map +1 -1
  239. package/dist/astro/routes/api/redirects/404s/summary.mjs +11 -10
  240. package/dist/astro/routes/api/redirects/404s/summary.mjs.map +1 -1
  241. package/dist/astro/routes/api/redirects/_id_.mjs +12 -11
  242. package/dist/astro/routes/api/redirects/_id_.mjs.map +1 -1
  243. package/dist/astro/routes/api/redirects/index.mjs +12 -11
  244. package/dist/astro/routes/api/redirects/index.mjs.map +1 -1
  245. package/dist/astro/routes/api/revisions/_revisionId_/index.mjs +4 -4
  246. package/dist/astro/routes/api/revisions/_revisionId_/restore.mjs +4 -4
  247. package/dist/astro/routes/api/schema/collections/_slug_/fields/_fieldSlug_.mjs +39 -36
  248. package/dist/astro/routes/api/schema/collections/_slug_/fields/_fieldSlug_.mjs.map +1 -1
  249. package/dist/astro/routes/api/schema/collections/_slug_/fields/index.mjs +39 -36
  250. package/dist/astro/routes/api/schema/collections/_slug_/fields/index.mjs.map +1 -1
  251. package/dist/astro/routes/api/schema/collections/_slug_/fields/reorder.mjs +39 -36
  252. package/dist/astro/routes/api/schema/collections/_slug_/fields/reorder.mjs.map +1 -1
  253. package/dist/astro/routes/api/schema/collections/_slug_/index.mjs +39 -36
  254. package/dist/astro/routes/api/schema/collections/_slug_/index.mjs.map +1 -1
  255. package/dist/astro/routes/api/schema/collections/index.mjs +39 -36
  256. package/dist/astro/routes/api/schema/collections/index.mjs.map +1 -1
  257. package/dist/astro/routes/api/schema/index.mjs +7 -7
  258. package/dist/astro/routes/api/schema/orphans/_slug_.mjs +39 -36
  259. package/dist/astro/routes/api/schema/orphans/_slug_.mjs.map +1 -1
  260. package/dist/astro/routes/api/schema/orphans/index.mjs +39 -36
  261. package/dist/astro/routes/api/schema/orphans/index.mjs.map +1 -1
  262. package/dist/astro/routes/api/search/enable.mjs +11 -10
  263. package/dist/astro/routes/api/search/enable.mjs.map +1 -1
  264. package/dist/astro/routes/api/search/index.mjs +10 -9
  265. package/dist/astro/routes/api/search/index.mjs.map +1 -1
  266. package/dist/astro/routes/api/search/rebuild.mjs +11 -10
  267. package/dist/astro/routes/api/search/rebuild.mjs.map +1 -1
  268. package/dist/astro/routes/api/search/stats.mjs +7 -7
  269. package/dist/astro/routes/api/search/suggest.mjs +10 -9
  270. package/dist/astro/routes/api/search/suggest.mjs.map +1 -1
  271. package/dist/astro/routes/api/sections/_slug_.mjs +10 -9
  272. package/dist/astro/routes/api/sections/_slug_.mjs.map +1 -1
  273. package/dist/astro/routes/api/sections/index.mjs +10 -9
  274. package/dist/astro/routes/api/sections/index.mjs.map +1 -1
  275. package/dist/astro/routes/api/settings/email.mjs +6 -6
  276. package/dist/astro/routes/api/settings.mjs +16 -13
  277. package/dist/astro/routes/api/settings.mjs.map +1 -1
  278. package/dist/astro/routes/api/setup/admin-verify.mjs +13 -12
  279. package/dist/astro/routes/api/setup/admin-verify.mjs.map +1 -1
  280. package/dist/astro/routes/api/setup/admin.mjs +12 -11
  281. package/dist/astro/routes/api/setup/admin.mjs.map +1 -1
  282. package/dist/astro/routes/api/setup/dev-bypass.d.mts.map +1 -1
  283. package/dist/astro/routes/api/setup/dev-bypass.mjs +29 -26
  284. package/dist/astro/routes/api/setup/dev-bypass.mjs.map +1 -1
  285. package/dist/astro/routes/api/setup/dev-reset.mjs +4 -4
  286. package/dist/astro/routes/api/setup/index.mjs +29 -26
  287. package/dist/astro/routes/api/setup/index.mjs.map +1 -1
  288. package/dist/astro/routes/api/setup/status.mjs +5 -5
  289. package/dist/astro/routes/api/snapshot.d.mts.map +1 -1
  290. package/dist/astro/routes/api/snapshot.mjs +10 -8
  291. package/dist/astro/routes/api/snapshot.mjs.map +1 -1
  292. package/dist/astro/routes/api/taxonomies/_name_/terms/_slug_/translations.mjs +16 -13
  293. package/dist/astro/routes/api/taxonomies/_name_/terms/_slug_/translations.mjs.map +1 -1
  294. package/dist/astro/routes/api/taxonomies/_name_/terms/_slug_.mjs +16 -13
  295. package/dist/astro/routes/api/taxonomies/_name_/terms/_slug_.mjs.map +1 -1
  296. package/dist/astro/routes/api/taxonomies/_name_/terms/index.mjs +16 -13
  297. package/dist/astro/routes/api/taxonomies/_name_/terms/index.mjs.map +1 -1
  298. package/dist/astro/routes/api/taxonomies/index.mjs +16 -13
  299. package/dist/astro/routes/api/taxonomies/index.mjs.map +1 -1
  300. package/dist/astro/routes/api/themes/preview.mjs +8 -7
  301. package/dist/astro/routes/api/themes/preview.mjs.map +1 -1
  302. package/dist/astro/routes/api/typegen.mjs +6 -6
  303. package/dist/astro/routes/api/well-known/auth.mjs +2 -2
  304. package/dist/astro/routes/api/well-known/oauth-authorization-server.mjs +2 -2
  305. package/dist/astro/routes/api/well-known/oauth-protected-resource.mjs +2 -2
  306. package/dist/astro/routes/api/widget-areas/_name_/reorder.mjs +8 -7
  307. package/dist/astro/routes/api/widget-areas/_name_/reorder.mjs.map +1 -1
  308. package/dist/astro/routes/api/widget-areas/_name_/widgets/_id_.mjs +11 -10
  309. package/dist/astro/routes/api/widget-areas/_name_/widgets/_id_.mjs.map +1 -1
  310. package/dist/astro/routes/api/widget-areas/_name_/widgets.mjs +11 -10
  311. package/dist/astro/routes/api/widget-areas/_name_/widgets.mjs.map +1 -1
  312. package/dist/astro/routes/api/widget-areas/_name_.mjs +7 -7
  313. package/dist/astro/routes/api/widget-areas/index.mjs +11 -10
  314. package/dist/astro/routes/api/widget-areas/index.mjs.map +1 -1
  315. package/dist/astro/routes/api/widget-components.mjs +4 -4
  316. package/dist/astro/routes/robots.txt.mjs +10 -8
  317. package/dist/astro/routes/robots.txt.mjs.map +1 -1
  318. package/dist/astro/routes/sitemap-_collection_.xml.mjs +13 -11
  319. package/dist/astro/routes/sitemap-_collection_.xml.mjs.map +1 -1
  320. package/dist/astro/routes/sitemap.xml.mjs +11 -9
  321. package/dist/astro/routes/sitemap.xml.mjs.map +1 -1
  322. package/dist/astro/types.d.mts +16 -12
  323. package/dist/astro/types.d.mts.map +1 -1
  324. package/dist/auth/providers/github.d.mts +1 -1
  325. package/dist/auth/providers/google.d.mts +1 -1
  326. package/dist/{authorize-DsMSVSaY.mjs → authorize-C0EYoUeV.mjs} +2 -2
  327. package/dist/{authorize-DsMSVSaY.mjs.map → authorize-C0EYoUeV.mjs.map} +1 -1
  328. package/dist/{base64-CqR-7kqF.mjs → base64-CmWvODNW.mjs} +1 -1
  329. package/dist/{base64-CqR-7kqF.mjs.map → base64-CmWvODNW.mjs.map} +1 -1
  330. package/dist/{byline-DUx48sJp.mjs → byline-CC0WS4Gu.mjs} +40 -18
  331. package/dist/byline-CC0WS4Gu.mjs.map +1 -0
  332. package/dist/{byline-fields-8TMtkBnH.mjs → byline-fields-53i9Et0x.mjs} +3 -3
  333. package/dist/{byline-fields-8TMtkBnH.mjs.map → byline-fields-53i9Et0x.mjs.map} +1 -1
  334. package/dist/{byline-fields--WxSNS79.mjs → byline-fields-DNp0HNKc.mjs} +2 -2
  335. package/dist/{byline-fields--WxSNS79.mjs.map → byline-fields-DNp0HNKc.mjs.map} +1 -1
  336. package/dist/{byline-fields-DbibsvTl.d.mts → byline-fields-jy07PZJM.d.mts} +9 -4
  337. package/dist/byline-fields-jy07PZJM.d.mts.map +1 -0
  338. package/dist/{byline-registry-CWP7I71B.mjs → byline-registry-BOjqDOim.mjs} +3 -3
  339. package/dist/{byline-registry-CWP7I71B.mjs.map → byline-registry-BOjqDOim.mjs.map} +1 -1
  340. package/dist/{bylines-s8c2DXbH.mjs → bylines-CCO1CYnH.mjs} +8 -8
  341. package/dist/{bylines-s8c2DXbH.mjs.map → bylines-CCO1CYnH.mjs.map} +1 -1
  342. package/dist/{bylines-BdxWCnPL.mjs → bylines-DGekMGGm.mjs} +10 -4
  343. package/dist/{bylines-BdxWCnPL.mjs.map → bylines-DGekMGGm.mjs.map} +1 -1
  344. package/dist/{cache-B_HzASVT.mjs → cache-pXTpun6s.mjs} +3 -3
  345. package/dist/{cache-B_HzASVT.mjs.map → cache-pXTpun6s.mjs.map} +1 -1
  346. package/dist/{challenge-store-DXX3rfdI.mjs → challenge-store-C6E_kWTs.mjs} +1 -1
  347. package/dist/{challenge-store-DXX3rfdI.mjs.map → challenge-store-C6E_kWTs.mjs.map} +1 -1
  348. package/dist/{chunks-BerYVuve.mjs → chunks-SyjZaYwV.mjs} +2 -2
  349. package/dist/{chunks-BerYVuve.mjs.map → chunks-SyjZaYwV.mjs.map} +1 -1
  350. package/dist/cli/index.mjs +29 -27
  351. package/dist/cli/index.mjs.map +1 -1
  352. package/dist/client/cf-access.d.mts +1 -1
  353. package/dist/client/index.d.mts +1 -1
  354. package/dist/client/index.mjs +2 -1
  355. package/dist/client/index.mjs.map +1 -1
  356. package/dist/{comment-sqQxNpN3.mjs → comment-80UyJJUR.mjs} +11 -3
  357. package/dist/comment-80UyJJUR.mjs.map +1 -0
  358. package/dist/comment-reaction-B6AdcpXw.mjs +85 -0
  359. package/dist/comment-reaction-B6AdcpXw.mjs.map +1 -0
  360. package/dist/{comments-Vkivawyl.mjs → comments-CtPkT2tp.mjs} +3 -3
  361. package/dist/{comments-Vkivawyl.mjs.map → comments-CtPkT2tp.mjs.map} +1 -1
  362. package/dist/{components-CK0cuUoH.mjs → components-D6ZnrzbB.mjs} +1 -1
  363. package/dist/{components-CK0cuUoH.mjs.map → components-D6ZnrzbB.mjs.map} +1 -1
  364. package/dist/{content-BIlVx-RX.mjs → content-2PTDNnoh.mjs} +22 -7
  365. package/dist/content-2PTDNnoh.mjs.map +1 -0
  366. package/dist/{context-Y7BRkWes.mjs → context-f1__jpzF.mjs} +11 -11
  367. package/dist/{context-Y7BRkWes.mjs.map → context-f1__jpzF.mjs.map} +1 -1
  368. package/dist/{cron-BJ2ClIlj.mjs → cron-CQPxBjYs.mjs} +1 -1
  369. package/dist/{cron-BJ2ClIlj.mjs.map → cron-CQPxBjYs.mjs.map} +1 -1
  370. package/dist/{dashboard-2JgAMWxK.mjs → dashboard-BOESNcwE.mjs} +4 -4
  371. package/dist/{dashboard-2JgAMWxK.mjs.map → dashboard-BOESNcwE.mjs.map} +1 -1
  372. package/dist/database/instrumentation.d.mts +19 -0
  373. package/dist/database/instrumentation.d.mts.map +1 -1
  374. package/dist/database/instrumentation.mjs +8 -1
  375. package/dist/database/instrumentation.mjs.map +1 -1
  376. package/dist/db/index.d.mts +3 -3
  377. package/dist/db/index.mjs +1 -1
  378. package/dist/db/libsql.d.mts +1 -1
  379. package/dist/db/postgres.d.mts +1 -1
  380. package/dist/db/sqlite.d.mts +1 -1
  381. package/dist/{db-errors-CtzxKBxe.mjs → db-errors-CrC5w3Jz.mjs} +1 -1
  382. package/dist/{db-errors-CtzxKBxe.mjs.map → db-errors-CrC5w3Jz.mjs.map} +1 -1
  383. package/dist/{default-IlBaTFxM.mjs → default-CpBEPn6a.mjs} +1 -1
  384. package/dist/{default-IlBaTFxM.mjs.map → default-CpBEPn6a.mjs.map} +1 -1
  385. package/dist/{device-flow-R23SIbQ2.mjs → device-flow-Bn-qiDrw.mjs} +5 -5
  386. package/dist/{device-flow-R23SIbQ2.mjs.map → device-flow-Bn-qiDrw.mjs.map} +1 -1
  387. package/dist/{email-console-DHT2Fbpj.mjs → email-console-B9VS6eN4.mjs} +1 -1
  388. package/dist/{email-console-DHT2Fbpj.mjs.map → email-console-B9VS6eN4.mjs.map} +1 -1
  389. package/dist/{error-RwM4dD35.mjs → error-BQ1pxs0L.mjs} +2 -2
  390. package/dist/{error-RwM4dD35.mjs.map → error-BQ1pxs0L.mjs.map} +1 -1
  391. package/dist/{escape-Ds07EEyu.mjs → escape-BtbJWyaW.mjs} +1 -1
  392. package/dist/{escape-Ds07EEyu.mjs.map → escape-BtbJWyaW.mjs.map} +1 -1
  393. package/dist/{fts-manager-1RgHmopc.mjs → fts-manager-DtiWqwNJ.mjs} +2 -2
  394. package/dist/{fts-manager-1RgHmopc.mjs.map → fts-manager-DtiWqwNJ.mjs.map} +1 -1
  395. package/dist/{hash-9w3pd3-m.mjs → hash-BowcuPwv.mjs} +1 -1
  396. package/dist/{hash-9w3pd3-m.mjs.map → hash-BowcuPwv.mjs.map} +1 -1
  397. package/dist/{import-Dh8bWmyq.mjs → import-DqSGOlmR.mjs} +4 -4
  398. package/dist/{import-Dh8bWmyq.mjs.map → import-DqSGOlmR.mjs.map} +1 -1
  399. package/dist/{index-B1keaX5Y.d.mts → index-C2dLNT6S.d.mts} +169 -14
  400. package/dist/index-C2dLNT6S.d.mts.map +1 -0
  401. package/dist/{index-DR56od45.d.mts → index-ZDEwR7qW.d.mts} +3 -3
  402. package/dist/{index-DR56od45.d.mts.map → index-ZDEwR7qW.d.mts.map} +1 -1
  403. package/dist/index.d.mts +18 -17
  404. package/dist/index.mjs +63 -59
  405. package/dist/init-lock-6b309ZrF.mjs +56 -0
  406. package/dist/init-lock-6b309ZrF.mjs.map +1 -0
  407. package/dist/{load-BBetCvLC.mjs → load-Dtoo7KcJ.mjs} +2 -2
  408. package/dist/{load-BBetCvLC.mjs.map → load-Dtoo7KcJ.mjs.map} +1 -1
  409. package/dist/{loader-ZN1ll-d-.mjs → loader-C8Z48Uof.mjs} +4 -4
  410. package/dist/{loader-ZN1ll-d-.mjs.map → loader-C8Z48Uof.mjs.map} +1 -1
  411. package/dist/{manifest-schema-BtwbL_vj.mjs → manifest-schema-DDSbwkAL.mjs} +1 -1
  412. package/dist/{manifest-schema-BtwbL_vj.mjs.map → manifest-schema-DDSbwkAL.mjs.map} +1 -1
  413. package/dist/media/image-endpoint.d.mts +74 -0
  414. package/dist/media/image-endpoint.d.mts.map +1 -0
  415. package/dist/media/image-endpoint.mjs +162 -0
  416. package/dist/media/image-endpoint.mjs.map +1 -0
  417. package/dist/media/index.d.mts +1 -1
  418. package/dist/media/index.mjs +2 -2
  419. package/dist/media/local-runtime.d.mts +11 -11
  420. package/dist/media/local-runtime.mjs +9 -7
  421. package/dist/media/local-runtime.mjs.map +1 -1
  422. package/dist/{media-JOf3pNkw.mjs → media-Bw0sA6rb.mjs} +2 -2
  423. package/dist/{media-JOf3pNkw.mjs.map → media-Bw0sA6rb.mjs.map} +1 -1
  424. package/dist/{media-allowlist-Dknq-OFY.mjs → media-allowlist-DunzrKFM.mjs} +2 -2
  425. package/dist/{media-allowlist-Dknq-OFY.mjs.map → media-allowlist-DunzrKFM.mjs.map} +1 -1
  426. package/dist/{media-url-VClf8glU.mjs → media-url-S22B6aPr.mjs} +1 -1
  427. package/dist/{media-url-VClf8glU.mjs.map → media-url-S22B6aPr.mjs.map} +1 -1
  428. package/dist/{menus-DX4_E01q.mjs → menus-CYs0WZoL.mjs} +20 -6
  429. package/dist/menus-CYs0WZoL.mjs.map +1 -0
  430. package/dist/{menus-DrQLusqj.mjs → menus-DOs1MQJg.mjs} +120 -20
  431. package/dist/menus-DOs1MQJg.mjs.map +1 -0
  432. package/dist/{mime-CCEzze7W.mjs → mime-DYpsOAny.mjs} +1 -1
  433. package/dist/{mime-CCEzze7W.mjs.map → mime-DYpsOAny.mjs.map} +1 -1
  434. package/dist/{mode-CO2vQHfq.mjs → mode-CFh8Dw8G.mjs} +1 -1
  435. package/dist/{mode-CO2vQHfq.mjs.map → mode-CFh8Dw8G.mjs.map} +1 -1
  436. package/dist/{normalize-CK5o04zr.mjs → normalize-Uam4_Vkr.mjs} +1 -1
  437. package/dist/{normalize-CK5o04zr.mjs.map → normalize-Uam4_Vkr.mjs.map} +1 -1
  438. package/dist/{oauth-authorization-Bw4NdF_S.mjs → oauth-authorization-BN-t83Uy.mjs} +5 -5
  439. package/dist/{oauth-authorization-Bw4NdF_S.mjs.map → oauth-authorization-BN-t83Uy.mjs.map} +1 -1
  440. package/dist/{oauth-clients-BGGFp57s.mjs → oauth-clients-R6I_V0qz.mjs} +1 -1
  441. package/dist/{oauth-clients-BGGFp57s.mjs.map → oauth-clients-R6I_V0qz.mjs.map} +1 -1
  442. package/dist/{oauth-state-store-97x0xtN2.mjs → oauth-state-store-Csoc6kkR.mjs} +1 -1
  443. package/dist/{oauth-state-store-97x0xtN2.mjs.map → oauth-state-store-Csoc6kkR.mjs.map} +1 -1
  444. package/dist/{oauth-user-lookup-B_vnZHKO.mjs → oauth-user-lookup-d7VYjTpx.mjs} +1 -1
  445. package/dist/{oauth-user-lookup-B_vnZHKO.mjs.map → oauth-user-lookup-d7VYjTpx.mjs.map} +1 -1
  446. package/dist/object-cache/memory.d.mts +15 -0
  447. package/dist/object-cache/memory.d.mts.map +1 -0
  448. package/dist/object-cache/memory.mjs +56 -0
  449. package/dist/object-cache/memory.mjs.map +1 -0
  450. package/dist/object-cache-SEb2IM4Z.mjs +373 -0
  451. package/dist/object-cache-SEb2IM4Z.mjs.map +1 -0
  452. package/dist/{options-DyYIYpPd.d.mts → options-DFFpvNJU.d.mts} +3 -3
  453. package/dist/{options-DyYIYpPd.d.mts.map → options-DFFpvNJU.d.mts.map} +1 -1
  454. package/dist/{options-BPCVnesz.mjs → options-DTTML-Tx.mjs} +1 -1
  455. package/dist/{options-BPCVnesz.mjs.map → options-DTTML-Tx.mjs.map} +1 -1
  456. package/dist/page/index.d.mts +2 -2
  457. package/dist/{parse-CrGndy1A.mjs → parse-qrHlnzTy.mjs} +2 -2
  458. package/dist/{parse-CrGndy1A.mjs.map → parse-qrHlnzTy.mjs.map} +1 -1
  459. package/dist/{passkey-config-C3QgnQnU.mjs → passkey-config-BJTbcnI5.mjs} +1 -1
  460. package/dist/{passkey-config-C3QgnQnU.mjs.map → passkey-config-BJTbcnI5.mjs.map} +1 -1
  461. package/dist/{patterns-p-RBdTbM.mjs → patterns-BKmjvM7K.mjs} +1 -1
  462. package/dist/{patterns-p-RBdTbM.mjs.map → patterns-BKmjvM7K.mjs.map} +1 -1
  463. package/dist/{placeholder-BZxr8W1j.mjs → placeholder-CIDCpyEY.mjs} +1 -1
  464. package/dist/{placeholder-BZxr8W1j.mjs.map → placeholder-CIDCpyEY.mjs.map} +1 -1
  465. package/dist/{placeholder-CVBv5z8k.d.mts → placeholder-CirPauNG.d.mts} +1 -1
  466. package/dist/{placeholder-CVBv5z8k.d.mts.map → placeholder-CirPauNG.d.mts.map} +1 -1
  467. package/dist/plugin-types.d.mts +1 -1
  468. package/dist/plugin-utils.d.mts +9 -9
  469. package/dist/plugins/adapt-sandbox-entry.d.mts +9 -9
  470. package/dist/plugins/adapt-sandbox-entry.mjs +4 -2
  471. package/dist/plugins/adapt-sandbox-entry.mjs.map +1 -1
  472. package/dist/{transport-CmpLD7W3.mjs → portable-text-BIFhrU6T.mjs} +2 -135
  473. package/dist/portable-text-BIFhrU6T.mjs.map +1 -0
  474. package/dist/{preview-BfuRkVKW.mjs → preview-IDye9SPQ.mjs} +2 -2
  475. package/dist/{preview-BfuRkVKW.mjs.map → preview-IDye9SPQ.mjs.map} +1 -1
  476. package/dist/{public-url-BFVC2OTJ.mjs → public-url-8lFyQ8ZF.mjs} +1 -1
  477. package/dist/{public-url-BFVC2OTJ.mjs.map → public-url-8lFyQ8ZF.mjs.map} +1 -1
  478. package/dist/{query-CbUcI4Xk.mjs → query-B1RVFUNM.mjs} +159 -31
  479. package/dist/query-B1RVFUNM.mjs.map +1 -0
  480. package/dist/{rate-limit-C7hjdkS5.mjs → rate-limit-DfNAqIWW.mjs} +2 -2
  481. package/dist/{rate-limit-C7hjdkS5.mjs.map → rate-limit-DfNAqIWW.mjs.map} +1 -1
  482. package/dist/{redirect-B_q19j4v.mjs → redirect-B4wuX2A5.mjs} +1 -1
  483. package/dist/{redirect-B_q19j4v.mjs.map → redirect-B4wuX2A5.mjs.map} +1 -1
  484. package/dist/{redirect-CRWIt8Zj.mjs → redirect-Bifv_yHv.mjs} +3 -3
  485. package/dist/{redirect-CRWIt8Zj.mjs.map → redirect-Bifv_yHv.mjs.map} +1 -1
  486. package/dist/{redirects-DxVoR7PI.mjs → redirects-CT_vb3NV.mjs} +24 -18
  487. package/dist/redirects-CT_vb3NV.mjs.map +1 -0
  488. package/dist/{redirects-CCbCqCCd.mjs → redirects-DUvXgzCX.mjs} +14 -10
  489. package/dist/redirects-DUvXgzCX.mjs.map +1 -0
  490. package/dist/{registry-brYh-rAT.mjs → registry-CjK96fHD.mjs} +6 -6
  491. package/dist/{registry-brYh-rAT.mjs.map → registry-CjK96fHD.mjs.map} +1 -1
  492. package/dist/{request-cache-D32LpnmI.mjs → request-cache-KCNHp_RJ.mjs} +1 -1
  493. package/dist/{request-cache-D32LpnmI.mjs.map → request-cache-KCNHp_RJ.mjs.map} +1 -1
  494. package/dist/{request-meta-7ByVLxB-.mjs → request-meta-ei3ATilC.mjs} +2 -2
  495. package/dist/{request-meta-7ByVLxB-.mjs.map → request-meta-ei3ATilC.mjs.map} +1 -1
  496. package/dist/{resolve-BqYMVG0D.mjs → resolve-CpbBglV0.mjs} +1 -1
  497. package/dist/{resolve-BqYMVG0D.mjs.map → resolve-CpbBglV0.mjs.map} +1 -1
  498. package/dist/{runner--4wMWwKM.mjs → runner-DYYnW530.mjs} +201 -170
  499. package/dist/runner-DYYnW530.mjs.map +1 -0
  500. package/dist/{runner-DTdhuI9i.d.mts → runner-jdXtFEd3.d.mts} +2 -2
  501. package/dist/{runner-DTdhuI9i.d.mts.map → runner-jdXtFEd3.d.mts.map} +1 -1
  502. package/dist/runtime.d.mts +10 -10
  503. package/dist/runtime.mjs +3 -3
  504. package/dist/{schema-C1E70ug_.mjs → schema-5z2Jfnbm.mjs} +13 -8
  505. package/dist/schema-5z2Jfnbm.mjs.map +1 -0
  506. package/dist/{search-B3SGZw91.mjs → search-D9FkoM-k.mjs} +4 -4
  507. package/dist/{search-B3SGZw91.mjs.map → search-D9FkoM-k.mjs.map} +1 -1
  508. package/dist/{secrets-ChPTmy9x.mjs → secrets-BUE5UQys.mjs} +23 -13
  509. package/dist/secrets-BUE5UQys.mjs.map +1 -0
  510. package/dist/{sections-D_lVzwRZ.mjs → sections-DWYZo6HK.mjs} +3 -3
  511. package/dist/{sections-D_lVzwRZ.mjs.map → sections-DWYZo6HK.mjs.map} +1 -1
  512. package/dist/seed/index.d.mts +2 -2
  513. package/dist/seed/index.mjs +22 -20
  514. package/dist/seo/index.d.mts +1 -1
  515. package/dist/seo/index.mjs +1 -1
  516. package/dist/{seo-B5e6y9Wk.mjs → seo-Cu47j3mJ.mjs} +5 -2
  517. package/dist/seo-Cu47j3mJ.mjs.map +1 -0
  518. package/dist/{seo-D_LPkOtu.mjs → seo-DRnqnstF.mjs} +1 -1
  519. package/dist/{seo-D_LPkOtu.mjs.map → seo-DRnqnstF.mjs.map} +1 -1
  520. package/dist/{service-ChDcsTBs.mjs → service-DTmtqCnw.mjs} +3 -3
  521. package/dist/{service-ChDcsTBs.mjs.map → service-DTmtqCnw.mjs.map} +1 -1
  522. package/dist/session-user-DmtPMNa1.mjs +51 -0
  523. package/dist/session-user-DmtPMNa1.mjs.map +1 -0
  524. package/dist/{settings-Cv47v9u8.mjs → settings-DUrVDN0c.mjs} +3 -3
  525. package/dist/{settings-Cv47v9u8.mjs.map → settings-DUrVDN0c.mjs.map} +1 -1
  526. package/dist/settings-yaxu9mU-.mjs +245 -0
  527. package/dist/settings-yaxu9mU-.mjs.map +1 -0
  528. package/dist/{setup-complete-yvPE4OsP.mjs → setup-complete-BWFHzgvZ.mjs} +2 -2
  529. package/dist/{setup-complete-yvPE4OsP.mjs.map → setup-complete-BWFHzgvZ.mjs.map} +1 -1
  530. package/dist/{setup-nonce-C9aFzb94.mjs → setup-nonce-DFWG-J5c.mjs} +1 -1
  531. package/dist/{setup-nonce-C9aFzb94.mjs.map → setup-nonce-DFWG-J5c.mjs.map} +1 -1
  532. package/dist/single-flight-cache-B5p5cNOL.mjs +104 -0
  533. package/dist/single-flight-cache-B5p5cNOL.mjs.map +1 -0
  534. package/dist/{site-url-CnHlmAs9.mjs → site-url-BOTPgmeM.mjs} +2 -2
  535. package/dist/{site-url-CnHlmAs9.mjs.map → site-url-BOTPgmeM.mjs.map} +1 -1
  536. package/dist/{slugify-Cjh1ssOZ.mjs → slugify-Cce3dTdg.mjs} +1 -1
  537. package/dist/{slugify-Cjh1ssOZ.mjs.map → slugify-Cce3dTdg.mjs.map} +1 -1
  538. package/dist/{ssrf-BsVGIE0Z.mjs → ssrf-B0VeRLrp.mjs} +1 -1
  539. package/dist/{ssrf-BsVGIE0Z.mjs.map → ssrf-B0VeRLrp.mjs.map} +1 -1
  540. package/dist/status-CB2basWJ.mjs +30 -0
  541. package/dist/status-CB2basWJ.mjs.map +1 -0
  542. package/dist/storage/local.d.mts +1 -1
  543. package/dist/storage/local.mjs +2 -2
  544. package/dist/storage/s3.d.mts +1 -1
  545. package/dist/storage/s3.mjs +1 -1
  546. package/dist/{taxonomies-BdAmbOwx.mjs → taxonomies-Be9B1jEj.mjs} +156 -122
  547. package/dist/taxonomies-Be9B1jEj.mjs.map +1 -0
  548. package/dist/{taxonomies-BILwiyGk.mjs → taxonomies-CJmkEpdS.mjs} +7 -7
  549. package/dist/{taxonomies-BILwiyGk.mjs.map → taxonomies-CJmkEpdS.mjs.map} +1 -1
  550. package/dist/{taxonomy-CdllE4oq.mjs → taxonomy-B2HQuVf5.mjs} +19 -6
  551. package/dist/taxonomy-B2HQuVf5.mjs.map +1 -0
  552. package/dist/{tokens-Bx2afeT-.mjs → tokens-BvrJvIB6.mjs} +2 -2
  553. package/dist/{tokens-Bx2afeT-.mjs.map → tokens-BvrJvIB6.mjs.map} +1 -1
  554. package/dist/{transaction-x2tJQ-A1.mjs → transaction-qfqpPVpu.mjs} +1 -1
  555. package/dist/{transaction-x2tJQ-A1.mjs.map → transaction-qfqpPVpu.mjs.map} +1 -1
  556. package/dist/transport-B4rXnSTf.mjs +135 -0
  557. package/dist/transport-B4rXnSTf.mjs.map +1 -0
  558. package/dist/{transport-B7PPP2CC.d.mts → transport-k7YjfmEn.d.mts} +1 -1
  559. package/dist/{transport-B7PPP2CC.d.mts.map → transport-k7YjfmEn.d.mts.map} +1 -1
  560. package/dist/{trusted-proxy-B4AfnoAp.mjs → trusted-proxy-DY1_UqHr.mjs} +1 -1
  561. package/dist/{trusted-proxy-B4AfnoAp.mjs.map → trusted-proxy-DY1_UqHr.mjs.map} +1 -1
  562. package/dist/{types-CPAPl93j.d.mts → types-CIKX2HO5.d.mts} +2 -2
  563. package/dist/{types-CPAPl93j.d.mts.map → types-CIKX2HO5.d.mts.map} +1 -1
  564. package/dist/{types-D4kUqbHh.d.mts → types-CKNXt63n.d.mts} +1 -1
  565. package/dist/{types-D4kUqbHh.d.mts.map → types-CKNXt63n.d.mts.map} +1 -1
  566. package/dist/{types-DTniiNto.d.mts → types-CWGYDYqF.d.mts} +2 -2
  567. package/dist/{types-DTniiNto.d.mts.map → types-CWGYDYqF.d.mts.map} +1 -1
  568. package/dist/{types-BH8-30hc.d.mts → types-CgvhU-hF.d.mts} +1 -1
  569. package/dist/{types-BH8-30hc.d.mts.map → types-CgvhU-hF.d.mts.map} +1 -1
  570. package/dist/{types-BFgrqwSk.d.mts → types-CmivgZbp.d.mts} +1 -1
  571. package/dist/{types-BFgrqwSk.d.mts.map → types-CmivgZbp.d.mts.map} +1 -1
  572. package/dist/{types-BPzXTV9x.d.mts → types-Czg1S3gB.d.mts} +9 -1
  573. package/dist/{types-BPzXTV9x.d.mts.map → types-Czg1S3gB.d.mts.map} +1 -1
  574. package/dist/types-DCNNfeCv.d.mts +124 -0
  575. package/dist/types-DCNNfeCv.d.mts.map +1 -0
  576. package/dist/{types-BUUVn1zr.d.mts → types-DPCpkzvS.d.mts} +1 -1
  577. package/dist/{types-BUUVn1zr.d.mts.map → types-DPCpkzvS.d.mts.map} +1 -1
  578. package/dist/{types-S15DXXNi.d.mts → types-DXLVzV2w.d.mts} +1 -1
  579. package/dist/{types-S15DXXNi.d.mts.map → types-DXLVzV2w.d.mts.map} +1 -1
  580. package/dist/{types-BXSUSAjt.mjs → types-DXOIbece.mjs} +3 -3
  581. package/dist/{types-BXSUSAjt.mjs.map → types-DXOIbece.mjs.map} +1 -1
  582. package/dist/{types-DpFmlNyB.mjs → types-DYF2_Vf4.mjs} +1 -1
  583. package/dist/{types-DpFmlNyB.mjs.map → types-DYF2_Vf4.mjs.map} +1 -1
  584. package/dist/{types-DZk_y-MU.mjs → types-tM44hEcf.mjs} +1 -1
  585. package/dist/{types-DZk_y-MU.mjs.map → types-tM44hEcf.mjs.map} +1 -1
  586. package/dist/{user-C0um7wrg.mjs → user-Db-Rti_z.mjs} +3 -3
  587. package/dist/{user-C0um7wrg.mjs.map → user-Db-Rti_z.mjs.map} +1 -1
  588. package/dist/{utils-C4Ih4DML.mjs → utils-LbHcSRTj.mjs} +2 -2
  589. package/dist/{utils-C4Ih4DML.mjs.map → utils-LbHcSRTj.mjs.map} +1 -1
  590. package/dist/{validate-Bz4vqcX1.mjs → validate-Bwl64sxv.mjs} +3 -3
  591. package/dist/{validate-Bz4vqcX1.mjs.map → validate-Bwl64sxv.mjs.map} +1 -1
  592. package/dist/{validate-CNwkPWzz.d.mts → validate-CE2M0nvx.d.mts} +5 -5
  593. package/dist/{validate-CNwkPWzz.d.mts.map → validate-CE2M0nvx.d.mts.map} +1 -1
  594. package/dist/{validation-DgGTJm3u.mjs → validation-C_yOvFaO.mjs} +6 -6
  595. package/dist/{validation-DgGTJm3u.mjs.map → validation-C_yOvFaO.mjs.map} +1 -1
  596. package/dist/version-RnYXYjzD.mjs +7 -0
  597. package/dist/{version-D-5txk2m.mjs.map → version-RnYXYjzD.mjs.map} +1 -1
  598. package/dist/{widgets-DZfmAbE4.mjs → widgets-8GONuRHo.mjs} +4 -4
  599. package/dist/{widgets-DZfmAbE4.mjs.map → widgets-8GONuRHo.mjs.map} +1 -1
  600. package/dist/{zod-generator-Djo_VHCt.mjs → zod-generator-D481JjzD.mjs} +3 -3
  601. package/dist/{zod-generator-Djo_VHCt.mjs.map → zod-generator-D481JjzD.mjs.map} +1 -1
  602. package/package.json +18 -6
  603. package/src/api/handlers/api-tokens.ts +19 -0
  604. package/src/api/handlers/comment-reactions.ts +165 -0
  605. package/src/api/handlers/redirects.ts +24 -13
  606. package/src/api/handlers/schema.ts +8 -0
  607. package/src/api/schemas/comments.ts +10 -0
  608. package/src/api/schemas/redirects.ts +11 -4
  609. package/src/astro/image-endpoint.ts +84 -0
  610. package/src/astro/index.ts +6 -0
  611. package/src/astro/integration/index.ts +127 -30
  612. package/src/astro/integration/routes.ts +51 -9
  613. package/src/astro/integration/runtime.ts +65 -1
  614. package/src/astro/integration/virtual-modules.ts +32 -0
  615. package/src/astro/integration/vite-config.ts +16 -0
  616. package/src/astro/middleware/auth.ts +4 -3
  617. package/src/astro/middleware/redirect.ts +12 -0
  618. package/src/astro/middleware/stream-end-metrics.ts +11 -1
  619. package/src/astro/middleware.ts +41 -3
  620. package/src/astro/object-cache/adapters.ts +50 -0
  621. package/src/astro/prefetch.ts +77 -0
  622. package/src/astro/routes/api/comments/[collection]/[contentId]/reactions.ts +97 -0
  623. package/src/astro/routes/api/setup/dev-bypass.ts +5 -1
  624. package/src/astro/routes/api/snapshot.ts +3 -1
  625. package/src/astro/session-user.ts +57 -0
  626. package/src/astro/types.ts +1 -0
  627. package/src/bylines/field-defs-cache.ts +70 -20
  628. package/src/cli/commands/doctor.ts +1 -1
  629. package/src/comments/query.ts +78 -7
  630. package/src/comments/ranking.ts +58 -0
  631. package/src/components/Comments.astro +136 -1
  632. package/src/config/secrets.ts +28 -14
  633. package/src/database/instrumentation.ts +21 -1
  634. package/src/database/migrations/044_comment_reactions.ts +56 -0
  635. package/src/database/migrations/runner.ts +2 -0
  636. package/src/database/repositories/byline.ts +13 -0
  637. package/src/database/repositories/comment-reaction.ts +132 -0
  638. package/src/database/repositories/comment.ts +10 -0
  639. package/src/database/repositories/content.ts +25 -3
  640. package/src/database/repositories/menu.ts +13 -1
  641. package/src/database/repositories/seo.ts +3 -0
  642. package/src/database/repositories/taxonomy.ts +13 -1
  643. package/src/database/types.ts +9 -0
  644. package/src/emdash-runtime.ts +23 -9
  645. package/src/index.ts +22 -0
  646. package/src/mcp/server.ts +307 -20
  647. package/src/media/image-endpoint.ts +167 -0
  648. package/src/menus/index.ts +11 -4
  649. package/src/object-cache/codec.ts +73 -0
  650. package/src/object-cache/index.ts +495 -0
  651. package/src/object-cache/memory.ts +91 -0
  652. package/src/object-cache/types.ts +124 -0
  653. package/src/plugins/adapt-sandbox-entry.ts +11 -1
  654. package/src/query.ts +196 -17
  655. package/src/redirects/status.ts +27 -0
  656. package/src/schema/query.ts +11 -4
  657. package/src/settings/index.ts +30 -17
  658. package/src/taxonomies/index.ts +237 -165
  659. package/src/utils/{isolate-cache.ts → single-flight-cache.ts} +26 -21
  660. package/src/virtual-modules.d.ts +11 -0
  661. package/dist/api-DStv36ik.mjs.map +0 -1
  662. package/dist/api-tokens-DPfhPu5V.mjs.map +0 -1
  663. package/dist/byline-DUx48sJp.mjs.map +0 -1
  664. package/dist/byline-fields-DbibsvTl.d.mts.map +0 -1
  665. package/dist/comment-sqQxNpN3.mjs.map +0 -1
  666. package/dist/content-BIlVx-RX.mjs.map +0 -1
  667. package/dist/index-B1keaX5Y.d.mts.map +0 -1
  668. package/dist/menus-DX4_E01q.mjs.map +0 -1
  669. package/dist/menus-DrQLusqj.mjs.map +0 -1
  670. package/dist/query-CbUcI4Xk.mjs.map +0 -1
  671. package/dist/redirects-CCbCqCCd.mjs.map +0 -1
  672. package/dist/redirects-DxVoR7PI.mjs.map +0 -1
  673. package/dist/runner--4wMWwKM.mjs.map +0 -1
  674. package/dist/schema-C1E70ug_.mjs.map +0 -1
  675. package/dist/secrets-ChPTmy9x.mjs.map +0 -1
  676. package/dist/seo-B5e6y9Wk.mjs.map +0 -1
  677. package/dist/settings-DfxiWY_s.mjs +0 -411
  678. package/dist/settings-DfxiWY_s.mjs.map +0 -1
  679. package/dist/taxonomies-BdAmbOwx.mjs.map +0 -1
  680. package/dist/taxonomy-CdllE4oq.mjs.map +0 -1
  681. package/dist/transport-CmpLD7W3.mjs.map +0 -1
  682. package/dist/version-D-5txk2m.mjs +0 -7
  683. /package/dist/{api-tokens-Oq39ba-Z.mjs → api-tokens-BVH-H8Z9.mjs} +0 -0
  684. /package/dist/{ssrf-BvgVcfNQ.mjs → ssrf-Cz1e2QPn.mjs} +0 -0
  685. /package/dist/{types-CZI4E3qG.mjs → types-Bfr2Pj6z.mjs} +0 -0
@@ -1,14 +1,15 @@
1
1
  import "../../../../dialect-helpers-DRI5pyY3.mjs";
2
- import "../../../../base64-CqR-7kqF.mjs";
3
- import "../../../../types-BXSUSAjt.mjs";
4
- import "../../../../fts-manager-1RgHmopc.mjs";
5
- import "../../../../loader-ZN1ll-d-.mjs";
6
- import { n as apiSuccess, r as handleError, t as apiError } from "../../../../error-RwM4dD35.mjs";
7
- import { i as parseQuery, t as isParseError } from "../../../../parse-CrGndy1A.mjs";
8
- import { N as searchSuggestQuery } from "../../../../redirects-CCbCqCCd.mjs";
9
- import "../../../../byline-fields-8TMtkBnH.mjs";
2
+ import "../../../../base64-CmWvODNW.mjs";
3
+ import "../../../../types-DXOIbece.mjs";
4
+ import "../../../../fts-manager-DtiWqwNJ.mjs";
5
+ import "../../../../loader-C8Z48Uof.mjs";
6
+ import { n as apiSuccess, r as handleError, t as apiError } from "../../../../error-BQ1pxs0L.mjs";
7
+ import { i as parseQuery, t as isParseError } from "../../../../parse-qrHlnzTy.mjs";
8
+ import { N as searchSuggestQuery } from "../../../../redirects-DUvXgzCX.mjs";
9
+ import "../../../../byline-fields-53i9Et0x.mjs";
10
+ import "../../../../status-CB2basWJ.mjs";
10
11
  import "../../../../api/schemas/index.mjs";
11
- import { a as getSuggestions } from "../../../../search-B3SGZw91.mjs";
12
+ import { a as getSuggestions } from "../../../../search-D9FkoM-k.mjs";
12
13
 
13
14
  //#region src/astro/routes/api/search/suggest.ts
14
15
  const prerender = false;
@@ -1 +1 @@
1
- {"version":3,"file":"suggest.mjs","names":[],"sources":["../../../../../src/astro/routes/api/search/suggest.ts"],"sourcesContent":["/**\n * Search suggestions endpoint - Autocomplete\n *\n * GET /_emdash/api/search/suggest?q=hel&limit=5\n */\n\nimport type { APIRoute } from \"astro\";\n\nimport { apiError, apiSuccess, handleError } from \"#api/error.js\";\nimport { isParseError, parseQuery } from \"#api/parse.js\";\nimport { searchSuggestQuery } from \"#api/schemas.js\";\nimport { getSuggestions } from \"#search/index.js\";\n\nexport const prerender = false;\n\n/**\n * Get search suggestions for autocomplete\n *\n * Query parameters:\n * - q: Partial search query (required)\n * - collections: Comma-separated list of collection slugs (optional)\n * - limit: Maximum suggestions (optional, defaults to 5)\n */\nexport const GET: APIRoute = async ({ url, locals }) => {\n\tconst { emdash } = locals;\n\n\tif (!emdash?.db) {\n\t\treturn apiError(\"NOT_CONFIGURED\", \"EmDash not configured\", 500);\n\t}\n\n\tconst query = parseQuery(url, searchSuggestQuery);\n\tif (isParseError(query)) return query;\n\n\tconst collections = query.collections\n\t\t? query.collections.split(\",\").map((c: string) => c.trim())\n\t\t: undefined;\n\n\ttry {\n\t\t// Verify FTS indexes are healthy on first use. See search/index.ts.\n\t\tawait emdash.ensureSearchHealthy?.();\n\n\t\tconst suggestions = await getSuggestions(emdash.db, query.q, {\n\t\t\tcollections,\n\t\t\tlocale: query.locale,\n\t\t\tlimit: query.limit,\n\t\t});\n\n\t\treturn apiSuccess({ items: suggestions });\n\t} catch (error) {\n\t\treturn handleError(error, \"Failed to get suggestions\", \"SUGGESTION_ERROR\");\n\t}\n};\n"],"mappings":";;;;;;;;;;;;;AAaA,MAAa,YAAY;;;;;;;;;AAUzB,MAAa,MAAgB,OAAO,EAAE,KAAK,aAAa;CACvD,MAAM,EAAE,WAAW;AAEnB,KAAI,CAAC,QAAQ,GACZ,QAAO,SAAS,kBAAkB,yBAAyB,IAAI;CAGhE,MAAM,QAAQ,WAAW,KAAK,mBAAmB;AACjD,KAAI,aAAa,MAAM,CAAE,QAAO;CAEhC,MAAM,cAAc,MAAM,cACvB,MAAM,YAAY,MAAM,IAAI,CAAC,KAAK,MAAc,EAAE,MAAM,CAAC,GACzD;AAEH,KAAI;AAEH,QAAM,OAAO,uBAAuB;AAQpC,SAAO,WAAW,EAAE,OANA,MAAM,eAAe,OAAO,IAAI,MAAM,GAAG;GAC5D;GACA,QAAQ,MAAM;GACd,OAAO,MAAM;GACb,CAAC,EAEsC,CAAC;UACjC,OAAO;AACf,SAAO,YAAY,OAAO,6BAA6B,mBAAmB"}
1
+ {"version":3,"file":"suggest.mjs","names":[],"sources":["../../../../../src/astro/routes/api/search/suggest.ts"],"sourcesContent":["/**\n * Search suggestions endpoint - Autocomplete\n *\n * GET /_emdash/api/search/suggest?q=hel&limit=5\n */\n\nimport type { APIRoute } from \"astro\";\n\nimport { apiError, apiSuccess, handleError } from \"#api/error.js\";\nimport { isParseError, parseQuery } from \"#api/parse.js\";\nimport { searchSuggestQuery } from \"#api/schemas.js\";\nimport { getSuggestions } from \"#search/index.js\";\n\nexport const prerender = false;\n\n/**\n * Get search suggestions for autocomplete\n *\n * Query parameters:\n * - q: Partial search query (required)\n * - collections: Comma-separated list of collection slugs (optional)\n * - limit: Maximum suggestions (optional, defaults to 5)\n */\nexport const GET: APIRoute = async ({ url, locals }) => {\n\tconst { emdash } = locals;\n\n\tif (!emdash?.db) {\n\t\treturn apiError(\"NOT_CONFIGURED\", \"EmDash not configured\", 500);\n\t}\n\n\tconst query = parseQuery(url, searchSuggestQuery);\n\tif (isParseError(query)) return query;\n\n\tconst collections = query.collections\n\t\t? query.collections.split(\",\").map((c: string) => c.trim())\n\t\t: undefined;\n\n\ttry {\n\t\t// Verify FTS indexes are healthy on first use. See search/index.ts.\n\t\tawait emdash.ensureSearchHealthy?.();\n\n\t\tconst suggestions = await getSuggestions(emdash.db, query.q, {\n\t\t\tcollections,\n\t\t\tlocale: query.locale,\n\t\t\tlimit: query.limit,\n\t\t});\n\n\t\treturn apiSuccess({ items: suggestions });\n\t} catch (error) {\n\t\treturn handleError(error, \"Failed to get suggestions\", \"SUGGESTION_ERROR\");\n\t}\n};\n"],"mappings":";;;;;;;;;;;;;;AAaA,MAAa,YAAY;;;;;;;;;AAUzB,MAAa,MAAgB,OAAO,EAAE,KAAK,aAAa;CACvD,MAAM,EAAE,WAAW;AAEnB,KAAI,CAAC,QAAQ,GACZ,QAAO,SAAS,kBAAkB,yBAAyB,IAAI;CAGhE,MAAM,QAAQ,WAAW,KAAK,mBAAmB;AACjD,KAAI,aAAa,MAAM,CAAE,QAAO;CAEhC,MAAM,cAAc,MAAM,cACvB,MAAM,YAAY,MAAM,IAAI,CAAC,KAAK,MAAc,EAAE,MAAM,CAAC,GACzD;AAEH,KAAI;AAEH,QAAM,OAAO,uBAAuB;AAQpC,SAAO,WAAW,EAAE,OANA,MAAM,eAAe,OAAO,IAAI,MAAM,GAAG;GAC5D;GACA,QAAQ,MAAM;GACd,OAAO,MAAM;GACb,CAAC,EAEsC,CAAC;UACjC,OAAO;AACf,SAAO,YAAY,OAAO,6BAA6B,mBAAmB"}
@@ -1,14 +1,15 @@
1
1
  import "../../../../dialect-helpers-DRI5pyY3.mjs";
2
- import "../../../../base64-CqR-7kqF.mjs";
3
- import "../../../../types-BXSUSAjt.mjs";
4
- import "../../../../loader-ZN1ll-d-.mjs";
5
- import { a as handleSectionUpdate, n as handleSectionDelete, r as handleSectionGet } from "../../../../sections-D_lVzwRZ.mjs";
6
- import { a as unwrapResult, i as requireDb, r as handleError, t as apiError } from "../../../../error-RwM4dD35.mjs";
7
- import { n as parseBody, t as isParseError } from "../../../../parse-CrGndy1A.mjs";
8
- import { B as updateSectionBody } from "../../../../redirects-CCbCqCCd.mjs";
9
- import "../../../../byline-fields-8TMtkBnH.mjs";
2
+ import "../../../../base64-CmWvODNW.mjs";
3
+ import "../../../../types-DXOIbece.mjs";
4
+ import "../../../../loader-C8Z48Uof.mjs";
5
+ import { a as handleSectionUpdate, n as handleSectionDelete, r as handleSectionGet } from "../../../../sections-DWYZo6HK.mjs";
6
+ import { a as unwrapResult, i as requireDb, r as handleError, t as apiError } from "../../../../error-BQ1pxs0L.mjs";
7
+ import { n as parseBody, t as isParseError } from "../../../../parse-qrHlnzTy.mjs";
8
+ import { B as updateSectionBody } from "../../../../redirects-DUvXgzCX.mjs";
9
+ import "../../../../byline-fields-53i9Et0x.mjs";
10
+ import "../../../../status-CB2basWJ.mjs";
10
11
  import "../../../../api/schemas/index.mjs";
11
- import { n as requirePerm } from "../../../../authorize-DsMSVSaY.mjs";
12
+ import { n as requirePerm } from "../../../../authorize-C0EYoUeV.mjs";
12
13
 
13
14
  //#region src/astro/routes/api/sections/[slug].ts
14
15
  const prerender = false;
@@ -1 +1 @@
1
- {"version":3,"file":"_slug_.mjs","names":[],"sources":["../../../../../src/astro/routes/api/sections/[slug].ts"],"sourcesContent":["/**\n * Section by slug endpoints\n *\n * GET /_emdash/api/sections/:slug - Get section\n * PUT /_emdash/api/sections/:slug - Update section\n * DELETE /_emdash/api/sections/:slug - Delete section\n */\n\nimport type { APIRoute } from \"astro\";\n\nimport { requirePerm } from \"#api/authorize.js\";\nimport { apiError, handleError, requireDb, unwrapResult } from \"#api/error.js\";\nimport {\n\thandleSectionDelete,\n\thandleSectionGet,\n\thandleSectionUpdate,\n} from \"#api/handlers/sections.js\";\nimport { isParseError, parseBody } from \"#api/parse.js\";\nimport { updateSectionBody } from \"#api/schemas.js\";\n\nexport const prerender = false;\n\nexport const GET: APIRoute = async ({ params, locals }) => {\n\tconst { emdash, user } = locals;\n\tconst dbErr = requireDb(emdash?.db);\n\tif (dbErr) return dbErr;\n\tconst db = emdash.db;\n\tconst { slug } = params;\n\n\tconst denied = requirePerm(user, \"sections:read\");\n\tif (denied) return denied;\n\n\tif (!slug) {\n\t\treturn apiError(\"VALIDATION_ERROR\", \"slug is required\", 400);\n\t}\n\n\ttry {\n\t\tconst result = await handleSectionGet(db, slug);\n\t\treturn unwrapResult(result);\n\t} catch (error) {\n\t\treturn handleError(error, \"Failed to fetch section\", \"SECTION_GET_ERROR\");\n\t}\n};\n\nexport const PUT: APIRoute = async ({ params, request, locals }) => {\n\tconst { emdash, user } = locals;\n\tconst dbErr = requireDb(emdash?.db);\n\tif (dbErr) return dbErr;\n\tconst db = emdash.db;\n\tconst { slug } = params;\n\n\tconst denied = requirePerm(user, \"sections:manage\");\n\tif (denied) return denied;\n\n\tif (!slug) {\n\t\treturn apiError(\"VALIDATION_ERROR\", \"slug is required\", 400);\n\t}\n\n\ttry {\n\t\tconst body = await parseBody(request, updateSectionBody);\n\t\tif (isParseError(body)) return body;\n\n\t\tconst result = await handleSectionUpdate(db, slug, body);\n\t\treturn unwrapResult(result);\n\t} catch (error) {\n\t\treturn handleError(error, \"Failed to update section\", \"SECTION_UPDATE_ERROR\");\n\t}\n};\n\nexport const DELETE: APIRoute = async ({ params, locals }) => {\n\tconst { emdash, user } = locals;\n\tconst dbErr = requireDb(emdash?.db);\n\tif (dbErr) return dbErr;\n\tconst db = emdash.db;\n\tconst { slug } = params;\n\n\tconst denied = requirePerm(user, \"sections:manage\");\n\tif (denied) return denied;\n\n\tif (!slug) {\n\t\treturn apiError(\"VALIDATION_ERROR\", \"slug is required\", 400);\n\t}\n\n\ttry {\n\t\tconst result = await handleSectionDelete(db, slug);\n\t\treturn unwrapResult(result);\n\t} catch (error) {\n\t\treturn handleError(error, \"Failed to delete section\", \"SECTION_DELETE_ERROR\");\n\t}\n};\n"],"mappings":";;;;;;;;;;;;;AAoBA,MAAa,YAAY;AAEzB,MAAa,MAAgB,OAAO,EAAE,QAAQ,aAAa;CAC1D,MAAM,EAAE,QAAQ,SAAS;CACzB,MAAM,QAAQ,UAAU,QAAQ,GAAG;AACnC,KAAI,MAAO,QAAO;CAClB,MAAM,KAAK,OAAO;CAClB,MAAM,EAAE,SAAS;CAEjB,MAAM,SAAS,YAAY,MAAM,gBAAgB;AACjD,KAAI,OAAQ,QAAO;AAEnB,KAAI,CAAC,KACJ,QAAO,SAAS,oBAAoB,oBAAoB,IAAI;AAG7D,KAAI;AAEH,SAAO,aADQ,MAAM,iBAAiB,IAAI,KAAK,CACpB;UACnB,OAAO;AACf,SAAO,YAAY,OAAO,2BAA2B,oBAAoB;;;AAI3E,MAAa,MAAgB,OAAO,EAAE,QAAQ,SAAS,aAAa;CACnE,MAAM,EAAE,QAAQ,SAAS;CACzB,MAAM,QAAQ,UAAU,QAAQ,GAAG;AACnC,KAAI,MAAO,QAAO;CAClB,MAAM,KAAK,OAAO;CAClB,MAAM,EAAE,SAAS;CAEjB,MAAM,SAAS,YAAY,MAAM,kBAAkB;AACnD,KAAI,OAAQ,QAAO;AAEnB,KAAI,CAAC,KACJ,QAAO,SAAS,oBAAoB,oBAAoB,IAAI;AAG7D,KAAI;EACH,MAAM,OAAO,MAAM,UAAU,SAAS,kBAAkB;AACxD,MAAI,aAAa,KAAK,CAAE,QAAO;AAG/B,SAAO,aADQ,MAAM,oBAAoB,IAAI,MAAM,KAAK,CAC7B;UACnB,OAAO;AACf,SAAO,YAAY,OAAO,4BAA4B,uBAAuB;;;AAI/E,MAAa,SAAmB,OAAO,EAAE,QAAQ,aAAa;CAC7D,MAAM,EAAE,QAAQ,SAAS;CACzB,MAAM,QAAQ,UAAU,QAAQ,GAAG;AACnC,KAAI,MAAO,QAAO;CAClB,MAAM,KAAK,OAAO;CAClB,MAAM,EAAE,SAAS;CAEjB,MAAM,SAAS,YAAY,MAAM,kBAAkB;AACnD,KAAI,OAAQ,QAAO;AAEnB,KAAI,CAAC,KACJ,QAAO,SAAS,oBAAoB,oBAAoB,IAAI;AAG7D,KAAI;AAEH,SAAO,aADQ,MAAM,oBAAoB,IAAI,KAAK,CACvB;UACnB,OAAO;AACf,SAAO,YAAY,OAAO,4BAA4B,uBAAuB"}
1
+ {"version":3,"file":"_slug_.mjs","names":[],"sources":["../../../../../src/astro/routes/api/sections/[slug].ts"],"sourcesContent":["/**\n * Section by slug endpoints\n *\n * GET /_emdash/api/sections/:slug - Get section\n * PUT /_emdash/api/sections/:slug - Update section\n * DELETE /_emdash/api/sections/:slug - Delete section\n */\n\nimport type { APIRoute } from \"astro\";\n\nimport { requirePerm } from \"#api/authorize.js\";\nimport { apiError, handleError, requireDb, unwrapResult } from \"#api/error.js\";\nimport {\n\thandleSectionDelete,\n\thandleSectionGet,\n\thandleSectionUpdate,\n} from \"#api/handlers/sections.js\";\nimport { isParseError, parseBody } from \"#api/parse.js\";\nimport { updateSectionBody } from \"#api/schemas.js\";\n\nexport const prerender = false;\n\nexport const GET: APIRoute = async ({ params, locals }) => {\n\tconst { emdash, user } = locals;\n\tconst dbErr = requireDb(emdash?.db);\n\tif (dbErr) return dbErr;\n\tconst db = emdash.db;\n\tconst { slug } = params;\n\n\tconst denied = requirePerm(user, \"sections:read\");\n\tif (denied) return denied;\n\n\tif (!slug) {\n\t\treturn apiError(\"VALIDATION_ERROR\", \"slug is required\", 400);\n\t}\n\n\ttry {\n\t\tconst result = await handleSectionGet(db, slug);\n\t\treturn unwrapResult(result);\n\t} catch (error) {\n\t\treturn handleError(error, \"Failed to fetch section\", \"SECTION_GET_ERROR\");\n\t}\n};\n\nexport const PUT: APIRoute = async ({ params, request, locals }) => {\n\tconst { emdash, user } = locals;\n\tconst dbErr = requireDb(emdash?.db);\n\tif (dbErr) return dbErr;\n\tconst db = emdash.db;\n\tconst { slug } = params;\n\n\tconst denied = requirePerm(user, \"sections:manage\");\n\tif (denied) return denied;\n\n\tif (!slug) {\n\t\treturn apiError(\"VALIDATION_ERROR\", \"slug is required\", 400);\n\t}\n\n\ttry {\n\t\tconst body = await parseBody(request, updateSectionBody);\n\t\tif (isParseError(body)) return body;\n\n\t\tconst result = await handleSectionUpdate(db, slug, body);\n\t\treturn unwrapResult(result);\n\t} catch (error) {\n\t\treturn handleError(error, \"Failed to update section\", \"SECTION_UPDATE_ERROR\");\n\t}\n};\n\nexport const DELETE: APIRoute = async ({ params, locals }) => {\n\tconst { emdash, user } = locals;\n\tconst dbErr = requireDb(emdash?.db);\n\tif (dbErr) return dbErr;\n\tconst db = emdash.db;\n\tconst { slug } = params;\n\n\tconst denied = requirePerm(user, \"sections:manage\");\n\tif (denied) return denied;\n\n\tif (!slug) {\n\t\treturn apiError(\"VALIDATION_ERROR\", \"slug is required\", 400);\n\t}\n\n\ttry {\n\t\tconst result = await handleSectionDelete(db, slug);\n\t\treturn unwrapResult(result);\n\t} catch (error) {\n\t\treturn handleError(error, \"Failed to delete section\", \"SECTION_DELETE_ERROR\");\n\t}\n};\n"],"mappings":";;;;;;;;;;;;;;AAoBA,MAAa,YAAY;AAEzB,MAAa,MAAgB,OAAO,EAAE,QAAQ,aAAa;CAC1D,MAAM,EAAE,QAAQ,SAAS;CACzB,MAAM,QAAQ,UAAU,QAAQ,GAAG;AACnC,KAAI,MAAO,QAAO;CAClB,MAAM,KAAK,OAAO;CAClB,MAAM,EAAE,SAAS;CAEjB,MAAM,SAAS,YAAY,MAAM,gBAAgB;AACjD,KAAI,OAAQ,QAAO;AAEnB,KAAI,CAAC,KACJ,QAAO,SAAS,oBAAoB,oBAAoB,IAAI;AAG7D,KAAI;AAEH,SAAO,aADQ,MAAM,iBAAiB,IAAI,KAAK,CACpB;UACnB,OAAO;AACf,SAAO,YAAY,OAAO,2BAA2B,oBAAoB;;;AAI3E,MAAa,MAAgB,OAAO,EAAE,QAAQ,SAAS,aAAa;CACnE,MAAM,EAAE,QAAQ,SAAS;CACzB,MAAM,QAAQ,UAAU,QAAQ,GAAG;AACnC,KAAI,MAAO,QAAO;CAClB,MAAM,KAAK,OAAO;CAClB,MAAM,EAAE,SAAS;CAEjB,MAAM,SAAS,YAAY,MAAM,kBAAkB;AACnD,KAAI,OAAQ,QAAO;AAEnB,KAAI,CAAC,KACJ,QAAO,SAAS,oBAAoB,oBAAoB,IAAI;AAG7D,KAAI;EACH,MAAM,OAAO,MAAM,UAAU,SAAS,kBAAkB;AACxD,MAAI,aAAa,KAAK,CAAE,QAAO;AAG/B,SAAO,aADQ,MAAM,oBAAoB,IAAI,MAAM,KAAK,CAC7B;UACnB,OAAO;AACf,SAAO,YAAY,OAAO,4BAA4B,uBAAuB;;;AAI/E,MAAa,SAAmB,OAAO,EAAE,QAAQ,aAAa;CAC7D,MAAM,EAAE,QAAQ,SAAS;CACzB,MAAM,QAAQ,UAAU,QAAQ,GAAG;AACnC,KAAI,MAAO,QAAO;CAClB,MAAM,KAAK,OAAO;CAClB,MAAM,EAAE,SAAS;CAEjB,MAAM,SAAS,YAAY,MAAM,kBAAkB;AACnD,KAAI,OAAQ,QAAO;AAEnB,KAAI,CAAC,KACJ,QAAO,SAAS,oBAAoB,oBAAoB,IAAI;AAG7D,KAAI;AAEH,SAAO,aADQ,MAAM,oBAAoB,IAAI,KAAK,CACvB;UACnB,OAAO;AACf,SAAO,YAAY,OAAO,4BAA4B,uBAAuB"}
@@ -1,14 +1,15 @@
1
1
  import "../../../../dialect-helpers-DRI5pyY3.mjs";
2
- import "../../../../base64-CqR-7kqF.mjs";
3
- import "../../../../types-BXSUSAjt.mjs";
4
- import "../../../../loader-ZN1ll-d-.mjs";
5
- import { i as handleSectionList, t as handleSectionCreate } from "../../../../sections-D_lVzwRZ.mjs";
6
- import { a as unwrapResult, i as requireDb, r as handleError } from "../../../../error-RwM4dD35.mjs";
7
- import { i as parseQuery, n as parseBody, t as isParseError } from "../../../../parse-CrGndy1A.mjs";
8
- import { I as createSectionBody, z as sectionsListQuery } from "../../../../redirects-CCbCqCCd.mjs";
9
- import "../../../../byline-fields-8TMtkBnH.mjs";
2
+ import "../../../../base64-CmWvODNW.mjs";
3
+ import "../../../../types-DXOIbece.mjs";
4
+ import "../../../../loader-C8Z48Uof.mjs";
5
+ import { i as handleSectionList, t as handleSectionCreate } from "../../../../sections-DWYZo6HK.mjs";
6
+ import { a as unwrapResult, i as requireDb, r as handleError } from "../../../../error-BQ1pxs0L.mjs";
7
+ import { i as parseQuery, n as parseBody, t as isParseError } from "../../../../parse-qrHlnzTy.mjs";
8
+ import { I as createSectionBody, z as sectionsListQuery } from "../../../../redirects-DUvXgzCX.mjs";
9
+ import "../../../../byline-fields-53i9Et0x.mjs";
10
+ import "../../../../status-CB2basWJ.mjs";
10
11
  import "../../../../api/schemas/index.mjs";
11
- import { n as requirePerm } from "../../../../authorize-DsMSVSaY.mjs";
12
+ import { n as requirePerm } from "../../../../authorize-C0EYoUeV.mjs";
12
13
 
13
14
  //#region src/astro/routes/api/sections/index.ts
14
15
  const prerender = false;
@@ -1 +1 @@
1
- {"version":3,"file":"index.mjs","names":[],"sources":["../../../../../src/astro/routes/api/sections/index.ts"],"sourcesContent":["/**\n * Sections list and create endpoints\n *\n * GET /_emdash/api/sections - List all sections (with filters)\n * POST /_emdash/api/sections - Create section\n */\n\nimport type { APIRoute } from \"astro\";\n\nimport { requirePerm } from \"#api/authorize.js\";\nimport { handleError, requireDb, unwrapResult } from \"#api/error.js\";\nimport { handleSectionCreate, handleSectionList } from \"#api/handlers/sections.js\";\nimport { isParseError, parseBody, parseQuery } from \"#api/parse.js\";\nimport { createSectionBody, sectionsListQuery } from \"#api/schemas.js\";\n\nexport const prerender = false;\n\nexport const GET: APIRoute = async ({ url, locals }) => {\n\tconst { emdash, user } = locals;\n\tconst dbErr = requireDb(emdash?.db);\n\tif (dbErr) return dbErr;\n\tconst db = emdash.db;\n\n\tconst denied = requirePerm(user, \"sections:read\");\n\tif (denied) return denied;\n\n\ttry {\n\t\tconst query = parseQuery(url, sectionsListQuery);\n\t\tif (isParseError(query)) return query;\n\n\t\tconst result = await handleSectionList(db, query);\n\t\treturn unwrapResult(result);\n\t} catch (error) {\n\t\treturn handleError(error, \"Failed to fetch sections\", \"SECTION_LIST_ERROR\");\n\t}\n};\n\nexport const POST: APIRoute = async ({ request, locals }) => {\n\tconst { emdash, user } = locals;\n\tconst dbErr = requireDb(emdash?.db);\n\tif (dbErr) return dbErr;\n\tconst db = emdash.db;\n\n\tconst denied = requirePerm(user, \"sections:manage\");\n\tif (denied) return denied;\n\n\ttry {\n\t\tconst body = await parseBody(request, createSectionBody);\n\t\tif (isParseError(body)) return body;\n\n\t\tconst result = await handleSectionCreate(db, body);\n\t\treturn unwrapResult(result, 201);\n\t} catch (error) {\n\t\treturn handleError(error, \"Failed to create section\", \"SECTION_CREATE_ERROR\");\n\t}\n};\n"],"mappings":";;;;;;;;;;;;;AAeA,MAAa,YAAY;AAEzB,MAAa,MAAgB,OAAO,EAAE,KAAK,aAAa;CACvD,MAAM,EAAE,QAAQ,SAAS;CACzB,MAAM,QAAQ,UAAU,QAAQ,GAAG;AACnC,KAAI,MAAO,QAAO;CAClB,MAAM,KAAK,OAAO;CAElB,MAAM,SAAS,YAAY,MAAM,gBAAgB;AACjD,KAAI,OAAQ,QAAO;AAEnB,KAAI;EACH,MAAM,QAAQ,WAAW,KAAK,kBAAkB;AAChD,MAAI,aAAa,MAAM,CAAE,QAAO;AAGhC,SAAO,aADQ,MAAM,kBAAkB,IAAI,MAAM,CACtB;UACnB,OAAO;AACf,SAAO,YAAY,OAAO,4BAA4B,qBAAqB;;;AAI7E,MAAa,OAAiB,OAAO,EAAE,SAAS,aAAa;CAC5D,MAAM,EAAE,QAAQ,SAAS;CACzB,MAAM,QAAQ,UAAU,QAAQ,GAAG;AACnC,KAAI,MAAO,QAAO;CAClB,MAAM,KAAK,OAAO;CAElB,MAAM,SAAS,YAAY,MAAM,kBAAkB;AACnD,KAAI,OAAQ,QAAO;AAEnB,KAAI;EACH,MAAM,OAAO,MAAM,UAAU,SAAS,kBAAkB;AACxD,MAAI,aAAa,KAAK,CAAE,QAAO;AAG/B,SAAO,aADQ,MAAM,oBAAoB,IAAI,KAAK,EACtB,IAAI;UACxB,OAAO;AACf,SAAO,YAAY,OAAO,4BAA4B,uBAAuB"}
1
+ {"version":3,"file":"index.mjs","names":[],"sources":["../../../../../src/astro/routes/api/sections/index.ts"],"sourcesContent":["/**\n * Sections list and create endpoints\n *\n * GET /_emdash/api/sections - List all sections (with filters)\n * POST /_emdash/api/sections - Create section\n */\n\nimport type { APIRoute } from \"astro\";\n\nimport { requirePerm } from \"#api/authorize.js\";\nimport { handleError, requireDb, unwrapResult } from \"#api/error.js\";\nimport { handleSectionCreate, handleSectionList } from \"#api/handlers/sections.js\";\nimport { isParseError, parseBody, parseQuery } from \"#api/parse.js\";\nimport { createSectionBody, sectionsListQuery } from \"#api/schemas.js\";\n\nexport const prerender = false;\n\nexport const GET: APIRoute = async ({ url, locals }) => {\n\tconst { emdash, user } = locals;\n\tconst dbErr = requireDb(emdash?.db);\n\tif (dbErr) return dbErr;\n\tconst db = emdash.db;\n\n\tconst denied = requirePerm(user, \"sections:read\");\n\tif (denied) return denied;\n\n\ttry {\n\t\tconst query = parseQuery(url, sectionsListQuery);\n\t\tif (isParseError(query)) return query;\n\n\t\tconst result = await handleSectionList(db, query);\n\t\treturn unwrapResult(result);\n\t} catch (error) {\n\t\treturn handleError(error, \"Failed to fetch sections\", \"SECTION_LIST_ERROR\");\n\t}\n};\n\nexport const POST: APIRoute = async ({ request, locals }) => {\n\tconst { emdash, user } = locals;\n\tconst dbErr = requireDb(emdash?.db);\n\tif (dbErr) return dbErr;\n\tconst db = emdash.db;\n\n\tconst denied = requirePerm(user, \"sections:manage\");\n\tif (denied) return denied;\n\n\ttry {\n\t\tconst body = await parseBody(request, createSectionBody);\n\t\tif (isParseError(body)) return body;\n\n\t\tconst result = await handleSectionCreate(db, body);\n\t\treturn unwrapResult(result, 201);\n\t} catch (error) {\n\t\treturn handleError(error, \"Failed to create section\", \"SECTION_CREATE_ERROR\");\n\t}\n};\n"],"mappings":";;;;;;;;;;;;;;AAeA,MAAa,YAAY;AAEzB,MAAa,MAAgB,OAAO,EAAE,KAAK,aAAa;CACvD,MAAM,EAAE,QAAQ,SAAS;CACzB,MAAM,QAAQ,UAAU,QAAQ,GAAG;AACnC,KAAI,MAAO,QAAO;CAClB,MAAM,KAAK,OAAO;CAElB,MAAM,SAAS,YAAY,MAAM,gBAAgB;AACjD,KAAI,OAAQ,QAAO;AAEnB,KAAI;EACH,MAAM,QAAQ,WAAW,KAAK,kBAAkB;AAChD,MAAI,aAAa,MAAM,CAAE,QAAO;AAGhC,SAAO,aADQ,MAAM,kBAAkB,IAAI,MAAM,CACtB;UACnB,OAAO;AACf,SAAO,YAAY,OAAO,4BAA4B,qBAAqB;;;AAI7E,MAAa,OAAiB,OAAO,EAAE,SAAS,aAAa;CAC5D,MAAM,EAAE,QAAQ,SAAS;CACzB,MAAM,QAAQ,UAAU,QAAQ,GAAG;AACnC,KAAI,MAAO,QAAO;CAClB,MAAM,KAAK,OAAO;CAElB,MAAM,SAAS,YAAY,MAAM,kBAAkB;AACnD,KAAI,OAAQ,QAAO;AAEnB,KAAI;EACH,MAAM,OAAO,MAAM,UAAU,SAAS,kBAAkB;AACxD,MAAI,aAAa,KAAK,CAAE,QAAO;AAG/B,SAAO,aADQ,MAAM,oBAAoB,IAAI,KAAK,EACtB,IAAI;UACxB,OAAO;AACf,SAAO,YAAY,OAAO,4BAA4B,uBAAuB"}
@@ -1,9 +1,9 @@
1
- import "../../../../base64-CqR-7kqF.mjs";
2
- import "../../../../types-BXSUSAjt.mjs";
3
- import { t as OptionsRepository } from "../../../../options-BPCVnesz.mjs";
4
- import { n as apiSuccess, r as handleError, t as apiError } from "../../../../error-RwM4dD35.mjs";
5
- import { n as parseBody, t as isParseError } from "../../../../parse-CrGndy1A.mjs";
6
- import { n as requirePerm } from "../../../../authorize-DsMSVSaY.mjs";
1
+ import "../../../../base64-CmWvODNW.mjs";
2
+ import "../../../../types-DXOIbece.mjs";
3
+ import { t as OptionsRepository } from "../../../../options-DTTML-Tx.mjs";
4
+ import { n as apiSuccess, r as handleError, t as apiError } from "../../../../error-BQ1pxs0L.mjs";
5
+ import { n as parseBody, t as isParseError } from "../../../../parse-qrHlnzTy.mjs";
6
+ import { n as requirePerm } from "../../../../authorize-C0EYoUeV.mjs";
7
7
  import { z } from "zod";
8
8
  import { escapeHtml } from "@emdash-cms/auth";
9
9
 
@@ -1,18 +1,21 @@
1
1
  import "../../../dialect-helpers-DRI5pyY3.mjs";
2
- import "../../../base64-CqR-7kqF.mjs";
3
- import "../../../types-BXSUSAjt.mjs";
4
- import "../../../media-JOf3pNkw.mjs";
5
- import "../../../options-BPCVnesz.mjs";
6
- import "../../../request-cache-D32LpnmI.mjs";
7
- import "../../../loader-ZN1ll-d-.mjs";
8
- import "../../../settings-DfxiWY_s.mjs";
9
- import { n as handleSettingsUpdate, t as handleSettingsGet } from "../../../settings-Cv47v9u8.mjs";
10
- import { a as unwrapResult, r as handleError, t as apiError } from "../../../error-RwM4dD35.mjs";
11
- import { n as parseBody, t as isParseError } from "../../../parse-CrGndy1A.mjs";
12
- import { P as settingsUpdateBody } from "../../../redirects-CCbCqCCd.mjs";
13
- import "../../../byline-fields-8TMtkBnH.mjs";
2
+ import "../../../after-B1IIdH3Y.mjs";
3
+ import "../../../object-cache-SEb2IM4Z.mjs";
4
+ import "../../../base64-CmWvODNW.mjs";
5
+ import "../../../types-DXOIbece.mjs";
6
+ import "../../../media-Bw0sA6rb.mjs";
7
+ import "../../../options-DTTML-Tx.mjs";
8
+ import "../../../request-cache-KCNHp_RJ.mjs";
9
+ import "../../../loader-C8Z48Uof.mjs";
10
+ import "../../../settings-yaxu9mU-.mjs";
11
+ import { n as handleSettingsUpdate, t as handleSettingsGet } from "../../../settings-DUrVDN0c.mjs";
12
+ import { a as unwrapResult, r as handleError, t as apiError } from "../../../error-BQ1pxs0L.mjs";
13
+ import { n as parseBody, t as isParseError } from "../../../parse-qrHlnzTy.mjs";
14
+ import { P as settingsUpdateBody } from "../../../redirects-DUvXgzCX.mjs";
15
+ import "../../../byline-fields-53i9Et0x.mjs";
16
+ import "../../../status-CB2basWJ.mjs";
14
17
  import "../../../api/schemas/index.mjs";
15
- import { n as requirePerm } from "../../../authorize-DsMSVSaY.mjs";
18
+ import { n as requirePerm } from "../../../authorize-C0EYoUeV.mjs";
16
19
 
17
20
  //#region src/astro/routes/api/settings.ts
18
21
  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,16 +1,17 @@
1
- import "../../../../base64-CqR-7kqF.mjs";
2
- import "../../../../types-BXSUSAjt.mjs";
3
- import { t as OptionsRepository } from "../../../../options-BPCVnesz.mjs";
4
- import { n as apiSuccess, r as handleError, t as apiError } from "../../../../error-RwM4dD35.mjs";
5
- import { n as parseBody, t as isParseError } from "../../../../parse-CrGndy1A.mjs";
6
- import "../../../../redirects-CCbCqCCd.mjs";
7
- import { l as setupAdminVerifyBody } from "../../../../byline-fields-8TMtkBnH.mjs";
1
+ import "../../../../base64-CmWvODNW.mjs";
2
+ import "../../../../types-DXOIbece.mjs";
3
+ import { t as OptionsRepository } from "../../../../options-DTTML-Tx.mjs";
4
+ import { n as apiSuccess, r as handleError, t as apiError } from "../../../../error-BQ1pxs0L.mjs";
5
+ import { n as parseBody, t as isParseError } from "../../../../parse-qrHlnzTy.mjs";
6
+ import "../../../../redirects-DUvXgzCX.mjs";
7
+ import { l as setupAdminVerifyBody } from "../../../../byline-fields-53i9Et0x.mjs";
8
+ import "../../../../status-CB2basWJ.mjs";
8
9
  import "../../../../api/schemas/index.mjs";
9
- import { n as getPublicOrigin } from "../../../../public-url-BFVC2OTJ.mjs";
10
- import { n as validateAllowedOrigins, t as getConfiguredAllowedOrigins } from "../../../../allowed-origins-B1u7Qnvg.mjs";
11
- import { n as createChallengeStore } from "../../../../challenge-store-DXX3rfdI.mjs";
12
- import { t as getPasskeyConfig } from "../../../../passkey-config-C3QgnQnU.mjs";
13
- import { t as SETUP_NONCE_COOKIE } from "../../../../setup-nonce-C9aFzb94.mjs";
10
+ import { n as getPublicOrigin } from "../../../../public-url-8lFyQ8ZF.mjs";
11
+ import { n as validateAllowedOrigins, t as getConfiguredAllowedOrigins } from "../../../../allowed-origins-DjlhyfNN.mjs";
12
+ import { n as createChallengeStore } from "../../../../challenge-store-C6E_kWTs.mjs";
13
+ import { t as getPasskeyConfig } from "../../../../passkey-config-BJTbcnI5.mjs";
14
+ import { t as SETUP_NONCE_COOKIE } from "../../../../setup-nonce-DFWG-J5c.mjs";
14
15
  import { createKyselyAdapter } from "@emdash-cms/auth/adapters/kysely";
15
16
  import { Role, secureCompare } from "@emdash-cms/auth";
16
17
  import { registerPasskey, verifyRegistrationResponse } from "@emdash-cms/auth/passkey";
@@ -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\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,15 +1,16 @@
1
- import "../../../../base64-CqR-7kqF.mjs";
2
- import "../../../../types-BXSUSAjt.mjs";
3
- import { t as OptionsRepository } from "../../../../options-BPCVnesz.mjs";
4
- import { n as apiSuccess, r as handleError, t as apiError } from "../../../../error-RwM4dD35.mjs";
5
- import { n as parseBody, t as isParseError } from "../../../../parse-CrGndy1A.mjs";
6
- import "../../../../redirects-CCbCqCCd.mjs";
7
- import { c as setupAdminBody } from "../../../../byline-fields-8TMtkBnH.mjs";
1
+ import "../../../../base64-CmWvODNW.mjs";
2
+ import "../../../../types-DXOIbece.mjs";
3
+ import { t as OptionsRepository } from "../../../../options-DTTML-Tx.mjs";
4
+ import { n as apiSuccess, r as handleError, t as apiError } from "../../../../error-BQ1pxs0L.mjs";
5
+ import { n as parseBody, t as isParseError } from "../../../../parse-qrHlnzTy.mjs";
6
+ import "../../../../redirects-DUvXgzCX.mjs";
7
+ import { c as setupAdminBody } from "../../../../byline-fields-53i9Et0x.mjs";
8
+ import "../../../../status-CB2basWJ.mjs";
8
9
  import "../../../../api/schemas/index.mjs";
9
- import { n as getPublicOrigin } from "../../../../public-url-BFVC2OTJ.mjs";
10
- import { n as createChallengeStore } from "../../../../challenge-store-DXX3rfdI.mjs";
11
- import { t as getPasskeyConfig } from "../../../../passkey-config-C3QgnQnU.mjs";
12
- import { n as SETUP_NONCE_MAX_AGE_SECONDS, t as SETUP_NONCE_COOKIE } from "../../../../setup-nonce-C9aFzb94.mjs";
10
+ import { n as getPublicOrigin } from "../../../../public-url-8lFyQ8ZF.mjs";
11
+ import { n as createChallengeStore } from "../../../../challenge-store-C6E_kWTs.mjs";
12
+ import { t as getPasskeyConfig } from "../../../../passkey-config-BJTbcnI5.mjs";
13
+ import { n as SETUP_NONCE_MAX_AGE_SECONDS, t as SETUP_NONCE_COOKIE } from "../../../../setup-nonce-DFWG-J5c.mjs";
13
14
  import { createKyselyAdapter } from "@emdash-cms/auth/adapters/kysely";
14
15
  import { generateToken } from "@emdash-cms/auth";
15
16
  import { generateRegistrationOptions } from "@emdash-cms/auth/passkey";
@@ -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\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 +1 @@
1
- {"version":3,"file":"dev-bypass.d.mts","names":[],"sources":["../../../../../src/astro/routes/api/setup/dev-bypass.ts"],"mappings":";;;cAmBa,SAAA;AAAA,cAmLA,GAAA,EAAK,QAAA;AAAA,cACL,IAAA,EAAM,QAAA"}
1
+ {"version":3,"file":"dev-bypass.d.mts","names":[],"sources":["../../../../../src/astro/routes/api/setup/dev-bypass.ts"],"mappings":";;;cAmBa,SAAA;AAAA,cAuLA,GAAA,EAAK,QAAA;AAAA,cACL,IAAA,EAAM,QAAA"}
@@ -1,30 +1,32 @@
1
- import { i as runMigrations } from "../../../../runner--4wMWwKM.mjs";
1
+ import { i as runMigrations } from "../../../../runner-DYYnW530.mjs";
2
2
  import "../../../../dialect-helpers-DRI5pyY3.mjs";
3
- import "../../../../content-BIlVx-RX.mjs";
4
- import "../../../../base64-CqR-7kqF.mjs";
5
- import "../../../../types-BXSUSAjt.mjs";
6
- import "../../../../media-JOf3pNkw.mjs";
7
- import "../../../../taxonomy-CdllE4oq.mjs";
8
- import { t as OptionsRepository } from "../../../../options-BPCVnesz.mjs";
9
- import "../../../../redirect-CRWIt8Zj.mjs";
10
- import "../../../../request-cache-D32LpnmI.mjs";
11
- import "../../../../byline-registry-CWP7I71B.mjs";
12
- import "../../../../byline-DUx48sJp.mjs";
13
- import "../../../../fts-manager-1RgHmopc.mjs";
14
- import "../../../../registry-brYh-rAT.mjs";
15
- import "../../../../loader-ZN1ll-d-.mjs";
16
- import "../../../../settings-DfxiWY_s.mjs";
17
- import "../../../../ssrf-BsVGIE0Z.mjs";
18
- import { n as apiSuccess, r as handleError, t as apiError } from "../../../../error-RwM4dD35.mjs";
19
- import "../../../../ssrf-BvgVcfNQ.mjs";
20
- import { t as validateSeed } from "../../../../validate-Bz4vqcX1.mjs";
21
- import { t as applySeed } from "../../../../apply-Dr7snAMT.mjs";
22
- import { t as loadSeed } from "../../../../load-BBetCvLC.mjs";
23
- import { n as getPublicOrigin } from "../../../../public-url-BFVC2OTJ.mjs";
24
- import "../../../../api-tokens-Oq39ba-Z.mjs";
25
- import { t as handleApiTokenCreate } from "../../../../api-tokens-DPfhPu5V.mjs";
26
- import { t as escapeHtml } from "../../../../escape-Ds07EEyu.mjs";
27
- import { t as isSafeRedirect } from "../../../../redirect-B_q19j4v.mjs";
3
+ import "../../../../after-B1IIdH3Y.mjs";
4
+ import "../../../../object-cache-SEb2IM4Z.mjs";
5
+ import "../../../../content-2PTDNnoh.mjs";
6
+ import "../../../../base64-CmWvODNW.mjs";
7
+ import "../../../../types-DXOIbece.mjs";
8
+ import "../../../../media-Bw0sA6rb.mjs";
9
+ import "../../../../taxonomy-B2HQuVf5.mjs";
10
+ import { t as OptionsRepository } from "../../../../options-DTTML-Tx.mjs";
11
+ import "../../../../redirect-Bifv_yHv.mjs";
12
+ import "../../../../request-cache-KCNHp_RJ.mjs";
13
+ import "../../../../byline-registry-BOjqDOim.mjs";
14
+ import "../../../../byline-CC0WS4Gu.mjs";
15
+ import "../../../../fts-manager-DtiWqwNJ.mjs";
16
+ import "../../../../registry-CjK96fHD.mjs";
17
+ import "../../../../loader-C8Z48Uof.mjs";
18
+ import "../../../../settings-yaxu9mU-.mjs";
19
+ import "../../../../ssrf-B0VeRLrp.mjs";
20
+ import { n as apiSuccess, r as handleError, t as apiError } from "../../../../error-BQ1pxs0L.mjs";
21
+ import "../../../../ssrf-Cz1e2QPn.mjs";
22
+ import { t as validateSeed } from "../../../../validate-Bwl64sxv.mjs";
23
+ import { t as applySeed } from "../../../../apply-wDqQoxX4.mjs";
24
+ import { t as loadSeed } from "../../../../load-Dtoo7KcJ.mjs";
25
+ import { n as getPublicOrigin } from "../../../../public-url-8lFyQ8ZF.mjs";
26
+ import "../../../../api-tokens-BVH-H8Z9.mjs";
27
+ import { n as handleApiTokenCreate, t as deleteApiTokensByName } from "../../../../api-tokens-ViYKeIp9.mjs";
28
+ import { t as escapeHtml } from "../../../../escape-BtbJWyaW.mjs";
29
+ import { t as isSafeRedirect } from "../../../../redirect-B4wuX2A5.mjs";
28
30
  import { ulid } from "ulidx";
29
31
 
30
32
  //#region src/astro/routes/api/setup/dev-bypass.ts
@@ -86,6 +88,7 @@ async function handleDevBypass(context) {
86
88
  if (session) session.set("user", { id: user.id });
87
89
  let token;
88
90
  if (url.searchParams.has("token")) {
91
+ await deleteApiTokensByName(emdash.db, user.id, "dev-bypass-token");
89
92
  const result = await handleApiTokenCreate(emdash.db, user.id, {
90
93
  name: "dev-bypass-token",
91
94
  scopes: [
@@ -1 +1 @@
1
- {"version":3,"file":"dev-bypass.mjs","names":[],"sources":["../../../../../src/astro/routes/api/setup/dev-bypass.ts"],"sourcesContent":["/**\n * POST /_emdash/api/setup/dev-bypass\n * GET /_emdash/api/setup/dev-bypass\n *\n * Development-only endpoint to bypass the setup wizard.\n * Runs migrations, creates a dev admin user, and marks setup complete.\n *\n * ONLY available when import.meta.env.DEV is true.\n *\n * Usage:\n * - GET with redirect: /_emdash/api/setup/dev-bypass?redirect=/_emdash/admin\n * - POST for API: Returns JSON with setup info\n *\n * For agent/browser testing, navigate to:\n * /_emdash/api/setup/dev-bypass?redirect=/_emdash/admin\n */\n\nimport type { APIRoute } from \"astro\";\n\nexport const prerender = false;\n\nimport { ulid } from \"ulidx\";\n\nimport { apiError, apiSuccess, handleError } from \"#api/error.js\";\nimport { escapeHtml } from \"#api/escape.js\";\nimport { handleApiTokenCreate } from \"#api/handlers/api-tokens.js\";\nimport { getPublicOrigin } from \"#api/public-url.js\";\nimport { isSafeRedirect } from \"#api/redirect.js\";\nimport { runMigrations } from \"#db/migrations/runner.js\";\nimport { OptionsRepository } from \"#db/repositories/options.js\";\nimport { applySeed } from \"#seed/apply.js\";\nimport { loadSeed } from \"#seed/load.js\";\nimport { validateSeed } from \"#seed/validate.js\";\n\n// RBAC role levels (matching @emdash-cms/auth)\nconst ROLE_ADMIN = 50;\n\nconst DEV_USER_EMAIL = \"dev@emdash.local\";\nconst DEV_USER_NAME = \"Dev Admin\";\nconst DEV_SITE_TITLE = \"EmDash Dev Site\";\n\nasync function handleDevBypass(context: Parameters<APIRoute>[0]): Promise<Response> {\n\t// CRITICAL: Only allow in development mode\n\tif (!import.meta.env.DEV) {\n\t\treturn apiError(\"FORBIDDEN\", \"Dev bypass is only available in development mode\", 403);\n\t}\n\n\tconst { locals, url, session } = context;\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// Run migrations\n\t\tconst migrations = await runMigrations(emdash.db);\n\t\tconsole.log(\"[setup-dev-bypass] Migrations applied:\", migrations.applied);\n\n\t\t// Apply seed (user seed or built-in default)\n\t\tconst seed = await loadSeed();\n\t\tconst validation = validateSeed(seed);\n\t\tif (validation.valid) {\n\t\t\tconst seedResult = await applySeed(emdash.db, seed, {\n\t\t\t\tincludeContent: true,\n\t\t\t\tonConflict: \"skip\",\n\t\t\t\tstorage: emdash.storage ?? undefined,\n\t\t\t});\n\t\t\tconsole.log(\n\t\t\t\t`[setup-dev-bypass] Seed applied: ${seedResult.collections.created} collections, ${seedResult.fields.created} fields`,\n\t\t\t);\n\t\t}\n\n\t\tconst options = new OptionsRepository(emdash.db);\n\n\t\t// Find or create dev user (direct DB access to avoid @emdash-cms/auth import issues in dev)\n\t\tconst existingUser = await emdash.db\n\t\t\t.selectFrom(\"users\")\n\t\t\t.selectAll()\n\t\t\t.where(\"email\", \"=\", DEV_USER_EMAIL)\n\t\t\t.executeTakeFirst();\n\n\t\tlet user: { id: string; email: string; name: string; role: number };\n\t\tlet userCreated = false;\n\n\t\tif (!existingUser) {\n\t\t\tconst now = new Date().toISOString();\n\t\t\tconst newUser = {\n\t\t\t\tid: ulid(),\n\t\t\t\temail: DEV_USER_EMAIL,\n\t\t\t\tname: DEV_USER_NAME,\n\t\t\t\trole: ROLE_ADMIN,\n\t\t\t\temail_verified: 1,\n\t\t\t\tcreated_at: now,\n\t\t\t\tupdated_at: now,\n\t\t\t};\n\n\t\t\tawait emdash.db.insertInto(\"users\").values(newUser).execute();\n\n\t\t\tuser = {\n\t\t\t\tid: newUser.id,\n\t\t\t\temail: newUser.email,\n\t\t\t\tname: newUser.name,\n\t\t\t\trole: newUser.role,\n\t\t\t};\n\t\t\tuserCreated = true;\n\t\t\tconsole.log(\"[setup-dev-bypass] Created dev admin user:\", user.email);\n\t\t} else {\n\t\t\tuser = {\n\t\t\t\tid: existingUser.id,\n\t\t\t\temail: existingUser.email,\n\t\t\t\tname: existingUser.name || DEV_USER_NAME,\n\t\t\t\trole: existingUser.role,\n\t\t\t};\n\t\t}\n\n\t\t// Set site title if not already set\n\t\tconst existingTitle = await options.get(\"emdash:site_title\");\n\t\tif (!existingTitle) {\n\t\t\tawait options.set(\"emdash:site_title\", DEV_SITE_TITLE);\n\t\t}\n\n\t\t// Store canonical site URL (used by magic-link/recovery emails)\n\t\tawait options.set(\"emdash:site_url\", getPublicOrigin(url, emdash?.config));\n\n\t\t// Mark setup complete\n\t\tawait options.set(\"emdash:setup_complete\", true);\n\n\t\t// Create session\n\t\tif (session) {\n\t\t\tsession.set(\"user\", { id: user.id });\n\t\t}\n\n\t\t// Optionally create a PAT token (?token=1) for headless/CLI testing.\n\t\tlet token: string | undefined;\n\t\tif (url.searchParams.has(\"token\")) {\n\t\t\tconst result = await handleApiTokenCreate(emdash.db, user.id, {\n\t\t\t\tname: \"dev-bypass-token\",\n\t\t\t\tscopes: [\n\t\t\t\t\t\"content:read\",\n\t\t\t\t\t\"content:write\",\n\t\t\t\t\t\"media:read\",\n\t\t\t\t\t\"media:write\",\n\t\t\t\t\t\"schema:read\",\n\t\t\t\t\t\"schema:write\",\n\t\t\t\t\t\"admin\",\n\t\t\t\t],\n\t\t\t});\n\t\t\tif (result.success) {\n\t\t\t\ttoken = result.data.token;\n\t\t\t}\n\t\t}\n\n\t\t// Check for redirect parameter\n\t\tconst redirect = url.searchParams.get(\"redirect\");\n\n\t\tif (redirect) {\n\t\t\t// Validate redirect is a safe local path (prevent open redirect via //evil.com or /\\evil.com)\n\t\t\tif (!isSafeRedirect(redirect)) {\n\t\t\t\treturn apiError(\"INVALID_REDIRECT\", \"Redirect must be a local path\", 400);\n\t\t\t}\n\n\t\t\t// Return an HTML page with meta-refresh redirect\n\t\t\t// This ensures the session is fully saved before redirect\n\t\t\tconst safeRedirect = escapeHtml(redirect);\n\t\t\tconst html = `<!DOCTYPE html>\n<html>\n<head>\n\t<meta http-equiv=\"refresh\" content=\"0;url=${safeRedirect}\">\n</head>\n<body>Redirecting...</body>\n</html>`;\n\t\t\treturn new Response(html, {\n\t\t\t\tstatus: 200,\n\t\t\t\theaders: { \"Content-Type\": \"text/html\" },\n\t\t\t});\n\t\t}\n\n\t\t// Return JSON response\n\t\treturn apiSuccess({\n\t\t\tsuccess: true,\n\t\t\tmessage: \"Dev setup complete\",\n\t\t\tmigrations: migrations.applied,\n\t\t\tuserCreated,\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\t...(token ? { token } : {}),\n\t\t});\n\t} catch (error) {\n\t\treturn handleError(error, \"Dev bypass failed\", \"DEV_BYPASS_ERROR\");\n\t}\n}\n\n// Support both GET and POST\nexport const GET: APIRoute = handleDevBypass;\nexport const POST: APIRoute = handleDevBypass;\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAmBA,MAAa,YAAY;AAgBzB,MAAM,aAAa;AAEnB,MAAM,iBAAiB;AACvB,MAAM,gBAAgB;AACtB,MAAM,iBAAiB;AAEvB,eAAe,gBAAgB,SAAqD;AAEnF,KAAI,CAAC,OAAO,KAAK,IAAI,IACpB,QAAO,SAAS,aAAa,oDAAoD,IAAI;CAGtF,MAAM,EAAE,QAAQ,KAAK,YAAY;CACjC,MAAM,EAAE,WAAW;AAEnB,KAAI,CAAC,QAAQ,GACZ,QAAO,SAAS,kBAAkB,6BAA6B,IAAI;AAGpE,KAAI;EAEH,MAAM,aAAa,MAAM,cAAc,OAAO,GAAG;AACjD,UAAQ,IAAI,0CAA0C,WAAW,QAAQ;EAGzE,MAAM,OAAO,MAAM,UAAU;AAE7B,MADmB,aAAa,KAAK,CACtB,OAAO;GACrB,MAAM,aAAa,MAAM,UAAU,OAAO,IAAI,MAAM;IACnD,gBAAgB;IAChB,YAAY;IACZ,SAAS,OAAO,WAAW;IAC3B,CAAC;AACF,WAAQ,IACP,oCAAoC,WAAW,YAAY,QAAQ,gBAAgB,WAAW,OAAO,QAAQ,SAC7G;;EAGF,MAAM,UAAU,IAAI,kBAAkB,OAAO,GAAG;EAGhD,MAAM,eAAe,MAAM,OAAO,GAChC,WAAW,QAAQ,CACnB,WAAW,CACX,MAAM,SAAS,KAAK,eAAe,CACnC,kBAAkB;EAEpB,IAAI;EACJ,IAAI,cAAc;AAElB,MAAI,CAAC,cAAc;GAClB,MAAM,uBAAM,IAAI,MAAM,EAAC,aAAa;GACpC,MAAM,UAAU;IACf,IAAI,MAAM;IACV,OAAO;IACP,MAAM;IACN,MAAM;IACN,gBAAgB;IAChB,YAAY;IACZ,YAAY;IACZ;AAED,SAAM,OAAO,GAAG,WAAW,QAAQ,CAAC,OAAO,QAAQ,CAAC,SAAS;AAE7D,UAAO;IACN,IAAI,QAAQ;IACZ,OAAO,QAAQ;IACf,MAAM,QAAQ;IACd,MAAM,QAAQ;IACd;AACD,iBAAc;AACd,WAAQ,IAAI,8CAA8C,KAAK,MAAM;QAErE,QAAO;GACN,IAAI,aAAa;GACjB,OAAO,aAAa;GACpB,MAAM,aAAa,QAAQ;GAC3B,MAAM,aAAa;GACnB;AAKF,MAAI,CADkB,MAAM,QAAQ,IAAI,oBAAoB,CAE3D,OAAM,QAAQ,IAAI,qBAAqB,eAAe;AAIvD,QAAM,QAAQ,IAAI,mBAAmB,gBAAgB,KAAK,QAAQ,OAAO,CAAC;AAG1E,QAAM,QAAQ,IAAI,yBAAyB,KAAK;AAGhD,MAAI,QACH,SAAQ,IAAI,QAAQ,EAAE,IAAI,KAAK,IAAI,CAAC;EAIrC,IAAI;AACJ,MAAI,IAAI,aAAa,IAAI,QAAQ,EAAE;GAClC,MAAM,SAAS,MAAM,qBAAqB,OAAO,IAAI,KAAK,IAAI;IAC7D,MAAM;IACN,QAAQ;KACP;KACA;KACA;KACA;KACA;KACA;KACA;KACA;IACD,CAAC;AACF,OAAI,OAAO,QACV,SAAQ,OAAO,KAAK;;EAKtB,MAAM,WAAW,IAAI,aAAa,IAAI,WAAW;AAEjD,MAAI,UAAU;AAEb,OAAI,CAAC,eAAe,SAAS,CAC5B,QAAO,SAAS,oBAAoB,iCAAiC,IAAI;GAM1E,MAAM,OAAO;;;6CADQ,WAAW,SAAS,CAIc;;;;AAIvD,UAAO,IAAI,SAAS,MAAM;IACzB,QAAQ;IACR,SAAS,EAAE,gBAAgB,aAAa;IACxC,CAAC;;AAIH,SAAO,WAAW;GACjB,SAAS;GACT,SAAS;GACT,YAAY,WAAW;GACvB;GACA,MAAM;IACL,IAAI,KAAK;IACT,OAAO,KAAK;IACZ,MAAM,KAAK;IACX,MAAM,KAAK;IACX;GACD,GAAI,QAAQ,EAAE,OAAO,GAAG,EAAE;GAC1B,CAAC;UACM,OAAO;AACf,SAAO,YAAY,OAAO,qBAAqB,mBAAmB;;;AAKpE,MAAa,MAAgB;AAC7B,MAAa,OAAiB"}
1
+ {"version":3,"file":"dev-bypass.mjs","names":[],"sources":["../../../../../src/astro/routes/api/setup/dev-bypass.ts"],"sourcesContent":["/**\n * POST /_emdash/api/setup/dev-bypass\n * GET /_emdash/api/setup/dev-bypass\n *\n * Development-only endpoint to bypass the setup wizard.\n * Runs migrations, creates a dev admin user, and marks setup complete.\n *\n * ONLY available when import.meta.env.DEV is true.\n *\n * Usage:\n * - GET with redirect: /_emdash/api/setup/dev-bypass?redirect=/_emdash/admin\n * - POST for API: Returns JSON with setup info\n *\n * For agent/browser testing, navigate to:\n * /_emdash/api/setup/dev-bypass?redirect=/_emdash/admin\n */\n\nimport type { APIRoute } from \"astro\";\n\nexport const prerender = false;\n\nimport { ulid } from \"ulidx\";\n\nimport { apiError, apiSuccess, handleError } from \"#api/error.js\";\nimport { escapeHtml } from \"#api/escape.js\";\nimport { deleteApiTokensByName, handleApiTokenCreate } from \"#api/handlers/api-tokens.js\";\nimport { getPublicOrigin } from \"#api/public-url.js\";\nimport { isSafeRedirect } from \"#api/redirect.js\";\nimport { runMigrations } from \"#db/migrations/runner.js\";\nimport { OptionsRepository } from \"#db/repositories/options.js\";\nimport { applySeed } from \"#seed/apply.js\";\nimport { loadSeed } from \"#seed/load.js\";\nimport { validateSeed } from \"#seed/validate.js\";\n\n// RBAC role levels (matching @emdash-cms/auth)\nconst ROLE_ADMIN = 50;\n\nconst DEV_USER_EMAIL = \"dev@emdash.local\";\nconst DEV_USER_NAME = \"Dev Admin\";\nconst DEV_SITE_TITLE = \"EmDash Dev Site\";\n\nasync function handleDevBypass(context: Parameters<APIRoute>[0]): Promise<Response> {\n\t// CRITICAL: Only allow in development mode\n\tif (!import.meta.env.DEV) {\n\t\treturn apiError(\"FORBIDDEN\", \"Dev bypass is only available in development mode\", 403);\n\t}\n\n\tconst { locals, url, session } = context;\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// Run migrations\n\t\tconst migrations = await runMigrations(emdash.db);\n\t\tconsole.log(\"[setup-dev-bypass] Migrations applied:\", migrations.applied);\n\n\t\t// Apply seed (user seed or built-in default)\n\t\tconst seed = await loadSeed();\n\t\tconst validation = validateSeed(seed);\n\t\tif (validation.valid) {\n\t\t\tconst seedResult = await applySeed(emdash.db, seed, {\n\t\t\t\tincludeContent: true,\n\t\t\t\tonConflict: \"skip\",\n\t\t\t\tstorage: emdash.storage ?? undefined,\n\t\t\t});\n\t\t\tconsole.log(\n\t\t\t\t`[setup-dev-bypass] Seed applied: ${seedResult.collections.created} collections, ${seedResult.fields.created} fields`,\n\t\t\t);\n\t\t}\n\n\t\tconst options = new OptionsRepository(emdash.db);\n\n\t\t// Find or create dev user (direct DB access to avoid @emdash-cms/auth import issues in dev)\n\t\tconst existingUser = await emdash.db\n\t\t\t.selectFrom(\"users\")\n\t\t\t.selectAll()\n\t\t\t.where(\"email\", \"=\", DEV_USER_EMAIL)\n\t\t\t.executeTakeFirst();\n\n\t\tlet user: { id: string; email: string; name: string; role: number };\n\t\tlet userCreated = false;\n\n\t\tif (!existingUser) {\n\t\t\tconst now = new Date().toISOString();\n\t\t\tconst newUser = {\n\t\t\t\tid: ulid(),\n\t\t\t\temail: DEV_USER_EMAIL,\n\t\t\t\tname: DEV_USER_NAME,\n\t\t\t\trole: ROLE_ADMIN,\n\t\t\t\temail_verified: 1,\n\t\t\t\tcreated_at: now,\n\t\t\t\tupdated_at: now,\n\t\t\t};\n\n\t\t\tawait emdash.db.insertInto(\"users\").values(newUser).execute();\n\n\t\t\tuser = {\n\t\t\t\tid: newUser.id,\n\t\t\t\temail: newUser.email,\n\t\t\t\tname: newUser.name,\n\t\t\t\trole: newUser.role,\n\t\t\t};\n\t\t\tuserCreated = true;\n\t\t\tconsole.log(\"[setup-dev-bypass] Created dev admin user:\", user.email);\n\t\t} else {\n\t\t\tuser = {\n\t\t\t\tid: existingUser.id,\n\t\t\t\temail: existingUser.email,\n\t\t\t\tname: existingUser.name || DEV_USER_NAME,\n\t\t\t\trole: existingUser.role,\n\t\t\t};\n\t\t}\n\n\t\t// Set site title if not already set\n\t\tconst existingTitle = await options.get(\"emdash:site_title\");\n\t\tif (!existingTitle) {\n\t\t\tawait options.set(\"emdash:site_title\", DEV_SITE_TITLE);\n\t\t}\n\n\t\t// Store canonical site URL (used by magic-link/recovery emails)\n\t\tawait options.set(\"emdash:site_url\", getPublicOrigin(url, emdash?.config));\n\n\t\t// Mark setup complete\n\t\tawait options.set(\"emdash:setup_complete\", true);\n\n\t\t// Create session\n\t\tif (session) {\n\t\t\tsession.set(\"user\", { id: user.id });\n\t\t}\n\n\t\t// Optionally create a PAT token (?token=1) for headless/CLI testing.\n\t\tlet token: string | undefined;\n\t\tif (url.searchParams.has(\"token\")) {\n\t\t\t// Idempotent by name: a prior reset can leave a stale dev-bypass-token,\n\t\t\t// and the raw token is only available at creation, so drop any existing\n\t\t\t// one and mint a fresh, usable PAT rather than accumulating duplicates.\n\t\t\tawait deleteApiTokensByName(emdash.db, user.id, \"dev-bypass-token\");\n\t\t\tconst result = await handleApiTokenCreate(emdash.db, user.id, {\n\t\t\t\tname: \"dev-bypass-token\",\n\t\t\t\tscopes: [\n\t\t\t\t\t\"content:read\",\n\t\t\t\t\t\"content:write\",\n\t\t\t\t\t\"media:read\",\n\t\t\t\t\t\"media:write\",\n\t\t\t\t\t\"schema:read\",\n\t\t\t\t\t\"schema:write\",\n\t\t\t\t\t\"admin\",\n\t\t\t\t],\n\t\t\t});\n\t\t\tif (result.success) {\n\t\t\t\ttoken = result.data.token;\n\t\t\t}\n\t\t}\n\n\t\t// Check for redirect parameter\n\t\tconst redirect = url.searchParams.get(\"redirect\");\n\n\t\tif (redirect) {\n\t\t\t// Validate redirect is a safe local path (prevent open redirect via //evil.com or /\\evil.com)\n\t\t\tif (!isSafeRedirect(redirect)) {\n\t\t\t\treturn apiError(\"INVALID_REDIRECT\", \"Redirect must be a local path\", 400);\n\t\t\t}\n\n\t\t\t// Return an HTML page with meta-refresh redirect\n\t\t\t// This ensures the session is fully saved before redirect\n\t\t\tconst safeRedirect = escapeHtml(redirect);\n\t\t\tconst html = `<!DOCTYPE html>\n<html>\n<head>\n\t<meta http-equiv=\"refresh\" content=\"0;url=${safeRedirect}\">\n</head>\n<body>Redirecting...</body>\n</html>`;\n\t\t\treturn new Response(html, {\n\t\t\t\tstatus: 200,\n\t\t\t\theaders: { \"Content-Type\": \"text/html\" },\n\t\t\t});\n\t\t}\n\n\t\t// Return JSON response\n\t\treturn apiSuccess({\n\t\t\tsuccess: true,\n\t\t\tmessage: \"Dev setup complete\",\n\t\t\tmigrations: migrations.applied,\n\t\t\tuserCreated,\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\t...(token ? { token } : {}),\n\t\t});\n\t} catch (error) {\n\t\treturn handleError(error, \"Dev bypass failed\", \"DEV_BYPASS_ERROR\");\n\t}\n}\n\n// Support both GET and POST\nexport const GET: APIRoute = handleDevBypass;\nexport const POST: APIRoute = handleDevBypass;\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAmBA,MAAa,YAAY;AAgBzB,MAAM,aAAa;AAEnB,MAAM,iBAAiB;AACvB,MAAM,gBAAgB;AACtB,MAAM,iBAAiB;AAEvB,eAAe,gBAAgB,SAAqD;AAEnF,KAAI,CAAC,OAAO,KAAK,IAAI,IACpB,QAAO,SAAS,aAAa,oDAAoD,IAAI;CAGtF,MAAM,EAAE,QAAQ,KAAK,YAAY;CACjC,MAAM,EAAE,WAAW;AAEnB,KAAI,CAAC,QAAQ,GACZ,QAAO,SAAS,kBAAkB,6BAA6B,IAAI;AAGpE,KAAI;EAEH,MAAM,aAAa,MAAM,cAAc,OAAO,GAAG;AACjD,UAAQ,IAAI,0CAA0C,WAAW,QAAQ;EAGzE,MAAM,OAAO,MAAM,UAAU;AAE7B,MADmB,aAAa,KAAK,CACtB,OAAO;GACrB,MAAM,aAAa,MAAM,UAAU,OAAO,IAAI,MAAM;IACnD,gBAAgB;IAChB,YAAY;IACZ,SAAS,OAAO,WAAW;IAC3B,CAAC;AACF,WAAQ,IACP,oCAAoC,WAAW,YAAY,QAAQ,gBAAgB,WAAW,OAAO,QAAQ,SAC7G;;EAGF,MAAM,UAAU,IAAI,kBAAkB,OAAO,GAAG;EAGhD,MAAM,eAAe,MAAM,OAAO,GAChC,WAAW,QAAQ,CACnB,WAAW,CACX,MAAM,SAAS,KAAK,eAAe,CACnC,kBAAkB;EAEpB,IAAI;EACJ,IAAI,cAAc;AAElB,MAAI,CAAC,cAAc;GAClB,MAAM,uBAAM,IAAI,MAAM,EAAC,aAAa;GACpC,MAAM,UAAU;IACf,IAAI,MAAM;IACV,OAAO;IACP,MAAM;IACN,MAAM;IACN,gBAAgB;IAChB,YAAY;IACZ,YAAY;IACZ;AAED,SAAM,OAAO,GAAG,WAAW,QAAQ,CAAC,OAAO,QAAQ,CAAC,SAAS;AAE7D,UAAO;IACN,IAAI,QAAQ;IACZ,OAAO,QAAQ;IACf,MAAM,QAAQ;IACd,MAAM,QAAQ;IACd;AACD,iBAAc;AACd,WAAQ,IAAI,8CAA8C,KAAK,MAAM;QAErE,QAAO;GACN,IAAI,aAAa;GACjB,OAAO,aAAa;GACpB,MAAM,aAAa,QAAQ;GAC3B,MAAM,aAAa;GACnB;AAKF,MAAI,CADkB,MAAM,QAAQ,IAAI,oBAAoB,CAE3D,OAAM,QAAQ,IAAI,qBAAqB,eAAe;AAIvD,QAAM,QAAQ,IAAI,mBAAmB,gBAAgB,KAAK,QAAQ,OAAO,CAAC;AAG1E,QAAM,QAAQ,IAAI,yBAAyB,KAAK;AAGhD,MAAI,QACH,SAAQ,IAAI,QAAQ,EAAE,IAAI,KAAK,IAAI,CAAC;EAIrC,IAAI;AACJ,MAAI,IAAI,aAAa,IAAI,QAAQ,EAAE;AAIlC,SAAM,sBAAsB,OAAO,IAAI,KAAK,IAAI,mBAAmB;GACnE,MAAM,SAAS,MAAM,qBAAqB,OAAO,IAAI,KAAK,IAAI;IAC7D,MAAM;IACN,QAAQ;KACP;KACA;KACA;KACA;KACA;KACA;KACA;KACA;IACD,CAAC;AACF,OAAI,OAAO,QACV,SAAQ,OAAO,KAAK;;EAKtB,MAAM,WAAW,IAAI,aAAa,IAAI,WAAW;AAEjD,MAAI,UAAU;AAEb,OAAI,CAAC,eAAe,SAAS,CAC5B,QAAO,SAAS,oBAAoB,iCAAiC,IAAI;GAM1E,MAAM,OAAO;;;6CADQ,WAAW,SAAS,CAIc;;;;AAIvD,UAAO,IAAI,SAAS,MAAM;IACzB,QAAQ;IACR,SAAS,EAAE,gBAAgB,aAAa;IACxC,CAAC;;AAIH,SAAO,WAAW;GACjB,SAAS;GACT,SAAS;GACT,YAAY,WAAW;GACvB;GACA,MAAM;IACL,IAAI,KAAK;IACT,OAAO,KAAK;IACZ,MAAM,KAAK;IACX,MAAM,KAAK;IACX;GACD,GAAI,QAAQ,EAAE,OAAO,GAAG,EAAE;GAC1B,CAAC;UACM,OAAO;AACf,SAAO,YAAY,OAAO,qBAAqB,mBAAmB;;;AAKpE,MAAa,MAAgB;AAC7B,MAAa,OAAiB"}
@@ -1,7 +1,7 @@
1
- import "../../../../base64-CqR-7kqF.mjs";
2
- import "../../../../types-BXSUSAjt.mjs";
3
- import { t as OptionsRepository } from "../../../../options-BPCVnesz.mjs";
4
- import { n as apiSuccess, r as handleError, t as apiError } from "../../../../error-RwM4dD35.mjs";
1
+ import "../../../../base64-CmWvODNW.mjs";
2
+ import "../../../../types-DXOIbece.mjs";
3
+ import { t as OptionsRepository } from "../../../../options-DTTML-Tx.mjs";
4
+ import { n as apiSuccess, r as handleError, t as apiError } from "../../../../error-BQ1pxs0L.mjs";
5
5
 
6
6
  //#region src/astro/routes/api/setup/dev-reset.ts
7
7
  const prerender = false;
@@ -1,31 +1,34 @@
1
- import { i as runMigrations } from "../../../../runner--4wMWwKM.mjs";
1
+ import { i as runMigrations } from "../../../../runner-DYYnW530.mjs";
2
2
  import "../../../../dialect-helpers-DRI5pyY3.mjs";
3
- import "../../../../content-BIlVx-RX.mjs";
4
- import "../../../../base64-CqR-7kqF.mjs";
5
- import "../../../../types-BXSUSAjt.mjs";
6
- import "../../../../media-JOf3pNkw.mjs";
7
- import "../../../../taxonomy-CdllE4oq.mjs";
8
- import { t as OptionsRepository } from "../../../../options-BPCVnesz.mjs";
9
- import "../../../../redirect-CRWIt8Zj.mjs";
10
- import "../../../../request-cache-D32LpnmI.mjs";
11
- import "../../../../byline-registry-CWP7I71B.mjs";
12
- import "../../../../byline-DUx48sJp.mjs";
13
- import "../../../../fts-manager-1RgHmopc.mjs";
14
- import "../../../../registry-brYh-rAT.mjs";
15
- import "../../../../loader-ZN1ll-d-.mjs";
16
- import "../../../../settings-DfxiWY_s.mjs";
17
- import "../../../../ssrf-BsVGIE0Z.mjs";
18
- import { n as apiSuccess, r as handleError, t as apiError } from "../../../../error-RwM4dD35.mjs";
19
- import { n as parseBody, t as isParseError } from "../../../../parse-CrGndy1A.mjs";
20
- import "../../../../redirects-CCbCqCCd.mjs";
21
- import { d as setupBody } from "../../../../byline-fields-8TMtkBnH.mjs";
3
+ import "../../../../after-B1IIdH3Y.mjs";
4
+ import "../../../../object-cache-SEb2IM4Z.mjs";
5
+ import "../../../../content-2PTDNnoh.mjs";
6
+ import "../../../../base64-CmWvODNW.mjs";
7
+ import "../../../../types-DXOIbece.mjs";
8
+ import "../../../../media-Bw0sA6rb.mjs";
9
+ import "../../../../taxonomy-B2HQuVf5.mjs";
10
+ import { t as OptionsRepository } from "../../../../options-DTTML-Tx.mjs";
11
+ import "../../../../redirect-Bifv_yHv.mjs";
12
+ import "../../../../request-cache-KCNHp_RJ.mjs";
13
+ import "../../../../byline-registry-BOjqDOim.mjs";
14
+ import "../../../../byline-CC0WS4Gu.mjs";
15
+ import "../../../../fts-manager-DtiWqwNJ.mjs";
16
+ import "../../../../registry-CjK96fHD.mjs";
17
+ import "../../../../loader-C8Z48Uof.mjs";
18
+ import "../../../../settings-yaxu9mU-.mjs";
19
+ import "../../../../ssrf-B0VeRLrp.mjs";
20
+ import { n as apiSuccess, r as handleError, t as apiError } from "../../../../error-BQ1pxs0L.mjs";
21
+ import { n as parseBody, t as isParseError } from "../../../../parse-qrHlnzTy.mjs";
22
+ import "../../../../redirects-DUvXgzCX.mjs";
23
+ import { d as setupBody } from "../../../../byline-fields-53i9Et0x.mjs";
24
+ import "../../../../status-CB2basWJ.mjs";
22
25
  import "../../../../api/schemas/index.mjs";
23
- import "../../../../ssrf-BvgVcfNQ.mjs";
24
- import { t as validateSeed } from "../../../../validate-Bz4vqcX1.mjs";
25
- import { t as applySeed } from "../../../../apply-Dr7snAMT.mjs";
26
- import { t as loadSeed } from "../../../../load-BBetCvLC.mjs";
27
- import { n as getPublicOrigin } from "../../../../public-url-BFVC2OTJ.mjs";
28
- import { t as getAuthMode } from "../../../../mode-CO2vQHfq.mjs";
26
+ import "../../../../ssrf-Cz1e2QPn.mjs";
27
+ import { t as validateSeed } from "../../../../validate-Bwl64sxv.mjs";
28
+ import { t as applySeed } from "../../../../apply-wDqQoxX4.mjs";
29
+ import { t as loadSeed } from "../../../../load-Dtoo7KcJ.mjs";
30
+ import { n as getPublicOrigin } from "../../../../public-url-8lFyQ8ZF.mjs";
31
+ import { t as getAuthMode } from "../../../../mode-CFh8Dw8G.mjs";
29
32
 
30
33
  //#region src/astro/routes/api/setup/index.ts
31
34
  const prerender = false;
@@ -1 +1 @@
1
- {"version":3,"file":"index.mjs","names":[],"sources":["../../../../../src/astro/routes/api/setup/index.ts"],"sourcesContent":["/**\n * POST /_emdash/api/setup\n *\n * Executes the setup wizard - applies seed file and marks setup complete\n */\n\nimport type { APIRoute } from \"astro\";\n\nexport const prerender = false;\n\nimport { apiError, apiSuccess, handleError } from \"#api/error.js\";\nimport { isParseError, parseBody } from \"#api/parse.js\";\nimport { getPublicOrigin } from \"#api/public-url.js\";\nimport { setupBody } from \"#api/schemas.js\";\nimport { getAuthMode } from \"#auth/mode.js\";\nimport { runMigrations } from \"#db/migrations/runner.js\";\nimport { OptionsRepository } from \"#db/repositories/options.js\";\nimport { applySeed } from \"#seed/apply.js\";\nimport { loadSeed } from \"#seed/load.js\";\nimport { validateSeed } from \"#seed/validate.js\";\n\nexport const POST: APIRoute = async ({ request, url, 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// Guard: reject if setup has already been completed.\n\t\t// The options table may not exist on first-ever setup (pre-migration),\n\t\t// so a query failure means setup hasn't run yet — allow it to proceed.\n\t\ttry {\n\t\t\tconst options = new OptionsRepository(emdash.db);\n\t\t\tconst setupComplete = await options.get(\"emdash:setup_complete\");\n\n\t\t\tif (setupComplete === true || setupComplete === \"true\") {\n\t\t\t\treturn apiError(\"ALREADY_CONFIGURED\", \"Setup has already been completed\", 409);\n\t\t\t}\n\t\t} catch {\n\t\t\t// Options table doesn't exist yet — first-ever setup, allow it\n\t\t}\n\n\t\t// Parse request body\n\t\tconst body = await parseBody(request, setupBody);\n\t\tif (isParseError(body)) return body;\n\n\t\t// 1. Run core migrations\n\t\ttry {\n\t\t\tawait runMigrations(emdash.db);\n\t\t} catch (error) {\n\t\t\treturn handleError(error, \"Failed to run database migrations\", \"MIGRATION_ERROR\");\n\t\t}\n\n\t\t// 2. Load seed file (user seed or built-in default)\n\t\tconst seed = await loadSeed();\n\n\t\t// 3. Override seed settings with form values\n\t\tseed.settings = {\n\t\t\t...seed.settings,\n\t\t\ttitle: body.title,\n\t\t\ttagline: body.tagline,\n\t\t};\n\n\t\t// 4. Apply seed\n\t\tconst validation = validateSeed(seed);\n\t\tif (!validation.valid) {\n\t\t\treturn apiError(\"INVALID_SEED\", `Invalid seed file: ${validation.errors.join(\", \")}`, 400);\n\t\t}\n\n\t\tlet result;\n\t\ttry {\n\t\t\tresult = await applySeed(emdash.db, seed, {\n\t\t\t\tincludeContent: body.includeContent,\n\t\t\t\tonConflict: \"skip\",\n\t\t\t\tstorage: emdash.storage ?? undefined,\n\t\t\t});\n\t\t} catch (error) {\n\t\t\treturn handleError(error, \"Failed to apply seed\", \"SEED_ERROR\");\n\t\t}\n\n\t\t// 5. Store setup state\n\t\t// In external auth mode, mark setup complete immediately (first user to login becomes admin)\n\t\t// Otherwise, setup_complete is set after admin user is created (passkey or auth provider)\n\t\tconst authMode = getAuthMode(emdash.config);\n\t\tconst useExternalAuth = authMode.type === \"external\";\n\n\t\ttry {\n\t\t\tconst options = new OptionsRepository(emdash.db);\n\n\t\t\t// Store the canonical site URL from the setup request.\n\t\t\t// Write-once at the DB level so concurrent setup POSTs can't both\n\t\t\t// observe an empty value and race to write. A spoofed Host header\n\t\t\t// on a later call during the wizard window must not be able to\n\t\t\t// replace the first value.\n\t\t\tconst siteUrl = getPublicOrigin(url, emdash.config);\n\t\t\tawait options.setIfAbsent(\"emdash:site_url\", siteUrl);\n\n\t\t\tif (useExternalAuth) {\n\t\t\t\t// External auth mode: mark setup complete now\n\t\t\t\t// First user to log in via external provider will become admin\n\t\t\t\tawait options.set(\"emdash:setup_complete\", true);\n\t\t\t\tawait options.set(\"emdash:site_title\", body.title);\n\t\t\t\tif (body.tagline) {\n\t\t\t\t\tawait options.set(\"emdash:site_tagline\", body.tagline);\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\t// Passkey/provider mode: store state for next step (admin creation)\n\t\t\t\tawait options.set(\"emdash:setup_state\", {\n\t\t\t\t\tstep: \"site_complete\",\n\t\t\t\t\ttitle: body.title,\n\t\t\t\t\ttagline: body.tagline,\n\t\t\t\t});\n\t\t\t}\n\t\t} catch (error) {\n\t\t\tconsole.error(\"Failed to save setup state:\", error);\n\t\t\t// Non-fatal - continue anyway\n\t\t}\n\n\t\t// 6. Return success with result\n\t\treturn apiSuccess({\n\t\t\tsuccess: true,\n\t\t\t// In external auth mode, setup is complete - redirect to admin\n\t\t\tsetupComplete: useExternalAuth,\n\t\t\tresult,\n\t\t});\n\t} catch (error) {\n\t\treturn handleError(error, \"Setup failed\", \"SETUP_ERROR\");\n\t}\n};\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAQA,MAAa,YAAY;AAazB,MAAa,OAAiB,OAAO,EAAE,SAAS,KAAK,aAAa;CACjE,MAAM,EAAE,WAAW;AAEnB,KAAI,CAAC,QAAQ,GACZ,QAAO,SAAS,kBAAkB,6BAA6B,IAAI;AAGpE,KAAI;AAIH,MAAI;GAEH,MAAM,gBAAgB,MADN,IAAI,kBAAkB,OAAO,GAAG,CACZ,IAAI,wBAAwB;AAEhE,OAAI,kBAAkB,QAAQ,kBAAkB,OAC/C,QAAO,SAAS,sBAAsB,oCAAoC,IAAI;UAExE;EAKR,MAAM,OAAO,MAAM,UAAU,SAAS,UAAU;AAChD,MAAI,aAAa,KAAK,CAAE,QAAO;AAG/B,MAAI;AACH,SAAM,cAAc,OAAO,GAAG;WACtB,OAAO;AACf,UAAO,YAAY,OAAO,qCAAqC,kBAAkB;;EAIlF,MAAM,OAAO,MAAM,UAAU;AAG7B,OAAK,WAAW;GACf,GAAG,KAAK;GACR,OAAO,KAAK;GACZ,SAAS,KAAK;GACd;EAGD,MAAM,aAAa,aAAa,KAAK;AACrC,MAAI,CAAC,WAAW,MACf,QAAO,SAAS,gBAAgB,sBAAsB,WAAW,OAAO,KAAK,KAAK,IAAI,IAAI;EAG3F,IAAI;AACJ,MAAI;AACH,YAAS,MAAM,UAAU,OAAO,IAAI,MAAM;IACzC,gBAAgB,KAAK;IACrB,YAAY;IACZ,SAAS,OAAO,WAAW;IAC3B,CAAC;WACM,OAAO;AACf,UAAO,YAAY,OAAO,wBAAwB,aAAa;;EAOhE,MAAM,kBADW,YAAY,OAAO,OAAO,CACV,SAAS;AAE1C,MAAI;GACH,MAAM,UAAU,IAAI,kBAAkB,OAAO,GAAG;GAOhD,MAAM,UAAU,gBAAgB,KAAK,OAAO,OAAO;AACnD,SAAM,QAAQ,YAAY,mBAAmB,QAAQ;AAErD,OAAI,iBAAiB;AAGpB,UAAM,QAAQ,IAAI,yBAAyB,KAAK;AAChD,UAAM,QAAQ,IAAI,qBAAqB,KAAK,MAAM;AAClD,QAAI,KAAK,QACR,OAAM,QAAQ,IAAI,uBAAuB,KAAK,QAAQ;SAIvD,OAAM,QAAQ,IAAI,sBAAsB;IACvC,MAAM;IACN,OAAO,KAAK;IACZ,SAAS,KAAK;IACd,CAAC;WAEK,OAAO;AACf,WAAQ,MAAM,+BAA+B,MAAM;;AAKpD,SAAO,WAAW;GACjB,SAAS;GAET,eAAe;GACf;GACA,CAAC;UACM,OAAO;AACf,SAAO,YAAY,OAAO,gBAAgB,cAAc"}
1
+ {"version":3,"file":"index.mjs","names":[],"sources":["../../../../../src/astro/routes/api/setup/index.ts"],"sourcesContent":["/**\n * POST /_emdash/api/setup\n *\n * Executes the setup wizard - applies seed file and marks setup complete\n */\n\nimport type { APIRoute } from \"astro\";\n\nexport const prerender = false;\n\nimport { apiError, apiSuccess, handleError } from \"#api/error.js\";\nimport { isParseError, parseBody } from \"#api/parse.js\";\nimport { getPublicOrigin } from \"#api/public-url.js\";\nimport { setupBody } from \"#api/schemas.js\";\nimport { getAuthMode } from \"#auth/mode.js\";\nimport { runMigrations } from \"#db/migrations/runner.js\";\nimport { OptionsRepository } from \"#db/repositories/options.js\";\nimport { applySeed } from \"#seed/apply.js\";\nimport { loadSeed } from \"#seed/load.js\";\nimport { validateSeed } from \"#seed/validate.js\";\n\nexport const POST: APIRoute = async ({ request, url, 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// Guard: reject if setup has already been completed.\n\t\t// The options table may not exist on first-ever setup (pre-migration),\n\t\t// so a query failure means setup hasn't run yet — allow it to proceed.\n\t\ttry {\n\t\t\tconst options = new OptionsRepository(emdash.db);\n\t\t\tconst setupComplete = await options.get(\"emdash:setup_complete\");\n\n\t\t\tif (setupComplete === true || setupComplete === \"true\") {\n\t\t\t\treturn apiError(\"ALREADY_CONFIGURED\", \"Setup has already been completed\", 409);\n\t\t\t}\n\t\t} catch {\n\t\t\t// Options table doesn't exist yet — first-ever setup, allow it\n\t\t}\n\n\t\t// Parse request body\n\t\tconst body = await parseBody(request, setupBody);\n\t\tif (isParseError(body)) return body;\n\n\t\t// 1. Run core migrations\n\t\ttry {\n\t\t\tawait runMigrations(emdash.db);\n\t\t} catch (error) {\n\t\t\treturn handleError(error, \"Failed to run database migrations\", \"MIGRATION_ERROR\");\n\t\t}\n\n\t\t// 2. Load seed file (user seed or built-in default)\n\t\tconst seed = await loadSeed();\n\n\t\t// 3. Override seed settings with form values\n\t\tseed.settings = {\n\t\t\t...seed.settings,\n\t\t\ttitle: body.title,\n\t\t\ttagline: body.tagline,\n\t\t};\n\n\t\t// 4. Apply seed\n\t\tconst validation = validateSeed(seed);\n\t\tif (!validation.valid) {\n\t\t\treturn apiError(\"INVALID_SEED\", `Invalid seed file: ${validation.errors.join(\", \")}`, 400);\n\t\t}\n\n\t\tlet result;\n\t\ttry {\n\t\t\tresult = await applySeed(emdash.db, seed, {\n\t\t\t\tincludeContent: body.includeContent,\n\t\t\t\tonConflict: \"skip\",\n\t\t\t\tstorage: emdash.storage ?? undefined,\n\t\t\t});\n\t\t} catch (error) {\n\t\t\treturn handleError(error, \"Failed to apply seed\", \"SEED_ERROR\");\n\t\t}\n\n\t\t// 5. Store setup state\n\t\t// In external auth mode, mark setup complete immediately (first user to login becomes admin)\n\t\t// Otherwise, setup_complete is set after admin user is created (passkey or auth provider)\n\t\tconst authMode = getAuthMode(emdash.config);\n\t\tconst useExternalAuth = authMode.type === \"external\";\n\n\t\ttry {\n\t\t\tconst options = new OptionsRepository(emdash.db);\n\n\t\t\t// Store the canonical site URL from the setup request.\n\t\t\t// Write-once at the DB level so concurrent setup POSTs can't both\n\t\t\t// observe an empty value and race to write. A spoofed Host header\n\t\t\t// on a later call during the wizard window must not be able to\n\t\t\t// replace the first value.\n\t\t\tconst siteUrl = getPublicOrigin(url, emdash.config);\n\t\t\tawait options.setIfAbsent(\"emdash:site_url\", siteUrl);\n\n\t\t\tif (useExternalAuth) {\n\t\t\t\t// External auth mode: mark setup complete now\n\t\t\t\t// First user to log in via external provider will become admin\n\t\t\t\tawait options.set(\"emdash:setup_complete\", true);\n\t\t\t\tawait options.set(\"emdash:site_title\", body.title);\n\t\t\t\tif (body.tagline) {\n\t\t\t\t\tawait options.set(\"emdash:site_tagline\", body.tagline);\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\t// Passkey/provider mode: store state for next step (admin creation)\n\t\t\t\tawait options.set(\"emdash:setup_state\", {\n\t\t\t\t\tstep: \"site_complete\",\n\t\t\t\t\ttitle: body.title,\n\t\t\t\t\ttagline: body.tagline,\n\t\t\t\t});\n\t\t\t}\n\t\t} catch (error) {\n\t\t\tconsole.error(\"Failed to save setup state:\", error);\n\t\t\t// Non-fatal - continue anyway\n\t\t}\n\n\t\t// 6. Return success with result\n\t\treturn apiSuccess({\n\t\t\tsuccess: true,\n\t\t\t// In external auth mode, setup is complete - redirect to admin\n\t\t\tsetupComplete: useExternalAuth,\n\t\t\tresult,\n\t\t});\n\t} catch (error) {\n\t\treturn handleError(error, \"Setup failed\", \"SETUP_ERROR\");\n\t}\n};\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAQA,MAAa,YAAY;AAazB,MAAa,OAAiB,OAAO,EAAE,SAAS,KAAK,aAAa;CACjE,MAAM,EAAE,WAAW;AAEnB,KAAI,CAAC,QAAQ,GACZ,QAAO,SAAS,kBAAkB,6BAA6B,IAAI;AAGpE,KAAI;AAIH,MAAI;GAEH,MAAM,gBAAgB,MADN,IAAI,kBAAkB,OAAO,GAAG,CACZ,IAAI,wBAAwB;AAEhE,OAAI,kBAAkB,QAAQ,kBAAkB,OAC/C,QAAO,SAAS,sBAAsB,oCAAoC,IAAI;UAExE;EAKR,MAAM,OAAO,MAAM,UAAU,SAAS,UAAU;AAChD,MAAI,aAAa,KAAK,CAAE,QAAO;AAG/B,MAAI;AACH,SAAM,cAAc,OAAO,GAAG;WACtB,OAAO;AACf,UAAO,YAAY,OAAO,qCAAqC,kBAAkB;;EAIlF,MAAM,OAAO,MAAM,UAAU;AAG7B,OAAK,WAAW;GACf,GAAG,KAAK;GACR,OAAO,KAAK;GACZ,SAAS,KAAK;GACd;EAGD,MAAM,aAAa,aAAa,KAAK;AACrC,MAAI,CAAC,WAAW,MACf,QAAO,SAAS,gBAAgB,sBAAsB,WAAW,OAAO,KAAK,KAAK,IAAI,IAAI;EAG3F,IAAI;AACJ,MAAI;AACH,YAAS,MAAM,UAAU,OAAO,IAAI,MAAM;IACzC,gBAAgB,KAAK;IACrB,YAAY;IACZ,SAAS,OAAO,WAAW;IAC3B,CAAC;WACM,OAAO;AACf,UAAO,YAAY,OAAO,wBAAwB,aAAa;;EAOhE,MAAM,kBADW,YAAY,OAAO,OAAO,CACV,SAAS;AAE1C,MAAI;GACH,MAAM,UAAU,IAAI,kBAAkB,OAAO,GAAG;GAOhD,MAAM,UAAU,gBAAgB,KAAK,OAAO,OAAO;AACnD,SAAM,QAAQ,YAAY,mBAAmB,QAAQ;AAErD,OAAI,iBAAiB;AAGpB,UAAM,QAAQ,IAAI,yBAAyB,KAAK;AAChD,UAAM,QAAQ,IAAI,qBAAqB,KAAK,MAAM;AAClD,QAAI,KAAK,QACR,OAAM,QAAQ,IAAI,uBAAuB,KAAK,QAAQ;SAIvD,OAAM,QAAQ,IAAI,sBAAsB;IACvC,MAAM;IACN,OAAO,KAAK;IACZ,SAAS,KAAK;IACd,CAAC;WAEK,OAAO;AACf,WAAQ,MAAM,+BAA+B,MAAM;;AAKpD,SAAO,WAAW;GACjB,SAAS;GAET,eAAe;GACf;GACA,CAAC;UACM,OAAO;AACf,SAAO,YAAY,OAAO,gBAAgB,cAAc"}