emdash 1.1.0 → 1.3.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 (1571) hide show
  1. package/dist/action-token-SK8zyN7w.mjs +26 -0
  2. package/dist/action-token-SK8zyN7w.mjs.map +1 -0
  3. package/dist/activation-Dim4YMM7.mjs +387 -0
  4. package/dist/activation-Dim4YMM7.mjs.map +1 -0
  5. package/dist/adapters-F_xorvWv.d.mts +173 -0
  6. package/dist/adapters-F_xorvWv.d.mts.map +1 -0
  7. package/dist/allowed-origins-CEug-p0t.mjs +116 -0
  8. package/dist/allowed-origins-CEug-p0t.mjs.map +1 -0
  9. package/dist/api/route-utils.d.mts +4 -4
  10. package/dist/api/route-utils.d.mts.map +1 -1
  11. package/dist/api/route-utils.mjs +48 -46
  12. package/dist/api/route-utils.mjs.map +1 -1
  13. package/dist/api/schemas/index.d.mts +2 -2
  14. package/dist/api/schemas/index.mjs +10 -10
  15. package/dist/api-D-7BNHoz.mjs +5025 -0
  16. package/dist/api-D-7BNHoz.mjs.map +1 -0
  17. package/dist/api-tokens-Bx38ZCQp.mjs +173 -0
  18. package/dist/api-tokens-Bx38ZCQp.mjs.map +1 -0
  19. package/dist/apply-T7ATgzCh.mjs +1702 -0
  20. package/dist/apply-T7ATgzCh.mjs.map +1 -0
  21. package/dist/approvals-D-m6wvGl.mjs +460 -0
  22. package/dist/approvals-D-m6wvGl.mjs.map +1 -0
  23. package/dist/artifact-fetch-DIh7iyOV.mjs +659 -0
  24. package/dist/artifact-fetch-DIh7iyOV.mjs.map +1 -0
  25. package/dist/artifacts-htGyfCSt.mjs +307 -0
  26. package/dist/artifacts-htGyfCSt.mjs.map +1 -0
  27. package/dist/astro/image-endpoint.d.mts.map +1 -1
  28. package/dist/astro/image-endpoint.mjs +26 -6
  29. package/dist/astro/image-endpoint.mjs.map +1 -1
  30. package/dist/astro/index.d.mts +14 -14
  31. package/dist/astro/index.d.mts.map +1 -1
  32. package/dist/astro/index.mjs +324 -23
  33. package/dist/astro/index.mjs.map +1 -1
  34. package/dist/astro/middleware/auth.d.mts +12 -12
  35. package/dist/astro/middleware/auth.d.mts.map +1 -1
  36. package/dist/astro/middleware/auth.mjs +18 -13
  37. package/dist/astro/middleware/auth.mjs.map +1 -1
  38. package/dist/astro/middleware/media-usage-write-fence.mjs +5 -5
  39. package/dist/astro/middleware/redirect.d.mts.map +1 -1
  40. package/dist/astro/middleware/redirect.mjs +81 -46
  41. package/dist/astro/middleware/redirect.mjs.map +1 -1
  42. package/dist/astro/middleware/request-context.d.mts.map +1 -1
  43. package/dist/astro/middleware/request-context.mjs +117 -56
  44. package/dist/astro/middleware/request-context.mjs.map +1 -1
  45. package/dist/astro/middleware/setup.mjs +1 -1
  46. package/dist/astro/middleware.d.mts +12 -12
  47. package/dist/astro/middleware.d.mts.map +1 -1
  48. package/dist/astro/middleware.mjs +145 -415
  49. package/dist/astro/middleware.mjs.map +1 -1
  50. package/dist/astro/routes/api/admin/allowed-domains/_domain_.mjs +14 -14
  51. package/dist/astro/routes/api/admin/allowed-domains/index.mjs +14 -14
  52. package/dist/astro/routes/api/admin/api-tokens/_id_.mjs +7 -6
  53. package/dist/astro/routes/api/admin/api-tokens/_id_.mjs.map +1 -1
  54. package/dist/astro/routes/api/admin/api-tokens/index.mjs +8 -7
  55. package/dist/astro/routes/api/admin/api-tokens/index.mjs.map +1 -1
  56. package/dist/astro/routes/api/admin/byline-fields/_slug_/usage.mjs +6 -6
  57. package/dist/astro/routes/api/admin/byline-fields/_slug_.mjs +16 -16
  58. package/dist/astro/routes/api/admin/byline-fields/index.mjs +16 -16
  59. package/dist/astro/routes/api/admin/byline-fields/reorder.mjs +16 -16
  60. package/dist/astro/routes/api/admin/bylines/_id_/index.mjs +22 -21
  61. package/dist/astro/routes/api/admin/bylines/_id_/index.mjs.map +1 -1
  62. package/dist/astro/routes/api/admin/bylines/_id_/translations.mjs +22 -21
  63. package/dist/astro/routes/api/admin/bylines/_id_/translations.mjs.map +1 -1
  64. package/dist/astro/routes/api/admin/bylines/index.mjs +22 -21
  65. package/dist/astro/routes/api/admin/bylines/index.mjs.map +1 -1
  66. package/dist/astro/routes/api/admin/comments/_id_/status.mjs +18 -18
  67. package/dist/astro/routes/api/admin/comments/_id_.mjs +7 -7
  68. package/dist/astro/routes/api/admin/comments/bulk.mjs +17 -17
  69. package/dist/astro/routes/api/admin/comments/counts.mjs +7 -7
  70. package/dist/astro/routes/api/admin/comments/index.mjs +17 -17
  71. package/dist/astro/routes/api/admin/core-update.mjs +7 -7
  72. package/dist/astro/routes/api/admin/hooks/exclusive/_hookName_.mjs +6 -6
  73. package/dist/astro/routes/api/admin/hooks/exclusive/index.mjs +5 -5
  74. package/dist/astro/routes/api/admin/media-usage/activation.mjs +20 -20
  75. package/dist/astro/routes/api/admin/media-usage/collection-deletions/index.mjs +21 -21
  76. package/dist/astro/routes/api/admin/media-usage/collection-deletions/retry.mjs +21 -21
  77. package/dist/astro/routes/api/admin/media-usage/progress.mjs +23 -22
  78. package/dist/astro/routes/api/admin/media-usage/progress.mjs.map +1 -1
  79. package/dist/astro/routes/api/admin/media-usage/repair.mjs +29 -28
  80. package/dist/astro/routes/api/admin/media-usage/repair.mjs.map +1 -1
  81. package/dist/astro/routes/api/admin/media-usage/work/index.mjs +21 -21
  82. package/dist/astro/routes/api/admin/media-usage/work/retry.mjs +21 -21
  83. package/dist/astro/routes/api/admin/oauth-clients/_id_.mjs +6 -6
  84. package/dist/astro/routes/api/admin/oauth-clients/index.mjs +6 -6
  85. package/dist/astro/routes/api/admin/plugins/_id_/disable.mjs +8 -8
  86. package/dist/astro/routes/api/admin/plugins/_id_/enable.mjs +8 -8
  87. package/dist/astro/routes/api/admin/plugins/_id_/index.mjs +72 -70
  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 +7 -7
  90. package/dist/astro/routes/api/admin/plugins/_id_/settings.mjs +71 -69
  91. package/dist/astro/routes/api/admin/plugins/_id_/settings.mjs.map +1 -1
  92. package/dist/astro/routes/api/admin/plugins/_id_/uninstall.mjs +71 -70
  93. package/dist/astro/routes/api/admin/plugins/_id_/uninstall.mjs.map +1 -1
  94. package/dist/astro/routes/api/admin/plugins/_id_/update.mjs +80 -79
  95. package/dist/astro/routes/api/admin/plugins/_id_/update.mjs.map +1 -1
  96. package/dist/astro/routes/api/admin/plugins/index.mjs +72 -70
  97. package/dist/astro/routes/api/admin/plugins/index.mjs.map +1 -1
  98. package/dist/astro/routes/api/admin/plugins/marketplace/_id_/icon.mjs +7 -7
  99. package/dist/astro/routes/api/admin/plugins/marketplace/_id_/index.mjs +71 -69
  100. package/dist/astro/routes/api/admin/plugins/marketplace/_id_/index.mjs.map +1 -1
  101. package/dist/astro/routes/api/admin/plugins/marketplace/_id_/install.mjs +79 -78
  102. package/dist/astro/routes/api/admin/plugins/marketplace/_id_/install.mjs.map +1 -1
  103. package/dist/astro/routes/api/admin/plugins/marketplace/index.mjs +71 -69
  104. package/dist/astro/routes/api/admin/plugins/marketplace/index.mjs.map +1 -1
  105. package/dist/astro/routes/api/admin/plugins/registry/_id_/uninstall.mjs +71 -70
  106. package/dist/astro/routes/api/admin/plugins/registry/_id_/uninstall.mjs.map +1 -1
  107. package/dist/astro/routes/api/admin/plugins/registry/_id_/update.mjs +81 -80
  108. package/dist/astro/routes/api/admin/plugins/registry/_id_/update.mjs.map +1 -1
  109. package/dist/astro/routes/api/admin/plugins/registry/artifact.mjs +10 -10
  110. package/dist/astro/routes/api/admin/plugins/registry/artifact.mjs.map +1 -1
  111. package/dist/astro/routes/api/admin/plugins/registry/install.mjs +73 -72
  112. package/dist/astro/routes/api/admin/plugins/registry/install.mjs.map +1 -1
  113. package/dist/astro/routes/api/admin/plugins/registry/publisher-handle.mjs +7 -7
  114. package/dist/astro/routes/api/admin/plugins/registry/verify.mjs +72 -70
  115. package/dist/astro/routes/api/admin/plugins/registry/verify.mjs.map +1 -1
  116. package/dist/astro/routes/api/admin/plugins/updates.mjs +71 -69
  117. package/dist/astro/routes/api/admin/plugins/updates.mjs.map +1 -1
  118. package/dist/astro/routes/api/admin/scheduled-policy-rejections/_collection_/_id_.mjs +5 -5
  119. package/dist/astro/routes/api/admin/themes/marketplace/_id_/index.mjs +71 -69
  120. package/dist/astro/routes/api/admin/themes/marketplace/_id_/index.mjs.map +1 -1
  121. package/dist/astro/routes/api/admin/themes/marketplace/_id_/thumbnail.mjs +7 -7
  122. package/dist/astro/routes/api/admin/themes/marketplace/index.mjs +71 -69
  123. package/dist/astro/routes/api/admin/themes/marketplace/index.mjs.map +1 -1
  124. package/dist/astro/routes/api/admin/transfer/_...path_.mjs +4 -4
  125. package/dist/astro/routes/api/admin/transfer/approvals/_id_/approve.mjs +38 -37
  126. package/dist/astro/routes/api/admin/transfer/approvals/_id_/approve.mjs.map +1 -1
  127. package/dist/astro/routes/api/admin/transfer/approvals/_id_/deny.mjs +38 -37
  128. package/dist/astro/routes/api/admin/transfer/approvals/_id_/deny.mjs.map +1 -1
  129. package/dist/astro/routes/api/admin/transfer/approvals/index.mjs +40 -39
  130. package/dist/astro/routes/api/admin/transfer/approvals/index.mjs.map +1 -1
  131. package/dist/astro/routes/api/admin/transfer/capabilities.mjs +40 -39
  132. package/dist/astro/routes/api/admin/transfer/capabilities.mjs.map +1 -1
  133. package/dist/astro/routes/api/admin/transfer/exports/_id_/advance.mjs +40 -39
  134. package/dist/astro/routes/api/admin/transfer/exports/_id_/advance.mjs.map +1 -1
  135. package/dist/astro/routes/api/admin/transfer/exports/_id_/archive.mjs +41 -40
  136. package/dist/astro/routes/api/admin/transfer/exports/_id_/archive.mjs.map +1 -1
  137. package/dist/astro/routes/api/admin/transfer/exports/_id_/files/_...path_.mjs +41 -40
  138. package/dist/astro/routes/api/admin/transfer/exports/_id_/files/_...path_.mjs.map +1 -1
  139. package/dist/astro/routes/api/admin/transfer/exports/_id_/index.mjs +40 -39
  140. package/dist/astro/routes/api/admin/transfer/exports/_id_/index.mjs.map +1 -1
  141. package/dist/astro/routes/api/admin/transfer/exports/_id_/manifest.mjs +41 -40
  142. package/dist/astro/routes/api/admin/transfer/exports/_id_/manifest.mjs.map +1 -1
  143. package/dist/astro/routes/api/admin/transfer/exports/index.mjs +42 -41
  144. package/dist/astro/routes/api/admin/transfer/exports/index.mjs.map +1 -1
  145. package/dist/astro/routes/api/admin/transfer/imports/_id_/abandon.mjs +40 -39
  146. package/dist/astro/routes/api/admin/transfer/imports/_id_/abandon.mjs.map +1 -1
  147. package/dist/astro/routes/api/admin/transfer/imports/_id_/advance.mjs +40 -39
  148. package/dist/astro/routes/api/admin/transfer/imports/_id_/advance.mjs.map +1 -1
  149. package/dist/astro/routes/api/admin/transfer/imports/_id_/analyze.mjs +42 -41
  150. package/dist/astro/routes/api/admin/transfer/imports/_id_/analyze.mjs.map +1 -1
  151. package/dist/astro/routes/api/admin/transfer/imports/_id_/cancel.mjs +40 -39
  152. package/dist/astro/routes/api/admin/transfer/imports/_id_/cancel.mjs.map +1 -1
  153. package/dist/astro/routes/api/admin/transfer/imports/_id_/execute.mjs +42 -41
  154. package/dist/astro/routes/api/admin/transfer/imports/_id_/execute.mjs.map +1 -1
  155. package/dist/astro/routes/api/admin/transfer/imports/_id_/files/_...path_.mjs +40 -39
  156. package/dist/astro/routes/api/admin/transfer/imports/_id_/files/_...path_.mjs.map +1 -1
  157. package/dist/astro/routes/api/admin/transfer/imports/_id_/index.mjs +40 -39
  158. package/dist/astro/routes/api/admin/transfer/imports/_id_/index.mjs.map +1 -1
  159. package/dist/astro/routes/api/admin/transfer/imports/_id_/missing.mjs +42 -41
  160. package/dist/astro/routes/api/admin/transfer/imports/_id_/missing.mjs.map +1 -1
  161. package/dist/astro/routes/api/admin/transfer/imports/_id_/plan.mjs +40 -39
  162. package/dist/astro/routes/api/admin/transfer/imports/_id_/plan.mjs.map +1 -1
  163. package/dist/astro/routes/api/admin/transfer/imports/_id_/receipt.mjs +40 -39
  164. package/dist/astro/routes/api/admin/transfer/imports/_id_/receipt.mjs.map +1 -1
  165. package/dist/astro/routes/api/admin/transfer/imports/index.mjs +42 -41
  166. package/dist/astro/routes/api/admin/transfer/imports/index.mjs.map +1 -1
  167. package/dist/astro/routes/api/admin/users/_id_/disable.mjs +4 -4
  168. package/dist/astro/routes/api/admin/users/_id_/enable.mjs +4 -4
  169. package/dist/astro/routes/api/admin/users/_id_/index.mjs +14 -14
  170. package/dist/astro/routes/api/admin/users/_id_/send-recovery.mjs +6 -6
  171. package/dist/astro/routes/api/admin/users/index.mjs +14 -14
  172. package/dist/astro/routes/api/auth/dev-bypass.mjs +6 -6
  173. package/dist/astro/routes/api/auth/handover.d.mts +8 -0
  174. package/dist/astro/routes/api/auth/handover.d.mts.map +1 -0
  175. package/dist/astro/routes/api/auth/handover.mjs +49 -0
  176. package/dist/astro/routes/api/auth/handover.mjs.map +1 -0
  177. package/dist/astro/routes/api/auth/invite/accept.mjs +4 -4
  178. package/dist/astro/routes/api/auth/invite/complete.mjs +19 -19
  179. package/dist/astro/routes/api/auth/invite/index.mjs +16 -16
  180. package/dist/astro/routes/api/auth/invite/register-options.mjs +17 -17
  181. package/dist/astro/routes/api/auth/logout.mjs +5 -5
  182. package/dist/astro/routes/api/auth/magic-link/send.mjs +19 -18
  183. package/dist/astro/routes/api/auth/magic-link/send.mjs.map +1 -1
  184. package/dist/astro/routes/api/auth/magic-link/verify.d.mts.map +1 -1
  185. package/dist/astro/routes/api/auth/magic-link/verify.mjs +23 -17
  186. package/dist/astro/routes/api/auth/magic-link/verify.mjs.map +1 -1
  187. package/dist/astro/routes/api/auth/me.mjs +15 -15
  188. package/dist/astro/routes/api/auth/mode.mjs +5 -5
  189. package/dist/astro/routes/api/auth/oauth/_provider_/callback.mjs +8 -8
  190. package/dist/astro/routes/api/auth/oauth/_provider_.mjs +2 -2
  191. package/dist/astro/routes/api/auth/passkey/_id_.mjs +14 -14
  192. package/dist/astro/routes/api/auth/passkey/index.mjs +4 -4
  193. package/dist/astro/routes/api/auth/passkey/options.d.mts.map +1 -1
  194. package/dist/astro/routes/api/auth/passkey/options.mjs +27 -20
  195. package/dist/astro/routes/api/auth/passkey/options.mjs.map +1 -1
  196. package/dist/astro/routes/api/auth/passkey/register/options.mjs +17 -17
  197. package/dist/astro/routes/api/auth/passkey/register/verify.mjs +18 -18
  198. package/dist/astro/routes/api/auth/passkey/verify.mjs +19 -19
  199. package/dist/astro/routes/api/auth/signup/complete.mjs +19 -19
  200. package/dist/astro/routes/api/auth/signup/request.mjs +18 -17
  201. package/dist/astro/routes/api/auth/signup/request.mjs.map +1 -1
  202. package/dist/astro/routes/api/auth/signup/verify.mjs +4 -4
  203. package/dist/astro/routes/api/calendar.mjs +15 -15
  204. package/dist/astro/routes/api/comments/_collection_/_contentId_/index.mjs +12 -12
  205. package/dist/astro/routes/api/comments/_collection_/_contentId_/reactions.mjs +18 -18
  206. package/dist/astro/routes/api/content/_collection_/_id_/compare.mjs +5 -5
  207. package/dist/astro/routes/api/content/_collection_/_id_/discard-draft.d.mts.map +1 -1
  208. package/dist/astro/routes/api/content/_collection_/_id_/discard-draft.mjs +18 -17
  209. package/dist/astro/routes/api/content/_collection_/_id_/discard-draft.mjs.map +1 -1
  210. package/dist/astro/routes/api/content/_collection_/_id_/duplicate.mjs +7 -10
  211. package/dist/astro/routes/api/content/_collection_/_id_/duplicate.mjs.map +1 -1
  212. package/dist/astro/routes/api/content/_collection_/_id_/lock.mjs +20 -17
  213. package/dist/astro/routes/api/content/_collection_/_id_/lock.mjs.map +1 -1
  214. package/dist/astro/routes/api/content/_collection_/_id_/permanent.d.mts.map +1 -1
  215. package/dist/astro/routes/api/content/_collection_/_id_/permanent.mjs +7 -6
  216. package/dist/astro/routes/api/content/_collection_/_id_/permanent.mjs.map +1 -1
  217. package/dist/astro/routes/api/content/_collection_/_id_/plugin-extensions/_pluginId_/_kind_/_extensionId_.mjs +11 -11
  218. package/dist/astro/routes/api/content/_collection_/_id_/preview-url.mjs +30 -29
  219. package/dist/astro/routes/api/content/_collection_/_id_/preview-url.mjs.map +1 -1
  220. package/dist/astro/routes/api/content/_collection_/_id_/publish.d.mts.map +1 -1
  221. package/dist/astro/routes/api/content/_collection_/_id_/publish.mjs +18 -17
  222. package/dist/astro/routes/api/content/_collection_/_id_/publish.mjs.map +1 -1
  223. package/dist/astro/routes/api/content/_collection_/_id_/references/_relation_/children.mjs +35 -34
  224. package/dist/astro/routes/api/content/_collection_/_id_/references/_relation_/children.mjs.map +1 -1
  225. package/dist/astro/routes/api/content/_collection_/_id_/references/_relation_/parents.mjs +35 -34
  226. package/dist/astro/routes/api/content/_collection_/_id_/references/_relation_/parents.mjs.map +1 -1
  227. package/dist/astro/routes/api/content/_collection_/_id_/restore.d.mts.map +1 -1
  228. package/dist/astro/routes/api/content/_collection_/_id_/restore.mjs +7 -6
  229. package/dist/astro/routes/api/content/_collection_/_id_/restore.mjs.map +1 -1
  230. package/dist/astro/routes/api/content/_collection_/_id_/revisions.mjs +5 -5
  231. package/dist/astro/routes/api/content/_collection_/_id_/schedule.d.mts.map +1 -1
  232. package/dist/astro/routes/api/content/_collection_/_id_/schedule.mjs +19 -18
  233. package/dist/astro/routes/api/content/_collection_/_id_/schedule.mjs.map +1 -1
  234. package/dist/astro/routes/api/content/_collection_/_id_/terms/_taxonomy_.d.mts.map +1 -1
  235. package/dist/astro/routes/api/content/_collection_/_id_/terms/_taxonomy_.mjs +31 -26
  236. package/dist/astro/routes/api/content/_collection_/_id_/terms/_taxonomy_.mjs.map +1 -1
  237. package/dist/astro/routes/api/content/_collection_/_id_/translations.mjs +5 -5
  238. package/dist/astro/routes/api/content/_collection_/_id_/unpublish.d.mts.map +1 -1
  239. package/dist/astro/routes/api/content/_collection_/_id_/unpublish.mjs +18 -17
  240. package/dist/astro/routes/api/content/_collection_/_id_/unpublish.mjs.map +1 -1
  241. package/dist/astro/routes/api/content/_collection_/_id_.d.mts.map +1 -1
  242. package/dist/astro/routes/api/content/_collection_/_id_.mjs +27 -20
  243. package/dist/astro/routes/api/content/_collection_/_id_.mjs.map +1 -1
  244. package/dist/astro/routes/api/content/_collection_/authors.mjs +5 -5
  245. package/dist/astro/routes/api/content/_collection_/index.mjs +18 -21
  246. package/dist/astro/routes/api/content/_collection_/index.mjs.map +1 -1
  247. package/dist/astro/routes/api/content/_collection_/trash.mjs +15 -15
  248. package/dist/astro/routes/api/dashboard.d.mts.map +1 -1
  249. package/dist/astro/routes/api/dashboard.mjs +18 -12
  250. package/dist/astro/routes/api/dashboard.mjs.map +1 -1
  251. package/dist/astro/routes/api/dev/emails.mjs +5 -5
  252. package/dist/astro/routes/api/dev/scheduled-tasks.d.mts +12 -0
  253. package/dist/astro/routes/api/dev/scheduled-tasks.d.mts.map +1 -0
  254. package/dist/astro/routes/api/dev/scheduled-tasks.mjs +140 -0
  255. package/dist/astro/routes/api/dev/scheduled-tasks.mjs.map +1 -0
  256. package/dist/astro/routes/api/health.mjs +6 -6
  257. package/dist/astro/routes/api/import/probe.d.mts +3 -3
  258. package/dist/astro/routes/api/import/probe.mjs +25 -23
  259. package/dist/astro/routes/api/import/probe.mjs.map +1 -1
  260. package/dist/astro/routes/api/import/wordpress/analyze.d.mts.map +1 -1
  261. package/dist/astro/routes/api/import/wordpress/analyze.mjs +7 -20
  262. package/dist/astro/routes/api/import/wordpress/analyze.mjs.map +1 -1
  263. package/dist/astro/routes/api/import/wordpress/execute.d.mts +15 -14
  264. package/dist/astro/routes/api/import/wordpress/execute.d.mts.map +1 -1
  265. package/dist/astro/routes/api/import/wordpress/execute.mjs +36 -30
  266. package/dist/astro/routes/api/import/wordpress/execute.mjs.map +1 -1
  267. package/dist/astro/routes/api/import/wordpress/media.d.mts +12 -12
  268. package/dist/astro/routes/api/import/wordpress/media.mjs +17 -17
  269. package/dist/astro/routes/api/import/wordpress/prepare.mjs +19 -17
  270. package/dist/astro/routes/api/import/wordpress/prepare.mjs.map +1 -1
  271. package/dist/astro/routes/api/import/wordpress/rewrite-url-helpers.d.mts +8 -0
  272. package/dist/astro/routes/api/import/wordpress/rewrite-url-helpers.d.mts.map +1 -1
  273. package/dist/astro/routes/api/import/wordpress/rewrite-url-helpers.mjs +67 -31
  274. package/dist/astro/routes/api/import/wordpress/rewrite-url-helpers.mjs.map +1 -1
  275. package/dist/astro/routes/api/import/wordpress/rewrite-urls.d.mts +13 -13
  276. package/dist/astro/routes/api/import/wordpress/rewrite-urls.mjs +27 -26
  277. package/dist/astro/routes/api/import/wordpress/rewrite-urls.mjs.map +1 -1
  278. package/dist/astro/routes/api/import/wordpress-plugin/analyze.d.mts +1 -1
  279. package/dist/astro/routes/api/import/wordpress-plugin/analyze.mjs +26 -23
  280. package/dist/astro/routes/api/import/wordpress-plugin/analyze.mjs.map +1 -1
  281. package/dist/astro/routes/api/import/wordpress-plugin/execute.d.mts +13 -13
  282. package/dist/astro/routes/api/import/wordpress-plugin/execute.d.mts.map +1 -1
  283. package/dist/astro/routes/api/import/wordpress-plugin/execute.mjs +63 -35
  284. package/dist/astro/routes/api/import/wordpress-plugin/execute.mjs.map +1 -1
  285. package/dist/astro/routes/api/manifest.mjs +9 -6
  286. package/dist/astro/routes/api/manifest.mjs.map +1 -1
  287. package/dist/astro/routes/api/mcp.mjs +135 -101
  288. package/dist/astro/routes/api/mcp.mjs.map +1 -1
  289. package/dist/astro/routes/api/media/_id_/confirm.d.mts.map +1 -1
  290. package/dist/astro/routes/api/media/_id_/confirm.mjs +34 -18
  291. package/dist/astro/routes/api/media/_id_/confirm.mjs.map +1 -1
  292. package/dist/astro/routes/api/media/_id_/replace.mjs +15 -15
  293. package/dist/astro/routes/api/media/_id_/upload.mjs +8 -8
  294. package/dist/astro/routes/api/media/_id_/usage.mjs +31 -30
  295. package/dist/astro/routes/api/media/_id_/usage.mjs.map +1 -1
  296. package/dist/astro/routes/api/media/_id_.mjs +29 -28
  297. package/dist/astro/routes/api/media/_id_.mjs.map +1 -1
  298. package/dist/astro/routes/api/media/asset/_id_/_filename_.mjs +6 -6
  299. package/dist/astro/routes/api/media/file/_...key_.d.mts.map +1 -1
  300. package/dist/astro/routes/api/media/file/_...key_.mjs +45 -15
  301. package/dist/astro/routes/api/media/file/_...key_.mjs.map +1 -1
  302. package/dist/astro/routes/api/media/folders/_id_.mjs +16 -16
  303. package/dist/astro/routes/api/media/folders/index.mjs +16 -16
  304. package/dist/astro/routes/api/media/providers/_providerId_/_itemId_.mjs +5 -5
  305. package/dist/astro/routes/api/media/providers/_providerId_/index.mjs +5 -5
  306. package/dist/astro/routes/api/media/providers/index.mjs +5 -5
  307. package/dist/astro/routes/api/media/upload-url.mjs +40 -20
  308. package/dist/astro/routes/api/media/upload-url.mjs.map +1 -1
  309. package/dist/astro/routes/api/media.d.mts.map +1 -1
  310. package/dist/astro/routes/api/media.mjs +40 -29
  311. package/dist/astro/routes/api/media.mjs.map +1 -1
  312. package/dist/astro/routes/api/menus/_name_/items/_id_.d.mts.map +1 -1
  313. package/dist/astro/routes/api/menus/_name_/items/_id_.mjs +19 -18
  314. package/dist/astro/routes/api/menus/_name_/items/_id_.mjs.map +1 -1
  315. package/dist/astro/routes/api/menus/_name_/items.d.mts.map +1 -1
  316. package/dist/astro/routes/api/menus/_name_/items.mjs +18 -17
  317. package/dist/astro/routes/api/menus/_name_/items.mjs.map +1 -1
  318. package/dist/astro/routes/api/menus/_name_/reorder.d.mts.map +1 -1
  319. package/dist/astro/routes/api/menus/_name_/reorder.mjs +18 -17
  320. package/dist/astro/routes/api/menus/_name_/reorder.mjs.map +1 -1
  321. package/dist/astro/routes/api/menus/_name_/translations.d.mts.map +1 -1
  322. package/dist/astro/routes/api/menus/_name_/translations.mjs +18 -17
  323. package/dist/astro/routes/api/menus/_name_/translations.mjs.map +1 -1
  324. package/dist/astro/routes/api/menus/_name_.d.mts.map +1 -1
  325. package/dist/astro/routes/api/menus/_name_.mjs +19 -18
  326. package/dist/astro/routes/api/menus/_name_.mjs.map +1 -1
  327. package/dist/astro/routes/api/menus/index.d.mts.map +1 -1
  328. package/dist/astro/routes/api/menus/index.mjs +18 -17
  329. package/dist/astro/routes/api/menus/index.mjs.map +1 -1
  330. package/dist/astro/routes/api/oauth/authorize.mjs +6 -6
  331. package/dist/astro/routes/api/oauth/device/authorize.mjs +8 -8
  332. package/dist/astro/routes/api/oauth/device/code.mjs +12 -11
  333. package/dist/astro/routes/api/oauth/device/code.mjs.map +1 -1
  334. package/dist/astro/routes/api/oauth/device/token.mjs +11 -10
  335. package/dist/astro/routes/api/oauth/device/token.mjs.map +1 -1
  336. package/dist/astro/routes/api/oauth/register.mjs +8 -7
  337. package/dist/astro/routes/api/oauth/register.mjs.map +1 -1
  338. package/dist/astro/routes/api/oauth/token/refresh.mjs +8 -8
  339. package/dist/astro/routes/api/oauth/token/revoke.mjs +8 -8
  340. package/dist/astro/routes/api/oauth/token.mjs +8 -8
  341. package/dist/astro/routes/api/openapi.json.mjs +22 -22
  342. package/dist/astro/routes/api/openapi.json.mjs.map +1 -1
  343. package/dist/astro/routes/api/plugins/_pluginId_/_...path_.mjs +11 -11
  344. package/dist/astro/routes/api/redirects/404s/index.mjs +19 -19
  345. package/dist/astro/routes/api/redirects/404s/summary.mjs +19 -19
  346. package/dist/astro/routes/api/redirects/_id_.d.mts.map +1 -1
  347. package/dist/astro/routes/api/redirects/_id_.mjs +32 -23
  348. package/dist/astro/routes/api/redirects/_id_.mjs.map +1 -1
  349. package/dist/astro/routes/api/redirects/index.d.mts.map +1 -1
  350. package/dist/astro/routes/api/redirects/index.mjs +24 -21
  351. package/dist/astro/routes/api/redirects/index.mjs.map +1 -1
  352. package/dist/astro/routes/api/relations/_id_/index.mjs +35 -34
  353. package/dist/astro/routes/api/relations/_id_/index.mjs.map +1 -1
  354. package/dist/astro/routes/api/relations/index.mjs +35 -34
  355. package/dist/astro/routes/api/relations/index.mjs.map +1 -1
  356. package/dist/astro/routes/api/revisions/_revisionId_/index.mjs +5 -5
  357. package/dist/astro/routes/api/revisions/_revisionId_/restore.mjs +16 -16
  358. package/dist/astro/routes/api/schema/block-types/_slug_/index.mjs +71 -69
  359. package/dist/astro/routes/api/schema/block-types/_slug_/index.mjs.map +1 -1
  360. package/dist/astro/routes/api/schema/block-types/_slug_/versions/_version_/activate.mjs +71 -69
  361. package/dist/astro/routes/api/schema/block-types/_slug_/versions/_version_/activate.mjs.map +1 -1
  362. package/dist/astro/routes/api/schema/block-types/index.mjs +71 -69
  363. package/dist/astro/routes/api/schema/block-types/index.mjs.map +1 -1
  364. package/dist/astro/routes/api/schema/collections/_slug_/fields/_fieldSlug_.mjs +71 -69
  365. package/dist/astro/routes/api/schema/collections/_slug_/fields/_fieldSlug_.mjs.map +1 -1
  366. package/dist/astro/routes/api/schema/collections/_slug_/fields/index.mjs +71 -69
  367. package/dist/astro/routes/api/schema/collections/_slug_/fields/index.mjs.map +1 -1
  368. package/dist/astro/routes/api/schema/collections/_slug_/fields/reorder.mjs +71 -69
  369. package/dist/astro/routes/api/schema/collections/_slug_/fields/reorder.mjs.map +1 -1
  370. package/dist/astro/routes/api/schema/collections/_slug_/index.mjs +71 -69
  371. package/dist/astro/routes/api/schema/collections/_slug_/index.mjs.map +1 -1
  372. package/dist/astro/routes/api/schema/collections/index.mjs +71 -69
  373. package/dist/astro/routes/api/schema/collections/index.mjs.map +1 -1
  374. package/dist/astro/routes/api/schema/collections/reorder.mjs +71 -69
  375. package/dist/astro/routes/api/schema/collections/reorder.mjs.map +1 -1
  376. package/dist/astro/routes/api/schema/index.mjs +17 -16
  377. package/dist/astro/routes/api/schema/index.mjs.map +1 -1
  378. package/dist/astro/routes/api/schema/orphans/_slug_.mjs +71 -69
  379. package/dist/astro/routes/api/schema/orphans/_slug_.mjs.map +1 -1
  380. package/dist/astro/routes/api/schema/orphans/index.mjs +71 -69
  381. package/dist/astro/routes/api/schema/orphans/index.mjs.map +1 -1
  382. package/dist/astro/routes/api/search/enable.mjs +19 -18
  383. package/dist/astro/routes/api/search/enable.mjs.map +1 -1
  384. package/dist/astro/routes/api/search/index.mjs +18 -17
  385. package/dist/astro/routes/api/search/index.mjs.map +1 -1
  386. package/dist/astro/routes/api/search/rebuild.mjs +19 -18
  387. package/dist/astro/routes/api/search/rebuild.mjs.map +1 -1
  388. package/dist/astro/routes/api/search/stats.mjs +9 -8
  389. package/dist/astro/routes/api/search/stats.mjs.map +1 -1
  390. package/dist/astro/routes/api/search/suggest.mjs +18 -17
  391. package/dist/astro/routes/api/search/suggest.mjs.map +1 -1
  392. package/dist/astro/routes/api/sections/_slug_.mjs +18 -17
  393. package/dist/astro/routes/api/sections/_slug_.mjs.map +1 -1
  394. package/dist/astro/routes/api/sections/index.mjs +18 -17
  395. package/dist/astro/routes/api/sections/index.mjs.map +1 -1
  396. package/dist/astro/routes/api/settings/backups/archives/_name_.mjs +7 -7
  397. package/dist/astro/routes/api/settings/backups/archives/index.mjs +7 -7
  398. package/dist/astro/routes/api/settings/backups/export.mjs +7 -7
  399. package/dist/astro/routes/api/settings/backups/index.mjs +8 -8
  400. package/dist/astro/routes/api/settings/domain-notify.d.mts +8 -0
  401. package/dist/astro/routes/api/settings/domain-notify.d.mts.map +1 -0
  402. package/dist/astro/routes/api/settings/domain-notify.mjs +125 -0
  403. package/dist/astro/routes/api/settings/domain-notify.mjs.map +1 -0
  404. package/dist/astro/routes/api/settings/domain.d.mts +9 -0
  405. package/dist/astro/routes/api/settings/domain.d.mts.map +1 -0
  406. package/dist/astro/routes/api/settings/domain.mjs +64 -0
  407. package/dist/astro/routes/api/settings/domain.mjs.map +1 -0
  408. package/dist/astro/routes/api/settings/email.mjs +6 -6
  409. package/dist/astro/routes/api/settings.d.mts.map +1 -1
  410. package/dist/astro/routes/api/settings.mjs +23 -20
  411. package/dist/astro/routes/api/settings.mjs.map +1 -1
  412. package/dist/astro/routes/api/setup/admin-verify.d.mts.map +1 -1
  413. package/dist/astro/routes/api/setup/admin-verify.mjs +25 -21
  414. package/dist/astro/routes/api/setup/admin-verify.mjs.map +1 -1
  415. package/dist/astro/routes/api/setup/admin.mjs +18 -18
  416. package/dist/astro/routes/api/setup/dev-bypass.mjs +43 -41
  417. package/dist/astro/routes/api/setup/dev-bypass.mjs.map +1 -1
  418. package/dist/astro/routes/api/setup/dev-reset.mjs +4 -4
  419. package/dist/astro/routes/api/setup/index.d.mts.map +1 -1
  420. package/dist/astro/routes/api/setup/index.mjs +53 -47
  421. package/dist/astro/routes/api/setup/index.mjs.map +1 -1
  422. package/dist/astro/routes/api/setup/status.mjs +6 -6
  423. package/dist/astro/routes/api/site/domain-proof.d.mts +8 -0
  424. package/dist/astro/routes/api/site/domain-proof.d.mts.map +1 -0
  425. package/dist/astro/routes/api/site/domain-proof.mjs +35 -0
  426. package/dist/astro/routes/api/site/domain-proof.mjs.map +1 -0
  427. package/dist/astro/routes/api/snapshot.mjs +8 -8
  428. package/dist/astro/routes/api/taxonomies/_name_/reorder.d.mts.map +1 -1
  429. package/dist/astro/routes/api/taxonomies/_name_/reorder.mjs +24 -22
  430. package/dist/astro/routes/api/taxonomies/_name_/reorder.mjs.map +1 -1
  431. package/dist/astro/routes/api/taxonomies/_name_/terms/_slug_/translations.d.mts.map +1 -1
  432. package/dist/astro/routes/api/taxonomies/_name_/terms/_slug_/translations.mjs +24 -22
  433. package/dist/astro/routes/api/taxonomies/_name_/terms/_slug_/translations.mjs.map +1 -1
  434. package/dist/astro/routes/api/taxonomies/_name_/terms/_slug_.d.mts.map +1 -1
  435. package/dist/astro/routes/api/taxonomies/_name_/terms/_slug_.mjs +25 -23
  436. package/dist/astro/routes/api/taxonomies/_name_/terms/_slug_.mjs.map +1 -1
  437. package/dist/astro/routes/api/taxonomies/_name_/terms/index.d.mts.map +1 -1
  438. package/dist/astro/routes/api/taxonomies/_name_/terms/index.mjs +24 -22
  439. package/dist/astro/routes/api/taxonomies/_name_/terms/index.mjs.map +1 -1
  440. package/dist/astro/routes/api/taxonomies/_name_/translations.mjs +22 -21
  441. package/dist/astro/routes/api/taxonomies/_name_/translations.mjs.map +1 -1
  442. package/dist/astro/routes/api/taxonomies/_name_.d.mts.map +1 -1
  443. package/dist/astro/routes/api/taxonomies/_name_.mjs +25 -23
  444. package/dist/astro/routes/api/taxonomies/_name_.mjs.map +1 -1
  445. package/dist/astro/routes/api/taxonomies/bulk-tag.mjs +35 -34
  446. package/dist/astro/routes/api/taxonomies/bulk-tag.mjs.map +1 -1
  447. package/dist/astro/routes/api/taxonomies/index.d.mts.map +1 -1
  448. package/dist/astro/routes/api/taxonomies/index.mjs +24 -22
  449. package/dist/astro/routes/api/taxonomies/index.mjs.map +1 -1
  450. package/dist/astro/routes/api/themes/preview.mjs +6 -6
  451. package/dist/astro/routes/api/typegen.mjs +6 -6
  452. package/dist/astro/routes/api/visual-editing/action-token.mjs +6 -6
  453. package/dist/astro/routes/api/visual-editing/content/_collection_/_id_/publish.mjs +18 -18
  454. package/dist/astro/routes/api/visual-editing/toolbar-labels.mjs +4 -4
  455. package/dist/astro/routes/api/well-known/auth.mjs +1 -1
  456. package/dist/astro/routes/api/well-known/oauth-authorization-server.mjs +2 -2
  457. package/dist/astro/routes/api/well-known/oauth-protected-resource.mjs +2 -2
  458. package/dist/astro/routes/api/widget-areas/_name_/reorder.d.mts.map +1 -1
  459. package/dist/astro/routes/api/widget-areas/_name_/reorder.mjs +17 -16
  460. package/dist/astro/routes/api/widget-areas/_name_/reorder.mjs.map +1 -1
  461. package/dist/astro/routes/api/widget-areas/_name_/widgets/_id_.d.mts.map +1 -1
  462. package/dist/astro/routes/api/widget-areas/_name_/widgets/_id_.mjs +21 -19
  463. package/dist/astro/routes/api/widget-areas/_name_/widgets/_id_.mjs.map +1 -1
  464. package/dist/astro/routes/api/widget-areas/_name_/widgets.d.mts.map +1 -1
  465. package/dist/astro/routes/api/widget-areas/_name_/widgets.mjs +20 -18
  466. package/dist/astro/routes/api/widget-areas/_name_/widgets.mjs.map +1 -1
  467. package/dist/astro/routes/api/widget-areas/_name_.d.mts.map +1 -1
  468. package/dist/astro/routes/api/widget-areas/_name_.mjs +10 -8
  469. package/dist/astro/routes/api/widget-areas/_name_.mjs.map +1 -1
  470. package/dist/astro/routes/api/widget-areas/index.d.mts.map +1 -1
  471. package/dist/astro/routes/api/widget-areas/index.mjs +20 -18
  472. package/dist/astro/routes/api/widget-areas/index.mjs.map +1 -1
  473. package/dist/astro/routes/api/widget-components.mjs +5 -5
  474. package/dist/astro/routes/robots.txt.d.mts.map +1 -1
  475. package/dist/astro/routes/robots.txt.mjs +38 -5
  476. package/dist/astro/routes/robots.txt.mjs.map +1 -1
  477. package/dist/astro/routes/sitemap-_collection_.xml.d.mts.map +1 -1
  478. package/dist/astro/routes/sitemap-_collection_.xml.mjs +33 -11
  479. package/dist/astro/routes/sitemap-_collection_.xml.mjs.map +1 -1
  480. package/dist/astro/routes/sitemap.xml.d.mts.map +1 -1
  481. package/dist/astro/routes/sitemap.xml.mjs +17 -11
  482. package/dist/astro/routes/sitemap.xml.mjs.map +1 -1
  483. package/dist/astro/types.d.mts +32 -18
  484. package/dist/astro/types.d.mts.map +1 -1
  485. package/dist/audit-_gieLVGU.mjs +127 -0
  486. package/dist/audit-_gieLVGU.mjs.map +1 -0
  487. package/dist/auth/providers/github.d.mts +1 -1
  488. package/dist/auth/providers/google.d.mts +1 -1
  489. package/dist/auth/providers/microsoft.d.mts +1 -1
  490. package/dist/authoritative-records-CQlB3JzE.mjs +5183 -0
  491. package/dist/authoritative-records-CQlB3JzE.mjs.map +1 -0
  492. package/dist/authorize-DPFBGbE6.mjs +74 -0
  493. package/dist/authorize-DPFBGbE6.mjs.map +1 -0
  494. package/dist/backup-3FgVxiDJ.mjs +246 -0
  495. package/dist/backup-3FgVxiDJ.mjs.map +1 -0
  496. package/dist/block-types-CYcG56JB.mjs +132 -0
  497. package/dist/block-types-CYcG56JB.mjs.map +1 -0
  498. package/dist/block-values-gCX4HBSl.mjs +215 -0
  499. package/dist/block-values-gCX4HBSl.mjs.map +1 -0
  500. package/dist/byline-BR1qhyiw.mjs +909 -0
  501. package/dist/byline-BR1qhyiw.mjs.map +1 -0
  502. package/dist/byline-fields-4ClDC88c.mjs +123 -0
  503. package/dist/byline-fields-4ClDC88c.mjs.map +1 -0
  504. package/dist/byline-fields-BLXZnX7N.mjs +280 -0
  505. package/dist/byline-fields-BLXZnX7N.mjs.map +1 -0
  506. package/dist/bylines-CVOvRUL7.mjs +234 -0
  507. package/dist/bylines-CVOvRUL7.mjs.map +1 -0
  508. package/dist/bylines-DxOs9B7z.mjs +150 -0
  509. package/dist/bylines-DxOs9B7z.mjs.map +1 -0
  510. package/dist/cache-CEU9wo_h.mjs +151 -0
  511. package/dist/cache-CEU9wo_h.mjs.map +1 -0
  512. package/dist/canonical-BudtH-Fx.mjs +174 -0
  513. package/dist/canonical-BudtH-Fx.mjs.map +1 -0
  514. package/dist/capture-triggers-CT6dK9zd.mjs +362 -0
  515. package/dist/capture-triggers-CT6dK9zd.mjs.map +1 -0
  516. package/dist/challenge-store-C17BYx2-.mjs +51 -0
  517. package/dist/challenge-store-C17BYx2-.mjs.map +1 -0
  518. package/dist/checksum-CEqvfxGX.mjs +162 -0
  519. package/dist/checksum-CEqvfxGX.mjs.map +1 -0
  520. package/dist/chunks-xC4UD5-S.mjs +25 -0
  521. package/dist/chunks-xC4UD5-S.mjs.map +1 -0
  522. package/dist/cli/index.mjs +134 -118
  523. package/dist/cli/index.mjs.map +1 -1
  524. package/dist/client/cf-access.d.mts +1 -1
  525. package/dist/client/index.d.mts +122 -122
  526. package/dist/client/index.d.mts.map +1 -1
  527. package/dist/client/index.mjs +12 -10
  528. package/dist/client/index.mjs.map +1 -1
  529. package/dist/collection-slugs-cache-e09QeJQt.mjs +85 -0
  530. package/dist/collection-slugs-cache-e09QeJQt.mjs.map +1 -0
  531. package/dist/comment-UvIWDKcW.mjs +325 -0
  532. package/dist/comment-UvIWDKcW.mjs.map +1 -0
  533. package/dist/comment-reaction-dGp6_FRo.mjs +85 -0
  534. package/dist/comment-reaction-dGp6_FRo.mjs.map +1 -0
  535. package/dist/comments-pej-_BUO.mjs +195 -0
  536. package/dist/comments-pej-_BUO.mjs.map +1 -0
  537. package/dist/comments-yiRFx3w5.mjs +99 -0
  538. package/dist/comments-yiRFx3w5.mjs.map +1 -0
  539. package/dist/components-Brp__9xo.mjs +112 -0
  540. package/dist/components-Brp__9xo.mjs.map +1 -0
  541. package/dist/config-Bsm_u_oE.d.mts +6799 -0
  542. package/dist/config-Bsm_u_oE.d.mts.map +1 -0
  543. package/dist/config-CFMojMFK.d.mts +39 -0
  544. package/dist/config-CFMojMFK.d.mts.map +1 -0
  545. package/dist/config-DBU6iUQB.mjs +228 -0
  546. package/dist/config-DBU6iUQB.mjs.map +1 -0
  547. package/dist/connection-BtEN_lP9.mjs +36 -0
  548. package/dist/connection-BtEN_lP9.mjs.map +1 -0
  549. package/dist/content-DQSRZTVw.mjs +2075 -0
  550. package/dist/content-DQSRZTVw.mjs.map +1 -0
  551. package/dist/content-list-query-CYKcY6Vi.d.mts +26 -0
  552. package/dist/content-list-query-CYKcY6Vi.d.mts.map +1 -0
  553. package/dist/content-repair-DNh5--x5.mjs +442 -0
  554. package/dist/content-repair-DNh5--x5.mjs.map +1 -0
  555. package/dist/context-BYptmCN0.mjs +2090 -0
  556. package/dist/context-BYptmCN0.mjs.map +1 -0
  557. package/dist/credits-B9iORdWB.mjs +110 -0
  558. package/dist/credits-B9iORdWB.mjs.map +1 -0
  559. package/dist/cron-D7obTIfk.mjs +306 -0
  560. package/dist/cron-D7obTIfk.mjs.map +1 -0
  561. package/dist/dashboard-D0jcgBD7.mjs +167 -0
  562. package/dist/dashboard-D0jcgBD7.mjs.map +1 -0
  563. package/dist/database/migration-lock.d.mts +17 -4
  564. package/dist/database/migration-lock.d.mts.map +1 -1
  565. package/dist/database/migration-lock.mjs +32 -5
  566. package/dist/database/migration-lock.mjs.map +1 -1
  567. package/dist/db/index.d.mts +3 -3
  568. package/dist/db/index.mjs +1 -1
  569. package/dist/db/libsql-migrations.d.mts +1 -1
  570. package/dist/db/libsql-migrations.mjs +4 -4
  571. package/dist/db/libsql.d.mts +1 -1
  572. package/dist/db/postgres-migrations.d.mts +1 -1
  573. package/dist/db/postgres-migrations.mjs +4 -4
  574. package/dist/db/postgres.d.mts +1 -1
  575. package/dist/db/sqlite-migrations.d.mts +1 -1
  576. package/dist/db/sqlite-migrations.mjs +4 -4
  577. package/dist/db/sqlite.d.mts +1 -1
  578. package/dist/db/sqlite.mjs +1 -1
  579. package/dist/default-C0W-PhAp.mjs +81 -0
  580. package/dist/default-C0W-PhAp.mjs.map +1 -0
  581. package/dist/deferred-tasks-ZvUECSzI.d.mts +9 -0
  582. package/dist/deferred-tasks-ZvUECSzI.d.mts.map +1 -0
  583. package/dist/dev-typegen-EBni_pOQ.mjs +29 -0
  584. package/dist/dev-typegen-EBni_pOQ.mjs.map +1 -0
  585. package/dist/device-flow-BkFKBoAn.mjs +521 -0
  586. package/dist/device-flow-BkFKBoAn.mjs.map +1 -0
  587. package/dist/digest-DJ1tHCgy.mjs +194 -0
  588. package/dist/digest-DJ1tHCgy.mjs.map +1 -0
  589. package/dist/direct-executor-Cbxzg4qe.mjs +117 -0
  590. package/dist/direct-executor-Cbxzg4qe.mjs.map +1 -0
  591. package/dist/email-console-FFVJWb9N.mjs +50 -0
  592. package/dist/email-console-FFVJWb9N.mjs.map +1 -0
  593. package/dist/email-locale-BJ8DjTzZ.mjs +25 -0
  594. package/dist/email-locale-BJ8DjTzZ.mjs.map +1 -0
  595. package/dist/emdash-runtime-DVi7vtXC.mjs +4379 -0
  596. package/dist/emdash-runtime-DVi7vtXC.mjs.map +1 -0
  597. package/dist/entry-lock-C7VX0NGK.d.mts +4568 -0
  598. package/dist/entry-lock-C7VX0NGK.d.mts.map +1 -0
  599. package/dist/entry-lock-DLxCffFW.mjs +163 -0
  600. package/dist/entry-lock-DLxCffFW.mjs.map +1 -0
  601. package/dist/entry-lock-Df6-XhIu.mjs +1211 -0
  602. package/dist/entry-lock-Df6-XhIu.mjs.map +1 -0
  603. package/dist/env-types-C3FCVBWe.mjs +38 -0
  604. package/dist/env-types-C3FCVBWe.mjs.map +1 -0
  605. package/dist/error-CVWeIOku.mjs +90 -0
  606. package/dist/error-CVWeIOku.mjs.map +1 -0
  607. package/dist/errors-B4f4It-2.mjs +120 -0
  608. package/dist/errors-B4f4It-2.mjs.map +1 -0
  609. package/dist/errors-BOYNdIo3.mjs +479 -0
  610. package/dist/errors-BOYNdIo3.mjs.map +1 -0
  611. package/dist/escape-lsNq38PP.mjs +9 -0
  612. package/dist/escape-lsNq38PP.mjs.map +1 -0
  613. package/dist/fence-C3MUitUN.mjs +162 -0
  614. package/dist/fence-C3MUitUN.mjs.map +1 -0
  615. package/dist/field-defs-cache-Dez5iWJJ.mjs +77 -0
  616. package/dist/field-defs-cache-Dez5iWJJ.mjs.map +1 -0
  617. package/dist/field-map-Bft9LKak.mjs +83 -0
  618. package/dist/field-map-Bft9LKak.mjs.map +1 -0
  619. package/dist/fts-manager-Beg3e4bI.mjs +443 -0
  620. package/dist/fts-manager-Beg3e4bI.mjs.map +1 -0
  621. package/dist/gc-ByyAYiYE.mjs +75 -0
  622. package/dist/gc-ByyAYiYE.mjs.map +1 -0
  623. package/dist/hash-BJaeek87.mjs +37 -0
  624. package/dist/hash-BJaeek87.mjs.map +1 -0
  625. package/dist/hook-result-BrdLyOdI.d.mts +31 -0
  626. package/dist/hook-result-BrdLyOdI.d.mts.map +1 -0
  627. package/dist/hreflang-C8Jb-hrf.mjs +105 -0
  628. package/dist/hreflang-C8Jb-hrf.mjs.map +1 -0
  629. package/dist/hreflang-CY_F5OjF.d.mts +50 -0
  630. package/dist/hreflang-CY_F5OjF.d.mts.map +1 -0
  631. package/dist/http-route-dispatch-CyeW6iPv.mjs +342 -0
  632. package/dist/http-route-dispatch-CyeW6iPv.mjs.map +1 -0
  633. package/dist/identity-Cael5uTT.mjs +35 -0
  634. package/dist/identity-Cael5uTT.mjs.map +1 -0
  635. package/dist/import-BUXjdZUn.mjs +2126 -0
  636. package/dist/import-BUXjdZUn.mjs.map +1 -0
  637. package/dist/index-BB9sVisO.d.mts +623 -0
  638. package/dist/index-BB9sVisO.d.mts.map +1 -0
  639. package/dist/index.d.mts +24 -24
  640. package/dist/index.mjs +97 -95
  641. package/dist/install-finalization-3JX5qQEA.mjs +58 -0
  642. package/dist/install-finalization-3JX5qQEA.mjs.map +1 -0
  643. package/dist/json-recordset-BUjxhr77.mjs +12 -0
  644. package/dist/json-recordset-BUjxhr77.mjs.map +1 -0
  645. package/dist/json-schema-v_D_pPNG.mjs +15 -0
  646. package/dist/json-schema-v_D_pPNG.mjs.map +1 -0
  647. package/dist/keys-CifIkT0N.mjs +61 -0
  648. package/dist/keys-CifIkT0N.mjs.map +1 -0
  649. package/dist/kinds-B_Qcl5pz.mjs +974 -0
  650. package/dist/kinds-B_Qcl5pz.mjs.map +1 -0
  651. package/dist/lifecycle-7vUJeFRe.mjs +25 -0
  652. package/dist/lifecycle-7vUJeFRe.mjs.map +1 -0
  653. package/dist/load-CdAG9wz-.mjs +28 -0
  654. package/dist/load-CdAG9wz-.mjs.map +1 -0
  655. package/dist/loader-CswroUbe.mjs +1380 -0
  656. package/dist/loader-CswroUbe.mjs.map +1 -0
  657. package/dist/loops-uA4iTOzd.mjs +205 -0
  658. package/dist/loops-uA4iTOzd.mjs.map +1 -0
  659. package/dist/manifest-builder-B8zjuH3f.mjs +189 -0
  660. package/dist/manifest-builder-B8zjuH3f.mjs.map +1 -0
  661. package/dist/manifest-schema-DNb4XmTS.mjs +497 -0
  662. package/dist/manifest-schema-DNb4XmTS.mjs.map +1 -0
  663. package/dist/marketplace-CqbgeIa7.mjs +257 -0
  664. package/dist/marketplace-CqbgeIa7.mjs.map +1 -0
  665. package/dist/media/image-endpoint.d.mts +26 -2
  666. package/dist/media/image-endpoint.d.mts.map +1 -1
  667. package/dist/media/image-endpoint.mjs +73 -3
  668. package/dist/media/image-endpoint.mjs.map +1 -1
  669. package/dist/media/index.d.mts +1 -1
  670. package/dist/media/local-runtime.d.mts +14 -14
  671. package/dist/media/local-runtime.mjs +10 -5
  672. package/dist/media/local-runtime.mjs.map +1 -1
  673. package/dist/media--dJRU6i2.mjs +294 -0
  674. package/dist/media--dJRU6i2.mjs.map +1 -0
  675. package/dist/media-1WC65OCB.mjs +416 -0
  676. package/dist/media-1WC65OCB.mjs.map +1 -0
  677. package/dist/media-Bws9f18T.mjs +373 -0
  678. package/dist/media-Bws9f18T.mjs.map +1 -0
  679. package/dist/media-allowlist-BJB7MFx6.mjs +45 -0
  680. package/dist/media-allowlist-BJB7MFx6.mjs.map +1 -0
  681. package/dist/media-folders-Dn3C16B8.mjs +210 -0
  682. package/dist/media-folders-Dn3C16B8.mjs.map +1 -0
  683. package/dist/media-url-BQgKvpQ5.mjs +43 -0
  684. package/dist/media-url-BQgKvpQ5.mjs.map +1 -0
  685. package/dist/media-usage-CF0WVcLO.mjs +282 -0
  686. package/dist/media-usage-CF0WVcLO.mjs.map +1 -0
  687. package/dist/media-usage-activation-C9HwVw5w.mjs +78 -0
  688. package/dist/media-usage-activation-C9HwVw5w.mjs.map +1 -0
  689. package/dist/media-usage-work-CkLa5-nc.mjs +1036 -0
  690. package/dist/media-usage-work-CkLa5-nc.mjs.map +1 -0
  691. package/dist/media-usage-work-m3AWTmmC.mjs +151 -0
  692. package/dist/media-usage-work-m3AWTmmC.mjs.map +1 -0
  693. package/dist/menus-BCVSSp1z.mjs +753 -0
  694. package/dist/menus-BCVSSp1z.mjs.map +1 -0
  695. package/dist/menus-BSzwObhV.mjs +92 -0
  696. package/dist/menus-BSzwObhV.mjs.map +1 -0
  697. package/dist/menus-Cl4kwdt7.mjs +3721 -0
  698. package/dist/menus-Cl4kwdt7.mjs.map +1 -0
  699. package/dist/migrations/index.d.mts +1 -1
  700. package/dist/migrations/index.d.mts.map +1 -1
  701. package/dist/migrations/index.mjs +3 -3
  702. package/dist/mode-C-D3qICy.mjs +23 -0
  703. package/dist/mode-C-D3qICy.mjs.map +1 -0
  704. package/dist/node-sqlite-compat-CrKzRr0J.mjs +63 -0
  705. package/dist/node-sqlite-compat-CrKzRr0J.mjs.map +1 -0
  706. package/dist/oauth-authorization-TpEJrYB7.mjs +274 -0
  707. package/dist/oauth-authorization-TpEJrYB7.mjs.map +1 -0
  708. package/dist/oauth-clients-BT0Pg-MO.mjs +266 -0
  709. package/dist/oauth-clients-BT0Pg-MO.mjs.map +1 -0
  710. package/dist/oauth-state-store-CHMn_mwc.mjs +50 -0
  711. package/dist/oauth-state-store-CHMn_mwc.mjs.map +1 -0
  712. package/dist/oauth-user-lookup-BDgF6IVG.mjs +26 -0
  713. package/dist/oauth-user-lookup-BDgF6IVG.mjs.map +1 -0
  714. package/dist/object-cache/memory.d.mts +1 -1
  715. package/dist/options-DJWaq3Ie.d.mts +81 -0
  716. package/dist/options-DJWaq3Ie.d.mts.map +1 -0
  717. package/dist/ownership-MiyA7qKO.mjs +12 -0
  718. package/dist/ownership-MiyA7qKO.mjs.map +1 -0
  719. package/dist/page/index.d.mts +2 -2
  720. package/dist/page/index.mjs +9 -4
  721. package/dist/page/index.mjs.map +1 -1
  722. package/dist/parse-CWHOFc6z.d.mts +176 -0
  723. package/dist/parse-CWHOFc6z.d.mts.map +1 -0
  724. package/dist/parse-DgQ2NABT.mjs +81 -0
  725. package/dist/parse-DgQ2NABT.mjs.map +1 -0
  726. package/dist/passkey-config-D0kdzEao.mjs +46 -0
  727. package/dist/passkey-config-D0kdzEao.mjs.map +1 -0
  728. package/dist/paths-biDzFTY2.mjs +77 -0
  729. package/dist/paths-biDzFTY2.mjs.map +1 -0
  730. package/dist/patterns-CMNnYCgf.mjs +159 -0
  731. package/dist/patterns-CMNnYCgf.mjs.map +1 -0
  732. package/dist/placeholder-D41vk11_.d.mts +306 -0
  733. package/dist/placeholder-D41vk11_.d.mts.map +1 -0
  734. package/dist/plan-CCoqxNoU.mjs +135 -0
  735. package/dist/plan-CCoqxNoU.mjs.map +1 -0
  736. package/dist/plugin-test-runtime.d.mts +14 -14
  737. package/dist/plugin-test-runtime.d.mts.map +1 -1
  738. package/dist/plugin-test-runtime.mjs +110 -108
  739. package/dist/plugin-tool-name-DDUgN_0p.mjs +27 -0
  740. package/dist/plugin-tool-name-DDUgN_0p.mjs.map +1 -0
  741. package/dist/plugin-types.d.mts +2 -2
  742. package/dist/plugin-utils.d.mts +12 -12
  743. package/dist/plugin-utils.mjs +1 -1
  744. package/dist/plugin-utils.mjs.map +1 -1
  745. package/dist/plugins/adapt-sandbox-entry.d.mts +12 -12
  746. package/dist/plugins/adapt-sandbox-entry.d.mts.map +1 -1
  747. package/dist/plugins/adapt-sandbox-entry.mjs +9 -8
  748. package/dist/plugins/adapt-sandbox-entry.mjs.map +1 -1
  749. package/dist/plugins/host.d.mts +5 -5
  750. package/dist/plugins/host.mjs +46 -42
  751. package/dist/plugins-COJ2L49n.mjs +261 -0
  752. package/dist/plugins-COJ2L49n.mjs.map +1 -0
  753. package/dist/policy-DLQ--Hnm.mjs +45 -0
  754. package/dist/policy-DLQ--Hnm.mjs.map +1 -0
  755. package/dist/portable-text-BH4zgkSm.mjs +311 -0
  756. package/dist/portable-text-BH4zgkSm.mjs.map +1 -0
  757. package/dist/preview-DLexxwp3.mjs +107 -0
  758. package/dist/preview-DLexxwp3.mjs.map +1 -0
  759. package/dist/protocol-79kUO7jP.d.mts +65 -0
  760. package/dist/protocol-79kUO7jP.d.mts.map +1 -0
  761. package/dist/public-plugin-api-routes-BuAMJ8nN.mjs +316 -0
  762. package/dist/public-plugin-api-routes-BuAMJ8nN.mjs.map +1 -0
  763. package/dist/public-submission-Di3TsgzX.mjs +251 -0
  764. package/dist/public-submission-Di3TsgzX.mjs.map +1 -0
  765. package/dist/public-url-Bt98vysr.mjs +101 -0
  766. package/dist/public-url-Bt98vysr.mjs.map +1 -0
  767. package/dist/query-CpnRlBh8.mjs +1156 -0
  768. package/dist/query-CpnRlBh8.mjs.map +1 -0
  769. package/dist/query-haKvLAWl.mjs +41 -0
  770. package/dist/query-haKvLAWl.mjs.map +1 -0
  771. package/dist/range-CYfeXgGK.mjs +51 -0
  772. package/dist/range-CYfeXgGK.mjs.map +1 -0
  773. package/dist/rate-limit-Xp4d0NBY.mjs +127 -0
  774. package/dist/rate-limit-Xp4d0NBY.mjs.map +1 -0
  775. package/dist/receipt-BUsQCOeM.mjs +43 -0
  776. package/dist/receipt-BUsQCOeM.mjs.map +1 -0
  777. package/dist/redirect-CQAV7mCo.mjs +19 -0
  778. package/dist/redirect-CQAV7mCo.mjs.map +1 -0
  779. package/dist/redirect-DiS_3mA4.mjs +423 -0
  780. package/dist/redirect-DiS_3mA4.mjs.map +1 -0
  781. package/dist/redirect-paths-CNYq7w80.mjs +36 -0
  782. package/dist/redirect-paths-CNYq7w80.mjs.map +1 -0
  783. package/dist/redirects-BEVSRMa2.mjs +148 -0
  784. package/dist/redirects-BEVSRMa2.mjs.map +1 -0
  785. package/dist/redirects-BHpy-VsZ.mjs +446 -0
  786. package/dist/redirects-BHpy-VsZ.mjs.map +1 -0
  787. package/dist/registry/testing.mjs +3 -3
  788. package/dist/registry-TUVaid9Z.mjs +8369 -0
  789. package/dist/registry-TUVaid9Z.mjs.map +1 -0
  790. package/dist/relations-CA_QuMTU.mjs +776 -0
  791. package/dist/relations-CA_QuMTU.mjs.map +1 -0
  792. package/dist/request-context.d.mts +1 -1
  793. package/dist/request-meta-bwZ_NsvU.mjs +141 -0
  794. package/dist/request-meta-bwZ_NsvU.mjs.map +1 -0
  795. package/dist/resolve-DwNM-CXl.mjs +101 -0
  796. package/dist/resolve-DwNM-CXl.mjs.map +1 -0
  797. package/dist/revision-BVp8S0e_.mjs +374 -0
  798. package/dist/revision-BVp8S0e_.mjs.map +1 -0
  799. package/dist/route-cache-QSOyDEw0.mjs +20 -0
  800. package/dist/route-cache-QSOyDEw0.mjs.map +1 -0
  801. package/dist/route-wire-Ca_HWCZ5.mjs +197 -0
  802. package/dist/route-wire-Ca_HWCZ5.mjs.map +1 -0
  803. package/dist/routes-BerZFrvV.mjs +272 -0
  804. package/dist/routes-BerZFrvV.mjs.map +1 -0
  805. package/dist/runner-BObHz5FC.d.mts +68 -0
  806. package/dist/runner-BObHz5FC.d.mts.map +1 -0
  807. package/dist/runner-C5NeAkBQ.mjs +6595 -0
  808. package/dist/runner-C5NeAkBQ.mjs.map +1 -0
  809. package/dist/runtime.d.mts +13 -13
  810. package/dist/runtime.mjs +3 -2
  811. package/dist/runtime.mjs.map +1 -1
  812. package/dist/schema/project-env-types.mjs +40 -36
  813. package/dist/schema/project-env-types.mjs.map +1 -1
  814. package/dist/schema-C4OBuv6Z.mjs +13 -0
  815. package/dist/schema-C4OBuv6Z.mjs.map +1 -0
  816. package/dist/schema-DJRfvM_o.mjs +815 -0
  817. package/dist/schema-DJRfvM_o.mjs.map +1 -0
  818. package/dist/scopes-BU03K7Uo.mjs +34 -0
  819. package/dist/scopes-BU03K7Uo.mjs.map +1 -0
  820. package/dist/search-DfVzks89.mjs +450 -0
  821. package/dist/search-DfVzks89.mjs.map +1 -0
  822. package/dist/sections-BMy4JVUz.mjs +346 -0
  823. package/dist/sections-BMy4JVUz.mjs.map +1 -0
  824. package/dist/seed/index.d.mts +2 -2
  825. package/dist/seed/index.mjs +38 -34
  826. package/dist/seo/index.d.mts +3 -3
  827. package/dist/seo/index.mjs +25 -21
  828. package/dist/seo/index.mjs.map +1 -1
  829. package/dist/seo-ClB-dw9w.mjs +188 -0
  830. package/dist/seo-ClB-dw9w.mjs.map +1 -0
  831. package/dist/seo-VZYOEy8f.mjs +133 -0
  832. package/dist/seo-VZYOEy8f.mjs.map +1 -0
  833. package/dist/service-Bo_usgSk.mjs +150 -0
  834. package/dist/service-Bo_usgSk.mjs.map +1 -0
  835. package/dist/session-user-DlpPdf8L.mjs +61 -0
  836. package/dist/session-user-DlpPdf8L.mjs.map +1 -0
  837. package/dist/settings-CWb84sDm.mjs +452 -0
  838. package/dist/settings-CWb84sDm.mjs.map +1 -0
  839. package/dist/settings-DS914jjE.mjs +66 -0
  840. package/dist/settings-DS914jjE.mjs.map +1 -0
  841. package/dist/settings-Dd1uivmQ.mjs +73 -0
  842. package/dist/settings-Dd1uivmQ.mjs.map +1 -0
  843. package/dist/setup-complete-BuNxAUiN.mjs +65 -0
  844. package/dist/setup-complete-BuNxAUiN.mjs.map +1 -0
  845. package/dist/setup-nonce-BnEAX0iy.mjs +25 -0
  846. package/dist/setup-nonce-BnEAX0iy.mjs.map +1 -0
  847. package/dist/site-domain-Bq5j5bVg.mjs +131 -0
  848. package/dist/site-domain-Bq5j5bVg.mjs.map +1 -0
  849. package/dist/site-settings-DRHfX7bq.mjs +50 -0
  850. package/dist/site-settings-DRHfX7bq.mjs.map +1 -0
  851. package/dist/site-url-MB685I5X.mjs +45 -0
  852. package/dist/site-url-MB685I5X.mjs.map +1 -0
  853. package/dist/sitemap-name-BTg2NJJv.mjs +26 -0
  854. package/dist/sitemap-name-BTg2NJJv.mjs.map +1 -0
  855. package/dist/slug-aVnUV4SL.mjs +16 -0
  856. package/dist/slug-aVnUV4SL.mjs.map +1 -0
  857. package/dist/slugify-bu2-jKia.mjs +22 -0
  858. package/dist/slugify-bu2-jKia.mjs.map +1 -0
  859. package/dist/snapshot-DYsG4uOq.mjs +414 -0
  860. package/dist/snapshot-DYsG4uOq.mjs.map +1 -0
  861. package/dist/ssrf-BcYjyM4M.mjs +406 -0
  862. package/dist/ssrf-BcYjyM4M.mjs.map +1 -0
  863. package/dist/stage-D8DWgPcO.mjs +662 -0
  864. package/dist/stage-D8DWgPcO.mjs.map +1 -0
  865. package/dist/staged-CD_imitH.mjs +686 -0
  866. package/dist/staged-CD_imitH.mjs.map +1 -0
  867. package/dist/state-CFbGZziM.mjs +178 -0
  868. package/dist/state-CFbGZziM.mjs.map +1 -0
  869. package/dist/status-BFNdxzKc.mjs +30 -0
  870. package/dist/status-BFNdxzKc.mjs.map +1 -0
  871. package/dist/storage/local.d.mts +2 -2
  872. package/dist/storage/local.d.mts.map +1 -1
  873. package/dist/storage/local.mjs +12 -5
  874. package/dist/storage/local.mjs.map +1 -1
  875. package/dist/storage/s3.d.mts +4 -2
  876. package/dist/storage/s3.d.mts.map +1 -1
  877. package/dist/storage/s3.mjs +56 -9
  878. package/dist/storage/s3.mjs.map +1 -1
  879. package/dist/storage-query-DRyu3bSU.d.mts +1615 -0
  880. package/dist/storage-query-DRyu3bSU.d.mts.map +1 -0
  881. package/dist/tar-DFjExb9X.mjs +449 -0
  882. package/dist/tar-DFjExb9X.mjs.map +1 -0
  883. package/dist/target-CWZs2-o6.mjs +27 -0
  884. package/dist/target-CWZs2-o6.mjs.map +1 -0
  885. package/dist/taxonomies-ChnU7Mc8.mjs +697 -0
  886. package/dist/taxonomies-ChnU7Mc8.mjs.map +1 -0
  887. package/dist/taxonomies-Dd9JJv_a.mjs +939 -0
  888. package/dist/taxonomies-Dd9JJv_a.mjs.map +1 -0
  889. package/dist/taxonomy-C_C_LBAU.mjs +550 -0
  890. package/dist/taxonomy-C_C_LBAU.mjs.map +1 -0
  891. package/dist/tokens-BnhSnGwJ.mjs +171 -0
  892. package/dist/tokens-BnhSnGwJ.mjs.map +1 -0
  893. package/dist/transfer-ClH6w6BV.mjs +8873 -0
  894. package/dist/transfer-ClH6w6BV.mjs.map +1 -0
  895. package/dist/transfer-WmWiR3xf.mjs +166 -0
  896. package/dist/transfer-WmWiR3xf.mjs.map +1 -0
  897. package/dist/transfer-download--ofRj9Cw.mjs +33 -0
  898. package/dist/transfer-download--ofRj9Cw.mjs.map +1 -0
  899. package/dist/transformations-Bx4lYY0Y.mjs +196 -0
  900. package/dist/transformations-Bx4lYY0Y.mjs.map +1 -0
  901. package/dist/transport-BjbqNiPI.mjs +136 -0
  902. package/dist/transport-BjbqNiPI.mjs.map +1 -0
  903. package/dist/transport-DxiXnbXk.d.mts +42 -0
  904. package/dist/transport-DxiXnbXk.d.mts.map +1 -0
  905. package/dist/trusted-proxy-BU3Nx9g1.mjs +51 -0
  906. package/dist/trusted-proxy-BU3Nx9g1.mjs.map +1 -0
  907. package/dist/turnstile-CJwvsOqw.mjs +58 -0
  908. package/dist/turnstile-CJwvsOqw.mjs.map +1 -0
  909. package/dist/types-BA3ey2QH.d.mts +87 -0
  910. package/dist/types-BA3ey2QH.d.mts.map +1 -0
  911. package/dist/types-Bwpzb5o6.d.mts +227 -0
  912. package/dist/types-Bwpzb5o6.d.mts.map +1 -0
  913. package/dist/types-CNB-dj6F.d.mts +289 -0
  914. package/dist/types-CNB-dj6F.d.mts.map +1 -0
  915. package/dist/types-CgfFGfO5.mjs +16 -0
  916. package/dist/types-CgfFGfO5.mjs.map +1 -0
  917. package/dist/types-D2NEXtgB.mjs +127 -0
  918. package/dist/types-D2NEXtgB.mjs.map +1 -0
  919. package/dist/types-DCFavOii.d.mts +916 -0
  920. package/dist/types-DCFavOii.d.mts.map +1 -0
  921. package/dist/types-DHO7Pd25.d.mts +366 -0
  922. package/dist/types-DHO7Pd25.d.mts.map +1 -0
  923. package/dist/types-DvqVxZXa.d.mts +125 -0
  924. package/dist/types-DvqVxZXa.d.mts.map +1 -0
  925. package/dist/types-QoPHm-2w.d.mts +1741 -0
  926. package/dist/types-QoPHm-2w.d.mts.map +1 -0
  927. package/dist/types-RLgeIpnF.d.mts +374 -0
  928. package/dist/types-RLgeIpnF.d.mts.map +1 -0
  929. package/dist/types-qHVygneX.mjs +77 -0
  930. package/dist/types-qHVygneX.mjs.map +1 -0
  931. package/dist/types-sUHaH7lC.mjs +37 -0
  932. package/dist/types-sUHaH7lC.mjs.map +1 -0
  933. package/dist/types-slSqujQL.d.mts +204 -0
  934. package/dist/types-slSqujQL.d.mts.map +1 -0
  935. package/dist/update-check-BxNg9T6N.mjs +161 -0
  936. package/dist/update-check-BxNg9T6N.mjs.map +1 -0
  937. package/dist/upload-attempts-DPFC4COv.mjs +32 -0
  938. package/dist/upload-attempts-DPFC4COv.mjs.map +1 -0
  939. package/dist/url-pattern-QATUE_rv.mjs +41 -0
  940. package/dist/url-pattern-QATUE_rv.mjs.map +1 -0
  941. package/dist/user-BlCTKVAm.mjs +171 -0
  942. package/dist/user-BlCTKVAm.mjs.map +1 -0
  943. package/dist/utils-TPt7w2cS.mjs +442 -0
  944. package/dist/utils-TPt7w2cS.mjs.map +1 -0
  945. package/dist/validate-DxYhJQA-.mjs +524 -0
  946. package/dist/validate-DxYhJQA-.mjs.map +1 -0
  947. package/dist/validate-emKxGC5F.d.mts +468 -0
  948. package/dist/validate-emKxGC5F.d.mts.map +1 -0
  949. package/dist/validation-Ckq4vsVg.mjs +220 -0
  950. package/dist/validation-Ckq4vsVg.mjs.map +1 -0
  951. package/dist/version-BZj18Q7G.mjs +9 -0
  952. package/dist/version-BZj18Q7G.mjs.map +1 -0
  953. package/dist/version-DHmGpcch.mjs +7 -0
  954. package/dist/version-DHmGpcch.mjs.map +1 -0
  955. package/dist/video-DytCnw3L.mjs +54 -0
  956. package/dist/video-DytCnw3L.mjs.map +1 -0
  957. package/dist/virtual-modules-DO954n7P.mjs +515 -0
  958. package/dist/virtual-modules-DO954n7P.mjs.map +1 -0
  959. package/dist/widgets-DA5XmvVC.mjs +121 -0
  960. package/dist/widgets-DA5XmvVC.mjs.map +1 -0
  961. package/dist/wxr-taxonomies-CrMonejI.d.mts +34 -0
  962. package/dist/wxr-taxonomies-CrMonejI.d.mts.map +1 -0
  963. package/dist/wxr-taxonomies-RgRG0d5e.mjs +453 -0
  964. package/dist/wxr-taxonomies-RgRG0d5e.mjs.map +1 -0
  965. package/dist/zod-generator-D0JKy94C.mjs +424 -0
  966. package/dist/zod-generator-D0JKy94C.mjs.map +1 -0
  967. package/package.json +15 -11
  968. package/src/api/authorize.ts +42 -0
  969. package/src/api/errors.ts +9 -0
  970. package/src/api/handlers/api-tokens.ts +12 -6
  971. package/src/api/handlers/content.ts +57 -8
  972. package/src/api/handlers/dashboard.ts +33 -10
  973. package/src/api/handlers/domain-move-notice.ts +94 -0
  974. package/src/api/handlers/index.ts +2 -0
  975. package/src/api/handlers/manifest.ts +6 -0
  976. package/src/api/handlers/media-usage.ts +2 -1
  977. package/src/api/handlers/media.ts +1 -0
  978. package/src/api/handlers/plugins.ts +1 -0
  979. package/src/api/handlers/revision.ts +6 -2
  980. package/src/api/handlers/seo.ts +155 -59
  981. package/src/api/handlers/settings.ts +31 -1
  982. package/src/api/handlers/site-domain.ts +159 -0
  983. package/src/api/openapi/document.ts +2 -2
  984. package/src/api/public-url.ts +1 -1
  985. package/src/api/schemas/content.ts +20 -0
  986. package/src/api/schemas/media-usage.ts +7 -1
  987. package/src/api/schemas/media.ts +12 -0
  988. package/src/api/schemas/settings.ts +2 -0
  989. package/src/api/site-url.ts +53 -5
  990. package/src/api/types.ts +4 -0
  991. package/src/astro/image-endpoint.ts +46 -4
  992. package/src/astro/integration/admin-locales.ts +168 -0
  993. package/src/astro/integration/dev-env.ts +84 -0
  994. package/src/astro/integration/dev-scheduler-bridge.ts +91 -0
  995. package/src/astro/integration/index.ts +97 -10
  996. package/src/astro/integration/routes.ts +28 -0
  997. package/src/astro/integration/runtime.ts +17 -1
  998. package/src/astro/integration/virtual-modules.ts +9 -16
  999. package/src/astro/integration/vite-config.ts +22 -16
  1000. package/src/astro/middleware/auth.ts +19 -4
  1001. package/src/astro/middleware/csp.ts +1 -0
  1002. package/src/astro/middleware/redirect.ts +94 -50
  1003. package/src/astro/middleware/request-context.ts +12 -6
  1004. package/src/astro/middleware.ts +71 -17
  1005. package/src/astro/prefetch.ts +7 -5
  1006. package/src/astro/public-plugin-api-routes.ts +10 -2
  1007. package/src/astro/routes/api/admin/plugins/registry/artifact.ts +1 -1
  1008. package/src/astro/routes/api/auth/handover.ts +58 -0
  1009. package/src/astro/routes/api/auth/magic-link/verify.ts +11 -3
  1010. package/src/astro/routes/api/auth/passkey/options.ts +10 -2
  1011. package/src/astro/routes/api/content/[collection]/[id]/discard-draft.ts +2 -1
  1012. package/src/astro/routes/api/content/[collection]/[id]/duplicate.ts +1 -5
  1013. package/src/astro/routes/api/content/[collection]/[id]/lock.ts +2 -2
  1014. package/src/astro/routes/api/content/[collection]/[id]/permanent.ts +2 -1
  1015. package/src/astro/routes/api/content/[collection]/[id]/publish.ts +2 -1
  1016. package/src/astro/routes/api/content/[collection]/[id]/restore.ts +2 -1
  1017. package/src/astro/routes/api/content/[collection]/[id]/schedule.ts +3 -2
  1018. package/src/astro/routes/api/content/[collection]/[id]/terms/[taxonomy].ts +5 -4
  1019. package/src/astro/routes/api/content/[collection]/[id]/unpublish.ts +2 -1
  1020. package/src/astro/routes/api/content/[collection]/[id].ts +18 -6
  1021. package/src/astro/routes/api/content/[collection]/index.ts +1 -5
  1022. package/src/astro/routes/api/dashboard.ts +4 -1
  1023. package/src/astro/routes/api/dev/scheduled-tasks.ts +20 -0
  1024. package/src/astro/routes/api/import/wordpress/analyze.ts +1 -16
  1025. package/src/astro/routes/api/import/wordpress/execute.ts +27 -3
  1026. package/src/astro/routes/api/import/wordpress/rewrite-url-helpers.ts +80 -42
  1027. package/src/astro/routes/api/import/wordpress-plugin/analyze.ts +4 -1
  1028. package/src/astro/routes/api/import/wordpress-plugin/execute.ts +49 -5
  1029. package/src/astro/routes/api/manifest.ts +10 -0
  1030. package/src/astro/routes/api/media/[id]/confirm.ts +19 -0
  1031. package/src/astro/routes/api/media/file/[...key].ts +60 -12
  1032. package/src/astro/routes/api/media/upload-url.ts +28 -4
  1033. package/src/astro/routes/api/media.ts +15 -0
  1034. package/src/astro/routes/api/menus/[name]/items/[id].ts +3 -2
  1035. package/src/astro/routes/api/menus/[name]/items.ts +2 -1
  1036. package/src/astro/routes/api/menus/[name]/reorder.ts +2 -1
  1037. package/src/astro/routes/api/menus/[name]/translations.ts +2 -1
  1038. package/src/astro/routes/api/menus/[name].ts +3 -2
  1039. package/src/astro/routes/api/menus/index.ts +2 -1
  1040. package/src/astro/routes/api/redirects/[id].ts +15 -2
  1041. package/src/astro/routes/api/redirects/index.ts +5 -1
  1042. package/src/astro/routes/api/schema/index.ts +1 -1
  1043. package/src/astro/routes/api/settings/domain-notify.ts +76 -0
  1044. package/src/astro/routes/api/settings/domain.ts +64 -0
  1045. package/src/astro/routes/api/settings.ts +2 -1
  1046. package/src/astro/routes/api/setup/admin-verify.ts +7 -1
  1047. package/src/astro/routes/api/setup/index.ts +7 -0
  1048. package/src/astro/routes/api/site/domain-proof.ts +28 -0
  1049. package/src/astro/routes/api/taxonomies/[name]/reorder.ts +2 -1
  1050. package/src/astro/routes/api/taxonomies/[name]/terms/[slug]/translations.ts +2 -1
  1051. package/src/astro/routes/api/taxonomies/[name]/terms/[slug].ts +3 -2
  1052. package/src/astro/routes/api/taxonomies/[name]/terms/index.ts +2 -1
  1053. package/src/astro/routes/api/taxonomies/[name].ts +3 -2
  1054. package/src/astro/routes/api/taxonomies/index.ts +2 -1
  1055. package/src/astro/routes/api/widget-areas/[name]/reorder.ts +2 -1
  1056. package/src/astro/routes/api/widget-areas/[name]/widgets/[id].ts +3 -2
  1057. package/src/astro/routes/api/widget-areas/[name]/widgets.ts +2 -1
  1058. package/src/astro/routes/api/widget-areas/[name].ts +2 -1
  1059. package/src/astro/routes/api/widget-areas/index.ts +2 -1
  1060. package/src/astro/routes/robots.txt.ts +33 -2
  1061. package/src/astro/routes/sitemap-[collection].xml.ts +31 -8
  1062. package/src/astro/routes/sitemap.xml.ts +12 -10
  1063. package/src/astro/types.ts +23 -2
  1064. package/src/auth/rate-limit.ts +18 -13
  1065. package/src/auth/types.ts +11 -4
  1066. package/src/aws-sdk.d.ts +2 -1
  1067. package/src/cache/redirect-paths.ts +56 -0
  1068. package/src/cache/route-cache.ts +22 -0
  1069. package/src/cleanup.ts +26 -0
  1070. package/src/cli/commands/export-seed.ts +2 -0
  1071. package/src/cli/commands/import/wordpress.ts +3 -27
  1072. package/src/cli/commands/login.ts +35 -43
  1073. package/src/cli/commands/migrate.ts +36 -4
  1074. package/src/cli/commands/seed.ts +23 -12
  1075. package/src/cli/wxr/parser.ts +2 -2
  1076. package/src/client/index.ts +18 -3
  1077. package/src/client/portable-text.ts +21 -7
  1078. package/src/comments/public-submission.ts +15 -8
  1079. package/src/comments/query.ts +8 -2
  1080. package/src/components/CommentForm.astro +50 -10
  1081. package/src/components/Comments.astro +51 -29
  1082. package/src/components/EmDashImage.astro +6 -4
  1083. package/src/components/Gallery.astro +4 -3
  1084. package/src/components/Image.astro +4 -3
  1085. package/src/components/InlinePortableTextEditor.tsx +269 -1320
  1086. package/src/components/Video.astro +100 -0
  1087. package/src/components/index.ts +4 -1
  1088. package/src/components/inline-block-types.ts +278 -0
  1089. package/src/components/inline-bubble-menu.tsx +696 -0
  1090. package/src/components/inline-code-block.tsx +8 -0
  1091. package/src/components/inline-editor-ui.tsx +1192 -0
  1092. package/src/components/inline-image.tsx +722 -0
  1093. package/src/components/inline-media-picker.tsx +1221 -0
  1094. package/src/components/inline-slash-menu.tsx +556 -0
  1095. package/src/components/webmcp-search.ts +15 -19
  1096. package/src/components/widgets/RecentPosts.astro +57 -17
  1097. package/src/content/converters/mark-safety.ts +3 -3
  1098. package/src/content/converters/portable-text-identity.ts +1 -0
  1099. package/src/content/converters/portable-text-to-prosemirror.ts +7 -0
  1100. package/src/content/converters/prosemirror-to-portable-text.ts +16 -0
  1101. package/src/content/converters/types.ts +22 -0
  1102. package/src/content/converters/video.ts +77 -0
  1103. package/src/database/collection-cleanup.ts +30 -0
  1104. package/src/database/datetime-storage.ts +337 -60
  1105. package/src/database/migration-lock.ts +43 -7
  1106. package/src/database/migrations/runner.ts +13 -1
  1107. package/src/database/repositories/comment.ts +17 -3
  1108. package/src/database/repositories/content.ts +25 -4
  1109. package/src/database/repositories/plugin-storage.ts +137 -27
  1110. package/src/database/repositories/redirect.ts +24 -2
  1111. package/src/database/repositories/revision.ts +24 -6
  1112. package/src/database/repositories/taxonomy.ts +61 -46
  1113. package/src/database/repositories/types.ts +67 -7
  1114. package/src/emdash-runtime.ts +393 -228
  1115. package/src/import/index.ts +1 -0
  1116. package/src/import/registry.ts +17 -0
  1117. package/src/import/sources/wordpress-plugin.ts +154 -11
  1118. package/src/import/types.ts +3 -0
  1119. package/src/import/utils.ts +7 -3
  1120. package/src/index.ts +3 -0
  1121. package/src/loader.ts +170 -45
  1122. package/src/mcp/json-schema.ts +14 -0
  1123. package/src/mcp/plugin-tool-name.ts +36 -0
  1124. package/src/mcp/server.ts +74 -15
  1125. package/src/media/image-endpoint.ts +101 -1
  1126. package/src/media/responsive.ts +14 -7
  1127. package/src/media/usage/collection-deletion.ts +4 -0
  1128. package/src/media/usage/extractor.ts +19 -2
  1129. package/src/media/usage/types.ts +5 -1
  1130. package/src/migrations/direct-executor.ts +42 -12
  1131. package/src/migrations/protocol.ts +6 -2
  1132. package/src/plugin-utils.ts +1 -1
  1133. package/src/plugins/adapt-sandbox-entry.ts +16 -6
  1134. package/src/plugins/context.ts +3 -7
  1135. package/src/plugins/hooks.ts +1 -1
  1136. package/src/plugins/http-route-dispatch.ts +5 -1
  1137. package/src/plugins/manifest-schema.ts +1 -0
  1138. package/src/plugins/route-error.ts +14 -0
  1139. package/src/plugins/routes.ts +2 -2
  1140. package/src/plugins/state.ts +41 -8
  1141. package/src/plugins/types.ts +6 -0
  1142. package/src/query.ts +59 -10
  1143. package/src/redirects/cache.ts +34 -2
  1144. package/src/redirects/patterns.ts +26 -2
  1145. package/src/schema/block-values.ts +80 -17
  1146. package/src/schema/registry.ts +16 -5
  1147. package/src/schema/slug.ts +19 -0
  1148. package/src/search/query.ts +3 -1
  1149. package/src/search/text-extraction.ts +6 -1
  1150. package/src/seed/apply.ts +32 -8
  1151. package/src/seed/validate.ts +31 -0
  1152. package/src/seo/sitemap-name.ts +22 -0
  1153. package/src/settings/index.ts +20 -0
  1154. package/src/settings/types.ts +2 -0
  1155. package/src/storage/index.ts +2 -0
  1156. package/src/storage/local.ts +10 -2
  1157. package/src/storage/range.ts +54 -0
  1158. package/src/storage/s3.ts +52 -8
  1159. package/src/storage/types.ts +30 -3
  1160. package/src/ui.ts +1 -0
  1161. package/src/utils/slugify.ts +6 -1
  1162. package/src/visual-editing/toolbar.ts +126 -47
  1163. package/src/widgets/components.ts +4 -0
  1164. package/src/widgets/index.ts +74 -82
  1165. package/src/widgets/recent-posts.ts +62 -0
  1166. package/dist/action-token-AgOs1UWD.mjs +0 -26
  1167. package/dist/action-token-AgOs1UWD.mjs.map +0 -1
  1168. package/dist/activation-xomsCMJg.mjs +0 -387
  1169. package/dist/activation-xomsCMJg.mjs.map +0 -1
  1170. package/dist/adapters-DM1oyHIN.d.mts +0 -173
  1171. package/dist/adapters-DM1oyHIN.d.mts.map +0 -1
  1172. package/dist/allowed-origins-CFtudhyw.mjs +0 -116
  1173. package/dist/allowed-origins-CFtudhyw.mjs.map +0 -1
  1174. package/dist/api-CltsXhiX.mjs +0 -4980
  1175. package/dist/api-CltsXhiX.mjs.map +0 -1
  1176. package/dist/api-tokens-P3mAaQgr.mjs +0 -166
  1177. package/dist/api-tokens-P3mAaQgr.mjs.map +0 -1
  1178. package/dist/apply-Q7uvzBWW.mjs +0 -1680
  1179. package/dist/apply-Q7uvzBWW.mjs.map +0 -1
  1180. package/dist/approvals-DycwI6lZ.mjs +0 -460
  1181. package/dist/approvals-DycwI6lZ.mjs.map +0 -1
  1182. package/dist/artifact-fetch-CWxyELVI.mjs +0 -659
  1183. package/dist/artifact-fetch-CWxyELVI.mjs.map +0 -1
  1184. package/dist/artifacts-UzWbysb8.mjs +0 -307
  1185. package/dist/artifacts-UzWbysb8.mjs.map +0 -1
  1186. package/dist/audit-CCH3MA4Y.mjs +0 -127
  1187. package/dist/audit-CCH3MA4Y.mjs.map +0 -1
  1188. package/dist/authoritative-records-dSvXCfzb.mjs +0 -5172
  1189. package/dist/authoritative-records-dSvXCfzb.mjs.map +0 -1
  1190. package/dist/authorize-DeWfk--K.mjs +0 -49
  1191. package/dist/authorize-DeWfk--K.mjs.map +0 -1
  1192. package/dist/backup-CFnbdTSJ.mjs +0 -246
  1193. package/dist/backup-CFnbdTSJ.mjs.map +0 -1
  1194. package/dist/block-types-C0YFSfR7.mjs +0 -132
  1195. package/dist/block-types-C0YFSfR7.mjs.map +0 -1
  1196. package/dist/block-values-H4E0XwE8.mjs +0 -175
  1197. package/dist/block-values-H4E0XwE8.mjs.map +0 -1
  1198. package/dist/byline-BhVslYLz.mjs +0 -909
  1199. package/dist/byline-BhVslYLz.mjs.map +0 -1
  1200. package/dist/byline-fields-DHJs0Mja.mjs +0 -280
  1201. package/dist/byline-fields-DHJs0Mja.mjs.map +0 -1
  1202. package/dist/byline-fields-xdxE9kxZ.mjs +0 -123
  1203. package/dist/byline-fields-xdxE9kxZ.mjs.map +0 -1
  1204. package/dist/bylines-B_nN9liM.mjs +0 -234
  1205. package/dist/bylines-B_nN9liM.mjs.map +0 -1
  1206. package/dist/bylines-C71YACkL.mjs +0 -150
  1207. package/dist/bylines-C71YACkL.mjs.map +0 -1
  1208. package/dist/cache-aTYCL9nK.mjs +0 -133
  1209. package/dist/cache-aTYCL9nK.mjs.map +0 -1
  1210. package/dist/canonical-Y1dpjCnp.mjs +0 -174
  1211. package/dist/canonical-Y1dpjCnp.mjs.map +0 -1
  1212. package/dist/capture-triggers-C9JKoIdT.mjs +0 -362
  1213. package/dist/capture-triggers-C9JKoIdT.mjs.map +0 -1
  1214. package/dist/challenge-store-CxZxPqaw.mjs +0 -51
  1215. package/dist/challenge-store-CxZxPqaw.mjs.map +0 -1
  1216. package/dist/checksum-DtH6m5uk.mjs +0 -162
  1217. package/dist/checksum-DtH6m5uk.mjs.map +0 -1
  1218. package/dist/chunks-zlGB5IQP.mjs +0 -25
  1219. package/dist/chunks-zlGB5IQP.mjs.map +0 -1
  1220. package/dist/collection-slugs-cache-B2Gs9Jwx.mjs +0 -85
  1221. package/dist/collection-slugs-cache-B2Gs9Jwx.mjs.map +0 -1
  1222. package/dist/comment-Bu08Wvr3.mjs +0 -313
  1223. package/dist/comment-Bu08Wvr3.mjs.map +0 -1
  1224. package/dist/comment-reaction-B8SfT-yM.mjs +0 -85
  1225. package/dist/comment-reaction-B8SfT-yM.mjs.map +0 -1
  1226. package/dist/comments-BRtp992B.mjs +0 -99
  1227. package/dist/comments-BRtp992B.mjs.map +0 -1
  1228. package/dist/comments-DVUYqdyC.mjs +0 -195
  1229. package/dist/comments-DVUYqdyC.mjs.map +0 -1
  1230. package/dist/components-CQY-Sgm-.mjs +0 -108
  1231. package/dist/components-CQY-Sgm-.mjs.map +0 -1
  1232. package/dist/config-B-uePMLj.d.mts +0 -39
  1233. package/dist/config-B-uePMLj.d.mts.map +0 -1
  1234. package/dist/config-B6BDSsz2.d.mts +0 -6712
  1235. package/dist/config-B6BDSsz2.d.mts.map +0 -1
  1236. package/dist/config-BsJHiQxC.mjs +0 -228
  1237. package/dist/config-BsJHiQxC.mjs.map +0 -1
  1238. package/dist/connection-B9pIasFd.mjs +0 -36
  1239. package/dist/connection-B9pIasFd.mjs.map +0 -1
  1240. package/dist/content-Dji9vEiW.mjs +0 -2063
  1241. package/dist/content-Dji9vEiW.mjs.map +0 -1
  1242. package/dist/content-list-query-DiNwyKtd.d.mts +0 -26
  1243. package/dist/content-list-query-DiNwyKtd.d.mts.map +0 -1
  1244. package/dist/content-repair-B7wnbzhN.mjs +0 -442
  1245. package/dist/content-repair-B7wnbzhN.mjs.map +0 -1
  1246. package/dist/context-Ctcxc8Ia.mjs +0 -2026
  1247. package/dist/context-Ctcxc8Ia.mjs.map +0 -1
  1248. package/dist/credits-Bu7dlobo.mjs +0 -110
  1249. package/dist/credits-Bu7dlobo.mjs.map +0 -1
  1250. package/dist/cron-xe5XKqA-.mjs +0 -306
  1251. package/dist/cron-xe5XKqA-.mjs.map +0 -1
  1252. package/dist/dashboard-B5hVHOtf.mjs +0 -151
  1253. package/dist/dashboard-B5hVHOtf.mjs.map +0 -1
  1254. package/dist/default-DaoYyFRS.mjs +0 -81
  1255. package/dist/default-DaoYyFRS.mjs.map +0 -1
  1256. package/dist/deferred-tasks-BYcDx2o_.d.mts +0 -9
  1257. package/dist/deferred-tasks-BYcDx2o_.d.mts.map +0 -1
  1258. package/dist/dev-typegen-Dtl8AfS6.mjs +0 -29
  1259. package/dist/dev-typegen-Dtl8AfS6.mjs.map +0 -1
  1260. package/dist/device-flow-Ma5P5d2e.mjs +0 -521
  1261. package/dist/device-flow-Ma5P5d2e.mjs.map +0 -1
  1262. package/dist/digest-xIpR3o64.mjs +0 -194
  1263. package/dist/digest-xIpR3o64.mjs.map +0 -1
  1264. package/dist/direct-executor-DMWwCey3.mjs +0 -104
  1265. package/dist/direct-executor-DMWwCey3.mjs.map +0 -1
  1266. package/dist/email-console-DmqVF5J_.mjs +0 -50
  1267. package/dist/email-console-DmqVF5J_.mjs.map +0 -1
  1268. package/dist/email-locale-Cc5YSXfJ.mjs +0 -25
  1269. package/dist/email-locale-Cc5YSXfJ.mjs.map +0 -1
  1270. package/dist/emdash-runtime-BlybX9Ui.mjs +0 -4249
  1271. package/dist/emdash-runtime-BlybX9Ui.mjs.map +0 -1
  1272. package/dist/entry-lock-De1L8qUQ.mjs +0 -163
  1273. package/dist/entry-lock-De1L8qUQ.mjs.map +0 -1
  1274. package/dist/entry-lock-esmMbgI9.d.mts +0 -4551
  1275. package/dist/entry-lock-esmMbgI9.d.mts.map +0 -1
  1276. package/dist/entry-lock-sxz2PGAT.mjs +0 -1197
  1277. package/dist/entry-lock-sxz2PGAT.mjs.map +0 -1
  1278. package/dist/env-types-BkjCtN13.mjs +0 -38
  1279. package/dist/env-types-BkjCtN13.mjs.map +0 -1
  1280. package/dist/error-B0rgPgsQ.mjs +0 -90
  1281. package/dist/error-B0rgPgsQ.mjs.map +0 -1
  1282. package/dist/errors-CuHQRiBW.mjs +0 -120
  1283. package/dist/errors-CuHQRiBW.mjs.map +0 -1
  1284. package/dist/errors-DTE6C3K_.mjs +0 -470
  1285. package/dist/errors-DTE6C3K_.mjs.map +0 -1
  1286. package/dist/escape-nJW7dR0s.mjs +0 -9
  1287. package/dist/escape-nJW7dR0s.mjs.map +0 -1
  1288. package/dist/fence-CGw57S4v.mjs +0 -162
  1289. package/dist/fence-CGw57S4v.mjs.map +0 -1
  1290. package/dist/field-defs-cache-Bw8w499w.mjs +0 -77
  1291. package/dist/field-defs-cache-Bw8w499w.mjs.map +0 -1
  1292. package/dist/field-map-hn-D-SyH.mjs +0 -83
  1293. package/dist/field-map-hn-D-SyH.mjs.map +0 -1
  1294. package/dist/fts-manager-DacCYIe4.mjs +0 -443
  1295. package/dist/fts-manager-DacCYIe4.mjs.map +0 -1
  1296. package/dist/gc-BBplHrv6.mjs +0 -75
  1297. package/dist/gc-BBplHrv6.mjs.map +0 -1
  1298. package/dist/hash-C4DFoJ7Z.mjs +0 -37
  1299. package/dist/hash-C4DFoJ7Z.mjs.map +0 -1
  1300. package/dist/hook-result-DSRRxu_-.d.mts +0 -31
  1301. package/dist/hook-result-DSRRxu_-.d.mts.map +0 -1
  1302. package/dist/hreflang-CKPunvU0.mjs +0 -105
  1303. package/dist/hreflang-CKPunvU0.mjs.map +0 -1
  1304. package/dist/hreflang-egumj6WF.d.mts +0 -50
  1305. package/dist/hreflang-egumj6WF.d.mts.map +0 -1
  1306. package/dist/http-route-dispatch-DjNFZcJ2.mjs +0 -339
  1307. package/dist/http-route-dispatch-DjNFZcJ2.mjs.map +0 -1
  1308. package/dist/identity-Dfrx2_Bc.mjs +0 -35
  1309. package/dist/identity-Dfrx2_Bc.mjs.map +0 -1
  1310. package/dist/import-ROBvhbNc.mjs +0 -2021
  1311. package/dist/import-ROBvhbNc.mjs.map +0 -1
  1312. package/dist/index-B4sIdCAT.d.mts +0 -623
  1313. package/dist/index-B4sIdCAT.d.mts.map +0 -1
  1314. package/dist/install-finalization-CPM7Gged.mjs +0 -58
  1315. package/dist/install-finalization-CPM7Gged.mjs.map +0 -1
  1316. package/dist/keys-DxqxcAD4.mjs +0 -61
  1317. package/dist/keys-DxqxcAD4.mjs.map +0 -1
  1318. package/dist/kinds-BQl5gN6e.mjs +0 -974
  1319. package/dist/kinds-BQl5gN6e.mjs.map +0 -1
  1320. package/dist/lifecycle-DGQI7itS.mjs +0 -25
  1321. package/dist/lifecycle-DGQI7itS.mjs.map +0 -1
  1322. package/dist/load-DMxRl4VK.mjs +0 -28
  1323. package/dist/load-DMxRl4VK.mjs.map +0 -1
  1324. package/dist/loader-1DMiOq5s.mjs +0 -1303
  1325. package/dist/loader-1DMiOq5s.mjs.map +0 -1
  1326. package/dist/loops-Dn1i16FP.mjs +0 -205
  1327. package/dist/loops-Dn1i16FP.mjs.map +0 -1
  1328. package/dist/manifest-builder-CTw4FmZk.mjs +0 -189
  1329. package/dist/manifest-builder-CTw4FmZk.mjs.map +0 -1
  1330. package/dist/manifest-schema-gy37bD_D.mjs +0 -496
  1331. package/dist/manifest-schema-gy37bD_D.mjs.map +0 -1
  1332. package/dist/marketplace-tHWSsCUo.mjs +0 -257
  1333. package/dist/marketplace-tHWSsCUo.mjs.map +0 -1
  1334. package/dist/media-Bw-Q65ve.mjs +0 -294
  1335. package/dist/media-Bw-Q65ve.mjs.map +0 -1
  1336. package/dist/media-BzUDu7nl.mjs +0 -373
  1337. package/dist/media-BzUDu7nl.mjs.map +0 -1
  1338. package/dist/media-aahnKHze.mjs +0 -408
  1339. package/dist/media-aahnKHze.mjs.map +0 -1
  1340. package/dist/media-allowlist-RMrjo8TU.mjs +0 -45
  1341. package/dist/media-allowlist-RMrjo8TU.mjs.map +0 -1
  1342. package/dist/media-folders-kabR1oJf.mjs +0 -210
  1343. package/dist/media-folders-kabR1oJf.mjs.map +0 -1
  1344. package/dist/media-url-DloW2xrP.mjs +0 -43
  1345. package/dist/media-url-DloW2xrP.mjs.map +0 -1
  1346. package/dist/media-usage-CHHpV7ee.mjs +0 -282
  1347. package/dist/media-usage-CHHpV7ee.mjs.map +0 -1
  1348. package/dist/media-usage-activation-BinYqC_r.mjs +0 -78
  1349. package/dist/media-usage-activation-BinYqC_r.mjs.map +0 -1
  1350. package/dist/media-usage-work-C734aq6s.mjs +0 -1015
  1351. package/dist/media-usage-work-C734aq6s.mjs.map +0 -1
  1352. package/dist/media-usage-work-lxvV0-UO.mjs +0 -151
  1353. package/dist/media-usage-work-lxvV0-UO.mjs.map +0 -1
  1354. package/dist/menus-6RHNq4ZK.mjs +0 -753
  1355. package/dist/menus-6RHNq4ZK.mjs.map +0 -1
  1356. package/dist/menus-AuCTaO9W.mjs +0 -3704
  1357. package/dist/menus-AuCTaO9W.mjs.map +0 -1
  1358. package/dist/menus-BQKqf0Up.mjs +0 -92
  1359. package/dist/menus-BQKqf0Up.mjs.map +0 -1
  1360. package/dist/mode-nh0ppSX5.mjs +0 -23
  1361. package/dist/mode-nh0ppSX5.mjs.map +0 -1
  1362. package/dist/node-sqlite-compat-CDOEcc97.mjs +0 -63
  1363. package/dist/node-sqlite-compat-CDOEcc97.mjs.map +0 -1
  1364. package/dist/oauth-authorization-BtYQ80uU.mjs +0 -274
  1365. package/dist/oauth-authorization-BtYQ80uU.mjs.map +0 -1
  1366. package/dist/oauth-clients-C1S4NQHh.mjs +0 -266
  1367. package/dist/oauth-clients-C1S4NQHh.mjs.map +0 -1
  1368. package/dist/oauth-state-store-CpGi2FZH.mjs +0 -50
  1369. package/dist/oauth-state-store-CpGi2FZH.mjs.map +0 -1
  1370. package/dist/oauth-user-lookup-BNp1aFAr.mjs +0 -26
  1371. package/dist/oauth-user-lookup-BNp1aFAr.mjs.map +0 -1
  1372. package/dist/options-B41aLm1I.d.mts +0 -81
  1373. package/dist/options-B41aLm1I.d.mts.map +0 -1
  1374. package/dist/ownership-DoeAIuTg.mjs +0 -12
  1375. package/dist/ownership-DoeAIuTg.mjs.map +0 -1
  1376. package/dist/parse-CmFDTGzp.mjs +0 -81
  1377. package/dist/parse-CmFDTGzp.mjs.map +0 -1
  1378. package/dist/parse-QVS0t5oR.d.mts +0 -172
  1379. package/dist/parse-QVS0t5oR.d.mts.map +0 -1
  1380. package/dist/passkey-config-C-MxsV22.mjs +0 -46
  1381. package/dist/passkey-config-C-MxsV22.mjs.map +0 -1
  1382. package/dist/paths-kr8hAMMI.mjs +0 -77
  1383. package/dist/paths-kr8hAMMI.mjs.map +0 -1
  1384. package/dist/patterns-DyZJ67I7.mjs +0 -140
  1385. package/dist/patterns-DyZJ67I7.mjs.map +0 -1
  1386. package/dist/placeholder-Dn7MMdWr.d.mts +0 -306
  1387. package/dist/placeholder-Dn7MMdWr.d.mts.map +0 -1
  1388. package/dist/plan-CuQOeU9g.mjs +0 -135
  1389. package/dist/plan-CuQOeU9g.mjs.map +0 -1
  1390. package/dist/plugins-CGb-G98c.mjs +0 -261
  1391. package/dist/plugins-CGb-G98c.mjs.map +0 -1
  1392. package/dist/policy-C5wrDXYV.mjs +0 -45
  1393. package/dist/policy-C5wrDXYV.mjs.map +0 -1
  1394. package/dist/portable-text-BnRuiR1-.mjs +0 -307
  1395. package/dist/portable-text-BnRuiR1-.mjs.map +0 -1
  1396. package/dist/preview-xWNSR1Li.mjs +0 -107
  1397. package/dist/preview-xWNSR1Li.mjs.map +0 -1
  1398. package/dist/protocol-ClxN-m1e.d.mts +0 -61
  1399. package/dist/protocol-ClxN-m1e.d.mts.map +0 -1
  1400. package/dist/public-submission-CkmT2SKv.mjs +0 -250
  1401. package/dist/public-submission-CkmT2SKv.mjs.map +0 -1
  1402. package/dist/public-url-B5a0QAh6.mjs +0 -101
  1403. package/dist/public-url-B5a0QAh6.mjs.map +0 -1
  1404. package/dist/query-DHqFiqqH.mjs +0 -41
  1405. package/dist/query-DHqFiqqH.mjs.map +0 -1
  1406. package/dist/query-DT85BehD.mjs +0 -1125
  1407. package/dist/query-DT85BehD.mjs.map +0 -1
  1408. package/dist/rate-limit-iMvcu3eu.mjs +0 -120
  1409. package/dist/rate-limit-iMvcu3eu.mjs.map +0 -1
  1410. package/dist/receipt-Dpp1uaX9.mjs +0 -43
  1411. package/dist/receipt-Dpp1uaX9.mjs.map +0 -1
  1412. package/dist/redirect-BRoLiWQE.mjs +0 -19
  1413. package/dist/redirect-BRoLiWQE.mjs.map +0 -1
  1414. package/dist/redirect-xZNpBoGp.mjs +0 -417
  1415. package/dist/redirect-xZNpBoGp.mjs.map +0 -1
  1416. package/dist/redirects-D4EWeXAo.mjs +0 -148
  1417. package/dist/redirects-D4EWeXAo.mjs.map +0 -1
  1418. package/dist/redirects-DCKqwiWp.mjs +0 -446
  1419. package/dist/redirects-DCKqwiWp.mjs.map +0 -1
  1420. package/dist/registry-DaXmUsD4.mjs +0 -8369
  1421. package/dist/registry-DaXmUsD4.mjs.map +0 -1
  1422. package/dist/relations-JvBP8nGP.mjs +0 -776
  1423. package/dist/relations-JvBP8nGP.mjs.map +0 -1
  1424. package/dist/request-meta-B6blULFY.mjs +0 -141
  1425. package/dist/request-meta-B6blULFY.mjs.map +0 -1
  1426. package/dist/resolve-DAhHi5tn.mjs +0 -100
  1427. package/dist/resolve-DAhHi5tn.mjs.map +0 -1
  1428. package/dist/revision-BWEH2qQB.mjs +0 -368
  1429. package/dist/revision-BWEH2qQB.mjs.map +0 -1
  1430. package/dist/route-wire-DK600v4u.mjs +0 -197
  1431. package/dist/route-wire-DK600v4u.mjs.map +0 -1
  1432. package/dist/routes-BeZyaCzv.mjs +0 -272
  1433. package/dist/routes-BeZyaCzv.mjs.map +0 -1
  1434. package/dist/runner-CskI4Hmq.mjs +0 -6372
  1435. package/dist/runner-CskI4Hmq.mjs.map +0 -1
  1436. package/dist/runner-J3Cj6DGk.d.mts +0 -68
  1437. package/dist/runner-J3Cj6DGk.d.mts.map +0 -1
  1438. package/dist/schema-CK0ihqMR.mjs +0 -815
  1439. package/dist/schema-CK0ihqMR.mjs.map +0 -1
  1440. package/dist/schema-VtaZSrC-.mjs +0 -13
  1441. package/dist/schema-VtaZSrC-.mjs.map +0 -1
  1442. package/dist/scopes-BRnGlL9t.mjs +0 -34
  1443. package/dist/scopes-BRnGlL9t.mjs.map +0 -1
  1444. package/dist/search-D6-XK1Sn.mjs +0 -448
  1445. package/dist/search-D6-XK1Sn.mjs.map +0 -1
  1446. package/dist/sections-CBDCf7qR.mjs +0 -346
  1447. package/dist/sections-CBDCf7qR.mjs.map +0 -1
  1448. package/dist/seo-BdeEPDNW.mjs +0 -133
  1449. package/dist/seo-BdeEPDNW.mjs.map +0 -1
  1450. package/dist/seo-C61bnPuV.mjs +0 -114
  1451. package/dist/seo-C61bnPuV.mjs.map +0 -1
  1452. package/dist/service-BuRKLMxa.mjs +0 -150
  1453. package/dist/service-BuRKLMxa.mjs.map +0 -1
  1454. package/dist/session-user-CqkPtrPL.mjs +0 -61
  1455. package/dist/session-user-CqkPtrPL.mjs.map +0 -1
  1456. package/dist/settings-0u0lTthS.mjs +0 -51
  1457. package/dist/settings-0u0lTthS.mjs.map +0 -1
  1458. package/dist/settings-WHr45II1.mjs +0 -61
  1459. package/dist/settings-WHr45II1.mjs.map +0 -1
  1460. package/dist/settings-m5tIYnF0.mjs +0 -443
  1461. package/dist/settings-m5tIYnF0.mjs.map +0 -1
  1462. package/dist/setup-complete-B2_dhZZz.mjs +0 -65
  1463. package/dist/setup-complete-B2_dhZZz.mjs.map +0 -1
  1464. package/dist/setup-nonce-CJV9ftSK.mjs +0 -25
  1465. package/dist/setup-nonce-CJV9ftSK.mjs.map +0 -1
  1466. package/dist/site-settings-KJOqJW6W.mjs +0 -50
  1467. package/dist/site-settings-KJOqJW6W.mjs.map +0 -1
  1468. package/dist/site-url-Ceq_AUK0.mjs +0 -16
  1469. package/dist/site-url-Ceq_AUK0.mjs.map +0 -1
  1470. package/dist/slugify-T5GHH42D.mjs +0 -17
  1471. package/dist/slugify-T5GHH42D.mjs.map +0 -1
  1472. package/dist/snapshot-Dzsn3NZa.mjs +0 -414
  1473. package/dist/snapshot-Dzsn3NZa.mjs.map +0 -1
  1474. package/dist/ssrf-DsmvZB80.mjs +0 -406
  1475. package/dist/ssrf-DsmvZB80.mjs.map +0 -1
  1476. package/dist/stage-Csnh_yEd.mjs +0 -662
  1477. package/dist/stage-Csnh_yEd.mjs.map +0 -1
  1478. package/dist/staged-Q7pnEVvI.mjs +0 -686
  1479. package/dist/staged-Q7pnEVvI.mjs.map +0 -1
  1480. package/dist/state-kGdOMQRY.mjs +0 -153
  1481. package/dist/state-kGdOMQRY.mjs.map +0 -1
  1482. package/dist/status-D39Fpy8R.mjs +0 -30
  1483. package/dist/status-D39Fpy8R.mjs.map +0 -1
  1484. package/dist/storage-query-C7iy6eUb.d.mts +0 -1615
  1485. package/dist/storage-query-C7iy6eUb.d.mts.map +0 -1
  1486. package/dist/tar-BWiraSUY.mjs +0 -449
  1487. package/dist/tar-BWiraSUY.mjs.map +0 -1
  1488. package/dist/target-DOFs5oUC.mjs +0 -27
  1489. package/dist/target-DOFs5oUC.mjs.map +0 -1
  1490. package/dist/taxonomies-BS40Wxvi.mjs +0 -939
  1491. package/dist/taxonomies-BS40Wxvi.mjs.map +0 -1
  1492. package/dist/taxonomies-DAZU9VDd.mjs +0 -697
  1493. package/dist/taxonomies-DAZU9VDd.mjs.map +0 -1
  1494. package/dist/taxonomy-XzLE95Vx.mjs +0 -525
  1495. package/dist/taxonomy-XzLE95Vx.mjs.map +0 -1
  1496. package/dist/tokens-DSQan4p7.mjs +0 -171
  1497. package/dist/tokens-DSQan4p7.mjs.map +0 -1
  1498. package/dist/transfer-BcCVxDgf.mjs +0 -166
  1499. package/dist/transfer-BcCVxDgf.mjs.map +0 -1
  1500. package/dist/transfer-OMrancOt.mjs +0 -8873
  1501. package/dist/transfer-OMrancOt.mjs.map +0 -1
  1502. package/dist/transfer-download-Dc-ltjZY.mjs +0 -33
  1503. package/dist/transfer-download-Dc-ltjZY.mjs.map +0 -1
  1504. package/dist/transformations-Ddx7UtrY.mjs +0 -196
  1505. package/dist/transformations-Ddx7UtrY.mjs.map +0 -1
  1506. package/dist/transport-flR-Zmds.d.mts +0 -42
  1507. package/dist/transport-flR-Zmds.d.mts.map +0 -1
  1508. package/dist/transport-umzEbgYO.mjs +0 -136
  1509. package/dist/transport-umzEbgYO.mjs.map +0 -1
  1510. package/dist/trusted-proxy-BqfQFs6a.mjs +0 -51
  1511. package/dist/trusted-proxy-BqfQFs6a.mjs.map +0 -1
  1512. package/dist/turnstile-Do60baId.mjs +0 -58
  1513. package/dist/turnstile-Do60baId.mjs.map +0 -1
  1514. package/dist/types-BT1p3uyb.d.mts +0 -1735
  1515. package/dist/types-BT1p3uyb.d.mts.map +0 -1
  1516. package/dist/types-BYaPWs_F.d.mts +0 -198
  1517. package/dist/types-BYaPWs_F.d.mts.map +0 -1
  1518. package/dist/types-C-Xp0CcN.mjs +0 -103
  1519. package/dist/types-C-Xp0CcN.mjs.map +0 -1
  1520. package/dist/types-CLTQ9b_r.d.mts +0 -374
  1521. package/dist/types-CLTQ9b_r.d.mts.map +0 -1
  1522. package/dist/types-CPkQw2T2.d.mts +0 -85
  1523. package/dist/types-CPkQw2T2.d.mts.map +0 -1
  1524. package/dist/types-CQLvuXoZ.d.mts +0 -198
  1525. package/dist/types-CQLvuXoZ.d.mts.map +0 -1
  1526. package/dist/types-CV5xszpF.d.mts +0 -363
  1527. package/dist/types-CV5xszpF.d.mts.map +0 -1
  1528. package/dist/types-CdEMurNh.mjs +0 -77
  1529. package/dist/types-CdEMurNh.mjs.map +0 -1
  1530. package/dist/types-CxwtnuSS.mjs +0 -37
  1531. package/dist/types-CxwtnuSS.mjs.map +0 -1
  1532. package/dist/types-DGw8KMX_.mjs +0 -16
  1533. package/dist/types-DGw8KMX_.mjs.map +0 -1
  1534. package/dist/types-DOfVMPoo.d.mts +0 -125
  1535. package/dist/types-DOfVMPoo.d.mts.map +0 -1
  1536. package/dist/types-LtS0SM4F.d.mts +0 -287
  1537. package/dist/types-LtS0SM4F.d.mts.map +0 -1
  1538. package/dist/types-ifgOkcBa.d.mts +0 -916
  1539. package/dist/types-ifgOkcBa.d.mts.map +0 -1
  1540. package/dist/update-check-DOc2aBIU.mjs +0 -161
  1541. package/dist/update-check-DOc2aBIU.mjs.map +0 -1
  1542. package/dist/upload-attempts-nzdc3cay.mjs +0 -32
  1543. package/dist/upload-attempts-nzdc3cay.mjs.map +0 -1
  1544. package/dist/url-pattern-hVbqpXs6.mjs +0 -41
  1545. package/dist/url-pattern-hVbqpXs6.mjs.map +0 -1
  1546. package/dist/user-Dnp53zTq.mjs +0 -171
  1547. package/dist/user-Dnp53zTq.mjs.map +0 -1
  1548. package/dist/utils-CoV-PYhg.mjs +0 -439
  1549. package/dist/utils-CoV-PYhg.mjs.map +0 -1
  1550. package/dist/validate-CfQ9_YlD.d.mts +0 -468
  1551. package/dist/validate-CfQ9_YlD.d.mts.map +0 -1
  1552. package/dist/validate-DBX3DKtL.mjs +0 -516
  1553. package/dist/validate-DBX3DKtL.mjs.map +0 -1
  1554. package/dist/validation-BJMiDhB1.mjs +0 -219
  1555. package/dist/validation-BJMiDhB1.mjs.map +0 -1
  1556. package/dist/version-BaT8yKIT.mjs +0 -7
  1557. package/dist/version-BaT8yKIT.mjs.map +0 -1
  1558. package/dist/version-BwEGkqkx.mjs +0 -9
  1559. package/dist/version-BwEGkqkx.mjs.map +0 -1
  1560. package/dist/virtual-modules-B6vJW15k.mjs +0 -516
  1561. package/dist/virtual-modules-B6vJW15k.mjs.map +0 -1
  1562. package/dist/widgets-BkxBAgZ_.mjs +0 -126
  1563. package/dist/widgets-BkxBAgZ_.mjs.map +0 -1
  1564. package/dist/wxr-taxonomies-D7gAJyOF.mjs +0 -453
  1565. package/dist/wxr-taxonomies-D7gAJyOF.mjs.map +0 -1
  1566. package/dist/wxr-taxonomies-DM5J9AsT.d.mts +0 -34
  1567. package/dist/wxr-taxonomies-DM5J9AsT.d.mts.map +0 -1
  1568. package/dist/zod-generator-BQilAboC.mjs +0 -424
  1569. package/dist/zod-generator-BQilAboC.mjs.map +0 -1
  1570. /package/dist/{api-tokens-BLz2MtQs.mjs → api-tokens-CdP49zVF.mjs} +0 -0
  1571. /package/dist/{ssrf-tA45vIPX.mjs → ssrf-DM0E-D_8.mjs} +0 -0
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types-sUHaH7lC.mjs","names":[],"sources":["../src/plugins/types.ts"],"sourcesContent":["/**\n * Plugin System Types v2\n *\n * New plugin API with:\n * - Single unified context shape for all hooks and routes\n * - Paginated storage queries (no async iterators)\n * - Unified KV API (replaces settings + options)\n * - Explicit ctx.http and ctx.log\n *\n */\n\nimport type { Permission } from \"@emdash-cms/auth\";\nimport type { ConfirmDialog, Element, PluginUiContext } from \"@emdash-cms/blocks\";\n// The plugin capability vocabulary, the legacy-rename map, and the manifest\n// shape are authored once in @emdash-cms/plugin-types and shared between core\n// (the manifest reader at install/runtime) and @emdash-cms/plugin-cli (the\n// manifest writer at bundle/publish time).\n//\n// We import-and-re-export here so existing internal callers keep working\n// (e.g. `import { PluginCapability } from \"../plugins/types.js\"`).\nimport {\n\tCAPABILITY_RENAMES,\n\tcapabilitiesToDeclaredAccess,\n\tdeclaredAccessToCapabilities,\n\tisDeprecatedCapability,\n\tnormalizeCapabilities,\n\tnormalizeCapability,\n\ttype CurrentPluginCapability,\n\ttype DeclaredAccess,\n\ttype DeprecatedPluginCapability,\n\ttype ManifestHookEntry,\n\ttype ManifestMcpTool,\n\ttype ManifestRouteEntry,\n\ttype PluginMcpManifestConfig,\n\ttype PluginCapability,\n\ttype PluginEditorDraftAccess,\n\ttype PluginEditorDraftFieldSelector,\n\ttype PluginFormData,\n\ttype PluginRouteBodyMode,\n\ttype PluginRouteQuery,\n\ttype PluginRouteRequest,\n\ttype PluginStorageConfig,\n\ttype RouteOptions,\n\ttype StorageCollectionConfig,\n} from \"@emdash-cms/plugin-types\";\nimport type { JSX } from \"astro/jsx-runtime\";\nimport type { z } from \"astro/zod\";\n// =============================================================================\n// Core Types\n// =============================================================================\n\nimport type { ContentFieldFilters } from \"../content-list-query.js\";\nimport type { FieldType, FieldValidation, FieldWidgetOptions } from \"../schema/types.js\";\n\nexport type {\n\tContentFieldFilterScalar,\n\tContentFieldFilterValue,\n\tContentFieldFilters,\n\tContentFieldInFilter,\n\tContentFieldRangeFilter,\n} from \"../content-list-query.js\";\n\nexport {\n\tCAPABILITY_RENAMES,\n\tcapabilitiesToDeclaredAccess,\n\tdeclaredAccessToCapabilities,\n\tisDeprecatedCapability,\n\tnormalizeCapabilities,\n\tnormalizeCapability,\n\ttype CurrentPluginCapability,\n\ttype DeclaredAccess,\n\ttype DeprecatedPluginCapability,\n\ttype ManifestHookEntry,\n\ttype ManifestMcpTool,\n\ttype ManifestRouteEntry,\n\ttype PluginMcpManifestConfig,\n\ttype PluginCapability,\n\ttype PluginEditorDraftAccess,\n\ttype PluginEditorDraftFieldSelector,\n\ttype PluginStorageConfig,\n\ttype StorageCollectionConfig,\n};\n\nexport const PLUGIN_CAPABILITY_IMPLICATIONS: ReadonlyArray<\n\treadonly [PluginCapability, PluginCapability]\n> = [\n\t[\"content:write\", \"content:read\"],\n\t[\"content:revisions:read\", \"content:read\"],\n\t[\"taxonomies:write\", \"taxonomies:read\"],\n\t[\"content:publish\", \"content:read\"],\n\t[\"media:write\", \"media:read\"],\n\t[\"comments:moderate\", \"comments:read\"],\n\t[\"redirects:write\", \"redirects:read\"],\n\t[\"network:request:unrestricted\", \"network:request\"],\n];\n\nexport function normalizePluginCapabilities(\n\tcapabilities: readonly PluginCapability[],\n): PluginCapability[];\nexport function normalizePluginCapabilities(capabilities: readonly string[]): string[];\nexport function normalizePluginCapabilities(capabilities: readonly string[]): string[] {\n\tconst normalized = new Set(normalizeCapabilities(capabilities));\n\tfor (const [granted, implied] of PLUGIN_CAPABILITY_IMPLICATIONS) {\n\t\tif (normalized.has(granted)) normalized.add(implied);\n\t}\n\treturn [...normalized];\n}\n\nconst WARNED_DEPRECATED_CAPABILITY_PLUGINS = Symbol.for(\n\t\"emdash:warned-deprecated-capability-plugins\",\n);\n\n/**\n * Warn, once per plugin per process, that a plugin declares deprecated\n * capability names. Call with the plugin's raw, un-normalized capabilities.\n */\nexport function warnDeprecatedPluginCapabilities(\n\tpluginId: string,\n\tcapabilities: readonly string[],\n): void {\n\tconst deprecated = capabilities.filter(isDeprecatedCapability);\n\tif (deprecated.length === 0) return;\n\n\tconst g = globalThis as Record<symbol, unknown>;\n\t// eslint-disable-next-line typescript/no-unsafe-type-assertion -- globalThis singleton pattern (see request-context.ts)\n\tconst warned = (g[WARNED_DEPRECATED_CAPABILITY_PLUGINS] ??= new Set<string>()) as Set<string>;\n\tif (warned.has(pluginId)) return;\n\twarned.add(pluginId);\n\n\tconst renames = deprecated.map((cap) => `${cap} → ${CAPABILITY_RENAMES[cap]}`).join(\", \");\n\tconsole.warn(\n\t\t`[emdash] Plugin \"${pluginId}\" declares deprecated capability names (${renames}). ` +\n\t\t\t\"They still work, but support will be removed in a future major release. \" +\n\t\t\t\"Update the plugin, or ask its author to publish a version that uses the current names.\",\n\t);\n}\n\n// =============================================================================\n// Storage Types\n// =============================================================================\n//\n// `StorageCollectionConfig` and `PluginStorageConfig` are re-exported above\n// from `@emdash-cms/plugin-types`. The manifest carries these shapes\n// verbatim; both this package (reader) and plugin-cli (writer) agree on\n// the same types via the shared package.\n\n/**\n * Query filter operators\n */\nexport interface RangeFilter {\n\tgt?: number | string;\n\tgte?: number | string;\n\tlt?: number | string;\n\tlte?: number | string;\n}\n\nexport interface InFilter {\n\tin: Array<string | number>;\n}\n\nexport interface StartsWithFilter {\n\tstartsWith: string;\n}\n\n/**\n * Where clause value types\n */\nexport type WhereValue =\n\t| string\n\t| number\n\t| boolean\n\t| null\n\t| RangeFilter\n\t| InFilter\n\t| StartsWithFilter;\n\n/**\n * Where clause for storage queries\n */\nexport type WhereClause = Record<string, WhereValue>;\n\n/**\n * Query options for storage.query()\n */\nexport interface QueryOptions {\n\twhere?: WhereClause;\n\torderBy?: Record<string, \"asc\" | \"desc\">;\n\t/** Default 50, max 100 */\n\tlimit?: number;\n\tcursor?: string;\n}\n\n/**\n * Paginated result (used by storage.query, content.list, media.list)\n */\nexport interface PaginatedResult<T> {\n\titems: T[];\n\tcursor?: string;\n\thasMore: boolean;\n}\n\nexport interface VersionedValue<T = unknown> {\n\tvalue: T;\n\t/** Opaque host revision, valid only for the key from which it was read. */\n\trevision: string;\n}\n\nexport type ConditionalWriteResult = { applied: true; revision: string } | { applied: false };\n\nexport interface ConditionalDeleteResult {\n\tapplied: boolean;\n}\n\n/**\n * A single per-field integer delta for {@link StorageCollection.updateIf}.\n *\n * `inc`/`dec` values must be safe integers, enforced at runtime with\n * `Number.isSafeInteger` (which also rejects `NaN`/`Infinity`), because a TS\n * `number` cannot forbid float literals. Deltas are applied entirely in-SQL\n * over the stored value with `COALESCE(<value>, 0) ± n`, so a delta on a\n * missing or JSON-`null` field starts from `0` (never corrupts the document).\n *\n * `updateIf` does NOT clamp: a `dec` can drive a field negative when the\n * `where` guard doesn't cover the delta magnitude (e.g. stock `2` with\n * `where: { stock: { gte: 1 } }` and `delta: { stock: { dec: 3 } }` → `-1`,\n * `applied: true`). The guard is the caller's responsibility — pair a `dec: k`\n * with a `gte: k` guard to prevent underflow.\n */\nexport type NumericDelta = { inc: number } | { dec: number };\n\n/**\n * Arguments to {@link StorageCollection.updateIf}.\n *\n * `where` reuses the {@link QueryOptions} `WhereClause` verbatim — the guard is\n * evaluated in-SQL with the same numeric-correct, total comparisons as\n * `query()`. An empty `where: {}` emits no guard, i.e. it matches the row\n * unconditionally (update-if-row-exists) — a footgun in the no-oversell case,\n * where a real predicate (e.g. `{ stock: { gte: 1 } }`) is what you want.\n *\n * At least one of `set` / `delta` must be present (a runtime error is thrown\n * otherwise). A field may not appear in both `set` and `delta` in the same\n * call. `set` and `delta` are separate arguments (not a union) so a wholesale\n * value that happens to look like `{ inc: 5 }` is never mistaken for a delta.\n */\nexport interface UpdateIfArgs<T> {\n\t/**\n\t * Guard evaluated in-SQL; identical semantics to `query({ where })`. An\n\t * empty `{}` means \"match the row unconditionally (no guard)\".\n\t */\n\twhere: WhereClause;\n\t/** Wholesale field values merged into the stored JSON document. */\n\tset?: Partial<T>;\n\t/** Per-field integer deltas applied in-SQL (`COALESCE(base, 0) ± n`). */\n\tdelta?: { [K in keyof T]?: NumericDelta };\n}\n\n/**\n * Result of {@link StorageCollection.updateIf}.\n *\n * `applied: false` intentionally conflates \"row absent\" and \"guard failed\": a\n * single-statement guarded `UPDATE` cannot distinguish them, and the caller\n * should not need to. `updateIf` is update-only — it never inserts a missing\n * row.\n */\nexport type UpdateIfResult<T> = { applied: true; data: T } | { applied: false };\n\n/**\n * Storage collection interface - the API exposed to plugins\n * No async iterators - all operations return promises with pagination\n */\nexport interface StorageCollection<T = unknown> {\n\t// Basic CRUD\n\tget(id: string): Promise<T | null>;\n\tput(id: string, data: T): Promise<void>;\n\tdelete(id: string): Promise<boolean>;\n\texists(id: string): Promise<boolean>;\n\t/** A stored JSON null returns an envelope with value: null; only an absent row returns null. */\n\tgetVersioned(id: string): Promise<VersionedValue<T> | null>;\n\t/** A null expected revision creates only when absent. Errors reject; conflicts return applied: false. */\n\tcompareAndSet(\n\t\tid: string,\n\t\texpectedRevision: string | null,\n\t\tdata: T,\n\t): Promise<ConditionalWriteResult>;\n\tcompareAndDelete(id: string, expectedRevision: string): Promise<ConditionalDeleteResult>;\n\n\t// Batch operations\n\tgetMany(ids: string[]): Promise<Map<string, T>>;\n\tputMany(items: Array<{ id: string; data: T }>): Promise<void>;\n\tdeleteMany(ids: string[]): Promise<number>;\n\n\t// Query - always paginated\n\tquery(options?: QueryOptions): Promise<PaginatedResult<{ id: string; data: T }>>;\n\tcount(where?: WhereClause): Promise<number>;\n\n\t// Conditional write (single-statement, atomic per row).\n\t/**\n\t * Predicate-guarded atomic update. Applies `set`/`delta` to the row `id`\n\t * only if it exists and the `where` guard matches, in a single guarded\n\t * `UPDATE … RETURNING`. This is the no-oversell primitive: the guard and the\n\t * arithmetic live in one statement, so N concurrent guarded decrements\n\t * serialize correctly. `applied: false` means the row was absent OR the\n\t * guard failed (the two are intentionally indistinguishable). Non-object\n\t * documents, invalid counters and unsafe arithmetic results also fail the\n\t * guard. Never inserts.\n\t *\n\t * Serialization failures and deadlocks throw `StorageSerializationError`.\n\t * Retry the write with a bounded policy; restart an explicit transaction\n\t * before retrying its operations.\n\t */\n\tupdateIf(id: string, args: UpdateIfArgs<T>): Promise<UpdateIfResult<T>>;\n}\n\n/**\n * Plugin storage context - typed based on declared collections\n */\nexport type PluginStorage<T extends PluginStorageConfig> = {\n\t[K in keyof T]: StorageCollection;\n};\n\n// =============================================================================\n// Context APIs\n// =============================================================================\n\n/**\n * Plugin-scoped key-value state.\n *\n * Convention:\n * - `state:*` - Internal plugin state (not shown to users)\n * - `cache:*` - Reusable computed or remote data\n *\n * The `settings:*` namespace remains a compatibility alias through EmDash\n * 0.x. New code uses `PluginContext.settings` for user configuration.\n */\nexport interface KVAccess {\n\tget<T>(key: string): Promise<T | null>;\n\tgetVersioned<T>(key: string): Promise<VersionedValue<T> | null>;\n\t/** A null expected revision creates only when absent. Errors reject; conflicts return applied: false. */\n\tcompareAndSet(\n\t\tkey: string,\n\t\texpectedRevision: string | null,\n\t\tvalue: unknown,\n\t): Promise<ConditionalWriteResult>;\n\tcompareAndDelete(key: string, expectedRevision: string): Promise<ConditionalDeleteResult>;\n\tset(key: string, value: unknown): Promise<void>;\n\tdelete(key: string): Promise<boolean>;\n\tlist(prefix?: string): Promise<Array<{ key: string; value: unknown }>>;\n}\n\n/** Plugin settings. Fields declared as `secret` in `admin.settingsSchema` are encrypted. */\nexport interface SettingsAccess {\n\tget<T>(key: string): Promise<T | null>;\n\tgetVersioned<T>(key: string): Promise<VersionedValue<T> | null>;\n\tcompareAndSet(\n\t\tkey: string,\n\t\texpectedRevision: string | null,\n\t\tvalue: unknown,\n\t): Promise<ConditionalWriteResult>;\n\tcompareAndDelete(key: string, expectedRevision: string): Promise<ConditionalDeleteResult>;\n\tset(key: string, value: unknown): Promise<void>;\n\tdelete(key: string): Promise<boolean>;\n\tlist(prefix?: string): Promise<Array<{ key: string; value: unknown }>>;\n}\n\n/**\n * SEO metadata for a content item, as stored in the core SEO panel.\n *\n * Only present on items in collections with `has_seo = 1`. For collections\n * without SEO enabled, `ContentItem.seo` is `undefined`.\n */\nexport interface ContentItemSeo {\n\ttitle: string | null;\n\tdescription: string | null;\n\timage: string | null;\n\tcanonical: string | null;\n\tnoIndex: boolean;\n}\n\n/**\n * SEO input accepted by content write operations.\n *\n * All fields are optional — only fields that are present overwrite existing\n * values. An empty object is treated as a no-op.\n */\nexport interface ContentItemSeoInput {\n\ttitle?: string | null;\n\tdescription?: string | null;\n\timage?: string | null;\n\tcanonical?: string | null;\n\tnoIndex?: boolean;\n}\n\n/**\n * Content item returned from content API\n */\nexport interface ContentItem {\n\tid: string;\n\ttype: string;\n\tslug: string | null;\n\tstatus: string;\n\tlocale: string | null;\n\tdata: Record<string, unknown>;\n\t/**\n\t * SEO metadata, populated when the collection has SEO enabled\n\t * (`has_seo = 1`). `undefined` for non-SEO collections.\n\t */\n\tseo?: ContentItemSeo;\n\tcreatedAt: string;\n\tupdatedAt: string;\n\tpublishedAt: string | null;\n\t/** Scheduled publication time, if set (e.g. scheduled items or scheduled draft changes). */\n\tscheduledAt?: string | null;\n\tauthorId?: string | null;\n\ttranslationGroup?: string | null;\n\tliveRevisionId?: string | null;\n\tdraftRevisionId?: string | null;\n\tversion?: number;\n}\n\nexport interface ContentTranslationSummary {\n\tid: string;\n\tlocale: string | null;\n\tslug: string | null;\n\tstatus: string;\n\tupdatedAt: string;\n}\n\nexport interface ContentRevisionInfo {\n\tid: string;\n\tcollection: string;\n\tentryId: string;\n\tdata: Record<string, unknown>;\n\tcreatedAt: string;\n}\n\nexport interface FieldSchemaInfo {\n\tslug: string;\n\tlabel: string;\n\ttype: FieldType;\n\trequired: boolean;\n\tunique: boolean;\n\tdefault?: unknown;\n\tvalidation?: FieldValidation;\n\twidget?: string;\n\toptions?: FieldWidgetOptions;\n\tsearchable: boolean;\n\tindexed: boolean;\n\ttranslatable: boolean;\n\tsortOrder: number;\n}\n\nexport interface CollectionSchemaInfo {\n\tslug: string;\n\tlabel: string;\n\tlabelSingular: string | null;\n\tdescription: string | null;\n\tsupports: string[];\n\thasSeo: boolean;\n\ttitleField: string | null;\n\tdateField: string | null;\n\turlPattern: string | null;\n\troutable: boolean;\n\thidden: boolean;\n\tfields: FieldSchemaInfo[];\n}\n\nexport interface SchemaAccess {\n\tlistCollections(): Promise<CollectionSchemaInfo[]>;\n\tgetCollection(slug: string): Promise<CollectionSchemaInfo | null>;\n}\n\nexport interface ContentListWhere {\n\t/** Exact match on `status` (e.g. `\"published\"`, `\"draft\"`). */\n\tstatus?: string;\n\t/** Exact match on `locale` (e.g. `\"en\"`, `\"fr-CA\"`). */\n\tlocale?: string;\n\t/** AND-combined filters over custom fields explicitly marked as indexed. */\n\tfieldFilters?: ContentFieldFilters;\n}\n\n/**\n * Content list options\n */\nexport interface ContentListOptions {\n\tlimit?: number;\n\tcursor?: string;\n\torderBy?: Record<string, \"asc\" | \"desc\">;\n\twhere?: ContentListWhere;\n}\n\n/**\n * Input accepted by `content.create` / `content.update`.\n *\n * Most entries are field slugs mapped to their values. The reserved `seo`\n * key is extracted and routed to the core SEO panel (the `_emdash_seo`\n * table), matching the shape accepted by the REST API. Passing `seo` for a\n * collection that does not have SEO enabled throws a validation error.\n */\nexport type ContentWriteInput = Record<string, unknown> & {\n\tseo?: ContentItemSeoInput;\n};\n\n/** Options accepted by `content.create`. */\nexport interface ContentCreateOptions {\n\t/** Locale for the new content row. Defaults to the configured site locale, then `en`. */\n\tlocale?: string;\n\t/** Existing row in the same collection whose translation group the new row joins. */\n\ttranslationOf?: string;\n}\n\nexport type PluginContentCreateCallback = (\n\tpluginId: string,\n\tcollection: string,\n\tdata: ContentWriteInput,\n\toptions?: ContentCreateOptions & {\n\t\t/** Save-hook origin supplied by sandbox transports to prevent hook re-entry. */\n\t\toriginHook?: \"content:beforeSave\" | \"content:afterSave\";\n\t\tsandboxOrigin?: true;\n\t},\n) => Promise<ContentItem>;\n\n/**\n * Taxonomy definition returned from the taxonomy API (e.g. \"category\", \"tag\").\n */\nexport interface TaxonomyDefInfo {\n\tname: string;\n\tlabel: string;\n\tlabelSingular: string | null;\n\thierarchical: boolean;\n\t/** Collections this taxonomy is attached to (e.g. `[\"posts\"]`). */\n\tcollections: string[];\n\tlocale: string;\n}\n\n/**\n * Taxonomy term returned from the taxonomy API. Flat shape — for hierarchical\n * taxonomies the tree is reconstructed via `parentId` (which stores the\n * parent's locale-agnostic `translationGroup`).\n */\nexport interface TaxonomyTermInfo {\n\tid: string;\n\t/** Taxonomy name this term belongs to (e.g. \"category\"). */\n\ttaxonomy: string;\n\tslug: string;\n\tlabel: string;\n\tparentId: string | null;\n\t/** Term metadata as edited in the admin (`description` etc.). */\n\tdata: Record<string, unknown> | null;\n\tlocale: string;\n\ttranslationGroup: string | null;\n}\n\n/**\n * Options accepted by taxonomy read operations. Omitting `locale` returns\n * rows for every locale.\n */\nexport interface TaxonomyReadOptions {\n\tlocale?: string;\n}\n\nexport interface TaxonomyTermCreateInput {\n\tlabel: string;\n\tslug?: string;\n\tparentId?: string | null;\n\tdescription?: string;\n\tlocale?: string;\n\ttranslationOf?: string;\n}\n\n/**\n * Content access interface - capability-gated\n */\nexport interface ContentAccess {\n\t// Read operations (requires read:content)\n\tget(collection: string, id: string): Promise<ContentItem | null>;\n\tlist(collection: string, options?: ContentListOptions): Promise<PaginatedResult<ContentItem>>;\n\tgetTranslations?(\n\t\tcollection: string,\n\t\tid: string,\n\t): Promise<{ translationGroup: string; translations: ContentTranslationSummary[] }>;\n\tgetPublicUrl?(collection: string, id: string): Promise<string | null>;\n\tlistRevisions?(\n\t\tcollection: string,\n\t\tid: string,\n\t\toptions?: { limit?: number },\n\t): Promise<ContentRevisionInfo[]>;\n\tgetRevision?(\n\t\tcollection: string,\n\t\tid: string,\n\t\trevisionId: string,\n\t): Promise<ContentRevisionInfo | null>;\n\n\t// Write operations (requires write:content) - optional on interface\n\tcreate?(\n\t\tcollection: string,\n\t\tdata: ContentWriteInput,\n\t\toptions?: ContentCreateOptions,\n\t): Promise<ContentItem>;\n\tupdate?(collection: string, id: string, data: ContentWriteInput): Promise<ContentItem>;\n\tdelete?(collection: string, id: string): Promise<boolean>;\n\tgetVersioned?(collection: string, id: string): Promise<VersionedContentItem | null>;\n\tpublish?(\n\t\tcollection: string,\n\t\tid: string,\n\t\toptions: { _rev: string },\n\t): Promise<VersionedContentItem>;\n\tunpublish?(\n\t\tcollection: string,\n\t\tid: string,\n\t\toptions: { _rev: string },\n\t): Promise<VersionedContentItem>;\n\tschedule?(\n\t\tcollection: string,\n\t\tid: string,\n\t\toptions: { scheduledAt: string; _rev: string },\n\t): Promise<VersionedContentItem>;\n\tunschedule?(\n\t\tcollection: string,\n\t\tid: string,\n\t\toptions: { _rev: string },\n\t): Promise<VersionedContentItem>;\n\tgetTrashedVersioned?(collection: string, id: string): Promise<VersionedContentItem | null>;\n\trestore?(\n\t\tcollection: string,\n\t\tid: string,\n\t\toptions: { _rev: string },\n\t): Promise<VersionedContentItem>;\n}\n\nexport interface VersionedContentItem {\n\titem: ContentItem;\n\t_rev: string;\n}\n\nexport interface ContentPublicationAccess extends ContentAccess {\n\tgetVersioned(collection: string, id: string): Promise<VersionedContentItem | null>;\n\tpublish(collection: string, id: string, options: { _rev: string }): Promise<VersionedContentItem>;\n\tunpublish(\n\t\tcollection: string,\n\t\tid: string,\n\t\toptions: { _rev: string },\n\t): Promise<VersionedContentItem>;\n\tschedule(\n\t\tcollection: string,\n\t\tid: string,\n\t\toptions: { scheduledAt: string; _rev: string },\n\t): Promise<VersionedContentItem>;\n\tunschedule(\n\t\tcollection: string,\n\t\tid: string,\n\t\toptions: { _rev: string },\n\t): Promise<VersionedContentItem>;\n}\n\nexport interface ContentRestoreAccess {\n\tgetTrashedVersioned(collection: string, id: string): Promise<VersionedContentItem | null>;\n\trestore(collection: string, id: string, options: { _rev: string }): Promise<VersionedContentItem>;\n}\n\n/**\n * Taxonomy access interface — capability-gated on `taxonomies:read`.\n */\nexport interface TaxonomyAccess {\n\t/** List taxonomy definitions. */\n\tgetAll(options?: TaxonomyReadOptions): Promise<TaxonomyDefInfo[]>;\n\t/** All terms of a taxonomy, ordered by label. */\n\tgetTerms(taxonomy: string, options?: TaxonomyReadOptions): Promise<TaxonomyTermInfo[]>;\n\t/** Terms assigned to a content entry, optionally scoped to one taxonomy. */\n\tgetEntryTerms(\n\t\tcollection: string,\n\t\tentryId: string,\n\t\toptions?: TaxonomyReadOptions & { taxonomy?: string },\n\t): Promise<TaxonomyTermInfo[]>;\n\tcreateTerm?(taxonomy: string, input: TaxonomyTermCreateInput): Promise<TaxonomyTermInfo>;\n\taddEntryTerms?(\n\t\tcollection: string,\n\t\tentryId: string,\n\t\ttaxonomy: string,\n\t\ttermIds: string[],\n\t): Promise<TaxonomyTermInfo[]>;\n\tremoveEntryTerms?(\n\t\tcollection: string,\n\t\tentryId: string,\n\t\ttaxonomy: string,\n\t\ttermIds: string[],\n\t): Promise<TaxonomyTermInfo[]>;\n}\n\n/** Taxonomy mutations available with `taxonomies:write`. */\nexport interface TaxonomyAccessWithWrite extends TaxonomyAccess {\n\tcreateTerm(taxonomy: string, input: TaxonomyTermCreateInput): Promise<TaxonomyTermInfo>;\n\taddEntryTerms(\n\t\tcollection: string,\n\t\tentryId: string,\n\t\ttaxonomy: string,\n\t\ttermIds: string[],\n\t): Promise<TaxonomyTermInfo[]>;\n\tremoveEntryTerms(\n\t\tcollection: string,\n\t\tentryId: string,\n\t\ttaxonomy: string,\n\t\ttermIds: string[],\n\t): Promise<TaxonomyTermInfo[]>;\n}\n\n/**\n * Public byline profile returned from the byline API. Omits the linked user\n * account, guest flag, and custom field values.\n */\nexport interface BylineInfo {\n\tid: string;\n\tslug: string;\n\tdisplayName: string;\n\tbio: string | null;\n\twebsiteUrl: string | null;\n\t/** Media ID of the avatar image. Resolve it with `ctx.media.get()`. */\n\tavatarMediaId: string | null;\n\tlocale: string;\n\t/** Locale-agnostic identity shared by every translation of the byline. */\n\ttranslationGroup: string;\n}\n\n/** A byline credited on a content entry. */\nexport interface BylineCreditInfo {\n\tbyline: BylineInfo;\n\tsortOrder: number;\n\troleLabel: string | null;\n\t/**\n\t * `explicit` for a credit assigned in the editor; `inferred` when the entry\n\t * has no credits and the byline linked to the entry's author is used.\n\t */\n\tsource: \"explicit\" | \"inferred\";\n}\n\nexport interface BylineListOptions {\n\t/** Match one locale. Omit to list every locale. */\n\tlocale?: string;\n\t/** Page size, clamped to 1–100. Defaults to 50. */\n\tlimit?: number;\n\tcursor?: string;\n}\n\n/** Byline credits for one entry in a batched lookup. */\nexport interface EntryBylineCredits {\n\tentryId: string;\n\tbylines: BylineCreditInfo[];\n}\n\n/**\n * Byline access interface — capability-gated on `bylines:read`.\n */\nexport interface BylineAccess {\n\t/** Get a byline by its row ID. */\n\tget(id: string): Promise<BylineInfo | null>;\n\t/** List bylines, newest first. */\n\tlist(options?: BylineListOptions): Promise<PaginatedResult<BylineInfo>>;\n\t/**\n\t * Bylines credited on up to 100 entries of one collection, in the order the\n\t * IDs were given. Duplicate IDs are returned once. Credits resolve at each\n\t * entry's own locale, matching what the site renders. Trashed and missing\n\t * entries have no credits.\n\t */\n\tgetEntriesBylines(collection: string, entryIds: string[]): Promise<EntryBylineCredits[]>;\n}\n\nexport type RedirectStatus = 301 | 302 | 307 | 308 | 410 | 451;\n\nexport interface RedirectInfo {\n\tid: string;\n\tsource: string;\n\tdestination: string;\n\ttype: RedirectStatus;\n\tisPattern: boolean;\n\tenabled: boolean;\n\thits: number;\n\tlastHitAt: string | null;\n\tgroupName: string | null;\n\tauto: boolean;\n\tcreatedAt: string;\n\tupdatedAt: string;\n}\n\nexport interface VersionedRedirect {\n\tredirect: RedirectInfo;\n\t/** Opaque host revision. Pass it back unchanged for update or delete. */\n\t_rev: string;\n}\n\nexport interface RedirectListOptions {\n\tlimit?: number;\n\tcursor?: string;\n\tsearch?: string;\n\tgroup?: string;\n\tenabled?: boolean;\n\tauto?: boolean;\n}\n\nexport interface RedirectCreateInput {\n\tsource: string;\n\tdestination?: string;\n\ttype?: RedirectStatus;\n\tenabled?: boolean;\n\tgroupName?: string | null;\n}\n\nexport interface RedirectUpdateInput {\n\tsource?: string;\n\tdestination?: string;\n\ttype?: RedirectStatus;\n\tenabled?: boolean;\n\tgroupName?: string | null;\n}\n\nexport interface RedirectAccess {\n\tlist(options?: RedirectListOptions): Promise<PaginatedResult<RedirectInfo>>;\n\tget(id: string): Promise<VersionedRedirect | null>;\n\tcreate?(input: RedirectCreateInput): Promise<VersionedRedirect>;\n\tupdate?(id: string, input: RedirectUpdateInput & { _rev: string }): Promise<VersionedRedirect>;\n\tdelete?(id: string, options: { _rev: string }): Promise<boolean>;\n}\n\nexport interface RedirectAccessWithWrite extends RedirectAccess {\n\tcreate(input: RedirectCreateInput): Promise<VersionedRedirect>;\n\tupdate(id: string, input: RedirectUpdateInput & { _rev: string }): Promise<VersionedRedirect>;\n\tdelete(id: string, options: { _rev: string }): Promise<boolean>;\n}\n\n/**\n * Full content access with write operations\n */\nexport interface ContentAccessWithWrite extends ContentAccess {\n\tcreate(\n\t\tcollection: string,\n\t\tdata: ContentWriteInput,\n\t\toptions?: ContentCreateOptions,\n\t): Promise<ContentItem>;\n\tupdate(collection: string, id: string, data: ContentWriteInput): Promise<ContentItem>;\n\tdelete(collection: string, id: string): Promise<boolean>;\n}\n\n/**\n * Media item returned from media API\n */\nexport interface MediaItem {\n\tid: string;\n\tfilename: string;\n\tmimeType: string;\n\tsize: number | null;\n\turl: string;\n\tcreatedAt: string;\n\twidth?: number | null;\n\theight?: number | null;\n\talt?: string | null;\n\tcaption?: string | null;\n\tfocalX?: number | null;\n\tfocalY?: number | null;\n\tblurhash?: string | null;\n\tdominantColor?: string | null;\n\tfolderId?: string | null;\n\tstatus?: \"ready\";\n}\n\nexport interface MediaBytes {\n\tbytes: Uint8Array;\n\tfilename: string;\n\tmimeType: string;\n\tsize: number;\n\tcontentHash?: string;\n}\n\nexport interface MediaMetadataPatch {\n\talt?: string | null;\n\tcaption?: string | null;\n\tfocalX?: number | null;\n\tfocalY?: number | null;\n}\n\n/**\n * Media list options\n */\nexport interface MediaListOptions {\n\tlimit?: number;\n\tcursor?: string;\n\tmimeType?: string; // Filter by mime type prefix, e.g., \"image/\"\n}\n\n/**\n * Media access interface - capability-gated\n */\nexport interface MediaAccess {\n\t// Read operations (requires read:media)\n\tget(id: string): Promise<MediaItem | null>;\n\tlist(options?: MediaListOptions): Promise<PaginatedResult<MediaItem>>;\n\t/** Read ready media bytes, bounded by the caller's limit and the host maximum. */\n\treadBytes?(id: string, options?: { maxBytes?: number }): Promise<MediaBytes>;\n\t/** Change only alt text, caption, or the complete focal-point pair. */\n\tupdateMetadata?(id: string, patch: MediaMetadataPatch): Promise<MediaItem>;\n\n\t// Write operations (requires write:media) - optional on interface\n\tgetUploadUrl?(\n\t\tfilename: string,\n\t\tcontentType: string,\n\t): Promise<{ uploadUrl: string; mediaId: string }>;\n\t/**\n\t * Upload media bytes directly. Preferred in sandboxed mode where\n\t * plugins cannot make external requests to a presigned URL.\n\t * Returns the created media item.\n\t */\n\tupload?(\n\t\tfilename: string,\n\t\tcontentType: string,\n\t\tbytes: ArrayBuffer,\n\t): Promise<{ mediaId: string; storageKey: string; url: string }>;\n\tdelete?(id: string): Promise<boolean>;\n}\n\n/**\n * Full media access with write operations\n */\nexport interface MediaAccessWithWrite extends MediaAccess {\n\tgetUploadUrl(\n\t\tfilename: string,\n\t\tcontentType: string,\n\t): Promise<{ uploadUrl: string; mediaId: string }>;\n\tupload(\n\t\tfilename: string,\n\t\tcontentType: string,\n\t\tbytes: ArrayBuffer,\n\t): Promise<{ mediaId: string; storageKey: string; url: string }>;\n\tdelete(id: string): Promise<boolean>;\n}\n\n/**\n * HTTP client interface - requires network:request capability\n */\nexport interface HttpAccess {\n\t/**\n\t * Fetch an allowed external URL and return a buffered response.\n\t * Decoded request and response bodies are each limited to 8 MiB.\n\t */\n\tfetch(url: string, init?: RequestInit): Promise<Response>;\n}\n\n/**\n * Logger interface - always available\n */\nexport interface LogAccess {\n\tdebug(message: string, data?: unknown): void;\n\tinfo(message: string, data?: unknown): void;\n\twarn(message: string, data?: unknown): void;\n\terror(message: string, data?: unknown): void;\n}\n\n// =============================================================================\n// Site & User Access\n// =============================================================================\n\n/**\n * Site information available to all plugins\n */\nexport interface SiteInfo {\n\t/** Site name (from settings) */\n\tname: string;\n\t/** Site URL (from settings or request) */\n\turl: string;\n\t/** Site locale (from settings, defaults to \"en\") */\n\tlocale: string;\n\t/**\n\t * Astro's `trailingSlash` routing policy, from the host's Astro config.\n\t * Plugins that build absolute URLs (sitemap, canonical, hreflang) should\n\t * honor this so the URLs they emit match what the site serves. `createSiteInfo`\n\t * always populates it (defaulting to `\"ignore\"`, Astro's default); it is\n\t * optional on the type so pre-existing `SiteInfo` construction stays valid.\n\t */\n\ttrailingSlash?: \"always\" | \"never\" | \"ignore\";\n}\n\n/**\n * Read-only user information exposed to plugins.\n * Sensitive fields (password hashes, sessions, passkeys) are excluded.\n */\nexport interface UserInfo {\n\tid: string;\n\temail: string;\n\tname: string | null;\n\trole: number;\n\tcreatedAt: string;\n}\n\n/**\n * User access interface - requires read:users capability\n */\nexport interface UserAccess {\n\t/** Get a user by ID */\n\tget(id: string): Promise<UserInfo | null>;\n\t/** Get a user by email */\n\tgetByEmail(email: string): Promise<UserInfo | null>;\n\t/** List users with optional filters */\n\tlist(opts?: { role?: number; limit?: number; cursor?: string }): Promise<{\n\t\titems: UserInfo[];\n\t\tnextCursor?: string;\n\t}>;\n}\n\nexport type PluginCommentStatus = \"approved\" | \"pending\" | \"spam\";\n\n/** Comment data exposed by the explicit personal-data `comments:read` capability. */\nexport interface PluginComment {\n\tid: string;\n\tcollection: string;\n\tcontentId: string;\n\tparentId: string | null;\n\tauthorName: string;\n\tauthorEmail: string;\n\tbody: string;\n\tstatus: PluginCommentStatus;\n\tipHash: string | null;\n\tuserAgent: string | null;\n\tmoderationMetadata: Record<string, unknown> | null;\n\tcreatedAt: string;\n\tupdatedAt: string;\n}\n\nexport interface CommentListOptions {\n\tstatus?: PluginCommentStatus;\n\tcollection?: string;\n\tcontentId?: string;\n\tlimit?: number;\n\tcursor?: string;\n}\n\nexport interface CommentCountOptions {\n\tstatus?: PluginCommentStatus;\n\tcollection?: string;\n\tcontentId?: string;\n}\n\nexport interface CommentAccess {\n\tget(id: string): Promise<PluginComment | null>;\n\tlist(options?: CommentListOptions): Promise<PaginatedResult<PluginComment>>;\n\tcount(options?: CommentCountOptions): Promise<number>;\n\tsetStatus?(\n\t\tid: string,\n\t\tstatus: PluginCommentStatus,\n\t\toptions: { expectedStatus: PluginCommentStatus },\n\t): Promise<PluginComment>;\n}\n\n// =============================================================================\n// Plugin Context\n// =============================================================================\n\n/**\n * The unified plugin context - same shape for all hooks and routes\n */\nexport interface PluginContext<TStorage extends PluginStorageConfig = PluginStorageConfig> {\n\t/** Plugin metadata */\n\tplugin: {\n\t\tid: string;\n\t\tversion: string;\n\t};\n\n\t/** Storage collections - only if plugin declares storage */\n\tstorage: PluginStorage<TStorage>;\n\n\t/** Key-value store for internal state */\n\tkv: KVAccess;\n\n\t/** Plugin settings. Secret schema fields are encrypted by the host. */\n\tsettings: SettingsAccess;\n\n\t/** Content access - only if read:content or write:content capability */\n\tcontent?: ContentAccess | ContentAccessWithWrite;\n\t/** Schema discovery - only if schema:read capability */\n\tschema?: SchemaAccess;\n\n\t/** Taxonomy access - only if a taxonomy capability is declared. */\n\ttaxonomies?: TaxonomyAccess | TaxonomyAccessWithWrite;\n\n\t/** Byline access - only if bylines:read capability */\n\tbylines?: BylineAccess;\n\n\t/** Redirect access - only if redirects:read or redirects:write capability */\n\tredirects?: RedirectAccess | RedirectAccessWithWrite;\n\n\t/** Media access - only if read:media or write:media capability */\n\tmedia?: MediaAccess | MediaAccessWithWrite;\n\n\t/** HTTP client - only if network:request capability */\n\thttp?: HttpAccess;\n\n\t/** Logger - always available */\n\tlog: LogAccess;\n\n\t/** Site information - always available */\n\tsite: SiteInfo;\n\n\t/** URL helper - generates absolute URLs from paths. Always available. */\n\turl(path: string): string;\n\n\t/** User access - only if read:users capability */\n\tusers?: UserAccess;\n\n\t/** Comment access — only if comments:read or comments:moderate is declared. */\n\tcomments?: CommentAccess;\n\n\t/** Cron task scheduling - always available, scoped to plugin */\n\tcron?: CronAccess;\n\n\t/** Email access - only if email:send capability and a provider is configured */\n\temail?: EmailAccess;\n}\n\n// =============================================================================\n// Cron Types\n// =============================================================================\n\n/**\n * Cron access interface �� always available on plugin context, scoped to plugin.\n */\nexport interface CronAccess {\n\t/** Schedule a recurring or one-shot task */\n\tschedule(name: string, opts: { schedule: string; data?: Record<string, unknown> }): Promise<void>;\n\t/** Cancel a scheduled task */\n\tcancel(name: string): Promise<void>;\n\t/** List this plugin's scheduled tasks */\n\tlist(): Promise<CronTaskInfo[]>;\n}\n\n/**\n * Task info returned from CronAccess.list()\n */\nexport interface CronTaskInfo {\n\tname: string;\n\tschedule: string;\n\tnextRunAt: string;\n\tlastRunAt: string | null;\n}\n\n/**\n * Event passed to the `cron` hook handler\n */\nexport interface CronEvent {\n\tname: string;\n\tdata?: Record<string, unknown>;\n\tscheduledAt: string;\n}\n\n/**\n * Cron hook handler type\n */\nexport type CronHandler = (event: CronEvent, ctx: PluginContext) => Promise<void>;\n\n// =============================================================================\n// Email Types\n// =============================================================================\n\n/**\n * Email access interface — requires `email:send` capability.\n * Undefined when no `email:deliver` provider is configured.\n *\n * Related capabilities:\n * - `email:send` — grants ctx.email (this interface)\n * - `email:provide` — allows registering the `email:deliver` exclusive hook\n * - `email:intercept` — allows registering `email:beforeSend` / `email:afterSend` hooks\n */\nexport interface EmailAccess {\n\tsend(message: EmailMessage): Promise<void>;\n}\n\n/**\n * Email message shape\n */\nexport interface EmailMessage {\n\tto: string;\n\t/** Additional visible recipients. */\n\tcc?: string[];\n\t/** Address that replies go to instead of the sender. */\n\treplyTo?: string;\n\tsubject: string;\n\ttext: string;\n\thtml?: string;\n}\n\n/**\n * Event passed to email:beforeSend hooks (middleware — transform, validate, cancel)\n */\nexport interface EmailBeforeSendEvent {\n\tmessage: EmailMessage;\n\t/** Where the email originated — \"system\" for auth emails, plugin ID for plugin emails */\n\tsource: string;\n}\n\n/**\n * Event passed to email:deliver hook (exclusive — exactly one provider delivers)\n */\nexport interface EmailDeliverEvent {\n\tmessage: EmailMessage;\n\tsource: string;\n}\n\n/**\n * Event passed to email:afterSend hooks (logging, analytics, fire-and-forget)\n */\nexport interface EmailAfterSendEvent {\n\tmessage: EmailMessage;\n\tsource: string;\n}\n\n/**\n * Handler type for email:beforeSend hooks.\n * Returns modified message, or false to cancel delivery.\n */\nexport type EmailBeforeSendHandler = (\n\tevent: EmailBeforeSendEvent,\n\tctx: PluginContext,\n) => Promise<EmailMessage | false>;\n\n/**\n * Handler type for email:deliver hooks (exclusive provider).\n */\nexport type EmailDeliverHandler = (event: EmailDeliverEvent, ctx: PluginContext) => Promise<void>;\n\n/**\n * Handler type for email:afterSend hooks (fire-and-forget).\n */\nexport type EmailAfterSendHandler = (\n\tevent: EmailAfterSendEvent,\n\tctx: PluginContext,\n) => Promise<void>;\n\n// =============================================================================\n// Comment Types\n// =============================================================================\n\n/**\n * Collection comment settings (read from _emdash_collections)\n */\nexport interface CollectionCommentSettings {\n\tcommentsEnabled: boolean;\n\tcommentsModeration: \"all\" | \"first_time\" | \"none\";\n\tcommentsClosedAfterDays: number;\n\tcommentsAutoApproveUsers: boolean;\n}\n\n/**\n * Event passed to comment:beforeCreate hooks (middleware — transform, enrich, reject)\n */\nexport interface CommentBeforeCreateEvent {\n\tcomment: {\n\t\tcollection: string;\n\t\tcontentId: string;\n\t\tparentId: string | null;\n\t\tauthorName: string;\n\t\tauthorEmail: string;\n\t\tauthorUserId: string | null;\n\t\tbody: string;\n\t\tipHash: string | null;\n\t\tuserAgent: string | null;\n\t};\n\t/** Metadata bag — plugins can attach signals for the moderator */\n\tmetadata: Record<string, unknown>;\n}\n\n/**\n * Event passed to comment:moderate hook (exclusive — decides initial status)\n */\nexport interface CommentModerateEvent {\n\tcomment: CommentBeforeCreateEvent[\"comment\"];\n\tmetadata: Record<string, unknown>;\n\tcollectionSettings: CollectionCommentSettings;\n\t/** Number of prior approved comments from this email address */\n\tpriorApprovedCount: number;\n}\n\n/**\n * Moderation decision returned by the comment:moderate handler\n */\nexport interface ModerationDecision {\n\tstatus: \"approved\" | \"pending\" | \"spam\";\n\t/** Optional reason for admin visibility */\n\treason?: string;\n}\n\n/**\n * Stored comment shape (full record with id, status, timestamps)\n */\nexport interface StoredComment {\n\tid: string;\n\tcollection: string;\n\tcontentId: string;\n\tparentId: string | null;\n\tauthorName: string;\n\tauthorEmail: string;\n\tauthorUserId: string | null;\n\tbody: string;\n\tstatus: string;\n\tmoderationMetadata: Record<string, unknown> | null;\n\tcreatedAt: string;\n\tupdatedAt: string;\n}\n\n/**\n * Event passed to comment:afterCreate hooks (fire-and-forget)\n */\nexport interface CommentAfterCreateEvent {\n\tcomment: StoredComment;\n\tmetadata: Record<string, unknown>;\n\t/** The content item the comment is on */\n\tcontent: { id: string; collection: string; slug: string; title?: string };\n\t/** The content author (for notifications) */\n\tcontentAuthor?: { id: string; name: string | null; email: string };\n}\n\n/**\n * Event passed to comment:afterModerate hooks (fire-and-forget, admin status change)\n */\nexport interface CommentAfterModerateEvent {\n\tcomment: StoredComment;\n\tpreviousStatus: string;\n\tnewStatus: string;\n\t/** The admin who moderated */\n\tmoderator: { id: string; name: string | null };\n\t/** Identifies whether an administrator or a plugin initiated the transition. */\n\torigin?: { source: \"admin\"; userId: string } | { source: \"plugin\"; pluginId: string };\n}\n\n/**\n * Handler type for comment:beforeCreate hooks.\n * Returns modified event, or false to reject the comment.\n */\nexport type CommentBeforeCreateHandler = (\n\tevent: CommentBeforeCreateEvent,\n\tctx: PluginContext,\n) => Promise<CommentBeforeCreateEvent | false | void>;\n\n/**\n * Handler type for comment:moderate hook (exclusive provider).\n */\nexport type CommentModerateHandler = (\n\tevent: CommentModerateEvent,\n\tctx: PluginContext,\n) => Promise<ModerationDecision>;\n\n/**\n * Handler type for comment:afterCreate hooks (fire-and-forget).\n */\nexport type CommentAfterCreateHandler = (\n\tevent: CommentAfterCreateEvent,\n\tctx: PluginContext,\n) => Promise<void>;\n\n/**\n * Handler type for comment:afterModerate hooks (fire-and-forget).\n */\nexport type CommentAfterModerateHandler = (\n\tevent: CommentAfterModerateEvent,\n\tctx: PluginContext,\n) => Promise<void>;\n\n// =============================================================================\n// Hook Types\n// =============================================================================\n\n/**\n * Hook configuration\n */\nexport interface HookConfig<THandler> {\n\t/** Explicit ordering - lower numbers run first (default: 100) */\n\tpriority?: number;\n\t/** Max execution time in ms (default: 5000) */\n\ttimeout?: number;\n\t/** Run after these plugins */\n\tdependencies?: string[];\n\t/** Error handling policy */\n\terrorPolicy?: \"continue\" | \"abort\";\n\t/**\n\t * Mark this hook as exclusive — only one plugin can be the active provider.\n\t * Exclusive hooks skip the priority pipeline and dispatch only to the\n\t * admin-selected provider. Used for email:deliver, search, image optimization, etc.\n\t */\n\texclusive?: boolean;\n\t/** The hook handler */\n\thandler: THandler;\n}\n\n/**\n * Acting user that triggered a content hook. Present for authenticated\n * saves; absent for unauthenticated or internal writes.\n */\nexport interface ActorInfo {\n\treadonly id: string;\n\treadonly role: number;\n\treadonly source?: \"api\" | \"mcp\" | \"visual-editor\";\n}\n\nexport type ContentActionOrigin =\n\t| { source: \"api\" | \"mcp\" | \"visual-editor\" }\n\t| { source: \"plugin\"; pluginId: string }\n\t| { source: \"scheduler\" }\n\t| { source: \"system\" };\n\nexport type ContentPolicyDecision = void | { cancel: true; reason: string };\n\n/**\n * Content hook event\n */\nexport interface ContentHookEvent {\n\tcontent: Record<string, unknown>;\n\tcollection: string;\n\tisNew: boolean;\n\t/**\n\t * ID of the existing item on `content:beforeSave` for an update. Absent on\n\t * creates, where the ID is assigned when the save completes, and on\n\t * `content:afterSave`, where `content.id` carries it.\n\t */\n\tid?: string;\n\t/**\n\t * The acting user for this save. Carries the same authenticated identity\n\t * used to set the revision author, so plugins (e.g. audit logs) can record\n\t * who made the change.\n\t */\n\tactor?: ActorInfo;\n\t/**\n\t * Locale of the entry being saved: the resolved target locale on a create,\n\t * the stored entry's locale on an update.\n\t */\n\tlocale?: string;\n\t/**\n\t * ID of the source entry when a create comes from the translation flow.\n\t * Absent on updates and on creates that start a new translation group.\n\t */\n\ttranslationOf?: string;\n}\n\n/** Locale details a save passes to its `content:beforeSave` and `content:afterSave` hooks. */\nexport interface ContentSaveHookDetails {\n\tlocale?: string;\n\ttranslationOf?: string;\n}\n\n/**\n * Content delete hook event\n */\nexport interface ContentDeleteEvent {\n\tid: string;\n\tcollection: string;\n\t/** `true` when the content is permanently deleted (not just trashed). */\n\tpermanent: boolean;\n}\n\n/**\n * Content state-change hook event (fired after publish, unpublish, restore,\n * schedule, or unschedule).\n */\nexport interface ContentStateChangeEvent {\n\tcontent: Record<string, unknown>;\n\tcollection: string;\n}\n\n/**\n * Content publish/unpublish hook event.\n */\nexport type ContentPublishStateChangeEvent = ContentStateChangeEvent;\n\n/**\n * Content restore hook event.\n */\nexport type ContentRestoreStateChangeEvent = ContentStateChangeEvent;\n\n/**\n * Content schedule/unschedule hook event.\n */\nexport type ContentScheduleStateChangeEvent = ContentStateChangeEvent;\n\nexport interface ContentPolicyEvent extends ContentStateChangeEvent {\n\torigin: ContentActionOrigin;\n\tactor?: ActorInfo;\n}\n\nexport interface ContentSchedulePolicyEvent extends ContentPolicyEvent {\n\tscheduledAt: string;\n}\n\n/**\n * Media hook event\n */\nexport interface MediaUploadEvent {\n\tfile: { name: string; type: string; size: number };\n}\n\n/**\n * Media after upload event\n */\nexport interface MediaAfterUploadEvent {\n\tmedia: MediaItem;\n}\n\n/**\n * Lifecycle hook event\n */\nexport interface LifecycleEvent {\n\t// Empty for install/activate/deactivate\n}\n\n/**\n * Uninstall hook event\n */\nexport interface UninstallEvent {\n\tdeleteData: boolean;\n}\n\n// Hook handler types - all receive (event, ctx) with unified context\nexport type ContentBeforeSaveHandler = (\n\tevent: ContentHookEvent,\n\tctx: PluginContext,\n) => Promise<Record<string, unknown> | void>;\n\nexport type ContentAfterSaveHandler = (\n\tevent: ContentHookEvent,\n\tctx: PluginContext,\n) => Promise<void>;\n\nexport type ContentBeforeDeleteHandler = (\n\tevent: ContentDeleteEvent,\n\tctx: PluginContext,\n) => Promise<boolean | void>;\n\nexport type ContentAfterDeleteHandler = (\n\tevent: ContentDeleteEvent,\n\tctx: PluginContext,\n) => Promise<void>;\n\nexport type ContentBeforePublishHandler = (\n\tevent: ContentPolicyEvent,\n\tctx: PluginContext,\n) => Promise<ContentPolicyDecision>;\n\nexport type ContentBeforeScheduleHandler = (\n\tevent: ContentSchedulePolicyEvent,\n\tctx: PluginContext,\n) => Promise<ContentPolicyDecision>;\n\nexport type ContentBeforeUnpublishHandler = (\n\tevent: ContentPolicyEvent,\n\tctx: PluginContext,\n) => Promise<ContentPolicyDecision>;\n\nexport type ContentAfterPublishHandler = (\n\tevent: ContentPublishStateChangeEvent,\n\tctx: PluginContext,\n) => Promise<void>;\n\nexport type ContentAfterUnpublishHandler = (\n\tevent: ContentPublishStateChangeEvent,\n\tctx: PluginContext,\n) => Promise<void>;\n\nexport type ContentAfterRestoreHandler = (\n\tevent: ContentRestoreStateChangeEvent,\n\tctx: PluginContext,\n) => Promise<void>;\n\nexport type ContentAfterScheduleHandler = (\n\tevent: ContentScheduleStateChangeEvent,\n\tctx: PluginContext,\n) => Promise<void>;\n\nexport type ContentAfterUnscheduleHandler = (\n\tevent: ContentScheduleStateChangeEvent,\n\tctx: PluginContext,\n) => Promise<void>;\n\n/**\n * Event for `byline:afterSave`, fired after a byline profile or one of its\n * locale translations is created or updated.\n */\nexport interface BylineAfterSaveEvent {\n\tbyline: BylineInfo;\n\tisNew: boolean;\n}\n\n/**\n * Event for `byline:afterDelete`, fired after a byline row is deleted. When it\n * was the last locale of its translation group, its credits have already been\n * removed from every entry.\n */\nexport interface BylineAfterDeleteEvent {\n\tbyline: BylineInfo;\n}\n\nexport type BylineAfterSaveHandler = (\n\tevent: BylineAfterSaveEvent,\n\tctx: PluginContext,\n) => Promise<void>;\n\nexport type BylineAfterDeleteHandler = (\n\tevent: BylineAfterDeleteEvent,\n\tctx: PluginContext,\n) => Promise<void>;\n\nexport type MediaBeforeUploadHandler = (\n\tevent: MediaUploadEvent,\n\tctx: PluginContext,\n) => Promise<{ name: string; type: string; size: number } | void>;\n\nexport type MediaAfterUploadHandler = (\n\tevent: MediaAfterUploadEvent,\n\tctx: PluginContext,\n) => Promise<void>;\n\nexport type LifecycleHandler = (event: LifecycleEvent, ctx: PluginContext) => Promise<void>;\n\nexport type UninstallHandler = (event: UninstallEvent, ctx: PluginContext) => Promise<void>;\n\n// =============================================================================\n// Public Page Contribution Types\n// =============================================================================\n\n/** Placement targets for page fragment contributions */\nexport type PagePlacement = \"head\" | \"body:start\" | \"body:end\";\n\n/**\n * A single breadcrumb trail item. Used by `PublicPageContext.breadcrumbs`\n * so themes can publish breadcrumb trails that SEO plugins consume.\n */\nexport interface BreadcrumbItem {\n\t/** Display name for this crumb (e.g. \"Home\", \"Blog\", \"My Post\"). */\n\tname: string;\n\t/** Absolute or root-relative URL for this crumb. */\n\turl: string;\n}\n\n/**\n * Describes the page being rendered. Passed to page hooks so plugins\n * can decide what to contribute without fetching content themselves.\n */\nexport interface PublicPageContext {\n\turl: string;\n\tpath: string;\n\tlocale: string | null;\n\tkind: \"content\" | \"custom\";\n\tpageType: string;\n\t/** Full document title for the rendered page */\n\ttitle: string | null;\n\t/** Page-only title for OG/Twitter/JSON-LD headline output */\n\tpageTitle?: string | null;\n\tdescription: string | null;\n\tcanonical: string | null;\n\timage: string | null;\n\tcontent?: {\n\t\tcollection: string;\n\t\tid: string;\n\t\tslug: string | null;\n\t};\n\t/** SEO meta for base metadata generation in EmDashHead */\n\tseo?: {\n\t\togTitle?: string | null;\n\t\togDescription?: string | null;\n\t\togImage?: string | null;\n\t\trobots?: string | null;\n\t};\n\t/** Article metadata for Open Graph article: tags */\n\tarticleMeta?: {\n\t\tpublishedTime?: string | null;\n\t\tmodifiedTime?: string | null;\n\t\tauthor?: string | null;\n\t};\n\t/** Site name for structured data and og:site_name */\n\tsiteName?: string;\n\t/**\n\t * Optional breadcrumb trail for this page, root first. When set,\n\t * SEO plugins should use this verbatim rather than deriving a trail\n\t * from `path`. Themes typically populate this at the point they\n\t * build the context (e.g. from a content hierarchy walk, taxonomy\n\t * lookup, or per-`pageType` routing logic).\n\t *\n\t * Semantics for consumers:\n\t * - `undefined` — theme has no opinion; consumer falls back to\n\t * its own derivation.\n\t * - `[]` — this page has no breadcrumbs (e.g. homepage); consumer\n\t * should skip `BreadcrumbList` emission entirely.\n\t * - Non-empty array — used verbatim for `BreadcrumbList` output.\n\t */\n\tbreadcrumbs?: BreadcrumbItem[];\n\t/** Public-facing site URL (origin) for structured data */\n\tsiteUrl?: string;\n}\n\n// ── page:metadata ───────────────────────────────────────────────\n\nexport interface PageMetadataEvent {\n\tpage: PublicPageContext;\n}\n\n/**\n * Allowed rel values for link contributions.\n * This is a security-critical allowlist -- sandboxed plugins can only inject\n * link tags with these rel values. Adding \"stylesheet\", \"prefetch\", \"prerender\"\n * etc. would allow sandboxed plugins to inject external resources.\n */\nexport type PageMetadataLinkRel =\n\t| \"canonical\"\n\t| \"alternate\"\n\t| \"author\"\n\t| \"license\"\n\t| \"nlweb\"\n\t| \"site.standard.document\";\n\nexport type PageMetadataContribution =\n\t| { kind: \"meta\"; name: string; content: string; key?: string }\n\t| { kind: \"property\"; property: string; content: string; key?: string }\n\t| { kind: \"link\"; rel: PageMetadataLinkRel; href: string; hreflang?: string; key?: string }\n\t| {\n\t\t\tkind: \"jsonld\";\n\t\t\tid?: string;\n\t\t\tgraph: Record<string, unknown> | Array<Record<string, unknown>>;\n\t };\n\nexport type PageMetadataHandler = (\n\tevent: PageMetadataEvent,\n\tctx: PluginContext,\n) =>\n\t| PageMetadataContribution\n\t| PageMetadataContribution[]\n\t| null\n\t| Promise<PageMetadataContribution | PageMetadataContribution[] | null>;\n\n// ── page:fragments (trusted-only) ──────────────────────────────\n\nexport interface PageFragmentEvent {\n\tpage: PublicPageContext;\n}\n\nexport type PageFragmentContribution =\n\t| {\n\t\t\tkind: \"external-script\";\n\t\t\tplacement: PagePlacement;\n\t\t\tsrc: string;\n\t\t\tasync?: boolean;\n\t\t\tdefer?: boolean;\n\t\t\tattributes?: Record<string, string>;\n\t\t\tkey?: string;\n\t }\n\t| {\n\t\t\tkind: \"inline-script\";\n\t\t\tplacement: PagePlacement;\n\t\t\tcode: string;\n\t\t\tattributes?: Record<string, string>;\n\t\t\tkey?: string;\n\t }\n\t| {\n\t\t\tkind: \"html\";\n\t\t\tplacement: PagePlacement;\n\t\t\thtml: string;\n\t\t\tkey?: string;\n\t };\n\nexport type PageFragmentHandler = (\n\tevent: PageFragmentEvent,\n\tctx: PluginContext,\n) =>\n\t| PageFragmentContribution\n\t| PageFragmentContribution[]\n\t| null\n\t| Promise<PageFragmentContribution | PageFragmentContribution[] | null>;\n\n/**\n * Plugin hooks definition\n */\nexport interface PluginHooks {\n\t// Lifecycle hooks\n\t\"plugin:install\"?: HookConfig<LifecycleHandler> | LifecycleHandler;\n\t\"plugin:activate\"?: HookConfig<LifecycleHandler> | LifecycleHandler;\n\t\"plugin:deactivate\"?: HookConfig<LifecycleHandler> | LifecycleHandler;\n\t\"plugin:uninstall\"?: HookConfig<UninstallHandler> | UninstallHandler;\n\n\t// Content hooks\n\t\"content:beforeSave\"?: HookConfig<ContentBeforeSaveHandler> | ContentBeforeSaveHandler;\n\t\"content:afterSave\"?: HookConfig<ContentAfterSaveHandler> | ContentAfterSaveHandler;\n\t\"content:beforeDelete\"?: HookConfig<ContentBeforeDeleteHandler> | ContentBeforeDeleteHandler;\n\t\"content:afterDelete\"?: HookConfig<ContentAfterDeleteHandler> | ContentAfterDeleteHandler;\n\t\"content:beforePublish\"?: HookConfig<ContentBeforePublishHandler> | ContentBeforePublishHandler;\n\t\"content:beforeSchedule\"?:\n\t\t| HookConfig<ContentBeforeScheduleHandler>\n\t\t| ContentBeforeScheduleHandler;\n\t\"content:beforeUnpublish\"?:\n\t\t| HookConfig<ContentBeforeUnpublishHandler>\n\t\t| ContentBeforeUnpublishHandler;\n\t\"content:afterPublish\"?: HookConfig<ContentAfterPublishHandler> | ContentAfterPublishHandler;\n\t\"content:afterUnpublish\"?:\n\t\t| HookConfig<ContentAfterUnpublishHandler>\n\t\t| ContentAfterUnpublishHandler;\n\t\"content:afterRestore\"?: HookConfig<ContentAfterRestoreHandler> | ContentAfterRestoreHandler;\n\t\"content:afterSchedule\"?: HookConfig<ContentAfterScheduleHandler> | ContentAfterScheduleHandler;\n\t\"content:afterUnschedule\"?:\n\t\t| HookConfig<ContentAfterUnscheduleHandler>\n\t\t| ContentAfterUnscheduleHandler;\n\n\t// Media hooks\n\t\"media:beforeUpload\"?: HookConfig<MediaBeforeUploadHandler> | MediaBeforeUploadHandler;\n\t\"media:afterUpload\"?: HookConfig<MediaAfterUploadHandler> | MediaAfterUploadHandler;\n\n\t// Cron hook\n\tcron?: HookConfig<CronHandler> | CronHandler;\n\n\t// Email hooks\n\t\"email:beforeSend\"?: HookConfig<EmailBeforeSendHandler> | EmailBeforeSendHandler;\n\t\"email:deliver\"?: HookConfig<EmailDeliverHandler> | EmailDeliverHandler;\n\t\"email:afterSend\"?: HookConfig<EmailAfterSendHandler> | EmailAfterSendHandler;\n\n\t// Comment hooks\n\t\"comment:beforeCreate\"?: HookConfig<CommentBeforeCreateHandler> | CommentBeforeCreateHandler;\n\t\"comment:moderate\"?: HookConfig<CommentModerateHandler> | CommentModerateHandler;\n\t\"comment:afterCreate\"?: HookConfig<CommentAfterCreateHandler> | CommentAfterCreateHandler;\n\t\"comment:afterModerate\"?: HookConfig<CommentAfterModerateHandler> | CommentAfterModerateHandler;\n\t\"byline:afterSave\"?: HookConfig<BylineAfterSaveHandler> | BylineAfterSaveHandler;\n\t\"byline:afterDelete\"?: HookConfig<BylineAfterDeleteHandler> | BylineAfterDeleteHandler;\n\n\t// Public page hooks\n\t\"page:metadata\"?: HookConfig<PageMetadataHandler> | PageMetadataHandler;\n\t\"page:fragments\"?: HookConfig<PageFragmentHandler> | PageFragmentHandler;\n}\n\n/**\n * Hook names\n */\n/**\n * Hook name in a manifest. Core's exhaustive union of recognised hook names,\n * derived from the `PluginHooks` registry. The serialised manifest carries\n * these as opaque strings; this stricter type is only used for type-checking\n * inside core. `ManifestHookEntry` is re-exported from\n * `@emdash-cms/plugin-types` near the top of this file.\n */\nexport type HookName = keyof PluginHooks;\n\n/**\n * Resolved hook with normalized config\n */\nexport interface ResolvedHook<THandler> {\n\tpriority: number;\n\ttimeout: number;\n\tdependencies: string[];\n\terrorPolicy: \"continue\" | \"abort\";\n\t/** Whether this hook is exclusive (provider pattern) */\n\texclusive: boolean;\n\thandler: THandler;\n\tpluginId: string;\n}\n\n// =============================================================================\n// Request Metadata Types\n// =============================================================================\n\n/**\n * Geographic location information derived from the request.\n * Available when running on Cloudflare Workers (via the `cf` object).\n */\nexport interface GeoInfo {\n\tcountry: string | null;\n\tregion: string | null;\n\tcity: string | null;\n}\n\n/**\n * Normalized request metadata available to plugin route handlers.\n * Extracted from request headers and platform-specific properties.\n */\nexport interface RequestMeta {\n\tip: string | null;\n\tuserAgent: string | null;\n\treferer: string | null;\n\tgeo: GeoInfo | null;\n}\n\n// =============================================================================\n// Route Types\n// =============================================================================\n\n/**\n * Route handler context extends plugin context with request-specific data\n */\nexport interface RouteContext<TInput = unknown> extends PluginContext {\n\t/** Validated input from request body */\n\tinput: TInput;\n\t/** Original request */\n\trequest: Request;\n\t/** Normalized request metadata (IP, user agent, geo) */\n\trequestMeta: RequestMeta;\n\t/** Host-attested context for a validated Block Kit request. */\n\tui?: PluginUiContext;\n\t/**\n\t * Authenticated caller, if the route is private. The host has already\n\t * authenticated and authorized this user before dispatch, so the value\n\t * is trustworthy — unlike a user id read from the request body.\n\t *\n\t * `undefined` for public routes (which skip auth entirely) and for\n\t * token-authed requests where no user is bound to the token.\n\t *\n\t * Not gated by the `users:read` capability: this is the caller's own\n\t * identity for the current request, not a user directory lookup.\n\t */\n\tuser?: UserInfo;\n}\n\n/**\n * Route definition\n */\nexport interface PluginRoute<TInput = unknown> extends Omit<RouteOptions, \"request\"> {\n\t/** Zod schema for input validation */\n\tinput?: z.ZodType<TInput>;\n\t/**\n\t * Mark this route as publicly accessible (no authentication required).\n\t * Public routes skip session/token auth and CSRF checks.\n\t */\n\tpublic?: boolean;\n\t/** RBAC permission required to invoke the route. Legacy routes default to plugins:manage. */\n\tpermission?: Permission;\n\t/**\n\t * `Cache-Control` header value for successful GET responses, e.g.\n\t * `\"public, max-age=60, stale-while-revalidate=300\"`. Only honored on\n\t * routes that are also `public: true` — authenticated responses always\n\t * keep the default `private, no-store`. Errors are never cached.\n\t */\n\tcacheControl?: string;\n\t/** Bounded request parsing and incoming-header declaration. */\n\trequest?: PluginRouteRequest;\n\t/** Route handler */\n\thandler: { bivarianceHack(ctx: RouteContext<TInput>): Promise<unknown> }[\"bivarianceHack\"];\n}\n\nexport type PluginRouteInput<TMode extends PluginRouteBodyMode> = TMode extends \"none\"\n\t? PluginRouteQuery\n\t: TMode extends \"text\"\n\t\t? string\n\t\t: TMode extends \"bytes\"\n\t\t\t? Uint8Array\n\t\t\t: TMode extends \"form-data\"\n\t\t\t\t? PluginFormData\n\t\t\t\t: unknown;\n\nexport type PluginRouteDefinition<TMode extends PluginRouteBodyMode = PluginRouteBodyMode> = Omit<\n\tPluginRoute<PluginRouteInput<TMode>>,\n\t\"request\"\n> & {\n\trequest: PluginRouteRequest & { body: TMode };\n};\n\nexport interface PluginMcpToolDefinition {\n\tdescription: string;\n\troute: string;\n\tinput: z.ZodType;\n\toutput?: z.ZodType;\n\tdestructive?: boolean;\n}\n\nexport interface PluginMcpConfig {\n\ttools: Record<string, PluginMcpToolDefinition>;\n}\n\n// =============================================================================\n// Plugin Definition\n// =============================================================================\n\n/**\n * Admin page definition\n */\nexport interface PluginAdminPage {\n\tpath: string;\n\tlabel: string;\n\ticon?: string;\n\t/**\n\t * Admin sidebar folder. Pages sharing a group with a collection shown in\n\t * the sidebar join that folder; pages with any other group share a folder\n\t * with that label in the Plugins section, across plugins.\n\t */\n\tgroup?: string;\n}\n\n/**\n * Dashboard widget definition\n */\nexport interface PluginDashboardWidget {\n\tid: string;\n\tsize?: \"full\" | \"half\" | \"third\";\n\ttitle?: string;\n}\n\nexport interface PluginEditorPanel {\n\tid: string;\n\ttitle: string;\n\troute: string;\n\tcollections?: string[];\n\torder?: number;\n\tdraft?: PluginEditorDraftAccess;\n}\n\nexport interface PluginEditorAction {\n\tid: string;\n\tlabel: string;\n\troute: string;\n\tplacement: \"toolbar\" | \"overflow\";\n\tcollections?: string[];\n\tstyle?: \"default\" | \"danger\";\n\tconfirm?: ConfirmDialog;\n\tdraft?: PluginEditorDraftAccess;\n}\n\n/**\n * Settings field types (for admin UI generation)\n */\nexport type SettingFieldType =\n\t| \"string\"\n\t| \"number\"\n\t| \"boolean\"\n\t| \"select\"\n\t| \"secret\"\n\t| \"url\"\n\t| \"email\";\n\nexport interface BaseSettingField {\n\ttype: SettingFieldType;\n\tlabel: string;\n\tdescription?: string;\n}\n\nexport interface StringSettingField extends BaseSettingField {\n\ttype: \"string\";\n\tdefault?: string;\n\tmultiline?: boolean;\n}\n\nexport interface NumberSettingField extends BaseSettingField {\n\ttype: \"number\";\n\tdefault?: number;\n\tmin?: number;\n\tmax?: number;\n}\n\nexport interface BooleanSettingField extends BaseSettingField {\n\ttype: \"boolean\";\n\tdefault?: boolean;\n}\n\nexport interface SelectSettingField extends BaseSettingField {\n\ttype: \"select\";\n\toptions: Array<{ value: string; label: string }>;\n\tdefault?: string;\n}\n\nexport interface SecretSettingField extends BaseSettingField {\n\ttype: \"secret\";\n}\n\nexport interface UrlSettingField extends BaseSettingField {\n\ttype: \"url\";\n\tdefault?: string;\n\tplaceholder?: string;\n}\n\nexport interface EmailSettingField extends BaseSettingField {\n\ttype: \"email\";\n\tdefault?: string;\n\tplaceholder?: string;\n}\n\nexport type SettingField =\n\t| StringSettingField\n\t| NumberSettingField\n\t| BooleanSettingField\n\t| SelectSettingField\n\t| SecretSettingField\n\t| UrlSettingField\n\t| EmailSettingField;\n\n/**\n * Block Kit element for block editing fields.\n * This is the `Element` discriminated union from `@emdash-cms/blocks`.\n * Plugin authors should use `@emdash-cms/blocks` builder functions to create these.\n */\nexport type PortableTextBlockField = Element;\n\n/**\n * Configuration for a Portable Text block type contributed by a plugin\n */\nexport interface PortableTextBlockConfig {\n\t/** Block type name (must match the `_type` in Portable Text) */\n\ttype: string;\n\t/** Human-readable label shown in slash commands and modals */\n\tlabel: string;\n\t/** Icon key (e.g., \"video\", \"code\", \"link\", \"link-external\") */\n\ticon?: string;\n\t/** Description shown in slash command menu */\n\tdescription?: string;\n\t/** Placeholder text for the URL input */\n\tplaceholder?: string;\n\t/** Block Kit form fields for the editing UI. If declared, replaces the simple URL input. */\n\tfields?: PortableTextBlockField[];\n\t/**\n\t * Optional. Display category in the slash menu. Defaults to \"Embeds\".\n\t *\n\t * Plugin authors should pick a meaningful category that reflects what the\n\t * block actually is — e.g. \"Sections\", \"Marketing\", \"Media\", \"Embeds\",\n\t * \"Layout\". Blocks with the same category are grouped together in the\n\t * editor's slash menu.\n\t */\n\tcategory?: string;\n}\n\n/**\n * Configuration for a field widget type contributed by a plugin.\n * A field widget provides a custom editing UI for a schema field.\n * The field references the widget via `widget: \"pluginId:widgetName\"`.\n */\nexport interface FieldWidgetConfig {\n\t/** Widget name (without plugin ID prefix) */\n\tname: string;\n\t/** Human-readable label for the admin UI */\n\tlabel: string;\n\t/** Which field types this widget can edit (e.g., [\"json\", \"string\"]) */\n\tfieldTypes: FieldType[];\n\t/** Block Kit elements for sandboxed rendering. Omit for trusted plugins using React. */\n\telements?: Element[];\n}\n\n/**\n * Admin configuration\n */\nexport interface PluginAdminConfig {\n\t/** Module specifier for admin UI exports (e.g., \"@emdash-cms/plugin-audit-log/admin\") */\n\tentry?: string;\n\t/** Settings schema for auto-generated UI */\n\tsettingsSchema?: Record<string, SettingField>;\n\t/** Admin pages */\n\tpages?: PluginAdminPage[];\n\t/** Dashboard widgets */\n\twidgets?: PluginDashboardWidget[];\n\t/** Saved-entry Block Kit panels. */\n\teditorPanels?: PluginEditorPanel[];\n\t/** Saved-entry host-rendered actions. */\n\teditorActions?: PluginEditorAction[];\n\t/** Portable Text block types this plugin provides */\n\tportableTextBlocks?: PortableTextBlockConfig[];\n\t/** Field widget types this plugin provides */\n\tfieldWidgets?: FieldWidgetConfig[];\n}\n\n/**\n * Plugin definition - input to definePlugin()\n */\nexport interface PluginDefinition<TStorage extends PluginStorageConfig = PluginStorageConfig> {\n\t/** Unique plugin identifier */\n\tid: string;\n\t/** Plugin version (semver) */\n\tversion: string;\n\n\t/** Declared capabilities */\n\tcapabilities?: PluginCapability[];\n\n\t/** Allowed hosts for network:request (wildcards supported: *.example.com) */\n\tallowedHosts?: string[];\n\n\t/** Storage collections with indexes */\n\tstorage?: TStorage;\n\n\t/** Hooks */\n\thooks?: PluginHooks;\n\n\t/** API routes */\n\troutes?: Record<string, PluginRoute>;\n\n\t/** Routes explicitly exposed as agent-callable MCP tools. */\n\tmcp?: PluginMcpConfig;\n\n\t/** Admin UI configuration */\n\tadmin?: PluginAdminConfig;\n}\n\n/**\n * Resolved plugin - after definePlugin() processing\n */\nexport interface ResolvedPlugin<TStorage extends PluginStorageConfig = PluginStorageConfig> {\n\tid: string;\n\tversion: string;\n\tcapabilities: PluginCapability[];\n\tallowedHosts: string[];\n\tstorage: TStorage;\n\thooks: ResolvedPluginHooks;\n\troutes: Record<string, PluginRoute>;\n\tmcp?: PluginMcpConfig;\n\tadmin: PluginAdminConfig;\n}\n\n/**\n * Resolved hooks with normalized config\n */\nexport interface ResolvedPluginHooks {\n\t\"plugin:install\"?: ResolvedHook<LifecycleHandler>;\n\t\"plugin:activate\"?: ResolvedHook<LifecycleHandler>;\n\t\"plugin:deactivate\"?: ResolvedHook<LifecycleHandler>;\n\t\"plugin:uninstall\"?: ResolvedHook<UninstallHandler>;\n\t\"content:beforeSave\"?: ResolvedHook<ContentBeforeSaveHandler>;\n\t\"content:afterSave\"?: ResolvedHook<ContentAfterSaveHandler>;\n\t\"content:beforeDelete\"?: ResolvedHook<ContentBeforeDeleteHandler>;\n\t\"content:afterDelete\"?: ResolvedHook<ContentAfterDeleteHandler>;\n\t\"content:beforePublish\"?: ResolvedHook<ContentBeforePublishHandler>;\n\t\"content:beforeSchedule\"?: ResolvedHook<ContentBeforeScheduleHandler>;\n\t\"content:beforeUnpublish\"?: ResolvedHook<ContentBeforeUnpublishHandler>;\n\t\"content:afterPublish\"?: ResolvedHook<ContentAfterPublishHandler>;\n\t\"content:afterUnpublish\"?: ResolvedHook<ContentAfterUnpublishHandler>;\n\t\"content:afterRestore\"?: ResolvedHook<ContentAfterRestoreHandler>;\n\t\"content:afterSchedule\"?: ResolvedHook<ContentAfterScheduleHandler>;\n\t\"content:afterUnschedule\"?: ResolvedHook<ContentAfterUnscheduleHandler>;\n\t\"media:beforeUpload\"?: ResolvedHook<MediaBeforeUploadHandler>;\n\t\"media:afterUpload\"?: ResolvedHook<MediaAfterUploadHandler>;\n\tcron?: ResolvedHook<CronHandler>;\n\t\"email:beforeSend\"?: ResolvedHook<EmailBeforeSendHandler>;\n\t\"email:deliver\"?: ResolvedHook<EmailDeliverHandler>;\n\t\"email:afterSend\"?: ResolvedHook<EmailAfterSendHandler>;\n\t\"comment:beforeCreate\"?: ResolvedHook<CommentBeforeCreateHandler>;\n\t\"comment:moderate\"?: ResolvedHook<CommentModerateHandler>;\n\t\"comment:afterCreate\"?: ResolvedHook<CommentAfterCreateHandler>;\n\t\"comment:afterModerate\"?: ResolvedHook<CommentAfterModerateHandler>;\n\t\"byline:afterSave\"?: ResolvedHook<BylineAfterSaveHandler>;\n\t\"byline:afterDelete\"?: ResolvedHook<BylineAfterDeleteHandler>;\n\t\"page:metadata\"?: ResolvedHook<PageMetadataHandler>;\n\t\"page:fragments\"?: ResolvedHook<PageFragmentHandler>;\n}\n\n// =============================================================================\n// Plugin Admin Exports\n// =============================================================================\n\n/**\n * What a plugin exports from its /admin entrypoint\n * Uses generic component type to avoid React dependency\n */\nexport interface PluginAdminExports {\n\twidgets?: Record<string, JSX.Element>;\n\tpages?: Record<string, JSX.Element>;\n\tfields?: Record<string, JSX.Element>;\n}\n\n// =============================================================================\n// Sandbox Types\n// =============================================================================\n\n/**\n * Plugin manifest — the metadata portion of a plugin bundle, used for\n * sandboxed plugins loaded from the marketplace.\n *\n * This interface is core's stricter version of the manifest contract: it\n * uses the exhaustive `HookName` union and core's typed `PluginAdminConfig`.\n * The wire-shape lives in `@emdash-cms/plugin-types` as `PluginManifest`\n * with looser types (so the registry CLI can serialise hook names it\n * doesn't know about). Both must stay structurally compatible: every value\n * of this type must be assignable to the shared one. The static assertion\n * below catches any drift at compile time.\n */\nexport interface PluginManifest {\n\tid: string;\n\tversion: string;\n\t/**\n\t * The trust contract (see `@emdash-cms/plugin-types`). Authoritative;\n\t * `capabilities`/`allowedHosts` are derived from it at the parse boundary\n\t * via `reconcileManifestAccess`. Optional during the wire-format migration.\n\t */\n\tdeclaredAccess?: DeclaredAccess;\n\tcapabilities: PluginCapability[];\n\tallowedHosts: string[];\n\tstorage: PluginStorageConfig;\n\t/** Hook declarations — either plain name strings or structured objects */\n\thooks: Array<ManifestHookEntry | HookName>;\n\t/** Route declarations — either plain name strings or structured objects */\n\troutes: Array<ManifestRouteEntry | string>;\n\tmcp?: PluginMcpManifestConfig;\n\tadmin: PluginAdminConfig;\n}\n\n// Type-level guard: core's `PluginManifest` is intentionally a SUBTYPE of\n// the shared wire shape (`@emdash-cms/plugin-types` `PluginManifest`). The\n// wire shape uses looser types like `string` for hook names so the registry\n// CLI can serialise plugins targeting hook versions this core doesn't yet\n// know about. Core narrows `string` to `HookName` and `Record<string,\n// unknown>` to `PluginAdminConfig` because core's loader actually executes\n// against those types.\n//\n// We assert one direction at compile time: `core extends shared`. The\n// reverse direction (`shared extends core`) intentionally does NOT hold\n// because shared is wider -- a manifest written against the wire shape\n// could carry a hook name core doesn't know. That runtime narrowing is the\n// job of `manifest-schema.ts` (zod-validated, called at every JSON.parse\n// of a manifest.json), not of the type system. The static check below\n// catches the OTHER failure mode: core adding a required field or\n// non-assignable type that the wire shape doesn't allow.\n//\n// `type X = never` is itself legal as a type alias, so the assertion has to\n// be in a value position (`const _check: T = true`) for the compiler to\n// error when T resolves to `never`. Don't replace this with a bare type\n// alias.\ntype _AssertManifestCompat =\n\tPluginManifest extends import(\"@emdash-cms/plugin-types\").PluginManifest ? true : never;\n// eslint-disable-next-line @typescript-eslint/no-unused-vars\nconst _MANIFEST_COMPAT: _AssertManifestCompat = true;\n"],"mappings":";;;AAmFA,MAAa,iCAET;CACH,CAAC,iBAAiB,eAAe;CACjC,CAAC,0BAA0B,eAAe;CAC1C,CAAC,oBAAoB,kBAAkB;CACvC,CAAC,mBAAmB,eAAe;CACnC,CAAC,eAAe,aAAa;CAC7B,CAAC,qBAAqB,gBAAgB;CACtC,CAAC,mBAAmB,iBAAiB;CACrC,CAAC,gCAAgC,kBAAkB;CACnD;AAMD,SAAgB,4BAA4B,cAA2C;CACtF,MAAM,aAAa,IAAI,IAAI,sBAAsB,aAAa,CAAC;AAC/D,MAAK,MAAM,CAAC,SAAS,YAAY,+BAChC,KAAI,WAAW,IAAI,QAAQ,CAAE,YAAW,IAAI,QAAQ;AAErD,QAAO,CAAC,GAAG,WAAW;;AAGvB,MAAM,uCAAuC,OAAO,IACnD,8CACA;;;;;AAMD,SAAgB,iCACf,UACA,cACO;CACP,MAAM,aAAa,aAAa,OAAO,uBAAuB;AAC9D,KAAI,WAAW,WAAW,EAAG;CAE7B,MAAM,IAAI;CAEV,MAAM,SAAU,EAAE,0DAA0C,IAAI,KAAa;AAC7E,KAAI,OAAO,IAAI,SAAS,CAAE;AAC1B,QAAO,IAAI,SAAS;CAEpB,MAAM,UAAU,WAAW,KAAK,QAAQ,GAAG,IAAI,KAAK,mBAAmB,OAAO,CAAC,KAAK,KAAK;AACzF,SAAQ,KACP,oBAAoB,SAAS,0CAA0C,QAAQ,mKAG/E"}
@@ -0,0 +1,204 @@
1
+ import * as react from "react";
2
+
3
+ //#region src/auth/types.d.ts
4
+ /**
5
+ * Auth Provider Types
6
+ *
7
+ * Defines the interfaces for pluggable authentication providers.
8
+ *
9
+ * Two systems coexist:
10
+ * - `AuthDescriptor` — transparent auth (Cloudflare Access) that authenticates
11
+ * every request via headers/cookies. No login UI needed.
12
+ * - `AuthProviderDescriptor` — pluggable login methods (GitHub, Google,
13
+ * AT Protocol, etc.) that appear as options on the login page and setup
14
+ * wizard. Passkey is built-in; providers are additive.
15
+ */
16
+ /**
17
+ * Result of authenticating a request via an external auth provider
18
+ */
19
+ interface AuthResult {
20
+ /** User's email address */
21
+ email: string;
22
+ /** User's display name */
23
+ name: string;
24
+ /** Resolved role level (e.g., 50 for Admin, 40 for Editor, 30 for Author) */
25
+ role: number;
26
+ /** Provider-specific subject ID */
27
+ subject?: string;
28
+ /** Additional provider-specific data */
29
+ metadata?: Record<string, unknown>;
30
+ }
31
+ /**
32
+ * Auth descriptor — transparent auth providers (e.g., Cloudflare Access).
33
+ *
34
+ * These authenticate every request via headers/cookies. No login UI needed.
35
+ * The module's `authenticate()` function is called by middleware on each request.
36
+ */
37
+ interface AuthDescriptor {
38
+ /**
39
+ * Auth provider type identifier
40
+ * @example "cloudflare-access", "okta", "auth0"
41
+ */
42
+ type: string;
43
+ /**
44
+ * Module specifier to import at runtime
45
+ * The module must export an `authenticate` function.
46
+ * @example "@emdash-cms/cloudflare/auth"
47
+ */
48
+ entrypoint: string;
49
+ /**
50
+ * Provider-specific configuration (JSON-serializable)
51
+ */
52
+ config: unknown;
53
+ }
54
+ /**
55
+ * Auth provider module interface
56
+ *
57
+ * Modules specified by AuthDescriptor.entrypoint must export
58
+ * an `authenticate` function matching this signature.
59
+ */
60
+ interface AuthProviderModule {
61
+ /**
62
+ * Authenticate a request using the provider
63
+ *
64
+ * @param request - The incoming HTTP request
65
+ * @param config - Provider-specific configuration from AuthDescriptor
66
+ * @returns Authentication result if valid, throws if invalid
67
+ */
68
+ authenticate(request: Request, config: unknown): Promise<AuthResult>;
69
+ }
70
+ /**
71
+ * Descriptor for a pluggable auth provider.
72
+ *
73
+ * Auth providers appear as login options on the login page and setup wizard.
74
+ * They coexist with passkey (which is built-in) and with each other.
75
+ * Any provider can be used to create the initial admin account.
76
+ *
77
+ * @example
78
+ * ```ts
79
+ * // astro.config.ts
80
+ * import { atproto } from "@emdash-cms/auth-atproto";
81
+ *
82
+ * emdash({
83
+ * authProviders: [atproto(), github(), google()],
84
+ * })
85
+ * ```
86
+ */
87
+ interface AuthProviderDescriptor {
88
+ /** Unique provider ID (e.g., "github", "atproto") */
89
+ id: string;
90
+ /** Human-readable label for UI (e.g., "GitHub", "AT Protocol") */
91
+ label: string;
92
+ /** Provider-specific config (JSON-serializable) */
93
+ config?: unknown;
94
+ /**
95
+ * Module exporting React components for the admin UI.
96
+ * Statically imported at build time via virtual module.
97
+ *
98
+ * The module should export components matching `AuthProviderAdminExports`.
99
+ */
100
+ adminEntry?: string;
101
+ /**
102
+ * Astro route handlers this provider needs injected at build time.
103
+ * Used for login initiation, OAuth callbacks, well-known endpoints, etc.
104
+ */
105
+ routes?: AuthRouteDescriptor[];
106
+ /**
107
+ * URL prefixes/paths that should bypass auth middleware.
108
+ * Added to the public routes set so login/callback endpoints work
109
+ * for unauthenticated users.
110
+ */
111
+ publicRoutes?: string[];
112
+ /**
113
+ * Storage collections for persistent auth state (e.g., OAuth sessions).
114
+ * Same format as plugin storage — collections are stored in the shared
115
+ * `_plugin_storage` table namespaced under `auth:<providerId>`.
116
+ *
117
+ * Access via `getAuthProviderStorage()` from `emdash/api/route-utils`.
118
+ */
119
+ storage?: Record<string, {
120
+ indexes?: Array<string | string[]>;
121
+ uniqueIndexes?: Array<string | string[]>;
122
+ }>;
123
+ }
124
+ /**
125
+ * A route that an auth provider needs injected into the Astro app.
126
+ */
127
+ interface AuthRouteDescriptor {
128
+ /** URL pattern (e.g., "/_emdash/api/auth/atproto/login") */
129
+ pattern: string;
130
+ /** Module specifier for the Astro route handler */
131
+ entrypoint: string;
132
+ }
133
+ /**
134
+ * Expected exports from an auth provider's `adminEntry` module.
135
+ *
136
+ * All exports are optional. Providers export whichever components
137
+ * make sense for their auth flow.
138
+ */
139
+ interface AuthProviderAdminExports {
140
+ /**
141
+ * Compact button for the login page (icon + label).
142
+ * Used for providers with a simple redirect flow (GitHub, Google).
143
+ * Rendered in the "Or continue with" section.
144
+ */
145
+ LoginButton?: react.ComponentType;
146
+ /**
147
+ * Full login form for providers that need custom input.
148
+ * Used for providers like AT Protocol that need a handle field.
149
+ * Rendered as an expandable section on the login page.
150
+ */
151
+ LoginForm?: react.ComponentType;
152
+ /**
153
+ * Setup wizard step for creating the admin account via this provider.
154
+ * When present, this provider appears as an option in the setup wizard's
155
+ * "Create admin account" step.
156
+ */
157
+ SetupStep?: react.ComponentType<{
158
+ onComplete: () => void;
159
+ }>;
160
+ }
161
+ /**
162
+ * Configuration options common to external auth providers
163
+ */
164
+ interface ExternalAuthConfig {
165
+ /**
166
+ * Automatically create EmDash users on first login
167
+ * @default true
168
+ */
169
+ autoProvision?: boolean;
170
+ /**
171
+ * Role level for users not matching any group in roleMapping
172
+ * @default 30 (Author, who can publish their own content)
173
+ */
174
+ defaultRole?: number;
175
+ /**
176
+ * Update user's role on each login based on current IdP groups
177
+ * When false, role is only set on first provisioning
178
+ * @default false
179
+ */
180
+ syncRoles?: boolean;
181
+ /**
182
+ * Update user's name from the IdP on every authenticated request
183
+ * When false, name is only set on first provisioning, so names edited in the admin are kept
184
+ * @default true
185
+ */
186
+ syncName?: boolean;
187
+ /**
188
+ * Map IdP group names to EmDash role levels
189
+ * First match wins if user is in multiple groups
190
+ *
191
+ * @example
192
+ * ```ts
193
+ * roleMapping: {
194
+ * "Admins": 50, // Admin
195
+ * "Editors": 40, // Editor
196
+ * "Content Team": 30, // Author
197
+ * }
198
+ * ```
199
+ */
200
+ roleMapping?: Record<string, number>;
201
+ }
202
+ //#endregion
203
+ export { AuthResult as a, AuthProviderModule as i, AuthProviderAdminExports as n, AuthRouteDescriptor as o, AuthProviderDescriptor as r, ExternalAuthConfig as s, AuthDescriptor as t };
204
+ //# sourceMappingURL=types-slSqujQL.d.mts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types-slSqujQL.d.mts","names":[],"sources":["../src/auth/types.ts"],"mappings":";;;;;;AAgBA;;;;;;;;;;;;UAAiB,UAAA;EAmBc;EAjB9B,KAAA;EAiB8B;EAf9B,IAAA;EA2BA;EAzBA,IAAA;EA8BM;EA5BN,OAAA;EAqCgB;EAnChB,QAAA,GAAW,MAAA;AAAA;;;;;;;UASK,cAAA;EAkCH;;;;EA7Bb,IAAA;EA6BmE;AAwBpE;;;;EA9CC,UAAA;EAsFuD;;;EAjFvD,MAAA;AAAA;;;;;;;UASgB,kBAAA;EAsEN;;;;;;;EA9DV,YAAA,CAAa,OAAA,EAAS,OAAA,EAAS,MAAA,YAAkB,OAAA,CAAQ,UAAA;AAAA;;;;AAoF1D;;;;;;;;;;;;;;UA5DiB,sBAAA;EAgFsC;EA9EtD,EAAA;EAoFgB;EAjFhB,KAAA;;EAGA,MAAA;EAmFA;;;;;;EA3EA,UAAA;EA8GoB;;;;EAxGpB,MAAA,GAAS,mBAAA;;;;;;EAOT,YAAA;;;;;;;;EASA,OAAA,GAAU,MAAA;IAEP,OAAA,GAAU,KAAA;IAA0B,aAAA,GAAgB,KAAA;EAAA;AAAA;;;;UAOvC,mBAAA;;EAEhB,OAAA;;EAEA,UAAA;AAAA;;;;;;;UASgB,wBAAA;;;;;;EAMhB,WAAA,GANwC,KAAA,CAMV,aAAA;;;;;;EAO9B,SAAA,GAP2C,KAAA,CAOf,aAAA;;;;;;EAO5B,SAAA,GAPyC,KAAA,CAOb,aAAA;IAAgB,UAAA;EAAA;AAAA;;;;UAM5B,kBAAA;;;;;EAKhB,aAAA;;;;;EAMA,WAAA;;;;;;EAOA,SAAA;;;;;;EAOA,QAAA;;;;;;;;;;;;;;EAeA,WAAA,GAAc,MAAA;AAAA"}
@@ -0,0 +1,161 @@
1
+ import { t as after } from "./after-PcEvMY_6.mjs";
2
+ import { t as OptionsRepository } from "./options-DhrI7eMv.mjs";
3
+ import { a as parseDurationSeconds } from "./config-DBU6iUQB.mjs";
4
+ import { n as VERSION } from "./version-DHmGpcch.mjs";
5
+ import { t as ErrorCode } from "./errors-BOYNdIo3.mjs";
6
+
7
+ //#region src/api/handlers/update-check.ts
8
+ /** Options-table key for the cached registry result. */
9
+ const CORE_UPDATE_OPTION = "emdash:core_update_check";
10
+ /** Check the registry at most once per day, whether or not the check succeeds. */
11
+ const CHECK_INTERVAL_MS = 1440 * 60 * 1e3;
12
+ /** npm packument for `emdash`: the `latest` dist-tag and each version's publish time. */
13
+ const REGISTRY_URL = "https://registry.npmjs.org/emdash";
14
+ /** Default time a release must be public before admins are told about it. */
15
+ const DEFAULT_MINIMUM_RELEASE_AGE = "24h";
16
+ const REGISTRY_TIMEOUT_MS = 1e4;
17
+ const SEMVER_RE = /^(\d+)\.(\d+)\.(\d+)(-.+)?$/;
18
+ const STABLE_RE = /^\d+\.\d+\.\d+$/;
19
+ /**
20
+ * True when `latest` is a strictly newer release than `current`.
21
+ *
22
+ * Handles plain `major.minor.patch` versions. Anything unparsable —
23
+ * including the `"dev"` fallback version — compares as "not newer", so
24
+ * dev/test runs never show the banner. On an equal base version, a stable
25
+ * release is newer than a prerelease of it, so a site running
26
+ * `0.24.0-beta.1` is notified when `0.24.0` ships. Prerelease identifiers
27
+ * are not compared to each other.
28
+ */
29
+ function isNewerVersion(latest, current) {
30
+ const l = SEMVER_RE.exec(latest);
31
+ const c = SEMVER_RE.exec(current);
32
+ if (!l || !c) return false;
33
+ for (let i = 1; i <= 3; i++) {
34
+ const a = Number(l[i]);
35
+ const b = Number(c[i]);
36
+ if (a !== b) return a > b;
37
+ }
38
+ return !l[4] && !!c[4];
39
+ }
40
+ function field(value, key) {
41
+ return typeof value === "object" && value !== null && Object.hasOwn(value, key) ? Reflect.get(value, key) : void 0;
42
+ }
43
+ /**
44
+ * Fetch the stable releases and their publish times from the npm registry
45
+ * and cache them. Exported for tests; production callers go through
46
+ * `handleCoreUpdateStatus`, which defers this via `after()`.
47
+ */
48
+ async function refreshCoreUpdateCache(db, fetchImpl = fetch) {
49
+ const response = await fetchImpl(REGISTRY_URL, {
50
+ headers: { accept: "application/json" },
51
+ signal: AbortSignal.timeout(REGISTRY_TIMEOUT_MS)
52
+ });
53
+ if (!response.ok) throw new Error(`registry responded ${response.status}`);
54
+ const body = await response.json();
55
+ const latest = field(field(body, "dist-tags"), "latest");
56
+ if (typeof latest !== "string" || !STABLE_RE.test(latest)) throw new Error("registry response missing a valid version");
57
+ const time = field(body, "time");
58
+ const versions = field(body, "versions");
59
+ const releases = {};
60
+ if (typeof time === "object" && time !== null) for (const [version, publishedAt] of Object.entries(time)) {
61
+ if (!STABLE_RE.test(version) || isNewerVersion(version, latest)) continue;
62
+ const manifest = field(versions, version);
63
+ if (manifest === void 0 || field(manifest, "deprecated") !== void 0) continue;
64
+ if (typeof publishedAt !== "string" || Number.isNaN(Date.parse(publishedAt))) continue;
65
+ releases[version] = publishedAt;
66
+ }
67
+ if (!releases[latest]) throw new Error("registry response missing a publish time for the latest version");
68
+ const cache = {
69
+ releases,
70
+ checkedAt: (/* @__PURE__ */ new Date()).toISOString()
71
+ };
72
+ await new OptionsRepository(db).set(CORE_UPDATE_OPTION, cache);
73
+ }
74
+ function parseCache(value) {
75
+ const releases = field(value, "releases");
76
+ const checkedAt = field(value, "checkedAt");
77
+ if (typeof releases !== "object" || releases === null || typeof checkedAt !== "string") return null;
78
+ if (Number.isNaN(Date.parse(checkedAt))) return null;
79
+ const valid = {};
80
+ for (const [version, publishedAt] of Object.entries(releases)) if (STABLE_RE.test(version) && typeof publishedAt === "string" && !Number.isNaN(Date.parse(publishedAt))) valid[version] = publishedAt;
81
+ return {
82
+ releases: valid,
83
+ checkedAt
84
+ };
85
+ }
86
+ /** The newest release published at least `minimumAgeMs` before `now`. */
87
+ function newestReleased(releases, now, minimumAgeMs) {
88
+ let newest = null;
89
+ for (const [version, publishedAt] of Object.entries(releases)) {
90
+ if (now.getTime() - Date.parse(publishedAt) < minimumAgeMs) continue;
91
+ if (!newest || isNewerVersion(version, newest)) newest = version;
92
+ }
93
+ return newest;
94
+ }
95
+ /**
96
+ * Seconds a release must be public before it is reported, from the
97
+ * `updateCheck` option. Throws on an invalid duration.
98
+ */
99
+ function minimumReleaseAgeSeconds(option) {
100
+ return parseDurationSeconds((typeof option === "object" ? option?.minimumReleaseAge : void 0) ?? DEFAULT_MINIMUM_RELEASE_AGE);
101
+ }
102
+ /**
103
+ * Report the cached update status and, when the cache is stale (or
104
+ * missing), kick a deferred registry refresh. Never blocks on the
105
+ * network: the first request after install/expiry reports the previous
106
+ * state and the next request sees the refreshed one.
107
+ */
108
+ async function handleCoreUpdateStatus(db, options) {
109
+ const current = options?.current ?? VERSION;
110
+ if (options?.enabled === false) return {
111
+ success: true,
112
+ data: {
113
+ current,
114
+ latest: null,
115
+ updateAvailable: false,
116
+ checkedAt: null
117
+ }
118
+ };
119
+ try {
120
+ const repo = new OptionsRepository(db);
121
+ const cache = parseCache(await repo.get(CORE_UPDATE_OPTION));
122
+ const now = options?.now ?? /* @__PURE__ */ new Date();
123
+ const minimumAgeMs = (options?.minimumReleaseAgeSeconds ?? minimumReleaseAgeSeconds(void 0)) * 1e3;
124
+ if ((!cache || now.getTime() - Date.parse(cache.checkedAt) >= CHECK_INTERVAL_MS) && current !== "dev") after(async () => {
125
+ try {
126
+ await refreshCoreUpdateCache(db);
127
+ } catch (error) {
128
+ console.warn("[update-check] registry refresh failed:", error);
129
+ if (parseCache(await repo.get(CORE_UPDATE_OPTION))?.checkedAt !== cache?.checkedAt) return;
130
+ const retryLater = {
131
+ releases: cache?.releases ?? {},
132
+ checkedAt: (/* @__PURE__ */ new Date()).toISOString()
133
+ };
134
+ await repo.set(CORE_UPDATE_OPTION, retryLater);
135
+ }
136
+ });
137
+ const latest = cache ? newestReleased(cache.releases, now, minimumAgeMs) : null;
138
+ return {
139
+ success: true,
140
+ data: {
141
+ current,
142
+ latest,
143
+ updateAvailable: latest ? isNewerVersion(latest, current) : false,
144
+ checkedAt: cache?.checkedAt ?? null
145
+ }
146
+ };
147
+ } catch (error) {
148
+ console.error("[update-check] status read failed:", error);
149
+ return {
150
+ success: false,
151
+ error: {
152
+ code: ErrorCode.UPDATE_CHECK_ERROR,
153
+ message: "Failed to read update status"
154
+ }
155
+ };
156
+ }
157
+ }
158
+
159
+ //#endregion
160
+ export { minimumReleaseAgeSeconds as n, handleCoreUpdateStatus as t };
161
+ //# sourceMappingURL=update-check-BxNg9T6N.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"update-check-BxNg9T6N.mjs","names":[],"sources":["../src/api/handlers/update-check.ts"],"sourcesContent":["/**\n * Core update status handler.\n *\n * Caches the publish times of stable `emdash` releases from the npm\n * registry in the options table, and reports the newest release that has\n * been public for the minimum release age when it is newer than the\n * running `VERSION`. A stale or missing cache schedules a deferred refresh.\n */\n\nimport type { Kysely } from \"kysely\";\n\nimport { after } from \"../../after.js\";\nimport { OptionsRepository } from \"../../database/repositories/options.js\";\nimport type { Database } from \"../../database/types.js\";\nimport { parseDurationSeconds } from \"../../registry/config.js\";\nimport { VERSION } from \"../../version.js\";\nimport { ErrorCode } from \"../errors.js\";\nimport type { ApiResult } from \"../types.js\";\n\n/** Options-table key for the cached registry result. */\nexport const CORE_UPDATE_OPTION = \"emdash:core_update_check\";\n\n/** Check the registry at most once per day, whether or not the check succeeds. */\nconst CHECK_INTERVAL_MS = 24 * 60 * 60 * 1000;\n\n/** npm packument for `emdash`: the `latest` dist-tag and each version's publish time. */\nconst REGISTRY_URL = \"https://registry.npmjs.org/emdash\";\n\n/** Default time a release must be public before admins are told about it. */\nexport const DEFAULT_MINIMUM_RELEASE_AGE = \"24h\";\n\nconst REGISTRY_TIMEOUT_MS = 10_000;\n\n/** Cached registry state, stored in the options table. */\ninterface CoreUpdateCache {\n\t/** Publish time (ISO) of each non-deprecated stable release up to the `latest` dist-tag. */\n\treleases: Record<string, string>;\n\t/** ISO timestamp of the last registry check. */\n\tcheckedAt: string;\n}\n\nexport interface CoreUpdateStatus {\n\t/** The running EmDash version (`\"dev\"` in uncompiled dev/test runs). */\n\tcurrent: string;\n\t/**\n\t * Newest stable release that has been public for the minimum release\n\t * age, or null when no check has completed yet.\n\t */\n\tlatest: string | null;\n\tupdateAvailable: boolean;\n\t/** ISO timestamp of the last registry check, if any. */\n\tcheckedAt: string | null;\n}\n\nconst SEMVER_RE = /^(\\d+)\\.(\\d+)\\.(\\d+)(-.+)?$/;\nconst STABLE_RE = /^\\d+\\.\\d+\\.\\d+$/;\n\n/**\n * True when `latest` is a strictly newer release than `current`.\n *\n * Handles plain `major.minor.patch` versions. Anything unparsable —\n * including the `\"dev\"` fallback version — compares as \"not newer\", so\n * dev/test runs never show the banner. On an equal base version, a stable\n * release is newer than a prerelease of it, so a site running\n * `0.24.0-beta.1` is notified when `0.24.0` ships. Prerelease identifiers\n * are not compared to each other.\n */\nexport function isNewerVersion(latest: string, current: string): boolean {\n\tconst l = SEMVER_RE.exec(latest);\n\tconst c = SEMVER_RE.exec(current);\n\tif (!l || !c) return false;\n\tfor (let i = 1; i <= 3; i++) {\n\t\tconst a = Number(l[i]);\n\t\tconst b = Number(c[i]);\n\t\tif (a !== b) return a > b;\n\t}\n\treturn !l[4] && !!c[4];\n}\n\nfunction field(value: unknown, key: string): unknown {\n\treturn typeof value === \"object\" && value !== null && Object.hasOwn(value, key)\n\t\t? (Reflect.get(value, key) as unknown)\n\t\t: undefined;\n}\n\n/**\n * Fetch the stable releases and their publish times from the npm registry\n * and cache them. Exported for tests; production callers go through\n * `handleCoreUpdateStatus`, which defers this via `after()`.\n */\nexport async function refreshCoreUpdateCache(\n\tdb: Kysely<Database>,\n\tfetchImpl: typeof fetch = fetch,\n): Promise<void> {\n\tconst response = await fetchImpl(REGISTRY_URL, {\n\t\theaders: { accept: \"application/json\" },\n\t\tsignal: AbortSignal.timeout(REGISTRY_TIMEOUT_MS),\n\t});\n\tif (!response.ok) {\n\t\tthrow new Error(`registry responded ${response.status}`);\n\t}\n\tconst body: unknown = await response.json();\n\tconst latest = field(field(body, \"dist-tags\"), \"latest\");\n\tif (typeof latest !== \"string\" || !STABLE_RE.test(latest)) {\n\t\tthrow new Error(\"registry response missing a valid version\");\n\t}\n\tconst time = field(body, \"time\");\n\tconst versions = field(body, \"versions\");\n\tconst releases: Record<string, string> = {};\n\tif (typeof time === \"object\" && time !== null) {\n\t\tfor (const [version, publishedAt] of Object.entries(time)) {\n\t\t\tif (!STABLE_RE.test(version) || isNewerVersion(version, latest)) continue;\n\t\t\tconst manifest = field(versions, version);\n\t\t\tif (manifest === undefined || field(manifest, \"deprecated\") !== undefined) continue;\n\t\t\tif (typeof publishedAt !== \"string\" || Number.isNaN(Date.parse(publishedAt))) continue;\n\t\t\treleases[version] = publishedAt;\n\t\t}\n\t}\n\tif (!releases[latest]) {\n\t\tthrow new Error(\"registry response missing a publish time for the latest version\");\n\t}\n\tconst cache: CoreUpdateCache = { releases, checkedAt: new Date().toISOString() };\n\tawait new OptionsRepository(db).set(CORE_UPDATE_OPTION, cache);\n}\n\nfunction parseCache(value: unknown): CoreUpdateCache | null {\n\tconst releases = field(value, \"releases\");\n\tconst checkedAt = field(value, \"checkedAt\");\n\tif (typeof releases !== \"object\" || releases === null || typeof checkedAt !== \"string\") {\n\t\treturn null;\n\t}\n\t// An unparsable checkedAt would make the staleness math NaN (never\n\t// stale), freezing a corrupt cache forever — treat it as no cache so\n\t// the next request schedules a refresh that overwrites it.\n\tif (Number.isNaN(Date.parse(checkedAt))) return null;\n\tconst valid: Record<string, string> = {};\n\tfor (const [version, publishedAt] of Object.entries(releases)) {\n\t\tif (\n\t\t\tSTABLE_RE.test(version) &&\n\t\t\ttypeof publishedAt === \"string\" &&\n\t\t\t!Number.isNaN(Date.parse(publishedAt))\n\t\t) {\n\t\t\tvalid[version] = publishedAt;\n\t\t}\n\t}\n\treturn { releases: valid, checkedAt };\n}\n\n/** The newest release published at least `minimumAgeMs` before `now`. */\nfunction newestReleased(\n\treleases: Record<string, string>,\n\tnow: Date,\n\tminimumAgeMs: number,\n): string | null {\n\tlet newest: string | null = null;\n\tfor (const [version, publishedAt] of Object.entries(releases)) {\n\t\tif (now.getTime() - Date.parse(publishedAt) < minimumAgeMs) continue;\n\t\tif (!newest || isNewerVersion(version, newest)) newest = version;\n\t}\n\treturn newest;\n}\n\n/**\n * Seconds a release must be public before it is reported, from the\n * `updateCheck` option. Throws on an invalid duration.\n */\nexport function minimumReleaseAgeSeconds(\n\toption: boolean | { minimumReleaseAge?: string | number } | null | undefined,\n): number {\n\tconst age = typeof option === \"object\" ? option?.minimumReleaseAge : undefined;\n\treturn parseDurationSeconds(age ?? DEFAULT_MINIMUM_RELEASE_AGE);\n}\n\n/**\n * Report the cached update status and, when the cache is stale (or\n * missing), kick a deferred registry refresh. Never blocks on the\n * network: the first request after install/expiry reports the previous\n * state and the next request sees the refreshed one.\n */\nexport async function handleCoreUpdateStatus(\n\tdb: Kysely<Database>,\n\toptions?: { now?: Date; enabled?: boolean; minimumReleaseAgeSeconds?: number; current?: string },\n): Promise<ApiResult<CoreUpdateStatus>> {\n\tconst current = options?.current ?? VERSION;\n\tif (options?.enabled === false) {\n\t\treturn {\n\t\t\tsuccess: true,\n\t\t\tdata: { current, latest: null, updateAvailable: false, checkedAt: null },\n\t\t};\n\t}\n\n\ttry {\n\t\tconst repo = new OptionsRepository(db);\n\t\tconst cache = parseCache(await repo.get(CORE_UPDATE_OPTION));\n\n\t\tconst now = options?.now ?? new Date();\n\t\tconst minimumAgeMs =\n\t\t\t(options?.minimumReleaseAgeSeconds ?? minimumReleaseAgeSeconds(undefined)) * 1000;\n\t\tconst stale = !cache || now.getTime() - Date.parse(cache.checkedAt) >= CHECK_INTERVAL_MS;\n\t\t// A \"dev\" version can never compare as outdated, so skip the\n\t\t// registry round-trip entirely in uncompiled dev/test runs.\n\t\tif (stale && current !== \"dev\") {\n\t\t\tafter(async () => {\n\t\t\t\ttry {\n\t\t\t\t\tawait refreshCoreUpdateCache(db);\n\t\t\t\t} catch (error) {\n\t\t\t\t\tconsole.warn(\"[update-check] registry refresh failed:\", error);\n\t\t\t\t\tconst latestCache = parseCache(await repo.get(CORE_UPDATE_OPTION));\n\t\t\t\t\tif (latestCache?.checkedAt !== cache?.checkedAt) return;\n\t\t\t\t\tconst retryLater: CoreUpdateCache = {\n\t\t\t\t\t\treleases: cache?.releases ?? {},\n\t\t\t\t\t\tcheckedAt: new Date().toISOString(),\n\t\t\t\t\t};\n\t\t\t\t\tawait repo.set(CORE_UPDATE_OPTION, retryLater);\n\t\t\t\t}\n\t\t\t});\n\t\t}\n\n\t\tconst latest = cache ? newestReleased(cache.releases, now, minimumAgeMs) : null;\n\t\treturn {\n\t\t\tsuccess: true,\n\t\t\tdata: {\n\t\t\t\tcurrent,\n\t\t\t\tlatest,\n\t\t\t\tupdateAvailable: latest ? isNewerVersion(latest, current) : false,\n\t\t\t\tcheckedAt: cache?.checkedAt ?? null,\n\t\t\t},\n\t\t};\n\t} catch (error) {\n\t\tconsole.error(\"[update-check] status read failed:\", error);\n\t\treturn {\n\t\t\tsuccess: false,\n\t\t\terror: { code: ErrorCode.UPDATE_CHECK_ERROR, message: \"Failed to read update status\" },\n\t\t};\n\t}\n}\n"],"mappings":";;;;;;;;AAoBA,MAAa,qBAAqB;;AAGlC,MAAM,oBAAoB,OAAU,KAAK;;AAGzC,MAAM,eAAe;;AAGrB,MAAa,8BAA8B;AAE3C,MAAM,sBAAsB;AAuB5B,MAAM,YAAY;AAClB,MAAM,YAAY;;;;;;;;;;;AAYlB,SAAgB,eAAe,QAAgB,SAA0B;CACxE,MAAM,IAAI,UAAU,KAAK,OAAO;CAChC,MAAM,IAAI,UAAU,KAAK,QAAQ;AACjC,KAAI,CAAC,KAAK,CAAC,EAAG,QAAO;AACrB,MAAK,IAAI,IAAI,GAAG,KAAK,GAAG,KAAK;EAC5B,MAAM,IAAI,OAAO,EAAE,GAAG;EACtB,MAAM,IAAI,OAAO,EAAE,GAAG;AACtB,MAAI,MAAM,EAAG,QAAO,IAAI;;AAEzB,QAAO,CAAC,EAAE,MAAM,CAAC,CAAC,EAAE;;AAGrB,SAAS,MAAM,OAAgB,KAAsB;AACpD,QAAO,OAAO,UAAU,YAAY,UAAU,QAAQ,OAAO,OAAO,OAAO,IAAI,GAC3E,QAAQ,IAAI,OAAO,IAAI,GACxB;;;;;;;AAQJ,eAAsB,uBACrB,IACA,YAA0B,OACV;CAChB,MAAM,WAAW,MAAM,UAAU,cAAc;EAC9C,SAAS,EAAE,QAAQ,oBAAoB;EACvC,QAAQ,YAAY,QAAQ,oBAAoB;EAChD,CAAC;AACF,KAAI,CAAC,SAAS,GACb,OAAM,IAAI,MAAM,sBAAsB,SAAS,SAAS;CAEzD,MAAM,OAAgB,MAAM,SAAS,MAAM;CAC3C,MAAM,SAAS,MAAM,MAAM,MAAM,YAAY,EAAE,SAAS;AACxD,KAAI,OAAO,WAAW,YAAY,CAAC,UAAU,KAAK,OAAO,CACxD,OAAM,IAAI,MAAM,4CAA4C;CAE7D,MAAM,OAAO,MAAM,MAAM,OAAO;CAChC,MAAM,WAAW,MAAM,MAAM,WAAW;CACxC,MAAM,WAAmC,EAAE;AAC3C,KAAI,OAAO,SAAS,YAAY,SAAS,KACxC,MAAK,MAAM,CAAC,SAAS,gBAAgB,OAAO,QAAQ,KAAK,EAAE;AAC1D,MAAI,CAAC,UAAU,KAAK,QAAQ,IAAI,eAAe,SAAS,OAAO,CAAE;EACjE,MAAM,WAAW,MAAM,UAAU,QAAQ;AACzC,MAAI,aAAa,UAAa,MAAM,UAAU,aAAa,KAAK,OAAW;AAC3E,MAAI,OAAO,gBAAgB,YAAY,OAAO,MAAM,KAAK,MAAM,YAAY,CAAC,CAAE;AAC9E,WAAS,WAAW;;AAGtB,KAAI,CAAC,SAAS,QACb,OAAM,IAAI,MAAM,kEAAkE;CAEnF,MAAM,QAAyB;EAAE;EAAU,4BAAW,IAAI,MAAM,EAAC,aAAa;EAAE;AAChF,OAAM,IAAI,kBAAkB,GAAG,CAAC,IAAI,oBAAoB,MAAM;;AAG/D,SAAS,WAAW,OAAwC;CAC3D,MAAM,WAAW,MAAM,OAAO,WAAW;CACzC,MAAM,YAAY,MAAM,OAAO,YAAY;AAC3C,KAAI,OAAO,aAAa,YAAY,aAAa,QAAQ,OAAO,cAAc,SAC7E,QAAO;AAKR,KAAI,OAAO,MAAM,KAAK,MAAM,UAAU,CAAC,CAAE,QAAO;CAChD,MAAM,QAAgC,EAAE;AACxC,MAAK,MAAM,CAAC,SAAS,gBAAgB,OAAO,QAAQ,SAAS,CAC5D,KACC,UAAU,KAAK,QAAQ,IACvB,OAAO,gBAAgB,YACvB,CAAC,OAAO,MAAM,KAAK,MAAM,YAAY,CAAC,CAEtC,OAAM,WAAW;AAGnB,QAAO;EAAE,UAAU;EAAO;EAAW;;;AAItC,SAAS,eACR,UACA,KACA,cACgB;CAChB,IAAI,SAAwB;AAC5B,MAAK,MAAM,CAAC,SAAS,gBAAgB,OAAO,QAAQ,SAAS,EAAE;AAC9D,MAAI,IAAI,SAAS,GAAG,KAAK,MAAM,YAAY,GAAG,aAAc;AAC5D,MAAI,CAAC,UAAU,eAAe,SAAS,OAAO,CAAE,UAAS;;AAE1D,QAAO;;;;;;AAOR,SAAgB,yBACf,QACS;AAET,QAAO,sBADK,OAAO,WAAW,WAAW,QAAQ,oBAAoB,WAClC,4BAA4B;;;;;;;;AAShE,eAAsB,uBACrB,IACA,SACuC;CACvC,MAAM,UAAU,SAAS,WAAW;AACpC,KAAI,SAAS,YAAY,MACxB,QAAO;EACN,SAAS;EACT,MAAM;GAAE;GAAS,QAAQ;GAAM,iBAAiB;GAAO,WAAW;GAAM;EACxE;AAGF,KAAI;EACH,MAAM,OAAO,IAAI,kBAAkB,GAAG;EACtC,MAAM,QAAQ,WAAW,MAAM,KAAK,IAAI,mBAAmB,CAAC;EAE5D,MAAM,MAAM,SAAS,uBAAO,IAAI,MAAM;EACtC,MAAM,gBACJ,SAAS,4BAA4B,yBAAyB,OAAU,IAAI;AAI9E,OAHc,CAAC,SAAS,IAAI,SAAS,GAAG,KAAK,MAAM,MAAM,UAAU,IAAI,sBAG1D,YAAY,MACxB,OAAM,YAAY;AACjB,OAAI;AACH,UAAM,uBAAuB,GAAG;YACxB,OAAO;AACf,YAAQ,KAAK,2CAA2C,MAAM;AAE9D,QADoB,WAAW,MAAM,KAAK,IAAI,mBAAmB,CAAC,EACjD,cAAc,OAAO,UAAW;IACjD,MAAM,aAA8B;KACnC,UAAU,OAAO,YAAY,EAAE;KAC/B,4BAAW,IAAI,MAAM,EAAC,aAAa;KACnC;AACD,UAAM,KAAK,IAAI,oBAAoB,WAAW;;IAE9C;EAGH,MAAM,SAAS,QAAQ,eAAe,MAAM,UAAU,KAAK,aAAa,GAAG;AAC3E,SAAO;GACN,SAAS;GACT,MAAM;IACL;IACA;IACA,iBAAiB,SAAS,eAAe,QAAQ,QAAQ,GAAG;IAC5D,WAAW,OAAO,aAAa;IAC/B;GACD;UACO,OAAO;AACf,UAAQ,MAAM,sCAAsC,MAAM;AAC1D,SAAO;GACN,SAAS;GACT,OAAO;IAAE,MAAM,UAAU;IAAoB,SAAS;IAAgC;GACtF"}
@@ -0,0 +1,32 @@
1
+ //#region src/media/upload-attempts.ts
2
+ async function removeUploadAttempt(storage, repo, storageKey, options = {}) {
3
+ try {
4
+ if (!await repo.claimUploadAttemptForCleanup(storageKey)) {
5
+ if (await repo.hasUploadAttempt(storageKey) || !options.allowUntracked) return false;
6
+ }
7
+ } catch (error) {
8
+ console.error("[media] upload cleanup claim failed:", error);
9
+ return false;
10
+ }
11
+ try {
12
+ await storage.delete(storageKey);
13
+ } catch (error) {
14
+ console.error("[media] upload cleanup failed:", error);
15
+ try {
16
+ await repo.deferUploadAttemptCleanup(storageKey);
17
+ } catch (deferError) {
18
+ console.error("[media] upload cleanup deferral failed:", deferError);
19
+ }
20
+ return false;
21
+ }
22
+ try {
23
+ await repo.deleteUploadAttempt(storageKey);
24
+ } catch (error) {
25
+ console.error("[media] upload cleanup record deletion failed:", error);
26
+ }
27
+ return true;
28
+ }
29
+
30
+ //#endregion
31
+ export { removeUploadAttempt as t };
32
+ //# sourceMappingURL=upload-attempts-DPFC4COv.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"upload-attempts-DPFC4COv.mjs","names":[],"sources":["../src/media/upload-attempts.ts"],"sourcesContent":["import type { MediaRepository } from \"../database/repositories/media.js\";\nimport type { Storage } from \"../storage/types.js\";\n\nexport async function removeUploadAttempt(\n\tstorage: Storage,\n\trepo: MediaRepository,\n\tstorageKey: string,\n\toptions: { allowUntracked?: boolean } = {},\n): Promise<boolean> {\n\ttry {\n\t\tif (!(await repo.claimUploadAttemptForCleanup(storageKey))) {\n\t\t\tconst tracked = await repo.hasUploadAttempt(storageKey);\n\t\t\tif (tracked || !options.allowUntracked) return false;\n\t\t}\n\t} catch (error) {\n\t\tconsole.error(\"[media] upload cleanup claim failed:\", error);\n\t\treturn false;\n\t}\n\n\ttry {\n\t\tawait storage.delete(storageKey);\n\t} catch (error) {\n\t\tconsole.error(\"[media] upload cleanup failed:\", error);\n\t\ttry {\n\t\t\tawait repo.deferUploadAttemptCleanup(storageKey);\n\t\t} catch (deferError) {\n\t\t\tconsole.error(\"[media] upload cleanup deferral failed:\", deferError);\n\t\t}\n\t\treturn false;\n\t}\n\n\ttry {\n\t\tawait repo.deleteUploadAttempt(storageKey);\n\t} catch (error) {\n\t\tconsole.error(\"[media] upload cleanup record deletion failed:\", error);\n\t}\n\treturn true;\n}\n"],"mappings":";AAGA,eAAsB,oBACrB,SACA,MACA,YACA,UAAwC,EAAE,EACvB;AACnB,KAAI;AACH,MAAI,CAAE,MAAM,KAAK,6BAA6B,WAAW,EAExD;OADgB,MAAM,KAAK,iBAAiB,WAAW,IACxC,CAAC,QAAQ,eAAgB,QAAO;;UAExC,OAAO;AACf,UAAQ,MAAM,wCAAwC,MAAM;AAC5D,SAAO;;AAGR,KAAI;AACH,QAAM,QAAQ,OAAO,WAAW;UACxB,OAAO;AACf,UAAQ,MAAM,kCAAkC,MAAM;AACtD,MAAI;AACH,SAAM,KAAK,0BAA0B,WAAW;WACxC,YAAY;AACpB,WAAQ,MAAM,2CAA2C,WAAW;;AAErE,SAAO;;AAGR,KAAI;AACH,QAAM,KAAK,oBAAoB,WAAW;UAClC,OAAO;AACf,UAAQ,MAAM,kDAAkD,MAAM;;AAEvE,QAAO"}