emdash 0.35.0 → 0.37.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/activation-K0kGBWuJ.mjs +382 -0
- package/dist/activation-K0kGBWuJ.mjs.map +1 -0
- package/dist/{adapters-Bb1vG41D.d.mts → adapters-BDQwg236.d.mts} +6 -4
- package/dist/{adapters-Bb1vG41D.d.mts.map → adapters-BDQwg236.d.mts.map} +1 -1
- package/dist/{allowed-origins-DW7sYyqg.mjs → allowed-origins-BGglilcs.mjs} +2 -2
- package/dist/{allowed-origins-DW7sYyqg.mjs.map → allowed-origins-BGglilcs.mjs.map} +1 -1
- package/dist/api/route-utils.d.mts +3 -3
- package/dist/api/route-utils.mjs +23 -21
- package/dist/api/route-utils.mjs.map +1 -1
- package/dist/api/schemas/index.d.mts +2 -2
- package/dist/api/schemas/index.mjs +5 -5
- package/dist/api-Dz6rgoa3.mjs +10040 -0
- package/dist/api-Dz6rgoa3.mjs.map +1 -0
- package/dist/{api-tokens-KO24G1Fd.mjs → api-tokens-BSsQACNe.mjs} +2 -2
- package/dist/{api-tokens-KO24G1Fd.mjs.map → api-tokens-BSsQACNe.mjs.map} +1 -1
- package/dist/{apply-kUDt80-G.mjs → apply-B4SIOxR1.mjs} +34 -35
- package/dist/{apply-kUDt80-G.mjs.map → apply-B4SIOxR1.mjs.map} +1 -1
- package/dist/astro/image-endpoint.mjs +2 -2
- package/dist/astro/image-endpoint.mjs.map +1 -1
- package/dist/astro/index.d.mts +12 -12
- package/dist/astro/index.d.mts.map +1 -1
- package/dist/astro/index.mjs +128 -44
- package/dist/astro/index.mjs.map +1 -1
- package/dist/astro/middleware/auth.d.mts +10 -10
- package/dist/astro/middleware/auth.d.mts.map +1 -1
- package/dist/astro/middleware/auth.mjs +10 -7
- package/dist/astro/middleware/auth.mjs.map +1 -1
- package/dist/astro/middleware/media-usage-write-fence.mjs +2 -2
- package/dist/astro/middleware/redirect.mjs +4 -4
- package/dist/astro/middleware/request-context.mjs +3 -3
- package/dist/astro/middleware/setup.mjs +1 -1
- package/dist/astro/middleware.d.mts +11 -12
- package/dist/astro/middleware.d.mts.map +1 -1
- package/dist/astro/middleware.mjs +237 -1412
- package/dist/astro/middleware.mjs.map +1 -1
- package/dist/astro/routes/api/admin/allowed-domains/_domain_.mjs +6 -6
- package/dist/astro/routes/api/admin/allowed-domains/index.mjs +6 -6
- package/dist/astro/routes/api/admin/api-tokens/_id_.mjs +3 -3
- package/dist/astro/routes/api/admin/api-tokens/index.d.mts.map +1 -1
- package/dist/astro/routes/api/admin/api-tokens/index.mjs +5 -5
- package/dist/astro/routes/api/admin/api-tokens/index.mjs.map +1 -1
- package/dist/astro/routes/api/admin/byline-fields/_slug_/usage.mjs +4 -4
- package/dist/astro/routes/api/admin/byline-fields/_slug_.mjs +9 -9
- package/dist/astro/routes/api/admin/byline-fields/index.mjs +9 -9
- package/dist/astro/routes/api/admin/byline-fields/reorder.mjs +9 -9
- package/dist/astro/routes/api/admin/bylines/_id_/index.mjs +16 -16
- package/dist/astro/routes/api/admin/bylines/_id_/translations.mjs +16 -16
- package/dist/astro/routes/api/admin/bylines/index.mjs +16 -16
- package/dist/astro/routes/api/admin/comments/_id_/status.mjs +13 -13
- package/dist/astro/routes/api/admin/comments/_id_.mjs +5 -5
- package/dist/astro/routes/api/admin/comments/bulk.mjs +10 -10
- package/dist/astro/routes/api/admin/comments/counts.mjs +5 -5
- package/dist/astro/routes/api/admin/comments/index.mjs +10 -10
- package/dist/astro/routes/api/admin/hooks/exclusive/_hookName_.mjs +4 -4
- package/dist/astro/routes/api/admin/hooks/exclusive/index.mjs +3 -3
- package/dist/astro/routes/api/admin/media-usage/activation.d.mts +9 -0
- package/dist/astro/routes/api/admin/media-usage/activation.d.mts.map +1 -0
- package/dist/astro/routes/api/admin/media-usage/activation.mjs +46 -0
- package/dist/astro/routes/api/admin/media-usage/activation.mjs.map +1 -0
- package/dist/astro/routes/api/admin/media-usage/collection-deletions/index.mjs +14 -13
- package/dist/astro/routes/api/admin/media-usage/collection-deletions/index.mjs.map +1 -1
- package/dist/astro/routes/api/admin/media-usage/collection-deletions/retry.mjs +14 -13
- package/dist/astro/routes/api/admin/media-usage/collection-deletions/retry.mjs.map +1 -1
- package/dist/astro/routes/api/admin/media-usage/progress.d.mts +9 -0
- package/dist/astro/routes/api/admin/media-usage/progress.d.mts.map +1 -0
- package/dist/astro/routes/api/admin/media-usage/progress.mjs +44 -0
- package/dist/astro/routes/api/admin/media-usage/progress.mjs.map +1 -0
- package/dist/astro/routes/api/admin/media-usage/repair.mjs +16 -11
- package/dist/astro/routes/api/admin/media-usage/repair.mjs.map +1 -1
- package/dist/astro/routes/api/admin/media-usage/work/index.mjs +14 -13
- package/dist/astro/routes/api/admin/media-usage/work/index.mjs.map +1 -1
- package/dist/astro/routes/api/admin/media-usage/work/retry.mjs +14 -13
- package/dist/astro/routes/api/admin/media-usage/work/retry.mjs.map +1 -1
- package/dist/astro/routes/api/admin/oauth-clients/_id_.mjs +4 -4
- package/dist/astro/routes/api/admin/oauth-clients/_id_.mjs.map +1 -1
- package/dist/astro/routes/api/admin/oauth-clients/index.mjs +4 -4
- package/dist/astro/routes/api/admin/oauth-clients/index.mjs.map +1 -1
- package/dist/astro/routes/api/admin/plugins/_id_/disable.mjs +55 -49
- package/dist/astro/routes/api/admin/plugins/_id_/disable.mjs.map +1 -1
- package/dist/astro/routes/api/admin/plugins/_id_/enable.mjs +55 -49
- package/dist/astro/routes/api/admin/plugins/_id_/enable.mjs.map +1 -1
- package/dist/astro/routes/api/admin/plugins/_id_/index.mjs +53 -47
- package/dist/astro/routes/api/admin/plugins/_id_/index.mjs.map +1 -1
- package/dist/astro/routes/api/admin/plugins/_id_/mcp.mjs +4 -4
- package/dist/astro/routes/api/admin/plugins/_id_/settings.mjs +53 -47
- package/dist/astro/routes/api/admin/plugins/_id_/settings.mjs.map +1 -1
- package/dist/astro/routes/api/admin/plugins/_id_/uninstall.mjs +54 -48
- package/dist/astro/routes/api/admin/plugins/_id_/uninstall.mjs.map +1 -1
- package/dist/astro/routes/api/admin/plugins/_id_/update.mjs +54 -48
- package/dist/astro/routes/api/admin/plugins/_id_/update.mjs.map +1 -1
- package/dist/astro/routes/api/admin/plugins/index.mjs +53 -47
- package/dist/astro/routes/api/admin/plugins/index.mjs.map +1 -1
- package/dist/astro/routes/api/admin/plugins/marketplace/_id_/icon.mjs +2 -2
- package/dist/astro/routes/api/admin/plugins/marketplace/_id_/index.mjs +53 -47
- package/dist/astro/routes/api/admin/plugins/marketplace/_id_/index.mjs.map +1 -1
- package/dist/astro/routes/api/admin/plugins/marketplace/_id_/install.mjs +54 -48
- package/dist/astro/routes/api/admin/plugins/marketplace/_id_/install.mjs.map +1 -1
- package/dist/astro/routes/api/admin/plugins/marketplace/index.mjs +53 -47
- package/dist/astro/routes/api/admin/plugins/marketplace/index.mjs.map +1 -1
- package/dist/astro/routes/api/admin/plugins/registry/_id_/uninstall.mjs +54 -48
- package/dist/astro/routes/api/admin/plugins/registry/_id_/uninstall.mjs.map +1 -1
- package/dist/astro/routes/api/admin/plugins/registry/_id_/update.d.mts.map +1 -1
- package/dist/astro/routes/api/admin/plugins/registry/_id_/update.mjs +60 -50
- package/dist/astro/routes/api/admin/plugins/registry/_id_/update.mjs.map +1 -1
- package/dist/astro/routes/api/admin/plugins/registry/artifact.d.mts.map +1 -1
- package/dist/astro/routes/api/admin/plugins/registry/artifact.mjs +179 -139
- package/dist/astro/routes/api/admin/plugins/registry/artifact.mjs.map +1 -1
- package/dist/astro/routes/api/admin/plugins/registry/install.d.mts.map +1 -1
- package/dist/astro/routes/api/admin/plugins/registry/install.mjs +61 -51
- package/dist/astro/routes/api/admin/plugins/registry/install.mjs.map +1 -1
- package/dist/astro/routes/api/admin/plugins/registry/verify.d.mts +8 -0
- package/dist/astro/routes/api/admin/plugins/registry/verify.d.mts.map +1 -0
- package/dist/astro/routes/api/admin/plugins/registry/verify.mjs +93 -0
- package/dist/astro/routes/api/admin/plugins/registry/verify.mjs.map +1 -0
- package/dist/astro/routes/api/admin/plugins/updates.mjs +53 -47
- package/dist/astro/routes/api/admin/plugins/updates.mjs.map +1 -1
- package/dist/astro/routes/api/admin/themes/marketplace/_id_/index.mjs +53 -47
- package/dist/astro/routes/api/admin/themes/marketplace/_id_/index.mjs.map +1 -1
- package/dist/astro/routes/api/admin/themes/marketplace/_id_/thumbnail.mjs +2 -2
- package/dist/astro/routes/api/admin/themes/marketplace/index.mjs +53 -47
- package/dist/astro/routes/api/admin/themes/marketplace/index.mjs.map +1 -1
- package/dist/astro/routes/api/admin/users/_id_/disable.mjs +2 -2
- package/dist/astro/routes/api/admin/users/_id_/enable.mjs +1 -1
- package/dist/astro/routes/api/admin/users/_id_/index.mjs +7 -7
- package/dist/astro/routes/api/admin/users/_id_/send-recovery.mjs +3 -3
- package/dist/astro/routes/api/admin/users/index.mjs +6 -6
- package/dist/astro/routes/api/auth/dev-bypass.mjs +3 -3
- package/dist/astro/routes/api/auth/invite/accept.mjs +1 -1
- package/dist/astro/routes/api/auth/invite/complete.mjs +11 -11
- package/dist/astro/routes/api/auth/invite/index.mjs +8 -8
- package/dist/astro/routes/api/auth/invite/register-options.mjs +10 -10
- package/dist/astro/routes/api/auth/logout.mjs +2 -2
- package/dist/astro/routes/api/auth/magic-link/send.mjs +10 -10
- package/dist/astro/routes/api/auth/magic-link/verify.mjs +2 -2
- package/dist/astro/routes/api/auth/me.d.mts.map +1 -1
- package/dist/astro/routes/api/auth/me.mjs +19 -9
- package/dist/astro/routes/api/auth/me.mjs.map +1 -1
- package/dist/astro/routes/api/auth/mode.mjs +2 -2
- package/dist/astro/routes/api/auth/oauth/_provider_/callback.mjs +4 -4
- package/dist/astro/routes/api/auth/oauth/_provider_.mjs +2 -2
- package/dist/astro/routes/api/auth/passkey/_id_.mjs +6 -6
- package/dist/astro/routes/api/auth/passkey/index.mjs +1 -1
- package/dist/astro/routes/api/auth/passkey/options.mjs +12 -12
- package/dist/astro/routes/api/auth/passkey/register/options.mjs +10 -10
- package/dist/astro/routes/api/auth/passkey/register/verify.mjs +11 -11
- package/dist/astro/routes/api/auth/passkey/verify.mjs +11 -11
- package/dist/astro/routes/api/auth/signup/complete.mjs +11 -11
- package/dist/astro/routes/api/auth/signup/request.mjs +10 -10
- package/dist/astro/routes/api/auth/signup/verify.mjs +1 -1
- package/dist/astro/routes/api/comments/_collection_/_contentId_/index.mjs +14 -14
- package/dist/astro/routes/api/comments/_collection_/_contentId_/reactions.mjs +13 -13
- package/dist/astro/routes/api/content/_collection_/_id_/compare.mjs +2 -2
- package/dist/astro/routes/api/content/_collection_/_id_/discard-draft.d.mts.map +1 -1
- package/dist/astro/routes/api/content/_collection_/_id_/discard-draft.mjs +14 -5
- package/dist/astro/routes/api/content/_collection_/_id_/discard-draft.mjs.map +1 -1
- package/dist/astro/routes/api/content/_collection_/_id_/duplicate.mjs +3 -3
- package/dist/astro/routes/api/content/_collection_/_id_/permanent.mjs +2 -2
- package/dist/astro/routes/api/content/_collection_/_id_/preview-url.mjs +11 -11
- package/dist/astro/routes/api/content/_collection_/_id_/publish.mjs +13 -10
- package/dist/astro/routes/api/content/_collection_/_id_/publish.mjs.map +1 -1
- package/dist/astro/routes/api/content/_collection_/_id_/references/_relation_/children.mjs +17 -15
- package/dist/astro/routes/api/content/_collection_/_id_/references/_relation_/children.mjs.map +1 -1
- package/dist/astro/routes/api/content/_collection_/_id_/references/_relation_/parents.mjs +17 -15
- package/dist/astro/routes/api/content/_collection_/_id_/references/_relation_/parents.mjs.map +1 -1
- package/dist/astro/routes/api/content/_collection_/_id_/restore.mjs +3 -3
- package/dist/astro/routes/api/content/_collection_/_id_/revisions.mjs +2 -2
- package/dist/astro/routes/api/content/_collection_/_id_/schedule.mjs +8 -8
- package/dist/astro/routes/api/content/_collection_/_id_/terms/_taxonomy_.mjs +14 -14
- package/dist/astro/routes/api/content/_collection_/_id_/translations.mjs +2 -2
- package/dist/astro/routes/api/content/_collection_/_id_/unpublish.d.mts.map +1 -1
- package/dist/astro/routes/api/content/_collection_/_id_/unpublish.mjs +14 -5
- package/dist/astro/routes/api/content/_collection_/_id_/unpublish.mjs.map +1 -1
- package/dist/astro/routes/api/content/_collection_/_id_.mjs +8 -8
- package/dist/astro/routes/api/content/_collection_/authors.mjs +2 -2
- package/dist/astro/routes/api/content/_collection_/index.mjs +8 -8
- package/dist/astro/routes/api/content/_collection_/trash.mjs +7 -7
- package/dist/astro/routes/api/dashboard.mjs +8 -8
- package/dist/astro/routes/api/dev/emails.mjs +2 -2
- package/dist/astro/routes/api/import/probe.d.mts +3 -3
- package/dist/astro/routes/api/import/probe.mjs +17 -17
- package/dist/astro/routes/api/import/wordpress/analyze.mjs +2 -2
- package/dist/astro/routes/api/import/wordpress/execute.d.mts +11 -11
- package/dist/astro/routes/api/import/wordpress/execute.mjs +13 -13
- package/dist/astro/routes/api/import/wordpress/media.d.mts +10 -10
- package/dist/astro/routes/api/import/wordpress/media.mjs +11 -11
- package/dist/astro/routes/api/import/wordpress/prepare.mjs +9 -9
- package/dist/astro/routes/api/import/wordpress/rewrite-urls.d.mts +11 -11
- package/dist/astro/routes/api/import/wordpress/rewrite-urls.mjs +12 -10
- package/dist/astro/routes/api/import/wordpress/rewrite-urls.mjs.map +1 -1
- package/dist/astro/routes/api/import/wordpress-plugin/analyze.d.mts +1 -1
- package/dist/astro/routes/api/import/wordpress-plugin/analyze.mjs +17 -17
- package/dist/astro/routes/api/import/wordpress-plugin/execute.d.mts +11 -11
- package/dist/astro/routes/api/import/wordpress-plugin/execute.mjs +27 -27
- package/dist/astro/routes/api/manifest.mjs +4 -4
- package/dist/astro/routes/api/manifest.mjs.map +1 -1
- package/dist/astro/routes/api/mcp.mjs +188 -65
- package/dist/astro/routes/api/mcp.mjs.map +1 -1
- package/dist/astro/routes/api/media/_id_/confirm.mjs +11 -11
- package/dist/astro/routes/api/media/_id_/replace.d.mts +8 -0
- package/dist/astro/routes/api/media/_id_/replace.d.mts.map +1 -0
- package/dist/astro/routes/api/media/_id_/replace.mjs +91 -0
- package/dist/astro/routes/api/media/_id_/replace.mjs.map +1 -0
- package/dist/astro/routes/api/media/_id_/upload.mjs +6 -6
- package/dist/astro/routes/api/media/_id_/usage.mjs +18 -13
- package/dist/astro/routes/api/media/_id_/usage.mjs.map +1 -1
- package/dist/astro/routes/api/media/_id_.d.mts.map +1 -1
- package/dist/astro/routes/api/media/_id_.mjs +21 -13
- package/dist/astro/routes/api/media/_id_.mjs.map +1 -1
- package/dist/astro/routes/api/media/file/_...key_.d.mts.map +1 -1
- package/dist/astro/routes/api/media/file/_...key_.mjs +3 -2
- package/dist/astro/routes/api/media/file/_...key_.mjs.map +1 -1
- package/dist/astro/routes/api/media/folders/_id_.d.mts +10 -0
- package/dist/astro/routes/api/media/folders/_id_.d.mts.map +1 -0
- package/dist/astro/routes/api/media/folders/_id_.mjs +52 -0
- package/dist/astro/routes/api/media/folders/_id_.mjs.map +1 -0
- package/dist/astro/routes/api/media/folders/index.d.mts +9 -0
- package/dist/astro/routes/api/media/folders/index.d.mts.map +1 -0
- package/dist/astro/routes/api/media/folders/index.mjs +41 -0
- package/dist/astro/routes/api/media/folders/index.mjs.map +1 -0
- 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 +16 -14
- package/dist/astro/routes/api/media/upload-url.mjs.map +1 -1
- package/dist/astro/routes/api/media.d.mts.map +1 -1
- package/dist/astro/routes/api/media.mjs +59 -27
- package/dist/astro/routes/api/media.mjs.map +1 -1
- package/dist/astro/routes/api/menus/_name_/items/_id_.d.mts.map +1 -1
- package/dist/astro/routes/api/menus/_name_/items/_id_.mjs +20 -13
- package/dist/astro/routes/api/menus/_name_/items/_id_.mjs.map +1 -1
- package/dist/astro/routes/api/menus/_name_/items.d.mts.map +1 -1
- package/dist/astro/routes/api/menus/_name_/items.mjs +15 -11
- package/dist/astro/routes/api/menus/_name_/items.mjs.map +1 -1
- package/dist/astro/routes/api/menus/_name_/reorder.d.mts.map +1 -1
- package/dist/astro/routes/api/menus/_name_/reorder.mjs +15 -11
- package/dist/astro/routes/api/menus/_name_/reorder.mjs.map +1 -1
- package/dist/astro/routes/api/menus/_name_/translations.d.mts.map +1 -1
- package/dist/astro/routes/api/menus/_name_/translations.mjs +16 -12
- package/dist/astro/routes/api/menus/_name_/translations.mjs.map +1 -1
- package/dist/astro/routes/api/menus/_name_.d.mts.map +1 -1
- package/dist/astro/routes/api/menus/_name_.mjs +21 -14
- package/dist/astro/routes/api/menus/_name_.mjs.map +1 -1
- package/dist/astro/routes/api/menus/index.d.mts.map +1 -1
- package/dist/astro/routes/api/menus/index.mjs +15 -11
- package/dist/astro/routes/api/menus/index.mjs.map +1 -1
- package/dist/astro/routes/api/oauth/authorize.mjs +6 -6
- package/dist/astro/routes/api/oauth/device/authorize.mjs +5 -5
- package/dist/astro/routes/api/oauth/device/code.mjs +8 -8
- package/dist/astro/routes/api/oauth/device/token.mjs +7 -7
- package/dist/astro/routes/api/oauth/register.mjs +2 -2
- package/dist/astro/routes/api/oauth/token/refresh.mjs +5 -5
- package/dist/astro/routes/api/oauth/token/revoke.mjs +5 -5
- package/dist/astro/routes/api/oauth/token.mjs +5 -5
- package/dist/astro/routes/api/openapi.json.mjs +253 -40
- package/dist/astro/routes/api/openapi.json.mjs.map +1 -1
- package/dist/astro/routes/api/plugins/_pluginId_/_...path_.mjs +4 -4
- package/dist/astro/routes/api/redirects/404s/index.mjs +10 -10
- package/dist/astro/routes/api/redirects/404s/summary.mjs +10 -10
- package/dist/astro/routes/api/redirects/_id_.mjs +11 -11
- package/dist/astro/routes/api/redirects/index.mjs +11 -11
- package/dist/astro/routes/api/relations/_id_/index.mjs +17 -15
- package/dist/astro/routes/api/relations/_id_/index.mjs.map +1 -1
- package/dist/astro/routes/api/relations/_id_/translations.mjs +12 -10
- package/dist/astro/routes/api/relations/_id_/translations.mjs.map +1 -1
- package/dist/astro/routes/api/relations/index.mjs +17 -15
- package/dist/astro/routes/api/relations/index.mjs.map +1 -1
- package/dist/astro/routes/api/revisions/_revisionId_/index.mjs +2 -2
- package/dist/astro/routes/api/revisions/_revisionId_/restore.mjs +3 -3
- package/dist/astro/routes/api/schema/collections/_slug_/fields/_fieldSlug_.mjs +53 -47
- package/dist/astro/routes/api/schema/collections/_slug_/fields/_fieldSlug_.mjs.map +1 -1
- package/dist/astro/routes/api/schema/collections/_slug_/fields/index.mjs +53 -47
- package/dist/astro/routes/api/schema/collections/_slug_/fields/index.mjs.map +1 -1
- package/dist/astro/routes/api/schema/collections/_slug_/fields/reorder.mjs +53 -47
- package/dist/astro/routes/api/schema/collections/_slug_/fields/reorder.mjs.map +1 -1
- package/dist/astro/routes/api/schema/collections/_slug_/index.mjs +53 -47
- package/dist/astro/routes/api/schema/collections/_slug_/index.mjs.map +1 -1
- package/dist/astro/routes/api/schema/collections/index.mjs +53 -47
- package/dist/astro/routes/api/schema/collections/index.mjs.map +1 -1
- package/dist/astro/routes/api/schema/collections/reorder.mjs +53 -47
- package/dist/astro/routes/api/schema/collections/reorder.mjs.map +1 -1
- package/dist/astro/routes/api/schema/index.mjs +10 -8
- package/dist/astro/routes/api/schema/index.mjs.map +1 -1
- package/dist/astro/routes/api/schema/orphans/_slug_.mjs +53 -47
- package/dist/astro/routes/api/schema/orphans/_slug_.mjs.map +1 -1
- package/dist/astro/routes/api/schema/orphans/index.mjs +53 -47
- package/dist/astro/routes/api/schema/orphans/index.mjs.map +1 -1
- package/dist/astro/routes/api/search/enable.mjs +10 -10
- package/dist/astro/routes/api/search/index.mjs +9 -9
- package/dist/astro/routes/api/search/rebuild.mjs +10 -10
- package/dist/astro/routes/api/search/stats.mjs +5 -5
- package/dist/astro/routes/api/search/suggest.mjs +9 -9
- package/dist/astro/routes/api/sections/_slug_.mjs +9 -9
- package/dist/astro/routes/api/sections/index.mjs +9 -9
- package/dist/astro/routes/api/settings/backups/archives/_name_.mjs +6 -6
- package/dist/astro/routes/api/settings/backups/archives/index.mjs +5 -5
- package/dist/astro/routes/api/settings/backups/export.mjs +6 -6
- package/dist/astro/routes/api/settings/backups/index.mjs +7 -7
- package/dist/astro/routes/api/settings/email.mjs +5 -5
- package/dist/astro/routes/api/settings/email.mjs.map +1 -1
- package/dist/astro/routes/api/settings.d.mts.map +1 -1
- package/dist/astro/routes/api/settings.mjs +20 -16
- package/dist/astro/routes/api/settings.mjs.map +1 -1
- package/dist/astro/routes/api/setup/admin-verify.mjs +12 -12
- package/dist/astro/routes/api/setup/admin.mjs +11 -11
- package/dist/astro/routes/api/setup/dev-bypass.d.mts.map +1 -1
- package/dist/astro/routes/api/setup/dev-bypass.mjs +35 -28
- package/dist/astro/routes/api/setup/dev-bypass.mjs.map +1 -1
- package/dist/astro/routes/api/setup/dev-reset.mjs +2 -2
- package/dist/astro/routes/api/setup/index.mjs +32 -30
- package/dist/astro/routes/api/setup/index.mjs.map +1 -1
- package/dist/astro/routes/api/setup/status.mjs +3 -3
- package/dist/astro/routes/api/snapshot.mjs +7 -7
- package/dist/astro/routes/api/taxonomies/_name_/reorder.d.mts.map +1 -1
- package/dist/astro/routes/api/taxonomies/_name_/reorder.mjs +20 -16
- package/dist/astro/routes/api/taxonomies/_name_/reorder.mjs.map +1 -1
- package/dist/astro/routes/api/taxonomies/_name_/terms/_slug_/translations.d.mts.map +1 -1
- package/dist/astro/routes/api/taxonomies/_name_/terms/_slug_/translations.mjs +21 -17
- package/dist/astro/routes/api/taxonomies/_name_/terms/_slug_/translations.mjs.map +1 -1
- package/dist/astro/routes/api/taxonomies/_name_/terms/_slug_.d.mts.map +1 -1
- package/dist/astro/routes/api/taxonomies/_name_/terms/_slug_.mjs +25 -18
- package/dist/astro/routes/api/taxonomies/_name_/terms/_slug_.mjs.map +1 -1
- package/dist/astro/routes/api/taxonomies/_name_/terms/index.d.mts.map +1 -1
- package/dist/astro/routes/api/taxonomies/_name_/terms/index.mjs +20 -16
- package/dist/astro/routes/api/taxonomies/_name_/terms/index.mjs.map +1 -1
- package/dist/astro/routes/api/taxonomies/_name_/translations.mjs +14 -14
- package/dist/astro/routes/api/taxonomies/_name_.d.mts.map +1 -1
- package/dist/astro/routes/api/taxonomies/_name_.mjs +26 -19
- package/dist/astro/routes/api/taxonomies/_name_.mjs.map +1 -1
- package/dist/astro/routes/api/taxonomies/index.d.mts.map +1 -1
- package/dist/astro/routes/api/taxonomies/index.mjs +20 -16
- package/dist/astro/routes/api/taxonomies/index.mjs.map +1 -1
- package/dist/astro/routes/api/themes/preview.mjs +5 -5
- package/dist/astro/routes/api/typegen.mjs +4 -4
- package/dist/astro/routes/api/well-known/auth.mjs +2 -2
- package/dist/astro/routes/api/well-known/oauth-authorization-server.mjs +2 -2
- package/dist/astro/routes/api/well-known/oauth-protected-resource.mjs +2 -2
- package/dist/astro/routes/api/widget-areas/_name_/reorder.d.mts.map +1 -1
- package/dist/astro/routes/api/widget-areas/_name_/reorder.mjs +10 -8
- package/dist/astro/routes/api/widget-areas/_name_/reorder.mjs.map +1 -1
- package/dist/astro/routes/api/widget-areas/_name_/widgets/_id_.d.mts.map +1 -1
- package/dist/astro/routes/api/widget-areas/_name_/widgets/_id_.mjs +17 -13
- package/dist/astro/routes/api/widget-areas/_name_/widgets/_id_.mjs.map +1 -1
- package/dist/astro/routes/api/widget-areas/_name_/widgets.d.mts.map +1 -1
- package/dist/astro/routes/api/widget-areas/_name_/widgets.mjs +15 -12
- package/dist/astro/routes/api/widget-areas/_name_/widgets.mjs.map +1 -1
- package/dist/astro/routes/api/widget-areas/_name_.d.mts.map +1 -1
- package/dist/astro/routes/api/widget-areas/_name_.mjs +8 -6
- package/dist/astro/routes/api/widget-areas/_name_.mjs.map +1 -1
- package/dist/astro/routes/api/widget-areas/index.d.mts.map +1 -1
- package/dist/astro/routes/api/widget-areas/index.mjs +15 -12
- package/dist/astro/routes/api/widget-areas/index.mjs.map +1 -1
- package/dist/astro/routes/api/widget-components.mjs +2 -2
- package/dist/astro/routes/robots.txt.mjs +7 -7
- package/dist/astro/routes/sitemap-_collection_.xml.mjs +10 -10
- package/dist/astro/routes/sitemap.xml.mjs +8 -8
- package/dist/astro/types.d.mts +37 -17
- package/dist/astro/types.d.mts.map +1 -1
- package/dist/auth/providers/github.d.mts +1 -1
- package/dist/auth/providers/google.d.mts +1 -1
- package/dist/{authorize-DUElxgOQ.mjs → authorize-Bkf_UHhD.mjs} +2 -2
- package/dist/{authorize-DUElxgOQ.mjs.map → authorize-Bkf_UHhD.mjs.map} +1 -1
- package/dist/{backup-DWYpJlLj.mjs → backup-rwVAl9NI.mjs} +5 -5
- package/dist/{backup-DWYpJlLj.mjs.map → backup-rwVAl9NI.mjs.map} +1 -1
- package/dist/{bundle-vn56sLos.mjs → bundle-C8S2Zl6U.mjs} +4 -4
- package/dist/{bundle-vn56sLos.mjs.map → bundle-C8S2Zl6U.mjs.map} +1 -1
- package/dist/{byline-yjvWq4ip.mjs → byline-DuhF7NWl.mjs} +27 -14
- package/dist/byline-DuhF7NWl.mjs.map +1 -0
- package/dist/{byline-fields-txaLGoME.mjs → byline-fields-BovY4KYM.mjs} +2 -2
- package/dist/{byline-fields-txaLGoME.mjs.map → byline-fields-BovY4KYM.mjs.map} +1 -1
- package/dist/{byline-registry-DDun8sxh.mjs → byline-registry-Bpu9-MVs.mjs} +2 -2
- package/dist/{byline-registry-DDun8sxh.mjs.map → byline-registry-Bpu9-MVs.mjs.map} +1 -1
- package/dist/{bylines-DjXS5p0P.mjs → bylines-CJ5nd6Lw.mjs} +7 -7
- package/dist/{bylines-DjXS5p0P.mjs.map → bylines-CJ5nd6Lw.mjs.map} +1 -1
- package/dist/{bylines-Bu7pchQ4.mjs → bylines-RwBAeOF1.mjs} +3 -3
- package/dist/{bylines-Bu7pchQ4.mjs.map → bylines-RwBAeOF1.mjs.map} +1 -1
- package/dist/{cache-C46-3Irl.mjs → cache-BF5Kvn59.mjs} +4 -4
- package/dist/{cache-C46-3Irl.mjs.map → cache-BF5Kvn59.mjs.map} +1 -1
- package/dist/capture-triggers-CNW1q3HK.mjs +362 -0
- package/dist/capture-triggers-CNW1q3HK.mjs.map +1 -0
- package/dist/{challenge-store-SIL5DsF2.mjs → challenge-store-DQN_Yrck.mjs} +5 -3
- package/dist/challenge-store-DQN_Yrck.mjs.map +1 -0
- package/dist/chrome-tags-D8fiZG94.mjs +24 -0
- package/dist/chrome-tags-D8fiZG94.mjs.map +1 -0
- package/dist/{chunks-fiZ8G9RJ.mjs → chunks-C4szrD8o.mjs} +2 -2
- package/dist/{chunks-fiZ8G9RJ.mjs.map → chunks-C4szrD8o.mjs.map} +1 -1
- package/dist/cli/index.mjs +37 -53
- package/dist/cli/index.mjs.map +1 -1
- package/dist/client/cf-access.d.mts +1 -1
- package/dist/client/index.d.mts +74 -4
- package/dist/client/index.d.mts.map +1 -1
- package/dist/client/index.mjs +54 -2
- package/dist/client/index.mjs.map +1 -1
- package/dist/{collection-deletion-DQPvMD8R.mjs → collection-deletion-Bj07NHbj.mjs} +13 -356
- package/dist/collection-deletion-Bj07NHbj.mjs.map +1 -0
- package/dist/{comment-reaction-D-2J84UE.mjs → comment-reaction-BhrvSHml.mjs} +2 -2
- package/dist/{comment-reaction-D-2J84UE.mjs.map → comment-reaction-BhrvSHml.mjs.map} +1 -1
- package/dist/{comment-Dxlep6cE.mjs → comment-vxOzWbZN.mjs} +2 -2
- package/dist/{comment-Dxlep6cE.mjs.map → comment-vxOzWbZN.mjs.map} +1 -1
- package/dist/{comments-CTfZtLmM.mjs → comments-Ct4ensnf.mjs} +2 -2
- package/dist/{comments-CTfZtLmM.mjs.map → comments-Ct4ensnf.mjs.map} +1 -1
- package/dist/{components-CQy3lh9x.mjs → components-DJbo1z0S.mjs} +1 -1
- package/dist/{components-CQy3lh9x.mjs.map → components-DJbo1z0S.mjs.map} +1 -1
- package/dist/{config-COQzTe5Q.d.mts → config-B9eZ340f.d.mts} +1 -1
- package/dist/{config-COQzTe5Q.d.mts.map → config-B9eZ340f.d.mts.map} +1 -1
- package/dist/config-it29yDLA.mjs +1163 -0
- package/dist/config-it29yDLA.mjs.map +1 -0
- package/dist/{content-ZHCc1ngN.mjs → content-DjvM0T92.mjs} +86 -45
- package/dist/content-DjvM0T92.mjs.map +1 -0
- package/dist/{content-list-query-wJ2WN8Vp.d.mts → content-list-query-Btqd4uV2.d.mts} +1 -1
- package/dist/{content-list-query-wJ2WN8Vp.d.mts.map → content-list-query-Btqd4uV2.d.mts.map} +1 -1
- package/dist/{content-refresh-B_8SJzuU.mjs → content-refresh-Bwp-8yGy.mjs} +1139 -111
- package/dist/content-refresh-Bwp-8yGy.mjs.map +1 -0
- package/dist/{media-usage-BZCydfvu.mjs → content-repair-Czdp7jz5.mjs} +5 -196
- package/dist/content-repair-Czdp7jz5.mjs.map +1 -0
- package/dist/{context-ZldbZcle.mjs → context-CX6gxOLW.mjs} +55 -20
- package/dist/context-CX6gxOLW.mjs.map +1 -0
- package/dist/{cron-Y9aLtgrA.mjs → cron-C6o7VppJ.mjs} +1 -1
- package/dist/{cron-Y9aLtgrA.mjs.map → cron-C6o7VppJ.mjs.map} +1 -1
- package/dist/{dashboard-DvHbk_cv.mjs → dashboard-C2kTeeRI.mjs} +5 -5
- package/dist/{dashboard-DvHbk_cv.mjs.map → dashboard-C2kTeeRI.mjs.map} +1 -1
- package/dist/db/index.d.mts +3 -3
- package/dist/db/index.mjs +3 -3
- package/dist/db/index.mjs.map +1 -1
- package/dist/db/libsql-migrations.d.mts +1 -1
- package/dist/db/libsql-migrations.mjs +4 -4
- package/dist/db/libsql.d.mts +1 -1
- package/dist/db/postgres-migrations.d.mts +1 -1
- package/dist/db/postgres-migrations.mjs +4 -4
- package/dist/db/postgres.d.mts +1 -1
- package/dist/db/postgres.d.mts.map +1 -1
- package/dist/db/postgres.mjs +19 -3
- package/dist/db/postgres.mjs.map +1 -1
- package/dist/db/sqlite-migrations.d.mts +1 -1
- package/dist/db/sqlite-migrations.mjs +4 -4
- package/dist/db/sqlite.d.mts +1 -1
- package/dist/db/sqlite.mjs +3 -3
- package/dist/db/sqlite.mjs.map +1 -1
- package/dist/{default-DdDl3fxv.mjs → default-Clra32mw.mjs} +1 -1
- package/dist/{default-DdDl3fxv.mjs.map → default-Clra32mw.mjs.map} +1 -1
- package/dist/{deferred-tasks-SDWxrgzJ.d.mts → deferred-tasks-CvDETTJO.d.mts} +1 -1
- package/dist/{deferred-tasks-SDWxrgzJ.d.mts.map → deferred-tasks-CvDETTJO.d.mts.map} +1 -1
- package/dist/dev-typegen-DzOPfsNj.mjs +29 -0
- package/dist/dev-typegen-DzOPfsNj.mjs.map +1 -0
- package/dist/{device-flow-C0GdD_z8.mjs → device-flow-D2oCWvLJ.mjs} +5 -5
- package/dist/{device-flow-C0GdD_z8.mjs.map → device-flow-D2oCWvLJ.mjs.map} +1 -1
- package/dist/{direct-executor-CDXeJCSs.mjs → direct-executor-Bfa5_ToE.mjs} +3 -3
- package/dist/{direct-executor-CDXeJCSs.mjs.map → direct-executor-Bfa5_ToE.mjs.map} +1 -1
- package/dist/{dist-D_6CKR8z.mjs → dist-89xCrGqi.mjs} +1 -1
- package/dist/{dist-D_6CKR8z.mjs.map → dist-89xCrGqi.mjs.map} +1 -1
- package/dist/{email-console-BHNjIwiB.mjs → email-console-Dzb6uGYa.mjs} +1 -1
- package/dist/{email-console-BHNjIwiB.mjs.map → email-console-Dzb6uGYa.mjs.map} +1 -1
- package/dist/{enrich-_ySMEvEE.mjs → enrich-BX0IDp4z.mjs} +3 -3
- package/dist/{enrich-_ySMEvEE.mjs.map → enrich-BX0IDp4z.mjs.map} +1 -1
- package/dist/{error-DupyJZE2.mjs → error-DFrQjppn.mjs} +2 -2
- package/dist/{error-DupyJZE2.mjs.map → error-DFrQjppn.mjs.map} +1 -1
- package/dist/{errors-CLUPm7aD.mjs → errors-DsVoDUjJ.mjs} +24 -2
- package/dist/errors-DsVoDUjJ.mjs.map +1 -0
- package/dist/{escape-DUY2r2Zs.mjs → escape-HmHTC1Is.mjs} +1 -1
- package/dist/{escape-DUY2r2Zs.mjs.map → escape-HmHTC1Is.mjs.map} +1 -1
- package/dist/{field-defs-cache-BzwBlJrR.mjs → field-defs-cache-BM4SIRqH.mjs} +5 -5
- package/dist/{field-defs-cache-BzwBlJrR.mjs.map → field-defs-cache-BM4SIRqH.mjs.map} +1 -1
- package/dist/focal-point-BeWFo6Xx.mjs +23 -0
- package/dist/focal-point-BeWFo6Xx.mjs.map +1 -0
- package/dist/{fts-manager-DyZEohZC.mjs → fts-manager-Do1BlW2r.mjs} +3 -3
- package/dist/{fts-manager-DyZEohZC.mjs.map → fts-manager-Do1BlW2r.mjs.map} +1 -1
- package/dist/{hash-Cg0TXJPV.mjs → hash-3JJPlHF2.mjs} +1 -1
- package/dist/{hash-Cg0TXJPV.mjs.map → hash-3JJPlHF2.mjs.map} +1 -1
- package/dist/hook-result-DCh2WUpe.d.mts +31 -0
- package/dist/hook-result-DCh2WUpe.d.mts.map +1 -0
- package/dist/{hreflang-DwT2E0Sa.d.mts → hreflang-B6hbAuuO.d.mts} +2 -2
- package/dist/{hreflang-DwT2E0Sa.d.mts.map → hreflang-B6hbAuuO.d.mts.map} +1 -1
- package/dist/{hreflang-BBe83kKa.mjs → hreflang-DQbPZliA.mjs} +7 -7
- package/dist/{hreflang-BBe83kKa.mjs.map → hreflang-DQbPZliA.mjs.map} +1 -1
- package/dist/{identity-Ys6Dlc9C.mjs → identity-DksvEazf.mjs} +3 -3
- package/dist/{identity-Ys6Dlc9C.mjs.map → identity-DksvEazf.mjs.map} +1 -1
- package/dist/{import-DPkLmeXO.mjs → import-CJpaBBBT.mjs} +6 -6
- package/dist/{import-DPkLmeXO.mjs.map → import-CJpaBBBT.mjs.map} +1 -1
- package/dist/{index-BVBZj4-7.d.mts → index-BJNMCWmu.d.mts} +267 -82
- package/dist/index-BJNMCWmu.d.mts.map +1 -0
- package/dist/{index-C9KuQyO-.d.mts → index-Du8K7bWa.d.mts} +3 -3
- package/dist/{index-C9KuQyO-.d.mts.map → index-Du8K7bWa.d.mts.map} +1 -1
- package/dist/index.d.mts +22 -21
- package/dist/index.mjs +79 -73
- package/dist/{init-lock-6b309ZrF.mjs → init-lock-DJkX6Hto.mjs} +1 -1
- package/dist/{init-lock-6b309ZrF.mjs.map → init-lock-DJkX6Hto.mjs.map} +1 -1
- package/dist/{load-YJ2xl3ra.mjs → load-CawHjTOH.mjs} +2 -2
- package/dist/{load-YJ2xl3ra.mjs.map → load-CawHjTOH.mjs.map} +1 -1
- package/dist/{loader-CdG_Ci3H.mjs → loader-Z8vl7zTq.mjs} +48 -13
- package/dist/loader-Z8vl7zTq.mjs.map +1 -0
- package/dist/{manifest-builder-B252yQUf.mjs → manifest-builder-COtzuca2.mjs} +2 -2
- package/dist/{manifest-builder-B252yQUf.mjs.map → manifest-builder-COtzuca2.mjs.map} +1 -1
- package/dist/{manifest-schema-BXbUAHod.mjs → manifest-schema-BNWwR8Vd.mjs} +5 -5
- package/dist/manifest-schema-BNWwR8Vd.mjs.map +1 -0
- package/dist/media/image-endpoint.d.mts +4 -2
- package/dist/media/image-endpoint.d.mts.map +1 -1
- package/dist/media/image-endpoint.mjs +6 -4
- package/dist/media/image-endpoint.mjs.map +1 -1
- package/dist/media/index.d.mts +1 -1
- package/dist/media/index.mjs +13 -3
- package/dist/media/index.mjs.map +1 -1
- package/dist/media/local-runtime.d.mts +14 -12
- package/dist/media/local-runtime.d.mts.map +1 -1
- package/dist/media/local-runtime.mjs +12 -6
- package/dist/media/local-runtime.mjs.map +1 -1
- package/dist/{media-CzhAn2--.mjs → media-BBm8Wg3f.mjs} +69 -12
- package/dist/media-BBm8Wg3f.mjs.map +1 -0
- package/dist/{media-BWWWb8kg.mjs → media-BHjus86Y.mjs} +133 -9
- package/dist/media-BHjus86Y.mjs.map +1 -0
- package/dist/{media-allowlist-D6x-Us02.mjs → media-allowlist-CoTBWoDp.mjs} +3 -2
- package/dist/media-allowlist-CoTBWoDp.mjs.map +1 -0
- package/dist/media-folders-BGkATs8n.mjs +210 -0
- package/dist/media-folders-BGkATs8n.mjs.map +1 -0
- package/dist/{media-upload-CHBVn6m-.mjs → media-upload-BCidR-EY.mjs} +9 -9
- package/dist/{media-upload-CHBVn6m-.mjs.map → media-upload-BCidR-EY.mjs.map} +1 -1
- package/dist/{media-url-BvoX88FA.mjs → media-url-DHoPr0hq.mjs} +1 -1
- package/dist/{media-url-BvoX88FA.mjs.map → media-url-DHoPr0hq.mjs.map} +1 -1
- package/dist/media-usage-CdY5jhSR.mjs +1833 -0
- package/dist/media-usage-CdY5jhSR.mjs.map +1 -0
- package/dist/media-usage-activation-BgeMtK5C.mjs +78 -0
- package/dist/media-usage-activation-BgeMtK5C.mjs.map +1 -0
- package/dist/{media-usage-work-CLo_6tct.mjs → media-usage-work-CnGCdHxx.mjs} +4 -4
- package/dist/{media-usage-work-CLo_6tct.mjs.map → media-usage-work-CnGCdHxx.mjs.map} +1 -1
- package/dist/{media-usage-work-DrCbqBcl.mjs → media-usage-work-D6D9sMCA.mjs} +221 -59
- package/dist/media-usage-work-D6D9sMCA.mjs.map +1 -0
- package/dist/{media-usage-write-fence-aHEgN1zB.mjs → media-usage-write-fence-hjeD4u7s.mjs} +2 -2
- package/dist/{media-usage-write-fence-aHEgN1zB.mjs.map → media-usage-write-fence-hjeD4u7s.mjs.map} +1 -1
- package/dist/{menus-DSo5QeW0.mjs → menus-6qSwTNxG.mjs} +375 -107
- package/dist/menus-6qSwTNxG.mjs.map +1 -0
- package/dist/{menus-TCNSd2vp.mjs → menus-uvPLXMZf.mjs} +4 -4
- package/dist/{menus-TCNSd2vp.mjs.map → menus-uvPLXMZf.mjs.map} +1 -1
- package/dist/migrations/index.d.mts +1 -1
- package/dist/migrations/index.mjs +3 -3
- package/dist/{mime-DfIVjNkr.mjs → mime-CUIG6x84.mjs} +1 -1
- package/dist/mime-CUIG6x84.mjs.map +1 -0
- package/dist/{mode-BDoH_WcF.mjs → mode-DN_WneRx.mjs} +1 -1
- package/dist/{mode-BDoH_WcF.mjs.map → mode-DN_WneRx.mjs.map} +1 -1
- package/dist/node-sqlite-compat-BuJXIeMz.mjs +46 -0
- package/dist/node-sqlite-compat-BuJXIeMz.mjs.map +1 -0
- package/dist/{normalize-Bc-s_r-a.mjs → normalize-C2xNjTSG.mjs} +36 -5
- package/dist/normalize-C2xNjTSG.mjs.map +1 -0
- package/dist/{oauth-authorization-iOikmrJd.mjs → oauth-authorization-Dj6Kwc21.mjs} +5 -5
- package/dist/{oauth-authorization-iOikmrJd.mjs.map → oauth-authorization-Dj6Kwc21.mjs.map} +1 -1
- package/dist/{oauth-clients-CvI0nHMJ.mjs → oauth-clients-FD7I0J8m.mjs} +1 -1
- package/dist/{oauth-clients-CvI0nHMJ.mjs.map → oauth-clients-FD7I0J8m.mjs.map} +1 -1
- package/dist/{oauth-state-store-Ba8KZlwW.mjs → oauth-state-store-DkmDOmHs.mjs} +1 -1
- package/dist/{oauth-state-store-Ba8KZlwW.mjs.map → oauth-state-store-DkmDOmHs.mjs.map} +1 -1
- package/dist/{oauth-user-lookup-C5SQwGYC.mjs → oauth-user-lookup-CvIwGpYd.mjs} +1 -1
- package/dist/{oauth-user-lookup-C5SQwGYC.mjs.map → oauth-user-lookup-CvIwGpYd.mjs.map} +1 -1
- package/dist/object-cache/memory.d.mts +1 -1
- package/dist/{object-cache-71tPfV4A.mjs → object-cache-DVKnyOfy.mjs} +19 -3
- package/dist/object-cache-DVKnyOfy.mjs.map +1 -0
- package/dist/{options-CBXIHUoT.mjs → options-BHPeIbBd.mjs} +1 -1
- package/dist/{options-CBXIHUoT.mjs.map → options-BHPeIbBd.mjs.map} +1 -1
- package/dist/{options--hhz-jZ1.d.mts → options-CYb4y7hM.d.mts} +24 -11
- package/dist/options-CYb4y7hM.d.mts.map +1 -0
- package/dist/page/index.d.mts +2 -2
- package/dist/{parse-DFbuc-Fh.mjs → parse-Ckpg-Qfp.mjs} +2 -2
- package/dist/{parse-DFbuc-Fh.mjs.map → parse-Ckpg-Qfp.mjs.map} +1 -1
- package/dist/{passkey-config-DFAmUyuE.mjs → passkey-config-O_lj3y0k.mjs} +1 -1
- package/dist/{passkey-config-DFAmUyuE.mjs.map → passkey-config-O_lj3y0k.mjs.map} +1 -1
- package/dist/{patterns-CiyXeDgr.mjs → patterns-D9iDO3j8.mjs} +1 -1
- package/dist/{patterns-CiyXeDgr.mjs.map → patterns-D9iDO3j8.mjs.map} +1 -1
- package/dist/{placeholder-Dp0K3RkD.d.mts → placeholder-4X9BrRrp.d.mts} +7 -1
- package/dist/placeholder-4X9BrRrp.d.mts.map +1 -0
- package/dist/plugin-types.d.mts +8 -3
- package/dist/plugin-types.d.mts.map +1 -1
- package/dist/plugin-utils.d.mts +10 -10
- package/dist/plugins/adapt-sandbox-entry.d.mts +10 -10
- package/dist/plugins/adapt-sandbox-entry.mjs +2 -2
- package/dist/{policy-TluUIxuu.mjs → policy-Dhtwntrt.mjs} +2 -2
- package/dist/{policy-TluUIxuu.mjs.map → policy-Dhtwntrt.mjs.map} +1 -1
- package/dist/{portable-text-imBW5cHK.mjs → portable-text-U85hOafW.mjs} +1 -1
- package/dist/{portable-text-imBW5cHK.mjs.map → portable-text-U85hOafW.mjs.map} +1 -1
- package/dist/{preview-PW-nOnq4.mjs → preview-B_vJLvf8.mjs} +2 -2
- package/dist/{preview-PW-nOnq4.mjs.map → preview-B_vJLvf8.mjs.map} +1 -1
- package/dist/{protocol-DjsJHTlK.d.mts → protocol-JdD2YhY9.d.mts} +2 -2
- package/dist/{protocol-DjsJHTlK.d.mts.map → protocol-JdD2YhY9.d.mts.map} +1 -1
- package/dist/{public-url-CWoFhQT8.mjs → public-url-CarhZJgf.mjs} +1 -1
- package/dist/{public-url-CWoFhQT8.mjs.map → public-url-CarhZJgf.mjs.map} +1 -1
- package/dist/{query-zTVAR1Sl.mjs → query-BZKZcG5b.mjs} +15 -15
- package/dist/{query-zTVAR1Sl.mjs.map → query-BZKZcG5b.mjs.map} +1 -1
- package/dist/{query-BWs7O5Il.mjs → query-BndaFxxp.mjs} +5 -5
- package/dist/{query-BWs7O5Il.mjs.map → query-BndaFxxp.mjs.map} +1 -1
- package/dist/{rate-limit-Bx4g9m3p.mjs → rate-limit-BZmATC6W.mjs} +2 -2
- package/dist/{rate-limit-Bx4g9m3p.mjs.map → rate-limit-BZmATC6W.mjs.map} +1 -1
- package/dist/{redirect-COsS6SWJ.mjs → redirect-CZkbozu9.mjs} +2 -2
- package/dist/{redirect-COsS6SWJ.mjs.map → redirect-CZkbozu9.mjs.map} +1 -1
- package/dist/{redirect-BgAOGHDq.mjs → redirect-CzqnLxK-.mjs} +1 -1
- package/dist/{redirect-BgAOGHDq.mjs.map → redirect-CzqnLxK-.mjs.map} +1 -1
- package/dist/{redirects-DTDHWH31.mjs → redirects-BLNOWQTn.mjs} +64 -29
- package/dist/redirects-BLNOWQTn.mjs.map +1 -0
- package/dist/{redirects-DyChwDkG.mjs → redirects-CqzNM0KM.mjs} +5 -5
- package/dist/{redirects-DyChwDkG.mjs.map → redirects-CqzNM0KM.mjs.map} +1 -1
- package/dist/{registry-Cqa2I749.mjs → registry-AZAsRsor.mjs} +30 -126
- package/dist/registry-AZAsRsor.mjs.map +1 -0
- package/dist/{relation-BnHB0T4J.mjs → relation-04DfKRTO.mjs} +2 -2
- package/dist/{relation-BnHB0T4J.mjs.map → relation-04DfKRTO.mjs.map} +1 -1
- package/dist/{relations-BBApI4e2.mjs → relations-C4htk5sb.mjs} +7 -7
- package/dist/relations-C4htk5sb.mjs.map +1 -0
- package/dist/{relations-D5sM5fW0.mjs → relations-CcFwDJdJ.mjs} +4 -4
- package/dist/{relations-D5sM5fW0.mjs.map → relations-CcFwDJdJ.mjs.map} +1 -1
- package/dist/{relations-BHo5A8Zf.d.mts → relations-DnRK4YIT.d.mts} +347 -54
- package/dist/relations-DnRK4YIT.d.mts.map +1 -0
- package/dist/{request-cache-BSUptuJR.mjs → request-cache-DH9zdCOD.mjs} +1 -1
- package/dist/{request-cache-BSUptuJR.mjs.map → request-cache-DH9zdCOD.mjs.map} +1 -1
- package/dist/request-context.d.mts +1 -1
- package/dist/{request-meta-DgZJh3zG.mjs → request-meta-DYxLlnmz.mjs} +2 -2
- package/dist/{request-meta-DgZJh3zG.mjs.map → request-meta-DYxLlnmz.mjs.map} +1 -1
- package/dist/{resolve-DOhVEvty.mjs → resolve-prZ3mP7l.mjs} +1 -1
- package/dist/{resolve-DOhVEvty.mjs.map → resolve-prZ3mP7l.mjs.map} +1 -1
- package/dist/{runner-C1T11CfC.mjs → runner-BLIDKpmA.mjs} +471 -290
- package/dist/runner-BLIDKpmA.mjs.map +1 -0
- package/dist/{runner-BYHZn3Jy.d.mts → runner-YKfIMnaF.d.mts} +3 -2
- package/dist/runner-YKfIMnaF.d.mts.map +1 -0
- package/dist/runtime.d.mts +11 -11
- package/dist/runtime.mjs +1 -1
- package/dist/{schema-DZ5YVVZj.mjs → schema-CGnBeLiW.mjs} +3 -3
- package/dist/{schema-DZ5YVVZj.mjs.map → schema-CGnBeLiW.mjs.map} +1 -1
- package/dist/{schema-2AOsSn2v.mjs → schema-DYr-Vd-L.mjs} +36 -6
- package/dist/{schema-2AOsSn2v.mjs.map → schema-DYr-Vd-L.mjs.map} +1 -1
- package/dist/{scopes-8ClPF2bC.mjs → scopes-BhWvBavj.mjs} +3 -3
- package/dist/{scopes-8ClPF2bC.mjs.map → scopes-BhWvBavj.mjs.map} +1 -1
- package/dist/{search-u1QYdOCG.mjs → search-C-qDk4kx.mjs} +4 -4
- package/dist/{search-u1QYdOCG.mjs.map → search-C-qDk4kx.mjs.map} +1 -1
- package/dist/{secrets-BEgsAQEU.mjs → secrets-rEtHt-6z.mjs} +3 -3
- package/dist/{secrets-BEgsAQEU.mjs.map → secrets-rEtHt-6z.mjs.map} +1 -1
- package/dist/{sections-DmHviGyM.mjs → sections-B_nYvlwn.mjs} +2 -2
- package/dist/{sections-DmHviGyM.mjs.map → sections-B_nYvlwn.mjs.map} +1 -1
- package/dist/seed/index.d.mts +2 -2
- package/dist/seed/index.mjs +25 -23
- package/dist/seo/index.d.mts +3 -3
- package/dist/seo/index.mjs +17 -15
- package/dist/seo/index.mjs.map +1 -1
- package/dist/{seo-Dq4G-RrO.mjs → seo-926NRIgt.mjs} +3 -3
- package/dist/{seo-Dq4G-RrO.mjs.map → seo-926NRIgt.mjs.map} +1 -1
- package/dist/{seo-AFpVvTqr.mjs → seo-CVWkdv6x.mjs} +1 -1
- package/dist/{seo-AFpVvTqr.mjs.map → seo-CVWkdv6x.mjs.map} +1 -1
- package/dist/{service-BpArayPr.mjs → service-CJl3ZAYs.mjs} +3 -3
- package/dist/{service-BpArayPr.mjs.map → service-CJl3ZAYs.mjs.map} +1 -1
- package/dist/{session-user-BEorKVT-.mjs → session-user-BlMgqCHS.mjs} +1 -1
- package/dist/{session-user-BEorKVT-.mjs.map → session-user-BlMgqCHS.mjs.map} +1 -1
- package/dist/{settings-xRdoUZr0.mjs → settings--wobrkkC.mjs} +21 -8
- package/dist/settings--wobrkkC.mjs.map +1 -0
- package/dist/{settings-DE9xtzqd.mjs → settings-Cwm6o2jY.mjs} +3 -3
- package/dist/{settings-DE9xtzqd.mjs.map → settings-Cwm6o2jY.mjs.map} +1 -1
- package/dist/{setup-complete-BnT8pq_C.mjs → setup-complete-DQbClIN2.mjs} +2 -2
- package/dist/{setup-complete-BnT8pq_C.mjs.map → setup-complete-DQbClIN2.mjs.map} +1 -1
- package/dist/{setup-nonce-CBitf_oQ.mjs → setup-nonce-DZCFS2sn.mjs} +1 -1
- package/dist/{setup-nonce-CBitf_oQ.mjs.map → setup-nonce-DZCFS2sn.mjs.map} +1 -1
- package/dist/{single-flight-cache-B0eLKS6K.mjs → single-flight-cache-BPuGPdcN.mjs} +2 -2
- package/dist/{single-flight-cache-B0eLKS6K.mjs.map → single-flight-cache-BPuGPdcN.mjs.map} +1 -1
- package/dist/{site-url-DjpIXMXJ.mjs → site-url-BrxA_E9H.mjs} +3 -3
- package/dist/{site-url-DjpIXMXJ.mjs.map → site-url-BrxA_E9H.mjs.map} +1 -1
- package/dist/{snapshot-BBlGkb2q.mjs → snapshot--OCDTqdb.mjs} +1 -1
- package/dist/{snapshot-BBlGkb2q.mjs.map → snapshot--OCDTqdb.mjs.map} +1 -1
- package/dist/{ssrf-Cpvg_n3A.mjs → ssrf-5sIM5jzl.mjs} +23 -6
- package/dist/{ssrf-Cpvg_n3A.mjs.map → ssrf-5sIM5jzl.mjs.map} +1 -1
- package/dist/{state-DYwPue40.mjs → state-BpFVsJZB.mjs} +12 -4
- package/dist/state-BpFVsJZB.mjs.map +1 -0
- package/dist/{status-CWVYpbD8.mjs → status-B777-dXz.mjs} +1 -1
- package/dist/{status-CWVYpbD8.mjs.map → status-B777-dXz.mjs.map} +1 -1
- package/dist/storage/local.d.mts +2 -1
- package/dist/storage/local.d.mts.map +1 -1
- package/dist/storage/local.mjs +1 -1
- package/dist/storage/local.mjs.map +1 -1
- package/dist/storage/s3.d.mts +2 -1
- package/dist/storage/s3.d.mts.map +1 -1
- package/dist/storage/s3.mjs +3 -2
- package/dist/storage/s3.mjs.map +1 -1
- package/dist/{target-DixqqV5i.mjs → target-BmR0iTwz.mjs} +1 -1
- package/dist/{target-DixqqV5i.mjs.map → target-BmR0iTwz.mjs.map} +1 -1
- package/dist/{taxonomies-OHUIiIpI.mjs → taxonomies-DkAkMupr.mjs} +17 -14
- package/dist/taxonomies-DkAkMupr.mjs.map +1 -0
- package/dist/{taxonomies-BlrncHi9.mjs → taxonomies-Wfy_Lg12.mjs} +43 -17
- package/dist/taxonomies-Wfy_Lg12.mjs.map +1 -0
- package/dist/{taxonomy-BqCZ1TdU.mjs → taxonomy-tJepplLL.mjs} +5 -5
- package/dist/{taxonomy-BqCZ1TdU.mjs.map → taxonomy-tJepplLL.mjs.map} +1 -1
- package/dist/{tokens-C39klX8R.mjs → tokens-BCO1oruF.mjs} +1 -1
- package/dist/{tokens-C39klX8R.mjs.map → tokens-BCO1oruF.mjs.map} +1 -1
- package/dist/{transaction-NQj4VJ7Z.mjs → transaction-0KOpOyMu.mjs} +2 -1
- package/dist/{transaction-NQj4VJ7Z.mjs.map → transaction-0KOpOyMu.mjs.map} +1 -1
- package/dist/{transport-DBJwa-Si.mjs → transport-Dr3qtwXC.mjs} +4 -3
- package/dist/{transport-DBJwa-Si.mjs.map → transport-Dr3qtwXC.mjs.map} +1 -1
- package/dist/{transport-RQE36APG.d.mts → transport-xh6YKW2G.d.mts} +1 -1
- package/dist/{transport-RQE36APG.d.mts.map → transport-xh6YKW2G.d.mts.map} +1 -1
- package/dist/{trusted-proxy-CEVekpby.mjs → trusted-proxy-BR5F1Otp.mjs} +1 -1
- package/dist/{trusted-proxy-CEVekpby.mjs.map → trusted-proxy-BR5F1Otp.mjs.map} +1 -1
- package/dist/{types-BW1syrlw.mjs → types-3qNFPlci.mjs} +1 -1
- package/dist/{types-BW1syrlw.mjs.map → types-3qNFPlci.mjs.map} +1 -1
- package/dist/types-75KIqzL9.mjs.map +1 -1
- package/dist/{types-DrJrVCT1.d.mts → types-B6GrPic4.d.mts} +9 -3
- package/dist/{types-DrJrVCT1.d.mts.map → types-B6GrPic4.d.mts.map} +1 -1
- package/dist/{types-DN64_zzZ.d.mts → types-BuHW4xDE.d.mts} +11 -10
- package/dist/types-BuHW4xDE.d.mts.map +1 -0
- package/dist/{types-DWRhk9xZ.d.mts → types-C00oyCZp.d.mts} +1 -1
- package/dist/{types-DWRhk9xZ.d.mts.map → types-C00oyCZp.d.mts.map} +1 -1
- package/dist/{types-BntycPTF.d.mts → types-CDtkNSFQ.d.mts} +1 -1
- package/dist/{types-BntycPTF.d.mts.map → types-CDtkNSFQ.d.mts.map} +1 -1
- package/dist/{types-Dfk8KI5R.d.mts → types-CPeXo1wF.d.mts} +1 -1
- package/dist/{types-Dfk8KI5R.d.mts.map → types-CPeXo1wF.d.mts.map} +1 -1
- package/dist/types-CQPWhPxE.mjs.map +1 -1
- package/dist/{types-BcqdcT-r.d.mts → types-CXFkwEGC.d.mts} +3 -2
- package/dist/types-CXFkwEGC.d.mts.map +1 -0
- package/dist/{types-CtzytVXn.mjs → types-DM3vioBY.mjs} +1 -1
- package/dist/{types-CtzytVXn.mjs.map → types-DM3vioBY.mjs.map} +1 -1
- package/dist/{types-CXnOzDe1.d.mts → types-DczELMop.d.mts} +1 -1
- package/dist/{types-CXnOzDe1.d.mts.map → types-DczELMop.d.mts.map} +1 -1
- package/dist/types-DfuTR6dL.mjs +3 -0
- package/dist/{types-DQIDRKF2.d.mts → types-FV23hEoW.d.mts} +10 -1
- package/dist/types-FV23hEoW.d.mts.map +1 -0
- package/dist/{types-C2pMvO62.d.mts → types-xDMtUFnO.d.mts} +2 -1
- package/dist/types-xDMtUFnO.d.mts.map +1 -0
- package/dist/{upload-attempts-D4FS8LT6.mjs → upload-attempts-BsqoQ1fn.mjs} +1 -1
- package/dist/{upload-attempts-D4FS8LT6.mjs.map → upload-attempts-BsqoQ1fn.mjs.map} +1 -1
- package/dist/{url-pattern-BHS0V5Ng.mjs → url-pattern-D4c2czpJ.mjs} +1 -1
- package/dist/{url-pattern-BHS0V5Ng.mjs.map → url-pattern-D4c2czpJ.mjs.map} +1 -1
- package/dist/{user-DJZfUJVE.mjs → user-BTZ40aq6.mjs} +2 -2
- package/dist/{user-DJZfUJVE.mjs.map → user-BTZ40aq6.mjs.map} +1 -1
- package/dist/{utils-D4vD_Y98.mjs → utils-BKvNjjhY.mjs} +1 -1
- package/dist/{utils-D4vD_Y98.mjs.map → utils-BKvNjjhY.mjs.map} +1 -1
- package/dist/{validate-BMLBvxOC.mjs → validate-DE_LRwo9.mjs} +2 -2
- package/dist/{validate-BMLBvxOC.mjs.map → validate-DE_LRwo9.mjs.map} +1 -1
- package/dist/{validate-CTqt5nuE.d.mts → validate-DUP27OYD.d.mts} +5 -5
- package/dist/{validate-CTqt5nuE.d.mts.map → validate-DUP27OYD.d.mts.map} +1 -1
- package/dist/{validation-npvENUCB.mjs → validation-BMImFJ11.mjs} +10 -8
- package/dist/{validation-npvENUCB.mjs.map → validation-BMImFJ11.mjs.map} +1 -1
- package/dist/version-Bii3suaO.mjs +7 -0
- package/dist/{version-DB_fqCSI.mjs.map → version-Bii3suaO.mjs.map} +1 -1
- package/dist/{widgets-BD3ho7Rq.mjs → widgets-D3gJ10xU.mjs} +18 -5
- package/dist/widgets-D3gJ10xU.mjs.map +1 -0
- package/dist/{wxr-taxonomies-Ca68766D.d.mts → wxr-taxonomies-B2Og_6rU.d.mts} +1 -1
- package/dist/{wxr-taxonomies-Ca68766D.d.mts.map → wxr-taxonomies-B2Og_6rU.d.mts.map} +1 -1
- package/dist/{wxr-taxonomies-B1R3vBoD.mjs → wxr-taxonomies-Cxngsjwo.mjs} +4 -4
- package/dist/{wxr-taxonomies-B1R3vBoD.mjs.map → wxr-taxonomies-Cxngsjwo.mjs.map} +1 -1
- package/dist/{zod-generator-LC-on_Vb.mjs → zod-generator-BuYSQJB7.mjs} +32 -22
- package/dist/zod-generator-BuYSQJB7.mjs.map +1 -0
- package/package.json +20 -9
- package/src/api/errors.ts +22 -0
- package/src/api/handlers/content.ts +49 -11
- package/src/api/handlers/index.ts +18 -0
- package/src/api/handlers/manifest.ts +161 -12
- package/src/api/handlers/media-allowlist.ts +1 -0
- package/src/api/handlers/media-folders.ts +130 -0
- package/src/api/handlers/media-usage-activation.ts +102 -0
- package/src/api/handlers/media-usage.ts +108 -0
- package/src/api/handlers/media.ts +92 -2
- package/src/api/handlers/registry.ts +483 -561
- package/src/api/handlers/taxonomies.ts +16 -9
- package/src/api/openapi/document.ts +277 -7
- package/src/api/parse.ts +1 -1
- package/src/api/schemas/auth.ts +4 -4
- package/src/api/schemas/bylines.ts +3 -3
- package/src/api/schemas/comments.ts +1 -1
- package/src/api/schemas/common.ts +3 -2
- package/src/api/schemas/content.ts +78 -22
- package/src/api/schemas/media-usage.ts +77 -0
- package/src/api/schemas/media.ts +121 -0
- package/src/api/schemas/redirects.ts +6 -1
- package/src/api/schemas/schema.ts +4 -0
- package/src/api/schemas/setup.ts +1 -1
- package/src/api/schemas/taxonomies.ts +2 -2
- package/src/api/schemas/users.ts +1 -1
- package/src/api/types.ts +23 -10
- package/src/astro/dev-typegen.ts +35 -0
- package/src/astro/image-endpoint.ts +2 -2
- package/src/astro/integration/dev-typegen.ts +91 -0
- package/src/astro/integration/index.ts +9 -44
- package/src/astro/integration/routes.ts +23 -0
- package/src/astro/integration/vite-config.ts +23 -9
- package/src/astro/middleware/auth.ts +4 -0
- package/src/astro/middleware.ts +5 -7
- package/src/astro/routes/api/admin/api-tokens/index.ts +4 -1
- package/src/astro/routes/api/admin/media-usage/activation.ts +42 -0
- package/src/astro/routes/api/admin/media-usage/progress.ts +37 -0
- package/src/astro/routes/api/admin/oauth-clients/[id].ts +1 -1
- package/src/astro/routes/api/admin/oauth-clients/index.ts +1 -1
- package/src/astro/routes/api/admin/plugins/registry/[id]/update.ts +4 -0
- package/src/astro/routes/api/admin/plugins/registry/artifact.ts +247 -101
- package/src/astro/routes/api/admin/plugins/registry/install.ts +4 -0
- package/src/astro/routes/api/admin/plugins/registry/verify.ts +60 -0
- package/src/astro/routes/api/auth/me.ts +14 -2
- package/src/astro/routes/api/content/[collection]/[id]/discard-draft.ts +8 -2
- package/src/astro/routes/api/content/[collection]/[id]/publish.ts +2 -1
- package/src/astro/routes/api/content/[collection]/[id]/unpublish.ts +6 -2
- package/src/astro/routes/api/manifest.ts +1 -1
- package/src/astro/routes/api/media/[id]/replace.ts +114 -0
- package/src/astro/routes/api/media/[id].ts +3 -0
- package/src/astro/routes/api/media/file/[...key].ts +4 -1
- package/src/astro/routes/api/media/folders/[id].ts +55 -0
- package/src/astro/routes/api/media/folders/index.ts +37 -0
- package/src/astro/routes/api/media/upload-url.ts +8 -4
- package/src/astro/routes/api/media.ts +66 -10
- package/src/astro/routes/api/menus/[name]/items/[id].ts +7 -2
- package/src/astro/routes/api/menus/[name]/items.ts +4 -1
- package/src/astro/routes/api/menus/[name]/reorder.ts +4 -1
- package/src/astro/routes/api/menus/[name]/translations.ts +4 -1
- package/src/astro/routes/api/menus/[name].ts +7 -2
- package/src/astro/routes/api/menus/index.ts +4 -1
- package/src/astro/routes/api/settings/email.ts +1 -1
- package/src/astro/routes/api/settings.ts +4 -1
- package/src/astro/routes/api/setup/dev-bypass.ts +12 -0
- package/src/astro/routes/api/taxonomies/[name]/reorder.ts +4 -1
- package/src/astro/routes/api/taxonomies/[name]/terms/[slug]/translations.ts +4 -1
- package/src/astro/routes/api/taxonomies/[name]/terms/[slug].ts +7 -2
- package/src/astro/routes/api/taxonomies/[name]/terms/index.ts +4 -1
- package/src/astro/routes/api/taxonomies/[name].ts +7 -2
- package/src/astro/routes/api/taxonomies/index.ts +4 -1
- package/src/astro/routes/api/widget-areas/[name]/reorder.ts +3 -1
- package/src/astro/routes/api/widget-areas/[name]/widgets/[id].ts +5 -2
- package/src/astro/routes/api/widget-areas/[name]/widgets.ts +3 -1
- package/src/astro/routes/api/widget-areas/[name].ts +3 -1
- package/src/astro/routes/api/widget-areas/index.ts +3 -1
- package/src/astro/types.ts +34 -6
- package/src/auth/challenge-store.ts +3 -1
- package/src/aws-sdk.d.ts +1 -0
- package/src/cache/chrome-tags.ts +24 -0
- package/src/client/index.ts +140 -2
- package/src/client/transport.ts +6 -2
- package/src/components/EmDashImage.astro +156 -51
- package/src/components/EmDashMedia.astro +2 -1
- package/src/components/Gallery.astro +7 -0
- package/src/components/InlinePortableTextEditor.tsx +136 -2
- package/src/components/LiveSearch.astro +23 -0
- package/src/components/inline-code-block.tsx +180 -49
- package/src/components/widgets/Archives.astro +2 -37
- package/src/content/converters/gallery.ts +2 -0
- package/src/content/converters/index.ts +2 -0
- package/src/content/converters/mark-safety.ts +1 -0
- package/src/content/converters/portable-text-identity.ts +139 -0
- package/src/content/converters/portable-text-to-prosemirror.ts +202 -69
- package/src/content/converters/prosemirror-to-portable-text.ts +96 -25
- package/src/content/converters/types.ts +3 -0
- package/src/database/connection.ts +2 -31
- package/src/database/index.ts +1 -1
- package/src/database/json-recordset.ts +16 -0
- package/src/database/migrations/017_authorization_codes.ts +14 -4
- package/src/database/migrations/019_i18n.ts +1 -1
- package/src/database/migrations/071_restore_content_bylines_table.ts +43 -0
- package/src/database/migrations/072_media_folders.ts +72 -0
- package/src/database/migrations/073_media_focal_point.ts +57 -0
- package/src/database/migrations/074_content_deleted_scheduled_index.ts +55 -0
- package/src/database/migrations/runner.ts +11 -3
- package/src/database/repositories/byline.ts +32 -16
- package/src/database/repositories/content.ts +119 -51
- package/src/database/repositories/media-folders.ts +115 -0
- package/src/database/repositories/media-usage-work.ts +395 -111
- package/src/database/repositories/media-usage.ts +1104 -47
- package/src/database/repositories/media.ts +156 -29
- package/src/database/repositories/plugin-storage.ts +74 -9
- package/src/database/repositories/types.ts +8 -7
- package/src/database/transaction.ts +1 -0
- package/src/database/types.ts +13 -0
- package/src/db/adapters.ts +10 -3
- package/src/db/node-sqlite-compat.ts +78 -0
- package/src/db/postgres.ts +23 -0
- package/src/db/sqlite.ts +3 -3
- package/src/emdash-runtime.ts +186 -251
- package/src/fields/boolean.ts +1 -1
- package/src/fields/datetime.ts +1 -1
- package/src/fields/file.ts +1 -1
- package/src/fields/image.ts +7 -1
- package/src/fields/integer.ts +1 -1
- package/src/fields/json.ts +1 -1
- package/src/fields/multiselect.ts +1 -1
- package/src/fields/number.ts +1 -1
- package/src/fields/portable-text.ts +1 -1
- package/src/fields/richtext.ts +1 -1
- package/src/fields/select.ts +1 -1
- package/src/fields/slug.ts +1 -1
- package/src/fields/text.ts +1 -1
- package/src/fields/textarea.ts +1 -1
- package/src/fields/types.ts +8 -4
- package/src/index.ts +30 -3
- package/src/loader.ts +63 -10
- package/src/mcp/server.ts +228 -24
- package/src/media/focal-point.ts +37 -0
- package/src/media/image-endpoint.ts +5 -2
- package/src/media/local-runtime.ts +8 -0
- package/src/media/mime.ts +1 -0
- package/src/media/normalize.ts +25 -4
- package/src/media/types.ts +10 -0
- package/src/media/usage/activation.ts +162 -35
- package/src/media/usage/capture-triggers.ts +19 -3
- package/src/media/usage/cleanup.ts +9 -8
- package/src/media/usage/collection-deletion-processor.ts +7 -3
- package/src/media/usage/collection-deletion.ts +10 -0
- package/src/media/usage/content-refresh.ts +258 -39
- package/src/media/usage/content-snapshots.ts +128 -31
- package/src/media/usage/extractor.ts +32 -13
- package/src/media/usage/maintenance-engine.ts +166 -0
- package/src/media/usage/reconciliation-processor.ts +106 -29
- package/src/media/usage/reconciliation.ts +90 -7
- package/src/media/usage/work-processor.ts +342 -101
- package/src/menus/index.ts +16 -0
- package/src/object-cache/index.ts +44 -2
- package/src/plugin-types.ts +18 -1
- package/src/plugins/hooks.ts +4 -1
- package/src/plugins/index.ts +7 -0
- package/src/plugins/manager.ts +2 -1
- package/src/plugins/manifest-schema.ts +1 -1
- package/src/plugins/routes.ts +3 -1
- package/src/plugins/sandbox/hook-result.ts +52 -0
- package/src/plugins/sandbox/index.ts +10 -0
- package/src/plugins/save-rejection.ts +20 -0
- package/src/plugins/scheduler/node.ts +1 -13
- package/src/plugins/scheduler/types.ts +0 -2
- package/src/plugins/state.ts +13 -3
- package/src/plugins/types.ts +6 -0
- package/src/registry/artifact-checksum.ts +15 -0
- package/src/registry/artifact-fetch.ts +530 -0
- package/src/registry/artifact-verification.ts +85 -0
- package/src/registry/authoritative-records.ts +180 -0
- package/src/registry/config.ts +24 -6
- package/src/registry/record-labels.ts +28 -0
- package/src/registry/types.ts +12 -15
- package/src/schema/registry.ts +26 -3
- package/src/schema/types.ts +1 -0
- package/src/schema/zod-generator.ts +28 -17
- package/src/security/ssrf.ts +26 -4
- package/src/seed/apply.ts +4 -4
- package/src/settings/index.ts +16 -0
- package/src/storage/local.ts +1 -0
- package/src/storage/s3.ts +2 -0
- package/src/storage/types.ts +2 -0
- package/src/taxonomies/index.ts +40 -20
- package/src/ui.ts +2 -0
- package/src/widgets/archives.ts +67 -0
- package/src/widgets/index.ts +16 -0
- package/dist/api-BeBglVxU.mjs +0 -4695
- package/dist/api-BeBglVxU.mjs.map +0 -1
- package/dist/byline-yjvWq4ip.mjs.map +0 -1
- package/dist/challenge-store-SIL5DsF2.mjs.map +0 -1
- package/dist/collection-deletion-DQPvMD8R.mjs.map +0 -1
- package/dist/content-ZHCc1ngN.mjs.map +0 -1
- package/dist/content-refresh-B_8SJzuU.mjs.map +0 -1
- package/dist/context-ZldbZcle.mjs.map +0 -1
- package/dist/errors-CLUPm7aD.mjs.map +0 -1
- package/dist/index-BVBZj4-7.d.mts.map +0 -1
- package/dist/loader-CdG_Ci3H.mjs.map +0 -1
- package/dist/manifest-schema-BXbUAHod.mjs.map +0 -1
- package/dist/media-BWWWb8kg.mjs.map +0 -1
- package/dist/media-CzhAn2--.mjs.map +0 -1
- package/dist/media-allowlist-D6x-Us02.mjs.map +0 -1
- package/dist/media-usage-BZCydfvu.mjs.map +0 -1
- package/dist/media-usage-work-DrCbqBcl.mjs.map +0 -1
- package/dist/menus-DSo5QeW0.mjs.map +0 -1
- package/dist/mime-DfIVjNkr.mjs.map +0 -1
- package/dist/normalize-Bc-s_r-a.mjs.map +0 -1
- package/dist/object-cache-71tPfV4A.mjs.map +0 -1
- package/dist/options--hhz-jZ1.d.mts.map +0 -1
- package/dist/placeholder-Dp0K3RkD.d.mts.map +0 -1
- package/dist/redirects-DTDHWH31.mjs.map +0 -1
- package/dist/registry-Cqa2I749.mjs.map +0 -1
- package/dist/relations-BBApI4e2.mjs.map +0 -1
- package/dist/relations-BHo5A8Zf.d.mts.map +0 -1
- package/dist/runner-BYHZn3Jy.d.mts.map +0 -1
- package/dist/runner-C1T11CfC.mjs.map +0 -1
- package/dist/settings-xRdoUZr0.mjs.map +0 -1
- package/dist/state-DYwPue40.mjs.map +0 -1
- package/dist/taxonomies-BlrncHi9.mjs.map +0 -1
- package/dist/taxonomies-OHUIiIpI.mjs.map +0 -1
- package/dist/types-BcqdcT-r.d.mts.map +0 -1
- package/dist/types-C2pMvO62.d.mts.map +0 -1
- package/dist/types-CP1CflWf.mjs +0 -3
- package/dist/types-DN64_zzZ.d.mts.map +0 -1
- package/dist/types-DQIDRKF2.d.mts.map +0 -1
- package/dist/version-DB_fqCSI.mjs +0 -7
- package/dist/widgets-BD3ho7Rq.mjs.map +0 -1
- package/dist/zod-generator-LC-on_Vb.mjs.map +0 -1
- /package/dist/{api-tokens-rIXC6LdE.mjs → api-tokens-BfYts-sq.mjs} +0 -0
- /package/dist/{ssrf-DpXgKsna.mjs → ssrf-Dg3cIT-b.mjs} +0 -0
|
@@ -5,13 +5,13 @@ import { ulid } from "ulidx";
|
|
|
5
5
|
|
|
6
6
|
//#region src/database/repositories/media-usage-work.ts
|
|
7
7
|
const MAX_PORTABLE_DURATION_SECONDS = 365 * 24 * 60 * 60;
|
|
8
|
-
const MAX_WORK_SELECTION_LIMIT =
|
|
8
|
+
const MAX_WORK_SELECTION_LIMIT = 1e3;
|
|
9
9
|
const NON_NEGATIVE_DECIMAL_PATTERN = /^(?:0|[1-9][0-9]*)$/;
|
|
10
10
|
const POSITIVE_DECIMAL_PATTERN = /^[1-9][0-9]*$/;
|
|
11
11
|
const STABLE_ERROR_CODE_PATTERN = /^[A-Z][A-Z0-9_]{0,63}$/;
|
|
12
12
|
const MEDIA_USAGE_WORK_OPERATOR_DEFAULT_LIMIT = 50;
|
|
13
13
|
const MEDIA_USAGE_WORK_OPERATOR_MAX_LIMIT = 100;
|
|
14
|
-
const MEDIA_USAGE_RECONCILIATION_PAGE_LIMIT =
|
|
14
|
+
const MEDIA_USAGE_RECONCILIATION_PAGE_LIMIT = 1e3;
|
|
15
15
|
const MEDIA_USAGE_WORK_STATES = [
|
|
16
16
|
"pending",
|
|
17
17
|
"retry",
|
|
@@ -26,11 +26,12 @@ var MediaUsageWorkRepository = class {
|
|
|
26
26
|
if (!input.collectionId || !input.collectionSlug || !input.runToken || !input.leaseToken) throw new Error("Reconciliation enqueue requires exact collection and lease identity");
|
|
27
27
|
assertNonNegativeDecimal(input.changeEpoch, "change epoch");
|
|
28
28
|
const contentIds = [...new Set(input.contentIds)];
|
|
29
|
-
if (contentIds.length < 1 || contentIds.length > MEDIA_USAGE_RECONCILIATION_PAGE_LIMIT) throw new Error("Reconciliation enqueue requires from 1 to
|
|
29
|
+
if (contentIds.length < 1 || contentIds.length > MEDIA_USAGE_RECONCILIATION_PAGE_LIMIT) throw new Error("Reconciliation enqueue requires from 1 to 1000 content IDs");
|
|
30
30
|
if (contentIds.some((contentId) => !contentId)) throw new Error("Reconciliation enqueue content IDs must not be empty");
|
|
31
31
|
const now = this.timestampOffset(0);
|
|
32
|
+
const contentIdsJson = JSON.stringify(contentIds);
|
|
32
33
|
await sql`
|
|
33
|
-
WITH page(content_id) AS (
|
|
34
|
+
WITH page(content_id) AS (${isPostgres(this.db) ? sql`SELECT value::text AS content_id FROM jsonb_array_elements_text(${contentIdsJson}::jsonb) AS value` : sql`SELECT value AS content_id FROM json_each(${contentIdsJson})`})
|
|
34
35
|
INSERT INTO _emdash_media_usage_work (
|
|
35
36
|
collection_id, collection_slug, content_id, change_epoch, work_version,
|
|
36
37
|
state, attempt_count, next_attempt_at, lease_token, lease_expires_at,
|
|
@@ -159,8 +160,9 @@ var MediaUsageWorkRepository = class {
|
|
|
159
160
|
async invalidateCoverageForOperatorRetry(input) {
|
|
160
161
|
let query = this.db.updateTable("_emdash_media_usage_index_status as status").set({
|
|
161
162
|
change_epoch: sql`change_epoch + 1`,
|
|
162
|
-
status: sql`CASE WHEN status
|
|
163
|
-
completed_at: sql`CASE WHEN status
|
|
163
|
+
status: sql`CASE WHEN status IN ('complete', 'partial', 'failed') THEN 'stale' ELSE status END`,
|
|
164
|
+
completed_at: sql`CASE WHEN status IN ('complete', 'partial', 'failed') THEN NULL ELSE completed_at END`,
|
|
165
|
+
last_error_code: null,
|
|
164
166
|
updated_at: this.timestampOffset(0)
|
|
165
167
|
}).where("status.adapter_id", "=", "content-media").where("status.scope_type", "=", "collection").where("status.scope_key", "=", input.collectionSlug).where("status.collection_id", "=", input.collectionId).where("status.capture_state", "=", "active").where((eb) => eb.exists(eb.selectFrom("_emdash_collections as collection").select("collection.id").whereRef("collection.id", "=", "status.collection_id").whereRef("collection.slug", "=", "status.scope_key")));
|
|
166
168
|
const observed = input.observed;
|
|
@@ -241,21 +243,42 @@ var MediaUsageWorkRepository = class {
|
|
|
241
243
|
async findLiveLeaseExpiry(collectionId, contentId) {
|
|
242
244
|
return (await this.db.selectFrom("_emdash_media_usage_work").select("lease_expires_at").where("collection_id", "=", collectionId).where("content_id", "=", contentId).where("state", "=", "leased").where("lease_expires_at", "is not", null).where(this.leaseIsLive()).executeTakeFirst())?.lease_expires_at ?? null;
|
|
243
245
|
}
|
|
244
|
-
async
|
|
245
|
-
if (!Number.isSafeInteger(limit) || limit < 1 || limit > MAX_WORK_SELECTION_LIMIT) throw new Error(`Media usage due-work limit must be a whole number from 1 to ${MAX_WORK_SELECTION_LIMIT}`);
|
|
246
|
-
const
|
|
247
|
-
const
|
|
248
|
-
const
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
].
|
|
246
|
+
async claimDueWorkBatch(input) {
|
|
247
|
+
if (!Number.isSafeInteger(input.limit) || input.limit < 1 || input.limit > MAX_WORK_SELECTION_LIMIT) throw new Error(`Media usage due-work limit must be a whole number from 1 to ${MAX_WORK_SELECTION_LIMIT}`);
|
|
248
|
+
const leaseDurationSeconds = durationSeconds(input.leaseDurationSeconds, "lease duration", false);
|
|
249
|
+
const leaseToken = ulid();
|
|
250
|
+
const now = this.timestampOffset(0);
|
|
251
|
+
let candidates = this.db.selectFrom("_emdash_media_usage_work as due").select([
|
|
252
|
+
"due.collection_id",
|
|
253
|
+
"due.content_id",
|
|
254
|
+
"due.work_version"
|
|
255
|
+
]).where((eb) => eb.or([eb.and([eb("due.state", "in", ["pending", "retry"]), this.timestampIsDue("due.next_attempt_at")]), eb.and([
|
|
256
|
+
eb("due.state", "=", "leased"),
|
|
257
|
+
eb("due.lease_expires_at", "is not", null),
|
|
258
|
+
this.timestampIsDue("due.lease_expires_at")
|
|
259
|
+
])])).orderBy(sql`CASE
|
|
260
|
+
WHEN due.state = 'leased' THEN due.lease_expires_at
|
|
261
|
+
ELSE due.next_attempt_at
|
|
262
|
+
END`, "asc").orderBy("due.updated_at", "asc").orderBy("due.collection_id", "asc").orderBy("due.content_id", "asc").limit(input.limit);
|
|
263
|
+
if (isPostgres(this.db)) candidates = candidates.forUpdate().skipLocked();
|
|
264
|
+
return (await this.db.with("due_media_usage_work", () => candidates).updateTable("_emdash_media_usage_work").set({
|
|
265
|
+
state: "leased",
|
|
266
|
+
lease_token: leaseToken,
|
|
267
|
+
lease_expires_at: this.timestampOffset(leaseDurationSeconds),
|
|
268
|
+
last_attempted_at: now,
|
|
269
|
+
updated_at: now
|
|
270
|
+
}).where((eb) => eb.and([eb.exists(eb.selectFrom("due_media_usage_work as due").select("due.content_id").whereRef("due.collection_id", "=", "_emdash_media_usage_work.collection_id").whereRef("due.content_id", "=", "_emdash_media_usage_work.content_id").whereRef("due.work_version", "=", "_emdash_media_usage_work.work_version")), eb.or([eb.and([eb("state", "in", ["pending", "retry"]), this.timestampIsDue("next_attempt_at")]), eb.and([
|
|
271
|
+
eb("state", "=", "leased"),
|
|
272
|
+
eb("lease_expires_at", "is not", null),
|
|
273
|
+
this.timestampIsDue("lease_expires_at")
|
|
274
|
+
])])])).returningAll().execute()).map(rowToWork);
|
|
254
275
|
}
|
|
255
|
-
async
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
276
|
+
async hasNonterminalWork() {
|
|
277
|
+
return await this.db.selectFrom("_emdash_media_usage_work").select("content_id").where("state", "in", [
|
|
278
|
+
"pending",
|
|
279
|
+
"retry",
|
|
280
|
+
"leased"
|
|
281
|
+
]).limit(1).executeTakeFirst() !== void 0;
|
|
259
282
|
}
|
|
260
283
|
async findWorkForContent(collectionSlug, contentId) {
|
|
261
284
|
if (!collectionSlug || !contentId) throw new Error("Media usage work lookup requires collection and content identity");
|
|
@@ -280,10 +303,158 @@ var MediaUsageWorkRepository = class {
|
|
|
280
303
|
])])).returningAll().executeTakeFirst();
|
|
281
304
|
return row ? rowToWork(row) : null;
|
|
282
305
|
}
|
|
283
|
-
async
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
306
|
+
async completeWorkBatch(inputs) {
|
|
307
|
+
const unique = [...new Map(inputs.map((input) => {
|
|
308
|
+
assertLease(input);
|
|
309
|
+
return [workIdentityKey(input), input];
|
|
310
|
+
})).values()];
|
|
311
|
+
const completed = /* @__PURE__ */ new Set();
|
|
312
|
+
if (unique.length === 0) return completed;
|
|
313
|
+
const payload = JSON.stringify(unique.map((input) => ({
|
|
314
|
+
collection_id: input.collectionId,
|
|
315
|
+
content_id: input.contentId,
|
|
316
|
+
work_version: String(input.workVersion),
|
|
317
|
+
lease_token: input.leaseToken
|
|
318
|
+
})));
|
|
319
|
+
const result = await sql`
|
|
320
|
+
WITH claimed AS (${this.claimedWorkBatchInput(payload)})
|
|
321
|
+
DELETE FROM _emdash_media_usage_work AS work
|
|
322
|
+
WHERE work.state = 'leased'
|
|
323
|
+
AND ${this.qualifiedLeaseIsLive("work.lease_expires_at")}
|
|
324
|
+
AND EXISTS (
|
|
325
|
+
SELECT 1
|
|
326
|
+
FROM claimed
|
|
327
|
+
WHERE claimed.collection_id = work.collection_id
|
|
328
|
+
AND claimed.content_id = work.content_id
|
|
329
|
+
AND claimed.work_version = work.work_version
|
|
330
|
+
AND claimed.lease_token = work.lease_token
|
|
331
|
+
)
|
|
332
|
+
RETURNING collection_id, content_id, work_version
|
|
333
|
+
`.execute(this.db);
|
|
334
|
+
for (const row of result.rows) completed.add(workIdentityKey({
|
|
335
|
+
collectionId: row.collection_id,
|
|
336
|
+
contentId: row.content_id,
|
|
337
|
+
workVersion: row.work_version
|
|
338
|
+
}));
|
|
339
|
+
return completed;
|
|
340
|
+
}
|
|
341
|
+
async lockClaimedWorkBatch(inputs) {
|
|
342
|
+
const unique = [...new Map(inputs.map((input) => {
|
|
343
|
+
assertLease(input);
|
|
344
|
+
return [workIdentityKey(input), input];
|
|
345
|
+
})).values()].toSorted((left, right) => workIdentityKey(left).localeCompare(workIdentityKey(right)));
|
|
346
|
+
if (!isPostgres(this.db)) return new Set(unique.map(workIdentityKey));
|
|
347
|
+
if (unique.length === 0) return /* @__PURE__ */ new Set();
|
|
348
|
+
const payload = JSON.stringify(unique.map((input) => ({
|
|
349
|
+
collection_id: input.collectionId,
|
|
350
|
+
content_id: input.contentId,
|
|
351
|
+
work_version: String(input.workVersion),
|
|
352
|
+
lease_token: input.leaseToken
|
|
353
|
+
})));
|
|
354
|
+
const result = await sql`
|
|
355
|
+
WITH claimed AS (${this.claimedWorkBatchInput(payload)})
|
|
356
|
+
SELECT work.collection_id, work.content_id, work.work_version
|
|
357
|
+
FROM _emdash_media_usage_work AS work
|
|
358
|
+
INNER JOIN claimed
|
|
359
|
+
ON claimed.collection_id = work.collection_id
|
|
360
|
+
AND claimed.content_id = work.content_id
|
|
361
|
+
AND claimed.work_version = work.work_version
|
|
362
|
+
AND claimed.lease_token = work.lease_token
|
|
363
|
+
WHERE work.state = 'leased'
|
|
364
|
+
AND ${this.qualifiedLeaseIsLive("work.lease_expires_at")}
|
|
365
|
+
ORDER BY work.collection_id, work.content_id
|
|
366
|
+
FOR UPDATE
|
|
367
|
+
`.execute(this.db);
|
|
368
|
+
return new Set(result.rows.map((row) => workIdentityKey({
|
|
369
|
+
collectionId: row.collection_id,
|
|
370
|
+
contentId: row.content_id,
|
|
371
|
+
workVersion: row.work_version
|
|
372
|
+
})));
|
|
373
|
+
}
|
|
374
|
+
async retryClaimedWorkBatch(input) {
|
|
375
|
+
assertErrorCode(input.errorCode);
|
|
376
|
+
const retryDelaySeconds = durationSeconds(input.retryDelaySeconds, "retry delay", true);
|
|
377
|
+
if (!Number.isSafeInteger(input.maxAttempts) || input.maxAttempts < 1) throw new Error("Media usage work max attempts must be a positive whole number");
|
|
378
|
+
const unique = [...new Map(input.work.map((work) => {
|
|
379
|
+
assertLease(work);
|
|
380
|
+
return [workIdentityKey(work), work];
|
|
381
|
+
})).values()];
|
|
382
|
+
const transitioned = /* @__PURE__ */ new Map();
|
|
383
|
+
if (unique.length === 0) return transitioned;
|
|
384
|
+
const payload = JSON.stringify(unique.map((work) => ({
|
|
385
|
+
collection_id: work.collectionId,
|
|
386
|
+
content_id: work.contentId,
|
|
387
|
+
work_version: String(work.workVersion),
|
|
388
|
+
lease_token: work.leaseToken
|
|
389
|
+
})));
|
|
390
|
+
const result = await sql`
|
|
391
|
+
WITH claimed AS (${this.claimedWorkBatchInput(payload)})
|
|
392
|
+
UPDATE _emdash_media_usage_work AS work
|
|
393
|
+
SET state = CASE WHEN work.attempt_count + 1 >= ${input.maxAttempts} THEN 'failed' ELSE 'retry' END,
|
|
394
|
+
attempt_count = work.attempt_count + 1,
|
|
395
|
+
next_attempt_at = ${this.timestampOffset(retryDelaySeconds)},
|
|
396
|
+
lease_token = NULL,
|
|
397
|
+
lease_expires_at = NULL,
|
|
398
|
+
last_error_code = ${input.errorCode},
|
|
399
|
+
updated_at = ${this.timestampOffset(0)}
|
|
400
|
+
WHERE work.state = 'leased'
|
|
401
|
+
AND ${this.qualifiedLeaseIsLive("work.lease_expires_at")}
|
|
402
|
+
AND EXISTS (
|
|
403
|
+
SELECT 1
|
|
404
|
+
FROM claimed
|
|
405
|
+
WHERE claimed.collection_id = work.collection_id
|
|
406
|
+
AND claimed.content_id = work.content_id
|
|
407
|
+
AND claimed.work_version = work.work_version
|
|
408
|
+
AND claimed.lease_token = work.lease_token
|
|
409
|
+
)
|
|
410
|
+
RETURNING collection_id, content_id, work_version, state
|
|
411
|
+
`.execute(this.db);
|
|
412
|
+
for (const row of result.rows) transitioned.set(workIdentityKey({
|
|
413
|
+
collectionId: row.collection_id,
|
|
414
|
+
contentId: row.content_id,
|
|
415
|
+
workVersion: row.work_version
|
|
416
|
+
}), row.state);
|
|
417
|
+
return transitioned;
|
|
418
|
+
}
|
|
419
|
+
async releaseClaimedWorkBatch(inputs) {
|
|
420
|
+
const unique = [...new Map(inputs.map((input) => {
|
|
421
|
+
assertLease(input);
|
|
422
|
+
return [workIdentityKey(input), input];
|
|
423
|
+
})).values()];
|
|
424
|
+
const released = /* @__PURE__ */ new Set();
|
|
425
|
+
if (unique.length === 0) return released;
|
|
426
|
+
const payload = JSON.stringify(unique.map((input) => ({
|
|
427
|
+
collection_id: input.collectionId,
|
|
428
|
+
content_id: input.contentId,
|
|
429
|
+
work_version: String(input.workVersion),
|
|
430
|
+
lease_token: input.leaseToken
|
|
431
|
+
})));
|
|
432
|
+
const result = await sql`
|
|
433
|
+
WITH claimed AS (${this.claimedWorkBatchInput(payload)})
|
|
434
|
+
UPDATE _emdash_media_usage_work AS work
|
|
435
|
+
SET state = 'pending',
|
|
436
|
+
next_attempt_at = ${this.timestampOffset(0)},
|
|
437
|
+
lease_token = NULL,
|
|
438
|
+
lease_expires_at = NULL,
|
|
439
|
+
updated_at = ${this.timestampOffset(0)}
|
|
440
|
+
WHERE work.state = 'leased'
|
|
441
|
+
AND ${this.qualifiedLeaseIsLive("work.lease_expires_at")}
|
|
442
|
+
AND EXISTS (
|
|
443
|
+
SELECT 1
|
|
444
|
+
FROM claimed
|
|
445
|
+
WHERE claimed.collection_id = work.collection_id
|
|
446
|
+
AND claimed.content_id = work.content_id
|
|
447
|
+
AND claimed.work_version = work.work_version
|
|
448
|
+
AND claimed.lease_token = work.lease_token
|
|
449
|
+
)
|
|
450
|
+
RETURNING collection_id, content_id, work_version
|
|
451
|
+
`.execute(this.db);
|
|
452
|
+
for (const row of result.rows) released.add(workIdentityKey({
|
|
453
|
+
collectionId: row.collection_id,
|
|
454
|
+
contentId: row.content_id,
|
|
455
|
+
workVersion: row.work_version
|
|
456
|
+
}));
|
|
457
|
+
return released;
|
|
287
458
|
}
|
|
288
459
|
async deleteWorkThroughEpoch(collectionId, maxChangeEpoch) {
|
|
289
460
|
if (!collectionId) throw new Error("Media usage work cleanup requires a collection ID");
|
|
@@ -291,27 +462,10 @@ var MediaUsageWorkRepository = class {
|
|
|
291
462
|
const result = await this.db.deleteFrom("_emdash_media_usage_work").where("collection_id", "=", collectionId).where("change_epoch", "<=", maxChangeEpoch).executeTakeFirst();
|
|
292
463
|
return Number(result.numDeletedRows ?? 0);
|
|
293
464
|
}
|
|
294
|
-
async
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
return
|
|
298
|
-
}
|
|
299
|
-
async failWork(input) {
|
|
300
|
-
assertErrorCode(input.errorCode);
|
|
301
|
-
return this.transitionFailure(input, "failed");
|
|
302
|
-
}
|
|
303
|
-
async transitionFailure(input, state, extra = {}) {
|
|
304
|
-
assertLease(input);
|
|
305
|
-
const result = await this.db.updateTable("_emdash_media_usage_work").set({
|
|
306
|
-
state,
|
|
307
|
-
attempt_count: sql`attempt_count + 1`,
|
|
308
|
-
lease_token: null,
|
|
309
|
-
lease_expires_at: null,
|
|
310
|
-
last_error_code: input.errorCode,
|
|
311
|
-
updated_at: this.timestampOffset(0),
|
|
312
|
-
...extra
|
|
313
|
-
}).where("collection_id", "=", input.collectionId).where("content_id", "=", input.contentId).where("work_version", "=", input.workVersion).where("state", "=", "leased").where("lease_token", "=", input.leaseToken).where(this.leaseIsLive()).executeTakeFirst();
|
|
314
|
-
return Number(result.numUpdatedRows ?? 0) > 0;
|
|
465
|
+
async deleteObsoleteReconciliationWork(input) {
|
|
466
|
+
assertNonNegativeDecimal(input.targetEpoch, "target epoch");
|
|
467
|
+
const result = await this.db.deleteFrom("_emdash_media_usage_work as work").where("work.collection_id", "=", input.collectionId).where("work.change_epoch", "<", input.targetEpoch).where((eb) => eb.exists(eb.selectFrom("_emdash_media_usage_reconciliations as reconciliation").innerJoin("_emdash_media_usage_index_status as status", (join) => join.onRef("status.collection_id", "=", "reconciliation.collection_id").onRef("status.scope_key", "=", "reconciliation.collection_slug")).innerJoin("_emdash_collections as collection", (join) => join.onRef("collection.id", "=", "reconciliation.collection_id").onRef("collection.slug", "=", "reconciliation.collection_slug")).select("reconciliation.collection_id").where("reconciliation.collection_id", "=", input.collectionId).where("reconciliation.collection_slug", "=", input.collectionSlug).where("reconciliation.run_token", "=", input.runToken).where("reconciliation.target_epoch", "=", input.targetEpoch).where("reconciliation.state", "=", "leased").where("reconciliation.lease_token", "=", input.leaseToken).where(this.qualifiedLeaseIsLive("reconciliation.lease_expires_at")).where("status.capture_state", "=", "active").where("status.reconciliation_required", "=", 1).where("status.status", "=", "running").where("status.cursor", "=", input.runToken).where("status.change_epoch", "=", input.targetEpoch))).executeTakeFirst();
|
|
468
|
+
return Number(result.numDeletedRows ?? 0);
|
|
315
469
|
}
|
|
316
470
|
leaseIsLive() {
|
|
317
471
|
return isPostgres(this.db) ? sql`lease_expires_at::timestamptz > clock_timestamp()` : sql`lease_expires_at > strftime('%Y-%m-%dT%H:%M:%fZ', 'now')`;
|
|
@@ -337,7 +491,28 @@ var MediaUsageWorkRepository = class {
|
|
|
337
491
|
${`${offsetSeconds >= 0 ? "+" : ""}${offsetSeconds} seconds`}
|
|
338
492
|
)`;
|
|
339
493
|
}
|
|
494
|
+
claimedWorkBatchInput(payload) {
|
|
495
|
+
if (isPostgres(this.db)) return sql`
|
|
496
|
+
SELECT
|
|
497
|
+
entry.value ->> 'collection_id' AS collection_id,
|
|
498
|
+
entry.value ->> 'content_id' AS content_id,
|
|
499
|
+
CAST(entry.value ->> 'work_version' AS bigint) AS work_version,
|
|
500
|
+
entry.value ->> 'lease_token' AS lease_token
|
|
501
|
+
FROM jsonb_array_elements(${payload}::jsonb) AS entry(value)
|
|
502
|
+
`;
|
|
503
|
+
return sql`
|
|
504
|
+
SELECT
|
|
505
|
+
json_extract(entry.value, '$.collection_id') AS collection_id,
|
|
506
|
+
json_extract(entry.value, '$.content_id') AS content_id,
|
|
507
|
+
CAST(json_extract(entry.value, '$.work_version') AS integer) AS work_version,
|
|
508
|
+
json_extract(entry.value, '$.lease_token') AS lease_token
|
|
509
|
+
FROM json_each(${payload}) AS entry
|
|
510
|
+
`;
|
|
511
|
+
}
|
|
340
512
|
};
|
|
513
|
+
function workIdentityKey(input) {
|
|
514
|
+
return `${input.collectionId}\u0000${input.contentId}\u0000${String(input.workVersion)}`;
|
|
515
|
+
}
|
|
341
516
|
function operatorLimit(value) {
|
|
342
517
|
if (value === void 0) return MEDIA_USAGE_WORK_OPERATOR_DEFAULT_LIMIT;
|
|
343
518
|
if (!Number.isSafeInteger(value) || value < 1 || value > MEDIA_USAGE_WORK_OPERATOR_MAX_LIMIT) throw new Error(`Media usage operator limit must be a whole number from 1 to ${MEDIA_USAGE_WORK_OPERATOR_MAX_LIMIT}`);
|
|
@@ -401,24 +576,11 @@ function rowToOperatorWork(row) {
|
|
|
401
576
|
function isMediaUsageWorkState(value) {
|
|
402
577
|
return value === "pending" || value === "retry" || value === "leased" || value === "failed";
|
|
403
578
|
}
|
|
404
|
-
function compareDueWork(a, b) {
|
|
405
|
-
const eligibility = dueTimestamp(a).localeCompare(dueTimestamp(b));
|
|
406
|
-
if (eligibility !== 0) return eligibility;
|
|
407
|
-
const updated = a.updatedAt.localeCompare(b.updatedAt);
|
|
408
|
-
if (updated !== 0) return updated;
|
|
409
|
-
const collection = a.collectionId.localeCompare(b.collectionId);
|
|
410
|
-
return collection !== 0 ? collection : a.contentId.localeCompare(b.contentId);
|
|
411
|
-
}
|
|
412
579
|
function compareOperatorWork(a, b) {
|
|
413
580
|
const updated = b.updatedAt.localeCompare(a.updatedAt);
|
|
414
581
|
return updated !== 0 ? updated : b.contentId.localeCompare(a.contentId);
|
|
415
582
|
}
|
|
416
|
-
function dueTimestamp(work) {
|
|
417
|
-
if (work.state !== "leased") return work.nextAttemptAt;
|
|
418
|
-
if (!work.leaseExpiresAt) throw new Error("Due leased media usage work must have a lease expiry");
|
|
419
|
-
return work.leaseExpiresAt;
|
|
420
|
-
}
|
|
421
583
|
|
|
422
584
|
//#endregion
|
|
423
585
|
export { MediaUsageWorkRepository as t };
|
|
424
|
-
//# sourceMappingURL=media-usage-work-
|
|
586
|
+
//# sourceMappingURL=media-usage-work-D6D9sMCA.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"media-usage-work-D6D9sMCA.mjs","names":[],"sources":["../src/database/repositories/media-usage-work.ts"],"sourcesContent":["import { sql, type Kysely, type RawBuilder, type Selectable } from \"kysely\";\nimport { ulid } from \"ulidx\";\n\nimport { isPostgres } from \"../dialect-helpers.js\";\nimport type { Database, MediaUsageWorkTable } from \"../types.js\";\nimport { decodeCursor, encodeCursor, type FindManyResult } from \"./types.js\";\n\nexport type MediaUsageWorkState = \"pending\" | \"retry\" | \"leased\" | \"failed\";\nexport type MediaUsageWorkVersion = number | string;\nconst MAX_PORTABLE_DURATION_SECONDS = 365 * 24 * 60 * 60;\nconst MAX_WORK_SELECTION_LIMIT = 1_000;\nconst NON_NEGATIVE_DECIMAL_PATTERN = /^(?:0|[1-9][0-9]*)$/;\nconst POSITIVE_DECIMAL_PATTERN = /^[1-9][0-9]*$/;\nconst STABLE_ERROR_CODE_PATTERN = /^[A-Z][A-Z0-9_]{0,63}$/;\n\nexport const MEDIA_USAGE_WORK_OPERATOR_DEFAULT_LIMIT = 50;\nexport const MEDIA_USAGE_WORK_OPERATOR_MAX_LIMIT = 100;\nexport const MEDIA_USAGE_RECONCILIATION_PAGE_LIMIT = 1_000;\nconst MEDIA_USAGE_WORK_STATES = [\"pending\", \"retry\", \"leased\", \"failed\"] as const;\n\nexport interface MediaUsageWorkIdentity {\n\tcollectionId: string;\n\tcontentId: string;\n\tworkVersion: MediaUsageWorkVersion;\n}\n\nexport interface MediaUsageWorkLease extends MediaUsageWorkIdentity {\n\tleaseToken: string;\n}\n\nexport interface MediaUsageWorkRecord extends MediaUsageWorkIdentity {\n\tcollectionSlug: string;\n\tchangeEpoch: number | string;\n\tstate: MediaUsageWorkState;\n\tattemptCount: number;\n\tnextAttemptAt: string;\n\tleaseToken: string | null;\n\tleaseExpiresAt: string | null;\n\tlastAttemptedAt: string | null;\n\tlastErrorCode: string | null;\n\tcreatedAt: string;\n\tupdatedAt: string;\n}\n\nexport interface MediaUsageOperatorWorkItem {\n\tcollectionId: string;\n\tcollectionSlug: string;\n\tcontentId: string;\n\tstate: MediaUsageWorkState;\n\tattemptCount: number;\n\tnextAttemptAt: string;\n\tleaseExpiresAt: string | null;\n\tlastAttemptedAt: string | null;\n\tlastErrorCode: string | null;\n\tupdatedAt: string;\n}\n\nexport type MediaUsageOperatorRetryResult =\n\t| { outcome: \"pending\"; changed: boolean; work: MediaUsageOperatorWorkItem }\n\t| { outcome: \"lease_active\"; leaseExpiresAt: string }\n\t| { outcome: \"collection_not_found\" }\n\t| { outcome: \"conflict\" };\n\nexport class MediaUsageWorkRepository {\n\tconstructor(private db: Kysely<Database>) {}\n\n\tasync enqueueReconciliationPage(input: {\n\t\tcollectionId: string;\n\t\tcollectionSlug: string;\n\t\trunToken: string;\n\t\tleaseToken: string;\n\t\tchangeEpoch: number | string;\n\t\tphase: \"scan\" | \"sources\";\n\t\tcontentIds: readonly string[];\n\t}): Promise<void> {\n\t\tif (!input.collectionId || !input.collectionSlug || !input.runToken || !input.leaseToken) {\n\t\t\tthrow new Error(\"Reconciliation enqueue requires exact collection and lease identity\");\n\t\t}\n\t\tassertNonNegativeDecimal(input.changeEpoch, \"change epoch\");\n\t\tconst contentIds = [...new Set(input.contentIds)];\n\t\tif (contentIds.length < 1 || contentIds.length > MEDIA_USAGE_RECONCILIATION_PAGE_LIMIT) {\n\t\t\tthrow new Error(\"Reconciliation enqueue requires from 1 to 1000 content IDs\");\n\t\t}\n\t\tif (contentIds.some((contentId) => !contentId)) {\n\t\t\tthrow new Error(\"Reconciliation enqueue content IDs must not be empty\");\n\t\t}\n\t\tconst now = this.timestampOffset(0);\n\t\tconst contentIdsJson = JSON.stringify(contentIds);\n\t\tconst page = isPostgres(this.db)\n\t\t\t? sql`SELECT value::text AS content_id FROM jsonb_array_elements_text(${contentIdsJson}::jsonb) AS value`\n\t\t\t: sql`SELECT value AS content_id FROM json_each(${contentIdsJson})`;\n\t\tawait sql`\n\t\t\tWITH page(content_id) AS (${page})\n\t\t\tINSERT INTO _emdash_media_usage_work (\n\t\t\t\tcollection_id, collection_slug, content_id, change_epoch, work_version,\n\t\t\t\tstate, attempt_count, next_attempt_at, lease_token, lease_expires_at,\n\t\t\t\tlast_attempted_at, last_error_code, created_at, updated_at\n\t\t\t)\n\t\t\tSELECT\n\t\t\t\t${input.collectionId}, ${input.collectionSlug}, page.content_id, ${input.changeEpoch}, 1,\n\t\t\t\t'pending', 0, ${now}, NULL, NULL, NULL, NULL, ${now}, ${now}\n\t\t\tFROM page\n\t\t\tWHERE EXISTS (\n\t\t\t\tSELECT 1\n\t\t\t\tFROM _emdash_media_usage_reconciliations AS reconciliation\n\t\t\t\tINNER JOIN _emdash_media_usage_index_status AS status\n\t\t\t\t\tON status.collection_id = reconciliation.collection_id\n\t\t\t\t\tAND status.scope_key = reconciliation.collection_slug\n\t\t\t\tINNER JOIN _emdash_collections AS collection\n\t\t\t\t\tON collection.id = reconciliation.collection_id\n\t\t\t\t\tAND collection.slug = reconciliation.collection_slug\n\t\t\t\tWHERE reconciliation.collection_id = ${input.collectionId}\n\t\t\t\t\tAND reconciliation.collection_slug = ${input.collectionSlug}\n\t\t\t\t\tAND reconciliation.run_token = ${input.runToken}\n\t\t\t\t\tAND reconciliation.target_epoch = ${input.changeEpoch}\n\t\t\t\t\tAND reconciliation.state = 'leased'\n\t\t\t\t\tAND reconciliation.phase = ${input.phase}\n\t\t\t\t\tAND reconciliation.lease_token = ${input.leaseToken}\n\t\t\t\t\tAND ${this.qualifiedLeaseIsLive(\"reconciliation.lease_expires_at\")}\n\t\t\t\t\tAND status.adapter_id = 'content-media'\n\t\t\t\t\tAND status.scope_type = 'collection'\n\t\t\t\t\tAND status.capture_state = 'active'\n\t\t\t\t\tAND status.reconciliation_required = 1\n\t\t\t\t\tAND status.status = 'running'\n\t\t\t\t\tAND status.cursor = ${input.runToken}\n\t\t\t\t\tAND status.change_epoch = ${input.changeEpoch}\n\t\t\t\t\tAND EXISTS (\n\t\t\t\t\t\tSELECT 1 FROM _emdash_media_usage_activation AS activation\n\t\t\t\t\t\tWHERE activation.task_key = 'incremental_capture'\n\t\t\t\t\t\t\tAND activation.state = 'active'\n\t\t\t\t\t)\n\t\t\t\t\tAND NOT EXISTS (\n\t\t\t\t\t\tSELECT 1 FROM _emdash_media_usage_collection_deletions AS deletion\n\t\t\t\t\t\tWHERE deletion.collection_id = reconciliation.collection_id\n\t\t\t\t\t)\n\t\t\t)\n\t\t\tON CONFLICT (collection_id, content_id) DO UPDATE SET\n\t\t\t\tcollection_slug = excluded.collection_slug,\n\t\t\t\tchange_epoch = excluded.change_epoch,\n\t\t\t\twork_version = _emdash_media_usage_work.work_version + 1,\n\t\t\t\tstate = 'pending',\n\t\t\t\tattempt_count = 0,\n\t\t\t\tnext_attempt_at = excluded.next_attempt_at,\n\t\t\t\tlease_token = NULL,\n\t\t\t\tlease_expires_at = NULL,\n\t\t\t\tlast_attempted_at = NULL,\n\t\t\t\tlast_error_code = NULL,\n\t\t\t\tupdated_at = excluded.updated_at\n\t\t\tWHERE _emdash_media_usage_work.change_epoch < excluded.change_epoch\n\t\t`.execute(this.db);\n\t}\n\n\tasync findOperatorPage(options: {\n\t\tcollectionSlug: string;\n\t\tstate?: MediaUsageWorkState;\n\t\tlimit?: number;\n\t\tcursor?: string;\n\t}): Promise<FindManyResult<MediaUsageOperatorWorkItem> | null> {\n\t\tif (!options.collectionSlug) {\n\t\t\tthrow new Error(\"Media usage work listing requires a collection slug\");\n\t\t}\n\t\tif (options.state !== undefined && !isMediaUsageWorkState(options.state)) {\n\t\t\tthrow new Error(\"Media usage work listing requires a valid state\");\n\t\t}\n\t\tconst limit = operatorLimit(options.limit);\n\t\tconst cursor = options.cursor ? decodeCursor(options.cursor) : null;\n\t\tconst collection = await this.db\n\t\t\t.selectFrom(\"_emdash_collections\")\n\t\t\t.select([\"id\", \"slug\"])\n\t\t\t.where(\"slug\", \"=\", options.collectionSlug)\n\t\t\t.executeTakeFirst();\n\t\tif (!collection) return null;\n\n\t\tconst states = options.state ? [options.state] : MEDIA_USAGE_WORK_STATES;\n\t\tconst candidates: MediaUsageOperatorWorkItem[] = [];\n\t\tfor (const state of states) {\n\t\t\tconst rows = await this.findOperatorRows({\n\t\t\t\tcollectionId: collection.id,\n\t\t\t\tcollectionSlug: collection.slug,\n\t\t\t\tstate,\n\t\t\t\tlimit: limit + 1,\n\t\t\t\tcursor,\n\t\t\t});\n\t\t\tcandidates.push(...rows.map(rowToOperatorWork));\n\t\t}\n\n\t\tconst ordered = candidates.toSorted(compareOperatorWork);\n\t\tconst items = ordered.slice(0, limit);\n\t\tconst result: FindManyResult<MediaUsageOperatorWorkItem> = { items };\n\t\tif (ordered.length > limit && items.length > 0) {\n\t\t\tconst last = items.at(-1)!;\n\t\t\tresult.nextCursor = encodeCursor(last.updatedAt, last.contentId);\n\t\t}\n\t\treturn result;\n\t}\n\n\tprivate async findOperatorRows(input: {\n\t\tcollectionId: string;\n\t\tcollectionSlug: string;\n\t\tstate: MediaUsageWorkState;\n\t\tlimit: number;\n\t\tcursor: { orderValue: string; id: string } | null;\n\t}): Promise<Selectable<MediaUsageWorkTable>[]> {\n\t\tlet query = this.db\n\t\t\t.selectFrom(\"_emdash_media_usage_work as work\")\n\t\t\t.innerJoin(\"_emdash_collections as current_collection\", (join) =>\n\t\t\t\tjoin\n\t\t\t\t\t.onRef(\"current_collection.id\", \"=\", \"work.collection_id\")\n\t\t\t\t\t.onRef(\"current_collection.slug\", \"=\", \"work.collection_slug\"),\n\t\t\t)\n\t\t\t.selectAll(\"work\")\n\t\t\t.where(\"work.collection_id\", \"=\", input.collectionId)\n\t\t\t.where(\"work.collection_slug\", \"=\", input.collectionSlug)\n\t\t\t.where(\"work.state\", \"=\", input.state);\n\t\tif (input.cursor) {\n\t\t\tquery = query.where((eb) =>\n\t\t\t\teb.or([\n\t\t\t\t\teb(\"work.updated_at\", \"<\", input.cursor!.orderValue),\n\t\t\t\t\teb.and([\n\t\t\t\t\t\teb(\"work.updated_at\", \"=\", input.cursor!.orderValue),\n\t\t\t\t\t\teb(\"work.content_id\", \"<\", input.cursor!.id),\n\t\t\t\t\t]),\n\t\t\t\t]),\n\t\t\t);\n\t\t}\n\t\treturn query\n\t\t\t.orderBy(\"work.updated_at\", \"desc\")\n\t\t\t.orderBy(\"work.content_id\", \"desc\")\n\t\t\t.limit(input.limit)\n\t\t\t.execute();\n\t}\n\n\tasync retryOperatorWork(input: {\n\t\tcollectionId: string;\n\t\tcontentId: string;\n\t}): Promise<MediaUsageOperatorRetryResult> {\n\t\tif (!input.collectionId || !input.contentId) {\n\t\t\tthrow new Error(\"Media usage operator retry requires collection and content IDs\");\n\t\t}\n\t\tconst collection = await this.findActiveOperatorCollection(input.collectionId);\n\t\tif (!collection) return { outcome: \"collection_not_found\" };\n\n\t\tconst observed = await this.findWorkByIdentity(input.collectionId, input.contentId);\n\t\tif (observed?.state === \"pending\" && observed.collection_slug === collection.slug) {\n\t\t\treturn { outcome: \"pending\", changed: false, work: rowToOperatorWork(observed) };\n\t\t}\n\n\t\tconst invalidated = await this.invalidateCoverageForOperatorRetry({\n\t\t\t...input,\n\t\t\tcollectionSlug: collection.slug,\n\t\t\tobserved,\n\t\t});\n\t\tif (!invalidated) return this.operatorRetryLost(input);\n\n\t\tconst reopened = observed\n\t\t\t? await this.reopenObservedWork(observed, collection.slug, invalidated.change_epoch)\n\t\t\t: await this.createOperatorWork({\n\t\t\t\t\t...input,\n\t\t\t\t\tcollectionSlug: collection.slug,\n\t\t\t\t\tchangeEpoch: invalidated.change_epoch,\n\t\t\t\t});\n\t\tif (reopened) {\n\t\t\treturn { outcome: \"pending\", changed: true, work: rowToOperatorWork(reopened) };\n\t\t}\n\t\treturn this.operatorRetryLost(input);\n\t}\n\n\tprivate async findActiveOperatorCollection(\n\t\tcollectionId: string,\n\t): Promise<{ id: string; slug: string } | null> {\n\t\tconst row = await this.db\n\t\t\t.selectFrom(\"_emdash_collections as collection\")\n\t\t\t.innerJoin(\"_emdash_media_usage_index_status as status\", (join) =>\n\t\t\t\tjoin\n\t\t\t\t\t.onRef(\"status.collection_id\", \"=\", \"collection.id\")\n\t\t\t\t\t.onRef(\"status.scope_key\", \"=\", \"collection.slug\"),\n\t\t\t)\n\t\t\t.select([\"collection.id\", \"collection.slug\"])\n\t\t\t.where(\"collection.id\", \"=\", collectionId)\n\t\t\t.where(\"status.adapter_id\", \"=\", \"content-media\")\n\t\t\t.where(\"status.scope_type\", \"=\", \"collection\")\n\t\t\t.where(\"status.capture_state\", \"=\", \"active\")\n\t\t\t.executeTakeFirst();\n\t\treturn row ?? null;\n\t}\n\n\tprivate async findWorkByIdentity(\n\t\tcollectionId: string,\n\t\tcontentId: string,\n\t): Promise<Selectable<MediaUsageWorkTable> | null> {\n\t\treturn (\n\t\t\t(await this.db\n\t\t\t\t.selectFrom(\"_emdash_media_usage_work\")\n\t\t\t\t.selectAll()\n\t\t\t\t.where(\"collection_id\", \"=\", collectionId)\n\t\t\t\t.where(\"content_id\", \"=\", contentId)\n\t\t\t\t.executeTakeFirst()) ?? null\n\t\t);\n\t}\n\n\tprivate async invalidateCoverageForOperatorRetry(input: {\n\t\tcollectionId: string;\n\t\tcollectionSlug: string;\n\t\tcontentId: string;\n\t\tobserved: Selectable<MediaUsageWorkTable> | null;\n\t}): Promise<{ change_epoch: number | string } | null> {\n\t\tlet query = this.db\n\t\t\t.updateTable(\"_emdash_media_usage_index_status as status\")\n\t\t\t.set({\n\t\t\t\tchange_epoch: sql<number>`change_epoch + 1`,\n\t\t\t\tstatus: sql<string>`CASE WHEN status IN ('complete', 'partial', 'failed') THEN 'stale' ELSE status END`,\n\t\t\t\tcompleted_at: sql<\n\t\t\t\t\tstring | null\n\t\t\t\t>`CASE WHEN status IN ('complete', 'partial', 'failed') THEN NULL ELSE completed_at END`,\n\t\t\t\tlast_error_code: null,\n\t\t\t\tupdated_at: this.timestampOffset(0),\n\t\t\t})\n\t\t\t.where(\"status.adapter_id\", \"=\", \"content-media\")\n\t\t\t.where(\"status.scope_type\", \"=\", \"collection\")\n\t\t\t.where(\"status.scope_key\", \"=\", input.collectionSlug)\n\t\t\t.where(\"status.collection_id\", \"=\", input.collectionId)\n\t\t\t.where(\"status.capture_state\", \"=\", \"active\")\n\t\t\t.where((eb) =>\n\t\t\t\teb.exists(\n\t\t\t\t\teb\n\t\t\t\t\t\t.selectFrom(\"_emdash_collections as collection\")\n\t\t\t\t\t\t.select(\"collection.id\")\n\t\t\t\t\t\t.whereRef(\"collection.id\", \"=\", \"status.collection_id\")\n\t\t\t\t\t\t.whereRef(\"collection.slug\", \"=\", \"status.scope_key\"),\n\t\t\t\t),\n\t\t\t);\n\n\t\tconst observed = input.observed;\n\t\tif (observed) {\n\t\t\tquery = query.where((eb) => {\n\t\t\t\tlet work = eb\n\t\t\t\t\t.selectFrom(\"_emdash_media_usage_work as work\")\n\t\t\t\t\t.select(\"work.content_id\")\n\t\t\t\t\t.whereRef(\"work.collection_id\", \"=\", \"status.collection_id\")\n\t\t\t\t\t.where(\"work.content_id\", \"=\", input.contentId)\n\t\t\t\t\t.where(\"work.work_version\", \"=\", observed.work_version)\n\t\t\t\t\t.where(\"work.state\", \"=\", observed.state);\n\t\t\t\tif (observed.state === \"leased\") {\n\t\t\t\t\twork = work\n\t\t\t\t\t\t.where(\"work.lease_expires_at\", \"is not\", null)\n\t\t\t\t\t\t.where(this.timestampIsDue(\"work.lease_expires_at\"));\n\t\t\t\t}\n\t\t\t\treturn eb.exists(work);\n\t\t\t});\n\t\t} else {\n\t\t\tquery = query.where((eb) =>\n\t\t\t\teb.not(\n\t\t\t\t\teb.exists(\n\t\t\t\t\t\teb\n\t\t\t\t\t\t\t.selectFrom(\"_emdash_media_usage_work as work\")\n\t\t\t\t\t\t\t.select(\"work.content_id\")\n\t\t\t\t\t\t\t.whereRef(\"work.collection_id\", \"=\", \"status.collection_id\")\n\t\t\t\t\t\t\t.where(\"work.content_id\", \"=\", input.contentId),\n\t\t\t\t\t),\n\t\t\t\t),\n\t\t\t);\n\t\t}\n\n\t\treturn (await query.returning(\"change_epoch\").executeTakeFirst()) ?? null;\n\t}\n\n\tprivate async reopenObservedWork(\n\t\tobserved: Selectable<MediaUsageWorkTable>,\n\t\tcollectionSlug: string,\n\t\tchangeEpoch: number | string,\n\t): Promise<Selectable<MediaUsageWorkTable> | null> {\n\t\tlet query = this.db\n\t\t\t.updateTable(\"_emdash_media_usage_work\")\n\t\t\t.set({\n\t\t\t\tcollection_slug: collectionSlug,\n\t\t\t\tchange_epoch: changeEpoch,\n\t\t\t\twork_version: sql<number>`work_version + 1`,\n\t\t\t\tstate: \"pending\",\n\t\t\t\tattempt_count: 0,\n\t\t\t\tnext_attempt_at: this.timestampOffset(0),\n\t\t\t\tlease_token: null,\n\t\t\t\tlease_expires_at: null,\n\t\t\t\tlast_attempted_at: null,\n\t\t\t\tlast_error_code: null,\n\t\t\t\tupdated_at: this.timestampOffset(0),\n\t\t\t})\n\t\t\t.where(\"collection_id\", \"=\", observed.collection_id)\n\t\t\t.where(\"content_id\", \"=\", observed.content_id)\n\t\t\t.where(\"work_version\", \"=\", observed.work_version)\n\t\t\t.where(\"state\", \"=\", observed.state)\n\t\t\t.where((eb) =>\n\t\t\t\teb.exists(\n\t\t\t\t\teb\n\t\t\t\t\t\t.selectFrom(\"_emdash_collections as collection\")\n\t\t\t\t\t\t.innerJoin(\"_emdash_media_usage_index_status as status\", (join) =>\n\t\t\t\t\t\t\tjoin\n\t\t\t\t\t\t\t\t.onRef(\"status.collection_id\", \"=\", \"collection.id\")\n\t\t\t\t\t\t\t\t.onRef(\"status.scope_key\", \"=\", \"collection.slug\"),\n\t\t\t\t\t\t)\n\t\t\t\t\t\t.select(\"collection.id\")\n\t\t\t\t\t\t.where(\"collection.id\", \"=\", observed.collection_id)\n\t\t\t\t\t\t.where(\"collection.slug\", \"=\", collectionSlug)\n\t\t\t\t\t\t.where(\"status.adapter_id\", \"=\", \"content-media\")\n\t\t\t\t\t\t.where(\"status.scope_type\", \"=\", \"collection\")\n\t\t\t\t\t\t.where(\"status.capture_state\", \"=\", \"active\")\n\t\t\t\t\t\t.where(\"status.change_epoch\", \"=\", changeEpoch),\n\t\t\t\t),\n\t\t\t);\n\t\tif (observed.state === \"leased\") {\n\t\t\tquery = query\n\t\t\t\t.where(\"lease_expires_at\", \"is not\", null)\n\t\t\t\t.where(this.timestampIsDue(\"lease_expires_at\"));\n\t\t}\n\t\treturn (await query.returningAll().executeTakeFirst()) ?? null;\n\t}\n\n\tprivate async createOperatorWork(input: {\n\t\tcollectionId: string;\n\t\tcollectionSlug: string;\n\t\tcontentId: string;\n\t\tchangeEpoch: number | string;\n\t}): Promise<Selectable<MediaUsageWorkTable> | null> {\n\t\tconst now = this.timestampOffset(0);\n\t\treturn (\n\t\t\t(await this.db\n\t\t\t\t.insertInto(\"_emdash_media_usage_work\")\n\t\t\t\t.columns([\n\t\t\t\t\t\"collection_id\",\n\t\t\t\t\t\"collection_slug\",\n\t\t\t\t\t\"content_id\",\n\t\t\t\t\t\"change_epoch\",\n\t\t\t\t\t\"work_version\",\n\t\t\t\t\t\"state\",\n\t\t\t\t\t\"attempt_count\",\n\t\t\t\t\t\"next_attempt_at\",\n\t\t\t\t\t\"lease_token\",\n\t\t\t\t\t\"lease_expires_at\",\n\t\t\t\t\t\"last_attempted_at\",\n\t\t\t\t\t\"last_error_code\",\n\t\t\t\t\t\"created_at\",\n\t\t\t\t\t\"updated_at\",\n\t\t\t\t])\n\t\t\t\t.expression((insert) =>\n\t\t\t\t\tinsert\n\t\t\t\t\t\t.selectFrom(\"_emdash_media_usage_index_status as status\")\n\t\t\t\t\t\t.innerJoin(\"_emdash_collections as collection\", (join) =>\n\t\t\t\t\t\t\tjoin\n\t\t\t\t\t\t\t\t.onRef(\"collection.id\", \"=\", \"status.collection_id\")\n\t\t\t\t\t\t\t\t.onRef(\"collection.slug\", \"=\", \"status.scope_key\"),\n\t\t\t\t\t\t)\n\t\t\t\t\t\t.select((select) => [\n\t\t\t\t\t\t\tselect.val(input.collectionId).as(\"collection_id\"),\n\t\t\t\t\t\t\t\"collection.slug as collection_slug\",\n\t\t\t\t\t\t\tselect.val(input.contentId).as(\"content_id\"),\n\t\t\t\t\t\t\t\"status.change_epoch as change_epoch\",\n\t\t\t\t\t\t\tselect.val(1).as(\"work_version\"),\n\t\t\t\t\t\t\tselect.val(\"pending\").as(\"state\"),\n\t\t\t\t\t\t\tselect.val(0).as(\"attempt_count\"),\n\t\t\t\t\t\t\tnow.as(\"next_attempt_at\"),\n\t\t\t\t\t\t\tsql<null>`NULL`.as(\"lease_token\"),\n\t\t\t\t\t\t\tsql<null>`NULL`.as(\"lease_expires_at\"),\n\t\t\t\t\t\t\tsql<null>`NULL`.as(\"last_attempted_at\"),\n\t\t\t\t\t\t\tsql<null>`NULL`.as(\"last_error_code\"),\n\t\t\t\t\t\t\tnow.as(\"created_at\"),\n\t\t\t\t\t\t\tnow.as(\"updated_at\"),\n\t\t\t\t\t\t])\n\t\t\t\t\t\t.where(\"status.adapter_id\", \"=\", \"content-media\")\n\t\t\t\t\t\t.where(\"status.scope_type\", \"=\", \"collection\")\n\t\t\t\t\t\t.where(\"status.scope_key\", \"=\", input.collectionSlug)\n\t\t\t\t\t\t.where(\"status.collection_id\", \"=\", input.collectionId)\n\t\t\t\t\t\t.where(\"status.capture_state\", \"=\", \"active\")\n\t\t\t\t\t\t.where(\"status.change_epoch\", \"=\", input.changeEpoch),\n\t\t\t\t)\n\t\t\t\t.onConflict((conflict) => conflict.columns([\"collection_id\", \"content_id\"]).doNothing())\n\t\t\t\t.returningAll()\n\t\t\t\t.executeTakeFirst()) ?? null\n\t\t);\n\t}\n\n\tprivate async operatorRetryLost(input: {\n\t\tcollectionId: string;\n\t\tcontentId: string;\n\t}): Promise<MediaUsageOperatorRetryResult> {\n\t\tif (!(await this.findActiveOperatorCollection(input.collectionId))) {\n\t\t\treturn { outcome: \"collection_not_found\" };\n\t\t}\n\t\tconst current = await this.findWorkByIdentity(input.collectionId, input.contentId);\n\t\tif (current?.state === \"pending\") {\n\t\t\treturn { outcome: \"pending\", changed: false, work: rowToOperatorWork(current) };\n\t\t}\n\t\tconst liveLease = await this.findLiveLeaseExpiry(input.collectionId, input.contentId);\n\t\tif (liveLease) return { outcome: \"lease_active\", leaseExpiresAt: liveLease };\n\t\treturn { outcome: \"conflict\" };\n\t}\n\n\tprivate async findLiveLeaseExpiry(\n\t\tcollectionId: string,\n\t\tcontentId: string,\n\t): Promise<string | null> {\n\t\tconst row = await this.db\n\t\t\t.selectFrom(\"_emdash_media_usage_work\")\n\t\t\t.select(\"lease_expires_at\")\n\t\t\t.where(\"collection_id\", \"=\", collectionId)\n\t\t\t.where(\"content_id\", \"=\", contentId)\n\t\t\t.where(\"state\", \"=\", \"leased\")\n\t\t\t.where(\"lease_expires_at\", \"is not\", null)\n\t\t\t.where(this.leaseIsLive())\n\t\t\t.executeTakeFirst();\n\t\treturn row?.lease_expires_at ?? null;\n\t}\n\n\tasync claimDueWorkBatch(input: {\n\t\tlimit: number;\n\t\tleaseDurationSeconds: number;\n\t}): Promise<MediaUsageWorkRecord[]> {\n\t\tif (\n\t\t\t!Number.isSafeInteger(input.limit) ||\n\t\t\tinput.limit < 1 ||\n\t\t\tinput.limit > MAX_WORK_SELECTION_LIMIT\n\t\t) {\n\t\t\tthrow new Error(\n\t\t\t\t`Media usage due-work limit must be a whole number from 1 to ${MAX_WORK_SELECTION_LIMIT}`,\n\t\t\t);\n\t\t}\n\t\tconst leaseDurationSeconds = durationSeconds(\n\t\t\tinput.leaseDurationSeconds,\n\t\t\t\"lease duration\",\n\t\t\tfalse,\n\t\t);\n\t\tconst leaseToken = ulid();\n\t\tconst now = this.timestampOffset(0);\n\t\tlet candidates = this.db\n\t\t\t.selectFrom(\"_emdash_media_usage_work as due\")\n\t\t\t.select([\"due.collection_id\", \"due.content_id\", \"due.work_version\"])\n\t\t\t.where((eb) =>\n\t\t\t\teb.or([\n\t\t\t\t\teb.and([\n\t\t\t\t\t\teb(\"due.state\", \"in\", [\"pending\", \"retry\"]),\n\t\t\t\t\t\tthis.timestampIsDue(\"due.next_attempt_at\"),\n\t\t\t\t\t]),\n\t\t\t\t\teb.and([\n\t\t\t\t\t\teb(\"due.state\", \"=\", \"leased\"),\n\t\t\t\t\t\teb(\"due.lease_expires_at\", \"is not\", null),\n\t\t\t\t\t\tthis.timestampIsDue(\"due.lease_expires_at\"),\n\t\t\t\t\t]),\n\t\t\t\t]),\n\t\t\t)\n\t\t\t.orderBy(\n\t\t\t\tsql<string>`CASE\n\t\t\t\t\tWHEN due.state = 'leased' THEN due.lease_expires_at\n\t\t\t\t\tELSE due.next_attempt_at\n\t\t\t\tEND`,\n\t\t\t\t\"asc\",\n\t\t\t)\n\t\t\t.orderBy(\"due.updated_at\", \"asc\")\n\t\t\t.orderBy(\"due.collection_id\", \"asc\")\n\t\t\t.orderBy(\"due.content_id\", \"asc\")\n\t\t\t.limit(input.limit);\n\t\tif (isPostgres(this.db)) candidates = candidates.forUpdate().skipLocked();\n\t\tconst rows = await this.db\n\t\t\t.with(\"due_media_usage_work\", () => candidates)\n\t\t\t.updateTable(\"_emdash_media_usage_work\")\n\t\t\t.set({\n\t\t\t\tstate: \"leased\",\n\t\t\t\tlease_token: leaseToken,\n\t\t\t\tlease_expires_at: this.timestampOffset(leaseDurationSeconds),\n\t\t\t\tlast_attempted_at: now,\n\t\t\t\tupdated_at: now,\n\t\t\t})\n\t\t\t.where((eb) =>\n\t\t\t\teb.and([\n\t\t\t\t\teb.exists(\n\t\t\t\t\t\teb\n\t\t\t\t\t\t\t.selectFrom(\"due_media_usage_work as due\")\n\t\t\t\t\t\t\t.select(\"due.content_id\")\n\t\t\t\t\t\t\t.whereRef(\"due.collection_id\", \"=\", \"_emdash_media_usage_work.collection_id\")\n\t\t\t\t\t\t\t.whereRef(\"due.content_id\", \"=\", \"_emdash_media_usage_work.content_id\")\n\t\t\t\t\t\t\t.whereRef(\"due.work_version\", \"=\", \"_emdash_media_usage_work.work_version\"),\n\t\t\t\t\t),\n\t\t\t\t\teb.or([\n\t\t\t\t\t\teb.and([\n\t\t\t\t\t\t\teb(\"state\", \"in\", [\"pending\", \"retry\"]),\n\t\t\t\t\t\t\tthis.timestampIsDue(\"next_attempt_at\"),\n\t\t\t\t\t\t]),\n\t\t\t\t\t\teb.and([\n\t\t\t\t\t\t\teb(\"state\", \"=\", \"leased\"),\n\t\t\t\t\t\t\teb(\"lease_expires_at\", \"is not\", null),\n\t\t\t\t\t\t\tthis.timestampIsDue(\"lease_expires_at\"),\n\t\t\t\t\t\t]),\n\t\t\t\t\t]),\n\t\t\t\t]),\n\t\t\t)\n\t\t\t.returningAll()\n\t\t\t.execute();\n\n\t\treturn rows.map(rowToWork);\n\t}\n\n\tasync hasNonterminalWork(): Promise<boolean> {\n\t\tconst row = await this.db\n\t\t\t.selectFrom(\"_emdash_media_usage_work\")\n\t\t\t.select(\"content_id\")\n\t\t\t.where(\"state\", \"in\", [\"pending\", \"retry\", \"leased\"])\n\t\t\t.limit(1)\n\t\t\t.executeTakeFirst();\n\t\treturn row !== undefined;\n\t}\n\n\tasync findWorkForContent(\n\t\tcollectionSlug: string,\n\t\tcontentId: string,\n\t): Promise<MediaUsageWorkRecord | null> {\n\t\tif (!collectionSlug || !contentId) {\n\t\t\tthrow new Error(\"Media usage work lookup requires collection and content identity\");\n\t\t}\n\t\tconst row = await this.db\n\t\t\t.selectFrom(\"_emdash_media_usage_work\")\n\t\t\t.innerJoin(\"_emdash_collections as current_collection\", (join) =>\n\t\t\t\tjoin\n\t\t\t\t\t.onRef(\"current_collection.id\", \"=\", \"_emdash_media_usage_work.collection_id\")\n\t\t\t\t\t.onRef(\"current_collection.slug\", \"=\", \"_emdash_media_usage_work.collection_slug\"),\n\t\t\t)\n\t\t\t.selectAll(\"_emdash_media_usage_work\")\n\t\t\t.where(\"_emdash_media_usage_work.collection_slug\", \"=\", collectionSlug)\n\t\t\t.where(\"_emdash_media_usage_work.content_id\", \"=\", contentId)\n\t\t\t.executeTakeFirst();\n\t\treturn row ? rowToWork(row) : null;\n\t}\n\n\tasync claimWork(\n\t\tinput: MediaUsageWorkIdentity & {\n\t\t\tleaseDurationSeconds: number;\n\t\t},\n\t): Promise<MediaUsageWorkRecord | null> {\n\t\tassertIdentity(input);\n\t\tconst leaseDurationSeconds = durationSeconds(\n\t\t\tinput.leaseDurationSeconds,\n\t\t\t\"lease duration\",\n\t\t\tfalse,\n\t\t);\n\t\tconst leaseToken = ulid();\n\t\tconst now = this.timestampOffset(0);\n\t\tconst row = await this.db\n\t\t\t.updateTable(\"_emdash_media_usage_work\")\n\t\t\t.set({\n\t\t\t\tstate: \"leased\",\n\t\t\t\tlease_token: leaseToken,\n\t\t\t\tlease_expires_at: this.timestampOffset(leaseDurationSeconds),\n\t\t\t\tlast_attempted_at: now,\n\t\t\t\tupdated_at: now,\n\t\t\t})\n\t\t\t.where(\"collection_id\", \"=\", input.collectionId)\n\t\t\t.where(\"content_id\", \"=\", input.contentId)\n\t\t\t.where(\"work_version\", \"=\", input.workVersion)\n\t\t\t.where((eb) =>\n\t\t\t\teb.or([\n\t\t\t\t\teb.and([eb(\"state\", \"in\", [\"pending\", \"retry\"]), this.timestampIsDue(\"next_attempt_at\")]),\n\t\t\t\t\teb.and([\n\t\t\t\t\t\teb(\"state\", \"=\", \"leased\"),\n\t\t\t\t\t\teb(\"lease_expires_at\", \"is not\", null),\n\t\t\t\t\t\tthis.timestampIsDue(\"lease_expires_at\"),\n\t\t\t\t\t]),\n\t\t\t\t]),\n\t\t\t)\n\t\t\t.returningAll()\n\t\t\t.executeTakeFirst();\n\n\t\treturn row ? rowToWork(row) : null;\n\t}\n\n\tasync completeWorkBatch(inputs: readonly MediaUsageWorkLease[]): Promise<Set<string>> {\n\t\tconst unique = [\n\t\t\t...new Map(\n\t\t\t\tinputs.map((input) => {\n\t\t\t\t\tassertLease(input);\n\t\t\t\t\treturn [workIdentityKey(input), input] as const;\n\t\t\t\t}),\n\t\t\t).values(),\n\t\t];\n\t\tconst completed = new Set<string>();\n\t\tif (unique.length === 0) return completed;\n\t\tconst payload = JSON.stringify(\n\t\t\tunique.map((input) => ({\n\t\t\t\tcollection_id: input.collectionId,\n\t\t\t\tcontent_id: input.contentId,\n\t\t\t\twork_version: String(input.workVersion),\n\t\t\t\tlease_token: input.leaseToken,\n\t\t\t})),\n\t\t);\n\t\tconst claimed = this.claimedWorkBatchInput(payload);\n\t\tconst result = await sql<{\n\t\t\tcollection_id: string;\n\t\t\tcontent_id: string;\n\t\t\twork_version: MediaUsageWorkVersion;\n\t\t}>`\n\t\t\tWITH claimed AS (${claimed})\n\t\t\tDELETE FROM _emdash_media_usage_work AS work\n\t\t\tWHERE work.state = 'leased'\n\t\t\t\tAND ${this.qualifiedLeaseIsLive(\"work.lease_expires_at\")}\n\t\t\t\tAND EXISTS (\n\t\t\t\t\tSELECT 1\n\t\t\t\t\tFROM claimed\n\t\t\t\t\tWHERE claimed.collection_id = work.collection_id\n\t\t\t\t\t\tAND claimed.content_id = work.content_id\n\t\t\t\t\t\tAND claimed.work_version = work.work_version\n\t\t\t\t\t\tAND claimed.lease_token = work.lease_token\n\t\t\t\t)\n\t\t\tRETURNING collection_id, content_id, work_version\n\t\t`.execute(this.db);\n\t\tfor (const row of result.rows) {\n\t\t\tcompleted.add(\n\t\t\t\tworkIdentityKey({\n\t\t\t\t\tcollectionId: row.collection_id,\n\t\t\t\t\tcontentId: row.content_id,\n\t\t\t\t\tworkVersion: row.work_version,\n\t\t\t\t}),\n\t\t\t);\n\t\t}\n\t\treturn completed;\n\t}\n\n\tasync lockClaimedWorkBatch(inputs: readonly MediaUsageWorkLease[]): Promise<Set<string>> {\n\t\tconst unique = [\n\t\t\t...new Map(\n\t\t\t\tinputs.map((input) => {\n\t\t\t\t\tassertLease(input);\n\t\t\t\t\treturn [workIdentityKey(input), input] as const;\n\t\t\t\t}),\n\t\t\t).values(),\n\t\t].toSorted((left, right) => workIdentityKey(left).localeCompare(workIdentityKey(right)));\n\t\tif (!isPostgres(this.db)) return new Set(unique.map(workIdentityKey));\n\t\tif (unique.length === 0) return new Set();\n\t\tconst payload = JSON.stringify(\n\t\t\tunique.map((input) => ({\n\t\t\t\tcollection_id: input.collectionId,\n\t\t\t\tcontent_id: input.contentId,\n\t\t\t\twork_version: String(input.workVersion),\n\t\t\t\tlease_token: input.leaseToken,\n\t\t\t})),\n\t\t);\n\t\tconst claimed = this.claimedWorkBatchInput(payload);\n\t\tconst result = await sql<{\n\t\t\tcollection_id: string;\n\t\t\tcontent_id: string;\n\t\t\twork_version: MediaUsageWorkVersion;\n\t\t}>`\n\t\t\tWITH claimed AS (${claimed})\n\t\t\tSELECT work.collection_id, work.content_id, work.work_version\n\t\t\tFROM _emdash_media_usage_work AS work\n\t\t\tINNER JOIN claimed\n\t\t\t\tON claimed.collection_id = work.collection_id\n\t\t\t\tAND claimed.content_id = work.content_id\n\t\t\t\tAND claimed.work_version = work.work_version\n\t\t\t\tAND claimed.lease_token = work.lease_token\n\t\t\tWHERE work.state = 'leased'\n\t\t\t\tAND ${this.qualifiedLeaseIsLive(\"work.lease_expires_at\")}\n\t\t\tORDER BY work.collection_id, work.content_id\n\t\t\tFOR UPDATE\n\t\t`.execute(this.db);\n\t\treturn new Set(\n\t\t\tresult.rows.map((row) =>\n\t\t\t\tworkIdentityKey({\n\t\t\t\t\tcollectionId: row.collection_id,\n\t\t\t\t\tcontentId: row.content_id,\n\t\t\t\t\tworkVersion: row.work_version,\n\t\t\t\t}),\n\t\t\t),\n\t\t);\n\t}\n\n\tasync retryClaimedWorkBatch(input: {\n\t\twork: readonly MediaUsageWorkLease[];\n\t\terrorCode: string;\n\t\tretryDelaySeconds: number;\n\t\tmaxAttempts: number;\n\t}): Promise<Map<string, \"retry\" | \"failed\">> {\n\t\tassertErrorCode(input.errorCode);\n\t\tconst retryDelaySeconds = durationSeconds(input.retryDelaySeconds, \"retry delay\", true);\n\t\tif (!Number.isSafeInteger(input.maxAttempts) || input.maxAttempts < 1) {\n\t\t\tthrow new Error(\"Media usage work max attempts must be a positive whole number\");\n\t\t}\n\t\tconst unique = [\n\t\t\t...new Map(\n\t\t\t\tinput.work.map((work) => {\n\t\t\t\t\tassertLease(work);\n\t\t\t\t\treturn [workIdentityKey(work), work] as const;\n\t\t\t\t}),\n\t\t\t).values(),\n\t\t];\n\t\tconst transitioned = new Map<string, \"retry\" | \"failed\">();\n\t\tif (unique.length === 0) return transitioned;\n\t\tconst payload = JSON.stringify(\n\t\t\tunique.map((work) => ({\n\t\t\t\tcollection_id: work.collectionId,\n\t\t\t\tcontent_id: work.contentId,\n\t\t\t\twork_version: String(work.workVersion),\n\t\t\t\tlease_token: work.leaseToken,\n\t\t\t})),\n\t\t);\n\t\tconst claimed = this.claimedWorkBatchInput(payload);\n\t\tconst result = await sql<{\n\t\t\tcollection_id: string;\n\t\t\tcontent_id: string;\n\t\t\twork_version: MediaUsageWorkVersion;\n\t\t\tstate: \"retry\" | \"failed\";\n\t\t}>`\n\t\t\tWITH claimed AS (${claimed})\n\t\t\tUPDATE _emdash_media_usage_work AS work\n\t\t\tSET state = CASE WHEN work.attempt_count + 1 >= ${input.maxAttempts} THEN 'failed' ELSE 'retry' END,\n\t\t\t\tattempt_count = work.attempt_count + 1,\n\t\t\t\tnext_attempt_at = ${this.timestampOffset(retryDelaySeconds)},\n\t\t\t\tlease_token = NULL,\n\t\t\t\tlease_expires_at = NULL,\n\t\t\t\tlast_error_code = ${input.errorCode},\n\t\t\t\tupdated_at = ${this.timestampOffset(0)}\n\t\t\tWHERE work.state = 'leased'\n\t\t\t\tAND ${this.qualifiedLeaseIsLive(\"work.lease_expires_at\")}\n\t\t\t\tAND EXISTS (\n\t\t\t\t\tSELECT 1\n\t\t\t\t\tFROM claimed\n\t\t\t\t\tWHERE claimed.collection_id = work.collection_id\n\t\t\t\t\t\tAND claimed.content_id = work.content_id\n\t\t\t\t\t\tAND claimed.work_version = work.work_version\n\t\t\t\t\t\tAND claimed.lease_token = work.lease_token\n\t\t\t\t)\n\t\t\tRETURNING collection_id, content_id, work_version, state\n\t\t`.execute(this.db);\n\t\tfor (const row of result.rows) {\n\t\t\ttransitioned.set(\n\t\t\t\tworkIdentityKey({\n\t\t\t\t\tcollectionId: row.collection_id,\n\t\t\t\t\tcontentId: row.content_id,\n\t\t\t\t\tworkVersion: row.work_version,\n\t\t\t\t}),\n\t\t\t\trow.state,\n\t\t\t);\n\t\t}\n\t\treturn transitioned;\n\t}\n\n\tasync releaseClaimedWorkBatch(inputs: readonly MediaUsageWorkLease[]): Promise<Set<string>> {\n\t\tconst unique = [\n\t\t\t...new Map(\n\t\t\t\tinputs.map((input) => {\n\t\t\t\t\tassertLease(input);\n\t\t\t\t\treturn [workIdentityKey(input), input] as const;\n\t\t\t\t}),\n\t\t\t).values(),\n\t\t];\n\t\tconst released = new Set<string>();\n\t\tif (unique.length === 0) return released;\n\t\tconst payload = JSON.stringify(\n\t\t\tunique.map((input) => ({\n\t\t\t\tcollection_id: input.collectionId,\n\t\t\t\tcontent_id: input.contentId,\n\t\t\t\twork_version: String(input.workVersion),\n\t\t\t\tlease_token: input.leaseToken,\n\t\t\t})),\n\t\t);\n\t\tconst claimed = this.claimedWorkBatchInput(payload);\n\t\tconst result = await sql<{\n\t\t\tcollection_id: string;\n\t\t\tcontent_id: string;\n\t\t\twork_version: MediaUsageWorkVersion;\n\t\t}>`\n\t\t\tWITH claimed AS (${claimed})\n\t\t\tUPDATE _emdash_media_usage_work AS work\n\t\t\tSET state = 'pending',\n\t\t\t\tnext_attempt_at = ${this.timestampOffset(0)},\n\t\t\t\tlease_token = NULL,\n\t\t\t\tlease_expires_at = NULL,\n\t\t\t\tupdated_at = ${this.timestampOffset(0)}\n\t\t\tWHERE work.state = 'leased'\n\t\t\t\tAND ${this.qualifiedLeaseIsLive(\"work.lease_expires_at\")}\n\t\t\t\tAND EXISTS (\n\t\t\t\t\tSELECT 1\n\t\t\t\t\tFROM claimed\n\t\t\t\t\tWHERE claimed.collection_id = work.collection_id\n\t\t\t\t\t\tAND claimed.content_id = work.content_id\n\t\t\t\t\t\tAND claimed.work_version = work.work_version\n\t\t\t\t\t\tAND claimed.lease_token = work.lease_token\n\t\t\t\t)\n\t\t\tRETURNING collection_id, content_id, work_version\n\t\t`.execute(this.db);\n\t\tfor (const row of result.rows) {\n\t\t\treleased.add(\n\t\t\t\tworkIdentityKey({\n\t\t\t\t\tcollectionId: row.collection_id,\n\t\t\t\t\tcontentId: row.content_id,\n\t\t\t\t\tworkVersion: row.work_version,\n\t\t\t\t}),\n\t\t\t);\n\t\t}\n\t\treturn released;\n\t}\n\n\tasync deleteWorkThroughEpoch(\n\t\tcollectionId: string,\n\t\tmaxChangeEpoch: number | string,\n\t): Promise<number> {\n\t\tif (!collectionId) throw new Error(\"Media usage work cleanup requires a collection ID\");\n\t\tassertNonNegativeDecimal(maxChangeEpoch, \"change epoch\");\n\t\tconst result = await this.db\n\t\t\t.deleteFrom(\"_emdash_media_usage_work\")\n\t\t\t.where(\"collection_id\", \"=\", collectionId)\n\t\t\t.where(\"change_epoch\", \"<=\", maxChangeEpoch)\n\t\t\t.executeTakeFirst();\n\t\treturn Number(result.numDeletedRows ?? 0);\n\t}\n\n\tasync deleteObsoleteReconciliationWork(input: {\n\t\tcollectionId: string;\n\t\tcollectionSlug: string;\n\t\trunToken: string;\n\t\tleaseToken: string;\n\t\ttargetEpoch: number | string;\n\t}): Promise<number> {\n\t\tassertNonNegativeDecimal(input.targetEpoch, \"target epoch\");\n\t\tconst result = await this.db\n\t\t\t.deleteFrom(\"_emdash_media_usage_work as work\")\n\t\t\t.where(\"work.collection_id\", \"=\", input.collectionId)\n\t\t\t.where(\"work.change_epoch\", \"<\", input.targetEpoch)\n\t\t\t.where((eb) =>\n\t\t\t\teb.exists(\n\t\t\t\t\teb\n\t\t\t\t\t\t.selectFrom(\"_emdash_media_usage_reconciliations as reconciliation\")\n\t\t\t\t\t\t.innerJoin(\"_emdash_media_usage_index_status as status\", (join) =>\n\t\t\t\t\t\t\tjoin\n\t\t\t\t\t\t\t\t.onRef(\"status.collection_id\", \"=\", \"reconciliation.collection_id\")\n\t\t\t\t\t\t\t\t.onRef(\"status.scope_key\", \"=\", \"reconciliation.collection_slug\"),\n\t\t\t\t\t\t)\n\t\t\t\t\t\t.innerJoin(\"_emdash_collections as collection\", (join) =>\n\t\t\t\t\t\t\tjoin\n\t\t\t\t\t\t\t\t.onRef(\"collection.id\", \"=\", \"reconciliation.collection_id\")\n\t\t\t\t\t\t\t\t.onRef(\"collection.slug\", \"=\", \"reconciliation.collection_slug\"),\n\t\t\t\t\t\t)\n\t\t\t\t\t\t.select(\"reconciliation.collection_id\")\n\t\t\t\t\t\t.where(\"reconciliation.collection_id\", \"=\", input.collectionId)\n\t\t\t\t\t\t.where(\"reconciliation.collection_slug\", \"=\", input.collectionSlug)\n\t\t\t\t\t\t.where(\"reconciliation.run_token\", \"=\", input.runToken)\n\t\t\t\t\t\t.where(\"reconciliation.target_epoch\", \"=\", input.targetEpoch)\n\t\t\t\t\t\t.where(\"reconciliation.state\", \"=\", \"leased\")\n\t\t\t\t\t\t.where(\"reconciliation.lease_token\", \"=\", input.leaseToken)\n\t\t\t\t\t\t.where(this.qualifiedLeaseIsLive(\"reconciliation.lease_expires_at\"))\n\t\t\t\t\t\t.where(\"status.capture_state\", \"=\", \"active\")\n\t\t\t\t\t\t.where(\"status.reconciliation_required\", \"=\", 1)\n\t\t\t\t\t\t.where(\"status.status\", \"=\", \"running\")\n\t\t\t\t\t\t.where(\"status.cursor\", \"=\", input.runToken)\n\t\t\t\t\t\t.where(\"status.change_epoch\", \"=\", input.targetEpoch),\n\t\t\t\t),\n\t\t\t)\n\t\t\t.executeTakeFirst();\n\t\treturn Number(result.numDeletedRows ?? 0);\n\t}\n\n\tprivate leaseIsLive(): RawBuilder<boolean> {\n\t\treturn isPostgres(this.db)\n\t\t\t? sql<boolean>`lease_expires_at::timestamptz > clock_timestamp()`\n\t\t\t: sql<boolean>`lease_expires_at > strftime('%Y-%m-%dT%H:%M:%fZ', 'now')`;\n\t}\n\n\tprivate qualifiedLeaseIsLive(column: string): RawBuilder<boolean> {\n\t\tconst expiry = sql.ref(column);\n\t\treturn isPostgres(this.db)\n\t\t\t? sql<boolean>`${expiry} > to_char(statement_timestamp() AT TIME ZONE 'UTC', 'YYYY-MM-DD\"T\"HH24:MI:SS.MS\"Z\"')`\n\t\t\t: sql<boolean>`${expiry} > strftime('%Y-%m-%dT%H:%M:%fZ', 'now')`;\n\t}\n\n\tprivate timestampIsDue(\n\t\tcolumn:\n\t\t\t| \"next_attempt_at\"\n\t\t\t| \"lease_expires_at\"\n\t\t\t| \"work.lease_expires_at\"\n\t\t\t| \"work.next_attempt_at\"\n\t\t\t| \"due.next_attempt_at\"\n\t\t\t| \"due.lease_expires_at\",\n\t): RawBuilder<boolean> {\n\t\treturn isPostgres(this.db)\n\t\t\t? sql<boolean>`${sql.ref(column)} <= to_char(\n\t\t\t\tstatement_timestamp() AT TIME ZONE 'UTC',\n\t\t\t\t'YYYY-MM-DD\"T\"HH24:MI:SS.MS\"Z\"'\n\t\t\t)`\n\t\t\t: sql<boolean>`${sql.ref(column)} <= strftime('%Y-%m-%dT%H:%M:%fZ', 'now')`;\n\t}\n\n\tprivate timestampOffset(offsetSeconds: number): RawBuilder<string> {\n\t\tif (isPostgres(this.db)) {\n\t\t\treturn sql<string>`to_char(\n\t\t\t\t(clock_timestamp() AT TIME ZONE 'UTC') + (${offsetSeconds} * INTERVAL '1 second'),\n\t\t\t\t'YYYY-MM-DD\"T\"HH24:MI:SS.MS\"Z\"'\n\t\t\t)`;\n\t\t}\n\t\treturn sql<string>`strftime(\n\t\t\t'%Y-%m-%dT%H:%M:%fZ',\n\t\t\t'now',\n\t\t\t${`${offsetSeconds >= 0 ? \"+\" : \"\"}${offsetSeconds} seconds`}\n\t\t)`;\n\t}\n\n\tprivate claimedWorkBatchInput(payload: string): RawBuilder<unknown> {\n\t\tif (isPostgres(this.db)) {\n\t\t\treturn sql`\n\t\t\t\tSELECT\n\t\t\t\t\tentry.value ->> 'collection_id' AS collection_id,\n\t\t\t\t\tentry.value ->> 'content_id' AS content_id,\n\t\t\t\t\tCAST(entry.value ->> 'work_version' AS bigint) AS work_version,\n\t\t\t\t\tentry.value ->> 'lease_token' AS lease_token\n\t\t\t\tFROM jsonb_array_elements(${payload}::jsonb) AS entry(value)\n\t\t\t`;\n\t\t}\n\t\treturn sql`\n\t\t\tSELECT\n\t\t\t\tjson_extract(entry.value, '$.collection_id') AS collection_id,\n\t\t\t\tjson_extract(entry.value, '$.content_id') AS content_id,\n\t\t\t\tCAST(json_extract(entry.value, '$.work_version') AS integer) AS work_version,\n\t\t\t\tjson_extract(entry.value, '$.lease_token') AS lease_token\n\t\t\tFROM json_each(${payload}) AS entry\n\t\t`;\n\t}\n}\n\nfunction workIdentityKey(input: MediaUsageWorkIdentity): string {\n\treturn `${input.collectionId}\\u0000${input.contentId}\\u0000${String(input.workVersion)}`;\n}\n\nfunction operatorLimit(value: number | undefined): number {\n\tif (value === undefined) return MEDIA_USAGE_WORK_OPERATOR_DEFAULT_LIMIT;\n\tif (!Number.isSafeInteger(value) || value < 1 || value > MEDIA_USAGE_WORK_OPERATOR_MAX_LIMIT) {\n\t\tthrow new Error(\n\t\t\t`Media usage operator limit must be a whole number from 1 to ${MEDIA_USAGE_WORK_OPERATOR_MAX_LIMIT}`,\n\t\t);\n\t}\n\treturn value;\n}\n\nfunction durationSeconds(value: number, label: string, allowZero: boolean): number {\n\tif (\n\t\t!Number.isSafeInteger(value) ||\n\t\tvalue < (allowZero ? 0 : 1) ||\n\t\tvalue > MAX_PORTABLE_DURATION_SECONDS\n\t) {\n\t\tthrow new Error(\n\t\t\t`Media usage work ${label} must be ${allowZero ? \"a non-negative\" : \"a positive\"} whole number of seconds no greater than one year`,\n\t\t);\n\t}\n\treturn value;\n}\n\nfunction assertIdentity(input: MediaUsageWorkIdentity): void {\n\tif (!input.collectionId || !input.contentId) {\n\t\tthrow new Error(\"Media usage work identity must include collection and content IDs\");\n\t}\n\tconst validVersion =\n\t\t(typeof input.workVersion === \"number\" &&\n\t\t\tNumber.isSafeInteger(input.workVersion) &&\n\t\t\tinput.workVersion > 0) ||\n\t\t(typeof input.workVersion === \"string\" && POSITIVE_DECIMAL_PATTERN.test(input.workVersion));\n\tif (!validVersion) {\n\t\tthrow new Error(\"Media usage work identity must include a work version\");\n\t}\n}\n\nfunction assertNonNegativeDecimal(value: number | string, label: string): void {\n\tconst valid =\n\t\t(typeof value === \"number\" && Number.isSafeInteger(value) && value >= 0) ||\n\t\t(typeof value === \"string\" && NON_NEGATIVE_DECIMAL_PATTERN.test(value));\n\tif (!valid) throw new Error(`Media usage work ${label} must be a non-negative whole number`);\n}\n\nfunction assertToken(value: string): void {\n\tif (!value) throw new Error(\"Media usage work lease token must not be empty\");\n}\n\nfunction assertLease(input: MediaUsageWorkLease): void {\n\tassertIdentity(input);\n\tassertToken(input.leaseToken);\n}\n\nfunction assertErrorCode(value: string): void {\n\tif (!STABLE_ERROR_CODE_PATTERN.test(value)) {\n\t\tthrow new Error(\"Media usage work error code must use a stable SCREAMING_SNAKE_CASE value\");\n\t}\n}\n\nfunction rowToWork(row: Selectable<MediaUsageWorkTable>): MediaUsageWorkRecord {\n\tif (!isMediaUsageWorkState(row.state)) {\n\t\tthrow new Error(`Invalid media usage work state: ${row.state}`);\n\t}\n\treturn {\n\t\tcollectionId: row.collection_id,\n\t\tcollectionSlug: row.collection_slug,\n\t\tcontentId: row.content_id,\n\t\tchangeEpoch: row.change_epoch,\n\t\tworkVersion: row.work_version,\n\t\tstate: row.state,\n\t\tattemptCount: row.attempt_count,\n\t\tnextAttemptAt: row.next_attempt_at,\n\t\tleaseToken: row.lease_token,\n\t\tleaseExpiresAt: row.lease_expires_at,\n\t\tlastAttemptedAt: row.last_attempted_at,\n\t\tlastErrorCode: row.last_error_code,\n\t\tcreatedAt: row.created_at,\n\t\tupdatedAt: row.updated_at,\n\t};\n}\n\nfunction rowToOperatorWork(\n\trow: Selectable<MediaUsageWorkTable> | MediaUsageWorkRecord,\n): MediaUsageOperatorWorkItem {\n\tconst work = \"collection_id\" in row ? rowToWork(row) : row;\n\treturn {\n\t\tcollectionId: work.collectionId,\n\t\tcollectionSlug: work.collectionSlug,\n\t\tcontentId: work.contentId,\n\t\tstate: work.state,\n\t\tattemptCount: work.attemptCount,\n\t\tnextAttemptAt: work.nextAttemptAt,\n\t\tleaseExpiresAt: work.leaseExpiresAt,\n\t\tlastAttemptedAt: work.lastAttemptedAt,\n\t\tlastErrorCode: work.lastErrorCode,\n\t\tupdatedAt: work.updatedAt,\n\t};\n}\n\nfunction isMediaUsageWorkState(value: string): value is MediaUsageWorkState {\n\treturn value === \"pending\" || value === \"retry\" || value === \"leased\" || value === \"failed\";\n}\n\nfunction compareOperatorWork(a: MediaUsageOperatorWorkItem, b: MediaUsageOperatorWorkItem): number {\n\tconst updated = b.updatedAt.localeCompare(a.updatedAt);\n\treturn updated !== 0 ? updated : b.contentId.localeCompare(a.contentId);\n}\n"],"mappings":"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"}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { p as tableExists } from "./dialect-helpers-BSbfaO3F.mjs";
|
|
2
|
-
import { t as apiError } from "./error-
|
|
2
|
+
import { t as apiError } from "./error-DFrQjppn.mjs";
|
|
3
3
|
|
|
4
4
|
//#region src/api/media-usage-write-fence.ts
|
|
5
5
|
var MediaUsageActivationWriteBlockedError = class extends Error {
|
|
@@ -39,4 +39,4 @@ async function findMediaUsageActivationWriteFenceError(db) {
|
|
|
39
39
|
|
|
40
40
|
//#endregion
|
|
41
41
|
export { assertMediaUsageActivationWriteAllowed as n, checkMediaUsageActivationWriteFence as r, MediaUsageActivationWriteBlockedError as t };
|
|
42
|
-
//# sourceMappingURL=media-usage-write-fence-
|
|
42
|
+
//# sourceMappingURL=media-usage-write-fence-hjeD4u7s.mjs.map
|
package/dist/{media-usage-write-fence-aHEgN1zB.mjs.map → media-usage-write-fence-hjeD4u7s.mjs.map}
RENAMED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"media-usage-write-fence-
|
|
1
|
+
{"version":3,"file":"media-usage-write-fence-hjeD4u7s.mjs","names":[],"sources":["../src/api/media-usage-write-fence.ts"],"sourcesContent":["import type { Kysely } from \"kysely\";\n\nimport { tableExists } from \"../database/dialect-helpers.js\";\nimport type { Database } from \"../database/types.js\";\nimport { apiError } from \"./error.js\";\n\nexport interface MediaUsageActivationWriteFenceError {\n\tcode: \"MEDIA_USAGE_ACTIVATION_IN_PROGRESS\" | \"MEDIA_USAGE_ACTIVATION_CHECK_FAILED\";\n\tmessage: string;\n\tstatus: 503;\n}\n\nexport class MediaUsageActivationWriteBlockedError extends Error {\n\tconstructor(\n\t\treadonly code: MediaUsageActivationWriteFenceError[\"code\"],\n\t\tmessage: string,\n\t\treadonly status: 503,\n\t) {\n\t\tsuper(message);\n\t\tthis.name = code;\n\t}\n}\n\nexport async function checkMediaUsageActivationWriteFence(\n\tdb: Kysely<Database>,\n): Promise<Response | null> {\n\tconst error = await findMediaUsageActivationWriteFenceError(db);\n\treturn error ? apiError(error.code, error.message, error.status) : null;\n}\n\nexport async function assertMediaUsageActivationWriteAllowed(db: Kysely<Database>): Promise<void> {\n\tconst error = await findMediaUsageActivationWriteFenceError(db);\n\tif (error) {\n\t\tthrow new MediaUsageActivationWriteBlockedError(error.code, error.message, error.status);\n\t}\n}\n\nexport async function findMediaUsageActivationWriteFenceError(\n\tdb: Kysely<Database>,\n): Promise<MediaUsageActivationWriteFenceError | null> {\n\tif (!(await tableExists(db, \"_emdash_media_usage_activation\"))) return null;\n\ttry {\n\t\tconst row = await db\n\t\t\t.selectFrom(\"_emdash_media_usage_activation\")\n\t\t\t.select(\"state\")\n\t\t\t.where(\"task_key\", \"=\", \"incremental_capture\")\n\t\t\t.executeTakeFirst();\n\t\tif (row?.state === \"activating\") {\n\t\t\treturn {\n\t\t\t\tcode: \"MEDIA_USAGE_ACTIVATION_IN_PROGRESS\",\n\t\t\t\tmessage: \"Media usage activation is in progress\",\n\t\t\t\tstatus: 503,\n\t\t\t};\n\t\t}\n\t} catch (error) {\n\t\tconsole.error(\"[media-usage] Failed to check the activation write fence:\", error);\n\t\treturn {\n\t\t\tcode: \"MEDIA_USAGE_ACTIVATION_CHECK_FAILED\",\n\t\t\tmessage: \"Unable to verify media usage activation state\",\n\t\t\tstatus: 503,\n\t\t};\n\t}\n\treturn null;\n}\n"],"mappings":";;;;AAYA,IAAa,wCAAb,cAA2D,MAAM;CAChE,YACC,AAAS,MACT,SACA,AAAS,QACR;AACD,QAAM,QAAQ;EAJL;EAEA;AAGT,OAAK,OAAO;;;AAId,eAAsB,oCACrB,IAC2B;CAC3B,MAAM,QAAQ,MAAM,wCAAwC,GAAG;AAC/D,QAAO,QAAQ,SAAS,MAAM,MAAM,MAAM,SAAS,MAAM,OAAO,GAAG;;AAGpE,eAAsB,uCAAuC,IAAqC;CACjG,MAAM,QAAQ,MAAM,wCAAwC,GAAG;AAC/D,KAAI,MACH,OAAM,IAAI,sCAAsC,MAAM,MAAM,MAAM,SAAS,MAAM,OAAO;;AAI1F,eAAsB,wCACrB,IACsD;AACtD,KAAI,CAAE,MAAM,YAAY,IAAI,iCAAiC,CAAG,QAAO;AACvE,KAAI;AAMH,OALY,MAAM,GAChB,WAAW,iCAAiC,CAC5C,OAAO,QAAQ,CACf,MAAM,YAAY,KAAK,sBAAsB,CAC7C,kBAAkB,GACX,UAAU,aAClB,QAAO;GACN,MAAM;GACN,SAAS;GACT,QAAQ;GACR;UAEM,OAAO;AACf,UAAQ,MAAM,6DAA6D,MAAM;AACjF,SAAO;GACN,MAAM;GACN,SAAS;GACT,QAAQ;GACR;;AAEF,QAAO"}
|