@supatype/cli 0.1.0-alpha.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 +4 -0
- package/.turbo/turbo-test.log +221 -0
- package/.turbo/turbo-typecheck.log +4 -0
- package/assets/supatype-logo-wordmark.ascii.txt +6 -0
- package/bin/dev-entry.ts +2 -0
- package/bin/supatype.js +5 -0
- package/dist/app/framework.d.ts +44 -0
- package/dist/app/framework.d.ts.map +1 -0
- package/dist/app/framework.js +200 -0
- package/dist/app/framework.js.map +1 -0
- package/dist/app/proxy-dev-app.d.ts +13 -0
- package/dist/app/proxy-dev-app.d.ts.map +1 -0
- package/dist/app/proxy-dev-app.js +54 -0
- package/dist/app/proxy-dev-app.js.map +1 -0
- package/dist/app-config.d.ts +7 -0
- package/dist/app-config.d.ts.map +1 -0
- package/dist/app-config.js +113 -0
- package/dist/app-config.js.map +1 -0
- package/dist/assets/supatype-logo-wordmark.ascii.txt +6 -0
- package/dist/augmentation-generator.d.ts +2 -0
- package/dist/augmentation-generator.d.ts.map +1 -0
- package/dist/augmentation-generator.js +111 -0
- package/dist/augmentation-generator.js.map +1 -0
- package/dist/binary-cache.d.ts +98 -0
- package/dist/binary-cache.d.ts.map +1 -0
- package/dist/binary-cache.js +687 -0
- package/dist/binary-cache.js.map +1 -0
- package/dist/cli.d.ts +2 -0
- package/dist/cli.d.ts.map +1 -0
- package/dist/cli.js +61 -0
- package/dist/cli.js.map +1 -0
- package/dist/commands/admin.d.ts +4 -0
- package/dist/commands/admin.d.ts.map +1 -0
- package/dist/commands/admin.js +271 -0
- package/dist/commands/admin.js.map +1 -0
- package/dist/commands/app.d.ts +3 -0
- package/dist/commands/app.d.ts.map +1 -0
- package/dist/commands/app.js +82 -0
- package/dist/commands/app.js.map +1 -0
- package/dist/commands/cache.d.ts +6 -0
- package/dist/commands/cache.d.ts.map +1 -0
- package/dist/commands/cache.js +105 -0
- package/dist/commands/cache.js.map +1 -0
- package/dist/commands/cloud.d.ts +23 -0
- package/dist/commands/cloud.d.ts.map +1 -0
- package/dist/commands/cloud.js +254 -0
- package/dist/commands/cloud.js.map +1 -0
- package/dist/commands/db.d.ts +8 -0
- package/dist/commands/db.d.ts.map +1 -0
- package/dist/commands/db.js +116 -0
- package/dist/commands/db.js.map +1 -0
- package/dist/commands/deploy-types.d.ts +14 -0
- package/dist/commands/deploy-types.d.ts.map +1 -0
- package/dist/commands/deploy-types.js +38 -0
- package/dist/commands/deploy-types.js.map +1 -0
- package/dist/commands/deploy.d.ts +15 -0
- package/dist/commands/deploy.d.ts.map +1 -0
- package/dist/commands/deploy.js +322 -0
- package/dist/commands/deploy.js.map +1 -0
- package/dist/commands/dev.d.ts +14 -0
- package/dist/commands/dev.d.ts.map +1 -0
- package/dist/commands/dev.js +806 -0
- package/dist/commands/dev.js.map +1 -0
- package/dist/commands/diff.d.ts +3 -0
- package/dist/commands/diff.d.ts.map +1 -0
- package/dist/commands/diff.js +54 -0
- package/dist/commands/diff.js.map +1 -0
- package/dist/commands/engine.d.ts +7 -0
- package/dist/commands/engine.d.ts.map +1 -0
- package/dist/commands/engine.js +27 -0
- package/dist/commands/engine.js.map +1 -0
- package/dist/commands/functions.d.ts +3 -0
- package/dist/commands/functions.d.ts.map +1 -0
- package/dist/commands/functions.js +749 -0
- package/dist/commands/functions.js.map +1 -0
- package/dist/commands/generate.d.ts +3 -0
- package/dist/commands/generate.d.ts.map +1 -0
- package/dist/commands/generate.js +38 -0
- package/dist/commands/generate.js.map +1 -0
- package/dist/commands/init.d.ts +7 -0
- package/dist/commands/init.d.ts.map +1 -0
- package/dist/commands/init.js +228 -0
- package/dist/commands/init.js.map +1 -0
- package/dist/commands/keys.d.ts +4 -0
- package/dist/commands/keys.d.ts.map +1 -0
- package/dist/commands/keys.js +57 -0
- package/dist/commands/keys.js.map +1 -0
- package/dist/commands/logs.d.ts +6 -0
- package/dist/commands/logs.d.ts.map +1 -0
- package/dist/commands/logs.js +52 -0
- package/dist/commands/logs.js.map +1 -0
- package/dist/commands/migrate-from-v1.d.ts +5 -0
- package/dist/commands/migrate-from-v1.d.ts.map +1 -0
- package/dist/commands/migrate-from-v1.js +125 -0
- package/dist/commands/migrate-from-v1.js.map +1 -0
- package/dist/commands/migrate.d.ts +3 -0
- package/dist/commands/migrate.d.ts.map +1 -0
- package/dist/commands/migrate.js +75 -0
- package/dist/commands/migrate.js.map +1 -0
- package/dist/commands/pg.d.ts +8 -0
- package/dist/commands/pg.d.ts.map +1 -0
- package/dist/commands/pg.js +102 -0
- package/dist/commands/pg.js.map +1 -0
- package/dist/commands/plugins.d.ts +3 -0
- package/dist/commands/plugins.d.ts.map +1 -0
- package/dist/commands/plugins.js +431 -0
- package/dist/commands/plugins.js.map +1 -0
- package/dist/commands/pull.d.ts +3 -0
- package/dist/commands/pull.d.ts.map +1 -0
- package/dist/commands/pull.js +12 -0
- package/dist/commands/pull.js.map +1 -0
- package/dist/commands/push.d.ts +3 -0
- package/dist/commands/push.d.ts.map +1 -0
- package/dist/commands/push.js +179 -0
- package/dist/commands/push.js.map +1 -0
- package/dist/commands/seed.d.ts +5 -0
- package/dist/commands/seed.d.ts.map +1 -0
- package/dist/commands/seed.js +55 -0
- package/dist/commands/seed.js.map +1 -0
- package/dist/commands/self-host.d.ts +9 -0
- package/dist/commands/self-host.d.ts.map +1 -0
- package/dist/commands/self-host.js +310 -0
- package/dist/commands/self-host.js.map +1 -0
- package/dist/commands/self-update.d.ts +9 -0
- package/dist/commands/self-update.d.ts.map +1 -0
- package/dist/commands/self-update.js +33 -0
- package/dist/commands/self-update.js.map +1 -0
- package/dist/commands/status.d.ts +6 -0
- package/dist/commands/status.d.ts.map +1 -0
- package/dist/commands/status.js +70 -0
- package/dist/commands/status.js.map +1 -0
- package/dist/commands/types.d.ts +3 -0
- package/dist/commands/types.d.ts.map +1 -0
- package/dist/commands/types.js +62 -0
- package/dist/commands/types.js.map +1 -0
- package/dist/commands/update.d.ts +7 -0
- package/dist/commands/update.d.ts.map +1 -0
- package/dist/commands/update.js +118 -0
- package/dist/commands/update.js.map +1 -0
- package/dist/components.d.ts +5 -0
- package/dist/components.d.ts.map +1 -0
- package/dist/components.js +3 -0
- package/dist/components.js.map +1 -0
- package/dist/config.d.ts +65 -0
- package/dist/config.d.ts.map +1 -0
- package/dist/config.js +134 -0
- package/dist/config.js.map +1 -0
- package/dist/dev-compose.d.ts +19 -0
- package/dist/dev-compose.d.ts.map +1 -0
- package/dist/dev-compose.js +468 -0
- package/dist/dev-compose.js.map +1 -0
- 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 +57 -0
- package/dist/dev-logo.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 +9 -0
- package/dist/dev-shutdown.d.ts.map +1 -0
- package/dist/dev-shutdown.js +50 -0
- package/dist/dev-shutdown.js.map +1 -0
- package/dist/dev-task-colors.d.ts +14 -0
- package/dist/dev-task-colors.d.ts.map +1 -0
- package/dist/dev-task-colors.js +44 -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 +4 -0
- package/dist/diff-output.d.ts.map +1 -0
- package/dist/diff-output.js +12 -0
- package/dist/diff-output.js.map +1 -0
- package/dist/docker-postgres.d.ts +57 -0
- package/dist/docker-postgres.d.ts.map +1 -0
- package/dist/docker-postgres.js +208 -0
- package/dist/docker-postgres.js.map +1 -0
- package/dist/engine-client.d.ts +69 -0
- package/dist/engine-client.d.ts.map +1 -0
- package/dist/engine-client.js +157 -0
- package/dist/engine-client.js.map +1 -0
- package/dist/engine-push-output.d.ts +16 -0
- package/dist/engine-push-output.d.ts.map +1 -0
- package/dist/engine-push-output.js +61 -0
- package/dist/engine-push-output.js.map +1 -0
- package/dist/ensure-binary.d.ts +7 -0
- package/dist/ensure-binary.d.ts.map +1 -0
- package/dist/ensure-binary.js +17 -0
- package/dist/ensure-binary.js.map +1 -0
- package/dist/functions-router-gen.d.ts +14 -0
- package/dist/functions-router-gen.d.ts.map +1 -0
- package/dist/functions-router-gen.js +199 -0
- package/dist/functions-router-gen.js.map +1 -0
- package/dist/index.d.ts +11 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +9 -0
- package/dist/index.js.map +1 -0
- package/dist/jwt.d.ts +3 -0
- package/dist/jwt.d.ts.map +1 -0
- package/dist/jwt.js +13 -0
- package/dist/jwt.js.map +1 -0
- package/dist/kong-config.d.ts +25 -0
- package/dist/kong-config.d.ts.map +1 -0
- package/dist/kong-config.js +71 -0
- package/dist/kong-config.js.map +1 -0
- package/dist/local-gateway.d.ts +7 -0
- package/dist/local-gateway.d.ts.map +1 -0
- package/dist/local-gateway.js +9 -0
- package/dist/local-gateway.js.map +1 -0
- package/dist/local-storage.d.ts +8 -0
- package/dist/local-storage.d.ts.map +1 -0
- package/dist/local-storage.js +14 -0
- package/dist/local-storage.js.map +1 -0
- package/dist/pgbouncer-userlist.d.ts +5 -0
- package/dist/pgbouncer-userlist.d.ts.map +1 -0
- package/dist/pgbouncer-userlist.js +14 -0
- package/dist/pgbouncer-userlist.js.map +1 -0
- package/dist/postgres-ctl.d.ts +44 -0
- package/dist/postgres-ctl.d.ts.map +1 -0
- package/dist/postgres-ctl.js +137 -0
- package/dist/postgres-ctl.js.map +1 -0
- package/dist/process-manager.d.ts +49 -0
- package/dist/process-manager.d.ts.map +1 -0
- package/dist/process-manager.js +177 -0
- package/dist/process-manager.js.map +1 -0
- package/dist/project-config.d.ts +238 -0
- package/dist/project-config.d.ts.map +1 -0
- package/dist/project-config.js +159 -0
- package/dist/project-config.js.map +1 -0
- package/dist/pull-utils.d.ts +31 -0
- package/dist/pull-utils.d.ts.map +1 -0
- package/dist/pull-utils.js +77 -0
- package/dist/pull-utils.js.map +1 -0
- package/dist/release-pins.d.ts +7 -0
- package/dist/release-pins.d.ts.map +1 -0
- package/dist/release-pins.js +27 -0
- package/dist/release-pins.js.map +1 -0
- package/dist/release-public-key.d.ts +8 -0
- package/dist/release-public-key.d.ts.map +1 -0
- package/dist/release-public-key.js +13 -0
- package/dist/release-public-key.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 +34 -0
- package/dist/runtime-routes.d.ts.map +1 -0
- package/dist/runtime-routes.js +252 -0
- package/dist/runtime-routes.js.map +1 -0
- package/dist/schema-ast-v2.d.ts +127 -0
- package/dist/schema-ast-v2.d.ts.map +1 -0
- package/dist/schema-ast-v2.js +226 -0
- package/dist/schema-ast-v2.js.map +1 -0
- package/dist/scripts/postinstall.d.ts +11 -0
- package/dist/scripts/postinstall.d.ts.map +1 -0
- package/dist/scripts/postinstall.js +47 -0
- package/dist/scripts/postinstall.js.map +1 -0
- package/dist/seed.d.ts +8 -0
- package/dist/seed.d.ts.map +1 -0
- package/dist/seed.js +32 -0
- package/dist/seed.js.map +1 -0
- package/dist/self-host-compose.d.ts +43 -0
- package/dist/self-host-compose.d.ts.map +1 -0
- package/dist/self-host-compose.js +400 -0
- package/dist/self-host-compose.js.map +1 -0
- package/dist/storage-provision.d.ts +24 -0
- package/dist/storage-provision.d.ts.map +1 -0
- package/dist/storage-provision.js +44 -0
- package/dist/storage-provision.js.map +1 -0
- package/dist/studio-admin-roles.d.ts +7 -0
- package/dist/studio-admin-roles.d.ts.map +1 -0
- package/dist/studio-admin-roles.js +14 -0
- package/dist/studio-admin-roles.js.map +1 -0
- package/dist/studio-dev-server.d.ts +22 -0
- package/dist/studio-dev-server.d.ts.map +1 -0
- package/dist/studio-dev-server.js +28 -0
- package/dist/studio-dev-server.js.map +1 -0
- 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.d.ts +26 -0
- package/dist/systemd.d.ts.map +1 -0
- package/dist/systemd.js +102 -0
- package/dist/systemd.js.map +1 -0
- package/dist/tsx-runner.d.ts +18 -0
- package/dist/tsx-runner.d.ts.map +1 -0
- package/dist/tsx-runner.js +69 -0
- package/dist/tsx-runner.js.map +1 -0
- package/dist/type-extractor.d.ts +4 -0
- package/dist/type-extractor.d.ts.map +1 -0
- package/dist/type-extractor.js +1213 -0
- package/dist/type-extractor.js.map +1 -0
- package/dist/type-resolver.d.ts +33 -0
- package/dist/type-resolver.d.ts.map +1 -0
- package/dist/type-resolver.js +338 -0
- package/dist/type-resolver.js.map +1 -0
- package/package.json +41 -0
- package/releases/deno/VERSION +1 -0
- package/scripts/mirror-deno-release.sh +76 -0
- package/src/TYPE-RESOLUTION.md +294 -0
- package/src/app/framework.ts +249 -0
- package/src/app/proxy-dev-app.ts +68 -0
- package/src/app-config.ts +128 -0
- package/src/augmentation-generator.ts +126 -0
- package/src/binary-cache.ts +845 -0
- package/src/cli.ts +63 -0
- package/src/commands/admin.ts +372 -0
- package/src/commands/app.ts +97 -0
- package/src/commands/cache.ts +117 -0
- package/src/commands/cloud.ts +325 -0
- package/src/commands/db.ts +136 -0
- package/src/commands/deploy-types.ts +49 -0
- package/src/commands/deploy.ts +400 -0
- package/src/commands/dev.ts +1009 -0
- package/src/commands/diff.ts +63 -0
- package/src/commands/engine.ts +30 -0
- package/src/commands/functions.ts +901 -0
- package/src/commands/generate.ts +44 -0
- package/src/commands/init.ts +253 -0
- package/src/commands/keys.ts +66 -0
- package/src/commands/logs.ts +58 -0
- package/src/commands/migrate-from-v1.ts +131 -0
- package/src/commands/migrate.ts +87 -0
- package/src/commands/pg.ts +133 -0
- package/src/commands/plugins.ts +508 -0
- package/src/commands/pull.ts +17 -0
- package/src/commands/push.ts +226 -0
- package/src/commands/seed.ts +68 -0
- package/src/commands/self-host.ts +364 -0
- package/src/commands/self-update.ts +45 -0
- package/src/commands/status.ts +84 -0
- package/src/commands/types.ts +76 -0
- package/src/commands/update.ts +136 -0
- package/src/components.ts +6 -0
- package/src/config.ts +223 -0
- package/src/dev-compose.ts +583 -0
- package/src/dev-log-bus.ts +101 -0
- package/src/dev-log-filter.ts +32 -0
- package/src/dev-logo.ts +62 -0
- package/src/dev-session.ts +130 -0
- package/src/dev-shutdown.ts +54 -0
- package/src/dev-task-colors.ts +47 -0
- package/src/dev-tui.ts +232 -0
- package/src/diff-output.ts +12 -0
- package/src/docker-postgres.ts +295 -0
- package/src/engine-client.ts +236 -0
- package/src/engine-push-output.ts +71 -0
- package/src/ensure-binary.ts +28 -0
- package/src/functions-router-gen.ts +224 -0
- package/src/index.ts +11 -0
- package/src/jwt.ts +14 -0
- package/src/kong-config.ts +93 -0
- package/src/local-gateway.ts +9 -0
- package/src/local-storage.ts +14 -0
- package/src/pgbouncer-userlist.ts +15 -0
- package/src/postgres-ctl.ts +171 -0
- package/src/process-manager.ts +220 -0
- package/src/project-config.ts +388 -0
- package/src/pull-utils.ts +81 -0
- package/src/release-pins.ts +31 -0
- package/src/release-public-key.ts +12 -0
- package/src/restore-system-relation-targets.ts +45 -0
- package/src/runtime-routes.ts +291 -0
- package/src/schema-ast-v2.ts +324 -0
- package/src/scripts/postinstall.ts +51 -0
- package/src/seed.ts +43 -0
- package/src/self-host-compose.ts +452 -0
- package/src/storage-provision.ts +58 -0
- package/src/studio-admin-roles.ts +16 -0
- package/src/studio-dev-server.ts +53 -0
- package/src/supatype-eval-1781522769253.mts +1 -0
- package/src/systemd.ts +137 -0
- package/src/tsx-runner.ts +89 -0
- package/src/type-extractor.ts +1479 -0
- package/src/type-resolver.ts +457 -0
- package/tests/app-command.test.ts +54 -0
- package/tests/augmentation-generator.test.ts +59 -0
- package/tests/binary-cache-cloud-overrides.test.ts +123 -0
- package/tests/cached-artifact-format.test.ts +84 -0
- package/tests/cli-help.test.ts +133 -0
- package/tests/config.test.ts +252 -0
- package/tests/dev-ui.test.ts +139 -0
- package/tests/docker-postgres.test.ts +39 -0
- package/tests/engine-distribution.test.ts +418 -0
- package/tests/engine-push-output.test.ts +67 -0
- package/tests/ensure-binary.test.ts +59 -0
- package/tests/init.test.ts +127 -0
- package/tests/keys.test.ts +160 -0
- package/tests/migrate-from-v1.test.ts +29 -0
- package/tests/normalize-admin-config.test.ts +48 -0
- package/tests/pg-spawn-env.test.ts +18 -0
- package/tests/postgres-archive-tag.test.ts +9 -0
- package/tests/proxy-dev-app.test.ts +33 -0
- package/tests/pull-utils.test.ts +150 -0
- package/tests/release-pins.test.ts +28 -0
- package/tests/runtime-contract.test.ts +370 -0
- package/tests/seed-discover.test.ts +31 -0
- package/tests/studio-admin-roles.test.ts +27 -0
- package/tests/tsconfig.json +9 -0
- package/tests/tsx-runner.test.ts +66 -0
- package/tests/type-extractor.test.ts +985 -0
- package/tests/type-resolver.test.ts +59 -0
- package/tsconfig.json +10 -0
- package/tsconfig.tsbuildinfo +1 -0
- package/vitest.config.ts +12 -0
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Postinstall script — downloads component binaries on first install.
|
|
3
|
+
*
|
|
4
|
+
* Components: supatype-engine, supatype-server, supatype-pg (Postgres), deno.
|
|
5
|
+
* Binaries are cached in ~/.supatype/cache/{component}/{version}/.
|
|
6
|
+
*
|
|
7
|
+
* Failures are non-fatal: an installation message is printed and the user
|
|
8
|
+
* can run `supatype update` manually to retry.
|
|
9
|
+
*/
|
|
10
|
+
|
|
11
|
+
import { download, currentPlatform, fetchAllLatestVersions, type Component } from "../binary-cache.js"
|
|
12
|
+
|
|
13
|
+
async function main() {
|
|
14
|
+
const platform = currentPlatform()
|
|
15
|
+
|
|
16
|
+
let versions: Record<Component, string>
|
|
17
|
+
try {
|
|
18
|
+
console.log("[supatype] Fetching latest component versions...")
|
|
19
|
+
versions = await fetchAllLatestVersions()
|
|
20
|
+
} catch (err) {
|
|
21
|
+
console.error(`[supatype] Failed to fetch latest versions: ${(err as Error).message}`)
|
|
22
|
+
console.error("[supatype] Run 'supatype update' to download component binaries.")
|
|
23
|
+
return
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
console.log(`[supatype] Downloading component binaries for ${platform.os}/${platform.arch}...`)
|
|
27
|
+
|
|
28
|
+
const components = Object.entries(versions) as [Component, string][]
|
|
29
|
+
|
|
30
|
+
let anyFailed = false
|
|
31
|
+
for (const [component, version] of components) {
|
|
32
|
+
try {
|
|
33
|
+
await download(component, version, platform)
|
|
34
|
+
} catch (err) {
|
|
35
|
+
console.error(`[supatype] Failed to download ${component} v${version}: ${(err as Error).message}`)
|
|
36
|
+
anyFailed = true
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
if (anyFailed) {
|
|
41
|
+
console.error("[supatype] Some downloads failed. Run 'supatype update' to retry.")
|
|
42
|
+
} else {
|
|
43
|
+
console.log("[supatype] All component binaries downloaded successfully.")
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
main().catch((err) => {
|
|
48
|
+
// Non-fatal — postinstall failures should not break npm install.
|
|
49
|
+
console.error("[supatype] Postinstall failed:", err)
|
|
50
|
+
process.exit(0)
|
|
51
|
+
})
|
package/src/seed.ts
ADDED
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import pg from "pg"
|
|
2
|
+
|
|
3
|
+
export interface SeedSql {
|
|
4
|
+
(strings: TemplateStringsArray, ...values: unknown[]): Promise<pg.QueryResult>
|
|
5
|
+
end(): Promise<void>
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
/** Lightweight tagged-template SQL helper for project `seed.ts` scripts. */
|
|
9
|
+
export function sql(connectionString: string): SeedSql {
|
|
10
|
+
const client = new pg.Client({ connectionString })
|
|
11
|
+
let connected = false
|
|
12
|
+
|
|
13
|
+
const ensureConnected = async (): Promise<void> => {
|
|
14
|
+
if (!connected) {
|
|
15
|
+
await client.connect()
|
|
16
|
+
connected = true
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
const tag = async (
|
|
21
|
+
strings: TemplateStringsArray,
|
|
22
|
+
...values: unknown[]
|
|
23
|
+
): Promise<pg.QueryResult> => {
|
|
24
|
+
await ensureConnected()
|
|
25
|
+
let text = ""
|
|
26
|
+
for (let i = 0; i < strings.length; i++) {
|
|
27
|
+
text += strings[i]
|
|
28
|
+
if (i < values.length) {
|
|
29
|
+
text += `$${i + 1}`
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
return client.query(text, values)
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
return Object.assign(tag, {
|
|
36
|
+
end: async (): Promise<void> => {
|
|
37
|
+
if (connected) {
|
|
38
|
+
await client.end()
|
|
39
|
+
connected = false
|
|
40
|
+
}
|
|
41
|
+
},
|
|
42
|
+
})
|
|
43
|
+
}
|
|
@@ -0,0 +1,452 @@
|
|
|
1
|
+
import { existsSync, mkdirSync, writeFileSync } from "node:fs"
|
|
2
|
+
import { dirname, join, relative, resolve } from "node:path"
|
|
3
|
+
import { spawnSync } from "node:child_process"
|
|
4
|
+
import { preferredFunctionsPathFromProject, type SupatypeProjectConfig } from "./project-config.js"
|
|
5
|
+
import { hasEngineOverride, hasStudioOverride, pinnedVersion, fetchLatestVersion, VERSION_PIN_LOCAL } from "./binary-cache.js"
|
|
6
|
+
import { buildKongDeclarative } from "./kong-config.js"
|
|
7
|
+
|
|
8
|
+
/** Env keys written when `versions` pins exist in supatype.config.ts. */
|
|
9
|
+
export const COMPOSE_PINNED_IMAGE_ENV_KEYS = [
|
|
10
|
+
"SUPATYPE_ENGINE_IMAGE",
|
|
11
|
+
"SUPATYPE_SERVER_IMAGE",
|
|
12
|
+
"SUPATYPE_POSTGRES_IMAGE",
|
|
13
|
+
] as const
|
|
14
|
+
|
|
15
|
+
type DockerPinComponent = "engine" | "server" | "postgres"
|
|
16
|
+
|
|
17
|
+
/** Map a config version pin to a Docker Hub image reference. */
|
|
18
|
+
export function dockerImageRef(
|
|
19
|
+
component: DockerPinComponent,
|
|
20
|
+
version: string,
|
|
21
|
+
config?: SupatypeProjectConfig,
|
|
22
|
+
): string {
|
|
23
|
+
const trimmed = version.trim()
|
|
24
|
+
switch (component) {
|
|
25
|
+
case "engine":
|
|
26
|
+
return `supatype/schema-engine:${trimmed.startsWith("v") ? trimmed : `v${trimmed}`}`
|
|
27
|
+
case "server":
|
|
28
|
+
return `supatype/server:${trimmed.startsWith("v") ? trimmed : `v${trimmed}`}`
|
|
29
|
+
case "postgres": {
|
|
30
|
+
const override = config?.database?.image?.trim()
|
|
31
|
+
if (override) return override
|
|
32
|
+
if (trimmed.includes("-latest")) return `supatype/postgres:${trimmed}`
|
|
33
|
+
const major = trimmed.split(".")[0]
|
|
34
|
+
return `supatype/postgres:${major}-latest`
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
/**
|
|
40
|
+
* When the user pins `versions` in config, sync matching SUPATYPE_*_IMAGE vars for Compose.
|
|
41
|
+
* Unpinned components are omitted so compose falls back to :latest defaults.
|
|
42
|
+
*/
|
|
43
|
+
export function composeDockerImageEnv(config: SupatypeProjectConfig): Record<string, string> {
|
|
44
|
+
const env: Record<string, string> = {}
|
|
45
|
+
const versions = config.versions
|
|
46
|
+
if (!versions) return env
|
|
47
|
+
|
|
48
|
+
if (versions.engine && versions.engine !== VERSION_PIN_LOCAL) {
|
|
49
|
+
env.SUPATYPE_ENGINE_IMAGE = dockerImageRef("engine", versions.engine)
|
|
50
|
+
}
|
|
51
|
+
if (versions.server && versions.server !== VERSION_PIN_LOCAL) {
|
|
52
|
+
env.SUPATYPE_SERVER_IMAGE = dockerImageRef("server", versions.server)
|
|
53
|
+
}
|
|
54
|
+
if (versions.postgres && versions.postgres !== VERSION_PIN_LOCAL) {
|
|
55
|
+
env.SUPATYPE_POSTGRES_IMAGE = dockerImageRef("postgres", versions.postgres, config)
|
|
56
|
+
}
|
|
57
|
+
return env
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
/**
|
|
61
|
+
* Schema-engine image for a one-off `docker compose run` when pushing schema.
|
|
62
|
+
* Uses config pin when set; otherwise CDN engine semver (Docker Hub `:latest` can lag).
|
|
63
|
+
* Does not touch `.env` — server/postgres still use compose `:latest` defaults.
|
|
64
|
+
*/
|
|
65
|
+
export async function schemaEngineImageForPush(
|
|
66
|
+
config: SupatypeProjectConfig,
|
|
67
|
+
): Promise<string | undefined> {
|
|
68
|
+
const pinned = pinnedVersion("engine", config)
|
|
69
|
+
if (pinned === VERSION_PIN_LOCAL) return undefined
|
|
70
|
+
if (pinned) return dockerImageRef("engine", pinned)
|
|
71
|
+
const version = await fetchLatestVersion("engine")
|
|
72
|
+
return dockerImageRef("engine", version)
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
export interface SelfHostComposePaths {
|
|
76
|
+
dir: string
|
|
77
|
+
composePath: string
|
|
78
|
+
kongPath: string
|
|
79
|
+
nginxPath: string
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
export function selfHostComposePaths(cwd: string): SelfHostComposePaths {
|
|
83
|
+
const dir = resolve(cwd, ".supatype", "self-host")
|
|
84
|
+
return {
|
|
85
|
+
dir,
|
|
86
|
+
composePath: join(dir, "docker-compose.yml"),
|
|
87
|
+
kongPath: join(dir, "kong.yml"),
|
|
88
|
+
nginxPath: join(dir, "nginx.conf"),
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
export function appUpstreamForCompose(config: SupatypeProjectConfig): string | undefined {
|
|
93
|
+
if (config.app.mode !== "proxy") return undefined
|
|
94
|
+
const upstream = config.app.upstream?.trim()
|
|
95
|
+
return upstream && upstream.length > 0 ? upstream : undefined
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
export function staticDirForCompose(config: SupatypeProjectConfig): string | undefined {
|
|
99
|
+
if (config.app.mode !== "static") return undefined
|
|
100
|
+
const dir = config.app.static_dir?.trim()
|
|
101
|
+
return dir && dir.length > 0 ? dir : "./public"
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
/**
|
|
105
|
+
* Bind-mount source for `/project` in generated compose files.
|
|
106
|
+
* Paths are resolved from `--project-directory` (always the project root in `runDockerCompose`),
|
|
107
|
+
* not from the compose file directory — use `.` not `../..`.
|
|
108
|
+
*/
|
|
109
|
+
function projectMountPath(_cwd: string): string {
|
|
110
|
+
return "."
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
/** Paths in generated compose are resolved from `--project-directory` (project root). */
|
|
114
|
+
function relativeFromProjectRoot(cwd: string, target: string): string {
|
|
115
|
+
let rel = relative(resolve(cwd), resolve(target)).replace(/\\/g, "/")
|
|
116
|
+
if (!rel.startsWith(".") && !rel.startsWith("/")) {
|
|
117
|
+
rel = `./${rel}`
|
|
118
|
+
}
|
|
119
|
+
return rel
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
function kongMountPath(_cwd: string): string {
|
|
123
|
+
return ".supatype/self-host/kong.yml"
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
/** Host Vite dev server as seen from Kong inside Docker Compose. */
|
|
127
|
+
export const COMPOSE_STUDIO_HOST_URL = "http://host.docker.internal:3002"
|
|
128
|
+
|
|
129
|
+
/** Studio container — always Docker Hub unless SUPATYPE_STUDIO_IMAGE is set in .env. */
|
|
130
|
+
function studioServiceBlock(): string {
|
|
131
|
+
return ` image: \${SUPATYPE_STUDIO_IMAGE:-supatype/studio:latest}`
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
/** Host dev app (Astro/Vite on the machine) as seen from inside compose services. */
|
|
135
|
+
function proxyUpstreamForCompose(upstream: string, devLocal: boolean): string {
|
|
136
|
+
const trimmed = upstream.trim()
|
|
137
|
+
if (!devLocal) return trimmed
|
|
138
|
+
try {
|
|
139
|
+
const url = new URL(trimmed)
|
|
140
|
+
if (url.hostname === "localhost" || url.hostname === "127.0.0.1") {
|
|
141
|
+
url.hostname = "host.docker.internal"
|
|
142
|
+
return url.toString()
|
|
143
|
+
}
|
|
144
|
+
} catch {
|
|
145
|
+
// keep literal upstream when not a URL
|
|
146
|
+
}
|
|
147
|
+
return trimmed
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
function serverAppEnvForCompose(config: SupatypeProjectConfig, devLocal: boolean): string {
|
|
151
|
+
const mode = config.app.mode ?? "none"
|
|
152
|
+
const lines = [` SUPATYPE_APP_MODE: ${mode}`]
|
|
153
|
+
if (mode === "static") {
|
|
154
|
+
const dir = staticDirForCompose(config) ?? "./public"
|
|
155
|
+
lines.push(` SUPATYPE_APP_STATIC_DIR: /project/${dir.replace(/^\.\//, "")}`)
|
|
156
|
+
} else if (mode === "proxy" && config.app.upstream?.trim()) {
|
|
157
|
+
lines.push(` SUPATYPE_APP_UPSTREAM: ${proxyUpstreamForCompose(config.app.upstream, devLocal)}`)
|
|
158
|
+
}
|
|
159
|
+
return lines.join("\n")
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
export interface SelfHostComposeOptions {
|
|
163
|
+
/** `supatype dev` with provider docker: internal-only db/server; Kong on host :18473. */
|
|
164
|
+
devLocal?: boolean
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
export function renderSelfHostCompose(
|
|
168
|
+
config: SupatypeProjectConfig,
|
|
169
|
+
cwd: string = process.cwd(),
|
|
170
|
+
options?: SelfHostComposeOptions,
|
|
171
|
+
): string {
|
|
172
|
+
const projectMount = projectMountPath(cwd)
|
|
173
|
+
const kongMount = kongMountPath(cwd)
|
|
174
|
+
const devLocal = options?.devLocal === true
|
|
175
|
+
const studioHostDev = devLocal && hasStudioOverride(config)
|
|
176
|
+
const appEnv = serverAppEnvForCompose(config, devLocal)
|
|
177
|
+
const studioService = studioServiceBlock()
|
|
178
|
+
const studioBlock = studioHostDev
|
|
179
|
+
? ""
|
|
180
|
+
: `
|
|
181
|
+
studio:
|
|
182
|
+
${studioService}
|
|
183
|
+
environment:
|
|
184
|
+
SUPATYPE_CLOUD_JSON: '{"url":"\${API_EXTERNAL_URL:-http://localhost:18473}","anonKey":"\${ANON_KEY:-}"}'
|
|
185
|
+
expose:
|
|
186
|
+
- "3002"
|
|
187
|
+
`
|
|
188
|
+
const kongDependsOn = studioHostDev
|
|
189
|
+
? ` - server`
|
|
190
|
+
: ` - server
|
|
191
|
+
- studio`
|
|
192
|
+
const publishDbToHost = !devLocal || hasEngineOverride(config)
|
|
193
|
+
const dbPorts = publishDbToHost
|
|
194
|
+
? devLocal
|
|
195
|
+
? ` ports:
|
|
196
|
+
- "127.0.0.1:\${SUPATYPE_DEV_DB_PORT:-54329}:5432"
|
|
197
|
+
`
|
|
198
|
+
: ` ports:
|
|
199
|
+
- "5432:5432"
|
|
200
|
+
`
|
|
201
|
+
: ""
|
|
202
|
+
const serverPorts = devLocal
|
|
203
|
+
? ""
|
|
204
|
+
: ` ports:
|
|
205
|
+
- "9999:9999"
|
|
206
|
+
`
|
|
207
|
+
const minioPorts = devLocal
|
|
208
|
+
? ""
|
|
209
|
+
: ` ports:
|
|
210
|
+
- "9000:9000"
|
|
211
|
+
- "9001:9001"
|
|
212
|
+
`
|
|
213
|
+
|
|
214
|
+
return `# Generated by supatype self-host compose
|
|
215
|
+
# Kong → supatype-server (unified gateway) → internal PostgREST / storage / etc.
|
|
216
|
+
services:
|
|
217
|
+
db:
|
|
218
|
+
image: \${SUPATYPE_POSTGRES_IMAGE:-supatype/postgres:latest}
|
|
219
|
+
environment:
|
|
220
|
+
POSTGRES_USER: \${POSTGRES_USER:-supatype_admin}
|
|
221
|
+
POSTGRES_PASSWORD: \${POSTGRES_PASSWORD:-postgres}
|
|
222
|
+
POSTGRES_DB: \${POSTGRES_DB:-supatype}
|
|
223
|
+
${dbPorts} volumes:
|
|
224
|
+
- db-data:/var/lib/postgresql/data
|
|
225
|
+
healthcheck:
|
|
226
|
+
test: ["CMD-SHELL", "pg_isready -U \${POSTGRES_USER:-supatype_admin}"]
|
|
227
|
+
interval: 5s
|
|
228
|
+
timeout: 5s
|
|
229
|
+
retries: 20
|
|
230
|
+
|
|
231
|
+
postgrest:
|
|
232
|
+
image: postgrest/postgrest:v12.2.8
|
|
233
|
+
expose:
|
|
234
|
+
- "3000"
|
|
235
|
+
environment:
|
|
236
|
+
PGRST_DB_URI: postgresql://\${POSTGRES_USER:-supatype_admin}:\${POSTGRES_PASSWORD:-postgres}@db:5432/\${POSTGRES_DB:-supatype}
|
|
237
|
+
PGRST_DB_SCHEMA: "public, supatype, graphql_public, auth"
|
|
238
|
+
PGRST_DB_ANON_ROLE: anon
|
|
239
|
+
PGRST_JWT_SECRET: \${JWT_SECRET:-super-secret-jwt-token-change-in-production}
|
|
240
|
+
PGRST_DB_EXTRA_SEARCH_PATH: public,extensions
|
|
241
|
+
PGRST_DB_POOL: 3
|
|
242
|
+
depends_on:
|
|
243
|
+
db:
|
|
244
|
+
condition: service_healthy
|
|
245
|
+
|
|
246
|
+
storage:
|
|
247
|
+
image: \${SUPATYPE_STORAGE_IMAGE:-supatype/storage:latest}
|
|
248
|
+
expose:
|
|
249
|
+
- "5000"
|
|
250
|
+
environment:
|
|
251
|
+
PORT: 5000
|
|
252
|
+
DATABASE_URL: "postgresql://\${POSTGRES_USER:-supatype_admin}:\${POSTGRES_PASSWORD:-postgres}@db:5432/\${POSTGRES_DB:-supatype}"
|
|
253
|
+
JWT_SECRET: \${JWT_SECRET:-super-secret-jwt-token-change-in-production}
|
|
254
|
+
S3_ENDPOINT: http://minio:9000
|
|
255
|
+
S3_REGION: us-east-1
|
|
256
|
+
S3_ACCESS_KEY: supatype
|
|
257
|
+
S3_SECRET_KEY: supatype-secret
|
|
258
|
+
S3_FORCE_PATH_STYLE: "true"
|
|
259
|
+
depends_on:
|
|
260
|
+
db:
|
|
261
|
+
condition: service_healthy
|
|
262
|
+
|
|
263
|
+
functions-worker:
|
|
264
|
+
image: \${SUPATYPE_FUNCTIONS_WORKER_IMAGE:-supatype/functions-worker:latest}
|
|
265
|
+
expose:
|
|
266
|
+
- "8001"
|
|
267
|
+
volumes:
|
|
268
|
+
- ${projectMount}:/project:ro
|
|
269
|
+
environment:
|
|
270
|
+
SUPATYPE_FUNCTIONS_ROOT: /project/functions
|
|
271
|
+
SUPATYPE_DENO_FUNCTIONS_DIR: /project/functions
|
|
272
|
+
PORT: "8001"
|
|
273
|
+
SUPATYPE_URL: \${API_EXTERNAL_URL:-http://localhost:18473}
|
|
274
|
+
SUPATYPE_ANON_KEY: \${ANON_KEY:-}
|
|
275
|
+
SUPATYPE_SERVICE_ROLE_KEY: \${SERVICE_ROLE_KEY:-}
|
|
276
|
+
STRIPE_SECRET_KEY: \${STRIPE_SECRET_KEY:-}
|
|
277
|
+
STRIPE_WEBHOOK_SECRET: \${STRIPE_WEBHOOK_SECRET:-}
|
|
278
|
+
SITE_URL: \${SITE_URL:-\${API_EXTERNAL_URL:-http://localhost:18473}}
|
|
279
|
+
depends_on:
|
|
280
|
+
db:
|
|
281
|
+
condition: service_healthy
|
|
282
|
+
|
|
283
|
+
server:
|
|
284
|
+
image: \${SUPATYPE_SERVER_IMAGE:-\${SUPATYPE_AUTH_IMAGE:-supatype/server:latest}}
|
|
285
|
+
${serverPorts} volumes:
|
|
286
|
+
- ${projectMount}:/project:ro
|
|
287
|
+
working_dir: /project
|
|
288
|
+
environment:
|
|
289
|
+
SUPATYPE_MODE: ${devLocal ? "dev" : "standalone"}
|
|
290
|
+
SUPATYPE_MANIFEST_PATH: .supatype/manifest.json
|
|
291
|
+
SUPATYPE_ADMIN_CONFIG_PATH: .supatype/admin-config.json
|
|
292
|
+
SUPATYPE_API_CONFIG_PATH: .supatype/api-config.json
|
|
293
|
+
SUPATYPE_POSTGREST_URL: http://postgrest:3000
|
|
294
|
+
SUPATYPE_GRAPHQL_URL: http://postgrest:3000
|
|
295
|
+
SUPATYPE_STORAGE_URL: http://storage:5000
|
|
296
|
+
SUPATYPE_URL: \${API_EXTERNAL_URL:-http://localhost:18473}
|
|
297
|
+
SUPATYPE_ANON_KEY: \${ANON_KEY:-}
|
|
298
|
+
SUPATYPE_SERVICE_ROLE_KEY: \${SERVICE_ROLE_KEY:-}
|
|
299
|
+
SUPATYPE_SQL_DATABASE_URL: "postgresql://\${POSTGRES_USER:-supatype_admin}:\${POSTGRES_PASSWORD:-postgres}@db:5432/\${POSTGRES_DB:-supatype}"
|
|
300
|
+
SUPATYPE_DENO_FUNCTIONS_DIR: /project/functions
|
|
301
|
+
SUPATYPE_FUNCTIONS_WORKER_URL: http://functions-worker:8001
|
|
302
|
+
${appEnv}
|
|
303
|
+
GOTRUE_API_HOST: 0.0.0.0
|
|
304
|
+
GOTRUE_API_PORT: 9999
|
|
305
|
+
API_EXTERNAL_URL: \${API_EXTERNAL_URL:-http://localhost:18473}
|
|
306
|
+
GOTRUE_API_EXTERNAL_URL: \${API_EXTERNAL_URL:-http://localhost:18473}
|
|
307
|
+
GOTRUE_DB_DRIVER: postgres
|
|
308
|
+
GOTRUE_DB_DATABASE_URL: "postgres://\${POSTGRES_USER:-supatype_admin}:\${POSTGRES_PASSWORD:-postgres}@db:5432/\${POSTGRES_DB:-supatype}?search_path=auth"
|
|
309
|
+
GOTRUE_SITE_URL: \${SITE_URL:-http://localhost:3000}
|
|
310
|
+
GOTRUE_JWT_SECRET: \${JWT_SECRET:-super-secret-jwt-token-change-in-production}
|
|
311
|
+
GOTRUE_JWT_EXP: 3600
|
|
312
|
+
GOTRUE_JWT_AUD: authenticated
|
|
313
|
+
GOTRUE_JWT_DEFAULT_GROUP_NAME: authenticated
|
|
314
|
+
GOTRUE_JWT_ADMIN_ROLES: service_role,supatype_admin
|
|
315
|
+
GOTRUE_MAILER_AUTOCONFIRM: \${GOTRUE_MAILER_AUTOCONFIRM:-true}
|
|
316
|
+
GOTRUE_DISABLE_SIGNUP: \${DISABLE_SIGNUP:-false}
|
|
317
|
+
${devLocal ? " STUDIO_OPEN_DEV: \"1\"\n" : ""}
|
|
318
|
+
depends_on:
|
|
319
|
+
db:
|
|
320
|
+
condition: service_healthy
|
|
321
|
+
postgrest:
|
|
322
|
+
condition: service_started
|
|
323
|
+
storage:
|
|
324
|
+
condition: service_started
|
|
325
|
+
functions-worker:
|
|
326
|
+
condition: service_started
|
|
327
|
+
|
|
328
|
+
minio:
|
|
329
|
+
image: minio/minio:RELEASE.2024-11-07T00-52-20Z
|
|
330
|
+
command: server /data --console-address ":9001"
|
|
331
|
+
environment:
|
|
332
|
+
MINIO_ROOT_USER: supatype
|
|
333
|
+
MINIO_ROOT_PASSWORD: supatype-secret
|
|
334
|
+
${minioPorts} volumes:
|
|
335
|
+
- minio-data:/data
|
|
336
|
+
|
|
337
|
+
schema-engine:
|
|
338
|
+
image: \${SUPATYPE_ENGINE_IMAGE:-supatype/schema-engine:latest}
|
|
339
|
+
profiles: ["tools"]
|
|
340
|
+
entrypoint: ["supatype-engine"]
|
|
341
|
+
volumes:
|
|
342
|
+
- ${projectMount}:/project
|
|
343
|
+
working_dir: /project
|
|
344
|
+
depends_on:
|
|
345
|
+
db:
|
|
346
|
+
condition: service_healthy
|
|
347
|
+
${studioBlock}
|
|
348
|
+
kong:
|
|
349
|
+
image: kong:3.6
|
|
350
|
+
environment:
|
|
351
|
+
KONG_DATABASE: "off"
|
|
352
|
+
KONG_DECLARATIVE_CONFIG: /etc/kong/kong.yml
|
|
353
|
+
KONG_PROXY_ACCESS_LOG: /dev/stdout
|
|
354
|
+
KONG_ADMIN_ACCESS_LOG: /dev/stdout
|
|
355
|
+
KONG_PROXY_ERROR_LOG: /dev/stderr
|
|
356
|
+
KONG_ADMIN_ERROR_LOG: /dev/stderr
|
|
357
|
+
volumes:
|
|
358
|
+
- ${kongMount}:/etc/kong/kong.yml:ro
|
|
359
|
+
ports:
|
|
360
|
+
- "\${SUPATYPE_KONG_PORT:-18473}:8000"
|
|
361
|
+
depends_on:
|
|
362
|
+
${kongDependsOn}
|
|
363
|
+
|
|
364
|
+
volumes:
|
|
365
|
+
db-data:
|
|
366
|
+
minio-data:
|
|
367
|
+
`
|
|
368
|
+
}
|
|
369
|
+
|
|
370
|
+
function ensureComposeManifest(cwd: string): void {
|
|
371
|
+
const manifestPath = join(cwd, ".supatype", "manifest.json")
|
|
372
|
+
if (existsSync(manifestPath)) return
|
|
373
|
+
mkdirSync(dirname(manifestPath), { recursive: true })
|
|
374
|
+
const manifest = {
|
|
375
|
+
schema: "public",
|
|
376
|
+
postgrest_url: "http://postgrest:3000",
|
|
377
|
+
storage_url: "http://storage:5000",
|
|
378
|
+
realtime_enabled: true,
|
|
379
|
+
functions_enabled: false,
|
|
380
|
+
}
|
|
381
|
+
writeFileSync(manifestPath, `${JSON.stringify(manifest, null, 2)}\n`, "utf8")
|
|
382
|
+
}
|
|
383
|
+
|
|
384
|
+
function ensureProjectFunctionsDir(cwd: string, config: SupatypeProjectConfig): void {
|
|
385
|
+
mkdirSync(preferredFunctionsPathFromProject(config, cwd), { recursive: true })
|
|
386
|
+
}
|
|
387
|
+
|
|
388
|
+
export function writeSelfHostCompose(
|
|
389
|
+
cwd: string,
|
|
390
|
+
config: SupatypeProjectConfig,
|
|
391
|
+
options?: SelfHostComposeOptions,
|
|
392
|
+
): SelfHostComposePaths {
|
|
393
|
+
const paths = selfHostComposePaths(cwd)
|
|
394
|
+
mkdirSync(paths.dir, { recursive: true })
|
|
395
|
+
ensureProjectFunctionsDir(cwd, config)
|
|
396
|
+
ensureComposeManifest(cwd)
|
|
397
|
+
writeFileSync(paths.composePath, renderSelfHostCompose(config, cwd, options), "utf8")
|
|
398
|
+
const studioHostDev = options?.devLocal === true && hasStudioOverride(config)
|
|
399
|
+
writeFileSync(
|
|
400
|
+
paths.kongPath,
|
|
401
|
+
buildKongDeclarative({
|
|
402
|
+
unifiedGateway: true,
|
|
403
|
+
...(studioHostDev && {
|
|
404
|
+
studioServiceUrl: COMPOSE_STUDIO_HOST_URL,
|
|
405
|
+
studioStripPath: false,
|
|
406
|
+
}),
|
|
407
|
+
}),
|
|
408
|
+
"utf8",
|
|
409
|
+
)
|
|
410
|
+
return paths
|
|
411
|
+
}
|
|
412
|
+
|
|
413
|
+
export interface RunDockerComposeOptions {
|
|
414
|
+
/** Suppress docker compose progress UI (container status lines). */
|
|
415
|
+
quiet?: boolean
|
|
416
|
+
}
|
|
417
|
+
|
|
418
|
+
export function runDockerCompose(
|
|
419
|
+
composePath: string,
|
|
420
|
+
args: string[],
|
|
421
|
+
projectRoot: string = process.cwd(),
|
|
422
|
+
composeProject?: string,
|
|
423
|
+
options?: RunDockerComposeOptions,
|
|
424
|
+
): number {
|
|
425
|
+
const envFile = resolve(projectRoot, ".env")
|
|
426
|
+
const composeArgs = ["compose"]
|
|
427
|
+
if (options?.quiet) {
|
|
428
|
+
composeArgs.push("--progress", "quiet")
|
|
429
|
+
}
|
|
430
|
+
// Per-project name isolates containers/volumes/network so multiple Supatype
|
|
431
|
+
// projects on one machine never share a database (default would be the
|
|
432
|
+
// ".supatype/self-host" dir name, identical for every project).
|
|
433
|
+
if (composeProject) composeArgs.push("-p", composeProject)
|
|
434
|
+
// Resolve ${VAR} in compose.yml from the project root .env (not .supatype/self-host/).
|
|
435
|
+
composeArgs.push("--project-directory", projectRoot)
|
|
436
|
+
composeArgs.push("-f", composePath)
|
|
437
|
+
if (existsSync(envFile)) {
|
|
438
|
+
composeArgs.push("--env-file", envFile)
|
|
439
|
+
}
|
|
440
|
+
composeArgs.push(...args)
|
|
441
|
+
const env: NodeJS.ProcessEnv = options?.quiet
|
|
442
|
+
? { ...process.env, COMPOSE_PROGRESS: "quiet" }
|
|
443
|
+
: process.env
|
|
444
|
+
const result = spawnSync("docker", composeArgs, { stdio: "inherit", cwd: projectRoot, env })
|
|
445
|
+
return result.status ?? 1
|
|
446
|
+
}
|
|
447
|
+
|
|
448
|
+
/** Compose project name for a Supatype project — isolates docker state per project. */
|
|
449
|
+
export function composeProjectName(projectName: string): string {
|
|
450
|
+
const slug = projectName.toLowerCase().replace(/[^a-z0-9_-]+/g, "-").replace(/^-+|-+$/g, "")
|
|
451
|
+
return `supatype-${slug || "project"}`
|
|
452
|
+
}
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Provision storage buckets declared in a schema AST via the storage server API.
|
|
3
|
+
*
|
|
4
|
+
* The storage server is the authority on bucket existence — going through the API
|
|
5
|
+
* ensures it creates any backing resources (directories, S3 buckets, etc.).
|
|
6
|
+
* Buckets already registered return 409 Conflict, which is treated as success.
|
|
7
|
+
*/
|
|
8
|
+
|
|
9
|
+
export interface BucketSpec {
|
|
10
|
+
id: string
|
|
11
|
+
public: boolean
|
|
12
|
+
allowed_mime_types?: string[] | null
|
|
13
|
+
file_size_limit?: number | null
|
|
14
|
+
access_mode?: "public" | "private" | "custom"
|
|
15
|
+
s3_bucket_policy?: string | null
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
/**
|
|
19
|
+
* Ensure all declared buckets exist in the storage server.
|
|
20
|
+
*
|
|
21
|
+
* @param storageApiUrl Base URL of the storage API, e.g. "http://localhost:54321/storage/v1"
|
|
22
|
+
* @param serviceRoleKey A service_role JWT for the storage server
|
|
23
|
+
* @param buckets Buckets to provision (from the resolved AST)
|
|
24
|
+
*/
|
|
25
|
+
export async function provisionBuckets(
|
|
26
|
+
storageApiUrl: string,
|
|
27
|
+
serviceRoleKey: string,
|
|
28
|
+
buckets: BucketSpec[],
|
|
29
|
+
): Promise<void> {
|
|
30
|
+
const base = storageApiUrl.replace(/\/$/, "")
|
|
31
|
+
const headers = {
|
|
32
|
+
"Authorization": `Bearer ${serviceRoleKey}`,
|
|
33
|
+
"Content-Type": "application/json",
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
for (const bucket of buckets) {
|
|
37
|
+
const body = JSON.stringify({
|
|
38
|
+
id: bucket.id,
|
|
39
|
+
name: bucket.id,
|
|
40
|
+
public: bucket.public,
|
|
41
|
+
...(bucket.allowed_mime_types != null && { allowed_mime_types: bucket.allowed_mime_types }),
|
|
42
|
+
...(bucket.file_size_limit != null && { file_size_limit: bucket.file_size_limit }),
|
|
43
|
+
...(bucket.access_mode != null && { access_mode: bucket.access_mode }),
|
|
44
|
+
...(bucket.s3_bucket_policy != null &&
|
|
45
|
+
bucket.s3_bucket_policy !== "" && { s3_bucket_policy: bucket.s3_bucket_policy }),
|
|
46
|
+
})
|
|
47
|
+
|
|
48
|
+
const res = await fetch(`${base}/bucket`, { method: "POST", headers, body })
|
|
49
|
+
.catch(() => null)
|
|
50
|
+
|
|
51
|
+
if (res === null) continue // server not reachable — skip silently
|
|
52
|
+
if (res.status === 409) continue // already exists — fine
|
|
53
|
+
if (!res.ok) {
|
|
54
|
+
const msg = await res.text().catch(() => res.statusText)
|
|
55
|
+
console.warn(`[storage] Failed to provision bucket "${bucket.id}": ${msg}`)
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import type { SupatypeProjectConfig } from "./project-config.js"
|
|
2
|
+
|
|
3
|
+
export const DEFAULT_STUDIO_ADMIN_ROLES = ["admin", "supatype_admin"] as const
|
|
4
|
+
|
|
5
|
+
/** Studio admin roles from `supatype.config.ts` `admin.roles` or defaults. */
|
|
6
|
+
export function studioAdminRoles(cfg: SupatypeProjectConfig): string[] {
|
|
7
|
+
const roles = cfg.admin?.roles
|
|
8
|
+
if (roles !== undefined && roles.length > 0) return roles
|
|
9
|
+
return [...DEFAULT_STUDIO_ADMIN_ROLES]
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
/** Merge `adminRoles` into engine admin-config JSON for Studio and supatype-server. */
|
|
13
|
+
export function withAdminRoles(admin: unknown, cfg: SupatypeProjectConfig): Record<string, unknown> {
|
|
14
|
+
const base = typeof admin === "object" && admin !== null ? (admin as Record<string, unknown>) : {}
|
|
15
|
+
return { ...base, adminRoles: studioAdminRoles(cfg) }
|
|
16
|
+
}
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
import { existsSync } from "node:fs"
|
|
2
|
+
import { join, resolve } from "node:path"
|
|
3
|
+
import { ProcessManager } from "./process-manager.js"
|
|
4
|
+
|
|
5
|
+
const STUDIO_PORT = 3002
|
|
6
|
+
|
|
7
|
+
export interface StudioDevServerOptions {
|
|
8
|
+
cwd: string
|
|
9
|
+
studioOverride: string
|
|
10
|
+
pidDir: string
|
|
11
|
+
serviceRoleKey: string
|
|
12
|
+
/**
|
|
13
|
+
* Where Vite proxies API requests (Kong gateway port for compose dev, or
|
|
14
|
+
* supatype-server port for native `supatype dev`).
|
|
15
|
+
*/
|
|
16
|
+
proxyTarget: string
|
|
17
|
+
/**
|
|
18
|
+
* Public Supatype URL the browser uses. Compose dev: Kong on the host.
|
|
19
|
+
* Native dev: Vite dev server (same origin as Studio).
|
|
20
|
+
*/
|
|
21
|
+
viteSupatypeUrl: string
|
|
22
|
+
/** Vite `base` — `/studio/` when behind Kong at `/studio/`; `/` for native dev on :3002. */
|
|
23
|
+
basePath?: string
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
/** Start @supatype/studio Vite dev server when `overrides.studio` is set. */
|
|
27
|
+
export function startStudioViteDevServer(opts: StudioDevServerOptions): ProcessManager | null {
|
|
28
|
+
const studioDir = resolve(opts.cwd, opts.studioOverride)
|
|
29
|
+
const viteJs = join(studioDir, "node_modules", "vite", "bin", "vite.js")
|
|
30
|
+
if (!existsSync(viteJs)) {
|
|
31
|
+
console.warn(`[supatype] ⚠ Studio override set but vite not found at ${viteJs}. Run: pnpm install`)
|
|
32
|
+
return null
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
const basePath = opts.basePath ?? "/"
|
|
36
|
+
return new ProcessManager(
|
|
37
|
+
process.execPath,
|
|
38
|
+
[viteJs, "--port", String(STUDIO_PORT), "--strictPort", "--host"],
|
|
39
|
+
{
|
|
40
|
+
label: "studio",
|
|
41
|
+
pidDir: opts.pidDir,
|
|
42
|
+
cwd: studioDir,
|
|
43
|
+
colour: "\x1b[35m",
|
|
44
|
+
env: {
|
|
45
|
+
VITE_SUPATYPE_URL: opts.viteSupatypeUrl,
|
|
46
|
+
SUPATYPE_PROXY_TARGET: opts.proxyTarget,
|
|
47
|
+
VITE_SUPATYPE_ANON_KEY: opts.serviceRoleKey,
|
|
48
|
+
VITE_SUPATYPE_SERVICE_ROLE_KEY: opts.serviceRoleKey,
|
|
49
|
+
VITE_BASE_PATH: basePath,
|
|
50
|
+
},
|
|
51
|
+
},
|
|
52
|
+
)
|
|
53
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
process.stdout.write("hello from tsx")
|