@supatype/cli 0.1.0-alpha.9 → 0.1.1
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 +2 -2
- package/.turbo/turbo-test.log +285 -69
- package/.turbo/turbo-typecheck.log +1 -1
- package/assets/supatype-logo-wordmark.ascii.txt +6 -0
- package/bin/dev-entry.ts +2 -1
- package/dist/app/framework.js +1 -3
- package/dist/app/framework.js.map +1 -1
- package/dist/app/proxy-dev-app.d.ts +14 -0
- package/dist/app/proxy-dev-app.d.ts.map +1 -1
- package/dist/app/proxy-dev-app.js +110 -6
- package/dist/app/proxy-dev-app.js.map +1 -1
- package/dist/app-config.d.ts +10 -0
- package/dist/app-config.d.ts.map +1 -1
- package/dist/app-config.js +72 -0
- package/dist/app-config.js.map +1 -1
- package/dist/assets/supatype-logo-wordmark.ascii.txt +6 -0
- package/dist/binary-cache.d.ts +19 -7
- package/dist/binary-cache.d.ts.map +1 -1
- package/dist/binary-cache.js +92 -46
- package/dist/binary-cache.js.map +1 -1
- package/dist/cli.d.ts +1 -1
- package/dist/cli.d.ts.map +1 -1
- package/dist/cli.js +17 -2
- package/dist/cli.js.map +1 -1
- package/dist/commands/add.d.ts +3 -0
- package/dist/commands/add.d.ts.map +1 -0
- package/dist/commands/add.js +86 -0
- package/dist/commands/add.js.map +1 -0
- package/dist/commands/admin.d.ts +28 -1
- package/dist/commands/admin.d.ts.map +1 -1
- package/dist/commands/admin.js +297 -149
- package/dist/commands/admin.js.map +1 -1
- package/dist/commands/adopt.d.ts +3 -0
- package/dist/commands/adopt.d.ts.map +1 -0
- package/dist/commands/adopt.js +55 -0
- package/dist/commands/adopt.js.map +1 -0
- package/dist/commands/app.d.ts.map +1 -1
- package/dist/commands/app.js +20 -17
- package/dist/commands/app.js.map +1 -1
- package/dist/commands/cache.d.ts.map +1 -1
- package/dist/commands/cache.js +11 -10
- package/dist/commands/cache.js.map +1 -1
- package/dist/commands/cloud.d.ts +4 -9
- package/dist/commands/cloud.d.ts.map +1 -1
- package/dist/commands/cloud.js +75 -125
- package/dist/commands/cloud.js.map +1 -1
- package/dist/commands/db.d.ts.map +1 -1
- package/dist/commands/db.js +37 -58
- package/dist/commands/db.js.map +1 -1
- package/dist/commands/deploy.d.ts.map +1 -1
- package/dist/commands/deploy.js +140 -96
- package/dist/commands/deploy.js.map +1 -1
- package/dist/commands/dev.d.ts.map +1 -1
- package/dist/commands/dev.js +74 -39
- package/dist/commands/dev.js.map +1 -1
- package/dist/commands/diff.d.ts.map +1 -1
- package/dist/commands/diff.js +39 -39
- package/dist/commands/diff.js.map +1 -1
- package/dist/commands/doctor.d.ts +3 -0
- package/dist/commands/doctor.d.ts.map +1 -0
- package/dist/commands/doctor.js +78 -0
- package/dist/commands/doctor.js.map +1 -0
- package/dist/commands/engine.d.ts.map +1 -1
- package/dist/commands/engine.js +5 -4
- package/dist/commands/engine.js.map +1 -1
- package/dist/commands/functions.d.ts.map +1 -1
- package/dist/commands/functions.js +172 -119
- package/dist/commands/functions.js.map +1 -1
- package/dist/commands/generate.d.ts.map +1 -1
- package/dist/commands/generate.js +5 -4
- package/dist/commands/generate.js.map +1 -1
- package/dist/commands/init.d.ts +35 -1
- package/dist/commands/init.d.ts.map +1 -1
- package/dist/commands/init.js +883 -107
- package/dist/commands/init.js.map +1 -1
- package/dist/commands/introspect.d.ts +3 -0
- package/dist/commands/introspect.d.ts.map +1 -0
- package/dist/commands/introspect.js +35 -0
- package/dist/commands/introspect.js.map +1 -0
- package/dist/commands/keys.d.ts +15 -1
- package/dist/commands/keys.d.ts.map +1 -1
- package/dist/commands/keys.js +46 -10
- package/dist/commands/keys.js.map +1 -1
- package/dist/commands/link-helpers.d.ts +15 -0
- package/dist/commands/link-helpers.d.ts.map +1 -0
- package/dist/commands/link-helpers.js +225 -0
- package/dist/commands/link-helpers.js.map +1 -0
- package/dist/commands/logs.d.ts.map +1 -1
- package/dist/commands/logs.js +5 -4
- package/dist/commands/logs.js.map +1 -1
- package/dist/commands/migrate-from-v1.d.ts.map +1 -1
- package/dist/commands/migrate-from-v1.js +3 -2
- package/dist/commands/migrate-from-v1.js.map +1 -1
- package/dist/commands/migrate.d.ts.map +1 -1
- package/dist/commands/migrate.js +119 -26
- package/dist/commands/migrate.js.map +1 -1
- package/dist/commands/pg.d.ts.map +1 -1
- package/dist/commands/pg.js +11 -12
- package/dist/commands/pg.js.map +1 -1
- package/dist/commands/plugins.d.ts.map +1 -1
- package/dist/commands/plugins.js +55 -46
- package/dist/commands/plugins.js.map +1 -1
- package/dist/commands/pull.d.ts.map +1 -1
- package/dist/commands/pull.js +33 -5
- package/dist/commands/pull.js.map +1 -1
- package/dist/commands/push.d.ts.map +1 -1
- package/dist/commands/push.js +111 -138
- package/dist/commands/push.js.map +1 -1
- package/dist/commands/seed.d.ts.map +1 -1
- package/dist/commands/seed.js +4 -3
- package/dist/commands/seed.js.map +1 -1
- package/dist/commands/self-host.d.ts +2 -2
- package/dist/commands/self-host.d.ts.map +1 -1
- package/dist/commands/self-host.js +65 -50
- package/dist/commands/self-host.js.map +1 -1
- package/dist/commands/self-update.d.ts.map +1 -1
- package/dist/commands/self-update.js +3 -2
- package/dist/commands/self-update.js.map +1 -1
- package/dist/commands/status.d.ts +1 -1
- package/dist/commands/status.d.ts.map +1 -1
- package/dist/commands/status.js +95 -29
- package/dist/commands/status.js.map +1 -1
- package/dist/commands/types.d.ts.map +1 -1
- package/dist/commands/types.js +3 -2
- package/dist/commands/types.js.map +1 -1
- package/dist/commands/update.d.ts.map +1 -1
- package/dist/commands/update.js +54 -21
- package/dist/commands/update.js.map +1 -1
- package/dist/compose-rename.d.ts +10 -0
- package/dist/compose-rename.d.ts.map +1 -0
- package/dist/compose-rename.js +67 -0
- package/dist/compose-rename.js.map +1 -0
- package/dist/config.d.ts +2 -1
- package/dist/config.d.ts.map +1 -1
- package/dist/config.js.map +1 -1
- package/dist/dev-compose.d.ts +26 -0
- package/dist/dev-compose.d.ts.map +1 -1
- package/dist/dev-compose.js +357 -79
- package/dist/dev-compose.js.map +1 -1
- package/dist/dev-log-bus.d.ts +30 -0
- package/dist/dev-log-bus.d.ts.map +1 -0
- package/dist/dev-log-bus.js +87 -0
- package/dist/dev-log-bus.js.map +1 -0
- package/dist/dev-log-filter.d.ts +10 -0
- package/dist/dev-log-filter.d.ts.map +1 -0
- package/dist/dev-log-filter.js +36 -0
- package/dist/dev-log-filter.js.map +1 -0
- package/dist/dev-logo.d.ts +12 -0
- package/dist/dev-logo.d.ts.map +1 -0
- package/dist/dev-logo.js +56 -0
- package/dist/dev-logo.js.map +1 -0
- package/dist/dev-ports.d.ts +27 -0
- package/dist/dev-ports.d.ts.map +1 -0
- package/dist/dev-ports.js +171 -0
- package/dist/dev-ports.js.map +1 -0
- package/dist/dev-session-lock.d.ts +25 -0
- package/dist/dev-session-lock.d.ts.map +1 -0
- package/dist/dev-session-lock.js +81 -0
- package/dist/dev-session-lock.js.map +1 -0
- package/dist/dev-session.d.ts +26 -0
- package/dist/dev-session.d.ts.map +1 -0
- package/dist/dev-session.js +106 -0
- package/dist/dev-session.js.map +1 -0
- package/dist/dev-shutdown.d.ts +25 -0
- package/dist/dev-shutdown.d.ts.map +1 -0
- package/dist/dev-shutdown.js +114 -0
- package/dist/dev-shutdown.js.map +1 -0
- package/dist/dev-task-colors.d.ts +13 -0
- package/dist/dev-task-colors.d.ts.map +1 -0
- package/dist/dev-task-colors.js +43 -0
- package/dist/dev-task-colors.js.map +1 -0
- package/dist/dev-tui.d.ts +24 -0
- package/dist/dev-tui.d.ts.map +1 -0
- package/dist/dev-tui.js +188 -0
- package/dist/dev-tui.js.map +1 -0
- package/dist/diff-output.d.ts +5 -1
- package/dist/diff-output.d.ts.map +1 -1
- package/dist/diff-output.js +69 -0
- package/dist/diff-output.js.map +1 -1
- package/dist/docker-runtime.d.ts +30 -0
- package/dist/docker-runtime.d.ts.map +1 -0
- package/dist/docker-runtime.js +118 -0
- package/dist/docker-runtime.js.map +1 -0
- package/dist/engine-client.d.ts +10 -1
- package/dist/engine-client.d.ts.map +1 -1
- package/dist/engine-client.js +76 -17
- package/dist/engine-client.js.map +1 -1
- package/dist/engine-push-output.d.ts +17 -0
- package/dist/engine-push-output.d.ts.map +1 -0
- package/dist/engine-push-output.js +64 -0
- package/dist/engine-push-output.js.map +1 -0
- package/dist/ensure-binary.js +2 -2
- package/dist/ensure-binary.js.map +1 -1
- package/dist/env-file.d.ts +5 -0
- package/dist/env-file.d.ts.map +1 -0
- package/dist/env-file.js +33 -0
- package/dist/env-file.js.map +1 -0
- package/dist/gitignore.d.ts +8 -0
- package/dist/gitignore.d.ts.map +1 -0
- package/dist/gitignore.js +41 -0
- package/dist/gitignore.js.map +1 -0
- package/dist/kong-config.d.ts +9 -0
- package/dist/kong-config.d.ts.map +1 -1
- package/dist/kong-config.js +18 -1
- package/dist/kong-config.js.map +1 -1
- package/dist/link.d.ts +66 -0
- package/dist/link.d.ts.map +1 -0
- package/dist/link.js +160 -0
- package/dist/link.js.map +1 -0
- package/dist/process-manager.d.ts +8 -0
- package/dist/process-manager.d.ts.map +1 -1
- package/dist/process-manager.js +53 -9
- package/dist/process-manager.js.map +1 -1
- package/dist/project-config.d.ts +30 -3
- package/dist/project-config.d.ts.map +1 -1
- package/dist/project-config.js +37 -4
- package/dist/project-config.js.map +1 -1
- package/dist/prompts.d.ts +3 -0
- package/dist/prompts.d.ts.map +1 -0
- package/dist/prompts.js +3 -0
- package/dist/prompts.js.map +1 -0
- package/dist/pull-utils.d.ts +50 -14
- package/dist/pull-utils.d.ts.map +1 -1
- package/dist/pull-utils.js +152 -12
- package/dist/pull-utils.js.map +1 -1
- package/dist/resolve-target.d.ts +86 -0
- package/dist/resolve-target.d.ts.map +1 -0
- package/dist/resolve-target.js +291 -0
- package/dist/resolve-target.js.map +1 -0
- package/dist/restore-system-relation-targets.d.ts +3 -0
- package/dist/restore-system-relation-targets.d.ts.map +1 -0
- package/dist/restore-system-relation-targets.js +45 -0
- package/dist/restore-system-relation-targets.js.map +1 -0
- package/dist/runtime-routes.d.ts.map +1 -1
- package/dist/runtime-routes.js +7 -0
- package/dist/runtime-routes.js.map +1 -1
- package/dist/schema-ast-v2.d.ts +1 -1
- 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-sources.d.ts +40 -0
- package/dist/schema-sources.d.ts.map +1 -0
- package/dist/schema-sources.js +183 -0
- package/dist/schema-sources.js.map +1 -0
- package/dist/scripts/postinstall.js +5 -1
- package/dist/scripts/postinstall.js.map +1 -1
- package/dist/self-host-compose.d.ts +37 -1
- package/dist/self-host-compose.d.ts.map +1 -1
- package/dist/self-host-compose.js +234 -43
- package/dist/self-host-compose.js.map +1 -1
- package/dist/storage-provision.d.ts +4 -0
- package/dist/storage-provision.d.ts.map +1 -1
- package/dist/storage-provision.js +24 -2
- package/dist/storage-provision.js.map +1 -1
- package/dist/supatype-eval-1781522769253.d.mts +2 -0
- package/dist/supatype-eval-1781522769253.d.mts.map +1 -0
- package/dist/supatype-eval-1781522769253.mjs +3 -0
- package/dist/supatype-eval-1781522769253.mjs.map +1 -0
- package/dist/systemd.js +2 -2
- package/dist/systemd.js.map +1 -1
- package/dist/target-client.d.ts +10 -0
- package/dist/target-client.d.ts.map +1 -0
- package/dist/target-client.js +22 -0
- package/dist/target-client.js.map +1 -0
- package/dist/type-extractor.d.ts +11 -0
- package/dist/type-extractor.d.ts.map +1 -1
- package/dist/type-extractor.js +95 -8
- package/dist/type-extractor.js.map +1 -1
- package/dist/ui/brand.d.ts +9 -0
- package/dist/ui/brand.d.ts.map +1 -0
- package/dist/ui/brand.js +11 -0
- package/dist/ui/brand.js.map +1 -0
- package/dist/ui/confirm.d.ts +12 -0
- package/dist/ui/confirm.d.ts.map +1 -0
- package/dist/ui/confirm.js +28 -0
- package/dist/ui/confirm.js.map +1 -0
- package/dist/ui/fatal.d.ts +10 -0
- package/dist/ui/fatal.d.ts.map +1 -0
- package/dist/ui/fatal.js +34 -0
- package/dist/ui/fatal.js.map +1 -0
- package/dist/ui/index.d.ts +9 -0
- package/dist/ui/index.d.ts.map +1 -0
- package/dist/ui/index.js +9 -0
- package/dist/ui/index.js.map +1 -0
- package/dist/ui/interactive.d.ts +3 -0
- package/dist/ui/interactive.d.ts.map +1 -0
- package/dist/ui/interactive.js +5 -0
- package/dist/ui/interactive.js.map +1 -0
- package/dist/ui/messages.d.ts +10 -0
- package/dist/ui/messages.d.ts.map +1 -0
- package/dist/ui/messages.js +35 -0
- package/dist/ui/messages.js.map +1 -0
- package/dist/ui/next-steps.d.ts +3 -0
- package/dist/ui/next-steps.d.ts.map +1 -0
- package/dist/ui/next-steps.js +10 -0
- package/dist/ui/next-steps.js.map +1 -0
- package/dist/ui/progress.d.ts +5 -0
- package/dist/ui/progress.d.ts.map +1 -0
- package/dist/ui/progress.js +24 -0
- package/dist/ui/progress.js.map +1 -0
- package/dist/ui/prompts.d.ts +14 -0
- package/dist/ui/prompts.d.ts.map +1 -0
- package/dist/ui/prompts.js +34 -0
- package/dist/ui/prompts.js.map +1 -0
- package/package.json +5 -2
- package/src/app/framework.ts +1 -3
- package/src/app/proxy-dev-app.ts +114 -6
- package/src/app-config.ts +80 -0
- package/src/binary-cache.ts +102 -52
- package/src/cli.ts +16 -2
- package/src/commands/add.ts +97 -0
- package/src/commands/admin.ts +381 -190
- package/src/commands/adopt.ts +82 -0
- package/src/commands/app.ts +20 -17
- package/src/commands/cache.ts +11 -10
- package/src/commands/cloud.ts +91 -142
- package/src/commands/db.ts +40 -63
- package/src/commands/deploy.ts +186 -126
- package/src/commands/dev.ts +98 -55
- package/src/commands/diff.ts +52 -43
- package/src/commands/doctor.ts +103 -0
- package/src/commands/engine.ts +5 -4
- package/src/commands/functions.ts +187 -123
- package/src/commands/generate.ts +5 -4
- package/src/commands/init.ts +1087 -104
- package/src/commands/introspect.ts +48 -0
- package/src/commands/keys.ts +56 -14
- package/src/commands/link-helpers.ts +273 -0
- package/src/commands/logs.ts +5 -4
- package/src/commands/migrate-from-v1.ts +3 -2
- package/src/commands/migrate.ts +167 -27
- package/src/commands/pg.ts +13 -18
- package/src/commands/plugins.ts +55 -46
- package/src/commands/pull.ts +38 -9
- package/src/commands/push.ts +148 -175
- package/src/commands/seed.ts +5 -4
- package/src/commands/self-host.ts +85 -54
- package/src/commands/self-update.ts +3 -2
- package/src/commands/status.ts +102 -33
- package/src/commands/types.ts +3 -2
- package/src/commands/update.ts +59 -23
- package/src/compose-rename.ts +76 -0
- package/src/config.ts +2 -1
- package/src/dev-compose.ts +462 -76
- package/src/dev-log-bus.ts +101 -0
- package/src/dev-log-filter.ts +32 -0
- package/src/dev-logo.ts +61 -0
- package/src/dev-ports.ts +212 -0
- package/src/dev-session-lock.ts +101 -0
- package/src/dev-session.ts +130 -0
- package/src/dev-shutdown.ts +147 -0
- package/src/dev-task-colors.ts +47 -0
- package/src/dev-tui.ts +232 -0
- package/src/diff-output.ts +79 -1
- package/src/docker-runtime.ts +151 -0
- package/src/engine-client.ts +81 -17
- package/src/engine-push-output.ts +75 -0
- package/src/ensure-binary.ts +2 -2
- package/src/env-file.ts +37 -0
- package/src/gitignore.ts +48 -0
- package/src/kong-config.ts +24 -1
- package/src/link.ts +243 -0
- package/src/process-manager.ts +66 -10
- package/src/project-config.ts +62 -7
- package/src/prompts.ts +2 -0
- package/src/pull-utils.ts +217 -23
- package/src/resolve-target.ts +419 -0
- package/src/restore-system-relation-targets.ts +45 -0
- package/src/runtime-routes.ts +7 -0
- package/src/schema-ast-v2.ts +2 -1
- package/src/schema-sources.ts +248 -0
- package/src/scripts/postinstall.ts +7 -1
- package/src/self-host-compose.ts +262 -46
- package/src/storage-provision.ts +33 -1
- package/src/supatype-eval-1781522769253.mts +1 -0
- package/src/systemd.ts +2 -2
- package/src/target-client.ts +40 -0
- package/src/type-extractor.ts +124 -11
- package/src/ui/README.md +17 -0
- package/src/ui/brand.ts +12 -0
- package/src/ui/confirm.ts +38 -0
- package/src/ui/fatal.ts +43 -0
- package/src/ui/index.ts +8 -0
- package/src/ui/interactive.ts +4 -0
- package/src/ui/messages.ts +43 -0
- package/src/ui/next-steps.ts +10 -0
- package/src/ui/progress.ts +28 -0
- package/src/ui/prompts.ts +40 -0
- package/tests/admin-ensure.test.ts +59 -0
- package/tests/cli-help.test.ts +27 -2
- package/tests/config.test.ts +29 -2
- package/tests/dev-ports.test.ts +41 -0
- package/tests/dev-session-lock.test.ts +54 -0
- package/tests/dev-ui.test.ts +162 -0
- package/tests/docker-runtime.test.ts +236 -0
- package/tests/engine-push-output.test.ts +67 -0
- package/tests/init.test.ts +197 -18
- package/tests/link.test.ts +148 -0
- package/tests/minisign.test.ts +102 -0
- package/tests/proxy-dev-app.test.ts +45 -1
- package/tests/pull-utils.test.ts +5 -4
- package/tests/runtime-contract.test.ts +186 -2
- package/tests/schema-sources.test.ts +119 -0
- package/tests/storage-provision.test.ts +100 -0
- package/tests/ui-confirm.test.ts +41 -0
- package/tests/ui-messages.test.ts +66 -0
- package/tsconfig.tsbuildinfo +1 -1
package/dist/dev-compose.js
CHANGED
|
@@ -1,54 +1,51 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* `supatype dev` when `provider: docker` — full self-host Compose stack (Kong gateway).
|
|
3
3
|
*/
|
|
4
|
-
import { existsSync, mkdirSync,
|
|
4
|
+
import { existsSync, mkdirSync, writeFileSync } from "node:fs";
|
|
5
5
|
import { homedir } from "node:os";
|
|
6
6
|
import { dirname, join, resolve } from "node:path";
|
|
7
7
|
import { spawnSync } from "node:child_process";
|
|
8
8
|
import { startProxyDevApp } from "./app/proxy-dev-app.js";
|
|
9
9
|
import { loadSchemaAst } from "./config.js";
|
|
10
|
-
import {
|
|
10
|
+
import { connectionString, projectRootFromConfig, resolveRuntimeProvider, schemaPathFromProject, } from "./project-config.js";
|
|
11
11
|
import { signJwt } from "./jwt.js";
|
|
12
|
-
import {
|
|
13
|
-
import {
|
|
12
|
+
import { ensureDevDbPort, ensureKongPort } from "./dev-ports.js";
|
|
13
|
+
import { handleComposeProjectRename } from "./compose-rename.js";
|
|
14
|
+
import { recoverStaleDevSession, writeDevSessionLock } from "./dev-session-lock.js";
|
|
15
|
+
import { readEnvValue, upsertEnvFile } from "./env-file.js";
|
|
16
|
+
import { COMPOSE_PINNED_IMAGE_ENV_KEYS, composeDockerImageEnv, composeProjectName, exitComposeFailed, runDockerCompose, schemaEngineImageForPush, writeSelfHostCompose, } from "./self-host-compose.js";
|
|
14
17
|
import { hasEngineOverride } from "./binary-cache.js";
|
|
15
18
|
import { startStudioViteDevServer } from "./studio-dev-server.js";
|
|
16
19
|
import { ensureEngine, engineRequest } from "./engine-client.js";
|
|
20
|
+
import { writeSchemaSourcePushArtifacts } from "./schema-sources.js";
|
|
21
|
+
import { endDevSession } from "./dev-session.js";
|
|
22
|
+
import { writeLocalEnvironment } from "./link.js";
|
|
23
|
+
import { registerDevShutdown } from "./dev-shutdown.js";
|
|
24
|
+
import { filterComposeNoise, formatEnginePushMessage, parseEngineJsonOutput, parseEnginePushOutput, } from "./engine-push-output.js";
|
|
17
25
|
import { withAdminRoles } from "./studio-admin-roles.js";
|
|
26
|
+
import { restoreSystemRelationTargets } from "./restore-system-relation-targets.js";
|
|
27
|
+
import { provisionBucketsFromAst } from "./storage-provision.js";
|
|
28
|
+
import { ensureFirstAdminUserForProject } from "./commands/admin.js";
|
|
18
29
|
const LOCAL_JWT_SECRET = "super-secret-jwt-token-with-at-least-32-characters-long";
|
|
19
30
|
/** Default host port for compose Postgres when `overrides.engine` is set (devLocal). */
|
|
20
31
|
const COMPOSE_DEV_DB_PORT = 54329;
|
|
32
|
+
/** Sync optional Docker image pins from config into `.env` (no JWT rotation). */
|
|
33
|
+
export function syncComposeImagePins(cwd, config) {
|
|
34
|
+
const imagePins = composeDockerImageEnv(config);
|
|
35
|
+
const removeImageKeys = COMPOSE_PINNED_IMAGE_ENV_KEYS.filter((key) => !(key in imagePins));
|
|
36
|
+
upsertEnvFile(cwd, imagePins, removeImageKeys);
|
|
37
|
+
}
|
|
21
38
|
/** In-compose Postgres URL (SCRAM; not published to the host). */
|
|
22
39
|
export function composeDbUrl() {
|
|
23
40
|
return "postgresql://supatype_admin:postgres@db:5432/supatype?sslmode=disable";
|
|
24
41
|
}
|
|
25
42
|
/**
|
|
26
43
|
* Resolve the host Kong port for this project. Persisted in `.env` as
|
|
27
|
-
* SUPATYPE_KONG_PORT
|
|
28
|
-
* (18473) or the next free port, so multiple projects can run concurrently.
|
|
44
|
+
* SUPATYPE_KONG_PORT; prompts when the configured port is already taken.
|
|
29
45
|
*/
|
|
30
46
|
async function resolveDevDbPort(cwd) {
|
|
31
|
-
|
|
32
|
-
if (existsSync(envPath)) {
|
|
33
|
-
const m = readFileSync(envPath, "utf8").match(/^SUPATYPE_DEV_DB_PORT=(\d+)/m);
|
|
34
|
-
if (m && m[1])
|
|
35
|
-
return Number(m[1]);
|
|
36
|
-
}
|
|
37
|
-
let port = COMPOSE_DEV_DB_PORT;
|
|
38
|
-
while (await isPortInUse(port))
|
|
39
|
-
port++;
|
|
40
|
-
return port;
|
|
41
|
-
}
|
|
42
|
-
function readEnvValue(cwd, key, fallback) {
|
|
43
|
-
const envPath = join(cwd, ".env");
|
|
44
|
-
if (existsSync(envPath)) {
|
|
45
|
-
const m = readFileSync(envPath, "utf8").match(new RegExp(`^${key}=(.+)$`, "m"));
|
|
46
|
-
if (m?.[1])
|
|
47
|
-
return m[1].trim();
|
|
48
|
-
}
|
|
49
|
-
return fallback;
|
|
47
|
+
return ensureDevDbPort(cwd);
|
|
50
48
|
}
|
|
51
|
-
/** Postgres DSN for compose db when published to the host (local engine push). */
|
|
52
49
|
function hostComposeDbUrl(cwd) {
|
|
53
50
|
const port = readEnvValue(cwd, "SUPATYPE_DEV_DB_PORT", String(COMPOSE_DEV_DB_PORT));
|
|
54
51
|
const user = readEnvValue(cwd, "POSTGRES_USER", "supatype_admin");
|
|
@@ -56,34 +53,69 @@ function hostComposeDbUrl(cwd) {
|
|
|
56
53
|
const db = readEnvValue(cwd, "POSTGRES_DB", "supatype");
|
|
57
54
|
return `postgresql://${user}:${pass}@127.0.0.1:${port}/${db}?sslmode=disable`;
|
|
58
55
|
}
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
}
|
|
71
|
-
|
|
72
|
-
const
|
|
73
|
-
const
|
|
74
|
-
const
|
|
75
|
-
const
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
56
|
+
/**
|
|
57
|
+
* When `provider: docker` and `overrides.engine` is set, ensure Postgres is published
|
|
58
|
+
* on the host (SUPATYPE_DEV_DB_PORT) so the local engine binary can connect.
|
|
59
|
+
*/
|
|
60
|
+
export async function ensureDockerDbPublishedForHostEngine(cwd, config, brand) {
|
|
61
|
+
if (resolveRuntimeProvider(config) !== "docker") {
|
|
62
|
+
throw new Error("ensureDockerDbPublishedForHostEngine requires provider: docker");
|
|
63
|
+
}
|
|
64
|
+
if (!hasEngineOverride(config)) {
|
|
65
|
+
throw new Error("Docker Postgres is not published to the host without overrides.engine. " +
|
|
66
|
+
"Set overrides.engine in supatype.local.config.ts or pass --connection.");
|
|
67
|
+
}
|
|
68
|
+
const project = composeProjectName(config.project.name);
|
|
69
|
+
const kongPort = await resolveKongPort(cwd);
|
|
70
|
+
const devDbPort = await resolveDevDbPort(cwd);
|
|
71
|
+
const now = Math.floor(Date.now() / 1000);
|
|
72
|
+
const jwtBase = { iss: "supatype", iat: now, exp: now + 315_360_000 };
|
|
73
|
+
const anonKey = signJwt({ ...jwtBase, role: "anon" }, LOCAL_JWT_SECRET);
|
|
74
|
+
const serviceRoleKey = signJwt({ ...jwtBase, role: "service_role" }, LOCAL_JWT_SECRET);
|
|
75
|
+
ensureDevComposeEnv(cwd, config, anonKey, serviceRoleKey, kongPort, devDbPort);
|
|
76
|
+
const paths = writeSelfHostCompose(cwd, config, { devLocal: true });
|
|
77
|
+
const up = runDockerCompose(paths.composePath, ["up", "-d", "db"], cwd, project, {
|
|
78
|
+
quiet: true,
|
|
79
|
+
...(brand !== undefined && { brand }),
|
|
80
80
|
});
|
|
81
|
-
|
|
82
|
-
|
|
81
|
+
if (up !== 0) {
|
|
82
|
+
exitComposeFailed(up, "Could not start Postgres (compose db service).", brand);
|
|
83
|
+
}
|
|
84
|
+
await waitComposeHealthy(paths, cwd, 120_000, project);
|
|
85
|
+
}
|
|
86
|
+
/**
|
|
87
|
+
* True when CLI should publish local Compose Postgres for the host-side engine
|
|
88
|
+
* (local dev with overrides.engine). False for remote DB URLs via config or --connection.
|
|
89
|
+
*/
|
|
90
|
+
export function usesLocalDockerEngineDb(config, explicitConnection) {
|
|
91
|
+
if (explicitConnection?.trim())
|
|
92
|
+
return false;
|
|
93
|
+
if (config.connection?.trim())
|
|
94
|
+
return false;
|
|
95
|
+
return resolveRuntimeProvider(config) === "docker" && hasEngineOverride(config);
|
|
96
|
+
}
|
|
97
|
+
/**
|
|
98
|
+
* Resolve a Postgres URL reachable from the host-side engine binary.
|
|
99
|
+
* Local docker + overrides.engine → SUPATYPE_DEV_DB_PORT on localhost.
|
|
100
|
+
* Remote self-host → set `connection` in config or pass `--connection`.
|
|
101
|
+
*/
|
|
102
|
+
export async function resolveHostEngineDatabaseUrl(cwd, config, explicit) {
|
|
103
|
+
if (explicit?.trim())
|
|
104
|
+
return explicit;
|
|
105
|
+
if (config.connection?.trim())
|
|
106
|
+
return config.connection;
|
|
107
|
+
if (usesLocalDockerEngineDb(config)) {
|
|
108
|
+
await ensureDockerDbPublishedForHostEngine(cwd, config);
|
|
109
|
+
return hostComposeDbUrl(cwd);
|
|
110
|
+
}
|
|
111
|
+
return connectionString(config);
|
|
83
112
|
}
|
|
84
|
-
|
|
85
|
-
|
|
113
|
+
async function resolveKongPort(cwd) {
|
|
114
|
+
return ensureKongPort(cwd, { context: "dev" });
|
|
115
|
+
}
|
|
116
|
+
function upsertDevComposeEnv(cwd, config, anonKey, serviceRoleKey, kongPort, devDbPort) {
|
|
86
117
|
const apiUrl = `http://localhost:${kongPort}`;
|
|
118
|
+
const imagePins = composeDockerImageEnv(config);
|
|
87
119
|
const updates = {
|
|
88
120
|
POSTGRES_USER: "supatype_admin",
|
|
89
121
|
POSTGRES_PASSWORD: "postgres",
|
|
@@ -92,16 +124,25 @@ function ensureDevComposeEnv(cwd, anonKey, serviceRoleKey, kongPort, devDbPort)
|
|
|
92
124
|
ANON_KEY: anonKey,
|
|
93
125
|
SERVICE_ROLE_KEY: serviceRoleKey,
|
|
94
126
|
PUBLIC_SUPATYPE_ANON_KEY: anonKey,
|
|
127
|
+
VITE_SUPATYPE_ANON_KEY: anonKey,
|
|
95
128
|
PUBLIC_SUPATYPE_URL: apiUrl,
|
|
96
129
|
SUPATYPE_KONG_PORT: String(kongPort),
|
|
97
130
|
API_EXTERNAL_URL: apiUrl,
|
|
98
131
|
SITE_URL: apiUrl,
|
|
99
132
|
GOTRUE_MAILER_AUTOCONFIRM: "true",
|
|
133
|
+
...imagePins,
|
|
100
134
|
};
|
|
101
135
|
if (devDbPort !== undefined) {
|
|
102
136
|
updates.SUPATYPE_DEV_DB_PORT = String(devDbPort);
|
|
137
|
+
updates.DATABASE_URL =
|
|
138
|
+
`postgresql://supatype_admin:postgres@localhost:${devDbPort}/supatype?sslmode=disable`;
|
|
103
139
|
}
|
|
104
|
-
|
|
140
|
+
const removeImageKeys = COMPOSE_PINNED_IMAGE_ENV_KEYS.filter((key) => !(key in imagePins));
|
|
141
|
+
upsertEnvFile(cwd, updates, removeImageKeys);
|
|
142
|
+
}
|
|
143
|
+
/** Keep compose + Studio on the same freshly signed dev JWTs; sync optional image pins from config. */
|
|
144
|
+
function ensureDevComposeEnv(cwd, config, anonKey, serviceRoleKey, kongPort, devDbPort) {
|
|
145
|
+
upsertDevComposeEnv(cwd, config, anonKey, serviceRoleKey, kongPort, devDbPort);
|
|
105
146
|
}
|
|
106
147
|
async function waitComposeHealthy(paths, cwd, maxMs, composeProject) {
|
|
107
148
|
const composeDir = dirname(paths.composePath);
|
|
@@ -133,8 +174,13 @@ async function waitKongReady(kongPort, maxSec) {
|
|
|
133
174
|
}
|
|
134
175
|
throw new Error(`Kong gateway at ${base} did not become ready within ${maxSec}s`);
|
|
135
176
|
}
|
|
177
|
+
async function provisionDockerStorageBuckets(ast, kongPort, serviceRoleKey) {
|
|
178
|
+
await provisionBucketsFromAst(ast, `http://localhost:${kongPort}/storage/v1`, serviceRoleKey);
|
|
179
|
+
}
|
|
136
180
|
let _lastPushedAst = null;
|
|
137
181
|
let _lastFailedAst = null;
|
|
182
|
+
let _composePushInFlight = false;
|
|
183
|
+
let _composePushQueued = false;
|
|
138
184
|
/**
|
|
139
185
|
* Regenerate admin-config + TypeScript types from the AST using the **host** engine.
|
|
140
186
|
* Only schema push/migrate runs in compose (Postgres is not on the host).
|
|
@@ -175,6 +221,7 @@ async function refreshSchemaArtifacts(cwd, config, ast) {
|
|
|
175
221
|
}
|
|
176
222
|
try {
|
|
177
223
|
const admin = withAdminRoles(await engineRequest("/admin", { ast }), config);
|
|
224
|
+
restoreSystemRelationTargets(admin, ast);
|
|
178
225
|
writeFileSync(adminConfigPath, `${JSON.stringify(admin, null, 2)}\n`);
|
|
179
226
|
console.log("[supatype] Admin config written to .supatype/admin-config.json");
|
|
180
227
|
}
|
|
@@ -202,12 +249,19 @@ async function runComposeSchemaPush(cwd, config, paths, schemaPath, composeProje
|
|
|
202
249
|
console.log("[supatype] Applying schema via local engine (overrides.engine)...");
|
|
203
250
|
await ensureEngine();
|
|
204
251
|
const pgSchema = config.schema?.pg_schema ?? "public";
|
|
252
|
+
const sources = writeSchemaSourcePushArtifacts(cwd);
|
|
205
253
|
try {
|
|
206
254
|
await engineRequest("/push", {
|
|
207
255
|
ast,
|
|
208
256
|
database_url: hostComposeDbUrl(cwd),
|
|
209
257
|
schema: pgSchema,
|
|
210
258
|
force: true,
|
|
259
|
+
...(sources
|
|
260
|
+
? {
|
|
261
|
+
schema_sources_gz_base64: sources.payload.dataBase64,
|
|
262
|
+
schema_sources_manifest: sources.payload.manifest,
|
|
263
|
+
}
|
|
264
|
+
: {}),
|
|
211
265
|
});
|
|
212
266
|
}
|
|
213
267
|
catch (err) {
|
|
@@ -216,27 +270,51 @@ async function runComposeSchemaPush(cwd, config, paths, schemaPath, composeProje
|
|
|
216
270
|
}
|
|
217
271
|
_lastPushedAst = astJson;
|
|
218
272
|
_lastFailedAst = null;
|
|
273
|
+
if (astHasSystemAuthRelation(ast)) {
|
|
274
|
+
grantAuthSchemaAccess(paths, cwd, composeProject);
|
|
275
|
+
}
|
|
219
276
|
console.log("[supatype] Schema applied.");
|
|
220
277
|
return;
|
|
221
278
|
}
|
|
222
279
|
console.log("[supatype] Applying schema via compose schema-engine...");
|
|
223
|
-
|
|
280
|
+
const sources = writeSchemaSourcePushArtifacts(cwd);
|
|
281
|
+
let push = await runComposeEnginePush(paths, cwd, composeProject, config, sources);
|
|
224
282
|
// Windows Docker bind mounts can lag briefly after the host write.
|
|
225
283
|
if (push.status !== 0) {
|
|
226
284
|
await new Promise((r) => setTimeout(r, 250));
|
|
227
|
-
push = runComposeEnginePush(paths, cwd, composeProject);
|
|
285
|
+
push = await runComposeEnginePush(paths, cwd, composeProject, config, sources);
|
|
228
286
|
}
|
|
229
287
|
if (push.status !== 0) {
|
|
230
288
|
_lastFailedAst = astJson;
|
|
231
|
-
|
|
289
|
+
const detail = filterComposeNoise(push.output) || push.output;
|
|
290
|
+
throw new Error(detail || `Engine schema push failed (exit ${push.status})`);
|
|
232
291
|
}
|
|
233
292
|
_lastPushedAst = astJson;
|
|
234
293
|
_lastFailedAst = null;
|
|
235
|
-
|
|
294
|
+
if (astHasSystemAuthRelation(ast)) {
|
|
295
|
+
grantAuthSchemaAccess(paths, cwd, composeProject);
|
|
296
|
+
}
|
|
297
|
+
}
|
|
298
|
+
/** Serialize watch-triggered pushes so docker output cannot interleave. */
|
|
299
|
+
async function runComposeSchemaPushQueued(cwd, config, paths, schemaPath, composeProject) {
|
|
300
|
+
if (_composePushInFlight) {
|
|
301
|
+
_composePushQueued = true;
|
|
302
|
+
return;
|
|
303
|
+
}
|
|
304
|
+
_composePushInFlight = true;
|
|
305
|
+
try {
|
|
306
|
+
do {
|
|
307
|
+
_composePushQueued = false;
|
|
308
|
+
await runComposeSchemaPush(cwd, config, paths, schemaPath, composeProject);
|
|
309
|
+
} while (_composePushQueued);
|
|
310
|
+
}
|
|
311
|
+
finally {
|
|
312
|
+
_composePushInFlight = false;
|
|
313
|
+
}
|
|
236
314
|
}
|
|
237
|
-
function runComposeEnginePush(paths, cwd, composeProject) {
|
|
315
|
+
async function runComposeEnginePush(paths, cwd, composeProject, config, sources) {
|
|
238
316
|
const envFile = resolve(cwd, ".env");
|
|
239
|
-
const composeArgs = ["compose"];
|
|
317
|
+
const composeArgs = ["compose", "--progress", "quiet"];
|
|
240
318
|
if (composeProject)
|
|
241
319
|
composeArgs.push("-p", composeProject);
|
|
242
320
|
composeArgs.push("--project-directory", cwd);
|
|
@@ -245,16 +323,125 @@ function runComposeEnginePush(paths, cwd, composeProject) {
|
|
|
245
323
|
composeArgs.push("--env-file", envFile);
|
|
246
324
|
}
|
|
247
325
|
composeArgs.push("--profile", "tools", "run", "--rm", "schema-engine", "push", "-i", "/project/.supatype/schema.ast.json", "--database-url", composeDbUrl(), "--force", "--non-interactive");
|
|
326
|
+
if (sources) {
|
|
327
|
+
composeArgs.push("--schema-sources-gz", sources.dockerGzPath, "--schema-sources-manifest", sources.dockerManifestPath);
|
|
328
|
+
}
|
|
329
|
+
const pushEnv = {
|
|
330
|
+
...process.env,
|
|
331
|
+
COMPOSE_PROGRESS: "quiet",
|
|
332
|
+
};
|
|
333
|
+
const engineImage = await schemaEngineImageForPush(config);
|
|
334
|
+
if (engineImage) {
|
|
335
|
+
pushEnv.SUPATYPE_ENGINE_IMAGE = engineImage;
|
|
336
|
+
}
|
|
248
337
|
const result = spawnSync("docker", composeArgs, {
|
|
249
338
|
cwd,
|
|
250
339
|
encoding: "utf8",
|
|
251
340
|
maxBuffer: 10 * 1024 * 1024,
|
|
341
|
+
env: pushEnv,
|
|
252
342
|
});
|
|
253
343
|
const output = `${result.stdout ?? ""}${result.stderr ?? ""}`.trim();
|
|
254
|
-
|
|
255
|
-
|
|
344
|
+
const exitStatus = result.status ?? 1;
|
|
345
|
+
const pushResult = parseEnginePushOutput(output);
|
|
346
|
+
if (exitStatus === 0) {
|
|
347
|
+
if (pushResult) {
|
|
348
|
+
console.log(`[supatype] ${formatEnginePushMessage(pushResult)}`);
|
|
349
|
+
}
|
|
350
|
+
else {
|
|
351
|
+
console.log("[supatype] Schema applied.");
|
|
352
|
+
}
|
|
256
353
|
}
|
|
257
|
-
return { status:
|
|
354
|
+
return { status: exitStatus, output };
|
|
355
|
+
}
|
|
356
|
+
async function runComposeEngineDiff(paths, cwd, composeProject, config, pgSchema) {
|
|
357
|
+
const envFile = resolve(cwd, ".env");
|
|
358
|
+
const composeArgs = ["compose", "--progress", "quiet"];
|
|
359
|
+
if (composeProject)
|
|
360
|
+
composeArgs.push("-p", composeProject);
|
|
361
|
+
composeArgs.push("--project-directory", cwd);
|
|
362
|
+
composeArgs.push("-f", paths.composePath);
|
|
363
|
+
if (existsSync(envFile)) {
|
|
364
|
+
composeArgs.push("--env-file", envFile);
|
|
365
|
+
}
|
|
366
|
+
composeArgs.push("--profile", "tools", "run", "--rm", "schema-engine", "diff", "-i", "/project/.supatype/schema.ast.json", "--database-url", composeDbUrl(), "--schema", pgSchema);
|
|
367
|
+
const diffEnv = {
|
|
368
|
+
...process.env,
|
|
369
|
+
COMPOSE_PROGRESS: "quiet",
|
|
370
|
+
};
|
|
371
|
+
const engineImage = await schemaEngineImageForPush(config);
|
|
372
|
+
if (engineImage) {
|
|
373
|
+
diffEnv.SUPATYPE_ENGINE_IMAGE = engineImage;
|
|
374
|
+
}
|
|
375
|
+
const result = spawnSync("docker", composeArgs, {
|
|
376
|
+
cwd,
|
|
377
|
+
encoding: "utf8",
|
|
378
|
+
maxBuffer: 10 * 1024 * 1024,
|
|
379
|
+
env: diffEnv,
|
|
380
|
+
});
|
|
381
|
+
const output = `${result.stdout ?? ""}${result.stderr ?? ""}`.trim();
|
|
382
|
+
const exitStatus = result.status ?? 1;
|
|
383
|
+
const diff = parseEngineJsonOutput(output);
|
|
384
|
+
return { status: exitStatus, output, diff };
|
|
385
|
+
}
|
|
386
|
+
/**
|
|
387
|
+
* `supatype diff` when `provider: docker`. Uses in-compose schema-engine unless
|
|
388
|
+
* `overrides.engine` is set — then Postgres is published to the host and diff runs
|
|
389
|
+
* through the local engine binary.
|
|
390
|
+
*/
|
|
391
|
+
export async function diffSchemaDocker(cwd, config) {
|
|
392
|
+
if (resolveRuntimeProvider(config) !== "docker") {
|
|
393
|
+
throw new Error("diffSchemaDocker requires provider: docker");
|
|
394
|
+
}
|
|
395
|
+
const project = composeProjectName(config.project.name);
|
|
396
|
+
const pgSchema = config.schema?.pg_schema ?? "public";
|
|
397
|
+
if (hasEngineOverride(config)) {
|
|
398
|
+
const brand = { intro: "Schema diff" };
|
|
399
|
+
await ensureDockerDbPublishedForHostEngine(cwd, config, brand);
|
|
400
|
+
const schemaPath = schemaPathFromProject(config, cwd);
|
|
401
|
+
const ast = loadSchemaAst(schemaPath, cwd);
|
|
402
|
+
await ensureEngine();
|
|
403
|
+
return engineRequest("/diff", {
|
|
404
|
+
ast,
|
|
405
|
+
database_url: hostComposeDbUrl(cwd),
|
|
406
|
+
schema: pgSchema,
|
|
407
|
+
});
|
|
408
|
+
}
|
|
409
|
+
const kongPort = await resolveKongPort(cwd);
|
|
410
|
+
const now = Math.floor(Date.now() / 1000);
|
|
411
|
+
const jwtBase = { iss: "supatype", iat: now, exp: now + 315_360_000 };
|
|
412
|
+
const anonKey = signJwt({ ...jwtBase, role: "anon" }, LOCAL_JWT_SECRET);
|
|
413
|
+
const serviceRoleKey = signJwt({ ...jwtBase, role: "service_role" }, LOCAL_JWT_SECRET);
|
|
414
|
+
ensureDevComposeEnv(cwd, config, anonKey, serviceRoleKey, kongPort, undefined);
|
|
415
|
+
const paths = writeSelfHostCompose(cwd, config, { devLocal: true });
|
|
416
|
+
const diffBrand = { intro: "Schema diff" };
|
|
417
|
+
const up = runDockerCompose(paths.composePath, ["up", "-d", "db"], cwd, project, {
|
|
418
|
+
quiet: true,
|
|
419
|
+
brand: diffBrand,
|
|
420
|
+
});
|
|
421
|
+
if (up !== 0) {
|
|
422
|
+
exitComposeFailed(up, "Could not start Postgres (compose db service).", diffBrand);
|
|
423
|
+
}
|
|
424
|
+
await waitComposeHealthy(paths, cwd, 120_000, project);
|
|
425
|
+
const schemaPath = schemaPathFromProject(config, cwd);
|
|
426
|
+
const ast = loadSchemaAst(schemaPath, cwd);
|
|
427
|
+
const supatypeDir = join(cwd, ".supatype");
|
|
428
|
+
mkdirSync(supatypeDir, { recursive: true });
|
|
429
|
+
const astPath = join(supatypeDir, "schema.ast.json");
|
|
430
|
+
writeFileSync(astPath, JSON.stringify(ast));
|
|
431
|
+
let result = await runComposeEngineDiff(paths, cwd, project, config, pgSchema);
|
|
432
|
+
// Windows Docker bind mounts can lag briefly after the host write.
|
|
433
|
+
if (result.status !== 0) {
|
|
434
|
+
await new Promise((r) => setTimeout(r, 250));
|
|
435
|
+
result = await runComposeEngineDiff(paths, cwd, project, config, pgSchema);
|
|
436
|
+
}
|
|
437
|
+
if (result.status !== 0) {
|
|
438
|
+
const detail = filterComposeNoise(result.output) || result.output;
|
|
439
|
+
throw new Error(detail || `Engine schema diff failed (exit ${result.status})`);
|
|
440
|
+
}
|
|
441
|
+
if (!result.diff) {
|
|
442
|
+
throw new Error("Engine diff returned no result");
|
|
443
|
+
}
|
|
444
|
+
return result.diff;
|
|
258
445
|
}
|
|
259
446
|
/**
|
|
260
447
|
* `supatype push` when `provider: docker`. Uses in-compose schema-engine unless
|
|
@@ -272,15 +459,33 @@ export async function pushSchemaDocker(cwd, config) {
|
|
|
272
459
|
const jwtBase = { iss: "supatype", iat: now, exp: now + 315_360_000 };
|
|
273
460
|
const anonKey = signJwt({ ...jwtBase, role: "anon" }, LOCAL_JWT_SECRET);
|
|
274
461
|
const serviceRoleKey = signJwt({ ...jwtBase, role: "service_role" }, LOCAL_JWT_SECRET);
|
|
275
|
-
ensureDevComposeEnv(cwd, anonKey, serviceRoleKey, kongPort, devDbPort);
|
|
462
|
+
ensureDevComposeEnv(cwd, config, anonKey, serviceRoleKey, kongPort, devDbPort);
|
|
276
463
|
const paths = writeSelfHostCompose(cwd, config, { devLocal: true });
|
|
464
|
+
const pushBrand = { intro: "Push schema" };
|
|
277
465
|
console.log(`[supatype] provider: docker — applying schema via compose (project ${project})...`);
|
|
278
|
-
const up = runDockerCompose(paths.composePath, ["up", "-d", "db"], cwd, project
|
|
279
|
-
|
|
280
|
-
|
|
466
|
+
const up = runDockerCompose(paths.composePath, ["up", "-d", "db"], cwd, project, {
|
|
467
|
+
quiet: true,
|
|
468
|
+
brand: pushBrand,
|
|
469
|
+
});
|
|
470
|
+
if (up !== 0) {
|
|
471
|
+
exitComposeFailed(up, "Could not start Postgres (compose db service).", pushBrand);
|
|
472
|
+
}
|
|
281
473
|
await waitComposeHealthy(paths, cwd, 120_000, project);
|
|
282
474
|
const schemaPath = schemaPathFromProject(config, cwd);
|
|
475
|
+
const ast = loadSchemaAst(schemaPath, cwd);
|
|
283
476
|
await runComposeSchemaPush(cwd, config, paths, schemaPath, project);
|
|
477
|
+
const upGateway = runDockerCompose(paths.composePath, ["up", "-d"], cwd, project, {
|
|
478
|
+
quiet: true,
|
|
479
|
+
brand: pushBrand,
|
|
480
|
+
});
|
|
481
|
+
if (upGateway !== 0) {
|
|
482
|
+
exitComposeFailed(upGateway, "Could not start the Compose gateway stack.", pushBrand);
|
|
483
|
+
}
|
|
484
|
+
await waitKongReady(kongPort, 120);
|
|
485
|
+
await provisionDockerStorageBuckets(ast, kongPort, serviceRoleKey);
|
|
486
|
+
await ensureFirstAdminUserForProject(cwd, config, {
|
|
487
|
+
compose: { project, composePath: paths.composePath },
|
|
488
|
+
});
|
|
284
489
|
console.log("[supatype] Schema pushed.");
|
|
285
490
|
}
|
|
286
491
|
export async function runDevCompose(cwd, config, opts) {
|
|
@@ -296,18 +501,46 @@ export async function runDevCompose(cwd, config, opts) {
|
|
|
296
501
|
const jwtBase = { iss: "supatype", iat: now, exp: now + 315_360_000 };
|
|
297
502
|
const anonKey = signJwt({ ...jwtBase, role: "anon" }, LOCAL_JWT_SECRET);
|
|
298
503
|
const serviceRoleKey = signJwt({ ...jwtBase, role: "service_role" }, LOCAL_JWT_SECRET);
|
|
299
|
-
ensureDevComposeEnv(cwd, anonKey, serviceRoleKey, kongPort, devDbPort);
|
|
504
|
+
ensureDevComposeEnv(cwd, config, anonKey, serviceRoleKey, kongPort, devDbPort);
|
|
300
505
|
console.log(`[supatype] provider: docker — starting self-host Compose stack (project ${project}, gateway :${kongPort})...`);
|
|
301
506
|
const paths = writeSelfHostCompose(cwd, config, { devLocal: true });
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
507
|
+
await recoverStaleDevSession(cwd);
|
|
508
|
+
await handleComposeProjectRename(cwd, config.project.name, paths);
|
|
509
|
+
const devBrand = { intro: "Local development" };
|
|
510
|
+
const upStatus = runDockerCompose(paths.composePath, ["up", "-d"], cwd, project, {
|
|
511
|
+
quiet: true,
|
|
512
|
+
brand: devBrand,
|
|
513
|
+
});
|
|
514
|
+
if (upStatus !== 0) {
|
|
515
|
+
endDevSession();
|
|
516
|
+
exitComposeFailed(upStatus, "Could not start the local Compose stack.", devBrand);
|
|
517
|
+
}
|
|
305
518
|
console.log("[supatype] Waiting for Postgres (compose)...");
|
|
306
519
|
await waitComposeHealthy(paths, cwd, 180_000, project);
|
|
307
520
|
const schemaPath = schemaPathFromProject(config, cwd);
|
|
308
521
|
await runComposeSchemaPush(cwd, config, paths, schemaPath, project).catch((e) => console.error("[supatype] Initial schema push failed:", e.message));
|
|
522
|
+
await ensureFirstAdminUserForProject(cwd, config, {
|
|
523
|
+
compose: { project, composePath: paths.composePath },
|
|
524
|
+
});
|
|
309
525
|
console.log("[supatype] Waiting for API gateway...");
|
|
310
526
|
await waitKongReady(kongPort, 120);
|
|
527
|
+
writeLocalEnvironment(cwd, {
|
|
528
|
+
target: "local",
|
|
529
|
+
apiUrl: `http://localhost:${kongPort}`,
|
|
530
|
+
databaseUrl: hasEngineOverride(config) ? hostComposeDbUrl(cwd) : composeDbUrl(),
|
|
531
|
+
projectRef: config.project.name,
|
|
532
|
+
kongPort,
|
|
533
|
+
provider: "docker",
|
|
534
|
+
});
|
|
535
|
+
writeDevSessionLock(cwd, {
|
|
536
|
+
composeProject: project,
|
|
537
|
+
projectRef: config.project.name,
|
|
538
|
+
composePath: paths.composePath,
|
|
539
|
+
kongPort,
|
|
540
|
+
startedAt: new Date().toISOString(),
|
|
541
|
+
});
|
|
542
|
+
const ast = loadSchemaAst(schemaPath, cwd);
|
|
543
|
+
await provisionDockerStorageBuckets(ast, kongPort, serviceRoleKey);
|
|
311
544
|
const pidDir = join(homedir(), ".supatype", "projects", config.project.name, "pid");
|
|
312
545
|
mkdirSync(pidDir, { recursive: true });
|
|
313
546
|
let studioProc = null;
|
|
@@ -343,21 +576,34 @@ export async function runDevCompose(cwd, config, opts) {
|
|
|
343
576
|
Press Ctrl+C to stop.
|
|
344
577
|
`);
|
|
345
578
|
const appProc = startProxyDevApp(cwd, config, pidDir);
|
|
346
|
-
|
|
347
|
-
|
|
579
|
+
let schemaWatcher = null;
|
|
580
|
+
let debounceTimer = null;
|
|
581
|
+
registerDevShutdown(async () => {
|
|
582
|
+
schemaWatcher?.close();
|
|
583
|
+
schemaWatcher = null;
|
|
584
|
+
if (debounceTimer) {
|
|
585
|
+
clearTimeout(debounceTimer);
|
|
586
|
+
debounceTimer = null;
|
|
587
|
+
}
|
|
588
|
+
console.log("[supatype] Shutting down compose...");
|
|
348
589
|
await studioProc?.stop();
|
|
349
590
|
await appProc?.stop();
|
|
350
|
-
runDockerCompose(paths.composePath, ["down"], cwd, project);
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
591
|
+
const downStatus = runDockerCompose(paths.composePath, ["down"], cwd, project, { quiet: true });
|
|
592
|
+
if (downStatus === 0) {
|
|
593
|
+
console.log("[supatype] Compose stack stopped.");
|
|
594
|
+
}
|
|
595
|
+
else {
|
|
596
|
+
console.warn(`[supatype] Compose down exited with status ${downStatus}.`);
|
|
597
|
+
}
|
|
598
|
+
}, {
|
|
599
|
+
cwd,
|
|
600
|
+
compose: { cwd, composePath: paths.composePath, composeProject: project },
|
|
601
|
+
});
|
|
355
602
|
if (opts.watch) {
|
|
356
603
|
const schemaDir = join(projectRootFromConfig(config, cwd), config.schema?.path ?? "schema/index.ts", "..");
|
|
357
604
|
console.log(`[supatype] Watching ${schemaDir} for changes...`);
|
|
358
605
|
const { watch } = await import("node:fs");
|
|
359
|
-
|
|
360
|
-
watch(schemaDir, { recursive: true }, (_eventType, filename) => {
|
|
606
|
+
schemaWatcher = watch(schemaDir, { recursive: true }, (_eventType, filename) => {
|
|
361
607
|
if (!filename?.endsWith(".ts"))
|
|
362
608
|
return;
|
|
363
609
|
if (debounceTimer)
|
|
@@ -365,10 +611,42 @@ export async function runDevCompose(cwd, config, opts) {
|
|
|
365
611
|
debounceTimer = setTimeout(() => {
|
|
366
612
|
debounceTimer = null;
|
|
367
613
|
console.log(`\n[supatype] Change detected in ${filename}, pushing schema...`);
|
|
368
|
-
|
|
614
|
+
runComposeSchemaPushQueued(cwd, config, paths, schemaPath, project)
|
|
615
|
+
.then(async () => {
|
|
616
|
+
const updatedAst = loadSchemaAst(schemaPath, cwd);
|
|
617
|
+
await provisionDockerStorageBuckets(updatedAst, kongPort, serviceRoleKey);
|
|
618
|
+
})
|
|
619
|
+
.catch((e) => console.error("[supatype] Schema push failed:", e.message));
|
|
369
620
|
}, 300);
|
|
370
621
|
});
|
|
371
622
|
}
|
|
372
623
|
await new Promise(() => undefined);
|
|
373
624
|
}
|
|
625
|
+
function astHasSystemAuthRelation(ast) {
|
|
626
|
+
const obj = ast;
|
|
627
|
+
if (!obj?.models)
|
|
628
|
+
return false;
|
|
629
|
+
for (const model of obj.models) {
|
|
630
|
+
if (!model.fields)
|
|
631
|
+
continue;
|
|
632
|
+
for (const field of Object.values(model.fields)) {
|
|
633
|
+
if (field.kind === "relation" && field.target === "supatype:user")
|
|
634
|
+
return true;
|
|
635
|
+
}
|
|
636
|
+
}
|
|
637
|
+
return false;
|
|
638
|
+
}
|
|
639
|
+
function grantAuthSchemaAccess(paths, cwd, composeProject) {
|
|
640
|
+
const composeDir = dirname(paths.composePath);
|
|
641
|
+
const baseArgs = [
|
|
642
|
+
"compose", "-p", composeProject,
|
|
643
|
+
"-f", paths.composePath,
|
|
644
|
+
];
|
|
645
|
+
const sql = "GRANT USAGE ON SCHEMA auth TO service_role; GRANT SELECT ON auth.users TO service_role;";
|
|
646
|
+
const result = spawnSync("docker", [...baseArgs, "exec", "-T", "-e", "PGPASSWORD=postgres", "db",
|
|
647
|
+
"psql", "-U", "supatype_admin", "-d", "supatype", "-c", sql], { cwd: composeDir, encoding: "utf8", timeout: 10_000 });
|
|
648
|
+
if (result.status !== 0) {
|
|
649
|
+
console.warn("[supatype] Could not grant service_role access to auth.users — Studio relation preview may fail.");
|
|
650
|
+
}
|
|
651
|
+
}
|
|
374
652
|
//# sourceMappingURL=dev-compose.js.map
|