emdash 0.38.0 → 0.39.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (1394) hide show
  1. package/dist/action-token-On1sot_c.mjs +26 -0
  2. package/dist/action-token-On1sot_c.mjs.map +1 -0
  3. package/dist/activation-CaMfdBt1.mjs +382 -0
  4. package/dist/activation-CaMfdBt1.mjs.map +1 -0
  5. package/dist/adapters-Cq10K4_c.d.mts +171 -0
  6. package/dist/adapters-Cq10K4_c.d.mts.map +1 -0
  7. package/dist/after-PcEvMY_6.mjs +96 -0
  8. package/dist/after-PcEvMY_6.mjs.map +1 -0
  9. package/dist/allowed-origins-1Sa-2wZK.mjs +116 -0
  10. package/dist/allowed-origins-1Sa-2wZK.mjs.map +1 -0
  11. package/dist/api/route-utils.d.mts +4 -3
  12. package/dist/api/route-utils.d.mts.map +1 -1
  13. package/dist/api/route-utils.mjs +45 -30
  14. package/dist/api/route-utils.mjs.map +1 -1
  15. package/dist/api/schemas/index.d.mts +2 -2
  16. package/dist/api/schemas/index.mjs +7 -6
  17. package/dist/api-BB5BoQbN.mjs +4831 -0
  18. package/dist/api-BB5BoQbN.mjs.map +1 -0
  19. package/dist/api-tokens-BIXItFKV.mjs +163 -0
  20. package/dist/api-tokens-BIXItFKV.mjs.map +1 -0
  21. package/dist/apply-CsKm_5S5.mjs +1005 -0
  22. package/dist/apply-CsKm_5S5.mjs.map +1 -0
  23. package/dist/artifact-fetch-COiMhVgk.mjs +813 -0
  24. package/dist/artifact-fetch-COiMhVgk.mjs.map +1 -0
  25. package/dist/astro/index.d.mts +14 -12
  26. package/dist/astro/index.d.mts.map +1 -1
  27. package/dist/astro/index.mjs +99 -15
  28. package/dist/astro/index.mjs.map +1 -1
  29. package/dist/astro/middleware/auth.d.mts +12 -10
  30. package/dist/astro/middleware/auth.d.mts.map +1 -1
  31. package/dist/astro/middleware/auth.mjs +20 -11
  32. package/dist/astro/middleware/auth.mjs.map +1 -1
  33. package/dist/astro/middleware/media-usage-write-fence.mjs +5 -5
  34. package/dist/astro/middleware/redirect.mjs +11 -11
  35. package/dist/astro/middleware/request-context.d.mts +1 -1
  36. package/dist/astro/middleware/request-context.d.mts.map +1 -1
  37. package/dist/astro/middleware/request-context.mjs +154 -28
  38. package/dist/astro/middleware/request-context.mjs.map +1 -1
  39. package/dist/astro/middleware/setup.mjs +1 -1
  40. package/dist/astro/middleware.d.mts +13 -10
  41. package/dist/astro/middleware.d.mts.map +1 -1
  42. package/dist/astro/middleware.mjs +115 -3062
  43. package/dist/astro/middleware.mjs.map +1 -1
  44. package/dist/astro/routes/api/admin/allowed-domains/_domain_.mjs +10 -9
  45. package/dist/astro/routes/api/admin/allowed-domains/_domain_.mjs.map +1 -1
  46. package/dist/astro/routes/api/admin/allowed-domains/index.mjs +10 -9
  47. package/dist/astro/routes/api/admin/allowed-domains/index.mjs.map +1 -1
  48. package/dist/astro/routes/api/admin/api-tokens/_id_.mjs +5 -5
  49. package/dist/astro/routes/api/admin/api-tokens/index.mjs +6 -6
  50. package/dist/astro/routes/api/admin/byline-fields/_slug_/usage.mjs +6 -6
  51. package/dist/astro/routes/api/admin/byline-fields/_slug_.mjs +13 -12
  52. package/dist/astro/routes/api/admin/byline-fields/_slug_.mjs.map +1 -1
  53. package/dist/astro/routes/api/admin/byline-fields/index.mjs +13 -12
  54. package/dist/astro/routes/api/admin/byline-fields/index.mjs.map +1 -1
  55. package/dist/astro/routes/api/admin/byline-fields/reorder.mjs +13 -12
  56. package/dist/astro/routes/api/admin/byline-fields/reorder.mjs.map +1 -1
  57. package/dist/astro/routes/api/admin/bylines/_id_/index.mjs +22 -21
  58. package/dist/astro/routes/api/admin/bylines/_id_/index.mjs.map +1 -1
  59. package/dist/astro/routes/api/admin/bylines/_id_/translations.mjs +22 -21
  60. package/dist/astro/routes/api/admin/bylines/_id_/translations.mjs.map +1 -1
  61. package/dist/astro/routes/api/admin/bylines/index.mjs +22 -21
  62. package/dist/astro/routes/api/admin/bylines/index.mjs.map +1 -1
  63. package/dist/astro/routes/api/admin/comments/_id_/status.d.mts.map +1 -1
  64. package/dist/astro/routes/api/admin/comments/_id_/status.mjs +21 -54
  65. package/dist/astro/routes/api/admin/comments/_id_/status.mjs.map +1 -1
  66. package/dist/astro/routes/api/admin/comments/_id_.mjs +8 -8
  67. package/dist/astro/routes/api/admin/comments/bulk.mjs +15 -14
  68. package/dist/astro/routes/api/admin/comments/bulk.mjs.map +1 -1
  69. package/dist/astro/routes/api/admin/comments/counts.mjs +8 -8
  70. package/dist/astro/routes/api/admin/comments/index.mjs +15 -14
  71. package/dist/astro/routes/api/admin/comments/index.mjs.map +1 -1
  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 +17 -16
  75. package/dist/astro/routes/api/admin/media-usage/activation.mjs.map +1 -1
  76. package/dist/astro/routes/api/admin/media-usage/collection-deletions/index.mjs +19 -18
  77. package/dist/astro/routes/api/admin/media-usage/collection-deletions/index.mjs.map +1 -1
  78. package/dist/astro/routes/api/admin/media-usage/collection-deletions/retry.mjs +19 -18
  79. package/dist/astro/routes/api/admin/media-usage/collection-deletions/retry.mjs.map +1 -1
  80. package/dist/astro/routes/api/admin/media-usage/progress.mjs +17 -17
  81. package/dist/astro/routes/api/admin/media-usage/repair.mjs +21 -20
  82. package/dist/astro/routes/api/admin/media-usage/repair.mjs.map +1 -1
  83. package/dist/astro/routes/api/admin/media-usage/work/index.mjs +19 -18
  84. package/dist/astro/routes/api/admin/media-usage/work/index.mjs.map +1 -1
  85. package/dist/astro/routes/api/admin/media-usage/work/retry.mjs +19 -18
  86. package/dist/astro/routes/api/admin/media-usage/work/retry.mjs.map +1 -1
  87. package/dist/astro/routes/api/admin/oauth-clients/_id_.mjs +5 -5
  88. package/dist/astro/routes/api/admin/oauth-clients/index.mjs +5 -5
  89. package/dist/astro/routes/api/admin/plugins/_id_/disable.d.mts.map +1 -1
  90. package/dist/astro/routes/api/admin/plugins/_id_/disable.mjs +9 -69
  91. package/dist/astro/routes/api/admin/plugins/_id_/disable.mjs.map +1 -1
  92. package/dist/astro/routes/api/admin/plugins/_id_/enable.d.mts.map +1 -1
  93. package/dist/astro/routes/api/admin/plugins/_id_/enable.mjs +9 -72
  94. package/dist/astro/routes/api/admin/plugins/_id_/enable.mjs.map +1 -1
  95. package/dist/astro/routes/api/admin/plugins/_id_/index.mjs +67 -62
  96. package/dist/astro/routes/api/admin/plugins/_id_/index.mjs.map +1 -1
  97. package/dist/astro/routes/api/admin/plugins/_id_/mcp.mjs +6 -6
  98. package/dist/astro/routes/api/admin/plugins/_id_/settings.mjs +66 -62
  99. package/dist/astro/routes/api/admin/plugins/_id_/settings.mjs.map +1 -1
  100. package/dist/astro/routes/api/admin/plugins/_id_/uninstall.mjs +71 -64
  101. package/dist/astro/routes/api/admin/plugins/_id_/uninstall.mjs.map +1 -1
  102. package/dist/astro/routes/api/admin/plugins/_id_/update.d.mts.map +1 -1
  103. package/dist/astro/routes/api/admin/plugins/_id_/update.mjs +88 -66
  104. package/dist/astro/routes/api/admin/plugins/_id_/update.mjs.map +1 -1
  105. package/dist/astro/routes/api/admin/plugins/index.mjs +67 -62
  106. package/dist/astro/routes/api/admin/plugins/index.mjs.map +1 -1
  107. package/dist/astro/routes/api/admin/plugins/marketplace/_id_/icon.mjs +4 -4
  108. package/dist/astro/routes/api/admin/plugins/marketplace/_id_/index.mjs +66 -62
  109. package/dist/astro/routes/api/admin/plugins/marketplace/_id_/index.mjs.map +1 -1
  110. package/dist/astro/routes/api/admin/plugins/marketplace/_id_/install.d.mts.map +1 -1
  111. package/dist/astro/routes/api/admin/plugins/marketplace/_id_/install.mjs +86 -66
  112. package/dist/astro/routes/api/admin/plugins/marketplace/_id_/install.mjs.map +1 -1
  113. package/dist/astro/routes/api/admin/plugins/marketplace/index.mjs +66 -62
  114. package/dist/astro/routes/api/admin/plugins/marketplace/index.mjs.map +1 -1
  115. package/dist/astro/routes/api/admin/plugins/registry/_id_/uninstall.mjs +71 -64
  116. package/dist/astro/routes/api/admin/plugins/registry/_id_/uninstall.mjs.map +1 -1
  117. package/dist/astro/routes/api/admin/plugins/registry/_id_/update.d.mts.map +1 -1
  118. package/dist/astro/routes/api/admin/plugins/registry/_id_/update.mjs +91 -69
  119. package/dist/astro/routes/api/admin/plugins/registry/_id_/update.mjs.map +1 -1
  120. package/dist/astro/routes/api/admin/plugins/registry/artifact.d.mts.map +1 -1
  121. package/dist/astro/routes/api/admin/plugins/registry/artifact.mjs +9 -8
  122. package/dist/astro/routes/api/admin/plugins/registry/artifact.mjs.map +1 -1
  123. package/dist/astro/routes/api/admin/plugins/registry/install.d.mts.map +1 -1
  124. package/dist/astro/routes/api/admin/plugins/registry/install.mjs +78 -66
  125. package/dist/astro/routes/api/admin/plugins/registry/install.mjs.map +1 -1
  126. package/dist/astro/routes/api/admin/plugins/registry/verify.d.mts.map +1 -1
  127. package/dist/astro/routes/api/admin/plugins/registry/verify.mjs +68 -64
  128. package/dist/astro/routes/api/admin/plugins/registry/verify.mjs.map +1 -1
  129. package/dist/astro/routes/api/admin/plugins/updates.d.mts.map +1 -1
  130. package/dist/astro/routes/api/admin/plugins/updates.mjs +67 -63
  131. package/dist/astro/routes/api/admin/plugins/updates.mjs.map +1 -1
  132. package/dist/astro/routes/api/admin/scheduled-policy-rejections/_collection_/_id_.d.mts +8 -0
  133. package/dist/astro/routes/api/admin/scheduled-policy-rejections/_collection_/_id_.d.mts.map +1 -0
  134. package/dist/astro/routes/api/admin/scheduled-policy-rejections/_collection_/_id_.mjs +27 -0
  135. package/dist/astro/routes/api/admin/scheduled-policy-rejections/_collection_/_id_.mjs.map +1 -0
  136. package/dist/astro/routes/api/admin/themes/marketplace/_id_/index.mjs +66 -62
  137. package/dist/astro/routes/api/admin/themes/marketplace/_id_/index.mjs.map +1 -1
  138. package/dist/astro/routes/api/admin/themes/marketplace/_id_/thumbnail.mjs +4 -4
  139. package/dist/astro/routes/api/admin/themes/marketplace/index.mjs +66 -62
  140. package/dist/astro/routes/api/admin/themes/marketplace/index.mjs.map +1 -1
  141. package/dist/astro/routes/api/admin/users/_id_/disable.mjs +4 -4
  142. package/dist/astro/routes/api/admin/users/_id_/enable.mjs +3 -3
  143. package/dist/astro/routes/api/admin/users/_id_/index.mjs +11 -10
  144. package/dist/astro/routes/api/admin/users/_id_/index.mjs.map +1 -1
  145. package/dist/astro/routes/api/admin/users/_id_/send-recovery.mjs +5 -5
  146. package/dist/astro/routes/api/admin/users/index.mjs +10 -9
  147. package/dist/astro/routes/api/admin/users/index.mjs.map +1 -1
  148. package/dist/astro/routes/api/auth/dev-bypass.mjs +5 -5
  149. package/dist/astro/routes/api/auth/invite/accept.mjs +3 -3
  150. package/dist/astro/routes/api/auth/invite/complete.mjs +15 -14
  151. package/dist/astro/routes/api/auth/invite/complete.mjs.map +1 -1
  152. package/dist/astro/routes/api/auth/invite/index.mjs +12 -11
  153. package/dist/astro/routes/api/auth/invite/index.mjs.map +1 -1
  154. package/dist/astro/routes/api/auth/invite/register-options.mjs +14 -13
  155. package/dist/astro/routes/api/auth/invite/register-options.mjs.map +1 -1
  156. package/dist/astro/routes/api/auth/logout.mjs +4 -4
  157. package/dist/astro/routes/api/auth/magic-link/send.mjs +14 -13
  158. package/dist/astro/routes/api/auth/magic-link/send.mjs.map +1 -1
  159. package/dist/astro/routes/api/auth/magic-link/verify.mjs +4 -4
  160. package/dist/astro/routes/api/auth/me.mjs +11 -10
  161. package/dist/astro/routes/api/auth/me.mjs.map +1 -1
  162. package/dist/astro/routes/api/auth/mode.mjs +4 -4
  163. package/dist/astro/routes/api/auth/oauth/_provider_/callback.mjs +4 -4
  164. package/dist/astro/routes/api/auth/oauth/_provider_.mjs +2 -2
  165. package/dist/astro/routes/api/auth/passkey/_id_.mjs +10 -9
  166. package/dist/astro/routes/api/auth/passkey/_id_.mjs.map +1 -1
  167. package/dist/astro/routes/api/auth/passkey/index.mjs +3 -3
  168. package/dist/astro/routes/api/auth/passkey/options.mjs +16 -15
  169. package/dist/astro/routes/api/auth/passkey/options.mjs.map +1 -1
  170. package/dist/astro/routes/api/auth/passkey/register/options.mjs +14 -13
  171. package/dist/astro/routes/api/auth/passkey/register/options.mjs.map +1 -1
  172. package/dist/astro/routes/api/auth/passkey/register/verify.mjs +15 -14
  173. package/dist/astro/routes/api/auth/passkey/register/verify.mjs.map +1 -1
  174. package/dist/astro/routes/api/auth/passkey/verify.mjs +15 -14
  175. package/dist/astro/routes/api/auth/passkey/verify.mjs.map +1 -1
  176. package/dist/astro/routes/api/auth/signup/complete.mjs +15 -14
  177. package/dist/astro/routes/api/auth/signup/complete.mjs.map +1 -1
  178. package/dist/astro/routes/api/auth/signup/request.mjs +14 -13
  179. package/dist/astro/routes/api/auth/signup/request.mjs.map +1 -1
  180. package/dist/astro/routes/api/auth/signup/verify.mjs +3 -3
  181. package/dist/astro/routes/api/comments/_collection_/_contentId_/index.d.mts.map +1 -1
  182. package/dist/astro/routes/api/comments/_collection_/_contentId_/index.mjs +15 -211
  183. package/dist/astro/routes/api/comments/_collection_/_contentId_/index.mjs.map +1 -1
  184. package/dist/astro/routes/api/comments/_collection_/_contentId_/reactions.mjs +18 -17
  185. package/dist/astro/routes/api/comments/_collection_/_contentId_/reactions.mjs.map +1 -1
  186. package/dist/astro/routes/api/content/_collection_/_id_/compare.mjs +4 -4
  187. package/dist/astro/routes/api/content/_collection_/_id_/discard-draft.mjs +15 -14
  188. package/dist/astro/routes/api/content/_collection_/_id_/discard-draft.mjs.map +1 -1
  189. package/dist/astro/routes/api/content/_collection_/_id_/duplicate.mjs +5 -5
  190. package/dist/astro/routes/api/content/_collection_/_id_/lock.mjs +15 -14
  191. package/dist/astro/routes/api/content/_collection_/_id_/lock.mjs.map +1 -1
  192. package/dist/astro/routes/api/content/_collection_/_id_/permanent.mjs +4 -4
  193. package/dist/astro/routes/api/content/_collection_/_id_/plugin-extensions/_pluginId_/_kind_/_extensionId_.d.mts +8 -0
  194. package/dist/astro/routes/api/content/_collection_/_id_/plugin-extensions/_pluginId_/_kind_/_extensionId_.d.mts.map +1 -0
  195. package/dist/astro/routes/api/content/_collection_/_id_/plugin-extensions/_pluginId_/_kind_/_extensionId_.mjs +35 -0
  196. package/dist/astro/routes/api/content/_collection_/_id_/plugin-extensions/_pluginId_/_kind_/_extensionId_.mjs.map +1 -0
  197. package/dist/astro/routes/api/content/_collection_/_id_/preview-url.mjs +16 -15
  198. package/dist/astro/routes/api/content/_collection_/_id_/preview-url.mjs.map +1 -1
  199. package/dist/astro/routes/api/content/_collection_/_id_/publish.d.mts +9 -2
  200. package/dist/astro/routes/api/content/_collection_/_id_/publish.d.mts.map +1 -1
  201. package/dist/astro/routes/api/content/_collection_/_id_/publish.mjs +25 -18
  202. package/dist/astro/routes/api/content/_collection_/_id_/publish.mjs.map +1 -1
  203. package/dist/astro/routes/api/content/_collection_/_id_/references/_relation_/children.mjs +27 -25
  204. package/dist/astro/routes/api/content/_collection_/_id_/references/_relation_/children.mjs.map +1 -1
  205. package/dist/astro/routes/api/content/_collection_/_id_/references/_relation_/parents.mjs +27 -25
  206. package/dist/astro/routes/api/content/_collection_/_id_/references/_relation_/parents.mjs.map +1 -1
  207. package/dist/astro/routes/api/content/_collection_/_id_/restore.mjs +5 -5
  208. package/dist/astro/routes/api/content/_collection_/_id_/revisions.mjs +4 -4
  209. package/dist/astro/routes/api/content/_collection_/_id_/schedule.d.mts.map +1 -1
  210. package/dist/astro/routes/api/content/_collection_/_id_/schedule.mjs +23 -15
  211. package/dist/astro/routes/api/content/_collection_/_id_/schedule.mjs.map +1 -1
  212. package/dist/astro/routes/api/content/_collection_/_id_/terms/_taxonomy_.mjs +23 -21
  213. package/dist/astro/routes/api/content/_collection_/_id_/terms/_taxonomy_.mjs.map +1 -1
  214. package/dist/astro/routes/api/content/_collection_/_id_/translations.mjs +4 -4
  215. package/dist/astro/routes/api/content/_collection_/_id_/unpublish.mjs +23 -15
  216. package/dist/astro/routes/api/content/_collection_/_id_/unpublish.mjs.map +1 -1
  217. package/dist/astro/routes/api/content/_collection_/_id_.mjs +15 -14
  218. package/dist/astro/routes/api/content/_collection_/_id_.mjs.map +1 -1
  219. package/dist/astro/routes/api/content/_collection_/authors.mjs +4 -4
  220. package/dist/astro/routes/api/content/_collection_/index.mjs +12 -11
  221. package/dist/astro/routes/api/content/_collection_/index.mjs.map +1 -1
  222. package/dist/astro/routes/api/content/_collection_/trash.mjs +11 -10
  223. package/dist/astro/routes/api/content/_collection_/trash.mjs.map +1 -1
  224. package/dist/astro/routes/api/dashboard.mjs +14 -12
  225. package/dist/astro/routes/api/dashboard.mjs.map +1 -1
  226. package/dist/astro/routes/api/dev/emails.mjs +4 -4
  227. package/dist/astro/routes/api/health.d.mts +8 -0
  228. package/dist/astro/routes/api/health.d.mts.map +1 -0
  229. package/dist/astro/routes/api/health.mjs +21 -0
  230. package/dist/astro/routes/api/health.mjs.map +1 -0
  231. package/dist/astro/routes/api/import/probe.d.mts +3 -3
  232. package/dist/astro/routes/api/import/probe.mjs +25 -23
  233. package/dist/astro/routes/api/import/probe.mjs.map +1 -1
  234. package/dist/astro/routes/api/import/wordpress/analyze.mjs +5 -5
  235. package/dist/astro/routes/api/import/wordpress/execute.d.mts +13 -11
  236. package/dist/astro/routes/api/import/wordpress/execute.d.mts.map +1 -1
  237. package/dist/astro/routes/api/import/wordpress/execute.mjs +20 -20
  238. package/dist/astro/routes/api/import/wordpress/media.d.mts +12 -10
  239. package/dist/astro/routes/api/import/wordpress/media.d.mts.map +1 -1
  240. package/dist/astro/routes/api/import/wordpress/media.mjs +15 -14
  241. package/dist/astro/routes/api/import/wordpress/media.mjs.map +1 -1
  242. package/dist/astro/routes/api/import/wordpress/prepare.mjs +14 -13
  243. package/dist/astro/routes/api/import/wordpress/prepare.mjs.map +1 -1
  244. package/dist/astro/routes/api/import/wordpress/rewrite-urls.d.mts +13 -11
  245. package/dist/astro/routes/api/import/wordpress/rewrite-urls.d.mts.map +1 -1
  246. package/dist/astro/routes/api/import/wordpress/rewrite-urls.mjs +18 -17
  247. package/dist/astro/routes/api/import/wordpress/rewrite-urls.mjs.map +1 -1
  248. package/dist/astro/routes/api/import/wordpress-plugin/analyze.d.mts +1 -1
  249. package/dist/astro/routes/api/import/wordpress-plugin/analyze.mjs +25 -23
  250. package/dist/astro/routes/api/import/wordpress-plugin/analyze.mjs.map +1 -1
  251. package/dist/astro/routes/api/import/wordpress-plugin/callback.mjs +1 -1
  252. package/dist/astro/routes/api/import/wordpress-plugin/execute.d.mts +13 -11
  253. package/dist/astro/routes/api/import/wordpress-plugin/execute.d.mts.map +1 -1
  254. package/dist/astro/routes/api/import/wordpress-plugin/execute.mjs +36 -34
  255. package/dist/astro/routes/api/import/wordpress-plugin/execute.mjs.map +1 -1
  256. package/dist/astro/routes/api/manifest.mjs +17 -9
  257. package/dist/astro/routes/api/manifest.mjs.map +1 -1
  258. package/dist/astro/routes/api/mcp.d.mts.map +1 -1
  259. package/dist/astro/routes/api/mcp.mjs +167 -101
  260. package/dist/astro/routes/api/mcp.mjs.map +1 -1
  261. package/dist/astro/routes/api/media/_id_/confirm.mjs +15 -14
  262. package/dist/astro/routes/api/media/_id_/confirm.mjs.map +1 -1
  263. package/dist/astro/routes/api/media/_id_/replace.mjs +12 -11
  264. package/dist/astro/routes/api/media/_id_/replace.mjs.map +1 -1
  265. package/dist/astro/routes/api/media/_id_/upload.mjs +8 -8
  266. package/dist/astro/routes/api/media/_id_/usage.mjs +23 -22
  267. package/dist/astro/routes/api/media/_id_/usage.mjs.map +1 -1
  268. package/dist/astro/routes/api/media/_id_.mjs +22 -21
  269. package/dist/astro/routes/api/media/_id_.mjs.map +1 -1
  270. package/dist/astro/routes/api/media/asset/_id_/_filename_.d.mts +8 -0
  271. package/dist/astro/routes/api/media/asset/_id_/_filename_.d.mts.map +1 -0
  272. package/dist/astro/routes/api/media/asset/_id_/_filename_.mjs +52 -0
  273. package/dist/astro/routes/api/media/asset/_id_/_filename_.mjs.map +1 -0
  274. package/dist/astro/routes/api/media/file/_...key_.mjs +3 -3
  275. package/dist/astro/routes/api/media/folders/_id_.mjs +12 -11
  276. package/dist/astro/routes/api/media/folders/_id_.mjs.map +1 -1
  277. package/dist/astro/routes/api/media/folders/index.mjs +12 -11
  278. package/dist/astro/routes/api/media/folders/index.mjs.map +1 -1
  279. package/dist/astro/routes/api/media/providers/_providerId_/_itemId_.mjs +4 -4
  280. package/dist/astro/routes/api/media/providers/_providerId_/index.mjs +4 -4
  281. package/dist/astro/routes/api/media/providers/index.mjs +4 -4
  282. package/dist/astro/routes/api/media/upload-url.mjs +14 -13
  283. package/dist/astro/routes/api/media/upload-url.mjs.map +1 -1
  284. package/dist/astro/routes/api/media.mjs +26 -25
  285. package/dist/astro/routes/api/media.mjs.map +1 -1
  286. package/dist/astro/routes/api/menus/_name_/items/_id_.mjs +15 -14
  287. package/dist/astro/routes/api/menus/_name_/items/_id_.mjs.map +1 -1
  288. package/dist/astro/routes/api/menus/_name_/items.mjs +15 -14
  289. package/dist/astro/routes/api/menus/_name_/items.mjs.map +1 -1
  290. package/dist/astro/routes/api/menus/_name_/reorder.mjs +15 -14
  291. package/dist/astro/routes/api/menus/_name_/reorder.mjs.map +1 -1
  292. package/dist/astro/routes/api/menus/_name_/translations.mjs +15 -14
  293. package/dist/astro/routes/api/menus/_name_/translations.mjs.map +1 -1
  294. package/dist/astro/routes/api/menus/_name_.mjs +15 -14
  295. package/dist/astro/routes/api/menus/_name_.mjs.map +1 -1
  296. package/dist/astro/routes/api/menus/index.mjs +15 -14
  297. package/dist/astro/routes/api/menus/index.mjs.map +1 -1
  298. package/dist/astro/routes/api/oauth/authorize.mjs +6 -6
  299. package/dist/astro/routes/api/oauth/device/authorize.mjs +7 -7
  300. package/dist/astro/routes/api/oauth/device/code.mjs +10 -10
  301. package/dist/astro/routes/api/oauth/device/token.mjs +9 -9
  302. package/dist/astro/routes/api/oauth/register.mjs +4 -4
  303. package/dist/astro/routes/api/oauth/token/refresh.mjs +7 -7
  304. package/dist/astro/routes/api/oauth/token/revoke.mjs +7 -7
  305. package/dist/astro/routes/api/oauth/token.mjs +7 -7
  306. package/dist/astro/routes/api/openapi.json.mjs +28 -23
  307. package/dist/astro/routes/api/openapi.json.mjs.map +1 -1
  308. package/dist/astro/routes/api/plugins/_pluginId_/_...path_.d.mts +2 -1
  309. package/dist/astro/routes/api/plugins/_pluginId_/_...path_.d.mts.map +1 -1
  310. package/dist/astro/routes/api/plugins/_pluginId_/_...path_.mjs +22 -40
  311. package/dist/astro/routes/api/plugins/_pluginId_/_...path_.mjs.map +1 -1
  312. package/dist/astro/routes/api/redirects/404s/index.mjs +18 -15
  313. package/dist/astro/routes/api/redirects/404s/index.mjs.map +1 -1
  314. package/dist/astro/routes/api/redirects/404s/summary.mjs +18 -15
  315. package/dist/astro/routes/api/redirects/404s/summary.mjs.map +1 -1
  316. package/dist/astro/routes/api/redirects/_id_.d.mts.map +1 -1
  317. package/dist/astro/routes/api/redirects/_id_.mjs +20 -23
  318. package/dist/astro/routes/api/redirects/_id_.mjs.map +1 -1
  319. package/dist/astro/routes/api/redirects/index.d.mts.map +1 -1
  320. package/dist/astro/routes/api/redirects/index.mjs +19 -20
  321. package/dist/astro/routes/api/redirects/index.mjs.map +1 -1
  322. package/dist/astro/routes/api/relations/_id_/index.mjs +27 -25
  323. package/dist/astro/routes/api/relations/_id_/index.mjs.map +1 -1
  324. package/dist/astro/routes/api/relations/_id_/translations.mjs +21 -20
  325. package/dist/astro/routes/api/relations/_id_/translations.mjs.map +1 -1
  326. package/dist/astro/routes/api/relations/index.mjs +27 -25
  327. package/dist/astro/routes/api/relations/index.mjs.map +1 -1
  328. package/dist/astro/routes/api/revisions/_revisionId_/index.mjs +4 -4
  329. package/dist/astro/routes/api/revisions/_revisionId_/restore.mjs +5 -5
  330. package/dist/astro/routes/api/schema/collections/_slug_/fields/_fieldSlug_.mjs +66 -62
  331. package/dist/astro/routes/api/schema/collections/_slug_/fields/_fieldSlug_.mjs.map +1 -1
  332. package/dist/astro/routes/api/schema/collections/_slug_/fields/index.mjs +66 -62
  333. package/dist/astro/routes/api/schema/collections/_slug_/fields/index.mjs.map +1 -1
  334. package/dist/astro/routes/api/schema/collections/_slug_/fields/reorder.mjs +66 -62
  335. package/dist/astro/routes/api/schema/collections/_slug_/fields/reorder.mjs.map +1 -1
  336. package/dist/astro/routes/api/schema/collections/_slug_/index.mjs +66 -62
  337. package/dist/astro/routes/api/schema/collections/_slug_/index.mjs.map +1 -1
  338. package/dist/astro/routes/api/schema/collections/index.mjs +66 -62
  339. package/dist/astro/routes/api/schema/collections/index.mjs.map +1 -1
  340. package/dist/astro/routes/api/schema/collections/reorder.mjs +66 -62
  341. package/dist/astro/routes/api/schema/collections/reorder.mjs.map +1 -1
  342. package/dist/astro/routes/api/schema/index.mjs +16 -16
  343. package/dist/astro/routes/api/schema/orphans/_slug_.mjs +66 -62
  344. package/dist/astro/routes/api/schema/orphans/_slug_.mjs.map +1 -1
  345. package/dist/astro/routes/api/schema/orphans/index.mjs +66 -62
  346. package/dist/astro/routes/api/schema/orphans/index.mjs.map +1 -1
  347. package/dist/astro/routes/api/search/enable.mjs +16 -15
  348. package/dist/astro/routes/api/search/enable.mjs.map +1 -1
  349. package/dist/astro/routes/api/search/index.mjs +17 -15
  350. package/dist/astro/routes/api/search/index.mjs.map +1 -1
  351. package/dist/astro/routes/api/search/rebuild.mjs +16 -15
  352. package/dist/astro/routes/api/search/rebuild.mjs.map +1 -1
  353. package/dist/astro/routes/api/search/stats.mjs +10 -10
  354. package/dist/astro/routes/api/search/suggest.mjs +15 -14
  355. package/dist/astro/routes/api/search/suggest.mjs.map +1 -1
  356. package/dist/astro/routes/api/sections/_slug_.mjs +15 -14
  357. package/dist/astro/routes/api/sections/_slug_.mjs.map +1 -1
  358. package/dist/astro/routes/api/sections/index.mjs +15 -14
  359. package/dist/astro/routes/api/sections/index.mjs.map +1 -1
  360. package/dist/astro/routes/api/settings/backups/archives/_name_.mjs +9 -9
  361. package/dist/astro/routes/api/settings/backups/archives/index.mjs +8 -8
  362. package/dist/astro/routes/api/settings/backups/export.mjs +9 -9
  363. package/dist/astro/routes/api/settings/backups/index.mjs +10 -10
  364. package/dist/astro/routes/api/settings/email.mjs +6 -6
  365. package/dist/astro/routes/api/settings.mjs +22 -20
  366. package/dist/astro/routes/api/settings.mjs.map +1 -1
  367. package/dist/astro/routes/api/setup/admin-verify.mjs +16 -15
  368. package/dist/astro/routes/api/setup/admin-verify.mjs.map +1 -1
  369. package/dist/astro/routes/api/setup/admin.mjs +15 -14
  370. package/dist/astro/routes/api/setup/admin.mjs.map +1 -1
  371. package/dist/astro/routes/api/setup/dev-bypass.mjs +42 -40
  372. package/dist/astro/routes/api/setup/dev-bypass.mjs.map +1 -1
  373. package/dist/astro/routes/api/setup/dev-reset.mjs +4 -4
  374. package/dist/astro/routes/api/setup/index.mjs +43 -40
  375. package/dist/astro/routes/api/setup/index.mjs.map +1 -1
  376. package/dist/astro/routes/api/setup/status.mjs +5 -5
  377. package/dist/astro/routes/api/snapshot.mjs +11 -11
  378. package/dist/astro/routes/api/taxonomies/_name_/reorder.mjs +23 -22
  379. package/dist/astro/routes/api/taxonomies/_name_/reorder.mjs.map +1 -1
  380. package/dist/astro/routes/api/taxonomies/_name_/terms/_slug_/translations.mjs +23 -22
  381. package/dist/astro/routes/api/taxonomies/_name_/terms/_slug_/translations.mjs.map +1 -1
  382. package/dist/astro/routes/api/taxonomies/_name_/terms/_slug_.mjs +23 -22
  383. package/dist/astro/routes/api/taxonomies/_name_/terms/_slug_.mjs.map +1 -1
  384. package/dist/astro/routes/api/taxonomies/_name_/terms/index.mjs +23 -22
  385. package/dist/astro/routes/api/taxonomies/_name_/terms/index.mjs.map +1 -1
  386. package/dist/astro/routes/api/taxonomies/_name_/translations.mjs +22 -21
  387. package/dist/astro/routes/api/taxonomies/_name_/translations.mjs.map +1 -1
  388. package/dist/astro/routes/api/taxonomies/_name_.mjs +23 -22
  389. package/dist/astro/routes/api/taxonomies/_name_.mjs.map +1 -1
  390. package/dist/astro/routes/api/taxonomies/index.mjs +23 -22
  391. package/dist/astro/routes/api/taxonomies/index.mjs.map +1 -1
  392. package/dist/astro/routes/api/themes/preview.mjs +8 -8
  393. package/dist/astro/routes/api/typegen.mjs +6 -6
  394. package/dist/astro/routes/api/visual-editing/action-token.d.mts +8 -0
  395. package/dist/astro/routes/api/visual-editing/action-token.d.mts.map +1 -0
  396. package/dist/astro/routes/api/visual-editing/action-token.mjs +25 -0
  397. package/dist/astro/routes/api/visual-editing/action-token.mjs.map +1 -0
  398. package/dist/astro/routes/api/visual-editing/content/_collection_/_id_/publish.d.mts +8 -0
  399. package/dist/astro/routes/api/visual-editing/content/_collection_/_id_/publish.d.mts.map +1 -0
  400. package/dist/astro/routes/api/visual-editing/content/_collection_/_id_/publish.mjs +37 -0
  401. package/dist/astro/routes/api/visual-editing/content/_collection_/_id_/publish.mjs.map +1 -0
  402. package/dist/astro/routes/api/visual-editing/toolbar-labels.d.mts +8 -0
  403. package/dist/astro/routes/api/visual-editing/toolbar-labels.d.mts.map +1 -0
  404. package/dist/astro/routes/api/visual-editing/toolbar-labels.mjs +20 -0
  405. package/dist/astro/routes/api/visual-editing/toolbar-labels.mjs.map +1 -0
  406. package/dist/astro/routes/api/well-known/auth.mjs +2 -2
  407. package/dist/astro/routes/api/well-known/oauth-authorization-server.mjs +2 -2
  408. package/dist/astro/routes/api/well-known/oauth-protected-resource.mjs +2 -2
  409. package/dist/astro/routes/api/widget-areas/_name_/reorder.mjs +12 -11
  410. package/dist/astro/routes/api/widget-areas/_name_/reorder.mjs.map +1 -1
  411. package/dist/astro/routes/api/widget-areas/_name_/widgets/_id_.mjs +16 -15
  412. package/dist/astro/routes/api/widget-areas/_name_/widgets/_id_.mjs.map +1 -1
  413. package/dist/astro/routes/api/widget-areas/_name_/widgets.mjs +16 -15
  414. package/dist/astro/routes/api/widget-areas/_name_/widgets.mjs.map +1 -1
  415. package/dist/astro/routes/api/widget-areas/_name_.mjs +10 -10
  416. package/dist/astro/routes/api/widget-areas/index.mjs +16 -15
  417. package/dist/astro/routes/api/widget-areas/index.mjs.map +1 -1
  418. package/dist/astro/routes/api/widget-components.mjs +4 -4
  419. package/dist/astro/routes/robots.txt.mjs +13 -12
  420. package/dist/astro/routes/robots.txt.mjs.map +1 -1
  421. package/dist/astro/routes/sitemap-_collection_.xml.d.mts.map +1 -1
  422. package/dist/astro/routes/sitemap-_collection_.xml.mjs +23 -19
  423. package/dist/astro/routes/sitemap-_collection_.xml.mjs.map +1 -1
  424. package/dist/astro/routes/sitemap.xml.mjs +14 -13
  425. package/dist/astro/routes/sitemap.xml.mjs.map +1 -1
  426. package/dist/astro/types.d.mts +61 -23
  427. package/dist/astro/types.d.mts.map +1 -1
  428. package/dist/auth/providers/github.d.mts +1 -1
  429. package/dist/auth/providers/google.d.mts +1 -1
  430. package/dist/authoritative-records-DbqshfKD.mjs +5172 -0
  431. package/dist/authoritative-records-DbqshfKD.mjs.map +1 -0
  432. package/dist/authorize-BXpfMpp0.mjs +40 -0
  433. package/dist/authorize-BXpfMpp0.mjs.map +1 -0
  434. package/dist/backup-B4tByjBb.mjs +246 -0
  435. package/dist/backup-B4tByjBb.mjs.map +1 -0
  436. package/dist/base64-DvnNgP7e.mjs +63 -0
  437. package/dist/base64-DvnNgP7e.mjs.map +1 -0
  438. package/dist/byline-C8ndlnP0.mjs +906 -0
  439. package/dist/byline-C8ndlnP0.mjs.map +1 -0
  440. package/dist/byline-fields-CsrdvaLV.mjs +123 -0
  441. package/dist/byline-fields-CsrdvaLV.mjs.map +1 -0
  442. package/dist/byline-registry-D6lWzXk6.mjs +406 -0
  443. package/dist/byline-registry-D6lWzXk6.mjs.map +1 -0
  444. package/dist/bylines-CHP44GkL.mjs +232 -0
  445. package/dist/bylines-CHP44GkL.mjs.map +1 -0
  446. package/dist/bylines-DxjM4Usz.mjs +214 -0
  447. package/dist/bylines-DxjM4Usz.mjs.map +1 -0
  448. package/dist/cache-BByLKGPu.mjs +108 -0
  449. package/dist/cache-BByLKGPu.mjs.map +1 -0
  450. package/dist/capture-triggers-gxQxnxrJ.mjs +362 -0
  451. package/dist/capture-triggers-gxQxnxrJ.mjs.map +1 -0
  452. package/dist/challenge-store-CkRdSdd8.mjs +51 -0
  453. package/dist/challenge-store-CkRdSdd8.mjs.map +1 -0
  454. package/dist/checksum-Bsi2D9M1.mjs +162 -0
  455. package/dist/checksum-Bsi2D9M1.mjs.map +1 -0
  456. package/dist/chrome-tags-D7LGB91U.mjs +24 -0
  457. package/dist/chrome-tags-D7LGB91U.mjs.map +1 -0
  458. package/dist/chunks-DUK-cWXi.mjs +25 -0
  459. package/dist/chunks-DUK-cWXi.mjs.map +1 -0
  460. package/dist/cli/index.mjs +889 -102
  461. package/dist/cli/index.mjs.map +1 -1
  462. package/dist/client/cf-access.d.mts +1 -1
  463. package/dist/client/index.d.mts +2 -2
  464. package/dist/client/index.mjs +2 -2
  465. package/dist/collection-deletion-C-yQB9fq.mjs +436 -0
  466. package/dist/collection-deletion-C-yQB9fq.mjs.map +1 -0
  467. package/dist/collection-slugs-cache-D9auiKmI.mjs +85 -0
  468. package/dist/collection-slugs-cache-D9auiKmI.mjs.map +1 -0
  469. package/dist/comment-DcT8qdPK.mjs +313 -0
  470. package/dist/comment-DcT8qdPK.mjs.map +1 -0
  471. package/dist/comment-reaction-B6KHCLYK.mjs +85 -0
  472. package/dist/comment-reaction-B6KHCLYK.mjs.map +1 -0
  473. package/dist/comments-B67VRNGw.mjs +204 -0
  474. package/dist/comments-B67VRNGw.mjs.map +1 -0
  475. package/dist/comments-BVzzt6x5.mjs +99 -0
  476. package/dist/comments-BVzzt6x5.mjs.map +1 -0
  477. package/dist/components-DIl9Qzh6.mjs +108 -0
  478. package/dist/components-DIl9Qzh6.mjs.map +1 -0
  479. package/dist/config-B2acLeC5.mjs +242 -0
  480. package/dist/config-B2acLeC5.mjs.map +1 -0
  481. package/dist/config-CGVeT8Hc.mjs +73 -0
  482. package/dist/config-CGVeT8Hc.mjs.map +1 -0
  483. package/dist/config-Cw1Xz_Br.d.mts +6387 -0
  484. package/dist/config-Cw1Xz_Br.d.mts.map +1 -0
  485. package/dist/config-D3HhLON3.d.mts +39 -0
  486. package/dist/config-D3HhLON3.d.mts.map +1 -0
  487. package/dist/content-C0Hl3ktM.mjs +2216 -0
  488. package/dist/content-C0Hl3ktM.mjs.map +1 -0
  489. package/dist/content-list-query-CbPdzsna.d.mts +26 -0
  490. package/dist/content-list-query-CbPdzsna.d.mts.map +1 -0
  491. package/dist/content-policy-CM4skrNi.mjs +46 -0
  492. package/dist/content-policy-CM4skrNi.mjs.map +1 -0
  493. package/dist/content-refresh-iRBhQHr5.mjs +3599 -0
  494. package/dist/content-refresh-iRBhQHr5.mjs.map +1 -0
  495. package/dist/content-repair-8uHRIJkd.mjs +440 -0
  496. package/dist/content-repair-8uHRIJkd.mjs.map +1 -0
  497. package/dist/context-DJP3aNeR.mjs +1835 -0
  498. package/dist/context-DJP3aNeR.mjs.map +1 -0
  499. package/dist/cron-BcR3RN4K.mjs +282 -0
  500. package/dist/cron-BcR3RN4K.mjs.map +1 -0
  501. package/dist/dashboard-B0s6QKgi.mjs +151 -0
  502. package/dist/dashboard-B0s6QKgi.mjs.map +1 -0
  503. package/dist/database/migration-lock.d.mts +37 -0
  504. package/dist/database/migration-lock.d.mts.map +1 -0
  505. package/dist/database/migration-lock.mjs +76 -0
  506. package/dist/database/migration-lock.mjs.map +1 -0
  507. package/dist/database/pg-migration-lock.d.mts +1 -1
  508. package/dist/database/pg-migration-lock.mjs +1 -1
  509. package/dist/database/pg-migration-lock.mjs.map +1 -1
  510. package/dist/datetime-normalization-PeiEdcRY.mjs +187 -0
  511. package/dist/datetime-normalization-PeiEdcRY.mjs.map +1 -0
  512. package/dist/db/index.d.mts +3 -3
  513. package/dist/db/index.mjs +4 -3
  514. package/dist/db/index.mjs.map +1 -1
  515. package/dist/db/libsql-migrations.d.mts +1 -1
  516. package/dist/db/libsql-migrations.mjs +7 -6
  517. package/dist/db/libsql-migrations.mjs.map +1 -1
  518. package/dist/db/libsql.d.mts +1 -1
  519. package/dist/db/postgres-migrations.d.mts +1 -1
  520. package/dist/db/postgres-migrations.mjs +7 -6
  521. package/dist/db/postgres-migrations.mjs.map +1 -1
  522. package/dist/db/postgres.d.mts +1 -1
  523. package/dist/db/sqlite-migrations.d.mts +1 -1
  524. package/dist/db/sqlite-migrations.mjs +7 -6
  525. package/dist/db/sqlite-migrations.mjs.map +1 -1
  526. package/dist/db/sqlite.d.mts +1 -1
  527. package/dist/db/sqlite.mjs +1 -1
  528. package/dist/db-errors-CBD5yMro.mjs +55 -0
  529. package/dist/db-errors-CBD5yMro.mjs.map +1 -0
  530. package/dist/default-BtlxWgh9.mjs +81 -0
  531. package/dist/default-BtlxWgh9.mjs.map +1 -0
  532. package/dist/deferred-tasks-Ba9fphlE.d.mts +9 -0
  533. package/dist/deferred-tasks-Ba9fphlE.d.mts.map +1 -0
  534. package/dist/dev-typegen-CZaPLl3V.mjs +29 -0
  535. package/dist/dev-typegen-CZaPLl3V.mjs.map +1 -0
  536. package/dist/device-flow-3E5l0fpH.mjs +466 -0
  537. package/dist/device-flow-3E5l0fpH.mjs.map +1 -0
  538. package/dist/dialect-helpers-CtYdsX4W.mjs +307 -0
  539. package/dist/dialect-helpers-CtYdsX4W.mjs.map +1 -0
  540. package/dist/direct-executor-CDr1quOq.mjs +104 -0
  541. package/dist/direct-executor-CDr1quOq.mjs.map +1 -0
  542. package/dist/dist-2hDLsLeq.mjs +810 -0
  543. package/dist/dist-2hDLsLeq.mjs.map +1 -0
  544. package/dist/email-console-gc-E3Eqj.mjs +50 -0
  545. package/dist/email-console-gc-E3Eqj.mjs.map +1 -0
  546. package/dist/emdash-runtime-CxxL05Z0.mjs +4041 -0
  547. package/dist/emdash-runtime-CxxL05Z0.mjs.map +1 -0
  548. package/dist/enrich-C2Mk0lwE.mjs +194 -0
  549. package/dist/enrich-C2Mk0lwE.mjs.map +1 -0
  550. package/dist/entry-lock-CwWdnFyR.mjs +1520 -0
  551. package/dist/entry-lock-CwWdnFyR.mjs.map +1 -0
  552. package/dist/entry-lock-D9rnj2Lu.mjs +163 -0
  553. package/dist/entry-lock-D9rnj2Lu.mjs.map +1 -0
  554. package/dist/entry-lock-DqkvBC6L.d.mts +3503 -0
  555. package/dist/entry-lock-DqkvBC6L.d.mts.map +1 -0
  556. package/dist/entry-locks-CO_KaoU5.mjs +167 -0
  557. package/dist/entry-locks-CO_KaoU5.mjs.map +1 -0
  558. package/dist/error-CCTCskie.mjs +90 -0
  559. package/dist/error-CCTCskie.mjs.map +1 -0
  560. package/dist/errors-W3PA8HqB.mjs +447 -0
  561. package/dist/errors-W3PA8HqB.mjs.map +1 -0
  562. package/dist/escape-DN4Qmjsl.mjs +9 -0
  563. package/dist/escape-DN4Qmjsl.mjs.map +1 -0
  564. package/dist/field-defs-cache-Db0pJgqn.mjs +77 -0
  565. package/dist/field-defs-cache-Db0pJgqn.mjs.map +1 -0
  566. package/dist/focal-point-Gr34o-4o.mjs +23 -0
  567. package/dist/focal-point-Gr34o-4o.mjs.map +1 -0
  568. package/dist/fts-manager-CjX0e5BR.mjs +413 -0
  569. package/dist/fts-manager-CjX0e5BR.mjs.map +1 -0
  570. package/dist/hash-CLVFzWvx.mjs +37 -0
  571. package/dist/hash-CLVFzWvx.mjs.map +1 -0
  572. package/dist/hook-result-KY1jq21o.d.mts +31 -0
  573. package/dist/hook-result-KY1jq21o.d.mts.map +1 -0
  574. package/dist/hreflang-BgS2FqhH.d.mts +50 -0
  575. package/dist/hreflang-BgS2FqhH.d.mts.map +1 -0
  576. package/dist/hreflang-DOQeTXpg.mjs +105 -0
  577. package/dist/hreflang-DOQeTXpg.mjs.map +1 -0
  578. package/dist/http-route-dispatch-MCVKiQCl.mjs +339 -0
  579. package/dist/http-route-dispatch-MCVKiQCl.mjs.map +1 -0
  580. package/dist/identity-vFbpuwfY.mjs +35 -0
  581. package/dist/identity-vFbpuwfY.mjs.map +1 -0
  582. package/dist/import-got6I69S.mjs +2020 -0
  583. package/dist/import-got6I69S.mjs.map +1 -0
  584. package/dist/index-CDwKDkTq.d.mts +623 -0
  585. package/dist/index-CDwKDkTq.d.mts.map +1 -0
  586. package/dist/index.d.mts +27 -22
  587. package/dist/index.mjs +101 -89
  588. package/dist/init-lock-4eRRB4Le.mjs +56 -0
  589. package/dist/init-lock-4eRRB4Le.mjs.map +1 -0
  590. package/dist/install-finalization-5Os-QZ-2.mjs +58 -0
  591. package/dist/install-finalization-5Os-QZ-2.mjs.map +1 -0
  592. package/dist/lifecycle-7e-Lt_kX.mjs +25 -0
  593. package/dist/lifecycle-7e-Lt_kX.mjs.map +1 -0
  594. package/dist/load-C56XiwbV.mjs +28 -0
  595. package/dist/load-C56XiwbV.mjs.map +1 -0
  596. package/dist/loader-xhNQiT9T.mjs +1004 -0
  597. package/dist/loader-xhNQiT9T.mjs.map +1 -0
  598. package/dist/manifest-builder-Bz3nxVET.mjs +189 -0
  599. package/dist/manifest-builder-Bz3nxVET.mjs.map +1 -0
  600. package/dist/manifest-schema-Bkh8SeHd.mjs +491 -0
  601. package/dist/manifest-schema-Bkh8SeHd.mjs.map +1 -0
  602. package/dist/media/image-endpoint.mjs +1 -1
  603. package/dist/media/index.d.mts +1 -1
  604. package/dist/media/index.mjs +4 -4
  605. package/dist/media/local-runtime.d.mts +14 -12
  606. package/dist/media/local-runtime.d.mts.map +1 -1
  607. package/dist/media/local-runtime.mjs +12 -11
  608. package/dist/media/local-runtime.mjs.map +1 -1
  609. package/dist/media-TBlKCwo7.mjs +334 -0
  610. package/dist/media-TBlKCwo7.mjs.map +1 -0
  611. package/dist/media-allowlist-s60eAIf6.mjs +44 -0
  612. package/dist/media-allowlist-s60eAIf6.mjs.map +1 -0
  613. package/dist/media-folders-ClIRLUQv.mjs +210 -0
  614. package/dist/media-folders-ClIRLUQv.mjs.map +1 -0
  615. package/dist/media-url-DY_ijO3B.mjs +43 -0
  616. package/dist/media-url-DY_ijO3B.mjs.map +1 -0
  617. package/dist/media-usage-Bd9rFPKN.mjs +1833 -0
  618. package/dist/media-usage-Bd9rFPKN.mjs.map +1 -0
  619. package/dist/media-usage-activation-CAhmb14O.mjs +78 -0
  620. package/dist/media-usage-activation-CAhmb14O.mjs.map +1 -0
  621. package/dist/media-usage-work-BPlRMOJv.mjs +152 -0
  622. package/dist/media-usage-work-BPlRMOJv.mjs.map +1 -0
  623. package/dist/media-usage-work-Cu5DqewW.mjs +586 -0
  624. package/dist/media-usage-work-Cu5DqewW.mjs.map +1 -0
  625. package/dist/media-usage-write-fence-DW5oHT7q.mjs +42 -0
  626. package/dist/media-usage-write-fence-DW5oHT7q.mjs.map +1 -0
  627. package/dist/menus-BUQdvXep.mjs +3732 -0
  628. package/dist/menus-BUQdvXep.mjs.map +1 -0
  629. package/dist/menus-DgSUodmF.mjs +753 -0
  630. package/dist/menus-DgSUodmF.mjs.map +1 -0
  631. package/dist/migrations/index.d.mts +2 -2
  632. package/dist/migrations/index.d.mts.map +1 -1
  633. package/dist/migrations/index.mjs +6 -5
  634. package/dist/mime-CCYRC4r1.mjs +36 -0
  635. package/dist/mime-CCYRC4r1.mjs.map +1 -0
  636. package/dist/mode-CkmOhFqj.mjs +23 -0
  637. package/dist/mode-CkmOhFqj.mjs.map +1 -0
  638. package/dist/node-sqlite-compat-vpVaILnb.mjs +46 -0
  639. package/dist/node-sqlite-compat-vpVaILnb.mjs.map +1 -0
  640. package/dist/normalize-dChXQjwS.mjs +191 -0
  641. package/dist/normalize-dChXQjwS.mjs.map +1 -0
  642. package/dist/oauth-authorization-DZ-R-hmx.mjs +274 -0
  643. package/dist/oauth-authorization-DZ-R-hmx.mjs.map +1 -0
  644. package/dist/oauth-clients-BMPA8vjl.mjs +266 -0
  645. package/dist/oauth-clients-BMPA8vjl.mjs.map +1 -0
  646. package/dist/oauth-state-store-0gIdb48-.mjs +50 -0
  647. package/dist/oauth-state-store-0gIdb48-.mjs.map +1 -0
  648. package/dist/oauth-user-lookup-ChVW4UWu.mjs +26 -0
  649. package/dist/oauth-user-lookup-ChVW4UWu.mjs.map +1 -0
  650. package/dist/object-cache/memory.d.mts +1 -1
  651. package/dist/object-cache-DlSVbn5Y.mjs +534 -0
  652. package/dist/object-cache-DlSVbn5Y.mjs.map +1 -0
  653. package/dist/options-D5WcorD5.mjs +200 -0
  654. package/dist/options-D5WcorD5.mjs.map +1 -0
  655. package/dist/options-DAknChnw.d.mts +77 -0
  656. package/dist/options-DAknChnw.d.mts.map +1 -0
  657. package/dist/page/index.d.mts +2 -2
  658. package/dist/page/index.mjs +12 -11
  659. package/dist/page/index.mjs.map +1 -1
  660. package/dist/parse-Cr379Av9.mjs +81 -0
  661. package/dist/parse-Cr379Av9.mjs.map +1 -0
  662. package/dist/parse-tj9XLNO_.d.mts +165 -0
  663. package/dist/parse-tj9XLNO_.d.mts.map +1 -0
  664. package/dist/passkey-config-BD-wMaCf.mjs +46 -0
  665. package/dist/passkey-config-BD-wMaCf.mjs.map +1 -0
  666. package/dist/patterns-Do3iqi7N.mjs +145 -0
  667. package/dist/patterns-Do3iqi7N.mjs.map +1 -0
  668. package/dist/placeholder-CubPFn_L.d.mts +306 -0
  669. package/dist/placeholder-CubPFn_L.d.mts.map +1 -0
  670. package/dist/plugin-test-runtime.d.mts +97 -0
  671. package/dist/plugin-test-runtime.d.mts.map +1 -0
  672. package/dist/plugin-test-runtime.mjs +106 -0
  673. package/dist/plugin-types.d.mts +53 -15
  674. package/dist/plugin-types.d.mts.map +1 -1
  675. package/dist/plugin-types.mjs +18 -1
  676. package/dist/plugin-types.mjs.map +1 -0
  677. package/dist/plugin-utils.d.mts +12 -10
  678. package/dist/plugin-utils.d.mts.map +1 -1
  679. package/dist/plugins/adapt-sandbox-entry.d.mts +12 -10
  680. package/dist/plugins/adapt-sandbox-entry.d.mts.map +1 -1
  681. package/dist/plugins/adapt-sandbox-entry.mjs +18 -13
  682. package/dist/plugins/adapt-sandbox-entry.mjs.map +1 -1
  683. package/dist/plugins/host.d.mts +7 -0
  684. package/dist/plugins/host.mjs +45 -0
  685. package/dist/plugins/http-wire.d.mts +25 -0
  686. package/dist/plugins/http-wire.d.mts.map +1 -0
  687. package/dist/plugins/http-wire.mjs +148 -0
  688. package/dist/plugins/http-wire.mjs.map +1 -0
  689. package/dist/plugins/secret-redactor.d.mts +9 -0
  690. package/dist/plugins/secret-redactor.d.mts.map +1 -0
  691. package/dist/plugins/secret-redactor.mjs +51 -0
  692. package/dist/plugins/secret-redactor.mjs.map +1 -0
  693. package/dist/plugins-DHurtdXQ.mjs +277 -0
  694. package/dist/plugins-DHurtdXQ.mjs.map +1 -0
  695. package/dist/policy-pL9QLKZm.mjs +45 -0
  696. package/dist/policy-pL9QLKZm.mjs.map +1 -0
  697. package/dist/portable-text-oAwodbPS.mjs +286 -0
  698. package/dist/portable-text-oAwodbPS.mjs.map +1 -0
  699. package/dist/preview-Cup2bj8c.mjs +107 -0
  700. package/dist/preview-Cup2bj8c.mjs.map +1 -0
  701. package/dist/protocol-C1CNiKX4.d.mts +61 -0
  702. package/dist/protocol-C1CNiKX4.d.mts.map +1 -0
  703. package/dist/public-submission-Cs-pFMQK.mjs +245 -0
  704. package/dist/public-submission-Cs-pFMQK.mjs.map +1 -0
  705. package/dist/public-url-BWVHsfQv.mjs +101 -0
  706. package/dist/public-url-BWVHsfQv.mjs.map +1 -0
  707. package/dist/query-CxnFU6sz.mjs +890 -0
  708. package/dist/query-CxnFU6sz.mjs.map +1 -0
  709. package/dist/query-sgHYEgBW.mjs +41 -0
  710. package/dist/query-sgHYEgBW.mjs.map +1 -0
  711. package/dist/rate-limit-CqJn-w4h.mjs +120 -0
  712. package/dist/rate-limit-CqJn-w4h.mjs.map +1 -0
  713. package/dist/redirect-BrChFPIu.mjs +17 -0
  714. package/dist/redirect-BrChFPIu.mjs.map +1 -0
  715. package/dist/redirect-D2Yo-b6S.mjs +415 -0
  716. package/dist/redirect-D2Yo-b6S.mjs.map +1 -0
  717. package/dist/redirects-BCiTaIQ-.mjs +146 -0
  718. package/dist/redirects-BCiTaIQ-.mjs.map +1 -0
  719. package/dist/redirects-CAoL3r26.mjs +644 -0
  720. package/dist/redirects-CAoL3r26.mjs.map +1 -0
  721. package/dist/registry/testing.d.mts +14 -0
  722. package/dist/registry/testing.d.mts.map +1 -0
  723. package/dist/registry/testing.mjs +255 -0
  724. package/dist/registry/testing.mjs.map +1 -0
  725. package/dist/registry-xKzE-_m5.mjs +1222 -0
  726. package/dist/registry-xKzE-_m5.mjs.map +1 -0
  727. package/dist/relation-ClsWcYg2.mjs +334 -0
  728. package/dist/relation-ClsWcYg2.mjs.map +1 -0
  729. package/dist/relations-B4w-G5U9.mjs +309 -0
  730. package/dist/relations-B4w-G5U9.mjs.map +1 -0
  731. package/dist/relations-C3Td_mct.mjs +403 -0
  732. package/dist/relations-C3Td_mct.mjs.map +1 -0
  733. package/dist/request-cache-DaMhSQdx.mjs +104 -0
  734. package/dist/request-cache-DaMhSQdx.mjs.map +1 -0
  735. package/dist/request-context.d.mts +1 -1
  736. package/dist/request-meta-C8yl_sIs.mjs +141 -0
  737. package/dist/request-meta-C8yl_sIs.mjs.map +1 -0
  738. package/dist/resolve-BJIS8wKr.mjs +199 -0
  739. package/dist/resolve-BJIS8wKr.mjs.map +1 -0
  740. package/dist/route-wire-D66L2oaZ.mjs +197 -0
  741. package/dist/route-wire-D66L2oaZ.mjs.map +1 -0
  742. package/dist/routes-CWzxcZpn.mjs +321 -0
  743. package/dist/routes-CWzxcZpn.mjs.map +1 -0
  744. package/dist/runner-3gfxRsJG.d.mts +68 -0
  745. package/dist/runner-3gfxRsJG.d.mts.map +1 -0
  746. package/dist/runner-CIltKk4i.mjs +5502 -0
  747. package/dist/runner-CIltKk4i.mjs.map +1 -0
  748. package/dist/runtime.d.mts +13 -11
  749. package/dist/runtime.d.mts.map +1 -1
  750. package/dist/runtime.mjs +6 -6
  751. package/dist/schema-DQIE9Htn.mjs +420 -0
  752. package/dist/schema-DQIE9Htn.mjs.map +1 -0
  753. package/dist/schema-ILPFMPW3.mjs +9 -0
  754. package/dist/schema-ILPFMPW3.mjs.map +1 -0
  755. package/dist/scopes-Bn8_rCSt.mjs +27 -0
  756. package/dist/scopes-Bn8_rCSt.mjs.map +1 -0
  757. package/dist/search-D6muneha.mjs +448 -0
  758. package/dist/search-D6muneha.mjs.map +1 -0
  759. package/dist/secrets-DNgVgz_e.mjs +341 -0
  760. package/dist/secrets-DNgVgz_e.mjs.map +1 -0
  761. package/dist/sections-BPCEGYWd.mjs +346 -0
  762. package/dist/sections-BPCEGYWd.mjs.map +1 -0
  763. package/dist/seed/index.d.mts +2 -2
  764. package/dist/seed/index.mjs +35 -33
  765. package/dist/seo/index.d.mts +3 -3
  766. package/dist/seo/index.mjs +26 -24
  767. package/dist/seo/index.mjs.map +1 -1
  768. package/dist/seo-BtU70b7l.mjs +114 -0
  769. package/dist/seo-BtU70b7l.mjs.map +1 -0
  770. package/dist/seo-rCk6pDwT.mjs +133 -0
  771. package/dist/seo-rCk6pDwT.mjs.map +1 -0
  772. package/dist/service-Bpy5iTX0.mjs +150 -0
  773. package/dist/service-Bpy5iTX0.mjs.map +1 -0
  774. package/dist/session-user-BQeS2Mrb.mjs +51 -0
  775. package/dist/session-user-BQeS2Mrb.mjs.map +1 -0
  776. package/dist/settings-CsoLiwpL.mjs +420 -0
  777. package/dist/settings-CsoLiwpL.mjs.map +1 -0
  778. package/dist/settings-DCnWtfSZ.mjs +51 -0
  779. package/dist/settings-DCnWtfSZ.mjs.map +1 -0
  780. package/dist/setup-complete-BrZaXpVV.mjs +26 -0
  781. package/dist/setup-complete-BrZaXpVV.mjs.map +1 -0
  782. package/dist/setup-nonce-Cb9-884O.mjs +25 -0
  783. package/dist/setup-nonce-Cb9-884O.mjs.map +1 -0
  784. package/dist/single-flight-cache-B5O2qhO1.mjs +104 -0
  785. package/dist/single-flight-cache-B5O2qhO1.mjs.map +1 -0
  786. package/dist/site-url-DjhYCaep.mjs +16 -0
  787. package/dist/site-url-DjhYCaep.mjs.map +1 -0
  788. package/dist/slugify-T5GHH42D.mjs +17 -0
  789. package/dist/slugify-T5GHH42D.mjs.map +1 -0
  790. package/dist/snapshot-C32Xuv3o.mjs +233 -0
  791. package/dist/snapshot-C32Xuv3o.mjs.map +1 -0
  792. package/dist/ssrf-Co1GGFZz.mjs +406 -0
  793. package/dist/ssrf-Co1GGFZz.mjs.map +1 -0
  794. package/dist/state-C7gCoiHr.mjs +153 -0
  795. package/dist/state-C7gCoiHr.mjs.map +1 -0
  796. package/dist/status-DLoBmcDz.mjs +30 -0
  797. package/dist/status-DLoBmcDz.mjs.map +1 -0
  798. package/dist/storage/local.d.mts +1 -1
  799. package/dist/storage/local.mjs +1 -1
  800. package/dist/storage/s3.d.mts +1 -1
  801. package/dist/storage/s3.mjs +1 -1
  802. package/dist/storage-query-CPctdMKX.d.mts +1519 -0
  803. package/dist/storage-query-CPctdMKX.d.mts.map +1 -0
  804. package/dist/target-CUKlGrXb.mjs +27 -0
  805. package/dist/target-CUKlGrXb.mjs.map +1 -0
  806. package/dist/taxonomies-Bs5dJVDJ.mjs +899 -0
  807. package/dist/taxonomies-Bs5dJVDJ.mjs.map +1 -0
  808. package/dist/taxonomies-DjGU22ur.mjs +707 -0
  809. package/dist/taxonomies-DjGU22ur.mjs.map +1 -0
  810. package/dist/taxonomy-c1Q8PMFF.mjs +508 -0
  811. package/dist/taxonomy-c1Q8PMFF.mjs.map +1 -0
  812. package/dist/tokens-Ns02GAma.mjs +171 -0
  813. package/dist/tokens-Ns02GAma.mjs.map +1 -0
  814. package/dist/transaction-BcJO4Tmc.mjs +29 -0
  815. package/dist/transaction-BcJO4Tmc.mjs.map +1 -0
  816. package/dist/transport-B8P1xsqk.mjs +136 -0
  817. package/dist/transport-B8P1xsqk.mjs.map +1 -0
  818. package/dist/transport-BLHZZcD_.d.mts +42 -0
  819. package/dist/transport-BLHZZcD_.d.mts.map +1 -0
  820. package/dist/trusted-proxy-Cg7SuD15.mjs +51 -0
  821. package/dist/trusted-proxy-Cg7SuD15.mjs.map +1 -0
  822. package/dist/turnstile-DWCSh_Qc.mjs +53 -0
  823. package/dist/turnstile-DWCSh_Qc.mjs.map +1 -0
  824. package/dist/types-B3RkqvDW.mjs +156 -0
  825. package/dist/types-B3RkqvDW.mjs.map +1 -0
  826. package/dist/types-BkUg2yHx.mjs +92 -0
  827. package/dist/types-BkUg2yHx.mjs.map +1 -0
  828. package/dist/types-BtuppOTV.mjs +16 -0
  829. package/dist/types-BtuppOTV.mjs.map +1 -0
  830. package/dist/types-CCR3ivXE.d.mts +363 -0
  831. package/dist/types-CCR3ivXE.d.mts.map +1 -0
  832. package/dist/types-CSHgU_-_.mjs +18 -0
  833. package/dist/types-CSHgU_-_.mjs.map +1 -0
  834. package/dist/types-CbwqGOXm.d.mts +766 -0
  835. package/dist/types-CbwqGOXm.d.mts.map +1 -0
  836. package/dist/types-D4RGIc2I.d.mts +198 -0
  837. package/dist/types-D4RGIc2I.d.mts.map +1 -0
  838. package/dist/types-DEHidMEk.d.mts +1637 -0
  839. package/dist/types-DEHidMEk.d.mts.map +1 -0
  840. package/dist/types-DQeU2SR7.d.mts +279 -0
  841. package/dist/types-DQeU2SR7.d.mts.map +1 -0
  842. package/dist/types-DxQWoQLA.d.mts +264 -0
  843. package/dist/types-DxQWoQLA.d.mts.map +1 -0
  844. package/dist/types-FBBnGZ2Y.d.mts +198 -0
  845. package/dist/types-FBBnGZ2Y.d.mts.map +1 -0
  846. package/dist/types-ZCnlropY.mjs +69 -0
  847. package/dist/types-ZCnlropY.mjs.map +1 -0
  848. package/dist/types-_Qtyawiy.d.mts +124 -0
  849. package/dist/types-_Qtyawiy.d.mts.map +1 -0
  850. package/dist/types-gC6FAoa_.d.mts +75 -0
  851. package/dist/types-gC6FAoa_.d.mts.map +1 -0
  852. package/dist/types-k--LneIF.mjs +22 -0
  853. package/dist/types-k--LneIF.mjs.map +1 -0
  854. package/dist/upload-attempts-2xdnoKGe.mjs +27 -0
  855. package/dist/upload-attempts-2xdnoKGe.mjs.map +1 -0
  856. package/dist/url-pattern-3m3reMzr.mjs +33 -0
  857. package/dist/url-pattern-3m3reMzr.mjs.map +1 -0
  858. package/dist/user-2R1gceFl.mjs +171 -0
  859. package/dist/user-2R1gceFl.mjs.map +1 -0
  860. package/dist/utils-CC2oNGV8.mjs +435 -0
  861. package/dist/utils-CC2oNGV8.mjs.map +1 -0
  862. package/dist/validate-CaFSi_Wa.mjs +384 -0
  863. package/dist/validate-CaFSi_Wa.mjs.map +1 -0
  864. package/dist/validate-CyQ7I3xF.d.mts +410 -0
  865. package/dist/validate-CyQ7I3xF.d.mts.map +1 -0
  866. package/dist/validate-DANX1-Qi.mjs +120 -0
  867. package/dist/validate-DANX1-Qi.mjs.map +1 -0
  868. package/dist/validation-nsX2uixg.mjs +216 -0
  869. package/dist/validation-nsX2uixg.mjs.map +1 -0
  870. package/dist/version-DGh4SL8e.mjs +7 -0
  871. package/dist/version-DGh4SL8e.mjs.map +1 -0
  872. package/dist/widgets-B7ued6f5.mjs +126 -0
  873. package/dist/widgets-B7ued6f5.mjs.map +1 -0
  874. package/dist/wxr-taxonomies-BtH3jYSg.mjs +406 -0
  875. package/dist/wxr-taxonomies-BtH3jYSg.mjs.map +1 -0
  876. package/dist/wxr-taxonomies-DU2ZSiGc.d.mts +34 -0
  877. package/dist/wxr-taxonomies-DU2ZSiGc.d.mts.map +1 -0
  878. package/dist/zod-generator-DuBjYyrI.mjs +329 -0
  879. package/dist/zod-generator-DuBjYyrI.mjs.map +1 -0
  880. package/package.json +36 -11
  881. package/src/api/errors.ts +16 -0
  882. package/src/api/handlers/backup.ts +11 -5
  883. package/src/api/handlers/content.ts +160 -6
  884. package/src/api/handlers/dashboard.ts +31 -1
  885. package/src/api/handlers/index.ts +3 -0
  886. package/src/api/handlers/manifest.ts +4 -6
  887. package/src/api/handlers/marketplace.ts +99 -15
  888. package/src/api/handlers/media-upload.ts +31 -4
  889. package/src/api/handlers/plugin-settings.ts +35 -3
  890. package/src/api/handlers/redirects.ts +221 -138
  891. package/src/api/handlers/registry.ts +62 -21
  892. package/src/api/handlers/revision.ts +14 -26
  893. package/src/api/handlers/snapshot.ts +4 -1
  894. package/src/api/handlers/taxonomies.ts +70 -5
  895. package/src/api/handlers/validation.ts +120 -19
  896. package/src/api/openapi/document.ts +34 -17
  897. package/src/api/schemas/content.ts +26 -14
  898. package/src/api/schemas/entry-lock.ts +9 -0
  899. package/src/api/schemas/search.ts +4 -0
  900. package/src/api/types.ts +2 -0
  901. package/src/astro/integration/index.ts +16 -3
  902. package/src/astro/integration/routes.ts +84 -0
  903. package/src/astro/integration/runtime.ts +31 -23
  904. package/src/astro/integration/virtual-modules.ts +4 -0
  905. package/src/astro/integration/vite-config.ts +1 -0
  906. package/src/astro/middleware/auth.ts +25 -4
  907. package/src/astro/middleware/request-context.ts +28 -10
  908. package/src/astro/middleware.ts +17 -1
  909. package/src/astro/prefetch.ts +2 -2
  910. package/src/astro/routes/api/admin/comments/[id]/status.ts +22 -58
  911. package/src/astro/routes/api/admin/plugins/[id]/disable.ts +2 -15
  912. package/src/astro/routes/api/admin/plugins/[id]/enable.ts +2 -25
  913. package/src/astro/routes/api/admin/plugins/[id]/uninstall.ts +1 -0
  914. package/src/astro/routes/api/admin/plugins/[id]/update.ts +23 -4
  915. package/src/astro/routes/api/admin/plugins/marketplace/[id]/install.ts +12 -2
  916. package/src/astro/routes/api/admin/plugins/registry/[id]/uninstall.ts +1 -0
  917. package/src/astro/routes/api/admin/plugins/registry/[id]/update.ts +29 -10
  918. package/src/astro/routes/api/admin/plugins/registry/artifact.ts +8 -2
  919. package/src/astro/routes/api/admin/plugins/registry/install.ts +15 -4
  920. package/src/astro/routes/api/admin/plugins/registry/verify.ts +2 -1
  921. package/src/astro/routes/api/admin/plugins/updates.ts +6 -1
  922. package/src/astro/routes/api/admin/scheduled-policy-rejections/[collection]/[id].ts +34 -0
  923. package/src/astro/routes/api/comments/[collection]/[contentId]/index.ts +4 -259
  924. package/src/astro/routes/api/content/[collection]/[id]/plugin-extensions/[pluginId]/[kind]/[extensionId].ts +29 -0
  925. package/src/astro/routes/api/content/[collection]/[id]/publish.ts +10 -3
  926. package/src/astro/routes/api/content/[collection]/[id]/schedule.ts +10 -1
  927. package/src/astro/routes/api/content/[collection]/[id]/unpublish.ts +5 -1
  928. package/src/astro/routes/api/health.ts +23 -0
  929. package/src/astro/routes/api/manifest.ts +14 -4
  930. package/src/astro/routes/api/mcp.ts +2 -1
  931. package/src/astro/routes/api/media/asset/[id]/[filename].ts +50 -0
  932. package/src/astro/routes/api/plugins/[pluginId]/[...path].ts +13 -81
  933. package/src/astro/routes/api/redirects/[id].ts +0 -3
  934. package/src/astro/routes/api/redirects/index.ts +0 -2
  935. package/src/astro/routes/api/search/index.ts +1 -0
  936. package/src/astro/routes/api/visual-editing/action-token.ts +36 -0
  937. package/src/astro/routes/api/visual-editing/content/[collection]/[id]/publish.ts +32 -0
  938. package/src/astro/routes/api/visual-editing/toolbar-labels.ts +16 -0
  939. package/src/astro/routes/sitemap-[collection].xml.ts +7 -4
  940. package/src/astro/types.ts +70 -9
  941. package/src/cli/commands/bundle-utils.ts +19 -19
  942. package/src/cli/commands/bundle.ts +9 -6
  943. package/src/cli/commands/content.ts +1 -1
  944. package/src/cli/commands/doctor.ts +25 -0
  945. package/src/cli/commands/export-seed.ts +193 -56
  946. package/src/cli/commands/migrate.ts +71 -23
  947. package/src/cli/commands/publish.ts +2 -2
  948. package/src/comments/public-submission.ts +246 -0
  949. package/src/comments/service.ts +59 -12
  950. package/src/components/EmDashHead.astro +1 -0
  951. package/src/components/widgets/Archives.astro +6 -5
  952. package/src/config/secrets.ts +25 -11
  953. package/src/content/known-fields.ts +44 -0
  954. package/src/database/connection.ts +5 -1
  955. package/src/database/content-datetime.ts +123 -0
  956. package/src/database/datetime-storage.ts +452 -0
  957. package/src/database/dialect-helpers.ts +36 -1
  958. package/src/database/migration-lock.ts +140 -0
  959. package/src/database/migrations/078_menu_item_translation_groups.ts +15 -0
  960. package/src/database/migrations/079_datetime_normalization.ts +13 -0
  961. package/src/database/migrations/080_content_translation_locale_unique.ts +88 -0
  962. package/src/database/migrations/081_redirect_write_guards.ts +260 -0
  963. package/src/database/migrations/082_taxonomy_translation_locale_unique.ts +49 -0
  964. package/src/database/migrations/runner.ts +57 -15
  965. package/src/database/pg-migration-lock.ts +2 -2
  966. package/src/database/repositories/byline.ts +9 -0
  967. package/src/database/repositories/comment.ts +86 -0
  968. package/src/database/repositories/content.ts +391 -69
  969. package/src/database/repositories/media.ts +35 -4
  970. package/src/database/repositories/menu.ts +1 -0
  971. package/src/database/repositories/options.ts +46 -4
  972. package/src/database/repositories/redirect.ts +259 -64
  973. package/src/database/repositories/revision.ts +116 -17
  974. package/src/database/repositories/taxonomy.ts +34 -0
  975. package/src/database/repositories/types.ts +2 -0
  976. package/src/database/types.ts +11 -0
  977. package/src/datetime-normalization.ts +311 -0
  978. package/src/db/node-sqlite-compat.ts +3 -2
  979. package/src/emdash-runtime.ts +1925 -422
  980. package/src/fields/image.ts +2 -0
  981. package/src/i18n/config.ts +6 -6
  982. package/src/i18n/resolve.ts +54 -11
  983. package/src/index.ts +87 -0
  984. package/src/loader.ts +14 -0
  985. package/src/mcp/server.ts +194 -64
  986. package/src/media/usage/extractor.ts +50 -15
  987. package/src/media/usage/types.ts +1 -1
  988. package/src/menus/index.ts +49 -16
  989. package/src/migrations/direct-executor.ts +40 -2
  990. package/src/migrations/index.ts +1 -0
  991. package/src/migrations/protocol.ts +11 -1
  992. package/src/plugin-test-runtime.ts +17 -0
  993. package/src/plugin-types.ts +119 -21
  994. package/src/plugins/adapt-sandbox-entry.ts +34 -27
  995. package/src/plugins/content-access.ts +170 -0
  996. package/src/plugins/content-policy.ts +74 -0
  997. package/src/plugins/context.ts +742 -150
  998. package/src/plugins/cron.ts +18 -10
  999. package/src/plugins/define-plugin.ts +55 -54
  1000. package/src/plugins/editor-draft.ts +257 -0
  1001. package/src/plugins/hooks.ts +129 -2
  1002. package/src/plugins/host.ts +29 -0
  1003. package/src/plugins/http-route-dispatch.ts +389 -0
  1004. package/src/plugins/http-wire.ts +180 -0
  1005. package/src/plugins/index.ts +88 -3
  1006. package/src/plugins/install-finalization.ts +77 -0
  1007. package/src/plugins/lifecycle.ts +47 -0
  1008. package/src/plugins/manifest-schema.ts +314 -58
  1009. package/src/plugins/media.ts +166 -0
  1010. package/src/plugins/request-meta.ts +12 -2
  1011. package/src/plugins/route-wire.ts +304 -0
  1012. package/src/plugins/routes.ts +38 -5
  1013. package/src/plugins/sandbox/index.ts +4 -0
  1014. package/src/plugins/sandbox/proxy.ts +129 -0
  1015. package/src/plugins/sandbox/types.ts +67 -5
  1016. package/src/plugins/secret-redactor.ts +65 -0
  1017. package/src/plugins/settings.ts +303 -0
  1018. package/src/plugins/state.ts +26 -0
  1019. package/src/plugins/types.ts +488 -15
  1020. package/src/query.ts +55 -1
  1021. package/src/registry/authoritative-records.ts +26 -0
  1022. package/src/registry/config.ts +70 -22
  1023. package/src/registry/testing.ts +100 -0
  1024. package/src/registry/types.ts +7 -64
  1025. package/src/scheduled-publish.ts +70 -3
  1026. package/src/schema/index.ts +1 -0
  1027. package/src/schema/registry.ts +45 -1
  1028. package/src/schema/types.ts +7 -0
  1029. package/src/schema/zod-generator.ts +5 -13
  1030. package/src/search/fts-manager.ts +3 -3
  1031. package/src/search/query.ts +32 -5
  1032. package/src/search/types.ts +8 -0
  1033. package/src/seed/apply.ts +37 -3
  1034. package/src/seed/types.ts +6 -1
  1035. package/src/seo/hreflang.ts +9 -6
  1036. package/src/settings/index.ts +53 -11
  1037. package/src/visual-editing/action-token.ts +31 -0
  1038. package/src/visual-editing/toolbar-bootstrap.ts +31 -6
  1039. package/src/visual-editing/toolbar.ts +103 -12
  1040. package/src/widgets/archives.ts +10 -9
  1041. package/src/widgets/index.ts +11 -1
  1042. package/dist/activation-DyNTe_Tl.mjs +0 -382
  1043. package/dist/activation-DyNTe_Tl.mjs.map +0 -1
  1044. package/dist/adapters-DCEgOBXi.d.mts +0 -171
  1045. package/dist/adapters-DCEgOBXi.d.mts.map +0 -1
  1046. package/dist/after-CBU2vkoO.mjs +0 -96
  1047. package/dist/after-CBU2vkoO.mjs.map +0 -1
  1048. package/dist/allowed-origins-GFUVavRj.mjs +0 -116
  1049. package/dist/allowed-origins-GFUVavRj.mjs.map +0 -1
  1050. package/dist/api-BvxJmnFY.mjs +0 -10094
  1051. package/dist/api-BvxJmnFY.mjs.map +0 -1
  1052. package/dist/api-tokens-xpGqMHrC.mjs +0 -163
  1053. package/dist/api-tokens-xpGqMHrC.mjs.map +0 -1
  1054. package/dist/apply-DLmM3R7f.mjs +0 -984
  1055. package/dist/apply-DLmM3R7f.mjs.map +0 -1
  1056. package/dist/artifact-fetch-P2JXVwOq.mjs +0 -972
  1057. package/dist/artifact-fetch-P2JXVwOq.mjs.map +0 -1
  1058. package/dist/authorize-C2QHlWSS.mjs +0 -40
  1059. package/dist/authorize-C2QHlWSS.mjs.map +0 -1
  1060. package/dist/backup-oS8ft5Cm.mjs +0 -241
  1061. package/dist/backup-oS8ft5Cm.mjs.map +0 -1
  1062. package/dist/base64-CvLhUKQv.mjs +0 -63
  1063. package/dist/base64-CvLhUKQv.mjs.map +0 -1
  1064. package/dist/bundle-CL0JjIPx.mjs +0 -663
  1065. package/dist/bundle-CL0JjIPx.mjs.map +0 -1
  1066. package/dist/byline-Vdi85CsZ.mjs +0 -902
  1067. package/dist/byline-Vdi85CsZ.mjs.map +0 -1
  1068. package/dist/byline-fields-DPVRFMz2.mjs +0 -123
  1069. package/dist/byline-fields-DPVRFMz2.mjs.map +0 -1
  1070. package/dist/byline-registry-BxDGIO0I.mjs +0 -406
  1071. package/dist/byline-registry-BxDGIO0I.mjs.map +0 -1
  1072. package/dist/bylines-BX8QhcTk.mjs +0 -232
  1073. package/dist/bylines-BX8QhcTk.mjs.map +0 -1
  1074. package/dist/bylines-w-E1IEQd.mjs +0 -214
  1075. package/dist/bylines-w-E1IEQd.mjs.map +0 -1
  1076. package/dist/cache--7HKu5Xm.mjs +0 -108
  1077. package/dist/cache--7HKu5Xm.mjs.map +0 -1
  1078. package/dist/capture-triggers-CeAsC76Z.mjs +0 -362
  1079. package/dist/capture-triggers-CeAsC76Z.mjs.map +0 -1
  1080. package/dist/challenge-store-BIOak-tp.mjs +0 -51
  1081. package/dist/challenge-store-BIOak-tp.mjs.map +0 -1
  1082. package/dist/chrome-tags-DzDQBCjX.mjs +0 -24
  1083. package/dist/chrome-tags-DzDQBCjX.mjs.map +0 -1
  1084. package/dist/chunks-VG_tyqnP.mjs +0 -25
  1085. package/dist/chunks-VG_tyqnP.mjs.map +0 -1
  1086. package/dist/collection-deletion-BCwaWTDw.mjs +0 -436
  1087. package/dist/collection-deletion-BCwaWTDw.mjs.map +0 -1
  1088. package/dist/collection-slugs-cache-7lTmNzeA.mjs +0 -85
  1089. package/dist/collection-slugs-cache-7lTmNzeA.mjs.map +0 -1
  1090. package/dist/comment-reaction-CDyvPQRj.mjs +0 -85
  1091. package/dist/comment-reaction-CDyvPQRj.mjs.map +0 -1
  1092. package/dist/comment-vxOzWbZN.mjs +0 -255
  1093. package/dist/comment-vxOzWbZN.mjs.map +0 -1
  1094. package/dist/comments-VzmVLyaC.mjs +0 -204
  1095. package/dist/comments-VzmVLyaC.mjs.map +0 -1
  1096. package/dist/components-CL6Wkdk-.mjs +0 -108
  1097. package/dist/components-CL6Wkdk-.mjs.map +0 -1
  1098. package/dist/config--eWjQJE5.mjs +0 -217
  1099. package/dist/config--eWjQJE5.mjs.map +0 -1
  1100. package/dist/config-C3EBstHi.mjs +0 -72
  1101. package/dist/config-C3EBstHi.mjs.map +0 -1
  1102. package/dist/config-CGAhyOjP.d.mts +0 -6653
  1103. package/dist/config-CGAhyOjP.d.mts.map +0 -1
  1104. package/dist/config-ChFzshGd.d.mts +0 -34
  1105. package/dist/config-ChFzshGd.d.mts.map +0 -1
  1106. package/dist/content-CNfMWuhY.mjs +0 -1841
  1107. package/dist/content-CNfMWuhY.mjs.map +0 -1
  1108. package/dist/content-list-query-B8d4UQp9.d.mts +0 -26
  1109. package/dist/content-list-query-B8d4UQp9.d.mts.map +0 -1
  1110. package/dist/content-refresh-GTMyi2Xy.mjs +0 -3588
  1111. package/dist/content-refresh-GTMyi2Xy.mjs.map +0 -1
  1112. package/dist/content-repair-CIMt5C0U.mjs +0 -440
  1113. package/dist/content-repair-CIMt5C0U.mjs.map +0 -1
  1114. package/dist/context-C9PB8vGd.mjs +0 -1308
  1115. package/dist/context-C9PB8vGd.mjs.map +0 -1
  1116. package/dist/cron-DHAy9oyq.mjs +0 -277
  1117. package/dist/cron-DHAy9oyq.mjs.map +0 -1
  1118. package/dist/dashboard-BNSvAN8A.mjs +0 -140
  1119. package/dist/dashboard-BNSvAN8A.mjs.map +0 -1
  1120. package/dist/db-errors-Cl-sKYTm.mjs +0 -55
  1121. package/dist/db-errors-Cl-sKYTm.mjs.map +0 -1
  1122. package/dist/default-ByZ0JqZo.mjs +0 -81
  1123. package/dist/default-ByZ0JqZo.mjs.map +0 -1
  1124. package/dist/deferred-tasks-Cu4NSJpa.d.mts +0 -9
  1125. package/dist/deferred-tasks-Cu4NSJpa.d.mts.map +0 -1
  1126. package/dist/dev-typegen-DHT7lcMU.mjs +0 -29
  1127. package/dist/dev-typegen-DHT7lcMU.mjs.map +0 -1
  1128. package/dist/device-flow-Cf6bhCCT.mjs +0 -466
  1129. package/dist/device-flow-Cf6bhCCT.mjs.map +0 -1
  1130. package/dist/dialect-helpers-BcQvkHgn.mjs +0 -283
  1131. package/dist/dialect-helpers-BcQvkHgn.mjs.map +0 -1
  1132. package/dist/direct-executor-yAyUGSqB.mjs +0 -85
  1133. package/dist/direct-executor-yAyUGSqB.mjs.map +0 -1
  1134. package/dist/dist-BAsh8dbf.mjs +0 -810
  1135. package/dist/dist-BAsh8dbf.mjs.map +0 -1
  1136. package/dist/email-console-DNup1Fku.mjs +0 -50
  1137. package/dist/email-console-DNup1Fku.mjs.map +0 -1
  1138. package/dist/enrich-t2Xvjdqa.mjs +0 -194
  1139. package/dist/enrich-t2Xvjdqa.mjs.map +0 -1
  1140. package/dist/entry-lock-BEr8gDkG.mjs +0 -163
  1141. package/dist/entry-lock-BEr8gDkG.mjs.map +0 -1
  1142. package/dist/entry-lock-CGAtrwAR.d.mts +0 -3409
  1143. package/dist/entry-lock-CGAtrwAR.d.mts.map +0 -1
  1144. package/dist/entry-lock-DIYHAaSw.mjs +0 -1281
  1145. package/dist/entry-lock-DIYHAaSw.mjs.map +0 -1
  1146. package/dist/entry-locks-BEcX7ET0.mjs +0 -167
  1147. package/dist/entry-locks-BEcX7ET0.mjs.map +0 -1
  1148. package/dist/error-BDcFyoRt.mjs +0 -90
  1149. package/dist/error-BDcFyoRt.mjs.map +0 -1
  1150. package/dist/errors-DvMdNrgf.mjs +0 -434
  1151. package/dist/errors-DvMdNrgf.mjs.map +0 -1
  1152. package/dist/escape-B3asJC6W.mjs +0 -9
  1153. package/dist/escape-B3asJC6W.mjs.map +0 -1
  1154. package/dist/field-defs-cache-Cf5FHK0M.mjs +0 -77
  1155. package/dist/field-defs-cache-Cf5FHK0M.mjs.map +0 -1
  1156. package/dist/focal-point-BeWFo6Xx.mjs +0 -23
  1157. package/dist/focal-point-BeWFo6Xx.mjs.map +0 -1
  1158. package/dist/fts-manager-iddym8cd.mjs +0 -413
  1159. package/dist/fts-manager-iddym8cd.mjs.map +0 -1
  1160. package/dist/hash-BRweX6jz.mjs +0 -37
  1161. package/dist/hash-BRweX6jz.mjs.map +0 -1
  1162. package/dist/hook-result-BrshYHLx.d.mts +0 -31
  1163. package/dist/hook-result-BrshYHLx.d.mts.map +0 -1
  1164. package/dist/hreflang-CQpu5bMy.d.mts +0 -48
  1165. package/dist/hreflang-CQpu5bMy.d.mts.map +0 -1
  1166. package/dist/hreflang-DshnweTC.mjs +0 -103
  1167. package/dist/hreflang-DshnweTC.mjs.map +0 -1
  1168. package/dist/identity-CjGKDq8J.mjs +0 -35
  1169. package/dist/identity-CjGKDq8J.mjs.map +0 -1
  1170. package/dist/import-D96g2otw.mjs +0 -2020
  1171. package/dist/import-D96g2otw.mjs.map +0 -1
  1172. package/dist/index-1ECYpfiF.d.mts +0 -278
  1173. package/dist/index-1ECYpfiF.d.mts.map +0 -1
  1174. package/dist/init-lock-CFNBe_iH.mjs +0 -56
  1175. package/dist/init-lock-CFNBe_iH.mjs.map +0 -1
  1176. package/dist/load-DPtY9cZo.mjs +0 -28
  1177. package/dist/load-DPtY9cZo.mjs.map +0 -1
  1178. package/dist/loader-WJi6GFRn.mjs +0 -1004
  1179. package/dist/loader-WJi6GFRn.mjs.map +0 -1
  1180. package/dist/manifest-builder-BfNlGQIA.mjs +0 -189
  1181. package/dist/manifest-builder-BfNlGQIA.mjs.map +0 -1
  1182. package/dist/manifest-schema-CILooI5J.mjs +0 -301
  1183. package/dist/manifest-schema-CILooI5J.mjs.map +0 -1
  1184. package/dist/media-BBm8Wg3f.mjs +0 -318
  1185. package/dist/media-BBm8Wg3f.mjs.map +0 -1
  1186. package/dist/media-C1EIZKh1.mjs +0 -464
  1187. package/dist/media-C1EIZKh1.mjs.map +0 -1
  1188. package/dist/media-allowlist-elXJgb_K.mjs +0 -44
  1189. package/dist/media-allowlist-elXJgb_K.mjs.map +0 -1
  1190. package/dist/media-folders-DASfX_DH.mjs +0 -210
  1191. package/dist/media-folders-DASfX_DH.mjs.map +0 -1
  1192. package/dist/media-upload-C7_AQJ5v.mjs +0 -147
  1193. package/dist/media-upload-C7_AQJ5v.mjs.map +0 -1
  1194. package/dist/media-url-8dVl1loq.mjs +0 -43
  1195. package/dist/media-url-8dVl1loq.mjs.map +0 -1
  1196. package/dist/media-usage-C1EswMTq.mjs +0 -1833
  1197. package/dist/media-usage-C1EswMTq.mjs.map +0 -1
  1198. package/dist/media-usage-activation-CrHNltlL.mjs +0 -78
  1199. package/dist/media-usage-activation-CrHNltlL.mjs.map +0 -1
  1200. package/dist/media-usage-work-C5B1zT1c.mjs +0 -586
  1201. package/dist/media-usage-work-C5B1zT1c.mjs.map +0 -1
  1202. package/dist/media-usage-work-IkQx_Yz6.mjs +0 -152
  1203. package/dist/media-usage-work-IkQx_Yz6.mjs.map +0 -1
  1204. package/dist/media-usage-write-fence-B9anjOSg.mjs +0 -42
  1205. package/dist/media-usage-write-fence-B9anjOSg.mjs.map +0 -1
  1206. package/dist/menus-D8mC4eaN.mjs +0 -3989
  1207. package/dist/menus-D8mC4eaN.mjs.map +0 -1
  1208. package/dist/menus-UdwjHZJC.mjs +0 -752
  1209. package/dist/menus-UdwjHZJC.mjs.map +0 -1
  1210. package/dist/mime-DYpsOAny.mjs +0 -36
  1211. package/dist/mime-DYpsOAny.mjs.map +0 -1
  1212. package/dist/mode-Dm4BHhRH.mjs +0 -23
  1213. package/dist/mode-Dm4BHhRH.mjs.map +0 -1
  1214. package/dist/node-sqlite-compat-2sezm-Zd.mjs +0 -46
  1215. package/dist/node-sqlite-compat-2sezm-Zd.mjs.map +0 -1
  1216. package/dist/normalize-4nkKGsuW.mjs +0 -191
  1217. package/dist/normalize-4nkKGsuW.mjs.map +0 -1
  1218. package/dist/oauth-authorization-BxE_lURD.mjs +0 -274
  1219. package/dist/oauth-authorization-BxE_lURD.mjs.map +0 -1
  1220. package/dist/oauth-clients-DJIdOdq0.mjs +0 -266
  1221. package/dist/oauth-clients-DJIdOdq0.mjs.map +0 -1
  1222. package/dist/oauth-state-store-CsdxP57n.mjs +0 -50
  1223. package/dist/oauth-state-store-CsdxP57n.mjs.map +0 -1
  1224. package/dist/oauth-user-lookup-HzzW-dkF.mjs +0 -26
  1225. package/dist/oauth-user-lookup-HzzW-dkF.mjs.map +0 -1
  1226. package/dist/object-cache-DVKnyOfy.mjs +0 -534
  1227. package/dist/object-cache-DVKnyOfy.mjs.map +0 -1
  1228. package/dist/options-D1FBiAv1.mjs +0 -172
  1229. package/dist/options-D1FBiAv1.mjs.map +0 -1
  1230. package/dist/options-D8Y0VHc7.d.mts +0 -227
  1231. package/dist/options-D8Y0VHc7.d.mts.map +0 -1
  1232. package/dist/parse-WRg5C3NX.mjs +0 -81
  1233. package/dist/parse-WRg5C3NX.mjs.map +0 -1
  1234. package/dist/passkey-config-qIdO-wF6.mjs +0 -46
  1235. package/dist/passkey-config-qIdO-wF6.mjs.map +0 -1
  1236. package/dist/patterns-DC8CLptu.mjs +0 -145
  1237. package/dist/patterns-DC8CLptu.mjs.map +0 -1
  1238. package/dist/placeholder-COrvARyD.d.mts +0 -306
  1239. package/dist/placeholder-COrvARyD.d.mts.map +0 -1
  1240. package/dist/policy-XCfb-IE9.mjs +0 -45
  1241. package/dist/policy-XCfb-IE9.mjs.map +0 -1
  1242. package/dist/portable-text-BS3d5n-0.mjs +0 -286
  1243. package/dist/portable-text-BS3d5n-0.mjs.map +0 -1
  1244. package/dist/preview-BxwsGgGp.mjs +0 -107
  1245. package/dist/preview-BxwsGgGp.mjs.map +0 -1
  1246. package/dist/protocol-CLn58-nw.d.mts +0 -52
  1247. package/dist/protocol-CLn58-nw.d.mts.map +0 -1
  1248. package/dist/public-url-FWWAvnre.mjs +0 -101
  1249. package/dist/public-url-FWWAvnre.mjs.map +0 -1
  1250. package/dist/query-DygOte9M.mjs +0 -890
  1251. package/dist/query-DygOte9M.mjs.map +0 -1
  1252. package/dist/query-gtXT03Wc.mjs +0 -41
  1253. package/dist/query-gtXT03Wc.mjs.map +0 -1
  1254. package/dist/rate-limit-CQUPm0dh.mjs +0 -120
  1255. package/dist/rate-limit-CQUPm0dh.mjs.map +0 -1
  1256. package/dist/redirect-D1cWafi6.mjs +0 -17
  1257. package/dist/redirect-D1cWafi6.mjs.map +0 -1
  1258. package/dist/redirect-DId44BS1.mjs +0 -326
  1259. package/dist/redirect-DId44BS1.mjs.map +0 -1
  1260. package/dist/redirects-DN-ZE33W.mjs +0 -579
  1261. package/dist/redirects-DN-ZE33W.mjs.map +0 -1
  1262. package/dist/registry-DTqaqxed.mjs +0 -1195
  1263. package/dist/registry-DTqaqxed.mjs.map +0 -1
  1264. package/dist/relation-DxgCHOBw.mjs +0 -334
  1265. package/dist/relation-DxgCHOBw.mjs.map +0 -1
  1266. package/dist/relations-KKDSLUwS.mjs +0 -403
  1267. package/dist/relations-KKDSLUwS.mjs.map +0 -1
  1268. package/dist/relations-rOmbndUJ.mjs +0 -309
  1269. package/dist/relations-rOmbndUJ.mjs.map +0 -1
  1270. package/dist/request-cache-DAZZmesc.mjs +0 -104
  1271. package/dist/request-cache-DAZZmesc.mjs.map +0 -1
  1272. package/dist/request-meta-BgjUQLQ-.mjs +0 -140
  1273. package/dist/request-meta-BgjUQLQ-.mjs.map +0 -1
  1274. package/dist/resolve-Cy0aWSRj.mjs +0 -176
  1275. package/dist/resolve-Cy0aWSRj.mjs.map +0 -1
  1276. package/dist/runner-CfwysRM0.d.mts +0 -67
  1277. package/dist/runner-CfwysRM0.d.mts.map +0 -1
  1278. package/dist/runner-nEzvnogG.mjs +0 -4800
  1279. package/dist/runner-nEzvnogG.mjs.map +0 -1
  1280. package/dist/schema-CRu38Pr5.mjs +0 -9
  1281. package/dist/schema-CRu38Pr5.mjs.map +0 -1
  1282. package/dist/schema-DifxndJx.mjs +0 -420
  1283. package/dist/schema-DifxndJx.mjs.map +0 -1
  1284. package/dist/scopes-D5A1OZbq.mjs +0 -27
  1285. package/dist/scopes-D5A1OZbq.mjs.map +0 -1
  1286. package/dist/search-DEPFSBFq.mjs +0 -439
  1287. package/dist/search-DEPFSBFq.mjs.map +0 -1
  1288. package/dist/secrets-CdfzLdoO.mjs +0 -330
  1289. package/dist/secrets-CdfzLdoO.mjs.map +0 -1
  1290. package/dist/sections-3X52kmIR.mjs +0 -346
  1291. package/dist/sections-3X52kmIR.mjs.map +0 -1
  1292. package/dist/seo-Bw68KxRc.mjs +0 -133
  1293. package/dist/seo-Bw68KxRc.mjs.map +0 -1
  1294. package/dist/seo-C4AmbsMU.mjs +0 -114
  1295. package/dist/seo-C4AmbsMU.mjs.map +0 -1
  1296. package/dist/service-J_-Vgo7R.mjs +0 -195
  1297. package/dist/service-J_-Vgo7R.mjs.map +0 -1
  1298. package/dist/session-user-CbnMMwk6.mjs +0 -51
  1299. package/dist/session-user-CbnMMwk6.mjs.map +0 -1
  1300. package/dist/settings-AnEFYICn.mjs +0 -51
  1301. package/dist/settings-AnEFYICn.mjs.map +0 -1
  1302. package/dist/settings-DcMjREe5.mjs +0 -258
  1303. package/dist/settings-DcMjREe5.mjs.map +0 -1
  1304. package/dist/setup-complete-BClXXTvr.mjs +0 -26
  1305. package/dist/setup-complete-BClXXTvr.mjs.map +0 -1
  1306. package/dist/setup-nonce-BheRa4RG.mjs +0 -25
  1307. package/dist/setup-nonce-BheRa4RG.mjs.map +0 -1
  1308. package/dist/single-flight-cache-jaswDzmQ.mjs +0 -104
  1309. package/dist/single-flight-cache-jaswDzmQ.mjs.map +0 -1
  1310. package/dist/site-url-Bqf-ea3N.mjs +0 -16
  1311. package/dist/site-url-Bqf-ea3N.mjs.map +0 -1
  1312. package/dist/slugify-B994zkXC.mjs +0 -17
  1313. package/dist/slugify-B994zkXC.mjs.map +0 -1
  1314. package/dist/snapshot-C4CtXntb.mjs +0 -232
  1315. package/dist/snapshot-C4CtXntb.mjs.map +0 -1
  1316. package/dist/ssrf-gl4gFNhw.mjs +0 -406
  1317. package/dist/ssrf-gl4gFNhw.mjs.map +0 -1
  1318. package/dist/state-1F6IOhdQ.mjs +0 -136
  1319. package/dist/state-1F6IOhdQ.mjs.map +0 -1
  1320. package/dist/status-Cenfk_r5.mjs +0 -30
  1321. package/dist/status-Cenfk_r5.mjs.map +0 -1
  1322. package/dist/target-CRzeTs8G.mjs +0 -27
  1323. package/dist/target-CRzeTs8G.mjs.map +0 -1
  1324. package/dist/taxonomies-BOdxuZpV.mjs +0 -844
  1325. package/dist/taxonomies-BOdxuZpV.mjs.map +0 -1
  1326. package/dist/taxonomies-NcFDq5Gg.mjs +0 -707
  1327. package/dist/taxonomies-NcFDq5Gg.mjs.map +0 -1
  1328. package/dist/taxonomy-DP1vny4K.mjs +0 -492
  1329. package/dist/taxonomy-DP1vny4K.mjs.map +0 -1
  1330. package/dist/tokens-CDk8ox9p.mjs +0 -171
  1331. package/dist/tokens-CDk8ox9p.mjs.map +0 -1
  1332. package/dist/transaction-0KOpOyMu.mjs +0 -29
  1333. package/dist/transaction-0KOpOyMu.mjs.map +0 -1
  1334. package/dist/transport-BVn4tVb9.d.mts +0 -42
  1335. package/dist/transport-BVn4tVb9.d.mts.map +0 -1
  1336. package/dist/transport-DP0JI-8i.mjs +0 -136
  1337. package/dist/transport-DP0JI-8i.mjs.map +0 -1
  1338. package/dist/trusted-proxy-BTM6UxqD.mjs +0 -51
  1339. package/dist/trusted-proxy-BTM6UxqD.mjs.map +0 -1
  1340. package/dist/types-2n848aVW.d.mts +0 -198
  1341. package/dist/types-2n848aVW.d.mts.map +0 -1
  1342. package/dist/types-A2cN6a4a.mjs +0 -3
  1343. package/dist/types-BMXnRIrX.mjs +0 -144
  1344. package/dist/types-BMXnRIrX.mjs.map +0 -1
  1345. package/dist/types-BouXpOsa.d.mts +0 -1446
  1346. package/dist/types-BouXpOsa.d.mts.map +0 -1
  1347. package/dist/types-ByG2coLw.mjs +0 -16
  1348. package/dist/types-ByG2coLw.mjs.map +0 -1
  1349. package/dist/types-CQPWhPxE.mjs +0 -92
  1350. package/dist/types-CQPWhPxE.mjs.map +0 -1
  1351. package/dist/types-DEfNJ__A.d.mts +0 -75
  1352. package/dist/types-DEfNJ__A.d.mts.map +0 -1
  1353. package/dist/types-DKcKSbtB.d.mts +0 -273
  1354. package/dist/types-DKcKSbtB.d.mts.map +0 -1
  1355. package/dist/types-DRYs7uTL.d.mts +0 -198
  1356. package/dist/types-DRYs7uTL.d.mts.map +0 -1
  1357. package/dist/types-DaEg7KX2.d.mts +0 -363
  1358. package/dist/types-DaEg7KX2.d.mts.map +0 -1
  1359. package/dist/types-LU8utpP_.d.mts +0 -262
  1360. package/dist/types-LU8utpP_.d.mts.map +0 -1
  1361. package/dist/types-VpYfPUxN.d.mts +0 -124
  1362. package/dist/types-VpYfPUxN.d.mts.map +0 -1
  1363. package/dist/types-c9GP7Dj5.mjs +0 -18
  1364. package/dist/types-c9GP7Dj5.mjs.map +0 -1
  1365. package/dist/types-tJWDK__M.d.mts +0 -756
  1366. package/dist/types-tJWDK__M.d.mts.map +0 -1
  1367. package/dist/upload-attempts-C6S2y-lp.mjs +0 -27
  1368. package/dist/upload-attempts-C6S2y-lp.mjs.map +0 -1
  1369. package/dist/url-pattern-UYtxVTuj.mjs +0 -33
  1370. package/dist/url-pattern-UYtxVTuj.mjs.map +0 -1
  1371. package/dist/user-DIsIXogT.mjs +0 -171
  1372. package/dist/user-DIsIXogT.mjs.map +0 -1
  1373. package/dist/utils-BicP5Qbg.mjs +0 -435
  1374. package/dist/utils-BicP5Qbg.mjs.map +0 -1
  1375. package/dist/validate-BpwoDOgt.mjs +0 -120
  1376. package/dist/validate-BpwoDOgt.mjs.map +0 -1
  1377. package/dist/validate-D8VPn4Hv.mjs +0 -384
  1378. package/dist/validate-D8VPn4Hv.mjs.map +0 -1
  1379. package/dist/validate-Df6Dvwbw.d.mts +0 -405
  1380. package/dist/validate-Df6Dvwbw.d.mts.map +0 -1
  1381. package/dist/validation-CzMJn9Ku.mjs +0 -155
  1382. package/dist/validation-CzMJn9Ku.mjs.map +0 -1
  1383. package/dist/version-CK67_SXX.mjs +0 -7
  1384. package/dist/version-CK67_SXX.mjs.map +0 -1
  1385. package/dist/widgets-RFVAxQl3.mjs +0 -122
  1386. package/dist/widgets-RFVAxQl3.mjs.map +0 -1
  1387. package/dist/wxr-taxonomies-BX4yQL9s.d.mts +0 -34
  1388. package/dist/wxr-taxonomies-BX4yQL9s.d.mts.map +0 -1
  1389. package/dist/wxr-taxonomies-Csdp7yde.mjs +0 -406
  1390. package/dist/wxr-taxonomies-Csdp7yde.mjs.map +0 -1
  1391. package/dist/zod-generator-CNRGdnBY.mjs +0 -331
  1392. package/dist/zod-generator-CNRGdnBY.mjs.map +0 -1
  1393. /package/dist/{api-tokens-B_lfpmH3.mjs → api-tokens-DS1VzN7_.mjs} +0 -0
  1394. /package/dist/{ssrf-TQhaljuI.mjs → ssrf-BRpTDMV6.mjs} +0 -0
@@ -8,17 +8,31 @@
8
8
  import type { Kysely } from "kysely";
9
9
  import { ulid } from "ulidx";
10
10
 
11
+ import {
12
+ handleRedirectCreate,
13
+ handleRedirectDelete,
14
+ handleRedirectList,
15
+ handleRedirectUpdate,
16
+ } from "../api/handlers/redirects.js";
17
+ import { handleTermCreate } from "../api/handlers/taxonomies.js";
18
+ import { createRedirectBody, updateRedirectBody } from "../api/schemas/redirects.js";
19
+ import { CommentRepository, type Comment } from "../database/repositories/comment.js";
11
20
  import { ContentRepository } from "../database/repositories/content.js";
12
21
  import { EntryLockRepository } from "../database/repositories/entry-locks.js";
13
22
  import { MediaRepository } from "../database/repositories/media.js";
14
23
  import { OptionsRepository } from "../database/repositories/options.js";
15
24
  import { PluginStorageRepository } from "../database/repositories/plugin-storage.js";
25
+ import {
26
+ RedirectRepository,
27
+ type Redirect,
28
+ type VersionedRedirectRecord,
29
+ } from "../database/repositories/redirect.js";
16
30
  import { SeoRepository } from "../database/repositories/seo.js";
17
31
  import { TaxonomyRepository, type Taxonomy } from "../database/repositories/taxonomy.js";
18
32
  import { UserRepository } from "../database/repositories/user.js";
19
33
  import { withTransaction } from "../database/transaction.js";
20
34
  import type { Database } from "../database/types.js";
21
- import { resolveContentCreateLocale } from "../i18n/config.js";
35
+ import { getI18nConfig, resolveContentCreateLocale } from "../i18n/config.js";
22
36
  import {
23
37
  resolveAndValidateExternalUrl,
24
38
  SsrfError,
@@ -26,21 +40,38 @@ import {
26
40
  } from "../import/ssrf.js";
27
41
  import { enrichImageMetadata } from "../media/enrich.js";
28
42
  import { markContentMediaUsageCollectionStaleSafely } from "../media/usage/content-refresh.js";
43
+ import { SchemaRegistry } from "../schema/registry.js";
29
44
  import { invalidateSiteSettingsCache } from "../settings/index.js";
30
45
  import type { Storage } from "../storage/types.js";
31
46
  import { assertStorageKey } from "./conditional-storage.js";
47
+ import { createContentAccess } from "./content-access.js";
32
48
  import { CronAccessImpl } from "./cron.js";
33
49
  import type { EmailPipeline } from "./email.js";
50
+ import {
51
+ bufferPluginHttpRequest,
52
+ pluginHttpRedirectAction,
53
+ pluginHttpResponseFromWire,
54
+ pluginHttpResponseToWire,
55
+ rewritePluginHttpRedirect,
56
+ } from "./http-wire.js";
57
+ import { readPluginMediaBytes, toPluginMediaItem, updatePluginMediaMetadata } from "./media.js";
58
+ import {
59
+ createPluginSecretRedactor,
60
+ createSettingsAccess,
61
+ type PluginSecretRedactor,
62
+ } from "./settings.js";
34
63
  import type {
35
64
  ResolvedPlugin,
36
65
  PluginContext,
37
66
  PluginStorageConfig,
38
67
  StorageCollection,
39
68
  KVAccess,
69
+ SettingsAccess,
40
70
  CronAccess,
41
71
  EmailAccess,
42
72
  ContentAccess,
43
73
  ContentAccessWithWrite,
74
+ VersionedContentItem,
44
75
  MediaAccess,
45
76
  MediaAccessWithWrite,
46
77
  HttpAccess,
@@ -55,14 +86,32 @@ import type {
55
86
  MediaItem,
56
87
  PaginatedResult,
57
88
  QueryOptions,
58
- ContentListOptions,
59
89
  MediaListOptions,
60
90
  TaxonomyAccess,
91
+ TaxonomyAccessWithWrite,
61
92
  TaxonomyDefInfo,
62
93
  TaxonomyTermInfo,
94
+ TaxonomyTermCreateInput,
63
95
  TaxonomyReadOptions,
96
+ CommentAccess,
97
+ CommentListOptions,
98
+ PluginComment,
99
+ PluginCommentStatus,
100
+ RedirectAccess,
101
+ RedirectAccessWithWrite,
102
+ RedirectCreateInput,
103
+ RedirectInfo,
104
+ RedirectListOptions,
105
+ RedirectStatus,
106
+ RedirectUpdateInput,
107
+ VersionedRedirect,
108
+ SchemaAccess,
109
+ CollectionSchemaInfo,
110
+ PluginContentCreateCallback,
64
111
  } from "./types.js";
65
112
 
113
+ export { createContentAccess } from "./content-access.js";
114
+
66
115
  // =============================================================================
67
116
  // KV Access
68
117
  // =============================================================================
@@ -71,44 +120,76 @@ import type {
71
120
  * Create KV accessor for a plugin
72
121
  * All keys are automatically prefixed with the plugin ID
73
122
  */
74
- export function createKVAccess(optionsRepo: OptionsRepository, pluginId: string): KVAccess {
123
+ export function createKVAccess(
124
+ optionsRepo: OptionsRepository,
125
+ pluginId: string,
126
+ settings: SettingsAccess = createSettingsAccess(optionsRepo, pluginId),
127
+ ): KVAccess {
75
128
  const prefix = `plugin:${pluginId}:`;
76
129
 
77
130
  return {
78
131
  async get<T>(key: string): Promise<T | null> {
132
+ if (key.startsWith("settings:")) return settings.get<T>(key.slice("settings:".length));
79
133
  return optionsRepo.get<T>(`${prefix}${key}`);
80
134
  },
81
135
  async getVersioned<T>(key: string) {
82
136
  assertStorageKey(key);
137
+ if (key.startsWith("settings:")) {
138
+ return settings.getVersioned<T>(key.slice("settings:".length));
139
+ }
83
140
  return optionsRepo.getVersioned<T>(`${prefix}${key}`);
84
141
  },
85
142
  async compareAndSet(key, expectedRevision, value) {
86
143
  assertStorageKey(key);
144
+ if (key.startsWith("settings:")) {
145
+ return settings.compareAndSet(key.slice("settings:".length), expectedRevision, value);
146
+ }
87
147
  return optionsRepo.compareAndSet(`${prefix}${key}`, expectedRevision, value);
88
148
  },
89
149
  async compareAndDelete(key, expectedRevision) {
90
150
  assertStorageKey(key);
151
+ if (key.startsWith("settings:")) {
152
+ return settings.compareAndDelete(key.slice("settings:".length), expectedRevision);
153
+ }
91
154
  return optionsRepo.compareAndDelete(`${prefix}${key}`, expectedRevision);
92
155
  },
93
156
 
94
157
  async set(key: string, value: unknown): Promise<void> {
158
+ if (key.startsWith("settings:")) {
159
+ await settings.set(key.slice("settings:".length), value);
160
+ return;
161
+ }
95
162
  await optionsRepo.set(`${prefix}${key}`, value);
96
163
  },
97
164
 
98
165
  async delete(key: string): Promise<boolean> {
166
+ if (key.startsWith("settings:")) return settings.delete(key.slice("settings:".length));
99
167
  return optionsRepo.delete(`${prefix}${key}`);
100
168
  },
101
169
 
102
170
  async list(keyPrefix?: string): Promise<Array<{ key: string; value: unknown }>> {
103
- const fullPrefix = `${prefix}${keyPrefix ?? ""}`;
171
+ const requestedPrefix = keyPrefix ?? "";
172
+ const includesSettings =
173
+ "settings:".startsWith(requestedPrefix) || requestedPrefix.startsWith("settings:");
174
+ const fullPrefix = `${prefix}${requestedPrefix}`;
104
175
  const entriesMap = await optionsRepo.getByPrefix(fullPrefix);
105
176
  const result: Array<{ key: string; value: unknown }> = [];
106
177
  for (const [fullKey, value] of entriesMap) {
178
+ if (includesSettings && fullKey.startsWith(`${prefix}settings:`)) continue;
107
179
  result.push({
108
180
  key: fullKey.slice(prefix.length),
109
181
  value,
110
182
  });
111
183
  }
184
+ if (includesSettings) {
185
+ const settingPrefix = requestedPrefix.startsWith("settings:")
186
+ ? requestedPrefix.slice("settings:".length)
187
+ : "";
188
+ for (const entry of await settings.list(settingPrefix)) {
189
+ const key = `settings:${entry.key}`;
190
+ if (key.startsWith(requestedPrefix)) result.push({ key, value: entry.value });
191
+ }
192
+ }
112
193
  return result;
113
194
  },
114
195
  };
@@ -250,88 +331,53 @@ function taxonomyToTermInfo(term: Taxonomy): TaxonomyTermInfo {
250
331
  };
251
332
  }
252
333
 
253
- /**
254
- * Create read-only content access
255
- */
256
- export function createContentAccess(db: Kysely<Database>): ContentAccess {
257
- const contentRepo = new ContentRepository(db);
258
- const seoRepo = new SeoRepository(db);
259
-
334
+ function collectionToSchemaInfo(
335
+ collection: Awaited<ReturnType<SchemaRegistry["getCollectionWithFields"]>>,
336
+ ): CollectionSchemaInfo | null {
337
+ if (!collection) return null;
260
338
  return {
261
- async get(collection: string, id: string): Promise<ContentItem | null> {
262
- const item = await contentRepo.findById(collection, id);
263
- if (!item) return null;
264
-
265
- const result: ContentItem = {
266
- id: item.id,
267
- type: item.type,
268
- slug: item.slug,
269
- status: item.status,
270
- data: item.data,
271
- createdAt: item.createdAt,
272
- updatedAt: item.updatedAt,
273
- locale: item.locale,
274
- publishedAt: item.publishedAt,
275
- scheduledAt: item.scheduledAt,
276
- };
339
+ slug: collection.slug,
340
+ label: collection.label,
341
+ labelSingular: collection.labelSingular ?? null,
342
+ description: collection.description ?? null,
343
+ supports: collection.supports,
344
+ hasSeo: collection.hasSeo,
345
+ titleField: collection.titleField ?? null,
346
+ dateField: collection.dateField ?? null,
347
+ urlPattern: collection.urlPattern ?? null,
348
+ routable: collection.routable !== false,
349
+ hidden: collection.hidden,
350
+ fields: collection.fields.map((field) => ({
351
+ slug: field.slug,
352
+ label: field.label,
353
+ type: field.type,
354
+ required: field.required,
355
+ unique: field.unique,
356
+ ...(field.defaultValue === undefined ? {} : { default: field.defaultValue }),
357
+ ...(field.validation === undefined ? {} : { validation: field.validation }),
358
+ ...(field.widget === undefined ? {} : { widget: field.widget }),
359
+ ...(field.options === undefined ? {} : { options: field.options }),
360
+ searchable: field.searchable,
361
+ indexed: field.indexed,
362
+ translatable: field.translatable,
363
+ sortOrder: field.sortOrder,
364
+ })),
365
+ };
366
+ }
277
367
 
278
- if (await seoRepo.isEnabled(collection)) {
279
- result.seo = await seoRepo.get(collection, item.id);
368
+ export function createSchemaAccess(db: Kysely<Database>): SchemaAccess {
369
+ const registry = new SchemaRegistry(db);
370
+ return {
371
+ async listCollections() {
372
+ const collections: CollectionSchemaInfo[] = [];
373
+ for (const collection of await registry.listCollectionsWithFields()) {
374
+ const info = collectionToSchemaInfo(collection);
375
+ if (info) collections.push(info);
280
376
  }
281
-
282
- return result;
377
+ return collections;
283
378
  },
284
-
285
- async list(
286
- collection: string,
287
- options?: ContentListOptions,
288
- ): Promise<PaginatedResult<ContentItem>> {
289
- // Convert orderBy format if provided
290
- let orderBy: { field: string; direction: "asc" | "desc" } | undefined;
291
- if (options?.orderBy) {
292
- const entries = Object.entries(options.orderBy);
293
- const first = entries[0];
294
- if (first) {
295
- orderBy = { field: first[0], direction: first[1] };
296
- }
297
- }
298
-
299
- const result = await contentRepo.findMany(collection, {
300
- limit: options?.limit ?? 50,
301
- cursor: options?.cursor,
302
- orderBy,
303
- where: options?.where,
304
- });
305
-
306
- const items: ContentItem[] = result.items.map((item) => ({
307
- id: item.id,
308
- type: item.type,
309
- slug: item.slug,
310
- status: item.status,
311
- data: item.data,
312
- createdAt: item.createdAt,
313
- updatedAt: item.updatedAt,
314
- locale: item.locale,
315
- publishedAt: item.publishedAt,
316
- scheduledAt: item.scheduledAt,
317
- }));
318
-
319
- if (items.length > 0 && (await seoRepo.isEnabled(collection))) {
320
- const seoMap = await seoRepo.getMany(
321
- collection,
322
- items.map((i) => i.id),
323
- );
324
- for (const item of items) {
325
- const seo = seoMap.get(item.id);
326
- if (seo) item.seo = seo;
327
- }
328
- }
329
-
330
- return {
331
- items,
332
- cursor: result.nextCursor,
333
- hasMore: !!result.nextCursor,
334
- };
379
+ async getCollection(slug) {
380
+ return collectionToSchemaInfo(await registry.getCollectionWithFields(slug));
335
381
  },
336
382
  };
337
383
  }
@@ -378,6 +424,327 @@ export function createTaxonomyAccess(db: Kysely<Database>): TaxonomyAccess {
378
424
  };
379
425
  }
380
426
 
427
+ function toPluginComment(comment: Comment): PluginComment {
428
+ if (comment.status === "trash") throw new Error("Trashed comments are not plugin-readable");
429
+ return {
430
+ id: comment.id,
431
+ collection: comment.collection,
432
+ contentId: comment.contentId,
433
+ parentId: comment.parentId,
434
+ authorName: comment.authorName,
435
+ authorEmail: comment.authorEmail,
436
+ body: comment.body,
437
+ status: comment.status,
438
+ ipHash: comment.ipHash,
439
+ userAgent: comment.userAgent,
440
+ moderationMetadata: comment.moderationMetadata,
441
+ createdAt: comment.createdAt,
442
+ updatedAt: comment.updatedAt,
443
+ };
444
+ }
445
+
446
+ export function createCommentAccess(
447
+ db: Kysely<Database>,
448
+ moderate?: (
449
+ id: string,
450
+ status: PluginCommentStatus,
451
+ expectedStatus: PluginCommentStatus,
452
+ ) => Promise<PluginComment>,
453
+ ): CommentAccess {
454
+ const repo = new CommentRepository(db);
455
+ return {
456
+ async get(id) {
457
+ const comment = await repo.findById(id);
458
+ return !comment || comment.status === "trash" ? null : toPluginComment(comment);
459
+ },
460
+ async list(options: CommentListOptions = {}) {
461
+ const result = await repo.findForPlugin(options);
462
+ return {
463
+ items: result.items.map(toPluginComment),
464
+ cursor: result.nextCursor,
465
+ hasMore: result.nextCursor !== undefined,
466
+ };
467
+ },
468
+ count: (options) => repo.countForPlugin(options),
469
+ ...(moderate
470
+ ? {
471
+ setStatus: (id, status, options) => moderate(id, status, options.expectedStatus),
472
+ }
473
+ : {}),
474
+ };
475
+ }
476
+
477
+ export class RedirectAccessError extends Error {
478
+ override readonly name = "RedirectAccessError";
479
+
480
+ constructor(
481
+ readonly code: string,
482
+ message: string,
483
+ ) {
484
+ super(message);
485
+ }
486
+ }
487
+
488
+ const REDIRECT_REVISION_PREFIX = "r1.";
489
+ const BASE64_PADDING_RE = /=+$/;
490
+
491
+ function encodeRedirectRevision(id: string, revision: string): string {
492
+ const payload = `${id}\0${revision}`;
493
+ return `${REDIRECT_REVISION_PREFIX}${btoa(payload)
494
+ .replaceAll("+", "-")
495
+ .replaceAll("/", "_")
496
+ .replace(BASE64_PADDING_RE, "")}`;
497
+ }
498
+
499
+ function decodeRedirectRevision(id: string, revision: string): string {
500
+ if (typeof revision !== "string" || !revision.startsWith(REDIRECT_REVISION_PREFIX)) {
501
+ throw new RedirectAccessError("INVALID_PRECONDITION", "Invalid redirect revision");
502
+ }
503
+ try {
504
+ const encoded = revision
505
+ .slice(REDIRECT_REVISION_PREFIX.length)
506
+ .replaceAll("-", "+")
507
+ .replaceAll("_", "/");
508
+ const padded = encoded.padEnd(Math.ceil(encoded.length / 4) * 4, "=");
509
+ const [revisionId, updatedAt, extra] = atob(padded).split("\0");
510
+ if (revisionId !== id || !updatedAt || extra !== undefined) throw new Error("invalid");
511
+ return updatedAt;
512
+ } catch (error) {
513
+ if (error instanceof RedirectAccessError) throw error;
514
+ throw new RedirectAccessError("INVALID_PRECONDITION", "Invalid redirect revision");
515
+ }
516
+ }
517
+
518
+ function toRedirectInfo(redirect: Redirect): RedirectInfo {
519
+ return {
520
+ ...redirect,
521
+ type: redirect.type as RedirectStatus,
522
+ };
523
+ }
524
+
525
+ function toVersionedRedirect(record: VersionedRedirectRecord): VersionedRedirect {
526
+ return {
527
+ redirect: toRedirectInfo(record.redirect),
528
+ _rev: encodeRedirectRevision(record.redirect.id, record.configRevision),
529
+ };
530
+ }
531
+
532
+ async function readVersionedRedirect(
533
+ repo: RedirectRepository,
534
+ id: string,
535
+ ): Promise<VersionedRedirect | null> {
536
+ const record = await repo.findVersionedById(id);
537
+ return record ? toVersionedRedirect(record) : null;
538
+ }
539
+
540
+ function throwRedirectResult(error: { code: string; message: string }): never {
541
+ throw new RedirectAccessError(error.code, error.message);
542
+ }
543
+
544
+ function assertNoAutomaticRedirectMarker(input: object): void {
545
+ if (typeof input !== "object" || input === null || Array.isArray(input)) {
546
+ throw new RedirectAccessError("VALIDATION_ERROR", "Redirect input must be an object");
547
+ }
548
+ if (Object.hasOwn(input, "auto")) {
549
+ throw new RedirectAccessError(
550
+ "VALIDATION_ERROR",
551
+ "The automatic redirect marker is managed by EmDash",
552
+ );
553
+ }
554
+ }
555
+
556
+ export function createRedirectAccess(db: Kysely<Database>): RedirectAccess;
557
+ export function createRedirectAccess(db: Kysely<Database>, writable: true): RedirectAccessWithWrite;
558
+ export function createRedirectAccess(
559
+ db: Kysely<Database>,
560
+ writable = false,
561
+ ): RedirectAccess | RedirectAccessWithWrite {
562
+ const repo = new RedirectRepository(db);
563
+ const readAccess: RedirectAccess = {
564
+ async list(options: RedirectListOptions = {}) {
565
+ const result = await handleRedirectList(db, options);
566
+ if (!result.success) return throwRedirectResult(result.error);
567
+ return {
568
+ items: result.data.items.map(toRedirectInfo),
569
+ cursor: result.data.nextCursor,
570
+ hasMore: result.data.nextCursor !== undefined,
571
+ };
572
+ },
573
+ get: (id: string) => readVersionedRedirect(repo, id),
574
+ };
575
+ if (!writable) return readAccess;
576
+
577
+ return {
578
+ ...readAccess,
579
+ async create(input: RedirectCreateInput) {
580
+ assertNoAutomaticRedirectMarker(input);
581
+ const parsed = createRedirectBody.safeParse(input);
582
+ if (!parsed.success) {
583
+ throw new RedirectAccessError(
584
+ "VALIDATION_ERROR",
585
+ parsed.error.issues[0]?.message ?? "Invalid redirect",
586
+ );
587
+ }
588
+ const result = await handleRedirectCreate(db, parsed.data);
589
+ if (!result.success) return throwRedirectResult(result.error);
590
+ const current = await readVersionedRedirect(repo, result.data.id);
591
+ if (!current) throw new RedirectAccessError("NOT_FOUND", "Created redirect not found");
592
+ return current;
593
+ },
594
+ async update(id: string, input: RedirectUpdateInput & { _rev: string }) {
595
+ assertNoAutomaticRedirectMarker(input);
596
+ const { _rev, ...patch } = input;
597
+ const expectedRevision = decodeRedirectRevision(id, _rev);
598
+ const parsed = updateRedirectBody.safeParse(patch);
599
+ if (!parsed.success) {
600
+ throw new RedirectAccessError(
601
+ "VALIDATION_ERROR",
602
+ parsed.error.issues[0]?.message ?? "Invalid redirect",
603
+ );
604
+ }
605
+ const result = await handleRedirectUpdate(db, id, parsed.data, { expectedRevision });
606
+ if (!result.success) return throwRedirectResult(result.error);
607
+ const current = await readVersionedRedirect(repo, result.data.id);
608
+ if (!current) throw new RedirectAccessError("NOT_FOUND", "Updated redirect not found");
609
+ return current;
610
+ },
611
+ async delete(id: string, options: { _rev: string }) {
612
+ if (typeof options !== "object" || options === null) {
613
+ throw new RedirectAccessError("INVALID_PRECONDITION", "Invalid redirect revision");
614
+ }
615
+ const expectedRevision = decodeRedirectRevision(id, options._rev);
616
+ const result = await handleRedirectDelete(db, id, { expectedRevision });
617
+ if (!result.success) return throwRedirectResult(result.error);
618
+ return result.data.deleted;
619
+ },
620
+ };
621
+ }
622
+
623
+ const MAX_TAXONOMY_DELTA_TERMS = 64;
624
+
625
+ function taxonomyAccessError(code: string, message: string): Error {
626
+ return Object.assign(new Error(message), { code });
627
+ }
628
+
629
+ async function resolveTaxonomyDelta(
630
+ db: Kysely<Database>,
631
+ collection: string,
632
+ entryId: string,
633
+ taxonomy: string,
634
+ termIds: string[],
635
+ ): Promise<{ repo: TaxonomyRepository; groups: string[]; locale: string }> {
636
+ if (termIds.length > MAX_TAXONOMY_DELTA_TERMS) {
637
+ throw taxonomyAccessError(
638
+ "VALIDATION_ERROR",
639
+ `A taxonomy assignment delta can contain at most ${MAX_TAXONOMY_DELTA_TERMS} term IDs`,
640
+ );
641
+ }
642
+ if (termIds.some((id) => typeof id !== "string" || id.length === 0)) {
643
+ throw taxonomyAccessError("VALIDATION_ERROR", "Taxonomy term IDs must be non-empty strings");
644
+ }
645
+
646
+ const defs = await db
647
+ .selectFrom("_emdash_taxonomy_defs")
648
+ .select(["collections"])
649
+ .where("name", "=", taxonomy)
650
+ .execute();
651
+ if (defs.length === 0) {
652
+ throw taxonomyAccessError("NOT_FOUND", `Taxonomy '${taxonomy}' not found`);
653
+ }
654
+ const attached = defs.some((def) => parseCollectionsColumn(def.collections).includes(collection));
655
+ if (!attached) {
656
+ throw taxonomyAccessError(
657
+ "VALIDATION_ERROR",
658
+ `Taxonomy '${taxonomy}' is not attached to collection '${collection}'`,
659
+ );
660
+ }
661
+
662
+ const entry = await new ContentRepository(db).findById(collection, entryId);
663
+ if (!entry) {
664
+ throw taxonomyAccessError(
665
+ "NOT_FOUND",
666
+ `Content entry '${entryId}' not found in '${collection}'`,
667
+ );
668
+ }
669
+
670
+ const repo = new TaxonomyRepository(db);
671
+ const groups: string[] = [];
672
+ for (const id of new Set(termIds)) {
673
+ const term = await repo.findByIdOrTranslationGroup(id);
674
+ if (!term) throw taxonomyAccessError("NOT_FOUND", `Taxonomy term '${id}' not found`);
675
+ if (term.name !== taxonomy) {
676
+ throw taxonomyAccessError(
677
+ "VALIDATION_ERROR",
678
+ `Taxonomy term '${id}' belongs to '${term.name}', not '${taxonomy}'`,
679
+ );
680
+ }
681
+ groups.push(term.translationGroup ?? term.id);
682
+ }
683
+
684
+ return { repo, groups, locale: entry.locale ?? getI18nConfig()?.defaultLocale ?? "en" };
685
+ }
686
+
687
+ async function readResolvedEntryTerms(
688
+ repo: TaxonomyRepository,
689
+ collection: string,
690
+ entryId: string,
691
+ taxonomy: string,
692
+ locale: string,
693
+ ): Promise<TaxonomyTermInfo[]> {
694
+ const defaultLocale = getI18nConfig()?.defaultLocale ?? locale;
695
+ const assignments = await repo.getTermAssignmentsForEntry(
696
+ collection,
697
+ entryId,
698
+ taxonomy,
699
+ locale,
700
+ defaultLocale,
701
+ );
702
+ return assignments.flatMap(({ term }) => (term ? [taxonomyToTermInfo(term)] : []));
703
+ }
704
+
705
+ export function createTaxonomyAccessWithWrite(db: Kysely<Database>): TaxonomyAccessWithWrite {
706
+ return {
707
+ ...createTaxonomyAccess(db),
708
+ async createTerm(taxonomy: string, input: TaxonomyTermCreateInput) {
709
+ const result = await handleTermCreate(db, taxonomy, input);
710
+ if (!result.success) throw taxonomyAccessError(result.error.code, result.error.message);
711
+ const { term } = result.data;
712
+ return {
713
+ id: term.id,
714
+ taxonomy: term.name,
715
+ slug: term.slug,
716
+ label: term.label,
717
+ parentId: term.parentId,
718
+ data: term.description ? { description: term.description } : null,
719
+ locale: term.locale,
720
+ translationGroup: term.translationGroup,
721
+ };
722
+ },
723
+ async addEntryTerms(collection, entryId, taxonomy, termIds) {
724
+ const { repo, groups, locale } = await resolveTaxonomyDelta(
725
+ db,
726
+ collection,
727
+ entryId,
728
+ taxonomy,
729
+ termIds,
730
+ );
731
+ await repo.attachGroupsToEntry(collection, entryId, groups);
732
+ return readResolvedEntryTerms(repo, collection, entryId, taxonomy, locale);
733
+ },
734
+ async removeEntryTerms(collection, entryId, taxonomy, termIds) {
735
+ const { repo, groups, locale } = await resolveTaxonomyDelta(
736
+ db,
737
+ collection,
738
+ entryId,
739
+ taxonomy,
740
+ termIds,
741
+ );
742
+ await repo.detachGroupsFromEntry(collection, entryId, groups);
743
+ return readResolvedEntryTerms(repo, collection, entryId, taxonomy, locale);
744
+ },
745
+ };
746
+ }
747
+
381
748
  /**
382
749
  * Create full content access with write operations.
383
750
  *
@@ -390,8 +757,14 @@ export function createTaxonomyAccess(db: Kysely<Database>): TaxonomyAccess {
390
757
  export function createContentAccessWithWrite(
391
758
  db: Kysely<Database>,
392
759
  beforeContentWrite?: () => Promise<void>,
760
+ accessOptions?: { site?: SiteInfo; revisions?: boolean },
761
+ contentCreate?: (data: {
762
+ collection: string;
763
+ input: ContentWriteInput;
764
+ options?: ContentCreateOptions;
765
+ }) => Promise<ContentItem>,
393
766
  ): ContentAccessWithWrite {
394
- const readAccess = createContentAccess(db);
767
+ const readAccess = createContentAccess(db, accessOptions);
395
768
 
396
769
  return {
397
770
  ...readAccess,
@@ -403,6 +776,13 @@ export function createContentAccessWithWrite(
403
776
  ): Promise<ContentItem> {
404
777
  const locale = resolveContentCreateLocale(options?.locale);
405
778
  await beforeContentWrite?.();
779
+ if (contentCreate) {
780
+ return contentCreate({
781
+ collection,
782
+ input: data,
783
+ options: { ...options, locale },
784
+ });
785
+ }
406
786
  const { fields, seo } = splitSeoFromInput(data);
407
787
  let contentMutated = false;
408
788
 
@@ -417,6 +797,7 @@ export function createContentAccessWithWrite(
417
797
  type: collection,
418
798
  data: fields,
419
799
  locale,
800
+ translationOf: options?.translationOf,
420
801
  });
421
802
  contentMutated = true;
422
803
 
@@ -541,17 +922,7 @@ export function createMediaAccess(db: Kysely<Database>): MediaAccess {
541
922
  return {
542
923
  async get(id: string): Promise<MediaItem | null> {
543
924
  const item = await mediaRepo.findById(id);
544
- if (!item) return null;
545
-
546
- return {
547
- id: item.id,
548
- filename: item.filename,
549
- mimeType: item.mimeType,
550
- size: item.size,
551
- // Construct URL from storage key (or use a sensible default path)
552
- url: `/media/${item.id}/${item.filename}`,
553
- createdAt: item.createdAt,
554
- };
925
+ return item?.status === "ready" ? toPluginMediaItem(item) : null;
555
926
  },
556
927
 
557
928
  async list(options?: MediaListOptions): Promise<PaginatedResult<MediaItem>> {
@@ -562,14 +933,7 @@ export function createMediaAccess(db: Kysely<Database>): MediaAccess {
562
933
  });
563
934
 
564
935
  return {
565
- items: result.items.map((item) => ({
566
- id: item.id,
567
- filename: item.filename,
568
- mimeType: item.mimeType,
569
- size: item.size,
570
- url: `/media/${item.id}/${item.filename}`,
571
- createdAt: item.createdAt,
572
- })),
936
+ items: result.items.map(toPluginMediaItem),
573
937
  cursor: result.nextCursor,
574
938
  hasMore: !!result.nextCursor,
575
939
  };
@@ -577,6 +941,17 @@ export function createMediaAccess(db: Kysely<Database>): MediaAccess {
577
941
  };
578
942
  }
579
943
 
944
+ function mediaReadDenied(): never {
945
+ throw new Error("Missing capability: media:read");
946
+ }
947
+
948
+ function createBlockedMediaReadAccess(): MediaAccess {
949
+ return {
950
+ get: async () => mediaReadDenied(),
951
+ list: async () => mediaReadDenied(),
952
+ };
953
+ }
954
+
580
955
  /**
581
956
  * Create full media access with write operations.
582
957
  *
@@ -710,20 +1085,28 @@ export function createMediaAccessWithWrite(
710
1085
  /** Maximum number of redirects to follow in plugin HTTP access */
711
1086
  const MAX_PLUGIN_REDIRECTS = 5;
712
1087
 
1088
+ function stripTrailingDots(value: string): string {
1089
+ let end = value.length;
1090
+ while (end > 0 && value.charCodeAt(end - 1) === 46) end--;
1091
+ return end === value.length ? value : value.slice(0, end);
1092
+ }
1093
+
713
1094
  /**
714
1095
  * Check if a hostname matches any pattern in the allowed list.
715
1096
  * Patterns: "*" matches all, "*.example.com" matches subdomains AND bare "example.com",
716
1097
  * "api.example.com" matches exactly.
717
1098
  */
718
1099
  function isHostAllowed(host: string, allowedHosts: string[]): boolean {
1100
+ const normalizedHost = stripTrailingDots(host.toLowerCase());
719
1101
  return allowedHosts.some((pattern) => {
720
- if (pattern === "*") return true;
721
- if (pattern.startsWith("*.")) {
722
- const suffix = pattern.slice(1); // ".example.com"
1102
+ const normalizedPattern = stripTrailingDots(pattern.toLowerCase());
1103
+ if (normalizedPattern === "*") return true;
1104
+ if (normalizedPattern.startsWith("*.")) {
1105
+ const suffix = normalizedPattern.slice(1); // ".example.com"
723
1106
  // Match subdomains (foo.example.com) and bare domain (example.com)
724
- return host.endsWith(suffix) || host === pattern.slice(2);
1107
+ return normalizedHost.endsWith(suffix) || normalizedHost === normalizedPattern.slice(2);
725
1108
  }
726
- return host === pattern;
1109
+ return normalizedHost === normalizedPattern;
727
1110
  });
728
1111
  }
729
1112
 
@@ -753,7 +1136,11 @@ async function validatePluginHttpTarget(pluginId: string, url: string): Promise<
753
1136
  *
754
1137
  * Uses redirect: "manual" to re-validate each redirect target before dispatch.
755
1138
  */
756
- export function createHttpAccess(pluginId: string, allowedHosts: string[]): HttpAccess {
1139
+ export function createHttpAccess(
1140
+ pluginId: string,
1141
+ allowedHosts: string[],
1142
+ fetchImpl: typeof fetch = globalThis.fetch,
1143
+ ): HttpAccess {
757
1144
  return {
758
1145
  async fetch(url: string, init?: RequestInit): Promise<Response> {
759
1146
  // Deny by default — plugins must declare allowed hosts
@@ -766,6 +1153,8 @@ export function createHttpAccess(pluginId: string, allowedHosts: string[]): Http
766
1153
 
767
1154
  let currentUrl = url;
768
1155
  let currentInit = init;
1156
+ let requestBuffered = false;
1157
+ let redirected = false;
769
1158
 
770
1159
  for (let i = 0; i <= MAX_PLUGIN_REDIRECTS; i++) {
771
1160
  const target = tryParsePluginHttpTarget(currentUrl);
@@ -776,27 +1165,39 @@ export function createHttpAccess(pluginId: string, allowedHosts: string[]): Http
776
1165
  );
777
1166
  }
778
1167
  await validatePluginHttpTarget(pluginId, currentUrl);
1168
+ if (!requestBuffered) {
1169
+ currentInit = await bufferPluginHttpRequest(currentInit);
1170
+ requestBuffered = true;
1171
+ }
779
1172
 
780
- const response = await globalThis.fetch(currentUrl, {
1173
+ const response = await fetchImpl(currentUrl, {
781
1174
  ...currentInit,
782
1175
  redirect: "manual",
783
1176
  });
784
1177
 
785
- // Not a redirect -- return directly
786
- if (response.status < 300 || response.status >= 400) {
787
- return response;
788
- }
789
-
790
- // Extract redirect target
791
1178
  const location = response.headers.get("Location");
792
- if (!location) {
793
- return response;
1179
+ if (location === null) {
1180
+ return pluginHttpResponseFromWire(
1181
+ await pluginHttpResponseToWire(response, currentUrl, redirected),
1182
+ );
1183
+ }
1184
+ const redirectAction = pluginHttpRedirectAction(response.status, true, currentInit);
1185
+ if (redirectAction === "return") {
1186
+ return pluginHttpResponseFromWire(
1187
+ await pluginHttpResponseToWire(response, currentUrl, redirected),
1188
+ );
1189
+ }
1190
+ await response.body?.cancel();
1191
+ if (redirectAction === "error") {
1192
+ throw new Error(`Plugin "${pluginId}": redirect mode is "error"`);
794
1193
  }
795
1194
 
796
1195
  // Resolve relative redirects; strip credentials on cross-origin hops
797
1196
  const previousOrigin = new URL(currentUrl).origin;
798
1197
  currentUrl = new URL(location, currentUrl).href;
1198
+ redirected = true;
799
1199
  const nextOrigin = new URL(currentUrl).origin;
1200
+ currentInit = rewritePluginHttpRedirect(response.status, currentInit);
800
1201
 
801
1202
  if (previousOrigin !== nextOrigin && currentInit) {
802
1203
  currentInit = stripCredentialHeaders(currentInit);
@@ -809,39 +1210,56 @@ export function createHttpAccess(pluginId: string, allowedHosts: string[]): Http
809
1210
  }
810
1211
 
811
1212
  /**
812
- * Create unrestricted HTTP access (for plugins with network:fetch:any capability).
1213
+ * Create unrestricted HTTP access (for plugins with network:request:unrestricted capability).
813
1214
  * No host validation, but applies SSRF protection on redirect targets to
814
1215
  * prevent plugins from being tricked into reaching internal services.
815
1216
  */
816
- export function createUnrestrictedHttpAccess(pluginId: string): HttpAccess {
1217
+ export function createUnrestrictedHttpAccess(
1218
+ pluginId: string,
1219
+ fetchImpl: typeof fetch = globalThis.fetch,
1220
+ ): HttpAccess {
817
1221
  return {
818
1222
  async fetch(url: string, init?: RequestInit): Promise<Response> {
819
1223
  let currentUrl = url;
820
1224
  let currentInit = init;
1225
+ let requestBuffered = false;
1226
+ let redirected = false;
821
1227
 
822
1228
  for (let i = 0; i <= MAX_PLUGIN_REDIRECTS; i++) {
823
1229
  await validatePluginHttpTarget(pluginId, currentUrl);
1230
+ if (!requestBuffered) {
1231
+ currentInit = await bufferPluginHttpRequest(currentInit);
1232
+ requestBuffered = true;
1233
+ }
824
1234
 
825
- const response = await globalThis.fetch(currentUrl, {
1235
+ const response = await fetchImpl(currentUrl, {
826
1236
  ...currentInit,
827
1237
  redirect: "manual",
828
1238
  });
829
1239
 
830
- // Not a redirect -- return directly
831
- if (response.status < 300 || response.status >= 400) {
832
- return response;
833
- }
834
-
835
- // Extract redirect target
836
1240
  const location = response.headers.get("Location");
837
- if (!location) {
838
- return response;
1241
+ if (location === null) {
1242
+ return pluginHttpResponseFromWire(
1243
+ await pluginHttpResponseToWire(response, currentUrl, redirected),
1244
+ );
1245
+ }
1246
+ const redirectAction = pluginHttpRedirectAction(response.status, true, currentInit);
1247
+ if (redirectAction === "return") {
1248
+ return pluginHttpResponseFromWire(
1249
+ await pluginHttpResponseToWire(response, currentUrl, redirected),
1250
+ );
1251
+ }
1252
+ await response.body?.cancel();
1253
+ if (redirectAction === "error") {
1254
+ throw new Error(`Plugin "${pluginId}": redirect mode is "error"`);
839
1255
  }
840
1256
 
841
1257
  // Resolve relative redirects; strip credentials on cross-origin hops
842
1258
  const previousOrigin = new URL(currentUrl).origin;
843
1259
  currentUrl = new URL(location, currentUrl).href;
1260
+ redirected = true;
844
1261
  const nextOrigin = new URL(currentUrl).origin;
1262
+ currentInit = rewritePluginHttpRedirect(response.status, currentInit);
845
1263
 
846
1264
  if (previousOrigin !== nextOrigin && currentInit) {
847
1265
  currentInit = stripCredentialHeaders(currentInit);
@@ -874,39 +1292,40 @@ export function createBlockedHttpAccess(pluginId: string): HttpAccess {
874
1292
  /**
875
1293
  * Create logger for a plugin
876
1294
  */
877
- export function createLogAccess(pluginId: string): LogAccess {
1295
+ export function createLogAccess(pluginId: string, redactor?: PluginSecretRedactor): LogAccess {
878
1296
  const prefix = `[plugin:${pluginId}]`;
1297
+ const redact = <T>(value: T): T => redactor?.redact(value) ?? value;
879
1298
 
880
1299
  return {
881
1300
  debug(message: string, data?: unknown): void {
882
1301
  if (data !== undefined) {
883
- console.debug(prefix, message, data);
1302
+ console.debug(prefix, redact(message), redact(data));
884
1303
  } else {
885
- console.debug(prefix, message);
1304
+ console.debug(prefix, redact(message));
886
1305
  }
887
1306
  },
888
1307
 
889
1308
  info(message: string, data?: unknown): void {
890
1309
  if (data !== undefined) {
891
- console.info(prefix, message, data);
1310
+ console.info(prefix, redact(message), redact(data));
892
1311
  } else {
893
- console.info(prefix, message);
1312
+ console.info(prefix, redact(message));
894
1313
  }
895
1314
  },
896
1315
 
897
1316
  warn(message: string, data?: unknown): void {
898
1317
  if (data !== undefined) {
899
- console.warn(prefix, message, data);
1318
+ console.warn(prefix, redact(message), redact(data));
900
1319
  } else {
901
- console.warn(prefix, message);
1320
+ console.warn(prefix, redact(message));
902
1321
  }
903
1322
  },
904
1323
 
905
1324
  error(message: string, data?: unknown): void {
906
1325
  if (data !== undefined) {
907
- console.error(prefix, message, data);
1326
+ console.error(prefix, redact(message), redact(data));
908
1327
  } else {
909
- console.error(prefix, message);
1328
+ console.error(prefix, redact(message));
910
1329
  }
911
1330
  },
912
1331
  };
@@ -1037,6 +1456,8 @@ export function createUserAccess(db: Kysely<Database>): UserAccess {
1037
1456
  export interface PluginContextFactoryOptions {
1038
1457
  db: Kysely<Database>;
1039
1458
  beforeContentWrite?: () => Promise<void>;
1459
+ contentCreate?: PluginContentCreateCallback;
1460
+ contentActions?: ContentActionCallbacks;
1040
1461
  /**
1041
1462
  * Resolver for the database connection, preferred over `db` when present.
1042
1463
  * Called per `createContext()` so connection-backed adapters (e.g. Postgres
@@ -1072,6 +1493,8 @@ export interface PluginContextFactoryOptions {
1072
1493
  * If not provided, ctx.cron will not be available.
1073
1494
  */
1074
1495
  cronReschedule?: () => void;
1496
+ /** Clock used to calculate the first run of recurring plugin tasks. */
1497
+ now?: () => Date;
1075
1498
  /**
1076
1499
  * Email pipeline instance for ctx.email.
1077
1500
  * If not provided (or no provider configured), ctx.email will be undefined.
@@ -1084,6 +1507,73 @@ export interface PluginContextFactoryOptions {
1084
1507
  * client IP the core auth path does.
1085
1508
  */
1086
1509
  trustedProxyHeaders?: string[];
1510
+ commentModerate?: (
1511
+ pluginId: string,
1512
+ id: string,
1513
+ status: PluginCommentStatus,
1514
+ expectedStatus: PluginCommentStatus,
1515
+ ) => Promise<PluginComment>;
1516
+ }
1517
+
1518
+ export interface ContentActionCallbacks {
1519
+ /** Register a sandbox invocation before it can call a content action. */
1520
+ begin?(
1521
+ pluginId: string,
1522
+ invocationId: string,
1523
+ invalidateContentCache?: (tags: string[]) => Promise<void>,
1524
+ ): void;
1525
+ /** Release queued after-hooks; `final: false` keeps late actions self-scheduling after timeout. */
1526
+ flush(pluginId: string, invocationId?: string, final?: boolean): Promise<void>;
1527
+ getVersioned(
1528
+ pluginId: string,
1529
+ collection: string,
1530
+ id: string,
1531
+ ): Promise<VersionedContentItem | null>;
1532
+ publish(
1533
+ pluginId: string,
1534
+ collection: string,
1535
+ id: string,
1536
+ options: { _rev: string },
1537
+ invocationId?: string,
1538
+ invalidateContentCache?: (tags: string[]) => Promise<void>,
1539
+ ): Promise<VersionedContentItem>;
1540
+ unpublish(
1541
+ pluginId: string,
1542
+ collection: string,
1543
+ id: string,
1544
+ options: { _rev: string },
1545
+ invocationId?: string,
1546
+ invalidateContentCache?: (tags: string[]) => Promise<void>,
1547
+ ): Promise<VersionedContentItem>;
1548
+ schedule(
1549
+ pluginId: string,
1550
+ collection: string,
1551
+ id: string,
1552
+ options: { scheduledAt: string; _rev: string },
1553
+ invocationId?: string,
1554
+ invalidateContentCache?: (tags: string[]) => Promise<void>,
1555
+ ): Promise<VersionedContentItem>;
1556
+ unschedule(
1557
+ pluginId: string,
1558
+ collection: string,
1559
+ id: string,
1560
+ options: { _rev: string },
1561
+ invocationId?: string,
1562
+ invalidateContentCache?: (tags: string[]) => Promise<void>,
1563
+ ): Promise<VersionedContentItem>;
1564
+ getTrashedVersioned(
1565
+ pluginId: string,
1566
+ collection: string,
1567
+ id: string,
1568
+ ): Promise<VersionedContentItem | null>;
1569
+ restore(
1570
+ pluginId: string,
1571
+ collection: string,
1572
+ id: string,
1573
+ options: { _rev: string },
1574
+ invocationId?: string,
1575
+ invalidateContentCache?: (tags: string[]) => Promise<void>,
1576
+ ): Promise<VersionedContentItem>;
1087
1577
  }
1088
1578
 
1089
1579
  /**
@@ -1092,6 +1582,8 @@ export interface PluginContextFactoryOptions {
1092
1582
  export class PluginContextFactory {
1093
1583
  private resolveDb: () => Kysely<Database>;
1094
1584
  private beforeContentWrite?: () => Promise<void>;
1585
+ private contentCreate?: PluginContentCreateCallback;
1586
+ private contentActions?: ContentActionCallbacks;
1095
1587
  private storage?: Storage;
1096
1588
  private getUploadUrl?: (
1097
1589
  filename: string,
@@ -1100,7 +1592,9 @@ export class PluginContextFactory {
1100
1592
  private site: SiteInfo;
1101
1593
  private urlHelper: (path: string) => string;
1102
1594
  private cronReschedule?: () => void;
1595
+ private now: () => Date;
1103
1596
  private emailPipeline?: EmailPipeline;
1597
+ private commentModerate?: PluginContextFactoryOptions["commentModerate"];
1104
1598
  /**
1105
1599
  * Plugin IDs already warned about a missing media-write backend, so the
1106
1600
  * warning fires once per factory instead of on every hook/route context
@@ -1112,12 +1606,16 @@ export class PluginContextFactory {
1112
1606
  const fixedDb = options.db;
1113
1607
  this.resolveDb = options.getDb ?? (() => fixedDb);
1114
1608
  this.beforeContentWrite = options.beforeContentWrite;
1609
+ this.contentCreate = options.contentCreate;
1610
+ this.contentActions = options.contentActions;
1115
1611
  this.storage = options.storage;
1116
1612
  this.getUploadUrl = options.getUploadUrl;
1117
1613
  this.site = createSiteInfo(options.siteInfo ?? {});
1118
1614
  this.urlHelper = createUrlHelper(this.site.url);
1119
1615
  this.cronReschedule = options.cronReschedule;
1616
+ this.now = options.now ?? (() => new Date());
1120
1617
  this.emailPipeline = options.emailPipeline;
1618
+ this.commentModerate = options.commentModerate;
1121
1619
  }
1122
1620
 
1123
1621
  /**
@@ -1134,8 +1632,16 @@ export class PluginContextFactory {
1134
1632
  const optionsRepo = new OptionsRepository(db);
1135
1633
 
1136
1634
  // Always available
1137
- const kv = createKVAccess(optionsRepo, plugin.id);
1138
- const log = createLogAccess(plugin.id);
1635
+ const secretRedactor = createPluginSecretRedactor();
1636
+ const settings = createSettingsAccess(
1637
+ optionsRepo,
1638
+ plugin.id,
1639
+ plugin.admin.settingsSchema ?? {},
1640
+ undefined,
1641
+ secretRedactor.add,
1642
+ );
1643
+ const kv = createKVAccess(optionsRepo, plugin.id, settings);
1644
+ const log = createLogAccess(plugin.id, secretRedactor);
1139
1645
  const storage = createStorageAccess(db, plugin.id, plugin.storage);
1140
1646
 
1141
1647
  // Capability-gated: content
@@ -1144,23 +1650,93 @@ export class PluginContextFactory {
1144
1650
  // names ("read:content", "write:content") never appear here.
1145
1651
  let content: ContentAccess | ContentAccessWithWrite | undefined;
1146
1652
  if (capabilities.has("content:write")) {
1147
- content = createContentAccessWithWrite(db, this.beforeContentWrite);
1653
+ content = createContentAccessWithWrite(
1654
+ db,
1655
+ this.beforeContentWrite,
1656
+ {
1657
+ site: this.site,
1658
+ revisions: capabilities.has("content:revisions:read"),
1659
+ },
1660
+ this.contentCreate
1661
+ ? (input) => this.contentCreate!(plugin.id, input.collection, input.input, input.options)
1662
+ : undefined,
1663
+ );
1148
1664
  } else if (capabilities.has("content:read")) {
1149
- content = createContentAccess(db);
1665
+ content = createContentAccess(db, {
1666
+ site: this.site,
1667
+ revisions: capabilities.has("content:revisions:read"),
1668
+ });
1669
+ }
1670
+ if (capabilities.has("content:publish") && this.contentActions) {
1671
+ content = Object.assign(content ?? createContentAccess(db), {
1672
+ getVersioned: (collection: string, id: string) =>
1673
+ this.contentActions!.getVersioned(plugin.id, collection, id),
1674
+ publish: (collection: string, id: string, options: { _rev: string }) =>
1675
+ this.contentActions!.publish(plugin.id, collection, id, options),
1676
+ unpublish: (collection: string, id: string, options: { _rev: string }) =>
1677
+ this.contentActions!.unpublish(plugin.id, collection, id, options),
1678
+ schedule: (
1679
+ collection: string,
1680
+ id: string,
1681
+ options: { scheduledAt: string; _rev: string },
1682
+ ) => this.contentActions!.schedule(plugin.id, collection, id, options),
1683
+ unschedule: (collection: string, id: string, options: { _rev: string }) =>
1684
+ this.contentActions!.unschedule(plugin.id, collection, id, options),
1685
+ });
1150
1686
  }
1687
+ if (capabilities.has("content:restore") && this.contentActions) {
1688
+ content = Object.assign(
1689
+ content ?? {
1690
+ get: async () => {
1691
+ throw new Error("Missing capability: content:read");
1692
+ },
1693
+ list: async () => {
1694
+ throw new Error("Missing capability: content:read");
1695
+ },
1696
+ },
1697
+ {
1698
+ getTrashedVersioned: (collection: string, id: string) =>
1699
+ this.contentActions!.getTrashedVersioned(plugin.id, collection, id),
1700
+ restore: (collection: string, id: string, options: { _rev: string }) =>
1701
+ this.contentActions!.restore(plugin.id, collection, id, options),
1702
+ },
1703
+ );
1704
+ }
1705
+
1706
+ const schema = capabilities.has("schema:read") ? createSchemaAccess(db) : undefined;
1151
1707
 
1152
- // Capability-gated: taxonomies (read-only)
1153
- let taxonomies: TaxonomyAccess | undefined;
1154
- if (capabilities.has("taxonomies:read")) {
1708
+ // Capability-gated: taxonomies
1709
+ let taxonomies: TaxonomyAccess | TaxonomyAccessWithWrite | undefined;
1710
+ if (capabilities.has("taxonomies:write")) {
1711
+ taxonomies = createTaxonomyAccessWithWrite(db);
1712
+ } else if (capabilities.has("taxonomies:read")) {
1155
1713
  taxonomies = createTaxonomyAccess(db);
1156
1714
  }
1157
1715
 
1716
+ let redirects: RedirectAccess | RedirectAccessWithWrite | undefined;
1717
+ if (capabilities.has("redirects:write")) {
1718
+ redirects = createRedirectAccess(db, true);
1719
+ } else if (capabilities.has("redirects:read")) {
1720
+ redirects = createRedirectAccess(db);
1721
+ }
1722
+
1158
1723
  // Capability-gated: media
1159
1724
  // `upload()` only needs `storage`; `getUploadUrl()` is derived from
1160
1725
  // storage when no explicit provider is wired. Granting write access on
1161
1726
  // either avoids silently degrading media:write to read-only — the bug
1162
1727
  // where the runtime threads `storage` but not `getUploadUrl`.
1163
1728
  let media: MediaAccess | MediaAccessWithWrite | undefined;
1729
+ const hasMediaAccess =
1730
+ capabilities.has("media:read") ||
1731
+ capabilities.has("media:write") ||
1732
+ capabilities.has("media:bytes:read") ||
1733
+ capabilities.has("media:metadata:write");
1734
+ if (hasMediaAccess) {
1735
+ media =
1736
+ capabilities.has("media:read") || capabilities.has("media:write")
1737
+ ? createMediaAccess(db)
1738
+ : createBlockedMediaReadAccess();
1739
+ }
1164
1740
  if (capabilities.has("media:write")) {
1165
1741
  if (this.getUploadUrl || this.storage) {
1166
1742
  media = createMediaAccessWithWrite(db, this.getUploadUrl, this.storage);
@@ -1171,12 +1747,14 @@ export class PluginContextFactory {
1171
1747
  "declares the media:write capability but no storage backend is configured; upload() is unavailable.",
1172
1748
  );
1173
1749
  }
1174
- if (capabilities.has("media:read")) {
1175
- media = createMediaAccess(db);
1176
- }
1750
+ media ??= createMediaAccess(db);
1177
1751
  }
1178
- } else if (capabilities.has("media:read")) {
1179
- media = createMediaAccess(db);
1752
+ }
1753
+ if (capabilities.has("media:bytes:read") && media) {
1754
+ media.readBytes = (id, options) => readPluginMediaBytes(db, this.storage, id, options);
1755
+ }
1756
+ if (capabilities.has("media:metadata:write") && media) {
1757
+ media.updateMetadata = (id, patch) => updatePluginMediaMetadata(db, id, patch);
1180
1758
  }
1181
1759
 
1182
1760
  // Capability-gated: http
@@ -1193,11 +1771,21 @@ export class PluginContextFactory {
1193
1771
  users = createUserAccess(db);
1194
1772
  }
1195
1773
 
1774
+ let comments: CommentAccess | undefined;
1775
+ if (capabilities.has("comments:moderate")) {
1776
+ comments = createCommentAccess(db, (id, status, expectedStatus) => {
1777
+ if (!this.commentModerate) throw new Error("Comment moderation is unavailable");
1778
+ return this.commentModerate(plugin.id, id, status, expectedStatus);
1779
+ });
1780
+ } else if (capabilities.has("comments:read")) {
1781
+ comments = createCommentAccess(db);
1782
+ }
1783
+
1196
1784
  // Cron access — always available (scoped to plugin), but only if
1197
1785
  // the runtime provided a reschedule callback (i.e. cron is wired up).
1198
1786
  let cron: CronAccess | undefined;
1199
1787
  if (this.cronReschedule) {
1200
- cron = new CronAccessImpl(db, plugin.id, this.cronReschedule);
1788
+ cron = new CronAccessImpl(db, plugin.id, this.cronReschedule, this.now);
1201
1789
  }
1202
1790
 
1203
1791
  // Email access — requires email:send capability AND a configured provider
@@ -1217,14 +1805,18 @@ export class PluginContextFactory {
1217
1805
  },
1218
1806
  storage,
1219
1807
  kv,
1808
+ settings,
1220
1809
  content,
1810
+ schema,
1221
1811
  taxonomies,
1812
+ redirects,
1222
1813
  media,
1223
1814
  http,
1224
1815
  log,
1225
1816
  site: this.site,
1226
1817
  url: this.urlHelper,
1227
1818
  users,
1819
+ comments,
1228
1820
  cron,
1229
1821
  email,
1230
1822
  };