@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/commands/dev.ts
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* supatype dev
|
|
2
|
+
* supatype dev: start local Postgres, apply schema, run supatype-server.
|
|
3
3
|
*
|
|
4
4
|
* Runtime provider (top-level `provider` or legacy `database.provider`):
|
|
5
|
-
* native
|
|
6
|
-
* docker
|
|
5
|
+
* native: host Postgres + host server + host engine (default)
|
|
6
|
+
* docker: full self-host Compose stack (Kong :18473); see dev-compose.ts
|
|
7
7
|
*
|
|
8
8
|
* Edge functions (when a functions/ dir exists): Deno is resolved from the CDN cache
|
|
9
9
|
* (auto-download on miss). Self-host/cloud Docker stacks use supatype-server in-container;
|
|
@@ -127,7 +127,7 @@ export function registerDev(program: Command): void {
|
|
|
127
127
|
.action(async (opts: { watch: boolean; stream?: boolean; port?: string }) => {
|
|
128
128
|
const cwd = process.cwd()
|
|
129
129
|
|
|
130
|
-
// ── 1. Load project config (before TUI
|
|
130
|
+
// ── 1. Load project config (before TUI, fatal errors must hit real stderr) ──
|
|
131
131
|
const config = loadConfig(cwd)
|
|
132
132
|
const provider = resolveRuntimeProvider(config)
|
|
133
133
|
|
|
@@ -181,7 +181,7 @@ export function registerDev(program: Command): void {
|
|
|
181
181
|
|
|
182
182
|
// ── 5–7. Start Postgres ───────────────────────────────────────────────
|
|
183
183
|
let dbURL: string
|
|
184
|
-
/** What PostgREST connects as
|
|
184
|
+
/** What PostgREST connects as, deliberately not `dbURL`, which is a superuser. */
|
|
185
185
|
let postgrestDbURL: string
|
|
186
186
|
let stopPostgres: () => void | Promise<void>
|
|
187
187
|
const pgPort = NATIVE_PG_PORT
|
|
@@ -195,7 +195,7 @@ export function registerDev(program: Command): void {
|
|
|
195
195
|
let pgBinDir: string | null = null
|
|
196
196
|
|
|
197
197
|
{
|
|
198
|
-
// native
|
|
198
|
+
// native: resolve pg bin dir and manage with pg_ctl
|
|
199
199
|
pgBinDir = await resolvePgBinDir(config)
|
|
200
200
|
const dataDir = config.database.data_dir ?? join(stateRoot, "data")
|
|
201
201
|
mkdirSync(dataDir, { recursive: true })
|
|
@@ -239,7 +239,7 @@ export function registerDev(program: Command): void {
|
|
|
239
239
|
//
|
|
240
240
|
// `authenticator` is NOINHERIT and holds no privileges of its own: it can only
|
|
241
241
|
// SET ROLE to the three above. That containment is the point. Connecting as
|
|
242
|
-
// `postgres
|
|
242
|
+
// `postgres`: a superuser: meant a request whose JWT named *any* role in the
|
|
243
243
|
// cluster got it, because a superuser may SET ROLE to anything. Verified: as
|
|
244
244
|
// postgres, `SET ROLE supatype_replication_admin` succeeds; as authenticator the
|
|
245
245
|
// same statement is refused. Mirrors the image, which has had this role all along.
|
|
@@ -300,7 +300,7 @@ ALTER DEFAULT PRIVILEGES IN SCHEMA public GRANT ALL ON SEQUENCES TO authenticate
|
|
|
300
300
|
mkdirSync(supatypeDir, { recursive: true })
|
|
301
301
|
|
|
302
302
|
const localStoragePath = config.storage?.provider !== "s3" ? join(stateRoot, "storage") : undefined
|
|
303
|
-
// Native Postgres builds don't include PostGIS
|
|
303
|
+
// Native Postgres builds don't include PostGIS, skip geo fields rather than failing.
|
|
304
304
|
const skipFieldKinds: ReadonlySet<string> = new Set(["geo", "vector"])
|
|
305
305
|
|
|
306
306
|
await runSchemaPush(cwd, engineBin, schemaPath, dbURL, manifestPath, adminConfigPath, localStoragePath, skipFieldKinds, config).catch(
|
|
@@ -341,7 +341,7 @@ ALTER DEFAULT PRIVILEGES IN SCHEMA public GRANT ALL ON SEQUENCES TO authenticate
|
|
|
341
341
|
}
|
|
342
342
|
} catch (err) {
|
|
343
343
|
console.warn(
|
|
344
|
-
`[supatype] ⚠ Found ${functionsDir} but could not provision Deno
|
|
344
|
+
`[supatype] ⚠ Found ${functionsDir} but could not provision Deno, edge functions will not run.\n` +
|
|
345
345
|
` ${(err as Error).message}\n` +
|
|
346
346
|
" (Functions still appear in Studio; invocations need Deno.)",
|
|
347
347
|
)
|
|
@@ -383,7 +383,7 @@ ALTER DEFAULT PRIVILEGES IN SCHEMA public GRANT ALL ON SEQUENCES TO authenticate
|
|
|
383
383
|
console.log(`[supatype] Realtime service: ${realtimeUrl}`)
|
|
384
384
|
} catch (err) {
|
|
385
385
|
console.warn(
|
|
386
|
-
`[supatype] ⚠ Realtime unavailable
|
|
386
|
+
`[supatype] ⚠ Realtime unavailable, WebSocket subscriptions will not work.\n` +
|
|
387
387
|
` ${(err as Error).message}`,
|
|
388
388
|
)
|
|
389
389
|
}
|
|
@@ -509,10 +509,10 @@ ALTER DEFAULT PRIVILEGES IN SCHEMA public GRANT ALL ON SEQUENCES TO authenticate
|
|
|
509
509
|
|
|
510
510
|
const postgrestEnv: Record<string, string> = {
|
|
511
511
|
PGRST_DB_URI: postgrestDbURL,
|
|
512
|
-
// Derived from schema.pg_schema (or schema.api_schemas)
|
|
512
|
+
// Derived from schema.pg_schema (or schema.api_schemas), a hardcoded "public" here meant
|
|
513
513
|
// a non-default pg_schema pushed correctly and then answered PGRST106 on every request.
|
|
514
514
|
// Native dev has no masking extension either, so a schema with field rules is served from
|
|
515
|
-
// `api` here too
|
|
515
|
+
// `api` here too: the case an "is the database external" rule would have got wrong.
|
|
516
516
|
PGRST_DB_SCHEMA: apiSchemaList(
|
|
517
517
|
config,
|
|
518
518
|
// The installed archive decides: one downloaded before the masking library was bundled
|
|
@@ -644,9 +644,9 @@ ALTER DEFAULT PRIVILEGES IN SCHEMA public GRANT ALL ON SEQUENCES TO authenticate
|
|
|
644
644
|
// Schema push (engine subprocess)
|
|
645
645
|
// ---------------------------------------------------------------------------
|
|
646
646
|
|
|
647
|
-
// Last successfully-pushed AST JSON
|
|
647
|
+
// Last successfully-pushed AST JSON, used to skip no-op re-fires.
|
|
648
648
|
let _lastPushedAst: string | null = null
|
|
649
|
-
// AST that failed on its last attempt
|
|
649
|
+
// AST that failed on its last attempt, always retried even if content is unchanged.
|
|
650
650
|
let _lastFailedAst: string | null = null
|
|
651
651
|
|
|
652
652
|
async function runSchemaPush(
|
|
@@ -670,7 +670,7 @@ async function runSchemaPush(
|
|
|
670
670
|
ast = filtered
|
|
671
671
|
if (adapted.length > 0) {
|
|
672
672
|
console.warn(
|
|
673
|
-
`[supatype] ⚠ ${adapted.length} field(s) replaced with JSONB
|
|
673
|
+
`[supatype] ⚠ ${adapted.length} field(s) replaced with JSONB, required extensions not available:\n` +
|
|
674
674
|
adapted.map((s: string) => ` ${s}`).join("\n"),
|
|
675
675
|
)
|
|
676
676
|
}
|
|
@@ -744,7 +744,7 @@ async function runSchemaPush(
|
|
|
744
744
|
{ cwd, stdio: "pipe", encoding: "utf8" },
|
|
745
745
|
)
|
|
746
746
|
if (genResult.status !== 0) {
|
|
747
|
-
console.warn("[supatype] Manifest generation failed
|
|
747
|
+
console.warn("[supatype] Manifest generation failed, server routing may be stale.")
|
|
748
748
|
}
|
|
749
749
|
|
|
750
750
|
// Generate admin config (for Studio). Engine writes to stdout.
|
|
@@ -889,7 +889,7 @@ async function extractPostgresArchive(
|
|
|
889
889
|
}
|
|
890
890
|
|
|
891
891
|
// ---------------------------------------------------------------------------
|
|
892
|
-
// PostgREST resolver
|
|
892
|
+
// PostgREST resolver: downloads from GitHub releases if not cached
|
|
893
893
|
// ---------------------------------------------------------------------------
|
|
894
894
|
|
|
895
895
|
const POSTGREST_DEFAULT_VERSION = "12.2.3"
|
|
@@ -1030,12 +1030,12 @@ function repairWindowsPostgrestRuntime(cacheDir: string, archivePath: string, bi
|
|
|
1030
1030
|
}
|
|
1031
1031
|
|
|
1032
1032
|
// ---------------------------------------------------------------------------
|
|
1033
|
-
// Local-dev JWT generator (no external dep
|
|
1033
|
+
// Local-dev JWT generator (no external dep, pure crypto)
|
|
1034
1034
|
// ---------------------------------------------------------------------------
|
|
1035
1035
|
|
|
1036
1036
|
|
|
1037
1037
|
// ---------------------------------------------------------------------------
|
|
1038
|
-
// AST adaptation
|
|
1038
|
+
// AST adaptation: replace extension-dependent fields with JSONB fallbacks
|
|
1039
1039
|
// ---------------------------------------------------------------------------
|
|
1040
1040
|
|
|
1041
1041
|
interface AstField { kind: string; required?: boolean; [k: string]: unknown }
|
package/src/commands/doctor.ts
CHANGED
|
@@ -114,7 +114,7 @@ export function registerDoctor(program: Command): void {
|
|
|
114
114
|
* Whether declared hooks can actually run.
|
|
115
115
|
*
|
|
116
116
|
* Worth its own section because every failure here is silent: a hook whose function is missing, or a
|
|
117
|
-
* stack with functions switched off, produces no error anywhere
|
|
117
|
+
* stack with functions switched off, produces no error anywhere, the write just succeeds
|
|
118
118
|
* unvalidated. Drift you cannot see is the thing doctor exists for.
|
|
119
119
|
*/
|
|
120
120
|
export function printHooks(report: HooksReport): void {
|
|
@@ -133,7 +133,7 @@ export function printHooks(report: HooksReport): void {
|
|
|
133
133
|
plain(" Create it with: supatype hooks new <name>")
|
|
134
134
|
}
|
|
135
135
|
if (report.functionsDisabled) {
|
|
136
|
-
plain("\n functions_enabled is false in .supatype/manifest.json
|
|
136
|
+
plain("\n functions_enabled is false in .supatype/manifest.json, every hook is inert.")
|
|
137
137
|
plain(" Regenerate the stack config with: supatype self-host compose")
|
|
138
138
|
}
|
|
139
139
|
if (report.mapMissing) {
|
|
@@ -162,7 +162,7 @@ export function printServiceRoleGrants(
|
|
|
162
162
|
}
|
|
163
163
|
|
|
164
164
|
if (broken.size > 0) {
|
|
165
|
-
plain("\n Those marked ✗ match no function, so they grant nothing
|
|
165
|
+
plain("\n Those marked ✗ match no function, so they grant nothing, the function reads no key.")
|
|
166
166
|
}
|
|
167
167
|
for (const warning of problems.warnings) plain(warning)
|
|
168
168
|
plain("\n These functions bypass every access rule in the schema. Anything not listed cannot.")
|
package/src/commands/engine.ts
CHANGED
|
@@ -11,7 +11,7 @@ import {
|
|
|
11
11
|
import { resolve, join, basename, relative, isAbsolute } from "node:path"
|
|
12
12
|
import { spawnSync, execSync } from "node:child_process"
|
|
13
13
|
import { localKongBaseUrl } from "../local-gateway.js"
|
|
14
|
-
import { loadConfig } from "../config.js"
|
|
14
|
+
import { loadConfig, rethrowIfConfigBroken } from "../config.js"
|
|
15
15
|
import { ensureBinary } from "../ensure-binary.js"
|
|
16
16
|
import {
|
|
17
17
|
functionsPathCandidatesFromProject,
|
|
@@ -138,7 +138,7 @@ function scaffoldFunction(cwd: string, name: string): void {
|
|
|
138
138
|
|
|
139
139
|
mkdirSync(fnDir, { recursive: true })
|
|
140
140
|
|
|
141
|
-
const indexContent = `// ${name}
|
|
141
|
+
const indexContent = `// ${name}, Supatype Edge Function
|
|
142
142
|
// Docs: https://supatype.com/docs/edge-functions
|
|
143
143
|
|
|
144
144
|
export default async function handler(req: Request): Promise<Response> {
|
|
@@ -257,7 +257,7 @@ function discoverFunctions(cwd: string): DiscoveredFunction[] {
|
|
|
257
257
|
const stat = statSync(fullPath)
|
|
258
258
|
|
|
259
259
|
if (stat.isDirectory()) {
|
|
260
|
-
// Directory function
|
|
260
|
+
// Directory function: look for index.ts
|
|
261
261
|
const indexPath = join(fullPath, "index.ts")
|
|
262
262
|
if (existsSync(indexPath)) {
|
|
263
263
|
fns.push({ name: entry, entrypoint: indexPath, absPath: fullPath })
|
|
@@ -369,7 +369,7 @@ async function deploy(cwd: string, opts: { only?: string; env?: string; dryRun?:
|
|
|
369
369
|
}
|
|
370
370
|
|
|
371
371
|
if (opts.dryRun) {
|
|
372
|
-
plain("Dry run
|
|
372
|
+
plain("Dry run: the following functions would be deployed:\n")
|
|
373
373
|
for (const fn of fns) {
|
|
374
374
|
plain(` ${fn.name} → ${relative(cwd, fn.entrypoint)}`)
|
|
375
375
|
}
|
|
@@ -532,7 +532,8 @@ async function deployCloud(cwd: string, fns: DiscoveredFunction[], env?: string)
|
|
|
532
532
|
export function serviceRoleRoutesFor(cwd: string): string[] | undefined {
|
|
533
533
|
try {
|
|
534
534
|
return serviceRoleRoutes(loadConfig(cwd))
|
|
535
|
-
} catch {
|
|
535
|
+
} catch (err) {
|
|
536
|
+
rethrowIfConfigBroken(err)
|
|
536
537
|
return undefined
|
|
537
538
|
}
|
|
538
539
|
}
|
|
@@ -543,7 +544,7 @@ function readFunctionSource(fn: DiscoveredFunction): string {
|
|
|
543
544
|
return readFileSync(fn.absPath, "utf8")
|
|
544
545
|
}
|
|
545
546
|
|
|
546
|
-
// Directory function
|
|
547
|
+
// Directory function: read all .ts files
|
|
547
548
|
const files: Record<string, string> = {}
|
|
548
549
|
const entries = readdirSync(fn.absPath, { recursive: true }) as string[]
|
|
549
550
|
for (const entry of entries) {
|
|
@@ -607,7 +608,7 @@ async function listFunctions(cwd: string): Promise<void> {
|
|
|
607
608
|
plain(` ${"─".repeat(28)} ${"─".repeat(24)} ${"─".repeat(20)} ${"─".repeat(12)}`)
|
|
608
609
|
|
|
609
610
|
for (const fn of data) {
|
|
610
|
-
const deployed = fn.deployedAt ? new Date(fn.deployedAt).toLocaleString() : "
|
|
611
|
+
const deployed = fn.deployedAt ? new Date(fn.deployedAt).toLocaleString() : "-"
|
|
611
612
|
plain(
|
|
612
613
|
` ${fn.name.padEnd(28)} ${deployed.padEnd(24)} ${String(fn.invocations24h ?? 0).padEnd(20)} ${fn.avgDurationMs ?? 0}ms`,
|
|
613
614
|
)
|
package/src/commands/hooks.ts
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* `supatype hooks
|
|
2
|
+
* `supatype hooks`: scaffold and inspect model hooks.
|
|
3
3
|
*
|
|
4
4
|
* Separate from `supatype functions` because the two are different things wearing the same runtime.
|
|
5
5
|
* A function is a **public endpoint**: anyone holding the anon key can invoke it. A hook is
|
|
6
|
-
* **procedural
|
|
6
|
+
* **procedural**: only the API server calls it, around a write, and the gateway refuses the route
|
|
7
7
|
* from outside. Keeping them in separate directories is what makes that boundary structural instead
|
|
8
8
|
* of a list somebody has to maintain.
|
|
9
9
|
*/
|
|
@@ -85,7 +85,7 @@ function scaffoldHook(cwd: string, name: string): void {
|
|
|
85
85
|
/**
|
|
86
86
|
* The scaffold deliberately imports from `../_supatype/hooks.ts`, which `push` generates.
|
|
87
87
|
*
|
|
88
|
-
* Before the first push that file does not exist, so the handler will not compile
|
|
88
|
+
* Before the first push that file does not exist, so the handler will not compile, which is the
|
|
89
89
|
* honest state: the types come from the schema, and a handler typed against a model that has not been
|
|
90
90
|
* pushed is a handler typed against a guess.
|
|
91
91
|
*/
|
|
@@ -94,7 +94,7 @@ function handlerTemplate(name: string, declared: { model: string; event: string
|
|
|
94
94
|
const model = declared[0]?.model ?? "YourModel"
|
|
95
95
|
|
|
96
96
|
if (event.startsWith("after")) {
|
|
97
|
-
return `// ${name}
|
|
97
|
+
return `// ${name}: model hook (${event})
|
|
98
98
|
//
|
|
99
99
|
// Runs after the write has succeeded. It cannot change or undo it: a rejection here would be a
|
|
100
100
|
// rejection of something that already happened. Failures are logged, not surfaced to the caller.
|
|
@@ -109,7 +109,7 @@ export default hook(handler)
|
|
|
109
109
|
`
|
|
110
110
|
}
|
|
111
111
|
|
|
112
|
-
return `// ${name}
|
|
112
|
+
return `// ${name}: model hook (${event}) for ${model}
|
|
113
113
|
//
|
|
114
114
|
// Runs before the write reaches Postgres, so it can reject it or rewrite the body.
|
|
115
115
|
//
|
|
@@ -125,7 +125,7 @@ const handler: BeforeChange<"your_table"> = async (ctx) => {
|
|
|
125
125
|
}
|
|
126
126
|
|
|
127
127
|
// \`ctx.patch\` is the submitted partial; \`ctx.previous()\` reads the rows about to change.
|
|
128
|
-
// Those come back as stored
|
|
128
|
+
// Those come back as stored, unmasked, so do not echo them into a rejection message.
|
|
129
129
|
return {}
|
|
130
130
|
|
|
131
131
|
// Reject with a message the caller sees, and a status of your choosing:
|
package/src/commands/init.ts
CHANGED
|
@@ -248,7 +248,7 @@ interface InteractiveInitArgs {
|
|
|
248
248
|
opts: InitCliOptions
|
|
249
249
|
}
|
|
250
250
|
|
|
251
|
-
/** Interactive init
|
|
251
|
+
/** Interactive init: one Ink session for wizard + scaffold + install + finish. */
|
|
252
252
|
async function runInteractiveInit(args: InteractiveInitArgs): Promise<void> {
|
|
253
253
|
const { name, dir, defaultName, modeTarget, opts } = args
|
|
254
254
|
|
|
@@ -501,7 +501,7 @@ async function promptAdminUser(): Promise<{ adminEmail?: string; adminPassword?:
|
|
|
501
501
|
)
|
|
502
502
|
if (!createAdmin) return {}
|
|
503
503
|
|
|
504
|
-
p.note("First sign-in at /admin
|
|
504
|
+
p.note("First sign-in at /admin, created automatically on supatype dev or push.")
|
|
505
505
|
|
|
506
506
|
const adminEmail = ensureNotCancelled(
|
|
507
507
|
await p.text({
|
|
@@ -686,7 +686,7 @@ export function scaffold(
|
|
|
686
686
|
writeFileSync(pkgPath, `${JSON.stringify(merged, null, 2)}\n`, "utf8")
|
|
687
687
|
file("updated", "package.json (added Supatype dependencies)")
|
|
688
688
|
} catch {
|
|
689
|
-
warn("Could not merge into package.json
|
|
689
|
+
warn("Could not merge into package.json, add @supatype/cli and @supatype/types manually.")
|
|
690
690
|
file("skipped", "package.json (invalid JSON)")
|
|
691
691
|
}
|
|
692
692
|
}
|
|
@@ -891,7 +891,7 @@ function localConfigTemplate(app: ScaffoldAppOptions): string {
|
|
|
891
891
|
const lines: string[] = [
|
|
892
892
|
`import type { SupatypeConfig } from "@supatype/cli"`,
|
|
893
893
|
``,
|
|
894
|
-
`// Local development overrides
|
|
894
|
+
`// Local development overrides, gitignored, deep-merged over supatype.config.ts.`,
|
|
895
895
|
`// Keeps \`supatype dev\` in local mode while the committed config targets production.`,
|
|
896
896
|
`const localConfig: Partial<SupatypeConfig> = {`,
|
|
897
897
|
` server: { mode: "dev" },`,
|
|
@@ -997,8 +997,8 @@ function holdingPageTemplate(projectName: string): string {
|
|
|
997
997
|
<head>
|
|
998
998
|
<meta charset="UTF-8" />
|
|
999
999
|
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
|
1000
|
-
<title>${name}
|
|
1001
|
-
<meta name="description" content="A Supatype project. Define your types
|
|
1000
|
+
<title>${name}: Supatype</title>
|
|
1001
|
+
<meta name="description" content="A Supatype project. Define your types, we generate your platform." />
|
|
1002
1002
|
<link rel="preconnect" href="https://fonts.googleapis.com" />
|
|
1003
1003
|
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin />
|
|
1004
1004
|
<link href="https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700&display=swap" rel="stylesheet" />
|
|
@@ -1146,12 +1146,12 @@ function storageConfigLines(
|
|
|
1146
1146
|
): string[] {
|
|
1147
1147
|
const lines: string[] = []
|
|
1148
1148
|
if (storageLocal === "s3") {
|
|
1149
|
-
lines.push(` storage: { provider: "s3" }, // dev
|
|
1149
|
+
lines.push(` storage: { provider: "s3" }, // dev, configure S3_* in .env`)
|
|
1150
1150
|
} else {
|
|
1151
1151
|
lines.push(` storage: { provider: "local", local_path: ".supatype/storage" },`)
|
|
1152
1152
|
}
|
|
1153
1153
|
if (storageProduction === "s3" && storageLocal !== "s3") {
|
|
1154
|
-
lines.push(` // Production storage: external S3 bucket
|
|
1154
|
+
lines.push(` // Production storage: external S3 bucket, set production S3_* in .env`)
|
|
1155
1155
|
} else if (storageProduction === "local" && storageLocal === "s3") {
|
|
1156
1156
|
lines.push(` // Production storage: MinIO on your server (included in self-host compose)`)
|
|
1157
1157
|
}
|
|
@@ -1174,7 +1174,7 @@ export type Profile = Model<{
|
|
|
1174
1174
|
}
|
|
1175
1175
|
}>
|
|
1176
1176
|
|
|
1177
|
-
/** Example singleton global
|
|
1177
|
+
/** Example singleton global: editable in Studio under Settings. */
|
|
1178
1178
|
export type SiteSettings = Model<{
|
|
1179
1179
|
id: UUID
|
|
1180
1180
|
site_name: string
|
|
@@ -1191,7 +1191,7 @@ export type SiteSettings = Model<{
|
|
|
1191
1191
|
function envTemplate(opts: ScaffoldOptions): string {
|
|
1192
1192
|
const sections: string[] = []
|
|
1193
1193
|
// Generated, not constant. These reach a server: the previous defaults meant a self-host
|
|
1194
|
-
// deployment ran with a password of `postgres` and a JWT secret published in this repo
|
|
1194
|
+
// deployment ran with a password of `postgres` and a JWT secret published in this repo,
|
|
1195
1195
|
// and anyone holding that secret can mint a token naming any Postgres role. Safe to generate
|
|
1196
1196
|
// only because `supatype dev` no longer overwrites them on every run (see local-secrets.ts).
|
|
1197
1197
|
const postgresPassword = randomBytes(24).toString("base64url")
|
|
@@ -1202,14 +1202,14 @@ POSTGRES_PASSWORD=${postgresPassword}
|
|
|
1202
1202
|
POSTGRES_DB=${opts.projectName}
|
|
1203
1203
|
|
|
1204
1204
|
# PostgREST's own database credential. It connects as \`authenticator\`, a role that holds no
|
|
1205
|
-
# privileges and can only switch to anon/authenticated/service_role
|
|
1205
|
+
# privileges and can only switch to anon/authenticated/service_role, so a request whose JWT
|
|
1206
1206
|
# names any other role is refused by Postgres rather than honoured.
|
|
1207
1207
|
#
|
|
1208
1208
|
# Deliberately NOT the same as POSTGRES_PASSWORD: that one is yours, for direct SQL access, and
|
|
1209
1209
|
# rotating it should never take the REST API down with it.
|
|
1210
1210
|
AUTHENTICATOR_PASSWORD=${randomBytes(24).toString("base64url")}`)
|
|
1211
1211
|
|
|
1212
|
-
sections.push(`# JWT
|
|
1212
|
+
sections.push(`# JWT: ANON_KEY and SERVICE_ROLE_KEY are derived from this secret.
|
|
1213
1213
|
# Changing it invalidates every issued token; re-run \`supatype keys\` afterwards.
|
|
1214
1214
|
JWT_SECRET=${randomBytes(48).toString("base64url")}
|
|
1215
1215
|
ANON_KEY=
|
|
@@ -1221,7 +1221,7 @@ SITE_URL=http://localhost:3000`)
|
|
|
1221
1221
|
if (opts.provider === "docker" && opts.kongPort !== undefined) {
|
|
1222
1222
|
const apiUrl = `http://localhost:${opts.kongPort}`
|
|
1223
1223
|
sections.push(
|
|
1224
|
-
`# Local API gateway (Kong)
|
|
1224
|
+
`# Local API gateway (Kong), unique per project so multiple stacks can run concurrently
|
|
1225
1225
|
SUPATYPE_KONG_PORT=${opts.kongPort}
|
|
1226
1226
|
PUBLIC_SUPATYPE_URL=${apiUrl}
|
|
1227
1227
|
API_EXTERNAL_URL=${apiUrl}
|
|
@@ -1235,7 +1235,7 @@ VITE_SUPATYPE_ANON_KEY=`,
|
|
|
1235
1235
|
|
|
1236
1236
|
if (opts.adminEmail && opts.adminPassword) {
|
|
1237
1237
|
sections.push(
|
|
1238
|
-
`# First admin for /admin
|
|
1238
|
+
`# First admin for /admin, consumed on first supatype dev or push (password removed after use)
|
|
1239
1239
|
SUPATYPE_ADMIN_EMAIL=${opts.adminEmail}
|
|
1240
1240
|
SUPATYPE_ADMIN_PASSWORD=${opts.adminPassword}`,
|
|
1241
1241
|
)
|
|
@@ -1269,7 +1269,7 @@ SMTP_PASS=
|
|
|
1269
1269
|
SMTP_SENDER_NAME=${projectName}`
|
|
1270
1270
|
case "console":
|
|
1271
1271
|
default:
|
|
1272
|
-
return `# SMTP
|
|
1272
|
+
return `# SMTP: leave empty to use email autoconfirm in dev (no emails sent)
|
|
1273
1273
|
SMTP_HOST=
|
|
1274
1274
|
SMTP_PORT=
|
|
1275
1275
|
SMTP_USER=
|
|
@@ -1284,7 +1284,7 @@ function storageEnvSections(
|
|
|
1284
1284
|
): string {
|
|
1285
1285
|
if (storageLocal === storageProduction) {
|
|
1286
1286
|
if (storageLocal === "s3") {
|
|
1287
|
-
return `# Storage (local development and production
|
|
1287
|
+
return `# Storage (local development and production, external bucket)
|
|
1288
1288
|
# Use separate buckets for dev and production in your provider.
|
|
1289
1289
|
S3_ENDPOINT=
|
|
1290
1290
|
S3_REGION=us-east-1
|
|
@@ -1295,7 +1295,7 @@ S3_SECRET_KEY=`
|
|
|
1295
1295
|
return `${localStorageEnvSection("local")}
|
|
1296
1296
|
|
|
1297
1297
|
# Production storage (MinIO on your server)
|
|
1298
|
-
# Included in the self-host compose stack
|
|
1298
|
+
# Included in the self-host compose stack, no extra configuration needed.`
|
|
1299
1299
|
}
|
|
1300
1300
|
|
|
1301
1301
|
return [localStorageEnvSection(storageLocal), productionStorageEnvSection(storageProduction)].join(
|
|
@@ -1305,14 +1305,14 @@ S3_SECRET_KEY=`
|
|
|
1305
1305
|
|
|
1306
1306
|
function localStorageEnvSection(storage: StorageProvider): string {
|
|
1307
1307
|
if (storage === "s3") {
|
|
1308
|
-
return `# Storage (local development
|
|
1308
|
+
return `# Storage (local development, external bucket)
|
|
1309
1309
|
S3_ENDPOINT=
|
|
1310
1310
|
S3_REGION=us-east-1
|
|
1311
1311
|
S3_BUCKET=
|
|
1312
1312
|
S3_ACCESS_KEY=
|
|
1313
1313
|
S3_SECRET_KEY=`
|
|
1314
1314
|
}
|
|
1315
|
-
return `# Storage (local development
|
|
1315
|
+
return `# Storage (local development, MinIO)
|
|
1316
1316
|
S3_ENDPOINT=http://localhost:9000
|
|
1317
1317
|
S3_ACCESS_KEY=supatype
|
|
1318
1318
|
S3_SECRET_KEY=supatype-secret`
|
|
@@ -1320,15 +1320,15 @@ S3_SECRET_KEY=supatype-secret`
|
|
|
1320
1320
|
|
|
1321
1321
|
function productionStorageEnvSection(storage: StorageProvider): string {
|
|
1322
1322
|
if (storage === "s3") {
|
|
1323
|
-
return `# Storage (production
|
|
1323
|
+
return `# Storage (production, external bucket)
|
|
1324
1324
|
S3_ENDPOINT=
|
|
1325
1325
|
S3_REGION=us-east-1
|
|
1326
1326
|
S3_BUCKET=
|
|
1327
1327
|
S3_ACCESS_KEY=
|
|
1328
1328
|
S3_SECRET_KEY=`
|
|
1329
1329
|
}
|
|
1330
|
-
return `# Storage (production
|
|
1331
|
-
# Included in the self-host compose stack
|
|
1330
|
+
return `# Storage (production, MinIO on your server)
|
|
1331
|
+
# Included in the self-host compose stack, no extra configuration needed.`
|
|
1332
1332
|
}
|
|
1333
1333
|
|
|
1334
1334
|
function seedTemplate(projectName: string): string {
|
|
@@ -1358,7 +1358,7 @@ seed().catch((e) => {
|
|
|
1358
1358
|
}
|
|
1359
1359
|
|
|
1360
1360
|
function helloFunctionTemplate(): string {
|
|
1361
|
-
return `// hello
|
|
1361
|
+
return `// hello: Supatype Edge Function
|
|
1362
1362
|
// Docs: https://supatype.com/docs/edge-functions
|
|
1363
1363
|
|
|
1364
1364
|
export default async function handler(req: Request): Promise<Response> {
|
|
@@ -1397,7 +1397,7 @@ dist/
|
|
|
1397
1397
|
supatype.local.config.ts
|
|
1398
1398
|
supatype.local.config.js
|
|
1399
1399
|
supatype.local.config.mjs
|
|
1400
|
-
# Generated by supatype push (legacy paths
|
|
1400
|
+
# Generated by supatype push (legacy paths, prefer output.types in config)
|
|
1401
1401
|
src/types/supatype.d.ts
|
|
1402
1402
|
src/lib/supatype.ts
|
|
1403
1403
|
`
|
|
@@ -1408,7 +1408,7 @@ export function mergeGitignoreTemplate(existingContent: string): string {
|
|
|
1408
1408
|
return existingContent
|
|
1409
1409
|
}
|
|
1410
1410
|
const block = `
|
|
1411
|
-
# Supatype
|
|
1411
|
+
# Supatype: local runtime (contains secrets in link.json)
|
|
1412
1412
|
.supatype/
|
|
1413
1413
|
`
|
|
1414
1414
|
return existingContent.endsWith("\n") ? `${existingContent}${block}` : `${existingContent}\n${block}`
|
|
@@ -1460,9 +1460,9 @@ function printNextSteps(args: {
|
|
|
1460
1460
|
nextSteps(setupComplete ? "Next steps:" : "Finish setup:", steps)
|
|
1461
1461
|
|
|
1462
1462
|
// Shown once, at creation. These are generated per project rather than shipped as
|
|
1463
|
-
// constants, so this is the moment to say they exist and where they live
|
|
1463
|
+
// constants, so this is the moment to say they exist and where they live, nothing prints
|
|
1464
1464
|
// them again, and the JWT secret is only echoed as a fingerprint from here on.
|
|
1465
|
-
nextSteps("Secrets
|
|
1465
|
+
nextSteps("Secrets: generated for this project, kept in .env:", [
|
|
1466
1466
|
"POSTGRES_PASSWORD direct SQL access as the superuser",
|
|
1467
1467
|
"AUTHENTICATOR_PASSWORD PostgREST's own login; rotating the one above does not affect it",
|
|
1468
1468
|
"JWT_SECRET signs ANON_KEY and SERVICE_ROLE_KEY; changing it invalidates every token",
|
|
@@ -1496,7 +1496,7 @@ function printNextSteps(args: {
|
|
|
1496
1496
|
selfHostSteps.push("supatype self-host compose up -d # Kong provisions HTTPS automatically")
|
|
1497
1497
|
selfHostSteps.push(`Your Supatype platform goes live at https://${domain}`)
|
|
1498
1498
|
selfHostSteps.push(
|
|
1499
|
-
"Your app, REST, Auth, Storage, Realtime, Functions, and Studio
|
|
1499
|
+
"Your app, REST, Auth, Storage, Realtime, Functions, and Studio, all behind one HTTPS domain (certs persist in valkey-data)",
|
|
1500
1500
|
)
|
|
1501
1501
|
} else {
|
|
1502
1502
|
selfHostSteps.push(
|
package/src/commands/internal.ts
CHANGED
|
@@ -3,6 +3,8 @@
|
|
|
3
3
|
*/
|
|
4
4
|
|
|
5
5
|
import type { Command } from "commander"
|
|
6
|
+
import { resolve } from "node:path"
|
|
7
|
+
import { pathToFileURL } from "node:url"
|
|
6
8
|
import { downloadAll } from "../binary-cache.js"
|
|
7
9
|
import { error, info } from "../ui/messages.js"
|
|
8
10
|
|
|
@@ -20,4 +22,39 @@ export function registerInternalCommands(program: Command): void {
|
|
|
20
22
|
process.exit(1)
|
|
21
23
|
}
|
|
22
24
|
})
|
|
25
|
+
|
|
26
|
+
// Interpreter for the standalone binary. It carries the Bun runtime, so it can import
|
|
27
|
+
// TypeScript directly; what it cannot do is spawn `node` with `tsx`, because a machine that
|
|
28
|
+
// installed with `curl | sh` has neither, and neither is embedded. So the binary re-executes
|
|
29
|
+
// itself for these two jobs rather than reaching for a toolchain that is not there.
|
|
30
|
+
//
|
|
31
|
+
// Hidden and prefixed, like _postinstall: they are an implementation detail of config loading,
|
|
32
|
+
// not commands anyone should run.
|
|
33
|
+
program
|
|
34
|
+
.command("_print-module <target>", { hidden: true })
|
|
35
|
+
.description("Import a module and print its default export as JSON")
|
|
36
|
+
.action(async (target: string) => {
|
|
37
|
+
try {
|
|
38
|
+
const href = target.startsWith("file:") ? target : pathToFileURL(resolve(target)).href
|
|
39
|
+
const mod = (await import(href)) as { default?: unknown }
|
|
40
|
+
const value = mod.default ?? mod
|
|
41
|
+
process.stdout.write(JSON.stringify(value))
|
|
42
|
+
} catch (err) {
|
|
43
|
+
// stderr, because the caller parses stdout as JSON and a message there would corrupt it.
|
|
44
|
+
process.stderr.write(err instanceof Error ? (err.stack ?? err.message) : String(err))
|
|
45
|
+
process.exit(1)
|
|
46
|
+
}
|
|
47
|
+
})
|
|
48
|
+
|
|
49
|
+
program
|
|
50
|
+
.command("_run-ts <file>", { hidden: true })
|
|
51
|
+
.description("Execute a TypeScript file for its side effects")
|
|
52
|
+
.action(async (file: string) => {
|
|
53
|
+
try {
|
|
54
|
+
await import(pathToFileURL(resolve(file)).href)
|
|
55
|
+
} catch (err) {
|
|
56
|
+
process.stderr.write(err instanceof Error ? (err.stack ?? err.message) : String(err))
|
|
57
|
+
process.exit(1)
|
|
58
|
+
}
|
|
59
|
+
})
|
|
23
60
|
}
|
package/src/commands/login.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Cloud session login / logout for CLI control-plane auth.
|
|
3
|
-
* Self-host uses SERVICE_ROLE_KEY via `supatype link --url
|
|
3
|
+
* Self-host uses SERVICE_ROLE_KEY via `supatype link --url`, not this command.
|
|
4
4
|
*/
|
|
5
5
|
import type { Command } from "commander"
|
|
6
6
|
import {
|
|
@@ -77,7 +77,7 @@ export function registerLogin(program: Command): void {
|
|
|
77
77
|
if (link?.kind === "cloud") {
|
|
78
78
|
info(`Updated cloud session for linked project ${link.projectRef}`)
|
|
79
79
|
} else if (!session.refreshToken) {
|
|
80
|
-
plain("Warning: no refresh_token returned
|
|
80
|
+
plain("Warning: no refresh_token returned, session may expire in ~1h. Update control plane.")
|
|
81
81
|
} else {
|
|
82
82
|
plain("Tip: link a project with: supatype link --project <slug>")
|
|
83
83
|
}
|
package/src/commands/logs.ts
CHANGED
package/src/commands/migrate.ts
CHANGED
|
@@ -58,9 +58,9 @@ export function registerMigrate(program: Command): void {
|
|
|
58
58
|
const size =
|
|
59
59
|
manifest?.compressedBytes !== undefined
|
|
60
60
|
? `${(manifest.compressedBytes / 1024).toFixed(1)} KB`
|
|
61
|
-
: "
|
|
62
|
-
const files = manifest?.fileCount ?? "
|
|
63
|
-
const author = manifest?.pushedBy ?? "
|
|
61
|
+
: "-"
|
|
62
|
+
const files = manifest?.fileCount ?? "-"
|
|
63
|
+
const author = manifest?.pushedBy ?? "-"
|
|
64
64
|
const rolled = m.rolledBack ? " (rolled back)" : ""
|
|
65
65
|
plain(
|
|
66
66
|
`${m.name}${rolled}\n applied: ${m.appliedAt} status: ${m.status}\n author: ${author} files: ${files} snapshot: ${size}`,
|
|
@@ -212,7 +212,7 @@ async function offerSchemaRestore(
|
|
|
212
212
|
const manifestPaths = new Set(manifest.files.map((f) => f.path))
|
|
213
213
|
const orphans = findOrphanSchemaFiles(root, manifest.entryPoint, manifestPaths)
|
|
214
214
|
for (const orphan of orphans) {
|
|
215
|
-
warn(`${orphan} not in snapshot
|
|
215
|
+
warn(`${orphan} not in snapshot, review manually`)
|
|
216
216
|
}
|
|
217
217
|
|
|
218
218
|
info(`Restored schema files from migration ${label}.`)
|
|
@@ -222,6 +222,6 @@ async function offerSchemaRestore(
|
|
|
222
222
|
if ((postDiff.operations ?? []).length === 0) {
|
|
223
223
|
info("Schema matches database after restore.")
|
|
224
224
|
} else {
|
|
225
|
-
info("Run `supatype diff
|
|
225
|
+
info("Run `supatype diff`: schema may still differ from database.")
|
|
226
226
|
}
|
|
227
227
|
}
|
package/src/commands/pg.ts
CHANGED
package/src/commands/plugins.ts
CHANGED
package/src/commands/pull.ts
CHANGED
|
@@ -10,7 +10,7 @@ import { info, plain } from "../ui/messages.js"
|
|
|
10
10
|
export function registerPull(program: Command): void {
|
|
11
11
|
program
|
|
12
12
|
.command("pull")
|
|
13
|
-
.description("Scaffold schema/index.ts from live database introspection (draft
|
|
13
|
+
.description("Scaffold schema/index.ts from live database introspection (draft, review before push)")
|
|
14
14
|
.option("--connection <url>", "Database connection URL (overrides config)")
|
|
15
15
|
.option("--out <path>", "Write scaffold to file (default: stdout)")
|
|
16
16
|
.option("--dry-run", "Print scaffold to stdout without writing files")
|
|
@@ -34,7 +34,7 @@ export function registerPull(program: Command): void {
|
|
|
34
34
|
if (opts.dryRun || !opts.out) {
|
|
35
35
|
plain(scaffold)
|
|
36
36
|
if (!opts.dryRun && !opts.out) {
|
|
37
|
-
info("(draft printed to stdout
|
|
37
|
+
info("(draft printed to stdout, use --out to write a file)")
|
|
38
38
|
}
|
|
39
39
|
return
|
|
40
40
|
}
|