@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/src/self-host-compose.ts
CHANGED
|
@@ -1,10 +1,135 @@
|
|
|
1
|
-
import { existsSync, mkdirSync, writeFileSync } from "node:fs"
|
|
1
|
+
import { existsSync, mkdirSync, readFileSync, writeFileSync } from "node:fs"
|
|
2
2
|
import { dirname, join, relative, resolve } from "node:path"
|
|
3
3
|
import { spawnSync } from "node:child_process"
|
|
4
|
-
import {
|
|
5
|
-
import {
|
|
4
|
+
import { requireDockerDaemon, type DockerBrandOptions } from "./docker-runtime.js"
|
|
5
|
+
import { fatalError } from "./ui/fatal.js"
|
|
6
|
+
import { preferredFunctionsPathFromProject, selfHostTlsEnabled, type SupatypeProjectConfig } from "./project-config.js"
|
|
7
|
+
import { hasEngineOverride, hasStudioOverride, pinnedVersion, fetchLatestVersion, VERSION_PIN_LOCAL } from "./binary-cache.js"
|
|
6
8
|
import { buildKongDeclarative } from "./kong-config.js"
|
|
7
9
|
|
|
10
|
+
/** Env keys written when `versions` pins exist in supatype.config.ts. */
|
|
11
|
+
export const COMPOSE_PINNED_IMAGE_ENV_KEYS = [
|
|
12
|
+
"SUPATYPE_ENGINE_IMAGE",
|
|
13
|
+
"SUPATYPE_SERVER_IMAGE",
|
|
14
|
+
"SUPATYPE_POSTGRES_IMAGE",
|
|
15
|
+
] as const
|
|
16
|
+
|
|
17
|
+
/** Compose image env vars that may be overridden manually in `.env`. */
|
|
18
|
+
export const COMPOSE_IMAGE_ENV_KEYS = [
|
|
19
|
+
...COMPOSE_PINNED_IMAGE_ENV_KEYS,
|
|
20
|
+
"SUPATYPE_CONTROL_PLANE_IMAGE",
|
|
21
|
+
"SUPATYPE_AUTH_IMAGE",
|
|
22
|
+
"SUPATYPE_STUDIO_IMAGE",
|
|
23
|
+
"SUPATYPE_STORAGE_IMAGE",
|
|
24
|
+
"SUPATYPE_FUNCTIONS_WORKER_IMAGE",
|
|
25
|
+
] as const
|
|
26
|
+
|
|
27
|
+
type DockerPinComponent = "engine" | "server" | "postgres"
|
|
28
|
+
|
|
29
|
+
/** Map a config version pin to a Docker Hub image reference. */
|
|
30
|
+
export function dockerImageRef(
|
|
31
|
+
component: DockerPinComponent,
|
|
32
|
+
version: string,
|
|
33
|
+
config?: SupatypeProjectConfig,
|
|
34
|
+
): string {
|
|
35
|
+
const trimmed = version.trim()
|
|
36
|
+
switch (component) {
|
|
37
|
+
case "engine":
|
|
38
|
+
return `supatype/schema-engine:${trimmed.startsWith("v") ? trimmed : `v${trimmed}`}`
|
|
39
|
+
case "server":
|
|
40
|
+
return `supatype/server:${trimmed.startsWith("v") ? trimmed : `v${trimmed}`}`
|
|
41
|
+
case "postgres": {
|
|
42
|
+
const override = config?.database?.image?.trim()
|
|
43
|
+
if (override) return override
|
|
44
|
+
if (trimmed.includes("-latest")) return `supatype/postgres:${trimmed}`
|
|
45
|
+
const major = trimmed.split(".")[0]
|
|
46
|
+
return `supatype/postgres:${major}-latest`
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
/**
|
|
52
|
+
* When the user pins `versions` in config, sync matching SUPATYPE_*_IMAGE vars for Compose.
|
|
53
|
+
* Unpinned components are omitted so compose falls back to :latest defaults.
|
|
54
|
+
*/
|
|
55
|
+
export function composeDockerImageEnv(config: SupatypeProjectConfig): Record<string, string> {
|
|
56
|
+
const env: Record<string, string> = {}
|
|
57
|
+
const versions = config.versions
|
|
58
|
+
if (!versions) return env
|
|
59
|
+
|
|
60
|
+
if (versions.engine && versions.engine !== VERSION_PIN_LOCAL) {
|
|
61
|
+
env.SUPATYPE_ENGINE_IMAGE = dockerImageRef("engine", versions.engine)
|
|
62
|
+
}
|
|
63
|
+
if (versions.server && versions.server !== VERSION_PIN_LOCAL) {
|
|
64
|
+
env.SUPATYPE_SERVER_IMAGE = dockerImageRef("server", versions.server)
|
|
65
|
+
}
|
|
66
|
+
if (versions.postgres && versions.postgres !== VERSION_PIN_LOCAL) {
|
|
67
|
+
env.SUPATYPE_POSTGRES_IMAGE = dockerImageRef("postgres", versions.postgres, config)
|
|
68
|
+
}
|
|
69
|
+
return env
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
/** True when a Docker image tag is a semver/latest ref we expect `docker pull` to resolve. */
|
|
73
|
+
export function isRegistryPullableImageRef(ref: string): boolean {
|
|
74
|
+
const trimmed = ref.trim()
|
|
75
|
+
if (!trimmed) return true
|
|
76
|
+
const tag = trimmed.includes(":") ? trimmed.slice(trimmed.lastIndexOf(":") + 1) : "latest"
|
|
77
|
+
if (tag === "latest") return true
|
|
78
|
+
if (/^v?\d+\.\d+/.test(tag)) return true
|
|
79
|
+
if (/^\d+-latest$/.test(tag)) return true
|
|
80
|
+
return false
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
export function hasLocalVersionPins(config: SupatypeProjectConfig): boolean {
|
|
84
|
+
const versions = config.versions
|
|
85
|
+
if (!versions) return false
|
|
86
|
+
return (
|
|
87
|
+
versions.engine === VERSION_PIN_LOCAL ||
|
|
88
|
+
versions.server === VERSION_PIN_LOCAL ||
|
|
89
|
+
versions.postgres === VERSION_PIN_LOCAL ||
|
|
90
|
+
versions.deno === VERSION_PIN_LOCAL
|
|
91
|
+
)
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
function readComposeImageEnvValues(cwd: string): string[] {
|
|
95
|
+
const envPath = resolve(cwd, ".env")
|
|
96
|
+
if (!existsSync(envPath)) return []
|
|
97
|
+
const text = readFileSync(envPath, "utf8")
|
|
98
|
+
const values: string[] = []
|
|
99
|
+
for (const key of COMPOSE_IMAGE_ENV_KEYS) {
|
|
100
|
+
const match = text.match(new RegExp(`^${key}=(.+)$`, "m"))
|
|
101
|
+
if (match?.[1]) values.push(match[1].trim())
|
|
102
|
+
}
|
|
103
|
+
return values
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
/**
|
|
107
|
+
* Use `docker compose pull --ignore-pull-failures` only when the project may
|
|
108
|
+
* reference local-only images (config `versions: local` or custom `.env` tags).
|
|
109
|
+
*/
|
|
110
|
+
export function composePullNeedsIgnoreFailures(
|
|
111
|
+
config: SupatypeProjectConfig,
|
|
112
|
+
cwd: string = process.cwd(),
|
|
113
|
+
): boolean {
|
|
114
|
+
if (hasLocalVersionPins(config)) return true
|
|
115
|
+
return readComposeImageEnvValues(cwd).some((ref) => !isRegistryPullableImageRef(ref))
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
/**
|
|
119
|
+
* Schema-engine image for a one-off `docker compose run` when pushing schema.
|
|
120
|
+
* Uses config pin when set; otherwise CDN engine semver (Docker Hub `:latest` can lag).
|
|
121
|
+
* Does not touch `.env` — server/postgres still use compose `:latest` defaults.
|
|
122
|
+
*/
|
|
123
|
+
export async function schemaEngineImageForPush(
|
|
124
|
+
config: SupatypeProjectConfig,
|
|
125
|
+
): Promise<string | undefined> {
|
|
126
|
+
const pinned = pinnedVersion("engine", config)
|
|
127
|
+
if (pinned === VERSION_PIN_LOCAL) return undefined
|
|
128
|
+
if (pinned) return dockerImageRef("engine", pinned)
|
|
129
|
+
const version = await fetchLatestVersion("engine")
|
|
130
|
+
return dockerImageRef("engine", version)
|
|
131
|
+
}
|
|
132
|
+
|
|
8
133
|
export interface SelfHostComposePaths {
|
|
9
134
|
dir: string
|
|
10
135
|
composePath: string
|
|
@@ -59,21 +184,9 @@ function kongMountPath(_cwd: string): string {
|
|
|
59
184
|
/** Host Vite dev server as seen from Kong inside Docker Compose. */
|
|
60
185
|
export const COMPOSE_STUDIO_HOST_URL = "http://host.docker.internal:3002"
|
|
61
186
|
|
|
62
|
-
/**
|
|
63
|
-
function studioServiceBlock(
|
|
64
|
-
|
|
65
|
-
return ` image: \${SUPATYPE_STUDIO_IMAGE:-supatype/studio:latest}`
|
|
66
|
-
}
|
|
67
|
-
const monorepoRoot = resolve(cwd, "..", "supatype")
|
|
68
|
-
const studioDockerfile = join(monorepoRoot, "packages", "studio", "Dockerfile")
|
|
69
|
-
if (!existsSync(studioDockerfile) || !existsSync(join(monorepoRoot, "pnpm-workspace.yaml"))) {
|
|
70
|
-
return ` image: \${SUPATYPE_STUDIO_IMAGE:-supatype/studio:latest}`
|
|
71
|
-
}
|
|
72
|
-
const context = relativeFromProjectRoot(cwd, monorepoRoot)
|
|
73
|
-
return ` build:
|
|
74
|
-
context: ${context}
|
|
75
|
-
dockerfile: packages/studio/Dockerfile
|
|
76
|
-
image: supatype/studio:dev-local`
|
|
187
|
+
/** Studio container — always Docker Hub unless SUPATYPE_STUDIO_IMAGE is set in .env. */
|
|
188
|
+
function studioServiceBlock(): string {
|
|
189
|
+
return ` image: \${SUPATYPE_STUDIO_IMAGE:-supatype/studio:latest}`
|
|
77
190
|
}
|
|
78
191
|
|
|
79
192
|
/** Host dev app (Astro/Vite on the machine) as seen from inside compose services. */
|
|
@@ -101,6 +214,11 @@ function serverAppEnvForCompose(config: SupatypeProjectConfig, devLocal: boolean
|
|
|
101
214
|
} else if (mode === "proxy" && config.app.upstream?.trim()) {
|
|
102
215
|
lines.push(` SUPATYPE_APP_UPSTREAM: ${proxyUpstreamForCompose(config.app.upstream, devLocal)}`)
|
|
103
216
|
}
|
|
217
|
+
if (config.app.vite_dev_url?.trim()) {
|
|
218
|
+
lines.push(
|
|
219
|
+
` SUPATYPE_VITE_DEV_URL: ${proxyUpstreamForCompose(config.app.vite_dev_url, devLocal)}`,
|
|
220
|
+
)
|
|
221
|
+
}
|
|
104
222
|
return lines.join("\n")
|
|
105
223
|
}
|
|
106
224
|
|
|
@@ -117,23 +235,32 @@ export function renderSelfHostCompose(
|
|
|
117
235
|
const projectMount = projectMountPath(cwd)
|
|
118
236
|
const kongMount = kongMountPath(cwd)
|
|
119
237
|
const devLocal = options?.devLocal === true
|
|
238
|
+
const tlsEnabled = selfHostTlsEnabled(config, devLocal)
|
|
239
|
+
const domain = config.server.domain?.trim() ?? ""
|
|
240
|
+
// When TLS is on, default external URLs to https://<domain> so auth links/redirects use HTTPS.
|
|
241
|
+
const externalUrlFallback = tlsEnabled ? `https://${domain}` : "http://localhost:18473"
|
|
242
|
+
const siteUrlFallback = tlsEnabled ? `https://${domain}` : "http://localhost:3000"
|
|
120
243
|
const studioHostDev = devLocal && hasStudioOverride(config)
|
|
121
244
|
const appEnv = serverAppEnvForCompose(config, devLocal)
|
|
122
|
-
const
|
|
245
|
+
const staticDir = staticDirForCompose(config) ?? "./dist"
|
|
246
|
+
const composeProject = composeProjectName(config.project.name)
|
|
247
|
+
const studioService = studioServiceBlock()
|
|
123
248
|
const studioBlock = studioHostDev
|
|
124
249
|
? ""
|
|
125
250
|
: `
|
|
126
251
|
studio:
|
|
127
252
|
${studioService}
|
|
128
253
|
environment:
|
|
129
|
-
SUPATYPE_CLOUD_JSON: '{"url":"\${API_EXTERNAL_URL
|
|
254
|
+
SUPATYPE_CLOUD_JSON: '{"url":"\${API_EXTERNAL_URL:-${externalUrlFallback}}","anonKey":"\${ANON_KEY:-}"}'
|
|
130
255
|
expose:
|
|
131
256
|
- "3002"
|
|
132
257
|
`
|
|
133
258
|
const kongDependsOn = studioHostDev
|
|
134
|
-
? ` - server
|
|
259
|
+
? ` - server
|
|
260
|
+
- control-plane`
|
|
135
261
|
: ` - server
|
|
136
|
-
- studio
|
|
262
|
+
- studio
|
|
263
|
+
- control-plane`
|
|
137
264
|
const publishDbToHost = !devLocal || hasEngineOverride(config)
|
|
138
265
|
const dbPorts = publishDbToHost
|
|
139
266
|
? devLocal
|
|
@@ -155,6 +282,44 @@ ${studioService}
|
|
|
155
282
|
- "9000:9000"
|
|
156
283
|
- "9001:9001"
|
|
157
284
|
`
|
|
285
|
+
const kongTlsEnv = tlsEnabled
|
|
286
|
+
? ` KONG_PROXY_LISTEN: "0.0.0.0:8000, 0.0.0.0:8443 ssl"
|
|
287
|
+
KONG_LUA_SSL_TRUSTED_CERTIFICATE: system
|
|
288
|
+
KONG_LUA_SSL_VERIFY_DEPTH: "2"
|
|
289
|
+
`
|
|
290
|
+
: ""
|
|
291
|
+
const kongPorts = tlsEnabled
|
|
292
|
+
? ` - "80:8000"
|
|
293
|
+
- "443:8443"`
|
|
294
|
+
: ` - "\${SUPATYPE_KONG_PORT:-18473}:8000"`
|
|
295
|
+
const kongTlsDependsOn = tlsEnabled ? "\n - valkey" : ""
|
|
296
|
+
const valkeyBlock = tlsEnabled
|
|
297
|
+
? `
|
|
298
|
+
valkey:
|
|
299
|
+
image: \${SUPATYPE_VALKEY_IMAGE:-valkey/valkey:8-alpine}
|
|
300
|
+
command: ["valkey-server", "--appendonly", "yes"]
|
|
301
|
+
expose:
|
|
302
|
+
- "6379"
|
|
303
|
+
volumes:
|
|
304
|
+
- valkey-data:/data
|
|
305
|
+
`
|
|
306
|
+
: ""
|
|
307
|
+
const tlsHintComment = tlsEnabled
|
|
308
|
+
? ""
|
|
309
|
+
: ` # HTTPS is off. To enable automatic TLS (Let's Encrypt) for production, set in supatype.config.ts:
|
|
310
|
+
# server: { mode: "standalone", domain: "your.domain", tls: { email: "you@example.com" } }
|
|
311
|
+
# then re-run \`supatype self-host compose up -d\`. Kong publishes :80/:443 and provisions certs automatically.
|
|
312
|
+
`
|
|
313
|
+
const volumesBlock = tlsEnabled
|
|
314
|
+
? `volumes:
|
|
315
|
+
db-data:
|
|
316
|
+
minio-data:
|
|
317
|
+
valkey-data:
|
|
318
|
+
`
|
|
319
|
+
: `volumes:
|
|
320
|
+
db-data:
|
|
321
|
+
minio-data:
|
|
322
|
+
`
|
|
158
323
|
|
|
159
324
|
return `# Generated by supatype self-host compose
|
|
160
325
|
# Kong → supatype-server (unified gateway) → internal PostgREST / storage / etc.
|
|
@@ -179,7 +344,7 @@ ${dbPorts} volumes:
|
|
|
179
344
|
- "3000"
|
|
180
345
|
environment:
|
|
181
346
|
PGRST_DB_URI: postgresql://\${POSTGRES_USER:-supatype_admin}:\${POSTGRES_PASSWORD:-postgres}@db:5432/\${POSTGRES_DB:-supatype}
|
|
182
|
-
PGRST_DB_SCHEMA: "public, supatype, graphql_public"
|
|
347
|
+
PGRST_DB_SCHEMA: "public, supatype, graphql_public, auth"
|
|
183
348
|
PGRST_DB_ANON_ROLE: anon
|
|
184
349
|
PGRST_JWT_SECRET: \${JWT_SECRET:-super-secret-jwt-token-change-in-production}
|
|
185
350
|
PGRST_DB_EXTRA_SEARCH_PATH: public,extensions
|
|
@@ -215,12 +380,33 @@ ${dbPorts} volumes:
|
|
|
215
380
|
SUPATYPE_FUNCTIONS_ROOT: /project/functions
|
|
216
381
|
SUPATYPE_DENO_FUNCTIONS_DIR: /project/functions
|
|
217
382
|
PORT: "8001"
|
|
218
|
-
SUPATYPE_URL: \${API_EXTERNAL_URL
|
|
383
|
+
SUPATYPE_URL: \${API_EXTERNAL_URL:-${externalUrlFallback}}
|
|
219
384
|
SUPATYPE_ANON_KEY: \${ANON_KEY:-}
|
|
220
385
|
SUPATYPE_SERVICE_ROLE_KEY: \${SERVICE_ROLE_KEY:-}
|
|
221
386
|
STRIPE_SECRET_KEY: \${STRIPE_SECRET_KEY:-}
|
|
222
387
|
STRIPE_WEBHOOK_SECRET: \${STRIPE_WEBHOOK_SECRET:-}
|
|
223
|
-
SITE_URL: \${SITE_URL:-\${API_EXTERNAL_URL
|
|
388
|
+
SITE_URL: \${SITE_URL:-\${API_EXTERNAL_URL:-${externalUrlFallback}}}
|
|
389
|
+
depends_on:
|
|
390
|
+
db:
|
|
391
|
+
condition: service_healthy
|
|
392
|
+
|
|
393
|
+
control-plane:
|
|
394
|
+
image: \${SUPATYPE_CONTROL_PLANE_IMAGE:-supatype/control-plane:latest}
|
|
395
|
+
expose:
|
|
396
|
+
- "8080"
|
|
397
|
+
volumes:
|
|
398
|
+
- ${projectMount}:/project
|
|
399
|
+
- /var/run/docker.sock:/var/run/docker.sock
|
|
400
|
+
environment:
|
|
401
|
+
PORT: "8080"
|
|
402
|
+
SUPATYPE_PROJECT_REF: ${JSON.stringify(config.project.name)}
|
|
403
|
+
SUPATYPE_PROJECT_ROOT: /project
|
|
404
|
+
DATABASE_URL: "postgresql://\${POSTGRES_USER:-supatype_admin}:\${POSTGRES_PASSWORD:-postgres}@db:5432/\${POSTGRES_DB:-supatype}"
|
|
405
|
+
SUPATYPE_FUNCTIONS_ROOT: /project/functions
|
|
406
|
+
SUPATYPE_STATIC_ROOT: /project/${staticDir.replace(/^\.\//, "")}
|
|
407
|
+
SUPATYPE_DEPLOYMENTS_DIR: /project/.supatype/deployments
|
|
408
|
+
COMPOSE_PROJECT_NAME: ${composeProject}
|
|
409
|
+
SUPATYPE_ENGINE_BIN: supatype-engine
|
|
224
410
|
depends_on:
|
|
225
411
|
db:
|
|
226
412
|
condition: service_healthy
|
|
@@ -232,26 +418,27 @@ ${serverPorts} volumes:
|
|
|
232
418
|
working_dir: /project
|
|
233
419
|
environment:
|
|
234
420
|
SUPATYPE_MODE: ${devLocal ? "dev" : "standalone"}
|
|
235
|
-
SUPATYPE_MANIFEST_PATH:
|
|
236
|
-
SUPATYPE_ADMIN_CONFIG_PATH:
|
|
237
|
-
SUPATYPE_API_CONFIG_PATH:
|
|
421
|
+
SUPATYPE_MANIFEST_PATH: .supatype/manifest.json
|
|
422
|
+
SUPATYPE_ADMIN_CONFIG_PATH: .supatype/admin-config.json
|
|
423
|
+
SUPATYPE_API_CONFIG_PATH: .supatype/api-config.json
|
|
238
424
|
SUPATYPE_POSTGREST_URL: http://postgrest:3000
|
|
239
425
|
SUPATYPE_GRAPHQL_URL: http://postgrest:3000
|
|
240
426
|
SUPATYPE_STORAGE_URL: http://storage:5000
|
|
241
|
-
SUPATYPE_URL: \${API_EXTERNAL_URL
|
|
427
|
+
SUPATYPE_URL: \${API_EXTERNAL_URL:-${externalUrlFallback}}
|
|
242
428
|
SUPATYPE_ANON_KEY: \${ANON_KEY:-}
|
|
243
429
|
SUPATYPE_SERVICE_ROLE_KEY: \${SERVICE_ROLE_KEY:-}
|
|
244
430
|
SUPATYPE_SQL_DATABASE_URL: "postgresql://\${POSTGRES_USER:-supatype_admin}:\${POSTGRES_PASSWORD:-postgres}@db:5432/\${POSTGRES_DB:-supatype}"
|
|
245
431
|
SUPATYPE_DENO_FUNCTIONS_DIR: /project/functions
|
|
246
432
|
SUPATYPE_FUNCTIONS_WORKER_URL: http://functions-worker:8001
|
|
433
|
+
SUPATYPE_CONTROL_PLANE_URL: http://control-plane:8080
|
|
247
434
|
${appEnv}
|
|
248
435
|
GOTRUE_API_HOST: 0.0.0.0
|
|
249
436
|
GOTRUE_API_PORT: 9999
|
|
250
|
-
API_EXTERNAL_URL: \${API_EXTERNAL_URL
|
|
251
|
-
GOTRUE_API_EXTERNAL_URL: \${API_EXTERNAL_URL
|
|
437
|
+
API_EXTERNAL_URL: \${API_EXTERNAL_URL:-${externalUrlFallback}}
|
|
438
|
+
GOTRUE_API_EXTERNAL_URL: \${API_EXTERNAL_URL:-${externalUrlFallback}}
|
|
252
439
|
GOTRUE_DB_DRIVER: postgres
|
|
253
440
|
GOTRUE_DB_DATABASE_URL: "postgres://\${POSTGRES_USER:-supatype_admin}:\${POSTGRES_PASSWORD:-postgres}@db:5432/\${POSTGRES_DB:-supatype}?search_path=auth"
|
|
254
|
-
GOTRUE_SITE_URL: \${SITE_URL
|
|
441
|
+
GOTRUE_SITE_URL: \${SITE_URL:-${siteUrlFallback}}
|
|
255
442
|
GOTRUE_JWT_SECRET: \${JWT_SECRET:-super-secret-jwt-token-change-in-production}
|
|
256
443
|
GOTRUE_JWT_EXP: 3600
|
|
257
444
|
GOTRUE_JWT_AUD: authenticated
|
|
@@ -269,6 +456,8 @@ ${devLocal ? " STUDIO_OPEN_DEV: \"1\"\n" : ""}
|
|
|
269
456
|
condition: service_started
|
|
270
457
|
functions-worker:
|
|
271
458
|
condition: service_started
|
|
459
|
+
control-plane:
|
|
460
|
+
condition: service_started
|
|
272
461
|
|
|
273
462
|
minio:
|
|
274
463
|
image: minio/minio:RELEASE.2024-11-07T00-52-20Z
|
|
@@ -289,8 +478,7 @@ ${minioPorts} volumes:
|
|
|
289
478
|
depends_on:
|
|
290
479
|
db:
|
|
291
480
|
condition: service_healthy
|
|
292
|
-
${studioBlock}
|
|
293
|
-
kong:
|
|
481
|
+
${studioBlock}${valkeyBlock}${tlsHintComment} kong:
|
|
294
482
|
image: kong:3.6
|
|
295
483
|
environment:
|
|
296
484
|
KONG_DATABASE: "off"
|
|
@@ -299,17 +487,14 @@ ${studioBlock}
|
|
|
299
487
|
KONG_ADMIN_ACCESS_LOG: /dev/stdout
|
|
300
488
|
KONG_PROXY_ERROR_LOG: /dev/stderr
|
|
301
489
|
KONG_ADMIN_ERROR_LOG: /dev/stderr
|
|
302
|
-
volumes:
|
|
490
|
+
${kongTlsEnv} volumes:
|
|
303
491
|
- ${kongMount}:/etc/kong/kong.yml:ro
|
|
304
492
|
ports:
|
|
305
|
-
|
|
493
|
+
${kongPorts}
|
|
306
494
|
depends_on:
|
|
307
|
-
${kongDependsOn}
|
|
495
|
+
${kongDependsOn}${kongTlsDependsOn}
|
|
308
496
|
|
|
309
|
-
|
|
310
|
-
db-data:
|
|
311
|
-
minio-data:
|
|
312
|
-
`
|
|
497
|
+
${volumesBlock}`
|
|
313
498
|
}
|
|
314
499
|
|
|
315
500
|
function ensureComposeManifest(cwd: string): void {
|
|
@@ -341,6 +526,9 @@ export function writeSelfHostCompose(
|
|
|
341
526
|
ensureComposeManifest(cwd)
|
|
342
527
|
writeFileSync(paths.composePath, renderSelfHostCompose(config, cwd, options), "utf8")
|
|
343
528
|
const studioHostDev = options?.devLocal === true && hasStudioOverride(config)
|
|
529
|
+
const tlsEnabled = selfHostTlsEnabled(config, options?.devLocal === true)
|
|
530
|
+
const domain = config.server.domain?.trim()
|
|
531
|
+
const acmeEmail = config.server.tls?.email?.trim()
|
|
344
532
|
writeFileSync(
|
|
345
533
|
paths.kongPath,
|
|
346
534
|
buildKongDeclarative({
|
|
@@ -349,20 +537,48 @@ export function writeSelfHostCompose(
|
|
|
349
537
|
studioServiceUrl: COMPOSE_STUDIO_HOST_URL,
|
|
350
538
|
studioStripPath: false,
|
|
351
539
|
}),
|
|
540
|
+
...(tlsEnabled && domain && acmeEmail
|
|
541
|
+
? { acme: { email: acmeEmail, domain, redisHost: "valkey" } }
|
|
542
|
+
: {}),
|
|
352
543
|
}),
|
|
353
544
|
"utf8",
|
|
354
545
|
)
|
|
355
546
|
return paths
|
|
356
547
|
}
|
|
357
548
|
|
|
549
|
+
export interface RunDockerComposeOptions {
|
|
550
|
+
/** Suppress docker compose progress UI (container status lines). */
|
|
551
|
+
quiet?: boolean
|
|
552
|
+
/** Logo + Clack intro when Docker preflight fails (TTY). */
|
|
553
|
+
brand?: DockerBrandOptions
|
|
554
|
+
}
|
|
555
|
+
|
|
556
|
+
/** Exit with a friendly compose failure message. */
|
|
557
|
+
export function exitComposeFailed(
|
|
558
|
+
status: number,
|
|
559
|
+
context: string,
|
|
560
|
+
brand?: DockerBrandOptions,
|
|
561
|
+
): never {
|
|
562
|
+
fatalError(
|
|
563
|
+
`docker compose failed (exit ${status}).`,
|
|
564
|
+
[context, "Check logs: supatype self-host compose logs"],
|
|
565
|
+
{ ...(brand !== undefined && { brand }), exitCode: status === 0 ? 1 : status },
|
|
566
|
+
)
|
|
567
|
+
}
|
|
568
|
+
|
|
358
569
|
export function runDockerCompose(
|
|
359
570
|
composePath: string,
|
|
360
571
|
args: string[],
|
|
361
572
|
projectRoot: string = process.cwd(),
|
|
362
573
|
composeProject?: string,
|
|
574
|
+
options?: RunDockerComposeOptions,
|
|
363
575
|
): number {
|
|
576
|
+
requireDockerDaemon(options?.brand !== undefined ? { brand: options.brand } : undefined)
|
|
364
577
|
const envFile = resolve(projectRoot, ".env")
|
|
365
578
|
const composeArgs = ["compose"]
|
|
579
|
+
if (options?.quiet) {
|
|
580
|
+
composeArgs.push("--progress", "quiet")
|
|
581
|
+
}
|
|
366
582
|
// Per-project name isolates containers/volumes/network so multiple Supatype
|
|
367
583
|
// projects on one machine never share a database (default would be the
|
|
368
584
|
// ".supatype/self-host" dir name, identical for every project).
|
|
@@ -374,11 +590,11 @@ export function runDockerCompose(
|
|
|
374
590
|
composeArgs.push("--env-file", envFile)
|
|
375
591
|
}
|
|
376
592
|
composeArgs.push(...args)
|
|
377
|
-
const
|
|
378
|
-
"
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
)
|
|
593
|
+
const env: NodeJS.ProcessEnv = options?.quiet
|
|
594
|
+
? { ...process.env, COMPOSE_PROGRESS: "quiet" }
|
|
595
|
+
: process.env
|
|
596
|
+
const stdio = options?.quiet ? "pipe" : "inherit"
|
|
597
|
+
const result = spawnSync("docker", composeArgs, { stdio, cwd: projectRoot, env })
|
|
382
598
|
return result.status ?? 1
|
|
383
599
|
}
|
|
384
600
|
|
package/src/storage-provision.ts
CHANGED
|
@@ -6,6 +6,10 @@
|
|
|
6
6
|
* Buckets already registered return 409 Conflict, which is treated as success.
|
|
7
7
|
*/
|
|
8
8
|
|
|
9
|
+
import type { ExtractedSchemaAstV2 } from "./schema-ast-v2.js"
|
|
10
|
+
|
|
11
|
+
export type { ExtractedStorageBucketAst as SchemaStorageBucketAst } from "./schema-ast-v2.js"
|
|
12
|
+
|
|
9
13
|
export interface BucketSpec {
|
|
10
14
|
id: string
|
|
11
15
|
public: boolean
|
|
@@ -15,6 +19,29 @@ export interface BucketSpec {
|
|
|
15
19
|
s3_bucket_policy?: string | null
|
|
16
20
|
}
|
|
17
21
|
|
|
22
|
+
export function bucketSpecsFromAst(ast: Pick<ExtractedSchemaAstV2, "storageBuckets">): BucketSpec[] {
|
|
23
|
+
return (ast.storageBuckets ?? []).map((b) => ({
|
|
24
|
+
id: b.id,
|
|
25
|
+
public: b.public,
|
|
26
|
+
...(b.accessMode !== undefined && { access_mode: b.accessMode }),
|
|
27
|
+
...(b.allowedMimeTypes != null && { allowed_mime_types: b.allowedMimeTypes }),
|
|
28
|
+
...(b.fileSizeLimit != null && { file_size_limit: b.fileSizeLimit }),
|
|
29
|
+
...(b.s3BucketPolicy != null &&
|
|
30
|
+
b.s3BucketPolicy !== "" && { s3_bucket_policy: b.s3BucketPolicy }),
|
|
31
|
+
}))
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
export async function provisionBucketsFromAst(
|
|
35
|
+
ast: Pick<ExtractedSchemaAstV2, "storageBuckets">,
|
|
36
|
+
storageApiUrl: string,
|
|
37
|
+
serviceRoleKey: string,
|
|
38
|
+
): Promise<void> {
|
|
39
|
+
const buckets = bucketSpecsFromAst(ast)
|
|
40
|
+
if (buckets.length === 0) return
|
|
41
|
+
console.log("[supatype] Provisioning storage buckets...")
|
|
42
|
+
await provisionBuckets(storageApiUrl, serviceRoleKey, buckets)
|
|
43
|
+
}
|
|
44
|
+
|
|
18
45
|
/**
|
|
19
46
|
* Ensure all declared buckets exist in the storage server.
|
|
20
47
|
*
|
|
@@ -48,11 +75,16 @@ export async function provisionBuckets(
|
|
|
48
75
|
const res = await fetch(`${base}/bucket`, { method: "POST", headers, body })
|
|
49
76
|
.catch(() => null)
|
|
50
77
|
|
|
51
|
-
if (res === null)
|
|
78
|
+
if (res === null) {
|
|
79
|
+
console.warn(`[storage] Storage API unreachable — skipped bucket "${bucket.id}"`)
|
|
80
|
+
continue
|
|
81
|
+
}
|
|
52
82
|
if (res.status === 409) continue // already exists — fine
|
|
53
83
|
if (!res.ok) {
|
|
54
84
|
const msg = await res.text().catch(() => res.statusText)
|
|
55
85
|
console.warn(`[storage] Failed to provision bucket "${bucket.id}": ${msg}`)
|
|
86
|
+
continue
|
|
56
87
|
}
|
|
88
|
+
console.log(`[supatype] Storage bucket "${bucket.id}" ready.`)
|
|
57
89
|
}
|
|
58
90
|
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
process.stdout.write("hello from tsx")
|
package/src/systemd.ts
CHANGED
|
@@ -62,7 +62,7 @@ function postgresUnit(
|
|
|
62
62
|
): string {
|
|
63
63
|
const dataDir = config.database.data_dir ?? join(stateDir, "data")
|
|
64
64
|
const logDir = join(stateDir, "logs")
|
|
65
|
-
const pgBinDir = `%h/.supatype/cache/postgres/${config.versions
|
|
65
|
+
const pgBinDir = `%h/.supatype/cache/postgres/${config.versions?.postgres ?? "latest"}/bin`
|
|
66
66
|
|
|
67
67
|
return `[Unit]
|
|
68
68
|
Description=Supatype Postgres (${config.project.name})
|
|
@@ -100,7 +100,7 @@ function serverUnit(
|
|
|
100
100
|
envFile: string,
|
|
101
101
|
): string {
|
|
102
102
|
const port = config.server.port ?? 54321
|
|
103
|
-
const serverBin = `%h/.supatype/cache/server/${config.versions
|
|
103
|
+
const serverBin = `%h/.supatype/cache/server/${config.versions?.server ?? "latest"}/supatype-server`
|
|
104
104
|
const logDir = join(stateDir, "logs")
|
|
105
105
|
|
|
106
106
|
const extraArgs: string[] = [`--mode ${config.server.mode}`]
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
export interface TargetFetchOptions {
|
|
2
|
+
method: string
|
|
3
|
+
path: string
|
|
4
|
+
body?: unknown
|
|
5
|
+
token: string
|
|
6
|
+
orgId?: string | undefined
|
|
7
|
+
environment?: string | undefined
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
export async function targetFetch<T>(
|
|
11
|
+
baseUrl: string,
|
|
12
|
+
apiPrefix: "/api/v1" | "/platform/v1",
|
|
13
|
+
opts: TargetFetchOptions,
|
|
14
|
+
): Promise<T> {
|
|
15
|
+
const headers: Record<string, string> = {
|
|
16
|
+
"Content-Type": "application/json",
|
|
17
|
+
Authorization: `Bearer ${opts.token}`,
|
|
18
|
+
}
|
|
19
|
+
if (opts.orgId) headers["X-Org-Id"] = opts.orgId
|
|
20
|
+
if (opts.environment) headers["X-Supatype-Environment"] = opts.environment
|
|
21
|
+
|
|
22
|
+
const url = `${baseUrl.replace(/\/$/, "")}${apiPrefix}${opts.path}`
|
|
23
|
+
const res = await fetch(url, {
|
|
24
|
+
method: opts.method,
|
|
25
|
+
headers,
|
|
26
|
+
...(opts.body !== undefined ? { body: JSON.stringify(opts.body) } : {}),
|
|
27
|
+
})
|
|
28
|
+
|
|
29
|
+
const json = (await res.json().catch(() => ({}))) as {
|
|
30
|
+
data?: T
|
|
31
|
+
error?: string
|
|
32
|
+
message?: string
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
if (!res.ok) {
|
|
36
|
+
throw new Error(json.message ?? json.error ?? `API error: ${res.status} ${url}`)
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
return (json.data !== undefined ? json.data : json) as T
|
|
40
|
+
}
|