emdash 1.3.0 → 1.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/{activation-Dim4YMM7.mjs → activation-CGlyigmg.mjs} +3 -3
- package/dist/{activation-Dim4YMM7.mjs.map → activation-CGlyigmg.mjs.map} +1 -1
- package/dist/{adapters-F_xorvWv.d.mts → adapters-D9a1PfqH.d.mts} +1 -1
- package/dist/{adapters-F_xorvWv.d.mts.map → adapters-D9a1PfqH.d.mts.map} +1 -1
- package/dist/{after-PcEvMY_6.mjs → after-32yNRvd2.mjs} +5 -2
- package/dist/{after-PcEvMY_6.mjs.map → after-32yNRvd2.mjs.map} +1 -1
- package/dist/api/route-utils.d.mts +4 -4
- package/dist/api/route-utils.mjs +50 -49
- package/dist/api/route-utils.mjs.map +1 -1
- package/dist/api/schemas/index.d.mts +1 -1
- package/dist/api/schemas/index.mjs +7 -7
- package/dist/{api-D-7BNHoz.mjs → api--PYoyeTo.mjs} +121 -48
- package/dist/api--PYoyeTo.mjs.map +1 -0
- package/dist/api-tokens-DqSlkDVI.mjs +9 -0
- package/dist/api-tokens-DqSlkDVI.mjs.map +1 -0
- package/dist/{api-tokens-Bx38ZCQp.mjs → api-tokens-GNCsIegW.mjs} +3 -3
- package/dist/{api-tokens-Bx38ZCQp.mjs.map → api-tokens-GNCsIegW.mjs.map} +1 -1
- package/dist/{apply-T7ATgzCh.mjs → apply-DVnupNeS.mjs} +149 -91
- package/dist/apply-DVnupNeS.mjs.map +1 -0
- package/dist/{approvals-D-m6wvGl.mjs → approvals-DTtYSB27.mjs} +2 -2
- package/dist/{approvals-D-m6wvGl.mjs.map → approvals-DTtYSB27.mjs.map} +1 -1
- package/dist/{artifacts-htGyfCSt.mjs → artifacts-Dvdp2KK-.mjs} +29 -13
- package/dist/artifacts-Dvdp2KK-.mjs.map +1 -0
- package/dist/astro/image-endpoint.mjs +12 -2
- package/dist/astro/image-endpoint.mjs.map +1 -1
- package/dist/astro/index.d.mts +15 -14
- package/dist/astro/index.d.mts.map +1 -1
- package/dist/astro/index.mjs +59 -8
- package/dist/astro/index.mjs.map +1 -1
- package/dist/astro/middleware/auth.d.mts +13 -12
- package/dist/astro/middleware/auth.d.mts.map +1 -1
- package/dist/astro/middleware/auth.mjs +10 -8
- package/dist/astro/middleware/auth.mjs.map +1 -1
- package/dist/astro/middleware/media-usage-write-fence.mjs +5 -5
- package/dist/astro/middleware/redirect.d.mts.map +1 -1
- package/dist/astro/middleware/redirect.mjs +129 -49
- package/dist/astro/middleware/redirect.mjs.map +1 -1
- package/dist/astro/middleware/request-context.d.mts.map +1 -1
- package/dist/astro/middleware/request-context.mjs +18 -9
- package/dist/astro/middleware/request-context.mjs.map +1 -1
- package/dist/astro/middleware.d.mts +13 -12
- package/dist/astro/middleware.d.mts.map +1 -1
- package/dist/astro/middleware.mjs +111 -101
- package/dist/astro/middleware.mjs.map +1 -1
- package/dist/astro/routes/api/admin/allowed-domains/_domain_.mjs +11 -11
- package/dist/astro/routes/api/admin/allowed-domains/index.mjs +11 -11
- 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 +6 -6
- package/dist/astro/routes/api/admin/byline-fields/_slug_.mjs +14 -14
- package/dist/astro/routes/api/admin/byline-fields/index.mjs +14 -14
- package/dist/astro/routes/api/admin/byline-fields/reorder.mjs +14 -14
- package/dist/astro/routes/api/admin/bylines/_id_/index.mjs +25 -25
- package/dist/astro/routes/api/admin/bylines/_id_/translations.mjs +25 -25
- package/dist/astro/routes/api/admin/bylines/index.mjs +25 -25
- package/dist/astro/routes/api/admin/comments/_id_/status.mjs +17 -17
- package/dist/astro/routes/api/admin/comments/_id_.mjs +8 -8
- package/dist/astro/routes/api/admin/comments/bulk.mjs +16 -16
- package/dist/astro/routes/api/admin/comments/counts.mjs +8 -8
- package/dist/astro/routes/api/admin/comments/index.mjs +16 -16
- package/dist/astro/routes/api/admin/core-update.mjs +6 -6
- package/dist/astro/routes/api/admin/hooks/exclusive/_hookName_.mjs +5 -5
- package/dist/astro/routes/api/admin/hooks/exclusive/index.mjs +4 -4
- package/dist/astro/routes/api/admin/media-usage/activation.mjs +18 -18
- package/dist/astro/routes/api/admin/media-usage/collection-deletions/index.mjs +19 -19
- package/dist/astro/routes/api/admin/media-usage/collection-deletions/retry.mjs +19 -19
- package/dist/astro/routes/api/admin/media-usage/progress.mjs +22 -21
- package/dist/astro/routes/api/admin/media-usage/progress.mjs.map +1 -1
- package/dist/astro/routes/api/admin/media-usage/repair.mjs +26 -25
- package/dist/astro/routes/api/admin/media-usage/repair.mjs.map +1 -1
- package/dist/astro/routes/api/admin/media-usage/work/index.mjs +19 -19
- package/dist/astro/routes/api/admin/media-usage/work/retry.mjs +19 -19
- package/dist/astro/routes/api/admin/oauth-clients/_id_.mjs +4 -4
- package/dist/astro/routes/api/admin/oauth-clients/index.mjs +4 -4
- package/dist/astro/routes/api/admin/plugins/_id_/disable.mjs +7 -7
- package/dist/astro/routes/api/admin/plugins/_id_/enable.mjs +7 -7
- package/dist/astro/routes/api/admin/plugins/_id_/index.mjs +66 -65
- package/dist/astro/routes/api/admin/plugins/_id_/index.mjs.map +1 -1
- package/dist/astro/routes/api/admin/plugins/_id_/mcp.mjs +5 -5
- package/dist/astro/routes/api/admin/plugins/_id_/settings.mjs +66 -65
- package/dist/astro/routes/api/admin/plugins/_id_/settings.mjs.map +1 -1
- package/dist/astro/routes/api/admin/plugins/_id_/uninstall.mjs +66 -65
- package/dist/astro/routes/api/admin/plugins/_id_/uninstall.mjs.map +1 -1
- package/dist/astro/routes/api/admin/plugins/_id_/update.mjs +73 -72
- package/dist/astro/routes/api/admin/plugins/_id_/update.mjs.map +1 -1
- package/dist/astro/routes/api/admin/plugins/index.mjs +66 -65
- package/dist/astro/routes/api/admin/plugins/index.mjs.map +1 -1
- package/dist/astro/routes/api/admin/plugins/marketplace/_id_/icon.mjs +4 -4
- package/dist/astro/routes/api/admin/plugins/marketplace/_id_/index.mjs +66 -65
- 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 +73 -72
- package/dist/astro/routes/api/admin/plugins/marketplace/_id_/install.mjs.map +1 -1
- package/dist/astro/routes/api/admin/plugins/marketplace/index.mjs +66 -65
- package/dist/astro/routes/api/admin/plugins/marketplace/index.mjs.map +1 -1
- package/dist/astro/routes/api/admin/plugins/registry/_id_/uninstall.mjs +66 -65
- 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 +74 -73
- package/dist/astro/routes/api/admin/plugins/registry/_id_/update.mjs.map +1 -1
- package/dist/astro/routes/api/admin/plugins/registry/artifact.mjs +4 -4
- package/dist/astro/routes/api/admin/plugins/registry/install.mjs +68 -67
- package/dist/astro/routes/api/admin/plugins/registry/install.mjs.map +1 -1
- package/dist/astro/routes/api/admin/plugins/registry/publisher-handle.mjs +4 -4
- package/dist/astro/routes/api/admin/plugins/registry/verify.mjs +67 -66
- package/dist/astro/routes/api/admin/plugins/registry/verify.mjs.map +1 -1
- package/dist/astro/routes/api/admin/plugins/updates.mjs +66 -65
- package/dist/astro/routes/api/admin/plugins/updates.mjs.map +1 -1
- package/dist/astro/routes/api/admin/scheduled-policy-rejections/_collection_/_id_.mjs +5 -5
- package/dist/astro/routes/api/admin/themes/marketplace/_id_/index.mjs +66 -65
- 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 +4 -4
- package/dist/astro/routes/api/admin/themes/marketplace/index.mjs +66 -65
- package/dist/astro/routes/api/admin/themes/marketplace/index.mjs.map +1 -1
- package/dist/astro/routes/api/admin/transfer/_...path_.mjs +3 -3
- package/dist/astro/routes/api/admin/transfer/approvals/_id_/approve.mjs +33 -32
- package/dist/astro/routes/api/admin/transfer/approvals/_id_/approve.mjs.map +1 -1
- package/dist/astro/routes/api/admin/transfer/approvals/_id_/deny.mjs +33 -32
- package/dist/astro/routes/api/admin/transfer/approvals/_id_/deny.mjs.map +1 -1
- package/dist/astro/routes/api/admin/transfer/approvals/index.mjs +35 -34
- package/dist/astro/routes/api/admin/transfer/approvals/index.mjs.map +1 -1
- package/dist/astro/routes/api/admin/transfer/capabilities.mjs +35 -34
- package/dist/astro/routes/api/admin/transfer/capabilities.mjs.map +1 -1
- package/dist/astro/routes/api/admin/transfer/exports/_id_/advance.mjs +35 -34
- package/dist/astro/routes/api/admin/transfer/exports/_id_/advance.mjs.map +1 -1
- package/dist/astro/routes/api/admin/transfer/exports/_id_/archive.mjs +36 -35
- package/dist/astro/routes/api/admin/transfer/exports/_id_/archive.mjs.map +1 -1
- package/dist/astro/routes/api/admin/transfer/exports/_id_/files/_...path_.mjs +36 -35
- package/dist/astro/routes/api/admin/transfer/exports/_id_/files/_...path_.mjs.map +1 -1
- package/dist/astro/routes/api/admin/transfer/exports/_id_/index.mjs +35 -34
- package/dist/astro/routes/api/admin/transfer/exports/_id_/index.mjs.map +1 -1
- package/dist/astro/routes/api/admin/transfer/exports/_id_/manifest.mjs +36 -35
- package/dist/astro/routes/api/admin/transfer/exports/_id_/manifest.mjs.map +1 -1
- package/dist/astro/routes/api/admin/transfer/exports/index.mjs +37 -36
- package/dist/astro/routes/api/admin/transfer/exports/index.mjs.map +1 -1
- package/dist/astro/routes/api/admin/transfer/imports/_id_/abandon.mjs +35 -34
- package/dist/astro/routes/api/admin/transfer/imports/_id_/abandon.mjs.map +1 -1
- package/dist/astro/routes/api/admin/transfer/imports/_id_/advance.mjs +35 -34
- package/dist/astro/routes/api/admin/transfer/imports/_id_/advance.mjs.map +1 -1
- package/dist/astro/routes/api/admin/transfer/imports/_id_/analyze.mjs +37 -36
- package/dist/astro/routes/api/admin/transfer/imports/_id_/analyze.mjs.map +1 -1
- package/dist/astro/routes/api/admin/transfer/imports/_id_/cancel.mjs +35 -34
- package/dist/astro/routes/api/admin/transfer/imports/_id_/cancel.mjs.map +1 -1
- package/dist/astro/routes/api/admin/transfer/imports/_id_/execute.mjs +37 -36
- package/dist/astro/routes/api/admin/transfer/imports/_id_/execute.mjs.map +1 -1
- package/dist/astro/routes/api/admin/transfer/imports/_id_/files/_...path_.mjs +35 -34
- package/dist/astro/routes/api/admin/transfer/imports/_id_/files/_...path_.mjs.map +1 -1
- package/dist/astro/routes/api/admin/transfer/imports/_id_/index.mjs +35 -34
- package/dist/astro/routes/api/admin/transfer/imports/_id_/index.mjs.map +1 -1
- package/dist/astro/routes/api/admin/transfer/imports/_id_/missing.mjs +37 -36
- package/dist/astro/routes/api/admin/transfer/imports/_id_/missing.mjs.map +1 -1
- package/dist/astro/routes/api/admin/transfer/imports/_id_/plan.mjs +35 -34
- package/dist/astro/routes/api/admin/transfer/imports/_id_/plan.mjs.map +1 -1
- package/dist/astro/routes/api/admin/transfer/imports/_id_/receipt.mjs +35 -34
- package/dist/astro/routes/api/admin/transfer/imports/_id_/receipt.mjs.map +1 -1
- package/dist/astro/routes/api/admin/transfer/imports/index.mjs +37 -36
- package/dist/astro/routes/api/admin/transfer/imports/index.mjs.map +1 -1
- package/dist/astro/routes/api/admin/users/_id_/disable.mjs +4 -4
- package/dist/astro/routes/api/admin/users/_id_/enable.mjs +3 -3
- package/dist/astro/routes/api/admin/users/_id_/index.mjs +12 -12
- package/dist/astro/routes/api/admin/users/_id_/send-recovery.mjs +4 -4
- package/dist/astro/routes/api/admin/users/index.mjs +11 -11
- package/dist/astro/routes/api/auth/dev-bypass.mjs +3 -3
- package/dist/astro/routes/api/auth/handover.mjs +5 -5
- package/dist/astro/routes/api/auth/invite/accept.mjs +3 -3
- package/dist/astro/routes/api/auth/invite/complete.mjs +15 -15
- package/dist/astro/routes/api/auth/invite/index.mjs +12 -12
- package/dist/astro/routes/api/auth/invite/register-options.mjs +13 -13
- package/dist/astro/routes/api/auth/logout.mjs +3 -3
- package/dist/astro/routes/api/auth/magic-link/send.mjs +14 -14
- package/dist/astro/routes/api/auth/magic-link/verify.mjs +13 -13
- package/dist/astro/routes/api/auth/me.mjs +12 -12
- package/dist/astro/routes/api/auth/mode.mjs +3 -3
- package/dist/astro/routes/api/auth/oauth/_provider_/callback.mjs +8 -8
- package/dist/astro/routes/api/auth/oauth/_provider_.mjs +1 -1
- package/dist/astro/routes/api/auth/passkey/_id_.mjs +11 -11
- package/dist/astro/routes/api/auth/passkey/index.mjs +3 -3
- package/dist/astro/routes/api/auth/passkey/options.mjs +15 -15
- package/dist/astro/routes/api/auth/passkey/register/options.mjs +13 -13
- package/dist/astro/routes/api/auth/passkey/register/verify.mjs +13 -13
- package/dist/astro/routes/api/auth/passkey/verify.mjs +15 -15
- package/dist/astro/routes/api/auth/signup/complete.mjs +15 -15
- package/dist/astro/routes/api/auth/signup/request.mjs +13 -13
- package/dist/astro/routes/api/auth/signup/verify.mjs +3 -3
- package/dist/astro/routes/api/calendar.mjs +12 -12
- package/dist/astro/routes/api/comments/_collection_/_contentId_/index.mjs +12 -12
- package/dist/astro/routes/api/comments/_collection_/_contentId_/reactions.mjs +17 -17
- package/dist/astro/routes/api/content/_collection_/_id_/compare.mjs +4 -4
- package/dist/astro/routes/api/content/_collection_/_id_/discard-draft.mjs +15 -15
- package/dist/astro/routes/api/content/_collection_/_id_/duplicate.mjs +4 -4
- package/dist/astro/routes/api/content/_collection_/_id_/lock.mjs +15 -15
- package/dist/astro/routes/api/content/_collection_/_id_/permanent.mjs +4 -4
- package/dist/astro/routes/api/content/_collection_/_id_/plugin-extensions/_pluginId_/_kind_/_extensionId_.mjs +9 -9
- package/dist/astro/routes/api/content/_collection_/_id_/preview-url.mjs +29 -28
- package/dist/astro/routes/api/content/_collection_/_id_/preview-url.mjs.map +1 -1
- package/dist/astro/routes/api/content/_collection_/_id_/publish.mjs +15 -15
- package/dist/astro/routes/api/content/_collection_/_id_/references/_relation_/children.mjs +34 -33
- 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 -33
- 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 +4 -4
- package/dist/astro/routes/api/content/_collection_/_id_/revisions.mjs +4 -4
- package/dist/astro/routes/api/content/_collection_/_id_/schedule.mjs +15 -15
- package/dist/astro/routes/api/content/_collection_/_id_/terms/_taxonomy_.d.mts.map +1 -1
- package/dist/astro/routes/api/content/_collection_/_id_/terms/_taxonomy_.mjs +35 -27
- package/dist/astro/routes/api/content/_collection_/_id_/terms/_taxonomy_.mjs.map +1 -1
- package/dist/astro/routes/api/content/_collection_/_id_/translations.d.mts.map +1 -1
- package/dist/astro/routes/api/content/_collection_/_id_/translations.mjs +8 -4
- package/dist/astro/routes/api/content/_collection_/_id_/translations.mjs.map +1 -1
- package/dist/astro/routes/api/content/_collection_/_id_/unpublish.mjs +15 -15
- package/dist/astro/routes/api/content/_collection_/_id_.mjs +15 -15
- package/dist/astro/routes/api/content/_collection_/authors.mjs +4 -4
- package/dist/astro/routes/api/content/_collection_/index.mjs +12 -12
- package/dist/astro/routes/api/content/_collection_/trash.mjs +12 -12
- package/dist/astro/routes/api/dashboard.mjs +22 -16
- package/dist/astro/routes/api/dashboard.mjs.map +1 -1
- package/dist/astro/routes/api/dev/emails.mjs +3 -3
- package/dist/astro/routes/api/dev/scheduled-tasks.mjs +97 -95
- package/dist/astro/routes/api/dev/scheduled-tasks.mjs.map +1 -1
- package/dist/astro/routes/api/health.mjs +4 -4
- package/dist/astro/routes/api/import/probe.d.mts +4 -3
- package/dist/astro/routes/api/import/probe.d.mts.map +1 -1
- package/dist/astro/routes/api/import/probe.mjs +27 -25
- package/dist/astro/routes/api/import/probe.mjs.map +1 -1
- package/dist/astro/routes/api/import/wordpress/analyze.d.mts +4 -3
- package/dist/astro/routes/api/import/wordpress/analyze.d.mts.map +1 -1
- package/dist/astro/routes/api/import/wordpress/analyze.mjs +7 -29
- package/dist/astro/routes/api/import/wordpress/analyze.mjs.map +1 -1
- package/dist/astro/routes/api/import/wordpress/execute.d.mts +14 -13
- package/dist/astro/routes/api/import/wordpress/execute.d.mts.map +1 -1
- package/dist/astro/routes/api/import/wordpress/execute.mjs +29 -29
- package/dist/astro/routes/api/import/wordpress/execute.mjs.map +1 -1
- package/dist/astro/routes/api/import/wordpress/media.d.mts +13 -12
- package/dist/astro/routes/api/import/wordpress/media.d.mts.map +1 -1
- package/dist/astro/routes/api/import/wordpress/media.mjs +14 -14
- package/dist/astro/routes/api/import/wordpress/prepare.mjs +19 -19
- package/dist/astro/routes/api/import/wordpress/prepare.mjs.map +1 -1
- package/dist/astro/routes/api/import/wordpress/rewrite-urls.d.mts +14 -13
- package/dist/astro/routes/api/import/wordpress/rewrite-urls.d.mts.map +1 -1
- package/dist/astro/routes/api/import/wordpress/rewrite-urls.mjs +25 -24
- package/dist/astro/routes/api/import/wordpress/rewrite-urls.mjs.map +1 -1
- package/dist/astro/routes/api/import/wordpress-plugin/analyze.d.mts +1 -1
- package/dist/astro/routes/api/import/wordpress-plugin/analyze.mjs +27 -25
- package/dist/astro/routes/api/import/wordpress-plugin/analyze.mjs.map +1 -1
- package/dist/astro/routes/api/import/wordpress-plugin/execute.d.mts +14 -13
- package/dist/astro/routes/api/import/wordpress-plugin/execute.d.mts.map +1 -1
- package/dist/astro/routes/api/import/wordpress-plugin/execute.mjs +39 -38
- package/dist/astro/routes/api/import/wordpress-plugin/execute.mjs.map +1 -1
- package/dist/astro/routes/api/manifest.mjs +4 -4
- package/dist/astro/routes/api/mcp.mjs +99 -83
- package/dist/astro/routes/api/mcp.mjs.map +1 -1
- package/dist/astro/routes/api/media/_id_/confirm.mjs +16 -16
- package/dist/astro/routes/api/media/_id_/replace.mjs +12 -12
- package/dist/astro/routes/api/media/_id_/upload.mjs +6 -6
- package/dist/astro/routes/api/media/_id_/usage.mjs +28 -27
- package/dist/astro/routes/api/media/_id_/usage.mjs.map +1 -1
- package/dist/astro/routes/api/media/_id_.mjs +26 -25
- package/dist/astro/routes/api/media/_id_.mjs.map +1 -1
- package/dist/astro/routes/api/media/asset/_id_/_filename_.mjs +5 -5
- package/dist/astro/routes/api/media/file/_...key_.d.mts.map +1 -1
- package/dist/astro/routes/api/media/file/_...key_.mjs +62 -8
- package/dist/astro/routes/api/media/file/_...key_.mjs.map +1 -1
- package/dist/astro/routes/api/media/folders/_id_.mjs +13 -13
- package/dist/astro/routes/api/media/folders/index.mjs +13 -13
- package/dist/astro/routes/api/media/providers/_providerId_/_itemId_.mjs +4 -4
- package/dist/astro/routes/api/media/providers/_providerId_/index.mjs +4 -4
- package/dist/astro/routes/api/media/providers/index.mjs +4 -4
- package/dist/astro/routes/api/media/upload-url.mjs +15 -15
- package/dist/astro/routes/api/media.mjs +30 -29
- package/dist/astro/routes/api/media.mjs.map +1 -1
- package/dist/astro/routes/api/menus/_name_/items/_id_.mjs +17 -15
- package/dist/astro/routes/api/menus/_name_/items/_id_.mjs.map +1 -1
- package/dist/astro/routes/api/menus/_name_/items.mjs +17 -15
- package/dist/astro/routes/api/menus/_name_/items.mjs.map +1 -1
- package/dist/astro/routes/api/menus/_name_/reorder.mjs +17 -15
- package/dist/astro/routes/api/menus/_name_/reorder.mjs.map +1 -1
- package/dist/astro/routes/api/menus/_name_/translations.mjs +17 -15
- package/dist/astro/routes/api/menus/_name_/translations.mjs.map +1 -1
- package/dist/astro/routes/api/menus/_name_.mjs +17 -15
- package/dist/astro/routes/api/menus/_name_.mjs.map +1 -1
- package/dist/astro/routes/api/menus/index.mjs +17 -15
- package/dist/astro/routes/api/menus/index.mjs.map +1 -1
- package/dist/astro/routes/api/oauth/authorize.mjs +2 -2
- package/dist/astro/routes/api/oauth/device/authorize.mjs +6 -6
- package/dist/astro/routes/api/oauth/device/code.mjs +8 -8
- package/dist/astro/routes/api/oauth/device/token.mjs +8 -8
- package/dist/astro/routes/api/oauth/register.mjs +5 -5
- package/dist/astro/routes/api/oauth/token/refresh.mjs +6 -6
- package/dist/astro/routes/api/oauth/token/revoke.mjs +6 -6
- package/dist/astro/routes/api/oauth/token.d.mts.map +1 -1
- package/dist/astro/routes/api/oauth/token.mjs +7 -7
- package/dist/astro/routes/api/oauth/token.mjs.map +1 -1
- package/dist/astro/routes/api/openapi.json.mjs +12 -12
- package/dist/astro/routes/api/plugins/_pluginId_/_...path_.mjs +9 -9
- package/dist/astro/routes/api/redirects/404s/index.mjs +20 -19
- package/dist/astro/routes/api/redirects/404s/index.mjs.map +1 -1
- package/dist/astro/routes/api/redirects/404s/summary.mjs +20 -19
- package/dist/astro/routes/api/redirects/404s/summary.mjs.map +1 -1
- package/dist/astro/routes/api/redirects/_id_.mjs +21 -20
- package/dist/astro/routes/api/redirects/_id_.mjs.map +1 -1
- package/dist/astro/routes/api/redirects/index.mjs +21 -20
- package/dist/astro/routes/api/redirects/index.mjs.map +1 -1
- package/dist/astro/routes/api/relations/_id_/index.mjs +34 -33
- package/dist/astro/routes/api/relations/_id_/index.mjs.map +1 -1
- package/dist/astro/routes/api/relations/index.mjs +34 -33
- package/dist/astro/routes/api/relations/index.mjs.map +1 -1
- package/dist/astro/routes/api/revisions/_revisionId_/index.mjs +4 -4
- package/dist/astro/routes/api/revisions/_revisionId_/restore.mjs +15 -15
- package/dist/astro/routes/api/schema/block-types/_slug_/index.mjs +66 -65
- 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 +66 -65
- 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 +66 -65
- package/dist/astro/routes/api/schema/block-types/index.mjs.map +1 -1
- package/dist/astro/routes/api/schema/collections/_slug_/fields/_fieldSlug_.mjs +66 -65
- 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 +66 -65
- 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 +66 -65
- package/dist/astro/routes/api/schema/collections/_slug_/fields/reorder.mjs.map +1 -1
- package/dist/astro/routes/api/schema/collections/_slug_/index.mjs +66 -65
- package/dist/astro/routes/api/schema/collections/_slug_/index.mjs.map +1 -1
- package/dist/astro/routes/api/schema/collections/index.mjs +66 -65
- package/dist/astro/routes/api/schema/collections/index.mjs.map +1 -1
- package/dist/astro/routes/api/schema/collections/reorder.mjs +66 -65
- package/dist/astro/routes/api/schema/collections/reorder.mjs.map +1 -1
- package/dist/astro/routes/api/schema/index.mjs +17 -16
- package/dist/astro/routes/api/schema/index.mjs.map +1 -1
- package/dist/astro/routes/api/schema/orphans/_slug_.mjs +66 -65
- package/dist/astro/routes/api/schema/orphans/_slug_.mjs.map +1 -1
- package/dist/astro/routes/api/schema/orphans/index.mjs +66 -65
- package/dist/astro/routes/api/schema/orphans/index.mjs.map +1 -1
- package/dist/astro/routes/api/search/enable.mjs +20 -18
- package/dist/astro/routes/api/search/enable.mjs.map +1 -1
- package/dist/astro/routes/api/search/index.mjs +19 -17
- package/dist/astro/routes/api/search/index.mjs.map +1 -1
- package/dist/astro/routes/api/search/rebuild.mjs +20 -18
- package/dist/astro/routes/api/search/rebuild.mjs.map +1 -1
- package/dist/astro/routes/api/search/stats.mjs +13 -11
- package/dist/astro/routes/api/search/stats.mjs.map +1 -1
- package/dist/astro/routes/api/search/suggest.mjs +19 -17
- package/dist/astro/routes/api/search/suggest.mjs.map +1 -1
- package/dist/astro/routes/api/sections/_slug_.mjs +19 -17
- package/dist/astro/routes/api/sections/_slug_.mjs.map +1 -1
- package/dist/astro/routes/api/sections/index.mjs +19 -17
- package/dist/astro/routes/api/sections/index.mjs.map +1 -1
- 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/domain-notify.mjs +7 -7
- package/dist/astro/routes/api/settings/domain.mjs +19 -17
- package/dist/astro/routes/api/settings/domain.mjs.map +1 -1
- package/dist/astro/routes/api/settings/email.mjs +5 -5
- package/dist/astro/routes/api/settings.mjs +25 -23
- package/dist/astro/routes/api/settings.mjs.map +1 -1
- package/dist/astro/routes/api/setup/admin-verify.mjs +18 -18
- package/dist/astro/routes/api/setup/admin.mjs +14 -14
- package/dist/astro/routes/api/setup/dev-bypass.mjs +45 -44
- package/dist/astro/routes/api/setup/dev-bypass.mjs.map +1 -1
- package/dist/astro/routes/api/setup/dev-reset.mjs +3 -3
- package/dist/astro/routes/api/setup/index.mjs +48 -47
- package/dist/astro/routes/api/setup/index.mjs.map +1 -1
- package/dist/astro/routes/api/setup/status.mjs +4 -4
- package/dist/astro/routes/api/site/domain-proof.mjs +17 -15
- package/dist/astro/routes/api/site/domain-proof.mjs.map +1 -1
- package/dist/astro/routes/api/snapshot.mjs +9 -9
- package/dist/astro/routes/api/taxonomies/_name_/reorder.mjs +25 -24
- package/dist/astro/routes/api/taxonomies/_name_/reorder.mjs.map +1 -1
- package/dist/astro/routes/api/taxonomies/_name_/terms/_slug_/translations.mjs +25 -24
- package/dist/astro/routes/api/taxonomies/_name_/terms/_slug_/translations.mjs.map +1 -1
- package/dist/astro/routes/api/taxonomies/_name_/terms/_slug_.mjs +25 -24
- package/dist/astro/routes/api/taxonomies/_name_/terms/_slug_.mjs.map +1 -1
- package/dist/astro/routes/api/taxonomies/_name_/terms/index.mjs +25 -24
- package/dist/astro/routes/api/taxonomies/_name_/terms/index.mjs.map +1 -1
- package/dist/astro/routes/api/taxonomies/_name_/translations.mjs +25 -24
- package/dist/astro/routes/api/taxonomies/_name_/translations.mjs.map +1 -1
- package/dist/astro/routes/api/taxonomies/_name_.mjs +25 -24
- package/dist/astro/routes/api/taxonomies/_name_.mjs.map +1 -1
- package/dist/astro/routes/api/taxonomies/bulk-tag.mjs +35 -34
- package/dist/astro/routes/api/taxonomies/bulk-tag.mjs.map +1 -1
- package/dist/astro/routes/api/taxonomies/index.mjs +25 -24
- package/dist/astro/routes/api/taxonomies/index.mjs.map +1 -1
- package/dist/astro/routes/api/themes/preview.mjs +6 -6
- package/dist/astro/routes/api/typegen.mjs +5 -5
- package/dist/astro/routes/api/visual-editing/action-token.mjs +5 -5
- package/dist/astro/routes/api/visual-editing/content/_collection_/_id_/publish.mjs +17 -17
- package/dist/astro/routes/api/visual-editing/toolbar-labels.mjs +3 -3
- package/dist/astro/routes/api/well-known/oauth-authorization-server.mjs +1 -1
- package/dist/astro/routes/api/well-known/oauth-protected-resource.mjs +1 -1
- package/dist/astro/routes/api/widget-areas/_name_/reorder.d.mts.map +1 -1
- package/dist/astro/routes/api/widget-areas/_name_/reorder.mjs +24 -13
- package/dist/astro/routes/api/widget-areas/_name_/reorder.mjs.map +1 -1
- package/dist/astro/routes/api/widget-areas/_name_/widgets/_id_.d.mts.map +1 -1
- package/dist/astro/routes/api/widget-areas/_name_/widgets/_id_.mjs +22 -17
- package/dist/astro/routes/api/widget-areas/_name_/widgets/_id_.mjs.map +1 -1
- package/dist/astro/routes/api/widget-areas/_name_/widgets.mjs +21 -17
- package/dist/astro/routes/api/widget-areas/_name_/widgets.mjs.map +1 -1
- package/dist/astro/routes/api/widget-areas/_name_.mjs +14 -10
- package/dist/astro/routes/api/widget-areas/_name_.mjs.map +1 -1
- package/dist/astro/routes/api/widget-areas/index.mjs +21 -17
- package/dist/astro/routes/api/widget-areas/index.mjs.map +1 -1
- package/dist/astro/routes/api/widget-components.mjs +3 -3
- package/dist/astro/routes/robots.txt.mjs +16 -14
- package/dist/astro/routes/robots.txt.mjs.map +1 -1
- package/dist/astro/routes/sitemap-_collection_.xml.mjs +18 -16
- package/dist/astro/routes/sitemap-_collection_.xml.mjs.map +1 -1
- package/dist/astro/routes/sitemap.xml.mjs +16 -14
- package/dist/astro/routes/sitemap.xml.mjs.map +1 -1
- package/dist/astro/types.d.mts +22 -20
- package/dist/astro/types.d.mts.map +1 -1
- package/dist/{audit-_gieLVGU.mjs → audit-B8XE-0UV.mjs} +2 -2
- package/dist/{audit-_gieLVGU.mjs.map → audit-B8XE-0UV.mjs.map} +1 -1
- package/dist/auth/providers/github.d.mts +1 -1
- package/dist/auth/providers/google.d.mts +1 -1
- package/dist/auth/providers/microsoft.d.mts +1 -1
- package/dist/{authorize-DPFBGbE6.mjs → authorize-NJgp8kLI.mjs} +2 -2
- package/dist/{authorize-DPFBGbE6.mjs.map → authorize-NJgp8kLI.mjs.map} +1 -1
- package/dist/{backup-3FgVxiDJ.mjs → backup-8rPSJ28a.mjs} +4 -4
- package/dist/{backup-3FgVxiDJ.mjs.map → backup-8rPSJ28a.mjs.map} +1 -1
- package/dist/{block-types-CYcG56JB.mjs → block-types-BbOrfnWs.mjs} +5 -5
- package/dist/{block-types-CYcG56JB.mjs.map → block-types-BbOrfnWs.mjs.map} +1 -1
- package/dist/{block-values-gCX4HBSl.mjs → block-values-Dg0-8PPS.mjs} +4 -4
- package/dist/{block-values-gCX4HBSl.mjs.map → block-values-Dg0-8PPS.mjs.map} +1 -1
- package/dist/{byline-BR1qhyiw.mjs → byline-DHJS-GGb.mjs} +123 -38
- package/dist/byline-DHJS-GGb.mjs.map +1 -0
- package/dist/{byline-fields-BLXZnX7N.mjs → byline-fields-CiR8FvvF.mjs} +3 -3
- package/dist/{byline-fields-BLXZnX7N.mjs.map → byline-fields-CiR8FvvF.mjs.map} +1 -1
- package/dist/{byline-fields-4ClDC88c.mjs → byline-fields-D6KYsEa7.mjs} +2 -2
- package/dist/{byline-fields-4ClDC88c.mjs.map → byline-fields-D6KYsEa7.mjs.map} +1 -1
- package/dist/{byline-registry-dvt4N3xV.mjs → byline-registry-BhzpO41z.mjs} +3 -3
- package/dist/{byline-registry-dvt4N3xV.mjs.map → byline-registry-BhzpO41z.mjs.map} +1 -1
- package/dist/{bylines-CVOvRUL7.mjs → bylines-Bsg5cH4S.mjs} +7 -7
- package/dist/bylines-Bsg5cH4S.mjs.map +1 -0
- package/dist/{bylines-DxOs9B7z.mjs → bylines-f_ZEc6Sn.mjs} +8 -8
- package/dist/{bylines-DxOs9B7z.mjs.map → bylines-f_ZEc6Sn.mjs.map} +1 -1
- package/dist/{cache-CEU9wo_h.mjs → cache-5DHbpEWu.mjs} +4 -4
- package/dist/{cache-CEU9wo_h.mjs.map → cache-5DHbpEWu.mjs.map} +1 -1
- package/dist/{capture-triggers-CT6dK9zd.mjs → capture-triggers-BezAvWcB.mjs} +2 -2
- package/dist/{capture-triggers-CT6dK9zd.mjs.map → capture-triggers-BezAvWcB.mjs.map} +1 -1
- package/dist/{challenge-store-C17BYx2-.mjs → challenge-store-B1C0V4b3.mjs} +1 -1
- package/dist/{challenge-store-C17BYx2-.mjs.map → challenge-store-B1C0V4b3.mjs.map} +1 -1
- package/dist/{chunks-xC4UD5-S.mjs → chunks-DiW8VMwz.mjs} +2 -2
- package/dist/{chunks-xC4UD5-S.mjs.map → chunks-DiW8VMwz.mjs.map} +1 -1
- package/dist/cli/index.mjs +53 -52
- package/dist/cli/index.mjs.map +1 -1
- package/dist/client/cf-access.d.mts +1 -1
- package/dist/client/index.d.mts +61 -61
- package/dist/client/index.d.mts.map +1 -1
- package/dist/client/index.mjs +3 -2
- package/dist/client/index.mjs.map +1 -1
- package/dist/{collection-slugs-cache-e09QeJQt.mjs → collection-slugs-cache-DIrLjqH-.mjs} +20 -14
- package/dist/collection-slugs-cache-DIrLjqH-.mjs.map +1 -0
- package/dist/{comment-UvIWDKcW.mjs → comment-DB74Zpa4.mjs} +18 -8
- package/dist/comment-DB74Zpa4.mjs.map +1 -0
- package/dist/{comment-reaction-dGp6_FRo.mjs → comment-reaction-BScxIWUn.mjs} +2 -2
- package/dist/{comment-reaction-dGp6_FRo.mjs.map → comment-reaction-BScxIWUn.mjs.map} +1 -1
- package/dist/{comments-pej-_BUO.mjs → comments-Cor_zKml.mjs} +3 -3
- package/dist/{comments-pej-_BUO.mjs.map → comments-Cor_zKml.mjs.map} +1 -1
- package/dist/config-Cs_AwWXI.mjs +106 -0
- package/dist/config-Cs_AwWXI.mjs.map +1 -0
- package/dist/{config-CFMojMFK.d.mts → config-D44_8G9J.d.mts} +3 -1
- package/dist/config-D44_8G9J.d.mts.map +1 -0
- package/dist/{config-Bsm_u_oE.d.mts → config-sDhZvkLR.d.mts} +56 -20
- package/dist/config-sDhZvkLR.d.mts.map +1 -0
- package/dist/{content-DQSRZTVw.mjs → content-BKHUVsE5.mjs} +67 -30
- package/dist/content-BKHUVsE5.mjs.map +1 -0
- package/dist/{content-list-query-CYKcY6Vi.d.mts → content-list-query-ByP4jRpZ.d.mts} +1 -1
- package/dist/{content-list-query-CYKcY6Vi.d.mts.map → content-list-query-ByP4jRpZ.d.mts.map} +1 -1
- package/dist/{content-policy-Dm32n9C6.mjs → content-policy-BmE0MPZY.mjs} +1 -1
- package/dist/{content-policy-Dm32n9C6.mjs.map → content-policy-BmE0MPZY.mjs.map} +1 -1
- package/dist/{content-repair-DNh5--x5.mjs → content-repair-Ukdxoq-R.mjs} +4 -4
- package/dist/{content-repair-DNh5--x5.mjs.map → content-repair-Ukdxoq-R.mjs.map} +1 -1
- package/dist/{context-BYptmCN0.mjs → context-CzjejcsE.mjs} +32 -33
- package/dist/context-CzjejcsE.mjs.map +1 -0
- package/dist/{credits-B9iORdWB.mjs → credits-BKREepht.mjs} +3 -3
- package/dist/{credits-B9iORdWB.mjs.map → credits-BKREepht.mjs.map} +1 -1
- package/dist/{dashboard-D0jcgBD7.mjs → dashboard-ynr1qJWM.mjs} +10 -9
- package/dist/dashboard-ynr1qJWM.mjs.map +1 -0
- package/dist/database/migration-lock.mjs +1 -1
- package/dist/db/index.d.mts +3 -3
- package/dist/db/index.mjs +3 -3
- package/dist/db/libsql-migrations.d.mts +1 -1
- package/dist/db/libsql-migrations.mjs +5 -5
- package/dist/db/libsql.d.mts +1 -1
- package/dist/db/postgres-migrations.d.mts +1 -1
- package/dist/db/postgres-migrations.mjs +5 -5
- package/dist/db/postgres.d.mts +1 -1
- package/dist/db/sqlite-migrations.d.mts +1 -1
- package/dist/db/sqlite-migrations.mjs +5 -5
- package/dist/db/sqlite.d.mts +1 -1
- package/dist/{db-errors-CBD5yMro.mjs → db-errors-unnO6yiZ.mjs} +12 -2
- package/dist/db-errors-unnO6yiZ.mjs.map +1 -0
- package/dist/deferred-tasks-wlMFJL95.d.mts +10 -0
- package/dist/deferred-tasks-wlMFJL95.d.mts.map +1 -0
- package/dist/{destination-r2zIAZ2S.mjs → destination-DR3IHjmy.mjs} +1 -1
- package/dist/{destination-r2zIAZ2S.mjs.map → destination-DR3IHjmy.mjs.map} +1 -1
- package/dist/{device-flow-BkFKBoAn.mjs → device-flow-D1U392GC.mjs} +3 -5
- package/dist/device-flow-D1U392GC.mjs.map +1 -0
- package/dist/{dialect-helpers-7_IqPdh9.mjs → dialect-helpers-B1XN2HGB.mjs} +10 -3
- package/dist/dialect-helpers-B1XN2HGB.mjs.map +1 -0
- package/dist/{direct-executor-Cbxzg4qe.mjs → direct-executor-Bs2g0ake.mjs} +4 -4
- package/dist/{direct-executor-Cbxzg4qe.mjs.map → direct-executor-Bs2g0ake.mjs.map} +1 -1
- package/dist/{dist-Cfu8mMBs.mjs → dist-BUmWMTbN.mjs} +1 -1
- package/dist/{dist-Cfu8mMBs.mjs.map → dist-BUmWMTbN.mjs.map} +1 -1
- package/dist/{email-locale-BJ8DjTzZ.mjs → email-locale-Bs3HFdnq.mjs} +1 -1
- package/dist/{email-locale-BJ8DjTzZ.mjs.map → email-locale-Bs3HFdnq.mjs.map} +1 -1
- package/dist/{emdash-runtime-DVi7vtXC.mjs → emdash-runtime-C8T-pZpS.mjs} +108 -62
- package/dist/emdash-runtime-C8T-pZpS.mjs.map +1 -0
- package/dist/{enrich-Duu4sV3a.mjs → enrich-DFlfnd3u.mjs} +3 -3
- package/dist/{enrich-Duu4sV3a.mjs.map → enrich-DFlfnd3u.mjs.map} +1 -1
- package/dist/{entry-lock-C7VX0NGK.d.mts → entry-lock-BulbgPBX.d.mts} +23 -23
- package/dist/{entry-lock-C7VX0NGK.d.mts.map → entry-lock-BulbgPBX.d.mts.map} +1 -1
- package/dist/{entry-lock-Df6-XhIu.mjs → entry-lock-CRVmruM0.mjs} +4 -4
- package/dist/{entry-lock-Df6-XhIu.mjs.map → entry-lock-CRVmruM0.mjs.map} +1 -1
- package/dist/{entry-lock-DLxCffFW.mjs → entry-lock-D-zJQ4q6.mjs} +3 -3
- package/dist/{entry-lock-DLxCffFW.mjs.map → entry-lock-D-zJQ4q6.mjs.map} +1 -1
- package/dist/{entry-locks-DJAqVweV.mjs → entry-locks-CJ9uhqg1.mjs} +2 -2
- package/dist/{entry-locks-DJAqVweV.mjs.map → entry-locks-CJ9uhqg1.mjs.map} +1 -1
- package/dist/{env-types-C3FCVBWe.mjs → env-types-BE3bCvfP.mjs} +5 -5
- package/dist/{env-types-C3FCVBWe.mjs.map → env-types-BE3bCvfP.mjs.map} +1 -1
- package/dist/{error-CVWeIOku.mjs → error-BCMgPxdn.mjs} +3 -3
- package/dist/{error-CVWeIOku.mjs.map → error-BCMgPxdn.mjs.map} +1 -1
- package/dist/{errors-BOYNdIo3.mjs → errors-8gJqv-XV.mjs} +15 -2
- package/dist/{errors-BOYNdIo3.mjs.map → errors-8gJqv-XV.mjs.map} +1 -1
- package/dist/{fence-C3MUitUN.mjs → fence-Dagicj14.mjs} +4 -4
- package/dist/{fence-C3MUitUN.mjs.map → fence-Dagicj14.mjs.map} +1 -1
- package/dist/{field-map-Bft9LKak.mjs → field-map-BSXdNGt5.mjs} +11 -10
- package/dist/field-map-BSXdNGt5.mjs.map +1 -0
- package/dist/{focal-point-JX8kcOTQ.mjs → focal-point-CgCcr1Ca.mjs} +1 -1
- package/dist/{focal-point-JX8kcOTQ.mjs.map → focal-point-CgCcr1Ca.mjs.map} +1 -1
- package/dist/{fts-manager-Beg3e4bI.mjs → fts-manager-6861qcwk.mjs} +68 -22
- package/dist/fts-manager-6861qcwk.mjs.map +1 -0
- package/dist/{gc-ByyAYiYE.mjs → gc-CNkXB3mE.mjs} +8 -8
- package/dist/{gc-ByyAYiYE.mjs.map → gc-CNkXB3mE.mjs.map} +1 -1
- package/dist/{hook-result-BrdLyOdI.d.mts → hook-result-f8t7hIuu.d.mts} +1 -1
- package/dist/{hook-result-BrdLyOdI.d.mts.map → hook-result-f8t7hIuu.d.mts.map} +1 -1
- package/dist/{hreflang-CY_F5OjF.d.mts → hreflang-8dUOJAPJ.d.mts} +2 -2
- package/dist/{hreflang-CY_F5OjF.d.mts.map → hreflang-8dUOJAPJ.d.mts.map} +1 -1
- package/dist/{hreflang-C8Jb-hrf.mjs → hreflang-BW5A4FLK.mjs} +8 -8
- package/dist/{hreflang-C8Jb-hrf.mjs.map → hreflang-BW5A4FLK.mjs.map} +1 -1
- package/dist/{http-route-dispatch-CyeW6iPv.mjs → http-route-dispatch-rXKvTNm9.mjs} +5 -5
- package/dist/{http-route-dispatch-CyeW6iPv.mjs.map → http-route-dispatch-rXKvTNm9.mjs.map} +1 -1
- package/dist/{identity-Cael5uTT.mjs → identity-CPRRSovU.mjs} +3 -3
- package/dist/{identity-Cael5uTT.mjs.map → identity-CPRRSovU.mjs.map} +1 -1
- package/dist/{import-BUXjdZUn.mjs → import-yVbfPyfd.mjs} +5 -5
- package/dist/{import-BUXjdZUn.mjs.map → import-yVbfPyfd.mjs.map} +1 -1
- package/dist/index-VM7Fzxwe.d.mts +260 -0
- package/dist/index-VM7Fzxwe.d.mts.map +1 -0
- package/dist/index.d.mts +25 -24
- package/dist/index.mjs +89 -88
- package/dist/{install-finalization-3JX5qQEA.mjs → install-finalization-RU6VrHOX.mjs} +1 -1
- package/dist/{install-finalization-3JX5qQEA.mjs.map → install-finalization-RU6VrHOX.mjs.map} +1 -1
- package/dist/{json-recordset-BUjxhr77.mjs → json-recordset-D0WhN2UA.mjs} +2 -2
- package/dist/{json-recordset-BUjxhr77.mjs.map → json-recordset-D0WhN2UA.mjs.map} +1 -1
- package/dist/{lifecycle-7vUJeFRe.mjs → lifecycle-B8d7Rdqx.mjs} +1 -1
- package/dist/{lifecycle-7vUJeFRe.mjs.map → lifecycle-B8d7Rdqx.mjs.map} +1 -1
- package/dist/{load-CdAG9wz-.mjs → load-D4xtzm6h.mjs} +2 -2
- package/dist/{load-CdAG9wz-.mjs.map → load-D4xtzm6h.mjs.map} +1 -1
- package/dist/{loader-CswroUbe.mjs → loader-DhnedqY4.mjs} +199 -101
- package/dist/loader-DhnedqY4.mjs.map +1 -0
- package/dist/{loops-uA4iTOzd.mjs → loops-B2YS-Zzr.mjs} +2 -2
- package/dist/{loops-uA4iTOzd.mjs.map → loops-B2YS-Zzr.mjs.map} +1 -1
- package/dist/{manifest-builder-B8zjuH3f.mjs → manifest-builder-g1FLviel.mjs} +10 -3
- package/dist/manifest-builder-g1FLviel.mjs.map +1 -0
- package/dist/media/image-endpoint.d.mts +3 -2
- package/dist/media/image-endpoint.d.mts.map +1 -1
- package/dist/media/image-endpoint.mjs +17 -8
- package/dist/media/image-endpoint.mjs.map +1 -1
- package/dist/media/index.d.mts +1 -1
- package/dist/media/index.mjs +7 -6
- package/dist/media/index.mjs.map +1 -1
- package/dist/media/local-runtime.d.mts +15 -14
- package/dist/media/local-runtime.d.mts.map +1 -1
- package/dist/media/local-runtime.mjs +20 -15
- package/dist/media/local-runtime.mjs.map +1 -1
- package/dist/{media-1WC65OCB.mjs → media-BR4_t-Wd.mjs} +3 -3
- package/dist/{media-1WC65OCB.mjs.map → media-BR4_t-Wd.mjs.map} +1 -1
- package/dist/{media--dJRU6i2.mjs → media-CikS-q6E.mjs} +4 -4
- package/dist/{media--dJRU6i2.mjs.map → media-CikS-q6E.mjs.map} +1 -1
- package/dist/{media-Bws9f18T.mjs → media-DepNLhPq.mjs} +14 -4
- package/dist/media-DepNLhPq.mjs.map +1 -0
- package/dist/{media-allowlist-BJB7MFx6.mjs → media-allowlist-BMBLqyWh.mjs} +2 -2
- package/dist/{media-allowlist-BJB7MFx6.mjs.map → media-allowlist-BMBLqyWh.mjs.map} +1 -1
- package/dist/{media-folders-Dn3C16B8.mjs → media-folders-CI0Wydfo.mjs} +2 -2
- package/dist/{media-folders-Dn3C16B8.mjs.map → media-folders-CI0Wydfo.mjs.map} +1 -1
- package/dist/{media-usage-CF0WVcLO.mjs → media-usage-X1_20MY-.mjs} +8 -8
- package/dist/{media-usage-CF0WVcLO.mjs.map → media-usage-X1_20MY-.mjs.map} +1 -1
- package/dist/{media-usage-activation-C9HwVw5w.mjs → media-usage-activation-bWusy3M2.mjs} +3 -3
- package/dist/{media-usage-activation-C9HwVw5w.mjs.map → media-usage-activation-bWusy3M2.mjs.map} +1 -1
- package/dist/{media-usage-work-m3AWTmmC.mjs → media-usage-work-B2RaoJIa.mjs} +4 -4
- package/dist/{media-usage-work-m3AWTmmC.mjs.map → media-usage-work-B2RaoJIa.mjs.map} +1 -1
- package/dist/{media-usage-work-CkLa5-nc.mjs → media-usage-work-BCK2J-v_.mjs} +7 -7
- package/dist/{media-usage-work-CkLa5-nc.mjs.map → media-usage-work-BCK2J-v_.mjs.map} +1 -1
- package/dist/{menus-BCVSSp1z.mjs → menus-B0Qqv_cS.mjs} +176 -92
- package/dist/menus-B0Qqv_cS.mjs.map +1 -0
- package/dist/{menus-Cl4kwdt7.mjs → menus-oypxT1pI.mjs} +134 -53
- package/dist/menus-oypxT1pI.mjs.map +1 -0
- package/dist/{menus-BSzwObhV.mjs → menus-uEAxWAm1.mjs} +3 -3
- package/dist/{menus-BSzwObhV.mjs.map → menus-uEAxWAm1.mjs.map} +1 -1
- package/dist/migrations/index.d.mts +1 -1
- package/dist/migrations/index.mjs +5 -5
- package/dist/{mime-B5M9R53H.mjs → mime-D1We9jUx.mjs} +1 -1
- package/dist/{mime-B5M9R53H.mjs.map → mime-D1We9jUx.mjs.map} +1 -1
- package/dist/{normalize-BuWa0lvd.mjs → normalize-Cx-bNwhP.mjs} +41 -12
- package/dist/normalize-Cx-bNwhP.mjs.map +1 -0
- package/dist/{oauth-authorization-TpEJrYB7.mjs → oauth-authorization-CPLgBrdo.mjs} +19 -6
- package/dist/oauth-authorization-CPLgBrdo.mjs.map +1 -0
- package/dist/{oauth-state-store-CHMn_mwc.mjs → oauth-state-store-BndCfRum.mjs} +1 -1
- package/dist/{oauth-state-store-CHMn_mwc.mjs.map → oauth-state-store-BndCfRum.mjs.map} +1 -1
- package/dist/object-cache/memory.d.mts +1 -1
- package/dist/{object-cache-Bo6DGaC9.mjs → object-cache-DmKr09La.mjs} +21 -4
- package/dist/{object-cache-Bo6DGaC9.mjs.map → object-cache-DmKr09La.mjs.map} +1 -1
- package/dist/{options-DJWaq3Ie.d.mts → options-BUUgroHg.d.mts} +3 -3
- package/dist/{options-DJWaq3Ie.d.mts.map → options-BUUgroHg.d.mts.map} +1 -1
- package/dist/page/index.d.mts +2 -2
- package/dist/page/index.mjs +16 -14
- package/dist/page/index.mjs.map +1 -1
- package/dist/{parse-DgQ2NABT.mjs → parse-B_b6gZxG.mjs} +2 -2
- package/dist/{parse-DgQ2NABT.mjs.map → parse-B_b6gZxG.mjs.map} +1 -1
- package/dist/{parse-CWHOFc6z.d.mts → parse-Dndx1QmN.d.mts} +3 -3
- package/dist/{parse-CWHOFc6z.d.mts.map → parse-Dndx1QmN.d.mts.map} +1 -1
- package/dist/{passkey-config-D0kdzEao.mjs → passkey-config-D2Lua5__.mjs} +1 -1
- package/dist/{passkey-config-D0kdzEao.mjs.map → passkey-config-D2Lua5__.mjs.map} +1 -1
- package/dist/{patterns-CMNnYCgf.mjs → patterns-CryGz_EV.mjs} +1 -1
- package/dist/{patterns-CMNnYCgf.mjs.map → patterns-CryGz_EV.mjs.map} +1 -1
- package/dist/{placeholder-D41vk11_.d.mts → placeholder-CSKu5OkD.d.mts} +9 -1
- package/dist/placeholder-CSKu5OkD.d.mts.map +1 -0
- package/dist/plugin-test-runtime.d.mts +17 -15
- package/dist/plugin-test-runtime.d.mts.map +1 -1
- package/dist/plugin-test-runtime.mjs +99 -98
- package/dist/plugin-types.d.mts +2 -2
- package/dist/plugin-utils.d.mts +13 -12
- package/dist/plugin-utils.d.mts.map +1 -1
- package/dist/plugins/adapt-sandbox-entry.d.mts +13 -12
- package/dist/plugins/adapt-sandbox-entry.d.mts.map +1 -1
- package/dist/plugins/host.d.mts +5 -5
- package/dist/plugins/host.mjs +48 -47
- package/dist/{policy-DLQ--Hnm.mjs → policy-BPugqmeV.mjs} +13 -5
- package/dist/policy-BPugqmeV.mjs.map +1 -0
- package/dist/{protocol-79kUO7jP.d.mts → protocol-PoAfD_9W.d.mts} +2 -2
- package/dist/{protocol-79kUO7jP.d.mts.map → protocol-PoAfD_9W.d.mts.map} +1 -1
- package/dist/{public-plugin-api-routes-BuAMJ8nN.mjs → public-plugin-api-routes-CMljrTby.mjs} +9 -9
- package/dist/{public-plugin-api-routes-BuAMJ8nN.mjs.map → public-plugin-api-routes-CMljrTby.mjs.map} +1 -1
- package/dist/{public-submission-Di3TsgzX.mjs → public-submission-ayqoyee4.mjs} +10 -10
- package/dist/{public-submission-Di3TsgzX.mjs.map → public-submission-ayqoyee4.mjs.map} +1 -1
- package/dist/query-BFHjCzSh.mjs +37 -0
- package/dist/query-BFHjCzSh.mjs.map +1 -0
- package/dist/{query-CpnRlBh8.mjs → query-D62NntCZ.mjs} +55 -65
- package/dist/query-D62NntCZ.mjs.map +1 -0
- package/dist/{query-haKvLAWl.mjs → query-LmPY2y0C.mjs} +5 -5
- package/dist/{query-haKvLAWl.mjs.map → query-LmPY2y0C.mjs.map} +1 -1
- package/dist/{rate-limit-Xp4d0NBY.mjs → rate-limit-C04Llsoc.mjs} +3 -3
- package/dist/{rate-limit-Xp4d0NBY.mjs.map → rate-limit-C04Llsoc.mjs.map} +1 -1
- package/dist/{redirect-DiS_3mA4.mjs → redirect-DjLdw427.mjs} +6 -6
- package/dist/{redirect-DiS_3mA4.mjs.map → redirect-DjLdw427.mjs.map} +1 -1
- package/dist/{redirect-paths-CNYq7w80.mjs → redirect-paths-DOaVBp6E.mjs} +1 -1
- package/dist/{redirect-paths-CNYq7w80.mjs.map → redirect-paths-DOaVBp6E.mjs.map} +1 -1
- package/dist/{redirects-BHpy-VsZ.mjs → redirects-Cpq1catN.mjs} +6 -6
- package/dist/{redirects-BHpy-VsZ.mjs.map → redirects-Cpq1catN.mjs.map} +1 -1
- package/dist/{redirects-BEVSRMa2.mjs → redirects-CyvvZrCJ.mjs} +2 -2
- package/dist/{redirects-BEVSRMa2.mjs.map → redirects-CyvvZrCJ.mjs.map} +1 -1
- package/dist/{registry-TUVaid9Z.mjs → registry-B0-O575m.mjs} +25 -20
- package/dist/registry-B0-O575m.mjs.map +1 -0
- package/dist/{relations-CA_QuMTU.mjs → relations-WIOojTL4.mjs} +24 -11
- package/dist/relations-WIOojTL4.mjs.map +1 -0
- package/dist/{request-cache-C4CIo5ad.mjs → request-cache-5z2WzWmh.mjs} +1 -1
- package/dist/{request-cache-C4CIo5ad.mjs.map → request-cache-5z2WzWmh.mjs.map} +1 -1
- package/dist/request-context.d.mts +12 -1
- package/dist/request-context.d.mts.map +1 -1
- package/dist/request-context.mjs.map +1 -1
- package/dist/{resolve-DwNM-CXl.mjs → resolve-BNnm8EkB.mjs} +14 -13
- package/dist/{resolve-DwNM-CXl.mjs.map → resolve-BNnm8EkB.mjs.map} +1 -1
- package/dist/{resolve-D-kqyKns.mjs → resolve-DdNXBJSr.mjs} +4 -4
- package/dist/resolve-DdNXBJSr.mjs.map +1 -0
- package/dist/{revision-BVp8S0e_.mjs → revision-Dx7Uth1X.mjs} +5 -5
- package/dist/{revision-BVp8S0e_.mjs.map → revision-Dx7Uth1X.mjs.map} +1 -1
- package/dist/{routes-BerZFrvV.mjs → routes-avqgc-8r.mjs} +3 -3
- package/dist/{routes-BerZFrvV.mjs.map → routes-avqgc-8r.mjs.map} +1 -1
- package/dist/{runner-C5NeAkBQ.mjs → runner-Bkkfk4O8.mjs} +78 -4
- package/dist/runner-Bkkfk4O8.mjs.map +1 -0
- package/dist/{runner-BObHz5FC.d.mts → runner-Dfgp6-S_.d.mts} +7 -2
- package/dist/runner-Dfgp6-S_.d.mts.map +1 -0
- package/dist/runtime.d.mts +14 -13
- package/dist/runtime.d.mts.map +1 -1
- package/dist/runtime.mjs +8 -6
- package/dist/runtime.mjs.map +1 -1
- package/dist/schema/project-env-types.mjs +43 -42
- package/dist/schema/project-env-types.mjs.map +1 -1
- package/dist/{schema-DJRfvM_o.mjs → schema-B-3rntlX.mjs} +11 -11
- package/dist/{schema-DJRfvM_o.mjs.map → schema-B-3rntlX.mjs.map} +1 -1
- package/dist/{schema-C4OBuv6Z.mjs → schema-BqBlUZtb.mjs} +4 -4
- package/dist/{schema-C4OBuv6Z.mjs.map → schema-BqBlUZtb.mjs.map} +1 -1
- package/dist/{scopes-BU03K7Uo.mjs → scopes-DNaY7Ey0.mjs} +3 -3
- package/dist/{scopes-BU03K7Uo.mjs.map → scopes-DNaY7Ey0.mjs.map} +1 -1
- package/dist/{search-DfVzks89.mjs → search-BPWTnpnD.mjs} +32 -32
- package/dist/search-BPWTnpnD.mjs.map +1 -0
- package/dist/{secrets-Cc_O3Kp-.mjs → secrets-Dswzrz3k.mjs} +2 -2
- package/dist/{secrets-Cc_O3Kp-.mjs.map → secrets-Dswzrz3k.mjs.map} +1 -1
- package/dist/{sections-BMy4JVUz.mjs → sections-rSao6rBG.mjs} +3 -3
- package/dist/{sections-BMy4JVUz.mjs.map → sections-rSao6rBG.mjs.map} +1 -1
- package/dist/seed/index.d.mts +2 -2
- package/dist/seed/index.mjs +42 -41
- package/dist/seo/index.d.mts +3 -3
- package/dist/seo/index.mjs +30 -28
- package/dist/seo/index.mjs.map +1 -1
- package/dist/{seo-VZYOEy8f.mjs → seo-B_H_pqOd.mjs} +3 -3
- package/dist/{seo-VZYOEy8f.mjs.map → seo-B_H_pqOd.mjs.map} +1 -1
- package/dist/{service-Bo_usgSk.mjs → service-DpiUQVpp.mjs} +2 -2
- package/dist/{service-Bo_usgSk.mjs.map → service-DpiUQVpp.mjs.map} +1 -1
- package/dist/{session-user-DlpPdf8L.mjs → session-user-DiE4JKPP.mjs} +4 -4
- package/dist/{session-user-DlpPdf8L.mjs.map → session-user-DiE4JKPP.mjs.map} +1 -1
- package/dist/{settings-DS914jjE.mjs → settings--XlUdUaI.mjs} +3 -3
- package/dist/{settings-DS914jjE.mjs.map → settings--XlUdUaI.mjs.map} +1 -1
- package/dist/{settings-CWb84sDm.mjs → settings-D932YP2-.mjs} +111 -44
- package/dist/settings-D932YP2-.mjs.map +1 -0
- package/dist/{setup-complete-BuNxAUiN.mjs → setup-complete-qsJYWutC.mjs} +2 -2
- package/dist/{setup-complete-BuNxAUiN.mjs.map → setup-complete-qsJYWutC.mjs.map} +1 -1
- package/dist/{setup-nonce-BnEAX0iy.mjs → setup-nonce-CBFgUFXw.mjs} +1 -1
- package/dist/{setup-nonce-BnEAX0iy.mjs.map → setup-nonce-CBFgUFXw.mjs.map} +1 -1
- package/dist/{site-domain-Bq5j5bVg.mjs → site-domain-oRGS_JfA.mjs} +2 -2
- package/dist/{site-domain-Bq5j5bVg.mjs.map → site-domain-oRGS_JfA.mjs.map} +1 -1
- package/dist/{sitemap-name-BTg2NJJv.mjs → sitemap-name-B8QP8wud.mjs} +1 -1
- package/dist/{sitemap-name-BTg2NJJv.mjs.map → sitemap-name-B8QP8wud.mjs.map} +1 -1
- package/dist/{slugify-bu2-jKia.mjs → slugify-BDEG9pLk.mjs} +1 -1
- package/dist/{slugify-bu2-jKia.mjs.map → slugify-BDEG9pLk.mjs.map} +1 -1
- package/dist/{snapshot-DYsG4uOq.mjs → snapshot-BjaXDZQ5.mjs} +2 -2
- package/dist/{snapshot-DYsG4uOq.mjs.map → snapshot-BjaXDZQ5.mjs.map} +1 -1
- package/dist/{stage-D8DWgPcO.mjs → stage-CZQnXM_G.mjs} +3 -3
- package/dist/{stage-D8DWgPcO.mjs.map → stage-CZQnXM_G.mjs.map} +1 -1
- package/dist/{staged-CD_imitH.mjs → staged-ByBmPFtX.mjs} +3 -3
- package/dist/{staged-CD_imitH.mjs.map → staged-ByBmPFtX.mjs.map} +1 -1
- package/dist/storage/local.d.mts +1 -1
- package/dist/storage/s3.d.mts +1 -1
- package/dist/{storage-query-DRyu3bSU.d.mts → storage-query-BFp06Y0s.d.mts} +22 -10
- package/dist/storage-query-BFp06Y0s.d.mts.map +1 -0
- package/dist/{taxonomies-Dd9JJv_a.mjs → taxonomies-5SR76j11.mjs} +15 -17
- package/dist/taxonomies-5SR76j11.mjs.map +1 -0
- package/dist/{taxonomies-ChnU7Mc8.mjs → taxonomies-B__VmCKQ.mjs} +64 -58
- package/dist/taxonomies-B__VmCKQ.mjs.map +1 -0
- package/dist/{taxonomy-C_C_LBAU.mjs → taxonomy-CMI5fczd.mjs} +30 -17
- package/dist/taxonomy-CMI5fczd.mjs.map +1 -0
- package/dist/{transaction-BVYIo_yu.mjs → transaction-CkoQ5wqQ.mjs} +1 -1
- package/dist/{transaction-BVYIo_yu.mjs.map → transaction-CkoQ5wqQ.mjs.map} +1 -1
- package/dist/{transfer-WmWiR3xf.mjs → transfer-BbKfufJ4.mjs} +2 -2
- package/dist/{transfer-WmWiR3xf.mjs.map → transfer-BbKfufJ4.mjs.map} +1 -1
- package/dist/{transfer-ClH6w6BV.mjs → transfer-DTGblAj2.mjs} +71 -34
- package/dist/{transfer-ClH6w6BV.mjs.map → transfer-DTGblAj2.mjs.map} +1 -1
- package/dist/{transfer-download--ofRj9Cw.mjs → transfer-download-D9LQEDX0.mjs} +1 -1
- package/dist/{transfer-download--ofRj9Cw.mjs.map → transfer-download-D9LQEDX0.mjs.map} +1 -1
- package/dist/{transport-DxiXnbXk.d.mts → transport-Dm5QzpT_.d.mts} +1 -1
- package/dist/{transport-DxiXnbXk.d.mts.map → transport-Dm5QzpT_.d.mts.map} +1 -1
- package/dist/{transport-BjbqNiPI.mjs → transport-Dzpn5b3i.mjs} +4 -3
- package/dist/transport-Dzpn5b3i.mjs.map +1 -0
- package/dist/{turnstile-CJwvsOqw.mjs → turnstile-Cs2wfkJG.mjs} +1 -1
- package/dist/{turnstile-CJwvsOqw.mjs.map → turnstile-Cs2wfkJG.mjs.map} +1 -1
- package/dist/{types-BA3ey2QH.d.mts → types-BAsCk5KU.d.mts} +1 -1
- package/dist/{types-BA3ey2QH.d.mts.map → types-BAsCk5KU.d.mts.map} +1 -1
- package/dist/{types-RLgeIpnF.d.mts → types-BuvSwT9Y.d.mts} +8 -7
- package/dist/{types-RLgeIpnF.d.mts.map → types-BuvSwT9Y.d.mts.map} +1 -1
- package/dist/{types-CNB-dj6F.d.mts → types-C4KT3Md2.d.mts} +10 -6
- package/dist/types-C4KT3Md2.d.mts.map +1 -0
- package/dist/{types-DvqVxZXa.d.mts → types-CVXHwIBB.d.mts} +1 -1
- package/dist/{types-DvqVxZXa.d.mts.map → types-CVXHwIBB.d.mts.map} +1 -1
- package/dist/{types-BGmQ0uXs.mjs → types-C_asjp1J.mjs} +1 -1
- package/dist/types-C_asjp1J.mjs.map +1 -0
- package/dist/{types-DHO7Pd25.d.mts → types-CadaL_k8.d.mts} +1 -1
- package/dist/{types-DHO7Pd25.d.mts.map → types-CadaL_k8.d.mts.map} +1 -1
- package/dist/{types-QoPHm-2w.d.mts → types-CjftrmZR.d.mts} +3 -3
- package/dist/{types-QoPHm-2w.d.mts.map → types-CjftrmZR.d.mts.map} +1 -1
- package/dist/{types-DCFavOii.d.mts → types-DKwRUA-x.d.mts} +1 -1
- package/dist/{types-DCFavOii.d.mts.map → types-DKwRUA-x.d.mts.map} +1 -1
- package/dist/{types-D2NEXtgB.mjs → types-DwhEvIVb.mjs} +8 -2
- package/dist/types-DwhEvIVb.mjs.map +1 -0
- package/dist/{types-Bwpzb5o6.d.mts → types-GwAyS5SH.d.mts} +1 -1
- package/dist/{types-Bwpzb5o6.d.mts.map → types-GwAyS5SH.d.mts.map} +1 -1
- package/dist/{types-slSqujQL.d.mts → types-uU2YNYSt.d.mts} +6 -1
- package/dist/types-uU2YNYSt.d.mts.map +1 -0
- package/dist/{update-check-BxNg9T6N.mjs → update-check-ABBJgg6M.mjs} +4 -4
- package/dist/{update-check-BxNg9T6N.mjs.map → update-check-ABBJgg6M.mjs.map} +1 -1
- package/dist/{url-Dn3IStq8.mjs → url-DTfGDJhI.mjs} +1 -1
- package/dist/{url-Dn3IStq8.mjs.map → url-DTfGDJhI.mjs.map} +1 -1
- package/dist/{user-BlCTKVAm.mjs → user-By8SzQxS.mjs} +3 -3
- package/dist/{user-BlCTKVAm.mjs.map → user-By8SzQxS.mjs.map} +1 -1
- package/dist/{utils-TPt7w2cS.mjs → utils-D5uOi6WS.mjs} +13 -5
- package/dist/utils-D5uOi6WS.mjs.map +1 -0
- package/dist/{index-BB9sVisO.d.mts → utils-Szp4iBQB.d.mts} +9 -256
- package/dist/utils-Szp4iBQB.d.mts.map +1 -0
- package/dist/{validate-emKxGC5F.d.mts → validate-DDvxy6qG.d.mts} +8 -8
- package/dist/{validate-emKxGC5F.d.mts.map → validate-DDvxy6qG.d.mts.map} +1 -1
- package/dist/{validate-DxYhJQA-.mjs → validate-Dz-TIOFB.mjs} +7 -7
- package/dist/{validate-DxYhJQA-.mjs.map → validate-Dz-TIOFB.mjs.map} +1 -1
- package/dist/{validation-Ckq4vsVg.mjs → validation-Fc9ZSUS_.mjs} +17 -16
- package/dist/{validation-Ckq4vsVg.mjs.map → validation-Fc9ZSUS_.mjs.map} +1 -1
- package/dist/version-Bu6Nlbb5.mjs +7 -0
- package/dist/{version-DHmGpcch.mjs.map → version-Bu6Nlbb5.mjs.map} +1 -1
- package/dist/version-DqB7LIO7.mjs +49 -0
- package/dist/version-DqB7LIO7.mjs.map +1 -0
- package/dist/{widgets-DA5XmvVC.mjs → widgets-BUx_Mf2q.mjs} +18 -5
- package/dist/widgets-BUx_Mf2q.mjs.map +1 -0
- package/dist/{wxr-taxonomies-RgRG0d5e.mjs → wxr-taxonomies-DbJtWrWM.mjs} +7 -6
- package/dist/wxr-taxonomies-DbJtWrWM.mjs.map +1 -0
- package/dist/{wxr-taxonomies-CrMonejI.d.mts → wxr-taxonomies-Dy2i2ON3.d.mts} +1 -1
- package/dist/wxr-taxonomies-Dy2i2ON3.d.mts.map +1 -0
- package/dist/{zod-generator-D0JKy94C.mjs → zod-generator--nlM0930.mjs} +5 -4
- package/dist/zod-generator--nlM0930.mjs.map +1 -0
- package/package.json +5 -5
- package/src/api/handlers/bulk-tag.ts +11 -3
- package/src/api/handlers/bylines.ts +6 -2
- package/src/api/handlers/content.ts +154 -23
- package/src/api/handlers/dashboard.ts +13 -6
- package/src/api/handlers/device-flow.ts +1 -3
- package/src/api/handlers/menus.ts +27 -13
- package/src/api/handlers/oauth-authorization.ts +1 -3
- package/src/api/handlers/relations.ts +15 -1
- package/src/api/handlers/taxonomies.ts +27 -17
- package/src/astro/image-endpoint.ts +23 -2
- package/src/astro/integration/admin-nav.ts +52 -0
- package/src/astro/integration/index.ts +7 -0
- package/src/astro/integration/runtime.ts +14 -0
- package/src/astro/integration/shims/use-sync-external-store-with-selector.js +2 -0
- package/src/astro/integration/shims/use-sync-external-store.js +4 -1
- package/src/astro/integration/vite-config.ts +16 -8
- package/src/astro/middleware/auth.ts +9 -2
- package/src/astro/middleware/redirect.ts +158 -63
- package/src/astro/middleware/request-context.ts +1 -0
- package/src/astro/middleware.ts +17 -4
- package/src/astro/routes/api/content/[collection]/[id]/terms/[taxonomy].ts +4 -1
- package/src/astro/routes/api/content/[collection]/[id]/translations.ts +14 -1
- package/src/astro/routes/api/dashboard.ts +2 -0
- package/src/astro/routes/api/import/wordpress/analyze.ts +5 -29
- package/src/astro/routes/api/import/wordpress-plugin/execute.ts +3 -3
- package/src/astro/routes/api/media/file/[...key].ts +31 -7
- package/src/astro/routes/api/oauth/token.ts +5 -1
- package/src/astro/routes/api/widget-areas/[name]/reorder.ts +7 -1
- package/src/astro/routes/api/widget-areas/[name]/widgets/[id].ts +3 -1
- package/src/astro/routes/api/widget-areas/[name]/widgets.ts +2 -1
- package/src/astro/routes/api/widget-areas/[name].ts +2 -1
- package/src/astro/routes/api/widget-areas/index.ts +2 -1
- package/src/astro/types.ts +4 -3
- package/src/auth/api-tokens.ts +3 -0
- package/src/auth/types.ts +6 -0
- package/src/cleanup.ts +44 -0
- package/src/cli/commands/export-seed.ts +6 -4
- package/src/cli/commands/login.ts +2 -4
- package/src/client/index.ts +1 -0
- package/src/client/transport.ts +11 -7
- package/src/components/EmDashImage.astro +14 -2
- package/src/components/InlinePortableTextEditor.tsx +4 -1
- package/src/components/inline-bubble-menu.tsx +109 -95
- package/src/components/inline-image.tsx +54 -48
- package/src/database/dialect-helpers.ts +10 -3
- package/src/database/migrations/content-sized.ts +82 -0
- package/src/database/migrations/policy.ts +28 -2
- package/src/database/migrations/runner.ts +48 -0
- package/src/database/repositories/byline.ts +95 -31
- package/src/database/repositories/comment.ts +17 -7
- package/src/database/repositories/content.ts +96 -23
- package/src/database/repositories/media.ts +17 -0
- package/src/database/repositories/menu.ts +236 -139
- package/src/database/repositories/taxonomy-def.ts +9 -2
- package/src/database/repositories/taxonomy.ts +47 -14
- package/src/database/repositories/types.ts +14 -3
- package/src/database/types.ts +1 -1
- package/src/emdash-runtime.ts +60 -17
- package/src/fields/image.ts +1 -0
- package/src/i18n/config.ts +58 -10
- package/src/i18n/normalize.ts +16 -2
- package/src/i18n/query.ts +47 -0
- package/src/i18n/resolve.ts +8 -3
- package/src/import/utils.ts +15 -2
- package/src/import/wxr-taxonomies.ts +3 -2
- package/src/index.ts +1 -0
- package/src/loader.ts +183 -114
- package/src/mcp/server.ts +28 -1
- package/src/media/caption.ts +30 -0
- package/src/media/content-disposition.ts +56 -0
- package/src/media/image-endpoint.ts +13 -6
- package/src/media/local-runtime.ts +3 -0
- package/src/media/normalize.ts +17 -8
- package/src/media/responsive.ts +12 -2
- package/src/media/types.ts +16 -3
- package/src/media/usage/content-fields.ts +2 -1
- package/src/menus/index.ts +158 -36
- package/src/migrations/manifest.ts +1 -0
- package/src/object-cache/index.ts +22 -0
- package/src/plugin-test-runtime.ts +1 -0
- package/src/plugins/byline-access.ts +3 -1
- package/src/plugins/context.ts +1 -2
- package/src/plugins/storage-indexes.ts +7 -3
- package/src/query.ts +67 -53
- package/src/redirects/artifacts.ts +39 -5
- package/src/references/field-map.ts +6 -4
- package/src/request-context.ts +8 -0
- package/src/schema/collection-slugs-cache.ts +31 -17
- package/src/schema/registry.ts +9 -0
- package/src/schema/types.ts +7 -6
- package/src/schema/zod-generator.ts +2 -1
- package/src/search/fts-manager.ts +103 -31
- package/src/search/query.ts +31 -64
- package/src/seed/apply.ts +221 -109
- package/src/seed/types.ts +6 -4
- package/src/settings/index.ts +135 -35
- package/src/settings/version.ts +54 -0
- package/src/taxonomies/index.ts +99 -85
- package/src/taxonomies/term-counts.ts +2 -1
- package/src/transfer/import/advance.ts +12 -1
- package/src/transfer/import/scaffold.ts +7 -1
- package/src/transfer/import/stages.ts +53 -2
- package/src/utils/db-errors.ts +15 -0
- package/src/utils/revalidating-cache.ts +85 -0
- package/src/virtual-modules.d.ts +1 -0
- package/src/visual-editing/toolbar.ts +7 -2
- package/src/widgets/index.ts +27 -13
- package/dist/api-D-7BNHoz.mjs.map +0 -1
- package/dist/api-tokens-CdP49zVF.mjs +0 -3
- package/dist/apply-T7ATgzCh.mjs.map +0 -1
- package/dist/artifacts-htGyfCSt.mjs.map +0 -1
- package/dist/byline-BR1qhyiw.mjs.map +0 -1
- package/dist/bylines-CVOvRUL7.mjs.map +0 -1
- package/dist/collection-slugs-cache-e09QeJQt.mjs.map +0 -1
- package/dist/comment-UvIWDKcW.mjs.map +0 -1
- package/dist/config-Bsm_u_oE.d.mts.map +0 -1
- package/dist/config-CFMojMFK.d.mts.map +0 -1
- package/dist/config-CvmjJcVw.mjs +0 -73
- package/dist/config-CvmjJcVw.mjs.map +0 -1
- package/dist/content-DQSRZTVw.mjs.map +0 -1
- package/dist/context-BYptmCN0.mjs.map +0 -1
- package/dist/dashboard-D0jcgBD7.mjs.map +0 -1
- package/dist/db-errors-CBD5yMro.mjs.map +0 -1
- package/dist/deferred-tasks-ZvUECSzI.d.mts +0 -9
- package/dist/deferred-tasks-ZvUECSzI.d.mts.map +0 -1
- package/dist/device-flow-BkFKBoAn.mjs.map +0 -1
- package/dist/dialect-helpers-7_IqPdh9.mjs.map +0 -1
- package/dist/emdash-runtime-DVi7vtXC.mjs.map +0 -1
- package/dist/field-defs-cache-Dez5iWJJ.mjs +0 -77
- package/dist/field-defs-cache-Dez5iWJJ.mjs.map +0 -1
- package/dist/field-map-Bft9LKak.mjs.map +0 -1
- package/dist/fts-manager-Beg3e4bI.mjs.map +0 -1
- package/dist/index-BB9sVisO.d.mts.map +0 -1
- package/dist/loader-CswroUbe.mjs.map +0 -1
- package/dist/manifest-builder-B8zjuH3f.mjs.map +0 -1
- package/dist/media-Bws9f18T.mjs.map +0 -1
- package/dist/menus-BCVSSp1z.mjs.map +0 -1
- package/dist/menus-Cl4kwdt7.mjs.map +0 -1
- package/dist/normalize-BuWa0lvd.mjs.map +0 -1
- package/dist/oauth-authorization-TpEJrYB7.mjs.map +0 -1
- package/dist/placeholder-D41vk11_.d.mts.map +0 -1
- package/dist/policy-DLQ--Hnm.mjs.map +0 -1
- package/dist/query-CpnRlBh8.mjs.map +0 -1
- package/dist/registry-TUVaid9Z.mjs.map +0 -1
- package/dist/relations-CA_QuMTU.mjs.map +0 -1
- package/dist/resolve-D-kqyKns.mjs.map +0 -1
- package/dist/runner-BObHz5FC.d.mts.map +0 -1
- package/dist/runner-C5NeAkBQ.mjs.map +0 -1
- package/dist/search-DfVzks89.mjs.map +0 -1
- package/dist/settings-CWb84sDm.mjs.map +0 -1
- package/dist/storage-query-DRyu3bSU.d.mts.map +0 -1
- package/dist/taxonomies-ChnU7Mc8.mjs.map +0 -1
- package/dist/taxonomies-Dd9JJv_a.mjs.map +0 -1
- package/dist/taxonomy-C_C_LBAU.mjs.map +0 -1
- package/dist/transport-BjbqNiPI.mjs.map +0 -1
- package/dist/types-BGmQ0uXs.mjs.map +0 -1
- package/dist/types-CNB-dj6F.d.mts.map +0 -1
- package/dist/types-D2NEXtgB.mjs.map +0 -1
- package/dist/types-slSqujQL.d.mts.map +0 -1
- package/dist/utils-TPt7w2cS.mjs.map +0 -1
- package/dist/version-DHmGpcch.mjs +0 -7
- package/dist/widgets-DA5XmvVC.mjs.map +0 -1
- package/dist/wxr-taxonomies-CrMonejI.d.mts.map +0 -1
- package/dist/wxr-taxonomies-RgRG0d5e.mjs.map +0 -1
- package/dist/zod-generator-D0JKy94C.mjs.map +0 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"snapshot-DYsG4uOq.mjs","names":[],"sources":["../src/api/handlers/snapshot.ts"],"sourcesContent":["/**\n * Snapshot handler — generates a portable database snapshot.\n *\n * Returns all content tables, schema definitions, and supporting data\n * needed to render content in an isolated preview database.\n *\n * Used by:\n * - DO preview database (EmDashPreviewDB.populateFromSnapshot)\n * - Future: CLI export, backup, site migration\n */\n\nimport type { Kysely } from \"kysely\";\nimport { sql } from \"kysely\";\n\nimport { listTableColumns, listTablesLike } from \"../../database/dialect-helpers.js\";\nimport type { Database } from \"../../database/types.js\";\n\n// ─�� Preview signature verification ──────────────────────────────\n\n/**\n * Verify HMAC-SHA256 preview signature using crypto.subtle.\n * Returns true if the signature is valid and not expired.\n */\nexport async function verifyPreviewSignature(\n\tsource: string,\n\texp: number,\n\tsig: string,\n\tsecret: string,\n): Promise<boolean> {\n\tif (exp < Date.now() / 1000) return false;\n\n\tconst encoder = new TextEncoder();\n\tconst key = await crypto.subtle.importKey(\n\t\t\"raw\",\n\t\tencoder.encode(secret),\n\t\t{ name: \"HMAC\", hash: \"SHA-256\" },\n\t\tfalse,\n\t\t[\"verify\"],\n\t);\n\n\tconst sigBytes = new Uint8Array(sig.length / 2);\n\tfor (let i = 0; i < sig.length; i += 2) {\n\t\tsigBytes[i / 2] = parseInt(sig.substring(i, i + 2), 16);\n\t}\n\n\treturn crypto.subtle.verify(\"HMAC\", key, sigBytes, encoder.encode(`${source}:${exp}`));\n}\n\n/**\n * Parse an X-Preview-Signature header value into its components.\n *\n * Format: \"source:exp:sig\" where source is a URL (contains colons),\n * exp is a unix timestamp, and sig is 64 hex chars.\n *\n * Parses from the right since source URLs contain colons.\n *\n * @returns Parsed components, or null if the format is invalid\n */\nexport function parsePreviewSignatureHeader(\n\theader: string,\n): { source: string; exp: number; sig: string } | null {\n\tconst lastColon = header.lastIndexOf(\":\");\n\tif (lastColon <= 0) return null;\n\n\tconst sig = header.substring(lastColon + 1);\n\tif (sig.length !== 64) return null;\n\n\tconst rest = header.substring(0, lastColon);\n\tconst secondLastColon = rest.lastIndexOf(\":\");\n\tif (secondLastColon <= 0) return null;\n\n\tconst source = rest.substring(0, secondLastColon);\n\tconst exp = parseInt(rest.substring(secondLastColon + 1), 10);\n\n\tif (isNaN(exp) || source.length === 0) return null;\n\n\treturn { source, exp, sig };\n}\n\n// ── Media URL rewriting ─────────────────────────────────────────\n\nconst MEDIA_FILE_PREFIX = \"/_emdash/api/media/file/\";\nconst MEDIA_FILE_SUFFIX = /[?#]/;\nconst EXTERNAL_OR_ROOT_URL = /^(?:[a-z][a-z0-9+.-]*:|\\/)/i;\n\n/**\n * Parse a JSON string value and inject `src` for local media objects.\n * Returns the original string if it's not a local media value.\n */\nfunction injectMediaSrc(jsonStr: string, origin: string): string {\n\ttry {\n\t\tconst obj = JSON.parse(jsonStr);\n\t\tif (typeof obj !== \"object\" || obj === null || Array.isArray(obj)) return jsonStr;\n\t\tif (injectMediaSrcInto(obj, origin)) {\n\t\t\treturn JSON.stringify(obj);\n\t\t}\n\t\treturn jsonStr;\n\t} catch {\n\t\treturn jsonStr;\n\t}\n}\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n\treturn typeof value === \"object\" && value !== null && !Array.isArray(value);\n}\n\n/**\n * Recursively walk an object and inject `src` into local media values.\n * Returns true if any modifications were made.\n */\nfunction injectMediaSrcInto(obj: Record<string, unknown>, origin: string): boolean {\n\tlet modified = false;\n\n\t// Check if this object itself is a local media value\n\tif ((obj.provider === \"local\" || (!obj.provider && obj.id && obj.meta)) && !obj.src) {\n\t\tconst meta = isRecord(obj.meta) ? obj.meta : undefined;\n\t\tconst storageKey = meta?.storageKey ?? obj.id;\n\t\tif (typeof storageKey === \"string\" && storageKey) {\n\t\t\tobj.src = `${origin}${MEDIA_FILE_PREFIX}${storageKey}`;\n\t\t\tmodified = true;\n\t\t}\n\t}\n\n\t// Recurse into nested objects/arrays (e.g. Portable Text with image blocks)\n\tfor (const value of Object.values(obj)) {\n\t\tif (Array.isArray(value)) {\n\t\t\tfor (const item of value) {\n\t\t\t\tif (isRecord(item)) {\n\t\t\t\t\tif (injectMediaSrcInto(item, origin)) {\n\t\t\t\t\t\tmodified = true;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t} else if (isRecord(value)) {\n\t\t\tif (injectMediaSrcInto(value, origin)) {\n\t\t\t\tmodified = true;\n\t\t\t}\n\t\t}\n\t}\n\n\treturn modified;\n}\n\n// ── Snapshot generation ─────────────────────────────────────────\n\n/**\n * Safe identifier pattern for snapshot table names.\n * More permissive than validateIdentifier() — allows leading underscores\n * (needed for system tables like _emdash_collections).\n */\nconst SAFE_TABLE_NAME = /^[a-z_][a-z0-9_]*$/;\n\n/** Snapshot shape consumed by the DO preview database */\nexport interface Snapshot {\n\ttables: Record<string, Record<string, unknown>[]>;\n\tschema: Record<\n\t\tstring,\n\t\t{\n\t\t\tcolumns: string[];\n\t\t\ttypes?: Record<string, string>;\n\t\t}\n\t>;\n\tgeneratedAt: string;\n}\n\n/**\n * System tables included in snapshots.\n * Content tables (ec_*) are discovered dynamically.\n */\nconst SYSTEM_TABLES = [\n\t\"_emdash_block_types\",\n\t\"_emdash_block_type_versions\",\n\t\"_emdash_collections\",\n\t\"_emdash_fields\",\n\t\"_emdash_taxonomy_defs\",\n\t\"_emdash_taxonomy_def_groups\",\n\t\"_emdash_menus\",\n\t\"_emdash_menu_items\",\n\t\"_emdash_sections\",\n\t\"_emdash_widget_areas\",\n\t\"_emdash_widgets\",\n\t\"_emdash_seo\",\n\t\"_emdash_migrations\",\n\t\"content_taxonomies\",\n\t\"taxonomies\",\n\t\"options\",\n\t\"media\",\n\t\"revisions\",\n] as const;\n\ntype SystemTable = (typeof SYSTEM_TABLES)[number];\ntype PublishedTablePolicy = \"full\" | \"content-linked\" | \"omit\";\n\n/**\n * Published snapshots are available to preview-signature callers, so every\n * system table must be classified explicitly. Adding a snapshot table without\n * choosing a policy is a type error rather than an accidental data export.\n */\nconst PUBLISHED_TABLE_POLICIES: Record<SystemTable, PublishedTablePolicy> = {\n\t_emdash_block_types: \"full\",\n\t_emdash_block_type_versions: \"full\",\n\t_emdash_collections: \"full\",\n\t_emdash_fields: \"full\",\n\t_emdash_taxonomy_defs: \"full\",\n\t_emdash_taxonomy_def_groups: \"full\",\n\t_emdash_menus: \"full\",\n\t_emdash_menu_items: \"content-linked\",\n\t_emdash_sections: \"full\",\n\t_emdash_widget_areas: \"full\",\n\t_emdash_widgets: \"full\",\n\t_emdash_seo: \"content-linked\",\n\t_emdash_migrations: \"full\",\n\tcontent_taxonomies: \"content-linked\",\n\ttaxonomies: \"content-linked\",\n\toptions: \"content-linked\",\n\tmedia: \"content-linked\",\n\trevisions: \"omit\",\n};\n\nconst SYSTEM_TABLE_SET: ReadonlySet<string> = new Set(SYSTEM_TABLES);\n\nfunction isSystemTable(tableName: string): tableName is SystemTable {\n\treturn SYSTEM_TABLE_SET.has(tableName);\n}\n\ninterface PublishedContentReferences {\n\tids: Set<string>;\n\ttranslationGroups: Set<string>;\n}\n\ninterface PublishedProjection {\n\tcontent: Map<string, PublishedContentReferences>;\n\ttaxonomyGroups: Set<string>;\n\tmediaIds: Set<string>;\n\tmediaStorageKeys: Set<string>;\n}\n\n/**\n * Table name prefixes excluded from snapshots (auth/security data).\n */\nconst EXCLUDED_PREFIXES = [\n\t\"_emdash_api_tokens\",\n\t\"_emdash_oauth_tokens\",\n\t\"_emdash_authorization_codes\",\n\t\"_emdash_device_codes\",\n\t\"_emdash_migrations_lock\",\n\t\"_emdash_transfer_\",\n\t\"_plugin_\",\n\t\"users\",\n\t\"sessions\",\n\t\"credentials\",\n\t\"challenges\",\n];\n\n/**\n * Options key prefixes safe for inclusion in snapshots.\n *\n * The options table contains plugin secrets (plugin:*), passkey challenges\n * (emdash:passkey_pending:*), and setup state that must not leak to\n * preview databases. Only site-level rendering settings are needed.\n */\nconst SAFE_OPTIONS_PREFIXES = [\"site:\"];\n\nfunction isExcluded(tableName: string): boolean {\n\treturn EXCLUDED_PREFIXES.some((prefix) => tableName.startsWith(prefix));\n}\n\ntype SnapshotColumnType = \"TEXT\" | \"INTEGER\" | \"REAL\" | \"BLOB\" | \"JSON\";\n\nfunction normalizeColumnType(type: string): SnapshotColumnType {\n\tswitch (type.toLowerCase()) {\n\t\tcase \"smallint\":\n\t\tcase \"integer\":\n\t\tcase \"bigint\":\n\t\tcase \"boolean\":\n\t\t\treturn \"INTEGER\";\n\t\tcase \"real\":\n\t\tcase \"double precision\":\n\t\tcase \"numeric\":\n\t\tcase \"decimal\":\n\t\t\treturn \"REAL\";\n\t\tcase \"blob\":\n\t\tcase \"bytea\":\n\t\t\treturn \"BLOB\";\n\t\tcase \"json\":\n\t\tcase \"jsonb\":\n\t\t\treturn \"JSON\";\n\t\tdefault:\n\t\t\treturn \"TEXT\";\n\t}\n}\n\nfunction normalizeRows(\n\trows: Record<string, unknown>[],\n\ttypes: Record<string, SnapshotColumnType>,\n): Record<string, unknown>[] {\n\tfor (const row of rows) {\n\t\tfor (const [column, type] of Object.entries(types)) {\n\t\t\tconst value = row[column];\n\t\t\tif (type === \"JSON\" && value !== null && value !== undefined && typeof value !== \"string\") {\n\t\t\t\trow[column] = JSON.stringify(value);\n\t\t\t}\n\t\t}\n\t}\n\treturn rows;\n}\n\nfunction createPublishedProjection(): PublishedProjection {\n\treturn {\n\t\tcontent: new Map(),\n\t\ttaxonomyGroups: new Set(),\n\t\tmediaIds: new Set(),\n\t\tmediaStorageKeys: new Set(),\n\t};\n}\n\nfunction readString(value: unknown): string | null {\n\treturn typeof value === \"string\" && value.length > 0 ? value : null;\n}\n\nfunction recordPublishedContent(\n\tprojection: PublishedProjection,\n\ttableName: string,\n\trows: Record<string, unknown>[],\n): void {\n\tconst references: PublishedContentReferences = {\n\t\tids: new Set(),\n\t\ttranslationGroups: new Set(),\n\t};\n\tfor (const row of rows) {\n\t\tconst id = readString(row.id);\n\t\tconst translationGroup = readString(row.translation_group);\n\t\tif (id) references.ids.add(id);\n\t\tif (translationGroup) references.translationGroups.add(translationGroup);\n\t}\n\tprojection.content.set(tableName.slice(\"ec_\".length), references);\n}\n\nfunction isPublishedContentReference(\n\tprojection: PublishedProjection,\n\tcollection: unknown,\n\treference: unknown,\n): boolean {\n\tconst collectionName = readString(collection);\n\tconst id = readString(reference);\n\tif (!collectionName || !id) return false;\n\tconst references = projection.content.get(collectionName);\n\treturn references?.ids.has(id) === true || references?.translationGroups.has(id) === true;\n}\n\nfunction collectMediaReferences(value: unknown, projection: PublishedProjection): void {\n\tif (typeof value === \"string\") {\n\t\tif (value.startsWith(MEDIA_FILE_PREFIX)) {\n\t\t\tconst storageKey = value.slice(MEDIA_FILE_PREFIX.length).split(MEDIA_FILE_SUFFIX, 1)[0];\n\t\t\tif (storageKey) projection.mediaStorageKeys.add(storageKey);\n\t\t\treturn;\n\t\t}\n\t\tconst trimmed = value.trimStart();\n\t\tif (trimmed.startsWith(\"{\") || trimmed.startsWith(\"[\")) {\n\t\t\ttry {\n\t\t\t\tcollectMediaReferences(JSON.parse(value), projection);\n\t\t\t} catch {\n\t\t\t\t// Not structured data.\n\t\t\t}\n\t\t}\n\t\treturn;\n\t}\n\tif (Array.isArray(value)) {\n\t\tfor (const item of value) collectMediaReferences(item, projection);\n\t\treturn;\n\t}\n\tif (!isRecord(value)) return;\n\n\tconst mediaId = readString(value.mediaId);\n\tif (mediaId) projection.mediaIds.add(mediaId);\n\n\tconst provider = readString(value.provider);\n\tconst meta = isRecord(value.meta) ? value.meta : null;\n\tconst localMediaId = readString(value.id);\n\tif ((provider === \"local\" || (!provider && meta)) && localMediaId) {\n\t\tprojection.mediaIds.add(localMediaId);\n\t}\n\tconst storageKey = readString(value.storageKey) ?? readString(meta?.storageKey);\n\tif (storageKey) projection.mediaStorageKeys.add(storageKey);\n\n\tconst asset = isRecord(value.asset) ? value.asset : null;\n\tconst assetRef = readString(asset?._ref);\n\tif (assetRef) {\n\t\tprojection.mediaIds.add(assetRef);\n\t\tprojection.mediaStorageKeys.add(assetRef);\n\t}\n\n\tfor (const child of Object.values(value)) collectMediaReferences(child, projection);\n}\n\nfunction projectTaxonomyRows(\n\trows: Record<string, unknown>[],\n\tprojection: PublishedProjection,\n): Record<string, unknown>[] {\n\tconst includedGroups = new Set(projection.taxonomyGroups);\n\tconst includedIds = new Set(projection.taxonomyGroups);\n\tlet changed = true;\n\twhile (changed) {\n\t\tchanged = false;\n\t\tfor (const row of rows) {\n\t\t\tconst id = readString(row.id);\n\t\t\tconst group = readString(row.translation_group);\n\t\t\tif (!id) continue;\n\t\t\tif (includedIds.has(id) || (group && includedGroups.has(group))) {\n\t\t\t\tif (!includedIds.has(id)) {\n\t\t\t\t\tincludedIds.add(id);\n\t\t\t\t\tchanged = true;\n\t\t\t\t}\n\t\t\t\tif (group && !includedGroups.has(group)) {\n\t\t\t\t\tincludedGroups.add(group);\n\t\t\t\t\tchanged = true;\n\t\t\t\t}\n\t\t\t\tconst parentId = readString(row.parent_id);\n\t\t\t\tif (parentId && !includedIds.has(parentId)) {\n\t\t\t\t\tincludedIds.add(parentId);\n\t\t\t\t\tchanged = true;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\treturn rows.filter((row) => {\n\t\tconst id = readString(row.id);\n\t\tconst group = readString(row.translation_group);\n\t\treturn (id && includedIds.has(id)) || (group && includedGroups.has(group));\n\t});\n}\n\nfunction projectPublishedRows(\n\ttableName: SystemTable,\n\trows: Record<string, unknown>[],\n\tprojection: PublishedProjection,\n): Record<string, unknown>[] {\n\tswitch (tableName) {\n\t\tcase \"_emdash_seo\":\n\t\t\treturn rows.filter((row) => {\n\t\t\t\tconst published = isPublishedContentReference(projection, row.collection, row.content_id);\n\t\t\t\tif (!published) return false;\n\t\t\t\tconst image = readString(row.seo_image);\n\t\t\t\tif (image) {\n\t\t\t\t\tcollectMediaReferences(image, projection);\n\t\t\t\t\tif (!EXTERNAL_OR_ROOT_URL.test(image)) {\n\t\t\t\t\t\tprojection.mediaIds.add(image);\n\t\t\t\t\t\tprojection.mediaStorageKeys.add(image);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\treturn true;\n\t\t\t});\n\t\tcase \"content_taxonomies\":\n\t\t\treturn rows.filter((row) => {\n\t\t\t\tconst published = isPublishedContentReference(projection, row.collection, row.entry_id);\n\t\t\t\tconst taxonomyGroup = readString(row.taxonomy_id);\n\t\t\t\tif (published && taxonomyGroup) projection.taxonomyGroups.add(taxonomyGroup);\n\t\t\t\treturn published;\n\t\t\t});\n\t\tcase \"taxonomies\":\n\t\t\treturn projectTaxonomyRows(rows, projection);\n\t\tcase \"_emdash_menu_items\":\n\t\t\treturn rows.filter((row) => {\n\t\t\t\tconst type = readString(row.type);\n\t\t\t\tconst referenceId = readString(row.reference_id);\n\t\t\t\tif (!referenceId || type === \"custom\") return true;\n\t\t\t\tif (type === \"taxonomy\") {\n\t\t\t\t\tprojection.taxonomyGroups.add(referenceId);\n\t\t\t\t\treturn true;\n\t\t\t\t}\n\t\t\t\tif (type === \"collection\" && !row.reference_id) return true;\n\t\t\t\tconst collection =\n\t\t\t\t\treadString(row.reference_collection) ??\n\t\t\t\t\t(type === \"post\" || type === \"page\" ? `${type}s` : null);\n\t\t\t\treturn isPublishedContentReference(projection, collection, referenceId);\n\t\t\t});\n\t\tcase \"media\":\n\t\t\treturn rows.filter((row) => {\n\t\t\t\tconst id = readString(row.id);\n\t\t\t\tconst storageKey = readString(row.storage_key);\n\t\t\t\treturn (\n\t\t\t\t\t(id !== null && projection.mediaIds.has(id)) ||\n\t\t\t\t\t(storageKey !== null && projection.mediaStorageKeys.has(storageKey))\n\t\t\t\t);\n\t\t\t});\n\t\tcase \"options\":\n\t\t\treturn rows;\n\t\tdefault:\n\t\t\treturn [];\n\t}\n}\n\nexport interface GenerateSnapshotOptions {\n\t/** Include draft and scheduled content (default: false) */\n\tincludeDrafts?: boolean;\n\t/** Include trashed content (deleted_at set). Used by backups (default: false) */\n\tincludeTrashed?: boolean;\n\t/** Origin URL for absolutizing local media URLs (e.g. \"https://mysite.com\") */\n\torigin?: string;\n\t/**\n\t * Allowlist of options-table key prefixes to include (default:\n\t * `SAFE_OPTIONS_PREFIXES`). Callers widening this must never include a\n\t * prefix that matches secrets (`emdash:preview_secret`, `plugin:`,\n\t * `emdash:passkey_pending:`) — the output may be user-downloadable.\n\t */\n\toptionPrefixes?: string[];\n\t/** Exact options-table keys to include in addition to `optionPrefixes`. */\n\toptionKeys?: string[];\n}\n\n/**\n * Generate a portable database snapshot.\n *\n * Discovers ec_* content tables dynamically, exports system tables\n * needed for rendering, and includes schema info for table recreation.\n */\nexport async function generateSnapshot(\n\tdb: Kysely<Database>,\n\toptions?: GenerateSnapshotOptions,\n): Promise<Snapshot> {\n\tconst includeDrafts = options?.includeDrafts ?? false;\n\tconst includeTrashed = options?.includeTrashed ?? false;\n\tconst optionPrefixes = options?.optionPrefixes ?? SAFE_OPTIONS_PREFIXES;\n\tconst optionKeys = new Set(options?.optionKeys);\n\tconst publishedOnly = !includeDrafts && !includeTrashed;\n\tconst publishedProjection = createPublishedProjection();\n\n\tconst contentTables = await listTablesLike(db, \"ec_%\");\n\n\t// Build list of all tables to export\n\tconst allTables = [...contentTables, ...SYSTEM_TABLES];\n\n\tconst tables: Record<string, Record<string, unknown>[]> = {};\n\tconst schema: Record<string, { columns: string[]; types?: Record<string, string> }> = {};\n\n\tfor (const tableName of allTables) {\n\t\tif (isExcluded(tableName)) continue;\n\n\t\t// Content table names come from the database catalog. Validate them\n\t\t// before passing them to sql.ref().\n\t\tif (!SAFE_TABLE_NAME.test(tableName)) continue;\n\n\t\tconst columnInfo = await listTableColumns(db, tableName);\n\t\tif (columnInfo.length === 0) continue;\n\n\t\tconst columns = columnInfo.map((column) => column.name);\n\t\tconst types: Record<string, SnapshotColumnType> = {};\n\t\tfor (const column of columnInfo) {\n\t\t\ttypes[column.name] = normalizeColumnType(column.type);\n\t\t}\n\n\t\tschema[tableName] = { columns, types };\n\n\t\tlet rows: Record<string, unknown>[];\n\n\t\tif (tableName.startsWith(\"ec_\")) {\n\t\t\tif (includeTrashed) {\n\t\t\t\trows = (\n\t\t\t\t\tawait sql<Record<string, unknown>>`\n\t\t\t\t\t\tSELECT * FROM ${sql.ref(tableName)}\n\t\t\t\t\t`.execute(db)\n\t\t\t\t).rows;\n\t\t\t} else if (includeDrafts) {\n\t\t\t\trows = (\n\t\t\t\t\tawait sql<Record<string, unknown>>`\n\t\t\t\t\t\tSELECT * FROM ${sql.ref(tableName)}\n\t\t\t\t\t\tWHERE deleted_at IS NULL\n\t\t\t\t\t`.execute(db)\n\t\t\t\t).rows;\n\t\t\t} else {\n\t\t\t\trows = (\n\t\t\t\t\tawait sql<Record<string, unknown>>`\n\t\t\t\t\t\tSELECT * FROM ${sql.ref(tableName)}\n\t\t\t\t\t\tWHERE deleted_at IS NULL\n\t\t\t\t\t\tAND status = 'published'\n\t\t\t\t\t`.execute(db)\n\t\t\t\t).rows;\n\t\t\t}\n\t\t} else if (\n\t\t\tpublishedOnly &&\n\t\t\tisSystemTable(tableName) &&\n\t\t\tPUBLISHED_TABLE_POLICIES[tableName] === \"omit\"\n\t\t) {\n\t\t\trows = [];\n\t\t} else if (tableName === \"options\") {\n\t\t\trows = (\n\t\t\t\tawait sql<Record<string, unknown>>`\n\t\t\t\t\tSELECT * FROM ${sql.ref(tableName)}\n\t\t\t\t`.execute(db)\n\t\t\t).rows.filter((row) => {\n\t\t\t\tconst name = typeof row.name === \"string\" ? row.name : \"\";\n\t\t\t\treturn optionKeys.has(name) || optionPrefixes.some((prefix) => name.startsWith(prefix));\n\t\t\t});\n\t\t} else {\n\t\t\trows = (\n\t\t\t\tawait sql<Record<string, unknown>>`\n\t\t\t\t\tSELECT * FROM ${sql.ref(tableName)}\n\t\t\t\t`.execute(db)\n\t\t\t).rows;\n\t\t}\n\n\t\tif (publishedOnly) {\n\t\t\tif (tableName.startsWith(\"ec_\")) {\n\t\t\t\trecordPublishedContent(publishedProjection, tableName, rows);\n\t\t\t} else if (\n\t\t\t\tisSystemTable(tableName) &&\n\t\t\t\tPUBLISHED_TABLE_POLICIES[tableName] === \"content-linked\"\n\t\t\t) {\n\t\t\t\trows = projectPublishedRows(tableName, rows, publishedProjection);\n\t\t\t}\n\t\t\tfor (const row of rows) collectMediaReferences(row, publishedProjection);\n\t\t}\n\n\t\tif (rows.length > 0) {\n\t\t\ttables[tableName] = normalizeRows(rows, types);\n\t\t}\n\t}\n\n\t// Absolutize local media URLs in content tables so snapshots are portable.\n\t// Local image fields are stored as JSON with provider:\"local\" and\n\t// meta.storageKey but no src — the URL is derived at render time.\n\t// For snapshots consumed by external preview services, inject src now.\n\tif (options?.origin) {\n\t\tconst origin = options.origin;\n\t\tfor (const [tableName, rows] of Object.entries(tables)) {\n\t\t\tif (!tableName.startsWith(\"ec_\")) continue;\n\t\t\tfor (const row of rows) {\n\t\t\t\tfor (const [col, value] of Object.entries(row)) {\n\t\t\t\t\tif (typeof value !== \"string\" || !value.startsWith(\"{\")) continue;\n\t\t\t\t\trow[col] = injectMediaSrc(value, origin);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\treturn {\n\t\ttables,\n\t\tschema,\n\t\tgeneratedAt: new Date().toISOString(),\n\t};\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"snapshot-BjaXDZQ5.mjs","names":[],"sources":["../src/api/handlers/snapshot.ts"],"sourcesContent":["/**\n * Snapshot handler — generates a portable database snapshot.\n *\n * Returns all content tables, schema definitions, and supporting data\n * needed to render content in an isolated preview database.\n *\n * Used by:\n * - DO preview database (EmDashPreviewDB.populateFromSnapshot)\n * - Future: CLI export, backup, site migration\n */\n\nimport type { Kysely } from \"kysely\";\nimport { sql } from \"kysely\";\n\nimport { listTableColumns, listTablesLike } from \"../../database/dialect-helpers.js\";\nimport type { Database } from \"../../database/types.js\";\n\n// ─�� Preview signature verification ──────────────────────────────\n\n/**\n * Verify HMAC-SHA256 preview signature using crypto.subtle.\n * Returns true if the signature is valid and not expired.\n */\nexport async function verifyPreviewSignature(\n\tsource: string,\n\texp: number,\n\tsig: string,\n\tsecret: string,\n): Promise<boolean> {\n\tif (exp < Date.now() / 1000) return false;\n\n\tconst encoder = new TextEncoder();\n\tconst key = await crypto.subtle.importKey(\n\t\t\"raw\",\n\t\tencoder.encode(secret),\n\t\t{ name: \"HMAC\", hash: \"SHA-256\" },\n\t\tfalse,\n\t\t[\"verify\"],\n\t);\n\n\tconst sigBytes = new Uint8Array(sig.length / 2);\n\tfor (let i = 0; i < sig.length; i += 2) {\n\t\tsigBytes[i / 2] = parseInt(sig.substring(i, i + 2), 16);\n\t}\n\n\treturn crypto.subtle.verify(\"HMAC\", key, sigBytes, encoder.encode(`${source}:${exp}`));\n}\n\n/**\n * Parse an X-Preview-Signature header value into its components.\n *\n * Format: \"source:exp:sig\" where source is a URL (contains colons),\n * exp is a unix timestamp, and sig is 64 hex chars.\n *\n * Parses from the right since source URLs contain colons.\n *\n * @returns Parsed components, or null if the format is invalid\n */\nexport function parsePreviewSignatureHeader(\n\theader: string,\n): { source: string; exp: number; sig: string } | null {\n\tconst lastColon = header.lastIndexOf(\":\");\n\tif (lastColon <= 0) return null;\n\n\tconst sig = header.substring(lastColon + 1);\n\tif (sig.length !== 64) return null;\n\n\tconst rest = header.substring(0, lastColon);\n\tconst secondLastColon = rest.lastIndexOf(\":\");\n\tif (secondLastColon <= 0) return null;\n\n\tconst source = rest.substring(0, secondLastColon);\n\tconst exp = parseInt(rest.substring(secondLastColon + 1), 10);\n\n\tif (isNaN(exp) || source.length === 0) return null;\n\n\treturn { source, exp, sig };\n}\n\n// ── Media URL rewriting ─────────────────────────────────────────\n\nconst MEDIA_FILE_PREFIX = \"/_emdash/api/media/file/\";\nconst MEDIA_FILE_SUFFIX = /[?#]/;\nconst EXTERNAL_OR_ROOT_URL = /^(?:[a-z][a-z0-9+.-]*:|\\/)/i;\n\n/**\n * Parse a JSON string value and inject `src` for local media objects.\n * Returns the original string if it's not a local media value.\n */\nfunction injectMediaSrc(jsonStr: string, origin: string): string {\n\ttry {\n\t\tconst obj = JSON.parse(jsonStr);\n\t\tif (typeof obj !== \"object\" || obj === null || Array.isArray(obj)) return jsonStr;\n\t\tif (injectMediaSrcInto(obj, origin)) {\n\t\t\treturn JSON.stringify(obj);\n\t\t}\n\t\treturn jsonStr;\n\t} catch {\n\t\treturn jsonStr;\n\t}\n}\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n\treturn typeof value === \"object\" && value !== null && !Array.isArray(value);\n}\n\n/**\n * Recursively walk an object and inject `src` into local media values.\n * Returns true if any modifications were made.\n */\nfunction injectMediaSrcInto(obj: Record<string, unknown>, origin: string): boolean {\n\tlet modified = false;\n\n\t// Check if this object itself is a local media value\n\tif ((obj.provider === \"local\" || (!obj.provider && obj.id && obj.meta)) && !obj.src) {\n\t\tconst meta = isRecord(obj.meta) ? obj.meta : undefined;\n\t\tconst storageKey = meta?.storageKey ?? obj.id;\n\t\tif (typeof storageKey === \"string\" && storageKey) {\n\t\t\tobj.src = `${origin}${MEDIA_FILE_PREFIX}${storageKey}`;\n\t\t\tmodified = true;\n\t\t}\n\t}\n\n\t// Recurse into nested objects/arrays (e.g. Portable Text with image blocks)\n\tfor (const value of Object.values(obj)) {\n\t\tif (Array.isArray(value)) {\n\t\t\tfor (const item of value) {\n\t\t\t\tif (isRecord(item)) {\n\t\t\t\t\tif (injectMediaSrcInto(item, origin)) {\n\t\t\t\t\t\tmodified = true;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t} else if (isRecord(value)) {\n\t\t\tif (injectMediaSrcInto(value, origin)) {\n\t\t\t\tmodified = true;\n\t\t\t}\n\t\t}\n\t}\n\n\treturn modified;\n}\n\n// ── Snapshot generation ─────────────────────────────────────────\n\n/**\n * Safe identifier pattern for snapshot table names.\n * More permissive than validateIdentifier() — allows leading underscores\n * (needed for system tables like _emdash_collections).\n */\nconst SAFE_TABLE_NAME = /^[a-z_][a-z0-9_]*$/;\n\n/** Snapshot shape consumed by the DO preview database */\nexport interface Snapshot {\n\ttables: Record<string, Record<string, unknown>[]>;\n\tschema: Record<\n\t\tstring,\n\t\t{\n\t\t\tcolumns: string[];\n\t\t\ttypes?: Record<string, string>;\n\t\t}\n\t>;\n\tgeneratedAt: string;\n}\n\n/**\n * System tables included in snapshots.\n * Content tables (ec_*) are discovered dynamically.\n */\nconst SYSTEM_TABLES = [\n\t\"_emdash_block_types\",\n\t\"_emdash_block_type_versions\",\n\t\"_emdash_collections\",\n\t\"_emdash_fields\",\n\t\"_emdash_taxonomy_defs\",\n\t\"_emdash_taxonomy_def_groups\",\n\t\"_emdash_menus\",\n\t\"_emdash_menu_items\",\n\t\"_emdash_sections\",\n\t\"_emdash_widget_areas\",\n\t\"_emdash_widgets\",\n\t\"_emdash_seo\",\n\t\"_emdash_migrations\",\n\t\"content_taxonomies\",\n\t\"taxonomies\",\n\t\"options\",\n\t\"media\",\n\t\"revisions\",\n] as const;\n\ntype SystemTable = (typeof SYSTEM_TABLES)[number];\ntype PublishedTablePolicy = \"full\" | \"content-linked\" | \"omit\";\n\n/**\n * Published snapshots are available to preview-signature callers, so every\n * system table must be classified explicitly. Adding a snapshot table without\n * choosing a policy is a type error rather than an accidental data export.\n */\nconst PUBLISHED_TABLE_POLICIES: Record<SystemTable, PublishedTablePolicy> = {\n\t_emdash_block_types: \"full\",\n\t_emdash_block_type_versions: \"full\",\n\t_emdash_collections: \"full\",\n\t_emdash_fields: \"full\",\n\t_emdash_taxonomy_defs: \"full\",\n\t_emdash_taxonomy_def_groups: \"full\",\n\t_emdash_menus: \"full\",\n\t_emdash_menu_items: \"content-linked\",\n\t_emdash_sections: \"full\",\n\t_emdash_widget_areas: \"full\",\n\t_emdash_widgets: \"full\",\n\t_emdash_seo: \"content-linked\",\n\t_emdash_migrations: \"full\",\n\tcontent_taxonomies: \"content-linked\",\n\ttaxonomies: \"content-linked\",\n\toptions: \"content-linked\",\n\tmedia: \"content-linked\",\n\trevisions: \"omit\",\n};\n\nconst SYSTEM_TABLE_SET: ReadonlySet<string> = new Set(SYSTEM_TABLES);\n\nfunction isSystemTable(tableName: string): tableName is SystemTable {\n\treturn SYSTEM_TABLE_SET.has(tableName);\n}\n\ninterface PublishedContentReferences {\n\tids: Set<string>;\n\ttranslationGroups: Set<string>;\n}\n\ninterface PublishedProjection {\n\tcontent: Map<string, PublishedContentReferences>;\n\ttaxonomyGroups: Set<string>;\n\tmediaIds: Set<string>;\n\tmediaStorageKeys: Set<string>;\n}\n\n/**\n * Table name prefixes excluded from snapshots (auth/security data).\n */\nconst EXCLUDED_PREFIXES = [\n\t\"_emdash_api_tokens\",\n\t\"_emdash_oauth_tokens\",\n\t\"_emdash_authorization_codes\",\n\t\"_emdash_device_codes\",\n\t\"_emdash_migrations_lock\",\n\t\"_emdash_transfer_\",\n\t\"_plugin_\",\n\t\"users\",\n\t\"sessions\",\n\t\"credentials\",\n\t\"challenges\",\n];\n\n/**\n * Options key prefixes safe for inclusion in snapshots.\n *\n * The options table contains plugin secrets (plugin:*), passkey challenges\n * (emdash:passkey_pending:*), and setup state that must not leak to\n * preview databases. Only site-level rendering settings are needed.\n */\nconst SAFE_OPTIONS_PREFIXES = [\"site:\"];\n\nfunction isExcluded(tableName: string): boolean {\n\treturn EXCLUDED_PREFIXES.some((prefix) => tableName.startsWith(prefix));\n}\n\ntype SnapshotColumnType = \"TEXT\" | \"INTEGER\" | \"REAL\" | \"BLOB\" | \"JSON\";\n\nfunction normalizeColumnType(type: string): SnapshotColumnType {\n\tswitch (type.toLowerCase()) {\n\t\tcase \"smallint\":\n\t\tcase \"integer\":\n\t\tcase \"bigint\":\n\t\tcase \"boolean\":\n\t\t\treturn \"INTEGER\";\n\t\tcase \"real\":\n\t\tcase \"double precision\":\n\t\tcase \"numeric\":\n\t\tcase \"decimal\":\n\t\t\treturn \"REAL\";\n\t\tcase \"blob\":\n\t\tcase \"bytea\":\n\t\t\treturn \"BLOB\";\n\t\tcase \"json\":\n\t\tcase \"jsonb\":\n\t\t\treturn \"JSON\";\n\t\tdefault:\n\t\t\treturn \"TEXT\";\n\t}\n}\n\nfunction normalizeRows(\n\trows: Record<string, unknown>[],\n\ttypes: Record<string, SnapshotColumnType>,\n): Record<string, unknown>[] {\n\tfor (const row of rows) {\n\t\tfor (const [column, type] of Object.entries(types)) {\n\t\t\tconst value = row[column];\n\t\t\tif (type === \"JSON\" && value !== null && value !== undefined && typeof value !== \"string\") {\n\t\t\t\trow[column] = JSON.stringify(value);\n\t\t\t}\n\t\t}\n\t}\n\treturn rows;\n}\n\nfunction createPublishedProjection(): PublishedProjection {\n\treturn {\n\t\tcontent: new Map(),\n\t\ttaxonomyGroups: new Set(),\n\t\tmediaIds: new Set(),\n\t\tmediaStorageKeys: new Set(),\n\t};\n}\n\nfunction readString(value: unknown): string | null {\n\treturn typeof value === \"string\" && value.length > 0 ? value : null;\n}\n\nfunction recordPublishedContent(\n\tprojection: PublishedProjection,\n\ttableName: string,\n\trows: Record<string, unknown>[],\n): void {\n\tconst references: PublishedContentReferences = {\n\t\tids: new Set(),\n\t\ttranslationGroups: new Set(),\n\t};\n\tfor (const row of rows) {\n\t\tconst id = readString(row.id);\n\t\tconst translationGroup = readString(row.translation_group);\n\t\tif (id) references.ids.add(id);\n\t\tif (translationGroup) references.translationGroups.add(translationGroup);\n\t}\n\tprojection.content.set(tableName.slice(\"ec_\".length), references);\n}\n\nfunction isPublishedContentReference(\n\tprojection: PublishedProjection,\n\tcollection: unknown,\n\treference: unknown,\n): boolean {\n\tconst collectionName = readString(collection);\n\tconst id = readString(reference);\n\tif (!collectionName || !id) return false;\n\tconst references = projection.content.get(collectionName);\n\treturn references?.ids.has(id) === true || references?.translationGroups.has(id) === true;\n}\n\nfunction collectMediaReferences(value: unknown, projection: PublishedProjection): void {\n\tif (typeof value === \"string\") {\n\t\tif (value.startsWith(MEDIA_FILE_PREFIX)) {\n\t\t\tconst storageKey = value.slice(MEDIA_FILE_PREFIX.length).split(MEDIA_FILE_SUFFIX, 1)[0];\n\t\t\tif (storageKey) projection.mediaStorageKeys.add(storageKey);\n\t\t\treturn;\n\t\t}\n\t\tconst trimmed = value.trimStart();\n\t\tif (trimmed.startsWith(\"{\") || trimmed.startsWith(\"[\")) {\n\t\t\ttry {\n\t\t\t\tcollectMediaReferences(JSON.parse(value), projection);\n\t\t\t} catch {\n\t\t\t\t// Not structured data.\n\t\t\t}\n\t\t}\n\t\treturn;\n\t}\n\tif (Array.isArray(value)) {\n\t\tfor (const item of value) collectMediaReferences(item, projection);\n\t\treturn;\n\t}\n\tif (!isRecord(value)) return;\n\n\tconst mediaId = readString(value.mediaId);\n\tif (mediaId) projection.mediaIds.add(mediaId);\n\n\tconst provider = readString(value.provider);\n\tconst meta = isRecord(value.meta) ? value.meta : null;\n\tconst localMediaId = readString(value.id);\n\tif ((provider === \"local\" || (!provider && meta)) && localMediaId) {\n\t\tprojection.mediaIds.add(localMediaId);\n\t}\n\tconst storageKey = readString(value.storageKey) ?? readString(meta?.storageKey);\n\tif (storageKey) projection.mediaStorageKeys.add(storageKey);\n\n\tconst asset = isRecord(value.asset) ? value.asset : null;\n\tconst assetRef = readString(asset?._ref);\n\tif (assetRef) {\n\t\tprojection.mediaIds.add(assetRef);\n\t\tprojection.mediaStorageKeys.add(assetRef);\n\t}\n\n\tfor (const child of Object.values(value)) collectMediaReferences(child, projection);\n}\n\nfunction projectTaxonomyRows(\n\trows: Record<string, unknown>[],\n\tprojection: PublishedProjection,\n): Record<string, unknown>[] {\n\tconst includedGroups = new Set(projection.taxonomyGroups);\n\tconst includedIds = new Set(projection.taxonomyGroups);\n\tlet changed = true;\n\twhile (changed) {\n\t\tchanged = false;\n\t\tfor (const row of rows) {\n\t\t\tconst id = readString(row.id);\n\t\t\tconst group = readString(row.translation_group);\n\t\t\tif (!id) continue;\n\t\t\tif (includedIds.has(id) || (group && includedGroups.has(group))) {\n\t\t\t\tif (!includedIds.has(id)) {\n\t\t\t\t\tincludedIds.add(id);\n\t\t\t\t\tchanged = true;\n\t\t\t\t}\n\t\t\t\tif (group && !includedGroups.has(group)) {\n\t\t\t\t\tincludedGroups.add(group);\n\t\t\t\t\tchanged = true;\n\t\t\t\t}\n\t\t\t\tconst parentId = readString(row.parent_id);\n\t\t\t\tif (parentId && !includedIds.has(parentId)) {\n\t\t\t\t\tincludedIds.add(parentId);\n\t\t\t\t\tchanged = true;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\treturn rows.filter((row) => {\n\t\tconst id = readString(row.id);\n\t\tconst group = readString(row.translation_group);\n\t\treturn (id && includedIds.has(id)) || (group && includedGroups.has(group));\n\t});\n}\n\nfunction projectPublishedRows(\n\ttableName: SystemTable,\n\trows: Record<string, unknown>[],\n\tprojection: PublishedProjection,\n): Record<string, unknown>[] {\n\tswitch (tableName) {\n\t\tcase \"_emdash_seo\":\n\t\t\treturn rows.filter((row) => {\n\t\t\t\tconst published = isPublishedContentReference(projection, row.collection, row.content_id);\n\t\t\t\tif (!published) return false;\n\t\t\t\tconst image = readString(row.seo_image);\n\t\t\t\tif (image) {\n\t\t\t\t\tcollectMediaReferences(image, projection);\n\t\t\t\t\tif (!EXTERNAL_OR_ROOT_URL.test(image)) {\n\t\t\t\t\t\tprojection.mediaIds.add(image);\n\t\t\t\t\t\tprojection.mediaStorageKeys.add(image);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\treturn true;\n\t\t\t});\n\t\tcase \"content_taxonomies\":\n\t\t\treturn rows.filter((row) => {\n\t\t\t\tconst published = isPublishedContentReference(projection, row.collection, row.entry_id);\n\t\t\t\tconst taxonomyGroup = readString(row.taxonomy_id);\n\t\t\t\tif (published && taxonomyGroup) projection.taxonomyGroups.add(taxonomyGroup);\n\t\t\t\treturn published;\n\t\t\t});\n\t\tcase \"taxonomies\":\n\t\t\treturn projectTaxonomyRows(rows, projection);\n\t\tcase \"_emdash_menu_items\":\n\t\t\treturn rows.filter((row) => {\n\t\t\t\tconst type = readString(row.type);\n\t\t\t\tconst referenceId = readString(row.reference_id);\n\t\t\t\tif (!referenceId || type === \"custom\") return true;\n\t\t\t\tif (type === \"taxonomy\") {\n\t\t\t\t\tprojection.taxonomyGroups.add(referenceId);\n\t\t\t\t\treturn true;\n\t\t\t\t}\n\t\t\t\tif (type === \"collection\" && !row.reference_id) return true;\n\t\t\t\tconst collection =\n\t\t\t\t\treadString(row.reference_collection) ??\n\t\t\t\t\t(type === \"post\" || type === \"page\" ? `${type}s` : null);\n\t\t\t\treturn isPublishedContentReference(projection, collection, referenceId);\n\t\t\t});\n\t\tcase \"media\":\n\t\t\treturn rows.filter((row) => {\n\t\t\t\tconst id = readString(row.id);\n\t\t\t\tconst storageKey = readString(row.storage_key);\n\t\t\t\treturn (\n\t\t\t\t\t(id !== null && projection.mediaIds.has(id)) ||\n\t\t\t\t\t(storageKey !== null && projection.mediaStorageKeys.has(storageKey))\n\t\t\t\t);\n\t\t\t});\n\t\tcase \"options\":\n\t\t\treturn rows;\n\t\tdefault:\n\t\t\treturn [];\n\t}\n}\n\nexport interface GenerateSnapshotOptions {\n\t/** Include draft and scheduled content (default: false) */\n\tincludeDrafts?: boolean;\n\t/** Include trashed content (deleted_at set). Used by backups (default: false) */\n\tincludeTrashed?: boolean;\n\t/** Origin URL for absolutizing local media URLs (e.g. \"https://mysite.com\") */\n\torigin?: string;\n\t/**\n\t * Allowlist of options-table key prefixes to include (default:\n\t * `SAFE_OPTIONS_PREFIXES`). Callers widening this must never include a\n\t * prefix that matches secrets (`emdash:preview_secret`, `plugin:`,\n\t * `emdash:passkey_pending:`) — the output may be user-downloadable.\n\t */\n\toptionPrefixes?: string[];\n\t/** Exact options-table keys to include in addition to `optionPrefixes`. */\n\toptionKeys?: string[];\n}\n\n/**\n * Generate a portable database snapshot.\n *\n * Discovers ec_* content tables dynamically, exports system tables\n * needed for rendering, and includes schema info for table recreation.\n */\nexport async function generateSnapshot(\n\tdb: Kysely<Database>,\n\toptions?: GenerateSnapshotOptions,\n): Promise<Snapshot> {\n\tconst includeDrafts = options?.includeDrafts ?? false;\n\tconst includeTrashed = options?.includeTrashed ?? false;\n\tconst optionPrefixes = options?.optionPrefixes ?? SAFE_OPTIONS_PREFIXES;\n\tconst optionKeys = new Set(options?.optionKeys);\n\tconst publishedOnly = !includeDrafts && !includeTrashed;\n\tconst publishedProjection = createPublishedProjection();\n\n\tconst contentTables = await listTablesLike(db, \"ec_%\");\n\n\t// Build list of all tables to export\n\tconst allTables = [...contentTables, ...SYSTEM_TABLES];\n\n\tconst tables: Record<string, Record<string, unknown>[]> = {};\n\tconst schema: Record<string, { columns: string[]; types?: Record<string, string> }> = {};\n\n\tfor (const tableName of allTables) {\n\t\tif (isExcluded(tableName)) continue;\n\n\t\t// Content table names come from the database catalog. Validate them\n\t\t// before passing them to sql.ref().\n\t\tif (!SAFE_TABLE_NAME.test(tableName)) continue;\n\n\t\tconst columnInfo = await listTableColumns(db, tableName);\n\t\tif (columnInfo.length === 0) continue;\n\n\t\tconst columns = columnInfo.map((column) => column.name);\n\t\tconst types: Record<string, SnapshotColumnType> = {};\n\t\tfor (const column of columnInfo) {\n\t\t\ttypes[column.name] = normalizeColumnType(column.type);\n\t\t}\n\n\t\tschema[tableName] = { columns, types };\n\n\t\tlet rows: Record<string, unknown>[];\n\n\t\tif (tableName.startsWith(\"ec_\")) {\n\t\t\tif (includeTrashed) {\n\t\t\t\trows = (\n\t\t\t\t\tawait sql<Record<string, unknown>>`\n\t\t\t\t\t\tSELECT * FROM ${sql.ref(tableName)}\n\t\t\t\t\t`.execute(db)\n\t\t\t\t).rows;\n\t\t\t} else if (includeDrafts) {\n\t\t\t\trows = (\n\t\t\t\t\tawait sql<Record<string, unknown>>`\n\t\t\t\t\t\tSELECT * FROM ${sql.ref(tableName)}\n\t\t\t\t\t\tWHERE deleted_at IS NULL\n\t\t\t\t\t`.execute(db)\n\t\t\t\t).rows;\n\t\t\t} else {\n\t\t\t\trows = (\n\t\t\t\t\tawait sql<Record<string, unknown>>`\n\t\t\t\t\t\tSELECT * FROM ${sql.ref(tableName)}\n\t\t\t\t\t\tWHERE deleted_at IS NULL\n\t\t\t\t\t\tAND status = 'published'\n\t\t\t\t\t`.execute(db)\n\t\t\t\t).rows;\n\t\t\t}\n\t\t} else if (\n\t\t\tpublishedOnly &&\n\t\t\tisSystemTable(tableName) &&\n\t\t\tPUBLISHED_TABLE_POLICIES[tableName] === \"omit\"\n\t\t) {\n\t\t\trows = [];\n\t\t} else if (tableName === \"options\") {\n\t\t\trows = (\n\t\t\t\tawait sql<Record<string, unknown>>`\n\t\t\t\t\tSELECT * FROM ${sql.ref(tableName)}\n\t\t\t\t`.execute(db)\n\t\t\t).rows.filter((row) => {\n\t\t\t\tconst name = typeof row.name === \"string\" ? row.name : \"\";\n\t\t\t\treturn optionKeys.has(name) || optionPrefixes.some((prefix) => name.startsWith(prefix));\n\t\t\t});\n\t\t} else {\n\t\t\trows = (\n\t\t\t\tawait sql<Record<string, unknown>>`\n\t\t\t\t\tSELECT * FROM ${sql.ref(tableName)}\n\t\t\t\t`.execute(db)\n\t\t\t).rows;\n\t\t}\n\n\t\tif (publishedOnly) {\n\t\t\tif (tableName.startsWith(\"ec_\")) {\n\t\t\t\trecordPublishedContent(publishedProjection, tableName, rows);\n\t\t\t} else if (\n\t\t\t\tisSystemTable(tableName) &&\n\t\t\t\tPUBLISHED_TABLE_POLICIES[tableName] === \"content-linked\"\n\t\t\t) {\n\t\t\t\trows = projectPublishedRows(tableName, rows, publishedProjection);\n\t\t\t}\n\t\t\tfor (const row of rows) collectMediaReferences(row, publishedProjection);\n\t\t}\n\n\t\tif (rows.length > 0) {\n\t\t\ttables[tableName] = normalizeRows(rows, types);\n\t\t}\n\t}\n\n\t// Absolutize local media URLs in content tables so snapshots are portable.\n\t// Local image fields are stored as JSON with provider:\"local\" and\n\t// meta.storageKey but no src — the URL is derived at render time.\n\t// For snapshots consumed by external preview services, inject src now.\n\tif (options?.origin) {\n\t\tconst origin = options.origin;\n\t\tfor (const [tableName, rows] of Object.entries(tables)) {\n\t\t\tif (!tableName.startsWith(\"ec_\")) continue;\n\t\t\tfor (const row of rows) {\n\t\t\t\tfor (const [col, value] of Object.entries(row)) {\n\t\t\t\t\tif (typeof value !== \"string\" || !value.startsWith(\"{\")) continue;\n\t\t\t\t\trow[col] = injectMediaSrc(value, origin);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\treturn {\n\t\ttables,\n\t\tschema,\n\t\tgeneratedAt: new Date().toISOString(),\n\t};\n}\n"],"mappings":"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"}
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import { i as transferErrorDetailSchema, r as isTransferError, t as TransferError } from "./errors-B4f4It-2.mjs";
|
|
2
2
|
import { o as TRANSFER_LIMITS } from "./canonical-BudtH-Fx.mjs";
|
|
3
3
|
import { a as isSha256Digest, i as createSha256, r as createHashingStream } from "./digest-DJ1tHCgy.mjs";
|
|
4
|
-
import { r as bumpRunningExportWriteEpochs } from "./fence-
|
|
4
|
+
import { r as bumpRunningExportWriteEpochs } from "./fence-Dagicj14.mjs";
|
|
5
5
|
import { n as siteImportReceiptSchema } from "./receipt-BUsQCOeM.mjs";
|
|
6
|
-
import { a as timestampIsOlderThan, b as transferCursorSchema, c as EXECUTING_IMPORT_STATES, f as PRE_EXECUTION_IMPORT_STATES, h as TRANSFER_RUNTIME_GENERATION, i as timestampIsLive, m as TERMINAL_IMPORT_STATES, o as timestampNow, r as timestampIsDue, s as timestampOffset, v as isTransferOperationKind, x as transferProgressSchema, y as isTransferOperationState } from "./approvals-
|
|
6
|
+
import { a as timestampIsOlderThan, b as transferCursorSchema, c as EXECUTING_IMPORT_STATES, f as PRE_EXECUTION_IMPORT_STATES, h as TRANSFER_RUNTIME_GENERATION, i as timestampIsLive, m as TERMINAL_IMPORT_STATES, o as timestampNow, r as timestampIsDue, s as timestampOffset, v as isTransferOperationKind, x as transferProgressSchema, y as isTransferOperationState } from "./approvals-DTtYSB27.mjs";
|
|
7
7
|
import { n as stagingAuxKey, r as stagingKey } from "./keys-CifIkT0N.mjs";
|
|
8
8
|
import { sql } from "kysely";
|
|
9
9
|
import { ulid } from "ulidx";
|
|
@@ -659,4 +659,4 @@ var TransferStage = class {
|
|
|
659
659
|
|
|
660
660
|
//#endregion
|
|
661
661
|
export { toPublicOperation as a, TransferOperationRepository as i, putVerified as n, readStreamBytes as r, TransferStage as t };
|
|
662
|
-
//# sourceMappingURL=stage-
|
|
662
|
+
//# sourceMappingURL=stage-CZQnXM_G.mjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"stage-D8DWgPcO.mjs","names":[],"sources":["../src/transfer/ops/operations.ts","../src/transfer/staging/stage.ts"],"sourcesContent":["/**\n * Transfer operation rows: creation, lease claims, and lease-fenced state\n * writes.\n *\n * Every step of a running operation happens under a lease: `claim` is one\n * `UPDATE … WHERE lease is free … RETURNING` statement that installs a fresh\n * ULID lease token, and every later write is fenced on that token and on the\n * lease still being live. A caller that loses its lease (expiry, another\n * caller took over) gets `TRANSFER_LEASE_LOST` and must stop without writing.\n */\n\nimport { sql, type Kysely, type Selectable, type UpdateObject } from \"kysely\";\nimport { ulid } from \"ulidx\";\n\nimport type { Database, TransferOperationTable } from \"../../database/types.js\";\nimport {\n\tTransferError,\n\ttransferErrorDetailSchema,\n\ttype TransferErrorCode,\n\ttype TransferErrorDetail,\n} from \"../errors.js\";\nimport { bumpRunningExportWriteEpochs } from \"../fence.js\";\nimport { isSha256Digest, type Sha256Digest } from \"../format/digest.js\";\nimport { TRANSFER_LIMITS } from \"../format/limits.js\";\nimport { siteImportReceiptSchema, type SiteImportReceipt } from \"../format/receipt.js\";\nimport {\n\tEXECUTING_IMPORT_STATES,\n\tisTransferOperationKind,\n\tisTransferOperationState,\n\tPRE_EXECUTION_IMPORT_STATES,\n\tTERMINAL_IMPORT_STATES,\n\tTRANSFER_RUNTIME_GENERATION,\n\ttransferCursorSchema,\n\ttransferProgressSchema,\n\ttype TransferCursor,\n\ttype TransferOperationKind,\n\ttype TransferOperationState,\n\ttype TransferProgress,\n} from \"./states.js\";\nimport {\n\ttimestampIsDue,\n\ttimestampIsLive,\n\ttimestampIsOlderThan,\n\ttimestampNow,\n\ttimestampOffset,\n} from \"./time.js\";\n\ntype OperationRow = Selectable<TransferOperationTable>;\ntype OperationUpdate = UpdateObject<Database, \"_emdash_transfer_operations\">;\n\nexport interface TransferOperation {\n\tid: string;\n\tkind: TransferOperationKind;\n\tstate: TransferOperationState;\n\tstage: string | null;\n\tcursor: TransferCursor | null;\n\tprogress: TransferProgress | null;\n\toptions: unknown;\n\tidempotencyKey: string | null;\n\tpackageDigest: Sha256Digest | null;\n\tplanDigest: Sha256Digest | null;\n\toriginSiteId: string | null;\n\t/**\n\t * 128-bit hex secret in the operation's staging prefix. Internal only:\n\t * serialize operations for clients with {@link toPublicOperation}.\n\t */\n\tstagingSecret: string;\n\treceipt: SiteImportReceipt | null;\n\terrorCode: string | null;\n\terrorDetail: TransferErrorDetail | null;\n\twriteEpoch: number;\n\tattemptCount: number;\n\tleaseToken: string | null;\n\tleaseExpiresAt: string | null;\n\truntimeGeneration: number;\n\tcancelRequestedAt: string | null;\n\tmutationStartedAt: string | null;\n\tcreatedBy: string;\n\tcreatedAt: string;\n\tupdatedAt: string;\n\tcompletedAt: string | null;\n\texpiresAt: string | null;\n\tstagingCollectedAt: string | null;\n}\n\n/**\n * An operation as it may be shown to API clients: without the staging secret\n * and lease token.\n */\nexport type PublicTransferOperation = Omit<TransferOperation, \"stagingSecret\" | \"leaseToken\">;\n\nexport function toPublicOperation(operation: TransferOperation): PublicTransferOperation {\n\tconst { stagingSecret: _secret, leaseToken: _lease, ...rest } = operation;\n\treturn rest;\n}\n\nexport interface CreateTransferOperationInput {\n\tkind: TransferOperationKind;\n\tcreatedBy: string;\n\tidempotencyKey?: string;\n\t/** For imports, the digest of the manifest the operation was created with. */\n\tpackageDigest?: Sha256Digest;\n\toriginSiteId?: string;\n\toptions?: unknown;\n\t/** Seconds until the operation expires if it does not finish. */\n\tttlSeconds?: number;\n}\n\nexport type ClaimResult =\n\t| { outcome: \"claimed\"; operation: TransferOperation; leaseToken: string }\n\t| { outcome: \"lease_active\"; operation: TransferOperation }\n\t| { outcome: \"invalid_state\"; operation: TransferOperation };\n\nexport interface OperationPatch {\n\tstate?: TransferOperationState;\n\tstage?: string | null;\n\tcursor?: TransferCursor | null;\n\tprogress?: TransferProgress | null;\n\tpackageDigest?: Sha256Digest;\n\tplanDigest?: Sha256Digest | null;\n\toriginSiteId?: string;\n\t/** Record that the importer is about to write to the target (idempotent). */\n\tmarkMutationStarted?: true;\n\t/** Reset `expires_at` to now + this many seconds. */\n\tttlSeconds?: number;\n\t/**\n\t * Record the retryable failure of the last step on a non-terminal\n\t * operation in `error_code`/`error_detail`, or clear it with null.\n\t */\n\tretryError?: { code: TransferErrorCode; detail?: TransferErrorDetail } | null;\n}\n\nconst MAX_IDEMPOTENCY_KEY_LENGTH = 255;\n\nfunction parseJson(value: string | null): unknown {\n\tif (value === null) return null;\n\treturn JSON.parse(value);\n}\n\nfunction toOperation(row: OperationRow): TransferOperation {\n\tconst { kind, state } = row;\n\tif (!isTransferOperationKind(kind) || !isTransferOperationState(state)) {\n\t\tthrow new TransferError(\"TRANSFER_INVALID_STATE\", \"Unknown transfer operation kind or state\");\n\t}\n\tconst cursor = parseJson(row.cursor);\n\tconst progress = parseJson(row.progress);\n\tconst receipt = parseJson(row.receipt);\n\tconst errorDetail = parseJson(row.error_detail);\n\treturn {\n\t\tid: row.id,\n\t\tkind,\n\t\tstate,\n\t\tstage: row.stage,\n\t\tcursor: cursor === null ? null : transferCursorSchema.parse(cursor),\n\t\tprogress: progress === null ? null : transferProgressSchema.parse(progress),\n\t\toptions: parseJson(row.options),\n\t\tidempotencyKey: row.idempotency_key,\n\t\tpackageDigest: isSha256Digest(row.package_digest) ? row.package_digest : null,\n\t\tplanDigest: isSha256Digest(row.plan_digest) ? row.plan_digest : null,\n\t\toriginSiteId: row.origin_site_id,\n\t\tstagingSecret: row.staging_secret,\n\t\treceipt: receipt === null ? null : siteImportReceiptSchema.parse(receipt),\n\t\terrorCode: row.error_code,\n\t\terrorDetail: errorDetail === null ? null : transferErrorDetailSchema.parse(errorDetail),\n\t\twriteEpoch: Number(row.write_epoch),\n\t\tattemptCount: Number(row.attempt_count),\n\t\tleaseToken: row.lease_token,\n\t\tleaseExpiresAt: row.lease_expires_at,\n\t\truntimeGeneration: Number(row.runtime_generation),\n\t\tcancelRequestedAt: row.cancel_requested_at,\n\t\tmutationStartedAt: row.mutation_started_at,\n\t\tcreatedBy: row.created_by,\n\t\tcreatedAt: row.created_at,\n\t\tupdatedAt: row.updated_at,\n\t\tcompletedAt: row.completed_at,\n\t\texpiresAt: row.expires_at,\n\t\tstagingCollectedAt: row.staging_collected_at,\n\t};\n}\n\nexport function createStagingSecret(): string {\n\tconst bytes = new Uint8Array(16);\n\tcrypto.getRandomValues(bytes);\n\treturn Array.from(bytes, (byte) => byte.toString(16).padStart(2, \"0\")).join(\"\");\n}\n\nexport class TransferOperationRepository {\n\tconstructor(private readonly db: Kysely<Database>) {}\n\n\tasync get(id: string): Promise<TransferOperation | null> {\n\t\tconst row = await this.db\n\t\t\t.selectFrom(\"_emdash_transfer_operations\")\n\t\t\t.selectAll()\n\t\t\t.where(\"id\", \"=\", id)\n\t\t\t.executeTakeFirst();\n\t\treturn row ? toOperation(row) : null;\n\t}\n\n\tasync require(id: string): Promise<TransferOperation> {\n\t\tconst operation = await this.get(id);\n\t\tif (!operation) {\n\t\t\tthrow new TransferError(\"TRANSFER_OPERATION_NOT_FOUND\", \"Transfer operation not found\");\n\t\t}\n\t\treturn operation;\n\t}\n\n\t/**\n\t * Create an operation, or return the existing one for the same\n\t * `(createdBy, kind, idempotencyKey)`. Throws\n\t * `TRANSFER_IDEMPOTENCY_CONFLICT` when that key was used with a different\n\t * package digest, and `TRANSFER_IMPORT_IN_PROGRESS` when another import\n\t * already occupies the target.\n\t */\n\tasync create(\n\t\tinput: CreateTransferOperationInput,\n\t): Promise<{ operation: TransferOperation; created: boolean }> {\n\t\tif (\n\t\t\tinput.idempotencyKey !== undefined &&\n\t\t\t(input.idempotencyKey.length === 0 ||\n\t\t\t\tinput.idempotencyKey.length > MAX_IDEMPOTENCY_KEY_LENGTH)\n\t\t) {\n\t\t\tthrow new TransferError(\"TRANSFER_IDEMPOTENCY_CONFLICT\", \"Invalid idempotency key\");\n\t\t}\n\n\t\tif (input.idempotencyKey !== undefined) {\n\t\t\tconst existing = await this.findByIdempotencyKey(input);\n\t\t\tif (existing) return { operation: existing, created: false };\n\t\t}\n\n\t\tconst id = ulid();\n\t\tconst inserted = await this.db\n\t\t\t.insertInto(\"_emdash_transfer_operations\")\n\t\t\t.values({\n\t\t\t\tid,\n\t\t\t\tkind: input.kind,\n\t\t\t\tstate: input.kind === \"export\" ? \"pending\" : \"uploading\",\n\t\t\t\tidempotency_key: input.idempotencyKey ?? null,\n\t\t\t\tpackage_digest: input.packageDigest ?? null,\n\t\t\t\torigin_site_id: input.originSiteId ?? null,\n\t\t\t\toptions: input.options === undefined ? null : JSON.stringify(input.options),\n\t\t\t\tstaging_secret: createStagingSecret(),\n\t\t\t\truntime_generation: TRANSFER_RUNTIME_GENERATION,\n\t\t\t\tcreated_by: input.createdBy,\n\t\t\t\texpires_at: timestampOffset(this.db, input.ttlSeconds ?? defaultTtl(input.kind)),\n\t\t\t\tstage: null,\n\t\t\t\tcursor: null,\n\t\t\t\tprogress: null,\n\t\t\t\tplan_digest: null,\n\t\t\t\treceipt: null,\n\t\t\t\terror_code: null,\n\t\t\t\terror_detail: null,\n\t\t\t\tlease_token: null,\n\t\t\t\tlease_expires_at: null,\n\t\t\t\tcancel_requested_at: null,\n\t\t\t\tmutation_started_at: null,\n\t\t\t\tcompleted_at: null,\n\t\t\t\tstaging_collected_at: null,\n\t\t\t})\n\t\t\t.onConflict((conflict) => conflict.doNothing())\n\t\t\t.returningAll()\n\t\t\t.executeTakeFirst();\n\t\tif (inserted) return { operation: toOperation(inserted), created: true };\n\n\t\tif (input.idempotencyKey !== undefined) {\n\t\t\tconst existing = await this.findByIdempotencyKey(input);\n\t\t\tif (existing) return { operation: existing, created: false };\n\t\t}\n\t\tthrow new TransferError(\n\t\t\t\"TRANSFER_IMPORT_IN_PROGRESS\",\n\t\t\t\"Another import is already in progress on this site\",\n\t\t);\n\t}\n\n\tprivate async findByIdempotencyKey(\n\t\tinput: CreateTransferOperationInput,\n\t): Promise<TransferOperation | null> {\n\t\tconst row = await this.db\n\t\t\t.selectFrom(\"_emdash_transfer_operations\")\n\t\t\t.selectAll()\n\t\t\t.where(\"created_by\", \"=\", input.createdBy)\n\t\t\t.where(\"kind\", \"=\", input.kind)\n\t\t\t.where(\"idempotency_key\", \"=\", input.idempotencyKey ?? \"\")\n\t\t\t.executeTakeFirst();\n\t\tif (!row) return null;\n\t\tif (\n\t\t\tinput.packageDigest !== undefined &&\n\t\t\trow.package_digest !== null &&\n\t\t\trow.package_digest !== input.packageDigest\n\t\t) {\n\t\t\tthrow new TransferError(\n\t\t\t\t\"TRANSFER_IDEMPOTENCY_CONFLICT\",\n\t\t\t\t\"Idempotency key was already used for a different package\",\n\t\t\t);\n\t\t}\n\t\treturn toOperation(row);\n\t}\n\n\t/** The import that currently occupies the target, if any. */\n\tasync findOccupyingImport(): Promise<TransferOperation | null> {\n\t\tconst row = await this.db\n\t\t\t.selectFrom(\"_emdash_transfer_operations\")\n\t\t\t.selectAll()\n\t\t\t.where(\"kind\", \"=\", \"import\")\n\t\t\t.where((eb) =>\n\t\t\t\teb.or([\n\t\t\t\t\teb(\"state\", \"in\", [...PRE_EXECUTION_IMPORT_STATES, ...EXECUTING_IMPORT_STATES]),\n\t\t\t\t\teb.and([\n\t\t\t\t\t\teb(\"state\", \"in\", [\"failed\", \"cancelled\"]),\n\t\t\t\t\t\teb(\"mutation_started_at\", \"is not\", null),\n\t\t\t\t\t]),\n\t\t\t\t]),\n\t\t\t)\n\t\t\t.executeTakeFirst();\n\t\treturn row ? toOperation(row) : null;\n\t}\n\n\t/**\n\t * Take the operation's lease if it is in one of `states` and no live lease\n\t * exists. Throws `TRANSFER_OPERATION_NOT_FOUND`, or\n\t * `TRANSFER_RUNTIME_MISMATCH` when the row was written by an incompatible\n\t * runtime generation.\n\t */\n\tasync claim(\n\t\tid: string,\n\t\tstates: readonly TransferOperationState[],\n\t\toptions: { leaseSeconds?: number } = {},\n\t): Promise<ClaimResult> {\n\t\tconst leaseToken = ulid();\n\t\tconst now = timestampNow(this.db);\n\t\tconst row = await this.db\n\t\t\t.updateTable(\"_emdash_transfer_operations\")\n\t\t\t.set({\n\t\t\t\tlease_token: leaseToken,\n\t\t\t\tlease_expires_at: timestampOffset(\n\t\t\t\t\tthis.db,\n\t\t\t\t\toptions.leaseSeconds ?? TRANSFER_LIMITS.leaseSeconds,\n\t\t\t\t),\n\t\t\t\tattempt_count: sql<number>`attempt_count + 1`,\n\t\t\t\tupdated_at: now,\n\t\t\t})\n\t\t\t.where(\"id\", \"=\", id)\n\t\t\t.where(\"state\", \"in\", [...states])\n\t\t\t.where(\"runtime_generation\", \"=\", TRANSFER_RUNTIME_GENERATION)\n\t\t\t.where((eb) =>\n\t\t\t\teb.or([\n\t\t\t\t\teb(\"lease_token\", \"is\", null),\n\t\t\t\t\teb(\"lease_expires_at\", \"is\", null),\n\t\t\t\t\ttimestampIsDue(this.db, \"lease_expires_at\"),\n\t\t\t\t]),\n\t\t\t)\n\t\t\t.returningAll()\n\t\t\t.executeTakeFirst();\n\t\tif (row) return { outcome: \"claimed\", operation: toOperation(row), leaseToken };\n\n\t\tconst current = await this.require(id);\n\t\tif (current.runtimeGeneration !== TRANSFER_RUNTIME_GENERATION) {\n\t\t\tthrow new TransferError(\n\t\t\t\t\"TRANSFER_RUNTIME_MISMATCH\",\n\t\t\t\t\"Transfer operation was created by an incompatible EmDash version\",\n\t\t\t);\n\t\t}\n\t\tif (!states.includes(current.state)) return { outcome: \"invalid_state\", operation: current };\n\t\treturn { outcome: \"lease_active\", operation: current };\n\t}\n\n\t/**\n\t * Write state under the lease and extend it. Throws `TRANSFER_LEASE_LOST`\n\t * when the lease is gone.\n\t */\n\tasync advance(id: string, leaseToken: string, patch: OperationPatch): Promise<TransferOperation> {\n\t\treturn this.fencedUpdate(id, leaseToken, {\n\t\t\t...this.patchValues(patch),\n\t\t\tlease_expires_at: timestampOffset(this.db, TRANSFER_LIMITS.leaseSeconds),\n\t\t});\n\t}\n\n\t/** Write state and give up the lease so the next step can claim it. */\n\tasync release(\n\t\tid: string,\n\t\tleaseToken: string,\n\t\tpatch: OperationPatch = {},\n\t): Promise<TransferOperation> {\n\t\treturn this.fencedUpdate(id, leaseToken, {\n\t\t\t...this.patchValues(patch),\n\t\t\tlease_token: null,\n\t\t\tlease_expires_at: null,\n\t\t});\n\t}\n\n\t/**\n\t * Write `patch`, move to `state`, and give up the lease; when a cancel was\n\t * requested while the lease was held, move to `cancelled` instead. One\n\t * statement decides, so a cancel racing the release is never lost.\n\t */\n\tasync releaseUnlessCancelled(\n\t\tid: string,\n\t\tleaseToken: string,\n\t\tstate: TransferOperationState,\n\t\tpatch: Omit<OperationPatch, \"state\"> = {},\n\t): Promise<TransferOperation> {\n\t\tconst now = timestampNow(this.db);\n\t\treturn this.fencedUpdate(id, leaseToken, {\n\t\t\t...this.patchValues(patch),\n\t\t\tstate: sql<string>`CASE WHEN cancel_requested_at IS NULL THEN ${state} ELSE 'cancelled' END`,\n\t\t\tcompleted_at: sql<\n\t\t\t\tstring | null\n\t\t\t>`CASE WHEN cancel_requested_at IS NULL THEN completed_at ELSE ${now} END`,\n\t\t\tlease_token: null,\n\t\t\tlease_expires_at: null,\n\t\t});\n\t}\n\n\tasync complete(\n\t\tid: string,\n\t\tleaseToken: string,\n\t\tresult: { receipt?: SiteImportReceipt; ttlSeconds?: number; progress?: TransferProgress } = {},\n\t): Promise<TransferOperation> {\n\t\treturn this.fencedUpdate(id, leaseToken, {\n\t\t\tstate: \"complete\",\n\t\t\treceipt: result.receipt === undefined ? undefined : JSON.stringify(result.receipt),\n\t\t\tprogress: result.progress === undefined ? undefined : JSON.stringify(result.progress),\n\t\t\tcompleted_at: timestampNow(this.db),\n\t\t\texpires_at:\n\t\t\t\tresult.ttlSeconds === undefined ? undefined : timestampOffset(this.db, result.ttlSeconds),\n\t\t\tlease_token: null,\n\t\t\tlease_expires_at: null,\n\t\t});\n\t}\n\n\tasync fail(\n\t\tid: string,\n\t\tleaseToken: string,\n\t\terror: { code: TransferErrorCode; detail?: TransferErrorDetail },\n\t): Promise<TransferOperation> {\n\t\treturn this.fencedUpdate(id, leaseToken, {\n\t\t\tstate: \"failed\",\n\t\t\terror_code: error.code,\n\t\t\terror_detail: error.detail === undefined ? null : JSON.stringify(error.detail),\n\t\t\tcompleted_at: timestampNow(this.db),\n\t\t\tlease_token: null,\n\t\t\tlease_expires_at: null,\n\t\t});\n\t}\n\n\t/** Finish a cancellation the lease holder observed via `cancelRequestedAt`. */\n\tasync finishCancelled(id: string, leaseToken: string): Promise<TransferOperation> {\n\t\treturn this.fencedUpdate(id, leaseToken, {\n\t\t\tstate: \"cancelled\",\n\t\t\tcompleted_at: timestampNow(this.db),\n\t\t\tlease_token: null,\n\t\t\tlease_expires_at: null,\n\t\t});\n\t}\n\n\t/**\n\t * Cancel an import. Without a live lease the operation becomes `cancelled`\n\t * immediately; otherwise `cancel_requested_at` is set and the lease holder\n\t * stops after its current batch. Returns the updated operation.\n\t */\n\tasync requestCancel(id: string): Promise<TransferOperation> {\n\t\tconst cancellable = [...PRE_EXECUTION_IMPORT_STATES, ...EXECUTING_IMPORT_STATES];\n\t\tconst now = timestampNow(this.db);\n\t\tconst immediate = await this.db\n\t\t\t.updateTable(\"_emdash_transfer_operations\")\n\t\t\t.set({\n\t\t\t\tstate: \"cancelled\",\n\t\t\t\tcancel_requested_at: now,\n\t\t\t\tcompleted_at: now,\n\t\t\t\tupdated_at: now,\n\t\t\t\tlease_token: null,\n\t\t\t\tlease_expires_at: null,\n\t\t\t})\n\t\t\t.where(\"id\", \"=\", id)\n\t\t\t.where(\"kind\", \"=\", \"import\")\n\t\t\t.where(\"state\", \"in\", cancellable)\n\t\t\t.where((eb) =>\n\t\t\t\teb.or([\n\t\t\t\t\teb(\"lease_token\", \"is\", null),\n\t\t\t\t\teb(\"lease_expires_at\", \"is\", null),\n\t\t\t\t\ttimestampIsDue(this.db, \"lease_expires_at\"),\n\t\t\t\t]),\n\t\t\t)\n\t\t\t.returningAll()\n\t\t\t.executeTakeFirst();\n\t\tif (immediate) return toOperation(immediate);\n\n\t\tconst flagged = await this.db\n\t\t\t.updateTable(\"_emdash_transfer_operations\")\n\t\t\t.set({ cancel_requested_at: now, updated_at: now })\n\t\t\t.where(\"id\", \"=\", id)\n\t\t\t.where(\"kind\", \"=\", \"import\")\n\t\t\t.where(\"state\", \"in\", cancellable)\n\t\t\t.returningAll()\n\t\t\t.executeTakeFirst();\n\t\tif (flagged) return toOperation(flagged);\n\n\t\tawait this.require(id);\n\t\tthrow new TransferError(\"TRANSFER_INVALID_STATE\", \"Transfer operation cannot be cancelled\");\n\t}\n\n\t/**\n\t * Mark a failed or cancelled import abandoned. Lifts the write fence; never\n\t * deletes imported data.\n\t */\n\tasync abandon(id: string): Promise<TransferOperation> {\n\t\tconst now = timestampNow(this.db);\n\t\tconst row = await this.db\n\t\t\t.updateTable(\"_emdash_transfer_operations\")\n\t\t\t.set({ state: \"abandoned\", updated_at: now })\n\t\t\t.where(\"id\", \"=\", id)\n\t\t\t.where(\"kind\", \"=\", \"import\")\n\t\t\t.where(\"state\", \"in\", [\"failed\", \"cancelled\"])\n\t\t\t.where((eb) =>\n\t\t\t\teb.or([\n\t\t\t\t\teb(\"lease_token\", \"is\", null),\n\t\t\t\t\teb(\"lease_expires_at\", \"is\", null),\n\t\t\t\t\ttimestampIsDue(this.db, \"lease_expires_at\"),\n\t\t\t\t]),\n\t\t\t)\n\t\t\t.returningAll()\n\t\t\t.executeTakeFirst();\n\t\tif (row) return toOperation(row);\n\t\tawait this.require(id);\n\t\tthrow new TransferError(\n\t\t\t\"TRANSFER_INVALID_STATE\",\n\t\t\t\"Only a failed or cancelled import can be abandoned\",\n\t\t);\n\t}\n\n\t/**\n\t * Move operations past their `expires_at` to `expired` (pre-execution\n\t * imports and every non-expired export) when no live lease holds them.\n\t * Returns the expired operations so their staging can be collected.\n\t */\n\tasync expireDue(\n\t\tlimit = 50,\n\t): Promise<Array<Pick<TransferOperation, \"id\" | \"kind\" | \"stagingSecret\">>> {\n\t\tconst candidates = await this.db\n\t\t\t.selectFrom(\"_emdash_transfer_operations\")\n\t\t\t.select(\"id\")\n\t\t\t.where(\"expires_at\", \"is not\", null)\n\t\t\t.where(timestampIsDue(this.db, \"expires_at\"))\n\t\t\t.where((eb) =>\n\t\t\t\teb.or([\n\t\t\t\t\teb.and([\n\t\t\t\t\t\teb(\"kind\", \"=\", \"import\"),\n\t\t\t\t\t\teb(\"state\", \"in\", [...PRE_EXECUTION_IMPORT_STATES]),\n\t\t\t\t\t\teb(\"mutation_started_at\", \"is\", null),\n\t\t\t\t\t]),\n\t\t\t\t\teb.and([\n\t\t\t\t\t\teb(\"kind\", \"=\", \"export\"),\n\t\t\t\t\t\teb(\"state\", \"in\", [\"pending\", \"running\", \"complete\", \"failed\"]),\n\t\t\t\t\t]),\n\t\t\t\t]),\n\t\t\t)\n\t\t\t.where((eb) =>\n\t\t\t\teb.or([\n\t\t\t\t\teb(\"lease_token\", \"is\", null),\n\t\t\t\t\teb(\"lease_expires_at\", \"is\", null),\n\t\t\t\t\ttimestampIsDue(this.db, \"lease_expires_at\"),\n\t\t\t\t]),\n\t\t\t)\n\t\t\t.orderBy(\"expires_at\")\n\t\t\t.limit(limit)\n\t\t\t.execute();\n\t\tif (candidates.length === 0) return [];\n\t\tconst now = timestampNow(this.db);\n\t\tconst rows = await this.db\n\t\t\t.updateTable(\"_emdash_transfer_operations\")\n\t\t\t.set({ state: \"expired\", updated_at: now, lease_token: null, lease_expires_at: null })\n\t\t\t.where(\n\t\t\t\t\"id\",\n\t\t\t\t\"in\",\n\t\t\t\tcandidates.map((candidate) => candidate.id),\n\t\t\t)\n\t\t\t.where(timestampIsDue(this.db, \"expires_at\"))\n\t\t\t.where((eb) =>\n\t\t\t\teb.or([\n\t\t\t\t\teb.and([\n\t\t\t\t\t\teb(\"kind\", \"=\", \"import\"),\n\t\t\t\t\t\teb(\"state\", \"in\", [...PRE_EXECUTION_IMPORT_STATES]),\n\t\t\t\t\t\teb(\"mutation_started_at\", \"is\", null),\n\t\t\t\t\t]),\n\t\t\t\t\teb.and([\n\t\t\t\t\t\teb(\"kind\", \"=\", \"export\"),\n\t\t\t\t\t\teb(\"state\", \"in\", [\"pending\", \"running\", \"complete\", \"failed\"]),\n\t\t\t\t\t]),\n\t\t\t\t]),\n\t\t\t)\n\t\t\t.returning([\"id\", \"kind\", \"staging_secret\"])\n\t\t\t.execute();\n\t\treturn rows.flatMap((row) =>\n\t\t\tisTransferOperationKind(row.kind)\n\t\t\t\t? [{ id: row.id, kind: row.kind, stagingSecret: row.staging_secret }]\n\t\t\t\t: [],\n\t\t);\n\t}\n\n\t/**\n\t * Operations whose staging area can be collected and has not been yet:\n\t * imports in a terminal state, and exports that failed or expired\n\t * (complete exports stay downloadable until they expire). Oldest first.\n\t * A collector deletes staged objects with `TransferStage.deleteSome` until\n\t * it returns 0, deletes child rows with {@link deleteChildRows} until it\n\t * returns 0, then calls {@link markCollected}; a crash anywhere in between\n\t * leaves the operation listed here, so collection resumes.\n\t *\n\t * `importRetentionSeconds` keeps a finished import's staging for that long\n\t * after its last state change; expired imports are listed at once.\n\t */\n\tasync listUncollected(\n\t\tlimit = 20,\n\t\toptions: { importRetentionSeconds?: number } = {},\n\t): Promise<Array<Pick<TransferOperation, \"id\" | \"kind\" | \"state\" | \"stagingSecret\">>> {\n\t\tconst retention = options.importRetentionSeconds ?? 0;\n\t\tconst retainedStates = TERMINAL_IMPORT_STATES.filter((state) => state !== \"expired\");\n\t\tconst rows = await this.db\n\t\t\t.selectFrom(\"_emdash_transfer_operations\")\n\t\t\t.select([\"id\", \"kind\", \"state\", \"staging_secret\"])\n\t\t\t.where(\"staging_collected_at\", \"is\", null)\n\t\t\t.where((eb) =>\n\t\t\t\teb.or([\n\t\t\t\t\teb.and([eb(\"kind\", \"=\", \"import\"), eb(\"state\", \"=\", \"expired\")]),\n\t\t\t\t\teb.and([\n\t\t\t\t\t\teb(\"kind\", \"=\", \"import\"),\n\t\t\t\t\t\teb(\"state\", \"in\", retainedStates),\n\t\t\t\t\t\ttimestampIsOlderThan(this.db, \"updated_at\", retention),\n\t\t\t\t\t]),\n\t\t\t\t\teb.and([eb(\"kind\", \"=\", \"export\"), eb(\"state\", \"in\", [\"failed\", \"expired\"])]),\n\t\t\t\t]),\n\t\t\t)\n\t\t\t.where((eb) =>\n\t\t\t\teb.or([\n\t\t\t\t\teb(\"lease_token\", \"is\", null),\n\t\t\t\t\teb(\"lease_expires_at\", \"is\", null),\n\t\t\t\t\ttimestampIsDue(this.db, \"lease_expires_at\"),\n\t\t\t\t]),\n\t\t\t)\n\t\t\t.orderBy(\"updated_at\")\n\t\t\t.orderBy(\"id\")\n\t\t\t.limit(Math.min(Math.max(limit, 1), 100))\n\t\t\t.execute();\n\t\treturn rows.flatMap((row) =>\n\t\t\tisTransferOperationKind(row.kind) && isTransferOperationState(row.state)\n\t\t\t\t? [{ id: row.id, kind: row.kind, state: row.state, stagingSecret: row.staging_secret }]\n\t\t\t\t: [],\n\t\t);\n\t}\n\n\t/** Record that an operation's staging area and child rows are gone. */\n\tasync markCollected(id: string): Promise<void> {\n\t\tawait this.db\n\t\t\t.updateTable(\"_emdash_transfer_operations\")\n\t\t\t.set({ staging_collected_at: timestampNow(this.db) })\n\t\t\t.where(\"id\", \"=\", id)\n\t\t\t.where(\"staging_collected_at\", \"is\", null)\n\t\t\t.execute();\n\t}\n\n\t/**\n\t * Delete up to `limit` child rows of each child table of an operation\n\t * (staged files, package index, media blobs), one bounded statement per\n\t * table. Returns the number deleted; call until it returns 0. Always drain\n\t * children this way before deleting an operation row: an `ON DELETE\n\t * CASCADE` over millions of child rows in one statement exceeds D1's\n\t * limits.\n\t */\n\tasync deleteChildRows(operationId: string, limit = 500): Promise<number> {\n\t\tconst bounded = Math.min(Math.max(Math.trunc(limit), 1), 5000);\n\t\tconst staged = await sql`\n\t\t\tDELETE FROM _emdash_transfer_staged_files\n\t\t\tWHERE operation_id = ${operationId}\n\t\t\t\tAND path IN (\n\t\t\t\t\tSELECT path FROM _emdash_transfer_staged_files\n\t\t\t\t\tWHERE operation_id = ${operationId}\n\t\t\t\t\tLIMIT ${bounded}\n\t\t\t\t)\n\t\t`.execute(this.db);\n\t\tconst indexed = await sql`\n\t\t\tDELETE FROM _emdash_transfer_package_index\n\t\t\tWHERE operation_id = ${operationId}\n\t\t\t\tAND (kind, id) IN (\n\t\t\t\t\tSELECT kind, id FROM _emdash_transfer_package_index\n\t\t\t\t\tWHERE operation_id = ${operationId}\n\t\t\t\t\tLIMIT ${bounded}\n\t\t\t\t)\n\t\t`.execute(this.db);\n\t\tconst blobs = await sql`\n\t\t\tDELETE FROM _emdash_transfer_media_blobs\n\t\t\tWHERE operation_id = ${operationId}\n\t\t\t\tAND media_id IN (\n\t\t\t\t\tSELECT media_id FROM _emdash_transfer_media_blobs\n\t\t\t\t\tWHERE operation_id = ${operationId}\n\t\t\t\t\tLIMIT ${bounded}\n\t\t\t\t)\n\t\t`.execute(this.db);\n\t\treturn [staged, indexed, blobs].reduce(\n\t\t\t(sum, result) => sum + Number(result.numAffectedRows ?? 0n),\n\t\t\t0,\n\t\t);\n\t}\n\n\t/**\n\t * Delete a collected operation row once it has no child rows left.\n\t * Returns false, deleting nothing, otherwise. Identity-map rows are kept.\n\t */\n\tasync deleteIfChildless(id: string): Promise<boolean> {\n\t\tconst result = await this.db\n\t\t\t.deleteFrom(\"_emdash_transfer_operations\")\n\t\t\t.where(\"id\", \"=\", id)\n\t\t\t.where(\"staging_collected_at\", \"is not\", null)\n\t\t\t.where((eb) =>\n\t\t\t\teb.and([\n\t\t\t\t\teb.not(\n\t\t\t\t\t\teb.exists(\n\t\t\t\t\t\t\teb\n\t\t\t\t\t\t\t\t.selectFrom(\"_emdash_transfer_staged_files\")\n\t\t\t\t\t\t\t\t.select(\"path\")\n\t\t\t\t\t\t\t\t.where(\"_emdash_transfer_staged_files.operation_id\", \"=\", id),\n\t\t\t\t\t\t),\n\t\t\t\t\t),\n\t\t\t\t\teb.not(\n\t\t\t\t\t\teb.exists(\n\t\t\t\t\t\t\teb\n\t\t\t\t\t\t\t\t.selectFrom(\"_emdash_transfer_package_index\")\n\t\t\t\t\t\t\t\t.select(\"kind\")\n\t\t\t\t\t\t\t\t.where(\"_emdash_transfer_package_index.operation_id\", \"=\", id),\n\t\t\t\t\t\t),\n\t\t\t\t\t),\n\t\t\t\t\teb.not(\n\t\t\t\t\t\teb.exists(\n\t\t\t\t\t\t\teb\n\t\t\t\t\t\t\t\t.selectFrom(\"_emdash_transfer_media_blobs\")\n\t\t\t\t\t\t\t\t.select(\"media_id\")\n\t\t\t\t\t\t\t\t.where(\"_emdash_transfer_media_blobs.operation_id\", \"=\", id),\n\t\t\t\t\t\t),\n\t\t\t\t\t),\n\t\t\t\t]),\n\t\t\t)\n\t\t\t.executeTakeFirst();\n\t\treturn Number(result.numDeletedRows ?? 0n) > 0;\n\t}\n\n\t/**\n\t * Bump `write_epoch` on every running export. Fenced write paths call this\n\t * so an export's consistency fence notices writes to tables that have no\n\t * `updated_at`. Returns the number of exports touched.\n\t */\n\tasync recordWriteForRunningExports(): Promise<number> {\n\t\treturn bumpRunningExportWriteEpochs(this.db);\n\t}\n\n\t/** Operations newest first, `{ items, nextCursor }` over `(created_at, id)`. */\n\tasync list(\n\t\toptions: {\n\t\t\tkind?: TransferOperationKind;\n\t\t\tcreatedBy?: string;\n\t\t\tlimit?: number;\n\t\t\tcursor?: { createdAt: string; id: string };\n\t\t} = {},\n\t): Promise<{ items: PublicTransferOperation[]; next?: { createdAt: string; id: string } }> {\n\t\tconst limit = Math.min(Math.max(options.limit ?? 50, 1), 100);\n\t\tlet query = this.db.selectFrom(\"_emdash_transfer_operations\").selectAll();\n\t\tif (options.kind) query = query.where(\"kind\", \"=\", options.kind);\n\t\tif (options.createdBy) query = query.where(\"created_by\", \"=\", options.createdBy);\n\t\tconst cursor = options.cursor;\n\t\tif (cursor) {\n\t\t\tquery = query.where((eb) =>\n\t\t\t\teb.or([\n\t\t\t\t\teb(\"created_at\", \"<\", cursor.createdAt),\n\t\t\t\t\teb.and([eb(\"created_at\", \"=\", cursor.createdAt), eb(\"id\", \"<\", cursor.id)]),\n\t\t\t\t]),\n\t\t\t);\n\t\t}\n\t\tconst rows = await query\n\t\t\t.orderBy(\"created_at\", \"desc\")\n\t\t\t.orderBy(\"id\", \"desc\")\n\t\t\t.limit(limit + 1)\n\t\t\t.execute();\n\t\tconst items = rows.slice(0, limit).map((row) => toPublicOperation(toOperation(row)));\n\t\tconst last = items.at(-1);\n\t\treturn rows.length > limit && last\n\t\t\t? { items, next: { createdAt: last.createdAt, id: last.id } }\n\t\t\t: { items };\n\t}\n\n\tprivate patchValues(patch: OperationPatch): OperationUpdate {\n\t\tconst values: OperationUpdate = {};\n\t\tif (patch.state !== undefined) values.state = patch.state;\n\t\tif (patch.stage !== undefined) values.stage = patch.stage;\n\t\tif (patch.cursor !== undefined) {\n\t\t\tvalues.cursor =\n\t\t\t\tpatch.cursor === null ? null : JSON.stringify(transferCursorSchema.parse(patch.cursor));\n\t\t}\n\t\tif (patch.progress !== undefined) {\n\t\t\tvalues.progress =\n\t\t\t\tpatch.progress === null\n\t\t\t\t\t? null\n\t\t\t\t\t: JSON.stringify(transferProgressSchema.parse(patch.progress));\n\t\t}\n\t\tif (patch.packageDigest !== undefined) values.package_digest = patch.packageDigest;\n\t\tif (patch.planDigest !== undefined) values.plan_digest = patch.planDigest;\n\t\tif (patch.originSiteId !== undefined) values.origin_site_id = patch.originSiteId;\n\t\tif (patch.markMutationStarted) {\n\t\t\tvalues.mutation_started_at = sql<string>`COALESCE(mutation_started_at, ${timestampNow(this.db)})`;\n\t\t}\n\t\tif (patch.ttlSeconds !== undefined)\n\t\t\tvalues.expires_at = timestampOffset(this.db, patch.ttlSeconds);\n\t\tif (patch.retryError !== undefined) {\n\t\t\tvalues.error_code = patch.retryError?.code ?? null;\n\t\t\tvalues.error_detail =\n\t\t\t\tpatch.retryError?.detail === undefined ? null : JSON.stringify(patch.retryError.detail);\n\t\t}\n\t\treturn values;\n\t}\n\n\tprivate async fencedUpdate(\n\t\tid: string,\n\t\tleaseToken: string,\n\t\tvalues: OperationUpdate,\n\t): Promise<TransferOperation> {\n\t\tconst row = await this.db\n\t\t\t.updateTable(\"_emdash_transfer_operations\")\n\t\t\t.set({ ...values, updated_at: timestampNow(this.db) })\n\t\t\t.where(\"id\", \"=\", id)\n\t\t\t.where(\"lease_token\", \"=\", leaseToken)\n\t\t\t.where(\"lease_expires_at\", \"is not\", null)\n\t\t\t.where(timestampIsLive(this.db, \"lease_expires_at\"))\n\t\t\t.returningAll()\n\t\t\t.executeTakeFirst();\n\t\tif (!row) {\n\t\t\tthrow new TransferError(\"TRANSFER_LEASE_LOST\", \"Transfer operation lease was lost\");\n\t\t}\n\t\treturn toOperation(row);\n\t}\n}\n\nfunction defaultTtl(kind: TransferOperationKind): number {\n\treturn kind === \"export\"\n\t\t? TRANSFER_LIMITS.exportTtlSeconds\n\t\t: TRANSFER_LIMITS.pendingImportTtlSeconds;\n}\n","/**\n * Byte-level access to one operation's staging area.\n */\n\nimport type { DownloadResult, Storage } from \"../../storage/types.js\";\nimport { TransferError, isTransferError } from \"../errors.js\";\nimport { createHashingStream, createSha256 } from \"../format/digest.js\";\nimport { stagingAuxKey, stagingKey, type StagingAuxFile } from \"./keys.js\";\n\ntype FixedLengthStreamConstructor = new (\n\texpectedLength: number | bigint,\n) => TransformStream<ArrayBufferView | ArrayBuffer, Uint8Array>;\n\ndeclare const FixedLengthStream: FixedLengthStreamConstructor | undefined;\n\nexport interface ExpectedFile {\n\tbytes: number;\n\t/** Lowercase hex SHA-256. */\n\tsha256: string;\n}\n\nexport interface PutVerifiedOptions {\n\tcontentType?: string;\n\t/**\n\t * Called before deleting the object after a failed upload; return true to\n\t * keep it (the path was already verified by another upload).\n\t */\n\tkeepExistingOnFailure?: () => Promise<boolean>;\n}\n\nconst PACKAGE_CONTENT_TYPE = \"application/octet-stream\";\n\nfunction oversizeError(): TransferError {\n\treturn new TransferError(\"TRANSFER_FILE_SIZE_MISMATCH\", \"File is larger than declared\");\n}\n\nfunction toStream(body: ReadableStream<Uint8Array> | Uint8Array): ReadableStream<Uint8Array> {\n\tif (body instanceof Uint8Array) {\n\t\treturn new ReadableStream<Uint8Array>({\n\t\t\tstart(controller) {\n\t\t\t\tif (body.byteLength > 0) controller.enqueue(body);\n\t\t\t\tcontroller.close();\n\t\t\t},\n\t\t});\n\t}\n\treturn body;\n}\n\n/**\n * Stream `body` into `key`, hashing and counting as it goes. The object is\n * kept only if exactly `expected.bytes` bytes with digest `expected.sha256`\n * were written; otherwise it is deleted and `TRANSFER_FILE_SIZE_MISMATCH` or\n * `TRANSFER_FILE_DIGEST_MISMATCH` is thrown. Where the runtime provides\n * `FixedLengthStream` (workerd), the upload is wrapped in one so R2 receives\n * a known length.\n *\n * Callers staging a package file must check its staged-files row first and\n * refuse the upload when it is already `verified` and its object still\n * matches, and must pass `keepExistingOnFailure` returning true once the row\n * is verified: a failed retry or concurrent upload of the same path must not\n * delete the object a successful upload stored. A failing upload that\n * already overwrote the object can still leave bad bytes behind a verified\n * row, so readers verify sizes and digests again when they read staged\n * files, and a later upload of that path replaces the bad object.\n */\nexport async function putVerified(\n\tstorage: Storage,\n\tkey: string,\n\tbody: ReadableStream<Uint8Array> | Uint8Array,\n\texpected: ExpectedFile,\n\toptions: PutVerifiedOptions = {},\n): Promise<void> {\n\tconst discard = async () => {\n\t\tif (options.keepExistingOnFailure && (await options.keepExistingOnFailure())) return;\n\t\tawait storage.delete(key).catch(() => undefined);\n\t};\n\tif (!Number.isSafeInteger(expected.bytes) || expected.bytes < 0) {\n\t\tthrow new TransferError(\"TRANSFER_FILE_SIZE_MISMATCH\", \"Invalid declared size\");\n\t}\n\tconst hasher = await createSha256();\n\tconst hashing = createHashingStream(hasher, {\n\t\tmaxBytes: expected.bytes,\n\t\tonLimitExceeded: oversizeError,\n\t});\n\tlet stream = toStream(body).pipeThrough(hashing.stream);\n\tif (typeof FixedLengthStream !== \"undefined\") {\n\t\tstream = stream.pipeThrough(new FixedLengthStream(expected.bytes));\n\t}\n\n\ttry {\n\t\tawait storage.upload({\n\t\t\tkey,\n\t\t\tbody: stream,\n\t\t\tcontentType: options.contentType ?? PACKAGE_CONTENT_TYPE,\n\t\t});\n\t} catch (error) {\n\t\tawait discard();\n\t\tif (isTransferError(error)) throw error;\n\t\tconst cause = findTransferError(error);\n\t\tif (cause) throw cause;\n\t\tif (hashing.bytes() !== expected.bytes) {\n\t\t\tthrow new TransferError(\"TRANSFER_FILE_SIZE_MISMATCH\", \"File size does not match\", {\n\t\t\t\tcause: error,\n\t\t\t});\n\t\t}\n\t\tthrow new TransferError(\"TRANSFER_STORAGE_ERROR\", \"Failed to store file\", { cause: error });\n\t}\n\n\tconst digest = await hasher.digest();\n\tif (hashing.bytes() !== expected.bytes) {\n\t\tawait discard();\n\t\tthrow new TransferError(\"TRANSFER_FILE_SIZE_MISMATCH\", \"File size does not match\", {\n\t\t\tdetail: { expected: expected.bytes, actual: hashing.bytes() },\n\t\t});\n\t}\n\tif (digest !== expected.sha256) {\n\t\tawait discard();\n\t\tthrow new TransferError(\"TRANSFER_FILE_DIGEST_MISMATCH\", \"File digest does not match\");\n\t}\n}\n\nfunction findTransferError(error: unknown): TransferError | null {\n\tlet current: unknown = error;\n\tfor (let depth = 0; depth < 5 && current instanceof Error; depth++) {\n\t\tif (current instanceof TransferError) return current;\n\t\tcurrent = current.cause;\n\t}\n\treturn null;\n}\n\n/** Read a whole stream, failing once it exceeds `maxBytes`. */\nexport async function readStreamBytes(\n\tstream: ReadableStream<Uint8Array>,\n\tmaxBytes: number,\n): Promise<Uint8Array> {\n\tconst reader = stream.getReader();\n\tconst parts: Uint8Array[] = [];\n\tlet total = 0;\n\ttry {\n\t\tfor (;;) {\n\t\t\tconst { done, value } = await reader.read();\n\t\t\tif (done) break;\n\t\t\ttotal += value.byteLength;\n\t\t\tif (total > maxBytes) {\n\t\t\t\tthrow new TransferError(\"TRANSFER_LIMIT_EXCEEDED\", \"File exceeds its size limit\", {\n\t\t\t\t\tdetail: { limit: maxBytes },\n\t\t\t\t});\n\t\t\t}\n\t\t\tparts.push(value);\n\t\t}\n\t} catch (error) {\n\t\tawait reader.cancel().catch(() => undefined);\n\t\tthrow error;\n\t} finally {\n\t\treader.releaseLock();\n\t}\n\tconst bytes = new Uint8Array(total);\n\tlet offset = 0;\n\tfor (const part of parts) {\n\t\tbytes.set(part, offset);\n\t\toffset += part.byteLength;\n\t}\n\treturn bytes;\n}\n\n/** One operation's staging area in `storage` under `prefix` (see keys.ts). */\nexport class TransferStage {\n\tconstructor(\n\t\treadonly storage: Storage,\n\t\treadonly prefix: string,\n\t) {}\n\n\tkeyFor(path: string): string {\n\t\treturn stagingKey(this.prefix, path);\n\t}\n\n\tasync putVerified(\n\t\tpath: string,\n\t\tbody: ReadableStream<Uint8Array> | Uint8Array,\n\t\tbytes: number,\n\t\tsha256: string,\n\t\toptions: PutVerifiedOptions = {},\n\t): Promise<void> {\n\t\tawait putVerified(this.storage, this.keyFor(path), body, { bytes, sha256 }, options);\n\t}\n\n\tasync exists(path: string): Promise<boolean> {\n\t\treturn this.storage.exists(this.keyFor(path));\n\t}\n\n\tasync open(path: string): Promise<DownloadResult> {\n\t\ttry {\n\t\t\treturn await this.storage.download(this.keyFor(path));\n\t\t} catch (error) {\n\t\t\tthrow new TransferError(\"TRANSFER_FILE_MISSING\", \"Staged file is missing\", {\n\t\t\t\tdetail: { path },\n\t\t\t\tcause: error,\n\t\t\t});\n\t\t}\n\t}\n\n\tasync readBytes(path: string, maxBytes: number): Promise<Uint8Array> {\n\t\tconst file = await this.open(path);\n\t\treturn readStreamBytes(file.body, maxBytes);\n\t}\n\n\tasync putAux(file: StagingAuxFile, content: string): Promise<void> {\n\t\tawait this.storage.upload({\n\t\t\tkey: stagingAuxKey(this.prefix, file),\n\t\t\tbody: new TextEncoder().encode(content),\n\t\t\tcontentType: \"application/json\",\n\t\t});\n\t}\n\n\tasync readAux(file: StagingAuxFile, maxBytes: number): Promise<string | null> {\n\t\tconst key = stagingAuxKey(this.prefix, file);\n\t\tif (!(await this.storage.exists(key))) return null;\n\t\tconst download = await this.storage.download(key);\n\t\treturn new TextDecoder().decode(await readStreamBytes(download.body, maxBytes));\n\t}\n\n\t/**\n\t * Delete up to `limit` staged objects. Returns the number deleted; call\n\t * again until it returns 0.\n\t */\n\tasync deleteSome(limit = 100): Promise<number> {\n\t\tconst listing = await this.storage.list({ prefix: this.prefix, limit });\n\t\tfor (const file of listing.files) await this.storage.delete(file.key);\n\t\treturn listing.files.length;\n\t}\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;AA2FA,SAAgB,kBAAkB,WAAuD;CACxF,MAAM,EAAE,eAAe,SAAS,YAAY,QAAQ,GAAG,SAAS;AAChE,QAAO;;AAuCR,MAAM,6BAA6B;AAEnC,SAAS,UAAU,OAA+B;AACjD,KAAI,UAAU,KAAM,QAAO;AAC3B,QAAO,KAAK,MAAM,MAAM;;AAGzB,SAAS,YAAY,KAAsC;CAC1D,MAAM,EAAE,MAAM,UAAU;AACxB,KAAI,CAAC,wBAAwB,KAAK,IAAI,CAAC,yBAAyB,MAAM,CACrE,OAAM,IAAI,cAAc,0BAA0B,2CAA2C;CAE9F,MAAM,SAAS,UAAU,IAAI,OAAO;CACpC,MAAM,WAAW,UAAU,IAAI,SAAS;CACxC,MAAM,UAAU,UAAU,IAAI,QAAQ;CACtC,MAAM,cAAc,UAAU,IAAI,aAAa;AAC/C,QAAO;EACN,IAAI,IAAI;EACR;EACA;EACA,OAAO,IAAI;EACX,QAAQ,WAAW,OAAO,OAAO,qBAAqB,MAAM,OAAO;EACnE,UAAU,aAAa,OAAO,OAAO,uBAAuB,MAAM,SAAS;EAC3E,SAAS,UAAU,IAAI,QAAQ;EAC/B,gBAAgB,IAAI;EACpB,eAAe,eAAe,IAAI,eAAe,GAAG,IAAI,iBAAiB;EACzE,YAAY,eAAe,IAAI,YAAY,GAAG,IAAI,cAAc;EAChE,cAAc,IAAI;EAClB,eAAe,IAAI;EACnB,SAAS,YAAY,OAAO,OAAO,wBAAwB,MAAM,QAAQ;EACzE,WAAW,IAAI;EACf,aAAa,gBAAgB,OAAO,OAAO,0BAA0B,MAAM,YAAY;EACvF,YAAY,OAAO,IAAI,YAAY;EACnC,cAAc,OAAO,IAAI,cAAc;EACvC,YAAY,IAAI;EAChB,gBAAgB,IAAI;EACpB,mBAAmB,OAAO,IAAI,mBAAmB;EACjD,mBAAmB,IAAI;EACvB,mBAAmB,IAAI;EACvB,WAAW,IAAI;EACf,WAAW,IAAI;EACf,WAAW,IAAI;EACf,aAAa,IAAI;EACjB,WAAW,IAAI;EACf,oBAAoB,IAAI;EACxB;;AAGF,SAAgB,sBAA8B;CAC7C,MAAM,QAAQ,IAAI,WAAW,GAAG;AAChC,QAAO,gBAAgB,MAAM;AAC7B,QAAO,MAAM,KAAK,QAAQ,SAAS,KAAK,SAAS,GAAG,CAAC,SAAS,GAAG,IAAI,CAAC,CAAC,KAAK,GAAG;;AAGhF,IAAa,8BAAb,MAAyC;CACxC,YAAY,AAAiB,IAAsB;EAAtB;;CAE7B,MAAM,IAAI,IAA+C;EACxD,MAAM,MAAM,MAAM,KAAK,GACrB,WAAW,8BAA8B,CACzC,WAAW,CACX,MAAM,MAAM,KAAK,GAAG,CACpB,kBAAkB;AACpB,SAAO,MAAM,YAAY,IAAI,GAAG;;CAGjC,MAAM,QAAQ,IAAwC;EACrD,MAAM,YAAY,MAAM,KAAK,IAAI,GAAG;AACpC,MAAI,CAAC,UACJ,OAAM,IAAI,cAAc,gCAAgC,+BAA+B;AAExF,SAAO;;;;;;;;;CAUR,MAAM,OACL,OAC8D;AAC9D,MACC,MAAM,mBAAmB,WACxB,MAAM,eAAe,WAAW,KAChC,MAAM,eAAe,SAAS,4BAE/B,OAAM,IAAI,cAAc,iCAAiC,0BAA0B;AAGpF,MAAI,MAAM,mBAAmB,QAAW;GACvC,MAAM,WAAW,MAAM,KAAK,qBAAqB,MAAM;AACvD,OAAI,SAAU,QAAO;IAAE,WAAW;IAAU,SAAS;IAAO;;EAG7D,MAAM,KAAK,MAAM;EACjB,MAAM,WAAW,MAAM,KAAK,GAC1B,WAAW,8BAA8B,CACzC,OAAO;GACP;GACA,MAAM,MAAM;GACZ,OAAO,MAAM,SAAS,WAAW,YAAY;GAC7C,iBAAiB,MAAM,kBAAkB;GACzC,gBAAgB,MAAM,iBAAiB;GACvC,gBAAgB,MAAM,gBAAgB;GACtC,SAAS,MAAM,YAAY,SAAY,OAAO,KAAK,UAAU,MAAM,QAAQ;GAC3E,gBAAgB,qBAAqB;GACrC,oBAAoB;GACpB,YAAY,MAAM;GAClB,YAAY,gBAAgB,KAAK,IAAI,MAAM,cAAc,WAAW,MAAM,KAAK,CAAC;GAChF,OAAO;GACP,QAAQ;GACR,UAAU;GACV,aAAa;GACb,SAAS;GACT,YAAY;GACZ,cAAc;GACd,aAAa;GACb,kBAAkB;GAClB,qBAAqB;GACrB,qBAAqB;GACrB,cAAc;GACd,sBAAsB;GACtB,CAAC,CACD,YAAY,aAAa,SAAS,WAAW,CAAC,CAC9C,cAAc,CACd,kBAAkB;AACpB,MAAI,SAAU,QAAO;GAAE,WAAW,YAAY,SAAS;GAAE,SAAS;GAAM;AAExE,MAAI,MAAM,mBAAmB,QAAW;GACvC,MAAM,WAAW,MAAM,KAAK,qBAAqB,MAAM;AACvD,OAAI,SAAU,QAAO;IAAE,WAAW;IAAU,SAAS;IAAO;;AAE7D,QAAM,IAAI,cACT,+BACA,qDACA;;CAGF,MAAc,qBACb,OACoC;EACpC,MAAM,MAAM,MAAM,KAAK,GACrB,WAAW,8BAA8B,CACzC,WAAW,CACX,MAAM,cAAc,KAAK,MAAM,UAAU,CACzC,MAAM,QAAQ,KAAK,MAAM,KAAK,CAC9B,MAAM,mBAAmB,KAAK,MAAM,kBAAkB,GAAG,CACzD,kBAAkB;AACpB,MAAI,CAAC,IAAK,QAAO;AACjB,MACC,MAAM,kBAAkB,UACxB,IAAI,mBAAmB,QACvB,IAAI,mBAAmB,MAAM,cAE7B,OAAM,IAAI,cACT,iCACA,2DACA;AAEF,SAAO,YAAY,IAAI;;;CAIxB,MAAM,sBAAyD;EAC9D,MAAM,MAAM,MAAM,KAAK,GACrB,WAAW,8BAA8B,CACzC,WAAW,CACX,MAAM,QAAQ,KAAK,SAAS,CAC5B,OAAO,OACP,GAAG,GAAG,CACL,GAAG,SAAS,MAAM,CAAC,GAAG,6BAA6B,GAAG,wBAAwB,CAAC,EAC/E,GAAG,IAAI,CACN,GAAG,SAAS,MAAM,CAAC,UAAU,YAAY,CAAC,EAC1C,GAAG,uBAAuB,UAAU,KAAK,CACzC,CAAC,CACF,CAAC,CACF,CACA,kBAAkB;AACpB,SAAO,MAAM,YAAY,IAAI,GAAG;;;;;;;;CASjC,MAAM,MACL,IACA,QACA,UAAqC,EAAE,EAChB;EACvB,MAAM,aAAa,MAAM;EACzB,MAAM,MAAM,aAAa,KAAK,GAAG;EACjC,MAAM,MAAM,MAAM,KAAK,GACrB,YAAY,8BAA8B,CAC1C,IAAI;GACJ,aAAa;GACb,kBAAkB,gBACjB,KAAK,IACL,QAAQ,gBAAgB,gBAAgB,aACxC;GACD,eAAe,GAAW;GAC1B,YAAY;GACZ,CAAC,CACD,MAAM,MAAM,KAAK,GAAG,CACpB,MAAM,SAAS,MAAM,CAAC,GAAG,OAAO,CAAC,CACjC,MAAM,sBAAsB,KAAK,4BAA4B,CAC7D,OAAO,OACP,GAAG,GAAG;GACL,GAAG,eAAe,MAAM,KAAK;GAC7B,GAAG,oBAAoB,MAAM,KAAK;GAClC,eAAe,KAAK,IAAI,mBAAmB;GAC3C,CAAC,CACF,CACA,cAAc,CACd,kBAAkB;AACpB,MAAI,IAAK,QAAO;GAAE,SAAS;GAAW,WAAW,YAAY,IAAI;GAAE;GAAY;EAE/E,MAAM,UAAU,MAAM,KAAK,QAAQ,GAAG;AACtC,MAAI,QAAQ,sBAAsB,4BACjC,OAAM,IAAI,cACT,6BACA,mEACA;AAEF,MAAI,CAAC,OAAO,SAAS,QAAQ,MAAM,CAAE,QAAO;GAAE,SAAS;GAAiB,WAAW;GAAS;AAC5F,SAAO;GAAE,SAAS;GAAgB,WAAW;GAAS;;;;;;CAOvD,MAAM,QAAQ,IAAY,YAAoB,OAAmD;AAChG,SAAO,KAAK,aAAa,IAAI,YAAY;GACxC,GAAG,KAAK,YAAY,MAAM;GAC1B,kBAAkB,gBAAgB,KAAK,IAAI,gBAAgB,aAAa;GACxE,CAAC;;;CAIH,MAAM,QACL,IACA,YACA,QAAwB,EAAE,EACG;AAC7B,SAAO,KAAK,aAAa,IAAI,YAAY;GACxC,GAAG,KAAK,YAAY,MAAM;GAC1B,aAAa;GACb,kBAAkB;GAClB,CAAC;;;;;;;CAQH,MAAM,uBACL,IACA,YACA,OACA,QAAuC,EAAE,EACZ;EAC7B,MAAM,MAAM,aAAa,KAAK,GAAG;AACjC,SAAO,KAAK,aAAa,IAAI,YAAY;GACxC,GAAG,KAAK,YAAY,MAAM;GAC1B,OAAO,GAAW,8CAA8C,MAAM;GACtE,cAAc,GAEb,gEAAgE,IAAI;GACrE,aAAa;GACb,kBAAkB;GAClB,CAAC;;CAGH,MAAM,SACL,IACA,YACA,SAA4F,EAAE,EACjE;AAC7B,SAAO,KAAK,aAAa,IAAI,YAAY;GACxC,OAAO;GACP,SAAS,OAAO,YAAY,SAAY,SAAY,KAAK,UAAU,OAAO,QAAQ;GAClF,UAAU,OAAO,aAAa,SAAY,SAAY,KAAK,UAAU,OAAO,SAAS;GACrF,cAAc,aAAa,KAAK,GAAG;GACnC,YACC,OAAO,eAAe,SAAY,SAAY,gBAAgB,KAAK,IAAI,OAAO,WAAW;GAC1F,aAAa;GACb,kBAAkB;GAClB,CAAC;;CAGH,MAAM,KACL,IACA,YACA,OAC6B;AAC7B,SAAO,KAAK,aAAa,IAAI,YAAY;GACxC,OAAO;GACP,YAAY,MAAM;GAClB,cAAc,MAAM,WAAW,SAAY,OAAO,KAAK,UAAU,MAAM,OAAO;GAC9E,cAAc,aAAa,KAAK,GAAG;GACnC,aAAa;GACb,kBAAkB;GAClB,CAAC;;;CAIH,MAAM,gBAAgB,IAAY,YAAgD;AACjF,SAAO,KAAK,aAAa,IAAI,YAAY;GACxC,OAAO;GACP,cAAc,aAAa,KAAK,GAAG;GACnC,aAAa;GACb,kBAAkB;GAClB,CAAC;;;;;;;CAQH,MAAM,cAAc,IAAwC;EAC3D,MAAM,cAAc,CAAC,GAAG,6BAA6B,GAAG,wBAAwB;EAChF,MAAM,MAAM,aAAa,KAAK,GAAG;EACjC,MAAM,YAAY,MAAM,KAAK,GAC3B,YAAY,8BAA8B,CAC1C,IAAI;GACJ,OAAO;GACP,qBAAqB;GACrB,cAAc;GACd,YAAY;GACZ,aAAa;GACb,kBAAkB;GAClB,CAAC,CACD,MAAM,MAAM,KAAK,GAAG,CACpB,MAAM,QAAQ,KAAK,SAAS,CAC5B,MAAM,SAAS,MAAM,YAAY,CACjC,OAAO,OACP,GAAG,GAAG;GACL,GAAG,eAAe,MAAM,KAAK;GAC7B,GAAG,oBAAoB,MAAM,KAAK;GAClC,eAAe,KAAK,IAAI,mBAAmB;GAC3C,CAAC,CACF,CACA,cAAc,CACd,kBAAkB;AACpB,MAAI,UAAW,QAAO,YAAY,UAAU;EAE5C,MAAM,UAAU,MAAM,KAAK,GACzB,YAAY,8BAA8B,CAC1C,IAAI;GAAE,qBAAqB;GAAK,YAAY;GAAK,CAAC,CAClD,MAAM,MAAM,KAAK,GAAG,CACpB,MAAM,QAAQ,KAAK,SAAS,CAC5B,MAAM,SAAS,MAAM,YAAY,CACjC,cAAc,CACd,kBAAkB;AACpB,MAAI,QAAS,QAAO,YAAY,QAAQ;AAExC,QAAM,KAAK,QAAQ,GAAG;AACtB,QAAM,IAAI,cAAc,0BAA0B,yCAAyC;;;;;;CAO5F,MAAM,QAAQ,IAAwC;EACrD,MAAM,MAAM,aAAa,KAAK,GAAG;EACjC,MAAM,MAAM,MAAM,KAAK,GACrB,YAAY,8BAA8B,CAC1C,IAAI;GAAE,OAAO;GAAa,YAAY;GAAK,CAAC,CAC5C,MAAM,MAAM,KAAK,GAAG,CACpB,MAAM,QAAQ,KAAK,SAAS,CAC5B,MAAM,SAAS,MAAM,CAAC,UAAU,YAAY,CAAC,CAC7C,OAAO,OACP,GAAG,GAAG;GACL,GAAG,eAAe,MAAM,KAAK;GAC7B,GAAG,oBAAoB,MAAM,KAAK;GAClC,eAAe,KAAK,IAAI,mBAAmB;GAC3C,CAAC,CACF,CACA,cAAc,CACd,kBAAkB;AACpB,MAAI,IAAK,QAAO,YAAY,IAAI;AAChC,QAAM,KAAK,QAAQ,GAAG;AACtB,QAAM,IAAI,cACT,0BACA,qDACA;;;;;;;CAQF,MAAM,UACL,QAAQ,IACmE;EAC3E,MAAM,aAAa,MAAM,KAAK,GAC5B,WAAW,8BAA8B,CACzC,OAAO,KAAK,CACZ,MAAM,cAAc,UAAU,KAAK,CACnC,MAAM,eAAe,KAAK,IAAI,aAAa,CAAC,CAC5C,OAAO,OACP,GAAG,GAAG,CACL,GAAG,IAAI;GACN,GAAG,QAAQ,KAAK,SAAS;GACzB,GAAG,SAAS,MAAM,CAAC,GAAG,4BAA4B,CAAC;GACnD,GAAG,uBAAuB,MAAM,KAAK;GACrC,CAAC,EACF,GAAG,IAAI,CACN,GAAG,QAAQ,KAAK,SAAS,EACzB,GAAG,SAAS,MAAM;GAAC;GAAW;GAAW;GAAY;GAAS,CAAC,CAC/D,CAAC,CACF,CAAC,CACF,CACA,OAAO,OACP,GAAG,GAAG;GACL,GAAG,eAAe,MAAM,KAAK;GAC7B,GAAG,oBAAoB,MAAM,KAAK;GAClC,eAAe,KAAK,IAAI,mBAAmB;GAC3C,CAAC,CACF,CACA,QAAQ,aAAa,CACrB,MAAM,MAAM,CACZ,SAAS;AACX,MAAI,WAAW,WAAW,EAAG,QAAO,EAAE;EACtC,MAAM,MAAM,aAAa,KAAK,GAAG;AAyBjC,UAxBa,MAAM,KAAK,GACtB,YAAY,8BAA8B,CAC1C,IAAI;GAAE,OAAO;GAAW,YAAY;GAAK,aAAa;GAAM,kBAAkB;GAAM,CAAC,CACrF,MACA,MACA,MACA,WAAW,KAAK,cAAc,UAAU,GAAG,CAC3C,CACA,MAAM,eAAe,KAAK,IAAI,aAAa,CAAC,CAC5C,OAAO,OACP,GAAG,GAAG,CACL,GAAG,IAAI;GACN,GAAG,QAAQ,KAAK,SAAS;GACzB,GAAG,SAAS,MAAM,CAAC,GAAG,4BAA4B,CAAC;GACnD,GAAG,uBAAuB,MAAM,KAAK;GACrC,CAAC,EACF,GAAG,IAAI,CACN,GAAG,QAAQ,KAAK,SAAS,EACzB,GAAG,SAAS,MAAM;GAAC;GAAW;GAAW;GAAY;GAAS,CAAC,CAC/D,CAAC,CACF,CAAC,CACF,CACA,UAAU;GAAC;GAAM;GAAQ;GAAiB,CAAC,CAC3C,SAAS,EACC,SAAS,QACpB,wBAAwB,IAAI,KAAK,GAC9B,CAAC;GAAE,IAAI,IAAI;GAAI,MAAM,IAAI;GAAM,eAAe,IAAI;GAAgB,CAAC,GACnE,EAAE,CACL;;;;;;;;;;;;;;CAeF,MAAM,gBACL,QAAQ,IACR,UAA+C,EAAE,EACoC;EACrF,MAAM,YAAY,QAAQ,0BAA0B;EACpD,MAAM,iBAAiB,uBAAuB,QAAQ,UAAU,UAAU,UAAU;AA2BpF,UA1Ba,MAAM,KAAK,GACtB,WAAW,8BAA8B,CACzC,OAAO;GAAC;GAAM;GAAQ;GAAS;GAAiB,CAAC,CACjD,MAAM,wBAAwB,MAAM,KAAK,CACzC,OAAO,OACP,GAAG,GAAG;GACL,GAAG,IAAI,CAAC,GAAG,QAAQ,KAAK,SAAS,EAAE,GAAG,SAAS,KAAK,UAAU,CAAC,CAAC;GAChE,GAAG,IAAI;IACN,GAAG,QAAQ,KAAK,SAAS;IACzB,GAAG,SAAS,MAAM,eAAe;IACjC,qBAAqB,KAAK,IAAI,cAAc,UAAU;IACtD,CAAC;GACF,GAAG,IAAI,CAAC,GAAG,QAAQ,KAAK,SAAS,EAAE,GAAG,SAAS,MAAM,CAAC,UAAU,UAAU,CAAC,CAAC,CAAC;GAC7E,CAAC,CACF,CACA,OAAO,OACP,GAAG,GAAG;GACL,GAAG,eAAe,MAAM,KAAK;GAC7B,GAAG,oBAAoB,MAAM,KAAK;GAClC,eAAe,KAAK,IAAI,mBAAmB;GAC3C,CAAC,CACF,CACA,QAAQ,aAAa,CACrB,QAAQ,KAAK,CACb,MAAM,KAAK,IAAI,KAAK,IAAI,OAAO,EAAE,EAAE,IAAI,CAAC,CACxC,SAAS,EACC,SAAS,QACpB,wBAAwB,IAAI,KAAK,IAAI,yBAAyB,IAAI,MAAM,GACrE,CAAC;GAAE,IAAI,IAAI;GAAI,MAAM,IAAI;GAAM,OAAO,IAAI;GAAO,eAAe,IAAI;GAAgB,CAAC,GACrF,EAAE,CACL;;;CAIF,MAAM,cAAc,IAA2B;AAC9C,QAAM,KAAK,GACT,YAAY,8BAA8B,CAC1C,IAAI,EAAE,sBAAsB,aAAa,KAAK,GAAG,EAAE,CAAC,CACpD,MAAM,MAAM,KAAK,GAAG,CACpB,MAAM,wBAAwB,MAAM,KAAK,CACzC,SAAS;;;;;;;;;;CAWZ,MAAM,gBAAgB,aAAqB,QAAQ,KAAsB;EACxE,MAAM,UAAU,KAAK,IAAI,KAAK,IAAI,KAAK,MAAM,MAAM,EAAE,EAAE,EAAE,IAAK;AA4B9D,SAAO;GA3BQ,MAAM,GAAG;;0BAEA,YAAY;;;4BAGV,YAAY;aAC3B,QAAQ;;IAEjB,QAAQ,KAAK,GAAG;GACF,MAAM,GAAG;;0BAED,YAAY;;;4BAGV,YAAY;aAC3B,QAAQ;;IAEjB,QAAQ,KAAK,GAAG;GACJ,MAAM,GAAG;;0BAEC,YAAY;;;4BAGV,YAAY;aAC3B,QAAQ;;IAEjB,QAAQ,KAAK,GAAG;GACa,CAAC,QAC9B,KAAK,WAAW,MAAM,OAAO,OAAO,mBAAmB,GAAG,EAC3D,EACA;;;;;;CAOF,MAAM,kBAAkB,IAA8B;EACrD,MAAM,SAAS,MAAM,KAAK,GACxB,WAAW,8BAA8B,CACzC,MAAM,MAAM,KAAK,GAAG,CACpB,MAAM,wBAAwB,UAAU,KAAK,CAC7C,OAAO,OACP,GAAG,IAAI;GACN,GAAG,IACF,GAAG,OACF,GACE,WAAW,gCAAgC,CAC3C,OAAO,OAAO,CACd,MAAM,8CAA8C,KAAK,GAAG,CAC9D,CACD;GACD,GAAG,IACF,GAAG,OACF,GACE,WAAW,iCAAiC,CAC5C,OAAO,OAAO,CACd,MAAM,+CAA+C,KAAK,GAAG,CAC/D,CACD;GACD,GAAG,IACF,GAAG,OACF,GACE,WAAW,+BAA+B,CAC1C,OAAO,WAAW,CAClB,MAAM,6CAA6C,KAAK,GAAG,CAC7D,CACD;GACD,CAAC,CACF,CACA,kBAAkB;AACpB,SAAO,OAAO,OAAO,kBAAkB,GAAG,GAAG;;;;;;;CAQ9C,MAAM,+BAAgD;AACrD,SAAO,6BAA6B,KAAK,GAAG;;;CAI7C,MAAM,KACL,UAKI,EAAE,EACoF;EAC1F,MAAM,QAAQ,KAAK,IAAI,KAAK,IAAI,QAAQ,SAAS,IAAI,EAAE,EAAE,IAAI;EAC7D,IAAI,QAAQ,KAAK,GAAG,WAAW,8BAA8B,CAAC,WAAW;AACzE,MAAI,QAAQ,KAAM,SAAQ,MAAM,MAAM,QAAQ,KAAK,QAAQ,KAAK;AAChE,MAAI,QAAQ,UAAW,SAAQ,MAAM,MAAM,cAAc,KAAK,QAAQ,UAAU;EAChF,MAAM,SAAS,QAAQ;AACvB,MAAI,OACH,SAAQ,MAAM,OAAO,OACpB,GAAG,GAAG,CACL,GAAG,cAAc,KAAK,OAAO,UAAU,EACvC,GAAG,IAAI,CAAC,GAAG,cAAc,KAAK,OAAO,UAAU,EAAE,GAAG,MAAM,KAAK,OAAO,GAAG,CAAC,CAAC,CAC3E,CAAC,CACF;EAEF,MAAM,OAAO,MAAM,MACjB,QAAQ,cAAc,OAAO,CAC7B,QAAQ,MAAM,OAAO,CACrB,MAAM,QAAQ,EAAE,CAChB,SAAS;EACX,MAAM,QAAQ,KAAK,MAAM,GAAG,MAAM,CAAC,KAAK,QAAQ,kBAAkB,YAAY,IAAI,CAAC,CAAC;EACpF,MAAM,OAAO,MAAM,GAAG,GAAG;AACzB,SAAO,KAAK,SAAS,SAAS,OAC3B;GAAE;GAAO,MAAM;IAAE,WAAW,KAAK;IAAW,IAAI,KAAK;IAAI;GAAE,GAC3D,EAAE,OAAO;;CAGb,AAAQ,YAAY,OAAwC;EAC3D,MAAM,SAA0B,EAAE;AAClC,MAAI,MAAM,UAAU,OAAW,QAAO,QAAQ,MAAM;AACpD,MAAI,MAAM,UAAU,OAAW,QAAO,QAAQ,MAAM;AACpD,MAAI,MAAM,WAAW,OACpB,QAAO,SACN,MAAM,WAAW,OAAO,OAAO,KAAK,UAAU,qBAAqB,MAAM,MAAM,OAAO,CAAC;AAEzF,MAAI,MAAM,aAAa,OACtB,QAAO,WACN,MAAM,aAAa,OAChB,OACA,KAAK,UAAU,uBAAuB,MAAM,MAAM,SAAS,CAAC;AAEjE,MAAI,MAAM,kBAAkB,OAAW,QAAO,iBAAiB,MAAM;AACrE,MAAI,MAAM,eAAe,OAAW,QAAO,cAAc,MAAM;AAC/D,MAAI,MAAM,iBAAiB,OAAW,QAAO,iBAAiB,MAAM;AACpE,MAAI,MAAM,oBACT,QAAO,sBAAsB,GAAW,iCAAiC,aAAa,KAAK,GAAG,CAAC;AAEhG,MAAI,MAAM,eAAe,OACxB,QAAO,aAAa,gBAAgB,KAAK,IAAI,MAAM,WAAW;AAC/D,MAAI,MAAM,eAAe,QAAW;AACnC,UAAO,aAAa,MAAM,YAAY,QAAQ;AAC9C,UAAO,eACN,MAAM,YAAY,WAAW,SAAY,OAAO,KAAK,UAAU,MAAM,WAAW,OAAO;;AAEzF,SAAO;;CAGR,MAAc,aACb,IACA,YACA,QAC6B;EAC7B,MAAM,MAAM,MAAM,KAAK,GACrB,YAAY,8BAA8B,CAC1C,IAAI;GAAE,GAAG;GAAQ,YAAY,aAAa,KAAK,GAAG;GAAE,CAAC,CACrD,MAAM,MAAM,KAAK,GAAG,CACpB,MAAM,eAAe,KAAK,WAAW,CACrC,MAAM,oBAAoB,UAAU,KAAK,CACzC,MAAM,gBAAgB,KAAK,IAAI,mBAAmB,CAAC,CACnD,cAAc,CACd,kBAAkB;AACpB,MAAI,CAAC,IACJ,OAAM,IAAI,cAAc,uBAAuB,oCAAoC;AAEpF,SAAO,YAAY,IAAI;;;AAIzB,SAAS,WAAW,MAAqC;AACxD,QAAO,SAAS,WACb,gBAAgB,mBAChB,gBAAgB;;;;;AC1yBpB,MAAM,uBAAuB;AAE7B,SAAS,gBAA+B;AACvC,QAAO,IAAI,cAAc,+BAA+B,+BAA+B;;AAGxF,SAAS,SAAS,MAA2E;AAC5F,KAAI,gBAAgB,WACnB,QAAO,IAAI,eAA2B,EACrC,MAAM,YAAY;AACjB,MAAI,KAAK,aAAa,EAAG,YAAW,QAAQ,KAAK;AACjD,aAAW,OAAO;IAEnB,CAAC;AAEH,QAAO;;;;;;;;;;;;;;;;;;;AAoBR,eAAsB,YACrB,SACA,KACA,MACA,UACA,UAA8B,EAAE,EAChB;CAChB,MAAM,UAAU,YAAY;AAC3B,MAAI,QAAQ,yBAA0B,MAAM,QAAQ,uBAAuB,CAAG;AAC9E,QAAM,QAAQ,OAAO,IAAI,CAAC,YAAY,OAAU;;AAEjD,KAAI,CAAC,OAAO,cAAc,SAAS,MAAM,IAAI,SAAS,QAAQ,EAC7D,OAAM,IAAI,cAAc,+BAA+B,wBAAwB;CAEhF,MAAM,SAAS,MAAM,cAAc;CACnC,MAAM,UAAU,oBAAoB,QAAQ;EAC3C,UAAU,SAAS;EACnB,iBAAiB;EACjB,CAAC;CACF,IAAI,SAAS,SAAS,KAAK,CAAC,YAAY,QAAQ,OAAO;AACvD,KAAI,OAAO,sBAAsB,YAChC,UAAS,OAAO,YAAY,IAAI,kBAAkB,SAAS,MAAM,CAAC;AAGnE,KAAI;AACH,QAAM,QAAQ,OAAO;GACpB;GACA,MAAM;GACN,aAAa,QAAQ,eAAe;GACpC,CAAC;UACM,OAAO;AACf,QAAM,SAAS;AACf,MAAI,gBAAgB,MAAM,CAAE,OAAM;EAClC,MAAM,QAAQ,kBAAkB,MAAM;AACtC,MAAI,MAAO,OAAM;AACjB,MAAI,QAAQ,OAAO,KAAK,SAAS,MAChC,OAAM,IAAI,cAAc,+BAA+B,4BAA4B,EAClF,OAAO,OACP,CAAC;AAEH,QAAM,IAAI,cAAc,0BAA0B,wBAAwB,EAAE,OAAO,OAAO,CAAC;;CAG5F,MAAM,SAAS,MAAM,OAAO,QAAQ;AACpC,KAAI,QAAQ,OAAO,KAAK,SAAS,OAAO;AACvC,QAAM,SAAS;AACf,QAAM,IAAI,cAAc,+BAA+B,4BAA4B,EAClF,QAAQ;GAAE,UAAU,SAAS;GAAO,QAAQ,QAAQ,OAAO;GAAE,EAC7D,CAAC;;AAEH,KAAI,WAAW,SAAS,QAAQ;AAC/B,QAAM,SAAS;AACf,QAAM,IAAI,cAAc,iCAAiC,6BAA6B;;;AAIxF,SAAS,kBAAkB,OAAsC;CAChE,IAAI,UAAmB;AACvB,MAAK,IAAI,QAAQ,GAAG,QAAQ,KAAK,mBAAmB,OAAO,SAAS;AACnE,MAAI,mBAAmB,cAAe,QAAO;AAC7C,YAAU,QAAQ;;AAEnB,QAAO;;;AAIR,eAAsB,gBACrB,QACA,UACsB;CACtB,MAAM,SAAS,OAAO,WAAW;CACjC,MAAM,QAAsB,EAAE;CAC9B,IAAI,QAAQ;AACZ,KAAI;AACH,WAAS;GACR,MAAM,EAAE,MAAM,UAAU,MAAM,OAAO,MAAM;AAC3C,OAAI,KAAM;AACV,YAAS,MAAM;AACf,OAAI,QAAQ,SACX,OAAM,IAAI,cAAc,2BAA2B,+BAA+B,EACjF,QAAQ,EAAE,OAAO,UAAU,EAC3B,CAAC;AAEH,SAAM,KAAK,MAAM;;UAEV,OAAO;AACf,QAAM,OAAO,QAAQ,CAAC,YAAY,OAAU;AAC5C,QAAM;WACG;AACT,SAAO,aAAa;;CAErB,MAAM,QAAQ,IAAI,WAAW,MAAM;CACnC,IAAI,SAAS;AACb,MAAK,MAAM,QAAQ,OAAO;AACzB,QAAM,IAAI,MAAM,OAAO;AACvB,YAAU,KAAK;;AAEhB,QAAO;;;AAIR,IAAa,gBAAb,MAA2B;CAC1B,YACC,AAAS,SACT,AAAS,QACR;EAFQ;EACA;;CAGV,OAAO,MAAsB;AAC5B,SAAO,WAAW,KAAK,QAAQ,KAAK;;CAGrC,MAAM,YACL,MACA,MACA,OACA,QACA,UAA8B,EAAE,EAChB;AAChB,QAAM,YAAY,KAAK,SAAS,KAAK,OAAO,KAAK,EAAE,MAAM;GAAE;GAAO;GAAQ,EAAE,QAAQ;;CAGrF,MAAM,OAAO,MAAgC;AAC5C,SAAO,KAAK,QAAQ,OAAO,KAAK,OAAO,KAAK,CAAC;;CAG9C,MAAM,KAAK,MAAuC;AACjD,MAAI;AACH,UAAO,MAAM,KAAK,QAAQ,SAAS,KAAK,OAAO,KAAK,CAAC;WAC7C,OAAO;AACf,SAAM,IAAI,cAAc,yBAAyB,0BAA0B;IAC1E,QAAQ,EAAE,MAAM;IAChB,OAAO;IACP,CAAC;;;CAIJ,MAAM,UAAU,MAAc,UAAuC;AAEpE,SAAO,iBADM,MAAM,KAAK,KAAK,KAAK,EACN,MAAM,SAAS;;CAG5C,MAAM,OAAO,MAAsB,SAAgC;AAClE,QAAM,KAAK,QAAQ,OAAO;GACzB,KAAK,cAAc,KAAK,QAAQ,KAAK;GACrC,MAAM,IAAI,aAAa,CAAC,OAAO,QAAQ;GACvC,aAAa;GACb,CAAC;;CAGH,MAAM,QAAQ,MAAsB,UAA0C;EAC7E,MAAM,MAAM,cAAc,KAAK,QAAQ,KAAK;AAC5C,MAAI,CAAE,MAAM,KAAK,QAAQ,OAAO,IAAI,CAAG,QAAO;EAC9C,MAAM,WAAW,MAAM,KAAK,QAAQ,SAAS,IAAI;AACjD,SAAO,IAAI,aAAa,CAAC,OAAO,MAAM,gBAAgB,SAAS,MAAM,SAAS,CAAC;;;;;;CAOhF,MAAM,WAAW,QAAQ,KAAsB;EAC9C,MAAM,UAAU,MAAM,KAAK,QAAQ,KAAK;GAAE,QAAQ,KAAK;GAAQ;GAAO,CAAC;AACvE,OAAK,MAAM,QAAQ,QAAQ,MAAO,OAAM,KAAK,QAAQ,OAAO,KAAK,IAAI;AACrE,SAAO,QAAQ,MAAM"}
|
|
1
|
+
{"version":3,"file":"stage-CZQnXM_G.mjs","names":[],"sources":["../src/transfer/ops/operations.ts","../src/transfer/staging/stage.ts"],"sourcesContent":["/**\n * Transfer operation rows: creation, lease claims, and lease-fenced state\n * writes.\n *\n * Every step of a running operation happens under a lease: `claim` is one\n * `UPDATE … WHERE lease is free … RETURNING` statement that installs a fresh\n * ULID lease token, and every later write is fenced on that token and on the\n * lease still being live. A caller that loses its lease (expiry, another\n * caller took over) gets `TRANSFER_LEASE_LOST` and must stop without writing.\n */\n\nimport { sql, type Kysely, type Selectable, type UpdateObject } from \"kysely\";\nimport { ulid } from \"ulidx\";\n\nimport type { Database, TransferOperationTable } from \"../../database/types.js\";\nimport {\n\tTransferError,\n\ttransferErrorDetailSchema,\n\ttype TransferErrorCode,\n\ttype TransferErrorDetail,\n} from \"../errors.js\";\nimport { bumpRunningExportWriteEpochs } from \"../fence.js\";\nimport { isSha256Digest, type Sha256Digest } from \"../format/digest.js\";\nimport { TRANSFER_LIMITS } from \"../format/limits.js\";\nimport { siteImportReceiptSchema, type SiteImportReceipt } from \"../format/receipt.js\";\nimport {\n\tEXECUTING_IMPORT_STATES,\n\tisTransferOperationKind,\n\tisTransferOperationState,\n\tPRE_EXECUTION_IMPORT_STATES,\n\tTERMINAL_IMPORT_STATES,\n\tTRANSFER_RUNTIME_GENERATION,\n\ttransferCursorSchema,\n\ttransferProgressSchema,\n\ttype TransferCursor,\n\ttype TransferOperationKind,\n\ttype TransferOperationState,\n\ttype TransferProgress,\n} from \"./states.js\";\nimport {\n\ttimestampIsDue,\n\ttimestampIsLive,\n\ttimestampIsOlderThan,\n\ttimestampNow,\n\ttimestampOffset,\n} from \"./time.js\";\n\ntype OperationRow = Selectable<TransferOperationTable>;\ntype OperationUpdate = UpdateObject<Database, \"_emdash_transfer_operations\">;\n\nexport interface TransferOperation {\n\tid: string;\n\tkind: TransferOperationKind;\n\tstate: TransferOperationState;\n\tstage: string | null;\n\tcursor: TransferCursor | null;\n\tprogress: TransferProgress | null;\n\toptions: unknown;\n\tidempotencyKey: string | null;\n\tpackageDigest: Sha256Digest | null;\n\tplanDigest: Sha256Digest | null;\n\toriginSiteId: string | null;\n\t/**\n\t * 128-bit hex secret in the operation's staging prefix. Internal only:\n\t * serialize operations for clients with {@link toPublicOperation}.\n\t */\n\tstagingSecret: string;\n\treceipt: SiteImportReceipt | null;\n\terrorCode: string | null;\n\terrorDetail: TransferErrorDetail | null;\n\twriteEpoch: number;\n\tattemptCount: number;\n\tleaseToken: string | null;\n\tleaseExpiresAt: string | null;\n\truntimeGeneration: number;\n\tcancelRequestedAt: string | null;\n\tmutationStartedAt: string | null;\n\tcreatedBy: string;\n\tcreatedAt: string;\n\tupdatedAt: string;\n\tcompletedAt: string | null;\n\texpiresAt: string | null;\n\tstagingCollectedAt: string | null;\n}\n\n/**\n * An operation as it may be shown to API clients: without the staging secret\n * and lease token.\n */\nexport type PublicTransferOperation = Omit<TransferOperation, \"stagingSecret\" | \"leaseToken\">;\n\nexport function toPublicOperation(operation: TransferOperation): PublicTransferOperation {\n\tconst { stagingSecret: _secret, leaseToken: _lease, ...rest } = operation;\n\treturn rest;\n}\n\nexport interface CreateTransferOperationInput {\n\tkind: TransferOperationKind;\n\tcreatedBy: string;\n\tidempotencyKey?: string;\n\t/** For imports, the digest of the manifest the operation was created with. */\n\tpackageDigest?: Sha256Digest;\n\toriginSiteId?: string;\n\toptions?: unknown;\n\t/** Seconds until the operation expires if it does not finish. */\n\tttlSeconds?: number;\n}\n\nexport type ClaimResult =\n\t| { outcome: \"claimed\"; operation: TransferOperation; leaseToken: string }\n\t| { outcome: \"lease_active\"; operation: TransferOperation }\n\t| { outcome: \"invalid_state\"; operation: TransferOperation };\n\nexport interface OperationPatch {\n\tstate?: TransferOperationState;\n\tstage?: string | null;\n\tcursor?: TransferCursor | null;\n\tprogress?: TransferProgress | null;\n\tpackageDigest?: Sha256Digest;\n\tplanDigest?: Sha256Digest | null;\n\toriginSiteId?: string;\n\t/** Record that the importer is about to write to the target (idempotent). */\n\tmarkMutationStarted?: true;\n\t/** Reset `expires_at` to now + this many seconds. */\n\tttlSeconds?: number;\n\t/**\n\t * Record the retryable failure of the last step on a non-terminal\n\t * operation in `error_code`/`error_detail`, or clear it with null.\n\t */\n\tretryError?: { code: TransferErrorCode; detail?: TransferErrorDetail } | null;\n}\n\nconst MAX_IDEMPOTENCY_KEY_LENGTH = 255;\n\nfunction parseJson(value: string | null): unknown {\n\tif (value === null) return null;\n\treturn JSON.parse(value);\n}\n\nfunction toOperation(row: OperationRow): TransferOperation {\n\tconst { kind, state } = row;\n\tif (!isTransferOperationKind(kind) || !isTransferOperationState(state)) {\n\t\tthrow new TransferError(\"TRANSFER_INVALID_STATE\", \"Unknown transfer operation kind or state\");\n\t}\n\tconst cursor = parseJson(row.cursor);\n\tconst progress = parseJson(row.progress);\n\tconst receipt = parseJson(row.receipt);\n\tconst errorDetail = parseJson(row.error_detail);\n\treturn {\n\t\tid: row.id,\n\t\tkind,\n\t\tstate,\n\t\tstage: row.stage,\n\t\tcursor: cursor === null ? null : transferCursorSchema.parse(cursor),\n\t\tprogress: progress === null ? null : transferProgressSchema.parse(progress),\n\t\toptions: parseJson(row.options),\n\t\tidempotencyKey: row.idempotency_key,\n\t\tpackageDigest: isSha256Digest(row.package_digest) ? row.package_digest : null,\n\t\tplanDigest: isSha256Digest(row.plan_digest) ? row.plan_digest : null,\n\t\toriginSiteId: row.origin_site_id,\n\t\tstagingSecret: row.staging_secret,\n\t\treceipt: receipt === null ? null : siteImportReceiptSchema.parse(receipt),\n\t\terrorCode: row.error_code,\n\t\terrorDetail: errorDetail === null ? null : transferErrorDetailSchema.parse(errorDetail),\n\t\twriteEpoch: Number(row.write_epoch),\n\t\tattemptCount: Number(row.attempt_count),\n\t\tleaseToken: row.lease_token,\n\t\tleaseExpiresAt: row.lease_expires_at,\n\t\truntimeGeneration: Number(row.runtime_generation),\n\t\tcancelRequestedAt: row.cancel_requested_at,\n\t\tmutationStartedAt: row.mutation_started_at,\n\t\tcreatedBy: row.created_by,\n\t\tcreatedAt: row.created_at,\n\t\tupdatedAt: row.updated_at,\n\t\tcompletedAt: row.completed_at,\n\t\texpiresAt: row.expires_at,\n\t\tstagingCollectedAt: row.staging_collected_at,\n\t};\n}\n\nexport function createStagingSecret(): string {\n\tconst bytes = new Uint8Array(16);\n\tcrypto.getRandomValues(bytes);\n\treturn Array.from(bytes, (byte) => byte.toString(16).padStart(2, \"0\")).join(\"\");\n}\n\nexport class TransferOperationRepository {\n\tconstructor(private readonly db: Kysely<Database>) {}\n\n\tasync get(id: string): Promise<TransferOperation | null> {\n\t\tconst row = await this.db\n\t\t\t.selectFrom(\"_emdash_transfer_operations\")\n\t\t\t.selectAll()\n\t\t\t.where(\"id\", \"=\", id)\n\t\t\t.executeTakeFirst();\n\t\treturn row ? toOperation(row) : null;\n\t}\n\n\tasync require(id: string): Promise<TransferOperation> {\n\t\tconst operation = await this.get(id);\n\t\tif (!operation) {\n\t\t\tthrow new TransferError(\"TRANSFER_OPERATION_NOT_FOUND\", \"Transfer operation not found\");\n\t\t}\n\t\treturn operation;\n\t}\n\n\t/**\n\t * Create an operation, or return the existing one for the same\n\t * `(createdBy, kind, idempotencyKey)`. Throws\n\t * `TRANSFER_IDEMPOTENCY_CONFLICT` when that key was used with a different\n\t * package digest, and `TRANSFER_IMPORT_IN_PROGRESS` when another import\n\t * already occupies the target.\n\t */\n\tasync create(\n\t\tinput: CreateTransferOperationInput,\n\t): Promise<{ operation: TransferOperation; created: boolean }> {\n\t\tif (\n\t\t\tinput.idempotencyKey !== undefined &&\n\t\t\t(input.idempotencyKey.length === 0 ||\n\t\t\t\tinput.idempotencyKey.length > MAX_IDEMPOTENCY_KEY_LENGTH)\n\t\t) {\n\t\t\tthrow new TransferError(\"TRANSFER_IDEMPOTENCY_CONFLICT\", \"Invalid idempotency key\");\n\t\t}\n\n\t\tif (input.idempotencyKey !== undefined) {\n\t\t\tconst existing = await this.findByIdempotencyKey(input);\n\t\t\tif (existing) return { operation: existing, created: false };\n\t\t}\n\n\t\tconst id = ulid();\n\t\tconst inserted = await this.db\n\t\t\t.insertInto(\"_emdash_transfer_operations\")\n\t\t\t.values({\n\t\t\t\tid,\n\t\t\t\tkind: input.kind,\n\t\t\t\tstate: input.kind === \"export\" ? \"pending\" : \"uploading\",\n\t\t\t\tidempotency_key: input.idempotencyKey ?? null,\n\t\t\t\tpackage_digest: input.packageDigest ?? null,\n\t\t\t\torigin_site_id: input.originSiteId ?? null,\n\t\t\t\toptions: input.options === undefined ? null : JSON.stringify(input.options),\n\t\t\t\tstaging_secret: createStagingSecret(),\n\t\t\t\truntime_generation: TRANSFER_RUNTIME_GENERATION,\n\t\t\t\tcreated_by: input.createdBy,\n\t\t\t\texpires_at: timestampOffset(this.db, input.ttlSeconds ?? defaultTtl(input.kind)),\n\t\t\t\tstage: null,\n\t\t\t\tcursor: null,\n\t\t\t\tprogress: null,\n\t\t\t\tplan_digest: null,\n\t\t\t\treceipt: null,\n\t\t\t\terror_code: null,\n\t\t\t\terror_detail: null,\n\t\t\t\tlease_token: null,\n\t\t\t\tlease_expires_at: null,\n\t\t\t\tcancel_requested_at: null,\n\t\t\t\tmutation_started_at: null,\n\t\t\t\tcompleted_at: null,\n\t\t\t\tstaging_collected_at: null,\n\t\t\t})\n\t\t\t.onConflict((conflict) => conflict.doNothing())\n\t\t\t.returningAll()\n\t\t\t.executeTakeFirst();\n\t\tif (inserted) return { operation: toOperation(inserted), created: true };\n\n\t\tif (input.idempotencyKey !== undefined) {\n\t\t\tconst existing = await this.findByIdempotencyKey(input);\n\t\t\tif (existing) return { operation: existing, created: false };\n\t\t}\n\t\tthrow new TransferError(\n\t\t\t\"TRANSFER_IMPORT_IN_PROGRESS\",\n\t\t\t\"Another import is already in progress on this site\",\n\t\t);\n\t}\n\n\tprivate async findByIdempotencyKey(\n\t\tinput: CreateTransferOperationInput,\n\t): Promise<TransferOperation | null> {\n\t\tconst row = await this.db\n\t\t\t.selectFrom(\"_emdash_transfer_operations\")\n\t\t\t.selectAll()\n\t\t\t.where(\"created_by\", \"=\", input.createdBy)\n\t\t\t.where(\"kind\", \"=\", input.kind)\n\t\t\t.where(\"idempotency_key\", \"=\", input.idempotencyKey ?? \"\")\n\t\t\t.executeTakeFirst();\n\t\tif (!row) return null;\n\t\tif (\n\t\t\tinput.packageDigest !== undefined &&\n\t\t\trow.package_digest !== null &&\n\t\t\trow.package_digest !== input.packageDigest\n\t\t) {\n\t\t\tthrow new TransferError(\n\t\t\t\t\"TRANSFER_IDEMPOTENCY_CONFLICT\",\n\t\t\t\t\"Idempotency key was already used for a different package\",\n\t\t\t);\n\t\t}\n\t\treturn toOperation(row);\n\t}\n\n\t/** The import that currently occupies the target, if any. */\n\tasync findOccupyingImport(): Promise<TransferOperation | null> {\n\t\tconst row = await this.db\n\t\t\t.selectFrom(\"_emdash_transfer_operations\")\n\t\t\t.selectAll()\n\t\t\t.where(\"kind\", \"=\", \"import\")\n\t\t\t.where((eb) =>\n\t\t\t\teb.or([\n\t\t\t\t\teb(\"state\", \"in\", [...PRE_EXECUTION_IMPORT_STATES, ...EXECUTING_IMPORT_STATES]),\n\t\t\t\t\teb.and([\n\t\t\t\t\t\teb(\"state\", \"in\", [\"failed\", \"cancelled\"]),\n\t\t\t\t\t\teb(\"mutation_started_at\", \"is not\", null),\n\t\t\t\t\t]),\n\t\t\t\t]),\n\t\t\t)\n\t\t\t.executeTakeFirst();\n\t\treturn row ? toOperation(row) : null;\n\t}\n\n\t/**\n\t * Take the operation's lease if it is in one of `states` and no live lease\n\t * exists. Throws `TRANSFER_OPERATION_NOT_FOUND`, or\n\t * `TRANSFER_RUNTIME_MISMATCH` when the row was written by an incompatible\n\t * runtime generation.\n\t */\n\tasync claim(\n\t\tid: string,\n\t\tstates: readonly TransferOperationState[],\n\t\toptions: { leaseSeconds?: number } = {},\n\t): Promise<ClaimResult> {\n\t\tconst leaseToken = ulid();\n\t\tconst now = timestampNow(this.db);\n\t\tconst row = await this.db\n\t\t\t.updateTable(\"_emdash_transfer_operations\")\n\t\t\t.set({\n\t\t\t\tlease_token: leaseToken,\n\t\t\t\tlease_expires_at: timestampOffset(\n\t\t\t\t\tthis.db,\n\t\t\t\t\toptions.leaseSeconds ?? TRANSFER_LIMITS.leaseSeconds,\n\t\t\t\t),\n\t\t\t\tattempt_count: sql<number>`attempt_count + 1`,\n\t\t\t\tupdated_at: now,\n\t\t\t})\n\t\t\t.where(\"id\", \"=\", id)\n\t\t\t.where(\"state\", \"in\", [...states])\n\t\t\t.where(\"runtime_generation\", \"=\", TRANSFER_RUNTIME_GENERATION)\n\t\t\t.where((eb) =>\n\t\t\t\teb.or([\n\t\t\t\t\teb(\"lease_token\", \"is\", null),\n\t\t\t\t\teb(\"lease_expires_at\", \"is\", null),\n\t\t\t\t\ttimestampIsDue(this.db, \"lease_expires_at\"),\n\t\t\t\t]),\n\t\t\t)\n\t\t\t.returningAll()\n\t\t\t.executeTakeFirst();\n\t\tif (row) return { outcome: \"claimed\", operation: toOperation(row), leaseToken };\n\n\t\tconst current = await this.require(id);\n\t\tif (current.runtimeGeneration !== TRANSFER_RUNTIME_GENERATION) {\n\t\t\tthrow new TransferError(\n\t\t\t\t\"TRANSFER_RUNTIME_MISMATCH\",\n\t\t\t\t\"Transfer operation was created by an incompatible EmDash version\",\n\t\t\t);\n\t\t}\n\t\tif (!states.includes(current.state)) return { outcome: \"invalid_state\", operation: current };\n\t\treturn { outcome: \"lease_active\", operation: current };\n\t}\n\n\t/**\n\t * Write state under the lease and extend it. Throws `TRANSFER_LEASE_LOST`\n\t * when the lease is gone.\n\t */\n\tasync advance(id: string, leaseToken: string, patch: OperationPatch): Promise<TransferOperation> {\n\t\treturn this.fencedUpdate(id, leaseToken, {\n\t\t\t...this.patchValues(patch),\n\t\t\tlease_expires_at: timestampOffset(this.db, TRANSFER_LIMITS.leaseSeconds),\n\t\t});\n\t}\n\n\t/** Write state and give up the lease so the next step can claim it. */\n\tasync release(\n\t\tid: string,\n\t\tleaseToken: string,\n\t\tpatch: OperationPatch = {},\n\t): Promise<TransferOperation> {\n\t\treturn this.fencedUpdate(id, leaseToken, {\n\t\t\t...this.patchValues(patch),\n\t\t\tlease_token: null,\n\t\t\tlease_expires_at: null,\n\t\t});\n\t}\n\n\t/**\n\t * Write `patch`, move to `state`, and give up the lease; when a cancel was\n\t * requested while the lease was held, move to `cancelled` instead. One\n\t * statement decides, so a cancel racing the release is never lost.\n\t */\n\tasync releaseUnlessCancelled(\n\t\tid: string,\n\t\tleaseToken: string,\n\t\tstate: TransferOperationState,\n\t\tpatch: Omit<OperationPatch, \"state\"> = {},\n\t): Promise<TransferOperation> {\n\t\tconst now = timestampNow(this.db);\n\t\treturn this.fencedUpdate(id, leaseToken, {\n\t\t\t...this.patchValues(patch),\n\t\t\tstate: sql<string>`CASE WHEN cancel_requested_at IS NULL THEN ${state} ELSE 'cancelled' END`,\n\t\t\tcompleted_at: sql<\n\t\t\t\tstring | null\n\t\t\t>`CASE WHEN cancel_requested_at IS NULL THEN completed_at ELSE ${now} END`,\n\t\t\tlease_token: null,\n\t\t\tlease_expires_at: null,\n\t\t});\n\t}\n\n\tasync complete(\n\t\tid: string,\n\t\tleaseToken: string,\n\t\tresult: { receipt?: SiteImportReceipt; ttlSeconds?: number; progress?: TransferProgress } = {},\n\t): Promise<TransferOperation> {\n\t\treturn this.fencedUpdate(id, leaseToken, {\n\t\t\tstate: \"complete\",\n\t\t\treceipt: result.receipt === undefined ? undefined : JSON.stringify(result.receipt),\n\t\t\tprogress: result.progress === undefined ? undefined : JSON.stringify(result.progress),\n\t\t\tcompleted_at: timestampNow(this.db),\n\t\t\texpires_at:\n\t\t\t\tresult.ttlSeconds === undefined ? undefined : timestampOffset(this.db, result.ttlSeconds),\n\t\t\tlease_token: null,\n\t\t\tlease_expires_at: null,\n\t\t});\n\t}\n\n\tasync fail(\n\t\tid: string,\n\t\tleaseToken: string,\n\t\terror: { code: TransferErrorCode; detail?: TransferErrorDetail },\n\t): Promise<TransferOperation> {\n\t\treturn this.fencedUpdate(id, leaseToken, {\n\t\t\tstate: \"failed\",\n\t\t\terror_code: error.code,\n\t\t\terror_detail: error.detail === undefined ? null : JSON.stringify(error.detail),\n\t\t\tcompleted_at: timestampNow(this.db),\n\t\t\tlease_token: null,\n\t\t\tlease_expires_at: null,\n\t\t});\n\t}\n\n\t/** Finish a cancellation the lease holder observed via `cancelRequestedAt`. */\n\tasync finishCancelled(id: string, leaseToken: string): Promise<TransferOperation> {\n\t\treturn this.fencedUpdate(id, leaseToken, {\n\t\t\tstate: \"cancelled\",\n\t\t\tcompleted_at: timestampNow(this.db),\n\t\t\tlease_token: null,\n\t\t\tlease_expires_at: null,\n\t\t});\n\t}\n\n\t/**\n\t * Cancel an import. Without a live lease the operation becomes `cancelled`\n\t * immediately; otherwise `cancel_requested_at` is set and the lease holder\n\t * stops after its current batch. Returns the updated operation.\n\t */\n\tasync requestCancel(id: string): Promise<TransferOperation> {\n\t\tconst cancellable = [...PRE_EXECUTION_IMPORT_STATES, ...EXECUTING_IMPORT_STATES];\n\t\tconst now = timestampNow(this.db);\n\t\tconst immediate = await this.db\n\t\t\t.updateTable(\"_emdash_transfer_operations\")\n\t\t\t.set({\n\t\t\t\tstate: \"cancelled\",\n\t\t\t\tcancel_requested_at: now,\n\t\t\t\tcompleted_at: now,\n\t\t\t\tupdated_at: now,\n\t\t\t\tlease_token: null,\n\t\t\t\tlease_expires_at: null,\n\t\t\t})\n\t\t\t.where(\"id\", \"=\", id)\n\t\t\t.where(\"kind\", \"=\", \"import\")\n\t\t\t.where(\"state\", \"in\", cancellable)\n\t\t\t.where((eb) =>\n\t\t\t\teb.or([\n\t\t\t\t\teb(\"lease_token\", \"is\", null),\n\t\t\t\t\teb(\"lease_expires_at\", \"is\", null),\n\t\t\t\t\ttimestampIsDue(this.db, \"lease_expires_at\"),\n\t\t\t\t]),\n\t\t\t)\n\t\t\t.returningAll()\n\t\t\t.executeTakeFirst();\n\t\tif (immediate) return toOperation(immediate);\n\n\t\tconst flagged = await this.db\n\t\t\t.updateTable(\"_emdash_transfer_operations\")\n\t\t\t.set({ cancel_requested_at: now, updated_at: now })\n\t\t\t.where(\"id\", \"=\", id)\n\t\t\t.where(\"kind\", \"=\", \"import\")\n\t\t\t.where(\"state\", \"in\", cancellable)\n\t\t\t.returningAll()\n\t\t\t.executeTakeFirst();\n\t\tif (flagged) return toOperation(flagged);\n\n\t\tawait this.require(id);\n\t\tthrow new TransferError(\"TRANSFER_INVALID_STATE\", \"Transfer operation cannot be cancelled\");\n\t}\n\n\t/**\n\t * Mark a failed or cancelled import abandoned. Lifts the write fence; never\n\t * deletes imported data.\n\t */\n\tasync abandon(id: string): Promise<TransferOperation> {\n\t\tconst now = timestampNow(this.db);\n\t\tconst row = await this.db\n\t\t\t.updateTable(\"_emdash_transfer_operations\")\n\t\t\t.set({ state: \"abandoned\", updated_at: now })\n\t\t\t.where(\"id\", \"=\", id)\n\t\t\t.where(\"kind\", \"=\", \"import\")\n\t\t\t.where(\"state\", \"in\", [\"failed\", \"cancelled\"])\n\t\t\t.where((eb) =>\n\t\t\t\teb.or([\n\t\t\t\t\teb(\"lease_token\", \"is\", null),\n\t\t\t\t\teb(\"lease_expires_at\", \"is\", null),\n\t\t\t\t\ttimestampIsDue(this.db, \"lease_expires_at\"),\n\t\t\t\t]),\n\t\t\t)\n\t\t\t.returningAll()\n\t\t\t.executeTakeFirst();\n\t\tif (row) return toOperation(row);\n\t\tawait this.require(id);\n\t\tthrow new TransferError(\n\t\t\t\"TRANSFER_INVALID_STATE\",\n\t\t\t\"Only a failed or cancelled import can be abandoned\",\n\t\t);\n\t}\n\n\t/**\n\t * Move operations past their `expires_at` to `expired` (pre-execution\n\t * imports and every non-expired export) when no live lease holds them.\n\t * Returns the expired operations so their staging can be collected.\n\t */\n\tasync expireDue(\n\t\tlimit = 50,\n\t): Promise<Array<Pick<TransferOperation, \"id\" | \"kind\" | \"stagingSecret\">>> {\n\t\tconst candidates = await this.db\n\t\t\t.selectFrom(\"_emdash_transfer_operations\")\n\t\t\t.select(\"id\")\n\t\t\t.where(\"expires_at\", \"is not\", null)\n\t\t\t.where(timestampIsDue(this.db, \"expires_at\"))\n\t\t\t.where((eb) =>\n\t\t\t\teb.or([\n\t\t\t\t\teb.and([\n\t\t\t\t\t\teb(\"kind\", \"=\", \"import\"),\n\t\t\t\t\t\teb(\"state\", \"in\", [...PRE_EXECUTION_IMPORT_STATES]),\n\t\t\t\t\t\teb(\"mutation_started_at\", \"is\", null),\n\t\t\t\t\t]),\n\t\t\t\t\teb.and([\n\t\t\t\t\t\teb(\"kind\", \"=\", \"export\"),\n\t\t\t\t\t\teb(\"state\", \"in\", [\"pending\", \"running\", \"complete\", \"failed\"]),\n\t\t\t\t\t]),\n\t\t\t\t]),\n\t\t\t)\n\t\t\t.where((eb) =>\n\t\t\t\teb.or([\n\t\t\t\t\teb(\"lease_token\", \"is\", null),\n\t\t\t\t\teb(\"lease_expires_at\", \"is\", null),\n\t\t\t\t\ttimestampIsDue(this.db, \"lease_expires_at\"),\n\t\t\t\t]),\n\t\t\t)\n\t\t\t.orderBy(\"expires_at\")\n\t\t\t.limit(limit)\n\t\t\t.execute();\n\t\tif (candidates.length === 0) return [];\n\t\tconst now = timestampNow(this.db);\n\t\tconst rows = await this.db\n\t\t\t.updateTable(\"_emdash_transfer_operations\")\n\t\t\t.set({ state: \"expired\", updated_at: now, lease_token: null, lease_expires_at: null })\n\t\t\t.where(\n\t\t\t\t\"id\",\n\t\t\t\t\"in\",\n\t\t\t\tcandidates.map((candidate) => candidate.id),\n\t\t\t)\n\t\t\t.where(timestampIsDue(this.db, \"expires_at\"))\n\t\t\t.where((eb) =>\n\t\t\t\teb.or([\n\t\t\t\t\teb.and([\n\t\t\t\t\t\teb(\"kind\", \"=\", \"import\"),\n\t\t\t\t\t\teb(\"state\", \"in\", [...PRE_EXECUTION_IMPORT_STATES]),\n\t\t\t\t\t\teb(\"mutation_started_at\", \"is\", null),\n\t\t\t\t\t]),\n\t\t\t\t\teb.and([\n\t\t\t\t\t\teb(\"kind\", \"=\", \"export\"),\n\t\t\t\t\t\teb(\"state\", \"in\", [\"pending\", \"running\", \"complete\", \"failed\"]),\n\t\t\t\t\t]),\n\t\t\t\t]),\n\t\t\t)\n\t\t\t.returning([\"id\", \"kind\", \"staging_secret\"])\n\t\t\t.execute();\n\t\treturn rows.flatMap((row) =>\n\t\t\tisTransferOperationKind(row.kind)\n\t\t\t\t? [{ id: row.id, kind: row.kind, stagingSecret: row.staging_secret }]\n\t\t\t\t: [],\n\t\t);\n\t}\n\n\t/**\n\t * Operations whose staging area can be collected and has not been yet:\n\t * imports in a terminal state, and exports that failed or expired\n\t * (complete exports stay downloadable until they expire). Oldest first.\n\t * A collector deletes staged objects with `TransferStage.deleteSome` until\n\t * it returns 0, deletes child rows with {@link deleteChildRows} until it\n\t * returns 0, then calls {@link markCollected}; a crash anywhere in between\n\t * leaves the operation listed here, so collection resumes.\n\t *\n\t * `importRetentionSeconds` keeps a finished import's staging for that long\n\t * after its last state change; expired imports are listed at once.\n\t */\n\tasync listUncollected(\n\t\tlimit = 20,\n\t\toptions: { importRetentionSeconds?: number } = {},\n\t): Promise<Array<Pick<TransferOperation, \"id\" | \"kind\" | \"state\" | \"stagingSecret\">>> {\n\t\tconst retention = options.importRetentionSeconds ?? 0;\n\t\tconst retainedStates = TERMINAL_IMPORT_STATES.filter((state) => state !== \"expired\");\n\t\tconst rows = await this.db\n\t\t\t.selectFrom(\"_emdash_transfer_operations\")\n\t\t\t.select([\"id\", \"kind\", \"state\", \"staging_secret\"])\n\t\t\t.where(\"staging_collected_at\", \"is\", null)\n\t\t\t.where((eb) =>\n\t\t\t\teb.or([\n\t\t\t\t\teb.and([eb(\"kind\", \"=\", \"import\"), eb(\"state\", \"=\", \"expired\")]),\n\t\t\t\t\teb.and([\n\t\t\t\t\t\teb(\"kind\", \"=\", \"import\"),\n\t\t\t\t\t\teb(\"state\", \"in\", retainedStates),\n\t\t\t\t\t\ttimestampIsOlderThan(this.db, \"updated_at\", retention),\n\t\t\t\t\t]),\n\t\t\t\t\teb.and([eb(\"kind\", \"=\", \"export\"), eb(\"state\", \"in\", [\"failed\", \"expired\"])]),\n\t\t\t\t]),\n\t\t\t)\n\t\t\t.where((eb) =>\n\t\t\t\teb.or([\n\t\t\t\t\teb(\"lease_token\", \"is\", null),\n\t\t\t\t\teb(\"lease_expires_at\", \"is\", null),\n\t\t\t\t\ttimestampIsDue(this.db, \"lease_expires_at\"),\n\t\t\t\t]),\n\t\t\t)\n\t\t\t.orderBy(\"updated_at\")\n\t\t\t.orderBy(\"id\")\n\t\t\t.limit(Math.min(Math.max(limit, 1), 100))\n\t\t\t.execute();\n\t\treturn rows.flatMap((row) =>\n\t\t\tisTransferOperationKind(row.kind) && isTransferOperationState(row.state)\n\t\t\t\t? [{ id: row.id, kind: row.kind, state: row.state, stagingSecret: row.staging_secret }]\n\t\t\t\t: [],\n\t\t);\n\t}\n\n\t/** Record that an operation's staging area and child rows are gone. */\n\tasync markCollected(id: string): Promise<void> {\n\t\tawait this.db\n\t\t\t.updateTable(\"_emdash_transfer_operations\")\n\t\t\t.set({ staging_collected_at: timestampNow(this.db) })\n\t\t\t.where(\"id\", \"=\", id)\n\t\t\t.where(\"staging_collected_at\", \"is\", null)\n\t\t\t.execute();\n\t}\n\n\t/**\n\t * Delete up to `limit` child rows of each child table of an operation\n\t * (staged files, package index, media blobs), one bounded statement per\n\t * table. Returns the number deleted; call until it returns 0. Always drain\n\t * children this way before deleting an operation row: an `ON DELETE\n\t * CASCADE` over millions of child rows in one statement exceeds D1's\n\t * limits.\n\t */\n\tasync deleteChildRows(operationId: string, limit = 500): Promise<number> {\n\t\tconst bounded = Math.min(Math.max(Math.trunc(limit), 1), 5000);\n\t\tconst staged = await sql`\n\t\t\tDELETE FROM _emdash_transfer_staged_files\n\t\t\tWHERE operation_id = ${operationId}\n\t\t\t\tAND path IN (\n\t\t\t\t\tSELECT path FROM _emdash_transfer_staged_files\n\t\t\t\t\tWHERE operation_id = ${operationId}\n\t\t\t\t\tLIMIT ${bounded}\n\t\t\t\t)\n\t\t`.execute(this.db);\n\t\tconst indexed = await sql`\n\t\t\tDELETE FROM _emdash_transfer_package_index\n\t\t\tWHERE operation_id = ${operationId}\n\t\t\t\tAND (kind, id) IN (\n\t\t\t\t\tSELECT kind, id FROM _emdash_transfer_package_index\n\t\t\t\t\tWHERE operation_id = ${operationId}\n\t\t\t\t\tLIMIT ${bounded}\n\t\t\t\t)\n\t\t`.execute(this.db);\n\t\tconst blobs = await sql`\n\t\t\tDELETE FROM _emdash_transfer_media_blobs\n\t\t\tWHERE operation_id = ${operationId}\n\t\t\t\tAND media_id IN (\n\t\t\t\t\tSELECT media_id FROM _emdash_transfer_media_blobs\n\t\t\t\t\tWHERE operation_id = ${operationId}\n\t\t\t\t\tLIMIT ${bounded}\n\t\t\t\t)\n\t\t`.execute(this.db);\n\t\treturn [staged, indexed, blobs].reduce(\n\t\t\t(sum, result) => sum + Number(result.numAffectedRows ?? 0n),\n\t\t\t0,\n\t\t);\n\t}\n\n\t/**\n\t * Delete a collected operation row once it has no child rows left.\n\t * Returns false, deleting nothing, otherwise. Identity-map rows are kept.\n\t */\n\tasync deleteIfChildless(id: string): Promise<boolean> {\n\t\tconst result = await this.db\n\t\t\t.deleteFrom(\"_emdash_transfer_operations\")\n\t\t\t.where(\"id\", \"=\", id)\n\t\t\t.where(\"staging_collected_at\", \"is not\", null)\n\t\t\t.where((eb) =>\n\t\t\t\teb.and([\n\t\t\t\t\teb.not(\n\t\t\t\t\t\teb.exists(\n\t\t\t\t\t\t\teb\n\t\t\t\t\t\t\t\t.selectFrom(\"_emdash_transfer_staged_files\")\n\t\t\t\t\t\t\t\t.select(\"path\")\n\t\t\t\t\t\t\t\t.where(\"_emdash_transfer_staged_files.operation_id\", \"=\", id),\n\t\t\t\t\t\t),\n\t\t\t\t\t),\n\t\t\t\t\teb.not(\n\t\t\t\t\t\teb.exists(\n\t\t\t\t\t\t\teb\n\t\t\t\t\t\t\t\t.selectFrom(\"_emdash_transfer_package_index\")\n\t\t\t\t\t\t\t\t.select(\"kind\")\n\t\t\t\t\t\t\t\t.where(\"_emdash_transfer_package_index.operation_id\", \"=\", id),\n\t\t\t\t\t\t),\n\t\t\t\t\t),\n\t\t\t\t\teb.not(\n\t\t\t\t\t\teb.exists(\n\t\t\t\t\t\t\teb\n\t\t\t\t\t\t\t\t.selectFrom(\"_emdash_transfer_media_blobs\")\n\t\t\t\t\t\t\t\t.select(\"media_id\")\n\t\t\t\t\t\t\t\t.where(\"_emdash_transfer_media_blobs.operation_id\", \"=\", id),\n\t\t\t\t\t\t),\n\t\t\t\t\t),\n\t\t\t\t]),\n\t\t\t)\n\t\t\t.executeTakeFirst();\n\t\treturn Number(result.numDeletedRows ?? 0n) > 0;\n\t}\n\n\t/**\n\t * Bump `write_epoch` on every running export. Fenced write paths call this\n\t * so an export's consistency fence notices writes to tables that have no\n\t * `updated_at`. Returns the number of exports touched.\n\t */\n\tasync recordWriteForRunningExports(): Promise<number> {\n\t\treturn bumpRunningExportWriteEpochs(this.db);\n\t}\n\n\t/** Operations newest first, `{ items, nextCursor }` over `(created_at, id)`. */\n\tasync list(\n\t\toptions: {\n\t\t\tkind?: TransferOperationKind;\n\t\t\tcreatedBy?: string;\n\t\t\tlimit?: number;\n\t\t\tcursor?: { createdAt: string; id: string };\n\t\t} = {},\n\t): Promise<{ items: PublicTransferOperation[]; next?: { createdAt: string; id: string } }> {\n\t\tconst limit = Math.min(Math.max(options.limit ?? 50, 1), 100);\n\t\tlet query = this.db.selectFrom(\"_emdash_transfer_operations\").selectAll();\n\t\tif (options.kind) query = query.where(\"kind\", \"=\", options.kind);\n\t\tif (options.createdBy) query = query.where(\"created_by\", \"=\", options.createdBy);\n\t\tconst cursor = options.cursor;\n\t\tif (cursor) {\n\t\t\tquery = query.where((eb) =>\n\t\t\t\teb.or([\n\t\t\t\t\teb(\"created_at\", \"<\", cursor.createdAt),\n\t\t\t\t\teb.and([eb(\"created_at\", \"=\", cursor.createdAt), eb(\"id\", \"<\", cursor.id)]),\n\t\t\t\t]),\n\t\t\t);\n\t\t}\n\t\tconst rows = await query\n\t\t\t.orderBy(\"created_at\", \"desc\")\n\t\t\t.orderBy(\"id\", \"desc\")\n\t\t\t.limit(limit + 1)\n\t\t\t.execute();\n\t\tconst items = rows.slice(0, limit).map((row) => toPublicOperation(toOperation(row)));\n\t\tconst last = items.at(-1);\n\t\treturn rows.length > limit && last\n\t\t\t? { items, next: { createdAt: last.createdAt, id: last.id } }\n\t\t\t: { items };\n\t}\n\n\tprivate patchValues(patch: OperationPatch): OperationUpdate {\n\t\tconst values: OperationUpdate = {};\n\t\tif (patch.state !== undefined) values.state = patch.state;\n\t\tif (patch.stage !== undefined) values.stage = patch.stage;\n\t\tif (patch.cursor !== undefined) {\n\t\t\tvalues.cursor =\n\t\t\t\tpatch.cursor === null ? null : JSON.stringify(transferCursorSchema.parse(patch.cursor));\n\t\t}\n\t\tif (patch.progress !== undefined) {\n\t\t\tvalues.progress =\n\t\t\t\tpatch.progress === null\n\t\t\t\t\t? null\n\t\t\t\t\t: JSON.stringify(transferProgressSchema.parse(patch.progress));\n\t\t}\n\t\tif (patch.packageDigest !== undefined) values.package_digest = patch.packageDigest;\n\t\tif (patch.planDigest !== undefined) values.plan_digest = patch.planDigest;\n\t\tif (patch.originSiteId !== undefined) values.origin_site_id = patch.originSiteId;\n\t\tif (patch.markMutationStarted) {\n\t\t\tvalues.mutation_started_at = sql<string>`COALESCE(mutation_started_at, ${timestampNow(this.db)})`;\n\t\t}\n\t\tif (patch.ttlSeconds !== undefined)\n\t\t\tvalues.expires_at = timestampOffset(this.db, patch.ttlSeconds);\n\t\tif (patch.retryError !== undefined) {\n\t\t\tvalues.error_code = patch.retryError?.code ?? null;\n\t\t\tvalues.error_detail =\n\t\t\t\tpatch.retryError?.detail === undefined ? null : JSON.stringify(patch.retryError.detail);\n\t\t}\n\t\treturn values;\n\t}\n\n\tprivate async fencedUpdate(\n\t\tid: string,\n\t\tleaseToken: string,\n\t\tvalues: OperationUpdate,\n\t): Promise<TransferOperation> {\n\t\tconst row = await this.db\n\t\t\t.updateTable(\"_emdash_transfer_operations\")\n\t\t\t.set({ ...values, updated_at: timestampNow(this.db) })\n\t\t\t.where(\"id\", \"=\", id)\n\t\t\t.where(\"lease_token\", \"=\", leaseToken)\n\t\t\t.where(\"lease_expires_at\", \"is not\", null)\n\t\t\t.where(timestampIsLive(this.db, \"lease_expires_at\"))\n\t\t\t.returningAll()\n\t\t\t.executeTakeFirst();\n\t\tif (!row) {\n\t\t\tthrow new TransferError(\"TRANSFER_LEASE_LOST\", \"Transfer operation lease was lost\");\n\t\t}\n\t\treturn toOperation(row);\n\t}\n}\n\nfunction defaultTtl(kind: TransferOperationKind): number {\n\treturn kind === \"export\"\n\t\t? TRANSFER_LIMITS.exportTtlSeconds\n\t\t: TRANSFER_LIMITS.pendingImportTtlSeconds;\n}\n","/**\n * Byte-level access to one operation's staging area.\n */\n\nimport type { DownloadResult, Storage } from \"../../storage/types.js\";\nimport { TransferError, isTransferError } from \"../errors.js\";\nimport { createHashingStream, createSha256 } from \"../format/digest.js\";\nimport { stagingAuxKey, stagingKey, type StagingAuxFile } from \"./keys.js\";\n\ntype FixedLengthStreamConstructor = new (\n\texpectedLength: number | bigint,\n) => TransformStream<ArrayBufferView | ArrayBuffer, Uint8Array>;\n\ndeclare const FixedLengthStream: FixedLengthStreamConstructor | undefined;\n\nexport interface ExpectedFile {\n\tbytes: number;\n\t/** Lowercase hex SHA-256. */\n\tsha256: string;\n}\n\nexport interface PutVerifiedOptions {\n\tcontentType?: string;\n\t/**\n\t * Called before deleting the object after a failed upload; return true to\n\t * keep it (the path was already verified by another upload).\n\t */\n\tkeepExistingOnFailure?: () => Promise<boolean>;\n}\n\nconst PACKAGE_CONTENT_TYPE = \"application/octet-stream\";\n\nfunction oversizeError(): TransferError {\n\treturn new TransferError(\"TRANSFER_FILE_SIZE_MISMATCH\", \"File is larger than declared\");\n}\n\nfunction toStream(body: ReadableStream<Uint8Array> | Uint8Array): ReadableStream<Uint8Array> {\n\tif (body instanceof Uint8Array) {\n\t\treturn new ReadableStream<Uint8Array>({\n\t\t\tstart(controller) {\n\t\t\t\tif (body.byteLength > 0) controller.enqueue(body);\n\t\t\t\tcontroller.close();\n\t\t\t},\n\t\t});\n\t}\n\treturn body;\n}\n\n/**\n * Stream `body` into `key`, hashing and counting as it goes. The object is\n * kept only if exactly `expected.bytes` bytes with digest `expected.sha256`\n * were written; otherwise it is deleted and `TRANSFER_FILE_SIZE_MISMATCH` or\n * `TRANSFER_FILE_DIGEST_MISMATCH` is thrown. Where the runtime provides\n * `FixedLengthStream` (workerd), the upload is wrapped in one so R2 receives\n * a known length.\n *\n * Callers staging a package file must check its staged-files row first and\n * refuse the upload when it is already `verified` and its object still\n * matches, and must pass `keepExistingOnFailure` returning true once the row\n * is verified: a failed retry or concurrent upload of the same path must not\n * delete the object a successful upload stored. A failing upload that\n * already overwrote the object can still leave bad bytes behind a verified\n * row, so readers verify sizes and digests again when they read staged\n * files, and a later upload of that path replaces the bad object.\n */\nexport async function putVerified(\n\tstorage: Storage,\n\tkey: string,\n\tbody: ReadableStream<Uint8Array> | Uint8Array,\n\texpected: ExpectedFile,\n\toptions: PutVerifiedOptions = {},\n): Promise<void> {\n\tconst discard = async () => {\n\t\tif (options.keepExistingOnFailure && (await options.keepExistingOnFailure())) return;\n\t\tawait storage.delete(key).catch(() => undefined);\n\t};\n\tif (!Number.isSafeInteger(expected.bytes) || expected.bytes < 0) {\n\t\tthrow new TransferError(\"TRANSFER_FILE_SIZE_MISMATCH\", \"Invalid declared size\");\n\t}\n\tconst hasher = await createSha256();\n\tconst hashing = createHashingStream(hasher, {\n\t\tmaxBytes: expected.bytes,\n\t\tonLimitExceeded: oversizeError,\n\t});\n\tlet stream = toStream(body).pipeThrough(hashing.stream);\n\tif (typeof FixedLengthStream !== \"undefined\") {\n\t\tstream = stream.pipeThrough(new FixedLengthStream(expected.bytes));\n\t}\n\n\ttry {\n\t\tawait storage.upload({\n\t\t\tkey,\n\t\t\tbody: stream,\n\t\t\tcontentType: options.contentType ?? PACKAGE_CONTENT_TYPE,\n\t\t});\n\t} catch (error) {\n\t\tawait discard();\n\t\tif (isTransferError(error)) throw error;\n\t\tconst cause = findTransferError(error);\n\t\tif (cause) throw cause;\n\t\tif (hashing.bytes() !== expected.bytes) {\n\t\t\tthrow new TransferError(\"TRANSFER_FILE_SIZE_MISMATCH\", \"File size does not match\", {\n\t\t\t\tcause: error,\n\t\t\t});\n\t\t}\n\t\tthrow new TransferError(\"TRANSFER_STORAGE_ERROR\", \"Failed to store file\", { cause: error });\n\t}\n\n\tconst digest = await hasher.digest();\n\tif (hashing.bytes() !== expected.bytes) {\n\t\tawait discard();\n\t\tthrow new TransferError(\"TRANSFER_FILE_SIZE_MISMATCH\", \"File size does not match\", {\n\t\t\tdetail: { expected: expected.bytes, actual: hashing.bytes() },\n\t\t});\n\t}\n\tif (digest !== expected.sha256) {\n\t\tawait discard();\n\t\tthrow new TransferError(\"TRANSFER_FILE_DIGEST_MISMATCH\", \"File digest does not match\");\n\t}\n}\n\nfunction findTransferError(error: unknown): TransferError | null {\n\tlet current: unknown = error;\n\tfor (let depth = 0; depth < 5 && current instanceof Error; depth++) {\n\t\tif (current instanceof TransferError) return current;\n\t\tcurrent = current.cause;\n\t}\n\treturn null;\n}\n\n/** Read a whole stream, failing once it exceeds `maxBytes`. */\nexport async function readStreamBytes(\n\tstream: ReadableStream<Uint8Array>,\n\tmaxBytes: number,\n): Promise<Uint8Array> {\n\tconst reader = stream.getReader();\n\tconst parts: Uint8Array[] = [];\n\tlet total = 0;\n\ttry {\n\t\tfor (;;) {\n\t\t\tconst { done, value } = await reader.read();\n\t\t\tif (done) break;\n\t\t\ttotal += value.byteLength;\n\t\t\tif (total > maxBytes) {\n\t\t\t\tthrow new TransferError(\"TRANSFER_LIMIT_EXCEEDED\", \"File exceeds its size limit\", {\n\t\t\t\t\tdetail: { limit: maxBytes },\n\t\t\t\t});\n\t\t\t}\n\t\t\tparts.push(value);\n\t\t}\n\t} catch (error) {\n\t\tawait reader.cancel().catch(() => undefined);\n\t\tthrow error;\n\t} finally {\n\t\treader.releaseLock();\n\t}\n\tconst bytes = new Uint8Array(total);\n\tlet offset = 0;\n\tfor (const part of parts) {\n\t\tbytes.set(part, offset);\n\t\toffset += part.byteLength;\n\t}\n\treturn bytes;\n}\n\n/** One operation's staging area in `storage` under `prefix` (see keys.ts). */\nexport class TransferStage {\n\tconstructor(\n\t\treadonly storage: Storage,\n\t\treadonly prefix: string,\n\t) {}\n\n\tkeyFor(path: string): string {\n\t\treturn stagingKey(this.prefix, path);\n\t}\n\n\tasync putVerified(\n\t\tpath: string,\n\t\tbody: ReadableStream<Uint8Array> | Uint8Array,\n\t\tbytes: number,\n\t\tsha256: string,\n\t\toptions: PutVerifiedOptions = {},\n\t): Promise<void> {\n\t\tawait putVerified(this.storage, this.keyFor(path), body, { bytes, sha256 }, options);\n\t}\n\n\tasync exists(path: string): Promise<boolean> {\n\t\treturn this.storage.exists(this.keyFor(path));\n\t}\n\n\tasync open(path: string): Promise<DownloadResult> {\n\t\ttry {\n\t\t\treturn await this.storage.download(this.keyFor(path));\n\t\t} catch (error) {\n\t\t\tthrow new TransferError(\"TRANSFER_FILE_MISSING\", \"Staged file is missing\", {\n\t\t\t\tdetail: { path },\n\t\t\t\tcause: error,\n\t\t\t});\n\t\t}\n\t}\n\n\tasync readBytes(path: string, maxBytes: number): Promise<Uint8Array> {\n\t\tconst file = await this.open(path);\n\t\treturn readStreamBytes(file.body, maxBytes);\n\t}\n\n\tasync putAux(file: StagingAuxFile, content: string): Promise<void> {\n\t\tawait this.storage.upload({\n\t\t\tkey: stagingAuxKey(this.prefix, file),\n\t\t\tbody: new TextEncoder().encode(content),\n\t\t\tcontentType: \"application/json\",\n\t\t});\n\t}\n\n\tasync readAux(file: StagingAuxFile, maxBytes: number): Promise<string | null> {\n\t\tconst key = stagingAuxKey(this.prefix, file);\n\t\tif (!(await this.storage.exists(key))) return null;\n\t\tconst download = await this.storage.download(key);\n\t\treturn new TextDecoder().decode(await readStreamBytes(download.body, maxBytes));\n\t}\n\n\t/**\n\t * Delete up to `limit` staged objects. Returns the number deleted; call\n\t * again until it returns 0.\n\t */\n\tasync deleteSome(limit = 100): Promise<number> {\n\t\tconst listing = await this.storage.list({ prefix: this.prefix, limit });\n\t\tfor (const file of listing.files) await this.storage.delete(file.key);\n\t\treturn listing.files.length;\n\t}\n}\n"],"mappings":"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"}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { n as chunks, t as SQL_BATCH_SIZE } from "./chunks-
|
|
2
|
-
import {
|
|
1
|
+
import { n as chunks, t as SQL_BATCH_SIZE } from "./chunks-DiW8VMwz.mjs";
|
|
2
|
+
import { a as InvalidCursorError, l as decodeCursor, s as STAGED_CURSOR_MARKER, u as encodeCursor } from "./types-DwhEvIVb.mjs";
|
|
3
3
|
import { sql } from "kysely";
|
|
4
4
|
import { ulid } from "ulidx";
|
|
5
5
|
|
|
@@ -683,4 +683,4 @@ function mergeStagedReferenceBaselines(base, incoming) {
|
|
|
683
683
|
|
|
684
684
|
//#endregion
|
|
685
685
|
export { mergeStagedReferenceBaselines as a, readStagedReferenceBaselines as c, RelationRepository as d, STAGED_REFERENCES_KEY as i, readStagedReferences as l, REFERENCE_PAGE_MAX_LIMIT as n, mergeStagedReferences as o, STAGED_REFERENCES_BASELINE_KEY as r, pageStagedGroups as s, REFERENCE_PAGE_LIMIT as t, REFERENCE_INSERT_BATCH_SIZE as u };
|
|
686
|
-
//# sourceMappingURL=staged-
|
|
686
|
+
//# sourceMappingURL=staged-ByBmPFtX.mjs.map
|