@supatype/cli 0.1.6 → 0.1.9
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/.turbo/turbo-build.log +1 -1
- package/.turbo/turbo-test.log +152 -102
- package/.turbo/turbo-typecheck.log +1 -1
- package/LICENSE +202 -0
- package/deno.d.ts +52 -0
- package/dist/app/framework.js +1 -1
- package/dist/app/framework.js.map +1 -1
- package/dist/augmentation-generator.d.ts +22 -0
- package/dist/augmentation-generator.d.ts.map +1 -1
- package/dist/augmentation-generator.js +19 -5
- package/dist/augmentation-generator.js.map +1 -1
- package/dist/binary-cache.d.ts +42 -6
- package/dist/binary-cache.d.ts.map +1 -1
- package/dist/binary-cache.js +76 -44
- package/dist/binary-cache.js.map +1 -1
- package/dist/cache-clean.d.ts +15 -0
- package/dist/cache-clean.d.ts.map +1 -0
- package/dist/cache-clean.js +76 -0
- package/dist/cache-clean.js.map +1 -0
- package/dist/cache-pins.d.ts +51 -0
- package/dist/cache-pins.d.ts.map +1 -0
- package/dist/cache-pins.js +184 -0
- package/dist/cache-pins.js.map +1 -0
- package/dist/cli-artifacts.d.ts +32 -0
- package/dist/cli-artifacts.d.ts.map +1 -0
- package/dist/cli-artifacts.js +49 -0
- package/dist/cli-artifacts.js.map +1 -0
- package/dist/cli-install-method.d.ts +27 -0
- package/dist/cli-install-method.d.ts.map +1 -0
- package/dist/cli-install-method.js +78 -0
- package/dist/cli-install-method.js.map +1 -0
- package/dist/cli-package-version.d.ts +1 -1
- package/dist/cli-package-version.d.ts.map +1 -1
- package/dist/cli-package-version.js +6 -1
- package/dist/cli-package-version.js.map +1 -1
- package/dist/cli-standalone.d.ts +13 -4
- package/dist/cli-standalone.d.ts.map +1 -1
- package/dist/cli-standalone.js +86 -31
- package/dist/cli-standalone.js.map +1 -1
- package/dist/cli-version-embedded.d.ts +10 -0
- package/dist/cli-version-embedded.d.ts.map +1 -0
- package/dist/cli-version-embedded.js +13 -0
- package/dist/cli-version-embedded.js.map +1 -0
- package/dist/cli.d.ts.map +1 -1
- package/dist/cli.js +7 -1
- package/dist/cli.js.map +1 -1
- package/dist/cloud-credentials.d.ts +34 -0
- package/dist/cloud-credentials.d.ts.map +1 -0
- package/dist/cloud-credentials.js +139 -0
- package/dist/cloud-credentials.js.map +1 -0
- package/dist/commands/add.js +1 -1
- package/dist/commands/add.js.map +1 -1
- package/dist/commands/admin.d.ts +11 -0
- package/dist/commands/admin.d.ts.map +1 -1
- package/dist/commands/admin.js +123 -21
- package/dist/commands/admin.js.map +1 -1
- package/dist/commands/adopt.js +1 -1
- package/dist/commands/adopt.js.map +1 -1
- package/dist/commands/app.js +2 -2
- package/dist/commands/app.js.map +1 -1
- package/dist/commands/cache.d.ts +1 -1
- package/dist/commands/cache.d.ts.map +1 -1
- package/dist/commands/cache.js +69 -73
- package/dist/commands/cache.js.map +1 -1
- package/dist/commands/cloud.d.ts.map +1 -1
- package/dist/commands/cloud.js +32 -8
- package/dist/commands/cloud.js.map +1 -1
- package/dist/commands/db.d.ts +3 -2
- package/dist/commands/db.d.ts.map +1 -1
- package/dist/commands/db.js +149 -3
- package/dist/commands/db.js.map +1 -1
- package/dist/commands/deploy.d.ts +9 -9
- package/dist/commands/deploy.js +12 -12
- package/dist/commands/deploy.js.map +1 -1
- package/dist/commands/dev.d.ts +3 -3
- package/dist/commands/dev.d.ts.map +1 -1
- package/dist/commands/dev.js +63 -23
- package/dist/commands/dev.js.map +1 -1
- package/dist/commands/doctor.d.ts +28 -0
- package/dist/commands/doctor.d.ts.map +1 -1
- package/dist/commands/doctor.js +60 -3
- package/dist/commands/doctor.js.map +1 -1
- package/dist/commands/engine.d.ts +1 -1
- package/dist/commands/engine.js +1 -1
- package/dist/commands/functions.d.ts +7 -0
- package/dist/commands/functions.d.ts.map +1 -1
- package/dist/commands/functions.js +45 -11
- package/dist/commands/functions.js.map +1 -1
- package/dist/commands/generate.d.ts.map +1 -1
- package/dist/commands/generate.js +5 -1
- package/dist/commands/generate.js.map +1 -1
- package/dist/commands/hooks.d.ts +12 -0
- package/dist/commands/hooks.d.ts.map +1 -0
- package/dist/commands/hooks.js +118 -0
- package/dist/commands/hooks.js.map +1 -0
- package/dist/commands/init.d.ts.map +1 -1
- package/dist/commands/init.js +64 -30
- package/dist/commands/init.js.map +1 -1
- package/dist/commands/internal.d.ts +6 -0
- package/dist/commands/internal.d.ts.map +1 -0
- package/dist/commands/internal.js +22 -0
- package/dist/commands/internal.js.map +1 -0
- package/dist/commands/link-helpers.d.ts.map +1 -1
- package/dist/commands/link-helpers.js +8 -2
- package/dist/commands/link-helpers.js.map +1 -1
- package/dist/commands/login.d.ts +7 -0
- package/dist/commands/login.d.ts.map +1 -0
- package/dist/commands/login.js +110 -0
- package/dist/commands/login.js.map +1 -0
- package/dist/commands/logs.d.ts +1 -1
- package/dist/commands/migrate.js +5 -5
- package/dist/commands/migrate.js.map +1 -1
- package/dist/commands/pg.d.ts +1 -1
- package/dist/commands/pg.js +1 -1
- package/dist/commands/plugins.js +1 -1
- package/dist/commands/plugins.js.map +1 -1
- package/dist/commands/pull.js +2 -2
- package/dist/commands/pull.js.map +1 -1
- package/dist/commands/push.d.ts.map +1 -1
- package/dist/commands/push.js +110 -7
- package/dist/commands/push.js.map +1 -1
- package/dist/commands/self-host.d.ts +1 -1
- package/dist/commands/self-host.js +1 -1
- package/dist/commands/self-update.d.ts +3 -2
- package/dist/commands/self-update.d.ts.map +1 -1
- package/dist/commands/self-update.js +31 -16
- package/dist/commands/self-update.js.map +1 -1
- package/dist/commands/status.d.ts +1 -1
- package/dist/commands/update.d.ts +1 -1
- package/dist/commands/update.js +1 -1
- package/dist/config.d.ts +1 -1
- package/dist/config.d.ts.map +1 -1
- package/dist/config.js +19 -4
- package/dist/config.js.map +1 -1
- package/dist/db-preflight.d.ts +78 -0
- package/dist/db-preflight.d.ts.map +1 -0
- package/dist/db-preflight.js +452 -0
- package/dist/db-preflight.js.map +1 -0
- package/dist/dev-compose.d.ts +4 -4
- package/dist/dev-compose.d.ts.map +1 -1
- package/dist/dev-compose.js +143 -88
- package/dist/dev-compose.js.map +1 -1
- package/dist/dev-log-filter.d.ts +1 -1
- package/dist/dev-log-filter.d.ts.map +1 -1
- package/dist/dev-log-filter.js +1 -1
- package/dist/dev-log-filter.js.map +1 -1
- package/dist/dev-ports.d.ts +2 -2
- package/dist/dev-ports.d.ts.map +1 -1
- package/dist/dev-ports.js +2 -2
- package/dist/dev-ports.js.map +1 -1
- package/dist/dev-session.d.ts +5 -5
- package/dist/dev-session.d.ts.map +1 -1
- package/dist/dev-session.js +6 -6
- package/dist/dev-session.js.map +1 -1
- package/dist/dev-shutdown.d.ts +5 -5
- package/dist/dev-shutdown.d.ts.map +1 -1
- package/dist/dev-shutdown.js +7 -7
- package/dist/dev-shutdown.js.map +1 -1
- package/dist/dev-task-colors.d.ts +1 -1
- package/dist/dev-task-colors.d.ts.map +1 -1
- package/dist/dev-task-colors.js +1 -1
- package/dist/dev-task-colors.js.map +1 -1
- package/dist/docker-postgres.d.ts +5 -5
- package/dist/docker-postgres.d.ts.map +1 -1
- package/dist/docker-postgres.js +5 -5
- package/dist/docker-postgres.js.map +1 -1
- package/dist/docker-runtime.d.ts +2 -2
- package/dist/docker-runtime.d.ts.map +1 -1
- package/dist/docker-runtime.js +5 -5
- package/dist/docker-runtime.js.map +1 -1
- package/dist/engine-client.d.ts +1 -1
- package/dist/engine-client.js +3 -3
- package/dist/engine-client.js.map +1 -1
- package/dist/engine-push-output.js +1 -1
- package/dist/engine-push-output.js.map +1 -1
- package/dist/ensure-binary.d.ts.map +1 -1
- package/dist/ensure-binary.js +17 -0
- package/dist/ensure-binary.js.map +1 -1
- package/dist/ensure-component-binaries.js +1 -1
- package/dist/ensure-component-binaries.js.map +1 -1
- package/dist/env-file.d.ts +40 -2
- package/dist/env-file.d.ts.map +1 -1
- package/dist/env-file.js +132 -11
- package/dist/env-file.js.map +1 -1
- package/dist/field-masking-tier.d.ts +50 -0
- package/dist/field-masking-tier.d.ts.map +1 -0
- package/dist/field-masking-tier.js +91 -0
- package/dist/field-masking-tier.js.map +1 -0
- package/dist/functions-deno-types.d.ts +24 -0
- package/dist/functions-deno-types.d.ts.map +1 -0
- package/dist/functions-deno-types.js +155 -0
- package/dist/functions-deno-types.js.map +1 -0
- package/dist/functions-router-gen.js +1 -1
- package/dist/gitignore.d.ts +2 -2
- package/dist/gitignore.d.ts.map +1 -1
- package/dist/gitignore.js +3 -3
- package/dist/gitignore.js.map +1 -1
- package/dist/hook-upload.d.ts +30 -0
- package/dist/hook-upload.d.ts.map +1 -0
- package/dist/hook-upload.js +86 -0
- package/dist/hook-upload.js.map +1 -0
- package/dist/hooks-generator.d.ts +8 -0
- package/dist/hooks-generator.d.ts.map +1 -0
- package/dist/hooks-generator.js +332 -0
- package/dist/hooks-generator.js.map +1 -0
- package/dist/index.d.ts +1 -1
- package/dist/index.js +1 -1
- package/dist/init-project-detect.d.ts +1 -1
- package/dist/init-project-detect.d.ts.map +1 -1
- package/dist/init-project-detect.js +1 -1
- package/dist/init-project-detect.js.map +1 -1
- package/dist/link.d.ts +4 -0
- package/dist/link.d.ts.map +1 -1
- package/dist/link.js +2 -0
- package/dist/link.js.map +1 -1
- package/dist/local-secrets.d.ts +71 -0
- package/dist/local-secrets.d.ts.map +1 -0
- package/dist/local-secrets.js +100 -0
- package/dist/local-secrets.js.map +1 -0
- package/dist/main.d.ts +2 -0
- package/dist/main.d.ts.map +1 -0
- package/dist/main.js +20 -0
- package/dist/main.js.map +1 -0
- package/dist/model-hooks.d.ts +73 -0
- package/dist/model-hooks.d.ts.map +1 -0
- package/dist/model-hooks.js +211 -0
- package/dist/model-hooks.js.map +1 -0
- package/dist/pgbouncer-userlist.d.ts +1 -1
- package/dist/pgbouncer-userlist.d.ts.map +1 -1
- package/dist/pgbouncer-userlist.js +2 -2
- package/dist/pgbouncer-userlist.js.map +1 -1
- package/dist/postgres-ctl.d.ts +12 -1
- package/dist/postgres-ctl.d.ts.map +1 -1
- package/dist/postgres-ctl.js +28 -5
- package/dist/postgres-ctl.js.map +1 -1
- package/dist/process-manager.d.ts +2 -2
- package/dist/process-manager.d.ts.map +1 -1
- package/dist/process-manager.js +4 -4
- package/dist/process-manager.js.map +1 -1
- package/dist/project-config.d.ts +122 -2
- package/dist/project-config.d.ts.map +1 -1
- package/dist/project-config.js +150 -1
- package/dist/project-config.js.map +1 -1
- package/dist/pull-utils.d.ts +2 -2
- package/dist/pull-utils.d.ts.map +1 -1
- package/dist/pull-utils.js +4 -4
- package/dist/pull-utils.js.map +1 -1
- package/dist/realtime-launch.js +1 -1
- package/dist/realtime-launch.js.map +1 -1
- package/dist/release-pins.d.ts +1 -1
- package/dist/release-pins.js +2 -2
- package/dist/release-pins.js.map +1 -1
- package/dist/resolve-api-url.js +1 -1
- package/dist/resolve-api-url.js.map +1 -1
- package/dist/resolve-target.d.ts +4 -0
- package/dist/resolve-target.d.ts.map +1 -1
- package/dist/resolve-target.js +69 -73
- package/dist/resolve-target.js.map +1 -1
- package/dist/rest-cache-admin.js +2 -2
- package/dist/rest-cache-admin.js.map +1 -1
- package/dist/runtime-routes.d.ts +1 -1
- package/dist/runtime-routes.js +1 -1
- package/dist/schema-ast-v2.d.ts +5 -4
- package/dist/schema-ast-v2.d.ts.map +1 -1
- package/dist/schema-ast-v2.js +5 -3
- package/dist/schema-ast-v2.js.map +1 -1
- package/dist/schema-push-lock.d.ts.map +1 -1
- package/dist/schema-push-lock.js +43 -16
- package/dist/schema-push-lock.js.map +1 -1
- package/dist/scripts/postinstall.d.ts +1 -1
- package/dist/scripts/postinstall.js +1 -1
- package/dist/self-host-compose.d.ts +26 -2
- package/dist/self-host-compose.d.ts.map +1 -1
- package/dist/self-host-compose.js +305 -73
- package/dist/self-host-compose.js.map +1 -1
- package/dist/service-role-check.d.ts +21 -0
- package/dist/service-role-check.d.ts.map +1 -0
- package/dist/service-role-check.js +85 -0
- package/dist/service-role-check.js.map +1 -0
- package/dist/storage-provision.d.ts +1 -1
- package/dist/storage-provision.js +3 -3
- package/dist/storage-provision.js.map +1 -1
- package/dist/studio-dev-server.d.ts +1 -1
- package/dist/studio-dev-server.d.ts.map +1 -1
- package/dist/systemd.d.ts +1 -1
- package/dist/systemd.js +1 -1
- package/dist/target-client.d.ts +17 -0
- package/dist/target-client.d.ts.map +1 -1
- package/dist/target-client.js +69 -17
- package/dist/target-client.js.map +1 -1
- package/dist/tsx-runner.js +1 -1
- package/dist/tsx-runner.js.map +1 -1
- package/dist/type-extractor.d.ts.map +1 -1
- package/dist/type-extractor.js +738 -34
- package/dist/type-extractor.js.map +1 -1
- package/dist/type-resolver.js +1 -1
- package/dist/type-resolver.js.map +1 -1
- package/dist/ui/brand.d.ts +1 -1
- package/dist/ui/brand.js +1 -1
- package/dist/ui/components/LogoWordmark.d.ts +1 -1
- package/dist/ui/components/LogoWordmark.d.ts.map +1 -1
- package/dist/ui/components/LogoWordmark.js +1 -1
- package/dist/ui/components/LogoWordmark.js.map +1 -1
- package/dist/ui/components/SelectField.js +1 -1
- package/dist/ui/components/SelectField.js.map +1 -1
- package/dist/ui/confirm.d.ts +1 -1
- package/dist/ui/confirm.js +1 -1
- package/dist/ui/fatal.d.ts +1 -1
- package/dist/ui/fatal.d.ts.map +1 -1
- package/dist/ui/fatal.js +1 -1
- package/dist/ui/fatal.js.map +1 -1
- package/dist/ui/flows/prompt-fields.js +1 -1
- package/dist/ui/flows/prompt-fields.js.map +1 -1
- package/dist/ui/interactive.d.ts +1 -1
- package/dist/ui/interactive.d.ts.map +1 -1
- package/dist/ui/interactive.js +1 -1
- package/dist/ui/interactive.js.map +1 -1
- package/dist/ui/progress.d.ts +1 -1
- package/dist/ui/progress.js +1 -1
- package/dist/ui/runtime/command-chrome.js +2 -2
- package/dist/ui/runtime/command-chrome.js.map +1 -1
- package/dist/ui/runtime/run-clack-flow.js +1 -1
- package/dist/ui/runtime/run-clack-flow.js.map +1 -1
- package/dist/ui/runtime/stdin-after-ink.d.ts.map +1 -1
- package/dist/ui/runtime/stdin-after-ink.js +4 -2
- package/dist/ui/runtime/stdin-after-ink.js.map +1 -1
- package/dist/ui/theme.d.ts +1 -1
- package/dist/ui/theme.js +1 -1
- package/dist/valkey-sidecar.d.ts +1 -1
- package/dist/valkey-sidecar.d.ts.map +1 -1
- package/dist/valkey-sidecar.js +2 -2
- package/dist/valkey-sidecar.js.map +1 -1
- package/package.json +6 -2
- package/scripts/build-release-artifacts.sh +112 -0
- package/scripts/generate-homebrew-formula.mjs +123 -0
- package/scripts/mirror-deno-release.sh +1 -1
- package/src/TYPE-RESOLUTION.md +31 -31
- package/src/app/framework.ts +1 -1
- package/src/augmentation-generator.ts +19 -6
- package/src/binary-cache.ts +94 -47
- package/src/cache-clean.ts +81 -0
- package/src/cache-pins.ts +243 -0
- package/src/cli-artifacts.ts +65 -0
- package/src/cli-install-method.ts +87 -0
- package/src/cli-package-version.ts +5 -1
- package/src/cli-standalone.ts +116 -34
- package/src/cli-version-embedded.ts +12 -0
- package/src/cli.ts +7 -1
- package/src/cloud-credentials.ts +183 -0
- package/src/commands/add.ts +1 -1
- package/src/commands/admin.ts +142 -27
- package/src/commands/adopt.ts +1 -1
- package/src/commands/app.ts +2 -2
- package/src/commands/cache.ts +92 -77
- package/src/commands/cloud.ts +32 -8
- package/src/commands/db.ts +164 -3
- package/src/commands/deploy.ts +12 -12
- package/src/commands/dev.ts +72 -23
- package/src/commands/doctor.ts +69 -3
- package/src/commands/engine.ts +1 -1
- package/src/commands/functions.ts +47 -10
- package/src/commands/generate.ts +5 -1
- package/src/commands/hooks.ts +138 -0
- package/src/commands/init.ts +65 -31
- package/src/commands/internal.ts +23 -0
- package/src/commands/link-helpers.ts +9 -2
- package/src/commands/login.ts +127 -0
- package/src/commands/logs.ts +1 -1
- package/src/commands/migrate.ts +5 -5
- package/src/commands/pg.ts +1 -1
- package/src/commands/plugins.ts +1 -1
- package/src/commands/pull.ts +2 -2
- package/src/commands/push.ts +124 -7
- package/src/commands/self-host.ts +1 -1
- package/src/commands/self-update.ts +41 -19
- package/src/commands/status.ts +1 -1
- package/src/commands/update.ts +1 -1
- package/src/config.ts +23 -4
- package/src/db-preflight.ts +575 -0
- package/src/dev-compose.ts +158 -89
- package/src/dev-log-filter.ts +1 -1
- package/src/dev-ports.ts +3 -3
- package/src/dev-session.ts +6 -6
- package/src/dev-shutdown.ts +8 -8
- package/src/dev-task-colors.ts +1 -1
- package/src/docker-postgres.ts +6 -6
- package/src/docker-runtime.ts +5 -5
- package/src/engine-client.ts +3 -3
- package/src/engine-push-output.ts +1 -1
- package/src/ensure-binary.ts +20 -0
- package/src/ensure-component-binaries.ts +1 -1
- package/src/env-file.ts +157 -11
- package/src/field-masking-tier.ts +107 -0
- package/src/functions-deno-types.ts +188 -0
- package/src/functions-router-gen.ts +1 -1
- package/src/gitignore.ts +3 -3
- package/src/hook-upload.ts +107 -0
- package/src/hooks-generator.ts +352 -0
- package/src/index.ts +1 -1
- package/src/init-project-detect.ts +1 -1
- package/src/link.ts +7 -0
- package/src/local-secrets.ts +104 -0
- package/src/main.ts +20 -0
- package/src/model-hooks.ts +260 -0
- package/src/pgbouncer-userlist.ts +2 -2
- package/src/postgres-ctl.ts +32 -5
- package/src/process-manager.ts +4 -4
- package/src/project-config.ts +237 -3
- package/src/pull-utils.ts +4 -4
- package/src/realtime-launch.ts +1 -1
- package/src/release-pins.ts +2 -2
- package/src/resolve-api-url.ts +1 -1
- package/src/resolve-target.ts +113 -68
- package/src/rest-cache-admin.ts +2 -2
- package/src/runtime-routes.ts +2 -2
- package/src/schema-ast-v2.ts +8 -5
- package/src/schema-push-lock.ts +56 -17
- package/src/scripts/postinstall.ts +1 -1
- package/src/self-host-compose.ts +348 -72
- package/src/service-role-check.ts +111 -0
- package/src/storage-provision.ts +3 -3
- package/src/studio-dev-server.ts +1 -1
- package/src/systemd.ts +1 -1
- package/src/target-client.ts +105 -18
- package/src/tsx-runner.ts +1 -1
- package/src/type-extractor.ts +885 -30
- package/src/type-resolver.ts +1 -1
- package/src/ui/README.md +1 -1
- package/src/ui/brand.ts +1 -1
- package/src/ui/components/LogoWordmark.tsx +1 -1
- package/src/ui/components/SelectField.tsx +1 -1
- package/src/ui/confirm.ts +1 -1
- package/src/ui/fatal.ts +1 -1
- package/src/ui/flows/prompt-fields.tsx +1 -1
- package/src/ui/interactive.ts +1 -1
- package/src/ui/progress.ts +1 -1
- package/src/ui/runtime/command-chrome.ts +2 -2
- package/src/ui/runtime/run-clack-flow.tsx +1 -1
- package/src/ui/runtime/stdin-after-ink.ts +4 -2
- package/src/ui/theme.ts +1 -1
- package/src/valkey-sidecar.ts +2 -2
- package/tests/access-composition.test.ts +667 -0
- package/tests/admin-studio-membership.test.ts +121 -0
- package/tests/api-schemas.test.ts +83 -0
- package/tests/archive-name-alias.test.ts +42 -0
- package/tests/augmentation-generator.test.ts +28 -0
- package/tests/cache-clean.test.ts +206 -0
- package/tests/cli-help.test.ts +11 -2
- package/tests/cli-install-method.test.ts +66 -0
- package/tests/command-chrome-coverage.test.ts +31 -26
- package/tests/command-chrome-wrap.test.ts +1 -0
- package/tests/db-preflight.test.ts +72 -0
- package/tests/doctor-render.test.ts +62 -0
- package/tests/doctor-service-role.test.ts +55 -0
- package/tests/engine-push-output.test.ts +1 -1
- package/tests/env-file.test.ts +121 -0
- package/tests/external-database-compose.test.ts +184 -0
- package/tests/external-database-config.test.ts +154 -0
- package/tests/field-masking-tier.test.ts +184 -0
- package/tests/functions-deno-types.test.ts +197 -0
- package/tests/homebrew-formula.test.ts +100 -0
- package/tests/hook-upload.test.ts +125 -0
- package/tests/hooks-generator.test.ts +212 -0
- package/tests/init.test.ts +5 -2
- package/tests/keys.test.ts +8 -2
- package/tests/local-secrets.test.ts +92 -0
- package/tests/model-hooks.test.ts +322 -0
- package/tests/runtime-contract.test.ts +113 -1
- package/tests/service-role-check.test.ts +109 -0
- package/tests/service-role-routes.test.ts +51 -0
- package/tests/storage-provision.test.ts +1 -1
- package/tests/target-client-refresh.test.ts +94 -0
- package/tests/type-extractor.test.ts +187 -0
- package/tsconfig.tsbuildinfo +1 -1
- package/vitest.config.ts +7 -1
- package/scripts/build-release-bundle.mjs +0 -27
- package/tests/engine-distribution.test.ts +0 -418
package/src/dev-compose.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* `supatype dev` when `provider: docker
|
|
2
|
+
* `supatype dev` when `provider: docker`, full self-host Compose stack (Kong gateway).
|
|
3
3
|
*/
|
|
4
4
|
|
|
5
5
|
import { existsSync, mkdirSync, writeFileSync } from "node:fs"
|
|
@@ -15,6 +15,7 @@ import {
|
|
|
15
15
|
projectRootFromConfig,
|
|
16
16
|
resolveRuntimeProvider,
|
|
17
17
|
schemaPathFromProject,
|
|
18
|
+
usesExternalDatabase,
|
|
18
19
|
type SupatypeProjectConfig,
|
|
19
20
|
} from "./project-config.js"
|
|
20
21
|
import { signJwt } from "./jwt.js"
|
|
@@ -40,6 +41,12 @@ import { ensureLocalServerDockerImage } from "./compose-local-server-image.js"
|
|
|
40
41
|
import { ensureEngine, engineRequest, type DiffResult } from "./engine-client.js"
|
|
41
42
|
import { writeSchemaSourcePushArtifacts, type SchemaSourcePushArtifacts } from "./schema-sources.js"
|
|
42
43
|
import { readEnvValue, upsertEnvFile } from "./env-file.js"
|
|
44
|
+
import {
|
|
45
|
+
devJwtSecret,
|
|
46
|
+
devPostgresPassword,
|
|
47
|
+
seedMissingDatabaseIdentity,
|
|
48
|
+
seedMissingLocalSecrets,
|
|
49
|
+
} from "./local-secrets.js"
|
|
43
50
|
import { writeLocalEnvironment } from "./link.js"
|
|
44
51
|
import { registerDevShutdown } from "./dev-shutdown.js"
|
|
45
52
|
import {
|
|
@@ -55,16 +62,19 @@ import type { ExtractedSchemaAstV2 } from "./schema-ast-v2.js"
|
|
|
55
62
|
import { ensureFirstAdminUserForProject } from "./commands/admin.js"
|
|
56
63
|
import { publishDevReady } from "./dev-ready-panel.js"
|
|
57
64
|
|
|
58
|
-
const LOCAL_JWT_SECRET = "super-secret-jwt-token-with-at-least-32-characters-long"
|
|
59
|
-
|
|
60
65
|
/** Default host port for compose Postgres when `overrides.engine` is set (devLocal). */
|
|
61
66
|
const COMPOSE_DEV_DB_PORT = 54329
|
|
62
67
|
|
|
63
68
|
/** Sync optional Docker image pins from config into `.env` (no JWT rotation). */
|
|
64
69
|
export function syncComposeImagePins(cwd: string, config: SupatypeProjectConfig): void {
|
|
65
70
|
const imagePins = composeDockerImageEnv(config)
|
|
71
|
+
// Clean up only what a previous run wrote from config. A hand-written image tag in `.env` is the
|
|
72
|
+
// documented way to run a local build, and this used to delete it on every compose run.
|
|
66
73
|
const removeImageKeys = COMPOSE_PINNED_IMAGE_ENV_KEYS.filter((key) => !(key in imagePins))
|
|
67
|
-
upsertEnvFile(cwd, imagePins,
|
|
74
|
+
upsertEnvFile(cwd, imagePins, {
|
|
75
|
+
removeManaged: removeImageKeys,
|
|
76
|
+
managed: COMPOSE_PINNED_IMAGE_ENV_KEYS,
|
|
77
|
+
})
|
|
68
78
|
}
|
|
69
79
|
|
|
70
80
|
export interface DevComposeOptions {
|
|
@@ -72,8 +82,10 @@ export interface DevComposeOptions {
|
|
|
72
82
|
}
|
|
73
83
|
|
|
74
84
|
/** In-compose Postgres URL (SCRAM; not published to the host). */
|
|
75
|
-
export function composeDbUrl(): string {
|
|
76
|
-
|
|
85
|
+
export function composeDbUrl(cwd: string): string {
|
|
86
|
+
const user = readEnvValue(cwd, "POSTGRES_USER", "supatype_admin")
|
|
87
|
+
const db = readEnvValue(cwd, "POSTGRES_DB", "supatype")
|
|
88
|
+
return `postgresql://${user}:${devPostgresPassword(cwd)}@db:5432/${db}?sslmode=disable`
|
|
77
89
|
}
|
|
78
90
|
|
|
79
91
|
/**
|
|
@@ -84,10 +96,23 @@ async function resolveDevDbPort(cwd: string): Promise<number> {
|
|
|
84
96
|
return ensureDevDbPort(cwd)
|
|
85
97
|
}
|
|
86
98
|
|
|
99
|
+
/**
|
|
100
|
+
* The database URL to hand a tool, from wherever it happens to run.
|
|
101
|
+
*
|
|
102
|
+
* The compose helpers below describe the `db` *container*, on the host at
|
|
103
|
+
* `SUPATYPE_DEV_DB_PORT`, or in-network at `db:5432`. Neither exists for a project pointed at an
|
|
104
|
+
* external database, and passing one produced "pool timed out while waiting for an open connection"
|
|
105
|
+
*- a message with nothing in it about the URL being wrong.
|
|
106
|
+
*/
|
|
107
|
+
function projectDatabaseUrl(cwd: string, config: SupatypeProjectConfig, inNetwork = false): string {
|
|
108
|
+
if (usesExternalDatabase(config)) return connectionString(config)
|
|
109
|
+
return inNetwork ? composeDbUrl(cwd) : hostComposeDbUrl(cwd)
|
|
110
|
+
}
|
|
111
|
+
|
|
87
112
|
function hostComposeDbUrl(cwd: string): string {
|
|
88
113
|
const port = readEnvValue(cwd, "SUPATYPE_DEV_DB_PORT", String(COMPOSE_DEV_DB_PORT))
|
|
89
114
|
const user = readEnvValue(cwd, "POSTGRES_USER", "supatype_admin")
|
|
90
|
-
const pass =
|
|
115
|
+
const pass = devPostgresPassword(cwd)
|
|
91
116
|
const db = readEnvValue(cwd, "POSTGRES_DB", "supatype")
|
|
92
117
|
return `postgresql://${user}:${pass}@127.0.0.1:${port}/${db}?sslmode=disable`
|
|
93
118
|
}
|
|
@@ -117,19 +142,12 @@ export async function ensureDockerDbPublishedForHostEngine(
|
|
|
117
142
|
|
|
118
143
|
const now = Math.floor(Date.now() / 1000)
|
|
119
144
|
const jwtBase = { iss: "supatype", iat: now, exp: now + 315_360_000 }
|
|
120
|
-
const anonKey = signJwt({ ...jwtBase, role: "anon" },
|
|
121
|
-
const serviceRoleKey = signJwt({ ...jwtBase, role: "service_role" },
|
|
145
|
+
const anonKey = signJwt({ ...jwtBase, role: "anon" }, devJwtSecret(cwd))
|
|
146
|
+
const serviceRoleKey = signJwt({ ...jwtBase, role: "service_role" }, devJwtSecret(cwd))
|
|
122
147
|
ensureDevComposeEnv(cwd, config, anonKey, serviceRoleKey, kongPort, devDbPort)
|
|
123
148
|
|
|
124
149
|
const paths = writeSelfHostCompose(cwd, config, { devLocal: true })
|
|
125
|
-
|
|
126
|
-
quiet: true,
|
|
127
|
-
...(brand !== undefined && { brand }),
|
|
128
|
-
})
|
|
129
|
-
if (up !== 0) {
|
|
130
|
-
exitComposeFailed(up, "Could not start Postgres (compose db service).", brand)
|
|
131
|
-
}
|
|
132
|
-
await waitComposeHealthy(paths, cwd, 120_000, project)
|
|
150
|
+
await startComposeDatabase(config, paths, cwd, project, brand)
|
|
133
151
|
}
|
|
134
152
|
|
|
135
153
|
/**
|
|
@@ -142,6 +160,9 @@ export function usesLocalDockerEngineDb(
|
|
|
142
160
|
): boolean {
|
|
143
161
|
if (explicitConnection?.trim()) return false
|
|
144
162
|
if (config.connection?.trim()) return false
|
|
163
|
+
// An external database is already reachable and is not ours to publish. Without this the engine
|
|
164
|
+
// path tried `compose up -d db` against a compose file that deliberately has no `db` service.
|
|
165
|
+
if (usesExternalDatabase(config)) return false
|
|
145
166
|
return resolveRuntimeProvider(config) === "docker" && hasEngineOverride(config)
|
|
146
167
|
}
|
|
147
168
|
|
|
@@ -168,6 +189,36 @@ async function resolveKongPort(cwd: string): Promise<number> {
|
|
|
168
189
|
return ensureKongPort(cwd, { context: "dev" })
|
|
169
190
|
}
|
|
170
191
|
|
|
192
|
+
/**
|
|
193
|
+
* Bring up the compose `db` service and wait for it to answer.
|
|
194
|
+
*
|
|
195
|
+
* A no-op when the project uses an external database: there is no such service, the database is
|
|
196
|
+
* already running, and its readiness is the operator's, `supatype db check` is what reports on it.
|
|
197
|
+
* Four call sites did this inline, so an external project hit `compose up -d db` against a compose
|
|
198
|
+
* file that deliberately has no `db`.
|
|
199
|
+
*/
|
|
200
|
+
async function startComposeDatabase(
|
|
201
|
+
config: SupatypeProjectConfig,
|
|
202
|
+
paths: SelfHostComposePaths,
|
|
203
|
+
cwd: string,
|
|
204
|
+
project: string,
|
|
205
|
+
brand: DockerBrandOptions | undefined,
|
|
206
|
+
timeoutMs = 120_000,
|
|
207
|
+
onFailure?: () => void,
|
|
208
|
+
): Promise<void> {
|
|
209
|
+
if (usesExternalDatabase(config)) return
|
|
210
|
+
|
|
211
|
+
const up = runDockerCompose(paths.composePath, ["up", "-d", "db"], cwd, project, {
|
|
212
|
+
quiet: true,
|
|
213
|
+
...(brand !== undefined && { brand }),
|
|
214
|
+
})
|
|
215
|
+
if (up !== 0) {
|
|
216
|
+
onFailure?.()
|
|
217
|
+
exitComposeFailed(up, "Could not start Postgres (compose db service).", brand)
|
|
218
|
+
}
|
|
219
|
+
await waitComposeHealthy(paths, cwd, timeoutMs, project)
|
|
220
|
+
}
|
|
221
|
+
|
|
171
222
|
function upsertDevComposeEnv(
|
|
172
223
|
cwd: string,
|
|
173
224
|
config: SupatypeProjectConfig,
|
|
@@ -179,11 +230,25 @@ function upsertDevComposeEnv(
|
|
|
179
230
|
): void {
|
|
180
231
|
const apiUrl = `http://localhost:${kongPort}`
|
|
181
232
|
const imagePins = composeDockerImageEnv(config)
|
|
233
|
+
// `POSTGRES_PASSWORD` and `JWT_SECRET` are deliberately absent.
|
|
234
|
+
//
|
|
235
|
+
// They used to be pinned here to published constants on every `dev` run, against the same
|
|
236
|
+
// `.env` a self-host deployment reads, so a project could not hold its own secrets, and one
|
|
237
|
+
// `dev` after generating them put the published values back with nothing to show it. They are
|
|
238
|
+
// now resolved from `.env` (see `local-secrets.ts`) and written by `init` alone.
|
|
239
|
+
//
|
|
240
|
+
// The keys below still have to be written, because they are *derived*: the anon and
|
|
241
|
+
// service-role tokens are signed with the effective secret, so leaving a stale pair in place
|
|
242
|
+
// would desync them from the secret that validates them.
|
|
182
243
|
const updates: Record<string, string> = {
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
244
|
+
// The docker dev path renders the *self-host* compose file, where the secrets have no
|
|
245
|
+
// defaults: an unset value is a hard compose error rather than a service quietly starting
|
|
246
|
+
// with a published constant. This guarantees presence without overwriting: only keys
|
|
247
|
+
// genuinely absent from `.env` are filled, and with the value the project has been running
|
|
248
|
+
// with rather than a fresh one.
|
|
249
|
+
...seedMissingLocalSecrets(cwd),
|
|
250
|
+
// Project configuration, seeded not overwritten, see seedMissingDatabaseIdentity.
|
|
251
|
+
...seedMissingDatabaseIdentity(cwd),
|
|
187
252
|
ANON_KEY: anonKey,
|
|
188
253
|
SERVICE_ROLE_KEY: serviceRoleKey,
|
|
189
254
|
PUBLIC_SUPATYPE_ANON_KEY: anonKey,
|
|
@@ -198,13 +263,26 @@ function upsertDevComposeEnv(
|
|
|
198
263
|
...imagePins,
|
|
199
264
|
...(localServerImage !== undefined && { SUPATYPE_SERVER_IMAGE: localServerImage }),
|
|
200
265
|
}
|
|
201
|
-
|
|
266
|
+
// Never for an external database: this URL describes the `db` container, which that project does
|
|
267
|
+
// not have. Writing it overwrote the operator's own DATABASE_URL, the value the whole stack and
|
|
268
|
+
// every CLI command reads, with a DSN pointing at a database that does not exist. Found by
|
|
269
|
+
// rehearsing a push against a real external Postgres, where the compose guard then refused to
|
|
270
|
+
// proceed because .env and the config disagreed. They disagreed because of this line.
|
|
271
|
+
if (devDbPort !== undefined && !usesExternalDatabase(config)) {
|
|
202
272
|
updates.SUPATYPE_DEV_DB_PORT = String(devDbPort)
|
|
273
|
+
// User and database from the project, not hardcoded, same reason as
|
|
274
|
+
// `seedMissingDatabaseIdentity`: a project not named "supatype" had this URL pointing at a
|
|
275
|
+
// database that does not exist.
|
|
276
|
+
const dbUser = readEnvValue(cwd, "POSTGRES_USER", "supatype_admin")
|
|
277
|
+
const dbName = readEnvValue(cwd, "POSTGRES_DB", "supatype")
|
|
203
278
|
updates.DATABASE_URL =
|
|
204
|
-
`postgresql
|
|
279
|
+
`postgresql://${dbUser}:${devPostgresPassword(cwd)}@localhost:${devDbPort}/${dbName}?sslmode=disable`
|
|
205
280
|
}
|
|
206
281
|
const removeImageKeys = COMPOSE_PINNED_IMAGE_ENV_KEYS.filter((key) => !(key in imagePins))
|
|
207
|
-
upsertEnvFile(cwd, updates,
|
|
282
|
+
upsertEnvFile(cwd, updates, {
|
|
283
|
+
removeManaged: removeImageKeys,
|
|
284
|
+
managed: COMPOSE_PINNED_IMAGE_ENV_KEYS,
|
|
285
|
+
})
|
|
208
286
|
}
|
|
209
287
|
|
|
210
288
|
/** Keep compose + Studio on the same freshly signed dev JWTs; sync optional image pins from config. */
|
|
@@ -280,7 +358,7 @@ function dumpComposeDbLogs(
|
|
|
280
358
|
maxBuffer: 10 * 1024 * 1024,
|
|
281
359
|
})
|
|
282
360
|
const body = `${result.stdout ?? ""}${result.stderr ?? ""}`.trim()
|
|
283
|
-
const content = body || `(empty
|
|
361
|
+
const content = body || `(empty, docker compose logs db exit ${result.status ?? "?"})\n`
|
|
284
362
|
try {
|
|
285
363
|
writeFileSync(logPath, content)
|
|
286
364
|
} catch {
|
|
@@ -325,7 +403,7 @@ async function waitStorageApiReady(
|
|
|
325
403
|
const body = await res.text()
|
|
326
404
|
const kongUpstreamDown = body.includes("invalid response was received from the upstream server")
|
|
327
405
|
if (!kongUpstreamDown && res.status !== 503) {
|
|
328
|
-
// Non-transient storage response (e.g. 401)
|
|
406
|
+
// Non-transient storage response (e.g. 401), stop waiting.
|
|
329
407
|
return
|
|
330
408
|
}
|
|
331
409
|
} catch {
|
|
@@ -334,7 +412,7 @@ async function waitStorageApiReady(
|
|
|
334
412
|
await new Promise((r) => setTimeout(r, 1000))
|
|
335
413
|
}
|
|
336
414
|
console.warn(
|
|
337
|
-
`[supatype] Storage API at ${url} did not become ready within ${maxSec}s
|
|
415
|
+
`[supatype] Storage API at ${url} did not become ready within ${maxSec}s, bucket provisioning may fail.`,
|
|
338
416
|
)
|
|
339
417
|
}
|
|
340
418
|
|
|
@@ -367,7 +445,7 @@ async function refreshSchemaArtifacts(
|
|
|
367
445
|
await ensureEngine()
|
|
368
446
|
} catch (err) {
|
|
369
447
|
console.warn(
|
|
370
|
-
`[supatype] Host engine unavailable
|
|
448
|
+
`[supatype] Host engine unavailable, admin/types not refreshed: ${(err as Error).message}`,
|
|
371
449
|
)
|
|
372
450
|
return
|
|
373
451
|
}
|
|
@@ -402,7 +480,7 @@ async function refreshSchemaArtifacts(
|
|
|
402
480
|
console.log("[supatype] Admin config written to .supatype/admin-config.json")
|
|
403
481
|
} catch (err) {
|
|
404
482
|
console.warn(
|
|
405
|
-
`[supatype] Admin config generation failed
|
|
483
|
+
`[supatype] Admin config generation failed, Studio may show stale field widgets: ${(err as Error).message}`,
|
|
406
484
|
)
|
|
407
485
|
}
|
|
408
486
|
}
|
|
@@ -420,7 +498,7 @@ async function runComposeSchemaPush(
|
|
|
420
498
|
const supatypeDir = join(cwd, ".supatype")
|
|
421
499
|
mkdirSync(supatypeDir, { recursive: true })
|
|
422
500
|
const astPath = join(supatypeDir, "schema.ast.json")
|
|
423
|
-
// Always materialise on disk
|
|
501
|
+
// Always materialise on disk, schema-engine reads via bind mount; skip must not omit the write.
|
|
424
502
|
writeFileSync(astPath, astJson)
|
|
425
503
|
if (astJson === _lastPushedAst && astJson !== _lastFailedAst) return
|
|
426
504
|
|
|
@@ -428,7 +506,7 @@ async function runComposeSchemaPush(
|
|
|
428
506
|
throw new Error(`Failed to write schema AST at ${astPath}`)
|
|
429
507
|
}
|
|
430
508
|
|
|
431
|
-
// Admin + types come from the AST only (no DB)
|
|
509
|
+
// Admin + types come from the AST only (no DB), refresh before push so Studio stays
|
|
432
510
|
// in sync even when migration fails (e.g. bad engine image, lossy column change).
|
|
433
511
|
await refreshSchemaArtifacts(cwd, config, ast)
|
|
434
512
|
|
|
@@ -440,7 +518,7 @@ async function runComposeSchemaPush(
|
|
|
440
518
|
try {
|
|
441
519
|
await engineRequest("/push", {
|
|
442
520
|
ast,
|
|
443
|
-
database_url:
|
|
521
|
+
database_url: projectDatabaseUrl(cwd, config),
|
|
444
522
|
schema: pgSchema,
|
|
445
523
|
force: true,
|
|
446
524
|
...(sources
|
|
@@ -474,7 +552,7 @@ async function runComposeSchemaPush(
|
|
|
474
552
|
}
|
|
475
553
|
return result
|
|
476
554
|
}
|
|
477
|
-
// B: only hold the advisory lock when realtime is already decoding
|
|
555
|
+
// B: only hold the advisory lock when realtime is already decoding, first-boot
|
|
478
556
|
// push (db only) must not take the lock; that path crashed under lock+DDL in CI.
|
|
479
557
|
const push = composeServiceIsRunning(paths, cwd, composeProject, "realtime")
|
|
480
558
|
? await withComposeSchemaPushLock(paths, cwd, composeProject, runPush)
|
|
@@ -540,7 +618,7 @@ async function runComposeEnginePush(
|
|
|
540
618
|
"-i",
|
|
541
619
|
"/project/.supatype/schema.ast.json",
|
|
542
620
|
"--database-url",
|
|
543
|
-
|
|
621
|
+
projectDatabaseUrl(cwd, config, true),
|
|
544
622
|
"--force",
|
|
545
623
|
"--non-interactive",
|
|
546
624
|
)
|
|
@@ -606,7 +684,7 @@ async function runComposeEngineDiff(
|
|
|
606
684
|
"-i",
|
|
607
685
|
"/project/.supatype/schema.ast.json",
|
|
608
686
|
"--database-url",
|
|
609
|
-
|
|
687
|
+
projectDatabaseUrl(cwd, config, true),
|
|
610
688
|
"--schema",
|
|
611
689
|
pgSchema,
|
|
612
690
|
)
|
|
@@ -633,7 +711,7 @@ async function runComposeEngineDiff(
|
|
|
633
711
|
|
|
634
712
|
/**
|
|
635
713
|
* `supatype diff` when `provider: docker`. Uses in-compose schema-engine unless
|
|
636
|
-
* `overrides.engine` is set
|
|
714
|
+
* `overrides.engine` is set: then Postgres is published to the host and diff runs
|
|
637
715
|
* through the local engine binary.
|
|
638
716
|
*/
|
|
639
717
|
export async function diffSchemaDocker(cwd: string, config: SupatypeProjectConfig): Promise<DiffResult> {
|
|
@@ -651,7 +729,7 @@ export async function diffSchemaDocker(cwd: string, config: SupatypeProjectConfi
|
|
|
651
729
|
await ensureEngine()
|
|
652
730
|
return engineRequest<DiffResult>("/diff", {
|
|
653
731
|
ast,
|
|
654
|
-
database_url:
|
|
732
|
+
database_url: projectDatabaseUrl(cwd, config),
|
|
655
733
|
schema: pgSchema,
|
|
656
734
|
})
|
|
657
735
|
}
|
|
@@ -659,21 +737,14 @@ export async function diffSchemaDocker(cwd: string, config: SupatypeProjectConfi
|
|
|
659
737
|
const kongPort = await resolveKongPort(cwd)
|
|
660
738
|
const now = Math.floor(Date.now() / 1000)
|
|
661
739
|
const jwtBase = { iss: "supatype", iat: now, exp: now + 315_360_000 }
|
|
662
|
-
const anonKey = signJwt({ ...jwtBase, role: "anon" },
|
|
663
|
-
const serviceRoleKey = signJwt({ ...jwtBase, role: "service_role" },
|
|
740
|
+
const anonKey = signJwt({ ...jwtBase, role: "anon" }, devJwtSecret(cwd))
|
|
741
|
+
const serviceRoleKey = signJwt({ ...jwtBase, role: "service_role" }, devJwtSecret(cwd))
|
|
664
742
|
ensureDevComposeEnv(cwd, config, anonKey, serviceRoleKey, kongPort, undefined)
|
|
665
743
|
|
|
666
744
|
const paths = writeSelfHostCompose(cwd, config, { devLocal: true })
|
|
667
745
|
const diffBrand = { intro: "Schema diff" }
|
|
668
746
|
|
|
669
|
-
|
|
670
|
-
quiet: true,
|
|
671
|
-
brand: diffBrand,
|
|
672
|
-
})
|
|
673
|
-
if (up !== 0) {
|
|
674
|
-
exitComposeFailed(up, "Could not start Postgres (compose db service).", diffBrand)
|
|
675
|
-
}
|
|
676
|
-
await waitComposeHealthy(paths, cwd, 120_000, project)
|
|
747
|
+
await startComposeDatabase(config, paths, cwd, project, diffBrand)
|
|
677
748
|
|
|
678
749
|
const schemaPath = schemaPathFromProject(config, cwd)
|
|
679
750
|
const ast = loadSchemaAst(schemaPath, cwd)
|
|
@@ -701,7 +772,7 @@ export async function diffSchemaDocker(cwd: string, config: SupatypeProjectConfi
|
|
|
701
772
|
|
|
702
773
|
/**
|
|
703
774
|
* `supatype push` when `provider: docker`. Uses in-compose schema-engine unless
|
|
704
|
-
* `overrides.engine` is set
|
|
775
|
+
* `overrides.engine` is set: then Postgres is published to the host and push runs
|
|
705
776
|
* through the local engine binary (AST v2, contributor builds).
|
|
706
777
|
*/
|
|
707
778
|
export async function pushSchemaDocker(cwd: string, config: SupatypeProjectConfig): Promise<void> {
|
|
@@ -710,26 +781,25 @@ export async function pushSchemaDocker(cwd: string, config: SupatypeProjectConfi
|
|
|
710
781
|
}
|
|
711
782
|
const project = composeProjectName(config.project.name)
|
|
712
783
|
const kongPort = await resolveKongPort(cwd)
|
|
713
|
-
|
|
784
|
+
// No dev db port for an external database: `ensureDevDbPort` allocates a host port for the `db`
|
|
785
|
+
// container *and persists a matching DATABASE_URL*, which overwrote the operator's own URL, the
|
|
786
|
+
// one the whole stack and every CLI command reads.
|
|
787
|
+
const devDbPort =
|
|
788
|
+
hasEngineOverride(config) && !usesExternalDatabase(config)
|
|
789
|
+
? await resolveDevDbPort(cwd)
|
|
790
|
+
: undefined
|
|
714
791
|
|
|
715
792
|
const now = Math.floor(Date.now() / 1000)
|
|
716
793
|
const jwtBase = { iss: "supatype", iat: now, exp: now + 315_360_000 }
|
|
717
|
-
const anonKey = signJwt({ ...jwtBase, role: "anon" },
|
|
718
|
-
const serviceRoleKey = signJwt({ ...jwtBase, role: "service_role" },
|
|
794
|
+
const anonKey = signJwt({ ...jwtBase, role: "anon" }, devJwtSecret(cwd))
|
|
795
|
+
const serviceRoleKey = signJwt({ ...jwtBase, role: "service_role" }, devJwtSecret(cwd))
|
|
719
796
|
ensureDevComposeEnv(cwd, config, anonKey, serviceRoleKey, kongPort, devDbPort)
|
|
720
797
|
|
|
721
798
|
const paths = writeSelfHostCompose(cwd, config, { devLocal: true })
|
|
722
799
|
const pushBrand = { intro: "Push schema" }
|
|
723
800
|
|
|
724
|
-
console.log(`[supatype] provider
|
|
725
|
-
|
|
726
|
-
quiet: true,
|
|
727
|
-
brand: pushBrand,
|
|
728
|
-
})
|
|
729
|
-
if (up !== 0) {
|
|
730
|
-
exitComposeFailed(up, "Could not start Postgres (compose db service).", pushBrand)
|
|
731
|
-
}
|
|
732
|
-
await waitComposeHealthy(paths, cwd, 120_000, project)
|
|
801
|
+
console.log(`[supatype] provider docker, applying schema via compose (project ${project})...`)
|
|
802
|
+
await startComposeDatabase(config, paths, cwd, project, pushBrand)
|
|
733
803
|
|
|
734
804
|
const schemaPath = schemaPathFromProject(config, cwd)
|
|
735
805
|
const ast = loadSchemaAst(schemaPath, cwd)
|
|
@@ -762,19 +832,25 @@ export async function runDevCompose(cwd: string, config: SupatypeProjectConfig,
|
|
|
762
832
|
// stack on the machine (own containers, volumes, network, and gateway port).
|
|
763
833
|
const project = composeProjectName(config.project.name)
|
|
764
834
|
const kongPort = await resolveKongPort(cwd)
|
|
765
|
-
|
|
835
|
+
// No dev db port for an external database: `ensureDevDbPort` allocates a host port for the `db`
|
|
836
|
+
// container *and persists a matching DATABASE_URL*, which overwrote the operator's own URL, the
|
|
837
|
+
// one the whole stack and every CLI command reads.
|
|
838
|
+
const devDbPort =
|
|
839
|
+
hasEngineOverride(config) && !usesExternalDatabase(config)
|
|
840
|
+
? await resolveDevDbPort(cwd)
|
|
841
|
+
: undefined
|
|
766
842
|
|
|
767
843
|
const now = Math.floor(Date.now() / 1000)
|
|
768
844
|
const jwtBase = { iss: "supatype", iat: now, exp: now + 315_360_000 }
|
|
769
|
-
const anonKey = signJwt({ ...jwtBase, role: "anon" },
|
|
770
|
-
const serviceRoleKey = signJwt({ ...jwtBase, role: "service_role" },
|
|
845
|
+
const anonKey = signJwt({ ...jwtBase, role: "anon" }, devJwtSecret(cwd))
|
|
846
|
+
const serviceRoleKey = signJwt({ ...jwtBase, role: "service_role" }, devJwtSecret(cwd))
|
|
771
847
|
|
|
772
848
|
const devBrand = { intro: "Local development" }
|
|
773
849
|
const localServerImage = await ensureLocalServerDockerImage(cwd, config, devBrand)
|
|
774
850
|
|
|
775
851
|
ensureDevComposeEnv(cwd, config, anonKey, serviceRoleKey, kongPort, devDbPort, localServerImage)
|
|
776
852
|
|
|
777
|
-
console.log(`[supatype] provider
|
|
853
|
+
console.log(`[supatype] provider docker, starting self-host Compose stack (project ${project}, gateway :${kongPort})...`)
|
|
778
854
|
const paths = writeSelfHostCompose(cwd, config, { devLocal: true })
|
|
779
855
|
if (ensureDevApiConfig(cwd)) {
|
|
780
856
|
console.log("[supatype] API config written to .supatype/api-config.json")
|
|
@@ -818,19 +894,11 @@ export async function runDevCompose(cwd: string, config: SupatypeProjectConfig,
|
|
|
818
894
|
await recoverStaleDevSession(cwd)
|
|
819
895
|
await handleComposeProjectRename(cwd, config.project.name, paths)
|
|
820
896
|
|
|
821
|
-
|
|
822
|
-
|
|
823
|
-
quiet: true,
|
|
824
|
-
brand: devBrand,
|
|
825
|
-
})
|
|
826
|
-
if (upDbStatus !== 0) {
|
|
827
|
-
endDevSession()
|
|
828
|
-
exitComposeFailed(upDbStatus, "Could not start Postgres (compose db service).", devBrand)
|
|
897
|
+
if (!usesExternalDatabase(config)) {
|
|
898
|
+
console.log("[supatype] Bringing up Postgres (compose db)...")
|
|
829
899
|
}
|
|
830
|
-
|
|
831
|
-
|
|
832
|
-
await waitComposeHealthy(paths, cwd, 180_000, project)
|
|
833
|
-
// Settle before DDL — pg_isready can pass slightly before the instance is stable.
|
|
900
|
+
await startComposeDatabase(config, paths, cwd, project, devBrand, 180_000, endDevSession)
|
|
901
|
+
// Settle before DDL: pg_isready can pass slightly before the instance is stable.
|
|
834
902
|
await new Promise((r) => setTimeout(r, 3000))
|
|
835
903
|
|
|
836
904
|
// A: apply schema before realtime (and the rest of the stack) starts decoding WAL.
|
|
@@ -851,16 +919,17 @@ export async function runDevCompose(cwd: string, config: SupatypeProjectConfig,
|
|
|
851
919
|
)
|
|
852
920
|
dumpComposeDbLogs(paths, cwd, project, `schema push attempt ${attempt}/${maxAttempts}`)
|
|
853
921
|
if (attempt < maxAttempts) {
|
|
854
|
-
|
|
855
|
-
|
|
856
|
-
|
|
857
|
-
|
|
858
|
-
|
|
859
|
-
|
|
860
|
-
|
|
861
|
-
|
|
862
|
-
|
|
863
|
-
|
|
922
|
+
// Only for a database Supatype created. Tearing down an external one is not ours to do,
|
|
923
|
+
// and `down -v` would destroy the stack's other volumes for a failure that was never
|
|
924
|
+
// about Postgres.
|
|
925
|
+
if (!usesExternalDatabase(config)) {
|
|
926
|
+
console.log("[supatype] Resetting Postgres after failed schema push...")
|
|
927
|
+
runDockerCompose(paths.composePath, ["down", "-v"], cwd, project, {
|
|
928
|
+
quiet: true,
|
|
929
|
+
brand: devBrand,
|
|
930
|
+
})
|
|
931
|
+
await startComposeDatabase(config, paths, cwd, project, devBrand)
|
|
932
|
+
}
|
|
864
933
|
await new Promise((r) => setTimeout(r, 3000 * attempt))
|
|
865
934
|
}
|
|
866
935
|
}
|
|
@@ -927,7 +996,7 @@ export async function runDevCompose(cwd: string, config: SupatypeProjectConfig,
|
|
|
927
996
|
writeLocalEnvironment(cwd, {
|
|
928
997
|
target: "local",
|
|
929
998
|
apiUrl: `http://localhost:${kongPort}`,
|
|
930
|
-
databaseUrl:
|
|
999
|
+
databaseUrl: projectDatabaseUrl(cwd, config, !hasEngineOverride(config)),
|
|
931
1000
|
projectRef: config.project.name,
|
|
932
1001
|
kongPort,
|
|
933
1002
|
provider: "docker",
|
|
@@ -965,7 +1034,7 @@ export async function runDevCompose(cwd: string, config: SupatypeProjectConfig,
|
|
|
965
1034
|
shutdownState.studioProc = studioProc
|
|
966
1035
|
if (studioProc) {
|
|
967
1036
|
console.log(
|
|
968
|
-
`[supatype] Studio (overrides.studio)
|
|
1037
|
+
`[supatype] Studio (overrides.studio): live reload proxied at http://localhost:${kongPort}/studio/`,
|
|
969
1038
|
)
|
|
970
1039
|
}
|
|
971
1040
|
}
|
|
@@ -1053,6 +1122,6 @@ function grantAuthSchemaAccess(
|
|
|
1053
1122
|
{ cwd: composeDir, encoding: "utf8", timeout: 10_000 },
|
|
1054
1123
|
)
|
|
1055
1124
|
if (result.status !== 0) {
|
|
1056
|
-
console.warn("[supatype] Could not grant service_role access to auth.users
|
|
1125
|
+
console.warn("[supatype] Could not grant service_role access to auth.users, Studio relation preview may fail.")
|
|
1057
1126
|
}
|
|
1058
1127
|
}
|
package/src/dev-log-filter.ts
CHANGED
|
@@ -48,7 +48,7 @@ export function filterStackLogLine(line: string): boolean {
|
|
|
48
48
|
return false
|
|
49
49
|
}
|
|
50
50
|
|
|
51
|
-
/** Drop docker noise only
|
|
51
|
+
/** Drop docker noise only, keep diff tables, push status, and command output. */
|
|
52
52
|
export function filterCommandLogLine(line: string): boolean {
|
|
53
53
|
const t = stripAnsi(line).trim()
|
|
54
54
|
if (!t) return false
|
package/src/dev-ports.ts
CHANGED
|
@@ -60,7 +60,7 @@ async function promptPortConflict(
|
|
|
60
60
|
export interface EnsureKongPortOptions {
|
|
61
61
|
/** When false, fail fast instead of prompting (CI / scripts). */
|
|
62
62
|
interactive?: boolean
|
|
63
|
-
/** init wizard
|
|
63
|
+
/** init wizard: slightly different copy */
|
|
64
64
|
context?: "dev" | "init"
|
|
65
65
|
}
|
|
66
66
|
|
|
@@ -102,7 +102,7 @@ export async function ensureKongPort(
|
|
|
102
102
|
return port
|
|
103
103
|
}
|
|
104
104
|
|
|
105
|
-
/** Wizard / init
|
|
105
|
+
/** Wizard / init: pick a Kong port without writing `.env` (scaffold writes it). */
|
|
106
106
|
export async function promptKongPortChoice(): Promise<number> {
|
|
107
107
|
const freeDefault = (await isPortInUse(COMPOSE_DEV_KONG_PORT))
|
|
108
108
|
? await findNextFreePort(COMPOSE_DEV_KONG_PORT)
|
|
@@ -139,7 +139,7 @@ async function promptPortConflictWithoutPersist(
|
|
|
139
139
|
const headline =
|
|
140
140
|
reason === "init"
|
|
141
141
|
? `Port ${blockedPort} is already in use on this machine.`
|
|
142
|
-
: `Port ${blockedPort} is in use
|
|
142
|
+
: `Port ${blockedPort} is in use, another Supatype project or service may already be bound to it.`
|
|
143
143
|
|
|
144
144
|
const choice = await p.select<"suggested" | "custom" | "cancel">({
|
|
145
145
|
message: headline,
|
package/src/dev-session.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* `supatype dev` output session
|
|
2
|
+
* `supatype dev` output session, Ink dashboard (default) or interleaved stream mode.
|
|
3
3
|
*/
|
|
4
4
|
|
|
5
5
|
import { render, type Instance } from "ink"
|
|
@@ -32,7 +32,7 @@ export function beginDevSession(mode: DevUiMode): DevSession {
|
|
|
32
32
|
return activeSession
|
|
33
33
|
}
|
|
34
34
|
|
|
35
|
-
/** @deprecated Ink starts in beginDevSession
|
|
35
|
+
/** @deprecated Ink starts in beginDevSession, kept for callers that invoke late. */
|
|
36
36
|
export function startDevSession(): void {
|
|
37
37
|
activeSession?.startInk()
|
|
38
38
|
}
|
|
@@ -47,7 +47,7 @@ export function endDevSession(): void {
|
|
|
47
47
|
activeSession = null
|
|
48
48
|
}
|
|
49
49
|
|
|
50
|
-
/** @deprecated Dev prompts render inside the Ink dashboard
|
|
50
|
+
/** @deprecated Dev prompts render inside the Ink dashboard, no suspend needed. */
|
|
51
51
|
export function suspendDevSessionForPrompt(): void {
|
|
52
52
|
prepareStdinForInteractivePrompt()
|
|
53
53
|
}
|
|
@@ -58,12 +58,12 @@ export function prepareStdinForInteractivePrompt(): void {
|
|
|
58
58
|
process.stdin.resume()
|
|
59
59
|
}
|
|
60
60
|
|
|
61
|
-
/** @deprecated Dev prompts render inside the Ink dashboard
|
|
61
|
+
/** @deprecated Dev prompts render inside the Ink dashboard, no resume needed. */
|
|
62
62
|
export function resumeDevSessionAfterPrompt(): void {
|
|
63
|
-
// no-op
|
|
63
|
+
// no-op: prompts are Ink overlays
|
|
64
64
|
}
|
|
65
65
|
|
|
66
|
-
/** @deprecated Use Ink overlay prompts
|
|
66
|
+
/** @deprecated Use Ink overlay prompts, runs fn without tearing down the dashboard. */
|
|
67
67
|
export async function withDevSessionSuspended<T>(fn: () => Promise<T>): Promise<T> {
|
|
68
68
|
return fn()
|
|
69
69
|
}
|
package/src/dev-shutdown.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Graceful shutdown for `supatype dev
|
|
2
|
+
* Graceful shutdown for `supatype dev`, SIGINT, TUI Ctrl+C, terminal close,
|
|
3
3
|
* and a synchronous compose-down fallback on process exit.
|
|
4
4
|
*/
|
|
5
5
|
|
|
@@ -23,7 +23,7 @@ let forceQuitRequested = false
|
|
|
23
23
|
let hooksRegistered = false
|
|
24
24
|
let ignoreSigintUntil = 0
|
|
25
25
|
|
|
26
|
-
/** SIGINT/SIGTERM hooks
|
|
26
|
+
/** SIGINT/SIGTERM hooks: call as soon as `supatype dev` starts (before compose is up). */
|
|
27
27
|
export function ensureDevShutdownHooks(): void {
|
|
28
28
|
if (hooksRegistered) return
|
|
29
29
|
hooksRegistered = true
|
|
@@ -62,7 +62,7 @@ function syncComposeDownFallback(): void {
|
|
|
62
62
|
{ quiet: true },
|
|
63
63
|
)
|
|
64
64
|
} catch {
|
|
65
|
-
// best-effort
|
|
65
|
+
// best-effort: process is exiting
|
|
66
66
|
}
|
|
67
67
|
if (shutdownCwd) clearDevSessionLock(shutdownCwd)
|
|
68
68
|
}
|
|
@@ -74,7 +74,7 @@ function onProcessExit(): void {
|
|
|
74
74
|
export interface RegisterDevShutdownOptions {
|
|
75
75
|
/** Sync `docker compose down` when async teardown cannot finish (terminal close, kill). */
|
|
76
76
|
compose?: DevComposeShutdownFallback
|
|
77
|
-
/** Project root
|
|
77
|
+
/** Project root: clears `.supatype/dev-session.json` after shutdown. */
|
|
78
78
|
cwd?: string
|
|
79
79
|
}
|
|
80
80
|
|
|
@@ -89,7 +89,7 @@ export function registerDevShutdown(
|
|
|
89
89
|
ensureDevShutdownHooks()
|
|
90
90
|
}
|
|
91
91
|
|
|
92
|
-
/** TUI Ctrl+C
|
|
92
|
+
/** TUI Ctrl+C: do not re-emit SIGINT (avoids double-fire on Windows raw mode). */
|
|
93
93
|
export function requestDevShutdown(): void {
|
|
94
94
|
ignoreSigintUntil = Date.now() + 400
|
|
95
95
|
void runDevShutdown()
|
|
@@ -99,7 +99,7 @@ export function isDevShuttingDown(): boolean {
|
|
|
99
99
|
return shuttingDown
|
|
100
100
|
}
|
|
101
101
|
|
|
102
|
-
/** @internal Tests
|
|
102
|
+
/** @internal Tests: reset module state between cases. */
|
|
103
103
|
export function resetDevShutdownForTests(): void {
|
|
104
104
|
shutdownWork = null
|
|
105
105
|
composeFallback = null
|
|
@@ -125,7 +125,7 @@ async function runDevShutdown(): Promise<void> {
|
|
|
125
125
|
} catch {
|
|
126
126
|
// best-effort terminal restore
|
|
127
127
|
}
|
|
128
|
-
process.stderr.write("\n[supatype] Forced quit
|
|
128
|
+
process.stderr.write("\n[supatype] Forced quit: Docker containers may still be running.\n")
|
|
129
129
|
process.stdout.write("\n")
|
|
130
130
|
process.exit(130)
|
|
131
131
|
}
|
|
@@ -145,7 +145,7 @@ async function runDevShutdown(): Promise<void> {
|
|
|
145
145
|
} catch (err) {
|
|
146
146
|
process.stderr.write(`[supatype] Shutdown failed: ${(err as Error).message}\n`)
|
|
147
147
|
process.stderr.write(
|
|
148
|
-
"[supatype] Docker containers may still be running
|
|
148
|
+
"[supatype] Docker containers may still be running, try: supatype self-host compose down\n",
|
|
149
149
|
)
|
|
150
150
|
syncComposeDownFallback()
|
|
151
151
|
shutdownCompleted = true
|
package/src/dev-task-colors.ts
CHANGED
|
@@ -30,7 +30,7 @@ export function levelColor(line: string): string | null {
|
|
|
30
30
|
return null
|
|
31
31
|
}
|
|
32
32
|
|
|
33
|
-
/** Drop redundant prefix
|
|
33
|
+
/** Drop redundant prefix: task pane is already labelled supatype. */
|
|
34
34
|
export function normalizeStackLogLine(line: string): string {
|
|
35
35
|
return line.replace(/^\[supatype\]\s*/, "")
|
|
36
36
|
}
|