emdash 0.39.1 → 0.40.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 (1649) hide show
  1. package/dist/action-token-DYwe4Pk0.mjs +26 -0
  2. package/dist/action-token-DYwe4Pk0.mjs.map +1 -0
  3. package/dist/activation-LOkDM5WT.mjs +382 -0
  4. package/dist/activation-LOkDM5WT.mjs.map +1 -0
  5. package/dist/adapters-B64LbYcB.d.mts +171 -0
  6. package/dist/adapters-B64LbYcB.d.mts.map +1 -0
  7. package/dist/allowed-origins-CHB8oZNM.mjs +116 -0
  8. package/dist/allowed-origins-CHB8oZNM.mjs.map +1 -0
  9. package/dist/api/route-utils.d.mts +4 -4
  10. package/dist/api/route-utils.mjs +49 -40
  11. package/dist/api/route-utils.mjs.map +1 -1
  12. package/dist/api/schemas/index.d.mts +2 -2
  13. package/dist/api/schemas/index.mjs +11 -7
  14. package/dist/api-cFFZpyS0.mjs +4718 -0
  15. package/dist/api-cFFZpyS0.mjs.map +1 -0
  16. package/dist/api-tokens-CE1ECIg0.mjs +3 -0
  17. package/dist/api-tokens-s4i4aUp_.mjs +166 -0
  18. package/dist/api-tokens-s4i4aUp_.mjs.map +1 -0
  19. package/dist/apply-CoT603H3.mjs +1163 -0
  20. package/dist/apply-CoT603H3.mjs.map +1 -0
  21. package/dist/approvals-CqMfNxak.mjs +460 -0
  22. package/dist/approvals-CqMfNxak.mjs.map +1 -0
  23. package/dist/artifact-fetch-DZMOGZ3-.mjs +818 -0
  24. package/dist/artifact-fetch-DZMOGZ3-.mjs.map +1 -0
  25. package/dist/astro/index.d.mts +14 -14
  26. package/dist/astro/index.mjs +62 -12
  27. package/dist/astro/index.mjs.map +1 -1
  28. package/dist/astro/middleware/auth.d.mts +14 -12
  29. package/dist/astro/middleware/auth.d.mts.map +1 -1
  30. package/dist/astro/middleware/auth.mjs +26 -11
  31. package/dist/astro/middleware/auth.mjs.map +1 -1
  32. package/dist/astro/middleware/media-usage-write-fence.d.mts +9 -1
  33. package/dist/astro/middleware/media-usage-write-fence.d.mts.map +1 -1
  34. package/dist/astro/middleware/media-usage-write-fence.mjs +95 -13
  35. package/dist/astro/middleware/media-usage-write-fence.mjs.map +1 -1
  36. package/dist/astro/middleware/redirect.mjs +8 -8
  37. package/dist/astro/middleware/request-context.d.mts.map +1 -1
  38. package/dist/astro/middleware/request-context.mjs +145 -47
  39. package/dist/astro/middleware/request-context.mjs.map +1 -1
  40. package/dist/astro/middleware/setup.mjs +1 -1
  41. package/dist/astro/middleware.d.mts +12 -12
  42. package/dist/astro/middleware.d.mts.map +1 -1
  43. package/dist/astro/middleware.mjs +129 -123
  44. package/dist/astro/middleware.mjs.map +1 -1
  45. package/dist/astro/routes/api/admin/allowed-domains/_domain_.mjs +14 -8
  46. package/dist/astro/routes/api/admin/allowed-domains/_domain_.mjs.map +1 -1
  47. package/dist/astro/routes/api/admin/allowed-domains/index.mjs +14 -8
  48. package/dist/astro/routes/api/admin/allowed-domains/index.mjs.map +1 -1
  49. package/dist/astro/routes/api/admin/api-tokens/_id_.mjs +5 -3
  50. package/dist/astro/routes/api/admin/api-tokens/_id_.mjs.map +1 -1
  51. package/dist/astro/routes/api/admin/api-tokens/index.mjs +6 -4
  52. package/dist/astro/routes/api/admin/api-tokens/index.mjs.map +1 -1
  53. package/dist/astro/routes/api/admin/byline-fields/_slug_/usage.mjs +6 -4
  54. package/dist/astro/routes/api/admin/byline-fields/_slug_/usage.mjs.map +1 -1
  55. package/dist/astro/routes/api/admin/byline-fields/_slug_.mjs +17 -11
  56. package/dist/astro/routes/api/admin/byline-fields/_slug_.mjs.map +1 -1
  57. package/dist/astro/routes/api/admin/byline-fields/index.mjs +17 -11
  58. package/dist/astro/routes/api/admin/byline-fields/index.mjs.map +1 -1
  59. package/dist/astro/routes/api/admin/byline-fields/reorder.mjs +17 -11
  60. package/dist/astro/routes/api/admin/byline-fields/reorder.mjs.map +1 -1
  61. package/dist/astro/routes/api/admin/bylines/_id_/index.mjs +25 -19
  62. package/dist/astro/routes/api/admin/bylines/_id_/index.mjs.map +1 -1
  63. package/dist/astro/routes/api/admin/bylines/_id_/translations.mjs +25 -19
  64. package/dist/astro/routes/api/admin/bylines/_id_/translations.mjs.map +1 -1
  65. package/dist/astro/routes/api/admin/bylines/index.mjs +25 -19
  66. package/dist/astro/routes/api/admin/bylines/index.mjs.map +1 -1
  67. package/dist/astro/routes/api/admin/comments/_id_/status.mjs +19 -13
  68. package/dist/astro/routes/api/admin/comments/_id_/status.mjs.map +1 -1
  69. package/dist/astro/routes/api/admin/comments/_id_.mjs +7 -5
  70. package/dist/astro/routes/api/admin/comments/_id_.mjs.map +1 -1
  71. package/dist/astro/routes/api/admin/comments/bulk.mjs +18 -12
  72. package/dist/astro/routes/api/admin/comments/bulk.mjs.map +1 -1
  73. package/dist/astro/routes/api/admin/comments/counts.mjs +7 -5
  74. package/dist/astro/routes/api/admin/comments/counts.mjs.map +1 -1
  75. package/dist/astro/routes/api/admin/comments/index.mjs +18 -12
  76. package/dist/astro/routes/api/admin/comments/index.mjs.map +1 -1
  77. package/dist/astro/routes/api/admin/hooks/exclusive/_hookName_.mjs +6 -4
  78. package/dist/astro/routes/api/admin/hooks/exclusive/_hookName_.mjs.map +1 -1
  79. package/dist/astro/routes/api/admin/hooks/exclusive/index.d.mts.map +1 -1
  80. package/dist/astro/routes/api/admin/hooks/exclusive/index.mjs +5 -6
  81. package/dist/astro/routes/api/admin/hooks/exclusive/index.mjs.map +1 -1
  82. package/dist/astro/routes/api/admin/media-usage/activation.mjs +21 -15
  83. package/dist/astro/routes/api/admin/media-usage/activation.mjs.map +1 -1
  84. package/dist/astro/routes/api/admin/media-usage/collection-deletions/index.mjs +23 -17
  85. package/dist/astro/routes/api/admin/media-usage/collection-deletions/index.mjs.map +1 -1
  86. package/dist/astro/routes/api/admin/media-usage/collection-deletions/retry.mjs +23 -17
  87. package/dist/astro/routes/api/admin/media-usage/collection-deletions/retry.mjs.map +1 -1
  88. package/dist/astro/routes/api/admin/media-usage/progress.mjs +26 -15
  89. package/dist/astro/routes/api/admin/media-usage/progress.mjs.map +1 -1
  90. package/dist/astro/routes/api/admin/media-usage/repair.mjs +32 -19
  91. package/dist/astro/routes/api/admin/media-usage/repair.mjs.map +1 -1
  92. package/dist/astro/routes/api/admin/media-usage/work/index.mjs +23 -17
  93. package/dist/astro/routes/api/admin/media-usage/work/index.mjs.map +1 -1
  94. package/dist/astro/routes/api/admin/media-usage/work/retry.mjs +23 -17
  95. package/dist/astro/routes/api/admin/media-usage/work/retry.mjs.map +1 -1
  96. package/dist/astro/routes/api/admin/oauth-clients/_id_.mjs +5 -3
  97. package/dist/astro/routes/api/admin/oauth-clients/_id_.mjs.map +1 -1
  98. package/dist/astro/routes/api/admin/oauth-clients/index.mjs +5 -3
  99. package/dist/astro/routes/api/admin/oauth-clients/index.mjs.map +1 -1
  100. package/dist/astro/routes/api/admin/plugins/_id_/disable.d.mts.map +1 -1
  101. package/dist/astro/routes/api/admin/plugins/_id_/disable.mjs +10 -8
  102. package/dist/astro/routes/api/admin/plugins/_id_/disable.mjs.map +1 -1
  103. package/dist/astro/routes/api/admin/plugins/_id_/enable.d.mts.map +1 -1
  104. package/dist/astro/routes/api/admin/plugins/_id_/enable.mjs +10 -8
  105. package/dist/astro/routes/api/admin/plugins/_id_/enable.mjs.map +1 -1
  106. package/dist/astro/routes/api/admin/plugins/_id_/index.mjs +72 -62
  107. package/dist/astro/routes/api/admin/plugins/_id_/index.mjs.map +1 -1
  108. package/dist/astro/routes/api/admin/plugins/_id_/mcp.mjs +6 -4
  109. package/dist/astro/routes/api/admin/plugins/_id_/mcp.mjs.map +1 -1
  110. package/dist/astro/routes/api/admin/plugins/_id_/settings.mjs +71 -61
  111. package/dist/astro/routes/api/admin/plugins/_id_/settings.mjs.map +1 -1
  112. package/dist/astro/routes/api/admin/plugins/_id_/uninstall.d.mts.map +1 -1
  113. package/dist/astro/routes/api/admin/plugins/_id_/uninstall.mjs +74 -64
  114. package/dist/astro/routes/api/admin/plugins/_id_/uninstall.mjs.map +1 -1
  115. package/dist/astro/routes/api/admin/plugins/_id_/update.d.mts.map +1 -1
  116. package/dist/astro/routes/api/admin/plugins/_id_/update.mjs +84 -74
  117. package/dist/astro/routes/api/admin/plugins/_id_/update.mjs.map +1 -1
  118. package/dist/astro/routes/api/admin/plugins/index.mjs +72 -62
  119. package/dist/astro/routes/api/admin/plugins/index.mjs.map +1 -1
  120. package/dist/astro/routes/api/admin/plugins/marketplace/_id_/icon.mjs +4 -2
  121. package/dist/astro/routes/api/admin/plugins/marketplace/_id_/icon.mjs.map +1 -1
  122. package/dist/astro/routes/api/admin/plugins/marketplace/_id_/index.mjs +71 -61
  123. package/dist/astro/routes/api/admin/plugins/marketplace/_id_/index.mjs.map +1 -1
  124. package/dist/astro/routes/api/admin/plugins/marketplace/_id_/install.d.mts.map +1 -1
  125. package/dist/astro/routes/api/admin/plugins/marketplace/_id_/install.mjs +83 -73
  126. package/dist/astro/routes/api/admin/plugins/marketplace/_id_/install.mjs.map +1 -1
  127. package/dist/astro/routes/api/admin/plugins/marketplace/index.mjs +71 -61
  128. package/dist/astro/routes/api/admin/plugins/marketplace/index.mjs.map +1 -1
  129. package/dist/astro/routes/api/admin/plugins/registry/_id_/uninstall.d.mts.map +1 -1
  130. package/dist/astro/routes/api/admin/plugins/registry/_id_/uninstall.mjs +74 -64
  131. package/dist/astro/routes/api/admin/plugins/registry/_id_/uninstall.mjs.map +1 -1
  132. package/dist/astro/routes/api/admin/plugins/registry/_id_/update.mjs +85 -75
  133. package/dist/astro/routes/api/admin/plugins/registry/_id_/update.mjs.map +1 -1
  134. package/dist/astro/routes/api/admin/plugins/registry/artifact.mjs +8 -6
  135. package/dist/astro/routes/api/admin/plugins/registry/artifact.mjs.map +1 -1
  136. package/dist/astro/routes/api/admin/plugins/registry/install.mjs +76 -66
  137. package/dist/astro/routes/api/admin/plugins/registry/install.mjs.map +1 -1
  138. package/dist/astro/routes/api/admin/plugins/registry/publisher-handle.d.mts +8 -0
  139. package/dist/astro/routes/api/admin/plugins/registry/publisher-handle.d.mts.map +1 -0
  140. package/dist/astro/routes/api/admin/plugins/registry/publisher-handle.mjs +221 -0
  141. package/dist/astro/routes/api/admin/plugins/registry/publisher-handle.mjs.map +1 -0
  142. package/dist/astro/routes/api/admin/plugins/registry/verify.mjs +72 -62
  143. package/dist/astro/routes/api/admin/plugins/registry/verify.mjs.map +1 -1
  144. package/dist/astro/routes/api/admin/plugins/updates.mjs +71 -61
  145. package/dist/astro/routes/api/admin/plugins/updates.mjs.map +1 -1
  146. package/dist/astro/routes/api/admin/scheduled-policy-rejections/_collection_/_id_.mjs +6 -4
  147. package/dist/astro/routes/api/admin/scheduled-policy-rejections/_collection_/_id_.mjs.map +1 -1
  148. package/dist/astro/routes/api/admin/themes/marketplace/_id_/index.mjs +71 -61
  149. package/dist/astro/routes/api/admin/themes/marketplace/_id_/index.mjs.map +1 -1
  150. package/dist/astro/routes/api/admin/themes/marketplace/_id_/thumbnail.mjs +4 -2
  151. package/dist/astro/routes/api/admin/themes/marketplace/_id_/thumbnail.mjs.map +1 -1
  152. package/dist/astro/routes/api/admin/themes/marketplace/index.mjs +71 -61
  153. package/dist/astro/routes/api/admin/themes/marketplace/index.mjs.map +1 -1
  154. package/dist/astro/routes/api/admin/transfer/_...path_.d.mts +12 -0
  155. package/dist/astro/routes/api/admin/transfer/_...path_.d.mts.map +1 -0
  156. package/dist/astro/routes/api/admin/transfer/_...path_.mjs +144 -0
  157. package/dist/astro/routes/api/admin/transfer/_...path_.mjs.map +1 -0
  158. package/dist/astro/routes/api/admin/transfer/approvals/_id_/approve.d.mts +8 -0
  159. package/dist/astro/routes/api/admin/transfer/approvals/_id_/approve.d.mts.map +1 -0
  160. package/dist/astro/routes/api/admin/transfer/approvals/_id_/approve.mjs +68 -0
  161. package/dist/astro/routes/api/admin/transfer/approvals/_id_/approve.mjs.map +1 -0
  162. package/dist/astro/routes/api/admin/transfer/approvals/_id_/deny.d.mts +8 -0
  163. package/dist/astro/routes/api/admin/transfer/approvals/_id_/deny.d.mts.map +1 -0
  164. package/dist/astro/routes/api/admin/transfer/approvals/_id_/deny.mjs +68 -0
  165. package/dist/astro/routes/api/admin/transfer/approvals/_id_/deny.mjs.map +1 -0
  166. package/dist/astro/routes/api/admin/transfer/approvals/index.d.mts +8 -0
  167. package/dist/astro/routes/api/admin/transfer/approvals/index.d.mts.map +1 -0
  168. package/dist/astro/routes/api/admin/transfer/approvals/index.mjs +67 -0
  169. package/dist/astro/routes/api/admin/transfer/approvals/index.mjs.map +1 -0
  170. package/dist/astro/routes/api/admin/transfer/capabilities.d.mts +8 -0
  171. package/dist/astro/routes/api/admin/transfer/capabilities.d.mts.map +1 -0
  172. package/dist/astro/routes/api/admin/transfer/capabilities.mjs +70 -0
  173. package/dist/astro/routes/api/admin/transfer/capabilities.mjs.map +1 -0
  174. package/dist/astro/routes/api/admin/transfer/exports/_id_/advance.d.mts +8 -0
  175. package/dist/astro/routes/api/admin/transfer/exports/_id_/advance.d.mts.map +1 -0
  176. package/dist/astro/routes/api/admin/transfer/exports/_id_/advance.mjs +67 -0
  177. package/dist/astro/routes/api/admin/transfer/exports/_id_/advance.mjs.map +1 -0
  178. package/dist/astro/routes/api/admin/transfer/exports/_id_/archive.d.mts +8 -0
  179. package/dist/astro/routes/api/admin/transfer/exports/_id_/archive.d.mts.map +1 -0
  180. package/dist/astro/routes/api/admin/transfer/exports/_id_/archive.mjs +70 -0
  181. package/dist/astro/routes/api/admin/transfer/exports/_id_/archive.mjs.map +1 -0
  182. package/dist/astro/routes/api/admin/transfer/exports/_id_/files/_...path_.d.mts +8 -0
  183. package/dist/astro/routes/api/admin/transfer/exports/_id_/files/_...path_.d.mts.map +1 -0
  184. package/dist/astro/routes/api/admin/transfer/exports/_id_/files/_...path_.mjs +69 -0
  185. package/dist/astro/routes/api/admin/transfer/exports/_id_/files/_...path_.mjs.map +1 -0
  186. package/dist/astro/routes/api/admin/transfer/exports/_id_/index.d.mts +8 -0
  187. package/dist/astro/routes/api/admin/transfer/exports/_id_/index.d.mts.map +1 -0
  188. package/dist/astro/routes/api/admin/transfer/exports/_id_/index.mjs +66 -0
  189. package/dist/astro/routes/api/admin/transfer/exports/_id_/index.mjs.map +1 -0
  190. package/dist/astro/routes/api/admin/transfer/exports/_id_/manifest.d.mts +8 -0
  191. package/dist/astro/routes/api/admin/transfer/exports/_id_/manifest.d.mts.map +1 -0
  192. package/dist/astro/routes/api/admin/transfer/exports/_id_/manifest.mjs +69 -0
  193. package/dist/astro/routes/api/admin/transfer/exports/_id_/manifest.mjs.map +1 -0
  194. package/dist/astro/routes/api/admin/transfer/exports/index.d.mts +9 -0
  195. package/dist/astro/routes/api/admin/transfer/exports/index.d.mts.map +1 -0
  196. package/dist/astro/routes/api/admin/transfer/exports/index.mjs +91 -0
  197. package/dist/astro/routes/api/admin/transfer/exports/index.mjs.map +1 -0
  198. package/dist/astro/routes/api/admin/transfer/imports/_id_/abandon.d.mts +8 -0
  199. package/dist/astro/routes/api/admin/transfer/imports/_id_/abandon.d.mts.map +1 -0
  200. package/dist/astro/routes/api/admin/transfer/imports/_id_/abandon.mjs +66 -0
  201. package/dist/astro/routes/api/admin/transfer/imports/_id_/abandon.mjs.map +1 -0
  202. package/dist/astro/routes/api/admin/transfer/imports/_id_/advance.d.mts +8 -0
  203. package/dist/astro/routes/api/admin/transfer/imports/_id_/advance.d.mts.map +1 -0
  204. package/dist/astro/routes/api/admin/transfer/imports/_id_/advance.mjs +70 -0
  205. package/dist/astro/routes/api/admin/transfer/imports/_id_/advance.mjs.map +1 -0
  206. package/dist/astro/routes/api/admin/transfer/imports/_id_/analyze.d.mts +8 -0
  207. package/dist/astro/routes/api/admin/transfer/imports/_id_/analyze.d.mts.map +1 -0
  208. package/dist/astro/routes/api/admin/transfer/imports/_id_/analyze.mjs +78 -0
  209. package/dist/astro/routes/api/admin/transfer/imports/_id_/analyze.mjs.map +1 -0
  210. package/dist/astro/routes/api/admin/transfer/imports/_id_/cancel.d.mts +8 -0
  211. package/dist/astro/routes/api/admin/transfer/imports/_id_/cancel.d.mts.map +1 -0
  212. package/dist/astro/routes/api/admin/transfer/imports/_id_/cancel.mjs +66 -0
  213. package/dist/astro/routes/api/admin/transfer/imports/_id_/cancel.mjs.map +1 -0
  214. package/dist/astro/routes/api/admin/transfer/imports/_id_/execute.d.mts +8 -0
  215. package/dist/astro/routes/api/admin/transfer/imports/_id_/execute.d.mts.map +1 -0
  216. package/dist/astro/routes/api/admin/transfer/imports/_id_/execute.mjs +77 -0
  217. package/dist/astro/routes/api/admin/transfer/imports/_id_/execute.mjs.map +1 -0
  218. package/dist/astro/routes/api/admin/transfer/imports/_id_/files/_...path_.d.mts +8 -0
  219. package/dist/astro/routes/api/admin/transfer/imports/_id_/files/_...path_.d.mts.map +1 -0
  220. package/dist/astro/routes/api/admin/transfer/imports/_id_/files/_...path_.mjs +77 -0
  221. package/dist/astro/routes/api/admin/transfer/imports/_id_/files/_...path_.mjs.map +1 -0
  222. package/dist/astro/routes/api/admin/transfer/imports/_id_/index.d.mts +8 -0
  223. package/dist/astro/routes/api/admin/transfer/imports/_id_/index.d.mts.map +1 -0
  224. package/dist/astro/routes/api/admin/transfer/imports/_id_/index.mjs +66 -0
  225. package/dist/astro/routes/api/admin/transfer/imports/_id_/index.mjs.map +1 -0
  226. package/dist/astro/routes/api/admin/transfer/imports/_id_/missing.d.mts +8 -0
  227. package/dist/astro/routes/api/admin/transfer/imports/_id_/missing.d.mts.map +1 -0
  228. package/dist/astro/routes/api/admin/transfer/imports/_id_/missing.mjs +70 -0
  229. package/dist/astro/routes/api/admin/transfer/imports/_id_/missing.mjs.map +1 -0
  230. package/dist/astro/routes/api/admin/transfer/imports/_id_/plan.d.mts +8 -0
  231. package/dist/astro/routes/api/admin/transfer/imports/_id_/plan.d.mts.map +1 -0
  232. package/dist/astro/routes/api/admin/transfer/imports/_id_/plan.mjs +67 -0
  233. package/dist/astro/routes/api/admin/transfer/imports/_id_/plan.mjs.map +1 -0
  234. package/dist/astro/routes/api/admin/transfer/imports/_id_/receipt.d.mts +8 -0
  235. package/dist/astro/routes/api/admin/transfer/imports/_id_/receipt.d.mts.map +1 -0
  236. package/dist/astro/routes/api/admin/transfer/imports/_id_/receipt.mjs +66 -0
  237. package/dist/astro/routes/api/admin/transfer/imports/_id_/receipt.mjs.map +1 -0
  238. package/dist/astro/routes/api/admin/transfer/imports/index.d.mts +9 -0
  239. package/dist/astro/routes/api/admin/transfer/imports/index.d.mts.map +1 -0
  240. package/dist/astro/routes/api/admin/transfer/imports/index.mjs +99 -0
  241. package/dist/astro/routes/api/admin/transfer/imports/index.mjs.map +1 -0
  242. package/dist/astro/routes/api/admin/users/_id_/disable.mjs +3 -1
  243. package/dist/astro/routes/api/admin/users/_id_/disable.mjs.map +1 -1
  244. package/dist/astro/routes/api/admin/users/_id_/enable.mjs +3 -1
  245. package/dist/astro/routes/api/admin/users/_id_/enable.mjs.map +1 -1
  246. package/dist/astro/routes/api/admin/users/_id_/index.mjs +14 -8
  247. package/dist/astro/routes/api/admin/users/_id_/index.mjs.map +1 -1
  248. package/dist/astro/routes/api/admin/users/_id_/send-recovery.d.mts.map +1 -1
  249. package/dist/astro/routes/api/admin/users/_id_/send-recovery.mjs +16 -6
  250. package/dist/astro/routes/api/admin/users/_id_/send-recovery.mjs.map +1 -1
  251. package/dist/astro/routes/api/admin/users/index.mjs +14 -8
  252. package/dist/astro/routes/api/admin/users/index.mjs.map +1 -1
  253. package/dist/astro/routes/api/auth/dev-bypass.mjs +5 -3
  254. package/dist/astro/routes/api/auth/dev-bypass.mjs.map +1 -1
  255. package/dist/astro/routes/api/auth/invite/accept.mjs +3 -1
  256. package/dist/astro/routes/api/auth/invite/accept.mjs.map +1 -1
  257. package/dist/astro/routes/api/auth/invite/complete.mjs +19 -13
  258. package/dist/astro/routes/api/auth/invite/complete.mjs.map +1 -1
  259. package/dist/astro/routes/api/auth/invite/index.d.mts.map +1 -1
  260. package/dist/astro/routes/api/auth/invite/index.mjs +24 -12
  261. package/dist/astro/routes/api/auth/invite/index.mjs.map +1 -1
  262. package/dist/astro/routes/api/auth/invite/register-options.mjs +18 -12
  263. package/dist/astro/routes/api/auth/invite/register-options.mjs.map +1 -1
  264. package/dist/astro/routes/api/auth/logout.mjs +4 -2
  265. package/dist/astro/routes/api/auth/logout.mjs.map +1 -1
  266. package/dist/astro/routes/api/auth/magic-link/send.d.mts.map +1 -1
  267. package/dist/astro/routes/api/auth/magic-link/send.mjs +29 -15
  268. package/dist/astro/routes/api/auth/magic-link/send.mjs.map +1 -1
  269. package/dist/astro/routes/api/auth/magic-link/verify.d.mts +2 -1
  270. package/dist/astro/routes/api/auth/magic-link/verify.d.mts.map +1 -1
  271. package/dist/astro/routes/api/auth/magic-link/verify.mjs +37 -17
  272. package/dist/astro/routes/api/auth/magic-link/verify.mjs.map +1 -1
  273. package/dist/astro/routes/api/auth/me.mjs +15 -9
  274. package/dist/astro/routes/api/auth/me.mjs.map +1 -1
  275. package/dist/astro/routes/api/auth/mode.mjs +4 -2
  276. package/dist/astro/routes/api/auth/mode.mjs.map +1 -1
  277. package/dist/astro/routes/api/auth/oauth/_provider_/callback.mjs +4 -4
  278. package/dist/astro/routes/api/auth/oauth/_provider_.mjs +2 -2
  279. package/dist/astro/routes/api/auth/passkey/_id_.mjs +14 -8
  280. package/dist/astro/routes/api/auth/passkey/_id_.mjs.map +1 -1
  281. package/dist/astro/routes/api/auth/passkey/index.mjs +3 -1
  282. package/dist/astro/routes/api/auth/passkey/index.mjs.map +1 -1
  283. package/dist/astro/routes/api/auth/passkey/options.d.mts.map +1 -1
  284. package/dist/astro/routes/api/auth/passkey/options.mjs +21 -24
  285. package/dist/astro/routes/api/auth/passkey/options.mjs.map +1 -1
  286. package/dist/astro/routes/api/auth/passkey/register/options.mjs +18 -12
  287. package/dist/astro/routes/api/auth/passkey/register/options.mjs.map +1 -1
  288. package/dist/astro/routes/api/auth/passkey/register/verify.mjs +19 -13
  289. package/dist/astro/routes/api/auth/passkey/register/verify.mjs.map +1 -1
  290. package/dist/astro/routes/api/auth/passkey/verify.mjs +19 -13
  291. package/dist/astro/routes/api/auth/passkey/verify.mjs.map +1 -1
  292. package/dist/astro/routes/api/auth/signup/complete.mjs +19 -13
  293. package/dist/astro/routes/api/auth/signup/complete.mjs.map +1 -1
  294. package/dist/astro/routes/api/auth/signup/request.mjs +18 -12
  295. package/dist/astro/routes/api/auth/signup/request.mjs.map +1 -1
  296. package/dist/astro/routes/api/auth/signup/verify.mjs +3 -1
  297. package/dist/astro/routes/api/auth/signup/verify.mjs.map +1 -1
  298. package/dist/astro/routes/api/comments/_collection_/_contentId_/index.mjs +14 -11
  299. package/dist/astro/routes/api/comments/_collection_/_contentId_/index.mjs.map +1 -1
  300. package/dist/astro/routes/api/comments/_collection_/_contentId_/reactions.mjs +21 -15
  301. package/dist/astro/routes/api/comments/_collection_/_contentId_/reactions.mjs.map +1 -1
  302. package/dist/astro/routes/api/content/_collection_/_id_/compare.mjs +4 -2
  303. package/dist/astro/routes/api/content/_collection_/_id_/compare.mjs.map +1 -1
  304. package/dist/astro/routes/api/content/_collection_/_id_/discard-draft.mjs +18 -13
  305. package/dist/astro/routes/api/content/_collection_/_id_/discard-draft.mjs.map +1 -1
  306. package/dist/astro/routes/api/content/_collection_/_id_/duplicate.mjs +4 -3
  307. package/dist/astro/routes/api/content/_collection_/_id_/duplicate.mjs.map +1 -1
  308. package/dist/astro/routes/api/content/_collection_/_id_/lock.mjs +18 -13
  309. package/dist/astro/routes/api/content/_collection_/_id_/lock.mjs.map +1 -1
  310. package/dist/astro/routes/api/content/_collection_/_id_/permanent.mjs +4 -2
  311. package/dist/astro/routes/api/content/_collection_/_id_/permanent.mjs.map +1 -1
  312. package/dist/astro/routes/api/content/_collection_/_id_/plugin-extensions/_pluginId_/_kind_/_extensionId_.mjs +10 -8
  313. package/dist/astro/routes/api/content/_collection_/_id_/plugin-extensions/_pluginId_/_kind_/_extensionId_.mjs.map +1 -1
  314. package/dist/astro/routes/api/content/_collection_/_id_/preview-url.d.mts.map +1 -1
  315. package/dist/astro/routes/api/content/_collection_/_id_/preview-url.mjs +68 -16
  316. package/dist/astro/routes/api/content/_collection_/_id_/preview-url.mjs.map +1 -1
  317. package/dist/astro/routes/api/content/_collection_/_id_/publish.mjs +18 -13
  318. package/dist/astro/routes/api/content/_collection_/_id_/publish.mjs.map +1 -1
  319. package/dist/astro/routes/api/content/_collection_/_id_/references/_relation_/children.mjs +31 -22
  320. package/dist/astro/routes/api/content/_collection_/_id_/references/_relation_/children.mjs.map +1 -1
  321. package/dist/astro/routes/api/content/_collection_/_id_/references/_relation_/parents.mjs +31 -22
  322. package/dist/astro/routes/api/content/_collection_/_id_/references/_relation_/parents.mjs.map +1 -1
  323. package/dist/astro/routes/api/content/_collection_/_id_/restore.mjs +4 -3
  324. package/dist/astro/routes/api/content/_collection_/_id_/restore.mjs.map +1 -1
  325. package/dist/astro/routes/api/content/_collection_/_id_/revisions.mjs +4 -2
  326. package/dist/astro/routes/api/content/_collection_/_id_/revisions.mjs.map +1 -1
  327. package/dist/astro/routes/api/content/_collection_/_id_/schedule.mjs +18 -13
  328. package/dist/astro/routes/api/content/_collection_/_id_/schedule.mjs.map +1 -1
  329. package/dist/astro/routes/api/content/_collection_/_id_/terms/_taxonomy_.d.mts.map +1 -1
  330. package/dist/astro/routes/api/content/_collection_/_id_/terms/_taxonomy_.mjs +38 -19
  331. package/dist/astro/routes/api/content/_collection_/_id_/terms/_taxonomy_.mjs.map +1 -1
  332. package/dist/astro/routes/api/content/_collection_/_id_/translations.mjs +4 -2
  333. package/dist/astro/routes/api/content/_collection_/_id_/translations.mjs.map +1 -1
  334. package/dist/astro/routes/api/content/_collection_/_id_/unpublish.mjs +18 -13
  335. package/dist/astro/routes/api/content/_collection_/_id_/unpublish.mjs.map +1 -1
  336. package/dist/astro/routes/api/content/_collection_/_id_.mjs +18 -13
  337. package/dist/astro/routes/api/content/_collection_/_id_.mjs.map +1 -1
  338. package/dist/astro/routes/api/content/_collection_/authors.mjs +4 -2
  339. package/dist/astro/routes/api/content/_collection_/authors.mjs.map +1 -1
  340. package/dist/astro/routes/api/content/_collection_/index.mjs +15 -10
  341. package/dist/astro/routes/api/content/_collection_/index.mjs.map +1 -1
  342. package/dist/astro/routes/api/content/_collection_/trash.mjs +15 -9
  343. package/dist/astro/routes/api/content/_collection_/trash.mjs.map +1 -1
  344. package/dist/astro/routes/api/dashboard.mjs +11 -9
  345. package/dist/astro/routes/api/dashboard.mjs.map +1 -1
  346. package/dist/astro/routes/api/dev/emails.mjs +4 -2
  347. package/dist/astro/routes/api/dev/emails.mjs.map +1 -1
  348. package/dist/astro/routes/api/health.mjs +5 -3
  349. package/dist/astro/routes/api/health.mjs.map +1 -1
  350. package/dist/astro/routes/api/import/probe.d.mts +3 -3
  351. package/dist/astro/routes/api/import/probe.mjs +27 -21
  352. package/dist/astro/routes/api/import/probe.mjs.map +1 -1
  353. package/dist/astro/routes/api/import/wordpress/analyze.mjs +5 -3
  354. package/dist/astro/routes/api/import/wordpress/analyze.mjs.map +1 -1
  355. package/dist/astro/routes/api/import/wordpress/execute.d.mts +13 -13
  356. package/dist/astro/routes/api/import/wordpress/execute.mjs +18 -16
  357. package/dist/astro/routes/api/import/wordpress/execute.mjs.map +1 -1
  358. package/dist/astro/routes/api/import/wordpress/media.d.mts +12 -12
  359. package/dist/astro/routes/api/import/wordpress/media.mjs +19 -13
  360. package/dist/astro/routes/api/import/wordpress/media.mjs.map +1 -1
  361. package/dist/astro/routes/api/import/wordpress/prepare.mjs +18 -12
  362. package/dist/astro/routes/api/import/wordpress/prepare.mjs.map +1 -1
  363. package/dist/astro/routes/api/import/wordpress/rewrite-url-helpers.d.mts +5 -1
  364. package/dist/astro/routes/api/import/wordpress/rewrite-url-helpers.d.mts.map +1 -1
  365. package/dist/astro/routes/api/import/wordpress/rewrite-url-helpers.mjs +4 -2
  366. package/dist/astro/routes/api/import/wordpress/rewrite-url-helpers.mjs.map +1 -1
  367. package/dist/astro/routes/api/import/wordpress/rewrite-urls.d.mts +13 -13
  368. package/dist/astro/routes/api/import/wordpress/rewrite-urls.mjs +29 -15
  369. package/dist/astro/routes/api/import/wordpress/rewrite-urls.mjs.map +1 -1
  370. package/dist/astro/routes/api/import/wordpress-plugin/analyze.d.mts +1 -1
  371. package/dist/astro/routes/api/import/wordpress-plugin/analyze.mjs +27 -21
  372. package/dist/astro/routes/api/import/wordpress-plugin/analyze.mjs.map +1 -1
  373. package/dist/astro/routes/api/import/wordpress-plugin/execute.d.mts +13 -13
  374. package/dist/astro/routes/api/import/wordpress-plugin/execute.mjs +38 -32
  375. package/dist/astro/routes/api/import/wordpress-plugin/execute.mjs.map +1 -1
  376. package/dist/astro/routes/api/manifest.mjs +6 -4
  377. package/dist/astro/routes/api/manifest.mjs.map +1 -1
  378. package/dist/astro/routes/api/mcp.d.mts.map +1 -1
  379. package/dist/astro/routes/api/mcp.mjs +717 -67
  380. package/dist/astro/routes/api/mcp.mjs.map +1 -1
  381. package/dist/astro/routes/api/media/_id_/confirm.mjs +19 -13
  382. package/dist/astro/routes/api/media/_id_/confirm.mjs.map +1 -1
  383. package/dist/astro/routes/api/media/_id_/replace.mjs +16 -10
  384. package/dist/astro/routes/api/media/_id_/replace.mjs.map +1 -1
  385. package/dist/astro/routes/api/media/_id_/upload.mjs +8 -6
  386. package/dist/astro/routes/api/media/_id_/upload.mjs.map +1 -1
  387. package/dist/astro/routes/api/media/_id_/usage.mjs +34 -21
  388. package/dist/astro/routes/api/media/_id_/usage.mjs.map +1 -1
  389. package/dist/astro/routes/api/media/_id_.d.mts.map +1 -1
  390. package/dist/astro/routes/api/media/_id_.mjs +37 -26
  391. package/dist/astro/routes/api/media/_id_.mjs.map +1 -1
  392. package/dist/astro/routes/api/media/asset/_id_/_filename_.mjs +5 -3
  393. package/dist/astro/routes/api/media/asset/_id_/_filename_.mjs.map +1 -1
  394. package/dist/astro/routes/api/media/file/_...key_.d.mts.map +1 -1
  395. package/dist/astro/routes/api/media/file/_...key_.mjs +31 -2
  396. package/dist/astro/routes/api/media/file/_...key_.mjs.map +1 -1
  397. package/dist/astro/routes/api/media/folders/_id_.mjs +16 -10
  398. package/dist/astro/routes/api/media/folders/_id_.mjs.map +1 -1
  399. package/dist/astro/routes/api/media/folders/index.mjs +16 -10
  400. package/dist/astro/routes/api/media/folders/index.mjs.map +1 -1
  401. package/dist/astro/routes/api/media/providers/_providerId_/_itemId_.mjs +4 -2
  402. package/dist/astro/routes/api/media/providers/_providerId_/_itemId_.mjs.map +1 -1
  403. package/dist/astro/routes/api/media/providers/_providerId_/index.mjs +4 -2
  404. package/dist/astro/routes/api/media/providers/_providerId_/index.mjs.map +1 -1
  405. package/dist/astro/routes/api/media/providers/index.mjs +4 -2
  406. package/dist/astro/routes/api/media/providers/index.mjs.map +1 -1
  407. package/dist/astro/routes/api/media/upload-url.mjs +18 -12
  408. package/dist/astro/routes/api/media/upload-url.mjs.map +1 -1
  409. package/dist/astro/routes/api/media.mjs +36 -24
  410. package/dist/astro/routes/api/media.mjs.map +1 -1
  411. package/dist/astro/routes/api/menus/_name_/items/_id_.mjs +18 -12
  412. package/dist/astro/routes/api/menus/_name_/items/_id_.mjs.map +1 -1
  413. package/dist/astro/routes/api/menus/_name_/items.mjs +18 -12
  414. package/dist/astro/routes/api/menus/_name_/items.mjs.map +1 -1
  415. package/dist/astro/routes/api/menus/_name_/reorder.mjs +18 -12
  416. package/dist/astro/routes/api/menus/_name_/reorder.mjs.map +1 -1
  417. package/dist/astro/routes/api/menus/_name_/translations.mjs +18 -12
  418. package/dist/astro/routes/api/menus/_name_/translations.mjs.map +1 -1
  419. package/dist/astro/routes/api/menus/_name_.mjs +18 -12
  420. package/dist/astro/routes/api/menus/_name_.mjs.map +1 -1
  421. package/dist/astro/routes/api/menus/index.mjs +18 -12
  422. package/dist/astro/routes/api/menus/index.mjs.map +1 -1
  423. package/dist/astro/routes/api/oauth/authorize.d.mts.map +1 -1
  424. package/dist/astro/routes/api/oauth/authorize.mjs +9 -6
  425. package/dist/astro/routes/api/oauth/authorize.mjs.map +1 -1
  426. package/dist/astro/routes/api/oauth/device/authorize.mjs +7 -5
  427. package/dist/astro/routes/api/oauth/device/authorize.mjs.map +1 -1
  428. package/dist/astro/routes/api/oauth/device/code.mjs +10 -8
  429. package/dist/astro/routes/api/oauth/device/code.mjs.map +1 -1
  430. package/dist/astro/routes/api/oauth/device/token.mjs +9 -7
  431. package/dist/astro/routes/api/oauth/device/token.mjs.map +1 -1
  432. package/dist/astro/routes/api/oauth/register.mjs +4 -2
  433. package/dist/astro/routes/api/oauth/register.mjs.map +1 -1
  434. package/dist/astro/routes/api/oauth/token/refresh.mjs +7 -5
  435. package/dist/astro/routes/api/oauth/token/refresh.mjs.map +1 -1
  436. package/dist/astro/routes/api/oauth/token/revoke.mjs +7 -5
  437. package/dist/astro/routes/api/oauth/token/revoke.mjs.map +1 -1
  438. package/dist/astro/routes/api/oauth/token.mjs +7 -5
  439. package/dist/astro/routes/api/oauth/token.mjs.map +1 -1
  440. package/dist/astro/routes/api/openapi.json.mjs +497 -12
  441. package/dist/astro/routes/api/openapi.json.mjs.map +1 -1
  442. package/dist/astro/routes/api/plugins/_pluginId_/_...path_.mjs +10 -8
  443. package/dist/astro/routes/api/plugins/_pluginId_/_...path_.mjs.map +1 -1
  444. package/dist/astro/routes/api/redirects/404s/index.mjs +21 -15
  445. package/dist/astro/routes/api/redirects/404s/index.mjs.map +1 -1
  446. package/dist/astro/routes/api/redirects/404s/summary.mjs +21 -15
  447. package/dist/astro/routes/api/redirects/404s/summary.mjs.map +1 -1
  448. package/dist/astro/routes/api/redirects/_id_.mjs +21 -15
  449. package/dist/astro/routes/api/redirects/_id_.mjs.map +1 -1
  450. package/dist/astro/routes/api/redirects/index.mjs +21 -15
  451. package/dist/astro/routes/api/redirects/index.mjs.map +1 -1
  452. package/dist/astro/routes/api/relations/_id_/index.mjs +31 -22
  453. package/dist/astro/routes/api/relations/_id_/index.mjs.map +1 -1
  454. package/dist/astro/routes/api/relations/_id_/translations.mjs +21 -16
  455. package/dist/astro/routes/api/relations/_id_/translations.mjs.map +1 -1
  456. package/dist/astro/routes/api/relations/index.mjs +31 -22
  457. package/dist/astro/routes/api/relations/index.mjs.map +1 -1
  458. package/dist/astro/routes/api/revisions/_revisionId_/index.mjs +4 -2
  459. package/dist/astro/routes/api/revisions/_revisionId_/index.mjs.map +1 -1
  460. package/dist/astro/routes/api/revisions/_revisionId_/restore.mjs +4 -3
  461. package/dist/astro/routes/api/revisions/_revisionId_/restore.mjs.map +1 -1
  462. package/dist/astro/routes/api/schema/block-types/_slug_/index.d.mts +9 -0
  463. package/dist/astro/routes/api/schema/block-types/_slug_/index.d.mts.map +1 -0
  464. package/dist/astro/routes/api/schema/block-types/_slug_/index.mjs +102 -0
  465. package/dist/astro/routes/api/schema/block-types/_slug_/index.mjs.map +1 -0
  466. package/dist/astro/routes/api/schema/block-types/_slug_/versions/_version_/activate.d.mts +8 -0
  467. package/dist/astro/routes/api/schema/block-types/_slug_/versions/_version_/activate.d.mts.map +1 -0
  468. package/dist/astro/routes/api/schema/block-types/_slug_/versions/_version_/activate.mjs +96 -0
  469. package/dist/astro/routes/api/schema/block-types/_slug_/versions/_version_/activate.mjs.map +1 -0
  470. package/dist/astro/routes/api/schema/block-types/index.d.mts +9 -0
  471. package/dist/astro/routes/api/schema/block-types/index.d.mts.map +1 -0
  472. package/dist/astro/routes/api/schema/block-types/index.mjs +102 -0
  473. package/dist/astro/routes/api/schema/block-types/index.mjs.map +1 -0
  474. package/dist/astro/routes/api/schema/collections/_slug_/fields/_fieldSlug_.mjs +71 -61
  475. package/dist/astro/routes/api/schema/collections/_slug_/fields/_fieldSlug_.mjs.map +1 -1
  476. package/dist/astro/routes/api/schema/collections/_slug_/fields/index.mjs +71 -61
  477. package/dist/astro/routes/api/schema/collections/_slug_/fields/index.mjs.map +1 -1
  478. package/dist/astro/routes/api/schema/collections/_slug_/fields/reorder.mjs +71 -61
  479. package/dist/astro/routes/api/schema/collections/_slug_/fields/reorder.mjs.map +1 -1
  480. package/dist/astro/routes/api/schema/collections/_slug_/index.mjs +71 -61
  481. package/dist/astro/routes/api/schema/collections/_slug_/index.mjs.map +1 -1
  482. package/dist/astro/routes/api/schema/collections/index.mjs +71 -61
  483. package/dist/astro/routes/api/schema/collections/index.mjs.map +1 -1
  484. package/dist/astro/routes/api/schema/collections/reorder.mjs +71 -61
  485. package/dist/astro/routes/api/schema/collections/reorder.mjs.map +1 -1
  486. package/dist/astro/routes/api/schema/index.mjs +17 -14
  487. package/dist/astro/routes/api/schema/index.mjs.map +1 -1
  488. package/dist/astro/routes/api/schema/orphans/_slug_.mjs +71 -61
  489. package/dist/astro/routes/api/schema/orphans/_slug_.mjs.map +1 -1
  490. package/dist/astro/routes/api/schema/orphans/index.mjs +71 -61
  491. package/dist/astro/routes/api/schema/orphans/index.mjs.map +1 -1
  492. package/dist/astro/routes/api/search/enable.mjs +20 -14
  493. package/dist/astro/routes/api/search/enable.mjs.map +1 -1
  494. package/dist/astro/routes/api/search/index.mjs +19 -13
  495. package/dist/astro/routes/api/search/index.mjs.map +1 -1
  496. package/dist/astro/routes/api/search/rebuild.mjs +20 -14
  497. package/dist/astro/routes/api/search/rebuild.mjs.map +1 -1
  498. package/dist/astro/routes/api/search/stats.mjs +10 -8
  499. package/dist/astro/routes/api/search/stats.mjs.map +1 -1
  500. package/dist/astro/routes/api/search/suggest.mjs +19 -13
  501. package/dist/astro/routes/api/search/suggest.mjs.map +1 -1
  502. package/dist/astro/routes/api/sections/_slug_.mjs +19 -13
  503. package/dist/astro/routes/api/sections/_slug_.mjs.map +1 -1
  504. package/dist/astro/routes/api/sections/index.mjs +19 -13
  505. package/dist/astro/routes/api/sections/index.mjs.map +1 -1
  506. package/dist/astro/routes/api/settings/backups/archives/_name_.mjs +8 -7
  507. package/dist/astro/routes/api/settings/backups/archives/_name_.mjs.map +1 -1
  508. package/dist/astro/routes/api/settings/backups/archives/index.mjs +8 -6
  509. package/dist/astro/routes/api/settings/backups/archives/index.mjs.map +1 -1
  510. package/dist/astro/routes/api/settings/backups/export.mjs +8 -7
  511. package/dist/astro/routes/api/settings/backups/export.mjs.map +1 -1
  512. package/dist/astro/routes/api/settings/backups/index.mjs +9 -8
  513. package/dist/astro/routes/api/settings/backups/index.mjs.map +1 -1
  514. package/dist/astro/routes/api/settings/email.mjs +6 -4
  515. package/dist/astro/routes/api/settings/email.mjs.map +1 -1
  516. package/dist/astro/routes/api/settings.mjs +25 -19
  517. package/dist/astro/routes/api/settings.mjs.map +1 -1
  518. package/dist/astro/routes/api/setup/admin-verify.mjs +20 -14
  519. package/dist/astro/routes/api/setup/admin-verify.mjs.map +1 -1
  520. package/dist/astro/routes/api/setup/admin.mjs +19 -13
  521. package/dist/astro/routes/api/setup/admin.mjs.map +1 -1
  522. package/dist/astro/routes/api/setup/dev-bypass.mjs +43 -37
  523. package/dist/astro/routes/api/setup/dev-bypass.mjs.map +1 -1
  524. package/dist/astro/routes/api/setup/dev-reset.mjs +4 -2
  525. package/dist/astro/routes/api/setup/dev-reset.mjs.map +1 -1
  526. package/dist/astro/routes/api/setup/index.mjs +48 -38
  527. package/dist/astro/routes/api/setup/index.mjs.map +1 -1
  528. package/dist/astro/routes/api/setup/status.mjs +5 -3
  529. package/dist/astro/routes/api/setup/status.mjs.map +1 -1
  530. package/dist/astro/routes/api/snapshot.mjs +10 -8
  531. package/dist/astro/routes/api/snapshot.mjs.map +1 -1
  532. package/dist/astro/routes/api/taxonomies/_name_/reorder.mjs +25 -19
  533. package/dist/astro/routes/api/taxonomies/_name_/reorder.mjs.map +1 -1
  534. package/dist/astro/routes/api/taxonomies/_name_/terms/_slug_/translations.mjs +25 -19
  535. package/dist/astro/routes/api/taxonomies/_name_/terms/_slug_/translations.mjs.map +1 -1
  536. package/dist/astro/routes/api/taxonomies/_name_/terms/_slug_.mjs +25 -19
  537. package/dist/astro/routes/api/taxonomies/_name_/terms/_slug_.mjs.map +1 -1
  538. package/dist/astro/routes/api/taxonomies/_name_/terms/index.mjs +25 -19
  539. package/dist/astro/routes/api/taxonomies/_name_/terms/index.mjs.map +1 -1
  540. package/dist/astro/routes/api/taxonomies/_name_/translations.mjs +24 -18
  541. package/dist/astro/routes/api/taxonomies/_name_/translations.mjs.map +1 -1
  542. package/dist/astro/routes/api/taxonomies/_name_.mjs +25 -19
  543. package/dist/astro/routes/api/taxonomies/_name_.mjs.map +1 -1
  544. package/dist/astro/routes/api/taxonomies/bulk-tag.d.mts +8 -0
  545. package/dist/astro/routes/api/taxonomies/bulk-tag.d.mts.map +1 -0
  546. package/dist/astro/routes/api/taxonomies/bulk-tag.mjs +295 -0
  547. package/dist/astro/routes/api/taxonomies/bulk-tag.mjs.map +1 -0
  548. package/dist/astro/routes/api/taxonomies/index.mjs +25 -19
  549. package/dist/astro/routes/api/taxonomies/index.mjs.map +1 -1
  550. package/dist/astro/routes/api/themes/preview.mjs +7 -5
  551. package/dist/astro/routes/api/themes/preview.mjs.map +1 -1
  552. package/dist/astro/routes/api/typegen.d.mts.map +1 -1
  553. package/dist/astro/routes/api/typegen.mjs +12 -9
  554. package/dist/astro/routes/api/typegen.mjs.map +1 -1
  555. package/dist/astro/routes/api/visual-editing/action-token.mjs +7 -5
  556. package/dist/astro/routes/api/visual-editing/action-token.mjs.map +1 -1
  557. package/dist/astro/routes/api/visual-editing/content/_collection_/_id_/publish.mjs +22 -16
  558. package/dist/astro/routes/api/visual-editing/content/_collection_/_id_/publish.mjs.map +1 -1
  559. package/dist/astro/routes/api/visual-editing/toolbar-labels.mjs +3 -1
  560. package/dist/astro/routes/api/visual-editing/toolbar-labels.mjs.map +1 -1
  561. package/dist/astro/routes/api/well-known/auth.mjs +2 -2
  562. package/dist/astro/routes/api/well-known/oauth-authorization-server.mjs +2 -2
  563. package/dist/astro/routes/api/well-known/oauth-protected-resource.mjs +2 -2
  564. package/dist/astro/routes/api/widget-areas/_name_/reorder.mjs +16 -10
  565. package/dist/astro/routes/api/widget-areas/_name_/reorder.mjs.map +1 -1
  566. package/dist/astro/routes/api/widget-areas/_name_/widgets/_id_.mjs +20 -14
  567. package/dist/astro/routes/api/widget-areas/_name_/widgets/_id_.mjs.map +1 -1
  568. package/dist/astro/routes/api/widget-areas/_name_/widgets.mjs +20 -14
  569. package/dist/astro/routes/api/widget-areas/_name_/widgets.mjs.map +1 -1
  570. package/dist/astro/routes/api/widget-areas/_name_.mjs +10 -8
  571. package/dist/astro/routes/api/widget-areas/_name_.mjs.map +1 -1
  572. package/dist/astro/routes/api/widget-areas/index.mjs +20 -14
  573. package/dist/astro/routes/api/widget-areas/index.mjs.map +1 -1
  574. package/dist/astro/routes/api/widget-components.mjs +4 -2
  575. package/dist/astro/routes/api/widget-components.mjs.map +1 -1
  576. package/dist/astro/routes/robots.txt.mjs +10 -10
  577. package/dist/astro/routes/sitemap-_collection_.xml.mjs +13 -13
  578. package/dist/astro/routes/sitemap.xml.mjs +11 -11
  579. package/dist/astro/types.d.mts +21 -17
  580. package/dist/astro/types.d.mts.map +1 -1
  581. package/dist/audit-RfCugiSB.mjs +127 -0
  582. package/dist/audit-RfCugiSB.mjs.map +1 -0
  583. package/dist/auth/providers/github.d.mts +1 -1
  584. package/dist/auth/providers/google.d.mts +1 -1
  585. package/dist/authoritative-records-CoJvBXAD.mjs +5172 -0
  586. package/dist/authoritative-records-CoJvBXAD.mjs.map +1 -0
  587. package/dist/authorize-seCifOMJ.mjs +49 -0
  588. package/dist/authorize-seCifOMJ.mjs.map +1 -0
  589. package/dist/backup-CBu0LrXf.mjs +246 -0
  590. package/dist/backup-CBu0LrXf.mjs.map +1 -0
  591. package/dist/block-type-registry-DUI_3KxT.mjs +6709 -0
  592. package/dist/block-type-registry-DUI_3KxT.mjs.map +1 -0
  593. package/dist/block-types-BmZmLmAD.mjs +132 -0
  594. package/dist/block-types-BmZmLmAD.mjs.map +1 -0
  595. package/dist/block-values-C_VIPr5t.mjs +175 -0
  596. package/dist/block-values-C_VIPr5t.mjs.map +1 -0
  597. package/dist/byline-DYmkXqvo.mjs +909 -0
  598. package/dist/byline-DYmkXqvo.mjs.map +1 -0
  599. package/dist/byline-fields-D28AT-Fh.mjs +123 -0
  600. package/dist/byline-fields-D28AT-Fh.mjs.map +1 -0
  601. package/dist/byline-registry-gnKscbQX.mjs +406 -0
  602. package/dist/byline-registry-gnKscbQX.mjs.map +1 -0
  603. package/dist/bylines-BPwJqoYH.mjs +232 -0
  604. package/dist/bylines-BPwJqoYH.mjs.map +1 -0
  605. package/dist/bylines-ukLaYpVZ.mjs +214 -0
  606. package/dist/bylines-ukLaYpVZ.mjs.map +1 -0
  607. package/dist/cache-m7UEkRFV.mjs +108 -0
  608. package/dist/cache-m7UEkRFV.mjs.map +1 -0
  609. package/dist/canonical-YhEQezjg.mjs +174 -0
  610. package/dist/canonical-YhEQezjg.mjs.map +1 -0
  611. package/dist/capture-triggers-kJyl_yyM.mjs +362 -0
  612. package/dist/capture-triggers-kJyl_yyM.mjs.map +1 -0
  613. package/dist/challenge-store-ppU6Uv13.mjs +51 -0
  614. package/dist/challenge-store-ppU6Uv13.mjs.map +1 -0
  615. package/dist/checksum-B2IINIlN.mjs +162 -0
  616. package/dist/checksum-B2IINIlN.mjs.map +1 -0
  617. package/dist/chrome-tags-DApCQSIk.mjs +24 -0
  618. package/dist/chrome-tags-DApCQSIk.mjs.map +1 -0
  619. package/dist/chunks-Dms7Uxbt.mjs +25 -0
  620. package/dist/chunks-Dms7Uxbt.mjs.map +1 -0
  621. package/dist/cli/index.mjs +1471 -56
  622. package/dist/cli/index.mjs.map +1 -1
  623. package/dist/client/cf-access.d.mts +1 -1
  624. package/dist/client/index.d.mts +1050 -4
  625. package/dist/client/index.d.mts.map +1 -1
  626. package/dist/client/index.mjs +193 -11
  627. package/dist/client/index.mjs.map +1 -1
  628. package/dist/collection-deletion-BIm28mo3.mjs +436 -0
  629. package/dist/collection-deletion-BIm28mo3.mjs.map +1 -0
  630. package/dist/collection-deletion-processor-Br6rxs3u.mjs +217 -0
  631. package/dist/collection-deletion-processor-Br6rxs3u.mjs.map +1 -0
  632. package/dist/collection-slugs-cache-CjGk__zp.mjs +85 -0
  633. package/dist/collection-slugs-cache-CjGk__zp.mjs.map +1 -0
  634. package/dist/comment-CrBl22OF.mjs +313 -0
  635. package/dist/comment-CrBl22OF.mjs.map +1 -0
  636. package/dist/comment-reaction-JEQ2Fpd8.mjs +85 -0
  637. package/dist/comment-reaction-JEQ2Fpd8.mjs.map +1 -0
  638. package/dist/comments-2ah9du9y.mjs +195 -0
  639. package/dist/comments-2ah9du9y.mjs.map +1 -0
  640. package/dist/comments-fHZ8ON9O.mjs +99 -0
  641. package/dist/comments-fHZ8ON9O.mjs.map +1 -0
  642. package/dist/components-CXbq7CSM.mjs +108 -0
  643. package/dist/components-CXbq7CSM.mjs.map +1 -0
  644. package/dist/config-5ii2haYu.d.mts +6528 -0
  645. package/dist/config-5ii2haYu.d.mts.map +1 -0
  646. package/dist/config-CvmjJcVw.mjs +73 -0
  647. package/dist/config-CvmjJcVw.mjs.map +1 -0
  648. package/dist/config-IhybvkIQ.mjs +242 -0
  649. package/dist/config-IhybvkIQ.mjs.map +1 -0
  650. package/dist/config-Py43JK9r.d.mts +39 -0
  651. package/dist/config-Py43JK9r.d.mts.map +1 -0
  652. package/dist/content-DFaIEDj9.mjs +2281 -0
  653. package/dist/content-DFaIEDj9.mjs.map +1 -0
  654. package/dist/content-list-query-Dra4Dalc.d.mts +26 -0
  655. package/dist/content-list-query-Dra4Dalc.d.mts.map +1 -0
  656. package/dist/content-policy-DFNw91-d.mjs +46 -0
  657. package/dist/content-policy-DFNw91-d.mjs.map +1 -0
  658. package/dist/content-repair-Q8IUrpLL.mjs +442 -0
  659. package/dist/content-repair-Q8IUrpLL.mjs.map +1 -0
  660. package/dist/context-BeGccdUX.mjs +1921 -0
  661. package/dist/context-BeGccdUX.mjs.map +1 -0
  662. package/dist/cron-7DCJwPXq.mjs +284 -0
  663. package/dist/cron-7DCJwPXq.mjs.map +1 -0
  664. package/dist/dashboard-DjrB-xxZ.mjs +151 -0
  665. package/dist/dashboard-DjrB-xxZ.mjs.map +1 -0
  666. package/dist/db/index.d.mts +3 -3
  667. package/dist/db/index.mjs +3 -3
  668. package/dist/db/libsql-migrations.d.mts +1 -1
  669. package/dist/db/libsql-migrations.mjs +6 -6
  670. package/dist/db/libsql.d.mts +1 -1
  671. package/dist/db/postgres-migrations.d.mts +1 -1
  672. package/dist/db/postgres-migrations.mjs +6 -6
  673. package/dist/db/postgres.d.mts +1 -1
  674. package/dist/db/sqlite-migrations.d.mts +1 -1
  675. package/dist/db/sqlite-migrations.mjs +6 -6
  676. package/dist/db/sqlite.d.mts +1 -1
  677. package/dist/db/sqlite.mjs +2 -2
  678. package/dist/db/sqlite.mjs.map +1 -1
  679. package/dist/default-DQ6vsviu.mjs +81 -0
  680. package/dist/default-DQ6vsviu.mjs.map +1 -0
  681. package/dist/deferred-tasks-BPxXUB4x.d.mts +9 -0
  682. package/dist/deferred-tasks-BPxXUB4x.d.mts.map +1 -0
  683. package/dist/device-flow-CRd6DXmW.mjs +466 -0
  684. package/dist/device-flow-CRd6DXmW.mjs.map +1 -0
  685. package/dist/dialect-helpers-7_IqPdh9.mjs +307 -0
  686. package/dist/dialect-helpers-7_IqPdh9.mjs.map +1 -0
  687. package/dist/digest-BarSh-pN.mjs +194 -0
  688. package/dist/digest-BarSh-pN.mjs.map +1 -0
  689. package/dist/direct-executor-BmuFJJZV.mjs +104 -0
  690. package/dist/direct-executor-BmuFJJZV.mjs.map +1 -0
  691. package/dist/dist-BNwANFJR.mjs +810 -0
  692. package/dist/dist-BNwANFJR.mjs.map +1 -0
  693. package/dist/email-console-bJn3ctqA.mjs +50 -0
  694. package/dist/email-console-bJn3ctqA.mjs.map +1 -0
  695. package/dist/email-locale-CN6WAMx0.mjs +25 -0
  696. package/dist/email-locale-CN6WAMx0.mjs.map +1 -0
  697. package/dist/emdash-runtime-DAjghyEG.mjs +4186 -0
  698. package/dist/emdash-runtime-DAjghyEG.mjs.map +1 -0
  699. package/dist/enrich-Dl3kZ-lP.mjs +194 -0
  700. package/dist/enrich-Dl3kZ-lP.mjs.map +1 -0
  701. package/dist/entry-lock-BJYdBfXb.mjs +1097 -0
  702. package/dist/entry-lock-BJYdBfXb.mjs.map +1 -0
  703. package/dist/entry-lock-DHQOxN7R.mjs +163 -0
  704. package/dist/entry-lock-DHQOxN7R.mjs.map +1 -0
  705. package/dist/entry-lock-DVhCt49A.d.mts +4368 -0
  706. package/dist/entry-lock-DVhCt49A.d.mts.map +1 -0
  707. package/dist/entry-locks-D0foLdjQ.mjs +167 -0
  708. package/dist/entry-locks-D0foLdjQ.mjs.map +1 -0
  709. package/dist/error-CfvOHP0M.mjs +90 -0
  710. package/dist/error-CfvOHP0M.mjs.map +1 -0
  711. package/dist/errors-BF0_LFhW.mjs +460 -0
  712. package/dist/errors-BF0_LFhW.mjs.map +1 -0
  713. package/dist/errors-DgE1zJGG.mjs +120 -0
  714. package/dist/errors-DgE1zJGG.mjs.map +1 -0
  715. package/dist/escape-CuaZhZvL.mjs +9 -0
  716. package/dist/escape-CuaZhZvL.mjs.map +1 -0
  717. package/dist/fence-CMDXJYc_.mjs +162 -0
  718. package/dist/fence-CMDXJYc_.mjs.map +1 -0
  719. package/dist/field-defs-cache-HIgBbqZZ.mjs +77 -0
  720. package/dist/field-defs-cache-HIgBbqZZ.mjs.map +1 -0
  721. package/dist/fts-manager-S-K0laoS.mjs +443 -0
  722. package/dist/fts-manager-S-K0laoS.mjs.map +1 -0
  723. package/dist/gc-DjKY0Ay1.mjs +75 -0
  724. package/dist/gc-DjKY0Ay1.mjs.map +1 -0
  725. package/dist/hash-SDAW6zC-.mjs +37 -0
  726. package/dist/hash-SDAW6zC-.mjs.map +1 -0
  727. package/dist/hook-result-B5bXDgS2.d.mts +31 -0
  728. package/dist/hook-result-B5bXDgS2.d.mts.map +1 -0
  729. package/dist/hreflang-D5uNnsGJ.d.mts +50 -0
  730. package/dist/hreflang-D5uNnsGJ.d.mts.map +1 -0
  731. package/dist/hreflang-DMFBL2eb.mjs +105 -0
  732. package/dist/hreflang-DMFBL2eb.mjs.map +1 -0
  733. package/dist/http-route-dispatch-BitqzwMy.mjs +339 -0
  734. package/dist/http-route-dispatch-BitqzwMy.mjs.map +1 -0
  735. package/dist/identity-IyNWwXr6.mjs +35 -0
  736. package/dist/identity-IyNWwXr6.mjs.map +1 -0
  737. package/dist/import-C3JZplWq.mjs +2020 -0
  738. package/dist/import-C3JZplWq.mjs.map +1 -0
  739. package/dist/index-D-hdtLe8.d.mts +623 -0
  740. package/dist/index-D-hdtLe8.d.mts.map +1 -0
  741. package/dist/index.d.mts +24 -24
  742. package/dist/index.mjs +105 -93
  743. package/dist/install-finalization-DfM1fj5x.mjs +58 -0
  744. package/dist/install-finalization-DfM1fj5x.mjs.map +1 -0
  745. package/dist/keys-yxLm5l35.mjs +61 -0
  746. package/dist/keys-yxLm5l35.mjs.map +1 -0
  747. package/dist/kinds-CRu_T5T5.mjs +961 -0
  748. package/dist/kinds-CRu_T5T5.mjs.map +1 -0
  749. package/dist/lifecycle-BzeGPeQ-.mjs +25 -0
  750. package/dist/lifecycle-BzeGPeQ-.mjs.map +1 -0
  751. package/dist/load-XgJiE6_3.mjs +28 -0
  752. package/dist/load-XgJiE6_3.mjs.map +1 -0
  753. package/dist/loader-BzqeR1ZN.mjs +1086 -0
  754. package/dist/loader-BzqeR1ZN.mjs.map +1 -0
  755. package/dist/loops-BQSzv5Zn.mjs +203 -0
  756. package/dist/loops-BQSzv5Zn.mjs.map +1 -0
  757. package/dist/manifest-builder-B8zR-73J.mjs +189 -0
  758. package/dist/manifest-builder-B8zR-73J.mjs.map +1 -0
  759. package/dist/manifest-schema-CY3zng_M.mjs +492 -0
  760. package/dist/manifest-schema-CY3zng_M.mjs.map +1 -0
  761. package/dist/media/image-endpoint.mjs +1 -1
  762. package/dist/media/index.d.mts +1 -1
  763. package/dist/media/index.mjs +3 -3
  764. package/dist/media/local-runtime.d.mts +14 -14
  765. package/dist/media/local-runtime.d.mts.map +1 -1
  766. package/dist/media/local-runtime.mjs +15 -16
  767. package/dist/media/local-runtime.mjs.map +1 -1
  768. package/dist/media-Pu1L6xir.mjs +408 -0
  769. package/dist/media-Pu1L6xir.mjs.map +1 -0
  770. package/dist/media-Qp5S3eH3.mjs +355 -0
  771. package/dist/media-Qp5S3eH3.mjs.map +1 -0
  772. package/dist/media-allowlist-BSoa9Vvm.mjs +44 -0
  773. package/dist/media-allowlist-BSoa9Vvm.mjs.map +1 -0
  774. package/dist/media-folders-BE0oo2eX.mjs +210 -0
  775. package/dist/media-folders-BE0oo2eX.mjs.map +1 -0
  776. package/dist/media-h7tOiDLj.mjs +221 -0
  777. package/dist/media-h7tOiDLj.mjs.map +1 -0
  778. package/dist/media-url-jArBpzIG.mjs +43 -0
  779. package/dist/media-url-jArBpzIG.mjs.map +1 -0
  780. package/dist/media-usage-My-Vi-ex.mjs +1629 -0
  781. package/dist/media-usage-My-Vi-ex.mjs.map +1 -0
  782. package/dist/media-usage-activation-HKp7zk7W.mjs +78 -0
  783. package/dist/media-usage-activation-HKp7zk7W.mjs.map +1 -0
  784. package/dist/media-usage-work-C2OZLCAd.mjs +586 -0
  785. package/dist/media-usage-work-C2OZLCAd.mjs.map +1 -0
  786. package/dist/media-usage-work-DwUNbgvS.mjs +152 -0
  787. package/dist/media-usage-work-DwUNbgvS.mjs.map +1 -0
  788. package/dist/menus-BM7BPLOb.mjs +139 -0
  789. package/dist/menus-BM7BPLOb.mjs.map +1 -0
  790. package/dist/menus-ITeAbcIF.mjs +753 -0
  791. package/dist/menus-ITeAbcIF.mjs.map +1 -0
  792. package/dist/menus-TsSGmSR4.mjs +3608 -0
  793. package/dist/menus-TsSGmSR4.mjs.map +1 -0
  794. package/dist/migrations/index.d.mts +1 -1
  795. package/dist/migrations/index.mjs +5 -5
  796. package/dist/mime-ChLqYwDk.mjs +36 -0
  797. package/dist/mime-ChLqYwDk.mjs.map +1 -0
  798. package/dist/mode-CCuKXUci.mjs +23 -0
  799. package/dist/mode-CCuKXUci.mjs.map +1 -0
  800. package/dist/node-sqlite-compat-CONMsl-x.mjs +46 -0
  801. package/dist/node-sqlite-compat-CONMsl-x.mjs.map +1 -0
  802. package/dist/normalize-CO2P8-iE.mjs +191 -0
  803. package/dist/normalize-CO2P8-iE.mjs.map +1 -0
  804. package/dist/oauth-authorization-DlMIL5_h.mjs +274 -0
  805. package/dist/oauth-authorization-DlMIL5_h.mjs.map +1 -0
  806. package/dist/oauth-clients-Djq9r_KP.mjs +266 -0
  807. package/dist/oauth-clients-Djq9r_KP.mjs.map +1 -0
  808. package/dist/oauth-state-store-BbjnZXNC.mjs +50 -0
  809. package/dist/oauth-state-store-BbjnZXNC.mjs.map +1 -0
  810. package/dist/oauth-user-lookup-vue9a64A.mjs +26 -0
  811. package/dist/oauth-user-lookup-vue9a64A.mjs.map +1 -0
  812. package/dist/object-cache/memory.d.mts +1 -1
  813. package/dist/object-cache-CqWNY5uP.mjs +582 -0
  814. package/dist/object-cache-CqWNY5uP.mjs.map +1 -0
  815. package/dist/options-DhrI7eMv.mjs +208 -0
  816. package/dist/options-DhrI7eMv.mjs.map +1 -0
  817. package/dist/options-SQCHQCPH.d.mts +81 -0
  818. package/dist/options-SQCHQCPH.d.mts.map +1 -0
  819. package/dist/page/index.d.mts +2 -2
  820. package/dist/page/index.mjs +9 -9
  821. package/dist/parse-CVgO-Qai.d.mts +168 -0
  822. package/dist/parse-CVgO-Qai.d.mts.map +1 -0
  823. package/dist/parse-DY6OD1j_.mjs +81 -0
  824. package/dist/parse-DY6OD1j_.mjs.map +1 -0
  825. package/dist/passkey-config-X_H8128a.mjs +46 -0
  826. package/dist/passkey-config-X_H8128a.mjs.map +1 -0
  827. package/dist/paths-JxokKIbr.mjs +77 -0
  828. package/dist/paths-JxokKIbr.mjs.map +1 -0
  829. package/dist/patterns-BhAvqO0S.mjs +145 -0
  830. package/dist/patterns-BhAvqO0S.mjs.map +1 -0
  831. package/dist/placeholder-MSEd8gty.d.mts +306 -0
  832. package/dist/placeholder-MSEd8gty.d.mts.map +1 -0
  833. package/dist/plan-xjcWrAah.mjs +135 -0
  834. package/dist/plan-xjcWrAah.mjs.map +1 -0
  835. package/dist/plugin-test-runtime.d.mts +38 -15
  836. package/dist/plugin-test-runtime.d.mts.map +1 -1
  837. package/dist/plugin-test-runtime.mjs +112 -100
  838. package/dist/plugin-types.d.mts +2 -2
  839. package/dist/plugin-utils.d.mts +12 -12
  840. package/dist/plugins/adapt-sandbox-entry.d.mts +12 -12
  841. package/dist/plugins/adapt-sandbox-entry.mjs +3 -3
  842. package/dist/plugins/host.d.mts +5 -5
  843. package/dist/plugins/host.mjs +45 -37
  844. package/dist/plugins-DUXUt8B9.mjs +277 -0
  845. package/dist/plugins-DUXUt8B9.mjs.map +1 -0
  846. package/dist/policy-CUvwAARc.mjs +45 -0
  847. package/dist/policy-CUvwAARc.mjs.map +1 -0
  848. package/dist/portable-text-5O_ZGUjB.mjs +307 -0
  849. package/dist/portable-text-5O_ZGUjB.mjs.map +1 -0
  850. package/dist/preview-CIUcPYr6.mjs +107 -0
  851. package/dist/preview-CIUcPYr6.mjs.map +1 -0
  852. package/dist/protocol-B97DZaFr.d.mts +61 -0
  853. package/dist/protocol-B97DZaFr.d.mts.map +1 -0
  854. package/dist/public-submission-BFBUrqst.mjs +250 -0
  855. package/dist/public-submission-BFBUrqst.mjs.map +1 -0
  856. package/dist/public-url-Bn7U0D7-.mjs +101 -0
  857. package/dist/public-url-Bn7U0D7-.mjs.map +1 -0
  858. package/dist/query-B48peoRT.mjs +890 -0
  859. package/dist/query-B48peoRT.mjs.map +1 -0
  860. package/dist/query-C4IH0uhR.mjs +41 -0
  861. package/dist/query-C4IH0uhR.mjs.map +1 -0
  862. package/dist/rate-limit-BZ6nybgc.mjs +120 -0
  863. package/dist/rate-limit-BZ6nybgc.mjs.map +1 -0
  864. package/dist/receipt-B4wJj5Jq.mjs +43 -0
  865. package/dist/receipt-B4wJj5Jq.mjs.map +1 -0
  866. package/dist/redirect-Cd1E7VUt.mjs +17 -0
  867. package/dist/redirect-Cd1E7VUt.mjs.map +1 -0
  868. package/dist/redirect-iJf5fltD.mjs +415 -0
  869. package/dist/redirect-iJf5fltD.mjs.map +1 -0
  870. package/dist/redirects-CYu1u1aK.mjs +446 -0
  871. package/dist/redirects-CYu1u1aK.mjs.map +1 -0
  872. package/dist/redirects-Cv9apQKj.mjs +148 -0
  873. package/dist/redirects-Cv9apQKj.mjs.map +1 -0
  874. package/dist/registry/testing.mjs +3 -3
  875. package/dist/relation-M4NUCb0b.mjs +334 -0
  876. package/dist/relation-M4NUCb0b.mjs.map +1 -0
  877. package/dist/relations-CCif47Oq.mjs +403 -0
  878. package/dist/relations-CCif47Oq.mjs.map +1 -0
  879. package/dist/relations-CK9CYUyr.mjs +310 -0
  880. package/dist/relations-CK9CYUyr.mjs.map +1 -0
  881. package/dist/request-cache-DzLYKm_x.mjs +104 -0
  882. package/dist/request-cache-DzLYKm_x.mjs.map +1 -0
  883. package/dist/request-context.d.mts +1 -1
  884. package/dist/request-meta-sZXt3sRo.mjs +141 -0
  885. package/dist/request-meta-sZXt3sRo.mjs.map +1 -0
  886. package/dist/resolve-2WbQsCvT.mjs +199 -0
  887. package/dist/resolve-2WbQsCvT.mjs.map +1 -0
  888. package/dist/route-wire--1hLuACz.mjs +197 -0
  889. package/dist/route-wire--1hLuACz.mjs.map +1 -0
  890. package/dist/routes-CUsM40Cc.mjs +272 -0
  891. package/dist/routes-CUsM40Cc.mjs.map +1 -0
  892. package/dist/runner-1y4J9fJB.mjs +5742 -0
  893. package/dist/runner-1y4J9fJB.mjs.map +1 -0
  894. package/dist/runner-D5_LzKXI.d.mts +68 -0
  895. package/dist/runner-D5_LzKXI.d.mts.map +1 -0
  896. package/dist/runtime.d.mts +13 -13
  897. package/dist/runtime.mjs +4 -4
  898. package/dist/schema-BABiRdsH.mjs +13 -0
  899. package/dist/schema-BABiRdsH.mjs.map +1 -0
  900. package/dist/schema-Du3MzCG0.mjs +446 -0
  901. package/dist/schema-Du3MzCG0.mjs.map +1 -0
  902. package/dist/scopes-Dbk-ElhT.mjs +34 -0
  903. package/dist/scopes-Dbk-ElhT.mjs.map +1 -0
  904. package/dist/search-Bt1PL1jf.mjs +448 -0
  905. package/dist/search-Bt1PL1jf.mjs.map +1 -0
  906. package/dist/secrets-CIi0nFiR.mjs +341 -0
  907. package/dist/secrets-CIi0nFiR.mjs.map +1 -0
  908. package/dist/sections-Ddptx_o9.mjs +346 -0
  909. package/dist/sections-Ddptx_o9.mjs.map +1 -0
  910. package/dist/seed/index.d.mts +2 -2
  911. package/dist/seed/index.mjs +35 -30
  912. package/dist/seo/index.d.mts +3 -3
  913. package/dist/seo/index.mjs +25 -21
  914. package/dist/seo/index.mjs.map +1 -1
  915. package/dist/seo-CZT2oLtT.mjs +114 -0
  916. package/dist/seo-CZT2oLtT.mjs.map +1 -0
  917. package/dist/seo-D5w3-Azy.mjs +133 -0
  918. package/dist/seo-D5w3-Azy.mjs.map +1 -0
  919. package/dist/service-DuykXPyW.mjs +150 -0
  920. package/dist/service-DuykXPyW.mjs.map +1 -0
  921. package/dist/session-user-BhaVp8w0.mjs +51 -0
  922. package/dist/session-user-BhaVp8w0.mjs.map +1 -0
  923. package/dist/settings-2xNYr90o.mjs +51 -0
  924. package/dist/settings-2xNYr90o.mjs.map +1 -0
  925. package/dist/settings-CgjRWGW9.mjs +439 -0
  926. package/dist/settings-CgjRWGW9.mjs.map +1 -0
  927. package/dist/settings-DYidIB26.mjs +61 -0
  928. package/dist/settings-DYidIB26.mjs.map +1 -0
  929. package/dist/setup-complete-bOogcHWG.mjs +26 -0
  930. package/dist/setup-complete-bOogcHWG.mjs.map +1 -0
  931. package/dist/setup-nonce-0EGuKM4s.mjs +25 -0
  932. package/dist/setup-nonce-0EGuKM4s.mjs.map +1 -0
  933. package/dist/site-settings-DOgRUoFX.mjs +50 -0
  934. package/dist/site-settings-DOgRUoFX.mjs.map +1 -0
  935. package/dist/site-url-BU_bbxwj.mjs +16 -0
  936. package/dist/site-url-BU_bbxwj.mjs.map +1 -0
  937. package/dist/snapshot-CugwUqKQ.mjs +237 -0
  938. package/dist/snapshot-CugwUqKQ.mjs.map +1 -0
  939. package/dist/ssrf-CJUnJymJ.mjs +406 -0
  940. package/dist/ssrf-CJUnJymJ.mjs.map +1 -0
  941. package/dist/stage-DgrBz_du.mjs +662 -0
  942. package/dist/stage-DgrBz_du.mjs.map +1 -0
  943. package/dist/state-DDiPySSG.mjs +153 -0
  944. package/dist/state-DDiPySSG.mjs.map +1 -0
  945. package/dist/status-DZKIG4a9.mjs +30 -0
  946. package/dist/status-DZKIG4a9.mjs.map +1 -0
  947. package/dist/storage/local.d.mts +1 -1
  948. package/dist/storage/local.mjs +1 -1
  949. package/dist/storage/s3.d.mts +1 -1
  950. package/dist/storage/s3.mjs +1 -1
  951. package/dist/storage-query-Bdv7A62k.d.mts +1576 -0
  952. package/dist/storage-query-Bdv7A62k.d.mts.map +1 -0
  953. package/dist/tar-_1AgTYFu.mjs +449 -0
  954. package/dist/tar-_1AgTYFu.mjs.map +1 -0
  955. package/dist/target-_7pn2Gbg.mjs +27 -0
  956. package/dist/target-_7pn2Gbg.mjs.map +1 -0
  957. package/dist/taxonomies-C1IwNe8Q.mjs +697 -0
  958. package/dist/taxonomies-C1IwNe8Q.mjs.map +1 -0
  959. package/dist/taxonomies-C_XMoRcX.mjs +939 -0
  960. package/dist/taxonomies-C_XMoRcX.mjs.map +1 -0
  961. package/dist/taxonomy-C3Fu1YeH.mjs +525 -0
  962. package/dist/taxonomy-C3Fu1YeH.mjs.map +1 -0
  963. package/dist/tokens-u78jETkX.mjs +171 -0
  964. package/dist/tokens-u78jETkX.mjs.map +1 -0
  965. package/dist/transfer-BhUCrgDc.mjs +8675 -0
  966. package/dist/transfer-BhUCrgDc.mjs.map +1 -0
  967. package/dist/transfer-DIGvR9Af.mjs +166 -0
  968. package/dist/transfer-DIGvR9Af.mjs.map +1 -0
  969. package/dist/transfer-download-Pml7RMio.mjs +33 -0
  970. package/dist/transfer-download-Pml7RMio.mjs.map +1 -0
  971. package/dist/transformations-9gfpwY65.mjs +196 -0
  972. package/dist/transformations-9gfpwY65.mjs.map +1 -0
  973. package/dist/transport-BIfH7_hx.d.mts +42 -0
  974. package/dist/transport-BIfH7_hx.d.mts.map +1 -0
  975. package/dist/transport-DKWIq53q.mjs +136 -0
  976. package/dist/transport-DKWIq53q.mjs.map +1 -0
  977. package/dist/trusted-proxy-tKiVtyTD.mjs +51 -0
  978. package/dist/trusted-proxy-tKiVtyTD.mjs.map +1 -0
  979. package/dist/turnstile-DpsoyOfg.mjs +53 -0
  980. package/dist/turnstile-DpsoyOfg.mjs.map +1 -0
  981. package/dist/types-B4sUC2p1.d.mts +198 -0
  982. package/dist/types-B4sUC2p1.d.mts.map +1 -0
  983. package/dist/types-B7Lmsh1E.d.mts +887 -0
  984. package/dist/types-B7Lmsh1E.d.mts.map +1 -0
  985. package/dist/types-BZakh7Ym.mjs +22 -0
  986. package/dist/types-BZakh7Ym.mjs.map +1 -0
  987. package/dist/types-B_CppEmv.d.mts +264 -0
  988. package/dist/types-B_CppEmv.d.mts.map +1 -0
  989. package/dist/types-BcrBrE6-.mjs +159 -0
  990. package/dist/types-BcrBrE6-.mjs.map +1 -0
  991. package/dist/types-CAZgq9fO.d.mts +124 -0
  992. package/dist/types-CAZgq9fO.d.mts.map +1 -0
  993. package/dist/types-Cd-O03VG.d.mts +363 -0
  994. package/dist/types-Cd-O03VG.d.mts.map +1 -0
  995. package/dist/types-Cr-Kg-3D.d.mts +1641 -0
  996. package/dist/types-Cr-Kg-3D.d.mts.map +1 -0
  997. package/dist/types-D2fvWd1i.d.mts +359 -0
  998. package/dist/types-D2fvWd1i.d.mts.map +1 -0
  999. package/dist/types-D7HUsguf.mjs +77 -0
  1000. package/dist/types-D7HUsguf.mjs.map +1 -0
  1001. package/dist/types-DA1Te3Oy.d.mts +198 -0
  1002. package/dist/types-DA1Te3Oy.d.mts.map +1 -0
  1003. package/dist/types-DhV6Q5bP.mjs +18 -0
  1004. package/dist/types-DhV6Q5bP.mjs.map +1 -0
  1005. package/dist/types-DnnVSl6Y.d.mts +85 -0
  1006. package/dist/types-DnnVSl6Y.d.mts.map +1 -0
  1007. package/dist/types-VT4-BugW.mjs +16 -0
  1008. package/dist/types-VT4-BugW.mjs.map +1 -0
  1009. package/dist/upload-attempts-B68ZGNu9.mjs +32 -0
  1010. package/dist/upload-attempts-B68ZGNu9.mjs.map +1 -0
  1011. package/dist/url-pattern-CCeZMGOh.mjs +33 -0
  1012. package/dist/url-pattern-CCeZMGOh.mjs.map +1 -0
  1013. package/dist/user-DDSL-sGw.mjs +171 -0
  1014. package/dist/user-DDSL-sGw.mjs.map +1 -0
  1015. package/dist/utils-DdhmO9w9.mjs +439 -0
  1016. package/dist/utils-DdhmO9w9.mjs.map +1 -0
  1017. package/dist/validate-CHosPEhs.mjs +453 -0
  1018. package/dist/validate-CHosPEhs.mjs.map +1 -0
  1019. package/dist/validate-CM79QXYE.d.mts +432 -0
  1020. package/dist/validate-CM79QXYE.d.mts.map +1 -0
  1021. package/dist/validation-BFecQczG.mjs +218 -0
  1022. package/dist/validation-BFecQczG.mjs.map +1 -0
  1023. package/dist/version-BRZXVifl.mjs +9 -0
  1024. package/dist/version-BRZXVifl.mjs.map +1 -0
  1025. package/dist/version-DUQDHgrf.mjs +7 -0
  1026. package/dist/version-DUQDHgrf.mjs.map +1 -0
  1027. package/dist/widgets-WdV72brA.mjs +126 -0
  1028. package/dist/widgets-WdV72brA.mjs.map +1 -0
  1029. package/dist/wxr-taxonomies-BHTdqkmZ.d.mts +34 -0
  1030. package/dist/wxr-taxonomies-BHTdqkmZ.d.mts.map +1 -0
  1031. package/dist/wxr-taxonomies-DP6ESgMN.mjs +372 -0
  1032. package/dist/wxr-taxonomies-DP6ESgMN.mjs.map +1 -0
  1033. package/dist/zod-generator-D6uE4WiS.mjs +389 -0
  1034. package/dist/zod-generator-D6uE4WiS.mjs.map +1 -0
  1035. package/package.json +6 -5
  1036. package/src/api/authorize.ts +17 -0
  1037. package/src/api/email-locale.ts +24 -0
  1038. package/src/api/errors.ts +16 -0
  1039. package/src/api/handlers/api-tokens.ts +18 -3
  1040. package/src/api/handlers/block-types.ts +129 -0
  1041. package/src/api/handlers/bulk-tag.ts +309 -0
  1042. package/src/api/handlers/comments.ts +0 -28
  1043. package/src/api/handlers/index.ts +10 -0
  1044. package/src/api/handlers/manifest.ts +8 -1
  1045. package/src/api/handlers/marketplace.ts +22 -16
  1046. package/src/api/handlers/media-usage.ts +31 -12
  1047. package/src/api/handlers/media.ts +19 -14
  1048. package/src/api/handlers/schema.ts +33 -8
  1049. package/src/api/handlers/settings.ts +2 -2
  1050. package/src/api/handlers/snapshot.ts +4 -0
  1051. package/src/api/handlers/taxonomies.ts +132 -83
  1052. package/src/api/handlers/transfer.ts +1347 -0
  1053. package/src/api/handlers/validate-media-fields.ts +124 -12
  1054. package/src/api/media-usage-write-fence.ts +5 -26
  1055. package/src/api/openapi/document.ts +614 -5
  1056. package/src/api/schemas/auth.ts +7 -1
  1057. package/src/api/schemas/common.ts +5 -0
  1058. package/src/api/schemas/content.ts +20 -1
  1059. package/src/api/schemas/media-usage.ts +11 -0
  1060. package/src/api/schemas/menus.ts +1 -1
  1061. package/src/api/schemas/schema.ts +117 -0
  1062. package/src/api/schemas/settings.ts +3 -3
  1063. package/src/api/schemas/taxonomies.ts +18 -0
  1064. package/src/api/schemas/transfer.ts +249 -0
  1065. package/src/api/transfer-download.ts +36 -0
  1066. package/src/api/types.ts +3 -0
  1067. package/src/astro/integration/routes.ts +31 -0
  1068. package/src/astro/integration/vite-config.ts +26 -0
  1069. package/src/astro/middleware/auth.ts +30 -7
  1070. package/src/astro/middleware/media-usage-write-fence.ts +106 -11
  1071. package/src/astro/middleware/request-context.ts +16 -2
  1072. package/src/astro/middleware.ts +38 -18
  1073. package/src/astro/routes/admin.astro +3 -1
  1074. package/src/astro/routes/api/admin/hooks/exclusive/index.ts +1 -5
  1075. package/src/astro/routes/api/admin/plugins/[id]/disable.ts +4 -3
  1076. package/src/astro/routes/api/admin/plugins/[id]/enable.ts +4 -3
  1077. package/src/astro/routes/api/admin/plugins/[id]/uninstall.ts +4 -3
  1078. package/src/astro/routes/api/admin/plugins/[id]/update.ts +4 -3
  1079. package/src/astro/routes/api/admin/plugins/marketplace/[id]/install.ts +4 -3
  1080. package/src/astro/routes/api/admin/plugins/registry/[id]/uninstall.ts +4 -3
  1081. package/src/astro/routes/api/admin/plugins/registry/[id]/update.ts +3 -3
  1082. package/src/astro/routes/api/admin/plugins/registry/install.ts +3 -3
  1083. package/src/astro/routes/api/admin/plugins/registry/publisher-handle.ts +59 -0
  1084. package/src/astro/routes/api/admin/transfer/[...path].ts +143 -0
  1085. package/src/astro/routes/api/admin/transfer/approvals/[id]/approve.ts +35 -0
  1086. package/src/astro/routes/api/admin/transfer/approvals/[id]/deny.ts +35 -0
  1087. package/src/astro/routes/api/admin/transfer/approvals/index.ts +33 -0
  1088. package/src/astro/routes/api/admin/transfer/capabilities.ts +36 -0
  1089. package/src/astro/routes/api/admin/transfer/exports/[id]/advance.ts +34 -0
  1090. package/src/astro/routes/api/admin/transfer/exports/[id]/archive.ts +35 -0
  1091. package/src/astro/routes/api/admin/transfer/exports/[id]/files/[...path].ts +40 -0
  1092. package/src/astro/routes/api/admin/transfer/exports/[id]/index.ts +25 -0
  1093. package/src/astro/routes/api/admin/transfer/exports/[id]/manifest.ts +38 -0
  1094. package/src/astro/routes/api/admin/transfer/exports/index.ts +64 -0
  1095. package/src/astro/routes/api/admin/transfer/imports/[id]/abandon.ts +28 -0
  1096. package/src/astro/routes/api/admin/transfer/imports/[id]/advance.ts +37 -0
  1097. package/src/astro/routes/api/admin/transfer/imports/[id]/analyze.ts +51 -0
  1098. package/src/astro/routes/api/admin/transfer/imports/[id]/cancel.ts +27 -0
  1099. package/src/astro/routes/api/admin/transfer/imports/[id]/execute.ts +48 -0
  1100. package/src/astro/routes/api/admin/transfer/imports/[id]/files/[...path].ts +54 -0
  1101. package/src/astro/routes/api/admin/transfer/imports/[id]/index.ts +25 -0
  1102. package/src/astro/routes/api/admin/transfer/imports/[id]/missing.ts +34 -0
  1103. package/src/astro/routes/api/admin/transfer/imports/[id]/plan.ts +29 -0
  1104. package/src/astro/routes/api/admin/transfer/imports/[id]/receipt.ts +25 -0
  1105. package/src/astro/routes/api/admin/transfer/imports/index.ts +85 -0
  1106. package/src/astro/routes/api/admin/users/[id]/send-recovery.ts +9 -1
  1107. package/src/astro/routes/api/auth/invite/index.ts +15 -1
  1108. package/src/astro/routes/api/auth/magic-link/send.ts +9 -1
  1109. package/src/astro/routes/api/auth/magic-link/verify.ts +37 -39
  1110. package/src/astro/routes/api/auth/passkey/options.ts +2 -21
  1111. package/src/astro/routes/api/content/[collection]/[id]/preview-url.ts +64 -13
  1112. package/src/astro/routes/api/content/[collection]/[id]/terms/[taxonomy].ts +16 -1
  1113. package/src/astro/routes/api/import/wordpress/rewrite-url-helpers.ts +11 -4
  1114. package/src/astro/routes/api/mcp.ts +1 -0
  1115. package/src/astro/routes/api/media/[id].ts +5 -15
  1116. package/src/astro/routes/api/media/file/[...key].ts +30 -5
  1117. package/src/astro/routes/api/oauth/authorize.ts +4 -0
  1118. package/src/astro/routes/api/schema/block-types/[slug]/index.ts +29 -0
  1119. package/src/astro/routes/api/schema/block-types/[slug]/versions/[version]/activate.ts +31 -0
  1120. package/src/astro/routes/api/schema/block-types/index.ts +29 -0
  1121. package/src/astro/routes/api/taxonomies/bulk-tag.ts +29 -0
  1122. package/src/astro/routes/api/typegen.ts +8 -4
  1123. package/src/astro/types.ts +4 -0
  1124. package/src/auth/api-tokens.ts +1 -0
  1125. package/src/auth/rate-limit.ts +2 -1
  1126. package/src/auth/scopes.ts +11 -0
  1127. package/src/cleanup.ts +14 -0
  1128. package/src/cli/client-factory.ts +6 -1
  1129. package/src/cli/commands/export-seed.ts +41 -15
  1130. package/src/cli/commands/seed.ts +6 -2
  1131. package/src/cli/commands/site.ts +556 -0
  1132. package/src/cli/index.ts +2 -0
  1133. package/src/cli/site/archive.ts +273 -0
  1134. package/src/cli/site/export.ts +311 -0
  1135. package/src/cli/site/import.ts +815 -0
  1136. package/src/cli/site/shared.ts +241 -0
  1137. package/src/client/index.ts +414 -11
  1138. package/src/client/portable-text.ts +41 -0
  1139. package/src/comments/public-submission.ts +19 -11
  1140. package/src/components/Blocks.astro +46 -0
  1141. package/src/components/Gallery.astro +2 -1
  1142. package/src/components/Image.astro +51 -6
  1143. package/src/components/InlinePortableTextEditor.tsx +28 -18
  1144. package/src/components/blocks.ts +44 -0
  1145. package/src/components/index.ts +14 -4
  1146. package/src/content/converters/gallery.ts +54 -16
  1147. package/src/content/converters/image-link.ts +27 -0
  1148. package/src/content/converters/index.ts +1 -0
  1149. package/src/content/converters/portable-text-to-prosemirror.ts +10 -7
  1150. package/src/content/converters/prosemirror-to-portable-text.ts +14 -0
  1151. package/src/content/converters/types.ts +17 -0
  1152. package/src/database/content-datetime.ts +19 -2
  1153. package/src/database/migrations/035_bounded_404_log.ts +28 -39
  1154. package/src/database/migrations/083_block_types.ts +58 -0
  1155. package/src/database/migrations/084_site_transfer.ts +264 -0
  1156. package/src/database/migrations/085_taxonomy_def_groups.ts +155 -0
  1157. package/src/database/migrations/runner.ts +6 -0
  1158. package/src/database/repositories/audit.ts +10 -1
  1159. package/src/database/repositories/byline.ts +4 -1
  1160. package/src/database/repositories/content.ts +83 -11
  1161. package/src/database/repositories/media-usage.ts +43 -13
  1162. package/src/database/repositories/media.ts +32 -1
  1163. package/src/database/repositories/options.ts +12 -0
  1164. package/src/database/repositories/revision.ts +6 -3
  1165. package/src/database/repositories/taxonomy-def.ts +126 -0
  1166. package/src/database/repositories/taxonomy.ts +65 -26
  1167. package/src/database/types.ts +133 -1
  1168. package/src/db/sqlite.ts +1 -1
  1169. package/src/emdash-runtime.ts +287 -51
  1170. package/src/import/utils.ts +8 -1
  1171. package/src/import/wxr-taxonomies.ts +11 -67
  1172. package/src/index.ts +26 -1
  1173. package/src/loader.ts +9 -5
  1174. package/src/mcp/server.ts +521 -29
  1175. package/src/mcp/transfer.ts +569 -0
  1176. package/src/media/local-runtime.ts +5 -18
  1177. package/src/media/upload-attempts.ts +5 -0
  1178. package/src/media/url.ts +15 -0
  1179. package/src/media/usage/content-fields.ts +69 -5
  1180. package/src/media/usage/content-refresh.ts +13 -66
  1181. package/src/media/usage/content-repair.ts +10 -2
  1182. package/src/media/usage/extractor.ts +74 -3
  1183. package/src/media/usage/projection-fingerprint.ts +14 -0
  1184. package/src/media/usage/schema-invalidation.ts +72 -0
  1185. package/src/media/usage/site-settings.ts +52 -0
  1186. package/src/media/usage/types.ts +2 -0
  1187. package/src/object-cache/index.ts +69 -4
  1188. package/src/plugin-test-runtime.ts +1 -0
  1189. package/src/plugins/context.ts +104 -56
  1190. package/src/plugins/cron.ts +6 -4
  1191. package/src/plugins/define-plugin.ts +11 -1
  1192. package/src/plugins/email-console.ts +2 -0
  1193. package/src/plugins/email.ts +16 -0
  1194. package/src/plugins/hooks.ts +33 -9
  1195. package/src/plugins/manifest-schema.ts +1 -0
  1196. package/src/plugins/route-error.ts +57 -0
  1197. package/src/plugins/routes.ts +5 -60
  1198. package/src/plugins/sandbox/types.ts +22 -2
  1199. package/src/plugins/types.ts +4 -0
  1200. package/src/registry/artifact-fetch.ts +17 -4
  1201. package/src/registry/publisher-handle.ts +273 -0
  1202. package/src/schema/block-type-contract.ts +478 -0
  1203. package/src/schema/block-type-registry.ts +689 -0
  1204. package/src/schema/block-types.ts +110 -0
  1205. package/src/schema/block-values.ts +293 -0
  1206. package/src/schema/byline-registry.ts +1 -1
  1207. package/src/schema/index.ts +28 -0
  1208. package/src/schema/registry.ts +462 -12
  1209. package/src/schema/types.ts +12 -1
  1210. package/src/schema/zod-generator.ts +92 -9
  1211. package/src/search/fts-manager.ts +40 -0
  1212. package/src/seed/apply.ts +173 -49
  1213. package/src/seed/types.ts +23 -3
  1214. package/src/seed/validate.ts +131 -7
  1215. package/src/settings/index.ts +32 -9
  1216. package/src/settings/types.ts +15 -0
  1217. package/src/taxonomies/index.ts +72 -83
  1218. package/src/transfer/analyze/index.ts +45 -0
  1219. package/src/transfer/analyze/issues.ts +55 -0
  1220. package/src/transfer/analyze/plan.ts +327 -0
  1221. package/src/transfer/analyze/read.ts +134 -0
  1222. package/src/transfer/analyze/step.ts +551 -0
  1223. package/src/transfer/analyze/target.ts +269 -0
  1224. package/src/transfer/analyze/unique-keys.ts +228 -0
  1225. package/src/transfer/analyze/validate.ts +1412 -0
  1226. package/src/transfer/analyze/values.ts +227 -0
  1227. package/src/transfer/analyze/write-rules.ts +196 -0
  1228. package/src/transfer/audit.ts +38 -0
  1229. package/src/transfer/auth.ts +25 -0
  1230. package/src/transfer/container/tar.ts +242 -0
  1231. package/src/transfer/domain.ts +248 -0
  1232. package/src/transfer/errors.ts +134 -0
  1233. package/src/transfer/export/exporter.ts +1067 -0
  1234. package/src/transfer/export/fence.ts +84 -0
  1235. package/src/transfer/export/media.ts +165 -0
  1236. package/src/transfer/export/readers.ts +1164 -0
  1237. package/src/transfer/export/verify.ts +677 -0
  1238. package/src/transfer/fence.ts +193 -0
  1239. package/src/transfer/format/canonical.ts +151 -0
  1240. package/src/transfer/format/column-codec.ts +275 -0
  1241. package/src/transfer/format/columns.ts +707 -0
  1242. package/src/transfer/format/digest.ts +287 -0
  1243. package/src/transfer/format/features.ts +91 -0
  1244. package/src/transfer/format/issues.ts +39 -0
  1245. package/src/transfer/format/kinds.ts +936 -0
  1246. package/src/transfer/format/limits.ts +87 -0
  1247. package/src/transfer/format/manifest.ts +297 -0
  1248. package/src/transfer/format/media-refs.ts +716 -0
  1249. package/src/transfer/format/paths.ts +73 -0
  1250. package/src/transfer/format/plan.ts +162 -0
  1251. package/src/transfer/format/receipt.ts +43 -0
  1252. package/src/transfer/format/records.ts +127 -0
  1253. package/src/transfer/format/settings.ts +94 -0
  1254. package/src/transfer/format/transformations.ts +260 -0
  1255. package/src/transfer/format/version.ts +9 -0
  1256. package/src/transfer/gc.ts +103 -0
  1257. package/src/transfer/import/advance.ts +522 -0
  1258. package/src/transfer/import/context.ts +281 -0
  1259. package/src/transfer/import/entries.ts +186 -0
  1260. package/src/transfer/import/ids.ts +40 -0
  1261. package/src/transfer/import/index.ts +15 -0
  1262. package/src/transfer/import/media.ts +141 -0
  1263. package/src/transfer/import/rebuild.ts +300 -0
  1264. package/src/transfer/import/rows.ts +114 -0
  1265. package/src/transfer/import/scaffold.ts +221 -0
  1266. package/src/transfer/import/sql.ts +134 -0
  1267. package/src/transfer/import/stages.ts +329 -0
  1268. package/src/transfer/import/writers.ts +370 -0
  1269. package/src/transfer/index.ts +472 -0
  1270. package/src/transfer/ops/approvals.ts +359 -0
  1271. package/src/transfer/ops/budget.ts +82 -0
  1272. package/src/transfer/ops/collation.ts +21 -0
  1273. package/src/transfer/ops/identity-map.ts +142 -0
  1274. package/src/transfer/ops/media-blobs.ts +135 -0
  1275. package/src/transfer/ops/operations.ts +842 -0
  1276. package/src/transfer/ops/package-index.ts +159 -0
  1277. package/src/transfer/ops/staged-files.ts +231 -0
  1278. package/src/transfer/ops/states.ts +265 -0
  1279. package/src/transfer/ops/time.ts +54 -0
  1280. package/src/transfer/schema-importer.ts +34 -0
  1281. package/src/transfer/site-id.ts +30 -0
  1282. package/src/transfer/staging/assembler.ts +217 -0
  1283. package/src/transfer/staging/keys.ts +94 -0
  1284. package/src/transfer/staging/package.ts +229 -0
  1285. package/src/transfer/staging/stage.ts +231 -0
  1286. package/src/ui.ts +19 -0
  1287. package/src/visual-editing/toolbar.ts +125 -37
  1288. package/dist/action-token-On1sot_c.mjs +0 -26
  1289. package/dist/action-token-On1sot_c.mjs.map +0 -1
  1290. package/dist/activation-CaMfdBt1.mjs +0 -382
  1291. package/dist/activation-CaMfdBt1.mjs.map +0 -1
  1292. package/dist/adapters-Cq10K4_c.d.mts +0 -171
  1293. package/dist/adapters-Cq10K4_c.d.mts.map +0 -1
  1294. package/dist/allowed-origins-1Sa-2wZK.mjs +0 -116
  1295. package/dist/allowed-origins-1Sa-2wZK.mjs.map +0 -1
  1296. package/dist/api-BB5BoQbN.mjs +0 -4831
  1297. package/dist/api-BB5BoQbN.mjs.map +0 -1
  1298. package/dist/api-tokens-BIXItFKV.mjs +0 -163
  1299. package/dist/api-tokens-BIXItFKV.mjs.map +0 -1
  1300. package/dist/api-tokens-DS1VzN7_.mjs +0 -3
  1301. package/dist/apply-CsKm_5S5.mjs +0 -1005
  1302. package/dist/apply-CsKm_5S5.mjs.map +0 -1
  1303. package/dist/artifact-fetch-COiMhVgk.mjs +0 -813
  1304. package/dist/artifact-fetch-COiMhVgk.mjs.map +0 -1
  1305. package/dist/authoritative-records-DbqshfKD.mjs +0 -5172
  1306. package/dist/authoritative-records-DbqshfKD.mjs.map +0 -1
  1307. package/dist/authorize-BXpfMpp0.mjs +0 -40
  1308. package/dist/authorize-BXpfMpp0.mjs.map +0 -1
  1309. package/dist/backup-B4tByjBb.mjs +0 -246
  1310. package/dist/backup-B4tByjBb.mjs.map +0 -1
  1311. package/dist/byline-C8ndlnP0.mjs +0 -906
  1312. package/dist/byline-C8ndlnP0.mjs.map +0 -1
  1313. package/dist/byline-fields-CsrdvaLV.mjs +0 -123
  1314. package/dist/byline-fields-CsrdvaLV.mjs.map +0 -1
  1315. package/dist/byline-registry-D6lWzXk6.mjs +0 -406
  1316. package/dist/byline-registry-D6lWzXk6.mjs.map +0 -1
  1317. package/dist/bylines-CHP44GkL.mjs +0 -232
  1318. package/dist/bylines-CHP44GkL.mjs.map +0 -1
  1319. package/dist/bylines-DxjM4Usz.mjs +0 -214
  1320. package/dist/bylines-DxjM4Usz.mjs.map +0 -1
  1321. package/dist/cache-BByLKGPu.mjs +0 -108
  1322. package/dist/cache-BByLKGPu.mjs.map +0 -1
  1323. package/dist/capture-triggers-gxQxnxrJ.mjs +0 -362
  1324. package/dist/capture-triggers-gxQxnxrJ.mjs.map +0 -1
  1325. package/dist/challenge-store-CkRdSdd8.mjs +0 -51
  1326. package/dist/challenge-store-CkRdSdd8.mjs.map +0 -1
  1327. package/dist/checksum-Bsi2D9M1.mjs +0 -162
  1328. package/dist/checksum-Bsi2D9M1.mjs.map +0 -1
  1329. package/dist/chrome-tags-D7LGB91U.mjs +0 -24
  1330. package/dist/chrome-tags-D7LGB91U.mjs.map +0 -1
  1331. package/dist/chunks-DUK-cWXi.mjs +0 -25
  1332. package/dist/chunks-DUK-cWXi.mjs.map +0 -1
  1333. package/dist/collection-deletion-C-yQB9fq.mjs +0 -436
  1334. package/dist/collection-deletion-C-yQB9fq.mjs.map +0 -1
  1335. package/dist/collection-slugs-cache-D9auiKmI.mjs +0 -85
  1336. package/dist/collection-slugs-cache-D9auiKmI.mjs.map +0 -1
  1337. package/dist/comment-DcT8qdPK.mjs +0 -313
  1338. package/dist/comment-DcT8qdPK.mjs.map +0 -1
  1339. package/dist/comment-reaction-B6KHCLYK.mjs +0 -85
  1340. package/dist/comment-reaction-B6KHCLYK.mjs.map +0 -1
  1341. package/dist/comments-B67VRNGw.mjs +0 -204
  1342. package/dist/comments-B67VRNGw.mjs.map +0 -1
  1343. package/dist/comments-BVzzt6x5.mjs +0 -99
  1344. package/dist/comments-BVzzt6x5.mjs.map +0 -1
  1345. package/dist/components-DIl9Qzh6.mjs +0 -108
  1346. package/dist/components-DIl9Qzh6.mjs.map +0 -1
  1347. package/dist/config-B2acLeC5.mjs +0 -242
  1348. package/dist/config-B2acLeC5.mjs.map +0 -1
  1349. package/dist/config-CGVeT8Hc.mjs +0 -73
  1350. package/dist/config-CGVeT8Hc.mjs.map +0 -1
  1351. package/dist/config-Cw1Xz_Br.d.mts +0 -6387
  1352. package/dist/config-Cw1Xz_Br.d.mts.map +0 -1
  1353. package/dist/config-D3HhLON3.d.mts +0 -39
  1354. package/dist/config-D3HhLON3.d.mts.map +0 -1
  1355. package/dist/content-C0Hl3ktM.mjs +0 -2216
  1356. package/dist/content-C0Hl3ktM.mjs.map +0 -1
  1357. package/dist/content-list-query-CbPdzsna.d.mts +0 -26
  1358. package/dist/content-list-query-CbPdzsna.d.mts.map +0 -1
  1359. package/dist/content-policy-CM4skrNi.mjs +0 -46
  1360. package/dist/content-policy-CM4skrNi.mjs.map +0 -1
  1361. package/dist/content-refresh-iRBhQHr5.mjs +0 -3599
  1362. package/dist/content-refresh-iRBhQHr5.mjs.map +0 -1
  1363. package/dist/content-repair-8uHRIJkd.mjs +0 -440
  1364. package/dist/content-repair-8uHRIJkd.mjs.map +0 -1
  1365. package/dist/context-DJP3aNeR.mjs +0 -1835
  1366. package/dist/context-DJP3aNeR.mjs.map +0 -1
  1367. package/dist/cron-BcR3RN4K.mjs +0 -282
  1368. package/dist/cron-BcR3RN4K.mjs.map +0 -1
  1369. package/dist/dashboard-B0s6QKgi.mjs +0 -151
  1370. package/dist/dashboard-B0s6QKgi.mjs.map +0 -1
  1371. package/dist/default-BtlxWgh9.mjs +0 -81
  1372. package/dist/default-BtlxWgh9.mjs.map +0 -1
  1373. package/dist/deferred-tasks-Ba9fphlE.d.mts +0 -9
  1374. package/dist/deferred-tasks-Ba9fphlE.d.mts.map +0 -1
  1375. package/dist/device-flow-3E5l0fpH.mjs +0 -466
  1376. package/dist/device-flow-3E5l0fpH.mjs.map +0 -1
  1377. package/dist/dialect-helpers-CtYdsX4W.mjs +0 -307
  1378. package/dist/dialect-helpers-CtYdsX4W.mjs.map +0 -1
  1379. package/dist/direct-executor-CDr1quOq.mjs +0 -104
  1380. package/dist/direct-executor-CDr1quOq.mjs.map +0 -1
  1381. package/dist/dist-2hDLsLeq.mjs +0 -810
  1382. package/dist/dist-2hDLsLeq.mjs.map +0 -1
  1383. package/dist/email-console-gc-E3Eqj.mjs +0 -50
  1384. package/dist/email-console-gc-E3Eqj.mjs.map +0 -1
  1385. package/dist/emdash-runtime-CxxL05Z0.mjs +0 -4041
  1386. package/dist/emdash-runtime-CxxL05Z0.mjs.map +0 -1
  1387. package/dist/enrich-C2Mk0lwE.mjs +0 -194
  1388. package/dist/enrich-C2Mk0lwE.mjs.map +0 -1
  1389. package/dist/entry-lock-CwWdnFyR.mjs +0 -1520
  1390. package/dist/entry-lock-CwWdnFyR.mjs.map +0 -1
  1391. package/dist/entry-lock-D9rnj2Lu.mjs +0 -163
  1392. package/dist/entry-lock-D9rnj2Lu.mjs.map +0 -1
  1393. package/dist/entry-lock-DqkvBC6L.d.mts +0 -3503
  1394. package/dist/entry-lock-DqkvBC6L.d.mts.map +0 -1
  1395. package/dist/entry-locks-CO_KaoU5.mjs +0 -167
  1396. package/dist/entry-locks-CO_KaoU5.mjs.map +0 -1
  1397. package/dist/error-CCTCskie.mjs +0 -90
  1398. package/dist/error-CCTCskie.mjs.map +0 -1
  1399. package/dist/errors-W3PA8HqB.mjs +0 -447
  1400. package/dist/errors-W3PA8HqB.mjs.map +0 -1
  1401. package/dist/escape-DN4Qmjsl.mjs +0 -9
  1402. package/dist/escape-DN4Qmjsl.mjs.map +0 -1
  1403. package/dist/field-defs-cache-Db0pJgqn.mjs +0 -77
  1404. package/dist/field-defs-cache-Db0pJgqn.mjs.map +0 -1
  1405. package/dist/fts-manager-CjX0e5BR.mjs +0 -413
  1406. package/dist/fts-manager-CjX0e5BR.mjs.map +0 -1
  1407. package/dist/hash-CLVFzWvx.mjs +0 -37
  1408. package/dist/hash-CLVFzWvx.mjs.map +0 -1
  1409. package/dist/hook-result-KY1jq21o.d.mts +0 -31
  1410. package/dist/hook-result-KY1jq21o.d.mts.map +0 -1
  1411. package/dist/hreflang-BgS2FqhH.d.mts +0 -50
  1412. package/dist/hreflang-BgS2FqhH.d.mts.map +0 -1
  1413. package/dist/hreflang-DOQeTXpg.mjs +0 -105
  1414. package/dist/hreflang-DOQeTXpg.mjs.map +0 -1
  1415. package/dist/http-route-dispatch-MCVKiQCl.mjs +0 -339
  1416. package/dist/http-route-dispatch-MCVKiQCl.mjs.map +0 -1
  1417. package/dist/identity-vFbpuwfY.mjs +0 -35
  1418. package/dist/identity-vFbpuwfY.mjs.map +0 -1
  1419. package/dist/import-got6I69S.mjs +0 -2020
  1420. package/dist/import-got6I69S.mjs.map +0 -1
  1421. package/dist/index-CDwKDkTq.d.mts +0 -623
  1422. package/dist/index-CDwKDkTq.d.mts.map +0 -1
  1423. package/dist/install-finalization-5Os-QZ-2.mjs +0 -58
  1424. package/dist/install-finalization-5Os-QZ-2.mjs.map +0 -1
  1425. package/dist/lifecycle-7e-Lt_kX.mjs +0 -25
  1426. package/dist/lifecycle-7e-Lt_kX.mjs.map +0 -1
  1427. package/dist/load-C56XiwbV.mjs +0 -28
  1428. package/dist/load-C56XiwbV.mjs.map +0 -1
  1429. package/dist/loader-xhNQiT9T.mjs +0 -1004
  1430. package/dist/loader-xhNQiT9T.mjs.map +0 -1
  1431. package/dist/manifest-builder-Bz3nxVET.mjs +0 -189
  1432. package/dist/manifest-builder-Bz3nxVET.mjs.map +0 -1
  1433. package/dist/manifest-schema-Bkh8SeHd.mjs +0 -491
  1434. package/dist/manifest-schema-Bkh8SeHd.mjs.map +0 -1
  1435. package/dist/media-TBlKCwo7.mjs +0 -334
  1436. package/dist/media-TBlKCwo7.mjs.map +0 -1
  1437. package/dist/media-allowlist-s60eAIf6.mjs +0 -44
  1438. package/dist/media-allowlist-s60eAIf6.mjs.map +0 -1
  1439. package/dist/media-folders-ClIRLUQv.mjs +0 -210
  1440. package/dist/media-folders-ClIRLUQv.mjs.map +0 -1
  1441. package/dist/media-url-DY_ijO3B.mjs +0 -43
  1442. package/dist/media-url-DY_ijO3B.mjs.map +0 -1
  1443. package/dist/media-usage-Bd9rFPKN.mjs +0 -1833
  1444. package/dist/media-usage-Bd9rFPKN.mjs.map +0 -1
  1445. package/dist/media-usage-activation-CAhmb14O.mjs +0 -78
  1446. package/dist/media-usage-activation-CAhmb14O.mjs.map +0 -1
  1447. package/dist/media-usage-work-BPlRMOJv.mjs +0 -152
  1448. package/dist/media-usage-work-BPlRMOJv.mjs.map +0 -1
  1449. package/dist/media-usage-work-Cu5DqewW.mjs +0 -586
  1450. package/dist/media-usage-work-Cu5DqewW.mjs.map +0 -1
  1451. package/dist/media-usage-write-fence-DW5oHT7q.mjs +0 -42
  1452. package/dist/media-usage-write-fence-DW5oHT7q.mjs.map +0 -1
  1453. package/dist/menus-BUQdvXep.mjs +0 -3732
  1454. package/dist/menus-BUQdvXep.mjs.map +0 -1
  1455. package/dist/menus-DgSUodmF.mjs +0 -753
  1456. package/dist/menus-DgSUodmF.mjs.map +0 -1
  1457. package/dist/mime-CCYRC4r1.mjs +0 -36
  1458. package/dist/mime-CCYRC4r1.mjs.map +0 -1
  1459. package/dist/mode-CkmOhFqj.mjs +0 -23
  1460. package/dist/mode-CkmOhFqj.mjs.map +0 -1
  1461. package/dist/node-sqlite-compat-vpVaILnb.mjs +0 -46
  1462. package/dist/node-sqlite-compat-vpVaILnb.mjs.map +0 -1
  1463. package/dist/normalize-dChXQjwS.mjs +0 -191
  1464. package/dist/normalize-dChXQjwS.mjs.map +0 -1
  1465. package/dist/oauth-authorization-DZ-R-hmx.mjs +0 -274
  1466. package/dist/oauth-authorization-DZ-R-hmx.mjs.map +0 -1
  1467. package/dist/oauth-clients-BMPA8vjl.mjs +0 -266
  1468. package/dist/oauth-clients-BMPA8vjl.mjs.map +0 -1
  1469. package/dist/oauth-state-store-0gIdb48-.mjs +0 -50
  1470. package/dist/oauth-state-store-0gIdb48-.mjs.map +0 -1
  1471. package/dist/oauth-user-lookup-ChVW4UWu.mjs +0 -26
  1472. package/dist/oauth-user-lookup-ChVW4UWu.mjs.map +0 -1
  1473. package/dist/object-cache-DlSVbn5Y.mjs +0 -534
  1474. package/dist/object-cache-DlSVbn5Y.mjs.map +0 -1
  1475. package/dist/options-D5WcorD5.mjs +0 -200
  1476. package/dist/options-D5WcorD5.mjs.map +0 -1
  1477. package/dist/options-DAknChnw.d.mts +0 -77
  1478. package/dist/options-DAknChnw.d.mts.map +0 -1
  1479. package/dist/parse-Cr379Av9.mjs +0 -81
  1480. package/dist/parse-Cr379Av9.mjs.map +0 -1
  1481. package/dist/parse-tj9XLNO_.d.mts +0 -165
  1482. package/dist/parse-tj9XLNO_.d.mts.map +0 -1
  1483. package/dist/passkey-config-BD-wMaCf.mjs +0 -46
  1484. package/dist/passkey-config-BD-wMaCf.mjs.map +0 -1
  1485. package/dist/patterns-Do3iqi7N.mjs +0 -145
  1486. package/dist/patterns-Do3iqi7N.mjs.map +0 -1
  1487. package/dist/placeholder-CubPFn_L.d.mts +0 -306
  1488. package/dist/placeholder-CubPFn_L.d.mts.map +0 -1
  1489. package/dist/plugins-DHurtdXQ.mjs +0 -277
  1490. package/dist/plugins-DHurtdXQ.mjs.map +0 -1
  1491. package/dist/policy-pL9QLKZm.mjs +0 -45
  1492. package/dist/policy-pL9QLKZm.mjs.map +0 -1
  1493. package/dist/portable-text-oAwodbPS.mjs +0 -286
  1494. package/dist/portable-text-oAwodbPS.mjs.map +0 -1
  1495. package/dist/preview-Cup2bj8c.mjs +0 -107
  1496. package/dist/preview-Cup2bj8c.mjs.map +0 -1
  1497. package/dist/protocol-C1CNiKX4.d.mts +0 -61
  1498. package/dist/protocol-C1CNiKX4.d.mts.map +0 -1
  1499. package/dist/public-submission-Cs-pFMQK.mjs +0 -245
  1500. package/dist/public-submission-Cs-pFMQK.mjs.map +0 -1
  1501. package/dist/public-url-BWVHsfQv.mjs +0 -101
  1502. package/dist/public-url-BWVHsfQv.mjs.map +0 -1
  1503. package/dist/query-CxnFU6sz.mjs +0 -890
  1504. package/dist/query-CxnFU6sz.mjs.map +0 -1
  1505. package/dist/query-sgHYEgBW.mjs +0 -41
  1506. package/dist/query-sgHYEgBW.mjs.map +0 -1
  1507. package/dist/rate-limit-CqJn-w4h.mjs +0 -120
  1508. package/dist/rate-limit-CqJn-w4h.mjs.map +0 -1
  1509. package/dist/redirect-BrChFPIu.mjs +0 -17
  1510. package/dist/redirect-BrChFPIu.mjs.map +0 -1
  1511. package/dist/redirect-D2Yo-b6S.mjs +0 -415
  1512. package/dist/redirect-D2Yo-b6S.mjs.map +0 -1
  1513. package/dist/redirects-BCiTaIQ-.mjs +0 -146
  1514. package/dist/redirects-BCiTaIQ-.mjs.map +0 -1
  1515. package/dist/redirects-CAoL3r26.mjs +0 -644
  1516. package/dist/redirects-CAoL3r26.mjs.map +0 -1
  1517. package/dist/registry-xKzE-_m5.mjs +0 -1222
  1518. package/dist/registry-xKzE-_m5.mjs.map +0 -1
  1519. package/dist/relation-ClsWcYg2.mjs +0 -334
  1520. package/dist/relation-ClsWcYg2.mjs.map +0 -1
  1521. package/dist/relations-B4w-G5U9.mjs +0 -309
  1522. package/dist/relations-B4w-G5U9.mjs.map +0 -1
  1523. package/dist/relations-C3Td_mct.mjs +0 -403
  1524. package/dist/relations-C3Td_mct.mjs.map +0 -1
  1525. package/dist/request-cache-DaMhSQdx.mjs +0 -104
  1526. package/dist/request-cache-DaMhSQdx.mjs.map +0 -1
  1527. package/dist/request-meta-C8yl_sIs.mjs +0 -141
  1528. package/dist/request-meta-C8yl_sIs.mjs.map +0 -1
  1529. package/dist/resolve-BJIS8wKr.mjs +0 -199
  1530. package/dist/resolve-BJIS8wKr.mjs.map +0 -1
  1531. package/dist/route-wire-D66L2oaZ.mjs +0 -197
  1532. package/dist/route-wire-D66L2oaZ.mjs.map +0 -1
  1533. package/dist/routes-CWzxcZpn.mjs +0 -321
  1534. package/dist/routes-CWzxcZpn.mjs.map +0 -1
  1535. package/dist/runner-3gfxRsJG.d.mts +0 -68
  1536. package/dist/runner-3gfxRsJG.d.mts.map +0 -1
  1537. package/dist/runner-CIltKk4i.mjs +0 -5502
  1538. package/dist/runner-CIltKk4i.mjs.map +0 -1
  1539. package/dist/schema-DQIE9Htn.mjs +0 -420
  1540. package/dist/schema-DQIE9Htn.mjs.map +0 -1
  1541. package/dist/schema-ILPFMPW3.mjs +0 -9
  1542. package/dist/schema-ILPFMPW3.mjs.map +0 -1
  1543. package/dist/scopes-Bn8_rCSt.mjs +0 -27
  1544. package/dist/scopes-Bn8_rCSt.mjs.map +0 -1
  1545. package/dist/search-D6muneha.mjs +0 -448
  1546. package/dist/search-D6muneha.mjs.map +0 -1
  1547. package/dist/secrets-DNgVgz_e.mjs +0 -341
  1548. package/dist/secrets-DNgVgz_e.mjs.map +0 -1
  1549. package/dist/sections-BPCEGYWd.mjs +0 -346
  1550. package/dist/sections-BPCEGYWd.mjs.map +0 -1
  1551. package/dist/seo-BtU70b7l.mjs +0 -114
  1552. package/dist/seo-BtU70b7l.mjs.map +0 -1
  1553. package/dist/seo-rCk6pDwT.mjs +0 -133
  1554. package/dist/seo-rCk6pDwT.mjs.map +0 -1
  1555. package/dist/service-Bpy5iTX0.mjs +0 -150
  1556. package/dist/service-Bpy5iTX0.mjs.map +0 -1
  1557. package/dist/session-user-BQeS2Mrb.mjs +0 -51
  1558. package/dist/session-user-BQeS2Mrb.mjs.map +0 -1
  1559. package/dist/settings-CsoLiwpL.mjs +0 -420
  1560. package/dist/settings-CsoLiwpL.mjs.map +0 -1
  1561. package/dist/settings-DCnWtfSZ.mjs +0 -51
  1562. package/dist/settings-DCnWtfSZ.mjs.map +0 -1
  1563. package/dist/setup-complete-BrZaXpVV.mjs +0 -26
  1564. package/dist/setup-complete-BrZaXpVV.mjs.map +0 -1
  1565. package/dist/setup-nonce-Cb9-884O.mjs +0 -25
  1566. package/dist/setup-nonce-Cb9-884O.mjs.map +0 -1
  1567. package/dist/site-url-DjhYCaep.mjs +0 -16
  1568. package/dist/site-url-DjhYCaep.mjs.map +0 -1
  1569. package/dist/snapshot-C32Xuv3o.mjs +0 -233
  1570. package/dist/snapshot-C32Xuv3o.mjs.map +0 -1
  1571. package/dist/ssrf-Co1GGFZz.mjs +0 -406
  1572. package/dist/ssrf-Co1GGFZz.mjs.map +0 -1
  1573. package/dist/state-C7gCoiHr.mjs +0 -153
  1574. package/dist/state-C7gCoiHr.mjs.map +0 -1
  1575. package/dist/status-DLoBmcDz.mjs +0 -30
  1576. package/dist/status-DLoBmcDz.mjs.map +0 -1
  1577. package/dist/storage-query-CPctdMKX.d.mts +0 -1519
  1578. package/dist/storage-query-CPctdMKX.d.mts.map +0 -1
  1579. package/dist/target-CUKlGrXb.mjs +0 -27
  1580. package/dist/target-CUKlGrXb.mjs.map +0 -1
  1581. package/dist/taxonomies-Bs5dJVDJ.mjs +0 -899
  1582. package/dist/taxonomies-Bs5dJVDJ.mjs.map +0 -1
  1583. package/dist/taxonomies-DjGU22ur.mjs +0 -707
  1584. package/dist/taxonomies-DjGU22ur.mjs.map +0 -1
  1585. package/dist/taxonomy-c1Q8PMFF.mjs +0 -508
  1586. package/dist/taxonomy-c1Q8PMFF.mjs.map +0 -1
  1587. package/dist/tokens-Ns02GAma.mjs +0 -171
  1588. package/dist/tokens-Ns02GAma.mjs.map +0 -1
  1589. package/dist/transport-B8P1xsqk.mjs +0 -136
  1590. package/dist/transport-B8P1xsqk.mjs.map +0 -1
  1591. package/dist/transport-BLHZZcD_.d.mts +0 -42
  1592. package/dist/transport-BLHZZcD_.d.mts.map +0 -1
  1593. package/dist/trusted-proxy-Cg7SuD15.mjs +0 -51
  1594. package/dist/trusted-proxy-Cg7SuD15.mjs.map +0 -1
  1595. package/dist/turnstile-DWCSh_Qc.mjs +0 -53
  1596. package/dist/turnstile-DWCSh_Qc.mjs.map +0 -1
  1597. package/dist/types-B3RkqvDW.mjs +0 -156
  1598. package/dist/types-B3RkqvDW.mjs.map +0 -1
  1599. package/dist/types-BtuppOTV.mjs +0 -16
  1600. package/dist/types-BtuppOTV.mjs.map +0 -1
  1601. package/dist/types-CCR3ivXE.d.mts +0 -363
  1602. package/dist/types-CCR3ivXE.d.mts.map +0 -1
  1603. package/dist/types-CSHgU_-_.mjs +0 -18
  1604. package/dist/types-CSHgU_-_.mjs.map +0 -1
  1605. package/dist/types-CbwqGOXm.d.mts +0 -766
  1606. package/dist/types-CbwqGOXm.d.mts.map +0 -1
  1607. package/dist/types-D4RGIc2I.d.mts +0 -198
  1608. package/dist/types-D4RGIc2I.d.mts.map +0 -1
  1609. package/dist/types-DEHidMEk.d.mts +0 -1637
  1610. package/dist/types-DEHidMEk.d.mts.map +0 -1
  1611. package/dist/types-DQeU2SR7.d.mts +0 -279
  1612. package/dist/types-DQeU2SR7.d.mts.map +0 -1
  1613. package/dist/types-DxQWoQLA.d.mts +0 -264
  1614. package/dist/types-DxQWoQLA.d.mts.map +0 -1
  1615. package/dist/types-FBBnGZ2Y.d.mts +0 -198
  1616. package/dist/types-FBBnGZ2Y.d.mts.map +0 -1
  1617. package/dist/types-ZCnlropY.mjs +0 -69
  1618. package/dist/types-ZCnlropY.mjs.map +0 -1
  1619. package/dist/types-_Qtyawiy.d.mts +0 -124
  1620. package/dist/types-_Qtyawiy.d.mts.map +0 -1
  1621. package/dist/types-gC6FAoa_.d.mts +0 -75
  1622. package/dist/types-gC6FAoa_.d.mts.map +0 -1
  1623. package/dist/types-k--LneIF.mjs +0 -22
  1624. package/dist/types-k--LneIF.mjs.map +0 -1
  1625. package/dist/upload-attempts-2xdnoKGe.mjs +0 -27
  1626. package/dist/upload-attempts-2xdnoKGe.mjs.map +0 -1
  1627. package/dist/url-pattern-3m3reMzr.mjs +0 -33
  1628. package/dist/url-pattern-3m3reMzr.mjs.map +0 -1
  1629. package/dist/user-2R1gceFl.mjs +0 -171
  1630. package/dist/user-2R1gceFl.mjs.map +0 -1
  1631. package/dist/utils-CC2oNGV8.mjs +0 -435
  1632. package/dist/utils-CC2oNGV8.mjs.map +0 -1
  1633. package/dist/validate-CaFSi_Wa.mjs +0 -384
  1634. package/dist/validate-CaFSi_Wa.mjs.map +0 -1
  1635. package/dist/validate-CyQ7I3xF.d.mts +0 -410
  1636. package/dist/validate-CyQ7I3xF.d.mts.map +0 -1
  1637. package/dist/validation-nsX2uixg.mjs +0 -216
  1638. package/dist/validation-nsX2uixg.mjs.map +0 -1
  1639. package/dist/version-DGh4SL8e.mjs +0 -7
  1640. package/dist/version-DGh4SL8e.mjs.map +0 -1
  1641. package/dist/widgets-B7ued6f5.mjs +0 -126
  1642. package/dist/widgets-B7ued6f5.mjs.map +0 -1
  1643. package/dist/wxr-taxonomies-BtH3jYSg.mjs +0 -406
  1644. package/dist/wxr-taxonomies-BtH3jYSg.mjs.map +0 -1
  1645. package/dist/wxr-taxonomies-DU2ZSiGc.d.mts +0 -34
  1646. package/dist/wxr-taxonomies-DU2ZSiGc.d.mts.map +0 -1
  1647. package/dist/zod-generator-DuBjYyrI.mjs +0 -329
  1648. package/dist/zod-generator-DuBjYyrI.mjs.map +0 -1
  1649. /package/dist/{ssrf-BRpTDMV6.mjs → ssrf-DpBH7aOt.mjs} +0 -0
@@ -1,19 +1,25 @@
1
- import "../../../../../config-CGVeT8Hc.mjs";
1
+ import "../../../../../config-CvmjJcVw.mjs";
2
2
  import "../../../../../base64-DvnNgP7e.mjs";
3
3
  import "../../../../../types-BkUg2yHx.mjs";
4
- import { t as MediaRepository } from "../../../../../media-TBlKCwo7.mjs";
5
- import "../../../../../dist-2hDLsLeq.mjs";
6
- import { t as enrichImageMetadata } from "../../../../../enrich-C2Mk0lwE.mjs";
7
- import { n as computeContentHash, t as MAX_CONTENT_HASH_BYTES } from "../../../../../hash-CLVFzWvx.mjs";
8
- import { n as apiSuccess, r as handleError, t as apiError } from "../../../../../error-CCTCskie.mjs";
9
- import { r as parseOptionalBody, t as isParseError } from "../../../../../parse-Cr379Av9.mjs";
10
- import "../../../../../redirects-BCiTaIQ-.mjs";
11
- import { Mt as mediaConfirmBody } from "../../../../../entry-lock-CwWdnFyR.mjs";
12
- import "../../../../../comments-BVzzt6x5.mjs";
13
- import "../../../../../relations-B4w-G5U9.mjs";
14
- import "../../../../../status-DLoBmcDz.mjs";
4
+ import { t as MediaRepository } from "../../../../../media-Qp5S3eH3.mjs";
5
+ import "../../../../../dist-BNwANFJR.mjs";
6
+ import { t as enrichImageMetadata } from "../../../../../enrich-Dl3kZ-lP.mjs";
7
+ import "../../../../../errors-DgE1zJGG.mjs";
8
+ import { n as computeContentHash, t as MAX_CONTENT_HASH_BYTES } from "../../../../../hash-SDAW6zC-.mjs";
9
+ import "../../../../../settings-DYidIB26.mjs";
10
+ import "../../../../../site-settings-DOgRUoFX.mjs";
11
+ import "../../../../../errors-BF0_LFhW.mjs";
12
+ import { n as apiSuccess, r as handleError, t as apiError } from "../../../../../error-CfvOHP0M.mjs";
13
+ import { r as parseOptionalBody, t as isParseError } from "../../../../../parse-DY6OD1j_.mjs";
14
+ import "../../../../../redirects-Cv9apQKj.mjs";
15
+ import "../../../../../entry-lock-BJYdBfXb.mjs";
16
+ import { i as mediaConfirmBody } from "../../../../../media-Pu1L6xir.mjs";
17
+ import "../../../../../comments-fHZ8ON9O.mjs";
18
+ import "../../../../../relations-CK9CYUyr.mjs";
19
+ import "../../../../../menus-BM7BPLOb.mjs";
20
+ import "../../../../../status-DZKIG4a9.mjs";
15
21
  import "../../../../../api/schemas/index.mjs";
16
- import { n as requireOwnerPerm, r as requirePerm } from "../../../../../authorize-BXpfMpp0.mjs";
22
+ import { i as requirePerm, r as requireOwnerPerm } from "../../../../../authorize-seCifOMJ.mjs";
17
23
 
18
24
  //#region src/astro/routes/api/media/[id]/confirm.ts
19
25
  const prerender = false;
@@ -1 +1 @@
1
- {"version":3,"file":"confirm.mjs","names":[],"sources":["../../../../../../src/astro/routes/api/media/[id]/confirm.ts"],"sourcesContent":["/**\n * Confirm media upload endpoint\n *\n * POST /_emdash/api/media/{id}/confirm\n *\n * Confirms that the client has successfully uploaded the file to storage.\n * Marks the media record as ready and optionally updates metadata.\n */\n\nimport type { APIRoute } from \"astro\";\nimport type { DownloadResult } from \"emdash\";\n\nimport { requireOwnerPerm, requirePerm } from \"#api/authorize.js\";\nimport { apiError, apiSuccess, handleError } from \"#api/error.js\";\nimport { isParseError, parseOptionalBody } from \"#api/parse.js\";\nimport { mediaConfirmBody } from \"#api/schemas.js\";\nimport { MediaRepository } from \"#db/repositories/media.js\";\nimport { enrichImageMetadata } from \"#media/enrich.js\";\nimport type { MediaItem } from \"#types\";\nimport { computeContentHash, MAX_CONTENT_HASH_BYTES } from \"#utils/hash.js\";\n\nexport const prerender = false;\n\n/**\n * Max raw bytes to buffer for server-side LQIP generation at confirm time. The\n * signed-URL upload flow exists so large files bypass server buffering — re-reading\n * the whole object into a Worker's 128 MB heap to compute a blurhash would OOM\n * on the very uploads that flow was designed for. LQIP is progressive\n * enhancement: large images simply ship without a server-generated placeholder.\n */\nconst MAX_PLACEHOLDER_DOWNLOAD_BYTES = MAX_CONTENT_HASH_BYTES;\n\n/**\n * Add URL to media item (relative URL for portability)\n */\nfunction addUrlToMedia(item: MediaItem): MediaItem & { url: string } {\n\treturn {\n\t\t...item,\n\t\turl: `/_emdash/api/media/file/${item.storageKey}`,\n\t};\n}\n\nasync function cancelDownload(download: DownloadResult): Promise<void> {\n\ttry {\n\t\tawait download.body.cancel();\n\t} catch (error) {\n\t\tconsole.error(\"[media] confirm download cancellation failed:\", error);\n\t}\n}\n\nasync function forgetUploadAttempt(repo: MediaRepository, storageKey: string): Promise<void> {\n\ttry {\n\t\tawait repo.deleteUploadAttempt(storageKey);\n\t} catch (error) {\n\t\tconsole.error(\"[media] confirm upload attempt cleanup failed:\", error);\n\t}\n}\n\nasync function confirmationConflict(repo: MediaRepository, id: string): Promise<Response> {\n\tconst current = await repo.findById(id);\n\tif (!current) {\n\t\treturn apiError(\"NOT_FOUND\", `Media item not found: ${id}`, 404);\n\t}\n\tif (current.status === \"ready\") {\n\t\tawait forgetUploadAttempt(repo, current.storageKey);\n\t\treturn apiSuccess({ item: addUrlToMedia(current) });\n\t}\n\tif (current.status === \"pending\") {\n\t\treturn apiError(\"INVALID_STATE\", \"Media item changed during confirmation\", 409);\n\t}\n\treturn apiError(\"INVALID_STATE\", `Media item is not pending: ${current.status}`, 400);\n}\n\nasync function consumeDownload(download: DownloadResult): Promise<Uint8Array> {\n\tconst reader = download.body.getReader();\n\ttry {\n\t\tconst bytes = new Uint8Array(download.size);\n\t\tlet receivedSize = 0;\n\t\twhile (true) {\n\t\t\tconst { done, value } = await reader.read();\n\t\t\tif (done) break;\n\t\t\tif (receivedSize + value.byteLength > bytes.byteLength) {\n\t\t\t\tthrow new Error(\"Stored file exceeds its reported size\");\n\t\t\t}\n\t\t\tbytes.set(value, receivedSize);\n\t\t\treceivedSize += value.byteLength;\n\t\t}\n\t\tif (receivedSize !== download.size) {\n\t\t\tthrow new Error(\"Stored file size does not match its reported size\");\n\t\t}\n\t\treturn bytes;\n\t} catch (error) {\n\t\ttry {\n\t\t\tawait reader.cancel(error);\n\t\t} catch (cancelError) {\n\t\t\tconsole.error(\"[media] confirm download cancellation failed:\", cancelError);\n\t\t}\n\t\tthrow error;\n\t} finally {\n\t\treader.releaseLock();\n\t}\n}\n\n/**\n * Confirm upload completion\n */\nexport const POST: APIRoute = async ({ params, request, locals }) => {\n\tconst { emdash, user } = locals;\n\tconst { id } = params;\n\n\tconst denied = requirePerm(user, \"media:upload\");\n\tif (denied) return denied;\n\n\tif (!id) {\n\t\treturn apiError(\"INVALID_REQUEST\", \"Media ID is required\", 400);\n\t}\n\n\tif (!emdash?.db) {\n\t\treturn apiError(\"NOT_CONFIGURED\", \"EmDash is not initialized\", 500);\n\t}\n\n\ttry {\n\t\tconst body = await parseOptionalBody(request, mediaConfirmBody, {});\n\t\tif (isParseError(body)) return body;\n\n\t\tconst repo = new MediaRepository(emdash.db);\n\n\t\t// Get the media item first to check status\n\t\tconst existing = await repo.findById(id);\n\t\tif (!existing) {\n\t\t\treturn apiError(\"NOT_FOUND\", `Media item not found: ${id}`, 404);\n\t\t}\n\n\t\t// Only the uploader or a user with media:edit_any can confirm/fail a pending upload\n\t\tconst ownerDenied = requireOwnerPerm(\n\t\t\tuser,\n\t\t\texisting.authorId ?? \"\",\n\t\t\t\"media:upload\",\n\t\t\t\"media:edit_any\",\n\t\t);\n\t\tif (ownerDenied) return ownerDenied;\n\n\t\tif (existing.status === \"ready\") {\n\t\t\tawait forgetUploadAttempt(repo, existing.storageKey);\n\t\t\treturn apiSuccess({ item: addUrlToMedia(existing) });\n\t\t}\n\t\tif (existing.status !== \"pending\") {\n\t\t\treturn apiError(\"INVALID_STATE\", `Media item is not pending: ${existing.status}`, 400);\n\t\t}\n\n\t\tif (body.size !== undefined && existing.size !== null && body.size !== existing.size) {\n\t\t\treturn apiError(\n\t\t\t\t\"UPLOAD_SIZE_MISMATCH\",\n\t\t\t\t\"Confirmed size does not match the pending media item\",\n\t\t\t\t400,\n\t\t\t);\n\t\t}\n\n\t\tlet confirmedSize = existing.size ?? body.size;\n\t\tlet contentHash = existing.contentHash;\n\t\tlet imageBytes: Uint8Array | undefined;\n\n\t\tif (emdash.storage) {\n\t\t\tconst exists = await emdash.storage.exists(existing.storageKey);\n\t\t\tif (!exists) {\n\t\t\t\tconst failed = await repo.markFailed(id, existing.storageKey);\n\t\t\t\tif (!failed) return await confirmationConflict(repo, id);\n\t\t\t\treturn apiError(\"FILE_NOT_FOUND\", \"File was not uploaded to storage\", 400);\n\t\t\t}\n\n\t\t\tconst storedFile = await emdash.storage.download(existing.storageKey);\n\t\t\tif (confirmedSize !== undefined && storedFile.size !== confirmedSize) {\n\t\t\t\tawait cancelDownload(storedFile);\n\t\t\t\treturn apiError(\n\t\t\t\t\t\"UPLOAD_SIZE_MISMATCH\",\n\t\t\t\t\t\"Stored file size does not match the pending media item\",\n\t\t\t\t\t400,\n\t\t\t\t);\n\t\t\t}\n\t\t\tconfirmedSize = storedFile.size;\n\n\t\t\tconst isImage = existing.mimeType.startsWith(\"image/\");\n\t\t\tconst canBuffer = storedFile.size <= MAX_PLACEHOLDER_DOWNLOAD_BYTES;\n\t\t\tconst hasServerHash =\n\t\t\t\tcontentHash !== null && (await repo.hasUploadAttempt(existing.storageKey));\n\t\t\tif (canBuffer && (isImage || !hasServerHash)) {\n\t\t\t\tconst bytes = await consumeDownload(storedFile);\n\t\t\t\tcontentHash = bytes.byteLength > 0 ? await computeContentHash(bytes) : null;\n\t\t\t\tif (isImage && bytes.byteLength > 0) imageBytes = bytes;\n\t\t\t} else {\n\t\t\t\tif (!hasServerHash) contentHash = null;\n\t\t\t\tawait cancelDownload(storedFile);\n\t\t\t}\n\n\t\t\tif (isImage && !canBuffer) {\n\t\t\t\tconsole.warn(\n\t\t\t\t\t`[media] confirm skipping placeholder: object ${existing.storageKey} reported size ${storedFile.size} bytes (> ${MAX_PLACEHOLDER_DOWNLOAD_BYTES})`,\n\t\t\t\t);\n\t\t\t}\n\t\t}\n\n\t\t// LQIP is best-effort; oversized images skip server-side placeholders.\n\t\tlet blurhash: string | undefined;\n\t\tlet dominantColor: string | undefined;\n\t\tlet width = body.width;\n\t\tlet height = body.height;\n\t\tif (imageBytes) {\n\t\t\ttry {\n\t\t\t\tconst enriched = await enrichImageMetadata(imageBytes, existing.mimeType, {\n\t\t\t\t\tknownDimensions:\n\t\t\t\t\t\tbody.width != null && body.height != null\n\t\t\t\t\t\t\t? { width: body.width, height: body.height }\n\t\t\t\t\t\t\t: undefined,\n\t\t\t\t});\n\t\t\t\tblurhash = enriched.blurhash;\n\t\t\t\tdominantColor = enriched.dominantColor;\n\t\t\t\twidth = width ?? enriched.width;\n\t\t\t\theight = height ?? enriched.height;\n\t\t\t} catch (error) {\n\t\t\t\tconsole.error(\"[media] confirm placeholder generation failed:\", error);\n\t\t\t}\n\t\t}\n\n\t\t// Confirm the upload\n\t\tconst item = await repo.confirmUpload(\n\t\t\tid,\n\t\t\t{\n\t\t\t\tsize: confirmedSize,\n\t\t\t\twidth,\n\t\t\t\theight,\n\t\t\t\tblurhash,\n\t\t\t\tdominantColor,\n\t\t\t\tcontentHash,\n\t\t\t},\n\t\t\texisting.storageKey,\n\t\t);\n\n\t\tif (!item) {\n\t\t\treturn await confirmationConflict(repo, id);\n\t\t}\n\n\t\tawait forgetUploadAttempt(repo, item.storageKey);\n\n\t\t// Add URL to the response (relative URL for portability)\n\t\tconst itemWithUrl = addUrlToMedia(item);\n\n\t\treturn apiSuccess({ item: itemWithUrl });\n\t} catch (error) {\n\t\treturn handleError(error, \"Failed to confirm upload\", \"CONFIRM_ERROR\");\n\t}\n};\n"],"mappings":"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"}
1
+ {"version":3,"file":"confirm.mjs","names":[],"sources":["../../../../../../src/astro/routes/api/media/[id]/confirm.ts"],"sourcesContent":["/**\n * Confirm media upload endpoint\n *\n * POST /_emdash/api/media/{id}/confirm\n *\n * Confirms that the client has successfully uploaded the file to storage.\n * Marks the media record as ready and optionally updates metadata.\n */\n\nimport type { APIRoute } from \"astro\";\nimport type { DownloadResult } from \"emdash\";\n\nimport { requireOwnerPerm, requirePerm } from \"#api/authorize.js\";\nimport { apiError, apiSuccess, handleError } from \"#api/error.js\";\nimport { isParseError, parseOptionalBody } from \"#api/parse.js\";\nimport { mediaConfirmBody } from \"#api/schemas.js\";\nimport { MediaRepository } from \"#db/repositories/media.js\";\nimport { enrichImageMetadata } from \"#media/enrich.js\";\nimport type { MediaItem } from \"#types\";\nimport { computeContentHash, MAX_CONTENT_HASH_BYTES } from \"#utils/hash.js\";\n\nexport const prerender = false;\n\n/**\n * Max raw bytes to buffer for server-side LQIP generation at confirm time. The\n * signed-URL upload flow exists so large files bypass server buffering — re-reading\n * the whole object into a Worker's 128 MB heap to compute a blurhash would OOM\n * on the very uploads that flow was designed for. LQIP is progressive\n * enhancement: large images simply ship without a server-generated placeholder.\n */\nconst MAX_PLACEHOLDER_DOWNLOAD_BYTES = MAX_CONTENT_HASH_BYTES;\n\n/**\n * Add URL to media item (relative URL for portability)\n */\nfunction addUrlToMedia(item: MediaItem): MediaItem & { url: string } {\n\treturn {\n\t\t...item,\n\t\turl: `/_emdash/api/media/file/${item.storageKey}`,\n\t};\n}\n\nasync function cancelDownload(download: DownloadResult): Promise<void> {\n\ttry {\n\t\tawait download.body.cancel();\n\t} catch (error) {\n\t\tconsole.error(\"[media] confirm download cancellation failed:\", error);\n\t}\n}\n\nasync function forgetUploadAttempt(repo: MediaRepository, storageKey: string): Promise<void> {\n\ttry {\n\t\tawait repo.deleteUploadAttempt(storageKey);\n\t} catch (error) {\n\t\tconsole.error(\"[media] confirm upload attempt cleanup failed:\", error);\n\t}\n}\n\nasync function confirmationConflict(repo: MediaRepository, id: string): Promise<Response> {\n\tconst current = await repo.findById(id);\n\tif (!current) {\n\t\treturn apiError(\"NOT_FOUND\", `Media item not found: ${id}`, 404);\n\t}\n\tif (current.status === \"ready\") {\n\t\tawait forgetUploadAttempt(repo, current.storageKey);\n\t\treturn apiSuccess({ item: addUrlToMedia(current) });\n\t}\n\tif (current.status === \"pending\") {\n\t\treturn apiError(\"INVALID_STATE\", \"Media item changed during confirmation\", 409);\n\t}\n\treturn apiError(\"INVALID_STATE\", `Media item is not pending: ${current.status}`, 400);\n}\n\nasync function consumeDownload(download: DownloadResult): Promise<Uint8Array> {\n\tconst reader = download.body.getReader();\n\ttry {\n\t\tconst bytes = new Uint8Array(download.size);\n\t\tlet receivedSize = 0;\n\t\twhile (true) {\n\t\t\tconst { done, value } = await reader.read();\n\t\t\tif (done) break;\n\t\t\tif (receivedSize + value.byteLength > bytes.byteLength) {\n\t\t\t\tthrow new Error(\"Stored file exceeds its reported size\");\n\t\t\t}\n\t\t\tbytes.set(value, receivedSize);\n\t\t\treceivedSize += value.byteLength;\n\t\t}\n\t\tif (receivedSize !== download.size) {\n\t\t\tthrow new Error(\"Stored file size does not match its reported size\");\n\t\t}\n\t\treturn bytes;\n\t} catch (error) {\n\t\ttry {\n\t\t\tawait reader.cancel(error);\n\t\t} catch (cancelError) {\n\t\t\tconsole.error(\"[media] confirm download cancellation failed:\", cancelError);\n\t\t}\n\t\tthrow error;\n\t} finally {\n\t\treader.releaseLock();\n\t}\n}\n\n/**\n * Confirm upload completion\n */\nexport const POST: APIRoute = async ({ params, request, locals }) => {\n\tconst { emdash, user } = locals;\n\tconst { id } = params;\n\n\tconst denied = requirePerm(user, \"media:upload\");\n\tif (denied) return denied;\n\n\tif (!id) {\n\t\treturn apiError(\"INVALID_REQUEST\", \"Media ID is required\", 400);\n\t}\n\n\tif (!emdash?.db) {\n\t\treturn apiError(\"NOT_CONFIGURED\", \"EmDash is not initialized\", 500);\n\t}\n\n\ttry {\n\t\tconst body = await parseOptionalBody(request, mediaConfirmBody, {});\n\t\tif (isParseError(body)) return body;\n\n\t\tconst repo = new MediaRepository(emdash.db);\n\n\t\t// Get the media item first to check status\n\t\tconst existing = await repo.findById(id);\n\t\tif (!existing) {\n\t\t\treturn apiError(\"NOT_FOUND\", `Media item not found: ${id}`, 404);\n\t\t}\n\n\t\t// Only the uploader or a user with media:edit_any can confirm/fail a pending upload\n\t\tconst ownerDenied = requireOwnerPerm(\n\t\t\tuser,\n\t\t\texisting.authorId ?? \"\",\n\t\t\t\"media:upload\",\n\t\t\t\"media:edit_any\",\n\t\t);\n\t\tif (ownerDenied) return ownerDenied;\n\n\t\tif (existing.status === \"ready\") {\n\t\t\tawait forgetUploadAttempt(repo, existing.storageKey);\n\t\t\treturn apiSuccess({ item: addUrlToMedia(existing) });\n\t\t}\n\t\tif (existing.status !== \"pending\") {\n\t\t\treturn apiError(\"INVALID_STATE\", `Media item is not pending: ${existing.status}`, 400);\n\t\t}\n\n\t\tif (body.size !== undefined && existing.size !== null && body.size !== existing.size) {\n\t\t\treturn apiError(\n\t\t\t\t\"UPLOAD_SIZE_MISMATCH\",\n\t\t\t\t\"Confirmed size does not match the pending media item\",\n\t\t\t\t400,\n\t\t\t);\n\t\t}\n\n\t\tlet confirmedSize = existing.size ?? body.size;\n\t\tlet contentHash = existing.contentHash;\n\t\tlet imageBytes: Uint8Array | undefined;\n\n\t\tif (emdash.storage) {\n\t\t\tconst exists = await emdash.storage.exists(existing.storageKey);\n\t\t\tif (!exists) {\n\t\t\t\tconst failed = await repo.markFailed(id, existing.storageKey);\n\t\t\t\tif (!failed) return await confirmationConflict(repo, id);\n\t\t\t\treturn apiError(\"FILE_NOT_FOUND\", \"File was not uploaded to storage\", 400);\n\t\t\t}\n\n\t\t\tconst storedFile = await emdash.storage.download(existing.storageKey);\n\t\t\tif (confirmedSize !== undefined && storedFile.size !== confirmedSize) {\n\t\t\t\tawait cancelDownload(storedFile);\n\t\t\t\treturn apiError(\n\t\t\t\t\t\"UPLOAD_SIZE_MISMATCH\",\n\t\t\t\t\t\"Stored file size does not match the pending media item\",\n\t\t\t\t\t400,\n\t\t\t\t);\n\t\t\t}\n\t\t\tconfirmedSize = storedFile.size;\n\n\t\t\tconst isImage = existing.mimeType.startsWith(\"image/\");\n\t\t\tconst canBuffer = storedFile.size <= MAX_PLACEHOLDER_DOWNLOAD_BYTES;\n\t\t\tconst hasServerHash =\n\t\t\t\tcontentHash !== null && (await repo.hasUploadAttempt(existing.storageKey));\n\t\t\tif (canBuffer && (isImage || !hasServerHash)) {\n\t\t\t\tconst bytes = await consumeDownload(storedFile);\n\t\t\t\tcontentHash = bytes.byteLength > 0 ? await computeContentHash(bytes) : null;\n\t\t\t\tif (isImage && bytes.byteLength > 0) imageBytes = bytes;\n\t\t\t} else {\n\t\t\t\tif (!hasServerHash) contentHash = null;\n\t\t\t\tawait cancelDownload(storedFile);\n\t\t\t}\n\n\t\t\tif (isImage && !canBuffer) {\n\t\t\t\tconsole.warn(\n\t\t\t\t\t`[media] confirm skipping placeholder: object ${existing.storageKey} reported size ${storedFile.size} bytes (> ${MAX_PLACEHOLDER_DOWNLOAD_BYTES})`,\n\t\t\t\t);\n\t\t\t}\n\t\t}\n\n\t\t// LQIP is best-effort; oversized images skip server-side placeholders.\n\t\tlet blurhash: string | undefined;\n\t\tlet dominantColor: string | undefined;\n\t\tlet width = body.width;\n\t\tlet height = body.height;\n\t\tif (imageBytes) {\n\t\t\ttry {\n\t\t\t\tconst enriched = await enrichImageMetadata(imageBytes, existing.mimeType, {\n\t\t\t\t\tknownDimensions:\n\t\t\t\t\t\tbody.width != null && body.height != null\n\t\t\t\t\t\t\t? { width: body.width, height: body.height }\n\t\t\t\t\t\t\t: undefined,\n\t\t\t\t});\n\t\t\t\tblurhash = enriched.blurhash;\n\t\t\t\tdominantColor = enriched.dominantColor;\n\t\t\t\twidth = width ?? enriched.width;\n\t\t\t\theight = height ?? enriched.height;\n\t\t\t} catch (error) {\n\t\t\t\tconsole.error(\"[media] confirm placeholder generation failed:\", error);\n\t\t\t}\n\t\t}\n\n\t\t// Confirm the upload\n\t\tconst item = await repo.confirmUpload(\n\t\t\tid,\n\t\t\t{\n\t\t\t\tsize: confirmedSize,\n\t\t\t\twidth,\n\t\t\t\theight,\n\t\t\t\tblurhash,\n\t\t\t\tdominantColor,\n\t\t\t\tcontentHash,\n\t\t\t},\n\t\t\texisting.storageKey,\n\t\t);\n\n\t\tif (!item) {\n\t\t\treturn await confirmationConflict(repo, id);\n\t\t}\n\n\t\tawait forgetUploadAttempt(repo, item.storageKey);\n\n\t\t// Add URL to the response (relative URL for portability)\n\t\tconst itemWithUrl = addUrlToMedia(item);\n\n\t\treturn apiSuccess({ item: itemWithUrl });\n\t} catch (error) {\n\t\treturn handleError(error, \"Failed to confirm upload\", \"CONFIRM_ERROR\");\n\t}\n};\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;AAqBA,MAAa,YAAY;;;;;;;;AASzB,MAAM,iCAAiC;;;;AAKvC,SAAS,cAAc,MAA8C;AACpE,QAAO;EACN,GAAG;EACH,KAAK,2BAA2B,KAAK;EACrC;;AAGF,eAAe,eAAe,UAAyC;AACtE,KAAI;AACH,QAAM,SAAS,KAAK,QAAQ;UACpB,OAAO;AACf,UAAQ,MAAM,iDAAiD,MAAM;;;AAIvE,eAAe,oBAAoB,MAAuB,YAAmC;AAC5F,KAAI;AACH,QAAM,KAAK,oBAAoB,WAAW;UAClC,OAAO;AACf,UAAQ,MAAM,kDAAkD,MAAM;;;AAIxE,eAAe,qBAAqB,MAAuB,IAA+B;CACzF,MAAM,UAAU,MAAM,KAAK,SAAS,GAAG;AACvC,KAAI,CAAC,QACJ,QAAO,SAAS,aAAa,yBAAyB,MAAM,IAAI;AAEjE,KAAI,QAAQ,WAAW,SAAS;AAC/B,QAAM,oBAAoB,MAAM,QAAQ,WAAW;AACnD,SAAO,WAAW,EAAE,MAAM,cAAc,QAAQ,EAAE,CAAC;;AAEpD,KAAI,QAAQ,WAAW,UACtB,QAAO,SAAS,iBAAiB,0CAA0C,IAAI;AAEhF,QAAO,SAAS,iBAAiB,8BAA8B,QAAQ,UAAU,IAAI;;AAGtF,eAAe,gBAAgB,UAA+C;CAC7E,MAAM,SAAS,SAAS,KAAK,WAAW;AACxC,KAAI;EACH,MAAM,QAAQ,IAAI,WAAW,SAAS,KAAK;EAC3C,IAAI,eAAe;AACnB,SAAO,MAAM;GACZ,MAAM,EAAE,MAAM,UAAU,MAAM,OAAO,MAAM;AAC3C,OAAI,KAAM;AACV,OAAI,eAAe,MAAM,aAAa,MAAM,WAC3C,OAAM,IAAI,MAAM,wCAAwC;AAEzD,SAAM,IAAI,OAAO,aAAa;AAC9B,mBAAgB,MAAM;;AAEvB,MAAI,iBAAiB,SAAS,KAC7B,OAAM,IAAI,MAAM,oDAAoD;AAErE,SAAO;UACC,OAAO;AACf,MAAI;AACH,SAAM,OAAO,OAAO,MAAM;WAClB,aAAa;AACrB,WAAQ,MAAM,iDAAiD,YAAY;;AAE5E,QAAM;WACG;AACT,SAAO,aAAa;;;;;;AAOtB,MAAa,OAAiB,OAAO,EAAE,QAAQ,SAAS,aAAa;CACpE,MAAM,EAAE,QAAQ,SAAS;CACzB,MAAM,EAAE,OAAO;CAEf,MAAM,SAAS,YAAY,MAAM,eAAe;AAChD,KAAI,OAAQ,QAAO;AAEnB,KAAI,CAAC,GACJ,QAAO,SAAS,mBAAmB,wBAAwB,IAAI;AAGhE,KAAI,CAAC,QAAQ,GACZ,QAAO,SAAS,kBAAkB,6BAA6B,IAAI;AAGpE,KAAI;EACH,MAAM,OAAO,MAAM,kBAAkB,SAAS,kBAAkB,EAAE,CAAC;AACnE,MAAI,aAAa,KAAK,CAAE,QAAO;EAE/B,MAAM,OAAO,IAAI,gBAAgB,OAAO,GAAG;EAG3C,MAAM,WAAW,MAAM,KAAK,SAAS,GAAG;AACxC,MAAI,CAAC,SACJ,QAAO,SAAS,aAAa,yBAAyB,MAAM,IAAI;EAIjE,MAAM,cAAc,iBACnB,MACA,SAAS,YAAY,IACrB,gBACA,iBACA;AACD,MAAI,YAAa,QAAO;AAExB,MAAI,SAAS,WAAW,SAAS;AAChC,SAAM,oBAAoB,MAAM,SAAS,WAAW;AACpD,UAAO,WAAW,EAAE,MAAM,cAAc,SAAS,EAAE,CAAC;;AAErD,MAAI,SAAS,WAAW,UACvB,QAAO,SAAS,iBAAiB,8BAA8B,SAAS,UAAU,IAAI;AAGvF,MAAI,KAAK,SAAS,UAAa,SAAS,SAAS,QAAQ,KAAK,SAAS,SAAS,KAC/E,QAAO,SACN,wBACA,wDACA,IACA;EAGF,IAAI,gBAAgB,SAAS,QAAQ,KAAK;EAC1C,IAAI,cAAc,SAAS;EAC3B,IAAI;AAEJ,MAAI,OAAO,SAAS;AAEnB,OAAI,CADW,MAAM,OAAO,QAAQ,OAAO,SAAS,WAAW,EAClD;AAEZ,QAAI,CADW,MAAM,KAAK,WAAW,IAAI,SAAS,WAAW,CAChD,QAAO,MAAM,qBAAqB,MAAM,GAAG;AACxD,WAAO,SAAS,kBAAkB,oCAAoC,IAAI;;GAG3E,MAAM,aAAa,MAAM,OAAO,QAAQ,SAAS,SAAS,WAAW;AACrE,OAAI,kBAAkB,UAAa,WAAW,SAAS,eAAe;AACrE,UAAM,eAAe,WAAW;AAChC,WAAO,SACN,wBACA,0DACA,IACA;;AAEF,mBAAgB,WAAW;GAE3B,MAAM,UAAU,SAAS,SAAS,WAAW,SAAS;GACtD,MAAM,YAAY,WAAW,QAAQ;GACrC,MAAM,gBACL,gBAAgB,QAAS,MAAM,KAAK,iBAAiB,SAAS,WAAW;AAC1E,OAAI,cAAc,WAAW,CAAC,gBAAgB;IAC7C,MAAM,QAAQ,MAAM,gBAAgB,WAAW;AAC/C,kBAAc,MAAM,aAAa,IAAI,MAAM,mBAAmB,MAAM,GAAG;AACvE,QAAI,WAAW,MAAM,aAAa,EAAG,cAAa;UAC5C;AACN,QAAI,CAAC,cAAe,eAAc;AAClC,UAAM,eAAe,WAAW;;AAGjC,OAAI,WAAW,CAAC,UACf,SAAQ,KACP,gDAAgD,SAAS,WAAW,iBAAiB,WAAW,KAAK,YAAY,+BAA+B,GAChJ;;EAKH,IAAI;EACJ,IAAI;EACJ,IAAI,QAAQ,KAAK;EACjB,IAAI,SAAS,KAAK;AAClB,MAAI,WACH,KAAI;GACH,MAAM,WAAW,MAAM,oBAAoB,YAAY,SAAS,UAAU,EACzE,iBACC,KAAK,SAAS,QAAQ,KAAK,UAAU,OAClC;IAAE,OAAO,KAAK;IAAO,QAAQ,KAAK;IAAQ,GAC1C,QACJ,CAAC;AACF,cAAW,SAAS;AACpB,mBAAgB,SAAS;AACzB,WAAQ,SAAS,SAAS;AAC1B,YAAS,UAAU,SAAS;WACpB,OAAO;AACf,WAAQ,MAAM,kDAAkD,MAAM;;EAKxE,MAAM,OAAO,MAAM,KAAK,cACvB,IACA;GACC,MAAM;GACN;GACA;GACA;GACA;GACA;GACA,EACD,SAAS,WACT;AAED,MAAI,CAAC,KACJ,QAAO,MAAM,qBAAqB,MAAM,GAAG;AAG5C,QAAM,oBAAoB,MAAM,KAAK,WAAW;AAKhD,SAAO,WAAW,EAAE,MAFA,cAAc,KAAK,EAEA,CAAC;UAChC,OAAO;AACf,SAAO,YAAY,OAAO,4BAA4B,gBAAgB"}
@@ -1,17 +1,23 @@
1
- import "../../../../../config-CGVeT8Hc.mjs";
1
+ import "../../../../../config-CvmjJcVw.mjs";
2
2
  import "../../../../../base64-DvnNgP7e.mjs";
3
3
  import "../../../../../types-BkUg2yHx.mjs";
4
- import { n as normalizeMime } from "../../../../../mime-CCYRC4r1.mjs";
5
- import { n as computeContentHash } from "../../../../../hash-CLVFzWvx.mjs";
6
- import { a as unwrapResult, n as apiSuccess, r as handleError, t as apiError } from "../../../../../error-CCTCskie.mjs";
7
- import "../../../../../redirects-BCiTaIQ-.mjs";
8
- import { At as DEFAULT_MAX_UPLOAD_SIZE, Qt as mediaReplaceMetadataForm } from "../../../../../entry-lock-CwWdnFyR.mjs";
9
- import "../../../../../comments-BVzzt6x5.mjs";
10
- import "../../../../../relations-B4w-G5U9.mjs";
11
- import "../../../../../status-DLoBmcDz.mjs";
4
+ import { n as normalizeMime } from "../../../../../mime-ChLqYwDk.mjs";
5
+ import "../../../../../errors-DgE1zJGG.mjs";
6
+ import { n as computeContentHash } from "../../../../../hash-SDAW6zC-.mjs";
7
+ import "../../../../../settings-DYidIB26.mjs";
8
+ import "../../../../../site-settings-DOgRUoFX.mjs";
9
+ import "../../../../../errors-BF0_LFhW.mjs";
10
+ import { a as unwrapResult, n as apiSuccess, r as handleError, t as apiError } from "../../../../../error-CfvOHP0M.mjs";
11
+ import "../../../../../redirects-Cv9apQKj.mjs";
12
+ import "../../../../../entry-lock-BJYdBfXb.mjs";
13
+ import { n as DEFAULT_MAX_UPLOAD_SIZE, w as mediaReplaceMetadataForm } from "../../../../../media-Pu1L6xir.mjs";
14
+ import "../../../../../comments-fHZ8ON9O.mjs";
15
+ import "../../../../../relations-CK9CYUyr.mjs";
16
+ import "../../../../../menus-BM7BPLOb.mjs";
17
+ import "../../../../../status-DZKIG4a9.mjs";
12
18
  import "../../../../../api/schemas/index.mjs";
13
19
  import { MUTABLE_MEDIA_CACHE_CONTROL } from "../../../../../media/image-endpoint.mjs";
14
- import { n as requireOwnerPerm, r as requirePerm } from "../../../../../authorize-BXpfMpp0.mjs";
20
+ import { i as requirePerm, r as requireOwnerPerm } from "../../../../../authorize-seCifOMJ.mjs";
15
21
 
16
22
  //#region src/astro/routes/api/media/[id]/replace.ts
17
23
  const prerender = false;
@@ -1 +1 @@
1
- {"version":3,"file":"replace.mjs","names":[],"sources":["../../../../../../src/astro/routes/api/media/[id]/replace.ts"],"sourcesContent":["import type { APIRoute } from \"astro\";\n\nimport { requireOwnerPerm, requirePerm } from \"#api/authorize.js\";\nimport { apiError, apiSuccess, handleError, unwrapResult } from \"#api/error.js\";\nimport { DEFAULT_MAX_UPLOAD_SIZE, mediaReplaceMetadataForm } from \"#api/schemas.js\";\nimport { MUTABLE_MEDIA_CACHE_CONTROL } from \"#media/image-endpoint.js\";\nimport { normalizeMime } from \"#media/mime.js\";\nimport { computeContentHash } from \"#utils/hash.js\";\n\nexport const prerender = false;\n\nconst REPLACEABLE_IMAGE_TYPES = new Set([\"image/jpeg\", \"image/png\", \"image/webp\"]);\n\nexport const PUT: APIRoute = async ({ params, request, locals }) => {\n\tconst { emdash, user } = locals;\n\tconst { id } = params;\n\n\tconst editDenied = requirePerm(user, \"media:edit_own\");\n\tif (editDenied) return editDenied;\n\tif (!id) return apiError(\"INVALID_REQUEST\", \"Media ID required\", 400);\n\tif (!emdash?.handleMediaGet || !emdash?.handleMediaReplaceMetadata) {\n\t\treturn apiError(\"NOT_CONFIGURED\", \"EmDash is not initialized\", 500);\n\t}\n\tif (!emdash.storage) return apiError(\"NO_STORAGE\", \"Storage not configured\", 500);\n\n\tconst getResult = await emdash.handleMediaGet(id);\n\tif (!getResult.success) return unwrapResult(getResult);\n\tconst media = getResult.data.item;\n\tconst ownerDenied = requireOwnerPerm(\n\t\tuser,\n\t\tmedia.authorId ?? \"\",\n\t\t\"media:edit_own\",\n\t\t\"media:edit_any\",\n\t);\n\tif (ownerDenied) return ownerDenied;\n\tif (media.status !== \"ready\") {\n\t\treturn apiError(\"INVALID_STATE\", \"Only ready media can be replaced\", 400);\n\t}\n\n\tconst sourceMime = normalizeMime(media.mimeType);\n\tif (!REPLACEABLE_IMAGE_TYPES.has(sourceMime)) {\n\t\treturn apiError(\"INVALID_TYPE\", \"Media type cannot be replaced\", 400);\n\t}\n\n\tconst rawMax = emdash.config.maxUploadSize ?? DEFAULT_MAX_UPLOAD_SIZE;\n\tif (!Number.isFinite(rawMax) || rawMax <= 0) {\n\t\treturn apiError(\"CONFIGURATION_ERROR\", \"Invalid maxUploadSize configuration\", 500);\n\t}\n\tconst maxUploadSize = rawMax;\n\tconst contentLength = request.headers.get(\"Content-Length\");\n\tif (contentLength && parseInt(contentLength, 10) > maxUploadSize) {\n\t\treturn apiError(\"PAYLOAD_TOO_LARGE\", \"Upload too large\", 413);\n\t}\n\n\ttry {\n\t\tconst formData = await request.formData();\n\t\tconst fileEntry = formData.get(\"file\");\n\t\tconst file = fileEntry instanceof File ? fileEntry : null;\n\t\tif (!file) return apiError(\"NO_FILE\", \"No file provided\", 400);\n\t\tif (file.size === 0) return apiError(\"VALIDATION_ERROR\", \"Replacement file is empty\", 400);\n\t\tif (file.size > maxUploadSize) {\n\t\t\treturn apiError(\"PAYLOAD_TOO_LARGE\", \"Upload too large\", 413);\n\t\t}\n\n\t\tconst replacementMime = normalizeMime(file.type);\n\t\tif (!REPLACEABLE_IMAGE_TYPES.has(replacementMime) || replacementMime !== sourceMime) {\n\t\t\treturn apiError(\"INVALID_TYPE\", \"Replacement file type must match the media item\", 400);\n\t\t}\n\n\t\tconst metadataResult = mediaReplaceMetadataForm.safeParse({\n\t\t\twidth: formData.get(\"width\"),\n\t\t\theight: formData.get(\"height\"),\n\t\t});\n\t\tif (!metadataResult.success) {\n\t\t\treturn apiError(\"VALIDATION_ERROR\", \"Invalid request data\", 400, {\n\t\t\t\tissues: metadataResult.error.issues.map((issue) => ({\n\t\t\t\t\tpath: issue.path.join(\".\"),\n\t\t\t\t\tmessage: issue.message,\n\t\t\t\t})),\n\t\t\t});\n\t\t}\n\t\tconst { width, height } = metadataResult.data;\n\n\t\tconst bytes = new Uint8Array(await file.arrayBuffer());\n\t\tconst contentHash = await computeContentHash(bytes);\n\t\ttry {\n\t\t\tawait emdash.storage.upload({\n\t\t\t\tkey: media.storageKey,\n\t\t\t\tbody: bytes,\n\t\t\t\tcontentType: sourceMime,\n\t\t\t\tcacheControl: MUTABLE_MEDIA_CACHE_CONTROL,\n\t\t\t});\n\t\t} catch (error) {\n\t\t\treturn handleError(error, \"Failed to replace media\", \"MEDIA_REPLACE_ERROR\");\n\t\t}\n\n\t\tconst result = await emdash.handleMediaReplaceMetadata(id, media.storageKey, {\n\t\t\tsize: file.size,\n\t\t\twidth,\n\t\t\theight,\n\t\t\tcontentHash,\n\t\t});\n\t\tif (!result.success) return unwrapResult(result);\n\n\t\treturn apiSuccess({\n\t\t\titem: {\n\t\t\t\t...result.data.item,\n\t\t\t\turl: `/_emdash/api/media/file/${result.data.item.storageKey}`,\n\t\t\t},\n\t\t});\n\t} catch (error) {\n\t\treturn handleError(error, \"Failed to replace media\", \"MEDIA_REPLACE_ERROR\");\n\t}\n};\n"],"mappings":"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"}
1
+ {"version":3,"file":"replace.mjs","names":[],"sources":["../../../../../../src/astro/routes/api/media/[id]/replace.ts"],"sourcesContent":["import type { APIRoute } from \"astro\";\n\nimport { requireOwnerPerm, requirePerm } from \"#api/authorize.js\";\nimport { apiError, apiSuccess, handleError, unwrapResult } from \"#api/error.js\";\nimport { DEFAULT_MAX_UPLOAD_SIZE, mediaReplaceMetadataForm } from \"#api/schemas.js\";\nimport { MUTABLE_MEDIA_CACHE_CONTROL } from \"#media/image-endpoint.js\";\nimport { normalizeMime } from \"#media/mime.js\";\nimport { computeContentHash } from \"#utils/hash.js\";\n\nexport const prerender = false;\n\nconst REPLACEABLE_IMAGE_TYPES = new Set([\"image/jpeg\", \"image/png\", \"image/webp\"]);\n\nexport const PUT: APIRoute = async ({ params, request, locals }) => {\n\tconst { emdash, user } = locals;\n\tconst { id } = params;\n\n\tconst editDenied = requirePerm(user, \"media:edit_own\");\n\tif (editDenied) return editDenied;\n\tif (!id) return apiError(\"INVALID_REQUEST\", \"Media ID required\", 400);\n\tif (!emdash?.handleMediaGet || !emdash?.handleMediaReplaceMetadata) {\n\t\treturn apiError(\"NOT_CONFIGURED\", \"EmDash is not initialized\", 500);\n\t}\n\tif (!emdash.storage) return apiError(\"NO_STORAGE\", \"Storage not configured\", 500);\n\n\tconst getResult = await emdash.handleMediaGet(id);\n\tif (!getResult.success) return unwrapResult(getResult);\n\tconst media = getResult.data.item;\n\tconst ownerDenied = requireOwnerPerm(\n\t\tuser,\n\t\tmedia.authorId ?? \"\",\n\t\t\"media:edit_own\",\n\t\t\"media:edit_any\",\n\t);\n\tif (ownerDenied) return ownerDenied;\n\tif (media.status !== \"ready\") {\n\t\treturn apiError(\"INVALID_STATE\", \"Only ready media can be replaced\", 400);\n\t}\n\n\tconst sourceMime = normalizeMime(media.mimeType);\n\tif (!REPLACEABLE_IMAGE_TYPES.has(sourceMime)) {\n\t\treturn apiError(\"INVALID_TYPE\", \"Media type cannot be replaced\", 400);\n\t}\n\n\tconst rawMax = emdash.config.maxUploadSize ?? DEFAULT_MAX_UPLOAD_SIZE;\n\tif (!Number.isFinite(rawMax) || rawMax <= 0) {\n\t\treturn apiError(\"CONFIGURATION_ERROR\", \"Invalid maxUploadSize configuration\", 500);\n\t}\n\tconst maxUploadSize = rawMax;\n\tconst contentLength = request.headers.get(\"Content-Length\");\n\tif (contentLength && parseInt(contentLength, 10) > maxUploadSize) {\n\t\treturn apiError(\"PAYLOAD_TOO_LARGE\", \"Upload too large\", 413);\n\t}\n\n\ttry {\n\t\tconst formData = await request.formData();\n\t\tconst fileEntry = formData.get(\"file\");\n\t\tconst file = fileEntry instanceof File ? fileEntry : null;\n\t\tif (!file) return apiError(\"NO_FILE\", \"No file provided\", 400);\n\t\tif (file.size === 0) return apiError(\"VALIDATION_ERROR\", \"Replacement file is empty\", 400);\n\t\tif (file.size > maxUploadSize) {\n\t\t\treturn apiError(\"PAYLOAD_TOO_LARGE\", \"Upload too large\", 413);\n\t\t}\n\n\t\tconst replacementMime = normalizeMime(file.type);\n\t\tif (!REPLACEABLE_IMAGE_TYPES.has(replacementMime) || replacementMime !== sourceMime) {\n\t\t\treturn apiError(\"INVALID_TYPE\", \"Replacement file type must match the media item\", 400);\n\t\t}\n\n\t\tconst metadataResult = mediaReplaceMetadataForm.safeParse({\n\t\t\twidth: formData.get(\"width\"),\n\t\t\theight: formData.get(\"height\"),\n\t\t});\n\t\tif (!metadataResult.success) {\n\t\t\treturn apiError(\"VALIDATION_ERROR\", \"Invalid request data\", 400, {\n\t\t\t\tissues: metadataResult.error.issues.map((issue) => ({\n\t\t\t\t\tpath: issue.path.join(\".\"),\n\t\t\t\t\tmessage: issue.message,\n\t\t\t\t})),\n\t\t\t});\n\t\t}\n\t\tconst { width, height } = metadataResult.data;\n\n\t\tconst bytes = new Uint8Array(await file.arrayBuffer());\n\t\tconst contentHash = await computeContentHash(bytes);\n\t\ttry {\n\t\t\tawait emdash.storage.upload({\n\t\t\t\tkey: media.storageKey,\n\t\t\t\tbody: bytes,\n\t\t\t\tcontentType: sourceMime,\n\t\t\t\tcacheControl: MUTABLE_MEDIA_CACHE_CONTROL,\n\t\t\t});\n\t\t} catch (error) {\n\t\t\treturn handleError(error, \"Failed to replace media\", \"MEDIA_REPLACE_ERROR\");\n\t\t}\n\n\t\tconst result = await emdash.handleMediaReplaceMetadata(id, media.storageKey, {\n\t\t\tsize: file.size,\n\t\t\twidth,\n\t\t\theight,\n\t\t\tcontentHash,\n\t\t});\n\t\tif (!result.success) return unwrapResult(result);\n\n\t\treturn apiSuccess({\n\t\t\titem: {\n\t\t\t\t...result.data.item,\n\t\t\t\turl: `/_emdash/api/media/file/${result.data.item.storageKey}`,\n\t\t\t},\n\t\t});\n\t} catch (error) {\n\t\treturn handleError(error, \"Failed to replace media\", \"MEDIA_REPLACE_ERROR\");\n\t}\n};\n"],"mappings":"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"}
@@ -1,11 +1,13 @@
1
1
  import "../../../../../base64-DvnNgP7e.mjs";
2
2
  import "../../../../../types-BkUg2yHx.mjs";
3
- import { t as MediaRepository } from "../../../../../media-TBlKCwo7.mjs";
4
- import { n as normalizeMime } from "../../../../../mime-CCYRC4r1.mjs";
5
- import { n as computeContentHash, t as MAX_CONTENT_HASH_BYTES } from "../../../../../hash-CLVFzWvx.mjs";
6
- import { n as apiSuccess, r as handleError, t as apiError } from "../../../../../error-CCTCskie.mjs";
7
- import { t as removeUploadAttempt } from "../../../../../upload-attempts-2xdnoKGe.mjs";
8
- import { n as requireOwnerPerm, r as requirePerm } from "../../../../../authorize-BXpfMpp0.mjs";
3
+ import { t as MediaRepository } from "../../../../../media-Qp5S3eH3.mjs";
4
+ import { n as normalizeMime } from "../../../../../mime-ChLqYwDk.mjs";
5
+ import "../../../../../errors-DgE1zJGG.mjs";
6
+ import { n as computeContentHash, t as MAX_CONTENT_HASH_BYTES } from "../../../../../hash-SDAW6zC-.mjs";
7
+ import { t as removeUploadAttempt } from "../../../../../upload-attempts-B68ZGNu9.mjs";
8
+ import "../../../../../errors-BF0_LFhW.mjs";
9
+ import { n as apiSuccess, r as handleError, t as apiError } from "../../../../../error-CfvOHP0M.mjs";
10
+ import { i as requirePerm, r as requireOwnerPerm } from "../../../../../authorize-seCifOMJ.mjs";
9
11
  import { ulid } from "ulidx";
10
12
 
11
13
  //#region src/astro/routes/api/media/[id]/upload.ts
@@ -1 +1 @@
1
- {"version":3,"file":"upload.mjs","names":[],"sources":["../../../../../../src/astro/routes/api/media/[id]/upload.ts"],"sourcesContent":["import type { APIRoute } from \"astro\";\nimport type { Storage } from \"emdash\";\nimport { ulid } from \"ulidx\";\n\nimport { requireOwnerPerm, requirePerm } from \"#api/authorize.js\";\nimport { apiError, apiSuccess, handleError } from \"#api/error.js\";\nimport { MediaRepository } from \"#db/repositories/media.js\";\nimport { normalizeMime } from \"#media/mime.js\";\nimport { removeUploadAttempt } from \"#media/upload-attempts.js\";\nimport { computeContentHash, MAX_CONTENT_HASH_BYTES } from \"#utils/hash.js\";\n\nexport const prerender = false;\n\nconst INITIAL_HASH_BUFFER_BYTES = 64 * 1024;\n\ntype FixedLengthStreamConstructor = new (\n\texpectedLength: number | bigint,\n) => TransformStream<ArrayBuffer | ArrayBufferView, Uint8Array>;\n\ndeclare const FixedLengthStream: FixedLengthStreamConstructor | undefined;\n\nclass UploadBodyError extends Error {\n\treadonly code: \"PAYLOAD_TOO_LARGE\" | \"UPLOAD_SIZE_MISMATCH\";\n\n\tconstructor(code: \"PAYLOAD_TOO_LARGE\" | \"UPLOAD_SIZE_MISMATCH\") {\n\t\tsuper(code);\n\t\tthis.code = code;\n\t}\n}\n\nfunction findUploadBodyError(error: unknown): UploadBodyError | null {\n\tlet current = error;\n\tfor (let depth = 0; depth < 5 && current instanceof Error; depth++) {\n\t\tif (current instanceof UploadBodyError) return current;\n\t\tcurrent = current.cause;\n\t}\n\treturn null;\n}\n\nfunction preserveKnownLength(\n\tbody: ReadableStream<Uint8Array>,\n\texpectedLength: number,\n): ReadableStream<Uint8Array> {\n\tif (typeof FixedLengthStream === \"undefined\") return body;\n\treturn body.pipeThrough(new FixedLengthStream(expectedLength));\n}\n\nfunction createUploadAttemptKey(key: string): string {\n\tconst pathSeparator = key.lastIndexOf(\"/\");\n\tconst extensionSeparator = key.lastIndexOf(\".\");\n\tif (extensionSeparator > pathSeparator) {\n\t\treturn `${key.slice(0, extensionSeparator)}.${ulid()}${key.slice(extensionSeparator)}`;\n\t}\n\treturn `${key}.${ulid()}`;\n}\n\nasync function getStoredSize(storage: Storage, key: string): Promise<number | null> {\n\tif (!(await storage.exists(key))) return null;\n\tconst download = await storage.download(key);\n\ttry {\n\t\treturn download.size;\n\t} finally {\n\t\ttry {\n\t\t\tawait download.body.cancel();\n\t\t} catch (error) {\n\t\t\tconsole.error(\"[media] upload download cancellation failed:\", error);\n\t\t}\n\t}\n}\n\nexport const PUT: APIRoute = async ({ params, request, locals }) => {\n\tconst { emdash, user } = locals;\n\tconst { id } = params;\n\n\tconst denied = requirePerm(user, \"media:upload\");\n\tif (denied) return denied;\n\n\tif (!id) {\n\t\treturn apiError(\"INVALID_REQUEST\", \"Media ID is required\", 400);\n\t}\n\n\tif (!emdash?.db) {\n\t\treturn apiError(\"NOT_CONFIGURED\", \"EmDash is not initialized\", 500);\n\t}\n\n\tif (!emdash.storage) {\n\t\treturn apiError(\"NO_STORAGE\", \"Storage not configured\", 500);\n\t}\n\n\ttry {\n\t\tconst repo = new MediaRepository(emdash.db);\n\t\tconst media = await repo.findById(id);\n\t\tif (!media) {\n\t\t\treturn apiError(\"NOT_FOUND\", `Media item not found: ${id}`, 404);\n\t\t}\n\n\t\tif (media.status !== \"pending\") {\n\t\t\treturn apiError(\"INVALID_STATE\", `Media item is not pending: ${media.status}`, 400);\n\t\t}\n\n\t\tconst ownerDenied = requireOwnerPerm(\n\t\t\tuser,\n\t\t\tmedia.authorId ?? \"\",\n\t\t\t\"media:upload\",\n\t\t\t\"media:edit_any\",\n\t\t);\n\t\tif (ownerDenied) return ownerDenied;\n\n\t\tif (!Number.isSafeInteger(media.size) || media.size === null || media.size < 0) {\n\t\t\treturn apiError(\"INVALID_STATE\", \"Pending media item has no valid upload size\", 400);\n\t\t}\n\t\tconst expectedSize = media.size;\n\n\t\tconst contentType = request.headers.get(\"Content-Type\");\n\t\tif (!contentType || normalizeMime(contentType) !== media.mimeType) {\n\t\t\treturn apiError(\"INVALID_TYPE\", \"Upload content type does not match the media item\", 400);\n\t\t}\n\n\t\tconst requestBody =\n\t\t\trequest.body ??\n\t\t\t(expectedSize === 0\n\t\t\t\t? new ReadableStream<Uint8Array>({\n\t\t\t\t\t\tstart(controller) {\n\t\t\t\t\t\t\tcontroller.close();\n\t\t\t\t\t\t},\n\t\t\t\t\t})\n\t\t\t\t: null);\n\t\tif (!requestBody) {\n\t\t\treturn apiError(\"NO_FILE\", \"No file provided\", 400);\n\t\t}\n\n\t\tconst contentLength = request.headers.get(\"Content-Length\");\n\t\tif (contentLength !== null) {\n\t\t\tconst declaredSize = Number(contentLength);\n\t\t\tif (!Number.isSafeInteger(declaredSize) || declaredSize < 0) {\n\t\t\t\treturn apiError(\"INVALID_REQUEST\", \"Invalid Content-Length header\", 400);\n\t\t\t}\n\t\t\tif (declaredSize > expectedSize) {\n\t\t\t\treturn apiError(\"PAYLOAD_TOO_LARGE\", \"Upload exceeds the expected size\", 413);\n\t\t\t}\n\t\t\tif (declaredSize !== expectedSize) {\n\t\t\t\treturn apiError(\"UPLOAD_SIZE_MISMATCH\", \"Upload size does not match the media item\", 400);\n\t\t\t}\n\t\t}\n\n\t\tlet receivedSize = 0;\n\t\tconst shouldHash = expectedSize > 0 && expectedSize <= MAX_CONTENT_HASH_BYTES;\n\t\tlet hashBytes: Uint8Array | null = null;\n\t\tconst checkedBody = requestBody.pipeThrough(\n\t\t\tnew TransformStream<Uint8Array, Uint8Array>({\n\t\t\t\ttransform(chunk, controller) {\n\t\t\t\t\tconst offset = receivedSize;\n\t\t\t\t\treceivedSize += chunk.byteLength;\n\t\t\t\t\tif (receivedSize > expectedSize) {\n\t\t\t\t\t\tcontroller.error(new UploadBodyError(\"PAYLOAD_TOO_LARGE\"));\n\t\t\t\t\t\treturn;\n\t\t\t\t\t}\n\t\t\t\t\tif (shouldHash && chunk.byteLength > 0) {\n\t\t\t\t\t\tif (!hashBytes) {\n\t\t\t\t\t\t\thashBytes = new Uint8Array(\n\t\t\t\t\t\t\t\tMath.min(expectedSize, Math.max(INITIAL_HASH_BUFFER_BYTES, receivedSize)),\n\t\t\t\t\t\t\t);\n\t\t\t\t\t\t} else if (receivedSize > hashBytes.byteLength) {\n\t\t\t\t\t\t\tconst grown = new Uint8Array(\n\t\t\t\t\t\t\t\tMath.min(expectedSize, Math.max(receivedSize, hashBytes.byteLength * 2)),\n\t\t\t\t\t\t\t);\n\t\t\t\t\t\t\tgrown.set(hashBytes);\n\t\t\t\t\t\t\thashBytes = grown;\n\t\t\t\t\t\t}\n\t\t\t\t\t\thashBytes.set(chunk, offset);\n\t\t\t\t\t}\n\t\t\t\t\tcontroller.enqueue(chunk);\n\t\t\t\t},\n\t\t\t\tflush(controller) {\n\t\t\t\t\tif (receivedSize !== expectedSize) {\n\t\t\t\t\t\tcontroller.error(new UploadBodyError(\"UPLOAD_SIZE_MISMATCH\"));\n\t\t\t\t\t}\n\t\t\t\t},\n\t\t\t}),\n\t\t);\n\t\tconst body = preserveKnownLength(checkedBody, expectedSize);\n\n\t\tconst attemptKey = createUploadAttemptKey(media.storageKey);\n\t\tawait repo.createUploadAttempt(id, attemptKey);\n\n\t\tlet attemptSize: number;\n\t\ttry {\n\t\t\tconst result = await emdash.storage.upload({\n\t\t\t\tkey: attemptKey,\n\t\t\t\tbody,\n\t\t\t\tcontentType: media.mimeType,\n\t\t\t});\n\t\t\tattemptSize = result.size;\n\t\t} catch (error) {\n\t\t\tawait removeUploadAttempt(emdash.storage, repo, attemptKey);\n\t\t\tconst bodyError = findUploadBodyError(error);\n\t\t\tif (bodyError?.code === \"PAYLOAD_TOO_LARGE\") {\n\t\t\t\treturn apiError(\"PAYLOAD_TOO_LARGE\", \"Upload exceeds the expected size\", 413);\n\t\t\t}\n\t\t\tif (bodyError?.code === \"UPLOAD_SIZE_MISMATCH\") {\n\t\t\t\treturn apiError(\"UPLOAD_SIZE_MISMATCH\", \"Upload size does not match the media item\", 400);\n\t\t\t}\n\t\t\treturn handleError(error, \"Upload failed\", \"UPLOAD_ERROR\");\n\t\t}\n\n\t\tif (receivedSize !== expectedSize || attemptSize !== expectedSize) {\n\t\t\tawait removeUploadAttempt(emdash.storage, repo, attemptKey);\n\t\t\treturn apiError(\"UPLOAD_SIZE_MISMATCH\", \"Upload size does not match the media item\", 400);\n\t\t}\n\t\tconst contentHash = hashBytes ? await computeContentHash(hashBytes) : undefined;\n\n\t\tlet published: boolean;\n\t\ttry {\n\t\t\tpublished = await repo.publishPendingStorageKey(\n\t\t\t\tid,\n\t\t\t\tmedia.storageKey,\n\t\t\t\tattemptKey,\n\t\t\t\tcontentHash,\n\t\t\t);\n\t\t} catch (error) {\n\t\t\ttry {\n\t\t\t\tconst current = await repo.findById(id);\n\t\t\t\tif (\n\t\t\t\t\tcurrent?.storageKey === attemptKey &&\n\t\t\t\t\t(current.status === \"pending\" || current.status === \"ready\") &&\n\t\t\t\t\tcurrent.size === expectedSize &&\n\t\t\t\t\t(await getStoredSize(emdash.storage, attemptKey)) === expectedSize\n\t\t\t\t) {\n\t\t\t\t\treturn apiSuccess({ uploaded: true, size: expectedSize });\n\t\t\t\t}\n\t\t\t} catch (verificationError) {\n\t\t\t\tconsole.error(\"[media] upload publication verification failed:\", verificationError);\n\t\t\t}\n\t\t\treturn handleError(error, \"Upload failed\", \"UPLOAD_ERROR\");\n\t\t}\n\n\t\tif (!published) {\n\t\t\tconst current = await repo.findById(id);\n\t\t\tif (\n\t\t\t\tcurrent &&\n\t\t\t\t(current.status === \"pending\" || current.status === \"ready\") &&\n\t\t\t\tcurrent.size === expectedSize &&\n\t\t\t\t(current.storageKey === attemptKey ||\n\t\t\t\t\texpectedSize === 0 ||\n\t\t\t\t\t(contentHash !== undefined && current.contentHash === contentHash)) &&\n\t\t\t\t(await getStoredSize(emdash.storage, current.storageKey)) === expectedSize\n\t\t\t) {\n\t\t\t\tif (current.storageKey !== attemptKey) {\n\t\t\t\t\tawait removeUploadAttempt(emdash.storage, repo, attemptKey);\n\t\t\t\t}\n\t\t\t\treturn apiSuccess({ uploaded: true, size: expectedSize });\n\t\t\t}\n\t\t\tawait removeUploadAttempt(emdash.storage, repo, attemptKey);\n\t\t\treturn apiError(\"INVALID_STATE\", \"Media item is no longer pending\", 400);\n\t\t}\n\n\t\tawait removeUploadAttempt(emdash.storage, repo, media.storageKey);\n\t\treturn apiSuccess({ uploaded: true, size: receivedSize });\n\t} catch (error) {\n\t\treturn handleError(error, \"Upload failed\", \"UPLOAD_ERROR\");\n\t}\n};\n"],"mappings":"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"}
1
+ {"version":3,"file":"upload.mjs","names":[],"sources":["../../../../../../src/astro/routes/api/media/[id]/upload.ts"],"sourcesContent":["import type { APIRoute } from \"astro\";\nimport type { Storage } from \"emdash\";\nimport { ulid } from \"ulidx\";\n\nimport { requireOwnerPerm, requirePerm } from \"#api/authorize.js\";\nimport { apiError, apiSuccess, handleError } from \"#api/error.js\";\nimport { MediaRepository } from \"#db/repositories/media.js\";\nimport { normalizeMime } from \"#media/mime.js\";\nimport { removeUploadAttempt } from \"#media/upload-attempts.js\";\nimport { computeContentHash, MAX_CONTENT_HASH_BYTES } from \"#utils/hash.js\";\n\nexport const prerender = false;\n\nconst INITIAL_HASH_BUFFER_BYTES = 64 * 1024;\n\ntype FixedLengthStreamConstructor = new (\n\texpectedLength: number | bigint,\n) => TransformStream<ArrayBuffer | ArrayBufferView, Uint8Array>;\n\ndeclare const FixedLengthStream: FixedLengthStreamConstructor | undefined;\n\nclass UploadBodyError extends Error {\n\treadonly code: \"PAYLOAD_TOO_LARGE\" | \"UPLOAD_SIZE_MISMATCH\";\n\n\tconstructor(code: \"PAYLOAD_TOO_LARGE\" | \"UPLOAD_SIZE_MISMATCH\") {\n\t\tsuper(code);\n\t\tthis.code = code;\n\t}\n}\n\nfunction findUploadBodyError(error: unknown): UploadBodyError | null {\n\tlet current = error;\n\tfor (let depth = 0; depth < 5 && current instanceof Error; depth++) {\n\t\tif (current instanceof UploadBodyError) return current;\n\t\tcurrent = current.cause;\n\t}\n\treturn null;\n}\n\nfunction preserveKnownLength(\n\tbody: ReadableStream<Uint8Array>,\n\texpectedLength: number,\n): ReadableStream<Uint8Array> {\n\tif (typeof FixedLengthStream === \"undefined\") return body;\n\treturn body.pipeThrough(new FixedLengthStream(expectedLength));\n}\n\nfunction createUploadAttemptKey(key: string): string {\n\tconst pathSeparator = key.lastIndexOf(\"/\");\n\tconst extensionSeparator = key.lastIndexOf(\".\");\n\tif (extensionSeparator > pathSeparator) {\n\t\treturn `${key.slice(0, extensionSeparator)}.${ulid()}${key.slice(extensionSeparator)}`;\n\t}\n\treturn `${key}.${ulid()}`;\n}\n\nasync function getStoredSize(storage: Storage, key: string): Promise<number | null> {\n\tif (!(await storage.exists(key))) return null;\n\tconst download = await storage.download(key);\n\ttry {\n\t\treturn download.size;\n\t} finally {\n\t\ttry {\n\t\t\tawait download.body.cancel();\n\t\t} catch (error) {\n\t\t\tconsole.error(\"[media] upload download cancellation failed:\", error);\n\t\t}\n\t}\n}\n\nexport const PUT: APIRoute = async ({ params, request, locals }) => {\n\tconst { emdash, user } = locals;\n\tconst { id } = params;\n\n\tconst denied = requirePerm(user, \"media:upload\");\n\tif (denied) return denied;\n\n\tif (!id) {\n\t\treturn apiError(\"INVALID_REQUEST\", \"Media ID is required\", 400);\n\t}\n\n\tif (!emdash?.db) {\n\t\treturn apiError(\"NOT_CONFIGURED\", \"EmDash is not initialized\", 500);\n\t}\n\n\tif (!emdash.storage) {\n\t\treturn apiError(\"NO_STORAGE\", \"Storage not configured\", 500);\n\t}\n\n\ttry {\n\t\tconst repo = new MediaRepository(emdash.db);\n\t\tconst media = await repo.findById(id);\n\t\tif (!media) {\n\t\t\treturn apiError(\"NOT_FOUND\", `Media item not found: ${id}`, 404);\n\t\t}\n\n\t\tif (media.status !== \"pending\") {\n\t\t\treturn apiError(\"INVALID_STATE\", `Media item is not pending: ${media.status}`, 400);\n\t\t}\n\n\t\tconst ownerDenied = requireOwnerPerm(\n\t\t\tuser,\n\t\t\tmedia.authorId ?? \"\",\n\t\t\t\"media:upload\",\n\t\t\t\"media:edit_any\",\n\t\t);\n\t\tif (ownerDenied) return ownerDenied;\n\n\t\tif (!Number.isSafeInteger(media.size) || media.size === null || media.size < 0) {\n\t\t\treturn apiError(\"INVALID_STATE\", \"Pending media item has no valid upload size\", 400);\n\t\t}\n\t\tconst expectedSize = media.size;\n\n\t\tconst contentType = request.headers.get(\"Content-Type\");\n\t\tif (!contentType || normalizeMime(contentType) !== media.mimeType) {\n\t\t\treturn apiError(\"INVALID_TYPE\", \"Upload content type does not match the media item\", 400);\n\t\t}\n\n\t\tconst requestBody =\n\t\t\trequest.body ??\n\t\t\t(expectedSize === 0\n\t\t\t\t? new ReadableStream<Uint8Array>({\n\t\t\t\t\t\tstart(controller) {\n\t\t\t\t\t\t\tcontroller.close();\n\t\t\t\t\t\t},\n\t\t\t\t\t})\n\t\t\t\t: null);\n\t\tif (!requestBody) {\n\t\t\treturn apiError(\"NO_FILE\", \"No file provided\", 400);\n\t\t}\n\n\t\tconst contentLength = request.headers.get(\"Content-Length\");\n\t\tif (contentLength !== null) {\n\t\t\tconst declaredSize = Number(contentLength);\n\t\t\tif (!Number.isSafeInteger(declaredSize) || declaredSize < 0) {\n\t\t\t\treturn apiError(\"INVALID_REQUEST\", \"Invalid Content-Length header\", 400);\n\t\t\t}\n\t\t\tif (declaredSize > expectedSize) {\n\t\t\t\treturn apiError(\"PAYLOAD_TOO_LARGE\", \"Upload exceeds the expected size\", 413);\n\t\t\t}\n\t\t\tif (declaredSize !== expectedSize) {\n\t\t\t\treturn apiError(\"UPLOAD_SIZE_MISMATCH\", \"Upload size does not match the media item\", 400);\n\t\t\t}\n\t\t}\n\n\t\tlet receivedSize = 0;\n\t\tconst shouldHash = expectedSize > 0 && expectedSize <= MAX_CONTENT_HASH_BYTES;\n\t\tlet hashBytes: Uint8Array | null = null;\n\t\tconst checkedBody = requestBody.pipeThrough(\n\t\t\tnew TransformStream<Uint8Array, Uint8Array>({\n\t\t\t\ttransform(chunk, controller) {\n\t\t\t\t\tconst offset = receivedSize;\n\t\t\t\t\treceivedSize += chunk.byteLength;\n\t\t\t\t\tif (receivedSize > expectedSize) {\n\t\t\t\t\t\tcontroller.error(new UploadBodyError(\"PAYLOAD_TOO_LARGE\"));\n\t\t\t\t\t\treturn;\n\t\t\t\t\t}\n\t\t\t\t\tif (shouldHash && chunk.byteLength > 0) {\n\t\t\t\t\t\tif (!hashBytes) {\n\t\t\t\t\t\t\thashBytes = new Uint8Array(\n\t\t\t\t\t\t\t\tMath.min(expectedSize, Math.max(INITIAL_HASH_BUFFER_BYTES, receivedSize)),\n\t\t\t\t\t\t\t);\n\t\t\t\t\t\t} else if (receivedSize > hashBytes.byteLength) {\n\t\t\t\t\t\t\tconst grown = new Uint8Array(\n\t\t\t\t\t\t\t\tMath.min(expectedSize, Math.max(receivedSize, hashBytes.byteLength * 2)),\n\t\t\t\t\t\t\t);\n\t\t\t\t\t\t\tgrown.set(hashBytes);\n\t\t\t\t\t\t\thashBytes = grown;\n\t\t\t\t\t\t}\n\t\t\t\t\t\thashBytes.set(chunk, offset);\n\t\t\t\t\t}\n\t\t\t\t\tcontroller.enqueue(chunk);\n\t\t\t\t},\n\t\t\t\tflush(controller) {\n\t\t\t\t\tif (receivedSize !== expectedSize) {\n\t\t\t\t\t\tcontroller.error(new UploadBodyError(\"UPLOAD_SIZE_MISMATCH\"));\n\t\t\t\t\t}\n\t\t\t\t},\n\t\t\t}),\n\t\t);\n\t\tconst body = preserveKnownLength(checkedBody, expectedSize);\n\n\t\tconst attemptKey = createUploadAttemptKey(media.storageKey);\n\t\tawait repo.createUploadAttempt(id, attemptKey);\n\n\t\tlet attemptSize: number;\n\t\ttry {\n\t\t\tconst result = await emdash.storage.upload({\n\t\t\t\tkey: attemptKey,\n\t\t\t\tbody,\n\t\t\t\tcontentType: media.mimeType,\n\t\t\t});\n\t\t\tattemptSize = result.size;\n\t\t} catch (error) {\n\t\t\tawait removeUploadAttempt(emdash.storage, repo, attemptKey);\n\t\t\tconst bodyError = findUploadBodyError(error);\n\t\t\tif (bodyError?.code === \"PAYLOAD_TOO_LARGE\") {\n\t\t\t\treturn apiError(\"PAYLOAD_TOO_LARGE\", \"Upload exceeds the expected size\", 413);\n\t\t\t}\n\t\t\tif (bodyError?.code === \"UPLOAD_SIZE_MISMATCH\") {\n\t\t\t\treturn apiError(\"UPLOAD_SIZE_MISMATCH\", \"Upload size does not match the media item\", 400);\n\t\t\t}\n\t\t\treturn handleError(error, \"Upload failed\", \"UPLOAD_ERROR\");\n\t\t}\n\n\t\tif (receivedSize !== expectedSize || attemptSize !== expectedSize) {\n\t\t\tawait removeUploadAttempt(emdash.storage, repo, attemptKey);\n\t\t\treturn apiError(\"UPLOAD_SIZE_MISMATCH\", \"Upload size does not match the media item\", 400);\n\t\t}\n\t\tconst contentHash = hashBytes ? await computeContentHash(hashBytes) : undefined;\n\n\t\tlet published: boolean;\n\t\ttry {\n\t\t\tpublished = await repo.publishPendingStorageKey(\n\t\t\t\tid,\n\t\t\t\tmedia.storageKey,\n\t\t\t\tattemptKey,\n\t\t\t\tcontentHash,\n\t\t\t);\n\t\t} catch (error) {\n\t\t\ttry {\n\t\t\t\tconst current = await repo.findById(id);\n\t\t\t\tif (\n\t\t\t\t\tcurrent?.storageKey === attemptKey &&\n\t\t\t\t\t(current.status === \"pending\" || current.status === \"ready\") &&\n\t\t\t\t\tcurrent.size === expectedSize &&\n\t\t\t\t\t(await getStoredSize(emdash.storage, attemptKey)) === expectedSize\n\t\t\t\t) {\n\t\t\t\t\treturn apiSuccess({ uploaded: true, size: expectedSize });\n\t\t\t\t}\n\t\t\t} catch (verificationError) {\n\t\t\t\tconsole.error(\"[media] upload publication verification failed:\", verificationError);\n\t\t\t}\n\t\t\treturn handleError(error, \"Upload failed\", \"UPLOAD_ERROR\");\n\t\t}\n\n\t\tif (!published) {\n\t\t\tconst current = await repo.findById(id);\n\t\t\tif (\n\t\t\t\tcurrent &&\n\t\t\t\t(current.status === \"pending\" || current.status === \"ready\") &&\n\t\t\t\tcurrent.size === expectedSize &&\n\t\t\t\t(current.storageKey === attemptKey ||\n\t\t\t\t\texpectedSize === 0 ||\n\t\t\t\t\t(contentHash !== undefined && current.contentHash === contentHash)) &&\n\t\t\t\t(await getStoredSize(emdash.storage, current.storageKey)) === expectedSize\n\t\t\t) {\n\t\t\t\tif (current.storageKey !== attemptKey) {\n\t\t\t\t\tawait removeUploadAttempt(emdash.storage, repo, attemptKey);\n\t\t\t\t}\n\t\t\t\treturn apiSuccess({ uploaded: true, size: expectedSize });\n\t\t\t}\n\t\t\tawait removeUploadAttempt(emdash.storage, repo, attemptKey);\n\t\t\treturn apiError(\"INVALID_STATE\", \"Media item is no longer pending\", 400);\n\t\t}\n\n\t\tawait removeUploadAttempt(emdash.storage, repo, media.storageKey);\n\t\treturn apiSuccess({ uploaded: true, size: receivedSize });\n\t} catch (error) {\n\t\treturn handleError(error, \"Upload failed\", \"UPLOAD_ERROR\");\n\t}\n};\n"],"mappings":"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"}
@@ -1,27 +1,40 @@
1
- import "../../../../../dialect-helpers-CtYdsX4W.mjs";
2
- import "../../../../../config-CGVeT8Hc.mjs";
1
+ import "../../../../../dialect-helpers-7_IqPdh9.mjs";
2
+ import "../../../../../config-CvmjJcVw.mjs";
3
3
  import "../../../../../base64-DvnNgP7e.mjs";
4
4
  import "../../../../../types-BkUg2yHx.mjs";
5
- import "../../../../../media-TBlKCwo7.mjs";
6
- import "../../../../../fts-manager-CjX0e5BR.mjs";
7
- import "../../../../../capture-triggers-gxQxnxrJ.mjs";
8
- import "../../../../../activation-CaMfdBt1.mjs";
9
- import "../../../../../collection-deletion-C-yQB9fq.mjs";
10
- import "../../../../../content-refresh-iRBhQHr5.mjs";
11
- import "../../../../../media-usage-work-Cu5DqewW.mjs";
12
- import "../../../../../content-repair-8uHRIJkd.mjs";
13
- import { t as handleMediaUsageDetails } from "../../../../../media-usage-Bd9rFPKN.mjs";
14
- import { a as unwrapResult, t as apiError } from "../../../../../error-CCTCskie.mjs";
15
- import { i as parseQuery, t as isParseError } from "../../../../../parse-Cr379Av9.mjs";
16
- import "../../../../../redirects-BCiTaIQ-.mjs";
17
- import { Sn as mediaUsageDetailsQuery } from "../../../../../entry-lock-CwWdnFyR.mjs";
18
- import "../../../../../comments-BVzzt6x5.mjs";
19
- import "../../../../../relations-B4w-G5U9.mjs";
20
- import "../../../../../status-DLoBmcDz.mjs";
5
+ import "../../../../../media-Qp5S3eH3.mjs";
6
+ import "../../../../../request-cache-DzLYKm_x.mjs";
7
+ import "../../../../../fts-manager-S-K0laoS.mjs";
8
+ import "../../../../../collection-slugs-cache-CjGk__zp.mjs";
9
+ import "../../../../../capture-triggers-kJyl_yyM.mjs";
10
+ import "../../../../../activation-LOkDM5WT.mjs";
11
+ import "../../../../../block-type-registry-DUI_3KxT.mjs";
12
+ import "../../../../../collection-deletion-BIm28mo3.mjs";
13
+ import "../../../../../errors-DgE1zJGG.mjs";
14
+ import "../../../../../canonical-YhEQezjg.mjs";
15
+ import "../../../../../digest-BarSh-pN.mjs";
16
+ import "../../../../../hash-SDAW6zC-.mjs";
17
+ import "../../../../../zod-generator-D6uE4WiS.mjs";
18
+ import "../../../../../media-usage-work-C2OZLCAd.mjs";
19
+ import "../../../../../content-repair-Q8IUrpLL.mjs";
20
+ import "../../../../../collection-deletion-processor-Br6rxs3u.mjs";
21
+ import { t as handleMediaUsageDetails } from "../../../../../media-usage-My-Vi-ex.mjs";
22
+ import "../../../../../settings-DYidIB26.mjs";
23
+ import "../../../../../site-settings-DOgRUoFX.mjs";
24
+ import "../../../../../errors-BF0_LFhW.mjs";
25
+ import { a as unwrapResult, t as apiError } from "../../../../../error-CfvOHP0M.mjs";
26
+ import { i as parseQuery, t as isParseError } from "../../../../../parse-DY6OD1j_.mjs";
27
+ import "../../../../../redirects-Cv9apQKj.mjs";
28
+ import "../../../../../entry-lock-BJYdBfXb.mjs";
29
+ import { J as mediaUsageDetailsQuery } from "../../../../../media-Pu1L6xir.mjs";
30
+ import "../../../../../comments-fHZ8ON9O.mjs";
31
+ import "../../../../../relations-CK9CYUyr.mjs";
32
+ import "../../../../../menus-BM7BPLOb.mjs";
33
+ import "../../../../../status-DZKIG4a9.mjs";
21
34
  import "../../../../../api/schemas/index.mjs";
22
- import "../../../../../api-tokens-DS1VzN7_.mjs";
23
- import { r as requirePerm } from "../../../../../authorize-BXpfMpp0.mjs";
24
- import { t as requireScope } from "../../../../../scopes-Bn8_rCSt.mjs";
35
+ import "../../../../../api-tokens-CE1ECIg0.mjs";
36
+ import { i as requirePerm } from "../../../../../authorize-seCifOMJ.mjs";
37
+ import { n as requireScope } from "../../../../../scopes-Dbk-ElhT.mjs";
25
38
 
26
39
  //#region src/astro/routes/api/media/[id]/usage.ts
27
40
  const prerender = false;
@@ -1 +1 @@
1
- {"version":3,"file":"usage.mjs","names":[],"sources":["../../../../../../src/astro/routes/api/media/[id]/usage.ts"],"sourcesContent":["import type { APIRoute } from \"astro\";\n\nimport { requirePerm } from \"#api/authorize.js\";\nimport { apiError, unwrapResult } from \"#api/error.js\";\nimport { handleMediaUsageDetails } from \"#api/handlers/media-usage.js\";\nimport { isParseError, parseQuery } from \"#api/parse.js\";\nimport { mediaUsageDetailsQuery } from \"#api/schemas.js\";\nimport { requireScope } from \"#auth/scopes.js\";\n\nexport const prerender = false;\n\nexport const GET: APIRoute = async ({ params, request, locals }) => {\n\tconst { emdash, user } = locals;\n\n\tconst mediaDenied = requirePerm(user, \"media:read\");\n\tif (mediaDenied) return mediaDenied;\n\tconst contentDenied = requirePerm(user, \"content:read_drafts\");\n\tif (contentDenied) return contentDenied;\n\tconst scopeDenied = requireScope(locals, \"admin\");\n\tif (scopeDenied) return scopeDenied;\n\n\tconst { id } = params;\n\tif (!id) return apiError(\"INVALID_REQUEST\", \"Media ID required\", 400);\n\tif (!emdash?.db) return apiError(\"NOT_CONFIGURED\", \"EmDash is not initialized\", 500);\n\n\tconst query = parseQuery(new URL(request.url), mediaUsageDetailsQuery);\n\tif (isParseError(query)) return query;\n\n\treturn unwrapResult(await handleMediaUsageDetails(emdash.db, id, query));\n};\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;AASA,MAAa,YAAY;AAEzB,MAAa,MAAgB,OAAO,EAAE,QAAQ,SAAS,aAAa;CACnE,MAAM,EAAE,QAAQ,SAAS;CAEzB,MAAM,cAAc,YAAY,MAAM,aAAa;AACnD,KAAI,YAAa,QAAO;CACxB,MAAM,gBAAgB,YAAY,MAAM,sBAAsB;AAC9D,KAAI,cAAe,QAAO;CAC1B,MAAM,cAAc,aAAa,QAAQ,QAAQ;AACjD,KAAI,YAAa,QAAO;CAExB,MAAM,EAAE,OAAO;AACf,KAAI,CAAC,GAAI,QAAO,SAAS,mBAAmB,qBAAqB,IAAI;AACrE,KAAI,CAAC,QAAQ,GAAI,QAAO,SAAS,kBAAkB,6BAA6B,IAAI;CAEpF,MAAM,QAAQ,WAAW,IAAI,IAAI,QAAQ,IAAI,EAAE,uBAAuB;AACtE,KAAI,aAAa,MAAM,CAAE,QAAO;AAEhC,QAAO,aAAa,MAAM,wBAAwB,OAAO,IAAI,IAAI,MAAM,CAAC"}
1
+ {"version":3,"file":"usage.mjs","names":[],"sources":["../../../../../../src/astro/routes/api/media/[id]/usage.ts"],"sourcesContent":["import type { APIRoute } from \"astro\";\n\nimport { requirePerm } from \"#api/authorize.js\";\nimport { apiError, unwrapResult } from \"#api/error.js\";\nimport { handleMediaUsageDetails } from \"#api/handlers/media-usage.js\";\nimport { isParseError, parseQuery } from \"#api/parse.js\";\nimport { mediaUsageDetailsQuery } from \"#api/schemas.js\";\nimport { requireScope } from \"#auth/scopes.js\";\n\nexport const prerender = false;\n\nexport const GET: APIRoute = async ({ params, request, locals }) => {\n\tconst { emdash, user } = locals;\n\n\tconst mediaDenied = requirePerm(user, \"media:read\");\n\tif (mediaDenied) return mediaDenied;\n\tconst contentDenied = requirePerm(user, \"content:read_drafts\");\n\tif (contentDenied) return contentDenied;\n\tconst scopeDenied = requireScope(locals, \"admin\");\n\tif (scopeDenied) return scopeDenied;\n\n\tconst { id } = params;\n\tif (!id) return apiError(\"INVALID_REQUEST\", \"Media ID required\", 400);\n\tif (!emdash?.db) return apiError(\"NOT_CONFIGURED\", \"EmDash is not initialized\", 500);\n\n\tconst query = parseQuery(new URL(request.url), mediaUsageDetailsQuery);\n\tif (isParseError(query)) return query;\n\n\treturn unwrapResult(await handleMediaUsageDetails(emdash.db, id, query));\n};\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AASA,MAAa,YAAY;AAEzB,MAAa,MAAgB,OAAO,EAAE,QAAQ,SAAS,aAAa;CACnE,MAAM,EAAE,QAAQ,SAAS;CAEzB,MAAM,cAAc,YAAY,MAAM,aAAa;AACnD,KAAI,YAAa,QAAO;CACxB,MAAM,gBAAgB,YAAY,MAAM,sBAAsB;AAC9D,KAAI,cAAe,QAAO;CAC1B,MAAM,cAAc,aAAa,QAAQ,QAAQ;AACjD,KAAI,YAAa,QAAO;CAExB,MAAM,EAAE,OAAO;AACf,KAAI,CAAC,GAAI,QAAO,SAAS,mBAAmB,qBAAqB,IAAI;AACrE,KAAI,CAAC,QAAQ,GAAI,QAAO,SAAS,kBAAkB,6BAA6B,IAAI;CAEpF,MAAM,QAAQ,WAAW,IAAI,IAAI,QAAQ,IAAI,EAAE,uBAAuB;AACtE,KAAI,aAAa,MAAM,CAAE,QAAO;AAEhC,QAAO,aAAa,MAAM,wBAAwB,OAAO,IAAI,IAAI,MAAM,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"_id_.d.mts","names":[],"sources":["../../../../../src/astro/routes/api/media/[id].ts"],"mappings":";;;cAkBa,SAAA;;;;cAKA,GAAA,EAAK,QAAA;AAkClB;;;;;AAAA,cAAa,GAAA,EAAK,QAAA;;;;;;cAqDL,MAAA,EAAQ,QAAA"}
1
+ {"version":3,"file":"_id_.d.mts","names":[],"sources":["../../../../../src/astro/routes/api/media/[id].ts"],"mappings":";;;cAea,SAAA;;;;cAKA,GAAA,EAAK,QAAA;AAkClB;;;;;AAAA,cAAa,GAAA,EAAK,QAAA;;;;;;cAqDL,MAAA,EAAQ,QAAA"}
@@ -1,26 +1,38 @@
1
- import "../../../../dialect-helpers-CtYdsX4W.mjs";
2
- import "../../../../config-CGVeT8Hc.mjs";
1
+ import "../../../../dialect-helpers-7_IqPdh9.mjs";
2
+ import "../../../../config-CvmjJcVw.mjs";
3
3
  import "../../../../base64-DvnNgP7e.mjs";
4
4
  import "../../../../types-BkUg2yHx.mjs";
5
- import { t as MediaRepository } from "../../../../media-TBlKCwo7.mjs";
6
- import "../../../../fts-manager-CjX0e5BR.mjs";
7
- import "../../../../capture-triggers-gxQxnxrJ.mjs";
8
- import "../../../../activation-CaMfdBt1.mjs";
9
- import "../../../../collection-deletion-C-yQB9fq.mjs";
10
- import "../../../../content-refresh-iRBhQHr5.mjs";
11
- import "../../../../media-usage-work-Cu5DqewW.mjs";
12
- import "../../../../content-repair-8uHRIJkd.mjs";
13
- import { a as handleMediaUsageSummaries } from "../../../../media-usage-Bd9rFPKN.mjs";
14
- import { a as unwrapResult, n as apiSuccess, r as handleError, t as apiError } from "../../../../error-CCTCskie.mjs";
15
- import { i as parseQuery, n as parseBody, t as isParseError } from "../../../../parse-Cr379Av9.mjs";
16
- import "../../../../redirects-BCiTaIQ-.mjs";
17
- import { Ht as mediaGetQuery, nn as mediaUpdateBody } from "../../../../entry-lock-CwWdnFyR.mjs";
18
- import "../../../../comments-BVzzt6x5.mjs";
19
- import "../../../../relations-B4w-G5U9.mjs";
20
- import "../../../../status-DLoBmcDz.mjs";
5
+ import "../../../../media-Qp5S3eH3.mjs";
6
+ import "../../../../request-cache-DzLYKm_x.mjs";
7
+ import "../../../../fts-manager-S-K0laoS.mjs";
8
+ import "../../../../collection-slugs-cache-CjGk__zp.mjs";
9
+ import "../../../../capture-triggers-kJyl_yyM.mjs";
10
+ import "../../../../activation-LOkDM5WT.mjs";
11
+ import "../../../../block-type-registry-DUI_3KxT.mjs";
12
+ import "../../../../collection-deletion-BIm28mo3.mjs";
13
+ import "../../../../errors-DgE1zJGG.mjs";
14
+ import "../../../../canonical-YhEQezjg.mjs";
15
+ import "../../../../digest-BarSh-pN.mjs";
16
+ import "../../../../hash-SDAW6zC-.mjs";
17
+ import "../../../../zod-generator-D6uE4WiS.mjs";
18
+ import "../../../../media-usage-work-C2OZLCAd.mjs";
19
+ import "../../../../content-repair-Q8IUrpLL.mjs";
20
+ import "../../../../collection-deletion-processor-Br6rxs3u.mjs";
21
+ import { a as handleMediaUsageSummaries } from "../../../../media-usage-My-Vi-ex.mjs";
22
+ import "../../../../settings-DYidIB26.mjs";
23
+ import "../../../../site-settings-DOgRUoFX.mjs";
24
+ import "../../../../errors-BF0_LFhW.mjs";
25
+ import { a as unwrapResult, n as apiSuccess, r as handleError, t as apiError } from "../../../../error-CfvOHP0M.mjs";
26
+ import { i as parseQuery, n as parseBody, t as isParseError } from "../../../../parse-DY6OD1j_.mjs";
27
+ import "../../../../redirects-Cv9apQKj.mjs";
28
+ import "../../../../entry-lock-BJYdBfXb.mjs";
29
+ import { O as mediaUpdateBody, m as mediaGetQuery } from "../../../../media-Pu1L6xir.mjs";
30
+ import "../../../../comments-fHZ8ON9O.mjs";
31
+ import "../../../../relations-CK9CYUyr.mjs";
32
+ import "../../../../menus-BM7BPLOb.mjs";
33
+ import "../../../../status-DZKIG4a9.mjs";
21
34
  import "../../../../api/schemas/index.mjs";
22
- import { t as removeUploadAttempt } from "../../../../upload-attempts-2xdnoKGe.mjs";
23
- import { n as requireOwnerPerm, r as requirePerm, t as canReadMediaUsageCount } from "../../../../authorize-BXpfMpp0.mjs";
35
+ import { i as requirePerm, r as requireOwnerPerm, t as canReadMediaUsageCount } from "../../../../authorize-seCifOMJ.mjs";
24
36
 
25
37
  //#region src/astro/routes/api/media/[id].ts
26
38
  const prerender = false;
@@ -101,12 +113,11 @@ const DELETE = async ({ params, locals }) => {
101
113
  if (ownerDenied) return ownerDenied;
102
114
  const result = await emdash.handleMediaDelete(id);
103
115
  if (!result.success) return unwrapResult(result);
104
- if (typeof result.data !== "object" || result.data === null || !("storageKey" in result.data) || typeof result.data.storageKey !== "string") return apiError("MEDIA_DELETE_ERROR", "Failed to delete media", 500);
105
- if (emdash.storage) {
106
- const repo = new MediaRepository(emdash.db);
107
- await removeUploadAttempt(emdash.storage, repo, result.data.storageKey, { allowUntracked: true });
108
- }
109
- return apiSuccess({ deleted: true });
116
+ if (typeof result.data !== "object" || result.data === null || !("storageDeleted" in result.data) || typeof result.data.storageDeleted !== "boolean") return apiError("MEDIA_DELETE_ERROR", "Failed to delete media", 500);
117
+ return apiSuccess({
118
+ deleted: true,
119
+ storageDeleted: result.data.storageDeleted
120
+ });
110
121
  } catch (error) {
111
122
  return handleError(error, "Failed to delete media", "MEDIA_DELETE_ERROR");
112
123
  }
@@ -1 +1 @@
1
- {"version":3,"file":"_id_.mjs","names":[],"sources":["../../../../../src/astro/routes/api/media/[id].ts"],"sourcesContent":["/**\n * Single media item endpoint\n *\n * GET /_emdash/api/media/:id - Get media item\n * PUT /_emdash/api/media/:id - Update media metadata\n * DELETE /_emdash/api/media/:id - Delete media item\n */\n\nimport type { APIRoute } from \"astro\";\n\nimport { canReadMediaUsageCount, requireOwnerPerm, requirePerm } from \"#api/authorize.js\";\nimport { apiError, apiSuccess, handleError, unwrapResult } from \"#api/error.js\";\nimport { handleMediaUsageSummaries } from \"#api/handlers/media-usage.js\";\nimport { isParseError, parseBody, parseQuery } from \"#api/parse.js\";\nimport { mediaGetQuery, mediaUpdateBody } from \"#api/schemas.js\";\nimport { MediaRepository } from \"#db/repositories/media.js\";\nimport { removeUploadAttempt } from \"#media/upload-attempts.js\";\n\nexport const prerender = false;\n\n/**\n * Get media item\n */\nexport const GET: APIRoute = async ({ params, request, locals }) => {\n\tconst { emdash, user } = locals;\n\tconst { id } = params;\n\n\tconst readDenied = requirePerm(user, \"media:read\");\n\tif (readDenied) return readDenied;\n\n\tif (!id) {\n\t\treturn apiError(\"INVALID_REQUEST\", \"Media ID required\", 400);\n\t}\n\n\tif (!emdash?.handleMediaGet) {\n\t\treturn apiError(\"NOT_CONFIGURED\", \"EmDash is not initialized\", 500);\n\t}\n\tconst query = parseQuery(new URL(request.url), mediaGetQuery);\n\tif (isParseError(query)) return query;\n\n\tconst result = await emdash.handleMediaGet(id);\n\tif (!result.success || query.includeUsage !== \"1\") return unwrapResult(result);\n\n\tconst includeCount = canReadMediaUsageCount(user, locals.tokenScopes);\n\tconst usageResult = await handleMediaUsageSummaries(emdash.db, [id], { includeCount });\n\tif (!usageResult.success) return unwrapResult(usageResult);\n\tconst usage = usageResult.data[id];\n\tif (!usage) return apiError(\"MEDIA_USAGE_READ_ERROR\", \"Failed to read media usage\", 500);\n\n\treturn apiSuccess({ item: { ...result.data.item, usage } });\n};\n\n/**\n * Update media metadata\n *\n * Authors can edit their own media; editors+ can edit any.\n */\nexport const PUT: APIRoute = async ({ params, request, locals }) => {\n\tconst { emdash, user } = locals;\n\tconst { id } = params;\n\n\t// Minimum permission gate — ownership checked below\n\tconst editDenied = requirePerm(user, \"media:edit_own\");\n\tif (editDenied) return editDenied;\n\n\tif (!id) {\n\t\treturn apiError(\"INVALID_REQUEST\", \"Media ID required\", 400);\n\t}\n\n\tif (!emdash?.handleMediaGet || !emdash?.handleMediaUpdate) {\n\t\treturn apiError(\"NOT_CONFIGURED\", \"EmDash is not initialized\", 500);\n\t}\n\n\ttry {\n\t\t// Fetch media item for ownership check\n\t\tconst getResult = await emdash.handleMediaGet(id);\n\t\tif (!getResult.success || !getResult.data?.item) {\n\t\t\treturn apiError(\"NOT_FOUND\", \"Media item not found\", 404);\n\t\t}\n\n\t\tconst media = getResult.data.item;\n\n\t\t// Ownership check: authors can edit own, editors+ can edit any\n\t\tconst ownerDenied = requireOwnerPerm(user, media.authorId, \"media:edit_own\", \"media:edit_any\");\n\t\tif (ownerDenied) return ownerDenied;\n\n\t\tconst body = await parseBody(request, mediaUpdateBody);\n\t\tif (isParseError(body)) return body;\n\n\t\tconst result = await emdash.handleMediaUpdate(id, {\n\t\t\talt: body.alt,\n\t\t\tcaption: body.caption,\n\t\t\twidth: body.width,\n\t\t\theight: body.height,\n\t\t\tfolderId: body.folderId,\n\t\t\tfocalX: body.focalX,\n\t\t\tfocalY: body.focalY,\n\t\t});\n\n\t\treturn unwrapResult(result);\n\t} catch (error) {\n\t\treturn handleError(error, \"Failed to update media\", \"MEDIA_UPDATE_ERROR\");\n\t}\n};\n\n/**\n * Delete media item\n *\n * Authors can delete their own media; editors+ can delete any.\n */\nexport const DELETE: APIRoute = async ({ params, locals }) => {\n\tconst { emdash, user } = locals;\n\tconst { id } = params;\n\n\t// Minimum permission gate — ownership checked below\n\tconst deleteDenied = requirePerm(user, \"media:delete_own\");\n\tif (deleteDenied) return deleteDenied;\n\n\tif (!id) {\n\t\treturn apiError(\"INVALID_REQUEST\", \"Media ID required\", 400);\n\t}\n\n\tif (!emdash?.handleMediaGet || !emdash?.handleMediaDelete) {\n\t\treturn apiError(\"NOT_CONFIGURED\", \"EmDash is not initialized\", 500);\n\t}\n\n\ttry {\n\t\t// Fetch media item for ownership check and storage key\n\t\tconst getResult = await emdash.handleMediaGet(id);\n\t\tif (!getResult.success || !getResult.data?.item) {\n\t\t\treturn apiError(\"NOT_FOUND\", \"Media item not found\", 404);\n\t\t}\n\n\t\tconst media = getResult.data.item;\n\n\t\t// Ownership check: authors can delete own, editors+ can delete any\n\t\tconst ownerDenied = requireOwnerPerm(\n\t\t\tuser,\n\t\t\tmedia.authorId,\n\t\t\t\"media:delete_own\",\n\t\t\t\"media:delete_any\",\n\t\t);\n\t\tif (ownerDenied) return ownerDenied;\n\n\t\t// Delete from database — site-settings cache invalidation happens\n\t\t// in `EmDashRuntime.handleMediaDelete` so MCP/plugin paths inherit it.\n\t\tconst result = await emdash.handleMediaDelete(id);\n\t\tif (!result.success) return unwrapResult(result);\n\t\tif (\n\t\t\ttypeof result.data !== \"object\" ||\n\t\t\tresult.data === null ||\n\t\t\t!(\"storageKey\" in result.data) ||\n\t\t\ttypeof result.data.storageKey !== \"string\"\n\t\t) {\n\t\t\treturn apiError(\"MEDIA_DELETE_ERROR\", \"Failed to delete media\", 500);\n\t\t}\n\n\t\tif (emdash.storage) {\n\t\t\tconst repo = new MediaRepository(emdash.db);\n\t\t\tawait removeUploadAttempt(emdash.storage, repo, result.data.storageKey, {\n\t\t\t\tallowUntracked: true,\n\t\t\t});\n\t\t}\n\n\t\treturn apiSuccess({ deleted: true });\n\t} catch (error) {\n\t\treturn handleError(error, \"Failed to delete media\", \"MEDIA_DELETE_ERROR\");\n\t}\n};\n"],"mappings":"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"}
1
+ {"version":3,"file":"_id_.mjs","names":[],"sources":["../../../../../src/astro/routes/api/media/[id].ts"],"sourcesContent":["/**\n * Single media item endpoint\n *\n * GET /_emdash/api/media/:id - Get media item\n * PUT /_emdash/api/media/:id - Update media metadata\n * DELETE /_emdash/api/media/:id - Delete media item\n */\n\nimport type { APIRoute } from \"astro\";\n\nimport { canReadMediaUsageCount, requireOwnerPerm, requirePerm } from \"#api/authorize.js\";\nimport { apiError, apiSuccess, handleError, unwrapResult } from \"#api/error.js\";\nimport { handleMediaUsageSummaries } from \"#api/handlers/media-usage.js\";\nimport { isParseError, parseBody, parseQuery } from \"#api/parse.js\";\nimport { mediaGetQuery, mediaUpdateBody } from \"#api/schemas.js\";\nexport const prerender = false;\n\n/**\n * Get media item\n */\nexport const GET: APIRoute = async ({ params, request, locals }) => {\n\tconst { emdash, user } = locals;\n\tconst { id } = params;\n\n\tconst readDenied = requirePerm(user, \"media:read\");\n\tif (readDenied) return readDenied;\n\n\tif (!id) {\n\t\treturn apiError(\"INVALID_REQUEST\", \"Media ID required\", 400);\n\t}\n\n\tif (!emdash?.handleMediaGet) {\n\t\treturn apiError(\"NOT_CONFIGURED\", \"EmDash is not initialized\", 500);\n\t}\n\tconst query = parseQuery(new URL(request.url), mediaGetQuery);\n\tif (isParseError(query)) return query;\n\n\tconst result = await emdash.handleMediaGet(id);\n\tif (!result.success || query.includeUsage !== \"1\") return unwrapResult(result);\n\n\tconst includeCount = canReadMediaUsageCount(user, locals.tokenScopes);\n\tconst usageResult = await handleMediaUsageSummaries(emdash.db, [id], { includeCount });\n\tif (!usageResult.success) return unwrapResult(usageResult);\n\tconst usage = usageResult.data[id];\n\tif (!usage) return apiError(\"MEDIA_USAGE_READ_ERROR\", \"Failed to read media usage\", 500);\n\n\treturn apiSuccess({ item: { ...result.data.item, usage } });\n};\n\n/**\n * Update media metadata\n *\n * Authors can edit their own media; editors+ can edit any.\n */\nexport const PUT: APIRoute = async ({ params, request, locals }) => {\n\tconst { emdash, user } = locals;\n\tconst { id } = params;\n\n\t// Minimum permission gate — ownership checked below\n\tconst editDenied = requirePerm(user, \"media:edit_own\");\n\tif (editDenied) return editDenied;\n\n\tif (!id) {\n\t\treturn apiError(\"INVALID_REQUEST\", \"Media ID required\", 400);\n\t}\n\n\tif (!emdash?.handleMediaGet || !emdash?.handleMediaUpdate) {\n\t\treturn apiError(\"NOT_CONFIGURED\", \"EmDash is not initialized\", 500);\n\t}\n\n\ttry {\n\t\t// Fetch media item for ownership check\n\t\tconst getResult = await emdash.handleMediaGet(id);\n\t\tif (!getResult.success || !getResult.data?.item) {\n\t\t\treturn apiError(\"NOT_FOUND\", \"Media item not found\", 404);\n\t\t}\n\n\t\tconst media = getResult.data.item;\n\n\t\t// Ownership check: authors can edit own, editors+ can edit any\n\t\tconst ownerDenied = requireOwnerPerm(user, media.authorId, \"media:edit_own\", \"media:edit_any\");\n\t\tif (ownerDenied) return ownerDenied;\n\n\t\tconst body = await parseBody(request, mediaUpdateBody);\n\t\tif (isParseError(body)) return body;\n\n\t\tconst result = await emdash.handleMediaUpdate(id, {\n\t\t\talt: body.alt,\n\t\t\tcaption: body.caption,\n\t\t\twidth: body.width,\n\t\t\theight: body.height,\n\t\t\tfolderId: body.folderId,\n\t\t\tfocalX: body.focalX,\n\t\t\tfocalY: body.focalY,\n\t\t});\n\n\t\treturn unwrapResult(result);\n\t} catch (error) {\n\t\treturn handleError(error, \"Failed to update media\", \"MEDIA_UPDATE_ERROR\");\n\t}\n};\n\n/**\n * Delete media item\n *\n * Authors can delete their own media; editors+ can delete any.\n */\nexport const DELETE: APIRoute = async ({ params, locals }) => {\n\tconst { emdash, user } = locals;\n\tconst { id } = params;\n\n\t// Minimum permission gate — ownership checked below\n\tconst deleteDenied = requirePerm(user, \"media:delete_own\");\n\tif (deleteDenied) return deleteDenied;\n\n\tif (!id) {\n\t\treturn apiError(\"INVALID_REQUEST\", \"Media ID required\", 400);\n\t}\n\n\tif (!emdash?.handleMediaGet || !emdash?.handleMediaDelete) {\n\t\treturn apiError(\"NOT_CONFIGURED\", \"EmDash is not initialized\", 500);\n\t}\n\n\ttry {\n\t\t// Fetch media item for ownership check and storage key\n\t\tconst getResult = await emdash.handleMediaGet(id);\n\t\tif (!getResult.success || !getResult.data?.item) {\n\t\t\treturn apiError(\"NOT_FOUND\", \"Media item not found\", 404);\n\t\t}\n\n\t\tconst media = getResult.data.item;\n\n\t\t// Ownership check: authors can delete own, editors+ can delete any\n\t\tconst ownerDenied = requireOwnerPerm(\n\t\t\tuser,\n\t\t\tmedia.authorId,\n\t\t\t\"media:delete_own\",\n\t\t\t\"media:delete_any\",\n\t\t);\n\t\tif (ownerDenied) return ownerDenied;\n\n\t\t// Storage deletion and site-settings cache invalidation happen in\n\t\t// `EmDashRuntime.handleMediaDelete` so the MCP tool inherits them.\n\t\tconst result = await emdash.handleMediaDelete(id);\n\t\tif (!result.success) return unwrapResult(result);\n\t\tif (\n\t\t\ttypeof result.data !== \"object\" ||\n\t\t\tresult.data === null ||\n\t\t\t!(\"storageDeleted\" in result.data) ||\n\t\t\ttypeof result.data.storageDeleted !== \"boolean\"\n\t\t) {\n\t\t\treturn apiError(\"MEDIA_DELETE_ERROR\", \"Failed to delete media\", 500);\n\t\t}\n\n\t\treturn apiSuccess({ deleted: true, storageDeleted: result.data.storageDeleted });\n\t} catch (error) {\n\t\treturn handleError(error, \"Failed to delete media\", \"MEDIA_DELETE_ERROR\");\n\t}\n};\n"],"mappings":"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"}
@@ -1,8 +1,10 @@
1
1
  import "../../../../../../base64-DvnNgP7e.mjs";
2
2
  import "../../../../../../types-BkUg2yHx.mjs";
3
- import { t as MediaRepository } from "../../../../../../media-TBlKCwo7.mjs";
4
- import { r as handleError, t as apiError } from "../../../../../../error-CCTCskie.mjs";
5
- import { r as requirePerm } from "../../../../../../authorize-BXpfMpp0.mjs";
3
+ import { t as MediaRepository } from "../../../../../../media-Qp5S3eH3.mjs";
4
+ import "../../../../../../errors-DgE1zJGG.mjs";
5
+ import "../../../../../../errors-BF0_LFhW.mjs";
6
+ import { r as handleError, t as apiError } from "../../../../../../error-CfvOHP0M.mjs";
7
+ import { i as requirePerm } from "../../../../../../authorize-seCifOMJ.mjs";
6
8
 
7
9
  //#region src/astro/routes/api/media/asset/[id]/[filename].ts
8
10
  const prerender = false;
@@ -1 +1 @@
1
- {"version":3,"file":"_filename_.mjs","names":[],"sources":["../../../../../../../src/astro/routes/api/media/asset/[id]/[filename].ts"],"sourcesContent":["import type { APIRoute } from \"astro\";\n\nimport { requirePerm } from \"#api/authorize.js\";\nimport { apiError, handleError } from \"#api/error.js\";\nimport { MediaRepository } from \"#db/repositories/media.js\";\n\nexport const prerender = false;\n\nconst SAFE_INLINE_TYPES = new Set([\n\t\"image/jpeg\",\n\t\"image/png\",\n\t\"image/gif\",\n\t\"image/webp\",\n\t\"image/avif\",\n\t\"image/x-icon\",\n\t\"video/mp4\",\n\t\"video/webm\",\n\t\"audio/mpeg\",\n\t\"audio/wav\",\n\t\"audio/ogg\",\n]);\n\nexport const GET: APIRoute = async ({ params, locals }) => {\n\tconst { id, filename } = params;\n\tconst { emdash, user } = locals;\n\tconst denied = requirePerm(user, \"media:read\");\n\tif (denied) return denied;\n\tif (!id || !filename) return apiError(\"NOT_FOUND\", \"File not found\", 404);\n\tif (!emdash?.storage) return apiError(\"NOT_CONFIGURED\", \"Storage not configured\", 500);\n\n\ttry {\n\t\tconst item = await new MediaRepository(emdash.db).findById(id);\n\t\tif (!item || item.status !== \"ready\" || item.filename !== filename) {\n\t\t\treturn apiError(\"NOT_FOUND\", \"File not found\", 404);\n\t\t}\n\t\tconst result = await emdash.storage.download(item.storageKey);\n\t\tconst headers: Record<string, string> = {\n\t\t\t\"Content-Type\": result.contentType,\n\t\t\t\"Cache-Control\": \"private, max-age=0, must-revalidate\",\n\t\t\t\"X-Content-Type-Options\": \"nosniff\",\n\t\t\t\"Content-Security-Policy\":\n\t\t\t\t\"sandbox; default-src 'none'; img-src 'self'; style-src 'unsafe-inline'\",\n\t\t\t\"Content-Disposition\": SAFE_INLINE_TYPES.has(result.contentType) ? \"inline\" : \"attachment\",\n\t\t};\n\t\tif (result.size) headers[\"Content-Length\"] = String(result.size);\n\t\treturn new Response(result.body, { status: 200, headers });\n\t} catch (error) {\n\t\treturn handleError(error, \"Failed to serve file\", \"FILE_SERVE_ERROR\");\n\t}\n};\n"],"mappings":";;;;;;;AAMA,MAAa,YAAY;AAEzB,MAAM,oBAAoB,IAAI,IAAI;CACjC;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA,CAAC;AAEF,MAAa,MAAgB,OAAO,EAAE,QAAQ,aAAa;CAC1D,MAAM,EAAE,IAAI,aAAa;CACzB,MAAM,EAAE,QAAQ,SAAS;CACzB,MAAM,SAAS,YAAY,MAAM,aAAa;AAC9C,KAAI,OAAQ,QAAO;AACnB,KAAI,CAAC,MAAM,CAAC,SAAU,QAAO,SAAS,aAAa,kBAAkB,IAAI;AACzE,KAAI,CAAC,QAAQ,QAAS,QAAO,SAAS,kBAAkB,0BAA0B,IAAI;AAEtF,KAAI;EACH,MAAM,OAAO,MAAM,IAAI,gBAAgB,OAAO,GAAG,CAAC,SAAS,GAAG;AAC9D,MAAI,CAAC,QAAQ,KAAK,WAAW,WAAW,KAAK,aAAa,SACzD,QAAO,SAAS,aAAa,kBAAkB,IAAI;EAEpD,MAAM,SAAS,MAAM,OAAO,QAAQ,SAAS,KAAK,WAAW;EAC7D,MAAM,UAAkC;GACvC,gBAAgB,OAAO;GACvB,iBAAiB;GACjB,0BAA0B;GAC1B,2BACC;GACD,uBAAuB,kBAAkB,IAAI,OAAO,YAAY,GAAG,WAAW;GAC9E;AACD,MAAI,OAAO,KAAM,SAAQ,oBAAoB,OAAO,OAAO,KAAK;AAChE,SAAO,IAAI,SAAS,OAAO,MAAM;GAAE,QAAQ;GAAK;GAAS,CAAC;UAClD,OAAO;AACf,SAAO,YAAY,OAAO,wBAAwB,mBAAmB"}
1
+ {"version":3,"file":"_filename_.mjs","names":[],"sources":["../../../../../../../src/astro/routes/api/media/asset/[id]/[filename].ts"],"sourcesContent":["import type { APIRoute } from \"astro\";\n\nimport { requirePerm } from \"#api/authorize.js\";\nimport { apiError, handleError } from \"#api/error.js\";\nimport { MediaRepository } from \"#db/repositories/media.js\";\n\nexport const prerender = false;\n\nconst SAFE_INLINE_TYPES = new Set([\n\t\"image/jpeg\",\n\t\"image/png\",\n\t\"image/gif\",\n\t\"image/webp\",\n\t\"image/avif\",\n\t\"image/x-icon\",\n\t\"video/mp4\",\n\t\"video/webm\",\n\t\"audio/mpeg\",\n\t\"audio/wav\",\n\t\"audio/ogg\",\n]);\n\nexport const GET: APIRoute = async ({ params, locals }) => {\n\tconst { id, filename } = params;\n\tconst { emdash, user } = locals;\n\tconst denied = requirePerm(user, \"media:read\");\n\tif (denied) return denied;\n\tif (!id || !filename) return apiError(\"NOT_FOUND\", \"File not found\", 404);\n\tif (!emdash?.storage) return apiError(\"NOT_CONFIGURED\", \"Storage not configured\", 500);\n\n\ttry {\n\t\tconst item = await new MediaRepository(emdash.db).findById(id);\n\t\tif (!item || item.status !== \"ready\" || item.filename !== filename) {\n\t\t\treturn apiError(\"NOT_FOUND\", \"File not found\", 404);\n\t\t}\n\t\tconst result = await emdash.storage.download(item.storageKey);\n\t\tconst headers: Record<string, string> = {\n\t\t\t\"Content-Type\": result.contentType,\n\t\t\t\"Cache-Control\": \"private, max-age=0, must-revalidate\",\n\t\t\t\"X-Content-Type-Options\": \"nosniff\",\n\t\t\t\"Content-Security-Policy\":\n\t\t\t\t\"sandbox; default-src 'none'; img-src 'self'; style-src 'unsafe-inline'\",\n\t\t\t\"Content-Disposition\": SAFE_INLINE_TYPES.has(result.contentType) ? \"inline\" : \"attachment\",\n\t\t};\n\t\tif (result.size) headers[\"Content-Length\"] = String(result.size);\n\t\treturn new Response(result.body, { status: 200, headers });\n\t} catch (error) {\n\t\treturn handleError(error, \"Failed to serve file\", \"FILE_SERVE_ERROR\");\n\t}\n};\n"],"mappings":";;;;;;;;;AAMA,MAAa,YAAY;AAEzB,MAAM,oBAAoB,IAAI,IAAI;CACjC;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA,CAAC;AAEF,MAAa,MAAgB,OAAO,EAAE,QAAQ,aAAa;CAC1D,MAAM,EAAE,IAAI,aAAa;CACzB,MAAM,EAAE,QAAQ,SAAS;CACzB,MAAM,SAAS,YAAY,MAAM,aAAa;AAC9C,KAAI,OAAQ,QAAO;AACnB,KAAI,CAAC,MAAM,CAAC,SAAU,QAAO,SAAS,aAAa,kBAAkB,IAAI;AACzE,KAAI,CAAC,QAAQ,QAAS,QAAO,SAAS,kBAAkB,0BAA0B,IAAI;AAEtF,KAAI;EACH,MAAM,OAAO,MAAM,IAAI,gBAAgB,OAAO,GAAG,CAAC,SAAS,GAAG;AAC9D,MAAI,CAAC,QAAQ,KAAK,WAAW,WAAW,KAAK,aAAa,SACzD,QAAO,SAAS,aAAa,kBAAkB,IAAI;EAEpD,MAAM,SAAS,MAAM,OAAO,QAAQ,SAAS,KAAK,WAAW;EAC7D,MAAM,UAAkC;GACvC,gBAAgB,OAAO;GACvB,iBAAiB;GACjB,0BAA0B;GAC1B,2BACC;GACD,uBAAuB,kBAAkB,IAAI,OAAO,YAAY,GAAG,WAAW;GAC9E;AACD,MAAI,OAAO,KAAM,SAAQ,oBAAoB,OAAO,OAAO,KAAK;AAChE,SAAO,IAAI,SAAS,OAAO,MAAM;GAAE,QAAQ;GAAK;GAAS,CAAC;UAClD,OAAO;AACf,SAAO,YAAY,OAAO,wBAAwB,mBAAmB"}
@@ -1 +1 @@
1
- {"version":3,"file":"_...key_.d.mts","names":[],"sources":["../../../../../../src/astro/routes/api/media/file/[...key].ts"],"mappings":";;;cAWa,SAAA;AAAA,cAoBA,GAAA,EAAK,QAAA"}
1
+ {"version":3,"file":"_...key_.d.mts","names":[],"sources":["../../../../../../src/astro/routes/api/media/file/[...key].ts"],"mappings":";;;cAaa,SAAA;AAAA,cA4CA,GAAA,EAAK,QAAA"}
@@ -1,10 +1,39 @@
1
1
  import "../../../../../base64-DvnNgP7e.mjs";
2
2
  import "../../../../../types-BkUg2yHx.mjs";
3
- import { r as handleError, t as apiError } from "../../../../../error-CCTCskie.mjs";
3
+ import "../../../../../errors-DgE1zJGG.mjs";
4
+ import "../../../../../canonical-YhEQezjg.mjs";
5
+ import "../../../../../settings-DYidIB26.mjs";
6
+ import "../../../../../errors-BF0_LFhW.mjs";
7
+ import { r as handleError, t as apiError } from "../../../../../error-CfvOHP0M.mjs";
4
8
  import { IMMUTABLE_IMAGE_CACHE, MUTABLE_MEDIA_CACHE_CONTROL } from "../../../../../media/image-endpoint.mjs";
9
+ import "../../../../../kinds-CRu_T5T5.mjs";
10
+ import "../../../../../paths-JxokKIbr.mjs";
11
+ import { t as isRefusedStorageKey } from "../../../../../keys-yxLm5l35.mjs";
5
12
 
6
13
  //#region src/astro/routes/api/media/file/[...key].ts
7
14
  const prerender = false;
15
+ const MAX_KEY_DECODES = 3;
16
+ /**
17
+ * Whether a key is, or percent-decodes to, a key this route must refuse.
18
+ * Every decoding layer is checked because storage backends differ in whether
19
+ * they decode keys; a key that is still encoded after the last layer, or
20
+ * does not decode, is refused.
21
+ */
22
+ function isPrivateMediaKey(key) {
23
+ let candidate = key;
24
+ for (let layer = 0; layer <= MAX_KEY_DECODES; layer++) {
25
+ if (isRefusedStorageKey(candidate)) return true;
26
+ let decoded;
27
+ try {
28
+ decoded = decodeURIComponent(candidate);
29
+ } catch {
30
+ return true;
31
+ }
32
+ if (decoded === candidate) return false;
33
+ candidate = decoded;
34
+ }
35
+ return true;
36
+ }
8
37
  /**
9
38
  * Content types that are safe to display inline (simple raster/vector images, video, audio).
10
39
  * Everything else gets Content-Disposition: attachment to prevent script execution.
@@ -26,7 +55,7 @@ const GET = async ({ params, locals }) => {
26
55
  const { key } = params;
27
56
  const { emdash } = locals;
28
57
  if (!key) return apiError("NOT_FOUND", "File not found", 404);
29
- if (key.startsWith("backups/")) return apiError("NOT_FOUND", "File not found", 404);
58
+ if (isPrivateMediaKey(key)) return apiError("NOT_FOUND", "File not found", 404);
30
59
  if (!emdash?.storage) return apiError("NOT_CONFIGURED", "Storage not configured", 500);
31
60
  try {
32
61
  const result = await emdash.storage.download(key);