emdash 0.13.0 → 0.15.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/{adapters-9DybjTO6.d.mts → adapters-C4yd_UJR.d.mts} +1 -1
- package/dist/{adapters-9DybjTO6.d.mts.map → adapters-C4yd_UJR.d.mts.map} +1 -1
- package/dist/{allowed-origins-CDdG-4Gd.mjs → allowed-origins-D0fFk9a6.mjs} +2 -2
- package/dist/{allowed-origins-CDdG-4Gd.mjs.map → allowed-origins-D0fFk9a6.mjs.map} +1 -1
- package/dist/api/route-utils.d.mts +3 -3
- package/dist/api/route-utils.mjs +15 -15
- package/dist/api/schemas/index.d.mts +2 -2
- package/dist/api/schemas/index.mjs +3 -3
- package/dist/{api-ayIQ7rIe.mjs → api-CLwG_3dh.mjs} +523 -59
- package/dist/api-CLwG_3dh.mjs.map +1 -0
- package/dist/{api-tokens-eYymBhIT.mjs → api-tokens-ucpcNXDt.mjs} +2 -2
- package/dist/{api-tokens-eYymBhIT.mjs.map → api-tokens-ucpcNXDt.mjs.map} +1 -1
- package/dist/{apply-v4DBgjPw.mjs → apply-wJhM_bwU.mjs} +17 -17
- package/dist/{apply-v4DBgjPw.mjs.map → apply-wJhM_bwU.mjs.map} +1 -1
- package/dist/astro/index.d.mts +10 -10
- package/dist/astro/index.mjs +21 -5
- package/dist/astro/index.mjs.map +1 -1
- package/dist/astro/middleware/auth.d.mts +9 -9
- package/dist/astro/middleware/auth.mjs +6 -6
- package/dist/astro/middleware/auth.mjs.map +1 -1
- package/dist/astro/middleware/redirect.mjs +4 -4
- package/dist/astro/middleware/request-context.mjs +2 -2
- package/dist/astro/middleware/request-context.mjs.map +1 -1
- package/dist/astro/middleware/setup.mjs +1 -1
- package/dist/astro/middleware.d.mts.map +1 -1
- package/dist/astro/middleware.mjs +353 -71
- package/dist/astro/middleware.mjs.map +1 -1
- package/dist/astro/routes/api/admin/allowed-domains/_domain_.mjs +5 -5
- package/dist/astro/routes/api/admin/allowed-domains/index.mjs +5 -5
- package/dist/astro/routes/api/admin/api-tokens/_id_.mjs +4 -4
- package/dist/astro/routes/api/admin/api-tokens/index.mjs +5 -5
- package/dist/astro/routes/api/admin/bylines/_id_/index.d.mts.map +1 -1
- package/dist/astro/routes/api/admin/bylines/_id_/index.mjs +14 -17
- package/dist/astro/routes/api/admin/bylines/_id_/index.mjs.map +1 -1
- package/dist/astro/routes/api/admin/bylines/_id_/translations.d.mts +9 -0
- package/dist/astro/routes/api/admin/bylines/_id_/translations.d.mts.map +1 -0
- package/dist/astro/routes/api/admin/bylines/_id_/translations.mjs +70 -0
- package/dist/astro/routes/api/admin/bylines/_id_/translations.mjs.map +1 -0
- package/dist/astro/routes/api/admin/bylines/index.d.mts.map +1 -1
- package/dist/astro/routes/api/admin/bylines/index.mjs +25 -16
- package/dist/astro/routes/api/admin/bylines/index.mjs.map +1 -1
- package/dist/astro/routes/api/admin/comments/_id_/status.mjs +10 -10
- package/dist/astro/routes/api/admin/comments/_id_.mjs +5 -5
- package/dist/astro/routes/api/admin/comments/bulk.mjs +8 -8
- package/dist/astro/routes/api/admin/comments/counts.mjs +5 -5
- package/dist/astro/routes/api/admin/comments/index.mjs +8 -8
- package/dist/astro/routes/api/admin/hooks/exclusive/_hookName_.mjs +4 -4
- package/dist/astro/routes/api/admin/hooks/exclusive/index.mjs +3 -3
- package/dist/astro/routes/api/admin/oauth-clients/_id_.mjs +4 -4
- package/dist/astro/routes/api/admin/oauth-clients/index.mjs +4 -4
- package/dist/astro/routes/api/admin/plugins/_id_/disable.mjs +32 -31
- package/dist/astro/routes/api/admin/plugins/_id_/disable.mjs.map +1 -1
- package/dist/astro/routes/api/admin/plugins/_id_/enable.mjs +32 -31
- package/dist/astro/routes/api/admin/plugins/_id_/enable.mjs.map +1 -1
- package/dist/astro/routes/api/admin/plugins/_id_/index.mjs +31 -30
- package/dist/astro/routes/api/admin/plugins/_id_/index.mjs.map +1 -1
- package/dist/astro/routes/api/admin/plugins/_id_/uninstall.mjs +31 -30
- package/dist/astro/routes/api/admin/plugins/_id_/uninstall.mjs.map +1 -1
- package/dist/astro/routes/api/admin/plugins/_id_/update.mjs +33 -31
- package/dist/astro/routes/api/admin/plugins/_id_/update.mjs.map +1 -1
- package/dist/astro/routes/api/admin/plugins/index.mjs +31 -30
- package/dist/astro/routes/api/admin/plugins/index.mjs.map +1 -1
- package/dist/astro/routes/api/admin/plugins/marketplace/_id_/icon.mjs +3 -3
- package/dist/astro/routes/api/admin/plugins/marketplace/_id_/index.mjs +31 -30
- 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 +33 -31
- package/dist/astro/routes/api/admin/plugins/marketplace/_id_/install.mjs.map +1 -1
- package/dist/astro/routes/api/admin/plugins/marketplace/index.mjs +31 -30
- package/dist/astro/routes/api/admin/plugins/marketplace/index.mjs.map +1 -1
- package/dist/astro/routes/api/admin/plugins/registry/_id_/uninstall.d.mts +8 -0
- package/dist/astro/routes/api/admin/plugins/registry/_id_/uninstall.d.mts.map +1 -0
- package/dist/astro/routes/api/admin/plugins/registry/_id_/uninstall.mjs +59 -0
- package/dist/astro/routes/api/admin/plugins/registry/_id_/uninstall.mjs.map +1 -0
- package/dist/astro/routes/api/admin/plugins/registry/_id_/update.d.mts +8 -0
- package/dist/astro/routes/api/admin/plugins/registry/_id_/update.d.mts.map +1 -0
- package/dist/astro/routes/api/admin/plugins/registry/_id_/update.mjs +72 -0
- package/dist/astro/routes/api/admin/plugins/registry/_id_/update.mjs.map +1 -0
- package/dist/astro/routes/api/admin/plugins/registry/install.mjs +31 -30
- package/dist/astro/routes/api/admin/plugins/registry/install.mjs.map +1 -1
- package/dist/astro/routes/api/admin/plugins/updates.d.mts.map +1 -1
- package/dist/astro/routes/api/admin/plugins/updates.mjs +44 -31
- package/dist/astro/routes/api/admin/plugins/updates.mjs.map +1 -1
- package/dist/astro/routes/api/admin/themes/marketplace/_id_/index.mjs +31 -30
- 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 +3 -3
- package/dist/astro/routes/api/admin/themes/marketplace/index.mjs +31 -30
- package/dist/astro/routes/api/admin/themes/marketplace/index.mjs.map +1 -1
- package/dist/astro/routes/api/admin/users/_id_/disable.mjs +2 -2
- package/dist/astro/routes/api/admin/users/_id_/enable.mjs +2 -2
- package/dist/astro/routes/api/admin/users/_id_/index.mjs +5 -5
- package/dist/astro/routes/api/admin/users/_id_/send-recovery.mjs +3 -3
- package/dist/astro/routes/api/admin/users/index.mjs +5 -5
- package/dist/astro/routes/api/auth/dev-bypass.mjs +5 -5
- package/dist/astro/routes/api/auth/invite/accept.mjs +2 -2
- package/dist/astro/routes/api/auth/invite/complete.mjs +9 -9
- package/dist/astro/routes/api/auth/invite/index.mjs +6 -6
- package/dist/astro/routes/api/auth/invite/register-options.mjs +8 -8
- package/dist/astro/routes/api/auth/logout.mjs +3 -3
- package/dist/astro/routes/api/auth/magic-link/send.mjs +8 -8
- package/dist/astro/routes/api/auth/magic-link/verify.mjs +3 -3
- package/dist/astro/routes/api/auth/me.mjs +5 -5
- package/dist/astro/routes/api/auth/mode.mjs +1 -1
- package/dist/astro/routes/api/auth/oauth/_provider_/callback.mjs +3 -3
- package/dist/astro/routes/api/auth/oauth/_provider_/callback.mjs.map +1 -1
- package/dist/astro/routes/api/auth/oauth/_provider_.mjs +2 -2
- package/dist/astro/routes/api/auth/oauth/_provider_.mjs.map +1 -1
- package/dist/astro/routes/api/auth/passkey/_id_.mjs +5 -5
- package/dist/astro/routes/api/auth/passkey/index.mjs +2 -2
- package/dist/astro/routes/api/auth/passkey/options.mjs +10 -10
- package/dist/astro/routes/api/auth/passkey/register/options.mjs +8 -8
- package/dist/astro/routes/api/auth/passkey/register/verify.mjs +9 -9
- package/dist/astro/routes/api/auth/passkey/verify.mjs +9 -9
- package/dist/astro/routes/api/auth/signup/complete.mjs +9 -9
- package/dist/astro/routes/api/auth/signup/request.mjs +8 -8
- package/dist/astro/routes/api/auth/signup/verify.mjs +2 -2
- package/dist/astro/routes/api/comments/_collection_/_contentId_/index.mjs +11 -11
- package/dist/astro/routes/api/content/_collection_/_id_/compare.mjs +3 -3
- package/dist/astro/routes/api/content/_collection_/_id_/discard-draft.mjs +3 -3
- package/dist/astro/routes/api/content/_collection_/_id_/discard-draft.mjs.map +1 -1
- package/dist/astro/routes/api/content/_collection_/_id_/duplicate.mjs +3 -3
- package/dist/astro/routes/api/content/_collection_/_id_/duplicate.mjs.map +1 -1
- package/dist/astro/routes/api/content/_collection_/_id_/permanent.mjs +3 -3
- package/dist/astro/routes/api/content/_collection_/_id_/preview-url.mjs +9 -9
- package/dist/astro/routes/api/content/_collection_/_id_/publish.mjs +6 -6
- package/dist/astro/routes/api/content/_collection_/_id_/publish.mjs.map +1 -1
- package/dist/astro/routes/api/content/_collection_/_id_/restore.mjs +3 -3
- package/dist/astro/routes/api/content/_collection_/_id_/restore.mjs.map +1 -1
- package/dist/astro/routes/api/content/_collection_/_id_/revisions.mjs +3 -3
- package/dist/astro/routes/api/content/_collection_/_id_/schedule.mjs +6 -6
- package/dist/astro/routes/api/content/_collection_/_id_/schedule.mjs.map +1 -1
- package/dist/astro/routes/api/content/_collection_/_id_/terms/_taxonomy_.mjs +10 -9
- package/dist/astro/routes/api/content/_collection_/_id_/terms/_taxonomy_.mjs.map +1 -1
- package/dist/astro/routes/api/content/_collection_/_id_/translations.mjs +3 -3
- package/dist/astro/routes/api/content/_collection_/_id_/translations.mjs.map +1 -1
- package/dist/astro/routes/api/content/_collection_/_id_/unpublish.mjs +3 -3
- package/dist/astro/routes/api/content/_collection_/_id_/unpublish.mjs.map +1 -1
- package/dist/astro/routes/api/content/_collection_/_id_.mjs +6 -6
- package/dist/astro/routes/api/content/_collection_/_id_.mjs.map +1 -1
- package/dist/astro/routes/api/content/_collection_/index.mjs +6 -6
- package/dist/astro/routes/api/content/_collection_/trash.mjs +6 -6
- package/dist/astro/routes/api/dashboard.mjs +7 -7
- package/dist/astro/routes/api/dev/emails.mjs +3 -3
- package/dist/astro/routes/api/import/probe.d.mts +3 -3
- package/dist/astro/routes/api/import/probe.mjs +10 -10
- package/dist/astro/routes/api/import/wordpress/analyze.mjs +3 -3
- package/dist/astro/routes/api/import/wordpress/execute.d.mts +9 -9
- package/dist/astro/routes/api/import/wordpress/execute.mjs +9 -8
- package/dist/astro/routes/api/import/wordpress/execute.mjs.map +1 -1
- package/dist/astro/routes/api/import/wordpress/media.mjs +8 -8
- package/dist/astro/routes/api/import/wordpress/prepare.mjs +8 -8
- package/dist/astro/routes/api/import/wordpress/prepare.mjs.map +1 -1
- package/dist/astro/routes/api/import/wordpress/rewrite-urls.mjs +7 -7
- package/dist/astro/routes/api/import/wordpress/rewrite-urls.mjs.map +1 -1
- package/dist/astro/routes/api/import/wordpress-plugin/analyze.d.mts +1 -1
- package/dist/astro/routes/api/import/wordpress-plugin/analyze.mjs +10 -10
- package/dist/astro/routes/api/import/wordpress-plugin/execute.d.mts +1 -1
- package/dist/astro/routes/api/import/wordpress-plugin/execute.mjs +11 -11
- package/dist/astro/routes/api/import/wordpress-plugin/execute.mjs.map +1 -1
- package/dist/astro/routes/api/manifest.mjs +4 -4
- package/dist/astro/routes/api/mcp.mjs +29 -29
- package/dist/astro/routes/api/mcp.mjs.map +1 -1
- package/dist/astro/routes/api/media/_id_/confirm.mjs +6 -6
- package/dist/astro/routes/api/media/_id_.mjs +6 -6
- package/dist/astro/routes/api/media/file/_...key_.mjs +2 -2
- package/dist/astro/routes/api/media/providers/_providerId_/_itemId_.mjs +3 -3
- package/dist/astro/routes/api/media/providers/_providerId_/index.mjs +3 -3
- package/dist/astro/routes/api/media/providers/index.mjs +3 -3
- package/dist/astro/routes/api/media/upload-url.mjs +7 -7
- package/dist/astro/routes/api/media/upload-url.mjs.map +1 -1
- package/dist/astro/routes/api/media.mjs +8 -8
- package/dist/astro/routes/api/menus/_name_/items/_id_.mjs +7 -7
- package/dist/astro/routes/api/menus/_name_/items.mjs +7 -7
- package/dist/astro/routes/api/menus/_name_/reorder.mjs +7 -7
- package/dist/astro/routes/api/menus/_name_/translations.mjs +7 -7
- package/dist/astro/routes/api/menus/_name_.mjs +7 -7
- package/dist/astro/routes/api/menus/index.mjs +7 -7
- package/dist/astro/routes/api/oauth/authorize.mjs +6 -6
- package/dist/astro/routes/api/oauth/device/authorize.mjs +6 -6
- package/dist/astro/routes/api/oauth/device/code.mjs +9 -9
- package/dist/astro/routes/api/oauth/device/token.mjs +8 -8
- package/dist/astro/routes/api/oauth/register.mjs +3 -3
- package/dist/astro/routes/api/oauth/token/refresh.mjs +6 -6
- package/dist/astro/routes/api/oauth/token/revoke.mjs +6 -6
- package/dist/astro/routes/api/oauth/token.mjs +6 -6
- package/dist/astro/routes/api/openapi.json.mjs +3 -3
- package/dist/astro/routes/api/openapi.json.mjs.map +1 -1
- package/dist/astro/routes/api/plugins/_pluginId_/_...path_.mjs +4 -4
- package/dist/astro/routes/api/redirects/404s/index.mjs +8 -8
- package/dist/astro/routes/api/redirects/404s/index.mjs.map +1 -1
- package/dist/astro/routes/api/redirects/404s/summary.mjs +8 -8
- package/dist/astro/routes/api/redirects/404s/summary.mjs.map +1 -1
- package/dist/astro/routes/api/redirects/_id_.mjs +9 -9
- package/dist/astro/routes/api/redirects/_id_.mjs.map +1 -1
- package/dist/astro/routes/api/redirects/index.mjs +9 -9
- package/dist/astro/routes/api/redirects/index.mjs.map +1 -1
- package/dist/astro/routes/api/revisions/_revisionId_/index.mjs +3 -3
- package/dist/astro/routes/api/revisions/_revisionId_/restore.mjs +3 -3
- package/dist/astro/routes/api/schema/collections/_slug_/fields/_fieldSlug_.mjs +31 -30
- 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 +31 -30
- 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 +31 -30
- package/dist/astro/routes/api/schema/collections/_slug_/fields/reorder.mjs.map +1 -1
- package/dist/astro/routes/api/schema/collections/_slug_/index.mjs +31 -30
- package/dist/astro/routes/api/schema/collections/_slug_/index.mjs.map +1 -1
- package/dist/astro/routes/api/schema/collections/index.mjs +31 -30
- package/dist/astro/routes/api/schema/collections/index.mjs.map +1 -1
- package/dist/astro/routes/api/schema/index.mjs +6 -6
- package/dist/astro/routes/api/schema/index.mjs.map +1 -1
- package/dist/astro/routes/api/schema/orphans/_slug_.mjs +31 -30
- package/dist/astro/routes/api/schema/orphans/_slug_.mjs.map +1 -1
- package/dist/astro/routes/api/schema/orphans/index.mjs +31 -30
- package/dist/astro/routes/api/schema/orphans/index.mjs.map +1 -1
- package/dist/astro/routes/api/search/enable.mjs +9 -9
- package/dist/astro/routes/api/search/index.mjs +8 -8
- package/dist/astro/routes/api/search/rebuild.mjs +9 -9
- package/dist/astro/routes/api/search/stats.mjs +6 -6
- package/dist/astro/routes/api/search/suggest.mjs +8 -8
- package/dist/astro/routes/api/sections/_slug_.mjs +8 -8
- package/dist/astro/routes/api/sections/_slug_.mjs.map +1 -1
- package/dist/astro/routes/api/sections/index.mjs +8 -8
- package/dist/astro/routes/api/sections/index.mjs.map +1 -1
- package/dist/astro/routes/api/settings/email.mjs +4 -4
- package/dist/astro/routes/api/settings.mjs +10 -10
- package/dist/astro/routes/api/setup/admin-verify.mjs +10 -10
- package/dist/astro/routes/api/setup/admin.mjs +9 -9
- package/dist/astro/routes/api/setup/dev-bypass.mjs +22 -22
- package/dist/astro/routes/api/setup/dev-reset.mjs +2 -2
- package/dist/astro/routes/api/setup/index.mjs +22 -22
- package/dist/astro/routes/api/setup/status.mjs +4 -4
- package/dist/astro/routes/api/snapshot.mjs +5 -5
- package/dist/astro/routes/api/taxonomies/_name_/terms/_slug_/translations.mjs +11 -10
- package/dist/astro/routes/api/taxonomies/_name_/terms/_slug_/translations.mjs.map +1 -1
- package/dist/astro/routes/api/taxonomies/_name_/terms/_slug_.mjs +11 -10
- package/dist/astro/routes/api/taxonomies/_name_/terms/_slug_.mjs.map +1 -1
- package/dist/astro/routes/api/taxonomies/_name_/terms/index.mjs +11 -10
- package/dist/astro/routes/api/taxonomies/_name_/terms/index.mjs.map +1 -1
- package/dist/astro/routes/api/taxonomies/index.mjs +11 -10
- package/dist/astro/routes/api/taxonomies/index.mjs.map +1 -1
- package/dist/astro/routes/api/themes/preview.mjs +5 -5
- package/dist/astro/routes/api/typegen.mjs +5 -5
- package/dist/astro/routes/api/well-known/auth.mjs +1 -1
- package/dist/astro/routes/api/well-known/oauth-authorization-server.mjs +2 -2
- package/dist/astro/routes/api/well-known/oauth-protected-resource.mjs +2 -2
- package/dist/astro/routes/api/widget-areas/_name_/reorder.mjs +6 -6
- package/dist/astro/routes/api/widget-areas/_name_/widgets/_id_.mjs +8 -8
- package/dist/astro/routes/api/widget-areas/_name_/widgets.mjs +8 -8
- package/dist/astro/routes/api/widget-areas/_name_.mjs +5 -5
- package/dist/astro/routes/api/widget-areas/index.mjs +8 -8
- package/dist/astro/routes/api/widget-components.mjs +3 -3
- package/dist/astro/routes/robots.txt.mjs +5 -5
- package/dist/astro/routes/sitemap-_collection_.xml.mjs +4 -4
- package/dist/astro/routes/sitemap.xml.mjs +5 -5
- package/dist/astro/types.d.mts +13 -12
- package/dist/astro/types.d.mts.map +1 -1
- package/dist/auth/providers/github.d.mts +1 -1
- package/dist/auth/providers/google.d.mts +1 -1
- package/dist/{authorize-BlyCH-96.mjs → authorize-Bkwe8kuL.mjs} +2 -2
- package/dist/{authorize-BlyCH-96.mjs.map → authorize-Bkwe8kuL.mjs.map} +1 -1
- package/dist/byline-CTaWkMh5.mjs +404 -0
- package/dist/byline-CTaWkMh5.mjs.map +1 -0
- package/dist/bylines-BYHWU3T7.mjs +174 -0
- package/dist/bylines-BYHWU3T7.mjs.map +1 -0
- package/dist/{bylines-C6eYUWlZ.d.mts → bylines-DtDRNF1n.d.mts} +63 -18
- package/dist/bylines-DtDRNF1n.d.mts.map +1 -0
- package/dist/bylines-H0Xh5TMy.mjs +118 -0
- package/dist/bylines-H0Xh5TMy.mjs.map +1 -0
- package/dist/{cache-CXCpjWiL.mjs → cache-CNk1jIxp.mjs} +2 -2
- package/dist/{cache-CXCpjWiL.mjs.map → cache-CNk1jIxp.mjs.map} +1 -1
- package/dist/{challenge-store-CJ0OOHOr.mjs → challenge-store-Dng1SxKT.mjs} +1 -1
- package/dist/{challenge-store-CJ0OOHOr.mjs.map → challenge-store-Dng1SxKT.mjs.map} +1 -1
- package/dist/{chunks-DyGtu1Bv.mjs → chunks-BkfVdD-3.mjs} +2 -2
- package/dist/{chunks-DyGtu1Bv.mjs.map → chunks-BkfVdD-3.mjs.map} +1 -1
- package/dist/cli/index.mjs +21 -29
- package/dist/cli/index.mjs.map +1 -1
- package/dist/client/cf-access.d.mts +1 -1
- package/dist/client/index.d.mts +1 -1
- package/dist/client/index.mjs +1 -1
- package/dist/client/index.mjs.map +1 -1
- package/dist/{comment-Dd9MI82-.mjs → comment-_yzlBYPx.mjs} +2 -2
- package/dist/{comment-Dd9MI82-.mjs.map → comment-_yzlBYPx.mjs.map} +1 -1
- package/dist/{comments-koGI0FrK.mjs → comments-DxID-rsd.mjs} +3 -3
- package/dist/{comments-koGI0FrK.mjs.map → comments-DxID-rsd.mjs.map} +1 -1
- package/dist/{components-mZem7pbe.mjs → components-Dx3DM0gg.mjs} +1 -1
- package/dist/{components-mZem7pbe.mjs.map → components-Dx3DM0gg.mjs.map} +1 -1
- package/dist/config-CVssduLe.mjs.map +1 -1
- package/dist/{content-D6YG26WG.mjs → content-C0ooIs-f.mjs} +3 -3
- package/dist/{content-D6YG26WG.mjs.map → content-C0ooIs-f.mjs.map} +1 -1
- package/dist/{context-qF8d3IPR.mjs → context-sAnCaUIR.mjs} +10 -10
- package/dist/context-sAnCaUIR.mjs.map +1 -0
- package/dist/{cron-H8eJ46dv.mjs → cron-Bd3b3iuj.mjs} +1 -1
- package/dist/{cron-H8eJ46dv.mjs.map → cron-Bd3b3iuj.mjs.map} +1 -1
- package/dist/{dashboard-BmWSIUwY.mjs → dashboard-Cqw3ay2X.mjs} +4 -4
- package/dist/{dashboard-BmWSIUwY.mjs.map → dashboard-Cqw3ay2X.mjs.map} +1 -1
- package/dist/db/index.d.mts +3 -3
- package/dist/db/index.mjs +1 -1
- package/dist/db/libsql.d.mts +1 -1
- package/dist/db/postgres.d.mts +1 -1
- package/dist/db/sqlite.d.mts +1 -1
- package/dist/{default-Dbs22Gg4.mjs → default-BvTAYCzx.mjs} +1 -1
- package/dist/{default-Dbs22Gg4.mjs.map → default-BvTAYCzx.mjs.map} +1 -1
- package/dist/{device-flow-BqJRxa0Q.mjs → device-flow-B9oG8PwP.mjs} +4 -4
- package/dist/{device-flow-BqJRxa0Q.mjs.map → device-flow-B9oG8PwP.mjs.map} +1 -1
- package/dist/{email-console-Dmp5Q-P2.mjs → email-console-CubRll9q.mjs} +1 -1
- package/dist/email-console-CubRll9q.mjs.map +1 -0
- package/dist/{error-tSQWIl5U.mjs → error-CPh_8eLq.mjs} +16 -8
- package/dist/error-CPh_8eLq.mjs.map +1 -0
- package/dist/{escape-B8bdIryO.mjs → escape-Cg6kMELH.mjs} +1 -1
- package/dist/{escape-B8bdIryO.mjs.map → escape-Cg6kMELH.mjs.map} +1 -1
- package/dist/{fts-manager-B633C-kQ.mjs → fts-manager-Mnrtn-r2.mjs} +2 -2
- package/dist/{fts-manager-B633C-kQ.mjs.map → fts-manager-Mnrtn-r2.mjs.map} +1 -1
- package/dist/{import-CNfLOgDE.mjs → import-DG80rC_I.mjs} +3 -3
- package/dist/{import-CNfLOgDE.mjs.map → import-DG80rC_I.mjs.map} +1 -1
- package/dist/{index-UmOMt9T-.d.mts → index-Bv1Wf1zB.d.mts} +235 -18
- package/dist/index-Bv1Wf1zB.d.mts.map +1 -0
- package/dist/{index-D2gvztOP.d.mts → index-CC42STEm.d.mts} +3 -3
- package/dist/{index-D2gvztOP.d.mts.map → index-CC42STEm.d.mts.map} +1 -1
- package/dist/index.d.mts +17 -17
- package/dist/index.mjs +50 -49
- package/dist/{load-QzYRpVN3.mjs → load-DmXNVhst.mjs} +2 -2
- package/dist/{load-QzYRpVN3.mjs.map → load-DmXNVhst.mjs.map} +1 -1
- package/dist/{loader-Cs6-Bqe6.mjs → loader-Chm5h7Gr.mjs} +3 -3
- package/dist/loader-Chm5h7Gr.mjs.map +1 -0
- package/dist/{manifest-schema-HCtSh4Jq.mjs → manifest-schema-Czqf0TLu.mjs} +1 -1
- package/dist/{manifest-schema-HCtSh4Jq.mjs.map → manifest-schema-Czqf0TLu.mjs.map} +1 -1
- package/dist/media/index.d.mts +1 -1
- package/dist/media/local-runtime.d.mts +11 -11
- package/dist/media/local-runtime.mjs +4 -4
- package/dist/{media-allowlist-B8EX01DH.mjs → media-allowlist-BNloC69x.mjs} +1 -1
- package/dist/{media-allowlist-B8EX01DH.mjs.map → media-allowlist-BNloC69x.mjs.map} +1 -1
- package/dist/{media-Dg7he9uK.mjs → media-oqRcNiQf.mjs} +2 -2
- package/dist/media-oqRcNiQf.mjs.map +1 -0
- package/dist/{menus-DOzIecHi.mjs → menus-Bjf5R1Qq.mjs} +2 -2
- package/dist/menus-Bjf5R1Qq.mjs.map +1 -0
- package/dist/{menus-X4Z-eBA1.mjs → menus-C75SSmRy.mjs} +30 -11
- package/dist/menus-C75SSmRy.mjs.map +1 -0
- package/dist/mime-KV5TqkMN.mjs.map +1 -1
- package/dist/{mode-DPRPvJYm.mjs → mode-CaaiebZI.mjs} +1 -1
- package/dist/{mode-DPRPvJYm.mjs.map → mode-CaaiebZI.mjs.map} +1 -1
- package/dist/{oauth-authorization-62GmpGIH.mjs → oauth-authorization-CTMeVfvj.mjs} +4 -4
- package/dist/{oauth-authorization-62GmpGIH.mjs.map → oauth-authorization-CTMeVfvj.mjs.map} +1 -1
- package/dist/{oauth-clients-D_B0_-Bz.mjs → oauth-clients-eJCbkVSG.mjs} +1 -1
- package/dist/oauth-clients-eJCbkVSG.mjs.map +1 -0
- package/dist/{oauth-state-store-DpsZViTu.mjs → oauth-state-store-vOSdOeGe.mjs} +1 -1
- package/dist/{oauth-state-store-DpsZViTu.mjs.map → oauth-state-store-vOSdOeGe.mjs.map} +1 -1
- package/dist/{oauth-user-lookup-meyS2oB1.mjs → oauth-user-lookup-3JwsVw6N.mjs} +1 -1
- package/dist/{oauth-user-lookup-meyS2oB1.mjs.map → oauth-user-lookup-3JwsVw6N.mjs.map} +1 -1
- package/dist/options-BL4X94qY.mjs.map +1 -1
- package/dist/{options-Cq64Wx0O.d.mts → options-DhV-gwJb.d.mts} +4 -4
- package/dist/options-DhV-gwJb.d.mts.map +1 -0
- package/dist/page/index.d.mts +2 -2
- package/dist/{parse-BFTPon-J.mjs → parse-3-caTKgt.mjs} +2 -2
- package/dist/{parse-BFTPon-J.mjs.map → parse-3-caTKgt.mjs.map} +1 -1
- package/dist/{passkey-config-Cg86_ISa.mjs → passkey-config-BloQOT3y.mjs} +1 -1
- package/dist/{passkey-config-Cg86_ISa.mjs.map → passkey-config-BloQOT3y.mjs.map} +1 -1
- package/dist/{placeholder-D3cFCU9y.d.mts → placeholder-KCkkCtgQ.d.mts} +1 -1
- package/dist/{placeholder-D3cFCU9y.d.mts.map → placeholder-KCkkCtgQ.d.mts.map} +1 -1
- package/dist/plugin-types.d.mts +1 -1
- package/dist/plugins/adapt-sandbox-entry.d.mts +9 -9
- package/dist/plugins/adapt-sandbox-entry.d.mts.map +1 -1
- package/dist/plugins/adapt-sandbox-entry.mjs +26 -15
- package/dist/plugins/adapt-sandbox-entry.mjs.map +1 -1
- package/dist/{preview-C1LOEbWZ.mjs → preview-D4z0WONU.mjs} +2 -2
- package/dist/{preview-C1LOEbWZ.mjs.map → preview-D4z0WONU.mjs.map} +1 -1
- package/dist/{public-url-CseXl9Fv.mjs → public-url-CUWWFME2.mjs} +1 -1
- package/dist/{public-url-CseXl9Fv.mjs.map → public-url-CUWWFME2.mjs.map} +1 -1
- package/dist/{query-axZmO6Tn.mjs → query-BJn8TOPk.mjs} +16 -13
- package/dist/{query-axZmO6Tn.mjs.map → query-BJn8TOPk.mjs.map} +1 -1
- package/dist/{rate-limit-t5CVjCO6.mjs → rate-limit-D_-gAeJ0.mjs} +2 -2
- package/dist/{rate-limit-t5CVjCO6.mjs.map → rate-limit-D_-gAeJ0.mjs.map} +1 -1
- package/dist/{redirect-DGRsLO2I.mjs → redirect-BINiRYq4.mjs} +1 -1
- package/dist/{redirect-DGRsLO2I.mjs.map → redirect-BINiRYq4.mjs.map} +1 -1
- package/dist/{redirect-DkaDxq8e.mjs → redirect-CNv4mHX2.mjs} +2 -2
- package/dist/{redirect-DkaDxq8e.mjs.map → redirect-CNv4mHX2.mjs.map} +1 -1
- package/dist/{redirects-D1fdd68T.mjs → redirects-B-CUZ1Xh.mjs} +3 -3
- package/dist/{redirects-D1fdd68T.mjs.map → redirects-B-CUZ1Xh.mjs.map} +1 -1
- package/dist/{redirects-Dmj6KRU3.mjs → redirects-COMLwsV5.mjs} +19 -5
- package/dist/redirects-COMLwsV5.mjs.map +1 -0
- package/dist/{registry-BnCeHYsf.mjs → registry-DqrAQDXH.mjs} +4 -4
- package/dist/{registry-BnCeHYsf.mjs.map → registry-DqrAQDXH.mjs.map} +1 -1
- package/dist/request-cache-dzCt8TZB.mjs.map +1 -1
- package/dist/request-context.mjs.map +1 -1
- package/dist/{request-meta-CLCwSQOS.mjs → request-meta-C_Cjii-T.mjs} +2 -2
- package/dist/{request-meta-CLCwSQOS.mjs.map → request-meta-C_Cjii-T.mjs.map} +1 -1
- package/dist/resolve-Cj98DuqN.mjs +39 -0
- package/dist/resolve-Cj98DuqN.mjs.map +1 -0
- package/dist/{runner-DdnQIwz_.mjs → runner-CGlojznK.mjs} +472 -165
- package/dist/runner-CGlojznK.mjs.map +1 -0
- package/dist/{runner-DcfZewkO.d.mts → runner-CNHRo1mT.d.mts} +2 -2
- package/dist/{runner-DcfZewkO.d.mts.map → runner-CNHRo1mT.d.mts.map} +1 -1
- package/dist/runtime.d.mts +10 -10
- package/dist/runtime.mjs +2 -2
- package/dist/{schema-BmqagCwG.mjs → schema-Djdlfi5G.mjs} +4 -4
- package/dist/{schema-BmqagCwG.mjs.map → schema-Djdlfi5G.mjs.map} +1 -1
- package/dist/{search-CPrvO5u8.mjs → search-By-NN3da.mjs} +4 -4
- package/dist/{search-CPrvO5u8.mjs.map → search-By-NN3da.mjs.map} +1 -1
- package/dist/{secrets-6pgZyq0K.mjs → secrets-rPdhEBkD.mjs} +1 -1
- package/dist/{secrets-6pgZyq0K.mjs.map → secrets-rPdhEBkD.mjs.map} +1 -1
- package/dist/{sections-Cm-zb-gZ.mjs → sections-DcBIlOq1.mjs} +3 -3
- package/dist/{sections-Cm-zb-gZ.mjs.map → sections-DcBIlOq1.mjs.map} +1 -1
- package/dist/seed/index.d.mts +2 -2
- package/dist/seed/index.mjs +16 -16
- package/dist/seo/index.d.mts +1 -1
- package/dist/{seo-DRq9-EPP.mjs → seo-bjDoq9Eg.mjs} +2 -2
- package/dist/{seo-DRq9-EPP.mjs.map → seo-bjDoq9Eg.mjs.map} +1 -1
- package/dist/{service-vByySp-2.mjs → service-BuuTdGAT.mjs} +3 -3
- package/dist/{service-vByySp-2.mjs.map → service-BuuTdGAT.mjs.map} +1 -1
- package/dist/{settings-CBBj7HUd.mjs → settings-CJnKiWuR.mjs} +3 -3
- package/dist/{settings-CBBj7HUd.mjs.map → settings-CJnKiWuR.mjs.map} +1 -1
- package/dist/{settings-xQKsWnzQ.mjs → settings-hcubRfkr.mjs} +3 -3
- package/dist/settings-hcubRfkr.mjs.map +1 -0
- package/dist/{setup-BGAJ2uXs.mjs → setup-Cf_TyOv5.mjs} +2 -2
- package/dist/{setup-BGAJ2uXs.mjs.map → setup-Cf_TyOv5.mjs.map} +1 -1
- package/dist/{setup-complete-C6ZCLhKo.mjs → setup-complete-MzzN9u0b.mjs} +1 -1
- package/dist/{setup-complete-C6ZCLhKo.mjs.map → setup-complete-MzzN9u0b.mjs.map} +1 -1
- package/dist/{setup-nonce-CY1gQiAU.mjs → setup-nonce-DXuriHsg.mjs} +1 -1
- package/dist/{setup-nonce-CY1gQiAU.mjs.map → setup-nonce-DXuriHsg.mjs.map} +1 -1
- package/dist/{site-url-D-M4Fd8O.mjs → site-url-xkhw1tcz.mjs} +1 -1
- package/dist/{site-url-D-M4Fd8O.mjs.map → site-url-xkhw1tcz.mjs.map} +1 -1
- package/dist/{ssrf-DzFN_qV-.mjs → ssrf-MZ-zrG6-.mjs} +1 -1
- package/dist/{ssrf-DzFN_qV-.mjs.map → ssrf-MZ-zrG6-.mjs.map} +1 -1
- package/dist/storage/local.d.mts +1 -1
- package/dist/storage/local.mjs +1 -1
- package/dist/storage/local.mjs.map +1 -1
- package/dist/storage/s3.d.mts +1 -1
- package/dist/storage/s3.mjs +1 -1
- package/dist/storage/s3.mjs.map +1 -1
- package/dist/{taxonomies-Dc0mzlms.mjs → taxonomies-CLs9HPE2.mjs} +4 -4
- package/dist/{taxonomies-Dc0mzlms.mjs.map → taxonomies-CLs9HPE2.mjs.map} +1 -1
- package/dist/{taxonomies-Cn9UpaR2.mjs → taxonomies-WamPVA2x.mjs} +7 -42
- package/dist/taxonomies-WamPVA2x.mjs.map +1 -0
- package/dist/{taxonomy-wPfusMK9.mjs → taxonomy-D4Uc2LsZ.mjs} +3 -3
- package/dist/{taxonomy-wPfusMK9.mjs.map → taxonomy-D4Uc2LsZ.mjs.map} +1 -1
- package/dist/{tokens-DILYNZMi.mjs → tokens-N8otWMmj.mjs} +1 -1
- package/dist/{tokens-DILYNZMi.mjs.map → tokens-N8otWMmj.mjs.map} +1 -1
- package/dist/{transport-fw-mKJzT.mjs → transport-B6CHddbu.mjs} +1 -1
- package/dist/{transport-fw-mKJzT.mjs.map → transport-B6CHddbu.mjs.map} +1 -1
- package/dist/{transport-GeXlLscf.d.mts → transport-DOxLfUir.d.mts} +1 -1
- package/dist/{transport-GeXlLscf.d.mts.map → transport-DOxLfUir.d.mts.map} +1 -1
- package/dist/{trusted-proxy-CJhQIk65.mjs → trusted-proxy-97pajC2f.mjs} +1 -1
- package/dist/{trusted-proxy-CJhQIk65.mjs.map → trusted-proxy-97pajC2f.mjs.map} +1 -1
- package/dist/{types-CwXMEPRr.mjs → types-ByV5sgsv.mjs} +2 -2
- package/dist/types-ByV5sgsv.mjs.map +1 -0
- package/dist/{types-Dz9CGX_d.mjs → types-Cd9UCu3t.mjs} +1 -1
- package/dist/{types-Dz9CGX_d.mjs.map → types-Cd9UCu3t.mjs.map} +1 -1
- package/dist/{types-DmxPPXGf.d.mts → types-CkDSF81F.d.mts} +1 -1
- package/dist/{types-DmxPPXGf.d.mts.map → types-CkDSF81F.d.mts.map} +1 -1
- package/dist/{types-BWhaSS7U.d.mts → types-CpUuGcd5.d.mts} +1 -1
- package/dist/{types-BWhaSS7U.d.mts.map → types-CpUuGcd5.d.mts.map} +1 -1
- package/dist/{types-DFowNO60.d.mts → types-D599-ruj.d.mts} +1 -1
- package/dist/{types-DFowNO60.d.mts.map → types-D599-ruj.d.mts.map} +1 -1
- package/dist/{types-B05e2naf.d.mts → types-DGHWRQgr.d.mts} +3 -3
- package/dist/{types-B05e2naf.d.mts.map → types-DGHWRQgr.d.mts.map} +1 -1
- package/dist/{types-CzvJd1ND.d.mts → types-DaYDYW6g.d.mts} +14 -1
- package/dist/types-DaYDYW6g.d.mts.map +1 -0
- package/dist/{types-C1KKK4VP.d.mts → types-DaqNzqVt.d.mts} +16 -1
- package/dist/{types-C1KKK4VP.d.mts.map → types-DaqNzqVt.d.mts.map} +1 -1
- package/dist/{types-DW1l0gCv.d.mts → types-Dgo6y-Ut.d.mts} +1 -1
- package/dist/{types-DW1l0gCv.d.mts.map → types-Dgo6y-Ut.d.mts.map} +1 -1
- package/dist/{types-Cb2UCDJg.d.mts → types-bYmRn_Uy.d.mts} +1 -1
- package/dist/{types-Cb2UCDJg.d.mts.map → types-bYmRn_Uy.d.mts.map} +1 -1
- package/dist/{user-Dr1bOCqS.mjs → user-D3BD5zdT.mjs} +2 -2
- package/dist/{user-Dr1bOCqS.mjs.map → user-D3BD5zdT.mjs.map} +1 -1
- package/dist/{utils-_F-rWBTN.mjs → utils-C3wTAP-P.mjs} +1 -1
- package/dist/{utils-_F-rWBTN.mjs.map → utils-C3wTAP-P.mjs.map} +1 -1
- package/dist/{validate-BpQGsmd7.d.mts → validate-DQtHw9NT.d.mts} +5 -5
- package/dist/{validate-BpQGsmd7.d.mts.map → validate-DQtHw9NT.d.mts.map} +1 -1
- package/dist/{validate-DlFxcVVK.mjs → validate-mz87i8_1.mjs} +2 -2
- package/dist/{validate-DlFxcVVK.mjs.map → validate-mz87i8_1.mjs.map} +1 -1
- package/dist/{validation-BiFJqUp5.mjs → validation-DKHhXjPr.mjs} +5 -5
- package/dist/{validation-BiFJqUp5.mjs.map → validation-DKHhXjPr.mjs.map} +1 -1
- package/dist/version-Ct7C6RSo.mjs +7 -0
- package/dist/{version-Dw7Z5PVU.mjs.map → version-Ct7C6RSo.mjs.map} +1 -1
- package/dist/{widgets-B9j_yzlk.mjs → widgets-lShIQXU5.mjs} +3 -3
- package/dist/widgets-lShIQXU5.mjs.map +1 -0
- package/dist/{zod-generator-DSyz01KE.mjs → zod-generator-dvxgmd1M.mjs} +2 -2
- package/dist/{zod-generator-DSyz01KE.mjs.map → zod-generator-dvxgmd1M.mjs.map} +1 -1
- package/package.json +10 -8
- package/src/api/error.ts +18 -3
- package/src/api/errors.ts +6 -0
- package/src/api/handlers/bylines.ts +161 -0
- package/src/api/handlers/content.ts +125 -43
- package/src/api/handlers/index.ts +6 -0
- package/src/api/handlers/marketplace.ts +27 -5
- package/src/api/handlers/oauth-clients.ts +1 -1
- package/src/api/handlers/registry.ts +568 -22
- package/src/api/openapi/document.ts +1 -1
- package/src/api/schemas/bylines.ts +46 -0
- package/src/astro/integration/index.ts +1 -1
- package/src/astro/integration/routes.ts +5 -0
- package/src/astro/integration/runtime.ts +12 -1
- package/src/astro/integration/virtual-modules.ts +19 -2
- package/src/astro/integration/vite-config.ts +2 -2
- package/src/astro/middleware/auth.ts +7 -7
- package/src/astro/middleware/request-context.ts +1 -1
- package/src/astro/middleware.ts +31 -20
- package/src/astro/routes/api/admin/bylines/[id]/index.ts +3 -12
- package/src/astro/routes/api/admin/bylines/[id]/translations.ts +99 -0
- package/src/astro/routes/api/admin/bylines/index.ts +22 -11
- package/src/astro/routes/api/admin/plugins/[id]/update.ts +1 -0
- package/src/astro/routes/api/admin/plugins/marketplace/[id]/install.ts +6 -1
- package/src/astro/routes/api/admin/plugins/registry/[id]/uninstall.ts +51 -0
- package/src/astro/routes/api/admin/plugins/registry/[id]/update.ts +79 -0
- package/src/astro/routes/api/admin/plugins/updates.ts +43 -6
- package/src/astro/routes/api/admin/themes/marketplace/index.ts +1 -1
- package/src/astro/routes/api/auth/oauth/[provider]/callback.ts +2 -2
- package/src/astro/routes/api/auth/oauth/[provider].ts +2 -2
- package/src/astro/routes/api/content/[collection]/[id]/discard-draft.ts +2 -2
- package/src/astro/routes/api/content/[collection]/[id]/duplicate.ts +2 -2
- package/src/astro/routes/api/content/[collection]/[id]/publish.ts +2 -2
- package/src/astro/routes/api/content/[collection]/[id]/restore.ts +2 -2
- package/src/astro/routes/api/content/[collection]/[id]/schedule.ts +2 -2
- package/src/astro/routes/api/content/[collection]/[id]/terms/[taxonomy].ts +6 -6
- package/src/astro/routes/api/content/[collection]/[id]/translations.ts +1 -1
- package/src/astro/routes/api/content/[collection]/[id]/unpublish.ts +2 -2
- package/src/astro/routes/api/content/[collection]/[id].ts +6 -6
- package/src/astro/routes/api/import/wordpress/execute.ts +1 -1
- package/src/astro/routes/api/import/wordpress/prepare.ts +2 -2
- package/src/astro/routes/api/import/wordpress/rewrite-urls.ts +3 -3
- package/src/astro/routes/api/import/wordpress-plugin/execute.ts +2 -2
- package/src/astro/routes/api/media/upload-url.ts +1 -1
- package/src/astro/routes/api/redirects/404s/index.ts +3 -3
- package/src/astro/routes/api/redirects/404s/summary.ts +1 -1
- package/src/astro/routes/api/redirects/[id].ts +3 -3
- package/src/astro/routes/api/redirects/index.ts +2 -2
- package/src/astro/routes/api/schema/collections/[slug]/fields/[fieldSlug].ts +4 -4
- package/src/astro/routes/api/schema/collections/[slug]/fields/index.ts +2 -6
- package/src/astro/routes/api/schema/collections/[slug]/fields/reorder.ts +1 -1
- package/src/astro/routes/api/schema/collections/[slug]/index.ts +6 -6
- package/src/astro/routes/api/schema/collections/index.ts +4 -4
- package/src/astro/routes/api/schema/index.ts +1 -1
- package/src/astro/routes/api/schema/orphans/[slug].ts +1 -1
- package/src/astro/routes/api/schema/orphans/index.ts +1 -1
- package/src/astro/routes/api/sections/[slug].ts +3 -3
- package/src/astro/routes/api/sections/index.ts +2 -2
- package/src/astro/types.ts +4 -0
- package/src/auth/rate-limit.ts +1 -1
- package/src/auth/trusted-proxy.ts +1 -1
- package/src/bylines/index.ts +154 -55
- package/src/cli/commands/init.ts +4 -8
- package/src/client/index.ts +1 -1
- package/src/components/InlinePortableTextEditor.tsx +5 -1
- package/src/components/inline-code-block.tsx +343 -0
- package/src/config/secrets.ts +3 -3
- package/src/database/migrations/006_taxonomy_defs.ts +1 -1
- package/src/database/migrations/014_draft_revisions.ts +6 -6
- package/src/database/migrations/040_byline_i18n.ts +497 -0
- package/src/database/migrations/runner.ts +4 -1
- package/src/database/repositories/audit.ts +2 -2
- package/src/database/repositories/byline.ts +320 -50
- package/src/database/repositories/media.ts +2 -2
- package/src/database/repositories/menu.ts +1 -1
- package/src/database/repositories/options.ts +3 -3
- package/src/database/repositories/plugin-storage.ts +3 -3
- package/src/database/repositories/types.ts +13 -0
- package/src/database/types.ts +15 -0
- package/src/emdash-runtime.ts +492 -20
- package/src/i18n/config.ts +1 -1
- package/src/index.ts +7 -0
- package/src/loader.ts +1 -1
- package/src/mcp/server.ts +3 -3
- package/src/media/mime.ts +1 -1
- package/src/page/absolute-url.ts +1 -1
- package/src/plugins/adapt-sandbox-entry.ts +45 -40
- package/src/plugins/email-console.ts +1 -1
- package/src/plugins/index.ts +1 -0
- package/src/plugins/marketplace.ts +1 -1
- package/src/plugins/sandbox/index.ts +1 -0
- package/src/plugins/sandbox/noop.ts +11 -3
- package/src/plugins/sandbox/types.ts +28 -0
- package/src/query.ts +17 -2
- package/src/registry/config.ts +1 -1
- package/src/request-cache.ts +3 -3
- package/src/request-context.ts +1 -1
- package/src/settings/index.ts +4 -4
- package/src/storage/local.ts +1 -1
- package/src/storage/s3.ts +3 -3
- package/src/widgets/index.ts +1 -1
- package/dist/api-ayIQ7rIe.mjs.map +0 -1
- package/dist/byline-D09BaS4j.mjs +0 -220
- package/dist/byline-D09BaS4j.mjs.map +0 -1
- package/dist/bylines-BTM2xtP8.mjs +0 -113
- package/dist/bylines-BTM2xtP8.mjs.map +0 -1
- package/dist/bylines-C6eYUWlZ.d.mts.map +0 -1
- package/dist/context-qF8d3IPR.mjs.map +0 -1
- package/dist/email-console-Dmp5Q-P2.mjs.map +0 -1
- package/dist/error-tSQWIl5U.mjs.map +0 -1
- package/dist/index-UmOMt9T-.d.mts.map +0 -1
- package/dist/loader-Cs6-Bqe6.mjs.map +0 -1
- package/dist/media-Dg7he9uK.mjs.map +0 -1
- package/dist/menus-DOzIecHi.mjs.map +0 -1
- package/dist/menus-X4Z-eBA1.mjs.map +0 -1
- package/dist/oauth-clients-D_B0_-Bz.mjs.map +0 -1
- package/dist/options-Cq64Wx0O.d.mts.map +0 -1
- package/dist/redirects-Dmj6KRU3.mjs.map +0 -1
- package/dist/runner-DdnQIwz_.mjs.map +0 -1
- package/dist/settings-xQKsWnzQ.mjs.map +0 -1
- package/dist/taxonomies-Cn9UpaR2.mjs.map +0 -1
- package/dist/types-CwXMEPRr.mjs.map +0 -1
- package/dist/types-CzvJd1ND.d.mts.map +0 -1
- package/dist/version-Dw7Z5PVU.mjs +0 -7
- package/dist/widgets-B9j_yzlk.mjs.map +0 -1
- /package/dist/{api-tokens-D3C9v02m.mjs → api-tokens-iPIHAY8N.mjs} +0 -0
- /package/dist/{ssrf-CTul4uQi.mjs → ssrf-BIcd-aXW.mjs} +0 -0
- /package/dist/{types-Db67HHlU.mjs → types-1NNkmTIn.mjs} +0 -0
|
@@ -0,0 +1,497 @@
|
|
|
1
|
+
import type { Kysely } from "kysely";
|
|
2
|
+
import { sql } from "kysely";
|
|
3
|
+
|
|
4
|
+
import { getI18nConfig } from "../../i18n/config.js";
|
|
5
|
+
import { currentTimestamp, isSqlite, listTablesLike } from "../dialect-helpers.js";
|
|
6
|
+
import { validateIdentifier } from "../validate.js";
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* i18n for bylines. Adds `locale` + `translation_group` to `_emdash_bylines`
|
|
10
|
+
* and stores translation_groups (not row ids) in
|
|
11
|
+
* `_emdash_content_bylines.byline_id` and `ec_*.primary_byline_id`. Backfill
|
|
12
|
+
* locale and column DEFAULTs use the site's configured defaultLocale.
|
|
13
|
+
*
|
|
14
|
+
* Mirrors the row-per-locale + `translation_group` model PR #916 (migration
|
|
15
|
+
* 036) applied to menus and taxonomies.
|
|
16
|
+
*
|
|
17
|
+
* Key consequences of the model:
|
|
18
|
+
* - `(slug, locale)` is unique on `_emdash_bylines`; a single slug can repeat
|
|
19
|
+
* across locales (one row per locale variant of a byline).
|
|
20
|
+
* - The partial unique on `user_id` widens to `(user_id, locale)` so a CMS
|
|
21
|
+
* user can have one byline per locale.
|
|
22
|
+
* - `_emdash_content_bylines.byline_id` no longer FKs to `_emdash_bylines.id`
|
|
23
|
+
* (it holds a `translation_group`, not a row id). The runtime is
|
|
24
|
+
* responsible for cascading on byline delete — see `BylineRepository.delete`.
|
|
25
|
+
*
|
|
26
|
+
* Hydration is strict per locale (see `BylineRepository.getContentBylines`):
|
|
27
|
+
* a credit at locale X renders iff a byline row exists at locale X within the
|
|
28
|
+
* credited translation group. This mirrors `getEntryTerms` and the convention
|
|
29
|
+
* established by #916. There is no read-time fallback.
|
|
30
|
+
*/
|
|
31
|
+
|
|
32
|
+
function getDefaultLocale(): string {
|
|
33
|
+
return getI18nConfig()?.defaultLocale ?? "en";
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
export async function up(db: Kysely<unknown>): Promise<void> {
|
|
37
|
+
const defaultLocale = getDefaultLocale();
|
|
38
|
+
|
|
39
|
+
if (isSqlite(db)) {
|
|
40
|
+
// Rebuild children before parents to drop FKs that would CASCADE
|
|
41
|
+
// on D1 (#1021). `_emdash_content_bylines.byline_id` has an FK to
|
|
42
|
+
// `_emdash_bylines(id) ON DELETE CASCADE` from migration 031.
|
|
43
|
+
// Stripping it first lets us rebuild `_emdash_bylines` without
|
|
44
|
+
// risking a cascading wipe of credits on D1.
|
|
45
|
+
await rebuildContentBylines(db);
|
|
46
|
+
await rebuildBylines(db, defaultLocale);
|
|
47
|
+
await remapPrimaryBylineIds(db);
|
|
48
|
+
return;
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
await pgWidenBylines(db, defaultLocale);
|
|
52
|
+
await pgDropContentBylinesFk(db);
|
|
53
|
+
await remapPrimaryBylineIds(db);
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
async function rebuildContentBylines(db: Kysely<unknown>): Promise<void> {
|
|
57
|
+
// Drops the FK so `byline_id` can point at a translation_group rather
|
|
58
|
+
// than a row id. Runs before `rebuildBylines` so the drop is safe on D1.
|
|
59
|
+
// No remap is needed here: `rebuildBylines` later seeds `translation_group
|
|
60
|
+
// = id` for every preserved row, so the row-id values we copy resolve as
|
|
61
|
+
// translation_group references after the migration completes. This coupling
|
|
62
|
+
// is load-bearing — if the translation_group seed ever changes, this needs
|
|
63
|
+
// an explicit remap *after* `rebuildBylines` runs.
|
|
64
|
+
const fks = await sql<{ id: number }>`PRAGMA foreign_key_list(_emdash_content_bylines)`.execute(
|
|
65
|
+
db,
|
|
66
|
+
);
|
|
67
|
+
if (fks.rows.length === 0) return;
|
|
68
|
+
|
|
69
|
+
await sql.raw(`DROP TABLE IF EXISTS "_emdash_content_bylines_new"`).execute(db);
|
|
70
|
+
await db.schema
|
|
71
|
+
.createTable("_emdash_content_bylines_new")
|
|
72
|
+
.addColumn("id", "text", (c) => c.primaryKey())
|
|
73
|
+
.addColumn("collection_slug", "text", (c) => c.notNull())
|
|
74
|
+
.addColumn("content_id", "text", (c) => c.notNull())
|
|
75
|
+
.addColumn("byline_id", "text", (c) => c.notNull())
|
|
76
|
+
.addColumn("sort_order", "integer", (c) => c.notNull().defaultTo(0))
|
|
77
|
+
.addColumn("role_label", "text")
|
|
78
|
+
.addColumn("created_at", "text", (c) => c.defaultTo(currentTimestamp(db)))
|
|
79
|
+
.addUniqueConstraint("content_bylines_unique", ["collection_slug", "content_id", "byline_id"])
|
|
80
|
+
.execute();
|
|
81
|
+
|
|
82
|
+
await sql`
|
|
83
|
+
INSERT INTO _emdash_content_bylines_new
|
|
84
|
+
(id, collection_slug, content_id, byline_id, sort_order, role_label, created_at)
|
|
85
|
+
SELECT id, collection_slug, content_id, byline_id, sort_order, role_label, created_at
|
|
86
|
+
FROM _emdash_content_bylines
|
|
87
|
+
`.execute(db);
|
|
88
|
+
|
|
89
|
+
await db.schema.dropTable("_emdash_content_bylines").execute();
|
|
90
|
+
await sql`ALTER TABLE _emdash_content_bylines_new RENAME TO _emdash_content_bylines`.execute(db);
|
|
91
|
+
|
|
92
|
+
// Indexes from migration 031 dropped with the table; restore.
|
|
93
|
+
await db.schema
|
|
94
|
+
.createIndex("idx_content_bylines_content")
|
|
95
|
+
.on("_emdash_content_bylines")
|
|
96
|
+
.columns(["collection_slug", "content_id", "sort_order"])
|
|
97
|
+
.execute();
|
|
98
|
+
await db.schema
|
|
99
|
+
.createIndex("idx_content_bylines_byline")
|
|
100
|
+
.on("_emdash_content_bylines")
|
|
101
|
+
.column("byline_id")
|
|
102
|
+
.execute();
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
async function rebuildBylines(db: Kysely<unknown>, defaultLocale: string): Promise<void> {
|
|
106
|
+
if (await hasColumn(db, "_emdash_bylines", "locale")) return;
|
|
107
|
+
await sql.raw(`DROP TABLE IF EXISTS "_emdash_bylines_new"`).execute(db);
|
|
108
|
+
|
|
109
|
+
await db.schema
|
|
110
|
+
.createTable("_emdash_bylines_new")
|
|
111
|
+
.addColumn("id", "text", (c) => c.primaryKey())
|
|
112
|
+
.addColumn("slug", "text", (c) => c.notNull())
|
|
113
|
+
.addColumn("display_name", "text", (c) => c.notNull())
|
|
114
|
+
.addColumn("bio", "text")
|
|
115
|
+
.addColumn("avatar_media_id", "text", (c) => c.references("media.id").onDelete("set null"))
|
|
116
|
+
.addColumn("website_url", "text")
|
|
117
|
+
.addColumn("user_id", "text", (c) => c.references("users.id").onDelete("set null"))
|
|
118
|
+
.addColumn("is_guest", "integer", (c) => c.notNull().defaultTo(0))
|
|
119
|
+
.addColumn("created_at", "text", (c) => c.defaultTo(currentTimestamp(db)))
|
|
120
|
+
.addColumn("updated_at", "text", (c) => c.defaultTo(currentTimestamp(db)))
|
|
121
|
+
.addColumn("locale", "text", (c) => c.notNull().defaultTo(defaultLocale))
|
|
122
|
+
.addColumn("translation_group", "text")
|
|
123
|
+
.addUniqueConstraint("_emdash_bylines_slug_locale_unique", ["slug", "locale"])
|
|
124
|
+
.execute();
|
|
125
|
+
|
|
126
|
+
await sql`
|
|
127
|
+
INSERT INTO _emdash_bylines_new (
|
|
128
|
+
id, slug, display_name, bio, avatar_media_id, website_url,
|
|
129
|
+
user_id, is_guest, created_at, updated_at, locale, translation_group
|
|
130
|
+
)
|
|
131
|
+
SELECT
|
|
132
|
+
id, slug, display_name, bio, avatar_media_id, website_url,
|
|
133
|
+
user_id, is_guest, created_at, updated_at, ${defaultLocale}, id
|
|
134
|
+
FROM _emdash_bylines
|
|
135
|
+
`.execute(db);
|
|
136
|
+
|
|
137
|
+
await db.schema.dropTable("_emdash_bylines").execute();
|
|
138
|
+
await sql`ALTER TABLE _emdash_bylines_new RENAME TO _emdash_bylines`.execute(db);
|
|
139
|
+
|
|
140
|
+
// Indexes from migration 031 dropped with the table; restore the
|
|
141
|
+
// per-slug and per-display-name indexes. The partial unique on
|
|
142
|
+
// user_id widens to (user_id, locale) so one CMS user can own one
|
|
143
|
+
// byline per locale.
|
|
144
|
+
await db.schema.createIndex("idx_bylines_slug").on("_emdash_bylines").column("slug").execute();
|
|
145
|
+
await db.schema
|
|
146
|
+
.createIndex("idx_bylines_display_name")
|
|
147
|
+
.on("_emdash_bylines")
|
|
148
|
+
.column("display_name")
|
|
149
|
+
.execute();
|
|
150
|
+
await sql`
|
|
151
|
+
CREATE UNIQUE INDEX ${sql.ref("idx_bylines_user_id_locale_unique")}
|
|
152
|
+
ON ${sql.ref("_emdash_bylines")} (user_id, locale)
|
|
153
|
+
WHERE user_id IS NOT NULL
|
|
154
|
+
`.execute(db);
|
|
155
|
+
|
|
156
|
+
await db.schema
|
|
157
|
+
.createIndex("idx__emdash_bylines_locale")
|
|
158
|
+
.on("_emdash_bylines")
|
|
159
|
+
.column("locale")
|
|
160
|
+
.execute();
|
|
161
|
+
await db.schema
|
|
162
|
+
.createIndex("idx__emdash_bylines_translation_group")
|
|
163
|
+
.on("_emdash_bylines")
|
|
164
|
+
.column("translation_group")
|
|
165
|
+
.execute();
|
|
166
|
+
|
|
167
|
+
// One row per (translation_group, locale): the row-per-locale model
|
|
168
|
+
// (PR #916) requires that each locale variant of a byline appears
|
|
169
|
+
// exactly once in its translation group. `UNIQUE(slug, locale)` doesn't
|
|
170
|
+
// catch the case where two siblings in the same group use different
|
|
171
|
+
// slugs at the same locale — this partial unique does. `WHERE
|
|
172
|
+
// translation_group IS NOT NULL` is defensive: post-040 every row has a
|
|
173
|
+
// value, but the column is nullable in the schema.
|
|
174
|
+
await sql`
|
|
175
|
+
CREATE UNIQUE INDEX ${sql.ref("idx_bylines_group_locale_unique")}
|
|
176
|
+
ON ${sql.ref("_emdash_bylines")} (translation_group, locale)
|
|
177
|
+
WHERE translation_group IS NOT NULL
|
|
178
|
+
`.execute(db);
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
async function remapPrimaryBylineIds(db: Kysely<unknown>): Promise<void> {
|
|
182
|
+
// Walks every `ec_*` table and remaps `primary_byline_id` (row id →
|
|
183
|
+
// translation_group). On a fresh install translation_group equals id
|
|
184
|
+
// for every row, so the values look unchanged — but the column
|
|
185
|
+
// semantics flip from "FK to _emdash_bylines.id" to "translation_group
|
|
186
|
+
// in _emdash_bylines.translation_group". Once translations exist, the
|
|
187
|
+
// remap is meaningful: a credit pointing at the en-row id still
|
|
188
|
+
// resolves to the same byline group at every locale variant.
|
|
189
|
+
const collections = await listTablesLike(db, "ec_%");
|
|
190
|
+
for (const table of collections) {
|
|
191
|
+
validateIdentifier(table, "content table");
|
|
192
|
+
await sql`
|
|
193
|
+
UPDATE ${sql.ref(table)} SET primary_byline_id = (
|
|
194
|
+
SELECT translation_group FROM _emdash_bylines
|
|
195
|
+
WHERE _emdash_bylines.id = ${sql.ref(table)}.primary_byline_id
|
|
196
|
+
)
|
|
197
|
+
WHERE primary_byline_id IS NOT NULL
|
|
198
|
+
AND EXISTS (
|
|
199
|
+
SELECT 1 FROM _emdash_bylines
|
|
200
|
+
WHERE _emdash_bylines.id = ${sql.ref(table)}.primary_byline_id
|
|
201
|
+
)
|
|
202
|
+
`.execute(db);
|
|
203
|
+
}
|
|
204
|
+
}
|
|
205
|
+
|
|
206
|
+
async function pgWidenBylines(db: Kysely<unknown>, defaultLocale: string): Promise<void> {
|
|
207
|
+
const ref = sql.ref("_emdash_bylines");
|
|
208
|
+
await sql`ALTER TABLE ${ref} ADD COLUMN IF NOT EXISTS locale TEXT NOT NULL DEFAULT ${sql.lit(defaultLocale)}`.execute(
|
|
209
|
+
db,
|
|
210
|
+
);
|
|
211
|
+
await sql`ALTER TABLE ${ref} ADD COLUMN IF NOT EXISTS translation_group TEXT`.execute(db);
|
|
212
|
+
await sql`UPDATE ${ref} SET translation_group = id WHERE translation_group IS NULL`.execute(db);
|
|
213
|
+
await sql`CREATE INDEX IF NOT EXISTS ${sql.ref("idx__emdash_bylines_locale")} ON ${ref} (locale)`.execute(
|
|
214
|
+
db,
|
|
215
|
+
);
|
|
216
|
+
await sql`
|
|
217
|
+
CREATE INDEX IF NOT EXISTS ${sql.ref("idx__emdash_bylines_translation_group")}
|
|
218
|
+
ON ${ref} (translation_group)
|
|
219
|
+
`.execute(db);
|
|
220
|
+
|
|
221
|
+
// Widen UNIQUE(slug) -> UNIQUE(slug, locale)
|
|
222
|
+
const slugCons = await sql<{ conname: string }>`
|
|
223
|
+
SELECT conname FROM pg_constraint c
|
|
224
|
+
WHERE c.conrelid = '_emdash_bylines'::regclass AND c.contype = 'u'
|
|
225
|
+
AND array_length(c.conkey, 1) = 1
|
|
226
|
+
AND (
|
|
227
|
+
SELECT array_agg(a.attname ORDER BY pos.ord)
|
|
228
|
+
FROM unnest(c.conkey) WITH ORDINALITY AS pos(attnum, ord)
|
|
229
|
+
JOIN pg_attribute a ON a.attrelid = c.conrelid AND a.attnum = pos.attnum
|
|
230
|
+
)::text[] = ARRAY['slug']
|
|
231
|
+
`.execute(db);
|
|
232
|
+
for (const c of slugCons.rows) {
|
|
233
|
+
await sql`ALTER TABLE ${ref} DROP CONSTRAINT ${sql.ref(c.conname)}`.execute(db);
|
|
234
|
+
}
|
|
235
|
+
await sql`
|
|
236
|
+
ALTER TABLE ${ref}
|
|
237
|
+
ADD CONSTRAINT _emdash_bylines_slug_locale_unique UNIQUE (slug, locale)
|
|
238
|
+
`.execute(db);
|
|
239
|
+
|
|
240
|
+
// Replace the partial unique on (user_id) with (user_id, locale).
|
|
241
|
+
await sql`DROP INDEX IF EXISTS idx_bylines_user_id_unique`.execute(db);
|
|
242
|
+
await sql`
|
|
243
|
+
CREATE UNIQUE INDEX IF NOT EXISTS ${sql.ref("idx_bylines_user_id_locale_unique")}
|
|
244
|
+
ON ${ref} (user_id, locale) WHERE user_id IS NOT NULL
|
|
245
|
+
`.execute(db);
|
|
246
|
+
|
|
247
|
+
// One row per (translation_group, locale): see SQLite branch above.
|
|
248
|
+
await sql`
|
|
249
|
+
CREATE UNIQUE INDEX IF NOT EXISTS ${sql.ref("idx_bylines_group_locale_unique")}
|
|
250
|
+
ON ${ref} (translation_group, locale) WHERE translation_group IS NOT NULL
|
|
251
|
+
`.execute(db);
|
|
252
|
+
}
|
|
253
|
+
|
|
254
|
+
async function pgDropContentBylinesFk(db: Kysely<unknown>): Promise<void> {
|
|
255
|
+
const fks = await sql<{ conname: string }>`
|
|
256
|
+
SELECT conname FROM pg_constraint
|
|
257
|
+
WHERE conrelid = '_emdash_content_bylines'::regclass AND contype = 'f'
|
|
258
|
+
`.execute(db);
|
|
259
|
+
for (const c of fks.rows) {
|
|
260
|
+
await sql`ALTER TABLE _emdash_content_bylines DROP CONSTRAINT ${sql.ref(c.conname)}`.execute(
|
|
261
|
+
db,
|
|
262
|
+
);
|
|
263
|
+
}
|
|
264
|
+
}
|
|
265
|
+
|
|
266
|
+
async function hasColumn(db: Kysely<unknown>, table: string, column: string): Promise<boolean> {
|
|
267
|
+
const rows = await sql<{ name: string }>`PRAGMA table_info(${sql.ref(table)})`.execute(db);
|
|
268
|
+
return rows.rows.some((r) => r.name === column);
|
|
269
|
+
}
|
|
270
|
+
|
|
271
|
+
/**
|
|
272
|
+
* down() restores the FK on `_emdash_content_bylines.byline_id`. Rows whose
|
|
273
|
+
* `byline_id` doesn't resolve to a (translation_group, defaultLocale) row in
|
|
274
|
+
* `_emdash_bylines` would fail the rebuild after other tables are already
|
|
275
|
+
* stripped — leaving the user mid-rollback. Surface dangling rows up front.
|
|
276
|
+
*/
|
|
277
|
+
async function assertContentBylinesResolve(
|
|
278
|
+
db: Kysely<unknown>,
|
|
279
|
+
defaultLocale: string,
|
|
280
|
+
): Promise<void> {
|
|
281
|
+
const result = await sql<{ count: number | string }>`
|
|
282
|
+
SELECT COUNT(*) AS count FROM _emdash_content_bylines cb
|
|
283
|
+
WHERE NOT EXISTS (
|
|
284
|
+
SELECT 1 FROM _emdash_bylines b
|
|
285
|
+
WHERE b.translation_group = cb.byline_id AND b.locale = ${defaultLocale}
|
|
286
|
+
)
|
|
287
|
+
`.execute(db);
|
|
288
|
+
const count = Number(result.rows[0]?.count ?? 0);
|
|
289
|
+
if (count > 0) {
|
|
290
|
+
throw new Error(
|
|
291
|
+
`Cannot revert migration 040_byline_i18n: ` +
|
|
292
|
+
`${count} row(s) in "_emdash_content_bylines" reference a translation_group ` +
|
|
293
|
+
`with no row in "_emdash_bylines" at locale="${defaultLocale}". ` +
|
|
294
|
+
`Clean up the dangling credits before rolling back.`,
|
|
295
|
+
);
|
|
296
|
+
}
|
|
297
|
+
}
|
|
298
|
+
|
|
299
|
+
/**
|
|
300
|
+
* down() is destructive on multi-locale installs (dropping `locale` collapses
|
|
301
|
+
* translated rows onto an ambiguous unique key). Refuse to run when any row
|
|
302
|
+
* sits at a locale other than the configured defaultLocale.
|
|
303
|
+
*/
|
|
304
|
+
async function assertSingleLocale(db: Kysely<unknown>, defaultLocale: string): Promise<void> {
|
|
305
|
+
const result = await sql<{ count: number | string }>`
|
|
306
|
+
SELECT COUNT(*) AS count FROM _emdash_bylines WHERE locale != ${defaultLocale}
|
|
307
|
+
`.execute(db);
|
|
308
|
+
const count = Number(result.rows[0]?.count ?? 0);
|
|
309
|
+
if (count > 0) {
|
|
310
|
+
throw new Error(
|
|
311
|
+
`Cannot revert migration 040_byline_i18n: ` +
|
|
312
|
+
`${count} row(s) in "_emdash_bylines" use a non-default locale ` +
|
|
313
|
+
`(defaultLocale="${defaultLocale}"). ` +
|
|
314
|
+
`Reverting would drop them silently. Export translations first ` +
|
|
315
|
+
`(or delete them) and re-run the rollback. ` +
|
|
316
|
+
`See packages/core/src/database/migrations/040_byline_i18n.ts.`,
|
|
317
|
+
);
|
|
318
|
+
}
|
|
319
|
+
}
|
|
320
|
+
|
|
321
|
+
export async function down(db: Kysely<unknown>): Promise<void> {
|
|
322
|
+
const defaultLocale = getDefaultLocale();
|
|
323
|
+
await assertSingleLocale(db, defaultLocale);
|
|
324
|
+
await assertContentBylinesResolve(db, defaultLocale);
|
|
325
|
+
|
|
326
|
+
if (isSqlite(db)) {
|
|
327
|
+
// Indexes first to avoid blocking the table rebuilds.
|
|
328
|
+
await sql.raw(`DROP INDEX IF EXISTS idx__emdash_bylines_locale`).execute(db);
|
|
329
|
+
await sql.raw(`DROP INDEX IF EXISTS idx__emdash_bylines_translation_group`).execute(db);
|
|
330
|
+
await sql.raw(`DROP INDEX IF EXISTS idx_bylines_user_id_locale_unique`).execute(db);
|
|
331
|
+
await sql.raw(`DROP INDEX IF EXISTS idx_bylines_group_locale_unique`).execute(db);
|
|
332
|
+
|
|
333
|
+
// Remap `_emdash_content_bylines.byline_id` and `ec_*.primary_byline_id`
|
|
334
|
+
// from translation_group back to the row id of the defaultLocale
|
|
335
|
+
// anchor. assertSingleLocale guarantees the mapping is 1:1, so the
|
|
336
|
+
// rebuilt FK can validate every reference.
|
|
337
|
+
await remapPrimaryBylineIdsDown(db, defaultLocale);
|
|
338
|
+
await remapContentBylinesDown(db, defaultLocale);
|
|
339
|
+
|
|
340
|
+
// Now safe to rebuild `_emdash_bylines` (strips locale +
|
|
341
|
+
// translation_group, restores UNIQUE(slug) and the partial unique
|
|
342
|
+
// on user_id alone).
|
|
343
|
+
await rebuildBylinesDown(db);
|
|
344
|
+
// And finally restore the FK on `_emdash_content_bylines.byline_id`.
|
|
345
|
+
await restoreContentBylinesFk(db);
|
|
346
|
+
return;
|
|
347
|
+
}
|
|
348
|
+
|
|
349
|
+
await remapPrimaryBylineIdsDown(db, defaultLocale);
|
|
350
|
+
await sql`
|
|
351
|
+
UPDATE _emdash_content_bylines
|
|
352
|
+
SET byline_id = COALESCE(
|
|
353
|
+
(SELECT b.id FROM _emdash_bylines b
|
|
354
|
+
WHERE b.translation_group = _emdash_content_bylines.byline_id
|
|
355
|
+
AND b.locale = ${defaultLocale}),
|
|
356
|
+
byline_id
|
|
357
|
+
)
|
|
358
|
+
`.execute(db);
|
|
359
|
+
|
|
360
|
+
await sql.raw(`DROP INDEX IF EXISTS idx__emdash_bylines_locale`).execute(db);
|
|
361
|
+
await sql.raw(`DROP INDEX IF EXISTS idx__emdash_bylines_translation_group`).execute(db);
|
|
362
|
+
await sql.raw(`DROP INDEX IF EXISTS idx_bylines_user_id_locale_unique`).execute(db);
|
|
363
|
+
await sql.raw(`DROP INDEX IF EXISTS idx_bylines_group_locale_unique`).execute(db);
|
|
364
|
+
await sql
|
|
365
|
+
.raw(
|
|
366
|
+
`ALTER TABLE "_emdash_bylines" DROP CONSTRAINT IF EXISTS _emdash_bylines_slug_locale_unique`,
|
|
367
|
+
)
|
|
368
|
+
.execute(db);
|
|
369
|
+
await sql.raw(`ALTER TABLE "_emdash_bylines" DROP COLUMN IF EXISTS locale`).execute(db);
|
|
370
|
+
await sql
|
|
371
|
+
.raw(`ALTER TABLE "_emdash_bylines" DROP COLUMN IF EXISTS translation_group`)
|
|
372
|
+
.execute(db);
|
|
373
|
+
await sql
|
|
374
|
+
.raw(`ALTER TABLE "_emdash_bylines" ADD CONSTRAINT _emdash_bylines_slug_unique UNIQUE (slug)`)
|
|
375
|
+
.execute(db);
|
|
376
|
+
await sql`
|
|
377
|
+
CREATE UNIQUE INDEX IF NOT EXISTS ${sql.ref("idx_bylines_user_id_unique")}
|
|
378
|
+
ON _emdash_bylines (user_id) WHERE user_id IS NOT NULL
|
|
379
|
+
`.execute(db);
|
|
380
|
+
await sql`
|
|
381
|
+
ALTER TABLE _emdash_content_bylines
|
|
382
|
+
ADD CONSTRAINT _emdash_content_bylines_byline_fk
|
|
383
|
+
FOREIGN KEY (byline_id) REFERENCES _emdash_bylines(id) ON DELETE CASCADE
|
|
384
|
+
`.execute(db);
|
|
385
|
+
}
|
|
386
|
+
|
|
387
|
+
async function remapPrimaryBylineIdsDown(
|
|
388
|
+
db: Kysely<unknown>,
|
|
389
|
+
defaultLocale: string,
|
|
390
|
+
): Promise<void> {
|
|
391
|
+
const collections = await listTablesLike(db, "ec_%");
|
|
392
|
+
for (const table of collections) {
|
|
393
|
+
validateIdentifier(table, "content table");
|
|
394
|
+
await sql`
|
|
395
|
+
UPDATE ${sql.ref(table)}
|
|
396
|
+
SET primary_byline_id = COALESCE(
|
|
397
|
+
(SELECT b.id FROM _emdash_bylines b
|
|
398
|
+
WHERE b.translation_group = ${sql.ref(table)}.primary_byline_id
|
|
399
|
+
AND b.locale = ${defaultLocale}),
|
|
400
|
+
primary_byline_id
|
|
401
|
+
)
|
|
402
|
+
WHERE primary_byline_id IS NOT NULL
|
|
403
|
+
`.execute(db);
|
|
404
|
+
}
|
|
405
|
+
}
|
|
406
|
+
|
|
407
|
+
async function remapContentBylinesDown(db: Kysely<unknown>, defaultLocale: string): Promise<void> {
|
|
408
|
+
await sql`
|
|
409
|
+
UPDATE _emdash_content_bylines
|
|
410
|
+
SET byline_id = COALESCE(
|
|
411
|
+
(SELECT b.id FROM _emdash_bylines b
|
|
412
|
+
WHERE b.translation_group = _emdash_content_bylines.byline_id
|
|
413
|
+
AND b.locale = ${defaultLocale}),
|
|
414
|
+
byline_id
|
|
415
|
+
)
|
|
416
|
+
`.execute(db);
|
|
417
|
+
}
|
|
418
|
+
|
|
419
|
+
async function rebuildBylinesDown(db: Kysely<unknown>): Promise<void> {
|
|
420
|
+
await sql.raw(`DROP TABLE IF EXISTS "_emdash_bylines_old"`).execute(db);
|
|
421
|
+
await db.schema
|
|
422
|
+
.createTable("_emdash_bylines_old")
|
|
423
|
+
.addColumn("id", "text", (c) => c.primaryKey())
|
|
424
|
+
.addColumn("slug", "text", (c) => c.notNull().unique())
|
|
425
|
+
.addColumn("display_name", "text", (c) => c.notNull())
|
|
426
|
+
.addColumn("bio", "text")
|
|
427
|
+
.addColumn("avatar_media_id", "text", (c) => c.references("media.id").onDelete("set null"))
|
|
428
|
+
.addColumn("website_url", "text")
|
|
429
|
+
.addColumn("user_id", "text", (c) => c.references("users.id").onDelete("set null"))
|
|
430
|
+
.addColumn("is_guest", "integer", (c) => c.notNull().defaultTo(0))
|
|
431
|
+
.addColumn("created_at", "text", (c) => c.defaultTo(currentTimestamp(db)))
|
|
432
|
+
.addColumn("updated_at", "text", (c) => c.defaultTo(currentTimestamp(db)))
|
|
433
|
+
.execute();
|
|
434
|
+
await sql`
|
|
435
|
+
INSERT INTO _emdash_bylines_old (
|
|
436
|
+
id, slug, display_name, bio, avatar_media_id, website_url,
|
|
437
|
+
user_id, is_guest, created_at, updated_at
|
|
438
|
+
)
|
|
439
|
+
SELECT
|
|
440
|
+
id, slug, display_name, bio, avatar_media_id, website_url,
|
|
441
|
+
user_id, is_guest, created_at, updated_at
|
|
442
|
+
FROM _emdash_bylines
|
|
443
|
+
`.execute(db);
|
|
444
|
+
await db.schema.dropTable("_emdash_bylines").execute();
|
|
445
|
+
await sql`ALTER TABLE _emdash_bylines_old RENAME TO _emdash_bylines`.execute(db);
|
|
446
|
+
|
|
447
|
+
// Restore the indexes that existed pre-040.
|
|
448
|
+
await db.schema.createIndex("idx_bylines_slug").on("_emdash_bylines").column("slug").execute();
|
|
449
|
+
await db.schema
|
|
450
|
+
.createIndex("idx_bylines_display_name")
|
|
451
|
+
.on("_emdash_bylines")
|
|
452
|
+
.column("display_name")
|
|
453
|
+
.execute();
|
|
454
|
+
await sql`
|
|
455
|
+
CREATE UNIQUE INDEX ${sql.ref("idx_bylines_user_id_unique")}
|
|
456
|
+
ON ${sql.ref("_emdash_bylines")} (user_id)
|
|
457
|
+
WHERE user_id IS NOT NULL
|
|
458
|
+
`.execute(db);
|
|
459
|
+
}
|
|
460
|
+
|
|
461
|
+
async function restoreContentBylinesFk(db: Kysely<unknown>): Promise<void> {
|
|
462
|
+
await sql.raw(`DROP TABLE IF EXISTS "_emdash_content_bylines_old"`).execute(db);
|
|
463
|
+
await db.schema
|
|
464
|
+
.createTable("_emdash_content_bylines_old")
|
|
465
|
+
.addColumn("id", "text", (c) => c.primaryKey())
|
|
466
|
+
.addColumn("collection_slug", "text", (c) => c.notNull())
|
|
467
|
+
.addColumn("content_id", "text", (c) => c.notNull())
|
|
468
|
+
.addColumn("byline_id", "text", (c) =>
|
|
469
|
+
c.notNull().references("_emdash_bylines.id").onDelete("cascade"),
|
|
470
|
+
)
|
|
471
|
+
.addColumn("sort_order", "integer", (c) => c.notNull().defaultTo(0))
|
|
472
|
+
.addColumn("role_label", "text")
|
|
473
|
+
.addColumn("created_at", "text", (c) => c.defaultTo(currentTimestamp(db)))
|
|
474
|
+
.addUniqueConstraint("content_bylines_unique", ["collection_slug", "content_id", "byline_id"])
|
|
475
|
+
.execute();
|
|
476
|
+
|
|
477
|
+
await sql`
|
|
478
|
+
INSERT INTO _emdash_content_bylines_old
|
|
479
|
+
(id, collection_slug, content_id, byline_id, sort_order, role_label, created_at)
|
|
480
|
+
SELECT id, collection_slug, content_id, byline_id, sort_order, role_label, created_at
|
|
481
|
+
FROM _emdash_content_bylines
|
|
482
|
+
`.execute(db);
|
|
483
|
+
|
|
484
|
+
await db.schema.dropTable("_emdash_content_bylines").execute();
|
|
485
|
+
await sql`ALTER TABLE _emdash_content_bylines_old RENAME TO _emdash_content_bylines`.execute(db);
|
|
486
|
+
|
|
487
|
+
await db.schema
|
|
488
|
+
.createIndex("idx_content_bylines_content")
|
|
489
|
+
.on("_emdash_content_bylines")
|
|
490
|
+
.columns(["collection_slug", "content_id", "sort_order"])
|
|
491
|
+
.execute();
|
|
492
|
+
await db.schema
|
|
493
|
+
.createIndex("idx_content_bylines_byline")
|
|
494
|
+
.on("_emdash_content_bylines")
|
|
495
|
+
.column("byline_id")
|
|
496
|
+
.execute();
|
|
497
|
+
}
|
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
import { type Kysely,
|
|
1
|
+
import { type Kysely, sql } from "kysely";
|
|
2
|
+
import { type Migration, type MigrationProvider, Migrator } from "kysely/migration";
|
|
2
3
|
|
|
3
4
|
import type { Database } from "../types.js";
|
|
4
5
|
// Import migrations statically for bundling
|
|
@@ -40,6 +41,7 @@ import * as m036 from "./036_i18n_menus_and_taxonomies.js";
|
|
|
40
41
|
import * as m037 from "./037_credential_algorithm.js";
|
|
41
42
|
import * as m038 from "./038_registry_plugin_state.js";
|
|
42
43
|
import * as m039 from "./039_fix_fts5_triggers.js";
|
|
44
|
+
import * as m040 from "./040_byline_i18n.js";
|
|
43
45
|
|
|
44
46
|
const MIGRATIONS: Readonly<Record<string, Migration>> = Object.freeze({
|
|
45
47
|
"001_initial": m001,
|
|
@@ -80,6 +82,7 @@ const MIGRATIONS: Readonly<Record<string, Migration>> = Object.freeze({
|
|
|
80
82
|
"037_credential_algorithm": m037,
|
|
81
83
|
"038_registry_plugin_state": m038,
|
|
82
84
|
"039_fix_fts5_triggers": m039,
|
|
85
|
+
"040_byline_i18n": m040,
|
|
83
86
|
});
|
|
84
87
|
|
|
85
88
|
/** Total number of registered migrations. Exported for use in tests. */
|
|
@@ -280,12 +280,12 @@ export class AuditRepository {
|
|
|
280
280
|
timestamp: row.timestamp,
|
|
281
281
|
actorId: row.actor_id,
|
|
282
282
|
actorIp: row.actor_ip,
|
|
283
|
-
// eslint-disable-next-line typescript
|
|
283
|
+
// eslint-disable-next-line typescript/no-unsafe-type-assertion -- DB stores string; validated at insert but linter can't follow
|
|
284
284
|
action: row.action as AuditAction,
|
|
285
285
|
resourceType: row.resource_type,
|
|
286
286
|
resourceId: row.resource_id,
|
|
287
287
|
details: row.details ? JSON.parse(row.details) : null,
|
|
288
|
-
// eslint-disable-next-line typescript
|
|
288
|
+
// eslint-disable-next-line typescript/no-unsafe-type-assertion -- DB stores string; validated at insert but linter can't follow
|
|
289
289
|
status: row.status as AuditStatus | null,
|
|
290
290
|
};
|
|
291
291
|
}
|