emdash 0.40.0 → 0.40.1

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 (200) hide show
  1. package/dist/api/route-utils.mjs +6 -6
  2. package/dist/api/schemas/index.d.mts +1 -1
  3. package/dist/{api-cFFZpyS0.mjs → api-CuyNEHZG.mjs} +3 -3
  4. package/dist/{api-cFFZpyS0.mjs.map → api-CuyNEHZG.mjs.map} +1 -1
  5. package/dist/{apply-CoT603H3.mjs → apply-npY1TAhG.mjs} +237 -34
  6. package/dist/apply-npY1TAhG.mjs.map +1 -0
  7. package/dist/astro/index.d.mts +3 -3
  8. package/dist/astro/index.mjs +9 -9
  9. package/dist/astro/index.mjs.map +1 -1
  10. package/dist/astro/middleware/auth.d.mts +3 -3
  11. package/dist/astro/middleware/redirect.mjs +1 -1
  12. package/dist/astro/middleware.d.mts +3 -3
  13. package/dist/astro/middleware.d.mts.map +1 -1
  14. package/dist/astro/middleware.mjs +19 -18
  15. package/dist/astro/middleware.mjs.map +1 -1
  16. package/dist/astro/routes/api/admin/media-usage/progress.mjs +2 -2
  17. package/dist/astro/routes/api/admin/media-usage/repair.mjs +2 -2
  18. package/dist/astro/routes/api/admin/plugins/_id_/index.mjs +8 -8
  19. package/dist/astro/routes/api/admin/plugins/_id_/settings.mjs +8 -8
  20. package/dist/astro/routes/api/admin/plugins/_id_/uninstall.mjs +8 -8
  21. package/dist/astro/routes/api/admin/plugins/_id_/update.mjs +11 -11
  22. package/dist/astro/routes/api/admin/plugins/index.mjs +8 -8
  23. package/dist/astro/routes/api/admin/plugins/marketplace/_id_/index.mjs +8 -8
  24. package/dist/astro/routes/api/admin/plugins/marketplace/_id_/install.mjs +11 -11
  25. package/dist/astro/routes/api/admin/plugins/marketplace/index.mjs +8 -8
  26. package/dist/astro/routes/api/admin/plugins/registry/_id_/uninstall.mjs +8 -8
  27. package/dist/astro/routes/api/admin/plugins/registry/_id_/update.mjs +12 -12
  28. package/dist/astro/routes/api/admin/plugins/registry/install.mjs +9 -9
  29. package/dist/astro/routes/api/admin/plugins/registry/verify.mjs +9 -9
  30. package/dist/astro/routes/api/admin/plugins/updates.mjs +8 -8
  31. package/dist/astro/routes/api/admin/themes/marketplace/_id_/index.mjs +8 -8
  32. package/dist/astro/routes/api/admin/themes/marketplace/index.mjs +8 -8
  33. package/dist/astro/routes/api/admin/transfer/approvals/_id_/approve.mjs +3 -3
  34. package/dist/astro/routes/api/admin/transfer/approvals/_id_/deny.mjs +3 -3
  35. package/dist/astro/routes/api/admin/transfer/approvals/index.mjs +3 -3
  36. package/dist/astro/routes/api/admin/transfer/capabilities.mjs +3 -3
  37. package/dist/astro/routes/api/admin/transfer/exports/_id_/advance.mjs +3 -3
  38. package/dist/astro/routes/api/admin/transfer/exports/_id_/archive.mjs +3 -3
  39. package/dist/astro/routes/api/admin/transfer/exports/_id_/files/_...path_.mjs +3 -3
  40. package/dist/astro/routes/api/admin/transfer/exports/_id_/index.mjs +3 -3
  41. package/dist/astro/routes/api/admin/transfer/exports/_id_/manifest.mjs +3 -3
  42. package/dist/astro/routes/api/admin/transfer/exports/index.mjs +3 -3
  43. package/dist/astro/routes/api/admin/transfer/imports/_id_/abandon.mjs +3 -3
  44. package/dist/astro/routes/api/admin/transfer/imports/_id_/advance.mjs +3 -3
  45. package/dist/astro/routes/api/admin/transfer/imports/_id_/analyze.mjs +3 -3
  46. package/dist/astro/routes/api/admin/transfer/imports/_id_/cancel.mjs +3 -3
  47. package/dist/astro/routes/api/admin/transfer/imports/_id_/execute.mjs +3 -3
  48. package/dist/astro/routes/api/admin/transfer/imports/_id_/files/_...path_.mjs +3 -3
  49. package/dist/astro/routes/api/admin/transfer/imports/_id_/index.mjs +3 -3
  50. package/dist/astro/routes/api/admin/transfer/imports/_id_/missing.mjs +3 -3
  51. package/dist/astro/routes/api/admin/transfer/imports/_id_/plan.mjs +3 -3
  52. package/dist/astro/routes/api/admin/transfer/imports/_id_/receipt.mjs +3 -3
  53. package/dist/astro/routes/api/admin/transfer/imports/index.mjs +3 -3
  54. package/dist/astro/routes/api/dashboard.mjs +2 -2
  55. package/dist/astro/routes/api/health.mjs +1 -1
  56. package/dist/astro/routes/api/import/probe.mjs +3 -3
  57. package/dist/astro/routes/api/import/wordpress/execute.d.mts +3 -3
  58. package/dist/astro/routes/api/import/wordpress/media.d.mts +3 -3
  59. package/dist/astro/routes/api/import/wordpress/rewrite-urls.d.mts +3 -3
  60. package/dist/astro/routes/api/import/wordpress-plugin/analyze.mjs +3 -3
  61. package/dist/astro/routes/api/import/wordpress-plugin/execute.d.mts +3 -3
  62. package/dist/astro/routes/api/import/wordpress-plugin/execute.mjs +3 -3
  63. package/dist/astro/routes/api/manifest.mjs +1 -1
  64. package/dist/astro/routes/api/mcp.mjs +13 -33
  65. package/dist/astro/routes/api/mcp.mjs.map +1 -1
  66. package/dist/astro/routes/api/media/_id_/confirm.mjs +1 -1
  67. package/dist/astro/routes/api/media/_id_/upload.mjs +1 -1
  68. package/dist/astro/routes/api/media/_id_/usage.mjs +2 -2
  69. package/dist/astro/routes/api/media/_id_.mjs +2 -2
  70. package/dist/astro/routes/api/media/asset/_id_/_filename_.mjs +1 -1
  71. package/dist/astro/routes/api/media/upload-url.mjs +1 -1
  72. package/dist/astro/routes/api/media.mjs +2 -2
  73. package/dist/astro/routes/api/redirects/404s/index.mjs +2 -2
  74. package/dist/astro/routes/api/redirects/404s/summary.mjs +2 -2
  75. package/dist/astro/routes/api/redirects/_id_.mjs +2 -2
  76. package/dist/astro/routes/api/redirects/index.mjs +2 -2
  77. package/dist/astro/routes/api/schema/block-types/_slug_/index.mjs +8 -8
  78. package/dist/astro/routes/api/schema/block-types/_slug_/versions/_version_/activate.mjs +8 -8
  79. package/dist/astro/routes/api/schema/block-types/index.mjs +8 -8
  80. package/dist/astro/routes/api/schema/collections/_slug_/fields/_fieldSlug_.mjs +8 -8
  81. package/dist/astro/routes/api/schema/collections/_slug_/fields/index.mjs +8 -8
  82. package/dist/astro/routes/api/schema/collections/_slug_/fields/reorder.mjs +8 -8
  83. package/dist/astro/routes/api/schema/collections/_slug_/index.mjs +8 -8
  84. package/dist/astro/routes/api/schema/collections/index.mjs +8 -8
  85. package/dist/astro/routes/api/schema/collections/reorder.mjs +8 -8
  86. package/dist/astro/routes/api/schema/orphans/_slug_.mjs +8 -8
  87. package/dist/astro/routes/api/schema/orphans/index.mjs +8 -8
  88. package/dist/astro/routes/api/settings/backups/archives/_name_.mjs +2 -2
  89. package/dist/astro/routes/api/settings/backups/archives/index.mjs +2 -2
  90. package/dist/astro/routes/api/settings/backups/export.mjs +2 -2
  91. package/dist/astro/routes/api/settings/backups/index.mjs +2 -2
  92. package/dist/astro/routes/api/settings.mjs +3 -3
  93. package/dist/astro/routes/api/setup/dev-bypass.mjs +4 -4
  94. package/dist/astro/routes/api/setup/index.d.mts.map +1 -1
  95. package/dist/astro/routes/api/setup/index.mjs +35 -10
  96. package/dist/astro/routes/api/setup/index.mjs.map +1 -1
  97. package/dist/astro/routes/api/snapshot.mjs +2 -2
  98. package/dist/astro/routes/api/snapshot.mjs.map +1 -1
  99. package/dist/astro/routes/robots.txt.mjs +2 -2
  100. package/dist/astro/routes/sitemap-_collection_.xml.mjs +2 -2
  101. package/dist/astro/routes/sitemap.xml.mjs +2 -2
  102. package/dist/astro/types.d.mts +7 -3
  103. package/dist/astro/types.d.mts.map +1 -1
  104. package/dist/{backup-CBu0LrXf.mjs → backup-BQRj3afm.mjs} +3 -3
  105. package/dist/{backup-CBu0LrXf.mjs.map → backup-BQRj3afm.mjs.map} +1 -1
  106. package/dist/cli/index.mjs +6 -6
  107. package/dist/client/index.d.mts +14 -14
  108. package/dist/{config-5ii2haYu.d.mts → config-BjEm_3xL.d.mts} +25 -16
  109. package/dist/config-BjEm_3xL.d.mts.map +1 -0
  110. package/dist/{context-BeGccdUX.mjs → context-BV_7t-Ua.mjs} +6 -6
  111. package/dist/{context-BeGccdUX.mjs.map → context-BV_7t-Ua.mjs.map} +1 -1
  112. package/dist/{dashboard-DjrB-xxZ.mjs → dashboard-BP-iJqpd.mjs} +2 -2
  113. package/dist/{dashboard-DjrB-xxZ.mjs.map → dashboard-BP-iJqpd.mjs.map} +1 -1
  114. package/dist/db/libsql-migrations.mjs +2 -2
  115. package/dist/db/postgres-migrations.mjs +2 -2
  116. package/dist/db/sqlite-migrations.mjs +2 -2
  117. package/dist/{direct-executor-BmuFJJZV.mjs → direct-executor-D2lNadwo.mjs} +2 -2
  118. package/dist/{direct-executor-BmuFJJZV.mjs.map → direct-executor-D2lNadwo.mjs.map} +1 -1
  119. package/dist/{emdash-runtime-DAjghyEG.mjs → emdash-runtime-CtfnZmPi.mjs} +56 -56
  120. package/dist/emdash-runtime-CtfnZmPi.mjs.map +1 -0
  121. package/dist/{entry-lock-DVhCt49A.d.mts → entry-lock-Cf5OoIgN.d.mts} +18 -18
  122. package/dist/{entry-lock-DVhCt49A.d.mts.map → entry-lock-Cf5OoIgN.d.mts.map} +1 -1
  123. package/dist/{hreflang-DMFBL2eb.mjs → hreflang-CbVI4paR.mjs} +2 -2
  124. package/dist/{hreflang-DMFBL2eb.mjs.map → hreflang-CbVI4paR.mjs.map} +1 -1
  125. package/dist/{identity-IyNWwXr6.mjs → identity-Be5kzutJ.mjs} +2 -2
  126. package/dist/{identity-IyNWwXr6.mjs.map → identity-Be5kzutJ.mjs.map} +1 -1
  127. package/dist/{import-C3JZplWq.mjs → import-YzfKCaco.mjs} +2 -2
  128. package/dist/{import-C3JZplWq.mjs.map → import-YzfKCaco.mjs.map} +1 -1
  129. package/dist/index.d.mts +4 -4
  130. package/dist/index.mjs +16 -16
  131. package/dist/{manifest-builder-B8zR-73J.mjs → manifest-builder-BmSAOOEF.mjs} +2 -2
  132. package/dist/{manifest-builder-B8zR-73J.mjs.map → manifest-builder-BmSAOOEF.mjs.map} +1 -1
  133. package/dist/media/local-runtime.d.mts +3 -3
  134. package/dist/media/local-runtime.mjs +3 -3
  135. package/dist/{media-Qp5S3eH3.mjs → media-CPXTbb1R.mjs} +20 -2
  136. package/dist/media-CPXTbb1R.mjs.map +1 -0
  137. package/dist/{media-h7tOiDLj.mjs → media-JXRWDhw3.mjs} +77 -4
  138. package/dist/media-JXRWDhw3.mjs.map +1 -0
  139. package/dist/{media-usage-My-Vi-ex.mjs → media-usage-De-zeR9E.mjs} +2 -2
  140. package/dist/{media-usage-My-Vi-ex.mjs.map → media-usage-De-zeR9E.mjs.map} +1 -1
  141. package/dist/{menus-TsSGmSR4.mjs → menus-Cm68rsAq.mjs} +4 -4
  142. package/dist/{menus-TsSGmSR4.mjs.map → menus-Cm68rsAq.mjs.map} +1 -1
  143. package/dist/migrations/index.mjs +2 -2
  144. package/dist/page/index.mjs +2 -2
  145. package/dist/plugin-test-runtime.d.mts +3 -3
  146. package/dist/plugin-test-runtime.mjs +18 -18
  147. package/dist/plugin-utils.d.mts +3 -3
  148. package/dist/plugins/adapt-sandbox-entry.d.mts +3 -3
  149. package/dist/plugins/host.d.mts +1 -1
  150. package/dist/plugins/host.mjs +6 -6
  151. package/dist/{redirect-iJf5fltD.mjs → redirect-B29UjdUn.mjs} +10 -14
  152. package/dist/redirect-B29UjdUn.mjs.map +1 -0
  153. package/dist/{redirects-CYu1u1aK.mjs → redirects-Ca2MPfEG.mjs} +2 -2
  154. package/dist/{redirects-CYu1u1aK.mjs.map → redirects-Ca2MPfEG.mjs.map} +1 -1
  155. package/dist/{routes-CUsM40Cc.mjs → routes-vrR95WR6.mjs} +2 -2
  156. package/dist/{routes-CUsM40Cc.mjs.map → routes-vrR95WR6.mjs.map} +1 -1
  157. package/dist/runtime.d.mts +3 -3
  158. package/dist/seed/index.mjs +4 -4
  159. package/dist/seo/index.mjs +3 -3
  160. package/dist/{settings-CgjRWGW9.mjs → settings-B4vDl1fK.mjs} +2 -2
  161. package/dist/{settings-CgjRWGW9.mjs.map → settings-B4vDl1fK.mjs.map} +1 -1
  162. package/dist/{settings-2xNYr90o.mjs → settings-Dyj6v8C4.mjs} +2 -2
  163. package/dist/{settings-2xNYr90o.mjs.map → settings-Dyj6v8C4.mjs.map} +1 -1
  164. package/dist/{snapshot-CugwUqKQ.mjs → snapshot-PawoX-WG.mjs} +180 -3
  165. package/dist/snapshot-PawoX-WG.mjs.map +1 -0
  166. package/dist/{storage-query-Bdv7A62k.d.mts → storage-query-FXJH5pI8.d.mts} +6 -1
  167. package/dist/storage-query-FXJH5pI8.d.mts.map +1 -0
  168. package/dist/{transfer-BhUCrgDc.mjs → transfer-DgeCvHnj.mjs} +4 -4
  169. package/dist/{transfer-BhUCrgDc.mjs.map → transfer-DgeCvHnj.mjs.map} +1 -1
  170. package/dist/validate-CM79QXYE.d.mts.map +1 -1
  171. package/dist/version-DXsxRrob.mjs +7 -0
  172. package/dist/{version-DUQDHgrf.mjs.map → version-DXsxRrob.mjs.map} +1 -1
  173. package/package.json +5 -5
  174. package/src/api/handlers/index.ts +1 -0
  175. package/src/api/handlers/media-upload.ts +17 -71
  176. package/src/api/handlers/media.ts +97 -3
  177. package/src/api/handlers/snapshot.ts +257 -3
  178. package/src/astro/integration/vite-config.ts +10 -4
  179. package/src/astro/middleware.ts +1 -0
  180. package/src/astro/routes/api/setup/index.ts +66 -23
  181. package/src/astro/routes/api/snapshot.ts +2 -1
  182. package/src/astro/types.ts +5 -0
  183. package/src/cleanup.ts +10 -0
  184. package/src/components/Columns.astro +3 -1
  185. package/src/components/Cover.astro +3 -1
  186. package/src/database/repositories/media.ts +40 -1
  187. package/src/database/repositories/redirect.ts +17 -34
  188. package/src/emdash-runtime.ts +28 -0
  189. package/src/index.ts +1 -0
  190. package/src/mcp/server.ts +13 -48
  191. package/src/seed/apply.ts +322 -41
  192. package/dist/apply-CoT603H3.mjs.map +0 -1
  193. package/dist/config-5ii2haYu.d.mts.map +0 -1
  194. package/dist/emdash-runtime-DAjghyEG.mjs.map +0 -1
  195. package/dist/media-Qp5S3eH3.mjs.map +0 -1
  196. package/dist/media-h7tOiDLj.mjs.map +0 -1
  197. package/dist/redirect-iJf5fltD.mjs.map +0 -1
  198. package/dist/snapshot-CugwUqKQ.mjs.map +0 -1
  199. package/dist/storage-query-Bdv7A62k.d.mts.map +0 -1
  200. package/dist/version-DUQDHgrf.mjs +0 -7
@@ -9,13 +9,13 @@ import "../../../../../content-DFaIEDj9.mjs";
9
9
  import "../../../../../object-cache-CqWNY5uP.mjs";
10
10
  import "../../../../../slugify-T5GHH42D.mjs";
11
11
  import "../../../../../types-BkUg2yHx.mjs";
12
- import "../../../../../media-Qp5S3eH3.mjs";
12
+ import "../../../../../media-CPXTbb1R.mjs";
13
13
  import "../../../../../user-DDSL-sGw.mjs";
14
14
  import "../../../../../taxonomy-C3Fu1YeH.mjs";
15
15
  import "../../../../../comment-CrBl22OF.mjs";
16
16
  import "../../../../../menus-ITeAbcIF.mjs";
17
17
  import "../../../../../resolve-2WbQsCvT.mjs";
18
- import "../../../../../redirect-iJf5fltD.mjs";
18
+ import "../../../../../redirect-B29UjdUn.mjs";
19
19
  import "../../../../../request-cache-DzLYKm_x.mjs";
20
20
  import "../../../../../byline-registry-gnKscbQX.mjs";
21
21
  import "../../../../../field-defs-cache-HIgBbqZZ.mjs";
@@ -27,7 +27,7 @@ import "../../../../../fts-manager-S-K0laoS.mjs";
27
27
  import "../../../../../loader-BzqeR1ZN.mjs";
28
28
  import "../../../../../collection-slugs-cache-CjGk__zp.mjs";
29
29
  import "../../../../../taxonomies-C1IwNe8Q.mjs";
30
- import "../../../../../api-cFFZpyS0.mjs";
30
+ import "../../../../../api-CuyNEHZG.mjs";
31
31
  import "../../../../../capture-triggers-kJyl_yyM.mjs";
32
32
  import "../../../../../activation-LOkDM5WT.mjs";
33
33
  import "../../../../../block-type-registry-DUI_3KxT.mjs";
@@ -37,14 +37,14 @@ import "../../../../../canonical-YhEQezjg.mjs";
37
37
  import "../../../../../digest-BarSh-pN.mjs";
38
38
  import "../../../../../hash-SDAW6zC-.mjs";
39
39
  import "../../../../../zod-generator-D6uE4WiS.mjs";
40
- import "../../../../../dashboard-DjrB-xxZ.mjs";
40
+ import "../../../../../dashboard-BP-iJqpd.mjs";
41
41
  import "../../../../../block-values-C_VIPr5t.mjs";
42
- import "../../../../../media-h7tOiDLj.mjs";
42
+ import "../../../../../media-JXRWDhw3.mjs";
43
43
  import "../../../../../media-folders-BE0oo2eX.mjs";
44
44
  import "../../../../../media-usage-work-C2OZLCAd.mjs";
45
45
  import "../../../../../content-repair-Q8IUrpLL.mjs";
46
46
  import "../../../../../collection-deletion-processor-Br6rxs3u.mjs";
47
- import "../../../../../media-usage-My-Vi-ex.mjs";
47
+ import "../../../../../media-usage-De-zeR9E.mjs";
48
48
  import "../../../../../settings-DYidIB26.mjs";
49
49
  import "../../../../../site-settings-DOgRUoFX.mjs";
50
50
  import "../../../../../errors-BF0_LFhW.mjs";
@@ -55,9 +55,9 @@ import "../../../../../schema-BABiRdsH.mjs";
55
55
  import { o as handleSchemaCollectionList, r as handleSchemaCollectionCreate } from "../../../../../schema-Du3MzCG0.mjs";
56
56
  import "../../../../../block-types-BmZmLmAD.mjs";
57
57
  import "../../../../../seo-CZT2oLtT.mjs";
58
- import "../../../../../settings-CgjRWGW9.mjs";
58
+ import "../../../../../settings-B4vDl1fK.mjs";
59
59
  import "../../../../../sections-Ddptx_o9.mjs";
60
- import "../../../../../settings-2xNYr90o.mjs";
60
+ import "../../../../../settings-Dyj6v8C4.mjs";
61
61
  import "../../../../../taxonomies-C_XMoRcX.mjs";
62
62
  import "../../../../../manifest-schema-CY3zng_M.mjs";
63
63
  import "../../../../../artifact-fetch-DZMOGZ3-.mjs";
@@ -9,13 +9,13 @@ import "../../../../../content-DFaIEDj9.mjs";
9
9
  import "../../../../../object-cache-CqWNY5uP.mjs";
10
10
  import "../../../../../slugify-T5GHH42D.mjs";
11
11
  import "../../../../../types-BkUg2yHx.mjs";
12
- import "../../../../../media-Qp5S3eH3.mjs";
12
+ import "../../../../../media-CPXTbb1R.mjs";
13
13
  import "../../../../../user-DDSL-sGw.mjs";
14
14
  import "../../../../../taxonomy-C3Fu1YeH.mjs";
15
15
  import "../../../../../comment-CrBl22OF.mjs";
16
16
  import "../../../../../menus-ITeAbcIF.mjs";
17
17
  import "../../../../../resolve-2WbQsCvT.mjs";
18
- import "../../../../../redirect-iJf5fltD.mjs";
18
+ import "../../../../../redirect-B29UjdUn.mjs";
19
19
  import "../../../../../request-cache-DzLYKm_x.mjs";
20
20
  import "../../../../../byline-registry-gnKscbQX.mjs";
21
21
  import "../../../../../field-defs-cache-HIgBbqZZ.mjs";
@@ -27,7 +27,7 @@ import "../../../../../fts-manager-S-K0laoS.mjs";
27
27
  import "../../../../../loader-BzqeR1ZN.mjs";
28
28
  import "../../../../../collection-slugs-cache-CjGk__zp.mjs";
29
29
  import "../../../../../taxonomies-C1IwNe8Q.mjs";
30
- import "../../../../../api-cFFZpyS0.mjs";
30
+ import "../../../../../api-CuyNEHZG.mjs";
31
31
  import "../../../../../capture-triggers-kJyl_yyM.mjs";
32
32
  import "../../../../../activation-LOkDM5WT.mjs";
33
33
  import "../../../../../block-type-registry-DUI_3KxT.mjs";
@@ -37,14 +37,14 @@ import "../../../../../canonical-YhEQezjg.mjs";
37
37
  import "../../../../../digest-BarSh-pN.mjs";
38
38
  import "../../../../../hash-SDAW6zC-.mjs";
39
39
  import "../../../../../zod-generator-D6uE4WiS.mjs";
40
- import "../../../../../dashboard-DjrB-xxZ.mjs";
40
+ import "../../../../../dashboard-BP-iJqpd.mjs";
41
41
  import "../../../../../block-values-C_VIPr5t.mjs";
42
- import "../../../../../media-h7tOiDLj.mjs";
42
+ import "../../../../../media-JXRWDhw3.mjs";
43
43
  import "../../../../../media-folders-BE0oo2eX.mjs";
44
44
  import "../../../../../media-usage-work-C2OZLCAd.mjs";
45
45
  import "../../../../../content-repair-Q8IUrpLL.mjs";
46
46
  import "../../../../../collection-deletion-processor-Br6rxs3u.mjs";
47
- import "../../../../../media-usage-My-Vi-ex.mjs";
47
+ import "../../../../../media-usage-De-zeR9E.mjs";
48
48
  import "../../../../../settings-DYidIB26.mjs";
49
49
  import "../../../../../site-settings-DOgRUoFX.mjs";
50
50
  import "../../../../../errors-BF0_LFhW.mjs";
@@ -55,9 +55,9 @@ import "../../../../../schema-BABiRdsH.mjs";
55
55
  import { s as handleSchemaCollectionReorder } from "../../../../../schema-Du3MzCG0.mjs";
56
56
  import "../../../../../block-types-BmZmLmAD.mjs";
57
57
  import "../../../../../seo-CZT2oLtT.mjs";
58
- import "../../../../../settings-CgjRWGW9.mjs";
58
+ import "../../../../../settings-B4vDl1fK.mjs";
59
59
  import "../../../../../sections-Ddptx_o9.mjs";
60
- import "../../../../../settings-2xNYr90o.mjs";
60
+ import "../../../../../settings-Dyj6v8C4.mjs";
61
61
  import "../../../../../taxonomies-C_XMoRcX.mjs";
62
62
  import "../../../../../manifest-schema-CY3zng_M.mjs";
63
63
  import "../../../../../artifact-fetch-DZMOGZ3-.mjs";
@@ -9,13 +9,13 @@ import "../../../../../content-DFaIEDj9.mjs";
9
9
  import "../../../../../object-cache-CqWNY5uP.mjs";
10
10
  import "../../../../../slugify-T5GHH42D.mjs";
11
11
  import "../../../../../types-BkUg2yHx.mjs";
12
- import "../../../../../media-Qp5S3eH3.mjs";
12
+ import "../../../../../media-CPXTbb1R.mjs";
13
13
  import "../../../../../user-DDSL-sGw.mjs";
14
14
  import "../../../../../taxonomy-C3Fu1YeH.mjs";
15
15
  import "../../../../../comment-CrBl22OF.mjs";
16
16
  import "../../../../../menus-ITeAbcIF.mjs";
17
17
  import "../../../../../resolve-2WbQsCvT.mjs";
18
- import "../../../../../redirect-iJf5fltD.mjs";
18
+ import "../../../../../redirect-B29UjdUn.mjs";
19
19
  import "../../../../../request-cache-DzLYKm_x.mjs";
20
20
  import "../../../../../byline-registry-gnKscbQX.mjs";
21
21
  import "../../../../../field-defs-cache-HIgBbqZZ.mjs";
@@ -27,7 +27,7 @@ import "../../../../../fts-manager-S-K0laoS.mjs";
27
27
  import "../../../../../loader-BzqeR1ZN.mjs";
28
28
  import "../../../../../collection-slugs-cache-CjGk__zp.mjs";
29
29
  import "../../../../../taxonomies-C1IwNe8Q.mjs";
30
- import "../../../../../api-cFFZpyS0.mjs";
30
+ import "../../../../../api-CuyNEHZG.mjs";
31
31
  import "../../../../../capture-triggers-kJyl_yyM.mjs";
32
32
  import "../../../../../activation-LOkDM5WT.mjs";
33
33
  import "../../../../../block-type-registry-DUI_3KxT.mjs";
@@ -37,14 +37,14 @@ import "../../../../../canonical-YhEQezjg.mjs";
37
37
  import "../../../../../digest-BarSh-pN.mjs";
38
38
  import "../../../../../hash-SDAW6zC-.mjs";
39
39
  import "../../../../../zod-generator-D6uE4WiS.mjs";
40
- import "../../../../../dashboard-DjrB-xxZ.mjs";
40
+ import "../../../../../dashboard-BP-iJqpd.mjs";
41
41
  import "../../../../../block-values-C_VIPr5t.mjs";
42
- import "../../../../../media-h7tOiDLj.mjs";
42
+ import "../../../../../media-JXRWDhw3.mjs";
43
43
  import "../../../../../media-folders-BE0oo2eX.mjs";
44
44
  import "../../../../../media-usage-work-C2OZLCAd.mjs";
45
45
  import "../../../../../content-repair-Q8IUrpLL.mjs";
46
46
  import "../../../../../collection-deletion-processor-Br6rxs3u.mjs";
47
- import "../../../../../media-usage-My-Vi-ex.mjs";
47
+ import "../../../../../media-usage-De-zeR9E.mjs";
48
48
  import "../../../../../settings-DYidIB26.mjs";
49
49
  import "../../../../../site-settings-DOgRUoFX.mjs";
50
50
  import "../../../../../errors-BF0_LFhW.mjs";
@@ -55,9 +55,9 @@ import "../../../../../schema-BABiRdsH.mjs";
55
55
  import { n as handleOrphanedTableRegister } from "../../../../../schema-Du3MzCG0.mjs";
56
56
  import "../../../../../block-types-BmZmLmAD.mjs";
57
57
  import "../../../../../seo-CZT2oLtT.mjs";
58
- import "../../../../../settings-CgjRWGW9.mjs";
58
+ import "../../../../../settings-B4vDl1fK.mjs";
59
59
  import "../../../../../sections-Ddptx_o9.mjs";
60
- import "../../../../../settings-2xNYr90o.mjs";
60
+ import "../../../../../settings-Dyj6v8C4.mjs";
61
61
  import "../../../../../taxonomies-C_XMoRcX.mjs";
62
62
  import "../../../../../manifest-schema-CY3zng_M.mjs";
63
63
  import "../../../../../artifact-fetch-DZMOGZ3-.mjs";
@@ -9,13 +9,13 @@ import "../../../../../content-DFaIEDj9.mjs";
9
9
  import "../../../../../object-cache-CqWNY5uP.mjs";
10
10
  import "../../../../../slugify-T5GHH42D.mjs";
11
11
  import "../../../../../types-BkUg2yHx.mjs";
12
- import "../../../../../media-Qp5S3eH3.mjs";
12
+ import "../../../../../media-CPXTbb1R.mjs";
13
13
  import "../../../../../user-DDSL-sGw.mjs";
14
14
  import "../../../../../taxonomy-C3Fu1YeH.mjs";
15
15
  import "../../../../../comment-CrBl22OF.mjs";
16
16
  import "../../../../../menus-ITeAbcIF.mjs";
17
17
  import "../../../../../resolve-2WbQsCvT.mjs";
18
- import "../../../../../redirect-iJf5fltD.mjs";
18
+ import "../../../../../redirect-B29UjdUn.mjs";
19
19
  import "../../../../../request-cache-DzLYKm_x.mjs";
20
20
  import "../../../../../byline-registry-gnKscbQX.mjs";
21
21
  import "../../../../../field-defs-cache-HIgBbqZZ.mjs";
@@ -27,7 +27,7 @@ import "../../../../../fts-manager-S-K0laoS.mjs";
27
27
  import "../../../../../loader-BzqeR1ZN.mjs";
28
28
  import "../../../../../collection-slugs-cache-CjGk__zp.mjs";
29
29
  import "../../../../../taxonomies-C1IwNe8Q.mjs";
30
- import "../../../../../api-cFFZpyS0.mjs";
30
+ import "../../../../../api-CuyNEHZG.mjs";
31
31
  import "../../../../../capture-triggers-kJyl_yyM.mjs";
32
32
  import "../../../../../activation-LOkDM5WT.mjs";
33
33
  import "../../../../../block-type-registry-DUI_3KxT.mjs";
@@ -37,14 +37,14 @@ import "../../../../../canonical-YhEQezjg.mjs";
37
37
  import "../../../../../digest-BarSh-pN.mjs";
38
38
  import "../../../../../hash-SDAW6zC-.mjs";
39
39
  import "../../../../../zod-generator-D6uE4WiS.mjs";
40
- import "../../../../../dashboard-DjrB-xxZ.mjs";
40
+ import "../../../../../dashboard-BP-iJqpd.mjs";
41
41
  import "../../../../../block-values-C_VIPr5t.mjs";
42
- import "../../../../../media-h7tOiDLj.mjs";
42
+ import "../../../../../media-JXRWDhw3.mjs";
43
43
  import "../../../../../media-folders-BE0oo2eX.mjs";
44
44
  import "../../../../../media-usage-work-C2OZLCAd.mjs";
45
45
  import "../../../../../content-repair-Q8IUrpLL.mjs";
46
46
  import "../../../../../collection-deletion-processor-Br6rxs3u.mjs";
47
- import "../../../../../media-usage-My-Vi-ex.mjs";
47
+ import "../../../../../media-usage-De-zeR9E.mjs";
48
48
  import "../../../../../settings-DYidIB26.mjs";
49
49
  import "../../../../../site-settings-DOgRUoFX.mjs";
50
50
  import "../../../../../errors-BF0_LFhW.mjs";
@@ -55,9 +55,9 @@ import "../../../../../schema-BABiRdsH.mjs";
55
55
  import { t as handleOrphanedTableList } from "../../../../../schema-Du3MzCG0.mjs";
56
56
  import "../../../../../block-types-BmZmLmAD.mjs";
57
57
  import "../../../../../seo-CZT2oLtT.mjs";
58
- import "../../../../../settings-CgjRWGW9.mjs";
58
+ import "../../../../../settings-B4vDl1fK.mjs";
59
59
  import "../../../../../sections-Ddptx_o9.mjs";
60
- import "../../../../../settings-2xNYr90o.mjs";
60
+ import "../../../../../settings-Dyj6v8C4.mjs";
61
61
  import "../../../../../taxonomies-C_XMoRcX.mjs";
62
62
  import "../../../../../manifest-schema-CY3zng_M.mjs";
63
63
  import "../../../../../artifact-fetch-DZMOGZ3-.mjs";
@@ -5,8 +5,8 @@ import "../../../../../../types-BkUg2yHx.mjs";
5
5
  import "../../../../../../errors-DgE1zJGG.mjs";
6
6
  import { t as ErrorCode } from "../../../../../../errors-BF0_LFhW.mjs";
7
7
  import { a as unwrapResult, r as handleError, t as apiError } from "../../../../../../error-CfvOHP0M.mjs";
8
- import "../../../../../../snapshot-CugwUqKQ.mjs";
9
- import { a as deleteBackupArchive, c as isValidArchiveName, r as BACKUP_STORAGE_PREFIX } from "../../../../../../backup-CBu0LrXf.mjs";
8
+ import "../../../../../../snapshot-PawoX-WG.mjs";
9
+ import { a as deleteBackupArchive, c as isValidArchiveName, r as BACKUP_STORAGE_PREFIX } from "../../../../../../backup-BQRj3afm.mjs";
10
10
  import { i as requirePerm } from "../../../../../../authorize-seCifOMJ.mjs";
11
11
 
12
12
  //#region src/astro/routes/api/settings/backups/archives/[name].ts
@@ -5,8 +5,8 @@ import "../../../../../../types-BkUg2yHx.mjs";
5
5
  import "../../../../../../errors-DgE1zJGG.mjs";
6
6
  import "../../../../../../errors-BF0_LFhW.mjs";
7
7
  import { a as unwrapResult, t as apiError } from "../../../../../../error-CfvOHP0M.mjs";
8
- import "../../../../../../snapshot-CugwUqKQ.mjs";
9
- import { d as runBackupToStorage, s as getBackupSettings } from "../../../../../../backup-CBu0LrXf.mjs";
8
+ import "../../../../../../snapshot-PawoX-WG.mjs";
9
+ import { d as runBackupToStorage, s as getBackupSettings } from "../../../../../../backup-BQRj3afm.mjs";
10
10
  import { i as requirePerm } from "../../../../../../authorize-seCifOMJ.mjs";
11
11
 
12
12
  //#region src/astro/routes/api/settings/backups/archives/index.ts
@@ -5,8 +5,8 @@ import "../../../../../types-BkUg2yHx.mjs";
5
5
  import "../../../../../errors-DgE1zJGG.mjs";
6
6
  import { t as ErrorCode } from "../../../../../errors-BF0_LFhW.mjs";
7
7
  import { r as handleError, t as apiError } from "../../../../../error-CfvOHP0M.mjs";
8
- import "../../../../../snapshot-CugwUqKQ.mjs";
9
- import { i as archiveNameForDate, o as generateBackupJson } from "../../../../../backup-CBu0LrXf.mjs";
8
+ import "../../../../../snapshot-PawoX-WG.mjs";
9
+ import { i as archiveNameForDate, o as generateBackupJson } from "../../../../../backup-BQRj3afm.mjs";
10
10
  import { i as requirePerm } from "../../../../../authorize-seCifOMJ.mjs";
11
11
 
12
12
  //#region src/astro/routes/api/settings/backups/export.ts
@@ -6,8 +6,8 @@ import "../../../../../errors-DgE1zJGG.mjs";
6
6
  import { t as ErrorCode } from "../../../../../errors-BF0_LFhW.mjs";
7
7
  import { a as unwrapResult, n as apiSuccess, r as handleError, t as apiError } from "../../../../../error-CfvOHP0M.mjs";
8
8
  import { n as parseBody, t as isParseError } from "../../../../../parse-DY6OD1j_.mjs";
9
- import "../../../../../snapshot-CugwUqKQ.mjs";
10
- import { f as updateBackupSettings, l as listBackupArchives, n as BACKUP_RETENTION_MIN, s as getBackupSettings, t as BACKUP_RETENTION_MAX } from "../../../../../backup-CBu0LrXf.mjs";
9
+ import "../../../../../snapshot-PawoX-WG.mjs";
10
+ import { f as updateBackupSettings, l as listBackupArchives, n as BACKUP_RETENTION_MIN, s as getBackupSettings, t as BACKUP_RETENTION_MAX } from "../../../../../backup-BQRj3afm.mjs";
11
11
  import { i as requirePerm } from "../../../../../authorize-seCifOMJ.mjs";
12
12
  import { z } from "zod";
13
13
 
@@ -6,7 +6,7 @@ import "../../../base64-DvnNgP7e.mjs";
6
6
  import "../../../secrets-CIi0nFiR.mjs";
7
7
  import "../../../object-cache-CqWNY5uP.mjs";
8
8
  import "../../../types-BkUg2yHx.mjs";
9
- import "../../../media-Qp5S3eH3.mjs";
9
+ import "../../../media-CPXTbb1R.mjs";
10
10
  import "../../../request-cache-DzLYKm_x.mjs";
11
11
  import { n as siteSettingsTag } from "../../../chrome-tags-DApCQSIk.mjs";
12
12
  import "../../../loader-BzqeR1ZN.mjs";
@@ -14,8 +14,8 @@ import "../../../errors-DgE1zJGG.mjs";
14
14
  import "../../../settings-DYidIB26.mjs";
15
15
  import "../../../site-settings-DOgRUoFX.mjs";
16
16
  import "../../../errors-BF0_LFhW.mjs";
17
- import "../../../settings-CgjRWGW9.mjs";
18
- import { n as handleSettingsUpdate, t as handleSettingsGet } from "../../../settings-2xNYr90o.mjs";
17
+ import "../../../settings-B4vDl1fK.mjs";
18
+ import { n as handleSettingsUpdate, t as handleSettingsGet } from "../../../settings-Dyj6v8C4.mjs";
19
19
  import { a as unwrapResult, r as handleError, t as apiError } from "../../../error-CfvOHP0M.mjs";
20
20
  import { n as parseBody, t as isParseError } from "../../../parse-DY6OD1j_.mjs";
21
21
  import "../../../redirects-Cv9apQKj.mjs";
@@ -9,10 +9,10 @@ import "../../../../content-DFaIEDj9.mjs";
9
9
  import "../../../../object-cache-CqWNY5uP.mjs";
10
10
  import "../../../../slugify-T5GHH42D.mjs";
11
11
  import "../../../../types-BkUg2yHx.mjs";
12
- import "../../../../media-Qp5S3eH3.mjs";
12
+ import "../../../../media-CPXTbb1R.mjs";
13
13
  import "../../../../taxonomy-C3Fu1YeH.mjs";
14
14
  import "../../../../resolve-2WbQsCvT.mjs";
15
- import "../../../../redirect-iJf5fltD.mjs";
15
+ import "../../../../redirect-B29UjdUn.mjs";
16
16
  import "../../../../request-cache-DzLYKm_x.mjs";
17
17
  import "../../../../byline-registry-gnKscbQX.mjs";
18
18
  import "../../../../field-defs-cache-HIgBbqZZ.mjs";
@@ -34,10 +34,10 @@ import "../../../../block-values-C_VIPr5t.mjs";
34
34
  import "../../../../media-usage-work-C2OZLCAd.mjs";
35
35
  import { n as repairContentMediaUsageCollection } from "../../../../content-repair-Q8IUrpLL.mjs";
36
36
  import "../../../../errors-BF0_LFhW.mjs";
37
- import "../../../../settings-CgjRWGW9.mjs";
37
+ import "../../../../settings-B4vDl1fK.mjs";
38
38
  import "../../../../ssrf-CJUnJymJ.mjs";
39
39
  import { n as apiSuccess, r as handleError, t as apiError } from "../../../../error-CfvOHP0M.mjs";
40
- import { t as applySeed } from "../../../../apply-CoT603H3.mjs";
40
+ import { t as applySeed } from "../../../../apply-npY1TAhG.mjs";
41
41
  import "../../../../ssrf-DpBH7aOt.mjs";
42
42
  import { n as validateSeed } from "../../../../validate-CHosPEhs.mjs";
43
43
  import { t as loadSeed } from "../../../../load-XgJiE6_3.mjs";
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.mts","names":[],"sources":["../../../../../src/astro/routes/api/setup/index.ts"],"mappings":";;;cAQa,SAAA;AAAA,cAYA,IAAA,EAAM,QAAA"}
1
+ {"version":3,"file":"index.d.mts","names":[],"sources":["../../../../../src/astro/routes/api/setup/index.ts"],"mappings":";;;cAQa,SAAA;AAAA,cAuBA,IAAA,EAAM,QAAA"}
@@ -9,10 +9,10 @@ import "../../../../content-DFaIEDj9.mjs";
9
9
  import "../../../../object-cache-CqWNY5uP.mjs";
10
10
  import "../../../../slugify-T5GHH42D.mjs";
11
11
  import "../../../../types-BkUg2yHx.mjs";
12
- import "../../../../media-Qp5S3eH3.mjs";
12
+ import "../../../../media-CPXTbb1R.mjs";
13
13
  import "../../../../taxonomy-C3Fu1YeH.mjs";
14
14
  import "../../../../resolve-2WbQsCvT.mjs";
15
- import "../../../../redirect-iJf5fltD.mjs";
15
+ import "../../../../redirect-B29UjdUn.mjs";
16
16
  import "../../../../request-cache-DzLYKm_x.mjs";
17
17
  import "../../../../byline-registry-gnKscbQX.mjs";
18
18
  import "../../../../field-defs-cache-HIgBbqZZ.mjs";
@@ -34,7 +34,7 @@ import "../../../../block-values-C_VIPr5t.mjs";
34
34
  import "../../../../settings-DYidIB26.mjs";
35
35
  import "../../../../site-settings-DOgRUoFX.mjs";
36
36
  import "../../../../errors-BF0_LFhW.mjs";
37
- import "../../../../settings-CgjRWGW9.mjs";
37
+ import "../../../../settings-B4vDl1fK.mjs";
38
38
  import "../../../../ssrf-CJUnJymJ.mjs";
39
39
  import { n as apiSuccess, r as handleError, t as apiError } from "../../../../error-CfvOHP0M.mjs";
40
40
  import { n as parseBody, t as isParseError } from "../../../../parse-DY6OD1j_.mjs";
@@ -46,15 +46,28 @@ import { x as setupBody } from "../../../../relations-CK9CYUyr.mjs";
46
46
  import "../../../../menus-BM7BPLOb.mjs";
47
47
  import "../../../../status-DZKIG4a9.mjs";
48
48
  import "../../../../api/schemas/index.mjs";
49
- import { t as applySeed } from "../../../../apply-CoT603H3.mjs";
49
+ import { n as applySeedWithinBudget } from "../../../../apply-npY1TAhG.mjs";
50
50
  import "../../../../ssrf-DpBH7aOt.mjs";
51
51
  import { n as validateSeed } from "../../../../validate-CHosPEhs.mjs";
52
52
  import { t as loadSeed } from "../../../../load-XgJiE6_3.mjs";
53
- import { r as getPublicOrigin } from "../../../../public-url-Bn7U0D7-.mjs";
53
+ import { t as getConfiguredOrigin } from "../../../../public-url-Bn7U0D7-.mjs";
54
54
  import { t as getAuthMode } from "../../../../mode-CCuKXUci.mjs";
55
55
 
56
56
  //#region src/astro/routes/api/setup/index.ts
57
57
  const prerender = false;
58
+ /**
59
+ * What one setup request may spend on the seed before the rest continues in
60
+ * the next request. Cloudflare Workers Free allows 1,000 calls to D1, KV and R2
61
+ * and 50 external fetches per request. A `$media` download takes at least three
62
+ * fetches (two DNS-over-HTTPS lookups in `ssrfSafeFetch`, then the file) and
63
+ * three more per redirect. The margin covers a redirect per download, the entry
64
+ * that crosses the budget with its images, the phases after content and the
65
+ * object-cache writes at the end.
66
+ */
67
+ const SEED_BUDGET_PER_REQUEST = {
68
+ queries: 500,
69
+ mediaDownloads: 5
70
+ };
58
71
  const POST = async ({ request, url, locals }) => {
59
72
  const { emdash } = locals;
60
73
  if (!emdash?.db) return apiError("NOT_CONFIGURED", "EmDash is not initialized", 500);
@@ -63,6 +76,10 @@ const POST = async ({ request, url, locals }) => {
63
76
  const setupComplete = await new OptionsRepository(emdash.db).get("emdash:setup_complete");
64
77
  if (setupComplete === true || setupComplete === "true") return apiError("ALREADY_CONFIGURED", "Setup has already been completed", 409);
65
78
  } catch {}
79
+ const configuredSiteUrl = getConfiguredOrigin(emdash.config);
80
+ const loopbackHost = url.hostname === "localhost" || url.hostname === "127.0.0.1" || url.hostname === "[::1]";
81
+ const siteUrl = configuredSiteUrl ?? (import.meta.env.DEV && loopbackHost ? url.origin : void 0);
82
+ if (!siteUrl) return apiError("SITE_URL_REQUIRED", "Set siteUrl or EMDASH_SITE_URL before running production setup", 500);
66
83
  const body = await parseBody(request, setupBody);
67
84
  if (isParseError(body)) return body;
68
85
  const seed = await loadSeed();
@@ -73,22 +90,22 @@ const POST = async ({ request, url, locals }) => {
73
90
  };
74
91
  const validation = validateSeed(seed);
75
92
  if (!validation.valid) return apiError("INVALID_SEED", `Invalid seed file: ${validation.errors.join(", ")}`, 400);
76
- let result;
93
+ let seeded;
77
94
  try {
78
- result = await applySeed(emdash.db, seed, {
95
+ seeded = await applySeedWithinBudget(emdash.db, seed, {
79
96
  includeContent: body.includeContent,
80
97
  onConflict: "skip",
81
98
  storage: emdash.storage ?? void 0
82
- });
99
+ }, SEED_BUDGET_PER_REQUEST);
83
100
  } catch (error) {
84
101
  return handleError(error, "Failed to apply seed", "SEED_ERROR");
85
102
  }
103
+ const { result, complete: seedComplete, progress: seedProgress } = seeded;
86
104
  const useExternalAuth = getAuthMode(emdash.config).type === "external";
87
105
  try {
88
106
  const options = new OptionsRepository(emdash.db);
89
- const siteUrl = getPublicOrigin(url, emdash.config);
90
107
  await options.setIfAbsent("emdash:site_url", siteUrl);
91
- if (useExternalAuth) {
108
+ if (seedComplete) if (useExternalAuth) {
92
109
  await options.set("emdash:setup_complete", true);
93
110
  await options.set("emdash:site_title", body.title);
94
111
  if (body.tagline) await options.set("emdash:site_tagline", body.tagline);
@@ -100,9 +117,17 @@ const POST = async ({ request, url, locals }) => {
100
117
  } catch (error) {
101
118
  console.error("Failed to save setup state:", error);
102
119
  }
120
+ if (!seedComplete) return apiSuccess({
121
+ success: true,
122
+ setupComplete: false,
123
+ seedComplete: false,
124
+ seedProgress,
125
+ result
126
+ });
103
127
  return apiSuccess({
104
128
  success: true,
105
129
  setupComplete: useExternalAuth,
130
+ seedComplete: true,
106
131
  result
107
132
  });
108
133
  } catch (error) {
@@ -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 { 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// Load seed file (user seed or built-in default)\n\t\tconst seed = await loadSeed();\n\n\t\t// 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// 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// 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// 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;AAYzB,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;EAG/B,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 { getConfiguredOrigin } from \"#api/public-url.js\";\nimport { setupBody } from \"#api/schemas.js\";\nimport { getAuthMode } from \"#auth/mode.js\";\nimport { OptionsRepository } from \"#db/repositories/options.js\";\nimport { applySeedWithinBudget, type SeedApplyBudget } from \"#seed/apply.js\";\nimport { loadSeed } from \"#seed/load.js\";\nimport { validateSeed } from \"#seed/validate.js\";\n\n/**\n * What one setup request may spend on the seed before the rest continues in\n * the next request. Cloudflare Workers Free allows 1,000 calls to D1, KV and R2\n * and 50 external fetches per request. A `$media` download takes at least three\n * fetches (two DNS-over-HTTPS lookups in `ssrfSafeFetch`, then the file) and\n * three more per redirect. The margin covers a redirect per download, the entry\n * that crosses the budget with its images, the phases after content and the\n * object-cache writes at the end.\n */\nconst SEED_BUDGET_PER_REQUEST: SeedApplyBudget = { queries: 500, mediaDownloads: 5 };\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\tconst configuredSiteUrl = getConfiguredOrigin(emdash.config);\n\t\tconst loopbackHost =\n\t\t\turl.hostname === \"localhost\" || url.hostname === \"127.0.0.1\" || url.hostname === \"[::1]\";\n\t\tconst siteUrl =\n\t\t\tconfiguredSiteUrl ?? (import.meta.env.DEV && loopbackHost ? url.origin : undefined);\n\t\tif (!siteUrl) {\n\t\t\treturn apiError(\n\t\t\t\t\"SITE_URL_REQUIRED\",\n\t\t\t\t\"Set siteUrl or EMDASH_SITE_URL before running production setup\",\n\t\t\t\t500,\n\t\t\t);\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// Load seed file (user seed or built-in default)\n\t\tconst seed = await loadSeed();\n\n\t\t// 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// 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 seeded;\n\t\ttry {\n\t\t\tseeded = await applySeedWithinBudget(\n\t\t\t\temdash.db,\n\t\t\t\tseed,\n\t\t\t\t{\n\t\t\t\t\tincludeContent: body.includeContent,\n\t\t\t\t\tonConflict: \"skip\",\n\t\t\t\t\tstorage: emdash.storage ?? undefined,\n\t\t\t\t},\n\t\t\t\tSEED_BUDGET_PER_REQUEST,\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\t\tconst { result, complete: seedComplete, progress: seedProgress } = seeded;\n\n\t\t// 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\tawait options.setIfAbsent(\"emdash:site_url\", siteUrl);\n\n\t\t\tif (seedComplete) {\n\t\t\t\tif (useExternalAuth) {\n\t\t\t\t\t// External auth mode: mark setup complete now\n\t\t\t\t\t// First user to log in via external provider will become admin\n\t\t\t\t\tawait options.set(\"emdash:setup_complete\", true);\n\t\t\t\t\tawait options.set(\"emdash:site_title\", body.title);\n\t\t\t\t\tif (body.tagline) {\n\t\t\t\t\t\tawait options.set(\"emdash:site_tagline\", body.tagline);\n\t\t\t\t\t}\n\t\t\t\t} else {\n\t\t\t\t\t// Passkey/provider mode: store state for next step (admin creation)\n\t\t\t\t\tawait options.set(\"emdash:setup_state\", {\n\t\t\t\t\t\tstep: \"site_complete\",\n\t\t\t\t\t\ttitle: body.title,\n\t\t\t\t\t\ttagline: body.tagline,\n\t\t\t\t\t});\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\tif (!seedComplete) {\n\t\t\t// The wizard posts again; items already created are skipped.\n\t\t\treturn apiSuccess({\n\t\t\t\tsuccess: true,\n\t\t\t\tsetupComplete: false,\n\t\t\t\tseedComplete: false,\n\t\t\t\tseedProgress,\n\t\t\t\tresult,\n\t\t\t});\n\t\t}\n\n\t\t// 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\tseedComplete: true,\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;;;;;;;;;;AAqBzB,MAAM,0BAA2C;CAAE,SAAS;CAAK,gBAAgB;CAAG;AAEpF,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;EAIR,MAAM,oBAAoB,oBAAoB,OAAO,OAAO;EAC5D,MAAM,eACL,IAAI,aAAa,eAAe,IAAI,aAAa,eAAe,IAAI,aAAa;EAClF,MAAM,UACL,sBAAsB,OAAO,KAAK,IAAI,OAAO,eAAe,IAAI,SAAS;AAC1E,MAAI,CAAC,QACJ,QAAO,SACN,qBACA,kEACA,IACA;EAIF,MAAM,OAAO,MAAM,UAAU,SAAS,UAAU;AAChD,MAAI,aAAa,KAAK,CAAE,QAAO;EAG/B,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,sBACd,OAAO,IACP,MACA;IACC,gBAAgB,KAAK;IACrB,YAAY;IACZ,SAAS,OAAO,WAAW;IAC3B,EACD,wBACA;WACO,OAAO;AACf,UAAO,YAAY,OAAO,wBAAwB,aAAa;;EAEhE,MAAM,EAAE,QAAQ,UAAU,cAAc,UAAU,iBAAiB;EAMnE,MAAM,kBADW,YAAY,OAAO,OAAO,CACV,SAAS;AAE1C,MAAI;GACH,MAAM,UAAU,IAAI,kBAAkB,OAAO,GAAG;AAOhD,SAAM,QAAQ,YAAY,mBAAmB,QAAQ;AAErD,OAAI,aACH,KAAI,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;WAGI,OAAO;AACf,WAAQ,MAAM,+BAA+B,MAAM;;AAIpD,MAAI,CAAC,aAEJ,QAAO,WAAW;GACjB,SAAS;GACT,eAAe;GACf,cAAc;GACd;GACA;GACA,CAAC;AAIH,SAAO,WAAW;GACjB,SAAS;GAET,eAAe;GACf,cAAc;GACd;GACA,CAAC;UACM,OAAO;AACf,SAAO,YAAY,OAAO,gBAAgB,cAAc"}
@@ -8,7 +8,7 @@ import "../../../errors-DgE1zJGG.mjs";
8
8
  import "../../../errors-BF0_LFhW.mjs";
9
9
  import { n as apiSuccess, r as handleError, t as apiError } from "../../../error-CfvOHP0M.mjs";
10
10
  import { r as getPublicOrigin } from "../../../public-url-Bn7U0D7-.mjs";
11
- import { n as parsePreviewSignatureHeader, r as verifyPreviewSignature, t as generateSnapshot } from "../../../snapshot-CugwUqKQ.mjs";
11
+ import { n as parsePreviewSignatureHeader, r as verifyPreviewSignature, t as generateSnapshot } from "../../../snapshot-PawoX-WG.mjs";
12
12
  import { t as resolveSessionUser } from "../../../session-user-BhaVp8w0.mjs";
13
13
  import { i as requirePerm } from "../../../authorize-seCifOMJ.mjs";
14
14
 
@@ -53,7 +53,7 @@ const GET = async ({ request, locals, url, session }) => {
53
53
  if (schemaDenied) return schemaDenied;
54
54
  }
55
55
  try {
56
- const includeDrafts = url.searchParams.get("drafts") === "true";
56
+ const includeDrafts = !authorized && url.searchParams.get("drafts") === "true";
57
57
  return apiSuccess(await generateSnapshot(emdash.db, {
58
58
  includeDrafts,
59
59
  origin: getPublicOrigin(url, emdash.config)
@@ -1 +1 @@
1
- {"version":3,"file":"snapshot.mjs","names":[],"sources":["../../../../src/astro/routes/api/snapshot.ts"],"sourcesContent":["/**\n * Snapshot endpoint — exports a portable database snapshot for preview mode.\n *\n * Security:\n * - Authenticated users: requires content:read + schema:read permissions\n * - Preview services: requires valid X-Preview-Signature header (HMAC-SHA256)\n * - Excludes auth/user/session/token tables\n */\n\nimport type { User } from \"@emdash-cms/auth\";\nimport type { APIRoute } from \"astro\";\n\nimport { requirePerm } from \"#api/authorize.js\";\nimport { apiError, apiSuccess, handleError } from \"#api/error.js\";\nimport {\n\tgenerateSnapshot,\n\tparsePreviewSignatureHeader,\n\tverifyPreviewSignature,\n} from \"#api/handlers/snapshot.js\";\nimport { getPublicOrigin } from \"#api/public-url.js\";\nimport { resolveSecretsCached } from \"#config/secrets.js\";\n\nimport { resolveSessionUser } from \"../../session-user.js\";\n\nexport const prerender = false;\n\nexport const GET: APIRoute = async ({ request, locals, url, session }) => {\n\tconst { emdash } = locals;\n\t// This route is in PUBLIC_API_EXACT (for preview-signature callers with no session),\n\t// so auth middleware skips user resolution. Manually resolve the session user here\n\t// to support session-authenticated admin users alongside preview-signature auth.\n\tlet user: User | undefined = (locals as { user?: User }).user;\n\tif (!user && session && emdash?.db) {\n\t\ttry {\n\t\t\tconst { createKyselyAdapter } = await import(\"@emdash-cms/auth/adapters/kysely\");\n\t\t\tconst sessionUser = await resolveSessionUser(session);\n\t\t\tif (sessionUser?.id) {\n\t\t\t\tconst adapter = createKyselyAdapter(emdash.db);\n\t\t\t\tconst resolved = await adapter.getUserById(sessionUser.id);\n\t\t\t\tif (resolved && !resolved.disabled) {\n\t\t\t\t\tuser = resolved;\n\t\t\t\t}\n\t\t\t}\n\t\t} catch {\n\t\t\t// Session resolution failed, continue to preview-signature check\n\t\t}\n\t}\n\n\tif (!emdash?.db) {\n\t\treturn apiError(\"NOT_CONFIGURED\", \"EmDash is not initialized\", 500);\n\t}\n\n\t// Check for preview signature auth (used by DO preview services)\n\tconst previewSig = request.headers.get(\"X-Preview-Signature\");\n\tlet authorized = false;\n\n\tif (previewSig) {\n\t\t// Resolves env override or DB-stored value. Always non-empty after\n\t\t// resolution, so the signature path is never silently disabled.\n\t\t// Note: a signing process without access to this database (e.g. a\n\t\t// remote preview Worker) must set the same `EMDASH_PREVIEW_SECRET`\n\t\t// env var on both sides.\n\t\tconst { previewSecret: secret, previewSecretSource } = await resolveSecretsCached(emdash.db);\n\t\tconst parsed = parsePreviewSignatureHeader(previewSig);\n\t\tif (!parsed) {\n\t\t\tconsole.warn(\"[snapshot] Failed to parse X-Preview-Signature header\");\n\t\t} else {\n\t\t\tauthorized = await verifyPreviewSignature(parsed.source, parsed.exp, parsed.sig, secret);\n\t\t\tif (!authorized) {\n\t\t\t\tconst fields: Record<string, unknown> = {\n\t\t\t\t\tsource: parsed.source,\n\t\t\t\t\texp: parsed.exp,\n\t\t\t\t\texpired: parsed.exp < Date.now() / 1000,\n\t\t\t\t\tsecretSource: previewSecretSource,\n\t\t\t\t};\n\t\t\t\tif (previewSecretSource === \"db\") {\n\t\t\t\t\tfields.hint =\n\t\t\t\t\t\t\"Set EMDASH_PREVIEW_SECRET in both this process and the signing process to share secrets across deployments\";\n\t\t\t\t}\n\t\t\t\tconsole.warn(\"[snapshot] Preview signature verification failed\", fields);\n\t\t\t}\n\t\t}\n\t}\n\n\tif (!authorized) {\n\t\t// Fall back to standard user auth\n\t\tconst contentDenied = requirePerm(user, \"content:read\");\n\t\tif (contentDenied) return contentDenied;\n\t\tconst schemaDenied = requirePerm(user, \"schema:read\");\n\t\tif (schemaDenied) return schemaDenied;\n\t}\n\n\ttry {\n\t\tconst includeDrafts = url.searchParams.get(\"drafts\") === \"true\";\n\t\tconst snapshot = await generateSnapshot(emdash.db, {\n\t\t\tincludeDrafts,\n\t\t\torigin: getPublicOrigin(url, emdash.config),\n\t\t});\n\n\t\treturn apiSuccess(snapshot);\n\t} catch (error) {\n\t\treturn handleError(error, \"Failed to generate snapshot\", \"SNAPSHOT_ERROR\");\n\t}\n};\n"],"mappings":";;;;;;;;;;;;;;;AAwBA,MAAa,YAAY;AAEzB,MAAa,MAAgB,OAAO,EAAE,SAAS,QAAQ,KAAK,cAAc;CACzE,MAAM,EAAE,WAAW;CAInB,IAAI,OAA0B,OAA2B;AACzD,KAAI,CAAC,QAAQ,WAAW,QAAQ,GAC/B,KAAI;EACH,MAAM,EAAE,wBAAwB,MAAM,OAAO;EAC7C,MAAM,cAAc,MAAM,mBAAmB,QAAQ;AACrD,MAAI,aAAa,IAAI;GAEpB,MAAM,WAAW,MADD,oBAAoB,OAAO,GAAG,CACf,YAAY,YAAY,GAAG;AAC1D,OAAI,YAAY,CAAC,SAAS,SACzB,QAAO;;SAGF;AAKT,KAAI,CAAC,QAAQ,GACZ,QAAO,SAAS,kBAAkB,6BAA6B,IAAI;CAIpE,MAAM,aAAa,QAAQ,QAAQ,IAAI,sBAAsB;CAC7D,IAAI,aAAa;AAEjB,KAAI,YAAY;EAMf,MAAM,EAAE,eAAe,QAAQ,wBAAwB,MAAM,qBAAqB,OAAO,GAAG;EAC5F,MAAM,SAAS,4BAA4B,WAAW;AACtD,MAAI,CAAC,OACJ,SAAQ,KAAK,wDAAwD;OAC/D;AACN,gBAAa,MAAM,uBAAuB,OAAO,QAAQ,OAAO,KAAK,OAAO,KAAK,OAAO;AACxF,OAAI,CAAC,YAAY;IAChB,MAAM,SAAkC;KACvC,QAAQ,OAAO;KACf,KAAK,OAAO;KACZ,SAAS,OAAO,MAAM,KAAK,KAAK,GAAG;KACnC,cAAc;KACd;AACD,QAAI,wBAAwB,KAC3B,QAAO,OACN;AAEF,YAAQ,KAAK,oDAAoD,OAAO;;;;AAK3E,KAAI,CAAC,YAAY;EAEhB,MAAM,gBAAgB,YAAY,MAAM,eAAe;AACvD,MAAI,cAAe,QAAO;EAC1B,MAAM,eAAe,YAAY,MAAM,cAAc;AACrD,MAAI,aAAc,QAAO;;AAG1B,KAAI;EACH,MAAM,gBAAgB,IAAI,aAAa,IAAI,SAAS,KAAK;AAMzD,SAAO,WALU,MAAM,iBAAiB,OAAO,IAAI;GAClD;GACA,QAAQ,gBAAgB,KAAK,OAAO,OAAO;GAC3C,CAAC,CAEyB;UACnB,OAAO;AACf,SAAO,YAAY,OAAO,+BAA+B,iBAAiB"}
1
+ {"version":3,"file":"snapshot.mjs","names":[],"sources":["../../../../src/astro/routes/api/snapshot.ts"],"sourcesContent":["/**\n * Snapshot endpoint — exports a portable database snapshot for preview mode.\n *\n * Security:\n * - Authenticated users: requires content:read + schema:read permissions\n * - Preview services: requires valid X-Preview-Signature header (HMAC-SHA256)\n * - Excludes auth/user/session/token tables\n */\n\nimport type { User } from \"@emdash-cms/auth\";\nimport type { APIRoute } from \"astro\";\n\nimport { requirePerm } from \"#api/authorize.js\";\nimport { apiError, apiSuccess, handleError } from \"#api/error.js\";\nimport {\n\tgenerateSnapshot,\n\tparsePreviewSignatureHeader,\n\tverifyPreviewSignature,\n} from \"#api/handlers/snapshot.js\";\nimport { getPublicOrigin } from \"#api/public-url.js\";\nimport { resolveSecretsCached } from \"#config/secrets.js\";\n\nimport { resolveSessionUser } from \"../../session-user.js\";\n\nexport const prerender = false;\n\nexport const GET: APIRoute = async ({ request, locals, url, session }) => {\n\tconst { emdash } = locals;\n\t// This route is in PUBLIC_API_EXACT (for preview-signature callers with no session),\n\t// so auth middleware skips user resolution. Manually resolve the session user here\n\t// to support session-authenticated admin users alongside preview-signature auth.\n\tlet user: User | undefined = (locals as { user?: User }).user;\n\tif (!user && session && emdash?.db) {\n\t\ttry {\n\t\t\tconst { createKyselyAdapter } = await import(\"@emdash-cms/auth/adapters/kysely\");\n\t\t\tconst sessionUser = await resolveSessionUser(session);\n\t\t\tif (sessionUser?.id) {\n\t\t\t\tconst adapter = createKyselyAdapter(emdash.db);\n\t\t\t\tconst resolved = await adapter.getUserById(sessionUser.id);\n\t\t\t\tif (resolved && !resolved.disabled) {\n\t\t\t\t\tuser = resolved;\n\t\t\t\t}\n\t\t\t}\n\t\t} catch {\n\t\t\t// Session resolution failed, continue to preview-signature check\n\t\t}\n\t}\n\n\tif (!emdash?.db) {\n\t\treturn apiError(\"NOT_CONFIGURED\", \"EmDash is not initialized\", 500);\n\t}\n\n\t// Check for preview signature auth (used by DO preview services)\n\tconst previewSig = request.headers.get(\"X-Preview-Signature\");\n\tlet authorized = false;\n\n\tif (previewSig) {\n\t\t// Resolves env override or DB-stored value. Always non-empty after\n\t\t// resolution, so the signature path is never silently disabled.\n\t\t// Note: a signing process without access to this database (e.g. a\n\t\t// remote preview Worker) must set the same `EMDASH_PREVIEW_SECRET`\n\t\t// env var on both sides.\n\t\tconst { previewSecret: secret, previewSecretSource } = await resolveSecretsCached(emdash.db);\n\t\tconst parsed = parsePreviewSignatureHeader(previewSig);\n\t\tif (!parsed) {\n\t\t\tconsole.warn(\"[snapshot] Failed to parse X-Preview-Signature header\");\n\t\t} else {\n\t\t\tauthorized = await verifyPreviewSignature(parsed.source, parsed.exp, parsed.sig, secret);\n\t\t\tif (!authorized) {\n\t\t\t\tconst fields: Record<string, unknown> = {\n\t\t\t\t\tsource: parsed.source,\n\t\t\t\t\texp: parsed.exp,\n\t\t\t\t\texpired: parsed.exp < Date.now() / 1000,\n\t\t\t\t\tsecretSource: previewSecretSource,\n\t\t\t\t};\n\t\t\t\tif (previewSecretSource === \"db\") {\n\t\t\t\t\tfields.hint =\n\t\t\t\t\t\t\"Set EMDASH_PREVIEW_SECRET in both this process and the signing process to share secrets across deployments\";\n\t\t\t\t}\n\t\t\t\tconsole.warn(\"[snapshot] Preview signature verification failed\", fields);\n\t\t\t}\n\t\t}\n\t}\n\n\tif (!authorized) {\n\t\t// Fall back to standard user auth\n\t\tconst contentDenied = requirePerm(user, \"content:read\");\n\t\tif (contentDenied) return contentDenied;\n\t\tconst schemaDenied = requirePerm(user, \"schema:read\");\n\t\tif (schemaDenied) return schemaDenied;\n\t}\n\n\ttry {\n\t\t// A preview signature covers published content only.\n\t\tconst includeDrafts = !authorized && url.searchParams.get(\"drafts\") === \"true\";\n\t\tconst snapshot = await generateSnapshot(emdash.db, {\n\t\t\tincludeDrafts,\n\t\t\torigin: getPublicOrigin(url, emdash.config),\n\t\t});\n\n\t\treturn apiSuccess(snapshot);\n\t} catch (error) {\n\t\treturn handleError(error, \"Failed to generate snapshot\", \"SNAPSHOT_ERROR\");\n\t}\n};\n"],"mappings":";;;;;;;;;;;;;;;AAwBA,MAAa,YAAY;AAEzB,MAAa,MAAgB,OAAO,EAAE,SAAS,QAAQ,KAAK,cAAc;CACzE,MAAM,EAAE,WAAW;CAInB,IAAI,OAA0B,OAA2B;AACzD,KAAI,CAAC,QAAQ,WAAW,QAAQ,GAC/B,KAAI;EACH,MAAM,EAAE,wBAAwB,MAAM,OAAO;EAC7C,MAAM,cAAc,MAAM,mBAAmB,QAAQ;AACrD,MAAI,aAAa,IAAI;GAEpB,MAAM,WAAW,MADD,oBAAoB,OAAO,GAAG,CACf,YAAY,YAAY,GAAG;AAC1D,OAAI,YAAY,CAAC,SAAS,SACzB,QAAO;;SAGF;AAKT,KAAI,CAAC,QAAQ,GACZ,QAAO,SAAS,kBAAkB,6BAA6B,IAAI;CAIpE,MAAM,aAAa,QAAQ,QAAQ,IAAI,sBAAsB;CAC7D,IAAI,aAAa;AAEjB,KAAI,YAAY;EAMf,MAAM,EAAE,eAAe,QAAQ,wBAAwB,MAAM,qBAAqB,OAAO,GAAG;EAC5F,MAAM,SAAS,4BAA4B,WAAW;AACtD,MAAI,CAAC,OACJ,SAAQ,KAAK,wDAAwD;OAC/D;AACN,gBAAa,MAAM,uBAAuB,OAAO,QAAQ,OAAO,KAAK,OAAO,KAAK,OAAO;AACxF,OAAI,CAAC,YAAY;IAChB,MAAM,SAAkC;KACvC,QAAQ,OAAO;KACf,KAAK,OAAO;KACZ,SAAS,OAAO,MAAM,KAAK,KAAK,GAAG;KACnC,cAAc;KACd;AACD,QAAI,wBAAwB,KAC3B,QAAO,OACN;AAEF,YAAQ,KAAK,oDAAoD,OAAO;;;;AAK3E,KAAI,CAAC,YAAY;EAEhB,MAAM,gBAAgB,YAAY,MAAM,eAAe;AACvD,MAAI,cAAe,QAAO;EAC1B,MAAM,eAAe,YAAY,MAAM,cAAc;AACrD,MAAI,aAAc,QAAO;;AAG1B,KAAI;EAEH,MAAM,gBAAgB,CAAC,cAAc,IAAI,aAAa,IAAI,SAAS,KAAK;AAMxE,SAAO,WALU,MAAM,iBAAiB,OAAO,IAAI;GAClD;GACA,QAAQ,gBAAgB,KAAK,OAAO,OAAO;GAC3C,CAAC,CAEyB;UACnB,OAAO;AACf,SAAO,YAAY,OAAO,+BAA+B,iBAAiB"}
@@ -6,10 +6,10 @@ import "../../base64-DvnNgP7e.mjs";
6
6
  import "../../secrets-CIi0nFiR.mjs";
7
7
  import "../../object-cache-CqWNY5uP.mjs";
8
8
  import "../../types-BkUg2yHx.mjs";
9
- import "../../media-Qp5S3eH3.mjs";
9
+ import "../../media-CPXTbb1R.mjs";
10
10
  import "../../request-cache-DzLYKm_x.mjs";
11
11
  import "../../loader-BzqeR1ZN.mjs";
12
- import { o as getSiteSettingsWithDb } from "../../settings-CgjRWGW9.mjs";
12
+ import { o as getSiteSettingsWithDb } from "../../settings-B4vDl1fK.mjs";
13
13
  import { r as getPublicOrigin } from "../../public-url-Bn7U0D7-.mjs";
14
14
 
15
15
  //#region src/astro/routes/robots.txt.ts
@@ -6,12 +6,12 @@ import "../../base64-DvnNgP7e.mjs";
6
6
  import "../../secrets-CIi0nFiR.mjs";
7
7
  import "../../object-cache-CqWNY5uP.mjs";
8
8
  import "../../types-BkUg2yHx.mjs";
9
- import "../../media-Qp5S3eH3.mjs";
9
+ import "../../media-CPXTbb1R.mjs";
10
10
  import { a as resolveLocalizedContentRoutePath } from "../../resolve-2WbQsCvT.mjs";
11
11
  import "../../request-cache-DzLYKm_x.mjs";
12
12
  import "../../loader-BzqeR1ZN.mjs";
13
13
  import { t as handleSitemapData } from "../../seo-CZT2oLtT.mjs";
14
- import { o as getSiteSettingsWithDb } from "../../settings-CgjRWGW9.mjs";
14
+ import { o as getSiteSettingsWithDb } from "../../settings-B4vDl1fK.mjs";
15
15
  import { t as buildSeoImageUrl } from "../../media-url-jArBpzIG.mjs";
16
16
  import { r as getPublicOrigin } from "../../public-url-Bn7U0D7-.mjs";
17
17
  import virtualConfig from "virtual:emdash/config";
@@ -6,11 +6,11 @@ import "../../base64-DvnNgP7e.mjs";
6
6
  import "../../secrets-CIi0nFiR.mjs";
7
7
  import "../../object-cache-CqWNY5uP.mjs";
8
8
  import "../../types-BkUg2yHx.mjs";
9
- import "../../media-Qp5S3eH3.mjs";
9
+ import "../../media-CPXTbb1R.mjs";
10
10
  import "../../request-cache-DzLYKm_x.mjs";
11
11
  import "../../loader-BzqeR1ZN.mjs";
12
12
  import { t as handleSitemapData } from "../../seo-CZT2oLtT.mjs";
13
- import { o as getSiteSettingsWithDb } from "../../settings-CgjRWGW9.mjs";
13
+ import { o as getSiteSettingsWithDb } from "../../settings-B4vDl1fK.mjs";
14
14
  import { r as getPublicOrigin } from "../../public-url-Bn7U0D7-.mjs";
15
15
 
16
16
  //#region src/astro/routes/sitemap.xml.ts
@@ -5,11 +5,11 @@ import { d as ContentResponse, u as ContentListResponse } from "../parse-CVgO-Qa
5
5
  import { t as Database } from "../types-B7Lmsh1E.mjs";
6
6
  import { At as PageMetadataContribution, Dt as PageFragmentContribution, Gt as PluginEditorAction, nn as PublicPageContext, pn as ResolvedPlugin, qt as PluginEditorPanel, t as ActorInfo, x as ContentActionOrigin } from "../types-Cr-Kg-3D.mjs";
7
7
  import "../options-SQCHQCPH.mjs";
8
- import "../entry-lock-DVhCt49A.mjs";
8
+ import "../entry-lock-Cf5OoIgN.mjs";
9
9
  import { f as MediaProvider, p as MediaProviderCapabilities } from "../placeholder-MSEd8gty.mjs";
10
- import { Br as MediaListResponse, Vr as MediaResponse, _r as RouteCallerInput, br as EmDashConfig, fr as SandboxedPluginEntry, gr as PluginContentCacheInvalidator, lr as PluginEditorExtensionDispatch, t as ManifestRegistryConfigurationError, ur as ResolvedPluginEditorExtension, vr as RouteMeta } from "../config-5ii2haYu.mjs";
10
+ import { Br as MediaListResponse, Vr as MediaResponse, _r as RouteCallerInput, br as EmDashConfig, fr as SandboxedPluginEntry, gr as PluginContentCacheInvalidator, lr as PluginEditorExtensionDispatch, t as ManifestRegistryConfigurationError, ur as ResolvedPluginEditorExtension, vr as RouteMeta } from "../config-BjEm_3xL.mjs";
11
11
  import "../runner-D5_LzKXI.mjs";
12
- import { K as EmailPipeline, Q as MediaItem, b as SandboxRunner, q as HookPipeline } from "../storage-query-Bdv7A62k.mjs";
12
+ import { K as EmailPipeline, Q as MediaItem, b as SandboxRunner, q as HookPipeline } from "../storage-query-FXJH5pI8.mjs";
13
13
  import "../index-D-hdtLe8.mjs";
14
14
  import { d as Storage } from "../types-DA1Te3Oy.mjs";
15
15
  import "../types-Cd-O03VG.mjs";
@@ -396,6 +396,10 @@ interface EmDashHandlers {
396
396
  authorId?: string;
397
397
  folderId?: string | null;
398
398
  }) => Promise<HandlerResponse>;
399
+ handleMediaRegisterUpload: (input: {
400
+ storageKey: string;
401
+ authorId?: string;
402
+ }) => Promise<HandlerResponse>;
399
403
  handleMediaUpdate: (id: string, input: {
400
404
  alt?: string;
401
405
  caption?: string;