@supatype/cli 0.1.7 → 0.1.10
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 +125 -122
- package/.turbo/turbo-typecheck.log +1 -1
- package/LICENSE +202 -0
- package/deno.d.ts +1 -1
- package/dist/app/framework.js +1 -1
- package/dist/app/framework.js.map +1 -1
- package/dist/augmentation-generator.d.ts +1 -1
- package/dist/augmentation-generator.js +3 -3
- package/dist/augmentation-generator.js.map +1 -1
- package/dist/binary-cache.d.ts +30 -8
- package/dist/binary-cache.d.ts.map +1 -1
- package/dist/binary-cache.js +47 -35
- package/dist/binary-cache.js.map +1 -1
- package/dist/cache-pins.d.ts +1 -1
- package/dist/cache-pins.js +2 -2
- package/dist/cache-pins.js.map +1 -1
- 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 +17 -1
- package/dist/cli-install-method.d.ts.map +1 -1
- package/dist/cli-install-method.js +32 -4
- package/dist/cli-install-method.js.map +1 -1
- 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.js +1 -1
- package/dist/cli.js.map +1 -1
- package/dist/commands/add.js +4 -3
- package/dist/commands/add.js.map +1 -1
- package/dist/commands/admin.js +6 -6
- 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.js +3 -3
- package/dist/commands/cache.js.map +1 -1
- package/dist/commands/db.d.ts +3 -3
- package/dist/commands/db.d.ts.map +1 -1
- package/dist/commands/db.js +12 -11
- 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.js +17 -17
- package/dist/commands/dev.js.map +1 -1
- package/dist/commands/doctor.d.ts +1 -1
- package/dist/commands/doctor.js +3 -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.map +1 -1
- package/dist/commands/functions.js +8 -7
- package/dist/commands/functions.js.map +1 -1
- package/dist/commands/hooks.d.ts +2 -2
- package/dist/commands/hooks.js +4 -4
- package/dist/commands/hooks.js.map +1 -1
- package/dist/commands/init.js +28 -28
- package/dist/commands/init.js.map +1 -1
- package/dist/commands/internal.d.ts.map +1 -1
- package/dist/commands/internal.js +37 -0
- package/dist/commands/internal.js.map +1 -1
- package/dist/commands/login.d.ts +1 -1
- package/dist/commands/login.js +1 -1
- package/dist/commands/login.js.map +1 -1
- 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.js +3 -3
- 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 +2 -8
- package/dist/commands/self-update.d.ts.map +1 -1
- package/dist/commands/self-update.js +20 -12
- 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 +23 -1
- package/dist/config.d.ts.map +1 -1
- package/dist/config.js +37 -18
- package/dist/config.js.map +1 -1
- package/dist/db-preflight.d.ts +4 -4
- package/dist/db-preflight.js +14 -14
- package/dist/db-preflight.js.map +1 -1
- package/dist/dev-compose.d.ts +3 -3
- package/dist/dev-compose.js +27 -27
- 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 +2 -2
- package/dist/env-file.d.ts.map +1 -1
- package/dist/env-file.js +1 -1
- package/dist/env-file.js.map +1 -1
- package/dist/field-masking-tier.d.ts +5 -5
- package/dist/field-masking-tier.d.ts.map +1 -1
- package/dist/field-masking-tier.js +6 -6
- package/dist/field-masking-tier.js.map +1 -1
- package/dist/functions-deno-types.d.ts +1 -1
- package/dist/functions-deno-types.d.ts.map +1 -1
- package/dist/functions-deno-types.js +3 -3
- package/dist/functions-deno-types.js.map +1 -1
- 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 +1 -1
- package/dist/hook-upload.js +3 -3
- package/dist/hooks-generator.d.ts +1 -1
- package/dist/hooks-generator.js +9 -9
- 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 +1 -1
- package/dist/link.d.ts.map +1 -1
- package/dist/local-secrets.d.ts +5 -5
- package/dist/local-secrets.js +5 -5
- 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 +3 -3
- package/dist/model-hooks.js +4 -4
- 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 +1 -1
- package/dist/postgres-ctl.js +4 -4
- 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 +12 -12
- package/dist/project-config.d.ts.map +1 -1
- package/dist/project-config.js +9 -9
- 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.d.ts.map +1 -1
- package/dist/resolve-api-url.js +4 -3
- package/dist/resolve-api-url.js.map +1 -1
- package/dist/resolve-target.d.ts +1 -1
- package/dist/resolve-target.d.ts.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 +3 -3
- package/dist/schema-ast-v2.d.ts.map +1 -1
- package/dist/schema-ast-v2.js +2 -2
- package/dist/schema-ast-v2.js.map +1 -1
- package/dist/schema-push-lock.js +3 -3
- 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 +5 -5
- package/dist/self-host-compose.d.ts.map +1 -1
- package/dist/self-host-compose.js +24 -24
- package/dist/self-host-compose.js.map +1 -1
- package/dist/service-role-check.js +3 -3
- package/dist/service-role-check.js.map +1 -1
- 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.js +1 -1
- package/dist/target-client.js.map +1 -1
- package/dist/tsx-runner.d.ts +12 -0
- package/dist/tsx-runner.d.ts.map +1 -1
- package/dist/tsx-runner.js +36 -2
- package/dist/tsx-runner.js.map +1 -1
- package/dist/type-extractor.js +27 -27
- 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 +1 -1
- 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.js +1 -1
- 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 +3 -2
- package/scripts/build-release-artifacts.sh +112 -0
- package/scripts/generate-homebrew-formula.mjs +47 -45
- 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 +3 -3
- package/src/binary-cache.ts +51 -36
- package/src/cache-pins.ts +2 -2
- package/src/cli-artifacts.ts +65 -0
- package/src/cli-install-method.ts +35 -4
- 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 +1 -1
- package/src/commands/add.ts +4 -3
- package/src/commands/admin.ts +6 -6
- package/src/commands/adopt.ts +1 -1
- package/src/commands/app.ts +2 -2
- package/src/commands/cache.ts +3 -3
- package/src/commands/db.ts +12 -11
- package/src/commands/deploy.ts +12 -12
- package/src/commands/dev.ts +19 -19
- package/src/commands/doctor.ts +3 -3
- package/src/commands/engine.ts +1 -1
- package/src/commands/functions.ts +8 -7
- package/src/commands/hooks.ts +6 -6
- package/src/commands/init.ts +28 -28
- package/src/commands/internal.ts +37 -0
- package/src/commands/login.ts +2 -2
- 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 +3 -3
- package/src/commands/self-host.ts +1 -1
- package/src/commands/self-update.ts +23 -73
- package/src/commands/status.ts +1 -1
- package/src/commands/update.ts +1 -1
- package/src/config.ts +39 -18
- package/src/db-preflight.ts +15 -15
- package/src/dev-compose.ts +27 -27
- 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 +2 -2
- package/src/field-masking-tier.ts +6 -6
- package/src/functions-deno-types.ts +3 -3
- package/src/functions-router-gen.ts +1 -1
- package/src/gitignore.ts +3 -3
- package/src/hook-upload.ts +3 -3
- package/src/hooks-generator.ts +9 -9
- package/src/index.ts +1 -1
- package/src/init-project-detect.ts +1 -1
- package/src/link.ts +1 -1
- package/src/local-secrets.ts +5 -5
- package/src/main.ts +20 -0
- package/src/model-hooks.ts +4 -4
- package/src/pgbouncer-userlist.ts +2 -2
- package/src/postgres-ctl.ts +4 -4
- package/src/process-manager.ts +4 -4
- package/src/project-config.ts +16 -16
- 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 +4 -3
- package/src/resolve-target.ts +1 -1
- package/src/rest-cache-admin.ts +2 -2
- package/src/runtime-routes.ts +2 -2
- package/src/schema-ast-v2.ts +4 -4
- package/src/schema-push-lock.ts +3 -3
- package/src/scripts/postinstall.ts +1 -1
- package/src/self-host-compose.ts +25 -25
- package/src/service-role-check.ts +3 -3
- 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 +1 -1
- package/src/tsx-runner.ts +41 -2
- package/src/type-extractor.ts +27 -27
- 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 +1 -1
- package/src/ui/runtime/run-clack-flow.tsx +1 -1
- package/src/ui/runtime/stdin-after-ink.ts +1 -1
- package/src/ui/theme.ts +1 -1
- package/src/valkey-sidecar.ts +2 -2
- package/tests/access-composition.test.ts +6 -6
- package/tests/admin-studio-membership.test.ts +1 -1
- package/tests/api-schemas.test.ts +1 -1
- package/tests/archive-name-alias.test.ts +1 -1
- package/tests/cli-help.test.ts +8 -2
- package/tests/config-load-failure.test.ts +44 -0
- package/tests/db-preflight.test.ts +1 -1
- package/tests/doctor-render.test.ts +3 -3
- package/tests/doctor-service-role.test.ts +2 -2
- package/tests/engine-push-output.test.ts +1 -1
- package/tests/env-file.test.ts +3 -3
- package/tests/external-database-compose.test.ts +5 -5
- package/tests/external-database-config.test.ts +2 -2
- package/tests/field-masking-tier.test.ts +1 -1
- package/tests/homebrew-formula.test.ts +68 -26
- package/tests/hook-upload.test.ts +1 -1
- package/tests/hooks-generator.test.ts +1 -1
- package/tests/init.test.ts +2 -2
- package/tests/keys.test.ts +8 -2
- package/tests/local-secrets.test.ts +3 -3
- package/tests/model-hooks.test.ts +6 -6
- package/tests/runtime-contract.test.ts +2 -2
- package/tests/service-role-check.test.ts +3 -3
- package/tests/storage-provision.test.ts +1 -1
- package/tests/type-extractor.test.ts +2 -2
- package/tsconfig.tsbuildinfo +1 -1
- package/vitest.config.ts +7 -1
- package/scripts/build-release-bundle.mjs +0 -27
package/src/cache-pins.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Pin-aware cache eviction
|
|
2
|
+
* Pin-aware cache eviction: collect `versions.*` pins across local projects (C13).
|
|
3
3
|
*/
|
|
4
4
|
|
|
5
5
|
import { existsSync, readdirSync, rmSync, statSync } from "node:fs"
|
|
@@ -219,7 +219,7 @@ export function cleanCachedBinaries(options: CleanCachedBinariesOptions): CleanC
|
|
|
219
219
|
if (!force && explicitVersion && pinned) {
|
|
220
220
|
const reason = pinReason(component, version, sources) ?? "pinned"
|
|
221
221
|
result.warned.push(
|
|
222
|
-
`${component}@${version} is ${reason}
|
|
222
|
+
`${component}@${version} is ${reason}: removing anyway (explicit version)`,
|
|
223
223
|
)
|
|
224
224
|
}
|
|
225
225
|
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Names and locations of the published standalone CLI artefacts.
|
|
3
|
+
*
|
|
4
|
+
* One place, because this layout had drifted into five: the release workflow, install.sh,
|
|
5
|
+
* this module's caller, the Homebrew generator and a now-deleted second installer all
|
|
6
|
+
* described it independently, and `supatype self-update` was asking for bare executables the
|
|
7
|
+
* publisher had stopped writing. `scripts/install.sh` cannot import this (it runs before any
|
|
8
|
+
* CLI exists on the machine), so the shell keeps its own copy; what holds the two together is
|
|
9
|
+
* the round-trip test in tests/integration/scripts/cli-artifact-roundtrip.sh, not this file.
|
|
10
|
+
*/
|
|
11
|
+
|
|
12
|
+
import { existsSync, readdirSync } from "node:fs"
|
|
13
|
+
import { currentPlatform, type PlatformId } from "./binary-cache.js"
|
|
14
|
+
|
|
15
|
+
/**
|
|
16
|
+
* Which C library the running system provides. Only meaningful on Linux: Bun links
|
|
17
|
+
* libstdc++ and libgcc dynamically, so a glibc build cannot start on Alpine, and installing a
|
|
18
|
+
* glibc binary over a working musl one is how a self-update would brick an Alpine install.
|
|
19
|
+
*/
|
|
20
|
+
export type LibcId = "glibc" | "musl"
|
|
21
|
+
|
|
22
|
+
/** Detects musl by its dynamic loader, the same signal scripts/install.sh uses. */
|
|
23
|
+
export function currentLibc(platform: PlatformId = currentPlatform()): LibcId {
|
|
24
|
+
if (platform.os !== "linux") return "glibc"
|
|
25
|
+
if (!existsSync("/lib")) return "glibc"
|
|
26
|
+
try {
|
|
27
|
+
const musl = readdirSync("/lib").some((f) => f.startsWith("ld-musl-") && f.endsWith(".so.1"))
|
|
28
|
+
return musl ? "musl" : "glibc"
|
|
29
|
+
} catch {
|
|
30
|
+
return "glibc"
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
/**
|
|
35
|
+
* The archive published for a platform. Windows gets a zip because that is what Windows
|
|
36
|
+
* users can open without extra tools; everything else is a tarball. Both hold a single
|
|
37
|
+
* executable called `supatype` (`supatype.exe` on Windows), whatever the archive is named.
|
|
38
|
+
*/
|
|
39
|
+
export function cliArchiveName(
|
|
40
|
+
platform: PlatformId = currentPlatform(),
|
|
41
|
+
libc: LibcId = currentLibc(platform),
|
|
42
|
+
): string {
|
|
43
|
+
const suffix = platform.os === "linux" && libc === "musl" ? "-musl" : ""
|
|
44
|
+
const ext = platform.os === "windows" ? "zip" : "tar.gz"
|
|
45
|
+
return `supatype-cli-${platform.os}-${platform.arch}${suffix}.${ext}`
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
/** The executable inside the archive. */
|
|
49
|
+
export function cliExecutableName(platform: PlatformId = currentPlatform()): string {
|
|
50
|
+
return platform.os === "windows" ? "supatype.exe" : "supatype"
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
/** CDN path of a version's archive, relative to the CDN root. */
|
|
54
|
+
export function cliArchivePath(
|
|
55
|
+
version: string,
|
|
56
|
+
platform: PlatformId = currentPlatform(),
|
|
57
|
+
libc: LibcId = currentLibc(platform),
|
|
58
|
+
): string {
|
|
59
|
+
return `/cli/v${version}/${cliArchiveName(platform, libc)}`
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
/** CDN path of the checksums file covering every archive in a version. */
|
|
63
|
+
export function cliChecksumsPath(version: string): string {
|
|
64
|
+
return `/cli/v${version}/checksums.sha256`
|
|
65
|
+
}
|
|
@@ -8,9 +8,40 @@ function normalizePath(path: string): string {
|
|
|
8
8
|
return path.replace(/\\/g, "/")
|
|
9
9
|
}
|
|
10
10
|
|
|
11
|
+
/**
|
|
12
|
+
* Inside a Bun-compiled binary, argv[1] is a path in the embedded filesystem, not on disk:
|
|
13
|
+
* `/$bunfs/root/supatype` on Linux and macOS, `B:/~BUN/root/supatype.exe` on Windows. No
|
|
14
|
+
* filesystem call can touch either, which is why self-update failed with
|
|
15
|
+
* `ENOENT: copyfile '/$bunfs/root/supatype'` and could never have replaced itself.
|
|
16
|
+
*/
|
|
17
|
+
const EMBEDDED_FS_PATH = /(^|\/)(\$bunfs|~BUN)\//i
|
|
18
|
+
|
|
19
|
+
/**
|
|
20
|
+
* The executable on disk.
|
|
21
|
+
*
|
|
22
|
+
* process.execPath is the compiled binary when running one, and the Node binary otherwise, so
|
|
23
|
+
* it is only correct to prefer it when argv[1] is an embedded path. Under Node the script path
|
|
24
|
+
* is what identifies the install.
|
|
25
|
+
*/
|
|
26
|
+
/**
|
|
27
|
+
* True when this process is a compiled single-file binary rather than Node running our JS.
|
|
28
|
+
*
|
|
29
|
+
* The distinction decides capability, not cosmetics: a compiled binary carries the Bun runtime
|
|
30
|
+
* and can import TypeScript directly, while it has no node_modules to resolve tsx from and no
|
|
31
|
+
* writable directory beside itself. A machine that installed with `curl | sh` has no Node at all.
|
|
32
|
+
*/
|
|
33
|
+
export function isCompiledBinary(): boolean {
|
|
34
|
+
return EMBEDDED_FS_PATH.test(normalizePath(process.argv[1] ?? ""))
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
export function runningBinaryPath(): string {
|
|
38
|
+
const main = normalizePath(process.argv[1] ?? "")
|
|
39
|
+
return EMBEDDED_FS_PATH.test(main) ? process.execPath : (process.argv[1] ?? "")
|
|
40
|
+
}
|
|
41
|
+
|
|
11
42
|
/** The running binary sits in an npm or workspace layout. */
|
|
12
43
|
function hasNpmInstallPath(): boolean {
|
|
13
|
-
const main = normalizePath(
|
|
44
|
+
const main = normalizePath(runningBinaryPath())
|
|
14
45
|
return (
|
|
15
46
|
main.includes("node_modules") ||
|
|
16
47
|
main.includes("/dist/cli") ||
|
|
@@ -30,7 +61,7 @@ export function looksLikeNpmOrWorkspaceCLI(): boolean {
|
|
|
30
61
|
|
|
31
62
|
/** Homebrew / Linuxbrew Cellar layout. */
|
|
32
63
|
export function looksLikeHomebrewCLI(): boolean {
|
|
33
|
-
const main = normalizePath(
|
|
64
|
+
const main = normalizePath(runningBinaryPath())
|
|
34
65
|
if (!main) return false
|
|
35
66
|
|
|
36
67
|
if (/(?:^|\/)Cellar\/supatype\//.test(main)) return true
|
|
@@ -44,7 +75,7 @@ export function looksLikeHomebrewCLI(): boolean {
|
|
|
44
75
|
}
|
|
45
76
|
|
|
46
77
|
/**
|
|
47
|
-
* Which installer owns the running binary
|
|
78
|
+
* Which installer owns the running binary. This decides what `self-update`
|
|
48
79
|
* tells the user to run, so it has to describe the binary on disk.
|
|
49
80
|
*
|
|
50
81
|
* Path shape wins over `npm_*` in the environment: those are set whenever the
|
|
@@ -62,6 +93,6 @@ export function detectCliInstallMethod(): CliInstallMethod {
|
|
|
62
93
|
|
|
63
94
|
/** The `curl | sh` installer's default target. */
|
|
64
95
|
function isStandalonePath(): boolean {
|
|
65
|
-
const main = normalizePath(
|
|
96
|
+
const main = normalizePath(runningBinaryPath())
|
|
66
97
|
return main.includes("/.supatype/bin/")
|
|
67
98
|
}
|
|
@@ -1,11 +1,15 @@
|
|
|
1
1
|
import { readFileSync } from "node:fs"
|
|
2
2
|
import { dirname, join } from "node:path"
|
|
3
3
|
import { fileURLToPath } from "node:url"
|
|
4
|
+
import { EMBEDDED_CLI_VERSION } from "./cli-version-embedded.js"
|
|
4
5
|
|
|
5
6
|
const CLI_PACKAGE_JSON = join(dirname(fileURLToPath(import.meta.url)), "..", "package.json")
|
|
6
7
|
|
|
7
|
-
/** Installed @supatype/cli version
|
|
8
|
+
/** Installed @supatype/cli version (used by --version and init scaffolding). */
|
|
8
9
|
export function cliPackageVersion(): string {
|
|
10
|
+
// Set in published builds; the package.json read below only works when one is on disk,
|
|
11
|
+
// which is true for the npm package and false inside the standalone binary.
|
|
12
|
+
if (EMBEDDED_CLI_VERSION !== "") return EMBEDDED_CLI_VERSION
|
|
9
13
|
try {
|
|
10
14
|
const pkg = JSON.parse(readFileSync(CLI_PACKAGE_JSON, "utf8")) as { version?: string }
|
|
11
15
|
return pkg.version ?? "0.0.0"
|
package/src/cli-standalone.ts
CHANGED
|
@@ -1,23 +1,45 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Standalone CLI
|
|
2
|
+
* Standalone CLI archive download, used by `supatype self-update`.
|
|
3
|
+
*
|
|
4
|
+
* The artefact is a per-platform archive holding one executable, not a bare executable, and it
|
|
5
|
+
* is verified against the release's checksums.sha256 before anything is replaced. Previously
|
|
6
|
+
* this path checked only that the download was over 64 bytes and did not begin like HTML or
|
|
7
|
+
* JSON, which made the CLI stricter about a postgres archive than about overwriting itself.
|
|
3
8
|
*/
|
|
4
9
|
|
|
5
|
-
import { chmodSync, existsSync, mkdirSync, writeFileSync } from "node:fs"
|
|
6
|
-
import {
|
|
10
|
+
import { chmodSync, existsSync, mkdirSync, readFileSync, rmSync, writeFileSync } from "node:fs"
|
|
11
|
+
import { createHash } from "node:crypto"
|
|
12
|
+
import { homedir, tmpdir } from "node:os"
|
|
7
13
|
import { join } from "node:path"
|
|
8
|
-
import {
|
|
14
|
+
import { spawnSync } from "node:child_process"
|
|
15
|
+
import { currentPlatform, fetchChecksums, type PlatformId } from "./binary-cache.js"
|
|
16
|
+
import {
|
|
17
|
+
cliArchiveName,
|
|
18
|
+
cliArchivePath,
|
|
19
|
+
cliChecksumsPath,
|
|
20
|
+
cliExecutableName,
|
|
21
|
+
currentLibc,
|
|
22
|
+
type LibcId,
|
|
23
|
+
} from "./cli-artifacts.js"
|
|
9
24
|
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
25
|
+
/**
|
|
26
|
+
* Overridable for the same reason scripts/install.sh takes SUPATYPE_CDN: with the host fixed,
|
|
27
|
+
* nothing can exercise this path except a real release, which is how it came to request bare
|
|
28
|
+
* executables the publisher had stopped writing. SUPATYPE_CDN_BASE is the CDN root, where
|
|
29
|
+
* install.sh's SUPATYPE_CDN is the root plus /cli.
|
|
30
|
+
*
|
|
31
|
+
* binary-cache.ts hardcodes the same host for component downloads and could use the same
|
|
32
|
+
* treatment, which is left alone here as it is not part of this change.
|
|
33
|
+
*/
|
|
34
|
+
const CDN_BASE = process.env["SUPATYPE_CDN_BASE"]?.replace(/\/$/, "")
|
|
35
|
+
|| "https://releases.supatype.com"
|
|
16
36
|
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
37
|
+
/** Where a downloaded release is unpacked, so a repeated update does not refetch it. */
|
|
38
|
+
export function cliCachePath(
|
|
39
|
+
version: string,
|
|
40
|
+
platform: PlatformId = currentPlatform(),
|
|
41
|
+
): string {
|
|
42
|
+
return join(homedir(), ".supatype", "cache", "cli", version, cliExecutableName(platform))
|
|
21
43
|
}
|
|
22
44
|
|
|
23
45
|
export async function fetchStandaloneCliLatestVersion(): Promise<string> {
|
|
@@ -32,31 +54,91 @@ export async function fetchStandaloneCliLatestVersion(): Promise<string> {
|
|
|
32
54
|
return data.version.trim()
|
|
33
55
|
}
|
|
34
56
|
|
|
35
|
-
|
|
36
|
-
export async function downloadStandaloneCli(version?: string): Promise<string> {
|
|
37
|
-
const platform = currentPlatform()
|
|
38
|
-
const resolved = version ?? await fetchStandaloneCliLatestVersion()
|
|
39
|
-
const dest = cliCachePath(resolved, platform)
|
|
40
|
-
if (existsSync(dest)) return dest
|
|
41
|
-
|
|
42
|
-
const url = `${CDN_BASE}${cliCdnPath(resolved, platform)}`
|
|
57
|
+
async function fetchBytes(url: string, what: string): Promise<Buffer> {
|
|
43
58
|
const resp = await fetch(url)
|
|
44
59
|
if (!resp.ok) {
|
|
45
|
-
throw new Error(`Failed to download
|
|
60
|
+
throw new Error(`Failed to download ${what} from ${url}: HTTP ${resp.status}`)
|
|
46
61
|
}
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
62
|
+
return Buffer.from(await resp.arrayBuffer())
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
/**
|
|
66
|
+
* Unpack the single executable from an archive.
|
|
67
|
+
*
|
|
68
|
+
* PowerShell on Windows, because Git Bash's tar is usually first on PATH there and chokes on
|
|
69
|
+
* drive-letter paths. The same split exists in commands/dev.ts for component archives.
|
|
70
|
+
*/
|
|
71
|
+
function unpackExecutable(archivePath: string, destDir: string, platform: PlatformId): string {
|
|
72
|
+
mkdirSync(destDir, { recursive: true })
|
|
73
|
+
const result = platform.os === "windows"
|
|
74
|
+
? spawnSync(
|
|
75
|
+
"powershell.exe",
|
|
76
|
+
[
|
|
77
|
+
"-NoProfile",
|
|
78
|
+
"-Command",
|
|
79
|
+
`Expand-Archive -Path '${archivePath}' -DestinationPath '${destDir}' -Force`,
|
|
80
|
+
],
|
|
81
|
+
{ stdio: "pipe" },
|
|
82
|
+
)
|
|
83
|
+
: spawnSync("tar", ["-xzf", archivePath, "-C", destDir], { stdio: "pipe" })
|
|
84
|
+
|
|
85
|
+
if (result.status !== 0) {
|
|
86
|
+
throw new Error(
|
|
87
|
+
`Failed to unpack ${archivePath}: ${result.stderr?.toString().trim() || "unknown error"}`,
|
|
88
|
+
)
|
|
50
89
|
}
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
90
|
+
|
|
91
|
+
const exe = join(destDir, cliExecutableName(platform))
|
|
92
|
+
if (!existsSync(exe)) {
|
|
93
|
+
throw new Error(
|
|
94
|
+
`${cliArchiveName(platform)} did not contain ${cliExecutableName(platform)}.`,
|
|
95
|
+
)
|
|
96
|
+
}
|
|
97
|
+
return exe
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
/**
|
|
101
|
+
* Download and verify the standalone CLI for this machine, returning the path to the
|
|
102
|
+
* executable. Nothing is written to the cache until the checksum matches.
|
|
103
|
+
*/
|
|
104
|
+
export async function downloadStandaloneCli(
|
|
105
|
+
version?: string,
|
|
106
|
+
platform: PlatformId = currentPlatform(),
|
|
107
|
+
libc: LibcId = currentLibc(platform),
|
|
108
|
+
): Promise<string> {
|
|
109
|
+
const resolved = version ?? await fetchStandaloneCliLatestVersion()
|
|
110
|
+
const dest = cliCachePath(resolved, platform)
|
|
111
|
+
if (existsSync(dest)) return dest
|
|
112
|
+
|
|
113
|
+
const name = cliArchiveName(platform, libc)
|
|
114
|
+
const archive = await fetchBytes(`${CDN_BASE}${cliArchivePath(resolved, platform, libc)}`, name)
|
|
115
|
+
|
|
116
|
+
// The manifest is verified before it is trusted, and only then is the archive compared
|
|
117
|
+
// against it. A checksum alone would prove the download was intact, not that it came from
|
|
118
|
+
// us, and the signature is what makes replacing our own executable no weaker than fetching
|
|
119
|
+
// a postgres archive. fetchChecksums treats the .minisig as mandatory and fails closed
|
|
120
|
+
// without a public key, which is the same rule component downloads follow.
|
|
121
|
+
const checksumsUrl = `${CDN_BASE}${cliChecksumsPath(resolved)}`
|
|
122
|
+
const expected = await fetchChecksums(checksumsUrl, `${checksumsUrl}.minisig`, name)
|
|
123
|
+
const actual = createHash("sha256").update(archive).digest("hex")
|
|
124
|
+
if (actual !== expected.checksum) {
|
|
125
|
+
throw new Error(
|
|
126
|
+
`Checksum mismatch for ${name}.\n expected: ${expected.checksum}\n actual: ${actual}`,
|
|
127
|
+
)
|
|
54
128
|
}
|
|
55
129
|
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
130
|
+
const staging = join(tmpdir(), `supatype-cli-${resolved}-${process.pid}`)
|
|
131
|
+
try {
|
|
132
|
+
mkdirSync(staging, { recursive: true })
|
|
133
|
+
const archivePath = join(staging, name)
|
|
134
|
+
writeFileSync(archivePath, archive)
|
|
135
|
+
const unpacked = unpackExecutable(archivePath, staging, platform)
|
|
136
|
+
|
|
137
|
+
mkdirSync(join(dest, ".."), { recursive: true })
|
|
138
|
+
writeFileSync(dest, readFileSync(unpacked))
|
|
139
|
+
if (platform.os !== "windows") chmodSync(dest, 0o755)
|
|
140
|
+
return dest
|
|
141
|
+
} finally {
|
|
142
|
+
rmSync(staging, { recursive: true, force: true })
|
|
60
143
|
}
|
|
61
|
-
return dest
|
|
62
144
|
}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* CLI version, baked in at publish by scripts/set-version.mjs.
|
|
3
|
+
*
|
|
4
|
+
* The standalone binary cannot read its own package.json: pkg carries only files it can
|
|
5
|
+
* find by static analysis, and that path is assembled at runtime, so `--version` inside a
|
|
6
|
+
* published binary would answer 0.0.0 without this. Empty in a source checkout, where
|
|
7
|
+
* cliPackageVersion() falls back to reading package.json.
|
|
8
|
+
*/
|
|
9
|
+
// Annotated `string`, not left to inference: once a release stamps a value here, the
|
|
10
|
+
// inferred literal type makes the `!== ""` test in cliPackageVersion() a compile error
|
|
11
|
+
// (TS2367, no overlap), so the build would only fail during a release.
|
|
12
|
+
export const EMBEDDED_CLI_VERSION: string = "0.1.10"
|
package/src/cli.ts
CHANGED
|
@@ -39,7 +39,7 @@ import { wrapProgramActionsWithChrome } from "./ui/runtime/command-chrome.js"
|
|
|
39
39
|
export async function run(): Promise<void> {
|
|
40
40
|
const program = new Command()
|
|
41
41
|
.name("supatype")
|
|
42
|
-
.description("Supatype
|
|
42
|
+
.description("Supatype: type-first platform for PostgreSQL")
|
|
43
43
|
.version(cliPackageVersion())
|
|
44
44
|
|
|
45
45
|
registerInit(program)
|
package/src/commands/add.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import type { Command } from "commander"
|
|
2
2
|
import { p, runClackFlow } from "../ui/clack.js"
|
|
3
|
-
import { loadConfig } from "../config.js"
|
|
3
|
+
import { loadConfig, rethrowIfConfigBroken } from "../config.js"
|
|
4
4
|
import { selfHostTlsEnabled } from "../project-config.js"
|
|
5
5
|
import { updateServerConfigInProject } from "../app-config.js"
|
|
6
6
|
import { ensureNotCancelled } from "../ui/prompts.js"
|
|
@@ -82,7 +82,8 @@ function printDomainNextSteps(cwd: string, domain: string): void {
|
|
|
82
82
|
let tlsActive = true
|
|
83
83
|
try {
|
|
84
84
|
tlsActive = selfHostTlsEnabled(loadConfig(cwd))
|
|
85
|
-
} catch {
|
|
85
|
+
} catch (err) {
|
|
86
|
+
rethrowIfConfigBroken(err)
|
|
86
87
|
// config re-load is best-effort for the warning below
|
|
87
88
|
}
|
|
88
89
|
|
|
@@ -99,6 +100,6 @@ function printDomainNextSteps(cwd: string, domain: string): void {
|
|
|
99
100
|
"supatype self-host compose up -d # Kong provisions HTTPS automatically",
|
|
100
101
|
`Platform URL: https://${domain}`,
|
|
101
102
|
])
|
|
102
|
-
plain(" App, REST, Auth, Storage, Realtime, Functions, and Studio
|
|
103
|
+
plain(" App, REST, Auth, Storage, Realtime, Functions, and Studio, one HTTPS domain.")
|
|
103
104
|
plain(" Certificates persist in the valkey-data volume.\n")
|
|
104
105
|
}
|
package/src/commands/admin.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
// ─── Admin panel CLI commands (Gap Appendices task 48) ──────────────────────
|
|
2
2
|
//
|
|
3
|
-
// `npx supatype admin create-user
|
|
3
|
+
// `npx supatype admin create-user`, create an admin user in the project's
|
|
4
4
|
// auth.users table. First admin is ensured on `supatype dev` or `supatype push`.
|
|
5
5
|
|
|
6
6
|
import type { Command } from "commander"
|
|
@@ -242,7 +242,7 @@ export function registerAdmin(program: Command): void {
|
|
|
242
242
|
const pool = new pg.Pool({ connectionString: connection, max: 2 })
|
|
243
243
|
|
|
244
244
|
try {
|
|
245
|
-
// Studio access is membership, not a claim
|
|
245
|
+
// Studio access is membership, not a claim, list the grant that
|
|
246
246
|
// actually decides admission. LEFT JOIN, because a membership held by a
|
|
247
247
|
// Supatype Cloud account has no row in this project's `auth.users`;
|
|
248
248
|
// hiding those would make `list-users` disagree with who can log in.
|
|
@@ -308,7 +308,7 @@ export async function ensureFirstAdminUser(
|
|
|
308
308
|
options,
|
|
309
309
|
)
|
|
310
310
|
} catch {
|
|
311
|
-
// Non-fatal
|
|
311
|
+
// Non-fatal: skip when DB is unreachable or auth schema is not ready
|
|
312
312
|
} finally {
|
|
313
313
|
await pool.end()
|
|
314
314
|
}
|
|
@@ -528,7 +528,7 @@ async function createAdminUser(
|
|
|
528
528
|
* the developer's own app roles, and letting it grant Studio access means a
|
|
529
529
|
* developer assigning an app role could hand out admin UI access by accident.
|
|
530
530
|
*
|
|
531
|
-
* This is now the *only* grant, so a failure here is fatal to the command
|
|
531
|
+
* This is now the *only* grant, so a failure here is fatal to the command, a
|
|
532
532
|
* user created without a membership row cannot reach Studio at all, and
|
|
533
533
|
* reporting success would leave no clue why.
|
|
534
534
|
*/
|
|
@@ -591,12 +591,12 @@ async function authUsersTableExists(query: DbQuery): Promise<boolean> {
|
|
|
591
591
|
*
|
|
592
592
|
* Counts membership rows, not `app_metadata` claims: the claim no longer grants
|
|
593
593
|
* anything, so counting it would report an admin exists while nobody can log in.
|
|
594
|
-
* A missing table means the project has never been pushed
|
|
594
|
+
* A missing table means the project has never been pushed, no admins.
|
|
595
595
|
*/
|
|
596
596
|
async function hasAdminUsers(query: DbQuery): Promise<boolean> {
|
|
597
597
|
// Postgres resolves relations at parse time, so the table has to be checked
|
|
598
598
|
// separately rather than guarded inside the count query. Absent means the
|
|
599
|
-
// project has never been pushed
|
|
599
|
+
// project has never been pushed, no admins, and `createAdminUser` will
|
|
600
600
|
// create the table itself.
|
|
601
601
|
if (!(await studioMembersTableExists(query))) return false
|
|
602
602
|
|
package/src/commands/adopt.ts
CHANGED
|
@@ -54,7 +54,7 @@ export function registerAdopt(program: Command): void {
|
|
|
54
54
|
|
|
55
55
|
const statements = preview.stampStatements ?? []
|
|
56
56
|
if (statements.length === 0) {
|
|
57
|
-
info("Nothing to stamp
|
|
57
|
+
info("Nothing to stamp: matching objects are already managed or absent.")
|
|
58
58
|
return
|
|
59
59
|
}
|
|
60
60
|
|
package/src/commands/app.ts
CHANGED
|
@@ -17,7 +17,7 @@ export function registerApp(program: Command): void {
|
|
|
17
17
|
.option("--static", "Serve a static directory at / (default: ./public, or [dir] argument)")
|
|
18
18
|
.option("--port <port>", "Port your app listens on (proxy mode)", "3000")
|
|
19
19
|
.option("--upstream <url>", "URL of your running dev server (proxy mode; defaults to localhost:<port>)")
|
|
20
|
-
.option("--dockerfile <path>", "(deprecated) ignored
|
|
20
|
+
.option("--dockerfile <path>", "(deprecated) ignored, use supatype.config.ts")
|
|
21
21
|
.action(
|
|
22
22
|
(
|
|
23
23
|
dir: string | undefined,
|
|
@@ -80,7 +80,7 @@ function addProxyApp(cwd: string, port: string, upstream?: string): void {
|
|
|
80
80
|
try {
|
|
81
81
|
const configPath = updateAppConfigInProject(cwd, { mode: "proxy", upstream: upstreamUrl })
|
|
82
82
|
file("updated", configPath)
|
|
83
|
-
info(`Forwarding to ${upstreamUrl}
|
|
83
|
+
info(`Forwarding to ${upstreamUrl}: app at ${localKongBaseUrl()}/`)
|
|
84
84
|
nextSteps("Next:", ["supatype self-host compose render"])
|
|
85
85
|
} catch (err) {
|
|
86
86
|
error((err as Error).message)
|
package/src/commands/cache.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* supatype cache
|
|
2
|
+
* supatype cache: list and clean cached component binaries + REST Valkey cache.
|
|
3
3
|
*/
|
|
4
4
|
|
|
5
5
|
import type { Command } from "commander"
|
|
@@ -126,7 +126,7 @@ export function registerCache(program: Command): void {
|
|
|
126
126
|
if (result.removed.length === 0 && result.skipped.length === 0) {
|
|
127
127
|
info("Nothing to clean.")
|
|
128
128
|
} else if (opts?.dryRun) {
|
|
129
|
-
info(`Dry run
|
|
129
|
+
info(`Dry run: ${result.removed.length} entr${result.removed.length === 1 ? "y" : "ies"} would be removed.`)
|
|
130
130
|
} else {
|
|
131
131
|
info("Done.")
|
|
132
132
|
}
|
|
@@ -160,7 +160,7 @@ export function registerCache(program: Command): void {
|
|
|
160
160
|
)
|
|
161
161
|
}
|
|
162
162
|
if (result.cursor !== "0") {
|
|
163
|
-
plain(`\n(more available
|
|
163
|
+
plain(`\n(more available: cursor ${result.cursor})`)
|
|
164
164
|
}
|
|
165
165
|
} catch (e) {
|
|
166
166
|
error(e instanceof Error ? e.message : String(e))
|
package/src/commands/db.ts
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Database connection commands:
|
|
3
|
-
* supatype db connection-string
|
|
4
|
-
* supatype db reset-password
|
|
5
|
-
* supatype db check
|
|
3
|
+
* supatype db connection-string: show the connection string for the linked project
|
|
4
|
+
* supatype db reset-password: reset the database password
|
|
5
|
+
* supatype db check: does this database meet what Supatype needs of it?
|
|
6
6
|
*/
|
|
7
7
|
|
|
8
8
|
import type { Command } from "commander"
|
|
9
|
-
import { loadConfig } from "../config.js"
|
|
9
|
+
import { loadConfig, rethrowIfConfigBroken } from "../config.js"
|
|
10
10
|
import { connectionString } from "../project-config.js"
|
|
11
11
|
import { loadProjectLink } from "../link.js"
|
|
12
12
|
import { resolveTarget } from "../resolve-target.js"
|
|
@@ -153,8 +153,9 @@ export function registerDb(program: Command): void {
|
|
|
153
153
|
const config = loadConfig(cwd)
|
|
154
154
|
url = url ?? connectionString(config)
|
|
155
155
|
schema = schema ?? config.schema?.pg_schema ?? "public"
|
|
156
|
-
} catch {
|
|
157
|
-
|
|
156
|
+
} catch (err) {
|
|
157
|
+
rethrowIfConfigBroken(err)
|
|
158
|
+
// Runnable outside a project, which is the point, an operator should be able to check a
|
|
158
159
|
// database before committing to any config at all.
|
|
159
160
|
url = url ?? process.env["DATABASE_URL"]
|
|
160
161
|
schema = schema ?? "public"
|
|
@@ -190,7 +191,7 @@ export function registerDb(program: Command): void {
|
|
|
190
191
|
if (opts.emit) {
|
|
191
192
|
// Machine-consumable: SQL on stdout, commentary on stderr, so it can be piped to psql.
|
|
192
193
|
if (fixable.length === 0) {
|
|
193
|
-
warn("Nothing to emit
|
|
194
|
+
warn("Nothing to emit: no SQL-fixable findings.")
|
|
194
195
|
} else {
|
|
195
196
|
plain("BEGIN;")
|
|
196
197
|
for (const r of fixable) plain(`\n-- ${r.title}\n${r.remedy}`)
|
|
@@ -198,7 +199,7 @@ export function registerDb(program: Command): void {
|
|
|
198
199
|
}
|
|
199
200
|
if (manual.length > 0) {
|
|
200
201
|
warn(`\n${manual.length} finding(s) need operator action and are not included above:`)
|
|
201
|
-
for (const r of manual) warn(` ${r.title}
|
|
202
|
+
for (const r of manual) warn(` ${r.title}, ${r.detail}`)
|
|
202
203
|
}
|
|
203
204
|
return
|
|
204
205
|
}
|
|
@@ -224,7 +225,7 @@ export function registerDb(program: Command): void {
|
|
|
224
225
|
await applyRemedies(client, fixable)
|
|
225
226
|
info("Applied. Re-run `supatype db check` to confirm.")
|
|
226
227
|
} catch (err) {
|
|
227
|
-
error(`Rolled back
|
|
228
|
+
error(`Rolled back: the database is unchanged: ${(err as Error).message}`)
|
|
228
229
|
process.exitCode = 1
|
|
229
230
|
return
|
|
230
231
|
}
|
|
@@ -232,7 +233,7 @@ export function registerDb(program: Command): void {
|
|
|
232
233
|
if (manual.length > 0) {
|
|
233
234
|
warn(`\n${manual.length} finding(s) cannot be fixed in a transaction:`)
|
|
234
235
|
for (const r of manual) {
|
|
235
|
-
warn(` ${r.title}
|
|
236
|
+
warn(` ${r.title}: needs a server setting change and likely a restart`)
|
|
236
237
|
}
|
|
237
238
|
}
|
|
238
239
|
return
|
|
@@ -265,7 +266,7 @@ const SEVERITY_LABEL: Record<Severity, string> = {
|
|
|
265
266
|
|
|
266
267
|
function printReport(results: readonly CheckResult[]): void {
|
|
267
268
|
for (const r of results) {
|
|
268
|
-
const line = `[${SEVERITY_LABEL[r.severity]}] ${r.title}
|
|
269
|
+
const line = `[${SEVERITY_LABEL[r.severity]}] ${r.title}, ${r.detail}`
|
|
269
270
|
if (r.severity === "fail") error(line)
|
|
270
271
|
else if (r.severity === "degrade" || r.severity === "warn") warn(line)
|
|
271
272
|
else plain(line)
|
package/src/commands/deploy.ts
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Deploy commands:
|
|
3
|
-
* supatype deploy
|
|
4
|
-
* supatype deploy --local
|
|
5
|
-
* supatype deploy --app-only
|
|
6
|
-
* supatype deploy --schema-only
|
|
7
|
-
* supatype deploy --skip-build
|
|
8
|
-
* supatype deploy --preview
|
|
9
|
-
* supatype deploy rollback
|
|
10
|
-
* supatype deploy status
|
|
11
|
-
* supatype deploy logs <version
|
|
3
|
+
* supatype deploy: Supatype Cloud by default (linked via supatype link), else platform projectRef; use --local for engine + DB
|
|
4
|
+
* supatype deploy --local: push schema via local engine + optional static app to .supatype/static
|
|
5
|
+
* supatype deploy --app-only: only build & deploy the static site
|
|
6
|
+
* supatype deploy --schema-only: only push schema changes
|
|
7
|
+
* supatype deploy --skip-build: deploy existing build output (no build step)
|
|
8
|
+
* supatype deploy --preview: deploy to a preview URL
|
|
9
|
+
* supatype deploy rollback: roll back to previous deployment
|
|
10
|
+
* supatype deploy status: show current deployment info
|
|
11
|
+
* supatype deploy logs <version>, show build logs
|
|
12
12
|
*/
|
|
13
13
|
|
|
14
14
|
import type { Command } from "commander"
|
|
@@ -31,7 +31,7 @@ export function registerDeploy(program: Command): void {
|
|
|
31
31
|
const deploy = program
|
|
32
32
|
.command("deploy")
|
|
33
33
|
.description(
|
|
34
|
-
"Deploy schema and app
|
|
34
|
+
"Deploy schema and app, Supatype Cloud by default when linked (`supatype link`); pass --local for engine + your database",
|
|
35
35
|
)
|
|
36
36
|
.option("--local", "Use local schema engine and database_url from config (skip cloud control plane)")
|
|
37
37
|
.option("--environment <name>", "Target environment when linked", "production")
|
|
@@ -119,7 +119,7 @@ export function registerDeploy(program: Command): void {
|
|
|
119
119
|
error("No build section found in supatype.config.ts")
|
|
120
120
|
process.exit(1)
|
|
121
121
|
}
|
|
122
|
-
// No build config
|
|
122
|
+
// No build config: skip app deployment silently
|
|
123
123
|
return
|
|
124
124
|
}
|
|
125
125
|
|
|
@@ -151,7 +151,7 @@ export function registerDeploy(program: Command): void {
|
|
|
151
151
|
buildEnv["NEXT_PUBLIC_SUPATYPE_URL"] = cloudCfg.apiUrl || `https://${cloudCfg.projectSlug}.supatype.dev`
|
|
152
152
|
buildEnv["VITE_SUPATYPE_URL"] = buildEnv["NEXT_PUBLIC_SUPATYPE_URL"]!
|
|
153
153
|
buildEnv["PUBLIC_SUPATYPE_URL"] = buildEnv["NEXT_PUBLIC_SUPATYPE_URL"]!
|
|
154
|
-
// NEVER inject service_role key
|
|
154
|
+
// NEVER inject service_role key, only anon key is safe for client-side
|
|
155
155
|
}
|
|
156
156
|
|
|
157
157
|
// Install dependencies
|