emdash 1.0.1 → 1.1.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/action-token-AgOs1UWD.mjs +26 -0
- package/dist/action-token-AgOs1UWD.mjs.map +1 -0
- package/dist/activation-xomsCMJg.mjs +387 -0
- package/dist/activation-xomsCMJg.mjs.map +1 -0
- package/dist/adapters-DM1oyHIN.d.mts +173 -0
- package/dist/adapters-DM1oyHIN.d.mts.map +1 -0
- package/dist/allowed-origins-CFtudhyw.mjs +116 -0
- package/dist/allowed-origins-CFtudhyw.mjs.map +1 -0
- package/dist/api/route-utils.d.mts +4 -4
- package/dist/api/route-utils.mjs +48 -47
- package/dist/api/route-utils.mjs.map +1 -1
- package/dist/api/schemas/index.d.mts +2 -2
- package/dist/api/schemas/index.mjs +10 -10
- package/dist/api-CltsXhiX.mjs +4980 -0
- package/dist/api-CltsXhiX.mjs.map +1 -0
- package/dist/api-tokens-P3mAaQgr.mjs +166 -0
- package/dist/api-tokens-P3mAaQgr.mjs.map +1 -0
- package/dist/apply-Q7uvzBWW.mjs +1680 -0
- package/dist/apply-Q7uvzBWW.mjs.map +1 -0
- package/dist/approvals-DycwI6lZ.mjs +460 -0
- package/dist/approvals-DycwI6lZ.mjs.map +1 -0
- package/dist/artifact-fetch-CWxyELVI.mjs +659 -0
- package/dist/artifact-fetch-CWxyELVI.mjs.map +1 -0
- package/dist/artifacts-UzWbysb8.mjs +307 -0
- package/dist/artifacts-UzWbysb8.mjs.map +1 -0
- package/dist/astro/index.d.mts +14 -14
- package/dist/astro/index.d.mts.map +1 -1
- package/dist/astro/index.mjs +38 -12
- package/dist/astro/index.mjs.map +1 -1
- package/dist/astro/middleware/auth.d.mts +12 -12
- package/dist/astro/middleware/auth.mjs +12 -11
- package/dist/astro/middleware/auth.mjs.map +1 -1
- package/dist/astro/middleware/media-usage-write-fence.mjs +6 -6
- package/dist/astro/middleware/redirect.d.mts.map +1 -1
- package/dist/astro/middleware/redirect.mjs +9 -22
- package/dist/astro/middleware/redirect.mjs.map +1 -1
- package/dist/astro/middleware/request-context.d.mts.map +1 -1
- package/dist/astro/middleware/request-context.mjs +33 -21
- package/dist/astro/middleware/request-context.mjs.map +1 -1
- package/dist/astro/middleware/setup.mjs +1 -1
- package/dist/astro/middleware.d.mts +12 -12
- package/dist/astro/middleware.d.mts.map +1 -1
- package/dist/astro/middleware.mjs +203 -120
- package/dist/astro/middleware.mjs.map +1 -1
- package/dist/astro/routes/api/admin/allowed-domains/_domain_.mjs +15 -15
- package/dist/astro/routes/api/admin/allowed-domains/index.mjs +15 -15
- package/dist/astro/routes/api/admin/api-tokens/_id_.mjs +7 -7
- package/dist/astro/routes/api/admin/api-tokens/index.mjs +8 -8
- package/dist/astro/routes/api/admin/byline-fields/_slug_/usage.mjs +7 -7
- package/dist/astro/routes/api/admin/byline-fields/_slug_.mjs +17 -17
- package/dist/astro/routes/api/admin/byline-fields/index.mjs +17 -17
- package/dist/astro/routes/api/admin/byline-fields/reorder.mjs +17 -17
- package/dist/astro/routes/api/admin/bylines/_id_/index.mjs +22 -22
- package/dist/astro/routes/api/admin/bylines/_id_/translations.mjs +22 -23
- package/dist/astro/routes/api/admin/bylines/_id_/translations.mjs.map +1 -1
- package/dist/astro/routes/api/admin/bylines/index.mjs +23 -23
- package/dist/astro/routes/api/admin/bylines/index.mjs.map +1 -1
- package/dist/astro/routes/api/admin/comments/_id_/status.mjs +19 -19
- package/dist/astro/routes/api/admin/comments/_id_.mjs +8 -8
- package/dist/astro/routes/api/admin/comments/bulk.mjs +18 -18
- package/dist/astro/routes/api/admin/comments/counts.mjs +8 -8
- package/dist/astro/routes/api/admin/comments/index.mjs +18 -18
- package/dist/astro/routes/api/admin/core-update.mjs +8 -8
- package/dist/astro/routes/api/admin/hooks/exclusive/_hookName_.mjs +7 -7
- package/dist/astro/routes/api/admin/hooks/exclusive/index.mjs +6 -6
- package/dist/astro/routes/api/admin/media-usage/activation.mjs +21 -21
- package/dist/astro/routes/api/admin/media-usage/collection-deletions/index.mjs +22 -22
- package/dist/astro/routes/api/admin/media-usage/collection-deletions/retry.mjs +22 -22
- package/dist/astro/routes/api/admin/media-usage/progress.mjs +23 -23
- package/dist/astro/routes/api/admin/media-usage/repair.mjs +29 -29
- package/dist/astro/routes/api/admin/media-usage/work/index.mjs +22 -22
- package/dist/astro/routes/api/admin/media-usage/work/retry.mjs +22 -22
- package/dist/astro/routes/api/admin/oauth-clients/_id_.mjs +7 -7
- package/dist/astro/routes/api/admin/oauth-clients/index.mjs +7 -7
- package/dist/astro/routes/api/admin/plugins/_id_/disable.mjs +9 -9
- package/dist/astro/routes/api/admin/plugins/_id_/enable.mjs +9 -9
- package/dist/astro/routes/api/admin/plugins/_id_/index.mjs +72 -71
- package/dist/astro/routes/api/admin/plugins/_id_/index.mjs.map +1 -1
- package/dist/astro/routes/api/admin/plugins/_id_/mcp.mjs +8 -8
- package/dist/astro/routes/api/admin/plugins/_id_/settings.mjs +70 -69
- package/dist/astro/routes/api/admin/plugins/_id_/settings.mjs.map +1 -1
- package/dist/astro/routes/api/admin/plugins/_id_/uninstall.mjs +71 -70
- package/dist/astro/routes/api/admin/plugins/_id_/uninstall.mjs.map +1 -1
- package/dist/astro/routes/api/admin/plugins/_id_/update.mjs +81 -80
- package/dist/astro/routes/api/admin/plugins/_id_/update.mjs.map +1 -1
- package/dist/astro/routes/api/admin/plugins/index.mjs +71 -70
- package/dist/astro/routes/api/admin/plugins/index.mjs.map +1 -1
- package/dist/astro/routes/api/admin/plugins/marketplace/_id_/icon.mjs +8 -8
- package/dist/astro/routes/api/admin/plugins/marketplace/_id_/index.mjs +70 -69
- 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 +80 -79
- package/dist/astro/routes/api/admin/plugins/marketplace/_id_/install.mjs.map +1 -1
- package/dist/astro/routes/api/admin/plugins/marketplace/index.mjs +70 -69
- package/dist/astro/routes/api/admin/plugins/marketplace/index.mjs.map +1 -1
- package/dist/astro/routes/api/admin/plugins/registry/_id_/uninstall.mjs +71 -70
- package/dist/astro/routes/api/admin/plugins/registry/_id_/uninstall.mjs.map +1 -1
- package/dist/astro/routes/api/admin/plugins/registry/_id_/update.mjs +82 -81
- package/dist/astro/routes/api/admin/plugins/registry/_id_/update.mjs.map +1 -1
- package/dist/astro/routes/api/admin/plugins/registry/artifact.mjs +10 -10
- package/dist/astro/routes/api/admin/plugins/registry/install.mjs +73 -72
- package/dist/astro/routes/api/admin/plugins/registry/install.mjs.map +1 -1
- package/dist/astro/routes/api/admin/plugins/registry/publisher-handle.mjs +8 -8
- package/dist/astro/routes/api/admin/plugins/registry/verify.mjs +71 -70
- package/dist/astro/routes/api/admin/plugins/registry/verify.mjs.map +1 -1
- package/dist/astro/routes/api/admin/plugins/updates.mjs +70 -69
- package/dist/astro/routes/api/admin/plugins/updates.mjs.map +1 -1
- package/dist/astro/routes/api/admin/scheduled-policy-rejections/_collection_/_id_.mjs +6 -6
- package/dist/astro/routes/api/admin/themes/marketplace/_id_/index.mjs +70 -69
- 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 +8 -8
- package/dist/astro/routes/api/admin/themes/marketplace/index.mjs +70 -69
- package/dist/astro/routes/api/admin/themes/marketplace/index.mjs.map +1 -1
- package/dist/astro/routes/api/admin/transfer/_...path_.mjs +5 -5
- package/dist/astro/routes/api/admin/transfer/approvals/_id_/approve.mjs +39 -39
- package/dist/astro/routes/api/admin/transfer/approvals/_id_/deny.mjs +39 -39
- package/dist/astro/routes/api/admin/transfer/approvals/index.mjs +41 -41
- package/dist/astro/routes/api/admin/transfer/capabilities.mjs +41 -41
- package/dist/astro/routes/api/admin/transfer/exports/_id_/advance.mjs +41 -41
- package/dist/astro/routes/api/admin/transfer/exports/_id_/archive.mjs +42 -42
- package/dist/astro/routes/api/admin/transfer/exports/_id_/files/_...path_.mjs +42 -42
- package/dist/astro/routes/api/admin/transfer/exports/_id_/index.mjs +41 -41
- package/dist/astro/routes/api/admin/transfer/exports/_id_/manifest.mjs +42 -42
- package/dist/astro/routes/api/admin/transfer/exports/index.mjs +43 -43
- package/dist/astro/routes/api/admin/transfer/imports/_id_/abandon.mjs +41 -41
- package/dist/astro/routes/api/admin/transfer/imports/_id_/advance.mjs +41 -41
- package/dist/astro/routes/api/admin/transfer/imports/_id_/analyze.mjs +43 -43
- package/dist/astro/routes/api/admin/transfer/imports/_id_/cancel.mjs +41 -41
- package/dist/astro/routes/api/admin/transfer/imports/_id_/execute.mjs +43 -43
- package/dist/astro/routes/api/admin/transfer/imports/_id_/files/_...path_.mjs +41 -41
- package/dist/astro/routes/api/admin/transfer/imports/_id_/index.mjs +41 -41
- package/dist/astro/routes/api/admin/transfer/imports/_id_/missing.mjs +43 -43
- package/dist/astro/routes/api/admin/transfer/imports/_id_/plan.mjs +41 -41
- package/dist/astro/routes/api/admin/transfer/imports/_id_/receipt.mjs +41 -41
- package/dist/astro/routes/api/admin/transfer/imports/index.mjs +43 -43
- package/dist/astro/routes/api/admin/users/_id_/disable.mjs +5 -5
- package/dist/astro/routes/api/admin/users/_id_/enable.mjs +5 -5
- package/dist/astro/routes/api/admin/users/_id_/index.mjs +15 -15
- package/dist/astro/routes/api/admin/users/_id_/send-recovery.mjs +7 -7
- package/dist/astro/routes/api/admin/users/index.mjs +15 -15
- package/dist/astro/routes/api/auth/dev-bypass.mjs +7 -7
- package/dist/astro/routes/api/auth/invite/accept.mjs +5 -5
- package/dist/astro/routes/api/auth/invite/complete.mjs +20 -20
- package/dist/astro/routes/api/auth/invite/index.mjs +17 -17
- package/dist/astro/routes/api/auth/invite/register-options.mjs +18 -18
- package/dist/astro/routes/api/auth/logout.mjs +6 -6
- package/dist/astro/routes/api/auth/magic-link/send.mjs +19 -19
- package/dist/astro/routes/api/auth/magic-link/verify.mjs +16 -16
- package/dist/astro/routes/api/auth/me.mjs +16 -16
- package/dist/astro/routes/api/auth/mode.mjs +6 -6
- package/dist/astro/routes/api/auth/oauth/_provider_/callback.d.mts.map +1 -1
- package/dist/astro/routes/api/auth/oauth/_provider_/callback.mjs +36 -13
- package/dist/astro/routes/api/auth/oauth/_provider_/callback.mjs.map +1 -1
- package/dist/astro/routes/api/auth/oauth/_provider_.d.mts.map +1 -1
- package/dist/astro/routes/api/auth/oauth/_provider_.mjs +20 -5
- package/dist/astro/routes/api/auth/oauth/_provider_.mjs.map +1 -1
- package/dist/astro/routes/api/auth/passkey/_id_.mjs +15 -15
- package/dist/astro/routes/api/auth/passkey/index.mjs +5 -5
- package/dist/astro/routes/api/auth/passkey/options.mjs +20 -20
- package/dist/astro/routes/api/auth/passkey/register/options.mjs +18 -18
- package/dist/astro/routes/api/auth/passkey/register/verify.mjs +19 -19
- package/dist/astro/routes/api/auth/passkey/verify.mjs +20 -20
- package/dist/astro/routes/api/auth/signup/complete.mjs +20 -20
- package/dist/astro/routes/api/auth/signup/request.mjs +18 -18
- package/dist/astro/routes/api/auth/signup/verify.mjs +5 -5
- package/dist/astro/routes/api/calendar.d.mts +8 -0
- package/dist/astro/routes/api/calendar.d.mts.map +1 -0
- package/dist/astro/routes/api/calendar.mjs +204 -0
- package/dist/astro/routes/api/calendar.mjs.map +1 -0
- package/dist/astro/routes/api/comments/_collection_/_contentId_/index.mjs +14 -14
- package/dist/astro/routes/api/comments/_collection_/_contentId_/reactions.mjs +20 -20
- package/dist/astro/routes/api/content/_collection_/_id_/compare.mjs +6 -6
- package/dist/astro/routes/api/content/_collection_/_id_/discard-draft.mjs +17 -17
- package/dist/astro/routes/api/content/_collection_/_id_/duplicate.mjs +6 -6
- package/dist/astro/routes/api/content/_collection_/_id_/lock.mjs +17 -17
- package/dist/astro/routes/api/content/_collection_/_id_/permanent.mjs +6 -6
- package/dist/astro/routes/api/content/_collection_/_id_/plugin-extensions/_pluginId_/_kind_/_extensionId_.mjs +12 -12
- package/dist/astro/routes/api/content/_collection_/_id_/preview-url.mjs +31 -31
- package/dist/astro/routes/api/content/_collection_/_id_/publish.mjs +17 -17
- package/dist/astro/routes/api/content/_collection_/_id_/references/_relation_/children.mjs +34 -34
- package/dist/astro/routes/api/content/_collection_/_id_/references/_relation_/parents.mjs +34 -34
- package/dist/astro/routes/api/content/_collection_/_id_/restore.mjs +6 -6
- package/dist/astro/routes/api/content/_collection_/_id_/revisions.mjs +6 -6
- package/dist/astro/routes/api/content/_collection_/_id_/schedule.mjs +17 -17
- package/dist/astro/routes/api/content/_collection_/_id_/terms/_taxonomy_.mjs +24 -24
- package/dist/astro/routes/api/content/_collection_/_id_/translations.mjs +6 -6
- package/dist/astro/routes/api/content/_collection_/_id_/unpublish.mjs +17 -17
- package/dist/astro/routes/api/content/_collection_/_id_.mjs +17 -17
- package/dist/astro/routes/api/content/_collection_/authors.mjs +6 -6
- package/dist/astro/routes/api/content/_collection_/index.mjs +16 -16
- package/dist/astro/routes/api/content/_collection_/trash.mjs +16 -16
- package/dist/astro/routes/api/dashboard.mjs +11 -11
- package/dist/astro/routes/api/dev/emails.mjs +6 -6
- package/dist/astro/routes/api/health.mjs +7 -7
- package/dist/astro/routes/api/import/probe.d.mts +3 -3
- package/dist/astro/routes/api/import/probe.mjs +24 -24
- package/dist/astro/routes/api/import/wordpress/analyze.mjs +6 -6
- package/dist/astro/routes/api/import/wordpress/execute.d.mts +13 -13
- package/dist/astro/routes/api/import/wordpress/execute.mjs +23 -23
- package/dist/astro/routes/api/import/wordpress/media.d.mts +12 -12
- package/dist/astro/routes/api/import/wordpress/media.mjs +20 -20
- package/dist/astro/routes/api/import/wordpress/prepare.mjs +18 -18
- package/dist/astro/routes/api/import/wordpress/rewrite-urls.d.mts +13 -13
- package/dist/astro/routes/api/import/wordpress/rewrite-urls.mjs +27 -27
- package/dist/astro/routes/api/import/wordpress-plugin/analyze.d.mts +1 -1
- package/dist/astro/routes/api/import/wordpress-plugin/analyze.mjs +24 -24
- package/dist/astro/routes/api/import/wordpress-plugin/callback.mjs +1 -1
- package/dist/astro/routes/api/import/wordpress-plugin/execute.d.mts +13 -13
- package/dist/astro/routes/api/import/wordpress-plugin/execute.mjs +32 -32
- package/dist/astro/routes/api/manifest.mjs +7 -7
- package/dist/astro/routes/api/mcp.mjs +94 -94
- package/dist/astro/routes/api/mcp.mjs.map +1 -1
- package/dist/astro/routes/api/media/_id_/confirm.mjs +19 -19
- package/dist/astro/routes/api/media/_id_/replace.mjs +17 -17
- package/dist/astro/routes/api/media/_id_/upload.mjs +10 -10
- package/dist/astro/routes/api/media/_id_/usage.mjs +31 -31
- package/dist/astro/routes/api/media/_id_.mjs +29 -29
- package/dist/astro/routes/api/media/asset/_id_/_filename_.mjs +7 -7
- package/dist/astro/routes/api/media/file/_...key_.mjs +10 -10
- package/dist/astro/routes/api/media/folders/_id_.mjs +17 -17
- package/dist/astro/routes/api/media/folders/index.mjs +17 -17
- package/dist/astro/routes/api/media/providers/_providerId_/_itemId_.mjs +6 -6
- package/dist/astro/routes/api/media/providers/_providerId_/index.mjs +6 -6
- package/dist/astro/routes/api/media/providers/index.mjs +6 -6
- package/dist/astro/routes/api/media/upload-url.mjs +23 -23
- package/dist/astro/routes/api/media/upload-url.mjs.map +1 -1
- package/dist/astro/routes/api/media.mjs +37 -36
- package/dist/astro/routes/api/media.mjs.map +1 -1
- package/dist/astro/routes/api/menus/_name_/items/_id_.mjs +18 -18
- package/dist/astro/routes/api/menus/_name_/items.mjs +18 -18
- package/dist/astro/routes/api/menus/_name_/reorder.mjs +18 -18
- package/dist/astro/routes/api/menus/_name_/translations.mjs +18 -18
- package/dist/astro/routes/api/menus/_name_.mjs +18 -18
- package/dist/astro/routes/api/menus/index.mjs +18 -18
- package/dist/astro/routes/api/oauth/authorize.mjs +6 -6
- package/dist/astro/routes/api/oauth/device/authorize.mjs +9 -9
- package/dist/astro/routes/api/oauth/device/code.mjs +12 -12
- package/dist/astro/routes/api/oauth/device/token.mjs +11 -11
- package/dist/astro/routes/api/oauth/register.mjs +8 -8
- package/dist/astro/routes/api/oauth/token/refresh.mjs +9 -9
- package/dist/astro/routes/api/oauth/token/revoke.mjs +9 -9
- package/dist/astro/routes/api/oauth/token.mjs +9 -9
- package/dist/astro/routes/api/openapi.json.mjs +21 -21
- package/dist/astro/routes/api/plugins/_pluginId_/_...path_.mjs +12 -12
- package/dist/astro/routes/api/redirects/404s/index.mjs +20 -19
- package/dist/astro/routes/api/redirects/404s/index.mjs.map +1 -1
- package/dist/astro/routes/api/redirects/404s/summary.mjs +20 -19
- package/dist/astro/routes/api/redirects/404s/summary.mjs.map +1 -1
- package/dist/astro/routes/api/redirects/_id_.mjs +20 -19
- package/dist/astro/routes/api/redirects/_id_.mjs.map +1 -1
- package/dist/astro/routes/api/redirects/index.mjs +20 -19
- package/dist/astro/routes/api/redirects/index.mjs.map +1 -1
- package/dist/astro/routes/api/relations/_id_/index.mjs +34 -34
- package/dist/astro/routes/api/relations/index.mjs +34 -34
- package/dist/astro/routes/api/revisions/_revisionId_/index.mjs +6 -6
- package/dist/astro/routes/api/revisions/_revisionId_/restore.mjs +17 -17
- package/dist/astro/routes/api/schema/block-types/_slug_/index.mjs +70 -69
- package/dist/astro/routes/api/schema/block-types/_slug_/index.mjs.map +1 -1
- package/dist/astro/routes/api/schema/block-types/_slug_/versions/_version_/activate.mjs +70 -69
- package/dist/astro/routes/api/schema/block-types/_slug_/versions/_version_/activate.mjs.map +1 -1
- package/dist/astro/routes/api/schema/block-types/index.mjs +70 -69
- package/dist/astro/routes/api/schema/block-types/index.mjs.map +1 -1
- package/dist/astro/routes/api/schema/collections/_slug_/fields/_fieldSlug_.mjs +70 -69
- 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 +70 -69
- 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 +70 -69
- package/dist/astro/routes/api/schema/collections/_slug_/fields/reorder.mjs.map +1 -1
- package/dist/astro/routes/api/schema/collections/_slug_/index.mjs +70 -69
- package/dist/astro/routes/api/schema/collections/_slug_/index.mjs.map +1 -1
- package/dist/astro/routes/api/schema/collections/index.mjs +70 -69
- package/dist/astro/routes/api/schema/collections/index.mjs.map +1 -1
- package/dist/astro/routes/api/schema/collections/reorder.mjs +70 -69
- package/dist/astro/routes/api/schema/collections/reorder.mjs.map +1 -1
- package/dist/astro/routes/api/schema/index.mjs +16 -16
- package/dist/astro/routes/api/schema/orphans/_slug_.mjs +70 -69
- package/dist/astro/routes/api/schema/orphans/_slug_.mjs.map +1 -1
- package/dist/astro/routes/api/schema/orphans/index.mjs +70 -69
- package/dist/astro/routes/api/schema/orphans/index.mjs.map +1 -1
- package/dist/astro/routes/api/search/enable.mjs +19 -19
- package/dist/astro/routes/api/search/index.mjs +18 -18
- package/dist/astro/routes/api/search/rebuild.mjs +19 -19
- package/dist/astro/routes/api/search/stats.mjs +9 -9
- package/dist/astro/routes/api/search/suggest.mjs +18 -18
- package/dist/astro/routes/api/sections/_slug_.mjs +18 -18
- package/dist/astro/routes/api/sections/index.mjs +18 -18
- package/dist/astro/routes/api/settings/backups/archives/_name_.mjs +8 -8
- package/dist/astro/routes/api/settings/backups/archives/index.mjs +8 -8
- package/dist/astro/routes/api/settings/backups/export.mjs +8 -8
- package/dist/astro/routes/api/settings/backups/index.mjs +9 -9
- package/dist/astro/routes/api/settings/email.mjs +7 -7
- package/dist/astro/routes/api/settings.mjs +22 -22
- package/dist/astro/routes/api/setup/admin-verify.mjs +21 -21
- package/dist/astro/routes/api/setup/admin.mjs +19 -19
- package/dist/astro/routes/api/setup/dev-bypass.mjs +42 -42
- package/dist/astro/routes/api/setup/dev-reset.mjs +5 -5
- package/dist/astro/routes/api/setup/index.mjs +54 -49
- package/dist/astro/routes/api/setup/index.mjs.map +1 -1
- package/dist/astro/routes/api/setup/status.mjs +7 -7
- package/dist/astro/routes/api/snapshot.mjs +10 -10
- package/dist/astro/routes/api/taxonomies/_name_/reorder.mjs +22 -22
- package/dist/astro/routes/api/taxonomies/_name_/terms/_slug_/translations.mjs +22 -22
- package/dist/astro/routes/api/taxonomies/_name_/terms/_slug_.mjs +22 -22
- package/dist/astro/routes/api/taxonomies/_name_/terms/index.mjs +22 -22
- package/dist/astro/routes/api/taxonomies/_name_/translations.mjs +21 -21
- package/dist/astro/routes/api/taxonomies/_name_.mjs +22 -22
- package/dist/astro/routes/api/taxonomies/bulk-tag.mjs +35 -35
- package/dist/astro/routes/api/taxonomies/index.mjs +22 -22
- package/dist/astro/routes/api/themes/preview.mjs +8 -8
- package/dist/astro/routes/api/typegen.mjs +7 -7
- package/dist/astro/routes/api/visual-editing/action-token.mjs +8 -8
- package/dist/astro/routes/api/visual-editing/content/_collection_/_id_/publish.mjs +20 -20
- package/dist/astro/routes/api/visual-editing/toolbar-labels.mjs +5 -5
- package/dist/astro/routes/api/well-known/auth.mjs +1 -1
- 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.mjs +17 -17
- package/dist/astro/routes/api/widget-areas/_name_/widgets/_id_.mjs +19 -19
- package/dist/astro/routes/api/widget-areas/_name_/widgets.mjs +19 -19
- package/dist/astro/routes/api/widget-areas/_name_.mjs +9 -9
- package/dist/astro/routes/api/widget-areas/index.mjs +19 -19
- package/dist/astro/routes/api/widget-components.mjs +6 -6
- package/dist/astro/routes/robots.txt.mjs +7 -7
- package/dist/astro/routes/sitemap-_collection_.xml.mjs +9 -9
- package/dist/astro/routes/sitemap.xml.mjs +8 -8
- package/dist/astro/types.d.mts +17 -17
- package/dist/audit-CCH3MA4Y.mjs +127 -0
- package/dist/audit-CCH3MA4Y.mjs.map +1 -0
- package/dist/auth/providers/github.d.mts +1 -1
- package/dist/auth/providers/google.d.mts +1 -1
- package/dist/auth/providers/microsoft.d.mts +27 -0
- package/dist/auth/providers/microsoft.d.mts.map +1 -0
- package/dist/auth/providers/microsoft.mjs +20 -0
- package/dist/auth/providers/microsoft.mjs.map +1 -0
- package/dist/authoritative-records-dSvXCfzb.mjs +5172 -0
- package/dist/authoritative-records-dSvXCfzb.mjs.map +1 -0
- package/dist/authorize-DeWfk--K.mjs +49 -0
- package/dist/authorize-DeWfk--K.mjs.map +1 -0
- package/dist/backup-CFnbdTSJ.mjs +246 -0
- package/dist/backup-CFnbdTSJ.mjs.map +1 -0
- package/dist/base64-BQBZwXCx.mjs +63 -0
- package/dist/base64-BQBZwXCx.mjs.map +1 -0
- package/dist/block-types-C0YFSfR7.mjs +132 -0
- package/dist/block-types-C0YFSfR7.mjs.map +1 -0
- package/dist/block-values-H4E0XwE8.mjs +175 -0
- package/dist/block-values-H4E0XwE8.mjs.map +1 -0
- package/dist/byline-BhVslYLz.mjs +909 -0
- package/dist/byline-BhVslYLz.mjs.map +1 -0
- package/dist/byline-fields-DHJs0Mja.mjs +280 -0
- package/dist/byline-fields-DHJs0Mja.mjs.map +1 -0
- package/dist/byline-fields-xdxE9kxZ.mjs +123 -0
- package/dist/byline-fields-xdxE9kxZ.mjs.map +1 -0
- package/dist/bylines-B_nN9liM.mjs +234 -0
- package/dist/bylines-B_nN9liM.mjs.map +1 -0
- package/dist/bylines-C71YACkL.mjs +150 -0
- package/dist/bylines-C71YACkL.mjs.map +1 -0
- package/dist/cache-aTYCL9nK.mjs +133 -0
- package/dist/cache-aTYCL9nK.mjs.map +1 -0
- package/dist/canonical-Y1dpjCnp.mjs +174 -0
- package/dist/canonical-Y1dpjCnp.mjs.map +1 -0
- package/dist/capture-triggers-C9JKoIdT.mjs +362 -0
- package/dist/capture-triggers-C9JKoIdT.mjs.map +1 -0
- package/dist/challenge-store-CxZxPqaw.mjs +51 -0
- package/dist/challenge-store-CxZxPqaw.mjs.map +1 -0
- package/dist/checksum-DtH6m5uk.mjs +162 -0
- package/dist/checksum-DtH6m5uk.mjs.map +1 -0
- package/dist/chrome-tags-BIKBMZYO.mjs +24 -0
- package/dist/chrome-tags-BIKBMZYO.mjs.map +1 -0
- package/dist/chunks-zlGB5IQP.mjs +25 -0
- package/dist/chunks-zlGB5IQP.mjs.map +1 -0
- package/dist/cli/index.mjs +47 -47
- package/dist/client/cf-access.d.mts +1 -1
- package/dist/client/index.d.mts +121 -121
- package/dist/client/index.mjs +2 -2
- package/dist/collection-slugs-cache-B2Gs9Jwx.mjs +85 -0
- package/dist/collection-slugs-cache-B2Gs9Jwx.mjs.map +1 -0
- package/dist/comment-Bu08Wvr3.mjs +313 -0
- package/dist/comment-Bu08Wvr3.mjs.map +1 -0
- package/dist/comment-reaction-B8SfT-yM.mjs +85 -0
- package/dist/comment-reaction-B8SfT-yM.mjs.map +1 -0
- package/dist/comments-BRtp992B.mjs +99 -0
- package/dist/comments-BRtp992B.mjs.map +1 -0
- package/dist/comments-DVUYqdyC.mjs +195 -0
- package/dist/comments-DVUYqdyC.mjs.map +1 -0
- package/dist/components-CQY-Sgm-.mjs +108 -0
- package/dist/components-CQY-Sgm-.mjs.map +1 -0
- package/dist/config-B-uePMLj.d.mts +39 -0
- package/dist/config-B-uePMLj.d.mts.map +1 -0
- package/dist/config-B6BDSsz2.d.mts +6712 -0
- package/dist/config-B6BDSsz2.d.mts.map +1 -0
- package/dist/config-BsJHiQxC.mjs +228 -0
- package/dist/config-BsJHiQxC.mjs.map +1 -0
- package/dist/connection-B9pIasFd.mjs +36 -0
- package/dist/connection-B9pIasFd.mjs.map +1 -0
- package/dist/content-Dji9vEiW.mjs +2063 -0
- package/dist/content-Dji9vEiW.mjs.map +1 -0
- package/dist/content-list-query-DiNwyKtd.d.mts +26 -0
- package/dist/content-list-query-DiNwyKtd.d.mts.map +1 -0
- package/dist/content-repair-B7wnbzhN.mjs +442 -0
- package/dist/content-repair-B7wnbzhN.mjs.map +1 -0
- package/dist/context-Ctcxc8Ia.mjs +2026 -0
- package/dist/context-Ctcxc8Ia.mjs.map +1 -0
- package/dist/credits-Bu7dlobo.mjs +110 -0
- package/dist/credits-Bu7dlobo.mjs.map +1 -0
- package/dist/cron-xe5XKqA-.mjs +306 -0
- package/dist/cron-xe5XKqA-.mjs.map +1 -0
- package/dist/dashboard-B5hVHOtf.mjs +151 -0
- package/dist/dashboard-B5hVHOtf.mjs.map +1 -0
- package/dist/db/index.d.mts +3 -3
- package/dist/db/index.mjs +1 -1
- package/dist/db/index.mjs.map +1 -1
- package/dist/db/libsql-migrations.d.mts +1 -1
- package/dist/db/libsql-migrations.mjs +5 -5
- 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/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 +1 -1
- package/dist/default-DaoYyFRS.mjs +81 -0
- package/dist/default-DaoYyFRS.mjs.map +1 -0
- package/dist/deferred-tasks-BYcDx2o_.d.mts +9 -0
- package/dist/deferred-tasks-BYcDx2o_.d.mts.map +1 -0
- package/dist/dev-typegen-Dtl8AfS6.mjs +29 -0
- package/dist/dev-typegen-Dtl8AfS6.mjs.map +1 -0
- package/dist/device-flow-Ma5P5d2e.mjs +521 -0
- package/dist/device-flow-Ma5P5d2e.mjs.map +1 -0
- package/dist/digest-xIpR3o64.mjs +194 -0
- package/dist/digest-xIpR3o64.mjs.map +1 -0
- package/dist/direct-executor-DMWwCey3.mjs +104 -0
- package/dist/direct-executor-DMWwCey3.mjs.map +1 -0
- package/dist/email-console-DmqVF5J_.mjs +50 -0
- package/dist/email-console-DmqVF5J_.mjs.map +1 -0
- package/dist/email-locale-Cc5YSXfJ.mjs +25 -0
- package/dist/email-locale-Cc5YSXfJ.mjs.map +1 -0
- package/dist/emdash-runtime-BlybX9Ui.mjs +4249 -0
- package/dist/emdash-runtime-BlybX9Ui.mjs.map +1 -0
- package/dist/enrich-Duu4sV3a.mjs +194 -0
- package/dist/enrich-Duu4sV3a.mjs.map +1 -0
- package/dist/entry-lock-De1L8qUQ.mjs +163 -0
- package/dist/entry-lock-De1L8qUQ.mjs.map +1 -0
- package/dist/entry-lock-esmMbgI9.d.mts +4551 -0
- package/dist/entry-lock-esmMbgI9.d.mts.map +1 -0
- package/dist/entry-lock-sxz2PGAT.mjs +1197 -0
- package/dist/entry-lock-sxz2PGAT.mjs.map +1 -0
- package/dist/env-types-BkjCtN13.mjs +38 -0
- package/dist/env-types-BkjCtN13.mjs.map +1 -0
- package/dist/error-B0rgPgsQ.mjs +90 -0
- package/dist/error-B0rgPgsQ.mjs.map +1 -0
- package/dist/errors-CuHQRiBW.mjs +120 -0
- package/dist/errors-CuHQRiBW.mjs.map +1 -0
- package/dist/errors-DTE6C3K_.mjs +470 -0
- package/dist/errors-DTE6C3K_.mjs.map +1 -0
- package/dist/escape-nJW7dR0s.mjs +9 -0
- package/dist/escape-nJW7dR0s.mjs.map +1 -0
- package/dist/fence-CGw57S4v.mjs +162 -0
- package/dist/fence-CGw57S4v.mjs.map +1 -0
- package/dist/field-defs-cache-Bw8w499w.mjs +77 -0
- package/dist/field-defs-cache-Bw8w499w.mjs.map +1 -0
- package/dist/field-map-hn-D-SyH.mjs +83 -0
- package/dist/field-map-hn-D-SyH.mjs.map +1 -0
- package/dist/fts-manager-DacCYIe4.mjs +443 -0
- package/dist/fts-manager-DacCYIe4.mjs.map +1 -0
- package/dist/gc-BBplHrv6.mjs +75 -0
- package/dist/gc-BBplHrv6.mjs.map +1 -0
- package/dist/hash-C4DFoJ7Z.mjs +37 -0
- package/dist/hash-C4DFoJ7Z.mjs.map +1 -0
- package/dist/hook-result-DSRRxu_-.d.mts +31 -0
- package/dist/hook-result-DSRRxu_-.d.mts.map +1 -0
- package/dist/hreflang-CKPunvU0.mjs +105 -0
- package/dist/hreflang-CKPunvU0.mjs.map +1 -0
- package/dist/hreflang-egumj6WF.d.mts +50 -0
- package/dist/hreflang-egumj6WF.d.mts.map +1 -0
- package/dist/http-route-dispatch-DjNFZcJ2.mjs +339 -0
- package/dist/http-route-dispatch-DjNFZcJ2.mjs.map +1 -0
- package/dist/identity-Dfrx2_Bc.mjs +35 -0
- package/dist/identity-Dfrx2_Bc.mjs.map +1 -0
- package/dist/import-ROBvhbNc.mjs +2021 -0
- package/dist/import-ROBvhbNc.mjs.map +1 -0
- package/dist/index-B4sIdCAT.d.mts +623 -0
- package/dist/index-B4sIdCAT.d.mts.map +1 -0
- package/dist/index.d.mts +24 -24
- package/dist/index.mjs +98 -97
- package/dist/init-lock-BGmew3r1.mjs +56 -0
- package/dist/init-lock-BGmew3r1.mjs.map +1 -0
- package/dist/install-finalization-CPM7Gged.mjs +58 -0
- package/dist/install-finalization-CPM7Gged.mjs.map +1 -0
- package/dist/keys-DxqxcAD4.mjs +61 -0
- package/dist/keys-DxqxcAD4.mjs.map +1 -0
- package/dist/kinds-BQl5gN6e.mjs +974 -0
- package/dist/kinds-BQl5gN6e.mjs.map +1 -0
- package/dist/lifecycle-DGQI7itS.mjs +25 -0
- package/dist/lifecycle-DGQI7itS.mjs.map +1 -0
- package/dist/load-DMxRl4VK.mjs +28 -0
- package/dist/load-DMxRl4VK.mjs.map +1 -0
- package/dist/loader-1DMiOq5s.mjs +1303 -0
- package/dist/loader-1DMiOq5s.mjs.map +1 -0
- package/dist/loops-Dn1i16FP.mjs +205 -0
- package/dist/loops-Dn1i16FP.mjs.map +1 -0
- package/dist/manifest-builder-CTw4FmZk.mjs +189 -0
- package/dist/manifest-builder-CTw4FmZk.mjs.map +1 -0
- package/dist/manifest-schema-gy37bD_D.mjs +496 -0
- package/dist/manifest-schema-gy37bD_D.mjs.map +1 -0
- package/dist/marketplace-tHWSsCUo.mjs +257 -0
- package/dist/marketplace-tHWSsCUo.mjs.map +1 -0
- package/dist/media/index.d.mts +1 -1
- package/dist/media/index.mjs +1 -1
- package/dist/media/local-runtime.d.mts +14 -14
- package/dist/media/local-runtime.mjs +7 -7
- package/dist/media-Bw-Q65ve.mjs +294 -0
- package/dist/media-Bw-Q65ve.mjs.map +1 -0
- package/dist/media-BzUDu7nl.mjs +373 -0
- package/dist/media-BzUDu7nl.mjs.map +1 -0
- package/dist/media-aahnKHze.mjs +408 -0
- package/dist/media-aahnKHze.mjs.map +1 -0
- package/dist/media-allowlist-RMrjo8TU.mjs +45 -0
- package/dist/media-allowlist-RMrjo8TU.mjs.map +1 -0
- package/dist/media-folders-kabR1oJf.mjs +210 -0
- package/dist/media-folders-kabR1oJf.mjs.map +1 -0
- package/dist/media-url-DloW2xrP.mjs +43 -0
- package/dist/media-url-DloW2xrP.mjs.map +1 -0
- package/dist/media-usage-CHHpV7ee.mjs +282 -0
- package/dist/media-usage-CHHpV7ee.mjs.map +1 -0
- package/dist/media-usage-activation-BinYqC_r.mjs +78 -0
- package/dist/media-usage-activation-BinYqC_r.mjs.map +1 -0
- package/dist/media-usage-work-C734aq6s.mjs +1015 -0
- package/dist/media-usage-work-C734aq6s.mjs.map +1 -0
- package/dist/media-usage-work-lxvV0-UO.mjs +151 -0
- package/dist/media-usage-work-lxvV0-UO.mjs.map +1 -0
- package/dist/menus-6RHNq4ZK.mjs +753 -0
- package/dist/menus-6RHNq4ZK.mjs.map +1 -0
- package/dist/menus-AuCTaO9W.mjs +3704 -0
- package/dist/menus-AuCTaO9W.mjs.map +1 -0
- package/dist/menus-BQKqf0Up.mjs +92 -0
- package/dist/menus-BQKqf0Up.mjs.map +1 -0
- package/dist/migrations/index.d.mts +1 -1
- package/dist/migrations/index.mjs +3 -3
- package/dist/mime-B5M9R53H.mjs +81 -0
- package/dist/mime-B5M9R53H.mjs.map +1 -0
- package/dist/mode-nh0ppSX5.mjs +23 -0
- package/dist/mode-nh0ppSX5.mjs.map +1 -0
- package/dist/node-sqlite-compat-CDOEcc97.mjs +63 -0
- package/dist/node-sqlite-compat-CDOEcc97.mjs.map +1 -0
- package/dist/oauth-authorization-BtYQ80uU.mjs +274 -0
- package/dist/oauth-authorization-BtYQ80uU.mjs.map +1 -0
- package/dist/oauth-clients-C1S4NQHh.mjs +266 -0
- package/dist/oauth-clients-C1S4NQHh.mjs.map +1 -0
- package/dist/oauth-state-store-CpGi2FZH.mjs +50 -0
- package/dist/oauth-state-store-CpGi2FZH.mjs.map +1 -0
- package/dist/oauth-user-lookup-BNp1aFAr.mjs +26 -0
- package/dist/oauth-user-lookup-BNp1aFAr.mjs.map +1 -0
- package/dist/object-cache/memory.d.mts +1 -1
- package/dist/options-B41aLm1I.d.mts +81 -0
- package/dist/options-B41aLm1I.d.mts.map +1 -0
- package/dist/ownership-DoeAIuTg.mjs +12 -0
- package/dist/ownership-DoeAIuTg.mjs.map +1 -0
- package/dist/page/index.d.mts +2 -2
- package/dist/page/index.mjs +6 -6
- package/dist/parse-CmFDTGzp.mjs +81 -0
- package/dist/parse-CmFDTGzp.mjs.map +1 -0
- package/dist/parse-QVS0t5oR.d.mts +172 -0
- package/dist/parse-QVS0t5oR.d.mts.map +1 -0
- package/dist/passkey-config-C-MxsV22.mjs +46 -0
- package/dist/passkey-config-C-MxsV22.mjs.map +1 -0
- package/dist/paths-kr8hAMMI.mjs +77 -0
- package/dist/paths-kr8hAMMI.mjs.map +1 -0
- package/dist/placeholder-Dn7MMdWr.d.mts +306 -0
- package/dist/placeholder-Dn7MMdWr.d.mts.map +1 -0
- package/dist/plan-CuQOeU9g.mjs +135 -0
- package/dist/plan-CuQOeU9g.mjs.map +1 -0
- package/dist/plugin-test-runtime.d.mts +14 -14
- package/dist/plugin-test-runtime.mjs +110 -109
- package/dist/plugin-types.d.mts +2 -2
- package/dist/plugin-utils.d.mts +12 -12
- package/dist/plugins/adapt-sandbox-entry.d.mts +12 -12
- package/dist/plugins/adapt-sandbox-entry.mjs +3 -3
- package/dist/plugins/host.d.mts +5 -5
- package/dist/plugins/host.mjs +44 -43
- package/dist/plugins-CGb-G98c.mjs +261 -0
- package/dist/plugins-CGb-G98c.mjs.map +1 -0
- package/dist/policy-C5wrDXYV.mjs +45 -0
- package/dist/policy-C5wrDXYV.mjs.map +1 -0
- package/dist/portable-text-BnRuiR1-.mjs +307 -0
- package/dist/portable-text-BnRuiR1-.mjs.map +1 -0
- package/dist/preview-xWNSR1Li.mjs +107 -0
- package/dist/preview-xWNSR1Li.mjs.map +1 -0
- package/dist/protocol-ClxN-m1e.d.mts +61 -0
- package/dist/protocol-ClxN-m1e.d.mts.map +1 -0
- package/dist/public-submission-CkmT2SKv.mjs +250 -0
- package/dist/public-submission-CkmT2SKv.mjs.map +1 -0
- package/dist/public-url-B5a0QAh6.mjs +101 -0
- package/dist/public-url-B5a0QAh6.mjs.map +1 -0
- package/dist/query-DHqFiqqH.mjs +41 -0
- package/dist/query-DHqFiqqH.mjs.map +1 -0
- package/dist/query-DT85BehD.mjs +1125 -0
- package/dist/query-DT85BehD.mjs.map +1 -0
- package/dist/rate-limit-iMvcu3eu.mjs +120 -0
- package/dist/rate-limit-iMvcu3eu.mjs.map +1 -0
- package/dist/receipt-Dpp1uaX9.mjs +43 -0
- package/dist/receipt-Dpp1uaX9.mjs.map +1 -0
- package/dist/redirect-BRoLiWQE.mjs +19 -0
- package/dist/redirect-BRoLiWQE.mjs.map +1 -0
- package/dist/redirect-xZNpBoGp.mjs +417 -0
- package/dist/redirect-xZNpBoGp.mjs.map +1 -0
- package/dist/redirects-D4EWeXAo.mjs +148 -0
- package/dist/redirects-D4EWeXAo.mjs.map +1 -0
- package/dist/redirects-DCKqwiWp.mjs +446 -0
- package/dist/redirects-DCKqwiWp.mjs.map +1 -0
- package/dist/registry/testing.mjs +3 -3
- package/dist/registry-DaXmUsD4.mjs +8369 -0
- package/dist/registry-DaXmUsD4.mjs.map +1 -0
- package/dist/relations-JvBP8nGP.mjs +776 -0
- package/dist/relations-JvBP8nGP.mjs.map +1 -0
- package/dist/request-context.d.mts +2 -2
- package/dist/request-context.mjs.map +1 -1
- package/dist/request-meta-B6blULFY.mjs +141 -0
- package/dist/request-meta-B6blULFY.mjs.map +1 -0
- package/dist/resolve-DAhHi5tn.mjs +100 -0
- package/dist/resolve-DAhHi5tn.mjs.map +1 -0
- package/dist/revision-BWEH2qQB.mjs +368 -0
- package/dist/revision-BWEH2qQB.mjs.map +1 -0
- package/dist/route-wire-DK600v4u.mjs +197 -0
- package/dist/route-wire-DK600v4u.mjs.map +1 -0
- package/dist/routes-BeZyaCzv.mjs +272 -0
- package/dist/routes-BeZyaCzv.mjs.map +1 -0
- package/dist/runner-CskI4Hmq.mjs +6372 -0
- package/dist/runner-CskI4Hmq.mjs.map +1 -0
- package/dist/runner-J3Cj6DGk.d.mts +68 -0
- package/dist/runner-J3Cj6DGk.d.mts.map +1 -0
- package/dist/runtime.d.mts +13 -13
- package/dist/runtime.mjs +3 -3
- package/dist/schema/project-env-types.mjs +37 -37
- package/dist/schema-CK0ihqMR.mjs +815 -0
- package/dist/schema-CK0ihqMR.mjs.map +1 -0
- package/dist/schema-VtaZSrC-.mjs +13 -0
- package/dist/schema-VtaZSrC-.mjs.map +1 -0
- package/dist/scopes-BRnGlL9t.mjs +34 -0
- package/dist/scopes-BRnGlL9t.mjs.map +1 -0
- package/dist/search-D6-XK1Sn.mjs +448 -0
- package/dist/search-D6-XK1Sn.mjs.map +1 -0
- package/dist/secrets-Cc_O3Kp-.mjs +369 -0
- package/dist/secrets-Cc_O3Kp-.mjs.map +1 -0
- package/dist/sections-CBDCf7qR.mjs +346 -0
- package/dist/sections-CBDCf7qR.mjs.map +1 -0
- package/dist/seed/index.d.mts +2 -2
- package/dist/seed/index.mjs +35 -35
- package/dist/seo/index.d.mts +3 -3
- package/dist/seo/index.mjs +22 -22
- package/dist/seo-BdeEPDNW.mjs +133 -0
- package/dist/seo-BdeEPDNW.mjs.map +1 -0
- package/dist/seo-C61bnPuV.mjs +114 -0
- package/dist/seo-C61bnPuV.mjs.map +1 -0
- package/dist/service-BuRKLMxa.mjs +150 -0
- package/dist/service-BuRKLMxa.mjs.map +1 -0
- package/dist/session-user-CqkPtrPL.mjs +61 -0
- package/dist/session-user-CqkPtrPL.mjs.map +1 -0
- package/dist/settings-0u0lTthS.mjs +51 -0
- package/dist/settings-0u0lTthS.mjs.map +1 -0
- package/dist/settings-WHr45II1.mjs +61 -0
- package/dist/settings-WHr45II1.mjs.map +1 -0
- package/dist/settings-m5tIYnF0.mjs +443 -0
- package/dist/settings-m5tIYnF0.mjs.map +1 -0
- package/dist/setup-complete-B2_dhZZz.mjs +65 -0
- package/dist/setup-complete-B2_dhZZz.mjs.map +1 -0
- package/dist/setup-nonce-CJV9ftSK.mjs +25 -0
- package/dist/setup-nonce-CJV9ftSK.mjs.map +1 -0
- package/dist/single-flight-cache-D0EaGbN1.mjs +104 -0
- package/dist/single-flight-cache-D0EaGbN1.mjs.map +1 -0
- package/dist/site-settings-KJOqJW6W.mjs +50 -0
- package/dist/site-settings-KJOqJW6W.mjs.map +1 -0
- package/dist/site-url-Ceq_AUK0.mjs +16 -0
- package/dist/site-url-Ceq_AUK0.mjs.map +1 -0
- package/dist/snapshot-Dzsn3NZa.mjs +414 -0
- package/dist/snapshot-Dzsn3NZa.mjs.map +1 -0
- package/dist/ssrf-DsmvZB80.mjs +406 -0
- package/dist/ssrf-DsmvZB80.mjs.map +1 -0
- package/dist/stage-Csnh_yEd.mjs +662 -0
- package/dist/stage-Csnh_yEd.mjs.map +1 -0
- package/dist/staged-Q7pnEVvI.mjs +686 -0
- package/dist/staged-Q7pnEVvI.mjs.map +1 -0
- package/dist/state-kGdOMQRY.mjs +153 -0
- package/dist/state-kGdOMQRY.mjs.map +1 -0
- package/dist/status-D39Fpy8R.mjs +30 -0
- package/dist/status-D39Fpy8R.mjs.map +1 -0
- package/dist/storage/local.d.mts +1 -1
- package/dist/storage/local.mjs +2 -2
- package/dist/storage/s3.d.mts +1 -1
- package/dist/storage/s3.mjs +1 -1
- package/dist/storage-query-C7iy6eUb.d.mts +1615 -0
- package/dist/storage-query-C7iy6eUb.d.mts.map +1 -0
- package/dist/tar-BWiraSUY.mjs +449 -0
- package/dist/tar-BWiraSUY.mjs.map +1 -0
- package/dist/target-DOFs5oUC.mjs +27 -0
- package/dist/target-DOFs5oUC.mjs.map +1 -0
- package/dist/taxonomies-BS40Wxvi.mjs +939 -0
- package/dist/taxonomies-BS40Wxvi.mjs.map +1 -0
- package/dist/taxonomies-DAZU9VDd.mjs +697 -0
- package/dist/taxonomies-DAZU9VDd.mjs.map +1 -0
- package/dist/taxonomy-XzLE95Vx.mjs +525 -0
- package/dist/taxonomy-XzLE95Vx.mjs.map +1 -0
- package/dist/tokens-DSQan4p7.mjs +171 -0
- package/dist/tokens-DSQan4p7.mjs.map +1 -0
- package/dist/transfer-BcCVxDgf.mjs +166 -0
- package/dist/transfer-BcCVxDgf.mjs.map +1 -0
- package/dist/transfer-OMrancOt.mjs +8873 -0
- package/dist/transfer-OMrancOt.mjs.map +1 -0
- package/dist/transfer-download-Dc-ltjZY.mjs +33 -0
- package/dist/transfer-download-Dc-ltjZY.mjs.map +1 -0
- package/dist/transformations-Ddx7UtrY.mjs +196 -0
- package/dist/transformations-Ddx7UtrY.mjs.map +1 -0
- package/dist/transport-flR-Zmds.d.mts +42 -0
- package/dist/transport-flR-Zmds.d.mts.map +1 -0
- package/dist/transport-umzEbgYO.mjs +136 -0
- package/dist/transport-umzEbgYO.mjs.map +1 -0
- package/dist/trusted-proxy-BqfQFs6a.mjs +51 -0
- package/dist/trusted-proxy-BqfQFs6a.mjs.map +1 -0
- package/dist/turnstile-Do60baId.mjs +58 -0
- package/dist/turnstile-Do60baId.mjs.map +1 -0
- package/dist/types-BT1p3uyb.d.mts +1735 -0
- package/dist/types-BT1p3uyb.d.mts.map +1 -0
- package/dist/types-BYaPWs_F.d.mts +198 -0
- package/dist/types-BYaPWs_F.d.mts.map +1 -0
- package/dist/types-C-Xp0CcN.mjs +103 -0
- package/dist/types-C-Xp0CcN.mjs.map +1 -0
- package/dist/types-CLTQ9b_r.d.mts +374 -0
- package/dist/types-CLTQ9b_r.d.mts.map +1 -0
- package/dist/types-CPkQw2T2.d.mts +85 -0
- package/dist/types-CPkQw2T2.d.mts.map +1 -0
- package/dist/types-CQLvuXoZ.d.mts +198 -0
- package/dist/types-CQLvuXoZ.d.mts.map +1 -0
- package/dist/types-CV5xszpF.d.mts +363 -0
- package/dist/types-CV5xszpF.d.mts.map +1 -0
- package/dist/types-CdEMurNh.mjs +77 -0
- package/dist/types-CdEMurNh.mjs.map +1 -0
- package/dist/types-Cj0_yZkn.mjs +18 -0
- package/dist/types-Cj0_yZkn.mjs.map +1 -0
- package/dist/types-CxwtnuSS.mjs +37 -0
- package/dist/types-CxwtnuSS.mjs.map +1 -0
- package/dist/types-DGw8KMX_.mjs +16 -0
- package/dist/types-DGw8KMX_.mjs.map +1 -0
- package/dist/types-DOfVMPoo.d.mts +125 -0
- package/dist/types-DOfVMPoo.d.mts.map +1 -0
- package/dist/types-LtS0SM4F.d.mts +287 -0
- package/dist/types-LtS0SM4F.d.mts.map +1 -0
- package/dist/types-ifgOkcBa.d.mts +916 -0
- package/dist/types-ifgOkcBa.d.mts.map +1 -0
- package/dist/update-check-DOc2aBIU.mjs +161 -0
- package/dist/update-check-DOc2aBIU.mjs.map +1 -0
- package/dist/upload-attempts-nzdc3cay.mjs +32 -0
- package/dist/upload-attempts-nzdc3cay.mjs.map +1 -0
- package/dist/url-pattern-hVbqpXs6.mjs +41 -0
- package/dist/url-pattern-hVbqpXs6.mjs.map +1 -0
- package/dist/user-Dnp53zTq.mjs +171 -0
- package/dist/user-Dnp53zTq.mjs.map +1 -0
- package/dist/utils-CoV-PYhg.mjs +439 -0
- package/dist/utils-CoV-PYhg.mjs.map +1 -0
- package/dist/validate-CfQ9_YlD.d.mts +468 -0
- package/dist/validate-CfQ9_YlD.d.mts.map +1 -0
- package/dist/validate-DBX3DKtL.mjs +516 -0
- package/dist/validate-DBX3DKtL.mjs.map +1 -0
- package/dist/validation-BJMiDhB1.mjs +219 -0
- package/dist/validation-BJMiDhB1.mjs.map +1 -0
- package/dist/version-BaT8yKIT.mjs +7 -0
- package/dist/version-BaT8yKIT.mjs.map +1 -0
- package/dist/version-BwEGkqkx.mjs +9 -0
- package/dist/version-BwEGkqkx.mjs.map +1 -0
- package/dist/virtual-modules-B6vJW15k.mjs +516 -0
- package/dist/virtual-modules-B6vJW15k.mjs.map +1 -0
- package/dist/widgets-BkxBAgZ_.mjs +126 -0
- package/dist/widgets-BkxBAgZ_.mjs.map +1 -0
- package/dist/wxr-taxonomies-D7gAJyOF.mjs +453 -0
- package/dist/wxr-taxonomies-D7gAJyOF.mjs.map +1 -0
- package/dist/wxr-taxonomies-DM5J9AsT.d.mts +34 -0
- package/dist/wxr-taxonomies-DM5J9AsT.d.mts.map +1 -0
- package/dist/zod-generator-BQilAboC.mjs +424 -0
- package/dist/zod-generator-BQilAboC.mjs.map +1 -0
- package/package.json +11 -5
- package/src/api/errors.ts +3 -0
- package/src/api/handlers/bylines.ts +24 -3
- package/src/api/handlers/calendar.ts +246 -0
- package/src/api/handlers/content.ts +12 -5
- package/src/api/handlers/media-allowlist.ts +1 -0
- package/src/api/handlers/media-upload.ts +13 -10
- package/src/api/handlers/plugins.ts +21 -29
- package/src/api/handlers/redirects.ts +6 -6
- package/src/api/schemas/bylines.ts +3 -1
- package/src/api/schemas/content.ts +16 -0
- package/src/astro/integration/index.ts +18 -1
- package/src/astro/integration/routes.ts +5 -0
- package/src/astro/integration/vite-config.ts +11 -0
- package/src/astro/middleware/csp.ts +1 -0
- package/src/astro/middleware/redirect.ts +20 -9
- package/src/astro/middleware/request-context.ts +54 -27
- package/src/astro/middleware.ts +97 -12
- package/src/astro/prefetch.ts +10 -3
- package/src/astro/routes/api/admin/bylines/[id]/translations.ts +0 -5
- package/src/astro/routes/api/admin/bylines/index.ts +1 -1
- package/src/astro/routes/api/admin/plugins/[id]/index.ts +1 -0
- package/src/astro/routes/api/auth/oauth/[provider]/callback.ts +56 -4
- package/src/astro/routes/api/auth/oauth/[provider].ts +37 -4
- package/src/astro/routes/api/calendar.ts +35 -0
- package/src/astro/routes/api/media/upload-url.ts +8 -4
- package/src/astro/routes/api/media.ts +9 -5
- package/src/astro/routes/api/setup/index.ts +14 -2
- package/src/auth/providers/microsoft-admin.tsx +31 -0
- package/src/auth/providers/microsoft.ts +47 -0
- package/src/comments/turnstile.ts +6 -1
- package/src/components/HtmlBlock.astro +17 -6
- package/src/components/HtmlBlockFrame.astro +63 -0
- package/src/components/Iframe.astro +141 -0
- package/src/components/InlinePortableTextEditor.tsx +8 -7
- package/src/components/WebMcpSearch.astro +80 -0
- package/src/components/index.ts +5 -2
- package/src/components/webmcp-search.ts +142 -0
- package/src/config/secrets.ts +27 -15
- package/src/content/converters/portable-text-identity.ts +1 -0
- package/src/content/converters/portable-text-to-prosemirror.ts +36 -2
- package/src/content/converters/prosemirror-to-portable-text.ts +28 -2
- package/src/content/converters/types.ts +24 -0
- package/src/database/content-datetime.ts +11 -4
- package/src/database/migrations/090_redirect_enable_loop_guard.ts +70 -0
- package/src/database/migrations/091_redirect_artifacts.ts +141 -0
- package/src/database/migrations/runner.ts +4 -0
- package/src/database/repositories/content.ts +81 -26
- package/src/database/repositories/redirect.ts +6 -1
- package/src/database/request-scoped.ts +34 -0
- package/src/database/types.ts +23 -0
- package/src/db/adapters.ts +2 -0
- package/src/emdash-runtime.ts +28 -3
- package/src/import/menus.ts +3 -0
- package/src/index.ts +1 -0
- package/src/loader.ts +226 -55
- package/src/mcp/server.ts +12 -4
- package/src/media/mime.ts +21 -0
- package/src/menus/index.ts +30 -26
- package/src/plugins/hooks.ts +10 -0
- package/src/plugins/manager.ts +12 -2
- package/src/plugins/types.ts +16 -0
- package/src/query.ts +12 -29
- package/src/redirects/artifacts.ts +460 -0
- package/src/redirects/cache.ts +76 -41
- package/src/request-context.ts +1 -1
- package/src/seed/apply.ts +65 -57
- package/src/settings/index.ts +17 -12
- package/src/transfer/format/columns.ts +3 -0
- package/src/transfer/import/rebuild.ts +17 -2
- package/src/transfer/import/scaffold.ts +16 -9
- package/src/ui.ts +1 -0
- package/src/utils/sanitize.ts +14 -9
- package/src/virtual-modules.d.ts +3 -0
- package/dist/action-token-D2KE1Rqf.mjs +0 -26
- package/dist/action-token-D2KE1Rqf.mjs.map +0 -1
- package/dist/activation-DDuqAat2.mjs +0 -387
- package/dist/activation-DDuqAat2.mjs.map +0 -1
- package/dist/adapters-Ds-1Pmkm.d.mts +0 -171
- package/dist/adapters-Ds-1Pmkm.d.mts.map +0 -1
- package/dist/allowed-origins-D78QvbTO.mjs +0 -116
- package/dist/allowed-origins-D78QvbTO.mjs.map +0 -1
- package/dist/api-BBZlif0y.mjs +0 -4974
- package/dist/api-BBZlif0y.mjs.map +0 -1
- package/dist/api-tokens-BGbfWZVO.mjs +0 -166
- package/dist/api-tokens-BGbfWZVO.mjs.map +0 -1
- package/dist/apply-CDNV4JJ-.mjs +0 -1672
- package/dist/apply-CDNV4JJ-.mjs.map +0 -1
- package/dist/approvals-CVvJSEBF.mjs +0 -460
- package/dist/approvals-CVvJSEBF.mjs.map +0 -1
- package/dist/artifact-fetch-CGK0DQLj.mjs +0 -659
- package/dist/artifact-fetch-CGK0DQLj.mjs.map +0 -1
- package/dist/audit-BszbE_BP.mjs +0 -127
- package/dist/audit-BszbE_BP.mjs.map +0 -1
- package/dist/authoritative-records-ChM8dTeV.mjs +0 -5172
- package/dist/authoritative-records-ChM8dTeV.mjs.map +0 -1
- package/dist/authorize-CTGywswM.mjs +0 -49
- package/dist/authorize-CTGywswM.mjs.map +0 -1
- package/dist/backup-CDrPP8fI.mjs +0 -246
- package/dist/backup-CDrPP8fI.mjs.map +0 -1
- package/dist/base64-DvnNgP7e.mjs +0 -63
- package/dist/base64-DvnNgP7e.mjs.map +0 -1
- package/dist/block-types-nNEaPkvx.mjs +0 -132
- package/dist/block-types-nNEaPkvx.mjs.map +0 -1
- package/dist/block-values-Bho1nsZF.mjs +0 -175
- package/dist/block-values-Bho1nsZF.mjs.map +0 -1
- package/dist/byline-02tu_Uc-.mjs +0 -909
- package/dist/byline-02tu_Uc-.mjs.map +0 -1
- package/dist/byline-fields-BYbTptTU.mjs +0 -280
- package/dist/byline-fields-BYbTptTU.mjs.map +0 -1
- package/dist/byline-fields-BjQH-1z9.mjs +0 -123
- package/dist/byline-fields-BjQH-1z9.mjs.map +0 -1
- package/dist/bylines-VytjeHBI.mjs +0 -214
- package/dist/bylines-VytjeHBI.mjs.map +0 -1
- package/dist/bylines-gyWBWUUc.mjs +0 -150
- package/dist/bylines-gyWBWUUc.mjs.map +0 -1
- package/dist/cache-CPanL9IO.mjs +0 -114
- package/dist/cache-CPanL9IO.mjs.map +0 -1
- package/dist/canonical-CAecl1UQ.mjs +0 -174
- package/dist/canonical-CAecl1UQ.mjs.map +0 -1
- package/dist/capture-triggers-CdZfvHtF.mjs +0 -362
- package/dist/capture-triggers-CdZfvHtF.mjs.map +0 -1
- package/dist/challenge-store-VePApay4.mjs +0 -51
- package/dist/challenge-store-VePApay4.mjs.map +0 -1
- package/dist/checksum-BSIhEAYW.mjs +0 -162
- package/dist/checksum-BSIhEAYW.mjs.map +0 -1
- package/dist/chrome-tags-CKELm-bo.mjs +0 -24
- package/dist/chrome-tags-CKELm-bo.mjs.map +0 -1
- package/dist/chunks-DBmkKmBH.mjs +0 -25
- package/dist/chunks-DBmkKmBH.mjs.map +0 -1
- package/dist/collection-slugs-cache-BNRAPNiu.mjs +0 -85
- package/dist/collection-slugs-cache-BNRAPNiu.mjs.map +0 -1
- package/dist/comment-Cq1UYN8_.mjs +0 -313
- package/dist/comment-Cq1UYN8_.mjs.map +0 -1
- package/dist/comment-reaction-B5sZzSoA.mjs +0 -85
- package/dist/comment-reaction-B5sZzSoA.mjs.map +0 -1
- package/dist/comments-B3F-ETyh.mjs +0 -195
- package/dist/comments-B3F-ETyh.mjs.map +0 -1
- package/dist/comments-zrTgWBSg.mjs +0 -99
- package/dist/comments-zrTgWBSg.mjs.map +0 -1
- package/dist/components-Dbf4Eq16.mjs +0 -108
- package/dist/components-Dbf4Eq16.mjs.map +0 -1
- package/dist/config-BCM5sQP7.d.mts +0 -6688
- package/dist/config-BCM5sQP7.d.mts.map +0 -1
- package/dist/config-CXPcy2iY.mjs +0 -228
- package/dist/config-CXPcy2iY.mjs.map +0 -1
- package/dist/config-CZkZBuBK.d.mts +0 -39
- package/dist/config-CZkZBuBK.d.mts.map +0 -1
- package/dist/connection-C5GIciX9.mjs +0 -36
- package/dist/connection-C5GIciX9.mjs.map +0 -1
- package/dist/content-RzEXY3QX.mjs +0 -2020
- package/dist/content-RzEXY3QX.mjs.map +0 -1
- package/dist/content-list-query-B6P37Ug_.d.mts +0 -26
- package/dist/content-list-query-B6P37Ug_.d.mts.map +0 -1
- package/dist/content-repair-BDVsYXWK.mjs +0 -442
- package/dist/content-repair-BDVsYXWK.mjs.map +0 -1
- package/dist/context-BpTIzY5h.mjs +0 -2026
- package/dist/context-BpTIzY5h.mjs.map +0 -1
- package/dist/credits-JOE92Gr7.mjs +0 -110
- package/dist/credits-JOE92Gr7.mjs.map +0 -1
- package/dist/cron-ktyapbdB.mjs +0 -306
- package/dist/cron-ktyapbdB.mjs.map +0 -1
- package/dist/dashboard-BoV4pwPP.mjs +0 -151
- package/dist/dashboard-BoV4pwPP.mjs.map +0 -1
- package/dist/default-B7KnYwtQ.mjs +0 -81
- package/dist/default-B7KnYwtQ.mjs.map +0 -1
- package/dist/deferred-tasks-eaUIqXj8.d.mts +0 -9
- package/dist/deferred-tasks-eaUIqXj8.d.mts.map +0 -1
- package/dist/dev-typegen-8JlYYFno.mjs +0 -29
- package/dist/dev-typegen-8JlYYFno.mjs.map +0 -1
- package/dist/device-flow-BlV_z24g.mjs +0 -521
- package/dist/device-flow-BlV_z24g.mjs.map +0 -1
- package/dist/digest-DiYAoZpf.mjs +0 -194
- package/dist/digest-DiYAoZpf.mjs.map +0 -1
- package/dist/direct-executor-Db8xA3zg.mjs +0 -104
- package/dist/direct-executor-Db8xA3zg.mjs.map +0 -1
- package/dist/email-console-Dm78wSmg.mjs +0 -50
- package/dist/email-console-Dm78wSmg.mjs.map +0 -1
- package/dist/email-locale-B4X9LXe9.mjs +0 -25
- package/dist/email-locale-B4X9LXe9.mjs.map +0 -1
- package/dist/emdash-runtime-BakQ6io7.mjs +0 -4239
- package/dist/emdash-runtime-BakQ6io7.mjs.map +0 -1
- package/dist/enrich-BDdVNeDK.mjs +0 -194
- package/dist/enrich-BDdVNeDK.mjs.map +0 -1
- package/dist/entry-lock-DY8B-xcr.d.mts +0 -4544
- package/dist/entry-lock-DY8B-xcr.d.mts.map +0 -1
- package/dist/entry-lock-DrUAdTzf.mjs +0 -163
- package/dist/entry-lock-DrUAdTzf.mjs.map +0 -1
- package/dist/entry-lock-yIkBduqJ.mjs +0 -1180
- package/dist/entry-lock-yIkBduqJ.mjs.map +0 -1
- package/dist/env-types-DkHYR2pl.mjs +0 -38
- package/dist/env-types-DkHYR2pl.mjs.map +0 -1
- package/dist/error-DIYXAVk4.mjs +0 -90
- package/dist/error-DIYXAVk4.mjs.map +0 -1
- package/dist/errors-CNvATh_7.mjs +0 -469
- package/dist/errors-CNvATh_7.mjs.map +0 -1
- package/dist/errors-CjXd1LgH.mjs +0 -120
- package/dist/errors-CjXd1LgH.mjs.map +0 -1
- package/dist/escape-B1GM0yJU.mjs +0 -9
- package/dist/escape-B1GM0yJU.mjs.map +0 -1
- package/dist/fence-8MaKKWhp.mjs +0 -162
- package/dist/fence-8MaKKWhp.mjs.map +0 -1
- package/dist/field-defs-cache-DEkFYCDE.mjs +0 -77
- package/dist/field-defs-cache-DEkFYCDE.mjs.map +0 -1
- package/dist/field-map-D7ioN0r0.mjs +0 -83
- package/dist/field-map-D7ioN0r0.mjs.map +0 -1
- package/dist/fts-manager-DU03MxWu.mjs +0 -443
- package/dist/fts-manager-DU03MxWu.mjs.map +0 -1
- package/dist/gc-DMiE7ezk.mjs +0 -75
- package/dist/gc-DMiE7ezk.mjs.map +0 -1
- package/dist/hash-CY4QdeMJ.mjs +0 -37
- package/dist/hash-CY4QdeMJ.mjs.map +0 -1
- package/dist/hook-result-Cb67D3P3.d.mts +0 -31
- package/dist/hook-result-Cb67D3P3.d.mts.map +0 -1
- package/dist/hreflang-Bterc3b7.mjs +0 -105
- package/dist/hreflang-Bterc3b7.mjs.map +0 -1
- package/dist/hreflang-uIBOE5yg.d.mts +0 -50
- package/dist/hreflang-uIBOE5yg.d.mts.map +0 -1
- package/dist/http-route-dispatch-DubjTibD.mjs +0 -339
- package/dist/http-route-dispatch-DubjTibD.mjs.map +0 -1
- package/dist/identity-DJ-5AcdG.mjs +0 -35
- package/dist/identity-DJ-5AcdG.mjs.map +0 -1
- package/dist/import-DEfuIgRz.mjs +0 -2020
- package/dist/import-DEfuIgRz.mjs.map +0 -1
- package/dist/index-xCy3j0f6.d.mts +0 -623
- package/dist/index-xCy3j0f6.d.mts.map +0 -1
- package/dist/init-lock-4eRRB4Le.mjs +0 -56
- package/dist/init-lock-4eRRB4Le.mjs.map +0 -1
- package/dist/install-finalization-DeGRbaVa.mjs +0 -58
- package/dist/install-finalization-DeGRbaVa.mjs.map +0 -1
- package/dist/keys-DWwMxdZh.mjs +0 -61
- package/dist/keys-DWwMxdZh.mjs.map +0 -1
- package/dist/kinds-D1A-00-F.mjs +0 -974
- package/dist/kinds-D1A-00-F.mjs.map +0 -1
- package/dist/lifecycle-BWtBGNEn.mjs +0 -25
- package/dist/lifecycle-BWtBGNEn.mjs.map +0 -1
- package/dist/load-BR1NEa_3.mjs +0 -28
- package/dist/load-BR1NEa_3.mjs.map +0 -1
- package/dist/loader-D4edocWH.mjs +0 -1197
- package/dist/loader-D4edocWH.mjs.map +0 -1
- package/dist/loops-DLaHFrvI.mjs +0 -205
- package/dist/loops-DLaHFrvI.mjs.map +0 -1
- package/dist/manifest-builder-8jsSLR7s.mjs +0 -189
- package/dist/manifest-builder-8jsSLR7s.mjs.map +0 -1
- package/dist/manifest-schema-DcZjRNEv.mjs +0 -496
- package/dist/manifest-schema-DcZjRNEv.mjs.map +0 -1
- package/dist/marketplace-CNxjq10S.mjs +0 -257
- package/dist/marketplace-CNxjq10S.mjs.map +0 -1
- package/dist/media-3v7mqAVX.mjs +0 -294
- package/dist/media-3v7mqAVX.mjs.map +0 -1
- package/dist/media-Bs6qmlVl.mjs +0 -408
- package/dist/media-Bs6qmlVl.mjs.map +0 -1
- package/dist/media-CputjGE1.mjs +0 -373
- package/dist/media-CputjGE1.mjs.map +0 -1
- package/dist/media-allowlist-isqF1gAh.mjs +0 -44
- package/dist/media-allowlist-isqF1gAh.mjs.map +0 -1
- package/dist/media-folders-D2VdVBf6.mjs +0 -210
- package/dist/media-folders-D2VdVBf6.mjs.map +0 -1
- package/dist/media-url-DbkMY3y6.mjs +0 -43
- package/dist/media-url-DbkMY3y6.mjs.map +0 -1
- package/dist/media-usage-activation-BaT4AlNI.mjs +0 -78
- package/dist/media-usage-activation-BaT4AlNI.mjs.map +0 -1
- package/dist/media-usage-v43L0kR_.mjs +0 -282
- package/dist/media-usage-v43L0kR_.mjs.map +0 -1
- package/dist/media-usage-work-CY8gIeU-.mjs +0 -151
- package/dist/media-usage-work-CY8gIeU-.mjs.map +0 -1
- package/dist/media-usage-work-VO108Q9E.mjs +0 -1015
- package/dist/media-usage-work-VO108Q9E.mjs.map +0 -1
- package/dist/menus-BYyeRemR.mjs +0 -3647
- package/dist/menus-BYyeRemR.mjs.map +0 -1
- package/dist/menus-mC_XTxD7.mjs +0 -92
- package/dist/menus-mC_XTxD7.mjs.map +0 -1
- package/dist/menus-trvc6_fW.mjs +0 -753
- package/dist/menus-trvc6_fW.mjs.map +0 -1
- package/dist/mime-IZf-LHIS.mjs +0 -36
- package/dist/mime-IZf-LHIS.mjs.map +0 -1
- package/dist/mode-B9-gMXL9.mjs +0 -23
- package/dist/mode-B9-gMXL9.mjs.map +0 -1
- package/dist/node-sqlite-compat-DztcWs4y.mjs +0 -63
- package/dist/node-sqlite-compat-DztcWs4y.mjs.map +0 -1
- package/dist/oauth-authorization-BIHy9SGU.mjs +0 -274
- package/dist/oauth-authorization-BIHy9SGU.mjs.map +0 -1
- package/dist/oauth-clients-BZWZvKXa.mjs +0 -266
- package/dist/oauth-clients-BZWZvKXa.mjs.map +0 -1
- package/dist/oauth-state-store-CxXTjXdI.mjs +0 -50
- package/dist/oauth-state-store-CxXTjXdI.mjs.map +0 -1
- package/dist/oauth-user-lookup-GWojfxRl.mjs +0 -26
- package/dist/oauth-user-lookup-GWojfxRl.mjs.map +0 -1
- package/dist/options-DRF6dlXY.d.mts +0 -81
- package/dist/options-DRF6dlXY.d.mts.map +0 -1
- package/dist/ownership-Bd77AmJz.mjs +0 -12
- package/dist/ownership-Bd77AmJz.mjs.map +0 -1
- package/dist/parse-5Y0W39xR.mjs +0 -81
- package/dist/parse-5Y0W39xR.mjs.map +0 -1
- package/dist/parse-BPblgoa-.d.mts +0 -172
- package/dist/parse-BPblgoa-.d.mts.map +0 -1
- package/dist/passkey-config-PiQ5cBnt.mjs +0 -46
- package/dist/passkey-config-PiQ5cBnt.mjs.map +0 -1
- package/dist/paths-DkS74lBM.mjs +0 -77
- package/dist/paths-DkS74lBM.mjs.map +0 -1
- package/dist/placeholder-Bez2282x.d.mts +0 -306
- package/dist/placeholder-Bez2282x.d.mts.map +0 -1
- package/dist/plan-Lw7iGnGD.mjs +0 -135
- package/dist/plan-Lw7iGnGD.mjs.map +0 -1
- package/dist/plugins-D7xSh1Lu.mjs +0 -277
- package/dist/plugins-D7xSh1Lu.mjs.map +0 -1
- package/dist/policy-DMRiMdLn.mjs +0 -45
- package/dist/policy-DMRiMdLn.mjs.map +0 -1
- package/dist/portable-text-kcyN3F-a.mjs +0 -307
- package/dist/portable-text-kcyN3F-a.mjs.map +0 -1
- package/dist/preview--2VDLaND.mjs +0 -107
- package/dist/preview--2VDLaND.mjs.map +0 -1
- package/dist/protocol-FvwLA8P-.d.mts +0 -61
- package/dist/protocol-FvwLA8P-.d.mts.map +0 -1
- package/dist/public-submission-BRyK76U8.mjs +0 -250
- package/dist/public-submission-BRyK76U8.mjs.map +0 -1
- package/dist/public-url-7j0cpCFc.mjs +0 -101
- package/dist/public-url-7j0cpCFc.mjs.map +0 -1
- package/dist/query-BRNTde3V.mjs +0 -41
- package/dist/query-BRNTde3V.mjs.map +0 -1
- package/dist/query-DyYYWOKk.mjs +0 -1161
- package/dist/query-DyYYWOKk.mjs.map +0 -1
- package/dist/rate-limit-D0BcE76H.mjs +0 -120
- package/dist/rate-limit-D0BcE76H.mjs.map +0 -1
- package/dist/receipt-C4icyHlC.mjs +0 -43
- package/dist/receipt-C4icyHlC.mjs.map +0 -1
- package/dist/redirect-9DbtxSNG.mjs +0 -19
- package/dist/redirect-9DbtxSNG.mjs.map +0 -1
- package/dist/redirect-BvFKh8Sz.mjs +0 -416
- package/dist/redirect-BvFKh8Sz.mjs.map +0 -1
- package/dist/redirects-1nhdEaTq.mjs +0 -148
- package/dist/redirects-1nhdEaTq.mjs.map +0 -1
- package/dist/redirects-D1yMnSR9.mjs +0 -446
- package/dist/redirects-D1yMnSR9.mjs.map +0 -1
- package/dist/registry-CzPJNu3H.mjs +0 -8366
- package/dist/registry-CzPJNu3H.mjs.map +0 -1
- package/dist/relations-C8JpSkU6.mjs +0 -776
- package/dist/relations-C8JpSkU6.mjs.map +0 -1
- package/dist/request-meta-Bs60XW1m.mjs +0 -141
- package/dist/request-meta-Bs60XW1m.mjs.map +0 -1
- package/dist/resolve-BHWgMU_X.mjs +0 -100
- package/dist/resolve-BHWgMU_X.mjs.map +0 -1
- package/dist/revision-CGkQA0e5.mjs +0 -366
- package/dist/revision-CGkQA0e5.mjs.map +0 -1
- package/dist/route-wire-ClUVQduA.mjs +0 -197
- package/dist/route-wire-ClUVQduA.mjs.map +0 -1
- package/dist/routes-D2GFl3B7.mjs +0 -272
- package/dist/routes-D2GFl3B7.mjs.map +0 -1
- package/dist/runner-CLpxmhl8.mjs +0 -6197
- package/dist/runner-CLpxmhl8.mjs.map +0 -1
- package/dist/runner-CWl76CH3.d.mts +0 -68
- package/dist/runner-CWl76CH3.d.mts.map +0 -1
- package/dist/schema-27XefSYG.mjs +0 -13
- package/dist/schema-27XefSYG.mjs.map +0 -1
- package/dist/schema-Btvj3BMh.mjs +0 -815
- package/dist/schema-Btvj3BMh.mjs.map +0 -1
- package/dist/scopes-DGCj6K4p.mjs +0 -34
- package/dist/scopes-DGCj6K4p.mjs.map +0 -1
- package/dist/search-pZRRmWjh.mjs +0 -448
- package/dist/search-pZRRmWjh.mjs.map +0 -1
- package/dist/secrets-CIi0nFiR.mjs +0 -341
- package/dist/secrets-CIi0nFiR.mjs.map +0 -1
- package/dist/sections-CIhqs3Ao.mjs +0 -346
- package/dist/sections-CIhqs3Ao.mjs.map +0 -1
- package/dist/seo-DifeiGdl.mjs +0 -114
- package/dist/seo-DifeiGdl.mjs.map +0 -1
- package/dist/seo-DpYxmGaL.mjs +0 -133
- package/dist/seo-DpYxmGaL.mjs.map +0 -1
- package/dist/service-COVdVpSK.mjs +0 -150
- package/dist/service-COVdVpSK.mjs.map +0 -1
- package/dist/session-user-C6IEjuty.mjs +0 -61
- package/dist/session-user-C6IEjuty.mjs.map +0 -1
- package/dist/settings-CwcrX-Ay.mjs +0 -61
- package/dist/settings-CwcrX-Ay.mjs.map +0 -1
- package/dist/settings-D_cJtT48.mjs +0 -439
- package/dist/settings-D_cJtT48.mjs.map +0 -1
- package/dist/settings-tnPQN3Z2.mjs +0 -51
- package/dist/settings-tnPQN3Z2.mjs.map +0 -1
- package/dist/setup-complete-BOrI10UY.mjs +0 -65
- package/dist/setup-complete-BOrI10UY.mjs.map +0 -1
- package/dist/setup-nonce-0XTBLTsX.mjs +0 -25
- package/dist/setup-nonce-0XTBLTsX.mjs.map +0 -1
- package/dist/single-flight-cache-B5O2qhO1.mjs +0 -104
- package/dist/single-flight-cache-B5O2qhO1.mjs.map +0 -1
- package/dist/site-settings-B7vGFRDT.mjs +0 -50
- package/dist/site-settings-B7vGFRDT.mjs.map +0 -1
- package/dist/site-url-wEYRMHBv.mjs +0 -16
- package/dist/site-url-wEYRMHBv.mjs.map +0 -1
- package/dist/snapshot-W36KbLmc.mjs +0 -414
- package/dist/snapshot-W36KbLmc.mjs.map +0 -1
- package/dist/ssrf-CRJ-xom5.mjs +0 -406
- package/dist/ssrf-CRJ-xom5.mjs.map +0 -1
- package/dist/stage-DA0NrTRZ.mjs +0 -662
- package/dist/stage-DA0NrTRZ.mjs.map +0 -1
- package/dist/staged-Bw5eHbKS.mjs +0 -686
- package/dist/staged-Bw5eHbKS.mjs.map +0 -1
- package/dist/state-BTlprvUF.mjs +0 -153
- package/dist/state-BTlprvUF.mjs.map +0 -1
- package/dist/status-C6IrSLMT.mjs +0 -30
- package/dist/status-C6IrSLMT.mjs.map +0 -1
- package/dist/storage-query-CdVF2bng.d.mts +0 -1614
- package/dist/storage-query-CdVF2bng.d.mts.map +0 -1
- package/dist/tar-BGOZARjy.mjs +0 -449
- package/dist/tar-BGOZARjy.mjs.map +0 -1
- package/dist/target-YhYH_0uc.mjs +0 -27
- package/dist/target-YhYH_0uc.mjs.map +0 -1
- package/dist/taxonomies-DK_XBrmT.mjs +0 -697
- package/dist/taxonomies-DK_XBrmT.mjs.map +0 -1
- package/dist/taxonomies-S1M3rUC0.mjs +0 -939
- package/dist/taxonomies-S1M3rUC0.mjs.map +0 -1
- package/dist/taxonomy-BesdHIwi.mjs +0 -525
- package/dist/taxonomy-BesdHIwi.mjs.map +0 -1
- package/dist/tokens-B_ffPF1q.mjs +0 -171
- package/dist/tokens-B_ffPF1q.mjs.map +0 -1
- package/dist/transfer-9fVSxyrV.mjs +0 -166
- package/dist/transfer-9fVSxyrV.mjs.map +0 -1
- package/dist/transfer-B7LUTaYD.mjs +0 -8855
- package/dist/transfer-B7LUTaYD.mjs.map +0 -1
- package/dist/transfer-download-BdNq4VWN.mjs +0 -33
- package/dist/transfer-download-BdNq4VWN.mjs.map +0 -1
- package/dist/transformations-BtQdvyly.mjs +0 -196
- package/dist/transformations-BtQdvyly.mjs.map +0 -1
- package/dist/transport-CriYXY1c.mjs +0 -136
- package/dist/transport-CriYXY1c.mjs.map +0 -1
- package/dist/transport-SnhS6xku.d.mts +0 -42
- package/dist/transport-SnhS6xku.d.mts.map +0 -1
- package/dist/trusted-proxy-C0eHXPd-.mjs +0 -51
- package/dist/trusted-proxy-C0eHXPd-.mjs.map +0 -1
- package/dist/turnstile-BNPrWd1e.mjs +0 -53
- package/dist/turnstile-BNPrWd1e.mjs.map +0 -1
- package/dist/types-B8sF_kE5.d.mts +0 -287
- package/dist/types-B8sF_kE5.d.mts.map +0 -1
- package/dist/types-BYVIYOlD.d.mts +0 -1720
- package/dist/types-BYVIYOlD.d.mts.map +0 -1
- package/dist/types-Bs4bi95j.d.mts +0 -374
- package/dist/types-Bs4bi95j.d.mts.map +0 -1
- package/dist/types-CGuODCZi.d.mts +0 -198
- package/dist/types-CGuODCZi.d.mts.map +0 -1
- package/dist/types-CVsmpTcU.mjs +0 -18
- package/dist/types-CVsmpTcU.mjs.map +0 -1
- package/dist/types-ClFEExxn.mjs +0 -37
- package/dist/types-ClFEExxn.mjs.map +0 -1
- package/dist/types-D994zUWB.d.mts +0 -85
- package/dist/types-D994zUWB.d.mts.map +0 -1
- package/dist/types-DAj1ByJQ.d.mts +0 -125
- package/dist/types-DAj1ByJQ.d.mts.map +0 -1
- package/dist/types-Dlv6esp4.mjs +0 -77
- package/dist/types-Dlv6esp4.mjs.map +0 -1
- package/dist/types-Dr1LVwL7.d.mts +0 -363
- package/dist/types-Dr1LVwL7.d.mts.map +0 -1
- package/dist/types-MN9bOQ1g.d.mts +0 -198
- package/dist/types-MN9bOQ1g.d.mts.map +0 -1
- package/dist/types-d2Szb1oz.mjs +0 -16
- package/dist/types-d2Szb1oz.mjs.map +0 -1
- package/dist/types-ibtP7GEA.d.mts +0 -896
- package/dist/types-ibtP7GEA.d.mts.map +0 -1
- package/dist/types-j6MBDjlZ.mjs +0 -103
- package/dist/types-j6MBDjlZ.mjs.map +0 -1
- package/dist/update-check-D8No-E5s.mjs +0 -161
- package/dist/update-check-D8No-E5s.mjs.map +0 -1
- package/dist/upload-attempts-BodUoFBu.mjs +0 -32
- package/dist/upload-attempts-BodUoFBu.mjs.map +0 -1
- package/dist/url-pattern-DGAG6ZP2.mjs +0 -41
- package/dist/url-pattern-DGAG6ZP2.mjs.map +0 -1
- package/dist/user-BOvuF1sQ.mjs +0 -171
- package/dist/user-BOvuF1sQ.mjs.map +0 -1
- package/dist/utils-Dr01wRKt.mjs +0 -439
- package/dist/utils-Dr01wRKt.mjs.map +0 -1
- package/dist/validate-BttYU7NK.mjs +0 -516
- package/dist/validate-BttYU7NK.mjs.map +0 -1
- package/dist/validate-Df09inbC.d.mts +0 -468
- package/dist/validate-Df09inbC.d.mts.map +0 -1
- package/dist/validation-DH2WRwWO.mjs +0 -219
- package/dist/validation-DH2WRwWO.mjs.map +0 -1
- package/dist/version-BbygH8CT.mjs +0 -7
- package/dist/version-BbygH8CT.mjs.map +0 -1
- package/dist/version-CseoDDOd.mjs +0 -9
- package/dist/version-CseoDDOd.mjs.map +0 -1
- package/dist/virtual-modules-82GlnQyG.mjs +0 -516
- package/dist/virtual-modules-82GlnQyG.mjs.map +0 -1
- package/dist/widgets-DMAgGcQt.mjs +0 -126
- package/dist/widgets-DMAgGcQt.mjs.map +0 -1
- package/dist/wxr-taxonomies-Bi5kFSxQ.mjs +0 -453
- package/dist/wxr-taxonomies-Bi5kFSxQ.mjs.map +0 -1
- package/dist/wxr-taxonomies-y_FpYlDn.d.mts +0 -34
- package/dist/wxr-taxonomies-y_FpYlDn.d.mts.map +0 -1
- package/dist/zod-generator-DnfG5sGQ.mjs +0 -424
- package/dist/zod-generator-DnfG5sGQ.mjs.map +0 -1
- /package/dist/{api-tokens-B4COohsb.mjs → api-tokens-BLz2MtQs.mjs} +0 -0
- /package/dist/{ssrf-sC4_5rxm.mjs → ssrf-tA45vIPX.mjs} +0 -0
|
@@ -1,1015 +0,0 @@
|
|
|
1
|
-
import { n as isMissingTableError } from "./db-errors-CBD5yMro.mjs";
|
|
2
|
-
import { t as validateIdentifier } from "./validate-DANX1-Qi.mjs";
|
|
3
|
-
import { u as isPostgres } from "./dialect-helpers-7_IqPdh9.mjs";
|
|
4
|
-
import { c as encodeCursor, s as decodeCursor } from "./types-j6MBDjlZ.mjs";
|
|
5
|
-
import { t as withTransaction } from "./transaction-BVYIo_yu.mjs";
|
|
6
|
-
import { t as FTSManager } from "./fts-manager-DU03MxWu.mjs";
|
|
7
|
-
import { n as verifyMediaUsageCaptureTriggers } from "./capture-triggers-CdZfvHtF.mjs";
|
|
8
|
-
import { sql } from "kysely";
|
|
9
|
-
import { ulid } from "ulidx";
|
|
10
|
-
|
|
11
|
-
//#region src/media/usage/collection-deletion.ts
|
|
12
|
-
const ACTIVATION_KEY = "incremental_capture";
|
|
13
|
-
const VIRTUAL_DIALECT_ID = "virtual:emdash/dialect";
|
|
14
|
-
var MediaUsageCollectionDeletionRepository = class {
|
|
15
|
-
constructor(db) {
|
|
16
|
-
this.db = db;
|
|
17
|
-
}
|
|
18
|
-
async createTombstone(input) {
|
|
19
|
-
assertIdentity$1(input);
|
|
20
|
-
const now = timestampOffset(this.db, 0);
|
|
21
|
-
await this.db.insertInto("_emdash_media_usage_collection_deletions").values({
|
|
22
|
-
collection_id: input.collectionId,
|
|
23
|
-
collection_slug: input.collectionSlug,
|
|
24
|
-
force_delete: input.forceDelete ? 1 : 0,
|
|
25
|
-
state: "pending",
|
|
26
|
-
phase: "fence",
|
|
27
|
-
next_attempt_at: now,
|
|
28
|
-
updated_at: now
|
|
29
|
-
}).onConflict((conflict) => conflict.column("collection_id").doNothing()).execute();
|
|
30
|
-
const row = await this.db.selectFrom("_emdash_media_usage_collection_deletions").selectAll().where("collection_id", "=", input.collectionId).executeTakeFirstOrThrow();
|
|
31
|
-
if (row.collection_slug !== input.collectionSlug || Boolean(row.force_delete) !== input.forceDelete) throw new Error("Collection deletion tombstone identity conflicts with existing work");
|
|
32
|
-
return rowToRecord(row);
|
|
33
|
-
}
|
|
34
|
-
async claim(input) {
|
|
35
|
-
if (!input.collectionId || !isPhase(input.phase)) throw new Error("Collection deletion claim requires an exact identity and phase");
|
|
36
|
-
if (!Number.isSafeInteger(input.leaseDurationSeconds) || input.leaseDurationSeconds < 1) throw new Error("Collection deletion lease duration must be a positive whole number");
|
|
37
|
-
const leaseToken = ulid();
|
|
38
|
-
const row = await this.db.updateTable("_emdash_media_usage_collection_deletions").set({
|
|
39
|
-
state: "leased",
|
|
40
|
-
lease_token: leaseToken,
|
|
41
|
-
lease_expires_at: timestampOffset(this.db, input.leaseDurationSeconds),
|
|
42
|
-
updated_at: timestampOffset(this.db, 0)
|
|
43
|
-
}).where("collection_id", "=", input.collectionId).where("phase", "=", input.phase).where((eb) => eb.or([eb.and([eb("state", "in", ["pending", "retry"]), timestampIsDue(this.db, "next_attempt_at")]), eb.and([eb("state", "=", "leased"), timestampIsDue(this.db, "lease_expires_at")])])).returningAll().executeTakeFirst();
|
|
44
|
-
if (!row) return null;
|
|
45
|
-
return {
|
|
46
|
-
...rowToRecord(row),
|
|
47
|
-
leaseToken
|
|
48
|
-
};
|
|
49
|
-
}
|
|
50
|
-
async findBySlug(collectionSlug) {
|
|
51
|
-
validateIdentifier(collectionSlug, "collection slug");
|
|
52
|
-
try {
|
|
53
|
-
const row = await this.db.selectFrom("_emdash_media_usage_collection_deletions").selectAll().where("collection_slug", "=", collectionSlug).executeTakeFirst();
|
|
54
|
-
return row ? rowToRecord(row) : null;
|
|
55
|
-
} catch (error) {
|
|
56
|
-
if (isMissingTableError(error)) return null;
|
|
57
|
-
throw error;
|
|
58
|
-
}
|
|
59
|
-
}
|
|
60
|
-
async findDue(limit) {
|
|
61
|
-
if (!Number.isSafeInteger(limit) || limit < 1 || limit > 100) throw new Error("Collection deletion candidate limit must be from 1 to 100");
|
|
62
|
-
const nextAttemptIsDue = timestampIsDue(this.db, "next_attempt_at");
|
|
63
|
-
return (await sql`
|
|
64
|
-
WITH pending_candidates AS (
|
|
65
|
-
SELECT * FROM _emdash_media_usage_collection_deletions
|
|
66
|
-
WHERE state = 'pending' AND ${nextAttemptIsDue}
|
|
67
|
-
ORDER BY next_attempt_at, updated_at, collection_id
|
|
68
|
-
LIMIT ${limit}
|
|
69
|
-
), retry_candidates AS (
|
|
70
|
-
SELECT * FROM _emdash_media_usage_collection_deletions
|
|
71
|
-
WHERE state = 'retry' AND ${nextAttemptIsDue}
|
|
72
|
-
ORDER BY next_attempt_at, updated_at, collection_id
|
|
73
|
-
LIMIT ${limit}
|
|
74
|
-
), leased_candidates AS (
|
|
75
|
-
SELECT * FROM _emdash_media_usage_collection_deletions
|
|
76
|
-
WHERE state = 'leased' AND ${timestampIsDue(this.db, "lease_expires_at")}
|
|
77
|
-
ORDER BY lease_expires_at, updated_at, collection_id
|
|
78
|
-
LIMIT ${limit}
|
|
79
|
-
), candidates AS (
|
|
80
|
-
SELECT * FROM pending_candidates
|
|
81
|
-
UNION ALL SELECT * FROM retry_candidates
|
|
82
|
-
UNION ALL SELECT * FROM leased_candidates
|
|
83
|
-
)
|
|
84
|
-
SELECT * FROM candidates
|
|
85
|
-
ORDER BY CASE WHEN state = 'leased' THEN lease_expires_at ELSE next_attempt_at END,
|
|
86
|
-
updated_at,
|
|
87
|
-
collection_id
|
|
88
|
-
LIMIT ${limit}
|
|
89
|
-
`.execute(this.db)).rows.map(rowToRecord);
|
|
90
|
-
}
|
|
91
|
-
async hasNonterminal() {
|
|
92
|
-
return await this.db.selectFrom("_emdash_media_usage_collection_deletions").select("collection_id").where("state", "in", [
|
|
93
|
-
"pending",
|
|
94
|
-
"retry",
|
|
95
|
-
"leased"
|
|
96
|
-
]).limit(1).executeTakeFirst() !== void 0;
|
|
97
|
-
}
|
|
98
|
-
async findOperatorPage(options) {
|
|
99
|
-
const state = options.state ?? "failed";
|
|
100
|
-
if (!isState(state)) throw new Error("Invalid collection deletion state");
|
|
101
|
-
const limit = options.limit ?? 50;
|
|
102
|
-
if (!Number.isSafeInteger(limit) || limit < 1 || limit > 100) throw new Error("Collection deletion operator limit must be from 1 to 100");
|
|
103
|
-
const cursor = options.cursor ? decodeCursor(options.cursor) : null;
|
|
104
|
-
let query = this.db.selectFrom("_emdash_media_usage_collection_deletions").selectAll().where("state", "=", state);
|
|
105
|
-
if (cursor) query = query.where((eb) => eb.or([eb("updated_at", "<", cursor.orderValue), eb.and([eb("updated_at", "=", cursor.orderValue), eb("collection_id", "<", cursor.id)])]));
|
|
106
|
-
const rows = await query.orderBy("updated_at", "desc").orderBy("collection_id", "desc").limit(limit + 1).execute();
|
|
107
|
-
const items = rows.slice(0, limit).map(rowToOperatorItem);
|
|
108
|
-
const result = { items };
|
|
109
|
-
if (rows.length > limit && items.length > 0) {
|
|
110
|
-
const last = items.at(-1);
|
|
111
|
-
result.nextCursor = encodeCursor(last.updatedAt, last.collectionId);
|
|
112
|
-
}
|
|
113
|
-
return result;
|
|
114
|
-
}
|
|
115
|
-
async retryOperatorDeletion(input) {
|
|
116
|
-
if (!input.collectionId) throw new Error("Collection deletion retry requires an ID");
|
|
117
|
-
const observed = await this.db.selectFrom("_emdash_media_usage_collection_deletions").selectAll().where("collection_id", "=", input.collectionId).executeTakeFirst();
|
|
118
|
-
if (!observed) return { outcome: "not_found" };
|
|
119
|
-
if (observed.state === "leased" && observed.lease_expires_at) {
|
|
120
|
-
const live = await this.db.selectFrom("_emdash_media_usage_collection_deletions").select("lease_expires_at").where("collection_id", "=", input.collectionId).where("state", "=", "leased").where(liveLease(this.db)).executeTakeFirst();
|
|
121
|
-
if (live?.lease_expires_at) return {
|
|
122
|
-
outcome: "lease_active",
|
|
123
|
-
leaseExpiresAt: live.lease_expires_at
|
|
124
|
-
};
|
|
125
|
-
}
|
|
126
|
-
const now = timestampOffset(this.db, 0);
|
|
127
|
-
const reopened = await this.db.updateTable("_emdash_media_usage_collection_deletions").set({
|
|
128
|
-
state: "pending",
|
|
129
|
-
attempt_count: 0,
|
|
130
|
-
next_attempt_at: now,
|
|
131
|
-
lease_token: null,
|
|
132
|
-
lease_expires_at: null,
|
|
133
|
-
last_error_code: null,
|
|
134
|
-
updated_at: now
|
|
135
|
-
}).where("collection_id", "=", input.collectionId).where((eb) => eb.or([eb("state", "in", ["failed", "retry"]), eb.and([eb("state", "=", "leased"), timestampIsDue(this.db, "lease_expires_at")])])).returningAll().executeTakeFirst();
|
|
136
|
-
if (reopened) return {
|
|
137
|
-
outcome: "pending",
|
|
138
|
-
changed: true,
|
|
139
|
-
item: rowToOperatorItem(reopened)
|
|
140
|
-
};
|
|
141
|
-
return { outcome: "conflict" };
|
|
142
|
-
}
|
|
143
|
-
async checkpoint(input) {
|
|
144
|
-
const result = await this.db.updateTable("_emdash_media_usage_collection_deletions").set({
|
|
145
|
-
phase: input.toPhase,
|
|
146
|
-
attempt_count: 0,
|
|
147
|
-
last_error_code: null,
|
|
148
|
-
updated_at: timestampOffset(this.db, 0)
|
|
149
|
-
}).where("collection_id", "=", input.collectionId).where("state", "=", "leased").where("phase", "=", input.fromPhase).where("lease_token", "=", input.leaseToken).where(liveLease(this.db)).executeTakeFirst();
|
|
150
|
-
return Number(result.numUpdatedRows ?? 0) === 1;
|
|
151
|
-
}
|
|
152
|
-
async release(input) {
|
|
153
|
-
const now = timestampOffset(this.db, 0);
|
|
154
|
-
const result = await this.db.updateTable("_emdash_media_usage_collection_deletions").set({
|
|
155
|
-
state: "pending",
|
|
156
|
-
next_attempt_at: now,
|
|
157
|
-
lease_token: null,
|
|
158
|
-
lease_expires_at: null,
|
|
159
|
-
attempt_count: 0,
|
|
160
|
-
last_error_code: null,
|
|
161
|
-
updated_at: now
|
|
162
|
-
}).where("collection_id", "=", input.collectionId).where("state", "=", "leased").where("lease_token", "=", input.leaseToken).where(liveLease(this.db)).executeTakeFirst();
|
|
163
|
-
return Number(result.numUpdatedRows ?? 0) === 1;
|
|
164
|
-
}
|
|
165
|
-
async cancelFence(input) {
|
|
166
|
-
const result = await this.db.deleteFrom("_emdash_media_usage_collection_deletions").where("collection_id", "=", input.collectionId).where("state", "=", "leased").where("phase", "=", "fence").where("lease_token", "=", input.leaseToken).where(liveLease(this.db)).executeTakeFirst();
|
|
167
|
-
return Number(result.numDeletedRows ?? 0) === 1;
|
|
168
|
-
}
|
|
169
|
-
async recordFailure(input) {
|
|
170
|
-
const result = await this.db.updateTable("_emdash_media_usage_collection_deletions").set({
|
|
171
|
-
state: input.terminal ? "failed" : "retry",
|
|
172
|
-
attempt_count: sql`attempt_count + 1`,
|
|
173
|
-
next_attempt_at: timestampOffset(this.db, input.retryDelaySeconds),
|
|
174
|
-
lease_token: null,
|
|
175
|
-
lease_expires_at: null,
|
|
176
|
-
last_error_code: input.errorCode,
|
|
177
|
-
updated_at: timestampOffset(this.db, 0)
|
|
178
|
-
}).where("collection_id", "=", input.collectionId).where("state", "=", "leased").where("lease_token", "=", input.leaseToken).where(liveLease(this.db)).executeTakeFirst();
|
|
179
|
-
return Number(result.numUpdatedRows ?? 0) === 1;
|
|
180
|
-
}
|
|
181
|
-
async deleteRegistryAndCheckpoint(input) {
|
|
182
|
-
return withTransaction(this.db, async (trx) => {
|
|
183
|
-
await trx.deleteFrom("_emdash_collections").where("id", "=", input.collectionId).where("slug", "=", input.collectionSlug).where((eb) => eb.exists(eb.selectFrom("_emdash_media_usage_collection_deletions as deletion").select("deletion.collection_id").where("deletion.collection_id", "=", input.collectionId).where("deletion.collection_slug", "=", input.collectionSlug).where("deletion.state", "=", "leased").where("deletion.phase", "=", "registry").where("deletion.lease_token", "=", input.leaseToken).where(liveLease(trx, "deletion.lease_expires_at")))).execute();
|
|
184
|
-
const checkpoint = await trx.updateTable("_emdash_media_usage_collection_deletions").set({
|
|
185
|
-
phase: "table",
|
|
186
|
-
updated_at: timestampOffset(trx, 0)
|
|
187
|
-
}).where("collection_id", "=", input.collectionId).where("collection_slug", "=", input.collectionSlug).where("state", "=", "leased").where("phase", "=", "registry").where("lease_token", "=", input.leaseToken).where(liveLease(trx)).executeTakeFirst();
|
|
188
|
-
return Number(checkpoint.numUpdatedRows ?? 0) === 1;
|
|
189
|
-
});
|
|
190
|
-
}
|
|
191
|
-
};
|
|
192
|
-
async function deleteActivatedMediaUsageCollection(db, input, options = {}) {
|
|
193
|
-
const frontPhaseLimit = options.frontPhaseLimit ?? 3;
|
|
194
|
-
if (!Number.isSafeInteger(frontPhaseLimit) || frontPhaseLimit < 1 || frontPhaseLimit > 3) throw new Error("Collection deletion front-phase limit must be from 1 to 3");
|
|
195
|
-
validateIdentifier(input.collectionSlug, "collection slug");
|
|
196
|
-
const repository = new MediaUsageCollectionDeletionRepository(db);
|
|
197
|
-
let deletion = await repository.findBySlug(input.collectionSlug);
|
|
198
|
-
if (deletion && input.collectionId && deletion.collectionId !== input.collectionId) throw new Error("Collection deletion tombstone identity conflict");
|
|
199
|
-
if (!deletion) {
|
|
200
|
-
let activation;
|
|
201
|
-
try {
|
|
202
|
-
activation = await db.selectFrom("_emdash_media_usage_activation").select("state").where("task_key", "=", ACTIVATION_KEY).executeTakeFirst();
|
|
203
|
-
} catch (error) {
|
|
204
|
-
if (!isMissingTableError(error)) throw error;
|
|
205
|
-
}
|
|
206
|
-
if (!activation || activation.state === "expanded") return "inactive";
|
|
207
|
-
if (activation.state !== "active") throw new Error("Media usage activation must be active before collection deletion");
|
|
208
|
-
if (!input.collectionId) return "not_found";
|
|
209
|
-
await assertActivatedCollectionDeletionReady(db, {
|
|
210
|
-
collectionId: input.collectionId,
|
|
211
|
-
collectionSlug: input.collectionSlug
|
|
212
|
-
});
|
|
213
|
-
deletion = await repository.createTombstone({
|
|
214
|
-
collectionId: input.collectionId,
|
|
215
|
-
collectionSlug: input.collectionSlug,
|
|
216
|
-
forceDelete: input.forceDelete
|
|
217
|
-
});
|
|
218
|
-
}
|
|
219
|
-
if (deletion.phase !== "fence" && deletion.phase !== "registry" && deletion.phase !== "table") return "deleted";
|
|
220
|
-
const claim = options.claimed ?? await repository.claim({
|
|
221
|
-
collectionId: deletion.collectionId,
|
|
222
|
-
phase: deletion.phase,
|
|
223
|
-
leaseDurationSeconds: 300
|
|
224
|
-
});
|
|
225
|
-
if (!claim) return "in_progress";
|
|
226
|
-
if (claim.collectionId !== deletion.collectionId || claim.phase !== deletion.phase) throw new Error("Collection deletion claim identity conflict");
|
|
227
|
-
let phase = claim.phase;
|
|
228
|
-
let processedFrontPhases = 0;
|
|
229
|
-
const lease = {
|
|
230
|
-
collectionId: claim.collectionId,
|
|
231
|
-
leaseToken: claim.leaseToken
|
|
232
|
-
};
|
|
233
|
-
if (phase === "fence") {
|
|
234
|
-
const captureState = await findCollectionCaptureState(db, claim);
|
|
235
|
-
if (captureState !== "active" && captureState !== "deleting") throw new Error("Activated collection deletion requires a fenced capture lifecycle");
|
|
236
|
-
if (!await verifyMediaUsageCaptureTriggers(db, claim)) throw new Error("Activated collection deletion requires the exact capture trigger set");
|
|
237
|
-
if (captureState === "active") {
|
|
238
|
-
const result = await executeCollectionDeletionGuard(db, {
|
|
239
|
-
action: "fence",
|
|
240
|
-
collectionId: claim.collectionId,
|
|
241
|
-
collectionSlug: claim.collectionSlug,
|
|
242
|
-
leaseToken: claim.leaseToken,
|
|
243
|
-
forceDelete: claim.forceDelete
|
|
244
|
-
});
|
|
245
|
-
if (result.outcome === "has_content") {
|
|
246
|
-
if (!await repository.cancelFence(lease)) throw new Error("Collection deletion lost its fence while preserving content");
|
|
247
|
-
return "has_content";
|
|
248
|
-
}
|
|
249
|
-
if (result.outcome !== "fenced") throw new Error("Collection deletion lost its fence");
|
|
250
|
-
}
|
|
251
|
-
if (!await repository.checkpoint({
|
|
252
|
-
...lease,
|
|
253
|
-
fromPhase: "fence",
|
|
254
|
-
toPhase: "registry"
|
|
255
|
-
})) throw new Error("Collection deletion lost its fence checkpoint");
|
|
256
|
-
phase = "registry";
|
|
257
|
-
processedFrontPhases++;
|
|
258
|
-
if (processedFrontPhases >= frontPhaseLimit) {
|
|
259
|
-
if (!await repository.release(lease)) throw new Error("Collection deletion lost its handoff");
|
|
260
|
-
return "advanced";
|
|
261
|
-
}
|
|
262
|
-
}
|
|
263
|
-
if (phase === "registry") {
|
|
264
|
-
if (!await repository.deleteRegistryAndCheckpoint({
|
|
265
|
-
...lease,
|
|
266
|
-
collectionSlug: claim.collectionSlug
|
|
267
|
-
})) throw new Error("Collection deletion lost its registry checkpoint");
|
|
268
|
-
phase = "table";
|
|
269
|
-
processedFrontPhases++;
|
|
270
|
-
if (processedFrontPhases >= frontPhaseLimit) {
|
|
271
|
-
if (!await repository.release(lease)) throw new Error("Collection deletion lost its handoff");
|
|
272
|
-
return "advanced";
|
|
273
|
-
}
|
|
274
|
-
}
|
|
275
|
-
if (phase === "table") {
|
|
276
|
-
if ((await executeCollectionDeletionGuard(db, {
|
|
277
|
-
action: "drop",
|
|
278
|
-
collectionId: claim.collectionId,
|
|
279
|
-
collectionSlug: claim.collectionSlug,
|
|
280
|
-
leaseToken: claim.leaseToken
|
|
281
|
-
})).outcome !== "dropped") throw new Error("Collection deletion lost its table fence");
|
|
282
|
-
if (!await repository.checkpoint({
|
|
283
|
-
...lease,
|
|
284
|
-
fromPhase: "table",
|
|
285
|
-
toPhase: "work"
|
|
286
|
-
})) throw new Error("Collection deletion lost its table checkpoint");
|
|
287
|
-
}
|
|
288
|
-
if (!await repository.release(lease)) throw new Error("Collection deletion lost its cleanup handoff");
|
|
289
|
-
return "deleted";
|
|
290
|
-
}
|
|
291
|
-
async function isMediaUsageCollectionSlugDeleting(db, collectionSlug) {
|
|
292
|
-
validateIdentifier(collectionSlug, "collection slug");
|
|
293
|
-
try {
|
|
294
|
-
return await db.selectFrom("_emdash_media_usage_collection_deletions").select("collection_id").where("collection_slug", "=", collectionSlug).executeTakeFirst() !== void 0;
|
|
295
|
-
} catch (error) {
|
|
296
|
-
if (isMissingTableError(error)) return false;
|
|
297
|
-
throw error;
|
|
298
|
-
}
|
|
299
|
-
}
|
|
300
|
-
async function assertActivatedCollectionDeletionReady(db, identity) {
|
|
301
|
-
if (await findCollectionCaptureState(db, identity) !== "active") throw new Error("Activated collection deletion requires an active capture lifecycle");
|
|
302
|
-
if (!await verifyMediaUsageCaptureTriggers(db, identity)) throw new Error("Activated collection deletion requires the exact capture trigger set");
|
|
303
|
-
}
|
|
304
|
-
async function findCollectionCaptureState(db, identity) {
|
|
305
|
-
return (await db.selectFrom("_emdash_media_usage_index_status").select("capture_state").where("adapter_id", "=", "content-media").where("scope_type", "=", "collection").where("scope_key", "=", identity.collectionSlug).where("collection_id", "=", identity.collectionId).executeTakeFirst())?.capture_state ?? null;
|
|
306
|
-
}
|
|
307
|
-
async function executeCollectionDeletionGuard(db, input) {
|
|
308
|
-
const executeAdapterGuard = await loadAdapterCollectionDeletionGuard();
|
|
309
|
-
if (executeAdapterGuard) {
|
|
310
|
-
const { default: config } = await import("virtual:emdash/config");
|
|
311
|
-
return executeAdapterGuard(config.database?.config, input);
|
|
312
|
-
}
|
|
313
|
-
return executeLocalCollectionDeletionGuard(db, input);
|
|
314
|
-
}
|
|
315
|
-
async function loadAdapterCollectionDeletionGuard() {
|
|
316
|
-
try {
|
|
317
|
-
return (await import("virtual:emdash/dialect")).executeCollectionDeletionGuard;
|
|
318
|
-
} catch (error) {
|
|
319
|
-
if (isVirtualDialectUnavailableError(error)) return void 0;
|
|
320
|
-
throw error;
|
|
321
|
-
}
|
|
322
|
-
}
|
|
323
|
-
function isVirtualDialectUnavailableError(error) {
|
|
324
|
-
if (!(error instanceof Error) || !("code" in error)) return false;
|
|
325
|
-
if (error.code === "ERR_MODULE_NOT_FOUND") return error.message.includes(VIRTUAL_DIALECT_ID);
|
|
326
|
-
return error.code === "ERR_UNSUPPORTED_ESM_URL_SCHEME" && error.message.includes("Received protocol 'virtual:'");
|
|
327
|
-
}
|
|
328
|
-
async function executeLocalCollectionDeletionGuard(db, input) {
|
|
329
|
-
assertGuardInput(input);
|
|
330
|
-
return db.transaction().execute(async (trx) => {
|
|
331
|
-
if (!await lockLiveTombstone(trx, input)) return { outcome: "stale" };
|
|
332
|
-
if (input.action === "fence") return fenceCollection(trx, input);
|
|
333
|
-
await new FTSManager(trx).dropFtsTable(input.collectionSlug);
|
|
334
|
-
await sql`DROP TABLE IF EXISTS ${sql.ref(`ec_${input.collectionSlug}`)}`.execute(trx);
|
|
335
|
-
return { outcome: "dropped" };
|
|
336
|
-
});
|
|
337
|
-
}
|
|
338
|
-
async function fenceCollection(trx, input) {
|
|
339
|
-
const tableName = `ec_${input.collectionSlug}`;
|
|
340
|
-
validateIdentifier(tableName, "content table");
|
|
341
|
-
if (isPostgres(trx)) await sql`LOCK TABLE ${sql.ref(tableName)} IN SHARE ROW EXCLUSIVE MODE`.execute(trx);
|
|
342
|
-
if (!input.forceDelete) {
|
|
343
|
-
if ((await sql`
|
|
344
|
-
SELECT 1 AS present FROM ${sql.ref(tableName)}
|
|
345
|
-
WHERE deleted_at IS NULL
|
|
346
|
-
LIMIT 1
|
|
347
|
-
`.execute(trx)).rows.length > 0) return { outcome: "has_content" };
|
|
348
|
-
}
|
|
349
|
-
const result = await trx.updateTable("_emdash_media_usage_index_status as status").set({
|
|
350
|
-
capture_state: "deleting",
|
|
351
|
-
updated_at: timestampOffset(trx, 0)
|
|
352
|
-
}).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").where("collection.id", "=", input.collectionId).where("collection.slug", "=", input.collectionSlug))).executeTakeFirst();
|
|
353
|
-
return Number(result.numUpdatedRows ?? 0) === 1 ? { outcome: "fenced" } : { outcome: "stale" };
|
|
354
|
-
}
|
|
355
|
-
async function lockLiveTombstone(trx, input) {
|
|
356
|
-
const phase = input.action === "fence" ? "fence" : "table";
|
|
357
|
-
if (isPostgres(trx)) return await trx.selectFrom("_emdash_media_usage_collection_deletions").select("collection_id").where("collection_id", "=", input.collectionId).where("collection_slug", "=", input.collectionSlug).where("state", "=", "leased").where("phase", "=", phase).where("lease_token", "=", input.leaseToken).where(liveLease(trx)).forUpdate().executeTakeFirst() !== void 0;
|
|
358
|
-
const locked = await trx.updateTable("_emdash_media_usage_collection_deletions").set({ updated_at: sql`updated_at` }).where("collection_id", "=", input.collectionId).where("collection_slug", "=", input.collectionSlug).where("state", "=", "leased").where("phase", "=", phase).where("lease_token", "=", input.leaseToken).where(liveLease(trx)).executeTakeFirst();
|
|
359
|
-
return Number(locked.numUpdatedRows ?? 0) === 1;
|
|
360
|
-
}
|
|
361
|
-
function assertIdentity$1(input) {
|
|
362
|
-
if (!input.collectionId) throw new Error("Collection deletion requires a collection ID");
|
|
363
|
-
validateIdentifier(input.collectionSlug, "collection slug");
|
|
364
|
-
}
|
|
365
|
-
function assertGuardInput(input) {
|
|
366
|
-
assertIdentity$1(input);
|
|
367
|
-
if (!input.leaseToken) throw new Error("Collection deletion requires a lease token");
|
|
368
|
-
}
|
|
369
|
-
function liveLease(db, column = "lease_expires_at") {
|
|
370
|
-
const leaseExpiresAt = sql.ref(column);
|
|
371
|
-
return isPostgres(db) ? sql`${leaseExpiresAt}::timestamptz > clock_timestamp()` : sql`${leaseExpiresAt} > strftime('%Y-%m-%dT%H:%M:%fZ', 'now')`;
|
|
372
|
-
}
|
|
373
|
-
function timestampIsDue(db, column) {
|
|
374
|
-
return isPostgres(db) ? sql`${sql.ref(column)} <= to_char(
|
|
375
|
-
statement_timestamp() AT TIME ZONE 'UTC',
|
|
376
|
-
'YYYY-MM-DD"T"HH24:MI:SS.MS"Z"'
|
|
377
|
-
)` : sql`${sql.ref(column)} <= strftime('%Y-%m-%dT%H:%M:%fZ', 'now')`;
|
|
378
|
-
}
|
|
379
|
-
function timestampOffset(db, offsetSeconds) {
|
|
380
|
-
if (isPostgres(db)) return sql`to_char(
|
|
381
|
-
(clock_timestamp() AT TIME ZONE 'UTC') + (${offsetSeconds} * INTERVAL '1 second'),
|
|
382
|
-
'YYYY-MM-DD"T"HH24:MI:SS.MS"Z"'
|
|
383
|
-
)`;
|
|
384
|
-
return sql`strftime(
|
|
385
|
-
'%Y-%m-%dT%H:%M:%fZ',
|
|
386
|
-
'now',
|
|
387
|
-
${`${offsetSeconds >= 0 ? "+" : ""}${offsetSeconds} seconds`}
|
|
388
|
-
)`;
|
|
389
|
-
}
|
|
390
|
-
function collectionDeletionCurrentTimestamp(db) {
|
|
391
|
-
return timestampOffset(db, 0);
|
|
392
|
-
}
|
|
393
|
-
function rowToRecord(row) {
|
|
394
|
-
if (!isState(row.state) || !isPhase(row.phase)) throw new Error("Invalid media usage collection deletion lifecycle");
|
|
395
|
-
return {
|
|
396
|
-
collectionId: row.collection_id,
|
|
397
|
-
collectionSlug: row.collection_slug,
|
|
398
|
-
forceDelete: Boolean(row.force_delete),
|
|
399
|
-
state: row.state,
|
|
400
|
-
phase: row.phase,
|
|
401
|
-
workCursor: row.work_cursor,
|
|
402
|
-
sourceKey: row.source_key,
|
|
403
|
-
occurrenceCursor: row.occurrence_cursor,
|
|
404
|
-
attemptCount: row.attempt_count,
|
|
405
|
-
nextAttemptAt: row.next_attempt_at,
|
|
406
|
-
leaseToken: row.lease_token,
|
|
407
|
-
leaseExpiresAt: row.lease_expires_at,
|
|
408
|
-
lastErrorCode: row.last_error_code,
|
|
409
|
-
createdAt: row.created_at,
|
|
410
|
-
updatedAt: row.updated_at
|
|
411
|
-
};
|
|
412
|
-
}
|
|
413
|
-
function rowToOperatorItem(row) {
|
|
414
|
-
const deletion = rowToRecord(row);
|
|
415
|
-
return {
|
|
416
|
-
collectionId: deletion.collectionId,
|
|
417
|
-
collectionSlug: deletion.collectionSlug,
|
|
418
|
-
state: deletion.state,
|
|
419
|
-
phase: deletion.phase,
|
|
420
|
-
attemptCount: deletion.attemptCount,
|
|
421
|
-
nextAttemptAt: deletion.nextAttemptAt,
|
|
422
|
-
leaseExpiresAt: deletion.leaseExpiresAt,
|
|
423
|
-
lastErrorCode: deletion.lastErrorCode,
|
|
424
|
-
updatedAt: deletion.updatedAt
|
|
425
|
-
};
|
|
426
|
-
}
|
|
427
|
-
function isState(value) {
|
|
428
|
-
return value === "pending" || value === "retry" || value === "leased" || value === "failed";
|
|
429
|
-
}
|
|
430
|
-
function isPhase(value) {
|
|
431
|
-
return value === "fence" || value === "registry" || value === "table" || value === "work" || value === "sources" || value === "status" || value === "finalize";
|
|
432
|
-
}
|
|
433
|
-
|
|
434
|
-
//#endregion
|
|
435
|
-
//#region src/database/repositories/media-usage-work.ts
|
|
436
|
-
const MAX_PORTABLE_DURATION_SECONDS = 365 * 24 * 60 * 60;
|
|
437
|
-
const MAX_WORK_SELECTION_LIMIT = 1e3;
|
|
438
|
-
const NON_NEGATIVE_DECIMAL_PATTERN = /^(?:0|[1-9][0-9]*)$/;
|
|
439
|
-
const POSITIVE_DECIMAL_PATTERN = /^[1-9][0-9]*$/;
|
|
440
|
-
const STABLE_ERROR_CODE_PATTERN = /^[A-Z][A-Z0-9_]{0,63}$/;
|
|
441
|
-
const MEDIA_USAGE_WORK_OPERATOR_DEFAULT_LIMIT = 50;
|
|
442
|
-
const MEDIA_USAGE_WORK_OPERATOR_MAX_LIMIT = 100;
|
|
443
|
-
const MEDIA_USAGE_RECONCILIATION_PAGE_LIMIT = 1e3;
|
|
444
|
-
const MEDIA_USAGE_WORK_STATES = [
|
|
445
|
-
"pending",
|
|
446
|
-
"retry",
|
|
447
|
-
"leased",
|
|
448
|
-
"failed"
|
|
449
|
-
];
|
|
450
|
-
var MediaUsageWorkRepository = class {
|
|
451
|
-
constructor(db) {
|
|
452
|
-
this.db = db;
|
|
453
|
-
}
|
|
454
|
-
async enqueueReconciliationPage(input) {
|
|
455
|
-
if (!input.collectionId || !input.collectionSlug || !input.runToken || !input.leaseToken) throw new Error("Reconciliation enqueue requires exact collection and lease identity");
|
|
456
|
-
assertNonNegativeDecimal(input.changeEpoch, "change epoch");
|
|
457
|
-
const contentIds = [...new Set(input.contentIds)];
|
|
458
|
-
if (contentIds.length < 1 || contentIds.length > MEDIA_USAGE_RECONCILIATION_PAGE_LIMIT) throw new Error("Reconciliation enqueue requires from 1 to 1000 content IDs");
|
|
459
|
-
if (contentIds.some((contentId) => !contentId)) throw new Error("Reconciliation enqueue content IDs must not be empty");
|
|
460
|
-
const now = this.timestampOffset(0);
|
|
461
|
-
const contentIdsJson = JSON.stringify(contentIds);
|
|
462
|
-
await sql`
|
|
463
|
-
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})`})
|
|
464
|
-
INSERT INTO _emdash_media_usage_work (
|
|
465
|
-
collection_id, collection_slug, content_id, change_epoch, work_version,
|
|
466
|
-
state, attempt_count, next_attempt_at, lease_token, lease_expires_at,
|
|
467
|
-
last_attempted_at, last_error_code, created_at, updated_at
|
|
468
|
-
)
|
|
469
|
-
SELECT
|
|
470
|
-
${input.collectionId}, ${input.collectionSlug}, page.content_id, ${input.changeEpoch}, 1,
|
|
471
|
-
'pending', 0, ${now}, NULL, NULL, NULL, NULL, ${now}, ${now}
|
|
472
|
-
FROM page
|
|
473
|
-
WHERE EXISTS (
|
|
474
|
-
SELECT 1
|
|
475
|
-
FROM _emdash_media_usage_reconciliations AS reconciliation
|
|
476
|
-
INNER JOIN _emdash_media_usage_index_status AS status
|
|
477
|
-
ON status.collection_id = reconciliation.collection_id
|
|
478
|
-
AND status.scope_key = reconciliation.collection_slug
|
|
479
|
-
INNER JOIN _emdash_collections AS collection
|
|
480
|
-
ON collection.id = reconciliation.collection_id
|
|
481
|
-
AND collection.slug = reconciliation.collection_slug
|
|
482
|
-
WHERE reconciliation.collection_id = ${input.collectionId}
|
|
483
|
-
AND reconciliation.collection_slug = ${input.collectionSlug}
|
|
484
|
-
AND reconciliation.run_token = ${input.runToken}
|
|
485
|
-
AND reconciliation.target_epoch = ${input.changeEpoch}
|
|
486
|
-
AND reconciliation.state = 'leased'
|
|
487
|
-
AND reconciliation.phase = ${input.phase}
|
|
488
|
-
AND reconciliation.lease_token = ${input.leaseToken}
|
|
489
|
-
AND ${this.qualifiedLeaseIsLive("reconciliation.lease_expires_at")}
|
|
490
|
-
AND status.adapter_id = 'content-media'
|
|
491
|
-
AND status.scope_type = 'collection'
|
|
492
|
-
AND status.capture_state = 'active'
|
|
493
|
-
AND status.reconciliation_required = 1
|
|
494
|
-
AND status.status = 'running'
|
|
495
|
-
AND status.cursor = ${input.runToken}
|
|
496
|
-
AND status.change_epoch = ${input.changeEpoch}
|
|
497
|
-
AND EXISTS (
|
|
498
|
-
SELECT 1 FROM _emdash_media_usage_activation AS activation
|
|
499
|
-
WHERE activation.task_key = 'incremental_capture'
|
|
500
|
-
AND activation.state = 'active'
|
|
501
|
-
)
|
|
502
|
-
AND NOT EXISTS (
|
|
503
|
-
SELECT 1 FROM _emdash_media_usage_collection_deletions AS deletion
|
|
504
|
-
WHERE deletion.collection_id = reconciliation.collection_id
|
|
505
|
-
)
|
|
506
|
-
)
|
|
507
|
-
ON CONFLICT (collection_id, content_id) DO UPDATE SET
|
|
508
|
-
collection_slug = excluded.collection_slug,
|
|
509
|
-
change_epoch = excluded.change_epoch,
|
|
510
|
-
work_version = _emdash_media_usage_work.work_version + 1,
|
|
511
|
-
state = 'pending',
|
|
512
|
-
attempt_count = 0,
|
|
513
|
-
next_attempt_at = excluded.next_attempt_at,
|
|
514
|
-
lease_token = NULL,
|
|
515
|
-
lease_expires_at = NULL,
|
|
516
|
-
last_attempted_at = NULL,
|
|
517
|
-
last_error_code = NULL,
|
|
518
|
-
updated_at = excluded.updated_at
|
|
519
|
-
WHERE _emdash_media_usage_work.change_epoch < excluded.change_epoch
|
|
520
|
-
`.execute(this.db);
|
|
521
|
-
}
|
|
522
|
-
async findOperatorPage(options) {
|
|
523
|
-
if (!options.collectionSlug) throw new Error("Media usage work listing requires a collection slug");
|
|
524
|
-
if (options.state !== void 0 && !isMediaUsageWorkState(options.state)) throw new Error("Media usage work listing requires a valid state");
|
|
525
|
-
const limit = operatorLimit(options.limit);
|
|
526
|
-
const cursor = options.cursor ? decodeCursor(options.cursor) : null;
|
|
527
|
-
const collection = await this.db.selectFrom("_emdash_collections").select(["id", "slug"]).where("slug", "=", options.collectionSlug).executeTakeFirst();
|
|
528
|
-
if (!collection) return null;
|
|
529
|
-
const states = options.state ? [options.state] : MEDIA_USAGE_WORK_STATES;
|
|
530
|
-
const candidates = [];
|
|
531
|
-
for (const state of states) {
|
|
532
|
-
const rows = await this.findOperatorRows({
|
|
533
|
-
collectionId: collection.id,
|
|
534
|
-
collectionSlug: collection.slug,
|
|
535
|
-
state,
|
|
536
|
-
limit: limit + 1,
|
|
537
|
-
cursor
|
|
538
|
-
});
|
|
539
|
-
candidates.push(...rows.map(rowToOperatorWork));
|
|
540
|
-
}
|
|
541
|
-
const ordered = candidates.toSorted(compareOperatorWork);
|
|
542
|
-
const items = ordered.slice(0, limit);
|
|
543
|
-
const result = { items };
|
|
544
|
-
if (ordered.length > limit && items.length > 0) {
|
|
545
|
-
const last = items.at(-1);
|
|
546
|
-
result.nextCursor = encodeCursor(last.updatedAt, last.contentId);
|
|
547
|
-
}
|
|
548
|
-
return result;
|
|
549
|
-
}
|
|
550
|
-
async findOperatorRows(input) {
|
|
551
|
-
let query = this.db.selectFrom("_emdash_media_usage_work as work").innerJoin("_emdash_collections as current_collection", (join) => join.onRef("current_collection.id", "=", "work.collection_id").onRef("current_collection.slug", "=", "work.collection_slug")).selectAll("work").where("work.collection_id", "=", input.collectionId).where("work.collection_slug", "=", input.collectionSlug).where("work.state", "=", input.state);
|
|
552
|
-
if (input.cursor) query = query.where((eb) => eb.or([eb("work.updated_at", "<", input.cursor.orderValue), eb.and([eb("work.updated_at", "=", input.cursor.orderValue), eb("work.content_id", "<", input.cursor.id)])]));
|
|
553
|
-
return query.orderBy("work.updated_at", "desc").orderBy("work.content_id", "desc").limit(input.limit).execute();
|
|
554
|
-
}
|
|
555
|
-
async retryOperatorWork(input) {
|
|
556
|
-
if (!input.collectionId || !input.contentId) throw new Error("Media usage operator retry requires collection and content IDs");
|
|
557
|
-
const collection = await this.findActiveOperatorCollection(input.collectionId);
|
|
558
|
-
if (!collection) return { outcome: "collection_not_found" };
|
|
559
|
-
const observed = await this.findWorkByIdentity(input.collectionId, input.contentId);
|
|
560
|
-
if (observed?.state === "pending" && observed.collection_slug === collection.slug) return {
|
|
561
|
-
outcome: "pending",
|
|
562
|
-
changed: false,
|
|
563
|
-
work: rowToOperatorWork(observed)
|
|
564
|
-
};
|
|
565
|
-
const invalidated = await this.invalidateCoverageForOperatorRetry({
|
|
566
|
-
...input,
|
|
567
|
-
collectionSlug: collection.slug,
|
|
568
|
-
observed
|
|
569
|
-
});
|
|
570
|
-
if (!invalidated) return this.operatorRetryLost(input);
|
|
571
|
-
const reopened = observed ? await this.reopenObservedWork(observed, collection.slug, invalidated.change_epoch) : await this.createOperatorWork({
|
|
572
|
-
...input,
|
|
573
|
-
collectionSlug: collection.slug,
|
|
574
|
-
changeEpoch: invalidated.change_epoch
|
|
575
|
-
});
|
|
576
|
-
if (reopened) return {
|
|
577
|
-
outcome: "pending",
|
|
578
|
-
changed: true,
|
|
579
|
-
work: rowToOperatorWork(reopened)
|
|
580
|
-
};
|
|
581
|
-
return this.operatorRetryLost(input);
|
|
582
|
-
}
|
|
583
|
-
async findActiveOperatorCollection(collectionId) {
|
|
584
|
-
return await this.db.selectFrom("_emdash_collections as collection").innerJoin("_emdash_media_usage_index_status as status", (join) => join.onRef("status.collection_id", "=", "collection.id").onRef("status.scope_key", "=", "collection.slug")).select(["collection.id", "collection.slug"]).where("collection.id", "=", collectionId).where("status.adapter_id", "=", "content-media").where("status.scope_type", "=", "collection").where("status.capture_state", "=", "active").executeTakeFirst() ?? null;
|
|
585
|
-
}
|
|
586
|
-
async findWorkByIdentity(collectionId, contentId) {
|
|
587
|
-
return await this.db.selectFrom("_emdash_media_usage_work").selectAll().where("collection_id", "=", collectionId).where("content_id", "=", contentId).executeTakeFirst() ?? null;
|
|
588
|
-
}
|
|
589
|
-
async invalidateCoverageForOperatorRetry(input) {
|
|
590
|
-
let query = this.db.updateTable("_emdash_media_usage_index_status as status").set({
|
|
591
|
-
change_epoch: sql`change_epoch + 1`,
|
|
592
|
-
status: sql`CASE WHEN status IN ('complete', 'partial', 'failed') THEN 'stale' ELSE status END`,
|
|
593
|
-
completed_at: sql`CASE WHEN status IN ('complete', 'partial', 'failed') THEN NULL ELSE completed_at END`,
|
|
594
|
-
last_error_code: null,
|
|
595
|
-
updated_at: this.timestampOffset(0)
|
|
596
|
-
}).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")));
|
|
597
|
-
const observed = input.observed;
|
|
598
|
-
if (observed) query = query.where((eb) => {
|
|
599
|
-
let work = eb.selectFrom("_emdash_media_usage_work as work").select("work.content_id").whereRef("work.collection_id", "=", "status.collection_id").where("work.content_id", "=", input.contentId).where("work.work_version", "=", observed.work_version).where("work.state", "=", observed.state);
|
|
600
|
-
if (observed.state === "leased") work = work.where("work.lease_expires_at", "is not", null).where(this.timestampIsDue("work.lease_expires_at"));
|
|
601
|
-
return eb.exists(work);
|
|
602
|
-
});
|
|
603
|
-
else query = query.where((eb) => eb.not(eb.exists(eb.selectFrom("_emdash_media_usage_work as work").select("work.content_id").whereRef("work.collection_id", "=", "status.collection_id").where("work.content_id", "=", input.contentId))));
|
|
604
|
-
return await query.returning("change_epoch").executeTakeFirst() ?? null;
|
|
605
|
-
}
|
|
606
|
-
async reopenObservedWork(observed, collectionSlug, changeEpoch) {
|
|
607
|
-
let query = this.db.updateTable("_emdash_media_usage_work").set({
|
|
608
|
-
collection_slug: collectionSlug,
|
|
609
|
-
change_epoch: changeEpoch,
|
|
610
|
-
work_version: sql`work_version + 1`,
|
|
611
|
-
state: "pending",
|
|
612
|
-
attempt_count: 0,
|
|
613
|
-
next_attempt_at: this.timestampOffset(0),
|
|
614
|
-
lease_token: null,
|
|
615
|
-
lease_expires_at: null,
|
|
616
|
-
last_attempted_at: null,
|
|
617
|
-
last_error_code: null,
|
|
618
|
-
updated_at: this.timestampOffset(0)
|
|
619
|
-
}).where("collection_id", "=", observed.collection_id).where("content_id", "=", observed.content_id).where("work_version", "=", observed.work_version).where("state", "=", observed.state).where((eb) => eb.exists(eb.selectFrom("_emdash_collections as collection").innerJoin("_emdash_media_usage_index_status as status", (join) => join.onRef("status.collection_id", "=", "collection.id").onRef("status.scope_key", "=", "collection.slug")).select("collection.id").where("collection.id", "=", observed.collection_id).where("collection.slug", "=", collectionSlug).where("status.adapter_id", "=", "content-media").where("status.scope_type", "=", "collection").where("status.capture_state", "=", "active").where("status.change_epoch", "=", changeEpoch)));
|
|
620
|
-
if (observed.state === "leased") query = query.where("lease_expires_at", "is not", null).where(this.timestampIsDue("lease_expires_at"));
|
|
621
|
-
return await query.returningAll().executeTakeFirst() ?? null;
|
|
622
|
-
}
|
|
623
|
-
async createOperatorWork(input) {
|
|
624
|
-
const now = this.timestampOffset(0);
|
|
625
|
-
return await this.db.insertInto("_emdash_media_usage_work").columns([
|
|
626
|
-
"collection_id",
|
|
627
|
-
"collection_slug",
|
|
628
|
-
"content_id",
|
|
629
|
-
"change_epoch",
|
|
630
|
-
"work_version",
|
|
631
|
-
"state",
|
|
632
|
-
"attempt_count",
|
|
633
|
-
"next_attempt_at",
|
|
634
|
-
"lease_token",
|
|
635
|
-
"lease_expires_at",
|
|
636
|
-
"last_attempted_at",
|
|
637
|
-
"last_error_code",
|
|
638
|
-
"created_at",
|
|
639
|
-
"updated_at"
|
|
640
|
-
]).expression((insert) => insert.selectFrom("_emdash_media_usage_index_status as status").innerJoin("_emdash_collections as collection", (join) => join.onRef("collection.id", "=", "status.collection_id").onRef("collection.slug", "=", "status.scope_key")).select((select) => [
|
|
641
|
-
select.val(input.collectionId).as("collection_id"),
|
|
642
|
-
"collection.slug as collection_slug",
|
|
643
|
-
select.val(input.contentId).as("content_id"),
|
|
644
|
-
"status.change_epoch as change_epoch",
|
|
645
|
-
select.val(1).as("work_version"),
|
|
646
|
-
select.val("pending").as("state"),
|
|
647
|
-
select.val(0).as("attempt_count"),
|
|
648
|
-
now.as("next_attempt_at"),
|
|
649
|
-
sql`NULL`.as("lease_token"),
|
|
650
|
-
sql`NULL`.as("lease_expires_at"),
|
|
651
|
-
sql`NULL`.as("last_attempted_at"),
|
|
652
|
-
sql`NULL`.as("last_error_code"),
|
|
653
|
-
now.as("created_at"),
|
|
654
|
-
now.as("updated_at")
|
|
655
|
-
]).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("status.change_epoch", "=", input.changeEpoch)).onConflict((conflict) => conflict.columns(["collection_id", "content_id"]).doNothing()).returningAll().executeTakeFirst() ?? null;
|
|
656
|
-
}
|
|
657
|
-
async operatorRetryLost(input) {
|
|
658
|
-
if (!await this.findActiveOperatorCollection(input.collectionId)) return { outcome: "collection_not_found" };
|
|
659
|
-
const current = await this.findWorkByIdentity(input.collectionId, input.contentId);
|
|
660
|
-
if (current?.state === "pending") return {
|
|
661
|
-
outcome: "pending",
|
|
662
|
-
changed: false,
|
|
663
|
-
work: rowToOperatorWork(current)
|
|
664
|
-
};
|
|
665
|
-
const liveLease = await this.findLiveLeaseExpiry(input.collectionId, input.contentId);
|
|
666
|
-
if (liveLease) return {
|
|
667
|
-
outcome: "lease_active",
|
|
668
|
-
leaseExpiresAt: liveLease
|
|
669
|
-
};
|
|
670
|
-
return { outcome: "conflict" };
|
|
671
|
-
}
|
|
672
|
-
async findLiveLeaseExpiry(collectionId, contentId) {
|
|
673
|
-
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;
|
|
674
|
-
}
|
|
675
|
-
async claimDueWorkBatch(input) {
|
|
676
|
-
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}`);
|
|
677
|
-
const leaseDurationSeconds = durationSeconds(input.leaseDurationSeconds, "lease duration", false);
|
|
678
|
-
const leaseToken = ulid();
|
|
679
|
-
const now = this.timestampOffset(0);
|
|
680
|
-
let candidates = this.db.selectFrom("_emdash_media_usage_work as due").select([
|
|
681
|
-
"due.collection_id",
|
|
682
|
-
"due.content_id",
|
|
683
|
-
"due.work_version"
|
|
684
|
-
]).where((eb) => eb.or([eb.and([eb("due.state", "in", ["pending", "retry"]), this.timestampIsDue("due.next_attempt_at")]), eb.and([
|
|
685
|
-
eb("due.state", "=", "leased"),
|
|
686
|
-
eb("due.lease_expires_at", "is not", null),
|
|
687
|
-
this.timestampIsDue("due.lease_expires_at")
|
|
688
|
-
])])).orderBy(sql`CASE
|
|
689
|
-
WHEN due.state = 'leased' THEN due.lease_expires_at
|
|
690
|
-
ELSE due.next_attempt_at
|
|
691
|
-
END`, "asc").orderBy("due.updated_at", "asc").orderBy("due.collection_id", "asc").orderBy("due.content_id", "asc").limit(input.limit);
|
|
692
|
-
if (isPostgres(this.db)) candidates = candidates.forUpdate().skipLocked();
|
|
693
|
-
return (await this.db.with("due_media_usage_work", () => candidates).updateTable("_emdash_media_usage_work").set({
|
|
694
|
-
state: "leased",
|
|
695
|
-
lease_token: leaseToken,
|
|
696
|
-
lease_expires_at: this.timestampOffset(leaseDurationSeconds),
|
|
697
|
-
last_attempted_at: now,
|
|
698
|
-
updated_at: now
|
|
699
|
-
}).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([
|
|
700
|
-
eb("state", "=", "leased"),
|
|
701
|
-
eb("lease_expires_at", "is not", null),
|
|
702
|
-
this.timestampIsDue("lease_expires_at")
|
|
703
|
-
])])])).returningAll().execute()).map(rowToWork);
|
|
704
|
-
}
|
|
705
|
-
async hasNonterminalWork() {
|
|
706
|
-
return await this.db.selectFrom("_emdash_media_usage_work").select("content_id").where("state", "in", [
|
|
707
|
-
"pending",
|
|
708
|
-
"retry",
|
|
709
|
-
"leased"
|
|
710
|
-
]).limit(1).executeTakeFirst() !== void 0;
|
|
711
|
-
}
|
|
712
|
-
async findWorkForContent(collectionSlug, contentId) {
|
|
713
|
-
if (!collectionSlug || !contentId) throw new Error("Media usage work lookup requires collection and content identity");
|
|
714
|
-
const row = await this.db.selectFrom("_emdash_media_usage_work").innerJoin("_emdash_collections as current_collection", (join) => join.onRef("current_collection.id", "=", "_emdash_media_usage_work.collection_id").onRef("current_collection.slug", "=", "_emdash_media_usage_work.collection_slug")).selectAll("_emdash_media_usage_work").where("_emdash_media_usage_work.collection_slug", "=", collectionSlug).where("_emdash_media_usage_work.content_id", "=", contentId).executeTakeFirst();
|
|
715
|
-
return row ? rowToWork(row) : null;
|
|
716
|
-
}
|
|
717
|
-
async claimWork(input) {
|
|
718
|
-
assertIdentity(input);
|
|
719
|
-
const leaseDurationSeconds = durationSeconds(input.leaseDurationSeconds, "lease duration", false);
|
|
720
|
-
const leaseToken = ulid();
|
|
721
|
-
const now = this.timestampOffset(0);
|
|
722
|
-
const row = await this.db.updateTable("_emdash_media_usage_work").set({
|
|
723
|
-
state: "leased",
|
|
724
|
-
lease_token: leaseToken,
|
|
725
|
-
lease_expires_at: this.timestampOffset(leaseDurationSeconds),
|
|
726
|
-
last_attempted_at: now,
|
|
727
|
-
updated_at: now
|
|
728
|
-
}).where("collection_id", "=", input.collectionId).where("content_id", "=", input.contentId).where("work_version", "=", input.workVersion).where((eb) => eb.or([eb.and([eb("state", "in", ["pending", "retry"]), this.timestampIsDue("next_attempt_at")]), eb.and([
|
|
729
|
-
eb("state", "=", "leased"),
|
|
730
|
-
eb("lease_expires_at", "is not", null),
|
|
731
|
-
this.timestampIsDue("lease_expires_at")
|
|
732
|
-
])])).returningAll().executeTakeFirst();
|
|
733
|
-
return row ? rowToWork(row) : null;
|
|
734
|
-
}
|
|
735
|
-
async completeWorkBatch(inputs) {
|
|
736
|
-
const unique = [...new Map(inputs.map((input) => {
|
|
737
|
-
assertLease(input);
|
|
738
|
-
return [workIdentityKey(input), input];
|
|
739
|
-
})).values()];
|
|
740
|
-
const completed = /* @__PURE__ */ new Set();
|
|
741
|
-
if (unique.length === 0) return completed;
|
|
742
|
-
const payload = JSON.stringify(unique.map((input) => ({
|
|
743
|
-
collection_id: input.collectionId,
|
|
744
|
-
content_id: input.contentId,
|
|
745
|
-
work_version: String(input.workVersion),
|
|
746
|
-
lease_token: input.leaseToken
|
|
747
|
-
})));
|
|
748
|
-
const result = await sql`
|
|
749
|
-
WITH claimed AS (${this.claimedWorkBatchInput(payload)})
|
|
750
|
-
DELETE FROM _emdash_media_usage_work AS work
|
|
751
|
-
WHERE work.state = 'leased'
|
|
752
|
-
AND ${this.qualifiedLeaseIsLive("work.lease_expires_at")}
|
|
753
|
-
AND EXISTS (
|
|
754
|
-
SELECT 1
|
|
755
|
-
FROM claimed
|
|
756
|
-
WHERE claimed.collection_id = work.collection_id
|
|
757
|
-
AND claimed.content_id = work.content_id
|
|
758
|
-
AND claimed.work_version = work.work_version
|
|
759
|
-
AND claimed.lease_token = work.lease_token
|
|
760
|
-
)
|
|
761
|
-
RETURNING collection_id, content_id, work_version
|
|
762
|
-
`.execute(this.db);
|
|
763
|
-
for (const row of result.rows) completed.add(workIdentityKey({
|
|
764
|
-
collectionId: row.collection_id,
|
|
765
|
-
contentId: row.content_id,
|
|
766
|
-
workVersion: row.work_version
|
|
767
|
-
}));
|
|
768
|
-
return completed;
|
|
769
|
-
}
|
|
770
|
-
async lockClaimedWorkBatch(inputs) {
|
|
771
|
-
const unique = [...new Map(inputs.map((input) => {
|
|
772
|
-
assertLease(input);
|
|
773
|
-
return [workIdentityKey(input), input];
|
|
774
|
-
})).values()].toSorted((left, right) => workIdentityKey(left).localeCompare(workIdentityKey(right)));
|
|
775
|
-
if (!isPostgres(this.db)) return new Set(unique.map(workIdentityKey));
|
|
776
|
-
if (unique.length === 0) return /* @__PURE__ */ new Set();
|
|
777
|
-
const payload = JSON.stringify(unique.map((input) => ({
|
|
778
|
-
collection_id: input.collectionId,
|
|
779
|
-
content_id: input.contentId,
|
|
780
|
-
work_version: String(input.workVersion),
|
|
781
|
-
lease_token: input.leaseToken
|
|
782
|
-
})));
|
|
783
|
-
const result = await sql`
|
|
784
|
-
WITH claimed AS (${this.claimedWorkBatchInput(payload)})
|
|
785
|
-
SELECT work.collection_id, work.content_id, work.work_version
|
|
786
|
-
FROM _emdash_media_usage_work AS work
|
|
787
|
-
INNER JOIN claimed
|
|
788
|
-
ON claimed.collection_id = work.collection_id
|
|
789
|
-
AND claimed.content_id = work.content_id
|
|
790
|
-
AND claimed.work_version = work.work_version
|
|
791
|
-
AND claimed.lease_token = work.lease_token
|
|
792
|
-
WHERE work.state = 'leased'
|
|
793
|
-
AND ${this.qualifiedLeaseIsLive("work.lease_expires_at")}
|
|
794
|
-
ORDER BY work.collection_id, work.content_id
|
|
795
|
-
FOR UPDATE
|
|
796
|
-
`.execute(this.db);
|
|
797
|
-
return new Set(result.rows.map((row) => workIdentityKey({
|
|
798
|
-
collectionId: row.collection_id,
|
|
799
|
-
contentId: row.content_id,
|
|
800
|
-
workVersion: row.work_version
|
|
801
|
-
})));
|
|
802
|
-
}
|
|
803
|
-
async retryClaimedWorkBatch(input) {
|
|
804
|
-
assertErrorCode(input.errorCode);
|
|
805
|
-
const retryDelaySeconds = durationSeconds(input.retryDelaySeconds, "retry delay", true);
|
|
806
|
-
if (!Number.isSafeInteger(input.maxAttempts) || input.maxAttempts < 1) throw new Error("Media usage work max attempts must be a positive whole number");
|
|
807
|
-
const unique = [...new Map(input.work.map((work) => {
|
|
808
|
-
assertLease(work);
|
|
809
|
-
return [workIdentityKey(work), work];
|
|
810
|
-
})).values()];
|
|
811
|
-
const transitioned = /* @__PURE__ */ new Map();
|
|
812
|
-
if (unique.length === 0) return transitioned;
|
|
813
|
-
const payload = JSON.stringify(unique.map((work) => ({
|
|
814
|
-
collection_id: work.collectionId,
|
|
815
|
-
content_id: work.contentId,
|
|
816
|
-
work_version: String(work.workVersion),
|
|
817
|
-
lease_token: work.leaseToken
|
|
818
|
-
})));
|
|
819
|
-
const result = await sql`
|
|
820
|
-
WITH claimed AS (${this.claimedWorkBatchInput(payload)})
|
|
821
|
-
UPDATE _emdash_media_usage_work AS work
|
|
822
|
-
SET state = CASE WHEN work.attempt_count + 1 >= ${input.maxAttempts} THEN 'failed' ELSE 'retry' END,
|
|
823
|
-
attempt_count = work.attempt_count + 1,
|
|
824
|
-
next_attempt_at = ${this.timestampOffset(retryDelaySeconds)},
|
|
825
|
-
lease_token = NULL,
|
|
826
|
-
lease_expires_at = NULL,
|
|
827
|
-
last_error_code = ${input.errorCode},
|
|
828
|
-
updated_at = ${this.timestampOffset(0)}
|
|
829
|
-
WHERE work.state = 'leased'
|
|
830
|
-
AND ${this.qualifiedLeaseIsLive("work.lease_expires_at")}
|
|
831
|
-
AND EXISTS (
|
|
832
|
-
SELECT 1
|
|
833
|
-
FROM claimed
|
|
834
|
-
WHERE claimed.collection_id = work.collection_id
|
|
835
|
-
AND claimed.content_id = work.content_id
|
|
836
|
-
AND claimed.work_version = work.work_version
|
|
837
|
-
AND claimed.lease_token = work.lease_token
|
|
838
|
-
)
|
|
839
|
-
RETURNING collection_id, content_id, work_version, state
|
|
840
|
-
`.execute(this.db);
|
|
841
|
-
for (const row of result.rows) transitioned.set(workIdentityKey({
|
|
842
|
-
collectionId: row.collection_id,
|
|
843
|
-
contentId: row.content_id,
|
|
844
|
-
workVersion: row.work_version
|
|
845
|
-
}), row.state);
|
|
846
|
-
return transitioned;
|
|
847
|
-
}
|
|
848
|
-
async releaseClaimedWorkBatch(inputs) {
|
|
849
|
-
const unique = [...new Map(inputs.map((input) => {
|
|
850
|
-
assertLease(input);
|
|
851
|
-
return [workIdentityKey(input), input];
|
|
852
|
-
})).values()];
|
|
853
|
-
const released = /* @__PURE__ */ new Set();
|
|
854
|
-
if (unique.length === 0) return released;
|
|
855
|
-
const payload = JSON.stringify(unique.map((input) => ({
|
|
856
|
-
collection_id: input.collectionId,
|
|
857
|
-
content_id: input.contentId,
|
|
858
|
-
work_version: String(input.workVersion),
|
|
859
|
-
lease_token: input.leaseToken
|
|
860
|
-
})));
|
|
861
|
-
const result = await sql`
|
|
862
|
-
WITH claimed AS (${this.claimedWorkBatchInput(payload)})
|
|
863
|
-
UPDATE _emdash_media_usage_work AS work
|
|
864
|
-
SET state = 'pending',
|
|
865
|
-
next_attempt_at = ${this.timestampOffset(0)},
|
|
866
|
-
lease_token = NULL,
|
|
867
|
-
lease_expires_at = NULL,
|
|
868
|
-
updated_at = ${this.timestampOffset(0)}
|
|
869
|
-
WHERE work.state = 'leased'
|
|
870
|
-
AND ${this.qualifiedLeaseIsLive("work.lease_expires_at")}
|
|
871
|
-
AND EXISTS (
|
|
872
|
-
SELECT 1
|
|
873
|
-
FROM claimed
|
|
874
|
-
WHERE claimed.collection_id = work.collection_id
|
|
875
|
-
AND claimed.content_id = work.content_id
|
|
876
|
-
AND claimed.work_version = work.work_version
|
|
877
|
-
AND claimed.lease_token = work.lease_token
|
|
878
|
-
)
|
|
879
|
-
RETURNING collection_id, content_id, work_version
|
|
880
|
-
`.execute(this.db);
|
|
881
|
-
for (const row of result.rows) released.add(workIdentityKey({
|
|
882
|
-
collectionId: row.collection_id,
|
|
883
|
-
contentId: row.content_id,
|
|
884
|
-
workVersion: row.work_version
|
|
885
|
-
}));
|
|
886
|
-
return released;
|
|
887
|
-
}
|
|
888
|
-
async deleteWorkThroughEpoch(collectionId, maxChangeEpoch) {
|
|
889
|
-
if (!collectionId) throw new Error("Media usage work cleanup requires a collection ID");
|
|
890
|
-
assertNonNegativeDecimal(maxChangeEpoch, "change epoch");
|
|
891
|
-
const result = await this.db.deleteFrom("_emdash_media_usage_work").where("collection_id", "=", collectionId).where("change_epoch", "<=", maxChangeEpoch).executeTakeFirst();
|
|
892
|
-
return Number(result.numDeletedRows ?? 0);
|
|
893
|
-
}
|
|
894
|
-
async deleteObsoleteReconciliationWork(input) {
|
|
895
|
-
assertNonNegativeDecimal(input.targetEpoch, "target epoch");
|
|
896
|
-
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();
|
|
897
|
-
return Number(result.numDeletedRows ?? 0);
|
|
898
|
-
}
|
|
899
|
-
leaseIsLive() {
|
|
900
|
-
return isPostgres(this.db) ? sql`lease_expires_at::timestamptz > clock_timestamp()` : sql`lease_expires_at > strftime('%Y-%m-%dT%H:%M:%fZ', 'now')`;
|
|
901
|
-
}
|
|
902
|
-
qualifiedLeaseIsLive(column) {
|
|
903
|
-
const expiry = sql.ref(column);
|
|
904
|
-
return isPostgres(this.db) ? sql`${expiry} > to_char(statement_timestamp() AT TIME ZONE 'UTC', 'YYYY-MM-DD"T"HH24:MI:SS.MS"Z"')` : sql`${expiry} > strftime('%Y-%m-%dT%H:%M:%fZ', 'now')`;
|
|
905
|
-
}
|
|
906
|
-
timestampIsDue(column) {
|
|
907
|
-
return isPostgres(this.db) ? sql`${sql.ref(column)} <= to_char(
|
|
908
|
-
statement_timestamp() AT TIME ZONE 'UTC',
|
|
909
|
-
'YYYY-MM-DD"T"HH24:MI:SS.MS"Z"'
|
|
910
|
-
)` : sql`${sql.ref(column)} <= strftime('%Y-%m-%dT%H:%M:%fZ', 'now')`;
|
|
911
|
-
}
|
|
912
|
-
timestampOffset(offsetSeconds) {
|
|
913
|
-
if (isPostgres(this.db)) return sql`to_char(
|
|
914
|
-
(clock_timestamp() AT TIME ZONE 'UTC') + (${offsetSeconds} * INTERVAL '1 second'),
|
|
915
|
-
'YYYY-MM-DD"T"HH24:MI:SS.MS"Z"'
|
|
916
|
-
)`;
|
|
917
|
-
return sql`strftime(
|
|
918
|
-
'%Y-%m-%dT%H:%M:%fZ',
|
|
919
|
-
'now',
|
|
920
|
-
${`${offsetSeconds >= 0 ? "+" : ""}${offsetSeconds} seconds`}
|
|
921
|
-
)`;
|
|
922
|
-
}
|
|
923
|
-
claimedWorkBatchInput(payload) {
|
|
924
|
-
if (isPostgres(this.db)) return sql`
|
|
925
|
-
SELECT
|
|
926
|
-
entry.value ->> 'collection_id' AS collection_id,
|
|
927
|
-
entry.value ->> 'content_id' AS content_id,
|
|
928
|
-
CAST(entry.value ->> 'work_version' AS bigint) AS work_version,
|
|
929
|
-
entry.value ->> 'lease_token' AS lease_token
|
|
930
|
-
FROM jsonb_array_elements(${payload}::jsonb) AS entry(value)
|
|
931
|
-
`;
|
|
932
|
-
return sql`
|
|
933
|
-
SELECT
|
|
934
|
-
json_extract(entry.value, '$.collection_id') AS collection_id,
|
|
935
|
-
json_extract(entry.value, '$.content_id') AS content_id,
|
|
936
|
-
CAST(json_extract(entry.value, '$.work_version') AS integer) AS work_version,
|
|
937
|
-
json_extract(entry.value, '$.lease_token') AS lease_token
|
|
938
|
-
FROM json_each(${payload}) AS entry
|
|
939
|
-
`;
|
|
940
|
-
}
|
|
941
|
-
};
|
|
942
|
-
function workIdentityKey(input) {
|
|
943
|
-
return `${input.collectionId}\u0000${input.contentId}\u0000${String(input.workVersion)}`;
|
|
944
|
-
}
|
|
945
|
-
function operatorLimit(value) {
|
|
946
|
-
if (value === void 0) return MEDIA_USAGE_WORK_OPERATOR_DEFAULT_LIMIT;
|
|
947
|
-
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}`);
|
|
948
|
-
return value;
|
|
949
|
-
}
|
|
950
|
-
function durationSeconds(value, label, allowZero) {
|
|
951
|
-
if (!Number.isSafeInteger(value) || value < (allowZero ? 0 : 1) || value > MAX_PORTABLE_DURATION_SECONDS) throw new Error(`Media usage work ${label} must be ${allowZero ? "a non-negative" : "a positive"} whole number of seconds no greater than one year`);
|
|
952
|
-
return value;
|
|
953
|
-
}
|
|
954
|
-
function assertIdentity(input) {
|
|
955
|
-
if (!input.collectionId || !input.contentId) throw new Error("Media usage work identity must include collection and content IDs");
|
|
956
|
-
if (!(typeof input.workVersion === "number" && Number.isSafeInteger(input.workVersion) && input.workVersion > 0 || typeof input.workVersion === "string" && POSITIVE_DECIMAL_PATTERN.test(input.workVersion))) throw new Error("Media usage work identity must include a work version");
|
|
957
|
-
}
|
|
958
|
-
function assertNonNegativeDecimal(value, label) {
|
|
959
|
-
if (!(typeof value === "number" && Number.isSafeInteger(value) && value >= 0 || typeof value === "string" && NON_NEGATIVE_DECIMAL_PATTERN.test(value))) throw new Error(`Media usage work ${label} must be a non-negative whole number`);
|
|
960
|
-
}
|
|
961
|
-
function assertToken(value) {
|
|
962
|
-
if (!value) throw new Error("Media usage work lease token must not be empty");
|
|
963
|
-
}
|
|
964
|
-
function assertLease(input) {
|
|
965
|
-
assertIdentity(input);
|
|
966
|
-
assertToken(input.leaseToken);
|
|
967
|
-
}
|
|
968
|
-
function assertErrorCode(value) {
|
|
969
|
-
if (!STABLE_ERROR_CODE_PATTERN.test(value)) throw new Error("Media usage work error code must use a stable SCREAMING_SNAKE_CASE value");
|
|
970
|
-
}
|
|
971
|
-
function rowToWork(row) {
|
|
972
|
-
if (!isMediaUsageWorkState(row.state)) throw new Error(`Invalid media usage work state: ${row.state}`);
|
|
973
|
-
return {
|
|
974
|
-
collectionId: row.collection_id,
|
|
975
|
-
collectionSlug: row.collection_slug,
|
|
976
|
-
contentId: row.content_id,
|
|
977
|
-
changeEpoch: row.change_epoch,
|
|
978
|
-
workVersion: row.work_version,
|
|
979
|
-
state: row.state,
|
|
980
|
-
attemptCount: row.attempt_count,
|
|
981
|
-
nextAttemptAt: row.next_attempt_at,
|
|
982
|
-
leaseToken: row.lease_token,
|
|
983
|
-
leaseExpiresAt: row.lease_expires_at,
|
|
984
|
-
lastAttemptedAt: row.last_attempted_at,
|
|
985
|
-
lastErrorCode: row.last_error_code,
|
|
986
|
-
createdAt: row.created_at,
|
|
987
|
-
updatedAt: row.updated_at
|
|
988
|
-
};
|
|
989
|
-
}
|
|
990
|
-
function rowToOperatorWork(row) {
|
|
991
|
-
const work = "collection_id" in row ? rowToWork(row) : row;
|
|
992
|
-
return {
|
|
993
|
-
collectionId: work.collectionId,
|
|
994
|
-
collectionSlug: work.collectionSlug,
|
|
995
|
-
contentId: work.contentId,
|
|
996
|
-
state: work.state,
|
|
997
|
-
attemptCount: work.attemptCount,
|
|
998
|
-
nextAttemptAt: work.nextAttemptAt,
|
|
999
|
-
leaseExpiresAt: work.leaseExpiresAt,
|
|
1000
|
-
lastAttemptedAt: work.lastAttemptedAt,
|
|
1001
|
-
lastErrorCode: work.lastErrorCode,
|
|
1002
|
-
updatedAt: work.updatedAt
|
|
1003
|
-
};
|
|
1004
|
-
}
|
|
1005
|
-
function isMediaUsageWorkState(value) {
|
|
1006
|
-
return value === "pending" || value === "retry" || value === "leased" || value === "failed";
|
|
1007
|
-
}
|
|
1008
|
-
function compareOperatorWork(a, b) {
|
|
1009
|
-
const updated = b.updatedAt.localeCompare(a.updatedAt);
|
|
1010
|
-
return updated !== 0 ? updated : b.contentId.localeCompare(a.contentId);
|
|
1011
|
-
}
|
|
1012
|
-
|
|
1013
|
-
//#endregion
|
|
1014
|
-
export { isMediaUsageCollectionSlugDeleting as a, deleteActivatedMediaUsageCollection as i, MediaUsageCollectionDeletionRepository as n, collectionDeletionCurrentTimestamp as r, MediaUsageWorkRepository as t };
|
|
1015
|
-
//# sourceMappingURL=media-usage-work-VO108Q9E.mjs.map
|