everything-dev 1.53.1 → 2.0.0-rc.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/README.md +2 -11
- package/dist/_virtual/_rolldown/runtime.cjs +17 -2
- package/dist/_virtual/_rolldown/runtime.mjs +36 -0
- package/dist/api/auth-middleware.cjs +161 -0
- package/dist/api/auth-middleware.cjs.map +1 -0
- package/dist/api/auth-middleware.d.cts +69 -0
- package/dist/api/auth-middleware.d.mts +69 -0
- package/dist/api/auth-middleware.mjs +160 -0
- package/dist/api/auth-middleware.mjs.map +1 -0
- package/dist/api-contract.cjs +250 -62
- package/dist/api-contract.cjs.map +1 -1
- package/dist/api-contract.mjs +246 -65
- package/dist/api-contract.mjs.map +1 -1
- package/dist/app.cjs +99 -26
- package/dist/app.cjs.map +1 -1
- package/dist/app.d.cts +3 -0
- package/dist/app.d.mts +3 -0
- package/dist/app.mjs +100 -27
- package/dist/app.mjs.map +1 -1
- package/dist/auth-login.cjs +163 -0
- package/dist/auth-login.cjs.map +1 -0
- package/dist/auth-login.mjs +162 -0
- package/dist/auth-login.mjs.map +1 -0
- package/dist/auth-session.cjs +64 -0
- package/dist/auth-session.cjs.map +1 -0
- package/dist/auth-session.mjs +58 -0
- package/dist/auth-session.mjs.map +1 -0
- package/dist/auth-types-gen.cjs +0 -1
- package/dist/auth-types-gen.cjs.map +1 -1
- package/dist/build.cjs +37 -173
- package/dist/build.cjs.map +1 -1
- package/dist/build.mjs +37 -171
- package/dist/build.mjs.map +1 -1
- package/dist/bundle-cache.cjs +74 -0
- package/dist/bundle-cache.cjs.map +1 -0
- package/dist/bundle-cache.d.cts +27 -0
- package/dist/bundle-cache.d.mts +27 -0
- package/dist/bundle-cache.mjs +68 -0
- package/dist/bundle-cache.mjs.map +1 -0
- package/dist/bundle-fs-resolve.cjs +209 -0
- package/dist/bundle-fs-resolve.cjs.map +1 -0
- package/dist/bundle-fs-resolve.d.cts +76 -0
- package/dist/bundle-fs-resolve.d.mts +76 -0
- package/dist/bundle-fs-resolve.mjs +202 -0
- package/dist/bundle-fs-resolve.mjs.map +1 -0
- package/dist/cdn-deploy.cjs +126 -0
- package/dist/cdn-deploy.cjs.map +1 -0
- package/dist/cdn-deploy.mjs +124 -0
- package/dist/cdn-deploy.mjs.map +1 -0
- package/dist/cli/db-doctor.cjs +19 -19
- package/dist/cli/db-doctor.cjs.map +1 -1
- package/dist/cli/db-doctor.mjs +18 -18
- package/dist/cli/db-doctor.mjs.map +1 -1
- package/dist/cli/db-repair.cjs +9 -32
- package/dist/cli/db-repair.cjs.map +1 -1
- package/dist/cli/db-repair.mjs +9 -32
- package/dist/cli/db-repair.mjs.map +1 -1
- package/dist/cli/framework-version.cjs +7 -3
- package/dist/cli/framework-version.cjs.map +1 -1
- package/dist/cli/framework-version.mjs +7 -3
- package/dist/cli/framework-version.mjs.map +1 -1
- package/dist/cli/infra.cjs +159 -251
- package/dist/cli/infra.cjs.map +1 -1
- package/dist/cli/infra.mjs +154 -242
- package/dist/cli/infra.mjs.map +1 -1
- package/dist/cli/init.cjs +624 -196
- package/dist/cli/init.cjs.map +1 -1
- package/dist/cli/init.d.cts +61 -8
- package/dist/cli/init.d.mts +61 -8
- package/dist/cli/init.mjs +613 -194
- package/dist/cli/init.mjs.map +1 -1
- package/dist/cli/parse.cjs +8 -7
- package/dist/cli/parse.cjs.map +1 -1
- package/dist/cli/parse.mjs +9 -7
- package/dist/cli/parse.mjs.map +1 -1
- package/dist/cli/prompts.cjs +14 -1
- package/dist/cli/prompts.cjs.map +1 -1
- package/dist/cli/prompts.mjs +14 -1
- package/dist/cli/prompts.mjs.map +1 -1
- package/dist/cli/prune.cjs +220 -0
- package/dist/cli/prune.cjs.map +1 -0
- package/dist/cli/prune.mjs +220 -0
- package/dist/cli/prune.mjs.map +1 -0
- package/dist/cli/snapshot.cjs +2 -1
- package/dist/cli/snapshot.cjs.map +1 -1
- package/dist/cli/snapshot.mjs +2 -1
- package/dist/cli/snapshot.mjs.map +1 -1
- package/dist/cli/status.cjs +5 -4
- package/dist/cli/status.cjs.map +1 -1
- package/dist/cli/status.mjs +6 -5
- package/dist/cli/status.mjs.map +1 -1
- package/dist/cli/sync.cjs +156 -58
- package/dist/cli/sync.cjs.map +1 -1
- package/dist/cli/sync.mjs +158 -63
- package/dist/cli/sync.mjs.map +1 -1
- package/dist/cli/timing.cjs +0 -1
- package/dist/cli/timing.cjs.map +1 -1
- package/dist/cli/upgrade.cjs +95 -69
- package/dist/cli/upgrade.cjs.map +1 -1
- package/dist/cli/upgrade.mjs +97 -72
- package/dist/cli/upgrade.mjs.map +1 -1
- package/dist/cli/utils/helpers.cjs.map +1 -1
- package/dist/cli.cjs +320 -72
- package/dist/cli.cjs.map +1 -1
- package/dist/cli.mjs +316 -68
- package/dist/cli.mjs.map +1 -1
- package/dist/code-artifacts.cjs +76 -8
- package/dist/code-artifacts.cjs.map +1 -1
- package/dist/code-artifacts.mjs +76 -10
- package/dist/code-artifacts.mjs.map +1 -1
- package/dist/commands/build.cjs +65 -0
- package/dist/commands/build.cjs.map +1 -0
- package/dist/commands/build.mjs +65 -0
- package/dist/commands/build.mjs.map +1 -0
- package/dist/commands/config.cjs +77 -0
- package/dist/commands/config.cjs.map +1 -0
- package/dist/commands/config.d.cts +8 -0
- package/dist/commands/config.d.mts +8 -0
- package/dist/commands/config.mjs +74 -0
- package/dist/commands/config.mjs.map +1 -0
- package/dist/commands/db.cjs +107 -0
- package/dist/commands/db.cjs.map +1 -0
- package/dist/commands/db.mjs +107 -0
- package/dist/commands/db.mjs.map +1 -0
- package/dist/commands/deploy.cjs +336 -0
- package/dist/commands/deploy.cjs.map +1 -0
- package/dist/commands/deploy.mjs +334 -0
- package/dist/commands/deploy.mjs.map +1 -0
- package/dist/commands/dev.cjs +75 -0
- package/dist/commands/dev.cjs.map +1 -0
- package/dist/commands/dev.mjs +73 -0
- package/dist/commands/dev.mjs.map +1 -0
- package/dist/commands/init.cjs +234 -0
- package/dist/commands/init.cjs.map +1 -0
- package/dist/commands/init.mjs +231 -0
- package/dist/commands/init.mjs.map +1 -0
- package/dist/commands/keys.cjs +255 -0
- package/dist/commands/keys.cjs.map +1 -0
- package/dist/commands/keys.mjs +253 -0
- package/dist/commands/keys.mjs.map +1 -0
- package/dist/commands/ops.cjs +199 -0
- package/dist/commands/ops.cjs.map +1 -0
- package/dist/commands/ops.mjs +197 -0
- package/dist/commands/ops.mjs.map +1 -0
- package/dist/commands/plugins.cjs +211 -0
- package/dist/commands/plugins.cjs.map +1 -0
- package/dist/commands/plugins.mjs +211 -0
- package/dist/commands/plugins.mjs.map +1 -0
- package/dist/commands/shared.cjs +8 -0
- package/dist/commands/shared.cjs.map +1 -0
- package/dist/commands/shared.d.cts +6 -0
- package/dist/commands/shared.d.mts +6 -0
- package/dist/commands/shared.mjs +8 -0
- package/dist/commands/shared.mjs.map +1 -0
- package/dist/commands/upgrade.cjs +325 -0
- package/dist/commands/upgrade.cjs.map +1 -0
- package/dist/commands/upgrade.mjs +323 -0
- package/dist/commands/upgrade.mjs.map +1 -0
- package/dist/components/dev-render.cjs +340 -0
- package/dist/components/dev-render.cjs.map +1 -0
- package/dist/components/dev-render.mjs +332 -0
- package/dist/components/dev-render.mjs.map +1 -0
- package/dist/config.cjs +460 -221
- package/dist/config.cjs.map +1 -1
- package/dist/config.d.cts +491 -48
- package/dist/config.d.mts +491 -48
- package/dist/config.mjs +439 -212
- package/dist/config.mjs.map +1 -1
- package/dist/contract.cjs +327 -50
- package/dist/contract.cjs.map +1 -1
- package/dist/contract.d.cts +1951 -1062
- package/dist/contract.d.mts +1951 -1062
- package/dist/contract.meta.cjs +107 -12
- package/dist/contract.meta.cjs.map +1 -1
- package/dist/contract.meta.d.cts +166 -8
- package/dist/contract.meta.d.mts +166 -8
- package/dist/contract.meta.mjs +107 -11
- package/dist/contract.meta.mjs.map +1 -1
- package/dist/contract.mjs +580 -327
- package/dist/contract.mjs.map +1 -1
- package/dist/dag.cjs +5 -3
- package/dist/dag.cjs.map +1 -1
- package/dist/dag.mjs +6 -3
- package/dist/dag.mjs.map +1 -1
- package/dist/db/binding.cjs +80 -0
- package/dist/db/binding.cjs.map +1 -0
- package/dist/db/binding.d.cts +39 -0
- package/dist/db/binding.d.mts +39 -0
- package/dist/db/binding.mjs +78 -0
- package/dist/db/binding.mjs.map +1 -0
- package/dist/db/bindings.cjs +78 -0
- package/dist/db/bindings.cjs.map +1 -0
- package/dist/db/bindings.d.cts +34 -0
- package/dist/db/bindings.d.mts +34 -0
- package/dist/db/bindings.mjs +76 -0
- package/dist/db/bindings.mjs.map +1 -0
- package/dist/db/core.cjs +204 -0
- package/dist/db/core.cjs.map +1 -0
- package/dist/db/core.d.cts +69 -0
- package/dist/db/core.d.mts +69 -0
- package/dist/db/core.mjs +192 -0
- package/dist/db/core.mjs.map +1 -0
- package/dist/db/driver.cjs +167 -0
- package/dist/db/driver.cjs.map +1 -0
- package/dist/db/driver.d.cts +50 -0
- package/dist/db/driver.d.mts +50 -0
- package/dist/db/driver.mjs +165 -0
- package/dist/db/driver.mjs.map +1 -0
- package/dist/db/drizzle-kit.cjs +177 -0
- package/dist/db/drizzle-kit.cjs.map +1 -0
- package/dist/db/drizzle-kit.d.cts +25 -0
- package/dist/db/drizzle-kit.d.mts +25 -0
- package/dist/db/drizzle-kit.mjs +175 -0
- package/dist/db/drizzle-kit.mjs.map +1 -0
- package/dist/db/errors.cjs +27 -0
- package/dist/db/errors.cjs.map +1 -0
- package/dist/db/errors.d.cts +16 -0
- package/dist/db/errors.d.mts +16 -0
- package/dist/db/errors.mjs +26 -0
- package/dist/db/errors.mjs.map +1 -0
- package/dist/db/identity.cjs +55 -0
- package/dist/db/identity.cjs.map +1 -0
- package/dist/db/identity.d.cts +40 -0
- package/dist/db/identity.d.mts +40 -0
- package/dist/db/identity.mjs +53 -0
- package/dist/db/identity.mjs.map +1 -0
- package/dist/db/index.cjs +43 -0
- package/dist/db/index.d.cts +9 -0
- package/dist/db/index.d.mts +9 -0
- package/dist/db/index.mjs +10 -0
- package/dist/db/run-migrations.cjs +343 -0
- package/dist/db/run-migrations.cjs.map +1 -0
- package/dist/db/run-migrations.d.cts +87 -0
- package/dist/db/run-migrations.d.mts +87 -0
- package/dist/db/run-migrations.mjs +341 -0
- package/dist/db/run-migrations.mjs.map +1 -0
- package/dist/delegate-signer.cjs +85 -0
- package/dist/delegate-signer.cjs.map +1 -0
- package/dist/delegate-signer.mjs +84 -0
- package/dist/delegate-signer.mjs.map +1 -0
- package/dist/deploy-diff.cjs +119 -0
- package/dist/deploy-diff.cjs.map +1 -0
- package/dist/deploy-diff.mjs +109 -0
- package/dist/deploy-diff.mjs.map +1 -0
- package/dist/descriptor/constructors.cjs +49 -0
- package/dist/descriptor/constructors.cjs.map +1 -0
- package/dist/descriptor/constructors.d.cts +27 -0
- package/dist/descriptor/constructors.d.mts +27 -0
- package/dist/descriptor/constructors.mjs +45 -0
- package/dist/descriptor/constructors.mjs.map +1 -0
- package/dist/descriptor/index.cjs +24 -0
- package/dist/descriptor/index.d.cts +5 -0
- package/dist/descriptor/index.d.mts +5 -0
- package/dist/descriptor/index.mjs +6 -0
- package/dist/descriptor/resolve.cjs +258 -0
- package/dist/descriptor/resolve.cjs.map +1 -0
- package/dist/descriptor/resolve.d.cts +50 -0
- package/dist/descriptor/resolve.d.mts +50 -0
- package/dist/descriptor/resolve.mjs +252 -0
- package/dist/descriptor/resolve.mjs.map +1 -0
- package/dist/descriptor/schema.cjs +109 -0
- package/dist/descriptor/schema.cjs.map +1 -0
- package/dist/descriptor/schema.d.cts +217 -0
- package/dist/descriptor/schema.d.mts +217 -0
- package/dist/descriptor/schema.mjs +102 -0
- package/dist/descriptor/schema.mjs.map +1 -0
- package/dist/descriptor/serialize.cjs +45 -0
- package/dist/descriptor/serialize.cjs.map +1 -0
- package/dist/descriptor/serialize.d.cts +7 -0
- package/dist/descriptor/serialize.d.mts +7 -0
- package/dist/descriptor/serialize.mjs +45 -0
- package/dist/descriptor/serialize.mjs.map +1 -0
- package/dist/dev-log-pipeline.cjs +273 -0
- package/dist/dev-log-pipeline.cjs.map +1 -0
- package/dist/dev-log-pipeline.mjs +267 -0
- package/dist/dev-log-pipeline.mjs.map +1 -0
- package/dist/dev-logs.cjs +39 -8
- package/dist/dev-logs.cjs.map +1 -1
- package/dist/dev-logs.mjs +37 -9
- package/dist/dev-logs.mjs.map +1 -1
- package/dist/dev-program.cjs +405 -0
- package/dist/dev-program.cjs.map +1 -0
- package/dist/dev-program.d.cts +10 -0
- package/dist/dev-program.d.mts +10 -0
- package/dist/dev-program.mjs +395 -0
- package/dist/dev-program.mjs.map +1 -0
- package/dist/dev-session-data.d.cts +27 -0
- package/dist/dev-session-data.d.mts +27 -0
- package/dist/dev-session.cjs +178 -105
- package/dist/dev-session.cjs.map +1 -1
- package/dist/dev-session.mjs +180 -105
- package/dist/dev-session.mjs.map +1 -1
- package/dist/env/process-env.cjs +16 -0
- package/dist/env/process-env.cjs.map +1 -0
- package/dist/env/process-env.mjs +13 -0
- package/dist/env/process-env.mjs.map +1 -0
- package/dist/env/project-env.cjs +144 -0
- package/dist/env/project-env.cjs.map +1 -0
- package/dist/env/project-env.d.cts +1 -0
- package/dist/env/project-env.d.mts +1 -0
- package/dist/env/project-env.mjs +132 -0
- package/dist/env/project-env.mjs.map +1 -0
- package/dist/fastkv.cjs +59 -12
- package/dist/fastkv.cjs.map +1 -1
- package/dist/fastkv.d.cts +42 -6
- package/dist/fastkv.d.mts +42 -6
- package/dist/fastkv.mjs +58 -13
- package/dist/fastkv.mjs.map +1 -1
- package/dist/fingerprint.cjs +57 -0
- package/dist/fingerprint.cjs.map +1 -0
- package/dist/fingerprint.d.cts +14 -0
- package/dist/fingerprint.d.mts +14 -0
- package/dist/fingerprint.mjs +55 -0
- package/dist/fingerprint.mjs.map +1 -0
- package/dist/http-client.cjs +17 -17
- package/dist/http-client.cjs.map +1 -1
- package/dist/http-client.mjs +17 -17
- package/dist/http-client.mjs.map +1 -1
- package/dist/image-deploy.cjs +186 -0
- package/dist/image-deploy.cjs.map +1 -0
- package/dist/image-deploy.mjs +182 -0
- package/dist/image-deploy.mjs.map +1 -0
- package/dist/index.cjs +66 -18
- package/dist/index.d.cts +8 -7
- package/dist/index.d.mts +8 -7
- package/dist/index.mjs +6 -5
- package/dist/infra/docker.cjs +77 -0
- package/dist/infra/docker.cjs.map +1 -0
- package/dist/infra/docker.d.cts +10 -0
- package/dist/infra/docker.d.mts +10 -0
- package/dist/infra/docker.mjs +69 -0
- package/dist/infra/docker.mjs.map +1 -0
- package/dist/infra/materializer.cjs +74 -0
- package/dist/infra/materializer.cjs.map +1 -0
- package/dist/infra/materializer.mjs +70 -0
- package/dist/infra/materializer.mjs.map +1 -0
- package/dist/infra/planner.cjs +135 -103
- package/dist/infra/planner.cjs.map +1 -1
- package/dist/infra/planner.mjs +137 -104
- package/dist/infra/planner.mjs.map +1 -1
- package/dist/infra/port-ownership.cjs +57 -0
- package/dist/infra/port-ownership.cjs.map +1 -0
- package/dist/infra/port-ownership.mjs +57 -0
- package/dist/infra/port-ownership.mjs.map +1 -0
- package/dist/infra/preflight.cjs +45 -33
- package/dist/infra/preflight.cjs.map +1 -1
- package/dist/infra/preflight.d.cts +1 -0
- package/dist/infra/preflight.d.mts +1 -0
- package/dist/infra/preflight.mjs +46 -34
- package/dist/infra/preflight.mjs.map +1 -1
- package/dist/infra/types.cjs.map +1 -1
- package/dist/infra/types.d.cts +2 -0
- package/dist/infra/types.d.mts +2 -0
- package/dist/infra/types.mjs.map +1 -1
- package/dist/integrity.cjs +50 -61
- package/dist/integrity.cjs.map +1 -1
- package/dist/integrity.d.cts +16 -10
- package/dist/integrity.d.mts +16 -10
- package/dist/integrity.mjs +50 -59
- package/dist/integrity.mjs.map +1 -1
- package/dist/internal/manifest-normalizer.cjs +8 -2
- package/dist/internal/manifest-normalizer.cjs.map +1 -1
- package/dist/internal/manifest-normalizer.mjs +9 -3
- package/dist/internal/manifest-normalizer.mjs.map +1 -1
- package/dist/merge.cjs +19 -1
- package/dist/merge.cjs.map +1 -1
- package/dist/merge.d.cts +1 -1
- package/dist/merge.d.mts +1 -1
- package/dist/merge.mjs +19 -2
- package/dist/merge.mjs.map +1 -1
- package/dist/mf.cjs +190 -3
- package/dist/mf.cjs.map +1 -1
- package/dist/mf.d.cts +24 -2
- package/dist/mf.d.mts +24 -2
- package/dist/mf.mjs +189 -4
- package/dist/mf.mjs.map +1 -1
- package/dist/near-cli.cjs +59 -91
- package/dist/near-cli.cjs.map +1 -1
- package/dist/near-cli.mjs +58 -90
- package/dist/near-cli.mjs.map +1 -1
- package/dist/near-signer.cjs +73 -0
- package/dist/near-signer.cjs.map +1 -0
- package/dist/near-signer.mjs +70 -0
- package/dist/near-signer.mjs.map +1 -0
- package/dist/network.cjs +0 -1
- package/dist/network.cjs.map +1 -1
- package/dist/orchestrator.cjs +256 -87
- package/dist/orchestrator.cjs.map +1 -1
- package/dist/orchestrator.mjs +248 -87
- package/dist/orchestrator.mjs.map +1 -1
- package/dist/platform-deploy.cjs +81 -0
- package/dist/platform-deploy.cjs.map +1 -0
- package/dist/platform-deploy.mjs +80 -0
- package/dist/platform-deploy.mjs.map +1 -0
- package/dist/plugin.cjs +54 -1389
- package/dist/plugin.cjs.map +1 -1
- package/dist/plugin.d.cts +6 -896
- package/dist/plugin.d.mts +6 -896
- package/dist/plugin.mjs +53 -1387
- package/dist/plugin.mjs.map +1 -1
- package/dist/process-kill.cjs +44 -0
- package/dist/process-kill.cjs.map +1 -0
- package/dist/process-kill.mjs +43 -0
- package/dist/process-kill.mjs.map +1 -0
- package/dist/process-registry.cjs +64 -9
- package/dist/process-registry.cjs.map +1 -1
- package/dist/process-registry.mjs +61 -10
- package/dist/process-registry.mjs.map +1 -1
- package/dist/progress.cjs +45 -0
- package/dist/progress.cjs.map +1 -0
- package/dist/progress.d.cts +13 -0
- package/dist/progress.d.mts +13 -0
- package/dist/progress.mjs +42 -0
- package/dist/progress.mjs.map +1 -0
- package/dist/publish.cjs +513 -79
- package/dist/publish.cjs.map +1 -1
- package/dist/publish.mjs +515 -82
- package/dist/publish.mjs.map +1 -1
- package/dist/registry-use.cjs +41 -0
- package/dist/registry-use.cjs.map +1 -0
- package/dist/registry-use.mjs +40 -0
- package/dist/registry-use.mjs.map +1 -0
- package/dist/resolution/session.cjs +335 -0
- package/dist/resolution/session.cjs.map +1 -0
- package/dist/resolution/session.d.cts +105 -0
- package/dist/resolution/session.d.mts +105 -0
- package/dist/resolution/session.mjs +331 -0
- package/dist/resolution/session.mjs.map +1 -0
- package/dist/rollback.cjs +131 -0
- package/dist/rollback.cjs.map +1 -0
- package/dist/rollback.mjs +128 -0
- package/dist/rollback.mjs.map +1 -0
- package/dist/sdk.cjs +7 -7
- package/dist/sdk.d.cts +3 -3
- package/dist/sdk.d.mts +3 -3
- package/dist/sdk.mjs +2 -2
- package/dist/service-descriptor.cjs +67 -34
- package/dist/service-descriptor.cjs.map +1 -1
- package/dist/service-descriptor.d.cts +4 -1
- package/dist/service-descriptor.d.mts +3 -0
- package/dist/service-descriptor.mjs +63 -35
- package/dist/service-descriptor.mjs.map +1 -1
- package/dist/shared-deps.cjs +17 -16
- package/dist/shared-deps.cjs.map +1 -1
- package/dist/shared-deps.mjs +17 -16
- package/dist/shared-deps.mjs.map +1 -1
- package/dist/start-config-source.cjs +24 -0
- package/dist/start-config-source.cjs.map +1 -0
- package/dist/start-config-source.d.cts +29 -0
- package/dist/start-config-source.d.mts +29 -0
- package/dist/start-config-source.mjs +22 -0
- package/dist/start-config-source.mjs.map +1 -0
- package/dist/storage-upload.cjs +145 -0
- package/dist/storage-upload.cjs.map +1 -0
- package/dist/storage-upload.mjs +143 -0
- package/dist/storage-upload.mjs.map +1 -0
- package/dist/types.cjs +126 -20
- package/dist/types.cjs.map +1 -1
- package/dist/types.d.cts +867 -585
- package/dist/types.d.mts +867 -585
- package/dist/types.mjs +307 -208
- package/dist/types.mjs.map +1 -1
- package/dist/ui/api.cjs +105 -0
- package/dist/ui/api.cjs.map +1 -0
- package/dist/ui/api.d.cts +31 -0
- package/dist/ui/api.d.mts +31 -0
- package/dist/ui/api.mjs +99 -0
- package/dist/ui/api.mjs.map +1 -0
- package/dist/ui/auth-guards.cjs +50 -0
- package/dist/ui/auth-guards.cjs.map +1 -0
- package/dist/ui/auth-guards.d.cts +39 -0
- package/dist/ui/auth-guards.d.mts +39 -0
- package/dist/ui/auth-guards.mjs +48 -0
- package/dist/ui/auth-guards.mjs.map +1 -0
- package/dist/ui/auth.cjs +197 -0
- package/dist/ui/auth.cjs.map +1 -0
- package/dist/ui/auth.d.cts +56 -0
- package/dist/ui/auth.d.mts +56 -0
- package/dist/ui/auth.mjs +179 -0
- package/dist/ui/auth.mjs.map +1 -0
- package/dist/ui/entry.cjs +16 -0
- package/dist/ui/entry.cjs.map +1 -0
- package/dist/ui/entry.d.cts +12 -0
- package/dist/ui/entry.d.mts +12 -0
- package/dist/ui/entry.mjs +15 -0
- package/dist/ui/entry.mjs.map +1 -0
- package/dist/ui/head.cjs +14 -7
- package/dist/ui/head.cjs.map +1 -1
- package/dist/ui/head.mjs +15 -7
- package/dist/ui/head.mjs.map +1 -1
- package/dist/ui/hydrate.cjs +265 -0
- package/dist/ui/hydrate.cjs.map +1 -0
- package/dist/ui/hydrate.d.cts +48 -0
- package/dist/ui/hydrate.d.mts +48 -0
- package/dist/ui/hydrate.mjs +263 -0
- package/dist/ui/hydrate.mjs.map +1 -0
- package/dist/ui/i18n.cjs +153 -0
- package/dist/ui/i18n.cjs.map +1 -0
- package/dist/ui/i18n.d.cts +29 -0
- package/dist/ui/i18n.d.mts +29 -0
- package/dist/ui/i18n.mjs +140 -0
- package/dist/ui/i18n.mjs.map +1 -0
- package/dist/ui/index.cjs +19 -1
- package/dist/ui/index.d.cts +6 -3
- package/dist/ui/index.d.mts +6 -3
- package/dist/ui/index.mjs +5 -2
- package/dist/ui/locale.cjs +53 -0
- package/dist/ui/locale.cjs.map +1 -0
- package/dist/ui/locale.d.cts +18 -0
- package/dist/ui/locale.d.mts +18 -0
- package/dist/ui/locale.mjs +49 -0
- package/dist/ui/locale.mjs.map +1 -0
- package/dist/ui/manifest/index.cjs +25 -0
- package/dist/ui/manifest/index.cjs.map +1 -0
- package/dist/ui/manifest/index.d.cts +9 -0
- package/dist/ui/manifest/index.d.mts +9 -0
- package/dist/ui/manifest/index.mjs +13 -0
- package/dist/ui/manifest/index.mjs.map +1 -0
- package/dist/ui/manifest-generator.cjs +8 -0
- package/dist/ui/manifest-generator.d.cts +1 -0
- package/dist/ui/manifest-generator.d.mts +1 -0
- package/dist/ui/manifest-generator.mjs +3 -0
- package/dist/ui/message-catalogs.cjs +8 -0
- package/dist/ui/message-catalogs.cjs.map +1 -0
- package/dist/ui/message-catalogs.d.cts +5 -0
- package/dist/ui/message-catalogs.d.mts +5 -0
- package/dist/ui/message-catalogs.mjs +8 -0
- package/dist/ui/message-catalogs.mjs.map +1 -0
- package/dist/ui/metadata.cjs +0 -1
- package/dist/ui/metadata.cjs.map +1 -1
- package/dist/ui/metadata.d.cts +1 -1
- package/dist/ui/metadata.d.mts +1 -1
- package/dist/ui/plugin-path.cjs +37 -0
- package/dist/ui/plugin-path.cjs.map +1 -0
- package/dist/ui/plugin-path.d.cts +25 -0
- package/dist/ui/plugin-path.d.mts +25 -0
- package/dist/ui/plugin-path.mjs +35 -0
- package/dist/ui/plugin-path.mjs.map +1 -0
- package/dist/ui/router-client.cjs +61 -0
- package/dist/ui/router-client.cjs.map +1 -0
- package/dist/ui/router-client.d.cts +20 -0
- package/dist/ui/router-client.d.mts +20 -0
- package/dist/ui/router-client.mjs +60 -0
- package/dist/ui/router-client.mjs.map +1 -0
- package/dist/ui/router-defaults.cjs +48 -0
- package/dist/ui/router-defaults.cjs.map +1 -0
- package/dist/ui/router-defaults.d.cts +8 -0
- package/dist/ui/router-defaults.d.mts +8 -0
- package/dist/ui/router-defaults.mjs +45 -0
- package/dist/ui/router-defaults.mjs.map +1 -0
- package/dist/ui/router-error.cjs +70 -0
- package/dist/ui/router-error.cjs.map +1 -0
- package/dist/ui/router-error.d.cts +19 -0
- package/dist/ui/router-error.d.mts +19 -0
- package/dist/ui/router-error.mjs +69 -0
- package/dist/ui/router-error.mjs.map +1 -0
- package/dist/ui/router-server.cjs +153 -0
- package/dist/ui/router-server.cjs.map +1 -0
- package/dist/ui/router-server.d.cts +38 -0
- package/dist/ui/router-server.d.mts +38 -0
- package/dist/ui/router-server.mjs +152 -0
- package/dist/ui/router-server.mjs.map +1 -0
- package/dist/ui/router.cjs +4 -16
- package/dist/ui/router.cjs.map +1 -1
- package/dist/ui/router.mjs +4 -15
- package/dist/ui/router.mjs.map +1 -1
- package/dist/ui/runtime.cjs +5 -1
- package/dist/ui/runtime.cjs.map +1 -1
- package/dist/ui/runtime.d.cts +2 -1
- package/dist/ui/runtime.d.mts +2 -1
- package/dist/ui/runtime.mjs +5 -1
- package/dist/ui/runtime.mjs.map +1 -1
- package/dist/ui/slot.cjs +34 -0
- package/dist/ui/slot.cjs.map +1 -0
- package/dist/ui/slot.d.cts +43 -0
- package/dist/ui/slot.d.mts +43 -0
- package/dist/ui/slot.mjs +34 -0
- package/dist/ui/slot.mjs.map +1 -0
- package/dist/ui/tenant.cjs +300 -0
- package/dist/ui/tenant.cjs.map +1 -0
- package/dist/ui/tenant.d.cts +122 -0
- package/dist/ui/tenant.d.mts +122 -0
- package/dist/ui/tenant.mjs +279 -0
- package/dist/ui/tenant.mjs.map +1 -0
- package/dist/ui/types.d.cts +32 -2
- package/dist/ui/types.d.mts +32 -2
- package/dist/ui/version-check.cjs +47 -0
- package/dist/ui/version-check.cjs.map +1 -0
- package/dist/ui/version-check.d.cts +23 -0
- package/dist/ui/version-check.d.mts +23 -0
- package/dist/ui/version-check.mjs +46 -0
- package/dist/ui/version-check.mjs.map +1 -0
- package/dist/utils/banner.cjs +2 -2
- package/dist/utils/banner.cjs.map +1 -1
- package/dist/utils/banner.mjs +2 -2
- package/dist/utils/banner.mjs.map +1 -1
- package/dist/utils/linkify.cjs +1 -1
- package/dist/utils/linkify.cjs.map +1 -1
- package/dist/utils/linkify.mjs +1 -0
- package/dist/utils/linkify.mjs.map +1 -1
- package/dist/utils/run.cjs +6 -6
- package/dist/utils/run.cjs.map +1 -1
- package/dist/utils/run.mjs +6 -6
- package/dist/utils/run.mjs.map +1 -1
- package/dist/utils/save-config.cjs +12 -0
- package/dist/utils/save-config.cjs.map +1 -1
- package/dist/utils/save-config.mjs +12 -0
- package/dist/utils/save-config.mjs.map +1 -1
- package/dist/utils/snapshot-hash.cjs +10 -0
- package/dist/utils/snapshot-hash.cjs.map +1 -0
- package/dist/utils/snapshot-hash.mjs +10 -0
- package/dist/utils/snapshot-hash.mjs.map +1 -0
- package/dist/utils/string.cjs +0 -1
- package/dist/utils/string.cjs.map +1 -1
- package/dist/utils/theme.cjs +30 -12
- package/dist/utils/theme.cjs.map +1 -1
- package/dist/utils/theme.mjs +30 -11
- package/dist/utils/theme.mjs.map +1 -1
- package/dist/version-manifest-deploy.cjs +50 -0
- package/dist/version-manifest-deploy.cjs.map +1 -0
- package/dist/version-manifest-deploy.mjs +49 -0
- package/dist/version-manifest-deploy.mjs.map +1 -0
- package/dist/version-manifest-resolve.cjs +42 -0
- package/dist/version-manifest-resolve.cjs.map +1 -0
- package/dist/version-manifest-resolve.d.cts +38 -0
- package/dist/version-manifest-resolve.d.mts +38 -0
- package/dist/version-manifest-resolve.mjs +40 -0
- package/dist/version-manifest-resolve.mjs.map +1 -0
- package/dist/version-status.cjs +18 -0
- package/dist/version-status.cjs.map +1 -0
- package/dist/version-status.d.cts +22 -0
- package/dist/version-status.d.mts +22 -0
- package/dist/version-status.mjs +17 -0
- package/dist/version-status.mjs.map +1 -0
- package/dist/workspace-catalog.cjs +53 -0
- package/dist/workspace-catalog.cjs.map +1 -0
- package/dist/workspace-catalog.mjs +51 -0
- package/dist/workspace-catalog.mjs.map +1 -0
- package/dist/workspace.cjs +237 -0
- package/dist/workspace.cjs.map +1 -0
- package/dist/workspace.mjs +233 -0
- package/dist/workspace.mjs.map +1 -0
- package/package.json +179 -27
- package/skills/add-a-route/SKILL.md +132 -0
- package/skills/api-and-auth/SKILL.md +87 -21
- package/skills/api-and-auth/references/middleware.md +1 -1
- package/skills/cli-reference/SKILL.md +48 -21
- package/skills/code-style/SKILL.md +8 -0
- package/skills/dev-workflow/SKILL.md +50 -26
- package/skills/extends-config/SKILL.md +31 -19
- package/skills/init-upgrade/SKILL.md +29 -16
- package/skills/plugin-development/SKILL.md +46 -112
- package/skills/plugin-development/references/database.md +82 -0
- package/skills/plugin-development/references/request-context.md +67 -0
- package/skills/publish-sync/SKILL.md +99 -22
- package/skills/registry/SKILL.md +82 -0
- package/skills/super-app/SKILL.md +25 -15
- package/skills/talk-to-the-app/SKILL.md +138 -0
- package/skills/ui-integration/SKILL.md +93 -11
- package/dist/cli/db-studio.cjs +0 -131
- package/dist/cli/db-studio.cjs.map +0 -1
- package/dist/cli/db-studio.mjs +0 -127
- package/dist/cli/db-studio.mjs.map +0 -1
- package/dist/cli/init.d.cts.map +0 -1
- package/dist/cli/init.d.mts.map +0 -1
- package/dist/components/dev-view.cjs +0 -309
- package/dist/components/dev-view.cjs.map +0 -1
- package/dist/components/dev-view.mjs +0 -309
- package/dist/components/dev-view.mjs.map +0 -1
- package/dist/components/streaming-view.cjs +0 -134
- package/dist/components/streaming-view.cjs.map +0 -1
- package/dist/components/streaming-view.mjs +0 -132
- package/dist/components/streaming-view.mjs.map +0 -1
- package/dist/config.d.cts.map +0 -1
- package/dist/config.d.mts.map +0 -1
- package/dist/contract.d.cts.map +0 -1
- package/dist/contract.d.mts.map +0 -1
- package/dist/contract.meta.d.cts.map +0 -1
- package/dist/contract.meta.d.mts.map +0 -1
- package/dist/dag.d.cts.map +0 -1
- package/dist/dag.d.mts.map +0 -1
- package/dist/db.cjs +0 -81
- package/dist/db.cjs.map +0 -1
- package/dist/db.d.cts +0 -30
- package/dist/db.d.cts.map +0 -1
- package/dist/db.d.mts +0 -30
- package/dist/db.d.mts.map +0 -1
- package/dist/db.mjs +0 -75
- package/dist/db.mjs.map +0 -1
- package/dist/fastkv.d.cts.map +0 -1
- package/dist/fastkv.d.mts.map +0 -1
- package/dist/integrity.d.cts.map +0 -1
- package/dist/integrity.d.mts.map +0 -1
- package/dist/merge.d.cts.map +0 -1
- package/dist/merge.d.mts.map +0 -1
- package/dist/mf.d.cts.map +0 -1
- package/dist/mf.d.mts.map +0 -1
- package/dist/plugin.d.cts.map +0 -1
- package/dist/plugin.d.mts.map +0 -1
- package/dist/service-descriptor.d.cts.map +0 -1
- package/dist/service-descriptor.d.mts.map +0 -1
- package/dist/types.d.cts.map +0 -1
- package/dist/types.d.mts.map +0 -1
- package/dist/ui/head.d.cts.map +0 -1
- package/dist/ui/head.d.mts.map +0 -1
- package/dist/ui/metadata.d.cts.map +0 -1
- package/dist/ui/metadata.d.mts.map +0 -1
- package/dist/ui/router.d.cts.map +0 -1
- package/dist/ui/router.d.mts.map +0 -1
- package/dist/ui/runtime.d.cts.map +0 -1
- package/dist/ui/runtime.d.mts.map +0 -1
- package/dist/ui/types.d.cts.map +0 -1
- package/dist/ui/types.d.mts.map +0 -1
|
@@ -0,0 +1,343 @@
|
|
|
1
|
+
const require_core = require('./core.cjs');
|
|
2
|
+
const require_errors = require('./errors.cjs');
|
|
3
|
+
let node_fs = require("node:fs");
|
|
4
|
+
let node_path = require("node:path");
|
|
5
|
+
let effect = require("effect");
|
|
6
|
+
let node_crypto = require("node:crypto");
|
|
7
|
+
let drizzle_orm = require("drizzle-orm");
|
|
8
|
+
|
|
9
|
+
//#region src/db/run-migrations.ts
|
|
10
|
+
const migrationJournalSchema = effect.Schema.Struct({ entries: effect.Schema.Array(effect.Schema.Struct({
|
|
11
|
+
idx: effect.Schema.Finite,
|
|
12
|
+
when: effect.Schema.Finite,
|
|
13
|
+
tag: effect.Schema.String
|
|
14
|
+
})) });
|
|
15
|
+
const DEFAULT_DUPLICATE_SQLSTATES = require_core.DUPLICATE_OBJECT_SQLSTATES;
|
|
16
|
+
function normalizeRows(result) {
|
|
17
|
+
if (Array.isArray(result)) return result;
|
|
18
|
+
if (result && typeof result === "object" && "rows" in result) return result.rows;
|
|
19
|
+
return [];
|
|
20
|
+
}
|
|
21
|
+
function isDuplicateObjectError(error, codes) {
|
|
22
|
+
return require_core.visitCauses(error, 6, (link) => {
|
|
23
|
+
const code = link.code;
|
|
24
|
+
return typeof code === "string" && codes.includes(code);
|
|
25
|
+
});
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
28
|
+
* Whether a failed migration statement should be treated as duplicate-DDL
|
|
29
|
+
* tolerance: either an explicit duplicate-object class, or the concurrent-DDL
|
|
30
|
+
* catalog collision (SQLSTATE 23505 on a pg_catalog unique index) that two
|
|
31
|
+
* booting processes can produce when they run the same `CREATE TABLE` against
|
|
32
|
+
* a fresh database at the same time.
|
|
33
|
+
*/
|
|
34
|
+
function isTolerableDuplicateDdl(error, codes) {
|
|
35
|
+
return isDuplicateObjectError(error, codes) || require_core.isConcurrentDdlUniqueViolation(error);
|
|
36
|
+
}
|
|
37
|
+
/**
|
|
38
|
+
* Check which of the given expected tables already exist in the target schema.
|
|
39
|
+
* The schema name is bound as a query parameter.
|
|
40
|
+
*/
|
|
41
|
+
async function existingTablesIn(executor, tables, schemaName) {
|
|
42
|
+
if (tables.length === 0) return /* @__PURE__ */ new Set();
|
|
43
|
+
const schema = schemaName ?? "public";
|
|
44
|
+
const result = await executor.execute(drizzle_orm.sql`
|
|
45
|
+
SELECT table_name FROM information_schema.tables
|
|
46
|
+
WHERE table_schema = ${schema}
|
|
47
|
+
AND table_name = ANY(${drizzle_orm.sql.raw(require_core.toSqlArray(tables))})
|
|
48
|
+
`);
|
|
49
|
+
return new Set(normalizeRows(result).map((r) => r.table_name));
|
|
50
|
+
}
|
|
51
|
+
/** Read applied hashes from the migration journal. */
|
|
52
|
+
async function readAppliedHashesIn(executor, ref) {
|
|
53
|
+
const result = await executor.execute(drizzle_orm.sql`SELECT hash FROM ${ref}`);
|
|
54
|
+
return new Set(normalizeRows(result).map((r) => r.hash));
|
|
55
|
+
}
|
|
56
|
+
function loadMigrations(opts = {}) {
|
|
57
|
+
return effect.Effect.gen(function* () {
|
|
58
|
+
if (opts.virtual) {
|
|
59
|
+
const mod = yield* effect.Effect.tryPromise({
|
|
60
|
+
try: () => opts.virtual(),
|
|
61
|
+
catch: (cause) => new require_errors.DatabaseError({
|
|
62
|
+
stage: "load",
|
|
63
|
+
cause
|
|
64
|
+
})
|
|
65
|
+
}).pipe(effect.Effect.option);
|
|
66
|
+
const migrations = effect.Option.getOrUndefined(mod)?.default;
|
|
67
|
+
if (migrations?.length) {
|
|
68
|
+
yield* effect.Effect.logInfo(`[Database] Loaded ${migrations.length} migration(s) from virtual module`);
|
|
69
|
+
return {
|
|
70
|
+
migrations,
|
|
71
|
+
source: "virtual"
|
|
72
|
+
};
|
|
73
|
+
}
|
|
74
|
+
yield* effect.Effect.logDebug("[Database] Virtual migrations unavailable, loading from disk");
|
|
75
|
+
}
|
|
76
|
+
const diskMigrations = effect.Option.getOrUndefined(yield* loadMigrationsFromDisk(opts.fromDir).pipe(effect.Effect.option));
|
|
77
|
+
if (diskMigrations) {
|
|
78
|
+
yield* effect.Effect.logInfo(`[Database] Loaded ${diskMigrations.length} migration(s) from disk`);
|
|
79
|
+
return {
|
|
80
|
+
migrations: diskMigrations,
|
|
81
|
+
source: "disk"
|
|
82
|
+
};
|
|
83
|
+
}
|
|
84
|
+
yield* effect.Effect.logWarning("[Database] No migrations found from virtual or disk");
|
|
85
|
+
return {
|
|
86
|
+
migrations: [],
|
|
87
|
+
source: "disk"
|
|
88
|
+
};
|
|
89
|
+
});
|
|
90
|
+
}
|
|
91
|
+
function loadMigrationsFromDisk(fromDir) {
|
|
92
|
+
return effect.Effect.gen(function* () {
|
|
93
|
+
const migrationsDir = (0, node_path.resolve)(fromDir ?? __dirname, "migrations");
|
|
94
|
+
const journalPath = (0, node_path.join)(migrationsDir, "meta", "_journal.json");
|
|
95
|
+
if (!(0, node_fs.existsSync)(journalPath)) return yield* new require_errors.DatabaseError({
|
|
96
|
+
stage: "load",
|
|
97
|
+
cause: /* @__PURE__ */ new Error(`Migrations journal not found at ${journalPath}. Run \`db:generate\` first.`)
|
|
98
|
+
});
|
|
99
|
+
const journalContents = yield* effect.Effect.try({
|
|
100
|
+
try: () => (0, node_fs.readFileSync)(journalPath, "utf8"),
|
|
101
|
+
catch: (cause) => new require_errors.DatabaseError({
|
|
102
|
+
stage: "load",
|
|
103
|
+
cause
|
|
104
|
+
})
|
|
105
|
+
});
|
|
106
|
+
const json = yield* effect.Schema.decodeEffect(effect.Schema.fromJsonString(effect.Schema.Json))(journalContents).pipe(effect.Effect.mapError((cause) => new require_errors.DatabaseError({
|
|
107
|
+
stage: "load",
|
|
108
|
+
cause
|
|
109
|
+
})));
|
|
110
|
+
const journal = yield* effect.Schema.decodeUnknownEffect(migrationJournalSchema)(json).pipe(effect.Effect.mapError((cause) => new require_errors.DatabaseError({
|
|
111
|
+
stage: "load",
|
|
112
|
+
cause
|
|
113
|
+
})));
|
|
114
|
+
return yield* effect.Effect.forEach(journal.entries, (entry) => effect.Effect.try({
|
|
115
|
+
try: () => {
|
|
116
|
+
const sqlPath = (0, node_path.join)(migrationsDir, `${entry.tag}.sql`);
|
|
117
|
+
if (!(0, node_fs.existsSync)(sqlPath)) throw new Error(`Migration SQL file not found: ${sqlPath}`);
|
|
118
|
+
const raw = (0, node_fs.readFileSync)(sqlPath, "utf8");
|
|
119
|
+
const sqlStatements = raw.split("--> statement-breakpoint").map((statement) => statement.trim());
|
|
120
|
+
const hash = (0, node_crypto.createHash)("sha256").update(raw).digest("hex");
|
|
121
|
+
return {
|
|
122
|
+
idx: entry.idx,
|
|
123
|
+
when: entry.when,
|
|
124
|
+
tag: entry.tag,
|
|
125
|
+
hash,
|
|
126
|
+
sql: sqlStatements
|
|
127
|
+
};
|
|
128
|
+
},
|
|
129
|
+
catch: (cause) => new require_errors.DatabaseError({
|
|
130
|
+
stage: "load",
|
|
131
|
+
cause
|
|
132
|
+
})
|
|
133
|
+
}));
|
|
134
|
+
});
|
|
135
|
+
}
|
|
136
|
+
function journalRef(s) {
|
|
137
|
+
return drizzle_orm.sql.raw(`"${s.schema}"."${s.table}"`);
|
|
138
|
+
}
|
|
139
|
+
/**
|
|
140
|
+
* Apply one statement under a savepoint, tolerating duplicate DDL: either an
|
|
141
|
+
* explicit duplicate-object class or the concurrent-DDL catalog collision a
|
|
142
|
+
* non-participant migrator (drizzle-kit) can still produce.
|
|
143
|
+
*/
|
|
144
|
+
async function applyWithSavepoint(tx, query, migrationTag, savepoint, duplicateSqlStates) {
|
|
145
|
+
await tx.execute(drizzle_orm.sql.raw(`SAVEPOINT ${savepoint}`));
|
|
146
|
+
try {
|
|
147
|
+
await tx.execute(query);
|
|
148
|
+
} catch (cause) {
|
|
149
|
+
if (isTolerableDuplicateDdl(cause, duplicateSqlStates)) {
|
|
150
|
+
await tx.execute(drizzle_orm.sql.raw(`ROLLBACK TO SAVEPOINT ${savepoint}`));
|
|
151
|
+
return;
|
|
152
|
+
}
|
|
153
|
+
throw new require_errors.DatabaseError({
|
|
154
|
+
stage: "migration",
|
|
155
|
+
migrationTag,
|
|
156
|
+
cause
|
|
157
|
+
});
|
|
158
|
+
}
|
|
159
|
+
await tx.execute(drizzle_orm.sql.raw(`RELEASE SAVEPOINT ${savepoint}`));
|
|
160
|
+
}
|
|
161
|
+
/**
|
|
162
|
+
* The whole migration run inside ONE transaction that opens with a
|
|
163
|
+
* journal-scoped `pg_advisory_xact_lock`. Drizzle's `db.transaction` pins a
|
|
164
|
+
* single pooled client for the callback, so the lock, the journal read, the
|
|
165
|
+
* DDL, and the journal inserts all share one session; the lock releases at
|
|
166
|
+
* COMMIT/ROLLBACK or on connection death — a crashed migrator can never
|
|
167
|
+
* orphan it. A concurrent migrator blocks (bounded by the driver's
|
|
168
|
+
* `lock_timeout`), then reads the winner's committed journal rows and applies
|
|
169
|
+
* nothing.
|
|
170
|
+
*/
|
|
171
|
+
async function runLockedTransaction(db, args) {
|
|
172
|
+
const { sorted, journal, ref, schemaName, duplicateSqlStates } = args;
|
|
173
|
+
const appliedTags = [];
|
|
174
|
+
const logs = [];
|
|
175
|
+
await db.transaction(async (tx) => {
|
|
176
|
+
await tx.execute(drizzle_orm.sql`SELECT pg_advisory_xact_lock(hashtextextended(${`${journal.schema}.${journal.table}`}, 0))`);
|
|
177
|
+
await applyWithSavepoint(tx, drizzle_orm.sql`CREATE SCHEMA IF NOT EXISTS ${drizzle_orm.sql.raw(`"${journal.schema}"`)}`, "init-schema", "sp_init_schema", duplicateSqlStates);
|
|
178
|
+
await applyWithSavepoint(tx, drizzle_orm.sql`
|
|
179
|
+
CREATE TABLE IF NOT EXISTS ${ref} (
|
|
180
|
+
id SERIAL PRIMARY KEY,
|
|
181
|
+
hash text NOT NULL,
|
|
182
|
+
created_at bigint
|
|
183
|
+
)
|
|
184
|
+
`, "init-table", "sp_init_table", duplicateSqlStates);
|
|
185
|
+
if (schemaName) await applyWithSavepoint(tx, drizzle_orm.sql`CREATE SCHEMA IF NOT EXISTS ${drizzle_orm.sql.raw(`"${schemaName}"`)}`, "init-data-schema", "sp_init_data_schema", duplicateSqlStates);
|
|
186
|
+
const appliedHashes = await readAppliedHashesIn(tx, ref);
|
|
187
|
+
for (const migration of sorted) {
|
|
188
|
+
if (appliedHashes.has(migration.hash) || appliedHashes.has(migration.hash.slice(0, 12))) continue;
|
|
189
|
+
const expectedTables = require_core.extractExpectedTables([migration]);
|
|
190
|
+
if (expectedTables.length > 0) {
|
|
191
|
+
const existing = await existingTablesIn(tx, expectedTables, schemaName);
|
|
192
|
+
const missingTables = expectedTables.filter((t) => !existing.has(t));
|
|
193
|
+
if (missingTables.length === 0) {
|
|
194
|
+
logs.push(`[Database] All tables for migration ${migration.tag} already exist — recording as applied without replaying DDL`);
|
|
195
|
+
await tx.execute(drizzle_orm.sql`INSERT INTO ${ref} (hash, created_at) VALUES (${migration.hash}, ${migration.when})`);
|
|
196
|
+
appliedHashes.add(migration.hash);
|
|
197
|
+
appliedTags.push(migration.tag);
|
|
198
|
+
continue;
|
|
199
|
+
}
|
|
200
|
+
if (missingTables.length < expectedTables.length) logs.push(`[Database] Partial table overlap for migration ${migration.tag}: ${expectedTables.length - missingTables.length} table(s) exist but not all. Applying migration — existing tables: ${expectedTables.filter((t) => existing.has(t)).join(", ")}`);
|
|
201
|
+
}
|
|
202
|
+
logs.push(`[Database] Applying migration: ${migration.tag}`);
|
|
203
|
+
for (const [i, statement] of migration.sql.entries()) {
|
|
204
|
+
const stmt = schemaName ? statement.replace(/"public"\./g, "") : statement;
|
|
205
|
+
await applyWithSavepoint(tx, drizzle_orm.sql.raw(stmt), migration.tag, `stmt_${i}`, duplicateSqlStates);
|
|
206
|
+
}
|
|
207
|
+
await tx.execute(drizzle_orm.sql`INSERT INTO ${ref} (hash, created_at) VALUES (${migration.hash}, ${migration.when})`);
|
|
208
|
+
appliedTags.push(migration.tag);
|
|
209
|
+
}
|
|
210
|
+
});
|
|
211
|
+
return {
|
|
212
|
+
appliedTags,
|
|
213
|
+
logs
|
|
214
|
+
};
|
|
215
|
+
}
|
|
216
|
+
/**
|
|
217
|
+
* Apply pending migrations to the target database.
|
|
218
|
+
*
|
|
219
|
+
* Namespace model: `opts.schemaName` (`plugin_<slug>`) scopes data tables; the
|
|
220
|
+
* journal lives in `opts.journal` (default the shared `drizzle.__drizzle_migrations`).
|
|
221
|
+
* Undefined `schemaName` means public-schema (api) or dedicated-DB (auth) topology.
|
|
222
|
+
*
|
|
223
|
+
* Concurrency: the run serializes on a journal-scoped Postgres advisory
|
|
224
|
+
* transaction lock, so the dev double-boot (plugin dev-server + the host's
|
|
225
|
+
* in-process load), parallel test files, and overlapping production replicas
|
|
226
|
+
* converge instead of colliding in pg_catalog. SAVEPOINT-based duplicate-DDL
|
|
227
|
+
* tolerance stays as defense-in-depth for non-participants (drizzle-kit).
|
|
228
|
+
*
|
|
229
|
+
* Reliability floor: hash-tracked idempotence with a preflight that records
|
|
230
|
+
* fully-overlapped migrations as applied, everything in one locked
|
|
231
|
+
* transaction, retried on deadlock/serialization/lock-timeout/connection
|
|
232
|
+
* states — a failed attempt rolls back cleanly and re-runs.
|
|
233
|
+
*/
|
|
234
|
+
function runMigrations(db, migrations, opts = {}) {
|
|
235
|
+
return effect.Effect.gen(function* () {
|
|
236
|
+
const sorted = [...migrations].sort((a, b) => a.idx - b.idx);
|
|
237
|
+
const journal = opts.journal ?? require_core.getMigrationStorage();
|
|
238
|
+
const schemaName = opts.schemaName;
|
|
239
|
+
const duplicateSqlStates = opts.duplicateSqlStates ?? DEFAULT_DUPLICATE_SQLSTATES;
|
|
240
|
+
const { appliedTags, logs } = yield* effect.Effect.retry(effect.Effect.tryPromise({
|
|
241
|
+
try: () => runLockedTransaction(db, {
|
|
242
|
+
sorted,
|
|
243
|
+
journal,
|
|
244
|
+
ref: journalRef(journal),
|
|
245
|
+
schemaName,
|
|
246
|
+
duplicateSqlStates
|
|
247
|
+
}),
|
|
248
|
+
catch: (cause) => cause instanceof require_errors.DatabaseError ? cause : new require_errors.DatabaseError({
|
|
249
|
+
stage: "migration",
|
|
250
|
+
migrationTag: "run",
|
|
251
|
+
cause
|
|
252
|
+
})
|
|
253
|
+
}), {
|
|
254
|
+
schedule: effect.Schedule.spaced("500 millis"),
|
|
255
|
+
times: 3,
|
|
256
|
+
while: require_core.isRetryableMigrationExecutionError
|
|
257
|
+
});
|
|
258
|
+
for (const line of logs) yield* effect.Effect.logInfo(line);
|
|
259
|
+
return {
|
|
260
|
+
applied: appliedTags.length,
|
|
261
|
+
total: sorted.length,
|
|
262
|
+
storage: journal,
|
|
263
|
+
schema: schemaName
|
|
264
|
+
};
|
|
265
|
+
});
|
|
266
|
+
}
|
|
267
|
+
/**
|
|
268
|
+
* Detect drift between the local migration set and the database journal.
|
|
269
|
+
*
|
|
270
|
+
* Pass an explicit `journal` resolved from the caller's workspace for reliable
|
|
271
|
+
* slug derivation; the default relies on `process.env.npm_package_name`, which is
|
|
272
|
+
* unreliable under bundlers and Module Federation remotes.
|
|
273
|
+
*/
|
|
274
|
+
function detectDrift(db, migrations, journal, schemaName) {
|
|
275
|
+
return effect.Effect.gen(function* () {
|
|
276
|
+
const storage = journal ?? require_core.getMigrationStorage();
|
|
277
|
+
const expectedTables = require_core.extractExpectedTables(migrations);
|
|
278
|
+
const ref = journalRef(storage);
|
|
279
|
+
const appliedCount = (yield* effect.Effect.tryPromise({
|
|
280
|
+
try: () => readAppliedHashesIn(db, ref),
|
|
281
|
+
catch: (cause) => new require_errors.DatabaseError({
|
|
282
|
+
stage: "migration",
|
|
283
|
+
migrationTag: "read-applied",
|
|
284
|
+
cause
|
|
285
|
+
})
|
|
286
|
+
}).pipe(effect.Effect.orElseSucceed(() => /* @__PURE__ */ new Set()))).size;
|
|
287
|
+
if (expectedTables.length === 0) return {
|
|
288
|
+
status: "empty",
|
|
289
|
+
expectedTables: [],
|
|
290
|
+
missingTables: [],
|
|
291
|
+
appliedHashes: appliedCount,
|
|
292
|
+
localHashes: migrations.length,
|
|
293
|
+
storage
|
|
294
|
+
};
|
|
295
|
+
const existing = yield* effect.Effect.tryPromise({
|
|
296
|
+
try: () => existingTablesIn(db, expectedTables, schemaName),
|
|
297
|
+
catch: (cause) => new require_errors.DatabaseError({
|
|
298
|
+
stage: "migration",
|
|
299
|
+
migrationTag: "preflight-table-check",
|
|
300
|
+
cause
|
|
301
|
+
})
|
|
302
|
+
}).pipe(effect.Effect.orElseSucceed(() => /* @__PURE__ */ new Set()));
|
|
303
|
+
const missingTables = expectedTables.filter((t) => !existing.has(t));
|
|
304
|
+
if (appliedCount === 0 && missingTables.length === 0) return {
|
|
305
|
+
status: "untracked-existing-schema",
|
|
306
|
+
expectedTables,
|
|
307
|
+
missingTables: [],
|
|
308
|
+
appliedHashes: 0,
|
|
309
|
+
localHashes: migrations.length,
|
|
310
|
+
storage
|
|
311
|
+
};
|
|
312
|
+
if (missingTables.length === 0) return {
|
|
313
|
+
status: "healthy",
|
|
314
|
+
expectedTables,
|
|
315
|
+
missingTables: [],
|
|
316
|
+
appliedHashes: appliedCount,
|
|
317
|
+
localHashes: migrations.length,
|
|
318
|
+
storage
|
|
319
|
+
};
|
|
320
|
+
if (missingTables.length === expectedTables.length) return {
|
|
321
|
+
status: "drift-safe-repair",
|
|
322
|
+
expectedTables,
|
|
323
|
+
missingTables,
|
|
324
|
+
appliedHashes: appliedCount,
|
|
325
|
+
localHashes: migrations.length,
|
|
326
|
+
storage
|
|
327
|
+
};
|
|
328
|
+
return {
|
|
329
|
+
status: "drift-manual",
|
|
330
|
+
expectedTables,
|
|
331
|
+
missingTables,
|
|
332
|
+
appliedHashes: appliedCount,
|
|
333
|
+
localHashes: migrations.length,
|
|
334
|
+
storage
|
|
335
|
+
};
|
|
336
|
+
});
|
|
337
|
+
}
|
|
338
|
+
|
|
339
|
+
//#endregion
|
|
340
|
+
exports.detectDrift = detectDrift;
|
|
341
|
+
exports.loadMigrations = loadMigrations;
|
|
342
|
+
exports.runMigrations = runMigrations;
|
|
343
|
+
//# sourceMappingURL=run-migrations.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"run-migrations.cjs","names":["Schema","DUPLICATE_OBJECT_SQLSTATES","visitCauses","isConcurrentDdlUniqueViolation","sql","toSqlArray","Effect","DatabaseError","Option","resolve","join","existsSync","readFileSync","createHash","extractExpectedTables","getMigrationStorage","Schedule","isRetryableMigrationExecutionError"],"sources":["../../src/db/run-migrations.ts"],"sourcesContent":["import { createHash } from \"node:crypto\";\nimport { existsSync, readFileSync } from \"node:fs\";\nimport { join, resolve } from \"node:path\";\nimport { sql } from \"drizzle-orm\";\nimport { Effect, Option, Schedule, Schema } from \"effect\";\nimport {\n DUPLICATE_OBJECT_SQLSTATES,\n extractExpectedTables,\n getMigrationStorage,\n isConcurrentDdlUniqueViolation,\n isRetryableMigrationExecutionError,\n type MigrationStorage,\n toSqlArray,\n visitCauses,\n} from \"./core\";\nimport { DatabaseError } from \"./errors\";\n\nexport interface Migration {\n idx: number;\n when: number;\n tag: string;\n hash: string;\n sql: string[];\n}\n\n/**\n * Minimal structural view of a drizzle PgDatabase — the concrete per-workspace\n * `PgDatabase<PgQueryResultHKT, TSchema>` values satisfy this.\n */\nexport interface MigrationDatabase {\n execute(query: unknown): Promise<unknown>;\n transaction<T>(fn: (tx: { execute(query: unknown): Promise<unknown> }) => Promise<T>): Promise<T>;\n}\n\nexport interface LoadedMigrations {\n migrations: Migration[];\n source: \"virtual\" | \"disk\";\n}\n\nconst migrationJournalSchema = Schema.Struct({\n entries: Schema.Array(\n Schema.Struct({\n idx: Schema.Finite,\n when: Schema.Finite,\n tag: Schema.String,\n }),\n ),\n});\n\nexport interface DriftReport {\n status: \"healthy\" | \"empty\" | \"untracked-existing-schema\" | \"drift-safe-repair\" | \"drift-manual\";\n expectedTables: string[];\n missingTables: string[];\n appliedHashes: number;\n localHashes: number;\n storage: MigrationStorage;\n}\n\nexport interface MigrationReport {\n applied: number;\n total: number;\n storage: MigrationStorage;\n schema: string | undefined;\n}\n\nexport interface RunMigrationsOptions {\n schemaName?: string;\n journal?: MigrationStorage;\n duplicateSqlStates?: readonly string[];\n}\n\nconst DEFAULT_DUPLICATE_SQLSTATES: readonly string[] = DUPLICATE_OBJECT_SQLSTATES;\n\nfunction normalizeRows<T>(result: unknown): T[] {\n if (Array.isArray(result)) return result as T[];\n if (result && typeof result === \"object\" && \"rows\" in result) {\n return (result as { rows: T[] }).rows;\n }\n return [];\n}\n\ntype QueryExecutor = { execute(query: unknown): Promise<unknown> };\n\nfunction isDuplicateObjectError(error: unknown, codes: readonly string[]): boolean {\n return visitCauses(error, 6, (link) => {\n const code = (link as { code?: unknown }).code;\n return typeof code === \"string\" && codes.includes(code);\n });\n}\n\n/**\n * Whether a failed migration statement should be treated as duplicate-DDL\n * tolerance: either an explicit duplicate-object class, or the concurrent-DDL\n * catalog collision (SQLSTATE 23505 on a pg_catalog unique index) that two\n * booting processes can produce when they run the same `CREATE TABLE` against\n * a fresh database at the same time.\n */\nfunction isTolerableDuplicateDdl(error: unknown, codes: readonly string[]): boolean {\n return isDuplicateObjectError(error, codes) || isConcurrentDdlUniqueViolation(error);\n}\n\n/**\n * Check which of the given expected tables already exist in the target schema.\n * The schema name is bound as a query parameter.\n */\nasync function existingTablesIn(\n executor: QueryExecutor,\n tables: string[],\n schemaName?: string,\n): Promise<Set<string>> {\n if (tables.length === 0) return new Set<string>();\n const schema = schemaName ?? \"public\";\n const result = await executor.execute(sql`\n SELECT table_name FROM information_schema.tables\n WHERE table_schema = ${schema}\n AND table_name = ANY(${sql.raw(toSqlArray(tables))})\n `);\n return new Set(normalizeRows<{ table_name: string }>(result).map((r) => r.table_name));\n}\n\n/** Read applied hashes from the migration journal. */\nasync function readAppliedHashesIn(\n executor: QueryExecutor,\n ref: ReturnType<typeof sql.raw>,\n): Promise<Set<string>> {\n const result = await executor.execute(sql`SELECT hash FROM ${ref}`);\n return new Set(normalizeRows<{ hash: string }>(result).map((r) => r.hash));\n}\n\nexport interface LoadMigrationsOptions {\n /** Directory containing the workspace's drizzle `migrations/` folder for the disk fallback. */\n fromDir?: string;\n /**\n * Bundler-provided virtual-module loader (e.g. `virtual:drizzle-migrations.sql`\n * registered by rspack). Lives at the call site — the shared package must not\n * name the virtual module, which only exists inside plugin bundles.\n */\n virtual?: () => Promise<{ default?: Migration[] }>;\n}\n\nexport function loadMigrations(\n opts: LoadMigrationsOptions = {},\n): Effect.Effect<LoadedMigrations, DatabaseError> {\n return Effect.gen(function* () {\n if (opts.virtual) {\n const mod = yield* Effect.tryPromise({\n try: () => opts.virtual!(),\n catch: (cause) => new DatabaseError({ stage: \"load\", cause }),\n }).pipe(Effect.option);\n const migrations = Option.getOrUndefined(mod)?.default;\n if (migrations?.length) {\n yield* Effect.logInfo(\n `[Database] Loaded ${migrations.length} migration(s) from virtual module`,\n );\n return { migrations, source: \"virtual\" as const };\n }\n yield* Effect.logDebug(\"[Database] Virtual migrations unavailable, loading from disk\");\n }\n\n const diskMigrations = Option.getOrUndefined(\n yield* loadMigrationsFromDisk(opts.fromDir).pipe(Effect.option),\n );\n if (diskMigrations) {\n yield* Effect.logInfo(`[Database] Loaded ${diskMigrations.length} migration(s) from disk`);\n return { migrations: diskMigrations, source: \"disk\" as const };\n }\n\n yield* Effect.logWarning(\"[Database] No migrations found from virtual or disk\");\n return { migrations: [], source: \"disk\" as const };\n });\n}\n\nfunction loadMigrationsFromDisk(fromDir?: string): Effect.Effect<Migration[], DatabaseError> {\n return Effect.gen(function* () {\n const migrationsDir = resolve(fromDir ?? import.meta.dirname, \"migrations\");\n const journalPath = join(migrationsDir, \"meta\", \"_journal.json\");\n\n if (!existsSync(journalPath)) {\n return yield* new DatabaseError({\n stage: \"load\",\n cause: new Error(\n `Migrations journal not found at ${journalPath}. Run \\`db:generate\\` first.`,\n ),\n });\n }\n\n const journalContents = yield* Effect.try({\n try: () => readFileSync(journalPath, \"utf8\"),\n catch: (cause) => new DatabaseError({ stage: \"load\", cause }),\n });\n const json = yield* Schema.decodeEffect(Schema.fromJsonString(Schema.Json))(\n journalContents,\n ).pipe(Effect.mapError((cause) => new DatabaseError({ stage: \"load\", cause })));\n const journal = yield* Schema.decodeUnknownEffect(migrationJournalSchema)(json).pipe(\n Effect.mapError((cause) => new DatabaseError({ stage: \"load\", cause })),\n );\n\n return yield* Effect.forEach(journal.entries, (entry) =>\n Effect.try({\n try: () => {\n const sqlPath = join(migrationsDir, `${entry.tag}.sql`);\n if (!existsSync(sqlPath)) {\n throw new Error(`Migration SQL file not found: ${sqlPath}`);\n }\n const raw = readFileSync(sqlPath, \"utf8\");\n const sqlStatements = raw\n .split(\"--> statement-breakpoint\")\n .map((statement) => statement.trim());\n const hash = createHash(\"sha256\").update(raw).digest(\"hex\");\n return { idx: entry.idx, when: entry.when, tag: entry.tag, hash, sql: sqlStatements };\n },\n catch: (cause) => new DatabaseError({ stage: \"load\", cause }),\n }),\n );\n });\n}\n\nfunction journalRef(s: MigrationStorage): ReturnType<typeof sql> {\n return sql.raw(`\"${s.schema}\".\"${s.table}\"`);\n}\n\n/**\n * Apply one statement under a savepoint, tolerating duplicate DDL: either an\n * explicit duplicate-object class or the concurrent-DDL catalog collision a\n * non-participant migrator (drizzle-kit) can still produce.\n */\nasync function applyWithSavepoint(\n tx: QueryExecutor,\n query: ReturnType<typeof sql>,\n migrationTag: string,\n savepoint: string,\n duplicateSqlStates: readonly string[],\n): Promise<void> {\n await tx.execute(sql.raw(`SAVEPOINT ${savepoint}`));\n try {\n await tx.execute(query);\n } catch (cause) {\n if (isTolerableDuplicateDdl(cause, duplicateSqlStates)) {\n await tx.execute(sql.raw(`ROLLBACK TO SAVEPOINT ${savepoint}`));\n return;\n }\n throw new DatabaseError({ stage: \"migration\", migrationTag, cause });\n }\n await tx.execute(sql.raw(`RELEASE SAVEPOINT ${savepoint}`));\n}\n\ninterface LockedRunArgs {\n sorted: Migration[];\n journal: MigrationStorage;\n ref: ReturnType<typeof sql.raw>;\n schemaName: string | undefined;\n duplicateSqlStates: readonly string[];\n}\n\n/**\n * The whole migration run inside ONE transaction that opens with a\n * journal-scoped `pg_advisory_xact_lock`. Drizzle's `db.transaction` pins a\n * single pooled client for the callback, so the lock, the journal read, the\n * DDL, and the journal inserts all share one session; the lock releases at\n * COMMIT/ROLLBACK or on connection death — a crashed migrator can never\n * orphan it. A concurrent migrator blocks (bounded by the driver's\n * `lock_timeout`), then reads the winner's committed journal rows and applies\n * nothing.\n */\nasync function runLockedTransaction(\n db: MigrationDatabase,\n args: LockedRunArgs,\n): Promise<{ appliedTags: string[]; logs: string[] }> {\n const { sorted, journal, ref, schemaName, duplicateSqlStates } = args;\n const appliedTags: string[] = [];\n const logs: string[] = [];\n\n await db.transaction(async (tx) => {\n await tx.execute(\n sql`SELECT pg_advisory_xact_lock(hashtextextended(${`${journal.schema}.${journal.table}`}, 0))`,\n );\n\n await applyWithSavepoint(\n tx,\n sql`CREATE SCHEMA IF NOT EXISTS ${sql.raw(`\"${journal.schema}\"`)}`,\n \"init-schema\",\n \"sp_init_schema\",\n duplicateSqlStates,\n );\n await applyWithSavepoint(\n tx,\n sql`\n CREATE TABLE IF NOT EXISTS ${ref} (\n id SERIAL PRIMARY KEY,\n hash text NOT NULL,\n created_at bigint\n )\n `,\n \"init-table\",\n \"sp_init_table\",\n duplicateSqlStates,\n );\n if (schemaName) {\n await applyWithSavepoint(\n tx,\n sql`CREATE SCHEMA IF NOT EXISTS ${sql.raw(`\"${schemaName}\"`)}`,\n \"init-data-schema\",\n \"sp_init_data_schema\",\n duplicateSqlStates,\n );\n }\n\n const appliedHashes = await readAppliedHashesIn(tx, ref);\n\n for (const migration of sorted) {\n const isApplied =\n appliedHashes.has(migration.hash) || appliedHashes.has(migration.hash.slice(0, 12));\n if (isApplied) continue;\n\n // Preflight: if this migration's expected tables already exist, record it\n // as applied rather than crashing on a duplicate DDL error.\n const expectedTables = extractExpectedTables([migration]);\n if (expectedTables.length > 0) {\n const existing = await existingTablesIn(tx, expectedTables, schemaName);\n const missingTables = expectedTables.filter((t) => !existing.has(t));\n if (missingTables.length === 0) {\n logs.push(\n `[Database] All tables for migration ${migration.tag} already exist — ` +\n `recording as applied without replaying DDL`,\n );\n await tx.execute(\n sql`INSERT INTO ${ref} (hash, created_at) VALUES (${migration.hash}, ${migration.when})`,\n );\n appliedHashes.add(migration.hash);\n appliedTags.push(migration.tag);\n continue;\n }\n if (missingTables.length < expectedTables.length) {\n logs.push(\n `[Database] Partial table overlap for migration ${migration.tag}: ` +\n `${expectedTables.length - missingTables.length} table(s) exist but not all. ` +\n `Applying migration — existing tables: ${expectedTables.filter((t) => existing.has(t)).join(\", \")}`,\n );\n }\n }\n\n logs.push(`[Database] Applying migration: ${migration.tag}`);\n\n for (const [i, statement] of migration.sql.entries()) {\n const stmt = schemaName ? statement.replace(/\"public\"\\./g, \"\") : statement;\n await applyWithSavepoint(tx, sql.raw(stmt), migration.tag, `stmt_${i}`, duplicateSqlStates);\n }\n await tx.execute(\n sql`INSERT INTO ${ref} (hash, created_at) VALUES (${migration.hash}, ${migration.when})`,\n );\n appliedTags.push(migration.tag);\n }\n });\n\n return { appliedTags, logs };\n}\n\n/**\n * Apply pending migrations to the target database.\n *\n * Namespace model: `opts.schemaName` (`plugin_<slug>`) scopes data tables; the\n * journal lives in `opts.journal` (default the shared `drizzle.__drizzle_migrations`).\n * Undefined `schemaName` means public-schema (api) or dedicated-DB (auth) topology.\n *\n * Concurrency: the run serializes on a journal-scoped Postgres advisory\n * transaction lock, so the dev double-boot (plugin dev-server + the host's\n * in-process load), parallel test files, and overlapping production replicas\n * converge instead of colliding in pg_catalog. SAVEPOINT-based duplicate-DDL\n * tolerance stays as defense-in-depth for non-participants (drizzle-kit).\n *\n * Reliability floor: hash-tracked idempotence with a preflight that records\n * fully-overlapped migrations as applied, everything in one locked\n * transaction, retried on deadlock/serialization/lock-timeout/connection\n * states — a failed attempt rolls back cleanly and re-runs.\n */\nexport function runMigrations(\n db: MigrationDatabase,\n migrations: Migration[],\n opts: RunMigrationsOptions = {},\n): Effect.Effect<MigrationReport, DatabaseError> {\n return Effect.gen(function* () {\n const sorted = [...migrations].sort((a, b) => a.idx - b.idx);\n const journal = opts.journal ?? getMigrationStorage();\n const schemaName = opts.schemaName;\n const duplicateSqlStates = opts.duplicateSqlStates ?? DEFAULT_DUPLICATE_SQLSTATES;\n\n const { appliedTags, logs } = yield* Effect.retry(\n Effect.tryPromise({\n try: () =>\n runLockedTransaction(db, {\n sorted,\n journal,\n ref: journalRef(journal),\n schemaName,\n duplicateSqlStates,\n }),\n catch: (cause) =>\n cause instanceof DatabaseError\n ? cause\n : new DatabaseError({ stage: \"migration\", migrationTag: \"run\", cause }),\n }),\n {\n schedule: Schedule.spaced(\"500 millis\"),\n times: 3,\n while: isRetryableMigrationExecutionError,\n },\n );\n\n for (const line of logs) yield* Effect.logInfo(line);\n\n return {\n applied: appliedTags.length,\n total: sorted.length,\n storage: journal,\n schema: schemaName,\n };\n });\n}\n\n/**\n * Detect drift between the local migration set and the database journal.\n *\n * Pass an explicit `journal` resolved from the caller's workspace for reliable\n * slug derivation; the default relies on `process.env.npm_package_name`, which is\n * unreliable under bundlers and Module Federation remotes.\n */\nexport function detectDrift(\n db: MigrationDatabase,\n migrations: Migration[],\n journal?: MigrationStorage,\n schemaName?: string,\n): Effect.Effect<DriftReport, DatabaseError> {\n return Effect.gen(function* () {\n const storage = journal ?? getMigrationStorage();\n const expectedTables = extractExpectedTables(migrations);\n const ref = journalRef(storage);\n\n // Lenient by design: drift detection reports on whatever it can read —\n // a failed journal read just means \"nothing tracked yet\".\n const appliedHashes = yield* Effect.tryPromise({\n try: () => readAppliedHashesIn(db, ref),\n catch: (cause) =>\n new DatabaseError({ stage: \"migration\", migrationTag: \"read-applied\", cause }),\n }).pipe(Effect.orElseSucceed(() => new Set<string>()));\n const appliedCount = appliedHashes.size;\n\n if (expectedTables.length === 0) {\n return {\n status: \"empty\",\n expectedTables: [],\n missingTables: [],\n appliedHashes: appliedCount,\n localHashes: migrations.length,\n storage,\n };\n }\n\n const existing = yield* Effect.tryPromise({\n try: () => existingTablesIn(db, expectedTables, schemaName),\n catch: (cause) =>\n new DatabaseError({ stage: \"migration\", migrationTag: \"preflight-table-check\", cause }),\n }).pipe(Effect.orElseSucceed(() => new Set<string>()));\n const missingTables = expectedTables.filter((t) => !existing.has(t));\n\n if (appliedCount === 0 && missingTables.length === 0) {\n // Journal is empty but all expected tables already exist.\n return {\n status: \"untracked-existing-schema\",\n expectedTables,\n missingTables: [],\n appliedHashes: 0,\n localHashes: migrations.length,\n storage,\n };\n }\n\n if (missingTables.length === 0) {\n return {\n status: \"healthy\",\n expectedTables,\n missingTables: [],\n appliedHashes: appliedCount,\n localHashes: migrations.length,\n storage,\n };\n }\n\n if (missingTables.length === expectedTables.length) {\n return {\n status: \"drift-safe-repair\",\n expectedTables,\n missingTables,\n appliedHashes: appliedCount,\n localHashes: migrations.length,\n storage,\n };\n }\n\n return {\n status: \"drift-manual\",\n expectedTables,\n missingTables,\n appliedHashes: appliedCount,\n localHashes: migrations.length,\n storage,\n };\n });\n}\n"],"mappings":"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"}
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
import { MigrationStorage } from "./core.cjs";
|
|
2
|
+
import { DatabaseError } from "./errors.cjs";
|
|
3
|
+
import { Effect } from "effect";
|
|
4
|
+
//#region src/db/run-migrations.d.ts
|
|
5
|
+
interface Migration {
|
|
6
|
+
idx: number;
|
|
7
|
+
when: number;
|
|
8
|
+
tag: string;
|
|
9
|
+
hash: string;
|
|
10
|
+
sql: string[];
|
|
11
|
+
}
|
|
12
|
+
/**
|
|
13
|
+
* Minimal structural view of a drizzle PgDatabase — the concrete per-workspace
|
|
14
|
+
* `PgDatabase<PgQueryResultHKT, TSchema>` values satisfy this.
|
|
15
|
+
*/
|
|
16
|
+
interface MigrationDatabase {
|
|
17
|
+
execute(query: unknown): Promise<unknown>;
|
|
18
|
+
transaction<T>(fn: (tx: {
|
|
19
|
+
execute(query: unknown): Promise<unknown>;
|
|
20
|
+
}) => Promise<T>): Promise<T>;
|
|
21
|
+
}
|
|
22
|
+
interface LoadedMigrations {
|
|
23
|
+
migrations: Migration[];
|
|
24
|
+
source: "virtual" | "disk";
|
|
25
|
+
}
|
|
26
|
+
interface DriftReport {
|
|
27
|
+
status: "healthy" | "empty" | "untracked-existing-schema" | "drift-safe-repair" | "drift-manual";
|
|
28
|
+
expectedTables: string[];
|
|
29
|
+
missingTables: string[];
|
|
30
|
+
appliedHashes: number;
|
|
31
|
+
localHashes: number;
|
|
32
|
+
storage: MigrationStorage;
|
|
33
|
+
}
|
|
34
|
+
interface MigrationReport {
|
|
35
|
+
applied: number;
|
|
36
|
+
total: number;
|
|
37
|
+
storage: MigrationStorage;
|
|
38
|
+
schema: string | undefined;
|
|
39
|
+
}
|
|
40
|
+
interface RunMigrationsOptions {
|
|
41
|
+
schemaName?: string;
|
|
42
|
+
journal?: MigrationStorage;
|
|
43
|
+
duplicateSqlStates?: readonly string[];
|
|
44
|
+
}
|
|
45
|
+
interface LoadMigrationsOptions {
|
|
46
|
+
/** Directory containing the workspace's drizzle `migrations/` folder for the disk fallback. */
|
|
47
|
+
fromDir?: string;
|
|
48
|
+
/**
|
|
49
|
+
* Bundler-provided virtual-module loader (e.g. `virtual:drizzle-migrations.sql`
|
|
50
|
+
* registered by rspack). Lives at the call site — the shared package must not
|
|
51
|
+
* name the virtual module, which only exists inside plugin bundles.
|
|
52
|
+
*/
|
|
53
|
+
virtual?: () => Promise<{
|
|
54
|
+
default?: Migration[];
|
|
55
|
+
}>;
|
|
56
|
+
}
|
|
57
|
+
declare function loadMigrations(opts?: LoadMigrationsOptions): Effect.Effect<LoadedMigrations, DatabaseError>;
|
|
58
|
+
/**
|
|
59
|
+
* Apply pending migrations to the target database.
|
|
60
|
+
*
|
|
61
|
+
* Namespace model: `opts.schemaName` (`plugin_<slug>`) scopes data tables; the
|
|
62
|
+
* journal lives in `opts.journal` (default the shared `drizzle.__drizzle_migrations`).
|
|
63
|
+
* Undefined `schemaName` means public-schema (api) or dedicated-DB (auth) topology.
|
|
64
|
+
*
|
|
65
|
+
* Concurrency: the run serializes on a journal-scoped Postgres advisory
|
|
66
|
+
* transaction lock, so the dev double-boot (plugin dev-server + the host's
|
|
67
|
+
* in-process load), parallel test files, and overlapping production replicas
|
|
68
|
+
* converge instead of colliding in pg_catalog. SAVEPOINT-based duplicate-DDL
|
|
69
|
+
* tolerance stays as defense-in-depth for non-participants (drizzle-kit).
|
|
70
|
+
*
|
|
71
|
+
* Reliability floor: hash-tracked idempotence with a preflight that records
|
|
72
|
+
* fully-overlapped migrations as applied, everything in one locked
|
|
73
|
+
* transaction, retried on deadlock/serialization/lock-timeout/connection
|
|
74
|
+
* states — a failed attempt rolls back cleanly and re-runs.
|
|
75
|
+
*/
|
|
76
|
+
declare function runMigrations(db: MigrationDatabase, migrations: Migration[], opts?: RunMigrationsOptions): Effect.Effect<MigrationReport, DatabaseError>;
|
|
77
|
+
/**
|
|
78
|
+
* Detect drift between the local migration set and the database journal.
|
|
79
|
+
*
|
|
80
|
+
* Pass an explicit `journal` resolved from the caller's workspace for reliable
|
|
81
|
+
* slug derivation; the default relies on `process.env.npm_package_name`, which is
|
|
82
|
+
* unreliable under bundlers and Module Federation remotes.
|
|
83
|
+
*/
|
|
84
|
+
declare function detectDrift(db: MigrationDatabase, migrations: Migration[], journal?: MigrationStorage, schemaName?: string): Effect.Effect<DriftReport, DatabaseError>;
|
|
85
|
+
//#endregion
|
|
86
|
+
export { DriftReport, LoadMigrationsOptions, LoadedMigrations, Migration, MigrationDatabase, MigrationReport, RunMigrationsOptions, detectDrift, loadMigrations, runMigrations };
|
|
87
|
+
//# sourceMappingURL=run-migrations.d.cts.map
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
import { MigrationStorage } from "./core.mjs";
|
|
2
|
+
import { DatabaseError } from "./errors.mjs";
|
|
3
|
+
import { Effect } from "effect";
|
|
4
|
+
//#region src/db/run-migrations.d.ts
|
|
5
|
+
interface Migration {
|
|
6
|
+
idx: number;
|
|
7
|
+
when: number;
|
|
8
|
+
tag: string;
|
|
9
|
+
hash: string;
|
|
10
|
+
sql: string[];
|
|
11
|
+
}
|
|
12
|
+
/**
|
|
13
|
+
* Minimal structural view of a drizzle PgDatabase — the concrete per-workspace
|
|
14
|
+
* `PgDatabase<PgQueryResultHKT, TSchema>` values satisfy this.
|
|
15
|
+
*/
|
|
16
|
+
interface MigrationDatabase {
|
|
17
|
+
execute(query: unknown): Promise<unknown>;
|
|
18
|
+
transaction<T>(fn: (tx: {
|
|
19
|
+
execute(query: unknown): Promise<unknown>;
|
|
20
|
+
}) => Promise<T>): Promise<T>;
|
|
21
|
+
}
|
|
22
|
+
interface LoadedMigrations {
|
|
23
|
+
migrations: Migration[];
|
|
24
|
+
source: "virtual" | "disk";
|
|
25
|
+
}
|
|
26
|
+
interface DriftReport {
|
|
27
|
+
status: "healthy" | "empty" | "untracked-existing-schema" | "drift-safe-repair" | "drift-manual";
|
|
28
|
+
expectedTables: string[];
|
|
29
|
+
missingTables: string[];
|
|
30
|
+
appliedHashes: number;
|
|
31
|
+
localHashes: number;
|
|
32
|
+
storage: MigrationStorage;
|
|
33
|
+
}
|
|
34
|
+
interface MigrationReport {
|
|
35
|
+
applied: number;
|
|
36
|
+
total: number;
|
|
37
|
+
storage: MigrationStorage;
|
|
38
|
+
schema: string | undefined;
|
|
39
|
+
}
|
|
40
|
+
interface RunMigrationsOptions {
|
|
41
|
+
schemaName?: string;
|
|
42
|
+
journal?: MigrationStorage;
|
|
43
|
+
duplicateSqlStates?: readonly string[];
|
|
44
|
+
}
|
|
45
|
+
interface LoadMigrationsOptions {
|
|
46
|
+
/** Directory containing the workspace's drizzle `migrations/` folder for the disk fallback. */
|
|
47
|
+
fromDir?: string;
|
|
48
|
+
/**
|
|
49
|
+
* Bundler-provided virtual-module loader (e.g. `virtual:drizzle-migrations.sql`
|
|
50
|
+
* registered by rspack). Lives at the call site — the shared package must not
|
|
51
|
+
* name the virtual module, which only exists inside plugin bundles.
|
|
52
|
+
*/
|
|
53
|
+
virtual?: () => Promise<{
|
|
54
|
+
default?: Migration[];
|
|
55
|
+
}>;
|
|
56
|
+
}
|
|
57
|
+
declare function loadMigrations(opts?: LoadMigrationsOptions): Effect.Effect<LoadedMigrations, DatabaseError>;
|
|
58
|
+
/**
|
|
59
|
+
* Apply pending migrations to the target database.
|
|
60
|
+
*
|
|
61
|
+
* Namespace model: `opts.schemaName` (`plugin_<slug>`) scopes data tables; the
|
|
62
|
+
* journal lives in `opts.journal` (default the shared `drizzle.__drizzle_migrations`).
|
|
63
|
+
* Undefined `schemaName` means public-schema (api) or dedicated-DB (auth) topology.
|
|
64
|
+
*
|
|
65
|
+
* Concurrency: the run serializes on a journal-scoped Postgres advisory
|
|
66
|
+
* transaction lock, so the dev double-boot (plugin dev-server + the host's
|
|
67
|
+
* in-process load), parallel test files, and overlapping production replicas
|
|
68
|
+
* converge instead of colliding in pg_catalog. SAVEPOINT-based duplicate-DDL
|
|
69
|
+
* tolerance stays as defense-in-depth for non-participants (drizzle-kit).
|
|
70
|
+
*
|
|
71
|
+
* Reliability floor: hash-tracked idempotence with a preflight that records
|
|
72
|
+
* fully-overlapped migrations as applied, everything in one locked
|
|
73
|
+
* transaction, retried on deadlock/serialization/lock-timeout/connection
|
|
74
|
+
* states — a failed attempt rolls back cleanly and re-runs.
|
|
75
|
+
*/
|
|
76
|
+
declare function runMigrations(db: MigrationDatabase, migrations: Migration[], opts?: RunMigrationsOptions): Effect.Effect<MigrationReport, DatabaseError>;
|
|
77
|
+
/**
|
|
78
|
+
* Detect drift between the local migration set and the database journal.
|
|
79
|
+
*
|
|
80
|
+
* Pass an explicit `journal` resolved from the caller's workspace for reliable
|
|
81
|
+
* slug derivation; the default relies on `process.env.npm_package_name`, which is
|
|
82
|
+
* unreliable under bundlers and Module Federation remotes.
|
|
83
|
+
*/
|
|
84
|
+
declare function detectDrift(db: MigrationDatabase, migrations: Migration[], journal?: MigrationStorage, schemaName?: string): Effect.Effect<DriftReport, DatabaseError>;
|
|
85
|
+
//#endregion
|
|
86
|
+
export { DriftReport, LoadMigrationsOptions, LoadedMigrations, Migration, MigrationDatabase, MigrationReport, RunMigrationsOptions, detectDrift, loadMigrations, runMigrations };
|
|
87
|
+
//# sourceMappingURL=run-migrations.d.mts.map
|