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,4 +1,4 @@
|
|
|
1
|
-
import { t as Database } from "./types-
|
|
1
|
+
import { t as Database } from "./types-DKwRUA-x.mjs";
|
|
2
2
|
import { Kysely } from "kysely";
|
|
3
3
|
import { Migrator } from "kysely/migration";
|
|
4
4
|
|
|
@@ -22,6 +22,11 @@ interface MigrationOptions {
|
|
|
22
22
|
* give-up path doesn't take 10 seconds per case.
|
|
23
23
|
*/
|
|
24
24
|
raceWaitMs?: number;
|
|
25
|
+
/**
|
|
26
|
+
* Refuse with MigrationRowLimitError, before taking the migration lock, when
|
|
27
|
+
* the pending content-sized migrations process more rows than this.
|
|
28
|
+
*/
|
|
29
|
+
contentRowLimit?: number;
|
|
25
30
|
}
|
|
26
31
|
/**
|
|
27
32
|
* Get migration status
|
|
@@ -65,4 +70,4 @@ declare function rollbackMigration(db: Kysely<Database>, options?: MigrationOpti
|
|
|
65
70
|
}>;
|
|
66
71
|
//#endregion
|
|
67
72
|
export { getMigrationStatus as a, getExactMigrationStatus as i, MIGRATION_NAMES as n, rollbackMigration as o, MigrationStatus as r, runMigrations as s, ExactMigrationStatus as t };
|
|
68
|
-
//# sourceMappingURL=runner-
|
|
73
|
+
//# sourceMappingURL=runner-Dfgp6-S_.d.mts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"runner-Dfgp6-S_.d.mts","names":[],"sources":["../src/database/migrations/runner.ts"],"mappings":";;;;;;cAqMa,eAAA;AAAA,UAeI,eAAA;EAChB,OAAA;EACA,OAAA;AAAA;AAAA,UAGgB,oBAAA;EAChB,YAAA;EACA,OAAA;EACA,cAAA;AAAA;AAAA,UAwEgB,gBAAA;EAChB,oBAAA;EA+LI;;;;;EAzLJ,UAAA;EAyLI;;;;EApLJ,eAAA;AAAA;;;AAyPD;iBAzOsB,kBAAA,CACrB,EAAA,EAAI,MAAA,CAAO,QAAA,GACX,OAAA,GAAU,gBAAA,GACR,OAAA,CAAQ,eAAA;;;;;;iBAgKW,uBAAA,CACrB,EAAA,EAAI,MAAA,CAAO,QAAA,GACX,OAAA,GAAU,gBAAA,GACR,OAAA,CAAQ,oBAAA;;;;AAwIX;;;;;;;;;;;;;;;;;;iBArEsB,aAAA,CACrB,EAAA,EAAI,MAAA,CAAO,QAAA,GACX,OAAA,GAAU,gBAAA,GACR,OAAA;EAAU,OAAA;AAAA;;;;iBAkES,iBAAA,CACrB,EAAA,EAAI,MAAA,CAAO,QAAA,GACX,OAAA,GAAU,gBAAA,GACR,OAAA;EAAU,UAAA;AAAA"}
|
package/dist/runtime.d.mts
CHANGED
|
@@ -1,16 +1,17 @@
|
|
|
1
|
-
import "./parse-
|
|
2
|
-
import "./types-
|
|
3
|
-
import "./types-
|
|
4
|
-
import "./options-
|
|
5
|
-
import "./entry-lock-
|
|
6
|
-
import { f as MediaProvider } from "./placeholder-
|
|
7
|
-
import {
|
|
8
|
-
import "./runner-
|
|
9
|
-
import "./storage-query-
|
|
10
|
-
import "./
|
|
11
|
-
import "./
|
|
12
|
-
import "./
|
|
13
|
-
import "./
|
|
1
|
+
import "./parse-Dndx1QmN.mjs";
|
|
2
|
+
import "./types-DKwRUA-x.mjs";
|
|
3
|
+
import "./types-CjftrmZR.mjs";
|
|
4
|
+
import "./options-BUUgroHg.mjs";
|
|
5
|
+
import "./entry-lock-BulbgPBX.mjs";
|
|
6
|
+
import { f as MediaProvider } from "./placeholder-CSKu5OkD.mjs";
|
|
7
|
+
import { Bn as getDb, Fn as EntryData, In as EntryFilter, Pn as CollectionFilter, zn as emdashLoader } from "./config-sDhZvkLR.mjs";
|
|
8
|
+
import "./runner-Dfgp6-S_.mjs";
|
|
9
|
+
import "./storage-query-BFp06Y0s.mjs";
|
|
10
|
+
import "./utils-Szp4iBQB.mjs";
|
|
11
|
+
import "./index-VM7Fzxwe.mjs";
|
|
12
|
+
import "./types-CadaL_k8.mjs";
|
|
13
|
+
import "./hreflang-8dUOJAPJ.mjs";
|
|
14
|
+
import "./validate-DDvxy6qG.mjs";
|
|
14
15
|
|
|
15
16
|
//#region src/media/provider-loader.d.ts
|
|
16
17
|
/**
|
package/dist/runtime.d.mts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"runtime.d.mts","names":[],"sources":["../src/media/provider-loader.ts"],"mappings":"
|
|
1
|
+
{"version":3,"file":"runtime.d.mts","names":[],"sources":["../src/media/provider-loader.ts"],"mappings":";;;;;;;;;;;;;;;;;;;;;;AAuDA;;;;;;;;iBAAsB,gBAAA,CAAiB,UAAA,WAAqB,OAAA,CAAQ,aAAA"}
|
package/dist/runtime.mjs
CHANGED
|
@@ -1,10 +1,12 @@
|
|
|
1
|
-
import "./dialect-helpers-
|
|
2
|
-
import "./config-
|
|
1
|
+
import "./dialect-helpers-B1XN2HGB.mjs";
|
|
2
|
+
import "./config-Cs_AwWXI.mjs";
|
|
3
|
+
import "./after-32yNRvd2.mjs";
|
|
3
4
|
import "./base64-BQBZwXCx.mjs";
|
|
4
|
-
import "./
|
|
5
|
-
import "./
|
|
6
|
-
import
|
|
7
|
-
import "./
|
|
5
|
+
import "./query-BFHjCzSh.mjs";
|
|
6
|
+
import "./request-cache-5z2WzWmh.mjs";
|
|
7
|
+
import "./types-DwhEvIVb.mjs";
|
|
8
|
+
import { c as emdashLoader, u as getDb } from "./loader-DhnedqY4.mjs";
|
|
9
|
+
import "./json-recordset-D0WhN2UA.mjs";
|
|
8
10
|
|
|
9
11
|
//#region src/media/provider-loader.ts
|
|
10
12
|
let virtualMediaProviders;
|
package/dist/runtime.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"runtime.mjs","names":[],"sources":["../src/media/provider-loader.ts"],"sourcesContent":["/**\n * Media Provider Loader\n *\n * Lazy-loads media providers from virtual module for frontend rendering.\n * Similar pattern to getDb() - providers are loaded on first use and cached.\n *\n * This allows EmDashMedia component to render media without requiring\n * the full EmDash runtime to be initialized.\n */\n\nimport type { MediaProvider, MediaProviderCapabilities } from \"./types.js\";\n\n/**\n * Media provider entry from virtual module\n */\ninterface MediaProviderEntry {\n\tid: string;\n\tname: string;\n\ticon?: string;\n\tcapabilities: MediaProviderCapabilities;\n\tcreateProvider: (ctx: Record<string, unknown>) => MediaProvider;\n}\n\n// Cached provider entries from virtual module\nlet virtualMediaProviders: MediaProviderEntry[] | undefined;\n\n// Cached provider instances (shared across calls)\nconst mediaProviderInstances = new Map<string, MediaProvider>();\n\n/**\n * Load media providers from virtual module\n */\nasync function loadMediaProviders(): Promise<void> {\n\tif (virtualMediaProviders === undefined) {\n\t\t// eslint-disable-next-line @typescript-eslint/ban-ts-comment\n\t\t// @ts-ignore - virtual module\n\t\tconst providersModule = await import(\"virtual:emdash/media-providers\");\n\t\tvirtualMediaProviders = providersModule.mediaProviders || [];\n\t}\n}\n\n/**\n * Get a media provider by ID.\n *\n * Used by EmDashMedia component for frontend rendering.\n * Providers are lazy-loaded from virtual module and cached.\n *\n * @example\n * ```ts\n * const provider = await getMediaProvider(\"cloudflare-images\");\n * if (provider) {\n * const embed = provider.getEmbed(mediaValue, { width: 800 });\n * }\n * ```\n */\nexport async function getMediaProvider(providerId: string): Promise<MediaProvider | undefined> {\n\t// Check cache first\n\tconst cached = mediaProviderInstances.get(providerId);\n\tif (cached) {\n\t\treturn cached;\n\t}\n\n\t// Load media providers from virtual module\n\tawait loadMediaProviders();\n\n\t// Find the provider entry\n\tconst entry = virtualMediaProviders?.find((p) => p.id === providerId);\n\tif (!entry) {\n\t\treturn undefined;\n\t}\n\n\t// Create the provider instance\n\t// For providers that don't need db/storage (like Cloudflare Images),\n\t// they'll get empty context and use env vars directly\n\tconst provider = entry.createProvider({});\n\tmediaProviderInstances.set(providerId, provider);\n\treturn provider;\n}\n"],"mappings":"
|
|
1
|
+
{"version":3,"file":"runtime.mjs","names":[],"sources":["../src/media/provider-loader.ts"],"sourcesContent":["/**\n * Media Provider Loader\n *\n * Lazy-loads media providers from virtual module for frontend rendering.\n * Similar pattern to getDb() - providers are loaded on first use and cached.\n *\n * This allows EmDashMedia component to render media without requiring\n * the full EmDash runtime to be initialized.\n */\n\nimport type { MediaProvider, MediaProviderCapabilities } from \"./types.js\";\n\n/**\n * Media provider entry from virtual module\n */\ninterface MediaProviderEntry {\n\tid: string;\n\tname: string;\n\ticon?: string;\n\tcapabilities: MediaProviderCapabilities;\n\tcreateProvider: (ctx: Record<string, unknown>) => MediaProvider;\n}\n\n// Cached provider entries from virtual module\nlet virtualMediaProviders: MediaProviderEntry[] | undefined;\n\n// Cached provider instances (shared across calls)\nconst mediaProviderInstances = new Map<string, MediaProvider>();\n\n/**\n * Load media providers from virtual module\n */\nasync function loadMediaProviders(): Promise<void> {\n\tif (virtualMediaProviders === undefined) {\n\t\t// eslint-disable-next-line @typescript-eslint/ban-ts-comment\n\t\t// @ts-ignore - virtual module\n\t\tconst providersModule = await import(\"virtual:emdash/media-providers\");\n\t\tvirtualMediaProviders = providersModule.mediaProviders || [];\n\t}\n}\n\n/**\n * Get a media provider by ID.\n *\n * Used by EmDashMedia component for frontend rendering.\n * Providers are lazy-loaded from virtual module and cached.\n *\n * @example\n * ```ts\n * const provider = await getMediaProvider(\"cloudflare-images\");\n * if (provider) {\n * const embed = provider.getEmbed(mediaValue, { width: 800 });\n * }\n * ```\n */\nexport async function getMediaProvider(providerId: string): Promise<MediaProvider | undefined> {\n\t// Check cache first\n\tconst cached = mediaProviderInstances.get(providerId);\n\tif (cached) {\n\t\treturn cached;\n\t}\n\n\t// Load media providers from virtual module\n\tawait loadMediaProviders();\n\n\t// Find the provider entry\n\tconst entry = virtualMediaProviders?.find((p) => p.id === providerId);\n\tif (!entry) {\n\t\treturn undefined;\n\t}\n\n\t// Create the provider instance\n\t// For providers that don't need db/storage (like Cloudflare Images),\n\t// they'll get empty context and use env vars directly\n\tconst provider = entry.createProvider({});\n\tmediaProviderInstances.set(providerId, provider);\n\treturn provider;\n}\n"],"mappings":";;;;;;;;;;;AAwBA,IAAI;AAGJ,MAAM,yCAAyB,IAAI,KAA4B;;;;AAK/D,eAAe,qBAAoC;AAClD,KAAI,0BAA0B,OAI7B,0BADwB,MAAM,OAAO,mCACG,kBAAkB,EAAE;;;;;;;;;;;;;;;;AAkB9D,eAAsB,iBAAiB,YAAwD;CAE9F,MAAM,SAAS,uBAAuB,IAAI,WAAW;AACrD,KAAI,OACH,QAAO;AAIR,OAAM,oBAAoB;CAG1B,MAAM,QAAQ,uBAAuB,MAAM,MAAM,EAAE,OAAO,WAAW;AACrE,KAAI,CAAC,MACJ;CAMD,MAAM,WAAW,MAAM,eAAe,EAAE,CAAC;AACzC,wBAAuB,IAAI,YAAY,SAAS;AAChD,QAAO"}
|
|
@@ -1,56 +1,57 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import "../dialect-helpers-
|
|
3
|
-
import "../config-
|
|
1
|
+
import { l as runMigrations } from "../runner-Bkkfk4O8.mjs";
|
|
2
|
+
import "../dialect-helpers-B1XN2HGB.mjs";
|
|
3
|
+
import "../config-Cs_AwWXI.mjs";
|
|
4
4
|
import "../datetime-normalization-PeiEdcRY.mjs";
|
|
5
|
-
import "../after-
|
|
5
|
+
import "../after-32yNRvd2.mjs";
|
|
6
6
|
import "../options-DhrI7eMv.mjs";
|
|
7
|
-
import "../secrets-
|
|
7
|
+
import "../secrets-Dswzrz3k.mjs";
|
|
8
8
|
import "../base64-BQBZwXCx.mjs";
|
|
9
|
-
import "../content-
|
|
10
|
-
import "../
|
|
11
|
-
import "../
|
|
12
|
-
import "../
|
|
13
|
-
import "../
|
|
14
|
-
import "../
|
|
15
|
-
import "../
|
|
16
|
-
import "../
|
|
17
|
-
import "../
|
|
18
|
-
import "../
|
|
19
|
-
import "../
|
|
20
|
-
import "../
|
|
21
|
-
import "../
|
|
22
|
-
import "../byline-
|
|
23
|
-
import "../staged-
|
|
24
|
-
import "../dist-
|
|
25
|
-
import "../
|
|
26
|
-
import "../
|
|
27
|
-
import "../
|
|
28
|
-
import "../
|
|
29
|
-
import "../
|
|
30
|
-
import "../
|
|
31
|
-
import "../
|
|
32
|
-
import "../
|
|
9
|
+
import "../content-BKHUVsE5.mjs";
|
|
10
|
+
import "../query-BFHjCzSh.mjs";
|
|
11
|
+
import "../object-cache-DmKr09La.mjs";
|
|
12
|
+
import "../slugify-BDEG9pLk.mjs";
|
|
13
|
+
import "../request-cache-5z2WzWmh.mjs";
|
|
14
|
+
import "../url-DTfGDJhI.mjs";
|
|
15
|
+
import "../types-DwhEvIVb.mjs";
|
|
16
|
+
import "../revision-Dx7Uth1X.mjs";
|
|
17
|
+
import "../media-DepNLhPq.mjs";
|
|
18
|
+
import "../taxonomy-CMI5fczd.mjs";
|
|
19
|
+
import "../resolve-DdNXBJSr.mjs";
|
|
20
|
+
import "../redirect-DjLdw427.mjs";
|
|
21
|
+
import "../byline-registry-BhzpO41z.mjs";
|
|
22
|
+
import "../byline-DHJS-GGb.mjs";
|
|
23
|
+
import "../staged-ByBmPFtX.mjs";
|
|
24
|
+
import "../dist-BUmWMTbN.mjs";
|
|
25
|
+
import "../version-DqB7LIO7.mjs";
|
|
26
|
+
import "../fts-manager-6861qcwk.mjs";
|
|
27
|
+
import "../loader-DhnedqY4.mjs";
|
|
28
|
+
import "../json-recordset-D0WhN2UA.mjs";
|
|
29
|
+
import "../collection-slugs-cache-DIrLjqH-.mjs";
|
|
30
|
+
import "../media-usage-work-BCK2J-v_.mjs";
|
|
31
|
+
import "../capture-triggers-BezAvWcB.mjs";
|
|
32
|
+
import "../activation-CGlyigmg.mjs";
|
|
33
|
+
import "../registry-B0-O575m.mjs";
|
|
33
34
|
import "../hash-BJaeek87.mjs";
|
|
34
|
-
import "../zod-generator
|
|
35
|
+
import "../zod-generator--nlM0930.mjs";
|
|
35
36
|
import "../errors-B4f4It-2.mjs";
|
|
36
37
|
import "../canonical-BudtH-Fx.mjs";
|
|
37
38
|
import "../digest-DJ1tHCgy.mjs";
|
|
38
|
-
import "../block-values-
|
|
39
|
-
import "../query-
|
|
40
|
-
import "../schema-
|
|
41
|
-
import "../relations-
|
|
42
|
-
import "../errors-
|
|
43
|
-
import "../schema-
|
|
44
|
-
import "../settings-
|
|
45
|
-
import "../error-
|
|
46
|
-
import "../fence-
|
|
39
|
+
import "../block-values-Dg0-8PPS.mjs";
|
|
40
|
+
import "../query-LmPY2y0C.mjs";
|
|
41
|
+
import "../schema-BqBlUZtb.mjs";
|
|
42
|
+
import "../relations-WIOojTL4.mjs";
|
|
43
|
+
import "../errors-8gJqv-XV.mjs";
|
|
44
|
+
import "../schema-B-3rntlX.mjs";
|
|
45
|
+
import "../settings-D932YP2-.mjs";
|
|
46
|
+
import "../error-BCMgPxdn.mjs";
|
|
47
|
+
import "../fence-Dagicj14.mjs";
|
|
47
48
|
import "../ssrf-BcYjyM4M.mjs";
|
|
48
|
-
import { t as applySeed } from "../apply-
|
|
49
|
+
import { t as applySeed } from "../apply-DVnupNeS.mjs";
|
|
49
50
|
import "../ssrf-DM0E-D_8.mjs";
|
|
50
|
-
import { n as validateSeed } from "../validate-
|
|
51
|
+
import { n as validateSeed } from "../validate-Dz-TIOFB.mjs";
|
|
51
52
|
import { Y as generateSeedModule } from "../virtual-modules-DO954n7P.mjs";
|
|
52
53
|
import { t as createDatabase } from "../connection-BtEN_lP9.mjs";
|
|
53
|
-
import { n as generateEnvTypes } from "../env-types-
|
|
54
|
+
import { n as generateEnvTypes } from "../env-types-BE3bCvfP.mjs";
|
|
54
55
|
|
|
55
56
|
//#region src/schema/project-env-types.ts
|
|
56
57
|
/**
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"project-env-types.mjs","names":[],"sources":["../../src/schema/project-env-types.ts"],"sourcesContent":["/**\n * Offline `emdash-env.d.ts` generation for a project directory.\n *\n * Reproduces what a fresh `astro dev` run writes: migrate an empty database,\n * apply the project's seed, and generate types from the resulting schema.\n * Used by `scripts/env-types.mjs` to keep committed files in the repo current.\n */\n\nimport { generateSeedModule } from \"../astro/integration/virtual-modules.js\";\nimport { createDatabase } from \"../database/connection.js\";\nimport { runMigrations } from \"../database/migrations/runner.js\";\nimport { applySeed } from \"../seed/apply.js\";\nimport type { SeedFile } from \"../seed/types.js\";\nimport { validateSeed } from \"../seed/validate.js\";\nimport { generateEnvTypes } from \"./env-types.js\";\n\nasync function loadProjectSeed(projectRoot: string): Promise<SeedFile> {\n\tconst source = generateSeedModule(projectRoot);\n\tconst mod: { seed: SeedFile } = await import(\n\t\t/* @vite-ignore */ `data:text/javascript,${encodeURIComponent(source)}`\n\t);\n\treturn mod.seed;\n}\n\nexport async function generateProjectEnvTypes(projectRoot: string): Promise<string> {\n\tconst seed = await loadProjectSeed(projectRoot);\n\tconst { errors } = validateSeed(seed);\n\tif (errors.length > 0) {\n\t\tthrow new Error(`Invalid seed in ${projectRoot}:\\n ${errors.join(\"\\n \")}`);\n\t}\n\n\tconst db = createDatabase({ url: \":memory:\" });\n\ttry {\n\t\tawait runMigrations(db);\n\t\tawait applySeed(db, seed, { includeContent: false, onConflict: \"skip\" });\n\t\tconst { types } = await generateEnvTypes(db);\n\t\treturn types;\n\t} finally {\n\t\tawait db.destroy();\n\t}\n}\n"],"mappings":"
|
|
1
|
+
{"version":3,"file":"project-env-types.mjs","names":[],"sources":["../../src/schema/project-env-types.ts"],"sourcesContent":["/**\n * Offline `emdash-env.d.ts` generation for a project directory.\n *\n * Reproduces what a fresh `astro dev` run writes: migrate an empty database,\n * apply the project's seed, and generate types from the resulting schema.\n * Used by `scripts/env-types.mjs` to keep committed files in the repo current.\n */\n\nimport { generateSeedModule } from \"../astro/integration/virtual-modules.js\";\nimport { createDatabase } from \"../database/connection.js\";\nimport { runMigrations } from \"../database/migrations/runner.js\";\nimport { applySeed } from \"../seed/apply.js\";\nimport type { SeedFile } from \"../seed/types.js\";\nimport { validateSeed } from \"../seed/validate.js\";\nimport { generateEnvTypes } from \"./env-types.js\";\n\nasync function loadProjectSeed(projectRoot: string): Promise<SeedFile> {\n\tconst source = generateSeedModule(projectRoot);\n\tconst mod: { seed: SeedFile } = await import(\n\t\t/* @vite-ignore */ `data:text/javascript,${encodeURIComponent(source)}`\n\t);\n\treturn mod.seed;\n}\n\nexport async function generateProjectEnvTypes(projectRoot: string): Promise<string> {\n\tconst seed = await loadProjectSeed(projectRoot);\n\tconst { errors } = validateSeed(seed);\n\tif (errors.length > 0) {\n\t\tthrow new Error(`Invalid seed in ${projectRoot}:\\n ${errors.join(\"\\n \")}`);\n\t}\n\n\tconst db = createDatabase({ url: \":memory:\" });\n\ttry {\n\t\tawait runMigrations(db);\n\t\tawait applySeed(db, seed, { includeContent: false, onConflict: \"skip\" });\n\t\tconst { types } = await generateEnvTypes(db);\n\t\treturn types;\n\t} finally {\n\t\tawait db.destroy();\n\t}\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAgBA,eAAe,gBAAgB,aAAwC;CACtE,MAAM,SAAS,mBAAmB,YAAY;AAI9C,SAHgC,MAAM;;EAClB,wBAAwB,mBAAmB,OAAO;GAE3D;;AAGZ,eAAsB,wBAAwB,aAAsC;CACnF,MAAM,OAAO,MAAM,gBAAgB,YAAY;CAC/C,MAAM,EAAE,WAAW,aAAa,KAAK;AACrC,KAAI,OAAO,SAAS,EACnB,OAAM,IAAI,MAAM,mBAAmB,YAAY,OAAO,OAAO,KAAK,OAAO,GAAG;CAG7E,MAAM,KAAK,eAAe,EAAE,KAAK,YAAY,CAAC;AAC9C,KAAI;AACH,QAAM,cAAc,GAAG;AACvB,QAAM,UAAU,IAAI,MAAM;GAAE,gBAAgB;GAAO,YAAY;GAAQ,CAAC;EACxE,MAAM,EAAE,UAAU,MAAM,iBAAiB,GAAG;AAC5C,SAAO;WACE;AACT,QAAM,GAAG,SAAS"}
|
|
@@ -1,14 +1,14 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { f as __exportAll } from "./runner-Bkkfk4O8.mjs";
|
|
2
2
|
import { t as validateIdentifier } from "./validate-DANX1-Qi.mjs";
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
5
|
-
import { n as chunks, t as SQL_BATCH_SIZE } from "./chunks-
|
|
6
|
-
import { t as withTransaction } from "./transaction-
|
|
7
|
-
import { d as RelationRepository, u as REFERENCE_INSERT_BATCH_SIZE } from "./staged-
|
|
8
|
-
import { n as SchemaRegistry, t as SchemaError } from "./registry-
|
|
9
|
-
import { s as invalidateSchemaCache } from "./zod-generator
|
|
10
|
-
import { n as expandCollectionBlockFields } from "./block-values-
|
|
11
|
-
import { o as handleRelationDelete, t as fieldsBoundToRelation } from "./relations-
|
|
3
|
+
import { b as tableExists, o as currentTimestampValue } from "./dialect-helpers-B1XN2HGB.mjs";
|
|
4
|
+
import { m as invalidateSchemaObjectCache, u as invalidateCollectionCache } from "./object-cache-DmKr09La.mjs";
|
|
5
|
+
import { n as chunks, t as SQL_BATCH_SIZE } from "./chunks-DiW8VMwz.mjs";
|
|
6
|
+
import { t as withTransaction } from "./transaction-CkoQ5wqQ.mjs";
|
|
7
|
+
import { d as RelationRepository, u as REFERENCE_INSERT_BATCH_SIZE } from "./staged-ByBmPFtX.mjs";
|
|
8
|
+
import { n as SchemaRegistry, t as SchemaError } from "./registry-B0-O575m.mjs";
|
|
9
|
+
import { s as invalidateSchemaCache } from "./zod-generator--nlM0930.mjs";
|
|
10
|
+
import { n as expandCollectionBlockFields } from "./block-values-Dg0-8PPS.mjs";
|
|
11
|
+
import { o as handleRelationDelete, t as fieldsBoundToRelation } from "./relations-WIOojTL4.mjs";
|
|
12
12
|
import { sql } from "kysely";
|
|
13
13
|
import { ulid } from "ulidx";
|
|
14
14
|
|
|
@@ -812,4 +812,4 @@ async function handleOrphanedTableRegister(db, slug, options) {
|
|
|
812
812
|
|
|
813
813
|
//#endregion
|
|
814
814
|
export { schema_exports as _, handleSchemaCollectionCreate as a, handleSchemaCollectionList as c, handleSchemaFieldCreate as d, handleSchemaFieldDelete as f, handleSchemaFieldUpdate as g, handleSchemaFieldReorder as h, handleOrphanedTableRegister as i, handleSchemaCollectionReorder as l, handleSchemaFieldList as m, createFieldRelation as n, handleSchemaCollectionDelete as o, handleSchemaFieldGet as p, handleOrphanedTableList as r, handleSchemaCollectionGet as s, bindReferenceField as t, handleSchemaCollectionUpdate as u };
|
|
815
|
-
//# sourceMappingURL=schema-
|
|
815
|
+
//# sourceMappingURL=schema-B-3rntlX.mjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"schema-DJRfvM_o.mjs","names":[],"sources":["../src/database/reference-backfill.ts","../src/api/handlers/schema.ts"],"sourcesContent":["import type { Kysely } from \"kysely\";\nimport { sql } from \"kysely\";\nimport { ulid } from \"ulidx\";\n\nimport { chunks, SQL_BATCH_SIZE } from \"../utils/chunks.js\";\nimport { currentTimestampValue, tableExists } from \"./dialect-helpers.js\";\nimport { REFERENCE_INSERT_BATCH_SIZE } from \"./repositories/relation.js\";\nimport { validateIdentifier } from \"./validate.js\";\n\n/** What to copy, and which relation to copy it into. */\nexport interface ReferenceBackfill {\n\t/** Collection owning the field, the relation's parent end. */\n\tparentCollection: string;\n\t/** The relation's child end, where the column's ids resolve. */\n\tchildCollection: string;\n\tfieldSlug: string;\n\trelationId: string;\n\t/** The relation's limit for this side. `null` is unlimited. */\n\tmaxChildren: number | null;\n}\n\n/** The ids one column value holds. */\nfunction parseColumnIds(value: unknown): string[] {\n\tif (typeof value !== \"string\" || value.length === 0) return [];\n\tif (!value.startsWith(\"[\")) return [value];\n\tlet parsed: unknown;\n\ttry {\n\t\tparsed = JSON.parse(value);\n\t} catch {\n\t\treturn [value];\n\t}\n\tif (!Array.isArray(parsed)) return [];\n\treturn parsed.filter((entry): entry is string => typeof entry === \"string\" && entry.length > 0);\n}\n\n/**\n * Copy a reference field's column values in as relation edges.\n *\n * A reference field created before relations existed holds its selection in a\n * TEXT column: one entry id, or a JSON array of them for a multiple-reference\n * field (`serializeValue` stringifies the array). Binding the field to a relation\n * moves that selection into `_emdash_content_references`, and this is the copy.\n *\n * The column is not touched. On a site that predates pickers it was a free-text\n * box, so it can hold anything an editor typed, and only the ids that resolve to\n * an entry become edges — clearing it would destroy the rest. Nothing writes to\n * it once the field is bound and typegen stops declaring the key, but a content\n * read still reports the frozen value in `data` beside the live `references`.\n *\n * Both ends of an edge are translation groups, so the locale siblings of one\n * entry contribute to the same parent group. They are read in a fixed order and\n * their ids deduped, and the result is capped at the relation's limit — a\n * single-reference field whose locale rows point at different entries keeps the\n * first rather than storing a selection the relation forbids.\n *\n * Every insert is `ON CONFLICT DO NOTHING` against the edge table's unique\n * constraint, so running this twice adds nothing the first run already wrote.\n *\n * Migration 077 carries its own copy of this for the upgrade path. A migration\n * must not share a module with the handler layer — the bundler then puts the two\n * in chunks that cycle through the migration runner, and the built package throws\n * on import — and a shipped migration has to keep behaving the way it did anyway.\n */\n// eslint-disable-next-line @typescript-eslint/no-explicit-any -- runs against a migration's untyped Kysely as well as the app's\nexport async function backfillReferenceEdges(\n\tdb: Kysely<any>,\n\tbackfill: ReferenceBackfill,\n): Promise<void> {\n\tconst parentTable = `ec_${backfill.parentCollection}`;\n\tconst childTable = `ec_${backfill.childCollection}`;\n\tvalidateIdentifier(parentTable, \"content table name\");\n\tvalidateIdentifier(childTable, \"content table name\");\n\tvalidateIdentifier(backfill.fieldSlug, \"content field name\");\n\n\tif (!(await tableExists(db, parentTable)) || !(await tableExists(db, childTable))) return;\n\n\tconst entries = await sql<{ translation_group: string | null; value: unknown }>`\n\t\tSELECT translation_group, ${sql.ref(backfill.fieldSlug)} AS value\n\t\tFROM ${sql.ref(parentTable)}\n\t\tWHERE ${sql.ref(backfill.fieldSlug)} IS NOT NULL\n\t\tORDER BY locale, id\n\t`.execute(db);\n\n\t// Parent group -> the child entry ids it selects, in order, deduped.\n\tconst selections = new Map<string, string[]>();\n\tfor (const entry of entries.rows) {\n\t\tif (!entry.translation_group) continue;\n\t\tconst existing = selections.get(entry.translation_group) ?? [];\n\t\tfor (const id of parseColumnIds(entry.value)) {\n\t\t\tif (!existing.includes(id)) existing.push(id);\n\t\t}\n\t\tselections.set(entry.translation_group, existing);\n\t}\n\tif (selections.size === 0) return;\n\n\tconst childIds = [...new Set([...selections.values()].flat())];\n\tconst childGroups = new Map<string, string>();\n\tfor (const batch of chunks(childIds, SQL_BATCH_SIZE)) {\n\t\t// oxlint-disable-next-line no-await-in-loop -- one statement per bind-parameter batch\n\t\tconst resolved = await sql<{ id: string; translation_group: string | null }>`\n\t\t\tSELECT id, translation_group\n\t\t\tFROM ${sql.ref(childTable)}\n\t\t\tWHERE id IN (${sql.join(batch)})\n\t\t`.execute(db);\n\t\tfor (const row of resolved.rows) {\n\t\t\tif (row.translation_group) childGroups.set(row.id, row.translation_group);\n\t\t}\n\t}\n\n\tconst now = currentTimestampValue(db);\n\tconst rows: Array<{ parentGroup: string; childGroup: string; sortOrder: number }> = [];\n\tfor (const parentGroup of [...selections.keys()].toSorted()) {\n\t\tconst groups: string[] = [];\n\t\tfor (const id of selections.get(parentGroup) ?? []) {\n\t\t\tconst group = childGroups.get(id);\n\t\t\t// An id whose entry is gone is dropped; its value stays in the column.\n\t\t\tif (group && !groups.includes(group)) groups.push(group);\n\t\t}\n\t\tconst selected = backfill.maxChildren === null ? groups : groups.slice(0, backfill.maxChildren);\n\t\tfor (const [sortOrder, childGroup] of selected.entries()) {\n\t\t\trows.push({ parentGroup, childGroup, sortOrder });\n\t\t}\n\t}\n\n\t// This runs inside the transaction that binds the field, so an editor binding\n\t// a field on a large legacy collection waits for it: batch rather than paying\n\t// a round trip per edge.\n\tfor (const batch of chunks(rows, REFERENCE_INSERT_BATCH_SIZE)) {\n\t\tconst values = batch.map(\n\t\t\t(row) =>\n\t\t\t\tsql`(${ulid()}, ${backfill.relationId}, ${row.parentGroup}, ${row.childGroup}, ${row.sortOrder}, ${now})`,\n\t\t);\n\t\t// oxlint-disable-next-line no-await-in-loop -- one statement per bind-parameter batch\n\t\tawait sql`\n\t\t\tINSERT INTO ${sql.ref(\"_emdash_content_references\")}\n\t\t\t\t(id, relation_id, parent_group, child_group, sort_order, created_at)\n\t\t\tVALUES ${sql.join(values)}\n\t\t\tON CONFLICT DO NOTHING\n\t\t`.execute(db);\n\t}\n}\n","/**\n * Schema/collection management handlers\n */\n\nimport type { Kysely } from \"kysely\";\n\nimport { backfillReferenceEdges } from \"../../database/reference-backfill.js\";\nimport { RelationRepository, type Relation } from \"../../database/repositories/relation.js\";\nimport { withTransaction } from \"../../database/transaction.js\";\nimport type { Database } from \"../../database/types.js\";\nimport {\n\tinvalidateCollectionCache,\n\tinvalidateSchemaObjectCache,\n} from \"../../object-cache/index.js\";\nimport {\n\tSchemaRegistry,\n\tSchemaError,\n\tinvalidateSchemaCache,\n\ttype Collection,\n\ttype Field,\n\ttype CreateCollectionInput,\n\ttype UpdateCollectionInput,\n\ttype CreateFieldInput,\n\ttype UpdateFieldInput,\n\ttype CollectionWithFields,\n\texpandCollectionBlockFields,\n} from \"../../schema/index.js\";\nimport type { ApiResult } from \"../types.js\";\nimport { fieldsBoundToRelation, handleRelationDelete } from \"./relations.js\";\n\n/** Maximum attempts to allocate a unique relation slug for a new reference\n * field: the base `${collection}_${field}` slug, then `_2` through `_5`. */\nconst RELATION_NAME_MAX_ATTEMPTS = 5;\n\n/** True for SQLite UNIQUE / Postgres unique_violation messages — mirrors the\n * fingerprint used in the relations API handler. */\nfunction isUniqueViolation(error: unknown): boolean {\n\tconst message = error instanceof Error ? error.message.toLowerCase() : \"\";\n\treturn message.includes(\"unique constraint failed\") || message.includes(\"duplicate key\");\n}\n\n/**\n * Create the relation definition backing a new reference field, retrying\n * with a numeric suffix on a name collision. Runs inside the caller's\n * transaction so the relation and the field row it backs commit or roll\n * back together.\n */\nexport async function createFieldRelation(\n\ttrx: Kysely<Database>,\n\tcollectionSlug: string,\n\tfieldSlug: string,\n\tfieldLabel: string,\n\ttargetCollection: string,\n\t/** How many entries the new field may hold. `null` is unlimited. */\n\tmaxChildrenPerParent: number | null = null,\n): Promise<Relation> {\n\tconst registry = new SchemaRegistry(trx);\n\tconst relations = new RelationRepository(trx);\n\n\tconst parent = await registry.getCollection(collectionSlug);\n\tif (!parent) {\n\t\tthrow new SchemaError(`Collection \"${collectionSlug}\" not found`, \"COLLECTION_NOT_FOUND\");\n\t}\n\n\tif (!(await registry.getCollection(targetCollection))) {\n\t\tthrow new SchemaError(\n\t\t\t`Target collection \"${targetCollection}\" not found`,\n\t\t\t\"COLLECTION_NOT_FOUND\",\n\t\t);\n\t}\n\n\tconst baseSlug = `${collectionSlug}_${fieldSlug}`.slice(0, 63);\n\tfor (let attempt = 0; attempt < RELATION_NAME_MAX_ATTEMPTS; attempt++) {\n\t\tconst suffix = attempt === 0 ? \"\" : `_${attempt + 1}`;\n\t\tconst slug = attempt === 0 ? baseSlug : `${baseSlug.slice(0, 63 - suffix.length)}${suffix}`;\n\t\ttry {\n\t\t\treturn await relations.create({\n\t\t\t\tslug,\n\t\t\t\tparentCollection: collectionSlug,\n\t\t\t\tchildCollection: targetCollection,\n\t\t\t\tparentLabel: parent.label,\n\t\t\t\tparentLabelSingular: parent.labelSingular ?? null,\n\t\t\t\tchildLabel: fieldLabel,\n\t\t\t\tmaxChildrenPerParent,\n\t\t\t});\n\t\t} catch (error) {\n\t\t\tconst isLastAttempt = attempt === RELATION_NAME_MAX_ATTEMPTS - 1;\n\t\t\tif (isLastAttempt || !isUniqueViolation(error)) throw error;\n\t\t}\n\t}\n\tthrow new SchemaError(\"Could not allocate a unique relation name\", \"RELATION_NAME_CONFLICT\");\n}\n\n/**\n * Every cache a field change can stale.\n *\n * The schema object-cache namespace is bumped here rather than only by the\n * collection routes: the render path's reference field map lives in that\n * namespace, so a field created, bound, relabelled or deleted would otherwise\n * keep resolving against the shape the collection used to have.\n */\nfunction invalidateFieldCaches(collectionSlug: string): void {\n\tinvalidateCollectionCache(collectionSlug);\n\tinvalidateSchemaCache(collectionSlug);\n\tinvalidateSchemaObjectCache();\n}\n\n/**\n * Bind a reference field that has no relation to one, and copy the selection its\n * column holds in as edges.\n *\n * The column is left in place but stops being written, so the field also stops\n * being `indexed` and `searchable`: an index over a frozen column would answer\n * content-list filters and searches from values that no longer change. Clearing\n * both here drops the field index and re-syncs FTS through `updateField`.\n */\nexport async function bindReferenceField(\n\tdb: Kysely<Database>,\n\tcollectionSlug: string,\n\texisting: Field,\n\tinput: UpdateFieldInput,\n\ttargetCollection: string,\n): Promise<Field> {\n\tconst label = input.label ?? existing.label;\n\tconst maxChildren = input.validation?.multiple ? null : 1;\n\n\treturn withTransaction(db, async (trx) => {\n\t\tconst relation = await createFieldRelation(\n\t\t\ttrx,\n\t\t\tcollectionSlug,\n\t\t\texisting.slug,\n\t\t\tlabel,\n\t\t\ttargetCollection,\n\t\t\tmaxChildren,\n\t\t);\n\t\tconst registry = new SchemaRegistry(trx);\n\t\tconst updated = await registry.updateField(collectionSlug, existing.slug, {\n\t\t\t...input,\n\t\t\tindexed: false,\n\t\t\tsearchable: false,\n\t\t\tvalidation: {\n\t\t\t\t...input.validation,\n\t\t\t\trelation: relation.slug,\n\t\t\t\trelationSide: \"parent\",\n\t\t\t\ttargetCollection,\n\t\t\t},\n\t\t});\n\n\t\tawait backfillReferenceEdges(trx, {\n\t\t\tparentCollection: collectionSlug,\n\t\t\tchildCollection: targetCollection,\n\t\t\tfieldSlug: existing.slug,\n\t\t\trelationId: relation.id,\n\t\t\tmaxChildren,\n\t\t});\n\n\t\treturn updated;\n\t});\n}\n\nexport interface CollectionListResponse {\n\titems: Collection[];\n}\n\nexport interface CollectionResponse {\n\titem: Collection;\n}\n\nexport interface CollectionWithFieldsResponse {\n\titem: CollectionWithFields;\n}\n\nexport interface FieldListResponse {\n\titems: Field[];\n}\n\nexport interface FieldResponse {\n\titem: Field;\n}\n\n/**\n * List all collections\n */\nexport async function handleSchemaCollectionList(\n\tdb: Kysely<Database>,\n): Promise<ApiResult<CollectionListResponse>> {\n\ttry {\n\t\tconst registry = new SchemaRegistry(db);\n\t\tconst items = await registry.listCollections();\n\n\t\treturn {\n\t\t\tsuccess: true,\n\t\t\tdata: { items },\n\t\t};\n\t} catch {\n\t\treturn {\n\t\t\tsuccess: false,\n\t\t\terror: {\n\t\t\t\tcode: \"SCHEMA_LIST_ERROR\",\n\t\t\t\tmessage: \"Failed to list collections\",\n\t\t\t},\n\t\t};\n\t}\n}\n\n/**\n * Get a collection by slug\n */\nexport async function handleSchemaCollectionGet(\n\tdb: Kysely<Database>,\n\tslug: string,\n\toptions?: { includeFields?: boolean },\n): Promise<ApiResult<CollectionResponse | CollectionWithFieldsResponse>> {\n\ttry {\n\t\tconst registry = new SchemaRegistry(db);\n\n\t\tif (options?.includeFields) {\n\t\t\tconst stored = await registry.getCollectionWithFields(slug);\n\t\t\tconst item = stored ? await expandCollectionBlockFields(db, stored) : null;\n\t\t\tif (!item) {\n\t\t\t\treturn {\n\t\t\t\t\tsuccess: false,\n\t\t\t\t\terror: {\n\t\t\t\t\t\tcode: \"NOT_FOUND\",\n\t\t\t\t\t\tmessage: `Collection not found: ${slug}`,\n\t\t\t\t\t},\n\t\t\t\t};\n\t\t\t}\n\t\t\treturn {\n\t\t\t\tsuccess: true,\n\t\t\t\tdata: { item },\n\t\t\t};\n\t\t}\n\n\t\tconst item = await registry.getCollection(slug);\n\t\tif (!item) {\n\t\t\treturn {\n\t\t\t\tsuccess: false,\n\t\t\t\terror: {\n\t\t\t\t\tcode: \"NOT_FOUND\",\n\t\t\t\t\tmessage: `Collection not found: ${slug}`,\n\t\t\t\t},\n\t\t\t};\n\t\t}\n\n\t\treturn {\n\t\t\tsuccess: true,\n\t\t\tdata: { item },\n\t\t};\n\t} catch (error) {\n\t\tif (error instanceof SchemaError) {\n\t\t\treturn {\n\t\t\t\tsuccess: false,\n\t\t\t\terror: { code: error.code, message: error.message, details: error.details },\n\t\t\t};\n\t\t}\n\t\treturn {\n\t\t\tsuccess: false,\n\t\t\terror: {\n\t\t\t\tcode: \"SCHEMA_GET_ERROR\",\n\t\t\t\tmessage: \"Failed to get collection\",\n\t\t\t},\n\t\t};\n\t}\n}\n\n/**\n * Create a collection\n */\nexport async function handleSchemaCollectionCreate(\n\tdb: Kysely<Database>,\n\tinput: CreateCollectionInput,\n): Promise<ApiResult<CollectionResponse>> {\n\ttry {\n\t\tconst registry = new SchemaRegistry(db);\n\t\tconst item = await registry.createCollection(input);\n\n\t\treturn {\n\t\t\tsuccess: true,\n\t\t\tdata: { item },\n\t\t};\n\t} catch (error) {\n\t\tif (error instanceof SchemaError) {\n\t\t\treturn {\n\t\t\t\tsuccess: false,\n\t\t\t\terror: {\n\t\t\t\t\tcode: error.code,\n\t\t\t\t\tmessage: error.message,\n\t\t\t\t\tdetails: error.details,\n\t\t\t\t},\n\t\t\t};\n\t\t}\n\t\tconsole.error(\"[emdash] Failed to create collection:\", error);\n\t\treturn {\n\t\t\tsuccess: false,\n\t\t\terror: {\n\t\t\t\tcode: \"SCHEMA_CREATE_ERROR\",\n\t\t\t\tmessage: \"Failed to create collection\",\n\t\t\t},\n\t\t};\n\t}\n}\n\n/**\n * Update a collection\n */\nexport async function handleSchemaCollectionUpdate(\n\tdb: Kysely<Database>,\n\tslug: string,\n\tinput: UpdateCollectionInput,\n): Promise<ApiResult<CollectionResponse>> {\n\ttry {\n\t\tconst registry = new SchemaRegistry(db);\n\t\tconst item = await registry.updateCollection(slug, input);\n\n\t\treturn {\n\t\t\tsuccess: true,\n\t\t\tdata: { item },\n\t\t};\n\t} catch (error) {\n\t\tif (error instanceof SchemaError) {\n\t\t\treturn {\n\t\t\t\tsuccess: false,\n\t\t\t\terror: {\n\t\t\t\t\tcode: error.code,\n\t\t\t\t\tmessage: error.message,\n\t\t\t\t\tdetails: error.details,\n\t\t\t\t},\n\t\t\t};\n\t\t}\n\t\treturn {\n\t\t\tsuccess: false,\n\t\t\terror: {\n\t\t\t\tcode: \"SCHEMA_UPDATE_ERROR\",\n\t\t\t\tmessage: \"Failed to update collection\",\n\t\t\t},\n\t\t};\n\t}\n}\n\n/**\n * Delete a collection\n */\nexport async function handleSchemaCollectionDelete(\n\tdb: Kysely<Database>,\n\tslug: string,\n\toptions?: { force?: boolean },\n): Promise<ApiResult<{ success: boolean }>> {\n\ttry {\n\t\tconst registry = new SchemaRegistry(db);\n\n\t\t// Nothing below can be undone on D1, so a delete that will be refused has\n\t\t// to be refused before the first relation goes.\n\t\tawait registry.assertCollectionDeletable(slug, options);\n\n\t\t// A relation with this collection on either end cannot outlive it: its\n\t\t// edges point at content that is about to be dropped, and the reference\n\t\t// fields viewing it — including ones on the *other* collection — would be\n\t\t// left addressing a collection that no longer exists. The admin lists both\n\t\t// before confirming. Relations go first, so an interrupted delete leaves a\n\t\t// collection with fewer relations rather than a dropped table with\n\t\t// relations still pointing at it.\n\t\tconst relations = new RelationRepository(db);\n\t\tfor (const relation of await relations.findForCollection(slug)) {\n\t\t\tconst removed = await handleRelationDelete(db, relation.id);\n\t\t\tif (!removed.success) return removed;\n\t\t}\n\n\t\tawait registry.deleteCollection(slug, options);\n\n\t\treturn {\n\t\t\tsuccess: true,\n\t\t\tdata: { success: true },\n\t\t};\n\t} catch (error) {\n\t\tif (error instanceof SchemaError) {\n\t\t\treturn {\n\t\t\t\tsuccess: false,\n\t\t\t\terror: {\n\t\t\t\t\tcode: error.code,\n\t\t\t\t\tmessage: error.message,\n\t\t\t\t\tdetails: error.details,\n\t\t\t\t},\n\t\t\t};\n\t\t}\n\t\treturn {\n\t\t\tsuccess: false,\n\t\t\terror: {\n\t\t\t\tcode: \"SCHEMA_DELETE_ERROR\",\n\t\t\t\tmessage: \"Failed to delete collection\",\n\t\t\t},\n\t\t};\n\t}\n}\n\n/**\n * List fields for a collection\n */\nexport async function handleSchemaFieldList(\n\tdb: Kysely<Database>,\n\tcollectionSlug: string,\n): Promise<ApiResult<FieldListResponse>> {\n\ttry {\n\t\tconst registry = new SchemaRegistry(db);\n\t\tconst stored = await registry.getCollectionWithFields(collectionSlug);\n\n\t\tif (!stored) {\n\t\t\treturn {\n\t\t\t\tsuccess: false,\n\t\t\t\terror: {\n\t\t\t\t\tcode: \"NOT_FOUND\",\n\t\t\t\t\tmessage: `Collection not found: ${collectionSlug}`,\n\t\t\t\t},\n\t\t\t};\n\t\t}\n\n\t\tconst items = (await expandCollectionBlockFields(db, stored)).fields;\n\n\t\treturn {\n\t\t\tsuccess: true,\n\t\t\tdata: { items },\n\t\t};\n\t} catch (error) {\n\t\tif (error instanceof SchemaError) {\n\t\t\treturn {\n\t\t\t\tsuccess: false,\n\t\t\t\terror: { code: error.code, message: error.message, details: error.details },\n\t\t\t};\n\t\t}\n\t\treturn {\n\t\t\tsuccess: false,\n\t\t\terror: {\n\t\t\t\tcode: \"SCHEMA_FIELD_LIST_ERROR\",\n\t\t\t\tmessage: \"Failed to list fields\",\n\t\t\t},\n\t\t};\n\t}\n}\n\n/**\n * Get a field\n */\nexport async function handleSchemaFieldGet(\n\tdb: Kysely<Database>,\n\tcollectionSlug: string,\n\tfieldSlug: string,\n): Promise<ApiResult<FieldResponse>> {\n\ttry {\n\t\tconst registry = new SchemaRegistry(db);\n\t\tconst collection = await registry.getCollectionWithFields(collectionSlug);\n\t\tconst item = collection\n\t\t\t? (await expandCollectionBlockFields(db, collection)).fields.find(\n\t\t\t\t\t(field) => field.slug === fieldSlug,\n\t\t\t\t)\n\t\t\t: null;\n\n\t\tif (!item) {\n\t\t\treturn {\n\t\t\t\tsuccess: false,\n\t\t\t\terror: {\n\t\t\t\t\tcode: \"NOT_FOUND\",\n\t\t\t\t\tmessage: `Field not found: ${fieldSlug} in collection ${collectionSlug}`,\n\t\t\t\t},\n\t\t\t};\n\t\t}\n\n\t\treturn {\n\t\t\tsuccess: true,\n\t\t\tdata: { item },\n\t\t};\n\t} catch (error) {\n\t\tif (error instanceof SchemaError) {\n\t\t\treturn {\n\t\t\t\tsuccess: false,\n\t\t\t\terror: { code: error.code, message: error.message, details: error.details },\n\t\t\t};\n\t\t}\n\t\treturn {\n\t\t\tsuccess: false,\n\t\t\terror: {\n\t\t\t\tcode: \"SCHEMA_FIELD_GET_ERROR\",\n\t\t\t\tmessage: \"Failed to get field\",\n\t\t\t},\n\t\t};\n\t}\n}\n\n/**\n * Resolve which end of `relation` a field on `collectionSlug` sits on.\n *\n * The side is only a choice when both ends are the same collection — a\n * self-referential relation such as related posts. Anywhere else the matching\n * end decides it, and an explicit side that disagrees is a client error rather\n * than something to silently override.\n */\nfunction resolveBindingSide(\n\trelation: Relation,\n\tcollectionSlug: string,\n\trequested: \"parent\" | \"child\" | undefined,\n): { side: \"parent\" | \"child\"; targetCollection: string } | { error: string } {\n\tconst isParent = relation.parentCollection === collectionSlug;\n\tconst isChild = relation.childCollection === collectionSlug;\n\n\tif (!isParent && !isChild) {\n\t\treturn {\n\t\t\terror: `Relation '${relation.slug}' does not touch collection '${collectionSlug}'`,\n\t\t};\n\t}\n\n\tif (isParent && isChild) {\n\t\tconst side = requested ?? \"parent\";\n\t\treturn {\n\t\t\tside,\n\t\t\ttargetCollection: side === \"parent\" ? relation.childCollection : relation.parentCollection,\n\t\t};\n\t}\n\n\tconst side = isParent ? \"parent\" : \"child\";\n\tif (requested && requested !== side) {\n\t\treturn {\n\t\t\terror: `Collection '${collectionSlug}' is the ${side} of relation '${relation.slug}'`,\n\t\t};\n\t}\n\n\treturn {\n\t\tside,\n\t\ttargetCollection: isParent ? relation.childCollection : relation.parentCollection,\n\t};\n}\n\n/**\n * Create a reference field that views an existing relation.\n *\n * Only one field may view a relation from a given end: two pickers writing the\n * same link set have no defined merge, and the second would silently overwrite\n * the first on every save.\n */\nasync function createBoundReferenceField(\n\tdb: Kysely<Database>,\n\tcollectionSlug: string,\n\tinput: CreateFieldInput,\n\trelationSlug: string,\n): Promise<ApiResult<FieldResponse>> {\n\tconst relation = await new RelationRepository(db).findBySlug(relationSlug);\n\tif (!relation) {\n\t\treturn {\n\t\t\tsuccess: false,\n\t\t\terror: { code: \"NOT_FOUND\", message: `Relation '${relationSlug}' not found` },\n\t\t};\n\t}\n\n\tconst resolved = resolveBindingSide(relation, collectionSlug, input.validation?.relationSide);\n\tif (\"error\" in resolved) {\n\t\treturn { success: false, error: { code: \"VALIDATION_ERROR\", message: resolved.error } };\n\t}\n\n\tconst bound = await fieldsBoundToRelation(db, relation.slug);\n\tconst taken = bound.find((field) => field.side === resolved.side);\n\tif (taken) {\n\t\treturn {\n\t\t\tsuccess: false,\n\t\t\terror: {\n\t\t\t\tcode: \"CONFLICT\",\n\t\t\t\tmessage: `Relation '${relation.slug}' is already picked from by ${taken.collectionSlug}.${taken.fieldSlug}`,\n\t\t\t},\n\t\t};\n\t}\n\n\tconst item = await new SchemaRegistry(db).createField(collectionSlug, {\n\t\t...input,\n\t\tvalidation: {\n\t\t\t...input.validation,\n\t\t\trelation: relation.slug,\n\t\t\trelationSide: resolved.side,\n\t\t\ttargetCollection: resolved.targetCollection,\n\t\t},\n\t});\n\n\tinvalidateFieldCaches(collectionSlug);\n\n\treturn { success: true, data: { item } };\n}\n\n/**\n * Create a field\n */\nexport async function handleSchemaFieldCreate(\n\tdb: Kysely<Database>,\n\tcollectionSlug: string,\n\tinput: CreateFieldInput,\n): Promise<ApiResult<FieldResponse>> {\n\ttry {\n\t\tif (input.type === \"reference\" && input.validation?.relation) {\n\t\t\treturn await createBoundReferenceField(db, collectionSlug, input, input.validation.relation);\n\t\t}\n\n\t\tif (input.type === \"reference\") {\n\t\t\tconst targetCollection = input.validation?.targetCollection;\n\t\t\tif (!targetCollection) {\n\t\t\t\treturn {\n\t\t\t\t\tsuccess: false,\n\t\t\t\t\terror: {\n\t\t\t\t\t\tcode: \"VALIDATION_ERROR\",\n\t\t\t\t\t\tmessage: \"Reference field requires a target collection\",\n\t\t\t\t\t},\n\t\t\t\t};\n\t\t\t}\n\n\t\t\t// The relation def and the field row it backs must commit or roll\n\t\t\t// back together — a field without its relation (or vice versa) is\n\t\t\t// an inconsistent reference field.\n\t\t\tconst item = await withTransaction(db, async (trx) => {\n\t\t\t\t// A single-reference field is a one-to-many relation: the limit is the\n\t\t\t\t// relation's, so binding its other end later sees the same rule.\n\t\t\t\tconst relation = await createFieldRelation(\n\t\t\t\t\ttrx,\n\t\t\t\t\tcollectionSlug,\n\t\t\t\t\tinput.slug,\n\t\t\t\t\tinput.label,\n\t\t\t\t\ttargetCollection,\n\t\t\t\t\tinput.validation?.multiple ? null : 1,\n\t\t\t\t);\n\t\t\t\tconst registry = new SchemaRegistry(trx);\n\t\t\t\treturn registry.createField(collectionSlug, {\n\t\t\t\t\t...input,\n\t\t\t\t\tvalidation: {\n\t\t\t\t\t\t...input.validation,\n\t\t\t\t\t\trelation: relation.slug,\n\t\t\t\t\t\trelationSide: \"parent\" as const,\n\t\t\t\t\t\ttargetCollection,\n\t\t\t\t\t},\n\t\t\t\t});\n\t\t\t});\n\n\t\t\t// Content snapshots embed field values; a column change invalidates them.\n\t\t\tinvalidateFieldCaches(collectionSlug);\n\n\t\t\treturn {\n\t\t\t\tsuccess: true,\n\t\t\t\tdata: { item },\n\t\t\t};\n\t\t}\n\n\t\tconst registry = new SchemaRegistry(db);\n\t\tconst item = await registry.createField(collectionSlug, input);\n\n\t\t// Content snapshots embed field values; a column change invalidates them.\n\t\tinvalidateFieldCaches(collectionSlug);\n\n\t\treturn {\n\t\t\tsuccess: true,\n\t\t\tdata: { item },\n\t\t};\n\t} catch (error) {\n\t\tif (error instanceof SchemaError) {\n\t\t\treturn {\n\t\t\t\tsuccess: false,\n\t\t\t\terror: {\n\t\t\t\t\tcode: error.code,\n\t\t\t\t\tmessage: error.message,\n\t\t\t\t\tdetails: error.details,\n\t\t\t\t},\n\t\t\t};\n\t\t}\n\t\treturn {\n\t\t\tsuccess: false,\n\t\t\terror: {\n\t\t\t\tcode: \"SCHEMA_FIELD_CREATE_ERROR\",\n\t\t\t\tmessage: \"Failed to create field\",\n\t\t\t},\n\t\t};\n\t}\n}\n\n/**\n * Update a field\n */\nexport async function handleSchemaFieldUpdate(\n\tdb: Kysely<Database>,\n\tcollectionSlug: string,\n\tfieldSlug: string,\n\tinput: UpdateFieldInput,\n): Promise<ApiResult<FieldResponse>> {\n\ttry {\n\t\tconst lookupRegistry = new SchemaRegistry(db);\n\t\tconst existing = await lookupRegistry.getField(collectionSlug, fieldSlug);\n\t\tconst relationSlug = existing?.type === \"reference\" ? existing.validation?.relation : undefined;\n\t\tconst relationSide = existing?.validation?.relationSide;\n\n\t\tif (existing && relationSlug) {\n\t\t\t// The relation's childCollection is immutable — a reference field's\n\t\t\t// target collection can't change after the relation is wired up.\n\t\t\tconst nextTargetCollection = input.validation?.targetCollection;\n\t\t\tif (\n\t\t\t\tnextTargetCollection !== undefined &&\n\t\t\t\tnextTargetCollection !== existing.validation?.targetCollection\n\t\t\t) {\n\t\t\t\treturn {\n\t\t\t\t\tsuccess: false,\n\t\t\t\t\terror: {\n\t\t\t\t\t\tcode: \"VALIDATION_ERROR\",\n\t\t\t\t\t\tmessage: \"Cannot change the target collection of an existing reference field\",\n\t\t\t\t\t},\n\t\t\t\t};\n\t\t\t}\n\n\t\t\t// `relation` and `targetCollection` are immutable identity for a wired\n\t\t\t// reference field. An update that sends `validation: null` or a partial\n\t\t\t// validation object omitting these keys must not be allowed to clear\n\t\t\t// them -- registry.updateField() writes whatever is passed verbatim,\n\t\t\t// which would otherwise orphan the relation row and its edges.\n\t\t\tconst updateInput =\n\t\t\t\tinput.validation !== undefined\n\t\t\t\t\t? {\n\t\t\t\t\t\t\t...input,\n\t\t\t\t\t\t\tvalidation: {\n\t\t\t\t\t\t\t\t...input.validation,\n\t\t\t\t\t\t\t\trelation: existing.validation?.relation,\n\t\t\t\t\t\t\t\trelationSide: existing.validation?.relationSide,\n\t\t\t\t\t\t\t\ttargetCollection: existing.validation?.targetCollection,\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t}\n\t\t\t\t\t: input;\n\n\t\t\tconst item = await withTransaction(db, async (trx) => {\n\t\t\t\tconst registry = new SchemaRegistry(trx);\n\t\t\t\tconst updated = await registry.updateField(collectionSlug, fieldSlug, updateInput);\n\n\t\t\t\tif (input.label !== undefined && input.label !== existing.label) {\n\t\t\t\t\tconst relations = new RelationRepository(trx);\n\t\t\t\t\tconst relation = await relations.findBySlug(relationSlug);\n\t\t\t\t\t// The field's label is the role name for the side it binds, so\n\t\t\t\t\t// renaming the field renames that role and leaves the other alone.\n\t\t\t\t\tif (relation) {\n\t\t\t\t\t\tawait relations.update(\n\t\t\t\t\t\t\trelation.id,\n\t\t\t\t\t\t\trelationSide === \"child\" ? { parentLabel: input.label } : { childLabel: input.label },\n\t\t\t\t\t\t);\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\treturn updated;\n\t\t\t});\n\n\t\t\tinvalidateFieldCaches(collectionSlug);\n\n\t\t\treturn {\n\t\t\t\tsuccess: true,\n\t\t\t\tdata: { item },\n\t\t\t};\n\t\t}\n\n\t\t// Giving an unbound reference field a target collection binds it: a field\n\t\t// created before relations existed, or one whose target could not be\n\t\t// resolved on upgrade, becomes a picker here rather than needing to be\n\t\t// deleted and recreated.\n\t\tconst bindTarget = existing?.type === \"reference\" ? input.validation?.targetCollection : null;\n\t\tif (existing && bindTarget) {\n\t\t\tconst item = await bindReferenceField(db, collectionSlug, existing, input, bindTarget);\n\t\t\tinvalidateFieldCaches(collectionSlug);\n\t\t\treturn { success: true, data: { item } };\n\t\t}\n\n\t\tconst registry = new SchemaRegistry(db);\n\t\tconst item = await registry.updateField(collectionSlug, fieldSlug, input);\n\n\t\tinvalidateFieldCaches(collectionSlug);\n\n\t\treturn {\n\t\t\tsuccess: true,\n\t\t\tdata: { item },\n\t\t};\n\t} catch (error) {\n\t\tif (error instanceof SchemaError) {\n\t\t\treturn {\n\t\t\t\tsuccess: false,\n\t\t\t\terror: {\n\t\t\t\t\tcode: error.code,\n\t\t\t\t\tmessage: error.message,\n\t\t\t\t\tdetails: error.details,\n\t\t\t\t},\n\t\t\t};\n\t\t}\n\t\treturn {\n\t\t\tsuccess: false,\n\t\t\terror: {\n\t\t\t\tcode: \"SCHEMA_FIELD_UPDATE_ERROR\",\n\t\t\t\tmessage: \"Failed to update field\",\n\t\t\t},\n\t\t};\n\t}\n}\n\n/**\n * Delete a field\n */\n/**\n * Delete a field.\n *\n * For a reference field, `deleteRelation` also takes the relation, its edges,\n * and the field bound to its other side. It is opt-in on the wire and checked\n * by default in the admin's confirm dialog, which enumerates what goes first.\n */\nexport async function handleSchemaFieldDelete(\n\tdb: Kysely<Database>,\n\tcollectionSlug: string,\n\tfieldSlug: string,\n\toptions?: { deleteRelation?: boolean },\n): Promise<ApiResult<{ success: boolean }>> {\n\ttry {\n\t\tconst lookupRegistry = new SchemaRegistry(db);\n\t\tconst existing = await lookupRegistry.getField(collectionSlug, fieldSlug);\n\t\tconst relationSlug = existing?.type === \"reference\" ? existing.validation?.relation : undefined;\n\n\t\tif (relationSlug && options?.deleteRelation) {\n\t\t\t// Taking the relation takes its edges and the field bound to its other\n\t\t\t// side, so route through the shared cascade rather than deleting the\n\t\t\t// field here and the relation separately.\n\t\t\tconst relations = new RelationRepository(db);\n\t\t\tconst relation = await relations.findBySlug(relationSlug);\n\t\t\tif (relation) {\n\t\t\t\tconst result = await handleRelationDelete(db, relation.id);\n\t\t\t\tif (!result.success) return result;\n\t\t\t\tinvalidateFieldCaches(collectionSlug);\n\t\t\t\treturn { success: true, data: { success: true } };\n\t\t\t}\n\t\t}\n\n\t\tconst registry = new SchemaRegistry(db);\n\t\tawait registry.deleteField(collectionSlug, fieldSlug);\n\n\t\tinvalidateFieldCaches(collectionSlug);\n\n\t\treturn {\n\t\t\tsuccess: true,\n\t\t\tdata: { success: true },\n\t\t};\n\t} catch (error) {\n\t\tif (error instanceof SchemaError) {\n\t\t\treturn {\n\t\t\t\tsuccess: false,\n\t\t\t\terror: {\n\t\t\t\t\tcode: error.code,\n\t\t\t\t\tmessage: error.message,\n\t\t\t\t\tdetails: error.details,\n\t\t\t\t},\n\t\t\t};\n\t\t}\n\t\treturn {\n\t\t\tsuccess: false,\n\t\t\terror: {\n\t\t\t\tcode: \"SCHEMA_FIELD_DELETE_ERROR\",\n\t\t\t\tmessage: \"Failed to delete field\",\n\t\t\t},\n\t\t};\n\t}\n}\n\n/**\n * Reorder collections in the admin sidebar\n */\nexport async function handleSchemaCollectionReorder(\n\tdb: Kysely<Database>,\n\tslugs: string[],\n): Promise<ApiResult<{ success: boolean }>> {\n\ttry {\n\t\tconst registry = new SchemaRegistry(db);\n\t\tawait registry.reorderCollections(slugs);\n\n\t\treturn {\n\t\t\tsuccess: true,\n\t\t\tdata: { success: true },\n\t\t};\n\t} catch (error) {\n\t\tif (error instanceof SchemaError) {\n\t\t\treturn {\n\t\t\t\tsuccess: false,\n\t\t\t\terror: {\n\t\t\t\t\tcode: error.code,\n\t\t\t\t\tmessage: error.message,\n\t\t\t\t\tdetails: error.details,\n\t\t\t\t},\n\t\t\t};\n\t\t}\n\t\tconsole.error(\"[emdash] Failed to reorder collections:\", error);\n\t\treturn {\n\t\t\tsuccess: false,\n\t\t\terror: {\n\t\t\t\tcode: \"SCHEMA_COLLECTION_REORDER_ERROR\",\n\t\t\t\tmessage: \"Failed to reorder collections\",\n\t\t\t},\n\t\t};\n\t}\n}\n\n/**\n * Reorder fields\n */\nexport async function handleSchemaFieldReorder(\n\tdb: Kysely<Database>,\n\tcollectionSlug: string,\n\tfieldSlugs: string[],\n): Promise<ApiResult<{ success: boolean }>> {\n\ttry {\n\t\tconst registry = new SchemaRegistry(db);\n\t\tawait registry.reorderFields(collectionSlug, fieldSlugs);\n\n\t\treturn {\n\t\t\tsuccess: true,\n\t\t\tdata: { success: true },\n\t\t};\n\t} catch (error) {\n\t\tif (error instanceof SchemaError) {\n\t\t\treturn {\n\t\t\t\tsuccess: false,\n\t\t\t\terror: {\n\t\t\t\t\tcode: error.code,\n\t\t\t\t\tmessage: error.message,\n\t\t\t\t\tdetails: error.details,\n\t\t\t\t},\n\t\t\t};\n\t\t}\n\t\treturn {\n\t\t\tsuccess: false,\n\t\t\terror: {\n\t\t\t\tcode: \"SCHEMA_FIELD_REORDER_ERROR\",\n\t\t\t\tmessage: \"Failed to reorder fields\",\n\t\t\t},\n\t\t};\n\t}\n}\n\n// ============================================\n// Orphaned Table Discovery\n// ============================================\n\nexport interface OrphanedTable {\n\tslug: string;\n\ttableName: string;\n\trowCount: number;\n}\n\nexport interface OrphanedTableListResponse {\n\titems: OrphanedTable[];\n}\n\n/**\n * List orphaned content tables\n */\nexport async function handleOrphanedTableList(\n\tdb: Kysely<Database>,\n): Promise<ApiResult<OrphanedTableListResponse>> {\n\ttry {\n\t\tconst registry = new SchemaRegistry(db);\n\t\tconst items = await registry.discoverOrphanedTables();\n\n\t\treturn {\n\t\t\tsuccess: true,\n\t\t\tdata: { items },\n\t\t};\n\t} catch (error) {\n\t\tconsole.error(\"[emdash] Failed to list orphaned tables:\", error);\n\t\treturn {\n\t\t\tsuccess: false,\n\t\t\terror: {\n\t\t\t\tcode: \"ORPHAN_LIST_ERROR\",\n\t\t\t\tmessage: \"Failed to list orphaned tables\",\n\t\t\t},\n\t\t};\n\t}\n}\n\n/**\n * Register an orphaned table as a collection\n */\nexport async function handleOrphanedTableRegister(\n\tdb: Kysely<Database>,\n\tslug: string,\n\toptions?: {\n\t\tlabel?: string;\n\t\tlabelSingular?: string;\n\t\tdescription?: string;\n\t},\n): Promise<ApiResult<CollectionResponse>> {\n\ttry {\n\t\tconst registry = new SchemaRegistry(db);\n\t\tconst item = await registry.registerOrphanedTable(slug, options);\n\n\t\treturn {\n\t\t\tsuccess: true,\n\t\t\tdata: { item },\n\t\t};\n\t} catch (error) {\n\t\tif (error instanceof SchemaError) {\n\t\t\treturn {\n\t\t\t\tsuccess: false,\n\t\t\t\terror: {\n\t\t\t\t\tcode: error.code,\n\t\t\t\t\tmessage: error.message,\n\t\t\t\t\tdetails: error.details,\n\t\t\t\t},\n\t\t\t};\n\t\t}\n\t\treturn {\n\t\t\tsuccess: false,\n\t\t\terror: {\n\t\t\t\tcode: \"ORPHAN_REGISTER_ERROR\",\n\t\t\t\tmessage: \"Failed to register orphaned table\",\n\t\t\t},\n\t\t};\n\t}\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"schema-B-3rntlX.mjs","names":[],"sources":["../src/database/reference-backfill.ts","../src/api/handlers/schema.ts"],"sourcesContent":["import type { Kysely } from \"kysely\";\nimport { sql } from \"kysely\";\nimport { ulid } from \"ulidx\";\n\nimport { chunks, SQL_BATCH_SIZE } from \"../utils/chunks.js\";\nimport { currentTimestampValue, tableExists } from \"./dialect-helpers.js\";\nimport { REFERENCE_INSERT_BATCH_SIZE } from \"./repositories/relation.js\";\nimport { validateIdentifier } from \"./validate.js\";\n\n/** What to copy, and which relation to copy it into. */\nexport interface ReferenceBackfill {\n\t/** Collection owning the field, the relation's parent end. */\n\tparentCollection: string;\n\t/** The relation's child end, where the column's ids resolve. */\n\tchildCollection: string;\n\tfieldSlug: string;\n\trelationId: string;\n\t/** The relation's limit for this side. `null` is unlimited. */\n\tmaxChildren: number | null;\n}\n\n/** The ids one column value holds. */\nfunction parseColumnIds(value: unknown): string[] {\n\tif (typeof value !== \"string\" || value.length === 0) return [];\n\tif (!value.startsWith(\"[\")) return [value];\n\tlet parsed: unknown;\n\ttry {\n\t\tparsed = JSON.parse(value);\n\t} catch {\n\t\treturn [value];\n\t}\n\tif (!Array.isArray(parsed)) return [];\n\treturn parsed.filter((entry): entry is string => typeof entry === \"string\" && entry.length > 0);\n}\n\n/**\n * Copy a reference field's column values in as relation edges.\n *\n * A reference field created before relations existed holds its selection in a\n * TEXT column: one entry id, or a JSON array of them for a multiple-reference\n * field (`serializeValue` stringifies the array). Binding the field to a relation\n * moves that selection into `_emdash_content_references`, and this is the copy.\n *\n * The column is not touched. On a site that predates pickers it was a free-text\n * box, so it can hold anything an editor typed, and only the ids that resolve to\n * an entry become edges — clearing it would destroy the rest. Nothing writes to\n * it once the field is bound and typegen stops declaring the key, but a content\n * read still reports the frozen value in `data` beside the live `references`.\n *\n * Both ends of an edge are translation groups, so the locale siblings of one\n * entry contribute to the same parent group. They are read in a fixed order and\n * their ids deduped, and the result is capped at the relation's limit — a\n * single-reference field whose locale rows point at different entries keeps the\n * first rather than storing a selection the relation forbids.\n *\n * Every insert is `ON CONFLICT DO NOTHING` against the edge table's unique\n * constraint, so running this twice adds nothing the first run already wrote.\n *\n * Migration 077 carries its own copy of this for the upgrade path. A migration\n * must not share a module with the handler layer — the bundler then puts the two\n * in chunks that cycle through the migration runner, and the built package throws\n * on import — and a shipped migration has to keep behaving the way it did anyway.\n */\n// eslint-disable-next-line @typescript-eslint/no-explicit-any -- runs against a migration's untyped Kysely as well as the app's\nexport async function backfillReferenceEdges(\n\tdb: Kysely<any>,\n\tbackfill: ReferenceBackfill,\n): Promise<void> {\n\tconst parentTable = `ec_${backfill.parentCollection}`;\n\tconst childTable = `ec_${backfill.childCollection}`;\n\tvalidateIdentifier(parentTable, \"content table name\");\n\tvalidateIdentifier(childTable, \"content table name\");\n\tvalidateIdentifier(backfill.fieldSlug, \"content field name\");\n\n\tif (!(await tableExists(db, parentTable)) || !(await tableExists(db, childTable))) return;\n\n\tconst entries = await sql<{ translation_group: string | null; value: unknown }>`\n\t\tSELECT translation_group, ${sql.ref(backfill.fieldSlug)} AS value\n\t\tFROM ${sql.ref(parentTable)}\n\t\tWHERE ${sql.ref(backfill.fieldSlug)} IS NOT NULL\n\t\tORDER BY locale, id\n\t`.execute(db);\n\n\t// Parent group -> the child entry ids it selects, in order, deduped.\n\tconst selections = new Map<string, string[]>();\n\tfor (const entry of entries.rows) {\n\t\tif (!entry.translation_group) continue;\n\t\tconst existing = selections.get(entry.translation_group) ?? [];\n\t\tfor (const id of parseColumnIds(entry.value)) {\n\t\t\tif (!existing.includes(id)) existing.push(id);\n\t\t}\n\t\tselections.set(entry.translation_group, existing);\n\t}\n\tif (selections.size === 0) return;\n\n\tconst childIds = [...new Set([...selections.values()].flat())];\n\tconst childGroups = new Map<string, string>();\n\tfor (const batch of chunks(childIds, SQL_BATCH_SIZE)) {\n\t\t// oxlint-disable-next-line no-await-in-loop -- one statement per bind-parameter batch\n\t\tconst resolved = await sql<{ id: string; translation_group: string | null }>`\n\t\t\tSELECT id, translation_group\n\t\t\tFROM ${sql.ref(childTable)}\n\t\t\tWHERE id IN (${sql.join(batch)})\n\t\t`.execute(db);\n\t\tfor (const row of resolved.rows) {\n\t\t\tif (row.translation_group) childGroups.set(row.id, row.translation_group);\n\t\t}\n\t}\n\n\tconst now = currentTimestampValue(db);\n\tconst rows: Array<{ parentGroup: string; childGroup: string; sortOrder: number }> = [];\n\tfor (const parentGroup of [...selections.keys()].toSorted()) {\n\t\tconst groups: string[] = [];\n\t\tfor (const id of selections.get(parentGroup) ?? []) {\n\t\t\tconst group = childGroups.get(id);\n\t\t\t// An id whose entry is gone is dropped; its value stays in the column.\n\t\t\tif (group && !groups.includes(group)) groups.push(group);\n\t\t}\n\t\tconst selected = backfill.maxChildren === null ? groups : groups.slice(0, backfill.maxChildren);\n\t\tfor (const [sortOrder, childGroup] of selected.entries()) {\n\t\t\trows.push({ parentGroup, childGroup, sortOrder });\n\t\t}\n\t}\n\n\t// This runs inside the transaction that binds the field, so an editor binding\n\t// a field on a large legacy collection waits for it: batch rather than paying\n\t// a round trip per edge.\n\tfor (const batch of chunks(rows, REFERENCE_INSERT_BATCH_SIZE)) {\n\t\tconst values = batch.map(\n\t\t\t(row) =>\n\t\t\t\tsql`(${ulid()}, ${backfill.relationId}, ${row.parentGroup}, ${row.childGroup}, ${row.sortOrder}, ${now})`,\n\t\t);\n\t\t// oxlint-disable-next-line no-await-in-loop -- one statement per bind-parameter batch\n\t\tawait sql`\n\t\t\tINSERT INTO ${sql.ref(\"_emdash_content_references\")}\n\t\t\t\t(id, relation_id, parent_group, child_group, sort_order, created_at)\n\t\t\tVALUES ${sql.join(values)}\n\t\t\tON CONFLICT DO NOTHING\n\t\t`.execute(db);\n\t}\n}\n","/**\n * Schema/collection management handlers\n */\n\nimport type { Kysely } from \"kysely\";\n\nimport { backfillReferenceEdges } from \"../../database/reference-backfill.js\";\nimport { RelationRepository, type Relation } from \"../../database/repositories/relation.js\";\nimport { withTransaction } from \"../../database/transaction.js\";\nimport type { Database } from \"../../database/types.js\";\nimport {\n\tinvalidateCollectionCache,\n\tinvalidateSchemaObjectCache,\n} from \"../../object-cache/index.js\";\nimport {\n\tSchemaRegistry,\n\tSchemaError,\n\tinvalidateSchemaCache,\n\ttype Collection,\n\ttype Field,\n\ttype CreateCollectionInput,\n\ttype UpdateCollectionInput,\n\ttype CreateFieldInput,\n\ttype UpdateFieldInput,\n\ttype CollectionWithFields,\n\texpandCollectionBlockFields,\n} from \"../../schema/index.js\";\nimport type { ApiResult } from \"../types.js\";\nimport { fieldsBoundToRelation, handleRelationDelete } from \"./relations.js\";\n\n/** Maximum attempts to allocate a unique relation slug for a new reference\n * field: the base `${collection}_${field}` slug, then `_2` through `_5`. */\nconst RELATION_NAME_MAX_ATTEMPTS = 5;\n\n/** True for SQLite UNIQUE / Postgres unique_violation messages — mirrors the\n * fingerprint used in the relations API handler. */\nfunction isUniqueViolation(error: unknown): boolean {\n\tconst message = error instanceof Error ? error.message.toLowerCase() : \"\";\n\treturn message.includes(\"unique constraint failed\") || message.includes(\"duplicate key\");\n}\n\n/**\n * Create the relation definition backing a new reference field, retrying\n * with a numeric suffix on a name collision. Runs inside the caller's\n * transaction so the relation and the field row it backs commit or roll\n * back together.\n */\nexport async function createFieldRelation(\n\ttrx: Kysely<Database>,\n\tcollectionSlug: string,\n\tfieldSlug: string,\n\tfieldLabel: string,\n\ttargetCollection: string,\n\t/** How many entries the new field may hold. `null` is unlimited. */\n\tmaxChildrenPerParent: number | null = null,\n): Promise<Relation> {\n\tconst registry = new SchemaRegistry(trx);\n\tconst relations = new RelationRepository(trx);\n\n\tconst parent = await registry.getCollection(collectionSlug);\n\tif (!parent) {\n\t\tthrow new SchemaError(`Collection \"${collectionSlug}\" not found`, \"COLLECTION_NOT_FOUND\");\n\t}\n\n\tif (!(await registry.getCollection(targetCollection))) {\n\t\tthrow new SchemaError(\n\t\t\t`Target collection \"${targetCollection}\" not found`,\n\t\t\t\"COLLECTION_NOT_FOUND\",\n\t\t);\n\t}\n\n\tconst baseSlug = `${collectionSlug}_${fieldSlug}`.slice(0, 63);\n\tfor (let attempt = 0; attempt < RELATION_NAME_MAX_ATTEMPTS; attempt++) {\n\t\tconst suffix = attempt === 0 ? \"\" : `_${attempt + 1}`;\n\t\tconst slug = attempt === 0 ? baseSlug : `${baseSlug.slice(0, 63 - suffix.length)}${suffix}`;\n\t\ttry {\n\t\t\treturn await relations.create({\n\t\t\t\tslug,\n\t\t\t\tparentCollection: collectionSlug,\n\t\t\t\tchildCollection: targetCollection,\n\t\t\t\tparentLabel: parent.label,\n\t\t\t\tparentLabelSingular: parent.labelSingular ?? null,\n\t\t\t\tchildLabel: fieldLabel,\n\t\t\t\tmaxChildrenPerParent,\n\t\t\t});\n\t\t} catch (error) {\n\t\t\tconst isLastAttempt = attempt === RELATION_NAME_MAX_ATTEMPTS - 1;\n\t\t\tif (isLastAttempt || !isUniqueViolation(error)) throw error;\n\t\t}\n\t}\n\tthrow new SchemaError(\"Could not allocate a unique relation name\", \"RELATION_NAME_CONFLICT\");\n}\n\n/**\n * Every cache a field change can stale.\n *\n * The schema object-cache namespace is bumped here rather than only by the\n * collection routes: the render path's reference field map lives in that\n * namespace, so a field created, bound, relabelled or deleted would otherwise\n * keep resolving against the shape the collection used to have.\n */\nfunction invalidateFieldCaches(collectionSlug: string): void {\n\tinvalidateCollectionCache(collectionSlug);\n\tinvalidateSchemaCache(collectionSlug);\n\tinvalidateSchemaObjectCache();\n}\n\n/**\n * Bind a reference field that has no relation to one, and copy the selection its\n * column holds in as edges.\n *\n * The column is left in place but stops being written, so the field also stops\n * being `indexed` and `searchable`: an index over a frozen column would answer\n * content-list filters and searches from values that no longer change. Clearing\n * both here drops the field index and re-syncs FTS through `updateField`.\n */\nexport async function bindReferenceField(\n\tdb: Kysely<Database>,\n\tcollectionSlug: string,\n\texisting: Field,\n\tinput: UpdateFieldInput,\n\ttargetCollection: string,\n): Promise<Field> {\n\tconst label = input.label ?? existing.label;\n\tconst maxChildren = input.validation?.multiple ? null : 1;\n\n\treturn withTransaction(db, async (trx) => {\n\t\tconst relation = await createFieldRelation(\n\t\t\ttrx,\n\t\t\tcollectionSlug,\n\t\t\texisting.slug,\n\t\t\tlabel,\n\t\t\ttargetCollection,\n\t\t\tmaxChildren,\n\t\t);\n\t\tconst registry = new SchemaRegistry(trx);\n\t\tconst updated = await registry.updateField(collectionSlug, existing.slug, {\n\t\t\t...input,\n\t\t\tindexed: false,\n\t\t\tsearchable: false,\n\t\t\tvalidation: {\n\t\t\t\t...input.validation,\n\t\t\t\trelation: relation.slug,\n\t\t\t\trelationSide: \"parent\",\n\t\t\t\ttargetCollection,\n\t\t\t},\n\t\t});\n\n\t\tawait backfillReferenceEdges(trx, {\n\t\t\tparentCollection: collectionSlug,\n\t\t\tchildCollection: targetCollection,\n\t\t\tfieldSlug: existing.slug,\n\t\t\trelationId: relation.id,\n\t\t\tmaxChildren,\n\t\t});\n\n\t\treturn updated;\n\t});\n}\n\nexport interface CollectionListResponse {\n\titems: Collection[];\n}\n\nexport interface CollectionResponse {\n\titem: Collection;\n}\n\nexport interface CollectionWithFieldsResponse {\n\titem: CollectionWithFields;\n}\n\nexport interface FieldListResponse {\n\titems: Field[];\n}\n\nexport interface FieldResponse {\n\titem: Field;\n}\n\n/**\n * List all collections\n */\nexport async function handleSchemaCollectionList(\n\tdb: Kysely<Database>,\n): Promise<ApiResult<CollectionListResponse>> {\n\ttry {\n\t\tconst registry = new SchemaRegistry(db);\n\t\tconst items = await registry.listCollections();\n\n\t\treturn {\n\t\t\tsuccess: true,\n\t\t\tdata: { items },\n\t\t};\n\t} catch {\n\t\treturn {\n\t\t\tsuccess: false,\n\t\t\terror: {\n\t\t\t\tcode: \"SCHEMA_LIST_ERROR\",\n\t\t\t\tmessage: \"Failed to list collections\",\n\t\t\t},\n\t\t};\n\t}\n}\n\n/**\n * Get a collection by slug\n */\nexport async function handleSchemaCollectionGet(\n\tdb: Kysely<Database>,\n\tslug: string,\n\toptions?: { includeFields?: boolean },\n): Promise<ApiResult<CollectionResponse | CollectionWithFieldsResponse>> {\n\ttry {\n\t\tconst registry = new SchemaRegistry(db);\n\n\t\tif (options?.includeFields) {\n\t\t\tconst stored = await registry.getCollectionWithFields(slug);\n\t\t\tconst item = stored ? await expandCollectionBlockFields(db, stored) : null;\n\t\t\tif (!item) {\n\t\t\t\treturn {\n\t\t\t\t\tsuccess: false,\n\t\t\t\t\terror: {\n\t\t\t\t\t\tcode: \"NOT_FOUND\",\n\t\t\t\t\t\tmessage: `Collection not found: ${slug}`,\n\t\t\t\t\t},\n\t\t\t\t};\n\t\t\t}\n\t\t\treturn {\n\t\t\t\tsuccess: true,\n\t\t\t\tdata: { item },\n\t\t\t};\n\t\t}\n\n\t\tconst item = await registry.getCollection(slug);\n\t\tif (!item) {\n\t\t\treturn {\n\t\t\t\tsuccess: false,\n\t\t\t\terror: {\n\t\t\t\t\tcode: \"NOT_FOUND\",\n\t\t\t\t\tmessage: `Collection not found: ${slug}`,\n\t\t\t\t},\n\t\t\t};\n\t\t}\n\n\t\treturn {\n\t\t\tsuccess: true,\n\t\t\tdata: { item },\n\t\t};\n\t} catch (error) {\n\t\tif (error instanceof SchemaError) {\n\t\t\treturn {\n\t\t\t\tsuccess: false,\n\t\t\t\terror: { code: error.code, message: error.message, details: error.details },\n\t\t\t};\n\t\t}\n\t\treturn {\n\t\t\tsuccess: false,\n\t\t\terror: {\n\t\t\t\tcode: \"SCHEMA_GET_ERROR\",\n\t\t\t\tmessage: \"Failed to get collection\",\n\t\t\t},\n\t\t};\n\t}\n}\n\n/**\n * Create a collection\n */\nexport async function handleSchemaCollectionCreate(\n\tdb: Kysely<Database>,\n\tinput: CreateCollectionInput,\n): Promise<ApiResult<CollectionResponse>> {\n\ttry {\n\t\tconst registry = new SchemaRegistry(db);\n\t\tconst item = await registry.createCollection(input);\n\n\t\treturn {\n\t\t\tsuccess: true,\n\t\t\tdata: { item },\n\t\t};\n\t} catch (error) {\n\t\tif (error instanceof SchemaError) {\n\t\t\treturn {\n\t\t\t\tsuccess: false,\n\t\t\t\terror: {\n\t\t\t\t\tcode: error.code,\n\t\t\t\t\tmessage: error.message,\n\t\t\t\t\tdetails: error.details,\n\t\t\t\t},\n\t\t\t};\n\t\t}\n\t\tconsole.error(\"[emdash] Failed to create collection:\", error);\n\t\treturn {\n\t\t\tsuccess: false,\n\t\t\terror: {\n\t\t\t\tcode: \"SCHEMA_CREATE_ERROR\",\n\t\t\t\tmessage: \"Failed to create collection\",\n\t\t\t},\n\t\t};\n\t}\n}\n\n/**\n * Update a collection\n */\nexport async function handleSchemaCollectionUpdate(\n\tdb: Kysely<Database>,\n\tslug: string,\n\tinput: UpdateCollectionInput,\n): Promise<ApiResult<CollectionResponse>> {\n\ttry {\n\t\tconst registry = new SchemaRegistry(db);\n\t\tconst item = await registry.updateCollection(slug, input);\n\n\t\treturn {\n\t\t\tsuccess: true,\n\t\t\tdata: { item },\n\t\t};\n\t} catch (error) {\n\t\tif (error instanceof SchemaError) {\n\t\t\treturn {\n\t\t\t\tsuccess: false,\n\t\t\t\terror: {\n\t\t\t\t\tcode: error.code,\n\t\t\t\t\tmessage: error.message,\n\t\t\t\t\tdetails: error.details,\n\t\t\t\t},\n\t\t\t};\n\t\t}\n\t\treturn {\n\t\t\tsuccess: false,\n\t\t\terror: {\n\t\t\t\tcode: \"SCHEMA_UPDATE_ERROR\",\n\t\t\t\tmessage: \"Failed to update collection\",\n\t\t\t},\n\t\t};\n\t}\n}\n\n/**\n * Delete a collection\n */\nexport async function handleSchemaCollectionDelete(\n\tdb: Kysely<Database>,\n\tslug: string,\n\toptions?: { force?: boolean },\n): Promise<ApiResult<{ success: boolean }>> {\n\ttry {\n\t\tconst registry = new SchemaRegistry(db);\n\n\t\t// Nothing below can be undone on D1, so a delete that will be refused has\n\t\t// to be refused before the first relation goes.\n\t\tawait registry.assertCollectionDeletable(slug, options);\n\n\t\t// A relation with this collection on either end cannot outlive it: its\n\t\t// edges point at content that is about to be dropped, and the reference\n\t\t// fields viewing it — including ones on the *other* collection — would be\n\t\t// left addressing a collection that no longer exists. The admin lists both\n\t\t// before confirming. Relations go first, so an interrupted delete leaves a\n\t\t// collection with fewer relations rather than a dropped table with\n\t\t// relations still pointing at it.\n\t\tconst relations = new RelationRepository(db);\n\t\tfor (const relation of await relations.findForCollection(slug)) {\n\t\t\tconst removed = await handleRelationDelete(db, relation.id);\n\t\t\tif (!removed.success) return removed;\n\t\t}\n\n\t\tawait registry.deleteCollection(slug, options);\n\n\t\treturn {\n\t\t\tsuccess: true,\n\t\t\tdata: { success: true },\n\t\t};\n\t} catch (error) {\n\t\tif (error instanceof SchemaError) {\n\t\t\treturn {\n\t\t\t\tsuccess: false,\n\t\t\t\terror: {\n\t\t\t\t\tcode: error.code,\n\t\t\t\t\tmessage: error.message,\n\t\t\t\t\tdetails: error.details,\n\t\t\t\t},\n\t\t\t};\n\t\t}\n\t\treturn {\n\t\t\tsuccess: false,\n\t\t\terror: {\n\t\t\t\tcode: \"SCHEMA_DELETE_ERROR\",\n\t\t\t\tmessage: \"Failed to delete collection\",\n\t\t\t},\n\t\t};\n\t}\n}\n\n/**\n * List fields for a collection\n */\nexport async function handleSchemaFieldList(\n\tdb: Kysely<Database>,\n\tcollectionSlug: string,\n): Promise<ApiResult<FieldListResponse>> {\n\ttry {\n\t\tconst registry = new SchemaRegistry(db);\n\t\tconst stored = await registry.getCollectionWithFields(collectionSlug);\n\n\t\tif (!stored) {\n\t\t\treturn {\n\t\t\t\tsuccess: false,\n\t\t\t\terror: {\n\t\t\t\t\tcode: \"NOT_FOUND\",\n\t\t\t\t\tmessage: `Collection not found: ${collectionSlug}`,\n\t\t\t\t},\n\t\t\t};\n\t\t}\n\n\t\tconst items = (await expandCollectionBlockFields(db, stored)).fields;\n\n\t\treturn {\n\t\t\tsuccess: true,\n\t\t\tdata: { items },\n\t\t};\n\t} catch (error) {\n\t\tif (error instanceof SchemaError) {\n\t\t\treturn {\n\t\t\t\tsuccess: false,\n\t\t\t\terror: { code: error.code, message: error.message, details: error.details },\n\t\t\t};\n\t\t}\n\t\treturn {\n\t\t\tsuccess: false,\n\t\t\terror: {\n\t\t\t\tcode: \"SCHEMA_FIELD_LIST_ERROR\",\n\t\t\t\tmessage: \"Failed to list fields\",\n\t\t\t},\n\t\t};\n\t}\n}\n\n/**\n * Get a field\n */\nexport async function handleSchemaFieldGet(\n\tdb: Kysely<Database>,\n\tcollectionSlug: string,\n\tfieldSlug: string,\n): Promise<ApiResult<FieldResponse>> {\n\ttry {\n\t\tconst registry = new SchemaRegistry(db);\n\t\tconst collection = await registry.getCollectionWithFields(collectionSlug);\n\t\tconst item = collection\n\t\t\t? (await expandCollectionBlockFields(db, collection)).fields.find(\n\t\t\t\t\t(field) => field.slug === fieldSlug,\n\t\t\t\t)\n\t\t\t: null;\n\n\t\tif (!item) {\n\t\t\treturn {\n\t\t\t\tsuccess: false,\n\t\t\t\terror: {\n\t\t\t\t\tcode: \"NOT_FOUND\",\n\t\t\t\t\tmessage: `Field not found: ${fieldSlug} in collection ${collectionSlug}`,\n\t\t\t\t},\n\t\t\t};\n\t\t}\n\n\t\treturn {\n\t\t\tsuccess: true,\n\t\t\tdata: { item },\n\t\t};\n\t} catch (error) {\n\t\tif (error instanceof SchemaError) {\n\t\t\treturn {\n\t\t\t\tsuccess: false,\n\t\t\t\terror: { code: error.code, message: error.message, details: error.details },\n\t\t\t};\n\t\t}\n\t\treturn {\n\t\t\tsuccess: false,\n\t\t\terror: {\n\t\t\t\tcode: \"SCHEMA_FIELD_GET_ERROR\",\n\t\t\t\tmessage: \"Failed to get field\",\n\t\t\t},\n\t\t};\n\t}\n}\n\n/**\n * Resolve which end of `relation` a field on `collectionSlug` sits on.\n *\n * The side is only a choice when both ends are the same collection — a\n * self-referential relation such as related posts. Anywhere else the matching\n * end decides it, and an explicit side that disagrees is a client error rather\n * than something to silently override.\n */\nfunction resolveBindingSide(\n\trelation: Relation,\n\tcollectionSlug: string,\n\trequested: \"parent\" | \"child\" | undefined,\n): { side: \"parent\" | \"child\"; targetCollection: string } | { error: string } {\n\tconst isParent = relation.parentCollection === collectionSlug;\n\tconst isChild = relation.childCollection === collectionSlug;\n\n\tif (!isParent && !isChild) {\n\t\treturn {\n\t\t\terror: `Relation '${relation.slug}' does not touch collection '${collectionSlug}'`,\n\t\t};\n\t}\n\n\tif (isParent && isChild) {\n\t\tconst side = requested ?? \"parent\";\n\t\treturn {\n\t\t\tside,\n\t\t\ttargetCollection: side === \"parent\" ? relation.childCollection : relation.parentCollection,\n\t\t};\n\t}\n\n\tconst side = isParent ? \"parent\" : \"child\";\n\tif (requested && requested !== side) {\n\t\treturn {\n\t\t\terror: `Collection '${collectionSlug}' is the ${side} of relation '${relation.slug}'`,\n\t\t};\n\t}\n\n\treturn {\n\t\tside,\n\t\ttargetCollection: isParent ? relation.childCollection : relation.parentCollection,\n\t};\n}\n\n/**\n * Create a reference field that views an existing relation.\n *\n * Only one field may view a relation from a given end: two pickers writing the\n * same link set have no defined merge, and the second would silently overwrite\n * the first on every save.\n */\nasync function createBoundReferenceField(\n\tdb: Kysely<Database>,\n\tcollectionSlug: string,\n\tinput: CreateFieldInput,\n\trelationSlug: string,\n): Promise<ApiResult<FieldResponse>> {\n\tconst relation = await new RelationRepository(db).findBySlug(relationSlug);\n\tif (!relation) {\n\t\treturn {\n\t\t\tsuccess: false,\n\t\t\terror: { code: \"NOT_FOUND\", message: `Relation '${relationSlug}' not found` },\n\t\t};\n\t}\n\n\tconst resolved = resolveBindingSide(relation, collectionSlug, input.validation?.relationSide);\n\tif (\"error\" in resolved) {\n\t\treturn { success: false, error: { code: \"VALIDATION_ERROR\", message: resolved.error } };\n\t}\n\n\tconst bound = await fieldsBoundToRelation(db, relation.slug);\n\tconst taken = bound.find((field) => field.side === resolved.side);\n\tif (taken) {\n\t\treturn {\n\t\t\tsuccess: false,\n\t\t\terror: {\n\t\t\t\tcode: \"CONFLICT\",\n\t\t\t\tmessage: `Relation '${relation.slug}' is already picked from by ${taken.collectionSlug}.${taken.fieldSlug}`,\n\t\t\t},\n\t\t};\n\t}\n\n\tconst item = await new SchemaRegistry(db).createField(collectionSlug, {\n\t\t...input,\n\t\tvalidation: {\n\t\t\t...input.validation,\n\t\t\trelation: relation.slug,\n\t\t\trelationSide: resolved.side,\n\t\t\ttargetCollection: resolved.targetCollection,\n\t\t},\n\t});\n\n\tinvalidateFieldCaches(collectionSlug);\n\n\treturn { success: true, data: { item } };\n}\n\n/**\n * Create a field\n */\nexport async function handleSchemaFieldCreate(\n\tdb: Kysely<Database>,\n\tcollectionSlug: string,\n\tinput: CreateFieldInput,\n): Promise<ApiResult<FieldResponse>> {\n\ttry {\n\t\tif (input.type === \"reference\" && input.validation?.relation) {\n\t\t\treturn await createBoundReferenceField(db, collectionSlug, input, input.validation.relation);\n\t\t}\n\n\t\tif (input.type === \"reference\") {\n\t\t\tconst targetCollection = input.validation?.targetCollection;\n\t\t\tif (!targetCollection) {\n\t\t\t\treturn {\n\t\t\t\t\tsuccess: false,\n\t\t\t\t\terror: {\n\t\t\t\t\t\tcode: \"VALIDATION_ERROR\",\n\t\t\t\t\t\tmessage: \"Reference field requires a target collection\",\n\t\t\t\t\t},\n\t\t\t\t};\n\t\t\t}\n\n\t\t\t// The relation def and the field row it backs must commit or roll\n\t\t\t// back together — a field without its relation (or vice versa) is\n\t\t\t// an inconsistent reference field.\n\t\t\tconst item = await withTransaction(db, async (trx) => {\n\t\t\t\t// A single-reference field is a one-to-many relation: the limit is the\n\t\t\t\t// relation's, so binding its other end later sees the same rule.\n\t\t\t\tconst relation = await createFieldRelation(\n\t\t\t\t\ttrx,\n\t\t\t\t\tcollectionSlug,\n\t\t\t\t\tinput.slug,\n\t\t\t\t\tinput.label,\n\t\t\t\t\ttargetCollection,\n\t\t\t\t\tinput.validation?.multiple ? null : 1,\n\t\t\t\t);\n\t\t\t\tconst registry = new SchemaRegistry(trx);\n\t\t\t\treturn registry.createField(collectionSlug, {\n\t\t\t\t\t...input,\n\t\t\t\t\tvalidation: {\n\t\t\t\t\t\t...input.validation,\n\t\t\t\t\t\trelation: relation.slug,\n\t\t\t\t\t\trelationSide: \"parent\" as const,\n\t\t\t\t\t\ttargetCollection,\n\t\t\t\t\t},\n\t\t\t\t});\n\t\t\t});\n\n\t\t\t// Content snapshots embed field values; a column change invalidates them.\n\t\t\tinvalidateFieldCaches(collectionSlug);\n\n\t\t\treturn {\n\t\t\t\tsuccess: true,\n\t\t\t\tdata: { item },\n\t\t\t};\n\t\t}\n\n\t\tconst registry = new SchemaRegistry(db);\n\t\tconst item = await registry.createField(collectionSlug, input);\n\n\t\t// Content snapshots embed field values; a column change invalidates them.\n\t\tinvalidateFieldCaches(collectionSlug);\n\n\t\treturn {\n\t\t\tsuccess: true,\n\t\t\tdata: { item },\n\t\t};\n\t} catch (error) {\n\t\tif (error instanceof SchemaError) {\n\t\t\treturn {\n\t\t\t\tsuccess: false,\n\t\t\t\terror: {\n\t\t\t\t\tcode: error.code,\n\t\t\t\t\tmessage: error.message,\n\t\t\t\t\tdetails: error.details,\n\t\t\t\t},\n\t\t\t};\n\t\t}\n\t\treturn {\n\t\t\tsuccess: false,\n\t\t\terror: {\n\t\t\t\tcode: \"SCHEMA_FIELD_CREATE_ERROR\",\n\t\t\t\tmessage: \"Failed to create field\",\n\t\t\t},\n\t\t};\n\t}\n}\n\n/**\n * Update a field\n */\nexport async function handleSchemaFieldUpdate(\n\tdb: Kysely<Database>,\n\tcollectionSlug: string,\n\tfieldSlug: string,\n\tinput: UpdateFieldInput,\n): Promise<ApiResult<FieldResponse>> {\n\ttry {\n\t\tconst lookupRegistry = new SchemaRegistry(db);\n\t\tconst existing = await lookupRegistry.getField(collectionSlug, fieldSlug);\n\t\tconst relationSlug = existing?.type === \"reference\" ? existing.validation?.relation : undefined;\n\t\tconst relationSide = existing?.validation?.relationSide;\n\n\t\tif (existing && relationSlug) {\n\t\t\t// The relation's childCollection is immutable — a reference field's\n\t\t\t// target collection can't change after the relation is wired up.\n\t\t\tconst nextTargetCollection = input.validation?.targetCollection;\n\t\t\tif (\n\t\t\t\tnextTargetCollection !== undefined &&\n\t\t\t\tnextTargetCollection !== existing.validation?.targetCollection\n\t\t\t) {\n\t\t\t\treturn {\n\t\t\t\t\tsuccess: false,\n\t\t\t\t\terror: {\n\t\t\t\t\t\tcode: \"VALIDATION_ERROR\",\n\t\t\t\t\t\tmessage: \"Cannot change the target collection of an existing reference field\",\n\t\t\t\t\t},\n\t\t\t\t};\n\t\t\t}\n\n\t\t\t// `relation` and `targetCollection` are immutable identity for a wired\n\t\t\t// reference field. An update that sends `validation: null` or a partial\n\t\t\t// validation object omitting these keys must not be allowed to clear\n\t\t\t// them -- registry.updateField() writes whatever is passed verbatim,\n\t\t\t// which would otherwise orphan the relation row and its edges.\n\t\t\tconst updateInput =\n\t\t\t\tinput.validation !== undefined\n\t\t\t\t\t? {\n\t\t\t\t\t\t\t...input,\n\t\t\t\t\t\t\tvalidation: {\n\t\t\t\t\t\t\t\t...input.validation,\n\t\t\t\t\t\t\t\trelation: existing.validation?.relation,\n\t\t\t\t\t\t\t\trelationSide: existing.validation?.relationSide,\n\t\t\t\t\t\t\t\ttargetCollection: existing.validation?.targetCollection,\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t}\n\t\t\t\t\t: input;\n\n\t\t\tconst item = await withTransaction(db, async (trx) => {\n\t\t\t\tconst registry = new SchemaRegistry(trx);\n\t\t\t\tconst updated = await registry.updateField(collectionSlug, fieldSlug, updateInput);\n\n\t\t\t\tif (input.label !== undefined && input.label !== existing.label) {\n\t\t\t\t\tconst relations = new RelationRepository(trx);\n\t\t\t\t\tconst relation = await relations.findBySlug(relationSlug);\n\t\t\t\t\t// The field's label is the role name for the side it binds, so\n\t\t\t\t\t// renaming the field renames that role and leaves the other alone.\n\t\t\t\t\tif (relation) {\n\t\t\t\t\t\tawait relations.update(\n\t\t\t\t\t\t\trelation.id,\n\t\t\t\t\t\t\trelationSide === \"child\" ? { parentLabel: input.label } : { childLabel: input.label },\n\t\t\t\t\t\t);\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\treturn updated;\n\t\t\t});\n\n\t\t\tinvalidateFieldCaches(collectionSlug);\n\n\t\t\treturn {\n\t\t\t\tsuccess: true,\n\t\t\t\tdata: { item },\n\t\t\t};\n\t\t}\n\n\t\t// Giving an unbound reference field a target collection binds it: a field\n\t\t// created before relations existed, or one whose target could not be\n\t\t// resolved on upgrade, becomes a picker here rather than needing to be\n\t\t// deleted and recreated.\n\t\tconst bindTarget = existing?.type === \"reference\" ? input.validation?.targetCollection : null;\n\t\tif (existing && bindTarget) {\n\t\t\tconst item = await bindReferenceField(db, collectionSlug, existing, input, bindTarget);\n\t\t\tinvalidateFieldCaches(collectionSlug);\n\t\t\treturn { success: true, data: { item } };\n\t\t}\n\n\t\tconst registry = new SchemaRegistry(db);\n\t\tconst item = await registry.updateField(collectionSlug, fieldSlug, input);\n\n\t\tinvalidateFieldCaches(collectionSlug);\n\n\t\treturn {\n\t\t\tsuccess: true,\n\t\t\tdata: { item },\n\t\t};\n\t} catch (error) {\n\t\tif (error instanceof SchemaError) {\n\t\t\treturn {\n\t\t\t\tsuccess: false,\n\t\t\t\terror: {\n\t\t\t\t\tcode: error.code,\n\t\t\t\t\tmessage: error.message,\n\t\t\t\t\tdetails: error.details,\n\t\t\t\t},\n\t\t\t};\n\t\t}\n\t\treturn {\n\t\t\tsuccess: false,\n\t\t\terror: {\n\t\t\t\tcode: \"SCHEMA_FIELD_UPDATE_ERROR\",\n\t\t\t\tmessage: \"Failed to update field\",\n\t\t\t},\n\t\t};\n\t}\n}\n\n/**\n * Delete a field\n */\n/**\n * Delete a field.\n *\n * For a reference field, `deleteRelation` also takes the relation, its edges,\n * and the field bound to its other side. It is opt-in on the wire and checked\n * by default in the admin's confirm dialog, which enumerates what goes first.\n */\nexport async function handleSchemaFieldDelete(\n\tdb: Kysely<Database>,\n\tcollectionSlug: string,\n\tfieldSlug: string,\n\toptions?: { deleteRelation?: boolean },\n): Promise<ApiResult<{ success: boolean }>> {\n\ttry {\n\t\tconst lookupRegistry = new SchemaRegistry(db);\n\t\tconst existing = await lookupRegistry.getField(collectionSlug, fieldSlug);\n\t\tconst relationSlug = existing?.type === \"reference\" ? existing.validation?.relation : undefined;\n\n\t\tif (relationSlug && options?.deleteRelation) {\n\t\t\t// Taking the relation takes its edges and the field bound to its other\n\t\t\t// side, so route through the shared cascade rather than deleting the\n\t\t\t// field here and the relation separately.\n\t\t\tconst relations = new RelationRepository(db);\n\t\t\tconst relation = await relations.findBySlug(relationSlug);\n\t\t\tif (relation) {\n\t\t\t\tconst result = await handleRelationDelete(db, relation.id);\n\t\t\t\tif (!result.success) return result;\n\t\t\t\tinvalidateFieldCaches(collectionSlug);\n\t\t\t\treturn { success: true, data: { success: true } };\n\t\t\t}\n\t\t}\n\n\t\tconst registry = new SchemaRegistry(db);\n\t\tawait registry.deleteField(collectionSlug, fieldSlug);\n\n\t\tinvalidateFieldCaches(collectionSlug);\n\n\t\treturn {\n\t\t\tsuccess: true,\n\t\t\tdata: { success: true },\n\t\t};\n\t} catch (error) {\n\t\tif (error instanceof SchemaError) {\n\t\t\treturn {\n\t\t\t\tsuccess: false,\n\t\t\t\terror: {\n\t\t\t\t\tcode: error.code,\n\t\t\t\t\tmessage: error.message,\n\t\t\t\t\tdetails: error.details,\n\t\t\t\t},\n\t\t\t};\n\t\t}\n\t\treturn {\n\t\t\tsuccess: false,\n\t\t\terror: {\n\t\t\t\tcode: \"SCHEMA_FIELD_DELETE_ERROR\",\n\t\t\t\tmessage: \"Failed to delete field\",\n\t\t\t},\n\t\t};\n\t}\n}\n\n/**\n * Reorder collections in the admin sidebar\n */\nexport async function handleSchemaCollectionReorder(\n\tdb: Kysely<Database>,\n\tslugs: string[],\n): Promise<ApiResult<{ success: boolean }>> {\n\ttry {\n\t\tconst registry = new SchemaRegistry(db);\n\t\tawait registry.reorderCollections(slugs);\n\n\t\treturn {\n\t\t\tsuccess: true,\n\t\t\tdata: { success: true },\n\t\t};\n\t} catch (error) {\n\t\tif (error instanceof SchemaError) {\n\t\t\treturn {\n\t\t\t\tsuccess: false,\n\t\t\t\terror: {\n\t\t\t\t\tcode: error.code,\n\t\t\t\t\tmessage: error.message,\n\t\t\t\t\tdetails: error.details,\n\t\t\t\t},\n\t\t\t};\n\t\t}\n\t\tconsole.error(\"[emdash] Failed to reorder collections:\", error);\n\t\treturn {\n\t\t\tsuccess: false,\n\t\t\terror: {\n\t\t\t\tcode: \"SCHEMA_COLLECTION_REORDER_ERROR\",\n\t\t\t\tmessage: \"Failed to reorder collections\",\n\t\t\t},\n\t\t};\n\t}\n}\n\n/**\n * Reorder fields\n */\nexport async function handleSchemaFieldReorder(\n\tdb: Kysely<Database>,\n\tcollectionSlug: string,\n\tfieldSlugs: string[],\n): Promise<ApiResult<{ success: boolean }>> {\n\ttry {\n\t\tconst registry = new SchemaRegistry(db);\n\t\tawait registry.reorderFields(collectionSlug, fieldSlugs);\n\n\t\treturn {\n\t\t\tsuccess: true,\n\t\t\tdata: { success: true },\n\t\t};\n\t} catch (error) {\n\t\tif (error instanceof SchemaError) {\n\t\t\treturn {\n\t\t\t\tsuccess: false,\n\t\t\t\terror: {\n\t\t\t\t\tcode: error.code,\n\t\t\t\t\tmessage: error.message,\n\t\t\t\t\tdetails: error.details,\n\t\t\t\t},\n\t\t\t};\n\t\t}\n\t\treturn {\n\t\t\tsuccess: false,\n\t\t\terror: {\n\t\t\t\tcode: \"SCHEMA_FIELD_REORDER_ERROR\",\n\t\t\t\tmessage: \"Failed to reorder fields\",\n\t\t\t},\n\t\t};\n\t}\n}\n\n// ============================================\n// Orphaned Table Discovery\n// ============================================\n\nexport interface OrphanedTable {\n\tslug: string;\n\ttableName: string;\n\trowCount: number;\n}\n\nexport interface OrphanedTableListResponse {\n\titems: OrphanedTable[];\n}\n\n/**\n * List orphaned content tables\n */\nexport async function handleOrphanedTableList(\n\tdb: Kysely<Database>,\n): Promise<ApiResult<OrphanedTableListResponse>> {\n\ttry {\n\t\tconst registry = new SchemaRegistry(db);\n\t\tconst items = await registry.discoverOrphanedTables();\n\n\t\treturn {\n\t\t\tsuccess: true,\n\t\t\tdata: { items },\n\t\t};\n\t} catch (error) {\n\t\tconsole.error(\"[emdash] Failed to list orphaned tables:\", error);\n\t\treturn {\n\t\t\tsuccess: false,\n\t\t\terror: {\n\t\t\t\tcode: \"ORPHAN_LIST_ERROR\",\n\t\t\t\tmessage: \"Failed to list orphaned tables\",\n\t\t\t},\n\t\t};\n\t}\n}\n\n/**\n * Register an orphaned table as a collection\n */\nexport async function handleOrphanedTableRegister(\n\tdb: Kysely<Database>,\n\tslug: string,\n\toptions?: {\n\t\tlabel?: string;\n\t\tlabelSingular?: string;\n\t\tdescription?: string;\n\t},\n): Promise<ApiResult<CollectionResponse>> {\n\ttry {\n\t\tconst registry = new SchemaRegistry(db);\n\t\tconst item = await registry.registerOrphanedTable(slug, options);\n\n\t\treturn {\n\t\t\tsuccess: true,\n\t\t\tdata: { item },\n\t\t};\n\t} catch (error) {\n\t\tif (error instanceof SchemaError) {\n\t\t\treturn {\n\t\t\t\tsuccess: false,\n\t\t\t\terror: {\n\t\t\t\t\tcode: error.code,\n\t\t\t\t\tmessage: error.message,\n\t\t\t\t\tdetails: error.details,\n\t\t\t\t},\n\t\t\t};\n\t\t}\n\t\treturn {\n\t\t\tsuccess: false,\n\t\t\terror: {\n\t\t\t\tcode: \"ORPHAN_REGISTER_ERROR\",\n\t\t\t\tmessage: \"Failed to register orphaned table\",\n\t\t\t},\n\t\t};\n\t}\n}\n"],"mappings":"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"}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { n as SchemaRegistry } from "./registry-
|
|
3
|
-
import { n as expandCollectionBlockFields } from "./block-values-
|
|
1
|
+
import { f as __exportAll } from "./runner-Bkkfk4O8.mjs";
|
|
2
|
+
import { n as SchemaRegistry } from "./registry-B0-O575m.mjs";
|
|
3
|
+
import { n as expandCollectionBlockFields } from "./block-values-Dg0-8PPS.mjs";
|
|
4
4
|
|
|
5
5
|
//#region src/schema/index.ts
|
|
6
6
|
var schema_exports = /* @__PURE__ */ __exportAll({
|
|
@@ -10,4 +10,4 @@ var schema_exports = /* @__PURE__ */ __exportAll({
|
|
|
10
10
|
|
|
11
11
|
//#endregion
|
|
12
12
|
export { schema_exports as t };
|
|
13
|
-
//# sourceMappingURL=schema-
|
|
13
|
+
//# sourceMappingURL=schema-BqBlUZtb.mjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"schema-
|
|
1
|
+
{"version":3,"file":"schema-BqBlUZtb.mjs","names":[],"sources":["../src/schema/index.ts"],"sourcesContent":["export { SchemaRegistry, SchemaError } from \"./registry.js\";\nexport { BlockTypeRegistry } from \"./block-type-registry.js\";\nexport {\n\tcanonicalBlockFields,\n\tcompareBlockFields,\n\tfingerprintBlockFields,\n\tvalidateBlockFields,\n} from \"./block-type-contract.js\";\nexport { BLOCK_FIELD_TYPES } from \"./block-types.js\";\nexport {\n\texpandCollectionBlockFields,\n\tnormalizeBlocksData,\n\tresolveBlockTypes,\n} from \"./block-values.js\";\nexport type { BlockWriteOptions, ResolvedBlockTypes, StoredBlockValue } from \"./block-values.js\";\nexport type {\n\tBlockFieldDefinition,\n\tBlockFieldOptions,\n\tBlockFieldType,\n\tBlockType,\n\tBlockTypeCompatibility,\n\tBlockTypeDifference,\n\tBlockTypeSource,\n\tBlockTypeVersion,\n\tCreateBlockTypeInput,\n\tUpdateBlockTypeInput,\n\tApplySeedBlockTypeInput,\n\tSeedBlockTypeVersionInput,\n} from \"./block-types.js\";\nexport type {\n\tFieldType,\n\tColumnType,\n\tCollectionSupport,\n\tCollectionSource,\n\tFieldValidation,\n\tFieldWidgetOptions,\n\tUnsupportedFieldType,\n\tCollection,\n\tField,\n\tCreateCollectionInput,\n\tUpdateCollectionInput,\n\tCreateFieldInput,\n\tUpdateFieldInput,\n\tCollectionWithFields,\n} from \"./types.js\";\nexport { FIELD_TYPE_TO_COLUMN, RESERVED_FIELD_SLUGS, RESERVED_COLLECTION_SLUGS } from \"./types.js\";\n\nexport { getCollectionInfo, getCollectionInfoWithDb } from \"./query.js\";\n\nexport {\n\tgenerateZodSchema,\n\tgenerateFieldSchema,\n\tgetCachedSchema,\n\tinvalidateSchemaCache,\n\tclearSchemaCache,\n\tvalidateContent,\n\tgenerateTypeScript,\n} from \"./zod-generator.js\";\n"],"mappings":""}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { t as apiError } from "./error-
|
|
2
|
-
import {
|
|
1
|
+
import { t as apiError } from "./error-BCMgPxdn.mjs";
|
|
2
|
+
import { o as hasScope } from "./api-tokens-DqSlkDVI.mjs";
|
|
3
3
|
|
|
4
4
|
//#region src/auth/scopes.ts
|
|
5
5
|
/**
|
|
@@ -31,4 +31,4 @@ function requireAnyScope(locals, scopes) {
|
|
|
31
31
|
|
|
32
32
|
//#endregion
|
|
33
33
|
export { requireScope as n, requireAnyScope as t };
|
|
34
|
-
//# sourceMappingURL=scopes-
|
|
34
|
+
//# sourceMappingURL=scopes-DNaY7Ey0.mjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"scopes-
|
|
1
|
+
{"version":3,"file":"scopes-DNaY7Ey0.mjs","names":[],"sources":["../src/auth/scopes.ts"],"sourcesContent":["/**\n * Scope enforcement for API token authentication.\n *\n * Routes call `requireScope(locals, \"content:write\")` alongside role checks.\n * Session-authenticated requests have no scope restrictions (implicit full access).\n * Token-authenticated requests must have the required scope (or \"admin\").\n */\n\nimport { apiError } from \"#api/error.js\";\n\nimport { hasScope } from \"./api-tokens.js\";\n\n/**\n * Check if the request has a required scope.\n * Returns a 403 Response if the scope is missing, or null if OK.\n *\n * For session-authenticated users (no tokenScopes), always returns null\n * since session auth has implicit full scope.\n */\nexport function requireScope(locals: { tokenScopes?: string[] }, scope: string): Response | null {\n\t// Session auth = no scope restrictions\n\tif (!locals.tokenScopes) return null;\n\n\tif (hasScope(locals.tokenScopes, scope)) return null;\n\n\treturn apiError(\"INSUFFICIENT_SCOPE\", `Token lacks required scope: ${scope}`, 403);\n}\n\n/** Like {@link requireScope}, but satisfied by any of `scopes`. */\nexport function requireAnyScope(\n\tlocals: { tokenScopes?: string[] },\n\tscopes: readonly string[],\n): Response | null {\n\tconst tokenScopes = locals.tokenScopes;\n\tif (!tokenScopes) return null;\n\tif (scopes.some((scope) => hasScope(tokenScopes, scope))) return null;\n\treturn apiError(\"INSUFFICIENT_SCOPE\", `Token lacks required scope: ${scopes.join(\" or \")}`, 403);\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;AAmBA,SAAgB,aAAa,QAAoC,OAAgC;AAEhG,KAAI,CAAC,OAAO,YAAa,QAAO;AAEhC,KAAI,SAAS,OAAO,aAAa,MAAM,CAAE,QAAO;AAEhD,QAAO,SAAS,sBAAsB,+BAA+B,SAAS,IAAI;;;AAInF,SAAgB,gBACf,QACA,QACkB;CAClB,MAAM,cAAc,OAAO;AAC3B,KAAI,CAAC,YAAa,QAAO;AACzB,KAAI,OAAO,MAAM,UAAU,SAAS,aAAa,MAAM,CAAC,CAAE,QAAO;AACjE,QAAO,SAAS,sBAAsB,+BAA+B,OAAO,KAAK,OAAO,IAAI,IAAI"}
|