emdash 0.34.0 → 0.35.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-34EN2eXO.d.mts → adapters-Bb1vG41D.d.mts} +8 -1
- package/dist/adapters-Bb1vG41D.d.mts.map +1 -0
- package/dist/api/route-utils.d.mts +3 -3
- package/dist/api/route-utils.mjs +9 -9
- package/dist/api/schemas/index.d.mts +1 -1
- package/dist/api/schemas/index.mjs +1 -1
- package/dist/{api-DdAsirBe.mjs → api-BeBglVxU.mjs} +10 -10
- package/dist/{api-DdAsirBe.mjs.map → api-BeBglVxU.mjs.map} +1 -1
- package/dist/{api-tokens-CFXu8F_2.mjs → api-tokens-KO24G1Fd.mjs} +2 -2
- package/dist/{api-tokens-CFXu8F_2.mjs.map → api-tokens-KO24G1Fd.mjs.map} +1 -1
- package/dist/{apply-D5zfeD09.mjs → apply-kUDt80-G.mjs} +16 -16
- package/dist/{apply-D5zfeD09.mjs.map → apply-kUDt80-G.mjs.map} +1 -1
- package/dist/astro/index.d.mts +12 -12
- package/dist/astro/index.d.mts.map +1 -1
- package/dist/astro/index.mjs +71 -15
- package/dist/astro/index.mjs.map +1 -1
- package/dist/astro/middleware/auth.d.mts +10 -10
- package/dist/astro/middleware/auth.mjs +4 -4
- package/dist/astro/middleware/redirect.mjs +2 -2
- package/dist/astro/middleware/request-context.mjs +1 -1
- package/dist/astro/middleware/setup.mjs +1 -1
- package/dist/astro/middleware.d.mts +10 -10
- package/dist/astro/middleware.d.mts.map +1 -1
- package/dist/astro/middleware.mjs +143 -74
- package/dist/astro/middleware.mjs.map +1 -1
- package/dist/astro/routes/api/admin/allowed-domains/_domain_.mjs +1 -1
- package/dist/astro/routes/api/admin/allowed-domains/index.mjs +1 -1
- package/dist/astro/routes/api/admin/api-tokens/_id_.mjs +2 -2
- package/dist/astro/routes/api/admin/api-tokens/index.mjs +2 -2
- package/dist/astro/routes/api/admin/byline-fields/_slug_/usage.mjs +2 -2
- package/dist/astro/routes/api/admin/byline-fields/_slug_.mjs +3 -3
- package/dist/astro/routes/api/admin/byline-fields/index.mjs +3 -3
- package/dist/astro/routes/api/admin/byline-fields/reorder.mjs +3 -3
- package/dist/astro/routes/api/admin/bylines/_id_/index.mjs +7 -7
- package/dist/astro/routes/api/admin/bylines/_id_/translations.mjs +7 -7
- package/dist/astro/routes/api/admin/bylines/index.mjs +7 -7
- package/dist/astro/routes/api/admin/comments/_id_/status.mjs +5 -5
- package/dist/astro/routes/api/admin/comments/_id_.mjs +2 -2
- package/dist/astro/routes/api/admin/comments/bulk.mjs +3 -3
- package/dist/astro/routes/api/admin/comments/counts.mjs +2 -2
- package/dist/astro/routes/api/admin/comments/index.mjs +3 -3
- package/dist/astro/routes/api/admin/hooks/exclusive/_hookName_.mjs +1 -1
- package/dist/astro/routes/api/admin/hooks/exclusive/index.mjs +1 -1
- package/dist/astro/routes/api/admin/media-usage/collection-deletions/index.mjs +7 -7
- package/dist/astro/routes/api/admin/media-usage/collection-deletions/retry.mjs +7 -7
- package/dist/astro/routes/api/admin/media-usage/repair.mjs +4 -4
- package/dist/astro/routes/api/admin/media-usage/work/index.mjs +7 -7
- package/dist/astro/routes/api/admin/media-usage/work/retry.mjs +7 -7
- package/dist/astro/routes/api/admin/oauth-clients/_id_.mjs +1 -1
- package/dist/astro/routes/api/admin/oauth-clients/index.mjs +1 -1
- package/dist/astro/routes/api/admin/plugins/_id_/disable.mjs +28 -28
- package/dist/astro/routes/api/admin/plugins/_id_/enable.mjs +28 -28
- package/dist/astro/routes/api/admin/plugins/_id_/index.mjs +28 -28
- package/dist/astro/routes/api/admin/plugins/_id_/mcp.mjs +1 -1
- package/dist/astro/routes/api/admin/plugins/_id_/settings.mjs +28 -28
- package/dist/astro/routes/api/admin/plugins/_id_/uninstall.mjs +28 -28
- package/dist/astro/routes/api/admin/plugins/_id_/update.mjs +28 -28
- package/dist/astro/routes/api/admin/plugins/index.mjs +28 -28
- package/dist/astro/routes/api/admin/plugins/marketplace/_id_/icon.mjs +1 -1
- package/dist/astro/routes/api/admin/plugins/marketplace/_id_/index.mjs +28 -28
- package/dist/astro/routes/api/admin/plugins/marketplace/_id_/install.mjs +28 -28
- package/dist/astro/routes/api/admin/plugins/marketplace/index.mjs +28 -28
- package/dist/astro/routes/api/admin/plugins/registry/_id_/uninstall.mjs +28 -28
- package/dist/astro/routes/api/admin/plugins/registry/_id_/update.mjs +29 -29
- package/dist/astro/routes/api/admin/plugins/registry/artifact.mjs +28 -28
- package/dist/astro/routes/api/admin/plugins/registry/install.mjs +29 -29
- package/dist/astro/routes/api/admin/plugins/updates.mjs +28 -28
- package/dist/astro/routes/api/admin/themes/marketplace/_id_/index.mjs +28 -28
- package/dist/astro/routes/api/admin/themes/marketplace/_id_/thumbnail.mjs +1 -1
- package/dist/astro/routes/api/admin/themes/marketplace/index.mjs +28 -28
- package/dist/astro/routes/api/admin/users/_id_/index.mjs +1 -1
- package/dist/astro/routes/api/admin/users/_id_/send-recovery.mjs +1 -1
- package/dist/astro/routes/api/admin/users/index.mjs +1 -1
- package/dist/astro/routes/api/auth/dev-bypass.d.mts.map +1 -1
- package/dist/astro/routes/api/auth/dev-bypass.mjs +2 -6
- package/dist/astro/routes/api/auth/dev-bypass.mjs.map +1 -1
- package/dist/astro/routes/api/auth/invite/complete.mjs +3 -3
- package/dist/astro/routes/api/auth/invite/index.mjs +2 -2
- package/dist/astro/routes/api/auth/invite/register-options.mjs +3 -3
- package/dist/astro/routes/api/auth/logout.mjs +1 -1
- package/dist/astro/routes/api/auth/magic-link/send.mjs +3 -3
- package/dist/astro/routes/api/auth/magic-link/verify.mjs +1 -1
- package/dist/astro/routes/api/auth/me.mjs +2 -2
- package/dist/astro/routes/api/auth/mode.mjs +1 -1
- package/dist/astro/routes/api/auth/oauth/_provider_/callback.mjs +2 -2
- package/dist/astro/routes/api/auth/oauth/_provider_.mjs +1 -1
- package/dist/astro/routes/api/auth/passkey/_id_.mjs +1 -1
- package/dist/astro/routes/api/auth/passkey/options.mjs +4 -4
- package/dist/astro/routes/api/auth/passkey/register/options.mjs +3 -3
- package/dist/astro/routes/api/auth/passkey/register/verify.mjs +3 -3
- package/dist/astro/routes/api/auth/passkey/verify.mjs +3 -3
- package/dist/astro/routes/api/auth/signup/complete.mjs +3 -3
- package/dist/astro/routes/api/auth/signup/request.mjs +3 -3
- package/dist/astro/routes/api/comments/_collection_/_contentId_/index.mjs +5 -5
- package/dist/astro/routes/api/comments/_collection_/_contentId_/reactions.mjs +4 -4
- package/dist/astro/routes/api/content/_collection_/_id_/compare.mjs +1 -1
- package/dist/astro/routes/api/content/_collection_/_id_/discard-draft.mjs +1 -1
- package/dist/astro/routes/api/content/_collection_/_id_/duplicate.mjs +1 -1
- package/dist/astro/routes/api/content/_collection_/_id_/permanent.mjs +1 -1
- package/dist/astro/routes/api/content/_collection_/_id_/preview-url.mjs +3 -3
- package/dist/astro/routes/api/content/_collection_/_id_/publish.mjs +2 -2
- package/dist/astro/routes/api/content/_collection_/_id_/references/_relation_/children.mjs +9 -9
- package/dist/astro/routes/api/content/_collection_/_id_/references/_relation_/parents.mjs +9 -9
- package/dist/astro/routes/api/content/_collection_/_id_/restore.mjs +1 -1
- package/dist/astro/routes/api/content/_collection_/_id_/revisions.mjs +1 -1
- package/dist/astro/routes/api/content/_collection_/_id_/schedule.mjs +2 -2
- package/dist/astro/routes/api/content/_collection_/_id_/terms/_taxonomy_.mjs +6 -6
- package/dist/astro/routes/api/content/_collection_/_id_/translations.mjs +1 -1
- package/dist/astro/routes/api/content/_collection_/_id_/unpublish.mjs +1 -1
- package/dist/astro/routes/api/content/_collection_/_id_.mjs +2 -2
- package/dist/astro/routes/api/content/_collection_/authors.mjs +1 -1
- package/dist/astro/routes/api/content/_collection_/index.mjs +2 -2
- package/dist/astro/routes/api/content/_collection_/trash.mjs +2 -2
- package/dist/astro/routes/api/dashboard.mjs +4 -4
- package/dist/astro/routes/api/import/probe.d.mts +3 -3
- package/dist/astro/routes/api/import/probe.mjs +5 -5
- package/dist/astro/routes/api/import/wordpress/analyze.mjs +1 -1
- package/dist/astro/routes/api/import/wordpress/execute.d.mts +11 -11
- package/dist/astro/routes/api/import/wordpress/execute.mjs +7 -7
- package/dist/astro/routes/api/import/wordpress/media.d.mts +10 -10
- package/dist/astro/routes/api/import/wordpress/media.mjs +2 -2
- package/dist/astro/routes/api/import/wordpress/prepare.mjs +4 -4
- package/dist/astro/routes/api/import/wordpress/rewrite-urls.d.mts +11 -11
- package/dist/astro/routes/api/import/wordpress/rewrite-urls.mjs +4 -4
- package/dist/astro/routes/api/import/wordpress-plugin/analyze.d.mts +1 -1
- package/dist/astro/routes/api/import/wordpress-plugin/analyze.mjs +5 -5
- package/dist/astro/routes/api/import/wordpress-plugin/execute.d.mts +11 -11
- package/dist/astro/routes/api/import/wordpress-plugin/execute.mjs +11 -11
- package/dist/astro/routes/api/manifest.mjs +2 -2
- package/dist/astro/routes/api/mcp.mjs +38 -38
- package/dist/astro/routes/api/media/_id_/confirm.mjs +2 -2
- package/dist/astro/routes/api/media/_id_/upload.mjs +2 -2
- package/dist/astro/routes/api/media/_id_/usage.mjs +6 -6
- package/dist/astro/routes/api/media/_id_.mjs +5 -5
- package/dist/astro/routes/api/media/providers/_providerId_/_itemId_.mjs +1 -1
- package/dist/astro/routes/api/media/providers/_providerId_/index.mjs +1 -1
- package/dist/astro/routes/api/media/providers/index.mjs +1 -1
- package/dist/astro/routes/api/media/upload-url.mjs +3 -3
- package/dist/astro/routes/api/media.mjs +5 -5
- package/dist/astro/routes/api/menus/_name_/items/_id_.mjs +3 -3
- package/dist/astro/routes/api/menus/_name_/items.mjs +3 -3
- package/dist/astro/routes/api/menus/_name_/reorder.mjs +3 -3
- package/dist/astro/routes/api/menus/_name_/translations.mjs +3 -3
- package/dist/astro/routes/api/menus/_name_.mjs +3 -3
- package/dist/astro/routes/api/menus/index.mjs +3 -3
- package/dist/astro/routes/api/oauth/authorize.mjs +5 -5
- package/dist/astro/routes/api/oauth/device/authorize.mjs +3 -3
- package/dist/astro/routes/api/oauth/device/code.mjs +4 -4
- package/dist/astro/routes/api/oauth/device/token.mjs +4 -4
- package/dist/astro/routes/api/oauth/register.mjs +1 -1
- package/dist/astro/routes/api/oauth/token/refresh.mjs +3 -3
- package/dist/astro/routes/api/oauth/token/revoke.mjs +3 -3
- package/dist/astro/routes/api/oauth/token.mjs +4 -4
- package/dist/astro/routes/api/openapi.json.mjs +1 -1
- package/dist/astro/routes/api/plugins/_pluginId_/_...path_.mjs +3 -3
- package/dist/astro/routes/api/redirects/404s/index.mjs +3 -3
- package/dist/astro/routes/api/redirects/404s/summary.mjs +3 -3
- package/dist/astro/routes/api/redirects/_id_.mjs +4 -4
- package/dist/astro/routes/api/redirects/index.mjs +4 -4
- package/dist/astro/routes/api/relations/_id_/index.mjs +9 -9
- package/dist/astro/routes/api/relations/_id_/translations.mjs +8 -8
- package/dist/astro/routes/api/relations/index.mjs +9 -9
- package/dist/astro/routes/api/revisions/_revisionId_/index.mjs +1 -1
- package/dist/astro/routes/api/revisions/_revisionId_/restore.mjs +1 -1
- package/dist/astro/routes/api/schema/collections/_slug_/fields/_fieldSlug_.mjs +28 -28
- package/dist/astro/routes/api/schema/collections/_slug_/fields/index.mjs +28 -28
- package/dist/astro/routes/api/schema/collections/_slug_/fields/reorder.mjs +28 -28
- package/dist/astro/routes/api/schema/collections/_slug_/index.mjs +28 -28
- package/dist/astro/routes/api/schema/collections/index.mjs +28 -28
- package/dist/astro/routes/api/schema/collections/reorder.mjs +28 -28
- package/dist/astro/routes/api/schema/index.mjs +6 -6
- package/dist/astro/routes/api/schema/orphans/_slug_.mjs +28 -28
- package/dist/astro/routes/api/schema/orphans/index.mjs +28 -28
- package/dist/astro/routes/api/search/enable.mjs +5 -5
- package/dist/astro/routes/api/search/index.mjs +4 -4
- package/dist/astro/routes/api/search/rebuild.mjs +5 -5
- package/dist/astro/routes/api/search/stats.mjs +4 -4
- package/dist/astro/routes/api/search/suggest.mjs +4 -4
- package/dist/astro/routes/api/sections/_slug_.mjs +4 -4
- package/dist/astro/routes/api/sections/index.mjs +4 -4
- package/dist/astro/routes/api/settings/backups/archives/_name_.mjs +3 -3
- package/dist/astro/routes/api/settings/backups/archives/index.mjs +3 -3
- package/dist/astro/routes/api/settings/backups/export.mjs +3 -3
- package/dist/astro/routes/api/settings/backups/index.mjs +3 -3
- package/dist/astro/routes/api/settings/email.mjs +1 -1
- package/dist/astro/routes/api/settings.mjs +5 -5
- package/dist/astro/routes/api/setup/admin-verify.mjs +4 -4
- package/dist/astro/routes/api/setup/admin.mjs +4 -4
- package/dist/astro/routes/api/setup/dev-bypass.d.mts.map +1 -1
- package/dist/astro/routes/api/setup/dev-bypass.mjs +18 -21
- package/dist/astro/routes/api/setup/dev-bypass.mjs.map +1 -1
- package/dist/astro/routes/api/setup/index.d.mts.map +1 -1
- package/dist/astro/routes/api/setup/index.mjs +15 -21
- package/dist/astro/routes/api/setup/index.mjs.map +1 -1
- package/dist/astro/routes/api/setup/status.mjs +2 -2
- package/dist/astro/routes/api/snapshot.mjs +4 -4
- package/dist/astro/routes/api/taxonomies/_name_/reorder.mjs +6 -6
- package/dist/astro/routes/api/taxonomies/_name_/terms/_slug_/translations.mjs +6 -6
- package/dist/astro/routes/api/taxonomies/_name_/terms/_slug_.mjs +6 -6
- package/dist/astro/routes/api/taxonomies/_name_/terms/index.mjs +6 -6
- package/dist/astro/routes/api/taxonomies/_name_/translations.mjs +6 -6
- package/dist/astro/routes/api/taxonomies/_name_.mjs +6 -6
- package/dist/astro/routes/api/taxonomies/index.mjs +6 -6
- package/dist/astro/routes/api/themes/preview.mjs +2 -2
- package/dist/astro/routes/api/typegen.mjs +3 -3
- package/dist/astro/routes/api/well-known/auth.mjs +1 -1
- package/dist/astro/routes/api/well-known/oauth-authorization-server.mjs +1 -1
- package/dist/astro/routes/api/well-known/oauth-protected-resource.mjs +1 -1
- package/dist/astro/routes/api/widget-areas/_name_/reorder.mjs +2 -2
- package/dist/astro/routes/api/widget-areas/_name_/widgets/_id_.mjs +4 -4
- package/dist/astro/routes/api/widget-areas/_name_/widgets.mjs +4 -4
- package/dist/astro/routes/api/widget-areas/_name_.mjs +3 -3
- package/dist/astro/routes/api/widget-areas/index.mjs +4 -4
- package/dist/astro/routes/robots.txt.mjs +2 -2
- package/dist/astro/routes/sitemap-_collection_.xml.mjs +2 -2
- package/dist/astro/routes/sitemap.xml.mjs +2 -2
- package/dist/astro/types.d.mts +14 -14
- package/dist/auth/providers/github.d.mts +1 -1
- package/dist/auth/providers/google.d.mts +1 -1
- package/dist/{authorize-1iFJzPaZ.mjs → authorize-DUElxgOQ.mjs} +1 -1
- package/dist/{authorize-1iFJzPaZ.mjs.map → authorize-DUElxgOQ.mjs.map} +1 -1
- package/dist/{backup-LHjIAVNP.mjs → backup-DWYpJlLj.mjs} +3 -3
- package/dist/{backup-LHjIAVNP.mjs.map → backup-DWYpJlLj.mjs.map} +1 -1
- package/dist/{bundle-CBEXrBnb.mjs → bundle-vn56sLos.mjs} +5 -5
- package/dist/{bundle-CBEXrBnb.mjs.map → bundle-vn56sLos.mjs.map} +1 -1
- package/dist/{byline-fields-C5S8wygO.mjs → byline-fields-txaLGoME.mjs} +1 -1
- package/dist/{byline-fields-C5S8wygO.mjs.map → byline-fields-txaLGoME.mjs.map} +1 -1
- package/dist/{byline-pEcoDps8.mjs → byline-yjvWq4ip.mjs} +4 -4
- package/dist/{byline-pEcoDps8.mjs.map → byline-yjvWq4ip.mjs.map} +1 -1
- package/dist/{bylines-DJfSfXCL.mjs → bylines-Bu7pchQ4.mjs} +3 -3
- package/dist/{bylines-DJfSfXCL.mjs.map → bylines-Bu7pchQ4.mjs.map} +1 -1
- package/dist/{bylines-BWemdX2k.mjs → bylines-DjXS5p0P.mjs} +5 -5
- package/dist/{bylines-BWemdX2k.mjs.map → bylines-DjXS5p0P.mjs.map} +1 -1
- package/dist/{cache-CBJaDy_E.mjs → cache-C46-3Irl.mjs} +2 -2
- package/dist/{cache-CBJaDy_E.mjs.map → cache-C46-3Irl.mjs.map} +1 -1
- package/dist/{challenge-store-CZyFVaad.mjs → challenge-store-SIL5DsF2.mjs} +1 -1
- package/dist/{challenge-store-CZyFVaad.mjs.map → challenge-store-SIL5DsF2.mjs.map} +1 -1
- package/dist/{chunks-DfPax1I0.mjs → chunks-fiZ8G9RJ.mjs} +2 -2
- package/dist/{chunks-DfPax1I0.mjs.map → chunks-fiZ8G9RJ.mjs.map} +1 -1
- package/dist/cli/index.mjs +551 -51
- package/dist/cli/index.mjs.map +1 -1
- package/dist/client/cf-access.d.mts +1 -1
- package/dist/client/index.d.mts +2 -2
- package/dist/client/index.mjs +2 -2
- package/dist/{collection-deletion-C8BugSGz.mjs → collection-deletion-DQPvMD8R.mjs} +2 -2
- package/dist/{collection-deletion-C8BugSGz.mjs.map → collection-deletion-DQPvMD8R.mjs.map} +1 -1
- package/dist/{comment-reaction-D6qfHKBc.mjs → comment-reaction-D-2J84UE.mjs} +2 -2
- package/dist/{comment-reaction-D6qfHKBc.mjs.map → comment-reaction-D-2J84UE.mjs.map} +1 -1
- package/dist/{comments-CTOuhTSX.mjs → comments-CTfZtLmM.mjs} +1 -1
- package/dist/{comments-CTOuhTSX.mjs.map → comments-CTfZtLmM.mjs.map} +1 -1
- package/dist/config-COQzTe5Q.d.mts +34 -0
- package/dist/config-COQzTe5Q.d.mts.map +1 -0
- package/dist/{content-BNfwh7xX.mjs → content-ZHCc1ngN.mjs} +3 -3
- package/dist/{content-BNfwh7xX.mjs.map → content-ZHCc1ngN.mjs.map} +1 -1
- package/dist/{content-list-query-DhQ84eVV.d.mts → content-list-query-wJ2WN8Vp.d.mts} +1 -1
- package/dist/{content-list-query-DhQ84eVV.d.mts.map → content-list-query-wJ2WN8Vp.d.mts.map} +1 -1
- package/dist/{content-refresh-DNERP4-f.mjs → content-refresh-B_8SJzuU.mjs} +2 -2
- package/dist/{content-refresh-DNERP4-f.mjs.map → content-refresh-B_8SJzuU.mjs.map} +1 -1
- package/dist/{context-DRgOvSnW.mjs → context-ZldbZcle.mjs} +7 -7
- package/dist/{context-DRgOvSnW.mjs.map → context-ZldbZcle.mjs.map} +1 -1
- package/dist/{dashboard-CB8J89rJ.mjs → dashboard-DvHbk_cv.mjs} +3 -3
- package/dist/{dashboard-CB8J89rJ.mjs.map → dashboard-DvHbk_cv.mjs.map} +1 -1
- package/dist/db/index.d.mts +4 -4
- package/dist/db/index.mjs +30 -7
- package/dist/db/index.mjs.map +1 -1
- package/dist/db/libsql-migrations.d.mts +11 -0
- package/dist/db/libsql-migrations.d.mts.map +1 -0
- package/dist/db/libsql-migrations.mjs +57 -0
- package/dist/db/libsql-migrations.mjs.map +1 -0
- package/dist/db/libsql.d.mts +1 -1
- package/dist/db/postgres-migrations.d.mts +10 -0
- package/dist/db/postgres-migrations.d.mts.map +1 -0
- package/dist/db/postgres-migrations.mjs +47 -0
- package/dist/db/postgres-migrations.mjs.map +1 -0
- package/dist/db/postgres.d.mts +1 -1
- package/dist/db/sqlite-migrations.d.mts +10 -0
- package/dist/db/sqlite-migrations.d.mts.map +1 -0
- package/dist/db/sqlite-migrations.mjs +28 -0
- package/dist/db/sqlite-migrations.mjs.map +1 -0
- package/dist/db/sqlite.d.mts +1 -1
- package/dist/{deferred-tasks-BMsa9F64.d.mts → deferred-tasks-SDWxrgzJ.d.mts} +1 -1
- package/dist/{deferred-tasks-BMsa9F64.d.mts.map → deferred-tasks-SDWxrgzJ.d.mts.map} +1 -1
- package/dist/{device-flow-CaioYGK3.mjs → device-flow-C0GdD_z8.mjs} +4 -4
- package/dist/{device-flow-CaioYGK3.mjs.map → device-flow-C0GdD_z8.mjs.map} +1 -1
- package/dist/direct-executor-CDXeJCSs.mjs +85 -0
- package/dist/direct-executor-CDXeJCSs.mjs.map +1 -0
- package/dist/{escape-C_aLKP3H.mjs → escape-DUY2r2Zs.mjs} +1 -1
- package/dist/{escape-C_aLKP3H.mjs.map → escape-DUY2r2Zs.mjs.map} +1 -1
- package/dist/{field-defs-cache-hg6QkjV9.mjs → field-defs-cache-BzwBlJrR.mjs} +2 -2
- package/dist/{field-defs-cache-hg6QkjV9.mjs.map → field-defs-cache-BzwBlJrR.mjs.map} +1 -1
- package/dist/{fts-manager-CZ-5dVwJ.mjs → fts-manager-DyZEohZC.mjs} +2 -2
- package/dist/{fts-manager-CZ-5dVwJ.mjs.map → fts-manager-DyZEohZC.mjs.map} +1 -1
- package/dist/{hreflang-DNswoYsi.mjs → hreflang-BBe83kKa.mjs} +5 -5
- package/dist/{hreflang-DNswoYsi.mjs.map → hreflang-BBe83kKa.mjs.map} +1 -1
- package/dist/{hreflang-D3Uehfv2.d.mts → hreflang-DwT2E0Sa.d.mts} +2 -2
- package/dist/{hreflang-D3Uehfv2.d.mts.map → hreflang-DwT2E0Sa.d.mts.map} +1 -1
- package/dist/identity-Ys6Dlc9C.mjs +35 -0
- package/dist/identity-Ys6Dlc9C.mjs.map +1 -0
- package/dist/{import-B41u8Rot.mjs → import-DPkLmeXO.mjs} +2 -2
- package/dist/{import-B41u8Rot.mjs.map → import-DPkLmeXO.mjs.map} +1 -1
- package/dist/{index-C3Y-rsyN.d.mts → index-BVBZj4-7.d.mts} +28 -49
- package/dist/index-BVBZj4-7.d.mts.map +1 -0
- package/dist/{index-Cof4-Fab.d.mts → index-C9KuQyO-.d.mts} +3 -3
- package/dist/{index-Cof4-Fab.d.mts.map → index-C9KuQyO-.d.mts.map} +1 -1
- package/dist/index.d.mts +21 -20
- package/dist/index.mjs +42 -42
- package/dist/{load-DmvJrtxS.mjs → load-YJ2xl3ra.mjs} +2 -2
- package/dist/{load-DmvJrtxS.mjs.map → load-YJ2xl3ra.mjs.map} +1 -1
- package/dist/{loader-DLBqRiGP.mjs → loader-CdG_Ci3H.mjs} +2 -2
- package/dist/{loader-DLBqRiGP.mjs.map → loader-CdG_Ci3H.mjs.map} +1 -1
- package/dist/manifest-builder-B252yQUf.mjs +189 -0
- package/dist/manifest-builder-B252yQUf.mjs.map +1 -0
- package/dist/media/index.d.mts +1 -1
- package/dist/media/local-runtime.d.mts +12 -12
- package/dist/media/local-runtime.mjs +2 -2
- package/dist/{media-allowlist-BD6HhgXA.mjs → media-allowlist-D6x-Us02.mjs} +1 -1
- package/dist/{media-allowlist-BD6HhgXA.mjs.map → media-allowlist-D6x-Us02.mjs.map} +1 -1
- package/dist/{media-upload-9yas9zGH.mjs → media-upload-CHBVn6m-.mjs} +2 -2
- package/dist/{media-upload-9yas9zGH.mjs.map → media-upload-CHBVn6m-.mjs.map} +1 -1
- package/dist/{media-usage-De3qvwjc.mjs → media-usage-BZCydfvu.mjs} +4 -4
- package/dist/{media-usage-De3qvwjc.mjs.map → media-usage-BZCydfvu.mjs.map} +1 -1
- package/dist/{media-usage-work-B9Bksh_b.mjs → media-usage-work-CLo_6tct.mjs} +2 -2
- package/dist/{media-usage-work-B9Bksh_b.mjs.map → media-usage-work-CLo_6tct.mjs.map} +1 -1
- package/dist/{menus-CC-yn1F9.mjs → menus-DSo5QeW0.mjs} +6 -6
- package/dist/{menus-CC-yn1F9.mjs.map → menus-DSo5QeW0.mjs.map} +1 -1
- package/dist/{menus-fxvEDYE6.mjs → menus-TCNSd2vp.mjs} +2 -2
- package/dist/{menus-fxvEDYE6.mjs.map → menus-TCNSd2vp.mjs.map} +1 -1
- package/dist/migrations/index.d.mts +22 -0
- package/dist/migrations/index.d.mts.map +1 -0
- package/dist/migrations/index.mjs +7 -0
- package/dist/{mode-Bpe-tNNy.mjs → mode-BDoH_WcF.mjs} +1 -1
- package/dist/{mode-Bpe-tNNy.mjs.map → mode-BDoH_WcF.mjs.map} +1 -1
- package/dist/{oauth-authorization-BXO1MKej.mjs → oauth-authorization-iOikmrJd.mjs} +4 -4
- package/dist/{oauth-authorization-BXO1MKej.mjs.map → oauth-authorization-iOikmrJd.mjs.map} +1 -1
- package/dist/{oauth-clients-C_DNqtRu.mjs → oauth-clients-CvI0nHMJ.mjs} +1 -1
- package/dist/{oauth-clients-C_DNqtRu.mjs.map → oauth-clients-CvI0nHMJ.mjs.map} +1 -1
- package/dist/{oauth-state-store-DwAxMtk4.mjs → oauth-state-store-Ba8KZlwW.mjs} +1 -1
- package/dist/{oauth-state-store-DwAxMtk4.mjs.map → oauth-state-store-Ba8KZlwW.mjs.map} +1 -1
- package/dist/{oauth-user-lookup-BxfZizdk.mjs → oauth-user-lookup-C5SQwGYC.mjs} +1 -1
- package/dist/{oauth-user-lookup-BxfZizdk.mjs.map → oauth-user-lookup-C5SQwGYC.mjs.map} +1 -1
- package/dist/object-cache/memory.d.mts +1 -1
- package/dist/{options-DRe1pIBL.d.mts → options--hhz-jZ1.d.mts} +3 -3
- package/dist/{options-DRe1pIBL.d.mts.map → options--hhz-jZ1.d.mts.map} +1 -1
- package/dist/page/index.d.mts +2 -2
- package/dist/{passkey-config-_2GOwwK8.mjs → passkey-config-DFAmUyuE.mjs} +1 -1
- package/dist/{passkey-config-_2GOwwK8.mjs.map → passkey-config-DFAmUyuE.mjs.map} +1 -1
- package/dist/{placeholder-CzW7Lshs.d.mts → placeholder-Dp0K3RkD.d.mts} +1 -1
- package/dist/{placeholder-CzW7Lshs.d.mts.map → placeholder-Dp0K3RkD.d.mts.map} +1 -1
- package/dist/plugin-types.d.mts +1 -1
- package/dist/plugin-utils.d.mts +10 -10
- package/dist/plugins/adapt-sandbox-entry.d.mts +10 -10
- package/dist/policy-TluUIxuu.mjs +45 -0
- package/dist/policy-TluUIxuu.mjs.map +1 -0
- package/dist/{portable-text-DhKbDAGr.mjs → portable-text-imBW5cHK.mjs} +1 -1
- package/dist/{portable-text-DhKbDAGr.mjs.map → portable-text-imBW5cHK.mjs.map} +1 -1
- package/dist/protocol-DjsJHTlK.d.mts +52 -0
- package/dist/protocol-DjsJHTlK.d.mts.map +1 -0
- package/dist/{query-vgZNwIhh.mjs → query-BWs7O5Il.mjs} +3 -3
- package/dist/{query-vgZNwIhh.mjs.map → query-BWs7O5Il.mjs.map} +1 -1
- package/dist/{query-BgjfiLUQ.mjs → query-zTVAR1Sl.mjs} +12 -12
- package/dist/{query-BgjfiLUQ.mjs.map → query-zTVAR1Sl.mjs.map} +1 -1
- package/dist/{rate-limit-L5anykgo.mjs → rate-limit-Bx4g9m3p.mjs} +1 -1
- package/dist/{rate-limit-L5anykgo.mjs.map → rate-limit-Bx4g9m3p.mjs.map} +1 -1
- package/dist/{redirect-KBNE3UEs.mjs → redirect-BgAOGHDq.mjs} +1 -1
- package/dist/{redirect-KBNE3UEs.mjs.map → redirect-BgAOGHDq.mjs.map} +1 -1
- package/dist/{redirects-cV9g7V-0.mjs → redirects-DTDHWH31.mjs} +2 -2
- package/dist/{redirects-cV9g7V-0.mjs.map → redirects-DTDHWH31.mjs.map} +1 -1
- package/dist/{redirects-CufRQt0Q.mjs → redirects-DyChwDkG.mjs} +1 -1
- package/dist/{redirects-CufRQt0Q.mjs.map → redirects-DyChwDkG.mjs.map} +1 -1
- package/dist/{registry-C581V4TP.mjs → registry-Cqa2I749.mjs} +6 -6
- package/dist/{registry-C581V4TP.mjs.map → registry-Cqa2I749.mjs.map} +1 -1
- package/dist/{relation-DtmAQH7s.mjs → relation-BnHB0T4J.mjs} +2 -2
- package/dist/{relation-DtmAQH7s.mjs.map → relation-BnHB0T4J.mjs.map} +1 -1
- package/dist/{relations-DItI3MN9.d.mts → relations-BHo5A8Zf.d.mts} +35 -35
- package/dist/{relations-DItI3MN9.d.mts.map → relations-BHo5A8Zf.d.mts.map} +1 -1
- package/dist/{relations-DICSyfsh.mjs → relations-D5sM5fW0.mjs} +4 -4
- package/dist/{relations-DICSyfsh.mjs.map → relations-D5sM5fW0.mjs.map} +1 -1
- package/dist/request-context.d.mts +1 -1
- package/dist/{runner-CgQbELYC.d.mts → runner-BYHZn3Jy.d.mts} +16 -3
- package/dist/runner-BYHZn3Jy.d.mts.map +1 -0
- package/dist/{runner-BiDvq5dv.mjs → runner-C1T11CfC.mjs} +34 -4
- package/dist/{runner-BiDvq5dv.mjs.map → runner-C1T11CfC.mjs.map} +1 -1
- package/dist/runtime.d.mts +11 -11
- package/dist/runtime.mjs +1 -1
- package/dist/{schema-CeQSNwB3.mjs → schema-2AOsSn2v.mjs} +4 -4
- package/dist/{schema-CeQSNwB3.mjs.map → schema-2AOsSn2v.mjs.map} +1 -1
- package/dist/{schema-BFyTg38T.mjs → schema-DZ5YVVZj.mjs} +3 -3
- package/dist/{schema-BFyTg38T.mjs.map → schema-DZ5YVVZj.mjs.map} +1 -1
- package/dist/{scopes-BVeuhGBE.mjs → scopes-8ClPF2bC.mjs} +2 -2
- package/dist/{scopes-BVeuhGBE.mjs.map → scopes-8ClPF2bC.mjs.map} +1 -1
- package/dist/{search-BpuPKZb0.mjs → search-u1QYdOCG.mjs} +4 -4
- package/dist/{search-BpuPKZb0.mjs.map → search-u1QYdOCG.mjs.map} +1 -1
- package/dist/{secrets-dtYs2hDo.mjs → secrets-BEgsAQEU.mjs} +1 -1
- package/dist/{secrets-dtYs2hDo.mjs.map → secrets-BEgsAQEU.mjs.map} +1 -1
- package/dist/{sections-COctk6hf.mjs → sections-DmHviGyM.mjs} +2 -2
- package/dist/{sections-COctk6hf.mjs.map → sections-DmHviGyM.mjs.map} +1 -1
- package/dist/seed/index.d.mts +2 -2
- package/dist/seed/index.mjs +13 -13
- package/dist/seo/index.d.mts +3 -3
- package/dist/seo/index.mjs +9 -9
- package/dist/{seo-CvDxfvFb.mjs → seo-Dq4G-RrO.mjs} +2 -2
- package/dist/{seo-CvDxfvFb.mjs.map → seo-Dq4G-RrO.mjs.map} +1 -1
- package/dist/{service-xMiMSTsR.mjs → service-BpArayPr.mjs} +2 -2
- package/dist/{service-xMiMSTsR.mjs.map → service-BpArayPr.mjs.map} +1 -1
- package/dist/{session-user-BzVemLkw.mjs → session-user-BEorKVT-.mjs} +1 -1
- package/dist/{session-user-BzVemLkw.mjs.map → session-user-BEorKVT-.mjs.map} +1 -1
- package/dist/{settings-BE9aqn_9.mjs → settings-DE9xtzqd.mjs} +3 -3
- package/dist/{settings-BE9aqn_9.mjs.map → settings-DE9xtzqd.mjs.map} +1 -1
- package/dist/{settings-B372MV0p.mjs → settings-xRdoUZr0.mjs} +2 -2
- package/dist/{settings-B372MV0p.mjs.map → settings-xRdoUZr0.mjs.map} +1 -1
- package/dist/{setup-complete-DF7TAfD5.mjs → setup-complete-BnT8pq_C.mjs} +1 -1
- package/dist/{setup-complete-DF7TAfD5.mjs.map → setup-complete-BnT8pq_C.mjs.map} +1 -1
- package/dist/{setup-nonce-Do-U_cg9.mjs → setup-nonce-CBitf_oQ.mjs} +1 -1
- package/dist/{setup-nonce-Do-U_cg9.mjs.map → setup-nonce-CBitf_oQ.mjs.map} +1 -1
- package/dist/{site-url-Bowsi9T-.mjs → site-url-DjpIXMXJ.mjs} +1 -1
- package/dist/{site-url-Bowsi9T-.mjs.map → site-url-DjpIXMXJ.mjs.map} +1 -1
- package/dist/{snapshot-B5h6aPMh.mjs → snapshot-BBlGkb2q.mjs} +1 -1
- package/dist/{snapshot-B5h6aPMh.mjs.map → snapshot-BBlGkb2q.mjs.map} +1 -1
- package/dist/storage/local.d.mts +1 -1
- package/dist/storage/local.mjs +2 -2
- package/dist/storage/s3.d.mts +1 -1
- package/dist/target-DixqqV5i.mjs +27 -0
- package/dist/target-DixqqV5i.mjs.map +1 -0
- package/dist/{taxonomies-B0o9ExNV.mjs → taxonomies-BlrncHi9.mjs} +5 -5
- package/dist/{taxonomies-B0o9ExNV.mjs.map → taxonomies-BlrncHi9.mjs.map} +1 -1
- package/dist/{taxonomies-Dk3MAklL.mjs → taxonomies-OHUIiIpI.mjs} +4 -4
- package/dist/{taxonomies-Dk3MAklL.mjs.map → taxonomies-OHUIiIpI.mjs.map} +1 -1
- package/dist/{taxonomy-CPeM8d2o.mjs → taxonomy-BqCZ1TdU.mjs} +3 -3
- package/dist/{taxonomy-CPeM8d2o.mjs.map → taxonomy-BqCZ1TdU.mjs.map} +1 -1
- package/dist/{transport--CfOflrp.mjs → transport-DBJwa-Si.mjs} +1 -1
- package/dist/{transport--CfOflrp.mjs.map → transport-DBJwa-Si.mjs.map} +1 -1
- package/dist/{transport-B_rfeU-a.d.mts → transport-RQE36APG.d.mts} +1 -1
- package/dist/{transport-B_rfeU-a.d.mts.map → transport-RQE36APG.d.mts.map} +1 -1
- package/dist/{types-CFUfyt1s.d.mts → types-BcqdcT-r.d.mts} +1 -1
- package/dist/{types-CFUfyt1s.d.mts.map → types-BcqdcT-r.d.mts.map} +1 -1
- package/dist/{types-CPx2lIGo.d.mts → types-BntycPTF.d.mts} +1 -1
- package/dist/{types-CPx2lIGo.d.mts.map → types-BntycPTF.d.mts.map} +1 -1
- package/dist/{types-C3_AbkDP.d.mts → types-C2pMvO62.d.mts} +1 -1
- package/dist/{types-C3_AbkDP.d.mts.map → types-C2pMvO62.d.mts.map} +1 -1
- package/dist/{types-DefV3OiO.d.mts → types-CXnOzDe1.d.mts} +1 -1
- package/dist/{types-DefV3OiO.d.mts.map → types-CXnOzDe1.d.mts.map} +1 -1
- package/dist/{types-D4_1Ga4L.d.mts → types-DN64_zzZ.d.mts} +3 -3
- package/dist/{types-D4_1Ga4L.d.mts.map → types-DN64_zzZ.d.mts.map} +1 -1
- package/dist/{types-CAGdePf3.d.mts → types-DQIDRKF2.d.mts} +1 -1
- package/dist/{types-CAGdePf3.d.mts.map → types-DQIDRKF2.d.mts.map} +1 -1
- package/dist/{types-BPuloofb.d.mts → types-DWRhk9xZ.d.mts} +1 -1
- package/dist/{types-BPuloofb.d.mts.map → types-DWRhk9xZ.d.mts.map} +1 -1
- package/dist/{types-X0MThr7x.d.mts → types-Dfk8KI5R.d.mts} +1 -1
- package/dist/{types-X0MThr7x.d.mts.map → types-Dfk8KI5R.d.mts.map} +1 -1
- package/dist/{types-Cs-TFLNf.d.mts → types-DrJrVCT1.d.mts} +3 -3
- package/dist/{types-Cs-TFLNf.d.mts.map → types-DrJrVCT1.d.mts.map} +1 -1
- package/dist/{upload-attempts-hlne3iA1.mjs → upload-attempts-D4FS8LT6.mjs} +1 -1
- package/dist/{upload-attempts-hlne3iA1.mjs.map → upload-attempts-D4FS8LT6.mjs.map} +1 -1
- package/dist/{user-sHgJ62SP.mjs → user-DJZfUJVE.mjs} +2 -2
- package/dist/{user-sHgJ62SP.mjs.map → user-DJZfUJVE.mjs.map} +1 -1
- package/dist/{validate-BkqIG_Uj.mjs → validate-BMLBvxOC.mjs} +2 -2
- package/dist/{validate-BkqIG_Uj.mjs.map → validate-BMLBvxOC.mjs.map} +1 -1
- package/dist/{validate-DeGtBN84.d.mts → validate-CTqt5nuE.d.mts} +5 -5
- package/dist/{validate-DeGtBN84.d.mts.map → validate-CTqt5nuE.d.mts.map} +1 -1
- package/dist/{validation-CiJb_X5o.mjs → validation-npvENUCB.mjs} +7 -7
- package/dist/{validation-CiJb_X5o.mjs.map → validation-npvENUCB.mjs.map} +1 -1
- package/dist/version-DB_fqCSI.mjs +7 -0
- package/dist/{version-x0NjTScG.mjs.map → version-DB_fqCSI.mjs.map} +1 -1
- package/dist/{widgets-Cwzvww0W.mjs → widgets-BD3ho7Rq.mjs} +2 -2
- package/dist/{widgets-Cwzvww0W.mjs.map → widgets-BD3ho7Rq.mjs.map} +1 -1
- package/dist/{wxr-taxonomies-QZjWxjyk.mjs → wxr-taxonomies-B1R3vBoD.mjs} +3 -3
- package/dist/{wxr-taxonomies-QZjWxjyk.mjs.map → wxr-taxonomies-B1R3vBoD.mjs.map} +1 -1
- package/dist/{wxr-taxonomies-CmC0ZsDr.d.mts → wxr-taxonomies-Ca68766D.d.mts} +1 -1
- package/dist/{wxr-taxonomies-CmC0ZsDr.d.mts.map → wxr-taxonomies-Ca68766D.d.mts.map} +1 -1
- package/dist/{zod-generator-D11MhxG4.mjs → zod-generator-LC-on_Vb.mjs} +2 -2
- package/dist/{zod-generator-D11MhxG4.mjs.map → zod-generator-LC-on_Vb.mjs.map} +1 -1
- package/package.json +21 -5
- package/src/astro/integration/index.ts +46 -14
- package/src/astro/integration/runtime.ts +3 -0
- package/src/astro/middleware/scoped-db.ts +21 -0
- package/src/astro/middleware.ts +67 -10
- package/src/astro/routes/api/auth/dev-bypass.ts +0 -4
- package/src/astro/routes/api/setup/dev-bypass.ts +2 -7
- package/src/astro/routes/api/setup/index.ts +5 -13
- package/src/cli/commands/migrate.ts +593 -0
- package/src/cli/index.ts +2 -23
- package/src/database/index.ts +8 -2
- package/src/database/migrations/policy.ts +70 -0
- package/src/database/migrations/runner.ts +49 -3
- package/src/db/adapters.ts +50 -2
- package/src/db/index.ts +3 -1
- package/src/db/libsql-migrations.ts +72 -0
- package/src/db/postgres-migrations.ts +59 -0
- package/src/db/sqlite-migrations.ts +37 -0
- package/src/emdash-runtime.ts +44 -15
- package/src/i18n/normalize.ts +31 -0
- package/src/index.ts +7 -1
- package/src/migrations/config-loader.ts +205 -0
- package/src/migrations/direct-executor.ts +141 -0
- package/src/migrations/identity.ts +46 -0
- package/src/migrations/index.ts +19 -0
- package/src/migrations/integration-metadata.ts +67 -0
- package/src/migrations/manifest-builder.ts +55 -0
- package/src/migrations/manifest-writer.ts +63 -0
- package/src/migrations/manifest.ts +197 -0
- package/src/migrations/protocol.ts +59 -0
- package/src/migrations/target.ts +35 -0
- package/src/virtual-modules.d.ts +8 -0
- package/dist/adapters-34EN2eXO.d.mts.map +0 -1
- package/dist/index-C3Y-rsyN.d.mts.map +0 -1
- package/dist/runner-CgQbELYC.d.mts.map +0 -1
- package/dist/version-x0NjTScG.mjs +0 -7
- /package/dist/{api-tokens-CyTsLszZ.mjs → api-tokens-rIXC6LdE.mjs} +0 -0
|
@@ -0,0 +1,205 @@
|
|
|
1
|
+
import { access } from "node:fs/promises";
|
|
2
|
+
import { createRequire } from "node:module";
|
|
3
|
+
import { isAbsolute, resolve } from "node:path";
|
|
4
|
+
import { pathToFileURL } from "node:url";
|
|
5
|
+
|
|
6
|
+
import type { AstroI18nInput } from "../i18n/normalize.js";
|
|
7
|
+
import { normalizeAstroI18n } from "../i18n/normalize.js";
|
|
8
|
+
import type { CoreMigrationIdentity } from "./identity.js";
|
|
9
|
+
import {
|
|
10
|
+
getMigrationIntegrationMetadata,
|
|
11
|
+
MIGRATION_CONFIG_SYMBOL,
|
|
12
|
+
} from "./integration-metadata.js";
|
|
13
|
+
import { buildMigrationManifest } from "./manifest-builder.js";
|
|
14
|
+
import type { MigrationManifestV1 } from "./manifest.js";
|
|
15
|
+
|
|
16
|
+
const ASTRO_CONFIG_FILENAMES = [
|
|
17
|
+
"astro.config.mjs",
|
|
18
|
+
"astro.config.js",
|
|
19
|
+
"astro.config.ts",
|
|
20
|
+
"astro.config.mts",
|
|
21
|
+
] as const;
|
|
22
|
+
|
|
23
|
+
interface EvaluatedAstroConfig {
|
|
24
|
+
integrations?: unknown[];
|
|
25
|
+
i18n?: AstroI18nInput | null;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
export interface BuildMigrationManifestFromConfigOptions {
|
|
29
|
+
projectRoot: string;
|
|
30
|
+
configFile?: string;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
export interface MigrationConfigLoaderDependencies {
|
|
34
|
+
findConfigFile: (projectRoot: string, configFile?: string) => Promise<string>;
|
|
35
|
+
loadConfig: (projectRoot: string, configFile: string) => Promise<unknown>;
|
|
36
|
+
loadIdentity: (projectRoot: string) => Promise<CoreMigrationIdentity>;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
export class MigrationConfigLoaderError extends Error {
|
|
40
|
+
constructor(message: string, options?: ErrorOptions) {
|
|
41
|
+
super(message, options);
|
|
42
|
+
this.name = "MigrationConfigLoaderError";
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
async function isAccessible(path: string): Promise<boolean> {
|
|
47
|
+
try {
|
|
48
|
+
await access(path);
|
|
49
|
+
return true;
|
|
50
|
+
} catch {
|
|
51
|
+
return false;
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
export async function findAstroConfigFile(
|
|
56
|
+
projectRoot: string,
|
|
57
|
+
configFile?: string,
|
|
58
|
+
): Promise<string> {
|
|
59
|
+
const root = resolve(projectRoot);
|
|
60
|
+
if (configFile) {
|
|
61
|
+
const explicitPath = isAbsolute(configFile) ? configFile : resolve(root, configFile);
|
|
62
|
+
if (await isAccessible(explicitPath)) return explicitPath;
|
|
63
|
+
throw new MigrationConfigLoaderError(`Astro config file not found: ${explicitPath}`);
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
for (const filename of ASTRO_CONFIG_FILENAMES) {
|
|
67
|
+
const candidate = resolve(root, filename);
|
|
68
|
+
if (await isAccessible(candidate)) return candidate;
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
throw new MigrationConfigLoaderError(`No Astro config file found in ${root}`);
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
function projectRequire(projectRoot: string) {
|
|
75
|
+
return createRequire(resolve(projectRoot, "package.json"));
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
async function importModule(path: string): Promise<unknown> {
|
|
79
|
+
return import(pathToFileURL(path).href);
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
function isRecord(value: unknown): value is Record<PropertyKey, unknown> {
|
|
83
|
+
return typeof value === "object" && value !== null;
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
function moduleExport(module: unknown, name: string): unknown {
|
|
87
|
+
if (!isRecord(module)) return undefined;
|
|
88
|
+
const direct = module[name];
|
|
89
|
+
if (direct !== undefined) return direct;
|
|
90
|
+
const defaultExport = module.default;
|
|
91
|
+
return isRecord(defaultExport) ? defaultExport[name] : undefined;
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
function isCoreMigrationIdentity(value: unknown): value is CoreMigrationIdentity {
|
|
95
|
+
return (
|
|
96
|
+
isRecord(value) &&
|
|
97
|
+
typeof value.emdashVersion === "string" &&
|
|
98
|
+
Array.isArray(value.names) &&
|
|
99
|
+
value.names.every((name) => typeof name === "string") &&
|
|
100
|
+
typeof value.fingerprint === "string"
|
|
101
|
+
);
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
async function loadProjectConfig(projectRoot: string, configFile: string): Promise<unknown> {
|
|
105
|
+
let viteEntrypoint: string;
|
|
106
|
+
try {
|
|
107
|
+
const require = projectRequire(projectRoot);
|
|
108
|
+
const astroEntrypoint = require.resolve("astro");
|
|
109
|
+
viteEntrypoint = createRequire(astroEntrypoint).resolve("vite");
|
|
110
|
+
} catch (error) {
|
|
111
|
+
throw new MigrationConfigLoaderError(
|
|
112
|
+
"Could not resolve Vite through the project's Astro installation",
|
|
113
|
+
{ cause: error },
|
|
114
|
+
);
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
const vite = await importModule(viteEntrypoint);
|
|
118
|
+
const loadConfigFromFile = moduleExport(vite, "loadConfigFromFile");
|
|
119
|
+
if (typeof loadConfigFromFile !== "function") {
|
|
120
|
+
throw new MigrationConfigLoaderError(
|
|
121
|
+
"The Vite installation used by project-local Astro does not export loadConfigFromFile",
|
|
122
|
+
);
|
|
123
|
+
}
|
|
124
|
+
const loaded: unknown = await Reflect.apply(loadConfigFromFile, undefined, [
|
|
125
|
+
{ command: "build", mode: "production" },
|
|
126
|
+
configFile,
|
|
127
|
+
projectRoot,
|
|
128
|
+
"silent",
|
|
129
|
+
]);
|
|
130
|
+
if (!isRecord(loaded) || !Object.hasOwn(loaded, "config")) {
|
|
131
|
+
throw new MigrationConfigLoaderError(`Vite could not load Astro config: ${configFile}`);
|
|
132
|
+
}
|
|
133
|
+
return loaded.config;
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
async function loadProjectIdentity(projectRoot: string): Promise<CoreMigrationIdentity> {
|
|
137
|
+
let identityEntrypoint: string;
|
|
138
|
+
try {
|
|
139
|
+
identityEntrypoint = projectRequire(projectRoot).resolve("emdash/migrations");
|
|
140
|
+
} catch (error) {
|
|
141
|
+
throw new MigrationConfigLoaderError("Could not resolve emdash/migrations from the project", {
|
|
142
|
+
cause: error,
|
|
143
|
+
});
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
const module = await importModule(identityEntrypoint);
|
|
147
|
+
const getIdentity = moduleExport(module, "getCoreMigrationIdentity");
|
|
148
|
+
if (typeof getIdentity !== "function") {
|
|
149
|
+
throw new MigrationConfigLoaderError(
|
|
150
|
+
"The project-local emdash/migrations module does not export getCoreMigrationIdentity",
|
|
151
|
+
);
|
|
152
|
+
}
|
|
153
|
+
const identity: unknown = await Reflect.apply(getIdentity, undefined, []);
|
|
154
|
+
if (!isCoreMigrationIdentity(identity)) {
|
|
155
|
+
throw new MigrationConfigLoaderError(
|
|
156
|
+
"The project-local emdash/migrations module returned an invalid migration identity",
|
|
157
|
+
);
|
|
158
|
+
}
|
|
159
|
+
return identity;
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
const defaultDependencies: MigrationConfigLoaderDependencies = {
|
|
163
|
+
findConfigFile: findAstroConfigFile,
|
|
164
|
+
loadConfig: loadProjectConfig,
|
|
165
|
+
loadIdentity: loadProjectIdentity,
|
|
166
|
+
};
|
|
167
|
+
|
|
168
|
+
function asAstroConfig(value: unknown): EvaluatedAstroConfig {
|
|
169
|
+
if (typeof value !== "object" || value === null) {
|
|
170
|
+
throw new MigrationConfigLoaderError("Astro config must export an object");
|
|
171
|
+
}
|
|
172
|
+
return value;
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
export async function buildMigrationManifestFromConfig(
|
|
176
|
+
options: BuildMigrationManifestFromConfigOptions,
|
|
177
|
+
dependencies: MigrationConfigLoaderDependencies = defaultDependencies,
|
|
178
|
+
): Promise<MigrationManifestV1> {
|
|
179
|
+
const projectRoot = resolve(options.projectRoot);
|
|
180
|
+
const configFile = await dependencies.findConfigFile(projectRoot, options.configFile);
|
|
181
|
+
const config = asAstroConfig(await dependencies.loadConfig(projectRoot, configFile));
|
|
182
|
+
const integrations = Array.isArray(config.integrations) ? config.integrations : [];
|
|
183
|
+
const matchingIntegrations = integrations.filter(
|
|
184
|
+
(integration) => getMigrationIntegrationMetadata(integration) !== undefined,
|
|
185
|
+
);
|
|
186
|
+
if (matchingIntegrations.length !== 1) {
|
|
187
|
+
throw new MigrationConfigLoaderError(
|
|
188
|
+
`Expected exactly one EmDash integration with migration metadata (${String(MIGRATION_CONFIG_SYMBOL)}), found ${matchingIntegrations.length}`,
|
|
189
|
+
);
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
const metadata = getMigrationIntegrationMetadata(matchingIntegrations[0]);
|
|
193
|
+
if (!metadata?.database) {
|
|
194
|
+
throw new MigrationConfigLoaderError(
|
|
195
|
+
"The EmDash integration does not provide database migration metadata",
|
|
196
|
+
);
|
|
197
|
+
}
|
|
198
|
+
const identity = await dependencies.loadIdentity(projectRoot);
|
|
199
|
+
|
|
200
|
+
return buildMigrationManifest({
|
|
201
|
+
identity,
|
|
202
|
+
i18n: normalizeAstroI18n(config.i18n),
|
|
203
|
+
database: metadata.database,
|
|
204
|
+
});
|
|
205
|
+
}
|
|
@@ -0,0 +1,141 @@
|
|
|
1
|
+
import { type Dialect, Kysely } from "kysely";
|
|
2
|
+
|
|
3
|
+
import {
|
|
4
|
+
getExactMigrationStatus,
|
|
5
|
+
runMigrations,
|
|
6
|
+
type ExactMigrationStatus,
|
|
7
|
+
} from "../database/migrations/runner.js";
|
|
8
|
+
import type { Database } from "../database/types.js";
|
|
9
|
+
import { getI18nConfig, setI18nConfig } from "../i18n/config.js";
|
|
10
|
+
import { getCoreMigrationIdentity } from "./identity.js";
|
|
11
|
+
import type {
|
|
12
|
+
MigrationExecutor,
|
|
13
|
+
MigrationReport,
|
|
14
|
+
MigrationRequest,
|
|
15
|
+
MigrationTarget,
|
|
16
|
+
} from "./protocol.js";
|
|
17
|
+
|
|
18
|
+
export interface DirectMigrationExecutorOptions {
|
|
19
|
+
target: MigrationTarget;
|
|
20
|
+
createDialect: () => Dialect | Promise<Dialect>;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
function createReport(
|
|
24
|
+
target: MigrationTarget,
|
|
25
|
+
status: ExactMigrationStatus,
|
|
26
|
+
executed: readonly string[],
|
|
27
|
+
): MigrationReport {
|
|
28
|
+
return {
|
|
29
|
+
target,
|
|
30
|
+
knownApplied: [...status.knownApplied],
|
|
31
|
+
pending: [...status.pending],
|
|
32
|
+
unknownApplied: [...status.unknownApplied],
|
|
33
|
+
executed: [...executed],
|
|
34
|
+
};
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
async function verifyRequest(request: MigrationRequest): Promise<void> {
|
|
38
|
+
const identity = await getCoreMigrationIdentity();
|
|
39
|
+
if (
|
|
40
|
+
request.artifact.emdashVersion !== identity.emdashVersion ||
|
|
41
|
+
request.artifact.migrationSetFingerprint !== identity.fingerprint
|
|
42
|
+
) {
|
|
43
|
+
throw new Error(
|
|
44
|
+
"Migration artifact does not match the loaded EmDash version and migration registry.",
|
|
45
|
+
);
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
async function executeRequest(
|
|
50
|
+
db: Kysely<Database>,
|
|
51
|
+
target: MigrationTarget,
|
|
52
|
+
request: MigrationRequest,
|
|
53
|
+
): Promise<MigrationReport> {
|
|
54
|
+
const initialStatus = await getExactMigrationStatus(db);
|
|
55
|
+
if (request.action === "check") {
|
|
56
|
+
return createReport(target, initialStatus, []);
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
if (initialStatus.unknownApplied.length > 0) {
|
|
60
|
+
throw new Error(
|
|
61
|
+
`Cannot apply migrations with unknown applied migrations: ${initialStatus.unknownApplied.join(", ")}`,
|
|
62
|
+
);
|
|
63
|
+
}
|
|
64
|
+
if (initialStatus.pending.length === 0) {
|
|
65
|
+
return createReport(target, initialStatus, []);
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
const result = await runMigrations(db);
|
|
69
|
+
const finalStatus = await getExactMigrationStatus(db);
|
|
70
|
+
return createReport(target, finalStatus, result.applied);
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
export function createDirectMigrationExecutor(
|
|
74
|
+
options: DirectMigrationExecutorOptions,
|
|
75
|
+
): MigrationExecutor {
|
|
76
|
+
const target = Object.freeze({ ...options.target });
|
|
77
|
+
let used = false;
|
|
78
|
+
let disposed = false;
|
|
79
|
+
let activeDb: Kysely<Database> | undefined;
|
|
80
|
+
let closePromise: Promise<void> | undefined;
|
|
81
|
+
|
|
82
|
+
const closeActiveDb = (): Promise<void> => {
|
|
83
|
+
if (!activeDb) return Promise.resolve();
|
|
84
|
+
closePromise ??= activeDb.destroy();
|
|
85
|
+
return closePromise;
|
|
86
|
+
};
|
|
87
|
+
|
|
88
|
+
return {
|
|
89
|
+
target,
|
|
90
|
+
async execute(request) {
|
|
91
|
+
if (disposed) {
|
|
92
|
+
throw new Error("Migration executor has been disposed.");
|
|
93
|
+
}
|
|
94
|
+
if (used) {
|
|
95
|
+
throw new Error("Migration executors are single-use.");
|
|
96
|
+
}
|
|
97
|
+
used = true;
|
|
98
|
+
|
|
99
|
+
if (request.action !== "check" && request.action !== "apply") {
|
|
100
|
+
throw new Error("Unsupported migration action.");
|
|
101
|
+
}
|
|
102
|
+
await verifyRequest(request);
|
|
103
|
+
|
|
104
|
+
const dialect = await options.createDialect();
|
|
105
|
+
const db = new Kysely<Database>({ dialect });
|
|
106
|
+
activeDb = db;
|
|
107
|
+
if (disposed) {
|
|
108
|
+
await closeActiveDb();
|
|
109
|
+
throw new Error("Migration executor has been disposed.");
|
|
110
|
+
}
|
|
111
|
+
const previousI18n = getI18nConfig();
|
|
112
|
+
let executionFailed = false;
|
|
113
|
+
let executionError: unknown;
|
|
114
|
+
let report: MigrationReport | undefined;
|
|
115
|
+
setI18nConfig(request.i18n);
|
|
116
|
+
|
|
117
|
+
try {
|
|
118
|
+
report = await executeRequest(db, target, request);
|
|
119
|
+
} catch (error) {
|
|
120
|
+
executionFailed = true;
|
|
121
|
+
executionError = error;
|
|
122
|
+
} finally {
|
|
123
|
+
setI18nConfig(previousI18n);
|
|
124
|
+
try {
|
|
125
|
+
await closeActiveDb();
|
|
126
|
+
} catch {
|
|
127
|
+
console.error("[migrations] Database close failed.");
|
|
128
|
+
closePromise = Promise.resolve();
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
if (executionFailed) throw executionError;
|
|
133
|
+
if (!report) throw new Error("Migration execution did not produce a report.");
|
|
134
|
+
return report;
|
|
135
|
+
},
|
|
136
|
+
dispose() {
|
|
137
|
+
disposed = true;
|
|
138
|
+
return closeActiveDb();
|
|
139
|
+
},
|
|
140
|
+
};
|
|
141
|
+
}
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import { MIGRATION_NAMES } from "../database/migrations/runner.js";
|
|
2
|
+
import { VERSION } from "../version.js";
|
|
3
|
+
|
|
4
|
+
export interface CoreMigrationIdentity {
|
|
5
|
+
emdashVersion: string;
|
|
6
|
+
names: readonly string[];
|
|
7
|
+
fingerprint: string;
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
function encodeFingerprintInput(emdashVersion: string, names: readonly string[]): ArrayBuffer {
|
|
11
|
+
const encoded = new TextEncoder().encode(JSON.stringify({ emdashVersion, names }));
|
|
12
|
+
const buffer = new ArrayBuffer(encoded.byteLength);
|
|
13
|
+
new Uint8Array(buffer).set(encoded);
|
|
14
|
+
return buffer;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
function encodeHex(bytes: Uint8Array): string {
|
|
18
|
+
return Array.from(bytes, (byte) => byte.toString(16).padStart(2, "0")).join("");
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
export async function fingerprintMigrationSet(
|
|
22
|
+
emdashVersion: string,
|
|
23
|
+
names: readonly string[],
|
|
24
|
+
): Promise<string> {
|
|
25
|
+
const digest = await crypto.subtle.digest(
|
|
26
|
+
"SHA-256",
|
|
27
|
+
encodeFingerprintInput(emdashVersion, names),
|
|
28
|
+
);
|
|
29
|
+
return encodeHex(new Uint8Array(digest));
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
export async function createCoreMigrationIdentity(
|
|
33
|
+
emdashVersion: string,
|
|
34
|
+
names: readonly string[],
|
|
35
|
+
): Promise<CoreMigrationIdentity> {
|
|
36
|
+
const nameSnapshot = Object.freeze([...names]);
|
|
37
|
+
return Object.freeze({
|
|
38
|
+
emdashVersion,
|
|
39
|
+
names: nameSnapshot,
|
|
40
|
+
fingerprint: await fingerprintMigrationSet(emdashVersion, nameSnapshot),
|
|
41
|
+
});
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
export function getCoreMigrationIdentity(): Promise<CoreMigrationIdentity> {
|
|
45
|
+
return createCoreMigrationIdentity(VERSION, MIGRATION_NAMES);
|
|
46
|
+
}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
export { createDirectMigrationExecutor } from "./direct-executor.js";
|
|
2
|
+
export type { DirectMigrationExecutorOptions } from "./direct-executor.js";
|
|
3
|
+
export {
|
|
4
|
+
createCoreMigrationIdentity,
|
|
5
|
+
fingerprintMigrationSet,
|
|
6
|
+
getCoreMigrationIdentity,
|
|
7
|
+
} from "./identity.js";
|
|
8
|
+
export type { CoreMigrationIdentity } from "./identity.js";
|
|
9
|
+
export type {
|
|
10
|
+
MigrationAction,
|
|
11
|
+
MigrationExecutor,
|
|
12
|
+
MigrationExecutorFactory,
|
|
13
|
+
MigrationExecutorFactoryContext,
|
|
14
|
+
MigrationExecutorModule,
|
|
15
|
+
MigrationReport,
|
|
16
|
+
MigrationRequest,
|
|
17
|
+
MigrationTarget,
|
|
18
|
+
MigrationTargetOverrides,
|
|
19
|
+
} from "./protocol.js";
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
import type { DatabaseDescriptor } from "../db/adapters.js";
|
|
2
|
+
import { validateSecretFreeExecutorConfig } from "./manifest.js";
|
|
3
|
+
|
|
4
|
+
export const MIGRATION_CONFIG_SYMBOL = Symbol.for("emdash:migration-config");
|
|
5
|
+
|
|
6
|
+
export interface MigrationIntegrationMetadata {
|
|
7
|
+
database?: Pick<DatabaseDescriptor, "type" | "migrations">;
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
function isRecord(value: unknown): value is Record<PropertyKey, unknown> {
|
|
11
|
+
return typeof value === "object" && value !== null;
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
function isMigrationIntegrationMetadata(value: unknown): value is MigrationIntegrationMetadata {
|
|
15
|
+
if (!isRecord(value)) return false;
|
|
16
|
+
const database = value.database;
|
|
17
|
+
if (database === undefined) return true;
|
|
18
|
+
if (!isRecord(database) || (database.type !== "sqlite" && database.type !== "postgres")) {
|
|
19
|
+
return false;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
const migrations = database.migrations;
|
|
23
|
+
return (
|
|
24
|
+
migrations === undefined ||
|
|
25
|
+
(isRecord(migrations) &&
|
|
26
|
+
typeof migrations.entrypoint === "string" &&
|
|
27
|
+
Object.hasOwn(migrations, "manifestConfig"))
|
|
28
|
+
);
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
export function createMigrationIntegrationMetadata(
|
|
32
|
+
database?: DatabaseDescriptor,
|
|
33
|
+
): MigrationIntegrationMetadata {
|
|
34
|
+
if (!database) return {};
|
|
35
|
+
|
|
36
|
+
return {
|
|
37
|
+
database: {
|
|
38
|
+
type: database.type,
|
|
39
|
+
migrations: database.migrations
|
|
40
|
+
? {
|
|
41
|
+
entrypoint: database.migrations.entrypoint,
|
|
42
|
+
manifestConfig: validateSecretFreeExecutorConfig(
|
|
43
|
+
database.migrations.manifestConfig,
|
|
44
|
+
"database.migrations.manifestConfig",
|
|
45
|
+
),
|
|
46
|
+
}
|
|
47
|
+
: undefined,
|
|
48
|
+
},
|
|
49
|
+
};
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
export function getMigrationIntegrationMetadata(
|
|
53
|
+
integration: unknown,
|
|
54
|
+
): MigrationIntegrationMetadata | undefined {
|
|
55
|
+
if (
|
|
56
|
+
(typeof integration !== "object" || integration === null) &&
|
|
57
|
+
typeof integration !== "function"
|
|
58
|
+
) {
|
|
59
|
+
return undefined;
|
|
60
|
+
}
|
|
61
|
+
if (!Object.hasOwn(integration, MIGRATION_CONFIG_SYMBOL)) {
|
|
62
|
+
return undefined;
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
const metadata: unknown = Reflect.get(integration, MIGRATION_CONFIG_SYMBOL);
|
|
66
|
+
return isMigrationIntegrationMetadata(metadata) ? metadata : undefined;
|
|
67
|
+
}
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
import type { DatabaseDescriptor } from "../db/adapters.js";
|
|
2
|
+
import type { I18nConfig } from "../i18n/config.js";
|
|
3
|
+
import type { CoreMigrationIdentity } from "./identity.js";
|
|
4
|
+
import { fingerprintMigrationSet } from "./identity.js";
|
|
5
|
+
import type { MigrationManifestV1 } from "./manifest.js";
|
|
6
|
+
import { MigrationManifestValidationError, validateMigrationManifest } from "./manifest.js";
|
|
7
|
+
|
|
8
|
+
export type ManifestDatabaseDescriptor = Pick<DatabaseDescriptor, "type" | "migrations">;
|
|
9
|
+
|
|
10
|
+
export interface BuildMigrationManifestOptions {
|
|
11
|
+
identity: CoreMigrationIdentity;
|
|
12
|
+
i18n: I18nConfig | null;
|
|
13
|
+
database: ManifestDatabaseDescriptor;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
export class UnsupportedMigrationAdapterError extends Error {
|
|
17
|
+
constructor() {
|
|
18
|
+
super("The configured database adapter does not provide a deployment migration executor");
|
|
19
|
+
this.name = "UnsupportedMigrationAdapterError";
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
export async function buildMigrationManifest({
|
|
24
|
+
identity,
|
|
25
|
+
i18n,
|
|
26
|
+
database,
|
|
27
|
+
}: BuildMigrationManifestOptions): Promise<MigrationManifestV1> {
|
|
28
|
+
const identityFingerprint = await fingerprintMigrationSet(identity.emdashVersion, identity.names);
|
|
29
|
+
if (identityFingerprint !== identity.fingerprint) {
|
|
30
|
+
throw new MigrationManifestValidationError(
|
|
31
|
+
"loaded identity fingerprint does not match its version and ordered names",
|
|
32
|
+
);
|
|
33
|
+
}
|
|
34
|
+
if (!database.migrations) {
|
|
35
|
+
throw new UnsupportedMigrationAdapterError();
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
return validateMigrationManifest(
|
|
39
|
+
{
|
|
40
|
+
schemaVersion: 1,
|
|
41
|
+
emdashVersion: identity.emdashVersion,
|
|
42
|
+
migrationSet: {
|
|
43
|
+
names: [...identity.names],
|
|
44
|
+
fingerprint: identity.fingerprint,
|
|
45
|
+
},
|
|
46
|
+
i18n,
|
|
47
|
+
database: {
|
|
48
|
+
type: database.type,
|
|
49
|
+
executorEntrypoint: database.migrations.entrypoint,
|
|
50
|
+
executorConfig: database.migrations.manifestConfig,
|
|
51
|
+
},
|
|
52
|
+
},
|
|
53
|
+
identity,
|
|
54
|
+
);
|
|
55
|
+
}
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
import { randomUUID } from "node:crypto";
|
|
2
|
+
import {
|
|
3
|
+
mkdir as nodeMkdir,
|
|
4
|
+
rename as nodeRename,
|
|
5
|
+
unlink as nodeUnlink,
|
|
6
|
+
writeFile as nodeWriteFile,
|
|
7
|
+
} from "node:fs/promises";
|
|
8
|
+
import { dirname, join } from "node:path";
|
|
9
|
+
|
|
10
|
+
import type { MigrationManifestV1 } from "./manifest.js";
|
|
11
|
+
import { serializeMigrationManifest, validateMigrationManifest } from "./manifest.js";
|
|
12
|
+
|
|
13
|
+
export const MIGRATION_MANIFEST_PATH = ".emdash/migrations.json";
|
|
14
|
+
|
|
15
|
+
export interface ManifestWriterFileSystem {
|
|
16
|
+
mkdir(path: string, options: { recursive: true }): Promise<unknown>;
|
|
17
|
+
writeFile(
|
|
18
|
+
path: string,
|
|
19
|
+
data: string,
|
|
20
|
+
options: { encoding: "utf8"; flag: "wx" },
|
|
21
|
+
): Promise<unknown>;
|
|
22
|
+
rename(from: string, to: string): Promise<unknown>;
|
|
23
|
+
unlink(path: string): Promise<unknown>;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
const nodeFileSystem: ManifestWriterFileSystem = {
|
|
27
|
+
mkdir: (path, options) => nodeMkdir(path, options),
|
|
28
|
+
writeFile: (path, data, options) => nodeWriteFile(path, data, options),
|
|
29
|
+
rename: (from, to) => nodeRename(from, to),
|
|
30
|
+
unlink: (path) => nodeUnlink(path),
|
|
31
|
+
};
|
|
32
|
+
|
|
33
|
+
export async function writeMigrationManifest(
|
|
34
|
+
projectRoot: string,
|
|
35
|
+
manifest: MigrationManifestV1,
|
|
36
|
+
fileSystem: ManifestWriterFileSystem = nodeFileSystem,
|
|
37
|
+
): Promise<string> {
|
|
38
|
+
const validated = await validateMigrationManifest(manifest);
|
|
39
|
+
const outputPath = join(projectRoot, MIGRATION_MANIFEST_PATH);
|
|
40
|
+
const outputDirectory = dirname(outputPath);
|
|
41
|
+
await fileSystem.mkdir(outputDirectory, { recursive: true });
|
|
42
|
+
|
|
43
|
+
const temporaryPath = join(
|
|
44
|
+
outputDirectory,
|
|
45
|
+
`.migrations.json.${process.pid}.${randomUUID()}.tmp`,
|
|
46
|
+
);
|
|
47
|
+
let temporaryFileMayExist = false;
|
|
48
|
+
try {
|
|
49
|
+
temporaryFileMayExist = true;
|
|
50
|
+
await fileSystem.writeFile(temporaryPath, serializeMigrationManifest(validated), {
|
|
51
|
+
encoding: "utf8",
|
|
52
|
+
flag: "wx",
|
|
53
|
+
});
|
|
54
|
+
await fileSystem.rename(temporaryPath, outputPath);
|
|
55
|
+
temporaryFileMayExist = false;
|
|
56
|
+
return outputPath;
|
|
57
|
+
} catch (error) {
|
|
58
|
+
if (temporaryFileMayExist) {
|
|
59
|
+
await fileSystem.unlink(temporaryPath).catch(() => undefined);
|
|
60
|
+
}
|
|
61
|
+
throw error;
|
|
62
|
+
}
|
|
63
|
+
}
|