emdash 0.40.0 → 0.41.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/action-token-CbKDcPJi.mjs +26 -0
- package/dist/action-token-CbKDcPJi.mjs.map +1 -0
- package/dist/activation-PtniBLt9.mjs +382 -0
- package/dist/activation-PtniBLt9.mjs.map +1 -0
- package/dist/adapters-C_Tf5x90.d.mts +171 -0
- package/dist/adapters-C_Tf5x90.d.mts.map +1 -0
- package/dist/allowed-origins-U1z4TdEZ.mjs +116 -0
- package/dist/allowed-origins-U1z4TdEZ.mjs.map +1 -0
- package/dist/api/route-utils.d.mts +4 -4
- package/dist/api/route-utils.mjs +46 -45
- package/dist/api/route-utils.mjs.map +1 -1
- package/dist/api/schemas/index.d.mts +2 -2
- package/dist/api/schemas/index.mjs +10 -10
- package/dist/api-CXwQkV_m.mjs +5122 -0
- package/dist/api-CXwQkV_m.mjs.map +1 -0
- package/dist/api-tokens-89WlohEN.mjs +166 -0
- package/dist/api-tokens-89WlohEN.mjs.map +1 -0
- package/dist/apply-Do3KNnUk.mjs +1659 -0
- package/dist/apply-Do3KNnUk.mjs.map +1 -0
- package/dist/approvals-CAX9Yw33.mjs +460 -0
- package/dist/approvals-CAX9Yw33.mjs.map +1 -0
- package/dist/artifact-fetch-B9W4CEST.mjs +659 -0
- package/dist/artifact-fetch-B9W4CEST.mjs.map +1 -0
- package/dist/astro/index.d.mts +14 -14
- package/dist/astro/index.mjs +26 -30
- package/dist/astro/index.mjs.map +1 -1
- package/dist/astro/middleware/auth.d.mts +12 -12
- package/dist/astro/middleware/auth.mjs +10 -10
- package/dist/astro/middleware/media-usage-write-fence.mjs +5 -5
- package/dist/astro/middleware/redirect.mjs +7 -7
- package/dist/astro/middleware/request-context.mjs +3 -3
- package/dist/astro/middleware/setup.mjs +1 -1
- package/dist/astro/middleware.d.mts +12 -12
- package/dist/astro/middleware.d.mts.map +1 -1
- package/dist/astro/middleware.mjs +110 -106
- package/dist/astro/middleware.mjs.map +1 -1
- package/dist/astro/routes/api/admin/allowed-domains/_domain_.mjs +14 -14
- package/dist/astro/routes/api/admin/allowed-domains/index.mjs +14 -14
- package/dist/astro/routes/api/admin/api-tokens/_id_.mjs +6 -6
- package/dist/astro/routes/api/admin/api-tokens/index.mjs +7 -7
- package/dist/astro/routes/api/admin/byline-fields/_slug_/usage.mjs +7 -7
- package/dist/astro/routes/api/admin/byline-fields/_slug_.mjs +17 -17
- package/dist/astro/routes/api/admin/byline-fields/index.mjs +17 -17
- package/dist/astro/routes/api/admin/byline-fields/reorder.mjs +17 -17
- package/dist/astro/routes/api/admin/bylines/_id_/index.mjs +23 -23
- package/dist/astro/routes/api/admin/bylines/_id_/translations.mjs +23 -23
- package/dist/astro/routes/api/admin/bylines/index.mjs +23 -23
- package/dist/astro/routes/api/admin/comments/_id_/status.mjs +18 -18
- package/dist/astro/routes/api/admin/comments/_id_.mjs +7 -7
- package/dist/astro/routes/api/admin/comments/bulk.mjs +17 -17
- package/dist/astro/routes/api/admin/comments/counts.mjs +7 -7
- package/dist/astro/routes/api/admin/comments/index.mjs +17 -17
- package/dist/astro/routes/api/admin/hooks/exclusive/_hookName_.mjs +6 -6
- package/dist/astro/routes/api/admin/hooks/exclusive/index.mjs +5 -5
- package/dist/astro/routes/api/admin/media-usage/activation.mjs +20 -20
- package/dist/astro/routes/api/admin/media-usage/collection-deletions/index.mjs +22 -22
- package/dist/astro/routes/api/admin/media-usage/collection-deletions/retry.mjs +22 -22
- package/dist/astro/routes/api/admin/media-usage/progress.mjs +25 -25
- package/dist/astro/routes/api/admin/media-usage/repair.mjs +31 -31
- package/dist/astro/routes/api/admin/media-usage/work/index.mjs +22 -22
- package/dist/astro/routes/api/admin/media-usage/work/retry.mjs +22 -22
- package/dist/astro/routes/api/admin/oauth-clients/_id_.mjs +6 -6
- package/dist/astro/routes/api/admin/oauth-clients/index.mjs +6 -6
- package/dist/astro/routes/api/admin/plugins/_id_/disable.mjs +8 -8
- package/dist/astro/routes/api/admin/plugins/_id_/enable.mjs +8 -8
- package/dist/astro/routes/api/admin/plugins/_id_/index.mjs +72 -68
- package/dist/astro/routes/api/admin/plugins/_id_/index.mjs.map +1 -1
- package/dist/astro/routes/api/admin/plugins/_id_/mcp.mjs +7 -7
- package/dist/astro/routes/api/admin/plugins/_id_/settings.mjs +71 -67
- package/dist/astro/routes/api/admin/plugins/_id_/settings.mjs.map +1 -1
- package/dist/astro/routes/api/admin/plugins/_id_/uninstall.mjs +72 -68
- package/dist/astro/routes/api/admin/plugins/_id_/uninstall.mjs.map +1 -1
- package/dist/astro/routes/api/admin/plugins/_id_/update.mjs +82 -78
- package/dist/astro/routes/api/admin/plugins/_id_/update.mjs.map +1 -1
- package/dist/astro/routes/api/admin/plugins/index.mjs +72 -68
- package/dist/astro/routes/api/admin/plugins/index.mjs.map +1 -1
- package/dist/astro/routes/api/admin/plugins/marketplace/_id_/icon.mjs +5 -5
- package/dist/astro/routes/api/admin/plugins/marketplace/_id_/index.mjs +71 -67
- package/dist/astro/routes/api/admin/plugins/marketplace/_id_/index.mjs.map +1 -1
- package/dist/astro/routes/api/admin/plugins/marketplace/_id_/install.mjs +81 -77
- package/dist/astro/routes/api/admin/plugins/marketplace/_id_/install.mjs.map +1 -1
- package/dist/astro/routes/api/admin/plugins/marketplace/index.mjs +71 -67
- package/dist/astro/routes/api/admin/plugins/marketplace/index.mjs.map +1 -1
- package/dist/astro/routes/api/admin/plugins/registry/_id_/uninstall.mjs +72 -68
- package/dist/astro/routes/api/admin/plugins/registry/_id_/uninstall.mjs.map +1 -1
- package/dist/astro/routes/api/admin/plugins/registry/_id_/update.mjs +83 -79
- package/dist/astro/routes/api/admin/plugins/registry/_id_/update.mjs.map +1 -1
- package/dist/astro/routes/api/admin/plugins/registry/artifact.mjs +9 -9
- package/dist/astro/routes/api/admin/plugins/registry/install.mjs +74 -70
- package/dist/astro/routes/api/admin/plugins/registry/install.mjs.map +1 -1
- package/dist/astro/routes/api/admin/plugins/registry/publisher-handle.mjs +7 -7
- package/dist/astro/routes/api/admin/plugins/registry/verify.mjs +72 -68
- package/dist/astro/routes/api/admin/plugins/registry/verify.mjs.map +1 -1
- package/dist/astro/routes/api/admin/plugins/updates.mjs +71 -67
- package/dist/astro/routes/api/admin/plugins/updates.mjs.map +1 -1
- package/dist/astro/routes/api/admin/scheduled-policy-rejections/_collection_/_id_.mjs +6 -6
- package/dist/astro/routes/api/admin/themes/marketplace/_id_/index.mjs +71 -67
- package/dist/astro/routes/api/admin/themes/marketplace/_id_/index.mjs.map +1 -1
- package/dist/astro/routes/api/admin/themes/marketplace/_id_/thumbnail.mjs +5 -5
- package/dist/astro/routes/api/admin/themes/marketplace/index.mjs +71 -67
- package/dist/astro/routes/api/admin/themes/marketplace/index.mjs.map +1 -1
- package/dist/astro/routes/api/admin/transfer/_...path_.mjs +4 -4
- package/dist/astro/routes/api/admin/transfer/approvals/_id_/approve.mjs +40 -40
- package/dist/astro/routes/api/admin/transfer/approvals/_id_/deny.mjs +40 -40
- package/dist/astro/routes/api/admin/transfer/approvals/index.mjs +42 -42
- package/dist/astro/routes/api/admin/transfer/capabilities.mjs +42 -42
- package/dist/astro/routes/api/admin/transfer/exports/_id_/advance.mjs +42 -42
- package/dist/astro/routes/api/admin/transfer/exports/_id_/archive.mjs +43 -43
- package/dist/astro/routes/api/admin/transfer/exports/_id_/files/_...path_.mjs +43 -43
- package/dist/astro/routes/api/admin/transfer/exports/_id_/index.mjs +42 -42
- package/dist/astro/routes/api/admin/transfer/exports/_id_/manifest.mjs +43 -43
- package/dist/astro/routes/api/admin/transfer/exports/index.mjs +44 -44
- package/dist/astro/routes/api/admin/transfer/imports/_id_/abandon.mjs +42 -42
- package/dist/astro/routes/api/admin/transfer/imports/_id_/advance.mjs +42 -42
- package/dist/astro/routes/api/admin/transfer/imports/_id_/analyze.mjs +44 -44
- package/dist/astro/routes/api/admin/transfer/imports/_id_/cancel.mjs +42 -42
- package/dist/astro/routes/api/admin/transfer/imports/_id_/execute.mjs +44 -44
- package/dist/astro/routes/api/admin/transfer/imports/_id_/files/_...path_.mjs +42 -42
- package/dist/astro/routes/api/admin/transfer/imports/_id_/index.mjs +42 -42
- package/dist/astro/routes/api/admin/transfer/imports/_id_/missing.mjs +44 -44
- package/dist/astro/routes/api/admin/transfer/imports/_id_/plan.mjs +42 -42
- package/dist/astro/routes/api/admin/transfer/imports/_id_/receipt.mjs +42 -42
- package/dist/astro/routes/api/admin/transfer/imports/index.mjs +44 -44
- package/dist/astro/routes/api/admin/users/_id_/disable.mjs +5 -5
- package/dist/astro/routes/api/admin/users/_id_/enable.mjs +4 -4
- package/dist/astro/routes/api/admin/users/_id_/index.mjs +15 -15
- package/dist/astro/routes/api/admin/users/_id_/send-recovery.mjs +6 -6
- package/dist/astro/routes/api/admin/users/index.mjs +14 -14
- package/dist/astro/routes/api/auth/dev-bypass.mjs +6 -6
- package/dist/astro/routes/api/auth/invite/accept.mjs +4 -4
- package/dist/astro/routes/api/auth/invite/complete.mjs +18 -18
- package/dist/astro/routes/api/auth/invite/index.mjs +16 -16
- package/dist/astro/routes/api/auth/invite/register-options.mjs +17 -17
- package/dist/astro/routes/api/auth/logout.mjs +5 -5
- package/dist/astro/routes/api/auth/magic-link/send.mjs +18 -18
- package/dist/astro/routes/api/auth/magic-link/verify.mjs +14 -14
- package/dist/astro/routes/api/auth/me.mjs +15 -15
- package/dist/astro/routes/api/auth/mode.mjs +5 -5
- package/dist/astro/routes/api/auth/oauth/_provider_/callback.mjs +3 -3
- package/dist/astro/routes/api/auth/oauth/_provider_.mjs +2 -2
- package/dist/astro/routes/api/auth/passkey/_id_.mjs +14 -14
- package/dist/astro/routes/api/auth/passkey/index.mjs +4 -4
- package/dist/astro/routes/api/auth/passkey/options.mjs +19 -19
- package/dist/astro/routes/api/auth/passkey/register/options.mjs +17 -17
- package/dist/astro/routes/api/auth/passkey/register/verify.mjs +18 -18
- package/dist/astro/routes/api/auth/passkey/verify.mjs +18 -18
- package/dist/astro/routes/api/auth/signup/complete.mjs +18 -18
- package/dist/astro/routes/api/auth/signup/request.mjs +17 -17
- package/dist/astro/routes/api/auth/signup/verify.mjs +4 -4
- package/dist/astro/routes/api/comments/_collection_/_contentId_/index.mjs +12 -12
- package/dist/astro/routes/api/comments/_collection_/_contentId_/reactions.mjs +18 -18
- package/dist/astro/routes/api/content/_collection_/_id_/compare.mjs +5 -5
- package/dist/astro/routes/api/content/_collection_/_id_/discard-draft.mjs +17 -17
- package/dist/astro/routes/api/content/_collection_/_id_/duplicate.mjs +5 -5
- package/dist/astro/routes/api/content/_collection_/_id_/lock.mjs +17 -17
- package/dist/astro/routes/api/content/_collection_/_id_/permanent.mjs +5 -5
- package/dist/astro/routes/api/content/_collection_/_id_/plugin-extensions/_pluginId_/_kind_/_extensionId_.mjs +11 -11
- package/dist/astro/routes/api/content/_collection_/_id_/preview-url.mjs +31 -31
- package/dist/astro/routes/api/content/_collection_/_id_/publish.mjs +17 -17
- package/dist/astro/routes/api/content/_collection_/_id_/references/_relation_/children.d.mts +1 -2
- package/dist/astro/routes/api/content/_collection_/_id_/references/_relation_/children.d.mts.map +1 -1
- package/dist/astro/routes/api/content/_collection_/_id_/references/_relation_/children.mjs +42 -53
- package/dist/astro/routes/api/content/_collection_/_id_/references/_relation_/children.mjs.map +1 -1
- package/dist/astro/routes/api/content/_collection_/_id_/references/_relation_/parents.mjs +34 -29
- package/dist/astro/routes/api/content/_collection_/_id_/references/_relation_/parents.mjs.map +1 -1
- package/dist/astro/routes/api/content/_collection_/_id_/restore.mjs +5 -5
- package/dist/astro/routes/api/content/_collection_/_id_/revisions.mjs +5 -5
- package/dist/astro/routes/api/content/_collection_/_id_/schedule.mjs +17 -17
- package/dist/astro/routes/api/content/_collection_/_id_/terms/_taxonomy_.mjs +25 -24
- package/dist/astro/routes/api/content/_collection_/_id_/terms/_taxonomy_.mjs.map +1 -1
- package/dist/astro/routes/api/content/_collection_/_id_/translations.mjs +5 -5
- package/dist/astro/routes/api/content/_collection_/_id_/unpublish.mjs +17 -17
- package/dist/astro/routes/api/content/_collection_/_id_.d.mts.map +1 -1
- package/dist/astro/routes/api/content/_collection_/_id_.mjs +18 -18
- package/dist/astro/routes/api/content/_collection_/_id_.mjs.map +1 -1
- package/dist/astro/routes/api/content/_collection_/authors.mjs +5 -5
- package/dist/astro/routes/api/content/_collection_/index.mjs +15 -15
- package/dist/astro/routes/api/content/_collection_/trash.mjs +15 -15
- package/dist/astro/routes/api/dashboard.mjs +10 -9
- package/dist/astro/routes/api/dashboard.mjs.map +1 -1
- package/dist/astro/routes/api/dev/emails.mjs +5 -5
- package/dist/astro/routes/api/health.mjs +6 -6
- package/dist/astro/routes/api/import/probe.d.mts +3 -3
- package/dist/astro/routes/api/import/probe.mjs +23 -23
- package/dist/astro/routes/api/import/wordpress/analyze.mjs +6 -6
- package/dist/astro/routes/api/import/wordpress/execute.d.mts +13 -13
- package/dist/astro/routes/api/import/wordpress/execute.mjs +16 -16
- package/dist/astro/routes/api/import/wordpress/media.d.mts +12 -12
- package/dist/astro/routes/api/import/wordpress/media.mjs +19 -19
- package/dist/astro/routes/api/import/wordpress/prepare.mjs +18 -18
- package/dist/astro/routes/api/import/wordpress/rewrite-urls.d.mts +13 -13
- package/dist/astro/routes/api/import/wordpress/rewrite-urls.mjs +28 -28
- package/dist/astro/routes/api/import/wordpress-plugin/analyze.d.mts +1 -1
- package/dist/astro/routes/api/import/wordpress-plugin/analyze.mjs +23 -23
- package/dist/astro/routes/api/import/wordpress-plugin/execute.d.mts +13 -13
- package/dist/astro/routes/api/import/wordpress-plugin/execute.mjs +34 -34
- package/dist/astro/routes/api/manifest.mjs +6 -6
- package/dist/astro/routes/api/mcp.mjs +98 -118
- package/dist/astro/routes/api/mcp.mjs.map +1 -1
- package/dist/astro/routes/api/media/_id_/confirm.mjs +19 -19
- package/dist/astro/routes/api/media/_id_/replace.mjs +16 -16
- package/dist/astro/routes/api/media/_id_/upload.mjs +9 -9
- package/dist/astro/routes/api/media/_id_/usage.mjs +33 -33
- package/dist/astro/routes/api/media/_id_.mjs +31 -31
- package/dist/astro/routes/api/media/asset/_id_/_filename_.mjs +6 -6
- package/dist/astro/routes/api/media/file/_...key_.mjs +9 -9
- package/dist/astro/routes/api/media/folders/_id_.mjs +16 -16
- package/dist/astro/routes/api/media/folders/index.mjs +16 -16
- package/dist/astro/routes/api/media/providers/_providerId_/_itemId_.mjs +5 -5
- package/dist/astro/routes/api/media/providers/_providerId_/index.mjs +5 -5
- package/dist/astro/routes/api/media/providers/index.mjs +5 -5
- package/dist/astro/routes/api/media/upload-url.mjs +18 -18
- package/dist/astro/routes/api/media.mjs +35 -35
- package/dist/astro/routes/api/menus/_name_/items/_id_.mjs +17 -17
- package/dist/astro/routes/api/menus/_name_/items.mjs +17 -17
- package/dist/astro/routes/api/menus/_name_/reorder.mjs +17 -17
- package/dist/astro/routes/api/menus/_name_/translations.mjs +17 -17
- package/dist/astro/routes/api/menus/_name_.mjs +17 -17
- package/dist/astro/routes/api/menus/index.mjs +17 -17
- package/dist/astro/routes/api/oauth/authorize.mjs +6 -6
- package/dist/astro/routes/api/oauth/device/authorize.d.mts +2 -1
- package/dist/astro/routes/api/oauth/device/authorize.d.mts.map +1 -1
- package/dist/astro/routes/api/oauth/device/authorize.mjs +23 -9
- package/dist/astro/routes/api/oauth/device/authorize.mjs.map +1 -1
- package/dist/astro/routes/api/oauth/device/code.mjs +11 -11
- package/dist/astro/routes/api/oauth/device/token.mjs +10 -10
- package/dist/astro/routes/api/oauth/register.mjs +5 -5
- package/dist/astro/routes/api/oauth/token/refresh.mjs +8 -8
- package/dist/astro/routes/api/oauth/token/revoke.mjs +8 -8
- package/dist/astro/routes/api/oauth/token.mjs +8 -8
- package/dist/astro/routes/api/openapi.json.mjs +20 -20
- package/dist/astro/routes/api/plugins/_pluginId_/_...path_.mjs +11 -11
- package/dist/astro/routes/api/redirects/404s/index.mjs +19 -19
- package/dist/astro/routes/api/redirects/404s/summary.mjs +19 -19
- package/dist/astro/routes/api/redirects/_id_.mjs +19 -19
- package/dist/astro/routes/api/redirects/index.mjs +19 -19
- package/dist/astro/routes/api/relations/_id_/index.mjs +34 -29
- package/dist/astro/routes/api/relations/_id_/index.mjs.map +1 -1
- package/dist/astro/routes/api/relations/index.mjs +36 -31
- package/dist/astro/routes/api/relations/index.mjs.map +1 -1
- package/dist/astro/routes/api/revisions/_revisionId_/index.mjs +5 -5
- package/dist/astro/routes/api/revisions/_revisionId_/restore.mjs +5 -5
- package/dist/astro/routes/api/schema/block-types/_slug_/index.mjs +71 -67
- package/dist/astro/routes/api/schema/block-types/_slug_/index.mjs.map +1 -1
- package/dist/astro/routes/api/schema/block-types/_slug_/versions/_version_/activate.mjs +71 -67
- package/dist/astro/routes/api/schema/block-types/_slug_/versions/_version_/activate.mjs.map +1 -1
- package/dist/astro/routes/api/schema/block-types/index.mjs +71 -67
- package/dist/astro/routes/api/schema/block-types/index.mjs.map +1 -1
- package/dist/astro/routes/api/schema/collections/_slug_/fields/_fieldSlug_.mjs +73 -69
- package/dist/astro/routes/api/schema/collections/_slug_/fields/_fieldSlug_.mjs.map +1 -1
- package/dist/astro/routes/api/schema/collections/_slug_/fields/index.mjs +71 -67
- package/dist/astro/routes/api/schema/collections/_slug_/fields/index.mjs.map +1 -1
- package/dist/astro/routes/api/schema/collections/_slug_/fields/reorder.mjs +71 -67
- package/dist/astro/routes/api/schema/collections/_slug_/fields/reorder.mjs.map +1 -1
- package/dist/astro/routes/api/schema/collections/_slug_/index.mjs +71 -67
- package/dist/astro/routes/api/schema/collections/_slug_/index.mjs.map +1 -1
- package/dist/astro/routes/api/schema/collections/index.mjs +71 -67
- package/dist/astro/routes/api/schema/collections/index.mjs.map +1 -1
- package/dist/astro/routes/api/schema/collections/reorder.mjs +71 -67
- package/dist/astro/routes/api/schema/collections/reorder.mjs.map +1 -1
- package/dist/astro/routes/api/schema/index.mjs +16 -16
- package/dist/astro/routes/api/schema/orphans/_slug_.mjs +71 -67
- package/dist/astro/routes/api/schema/orphans/_slug_.mjs.map +1 -1
- package/dist/astro/routes/api/schema/orphans/index.mjs +71 -67
- package/dist/astro/routes/api/schema/orphans/index.mjs.map +1 -1
- package/dist/astro/routes/api/search/enable.mjs +19 -19
- package/dist/astro/routes/api/search/index.mjs +18 -18
- package/dist/astro/routes/api/search/rebuild.mjs +19 -19
- package/dist/astro/routes/api/search/stats.mjs +9 -9
- package/dist/astro/routes/api/search/suggest.mjs +18 -18
- package/dist/astro/routes/api/sections/_slug_.mjs +18 -18
- package/dist/astro/routes/api/sections/index.mjs +18 -18
- package/dist/astro/routes/api/settings/backups/archives/_name_.mjs +7 -7
- package/dist/astro/routes/api/settings/backups/archives/index.mjs +7 -7
- package/dist/astro/routes/api/settings/backups/export.mjs +7 -7
- package/dist/astro/routes/api/settings/backups/index.mjs +8 -8
- package/dist/astro/routes/api/settings/email.mjs +6 -6
- package/dist/astro/routes/api/settings.mjs +21 -21
- package/dist/astro/routes/api/setup/admin-verify.mjs +19 -19
- package/dist/astro/routes/api/setup/admin.mjs +18 -18
- package/dist/astro/routes/api/setup/dev-bypass.mjs +45 -39
- package/dist/astro/routes/api/setup/dev-bypass.mjs.map +1 -1
- package/dist/astro/routes/api/setup/dev-reset.mjs +4 -4
- package/dist/astro/routes/api/setup/index.d.mts.map +1 -1
- package/dist/astro/routes/api/setup/index.mjs +80 -49
- package/dist/astro/routes/api/setup/index.mjs.map +1 -1
- package/dist/astro/routes/api/setup/status.mjs +6 -6
- package/dist/astro/routes/api/snapshot.mjs +9 -9
- package/dist/astro/routes/api/snapshot.mjs.map +1 -1
- package/dist/astro/routes/api/taxonomies/_name_/reorder.mjs +23 -23
- package/dist/astro/routes/api/taxonomies/_name_/terms/_slug_/translations.mjs +23 -23
- package/dist/astro/routes/api/taxonomies/_name_/terms/_slug_.mjs +23 -23
- package/dist/astro/routes/api/taxonomies/_name_/terms/index.mjs +23 -23
- package/dist/astro/routes/api/taxonomies/_name_/translations.mjs +22 -22
- package/dist/astro/routes/api/taxonomies/_name_.mjs +23 -23
- package/dist/astro/routes/api/taxonomies/bulk-tag.mjs +36 -35
- package/dist/astro/routes/api/taxonomies/bulk-tag.mjs.map +1 -1
- package/dist/astro/routes/api/taxonomies/index.mjs +23 -23
- package/dist/astro/routes/api/themes/preview.mjs +6 -6
- package/dist/astro/routes/api/typegen.mjs +8 -8
- package/dist/astro/routes/api/visual-editing/action-token.mjs +6 -6
- package/dist/astro/routes/api/visual-editing/content/_collection_/_id_/publish.mjs +19 -19
- package/dist/astro/routes/api/visual-editing/toolbar-labels.mjs +4 -4
- package/dist/astro/routes/api/well-known/auth.mjs +1 -1
- package/dist/astro/routes/api/well-known/oauth-authorization-server.mjs +2 -2
- package/dist/astro/routes/api/well-known/oauth-protected-resource.mjs +2 -2
- package/dist/astro/routes/api/widget-areas/_name_/reorder.mjs +16 -16
- package/dist/astro/routes/api/widget-areas/_name_/widgets/_id_.mjs +19 -19
- package/dist/astro/routes/api/widget-areas/_name_/widgets.mjs +19 -19
- package/dist/astro/routes/api/widget-areas/_name_.mjs +9 -9
- package/dist/astro/routes/api/widget-areas/index.mjs +19 -19
- package/dist/astro/routes/api/widget-components.mjs +5 -5
- package/dist/astro/routes/robots.txt.mjs +6 -6
- package/dist/astro/routes/sitemap-_collection_.xml.mjs +9 -9
- package/dist/astro/routes/sitemap.xml.mjs +7 -7
- package/dist/astro/types.d.mts +28 -18
- package/dist/astro/types.d.mts.map +1 -1
- package/dist/audit-CrgmE9LE.mjs +127 -0
- package/dist/audit-CrgmE9LE.mjs.map +1 -0
- package/dist/auth/providers/github.d.mts +1 -1
- package/dist/auth/providers/google.d.mts +1 -1
- package/dist/authoritative-records-C2YzIdbu.mjs +5172 -0
- package/dist/authoritative-records-C2YzIdbu.mjs.map +1 -0
- package/dist/authorize-WgdKF8QY.mjs +49 -0
- package/dist/authorize-WgdKF8QY.mjs.map +1 -0
- package/dist/backup-Ck8_lMO3.mjs +246 -0
- package/dist/backup-Ck8_lMO3.mjs.map +1 -0
- package/dist/block-types-BQ90asVI.mjs +132 -0
- package/dist/block-types-BQ90asVI.mjs.map +1 -0
- package/dist/block-values-ACFqgB1D.mjs +175 -0
- package/dist/block-values-ACFqgB1D.mjs.map +1 -0
- package/dist/bundle-Db1iNMv_.mjs +667 -0
- package/dist/bundle-Db1iNMv_.mjs.map +1 -0
- package/dist/byline-BayaYGoj.mjs +909 -0
- package/dist/byline-BayaYGoj.mjs.map +1 -0
- package/dist/byline-fields-B8HH-35f.mjs +254 -0
- package/dist/byline-fields-B8HH-35f.mjs.map +1 -0
- package/dist/byline-fields-hMPjf6Eu.mjs +123 -0
- package/dist/byline-fields-hMPjf6Eu.mjs.map +1 -0
- package/dist/byline-registry-B_EK_TQf.mjs +406 -0
- package/dist/byline-registry-B_EK_TQf.mjs.map +1 -0
- package/dist/bylines-DFAaFXWi.mjs +214 -0
- package/dist/bylines-DFAaFXWi.mjs.map +1 -0
- package/dist/bylines-DkIxUxmr.mjs +232 -0
- package/dist/bylines-DkIxUxmr.mjs.map +1 -0
- package/dist/cache-DkvhQ8XE.mjs +108 -0
- package/dist/cache-DkvhQ8XE.mjs.map +1 -0
- package/dist/canonical-CcSuuTlH.mjs +174 -0
- package/dist/canonical-CcSuuTlH.mjs.map +1 -0
- package/dist/capture-triggers-DJEoOTOq.mjs +362 -0
- package/dist/capture-triggers-DJEoOTOq.mjs.map +1 -0
- package/dist/challenge-store-CvBl81AQ.mjs +51 -0
- package/dist/challenge-store-CvBl81AQ.mjs.map +1 -0
- package/dist/checksum-CClweQzI.mjs +162 -0
- package/dist/checksum-CClweQzI.mjs.map +1 -0
- package/dist/chrome-tags-D5caJwwp.mjs +24 -0
- package/dist/chrome-tags-D5caJwwp.mjs.map +1 -0
- package/dist/chunks-DwBaj8aT.mjs +25 -0
- package/dist/chunks-DwBaj8aT.mjs.map +1 -0
- package/dist/cli/index.mjs +374 -761
- package/dist/cli/index.mjs.map +1 -1
- package/dist/client/cf-access.d.mts +1 -1
- package/dist/client/index.d.mts +18 -18
- package/dist/client/index.mjs +2 -2
- package/dist/collection-deletion-CLCdXsnV.mjs +436 -0
- package/dist/collection-deletion-CLCdXsnV.mjs.map +1 -0
- package/dist/collection-deletion-processor-hNw8x01F.mjs +217 -0
- package/dist/collection-deletion-processor-hNw8x01F.mjs.map +1 -0
- package/dist/collection-slugs-cache-CUuiduLq.mjs +85 -0
- package/dist/collection-slugs-cache-CUuiduLq.mjs.map +1 -0
- package/dist/comment-D2uvL63j.mjs +313 -0
- package/dist/comment-D2uvL63j.mjs.map +1 -0
- package/dist/comment-reaction-DevUuzg4.mjs +85 -0
- package/dist/comment-reaction-DevUuzg4.mjs.map +1 -0
- package/dist/comments-Cq0s7_hO.mjs +195 -0
- package/dist/comments-Cq0s7_hO.mjs.map +1 -0
- package/dist/comments-M4EDYAHw.mjs +99 -0
- package/dist/comments-M4EDYAHw.mjs.map +1 -0
- package/dist/components-CuIGwXMs.mjs +108 -0
- package/dist/components-CuIGwXMs.mjs.map +1 -0
- package/dist/config-52Ea5IWt.d.mts +39 -0
- package/dist/config-52Ea5IWt.d.mts.map +1 -0
- package/dist/config-CCz3xOLc.mjs +242 -0
- package/dist/config-CCz3xOLc.mjs.map +1 -0
- package/dist/config-D3d5Qudq.d.mts +6669 -0
- package/dist/config-D3d5Qudq.d.mts.map +1 -0
- package/dist/content-CbnufDsM.mjs +2018 -0
- package/dist/content-CbnufDsM.mjs.map +1 -0
- package/dist/content-list-query-D_7B1FE5.d.mts +26 -0
- package/dist/content-list-query-D_7B1FE5.d.mts.map +1 -0
- package/dist/content-policy-CYu6K1KB.mjs +46 -0
- package/dist/content-policy-CYu6K1KB.mjs.map +1 -0
- package/dist/content-repair-DlDUgFGp.mjs +442 -0
- package/dist/content-repair-DlDUgFGp.mjs.map +1 -0
- package/dist/context-CGQLA1-a.mjs +1922 -0
- package/dist/context-CGQLA1-a.mjs.map +1 -0
- package/dist/cron-c4D5C5Fx.mjs +284 -0
- package/dist/cron-c4D5C5Fx.mjs.map +1 -0
- package/dist/dashboard-CBq9kmOn.mjs +151 -0
- package/dist/dashboard-CBq9kmOn.mjs.map +1 -0
- package/dist/db/index.d.mts +3 -3
- package/dist/db/index.mjs +1 -1
- package/dist/db/libsql-migrations.d.mts +1 -1
- package/dist/db/libsql-migrations.mjs +4 -4
- package/dist/db/libsql.d.mts +1 -1
- package/dist/db/postgres-migrations.d.mts +1 -1
- package/dist/db/postgres-migrations.mjs +4 -4
- package/dist/db/postgres.d.mts +1 -1
- package/dist/db/sqlite-migrations.d.mts +1 -1
- package/dist/db/sqlite-migrations.mjs +4 -4
- package/dist/db/sqlite.d.mts +1 -1
- package/dist/db/sqlite.mjs +1 -1
- package/dist/default-DPsys51U.mjs +81 -0
- package/dist/default-DPsys51U.mjs.map +1 -0
- package/dist/deferred-tasks-CZ7rzBdo.d.mts +9 -0
- package/dist/deferred-tasks-CZ7rzBdo.d.mts.map +1 -0
- package/dist/dev-typegen-HRxwLRcT.mjs +29 -0
- package/dist/dev-typegen-HRxwLRcT.mjs.map +1 -0
- package/dist/device-flow-OcSqE9uY.mjs +521 -0
- package/dist/device-flow-OcSqE9uY.mjs.map +1 -0
- package/dist/digest-DVZ--cE9.mjs +194 -0
- package/dist/digest-DVZ--cE9.mjs.map +1 -0
- package/dist/direct-executor-DyjAqkpT.mjs +104 -0
- package/dist/direct-executor-DyjAqkpT.mjs.map +1 -0
- package/dist/dist-FPR93_xf.mjs +810 -0
- package/dist/dist-FPR93_xf.mjs.map +1 -0
- package/dist/email-console-DyQIgEnz.mjs +50 -0
- package/dist/email-console-DyQIgEnz.mjs.map +1 -0
- package/dist/email-locale-BYb16rVd.mjs +25 -0
- package/dist/email-locale-BYb16rVd.mjs.map +1 -0
- package/dist/emdash-runtime-CrzxJFmF.mjs +4214 -0
- package/dist/emdash-runtime-CrzxJFmF.mjs.map +1 -0
- package/dist/enrich-DBtCncE2.mjs +194 -0
- package/dist/enrich-DBtCncE2.mjs.map +1 -0
- package/dist/entry-lock-BN5y4YbO.d.mts +4481 -0
- package/dist/entry-lock-BN5y4YbO.d.mts.map +1 -0
- package/dist/entry-lock-BaRBHCsH.mjs +1173 -0
- package/dist/entry-lock-BaRBHCsH.mjs.map +1 -0
- package/dist/entry-lock-C6NcnZPV.mjs +163 -0
- package/dist/entry-lock-C6NcnZPV.mjs.map +1 -0
- package/dist/entry-locks-BTyQLdbC.mjs +167 -0
- package/dist/entry-locks-BTyQLdbC.mjs.map +1 -0
- package/dist/error-BfsNNrIE.mjs +90 -0
- package/dist/error-BfsNNrIE.mjs.map +1 -0
- package/dist/errors-BN1QAnEY.mjs +460 -0
- package/dist/errors-BN1QAnEY.mjs.map +1 -0
- package/dist/errors-Bt3goF8I.mjs +120 -0
- package/dist/errors-Bt3goF8I.mjs.map +1 -0
- package/dist/escape-BveidMa2.mjs +9 -0
- package/dist/escape-BveidMa2.mjs.map +1 -0
- package/dist/fence-Bb_IbCxI.mjs +162 -0
- package/dist/fence-Bb_IbCxI.mjs.map +1 -0
- package/dist/field-defs-cache-CsZctvbu.mjs +77 -0
- package/dist/field-defs-cache-CsZctvbu.mjs.map +1 -0
- package/dist/field-map-6m9rF49t.mjs +83 -0
- package/dist/field-map-6m9rF49t.mjs.map +1 -0
- package/dist/focal-point-CZ3d1wK5.mjs +23 -0
- package/dist/focal-point-CZ3d1wK5.mjs.map +1 -0
- package/dist/fts-manager-CCaZTp8y.mjs +443 -0
- package/dist/fts-manager-CCaZTp8y.mjs.map +1 -0
- package/dist/gc-xowRjczI.mjs +75 -0
- package/dist/gc-xowRjczI.mjs.map +1 -0
- package/dist/hash-COVK27Pc.mjs +37 -0
- package/dist/hash-COVK27Pc.mjs.map +1 -0
- package/dist/hook-result-CYSk0XFe.d.mts +31 -0
- package/dist/hook-result-CYSk0XFe.d.mts.map +1 -0
- package/dist/hreflang-CChPV7jx.mjs +105 -0
- package/dist/hreflang-CChPV7jx.mjs.map +1 -0
- package/dist/hreflang-DRslq3QI.d.mts +50 -0
- package/dist/hreflang-DRslq3QI.d.mts.map +1 -0
- package/dist/http-route-dispatch-CAdp2onn.mjs +339 -0
- package/dist/http-route-dispatch-CAdp2onn.mjs.map +1 -0
- package/dist/identity-NVTOOQyq.mjs +35 -0
- package/dist/identity-NVTOOQyq.mjs.map +1 -0
- package/dist/import-wpSO2N0x.mjs +2020 -0
- package/dist/import-wpSO2N0x.mjs.map +1 -0
- package/dist/index-CDs2wq4X.d.mts +623 -0
- package/dist/index-CDs2wq4X.d.mts.map +1 -0
- package/dist/index.d.mts +24 -24
- package/dist/index.mjs +103 -101
- package/dist/install-finalization-D9R9R-W8.mjs +58 -0
- package/dist/install-finalization-D9R9R-W8.mjs.map +1 -0
- package/dist/keys-Bck6LBfF.mjs +61 -0
- package/dist/keys-Bck6LBfF.mjs.map +1 -0
- package/dist/kinds-CYmRESWj.mjs +974 -0
- package/dist/kinds-CYmRESWj.mjs.map +1 -0
- package/dist/lifecycle-C815ZQfV.mjs +25 -0
- package/dist/lifecycle-C815ZQfV.mjs.map +1 -0
- package/dist/load-D99axixL.mjs +28 -0
- package/dist/load-D99axixL.mjs.map +1 -0
- package/dist/loader-CrRPfkHS.mjs +1197 -0
- package/dist/loader-CrRPfkHS.mjs.map +1 -0
- package/dist/loops-DMKlygqX.mjs +203 -0
- package/dist/loops-DMKlygqX.mjs.map +1 -0
- package/dist/manifest-builder-BQzCHNgB.mjs +189 -0
- package/dist/manifest-builder-BQzCHNgB.mjs.map +1 -0
- package/dist/manifest-schema-Ci2gmd0u.mjs +492 -0
- package/dist/manifest-schema-Ci2gmd0u.mjs.map +1 -0
- package/dist/media/image-endpoint.mjs +1 -1
- package/dist/media/index.d.mts +1 -1
- package/dist/media/index.mjs +4 -4
- package/dist/media/local-runtime.d.mts +14 -14
- package/dist/media/local-runtime.mjs +6 -6
- package/dist/media-BUQePMxP.mjs +373 -0
- package/dist/media-BUQePMxP.mjs.map +1 -0
- package/dist/media-DH8ibNlY.mjs +294 -0
- package/dist/media-DH8ibNlY.mjs.map +1 -0
- package/dist/media-OEIQ3bVc.mjs +408 -0
- package/dist/media-OEIQ3bVc.mjs.map +1 -0
- package/dist/media-allowlist-pYtaBA95.mjs +44 -0
- package/dist/media-allowlist-pYtaBA95.mjs.map +1 -0
- package/dist/media-folders-Bf8_s4de.mjs +210 -0
- package/dist/media-folders-Bf8_s4de.mjs.map +1 -0
- package/dist/media-url-C6klEuNd.mjs +43 -0
- package/dist/media-url-C6klEuNd.mjs.map +1 -0
- package/dist/media-usage-D7Y64m6v.mjs +1629 -0
- package/dist/media-usage-D7Y64m6v.mjs.map +1 -0
- package/dist/media-usage-activation-DrqbmgLA.mjs +78 -0
- package/dist/media-usage-activation-DrqbmgLA.mjs.map +1 -0
- package/dist/media-usage-work-DommYhYA.mjs +152 -0
- package/dist/media-usage-work-DommYhYA.mjs.map +1 -0
- package/dist/media-usage-work-HU63hNDu.mjs +586 -0
- package/dist/media-usage-work-HU63hNDu.mjs.map +1 -0
- package/dist/menus-BQfusWEC.mjs +3608 -0
- package/dist/menus-BQfusWEC.mjs.map +1 -0
- package/dist/menus-BtwjQt5s.mjs +753 -0
- package/dist/menus-BtwjQt5s.mjs.map +1 -0
- package/dist/menus-p_M1V7J_.mjs +139 -0
- package/dist/menus-p_M1V7J_.mjs.map +1 -0
- package/dist/migrations/index.d.mts +1 -1
- package/dist/migrations/index.mjs +3 -3
- package/dist/mime-C94qBG-P.mjs +36 -0
- package/dist/mime-C94qBG-P.mjs.map +1 -0
- package/dist/mode-DpYW3w6U.mjs +23 -0
- package/dist/mode-DpYW3w6U.mjs.map +1 -0
- package/dist/node-sqlite-compat-pWFw0lcc.mjs +46 -0
- package/dist/node-sqlite-compat-pWFw0lcc.mjs.map +1 -0
- package/dist/normalize-DduyxBjf.mjs +191 -0
- package/dist/normalize-DduyxBjf.mjs.map +1 -0
- package/dist/oauth-authorization-DAXsH1H9.mjs +274 -0
- package/dist/oauth-authorization-DAXsH1H9.mjs.map +1 -0
- package/dist/oauth-clients-DENiDQri.mjs +266 -0
- package/dist/oauth-clients-DENiDQri.mjs.map +1 -0
- package/dist/oauth-state-store-y8mEYVq9.mjs +50 -0
- package/dist/oauth-state-store-y8mEYVq9.mjs.map +1 -0
- package/dist/oauth-user-lookup-CtTYAy-O.mjs +26 -0
- package/dist/oauth-user-lookup-CtTYAy-O.mjs.map +1 -0
- package/dist/object-cache/memory.d.mts +1 -1
- package/dist/options-BYa1FgIM.d.mts +81 -0
- package/dist/options-BYa1FgIM.d.mts.map +1 -0
- package/dist/page/index.d.mts +2 -2
- package/dist/page/index.mjs +5 -5
- package/dist/parse-CORGGhHf.mjs +81 -0
- package/dist/parse-CORGGhHf.mjs.map +1 -0
- package/dist/parse-avNM1xWV.d.mts +168 -0
- package/dist/parse-avNM1xWV.d.mts.map +1 -0
- package/dist/passkey-config-Dih5YeIS.mjs +46 -0
- package/dist/passkey-config-Dih5YeIS.mjs.map +1 -0
- package/dist/paths-d51RFm8M.mjs +77 -0
- package/dist/paths-d51RFm8M.mjs.map +1 -0
- package/dist/patterns-CoqlXUvk.mjs +145 -0
- package/dist/patterns-CoqlXUvk.mjs.map +1 -0
- package/dist/placeholder-D2aksPMF.d.mts +306 -0
- package/dist/placeholder-D2aksPMF.d.mts.map +1 -0
- package/dist/plan-DqeZKuaR.mjs +135 -0
- package/dist/plan-DqeZKuaR.mjs.map +1 -0
- package/dist/plugin-test-runtime.d.mts +14 -14
- package/dist/plugin-test-runtime.mjs +110 -107
- package/dist/plugin-types.d.mts +2 -2
- package/dist/plugin-utils.d.mts +12 -12
- package/dist/plugins/adapt-sandbox-entry.d.mts +12 -12
- package/dist/plugins/adapt-sandbox-entry.mjs +3 -3
- package/dist/plugins/host.d.mts +5 -5
- package/dist/plugins/host.mjs +42 -41
- package/dist/plugins-Bb7oqjQA.mjs +277 -0
- package/dist/plugins-Bb7oqjQA.mjs.map +1 -0
- package/dist/policy-BcEqut3n.mjs +45 -0
- package/dist/policy-BcEqut3n.mjs.map +1 -0
- package/dist/portable-text-DXE8ymtD.mjs +307 -0
- package/dist/portable-text-DXE8ymtD.mjs.map +1 -0
- package/dist/preview-DEDWbwA_.mjs +107 -0
- package/dist/preview-DEDWbwA_.mjs.map +1 -0
- package/dist/protocol-BJbTzvwl.d.mts +61 -0
- package/dist/protocol-BJbTzvwl.d.mts.map +1 -0
- package/dist/public-submission-D9c9S14m.mjs +250 -0
- package/dist/public-submission-D9c9S14m.mjs.map +1 -0
- package/dist/public-url-CIRe-2T6.mjs +101 -0
- package/dist/public-url-CIRe-2T6.mjs.map +1 -0
- package/dist/query-BzifXlPS.mjs +1156 -0
- package/dist/query-BzifXlPS.mjs.map +1 -0
- package/dist/query-OzMJ6vJP.mjs +41 -0
- package/dist/query-OzMJ6vJP.mjs.map +1 -0
- package/dist/rate-limit-Csp60Vik.mjs +120 -0
- package/dist/rate-limit-Csp60Vik.mjs.map +1 -0
- package/dist/receipt-B-aU4hpJ.mjs +43 -0
- package/dist/receipt-B-aU4hpJ.mjs.map +1 -0
- package/dist/redirect-CDSw1sU3.mjs +17 -0
- package/dist/redirect-CDSw1sU3.mjs.map +1 -0
- package/dist/redirect-D1ArbO85.mjs +411 -0
- package/dist/redirect-D1ArbO85.mjs.map +1 -0
- package/dist/redirects-BjTwDTsV.mjs +148 -0
- package/dist/redirects-BjTwDTsV.mjs.map +1 -0
- package/dist/redirects-Ck50kH3n.mjs +446 -0
- package/dist/redirects-Ck50kH3n.mjs.map +1 -0
- package/dist/registry/testing.mjs +3 -3
- package/dist/registry-CFcNCayZ.mjs +6754 -0
- package/dist/registry-CFcNCayZ.mjs.map +1 -0
- package/dist/relations-Cfaa1fDl.mjs +776 -0
- package/dist/relations-Cfaa1fDl.mjs.map +1 -0
- package/dist/request-cache-iHRlHx1d.mjs +104 -0
- package/dist/request-cache-iHRlHx1d.mjs.map +1 -0
- package/dist/request-context.d.mts +1 -1
- package/dist/request-meta-D47mqyev.mjs +141 -0
- package/dist/request-meta-D47mqyev.mjs.map +1 -0
- package/dist/resolve-BPE8sMvx.mjs +99 -0
- package/dist/resolve-BPE8sMvx.mjs.map +1 -0
- package/dist/resolve-C0s1E_fH.mjs +199 -0
- package/dist/resolve-C0s1E_fH.mjs.map +1 -0
- package/dist/revision-j1p4-bOj.mjs +302 -0
- package/dist/revision-j1p4-bOj.mjs.map +1 -0
- package/dist/route-wire-C9PJV9aL.mjs +197 -0
- package/dist/route-wire-C9PJV9aL.mjs.map +1 -0
- package/dist/routes-lyYw0mMf.mjs +272 -0
- package/dist/routes-lyYw0mMf.mjs.map +1 -0
- package/dist/runner-B3eyB9Gb.mjs +6121 -0
- package/dist/runner-B3eyB9Gb.mjs.map +1 -0
- package/dist/runner-DoYH2Jcu.d.mts +68 -0
- package/dist/runner-DoYH2Jcu.d.mts.map +1 -0
- package/dist/runtime.d.mts +13 -13
- package/dist/runtime.mjs +3 -3
- package/dist/schema-BAayK46S.mjs +13 -0
- package/dist/schema-BAayK46S.mjs.map +1 -0
- package/dist/schema-Gqcl-8G4.mjs +815 -0
- package/dist/schema-Gqcl-8G4.mjs.map +1 -0
- package/dist/scopes-BqPOKoKf.mjs +34 -0
- package/dist/scopes-BqPOKoKf.mjs.map +1 -0
- package/dist/search-YJKPIEV6.mjs +448 -0
- package/dist/search-YJKPIEV6.mjs.map +1 -0
- package/dist/sections-BR_e-wK5.mjs +346 -0
- package/dist/sections-BR_e-wK5.mjs.map +1 -0
- package/dist/seed/index.d.mts +2 -2
- package/dist/seed/index.mjs +37 -31
- package/dist/seo/index.d.mts +3 -3
- package/dist/seo/index.mjs +22 -21
- package/dist/seo/index.mjs.map +1 -1
- package/dist/seo-Dsj8hy3j.mjs +114 -0
- package/dist/seo-Dsj8hy3j.mjs.map +1 -0
- package/dist/seo-XvH4LNNp.mjs +133 -0
- package/dist/seo-XvH4LNNp.mjs.map +1 -0
- package/dist/service-BsVG05gS.mjs +150 -0
- package/dist/service-BsVG05gS.mjs.map +1 -0
- package/dist/session-user-DgKbYrlj.mjs +51 -0
- package/dist/session-user-DgKbYrlj.mjs.map +1 -0
- package/dist/settings-CNPUntkh.mjs +51 -0
- package/dist/settings-CNPUntkh.mjs.map +1 -0
- package/dist/settings-D5EHi0Tk.mjs +439 -0
- package/dist/settings-D5EHi0Tk.mjs.map +1 -0
- package/dist/settings-DSfE7wOa.mjs +61 -0
- package/dist/settings-DSfE7wOa.mjs.map +1 -0
- package/dist/setup-complete-B8W8sJ9v.mjs +26 -0
- package/dist/setup-complete-B8W8sJ9v.mjs.map +1 -0
- package/dist/setup-nonce-DnSBP260.mjs +25 -0
- package/dist/setup-nonce-DnSBP260.mjs.map +1 -0
- package/dist/site-settings-NGzdrt7O.mjs +50 -0
- package/dist/site-settings-NGzdrt7O.mjs.map +1 -0
- package/dist/site-url-D6JB7tLW.mjs +16 -0
- package/dist/site-url-D6JB7tLW.mjs.map +1 -0
- package/dist/snapshot-CdcwwWAf.mjs +414 -0
- package/dist/snapshot-CdcwwWAf.mjs.map +1 -0
- package/dist/ssrf-Dv0_tRpo.mjs +406 -0
- package/dist/ssrf-Dv0_tRpo.mjs.map +1 -0
- package/dist/stage-CUjhED3P.mjs +662 -0
- package/dist/stage-CUjhED3P.mjs.map +1 -0
- package/dist/staged-C36IWXff.mjs +659 -0
- package/dist/staged-C36IWXff.mjs.map +1 -0
- package/dist/state-CKouMCSY.mjs +153 -0
- package/dist/state-CKouMCSY.mjs.map +1 -0
- package/dist/status-lzyj4Uu7.mjs +30 -0
- package/dist/status-lzyj4Uu7.mjs.map +1 -0
- package/dist/storage/local.d.mts +1 -1
- package/dist/storage/local.mjs +1 -1
- package/dist/storage/s3.d.mts +1 -1
- package/dist/storage/s3.mjs +1 -1
- package/dist/storage-query-B-cWcTjJ.d.mts +1594 -0
- package/dist/storage-query-B-cWcTjJ.d.mts.map +1 -0
- package/dist/tar-DsTXX6ch.mjs +449 -0
- package/dist/tar-DsTXX6ch.mjs.map +1 -0
- package/dist/target-DLQCwp_Z.mjs +27 -0
- package/dist/target-DLQCwp_Z.mjs.map +1 -0
- package/dist/taxonomies-BlAjr4BL.mjs +697 -0
- package/dist/taxonomies-BlAjr4BL.mjs.map +1 -0
- package/dist/taxonomies-Byyo7LOZ.mjs +939 -0
- package/dist/taxonomies-Byyo7LOZ.mjs.map +1 -0
- package/dist/taxonomy-CKDwM61Y.mjs +525 -0
- package/dist/taxonomy-CKDwM61Y.mjs.map +1 -0
- package/dist/tokens-BojXlk49.mjs +171 -0
- package/dist/tokens-BojXlk49.mjs.map +1 -0
- package/dist/transaction-DLPQWik1.mjs +29 -0
- package/dist/transaction-DLPQWik1.mjs.map +1 -0
- package/dist/transfer-XSTh2BCr.mjs +8706 -0
- package/dist/transfer-XSTh2BCr.mjs.map +1 -0
- package/dist/transfer-download-DkoCDA9d.mjs +33 -0
- package/dist/transfer-download-DkoCDA9d.mjs.map +1 -0
- package/dist/transfer-iQ26J-RT.mjs +166 -0
- package/dist/transfer-iQ26J-RT.mjs.map +1 -0
- package/dist/transformations-C7RQabKQ.mjs +196 -0
- package/dist/transformations-C7RQabKQ.mjs.map +1 -0
- package/dist/transport-D3RulfD6.mjs +136 -0
- package/dist/transport-D3RulfD6.mjs.map +1 -0
- package/dist/transport-DhlZlf4D.d.mts +42 -0
- package/dist/transport-DhlZlf4D.d.mts.map +1 -0
- package/dist/trusted-proxy-B6ECOZJc.mjs +51 -0
- package/dist/trusted-proxy-B6ECOZJc.mjs.map +1 -0
- package/dist/turnstile-lqUiY7lP.mjs +53 -0
- package/dist/turnstile-lqUiY7lP.mjs.map +1 -0
- package/dist/types-4Dn9bZhu.mjs +77 -0
- package/dist/types-4Dn9bZhu.mjs.map +1 -0
- package/dist/types-5LSo7PPx.d.mts +85 -0
- package/dist/types-5LSo7PPx.d.mts.map +1 -0
- package/dist/types-BQ3hwYJT.d.mts +896 -0
- package/dist/types-BQ3hwYJT.d.mts.map +1 -0
- package/dist/types-BYEk7qo3.d.mts +198 -0
- package/dist/types-BYEk7qo3.d.mts.map +1 -0
- package/dist/types-CJKsWVFR.mjs +199 -0
- package/dist/types-CJKsWVFR.mjs.map +1 -0
- package/dist/types-Ca_w8mmY.d.mts +363 -0
- package/dist/types-Ca_w8mmY.d.mts.map +1 -0
- package/dist/types-CkE41ZAG.mjs +18 -0
- package/dist/types-CkE41ZAG.mjs.map +1 -0
- package/dist/types-D0aJW2uR.d.mts +1641 -0
- package/dist/types-D0aJW2uR.d.mts.map +1 -0
- package/dist/types-DbpN4Qto.d.mts +372 -0
- package/dist/types-DbpN4Qto.d.mts.map +1 -0
- package/dist/types-ILDI1sdY.mjs +16 -0
- package/dist/types-ILDI1sdY.mjs.map +1 -0
- package/dist/types-OC5c-edM.mjs +22 -0
- package/dist/types-OC5c-edM.mjs.map +1 -0
- package/dist/types-aOOxRSx6.mjs +103 -0
- package/dist/types-aOOxRSx6.mjs.map +1 -0
- package/dist/types-m1WbUffD.d.mts +198 -0
- package/dist/types-m1WbUffD.d.mts.map +1 -0
- package/dist/types-uxLoPBio.d.mts +124 -0
- package/dist/types-uxLoPBio.d.mts.map +1 -0
- package/dist/types-we5uR-tV.d.mts +287 -0
- package/dist/types-we5uR-tV.d.mts.map +1 -0
- package/dist/upload-attempts-DduMy6B0.mjs +32 -0
- package/dist/upload-attempts-DduMy6B0.mjs.map +1 -0
- package/dist/url-pattern-B3EwxAAk.mjs +33 -0
- package/dist/url-pattern-B3EwxAAk.mjs.map +1 -0
- package/dist/user-ElwQjTQT.mjs +171 -0
- package/dist/user-ElwQjTQT.mjs.map +1 -0
- package/dist/utils-BlAXmfOG.mjs +439 -0
- package/dist/utils-BlAXmfOG.mjs.map +1 -0
- package/dist/validate-CH0X5b2c.d.mts +468 -0
- package/dist/validate-CH0X5b2c.d.mts.map +1 -0
- package/dist/validate-CfgRpcjA.mjs +492 -0
- package/dist/validate-CfgRpcjA.mjs.map +1 -0
- package/dist/validation-DvYJtv4k.mjs +218 -0
- package/dist/validation-DvYJtv4k.mjs.map +1 -0
- package/dist/version-DgYjhTud.mjs +9 -0
- package/dist/version-DgYjhTud.mjs.map +1 -0
- package/dist/version-Dq71scUb.mjs +7 -0
- package/dist/version-Dq71scUb.mjs.map +1 -0
- package/dist/widgets-ChFIj0be.mjs +126 -0
- package/dist/widgets-ChFIj0be.mjs.map +1 -0
- package/dist/wxr-taxonomies-CBZMp2YX.mjs +372 -0
- package/dist/wxr-taxonomies-CBZMp2YX.mjs.map +1 -0
- package/dist/wxr-taxonomies-DlKDpWN1.d.mts +34 -0
- package/dist/wxr-taxonomies-DlKDpWN1.d.mts.map +1 -0
- package/dist/zod-generator-DmTKI-Ig.mjs +426 -0
- package/dist/zod-generator-DmTKI-Ig.mjs.map +1 -0
- package/package.json +7 -6
- package/src/api/handlers/content.ts +593 -16
- package/src/api/handlers/device-flow.ts +74 -21
- package/src/api/handlers/index.ts +1 -0
- package/src/api/handlers/manifest.ts +79 -5
- package/src/api/handlers/media-upload.ts +17 -71
- package/src/api/handlers/media.ts +97 -3
- package/src/api/handlers/relations.ts +638 -157
- package/src/api/handlers/revision.ts +30 -0
- package/src/api/handlers/schema.ts +403 -1
- package/src/api/handlers/snapshot.ts +257 -3
- package/src/api/handlers/staged-references.ts +142 -0
- package/src/api/handlers/validate-references.ts +146 -0
- package/src/api/schemas/content.ts +13 -0
- package/src/api/schemas/relations.ts +54 -44
- package/src/api/schemas/schema.ts +14 -0
- package/src/astro/integration/routes.ts +15 -19
- package/src/astro/integration/vite-config.ts +10 -4
- package/src/astro/middleware.ts +1 -0
- package/src/astro/routes/api/content/[collection]/[id]/references/[relation]/children.ts +11 -54
- package/src/astro/routes/api/content/[collection]/[id].ts +3 -1
- package/src/astro/routes/api/oauth/device/authorize.ts +33 -4
- package/src/astro/routes/api/relations/index.ts +4 -4
- package/src/astro/routes/api/schema/collections/[slug]/fields/[fieldSlug].ts +6 -2
- package/src/astro/routes/api/setup/index.ts +66 -23
- package/src/astro/routes/api/snapshot.ts +2 -1
- package/src/astro/types.ts +10 -0
- package/src/cleanup.ts +10 -0
- package/src/cli/commands/export-seed.ts +510 -89
- package/src/components/Columns.astro +3 -1
- package/src/components/Cover.astro +3 -1
- package/src/components/WidgetArea.astro +3 -2
- package/src/database/migrations/086_relations_structural.ts +197 -0
- package/src/database/migrations/087_reference_field_relations.ts +407 -0
- package/src/database/migrations/runner.ts +4 -0
- package/src/database/reference-backfill.ts +141 -0
- package/src/database/repositories/content.ts +43 -8
- package/src/database/repositories/media.ts +40 -1
- package/src/database/repositories/redirect.ts +17 -34
- package/src/database/repositories/relation.ts +620 -208
- package/src/database/repositories/revision.ts +16 -0
- package/src/database/repositories/types.ts +38 -0
- package/src/database/transaction.ts +12 -1
- package/src/database/types.ts +14 -5
- package/src/emdash-runtime.ts +114 -11
- package/src/index.ts +11 -0
- package/src/loader.ts +169 -22
- package/src/mcp/server.ts +13 -48
- package/src/query.ts +455 -25
- package/src/references/field-map.ts +115 -0
- package/src/references/resolve.ts +160 -0
- package/src/references/staged.ts +117 -0
- package/src/references/types.ts +16 -0
- package/src/registry/artifact-fetch.ts +45 -271
- package/src/schema/registry.ts +99 -24
- package/src/schema/types.ts +58 -0
- package/src/schema/zod-generator.ts +67 -1
- package/src/seed/apply.ts +841 -103
- package/src/seed/types.ts +36 -2
- package/src/seed/validate.ts +78 -2
- package/src/transfer/analyze/unique-keys.ts +3 -12
- package/src/transfer/analyze/validate.ts +65 -39
- package/src/transfer/analyze/values.ts +12 -1
- package/src/transfer/export/readers.ts +12 -8
- package/src/transfer/format/columns.ts +26 -6
- package/src/transfer/format/kinds.ts +21 -5
- package/src/transfer/import/context.ts +8 -1
- package/src/transfer/ops/package-index.ts +1 -1
- package/dist/action-token-DYwe4Pk0.mjs +0 -26
- package/dist/action-token-DYwe4Pk0.mjs.map +0 -1
- package/dist/activation-LOkDM5WT.mjs +0 -382
- package/dist/activation-LOkDM5WT.mjs.map +0 -1
- package/dist/adapters-B64LbYcB.d.mts +0 -171
- package/dist/adapters-B64LbYcB.d.mts.map +0 -1
- package/dist/allowed-origins-CHB8oZNM.mjs +0 -116
- package/dist/allowed-origins-CHB8oZNM.mjs.map +0 -1
- package/dist/api-cFFZpyS0.mjs +0 -4718
- package/dist/api-cFFZpyS0.mjs.map +0 -1
- package/dist/api-tokens-s4i4aUp_.mjs +0 -166
- package/dist/api-tokens-s4i4aUp_.mjs.map +0 -1
- package/dist/apply-CoT603H3.mjs +0 -1163
- package/dist/apply-CoT603H3.mjs.map +0 -1
- package/dist/approvals-CqMfNxak.mjs +0 -460
- package/dist/approvals-CqMfNxak.mjs.map +0 -1
- package/dist/artifact-fetch-DZMOGZ3-.mjs +0 -818
- package/dist/artifact-fetch-DZMOGZ3-.mjs.map +0 -1
- package/dist/astro/routes/api/relations/_id_/translations.d.mts +0 -8
- package/dist/astro/routes/api/relations/_id_/translations.d.mts.map +0 -1
- package/dist/astro/routes/api/relations/_id_/translations.mjs +0 -47
- package/dist/astro/routes/api/relations/_id_/translations.mjs.map +0 -1
- package/dist/audit-RfCugiSB.mjs +0 -127
- package/dist/audit-RfCugiSB.mjs.map +0 -1
- package/dist/authoritative-records-CoJvBXAD.mjs +0 -5172
- package/dist/authoritative-records-CoJvBXAD.mjs.map +0 -1
- package/dist/authorize-seCifOMJ.mjs +0 -49
- package/dist/authorize-seCifOMJ.mjs.map +0 -1
- package/dist/backup-CBu0LrXf.mjs +0 -246
- package/dist/backup-CBu0LrXf.mjs.map +0 -1
- package/dist/block-type-registry-DUI_3KxT.mjs +0 -6709
- package/dist/block-type-registry-DUI_3KxT.mjs.map +0 -1
- package/dist/block-types-BmZmLmAD.mjs +0 -132
- package/dist/block-types-BmZmLmAD.mjs.map +0 -1
- package/dist/block-values-C_VIPr5t.mjs +0 -175
- package/dist/block-values-C_VIPr5t.mjs.map +0 -1
- package/dist/byline-DYmkXqvo.mjs +0 -909
- package/dist/byline-DYmkXqvo.mjs.map +0 -1
- package/dist/byline-fields-D28AT-Fh.mjs +0 -123
- package/dist/byline-fields-D28AT-Fh.mjs.map +0 -1
- package/dist/byline-registry-gnKscbQX.mjs +0 -406
- package/dist/byline-registry-gnKscbQX.mjs.map +0 -1
- package/dist/bylines-BPwJqoYH.mjs +0 -232
- package/dist/bylines-BPwJqoYH.mjs.map +0 -1
- package/dist/bylines-ukLaYpVZ.mjs +0 -214
- package/dist/bylines-ukLaYpVZ.mjs.map +0 -1
- package/dist/cache-m7UEkRFV.mjs +0 -108
- package/dist/cache-m7UEkRFV.mjs.map +0 -1
- package/dist/canonical-YhEQezjg.mjs +0 -174
- package/dist/canonical-YhEQezjg.mjs.map +0 -1
- package/dist/capture-triggers-kJyl_yyM.mjs +0 -362
- package/dist/capture-triggers-kJyl_yyM.mjs.map +0 -1
- package/dist/challenge-store-ppU6Uv13.mjs +0 -51
- package/dist/challenge-store-ppU6Uv13.mjs.map +0 -1
- package/dist/checksum-B2IINIlN.mjs +0 -162
- package/dist/checksum-B2IINIlN.mjs.map +0 -1
- package/dist/chrome-tags-DApCQSIk.mjs +0 -24
- package/dist/chrome-tags-DApCQSIk.mjs.map +0 -1
- package/dist/chunks-Dms7Uxbt.mjs +0 -25
- package/dist/chunks-Dms7Uxbt.mjs.map +0 -1
- package/dist/collection-deletion-BIm28mo3.mjs +0 -436
- package/dist/collection-deletion-BIm28mo3.mjs.map +0 -1
- package/dist/collection-deletion-processor-Br6rxs3u.mjs +0 -217
- package/dist/collection-deletion-processor-Br6rxs3u.mjs.map +0 -1
- package/dist/collection-slugs-cache-CjGk__zp.mjs +0 -85
- package/dist/collection-slugs-cache-CjGk__zp.mjs.map +0 -1
- package/dist/comment-CrBl22OF.mjs +0 -313
- package/dist/comment-CrBl22OF.mjs.map +0 -1
- package/dist/comment-reaction-JEQ2Fpd8.mjs +0 -85
- package/dist/comment-reaction-JEQ2Fpd8.mjs.map +0 -1
- package/dist/comments-2ah9du9y.mjs +0 -195
- package/dist/comments-2ah9du9y.mjs.map +0 -1
- package/dist/comments-fHZ8ON9O.mjs +0 -99
- package/dist/comments-fHZ8ON9O.mjs.map +0 -1
- package/dist/components-CXbq7CSM.mjs +0 -108
- package/dist/components-CXbq7CSM.mjs.map +0 -1
- package/dist/config-5ii2haYu.d.mts +0 -6528
- package/dist/config-5ii2haYu.d.mts.map +0 -1
- package/dist/config-IhybvkIQ.mjs +0 -242
- package/dist/config-IhybvkIQ.mjs.map +0 -1
- package/dist/config-Py43JK9r.d.mts +0 -39
- package/dist/config-Py43JK9r.d.mts.map +0 -1
- package/dist/content-DFaIEDj9.mjs +0 -2281
- package/dist/content-DFaIEDj9.mjs.map +0 -1
- package/dist/content-list-query-Dra4Dalc.d.mts +0 -26
- package/dist/content-list-query-Dra4Dalc.d.mts.map +0 -1
- package/dist/content-policy-DFNw91-d.mjs +0 -46
- package/dist/content-policy-DFNw91-d.mjs.map +0 -1
- package/dist/content-repair-Q8IUrpLL.mjs +0 -442
- package/dist/content-repair-Q8IUrpLL.mjs.map +0 -1
- package/dist/context-BeGccdUX.mjs +0 -1921
- package/dist/context-BeGccdUX.mjs.map +0 -1
- package/dist/cron-7DCJwPXq.mjs +0 -284
- package/dist/cron-7DCJwPXq.mjs.map +0 -1
- package/dist/dashboard-DjrB-xxZ.mjs +0 -151
- package/dist/dashboard-DjrB-xxZ.mjs.map +0 -1
- package/dist/default-DQ6vsviu.mjs +0 -81
- package/dist/default-DQ6vsviu.mjs.map +0 -1
- package/dist/deferred-tasks-BPxXUB4x.d.mts +0 -9
- package/dist/deferred-tasks-BPxXUB4x.d.mts.map +0 -1
- package/dist/dev-typegen-CZaPLl3V.mjs +0 -29
- package/dist/dev-typegen-CZaPLl3V.mjs.map +0 -1
- package/dist/device-flow-CRd6DXmW.mjs +0 -466
- package/dist/device-flow-CRd6DXmW.mjs.map +0 -1
- package/dist/digest-BarSh-pN.mjs +0 -194
- package/dist/digest-BarSh-pN.mjs.map +0 -1
- package/dist/direct-executor-BmuFJJZV.mjs +0 -104
- package/dist/direct-executor-BmuFJJZV.mjs.map +0 -1
- package/dist/dist-BNwANFJR.mjs +0 -810
- package/dist/dist-BNwANFJR.mjs.map +0 -1
- package/dist/email-console-bJn3ctqA.mjs +0 -50
- package/dist/email-console-bJn3ctqA.mjs.map +0 -1
- package/dist/email-locale-CN6WAMx0.mjs +0 -25
- package/dist/email-locale-CN6WAMx0.mjs.map +0 -1
- package/dist/emdash-runtime-DAjghyEG.mjs +0 -4186
- package/dist/emdash-runtime-DAjghyEG.mjs.map +0 -1
- package/dist/enrich-Dl3kZ-lP.mjs +0 -194
- package/dist/enrich-Dl3kZ-lP.mjs.map +0 -1
- package/dist/entry-lock-BJYdBfXb.mjs +0 -1097
- package/dist/entry-lock-BJYdBfXb.mjs.map +0 -1
- package/dist/entry-lock-DHQOxN7R.mjs +0 -163
- package/dist/entry-lock-DHQOxN7R.mjs.map +0 -1
- package/dist/entry-lock-DVhCt49A.d.mts +0 -4368
- package/dist/entry-lock-DVhCt49A.d.mts.map +0 -1
- package/dist/entry-locks-D0foLdjQ.mjs +0 -167
- package/dist/entry-locks-D0foLdjQ.mjs.map +0 -1
- package/dist/error-CfvOHP0M.mjs +0 -90
- package/dist/error-CfvOHP0M.mjs.map +0 -1
- package/dist/errors-BF0_LFhW.mjs +0 -460
- package/dist/errors-BF0_LFhW.mjs.map +0 -1
- package/dist/errors-DgE1zJGG.mjs +0 -120
- package/dist/errors-DgE1zJGG.mjs.map +0 -1
- package/dist/escape-CuaZhZvL.mjs +0 -9
- package/dist/escape-CuaZhZvL.mjs.map +0 -1
- package/dist/fence-CMDXJYc_.mjs +0 -162
- package/dist/fence-CMDXJYc_.mjs.map +0 -1
- package/dist/field-defs-cache-HIgBbqZZ.mjs +0 -77
- package/dist/field-defs-cache-HIgBbqZZ.mjs.map +0 -1
- package/dist/focal-point-Gr34o-4o.mjs +0 -23
- package/dist/focal-point-Gr34o-4o.mjs.map +0 -1
- package/dist/fts-manager-S-K0laoS.mjs +0 -443
- package/dist/fts-manager-S-K0laoS.mjs.map +0 -1
- package/dist/gc-DjKY0Ay1.mjs +0 -75
- package/dist/gc-DjKY0Ay1.mjs.map +0 -1
- package/dist/hash-SDAW6zC-.mjs +0 -37
- package/dist/hash-SDAW6zC-.mjs.map +0 -1
- package/dist/hook-result-B5bXDgS2.d.mts +0 -31
- package/dist/hook-result-B5bXDgS2.d.mts.map +0 -1
- package/dist/hreflang-D5uNnsGJ.d.mts +0 -50
- package/dist/hreflang-D5uNnsGJ.d.mts.map +0 -1
- package/dist/hreflang-DMFBL2eb.mjs +0 -105
- package/dist/hreflang-DMFBL2eb.mjs.map +0 -1
- package/dist/http-route-dispatch-BitqzwMy.mjs +0 -339
- package/dist/http-route-dispatch-BitqzwMy.mjs.map +0 -1
- package/dist/identity-IyNWwXr6.mjs +0 -35
- package/dist/identity-IyNWwXr6.mjs.map +0 -1
- package/dist/import-C3JZplWq.mjs +0 -2020
- package/dist/import-C3JZplWq.mjs.map +0 -1
- package/dist/index-D-hdtLe8.d.mts +0 -623
- package/dist/index-D-hdtLe8.d.mts.map +0 -1
- package/dist/install-finalization-DfM1fj5x.mjs +0 -58
- package/dist/install-finalization-DfM1fj5x.mjs.map +0 -1
- package/dist/keys-yxLm5l35.mjs +0 -61
- package/dist/keys-yxLm5l35.mjs.map +0 -1
- package/dist/kinds-CRu_T5T5.mjs +0 -961
- package/dist/kinds-CRu_T5T5.mjs.map +0 -1
- package/dist/lifecycle-BzeGPeQ-.mjs +0 -25
- package/dist/lifecycle-BzeGPeQ-.mjs.map +0 -1
- package/dist/load-XgJiE6_3.mjs +0 -28
- package/dist/load-XgJiE6_3.mjs.map +0 -1
- package/dist/loader-BzqeR1ZN.mjs +0 -1086
- package/dist/loader-BzqeR1ZN.mjs.map +0 -1
- package/dist/loops-BQSzv5Zn.mjs +0 -203
- package/dist/loops-BQSzv5Zn.mjs.map +0 -1
- package/dist/manifest-builder-B8zR-73J.mjs +0 -189
- package/dist/manifest-builder-B8zR-73J.mjs.map +0 -1
- package/dist/manifest-schema-CY3zng_M.mjs +0 -492
- package/dist/manifest-schema-CY3zng_M.mjs.map +0 -1
- package/dist/media-Pu1L6xir.mjs +0 -408
- package/dist/media-Pu1L6xir.mjs.map +0 -1
- package/dist/media-Qp5S3eH3.mjs +0 -355
- package/dist/media-Qp5S3eH3.mjs.map +0 -1
- package/dist/media-allowlist-BSoa9Vvm.mjs +0 -44
- package/dist/media-allowlist-BSoa9Vvm.mjs.map +0 -1
- package/dist/media-folders-BE0oo2eX.mjs +0 -210
- package/dist/media-folders-BE0oo2eX.mjs.map +0 -1
- package/dist/media-h7tOiDLj.mjs +0 -221
- package/dist/media-h7tOiDLj.mjs.map +0 -1
- package/dist/media-url-jArBpzIG.mjs +0 -43
- package/dist/media-url-jArBpzIG.mjs.map +0 -1
- package/dist/media-usage-My-Vi-ex.mjs +0 -1629
- package/dist/media-usage-My-Vi-ex.mjs.map +0 -1
- package/dist/media-usage-activation-HKp7zk7W.mjs +0 -78
- package/dist/media-usage-activation-HKp7zk7W.mjs.map +0 -1
- package/dist/media-usage-work-C2OZLCAd.mjs +0 -586
- package/dist/media-usage-work-C2OZLCAd.mjs.map +0 -1
- package/dist/media-usage-work-DwUNbgvS.mjs +0 -152
- package/dist/media-usage-work-DwUNbgvS.mjs.map +0 -1
- package/dist/menus-BM7BPLOb.mjs +0 -139
- package/dist/menus-BM7BPLOb.mjs.map +0 -1
- package/dist/menus-ITeAbcIF.mjs +0 -753
- package/dist/menus-ITeAbcIF.mjs.map +0 -1
- package/dist/menus-TsSGmSR4.mjs +0 -3608
- package/dist/menus-TsSGmSR4.mjs.map +0 -1
- package/dist/mime-ChLqYwDk.mjs +0 -36
- package/dist/mime-ChLqYwDk.mjs.map +0 -1
- package/dist/mode-CCuKXUci.mjs +0 -23
- package/dist/mode-CCuKXUci.mjs.map +0 -1
- package/dist/node-sqlite-compat-CONMsl-x.mjs +0 -46
- package/dist/node-sqlite-compat-CONMsl-x.mjs.map +0 -1
- package/dist/normalize-CO2P8-iE.mjs +0 -191
- package/dist/normalize-CO2P8-iE.mjs.map +0 -1
- package/dist/oauth-authorization-DlMIL5_h.mjs +0 -274
- package/dist/oauth-authorization-DlMIL5_h.mjs.map +0 -1
- package/dist/oauth-clients-Djq9r_KP.mjs +0 -266
- package/dist/oauth-clients-Djq9r_KP.mjs.map +0 -1
- package/dist/oauth-state-store-BbjnZXNC.mjs +0 -50
- package/dist/oauth-state-store-BbjnZXNC.mjs.map +0 -1
- package/dist/oauth-user-lookup-vue9a64A.mjs +0 -26
- package/dist/oauth-user-lookup-vue9a64A.mjs.map +0 -1
- package/dist/options-SQCHQCPH.d.mts +0 -81
- package/dist/options-SQCHQCPH.d.mts.map +0 -1
- package/dist/parse-CVgO-Qai.d.mts +0 -168
- package/dist/parse-CVgO-Qai.d.mts.map +0 -1
- package/dist/parse-DY6OD1j_.mjs +0 -81
- package/dist/parse-DY6OD1j_.mjs.map +0 -1
- package/dist/passkey-config-X_H8128a.mjs +0 -46
- package/dist/passkey-config-X_H8128a.mjs.map +0 -1
- package/dist/paths-JxokKIbr.mjs +0 -77
- package/dist/paths-JxokKIbr.mjs.map +0 -1
- package/dist/patterns-BhAvqO0S.mjs +0 -145
- package/dist/patterns-BhAvqO0S.mjs.map +0 -1
- package/dist/placeholder-MSEd8gty.d.mts +0 -306
- package/dist/placeholder-MSEd8gty.d.mts.map +0 -1
- package/dist/plan-xjcWrAah.mjs +0 -135
- package/dist/plan-xjcWrAah.mjs.map +0 -1
- package/dist/plugins-DUXUt8B9.mjs +0 -277
- package/dist/plugins-DUXUt8B9.mjs.map +0 -1
- package/dist/policy-CUvwAARc.mjs +0 -45
- package/dist/policy-CUvwAARc.mjs.map +0 -1
- package/dist/portable-text-5O_ZGUjB.mjs +0 -307
- package/dist/portable-text-5O_ZGUjB.mjs.map +0 -1
- package/dist/preview-CIUcPYr6.mjs +0 -107
- package/dist/preview-CIUcPYr6.mjs.map +0 -1
- package/dist/protocol-B97DZaFr.d.mts +0 -61
- package/dist/protocol-B97DZaFr.d.mts.map +0 -1
- package/dist/public-submission-BFBUrqst.mjs +0 -250
- package/dist/public-submission-BFBUrqst.mjs.map +0 -1
- package/dist/public-url-Bn7U0D7-.mjs +0 -101
- package/dist/public-url-Bn7U0D7-.mjs.map +0 -1
- package/dist/query-B48peoRT.mjs +0 -890
- package/dist/query-B48peoRT.mjs.map +0 -1
- package/dist/query-C4IH0uhR.mjs +0 -41
- package/dist/query-C4IH0uhR.mjs.map +0 -1
- package/dist/rate-limit-BZ6nybgc.mjs +0 -120
- package/dist/rate-limit-BZ6nybgc.mjs.map +0 -1
- package/dist/receipt-B4wJj5Jq.mjs +0 -43
- package/dist/receipt-B4wJj5Jq.mjs.map +0 -1
- package/dist/redirect-Cd1E7VUt.mjs +0 -17
- package/dist/redirect-Cd1E7VUt.mjs.map +0 -1
- package/dist/redirect-iJf5fltD.mjs +0 -415
- package/dist/redirect-iJf5fltD.mjs.map +0 -1
- package/dist/redirects-CYu1u1aK.mjs +0 -446
- package/dist/redirects-CYu1u1aK.mjs.map +0 -1
- package/dist/redirects-Cv9apQKj.mjs +0 -148
- package/dist/redirects-Cv9apQKj.mjs.map +0 -1
- package/dist/relation-M4NUCb0b.mjs +0 -334
- package/dist/relation-M4NUCb0b.mjs.map +0 -1
- package/dist/relations-CCif47Oq.mjs +0 -403
- package/dist/relations-CCif47Oq.mjs.map +0 -1
- package/dist/relations-CK9CYUyr.mjs +0 -310
- package/dist/relations-CK9CYUyr.mjs.map +0 -1
- package/dist/request-cache-DzLYKm_x.mjs +0 -104
- package/dist/request-cache-DzLYKm_x.mjs.map +0 -1
- package/dist/request-meta-sZXt3sRo.mjs +0 -141
- package/dist/request-meta-sZXt3sRo.mjs.map +0 -1
- package/dist/resolve-2WbQsCvT.mjs +0 -199
- package/dist/resolve-2WbQsCvT.mjs.map +0 -1
- package/dist/route-wire--1hLuACz.mjs +0 -197
- package/dist/route-wire--1hLuACz.mjs.map +0 -1
- package/dist/routes-CUsM40Cc.mjs +0 -272
- package/dist/routes-CUsM40Cc.mjs.map +0 -1
- package/dist/runner-1y4J9fJB.mjs +0 -5742
- package/dist/runner-1y4J9fJB.mjs.map +0 -1
- package/dist/runner-D5_LzKXI.d.mts +0 -68
- package/dist/runner-D5_LzKXI.d.mts.map +0 -1
- package/dist/schema-BABiRdsH.mjs +0 -13
- package/dist/schema-BABiRdsH.mjs.map +0 -1
- package/dist/schema-Du3MzCG0.mjs +0 -446
- package/dist/schema-Du3MzCG0.mjs.map +0 -1
- package/dist/scopes-Dbk-ElhT.mjs +0 -34
- package/dist/scopes-Dbk-ElhT.mjs.map +0 -1
- package/dist/search-Bt1PL1jf.mjs +0 -448
- package/dist/search-Bt1PL1jf.mjs.map +0 -1
- package/dist/sections-Ddptx_o9.mjs +0 -346
- package/dist/sections-Ddptx_o9.mjs.map +0 -1
- package/dist/seo-CZT2oLtT.mjs +0 -114
- package/dist/seo-CZT2oLtT.mjs.map +0 -1
- package/dist/seo-D5w3-Azy.mjs +0 -133
- package/dist/seo-D5w3-Azy.mjs.map +0 -1
- package/dist/service-DuykXPyW.mjs +0 -150
- package/dist/service-DuykXPyW.mjs.map +0 -1
- package/dist/session-user-BhaVp8w0.mjs +0 -51
- package/dist/session-user-BhaVp8w0.mjs.map +0 -1
- package/dist/settings-2xNYr90o.mjs +0 -51
- package/dist/settings-2xNYr90o.mjs.map +0 -1
- package/dist/settings-CgjRWGW9.mjs +0 -439
- package/dist/settings-CgjRWGW9.mjs.map +0 -1
- package/dist/settings-DYidIB26.mjs +0 -61
- package/dist/settings-DYidIB26.mjs.map +0 -1
- package/dist/setup-complete-bOogcHWG.mjs +0 -26
- package/dist/setup-complete-bOogcHWG.mjs.map +0 -1
- package/dist/setup-nonce-0EGuKM4s.mjs +0 -25
- package/dist/setup-nonce-0EGuKM4s.mjs.map +0 -1
- package/dist/site-settings-DOgRUoFX.mjs +0 -50
- package/dist/site-settings-DOgRUoFX.mjs.map +0 -1
- package/dist/site-url-BU_bbxwj.mjs +0 -16
- package/dist/site-url-BU_bbxwj.mjs.map +0 -1
- package/dist/snapshot-CugwUqKQ.mjs +0 -237
- package/dist/snapshot-CugwUqKQ.mjs.map +0 -1
- package/dist/ssrf-CJUnJymJ.mjs +0 -406
- package/dist/ssrf-CJUnJymJ.mjs.map +0 -1
- package/dist/stage-DgrBz_du.mjs +0 -662
- package/dist/stage-DgrBz_du.mjs.map +0 -1
- package/dist/state-DDiPySSG.mjs +0 -153
- package/dist/state-DDiPySSG.mjs.map +0 -1
- package/dist/status-DZKIG4a9.mjs +0 -30
- package/dist/status-DZKIG4a9.mjs.map +0 -1
- package/dist/storage-query-Bdv7A62k.d.mts +0 -1576
- package/dist/storage-query-Bdv7A62k.d.mts.map +0 -1
- package/dist/tar-_1AgTYFu.mjs +0 -449
- package/dist/tar-_1AgTYFu.mjs.map +0 -1
- package/dist/target-_7pn2Gbg.mjs +0 -27
- package/dist/target-_7pn2Gbg.mjs.map +0 -1
- package/dist/taxonomies-C1IwNe8Q.mjs +0 -697
- package/dist/taxonomies-C1IwNe8Q.mjs.map +0 -1
- package/dist/taxonomies-C_XMoRcX.mjs +0 -939
- package/dist/taxonomies-C_XMoRcX.mjs.map +0 -1
- package/dist/taxonomy-C3Fu1YeH.mjs +0 -525
- package/dist/taxonomy-C3Fu1YeH.mjs.map +0 -1
- package/dist/tokens-u78jETkX.mjs +0 -171
- package/dist/tokens-u78jETkX.mjs.map +0 -1
- package/dist/transaction-BcJO4Tmc.mjs +0 -29
- package/dist/transaction-BcJO4Tmc.mjs.map +0 -1
- package/dist/transfer-BhUCrgDc.mjs +0 -8675
- package/dist/transfer-BhUCrgDc.mjs.map +0 -1
- package/dist/transfer-DIGvR9Af.mjs +0 -166
- package/dist/transfer-DIGvR9Af.mjs.map +0 -1
- package/dist/transfer-download-Pml7RMio.mjs +0 -33
- package/dist/transfer-download-Pml7RMio.mjs.map +0 -1
- package/dist/transformations-9gfpwY65.mjs +0 -196
- package/dist/transformations-9gfpwY65.mjs.map +0 -1
- package/dist/transport-BIfH7_hx.d.mts +0 -42
- package/dist/transport-BIfH7_hx.d.mts.map +0 -1
- package/dist/transport-DKWIq53q.mjs +0 -136
- package/dist/transport-DKWIq53q.mjs.map +0 -1
- package/dist/trusted-proxy-tKiVtyTD.mjs +0 -51
- package/dist/trusted-proxy-tKiVtyTD.mjs.map +0 -1
- package/dist/turnstile-DpsoyOfg.mjs +0 -53
- package/dist/turnstile-DpsoyOfg.mjs.map +0 -1
- package/dist/types-B4sUC2p1.d.mts +0 -198
- package/dist/types-B4sUC2p1.d.mts.map +0 -1
- package/dist/types-B7Lmsh1E.d.mts +0 -887
- package/dist/types-B7Lmsh1E.d.mts.map +0 -1
- package/dist/types-BZakh7Ym.mjs +0 -22
- package/dist/types-BZakh7Ym.mjs.map +0 -1
- package/dist/types-B_CppEmv.d.mts +0 -264
- package/dist/types-B_CppEmv.d.mts.map +0 -1
- package/dist/types-BcrBrE6-.mjs +0 -159
- package/dist/types-BcrBrE6-.mjs.map +0 -1
- package/dist/types-BkUg2yHx.mjs +0 -92
- package/dist/types-BkUg2yHx.mjs.map +0 -1
- package/dist/types-CAZgq9fO.d.mts +0 -124
- package/dist/types-CAZgq9fO.d.mts.map +0 -1
- package/dist/types-Cd-O03VG.d.mts +0 -363
- package/dist/types-Cd-O03VG.d.mts.map +0 -1
- package/dist/types-Cr-Kg-3D.d.mts +0 -1641
- package/dist/types-Cr-Kg-3D.d.mts.map +0 -1
- package/dist/types-D2fvWd1i.d.mts +0 -359
- package/dist/types-D2fvWd1i.d.mts.map +0 -1
- package/dist/types-D7HUsguf.mjs +0 -77
- package/dist/types-D7HUsguf.mjs.map +0 -1
- package/dist/types-DA1Te3Oy.d.mts +0 -198
- package/dist/types-DA1Te3Oy.d.mts.map +0 -1
- package/dist/types-DhV6Q5bP.mjs +0 -18
- package/dist/types-DhV6Q5bP.mjs.map +0 -1
- package/dist/types-DnnVSl6Y.d.mts +0 -85
- package/dist/types-DnnVSl6Y.d.mts.map +0 -1
- package/dist/types-VT4-BugW.mjs +0 -16
- package/dist/types-VT4-BugW.mjs.map +0 -1
- package/dist/upload-attempts-B68ZGNu9.mjs +0 -32
- package/dist/upload-attempts-B68ZGNu9.mjs.map +0 -1
- package/dist/url-pattern-CCeZMGOh.mjs +0 -33
- package/dist/url-pattern-CCeZMGOh.mjs.map +0 -1
- package/dist/user-DDSL-sGw.mjs +0 -171
- package/dist/user-DDSL-sGw.mjs.map +0 -1
- package/dist/utils-DdhmO9w9.mjs +0 -439
- package/dist/utils-DdhmO9w9.mjs.map +0 -1
- package/dist/validate-CHosPEhs.mjs +0 -453
- package/dist/validate-CHosPEhs.mjs.map +0 -1
- package/dist/validate-CM79QXYE.d.mts +0 -432
- package/dist/validate-CM79QXYE.d.mts.map +0 -1
- package/dist/validation-BFecQczG.mjs +0 -218
- package/dist/validation-BFecQczG.mjs.map +0 -1
- package/dist/version-BRZXVifl.mjs +0 -9
- package/dist/version-BRZXVifl.mjs.map +0 -1
- package/dist/version-DUQDHgrf.mjs +0 -7
- package/dist/version-DUQDHgrf.mjs.map +0 -1
- package/dist/widgets-WdV72brA.mjs +0 -126
- package/dist/widgets-WdV72brA.mjs.map +0 -1
- package/dist/wxr-taxonomies-BHTdqkmZ.d.mts +0 -34
- package/dist/wxr-taxonomies-BHTdqkmZ.d.mts.map +0 -1
- package/dist/wxr-taxonomies-DP6ESgMN.mjs +0 -372
- package/dist/wxr-taxonomies-DP6ESgMN.mjs.map +0 -1
- package/dist/zod-generator-D6uE4WiS.mjs +0 -389
- package/dist/zod-generator-D6uE4WiS.mjs.map +0 -1
- package/src/astro/routes/api/relations/[id]/translations.ts +0 -33
- /package/dist/{api-tokens-CE1ECIg0.mjs → api-tokens-FaG1zPsj.mjs} +0 -0
- /package/dist/{ssrf-DpBH7aOt.mjs → ssrf-DZOt8Qof.mjs} +0 -0
package/src/seed/apply.ts
CHANGED
|
@@ -6,10 +6,20 @@
|
|
|
6
6
|
*/
|
|
7
7
|
|
|
8
8
|
import { imageSize } from "image-size";
|
|
9
|
-
import type {
|
|
9
|
+
import type {
|
|
10
|
+
Kysely,
|
|
11
|
+
KyselyPlugin,
|
|
12
|
+
PluginTransformQueryArgs,
|
|
13
|
+
PluginTransformResultArgs,
|
|
14
|
+
QueryResult,
|
|
15
|
+
RootOperationNode,
|
|
16
|
+
UnknownRow,
|
|
17
|
+
} from "kysely";
|
|
10
18
|
import mime from "mime/lite";
|
|
11
19
|
import { ulid } from "ulidx";
|
|
12
20
|
|
|
21
|
+
import { setReferenceSelection } from "../api/handlers/relations.js";
|
|
22
|
+
import { bindReferenceField, createFieldRelation } from "../api/handlers/schema.js";
|
|
13
23
|
import { sanitizeGalleryImages } from "../content/converters/gallery.js";
|
|
14
24
|
import type { DatetimeContextCache } from "../database/content-datetime.js";
|
|
15
25
|
import { BylineRepository } from "../database/repositories/byline.js";
|
|
@@ -23,6 +33,7 @@ import {
|
|
|
23
33
|
saveTaxonomyStructure,
|
|
24
34
|
} from "../database/repositories/taxonomy-def.js";
|
|
25
35
|
import { TaxonomyRepository } from "../database/repositories/taxonomy.js";
|
|
36
|
+
import type { ContentItem } from "../database/repositories/types.js";
|
|
26
37
|
import { withTransaction } from "../database/transaction.js";
|
|
27
38
|
import type { Database } from "../database/types.js";
|
|
28
39
|
import type { MediaValue } from "../fields/types.js";
|
|
@@ -32,16 +43,21 @@ import { markContentMediaUsageCollectionStaleSafely } from "../media/usage/conte
|
|
|
32
43
|
import { coalesceObjectCacheWrites } from "../object-cache/index.js";
|
|
33
44
|
import { BlockTypeRegistry } from "../schema/block-type-registry.js";
|
|
34
45
|
import { normalizeBlocksData, resolveBlockTypes } from "../schema/block-values.js";
|
|
35
|
-
import { SchemaRegistry } from "../schema/registry.js";
|
|
46
|
+
import { SchemaError, SchemaRegistry } from "../schema/registry.js";
|
|
47
|
+
import type { CollectionWithFields, Field } from "../schema/types.js";
|
|
36
48
|
import { FTSManager } from "../search/fts-manager.js";
|
|
37
49
|
import { invalidateSiteSettingsCache, setSiteSettings } from "../settings/index.js";
|
|
38
50
|
import type { SiteSettings } from "../settings/types.js";
|
|
39
51
|
import type { Storage } from "../storage/types.js";
|
|
52
|
+
import { chunks, SQL_BATCH_SIZE } from "../utils/chunks.js";
|
|
40
53
|
import type {
|
|
41
54
|
SeedFile,
|
|
55
|
+
SeedField,
|
|
42
56
|
SeedApplyOptions,
|
|
43
57
|
SeedApplyResult,
|
|
58
|
+
SeedContentEntry,
|
|
44
59
|
SeedCollection,
|
|
60
|
+
SeedRelation,
|
|
45
61
|
SeedTaxonomy,
|
|
46
62
|
SeedTaxonomyTerm,
|
|
47
63
|
SeedMenuItem,
|
|
@@ -99,6 +115,8 @@ async function applyDisplayDateFields(
|
|
|
99
115
|
}
|
|
100
116
|
|
|
101
117
|
const FILE_EXTENSION_PATTERN = /\.([a-z0-9]+)(?:\?|$)/i;
|
|
118
|
+
const SEED_RELATION_NAME_MAX_ATTEMPTS = 5;
|
|
119
|
+
const SEED_RELATION_INSERT_BATCH_SIZE = 10;
|
|
102
120
|
import { findTaxonomyStructureSource, validateSeed } from "./validate.js";
|
|
103
121
|
|
|
104
122
|
/** Pattern to remove file extensions */
|
|
@@ -158,14 +176,90 @@ export async function applySeed(
|
|
|
158
176
|
seed: SeedFile,
|
|
159
177
|
options: SeedApplyOptions = {},
|
|
160
178
|
): Promise<SeedApplyResult> {
|
|
161
|
-
|
|
179
|
+
const { result } = await coalesceObjectCacheWrites(() =>
|
|
180
|
+
applySeedWrites(db, seed, options, null),
|
|
181
|
+
);
|
|
182
|
+
return result;
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
/** Per-call limits for `applySeedWithinBudget`. A limit that is left out is not checked. */
|
|
186
|
+
export interface SeedApplyBudget {
|
|
187
|
+
queries?: number;
|
|
188
|
+
mediaDownloads?: number;
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
/** How many of a seed's items (taxonomy terms, bylines, content entries) exist after a call. */
|
|
192
|
+
export interface SeedApplyProgress {
|
|
193
|
+
done: number;
|
|
194
|
+
total: number;
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
/**
|
|
198
|
+
* Apply a seed over several calls, for a platform that caps the queries or
|
|
199
|
+
* fetches of one request.
|
|
200
|
+
*
|
|
201
|
+
* The limits are thresholds, checked before each taxonomy term, byline and
|
|
202
|
+
* content entry is created and before the phases that follow content. Schema,
|
|
203
|
+
* taxonomy definitions and settings are applied in every call, the item that
|
|
204
|
+
* crosses a threshold finishes, and the phases after content (menus,
|
|
205
|
+
* redirects, widgets, sections) run in one call, so set the limits well below
|
|
206
|
+
* the platform's. A call that stops returns `complete: false`; applying the
|
|
207
|
+
* same seed again continues with the first item not yet created. A call
|
|
208
|
+
* creates at least one item before it stops, so repeated calls finish. A
|
|
209
|
+
* `$media` URL used by entries in different calls is downloaded and stored
|
|
210
|
+
* again, as a new media row, in each of those calls. Requires
|
|
211
|
+
* `onConflict: "skip"`.
|
|
212
|
+
*/
|
|
213
|
+
export async function applySeedWithinBudget(
|
|
214
|
+
db: Kysely<Database>,
|
|
215
|
+
seed: SeedFile,
|
|
216
|
+
options: SeedApplyOptions,
|
|
217
|
+
limits: SeedApplyBudget,
|
|
218
|
+
): Promise<{ result: SeedApplyResult; complete: boolean; progress: SeedApplyProgress }> {
|
|
219
|
+
const budget = new SeedBudget(limits);
|
|
220
|
+
return coalesceObjectCacheWrites(() =>
|
|
221
|
+
applySeedWrites(db.withPlugin(budget), seed, options, budget),
|
|
222
|
+
);
|
|
223
|
+
}
|
|
224
|
+
|
|
225
|
+
/**
|
|
226
|
+
* Counts what a budgeted call spends. As a Kysely plugin it sees every query
|
|
227
|
+
* the call runs, including those inside transactions.
|
|
228
|
+
*/
|
|
229
|
+
class SeedBudget implements KyselyPlugin {
|
|
230
|
+
#queries = 0;
|
|
231
|
+
#mediaDownloads = 0;
|
|
232
|
+
|
|
233
|
+
constructor(private readonly limits: SeedApplyBudget) {}
|
|
234
|
+
|
|
235
|
+
transformQuery(args: PluginTransformQueryArgs): RootOperationNode {
|
|
236
|
+
this.#queries++;
|
|
237
|
+
return args.node;
|
|
238
|
+
}
|
|
239
|
+
|
|
240
|
+
transformResult(args: PluginTransformResultArgs): Promise<QueryResult<UnknownRow>> {
|
|
241
|
+
return Promise.resolve(args.result);
|
|
242
|
+
}
|
|
243
|
+
|
|
244
|
+
countMediaDownload(): void {
|
|
245
|
+
this.#mediaDownloads++;
|
|
246
|
+
}
|
|
247
|
+
|
|
248
|
+
isSpent(): boolean {
|
|
249
|
+
const { queries, mediaDownloads } = this.limits;
|
|
250
|
+
return (
|
|
251
|
+
(queries !== undefined && this.#queries >= queries) ||
|
|
252
|
+
(mediaDownloads !== undefined && this.#mediaDownloads >= mediaDownloads)
|
|
253
|
+
);
|
|
254
|
+
}
|
|
162
255
|
}
|
|
163
256
|
|
|
164
257
|
async function applySeedWrites(
|
|
165
258
|
db: Kysely<Database>,
|
|
166
259
|
seed: SeedFile,
|
|
167
260
|
options: SeedApplyOptions,
|
|
168
|
-
|
|
261
|
+
budget: SeedBudget | null,
|
|
262
|
+
): Promise<{ result: SeedApplyResult; complete: boolean; progress: SeedApplyProgress }> {
|
|
169
263
|
// Validate seed first
|
|
170
264
|
const validation = validateSeed(seed);
|
|
171
265
|
if (!validation.valid) {
|
|
@@ -179,11 +273,16 @@ async function applySeedWrites(
|
|
|
179
273
|
onConflict = "skip",
|
|
180
274
|
} = options;
|
|
181
275
|
|
|
276
|
+
if (budget && onConflict !== "skip") {
|
|
277
|
+
throw new Error('A seed budget requires onConflict: "skip"');
|
|
278
|
+
}
|
|
279
|
+
|
|
182
280
|
// Result counters
|
|
183
281
|
const result: SeedApplyResult = {
|
|
184
282
|
blockTypes: { created: 0, skipped: 0, updated: 0 },
|
|
185
283
|
collections: { created: 0, skipped: 0, updated: 0 },
|
|
186
284
|
fields: { created: 0, skipped: 0, updated: 0 },
|
|
285
|
+
relations: { created: 0, skipped: 0, updated: 0 },
|
|
187
286
|
taxonomies: { created: 0, skipped: 0, terms: 0 },
|
|
188
287
|
bylines: { created: 0, skipped: 0, updated: 0 },
|
|
189
288
|
menus: { created: 0, items: 0 },
|
|
@@ -194,6 +293,13 @@ async function applySeedWrites(
|
|
|
194
293
|
content: { created: 0, skipped: 0, updated: 0 },
|
|
195
294
|
media: { created: 0, skipped: 0 },
|
|
196
295
|
};
|
|
296
|
+
let complete = true;
|
|
297
|
+
const progress: SeedApplyProgress = { done: 0, total: countSeedItems(seed, includeContent) };
|
|
298
|
+
// With a budget, `onConflict` is "skip", so these counters count creations only.
|
|
299
|
+
const mayCreateItem = (): boolean =>
|
|
300
|
+
!budget ||
|
|
301
|
+
result.taxonomies.terms + result.bylines.created + result.content.created === 0 ||
|
|
302
|
+
!budget.isSpent();
|
|
197
303
|
|
|
198
304
|
// Media context for $media resolution
|
|
199
305
|
const mediaContext: MediaContext = {
|
|
@@ -201,16 +307,18 @@ async function applySeedWrites(
|
|
|
201
307
|
storage: storage ?? null,
|
|
202
308
|
skipMediaDownload,
|
|
203
309
|
mediaCache: new Map(), // Cache downloaded media by URL to avoid re-downloading
|
|
310
|
+
budget,
|
|
204
311
|
};
|
|
205
312
|
|
|
206
313
|
// Apply order (critical for foreign keys and references):
|
|
207
314
|
// 1. Site settings
|
|
208
|
-
// 2.
|
|
209
|
-
// 3.
|
|
210
|
-
// 4.
|
|
211
|
-
// 5.
|
|
212
|
-
// 6.
|
|
213
|
-
// 7.
|
|
315
|
+
// 2. Relations (so the fields that name them can resolve)
|
|
316
|
+
// 3. Collections + Fields
|
|
317
|
+
// 4. Taxonomy definitions + Terms
|
|
318
|
+
// 5. Content (so menu refs can resolve)
|
|
319
|
+
// 6. Menus + Menu items (can now resolve content refs)
|
|
320
|
+
// 7. Redirects
|
|
321
|
+
// 8. Widget areas + Widgets
|
|
214
322
|
|
|
215
323
|
// Track seed content IDs for reference resolution (shared across content and menus)
|
|
216
324
|
const seedIdMap = new Map<string, string>(); // seed id -> real entry id
|
|
@@ -257,6 +365,11 @@ async function applySeedWrites(
|
|
|
257
365
|
await applySiteSettings(db, seed.settings, onConflict, result);
|
|
258
366
|
}
|
|
259
367
|
|
|
368
|
+
// 2. Declared relations, before the fields that name them
|
|
369
|
+
if (seed.relations) {
|
|
370
|
+
await applySeedRelations(db, seed.relations, seed.collections ?? [], onConflict, result);
|
|
371
|
+
}
|
|
372
|
+
|
|
260
373
|
if (seed.blockTypes) {
|
|
261
374
|
const registry = new BlockTypeRegistry(db);
|
|
262
375
|
for (const blockType of seed.blockTypes) {
|
|
@@ -268,9 +381,23 @@ async function applySeedWrites(
|
|
|
268
381
|
}
|
|
269
382
|
}
|
|
270
383
|
|
|
271
|
-
//
|
|
384
|
+
// 3. Collections and Fields
|
|
272
385
|
if (seed.collections) {
|
|
273
386
|
const registry = new SchemaRegistry(db);
|
|
387
|
+
const seedCollectionSlugs = new Set(seed.collections.map((collection) => collection.slug));
|
|
388
|
+
const knownRelations = await readRelationEnds(db);
|
|
389
|
+
const relationSlugs = new Set(knownRelations.keys());
|
|
390
|
+
const externalTargetExists = new Map<string, boolean>();
|
|
391
|
+
const pendingRelations: Array<{
|
|
392
|
+
id: string;
|
|
393
|
+
slug: string;
|
|
394
|
+
parent_collection: string;
|
|
395
|
+
child_collection: string;
|
|
396
|
+
parent_label: string;
|
|
397
|
+
parent_label_singular: string | null;
|
|
398
|
+
child_label: string;
|
|
399
|
+
max_children_per_parent: number | null;
|
|
400
|
+
}> = [];
|
|
274
401
|
|
|
275
402
|
for (const collection of seed.collections) {
|
|
276
403
|
// Check if collection exists
|
|
@@ -302,36 +429,9 @@ async function applySeedWrites(
|
|
|
302
429
|
// Update or create fields
|
|
303
430
|
for (const field of collection.fields) {
|
|
304
431
|
const existingField = await registry.getField(collection.slug, field.slug);
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
type: field.type,
|
|
309
|
-
required: field.required || false,
|
|
310
|
-
unique: field.unique || false,
|
|
311
|
-
searchable: field.searchable || false,
|
|
312
|
-
indexed: field.indexed || false,
|
|
313
|
-
defaultValue: field.defaultValue,
|
|
314
|
-
validation: field.validation,
|
|
315
|
-
widget: field.widget,
|
|
316
|
-
options: field.options,
|
|
317
|
-
});
|
|
318
|
-
result.fields.updated++;
|
|
319
|
-
} else {
|
|
320
|
-
await registry.createField(collection.slug, {
|
|
321
|
-
slug: field.slug,
|
|
322
|
-
label: field.label,
|
|
323
|
-
type: field.type,
|
|
324
|
-
required: field.required || false,
|
|
325
|
-
unique: field.unique || false,
|
|
326
|
-
searchable: field.searchable || false,
|
|
327
|
-
indexed: field.indexed || false,
|
|
328
|
-
defaultValue: field.defaultValue,
|
|
329
|
-
validation: field.validation,
|
|
330
|
-
widget: field.widget,
|
|
331
|
-
options: field.options,
|
|
332
|
-
});
|
|
333
|
-
result.fields.created++;
|
|
334
|
-
}
|
|
432
|
+
await upsertSeedField(db, collection.slug, field, existingField, knownRelations);
|
|
433
|
+
if (existingField) result.fields.updated++;
|
|
434
|
+
else result.fields.created++;
|
|
335
435
|
}
|
|
336
436
|
|
|
337
437
|
// Second write: display/date fields, now that fields exist.
|
|
@@ -345,19 +445,71 @@ async function applySeedWrites(
|
|
|
345
445
|
continue;
|
|
346
446
|
}
|
|
347
447
|
|
|
348
|
-
const fields =
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
448
|
+
const fields = [];
|
|
449
|
+
for (const field of collection.fields) {
|
|
450
|
+
let fieldValidation = field.validation;
|
|
451
|
+
// A field naming a relation binds to it; one naming only a target
|
|
452
|
+
// collection gets a relation created for it below.
|
|
453
|
+
const bound = resolveSeedFieldRelation(collection.slug, field, knownRelations);
|
|
454
|
+
const targetCollection =
|
|
455
|
+
!bound &&
|
|
456
|
+
field.type === "reference" &&
|
|
457
|
+
typeof fieldValidation?.targetCollection === "string"
|
|
458
|
+
? fieldValidation.targetCollection
|
|
459
|
+
: undefined;
|
|
460
|
+
if (bound) {
|
|
461
|
+
fieldValidation = { ...fieldValidation, ...bound };
|
|
462
|
+
}
|
|
463
|
+
if (targetCollection) {
|
|
464
|
+
let targetExists = seedCollectionSlugs.has(targetCollection);
|
|
465
|
+
if (!targetExists) {
|
|
466
|
+
targetExists = externalTargetExists.get(targetCollection) ?? false;
|
|
467
|
+
if (!externalTargetExists.has(targetCollection)) {
|
|
468
|
+
targetExists = Boolean(await registry.getCollection(targetCollection));
|
|
469
|
+
externalTargetExists.set(targetCollection, targetExists);
|
|
470
|
+
}
|
|
471
|
+
}
|
|
472
|
+
if (!targetExists) {
|
|
473
|
+
throw new SchemaError(
|
|
474
|
+
`Target collection "${targetCollection}" not found`,
|
|
475
|
+
"COLLECTION_NOT_FOUND",
|
|
476
|
+
);
|
|
477
|
+
}
|
|
478
|
+
|
|
479
|
+
const relationId = ulid();
|
|
480
|
+
const relationSlug = allocateSeedRelationName(collection.slug, field.slug, relationSlugs);
|
|
481
|
+
pendingRelations.push({
|
|
482
|
+
id: relationId,
|
|
483
|
+
slug: relationSlug,
|
|
484
|
+
parent_collection: collection.slug,
|
|
485
|
+
child_collection: targetCollection,
|
|
486
|
+
parent_label: collection.label,
|
|
487
|
+
parent_label_singular: collection.labelSingular ?? null,
|
|
488
|
+
child_label: field.label,
|
|
489
|
+
max_children_per_parent: fieldValidation?.multiple ? null : 1,
|
|
490
|
+
});
|
|
491
|
+
fieldValidation = {
|
|
492
|
+
...fieldValidation,
|
|
493
|
+
relation: relationSlug,
|
|
494
|
+
relationSide: "parent",
|
|
495
|
+
};
|
|
496
|
+
}
|
|
497
|
+
|
|
498
|
+
fields.push({
|
|
499
|
+
slug: field.slug,
|
|
500
|
+
label: field.label,
|
|
501
|
+
type: field.type,
|
|
502
|
+
required: field.required || false,
|
|
503
|
+
unique: field.unique || false,
|
|
504
|
+
searchable: field.searchable || false,
|
|
505
|
+
indexed: field.indexed || false,
|
|
506
|
+
translatable: field.translatable,
|
|
507
|
+
defaultValue: field.defaultValue,
|
|
508
|
+
validation: fieldValidation,
|
|
509
|
+
widget: field.widget,
|
|
510
|
+
options: field.options,
|
|
511
|
+
});
|
|
512
|
+
}
|
|
361
513
|
|
|
362
514
|
// Create a fresh seed schema in bulk to stay within D1's query budget.
|
|
363
515
|
await registry.createSeedCollection(
|
|
@@ -383,7 +535,11 @@ async function applySeedWrites(
|
|
|
383
535
|
// the schema exists.
|
|
384
536
|
await applyDisplayDateFields(registry, collection);
|
|
385
537
|
result.collections.created++;
|
|
386
|
-
result.fields.created += fields.length;
|
|
538
|
+
result.fields.created += collection.fields.length;
|
|
539
|
+
}
|
|
540
|
+
|
|
541
|
+
for (const relationBatch of chunks(pendingRelations, SEED_RELATION_INSERT_BATCH_SIZE)) {
|
|
542
|
+
await db.insertInto("_emdash_relations").values(relationBatch).execute();
|
|
387
543
|
}
|
|
388
544
|
}
|
|
389
545
|
|
|
@@ -482,36 +638,47 @@ async function applySeedWrites(
|
|
|
482
638
|
// Create terms (if provided)
|
|
483
639
|
if (includeContent && taxonomy.terms && taxonomy.terms.length > 0) {
|
|
484
640
|
const termRepo = new TaxonomyRepository(db);
|
|
641
|
+
const existingTerms = await findExistingSeedTerms(db, taxonomy.name, taxonomy.terms);
|
|
485
642
|
|
|
486
643
|
if (structure.hierarchical) {
|
|
487
|
-
await applyHierarchicalTerms(
|
|
644
|
+
const applied = await applyHierarchicalTerms(
|
|
488
645
|
termRepo,
|
|
489
646
|
taxonomy.name,
|
|
490
647
|
defLocale,
|
|
491
648
|
taxonomy.terms,
|
|
649
|
+
existingTerms,
|
|
492
650
|
termSeedIdMap,
|
|
493
651
|
result,
|
|
494
652
|
onConflict,
|
|
653
|
+
mayCreateItem,
|
|
495
654
|
);
|
|
655
|
+
progress.done += applied.processed;
|
|
656
|
+
complete = applied.complete;
|
|
496
657
|
} else {
|
|
497
658
|
for (const term of taxonomy.terms) {
|
|
498
659
|
const termLocale = resolveConfiguredLocale(term.locale ?? defLocale);
|
|
499
|
-
const
|
|
500
|
-
|
|
660
|
+
const termKey = seedTermKey(termLocale, term.slug);
|
|
661
|
+
const existingId = existingTerms.get(termKey);
|
|
662
|
+
if (existingId) {
|
|
501
663
|
if (onConflict === "error") {
|
|
502
664
|
throw new Error(
|
|
503
665
|
`Conflict: taxonomy term "${term.slug}" in "${taxonomy.name}" (${termLocale}) already exists`,
|
|
504
666
|
);
|
|
505
667
|
}
|
|
506
668
|
if (onConflict === "update") {
|
|
507
|
-
await termRepo.update(
|
|
669
|
+
await termRepo.update(existingId, {
|
|
508
670
|
label: term.label,
|
|
509
671
|
data: term.description ? { description: term.description } : {},
|
|
510
672
|
});
|
|
511
673
|
result.taxonomies.terms++;
|
|
512
674
|
}
|
|
513
|
-
if (term.id) termSeedIdMap.set(term.id,
|
|
675
|
+
if (term.id) termSeedIdMap.set(term.id, existingId);
|
|
676
|
+
progress.done++;
|
|
514
677
|
} else {
|
|
678
|
+
if (!mayCreateItem()) {
|
|
679
|
+
complete = false;
|
|
680
|
+
break;
|
|
681
|
+
}
|
|
515
682
|
const translationOf = term.translationOf
|
|
516
683
|
? termSeedIdMap.get(term.translationOf)
|
|
517
684
|
: undefined;
|
|
@@ -523,12 +690,15 @@ async function applySeedWrites(
|
|
|
523
690
|
locale: termLocale,
|
|
524
691
|
translationOf,
|
|
525
692
|
});
|
|
693
|
+
existingTerms.set(termKey, created.id);
|
|
526
694
|
if (term.id) termSeedIdMap.set(term.id, created.id);
|
|
527
695
|
result.taxonomies.terms++;
|
|
696
|
+
progress.done++;
|
|
528
697
|
}
|
|
529
698
|
}
|
|
530
699
|
}
|
|
531
700
|
}
|
|
701
|
+
if (!complete) break;
|
|
532
702
|
}
|
|
533
703
|
|
|
534
704
|
// Seeded/updated defs change which taxonomies exist — clear the
|
|
@@ -539,11 +709,15 @@ async function applySeedWrites(
|
|
|
539
709
|
}
|
|
540
710
|
|
|
541
711
|
// 6. Bylines
|
|
542
|
-
if (includeContent && seed.bylines) {
|
|
712
|
+
if (complete && includeContent && seed.bylines) {
|
|
543
713
|
const bylineRepo = new BylineRepository(db);
|
|
714
|
+
const existingBylines = await findExistingSeedBylines(
|
|
715
|
+
db,
|
|
716
|
+
seed.bylines.map((byline) => byline.slug),
|
|
717
|
+
);
|
|
544
718
|
for (const byline of seed.bylines) {
|
|
545
|
-
const
|
|
546
|
-
if (
|
|
719
|
+
const existingId = existingBylines.get(byline.slug);
|
|
720
|
+
if (existingId) {
|
|
547
721
|
if (onConflict === "error") {
|
|
548
722
|
throw new Error(`Conflict: byline "${byline.slug}" already exists`);
|
|
549
723
|
}
|
|
@@ -555,7 +729,7 @@ async function applySeedWrites(
|
|
|
555
729
|
// one untouched.
|
|
556
730
|
const avatar = byline.avatar ? await resolveSeedBylineAvatar(db, byline.avatar) : null;
|
|
557
731
|
try {
|
|
558
|
-
const updated = await bylineRepo.update(
|
|
732
|
+
const updated = await bylineRepo.update(existingId, {
|
|
559
733
|
displayName: byline.displayName,
|
|
560
734
|
bio: byline.bio ?? null,
|
|
561
735
|
websiteUrl: byline.websiteUrl ?? null,
|
|
@@ -563,7 +737,7 @@ async function applySeedWrites(
|
|
|
563
737
|
...(avatar ? { avatarMediaId: avatar.id } : {}),
|
|
564
738
|
});
|
|
565
739
|
// update() returns null (no throw) if the row vanished between
|
|
566
|
-
//
|
|
740
|
+
// the lookup and here; treat that as a failure so the catch
|
|
567
741
|
// cleans up any freshly-created avatar media instead of leaking it.
|
|
568
742
|
if (!updated) {
|
|
569
743
|
throw new Error(`Byline "${byline.slug}" disappeared during update`);
|
|
@@ -574,18 +748,24 @@ async function applySeedWrites(
|
|
|
574
748
|
if (avatar?.created) await deleteMediaRow(db, avatar.id);
|
|
575
749
|
throw error;
|
|
576
750
|
}
|
|
577
|
-
seedBylineIdMap.set(byline.id,
|
|
751
|
+
seedBylineIdMap.set(byline.id, existingId);
|
|
578
752
|
result.bylines.updated++;
|
|
579
753
|
if (avatar?.created) result.media.created++;
|
|
754
|
+
progress.done++;
|
|
580
755
|
continue;
|
|
581
756
|
}
|
|
582
757
|
|
|
583
758
|
// skip
|
|
584
|
-
seedBylineIdMap.set(byline.id,
|
|
759
|
+
seedBylineIdMap.set(byline.id, existingId);
|
|
585
760
|
result.bylines.skipped++;
|
|
761
|
+
progress.done++;
|
|
586
762
|
continue;
|
|
587
763
|
}
|
|
588
764
|
|
|
765
|
+
if (!mayCreateItem()) {
|
|
766
|
+
complete = false;
|
|
767
|
+
break;
|
|
768
|
+
}
|
|
589
769
|
const avatar = byline.avatar ? await resolveSeedBylineAvatar(db, byline.avatar) : null;
|
|
590
770
|
let createdId: string;
|
|
591
771
|
try {
|
|
@@ -602,14 +782,16 @@ async function applySeedWrites(
|
|
|
602
782
|
if (avatar?.created) await deleteMediaRow(db, avatar.id);
|
|
603
783
|
throw error;
|
|
604
784
|
}
|
|
785
|
+
existingBylines.set(byline.slug, createdId);
|
|
605
786
|
seedBylineIdMap.set(byline.id, createdId);
|
|
606
787
|
result.bylines.created++;
|
|
607
788
|
if (avatar?.created) result.media.created++;
|
|
789
|
+
progress.done++;
|
|
608
790
|
}
|
|
609
791
|
}
|
|
610
792
|
|
|
611
793
|
// 7. Content (created before menus so refs can resolve)
|
|
612
|
-
if (includeContent && seed.content) {
|
|
794
|
+
if (complete && includeContent && seed.content) {
|
|
613
795
|
const contentRepo = new ContentRepository(db);
|
|
614
796
|
const schemaRegistry = new SchemaRegistry(db);
|
|
615
797
|
// Settings and fields are all written above, so every entry can share the
|
|
@@ -621,22 +803,20 @@ async function applySeedWrites(
|
|
|
621
803
|
for (const [collectionSlug, entries] of Object.entries(seed.content)) {
|
|
622
804
|
const collectionInfo = await schemaRegistry.getCollectionWithFields(collectionSlug);
|
|
623
805
|
const collectionRoutable = collectionInfo?.routable !== false;
|
|
806
|
+
const referenceFields = referenceFieldsOf(collectionInfo);
|
|
624
807
|
const resolvedBlockTypes = collectionInfo?.fields.some((field) => field.type === "blocks")
|
|
625
808
|
? await resolveBlockTypes(db)
|
|
626
809
|
: undefined;
|
|
810
|
+
const existingEntries = await findExistingSeedEntries(
|
|
811
|
+
contentRepo,
|
|
812
|
+
collectionSlug,
|
|
813
|
+
entries,
|
|
814
|
+
defaultLocale,
|
|
815
|
+
);
|
|
627
816
|
for (const entry of entries) {
|
|
628
|
-
const entrySlug =
|
|
629
|
-
|
|
630
|
-
|
|
631
|
-
// export (which omits `locale`) is filed under the project default
|
|
632
|
-
// rather than `en` (#1421).
|
|
633
|
-
const entryLocale = resolveConfiguredLocale(entry.locale ?? defaultLocale);
|
|
634
|
-
|
|
635
|
-
// Slugful entries use the existing locale-aware key. Slugless seed
|
|
636
|
-
// entries persist their seed ID, which keeps re-application idempotent.
|
|
637
|
-
const existing = entrySlug
|
|
638
|
-
? await contentRepo.findBySlug(collectionSlug, entrySlug, entryLocale)
|
|
639
|
-
: await contentRepo.findById(collectionSlug, entry.id);
|
|
817
|
+
const { slug: entrySlug, locale: entryLocale } = seedEntryIdentity(entry, defaultLocale);
|
|
818
|
+
const entryKey = seedEntryKey(entry, entrySlug, entryLocale);
|
|
819
|
+
const existing = existingEntries.get(entryKey);
|
|
640
820
|
|
|
641
821
|
if (existing) {
|
|
642
822
|
if (onConflict === "error") {
|
|
@@ -664,6 +844,13 @@ async function applySeedWrites(
|
|
|
664
844
|
resolvedBlockTypes,
|
|
665
845
|
);
|
|
666
846
|
}
|
|
847
|
+
// Reference fields are storage-less — route their resolved values to
|
|
848
|
+
// edges and keep them out of the column/revision data.
|
|
849
|
+
const { columnData, edges } = splitReferenceFields(
|
|
850
|
+
collectionSlug,
|
|
851
|
+
referenceFields,
|
|
852
|
+
resolvedData,
|
|
853
|
+
);
|
|
667
854
|
|
|
668
855
|
// Update content + bylines + taxonomies atomically
|
|
669
856
|
const status = entry.status || "published";
|
|
@@ -676,7 +863,7 @@ async function applySeedWrites(
|
|
|
676
863
|
|
|
677
864
|
await trxContentRepo.update(collectionSlug, existing.id, {
|
|
678
865
|
status,
|
|
679
|
-
data:
|
|
866
|
+
data: columnData,
|
|
680
867
|
});
|
|
681
868
|
contentMutated = true;
|
|
682
869
|
|
|
@@ -689,6 +876,7 @@ async function applySeedWrites(
|
|
|
689
876
|
true,
|
|
690
877
|
);
|
|
691
878
|
await applyContentTaxonomies(trx, collectionSlug, existing.id, entry, true);
|
|
879
|
+
await applyContentReferences(trx, collectionSlug, existing.id, edges);
|
|
692
880
|
|
|
693
881
|
// Seed is declarative — when status is "published", promote to a live
|
|
694
882
|
// revision so the admin UI shows "Unpublish" instead of "Save & Publish"
|
|
@@ -701,7 +889,7 @@ async function applySeedWrites(
|
|
|
701
889
|
const draft = await trxRevisionRepo.create({
|
|
702
890
|
collection: collectionSlug,
|
|
703
891
|
entryId: existing.id,
|
|
704
|
-
data:
|
|
892
|
+
data: columnData,
|
|
705
893
|
});
|
|
706
894
|
try {
|
|
707
895
|
await trxContentRepo.setDraftRevision(collectionSlug, existing.id, draft.id);
|
|
@@ -738,6 +926,7 @@ async function applySeedWrites(
|
|
|
738
926
|
|
|
739
927
|
seedIdMap.set(entry.id, existing.id);
|
|
740
928
|
result.content.updated++;
|
|
929
|
+
progress.done++;
|
|
741
930
|
await markSeedContentCollectionStale(collectionSlug);
|
|
742
931
|
continue;
|
|
743
932
|
}
|
|
@@ -745,9 +934,15 @@ async function applySeedWrites(
|
|
|
745
934
|
// skip
|
|
746
935
|
result.content.skipped++;
|
|
747
936
|
seedIdMap.set(entry.id, existing.id);
|
|
937
|
+
progress.done++;
|
|
748
938
|
continue;
|
|
749
939
|
}
|
|
750
940
|
|
|
941
|
+
if (!mayCreateItem()) {
|
|
942
|
+
complete = false;
|
|
943
|
+
break;
|
|
944
|
+
}
|
|
945
|
+
|
|
751
946
|
// Resolve $ref and $media in data
|
|
752
947
|
let resolvedData = await resolveReferences(entry.data, seedIdMap, mediaContext, result);
|
|
753
948
|
if (collectionInfo) {
|
|
@@ -761,6 +956,13 @@ async function applySeedWrites(
|
|
|
761
956
|
resolvedBlockTypes,
|
|
762
957
|
);
|
|
763
958
|
}
|
|
959
|
+
// Reference fields are storage-less — route their resolved values to
|
|
960
|
+
// edges and keep them out of the column/revision data.
|
|
961
|
+
const { columnData, edges } = splitReferenceFields(
|
|
962
|
+
collectionSlug,
|
|
963
|
+
referenceFields,
|
|
964
|
+
resolvedData,
|
|
965
|
+
);
|
|
764
966
|
|
|
765
967
|
// Resolve translationOf: map from seed-local ID to real EmDash ID
|
|
766
968
|
let translationOf: string | undefined;
|
|
@@ -789,7 +991,7 @@ async function applySeedWrites(
|
|
|
789
991
|
type: collectionSlug,
|
|
790
992
|
slug: entrySlug,
|
|
791
993
|
status,
|
|
792
|
-
data:
|
|
994
|
+
data: columnData,
|
|
793
995
|
locale: entryLocale,
|
|
794
996
|
translationOf,
|
|
795
997
|
publishedAt: status === "published" ? new Date().toISOString() : null,
|
|
@@ -804,6 +1006,7 @@ async function applySeedWrites(
|
|
|
804
1006
|
seedBylineIdMap,
|
|
805
1007
|
);
|
|
806
1008
|
await applyContentTaxonomies(trx, collectionSlug, item.id, entry, false);
|
|
1009
|
+
await applyContentReferences(trx, collectionSlug, item.id, edges);
|
|
807
1010
|
|
|
808
1011
|
// Seed is declarative — when status is "published", promote to a live
|
|
809
1012
|
// revision so the admin UI shows "Unpublish" instead of "Save & Publish"
|
|
@@ -828,15 +1031,26 @@ async function applySeedWrites(
|
|
|
828
1031
|
}
|
|
829
1032
|
|
|
830
1033
|
seedIdMap.set(entry.id, created.id);
|
|
1034
|
+
existingEntries.set(entryKey, created);
|
|
831
1035
|
result.content.created++;
|
|
1036
|
+
progress.done++;
|
|
832
1037
|
await markSeedContentCollectionStale(collectionSlug);
|
|
833
1038
|
}
|
|
1039
|
+
if (!complete) break;
|
|
834
1040
|
}
|
|
835
1041
|
} finally {
|
|
836
1042
|
await retryFailedSeedContentStaleMarks();
|
|
837
1043
|
}
|
|
838
1044
|
}
|
|
839
1045
|
|
|
1046
|
+
if (complete && !mayCreateItem()) {
|
|
1047
|
+
complete = false;
|
|
1048
|
+
}
|
|
1049
|
+
if (!complete) {
|
|
1050
|
+
await invalidateSeedCaches();
|
|
1051
|
+
return { result, complete, progress };
|
|
1052
|
+
}
|
|
1053
|
+
|
|
840
1054
|
// 8. Menus and Menu Items (after content so refs can resolve)
|
|
841
1055
|
if (seed.menus) {
|
|
842
1056
|
// seed-local id -> resolved info, used to wire `translationOf` refs.
|
|
@@ -1064,31 +1278,338 @@ async function applySeedWrites(
|
|
|
1064
1278
|
}
|
|
1065
1279
|
}
|
|
1066
1280
|
|
|
1067
|
-
|
|
1068
|
-
|
|
1069
|
-
|
|
1281
|
+
await invalidateSeedCaches();
|
|
1282
|
+
|
|
1283
|
+
return { result, complete, progress };
|
|
1284
|
+
}
|
|
1285
|
+
|
|
1286
|
+
function countSeedItems(seed: SeedFile, includeContent: boolean): number {
|
|
1287
|
+
if (!includeContent) return 0;
|
|
1288
|
+
const terms = (seed.taxonomies ?? []).reduce(
|
|
1289
|
+
(total, taxonomy) => total + (taxonomy.terms?.length ?? 0),
|
|
1290
|
+
0,
|
|
1291
|
+
);
|
|
1292
|
+
const entries = Object.values(seed.content ?? {}).reduce(
|
|
1293
|
+
(total, collectionEntries) => total + collectionEntries.length,
|
|
1294
|
+
0,
|
|
1295
|
+
);
|
|
1296
|
+
return terms + (seed.bylines?.length ?? 0) + entries;
|
|
1297
|
+
}
|
|
1298
|
+
|
|
1299
|
+
function seedTermKey(locale: string, slug: string): string {
|
|
1300
|
+
return `${locale}::${slug}`;
|
|
1301
|
+
}
|
|
1302
|
+
|
|
1303
|
+
/**
|
|
1304
|
+
* Find which of a taxonomy's seed terms already exist, as term ids keyed by
|
|
1305
|
+
* `seedTermKey`. Each query covers a batch of slugs.
|
|
1306
|
+
*/
|
|
1307
|
+
async function findExistingSeedTerms(
|
|
1308
|
+
db: Kysely<Database>,
|
|
1309
|
+
taxonomyName: string,
|
|
1310
|
+
terms: SeedTaxonomyTerm[],
|
|
1311
|
+
): Promise<Map<string, string>> {
|
|
1312
|
+
const existing = new Map<string, string>();
|
|
1313
|
+
for (const batch of chunks([...new Set(terms.map((term) => term.slug))], SQL_BATCH_SIZE)) {
|
|
1314
|
+
const rows = await db
|
|
1315
|
+
.selectFrom("taxonomies")
|
|
1316
|
+
.select(["id", "slug", "locale"])
|
|
1317
|
+
.where("name", "=", taxonomyName)
|
|
1318
|
+
.where("slug", "in", batch)
|
|
1319
|
+
.execute();
|
|
1320
|
+
for (const row of rows) existing.set(seedTermKey(row.locale, row.slug), row.id);
|
|
1321
|
+
}
|
|
1322
|
+
return existing;
|
|
1323
|
+
}
|
|
1324
|
+
|
|
1325
|
+
/**
|
|
1326
|
+
* Find which seed bylines already exist, as byline ids keyed by slug. A slug
|
|
1327
|
+
* in several locales resolves to the lowest locale code, as
|
|
1328
|
+
* `BylineRepository.findBySlug` does. Each query covers a batch of slugs.
|
|
1329
|
+
*/
|
|
1330
|
+
async function findExistingSeedBylines(
|
|
1331
|
+
db: Kysely<Database>,
|
|
1332
|
+
slugs: string[],
|
|
1333
|
+
): Promise<Map<string, string>> {
|
|
1334
|
+
const existing = new Map<string, string>();
|
|
1335
|
+
for (const batch of chunks([...new Set(slugs)], SQL_BATCH_SIZE)) {
|
|
1336
|
+
const rows = await db
|
|
1337
|
+
.selectFrom("_emdash_bylines")
|
|
1338
|
+
.select(["id", "slug"])
|
|
1339
|
+
.where("slug", "in", batch)
|
|
1340
|
+
.orderBy("locale", "asc")
|
|
1341
|
+
.execute();
|
|
1342
|
+
for (const row of rows) {
|
|
1343
|
+
if (!existing.has(row.slug)) existing.set(row.slug, row.id);
|
|
1344
|
+
}
|
|
1345
|
+
}
|
|
1346
|
+
return existing;
|
|
1347
|
+
}
|
|
1348
|
+
|
|
1349
|
+
/**
|
|
1350
|
+
* Invalidate caches that may have been affected by seed data.
|
|
1351
|
+
* Seed creates bylines, redirects, and collections, all of which
|
|
1352
|
+
* have module-level caches in the hot path.
|
|
1353
|
+
*/
|
|
1354
|
+
async function invalidateSeedCaches(): Promise<void> {
|
|
1070
1355
|
const { invalidateBylineCache } = await import("../bylines/index.js");
|
|
1071
1356
|
const { invalidateRedirectCache } = await import("../redirects/cache.js");
|
|
1072
1357
|
const { invalidateUrlPatternCache } = await import("../query.js");
|
|
1073
1358
|
invalidateBylineCache();
|
|
1074
1359
|
invalidateRedirectCache();
|
|
1075
1360
|
invalidateUrlPatternCache();
|
|
1361
|
+
}
|
|
1076
1362
|
|
|
1077
|
-
|
|
1363
|
+
function seedEntryIdentity(
|
|
1364
|
+
entry: SeedContentEntry,
|
|
1365
|
+
defaultLocale: string,
|
|
1366
|
+
): { slug: string | null; locale: string } {
|
|
1367
|
+
return {
|
|
1368
|
+
slug: typeof entry.slug === "string" && entry.slug.trim().length > 0 ? entry.slug : null,
|
|
1369
|
+
// Resolve the entry's locale up front so a non-`en` single-locale
|
|
1370
|
+
// export (which omits `locale`) is filed under the project default
|
|
1371
|
+
// rather than `en`.
|
|
1372
|
+
locale: resolveConfiguredLocale(entry.locale ?? defaultLocale),
|
|
1373
|
+
};
|
|
1374
|
+
}
|
|
1375
|
+
|
|
1376
|
+
/** Every relation the database knows, by slug, with the collections it joins. */
|
|
1377
|
+
type RelationEnds = Map<string, { parentCollection: string; childCollection: string }>;
|
|
1378
|
+
|
|
1379
|
+
async function readRelationEnds(db: Kysely<Database>): Promise<RelationEnds> {
|
|
1380
|
+
const rows = await db
|
|
1381
|
+
.selectFrom("_emdash_relations")
|
|
1382
|
+
.select(["slug", "parent_collection", "child_collection"])
|
|
1383
|
+
.execute();
|
|
1384
|
+
return new Map(
|
|
1385
|
+
rows.map((row) => [
|
|
1386
|
+
row.slug,
|
|
1387
|
+
{ parentCollection: row.parent_collection, childCollection: row.child_collection },
|
|
1388
|
+
]),
|
|
1389
|
+
);
|
|
1078
1390
|
}
|
|
1079
1391
|
|
|
1080
1392
|
/**
|
|
1081
|
-
*
|
|
1393
|
+
* Resolve the relation a seed reference field names, and which end of it this
|
|
1394
|
+
* collection sits on.
|
|
1395
|
+
*
|
|
1396
|
+
* `relationSide` is only needed for a self-referential relation, where both ends
|
|
1397
|
+
* are this collection; otherwise the side follows from which end matches.
|
|
1398
|
+
* `targetCollection` is the collection at the other end, derived rather than
|
|
1399
|
+
* trusted, so a seed cannot declare a target the relation disagrees with.
|
|
1400
|
+
*/
|
|
1401
|
+
function resolveSeedFieldRelation(
|
|
1402
|
+
collectionSlug: string,
|
|
1403
|
+
field: SeedField,
|
|
1404
|
+
knownRelations: RelationEnds,
|
|
1405
|
+
): { relation: string; relationSide: "parent" | "child"; targetCollection: string } | null {
|
|
1406
|
+
if (field.type !== "reference") return null;
|
|
1407
|
+
const named = field.validation?.relation;
|
|
1408
|
+
if (typeof named !== "string" || named.length === 0) return null;
|
|
1409
|
+
|
|
1410
|
+
const relation = knownRelations.get(named);
|
|
1411
|
+
if (!relation) {
|
|
1412
|
+
throw new SchemaError(`Relation "${named}" not found`, "RELATION_NOT_FOUND");
|
|
1413
|
+
}
|
|
1414
|
+
|
|
1415
|
+
const declared = field.validation?.relationSide;
|
|
1416
|
+
const side =
|
|
1417
|
+
declared === "parent" || declared === "child"
|
|
1418
|
+
? declared
|
|
1419
|
+
: relation.parentCollection === collectionSlug
|
|
1420
|
+
? "parent"
|
|
1421
|
+
: "child";
|
|
1422
|
+
|
|
1423
|
+
const end = side === "parent" ? relation.parentCollection : relation.childCollection;
|
|
1424
|
+
if (end !== collectionSlug) {
|
|
1425
|
+
throw new SchemaError(
|
|
1426
|
+
`Relation "${named}" has no ${side} end on collection "${collectionSlug}"`,
|
|
1427
|
+
"VALIDATION_ERROR",
|
|
1428
|
+
);
|
|
1429
|
+
}
|
|
1430
|
+
|
|
1431
|
+
return {
|
|
1432
|
+
relation: named,
|
|
1433
|
+
relationSide: side,
|
|
1434
|
+
targetCollection: side === "parent" ? relation.childCollection : relation.parentCollection,
|
|
1435
|
+
};
|
|
1436
|
+
}
|
|
1437
|
+
|
|
1438
|
+
/**
|
|
1439
|
+
* Create or update the relations a seed declares, before the fields that name
|
|
1440
|
+
* them.
|
|
1441
|
+
*
|
|
1442
|
+
* A relation's two collections are fixed once it exists: changing one would
|
|
1443
|
+
* leave its links pointing into a collection that is no longer an end of it, so
|
|
1444
|
+
* a seed that names different ones fails rather than rewriting the row. Labels
|
|
1445
|
+
* and limits are updated under `onConflict: "update"`.
|
|
1446
|
+
*/
|
|
1447
|
+
async function applySeedRelations(
|
|
1448
|
+
db: Kysely<Database>,
|
|
1449
|
+
relations: SeedRelation[],
|
|
1450
|
+
seedCollections: SeedCollection[],
|
|
1451
|
+
onConflict: "skip" | "update" | "error",
|
|
1452
|
+
result: SeedApplyResult,
|
|
1453
|
+
): Promise<void> {
|
|
1454
|
+
const existing = await readRelationEnds(db);
|
|
1455
|
+
const known = new Set(seedCollections.map((collection) => collection.slug));
|
|
1456
|
+
for (const row of await db.selectFrom("_emdash_collections").select("slug").execute()) {
|
|
1457
|
+
known.add(row.slug);
|
|
1458
|
+
}
|
|
1459
|
+
|
|
1460
|
+
const now = new Date().toISOString();
|
|
1461
|
+
for (const relation of relations) {
|
|
1462
|
+
for (const end of [relation.parentCollection, relation.childCollection]) {
|
|
1463
|
+
if (!known.has(end)) {
|
|
1464
|
+
throw new SchemaError(
|
|
1465
|
+
`Relation "${relation.slug}" names collection "${end}", which does not exist`,
|
|
1466
|
+
"COLLECTION_NOT_FOUND",
|
|
1467
|
+
);
|
|
1468
|
+
}
|
|
1469
|
+
}
|
|
1470
|
+
|
|
1471
|
+
const current = existing.get(relation.slug);
|
|
1472
|
+
if (current) {
|
|
1473
|
+
if (
|
|
1474
|
+
current.parentCollection !== relation.parentCollection ||
|
|
1475
|
+
current.childCollection !== relation.childCollection
|
|
1476
|
+
) {
|
|
1477
|
+
throw new SchemaError(
|
|
1478
|
+
`Relation "${relation.slug}" joins ${current.parentCollection} to ${current.childCollection}; ` +
|
|
1479
|
+
`a relation's collections cannot change`,
|
|
1480
|
+
"RELATION_COLLECTIONS_IMMUTABLE",
|
|
1481
|
+
);
|
|
1482
|
+
}
|
|
1483
|
+
if (onConflict === "error") {
|
|
1484
|
+
throw new Error(`Conflict: relation "${relation.slug}" already exists`);
|
|
1485
|
+
}
|
|
1486
|
+
if (onConflict !== "update") {
|
|
1487
|
+
result.relations.skipped++;
|
|
1488
|
+
continue;
|
|
1489
|
+
}
|
|
1490
|
+
await db
|
|
1491
|
+
.updateTable("_emdash_relations")
|
|
1492
|
+
.set({
|
|
1493
|
+
parent_label: relation.parentLabel,
|
|
1494
|
+
parent_label_singular: relation.parentLabelSingular ?? null,
|
|
1495
|
+
child_label: relation.childLabel,
|
|
1496
|
+
child_label_singular: relation.childLabelSingular ?? null,
|
|
1497
|
+
max_children_per_parent: relation.maxChildrenPerParent ?? null,
|
|
1498
|
+
max_parents_per_child: relation.maxParentsPerChild ?? null,
|
|
1499
|
+
updated_at: now,
|
|
1500
|
+
})
|
|
1501
|
+
.where("slug", "=", relation.slug)
|
|
1502
|
+
.execute();
|
|
1503
|
+
result.relations.updated++;
|
|
1504
|
+
continue;
|
|
1505
|
+
}
|
|
1506
|
+
|
|
1507
|
+
await db
|
|
1508
|
+
.insertInto("_emdash_relations")
|
|
1509
|
+
.values({
|
|
1510
|
+
id: ulid(),
|
|
1511
|
+
slug: relation.slug,
|
|
1512
|
+
parent_collection: relation.parentCollection,
|
|
1513
|
+
child_collection: relation.childCollection,
|
|
1514
|
+
parent_label: relation.parentLabel,
|
|
1515
|
+
parent_label_singular: relation.parentLabelSingular ?? null,
|
|
1516
|
+
child_label: relation.childLabel,
|
|
1517
|
+
child_label_singular: relation.childLabelSingular ?? null,
|
|
1518
|
+
max_children_per_parent: relation.maxChildrenPerParent ?? null,
|
|
1519
|
+
max_parents_per_child: relation.maxParentsPerChild ?? null,
|
|
1520
|
+
created_at: now,
|
|
1521
|
+
updated_at: now,
|
|
1522
|
+
})
|
|
1523
|
+
.execute();
|
|
1524
|
+
existing.set(relation.slug, {
|
|
1525
|
+
parentCollection: relation.parentCollection,
|
|
1526
|
+
childCollection: relation.childCollection,
|
|
1527
|
+
});
|
|
1528
|
+
result.relations.created++;
|
|
1529
|
+
}
|
|
1530
|
+
}
|
|
1531
|
+
|
|
1532
|
+
function allocateSeedRelationName(
|
|
1533
|
+
collectionSlug: string,
|
|
1534
|
+
fieldSlug: string,
|
|
1535
|
+
usedNames: Set<string>,
|
|
1536
|
+
): string {
|
|
1537
|
+
const baseName = `${collectionSlug}_${fieldSlug}`.slice(0, 63);
|
|
1538
|
+
for (let attempt = 0; attempt < SEED_RELATION_NAME_MAX_ATTEMPTS; attempt++) {
|
|
1539
|
+
const suffix = attempt === 0 ? "" : `_${attempt + 1}`;
|
|
1540
|
+
const name = attempt === 0 ? baseName : `${baseName.slice(0, 63 - suffix.length)}${suffix}`;
|
|
1541
|
+
if (!usedNames.has(name)) {
|
|
1542
|
+
usedNames.add(name);
|
|
1543
|
+
return name;
|
|
1544
|
+
}
|
|
1545
|
+
}
|
|
1546
|
+
throw new SchemaError("Could not allocate a unique relation name", "RELATION_NAME_CONFLICT");
|
|
1547
|
+
}
|
|
1548
|
+
|
|
1549
|
+
/**
|
|
1550
|
+
* Slugful entries use the existing locale-aware key. Slugless seed entries
|
|
1551
|
+
* persist their seed ID, which keeps re-application idempotent.
|
|
1552
|
+
*/
|
|
1553
|
+
function seedEntryKey(entry: SeedContentEntry, slug: string | null, locale: string): string {
|
|
1554
|
+
return slug === null ? `id:${entry.id}` : `slug:${locale}:${slug}`;
|
|
1555
|
+
}
|
|
1556
|
+
|
|
1557
|
+
/**
|
|
1558
|
+
* Find which of a collection's seed entries already exist, keyed by
|
|
1559
|
+
* `seedEntryKey`. Each query covers a batch of entries.
|
|
1560
|
+
*/
|
|
1561
|
+
async function findExistingSeedEntries(
|
|
1562
|
+
repo: ContentRepository,
|
|
1563
|
+
collectionSlug: string,
|
|
1564
|
+
entries: SeedContentEntry[],
|
|
1565
|
+
defaultLocale: string,
|
|
1566
|
+
): Promise<Map<string, ContentItem>> {
|
|
1567
|
+
const identities = entries.map((entry) => ({
|
|
1568
|
+
entry,
|
|
1569
|
+
...seedEntryIdentity(entry, defaultLocale),
|
|
1570
|
+
}));
|
|
1571
|
+
const slugsByLocale = new Map<string, string[]>();
|
|
1572
|
+
for (const { slug, locale } of identities) {
|
|
1573
|
+
if (slug === null) continue;
|
|
1574
|
+
const slugs = slugsByLocale.get(locale);
|
|
1575
|
+
if (slugs) slugs.push(slug);
|
|
1576
|
+
else slugsByLocale.set(locale, [slug]);
|
|
1577
|
+
}
|
|
1578
|
+
|
|
1579
|
+
const bySlug = new Map<string, Map<string, ContentItem>>();
|
|
1580
|
+
for (const [locale, slugs] of slugsByLocale) {
|
|
1581
|
+
bySlug.set(locale, await repo.findManyBySlugsInLocale(collectionSlug, slugs, locale));
|
|
1582
|
+
}
|
|
1583
|
+
const byId = await repo.findManyByIds(
|
|
1584
|
+
collectionSlug,
|
|
1585
|
+
identities.filter(({ slug }) => slug === null).map(({ entry }) => entry.id),
|
|
1586
|
+
);
|
|
1587
|
+
|
|
1588
|
+
const existing = new Map<string, ContentItem>();
|
|
1589
|
+
for (const { entry, slug, locale } of identities) {
|
|
1590
|
+
const item = slug === null ? byId.get(entry.id) : bySlug.get(locale)?.get(slug);
|
|
1591
|
+
if (item) existing.set(seedEntryKey(entry, slug, locale), item);
|
|
1592
|
+
}
|
|
1593
|
+
return existing;
|
|
1594
|
+
}
|
|
1595
|
+
|
|
1596
|
+
/**
|
|
1597
|
+
* Apply hierarchical taxonomy terms (parents before children). Stops before
|
|
1598
|
+
* creating a term once `mayCreate` returns false, and returns how many terms
|
|
1599
|
+
* were found or created.
|
|
1082
1600
|
*/
|
|
1083
1601
|
async function applyHierarchicalTerms(
|
|
1084
1602
|
termRepo: TaxonomyRepository,
|
|
1085
1603
|
taxonomyName: string,
|
|
1086
1604
|
defLocale: string,
|
|
1087
1605
|
terms: SeedTaxonomyTerm[],
|
|
1606
|
+
existingTerms: Map<string, string>,
|
|
1088
1607
|
termSeedIdMap: Map<string, string>,
|
|
1089
1608
|
result: SeedApplyResult,
|
|
1090
|
-
onConflict: "skip" | "update" | "error"
|
|
1091
|
-
|
|
1609
|
+
onConflict: "skip" | "update" | "error",
|
|
1610
|
+
mayCreate: () => boolean,
|
|
1611
|
+
): Promise<{ processed: number; complete: boolean }> {
|
|
1612
|
+
let processed = 0;
|
|
1092
1613
|
// "locale::slug" -> id, so the same slug can resolve per locale.
|
|
1093
1614
|
const slugToId = new Map<string, string>();
|
|
1094
1615
|
const resolveTermLocale = (term: SeedTaxonomyTerm) =>
|
|
@@ -1111,24 +1632,26 @@ async function applyHierarchicalTerms(
|
|
|
1111
1632
|
const parentId = term.parent ? slugToId.get(`${termLocale}::${term.parent}`) : undefined;
|
|
1112
1633
|
const translationOf = term.translationOf ? termSeedIdMap.get(term.translationOf) : undefined;
|
|
1113
1634
|
|
|
1114
|
-
const
|
|
1115
|
-
|
|
1635
|
+
const termKey = seedTermKey(termLocale, term.slug);
|
|
1636
|
+
const existingId = existingTerms.get(termKey);
|
|
1637
|
+
if (existingId) {
|
|
1116
1638
|
if (onConflict === "error") {
|
|
1117
1639
|
throw new Error(
|
|
1118
1640
|
`Conflict: taxonomy term "${term.slug}" in "${taxonomyName}" (${termLocale}) already exists`,
|
|
1119
1641
|
);
|
|
1120
1642
|
}
|
|
1121
1643
|
if (onConflict === "update") {
|
|
1122
|
-
await termRepo.update(
|
|
1644
|
+
await termRepo.update(existingId, {
|
|
1123
1645
|
label: term.label,
|
|
1124
1646
|
parentId,
|
|
1125
1647
|
data: term.description ? { description: term.description } : {},
|
|
1126
1648
|
});
|
|
1127
1649
|
result.taxonomies.terms++;
|
|
1128
1650
|
}
|
|
1129
|
-
slugToId.set(
|
|
1130
|
-
if (term.id) termSeedIdMap.set(term.id,
|
|
1651
|
+
slugToId.set(termKey, existingId);
|
|
1652
|
+
if (term.id) termSeedIdMap.set(term.id, existingId);
|
|
1131
1653
|
} else {
|
|
1654
|
+
if (!mayCreate()) return { processed, complete: false };
|
|
1132
1655
|
const created = await termRepo.create({
|
|
1133
1656
|
name: taxonomyName,
|
|
1134
1657
|
slug: term.slug,
|
|
@@ -1138,10 +1661,12 @@ async function applyHierarchicalTerms(
|
|
|
1138
1661
|
locale: termLocale,
|
|
1139
1662
|
translationOf,
|
|
1140
1663
|
});
|
|
1141
|
-
|
|
1664
|
+
existingTerms.set(termKey, created.id);
|
|
1665
|
+
slugToId.set(termKey, created.id);
|
|
1142
1666
|
if (term.id) termSeedIdMap.set(term.id, created.id);
|
|
1143
1667
|
result.taxonomies.terms++;
|
|
1144
1668
|
}
|
|
1669
|
+
processed++;
|
|
1145
1670
|
|
|
1146
1671
|
processedThisPass.push(term.slug + "::" + termLocale);
|
|
1147
1672
|
}
|
|
@@ -1155,6 +1680,7 @@ async function applyHierarchicalTerms(
|
|
|
1155
1680
|
if (remaining.length > 0) {
|
|
1156
1681
|
console.warn(`Could not process ${remaining.length} terms due to missing parents/translations`);
|
|
1157
1682
|
}
|
|
1683
|
+
return { processed, complete: true };
|
|
1158
1684
|
}
|
|
1159
1685
|
|
|
1160
1686
|
/**
|
|
@@ -1210,6 +1736,210 @@ async function applyContentBylines(
|
|
|
1210
1736
|
* Apply taxonomy term assignments to a content entry.
|
|
1211
1737
|
* In update mode, clears existing assignments before re-attaching.
|
|
1212
1738
|
*/
|
|
1739
|
+
/**
|
|
1740
|
+
* Create or update a field from a seed.
|
|
1741
|
+
*
|
|
1742
|
+
* A reference field bound to a relation is storage-less: it persists no column
|
|
1743
|
+
* and its edges live in `_emdash_content_references`. Seeds create fields
|
|
1744
|
+
* through the registry (not the schema handler that owns the relation
|
|
1745
|
+
* lifecycle), so this mirrors the handler — it creates the relation on first
|
|
1746
|
+
* insert (field + relation in one transaction) and preserves the
|
|
1747
|
+
* server-assigned `validation.relation`/`targetCollection` on re-apply, since a
|
|
1748
|
+
* seed's field validation omits them and would otherwise orphan the relation. A
|
|
1749
|
+
* reference field with no `targetCollection` cannot form a relation, so it is
|
|
1750
|
+
* created column-backed, holding a plain entry id.
|
|
1751
|
+
*/
|
|
1752
|
+
async function upsertSeedField(
|
|
1753
|
+
db: Kysely<Database>,
|
|
1754
|
+
collectionSlug: string,
|
|
1755
|
+
field: SeedField,
|
|
1756
|
+
existing: Field | null,
|
|
1757
|
+
knownRelations: RelationEnds,
|
|
1758
|
+
): Promise<void> {
|
|
1759
|
+
const bound = resolveSeedFieldRelation(collectionSlug, field, knownRelations);
|
|
1760
|
+
|
|
1761
|
+
if (existing) {
|
|
1762
|
+
const update = {
|
|
1763
|
+
label: field.label,
|
|
1764
|
+
type: field.type,
|
|
1765
|
+
required: field.required || false,
|
|
1766
|
+
unique: field.unique || false,
|
|
1767
|
+
searchable: field.searchable || false,
|
|
1768
|
+
indexed: field.indexed || false,
|
|
1769
|
+
translatable: field.translatable,
|
|
1770
|
+
defaultValue: field.defaultValue,
|
|
1771
|
+
widget: field.widget,
|
|
1772
|
+
options: field.options,
|
|
1773
|
+
};
|
|
1774
|
+
|
|
1775
|
+
// A reference field from before relations existed has no relation to
|
|
1776
|
+
// preserve, so a seed naming a target binds it the way the admin does
|
|
1777
|
+
// rather than leaving it unbound forever.
|
|
1778
|
+
if (
|
|
1779
|
+
!bound &&
|
|
1780
|
+
field.type === "reference" &&
|
|
1781
|
+
!existing.validation?.relation &&
|
|
1782
|
+
typeof field.validation?.targetCollection === "string"
|
|
1783
|
+
) {
|
|
1784
|
+
await bindReferenceField(
|
|
1785
|
+
db,
|
|
1786
|
+
collectionSlug,
|
|
1787
|
+
existing,
|
|
1788
|
+
{ ...update, validation: field.validation },
|
|
1789
|
+
field.validation.targetCollection,
|
|
1790
|
+
);
|
|
1791
|
+
return;
|
|
1792
|
+
}
|
|
1793
|
+
|
|
1794
|
+
// A field naming a relation binds to that one. Otherwise keep whatever
|
|
1795
|
+
// relation the field is already bound to: a seed's field validation omits
|
|
1796
|
+
// the server-assigned keys and would orphan the relation row.
|
|
1797
|
+
const validation = bound
|
|
1798
|
+
? { ...field.validation, ...bound }
|
|
1799
|
+
: field.type === "reference" && existing.validation?.relation
|
|
1800
|
+
? {
|
|
1801
|
+
...field.validation,
|
|
1802
|
+
relation: existing.validation.relation,
|
|
1803
|
+
relationSide: existing.validation.relationSide,
|
|
1804
|
+
targetCollection: existing.validation.targetCollection,
|
|
1805
|
+
}
|
|
1806
|
+
: field.validation;
|
|
1807
|
+
const registry = new SchemaRegistry(db);
|
|
1808
|
+
await registry.updateField(collectionSlug, field.slug, { ...update, validation });
|
|
1809
|
+
return;
|
|
1810
|
+
}
|
|
1811
|
+
|
|
1812
|
+
const input = {
|
|
1813
|
+
slug: field.slug,
|
|
1814
|
+
label: field.label,
|
|
1815
|
+
type: field.type,
|
|
1816
|
+
required: field.required || false,
|
|
1817
|
+
unique: field.unique || false,
|
|
1818
|
+
searchable: field.searchable || false,
|
|
1819
|
+
indexed: field.indexed || false,
|
|
1820
|
+
translatable: field.translatable,
|
|
1821
|
+
defaultValue: field.defaultValue,
|
|
1822
|
+
validation: field.validation,
|
|
1823
|
+
widget: field.widget,
|
|
1824
|
+
options: field.options,
|
|
1825
|
+
};
|
|
1826
|
+
|
|
1827
|
+
if (bound) {
|
|
1828
|
+
const registry = new SchemaRegistry(db);
|
|
1829
|
+
await registry.createField(collectionSlug, {
|
|
1830
|
+
...input,
|
|
1831
|
+
validation: { ...field.validation, ...bound },
|
|
1832
|
+
});
|
|
1833
|
+
return;
|
|
1834
|
+
}
|
|
1835
|
+
|
|
1836
|
+
const targetCollection =
|
|
1837
|
+
field.type === "reference" && typeof field.validation?.targetCollection === "string"
|
|
1838
|
+
? field.validation.targetCollection
|
|
1839
|
+
: undefined;
|
|
1840
|
+
|
|
1841
|
+
if (targetCollection) {
|
|
1842
|
+
await withTransaction(db, async (trx) => {
|
|
1843
|
+
const relation = await createFieldRelation(
|
|
1844
|
+
trx,
|
|
1845
|
+
collectionSlug,
|
|
1846
|
+
field.slug,
|
|
1847
|
+
field.label,
|
|
1848
|
+
targetCollection,
|
|
1849
|
+
field.validation?.multiple ? null : 1,
|
|
1850
|
+
);
|
|
1851
|
+
const registry = new SchemaRegistry(trx);
|
|
1852
|
+
await registry.createField(collectionSlug, {
|
|
1853
|
+
...input,
|
|
1854
|
+
validation: {
|
|
1855
|
+
...field.validation,
|
|
1856
|
+
relation: relation.slug,
|
|
1857
|
+
relationSide: "parent" as const,
|
|
1858
|
+
},
|
|
1859
|
+
});
|
|
1860
|
+
});
|
|
1861
|
+
return;
|
|
1862
|
+
}
|
|
1863
|
+
|
|
1864
|
+
const registry = new SchemaRegistry(db);
|
|
1865
|
+
await registry.createField(collectionSlug, input);
|
|
1866
|
+
}
|
|
1867
|
+
|
|
1868
|
+
/**
|
|
1869
|
+
* Split resolved content `data` into the plain column data and the reference
|
|
1870
|
+
* edge writes. A reference field bound to a relation is storage-less, so its key
|
|
1871
|
+
* left in `data` would hit the column writer (and `syncDataColumns` on publish)
|
|
1872
|
+
* and throw "no such column". Its `$ref:`-resolved value — a child entry id or
|
|
1873
|
+
* an array of them — is captured as an edge write instead, keyed by the field's
|
|
1874
|
+
* relation. A reference field with no relation still owns its column, so its
|
|
1875
|
+
* resolved id is written there like any other string.
|
|
1876
|
+
*/
|
|
1877
|
+
/** One collection's reference fields by slug, read once per collection: the
|
|
1878
|
+
* schema phase has finished by the time content is applied. */
|
|
1879
|
+
function referenceFieldsOf(collection: CollectionWithFields | null): Map<string, Field> {
|
|
1880
|
+
return new Map(
|
|
1881
|
+
(collection?.fields ?? []).filter((f) => f.type === "reference").map((f) => [f.slug, f]),
|
|
1882
|
+
);
|
|
1883
|
+
}
|
|
1884
|
+
|
|
1885
|
+
function splitReferenceFields(
|
|
1886
|
+
collectionSlug: string,
|
|
1887
|
+
referenceFields: Map<string, Field>,
|
|
1888
|
+
data: Record<string, unknown>,
|
|
1889
|
+
): {
|
|
1890
|
+
columnData: Record<string, unknown>;
|
|
1891
|
+
edges: Array<{ fieldSlug: string; childIds: string[] }>;
|
|
1892
|
+
} {
|
|
1893
|
+
if (referenceFields.size === 0) return { columnData: data, edges: [] };
|
|
1894
|
+
|
|
1895
|
+
const columnData: Record<string, unknown> = {};
|
|
1896
|
+
const edges: Array<{ fieldSlug: string; childIds: string[] }> = [];
|
|
1897
|
+
for (const [key, value] of Object.entries(data)) {
|
|
1898
|
+
const field = referenceFields.get(key);
|
|
1899
|
+
if (!field?.validation?.relation) {
|
|
1900
|
+
columnData[key] = value;
|
|
1901
|
+
continue;
|
|
1902
|
+
}
|
|
1903
|
+
const childIds: string[] = [];
|
|
1904
|
+
for (const candidate of Array.isArray(value) ? value : [value]) {
|
|
1905
|
+
if (typeof candidate !== "string" || candidate.length === 0) continue;
|
|
1906
|
+
// `seedIdMap` fills forward-only, so a reference pointing at a collection
|
|
1907
|
+
// emitted later in the file arrives here unresolved.
|
|
1908
|
+
if (candidate.startsWith("$ref:")) {
|
|
1909
|
+
console.warn(
|
|
1910
|
+
`content.${collectionSlug}: reference "${candidate}" in field "${key}" did not resolve (not yet created or missing). Skipping.`,
|
|
1911
|
+
);
|
|
1912
|
+
continue;
|
|
1913
|
+
}
|
|
1914
|
+
childIds.push(candidate);
|
|
1915
|
+
}
|
|
1916
|
+
edges.push({ fieldSlug: key, childIds });
|
|
1917
|
+
}
|
|
1918
|
+
return { columnData, edges };
|
|
1919
|
+
}
|
|
1920
|
+
|
|
1921
|
+
/**
|
|
1922
|
+
* Write reference edges for a content entry, replacing any existing set per
|
|
1923
|
+
* relation (so re-applying a seed is idempotent). Throws to abort the enclosing
|
|
1924
|
+
* transaction if a child entry cannot be resolved — a half-written entry is
|
|
1925
|
+
* worse than a failed apply.
|
|
1926
|
+
*/
|
|
1927
|
+
async function applyContentReferences(
|
|
1928
|
+
trx: Kysely<Database>,
|
|
1929
|
+
collectionSlug: string,
|
|
1930
|
+
contentId: string,
|
|
1931
|
+
edges: Array<{ fieldSlug: string; childIds: string[] }>,
|
|
1932
|
+
): Promise<void> {
|
|
1933
|
+
for (const { fieldSlug, childIds } of edges) {
|
|
1934
|
+
const result = await setReferenceSelection(trx, collectionSlug, contentId, fieldSlug, childIds);
|
|
1935
|
+
if (!result.success) {
|
|
1936
|
+
throw new Error(
|
|
1937
|
+
`content.${collectionSlug}: failed to write references for "${contentId}": ${result.error.message}`,
|
|
1938
|
+
);
|
|
1939
|
+
}
|
|
1940
|
+
}
|
|
1941
|
+
}
|
|
1942
|
+
|
|
1213
1943
|
async function applyContentTaxonomies(
|
|
1214
1944
|
db: Kysely<Database>,
|
|
1215
1945
|
collectionSlug: string,
|
|
@@ -1278,14 +2008,20 @@ async function applyMenuItems(
|
|
|
1278
2008
|
let referenceId: string | null = null;
|
|
1279
2009
|
let referenceCollection: string | null = null;
|
|
1280
2010
|
|
|
1281
|
-
if (item.type
|
|
1282
|
-
|
|
1283
|
-
|
|
1284
|
-
|
|
1285
|
-
//
|
|
1286
|
-
|
|
2011
|
+
if (item.type !== "custom" && item.type !== "taxonomy") {
|
|
2012
|
+
const collection =
|
|
2013
|
+
item.collection || (item.type === "page" || item.type === "post" ? `${item.type}s` : null);
|
|
2014
|
+
if (item.ref) {
|
|
2015
|
+
// An unresolved ref stays fully unset: a "collection" item that kept
|
|
2016
|
+
// its collection would render as that collection's archive link.
|
|
2017
|
+
const resolved = seedIdMap.get(item.ref);
|
|
2018
|
+
if (resolved && collection) {
|
|
2019
|
+
referenceId = resolved;
|
|
2020
|
+
referenceCollection = collection;
|
|
2021
|
+
}
|
|
2022
|
+
} else {
|
|
2023
|
+
referenceCollection = collection;
|
|
1287
2024
|
}
|
|
1288
|
-
// If not in map, the content might not exist yet (will be broken link)
|
|
1289
2025
|
}
|
|
1290
2026
|
|
|
1291
2027
|
let translationGroup = itemId;
|
|
@@ -1377,6 +2113,7 @@ interface MediaContext {
|
|
|
1377
2113
|
storage: Storage | null;
|
|
1378
2114
|
skipMediaDownload: boolean;
|
|
1379
2115
|
mediaCache: Map<string, MediaValue>; // URL -> resolved MediaValue
|
|
2116
|
+
budget: SeedBudget | null;
|
|
1380
2117
|
}
|
|
1381
2118
|
|
|
1382
2119
|
/**
|
|
@@ -1563,6 +2300,7 @@ async function resolveMedia(
|
|
|
1563
2300
|
|
|
1564
2301
|
// Download the media (ssrfSafeFetch re-validates redirect targets)
|
|
1565
2302
|
console.log(` 📥 Downloading: ${url}`);
|
|
2303
|
+
ctx.budget?.countMediaDownload();
|
|
1566
2304
|
const response = await ssrfSafeFetch(url, {
|
|
1567
2305
|
headers: {
|
|
1568
2306
|
// Some services like Unsplash require a user-agent
|