emdash 0.40.0 → 0.41.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-CbKDcPJi.mjs +26 -0
- package/dist/action-token-CbKDcPJi.mjs.map +1 -0
- package/dist/activation-PtniBLt9.mjs +382 -0
- package/dist/activation-PtniBLt9.mjs.map +1 -0
- package/dist/adapters-C_Tf5x90.d.mts +171 -0
- package/dist/adapters-C_Tf5x90.d.mts.map +1 -0
- package/dist/allowed-origins-U1z4TdEZ.mjs +116 -0
- package/dist/allowed-origins-U1z4TdEZ.mjs.map +1 -0
- package/dist/api/route-utils.d.mts +4 -4
- package/dist/api/route-utils.mjs +46 -45
- 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-CXwQkV_m.mjs +5122 -0
- package/dist/api-CXwQkV_m.mjs.map +1 -0
- package/dist/api-tokens-89WlohEN.mjs +166 -0
- package/dist/api-tokens-89WlohEN.mjs.map +1 -0
- package/dist/apply-Do3KNnUk.mjs +1659 -0
- package/dist/apply-Do3KNnUk.mjs.map +1 -0
- package/dist/approvals-CAX9Yw33.mjs +460 -0
- package/dist/approvals-CAX9Yw33.mjs.map +1 -0
- package/dist/artifact-fetch-B9W4CEST.mjs +659 -0
- package/dist/artifact-fetch-B9W4CEST.mjs.map +1 -0
- package/dist/astro/index.d.mts +14 -14
- package/dist/astro/index.mjs +26 -30
- package/dist/astro/index.mjs.map +1 -1
- package/dist/astro/middleware/auth.d.mts +12 -12
- package/dist/astro/middleware/auth.mjs +10 -10
- package/dist/astro/middleware/media-usage-write-fence.mjs +5 -5
- package/dist/astro/middleware/redirect.mjs +7 -7
- package/dist/astro/middleware/request-context.mjs +3 -3
- 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 +110 -106
- package/dist/astro/middleware.mjs.map +1 -1
- package/dist/astro/routes/api/admin/allowed-domains/_domain_.mjs +14 -14
- package/dist/astro/routes/api/admin/allowed-domains/index.mjs +14 -14
- package/dist/astro/routes/api/admin/api-tokens/_id_.mjs +6 -6
- package/dist/astro/routes/api/admin/api-tokens/index.mjs +7 -7
- 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 +23 -23
- package/dist/astro/routes/api/admin/bylines/_id_/translations.mjs +23 -23
- package/dist/astro/routes/api/admin/bylines/index.mjs +23 -23
- package/dist/astro/routes/api/admin/comments/_id_/status.mjs +18 -18
- package/dist/astro/routes/api/admin/comments/_id_.mjs +7 -7
- package/dist/astro/routes/api/admin/comments/bulk.mjs +17 -17
- package/dist/astro/routes/api/admin/comments/counts.mjs +7 -7
- package/dist/astro/routes/api/admin/comments/index.mjs +17 -17
- package/dist/astro/routes/api/admin/hooks/exclusive/_hookName_.mjs +6 -6
- package/dist/astro/routes/api/admin/hooks/exclusive/index.mjs +5 -5
- package/dist/astro/routes/api/admin/media-usage/activation.mjs +20 -20
- 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 +25 -25
- package/dist/astro/routes/api/admin/media-usage/repair.mjs +31 -31
- 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 +6 -6
- package/dist/astro/routes/api/admin/oauth-clients/index.mjs +6 -6
- package/dist/astro/routes/api/admin/plugins/_id_/disable.mjs +8 -8
- package/dist/astro/routes/api/admin/plugins/_id_/enable.mjs +8 -8
- package/dist/astro/routes/api/admin/plugins/_id_/index.mjs +72 -68
- package/dist/astro/routes/api/admin/plugins/_id_/index.mjs.map +1 -1
- package/dist/astro/routes/api/admin/plugins/_id_/mcp.mjs +7 -7
- package/dist/astro/routes/api/admin/plugins/_id_/settings.mjs +71 -67
- package/dist/astro/routes/api/admin/plugins/_id_/settings.mjs.map +1 -1
- package/dist/astro/routes/api/admin/plugins/_id_/uninstall.mjs +72 -68
- package/dist/astro/routes/api/admin/plugins/_id_/uninstall.mjs.map +1 -1
- package/dist/astro/routes/api/admin/plugins/_id_/update.mjs +82 -78
- package/dist/astro/routes/api/admin/plugins/_id_/update.mjs.map +1 -1
- package/dist/astro/routes/api/admin/plugins/index.mjs +72 -68
- package/dist/astro/routes/api/admin/plugins/index.mjs.map +1 -1
- package/dist/astro/routes/api/admin/plugins/marketplace/_id_/icon.mjs +5 -5
- package/dist/astro/routes/api/admin/plugins/marketplace/_id_/index.mjs +71 -67
- 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 +81 -77
- package/dist/astro/routes/api/admin/plugins/marketplace/_id_/install.mjs.map +1 -1
- package/dist/astro/routes/api/admin/plugins/marketplace/index.mjs +71 -67
- package/dist/astro/routes/api/admin/plugins/marketplace/index.mjs.map +1 -1
- package/dist/astro/routes/api/admin/plugins/registry/_id_/uninstall.mjs +72 -68
- 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 +83 -79
- package/dist/astro/routes/api/admin/plugins/registry/_id_/update.mjs.map +1 -1
- package/dist/astro/routes/api/admin/plugins/registry/artifact.mjs +9 -9
- package/dist/astro/routes/api/admin/plugins/registry/install.mjs +74 -70
- package/dist/astro/routes/api/admin/plugins/registry/install.mjs.map +1 -1
- package/dist/astro/routes/api/admin/plugins/registry/publisher-handle.mjs +7 -7
- package/dist/astro/routes/api/admin/plugins/registry/verify.mjs +72 -68
- package/dist/astro/routes/api/admin/plugins/registry/verify.mjs.map +1 -1
- package/dist/astro/routes/api/admin/plugins/updates.mjs +71 -67
- 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 +71 -67
- 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 +5 -5
- package/dist/astro/routes/api/admin/themes/marketplace/index.mjs +71 -67
- package/dist/astro/routes/api/admin/themes/marketplace/index.mjs.map +1 -1
- package/dist/astro/routes/api/admin/transfer/_...path_.mjs +4 -4
- package/dist/astro/routes/api/admin/transfer/approvals/_id_/approve.mjs +40 -40
- package/dist/astro/routes/api/admin/transfer/approvals/_id_/deny.mjs +40 -40
- package/dist/astro/routes/api/admin/transfer/approvals/index.mjs +42 -42
- package/dist/astro/routes/api/admin/transfer/capabilities.mjs +42 -42
- package/dist/astro/routes/api/admin/transfer/exports/_id_/advance.mjs +42 -42
- package/dist/astro/routes/api/admin/transfer/exports/_id_/archive.mjs +43 -43
- package/dist/astro/routes/api/admin/transfer/exports/_id_/files/_...path_.mjs +43 -43
- package/dist/astro/routes/api/admin/transfer/exports/_id_/index.mjs +42 -42
- package/dist/astro/routes/api/admin/transfer/exports/_id_/manifest.mjs +43 -43
- package/dist/astro/routes/api/admin/transfer/exports/index.mjs +44 -44
- package/dist/astro/routes/api/admin/transfer/imports/_id_/abandon.mjs +42 -42
- package/dist/astro/routes/api/admin/transfer/imports/_id_/advance.mjs +42 -42
- package/dist/astro/routes/api/admin/transfer/imports/_id_/analyze.mjs +44 -44
- package/dist/astro/routes/api/admin/transfer/imports/_id_/cancel.mjs +42 -42
- package/dist/astro/routes/api/admin/transfer/imports/_id_/execute.mjs +44 -44
- package/dist/astro/routes/api/admin/transfer/imports/_id_/files/_...path_.mjs +42 -42
- package/dist/astro/routes/api/admin/transfer/imports/_id_/index.mjs +42 -42
- package/dist/astro/routes/api/admin/transfer/imports/_id_/missing.mjs +44 -44
- package/dist/astro/routes/api/admin/transfer/imports/_id_/plan.mjs +42 -42
- package/dist/astro/routes/api/admin/transfer/imports/_id_/receipt.mjs +42 -42
- package/dist/astro/routes/api/admin/transfer/imports/index.mjs +44 -44
- package/dist/astro/routes/api/admin/users/_id_/disable.mjs +5 -5
- package/dist/astro/routes/api/admin/users/_id_/enable.mjs +4 -4
- package/dist/astro/routes/api/admin/users/_id_/index.mjs +15 -15
- package/dist/astro/routes/api/admin/users/_id_/send-recovery.mjs +6 -6
- package/dist/astro/routes/api/admin/users/index.mjs +14 -14
- package/dist/astro/routes/api/auth/dev-bypass.mjs +6 -6
- package/dist/astro/routes/api/auth/invite/accept.mjs +4 -4
- package/dist/astro/routes/api/auth/invite/complete.mjs +18 -18
- package/dist/astro/routes/api/auth/invite/index.mjs +16 -16
- package/dist/astro/routes/api/auth/invite/register-options.mjs +17 -17
- package/dist/astro/routes/api/auth/logout.mjs +5 -5
- package/dist/astro/routes/api/auth/magic-link/send.mjs +18 -18
- package/dist/astro/routes/api/auth/magic-link/verify.mjs +14 -14
- package/dist/astro/routes/api/auth/me.mjs +15 -15
- package/dist/astro/routes/api/auth/mode.mjs +5 -5
- package/dist/astro/routes/api/auth/oauth/_provider_/callback.mjs +3 -3
- package/dist/astro/routes/api/auth/oauth/_provider_.mjs +2 -2
- package/dist/astro/routes/api/auth/passkey/_id_.mjs +14 -14
- package/dist/astro/routes/api/auth/passkey/index.mjs +4 -4
- package/dist/astro/routes/api/auth/passkey/options.mjs +19 -19
- package/dist/astro/routes/api/auth/passkey/register/options.mjs +17 -17
- package/dist/astro/routes/api/auth/passkey/register/verify.mjs +18 -18
- package/dist/astro/routes/api/auth/passkey/verify.mjs +18 -18
- package/dist/astro/routes/api/auth/signup/complete.mjs +18 -18
- package/dist/astro/routes/api/auth/signup/request.mjs +17 -17
- package/dist/astro/routes/api/auth/signup/verify.mjs +4 -4
- package/dist/astro/routes/api/comments/_collection_/_contentId_/index.mjs +12 -12
- package/dist/astro/routes/api/comments/_collection_/_contentId_/reactions.mjs +18 -18
- package/dist/astro/routes/api/content/_collection_/_id_/compare.mjs +5 -5
- package/dist/astro/routes/api/content/_collection_/_id_/discard-draft.mjs +17 -17
- package/dist/astro/routes/api/content/_collection_/_id_/duplicate.mjs +5 -5
- package/dist/astro/routes/api/content/_collection_/_id_/lock.mjs +17 -17
- package/dist/astro/routes/api/content/_collection_/_id_/permanent.mjs +5 -5
- package/dist/astro/routes/api/content/_collection_/_id_/plugin-extensions/_pluginId_/_kind_/_extensionId_.mjs +11 -11
- 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.d.mts +1 -2
- package/dist/astro/routes/api/content/_collection_/_id_/references/_relation_/children.d.mts.map +1 -1
- package/dist/astro/routes/api/content/_collection_/_id_/references/_relation_/children.mjs +42 -53
- package/dist/astro/routes/api/content/_collection_/_id_/references/_relation_/children.mjs.map +1 -1
- package/dist/astro/routes/api/content/_collection_/_id_/references/_relation_/parents.mjs +34 -29
- package/dist/astro/routes/api/content/_collection_/_id_/references/_relation_/parents.mjs.map +1 -1
- package/dist/astro/routes/api/content/_collection_/_id_/restore.mjs +5 -5
- package/dist/astro/routes/api/content/_collection_/_id_/revisions.mjs +5 -5
- package/dist/astro/routes/api/content/_collection_/_id_/schedule.mjs +17 -17
- package/dist/astro/routes/api/content/_collection_/_id_/terms/_taxonomy_.mjs +25 -24
- package/dist/astro/routes/api/content/_collection_/_id_/terms/_taxonomy_.mjs.map +1 -1
- package/dist/astro/routes/api/content/_collection_/_id_/translations.mjs +5 -5
- package/dist/astro/routes/api/content/_collection_/_id_/unpublish.mjs +17 -17
- package/dist/astro/routes/api/content/_collection_/_id_.d.mts.map +1 -1
- package/dist/astro/routes/api/content/_collection_/_id_.mjs +18 -18
- package/dist/astro/routes/api/content/_collection_/_id_.mjs.map +1 -1
- package/dist/astro/routes/api/content/_collection_/authors.mjs +5 -5
- package/dist/astro/routes/api/content/_collection_/index.mjs +15 -15
- package/dist/astro/routes/api/content/_collection_/trash.mjs +15 -15
- package/dist/astro/routes/api/dashboard.mjs +10 -9
- package/dist/astro/routes/api/dashboard.mjs.map +1 -1
- package/dist/astro/routes/api/dev/emails.mjs +5 -5
- package/dist/astro/routes/api/health.mjs +6 -6
- package/dist/astro/routes/api/import/probe.d.mts +3 -3
- package/dist/astro/routes/api/import/probe.mjs +23 -23
- 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 +16 -16
- package/dist/astro/routes/api/import/wordpress/media.d.mts +12 -12
- package/dist/astro/routes/api/import/wordpress/media.mjs +19 -19
- 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 +28 -28
- package/dist/astro/routes/api/import/wordpress-plugin/analyze.d.mts +1 -1
- package/dist/astro/routes/api/import/wordpress-plugin/analyze.mjs +23 -23
- package/dist/astro/routes/api/import/wordpress-plugin/execute.d.mts +13 -13
- package/dist/astro/routes/api/import/wordpress-plugin/execute.mjs +34 -34
- package/dist/astro/routes/api/manifest.mjs +6 -6
- package/dist/astro/routes/api/mcp.mjs +98 -118
- 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 +16 -16
- package/dist/astro/routes/api/media/_id_/upload.mjs +9 -9
- package/dist/astro/routes/api/media/_id_/usage.mjs +33 -33
- package/dist/astro/routes/api/media/_id_.mjs +31 -31
- package/dist/astro/routes/api/media/asset/_id_/_filename_.mjs +6 -6
- package/dist/astro/routes/api/media/file/_...key_.mjs +9 -9
- package/dist/astro/routes/api/media/folders/_id_.mjs +16 -16
- package/dist/astro/routes/api/media/folders/index.mjs +16 -16
- package/dist/astro/routes/api/media/providers/_providerId_/_itemId_.mjs +5 -5
- package/dist/astro/routes/api/media/providers/_providerId_/index.mjs +5 -5
- package/dist/astro/routes/api/media/providers/index.mjs +5 -5
- package/dist/astro/routes/api/media/upload-url.mjs +18 -18
- package/dist/astro/routes/api/media.mjs +35 -35
- package/dist/astro/routes/api/menus/_name_/items/_id_.mjs +17 -17
- package/dist/astro/routes/api/menus/_name_/items.mjs +17 -17
- package/dist/astro/routes/api/menus/_name_/reorder.mjs +17 -17
- package/dist/astro/routes/api/menus/_name_/translations.mjs +17 -17
- package/dist/astro/routes/api/menus/_name_.mjs +17 -17
- package/dist/astro/routes/api/menus/index.mjs +17 -17
- package/dist/astro/routes/api/oauth/authorize.mjs +6 -6
- package/dist/astro/routes/api/oauth/device/authorize.d.mts +2 -1
- package/dist/astro/routes/api/oauth/device/authorize.d.mts.map +1 -1
- package/dist/astro/routes/api/oauth/device/authorize.mjs +23 -9
- package/dist/astro/routes/api/oauth/device/authorize.mjs.map +1 -1
- package/dist/astro/routes/api/oauth/device/code.mjs +11 -11
- package/dist/astro/routes/api/oauth/device/token.mjs +10 -10
- package/dist/astro/routes/api/oauth/register.mjs +5 -5
- package/dist/astro/routes/api/oauth/token/refresh.mjs +8 -8
- package/dist/astro/routes/api/oauth/token/revoke.mjs +8 -8
- package/dist/astro/routes/api/oauth/token.mjs +8 -8
- package/dist/astro/routes/api/openapi.json.mjs +20 -20
- package/dist/astro/routes/api/plugins/_pluginId_/_...path_.mjs +11 -11
- package/dist/astro/routes/api/redirects/404s/index.mjs +19 -19
- package/dist/astro/routes/api/redirects/404s/summary.mjs +19 -19
- package/dist/astro/routes/api/redirects/_id_.mjs +19 -19
- package/dist/astro/routes/api/redirects/index.mjs +19 -19
- package/dist/astro/routes/api/relations/_id_/index.mjs +34 -29
- package/dist/astro/routes/api/relations/_id_/index.mjs.map +1 -1
- package/dist/astro/routes/api/relations/index.mjs +36 -31
- package/dist/astro/routes/api/relations/index.mjs.map +1 -1
- package/dist/astro/routes/api/revisions/_revisionId_/index.mjs +5 -5
- package/dist/astro/routes/api/revisions/_revisionId_/restore.mjs +5 -5
- package/dist/astro/routes/api/schema/block-types/_slug_/index.mjs +71 -67
- 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 +71 -67
- 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 +71 -67
- package/dist/astro/routes/api/schema/block-types/index.mjs.map +1 -1
- package/dist/astro/routes/api/schema/collections/_slug_/fields/_fieldSlug_.mjs +73 -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 +71 -67
- 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 +71 -67
- package/dist/astro/routes/api/schema/collections/_slug_/fields/reorder.mjs.map +1 -1
- package/dist/astro/routes/api/schema/collections/_slug_/index.mjs +71 -67
- package/dist/astro/routes/api/schema/collections/_slug_/index.mjs.map +1 -1
- package/dist/astro/routes/api/schema/collections/index.mjs +71 -67
- package/dist/astro/routes/api/schema/collections/index.mjs.map +1 -1
- package/dist/astro/routes/api/schema/collections/reorder.mjs +71 -67
- 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 +71 -67
- package/dist/astro/routes/api/schema/orphans/_slug_.mjs.map +1 -1
- package/dist/astro/routes/api/schema/orphans/index.mjs +71 -67
- 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 +7 -7
- package/dist/astro/routes/api/settings/backups/archives/index.mjs +7 -7
- package/dist/astro/routes/api/settings/backups/export.mjs +7 -7
- package/dist/astro/routes/api/settings/backups/index.mjs +8 -8
- package/dist/astro/routes/api/settings/email.mjs +6 -6
- package/dist/astro/routes/api/settings.mjs +21 -21
- package/dist/astro/routes/api/setup/admin-verify.mjs +19 -19
- package/dist/astro/routes/api/setup/admin.mjs +18 -18
- package/dist/astro/routes/api/setup/dev-bypass.mjs +45 -39
- package/dist/astro/routes/api/setup/dev-bypass.mjs.map +1 -1
- package/dist/astro/routes/api/setup/dev-reset.mjs +4 -4
- package/dist/astro/routes/api/setup/index.d.mts.map +1 -1
- package/dist/astro/routes/api/setup/index.mjs +80 -49
- package/dist/astro/routes/api/setup/index.mjs.map +1 -1
- package/dist/astro/routes/api/setup/status.mjs +6 -6
- package/dist/astro/routes/api/snapshot.mjs +9 -9
- package/dist/astro/routes/api/snapshot.mjs.map +1 -1
- package/dist/astro/routes/api/taxonomies/_name_/reorder.mjs +23 -23
- package/dist/astro/routes/api/taxonomies/_name_/terms/_slug_/translations.mjs +23 -23
- package/dist/astro/routes/api/taxonomies/_name_/terms/_slug_.mjs +23 -23
- package/dist/astro/routes/api/taxonomies/_name_/terms/index.mjs +23 -23
- package/dist/astro/routes/api/taxonomies/_name_/translations.mjs +22 -22
- package/dist/astro/routes/api/taxonomies/_name_.mjs +23 -23
- package/dist/astro/routes/api/taxonomies/bulk-tag.mjs +36 -35
- package/dist/astro/routes/api/taxonomies/bulk-tag.mjs.map +1 -1
- package/dist/astro/routes/api/taxonomies/index.mjs +23 -23
- package/dist/astro/routes/api/themes/preview.mjs +6 -6
- package/dist/astro/routes/api/typegen.mjs +8 -8
- package/dist/astro/routes/api/visual-editing/action-token.mjs +6 -6
- package/dist/astro/routes/api/visual-editing/content/_collection_/_id_/publish.mjs +19 -19
- package/dist/astro/routes/api/visual-editing/toolbar-labels.mjs +4 -4
- 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 +16 -16
- 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 +5 -5
- package/dist/astro/routes/robots.txt.mjs +6 -6
- package/dist/astro/routes/sitemap-_collection_.xml.mjs +9 -9
- package/dist/astro/routes/sitemap.xml.mjs +7 -7
- package/dist/astro/types.d.mts +28 -18
- package/dist/astro/types.d.mts.map +1 -1
- package/dist/audit-CrgmE9LE.mjs +127 -0
- package/dist/audit-CrgmE9LE.mjs.map +1 -0
- package/dist/auth/providers/github.d.mts +1 -1
- package/dist/auth/providers/google.d.mts +1 -1
- package/dist/authoritative-records-C2YzIdbu.mjs +5172 -0
- package/dist/authoritative-records-C2YzIdbu.mjs.map +1 -0
- package/dist/authorize-WgdKF8QY.mjs +49 -0
- package/dist/authorize-WgdKF8QY.mjs.map +1 -0
- package/dist/backup-Ck8_lMO3.mjs +246 -0
- package/dist/backup-Ck8_lMO3.mjs.map +1 -0
- package/dist/block-types-BQ90asVI.mjs +132 -0
- package/dist/block-types-BQ90asVI.mjs.map +1 -0
- package/dist/block-values-ACFqgB1D.mjs +175 -0
- package/dist/block-values-ACFqgB1D.mjs.map +1 -0
- package/dist/bundle-Db1iNMv_.mjs +667 -0
- package/dist/bundle-Db1iNMv_.mjs.map +1 -0
- package/dist/byline-BayaYGoj.mjs +909 -0
- package/dist/byline-BayaYGoj.mjs.map +1 -0
- package/dist/byline-fields-B8HH-35f.mjs +254 -0
- package/dist/byline-fields-B8HH-35f.mjs.map +1 -0
- package/dist/byline-fields-hMPjf6Eu.mjs +123 -0
- package/dist/byline-fields-hMPjf6Eu.mjs.map +1 -0
- package/dist/byline-registry-B_EK_TQf.mjs +406 -0
- package/dist/byline-registry-B_EK_TQf.mjs.map +1 -0
- package/dist/bylines-DFAaFXWi.mjs +214 -0
- package/dist/bylines-DFAaFXWi.mjs.map +1 -0
- package/dist/bylines-DkIxUxmr.mjs +232 -0
- package/dist/bylines-DkIxUxmr.mjs.map +1 -0
- package/dist/cache-DkvhQ8XE.mjs +108 -0
- package/dist/cache-DkvhQ8XE.mjs.map +1 -0
- package/dist/canonical-CcSuuTlH.mjs +174 -0
- package/dist/canonical-CcSuuTlH.mjs.map +1 -0
- package/dist/capture-triggers-DJEoOTOq.mjs +362 -0
- package/dist/capture-triggers-DJEoOTOq.mjs.map +1 -0
- package/dist/challenge-store-CvBl81AQ.mjs +51 -0
- package/dist/challenge-store-CvBl81AQ.mjs.map +1 -0
- package/dist/checksum-CClweQzI.mjs +162 -0
- package/dist/checksum-CClweQzI.mjs.map +1 -0
- package/dist/chrome-tags-D5caJwwp.mjs +24 -0
- package/dist/chrome-tags-D5caJwwp.mjs.map +1 -0
- package/dist/chunks-DwBaj8aT.mjs +25 -0
- package/dist/chunks-DwBaj8aT.mjs.map +1 -0
- package/dist/cli/index.mjs +374 -761
- package/dist/cli/index.mjs.map +1 -1
- package/dist/client/cf-access.d.mts +1 -1
- package/dist/client/index.d.mts +18 -18
- package/dist/client/index.mjs +2 -2
- package/dist/collection-deletion-CLCdXsnV.mjs +436 -0
- package/dist/collection-deletion-CLCdXsnV.mjs.map +1 -0
- package/dist/collection-deletion-processor-hNw8x01F.mjs +217 -0
- package/dist/collection-deletion-processor-hNw8x01F.mjs.map +1 -0
- package/dist/collection-slugs-cache-CUuiduLq.mjs +85 -0
- package/dist/collection-slugs-cache-CUuiduLq.mjs.map +1 -0
- package/dist/comment-D2uvL63j.mjs +313 -0
- package/dist/comment-D2uvL63j.mjs.map +1 -0
- package/dist/comment-reaction-DevUuzg4.mjs +85 -0
- package/dist/comment-reaction-DevUuzg4.mjs.map +1 -0
- package/dist/comments-Cq0s7_hO.mjs +195 -0
- package/dist/comments-Cq0s7_hO.mjs.map +1 -0
- package/dist/comments-M4EDYAHw.mjs +99 -0
- package/dist/comments-M4EDYAHw.mjs.map +1 -0
- package/dist/components-CuIGwXMs.mjs +108 -0
- package/dist/components-CuIGwXMs.mjs.map +1 -0
- package/dist/config-52Ea5IWt.d.mts +39 -0
- package/dist/config-52Ea5IWt.d.mts.map +1 -0
- package/dist/config-CCz3xOLc.mjs +242 -0
- package/dist/config-CCz3xOLc.mjs.map +1 -0
- package/dist/config-D3d5Qudq.d.mts +6669 -0
- package/dist/config-D3d5Qudq.d.mts.map +1 -0
- package/dist/content-CbnufDsM.mjs +2018 -0
- package/dist/content-CbnufDsM.mjs.map +1 -0
- package/dist/content-list-query-D_7B1FE5.d.mts +26 -0
- package/dist/content-list-query-D_7B1FE5.d.mts.map +1 -0
- package/dist/content-policy-CYu6K1KB.mjs +46 -0
- package/dist/content-policy-CYu6K1KB.mjs.map +1 -0
- package/dist/content-repair-DlDUgFGp.mjs +442 -0
- package/dist/content-repair-DlDUgFGp.mjs.map +1 -0
- package/dist/context-CGQLA1-a.mjs +1922 -0
- package/dist/context-CGQLA1-a.mjs.map +1 -0
- package/dist/cron-c4D5C5Fx.mjs +284 -0
- package/dist/cron-c4D5C5Fx.mjs.map +1 -0
- package/dist/dashboard-CBq9kmOn.mjs +151 -0
- package/dist/dashboard-CBq9kmOn.mjs.map +1 -0
- package/dist/db/index.d.mts +3 -3
- package/dist/db/index.mjs +1 -1
- package/dist/db/libsql-migrations.d.mts +1 -1
- package/dist/db/libsql-migrations.mjs +4 -4
- package/dist/db/libsql.d.mts +1 -1
- package/dist/db/postgres-migrations.d.mts +1 -1
- package/dist/db/postgres-migrations.mjs +4 -4
- package/dist/db/postgres.d.mts +1 -1
- package/dist/db/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-DPsys51U.mjs +81 -0
- package/dist/default-DPsys51U.mjs.map +1 -0
- package/dist/deferred-tasks-CZ7rzBdo.d.mts +9 -0
- package/dist/deferred-tasks-CZ7rzBdo.d.mts.map +1 -0
- package/dist/dev-typegen-HRxwLRcT.mjs +29 -0
- package/dist/dev-typegen-HRxwLRcT.mjs.map +1 -0
- package/dist/device-flow-OcSqE9uY.mjs +521 -0
- package/dist/device-flow-OcSqE9uY.mjs.map +1 -0
- package/dist/digest-DVZ--cE9.mjs +194 -0
- package/dist/digest-DVZ--cE9.mjs.map +1 -0
- package/dist/direct-executor-DyjAqkpT.mjs +104 -0
- package/dist/direct-executor-DyjAqkpT.mjs.map +1 -0
- package/dist/dist-FPR93_xf.mjs +810 -0
- package/dist/dist-FPR93_xf.mjs.map +1 -0
- package/dist/email-console-DyQIgEnz.mjs +50 -0
- package/dist/email-console-DyQIgEnz.mjs.map +1 -0
- package/dist/email-locale-BYb16rVd.mjs +25 -0
- package/dist/email-locale-BYb16rVd.mjs.map +1 -0
- package/dist/emdash-runtime-CrzxJFmF.mjs +4214 -0
- package/dist/emdash-runtime-CrzxJFmF.mjs.map +1 -0
- package/dist/enrich-DBtCncE2.mjs +194 -0
- package/dist/enrich-DBtCncE2.mjs.map +1 -0
- package/dist/entry-lock-BN5y4YbO.d.mts +4481 -0
- package/dist/entry-lock-BN5y4YbO.d.mts.map +1 -0
- package/dist/entry-lock-BaRBHCsH.mjs +1173 -0
- package/dist/entry-lock-BaRBHCsH.mjs.map +1 -0
- package/dist/entry-lock-C6NcnZPV.mjs +163 -0
- package/dist/entry-lock-C6NcnZPV.mjs.map +1 -0
- package/dist/entry-locks-BTyQLdbC.mjs +167 -0
- package/dist/entry-locks-BTyQLdbC.mjs.map +1 -0
- package/dist/error-BfsNNrIE.mjs +90 -0
- package/dist/error-BfsNNrIE.mjs.map +1 -0
- package/dist/errors-BN1QAnEY.mjs +460 -0
- package/dist/errors-BN1QAnEY.mjs.map +1 -0
- package/dist/errors-Bt3goF8I.mjs +120 -0
- package/dist/errors-Bt3goF8I.mjs.map +1 -0
- package/dist/escape-BveidMa2.mjs +9 -0
- package/dist/escape-BveidMa2.mjs.map +1 -0
- package/dist/fence-Bb_IbCxI.mjs +162 -0
- package/dist/fence-Bb_IbCxI.mjs.map +1 -0
- package/dist/field-defs-cache-CsZctvbu.mjs +77 -0
- package/dist/field-defs-cache-CsZctvbu.mjs.map +1 -0
- package/dist/field-map-6m9rF49t.mjs +83 -0
- package/dist/field-map-6m9rF49t.mjs.map +1 -0
- package/dist/focal-point-CZ3d1wK5.mjs +23 -0
- package/dist/focal-point-CZ3d1wK5.mjs.map +1 -0
- package/dist/fts-manager-CCaZTp8y.mjs +443 -0
- package/dist/fts-manager-CCaZTp8y.mjs.map +1 -0
- package/dist/gc-xowRjczI.mjs +75 -0
- package/dist/gc-xowRjczI.mjs.map +1 -0
- package/dist/hash-COVK27Pc.mjs +37 -0
- package/dist/hash-COVK27Pc.mjs.map +1 -0
- package/dist/hook-result-CYSk0XFe.d.mts +31 -0
- package/dist/hook-result-CYSk0XFe.d.mts.map +1 -0
- package/dist/hreflang-CChPV7jx.mjs +105 -0
- package/dist/hreflang-CChPV7jx.mjs.map +1 -0
- package/dist/hreflang-DRslq3QI.d.mts +50 -0
- package/dist/hreflang-DRslq3QI.d.mts.map +1 -0
- package/dist/http-route-dispatch-CAdp2onn.mjs +339 -0
- package/dist/http-route-dispatch-CAdp2onn.mjs.map +1 -0
- package/dist/identity-NVTOOQyq.mjs +35 -0
- package/dist/identity-NVTOOQyq.mjs.map +1 -0
- package/dist/import-wpSO2N0x.mjs +2020 -0
- package/dist/import-wpSO2N0x.mjs.map +1 -0
- package/dist/index-CDs2wq4X.d.mts +623 -0
- package/dist/index-CDs2wq4X.d.mts.map +1 -0
- package/dist/index.d.mts +24 -24
- package/dist/index.mjs +103 -101
- package/dist/install-finalization-D9R9R-W8.mjs +58 -0
- package/dist/install-finalization-D9R9R-W8.mjs.map +1 -0
- package/dist/keys-Bck6LBfF.mjs +61 -0
- package/dist/keys-Bck6LBfF.mjs.map +1 -0
- package/dist/kinds-CYmRESWj.mjs +974 -0
- package/dist/kinds-CYmRESWj.mjs.map +1 -0
- package/dist/lifecycle-C815ZQfV.mjs +25 -0
- package/dist/lifecycle-C815ZQfV.mjs.map +1 -0
- package/dist/load-D99axixL.mjs +28 -0
- package/dist/load-D99axixL.mjs.map +1 -0
- package/dist/loader-CrRPfkHS.mjs +1197 -0
- package/dist/loader-CrRPfkHS.mjs.map +1 -0
- package/dist/loops-DMKlygqX.mjs +203 -0
- package/dist/loops-DMKlygqX.mjs.map +1 -0
- package/dist/manifest-builder-BQzCHNgB.mjs +189 -0
- package/dist/manifest-builder-BQzCHNgB.mjs.map +1 -0
- package/dist/manifest-schema-Ci2gmd0u.mjs +492 -0
- package/dist/manifest-schema-Ci2gmd0u.mjs.map +1 -0
- package/dist/media/image-endpoint.mjs +1 -1
- package/dist/media/index.d.mts +1 -1
- package/dist/media/index.mjs +4 -4
- package/dist/media/local-runtime.d.mts +14 -14
- package/dist/media/local-runtime.mjs +6 -6
- package/dist/media-BUQePMxP.mjs +373 -0
- package/dist/media-BUQePMxP.mjs.map +1 -0
- package/dist/media-DH8ibNlY.mjs +294 -0
- package/dist/media-DH8ibNlY.mjs.map +1 -0
- package/dist/media-OEIQ3bVc.mjs +408 -0
- package/dist/media-OEIQ3bVc.mjs.map +1 -0
- package/dist/media-allowlist-pYtaBA95.mjs +44 -0
- package/dist/media-allowlist-pYtaBA95.mjs.map +1 -0
- package/dist/media-folders-Bf8_s4de.mjs +210 -0
- package/dist/media-folders-Bf8_s4de.mjs.map +1 -0
- package/dist/media-url-C6klEuNd.mjs +43 -0
- package/dist/media-url-C6klEuNd.mjs.map +1 -0
- package/dist/media-usage-D7Y64m6v.mjs +1629 -0
- package/dist/media-usage-D7Y64m6v.mjs.map +1 -0
- package/dist/media-usage-activation-DrqbmgLA.mjs +78 -0
- package/dist/media-usage-activation-DrqbmgLA.mjs.map +1 -0
- package/dist/media-usage-work-DommYhYA.mjs +152 -0
- package/dist/media-usage-work-DommYhYA.mjs.map +1 -0
- package/dist/media-usage-work-HU63hNDu.mjs +586 -0
- package/dist/media-usage-work-HU63hNDu.mjs.map +1 -0
- package/dist/menus-BQfusWEC.mjs +3608 -0
- package/dist/menus-BQfusWEC.mjs.map +1 -0
- package/dist/menus-BtwjQt5s.mjs +753 -0
- package/dist/menus-BtwjQt5s.mjs.map +1 -0
- package/dist/menus-p_M1V7J_.mjs +139 -0
- package/dist/menus-p_M1V7J_.mjs.map +1 -0
- package/dist/migrations/index.d.mts +1 -1
- package/dist/migrations/index.mjs +3 -3
- package/dist/mime-C94qBG-P.mjs +36 -0
- package/dist/mime-C94qBG-P.mjs.map +1 -0
- package/dist/mode-DpYW3w6U.mjs +23 -0
- package/dist/mode-DpYW3w6U.mjs.map +1 -0
- package/dist/node-sqlite-compat-pWFw0lcc.mjs +46 -0
- package/dist/node-sqlite-compat-pWFw0lcc.mjs.map +1 -0
- package/dist/normalize-DduyxBjf.mjs +191 -0
- package/dist/normalize-DduyxBjf.mjs.map +1 -0
- package/dist/oauth-authorization-DAXsH1H9.mjs +274 -0
- package/dist/oauth-authorization-DAXsH1H9.mjs.map +1 -0
- package/dist/oauth-clients-DENiDQri.mjs +266 -0
- package/dist/oauth-clients-DENiDQri.mjs.map +1 -0
- package/dist/oauth-state-store-y8mEYVq9.mjs +50 -0
- package/dist/oauth-state-store-y8mEYVq9.mjs.map +1 -0
- package/dist/oauth-user-lookup-CtTYAy-O.mjs +26 -0
- package/dist/oauth-user-lookup-CtTYAy-O.mjs.map +1 -0
- package/dist/object-cache/memory.d.mts +1 -1
- package/dist/options-BYa1FgIM.d.mts +81 -0
- package/dist/options-BYa1FgIM.d.mts.map +1 -0
- package/dist/page/index.d.mts +2 -2
- package/dist/page/index.mjs +5 -5
- package/dist/parse-CORGGhHf.mjs +81 -0
- package/dist/parse-CORGGhHf.mjs.map +1 -0
- package/dist/parse-avNM1xWV.d.mts +168 -0
- package/dist/parse-avNM1xWV.d.mts.map +1 -0
- package/dist/passkey-config-Dih5YeIS.mjs +46 -0
- package/dist/passkey-config-Dih5YeIS.mjs.map +1 -0
- package/dist/paths-d51RFm8M.mjs +77 -0
- package/dist/paths-d51RFm8M.mjs.map +1 -0
- package/dist/patterns-CoqlXUvk.mjs +145 -0
- package/dist/patterns-CoqlXUvk.mjs.map +1 -0
- package/dist/placeholder-D2aksPMF.d.mts +306 -0
- package/dist/placeholder-D2aksPMF.d.mts.map +1 -0
- package/dist/plan-DqeZKuaR.mjs +135 -0
- package/dist/plan-DqeZKuaR.mjs.map +1 -0
- package/dist/plugin-test-runtime.d.mts +14 -14
- package/dist/plugin-test-runtime.mjs +110 -107
- 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 +42 -41
- package/dist/plugins-Bb7oqjQA.mjs +277 -0
- package/dist/plugins-Bb7oqjQA.mjs.map +1 -0
- package/dist/policy-BcEqut3n.mjs +45 -0
- package/dist/policy-BcEqut3n.mjs.map +1 -0
- package/dist/portable-text-DXE8ymtD.mjs +307 -0
- package/dist/portable-text-DXE8ymtD.mjs.map +1 -0
- package/dist/preview-DEDWbwA_.mjs +107 -0
- package/dist/preview-DEDWbwA_.mjs.map +1 -0
- package/dist/protocol-BJbTzvwl.d.mts +61 -0
- package/dist/protocol-BJbTzvwl.d.mts.map +1 -0
- package/dist/public-submission-D9c9S14m.mjs +250 -0
- package/dist/public-submission-D9c9S14m.mjs.map +1 -0
- package/dist/public-url-CIRe-2T6.mjs +101 -0
- package/dist/public-url-CIRe-2T6.mjs.map +1 -0
- package/dist/query-BzifXlPS.mjs +1156 -0
- package/dist/query-BzifXlPS.mjs.map +1 -0
- package/dist/query-OzMJ6vJP.mjs +41 -0
- package/dist/query-OzMJ6vJP.mjs.map +1 -0
- package/dist/rate-limit-Csp60Vik.mjs +120 -0
- package/dist/rate-limit-Csp60Vik.mjs.map +1 -0
- package/dist/receipt-B-aU4hpJ.mjs +43 -0
- package/dist/receipt-B-aU4hpJ.mjs.map +1 -0
- package/dist/redirect-CDSw1sU3.mjs +17 -0
- package/dist/redirect-CDSw1sU3.mjs.map +1 -0
- package/dist/redirect-D1ArbO85.mjs +411 -0
- package/dist/redirect-D1ArbO85.mjs.map +1 -0
- package/dist/redirects-BjTwDTsV.mjs +148 -0
- package/dist/redirects-BjTwDTsV.mjs.map +1 -0
- package/dist/redirects-Ck50kH3n.mjs +446 -0
- package/dist/redirects-Ck50kH3n.mjs.map +1 -0
- package/dist/registry/testing.mjs +3 -3
- package/dist/registry-CFcNCayZ.mjs +6754 -0
- package/dist/registry-CFcNCayZ.mjs.map +1 -0
- package/dist/relations-Cfaa1fDl.mjs +776 -0
- package/dist/relations-Cfaa1fDl.mjs.map +1 -0
- package/dist/request-cache-iHRlHx1d.mjs +104 -0
- package/dist/request-cache-iHRlHx1d.mjs.map +1 -0
- package/dist/request-context.d.mts +1 -1
- package/dist/request-meta-D47mqyev.mjs +141 -0
- package/dist/request-meta-D47mqyev.mjs.map +1 -0
- package/dist/resolve-BPE8sMvx.mjs +99 -0
- package/dist/resolve-BPE8sMvx.mjs.map +1 -0
- package/dist/resolve-C0s1E_fH.mjs +199 -0
- package/dist/resolve-C0s1E_fH.mjs.map +1 -0
- package/dist/revision-j1p4-bOj.mjs +302 -0
- package/dist/revision-j1p4-bOj.mjs.map +1 -0
- package/dist/route-wire-C9PJV9aL.mjs +197 -0
- package/dist/route-wire-C9PJV9aL.mjs.map +1 -0
- package/dist/routes-lyYw0mMf.mjs +272 -0
- package/dist/routes-lyYw0mMf.mjs.map +1 -0
- package/dist/runner-B3eyB9Gb.mjs +6121 -0
- package/dist/runner-B3eyB9Gb.mjs.map +1 -0
- package/dist/runner-DoYH2Jcu.d.mts +68 -0
- package/dist/runner-DoYH2Jcu.d.mts.map +1 -0
- package/dist/runtime.d.mts +13 -13
- package/dist/runtime.mjs +3 -3
- package/dist/schema-BAayK46S.mjs +13 -0
- package/dist/schema-BAayK46S.mjs.map +1 -0
- package/dist/schema-Gqcl-8G4.mjs +815 -0
- package/dist/schema-Gqcl-8G4.mjs.map +1 -0
- package/dist/scopes-BqPOKoKf.mjs +34 -0
- package/dist/scopes-BqPOKoKf.mjs.map +1 -0
- package/dist/search-YJKPIEV6.mjs +448 -0
- package/dist/search-YJKPIEV6.mjs.map +1 -0
- package/dist/sections-BR_e-wK5.mjs +346 -0
- package/dist/sections-BR_e-wK5.mjs.map +1 -0
- package/dist/seed/index.d.mts +2 -2
- package/dist/seed/index.mjs +37 -31
- package/dist/seo/index.d.mts +3 -3
- package/dist/seo/index.mjs +22 -21
- package/dist/seo/index.mjs.map +1 -1
- package/dist/seo-Dsj8hy3j.mjs +114 -0
- package/dist/seo-Dsj8hy3j.mjs.map +1 -0
- package/dist/seo-XvH4LNNp.mjs +133 -0
- package/dist/seo-XvH4LNNp.mjs.map +1 -0
- package/dist/service-BsVG05gS.mjs +150 -0
- package/dist/service-BsVG05gS.mjs.map +1 -0
- package/dist/session-user-DgKbYrlj.mjs +51 -0
- package/dist/session-user-DgKbYrlj.mjs.map +1 -0
- package/dist/settings-CNPUntkh.mjs +51 -0
- package/dist/settings-CNPUntkh.mjs.map +1 -0
- package/dist/settings-D5EHi0Tk.mjs +439 -0
- package/dist/settings-D5EHi0Tk.mjs.map +1 -0
- package/dist/settings-DSfE7wOa.mjs +61 -0
- package/dist/settings-DSfE7wOa.mjs.map +1 -0
- package/dist/setup-complete-B8W8sJ9v.mjs +26 -0
- package/dist/setup-complete-B8W8sJ9v.mjs.map +1 -0
- package/dist/setup-nonce-DnSBP260.mjs +25 -0
- package/dist/setup-nonce-DnSBP260.mjs.map +1 -0
- package/dist/site-settings-NGzdrt7O.mjs +50 -0
- package/dist/site-settings-NGzdrt7O.mjs.map +1 -0
- package/dist/site-url-D6JB7tLW.mjs +16 -0
- package/dist/site-url-D6JB7tLW.mjs.map +1 -0
- package/dist/snapshot-CdcwwWAf.mjs +414 -0
- package/dist/snapshot-CdcwwWAf.mjs.map +1 -0
- package/dist/ssrf-Dv0_tRpo.mjs +406 -0
- package/dist/ssrf-Dv0_tRpo.mjs.map +1 -0
- package/dist/stage-CUjhED3P.mjs +662 -0
- package/dist/stage-CUjhED3P.mjs.map +1 -0
- package/dist/staged-C36IWXff.mjs +659 -0
- package/dist/staged-C36IWXff.mjs.map +1 -0
- package/dist/state-CKouMCSY.mjs +153 -0
- package/dist/state-CKouMCSY.mjs.map +1 -0
- package/dist/status-lzyj4Uu7.mjs +30 -0
- package/dist/status-lzyj4Uu7.mjs.map +1 -0
- package/dist/storage/local.d.mts +1 -1
- package/dist/storage/local.mjs +1 -1
- package/dist/storage/s3.d.mts +1 -1
- package/dist/storage/s3.mjs +1 -1
- package/dist/storage-query-B-cWcTjJ.d.mts +1594 -0
- package/dist/storage-query-B-cWcTjJ.d.mts.map +1 -0
- package/dist/tar-DsTXX6ch.mjs +449 -0
- package/dist/tar-DsTXX6ch.mjs.map +1 -0
- package/dist/target-DLQCwp_Z.mjs +27 -0
- package/dist/target-DLQCwp_Z.mjs.map +1 -0
- package/dist/taxonomies-BlAjr4BL.mjs +697 -0
- package/dist/taxonomies-BlAjr4BL.mjs.map +1 -0
- package/dist/taxonomies-Byyo7LOZ.mjs +939 -0
- package/dist/taxonomies-Byyo7LOZ.mjs.map +1 -0
- package/dist/taxonomy-CKDwM61Y.mjs +525 -0
- package/dist/taxonomy-CKDwM61Y.mjs.map +1 -0
- package/dist/tokens-BojXlk49.mjs +171 -0
- package/dist/tokens-BojXlk49.mjs.map +1 -0
- package/dist/transaction-DLPQWik1.mjs +29 -0
- package/dist/transaction-DLPQWik1.mjs.map +1 -0
- package/dist/transfer-XSTh2BCr.mjs +8706 -0
- package/dist/transfer-XSTh2BCr.mjs.map +1 -0
- package/dist/transfer-download-DkoCDA9d.mjs +33 -0
- package/dist/transfer-download-DkoCDA9d.mjs.map +1 -0
- package/dist/transfer-iQ26J-RT.mjs +166 -0
- package/dist/transfer-iQ26J-RT.mjs.map +1 -0
- package/dist/transformations-C7RQabKQ.mjs +196 -0
- package/dist/transformations-C7RQabKQ.mjs.map +1 -0
- package/dist/transport-D3RulfD6.mjs +136 -0
- package/dist/transport-D3RulfD6.mjs.map +1 -0
- package/dist/transport-DhlZlf4D.d.mts +42 -0
- package/dist/transport-DhlZlf4D.d.mts.map +1 -0
- package/dist/trusted-proxy-B6ECOZJc.mjs +51 -0
- package/dist/trusted-proxy-B6ECOZJc.mjs.map +1 -0
- package/dist/turnstile-lqUiY7lP.mjs +53 -0
- package/dist/turnstile-lqUiY7lP.mjs.map +1 -0
- package/dist/types-4Dn9bZhu.mjs +77 -0
- package/dist/types-4Dn9bZhu.mjs.map +1 -0
- package/dist/types-5LSo7PPx.d.mts +85 -0
- package/dist/types-5LSo7PPx.d.mts.map +1 -0
- package/dist/types-BQ3hwYJT.d.mts +896 -0
- package/dist/types-BQ3hwYJT.d.mts.map +1 -0
- package/dist/types-BYEk7qo3.d.mts +198 -0
- package/dist/types-BYEk7qo3.d.mts.map +1 -0
- package/dist/types-CJKsWVFR.mjs +199 -0
- package/dist/types-CJKsWVFR.mjs.map +1 -0
- package/dist/types-Ca_w8mmY.d.mts +363 -0
- package/dist/types-Ca_w8mmY.d.mts.map +1 -0
- package/dist/types-CkE41ZAG.mjs +18 -0
- package/dist/types-CkE41ZAG.mjs.map +1 -0
- package/dist/types-D0aJW2uR.d.mts +1641 -0
- package/dist/types-D0aJW2uR.d.mts.map +1 -0
- package/dist/types-DbpN4Qto.d.mts +372 -0
- package/dist/types-DbpN4Qto.d.mts.map +1 -0
- package/dist/types-ILDI1sdY.mjs +16 -0
- package/dist/types-ILDI1sdY.mjs.map +1 -0
- package/dist/types-OC5c-edM.mjs +22 -0
- package/dist/types-OC5c-edM.mjs.map +1 -0
- package/dist/types-aOOxRSx6.mjs +103 -0
- package/dist/types-aOOxRSx6.mjs.map +1 -0
- package/dist/types-m1WbUffD.d.mts +198 -0
- package/dist/types-m1WbUffD.d.mts.map +1 -0
- package/dist/types-uxLoPBio.d.mts +124 -0
- package/dist/types-uxLoPBio.d.mts.map +1 -0
- package/dist/types-we5uR-tV.d.mts +287 -0
- package/dist/types-we5uR-tV.d.mts.map +1 -0
- package/dist/upload-attempts-DduMy6B0.mjs +32 -0
- package/dist/upload-attempts-DduMy6B0.mjs.map +1 -0
- package/dist/url-pattern-B3EwxAAk.mjs +33 -0
- package/dist/url-pattern-B3EwxAAk.mjs.map +1 -0
- package/dist/user-ElwQjTQT.mjs +171 -0
- package/dist/user-ElwQjTQT.mjs.map +1 -0
- package/dist/utils-BlAXmfOG.mjs +439 -0
- package/dist/utils-BlAXmfOG.mjs.map +1 -0
- package/dist/validate-CH0X5b2c.d.mts +468 -0
- package/dist/validate-CH0X5b2c.d.mts.map +1 -0
- package/dist/validate-CfgRpcjA.mjs +492 -0
- package/dist/validate-CfgRpcjA.mjs.map +1 -0
- package/dist/validation-DvYJtv4k.mjs +218 -0
- package/dist/validation-DvYJtv4k.mjs.map +1 -0
- package/dist/version-DgYjhTud.mjs +9 -0
- package/dist/version-DgYjhTud.mjs.map +1 -0
- package/dist/version-Dq71scUb.mjs +7 -0
- package/dist/version-Dq71scUb.mjs.map +1 -0
- package/dist/widgets-ChFIj0be.mjs +126 -0
- package/dist/widgets-ChFIj0be.mjs.map +1 -0
- package/dist/wxr-taxonomies-CBZMp2YX.mjs +372 -0
- package/dist/wxr-taxonomies-CBZMp2YX.mjs.map +1 -0
- package/dist/wxr-taxonomies-DlKDpWN1.d.mts +34 -0
- package/dist/wxr-taxonomies-DlKDpWN1.d.mts.map +1 -0
- package/dist/zod-generator-DmTKI-Ig.mjs +426 -0
- package/dist/zod-generator-DmTKI-Ig.mjs.map +1 -0
- package/package.json +7 -6
- package/src/api/handlers/content.ts +593 -16
- package/src/api/handlers/device-flow.ts +74 -21
- package/src/api/handlers/index.ts +1 -0
- package/src/api/handlers/manifest.ts +79 -5
- package/src/api/handlers/media-upload.ts +17 -71
- package/src/api/handlers/media.ts +97 -3
- package/src/api/handlers/relations.ts +638 -157
- package/src/api/handlers/revision.ts +30 -0
- package/src/api/handlers/schema.ts +403 -1
- package/src/api/handlers/snapshot.ts +257 -3
- package/src/api/handlers/staged-references.ts +142 -0
- package/src/api/handlers/validate-references.ts +146 -0
- package/src/api/schemas/content.ts +13 -0
- package/src/api/schemas/relations.ts +54 -44
- package/src/api/schemas/schema.ts +14 -0
- package/src/astro/integration/routes.ts +15 -19
- package/src/astro/integration/vite-config.ts +10 -4
- package/src/astro/middleware.ts +1 -0
- package/src/astro/routes/api/content/[collection]/[id]/references/[relation]/children.ts +11 -54
- package/src/astro/routes/api/content/[collection]/[id].ts +3 -1
- package/src/astro/routes/api/oauth/device/authorize.ts +33 -4
- package/src/astro/routes/api/relations/index.ts +4 -4
- package/src/astro/routes/api/schema/collections/[slug]/fields/[fieldSlug].ts +6 -2
- package/src/astro/routes/api/setup/index.ts +66 -23
- package/src/astro/routes/api/snapshot.ts +2 -1
- package/src/astro/types.ts +10 -0
- package/src/cleanup.ts +10 -0
- package/src/cli/commands/export-seed.ts +510 -89
- package/src/components/Columns.astro +3 -1
- package/src/components/Cover.astro +3 -1
- package/src/components/WidgetArea.astro +3 -2
- package/src/database/migrations/086_relations_structural.ts +197 -0
- package/src/database/migrations/087_reference_field_relations.ts +407 -0
- package/src/database/migrations/runner.ts +4 -0
- package/src/database/reference-backfill.ts +141 -0
- package/src/database/repositories/content.ts +43 -8
- package/src/database/repositories/media.ts +40 -1
- package/src/database/repositories/redirect.ts +17 -34
- package/src/database/repositories/relation.ts +620 -208
- package/src/database/repositories/revision.ts +16 -0
- package/src/database/repositories/types.ts +38 -0
- package/src/database/transaction.ts +12 -1
- package/src/database/types.ts +14 -5
- package/src/emdash-runtime.ts +114 -11
- package/src/index.ts +11 -0
- package/src/loader.ts +169 -22
- package/src/mcp/server.ts +13 -48
- package/src/query.ts +455 -25
- package/src/references/field-map.ts +115 -0
- package/src/references/resolve.ts +160 -0
- package/src/references/staged.ts +117 -0
- package/src/references/types.ts +16 -0
- package/src/registry/artifact-fetch.ts +45 -271
- package/src/schema/registry.ts +99 -24
- package/src/schema/types.ts +58 -0
- package/src/schema/zod-generator.ts +67 -1
- package/src/seed/apply.ts +841 -103
- package/src/seed/types.ts +36 -2
- package/src/seed/validate.ts +78 -2
- package/src/transfer/analyze/unique-keys.ts +3 -12
- package/src/transfer/analyze/validate.ts +65 -39
- package/src/transfer/analyze/values.ts +12 -1
- package/src/transfer/export/readers.ts +12 -8
- package/src/transfer/format/columns.ts +26 -6
- package/src/transfer/format/kinds.ts +21 -5
- package/src/transfer/import/context.ts +8 -1
- package/src/transfer/ops/package-index.ts +1 -1
- package/dist/action-token-DYwe4Pk0.mjs +0 -26
- package/dist/action-token-DYwe4Pk0.mjs.map +0 -1
- package/dist/activation-LOkDM5WT.mjs +0 -382
- package/dist/activation-LOkDM5WT.mjs.map +0 -1
- package/dist/adapters-B64LbYcB.d.mts +0 -171
- package/dist/adapters-B64LbYcB.d.mts.map +0 -1
- package/dist/allowed-origins-CHB8oZNM.mjs +0 -116
- package/dist/allowed-origins-CHB8oZNM.mjs.map +0 -1
- package/dist/api-cFFZpyS0.mjs +0 -4718
- package/dist/api-cFFZpyS0.mjs.map +0 -1
- package/dist/api-tokens-s4i4aUp_.mjs +0 -166
- package/dist/api-tokens-s4i4aUp_.mjs.map +0 -1
- package/dist/apply-CoT603H3.mjs +0 -1163
- package/dist/apply-CoT603H3.mjs.map +0 -1
- package/dist/approvals-CqMfNxak.mjs +0 -460
- package/dist/approvals-CqMfNxak.mjs.map +0 -1
- package/dist/artifact-fetch-DZMOGZ3-.mjs +0 -818
- package/dist/artifact-fetch-DZMOGZ3-.mjs.map +0 -1
- package/dist/astro/routes/api/relations/_id_/translations.d.mts +0 -8
- package/dist/astro/routes/api/relations/_id_/translations.d.mts.map +0 -1
- package/dist/astro/routes/api/relations/_id_/translations.mjs +0 -47
- package/dist/astro/routes/api/relations/_id_/translations.mjs.map +0 -1
- package/dist/audit-RfCugiSB.mjs +0 -127
- package/dist/audit-RfCugiSB.mjs.map +0 -1
- package/dist/authoritative-records-CoJvBXAD.mjs +0 -5172
- package/dist/authoritative-records-CoJvBXAD.mjs.map +0 -1
- package/dist/authorize-seCifOMJ.mjs +0 -49
- package/dist/authorize-seCifOMJ.mjs.map +0 -1
- package/dist/backup-CBu0LrXf.mjs +0 -246
- package/dist/backup-CBu0LrXf.mjs.map +0 -1
- package/dist/block-type-registry-DUI_3KxT.mjs +0 -6709
- package/dist/block-type-registry-DUI_3KxT.mjs.map +0 -1
- package/dist/block-types-BmZmLmAD.mjs +0 -132
- package/dist/block-types-BmZmLmAD.mjs.map +0 -1
- package/dist/block-values-C_VIPr5t.mjs +0 -175
- package/dist/block-values-C_VIPr5t.mjs.map +0 -1
- package/dist/byline-DYmkXqvo.mjs +0 -909
- package/dist/byline-DYmkXqvo.mjs.map +0 -1
- package/dist/byline-fields-D28AT-Fh.mjs +0 -123
- package/dist/byline-fields-D28AT-Fh.mjs.map +0 -1
- package/dist/byline-registry-gnKscbQX.mjs +0 -406
- package/dist/byline-registry-gnKscbQX.mjs.map +0 -1
- package/dist/bylines-BPwJqoYH.mjs +0 -232
- package/dist/bylines-BPwJqoYH.mjs.map +0 -1
- package/dist/bylines-ukLaYpVZ.mjs +0 -214
- package/dist/bylines-ukLaYpVZ.mjs.map +0 -1
- package/dist/cache-m7UEkRFV.mjs +0 -108
- package/dist/cache-m7UEkRFV.mjs.map +0 -1
- package/dist/canonical-YhEQezjg.mjs +0 -174
- package/dist/canonical-YhEQezjg.mjs.map +0 -1
- package/dist/capture-triggers-kJyl_yyM.mjs +0 -362
- package/dist/capture-triggers-kJyl_yyM.mjs.map +0 -1
- package/dist/challenge-store-ppU6Uv13.mjs +0 -51
- package/dist/challenge-store-ppU6Uv13.mjs.map +0 -1
- package/dist/checksum-B2IINIlN.mjs +0 -162
- package/dist/checksum-B2IINIlN.mjs.map +0 -1
- package/dist/chrome-tags-DApCQSIk.mjs +0 -24
- package/dist/chrome-tags-DApCQSIk.mjs.map +0 -1
- package/dist/chunks-Dms7Uxbt.mjs +0 -25
- package/dist/chunks-Dms7Uxbt.mjs.map +0 -1
- package/dist/collection-deletion-BIm28mo3.mjs +0 -436
- package/dist/collection-deletion-BIm28mo3.mjs.map +0 -1
- package/dist/collection-deletion-processor-Br6rxs3u.mjs +0 -217
- package/dist/collection-deletion-processor-Br6rxs3u.mjs.map +0 -1
- package/dist/collection-slugs-cache-CjGk__zp.mjs +0 -85
- package/dist/collection-slugs-cache-CjGk__zp.mjs.map +0 -1
- package/dist/comment-CrBl22OF.mjs +0 -313
- package/dist/comment-CrBl22OF.mjs.map +0 -1
- package/dist/comment-reaction-JEQ2Fpd8.mjs +0 -85
- package/dist/comment-reaction-JEQ2Fpd8.mjs.map +0 -1
- package/dist/comments-2ah9du9y.mjs +0 -195
- package/dist/comments-2ah9du9y.mjs.map +0 -1
- package/dist/comments-fHZ8ON9O.mjs +0 -99
- package/dist/comments-fHZ8ON9O.mjs.map +0 -1
- package/dist/components-CXbq7CSM.mjs +0 -108
- package/dist/components-CXbq7CSM.mjs.map +0 -1
- package/dist/config-5ii2haYu.d.mts +0 -6528
- package/dist/config-5ii2haYu.d.mts.map +0 -1
- package/dist/config-IhybvkIQ.mjs +0 -242
- package/dist/config-IhybvkIQ.mjs.map +0 -1
- package/dist/config-Py43JK9r.d.mts +0 -39
- package/dist/config-Py43JK9r.d.mts.map +0 -1
- package/dist/content-DFaIEDj9.mjs +0 -2281
- package/dist/content-DFaIEDj9.mjs.map +0 -1
- package/dist/content-list-query-Dra4Dalc.d.mts +0 -26
- package/dist/content-list-query-Dra4Dalc.d.mts.map +0 -1
- package/dist/content-policy-DFNw91-d.mjs +0 -46
- package/dist/content-policy-DFNw91-d.mjs.map +0 -1
- package/dist/content-repair-Q8IUrpLL.mjs +0 -442
- package/dist/content-repair-Q8IUrpLL.mjs.map +0 -1
- package/dist/context-BeGccdUX.mjs +0 -1921
- package/dist/context-BeGccdUX.mjs.map +0 -1
- package/dist/cron-7DCJwPXq.mjs +0 -284
- package/dist/cron-7DCJwPXq.mjs.map +0 -1
- package/dist/dashboard-DjrB-xxZ.mjs +0 -151
- package/dist/dashboard-DjrB-xxZ.mjs.map +0 -1
- package/dist/default-DQ6vsviu.mjs +0 -81
- package/dist/default-DQ6vsviu.mjs.map +0 -1
- package/dist/deferred-tasks-BPxXUB4x.d.mts +0 -9
- package/dist/deferred-tasks-BPxXUB4x.d.mts.map +0 -1
- package/dist/dev-typegen-CZaPLl3V.mjs +0 -29
- package/dist/dev-typegen-CZaPLl3V.mjs.map +0 -1
- package/dist/device-flow-CRd6DXmW.mjs +0 -466
- package/dist/device-flow-CRd6DXmW.mjs.map +0 -1
- package/dist/digest-BarSh-pN.mjs +0 -194
- package/dist/digest-BarSh-pN.mjs.map +0 -1
- package/dist/direct-executor-BmuFJJZV.mjs +0 -104
- package/dist/direct-executor-BmuFJJZV.mjs.map +0 -1
- package/dist/dist-BNwANFJR.mjs +0 -810
- package/dist/dist-BNwANFJR.mjs.map +0 -1
- package/dist/email-console-bJn3ctqA.mjs +0 -50
- package/dist/email-console-bJn3ctqA.mjs.map +0 -1
- package/dist/email-locale-CN6WAMx0.mjs +0 -25
- package/dist/email-locale-CN6WAMx0.mjs.map +0 -1
- package/dist/emdash-runtime-DAjghyEG.mjs +0 -4186
- package/dist/emdash-runtime-DAjghyEG.mjs.map +0 -1
- package/dist/enrich-Dl3kZ-lP.mjs +0 -194
- package/dist/enrich-Dl3kZ-lP.mjs.map +0 -1
- package/dist/entry-lock-BJYdBfXb.mjs +0 -1097
- package/dist/entry-lock-BJYdBfXb.mjs.map +0 -1
- package/dist/entry-lock-DHQOxN7R.mjs +0 -163
- package/dist/entry-lock-DHQOxN7R.mjs.map +0 -1
- package/dist/entry-lock-DVhCt49A.d.mts +0 -4368
- package/dist/entry-lock-DVhCt49A.d.mts.map +0 -1
- package/dist/entry-locks-D0foLdjQ.mjs +0 -167
- package/dist/entry-locks-D0foLdjQ.mjs.map +0 -1
- package/dist/error-CfvOHP0M.mjs +0 -90
- package/dist/error-CfvOHP0M.mjs.map +0 -1
- package/dist/errors-BF0_LFhW.mjs +0 -460
- package/dist/errors-BF0_LFhW.mjs.map +0 -1
- package/dist/errors-DgE1zJGG.mjs +0 -120
- package/dist/errors-DgE1zJGG.mjs.map +0 -1
- package/dist/escape-CuaZhZvL.mjs +0 -9
- package/dist/escape-CuaZhZvL.mjs.map +0 -1
- package/dist/fence-CMDXJYc_.mjs +0 -162
- package/dist/fence-CMDXJYc_.mjs.map +0 -1
- package/dist/field-defs-cache-HIgBbqZZ.mjs +0 -77
- package/dist/field-defs-cache-HIgBbqZZ.mjs.map +0 -1
- package/dist/focal-point-Gr34o-4o.mjs +0 -23
- package/dist/focal-point-Gr34o-4o.mjs.map +0 -1
- package/dist/fts-manager-S-K0laoS.mjs +0 -443
- package/dist/fts-manager-S-K0laoS.mjs.map +0 -1
- package/dist/gc-DjKY0Ay1.mjs +0 -75
- package/dist/gc-DjKY0Ay1.mjs.map +0 -1
- package/dist/hash-SDAW6zC-.mjs +0 -37
- package/dist/hash-SDAW6zC-.mjs.map +0 -1
- package/dist/hook-result-B5bXDgS2.d.mts +0 -31
- package/dist/hook-result-B5bXDgS2.d.mts.map +0 -1
- package/dist/hreflang-D5uNnsGJ.d.mts +0 -50
- package/dist/hreflang-D5uNnsGJ.d.mts.map +0 -1
- package/dist/hreflang-DMFBL2eb.mjs +0 -105
- package/dist/hreflang-DMFBL2eb.mjs.map +0 -1
- package/dist/http-route-dispatch-BitqzwMy.mjs +0 -339
- package/dist/http-route-dispatch-BitqzwMy.mjs.map +0 -1
- package/dist/identity-IyNWwXr6.mjs +0 -35
- package/dist/identity-IyNWwXr6.mjs.map +0 -1
- package/dist/import-C3JZplWq.mjs +0 -2020
- package/dist/import-C3JZplWq.mjs.map +0 -1
- package/dist/index-D-hdtLe8.d.mts +0 -623
- package/dist/index-D-hdtLe8.d.mts.map +0 -1
- package/dist/install-finalization-DfM1fj5x.mjs +0 -58
- package/dist/install-finalization-DfM1fj5x.mjs.map +0 -1
- package/dist/keys-yxLm5l35.mjs +0 -61
- package/dist/keys-yxLm5l35.mjs.map +0 -1
- package/dist/kinds-CRu_T5T5.mjs +0 -961
- package/dist/kinds-CRu_T5T5.mjs.map +0 -1
- package/dist/lifecycle-BzeGPeQ-.mjs +0 -25
- package/dist/lifecycle-BzeGPeQ-.mjs.map +0 -1
- package/dist/load-XgJiE6_3.mjs +0 -28
- package/dist/load-XgJiE6_3.mjs.map +0 -1
- package/dist/loader-BzqeR1ZN.mjs +0 -1086
- package/dist/loader-BzqeR1ZN.mjs.map +0 -1
- package/dist/loops-BQSzv5Zn.mjs +0 -203
- package/dist/loops-BQSzv5Zn.mjs.map +0 -1
- package/dist/manifest-builder-B8zR-73J.mjs +0 -189
- package/dist/manifest-builder-B8zR-73J.mjs.map +0 -1
- package/dist/manifest-schema-CY3zng_M.mjs +0 -492
- package/dist/manifest-schema-CY3zng_M.mjs.map +0 -1
- package/dist/media-Pu1L6xir.mjs +0 -408
- package/dist/media-Pu1L6xir.mjs.map +0 -1
- package/dist/media-Qp5S3eH3.mjs +0 -355
- package/dist/media-Qp5S3eH3.mjs.map +0 -1
- package/dist/media-allowlist-BSoa9Vvm.mjs +0 -44
- package/dist/media-allowlist-BSoa9Vvm.mjs.map +0 -1
- package/dist/media-folders-BE0oo2eX.mjs +0 -210
- package/dist/media-folders-BE0oo2eX.mjs.map +0 -1
- package/dist/media-h7tOiDLj.mjs +0 -221
- package/dist/media-h7tOiDLj.mjs.map +0 -1
- package/dist/media-url-jArBpzIG.mjs +0 -43
- package/dist/media-url-jArBpzIG.mjs.map +0 -1
- package/dist/media-usage-My-Vi-ex.mjs +0 -1629
- package/dist/media-usage-My-Vi-ex.mjs.map +0 -1
- package/dist/media-usage-activation-HKp7zk7W.mjs +0 -78
- package/dist/media-usage-activation-HKp7zk7W.mjs.map +0 -1
- package/dist/media-usage-work-C2OZLCAd.mjs +0 -586
- package/dist/media-usage-work-C2OZLCAd.mjs.map +0 -1
- package/dist/media-usage-work-DwUNbgvS.mjs +0 -152
- package/dist/media-usage-work-DwUNbgvS.mjs.map +0 -1
- package/dist/menus-BM7BPLOb.mjs +0 -139
- package/dist/menus-BM7BPLOb.mjs.map +0 -1
- package/dist/menus-ITeAbcIF.mjs +0 -753
- package/dist/menus-ITeAbcIF.mjs.map +0 -1
- package/dist/menus-TsSGmSR4.mjs +0 -3608
- package/dist/menus-TsSGmSR4.mjs.map +0 -1
- package/dist/mime-ChLqYwDk.mjs +0 -36
- package/dist/mime-ChLqYwDk.mjs.map +0 -1
- package/dist/mode-CCuKXUci.mjs +0 -23
- package/dist/mode-CCuKXUci.mjs.map +0 -1
- package/dist/node-sqlite-compat-CONMsl-x.mjs +0 -46
- package/dist/node-sqlite-compat-CONMsl-x.mjs.map +0 -1
- package/dist/normalize-CO2P8-iE.mjs +0 -191
- package/dist/normalize-CO2P8-iE.mjs.map +0 -1
- package/dist/oauth-authorization-DlMIL5_h.mjs +0 -274
- package/dist/oauth-authorization-DlMIL5_h.mjs.map +0 -1
- package/dist/oauth-clients-Djq9r_KP.mjs +0 -266
- package/dist/oauth-clients-Djq9r_KP.mjs.map +0 -1
- package/dist/oauth-state-store-BbjnZXNC.mjs +0 -50
- package/dist/oauth-state-store-BbjnZXNC.mjs.map +0 -1
- package/dist/oauth-user-lookup-vue9a64A.mjs +0 -26
- package/dist/oauth-user-lookup-vue9a64A.mjs.map +0 -1
- package/dist/options-SQCHQCPH.d.mts +0 -81
- package/dist/options-SQCHQCPH.d.mts.map +0 -1
- package/dist/parse-CVgO-Qai.d.mts +0 -168
- package/dist/parse-CVgO-Qai.d.mts.map +0 -1
- package/dist/parse-DY6OD1j_.mjs +0 -81
- package/dist/parse-DY6OD1j_.mjs.map +0 -1
- package/dist/passkey-config-X_H8128a.mjs +0 -46
- package/dist/passkey-config-X_H8128a.mjs.map +0 -1
- package/dist/paths-JxokKIbr.mjs +0 -77
- package/dist/paths-JxokKIbr.mjs.map +0 -1
- package/dist/patterns-BhAvqO0S.mjs +0 -145
- package/dist/patterns-BhAvqO0S.mjs.map +0 -1
- package/dist/placeholder-MSEd8gty.d.mts +0 -306
- package/dist/placeholder-MSEd8gty.d.mts.map +0 -1
- package/dist/plan-xjcWrAah.mjs +0 -135
- package/dist/plan-xjcWrAah.mjs.map +0 -1
- package/dist/plugins-DUXUt8B9.mjs +0 -277
- package/dist/plugins-DUXUt8B9.mjs.map +0 -1
- package/dist/policy-CUvwAARc.mjs +0 -45
- package/dist/policy-CUvwAARc.mjs.map +0 -1
- package/dist/portable-text-5O_ZGUjB.mjs +0 -307
- package/dist/portable-text-5O_ZGUjB.mjs.map +0 -1
- package/dist/preview-CIUcPYr6.mjs +0 -107
- package/dist/preview-CIUcPYr6.mjs.map +0 -1
- package/dist/protocol-B97DZaFr.d.mts +0 -61
- package/dist/protocol-B97DZaFr.d.mts.map +0 -1
- package/dist/public-submission-BFBUrqst.mjs +0 -250
- package/dist/public-submission-BFBUrqst.mjs.map +0 -1
- package/dist/public-url-Bn7U0D7-.mjs +0 -101
- package/dist/public-url-Bn7U0D7-.mjs.map +0 -1
- package/dist/query-B48peoRT.mjs +0 -890
- package/dist/query-B48peoRT.mjs.map +0 -1
- package/dist/query-C4IH0uhR.mjs +0 -41
- package/dist/query-C4IH0uhR.mjs.map +0 -1
- package/dist/rate-limit-BZ6nybgc.mjs +0 -120
- package/dist/rate-limit-BZ6nybgc.mjs.map +0 -1
- package/dist/receipt-B4wJj5Jq.mjs +0 -43
- package/dist/receipt-B4wJj5Jq.mjs.map +0 -1
- package/dist/redirect-Cd1E7VUt.mjs +0 -17
- package/dist/redirect-Cd1E7VUt.mjs.map +0 -1
- package/dist/redirect-iJf5fltD.mjs +0 -415
- package/dist/redirect-iJf5fltD.mjs.map +0 -1
- package/dist/redirects-CYu1u1aK.mjs +0 -446
- package/dist/redirects-CYu1u1aK.mjs.map +0 -1
- package/dist/redirects-Cv9apQKj.mjs +0 -148
- package/dist/redirects-Cv9apQKj.mjs.map +0 -1
- package/dist/relation-M4NUCb0b.mjs +0 -334
- package/dist/relation-M4NUCb0b.mjs.map +0 -1
- package/dist/relations-CCif47Oq.mjs +0 -403
- package/dist/relations-CCif47Oq.mjs.map +0 -1
- package/dist/relations-CK9CYUyr.mjs +0 -310
- package/dist/relations-CK9CYUyr.mjs.map +0 -1
- package/dist/request-cache-DzLYKm_x.mjs +0 -104
- package/dist/request-cache-DzLYKm_x.mjs.map +0 -1
- package/dist/request-meta-sZXt3sRo.mjs +0 -141
- package/dist/request-meta-sZXt3sRo.mjs.map +0 -1
- package/dist/resolve-2WbQsCvT.mjs +0 -199
- package/dist/resolve-2WbQsCvT.mjs.map +0 -1
- package/dist/route-wire--1hLuACz.mjs +0 -197
- package/dist/route-wire--1hLuACz.mjs.map +0 -1
- package/dist/routes-CUsM40Cc.mjs +0 -272
- package/dist/routes-CUsM40Cc.mjs.map +0 -1
- package/dist/runner-1y4J9fJB.mjs +0 -5742
- package/dist/runner-1y4J9fJB.mjs.map +0 -1
- package/dist/runner-D5_LzKXI.d.mts +0 -68
- package/dist/runner-D5_LzKXI.d.mts.map +0 -1
- package/dist/schema-BABiRdsH.mjs +0 -13
- package/dist/schema-BABiRdsH.mjs.map +0 -1
- package/dist/schema-Du3MzCG0.mjs +0 -446
- package/dist/schema-Du3MzCG0.mjs.map +0 -1
- package/dist/scopes-Dbk-ElhT.mjs +0 -34
- package/dist/scopes-Dbk-ElhT.mjs.map +0 -1
- package/dist/search-Bt1PL1jf.mjs +0 -448
- package/dist/search-Bt1PL1jf.mjs.map +0 -1
- package/dist/sections-Ddptx_o9.mjs +0 -346
- package/dist/sections-Ddptx_o9.mjs.map +0 -1
- package/dist/seo-CZT2oLtT.mjs +0 -114
- package/dist/seo-CZT2oLtT.mjs.map +0 -1
- package/dist/seo-D5w3-Azy.mjs +0 -133
- package/dist/seo-D5w3-Azy.mjs.map +0 -1
- package/dist/service-DuykXPyW.mjs +0 -150
- package/dist/service-DuykXPyW.mjs.map +0 -1
- package/dist/session-user-BhaVp8w0.mjs +0 -51
- package/dist/session-user-BhaVp8w0.mjs.map +0 -1
- package/dist/settings-2xNYr90o.mjs +0 -51
- package/dist/settings-2xNYr90o.mjs.map +0 -1
- package/dist/settings-CgjRWGW9.mjs +0 -439
- package/dist/settings-CgjRWGW9.mjs.map +0 -1
- package/dist/settings-DYidIB26.mjs +0 -61
- package/dist/settings-DYidIB26.mjs.map +0 -1
- package/dist/setup-complete-bOogcHWG.mjs +0 -26
- package/dist/setup-complete-bOogcHWG.mjs.map +0 -1
- package/dist/setup-nonce-0EGuKM4s.mjs +0 -25
- package/dist/setup-nonce-0EGuKM4s.mjs.map +0 -1
- package/dist/site-settings-DOgRUoFX.mjs +0 -50
- package/dist/site-settings-DOgRUoFX.mjs.map +0 -1
- package/dist/site-url-BU_bbxwj.mjs +0 -16
- package/dist/site-url-BU_bbxwj.mjs.map +0 -1
- package/dist/snapshot-CugwUqKQ.mjs +0 -237
- package/dist/snapshot-CugwUqKQ.mjs.map +0 -1
- package/dist/ssrf-CJUnJymJ.mjs +0 -406
- package/dist/ssrf-CJUnJymJ.mjs.map +0 -1
- package/dist/stage-DgrBz_du.mjs +0 -662
- package/dist/stage-DgrBz_du.mjs.map +0 -1
- package/dist/state-DDiPySSG.mjs +0 -153
- package/dist/state-DDiPySSG.mjs.map +0 -1
- package/dist/status-DZKIG4a9.mjs +0 -30
- package/dist/status-DZKIG4a9.mjs.map +0 -1
- package/dist/storage-query-Bdv7A62k.d.mts +0 -1576
- package/dist/storage-query-Bdv7A62k.d.mts.map +0 -1
- package/dist/tar-_1AgTYFu.mjs +0 -449
- package/dist/tar-_1AgTYFu.mjs.map +0 -1
- package/dist/target-_7pn2Gbg.mjs +0 -27
- package/dist/target-_7pn2Gbg.mjs.map +0 -1
- package/dist/taxonomies-C1IwNe8Q.mjs +0 -697
- package/dist/taxonomies-C1IwNe8Q.mjs.map +0 -1
- package/dist/taxonomies-C_XMoRcX.mjs +0 -939
- package/dist/taxonomies-C_XMoRcX.mjs.map +0 -1
- package/dist/taxonomy-C3Fu1YeH.mjs +0 -525
- package/dist/taxonomy-C3Fu1YeH.mjs.map +0 -1
- package/dist/tokens-u78jETkX.mjs +0 -171
- package/dist/tokens-u78jETkX.mjs.map +0 -1
- package/dist/transaction-BcJO4Tmc.mjs +0 -29
- package/dist/transaction-BcJO4Tmc.mjs.map +0 -1
- package/dist/transfer-BhUCrgDc.mjs +0 -8675
- package/dist/transfer-BhUCrgDc.mjs.map +0 -1
- package/dist/transfer-DIGvR9Af.mjs +0 -166
- package/dist/transfer-DIGvR9Af.mjs.map +0 -1
- package/dist/transfer-download-Pml7RMio.mjs +0 -33
- package/dist/transfer-download-Pml7RMio.mjs.map +0 -1
- package/dist/transformations-9gfpwY65.mjs +0 -196
- package/dist/transformations-9gfpwY65.mjs.map +0 -1
- package/dist/transport-BIfH7_hx.d.mts +0 -42
- package/dist/transport-BIfH7_hx.d.mts.map +0 -1
- package/dist/transport-DKWIq53q.mjs +0 -136
- package/dist/transport-DKWIq53q.mjs.map +0 -1
- package/dist/trusted-proxy-tKiVtyTD.mjs +0 -51
- package/dist/trusted-proxy-tKiVtyTD.mjs.map +0 -1
- package/dist/turnstile-DpsoyOfg.mjs +0 -53
- package/dist/turnstile-DpsoyOfg.mjs.map +0 -1
- package/dist/types-B4sUC2p1.d.mts +0 -198
- package/dist/types-B4sUC2p1.d.mts.map +0 -1
- package/dist/types-B7Lmsh1E.d.mts +0 -887
- package/dist/types-B7Lmsh1E.d.mts.map +0 -1
- package/dist/types-BZakh7Ym.mjs +0 -22
- package/dist/types-BZakh7Ym.mjs.map +0 -1
- package/dist/types-B_CppEmv.d.mts +0 -264
- package/dist/types-B_CppEmv.d.mts.map +0 -1
- package/dist/types-BcrBrE6-.mjs +0 -159
- package/dist/types-BcrBrE6-.mjs.map +0 -1
- package/dist/types-BkUg2yHx.mjs +0 -92
- package/dist/types-BkUg2yHx.mjs.map +0 -1
- package/dist/types-CAZgq9fO.d.mts +0 -124
- package/dist/types-CAZgq9fO.d.mts.map +0 -1
- package/dist/types-Cd-O03VG.d.mts +0 -363
- package/dist/types-Cd-O03VG.d.mts.map +0 -1
- package/dist/types-Cr-Kg-3D.d.mts +0 -1641
- package/dist/types-Cr-Kg-3D.d.mts.map +0 -1
- package/dist/types-D2fvWd1i.d.mts +0 -359
- package/dist/types-D2fvWd1i.d.mts.map +0 -1
- package/dist/types-D7HUsguf.mjs +0 -77
- package/dist/types-D7HUsguf.mjs.map +0 -1
- package/dist/types-DA1Te3Oy.d.mts +0 -198
- package/dist/types-DA1Te3Oy.d.mts.map +0 -1
- package/dist/types-DhV6Q5bP.mjs +0 -18
- package/dist/types-DhV6Q5bP.mjs.map +0 -1
- package/dist/types-DnnVSl6Y.d.mts +0 -85
- package/dist/types-DnnVSl6Y.d.mts.map +0 -1
- package/dist/types-VT4-BugW.mjs +0 -16
- package/dist/types-VT4-BugW.mjs.map +0 -1
- package/dist/upload-attempts-B68ZGNu9.mjs +0 -32
- package/dist/upload-attempts-B68ZGNu9.mjs.map +0 -1
- package/dist/url-pattern-CCeZMGOh.mjs +0 -33
- package/dist/url-pattern-CCeZMGOh.mjs.map +0 -1
- package/dist/user-DDSL-sGw.mjs +0 -171
- package/dist/user-DDSL-sGw.mjs.map +0 -1
- package/dist/utils-DdhmO9w9.mjs +0 -439
- package/dist/utils-DdhmO9w9.mjs.map +0 -1
- package/dist/validate-CHosPEhs.mjs +0 -453
- package/dist/validate-CHosPEhs.mjs.map +0 -1
- package/dist/validate-CM79QXYE.d.mts +0 -432
- package/dist/validate-CM79QXYE.d.mts.map +0 -1
- package/dist/validation-BFecQczG.mjs +0 -218
- package/dist/validation-BFecQczG.mjs.map +0 -1
- package/dist/version-BRZXVifl.mjs +0 -9
- package/dist/version-BRZXVifl.mjs.map +0 -1
- package/dist/version-DUQDHgrf.mjs +0 -7
- package/dist/version-DUQDHgrf.mjs.map +0 -1
- package/dist/widgets-WdV72brA.mjs +0 -126
- package/dist/widgets-WdV72brA.mjs.map +0 -1
- package/dist/wxr-taxonomies-BHTdqkmZ.d.mts +0 -34
- package/dist/wxr-taxonomies-BHTdqkmZ.d.mts.map +0 -1
- package/dist/wxr-taxonomies-DP6ESgMN.mjs +0 -372
- package/dist/wxr-taxonomies-DP6ESgMN.mjs.map +0 -1
- package/dist/zod-generator-D6uE4WiS.mjs +0 -389
- package/dist/zod-generator-D6uE4WiS.mjs.map +0 -1
- package/src/astro/routes/api/relations/[id]/translations.ts +0 -33
- /package/dist/{api-tokens-CE1ECIg0.mjs → api-tokens-FaG1zPsj.mjs} +0 -0
- /package/dist/{ssrf-DpBH7aOt.mjs → ssrf-DZOt8Qof.mjs} +0 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"device-flow-OcSqE9uY.mjs","names":[],"sources":["../src/api/handlers/device-flow.ts"],"sourcesContent":["/**\n * OAuth Device Flow handlers (RFC 8628).\n *\n * EmDash acts as an OAuth 2.0 authorization server. The CLI requests\n * a device code, displays a URL + user code, and polls for a token.\n * The user opens a browser, logs in, enters the code, and the CLI gets\n * an access + refresh token pair.\n *\n * Uses arctic for code generation and @emdash-cms/auth for token utilities.\n */\n\nimport { clampScopes } from \"@emdash-cms/auth\";\nimport type { RoleLevel } from \"@emdash-cms/auth\";\nimport { generateCodeVerifier } from \"arctic\";\nimport type { Kysely, Selectable } from \"kysely\";\n\nimport {\n\tgeneratePrefixedToken,\n\thashApiToken,\n\tisValidScope,\n\tTOKEN_PREFIXES,\n} from \"../../auth/api-tokens.js\";\nimport { withTransaction } from \"../../database/transaction.js\";\nimport type { Database, DeviceCodeTable } from \"../../database/types.js\";\nimport type { ApiResult } from \"../types.js\";\nimport { lookupOAuthClient } from \"./oauth-clients.js\";\nimport { lookupUserRoleAndStatus } from \"./oauth-user-lookup.js\";\n\n// ---------------------------------------------------------------------------\n// Constants\n// ---------------------------------------------------------------------------\n\n/** Device codes expire after 15 minutes */\nconst DEVICE_CODE_TTL_SECONDS = 15 * 60;\n\n/** Default polling interval in seconds */\nconst DEFAULT_INTERVAL = 5;\n\n/** RFC 8628 §3.5: interval increase on slow_down */\nconst SLOW_DOWN_INCREMENT = 5;\n\n/** Maximum slow_down interval cap (seconds) */\nconst MAX_SLOW_DOWN_INTERVAL = 60;\n\n/** Access token TTL: 1 hour */\nconst ACCESS_TOKEN_TTL_SECONDS = 60 * 60;\n\n/** Refresh token TTL: 90 days */\nconst REFRESH_TOKEN_TTL_SECONDS = 90 * 24 * 60 * 60;\n\n/** Default scopes for CLI login */\nconst DEFAULT_SCOPES = [\n\t\"content:read\",\n\t\"content:write\",\n\t\"media:read\",\n\t\"media:write\",\n\t\"schema:read\",\n] as const;\n\n/** Pattern to normalize user codes (strip hyphens) */\nconst HYPHEN_PATTERN = /-/g;\n\n/** Characters for user codes (uppercase, no ambiguous chars like 0/O, 1/I) */\nconst USER_CODE_CHARS = \"ABCDEFGHJKLMNPQRSTUVWXYZ23456789\";\n\n// ---------------------------------------------------------------------------\n// Types\n// ---------------------------------------------------------------------------\n\nexport interface DeviceCodeResponse {\n\tdevice_code: string;\n\tuser_code: string;\n\tverification_uri: string;\n\texpires_in: number;\n\tinterval: number;\n}\n\nexport interface TokenResponse {\n\taccess_token: string;\n\trefresh_token: string;\n\ttoken_type: \"Bearer\";\n\texpires_in: number;\n\tscope: string;\n}\n\n// RFC 8628 error codes\nexport type DeviceFlowError =\n\t| \"authorization_pending\"\n\t| \"slow_down\"\n\t| \"expired_token\"\n\t| \"access_denied\";\n\n// ---------------------------------------------------------------------------\n// Helpers\n// ---------------------------------------------------------------------------\n\n/** Generate a short human-readable user code (XXXX-XXXX) */\nfunction generateUserCode(): string {\n\tconst bytes = new Uint8Array(8);\n\tcrypto.getRandomValues(bytes);\n\tconst chars = Array.from(bytes, (b) => USER_CODE_CHARS[b % USER_CODE_CHARS.length]).join(\"\");\n\treturn `${chars.slice(0, 4)}-${chars.slice(4, 8)}`;\n}\n\n/** Get an ISO datetime string offset from now */\nfunction expiresAt(seconds: number): string {\n\treturn new Date(Date.now() + seconds * 1000).toISOString();\n}\n\n/** Validate and normalize scopes. Returns validated scope list. */\nfunction normalizeScopes(requested?: string[]): string[] {\n\tif (!requested || requested.length === 0) {\n\t\treturn [...DEFAULT_SCOPES];\n\t}\n\treturn [...new Set(requested.filter(isValidScope))];\n}\n\n/**\n * Scopes an approval by a user with `role` would grant:\n * requested_scopes ∩ scopesForRole(role). Approval and the approval-page\n * lookup must agree, so both go through here.\n */\nfunction grantableScopes(requested: string[], role: RoleLevel): string[] {\n\treturn clampScopes(requested, role);\n}\n\n/** Find a pending device code by user code, ignoring hyphens and case. Does not check expiry. */\nasync function findPendingDeviceCode(\n\tdb: Kysely<Database>,\n\tuserCode: string,\n): Promise<Selectable<DeviceCodeTable> | undefined> {\n\tconst chars = userCode.replace(HYPHEN_PATTERN, \"\").toUpperCase();\n\tif (chars.length !== 8) return undefined;\n\n\t// Stored codes always have the generateUserCode() shape.\n\treturn db\n\t\t.selectFrom(\"_emdash_device_codes\")\n\t\t.selectAll()\n\t\t.where(\"user_code\", \"=\", `${chars.slice(0, 4)}-${chars.slice(4)}`)\n\t\t.where(\"status\", \"=\", \"pending\")\n\t\t.executeTakeFirst();\n}\n\n// ---------------------------------------------------------------------------\n// Handlers\n// ---------------------------------------------------------------------------\n\n/**\n * POST /oauth/device/code\n *\n * Issue a device code + user code. The CLI displays the user code\n * and tells the user to open the verification URI.\n */\nexport async function handleDeviceCodeRequest(\n\tdb: Kysely<Database>,\n\tinput: {\n\t\tclient_id?: string;\n\t\tscope?: string;\n\t},\n\tverificationUri: string,\n): Promise<ApiResult<DeviceCodeResponse>> {\n\ttry {\n\t\t// Note: client_id is accepted but not validated against _emdash_oauth_clients\n\t\t// because the CLI uses a well-known built-in client ID (\"emdash-cli\") that\n\t\t// isn't stored in the DB. Full client_id validation + scope clamping for the\n\t\t// device flow is tracked as a follow-up.\n\n\t\t// Parse and validate scopes\n\t\tconst requestedScopes = input.scope ? input.scope.split(\" \").filter(Boolean) : [];\n\t\tconst scopes = normalizeScopes(requestedScopes);\n\n\t\tif (scopes.length === 0) {\n\t\t\treturn {\n\t\t\t\tsuccess: false,\n\t\t\t\terror: { code: \"INVALID_SCOPE\", message: \"No valid scopes requested\" },\n\t\t\t};\n\t\t}\n\n\t\tconst deviceCode = generateCodeVerifier();\n\t\tconst userCode = generateUserCode();\n\t\tconst expires = expiresAt(DEVICE_CODE_TTL_SECONDS);\n\n\t\tawait db\n\t\t\t.insertInto(\"_emdash_device_codes\")\n\t\t\t.values({\n\t\t\t\tdevice_code: deviceCode,\n\t\t\t\tuser_code: userCode,\n\t\t\t\tscopes: JSON.stringify(scopes),\n\t\t\t\tstatus: \"pending\",\n\t\t\t\texpires_at: expires,\n\t\t\t\tinterval: DEFAULT_INTERVAL,\n\t\t\t})\n\t\t\t.execute();\n\n\t\treturn {\n\t\t\tsuccess: true,\n\t\t\tdata: {\n\t\t\t\tdevice_code: deviceCode,\n\t\t\t\tuser_code: userCode,\n\t\t\t\tverification_uri: verificationUri,\n\t\t\t\texpires_in: DEVICE_CODE_TTL_SECONDS,\n\t\t\t\tinterval: DEFAULT_INTERVAL,\n\t\t\t},\n\t\t};\n\t} catch {\n\t\treturn {\n\t\t\tsuccess: false,\n\t\t\terror: {\n\t\t\t\tcode: \"DEVICE_CODE_ERROR\",\n\t\t\t\tmessage: \"Failed to create device code\",\n\t\t\t},\n\t\t};\n\t}\n}\n\n/**\n * POST /oauth/device/token\n *\n * CLI polls this endpoint with the device_code. Returns:\n * - 200 with tokens if authorized\n * - 400 with error \"authorization_pending\" while waiting\n * - 400 with error \"slow_down\" if polling too fast\n * - 400 with error \"expired_token\" if the code expired\n * - 400 with error \"access_denied\" if the user denied\n */\nexport async function handleDeviceTokenExchange(\n\tdb: Kysely<Database>,\n\tinput: {\n\t\tdevice_code: string;\n\t\tgrant_type: string;\n\t},\n): Promise<\n\tApiResult<TokenResponse> & { deviceFlowError?: DeviceFlowError; deviceFlowInterval?: number }\n> {\n\ttry {\n\t\t// Validate grant_type\n\t\tif (input.grant_type !== \"urn:ietf:params:oauth:grant-type:device_code\") {\n\t\t\treturn {\n\t\t\t\tsuccess: false,\n\t\t\t\terror: { code: \"UNSUPPORTED_GRANT_TYPE\", message: \"Invalid grant_type\" },\n\t\t\t};\n\t\t}\n\n\t\t// Look up the device code\n\t\tconst row = await db\n\t\t\t.selectFrom(\"_emdash_device_codes\")\n\t\t\t.selectAll()\n\t\t\t.where(\"device_code\", \"=\", input.device_code)\n\t\t\t.executeTakeFirst();\n\n\t\tif (!row) {\n\t\t\treturn {\n\t\t\t\tsuccess: false,\n\t\t\t\terror: { code: \"INVALID_GRANT\", message: \"Invalid device code\" },\n\t\t\t};\n\t\t}\n\n\t\tconst now = new Date();\n\n\t\t// Check expiry\n\t\tif (new Date(row.expires_at) < now) {\n\t\t\t// Clean up expired code\n\t\t\tawait db\n\t\t\t\t.deleteFrom(\"_emdash_device_codes\")\n\t\t\t\t.where(\"device_code\", \"=\", input.device_code)\n\t\t\t\t.execute();\n\n\t\t\treturn {\n\t\t\t\tsuccess: false,\n\t\t\t\tdeviceFlowError: \"expired_token\",\n\t\t\t\terror: { code: \"expired_token\", message: \"The device code has expired\" },\n\t\t\t};\n\t\t}\n\n\t\t// Check status\n\t\tif (row.status === \"denied\") {\n\t\t\t// Clean up denied code\n\t\t\tawait db\n\t\t\t\t.deleteFrom(\"_emdash_device_codes\")\n\t\t\t\t.where(\"device_code\", \"=\", input.device_code)\n\t\t\t\t.execute();\n\n\t\t\treturn {\n\t\t\t\tsuccess: false,\n\t\t\t\tdeviceFlowError: \"access_denied\",\n\t\t\t\terror: { code: \"access_denied\", message: \"The user denied the request\" },\n\t\t\t};\n\t\t}\n\n\t\tif (row.status === \"pending\") {\n\t\t\t// RFC 8628 §3.5: slow_down enforcement during polling phase.\n\t\t\t// Only applies while waiting for authorization — once authorized,\n\t\t\t// the final exchange proceeds without throttling.\n\t\t\tif (row.last_polled_at) {\n\t\t\t\tconst lastPolled = new Date(row.last_polled_at);\n\t\t\t\tconst elapsedSeconds = (now.getTime() - lastPolled.getTime()) / 1000;\n\n\t\t\t\tif (elapsedSeconds < row.interval) {\n\t\t\t\t\t// Too fast — increase interval by 5s per RFC 8628 §3.5, capped at 60s\n\t\t\t\t\tconst newInterval = Math.min(row.interval + SLOW_DOWN_INCREMENT, MAX_SLOW_DOWN_INTERVAL);\n\t\t\t\t\tawait db\n\t\t\t\t\t\t.updateTable(\"_emdash_device_codes\")\n\t\t\t\t\t\t.set({\n\t\t\t\t\t\t\tinterval: newInterval,\n\t\t\t\t\t\t\tlast_polled_at: now.toISOString(),\n\t\t\t\t\t\t})\n\t\t\t\t\t\t.where(\"device_code\", \"=\", input.device_code)\n\t\t\t\t\t\t.execute();\n\n\t\t\t\t\treturn {\n\t\t\t\t\t\tsuccess: false,\n\t\t\t\t\t\tdeviceFlowError: \"slow_down\",\n\t\t\t\t\t\tdeviceFlowInterval: newInterval,\n\t\t\t\t\t\terror: { code: \"slow_down\", message: \"Polling too fast\" },\n\t\t\t\t\t};\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// Update last_polled_at for future slow_down checks\n\t\t\tawait db\n\t\t\t\t.updateTable(\"_emdash_device_codes\")\n\t\t\t\t.set({ last_polled_at: now.toISOString() })\n\t\t\t\t.where(\"device_code\", \"=\", input.device_code)\n\t\t\t\t.execute();\n\n\t\t\treturn {\n\t\t\t\tsuccess: false,\n\t\t\t\tdeviceFlowError: \"authorization_pending\",\n\t\t\t\terror: { code: \"authorization_pending\", message: \"Authorization pending\" },\n\t\t\t};\n\t\t}\n\n\t\tif (row.status !== \"authorized\" || !row.user_id) {\n\t\t\treturn {\n\t\t\t\tsuccess: false,\n\t\t\t\terror: { code: \"INVALID_GRANT\", message: \"Invalid device code state\" },\n\t\t\t};\n\t\t}\n\n\t\t// Generate tokens before consuming the device code so that if\n\t\t// generation fails, the code is still available for retry.\n\t\tconst accessToken = generatePrefixedToken(TOKEN_PREFIXES.OAUTH_ACCESS);\n\t\tconst accessExpires = expiresAt(ACCESS_TOKEN_TTL_SECONDS);\n\t\tconst refreshToken = generatePrefixedToken(TOKEN_PREFIXES.OAUTH_REFRESH);\n\t\tconst refreshExpires = expiresAt(REFRESH_TOKEN_TTL_SECONDS);\n\n\t\t// Atomically consume the device code and create tokens in a single\n\t\t// transaction. DELETE...RETURNING prevents TOCTOU: two concurrent\n\t\t// requests race on the DELETE, only one gets a row back. Wrapping\n\t\t// in a transaction ensures the code isn't consumed if token storage fails.\n\t\tconst result = await withTransaction(db, async (trx) => {\n\t\t\tconst consumed = await trx\n\t\t\t\t.deleteFrom(\"_emdash_device_codes\")\n\t\t\t\t.where(\"device_code\", \"=\", input.device_code)\n\t\t\t\t.where(\"status\", \"=\", \"authorized\")\n\t\t\t\t.returningAll()\n\t\t\t\t.executeTakeFirst();\n\n\t\t\tif (!consumed) return null;\n\n\t\t\tif (!consumed.user_id) return null;\n\n\t\t\tconst scopes = JSON.parse(consumed.scopes) as string[];\n\n\t\t\tawait trx\n\t\t\t\t.insertInto(\"_emdash_oauth_tokens\")\n\t\t\t\t.values({\n\t\t\t\t\ttoken_hash: accessToken.hash,\n\t\t\t\t\ttoken_type: \"access\",\n\t\t\t\t\tuser_id: consumed.user_id,\n\t\t\t\t\tscopes: JSON.stringify(scopes),\n\t\t\t\t\tclient_type: \"cli\",\n\t\t\t\t\texpires_at: accessExpires,\n\t\t\t\t\trefresh_token_hash: refreshToken.hash,\n\t\t\t\t})\n\t\t\t\t.execute();\n\n\t\t\tawait trx\n\t\t\t\t.insertInto(\"_emdash_oauth_tokens\")\n\t\t\t\t.values({\n\t\t\t\t\ttoken_hash: refreshToken.hash,\n\t\t\t\t\ttoken_type: \"refresh\",\n\t\t\t\t\tuser_id: consumed.user_id,\n\t\t\t\t\tscopes: JSON.stringify(scopes),\n\t\t\t\t\tclient_type: \"cli\",\n\t\t\t\t\texpires_at: refreshExpires,\n\t\t\t\t\trefresh_token_hash: null,\n\t\t\t\t})\n\t\t\t\t.execute();\n\n\t\t\treturn { scopes };\n\t\t});\n\n\t\tif (!result) {\n\t\t\treturn {\n\t\t\t\tsuccess: false,\n\t\t\t\terror: { code: \"INVALID_GRANT\", message: \"Device code already consumed\" },\n\t\t\t};\n\t\t}\n\n\t\treturn {\n\t\t\tsuccess: true,\n\t\t\tdata: {\n\t\t\t\taccess_token: accessToken.raw,\n\t\t\t\trefresh_token: refreshToken.raw,\n\t\t\t\ttoken_type: \"Bearer\",\n\t\t\t\texpires_in: ACCESS_TOKEN_TTL_SECONDS,\n\t\t\t\tscope: result.scopes.join(\" \"),\n\t\t\t},\n\t\t};\n\t} catch {\n\t\treturn {\n\t\t\tsuccess: false,\n\t\t\terror: {\n\t\t\t\tcode: \"TOKEN_EXCHANGE_ERROR\",\n\t\t\t\tmessage: \"Failed to exchange device code\",\n\t\t\t},\n\t\t};\n\t}\n}\n\n/**\n * GET /oauth/device/authorize\n *\n * Returns the scopes a pending device code requested, and the subset an\n * approval by this user would grant, so the approval page can show them\n * before the user approves. Reveals nothing else about the device code.\n */\nexport async function handleDeviceCodeLookup(\n\tdb: Kysely<Database>,\n\tuserRole: RoleLevel,\n\tinput: { user_code: string },\n): Promise<ApiResult<{ requestedScopes: string[]; grantedScopes: string[] }>> {\n\ttry {\n\t\tconst match = await findPendingDeviceCode(db, input.user_code);\n\n\t\tif (!match) {\n\t\t\treturn {\n\t\t\t\tsuccess: false,\n\t\t\t\terror: { code: \"INVALID_CODE\", message: \"Invalid or expired code\" },\n\t\t\t};\n\t\t}\n\n\t\tif (new Date(match.expires_at) < new Date()) {\n\t\t\treturn {\n\t\t\t\tsuccess: false,\n\t\t\t\terror: { code: \"EXPIRED_CODE\", message: \"This code has expired\" },\n\t\t\t};\n\t\t}\n\n\t\tconst requestedScopes = JSON.parse(match.scopes) as string[];\n\n\t\treturn {\n\t\t\tsuccess: true,\n\t\t\tdata: { requestedScopes, grantedScopes: grantableScopes(requestedScopes, userRole) },\n\t\t};\n\t} catch {\n\t\treturn {\n\t\t\tsuccess: false,\n\t\t\terror: { code: \"DEVICE_CODE_LOOKUP_ERROR\", message: \"Failed to look up device code\" },\n\t\t};\n\t}\n}\n\n/**\n * POST /oauth/device/authorize\n *\n * The user submits the user_code after logging in via the browser.\n * This authorizes the device code, allowing the CLI to exchange it for tokens.\n *\n * Scopes are clamped to the user's role at this point. The stored scopes\n * are replaced with the intersection of requested scopes and the scopes\n * the user's role permits. This prevents scope escalation.\n */\nexport async function handleDeviceAuthorize(\n\tdb: Kysely<Database>,\n\tuserId: string,\n\tuserRole: RoleLevel,\n\tinput: {\n\t\tuser_code: string;\n\t\taction?: \"approve\" | \"deny\";\n\t},\n): Promise<ApiResult<{ authorized: boolean }>> {\n\ttry {\n\t\tconst match = await findPendingDeviceCode(db, input.user_code);\n\n\t\tif (!match) {\n\t\t\treturn {\n\t\t\t\tsuccess: false,\n\t\t\t\terror: { code: \"INVALID_CODE\", message: \"Invalid or expired code\" },\n\t\t\t};\n\t\t}\n\n\t\t// Check expiry\n\t\tif (new Date(match.expires_at) < new Date()) {\n\t\t\tawait db\n\t\t\t\t.deleteFrom(\"_emdash_device_codes\")\n\t\t\t\t.where(\"device_code\", \"=\", match.device_code)\n\t\t\t\t.execute();\n\n\t\t\treturn {\n\t\t\t\tsuccess: false,\n\t\t\t\terror: { code: \"EXPIRED_CODE\", message: \"This code has expired\" },\n\t\t\t};\n\t\t}\n\n\t\tconst action = input.action ?? \"approve\";\n\n\t\tif (action === \"deny\") {\n\t\t\tawait db\n\t\t\t\t.updateTable(\"_emdash_device_codes\")\n\t\t\t\t.set({ status: \"denied\" })\n\t\t\t\t.where(\"device_code\", \"=\", match.device_code)\n\t\t\t\t.execute();\n\n\t\t\treturn { success: true, data: { authorized: false } };\n\t\t}\n\n\t\tconst effectiveScopes = grantableScopes(JSON.parse(match.scopes) as string[], userRole);\n\n\t\tif (effectiveScopes.length === 0) {\n\t\t\treturn {\n\t\t\t\tsuccess: false,\n\t\t\t\terror: {\n\t\t\t\t\tcode: \"INSUFFICIENT_ROLE\",\n\t\t\t\t\tmessage: \"Your role does not permit any of the requested scopes\",\n\t\t\t\t},\n\t\t\t};\n\t\t}\n\n\t\t// Approve: set user_id, status, and clamped scopes\n\t\tawait db\n\t\t\t.updateTable(\"_emdash_device_codes\")\n\t\t\t.set({\n\t\t\t\tstatus: \"authorized\",\n\t\t\t\tuser_id: userId,\n\t\t\t\tscopes: JSON.stringify(effectiveScopes),\n\t\t\t})\n\t\t\t.where(\"device_code\", \"=\", match.device_code)\n\t\t\t.execute();\n\n\t\treturn { success: true, data: { authorized: true } };\n\t} catch {\n\t\treturn {\n\t\t\tsuccess: false,\n\t\t\terror: {\n\t\t\t\tcode: \"AUTHORIZE_ERROR\",\n\t\t\t\tmessage: \"Failed to authorize device\",\n\t\t\t},\n\t\t};\n\t}\n}\n\n/**\n * POST /oauth/token/refresh\n *\n * Exchange a refresh token for a new access token.\n * The refresh token itself is not rotated (per spec: optional rotation).\n */\nexport async function handleTokenRefresh(\n\tdb: Kysely<Database>,\n\tinput: {\n\t\trefresh_token: string;\n\t\tgrant_type: string;\n\t},\n): Promise<ApiResult<TokenResponse>> {\n\ttry {\n\t\tif (input.grant_type !== \"refresh_token\") {\n\t\t\treturn {\n\t\t\t\tsuccess: false,\n\t\t\t\terror: { code: \"UNSUPPORTED_GRANT_TYPE\", message: \"Invalid grant_type\" },\n\t\t\t};\n\t\t}\n\n\t\tif (!input.refresh_token.startsWith(TOKEN_PREFIXES.OAUTH_REFRESH)) {\n\t\t\treturn {\n\t\t\t\tsuccess: false,\n\t\t\t\terror: { code: \"INVALID_GRANT\", message: \"Invalid refresh token format\" },\n\t\t\t};\n\t\t}\n\n\t\tconst refreshHash = hashApiToken(input.refresh_token);\n\n\t\tconst row = await db\n\t\t\t.selectFrom(\"_emdash_oauth_tokens\")\n\t\t\t.selectAll()\n\t\t\t.where(\"token_hash\", \"=\", refreshHash)\n\t\t\t.where(\"token_type\", \"=\", \"refresh\")\n\t\t\t.executeTakeFirst();\n\n\t\tif (!row) {\n\t\t\treturn {\n\t\t\t\tsuccess: false,\n\t\t\t\terror: { code: \"INVALID_GRANT\", message: \"Invalid refresh token\" },\n\t\t\t};\n\t\t}\n\n\t\t// Check expiry\n\t\tif (new Date(row.expires_at) < new Date()) {\n\t\t\t// Clean up expired refresh token and its access tokens\n\t\t\tawait db.deleteFrom(\"_emdash_oauth_tokens\").where(\"token_hash\", \"=\", refreshHash).execute();\n\t\t\tawait db\n\t\t\t\t.deleteFrom(\"_emdash_oauth_tokens\")\n\t\t\t\t.where(\"refresh_token_hash\", \"=\", refreshHash)\n\t\t\t\t.execute();\n\n\t\t\treturn {\n\t\t\t\tsuccess: false,\n\t\t\t\terror: { code: \"INVALID_GRANT\", message: \"Refresh token expired\" },\n\t\t\t};\n\t\t}\n\n\t\t// SEC-42: Revalidate user role before issuing new access token.\n\t\t// SEC-43: Reject refresh if user is disabled or deleted.\n\t\tconst userInfo = await lookupUserRoleAndStatus(db, row.user_id);\n\t\tif (!userInfo) {\n\t\t\t// User no longer exists — revoke all their tokens\n\t\t\tawait db.deleteFrom(\"_emdash_oauth_tokens\").where(\"user_id\", \"=\", row.user_id).execute();\n\t\t\treturn {\n\t\t\t\tsuccess: false,\n\t\t\t\terror: { code: \"INVALID_GRANT\", message: \"User not found\" },\n\t\t\t};\n\t\t}\n\n\t\tif (userInfo.disabled) {\n\t\t\t// User is disabled — revoke all their tokens\n\t\t\tawait db.deleteFrom(\"_emdash_oauth_tokens\").where(\"user_id\", \"=\", row.user_id).execute();\n\t\t\treturn {\n\t\t\t\tsuccess: false,\n\t\t\t\terror: { code: \"INVALID_GRANT\", message: \"User account is disabled\" },\n\t\t\t};\n\t\t}\n\n\t\t// Revalidate stored scopes against the user's current role.\n\t\t// A demoted user's refresh token may carry stale elevated scopes.\n\t\tconst storedScopes = JSON.parse(row.scopes) as string[];\n\t\tlet scopes = clampScopes(storedScopes, userInfo.role);\n\n\t\t// SEC-41: Intersect with the client's registered scopes (if any).\n\t\t// Same check as the approval path — a client registered with limited\n\t\t// scopes should never receive elevated scopes on refresh, even if the\n\t\t// user's role would allow them.\n\t\tif (row.client_id) {\n\t\t\tconst client = await lookupOAuthClient(db, row.client_id);\n\t\t\tif (client?.scopes?.length) {\n\t\t\t\tscopes = scopes.filter((s: string) => client.scopes!.includes(s));\n\t\t\t}\n\t\t}\n\n\t\tif (scopes.length === 0) {\n\t\t\t// User's role no longer supports any of the token's scopes — revoke\n\t\t\tawait db.deleteFrom(\"_emdash_oauth_tokens\").where(\"token_hash\", \"=\", refreshHash).execute();\n\t\t\tawait db\n\t\t\t\t.deleteFrom(\"_emdash_oauth_tokens\")\n\t\t\t\t.where(\"refresh_token_hash\", \"=\", refreshHash)\n\t\t\t\t.execute();\n\t\t\treturn {\n\t\t\t\tsuccess: false,\n\t\t\t\terror: {\n\t\t\t\t\tcode: \"INVALID_GRANT\",\n\t\t\t\t\tmessage: \"User role no longer supports any of the token's scopes\",\n\t\t\t\t},\n\t\t\t};\n\t\t}\n\n\t\t// Delete old access tokens for this refresh token\n\t\tawait db\n\t\t\t.deleteFrom(\"_emdash_oauth_tokens\")\n\t\t\t.where(\"refresh_token_hash\", \"=\", refreshHash)\n\t\t\t.where(\"token_type\", \"=\", \"access\")\n\t\t\t.execute();\n\n\t\t// Generate new access token\n\t\tconst accessToken = generatePrefixedToken(TOKEN_PREFIXES.OAUTH_ACCESS);\n\t\tconst accessExpires = expiresAt(ACCESS_TOKEN_TTL_SECONDS);\n\n\t\tawait db\n\t\t\t.insertInto(\"_emdash_oauth_tokens\")\n\t\t\t.values({\n\t\t\t\ttoken_hash: accessToken.hash,\n\t\t\t\ttoken_type: \"access\",\n\t\t\t\tuser_id: row.user_id,\n\t\t\t\tscopes: JSON.stringify(scopes),\n\t\t\t\tclient_type: row.client_type,\n\t\t\t\texpires_at: accessExpires,\n\t\t\t\trefresh_token_hash: refreshHash,\n\t\t\t})\n\t\t\t.execute();\n\n\t\treturn {\n\t\t\tsuccess: true,\n\t\t\tdata: {\n\t\t\t\taccess_token: accessToken.raw,\n\t\t\t\trefresh_token: input.refresh_token, // Return same refresh token\n\t\t\t\ttoken_type: \"Bearer\",\n\t\t\t\texpires_in: ACCESS_TOKEN_TTL_SECONDS,\n\t\t\t\tscope: scopes.join(\" \"),\n\t\t\t},\n\t\t};\n\t} catch {\n\t\treturn {\n\t\t\tsuccess: false,\n\t\t\terror: {\n\t\t\t\tcode: \"TOKEN_REFRESH_ERROR\",\n\t\t\t\tmessage: \"Failed to refresh token\",\n\t\t\t},\n\t\t};\n\t}\n}\n\n/**\n * POST /oauth/token/revoke\n *\n * Revoke an access or refresh token. If a refresh token is revoked,\n * also revoke all associated access tokens.\n *\n * Per RFC 7009, this endpoint always returns 200 (even for invalid tokens).\n */\nexport async function handleTokenRevoke(\n\tdb: Kysely<Database>,\n\tinput: {\n\t\ttoken: string;\n\t},\n): Promise<ApiResult<{ revoked: boolean }>> {\n\ttry {\n\t\tconst hash = hashApiToken(input.token);\n\n\t\t// Look up the token\n\t\tconst row = await db\n\t\t\t.selectFrom(\"_emdash_oauth_tokens\")\n\t\t\t.select([\"token_hash\", \"token_type\", \"refresh_token_hash\"])\n\t\t\t.where(\"token_hash\", \"=\", hash)\n\t\t\t.executeTakeFirst();\n\n\t\tif (!row) {\n\t\t\t// Per RFC 7009: always 200, even for invalid tokens\n\t\t\treturn { success: true, data: { revoked: true } };\n\t\t}\n\n\t\tif (row.token_type === \"refresh\") {\n\t\t\t// Revoke refresh token and all its access tokens\n\t\t\tawait db.deleteFrom(\"_emdash_oauth_tokens\").where(\"refresh_token_hash\", \"=\", hash).execute();\n\t\t\tawait db.deleteFrom(\"_emdash_oauth_tokens\").where(\"token_hash\", \"=\", hash).execute();\n\t\t} else {\n\t\t\t// Revoke just the access token\n\t\t\tawait db.deleteFrom(\"_emdash_oauth_tokens\").where(\"token_hash\", \"=\", hash).execute();\n\t\t}\n\n\t\treturn { success: true, data: { revoked: true } };\n\t} catch {\n\t\treturn {\n\t\t\tsuccess: false,\n\t\t\terror: {\n\t\t\t\tcode: \"TOKEN_REVOKE_ERROR\",\n\t\t\t\tmessage: \"Failed to revoke token\",\n\t\t\t},\n\t\t};\n\t}\n}\n"],"mappings":"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"}
|
|
@@ -0,0 +1,194 @@
|
|
|
1
|
+
import { n as canonicalJson } from "./canonical-CcSuuTlH.mjs";
|
|
2
|
+
import { SHA256 } from "@oslojs/crypto/sha2";
|
|
3
|
+
import { encodeHexLowerCase } from "@oslojs/encoding";
|
|
4
|
+
|
|
5
|
+
//#region src/transfer/format/digest.ts
|
|
6
|
+
/**
|
|
7
|
+
* SHA-256 hashing and the digests that identify packages, plans, receipts,
|
|
8
|
+
* and verified target state.
|
|
9
|
+
*
|
|
10
|
+
* Digest rules (formatVersion "1"):
|
|
11
|
+
* - `packageDigest = "sha256:" + hex(sha256(utf8(canonicalJson(manifest))))`
|
|
12
|
+
* - `planDigest = "sha256:" + hex(sha256(utf8(canonicalJson(plan))))` over the
|
|
13
|
+
* complete {@link SiteImportPlan} including its `decisions`, `packageDigest`
|
|
14
|
+
* and `target.siteId`, so a plan cannot be replayed against another package
|
|
15
|
+
* or target.
|
|
16
|
+
* - `receiptDigest` covers the receipt with its `receiptDigest` property
|
|
17
|
+
* removed.
|
|
18
|
+
* - A record's hash is the hex SHA-256 of its canonical JSON (the NDJSON line
|
|
19
|
+
* without its newline).
|
|
20
|
+
* - A chunk's logical hash is
|
|
21
|
+
* `hex(sha256(utf8(canonicalJson([[id, recordSha256], …]))))` over the
|
|
22
|
+
* records of one package record chunk, in chunk order, each record in its
|
|
23
|
+
* predicted target form (after declared transformations).
|
|
24
|
+
* - `logicalDigest = "sha256:" + hex(sha256(utf8(canonicalJson(chunks))))`
|
|
25
|
+
* where `chunks` is `[[kind, seq, chunkLogicalSha256], …]` for every record
|
|
26
|
+
* chunk in package order (kinds in `RECORD_KINDS` order, then `seq`).
|
|
27
|
+
* `principal` chunks are excluded because principals are never written to
|
|
28
|
+
* a target. The two-level shape lets verification run in bounded steps and
|
|
29
|
+
* persist one hash per chunk instead of an in-progress hash state.
|
|
30
|
+
*/
|
|
31
|
+
const SHA256_HEX_PATTERN = /^[0-9a-f]{64}$/;
|
|
32
|
+
const SHA256_DIGEST_PATTERN = /^sha256:[0-9a-f]{64}$/;
|
|
33
|
+
function isSha256Hex(value) {
|
|
34
|
+
return typeof value === "string" && SHA256_HEX_PATTERN.test(value);
|
|
35
|
+
}
|
|
36
|
+
function isSha256Digest(value) {
|
|
37
|
+
return typeof value === "string" && SHA256_DIGEST_PATTERN.test(value);
|
|
38
|
+
}
|
|
39
|
+
function toSha256Digest(hex) {
|
|
40
|
+
if (!isSha256Hex(hex)) throw new TypeError("Expected a lowercase hex SHA-256");
|
|
41
|
+
return `sha256:${hex}`;
|
|
42
|
+
}
|
|
43
|
+
function isDigestStreamConstructor(value) {
|
|
44
|
+
return typeof value === "function";
|
|
45
|
+
}
|
|
46
|
+
function isNodeCreateHash(value) {
|
|
47
|
+
return typeof value === "function";
|
|
48
|
+
}
|
|
49
|
+
function getDigestStream() {
|
|
50
|
+
const candidate = typeof globalThis.crypto === "object" ? Reflect.get(globalThis.crypto, "DigestStream") : void 0;
|
|
51
|
+
return isDigestStreamConstructor(candidate) ? candidate : void 0;
|
|
52
|
+
}
|
|
53
|
+
function isNodeRuntime() {
|
|
54
|
+
const processLike = Reflect.get(globalThis, "process");
|
|
55
|
+
if (typeof processLike !== "object" || processLike === null) return false;
|
|
56
|
+
const versions = Reflect.get(processLike, "versions");
|
|
57
|
+
return typeof versions === "object" && versions !== null && typeof Reflect.get(versions, "node") === "string";
|
|
58
|
+
}
|
|
59
|
+
let nodeCreateHash;
|
|
60
|
+
function loadNodeCreateHash() {
|
|
61
|
+
nodeCreateHash ??= (async () => {
|
|
62
|
+
if (!isNodeRuntime()) return null;
|
|
63
|
+
try {
|
|
64
|
+
const nodeCrypto = await import("node:crypto");
|
|
65
|
+
return isNodeCreateHash(nodeCrypto.createHash) ? nodeCrypto.createHash : null;
|
|
66
|
+
} catch {
|
|
67
|
+
return null;
|
|
68
|
+
}
|
|
69
|
+
})();
|
|
70
|
+
return nodeCreateHash;
|
|
71
|
+
}
|
|
72
|
+
async function preferredBackend() {
|
|
73
|
+
if (getDigestStream()) return "digest-stream";
|
|
74
|
+
if (await loadNodeCreateHash()) return "node";
|
|
75
|
+
return "oslo";
|
|
76
|
+
}
|
|
77
|
+
var DigestStreamHasher = class {
|
|
78
|
+
backend = "digest-stream";
|
|
79
|
+
#stream;
|
|
80
|
+
#writer;
|
|
81
|
+
#failure;
|
|
82
|
+
constructor(DigestStream) {
|
|
83
|
+
this.#stream = new DigestStream("SHA-256");
|
|
84
|
+
this.#writer = this.#stream.getWriter();
|
|
85
|
+
}
|
|
86
|
+
update(chunk) {
|
|
87
|
+
this.#writer.write(chunk.slice()).catch((error) => {
|
|
88
|
+
this.#failure ??= error;
|
|
89
|
+
});
|
|
90
|
+
}
|
|
91
|
+
async digest() {
|
|
92
|
+
await this.#writer.close();
|
|
93
|
+
if (this.#failure !== void 0) throw this.#failure;
|
|
94
|
+
return encodeHexLowerCase(new Uint8Array(await this.#stream.digest));
|
|
95
|
+
}
|
|
96
|
+
};
|
|
97
|
+
var NodeHasher = class {
|
|
98
|
+
backend = "node";
|
|
99
|
+
#hash;
|
|
100
|
+
constructor(createHash) {
|
|
101
|
+
this.#hash = createHash("sha256");
|
|
102
|
+
}
|
|
103
|
+
update(chunk) {
|
|
104
|
+
this.#hash.update(chunk);
|
|
105
|
+
}
|
|
106
|
+
async digest() {
|
|
107
|
+
return this.#hash.digest("hex");
|
|
108
|
+
}
|
|
109
|
+
};
|
|
110
|
+
var OsloHasher = class {
|
|
111
|
+
backend = "oslo";
|
|
112
|
+
#hash = new SHA256();
|
|
113
|
+
update(chunk) {
|
|
114
|
+
this.#hash.update(chunk);
|
|
115
|
+
}
|
|
116
|
+
async digest() {
|
|
117
|
+
return encodeHexLowerCase(this.#hash.digest());
|
|
118
|
+
}
|
|
119
|
+
};
|
|
120
|
+
async function createSha256(options = {}) {
|
|
121
|
+
switch (options.backend ?? await preferredBackend()) {
|
|
122
|
+
case "digest-stream": {
|
|
123
|
+
const DigestStream = getDigestStream();
|
|
124
|
+
if (!DigestStream) throw new Error("crypto.DigestStream is not available");
|
|
125
|
+
return new DigestStreamHasher(DigestStream);
|
|
126
|
+
}
|
|
127
|
+
case "node": {
|
|
128
|
+
const createHash = await loadNodeCreateHash();
|
|
129
|
+
if (!createHash) throw new Error("node:crypto is not available");
|
|
130
|
+
return new NodeHasher(createHash);
|
|
131
|
+
}
|
|
132
|
+
case "oslo": return new OsloHasher();
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
const encoder = new TextEncoder();
|
|
136
|
+
async function sha256Hex(data) {
|
|
137
|
+
const bytes = typeof data === "string" ? encoder.encode(data) : data;
|
|
138
|
+
const hasher = await createSha256();
|
|
139
|
+
hasher.update(bytes);
|
|
140
|
+
return hasher.digest();
|
|
141
|
+
}
|
|
142
|
+
/** `"sha256:" + hex(sha256(utf8(canonicalJson(value))))`. */
|
|
143
|
+
async function canonicalDigest(value) {
|
|
144
|
+
return toSha256Digest(await sha256Hex(canonicalJson(value)));
|
|
145
|
+
}
|
|
146
|
+
/** Hex SHA-256 of a record's canonical JSON (its NDJSON line without the newline). */
|
|
147
|
+
async function recordSha256(record) {
|
|
148
|
+
return sha256Hex(canonicalJson(record));
|
|
149
|
+
}
|
|
150
|
+
function packageDigest(manifest) {
|
|
151
|
+
return canonicalDigest(manifest);
|
|
152
|
+
}
|
|
153
|
+
function planDigest(plan) {
|
|
154
|
+
return canonicalDigest(plan);
|
|
155
|
+
}
|
|
156
|
+
/** Digest over a receipt without its own `receiptDigest` property. */
|
|
157
|
+
function receiptDigest(receipt) {
|
|
158
|
+
const { receiptDigest: _ignored, ...rest } = receipt;
|
|
159
|
+
return canonicalDigest(rest);
|
|
160
|
+
}
|
|
161
|
+
/** Hex logical hash of one record chunk from its `[id, recordSha256]` pairs in chunk order. */
|
|
162
|
+
async function chunkLogicalSha256(records) {
|
|
163
|
+
for (const [, sha] of records) if (!isSha256Hex(sha)) throw new TypeError("Expected a lowercase hex SHA-256");
|
|
164
|
+
return sha256Hex(canonicalJson(records.map(([id, sha]) => [id, sha])));
|
|
165
|
+
}
|
|
166
|
+
/** `logicalDigest` from `[kind, seq, chunkLogicalSha256]` tuples in package order. */
|
|
167
|
+
async function logicalDigest(chunks) {
|
|
168
|
+
for (const [, , sha] of chunks) if (!isSha256Hex(sha)) throw new TypeError("Expected a lowercase hex SHA-256");
|
|
169
|
+
return canonicalDigest(chunks.map(([kind, seq, sha]) => [
|
|
170
|
+
kind,
|
|
171
|
+
seq,
|
|
172
|
+
sha
|
|
173
|
+
]));
|
|
174
|
+
}
|
|
175
|
+
/**
|
|
176
|
+
* Pass-through stream that feeds every chunk to `hasher` and counts bytes.
|
|
177
|
+
* Throws inside the stream as soon as more than `maxBytes` flow through.
|
|
178
|
+
*/
|
|
179
|
+
function createHashingStream(hasher, options = {}) {
|
|
180
|
+
let total = 0;
|
|
181
|
+
return {
|
|
182
|
+
stream: new TransformStream({ transform(chunk, controller) {
|
|
183
|
+
total += chunk.byteLength;
|
|
184
|
+
if (options.maxBytes !== void 0 && total > options.maxBytes) throw options.onLimitExceeded?.() ?? /* @__PURE__ */ new RangeError("Stream exceeded its declared size");
|
|
185
|
+
hasher.update(chunk);
|
|
186
|
+
controller.enqueue(chunk);
|
|
187
|
+
} }),
|
|
188
|
+
bytes: () => total
|
|
189
|
+
};
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
//#endregion
|
|
193
|
+
export { isSha256Digest as a, planDigest as c, sha256Hex as d, toSha256Digest as f, createSha256 as i, receiptDigest as l, chunkLogicalSha256 as n, logicalDigest as o, createHashingStream as r, packageDigest as s, canonicalDigest as t, recordSha256 as u };
|
|
194
|
+
//# sourceMappingURL=digest-DVZ--cE9.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"digest-DVZ--cE9.mjs","names":["#stream","#writer","#failure","#hash"],"sources":["../src/transfer/format/digest.ts"],"sourcesContent":["/**\n * SHA-256 hashing and the digests that identify packages, plans, receipts,\n * and verified target state.\n *\n * Digest rules (formatVersion \"1\"):\n * - `packageDigest = \"sha256:\" + hex(sha256(utf8(canonicalJson(manifest))))`\n * - `planDigest = \"sha256:\" + hex(sha256(utf8(canonicalJson(plan))))` over the\n * complete {@link SiteImportPlan} including its `decisions`, `packageDigest`\n * and `target.siteId`, so a plan cannot be replayed against another package\n * or target.\n * - `receiptDigest` covers the receipt with its `receiptDigest` property\n * removed.\n * - A record's hash is the hex SHA-256 of its canonical JSON (the NDJSON line\n * without its newline).\n * - A chunk's logical hash is\n * `hex(sha256(utf8(canonicalJson([[id, recordSha256], …]))))` over the\n * records of one package record chunk, in chunk order, each record in its\n * predicted target form (after declared transformations).\n * - `logicalDigest = \"sha256:\" + hex(sha256(utf8(canonicalJson(chunks))))`\n * where `chunks` is `[[kind, seq, chunkLogicalSha256], …]` for every record\n * chunk in package order (kinds in `RECORD_KINDS` order, then `seq`).\n * `principal` chunks are excluded because principals are never written to\n * a target. The two-level shape lets verification run in bounded steps and\n * persist one hash per chunk instead of an in-progress hash state.\n */\n\nimport { SHA256 } from \"@oslojs/crypto/sha2\";\nimport { encodeHexLowerCase } from \"@oslojs/encoding\";\n\nimport { canonicalJson } from \"./canonical.js\";\n\nexport type Sha256Digest = `sha256:${string}`;\n\nconst SHA256_HEX_PATTERN = /^[0-9a-f]{64}$/;\nconst SHA256_DIGEST_PATTERN = /^sha256:[0-9a-f]{64}$/;\n\nexport function isSha256Hex(value: unknown): value is string {\n\treturn typeof value === \"string\" && SHA256_HEX_PATTERN.test(value);\n}\n\nexport function isSha256Digest(value: unknown): value is Sha256Digest {\n\treturn typeof value === \"string\" && SHA256_DIGEST_PATTERN.test(value);\n}\n\nexport function toSha256Digest(hex: string): Sha256Digest {\n\tif (!isSha256Hex(hex)) throw new TypeError(\"Expected a lowercase hex SHA-256\");\n\treturn `sha256:${hex}`;\n}\n\nexport function sha256HexOf(digest: Sha256Digest): string {\n\tif (!isSha256Digest(digest)) throw new TypeError(\"Expected a sha256: digest\");\n\treturn digest.slice(\"sha256:\".length);\n}\n\n/** Incremental SHA-256. `update` never retains the chunk after it returns. */\nexport interface Sha256Hasher {\n\treadonly backend: Sha256Backend;\n\tupdate(chunk: Uint8Array): void;\n\t/** Lowercase hex digest. The hasher must not be used afterwards. */\n\tdigest(): Promise<string>;\n}\n\nexport type Sha256Backend = \"digest-stream\" | \"node\" | \"oslo\";\n\ninterface DigestStreamLike extends WritableStream<ArrayBufferView | ArrayBuffer> {\n\treadonly digest: Promise<ArrayBuffer>;\n}\n\ntype DigestStreamConstructor = new (algorithm: string) => DigestStreamLike;\n\ninterface NodeHash {\n\tupdate(data: Uint8Array): unknown;\n\tdigest(encoding: \"hex\"): string;\n}\n\ntype NodeCreateHash = (algorithm: string) => NodeHash;\n\nfunction isDigestStreamConstructor(value: unknown): value is DigestStreamConstructor {\n\treturn typeof value === \"function\";\n}\n\nfunction isNodeCreateHash(value: unknown): value is NodeCreateHash {\n\treturn typeof value === \"function\";\n}\n\nfunction getDigestStream(): DigestStreamConstructor | undefined {\n\tconst candidate: unknown =\n\t\ttypeof globalThis.crypto === \"object\"\n\t\t\t? Reflect.get(globalThis.crypto, \"DigestStream\")\n\t\t\t: undefined;\n\treturn isDigestStreamConstructor(candidate) ? candidate : undefined;\n}\n\nfunction isNodeRuntime(): boolean {\n\tconst processLike: unknown = Reflect.get(globalThis, \"process\");\n\tif (typeof processLike !== \"object\" || processLike === null) return false;\n\tconst versions: unknown = Reflect.get(processLike, \"versions\");\n\treturn (\n\t\ttypeof versions === \"object\" &&\n\t\tversions !== null &&\n\t\ttypeof Reflect.get(versions, \"node\") === \"string\"\n\t);\n}\n\nlet nodeCreateHash: Promise<NodeCreateHash | null> | undefined;\n\nfunction loadNodeCreateHash(): Promise<NodeCreateHash | null> {\n\tnodeCreateHash ??= (async () => {\n\t\tif (!isNodeRuntime()) return null;\n\t\ttry {\n\t\t\tconst nodeCrypto: { createHash?: unknown } = await import(\"node:crypto\");\n\t\t\treturn isNodeCreateHash(nodeCrypto.createHash) ? nodeCrypto.createHash : null;\n\t\t} catch {\n\t\t\treturn null;\n\t\t}\n\t})();\n\treturn nodeCreateHash;\n}\n\nasync function preferredBackend(): Promise<Sha256Backend> {\n\tif (getDigestStream()) return \"digest-stream\";\n\tif (await loadNodeCreateHash()) return \"node\";\n\treturn \"oslo\";\n}\n\nclass DigestStreamHasher implements Sha256Hasher {\n\treadonly backend = \"digest-stream\";\n\treadonly #stream: DigestStreamLike;\n\treadonly #writer: WritableStreamDefaultWriter<ArrayBufferView | ArrayBuffer>;\n\t#failure: unknown;\n\n\tconstructor(DigestStream: DigestStreamConstructor) {\n\t\tthis.#stream = new DigestStream(\"SHA-256\");\n\t\tthis.#writer = this.#stream.getWriter();\n\t}\n\n\tupdate(chunk: Uint8Array): void {\n\t\t// DigestStream consumes its input asynchronously; copy so the caller\n\t\t// may reuse its buffer as soon as update() returns.\n\t\tthis.#writer.write(chunk.slice()).catch((error: unknown) => {\n\t\t\tthis.#failure ??= error;\n\t\t});\n\t}\n\n\tasync digest(): Promise<string> {\n\t\tawait this.#writer.close();\n\t\tif (this.#failure !== undefined) throw this.#failure;\n\t\treturn encodeHexLowerCase(new Uint8Array(await this.#stream.digest));\n\t}\n}\n\nclass NodeHasher implements Sha256Hasher {\n\treadonly backend = \"node\";\n\treadonly #hash: NodeHash;\n\n\tconstructor(createHash: NodeCreateHash) {\n\t\tthis.#hash = createHash(\"sha256\");\n\t}\n\n\tupdate(chunk: Uint8Array): void {\n\t\tthis.#hash.update(chunk);\n\t}\n\n\tasync digest(): Promise<string> {\n\t\treturn this.#hash.digest(\"hex\");\n\t}\n}\n\nclass OsloHasher implements Sha256Hasher {\n\treadonly backend = \"oslo\";\n\treadonly #hash = new SHA256();\n\n\tupdate(chunk: Uint8Array): void {\n\t\tthis.#hash.update(chunk);\n\t}\n\n\tasync digest(): Promise<string> {\n\t\treturn encodeHexLowerCase(this.#hash.digest());\n\t}\n}\n\n/**\n * Backends usable in this runtime, most preferred first: `crypto.DigestStream`\n * (workerd), `node:crypto`, then the pure-JS oslo implementation.\n */\nexport async function availableSha256Backends(): Promise<Sha256Backend[]> {\n\tconst backends: Sha256Backend[] = [];\n\tif (getDigestStream()) backends.push(\"digest-stream\");\n\tif (await loadNodeCreateHash()) backends.push(\"node\");\n\tbackends.push(\"oslo\");\n\treturn backends;\n}\n\nexport async function createSha256(\n\toptions: { backend?: Sha256Backend } = {},\n): Promise<Sha256Hasher> {\n\tconst backend = options.backend ?? (await preferredBackend());\n\tswitch (backend) {\n\t\tcase \"digest-stream\": {\n\t\t\tconst DigestStream = getDigestStream();\n\t\t\tif (!DigestStream) throw new Error(\"crypto.DigestStream is not available\");\n\t\t\treturn new DigestStreamHasher(DigestStream);\n\t\t}\n\t\tcase \"node\": {\n\t\t\tconst createHash = await loadNodeCreateHash();\n\t\t\tif (!createHash) throw new Error(\"node:crypto is not available\");\n\t\t\treturn new NodeHasher(createHash);\n\t\t}\n\t\tcase \"oslo\":\n\t\t\treturn new OsloHasher();\n\t}\n}\n\nconst encoder = new TextEncoder();\n\nexport async function sha256Hex(data: Uint8Array | string): Promise<string> {\n\tconst bytes = typeof data === \"string\" ? encoder.encode(data) : data;\n\tconst hasher = await createSha256();\n\thasher.update(bytes);\n\treturn hasher.digest();\n}\n\n/** `\"sha256:\" + hex(sha256(utf8(canonicalJson(value))))`. */\nexport async function canonicalDigest(value: unknown): Promise<Sha256Digest> {\n\treturn toSha256Digest(await sha256Hex(canonicalJson(value)));\n}\n\n/** Hex SHA-256 of a record's canonical JSON (its NDJSON line without the newline). */\nexport async function recordSha256(record: unknown): Promise<string> {\n\treturn sha256Hex(canonicalJson(record));\n}\n\nexport function packageDigest(manifest: unknown): Promise<Sha256Digest> {\n\treturn canonicalDigest(manifest);\n}\n\nexport function planDigest(plan: unknown): Promise<Sha256Digest> {\n\treturn canonicalDigest(plan);\n}\n\n/** Digest over a receipt without its own `receiptDigest` property. */\nexport function receiptDigest(receipt: Record<string, unknown>): Promise<Sha256Digest> {\n\tconst { receiptDigest: _ignored, ...rest } = receipt;\n\treturn canonicalDigest(rest);\n}\n\n/** Hex logical hash of one record chunk from its `[id, recordSha256]` pairs in chunk order. */\nexport async function chunkLogicalSha256(\n\trecords: ReadonlyArray<readonly [id: string, recordSha256: string]>,\n): Promise<string> {\n\tfor (const [, sha] of records) {\n\t\tif (!isSha256Hex(sha)) throw new TypeError(\"Expected a lowercase hex SHA-256\");\n\t}\n\treturn sha256Hex(canonicalJson(records.map(([id, sha]) => [id, sha])));\n}\n\n/** `logicalDigest` from `[kind, seq, chunkLogicalSha256]` tuples in package order. */\nexport async function logicalDigest(\n\tchunks: ReadonlyArray<readonly [kind: string, seq: number, chunkLogicalSha256: string]>,\n): Promise<Sha256Digest> {\n\tfor (const [, , sha] of chunks) {\n\t\tif (!isSha256Hex(sha)) throw new TypeError(\"Expected a lowercase hex SHA-256\");\n\t}\n\treturn canonicalDigest(chunks.map(([kind, seq, sha]) => [kind, seq, sha]));\n}\n\n/**\n * Pass-through stream that feeds every chunk to `hasher` and counts bytes.\n * Throws inside the stream as soon as more than `maxBytes` flow through.\n */\nexport function createHashingStream(\n\thasher: Sha256Hasher,\n\toptions: { maxBytes?: number; onLimitExceeded?: () => unknown } = {},\n): { stream: TransformStream<Uint8Array, Uint8Array>; bytes: () => number } {\n\tlet total = 0;\n\tconst stream = new TransformStream<Uint8Array, Uint8Array>({\n\t\ttransform(chunk, controller) {\n\t\t\ttotal += chunk.byteLength;\n\t\t\tif (options.maxBytes !== undefined && total > options.maxBytes) {\n\t\t\t\tthrow options.onLimitExceeded?.() ?? new RangeError(\"Stream exceeded its declared size\");\n\t\t\t}\n\t\t\thasher.update(chunk);\n\t\t\tcontroller.enqueue(chunk);\n\t\t},\n\t});\n\treturn { stream, bytes: () => total };\n}\n"],"mappings":"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"}
|
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
import { i as getExactMigrationStatus, s as runMigrations } from "./runner-B3eyB9Gb.mjs";
|
|
2
|
+
import { clearMigrationLock, readMigrationLock } from "./database/migration-lock.mjs";
|
|
3
|
+
import { c as setI18nConfig, r as getI18nConfig } from "./config-CvmjJcVw.mjs";
|
|
4
|
+
import { r as getCoreMigrationIdentity } from "./identity-NVTOOQyq.mjs";
|
|
5
|
+
import { Kysely } from "kysely";
|
|
6
|
+
|
|
7
|
+
//#region src/migrations/direct-executor.ts
|
|
8
|
+
const LOCK_ID_PATTERN = /^[1-9]\d{0,15}$/;
|
|
9
|
+
function createReport(target, status, executed, lockHeldSince = null) {
|
|
10
|
+
const report = {
|
|
11
|
+
target,
|
|
12
|
+
knownApplied: [...status.knownApplied],
|
|
13
|
+
pending: [...status.pending],
|
|
14
|
+
unknownApplied: [...status.unknownApplied],
|
|
15
|
+
executed: [...executed]
|
|
16
|
+
};
|
|
17
|
+
if (lockHeldSince !== null) report.lock = {
|
|
18
|
+
id: String(lockHeldSince),
|
|
19
|
+
heldSince: new Date(lockHeldSince).toISOString()
|
|
20
|
+
};
|
|
21
|
+
return report;
|
|
22
|
+
}
|
|
23
|
+
async function releaseLock(db, lockId) {
|
|
24
|
+
if (!lockId || !LOCK_ID_PATTERN.test(lockId)) throw new Error("Releasing the migration lock requires the lock id reported by status.");
|
|
25
|
+
const lock = Number(lockId);
|
|
26
|
+
const heldSince = await readMigrationLock(db);
|
|
27
|
+
if (heldSince === lock && await clearMigrationLock(db, lock)) return;
|
|
28
|
+
const current = heldSince === lock ? await readMigrationLock(db) : heldSince;
|
|
29
|
+
throw new Error(current === null ? "The migration lock is not held." : "The migration lock has a different id now. Check the status again before releasing it.");
|
|
30
|
+
}
|
|
31
|
+
async function verifyRequest(request) {
|
|
32
|
+
const identity = await getCoreMigrationIdentity();
|
|
33
|
+
if (request.artifact.emdashVersion !== identity.emdashVersion || request.artifact.migrationSetFingerprint !== identity.fingerprint) throw new Error("Migration artifact does not match the loaded EmDash version and migration registry.");
|
|
34
|
+
}
|
|
35
|
+
async function executeRequest(db, target, request) {
|
|
36
|
+
const initialStatus = await getExactMigrationStatus(db);
|
|
37
|
+
if (request.action === "check") return createReport(target, initialStatus, [], await readMigrationLock(db));
|
|
38
|
+
if (request.action === "release-lock") {
|
|
39
|
+
await releaseLock(db, request.lockId);
|
|
40
|
+
return createReport(target, initialStatus, []);
|
|
41
|
+
}
|
|
42
|
+
if (initialStatus.unknownApplied.length > 0) throw new Error(`Cannot apply migrations with unknown applied migrations: ${initialStatus.unknownApplied.join(", ")}`);
|
|
43
|
+
if (initialStatus.pending.length === 0) return createReport(target, initialStatus, []);
|
|
44
|
+
const result = await runMigrations(db);
|
|
45
|
+
return createReport(target, await getExactMigrationStatus(db), result.applied);
|
|
46
|
+
}
|
|
47
|
+
function createDirectMigrationExecutor(options) {
|
|
48
|
+
const target = Object.freeze({ ...options.target });
|
|
49
|
+
let used = false;
|
|
50
|
+
let disposed = false;
|
|
51
|
+
let activeDb;
|
|
52
|
+
let closePromise;
|
|
53
|
+
const closeActiveDb = () => {
|
|
54
|
+
if (!activeDb) return Promise.resolve();
|
|
55
|
+
closePromise ??= activeDb.destroy();
|
|
56
|
+
return closePromise;
|
|
57
|
+
};
|
|
58
|
+
return {
|
|
59
|
+
target,
|
|
60
|
+
async execute(request) {
|
|
61
|
+
if (disposed) throw new Error("Migration executor has been disposed.");
|
|
62
|
+
if (used) throw new Error("Migration executors are single-use.");
|
|
63
|
+
used = true;
|
|
64
|
+
if (request.action !== "check" && request.action !== "apply" && request.action !== "release-lock") throw new Error("Unsupported migration action.");
|
|
65
|
+
await verifyRequest(request);
|
|
66
|
+
const db = new Kysely({ dialect: await options.createDialect() });
|
|
67
|
+
activeDb = db;
|
|
68
|
+
if (disposed) {
|
|
69
|
+
await closeActiveDb();
|
|
70
|
+
throw new Error("Migration executor has been disposed.");
|
|
71
|
+
}
|
|
72
|
+
const previousI18n = getI18nConfig();
|
|
73
|
+
let executionFailed = false;
|
|
74
|
+
let executionError;
|
|
75
|
+
let report;
|
|
76
|
+
setI18nConfig(request.i18n);
|
|
77
|
+
try {
|
|
78
|
+
report = await executeRequest(db, target, request);
|
|
79
|
+
} catch (error) {
|
|
80
|
+
executionFailed = true;
|
|
81
|
+
executionError = error;
|
|
82
|
+
} finally {
|
|
83
|
+
setI18nConfig(previousI18n);
|
|
84
|
+
try {
|
|
85
|
+
await closeActiveDb();
|
|
86
|
+
} catch {
|
|
87
|
+
console.error("[migrations] Database close failed.");
|
|
88
|
+
closePromise = Promise.resolve();
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
if (executionFailed) throw executionError;
|
|
92
|
+
if (!report) throw new Error("Migration execution did not produce a report.");
|
|
93
|
+
return report;
|
|
94
|
+
},
|
|
95
|
+
dispose() {
|
|
96
|
+
disposed = true;
|
|
97
|
+
return closeActiveDb();
|
|
98
|
+
}
|
|
99
|
+
};
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
//#endregion
|
|
103
|
+
export { createDirectMigrationExecutor as t };
|
|
104
|
+
//# sourceMappingURL=direct-executor-DyjAqkpT.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"direct-executor-DyjAqkpT.mjs","names":[],"sources":["../src/migrations/direct-executor.ts"],"sourcesContent":["import { type Dialect, Kysely } from \"kysely\";\n\nimport { clearMigrationLock, readMigrationLock } from \"../database/migration-lock.js\";\nimport {\n\tgetExactMigrationStatus,\n\trunMigrations,\n\ttype ExactMigrationStatus,\n} from \"../database/migrations/runner.js\";\nimport type { Database } from \"../database/types.js\";\nimport { getI18nConfig, setI18nConfig } from \"../i18n/config.js\";\nimport { getCoreMigrationIdentity } from \"./identity.js\";\nimport type {\n\tMigrationExecutor,\n\tMigrationReport,\n\tMigrationRequest,\n\tMigrationTarget,\n} from \"./protocol.js\";\n\nexport interface DirectMigrationExecutorOptions {\n\ttarget: MigrationTarget;\n\tcreateDialect: () => Dialect | Promise<Dialect>;\n}\n\nconst LOCK_ID_PATTERN = /^[1-9]\\d{0,15}$/;\n\nfunction createReport(\n\ttarget: MigrationTarget,\n\tstatus: ExactMigrationStatus,\n\texecuted: readonly string[],\n\tlockHeldSince: number | null = null,\n): MigrationReport {\n\tconst report: MigrationReport = {\n\t\ttarget,\n\t\tknownApplied: [...status.knownApplied],\n\t\tpending: [...status.pending],\n\t\tunknownApplied: [...status.unknownApplied],\n\t\texecuted: [...executed],\n\t};\n\tif (lockHeldSince !== null) {\n\t\treport.lock = {\n\t\t\tid: String(lockHeldSince),\n\t\t\theldSince: new Date(lockHeldSince).toISOString(),\n\t\t};\n\t}\n\treturn report;\n}\n\nasync function releaseLock(db: Kysely<Database>, lockId: string | undefined): Promise<void> {\n\tif (!lockId || !LOCK_ID_PATTERN.test(lockId)) {\n\t\tthrow new Error(\"Releasing the migration lock requires the lock id reported by status.\");\n\t}\n\tconst lock = Number(lockId);\n\t// Read before writing: on Postgres the lock column is a 32-bit integer that\n\t// a lock id does not fit, and no Postgres lock is ever held in it.\n\tconst heldSince = await readMigrationLock(db);\n\tif (heldSince === lock && (await clearMigrationLock(db, lock))) return;\n\tconst current = heldSince === lock ? await readMigrationLock(db) : heldSince;\n\t// No lock ids here: the CLI's redaction can rewrite digits that match an\n\t// environment value.\n\tthrow new Error(\n\t\tcurrent === null\n\t\t\t? \"The migration lock is not held.\"\n\t\t\t: \"The migration lock has a different id now. Check the status again before releasing it.\",\n\t);\n}\n\nasync function verifyRequest(request: MigrationRequest): Promise<void> {\n\tconst identity = await getCoreMigrationIdentity();\n\tif (\n\t\trequest.artifact.emdashVersion !== identity.emdashVersion ||\n\t\trequest.artifact.migrationSetFingerprint !== identity.fingerprint\n\t) {\n\t\tthrow new Error(\n\t\t\t\"Migration artifact does not match the loaded EmDash version and migration registry.\",\n\t\t);\n\t}\n}\n\nasync function executeRequest(\n\tdb: Kysely<Database>,\n\ttarget: MigrationTarget,\n\trequest: MigrationRequest,\n): Promise<MigrationReport> {\n\tconst initialStatus = await getExactMigrationStatus(db);\n\tif (request.action === \"check\") {\n\t\treturn createReport(target, initialStatus, [], await readMigrationLock(db));\n\t}\n\tif (request.action === \"release-lock\") {\n\t\tawait releaseLock(db, request.lockId);\n\t\treturn createReport(target, initialStatus, []);\n\t}\n\n\tif (initialStatus.unknownApplied.length > 0) {\n\t\tthrow new Error(\n\t\t\t`Cannot apply migrations with unknown applied migrations: ${initialStatus.unknownApplied.join(\", \")}`,\n\t\t);\n\t}\n\tif (initialStatus.pending.length === 0) {\n\t\treturn createReport(target, initialStatus, []);\n\t}\n\n\tconst result = await runMigrations(db);\n\tconst finalStatus = await getExactMigrationStatus(db);\n\treturn createReport(target, finalStatus, result.applied);\n}\n\nexport function createDirectMigrationExecutor(\n\toptions: DirectMigrationExecutorOptions,\n): MigrationExecutor {\n\tconst target = Object.freeze({ ...options.target });\n\tlet used = false;\n\tlet disposed = false;\n\tlet activeDb: Kysely<Database> | undefined;\n\tlet closePromise: Promise<void> | undefined;\n\n\tconst closeActiveDb = (): Promise<void> => {\n\t\tif (!activeDb) return Promise.resolve();\n\t\tclosePromise ??= activeDb.destroy();\n\t\treturn closePromise;\n\t};\n\n\treturn {\n\t\ttarget,\n\t\tasync execute(request) {\n\t\t\tif (disposed) {\n\t\t\t\tthrow new Error(\"Migration executor has been disposed.\");\n\t\t\t}\n\t\t\tif (used) {\n\t\t\t\tthrow new Error(\"Migration executors are single-use.\");\n\t\t\t}\n\t\t\tused = true;\n\n\t\t\tif (\n\t\t\t\trequest.action !== \"check\" &&\n\t\t\t\trequest.action !== \"apply\" &&\n\t\t\t\trequest.action !== \"release-lock\"\n\t\t\t) {\n\t\t\t\tthrow new Error(\"Unsupported migration action.\");\n\t\t\t}\n\t\t\tawait verifyRequest(request);\n\n\t\t\tconst dialect = await options.createDialect();\n\t\t\tconst db = new Kysely<Database>({ dialect });\n\t\t\tactiveDb = db;\n\t\t\tif (disposed) {\n\t\t\t\tawait closeActiveDb();\n\t\t\t\tthrow new Error(\"Migration executor has been disposed.\");\n\t\t\t}\n\t\t\tconst previousI18n = getI18nConfig();\n\t\t\tlet executionFailed = false;\n\t\t\tlet executionError: unknown;\n\t\t\tlet report: MigrationReport | undefined;\n\t\t\tsetI18nConfig(request.i18n);\n\n\t\t\ttry {\n\t\t\t\treport = await executeRequest(db, target, request);\n\t\t\t} catch (error) {\n\t\t\t\texecutionFailed = true;\n\t\t\t\texecutionError = error;\n\t\t\t} finally {\n\t\t\t\tsetI18nConfig(previousI18n);\n\t\t\t\ttry {\n\t\t\t\t\tawait closeActiveDb();\n\t\t\t\t} catch {\n\t\t\t\t\tconsole.error(\"[migrations] Database close failed.\");\n\t\t\t\t\tclosePromise = Promise.resolve();\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif (executionFailed) throw executionError;\n\t\t\tif (!report) throw new Error(\"Migration execution did not produce a report.\");\n\t\t\treturn report;\n\t\t},\n\t\tdispose() {\n\t\t\tdisposed = true;\n\t\t\treturn closeActiveDb();\n\t\t},\n\t};\n}\n"],"mappings":"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"}
|