dineway 0.2.33 → 0.2.35
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.
- package/dist/{activity-CfryM8jO.mjs → activity-BbtYp_4V.mjs} +2 -2
- package/dist/{activity-events-BVo9rMUz.mjs → activity-events-CiFN61xq.mjs} +1 -1
- package/dist/{actor-DrJJsvy6.mjs → actor-DxUAJgQX.mjs} +20 -6
- package/dist/{adapters-DHt3f2lu.d.mts → adapters-Rol-inz6.d.mts} +5 -7
- package/dist/after-BVaUn7bK.mjs +24 -0
- package/dist/{allowed-origins-DGSyhRCz.mjs → allowed-origins-Cp7BI3L9.mjs} +1 -1
- package/dist/api/route-utils.d.mts +10 -10
- package/dist/api/route-utils.mjs +23 -19
- package/dist/api/schemas/index.d.mts +1 -1
- package/dist/api/schemas/index.mjs +5 -5
- package/dist/{api-CTf1SLmg.mjs → api-CwhrR7H5.mjs} +55 -1215
- package/dist/api-tokens-DA18zxza.mjs +3 -0
- package/dist/{api-tokens-CSomx-l3.mjs → api-tokens-OAgvq4xg.mjs} +1 -1
- package/dist/{apply-Bs2jXsms.mjs → apply-BTfAReIv.mjs} +109 -93
- package/dist/astro/index.d.mts +16 -12
- package/dist/astro/index.mjs +50 -9
- package/dist/astro/middleware/auth.d.mts +9 -9
- package/dist/astro/middleware/auth.mjs +29 -8
- package/dist/astro/middleware/redirect.mjs +8 -7
- package/dist/astro/middleware/request-context.mjs +17 -10
- package/dist/astro/middleware/seed.d.mts +1 -1
- package/dist/astro/middleware/seed.mjs +93 -71
- package/dist/astro/middleware/setup.mjs +1 -1
- package/dist/astro/middleware/workers.d.mts +6 -0
- package/dist/astro/middleware/workers.mjs +8 -0
- package/dist/astro/middleware.mjs +287 -159
- package/dist/astro/routes/api/admin/allowed-domains/_domain_.mjs +7 -7
- package/dist/astro/routes/api/admin/allowed-domains/index.mjs +7 -7
- package/dist/astro/routes/api/admin/api-tokens/_id_.mjs +4 -4
- package/dist/astro/routes/api/admin/api-tokens/index.mjs +7 -7
- package/dist/astro/routes/api/admin/briefing.mjs +25 -23
- package/dist/astro/routes/api/admin/byline-fields/_slug_/usage.mjs +5 -4
- package/dist/astro/routes/api/admin/byline-fields/_slug_.mjs +11 -10
- package/dist/astro/routes/api/admin/byline-fields/index.mjs +11 -10
- package/dist/astro/routes/api/admin/byline-fields/reorder.mjs +11 -10
- package/dist/astro/routes/api/admin/bylines/_id_/index.mjs +22 -20
- package/dist/astro/routes/api/admin/bylines/_id_/translations.mjs +22 -20
- package/dist/astro/routes/api/admin/bylines/index.mjs +22 -20
- package/dist/astro/routes/api/admin/comments/_id_/status.mjs +18 -16
- package/dist/astro/routes/api/admin/comments/_id_.mjs +8 -7
- package/dist/astro/routes/api/admin/comments/bulk.mjs +14 -13
- package/dist/astro/routes/api/admin/comments/counts.mjs +8 -7
- package/dist/astro/routes/api/admin/comments/index.mjs +14 -13
- package/dist/astro/routes/api/admin/context/_id_/history.mjs +42 -31
- package/dist/astro/routes/api/admin/context/_id_/index.mjs +42 -31
- package/dist/astro/routes/api/admin/context/_id_/review.mjs +47 -36
- package/dist/astro/routes/api/admin/context/_id_/supersede.mjs +47 -36
- package/dist/astro/routes/api/admin/context/diff.mjs +46 -35
- package/dist/astro/routes/api/admin/context/index.mjs +47 -36
- package/dist/astro/routes/api/admin/context/stale.mjs +46 -35
- package/dist/astro/routes/api/admin/hitl-requests/_id_/index.mjs +42 -31
- package/dist/astro/routes/api/admin/hitl-requests/_id_/resolve.mjs +46 -35
- package/dist/astro/routes/api/admin/hitl-requests/index.mjs +46 -35
- package/dist/astro/routes/api/admin/hooks/exclusive/_hookName_.mjs +43 -32
- package/dist/astro/routes/api/admin/hooks/exclusive/index.mjs +3 -3
- package/dist/astro/routes/api/admin/oauth-clients/_id_.mjs +7 -7
- package/dist/astro/routes/api/admin/oauth-clients/index.mjs +7 -7
- package/dist/astro/routes/api/admin/plugins/_id_/disable.mjs +71 -66
- package/dist/astro/routes/api/admin/plugins/_id_/enable.mjs +71 -66
- package/dist/astro/routes/api/admin/plugins/_id_/index.mjs +63 -58
- package/dist/astro/routes/api/admin/plugins/_id_/uninstall.mjs +70 -65
- package/dist/astro/routes/api/admin/plugins/_id_/update.mjs +70 -65
- package/dist/astro/routes/api/admin/plugins/index.mjs +63 -58
- package/dist/astro/routes/api/admin/plugins/marketplace/_id_/icon.mjs +2 -2
- package/dist/astro/routes/api/admin/plugins/marketplace/_id_/index.mjs +63 -58
- package/dist/astro/routes/api/admin/plugins/marketplace/_id_/install.mjs +70 -65
- package/dist/astro/routes/api/admin/plugins/marketplace/index.mjs +63 -58
- package/dist/astro/routes/api/admin/plugins/updates.mjs +63 -58
- package/dist/astro/routes/api/admin/review-requests/_id_/image.mjs +26 -23
- package/dist/astro/routes/api/admin/review-requests/_id_/index.mjs +39 -25
- package/dist/astro/routes/api/admin/review-requests/_id_/resolve.mjs +55 -43
- package/dist/astro/routes/api/admin/review-requests/_id_/revoke.mjs +10 -9
- package/dist/astro/routes/api/admin/review-requests/index.mjs +53 -41
- package/dist/astro/routes/api/admin/themes/marketplace/_id_/index.mjs +63 -58
- package/dist/astro/routes/api/admin/themes/marketplace/_id_/thumbnail.mjs +2 -2
- package/dist/astro/routes/api/admin/themes/marketplace/index.mjs +63 -58
- package/dist/astro/routes/api/admin/users/_id_/disable.mjs +20 -12
- package/dist/astro/routes/api/admin/users/_id_/enable.mjs +1 -1
- package/dist/astro/routes/api/admin/users/_id_/index.mjs +40 -32
- package/dist/astro/routes/api/admin/users/_id_/send-recovery.mjs +3 -3
- package/dist/astro/routes/api/admin/users/index.mjs +7 -7
- package/dist/astro/routes/api/auth/dev-bypass.mjs +6 -5
- package/dist/astro/routes/api/auth/invite/accept.mjs +1 -1
- package/dist/astro/routes/api/auth/invite/complete.mjs +12 -12
- package/dist/astro/routes/api/auth/invite/index.mjs +9 -9
- package/dist/astro/routes/api/auth/invite/register-options.mjs +11 -11
- package/dist/astro/routes/api/auth/logout.mjs +2 -2
- package/dist/astro/routes/api/auth/magic-link/send.mjs +12 -11
- package/dist/astro/routes/api/auth/magic-link/verify.mjs +2 -2
- package/dist/astro/routes/api/auth/me.mjs +11 -11
- package/dist/astro/routes/api/auth/mode.mjs +1 -1
- package/dist/astro/routes/api/auth/oauth/_provider_/callback.mjs +5 -4
- package/dist/astro/routes/api/auth/oauth/_provider_.mjs +5 -4
- package/dist/astro/routes/api/auth/passkey/_id_.mjs +7 -7
- package/dist/astro/routes/api/auth/passkey/index.mjs +1 -1
- package/dist/astro/routes/api/auth/passkey/options.mjs +14 -13
- package/dist/astro/routes/api/auth/passkey/register/options.mjs +11 -11
- package/dist/astro/routes/api/auth/passkey/register/verify.mjs +12 -12
- package/dist/astro/routes/api/auth/passkey/verify.mjs +12 -12
- package/dist/astro/routes/api/auth/setup-token/index.mjs +32 -23
- package/dist/astro/routes/api/auth/setup-token/verify.mjs +32 -26
- package/dist/astro/routes/api/auth/signup/complete.mjs +12 -12
- package/dist/astro/routes/api/auth/signup/request.mjs +12 -11
- package/dist/astro/routes/api/auth/signup/verify.mjs +1 -1
- package/dist/astro/routes/api/comments/_collection_/_contentId_/index.d.mts +73 -2
- package/dist/astro/routes/api/comments/_collection_/_contentId_/index.mjs +91 -49
- package/dist/astro/routes/api/comments/_collection_/_contentId_/reactions.mjs +19 -16
- package/dist/astro/routes/api/content/_collection_/_id_/compare.mjs +2 -2
- package/dist/astro/routes/api/content/_collection_/_id_/discard-draft.mjs +8 -7
- package/dist/astro/routes/api/content/_collection_/_id_/duplicate.mjs +8 -7
- package/dist/astro/routes/api/content/_collection_/_id_/permanent.mjs +8 -7
- package/dist/astro/routes/api/content/_collection_/_id_/preview-url.mjs +24 -21
- package/dist/astro/routes/api/content/_collection_/_id_/publish.mjs +34 -22
- package/dist/astro/routes/api/content/_collection_/_id_/release-readiness.mjs +9 -9
- package/dist/astro/routes/api/content/_collection_/_id_/restore.mjs +8 -7
- package/dist/astro/routes/api/content/_collection_/_id_/revisions.mjs +2 -2
- package/dist/astro/routes/api/content/_collection_/_id_/schedule.mjs +34 -22
- package/dist/astro/routes/api/content/_collection_/_id_/terms/_taxonomy_.mjs +23 -19
- package/dist/astro/routes/api/content/_collection_/_id_/translations.mjs +2 -2
- package/dist/astro/routes/api/content/_collection_/_id_/unpublish.mjs +8 -7
- package/dist/astro/routes/api/content/_collection_/_id_.mjs +14 -13
- package/dist/astro/routes/api/content/_collection_/authors.mjs +2 -2
- package/dist/astro/routes/api/content/_collection_/index.mjs +14 -13
- package/dist/astro/routes/api/content/_collection_/trash.mjs +8 -8
- package/dist/astro/routes/api/dashboard.mjs +16 -11
- package/dist/astro/routes/api/dev/emails.mjs +2 -2
- package/dist/astro/routes/api/health.mjs +1 -1
- package/dist/astro/routes/api/import/probe.d.mts +3 -3
- package/dist/astro/routes/api/import/probe.mjs +25 -24
- package/dist/astro/routes/api/import/wordpress/analyze.mjs +12 -11
- package/dist/astro/routes/api/import/wordpress/execute.d.mts +9 -9
- package/dist/astro/routes/api/import/wordpress/execute.mjs +50 -42
- package/dist/astro/routes/api/import/wordpress/media.d.mts +9 -9
- package/dist/astro/routes/api/import/wordpress/media.mjs +14 -14
- package/dist/astro/routes/api/import/wordpress/prepare.mjs +51 -40
- package/dist/astro/routes/api/import/wordpress/rewrite-urls.d.mts +10 -10
- package/dist/astro/routes/api/import/wordpress/rewrite-urls.mjs +49 -38
- package/dist/astro/routes/api/import/wordpress-plugin/analyze.d.mts +1 -1
- package/dist/astro/routes/api/import/wordpress-plugin/analyze.mjs +29 -27
- package/dist/astro/routes/api/import/wordpress-plugin/callback.mjs +1 -1
- package/dist/astro/routes/api/import/wordpress-plugin/execute.d.mts +9 -9
- package/dist/astro/routes/api/import/wordpress-plugin/execute.mjs +55 -47
- package/dist/astro/routes/api/integration/artifact.mjs +11 -8
- package/dist/astro/routes/api/integration/dispatch.mjs +17 -14
- package/dist/astro/routes/api/integrations/_provider_.mjs +11 -8
- package/dist/astro/routes/api/integrations/index.mjs +10 -7
- package/dist/astro/routes/api/manifest.mjs +5 -5
- package/dist/astro/routes/api/mcp.mjs +97 -88
- package/dist/astro/routes/api/media/_id_/confirm.mjs +12 -12
- package/dist/astro/routes/api/media/_id_.mjs +9 -9
- package/dist/astro/routes/api/media/file/_...key_.mjs +1 -1
- package/dist/astro/routes/api/media/providers/_providerId_/_itemId_.mjs +2 -2
- package/dist/astro/routes/api/media/providers/_providerId_/index.mjs +2 -2
- package/dist/astro/routes/api/media/providers/index.mjs +2 -2
- package/dist/astro/routes/api/media/upload-url.mjs +13 -13
- package/dist/astro/routes/api/media.mjs +16 -16
- package/dist/astro/routes/api/menus/_name_/items/_id_.mjs +47 -36
- package/dist/astro/routes/api/menus/_name_/items.mjs +47 -36
- package/dist/astro/routes/api/menus/_name_/reorder.mjs +47 -36
- package/dist/astro/routes/api/menus/_name_/translations.mjs +47 -36
- package/dist/astro/routes/api/menus/_name_.mjs +47 -36
- package/dist/astro/routes/api/menus/index.mjs +47 -36
- package/dist/astro/routes/api/oauth/authorize.mjs +9 -7
- package/dist/astro/routes/api/oauth/device/authorize.mjs +7 -6
- package/dist/astro/routes/api/oauth/device/code.mjs +11 -9
- package/dist/astro/routes/api/oauth/device/token.mjs +10 -8
- package/dist/astro/routes/api/oauth/register.mjs +4 -4
- package/dist/astro/routes/api/oauth/token/refresh.mjs +7 -6
- package/dist/astro/routes/api/oauth/token/revoke.mjs +7 -6
- package/dist/astro/routes/api/oauth/token.mjs +8 -6
- package/dist/astro/routes/api/openapi.json.mjs +5 -5
- package/dist/astro/routes/api/plugins/_pluginId_/_...path_.mjs +4 -4
- package/dist/astro/routes/api/redirects/404s/index.mjs +15 -14
- package/dist/astro/routes/api/redirects/404s/summary.mjs +15 -14
- package/dist/astro/routes/api/redirects/_id_.mjs +47 -37
- package/dist/astro/routes/api/redirects/index.mjs +47 -37
- package/dist/astro/routes/api/revisions/_revisionId_/index.mjs +2 -2
- package/dist/astro/routes/api/revisions/_revisionId_/restore.mjs +2 -2
- package/dist/astro/routes/api/schema/collections/_slug_/fields/_fieldSlug_.mjs +65 -60
- package/dist/astro/routes/api/schema/collections/_slug_/fields/index.mjs +65 -60
- package/dist/astro/routes/api/schema/collections/_slug_/fields/reorder.mjs +65 -60
- package/dist/astro/routes/api/schema/collections/_slug_/index.mjs +65 -60
- package/dist/astro/routes/api/schema/collections/index.mjs +65 -60
- package/dist/astro/routes/api/schema/index.mjs +12 -11
- package/dist/astro/routes/api/schema/orphans/_slug_.mjs +63 -58
- package/dist/astro/routes/api/schema/orphans/index.mjs +63 -58
- package/dist/astro/routes/api/search/enable.mjs +15 -14
- package/dist/astro/routes/api/search/index.mjs +14 -13
- package/dist/astro/routes/api/search/rebuild.mjs +15 -14
- package/dist/astro/routes/api/search/stats.mjs +9 -8
- package/dist/astro/routes/api/search/suggest.mjs +14 -13
- package/dist/astro/routes/api/sections/_slug_.mjs +47 -36
- package/dist/astro/routes/api/sections/index.mjs +47 -36
- package/dist/astro/routes/api/settings/email.mjs +5 -5
- package/dist/astro/routes/api/settings/reviews.mjs +11 -10
- package/dist/astro/routes/api/settings.mjs +47 -36
- package/dist/astro/routes/api/setup/admin-verify.mjs +14 -14
- package/dist/astro/routes/api/setup/admin.mjs +12 -12
- package/dist/astro/routes/api/setup/dev-bypass.mjs +35 -31
- package/dist/astro/routes/api/setup/dev-reset.mjs +2 -2
- package/dist/astro/routes/api/setup/index.mjs +37 -33
- package/dist/astro/routes/api/setup/status.mjs +3 -3
- package/dist/astro/routes/api/snapshot.mjs +11 -9
- package/dist/astro/routes/api/system/heartbeat.mjs +2 -2
- package/dist/astro/routes/api/taxonomies/_name_/terms/_slug_/translations.mjs +50 -39
- package/dist/astro/routes/api/taxonomies/_name_/terms/_slug_.mjs +50 -39
- package/dist/astro/routes/api/taxonomies/_name_/terms/index.mjs +50 -39
- package/dist/astro/routes/api/taxonomies/index.mjs +50 -39
- package/dist/astro/routes/api/themes/preview.mjs +8 -6
- package/dist/astro/routes/api/typegen.mjs +4 -4
- package/dist/astro/routes/api/well-known/auth.mjs +3 -3
- package/dist/astro/routes/api/well-known/oauth-authorization-server.mjs +3 -3
- package/dist/astro/routes/api/well-known/oauth-protected-resource.mjs +3 -3
- package/dist/astro/routes/api/widget-areas/_name_/reorder.mjs +46 -35
- package/dist/astro/routes/api/widget-areas/_name_/widgets/_id_.mjs +47 -36
- package/dist/astro/routes/api/widget-areas/_name_/widgets.mjs +47 -36
- package/dist/astro/routes/api/widget-areas/_name_.mjs +44 -33
- package/dist/astro/routes/api/widget-areas/index.mjs +47 -36
- package/dist/astro/routes/api/widget-components.mjs +2 -2
- package/dist/astro/routes/robots.txt.mjs +11 -10
- package/dist/astro/routes/sitemap-_collection_.xml.mjs +20 -18
- package/dist/astro/routes/sitemap.xml.mjs +19 -17
- package/dist/astro/session-driver.d.mts +1 -1
- package/dist/astro/session-driver.mjs +4 -4
- package/dist/astro/types.d.mts +13 -13
- package/dist/atomic-authority-CnBQJ14T.mjs +33 -0
- package/dist/{audit-CYjfxG9i.mjs → audit-F5iWkbcJ.mjs} +11 -4
- package/dist/auth/providers/github.d.mts +1 -1
- package/dist/auth/providers/google.d.mts +1 -1
- package/dist/{auth-control-guard-CITT8ZA_.mjs → auth-control-guard-DPOSBNFI.mjs} +1 -1
- package/dist/{authorize-KcI0pAfN.mjs → authorize-CXIjxIfC.mjs} +1 -1
- package/dist/{briefing-BgQTljQt.mjs → briefing-5zf0YZbR.mjs} +445 -447
- package/dist/{briefing-r3hXCDQC.mjs → briefing-DiupPvyN.mjs} +1 -1
- package/dist/{bundle-S6zx-V4D.mjs → bundle-DImnxo71.mjs} +3 -3
- package/dist/{byline-Ctil4rij.mjs → byline-DEZKlzD9.mjs} +107 -113
- package/dist/{byline-fields-51ja6JDa.d.mts → byline-fields-BO96fXLv.d.mts} +8 -8
- package/dist/{byline-fields-DiCyW6eQ.mjs → byline-fields-CY6V0ew1.mjs} +1 -1
- package/dist/{byline-fields-QpmruT5r.mjs → byline-fields-DGNKitg3.mjs} +3 -3
- package/dist/{byline-registry-rkr73qSE.mjs → byline-registry-CkuVVeJJ.mjs} +46 -76
- package/dist/{bylines-v_ZUQnR-.mjs → bylines-CXyKpVLQ.mjs} +6 -6
- package/dist/{bylines-BcuBpzVi.mjs → bylines-gSAfpHl4.mjs} +4 -4
- package/dist/{cache-V2BCplaY.mjs → cache-DZDOBJv3.mjs} +2 -2
- package/dist/{chunks-CnuL55JE.mjs → chunks-BnG3LPMN.mjs} +1 -1
- package/dist/cli/index.mjs +452 -263
- package/dist/cli/plugin-kit.d.mts +9 -9
- package/dist/cli/plugin-kit.mjs +2 -2
- package/dist/client/external-auth-headers.d.mts +1 -1
- package/dist/client/index.d.mts +11 -11
- package/dist/client/index.mjs +2 -2
- package/dist/{client-factory-C-y9VZDX.mjs → client-factory-6vLLT06O.mjs} +1 -1
- package/dist/{comment-_nvJSS-A.mjs → comment-kgLTdtQD.mjs} +15 -8
- package/dist/{comment-reaction-DhVgJ17S.mjs → comment-reaction-Cun5eIXL.mjs} +1 -1
- package/dist/{comments-D4mIDjvA.mjs → comments-ZYK_cZvx.mjs} +1 -1
- package/dist/{content-CVCrcuvD.mjs → content-D9xKUSno.mjs} +287 -165
- package/dist/{content-refresh-QvBIyb_g.mjs → content-refresh-9M9cc55-.mjs} +170 -193
- package/dist/{context-JjKucxBm.mjs → context-BU8AbLmY.mjs} +2 -2
- package/dist/{context-MftkHbWx.mjs → context-C5lPtfeh.mjs} +95 -77
- package/dist/{context-route-helpers-e1APrqSm.mjs → context-route-helpers-CWAHJFl3.mjs} +2 -2
- package/dist/{cron-mGVPQ5e6.mjs → cron-BVYo08mi.mjs} +36 -32
- package/dist/d1-binding-D6HZa3ks.mjs +8 -0
- package/dist/d1-dialect-BBxPg6Om.mjs +48 -0
- package/dist/{dashboard-ZJ7sMcBI.mjs → dashboard-BnD5krLg.mjs} +5 -5
- package/dist/database/batch.d.mts +22 -0
- package/dist/database/batch.mjs +92 -0
- package/dist/database/d1/index.d.mts +18 -0
- package/dist/database/d1/index.mjs +8 -0
- package/dist/db/d1.d.mts +7 -0
- package/dist/db/d1.mjs +13 -0
- package/dist/db/index.d.mts +4 -4
- package/dist/db/index.mjs +10 -7
- package/dist/db/libsql.d.mts +1 -1
- package/dist/db/libsql.mjs +46 -3
- package/dist/db/postgres.d.mts +1 -1
- package/dist/db/sqlite.d.mts +1 -1
- package/dist/{device-flow-eOcL5m0Q.mjs → device-flow-Prqg6ycD.mjs} +130 -94
- package/dist/{dialect-helpers-fk43GbDb.mjs → dialect-helpers-C6xtO-Ui.mjs} +1 -1
- package/dist/{discovery-CJkuHGhZ.mjs → discovery-CYcZJ1o3.mjs} +5 -5
- package/dist/{enrich-KErvJOuI.mjs → enrich-BjF-J4sF.mjs} +1 -1
- package/dist/{evidence-6IUv9ML3.mjs → evidence-krrA3uiG.mjs} +7 -7
- package/dist/{field-defs-cache-CwrIyZFT.mjs → field-defs-cache-BKKFFf_V.mjs} +5 -5
- package/dist/{forgeway-account-lYJ8iX3G.mjs → forgeway-account-CnWOIusE.mjs} +1 -1
- package/dist/{fts-manager-DX7ZkrCa.mjs → fts-manager-DA74x_uP.mjs} +72 -57
- package/dist/{hitl-requests-CmYVunm-.mjs → hitl-requests-CGjA1jND.mjs} +2 -2
- package/dist/{hitl-route-helpers-CRm537zS.mjs → hitl-route-helpers-BxSL0iZB.mjs} +5 -5
- package/dist/{import-DqRAgsKr.mjs → import-CayDCPaH.mjs} +9 -9
- package/dist/{index-Co7xtjkd.d.mts → index-mlJSqFkG.d.mts} +7 -4
- package/dist/index.d.mts +16 -16
- package/dist/index.mjs +103 -96
- package/dist/{integration-credentials-qudN6yRr.mjs → integration-credentials-Br16M1VE.mjs} +2 -2
- package/dist/{jsonld-BpvnSp2m.d.mts → jsonld-BUiFEiCZ.d.mts} +2 -2
- package/dist/{load-fCOciq0Q.mjs → load-B2oitobd.mjs} +1 -1
- package/dist/{loader-BDje8ME2.mjs → loader-Cgsx23wU.mjs} +4 -4
- package/dist/{manifest-schema-CfKD0thC.mjs → manifest-schema-DBXM_g8l.mjs} +1 -1
- package/dist/{mcp-reviewed-executor-DmhM3Cy6.mjs → mcp-reviewed-executor-RJ71uyQb.mjs} +7 -7
- package/dist/media/image-endpoint.mjs +1 -1
- package/dist/media/index.d.mts +1 -1
- package/dist/media/index.mjs +2 -2
- package/dist/media/local-runtime.d.mts +11 -11
- package/dist/media/local-runtime.mjs +3 -3
- package/dist/{media-dvRjj4po.mjs → media-BZqwtRTZ.mjs} +12 -4
- package/dist/{media-allowlist-DaG6lNoy.mjs → media-allowlist-CyByjUXh.mjs} +1 -1
- package/dist/{menus-CZbz5L_V.mjs → menus-2o-DVcwA.mjs} +8 -8
- package/dist/{menus-CpuR4Qkm.mjs → menus-5liJusbp.mjs} +138 -90
- package/dist/migrations-C7YXse7V.mjs +76 -0
- package/dist/oauth-authority-DOjME4Hh.mjs +43 -0
- package/dist/{oauth-authorization-Jf5e3azH.mjs → oauth-authorization-B_mmz7O2.mjs} +89 -98
- package/dist/{oauth-clients-tovQ4D4h.mjs → oauth-clients-Cr4pdIAE.mjs} +2 -2
- package/dist/object-cache/memory.d.mts +1 -1
- package/dist/{object-cache-D51qOseS.mjs → object-cache-BGjIlY9s.mjs} +1 -1
- package/dist/page/index.d.mts +10 -10
- package/dist/page/index.mjs +1 -1
- package/dist/{parse-IsGn-5lt.mjs → parse-BscLr3p2.mjs} +1 -1
- package/dist/plugin-utils.d.mts +9 -9
- package/dist/plugins/adapt-sandbox-entry.d.mts +9 -9
- package/dist/plugins/adapt-sandbox-entry.mjs +1 -1
- package/dist/{plugins-DXyLI3Hb.mjs → plugins-f48yrwfI.mjs} +35 -84
- package/dist/{policy-DKdNMv8y.mjs → policy-CrK1vl8l.mjs} +2 -2
- package/dist/{preview-BXmS1SXL.mjs → preview-E1xKZGsX.mjs} +2 -2
- package/dist/{provider-loader-DDq7R_RN.d.mts → provider-loader-H2wdGD0o.d.mts} +1 -1
- package/dist/{public-url-Ci7UbC0W.d.mts → public-url-CI700CW4.d.mts} +1 -1
- package/dist/{public-url-BQ9vf0AS.d.mts → public-url-zoO-QbN6.d.mts} +2 -2
- package/dist/{publication-authorization-C-vYPGD8.mjs → publication-authorization-Dq_20SZR.mjs} +458 -33
- package/dist/{query-DcB9uGTW.mjs → query-BkWWdxyb.mjs} +4 -4
- package/dist/{query-CrW2yI6G.mjs → query-D6oNo9iz.mjs} +15 -15
- package/dist/{rate-limit-DEkoxTsP.mjs → rate-limit-RaBJEgyt.mjs} +2 -2
- package/dist/{redirect-DG-o0CKV.mjs → redirect-HLI3wT5Y.mjs} +26 -14
- package/dist/{redirects-Bjp4iKJU.mjs → redirects-D16GFaOa.mjs} +5 -5
- package/dist/{redirects-N8gmWhVM.mjs → redirects-DpRiuRWn.mjs} +3 -3
- package/dist/{registry-D-IV_h50.mjs → registry-DcV93OL_.mjs} +183 -186
- package/dist/release-CZfAeyXm.mjs +5148 -0
- package/dist/request-context.d.mts +8 -0
- package/dist/{request-meta-BW0the1R.mjs → request-meta-C6yGqnGD.mjs} +1 -1
- package/dist/{resolve-pZ4NQM-X.mjs → resolve-CpOV2jt_.mjs} +1 -1
- package/dist/review-payload-LLIi1sxO.mjs +1386 -0
- package/dist/{review-requests-DICrYH2-.mjs → review-requests-BF2eEKr8.mjs} +93 -37
- package/dist/{review-requests-BTKfeWlS.mjs → review-requests-C7prIbCo.mjs} +2 -2
- package/dist/{review-route-helpers-DaZBBps8.mjs → review-route-helpers-BYx3Px90.mjs} +2 -2
- package/dist/{revision-De7OmYVD.mjs → revision-090sZyGc.mjs} +28 -22
- package/dist/revocation-DZ8e4JCS.mjs +53 -0
- package/dist/{runner-DJiRFyLI.mjs → runner-CVeq0266.mjs} +594 -491
- package/dist/{runner-Dye73myO.d.mts → runner-Cxl-vyk2.d.mts} +1 -1
- package/dist/{runs-DEujUDOj.mjs → runs-B8kCirJ6.mjs} +5 -5
- package/dist/runtime-env-v-1UXPAH.mjs +19 -0
- package/dist/runtime.d.mts +10 -10
- package/dist/runtime.mjs +5 -5
- package/dist/schema-DFeC5axi.mjs +8 -0
- package/dist/{search-DxUKN9Zz.mjs → search-C9qOBgvo.mjs} +4 -4
- package/dist/{secrets-AdCrGg1c.mjs → secrets-BP2YTPWn.mjs} +10 -11
- package/dist/{sections-BPFOEMK6.mjs → sections-CkoQY7Z9.mjs} +2 -2
- package/dist/seed/index.d.mts +2 -2
- package/dist/seed/index.mjs +29 -25
- package/dist/seo/index.d.mts +3 -3
- package/dist/seo/index.mjs +11 -10
- package/dist/{seo-GfovzqpU.mjs → seo-Bypxm1iD.mjs} +1 -1
- package/dist/{seo-DWHdo5aW.mjs → seo-DYpc_rQ1.mjs} +25 -15
- package/dist/{service-BrNKVCjC.mjs → service-DOFqfUVv.mjs} +46 -21
- package/dist/{service-DbgjHWyW.mjs → service-mJBl4ZP4.mjs} +2 -2
- package/dist/{session-user-D8WwGEPH.mjs → session-user-DacoiKrJ.mjs} +1 -1
- package/dist/{settings-BKEHw6Bu.mjs → settings-2p7TuNWG.mjs} +2 -2
- package/dist/{settings-CAsQLi0N.mjs → settings-DRFy8JQx.mjs} +8 -8
- package/dist/{setup-complete-CHCYS5KV.mjs → setup-complete-CWMnrNFN.mjs} +1 -1
- package/dist/{site-activity-7oezuHXK.mjs → site-activity-BrN2NviL.mjs} +11 -4
- package/dist/{site-context-CA7rbxux.mjs → site-context-D9oETfxF.mjs} +50 -37
- package/dist/{site-url-DoZf_jVj.mjs → site-url-DoTPKRND.mjs} +1 -1
- package/dist/state-D8AogXCV.mjs +30 -0
- package/dist/storage/local.d.mts +1 -1
- package/dist/storage/local.mjs +1 -1
- package/dist/storage/s3.d.mts +1 -1
- package/dist/storage/s3.mjs +3 -3
- package/dist/{store-c4qx3gVh.mjs → store-CjmmGlVw.mjs} +37 -12
- package/dist/submission-BLvkvewK.mjs +411 -0
- package/dist/{taxonomies-ALDiRQ84.mjs → taxonomies-C5ayPp3T.mjs} +3 -3
- package/dist/{taxonomies-93DV-1QT.mjs → taxonomies-DW6Fps-w.mjs} +7 -7
- package/dist/{taxonomy-BOBTJ_aE.mjs → taxonomy-DWxxLpp5.mjs} +3 -3
- package/dist/{tokens-c-qxNqzC.mjs → tokens-I3tSjoFI.mjs} +1 -1
- package/dist/{trusted-proxy-CdEl6g6B.mjs → trusted-proxy-CvDP0g0F.mjs} +4 -12
- package/dist/{types-6KmeXInJ.d.mts → types-BFoQ5a1v.d.mts} +1 -1
- package/dist/{types-BpSTdH1H.mjs → types-BqxIv8Il.mjs} +2 -2
- package/dist/{types-BRCUO8NR.d.mts → types-CVRNRAA5.d.mts} +1 -0
- package/dist/{types-CfpX1og5.d.mts → types-Tt_IGMno.d.mts} +360 -172
- package/dist/ui/server-runtime.d.mts +13 -13
- package/dist/ui/server-runtime.mjs +28 -26
- package/dist/{user-D0NJ7gYf.mjs → user-1-YV30lf.mjs} +2 -2
- package/dist/{utils-BK2efsHv.mjs → utils-BoWkoty8.mjs} +2 -2
- package/dist/{validate-CDWVODvc.d.mts → validate-CCOsvPg2.d.mts} +3 -3
- package/dist/{validate-C9g9iX3q.mjs → validate-CupwWNWL.mjs} +3 -3
- package/dist/version-DpT-k_Ny.mjs +6 -0
- package/dist/{widgets-Cm5Qx2Np.mjs → widgets-DbOctkXv.mjs} +3 -3
- package/dist/{wordpress-slugs-WdPZaVXf.mjs → wordpress-slugs-pQlLXbKn.mjs} +1 -1
- package/dist/{worker-Bhuu7eqS.mjs → worker-wjRq4FI9.mjs} +76 -47
- package/dist/workers-build-QVrquLLe.mjs +36 -0
- package/dist/{zod-generator-DS5oZNaL.mjs → zod-generator-BzACAoR5.mjs} +2 -2
- package/package.json +34 -8
- package/dist/after-BfniwgIf.mjs +0 -9
- package/dist/api-tokens-CmT83Bgj.mjs +0 -3
- package/dist/db/libsql-http.d.mts +0 -27
- package/dist/db/libsql-http.mjs +0 -29
- package/dist/libsql-dialect-CANq6UNI.mjs +0 -47
- package/dist/oauth-user-lookup-B451pZmd.mjs +0 -25
- package/dist/review-payload-f1L4lzQg.mjs +0 -111
- package/dist/revocation-CkTOhdlw.mjs +0 -42
- package/dist/schema-IjuRxkqq.mjs +0 -8
- package/dist/submission-C47cHBIg.mjs +0 -67
- package/dist/transaction-BGQgnwUi.mjs +0 -28
- package/dist/version-CJqc1mwj.mjs +0 -6
- /package/dist/{base64-F8-DUraK.mjs → base64-Cz-aU0X1.mjs} +0 -0
- /package/dist/{challenge-store-CDKfye2r.mjs → challenge-store-DFGsDtCj.mjs} +0 -0
- /package/dist/{components-DAq_4iPX.mjs → components-gMTtJqHg.mjs} +0 -0
- /package/dist/{config-CVssduLe.mjs → config-XW5tMrH8.mjs} +0 -0
- /package/dist/{content-index-names-Bbu1FY1r.mjs → content-index-names-CDc2IQIx.mjs} +0 -0
- /package/dist/{context-types-CPWAJRs5.mjs → context-types-DLD_HnKT.mjs} +0 -0
- /package/dist/{default-BeIzUa1e.mjs → default-w3MwLng7.mjs} +0 -0
- /package/dist/{email-console-Bfi_exVg.mjs → email-console-CpvgEN1w.mjs} +0 -0
- /package/dist/{error-DLg1H2LT.mjs → error-B-44r5TD.mjs} +0 -0
- /package/dist/{escape-C6lkys0j.mjs → escape-B1GM0yJU.mjs} +0 -0
- /package/dist/{experimental-workflows-B9x8delL.mjs → experimental-workflows-fzJHB3ZI.mjs} +0 -0
- /package/dist/{hash-jhbF98tT.mjs → hash-DvMZXj2L.mjs} +0 -0
- /package/dist/{media-url-CL3NzgLh.mjs → media-url-D-elxQjL.mjs} +0 -0
- /package/dist/{mime-CDTtL7jE.mjs → mime-D_ae-u_U.mjs} +0 -0
- /package/dist/{mode-DJeacFCZ.mjs → mode-BJwb_MgK.mjs} +0 -0
- /package/dist/{normalize-Ev3FiBMx.mjs → normalize-5rct_U0I.mjs} +0 -0
- /package/dist/{oauth-state-store-Do1a_o3H.mjs → oauth-state-store-D2H9hKcN.mjs} +0 -0
- /package/dist/{options-1dBRkoCl.mjs → options-BcqHWpc-.mjs} +0 -0
- /package/dist/{output-8j9oltTf.mjs → output-CdmbQioY.mjs} +0 -0
- /package/dist/{parser-C9rzPuSZ.mjs → parser-ehIlj32k.mjs} +0 -0
- /package/dist/{passkey-config-CRN44T04.mjs → passkey-config-sUQoLEj_.mjs} +0 -0
- /package/dist/{patterns-3XE9bU4r.mjs → patterns-CZ7D4y_R.mjs} +0 -0
- /package/dist/{placeholder-D03pGvqM.d.mts → placeholder-CQKI6vLd.d.mts} +0 -0
- /package/dist/{portable-text-BdRm4uZq.d.mts → portable-text-BE7nszX6.d.mts} +0 -0
- /package/dist/{portable-text-tIk9_uz_.mjs → portable-text-DH3Om_2D.mjs} +0 -0
- /package/dist/{process-cache-B-L-A9zg.mjs → process-cache-MHM4Sqzs.mjs} +0 -0
- /package/dist/{provider-loader-C4i82ll1.mjs → provider-loader-Dnv2neOu.mjs} +0 -0
- /package/dist/{public-discovery-CyDzK1-S.mjs → public-discovery-CTql6jdZ.mjs} +0 -0
- /package/dist/{public-url-BVIjzMo3.mjs → public-url-4sMO36Gw.mjs} +0 -0
- /package/dist/{public-url-oudwI7K0.mjs → public-url-DNt9A1yS.mjs} +0 -0
- /package/dist/{redirect-Dp5u-8dH.mjs → redirect-Cjjb5VYr.mjs} +0 -0
- /package/dist/{request-cache-BruBnFAR.mjs → request-cache-DPmV5nk4.mjs} +0 -0
- /package/dist/{seo-contributions-BAtRDXEQ.mjs → seo-contributions-atY3jZEV.mjs} +0 -0
- /package/dist/{service-DeX1PRNt.mjs → service-CeEi6nax.mjs} +0 -0
- /package/dist/{setup-nonce-D-CEYlw7.mjs → setup-nonce-BUmfCiY1.mjs} +0 -0
- /package/dist/{sidecar-client-Bw2C0XTf.mjs → sidecar-client-CbrX8nuw.mjs} +0 -0
- /package/dist/{slugify-KSsVD_D3.mjs → slugify-Di8Q_MFq.mjs} +0 -0
- /package/dist/{ssrf-C7tTSD1r.mjs → ssrf-COxLChKv.mjs} +0 -0
- /package/dist/{stable-hash-DF7R5eN8.mjs → stable-hash-DEtJgcp7.mjs} +0 -0
- /package/dist/{status-Bba6RbkS.mjs → status-DBSB6tdS.mjs} +0 -0
- /package/dist/{transport-ktLL9r2O.d.mts → transport-CZbtxgKZ.d.mts} +0 -0
- /package/dist/{transport-BddGhTAI.mjs → transport-aPKvM53n.mjs} +0 -0
- /package/dist/{types-CKIt_jmM.d.mts → types-1qU0-N1P.d.mts} +0 -0
- /package/dist/{types-BQZFeZjd.mjs → types-BKsk4nnM.mjs} +0 -0
- /package/dist/{types-CLMOusxP.d.mts → types-BWsEjujW.d.mts} +0 -0
- /package/dist/{types--3oJQ0hs.d.mts → types-CAD4OvmF.d.mts} +0 -0
- /package/dist/{types-BbkkkAb6.mjs → types-ChSk0dmw.mjs} +0 -0
- /package/dist/{types-C0DPvhR5.mjs → types-CyBH89BS.mjs} +0 -0
- /package/dist/{types-CU3Wn2HC.d.mts → types-DNPP-eu4.d.mts} +0 -0
- /package/dist/{types-CPaVj_GC.d.mts → types-SddyDti7.d.mts} +0 -0
- /package/dist/{url-C_pLSrGZ.mjs → url-Ce0qtSdB.mjs} +0 -0
- /package/dist/{url-Dumsft7G.mjs → url-DfqolpO2.mjs} +0 -0
- /package/dist/{validate-VPnKoIzW.mjs → validate-Co3j6T_K.mjs} +0 -0
package/dist/{publication-authorization-C-vYPGD8.mjs → publication-authorization-Dq_20SZR.mjs}
RENAMED
|
@@ -1,39 +1,60 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
5
|
-
import {
|
|
6
|
-
import {
|
|
7
|
-
import { t as
|
|
8
|
-
import { n as
|
|
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-D9xKUSno.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 { i as invalidateRedirectCache } from "./cache-DZDOBJv3.mjs";
|
|
11
|
+
import { n as buildStableActionHash, t as ReviewPayloadBuilder, w as prepareContentPublication } from "./review-payload-LLIi1sxO.mjs";
|
|
12
|
+
import { a as getSiteSettingsWithDb } from "./settings-DRFy8JQx.mjs";
|
|
13
|
+
import { n as redactActivityRecord } from "./activity-BbtYp_4V.mjs";
|
|
14
|
+
import { sql } from "kysely";
|
|
9
15
|
import { ulid } from "ulidx";
|
|
16
|
+
import { canActOnOwn, hasPermission, hasScope, toRoleLevel } from "@dineway-ai/auth";
|
|
17
|
+
import { z } from "zod";
|
|
10
18
|
|
|
11
19
|
//#region src/database/repositories/content-release-grants.ts
|
|
12
20
|
var ContentReleaseGrantRepository = class {
|
|
13
21
|
constructor(db) {
|
|
14
22
|
this.db = db;
|
|
15
23
|
}
|
|
16
|
-
async
|
|
17
|
-
const
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
24
|
+
async prepareCreateOrReplaceActive(input) {
|
|
25
|
+
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();
|
|
26
|
+
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')`];
|
|
27
|
+
if (current?.action_hash === input.actionHash) return {
|
|
28
|
+
grant: rowToGrant(current),
|
|
29
|
+
batch: {
|
|
30
|
+
checks,
|
|
31
|
+
statements: []
|
|
32
|
+
}
|
|
33
|
+
};
|
|
34
|
+
const now = input.createdAt ?? (/* @__PURE__ */ new Date()).toISOString();
|
|
35
|
+
const statements = [];
|
|
36
|
+
if (current) statements.push(this.db.updateTable("_dineway_content_release_grants").set({
|
|
37
|
+
status: "revoked",
|
|
38
|
+
updated_at: now,
|
|
39
|
+
revoked_at: now,
|
|
40
|
+
revocation_reason: "replaced"
|
|
41
|
+
}).where("id", "=", current.id).where("status", "=", "active").compile());
|
|
42
|
+
const row = toInsertableGrant(ulid(), input, now);
|
|
43
|
+
statements.push(this.db.insertInto("_dineway_content_release_grants").values(row).compile());
|
|
44
|
+
return {
|
|
45
|
+
grant: rowToGrant(row),
|
|
46
|
+
batch: {
|
|
47
|
+
checks,
|
|
48
|
+
statements
|
|
29
49
|
}
|
|
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
50
|
};
|
|
36
|
-
|
|
51
|
+
}
|
|
52
|
+
async createOrReplaceActive(input) {
|
|
53
|
+
const prepared = await this.prepareCreateOrReplaceActive(input);
|
|
54
|
+
await atomicBatch(this.db, prepared.batch);
|
|
55
|
+
const grant = await this.findById(prepared.grant.id);
|
|
56
|
+
if (!grant) throw new Error("Failed to create content release grant");
|
|
57
|
+
return grant;
|
|
37
58
|
}
|
|
38
59
|
async findById(id) {
|
|
39
60
|
return findById(this.db, id);
|
|
@@ -511,7 +532,8 @@ var PublicationAuthorizationService = class {
|
|
|
511
532
|
now;
|
|
512
533
|
constructor(options) {
|
|
513
534
|
this.options = options;
|
|
514
|
-
|
|
535
|
+
const reviewRepository = new ReviewRequestRepository(options.db);
|
|
536
|
+
this.reviewRequests = { findById: async (id) => options.preparedReview?.review.id === id ? options.preparedReview.review : reviewRepository.findById(id) };
|
|
515
537
|
this.releaseGrants = new ContentReleaseGrantRepository(options.db);
|
|
516
538
|
this.hitlRequests = new HitlRequestRepository(options.db);
|
|
517
539
|
this.activity = new SiteActivityRepository(options.db);
|
|
@@ -655,7 +677,7 @@ var PublicationAuthorizationService = class {
|
|
|
655
677
|
};
|
|
656
678
|
}
|
|
657
679
|
async releaseApprovedReview(reviewId) {
|
|
658
|
-
if (!this.options.db.isTransaction) throw new PublicationAuthorizationError("RELEASE_GRANT_FAILED", "Automated release requires a transaction.");
|
|
680
|
+
if (!this.options.db.isTransaction && !isD1Database(this.options.db)) throw new PublicationAuthorizationError("RELEASE_GRANT_FAILED", "Automated release requires a transaction.");
|
|
659
681
|
const job = await this.options.db.selectFrom("_dineway_review_jobs").selectAll().where("review_id", "=", reviewId).where("release_state", "=", "releasing").executeTakeFirst();
|
|
660
682
|
const review = await this.reviewRequests.findById(reviewId);
|
|
661
683
|
if (!job || !review || review.status !== "approved" || review.revokedAt) throw new PublicationAuthorizationError("EDITORIAL_REVIEW_INVALID", "An active exact review approval is required.");
|
|
@@ -673,6 +695,27 @@ var PublicationAuthorizationService = class {
|
|
|
673
695
|
sourceType: "system",
|
|
674
696
|
sourceName: "review-automation"
|
|
675
697
|
};
|
|
698
|
+
if (isD1Database(this.options.db)) {
|
|
699
|
+
const future = job.scheduled_at && job.scheduled_at > this.now();
|
|
700
|
+
const outcome = future ? "scheduled" : "published";
|
|
701
|
+
await this.publishAtomic(future ? {
|
|
702
|
+
...input,
|
|
703
|
+
scheduledAt: job.scheduled_at
|
|
704
|
+
} : input, future ? "schedule" : "publish", {
|
|
705
|
+
checks: [rowUnchanged("_dineway_review_jobs", {
|
|
706
|
+
review_id: job.review_id,
|
|
707
|
+
release_state: job.release_state,
|
|
708
|
+
updated_at: job.updated_at,
|
|
709
|
+
scheduled_at: job.scheduled_at
|
|
710
|
+
})],
|
|
711
|
+
statements: [this.options.db.updateTable("_dineway_review_jobs").set({
|
|
712
|
+
release_state: outcome,
|
|
713
|
+
release_reason: null,
|
|
714
|
+
updated_at: this.now()
|
|
715
|
+
}).where("review_id", "=", job.review_id).where("release_state", "=", "releasing").compile()]
|
|
716
|
+
});
|
|
717
|
+
return outcome;
|
|
718
|
+
}
|
|
676
719
|
if (job.scheduled_at && job.scheduled_at > this.now()) {
|
|
677
720
|
await this.scheduleAuthorizedContent({
|
|
678
721
|
...input,
|
|
@@ -683,7 +726,13 @@ var PublicationAuthorizationService = class {
|
|
|
683
726
|
await this.publishAuthorizedContent(input);
|
|
684
727
|
return "published";
|
|
685
728
|
}
|
|
729
|
+
/** Commit a host-prepared review and publication as one explicit batch. */
|
|
730
|
+
async publishPreparedContent(input) {
|
|
731
|
+
if (!this.options.preparedReview) throw new PublicationAuthorizationError("CONFIRMATION_REQUIRED", "A prepared host confirmation is required");
|
|
732
|
+
return this.publishAtomic(input, "publish");
|
|
733
|
+
}
|
|
686
734
|
async publishAuthorizedContent(input) {
|
|
735
|
+
if (isD1Database(this.options.db)) return this.publishAtomic(input, "publish");
|
|
687
736
|
const siteTimezone = await this.getSiteTimezone();
|
|
688
737
|
const authorized = await this.authorize({
|
|
689
738
|
...input,
|
|
@@ -706,6 +755,7 @@ var PublicationAuthorizationService = class {
|
|
|
706
755
|
};
|
|
707
756
|
}
|
|
708
757
|
async scheduleAuthorizedContent(input) {
|
|
758
|
+
if (isD1Database(this.options.db)) return this.publishAtomic(input, "schedule");
|
|
709
759
|
const siteTimezone = await this.getSiteTimezone();
|
|
710
760
|
const authorized = await this.authorize({
|
|
711
761
|
...input,
|
|
@@ -722,6 +772,7 @@ var PublicationAuthorizationService = class {
|
|
|
722
772
|
};
|
|
723
773
|
}
|
|
724
774
|
async publishAuthorizedDueContent(input) {
|
|
775
|
+
if (isD1Database(this.options.db)) return this.publishDueAtomic(input);
|
|
725
776
|
const grant = await this.releaseGrants.findActiveForTarget(input.collection, input.id, "schedule");
|
|
726
777
|
if (!grant) {
|
|
727
778
|
await this.blockScheduledRelease(input, null, "schedule_grant_required");
|
|
@@ -760,6 +811,7 @@ var PublicationAuthorizationService = class {
|
|
|
760
811
|
};
|
|
761
812
|
}
|
|
762
813
|
async unscheduleAuthorizedContent(input) {
|
|
814
|
+
if (isD1Database(this.options.db)) return this.unscheduleAtomic(input);
|
|
763
815
|
const activeGrant = await this.releaseGrants.findActiveForTarget(input.collection, input.id, "schedule");
|
|
764
816
|
let revokedGrant = null;
|
|
765
817
|
if (activeGrant) {
|
|
@@ -791,6 +843,366 @@ var PublicationAuthorizationService = class {
|
|
|
791
843
|
await this.releasePolicies(prepared, "release_request_prepared");
|
|
792
844
|
}
|
|
793
845
|
}
|
|
846
|
+
async unscheduleAtomic(input) {
|
|
847
|
+
const db = this.options.db;
|
|
848
|
+
const snapshot = await new ContentRepository(db).snapshot(input.collection, input.id);
|
|
849
|
+
if (!snapshot) throw new PublicationAuthorizationError("NOT_FOUND", "Content not found");
|
|
850
|
+
const checks = [snapshot.check, ...await this.atomicActorChecks(input, snapshot.item)];
|
|
851
|
+
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();
|
|
852
|
+
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')`);
|
|
853
|
+
const grant = rawGrant ? await this.releaseGrants.findById(rawGrant.id) : null;
|
|
854
|
+
if (grant?.policyContributions.some((contribution) => contribution.reservationId)) throw new PublicationAuthorizationError("RELEASE_POLICY_FAILED", "Reservation policies require a transactional database adapter");
|
|
855
|
+
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)];
|
|
856
|
+
if (grant) statements.push(db.updateTable("_dineway_content_release_grants").set({
|
|
857
|
+
status: "revoked",
|
|
858
|
+
revoked_at: this.now(),
|
|
859
|
+
revocation_reason: "content_unscheduled",
|
|
860
|
+
updated_at: this.now()
|
|
861
|
+
}).where("id", "=", grant.id).compile(), db.updateTable("_dineway_review_jobs").set({
|
|
862
|
+
release_state: "blocked",
|
|
863
|
+
release_reason: "content_unscheduled",
|
|
864
|
+
updated_at: this.now()
|
|
865
|
+
}).where("review_id", "=", grant.editorialReviewRequestId).where("release_state", "in", [
|
|
866
|
+
"queued",
|
|
867
|
+
"scheduled",
|
|
868
|
+
"releasing"
|
|
869
|
+
]).compile());
|
|
870
|
+
statements.push(this.activity.prepareCreate({
|
|
871
|
+
...input.actor,
|
|
872
|
+
actionType: "content.unschedule",
|
|
873
|
+
subjectType: "content",
|
|
874
|
+
subjectId: input.id,
|
|
875
|
+
scope: `content:${input.collection}:${input.id}`,
|
|
876
|
+
summary: `Unscheduled ${input.collection}/${input.id}`,
|
|
877
|
+
sourceType: input.sourceType ?? "unknown",
|
|
878
|
+
sourceName: input.sourceName ?? null,
|
|
879
|
+
detail: {
|
|
880
|
+
releaseGrantId: grant?.id ?? null,
|
|
881
|
+
revocationReason: "content_unscheduled"
|
|
882
|
+
}
|
|
883
|
+
}).statement);
|
|
884
|
+
await atomicBatch(db, {
|
|
885
|
+
checks,
|
|
886
|
+
statements
|
|
887
|
+
});
|
|
888
|
+
invalidateCollectionCache(input.collection);
|
|
889
|
+
const result = await this.options.handlers.handleContentGet(input.collection, input.id);
|
|
890
|
+
await this.options.onUnscheduleCommitted?.(input.collection, input.id, snapshot.item);
|
|
891
|
+
return {
|
|
892
|
+
grant: grant ? await this.releaseGrants.findById(grant.id) : null,
|
|
893
|
+
result
|
|
894
|
+
};
|
|
895
|
+
}
|
|
896
|
+
async publishDueAtomic(input) {
|
|
897
|
+
const db = this.options.db;
|
|
898
|
+
const snapshot = await new ContentRepository(db).snapshot(input.collection, input.id);
|
|
899
|
+
if (!snapshot || !snapshot.item.scheduledAt || snapshot.item.scheduledAt > this.now()) throw new PublicationAuthorizationError("NOT_DUE", "Content is no longer due for publication");
|
|
900
|
+
const checks = [snapshot.check];
|
|
901
|
+
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();
|
|
902
|
+
const grant = rawGrant ? await this.releaseGrants.findById(rawGrant.id) : null;
|
|
903
|
+
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')`);
|
|
904
|
+
let release;
|
|
905
|
+
try {
|
|
906
|
+
if (!grant) throw new PublicationAuthorizationError("SCHEDULE_GRANT_REQUIRED", "Due content has no active schedule grant");
|
|
907
|
+
const review = await db.selectFrom("_dineway_review_requests").selectAll().where("id", "=", grant.editorialReviewRequestId).executeTakeFirst();
|
|
908
|
+
if (!review) throw new PublicationAuthorizationError("SCHEDULE_GRANT_INVALID", "Editorial review is missing");
|
|
909
|
+
checks.push(rowUnchanged("_dineway_review_requests", review));
|
|
910
|
+
const ids = [snapshot.item.liveRevisionId, snapshot.item.draftRevisionId].filter((id) => id !== null);
|
|
911
|
+
const revisions = ids.length ? await db.selectFrom("revisions").selectAll().where("id", "in", ids).execute() : [];
|
|
912
|
+
checks.push(...revisions.map((row) => rowUnchanged("revisions", row)));
|
|
913
|
+
const timezone = await db.selectFrom("options").selectAll().where("name", "=", "site:timezone").executeTakeFirst();
|
|
914
|
+
checks.push(timezone ? rowUnchanged("options", timezone) : sql`NOT EXISTS (SELECT 1 FROM options WHERE name = 'site:timezone')`);
|
|
915
|
+
const pluginStates = await db.selectFrom("_plugin_state").selectAll().execute();
|
|
916
|
+
checks.push(sql`(SELECT COUNT(*) FROM _plugin_state) = ${pluginStates.length}`, ...pluginStates.map((row) => rowUnchanged("_plugin_state", row)));
|
|
917
|
+
const preparedPolicies = this.restorePreparedPolicies(grant.policyContributions);
|
|
918
|
+
release = await this.revalidateScheduledGrant(input, grant, preparedPolicies, checks);
|
|
919
|
+
checks.push(...await this.atomicActorChecks({
|
|
920
|
+
actor: grantActor(grant),
|
|
921
|
+
editorialReviewRequestId: grant.editorialReviewRequestId
|
|
922
|
+
}, snapshot.item, true));
|
|
923
|
+
} catch (error) {
|
|
924
|
+
const reason = errorReason(error);
|
|
925
|
+
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)];
|
|
926
|
+
if (grant) statements.push(db.updateTable("_dineway_content_release_grants").set({
|
|
927
|
+
status: "revoked",
|
|
928
|
+
revoked_at: this.now(),
|
|
929
|
+
updated_at: this.now(),
|
|
930
|
+
revocation_reason: reason
|
|
931
|
+
}).where("id", "=", grant.id).compile(), db.updateTable("_dineway_review_jobs").set({
|
|
932
|
+
release_state: "blocked",
|
|
933
|
+
release_reason: reason,
|
|
934
|
+
updated_at: this.now()
|
|
935
|
+
}).where("review_id", "=", grant.editorialReviewRequestId).where("release_state", "=", "scheduled").compile());
|
|
936
|
+
statements.push(this.activity.prepareCreate({
|
|
937
|
+
actorType: "system",
|
|
938
|
+
actorId: SYSTEM_ACTOR_ID,
|
|
939
|
+
actionType: "content.schedule_blocked",
|
|
940
|
+
subjectType: "content",
|
|
941
|
+
subjectId: input.id,
|
|
942
|
+
scope: `content:${input.collection}:${input.id}`,
|
|
943
|
+
summary: "Blocked scheduled publication",
|
|
944
|
+
detail: {
|
|
945
|
+
reason,
|
|
946
|
+
releaseGrantId: grant?.id ?? null
|
|
947
|
+
},
|
|
948
|
+
sourceType: "system",
|
|
949
|
+
sourceName: "scheduled_publish",
|
|
950
|
+
resultStatus: "blocked"
|
|
951
|
+
}).statement);
|
|
952
|
+
await atomicBatch(db, {
|
|
953
|
+
checks,
|
|
954
|
+
statements
|
|
955
|
+
});
|
|
956
|
+
invalidateCollectionCache(input.collection);
|
|
957
|
+
throw error;
|
|
958
|
+
}
|
|
959
|
+
if (!grant) throw new Error("Validated schedule grant is missing");
|
|
960
|
+
const content = await prepareContentPublication(db, input.collection, input.id, {
|
|
961
|
+
publishedAt: input.publishedAt,
|
|
962
|
+
requireScheduledDue: true
|
|
963
|
+
});
|
|
964
|
+
checks.push(...content.batch.checks);
|
|
965
|
+
if (grant.expiresAt) checks.push(sql`${grant.expiresAt} > ${currentIsoTimestampValue(db)}`);
|
|
966
|
+
await atomicBatch(db, {
|
|
967
|
+
checks,
|
|
968
|
+
statements: [
|
|
969
|
+
...content.batch.statements,
|
|
970
|
+
db.updateTable("_dineway_content_release_grants").set({
|
|
971
|
+
status: "consumed",
|
|
972
|
+
consumed_at: this.now(),
|
|
973
|
+
updated_at: this.now()
|
|
974
|
+
}).where("id", "=", grant.id).where("status", "=", "active").compile(),
|
|
975
|
+
db.updateTable("_dineway_review_jobs").set({
|
|
976
|
+
release_state: "published",
|
|
977
|
+
release_reason: null,
|
|
978
|
+
updated_at: this.now()
|
|
979
|
+
}).where("review_id", "=", grant.editorialReviewRequestId).where("release_state", "in", ["scheduled", "releasing"]).compile(),
|
|
980
|
+
this.activity.prepareCreate({
|
|
981
|
+
actorType: "system",
|
|
982
|
+
actorId: SYSTEM_ACTOR_ID,
|
|
983
|
+
actionType: "content.schedule_published",
|
|
984
|
+
subjectType: "content",
|
|
985
|
+
subjectId: input.id,
|
|
986
|
+
relatedSubjectType: "review_request",
|
|
987
|
+
relatedSubjectId: grant.editorialReviewRequestId,
|
|
988
|
+
scope: release.scope,
|
|
989
|
+
summary: `Published scheduled ${input.collection}/${input.id}`,
|
|
990
|
+
detail: {
|
|
991
|
+
releaseGrantId: grant.id,
|
|
992
|
+
actionHash: release.actionHash
|
|
993
|
+
},
|
|
994
|
+
sourceType: "system",
|
|
995
|
+
sourceName: "scheduled_publish",
|
|
996
|
+
resultStatus: "succeeded"
|
|
997
|
+
}).statement
|
|
998
|
+
]
|
|
999
|
+
});
|
|
1000
|
+
invalidateCollectionCache(input.collection);
|
|
1001
|
+
invalidateRedirectCache();
|
|
1002
|
+
const consumed = await this.releaseGrants.findById(grant.id);
|
|
1003
|
+
if (!consumed) throw new Error("Committed schedule grant is missing");
|
|
1004
|
+
const result = await this.options.handlers.handleContentGet(input.collection, input.id);
|
|
1005
|
+
await this.options.onPublicationCommitted?.("publish", input.collection, input.id, snapshot.item);
|
|
1006
|
+
return {
|
|
1007
|
+
grant: consumed,
|
|
1008
|
+
result,
|
|
1009
|
+
receipt: publicationReceipt(consumed, "published")
|
|
1010
|
+
};
|
|
1011
|
+
}
|
|
1012
|
+
async atomicActorChecks(input, content, scheduledAutomation = false) {
|
|
1013
|
+
const db = this.options.db;
|
|
1014
|
+
const checks = [];
|
|
1015
|
+
const automated = input.actor.actorType === "system" && input.actor.actorId === "review-automation" && input.actor.authMetadata.auth_method === "review_automation";
|
|
1016
|
+
if (input.actor.actorType === "system" && scheduledAutomation && automated) return checks;
|
|
1017
|
+
if (input.actor.actorType === "system") {
|
|
1018
|
+
const claim = automated ? await db.selectFrom("_dineway_review_jobs").selectAll().where("review_id", "=", input.editorialReviewRequestId ?? "").where("release_state", "=", "releasing").executeTakeFirst() : null;
|
|
1019
|
+
if (!claim) throw new PublicationAuthorizationError("ACTOR_NOT_ALLOWED", "System publication requires a claimed approved review");
|
|
1020
|
+
checks.push(rowUnchanged("_dineway_review_jobs", {
|
|
1021
|
+
review_id: claim.review_id,
|
|
1022
|
+
release_state: claim.release_state,
|
|
1023
|
+
updated_at: claim.updated_at,
|
|
1024
|
+
scheduled_at: claim.scheduled_at
|
|
1025
|
+
}));
|
|
1026
|
+
} else {
|
|
1027
|
+
let userId = input.actor.actorId;
|
|
1028
|
+
if (input.actor.actorType === "api_token") {
|
|
1029
|
+
const token = await db.selectFrom("_dineway_api_tokens").select([
|
|
1030
|
+
"id",
|
|
1031
|
+
"user_id",
|
|
1032
|
+
"scopes",
|
|
1033
|
+
"expires_at"
|
|
1034
|
+
]).where("id", "=", input.actor.actorId).executeTakeFirst();
|
|
1035
|
+
if (!token || !hasScope(z.array(z.string()).parse(JSON.parse(token.scopes)), "content:write")) throw new PublicationAuthorizationError("ACTOR_NOT_ALLOWED", "Publication token is unavailable");
|
|
1036
|
+
userId = token.user_id;
|
|
1037
|
+
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)}))`);
|
|
1038
|
+
} else if (input.actor.authMetadata.auth_method === "oauth_token") {
|
|
1039
|
+
if (!scheduledAutomation) {
|
|
1040
|
+
const hash = getOAuthTokenHash(input.actor);
|
|
1041
|
+
const token = hash ? await db.selectFrom("_dineway_oauth_tokens").select([
|
|
1042
|
+
"token_hash",
|
|
1043
|
+
"token_type",
|
|
1044
|
+
"user_id",
|
|
1045
|
+
"scopes",
|
|
1046
|
+
"expires_at",
|
|
1047
|
+
"client_id"
|
|
1048
|
+
]).where("token_hash", "=", hash).executeTakeFirst() : void 0;
|
|
1049
|
+
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");
|
|
1050
|
+
checks.push(rowUnchanged("_dineway_oauth_tokens", token), sql`${token.expires_at} > ${currentIsoTimestampValue(db)}`);
|
|
1051
|
+
}
|
|
1052
|
+
} else if (input.actor.authMetadata.auth_method !== "session") throw new PublicationAuthorizationError("ACTOR_NOT_ALLOWED", "This authentication method requires an atomic authorization provider");
|
|
1053
|
+
const user = await db.selectFrom("users").select([
|
|
1054
|
+
"id",
|
|
1055
|
+
"role",
|
|
1056
|
+
"disabled"
|
|
1057
|
+
]).where("id", "=", userId).executeTakeFirst();
|
|
1058
|
+
const principal = user ? {
|
|
1059
|
+
id: user.id,
|
|
1060
|
+
role: toRoleLevel(user.role)
|
|
1061
|
+
} : null;
|
|
1062
|
+
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");
|
|
1063
|
+
checks.push(rowUnchanged("users", user));
|
|
1064
|
+
}
|
|
1065
|
+
return checks;
|
|
1066
|
+
}
|
|
1067
|
+
async publishAtomic(input, operation, extra = { statements: [] }) {
|
|
1068
|
+
const db = this.options.db;
|
|
1069
|
+
const snapshot = await new ContentRepository(db).snapshot(input.collection, input.id);
|
|
1070
|
+
if (!snapshot) throw new PublicationAuthorizationError("NOT_FOUND", "Content not found");
|
|
1071
|
+
const checks = [snapshot.check, ...extra.checks ?? []];
|
|
1072
|
+
const ids = [snapshot.item.liveRevisionId, snapshot.item.draftRevisionId].filter((id) => id !== null);
|
|
1073
|
+
const revisions = ids.length ? await db.selectFrom("revisions").selectAll().where("id", "in", ids).execute() : [];
|
|
1074
|
+
checks.push(...revisions.map((row) => rowUnchanged("revisions", row)));
|
|
1075
|
+
const storedReview = await db.selectFrom("_dineway_review_requests").selectAll().where("id", "=", input.editorialReviewRequestId).executeTakeFirst();
|
|
1076
|
+
const confirmation = this.options.preparedReview;
|
|
1077
|
+
const review = confirmation ? {
|
|
1078
|
+
id: confirmation.review.id,
|
|
1079
|
+
status: confirmation.review.status,
|
|
1080
|
+
revoked_at: confirmation.review.revokedAt
|
|
1081
|
+
} : storedReview;
|
|
1082
|
+
if (!review || review.status !== "approved" || review.revoked_at) throw new PublicationAuthorizationError("EDITORIAL_REVIEW_INVALID", "An active editorial approval is required");
|
|
1083
|
+
if (confirmation) {
|
|
1084
|
+
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");
|
|
1085
|
+
checks.push(...confirmation.batch.checks ?? [], ...confirmation.authorizationChecks);
|
|
1086
|
+
} else if (storedReview) checks.push(rowUnchanged("_dineway_review_requests", storedReview));
|
|
1087
|
+
const automated = input.actor.actorType === "system" && input.actor.actorId === "review-automation" && input.actor.authMetadata.auth_method === "review_automation";
|
|
1088
|
+
if (!confirmation) checks.push(...await this.atomicActorChecks(input, snapshot.item));
|
|
1089
|
+
if ((input.policyOverrides?.length ?? 0) > 0 && !isHumanSessionActor(input.actor)) throw new PublicationAuthorizationError("POLICY_OVERRIDE_NOT_ALLOWED", "Only a human session can confirm policy warnings");
|
|
1090
|
+
const timezone = await db.selectFrom("options").selectAll().where("name", "=", "site:timezone").executeTakeFirst();
|
|
1091
|
+
checks.push(timezone ? rowUnchanged("options", timezone) : sql`NOT EXISTS (SELECT 1 FROM options WHERE name = 'site:timezone')`);
|
|
1092
|
+
const pluginStates = await db.selectFrom("_plugin_state").selectAll().execute();
|
|
1093
|
+
checks.push(sql`(SELECT COUNT(*) FROM _plugin_state) = ${pluginStates.length}`, ...pluginStates.map((row) => rowUnchanged("_plugin_state", row)));
|
|
1094
|
+
const releaseInput = {
|
|
1095
|
+
...input,
|
|
1096
|
+
operation,
|
|
1097
|
+
siteTimezone: await this.getSiteTimezone()
|
|
1098
|
+
};
|
|
1099
|
+
const baseRelease = await this.buildRelease(releaseInput, []);
|
|
1100
|
+
const reviewJob = await db.selectFrom("_dineway_review_jobs").selectAll().where("review_id", "=", review.id).executeTakeFirst();
|
|
1101
|
+
if (reviewJob) checks.push(rowUnchanged("_dineway_review_jobs", reviewJob));
|
|
1102
|
+
const active = await this.releaseGrants.findActiveForTarget(input.collection, input.id, operation);
|
|
1103
|
+
if (active?.policyContributions.some((contribution) => contribution.reservationId)) throw new PublicationAuthorizationError("RELEASE_POLICY_FAILED", "Reservation policies require a transactional database adapter");
|
|
1104
|
+
const preparedPolicies = [];
|
|
1105
|
+
for (const policy of this.policies) {
|
|
1106
|
+
if (!policy.prepareAtomic || !policy.validateAtomic) throw new PublicationAuthorizationError("RELEASE_POLICY_FAILED", `Policy ${policy.id} does not provide atomic D1 checks`);
|
|
1107
|
+
const prepared = await policy.prepareAtomic(toPreparationTarget(baseRelease, active?.policyContributions ?? [], input.actor, input.policyOverrides ?? []));
|
|
1108
|
+
if (prepared.contribution.providerId !== policy.id || prepared.contribution.reservationId) throw new PublicationAuthorizationError("RELEASE_POLICY_FAILED", "Invalid atomic policy contribution");
|
|
1109
|
+
checks.push(...prepared.checks);
|
|
1110
|
+
preparedPolicies.push({
|
|
1111
|
+
policy,
|
|
1112
|
+
contribution: prepared.contribution
|
|
1113
|
+
});
|
|
1114
|
+
}
|
|
1115
|
+
const release = await this.buildRelease(releaseInput, preparedPolicies.map((prepared) => prepared.contribution));
|
|
1116
|
+
for (const prepared of preparedPolicies) checks.push(...await prepared.policy.validateAtomic(release, prepared.contribution));
|
|
1117
|
+
const hitl = isTokenAuthenticatedActor(input.actor) ? await this.requireApprovedReleaseHitl(releaseInput, release) : null;
|
|
1118
|
+
if (hitl) {
|
|
1119
|
+
const raw = await db.selectFrom("_dineway_hitl_requests").selectAll().where("id", "=", hitl.id).executeTakeFirstOrThrow();
|
|
1120
|
+
checks.push(rowUnchanged("_dineway_hitl_requests", raw));
|
|
1121
|
+
}
|
|
1122
|
+
const preparedGrant = await this.releaseGrants.prepareCreateOrReplaceActive({
|
|
1123
|
+
collection: release.collection,
|
|
1124
|
+
entryId: release.entryId,
|
|
1125
|
+
scope: release.scope,
|
|
1126
|
+
liveRevisionId: release.liveRevisionId,
|
|
1127
|
+
draftRevisionId: release.draftRevisionId,
|
|
1128
|
+
reviewedRev: release.reviewedRev,
|
|
1129
|
+
editorialReviewRequestId: release.editorialReviewRequestId,
|
|
1130
|
+
releaseHitlRequestId: hitl?.id ?? null,
|
|
1131
|
+
operation,
|
|
1132
|
+
scheduledAt: release.scheduledAt,
|
|
1133
|
+
publishedAt: release.publishedAt,
|
|
1134
|
+
siteTimezone: release.siteTimezone,
|
|
1135
|
+
actionHash: release.actionHash,
|
|
1136
|
+
policyContributions: toStoredPolicyContributions(release.policyContributions),
|
|
1137
|
+
authorizationMethod: automated ? "review_automation" : hitl ? "approved_hitl" : "human_action",
|
|
1138
|
+
authorizedByActorType: input.actor.actorType,
|
|
1139
|
+
authorizedByActorId: input.actor.actorId,
|
|
1140
|
+
authorizedAuthMetadata: redactActivityRecord(input.actor.authMetadata),
|
|
1141
|
+
createdAt: this.now()
|
|
1142
|
+
});
|
|
1143
|
+
checks.push(...preparedGrant.batch.checks ?? []);
|
|
1144
|
+
const statements = [...confirmation?.batch.statements ?? [], ...preparedGrant.batch.statements];
|
|
1145
|
+
if (operation === "publish") {
|
|
1146
|
+
const preparedContent = await prepareContentPublication(db, input.collection, input.id, "publishedAt" in input ? { publishedAt: input.publishedAt } : {});
|
|
1147
|
+
checks.push(...preparedContent.batch.checks);
|
|
1148
|
+
statements.push(...preparedContent.batch.statements, db.updateTable("_dineway_content_release_grants").set({
|
|
1149
|
+
status: "consumed",
|
|
1150
|
+
consumed_at: this.now(),
|
|
1151
|
+
updated_at: this.now()
|
|
1152
|
+
}).where("id", "=", preparedGrant.grant.id).where("status", "=", "active").compile());
|
|
1153
|
+
} else {
|
|
1154
|
+
if (!release.scheduledAt || release.scheduledAt <= this.now()) throw new PublicationAuthorizationError("VALIDATION_ERROR", "Scheduled date must be in the future");
|
|
1155
|
+
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));
|
|
1156
|
+
}
|
|
1157
|
+
statements.push(db.updateTable("_dineway_review_jobs").set({
|
|
1158
|
+
release_state: operation === "publish" ? "published" : "scheduled",
|
|
1159
|
+
release_reason: null,
|
|
1160
|
+
updated_at: this.now()
|
|
1161
|
+
}).where("review_id", "=", review.id).compile());
|
|
1162
|
+
statements.push(this.activity.prepareCreate({
|
|
1163
|
+
...input.actor,
|
|
1164
|
+
authMetadata: redactActivityRecord(input.actor.authMetadata),
|
|
1165
|
+
actionType: release.actionType,
|
|
1166
|
+
subjectType: "content",
|
|
1167
|
+
subjectId: input.id,
|
|
1168
|
+
relatedSubjectType: "review_request",
|
|
1169
|
+
relatedSubjectId: review.id,
|
|
1170
|
+
sourceType: input.sourceType ?? "unknown",
|
|
1171
|
+
sourceName: input.sourceName ?? null,
|
|
1172
|
+
resultStatus: "succeeded",
|
|
1173
|
+
scope: release.scope,
|
|
1174
|
+
summary: `${operation === "publish" ? "Published" : "Scheduled"} ${input.collection}/${input.id}`,
|
|
1175
|
+
detail: {
|
|
1176
|
+
editorialReviewRequestId: review.id,
|
|
1177
|
+
releaseHitlRequestId: hitl?.id ?? null,
|
|
1178
|
+
releaseGrantId: preparedGrant.grant.id,
|
|
1179
|
+
actionHash: release.actionHash,
|
|
1180
|
+
scheduledAt: release.scheduledAt,
|
|
1181
|
+
publishedAt: release.publishedAt
|
|
1182
|
+
},
|
|
1183
|
+
createdAt: this.now()
|
|
1184
|
+
}).statement, ...extra.statements);
|
|
1185
|
+
try {
|
|
1186
|
+
await atomicBatch(db, {
|
|
1187
|
+
checks,
|
|
1188
|
+
statements
|
|
1189
|
+
});
|
|
1190
|
+
} catch (error) {
|
|
1191
|
+
if (error instanceof AtomicWriteConflict) throw new PublicationAuthorizationError("EDITORIAL_REVIEW_INVALID", "Content, approval or publication permissions changed before commit");
|
|
1192
|
+
throw error;
|
|
1193
|
+
}
|
|
1194
|
+
invalidateCollectionCache(input.collection);
|
|
1195
|
+
invalidateRedirectCache();
|
|
1196
|
+
const grant = await this.releaseGrants.findById(preparedGrant.grant.id);
|
|
1197
|
+
if (!grant) throw new Error("Committed release grant is missing");
|
|
1198
|
+
const result = await this.options.handlers.handleContentGet(input.collection, input.id);
|
|
1199
|
+
await this.options.onPublicationCommitted?.(operation, input.collection, input.id, snapshot.item);
|
|
1200
|
+
return {
|
|
1201
|
+
grant,
|
|
1202
|
+
result,
|
|
1203
|
+
receipt: publicationReceipt(grant, operation === "publish" ? "published" : "scheduled")
|
|
1204
|
+
};
|
|
1205
|
+
}
|
|
794
1206
|
async authorize(input) {
|
|
795
1207
|
const automated = input.actor.actorType === "system" && input.actor.actorId === "review-automation" && input.actor.authMetadata.auth_method === "review_automation";
|
|
796
1208
|
if (input.actor.actorType === "system") {
|
|
@@ -839,7 +1251,7 @@ var PublicationAuthorizationService = class {
|
|
|
839
1251
|
throw new PublicationAuthorizationError("RELEASE_GRANT_FAILED", error instanceof Error ? error.message : "Failed to authorize content release");
|
|
840
1252
|
}
|
|
841
1253
|
}
|
|
842
|
-
async revalidateScheduledGrant(input, grant, preparedPolicies) {
|
|
1254
|
+
async revalidateScheduledGrant(input, grant, preparedPolicies, atomicChecks) {
|
|
843
1255
|
const now = this.now();
|
|
844
1256
|
if (grant.expiresAt && grant.expiresAt <= now) throw new PublicationAuthorizationError("SCHEDULE_GRANT_EXPIRED", "Schedule grant expired before execution");
|
|
845
1257
|
if (grant.scheduledAt !== input.scheduledAt) throw new PublicationAuthorizationError("SCHEDULE_GRANT_INVALID", "Schedule grant time does not match the due content");
|
|
@@ -930,7 +1342,11 @@ var PublicationAuthorizationService = class {
|
|
|
930
1342
|
const request = grant.releaseHitlRequestId ? await this.hitlRequests.findById(grant.releaseHitlRequestId) : null;
|
|
931
1343
|
if (!request || !matchesReleaseHitl(request, release, grantActor(grant))) throw new PublicationAuthorizationError("SCHEDULE_GRANT_INVALID", "Schedule grant release approval is no longer valid");
|
|
932
1344
|
}
|
|
933
|
-
|
|
1345
|
+
if (atomicChecks) for (const prepared of preparedPolicies) {
|
|
1346
|
+
if (!prepared.policy.validateAtomic || prepared.contribution.reservationId) throw new PublicationAuthorizationError("RELEASE_POLICY_FAILED", "Scheduled policy lacks atomic D1 checks");
|
|
1347
|
+
atomicChecks.push(...await prepared.policy.validateAtomic(release, prepared.contribution));
|
|
1348
|
+
}
|
|
1349
|
+
else await this.validatePolicies(release, preparedPolicies);
|
|
934
1350
|
return release;
|
|
935
1351
|
}
|
|
936
1352
|
async buildRelease(input, policyContributions) {
|
|
@@ -962,7 +1378,12 @@ var PublicationAuthorizationService = class {
|
|
|
962
1378
|
const prepared = [];
|
|
963
1379
|
try {
|
|
964
1380
|
for (const policy of this.policies) {
|
|
965
|
-
|
|
1381
|
+
let contribution;
|
|
1382
|
+
if (isD1Database(this.options.db)) {
|
|
1383
|
+
if (!policy.prepareAtomic) throw new Error(`Policy ${policy.id} does not provide atomic D1 checks`);
|
|
1384
|
+
contribution = (await policy.prepareAtomic(target)).contribution;
|
|
1385
|
+
} else contribution = await policy.prepare(target);
|
|
1386
|
+
if (isD1Database(this.options.db) && contribution.reservationId) throw new Error("D1 policies cannot reserve external state");
|
|
966
1387
|
if (contribution.providerId !== policy.id) throw new Error(`Publication policy ${policy.id} returned another provider ID`);
|
|
967
1388
|
prepared.push({
|
|
968
1389
|
policy,
|
|
@@ -977,7 +1398,10 @@ var PublicationAuthorizationService = class {
|
|
|
977
1398
|
}
|
|
978
1399
|
async validatePolicies(release, preparedPolicies) {
|
|
979
1400
|
try {
|
|
980
|
-
for (const prepared of preparedPolicies)
|
|
1401
|
+
for (const prepared of preparedPolicies) if (isD1Database(this.options.db)) {
|
|
1402
|
+
if (!prepared.policy.validateAtomic) throw new Error(`Policy ${prepared.policy.id} does not provide atomic D1 checks`);
|
|
1403
|
+
await prepared.policy.validateAtomic(release, prepared.contribution);
|
|
1404
|
+
} else await prepared.policy.validate(release, prepared.contribution);
|
|
981
1405
|
} catch (error) {
|
|
982
1406
|
throw new PublicationAuthorizationError("RELEASE_POLICY_FAILED", error instanceof Error ? error.message : "Publication release policy rejected release");
|
|
983
1407
|
}
|
|
@@ -991,6 +1415,7 @@ var PublicationAuthorizationService = class {
|
|
|
991
1415
|
for (const prepared of preparedPolicies) await prepared.policy.consume?.(prepared.contribution);
|
|
992
1416
|
}
|
|
993
1417
|
async releasePolicies(preparedPolicies, reason) {
|
|
1418
|
+
if (isD1Database(this.options.db)) return;
|
|
994
1419
|
for (const prepared of preparedPolicies.toReversed()) await prepared.policy.release?.(prepared.contribution, reason);
|
|
995
1420
|
}
|
|
996
1421
|
async releaseReplacedPolicies(contributions, currentPolicies) {
|
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import { r as getDb } from "./loader-
|
|
2
|
-
import { n as cachedQuery, t as CacheNamespace } from "./object-cache-
|
|
3
|
-
import { r as requestCached } from "./request-cache-
|
|
4
|
-
import { n as SchemaRegistry } from "./registry-
|
|
1
|
+
import { r as getDb } from "./loader-Cgsx23wU.mjs";
|
|
2
|
+
import { n as cachedQuery, t as CacheNamespace } from "./object-cache-BGjIlY9s.mjs";
|
|
3
|
+
import { r as requestCached } from "./request-cache-DPmV5nk4.mjs";
|
|
4
|
+
import { n as SchemaRegistry } from "./registry-DcV93OL_.mjs";
|
|
5
5
|
|
|
6
6
|
//#region src/schema/query.ts
|
|
7
7
|
/**
|