@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/pull-utils.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Utilities for `pull` and `introspect
|
|
2
|
+
* Utilities for `pull` and `introspect`, map engine DatabaseState to Model<> scaffold.
|
|
3
3
|
*/
|
|
4
4
|
|
|
5
5
|
export interface DbColumnState {
|
|
@@ -104,7 +104,7 @@ export function pgTypeToModelField(col: ColumnInfo): string {
|
|
|
104
104
|
const base = name.replace(/_id$/, "")
|
|
105
105
|
const rel = base.replace(/_([a-z])/g, (_, c: string) => c.toUpperCase())
|
|
106
106
|
const relName = rel.charAt(0).toUpperCase() + rel.slice(1)
|
|
107
|
-
return `${name}: UUID\n // TODO: relation
|
|
107
|
+
return `${name}: UUID\n // TODO: relation, RelatedTo<"${relName}">`
|
|
108
108
|
}
|
|
109
109
|
if (name === "created_at" || name === "updated_at") {
|
|
110
110
|
return `${name}: Timestamp`
|
|
@@ -160,7 +160,7 @@ export function databaseStateToSchemaScaffold(state: DatabaseStateJson): string
|
|
|
160
160
|
const skipTables = new Set(["spatial_ref_sys", "schema_migrations"])
|
|
161
161
|
|
|
162
162
|
const lines: string[] = [
|
|
163
|
-
"// DRAFT
|
|
163
|
+
"// DRAFT: generated by `supatype pull`. Review access rules, relations, and indexes before push.",
|
|
164
164
|
'import type { Model, Public, UUID, Timestamp, Optional, Unique, Email, Slug, SupatypeAuthUserId, JSON, Int, BigInt } from "@supatype/types"',
|
|
165
165
|
"",
|
|
166
166
|
]
|
|
@@ -231,7 +231,7 @@ export function printIntrospectSummary(state: DatabaseStateJson): void {
|
|
|
231
231
|
}
|
|
232
232
|
}
|
|
233
233
|
|
|
234
|
-
/** @deprecated Legacy pull helper
|
|
234
|
+
/** @deprecated Legacy pull helper, use {@link pgTypeToModelField}. */
|
|
235
235
|
export function pgTypeToField(col: ColumnInfo): string {
|
|
236
236
|
const opts: Record<string, unknown> = { required: !col.nullable }
|
|
237
237
|
if (col.isPrimary) opts["primaryKey"] = true
|
package/src/realtime-launch.ts
CHANGED
|
@@ -46,7 +46,7 @@ export async function resolveRealtimeLaunch(
|
|
|
46
46
|
return { bin: process.execPath, args: [entry] }
|
|
47
47
|
}
|
|
48
48
|
throw new Error(
|
|
49
|
-
"realtime binary not available
|
|
49
|
+
"realtime binary not available, run `supatype update` or set overrides.realtime in supatype.config.ts",
|
|
50
50
|
)
|
|
51
51
|
}
|
|
52
52
|
}
|
package/src/release-pins.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Release pins read from files under packages/cli/releases/.
|
|
3
|
-
* CI (deno-releases workflow) uses the same paths
|
|
3
|
+
* CI (deno-releases workflow) uses the same paths, bump only releases/deno/VERSION.
|
|
4
4
|
*/
|
|
5
5
|
|
|
6
6
|
import { readFileSync } from "node:fs"
|
|
@@ -17,7 +17,7 @@ function readPinFile(...segments: string[]): string {
|
|
|
17
17
|
} catch {
|
|
18
18
|
throw new Error(
|
|
19
19
|
`Missing release pin file: ${path}\n` +
|
|
20
|
-
"Expected packages/cli/releases
|
|
20
|
+
"Expected packages/cli/releases/…: reinstall @supatype/cli or build from the monorepo.",
|
|
21
21
|
)
|
|
22
22
|
}
|
|
23
23
|
const version = raw.trim()
|
package/src/resolve-api-url.ts
CHANGED
|
@@ -35,7 +35,7 @@ export function resolveProjectApiUrl(cwd: string): string {
|
|
|
35
35
|
return fromConfig.replace(/\/+$/, "")
|
|
36
36
|
}
|
|
37
37
|
} catch {
|
|
38
|
-
// No supatype.config
|
|
38
|
+
// No supatype.config: fall through to PORT default.
|
|
39
39
|
}
|
|
40
40
|
|
|
41
41
|
const port = readEnvValue(cwd, "PORT", "54321").trim() || "54321"
|
package/src/resolve-target.ts
CHANGED
|
@@ -6,6 +6,7 @@ import { ensureEngine, engineRequest } from "./engine-client.js"
|
|
|
6
6
|
import type { SchemaSourcesPayload } from "./schema-sources.js"
|
|
7
7
|
import {
|
|
8
8
|
connectionString,
|
|
9
|
+
pgSchema,
|
|
9
10
|
resolveRuntimeProvider,
|
|
10
11
|
schemaPathFromProject,
|
|
11
12
|
serverBaseUrl,
|
|
@@ -20,7 +21,12 @@ import {
|
|
|
20
21
|
type LocalEnvironment,
|
|
21
22
|
type ProjectLink,
|
|
22
23
|
} from "./link.js"
|
|
23
|
-
import {
|
|
24
|
+
import {
|
|
25
|
+
persistCloudSession,
|
|
26
|
+
resolveCloudAccessToken,
|
|
27
|
+
resolveCloudRefreshToken,
|
|
28
|
+
} from "./cloud-credentials.js"
|
|
29
|
+
import { targetFetch, type TargetFetchOptions } from "./target-client.js"
|
|
24
30
|
|
|
25
31
|
export interface ResolveTargetFlags {
|
|
26
32
|
env?: string | undefined
|
|
@@ -38,8 +44,12 @@ export interface DeployTarget {
|
|
|
38
44
|
apiBaseUrl: string
|
|
39
45
|
apiPrefix: "/api/v1" | "/platform/v1"
|
|
40
46
|
token?: string | undefined
|
|
47
|
+
/** Cloud GoTrue refresh token (mode === "cloud" only). */
|
|
48
|
+
refreshToken?: string | undefined
|
|
41
49
|
orgId?: string | undefined
|
|
42
50
|
link: ProjectLink | null
|
|
51
|
+
/** Project cwd: needed to persist refreshed cloud tokens. */
|
|
52
|
+
cwd?: string
|
|
43
53
|
/** Engine subprocess path when mode is direct or local without control plane. */
|
|
44
54
|
databaseUrl?: string
|
|
45
55
|
}
|
|
@@ -147,12 +157,19 @@ export function resolveTarget(cwd: string, flags: ResolveTargetFlags = {}): Depl
|
|
|
147
157
|
)
|
|
148
158
|
}
|
|
149
159
|
|
|
150
|
-
const token =
|
|
160
|
+
const token =
|
|
161
|
+
(link.kind === "cloud" ? resolveCloudAccessToken(link) : undefined) ??
|
|
162
|
+
resolveEnvironmentToken(link, envTarget)
|
|
151
163
|
if (!token) {
|
|
152
|
-
throw new Error(
|
|
164
|
+
throw new Error(
|
|
165
|
+
link.kind === "cloud"
|
|
166
|
+
? `No cloud session for environment "${envName}". Run: supatype login`
|
|
167
|
+
: `No token for environment "${envName}". Re-run supatype link --token ...`,
|
|
168
|
+
)
|
|
153
169
|
}
|
|
154
170
|
|
|
155
171
|
if (link.kind === "cloud") {
|
|
172
|
+
const refreshToken = resolveCloudRefreshToken(link)
|
|
156
173
|
return {
|
|
157
174
|
mode: "cloud",
|
|
158
175
|
environment: envName,
|
|
@@ -161,6 +178,8 @@ export function resolveTarget(cwd: string, flags: ResolveTargetFlags = {}): Depl
|
|
|
161
178
|
apiPrefix: "/api/v1",
|
|
162
179
|
token,
|
|
163
180
|
link,
|
|
181
|
+
cwd,
|
|
182
|
+
...(refreshToken !== undefined ? { refreshToken } : {}),
|
|
164
183
|
...(link.orgId !== undefined ? { orgId: link.orgId } : {}),
|
|
165
184
|
}
|
|
166
185
|
}
|
|
@@ -173,6 +192,44 @@ export function resolveTarget(cwd: string, flags: ResolveTargetFlags = {}): Depl
|
|
|
173
192
|
apiPrefix: "/platform/v1",
|
|
174
193
|
token,
|
|
175
194
|
link,
|
|
195
|
+
cwd,
|
|
196
|
+
}
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
function cloudAuthRefresh(target: DeployTarget): TargetFetchOptions["authRefresh"] | undefined {
|
|
200
|
+
if (target.mode !== "cloud" || !target.refreshToken || !target.cwd) return undefined
|
|
201
|
+
const cloudApiUrl = (target.link?.cloudApiUrl ?? target.apiBaseUrl).replace(/\/$/, "")
|
|
202
|
+
const cwd = target.cwd
|
|
203
|
+
return {
|
|
204
|
+
cloudApiUrl,
|
|
205
|
+
refreshToken: target.refreshToken,
|
|
206
|
+
onRefreshed: ({ accessToken, refreshToken }) => {
|
|
207
|
+
persistCloudSession(cwd, {
|
|
208
|
+
apiUrl: cloudApiUrl,
|
|
209
|
+
accessToken,
|
|
210
|
+
...(refreshToken !== undefined ? { refreshToken } : {}),
|
|
211
|
+
})
|
|
212
|
+
target.token = accessToken
|
|
213
|
+
if (refreshToken !== undefined) target.refreshToken = refreshToken
|
|
214
|
+
},
|
|
215
|
+
}
|
|
216
|
+
}
|
|
217
|
+
|
|
218
|
+
function apiFetchOpts(
|
|
219
|
+
target: DeployTarget,
|
|
220
|
+
method: string,
|
|
221
|
+
path: string,
|
|
222
|
+
body?: unknown,
|
|
223
|
+
): TargetFetchOptions {
|
|
224
|
+
const authRefresh = cloudAuthRefresh(target)
|
|
225
|
+
return {
|
|
226
|
+
method,
|
|
227
|
+
path,
|
|
228
|
+
token: target.token!,
|
|
229
|
+
...(body !== undefined ? { body } : {}),
|
|
230
|
+
...(target.orgId !== undefined ? { orgId: target.orgId } : {}),
|
|
231
|
+
...(target.mode === "cloud" ? { environment: target.environment } : {}),
|
|
232
|
+
...(authRefresh !== undefined ? { authRefresh } : {}),
|
|
176
233
|
}
|
|
177
234
|
}
|
|
178
235
|
|
|
@@ -194,14 +251,14 @@ export async function targetSchemaDiff(
|
|
|
194
251
|
})
|
|
195
252
|
}
|
|
196
253
|
|
|
197
|
-
return targetFetch<DiffResult>(
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
254
|
+
return targetFetch<DiffResult>(
|
|
255
|
+
target.apiBaseUrl,
|
|
256
|
+
target.apiPrefix,
|
|
257
|
+
apiFetchOpts(target, "POST", projectPath(target, "/schema/diff"), {
|
|
258
|
+
ast,
|
|
259
|
+
schema: opts?.schema ?? "public",
|
|
260
|
+
}),
|
|
261
|
+
)
|
|
205
262
|
}
|
|
206
263
|
|
|
207
264
|
export async function targetSchemaPush(
|
|
@@ -236,14 +293,11 @@ export async function targetSchemaPush(
|
|
|
236
293
|
}
|
|
237
294
|
}
|
|
238
295
|
|
|
239
|
-
return targetFetch(
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
orgId: target.orgId,
|
|
245
|
-
environment: target.mode === "cloud" ? target.environment : undefined,
|
|
246
|
-
})
|
|
296
|
+
return targetFetch(
|
|
297
|
+
target.apiBaseUrl,
|
|
298
|
+
target.apiPrefix,
|
|
299
|
+
apiFetchOpts(target, "POST", projectPath(target, "/schema/push"), pushBody),
|
|
300
|
+
)
|
|
247
301
|
}
|
|
248
302
|
|
|
249
303
|
export interface SchemaRollbackResult {
|
|
@@ -286,14 +340,13 @@ export async function targetSchemaRollback(
|
|
|
286
340
|
})
|
|
287
341
|
}
|
|
288
342
|
|
|
289
|
-
return targetFetch<SchemaRollbackResult>(
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
})
|
|
343
|
+
return targetFetch<SchemaRollbackResult>(
|
|
344
|
+
target.apiBaseUrl,
|
|
345
|
+
target.apiPrefix,
|
|
346
|
+
apiFetchOpts(target, "POST", projectPath(target, "/schema/rollback"), {
|
|
347
|
+
schema: opts?.schema ?? "public",
|
|
348
|
+
}),
|
|
349
|
+
)
|
|
297
350
|
}
|
|
298
351
|
|
|
299
352
|
export async function targetListMigrations(
|
|
@@ -308,13 +361,11 @@ export async function targetListMigrations(
|
|
|
308
361
|
return Array.isArray(result) ? result : (result.migrations ?? [])
|
|
309
362
|
}
|
|
310
363
|
|
|
311
|
-
return targetFetch<MigrationListEntry[]>(
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
environment: target.mode === "cloud" ? target.environment : undefined,
|
|
317
|
-
})
|
|
364
|
+
return targetFetch<MigrationListEntry[]>(
|
|
365
|
+
target.apiBaseUrl,
|
|
366
|
+
target.apiPrefix,
|
|
367
|
+
apiFetchOpts(target, "GET", projectPath(target, "/schema/migrations")),
|
|
368
|
+
)
|
|
318
369
|
}
|
|
319
370
|
|
|
320
371
|
export async function targetSchemaDoctor(
|
|
@@ -332,14 +383,15 @@ export async function targetSchemaDoctor(
|
|
|
332
383
|
})
|
|
333
384
|
}
|
|
334
385
|
|
|
335
|
-
return targetFetch(
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
386
|
+
return targetFetch(
|
|
387
|
+
target.apiBaseUrl,
|
|
388
|
+
target.apiPrefix,
|
|
389
|
+
apiFetchOpts(target, "POST", projectPath(target, "/schema/doctor"), {
|
|
390
|
+
ast,
|
|
391
|
+
no_cache: opts?.noCache ?? false,
|
|
392
|
+
schema: opts?.schema ?? "public",
|
|
393
|
+
}),
|
|
394
|
+
)
|
|
343
395
|
}
|
|
344
396
|
|
|
345
397
|
export async function targetSchemaIntrospect(
|
|
@@ -354,14 +406,13 @@ export async function targetSchemaIntrospect(
|
|
|
354
406
|
})
|
|
355
407
|
}
|
|
356
408
|
|
|
357
|
-
return targetFetch(
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
})
|
|
409
|
+
return targetFetch(
|
|
410
|
+
target.apiBaseUrl,
|
|
411
|
+
target.apiPrefix,
|
|
412
|
+
apiFetchOpts(target, "POST", projectPath(target, "/schema/introspect"), {
|
|
413
|
+
schema: opts?.schema ?? "public",
|
|
414
|
+
}),
|
|
415
|
+
)
|
|
365
416
|
}
|
|
366
417
|
|
|
367
418
|
export async function targetSchemaAdopt(
|
|
@@ -381,20 +432,17 @@ export async function targetSchemaAdopt(
|
|
|
381
432
|
})
|
|
382
433
|
}
|
|
383
434
|
|
|
384
|
-
return targetFetch(
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
435
|
+
return targetFetch(
|
|
436
|
+
target.apiBaseUrl,
|
|
437
|
+
target.apiPrefix,
|
|
438
|
+
apiFetchOpts(target, "POST", projectPath(target, "/schema/adopt"), {
|
|
388
439
|
ast,
|
|
389
440
|
schema: opts?.schema ?? "public",
|
|
390
441
|
yes: opts?.yes ?? false,
|
|
391
442
|
no_cache: opts?.noCache ?? false,
|
|
392
443
|
...(opts?.names !== undefined ? { names: opts.names } : {}),
|
|
393
|
-
},
|
|
394
|
-
|
|
395
|
-
orgId: target.orgId,
|
|
396
|
-
environment: target.mode === "cloud" ? target.environment : undefined,
|
|
397
|
-
})
|
|
444
|
+
}),
|
|
445
|
+
)
|
|
398
446
|
}
|
|
399
447
|
|
|
400
448
|
export async function targetStatus(target: DeployTarget): Promise<unknown> {
|
|
@@ -402,18 +450,15 @@ export async function targetStatus(target: DeployTarget): Promise<unknown> {
|
|
|
402
450
|
return { mode: "direct", environment: target.environment }
|
|
403
451
|
}
|
|
404
452
|
|
|
405
|
-
return targetFetch(
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
environment: target.mode === "cloud" ? target.environment : undefined,
|
|
411
|
-
})
|
|
453
|
+
return targetFetch(
|
|
454
|
+
target.apiBaseUrl,
|
|
455
|
+
target.apiPrefix,
|
|
456
|
+
apiFetchOpts(target, "GET", projectPath(target, "/status")),
|
|
457
|
+
)
|
|
412
458
|
}
|
|
413
459
|
|
|
414
460
|
export function schemaPgSchema(cwd: string): string {
|
|
415
|
-
|
|
416
|
-
return config.schema?.pg_schema ?? "public"
|
|
461
|
+
return pgSchema(loadConfig(cwd))
|
|
417
462
|
}
|
|
418
463
|
|
|
419
464
|
export { schemaPathFromProject }
|
package/src/rest-cache-admin.ts
CHANGED
|
@@ -34,7 +34,7 @@ function serviceRoleKey(cwd: string): string {
|
|
|
34
34
|
readEnvValue(cwd, "SUPATYPE_SERVICE_ROLE_KEY", "").trim() ||
|
|
35
35
|
readEnvValue(cwd, "SERVICE_ROLE_KEY", "").trim()
|
|
36
36
|
if (!key) {
|
|
37
|
-
throw new Error("SERVICE_ROLE_KEY not found in .env
|
|
37
|
+
throw new Error("SERVICE_ROLE_KEY not found in .env, run supatype dev or supatype keys")
|
|
38
38
|
}
|
|
39
39
|
return key.trim()
|
|
40
40
|
}
|
|
@@ -66,7 +66,7 @@ function formatCacheApiError(
|
|
|
66
66
|
return "REST server cache is not available on this plan or deployment."
|
|
67
67
|
}
|
|
68
68
|
if (status === 503 && trimmed.includes("valkey")) {
|
|
69
|
-
return "Valkey is not configured
|
|
69
|
+
return "Valkey is not configured, server-side REST cache requires Valkey (supatype dev with docker)."
|
|
70
70
|
}
|
|
71
71
|
return `${operation} failed (${status}): ${trimmed || "(empty body)"}`
|
|
72
72
|
}
|
package/src/runtime-routes.ts
CHANGED
|
@@ -17,7 +17,7 @@ export interface RuntimeRouteOptions {
|
|
|
17
17
|
functionsServiceUrl?: string
|
|
18
18
|
/**
|
|
19
19
|
* Self-host Compose: Kong forwards API traffic to supatype-server (unified gateway),
|
|
20
|
-
* which proxies to internal services
|
|
20
|
+
* which proxies to internal services, same model as `supatype dev`.
|
|
21
21
|
*/
|
|
22
22
|
unifiedGateway?: boolean
|
|
23
23
|
/** Studio UI upstream (default: in-compose `studio:3002`). */
|
|
@@ -161,7 +161,7 @@ function runtimeRouteSpecUnified(opts: RuntimeRouteOptions): RuntimeRoute[] {
|
|
|
161
161
|
|
|
162
162
|
/**
|
|
163
163
|
* Legacy split-stack routes (PostgREST/storage/realtime directly from Kong).
|
|
164
|
-
* Kept for tests or explicit opt-out only
|
|
164
|
+
* Kept for tests or explicit opt-out only, self-host uses unifiedGateway.
|
|
165
165
|
*/
|
|
166
166
|
function runtimeRouteSpecSplit(opts: RuntimeRouteOptions): RuntimeRoute[] {
|
|
167
167
|
const studioUrl = studioServiceUrl(opts)
|
package/src/schema-ast-v2.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* AST v2 wire format
|
|
2
|
+
* AST v2 wire format, canonical types and emitters.
|
|
3
3
|
* Parsers build {@link ParsedField}; only `emitField` / `emitModel` / `emitSchema` produce JSON.
|
|
4
4
|
*/
|
|
5
5
|
|
|
@@ -30,7 +30,7 @@ export interface FieldAnnotations {
|
|
|
30
30
|
platform?: PlatformFieldAnnotations
|
|
31
31
|
}
|
|
32
32
|
|
|
33
|
-
/** Kernel facts only
|
|
33
|
+
/** Kernel facts only: never db/platform keys at this layer. */
|
|
34
34
|
export interface KernelFieldFacts {
|
|
35
35
|
required?: boolean
|
|
36
36
|
primaryKey?: boolean
|
|
@@ -62,7 +62,7 @@ export interface KernelFieldFacts {
|
|
|
62
62
|
index?: boolean
|
|
63
63
|
}
|
|
64
64
|
|
|
65
|
-
/** Internal parse result
|
|
65
|
+
/** Internal parse result: not serialized. */
|
|
66
66
|
export interface ParsedField {
|
|
67
67
|
kind: string
|
|
68
68
|
kernel: KernelFieldFacts
|
|
@@ -88,7 +88,7 @@ export interface ModelAstV2 {
|
|
|
88
88
|
options: Record<string, unknown>
|
|
89
89
|
annotations: {
|
|
90
90
|
db: { tableName: string; indexes: unknown[] }
|
|
91
|
-
platform: { access: Record<string, unknown> }
|
|
91
|
+
platform: { access: Record<string, unknown>; hooks?: Record<string, unknown> }
|
|
92
92
|
}
|
|
93
93
|
}
|
|
94
94
|
|
|
@@ -294,6 +294,7 @@ export function emitModel(
|
|
|
294
294
|
tableName: string,
|
|
295
295
|
access: Record<string, unknown>,
|
|
296
296
|
indexes: unknown[] = [],
|
|
297
|
+
hooks: Record<string, unknown> = {},
|
|
297
298
|
): ModelAstV2 {
|
|
298
299
|
return {
|
|
299
300
|
name,
|
|
@@ -301,7 +302,9 @@ export function emitModel(
|
|
|
301
302
|
options,
|
|
302
303
|
annotations: {
|
|
303
304
|
db: { tableName, indexes },
|
|
304
|
-
platform
|
|
305
|
+
// Hooks sit in `platform` beside `access`: they are an API-layer concern, not a column one,
|
|
306
|
+
// supatype-server reads them, Postgres never sees them.
|
|
307
|
+
platform: { access, ...(Object.keys(hooks).length > 0 && { hooks }) },
|
|
305
308
|
},
|
|
306
309
|
}
|
|
307
310
|
}
|
package/src/schema-push-lock.ts
CHANGED
|
@@ -83,16 +83,26 @@ export async function withComposeSchemaPushLock<T>(
|
|
|
83
83
|
composeProject: string,
|
|
84
84
|
fn: () => Promise<T>,
|
|
85
85
|
): Promise<T> {
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
86
|
+
// The lock is held by a psql session reading from **stdin**, not by `-c … pg_sleep(86400)`.
|
|
87
|
+
//
|
|
88
|
+
// Killing the local `docker` client does not stop the process inside the container: `docker
|
|
89
|
+
// compose exec` does not forward the signal. With a sleeping session that meant every push
|
|
90
|
+
// left a backend holding this advisory lock for 24 hours, so `supatype push` never exited and
|
|
91
|
+
// the next push blocked on it. Observed end-to-end before this change.
|
|
92
|
+
//
|
|
93
|
+
// Closing stdin *does* propagate: psql sees EOF, exits, and the session ends, which is what
|
|
94
|
+
// releases an advisory lock. Deterministic, and it needs no signal to cross the boundary.
|
|
95
|
+
const args = dbExecArgs(paths, cwd, composeProject, ["-f", "-"])
|
|
90
96
|
|
|
91
97
|
let stderrBuf = ""
|
|
92
98
|
const holder: ChildProcess = spawn("docker", args, {
|
|
93
99
|
cwd,
|
|
94
|
-
stdio: ["
|
|
100
|
+
stdio: ["pipe", "pipe", "pipe"],
|
|
95
101
|
})
|
|
102
|
+
holder.stdin?.write(
|
|
103
|
+
`SELECT pg_advisory_lock(${SCHEMA_PUSH_LOCK_CLASSID}, ${SCHEMA_PUSH_LOCK_OBJID});\n`,
|
|
104
|
+
)
|
|
105
|
+
// Deliberately not ended: the open pipe is what keeps the session, and the lock, alive.
|
|
96
106
|
holder.stderr?.on("data", (chunk: Buffer) => {
|
|
97
107
|
stderrBuf += chunk.toString()
|
|
98
108
|
})
|
|
@@ -114,18 +124,47 @@ export async function withComposeSchemaPushLock<T>(
|
|
|
114
124
|
try {
|
|
115
125
|
return await fn()
|
|
116
126
|
} finally {
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
127
|
+
await releaseHolder(holder, paths, cwd, composeProject)
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
/**
|
|
132
|
+
* End the holder session, then confirm the lock is actually gone.
|
|
133
|
+
*
|
|
134
|
+
* Closing stdin is the mechanism; the check is because a leaked holder is silent and expensive,
|
|
135
|
+
* it blocks every later push. If EOF did not do it, terminate the backend directly.
|
|
136
|
+
*/
|
|
137
|
+
async function releaseHolder(
|
|
138
|
+
holder: ChildProcess,
|
|
139
|
+
paths: SelfHostComposePaths,
|
|
140
|
+
cwd: string,
|
|
141
|
+
composeProject: string,
|
|
142
|
+
): Promise<void> {
|
|
143
|
+
if (holder.exitCode === null) {
|
|
144
|
+
holder.stdin?.end()
|
|
145
|
+
await new Promise<void>((resolveDone) => {
|
|
146
|
+
const t = setTimeout(() => {
|
|
147
|
+
holder.kill("SIGKILL")
|
|
148
|
+
resolveDone()
|
|
149
|
+
}, 5000)
|
|
150
|
+
holder.once("exit", () => {
|
|
151
|
+
clearTimeout(t)
|
|
152
|
+
resolveDone()
|
|
128
153
|
})
|
|
129
|
-
}
|
|
154
|
+
})
|
|
130
155
|
}
|
|
156
|
+
|
|
157
|
+
if (!schemaPushLockIsHeld(paths, cwd, composeProject)) return
|
|
158
|
+
|
|
159
|
+
// Last resort: the session outlived its client. Ending it releases the lock.
|
|
160
|
+
spawnSync(
|
|
161
|
+
"docker",
|
|
162
|
+
dbExecArgs(paths, cwd, composeProject, [
|
|
163
|
+
"-tAc",
|
|
164
|
+
`SELECT pg_terminate_backend(pid) FROM pg_stat_activity
|
|
165
|
+
WHERE pid <> pg_backend_pid()
|
|
166
|
+
AND query LIKE '%pg_advisory_lock(${SCHEMA_PUSH_LOCK_CLASSID}, ${SCHEMA_PUSH_LOCK_OBJID})%'`,
|
|
167
|
+
]),
|
|
168
|
+
{ cwd, stdio: "ignore" },
|
|
169
|
+
)
|
|
131
170
|
}
|