emdash 0.33.0 → 0.35.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 (916) hide show
  1. package/dist/{adapters-BMyNSSZi.d.mts → adapters-Bb1vG41D.d.mts} +33 -2
  2. package/dist/adapters-Bb1vG41D.d.mts.map +1 -0
  3. package/dist/{allowed-origins-CG1pACtS.mjs → allowed-origins-DW7sYyqg.mjs} +2 -2
  4. package/dist/{allowed-origins-CG1pACtS.mjs.map → allowed-origins-DW7sYyqg.mjs.map} +1 -1
  5. package/dist/api/route-utils.d.mts +3 -3
  6. package/dist/api/route-utils.mjs +22 -21
  7. package/dist/api/route-utils.mjs.map +1 -1
  8. package/dist/api/schemas/index.d.mts +2 -2
  9. package/dist/api/schemas/index.mjs +6 -5
  10. package/dist/{api-D2hunekQ.mjs → api-BeBglVxU.mjs} +98 -407
  11. package/dist/api-BeBglVxU.mjs.map +1 -0
  12. package/dist/{api-tokens-CSND0i1z.mjs → api-tokens-KO24G1Fd.mjs} +2 -2
  13. package/dist/{api-tokens-CSND0i1z.mjs.map → api-tokens-KO24G1Fd.mjs.map} +1 -1
  14. package/dist/{apply-kwNEJW2l.mjs → apply-kUDt80-G.mjs} +131 -107
  15. package/dist/apply-kUDt80-G.mjs.map +1 -0
  16. package/dist/astro/index.d.mts +12 -12
  17. package/dist/astro/index.d.mts.map +1 -1
  18. package/dist/astro/index.mjs +163 -49
  19. package/dist/astro/index.mjs.map +1 -1
  20. package/dist/astro/middleware/auth.d.mts +10 -10
  21. package/dist/astro/middleware/auth.mjs +8 -8
  22. package/dist/astro/middleware/media-usage-write-fence.d.mts +7 -0
  23. package/dist/astro/middleware/media-usage-write-fence.d.mts.map +1 -0
  24. package/dist/astro/middleware/media-usage-write-fence.mjs +35 -0
  25. package/dist/astro/middleware/media-usage-write-fence.mjs.map +1 -0
  26. package/dist/astro/middleware/redirect.d.mts.map +1 -1
  27. package/dist/astro/middleware/redirect.mjs +10 -7
  28. package/dist/astro/middleware/redirect.mjs.map +1 -1
  29. package/dist/astro/middleware/request-context.mjs +3 -3
  30. package/dist/astro/middleware/setup.mjs +1 -1
  31. package/dist/astro/middleware.d.mts +12 -11
  32. package/dist/astro/middleware.d.mts.map +1 -1
  33. package/dist/astro/middleware.mjs +1763 -173
  34. package/dist/astro/middleware.mjs.map +1 -1
  35. package/dist/astro/routes/api/admin/allowed-domains/_domain_.mjs +9 -8
  36. package/dist/astro/routes/api/admin/allowed-domains/_domain_.mjs.map +1 -1
  37. package/dist/astro/routes/api/admin/allowed-domains/index.mjs +9 -8
  38. package/dist/astro/routes/api/admin/allowed-domains/index.mjs.map +1 -1
  39. package/dist/astro/routes/api/admin/api-tokens/_id_.mjs +5 -5
  40. package/dist/astro/routes/api/admin/api-tokens/index.mjs +6 -6
  41. package/dist/astro/routes/api/admin/byline-fields/_slug_/usage.mjs +6 -6
  42. package/dist/astro/routes/api/admin/byline-fields/_slug_.mjs +12 -11
  43. package/dist/astro/routes/api/admin/byline-fields/_slug_.mjs.map +1 -1
  44. package/dist/astro/routes/api/admin/byline-fields/index.mjs +12 -11
  45. package/dist/astro/routes/api/admin/byline-fields/index.mjs.map +1 -1
  46. package/dist/astro/routes/api/admin/byline-fields/reorder.mjs +12 -11
  47. package/dist/astro/routes/api/admin/byline-fields/reorder.mjs.map +1 -1
  48. package/dist/astro/routes/api/admin/bylines/_id_/index.mjs +17 -17
  49. package/dist/astro/routes/api/admin/bylines/_id_/translations.mjs +17 -17
  50. package/dist/astro/routes/api/admin/bylines/index.mjs +17 -17
  51. package/dist/astro/routes/api/admin/comments/_id_/status.mjs +14 -13
  52. package/dist/astro/routes/api/admin/comments/_id_/status.mjs.map +1 -1
  53. package/dist/astro/routes/api/admin/comments/_id_.mjs +6 -6
  54. package/dist/astro/routes/api/admin/comments/bulk.mjs +12 -11
  55. package/dist/astro/routes/api/admin/comments/bulk.mjs.map +1 -1
  56. package/dist/astro/routes/api/admin/comments/counts.mjs +6 -6
  57. package/dist/astro/routes/api/admin/comments/index.mjs +12 -11
  58. package/dist/astro/routes/api/admin/comments/index.mjs.map +1 -1
  59. package/dist/astro/routes/api/admin/hooks/exclusive/_hookName_.mjs +5 -5
  60. package/dist/astro/routes/api/admin/hooks/exclusive/index.mjs +4 -4
  61. package/dist/astro/routes/api/admin/media-usage/collection-deletions/index.d.mts +8 -0
  62. package/dist/astro/routes/api/admin/media-usage/collection-deletions/index.d.mts.map +1 -0
  63. package/dist/astro/routes/api/admin/media-usage/collection-deletions/index.mjs +36 -0
  64. package/dist/astro/routes/api/admin/media-usage/collection-deletions/index.mjs.map +1 -0
  65. package/dist/astro/routes/api/admin/media-usage/collection-deletions/retry.d.mts +8 -0
  66. package/dist/astro/routes/api/admin/media-usage/collection-deletions/retry.d.mts.map +1 -0
  67. package/dist/astro/routes/api/admin/media-usage/collection-deletions/retry.mjs +36 -0
  68. package/dist/astro/routes/api/admin/media-usage/collection-deletions/retry.mjs.map +1 -0
  69. package/dist/astro/routes/api/admin/media-usage/repair.mjs +15 -14
  70. package/dist/astro/routes/api/admin/media-usage/repair.mjs.map +1 -1
  71. package/dist/astro/routes/api/admin/media-usage/work/index.d.mts +8 -0
  72. package/dist/astro/routes/api/admin/media-usage/work/index.d.mts.map +1 -0
  73. package/dist/astro/routes/api/admin/media-usage/work/index.mjs +37 -0
  74. package/dist/astro/routes/api/admin/media-usage/work/index.mjs.map +1 -0
  75. package/dist/astro/routes/api/admin/media-usage/work/retry.d.mts +8 -0
  76. package/dist/astro/routes/api/admin/media-usage/work/retry.d.mts.map +1 -0
  77. package/dist/astro/routes/api/admin/media-usage/work/retry.mjs +37 -0
  78. package/dist/astro/routes/api/admin/media-usage/work/retry.mjs.map +1 -0
  79. package/dist/astro/routes/api/admin/oauth-clients/_id_.mjs +5 -5
  80. package/dist/astro/routes/api/admin/oauth-clients/index.mjs +5 -5
  81. package/dist/astro/routes/api/admin/plugins/_id_/disable.d.mts.map +1 -1
  82. package/dist/astro/routes/api/admin/plugins/_id_/disable.mjs +51 -43
  83. package/dist/astro/routes/api/admin/plugins/_id_/disable.mjs.map +1 -1
  84. package/dist/astro/routes/api/admin/plugins/_id_/enable.d.mts.map +1 -1
  85. package/dist/astro/routes/api/admin/plugins/_id_/enable.mjs +51 -43
  86. package/dist/astro/routes/api/admin/plugins/_id_/enable.mjs.map +1 -1
  87. package/dist/astro/routes/api/admin/plugins/_id_/index.mjs +47 -42
  88. package/dist/astro/routes/api/admin/plugins/_id_/index.mjs.map +1 -1
  89. package/dist/astro/routes/api/admin/plugins/_id_/mcp.mjs +6 -6
  90. package/dist/astro/routes/api/admin/plugins/_id_/settings.mjs +47 -42
  91. package/dist/astro/routes/api/admin/plugins/_id_/settings.mjs.map +1 -1
  92. package/dist/astro/routes/api/admin/plugins/_id_/uninstall.d.mts.map +1 -1
  93. package/dist/astro/routes/api/admin/plugins/_id_/uninstall.mjs +50 -42
  94. package/dist/astro/routes/api/admin/plugins/_id_/uninstall.mjs.map +1 -1
  95. package/dist/astro/routes/api/admin/plugins/_id_/update.d.mts.map +1 -1
  96. package/dist/astro/routes/api/admin/plugins/_id_/update.mjs +50 -42
  97. package/dist/astro/routes/api/admin/plugins/_id_/update.mjs.map +1 -1
  98. package/dist/astro/routes/api/admin/plugins/index.mjs +47 -42
  99. package/dist/astro/routes/api/admin/plugins/index.mjs.map +1 -1
  100. package/dist/astro/routes/api/admin/plugins/marketplace/_id_/icon.mjs +4 -4
  101. package/dist/astro/routes/api/admin/plugins/marketplace/_id_/index.mjs +47 -42
  102. package/dist/astro/routes/api/admin/plugins/marketplace/_id_/index.mjs.map +1 -1
  103. package/dist/astro/routes/api/admin/plugins/marketplace/_id_/install.d.mts.map +1 -1
  104. package/dist/astro/routes/api/admin/plugins/marketplace/_id_/install.mjs +50 -42
  105. package/dist/astro/routes/api/admin/plugins/marketplace/_id_/install.mjs.map +1 -1
  106. package/dist/astro/routes/api/admin/plugins/marketplace/index.mjs +47 -42
  107. package/dist/astro/routes/api/admin/plugins/marketplace/index.mjs.map +1 -1
  108. package/dist/astro/routes/api/admin/plugins/registry/_id_/uninstall.d.mts.map +1 -1
  109. package/dist/astro/routes/api/admin/plugins/registry/_id_/uninstall.mjs +50 -42
  110. package/dist/astro/routes/api/admin/plugins/registry/_id_/uninstall.mjs.map +1 -1
  111. package/dist/astro/routes/api/admin/plugins/registry/_id_/update.d.mts.map +1 -1
  112. package/dist/astro/routes/api/admin/plugins/registry/_id_/update.mjs +51 -43
  113. package/dist/astro/routes/api/admin/plugins/registry/_id_/update.mjs.map +1 -1
  114. package/dist/astro/routes/api/admin/plugins/registry/artifact.mjs +47 -42
  115. package/dist/astro/routes/api/admin/plugins/registry/artifact.mjs.map +1 -1
  116. package/dist/astro/routes/api/admin/plugins/registry/install.d.mts.map +1 -1
  117. package/dist/astro/routes/api/admin/plugins/registry/install.mjs +51 -43
  118. package/dist/astro/routes/api/admin/plugins/registry/install.mjs.map +1 -1
  119. package/dist/astro/routes/api/admin/plugins/updates.mjs +47 -42
  120. package/dist/astro/routes/api/admin/plugins/updates.mjs.map +1 -1
  121. package/dist/astro/routes/api/admin/themes/marketplace/_id_/index.mjs +47 -42
  122. package/dist/astro/routes/api/admin/themes/marketplace/_id_/index.mjs.map +1 -1
  123. package/dist/astro/routes/api/admin/themes/marketplace/_id_/thumbnail.mjs +4 -4
  124. package/dist/astro/routes/api/admin/themes/marketplace/index.mjs +47 -42
  125. package/dist/astro/routes/api/admin/themes/marketplace/index.mjs.map +1 -1
  126. package/dist/astro/routes/api/admin/users/_id_/disable.mjs +3 -3
  127. package/dist/astro/routes/api/admin/users/_id_/enable.mjs +3 -3
  128. package/dist/astro/routes/api/admin/users/_id_/index.mjs +9 -8
  129. package/dist/astro/routes/api/admin/users/_id_/index.mjs.map +1 -1
  130. package/dist/astro/routes/api/admin/users/_id_/send-recovery.mjs +4 -4
  131. package/dist/astro/routes/api/admin/users/index.mjs +9 -8
  132. package/dist/astro/routes/api/admin/users/index.mjs.map +1 -1
  133. package/dist/astro/routes/api/auth/dev-bypass.d.mts.map +1 -1
  134. package/dist/astro/routes/api/auth/dev-bypass.mjs +5 -9
  135. package/dist/astro/routes/api/auth/dev-bypass.mjs.map +1 -1
  136. package/dist/astro/routes/api/auth/invite/accept.mjs +3 -3
  137. package/dist/astro/routes/api/auth/invite/complete.mjs +13 -12
  138. package/dist/astro/routes/api/auth/invite/complete.mjs.map +1 -1
  139. package/dist/astro/routes/api/auth/invite/index.mjs +10 -9
  140. package/dist/astro/routes/api/auth/invite/index.mjs.map +1 -1
  141. package/dist/astro/routes/api/auth/invite/register-options.mjs +12 -11
  142. package/dist/astro/routes/api/auth/invite/register-options.mjs.map +1 -1
  143. package/dist/astro/routes/api/auth/logout.mjs +4 -4
  144. package/dist/astro/routes/api/auth/magic-link/send.mjs +12 -11
  145. package/dist/astro/routes/api/auth/magic-link/send.mjs.map +1 -1
  146. package/dist/astro/routes/api/auth/magic-link/verify.mjs +4 -4
  147. package/dist/astro/routes/api/auth/me.mjs +10 -9
  148. package/dist/astro/routes/api/auth/me.mjs.map +1 -1
  149. package/dist/astro/routes/api/auth/mode.mjs +4 -4
  150. package/dist/astro/routes/api/auth/oauth/_provider_/callback.mjs +3 -3
  151. package/dist/astro/routes/api/auth/oauth/_provider_.mjs +2 -2
  152. package/dist/astro/routes/api/auth/passkey/_id_.mjs +9 -8
  153. package/dist/astro/routes/api/auth/passkey/_id_.mjs.map +1 -1
  154. package/dist/astro/routes/api/auth/passkey/index.mjs +3 -3
  155. package/dist/astro/routes/api/auth/passkey/options.mjs +14 -13
  156. package/dist/astro/routes/api/auth/passkey/options.mjs.map +1 -1
  157. package/dist/astro/routes/api/auth/passkey/register/options.mjs +12 -11
  158. package/dist/astro/routes/api/auth/passkey/register/options.mjs.map +1 -1
  159. package/dist/astro/routes/api/auth/passkey/register/verify.mjs +13 -12
  160. package/dist/astro/routes/api/auth/passkey/register/verify.mjs.map +1 -1
  161. package/dist/astro/routes/api/auth/passkey/verify.mjs +13 -12
  162. package/dist/astro/routes/api/auth/passkey/verify.mjs.map +1 -1
  163. package/dist/astro/routes/api/auth/signup/complete.mjs +13 -12
  164. package/dist/astro/routes/api/auth/signup/complete.mjs.map +1 -1
  165. package/dist/astro/routes/api/auth/signup/request.mjs +12 -11
  166. package/dist/astro/routes/api/auth/signup/request.mjs.map +1 -1
  167. package/dist/astro/routes/api/auth/signup/verify.mjs +3 -3
  168. package/dist/astro/routes/api/comments/_collection_/_contentId_/index.mjs +15 -14
  169. package/dist/astro/routes/api/comments/_collection_/_contentId_/index.mjs.map +1 -1
  170. package/dist/astro/routes/api/comments/_collection_/_contentId_/reactions.mjs +14 -13
  171. package/dist/astro/routes/api/comments/_collection_/_contentId_/reactions.mjs.map +1 -1
  172. package/dist/astro/routes/api/content/_collection_/_id_/compare.mjs +4 -4
  173. package/dist/astro/routes/api/content/_collection_/_id_/discard-draft.mjs +5 -5
  174. package/dist/astro/routes/api/content/_collection_/_id_/duplicate.mjs +5 -5
  175. package/dist/astro/routes/api/content/_collection_/_id_/permanent.mjs +4 -4
  176. package/dist/astro/routes/api/content/_collection_/_id_/preview-url.mjs +13 -13
  177. package/dist/astro/routes/api/content/_collection_/_id_/publish.mjs +11 -10
  178. package/dist/astro/routes/api/content/_collection_/_id_/publish.mjs.map +1 -1
  179. package/dist/astro/routes/api/content/_collection_/_id_/references/_relation_/children.mjs +18 -17
  180. package/dist/astro/routes/api/content/_collection_/_id_/references/_relation_/children.mjs.map +1 -1
  181. package/dist/astro/routes/api/content/_collection_/_id_/references/_relation_/parents.mjs +18 -17
  182. package/dist/astro/routes/api/content/_collection_/_id_/references/_relation_/parents.mjs.map +1 -1
  183. package/dist/astro/routes/api/content/_collection_/_id_/restore.mjs +5 -5
  184. package/dist/astro/routes/api/content/_collection_/_id_/revisions.mjs +4 -4
  185. package/dist/astro/routes/api/content/_collection_/_id_/schedule.mjs +11 -10
  186. package/dist/astro/routes/api/content/_collection_/_id_/schedule.mjs.map +1 -1
  187. package/dist/astro/routes/api/content/_collection_/_id_/terms/_taxonomy_.d.mts.map +1 -1
  188. package/dist/astro/routes/api/content/_collection_/_id_/terms/_taxonomy_.mjs +44 -31
  189. package/dist/astro/routes/api/content/_collection_/_id_/terms/_taxonomy_.mjs.map +1 -1
  190. package/dist/astro/routes/api/content/_collection_/_id_/translations.mjs +4 -4
  191. package/dist/astro/routes/api/content/_collection_/_id_/unpublish.mjs +5 -5
  192. package/dist/astro/routes/api/content/_collection_/_id_.mjs +11 -10
  193. package/dist/astro/routes/api/content/_collection_/_id_.mjs.map +1 -1
  194. package/dist/astro/routes/api/content/_collection_/authors.mjs +4 -4
  195. package/dist/astro/routes/api/content/_collection_/index.mjs +11 -10
  196. package/dist/astro/routes/api/content/_collection_/index.mjs.map +1 -1
  197. package/dist/astro/routes/api/content/_collection_/trash.mjs +10 -9
  198. package/dist/astro/routes/api/content/_collection_/trash.mjs.map +1 -1
  199. package/dist/astro/routes/api/dashboard.mjs +10 -8
  200. package/dist/astro/routes/api/dashboard.mjs.map +1 -1
  201. package/dist/astro/routes/api/dev/emails.mjs +4 -4
  202. package/dist/astro/routes/api/import/probe.d.mts +3 -3
  203. package/dist/astro/routes/api/import/probe.mjs +18 -16
  204. package/dist/astro/routes/api/import/probe.mjs.map +1 -1
  205. package/dist/astro/routes/api/import/wordpress/analyze.mjs +5 -5
  206. package/dist/astro/routes/api/import/wordpress/execute.d.mts +11 -11
  207. package/dist/astro/routes/api/import/wordpress/execute.mjs +15 -15
  208. package/dist/astro/routes/api/import/wordpress/execute.mjs.map +1 -1
  209. package/dist/astro/routes/api/import/wordpress/media.d.mts +10 -10
  210. package/dist/astro/routes/api/import/wordpress/media.mjs +14 -12
  211. package/dist/astro/routes/api/import/wordpress/media.mjs.map +1 -1
  212. package/dist/astro/routes/api/import/wordpress/prepare.mjs +13 -12
  213. package/dist/astro/routes/api/import/wordpress/prepare.mjs.map +1 -1
  214. package/dist/astro/routes/api/import/wordpress/rewrite-urls.d.mts +11 -11
  215. package/dist/astro/routes/api/import/wordpress/rewrite-urls.mjs +14 -14
  216. package/dist/astro/routes/api/import/wordpress-plugin/analyze.d.mts +1 -1
  217. package/dist/astro/routes/api/import/wordpress-plugin/analyze.mjs +18 -16
  218. package/dist/astro/routes/api/import/wordpress-plugin/analyze.mjs.map +1 -1
  219. package/dist/astro/routes/api/import/wordpress-plugin/callback.mjs +1 -1
  220. package/dist/astro/routes/api/import/wordpress-plugin/execute.d.mts +11 -11
  221. package/dist/astro/routes/api/import/wordpress-plugin/execute.mjs +28 -27
  222. package/dist/astro/routes/api/import/wordpress-plugin/execute.mjs.map +1 -1
  223. package/dist/astro/routes/api/manifest.mjs +5 -5
  224. package/dist/astro/routes/api/mcp.d.mts.map +1 -1
  225. package/dist/astro/routes/api/mcp.mjs +174 -72
  226. package/dist/astro/routes/api/mcp.mjs.map +1 -1
  227. package/dist/astro/routes/api/media/_id_/confirm.mjs +13 -11
  228. package/dist/astro/routes/api/media/_id_/confirm.mjs.map +1 -1
  229. package/dist/astro/routes/api/media/_id_/upload.mjs +6 -6
  230. package/dist/astro/routes/api/media/_id_/usage.mjs +17 -16
  231. package/dist/astro/routes/api/media/_id_/usage.mjs.map +1 -1
  232. package/dist/astro/routes/api/media/_id_.mjs +16 -15
  233. package/dist/astro/routes/api/media/_id_.mjs.map +1 -1
  234. package/dist/astro/routes/api/media/file/_...key_.mjs +3 -3
  235. package/dist/astro/routes/api/media/providers/_providerId_/_itemId_.mjs +4 -4
  236. package/dist/astro/routes/api/media/providers/_providerId_/index.mjs +4 -4
  237. package/dist/astro/routes/api/media/providers/index.mjs +4 -4
  238. package/dist/astro/routes/api/media/upload-url.mjs +11 -10
  239. package/dist/astro/routes/api/media/upload-url.mjs.map +1 -1
  240. package/dist/astro/routes/api/media.mjs +18 -15
  241. package/dist/astro/routes/api/media.mjs.map +1 -1
  242. package/dist/astro/routes/api/menus/_name_/items/_id_.mjs +11 -11
  243. package/dist/astro/routes/api/menus/_name_/items.mjs +11 -11
  244. package/dist/astro/routes/api/menus/_name_/reorder.mjs +11 -11
  245. package/dist/astro/routes/api/menus/_name_/translations.mjs +11 -11
  246. package/dist/astro/routes/api/menus/_name_.mjs +11 -11
  247. package/dist/astro/routes/api/menus/index.mjs +11 -11
  248. package/dist/astro/routes/api/oauth/authorize.mjs +6 -6
  249. package/dist/astro/routes/api/oauth/device/authorize.mjs +7 -7
  250. package/dist/astro/routes/api/oauth/device/code.mjs +10 -10
  251. package/dist/astro/routes/api/oauth/device/token.mjs +9 -9
  252. package/dist/astro/routes/api/oauth/register.mjs +4 -4
  253. package/dist/astro/routes/api/oauth/token/refresh.mjs +7 -7
  254. package/dist/astro/routes/api/oauth/token/revoke.mjs +7 -7
  255. package/dist/astro/routes/api/oauth/token.mjs +7 -7
  256. package/dist/astro/routes/api/openapi.json.mjs +152 -6
  257. package/dist/astro/routes/api/openapi.json.mjs.map +1 -1
  258. package/dist/astro/routes/api/plugins/_pluginId_/_...path_.d.mts.map +1 -1
  259. package/dist/astro/routes/api/plugins/_pluginId_/_...path_.mjs +8 -7
  260. package/dist/astro/routes/api/plugins/_pluginId_/_...path_.mjs.map +1 -1
  261. package/dist/astro/routes/api/redirects/404s/index.mjs +12 -11
  262. package/dist/astro/routes/api/redirects/404s/index.mjs.map +1 -1
  263. package/dist/astro/routes/api/redirects/404s/summary.mjs +12 -11
  264. package/dist/astro/routes/api/redirects/404s/summary.mjs.map +1 -1
  265. package/dist/astro/routes/api/redirects/_id_.mjs +13 -12
  266. package/dist/astro/routes/api/redirects/_id_.mjs.map +1 -1
  267. package/dist/astro/routes/api/redirects/index.mjs +13 -12
  268. package/dist/astro/routes/api/redirects/index.mjs.map +1 -1
  269. package/dist/astro/routes/api/relations/_id_/index.mjs +18 -17
  270. package/dist/astro/routes/api/relations/_id_/index.mjs.map +1 -1
  271. package/dist/astro/routes/api/relations/_id_/translations.mjs +13 -12
  272. package/dist/astro/routes/api/relations/_id_/translations.mjs.map +1 -1
  273. package/dist/astro/routes/api/relations/index.mjs +18 -17
  274. package/dist/astro/routes/api/relations/index.mjs.map +1 -1
  275. package/dist/astro/routes/api/revisions/_revisionId_/index.mjs +4 -4
  276. package/dist/astro/routes/api/revisions/_revisionId_/restore.mjs +5 -5
  277. package/dist/astro/routes/api/schema/collections/_slug_/fields/_fieldSlug_.mjs +47 -42
  278. package/dist/astro/routes/api/schema/collections/_slug_/fields/_fieldSlug_.mjs.map +1 -1
  279. package/dist/astro/routes/api/schema/collections/_slug_/fields/index.mjs +47 -42
  280. package/dist/astro/routes/api/schema/collections/_slug_/fields/index.mjs.map +1 -1
  281. package/dist/astro/routes/api/schema/collections/_slug_/fields/reorder.mjs +47 -42
  282. package/dist/astro/routes/api/schema/collections/_slug_/fields/reorder.mjs.map +1 -1
  283. package/dist/astro/routes/api/schema/collections/_slug_/index.d.mts.map +1 -1
  284. package/dist/astro/routes/api/schema/collections/_slug_/index.mjs +47 -42
  285. package/dist/astro/routes/api/schema/collections/_slug_/index.mjs.map +1 -1
  286. package/dist/astro/routes/api/schema/collections/index.mjs +47 -42
  287. package/dist/astro/routes/api/schema/collections/index.mjs.map +1 -1
  288. package/dist/astro/routes/api/schema/collections/reorder.mjs +47 -42
  289. package/dist/astro/routes/api/schema/collections/reorder.mjs.map +1 -1
  290. package/dist/astro/routes/api/schema/index.mjs +10 -9
  291. package/dist/astro/routes/api/schema/index.mjs.map +1 -1
  292. package/dist/astro/routes/api/schema/orphans/_slug_.mjs +47 -42
  293. package/dist/astro/routes/api/schema/orphans/_slug_.mjs.map +1 -1
  294. package/dist/astro/routes/api/schema/orphans/index.mjs +47 -42
  295. package/dist/astro/routes/api/schema/orphans/index.mjs.map +1 -1
  296. package/dist/astro/routes/api/search/enable.mjs +13 -13
  297. package/dist/astro/routes/api/search/index.mjs +12 -12
  298. package/dist/astro/routes/api/search/rebuild.mjs +13 -13
  299. package/dist/astro/routes/api/search/stats.mjs +8 -8
  300. package/dist/astro/routes/api/search/suggest.mjs +12 -12
  301. package/dist/astro/routes/api/sections/_slug_.mjs +12 -11
  302. package/dist/astro/routes/api/sections/_slug_.mjs.map +1 -1
  303. package/dist/astro/routes/api/sections/index.mjs +12 -11
  304. package/dist/astro/routes/api/sections/index.mjs.map +1 -1
  305. package/dist/astro/routes/api/settings/backups/archives/_name_.mjs +7 -7
  306. package/dist/astro/routes/api/settings/backups/archives/index.mjs +6 -6
  307. package/dist/astro/routes/api/settings/backups/export.mjs +7 -7
  308. package/dist/astro/routes/api/settings/backups/index.mjs +8 -8
  309. package/dist/astro/routes/api/settings/email.mjs +5 -5
  310. package/dist/astro/routes/api/settings.mjs +14 -13
  311. package/dist/astro/routes/api/settings.mjs.map +1 -1
  312. package/dist/astro/routes/api/setup/admin-verify.mjs +14 -13
  313. package/dist/astro/routes/api/setup/admin-verify.mjs.map +1 -1
  314. package/dist/astro/routes/api/setup/admin.mjs +13 -12
  315. package/dist/astro/routes/api/setup/admin.mjs.map +1 -1
  316. package/dist/astro/routes/api/setup/dev-bypass.d.mts.map +1 -1
  317. package/dist/astro/routes/api/setup/dev-bypass.mjs +30 -31
  318. package/dist/astro/routes/api/setup/dev-bypass.mjs.map +1 -1
  319. package/dist/astro/routes/api/setup/dev-reset.mjs +3 -3
  320. package/dist/astro/routes/api/setup/index.d.mts.map +1 -1
  321. package/dist/astro/routes/api/setup/index.mjs +31 -35
  322. package/dist/astro/routes/api/setup/index.mjs.map +1 -1
  323. package/dist/astro/routes/api/setup/status.mjs +5 -5
  324. package/dist/astro/routes/api/snapshot.mjs +8 -8
  325. package/dist/astro/routes/api/taxonomies/_name_/reorder.mjs +16 -15
  326. package/dist/astro/routes/api/taxonomies/_name_/reorder.mjs.map +1 -1
  327. package/dist/astro/routes/api/taxonomies/_name_/terms/_slug_/translations.mjs +16 -15
  328. package/dist/astro/routes/api/taxonomies/_name_/terms/_slug_/translations.mjs.map +1 -1
  329. package/dist/astro/routes/api/taxonomies/_name_/terms/_slug_.mjs +16 -15
  330. package/dist/astro/routes/api/taxonomies/_name_/terms/_slug_.mjs.map +1 -1
  331. package/dist/astro/routes/api/taxonomies/_name_/terms/index.d.mts.map +1 -1
  332. package/dist/astro/routes/api/taxonomies/_name_/terms/index.mjs +18 -16
  333. package/dist/astro/routes/api/taxonomies/_name_/terms/index.mjs.map +1 -1
  334. package/dist/astro/routes/api/taxonomies/_name_/translations.d.mts +8 -0
  335. package/dist/astro/routes/api/taxonomies/_name_/translations.d.mts.map +1 -0
  336. package/dist/astro/routes/api/taxonomies/_name_/translations.mjs +46 -0
  337. package/dist/astro/routes/api/taxonomies/_name_/translations.mjs.map +1 -0
  338. package/dist/astro/routes/api/taxonomies/_name_.d.mts +19 -0
  339. package/dist/astro/routes/api/taxonomies/_name_.d.mts.map +1 -0
  340. package/dist/astro/routes/api/taxonomies/_name_.mjs +88 -0
  341. package/dist/astro/routes/api/taxonomies/_name_.mjs.map +1 -0
  342. package/dist/astro/routes/api/taxonomies/index.mjs +16 -15
  343. package/dist/astro/routes/api/taxonomies/index.mjs.map +1 -1
  344. package/dist/astro/routes/api/themes/preview.mjs +6 -6
  345. package/dist/astro/routes/api/typegen.mjs +6 -6
  346. package/dist/astro/routes/api/well-known/auth.mjs +1 -1
  347. package/dist/astro/routes/api/well-known/oauth-authorization-server.mjs +2 -2
  348. package/dist/astro/routes/api/well-known/oauth-protected-resource.mjs +2 -2
  349. package/dist/astro/routes/api/widget-areas/_name_/reorder.mjs +10 -9
  350. package/dist/astro/routes/api/widget-areas/_name_/reorder.mjs.map +1 -1
  351. package/dist/astro/routes/api/widget-areas/_name_/widgets/_id_.mjs +12 -11
  352. package/dist/astro/routes/api/widget-areas/_name_/widgets/_id_.mjs.map +1 -1
  353. package/dist/astro/routes/api/widget-areas/_name_/widgets.mjs +12 -11
  354. package/dist/astro/routes/api/widget-areas/_name_/widgets.mjs.map +1 -1
  355. package/dist/astro/routes/api/widget-areas/_name_.mjs +7 -6
  356. package/dist/astro/routes/api/widget-areas/_name_.mjs.map +1 -1
  357. package/dist/astro/routes/api/widget-areas/index.mjs +12 -11
  358. package/dist/astro/routes/api/widget-areas/index.mjs.map +1 -1
  359. package/dist/astro/routes/api/widget-components.mjs +4 -4
  360. package/dist/astro/routes/robots.txt.mjs +7 -6
  361. package/dist/astro/routes/robots.txt.mjs.map +1 -1
  362. package/dist/astro/routes/sitemap-_collection_.xml.mjs +10 -10
  363. package/dist/astro/routes/sitemap.xml.mjs +8 -7
  364. package/dist/astro/routes/sitemap.xml.mjs.map +1 -1
  365. package/dist/astro/types.d.mts +35 -17
  366. package/dist/astro/types.d.mts.map +1 -1
  367. package/dist/auth/providers/github.d.mts +1 -1
  368. package/dist/auth/providers/google.d.mts +1 -1
  369. package/dist/{authorize-qRhWQnel.mjs → authorize-DUElxgOQ.mjs} +2 -2
  370. package/dist/{authorize-qRhWQnel.mjs.map → authorize-DUElxgOQ.mjs.map} +1 -1
  371. package/dist/{backup-CtA6LDNw.mjs → backup-DWYpJlLj.mjs} +4 -4
  372. package/dist/{backup-CtA6LDNw.mjs.map → backup-DWYpJlLj.mjs.map} +1 -1
  373. package/dist/{base64-B-PsqheR.mjs → base64-CvLhUKQv.mjs} +1 -1
  374. package/dist/{base64-B-PsqheR.mjs.map → base64-CvLhUKQv.mjs.map} +1 -1
  375. package/dist/bundle-vn56sLos.mjs +663 -0
  376. package/dist/bundle-vn56sLos.mjs.map +1 -0
  377. package/dist/{byline-fields-CNc0Yq5i.mjs → byline-fields-txaLGoME.mjs} +2 -2
  378. package/dist/{byline-fields-CNc0Yq5i.mjs.map → byline-fields-txaLGoME.mjs.map} +1 -1
  379. package/dist/{byline-registry-ZkPKqEwC.mjs → byline-registry-DDun8sxh.mjs} +2 -2
  380. package/dist/{byline-registry-ZkPKqEwC.mjs.map → byline-registry-DDun8sxh.mjs.map} +1 -1
  381. package/dist/{byline-Cp6csL84.mjs → byline-yjvWq4ip.mjs} +5 -5
  382. package/dist/{byline-Cp6csL84.mjs.map → byline-yjvWq4ip.mjs.map} +1 -1
  383. package/dist/{bylines-cf-C9lmF.mjs → bylines-Bu7pchQ4.mjs} +5 -5
  384. package/dist/{bylines-cf-C9lmF.mjs.map → bylines-Bu7pchQ4.mjs.map} +1 -1
  385. package/dist/{bylines-CEj5CdT4.mjs → bylines-DjXS5p0P.mjs} +7 -7
  386. package/dist/{bylines-CEj5CdT4.mjs.map → bylines-DjXS5p0P.mjs.map} +1 -1
  387. package/dist/{cache-C9FptTFR.mjs → cache-C46-3Irl.mjs} +3 -3
  388. package/dist/{cache-C9FptTFR.mjs.map → cache-C46-3Irl.mjs.map} +1 -1
  389. package/dist/{challenge-store-D9VNKELo.mjs → challenge-store-SIL5DsF2.mjs} +1 -1
  390. package/dist/{challenge-store-D9VNKELo.mjs.map → challenge-store-SIL5DsF2.mjs.map} +1 -1
  391. package/dist/{chunks-DbYzib_k.mjs → chunks-fiZ8G9RJ.mjs} +2 -2
  392. package/dist/{chunks-DbYzib_k.mjs.map → chunks-fiZ8G9RJ.mjs.map} +1 -1
  393. package/dist/cli/index.mjs +655 -677
  394. package/dist/cli/index.mjs.map +1 -1
  395. package/dist/client/cf-access.d.mts +1 -1
  396. package/dist/client/index.d.mts +74 -4
  397. package/dist/client/index.d.mts.map +1 -1
  398. package/dist/client/index.mjs +25 -2
  399. package/dist/client/index.mjs.map +1 -1
  400. package/dist/collection-deletion-DQPvMD8R.mjs +779 -0
  401. package/dist/collection-deletion-DQPvMD8R.mjs.map +1 -0
  402. package/dist/{comment-BIkJ6Fil.mjs → comment-Dxlep6cE.mjs} +2 -2
  403. package/dist/{comment-BIkJ6Fil.mjs.map → comment-Dxlep6cE.mjs.map} +1 -1
  404. package/dist/{comment-reaction-D-laEceb.mjs → comment-reaction-D-2J84UE.mjs} +2 -2
  405. package/dist/{comment-reaction-D-laEceb.mjs.map → comment-reaction-D-2J84UE.mjs.map} +1 -1
  406. package/dist/{comments-0_w6KChA.mjs → comments-CTfZtLmM.mjs} +3 -3
  407. package/dist/{comments-0_w6KChA.mjs.map → comments-CTfZtLmM.mjs.map} +1 -1
  408. package/dist/{components-BPxrRjpE.mjs → components-CQy3lh9x.mjs} +1 -1
  409. package/dist/{components-BPxrRjpE.mjs.map → components-CQy3lh9x.mjs.map} +1 -1
  410. package/dist/{config-DyF3OKg_.mjs → config-C3EBstHi.mjs} +18 -2
  411. package/dist/config-C3EBstHi.mjs.map +1 -0
  412. package/dist/config-COQzTe5Q.d.mts +34 -0
  413. package/dist/config-COQzTe5Q.d.mts.map +1 -0
  414. package/dist/{content-CJ94NEx5.mjs → content-ZHCc1ngN.mjs} +509 -78
  415. package/dist/content-ZHCc1ngN.mjs.map +1 -0
  416. package/dist/content-list-query-wJ2WN8Vp.d.mts +26 -0
  417. package/dist/content-list-query-wJ2WN8Vp.d.mts.map +1 -0
  418. package/dist/content-refresh-B_8SJzuU.mjs +2560 -0
  419. package/dist/content-refresh-B_8SJzuU.mjs.map +1 -0
  420. package/dist/{context-C_1nrqnW.mjs → context-ZldbZcle.mjs} +25 -17
  421. package/dist/context-ZldbZcle.mjs.map +1 -0
  422. package/dist/{cron-DRV-UC4K.mjs → cron-Y9aLtgrA.mjs} +1 -1
  423. package/dist/{cron-DRV-UC4K.mjs.map → cron-Y9aLtgrA.mjs.map} +1 -1
  424. package/dist/{dashboard-DINnNVVU.mjs → dashboard-DvHbk_cv.mjs} +44 -10
  425. package/dist/dashboard-DvHbk_cv.mjs.map +1 -0
  426. package/dist/db/index.d.mts +4 -4
  427. package/dist/db/index.mjs +31 -8
  428. package/dist/db/index.mjs.map +1 -1
  429. package/dist/db/libsql-migrations.d.mts +11 -0
  430. package/dist/db/libsql-migrations.d.mts.map +1 -0
  431. package/dist/db/libsql-migrations.mjs +57 -0
  432. package/dist/db/libsql-migrations.mjs.map +1 -0
  433. package/dist/db/libsql.d.mts +1 -1
  434. package/dist/db/postgres-migrations.d.mts +10 -0
  435. package/dist/db/postgres-migrations.d.mts.map +1 -0
  436. package/dist/db/postgres-migrations.mjs +47 -0
  437. package/dist/db/postgres-migrations.mjs.map +1 -0
  438. package/dist/db/postgres.d.mts +1 -1
  439. package/dist/db/sqlite-migrations.d.mts +10 -0
  440. package/dist/db/sqlite-migrations.d.mts.map +1 -0
  441. package/dist/db/sqlite-migrations.mjs +28 -0
  442. package/dist/db/sqlite-migrations.mjs.map +1 -0
  443. package/dist/db/sqlite.d.mts +1 -1
  444. package/dist/{db-errors-CcWLaRiR.mjs → db-errors-Cl-sKYTm.mjs} +1 -1
  445. package/dist/{db-errors-CcWLaRiR.mjs.map → db-errors-Cl-sKYTm.mjs.map} +1 -1
  446. package/dist/{default-BD2FG0xV.mjs → default-DdDl3fxv.mjs} +1 -1
  447. package/dist/{default-BD2FG0xV.mjs.map → default-DdDl3fxv.mjs.map} +1 -1
  448. package/dist/{deferred-tasks-C-WRCcKo.d.mts → deferred-tasks-SDWxrgzJ.d.mts} +1 -1
  449. package/dist/{deferred-tasks-C-WRCcKo.d.mts.map → deferred-tasks-SDWxrgzJ.d.mts.map} +1 -1
  450. package/dist/{device-flow-CTqd8mud.mjs → device-flow-C0GdD_z8.mjs} +4 -4
  451. package/dist/{device-flow-CTqd8mud.mjs.map → device-flow-C0GdD_z8.mjs.map} +1 -1
  452. package/dist/direct-executor-CDXeJCSs.mjs +85 -0
  453. package/dist/direct-executor-CDXeJCSs.mjs.map +1 -0
  454. package/dist/dist-D_6CKR8z.mjs +810 -0
  455. package/dist/dist-D_6CKR8z.mjs.map +1 -0
  456. package/dist/{email-console-C6WdcWbL.mjs → email-console-BHNjIwiB.mjs} +1 -1
  457. package/dist/{email-console-C6WdcWbL.mjs.map → email-console-BHNjIwiB.mjs.map} +1 -1
  458. package/dist/{enrich-CFJJgxs_.mjs → enrich-_ySMEvEE.mjs} +2 -2
  459. package/dist/{enrich-CFJJgxs_.mjs.map → enrich-_ySMEvEE.mjs.map} +1 -1
  460. package/dist/{error-oh_9i6bR.mjs → error-DupyJZE2.mjs} +3 -3
  461. package/dist/{error-oh_9i6bR.mjs.map → error-DupyJZE2.mjs.map} +1 -1
  462. package/dist/{errors-BucQ8VYz.mjs → errors-CLUPm7aD.mjs} +14 -2
  463. package/dist/errors-CLUPm7aD.mjs.map +1 -0
  464. package/dist/{escape-CXps5F_v.mjs → escape-DUY2r2Zs.mjs} +1 -1
  465. package/dist/{escape-CXps5F_v.mjs.map → escape-DUY2r2Zs.mjs.map} +1 -1
  466. package/dist/{field-defs-cache-WD82dMQq.mjs → field-defs-cache-BzwBlJrR.mjs} +4 -4
  467. package/dist/{field-defs-cache-WD82dMQq.mjs.map → field-defs-cache-BzwBlJrR.mjs.map} +1 -1
  468. package/dist/{fts-manager-BITakW_R.mjs → fts-manager-DyZEohZC.mjs} +76 -50
  469. package/dist/fts-manager-DyZEohZC.mjs.map +1 -0
  470. package/dist/{hreflang-BdZuVBhL.mjs → hreflang-BBe83kKa.mjs} +7 -7
  471. package/dist/{hreflang-BdZuVBhL.mjs.map → hreflang-BBe83kKa.mjs.map} +1 -1
  472. package/dist/{hreflang-BaLCNcDx.d.mts → hreflang-DwT2E0Sa.d.mts} +2 -2
  473. package/dist/{hreflang-BaLCNcDx.d.mts.map → hreflang-DwT2E0Sa.d.mts.map} +1 -1
  474. package/dist/identity-Ys6Dlc9C.mjs +35 -0
  475. package/dist/identity-Ys6Dlc9C.mjs.map +1 -0
  476. package/dist/{import-C-9uqyT3.mjs → import-DPkLmeXO.mjs} +5 -5
  477. package/dist/{import-C-9uqyT3.mjs.map → import-DPkLmeXO.mjs.map} +1 -1
  478. package/dist/{index-M37iz29I.d.mts → index-BVBZj4-7.d.mts} +236 -104
  479. package/dist/index-BVBZj4-7.d.mts.map +1 -0
  480. package/dist/{index-MGw47uWq.d.mts → index-C9KuQyO-.d.mts} +5 -10
  481. package/dist/index-C9KuQyO-.d.mts.map +1 -0
  482. package/dist/index.d.mts +21 -19
  483. package/dist/index.mjs +73 -67
  484. package/dist/{init-lock-DJkX6Hto.mjs → init-lock-6b309ZrF.mjs} +1 -1
  485. package/dist/{init-lock-DJkX6Hto.mjs.map → init-lock-6b309ZrF.mjs.map} +1 -1
  486. package/dist/{load-DV1DZuUJ.mjs → load-YJ2xl3ra.mjs} +2 -2
  487. package/dist/{load-DV1DZuUJ.mjs.map → load-YJ2xl3ra.mjs.map} +1 -1
  488. package/dist/{loader-CGugY7Zl.mjs → loader-CdG_Ci3H.mjs} +95 -53
  489. package/dist/loader-CdG_Ci3H.mjs.map +1 -0
  490. package/dist/manifest-builder-B252yQUf.mjs +189 -0
  491. package/dist/manifest-builder-B252yQUf.mjs.map +1 -0
  492. package/dist/{manifest-schema-Da7kj23y.mjs → manifest-schema-BXbUAHod.mjs} +1 -1
  493. package/dist/{manifest-schema-Da7kj23y.mjs.map → manifest-schema-BXbUAHod.mjs.map} +1 -1
  494. package/dist/media/image-endpoint.mjs +1 -1
  495. package/dist/media/index.d.mts +1 -1
  496. package/dist/media/index.mjs +3 -2
  497. package/dist/media/index.mjs.map +1 -1
  498. package/dist/media/local-runtime.d.mts +12 -12
  499. package/dist/media/local-runtime.mjs +6 -5
  500. package/dist/media/local-runtime.mjs.map +1 -1
  501. package/dist/{media-OhYL-7Io.mjs → media-BWWWb8kg.mjs} +92 -3
  502. package/dist/media-BWWWb8kg.mjs.map +1 -0
  503. package/dist/{media-BP7S-nHT.mjs → media-CzhAn2--.mjs} +2 -2
  504. package/dist/{media-BP7S-nHT.mjs.map → media-CzhAn2--.mjs.map} +1 -1
  505. package/dist/{media-allowlist-D-peH1H5.mjs → media-allowlist-D6x-Us02.mjs} +14 -3
  506. package/dist/media-allowlist-D6x-Us02.mjs.map +1 -0
  507. package/dist/{media-upload-DtrwU2B0.mjs → media-upload-CHBVn6m-.mjs} +10 -8
  508. package/dist/{media-upload-DtrwU2B0.mjs.map → media-upload-CHBVn6m-.mjs.map} +1 -1
  509. package/dist/{media-url-DYs_YLOx.mjs → media-url-BvoX88FA.mjs} +1 -1
  510. package/dist/{media-url-DYs_YLOx.mjs.map → media-url-BvoX88FA.mjs.map} +1 -1
  511. package/dist/{media-usage-BlxfTkN0.mjs → media-usage-BZCydfvu.mjs} +137 -60
  512. package/dist/media-usage-BZCydfvu.mjs.map +1 -0
  513. package/dist/media-usage-work-CLo_6tct.mjs +152 -0
  514. package/dist/media-usage-work-CLo_6tct.mjs.map +1 -0
  515. package/dist/media-usage-work-DrCbqBcl.mjs +424 -0
  516. package/dist/media-usage-work-DrCbqBcl.mjs.map +1 -0
  517. package/dist/media-usage-write-fence-aHEgN1zB.mjs +42 -0
  518. package/dist/media-usage-write-fence-aHEgN1zB.mjs.map +1 -0
  519. package/dist/{menus-Y54RDPIN.mjs → menus-DSo5QeW0.mjs} +351 -95
  520. package/dist/menus-DSo5QeW0.mjs.map +1 -0
  521. package/dist/{menus-BcQWxeXu.mjs → menus-TCNSd2vp.mjs} +3 -3
  522. package/dist/{menus-BcQWxeXu.mjs.map → menus-TCNSd2vp.mjs.map} +1 -1
  523. package/dist/migrations/index.d.mts +22 -0
  524. package/dist/migrations/index.d.mts.map +1 -0
  525. package/dist/migrations/index.mjs +7 -0
  526. package/dist/{mode-BWyTBe3I.mjs → mode-BDoH_WcF.mjs} +1 -1
  527. package/dist/{mode-BWyTBe3I.mjs.map → mode-BDoH_WcF.mjs.map} +1 -1
  528. package/dist/{normalize-C-SHXmra.mjs → normalize-Bc-s_r-a.mjs} +1 -1
  529. package/dist/{normalize-C-SHXmra.mjs.map → normalize-Bc-s_r-a.mjs.map} +1 -1
  530. package/dist/{oauth-authorization-ClvktmrL.mjs → oauth-authorization-iOikmrJd.mjs} +4 -4
  531. package/dist/{oauth-authorization-ClvktmrL.mjs.map → oauth-authorization-iOikmrJd.mjs.map} +1 -1
  532. package/dist/{oauth-clients-8ao-U66l.mjs → oauth-clients-CvI0nHMJ.mjs} +1 -1
  533. package/dist/{oauth-clients-8ao-U66l.mjs.map → oauth-clients-CvI0nHMJ.mjs.map} +1 -1
  534. package/dist/{oauth-state-store-B1ofdTiQ.mjs → oauth-state-store-Ba8KZlwW.mjs} +1 -1
  535. package/dist/{oauth-state-store-B1ofdTiQ.mjs.map → oauth-state-store-Ba8KZlwW.mjs.map} +1 -1
  536. package/dist/{oauth-user-lookup-CscEuIiR.mjs → oauth-user-lookup-C5SQwGYC.mjs} +1 -1
  537. package/dist/{oauth-user-lookup-CscEuIiR.mjs.map → oauth-user-lookup-C5SQwGYC.mjs.map} +1 -1
  538. package/dist/object-cache/memory.d.mts +1 -1
  539. package/dist/{options-CA4eVX6P.d.mts → options--hhz-jZ1.d.mts} +4 -3
  540. package/dist/options--hhz-jZ1.d.mts.map +1 -0
  541. package/dist/page/index.d.mts +2 -2
  542. package/dist/{parse-CJKNuewM.mjs → parse-DFbuc-Fh.mjs} +2 -2
  543. package/dist/{parse-CJKNuewM.mjs.map → parse-DFbuc-Fh.mjs.map} +1 -1
  544. package/dist/{passkey-config-D-zrzMJI.mjs → passkey-config-DFAmUyuE.mjs} +1 -1
  545. package/dist/{passkey-config-D-zrzMJI.mjs.map → passkey-config-DFAmUyuE.mjs.map} +1 -1
  546. package/dist/{placeholder-DaeNS-VG.d.mts → placeholder-Dp0K3RkD.d.mts} +1 -1
  547. package/dist/{placeholder-DaeNS-VG.d.mts.map → placeholder-Dp0K3RkD.d.mts.map} +1 -1
  548. package/dist/plugin-types.d.mts +8 -1
  549. package/dist/plugin-types.d.mts.map +1 -1
  550. package/dist/plugin-utils.d.mts +10 -10
  551. package/dist/plugins/adapt-sandbox-entry.d.mts +10 -10
  552. package/dist/plugins/adapt-sandbox-entry.mjs +7 -4
  553. package/dist/plugins/adapt-sandbox-entry.mjs.map +1 -1
  554. package/dist/policy-TluUIxuu.mjs +45 -0
  555. package/dist/policy-TluUIxuu.mjs.map +1 -0
  556. package/dist/{portable-text-B_kqBmXB.mjs → portable-text-imBW5cHK.mjs} +1 -1
  557. package/dist/{portable-text-B_kqBmXB.mjs.map → portable-text-imBW5cHK.mjs.map} +1 -1
  558. package/dist/{preview-BU6PaLpM.mjs → preview-PW-nOnq4.mjs} +2 -2
  559. package/dist/{preview-BU6PaLpM.mjs.map → preview-PW-nOnq4.mjs.map} +1 -1
  560. package/dist/protocol-DjsJHTlK.d.mts +52 -0
  561. package/dist/protocol-DjsJHTlK.d.mts.map +1 -0
  562. package/dist/{public-url-Ox9oOlgp.mjs → public-url-CWoFhQT8.mjs} +1 -1
  563. package/dist/{public-url-Ox9oOlgp.mjs.map → public-url-CWoFhQT8.mjs.map} +1 -1
  564. package/dist/{query-rC9HKv1N.mjs → query-BWs7O5Il.mjs} +3 -3
  565. package/dist/{query-rC9HKv1N.mjs.map → query-BWs7O5Il.mjs.map} +1 -1
  566. package/dist/{query-C5w7PsRQ.mjs → query-zTVAR1Sl.mjs} +31 -49
  567. package/dist/query-zTVAR1Sl.mjs.map +1 -0
  568. package/dist/{rate-limit-kug6q99V.mjs → rate-limit-Bx4g9m3p.mjs} +2 -2
  569. package/dist/{rate-limit-kug6q99V.mjs.map → rate-limit-Bx4g9m3p.mjs.map} +1 -1
  570. package/dist/{redirect-Egf2R9yP.mjs → redirect-BgAOGHDq.mjs} +1 -1
  571. package/dist/{redirect-Egf2R9yP.mjs.map → redirect-BgAOGHDq.mjs.map} +1 -1
  572. package/dist/{redirect-DIJxXKOG.mjs → redirect-COsS6SWJ.mjs} +2 -2
  573. package/dist/{redirect-DIJxXKOG.mjs.map → redirect-COsS6SWJ.mjs.map} +1 -1
  574. package/dist/{redirects-G8wAhWAf.mjs → redirects-DTDHWH31.mjs} +133 -14
  575. package/dist/redirects-DTDHWH31.mjs.map +1 -0
  576. package/dist/{redirects-Bzm812bY.mjs → redirects-DyChwDkG.mjs} +4 -4
  577. package/dist/{redirects-Bzm812bY.mjs.map → redirects-DyChwDkG.mjs.map} +1 -1
  578. package/dist/registry-Cqa2I749.mjs +1275 -0
  579. package/dist/registry-Cqa2I749.mjs.map +1 -0
  580. package/dist/{relation-Cbe3Sd3m.mjs → relation-BnHB0T4J.mjs} +3 -3
  581. package/dist/{relation-Cbe3Sd3m.mjs.map → relation-BnHB0T4J.mjs.map} +1 -1
  582. package/dist/{relations-Bw_E1TXo.mjs → relations-BBApI4e2.mjs} +3 -3
  583. package/dist/{relations-Bw_E1TXo.mjs.map → relations-BBApI4e2.mjs.map} +1 -1
  584. package/dist/{relations-G2ta7GIl.d.mts → relations-BHo5A8Zf.d.mts} +367 -33
  585. package/dist/relations-BHo5A8Zf.d.mts.map +1 -0
  586. package/dist/{relations-qHwpUe66.mjs → relations-D5sM5fW0.mjs} +6 -6
  587. package/dist/{relations-qHwpUe66.mjs.map → relations-D5sM5fW0.mjs.map} +1 -1
  588. package/dist/request-context.d.mts +1 -1
  589. package/dist/{request-meta-Df-jFbAd.mjs → request-meta-DgZJh3zG.mjs} +2 -2
  590. package/dist/{request-meta-Df-jFbAd.mjs.map → request-meta-DgZJh3zG.mjs.map} +1 -1
  591. package/dist/{resolve-DZzG4HqM.mjs → resolve-DOhVEvty.mjs} +2 -2
  592. package/dist/{resolve-DZzG4HqM.mjs.map → resolve-DOhVEvty.mjs.map} +1 -1
  593. package/dist/{runner-BaADli8l.d.mts → runner-BYHZn3Jy.d.mts} +16 -3
  594. package/dist/runner-BYHZn3Jy.d.mts.map +1 -0
  595. package/dist/{runner-BFTrkYhu.mjs → runner-C1T11CfC.mjs} +1190 -257
  596. package/dist/runner-C1T11CfC.mjs.map +1 -0
  597. package/dist/runtime.d.mts +11 -11
  598. package/dist/runtime.mjs +4 -3
  599. package/dist/runtime.mjs.map +1 -1
  600. package/dist/schema-2AOsSn2v.mjs +390 -0
  601. package/dist/schema-2AOsSn2v.mjs.map +1 -0
  602. package/dist/{schema-CiQXr6_F.mjs → schema-DZ5YVVZj.mjs} +3 -3
  603. package/dist/{schema-CiQXr6_F.mjs.map → schema-DZ5YVVZj.mjs.map} +1 -1
  604. package/dist/{scopes-CNJVT5i5.mjs → scopes-8ClPF2bC.mjs} +3 -3
  605. package/dist/{scopes-CNJVT5i5.mjs.map → scopes-8ClPF2bC.mjs.map} +1 -1
  606. package/dist/{search-FZhx5dDU.mjs → search-u1QYdOCG.mjs} +25 -15
  607. package/dist/search-u1QYdOCG.mjs.map +1 -0
  608. package/dist/{secrets-DLd8RXee.mjs → secrets-BEgsAQEU.mjs} +3 -3
  609. package/dist/{secrets-DLd8RXee.mjs.map → secrets-BEgsAQEU.mjs.map} +1 -1
  610. package/dist/{sections-BrIrMUCn.mjs → sections-DmHviGyM.mjs} +3 -3
  611. package/dist/{sections-BrIrMUCn.mjs.map → sections-DmHviGyM.mjs.map} +1 -1
  612. package/dist/seed/index.d.mts +2 -2
  613. package/dist/seed/index.mjs +24 -22
  614. package/dist/seo/index.d.mts +3 -3
  615. package/dist/seo/index.mjs +16 -15
  616. package/dist/seo/index.mjs.map +1 -1
  617. package/dist/{seo-CobNfOvb.mjs → seo-AFpVvTqr.mjs} +5 -3
  618. package/dist/seo-AFpVvTqr.mjs.map +1 -0
  619. package/dist/{seo-DTHRntNC.mjs → seo-Dq4G-RrO.mjs} +2 -2
  620. package/dist/{seo-DTHRntNC.mjs.map → seo-Dq4G-RrO.mjs.map} +1 -1
  621. package/dist/{service-B-pYGPgR.mjs → service-BpArayPr.mjs} +3 -3
  622. package/dist/{service-B-pYGPgR.mjs.map → service-BpArayPr.mjs.map} +1 -1
  623. package/dist/{session-user-BvM9-zNl.mjs → session-user-BEorKVT-.mjs} +1 -1
  624. package/dist/{session-user-BvM9-zNl.mjs.map → session-user-BEorKVT-.mjs.map} +1 -1
  625. package/dist/{settings-DPHau-WH.mjs → settings-DE9xtzqd.mjs} +3 -3
  626. package/dist/{settings-DPHau-WH.mjs.map → settings-DE9xtzqd.mjs.map} +1 -1
  627. package/dist/{settings-kJhGiQ4z.mjs → settings-xRdoUZr0.mjs} +4 -4
  628. package/dist/{settings-kJhGiQ4z.mjs.map → settings-xRdoUZr0.mjs.map} +1 -1
  629. package/dist/{setup-complete-u50Qm8rY.mjs → setup-complete-BnT8pq_C.mjs} +1 -1
  630. package/dist/{setup-complete-u50Qm8rY.mjs.map → setup-complete-BnT8pq_C.mjs.map} +1 -1
  631. package/dist/{setup-nonce-DCjiiOD2.mjs → setup-nonce-CBitf_oQ.mjs} +1 -1
  632. package/dist/{setup-nonce-DCjiiOD2.mjs.map → setup-nonce-CBitf_oQ.mjs.map} +1 -1
  633. package/dist/{single-flight-cache-DW3w11Pu.mjs → single-flight-cache-B0eLKS6K.mjs} +2 -2
  634. package/dist/{single-flight-cache-DW3w11Pu.mjs.map → single-flight-cache-B0eLKS6K.mjs.map} +1 -1
  635. package/dist/{site-url-I-lJ5kma.mjs → site-url-DjpIXMXJ.mjs} +2 -2
  636. package/dist/{site-url-I-lJ5kma.mjs.map → site-url-DjpIXMXJ.mjs.map} +1 -1
  637. package/dist/slugify-B994zkXC.mjs +17 -0
  638. package/dist/slugify-B994zkXC.mjs.map +1 -0
  639. package/dist/{snapshot-I_fjLDaD.mjs → snapshot-BBlGkb2q.mjs} +1 -1
  640. package/dist/{snapshot-I_fjLDaD.mjs.map → snapshot-BBlGkb2q.mjs.map} +1 -1
  641. package/dist/{ssrf-CTa6v21i.mjs → ssrf-Cpvg_n3A.mjs} +1 -1
  642. package/dist/{ssrf-CTa6v21i.mjs.map → ssrf-Cpvg_n3A.mjs.map} +1 -1
  643. package/dist/{state-CQvoefYP.mjs → state-DYwPue40.mjs} +1 -1
  644. package/dist/{state-CQvoefYP.mjs.map → state-DYwPue40.mjs.map} +1 -1
  645. package/dist/{status-CIsmlC1E.mjs → status-CWVYpbD8.mjs} +1 -1
  646. package/dist/{status-CIsmlC1E.mjs.map → status-CWVYpbD8.mjs.map} +1 -1
  647. package/dist/storage/local.d.mts +1 -1
  648. package/dist/storage/local.mjs +3 -3
  649. package/dist/storage/s3.d.mts +1 -1
  650. package/dist/storage/s3.mjs +1 -1
  651. package/dist/target-DixqqV5i.mjs +27 -0
  652. package/dist/target-DixqqV5i.mjs.map +1 -0
  653. package/dist/{taxonomies-CLN1N92E.mjs → taxonomies-BlrncHi9.mjs} +75 -64
  654. package/dist/taxonomies-BlrncHi9.mjs.map +1 -0
  655. package/dist/{taxonomies-CKuaZER5.mjs → taxonomies-OHUIiIpI.mjs} +280 -56
  656. package/dist/taxonomies-OHUIiIpI.mjs.map +1 -0
  657. package/dist/{taxonomy-pOrB2kZe.mjs → taxonomy-BqCZ1TdU.mjs} +131 -78
  658. package/dist/taxonomy-BqCZ1TdU.mjs.map +1 -0
  659. package/dist/{tokens-DagaJGK8.mjs → tokens-C39klX8R.mjs} +2 -2
  660. package/dist/{tokens-DagaJGK8.mjs.map → tokens-C39klX8R.mjs.map} +1 -1
  661. package/dist/{transport-DVsa5YYo.mjs → transport-DBJwa-Si.mjs} +1 -1
  662. package/dist/{transport-DVsa5YYo.mjs.map → transport-DBJwa-Si.mjs.map} +1 -1
  663. package/dist/{transport-CAwTaTp_.d.mts → transport-RQE36APG.d.mts} +1 -1
  664. package/dist/{transport-CAwTaTp_.d.mts.map → transport-RQE36APG.d.mts.map} +1 -1
  665. package/dist/{trusted-proxy-D20_7fyX.mjs → trusted-proxy-CEVekpby.mjs} +1 -1
  666. package/dist/{trusted-proxy-D20_7fyX.mjs.map → trusted-proxy-CEVekpby.mjs.map} +1 -1
  667. package/dist/{types-NBI3rF-_.mjs → types-75KIqzL9.mjs} +18 -2
  668. package/dist/types-75KIqzL9.mjs.map +1 -0
  669. package/dist/{types-BjxTKxrZ.mjs → types-BW1syrlw.mjs} +1 -1
  670. package/dist/{types-BjxTKxrZ.mjs.map → types-BW1syrlw.mjs.map} +1 -1
  671. package/dist/{types-DLG4IFEQ.d.mts → types-BcqdcT-r.d.mts} +1 -1
  672. package/dist/{types-DLG4IFEQ.d.mts.map → types-BcqdcT-r.d.mts.map} +1 -1
  673. package/dist/{types-LoagAGzH.d.mts → types-BntycPTF.d.mts} +1 -1
  674. package/dist/{types-LoagAGzH.d.mts.map → types-BntycPTF.d.mts.map} +1 -1
  675. package/dist/{types-BnFP1M3J.d.mts → types-C2pMvO62.d.mts} +32 -10
  676. package/dist/types-C2pMvO62.d.mts.map +1 -0
  677. package/dist/{types-Cd8iuS1J.mjs → types-CQPWhPxE.mjs} +9 -12
  678. package/dist/types-CQPWhPxE.mjs.map +1 -0
  679. package/dist/{types-C8oz_ayJ.d.mts → types-CXnOzDe1.d.mts} +1 -1
  680. package/dist/{types-C8oz_ayJ.d.mts.map → types-CXnOzDe1.d.mts.map} +1 -1
  681. package/dist/types-CtzytVXn.mjs.map +1 -1
  682. package/dist/{types-BGWPMiBO.d.mts → types-DN64_zzZ.d.mts} +44 -5
  683. package/dist/types-DN64_zzZ.d.mts.map +1 -0
  684. package/dist/{types-Dc4ntQjQ.d.mts → types-DQIDRKF2.d.mts} +124 -1
  685. package/dist/types-DQIDRKF2.d.mts.map +1 -0
  686. package/dist/{types-CbUcuxxc.d.mts → types-DWRhk9xZ.d.mts} +1 -1
  687. package/dist/{types-CbUcuxxc.d.mts.map → types-DWRhk9xZ.d.mts.map} +1 -1
  688. package/dist/{types-BK6U01Ro.d.mts → types-Dfk8KI5R.d.mts} +1 -1
  689. package/dist/{types-BK6U01Ro.d.mts.map → types-Dfk8KI5R.d.mts.map} +1 -1
  690. package/dist/{types-Cz8hNch2.d.mts → types-DrJrVCT1.d.mts} +25 -5
  691. package/dist/types-DrJrVCT1.d.mts.map +1 -0
  692. package/dist/{upload-attempts-D8QAFLUJ.mjs → upload-attempts-D4FS8LT6.mjs} +1 -1
  693. package/dist/{upload-attempts-D8QAFLUJ.mjs.map → upload-attempts-D4FS8LT6.mjs.map} +1 -1
  694. package/dist/url-pattern-BHS0V5Ng.mjs +33 -0
  695. package/dist/url-pattern-BHS0V5Ng.mjs.map +1 -0
  696. package/dist/{user-DBrq4UVq.mjs → user-DJZfUJVE.mjs} +3 -3
  697. package/dist/{user-DBrq4UVq.mjs.map → user-DJZfUJVE.mjs.map} +1 -1
  698. package/dist/{utils-hLzi_2Fn.mjs → utils-D4vD_Y98.mjs} +3 -3
  699. package/dist/{utils-hLzi_2Fn.mjs.map → utils-D4vD_Y98.mjs.map} +1 -1
  700. package/dist/{validate-mKo3RxBM.mjs → validate-BMLBvxOC.mjs} +24 -5
  701. package/dist/validate-BMLBvxOC.mjs.map +1 -0
  702. package/dist/{validate-C3oSmA7F.d.mts → validate-CTqt5nuE.d.mts} +15 -7
  703. package/dist/validate-CTqt5nuE.d.mts.map +1 -0
  704. package/dist/{validation-BgpucsvF.mjs → validation-npvENUCB.mjs} +11 -10
  705. package/dist/{validation-BgpucsvF.mjs.map → validation-npvENUCB.mjs.map} +1 -1
  706. package/dist/version-DB_fqCSI.mjs +7 -0
  707. package/dist/{version-C4PnpmoV.mjs.map → version-DB_fqCSI.mjs.map} +1 -1
  708. package/dist/{widgets-CJJtkiKh.mjs → widgets-BD3ho7Rq.mjs} +3 -3
  709. package/dist/{widgets-CJJtkiKh.mjs.map → widgets-BD3ho7Rq.mjs.map} +1 -1
  710. package/dist/{wxr-taxonomies-9PPSy8X6.mjs → wxr-taxonomies-B1R3vBoD.mjs} +13 -32
  711. package/dist/{wxr-taxonomies-9PPSy8X6.mjs.map → wxr-taxonomies-B1R3vBoD.mjs.map} +1 -1
  712. package/dist/{wxr-taxonomies-Bkpp_2tK.d.mts → wxr-taxonomies-Ca68766D.d.mts} +1 -1
  713. package/dist/{wxr-taxonomies-Bkpp_2tK.d.mts.map → wxr-taxonomies-Ca68766D.d.mts.map} +1 -1
  714. package/dist/{zod-generator-CG64Hnbh.mjs → zod-generator-LC-on_Vb.mjs} +52 -5
  715. package/dist/zod-generator-LC-on_Vb.mjs.map +1 -0
  716. package/package.json +32 -8
  717. package/src/api/errors.ts +12 -0
  718. package/src/api/handlers/content.ts +127 -29
  719. package/src/api/handlers/dashboard.ts +12 -2
  720. package/src/api/handlers/index.ts +16 -0
  721. package/src/api/handlers/manifest.ts +2 -0
  722. package/src/api/handlers/media-allowlist.ts +13 -2
  723. package/src/api/handlers/media-usage-work.ts +188 -0
  724. package/src/api/handlers/media-usage.ts +5 -3
  725. package/src/api/handlers/schema.ts +9 -3
  726. package/src/api/handlers/seo.ts +5 -2
  727. package/src/api/handlers/taxonomies.ts +345 -82
  728. package/src/api/media-usage-write-fence.ts +64 -0
  729. package/src/api/openapi/document.ts +199 -0
  730. package/src/api/schemas/common.ts +3 -1
  731. package/src/api/schemas/content.ts +122 -1
  732. package/src/api/schemas/media-usage.ts +133 -0
  733. package/src/api/schemas/schema.ts +78 -3
  734. package/src/api/schemas/taxonomies.ts +40 -8
  735. package/src/api/types.ts +1 -0
  736. package/src/astro/integration/index.ts +101 -56
  737. package/src/astro/integration/routes.ts +34 -4
  738. package/src/astro/integration/runtime.ts +18 -0
  739. package/src/astro/integration/virtual-modules.ts +25 -1
  740. package/src/astro/integration/vite-config.ts +16 -1
  741. package/src/astro/middleware/media-usage-write-fence.ts +30 -0
  742. package/src/astro/middleware/redirect.ts +12 -2
  743. package/src/astro/middleware/scoped-db.ts +21 -0
  744. package/src/astro/middleware.ts +140 -16
  745. package/src/astro/routes/api/admin/media-usage/collection-deletions/index.ts +22 -0
  746. package/src/astro/routes/api/admin/media-usage/collection-deletions/retry.ts +22 -0
  747. package/src/astro/routes/api/admin/media-usage/work/index.ts +26 -0
  748. package/src/astro/routes/api/admin/media-usage/work/retry.ts +26 -0
  749. package/src/astro/routes/api/admin/plugins/[id]/disable.ts +4 -0
  750. package/src/astro/routes/api/admin/plugins/[id]/enable.ts +4 -0
  751. package/src/astro/routes/api/admin/plugins/[id]/uninstall.ts +4 -0
  752. package/src/astro/routes/api/admin/plugins/[id]/update.ts +4 -0
  753. package/src/astro/routes/api/admin/plugins/marketplace/[id]/install.ts +4 -0
  754. package/src/astro/routes/api/admin/plugins/registry/[id]/uninstall.ts +4 -0
  755. package/src/astro/routes/api/admin/plugins/registry/[id]/update.ts +4 -0
  756. package/src/astro/routes/api/admin/plugins/registry/install.ts +4 -0
  757. package/src/astro/routes/api/auth/dev-bypass.ts +0 -4
  758. package/src/astro/routes/api/content/[collection]/[id]/terms/[taxonomy].ts +67 -31
  759. package/src/astro/routes/api/import/wordpress/execute.ts +3 -10
  760. package/src/astro/routes/api/mcp.ts +1 -0
  761. package/src/astro/routes/api/plugins/[pluginId]/[...path].ts +7 -1
  762. package/src/astro/routes/api/schema/collections/[slug]/index.ts +1 -7
  763. package/src/astro/routes/api/setup/dev-bypass.ts +2 -7
  764. package/src/astro/routes/api/setup/index.ts +5 -13
  765. package/src/astro/routes/api/taxonomies/[name]/terms/index.ts +1 -0
  766. package/src/astro/routes/api/taxonomies/[name]/translations.ts +48 -0
  767. package/src/astro/routes/api/taxonomies/[name].ts +102 -0
  768. package/src/astro/types.ts +25 -4
  769. package/src/cleanup.ts +6 -12
  770. package/src/cli/commands/doctor.ts +193 -6
  771. package/src/cli/commands/export-seed.ts +4 -1
  772. package/src/cli/commands/migrate.ts +593 -0
  773. package/src/cli/index.ts +2 -23
  774. package/src/client/index.ts +119 -0
  775. package/src/components/Block.astro +12 -0
  776. package/src/components/InlinePortableTextEditor.tsx +89 -1
  777. package/src/content/converters/mark-safety.ts +120 -0
  778. package/src/content/converters/portable-text-to-prosemirror.ts +25 -16
  779. package/src/content/converters/prosemirror-to-portable-text.ts +12 -2
  780. package/src/content-list-query.ts +29 -0
  781. package/src/database/index.ts +8 -2
  782. package/src/database/migrations/060_collection_admin_config.ts +16 -0
  783. package/src/database/migrations/061_media_usage_cleanup.ts +77 -0
  784. package/src/database/migrations/062_media_usage_cleanup_fence.ts +295 -0
  785. package/src/database/migrations/063_media_usage_incremental_work.ts +397 -0
  786. package/src/database/migrations/064_fts_plain_text.ts +253 -0
  787. package/src/database/migrations/065_media_usage_collection_deletion.ts +85 -0
  788. package/src/database/migrations/066_media_usage_reconciliation.ts +115 -0
  789. package/src/database/migrations/067_indexed_content_fields.ts +39 -0
  790. package/src/database/migrations/068_content_taxonomy_entry_groups.ts +61 -0
  791. package/src/database/migrations/069_collection_title_date_fields.ts +45 -0
  792. package/src/database/migrations/070_collection_routable.ts +18 -0
  793. package/src/database/migrations/policy.ts +70 -0
  794. package/src/database/migrations/runner.ts +71 -3
  795. package/src/database/repositories/content.ts +861 -96
  796. package/src/database/repositories/media-usage-work.ts +848 -0
  797. package/src/database/repositories/media-usage.ts +1502 -138
  798. package/src/database/repositories/revision.ts +17 -6
  799. package/src/database/repositories/taxonomy.ts +234 -103
  800. package/src/database/repositories/types.ts +51 -2
  801. package/src/database/types.ts +134 -16
  802. package/src/db/adapters.ts +78 -2
  803. package/src/db/index.ts +6 -1
  804. package/src/db/libsql-migrations.ts +72 -0
  805. package/src/db/postgres-migrations.ts +59 -0
  806. package/src/db/sqlite-migrations.ts +37 -0
  807. package/src/emdash-runtime.ts +271 -35
  808. package/src/fields/file.ts +7 -4
  809. package/src/fields/image.ts +8 -1
  810. package/src/fields/types.ts +18 -5
  811. package/src/i18n/config.ts +32 -0
  812. package/src/i18n/normalize.ts +31 -0
  813. package/src/i18n/repair-locale-casing.ts +0 -14
  814. package/src/i18n/taxonomy-locale-diagnostic.ts +47 -0
  815. package/src/import/wxr-taxonomies.ts +7 -47
  816. package/src/index.ts +32 -3
  817. package/src/loader.ts +119 -65
  818. package/src/mcp/server.ts +242 -34
  819. package/src/media/usage/activation.ts +626 -0
  820. package/src/media/usage/capture-triggers.ts +543 -0
  821. package/src/media/usage/cleanup.ts +305 -0
  822. package/src/media/usage/collection-deletion-processor.ts +356 -0
  823. package/src/media/usage/collection-deletion.ts +836 -0
  824. package/src/media/usage/content-fields.ts +40 -3
  825. package/src/media/usage/content-refresh.ts +356 -47
  826. package/src/media/usage/content-repair.ts +180 -61
  827. package/src/media/usage/content-snapshots.ts +85 -105
  828. package/src/media/usage/projection-fingerprint.ts +129 -0
  829. package/src/media/usage/reconciliation-processor.ts +372 -0
  830. package/src/media/usage/reconciliation.ts +1117 -0
  831. package/src/media/usage/source-key.ts +4 -0
  832. package/src/media/usage/types.ts +2 -0
  833. package/src/media/usage/work-processor.ts +248 -0
  834. package/src/menus/index.ts +246 -141
  835. package/src/migrations/config-loader.ts +205 -0
  836. package/src/migrations/direct-executor.ts +141 -0
  837. package/src/migrations/identity.ts +46 -0
  838. package/src/migrations/index.ts +19 -0
  839. package/src/migrations/integration-metadata.ts +67 -0
  840. package/src/migrations/manifest-builder.ts +55 -0
  841. package/src/migrations/manifest-writer.ts +63 -0
  842. package/src/migrations/manifest.ts +197 -0
  843. package/src/migrations/protocol.ts +59 -0
  844. package/src/migrations/target.ts +35 -0
  845. package/src/plugin-types.ts +8 -0
  846. package/src/plugins/adapt-sandbox-entry.ts +24 -5
  847. package/src/plugins/context.ts +24 -7
  848. package/src/plugins/index.ts +9 -0
  849. package/src/plugins/routes.ts +43 -1
  850. package/src/plugins/sandbox/index.ts +10 -1
  851. package/src/plugins/sandbox/types.ts +78 -1
  852. package/src/plugins/scheduler/node.ts +13 -1
  853. package/src/plugins/scheduler/types.ts +2 -0
  854. package/src/plugins/types.ts +39 -2
  855. package/src/query.ts +29 -37
  856. package/src/scheduler-health.ts +46 -0
  857. package/src/schema/registry.ts +777 -255
  858. package/src/schema/types.ts +50 -8
  859. package/src/schema/url-pattern.ts +33 -0
  860. package/src/schema/zod-generator.ts +77 -5
  861. package/src/search/fts-manager.ts +117 -76
  862. package/src/search/query.ts +32 -11
  863. package/src/search/types.ts +2 -0
  864. package/src/seed/apply.ts +68 -15
  865. package/src/seed/types.ts +11 -3
  866. package/src/seed/validate.ts +52 -2
  867. package/src/taxonomies/index.ts +77 -75
  868. package/src/taxonomies/term-counts.ts +21 -8
  869. package/src/utils/slugify.ts +1 -29
  870. package/src/virtual-modules.d.ts +24 -0
  871. package/dist/adapters-BMyNSSZi.d.mts.map +0 -1
  872. package/dist/api-D2hunekQ.mjs.map +0 -1
  873. package/dist/apply-kwNEJW2l.mjs.map +0 -1
  874. package/dist/config-DyF3OKg_.mjs.map +0 -1
  875. package/dist/content-CJ94NEx5.mjs.map +0 -1
  876. package/dist/content-refresh-Xw7aKmou.mjs +0 -1629
  877. package/dist/content-refresh-Xw7aKmou.mjs.map +0 -1
  878. package/dist/context-C_1nrqnW.mjs.map +0 -1
  879. package/dist/dashboard-DINnNVVU.mjs.map +0 -1
  880. package/dist/errors-BucQ8VYz.mjs.map +0 -1
  881. package/dist/fts-manager-BITakW_R.mjs.map +0 -1
  882. package/dist/index-M37iz29I.d.mts.map +0 -1
  883. package/dist/index-MGw47uWq.d.mts.map +0 -1
  884. package/dist/loader-CGugY7Zl.mjs.map +0 -1
  885. package/dist/media-OhYL-7Io.mjs.map +0 -1
  886. package/dist/media-allowlist-D-peH1H5.mjs.map +0 -1
  887. package/dist/media-usage-BlxfTkN0.mjs.map +0 -1
  888. package/dist/menus-Y54RDPIN.mjs.map +0 -1
  889. package/dist/options-CA4eVX6P.d.mts.map +0 -1
  890. package/dist/query-C5w7PsRQ.mjs.map +0 -1
  891. package/dist/redirects-G8wAhWAf.mjs.map +0 -1
  892. package/dist/registry-Dbodb4Uo.mjs +0 -840
  893. package/dist/registry-Dbodb4Uo.mjs.map +0 -1
  894. package/dist/relations-G2ta7GIl.d.mts.map +0 -1
  895. package/dist/runner-BFTrkYhu.mjs.map +0 -1
  896. package/dist/runner-BaADli8l.d.mts.map +0 -1
  897. package/dist/search-FZhx5dDU.mjs.map +0 -1
  898. package/dist/seo-CobNfOvb.mjs.map +0 -1
  899. package/dist/slugify-C_tqlU4G.mjs +0 -30
  900. package/dist/slugify-C_tqlU4G.mjs.map +0 -1
  901. package/dist/taxonomies-CKuaZER5.mjs.map +0 -1
  902. package/dist/taxonomies-CLN1N92E.mjs.map +0 -1
  903. package/dist/taxonomy-pOrB2kZe.mjs.map +0 -1
  904. package/dist/types-BGWPMiBO.d.mts.map +0 -1
  905. package/dist/types-BnFP1M3J.d.mts.map +0 -1
  906. package/dist/types-Cd8iuS1J.mjs.map +0 -1
  907. package/dist/types-Cz8hNch2.d.mts.map +0 -1
  908. package/dist/types-Dc4ntQjQ.d.mts.map +0 -1
  909. package/dist/types-NBI3rF-_.mjs.map +0 -1
  910. package/dist/validate-C3oSmA7F.d.mts.map +0 -1
  911. package/dist/validate-mKo3RxBM.mjs.map +0 -1
  912. package/dist/version-C4PnpmoV.mjs +0 -7
  913. package/dist/zod-generator-CG64Hnbh.mjs.map +0 -1
  914. /package/dist/{api-tokens-Dai9dND0.mjs → api-tokens-rIXC6LdE.mjs} +0 -0
  915. /package/dist/{ssrf-Cj568Dgs.mjs → ssrf-DpXgKsna.mjs} +0 -0
  916. /package/dist/{types-DKuWPYV5.mjs → types-CP1CflWf.mjs} +0 -0
@@ -1,59 +1,62 @@
1
1
  #!/usr/bin/env node
2
- import { a as runMigrations, o as __exportAll, r as getMigrationStatus } from "../runner-BFTrkYhu.mjs";
2
+ import { a as getMigrationStatus, c as __exportAll, s as runMigrations } from "../runner-C1T11CfC.mjs";
3
3
  import { t as EmDashDatabaseError } from "../errors-9P_FDrJ_.mjs";
4
4
  import { t as validateIdentifier } from "../validate-BpwoDOgt.mjs";
5
5
  import { u as listTablesLike } from "../dialect-helpers-BSbfaO3F.mjs";
6
- import { n as getI18nConfig, r as isI18nEnabled } from "../config-DyF3OKg_.mjs";
6
+ import { i as isI18nEnabled, r as getI18nConfig } from "../config-C3EBstHi.mjs";
7
7
  import "../after-CBU2vkoO.mjs";
8
8
  import "../object-cache-71tPfV4A.mjs";
9
- import { t as ContentRepository } from "../content-CJ94NEx5.mjs";
10
- import { n as isMissingTableError } from "../db-errors-CcWLaRiR.mjs";
11
- import { n as slugify } from "../slugify-C_tqlU4G.mjs";
12
- import { a as encodeBase64url } from "../base64-B-PsqheR.mjs";
13
- import "../types-Cd8iuS1J.mjs";
14
- import { t as MediaRepository } from "../media-BP7S-nHT.mjs";
15
- import { t as TaxonomyRepository } from "../taxonomy-pOrB2kZe.mjs";
9
+ import { t as ContentRepository } from "../content-ZHCc1ngN.mjs";
10
+ import { n as isMissingTableError } from "../db-errors-Cl-sKYTm.mjs";
11
+ import { n as slugify } from "../slugify-B994zkXC.mjs";
12
+ import { a as encodeBase64url } from "../base64-CvLhUKQv.mjs";
13
+ import "../types-CQPWhPxE.mjs";
14
+ import { t as MediaRepository } from "../media-CzhAn2--.mjs";
15
+ import { t as TaxonomyRepository } from "../taxonomy-BqCZ1TdU.mjs";
16
16
  import { t as OptionsRepository } from "../options-CBXIHUoT.mjs";
17
- import "../redirect-DIJxXKOG.mjs";
17
+ import "../redirect-COsS6SWJ.mjs";
18
18
  import "../request-cache-BSUptuJR.mjs";
19
- import "../byline-registry-ZkPKqEwC.mjs";
20
- import "../field-defs-cache-WD82dMQq.mjs";
21
- import { t as BylineRepository } from "../byline-Cp6csL84.mjs";
22
- import "../fts-manager-BITakW_R.mjs";
19
+ import "../byline-registry-DDun8sxh.mjs";
20
+ import "../field-defs-cache-BzwBlJrR.mjs";
21
+ import { t as BylineRepository } from "../byline-yjvWq4ip.mjs";
22
+ import "../dist-D_6CKR8z.mjs";
23
+ import "../fts-manager-DyZEohZC.mjs";
23
24
  import { kyselyLogOption } from "../database/instrumentation.mjs";
24
- import "../loader-CGugY7Zl.mjs";
25
- import "../hash-Cg0TXJPV.mjs";
26
- import "../content-refresh-Xw7aKmou.mjs";
27
- import { n as SchemaRegistry } from "../registry-Dbodb4Uo.mjs";
28
- import "../settings-kJhGiQ4z.mjs";
29
- import { i as pluginManifestSchema } from "../manifest-schema-Da7kj23y.mjs";
30
- import { i as isDeprecatedCapability, n as capabilitiesToDeclaredAccess, t as CAPABILITY_RENAMES } from "../types-DKuWPYV5.mjs";
31
- import "../ssrf-CTa6v21i.mjs";
32
- import "../ssrf-Cj568Dgs.mjs";
33
- import { t as validateSeed } from "../validate-mKo3RxBM.mjs";
34
- import { t as applySeed } from "../apply-kwNEJW2l.mjs";
35
- import { n as fingerprintKey, r as generateEncryptionKey, t as EmDashSecretsError } from "../secrets-DLd8RXee.mjs";
25
+ import "../loader-CdG_Ci3H.mjs";
26
+ import "../content-refresh-B_8SJzuU.mjs";
27
+ import "../collection-deletion-DQPvMD8R.mjs";
28
+ import { n as SchemaRegistry } from "../registry-Cqa2I749.mjs";
29
+ import "../settings-xRdoUZr0.mjs";
30
+ import { i as pluginManifestSchema } from "../manifest-schema-BXbUAHod.mjs";
31
+ import { i as isDeprecatedCapability, t as CAPABILITY_RENAMES } from "../types-CP1CflWf.mjs";
32
+ import "../ssrf-Cpvg_n3A.mjs";
33
+ import "../ssrf-DpXgKsna.mjs";
34
+ import { t as validateSeed } from "../validate-BMLBvxOC.mjs";
35
+ import { t as applySeed } from "../apply-kUDt80-G.mjs";
36
+ import { a as MigrationManifestValidationError, c as normalizeAstroI18n, i as getMigrationIntegrationMetadata, n as MIGRATION_CONFIG_SYMBOL, s as validateMigrationManifest, t as buildMigrationManifest } from "../manifest-builder-B252yQUf.mjs";
37
+ import "../identity-Ys6Dlc9C.mjs";
38
+ import { n as fingerprintKey, r as generateEncryptionKey, t as EmDashSecretsError } from "../secrets-BEgsAQEU.mjs";
36
39
  import { LocalStorage } from "../storage/local.mjs";
37
- import { t as convertDataForRead } from "../portable-text-B_kqBmXB.mjs";
40
+ import { t as convertDataForRead } from "../portable-text-imBW5cHK.mjs";
38
41
  import { createHeaderAwareFetch, customHeadersInterceptor, getCachedAccessToken, isAccessRedirect, resolveCustomHeaders, runCloudflaredLogin } from "../client/cf-access.mjs";
39
42
  import { EmDashClient } from "../client/index.mjs";
43
+ import { r as fileExists$4, t as bundleCommand } from "../bundle-vn56sLos.mjs";
44
+ import { createRequire } from "node:module";
40
45
  import { Kysely, SqliteDialect, sql } from "kysely";
41
- import { imageSize } from "image-size";
42
- import { z } from "zod";
43
46
  import { createGzipDecoder, unpackTar } from "modern-tar";
44
- import { createWriteStream, existsSync, mkdirSync, readFileSync, writeFileSync } from "node:fs";
45
- import { basename, dirname, extname, join, resolve } from "node:path";
46
47
  import { pathToFileURL } from "node:url";
48
+ import { access, mkdir, readFile, stat, writeFile } from "node:fs/promises";
49
+ import { basename, dirname, isAbsolute, join, parse, resolve } from "node:path";
50
+ import { existsSync, mkdirSync, readFileSync, writeFileSync } from "node:fs";
47
51
  import BetterSqlite3 from "better-sqlite3";
48
- import { access, copyFile, mkdir, readFile, readdir, rm, stat, symlink, writeFile } from "node:fs/promises";
49
52
  import { defineCommand, runCommand, runMain } from "citty";
50
53
  import consola, { consola as consola$1 } from "consola";
51
54
  import pc from "picocolors";
52
55
  import { spawn } from "node:child_process";
53
56
  import { homedir } from "node:os";
54
- import { createHash } from "node:crypto";
55
- import { pipeline } from "node:stream/promises";
56
- import { packTar } from "modern-tar/fs";
57
+ import { parse as parse$1, printParseErrorCode } from "jsonc-parser";
58
+ import { parse as parse$2 } from "smol-toml";
59
+ import { createInterface } from "node:readline/promises";
57
60
 
58
61
  //#region src/cli/commands/auth.ts
59
62
  /**
@@ -132,7 +135,7 @@ function resolveCredentialKey(baseUrl) {
132
135
  try {
133
136
  const url = new URL(baseUrl);
134
137
  if (url.hostname === "localhost" || url.hostname === "127.0.0.1" || url.hostname === "[::1]") {
135
- const projectPath = findProjectRoot(process.cwd());
138
+ const projectPath = findProjectRoot$1(process.cwd());
136
139
  if (projectPath) return `path:${projectPath}`;
137
140
  return url.origin;
138
141
  }
@@ -144,7 +147,7 @@ function resolveCredentialKey(baseUrl) {
144
147
  /**
145
148
  * Walk up from cwd to find the project root (directory containing astro.config.*).
146
149
  */
147
- function findProjectRoot(from) {
150
+ function findProjectRoot$1(from) {
148
151
  let dir = resolve(from);
149
152
  const root = resolve("/");
150
153
  while (dir !== root) {
@@ -919,7 +922,7 @@ async function readPackageJson$2(cwd) {
919
922
  return null;
920
923
  }
921
924
  }
922
- async function fileExists$4(path) {
925
+ async function fileExists$3(path) {
923
926
  try {
924
927
  await access(path);
925
928
  return true;
@@ -971,7 +974,7 @@ const devCommand = defineCommand({
971
974
  process.exit(1);
972
975
  }
973
976
  const dbPath = resolve(cwd, args.database);
974
- if (!await fileExists$4(dbPath)) consola.start("Database not found, initializing...");
977
+ if (!await fileExists$3(dbPath)) consola.start("Database not found, initializing...");
975
978
  const db = createDatabase({ url: `file:${dbPath}` });
976
979
  try {
977
980
  consola.start("Checking database migrations...");
@@ -1010,8 +1013,8 @@ const devCommand = defineCommand({
1010
1013
  "--port",
1011
1014
  args.port
1012
1015
  ];
1013
- const pnpmLockExists = await fileExists$4(resolve(cwd, "pnpm-lock.yaml"));
1014
- const yarnLockExists = await fileExists$4(resolve(cwd, "yarn.lock"));
1016
+ const pnpmLockExists = await fileExists$3(resolve(cwd, "pnpm-lock.yaml"));
1017
+ const yarnLockExists = await fileExists$3(resolve(cwd, "yarn.lock"));
1015
1018
  let cmd;
1016
1019
  let cmdArgs;
1017
1020
  if (pnpmLockExists) {
@@ -1053,9 +1056,28 @@ const devCommand = defineCommand({
1053
1056
  /**
1054
1057
  * emdash doctor
1055
1058
  *
1056
- * Diagnose database health: connection, migrations, schema integrity.
1059
+ * Diagnose database health (connection, migrations, schema integrity) and
1060
+ * Cloudflare Worker scheduler wiring (Cron Trigger + scheduled() handler).
1057
1061
  */
1058
- async function fileExists$3(path) {
1062
+ const WRANGLER_CONFIG_FILES = [
1063
+ "wrangler.jsonc",
1064
+ "wrangler.json",
1065
+ "wrangler.toml"
1066
+ ];
1067
+ const CLOUDFLARE_WORKER_MODULE = "@emdash-cms/cloudflare/worker";
1068
+ const WORKER_FIX = `export { default, PluginBridge } from "${CLOUDFLARE_WORKER_MODULE}";`;
1069
+ const MAIN_FIX_JSONC = `"main": "./src/worker.ts"`;
1070
+ const MAIN_FIX_TOML = `main = "./src/worker.ts"`;
1071
+ const TRIGGER_FIX_JSONC = `"triggers": { "crons": ["* * * * *"] }`;
1072
+ const TRIGGER_FIX_TOML = `[triggers]\ncrons = ["* * * * *"]`;
1073
+ const SCHEDULED_HANDLER_PATTERN = /\bscheduled\s*:\s*createScheduledHandler\s*\(/m;
1074
+ function triggerFix(configPath) {
1075
+ return configPath.endsWith(".toml") ? TRIGGER_FIX_TOML : TRIGGER_FIX_JSONC;
1076
+ }
1077
+ function mainFix(configPath) {
1078
+ return configPath.endsWith(".toml") ? MAIN_FIX_TOML : MAIN_FIX_JSONC;
1079
+ }
1080
+ async function fileExists$2(path) {
1059
1081
  try {
1060
1082
  await access(path);
1061
1083
  return true;
@@ -1063,12 +1085,115 @@ async function fileExists$3(path) {
1063
1085
  return false;
1064
1086
  }
1065
1087
  }
1088
+ function isRecord$2(value) {
1089
+ return typeof value === "object" && value !== null && !Array.isArray(value);
1090
+ }
1091
+ function sourcePosition(source, offset) {
1092
+ const prefix = source.slice(0, offset);
1093
+ return {
1094
+ line: prefix.split("\n").length,
1095
+ column: offset - prefix.lastIndexOf("\n")
1096
+ };
1097
+ }
1098
+ async function findWranglerConfig(cwd) {
1099
+ for (const filename of WRANGLER_CONFIG_FILES) {
1100
+ const path = resolve(cwd, filename);
1101
+ if (await fileExists$2(path)) return path;
1102
+ }
1103
+ return null;
1104
+ }
1105
+ function workerExportsScheduledMaintenance(source) {
1106
+ const modulePattern = CLOUDFLARE_WORKER_MODULE.replaceAll("/", "\\/");
1107
+ const reExportsWorker = new RegExp(`export\\s*\\{[^}]*\\bdefault\\b[^}]*\\}\\s*from\\s*["']${modulePattern}["']`, "m");
1108
+ const importsFactory = new RegExp(`import\\s+[^;]*\\{[^}]*\\bcreateScheduledHandler\\b[^}]*\\}\\s*from\\s*["']${modulePattern}["']`, "m");
1109
+ return reExportsWorker.test(source) || importsFactory.test(source) && SCHEDULED_HANDLER_PATTERN.test(source);
1110
+ }
1111
+ async function checkSchedulerWiringAtPath(cwd, configPath) {
1112
+ const configSource = await readFile(configPath, "utf8");
1113
+ let parsed;
1114
+ if (configPath.endsWith(".toml")) try {
1115
+ parsed = parse$2(configSource);
1116
+ } catch (error) {
1117
+ return [{
1118
+ name: "scheduler config",
1119
+ status: "fail",
1120
+ message: `could not parse ${configPath}: ${error instanceof Error ? error.message : "invalid TOML"} — fix the Wrangler configuration syntax`
1121
+ }];
1122
+ }
1123
+ else {
1124
+ const parseErrors = [];
1125
+ parsed = parse$1(configSource, parseErrors, {
1126
+ allowTrailingComma: true,
1127
+ disallowComments: false
1128
+ });
1129
+ if (parseErrors.length > 0) {
1130
+ const error = parseErrors[0];
1131
+ const { line, column } = sourcePosition(configSource, error.offset);
1132
+ return [{
1133
+ name: "scheduler config",
1134
+ status: "fail",
1135
+ message: `could not parse ${configPath}: ${printParseErrorCode(error.error)} at line ${line}, column ${column} — fix the Wrangler configuration syntax`
1136
+ }];
1137
+ }
1138
+ }
1139
+ if (!isRecord$2(parsed)) return [{
1140
+ name: "scheduler config",
1141
+ status: "fail",
1142
+ message: `could not parse ${configPath}: expected an object — fix the Wrangler configuration syntax`
1143
+ }];
1144
+ const triggers = isRecord$2(parsed.triggers) ? parsed.triggers : null;
1145
+ const hasCronTrigger = Array.isArray(triggers?.crons) && triggers.crons.some((cron) => typeof cron === "string" && cron.trim().length > 0);
1146
+ const main = typeof parsed.main === "string" && parsed.main.trim() ? parsed.main : null;
1147
+ if (!main) return [{
1148
+ name: "scheduler handler",
1149
+ status: "fail",
1150
+ message: `Wrangler configuration has no Worker entry to inspect — add ${mainFix(configPath)}, then export: ${WORKER_FIX}`
1151
+ }];
1152
+ const workerPath = resolve(cwd, main);
1153
+ let hasScheduledHandler = false;
1154
+ try {
1155
+ hasScheduledHandler = workerExportsScheduledMaintenance(await readFile(workerPath, "utf8"));
1156
+ } catch (error) {
1157
+ if ((isRecord$2(error) && typeof error.code === "string" ? error.code : null) !== "ENOENT") return [{
1158
+ name: "scheduler handler",
1159
+ status: "fail",
1160
+ message: `could not read Worker entry ${workerPath}: ${error instanceof Error ? error.message : "unknown I/O error"} — check the file path and permissions`
1161
+ }];
1162
+ return [{
1163
+ name: "scheduler handler",
1164
+ status: "fail",
1165
+ message: `Worker entry not found at ${workerPath} — create it with: ${WORKER_FIX}`
1166
+ }];
1167
+ }
1168
+ if (hasCronTrigger && !hasScheduledHandler) return [{
1169
+ name: "scheduler handler",
1170
+ status: "fail",
1171
+ message: `Cron Trigger is configured, but ${main} does not export EmDash scheduled() maintenance — replace its Worker export with: ${WORKER_FIX}`
1172
+ }];
1173
+ if (hasScheduledHandler && !hasCronTrigger) return [{
1174
+ name: "scheduler trigger",
1175
+ status: "fail",
1176
+ message: `EmDash scheduled() handler is exported, but no Cron Trigger is configured — add this to ${configPath}: ${triggerFix(configPath)}`
1177
+ }];
1178
+ if (!hasCronTrigger && !hasScheduledHandler) return [];
1179
+ return [{
1180
+ name: "scheduler wiring",
1181
+ status: "pass",
1182
+ message: `Cron Trigger and scheduled() handler found (${main})`
1183
+ }];
1184
+ }
1185
+ async function checkDoctor(cwd, dbPath) {
1186
+ const results = await checkDatabase(dbPath);
1187
+ const configPath = await findWranglerConfig(cwd);
1188
+ if (configPath) results.push(...await checkSchedulerWiringAtPath(cwd, configPath));
1189
+ return results;
1190
+ }
1066
1191
  function printResult(result) {
1067
1192
  (result.status === "pass" ? consola.success : result.status === "warn" ? consola.warn : consola.error)(`${result.name}: ${result.message}`);
1068
1193
  }
1069
1194
  async function checkDatabase(dbPath) {
1070
1195
  const results = [];
1071
- if (!await fileExists$3(dbPath)) {
1196
+ if (!await fileExists$2(dbPath)) {
1072
1197
  results.push({
1073
1198
  name: "database",
1074
1199
  status: "fail",
@@ -1149,7 +1274,7 @@ async function checkDatabase(dbPath) {
1149
1274
  const doctorCommand = defineCommand({
1150
1275
  meta: {
1151
1276
  name: "doctor",
1152
- description: "Check database health and diagnose issues"
1277
+ description: "Check database health, scheduler wiring, and diagnose issues"
1153
1278
  },
1154
1279
  args: {
1155
1280
  database: {
@@ -1170,14 +1295,16 @@ const doctorCommand = defineCommand({
1170
1295
  }
1171
1296
  },
1172
1297
  async run({ args }) {
1173
- const results = await checkDatabase(resolve(resolve(args.cwd), args.database));
1298
+ const cwd = resolve(args.cwd);
1299
+ const results = await checkDoctor(cwd, resolve(cwd, args.database));
1300
+ const fails = results.filter((result) => result.status === "fail");
1174
1301
  if (args.json) {
1175
1302
  process.stdout.write(JSON.stringify(results, null, 2) + "\n");
1303
+ if (fails.length > 0) process.exitCode = 1;
1176
1304
  return;
1177
1305
  }
1178
1306
  consola.start("EmDash Doctor\n");
1179
1307
  for (const result of results) printResult(result);
1180
- const fails = results.filter((r) => r.status === "fail");
1181
1308
  const warns = results.filter((r) => r.status === "warn");
1182
1309
  consola.log("");
1183
1310
  if (fails.length === 0 && warns.length === 0) consola.success("All checks passed");
@@ -1392,8 +1519,10 @@ async function exportCollections(db) {
1392
1519
  labelSingular: collection.labelSingular || void 0,
1393
1520
  description: collection.description || void 0,
1394
1521
  icon: collection.icon || void 0,
1522
+ admin: collection.admin,
1395
1523
  supports: collection.supports.length > 0 ? collection.supports : void 0,
1396
1524
  urlPattern: collection.urlPattern || void 0,
1525
+ routable: collection.routable === false ? false : void 0,
1397
1526
  hidden: collection.hidden || void 0,
1398
1527
  sortOrder: collection.sortOrder,
1399
1528
  fields: fields.map((field) => ({
@@ -1403,6 +1532,7 @@ async function exportCollections(db) {
1403
1532
  required: field.required || void 0,
1404
1533
  unique: field.unique || void 0,
1405
1534
  searchable: field.searchable || void 0,
1535
+ indexed: field.indexed || void 0,
1406
1536
  defaultValue: field.defaultValue,
1407
1537
  validation: field.validation ? { ...field.validation } : void 0,
1408
1538
  widget: field.widget || void 0,
@@ -1633,7 +1763,7 @@ async function exportContent(db, collections, includeCollections, bylineGroupToS
1633
1763
  const processedData = processDataForExport(item.data, collection.fields, mediaMap);
1634
1764
  const entry = {
1635
1765
  id: seedId,
1636
- slug: item.slug || item.id,
1766
+ slug: item.slug?.trim() ? item.slug : collection.routable === false ? void 0 : item.id,
1637
1767
  status: item.status === "published" || item.status === "draft" ? item.status : void 0,
1638
1768
  data: processedData
1639
1769
  };
@@ -1735,7 +1865,7 @@ async function getTaxonomyAssignments(taxonomyRepo, collection, entryId) {
1735
1865
  *
1736
1866
  * Initialize database from template config in package.json
1737
1867
  */
1738
- async function fileExists$2(path) {
1868
+ async function fileExists$1(path) {
1739
1869
  try {
1740
1870
  await access(path);
1741
1871
  return true;
@@ -1826,7 +1956,7 @@ const initCommand = defineCommand({
1826
1956
  if (alreadyInitialized && args.force) consola.warn("Re-initializing (--force)...");
1827
1957
  if (config?.schema) {
1828
1958
  const schemaPath = resolve(cwd, config.schema);
1829
- if (await fileExists$2(schemaPath)) {
1959
+ if (await fileExists$1(schemaPath)) {
1830
1960
  consola.start(`Running schema: ${config.schema}`);
1831
1961
  try {
1832
1962
  await runSqlFile(db, schemaPath);
@@ -2475,77 +2605,20 @@ const menuCommand = defineCommand({
2475
2605
  });
2476
2606
 
2477
2607
  //#endregion
2478
- //#region src/cli/commands/bundle-utils.ts
2479
- /**
2480
- * Bundle utility functions
2481
- *
2482
- * Shared logic extracted from the bundle command so it can be tested
2483
- * without the CLI harness and tsdown dependency.
2484
- */
2485
- const MAX_BUNDLE_SIZE = 256 * 1024;
2486
- const MAX_FILE_SIZE = 128 * 1024;
2487
- const MAX_FILE_COUNT = 20;
2488
- const MAX_SCREENSHOTS = 5;
2489
- const MAX_SCREENSHOT_WIDTH = 1920;
2490
- const MAX_SCREENSHOT_HEIGHT = 1080;
2491
- const ICON_SIZE = 256;
2492
- const MCP_TOOL_NAME_PATTERN = /^[a-zA-Z0-9_-]+$/;
2493
- /**
2494
- * Matches Node.js built-in imports in bundled output:
2495
- * - require("node:xxx") / require("xxx")
2496
- * - import("node:xxx") / import("xxx")
2497
- * - import X from "node:xxx" / import { X } from "node:xxx"
2498
- * - import * as X from "node:xxx"
2499
- * - export { X } from "node:xxx"
2500
- * Captures the base module name (e.g. "fs" from "node:fs/promises").
2501
- */
2502
- const NODE_BUILTIN_IMPORT_RE = /(?:import|export|require)\s*(?:\(|[^(]*?\bfrom\s+)["'](?:node:)?([a-z_]+)(?:\/[^"']*)?\s*["']\)?/g;
2503
- const LEADING_DOT_SLASH_RE = /^\.\//;
2504
- const DIST_PREFIX_RE = /^dist\//;
2505
- const MJS_EXT_RE = /\.m?js$/;
2506
- const TS_TO_TSX_RE = /\.ts$/;
2507
- /** Node.js built-in modules that shouldn't appear in sandbox code */
2508
- const NODE_BUILTINS = new Set([
2509
- "assert",
2510
- "buffer",
2511
- "child_process",
2512
- "cluster",
2513
- "crypto",
2514
- "dgram",
2515
- "dns",
2516
- "domain",
2517
- "events",
2518
- "fs",
2519
- "http",
2520
- "http2",
2521
- "https",
2522
- "inspector",
2523
- "module",
2524
- "net",
2525
- "os",
2526
- "path",
2527
- "perf_hooks",
2528
- "process",
2529
- "punycode",
2530
- "querystring",
2531
- "readline",
2532
- "repl",
2533
- "stream",
2534
- "string_decoder",
2535
- "sys",
2536
- "timers",
2537
- "tls",
2538
- "trace_events",
2539
- "tty",
2540
- "url",
2541
- "util",
2542
- "v8",
2543
- "vm",
2544
- "wasi",
2545
- "worker_threads",
2546
- "zlib"
2547
- ]);
2548
- async function fileExists$1(path) {
2608
+ //#region src/migrations/config-loader.ts
2609
+ const ASTRO_CONFIG_FILENAMES = [
2610
+ "astro.config.mjs",
2611
+ "astro.config.js",
2612
+ "astro.config.ts",
2613
+ "astro.config.mts"
2614
+ ];
2615
+ var MigrationConfigLoaderError = class extends Error {
2616
+ constructor(message, options) {
2617
+ super(message, options);
2618
+ this.name = "MigrationConfigLoaderError";
2619
+ }
2620
+ };
2621
+ async function isAccessible(path) {
2549
2622
  try {
2550
2623
  await access(path);
2551
2624
  return true;
@@ -2553,571 +2626,497 @@ async function fileExists$1(path) {
2553
2626
  return false;
2554
2627
  }
2555
2628
  }
2556
- /** Convert an absolute build artifact path into a portable ESM import specifier. */
2557
- function toFileImportSpecifier(path) {
2558
- return pathToFileURL(path).href;
2629
+ async function findAstroConfigFile(projectRoot, configFile) {
2630
+ const root = resolve(projectRoot);
2631
+ if (configFile) {
2632
+ const explicitPath = isAbsolute(configFile) ? configFile : resolve(root, configFile);
2633
+ if (await isAccessible(explicitPath)) return explicitPath;
2634
+ throw new MigrationConfigLoaderError(`Astro config file not found: ${explicitPath}`);
2635
+ }
2636
+ for (const filename of ASTRO_CONFIG_FILENAMES) {
2637
+ const candidate = resolve(root, filename);
2638
+ if (await isAccessible(candidate)) return candidate;
2639
+ }
2640
+ throw new MigrationConfigLoaderError(`No Astro config file found in ${root}`);
2559
2641
  }
2560
- /**
2561
- * Read image dimensions from a buffer.
2562
- * Returns [width, height] or null if the format is unrecognized.
2563
- */
2564
- function readImageDimensions(buf) {
2642
+ function projectRequire(projectRoot) {
2643
+ return createRequire(resolve(projectRoot, "package.json"));
2644
+ }
2645
+ async function importModule(path) {
2646
+ return import(pathToFileURL(path).href);
2647
+ }
2648
+ function isRecord$1(value) {
2649
+ return typeof value === "object" && value !== null;
2650
+ }
2651
+ function moduleExport$1(module, name) {
2652
+ if (!isRecord$1(module)) return void 0;
2653
+ const direct = module[name];
2654
+ if (direct !== void 0) return direct;
2655
+ const defaultExport = module.default;
2656
+ return isRecord$1(defaultExport) ? defaultExport[name] : void 0;
2657
+ }
2658
+ function isCoreMigrationIdentity(value) {
2659
+ return isRecord$1(value) && typeof value.emdashVersion === "string" && Array.isArray(value.names) && value.names.every((name) => typeof name === "string") && typeof value.fingerprint === "string";
2660
+ }
2661
+ async function loadProjectConfig(projectRoot, configFile) {
2662
+ let viteEntrypoint;
2565
2663
  try {
2566
- const result = imageSize(buf);
2567
- if (result.width != null && result.height != null) return [result.width, result.height];
2568
- return null;
2569
- } catch {
2570
- return null;
2664
+ viteEntrypoint = createRequire(projectRequire(projectRoot).resolve("astro")).resolve("vite");
2665
+ } catch (error) {
2666
+ throw new MigrationConfigLoaderError("Could not resolve Vite through the project's Astro installation", { cause: error });
2571
2667
  }
2668
+ const loadConfigFromFile = moduleExport$1(await importModule(viteEntrypoint), "loadConfigFromFile");
2669
+ if (typeof loadConfigFromFile !== "function") throw new MigrationConfigLoaderError("The Vite installation used by project-local Astro does not export loadConfigFromFile");
2670
+ const loaded = await Reflect.apply(loadConfigFromFile, void 0, [
2671
+ {
2672
+ command: "build",
2673
+ mode: "production"
2674
+ },
2675
+ configFile,
2676
+ projectRoot,
2677
+ "silent"
2678
+ ]);
2679
+ if (!isRecord$1(loaded) || !Object.hasOwn(loaded, "config")) throw new MigrationConfigLoaderError(`Vite could not load Astro config: ${configFile}`);
2680
+ return loaded.config;
2572
2681
  }
2573
- /**
2574
- * Extract manifest metadata from a ResolvedPlugin.
2575
- * Strips functions (hooks, route handlers) and keeps only serializable metadata.
2576
- */
2577
- function extractManifest(plugin) {
2578
- const hooks = [];
2579
- for (const [name, resolved] of Object.entries(plugin.hooks)) {
2580
- if (!resolved) continue;
2581
- if (resolved.exclusive || resolved.priority !== 100 || resolved.timeout !== 5e3) {
2582
- const entry = { name };
2583
- if (resolved.exclusive) entry.exclusive = true;
2584
- if (resolved.priority !== 100) entry.priority = resolved.priority;
2585
- if (resolved.timeout !== 5e3) entry.timeout = resolved.timeout;
2586
- hooks.push(entry);
2587
- } else hooks.push(name);
2682
+ async function loadProjectIdentity(projectRoot) {
2683
+ let identityEntrypoint;
2684
+ try {
2685
+ identityEntrypoint = projectRequire(projectRoot).resolve("emdash/migrations");
2686
+ } catch (error) {
2687
+ throw new MigrationConfigLoaderError("Could not resolve emdash/migrations from the project", { cause: error });
2588
2688
  }
2589
- const routes = Object.entries(plugin.routes).map(([name, route]) => {
2590
- if (route.public === void 0 && route.permission === void 0 && route.cacheControl === void 0) return name;
2591
- const entry = { name };
2592
- if (route.public !== void 0) entry.public = route.public;
2593
- if (route.permission !== void 0) entry.permission = route.permission;
2594
- if (route.cacheControl !== void 0) entry.cacheControl = route.cacheControl;
2595
- return entry;
2596
- });
2597
- const tools = Object.entries(plugin.mcp?.tools ?? {}).map(([name, tool]) => {
2598
- if (!MCP_TOOL_NAME_PATTERN.test(name)) throw new Error(`Invalid MCP tool name "${name}"`);
2599
- const route = plugin.routes[tool.route];
2600
- if (!route?.permission || route.public) throw new Error(`MCP tool "${name}" must reference a private route with a permission`);
2601
- return {
2602
- name,
2603
- description: tool.description,
2604
- route: tool.route,
2605
- permission: route.permission,
2606
- destructive: tool.destructive ?? false,
2607
- inputSchema: z.toJSONSchema(tool.input, { target: "draft-7" }),
2608
- ...tool.output ? { outputSchema: z.toJSONSchema(tool.output, { target: "draft-7" }) } : {}
2609
- };
2689
+ const getIdentity = moduleExport$1(await importModule(identityEntrypoint), "getCoreMigrationIdentity");
2690
+ if (typeof getIdentity !== "function") throw new MigrationConfigLoaderError("The project-local emdash/migrations module does not export getCoreMigrationIdentity");
2691
+ const identity = await Reflect.apply(getIdentity, void 0, []);
2692
+ if (!isCoreMigrationIdentity(identity)) throw new MigrationConfigLoaderError("The project-local emdash/migrations module returned an invalid migration identity");
2693
+ return identity;
2694
+ }
2695
+ const defaultDependencies$1 = {
2696
+ findConfigFile: findAstroConfigFile,
2697
+ loadConfig: loadProjectConfig,
2698
+ loadIdentity: loadProjectIdentity
2699
+ };
2700
+ function asAstroConfig(value) {
2701
+ if (typeof value !== "object" || value === null) throw new MigrationConfigLoaderError("Astro config must export an object");
2702
+ return value;
2703
+ }
2704
+ async function buildMigrationManifestFromConfig(options, dependencies = defaultDependencies$1) {
2705
+ const projectRoot = resolve(options.projectRoot);
2706
+ const configFile = await dependencies.findConfigFile(projectRoot, options.configFile);
2707
+ const config = asAstroConfig(await dependencies.loadConfig(projectRoot, configFile));
2708
+ const matchingIntegrations = (Array.isArray(config.integrations) ? config.integrations : []).filter((integration) => getMigrationIntegrationMetadata(integration) !== void 0);
2709
+ if (matchingIntegrations.length !== 1) throw new MigrationConfigLoaderError(`Expected exactly one EmDash integration with migration metadata (${String(MIGRATION_CONFIG_SYMBOL)}), found ${matchingIntegrations.length}`);
2710
+ const metadata = getMigrationIntegrationMetadata(matchingIntegrations[0]);
2711
+ if (!metadata?.database) throw new MigrationConfigLoaderError("The EmDash integration does not provide database migration metadata");
2712
+ return buildMigrationManifest({
2713
+ identity: await dependencies.loadIdentity(projectRoot),
2714
+ i18n: normalizeAstroI18n(config.i18n),
2715
+ database: metadata.database
2610
2716
  });
2717
+ }
2718
+
2719
+ //#endregion
2720
+ //#region src/cli/commands/migrate.ts
2721
+ const FINGERPRINT_PATTERN = /^[0-9a-f]{64}$/;
2722
+ const SAFE_TARGET_KIND_PATTERN = /^[a-z][a-z0-9_-]*$/;
2723
+ const SAFE_MIGRATION_NAME_PATTERN = /^[A-Za-z0-9_.-]+$/;
2724
+ const CREDENTIAL_URL_PATTERN = /:\/\/[^/\s]+@/;
2725
+ const CREDENTIAL_QUERY_PATTERN = /[?&](?:auth|credential|key|password|secret|signature|token)=/i;
2726
+ const MIGRATE_EXIT_CODES = Object.freeze({
2727
+ success: 0,
2728
+ error: 1,
2729
+ pending: 2,
2730
+ unknownApplied: 3,
2731
+ confirmation: 4,
2732
+ interrupted: 130
2733
+ });
2734
+ var MigrateCommandError = class extends Error {
2735
+ constructor(message) {
2736
+ super(message);
2737
+ this.name = "MigrateCommandError";
2738
+ }
2739
+ };
2740
+ function isRecord(value) {
2741
+ return typeof value === "object" && value !== null && !Array.isArray(value);
2742
+ }
2743
+ function moduleExport(module, name) {
2744
+ if (!isRecord(module)) return void 0;
2745
+ const direct = Reflect.get(module, name);
2746
+ if (direct !== void 0) return direct;
2747
+ const defaultExport = Reflect.get(module, "default");
2748
+ return isRecord(defaultExport) ? Reflect.get(defaultExport, name) : void 0;
2749
+ }
2750
+ async function importProjectModule(projectRoot, specifier) {
2751
+ let resolvedEntrypoint;
2752
+ try {
2753
+ resolvedEntrypoint = createRequire(resolve(projectRoot, "package.json")).resolve(specifier);
2754
+ } catch {
2755
+ throw new MigrateCommandError(`Could not resolve ${specifier} from the project.`);
2756
+ }
2757
+ return import(pathToFileURL(resolvedEntrypoint).href);
2758
+ }
2759
+ function validateIdentity(value) {
2760
+ if (!isRecord(value) || typeof value.emdashVersion !== "string" || !Array.isArray(value.names) || !value.names.every((name) => typeof name === "string") || typeof value.fingerprint !== "string" || !FINGERPRINT_PATTERN.test(value.fingerprint)) throw new MigrateCommandError("The project-local emdash/migrations module returned an invalid migration identity.");
2611
2761
  return {
2612
- id: plugin.id,
2613
- version: plugin.version,
2614
- declaredAccess: capabilitiesToDeclaredAccess(plugin.capabilities, plugin.allowedHosts),
2615
- capabilities: plugin.capabilities,
2616
- allowedHosts: plugin.allowedHosts,
2617
- storage: plugin.storage,
2618
- hooks,
2619
- routes,
2620
- ...tools.length > 0 ? { mcp: { tools } } : {},
2621
- admin: {
2622
- settingsSchema: plugin.admin.settingsSchema,
2623
- pages: plugin.admin.pages,
2624
- widgets: plugin.admin.widgets
2625
- }
2762
+ emdashVersion: value.emdashVersion,
2763
+ names: [...value.names],
2764
+ fingerprint: value.fingerprint
2626
2765
  };
2627
2766
  }
2628
- /**
2629
- * Scan bundled code for Node.js built-in imports.
2630
- * Matches require("node:xxx"), require("xxx"), import("node:xxx") — the patterns
2631
- * that appear in bundled ESM/CJS output (not source-level named imports).
2632
- * Returns deduplicated array of built-in module names found.
2633
- */
2634
- function findNodeBuiltinImports(code) {
2635
- const found = [];
2636
- NODE_BUILTIN_IMPORT_RE.lastIndex = 0;
2637
- let match;
2638
- while ((match = NODE_BUILTIN_IMPORT_RE.exec(code)) !== null) {
2639
- const mod = match[1];
2640
- if (NODE_BUILTINS.has(mod)) found.push(mod);
2641
- }
2642
- return [...new Set(found)];
2767
+ async function loadProjectMigrationIdentity(projectRoot) {
2768
+ const getIdentity = moduleExport(await importProjectModule(projectRoot, "emdash/migrations"), "getCoreMigrationIdentity");
2769
+ if (typeof getIdentity !== "function") throw new MigrateCommandError("The project-local emdash/migrations module does not export getCoreMigrationIdentity.");
2770
+ return validateIdentity(await Reflect.apply(getIdentity, void 0, []));
2643
2771
  }
2644
- /**
2645
- * Find a build output file by base name, checking common extensions.
2646
- * tsdown may output .mjs, .js, or .cjs depending on format and config.
2647
- */
2648
- async function findBuildOutput(dir, baseName) {
2649
- for (const ext of [
2650
- ".mjs",
2651
- ".js",
2652
- ".cjs"
2653
- ]) {
2654
- const candidate = join(dir, `${baseName}${ext}`);
2655
- if (await fileExists$1(candidate)) return candidate;
2772
+ async function loadProjectMigrationExecutor(projectRoot, entrypoint) {
2773
+ const factory = moduleExport(await importProjectModule(projectRoot, entrypoint), "createMigrationExecutor");
2774
+ if (typeof factory !== "function") throw new MigrateCommandError(`The project-local ${entrypoint} module does not export createMigrationExecutor.`);
2775
+ return (manifestConfig, context) => Reflect.apply(factory, void 0, [manifestConfig, context]);
2776
+ }
2777
+ async function findProjectRoot(start) {
2778
+ let current = resolve(start);
2779
+ const filesystemRoot = parse(current).root;
2780
+ for (;;) {
2781
+ try {
2782
+ await readFile(resolve(current, "package.json"), "utf8");
2783
+ return current;
2784
+ } catch (error) {
2785
+ if (isRecord(error) && error.code !== "ENOENT" && error.code !== "ENOTDIR") throw new MigrateCommandError("Could not read the project package.json.");
2786
+ }
2787
+ if (current === filesystemRoot) break;
2788
+ current = dirname(current);
2656
2789
  }
2790
+ throw new MigrateCommandError("Could not find a project root containing package.json.");
2657
2791
  }
2658
- /**
2659
- * Resolve a dist/built path back to its source .ts/.tsx equivalent.
2660
- * E.g., "./dist/index.mjs" → "src/index.ts"
2661
- */
2662
- async function resolveSourceEntry(pluginDir, distPath) {
2663
- const cleaned = distPath.replace(LEADING_DOT_SLASH_RE, "");
2664
- const srcPath = cleaned.replace(DIST_PREFIX_RE, "src/").replace(MJS_EXT_RE, ".ts");
2665
- const srcFull = resolve(pluginDir, srcPath);
2666
- if (await fileExists$1(srcFull)) return srcFull;
2667
- const tsxFull = resolve(pluginDir, srcPath.replace(TS_TO_TSX_RE, ".tsx"));
2668
- if (await fileExists$1(tsxFull)) return tsxFull;
2669
- const direct = resolve(pluginDir, cleaned);
2670
- if (await fileExists$1(direct)) return direct;
2792
+ async function readMigrationManifestFile(path, isDefault) {
2793
+ let source;
2794
+ try {
2795
+ source = await readFile(path, "utf8");
2796
+ } catch (error) {
2797
+ if (isDefault && isRecord(error) && (error.code === "ENOENT" || error.code === "ENOTDIR")) throw new MigrateCommandError(`No migration manifest found at ${path}. Build the project or use --from-config.`);
2798
+ throw new MigrateCommandError(`Could not read migration manifest: ${path}`);
2799
+ }
2800
+ try {
2801
+ return JSON.parse(source);
2802
+ } catch {
2803
+ throw new MigrateCommandError(`Migration manifest is not valid JSON: ${path}`);
2804
+ }
2671
2805
  }
2672
- const TS_SOURCE_EXPORT_RE = /\.(?:ts|tsx|mts|cts|jsx)$/;
2673
- /**
2674
- * Find package.json exports that point to source files instead of built output.
2675
- * Returns an array of `{ exportPath, resolvedPath }` for each offending export.
2676
- */
2677
- function findSourceExports(exports) {
2678
- const issues = [];
2679
- for (const [exportPath, exportValue] of Object.entries(exports)) {
2680
- const resolved = typeof exportValue === "string" ? exportValue : exportValue && typeof exportValue === "object" && "import" in exportValue ? exportValue.import : null;
2681
- if (resolved && TS_SOURCE_EXPORT_RE.test(resolved)) issues.push({
2682
- exportPath,
2683
- resolvedPath: resolved
2684
- });
2806
+ async function confirmWithReadline(message) {
2807
+ const prompt = createInterface({
2808
+ input: process.stdin,
2809
+ output: process.stderr
2810
+ });
2811
+ try {
2812
+ const answer = await prompt.question(`${message} [y/N] `);
2813
+ return answer.trim().toLowerCase() === "y" || answer.trim().toLowerCase() === "yes";
2814
+ } finally {
2815
+ prompt.close();
2685
2816
  }
2686
- return issues;
2687
2817
  }
2688
- /**
2689
- * Recursively walk a staging directory and return a flat list of all files
2690
- * with sizes. Names are relative to `dir` so they match what would appear
2691
- * as the tarball entry name.
2692
- */
2693
- async function collectBundleEntries(dir) {
2694
- const entries = [];
2695
- await walkBundle(dir, "", entries);
2696
- return entries;
2818
+ function onProcessSignal(signal, handler) {
2819
+ const listener = () => {
2820
+ handler().finally(() => process.exit(MIGRATE_EXIT_CODES.interrupted));
2821
+ };
2822
+ process.once(signal, listener);
2823
+ return () => process.removeListener(signal, listener);
2697
2824
  }
2698
- async function walkBundle(dir, prefix, into) {
2699
- const items = await readdir(dir, { withFileTypes: true });
2700
- for (const item of items) {
2701
- const fullPath = join(dir, item.name);
2702
- const relPath = prefix ? `${prefix}/${item.name}` : item.name;
2703
- if (item.isFile()) {
2704
- const s = await stat(fullPath);
2705
- into.push({
2706
- name: relPath,
2707
- bytes: s.size
2708
- });
2709
- } else if (item.isDirectory()) await walkBundle(fullPath, relPath, into);
2825
+ const defaultDependencies = {
2826
+ cwd: process.cwd(),
2827
+ env: process.env,
2828
+ interactive: Boolean(process.stdin.isTTY && process.stdout.isTTY),
2829
+ findProjectRoot,
2830
+ readManifest: readMigrationManifestFile,
2831
+ buildManifestFromConfig: (projectRoot, configFile) => buildMigrationManifestFromConfig({
2832
+ projectRoot,
2833
+ configFile
2834
+ }),
2835
+ loadProjectIdentity: loadProjectMigrationIdentity,
2836
+ loadProjectExecutor: loadProjectMigrationExecutor,
2837
+ confirm: confirmWithReadline,
2838
+ writeStdout: (value) => process.stdout.write(`${value}\n`),
2839
+ writeStderr: (value) => process.stderr.write(`${value}\n`),
2840
+ onSignal: onProcessSignal,
2841
+ cleanupTimeoutMs: 2e3
2842
+ };
2843
+ function validateOptions(options) {
2844
+ if (options.manifest && options.fromConfig) throw new MigrateCommandError("--manifest and --from-config cannot be used together.");
2845
+ if (options.config && !options.fromConfig) throw new MigrateCommandError("--config requires --from-config.");
2846
+ if (options.check && options.status) throw new MigrateCommandError("--check and --status cannot be used together.");
2847
+ if (options.expectedTargetFingerprint && !FINGERPRINT_PATTERN.test(options.expectedTargetFingerprint)) throw new MigrateCommandError("--expected-target-fingerprint must be a SHA-256 fingerprint.");
2848
+ }
2849
+ function hasControlCharacter(value) {
2850
+ for (let index = 0; index < value.length; index++) {
2851
+ const code = value.charCodeAt(index);
2852
+ if (code <= 31 || code === 127) return true;
2710
2853
  }
2854
+ return false;
2711
2855
  }
2712
- /**
2713
- * Sum the byte sizes of all entries.
2714
- */
2715
- function totalBundleBytes(entries) {
2716
- let total = 0;
2717
- for (const e of entries) total += e.bytes;
2718
- return total;
2856
+ function targetField(value, name) {
2857
+ if (value === void 0) return void 0;
2858
+ if (typeof value !== "string" || value.length === 0 || hasControlCharacter(value) || CREDENTIAL_URL_PATTERN.test(value) || CREDENTIAL_QUERY_PATTERN.test(value)) throw new MigrateCommandError(`The executor returned an unsafe migration target ${name}.`);
2859
+ return value;
2719
2860
  }
2720
- /**
2721
- * Check a bundle against the three size caps from RFC 0001:
2722
- * - total decompressed ≤ MAX_BUNDLE_SIZE
2723
- * - per-file decompressed ≤ MAX_FILE_SIZE
2724
- * - file count ≤ MAX_FILE_COUNT
2725
- *
2726
- * Returns a list of violation messages (empty if the bundle is within all
2727
- * caps). Messages are deterministic per input — the total/count violations
2728
- * come first, then oversized files in alphabetical order — so the same
2729
- * bundle always produces the same error text.
2730
- */
2731
- function validateBundleSize(entries) {
2732
- const violations = [];
2733
- const total = totalBundleBytes(entries);
2734
- if (total > MAX_BUNDLE_SIZE) violations.push(`Bundle size ${formatBytes(total)} exceeds maximum of ${formatBytes(MAX_BUNDLE_SIZE)}.`);
2735
- if (entries.length > MAX_FILE_COUNT) violations.push(`Bundle contains ${entries.length} files, exceeds maximum of ${MAX_FILE_COUNT}.`);
2736
- const oversized = entries.filter((e) => e.bytes > MAX_FILE_SIZE).toSorted((a, b) => a.name.localeCompare(b.name));
2737
- for (const e of oversized) violations.push(`File ${e.name} is ${formatBytes(e.bytes)}, exceeds per-file maximum of ${formatBytes(MAX_FILE_SIZE)}.`);
2738
- return violations;
2861
+ function immutableTarget(value) {
2862
+ if (!isRecord(value)) throw new MigrateCommandError("The executor returned an invalid migration target.");
2863
+ const kind = targetField(value.kind, "kind");
2864
+ const label = targetField(value.label, "label");
2865
+ const fingerprint = targetField(value.fingerprint, "fingerprint");
2866
+ if (!kind || !SAFE_TARGET_KIND_PATTERN.test(kind) || !label || !fingerprint || !FINGERPRINT_PATTERN.test(fingerprint)) throw new MigrateCommandError("The executor returned an invalid migration target.");
2867
+ const target = {
2868
+ kind,
2869
+ label,
2870
+ fingerprint
2871
+ };
2872
+ const accountId = targetField(value.accountId, "accountId");
2873
+ const environment = targetField(value.environment, "environment");
2874
+ const resourceId = targetField(value.resourceId, "resourceId");
2875
+ if (accountId) target.accountId = accountId;
2876
+ if (environment) target.environment = environment;
2877
+ if (resourceId) target.resourceId = resourceId;
2878
+ return Object.freeze(target);
2739
2879
  }
2740
- /**
2741
- * Render a byte count as a human-friendly string (e.g. "256.0 KB").
2742
- */
2743
- function formatBytes(n) {
2744
- if (n < 1024) return `${n} B`;
2745
- if (n < 1024 * 1024) return `${(n / 1024).toFixed(1)} KB`;
2746
- return `${(n / 1024 / 1024).toFixed(2)} MB`;
2880
+ function safeMigrationNames(value, field) {
2881
+ if (!Array.isArray(value) || !value.every((name) => typeof name === "string" && SAFE_MIGRATION_NAME_PATTERN.test(name))) throw new MigrateCommandError(`The migration executor returned an invalid ${field} report.`);
2882
+ return [...value];
2747
2883
  }
2748
- /**
2749
- * Create a gzipped tarball from a directory.
2750
- */
2751
- async function createTarball(sourceDir, outputPath) {
2752
- const { createGzip } = await import("node:zlib");
2753
- await pipeline(packTar(sourceDir), createGzip({ level: 9 }), createWriteStream(outputPath));
2884
+ function safeReport(value, target) {
2885
+ if (!isRecord(value)) throw new MigrateCommandError("The migration executor returned an invalid report.");
2886
+ const reportTarget = immutableTarget(value.target);
2887
+ if (reportTarget.kind !== target.kind || reportTarget.label !== target.label || reportTarget.fingerprint !== target.fingerprint || reportTarget.accountId !== target.accountId || reportTarget.environment !== target.environment || reportTarget.resourceId !== target.resourceId) throw new MigrateCommandError("The migration executor report target does not match the confirmed target.");
2888
+ return {
2889
+ target: { ...reportTarget },
2890
+ knownApplied: safeMigrationNames(value.knownApplied, "knownApplied"),
2891
+ pending: safeMigrationNames(value.pending, "pending"),
2892
+ unknownApplied: safeMigrationNames(value.unknownApplied, "unknownApplied"),
2893
+ executed: safeMigrationNames(value.executed, "executed")
2894
+ };
2754
2895
  }
2755
-
2756
- //#endregion
2757
- //#region src/cli/commands/bundle.ts
2758
- /**
2759
- * emdash plugin bundle
2760
- *
2761
- * Produces a publishable plugin tarball from a plugin source directory.
2762
- *
2763
- * Steps:
2764
- * 1. Resolve plugin entrypoint (finds definePlugin() export)
2765
- * 2. Bundle backend code with tsdown → backend.js (single ES module, tree-shaken)
2766
- * 3. Bundle admin code if present → admin.js
2767
- * 4. Extract manifest from definePlugin() → manifest.json
2768
- * 5. Collect assets (README.md, icon.png, screenshots/)
2769
- * 6. Validate bundle (manifest schema, size limits, no Node.js builtins)
2770
- * 7. Create tarball ({id}-{version}.tar.gz)
2771
- */
2772
- var bundle_exports = /* @__PURE__ */ __exportAll({ bundleCommand: () => bundleCommand });
2773
- const TS_EXT_RE = /\.(tsx?|[mc]?js)$/;
2774
- const SLASH_RE = /\//g;
2775
- const LEADING_AT_RE = /^@/;
2776
- const emdash_SCOPE_RE = /^@emdash-cms\//;
2777
- const bundleCommand = defineCommand({
2896
+ function printTarget(target, write) {
2897
+ write(`Migration target: ${target.kind} ${target.label}`);
2898
+ if (target.accountId) write(`Account: ${target.accountId}`);
2899
+ if (target.environment) write(`Environment: ${target.environment}`);
2900
+ if (target.resourceId) write(`Resource: ${target.resourceId}`);
2901
+ write(`Target fingerprint: ${target.fingerprint}`);
2902
+ }
2903
+ function printNameSet(label, names, write) {
2904
+ write(`${label}: ${names.length === 0 ? "none" : names.join(", ")}`);
2905
+ }
2906
+ function printHumanReport(report, write) {
2907
+ printNameSet("Known applied", report.knownApplied, write);
2908
+ printNameSet("Pending", report.pending, write);
2909
+ printNameSet("Unknown applied", report.unknownApplied, write);
2910
+ printNameSet("Executed", report.executed, write);
2911
+ }
2912
+ function reportExitCode(options, report) {
2913
+ if (!options.check) return MIGRATE_EXIT_CODES.success;
2914
+ if (report.unknownApplied.length > 0) return MIGRATE_EXIT_CODES.unknownApplied;
2915
+ if (report.pending.length > 0) return MIGRATE_EXIT_CODES.pending;
2916
+ return MIGRATE_EXIT_CODES.success;
2917
+ }
2918
+ function createOverrides(options) {
2919
+ return {
2920
+ database: options.database,
2921
+ databaseUrlEnv: options.databaseUrlEnv,
2922
+ d1: options.d1,
2923
+ accountId: options.accountId,
2924
+ wranglerConfig: options.wranglerConfig,
2925
+ wranglerEnv: options.wranglerEnv
2926
+ };
2927
+ }
2928
+ function bounded(operation, timeoutMs) {
2929
+ let timer;
2930
+ const timeout = new Promise((resolveTimeout) => {
2931
+ timer = setTimeout(resolveTimeout, timeoutMs, "timeout");
2932
+ });
2933
+ const completion = operation.then(() => "complete", () => "failed");
2934
+ return Promise.race([completion, timeout]).finally(() => clearTimeout(timer));
2935
+ }
2936
+ async function loadManifest(options, projectRoot, dependencies) {
2937
+ if (options.fromConfig) {
2938
+ dependencies.writeStderr(`Using trusted evaluated Astro configuration${options.config ? `: ${options.config}` : "."}`);
2939
+ return dependencies.buildManifestFromConfig(projectRoot, options.config);
2940
+ }
2941
+ const isDefault = !options.manifest;
2942
+ const path = options.manifest ? isAbsolute(options.manifest) ? options.manifest : resolve(projectRoot, options.manifest) : resolve(projectRoot, ".emdash/migrations.json");
2943
+ return dependencies.readManifest(path, isDefault);
2944
+ }
2945
+ function redactExecutorMessage(message, env) {
2946
+ let redacted = message.replace(/[A-Za-z][A-Za-z0-9+.-]*:\/\/\S+/g, "[REDACTED_URL]").replace(/\b(auth|credential|key|password|secret|signature|token)\s*[=:]\s*\S+/gi, "$1=[REDACTED]");
2947
+ for (const value of Object.values(env)) if (value && value.length >= 4) redacted = redacted.replaceAll(value, "[REDACTED]");
2948
+ return redacted.replaceAll(/[\r\n\t]/g, " ").slice(0, 1e3);
2949
+ }
2950
+ function safeCommandMessage(error, env) {
2951
+ if (error instanceof MigrateCommandError || error instanceof MigrationManifestValidationError) return error.message;
2952
+ if (error instanceof Error && error.message) return redactExecutorMessage(error.message, env);
2953
+ return "Migration command failed. Check the project configuration, target, and credentials.";
2954
+ }
2955
+ async function runMigrateCommand(options, dependencies = defaultDependencies) {
2956
+ let executor;
2957
+ let disposePromise;
2958
+ let interrupted = false;
2959
+ let primaryFailure = false;
2960
+ let exitCode = MIGRATE_EXIT_CODES.error;
2961
+ const interruptedResult = Symbol("interrupted");
2962
+ let resolveInterruption;
2963
+ const interruption = new Promise((resolveInterrupted) => {
2964
+ resolveInterruption = () => resolveInterrupted(interruptedResult);
2965
+ });
2966
+ const dispose = () => {
2967
+ disposePromise ??= executor?.dispose?.() ?? Promise.resolve();
2968
+ return disposePromise;
2969
+ };
2970
+ const removeSignalHandlers = [];
2971
+ const execute = async () => {
2972
+ try {
2973
+ validateOptions(options);
2974
+ const projectRoot = await dependencies.findProjectRoot(dependencies.cwd);
2975
+ const manifest = await validateMigrationManifest(await loadManifest(options, projectRoot, dependencies), await dependencies.loadProjectIdentity(projectRoot));
2976
+ executor = await (await dependencies.loadProjectExecutor(projectRoot, manifest.database.executorEntrypoint))(manifest.database.executorConfig, {
2977
+ projectRoot,
2978
+ env: dependencies.env,
2979
+ overrides: createOverrides(options)
2980
+ });
2981
+ const target = immutableTarget(executor.target);
2982
+ printTarget(target, dependencies.writeStderr);
2983
+ const onSignal = async () => {
2984
+ interrupted = true;
2985
+ await bounded(dispose(), dependencies.cleanupTimeoutMs);
2986
+ resolveInterruption?.();
2987
+ };
2988
+ removeSignalHandlers.push(dependencies.onSignal("SIGINT", onSignal), dependencies.onSignal("SIGTERM", onSignal));
2989
+ const applying = !options.check && !options.status;
2990
+ if (applying && target.kind === "d1") dependencies.writeStderr("Warning: D1 migration jobs must be serialized externally by Cloudflare account and database UUID; this command does not coordinate concurrent applies.");
2991
+ if (applying) {
2992
+ if (options.expectedTargetFingerprint) {
2993
+ if (options.expectedTargetFingerprint !== target.fingerprint) {
2994
+ dependencies.writeStderr("Expected target fingerprint does not match the target.");
2995
+ exitCode = MIGRATE_EXIT_CODES.confirmation;
2996
+ return exitCode;
2997
+ }
2998
+ } else if (!dependencies.interactive || options.json) {
2999
+ dependencies.writeStderr("Noninteractive apply requires --expected-target-fingerprint with the displayed fingerprint.");
3000
+ exitCode = MIGRATE_EXIT_CODES.confirmation;
3001
+ return exitCode;
3002
+ } else if (!await dependencies.confirm(`Apply EmDash migrations to ${target.label}?`)) {
3003
+ dependencies.writeStderr("Migration cancelled.");
3004
+ exitCode = MIGRATE_EXIT_CODES.confirmation;
3005
+ return exitCode;
3006
+ }
3007
+ }
3008
+ const rawReport = await Promise.race([executor.execute({
3009
+ action: applying ? "apply" : "check",
3010
+ i18n: manifest.i18n,
3011
+ artifact: {
3012
+ emdashVersion: manifest.emdashVersion,
3013
+ migrationSetFingerprint: manifest.migrationSet.fingerprint
3014
+ }
3015
+ }), interruption]);
3016
+ if (rawReport === interruptedResult || interrupted) {
3017
+ exitCode = MIGRATE_EXIT_CODES.interrupted;
3018
+ return exitCode;
3019
+ }
3020
+ const report = safeReport(rawReport, target);
3021
+ if (options.json) dependencies.writeStdout(JSON.stringify(report));
3022
+ else printHumanReport(report, dependencies.writeStdout);
3023
+ exitCode = reportExitCode(options, report);
3024
+ return exitCode;
3025
+ } catch (error) {
3026
+ primaryFailure = true;
3027
+ dependencies.writeStderr(safeCommandMessage(error, dependencies.env));
3028
+ exitCode = interrupted ? MIGRATE_EXIT_CODES.interrupted : MIGRATE_EXIT_CODES.error;
3029
+ return exitCode;
3030
+ }
3031
+ };
3032
+ try {
3033
+ exitCode = await execute();
3034
+ } finally {
3035
+ for (const remove of removeSignalHandlers) remove();
3036
+ if (executor) {
3037
+ if (await bounded(dispose(), dependencies.cleanupTimeoutMs) !== "complete" && !primaryFailure && !interrupted) {
3038
+ dependencies.writeStderr("Migration executor cleanup failed.");
3039
+ exitCode = MIGRATE_EXIT_CODES.error;
3040
+ }
3041
+ }
3042
+ }
3043
+ return exitCode;
3044
+ }
3045
+ const migrateCommand = defineCommand({
2778
3046
  meta: {
2779
- name: "bundle",
2780
- description: "Bundle a plugin for marketplace distribution"
3047
+ name: "migrate",
3048
+ description: "Check or apply deployment-managed EmDash migrations"
2781
3049
  },
2782
3050
  args: {
2783
- dir: {
3051
+ manifest: {
2784
3052
  type: "string",
2785
- description: "Plugin directory (default: current directory)",
2786
- default: process.cwd()
3053
+ description: "Migration manifest path"
3054
+ },
3055
+ "from-config": {
3056
+ type: "boolean",
3057
+ description: "Build the manifest from Astro config"
2787
3058
  },
2788
- outDir: {
3059
+ config: {
2789
3060
  type: "string",
2790
- alias: "o",
2791
- description: "Output directory for the tarball (default: ./dist)",
2792
- default: "dist"
3061
+ description: "Astro config path (requires --from-config)"
2793
3062
  },
2794
- validateOnly: {
3063
+ check: {
2795
3064
  type: "boolean",
2796
- description: "Run validation only, skip tarball creation",
2797
- default: false
3065
+ description: "Check for pending or unknown migrations"
3066
+ },
3067
+ status: {
3068
+ type: "boolean",
3069
+ description: "Report all migration status sets"
3070
+ },
3071
+ json: {
3072
+ type: "boolean",
3073
+ description: "Print the stable JSON report"
3074
+ },
3075
+ "expected-target-fingerprint": {
3076
+ type: "string",
3077
+ description: "Required target fingerprint for noninteractive apply"
3078
+ },
3079
+ database: {
3080
+ type: "string",
3081
+ description: "Override the SQLite database path"
3082
+ },
3083
+ "database-url-env": {
3084
+ type: "string",
3085
+ description: "Override the database URL environment-variable name"
3086
+ },
3087
+ d1: {
3088
+ type: "string",
3089
+ description: "Override the D1 database UUID or name"
3090
+ },
3091
+ "account-id": {
3092
+ type: "string",
3093
+ description: "Override the Cloudflare account ID"
3094
+ },
3095
+ "wrangler-config": {
3096
+ type: "string",
3097
+ description: "Override the Wrangler config path"
3098
+ },
3099
+ "wrangler-env": {
3100
+ type: "string",
3101
+ description: "Override the Wrangler environment"
2798
3102
  }
2799
3103
  },
2800
3104
  async run({ args }) {
2801
- const pluginDir = resolve(args.dir);
2802
- const outDir = resolve(pluginDir, args.outDir);
2803
- const validateOnly = args.validateOnly;
2804
- consola.start(validateOnly ? "Validating plugin..." : "Bundling plugin...");
2805
- const pkgPath = join(pluginDir, "package.json");
2806
- if (!await fileExists$1(pkgPath)) {
2807
- consola.error("No package.json found in", pluginDir);
2808
- process.exit(1);
2809
- }
2810
- const pkg = JSON.parse(await readFile(pkgPath, "utf-8"));
2811
- let backendEntry;
2812
- let adminEntry;
2813
- if (pkg.exports) {
2814
- const sandboxExport = pkg.exports["./sandbox"];
2815
- if (typeof sandboxExport === "string") backendEntry = await resolveSourceEntry(pluginDir, sandboxExport);
2816
- else if (sandboxExport && typeof sandboxExport === "object" && "import" in sandboxExport) backendEntry = await resolveSourceEntry(pluginDir, sandboxExport.import);
2817
- const adminExport = pkg.exports["./admin"];
2818
- if (typeof adminExport === "string") adminEntry = await resolveSourceEntry(pluginDir, adminExport);
2819
- else if (adminExport && typeof adminExport === "object" && "import" in adminExport) adminEntry = await resolveSourceEntry(pluginDir, adminExport.import);
2820
- }
2821
- if (!backendEntry) {
2822
- const defaultSandbox = join(pluginDir, "src/sandbox-entry.ts");
2823
- if (await fileExists$1(defaultSandbox)) backendEntry = defaultSandbox;
2824
- }
2825
- let mainEntry;
2826
- if (pkg.exports?.["."] !== void 0) {
2827
- const mainExport = pkg.exports["."];
2828
- if (typeof mainExport === "string") mainEntry = await resolveSourceEntry(pluginDir, mainExport);
2829
- else if (mainExport && typeof mainExport === "object" && "import" in mainExport) mainEntry = await resolveSourceEntry(pluginDir, mainExport.import);
2830
- }
2831
- if (!mainEntry && pkg.main) mainEntry = await resolveSourceEntry(pluginDir, pkg.main);
2832
- if (!mainEntry) {
2833
- const defaultMain = join(pluginDir, "src/index.ts");
2834
- if (await fileExists$1(defaultMain)) mainEntry = defaultMain;
2835
- }
2836
- if (!mainEntry) {
2837
- consola.error("Cannot find plugin entrypoint. Expected src/index.ts or main/exports in package.json");
2838
- process.exit(1);
2839
- }
2840
- consola.info(`Main entry: ${mainEntry}`);
2841
- if (backendEntry) consola.info(`Backend entry: ${backendEntry}`);
2842
- if (adminEntry) consola.info(`Admin entry: ${adminEntry}`);
2843
- consola.start("Extracting plugin manifest...");
2844
- const { build } = await import("tsdown");
2845
- const tmpDir = join(pluginDir, ".emdash-bundle-tmp");
2846
- try {
2847
- await rm(tmpDir, {
2848
- recursive: true,
2849
- force: true
2850
- });
2851
- await mkdir(tmpDir, { recursive: true });
2852
- const mainOutDir = join(tmpDir, "main");
2853
- await build({
2854
- config: false,
2855
- entry: [mainEntry],
2856
- format: "esm",
2857
- outDir: mainOutDir,
2858
- dts: false,
2859
- platform: "node",
2860
- external: ["emdash", emdash_SCOPE_RE]
2861
- });
2862
- const pluginNodeModules = join(pluginDir, "node_modules");
2863
- const tmpNodeModules = join(mainOutDir, "node_modules");
2864
- if (await fileExists$1(pluginNodeModules)) await symlink(pluginNodeModules, tmpNodeModules, "junction");
2865
- const mainOutputPath = await findBuildOutput(mainOutDir, basename(mainEntry).replace(TS_EXT_RE, ""));
2866
- if (!mainOutputPath) {
2867
- consola.error("Failed to build main entry — no output found in", mainOutDir);
2868
- process.exit(1);
2869
- }
2870
- const pluginModule = await import(toFileImportSpecifier(mainOutputPath));
2871
- let resolvedPlugin;
2872
- if (typeof pluginModule.createPlugin === "function") resolvedPlugin = pluginModule.createPlugin();
2873
- else if (typeof pluginModule.default === "function") resolvedPlugin = pluginModule.default();
2874
- else if (typeof pluginModule.default === "object" && pluginModule.default !== null) {
2875
- const defaultExport = pluginModule.default;
2876
- if ("id" in defaultExport && "version" in defaultExport) resolvedPlugin = defaultExport;
2877
- }
2878
- if (!resolvedPlugin) for (const [key, value] of Object.entries(pluginModule)) {
2879
- if (key === "default" || typeof value !== "function") continue;
2880
- try {
2881
- const result = value();
2882
- if (result && typeof result === "object" && "id" in result && "version" in result) {
2883
- resolvedPlugin = {
2884
- id: result.id,
2885
- version: result.version,
2886
- capabilities: result.capabilities ?? [],
2887
- allowedHosts: result.allowedHosts ?? [],
2888
- storage: result.storage ?? {},
2889
- hooks: {},
2890
- routes: {},
2891
- admin: {
2892
- pages: result.adminPages,
2893
- widgets: result.adminWidgets
2894
- }
2895
- };
2896
- if (backendEntry) {
2897
- const backendProbeDir = join(tmpDir, "backend-probe");
2898
- const probeShimDir = join(tmpDir, "probe-shims");
2899
- await mkdir(probeShimDir, { recursive: true });
2900
- await writeFile(join(probeShimDir, "emdash.mjs"), "export const definePlugin = (d) => d;\n");
2901
- await build({
2902
- config: false,
2903
- entry: [backendEntry],
2904
- format: "esm",
2905
- outDir: backendProbeDir,
2906
- dts: false,
2907
- platform: "neutral",
2908
- external: [],
2909
- alias: { emdash: join(probeShimDir, "emdash.mjs") },
2910
- treeshake: true
2911
- });
2912
- const backendProbePath = await findBuildOutput(backendProbeDir, basename(backendEntry).replace(TS_EXT_RE, ""));
2913
- if (backendProbePath) {
2914
- const standardDef = (await import(toFileImportSpecifier(backendProbePath))).default ?? {};
2915
- const hooks = standardDef.hooks;
2916
- const routes = standardDef.routes;
2917
- if (hooks) for (const hookName of Object.keys(hooks)) {
2918
- const hookEntry = hooks[hookName];
2919
- const isConfig = typeof hookEntry === "object" && hookEntry !== null && "handler" in hookEntry;
2920
- const config = isConfig ? hookEntry : {};
2921
- resolvedPlugin.hooks[hookName] = {
2922
- handler: isConfig ? hookEntry.handler : hookEntry,
2923
- priority: config.priority ?? 100,
2924
- timeout: config.timeout ?? 5e3,
2925
- dependencies: config.dependencies ?? [],
2926
- errorPolicy: config.errorPolicy ?? "abort",
2927
- exclusive: config.exclusive ?? false,
2928
- pluginId: result.id
2929
- };
2930
- }
2931
- if (routes) for (const [name, route] of Object.entries(routes)) {
2932
- const routeObj = route;
2933
- resolvedPlugin.routes[name] = {
2934
- handler: routeObj.handler,
2935
- public: routeObj.public,
2936
- cacheControl: routeObj.cacheControl
2937
- };
2938
- }
2939
- }
2940
- }
2941
- break;
2942
- }
2943
- } catch {}
2944
- }
2945
- if (!resolvedPlugin?.id || !resolvedPlugin?.version) {
2946
- consola.error("Could not extract plugin definition. Expected one of:\n - createPlugin() export (native format)\n - Descriptor factory function returning { id, version, ... } (standard format)");
2947
- process.exit(1);
2948
- }
2949
- const manifest = extractManifest(resolvedPlugin);
2950
- if (resolvedPlugin.admin?.entry) {
2951
- consola.error("Plugin declares adminEntry — React admin components require native/trusted mode. Use Block Kit for sandboxed admin pages, or remove adminEntry.");
2952
- process.exit(1);
2953
- }
2954
- if (resolvedPlugin.admin?.portableTextBlocks && resolvedPlugin.admin.portableTextBlocks.length > 0) {
2955
- consola.error("Plugin declares portableTextBlocks — these require native/trusted mode and cannot be bundled for the marketplace.");
2956
- process.exit(1);
2957
- }
2958
- consola.success(`Plugin: ${manifest.id}@${manifest.version}`);
2959
- consola.info(` Capabilities: ${manifest.capabilities.length > 0 ? manifest.capabilities.join(", ") : "(none)"}`);
2960
- consola.info(` Hooks: ${manifest.hooks.length > 0 ? manifest.hooks.map((h) => typeof h === "string" ? h : h.name).join(", ") : "(none)"}`);
2961
- consola.info(` Routes: ${manifest.routes.length > 0 ? manifest.routes.map((r) => typeof r === "string" ? r : r.name).join(", ") : "(none)"}`);
2962
- const bundleDir = join(tmpDir, "bundle");
2963
- await mkdir(bundleDir, { recursive: true });
2964
- if (backendEntry) {
2965
- consola.start("Bundling backend...");
2966
- const shimDir = join(tmpDir, "shims");
2967
- await mkdir(shimDir, { recursive: true });
2968
- await writeFile(join(shimDir, "emdash.mjs"), "export const definePlugin = (d) => d;\n");
2969
- await build({
2970
- config: false,
2971
- entry: [backendEntry],
2972
- format: "esm",
2973
- outDir: join(tmpDir, "backend"),
2974
- dts: false,
2975
- platform: "neutral",
2976
- external: [],
2977
- alias: { emdash: join(shimDir, "emdash.mjs") },
2978
- minify: true,
2979
- treeshake: true
2980
- });
2981
- const backendBaseName = basename(backendEntry).replace(TS_EXT_RE, "");
2982
- const backendOutputPath = await findBuildOutput(join(tmpDir, "backend"), backendBaseName);
2983
- if (backendOutputPath) {
2984
- await copyFile(backendOutputPath, join(bundleDir, "backend.js"));
2985
- consola.success("Built backend.js");
2986
- } else {
2987
- consola.error("Backend build produced no output");
2988
- process.exit(1);
2989
- }
2990
- } else {
2991
- consola.warn("No sandbox entry found — bundle will have no backend.js");
2992
- consola.warn(" Add a \"sandbox-entry.ts\" in src/ or a \"./sandbox\" export in package.json");
2993
- }
2994
- if (adminEntry) {
2995
- consola.start("Bundling admin...");
2996
- await build({
2997
- config: false,
2998
- entry: [adminEntry],
2999
- format: "esm",
3000
- outDir: join(tmpDir, "admin"),
3001
- dts: false,
3002
- platform: "neutral",
3003
- external: [],
3004
- minify: true,
3005
- treeshake: true
3006
- });
3007
- const adminBaseName = basename(adminEntry).replace(TS_EXT_RE, "");
3008
- const adminOutputPath = await findBuildOutput(join(tmpDir, "admin"), adminBaseName);
3009
- if (adminOutputPath) {
3010
- await copyFile(adminOutputPath, join(bundleDir, "admin.js"));
3011
- consola.success("Built admin.js");
3012
- }
3013
- }
3014
- await writeFile(join(bundleDir, "manifest.json"), JSON.stringify(manifest, null, 2));
3015
- consola.start("Collecting assets...");
3016
- const readmePath = join(pluginDir, "README.md");
3017
- if (await fileExists$1(readmePath)) {
3018
- await copyFile(readmePath, join(bundleDir, "README.md"));
3019
- consola.success("Included README.md");
3020
- }
3021
- const iconPath = join(pluginDir, "icon.png");
3022
- if (await fileExists$1(iconPath)) {
3023
- const dims = readImageDimensions(await readFile(iconPath));
3024
- if (!dims) consola.warn("icon.png is not a valid PNG — skipping");
3025
- else if (dims[0] !== ICON_SIZE || dims[1] !== ICON_SIZE) {
3026
- consola.warn(`icon.png is ${dims[0]}x${dims[1]}, expected ${ICON_SIZE}x${ICON_SIZE} — including anyway`);
3027
- await copyFile(iconPath, join(bundleDir, "icon.png"));
3028
- } else {
3029
- await copyFile(iconPath, join(bundleDir, "icon.png"));
3030
- consola.success("Included icon.png");
3031
- }
3032
- }
3033
- const screenshotsDir = join(pluginDir, "screenshots");
3034
- if (await fileExists$1(screenshotsDir)) {
3035
- const screenshotFiles = (await readdir(screenshotsDir)).filter((f) => {
3036
- const ext = extname(f).toLowerCase();
3037
- return ext === ".png" || ext === ".jpg" || ext === ".jpeg";
3038
- }).toSorted().slice(0, MAX_SCREENSHOTS);
3039
- if (screenshotFiles.length > 0) {
3040
- await mkdir(join(bundleDir, "screenshots"), { recursive: true });
3041
- for (const file of screenshotFiles) {
3042
- const filePath = join(screenshotsDir, file);
3043
- const dims = readImageDimensions(await readFile(filePath));
3044
- if (!dims) {
3045
- consola.warn(`screenshots/${file} — cannot read dimensions, skipping`);
3046
- continue;
3047
- }
3048
- if (dims[0] > MAX_SCREENSHOT_WIDTH || dims[1] > MAX_SCREENSHOT_HEIGHT) consola.warn(`screenshots/${file} is ${dims[0]}x${dims[1]}, max ${MAX_SCREENSHOT_WIDTH}x${MAX_SCREENSHOT_HEIGHT} — including anyway`);
3049
- await copyFile(filePath, join(bundleDir, "screenshots", file));
3050
- }
3051
- consola.success(`Included ${screenshotFiles.length} screenshot(s)`);
3052
- }
3053
- }
3054
- consola.start("Validating bundle...");
3055
- let hasErrors = false;
3056
- if (pkg.exports) for (const issue of findSourceExports(pkg.exports)) {
3057
- consola.error(`Export "${issue.exportPath}" points to source (${issue.resolvedPath}). Package exports must point to built files (e.g. dist/*.mjs). Add a build step and update the exports map.`);
3058
- hasErrors = true;
3059
- }
3060
- const backendPath = join(bundleDir, "backend.js");
3061
- if (await fileExists$1(backendPath)) {
3062
- const builtins = findNodeBuiltinImports(await readFile(backendPath, "utf-8"));
3063
- if (builtins.length > 0) {
3064
- consola.error(`backend.js imports Node.js built-in modules: ${builtins.join(", ")}`);
3065
- consola.error("Sandboxed plugins cannot use Node.js APIs");
3066
- hasErrors = true;
3067
- }
3068
- }
3069
- const declaresUnrestricted = manifest.capabilities.includes("network:request:unrestricted") || manifest.capabilities.includes("network:fetch:any");
3070
- const declaresHostRestricted = manifest.capabilities.includes("network:request") || manifest.capabilities.includes("network:fetch");
3071
- if (declaresUnrestricted) consola.warn("Plugin declares unrestricted network access (network:request:unrestricted) — it can make requests to any host");
3072
- else if (declaresHostRestricted && manifest.allowedHosts.length === 0) consola.warn("Plugin declares network:request capability but no allowedHosts — all requests will be blocked");
3073
- const deprecatedCaps = manifest.capabilities.filter(isDeprecatedCapability);
3074
- if (deprecatedCaps.length > 0) {
3075
- consola.warn("Plugin uses deprecated capability names. Rename them before publishing:");
3076
- for (const cap of deprecatedCaps) {
3077
- const replacement = CAPABILITY_RENAMES[cap];
3078
- consola.warn(` ${cap} → ${replacement}`);
3079
- }
3080
- }
3081
- if (resolvedPlugin.admin?.portableTextBlocks && resolvedPlugin.admin.portableTextBlocks.length > 0) consola.warn("Plugin declares portableTextBlocks — these require trusted mode and will be ignored in sandboxed plugins");
3082
- if (resolvedPlugin.admin?.entry) consola.warn("Plugin declares admin.entry — custom React components require trusted mode. Use Block Kit for sandboxed admin pages");
3083
- if (resolvedPlugin.hooks["page:fragments"]) consola.warn("Plugin declares page:fragments hook — this is trusted-only and will not work in sandboxed mode");
3084
- const hasAdminPages = (manifest.admin?.pages?.length ?? 0) > 0;
3085
- const hasAdminWidgets = (manifest.admin?.widgets?.length ?? 0) > 0;
3086
- if (hasAdminPages || hasAdminWidgets) {
3087
- if (!manifest.routes.map((r) => typeof r === "string" ? r : r.name).includes("admin")) {
3088
- consola.error(`Plugin declares ${hasAdminPages ? "adminPages" : ""}${hasAdminPages && hasAdminWidgets ? " and " : ""}${hasAdminWidgets ? "adminWidgets" : ""} but the sandbox entry has no "admin" route. Add an admin route handler to serve Block Kit pages.`);
3089
- hasErrors = true;
3090
- }
3091
- }
3092
- const bundleEntries = await collectBundleEntries(bundleDir);
3093
- const sizeViolations = validateBundleSize(bundleEntries);
3094
- if (sizeViolations.length > 0) {
3095
- for (const v of sizeViolations) consola.error(v);
3096
- hasErrors = true;
3097
- } else consola.info(`Bundle size: ${formatBytes(totalBundleBytes(bundleEntries))} across ${bundleEntries.length} file${bundleEntries.length === 1 ? "" : "s"}`);
3098
- if (hasErrors) {
3099
- consola.error("Bundle validation failed");
3100
- process.exit(1);
3101
- }
3102
- consola.success("Validation passed");
3103
- if (validateOnly) return;
3104
- await mkdir(outDir, { recursive: true });
3105
- const tarballName = `${manifest.id.replace(SLASH_RE, "-").replace(LEADING_AT_RE, "")}-${manifest.version}.tar.gz`;
3106
- const tarballPath = join(outDir, tarballName);
3107
- consola.start("Creating tarball...");
3108
- await createTarball(bundleDir, tarballPath);
3109
- const tarballSizeKB = ((await stat(tarballPath)).size / 1024).toFixed(1);
3110
- const tarballBuf = await readFile(tarballPath);
3111
- const checksum = createHash("sha256").update(tarballBuf).digest("hex");
3112
- consola.success(`Created ${tarballName} (${tarballSizeKB}KB)`);
3113
- consola.info(` SHA-256: ${checksum}`);
3114
- consola.info(` Path: ${tarballPath}`);
3115
- } finally {
3116
- if (tmpDir.endsWith(".emdash-bundle-tmp")) await rm(tmpDir, {
3117
- recursive: true,
3118
- force: true
3119
- });
3120
- }
3105
+ process.exitCode = await runMigrateCommand({
3106
+ manifest: args.manifest,
3107
+ fromConfig: args["from-config"],
3108
+ config: args.config,
3109
+ check: args.check,
3110
+ status: args.status,
3111
+ json: args.json,
3112
+ expectedTargetFingerprint: args["expected-target-fingerprint"],
3113
+ database: args.database,
3114
+ databaseUrlEnv: args["database-url-env"],
3115
+ d1: args.d1,
3116
+ accountId: args["account-id"],
3117
+ wranglerConfig: args["wrangler-config"],
3118
+ wranglerEnv: args["wrangler-env"]
3119
+ });
3121
3120
  }
3122
3121
  });
3123
3122
 
@@ -3181,7 +3180,7 @@ const pluginInitCommand = defineCommand({
3181
3180
  process.exit(1);
3182
3181
  }
3183
3182
  const srcDir = join(targetDir, "src");
3184
- if (await fileExists$1(join(targetDir, "package.json"))) {
3183
+ if (await fileExists$4(join(targetDir, "package.json"))) {
3185
3184
  consola.error(`package.json already exists in ${targetDir}`);
3186
3185
  process.exit(1);
3187
3186
  }
@@ -3663,7 +3662,7 @@ const publishCommand = defineCommand({
3663
3662
  const pluginDir = resolve(args.dir);
3664
3663
  try {
3665
3664
  const { runCommand } = await import("citty");
3666
- const { bundleCommand } = await Promise.resolve().then(() => bundle_exports);
3665
+ const { bundleCommand } = await import("../bundle-vn56sLos.mjs").then((n) => n.n);
3667
3666
  await runCommand(bundleCommand, { rawArgs: ["--dir", pluginDir] });
3668
3667
  } catch {
3669
3668
  consola.error("Build failed");
@@ -4647,28 +4646,6 @@ const typesCommand = defineCommand({
4647
4646
 
4648
4647
  //#endregion
4649
4648
  //#region src/cli/index.ts
4650
- /**
4651
- * EmDash CLI
4652
- *
4653
- * Built with citty + clack (same stack as Nuxt CLI)
4654
- *
4655
- * Commands:
4656
- * - init: Bootstrap database from template config, or interactive setup
4657
- * - types: Generate TypeScript types from schema
4658
- * - dev: [DEPRECATED, hidden] Run dev server with a local SQLite database
4659
- * - seed: Apply a seed file to the database
4660
- * - export-seed: Export database schema and content as a seed file
4661
- * - secrets: Generate and inspect EmDash secrets (encryption keys, etc.)
4662
- * - auth: [DEPRECATED] Generate auth secret (use `secrets` instead)
4663
- * - login/logout/whoami: Session management
4664
- * - content: Create, read, update, delete content
4665
- * - schema: Manage collections and fields
4666
- * - media: Upload and manage media
4667
- * - search: Full-text search
4668
- * - taxonomy: Manage taxonomies and terms
4669
- * - menu: Manage navigation menus
4670
- * - plugin: Plugin management (init, bundle, validate, publish, login, logout)
4671
- */
4672
4649
  runMain(defineCommand({
4673
4650
  meta: {
4674
4651
  name: "emdash",
@@ -4681,6 +4658,7 @@ runMain(defineCommand({
4681
4658
  dev: devCommand,
4682
4659
  doctor: doctorCommand,
4683
4660
  seed: seedCommand,
4661
+ migrate: migrateCommand,
4684
4662
  "export-seed": exportSeedCommand,
4685
4663
  secrets: secretsCommand,
4686
4664
  auth: authCommand,