dineway 0.2.32 → 0.2.34

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 (457) hide show
  1. package/dist/{activity-CfryM8jO.mjs → activity-CZnq5YlZ.mjs} +2 -2
  2. package/dist/{activity-events-BVo9rMUz.mjs → activity-events-D-yGV7cW.mjs} +1 -1
  3. package/dist/{actor-DrJJsvy6.mjs → actor-DxUAJgQX.mjs} +20 -6
  4. package/dist/{adapters-DHt3f2lu.d.mts → adapters-BQ8CQbBm.d.mts} +5 -7
  5. package/dist/after-BVaUn7bK.mjs +24 -0
  6. package/dist/{allowed-origins-DtBQa4JR.mjs → allowed-origins-DV3LWuWW.mjs} +1 -1
  7. package/dist/api/route-utils.d.mts +10 -10
  8. package/dist/api/route-utils.mjs +23 -19
  9. package/dist/api/schemas/index.d.mts +1 -1
  10. package/dist/api/schemas/index.mjs +5 -5
  11. package/dist/{api-DF92r_un.mjs → api-CL4pG2zf.mjs} +55 -1215
  12. package/dist/api-tokens-D5K_Csub.mjs +3 -0
  13. package/dist/{api-tokens-CSomx-l3.mjs → api-tokens-_6tMD1W4.mjs} +1 -1
  14. package/dist/{apply-Bs2jXsms.mjs → apply-CYLUMiZg.mjs} +109 -93
  15. package/dist/astro/index.d.mts +16 -12
  16. package/dist/astro/index.mjs +50 -9
  17. package/dist/astro/middleware/auth.d.mts +9 -9
  18. package/dist/astro/middleware/auth.mjs +29 -8
  19. package/dist/astro/middleware/redirect.mjs +8 -7
  20. package/dist/astro/middleware/request-context.mjs +17 -10
  21. package/dist/astro/middleware/seed.d.mts +1 -1
  22. package/dist/astro/middleware/seed.mjs +93 -71
  23. package/dist/astro/middleware/setup.mjs +1 -1
  24. package/dist/astro/middleware/workers.d.mts +6 -0
  25. package/dist/astro/middleware/workers.mjs +8 -0
  26. package/dist/astro/middleware.mjs +288 -159
  27. package/dist/astro/routes/api/admin/allowed-domains/_domain_.mjs +7 -7
  28. package/dist/astro/routes/api/admin/allowed-domains/index.mjs +7 -7
  29. package/dist/astro/routes/api/admin/api-tokens/_id_.mjs +4 -4
  30. package/dist/astro/routes/api/admin/api-tokens/index.mjs +7 -7
  31. package/dist/astro/routes/api/admin/briefing.mjs +25 -23
  32. package/dist/astro/routes/api/admin/byline-fields/_slug_/usage.mjs +5 -4
  33. package/dist/astro/routes/api/admin/byline-fields/_slug_.mjs +11 -10
  34. package/dist/astro/routes/api/admin/byline-fields/index.mjs +11 -10
  35. package/dist/astro/routes/api/admin/byline-fields/reorder.mjs +11 -10
  36. package/dist/astro/routes/api/admin/bylines/_id_/index.mjs +22 -20
  37. package/dist/astro/routes/api/admin/bylines/_id_/translations.mjs +22 -20
  38. package/dist/astro/routes/api/admin/bylines/index.mjs +22 -20
  39. package/dist/astro/routes/api/admin/comments/_id_/status.mjs +17 -16
  40. package/dist/astro/routes/api/admin/comments/_id_.mjs +8 -7
  41. package/dist/astro/routes/api/admin/comments/bulk.mjs +14 -13
  42. package/dist/astro/routes/api/admin/comments/counts.mjs +8 -7
  43. package/dist/astro/routes/api/admin/comments/index.mjs +14 -13
  44. package/dist/astro/routes/api/admin/context/_id_/history.mjs +43 -31
  45. package/dist/astro/routes/api/admin/context/_id_/index.mjs +43 -31
  46. package/dist/astro/routes/api/admin/context/_id_/review.mjs +48 -36
  47. package/dist/astro/routes/api/admin/context/_id_/supersede.mjs +48 -36
  48. package/dist/astro/routes/api/admin/context/diff.mjs +47 -35
  49. package/dist/astro/routes/api/admin/context/index.mjs +48 -36
  50. package/dist/astro/routes/api/admin/context/stale.mjs +47 -35
  51. package/dist/astro/routes/api/admin/hitl-requests/_id_/index.mjs +43 -31
  52. package/dist/astro/routes/api/admin/hitl-requests/_id_/resolve.mjs +47 -35
  53. package/dist/astro/routes/api/admin/hitl-requests/index.mjs +47 -35
  54. package/dist/astro/routes/api/admin/hooks/exclusive/_hookName_.mjs +44 -32
  55. package/dist/astro/routes/api/admin/hooks/exclusive/index.mjs +3 -3
  56. package/dist/astro/routes/api/admin/oauth-clients/_id_.mjs +7 -7
  57. package/dist/astro/routes/api/admin/oauth-clients/index.mjs +7 -7
  58. package/dist/astro/routes/api/admin/plugins/_id_/disable.mjs +72 -66
  59. package/dist/astro/routes/api/admin/plugins/_id_/enable.mjs +72 -66
  60. package/dist/astro/routes/api/admin/plugins/_id_/index.mjs +64 -58
  61. package/dist/astro/routes/api/admin/plugins/_id_/uninstall.mjs +71 -65
  62. package/dist/astro/routes/api/admin/plugins/_id_/update.mjs +71 -65
  63. package/dist/astro/routes/api/admin/plugins/index.mjs +64 -58
  64. package/dist/astro/routes/api/admin/plugins/marketplace/_id_/icon.mjs +2 -2
  65. package/dist/astro/routes/api/admin/plugins/marketplace/_id_/index.mjs +64 -58
  66. package/dist/astro/routes/api/admin/plugins/marketplace/_id_/install.mjs +71 -65
  67. package/dist/astro/routes/api/admin/plugins/marketplace/index.mjs +64 -58
  68. package/dist/astro/routes/api/admin/plugins/updates.mjs +64 -58
  69. package/dist/astro/routes/api/admin/review-requests/_id_/image.mjs +26 -23
  70. package/dist/astro/routes/api/admin/review-requests/_id_/index.mjs +33 -25
  71. package/dist/astro/routes/api/admin/review-requests/_id_/resolve.mjs +56 -43
  72. package/dist/astro/routes/api/admin/review-requests/_id_/revoke.mjs +10 -9
  73. package/dist/astro/routes/api/admin/review-requests/index.mjs +54 -41
  74. package/dist/astro/routes/api/admin/themes/marketplace/_id_/index.mjs +64 -58
  75. package/dist/astro/routes/api/admin/themes/marketplace/_id_/thumbnail.mjs +2 -2
  76. package/dist/astro/routes/api/admin/themes/marketplace/index.mjs +64 -58
  77. package/dist/astro/routes/api/admin/users/_id_/disable.mjs +20 -12
  78. package/dist/astro/routes/api/admin/users/_id_/enable.mjs +1 -1
  79. package/dist/astro/routes/api/admin/users/_id_/index.mjs +40 -32
  80. package/dist/astro/routes/api/admin/users/_id_/send-recovery.mjs +3 -3
  81. package/dist/astro/routes/api/admin/users/index.mjs +7 -7
  82. package/dist/astro/routes/api/auth/dev-bypass.mjs +6 -5
  83. package/dist/astro/routes/api/auth/invite/accept.mjs +1 -1
  84. package/dist/astro/routes/api/auth/invite/complete.mjs +12 -12
  85. package/dist/astro/routes/api/auth/invite/index.mjs +9 -9
  86. package/dist/astro/routes/api/auth/invite/register-options.mjs +11 -11
  87. package/dist/astro/routes/api/auth/logout.mjs +2 -2
  88. package/dist/astro/routes/api/auth/magic-link/send.mjs +12 -11
  89. package/dist/astro/routes/api/auth/magic-link/verify.mjs +2 -2
  90. package/dist/astro/routes/api/auth/me.mjs +11 -11
  91. package/dist/astro/routes/api/auth/mode.mjs +1 -1
  92. package/dist/astro/routes/api/auth/oauth/_provider_/callback.mjs +5 -4
  93. package/dist/astro/routes/api/auth/oauth/_provider_.mjs +5 -4
  94. package/dist/astro/routes/api/auth/passkey/_id_.mjs +7 -7
  95. package/dist/astro/routes/api/auth/passkey/index.mjs +1 -1
  96. package/dist/astro/routes/api/auth/passkey/options.mjs +14 -13
  97. package/dist/astro/routes/api/auth/passkey/register/options.mjs +11 -11
  98. package/dist/astro/routes/api/auth/passkey/register/verify.mjs +12 -12
  99. package/dist/astro/routes/api/auth/passkey/verify.mjs +12 -12
  100. package/dist/astro/routes/api/auth/setup-token/index.mjs +32 -23
  101. package/dist/astro/routes/api/auth/setup-token/verify.mjs +32 -26
  102. package/dist/astro/routes/api/auth/signup/complete.mjs +12 -12
  103. package/dist/astro/routes/api/auth/signup/request.mjs +12 -11
  104. package/dist/astro/routes/api/auth/signup/verify.mjs +1 -1
  105. package/dist/astro/routes/api/comments/_collection_/_contentId_/index.mjs +21 -18
  106. package/dist/astro/routes/api/comments/_collection_/_contentId_/reactions.mjs +19 -16
  107. package/dist/astro/routes/api/content/_collection_/_id_/compare.mjs +2 -2
  108. package/dist/astro/routes/api/content/_collection_/_id_/discard-draft.mjs +8 -7
  109. package/dist/astro/routes/api/content/_collection_/_id_/duplicate.mjs +8 -7
  110. package/dist/astro/routes/api/content/_collection_/_id_/permanent.mjs +8 -7
  111. package/dist/astro/routes/api/content/_collection_/_id_/preview-url.mjs +24 -21
  112. package/dist/astro/routes/api/content/_collection_/_id_/publish.mjs +35 -22
  113. package/dist/astro/routes/api/content/_collection_/_id_/release-readiness.mjs +9 -9
  114. package/dist/astro/routes/api/content/_collection_/_id_/restore.mjs +8 -7
  115. package/dist/astro/routes/api/content/_collection_/_id_/revisions.mjs +2 -2
  116. package/dist/astro/routes/api/content/_collection_/_id_/schedule.mjs +35 -22
  117. package/dist/astro/routes/api/content/_collection_/_id_/terms/_taxonomy_.mjs +23 -19
  118. package/dist/astro/routes/api/content/_collection_/_id_/translations.mjs +2 -2
  119. package/dist/astro/routes/api/content/_collection_/_id_/unpublish.mjs +8 -7
  120. package/dist/astro/routes/api/content/_collection_/_id_.mjs +14 -13
  121. package/dist/astro/routes/api/content/_collection_/authors.mjs +2 -2
  122. package/dist/astro/routes/api/content/_collection_/index.mjs +14 -13
  123. package/dist/astro/routes/api/content/_collection_/trash.mjs +8 -8
  124. package/dist/astro/routes/api/dashboard.mjs +16 -11
  125. package/dist/astro/routes/api/dev/emails.mjs +2 -2
  126. package/dist/astro/routes/api/health.mjs +1 -1
  127. package/dist/astro/routes/api/import/probe.d.mts +3 -3
  128. package/dist/astro/routes/api/import/probe.mjs +25 -24
  129. package/dist/astro/routes/api/import/wordpress/analyze.mjs +12 -11
  130. package/dist/astro/routes/api/import/wordpress/execute.d.mts +9 -9
  131. package/dist/astro/routes/api/import/wordpress/execute.mjs +51 -42
  132. package/dist/astro/routes/api/import/wordpress/media.d.mts +9 -9
  133. package/dist/astro/routes/api/import/wordpress/media.mjs +14 -14
  134. package/dist/astro/routes/api/import/wordpress/prepare.mjs +52 -40
  135. package/dist/astro/routes/api/import/wordpress/rewrite-urls.d.mts +10 -10
  136. package/dist/astro/routes/api/import/wordpress/rewrite-urls.mjs +50 -38
  137. package/dist/astro/routes/api/import/wordpress-plugin/analyze.d.mts +1 -1
  138. package/dist/astro/routes/api/import/wordpress-plugin/analyze.mjs +29 -27
  139. package/dist/astro/routes/api/import/wordpress-plugin/callback.mjs +1 -1
  140. package/dist/astro/routes/api/import/wordpress-plugin/execute.d.mts +9 -9
  141. package/dist/astro/routes/api/import/wordpress-plugin/execute.mjs +56 -47
  142. package/dist/astro/routes/api/integration/artifact.mjs +11 -8
  143. package/dist/astro/routes/api/integration/dispatch.mjs +17 -14
  144. package/dist/astro/routes/api/integrations/_provider_.mjs +11 -8
  145. package/dist/astro/routes/api/integrations/index.mjs +10 -7
  146. package/dist/astro/routes/api/manifest.mjs +5 -5
  147. package/dist/astro/routes/api/mcp.mjs +98 -88
  148. package/dist/astro/routes/api/media/_id_/confirm.mjs +12 -12
  149. package/dist/astro/routes/api/media/_id_.mjs +9 -9
  150. package/dist/astro/routes/api/media/file/_...key_.mjs +1 -1
  151. package/dist/astro/routes/api/media/providers/_providerId_/_itemId_.mjs +2 -2
  152. package/dist/astro/routes/api/media/providers/_providerId_/index.mjs +2 -2
  153. package/dist/astro/routes/api/media/providers/index.mjs +2 -2
  154. package/dist/astro/routes/api/media/upload-url.mjs +13 -13
  155. package/dist/astro/routes/api/media.mjs +16 -16
  156. package/dist/astro/routes/api/menus/_name_/items/_id_.mjs +48 -36
  157. package/dist/astro/routes/api/menus/_name_/items.mjs +48 -36
  158. package/dist/astro/routes/api/menus/_name_/reorder.mjs +48 -36
  159. package/dist/astro/routes/api/menus/_name_/translations.mjs +48 -36
  160. package/dist/astro/routes/api/menus/_name_.mjs +48 -36
  161. package/dist/astro/routes/api/menus/index.mjs +48 -36
  162. package/dist/astro/routes/api/oauth/authorize.mjs +9 -7
  163. package/dist/astro/routes/api/oauth/device/authorize.mjs +7 -6
  164. package/dist/astro/routes/api/oauth/device/code.mjs +11 -9
  165. package/dist/astro/routes/api/oauth/device/token.mjs +10 -8
  166. package/dist/astro/routes/api/oauth/register.mjs +4 -4
  167. package/dist/astro/routes/api/oauth/token/refresh.mjs +7 -6
  168. package/dist/astro/routes/api/oauth/token/revoke.mjs +7 -6
  169. package/dist/astro/routes/api/oauth/token.mjs +8 -6
  170. package/dist/astro/routes/api/openapi.json.mjs +5 -5
  171. package/dist/astro/routes/api/plugins/_pluginId_/_...path_.mjs +4 -4
  172. package/dist/astro/routes/api/redirects/404s/index.mjs +15 -14
  173. package/dist/astro/routes/api/redirects/404s/summary.mjs +15 -14
  174. package/dist/astro/routes/api/redirects/_id_.mjs +48 -37
  175. package/dist/astro/routes/api/redirects/index.mjs +48 -37
  176. package/dist/astro/routes/api/revisions/_revisionId_/index.mjs +2 -2
  177. package/dist/astro/routes/api/revisions/_revisionId_/restore.mjs +2 -2
  178. package/dist/astro/routes/api/schema/collections/_slug_/fields/_fieldSlug_.mjs +66 -60
  179. package/dist/astro/routes/api/schema/collections/_slug_/fields/index.mjs +66 -60
  180. package/dist/astro/routes/api/schema/collections/_slug_/fields/reorder.mjs +66 -60
  181. package/dist/astro/routes/api/schema/collections/_slug_/index.mjs +66 -60
  182. package/dist/astro/routes/api/schema/collections/index.mjs +66 -60
  183. package/dist/astro/routes/api/schema/index.mjs +12 -11
  184. package/dist/astro/routes/api/schema/orphans/_slug_.mjs +64 -58
  185. package/dist/astro/routes/api/schema/orphans/index.mjs +64 -58
  186. package/dist/astro/routes/api/search/enable.mjs +15 -14
  187. package/dist/astro/routes/api/search/index.mjs +14 -13
  188. package/dist/astro/routes/api/search/rebuild.mjs +15 -14
  189. package/dist/astro/routes/api/search/stats.mjs +9 -8
  190. package/dist/astro/routes/api/search/suggest.mjs +14 -13
  191. package/dist/astro/routes/api/sections/_slug_.mjs +48 -36
  192. package/dist/astro/routes/api/sections/index.mjs +48 -36
  193. package/dist/astro/routes/api/settings/email.mjs +5 -5
  194. package/dist/astro/routes/api/settings/reviews.mjs +11 -10
  195. package/dist/astro/routes/api/settings.mjs +48 -36
  196. package/dist/astro/routes/api/setup/admin-verify.mjs +14 -14
  197. package/dist/astro/routes/api/setup/admin.mjs +12 -12
  198. package/dist/astro/routes/api/setup/dev-bypass.mjs +35 -31
  199. package/dist/astro/routes/api/setup/dev-reset.mjs +2 -2
  200. package/dist/astro/routes/api/setup/index.mjs +37 -33
  201. package/dist/astro/routes/api/setup/status.mjs +3 -3
  202. package/dist/astro/routes/api/snapshot.mjs +11 -9
  203. package/dist/astro/routes/api/system/heartbeat.mjs +2 -2
  204. package/dist/astro/routes/api/taxonomies/_name_/terms/_slug_/translations.mjs +51 -39
  205. package/dist/astro/routes/api/taxonomies/_name_/terms/_slug_.mjs +51 -39
  206. package/dist/astro/routes/api/taxonomies/_name_/terms/index.mjs +51 -39
  207. package/dist/astro/routes/api/taxonomies/index.mjs +51 -39
  208. package/dist/astro/routes/api/themes/preview.mjs +8 -6
  209. package/dist/astro/routes/api/typegen.mjs +4 -4
  210. package/dist/astro/routes/api/well-known/auth.mjs +3 -3
  211. package/dist/astro/routes/api/well-known/oauth-authorization-server.mjs +3 -3
  212. package/dist/astro/routes/api/well-known/oauth-protected-resource.mjs +3 -3
  213. package/dist/astro/routes/api/widget-areas/_name_/reorder.mjs +47 -35
  214. package/dist/astro/routes/api/widget-areas/_name_/widgets/_id_.mjs +48 -36
  215. package/dist/astro/routes/api/widget-areas/_name_/widgets.mjs +48 -36
  216. package/dist/astro/routes/api/widget-areas/_name_.mjs +45 -33
  217. package/dist/astro/routes/api/widget-areas/index.mjs +48 -36
  218. package/dist/astro/routes/api/widget-components.mjs +2 -2
  219. package/dist/astro/routes/robots.txt.mjs +11 -10
  220. package/dist/astro/routes/sitemap-_collection_.xml.mjs +20 -18
  221. package/dist/astro/routes/sitemap.xml.mjs +19 -17
  222. package/dist/astro/session-driver.d.mts +1 -1
  223. package/dist/astro/session-driver.mjs +4 -4
  224. package/dist/astro/types.d.mts +13 -13
  225. package/dist/atomic-authority-CnBQJ14T.mjs +33 -0
  226. package/dist/{audit-CYjfxG9i.mjs → audit-F5iWkbcJ.mjs} +11 -4
  227. package/dist/auth/providers/github.d.mts +1 -1
  228. package/dist/auth/providers/google.d.mts +1 -1
  229. package/dist/{auth-control-guard-CITT8ZA_.mjs → auth-control-guard-D4WW-wFF.mjs} +1 -1
  230. package/dist/{authorize-KcI0pAfN.mjs → authorize-EnP57AQl.mjs} +1 -1
  231. package/dist/{briefing-r3hXCDQC.mjs → briefing-BXsVwd4P.mjs} +1 -1
  232. package/dist/{briefing-BgQTljQt.mjs → briefing-CkCi6S-W.mjs} +445 -447
  233. package/dist/{bundle-S6zx-V4D.mjs → bundle-Cgak1zGE.mjs} +3 -3
  234. package/dist/{byline-Ctil4rij.mjs → byline-DEZKlzD9.mjs} +107 -113
  235. package/dist/{byline-fields-QpmruT5r.mjs → byline-fields-BGEIA9dZ.mjs} +3 -3
  236. package/dist/{byline-fields-DNXKWUW9.d.mts → byline-fields-BmkhEDFF.d.mts} +2 -2
  237. package/dist/{byline-fields-DiCyW6eQ.mjs → byline-fields-Qg8TesxL.mjs} +1 -1
  238. package/dist/{byline-registry-rkr73qSE.mjs → byline-registry-CkuVVeJJ.mjs} +46 -76
  239. package/dist/{bylines-BcuBpzVi.mjs → bylines-7BQxRGyG.mjs} +4 -4
  240. package/dist/{bylines-v_ZUQnR-.mjs → bylines-LqNRjma2.mjs} +6 -6
  241. package/dist/{cache-V2BCplaY.mjs → cache-CSTy-R-K.mjs} +2 -2
  242. package/dist/{chunks-CnuL55JE.mjs → chunks-BnG3LPMN.mjs} +1 -1
  243. package/dist/cli/index.mjs +452 -263
  244. package/dist/cli/plugin-kit.d.mts +9 -9
  245. package/dist/cli/plugin-kit.mjs +2 -2
  246. package/dist/client/external-auth-headers.d.mts +1 -1
  247. package/dist/client/index.d.mts +11 -11
  248. package/dist/client/index.mjs +2 -2
  249. package/dist/{client-factory-C-y9VZDX.mjs → client-factory-BLSkgsTg.mjs} +1 -1
  250. package/dist/{comment-_nvJSS-A.mjs → comment-Bi7cJ9SS.mjs} +2 -2
  251. package/dist/{comment-reaction-DhVgJ17S.mjs → comment-reaction-BLqIj5mx.mjs} +1 -1
  252. package/dist/{comments-D4mIDjvA.mjs → comments-Dg_gWBEB.mjs} +1 -1
  253. package/dist/content-De_XeXy_.mjs +1230 -0
  254. package/dist/{content-CVCrcuvD.mjs → content-NobcQti0.mjs} +240 -161
  255. package/dist/{content-refresh-QvBIyb_g.mjs → content-refresh-l4mPoGeX.mjs} +170 -193
  256. package/dist/{context-MftkHbWx.mjs → context-6uqzU-M9.mjs} +95 -77
  257. package/dist/{context-JjKucxBm.mjs → context-B0SG9Xkc.mjs} +2 -2
  258. package/dist/{context-route-helpers-e1APrqSm.mjs → context-route-helpers-C8s26uDT.mjs} +2 -2
  259. package/dist/{cron-mGVPQ5e6.mjs → cron-D7zB6m8i.mjs} +36 -32
  260. package/dist/d1-binding-D6HZa3ks.mjs +8 -0
  261. package/dist/d1-dialect-B1b8cmxX.mjs +48 -0
  262. package/dist/{dashboard-ZJ7sMcBI.mjs → dashboard-B-OybCMw.mjs} +5 -5
  263. package/dist/database/batch.d.mts +20 -0
  264. package/dist/database/batch.mjs +69 -0
  265. package/dist/database/d1/index.d.mts +18 -0
  266. package/dist/database/d1/index.mjs +8 -0
  267. package/dist/db/d1.d.mts +7 -0
  268. package/dist/db/d1.mjs +13 -0
  269. package/dist/db/index.d.mts +4 -4
  270. package/dist/db/index.mjs +10 -7
  271. package/dist/db/libsql.d.mts +1 -1
  272. package/dist/db/libsql.mjs +46 -3
  273. package/dist/db/postgres.d.mts +1 -1
  274. package/dist/db/sqlite.d.mts +1 -1
  275. package/dist/{device-flow-eOcL5m0Q.mjs → device-flow-DhpCzMo0.mjs} +130 -94
  276. package/dist/{dialect-helpers-fk43GbDb.mjs → dialect-helpers-C6xtO-Ui.mjs} +1 -1
  277. package/dist/{discovery-CJkuHGhZ.mjs → discovery-CqXbN0WZ.mjs} +5 -5
  278. package/dist/{enrich-KErvJOuI.mjs → enrich-BjF-J4sF.mjs} +1 -1
  279. package/dist/{evidence-6IUv9ML3.mjs → evidence-xJf8hQgH.mjs} +7 -7
  280. package/dist/{field-defs-cache-CwrIyZFT.mjs → field-defs-cache-BKKFFf_V.mjs} +5 -5
  281. package/dist/{forgeway-account-lYJ8iX3G.mjs → forgeway-account-BeKJlKh1.mjs} +1 -1
  282. package/dist/{fts-manager-DX7ZkrCa.mjs → fts-manager-BeWtB7ZD.mjs} +72 -57
  283. package/dist/{hitl-requests-CmYVunm-.mjs → hitl-requests-evSsel48.mjs} +2 -2
  284. package/dist/{hitl-route-helpers-CRm537zS.mjs → hitl-route-helpers-D2kJSOFX.mjs} +5 -5
  285. package/dist/{import-DqRAgsKr.mjs → import-Jpta-CYE.mjs} +9 -9
  286. package/dist/{index-Co7xtjkd.d.mts → index-CSUSBfdD.d.mts} +7 -4
  287. package/dist/index.d.mts +16 -16
  288. package/dist/index.mjs +104 -96
  289. package/dist/{integration-credentials-qudN6yRr.mjs → integration-credentials-BrQr0fb_.mjs} +2 -2
  290. package/dist/{jsonld-DTd-AVWg.d.mts → jsonld-CqIVIeZK.d.mts} +2 -2
  291. package/dist/{load-fCOciq0Q.mjs → load-Dc5ttyg4.mjs} +1 -1
  292. package/dist/{loader-BDje8ME2.mjs → loader-Cgsx23wU.mjs} +4 -4
  293. package/dist/{manifest-schema-CfKD0thC.mjs → manifest-schema-DG29meRy.mjs} +1 -1
  294. package/dist/{mcp-reviewed-executor-DmhM3Cy6.mjs → mcp-reviewed-executor-DAZL3Ckt.mjs} +7 -7
  295. package/dist/media/image-endpoint.mjs +1 -1
  296. package/dist/media/index.d.mts +1 -1
  297. package/dist/media/index.mjs +2 -2
  298. package/dist/media/local-runtime.d.mts +11 -11
  299. package/dist/media/local-runtime.mjs +3 -3
  300. package/dist/{media-dvRjj4po.mjs → media-3fK0u-bo.mjs} +1 -1
  301. package/dist/{media-allowlist-DaG6lNoy.mjs → media-allowlist-rN4qIF6W.mjs} +1 -1
  302. package/dist/{menus-CpuR4Qkm.mjs → menus-5liJusbp.mjs} +138 -90
  303. package/dist/{menus-CZbz5L_V.mjs → menus-CbR_J8cJ.mjs} +8 -8
  304. package/dist/migrations-CMdxWKx-.mjs +76 -0
  305. package/dist/oauth-authority-CCqo4eBm.mjs +43 -0
  306. package/dist/{oauth-authorization-Jf5e3azH.mjs → oauth-authorization--0UtTZpv.mjs} +89 -98
  307. package/dist/{oauth-clients-tovQ4D4h.mjs → oauth-clients-D4WBYaYW.mjs} +2 -2
  308. package/dist/object-cache/memory.d.mts +1 -1
  309. package/dist/{object-cache-D51qOseS.mjs → object-cache-BGjIlY9s.mjs} +1 -1
  310. package/dist/page/index.d.mts +10 -10
  311. package/dist/page/index.mjs +1 -1
  312. package/dist/{parse-IsGn-5lt.mjs → parse--7nG62_h.mjs} +1 -1
  313. package/dist/plugin-utils.d.mts +9 -9
  314. package/dist/plugins/adapt-sandbox-entry.d.mts +9 -9
  315. package/dist/plugins/adapt-sandbox-entry.mjs +1 -1
  316. package/dist/{plugins-DXyLI3Hb.mjs → plugins-DK1wLuao.mjs} +35 -84
  317. package/dist/{policy-950odoX_.mjs → policy-Dej7NJFD.mjs} +2 -2
  318. package/dist/{preview-BXmS1SXL.mjs → preview-q0pkibNO.mjs} +2 -2
  319. package/dist/{provider-loader-DDq7R_RN.d.mts → provider-loader-C0GaLwKB.d.mts} +1 -1
  320. package/dist/{public-url-CT-T1D_w.d.mts → public-url-B9zEdO8p.d.mts} +1 -1
  321. package/dist/{public-url-BQ9vf0AS.d.mts → public-url-BV-YQ_LF.d.mts} +2 -2
  322. package/dist/{publication-authorization-C-vYPGD8.mjs → publication-authorization-BrEZ2TsE.mjs} +459 -33
  323. package/dist/{query-CrW2yI6G.mjs → query-CEn9HXnf.mjs} +15 -15
  324. package/dist/{query-DcB9uGTW.mjs → query-DAS6VbMS.mjs} +4 -4
  325. package/dist/{rate-limit-DEkoxTsP.mjs → rate-limit-Dd1TnzZP.mjs} +2 -2
  326. package/dist/{redirect-DG-o0CKV.mjs → redirect-HLI3wT5Y.mjs} +26 -14
  327. package/dist/{redirects-Bjp4iKJU.mjs → redirects-DmOdfRjI.mjs} +5 -5
  328. package/dist/{redirects-N8gmWhVM.mjs → redirects-UCXyL0lP.mjs} +3 -3
  329. package/dist/{registry-D-IV_h50.mjs → registry-RD9qTnYL.mjs} +183 -186
  330. package/dist/release-BR08Slqf.mjs +5148 -0
  331. package/dist/request-context.d.mts +8 -0
  332. package/dist/{request-meta-BW0the1R.mjs → request-meta-BOcuHAXD.mjs} +1 -1
  333. package/dist/{resolve-pZ4NQM-X.mjs → resolve-C80Pm2DW.mjs} +1 -1
  334. package/dist/{review-payload-f1L4lzQg.mjs → review-payload-DEylbssM.mjs} +52 -4
  335. package/dist/{review-requests-DICrYH2-.mjs → review-requests-BF2eEKr8.mjs} +93 -37
  336. package/dist/{review-requests-BTKfeWlS.mjs → review-requests-CyfWbJ6W.mjs} +2 -2
  337. package/dist/{review-route-helpers-DaZBBps8.mjs → review-route-helpers-lKA-CXms.mjs} +2 -2
  338. package/dist/{revision-De7OmYVD.mjs → revision-090sZyGc.mjs} +28 -22
  339. package/dist/revocation-B7GL5fMl.mjs +53 -0
  340. package/dist/{runner-DJiRFyLI.mjs → runner-CVeq0266.mjs} +594 -491
  341. package/dist/{runner-Dye73myO.d.mts → runner-JnJSGXEB.d.mts} +1 -1
  342. package/dist/{runs-DEujUDOj.mjs → runs-B5BExdKO.mjs} +5 -5
  343. package/dist/runtime-env-CQVAWHzH.mjs +19 -0
  344. package/dist/runtime.d.mts +10 -10
  345. package/dist/runtime.mjs +5 -5
  346. package/dist/schema-DLMkODQc.mjs +8 -0
  347. package/dist/{search-DxUKN9Zz.mjs → search-CRzWNfxX.mjs} +4 -4
  348. package/dist/{secrets-AdCrGg1c.mjs → secrets-Cg0D2gQW.mjs} +10 -11
  349. package/dist/{sections-BPFOEMK6.mjs → sections-BwUjOGqn.mjs} +2 -2
  350. package/dist/seed/index.d.mts +2 -2
  351. package/dist/seed/index.mjs +29 -25
  352. package/dist/seo/index.d.mts +3 -3
  353. package/dist/seo/index.mjs +11 -10
  354. package/dist/{seo-DWHdo5aW.mjs → seo-BOTuCeh-.mjs} +25 -15
  355. package/dist/{seo-GfovzqpU.mjs → seo-B_tBFyud.mjs} +1 -1
  356. package/dist/{service-DbgjHWyW.mjs → service--bQht6oN.mjs} +2 -2
  357. package/dist/{service-BrNKVCjC.mjs → service-DilVsWGD.mjs} +3 -3
  358. package/dist/{session-user-DyqWGIh4.mjs → session-user-DeqTcAmR.mjs} +1 -1
  359. package/dist/{settings-CAsQLi0N.mjs → settings-DFzevIrU.mjs} +8 -8
  360. package/dist/{settings-BKEHw6Bu.mjs → settings-Deqx3Upy.mjs} +2 -2
  361. package/dist/{setup-complete-C8LTo8cO.mjs → setup-complete-BFqudwbW.mjs} +1 -1
  362. package/dist/{site-activity-7oezuHXK.mjs → site-activity-BrN2NviL.mjs} +11 -4
  363. package/dist/{site-context-CA7rbxux.mjs → site-context-vCiDRr4H.mjs} +50 -37
  364. package/dist/{site-url-DoZf_jVj.mjs → site-url-wXFqbm9c.mjs} +1 -1
  365. package/dist/state-jyNZ6-7L.mjs +30 -0
  366. package/dist/storage/local.d.mts +1 -1
  367. package/dist/storage/local.mjs +1 -1
  368. package/dist/storage/s3.d.mts +1 -1
  369. package/dist/storage/s3.mjs +3 -3
  370. package/dist/{store-c4qx3gVh.mjs → store-C1yDxxfv.mjs} +37 -12
  371. package/dist/submission-BsHNfHc7.mjs +155 -0
  372. package/dist/{taxonomies-ALDiRQ84.mjs → taxonomies-4cnTcbD6.mjs} +3 -3
  373. package/dist/{taxonomies-93DV-1QT.mjs → taxonomies-CllxqaH0.mjs} +7 -7
  374. package/dist/{taxonomy-BOBTJ_aE.mjs → taxonomy-DWxxLpp5.mjs} +3 -3
  375. package/dist/{tokens-c-qxNqzC.mjs → tokens-Bjuf1HID.mjs} +1 -1
  376. package/dist/{trusted-proxy-CdEl6g6B.mjs → trusted-proxy-CAW9o4Dw.mjs} +4 -12
  377. package/dist/{types-BRCUO8NR.d.mts → types-7Th6Mwz3.d.mts} +1 -0
  378. package/dist/{types-BpSTdH1H.mjs → types-BqxIv8Il.mjs} +2 -2
  379. package/dist/{types-6KmeXInJ.d.mts → types-CFgTpfPk.d.mts} +1 -1
  380. package/dist/{types-TpXK8km5.d.mts → types-QjOcidFc.d.mts} +300 -172
  381. package/dist/ui/server-runtime.d.mts +13 -13
  382. package/dist/ui/server-runtime.mjs +28 -26
  383. package/dist/{user-D0NJ7gYf.mjs → user-1-YV30lf.mjs} +2 -2
  384. package/dist/{utils-BK2efsHv.mjs → utils-Cglcqpm2.mjs} +2 -2
  385. package/dist/{validate-CDWVODvc.d.mts → validate-A27peRc4.d.mts} +3 -3
  386. package/dist/{validate-C9g9iX3q.mjs → validate-Wl4MSf3V.mjs} +3 -3
  387. package/dist/version-BWxyC5s4.mjs +6 -0
  388. package/dist/{widgets-Cm5Qx2Np.mjs → widgets-Di-6yDH7.mjs} +3 -3
  389. package/dist/{wordpress-slugs-WdPZaVXf.mjs → wordpress-slugs-vOx7R1dM.mjs} +1 -1
  390. package/dist/{worker-D7OccgB8.mjs → worker-RpaMP71d.mjs} +76 -47
  391. package/dist/workers-build-BaQCrSmf.mjs +36 -0
  392. package/dist/{zod-generator-DS5oZNaL.mjs → zod-generator-Cylvl_SM.mjs} +2 -2
  393. package/package.json +35 -9
  394. package/dist/after-BfniwgIf.mjs +0 -9
  395. package/dist/api-tokens-CmT83Bgj.mjs +0 -3
  396. package/dist/db/libsql-http.d.mts +0 -27
  397. package/dist/db/libsql-http.mjs +0 -29
  398. package/dist/libsql-dialect-CANq6UNI.mjs +0 -47
  399. package/dist/oauth-user-lookup-B451pZmd.mjs +0 -25
  400. package/dist/revocation-CkTOhdlw.mjs +0 -42
  401. package/dist/schema-IjuRxkqq.mjs +0 -8
  402. package/dist/submission-C47cHBIg.mjs +0 -67
  403. package/dist/transaction-BGQgnwUi.mjs +0 -28
  404. package/dist/version-9orir5LL.mjs +0 -6
  405. /package/dist/{base64-F8-DUraK.mjs → base64-Cz-aU0X1.mjs} +0 -0
  406. /package/dist/{challenge-store-CYrg4F4t.mjs → challenge-store-D-_-VavY.mjs} +0 -0
  407. /package/dist/{components-DAq_4iPX.mjs → components-BWQUCJEr.mjs} +0 -0
  408. /package/dist/{config-CVssduLe.mjs → config-XW5tMrH8.mjs} +0 -0
  409. /package/dist/{content-index-names-Bbu1FY1r.mjs → content-index-names-CDc2IQIx.mjs} +0 -0
  410. /package/dist/{context-types-CPWAJRs5.mjs → context-types-DqTo6C79.mjs} +0 -0
  411. /package/dist/{default-BeIzUa1e.mjs → default-D9zxuUU7.mjs} +0 -0
  412. /package/dist/{email-console-Bfi_exVg.mjs → email-console-BONByQiC.mjs} +0 -0
  413. /package/dist/{error-DLg1H2LT.mjs → error-Dd8LtpG5.mjs} +0 -0
  414. /package/dist/{escape-C6lkys0j.mjs → escape-BWC4s5bV.mjs} +0 -0
  415. /package/dist/{experimental-workflows-B9x8delL.mjs → experimental-workflows-M5D3RTFo.mjs} +0 -0
  416. /package/dist/{hash-jhbF98tT.mjs → hash-lNx3KJis.mjs} +0 -0
  417. /package/dist/{media-url-CL3NzgLh.mjs → media-url-B4YtTY6c.mjs} +0 -0
  418. /package/dist/{mime-CDTtL7jE.mjs → mime-D_ae-u_U.mjs} +0 -0
  419. /package/dist/{mode-D554vAgH.mjs → mode-CPf_KZ37.mjs} +0 -0
  420. /package/dist/{normalize-Ev3FiBMx.mjs → normalize-5rct_U0I.mjs} +0 -0
  421. /package/dist/{oauth-state-store-Do1a_o3H.mjs → oauth-state-store-CMgcimzA.mjs} +0 -0
  422. /package/dist/{options-1dBRkoCl.mjs → options-BcqHWpc-.mjs} +0 -0
  423. /package/dist/{output-8j9oltTf.mjs → output-BYpiVUBf.mjs} +0 -0
  424. /package/dist/{parser-C9rzPuSZ.mjs → parser-BV0wzQHo.mjs} +0 -0
  425. /package/dist/{passkey-config-CRN44T04.mjs → passkey-config-BG4GO4OO.mjs} +0 -0
  426. /package/dist/{patterns-3XE9bU4r.mjs → patterns-CZ7D4y_R.mjs} +0 -0
  427. /package/dist/{placeholder-D03pGvqM.d.mts → placeholder-BHTaoCYx.d.mts} +0 -0
  428. /package/dist/{portable-text-tIk9_uz_.mjs → portable-text-B9YuySom.mjs} +0 -0
  429. /package/dist/{portable-text-BdRm4uZq.d.mts → portable-text-FKf3IrPz.d.mts} +0 -0
  430. /package/dist/{process-cache-B-L-A9zg.mjs → process-cache-MHM4Sqzs.mjs} +0 -0
  431. /package/dist/{provider-loader-C4i82ll1.mjs → provider-loader-3MY1SjzA.mjs} +0 -0
  432. /package/dist/{public-discovery-CyDzK1-S.mjs → public-discovery-BAbOvKiR.mjs} +0 -0
  433. /package/dist/{public-url-oudwI7K0.mjs → public-url-C7pbmS_7.mjs} +0 -0
  434. /package/dist/{public-url-BVIjzMo3.mjs → public-url-D5Wjq0sy.mjs} +0 -0
  435. /package/dist/{redirect-Dp5u-8dH.mjs → redirect-Bx96u2nS.mjs} +0 -0
  436. /package/dist/{request-cache-BruBnFAR.mjs → request-cache-DPmV5nk4.mjs} +0 -0
  437. /package/dist/{seo-contributions-BAtRDXEQ.mjs → seo-contributions-Dt57p6Sq.mjs} +0 -0
  438. /package/dist/{service-DeX1PRNt.mjs → service-wYQ_ePZ4.mjs} +0 -0
  439. /package/dist/{setup-nonce-D-CEYlw7.mjs → setup-nonce-CAqDUxxU.mjs} +0 -0
  440. /package/dist/{sidecar-client-Bw2C0XTf.mjs → sidecar-client-CnpGTvYq.mjs} +0 -0
  441. /package/dist/{slugify-KSsVD_D3.mjs → slugify-Di8Q_MFq.mjs} +0 -0
  442. /package/dist/{ssrf-C7tTSD1r.mjs → ssrf-LN16WMip.mjs} +0 -0
  443. /package/dist/{stable-hash-DF7R5eN8.mjs → stable-hash-DEtJgcp7.mjs} +0 -0
  444. /package/dist/{status-Bba6RbkS.mjs → status-Bwkeuz8g.mjs} +0 -0
  445. /package/dist/{transport-BddGhTAI.mjs → transport-472KVGBe.mjs} +0 -0
  446. /package/dist/{transport-ktLL9r2O.d.mts → transport-C0jj-Nc8.d.mts} +0 -0
  447. /package/dist/{types-BQZFeZjd.mjs → types-BDq9t5lG.mjs} +0 -0
  448. /package/dist/{types-CKIt_jmM.d.mts → types-Bs-7Geuh.d.mts} +0 -0
  449. /package/dist/{types-CLMOusxP.d.mts → types-CwkJp6zr.d.mts} +0 -0
  450. /package/dist/{types-C0DPvhR5.mjs → types-CyBH89BS.mjs} +0 -0
  451. /package/dist/{types-BbkkkAb6.mjs → types-D17dJRht.mjs} +0 -0
  452. /package/dist/{types--3oJQ0hs.d.mts → types-DTjrkhKU.d.mts} +0 -0
  453. /package/dist/{types-CPaVj_GC.d.mts → types-DkXuBo8k.d.mts} +0 -0
  454. /package/dist/{types-CU3Wn2HC.d.mts → types-b2sq7ZDk.d.mts} +0 -0
  455. /package/dist/{url-C_pLSrGZ.mjs → url-D375-6LM.mjs} +0 -0
  456. /package/dist/{url-Dumsft7G.mjs → url-bv5i4JN0.mjs} +0 -0
  457. /package/dist/{validate-VPnKoIzW.mjs → validate-Co3j6T_K.mjs} +0 -0
@@ -1,39 +1,61 @@
1
- import { i as encodeCursor, r as decodeCursor } from "./types-BpSTdH1H.mjs";
2
- import { t as SiteActivityRepository } from "./site-activity-7oezuHXK.mjs";
3
- import { n as stableStringify } from "./stable-hash-DF7R5eN8.mjs";
4
- import { n as ReviewRequestRepository } from "./review-requests-DICrYH2-.mjs";
5
- import { a as getSiteSettingsWithDb } from "./settings-CAsQLi0N.mjs";
6
- import { n as buildStableActionHash, t as ReviewPayloadBuilder } from "./review-payload-f1L4lzQg.mjs";
7
- import { t as SYSTEM_ACTOR_ID } from "./actor-DrJJsvy6.mjs";
8
- import { n as redactActivityRecord } from "./activity-CfryM8jO.mjs";
1
+ import { AtomicWriteConflict, atomicBatch, isD1Database, rowUnchanged } from "./database/batch.mjs";
2
+ import { r as currentIsoTimestampValue } from "./dialect-helpers-C6xtO-Ui.mjs";
3
+ import { i as encodeCursor, r as decodeCursor } from "./types-BqxIv8Il.mjs";
4
+ import { r as getOAuthTokenHash, t as SYSTEM_ACTOR_ID } from "./actor-DxUAJgQX.mjs";
5
+ import { o as invalidateCollectionCache } from "./object-cache-BGjIlY9s.mjs";
6
+ import { t as ContentRepository } from "./content-NobcQti0.mjs";
7
+ import { t as SiteActivityRepository } from "./site-activity-BrN2NviL.mjs";
8
+ import { n as stableStringify } from "./stable-hash-DEtJgcp7.mjs";
9
+ import { r as ReviewRequestRepository } from "./review-requests-BF2eEKr8.mjs";
10
+ import { n as buildStableActionHash, t as ReviewPayloadBuilder } from "./review-payload-DEylbssM.mjs";
11
+ import { a as getSiteSettingsWithDb } from "./settings-DFzevIrU.mjs";
12
+ import { i as invalidateRedirectCache } from "./cache-CSTy-R-K.mjs";
13
+ import { x as prepareContentPublication } from "./content-De_XeXy_.mjs";
14
+ import { n as redactActivityRecord } from "./activity-CZnq5YlZ.mjs";
15
+ import { sql } from "kysely";
9
16
  import { ulid } from "ulidx";
17
+ import { canActOnOwn, hasPermission, hasScope, toRoleLevel } from "@dineway-ai/auth";
18
+ import { z } from "zod";
10
19
 
11
20
  //#region src/database/repositories/content-release-grants.ts
12
21
  var ContentReleaseGrantRepository = class {
13
22
  constructor(db) {
14
23
  this.db = db;
15
24
  }
16
- async createOrReplaceActive(input) {
17
- const operation = async (transaction) => {
18
- const existing = await findActiveForTarget(transaction, input.collection, input.entryId, input.operation);
19
- if (existing?.actionHash === input.actionHash) return existing;
20
- const now = input.createdAt ?? (/* @__PURE__ */ new Date()).toISOString();
21
- if (existing) {
22
- const revoked = await transaction.updateTable("_dineway_content_release_grants").set({
23
- status: "revoked",
24
- updated_at: now,
25
- revoked_at: now,
26
- revocation_reason: "replaced"
27
- }).where("id", "=", existing.id).where("status", "=", "active").executeTakeFirst();
28
- if (Number(revoked.numUpdatedRows ?? 0) !== 1) throw new Error("Active content release grant changed during replacement");
25
+ async prepareCreateOrReplaceActive(input) {
26
+ const current = await this.db.selectFrom("_dineway_content_release_grants").selectAll().where("collection", "=", input.collection).where("entry_id", "=", input.entryId).where("operation", "=", input.operation).where("status", "=", "active").executeTakeFirst();
27
+ const checks = [current ? rowUnchanged("_dineway_content_release_grants", current) : sql`NOT EXISTS (SELECT 1 FROM _dineway_content_release_grants WHERE collection = ${input.collection} AND entry_id = ${input.entryId} AND operation = ${input.operation} AND status = 'active')`];
28
+ if (current?.action_hash === input.actionHash) return {
29
+ grant: rowToGrant(current),
30
+ batch: {
31
+ checks,
32
+ statements: []
33
+ }
34
+ };
35
+ const now = input.createdAt ?? (/* @__PURE__ */ new Date()).toISOString();
36
+ const statements = [];
37
+ if (current) statements.push(this.db.updateTable("_dineway_content_release_grants").set({
38
+ status: "revoked",
39
+ updated_at: now,
40
+ revoked_at: now,
41
+ revocation_reason: "replaced"
42
+ }).where("id", "=", current.id).where("status", "=", "active").compile());
43
+ const row = toInsertableGrant(ulid(), input, now);
44
+ statements.push(this.db.insertInto("_dineway_content_release_grants").values(row).compile());
45
+ return {
46
+ grant: rowToGrant(row),
47
+ batch: {
48
+ checks,
49
+ statements
29
50
  }
30
- const id = ulid();
31
- await transaction.insertInto("_dineway_content_release_grants").values(toInsertableGrant(id, input, now)).execute();
32
- const created = await findById(transaction, id);
33
- if (!created) throw new Error("Failed to create content release grant");
34
- return created;
35
51
  };
36
- return this.db.isTransaction ? operation(this.db) : this.db.transaction().execute(operation);
52
+ }
53
+ async createOrReplaceActive(input) {
54
+ const prepared = await this.prepareCreateOrReplaceActive(input);
55
+ await atomicBatch(this.db, prepared.batch);
56
+ const grant = await this.findById(prepared.grant.id);
57
+ if (!grant) throw new Error("Failed to create content release grant");
58
+ return grant;
37
59
  }
38
60
  async findById(id) {
39
61
  return findById(this.db, id);
@@ -511,7 +533,8 @@ var PublicationAuthorizationService = class {
511
533
  now;
512
534
  constructor(options) {
513
535
  this.options = options;
514
- this.reviewRequests = new ReviewRequestRepository(options.db);
536
+ const reviewRepository = new ReviewRequestRepository(options.db);
537
+ this.reviewRequests = { findById: async (id) => options.preparedReview?.review.id === id ? options.preparedReview.review : reviewRepository.findById(id) };
515
538
  this.releaseGrants = new ContentReleaseGrantRepository(options.db);
516
539
  this.hitlRequests = new HitlRequestRepository(options.db);
517
540
  this.activity = new SiteActivityRepository(options.db);
@@ -655,7 +678,7 @@ var PublicationAuthorizationService = class {
655
678
  };
656
679
  }
657
680
  async releaseApprovedReview(reviewId) {
658
- if (!this.options.db.isTransaction) throw new PublicationAuthorizationError("RELEASE_GRANT_FAILED", "Automated release requires a transaction.");
681
+ if (!this.options.db.isTransaction && !isD1Database(this.options.db)) throw new PublicationAuthorizationError("RELEASE_GRANT_FAILED", "Automated release requires a transaction.");
659
682
  const job = await this.options.db.selectFrom("_dineway_review_jobs").selectAll().where("review_id", "=", reviewId).where("release_state", "=", "releasing").executeTakeFirst();
660
683
  const review = await this.reviewRequests.findById(reviewId);
661
684
  if (!job || !review || review.status !== "approved" || review.revokedAt) throw new PublicationAuthorizationError("EDITORIAL_REVIEW_INVALID", "An active exact review approval is required.");
@@ -673,6 +696,27 @@ var PublicationAuthorizationService = class {
673
696
  sourceType: "system",
674
697
  sourceName: "review-automation"
675
698
  };
699
+ if (isD1Database(this.options.db)) {
700
+ const future = job.scheduled_at && job.scheduled_at > this.now();
701
+ const outcome = future ? "scheduled" : "published";
702
+ await this.publishAtomic(future ? {
703
+ ...input,
704
+ scheduledAt: job.scheduled_at
705
+ } : input, future ? "schedule" : "publish", {
706
+ checks: [rowUnchanged("_dineway_review_jobs", {
707
+ review_id: job.review_id,
708
+ release_state: job.release_state,
709
+ updated_at: job.updated_at,
710
+ scheduled_at: job.scheduled_at
711
+ })],
712
+ statements: [this.options.db.updateTable("_dineway_review_jobs").set({
713
+ release_state: outcome,
714
+ release_reason: null,
715
+ updated_at: this.now()
716
+ }).where("review_id", "=", job.review_id).where("release_state", "=", "releasing").compile()]
717
+ });
718
+ return outcome;
719
+ }
676
720
  if (job.scheduled_at && job.scheduled_at > this.now()) {
677
721
  await this.scheduleAuthorizedContent({
678
722
  ...input,
@@ -683,7 +727,13 @@ var PublicationAuthorizationService = class {
683
727
  await this.publishAuthorizedContent(input);
684
728
  return "published";
685
729
  }
730
+ /** Commit a host-prepared review and publication as one explicit batch. */
731
+ async publishPreparedContent(input) {
732
+ if (!this.options.preparedReview) throw new PublicationAuthorizationError("CONFIRMATION_REQUIRED", "A prepared host confirmation is required");
733
+ return this.publishAtomic(input, "publish");
734
+ }
686
735
  async publishAuthorizedContent(input) {
736
+ if (isD1Database(this.options.db)) return this.publishAtomic(input, "publish");
687
737
  const siteTimezone = await this.getSiteTimezone();
688
738
  const authorized = await this.authorize({
689
739
  ...input,
@@ -706,6 +756,7 @@ var PublicationAuthorizationService = class {
706
756
  };
707
757
  }
708
758
  async scheduleAuthorizedContent(input) {
759
+ if (isD1Database(this.options.db)) return this.publishAtomic(input, "schedule");
709
760
  const siteTimezone = await this.getSiteTimezone();
710
761
  const authorized = await this.authorize({
711
762
  ...input,
@@ -722,6 +773,7 @@ var PublicationAuthorizationService = class {
722
773
  };
723
774
  }
724
775
  async publishAuthorizedDueContent(input) {
776
+ if (isD1Database(this.options.db)) return this.publishDueAtomic(input);
725
777
  const grant = await this.releaseGrants.findActiveForTarget(input.collection, input.id, "schedule");
726
778
  if (!grant) {
727
779
  await this.blockScheduledRelease(input, null, "schedule_grant_required");
@@ -760,6 +812,7 @@ var PublicationAuthorizationService = class {
760
812
  };
761
813
  }
762
814
  async unscheduleAuthorizedContent(input) {
815
+ if (isD1Database(this.options.db)) return this.unscheduleAtomic(input);
763
816
  const activeGrant = await this.releaseGrants.findActiveForTarget(input.collection, input.id, "schedule");
764
817
  let revokedGrant = null;
765
818
  if (activeGrant) {
@@ -791,6 +844,366 @@ var PublicationAuthorizationService = class {
791
844
  await this.releasePolicies(prepared, "release_request_prepared");
792
845
  }
793
846
  }
847
+ async unscheduleAtomic(input) {
848
+ const db = this.options.db;
849
+ const snapshot = await new ContentRepository(db).snapshot(input.collection, input.id);
850
+ if (!snapshot) throw new PublicationAuthorizationError("NOT_FOUND", "Content not found");
851
+ const checks = [snapshot.check, ...await this.atomicActorChecks(input, snapshot.item)];
852
+ const rawGrant = await db.selectFrom("_dineway_content_release_grants").selectAll().where("collection", "=", input.collection).where("entry_id", "=", input.id).where("operation", "=", "schedule").where("status", "=", "active").executeTakeFirst();
853
+ checks.push(rawGrant ? rowUnchanged("_dineway_content_release_grants", rawGrant) : sql`NOT EXISTS (SELECT 1 FROM _dineway_content_release_grants WHERE collection = ${input.collection} AND entry_id = ${input.id} AND operation = 'schedule' AND status = 'active')`);
854
+ const grant = rawGrant ? await this.releaseGrants.findById(rawGrant.id) : null;
855
+ if (grant?.policyContributions.some((contribution) => contribution.reservationId)) throw new PublicationAuthorizationError("RELEASE_POLICY_FAILED", "Reservation policies require a transactional database adapter");
856
+ const statements = [sql`UPDATE ${sql.table(`ec_${input.collection}`)} SET scheduled_at = NULL, status = CASE WHEN status = 'published' THEN 'published' ELSE 'draft' END, updated_at = ${this.now()} WHERE id = ${input.id}`.compile(db)];
857
+ if (grant) statements.push(db.updateTable("_dineway_content_release_grants").set({
858
+ status: "revoked",
859
+ revoked_at: this.now(),
860
+ revocation_reason: "content_unscheduled",
861
+ updated_at: this.now()
862
+ }).where("id", "=", grant.id).compile(), db.updateTable("_dineway_review_jobs").set({
863
+ release_state: "blocked",
864
+ release_reason: "content_unscheduled",
865
+ updated_at: this.now()
866
+ }).where("review_id", "=", grant.editorialReviewRequestId).where("release_state", "in", [
867
+ "queued",
868
+ "scheduled",
869
+ "releasing"
870
+ ]).compile());
871
+ statements.push(this.activity.prepareCreate({
872
+ ...input.actor,
873
+ actionType: "content.unschedule",
874
+ subjectType: "content",
875
+ subjectId: input.id,
876
+ scope: `content:${input.collection}:${input.id}`,
877
+ summary: `Unscheduled ${input.collection}/${input.id}`,
878
+ sourceType: input.sourceType ?? "unknown",
879
+ sourceName: input.sourceName ?? null,
880
+ detail: {
881
+ releaseGrantId: grant?.id ?? null,
882
+ revocationReason: "content_unscheduled"
883
+ }
884
+ }).statement);
885
+ await atomicBatch(db, {
886
+ checks,
887
+ statements
888
+ });
889
+ invalidateCollectionCache(input.collection);
890
+ const result = await this.options.handlers.handleContentGet(input.collection, input.id);
891
+ await this.options.onUnscheduleCommitted?.(input.collection, input.id, snapshot.item);
892
+ return {
893
+ grant: grant ? await this.releaseGrants.findById(grant.id) : null,
894
+ result
895
+ };
896
+ }
897
+ async publishDueAtomic(input) {
898
+ const db = this.options.db;
899
+ const snapshot = await new ContentRepository(db).snapshot(input.collection, input.id);
900
+ if (!snapshot || !snapshot.item.scheduledAt || snapshot.item.scheduledAt > this.now()) throw new PublicationAuthorizationError("NOT_DUE", "Content is no longer due for publication");
901
+ const checks = [snapshot.check];
902
+ const rawGrant = await db.selectFrom("_dineway_content_release_grants").selectAll().where("collection", "=", input.collection).where("entry_id", "=", input.id).where("operation", "=", "schedule").where("status", "=", "active").executeTakeFirst();
903
+ const grant = rawGrant ? await this.releaseGrants.findById(rawGrant.id) : null;
904
+ checks.push(rawGrant ? rowUnchanged("_dineway_content_release_grants", rawGrant) : sql`NOT EXISTS (SELECT 1 FROM _dineway_content_release_grants WHERE collection = ${input.collection} AND entry_id = ${input.id} AND operation = 'schedule' AND status = 'active')`);
905
+ let release;
906
+ try {
907
+ if (!grant) throw new PublicationAuthorizationError("SCHEDULE_GRANT_REQUIRED", "Due content has no active schedule grant");
908
+ const review = await db.selectFrom("_dineway_review_requests").selectAll().where("id", "=", grant.editorialReviewRequestId).executeTakeFirst();
909
+ if (!review) throw new PublicationAuthorizationError("SCHEDULE_GRANT_INVALID", "Editorial review is missing");
910
+ checks.push(rowUnchanged("_dineway_review_requests", review));
911
+ const ids = [snapshot.item.liveRevisionId, snapshot.item.draftRevisionId].filter((id) => id !== null);
912
+ const revisions = ids.length ? await db.selectFrom("revisions").selectAll().where("id", "in", ids).execute() : [];
913
+ checks.push(...revisions.map((row) => rowUnchanged("revisions", row)));
914
+ const timezone = await db.selectFrom("options").selectAll().where("name", "=", "site:timezone").executeTakeFirst();
915
+ checks.push(timezone ? rowUnchanged("options", timezone) : sql`NOT EXISTS (SELECT 1 FROM options WHERE name = 'site:timezone')`);
916
+ const pluginStates = await db.selectFrom("_plugin_state").selectAll().execute();
917
+ checks.push(sql`(SELECT COUNT(*) FROM _plugin_state) = ${pluginStates.length}`, ...pluginStates.map((row) => rowUnchanged("_plugin_state", row)));
918
+ const preparedPolicies = this.restorePreparedPolicies(grant.policyContributions);
919
+ release = await this.revalidateScheduledGrant(input, grant, preparedPolicies, checks);
920
+ checks.push(...await this.atomicActorChecks({
921
+ actor: grantActor(grant),
922
+ editorialReviewRequestId: grant.editorialReviewRequestId
923
+ }, snapshot.item, true));
924
+ } catch (error) {
925
+ const reason = errorReason(error);
926
+ const statements = [sql`UPDATE ${sql.table(`ec_${input.collection}`)} SET scheduled_at = NULL, status = CASE WHEN status = 'published' THEN 'published' ELSE 'draft' END, updated_at = ${this.now()} WHERE id = ${input.id}`.compile(db)];
927
+ if (grant) statements.push(db.updateTable("_dineway_content_release_grants").set({
928
+ status: "revoked",
929
+ revoked_at: this.now(),
930
+ updated_at: this.now(),
931
+ revocation_reason: reason
932
+ }).where("id", "=", grant.id).compile(), db.updateTable("_dineway_review_jobs").set({
933
+ release_state: "blocked",
934
+ release_reason: reason,
935
+ updated_at: this.now()
936
+ }).where("review_id", "=", grant.editorialReviewRequestId).where("release_state", "=", "scheduled").compile());
937
+ statements.push(this.activity.prepareCreate({
938
+ actorType: "system",
939
+ actorId: SYSTEM_ACTOR_ID,
940
+ actionType: "content.schedule_blocked",
941
+ subjectType: "content",
942
+ subjectId: input.id,
943
+ scope: `content:${input.collection}:${input.id}`,
944
+ summary: "Blocked scheduled publication",
945
+ detail: {
946
+ reason,
947
+ releaseGrantId: grant?.id ?? null
948
+ },
949
+ sourceType: "system",
950
+ sourceName: "scheduled_publish",
951
+ resultStatus: "blocked"
952
+ }).statement);
953
+ await atomicBatch(db, {
954
+ checks,
955
+ statements
956
+ });
957
+ invalidateCollectionCache(input.collection);
958
+ throw error;
959
+ }
960
+ if (!grant) throw new Error("Validated schedule grant is missing");
961
+ const content = await prepareContentPublication(db, input.collection, input.id, {
962
+ publishedAt: input.publishedAt,
963
+ requireScheduledDue: true
964
+ });
965
+ checks.push(...content.batch.checks);
966
+ if (grant.expiresAt) checks.push(sql`${grant.expiresAt} > ${currentIsoTimestampValue(db)}`);
967
+ await atomicBatch(db, {
968
+ checks,
969
+ statements: [
970
+ ...content.batch.statements,
971
+ db.updateTable("_dineway_content_release_grants").set({
972
+ status: "consumed",
973
+ consumed_at: this.now(),
974
+ updated_at: this.now()
975
+ }).where("id", "=", grant.id).where("status", "=", "active").compile(),
976
+ db.updateTable("_dineway_review_jobs").set({
977
+ release_state: "published",
978
+ release_reason: null,
979
+ updated_at: this.now()
980
+ }).where("review_id", "=", grant.editorialReviewRequestId).where("release_state", "in", ["scheduled", "releasing"]).compile(),
981
+ this.activity.prepareCreate({
982
+ actorType: "system",
983
+ actorId: SYSTEM_ACTOR_ID,
984
+ actionType: "content.schedule_published",
985
+ subjectType: "content",
986
+ subjectId: input.id,
987
+ relatedSubjectType: "review_request",
988
+ relatedSubjectId: grant.editorialReviewRequestId,
989
+ scope: release.scope,
990
+ summary: `Published scheduled ${input.collection}/${input.id}`,
991
+ detail: {
992
+ releaseGrantId: grant.id,
993
+ actionHash: release.actionHash
994
+ },
995
+ sourceType: "system",
996
+ sourceName: "scheduled_publish",
997
+ resultStatus: "succeeded"
998
+ }).statement
999
+ ]
1000
+ });
1001
+ invalidateCollectionCache(input.collection);
1002
+ invalidateRedirectCache();
1003
+ const consumed = await this.releaseGrants.findById(grant.id);
1004
+ if (!consumed) throw new Error("Committed schedule grant is missing");
1005
+ const result = await this.options.handlers.handleContentGet(input.collection, input.id);
1006
+ await this.options.onPublicationCommitted?.("publish", input.collection, input.id, snapshot.item);
1007
+ return {
1008
+ grant: consumed,
1009
+ result,
1010
+ receipt: publicationReceipt(consumed, "published")
1011
+ };
1012
+ }
1013
+ async atomicActorChecks(input, content, scheduledAutomation = false) {
1014
+ const db = this.options.db;
1015
+ const checks = [];
1016
+ const automated = input.actor.actorType === "system" && input.actor.actorId === "review-automation" && input.actor.authMetadata.auth_method === "review_automation";
1017
+ if (input.actor.actorType === "system" && scheduledAutomation && automated) return checks;
1018
+ if (input.actor.actorType === "system") {
1019
+ const claim = automated ? await db.selectFrom("_dineway_review_jobs").selectAll().where("review_id", "=", input.editorialReviewRequestId ?? "").where("release_state", "=", "releasing").executeTakeFirst() : null;
1020
+ if (!claim) throw new PublicationAuthorizationError("ACTOR_NOT_ALLOWED", "System publication requires a claimed approved review");
1021
+ checks.push(rowUnchanged("_dineway_review_jobs", {
1022
+ review_id: claim.review_id,
1023
+ release_state: claim.release_state,
1024
+ updated_at: claim.updated_at,
1025
+ scheduled_at: claim.scheduled_at
1026
+ }));
1027
+ } else {
1028
+ let userId = input.actor.actorId;
1029
+ if (input.actor.actorType === "api_token") {
1030
+ const token = await db.selectFrom("_dineway_api_tokens").select([
1031
+ "id",
1032
+ "user_id",
1033
+ "scopes",
1034
+ "expires_at"
1035
+ ]).where("id", "=", input.actor.actorId).executeTakeFirst();
1036
+ if (!token || !hasScope(z.array(z.string()).parse(JSON.parse(token.scopes)), "content:write")) throw new PublicationAuthorizationError("ACTOR_NOT_ALLOWED", "Publication token is unavailable");
1037
+ userId = token.user_id;
1038
+ checks.push(rowUnchanged("_dineway_api_tokens", token), sql`EXISTS (SELECT 1 FROM _dineway_api_tokens WHERE id = ${token.id} AND (expires_at IS NULL OR expires_at > ${currentIsoTimestampValue(db)}))`);
1039
+ } else if (input.actor.authMetadata.auth_method === "oauth_token") {
1040
+ if (!scheduledAutomation) {
1041
+ const hash = getOAuthTokenHash(input.actor);
1042
+ const token = hash ? await db.selectFrom("_dineway_oauth_tokens").select([
1043
+ "token_hash",
1044
+ "token_type",
1045
+ "user_id",
1046
+ "scopes",
1047
+ "expires_at",
1048
+ "client_id"
1049
+ ]).where("token_hash", "=", hash).executeTakeFirst() : void 0;
1050
+ if (!token || token.token_type !== "access" || token.user_id !== userId || !hasScope(z.array(z.string()).parse(JSON.parse(token.scopes)), "content:write")) throw new PublicationAuthorizationError("ACTOR_NOT_ALLOWED", "The authenticated OAuth publication token is unavailable");
1051
+ checks.push(rowUnchanged("_dineway_oauth_tokens", token), sql`${token.expires_at} > ${currentIsoTimestampValue(db)}`);
1052
+ }
1053
+ } else if (input.actor.authMetadata.auth_method !== "session") throw new PublicationAuthorizationError("ACTOR_NOT_ALLOWED", "This authentication method requires an atomic authorization provider");
1054
+ const user = await db.selectFrom("users").select([
1055
+ "id",
1056
+ "role",
1057
+ "disabled"
1058
+ ]).where("id", "=", userId).executeTakeFirst();
1059
+ const principal = user ? {
1060
+ id: user.id,
1061
+ role: toRoleLevel(user.role)
1062
+ } : null;
1063
+ if (!user || user.disabled || !principal || !canActOnOwn(principal, content.authorId ?? "", "content:publish_own", "content:publish_any") || "publishedAt" in input && input.publishedAt !== void 0 && !hasPermission(principal, "content:publish_any")) throw new PublicationAuthorizationError("ACTOR_NOT_ALLOWED", "Publication permission is no longer available");
1064
+ checks.push(rowUnchanged("users", user));
1065
+ }
1066
+ return checks;
1067
+ }
1068
+ async publishAtomic(input, operation, extra = { statements: [] }) {
1069
+ const db = this.options.db;
1070
+ const snapshot = await new ContentRepository(db).snapshot(input.collection, input.id);
1071
+ if (!snapshot) throw new PublicationAuthorizationError("NOT_FOUND", "Content not found");
1072
+ const checks = [snapshot.check, ...extra.checks ?? []];
1073
+ const ids = [snapshot.item.liveRevisionId, snapshot.item.draftRevisionId].filter((id) => id !== null);
1074
+ const revisions = ids.length ? await db.selectFrom("revisions").selectAll().where("id", "in", ids).execute() : [];
1075
+ checks.push(...revisions.map((row) => rowUnchanged("revisions", row)));
1076
+ const storedReview = await db.selectFrom("_dineway_review_requests").selectAll().where("id", "=", input.editorialReviewRequestId).executeTakeFirst();
1077
+ const confirmation = this.options.preparedReview;
1078
+ const review = confirmation ? {
1079
+ id: confirmation.review.id,
1080
+ status: confirmation.review.status,
1081
+ revoked_at: confirmation.review.revokedAt
1082
+ } : storedReview;
1083
+ if (!review || review.status !== "approved" || review.revoked_at) throw new PublicationAuthorizationError("EDITORIAL_REVIEW_INVALID", "An active editorial approval is required");
1084
+ if (confirmation) {
1085
+ if (operation !== "publish" || confirmation.review.id !== input.editorialReviewRequestId || !isHumanSessionActor(input.actor) || confirmation.review.requestedByActorId !== input.actor.actorId || confirmation.review.resolvedByActorId !== input.actor.actorId || confirmation.authorizationChecks.length === 0) throw new PublicationAuthorizationError("ACTOR_NOT_ALLOWED", "Confirmed publication requires explicit host authority for this review");
1086
+ checks.push(...confirmation.batch.checks ?? [], ...confirmation.authorizationChecks);
1087
+ } else if (storedReview) checks.push(rowUnchanged("_dineway_review_requests", storedReview));
1088
+ const automated = input.actor.actorType === "system" && input.actor.actorId === "review-automation" && input.actor.authMetadata.auth_method === "review_automation";
1089
+ if (!confirmation) checks.push(...await this.atomicActorChecks(input, snapshot.item));
1090
+ if ((input.policyOverrides?.length ?? 0) > 0 && !isHumanSessionActor(input.actor)) throw new PublicationAuthorizationError("POLICY_OVERRIDE_NOT_ALLOWED", "Only a human session can confirm policy warnings");
1091
+ const timezone = await db.selectFrom("options").selectAll().where("name", "=", "site:timezone").executeTakeFirst();
1092
+ checks.push(timezone ? rowUnchanged("options", timezone) : sql`NOT EXISTS (SELECT 1 FROM options WHERE name = 'site:timezone')`);
1093
+ const pluginStates = await db.selectFrom("_plugin_state").selectAll().execute();
1094
+ checks.push(sql`(SELECT COUNT(*) FROM _plugin_state) = ${pluginStates.length}`, ...pluginStates.map((row) => rowUnchanged("_plugin_state", row)));
1095
+ const releaseInput = {
1096
+ ...input,
1097
+ operation,
1098
+ siteTimezone: await this.getSiteTimezone()
1099
+ };
1100
+ const baseRelease = await this.buildRelease(releaseInput, []);
1101
+ const reviewJob = await db.selectFrom("_dineway_review_jobs").selectAll().where("review_id", "=", review.id).executeTakeFirst();
1102
+ if (reviewJob) checks.push(rowUnchanged("_dineway_review_jobs", reviewJob));
1103
+ const active = await this.releaseGrants.findActiveForTarget(input.collection, input.id, operation);
1104
+ if (active?.policyContributions.some((contribution) => contribution.reservationId)) throw new PublicationAuthorizationError("RELEASE_POLICY_FAILED", "Reservation policies require a transactional database adapter");
1105
+ const preparedPolicies = [];
1106
+ for (const policy of this.policies) {
1107
+ if (!policy.prepareAtomic || !policy.validateAtomic) throw new PublicationAuthorizationError("RELEASE_POLICY_FAILED", `Policy ${policy.id} does not provide atomic D1 checks`);
1108
+ const prepared = await policy.prepareAtomic(toPreparationTarget(baseRelease, active?.policyContributions ?? [], input.actor, input.policyOverrides ?? []));
1109
+ if (prepared.contribution.providerId !== policy.id || prepared.contribution.reservationId) throw new PublicationAuthorizationError("RELEASE_POLICY_FAILED", "Invalid atomic policy contribution");
1110
+ checks.push(...prepared.checks);
1111
+ preparedPolicies.push({
1112
+ policy,
1113
+ contribution: prepared.contribution
1114
+ });
1115
+ }
1116
+ const release = await this.buildRelease(releaseInput, preparedPolicies.map((prepared) => prepared.contribution));
1117
+ for (const prepared of preparedPolicies) checks.push(...await prepared.policy.validateAtomic(release, prepared.contribution));
1118
+ const hitl = isTokenAuthenticatedActor(input.actor) ? await this.requireApprovedReleaseHitl(releaseInput, release) : null;
1119
+ if (hitl) {
1120
+ const raw = await db.selectFrom("_dineway_hitl_requests").selectAll().where("id", "=", hitl.id).executeTakeFirstOrThrow();
1121
+ checks.push(rowUnchanged("_dineway_hitl_requests", raw));
1122
+ }
1123
+ const preparedGrant = await this.releaseGrants.prepareCreateOrReplaceActive({
1124
+ collection: release.collection,
1125
+ entryId: release.entryId,
1126
+ scope: release.scope,
1127
+ liveRevisionId: release.liveRevisionId,
1128
+ draftRevisionId: release.draftRevisionId,
1129
+ reviewedRev: release.reviewedRev,
1130
+ editorialReviewRequestId: release.editorialReviewRequestId,
1131
+ releaseHitlRequestId: hitl?.id ?? null,
1132
+ operation,
1133
+ scheduledAt: release.scheduledAt,
1134
+ publishedAt: release.publishedAt,
1135
+ siteTimezone: release.siteTimezone,
1136
+ actionHash: release.actionHash,
1137
+ policyContributions: toStoredPolicyContributions(release.policyContributions),
1138
+ authorizationMethod: automated ? "review_automation" : hitl ? "approved_hitl" : "human_action",
1139
+ authorizedByActorType: input.actor.actorType,
1140
+ authorizedByActorId: input.actor.actorId,
1141
+ authorizedAuthMetadata: redactActivityRecord(input.actor.authMetadata),
1142
+ createdAt: this.now()
1143
+ });
1144
+ checks.push(...preparedGrant.batch.checks ?? []);
1145
+ const statements = [...confirmation?.batch.statements ?? [], ...preparedGrant.batch.statements];
1146
+ if (operation === "publish") {
1147
+ const preparedContent = await prepareContentPublication(db, input.collection, input.id, "publishedAt" in input ? { publishedAt: input.publishedAt } : {});
1148
+ checks.push(...preparedContent.batch.checks);
1149
+ statements.push(...preparedContent.batch.statements, db.updateTable("_dineway_content_release_grants").set({
1150
+ status: "consumed",
1151
+ consumed_at: this.now(),
1152
+ updated_at: this.now()
1153
+ }).where("id", "=", preparedGrant.grant.id).where("status", "=", "active").compile());
1154
+ } else {
1155
+ if (!release.scheduledAt || release.scheduledAt <= this.now()) throw new PublicationAuthorizationError("VALIDATION_ERROR", "Scheduled date must be in the future");
1156
+ statements.push(sql`UPDATE ${sql.table(`ec_${input.collection}`)} SET status = CASE WHEN status = 'published' THEN 'published' ELSE 'scheduled' END, scheduled_at = ${release.scheduledAt}, updated_at = ${this.now()} WHERE id = ${input.id}`.compile(db));
1157
+ }
1158
+ statements.push(db.updateTable("_dineway_review_jobs").set({
1159
+ release_state: operation === "publish" ? "published" : "scheduled",
1160
+ release_reason: null,
1161
+ updated_at: this.now()
1162
+ }).where("review_id", "=", review.id).compile());
1163
+ statements.push(this.activity.prepareCreate({
1164
+ ...input.actor,
1165
+ authMetadata: redactActivityRecord(input.actor.authMetadata),
1166
+ actionType: release.actionType,
1167
+ subjectType: "content",
1168
+ subjectId: input.id,
1169
+ relatedSubjectType: "review_request",
1170
+ relatedSubjectId: review.id,
1171
+ sourceType: input.sourceType ?? "unknown",
1172
+ sourceName: input.sourceName ?? null,
1173
+ resultStatus: "succeeded",
1174
+ scope: release.scope,
1175
+ summary: `${operation === "publish" ? "Published" : "Scheduled"} ${input.collection}/${input.id}`,
1176
+ detail: {
1177
+ editorialReviewRequestId: review.id,
1178
+ releaseHitlRequestId: hitl?.id ?? null,
1179
+ releaseGrantId: preparedGrant.grant.id,
1180
+ actionHash: release.actionHash,
1181
+ scheduledAt: release.scheduledAt,
1182
+ publishedAt: release.publishedAt
1183
+ },
1184
+ createdAt: this.now()
1185
+ }).statement, ...extra.statements);
1186
+ try {
1187
+ await atomicBatch(db, {
1188
+ checks,
1189
+ statements
1190
+ });
1191
+ } catch (error) {
1192
+ if (error instanceof AtomicWriteConflict) throw new PublicationAuthorizationError("EDITORIAL_REVIEW_INVALID", "Content, approval or publication permissions changed before commit");
1193
+ throw error;
1194
+ }
1195
+ invalidateCollectionCache(input.collection);
1196
+ invalidateRedirectCache();
1197
+ const grant = await this.releaseGrants.findById(preparedGrant.grant.id);
1198
+ if (!grant) throw new Error("Committed release grant is missing");
1199
+ const result = await this.options.handlers.handleContentGet(input.collection, input.id);
1200
+ await this.options.onPublicationCommitted?.(operation, input.collection, input.id, snapshot.item);
1201
+ return {
1202
+ grant,
1203
+ result,
1204
+ receipt: publicationReceipt(grant, operation === "publish" ? "published" : "scheduled")
1205
+ };
1206
+ }
794
1207
  async authorize(input) {
795
1208
  const automated = input.actor.actorType === "system" && input.actor.actorId === "review-automation" && input.actor.authMetadata.auth_method === "review_automation";
796
1209
  if (input.actor.actorType === "system") {
@@ -839,7 +1252,7 @@ var PublicationAuthorizationService = class {
839
1252
  throw new PublicationAuthorizationError("RELEASE_GRANT_FAILED", error instanceof Error ? error.message : "Failed to authorize content release");
840
1253
  }
841
1254
  }
842
- async revalidateScheduledGrant(input, grant, preparedPolicies) {
1255
+ async revalidateScheduledGrant(input, grant, preparedPolicies, atomicChecks) {
843
1256
  const now = this.now();
844
1257
  if (grant.expiresAt && grant.expiresAt <= now) throw new PublicationAuthorizationError("SCHEDULE_GRANT_EXPIRED", "Schedule grant expired before execution");
845
1258
  if (grant.scheduledAt !== input.scheduledAt) throw new PublicationAuthorizationError("SCHEDULE_GRANT_INVALID", "Schedule grant time does not match the due content");
@@ -930,7 +1343,11 @@ var PublicationAuthorizationService = class {
930
1343
  const request = grant.releaseHitlRequestId ? await this.hitlRequests.findById(grant.releaseHitlRequestId) : null;
931
1344
  if (!request || !matchesReleaseHitl(request, release, grantActor(grant))) throw new PublicationAuthorizationError("SCHEDULE_GRANT_INVALID", "Schedule grant release approval is no longer valid");
932
1345
  }
933
- await this.validatePolicies(release, preparedPolicies);
1346
+ if (atomicChecks) for (const prepared of preparedPolicies) {
1347
+ if (!prepared.policy.validateAtomic || prepared.contribution.reservationId) throw new PublicationAuthorizationError("RELEASE_POLICY_FAILED", "Scheduled policy lacks atomic D1 checks");
1348
+ atomicChecks.push(...await prepared.policy.validateAtomic(release, prepared.contribution));
1349
+ }
1350
+ else await this.validatePolicies(release, preparedPolicies);
934
1351
  return release;
935
1352
  }
936
1353
  async buildRelease(input, policyContributions) {
@@ -962,7 +1379,12 @@ var PublicationAuthorizationService = class {
962
1379
  const prepared = [];
963
1380
  try {
964
1381
  for (const policy of this.policies) {
965
- const contribution = await policy.prepare(target);
1382
+ let contribution;
1383
+ if (isD1Database(this.options.db)) {
1384
+ if (!policy.prepareAtomic) throw new Error(`Policy ${policy.id} does not provide atomic D1 checks`);
1385
+ contribution = (await policy.prepareAtomic(target)).contribution;
1386
+ } else contribution = await policy.prepare(target);
1387
+ if (isD1Database(this.options.db) && contribution.reservationId) throw new Error("D1 policies cannot reserve external state");
966
1388
  if (contribution.providerId !== policy.id) throw new Error(`Publication policy ${policy.id} returned another provider ID`);
967
1389
  prepared.push({
968
1390
  policy,
@@ -977,7 +1399,10 @@ var PublicationAuthorizationService = class {
977
1399
  }
978
1400
  async validatePolicies(release, preparedPolicies) {
979
1401
  try {
980
- for (const prepared of preparedPolicies) await prepared.policy.validate(release, prepared.contribution);
1402
+ for (const prepared of preparedPolicies) if (isD1Database(this.options.db)) {
1403
+ if (!prepared.policy.validateAtomic) throw new Error(`Policy ${prepared.policy.id} does not provide atomic D1 checks`);
1404
+ await prepared.policy.validateAtomic(release, prepared.contribution);
1405
+ } else await prepared.policy.validate(release, prepared.contribution);
981
1406
  } catch (error) {
982
1407
  throw new PublicationAuthorizationError("RELEASE_POLICY_FAILED", error instanceof Error ? error.message : "Publication release policy rejected release");
983
1408
  }
@@ -991,6 +1416,7 @@ var PublicationAuthorizationService = class {
991
1416
  for (const prepared of preparedPolicies) await prepared.policy.consume?.(prepared.contribution);
992
1417
  }
993
1418
  async releasePolicies(preparedPolicies, reason) {
1419
+ if (isD1Database(this.options.db)) return;
994
1420
  for (const prepared of preparedPolicies.toReversed()) await prepared.policy.release?.(prepared.contribution, reason);
995
1421
  }
996
1422
  async releaseReplacedPolicies(contributions, currentPolicies) {