@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
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
import type { Command } from "commander"
|
|
2
|
+
import { writeFileSync } from "node:fs"
|
|
3
|
+
import { loadProjectLink } from "../link.js"
|
|
4
|
+
import { resolveTarget, targetSchemaIntrospect, schemaPgSchema } from "../resolve-target.js"
|
|
5
|
+
import type { DatabaseStateJson } from "../pull-utils.js"
|
|
6
|
+
import { printIntrospectSummary } from "../pull-utils.js"
|
|
7
|
+
import { info, plain } from "../ui/messages.js"
|
|
8
|
+
|
|
9
|
+
export function registerIntrospect(program: Command): void {
|
|
10
|
+
program
|
|
11
|
+
.command("introspect")
|
|
12
|
+
.description("Introspect the live Postgres database (JSON or summary)")
|
|
13
|
+
.option("--connection <url>", "Database connection URL (overrides config)")
|
|
14
|
+
.option("--env <name>", "Target environment when linked")
|
|
15
|
+
.option("--direct", "Use local engine subprocess")
|
|
16
|
+
.option("--json", "Output full DatabaseState JSON")
|
|
17
|
+
.option("--out <path>", "Write JSON output to a file")
|
|
18
|
+
.action(async (opts: {
|
|
19
|
+
connection?: string
|
|
20
|
+
env?: string
|
|
21
|
+
direct?: boolean
|
|
22
|
+
json?: boolean
|
|
23
|
+
out?: string
|
|
24
|
+
}) => {
|
|
25
|
+
const cwd = process.cwd()
|
|
26
|
+
const pgSchema = schemaPgSchema(cwd)
|
|
27
|
+
|
|
28
|
+
const linked = loadProjectLink(cwd)
|
|
29
|
+
const target = linked && !opts.direct && !opts.connection
|
|
30
|
+
? resolveTarget(cwd, { env: opts.env })
|
|
31
|
+
: resolveTarget(cwd, { env: opts.env, direct: true, connection: opts.connection })
|
|
32
|
+
|
|
33
|
+
const state = (await targetSchemaIntrospect(target, { schema: pgSchema })) as DatabaseStateJson
|
|
34
|
+
|
|
35
|
+
if (opts.out) {
|
|
36
|
+
writeFileSync(opts.out, JSON.stringify(state, null, 2), "utf8")
|
|
37
|
+
info(`Wrote introspection to ${opts.out}`)
|
|
38
|
+
return
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
if (opts.json) {
|
|
42
|
+
plain(JSON.stringify(state, null, 2))
|
|
43
|
+
return
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
printIntrospectSummary(state)
|
|
47
|
+
})
|
|
48
|
+
}
|
package/src/commands/keys.ts
CHANGED
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
import type { Command } from "commander"
|
|
2
|
-
import { readFileSync, existsSync } from "node:fs"
|
|
2
|
+
import { readFileSync, existsSync, writeFileSync } from "node:fs"
|
|
3
3
|
import { resolve } from "node:path"
|
|
4
4
|
import { signJwt } from "../jwt.js"
|
|
5
|
+
import { error, plain } from "../ui/messages.js"
|
|
5
6
|
|
|
6
7
|
export function registerKeys(program: Command): void {
|
|
7
8
|
program
|
|
@@ -12,15 +13,13 @@ export function registerKeys(program: Command): void {
|
|
|
12
13
|
.action((opts: { secret?: string; expYears: string }) => {
|
|
13
14
|
const secret = opts.secret ?? resolveSecret()
|
|
14
15
|
if (!secret) {
|
|
15
|
-
|
|
16
|
-
"Error: JWT_SECRET not found. Set it in .env or pass --secret <value>",
|
|
17
|
-
)
|
|
16
|
+
error("JWT_SECRET not found. Set it in .env or pass --secret <value>")
|
|
18
17
|
process.exit(1)
|
|
19
18
|
}
|
|
20
19
|
|
|
21
20
|
const expYears = parseInt(opts.expYears, 10)
|
|
22
21
|
if (isNaN(expYears) || expYears < 1) {
|
|
23
|
-
|
|
22
|
+
error("--exp-years must be a positive integer")
|
|
24
23
|
process.exit(1)
|
|
25
24
|
}
|
|
26
25
|
|
|
@@ -30,24 +29,67 @@ export function registerKeys(program: Command): void {
|
|
|
30
29
|
const anonKey = signJwt({ iss: "supatype", role: "anon", iat: now, exp }, secret)
|
|
31
30
|
const serviceKey = signJwt({ iss: "supatype", role: "service_role", iat: now, exp }, secret)
|
|
32
31
|
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
"\nAdd these to your .env file. Do not commit .env to source control.",
|
|
38
|
-
)
|
|
32
|
+
plain(`\nGenerated keys (valid for ${expYears} years):\n`)
|
|
33
|
+
plain("ANON_KEY=" + anonKey)
|
|
34
|
+
plain("SERVICE_ROLE_KEY=" + serviceKey)
|
|
35
|
+
plain("\nAdd these to your .env file. Do not commit .env to source control.")
|
|
39
36
|
})
|
|
40
37
|
}
|
|
41
38
|
|
|
42
39
|
// ─── Helpers ─────────────────────────────────────────────────────────────────
|
|
43
40
|
|
|
44
|
-
|
|
41
|
+
/** Mint a long-lived anon + service_role JWT pair from a secret. */
|
|
42
|
+
export function signKeyPair(
|
|
43
|
+
secret: string,
|
|
44
|
+
expYears = 10,
|
|
45
|
+
): { anonKey: string; serviceKey: string } {
|
|
46
|
+
const now = Math.floor(Date.now() / 1000)
|
|
47
|
+
const exp = now + expYears * 365 * 24 * 60 * 60
|
|
48
|
+
return {
|
|
49
|
+
anonKey: signJwt({ iss: "supatype", role: "anon", iat: now, exp }, secret),
|
|
50
|
+
serviceKey: signJwt({ iss: "supatype", role: "service_role", iat: now, exp }, secret),
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
/**
|
|
55
|
+
* Generate keys from the JWT_SECRET found in `dir`'s .env (or env var) and
|
|
56
|
+
* rewrite the ANON_KEY / SERVICE_ROLE_KEY lines in that .env file in place.
|
|
57
|
+
* Returns the minted pair, or null if no secret could be resolved.
|
|
58
|
+
*/
|
|
59
|
+
export function generateAndWriteKeys(
|
|
60
|
+
dir: string,
|
|
61
|
+
expYears = 10,
|
|
62
|
+
): { anonKey: string; serviceKey: string } | null {
|
|
63
|
+
const secret = resolveSecret(dir)
|
|
64
|
+
if (!secret) return null
|
|
65
|
+
|
|
66
|
+
const { anonKey, serviceKey } = signKeyPair(secret, expYears)
|
|
67
|
+
|
|
68
|
+
const envPath = resolve(dir, ".env")
|
|
69
|
+
if (existsSync(envPath)) {
|
|
70
|
+
let content = readFileSync(envPath, "utf8")
|
|
71
|
+
content = upsertEnvVar(content, "ANON_KEY", anonKey)
|
|
72
|
+
content = upsertEnvVar(content, "SERVICE_ROLE_KEY", serviceKey)
|
|
73
|
+
writeFileSync(envPath, content, "utf8")
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
return { anonKey, serviceKey }
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
function upsertEnvVar(content: string, key: string, value: string): string {
|
|
80
|
+
const re = new RegExp(`^${key}=.*$`, "m")
|
|
81
|
+
if (re.test(content)) return content.replace(re, `${key}=${value}`)
|
|
82
|
+
const sep = content.endsWith("\n") || content.length === 0 ? "" : "\n"
|
|
83
|
+
return `${content}${sep}${key}=${value}\n`
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
export function resolveSecret(dir: string = process.cwd()): string | undefined {
|
|
45
87
|
// 1. Check environment variable
|
|
46
88
|
const fromEnv = process.env["JWT_SECRET"]
|
|
47
89
|
if (fromEnv) return fromEnv
|
|
48
90
|
|
|
49
|
-
// 2. Parse .env file in
|
|
50
|
-
const envPath = resolve(
|
|
91
|
+
// 2. Parse .env file in the target directory
|
|
92
|
+
const envPath = resolve(dir, ".env")
|
|
51
93
|
if (!existsSync(envPath)) return undefined
|
|
52
94
|
|
|
53
95
|
try {
|
|
@@ -0,0 +1,273 @@
|
|
|
1
|
+
import type { Command } from "commander"
|
|
2
|
+
import { loadConfig } from "../config.js"
|
|
3
|
+
import {
|
|
4
|
+
createCloudLink,
|
|
5
|
+
createSelfHostLink,
|
|
6
|
+
loadProjectLink,
|
|
7
|
+
saveProjectLink,
|
|
8
|
+
type ProjectLink,
|
|
9
|
+
} from "../link.js"
|
|
10
|
+
import { ensureSupatypeGitignore, warnIfLinkNotGitignored } from "../gitignore.js"
|
|
11
|
+
import { targetFetch } from "../target-client.js"
|
|
12
|
+
import { error, info, plain } from "../ui/messages.js"
|
|
13
|
+
import { nextSteps } from "../ui/next-steps.js"
|
|
14
|
+
import { isInteractive } from "../ui/interactive.js"
|
|
15
|
+
import { ensureNotCancelled, printLogo, clack as p } from "../ui/prompts.js"
|
|
16
|
+
|
|
17
|
+
function resolveLinkToken(opts: {
|
|
18
|
+
token?: string
|
|
19
|
+
serviceRoleKey?: string
|
|
20
|
+
}): string | undefined {
|
|
21
|
+
return (
|
|
22
|
+
opts.token ??
|
|
23
|
+
opts.serviceRoleKey ??
|
|
24
|
+
process.env["SUPATYPE_ACCESS_TOKEN"] ??
|
|
25
|
+
process.env["SUPATYPE_TOKEN"] ??
|
|
26
|
+
process.env["SERVICE_ROLE_KEY"]
|
|
27
|
+
)
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
async function probeSelfHostLink(apiUrl: string, projectRef: string, token: string): Promise<void> {
|
|
31
|
+
await targetFetch(apiUrl, "/platform/v1", {
|
|
32
|
+
method: "GET",
|
|
33
|
+
path: `/projects/${projectRef}/status`,
|
|
34
|
+
token,
|
|
35
|
+
})
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
export function registerEnvs(program: Command): void {
|
|
39
|
+
const envs = program.command("envs").description("Manage linked deployment environments")
|
|
40
|
+
|
|
41
|
+
envs
|
|
42
|
+
.command("list")
|
|
43
|
+
.description("List linked environments")
|
|
44
|
+
.action(() => {
|
|
45
|
+
const cwd = process.cwd()
|
|
46
|
+
const link = loadProjectLink(cwd)
|
|
47
|
+
if (!link) {
|
|
48
|
+
info("Not linked. Run: supatype link")
|
|
49
|
+
return
|
|
50
|
+
}
|
|
51
|
+
plain(`\nProject: ${link.projectRef} (${link.kind})`)
|
|
52
|
+
plain(`Default: ${link.defaultEnvironment}\n`)
|
|
53
|
+
for (const [name, env] of Object.entries(link.environments)) {
|
|
54
|
+
const mark = name === link.defaultEnvironment ? " *" : " "
|
|
55
|
+
plain(`${mark} ${name.padEnd(14)} ${env.apiUrl}`)
|
|
56
|
+
}
|
|
57
|
+
plain()
|
|
58
|
+
})
|
|
59
|
+
|
|
60
|
+
envs
|
|
61
|
+
.command("use <name>")
|
|
62
|
+
.description("Set the default environment")
|
|
63
|
+
.action((name: string) => {
|
|
64
|
+
const cwd = process.cwd()
|
|
65
|
+
const link = loadProjectLink(cwd)
|
|
66
|
+
if (!link?.environments[name]) {
|
|
67
|
+
error(`Environment "${name}" is not linked.`)
|
|
68
|
+
process.exit(1)
|
|
69
|
+
}
|
|
70
|
+
link.defaultEnvironment = name
|
|
71
|
+
saveProjectLink(cwd, link)
|
|
72
|
+
info(`Default environment set to "${name}".`)
|
|
73
|
+
})
|
|
74
|
+
|
|
75
|
+
envs
|
|
76
|
+
.command("create <name>")
|
|
77
|
+
.description("Create a cloud environment (staging/preview)")
|
|
78
|
+
.action(async (name: string) => {
|
|
79
|
+
const cwd = process.cwd()
|
|
80
|
+
const link = loadProjectLink(cwd)
|
|
81
|
+
if (!link || link.kind !== "cloud") {
|
|
82
|
+
error("Cloud link required. Run: supatype link --project <slug>")
|
|
83
|
+
process.exit(1)
|
|
84
|
+
}
|
|
85
|
+
if (!link.token || !link.cloudApiUrl) {
|
|
86
|
+
error("Missing cloud credentials in link.json")
|
|
87
|
+
process.exit(1)
|
|
88
|
+
}
|
|
89
|
+
const bodyName = name === "staging" || name === "preview" ? name : "staging"
|
|
90
|
+
await targetFetch(link.cloudApiUrl, "/api/v1", {
|
|
91
|
+
method: "POST",
|
|
92
|
+
path: `/projects/${link.projectRef}/environments`,
|
|
93
|
+
body: { name: bodyName },
|
|
94
|
+
token: link.token,
|
|
95
|
+
orgId: link.orgId,
|
|
96
|
+
})
|
|
97
|
+
const envsList = await targetFetch<Array<{ name: string; apiUrl: string }>>(
|
|
98
|
+
link.cloudApiUrl,
|
|
99
|
+
"/api/v1",
|
|
100
|
+
{
|
|
101
|
+
method: "GET",
|
|
102
|
+
path: `/projects/${link.projectRef}/environments`,
|
|
103
|
+
token: link.token,
|
|
104
|
+
orgId: link.orgId,
|
|
105
|
+
},
|
|
106
|
+
)
|
|
107
|
+
const updated = createCloudLink({
|
|
108
|
+
projectRef: link.projectRef,
|
|
109
|
+
cloudApiUrl: link.cloudApiUrl,
|
|
110
|
+
token: link.token,
|
|
111
|
+
environments: envsList.map((e) => ({ name: e.name, apiUrl: e.apiUrl })),
|
|
112
|
+
existing: link,
|
|
113
|
+
...(link.orgId !== undefined ? { orgId: link.orgId } : {}),
|
|
114
|
+
})
|
|
115
|
+
saveProjectLink(cwd, updated)
|
|
116
|
+
info(`Environment "${bodyName}" created.`)
|
|
117
|
+
})
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
export function registerLinkOptions(linkCmd: Command): void {
|
|
121
|
+
linkCmd
|
|
122
|
+
.option("--project <slug>", "Cloud project slug")
|
|
123
|
+
.option("--url <url>", "Self-host or local Kong URL")
|
|
124
|
+
.option("--api-url <url>", "Cloud control plane API URL", "https://api.supatype.com")
|
|
125
|
+
.option("--token <token>", "Access token (cloud PAT or self-host SERVICE_ROLE_KEY)")
|
|
126
|
+
.option("--service-role-key <key>", "Deprecated alias for --token on self-host")
|
|
127
|
+
.option("--env <name>", "Environment name (default: production)", "production")
|
|
128
|
+
.option("--fix-gitignore", "Append .supatype/ to .gitignore if missing")
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
export async function runLinkAction(opts: {
|
|
132
|
+
project?: string
|
|
133
|
+
url?: string
|
|
134
|
+
apiUrl: string
|
|
135
|
+
token?: string
|
|
136
|
+
serviceRoleKey?: string
|
|
137
|
+
env?: string
|
|
138
|
+
fixGitignore?: boolean
|
|
139
|
+
}): Promise<void> {
|
|
140
|
+
const cwd = process.cwd()
|
|
141
|
+
const config = loadConfig(cwd)
|
|
142
|
+
const projectRef = config.project?.name ?? "project"
|
|
143
|
+
const envName = opts.env ?? "production"
|
|
144
|
+
let project = opts.project
|
|
145
|
+
let url = opts.url
|
|
146
|
+
|
|
147
|
+
if (isInteractive() && !project && !url) {
|
|
148
|
+
printLogo()
|
|
149
|
+
p.intro("Link this project")
|
|
150
|
+
const targetKind = ensureNotCancelled(
|
|
151
|
+
await p.select<"cloud" | "self-host">({
|
|
152
|
+
message: "Link target",
|
|
153
|
+
options: [
|
|
154
|
+
{ value: "cloud", label: "Supatype Cloud", hint: "managed project on supatype.com" },
|
|
155
|
+
{ value: "self-host", label: "Self-host", hint: "your Kong gateway URL" },
|
|
156
|
+
],
|
|
157
|
+
}),
|
|
158
|
+
)
|
|
159
|
+
if (targetKind === "cloud") {
|
|
160
|
+
project = ensureNotCancelled(
|
|
161
|
+
await p.text({
|
|
162
|
+
message: "Cloud project slug",
|
|
163
|
+
placeholder: projectRef,
|
|
164
|
+
defaultValue: projectRef,
|
|
165
|
+
}),
|
|
166
|
+
).trim()
|
|
167
|
+
} else {
|
|
168
|
+
url = ensureNotCancelled(
|
|
169
|
+
await p.text({
|
|
170
|
+
message: "Kong gateway URL",
|
|
171
|
+
placeholder: "https://api.example.com",
|
|
172
|
+
defaultValue: "http://localhost:18473",
|
|
173
|
+
}),
|
|
174
|
+
).trim()
|
|
175
|
+
}
|
|
176
|
+
p.outro("Linking...")
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
const token = resolveLinkToken(opts)
|
|
180
|
+
|
|
181
|
+
if (opts.fixGitignore) {
|
|
182
|
+
ensureSupatypeGitignore(cwd)
|
|
183
|
+
} else {
|
|
184
|
+
warnIfLinkNotGitignored(cwd)
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
const existing = loadProjectLink(cwd)
|
|
188
|
+
|
|
189
|
+
if (url) {
|
|
190
|
+
if (!token) {
|
|
191
|
+
error("Authentication required. Pass --token $SERVICE_ROLE_KEY")
|
|
192
|
+
process.exit(1)
|
|
193
|
+
}
|
|
194
|
+
const apiUrl = url.replace(/\/$/, "")
|
|
195
|
+
await probeSelfHostLink(apiUrl, projectRef, token)
|
|
196
|
+
const link = createSelfHostLink({
|
|
197
|
+
projectRef,
|
|
198
|
+
apiUrl,
|
|
199
|
+
token,
|
|
200
|
+
envName,
|
|
201
|
+
existing,
|
|
202
|
+
})
|
|
203
|
+
saveProjectLink(cwd, link)
|
|
204
|
+
info(`Linked to self-host environment "${envName}" at ${apiUrl}`)
|
|
205
|
+
nextSteps("Next steps:", [
|
|
206
|
+
"supatype push --env " + envName,
|
|
207
|
+
"supatype deploy",
|
|
208
|
+
])
|
|
209
|
+
return
|
|
210
|
+
}
|
|
211
|
+
|
|
212
|
+
if (!token) {
|
|
213
|
+
error("Authentication required. Set SUPATYPE_ACCESS_TOKEN or pass --token.")
|
|
214
|
+
process.exit(1)
|
|
215
|
+
}
|
|
216
|
+
|
|
217
|
+
const cloudApiUrl = opts.apiUrl.replace(/\/$/, "")
|
|
218
|
+
|
|
219
|
+
if (project) {
|
|
220
|
+
const one = await targetFetch<{ slug: string; orgId: string }>(cloudApiUrl, "/api/v1", {
|
|
221
|
+
method: "GET",
|
|
222
|
+
path: `/projects/${project}`,
|
|
223
|
+
token,
|
|
224
|
+
})
|
|
225
|
+
let environments: Array<{ name: string; apiUrl: string }> = [
|
|
226
|
+
{ name: "production", apiUrl: cloudApiUrl },
|
|
227
|
+
]
|
|
228
|
+
try {
|
|
229
|
+
const listed = await targetFetch<Array<{ name: string; apiUrl: string }>>(
|
|
230
|
+
cloudApiUrl,
|
|
231
|
+
"/api/v1",
|
|
232
|
+
{
|
|
233
|
+
method: "GET",
|
|
234
|
+
path: `/projects/${project}/environments`,
|
|
235
|
+
token,
|
|
236
|
+
orgId: one.orgId,
|
|
237
|
+
},
|
|
238
|
+
)
|
|
239
|
+
if (listed.length > 0) {
|
|
240
|
+
environments = listed.map((e) => ({ name: e.name, apiUrl: e.apiUrl }))
|
|
241
|
+
}
|
|
242
|
+
} catch {
|
|
243
|
+
// environments optional on older control planes
|
|
244
|
+
}
|
|
245
|
+
const link = createCloudLink({
|
|
246
|
+
projectRef: project,
|
|
247
|
+
cloudApiUrl,
|
|
248
|
+
token,
|
|
249
|
+
orgId: one.orgId,
|
|
250
|
+
environments,
|
|
251
|
+
existing,
|
|
252
|
+
})
|
|
253
|
+
saveProjectLink(cwd, link)
|
|
254
|
+
info(`Linked to cloud project: ${project}`)
|
|
255
|
+
nextSteps("Next steps:", [
|
|
256
|
+
"supatype push --env production",
|
|
257
|
+
"supatype deploy",
|
|
258
|
+
])
|
|
259
|
+
return
|
|
260
|
+
}
|
|
261
|
+
|
|
262
|
+
error("Specify --project <slug> for cloud or --url <kong-url> for self-host.")
|
|
263
|
+
process.exit(1)
|
|
264
|
+
}
|
|
265
|
+
|
|
266
|
+
export function getLinkOrExit(cwd: string): ProjectLink {
|
|
267
|
+
const link = loadProjectLink(cwd)
|
|
268
|
+
if (!link) {
|
|
269
|
+
error("Not linked. Run: supatype link")
|
|
270
|
+
process.exit(1)
|
|
271
|
+
}
|
|
272
|
+
return link
|
|
273
|
+
}
|
package/src/commands/logs.ts
CHANGED
|
@@ -3,6 +3,7 @@
|
|
|
3
3
|
*/
|
|
4
4
|
import type { Command } from "commander"
|
|
5
5
|
import { spawn } from "node:child_process"
|
|
6
|
+
import { error } from "../ui/messages.js"
|
|
6
7
|
|
|
7
8
|
const SERVICES = ["postgres", "postgrest", "gotrue", "kong", "minio", "realtime", "studio"]
|
|
8
9
|
|
|
@@ -19,8 +20,8 @@ export function registerLogs(program: Command): void {
|
|
|
19
20
|
: SERVICES.map((s) => `supatype-${s}`)
|
|
20
21
|
|
|
21
22
|
if (opts.service && !SERVICES.includes(opts.service)) {
|
|
22
|
-
|
|
23
|
-
|
|
23
|
+
error(`Unknown service: ${opts.service}`)
|
|
24
|
+
error(`Available: ${SERVICES.join(", ")}`)
|
|
24
25
|
process.exit(1)
|
|
25
26
|
}
|
|
26
27
|
|
|
@@ -39,7 +40,7 @@ export function registerLogs(program: Command): void {
|
|
|
39
40
|
|
|
40
41
|
const child = spawn("docker", containerArgs, { stdio: "inherit" })
|
|
41
42
|
child.on("error", () => {
|
|
42
|
-
|
|
43
|
+
error("Docker not found. Ensure Docker is installed and running.")
|
|
43
44
|
process.exit(1)
|
|
44
45
|
})
|
|
45
46
|
return
|
|
@@ -51,7 +52,7 @@ export function registerLogs(program: Command): void {
|
|
|
51
52
|
cwd: process.cwd(),
|
|
52
53
|
})
|
|
53
54
|
child.on("error", () => {
|
|
54
|
-
|
|
55
|
+
error("Docker not found. Ensure Docker is installed and running.")
|
|
55
56
|
process.exit(1)
|
|
56
57
|
})
|
|
57
58
|
})
|
|
@@ -4,6 +4,7 @@ import { basename, dirname, extname, join, resolve } from "node:path"
|
|
|
4
4
|
import ts from "typescript"
|
|
5
5
|
import { loadConfig } from "../config.js"
|
|
6
6
|
import { schemaPathFromProject } from "../project-config.js"
|
|
7
|
+
import { info } from "../ui/messages.js"
|
|
7
8
|
|
|
8
9
|
export function registerMigrateFromV1(program: Command): void {
|
|
9
10
|
program
|
|
@@ -29,9 +30,9 @@ export function registerMigrateFromV1(program: Command): void {
|
|
|
29
30
|
: join(dirname(schemaPath), basename(schemaPath).replace(extname(schemaPath), ".v2.ts"))
|
|
30
31
|
|
|
31
32
|
writeFileSync(outPath, output, "utf8")
|
|
32
|
-
|
|
33
|
+
info(`v2 schema written to ${outPath}`)
|
|
33
34
|
if (!opts.write) {
|
|
34
|
-
|
|
35
|
+
info("Review TODO comments and replace unknown mappings before using this file in production.")
|
|
35
36
|
}
|
|
36
37
|
})
|
|
37
38
|
}
|