@supatype/cli 0.1.1 → 0.1.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.turbo/turbo-build.log +1 -1
- package/.turbo/turbo-test.log +114 -90
- package/.turbo/turbo-typecheck.log +2 -2
- package/dist/binary-cache.d.ts +2 -0
- package/dist/binary-cache.d.ts.map +1 -1
- package/dist/binary-cache.js +36 -0
- package/dist/binary-cache.js.map +1 -1
- package/dist/binary-download-lock.d.ts +12 -0
- package/dist/binary-download-lock.d.ts.map +1 -0
- package/dist/binary-download-lock.js +106 -0
- package/dist/binary-download-lock.js.map +1 -0
- package/dist/cli-package-version.d.ts +3 -0
- package/dist/cli-package-version.d.ts.map +1 -0
- package/dist/cli-package-version.js +15 -0
- package/dist/cli-package-version.js.map +1 -0
- package/dist/cli.d.ts.map +1 -1
- package/dist/cli.js +5 -2
- package/dist/cli.js.map +1 -1
- package/dist/commands/add.js +25 -19
- package/dist/commands/add.js.map +1 -1
- package/dist/commands/admin.d.ts.map +1 -1
- package/dist/commands/admin.js +22 -6
- package/dist/commands/admin.js.map +1 -1
- package/dist/commands/cache.d.ts +1 -1
- package/dist/commands/cache.d.ts.map +1 -1
- package/dist/commands/cache.js +98 -5
- package/dist/commands/cache.js.map +1 -1
- package/dist/commands/dev.d.ts.map +1 -1
- package/dist/commands/dev.js +26 -22
- package/dist/commands/dev.js.map +1 -1
- package/dist/commands/init.d.ts +3 -4
- package/dist/commands/init.d.ts.map +1 -1
- package/dist/commands/init.js +238 -168
- package/dist/commands/init.js.map +1 -1
- package/dist/commands/link-helpers.d.ts.map +1 -1
- package/dist/commands/link-helpers.js +26 -25
- package/dist/commands/link-helpers.js.map +1 -1
- package/dist/compose-local-server-image.d.ts +13 -0
- package/dist/compose-local-server-image.d.ts.map +1 -0
- package/dist/compose-local-server-image.js +57 -0
- package/dist/compose-local-server-image.js.map +1 -0
- package/dist/compose-rename.d.ts.map +1 -1
- package/dist/compose-rename.js +5 -8
- package/dist/compose-rename.js.map +1 -1
- package/dist/dev-compose.d.ts.map +1 -1
- package/dist/dev-compose.js +111 -54
- package/dist/dev-compose.js.map +1 -1
- package/dist/dev-log-bus.d.ts +5 -0
- package/dist/dev-log-bus.d.ts.map +1 -1
- package/dist/dev-log-bus.js +14 -0
- package/dist/dev-log-bus.js.map +1 -1
- package/dist/dev-log-filter.d.ts +4 -0
- package/dist/dev-log-filter.d.ts.map +1 -1
- package/dist/dev-log-filter.js +52 -0
- package/dist/dev-log-filter.js.map +1 -1
- package/dist/dev-ports.d.ts.map +1 -1
- package/dist/dev-ports.js +19 -12
- package/dist/dev-ports.js.map +1 -1
- package/dist/dev-ready-panel.d.ts +19 -0
- package/dist/dev-ready-panel.d.ts.map +1 -0
- package/dist/dev-ready-panel.js +49 -0
- package/dist/dev-ready-panel.js.map +1 -0
- package/dist/dev-session-lock.d.ts.map +1 -1
- package/dist/dev-session-lock.js +5 -8
- package/dist/dev-session-lock.js.map +1 -1
- package/dist/dev-session.d.ts +18 -5
- package/dist/dev-session.d.ts.map +1 -1
- package/dist/dev-session.js +91 -18
- package/dist/dev-session.js.map +1 -1
- package/dist/dev-shutdown.d.ts +2 -0
- package/dist/dev-shutdown.d.ts.map +1 -1
- package/dist/dev-shutdown.js +29 -15
- package/dist/dev-shutdown.js.map +1 -1
- package/dist/dev-task-colors.d.ts +3 -1
- package/dist/dev-task-colors.d.ts.map +1 -1
- package/dist/dev-task-colors.js +23 -3
- package/dist/dev-task-colors.js.map +1 -1
- package/dist/docker-runtime.js +1 -1
- package/dist/docker-runtime.js.map +1 -1
- package/dist/engine-push-output.d.ts +1 -0
- package/dist/engine-push-output.d.ts.map +1 -1
- package/dist/engine-push-output.js +4 -1
- package/dist/engine-push-output.js.map +1 -1
- package/dist/ensure-binary.d.ts.map +1 -1
- package/dist/ensure-binary.js +14 -2
- package/dist/ensure-binary.js.map +1 -1
- package/dist/ensure-component-binaries.d.ts +17 -0
- package/dist/ensure-component-binaries.d.ts.map +1 -0
- package/dist/ensure-component-binaries.js +45 -0
- package/dist/ensure-component-binaries.js.map +1 -0
- package/dist/ensure-dev-api-config.d.ts +3 -0
- package/dist/ensure-dev-api-config.d.ts.map +1 -0
- package/dist/ensure-dev-api-config.js +17 -0
- package/dist/ensure-dev-api-config.js.map +1 -0
- package/dist/init-dependency-versions.d.ts +13 -0
- package/dist/init-dependency-versions.d.ts.map +1 -0
- package/dist/init-dependency-versions.js +53 -0
- package/dist/init-dependency-versions.js.map +1 -0
- package/dist/init-package-json.d.ts +21 -0
- package/dist/init-package-json.d.ts.map +1 -0
- package/dist/init-package-json.js +46 -0
- package/dist/init-package-json.js.map +1 -0
- package/dist/postgres-ctl.d.ts.map +1 -1
- package/dist/postgres-ctl.js +2 -1
- package/dist/postgres-ctl.js.map +1 -1
- package/dist/required-host-components.d.ts +11 -0
- package/dist/required-host-components.d.ts.map +1 -0
- package/dist/required-host-components.js +25 -0
- package/dist/required-host-components.js.map +1 -0
- package/dist/resolve-api-url.d.ts +6 -0
- package/dist/resolve-api-url.d.ts.map +1 -0
- package/dist/resolve-api-url.js +39 -0
- package/dist/resolve-api-url.js.map +1 -0
- package/dist/rest-cache-admin.d.ts +33 -0
- package/dist/rest-cache-admin.d.ts.map +1 -0
- package/dist/rest-cache-admin.js +96 -0
- package/dist/rest-cache-admin.js.map +1 -0
- package/dist/scripts/postinstall.d.ts +4 -6
- package/dist/scripts/postinstall.d.ts.map +1 -1
- package/dist/scripts/postinstall.js +8 -41
- package/dist/scripts/postinstall.js.map +1 -1
- package/dist/self-host-compose.d.ts.map +1 -1
- package/dist/self-host-compose.js +23 -13
- package/dist/self-host-compose.js.map +1 -1
- package/dist/studio-dev-server.d.ts +4 -2
- package/dist/studio-dev-server.d.ts.map +1 -1
- package/dist/studio-dev-server.js +3 -2
- package/dist/studio-dev-server.js.map +1 -1
- package/dist/ui/brand.d.ts +2 -5
- package/dist/ui/brand.d.ts.map +1 -1
- package/dist/ui/brand.js +2 -7
- package/dist/ui/brand.js.map +1 -1
- package/dist/ui/clack-api.d.ts +44 -0
- package/dist/ui/clack-api.d.ts.map +1 -0
- package/dist/ui/clack-api.js +76 -0
- package/dist/ui/clack-api.js.map +1 -0
- package/dist/ui/clack.d.ts +14 -0
- package/dist/ui/clack.d.ts.map +1 -0
- package/dist/ui/clack.js +147 -0
- package/dist/ui/clack.js.map +1 -0
- package/dist/ui/components/FlowSpinner.d.ts +5 -0
- package/dist/ui/components/FlowSpinner.d.ts.map +1 -0
- package/dist/ui/components/FlowSpinner.js +8 -0
- package/dist/ui/components/FlowSpinner.js.map +1 -0
- package/dist/ui/components/LogoWordmark.d.ts +9 -0
- package/dist/ui/components/LogoWordmark.d.ts.map +1 -0
- package/dist/ui/components/LogoWordmark.js +17 -0
- package/dist/ui/components/LogoWordmark.js.map +1 -0
- package/dist/ui/components/PromptPanel.d.ts +5 -0
- package/dist/ui/components/PromptPanel.d.ts.map +1 -0
- package/dist/ui/components/PromptPanel.js +7 -0
- package/dist/ui/components/PromptPanel.js.map +1 -0
- package/dist/ui/components/SelectField.d.ts +11 -0
- package/dist/ui/components/SelectField.d.ts.map +1 -0
- package/dist/ui/components/SelectField.js +19 -0
- package/dist/ui/components/SelectField.js.map +1 -0
- package/dist/ui/confirm.d.ts +2 -1
- package/dist/ui/confirm.d.ts.map +1 -1
- package/dist/ui/confirm.js +4 -4
- package/dist/ui/confirm.js.map +1 -1
- package/dist/ui/dev/DevDashboard.d.ts +8 -0
- package/dist/ui/dev/DevDashboard.d.ts.map +1 -0
- package/dist/ui/dev/DevDashboard.js +151 -0
- package/dist/ui/dev/DevDashboard.js.map +1 -0
- package/dist/ui/dev/DevReadyPanelView.d.ts +7 -0
- package/dist/ui/dev/DevReadyPanelView.d.ts.map +1 -0
- package/dist/ui/dev/DevReadyPanelView.js +29 -0
- package/dist/ui/dev/DevReadyPanelView.js.map +1 -0
- package/dist/ui/fatal.d.ts.map +1 -1
- package/dist/ui/fatal.js +5 -11
- package/dist/ui/fatal.js.map +1 -1
- package/dist/ui/flows/FlowApp.d.ts +8 -0
- package/dist/ui/flows/FlowApp.d.ts.map +1 -0
- package/dist/ui/flows/FlowApp.js +42 -0
- package/dist/ui/flows/FlowApp.js.map +1 -0
- package/dist/ui/flows/prompt-fields.d.ts +48 -0
- package/dist/ui/flows/prompt-fields.d.ts.map +1 -0
- package/dist/ui/flows/prompt-fields.js +88 -0
- package/dist/ui/flows/prompt-fields.js.map +1 -0
- package/dist/ui/flows/types.d.ts +41 -0
- package/dist/ui/flows/types.d.ts.map +1 -0
- package/dist/ui/flows/types.js +2 -0
- package/dist/ui/flows/types.js.map +1 -0
- package/dist/ui/index.d.ts +1 -1
- package/dist/ui/index.js +1 -1
- package/dist/ui/messages.d.ts +1 -0
- package/dist/ui/messages.d.ts.map +1 -1
- package/dist/ui/messages.js +48 -8
- package/dist/ui/messages.js.map +1 -1
- package/dist/ui/progress.d.ts +5 -1
- package/dist/ui/progress.d.ts.map +1 -1
- package/dist/ui/progress.js +12 -3
- package/dist/ui/progress.js.map +1 -1
- package/dist/ui/prompts.d.ts +7 -5
- package/dist/ui/prompts.d.ts.map +1 -1
- package/dist/ui/prompts.js +15 -8
- package/dist/ui/prompts.js.map +1 -1
- package/dist/ui/runtime/cancel.d.ts +4 -0
- package/dist/ui/runtime/cancel.d.ts.map +1 -0
- package/dist/ui/runtime/cancel.js +6 -0
- package/dist/ui/runtime/cancel.js.map +1 -0
- package/dist/ui/runtime/command-chrome.d.ts +17 -0
- package/dist/ui/runtime/command-chrome.d.ts.map +1 -0
- package/dist/ui/runtime/command-chrome.js +123 -0
- package/dist/ui/runtime/command-chrome.js.map +1 -0
- package/dist/ui/runtime/dev-prompt-queue.d.ts +30 -0
- package/dist/ui/runtime/dev-prompt-queue.d.ts.map +1 -0
- package/dist/ui/runtime/dev-prompt-queue.js +57 -0
- package/dist/ui/runtime/dev-prompt-queue.js.map +1 -0
- package/dist/ui/runtime/flow-session.d.ts +4 -0
- package/dist/ui/runtime/flow-session.d.ts.map +1 -0
- package/dist/ui/runtime/flow-session.js +8 -0
- package/dist/ui/runtime/flow-session.js.map +1 -0
- package/dist/ui/runtime/run-clack-flow.d.ts +5 -0
- package/dist/ui/runtime/run-clack-flow.d.ts.map +1 -0
- package/dist/ui/runtime/run-clack-flow.js +34 -0
- package/dist/ui/runtime/run-clack-flow.js.map +1 -0
- package/dist/ui/theme.d.ts +24 -0
- package/dist/ui/theme.d.ts.map +1 -0
- package/dist/ui/theme.js +34 -0
- package/dist/ui/theme.js.map +1 -0
- package/dist/valkey-sidecar.d.ts +17 -0
- package/dist/valkey-sidecar.d.ts.map +1 -0
- package/dist/valkey-sidecar.js +94 -0
- package/dist/valkey-sidecar.js.map +1 -0
- package/package.json +9 -3
- package/src/binary-cache.ts +61 -0
- package/src/binary-download-lock.ts +124 -0
- package/src/cli-package-version.ts +15 -0
- package/src/cli.ts +6 -2
- package/src/commands/add.ts +26 -19
- package/src/commands/admin.ts +24 -6
- package/src/commands/cache.ts +105 -5
- package/src/commands/dev.ts +26 -21
- package/src/commands/init.ts +124 -45
- package/src/commands/link-helpers.ts +30 -29
- package/src/compose-local-server-image.ts +68 -0
- package/src/compose-rename.ts +5 -8
- package/src/dev-compose.ts +136 -51
- package/src/dev-log-bus.ts +18 -0
- package/src/dev-log-filter.ts +42 -0
- package/src/dev-ports.ts +22 -11
- package/src/dev-ready-panel.ts +63 -0
- package/src/dev-session-lock.ts +5 -8
- package/src/dev-session.ts +98 -18
- package/src/dev-shutdown.ts +29 -17
- package/src/dev-task-colors.ts +22 -3
- package/src/docker-runtime.ts +1 -1
- package/src/engine-push-output.ts +5 -1
- package/src/ensure-binary.ts +21 -1
- package/src/ensure-component-binaries.ts +71 -0
- package/src/ensure-dev-api-config.ts +18 -0
- package/src/init-dependency-versions.ts +69 -0
- package/src/init-package-json.ts +63 -0
- package/src/postgres-ctl.ts +2 -1
- package/src/required-host-components.ts +37 -0
- package/src/resolve-api-url.ts +43 -0
- package/src/rest-cache-admin.ts +135 -0
- package/src/scripts/postinstall.ts +9 -46
- package/src/self-host-compose.ts +22 -12
- package/src/studio-dev-server.ts +5 -4
- package/src/ui/README.md +13 -9
- package/src/ui/brand.ts +2 -8
- package/src/ui/clack-api.ts +123 -0
- package/src/ui/clack.ts +153 -0
- package/src/ui/components/FlowSpinner.tsx +15 -0
- package/src/ui/components/LogoWordmark.tsx +36 -0
- package/src/ui/components/PromptPanel.tsx +17 -0
- package/src/ui/components/SelectField.tsx +58 -0
- package/src/ui/confirm.ts +5 -4
- package/src/ui/dev/DevDashboard.tsx +213 -0
- package/src/ui/dev/DevReadyPanelView.tsx +67 -0
- package/src/ui/fatal.ts +5 -10
- package/src/ui/flows/FlowApp.tsx +67 -0
- package/src/ui/flows/prompt-fields.tsx +192 -0
- package/src/ui/flows/types.ts +50 -0
- package/src/ui/index.ts +1 -1
- package/src/ui/messages.ts +50 -8
- package/src/ui/progress.ts +14 -3
- package/src/ui/prompts.ts +17 -9
- package/src/ui/runtime/cancel.ts +6 -0
- package/src/ui/runtime/command-chrome.ts +147 -0
- package/src/ui/runtime/dev-prompt-queue.ts +84 -0
- package/src/ui/runtime/flow-session.ts +11 -0
- package/src/ui/runtime/run-clack-flow.tsx +52 -0
- package/src/ui/theme.ts +41 -0
- package/src/valkey-sidecar.ts +126 -0
- package/tests/binary-cache-cloud-overrides.test.ts +2 -2
- package/tests/binary-download-lock.test.ts +41 -0
- package/tests/cli-help.test.ts +7 -4
- package/tests/cli-package-version.test.ts +15 -0
- package/tests/command-chrome-coverage.test.ts +149 -0
- package/tests/command-chrome-wrap.test.ts +51 -0
- package/tests/config.test.ts +8 -4
- package/tests/dev-ready-panel.test.ts +20 -0
- package/tests/dev-ui.test.ts +42 -2
- package/tests/docker-runtime.test.ts +9 -20
- package/tests/ensure-dev-api-config.test.ts +22 -0
- package/tests/init-dependency-versions.test.ts +62 -0
- package/tests/init-package-json.test.ts +18 -0
- package/tests/init.test.ts +30 -3
- package/tests/required-host-components.test.ts +51 -0
- package/tests/resolve-api-url.test.ts +23 -0
- package/tests/rest-cache-admin.test.ts +28 -0
- package/tests/runtime-contract.test.ts +12 -3
- package/tests/tsconfig.json +8 -2
- package/tests/ui-confirm.test.ts +13 -9
- package/tests/ui-messages.test.ts +4 -18
- package/tsconfig.json +1 -0
- package/tsconfig.tsbuildinfo +1 -1
- package/vitest.config.ts +3 -0
- package/dist/dev-tui.d.ts +0 -24
- package/dist/dev-tui.d.ts.map +0 -1
- package/dist/dev-tui.js +0 -188
- package/dist/dev-tui.js.map +0 -1
- package/src/dev-tui.ts +0 -232
package/src/commands/cache.ts
CHANGED
|
@@ -1,24 +1,30 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* supatype cache — list and clean cached component binaries.
|
|
2
|
+
* supatype cache — list and clean cached component binaries + REST Valkey cache.
|
|
3
3
|
*/
|
|
4
4
|
|
|
5
5
|
import type { Command } from "commander"
|
|
6
6
|
import { existsSync, readdirSync, rmSync, statSync } from "node:fs"
|
|
7
7
|
import { join } from "node:path"
|
|
8
8
|
import { cacheRoot, type Component } from "../binary-cache.js"
|
|
9
|
-
import {
|
|
9
|
+
import {
|
|
10
|
+
deleteRestCacheEntry,
|
|
11
|
+
flushRestCache,
|
|
12
|
+
getRestCacheEntry,
|
|
13
|
+
listRestCacheEntries,
|
|
14
|
+
} from "../rest-cache-admin.js"
|
|
15
|
+
import { error, info, plain } from "../ui/messages.js"
|
|
10
16
|
|
|
11
17
|
const COMPONENTS: Component[] = ["engine", "server", "postgres", "deno"]
|
|
12
18
|
|
|
13
19
|
export function registerCache(program: Command): void {
|
|
14
20
|
const cache = program
|
|
15
21
|
.command("cache")
|
|
16
|
-
.description("Manage cached component binaries")
|
|
22
|
+
.description("Manage cached component binaries and REST API response cache")
|
|
17
23
|
|
|
18
24
|
cache
|
|
19
25
|
.command("list")
|
|
20
26
|
.description("List cached component binaries and their sizes")
|
|
21
|
-
.action(() => {
|
|
27
|
+
.action(async () => {
|
|
22
28
|
const root = cacheRoot()
|
|
23
29
|
if (!existsSync(root)) {
|
|
24
30
|
info("Cache is empty.")
|
|
@@ -62,7 +68,7 @@ export function registerCache(program: Command): void {
|
|
|
62
68
|
" supatype cache clean engine # remove all engine versions\n" +
|
|
63
69
|
" supatype cache clean engine 0.4.2",
|
|
64
70
|
)
|
|
65
|
-
.action((component?: string, version?: string) => {
|
|
71
|
+
.action(async (component?: string, version?: string) => {
|
|
66
72
|
const root = cacheRoot()
|
|
67
73
|
if (!existsSync(root)) {
|
|
68
74
|
info("Cache is already empty.")
|
|
@@ -91,6 +97,100 @@ export function registerCache(program: Command): void {
|
|
|
91
97
|
|
|
92
98
|
info("Done.")
|
|
93
99
|
})
|
|
100
|
+
|
|
101
|
+
const rest = cache
|
|
102
|
+
.command("rest")
|
|
103
|
+
.description("Manage REST API response cache in Valkey")
|
|
104
|
+
|
|
105
|
+
rest
|
|
106
|
+
.command("list")
|
|
107
|
+
.description("List cached REST GET entries")
|
|
108
|
+
.option("--table <name>", "Filter by table name")
|
|
109
|
+
.option("--json", "Output JSON")
|
|
110
|
+
.action(async (opts: { table?: string; json?: boolean }) => {
|
|
111
|
+
const cwd = process.cwd()
|
|
112
|
+
try {
|
|
113
|
+
const result = await listRestCacheEntries(cwd, { table: opts.table, limit: 100 })
|
|
114
|
+
if (opts.json) {
|
|
115
|
+
plain(JSON.stringify(result, null, 2))
|
|
116
|
+
return
|
|
117
|
+
}
|
|
118
|
+
if (result.entries.length === 0) {
|
|
119
|
+
info("No REST cache entries.")
|
|
120
|
+
return
|
|
121
|
+
}
|
|
122
|
+
for (const e of result.entries) {
|
|
123
|
+
plain(
|
|
124
|
+
` ${e.table ?? "?"} ${e.scope ?? "?"} ttl=${e.ttl_seconds}s ${e.size_bytes}B ${e.key}`,
|
|
125
|
+
)
|
|
126
|
+
}
|
|
127
|
+
if (result.cursor !== "0") {
|
|
128
|
+
plain(`\n(more available — cursor ${result.cursor})`)
|
|
129
|
+
}
|
|
130
|
+
} catch (e) {
|
|
131
|
+
error(e instanceof Error ? e.message : String(e))
|
|
132
|
+
process.exitCode = 1
|
|
133
|
+
}
|
|
134
|
+
})
|
|
135
|
+
|
|
136
|
+
rest
|
|
137
|
+
.command("get <key>")
|
|
138
|
+
.description("Show one cache entry (full Valkey key)")
|
|
139
|
+
.option("--json", "Output JSON")
|
|
140
|
+
.action(async (key: string, opts: { json?: boolean }) => {
|
|
141
|
+
const cwd = process.cwd()
|
|
142
|
+
try {
|
|
143
|
+
const detail = await getRestCacheEntry(cwd, key)
|
|
144
|
+
if (opts.json) {
|
|
145
|
+
plain(JSON.stringify(detail, null, 2))
|
|
146
|
+
return
|
|
147
|
+
}
|
|
148
|
+
plain(`key: ${detail.key}`)
|
|
149
|
+
plain(`table: ${detail.table ?? ""}`)
|
|
150
|
+
plain(`scope: ${detail.scope ?? ""}`)
|
|
151
|
+
plain(`ttl: ${detail.ttl_seconds}s`)
|
|
152
|
+
plain(`status: ${detail.status_code}`)
|
|
153
|
+
if (detail.body_preview) plain(`body:\n${detail.body_preview}`)
|
|
154
|
+
} catch (e) {
|
|
155
|
+
error(e instanceof Error ? e.message : String(e))
|
|
156
|
+
process.exitCode = 1
|
|
157
|
+
}
|
|
158
|
+
})
|
|
159
|
+
|
|
160
|
+
rest
|
|
161
|
+
.command("delete <key>")
|
|
162
|
+
.description("Delete one cache entry")
|
|
163
|
+
.action(async (key: string) => {
|
|
164
|
+
const cwd = process.cwd()
|
|
165
|
+
try {
|
|
166
|
+
await deleteRestCacheEntry(cwd, key)
|
|
167
|
+
info(`Deleted ${key}`)
|
|
168
|
+
} catch (e) {
|
|
169
|
+
error(e instanceof Error ? e.message : String(e))
|
|
170
|
+
process.exitCode = 1
|
|
171
|
+
}
|
|
172
|
+
})
|
|
173
|
+
|
|
174
|
+
rest
|
|
175
|
+
.command("flush")
|
|
176
|
+
.description("Flush REST cache entries")
|
|
177
|
+
.option("--table <name>", "Only flush one table")
|
|
178
|
+
.option("--yes", "Confirm flush")
|
|
179
|
+
.action(async (opts: { table?: string; yes?: boolean }) => {
|
|
180
|
+
if (!opts.yes) {
|
|
181
|
+
error("Pass --yes to confirm flush")
|
|
182
|
+
process.exitCode = 1
|
|
183
|
+
return
|
|
184
|
+
}
|
|
185
|
+
const cwd = process.cwd()
|
|
186
|
+
try {
|
|
187
|
+
await flushRestCache(cwd, opts.table)
|
|
188
|
+
info(opts.table ? `Flushed cache for table ${opts.table}` : "Flushed all REST cache entries")
|
|
189
|
+
} catch (e) {
|
|
190
|
+
error(e instanceof Error ? e.message : String(e))
|
|
191
|
+
process.exitCode = 1
|
|
192
|
+
}
|
|
193
|
+
})
|
|
94
194
|
}
|
|
95
195
|
|
|
96
196
|
function dirSize(dir: string): number {
|
package/src/commands/dev.ts
CHANGED
|
@@ -36,13 +36,15 @@ import {
|
|
|
36
36
|
import { ensureBinary } from "../ensure-binary.js"
|
|
37
37
|
import { startProxyDevApp } from "../app/proxy-dev-app.js"
|
|
38
38
|
import { ProcessManager } from "../process-manager.js"
|
|
39
|
-
import { startStudioViteDevServer } from "../studio-dev-server.js"
|
|
39
|
+
import { STUDIO_DEV_PORT, startStudioViteDevServer } from "../studio-dev-server.js"
|
|
40
40
|
import { restoreSystemRelationTargets } from "../restore-system-relation-targets.js"
|
|
41
41
|
import { localStorageEnv } from "../local-storage.js"
|
|
42
42
|
import { beginDevSession, endDevSession, resolveDevUiMode, startDevSession } from "../dev-session.js"
|
|
43
|
+
import { publishDevReady } from "../dev-ready-panel.js"
|
|
43
44
|
import { probeDockerDaemon, reportDockerUnavailable } from "../docker-runtime.js"
|
|
44
45
|
import { fatalError } from "../ui/fatal.js"
|
|
45
46
|
import { registerDevShutdown } from "../dev-shutdown.js"
|
|
47
|
+
import { ensureValkeySidecar, stopValkeySidecar } from "../valkey-sidecar.js"
|
|
46
48
|
import {
|
|
47
49
|
initdb,
|
|
48
50
|
start as pgStart,
|
|
@@ -133,7 +135,6 @@ export function registerDev(program: Command): void {
|
|
|
133
135
|
}
|
|
134
136
|
|
|
135
137
|
beginDevSession(resolveDevUiMode(opts.stream === true))
|
|
136
|
-
startDevSession()
|
|
137
138
|
if (hasMeaningfulOverrides(config)) {
|
|
138
139
|
console.warn("[supatype] Local binary overrides active:")
|
|
139
140
|
for (const line of describeActiveOverrides(config)) {
|
|
@@ -326,9 +327,13 @@ ALTER DEFAULT PRIVILEGES IN SCHEMA public GRANT ALL ON SEQUENCES TO authenticate
|
|
|
326
327
|
? "ses"
|
|
327
328
|
: "smtp"
|
|
328
329
|
|
|
330
|
+
const valkeySidecar = ensureValkeySidecar(projectName)
|
|
331
|
+
|
|
329
332
|
const serverEnv: Record<string, string> = {
|
|
330
333
|
// supatype-server outer layer
|
|
331
334
|
SUPATYPE_MODE: config.server.mode ?? "dev",
|
|
335
|
+
...(valkeySidecar.addr ? { SUPATYPE_VALKEY_ADDR: valkeySidecar.addr } : {}),
|
|
336
|
+
SUPATYPE_MANAGED_PROJECT_REF: projectName,
|
|
332
337
|
SUPATYPE_MANIFEST_PATH: manifestPath,
|
|
333
338
|
SUPATYPE_ADMIN_CONFIG_PATH: adminConfigPath,
|
|
334
339
|
SUPATYPE_POSTGREST_URL: `http://127.0.0.1:${postgrestPort}`,
|
|
@@ -471,7 +476,7 @@ ALTER DEFAULT PRIVILEGES IN SCHEMA public GRANT ALL ON SEQUENCES TO authenticate
|
|
|
471
476
|
}
|
|
472
477
|
|
|
473
478
|
// ── 9d. Studio (optional) ─────────────────────────────────────────────
|
|
474
|
-
const studioPort =
|
|
479
|
+
const studioPort = STUDIO_DEV_PORT
|
|
475
480
|
let studioProc: ProcessManager | null = null
|
|
476
481
|
|
|
477
482
|
const studioOverride = config.overrides?.studio
|
|
@@ -489,25 +494,24 @@ ALTER DEFAULT PRIVILEGES IN SCHEMA public GRANT ALL ON SEQUENCES TO authenticate
|
|
|
489
494
|
|
|
490
495
|
const appProc = startProxyDevApp(cwd, config, pidDir)
|
|
491
496
|
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
|
|
498
|
-
|
|
499
|
-
|
|
500
|
-
|
|
501
|
-
|
|
502
|
-
API keys (local dev only):
|
|
503
|
-
anon key ${anonKey}
|
|
504
|
-
service_role ${serviceRoleKey}
|
|
505
|
-
|
|
506
|
-
JWT secret: ${LOCAL_JWT_SECRET}
|
|
507
|
-
|
|
508
|
-
Press Ctrl+C to stop.
|
|
509
|
-
`)
|
|
497
|
+
const links = [
|
|
498
|
+
{ label: "API", url: `http://localhost:${serverPort}` },
|
|
499
|
+
{ label: "REST", url: `http://localhost:${serverPort}/rest/v1/` },
|
|
500
|
+
{ label: "Auth", url: `http://localhost:${serverPort}/auth/v1/` },
|
|
501
|
+
{ label: "Storage", url: `http://localhost:${serverPort}/storage/v1/` },
|
|
502
|
+
{ label: "Realtime", url: `ws://localhost:${serverPort}/realtime/v1/` },
|
|
503
|
+
]
|
|
504
|
+
if (studioProc) {
|
|
505
|
+
links.push({ label: "Studio", url: `http://localhost:${studioPort}` })
|
|
506
|
+
}
|
|
510
507
|
|
|
508
|
+
publishDevReady({
|
|
509
|
+
title: "Services running",
|
|
510
|
+
links,
|
|
511
|
+
anonKey,
|
|
512
|
+
serviceRoleKey,
|
|
513
|
+
hints: [`Postgres ${dbURL}`, `JWT secret: ${LOCAL_JWT_SECRET}`],
|
|
514
|
+
})
|
|
511
515
|
|
|
512
516
|
// ── Shutdown handler ──────────────────────────────────────────────────
|
|
513
517
|
registerDevShutdown(async () => {
|
|
@@ -518,6 +522,7 @@ ALTER DEFAULT PRIVILEGES IN SCHEMA public GRANT ALL ON SEQUENCES TO authenticate
|
|
|
518
522
|
studioProc?.stop(),
|
|
519
523
|
appProc?.stop(),
|
|
520
524
|
])
|
|
525
|
+
stopValkeySidecar(valkeySidecar.containerName)
|
|
521
526
|
await stopPostgres()
|
|
522
527
|
})
|
|
523
528
|
|
package/src/commands/init.ts
CHANGED
|
@@ -1,36 +1,25 @@
|
|
|
1
1
|
import type { Command } from "commander"
|
|
2
2
|
import { existsSync, mkdirSync, readFileSync, writeFileSync } from "node:fs"
|
|
3
|
-
import { resolve, join,
|
|
4
|
-
import { fileURLToPath } from "node:url"
|
|
3
|
+
import { resolve, join, basename } from "node:path"
|
|
5
4
|
import { spawnSync } from "node:child_process"
|
|
6
|
-
import
|
|
5
|
+
import { p, runClackFlow } from "../ui/clack.js"
|
|
7
6
|
import { ensureNotCancelled, printLogo } from "../ui/prompts.js"
|
|
8
7
|
import { generateAndWriteKeys } from "./keys.js"
|
|
9
8
|
import { file, error, info, plain, warn } from "../ui/messages.js"
|
|
10
9
|
import { nextSteps } from "../ui/next-steps.js"
|
|
11
10
|
import { probeDockerDaemon, reportDockerUnavailable } from "../docker-runtime.js"
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
)
|
|
25
|
-
|
|
26
|
-
function cliPackageVersion(): string {
|
|
27
|
-
try {
|
|
28
|
-
const pkg = JSON.parse(readFileSync(CLI_PACKAGE_JSON, "utf8")) as { version?: string }
|
|
29
|
-
return pkg.version ?? "0.1.0"
|
|
30
|
-
} catch {
|
|
31
|
-
return "0.1.0"
|
|
32
|
-
}
|
|
33
|
-
}
|
|
11
|
+
import { loadConfig } from "../config.js"
|
|
12
|
+
import {
|
|
13
|
+
ensureComponentBinaries,
|
|
14
|
+
reportComponentBinaryFailures,
|
|
15
|
+
} from "../ensure-component-binaries.js"
|
|
16
|
+
import { mergeSupatypePackageJson } from "../init-package-json.js"
|
|
17
|
+
import { cliPackageVersion } from "../cli-package-version.js"
|
|
18
|
+
import {
|
|
19
|
+
initDependencyVersionsFallback,
|
|
20
|
+
resolveInitDependencyVersions,
|
|
21
|
+
type InitDependencyVersions,
|
|
22
|
+
} from "../init-dependency-versions.js"
|
|
34
23
|
|
|
35
24
|
// ─── Options model ─────────────────────────────────────────────────────────--
|
|
36
25
|
|
|
@@ -200,9 +189,23 @@ export function registerInit(program: Command): void {
|
|
|
200
189
|
|
|
201
190
|
if (name) mkdirSync(dir, { recursive: true })
|
|
202
191
|
|
|
203
|
-
|
|
192
|
+
const deps = await resolveInitDependencyVersions()
|
|
193
|
+
const runningCli = cliPackageVersion()
|
|
194
|
+
if (deps.cli !== runningCli || deps.types !== runningCli) {
|
|
195
|
+
info(
|
|
196
|
+
`Using published npm versions: @supatype/cli ^${deps.cli}, @supatype/types ^${deps.types}`,
|
|
197
|
+
)
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
scaffold(dir, result, deps)
|
|
201
|
+
|
|
202
|
+
const installOk = doInstall ? runInstall(dir, result.packageManager) : true
|
|
203
|
+
|
|
204
|
+
const binariesReady = installOk ? await ensureInitBinaries(dir) : false
|
|
205
|
+
if (doInstall && !installOk) {
|
|
206
|
+
warn("Skipping component binary check until dependencies install successfully.")
|
|
207
|
+
}
|
|
204
208
|
|
|
205
|
-
if (doInstall) runInstall(dir, result.packageManager)
|
|
206
209
|
const keysGenerated = doKeys ? writeKeys(dir) : false
|
|
207
210
|
|
|
208
211
|
warnDockerUnavailableForProvider(result.provider)
|
|
@@ -210,8 +213,9 @@ export function registerInit(program: Command): void {
|
|
|
210
213
|
printNextSteps({
|
|
211
214
|
name,
|
|
212
215
|
result,
|
|
213
|
-
installed: doInstall,
|
|
216
|
+
installed: doInstall && installOk,
|
|
214
217
|
keysGenerated,
|
|
218
|
+
binariesReady,
|
|
215
219
|
})
|
|
216
220
|
})
|
|
217
221
|
}
|
|
@@ -222,6 +226,7 @@ async function runWizard(
|
|
|
222
226
|
defaultName: string,
|
|
223
227
|
defaultTarget: ProductionTarget,
|
|
224
228
|
): Promise<WizardResult> {
|
|
229
|
+
return runClackFlow(async () => {
|
|
225
230
|
p.intro("Create a new Supatype project")
|
|
226
231
|
|
|
227
232
|
const projectName = ensureNotCancelled(
|
|
@@ -407,6 +412,7 @@ async function runWizard(
|
|
|
407
412
|
generateKeys,
|
|
408
413
|
...(adminEmail && adminPassword ? { adminEmail, adminPassword } : {}),
|
|
409
414
|
}
|
|
415
|
+
})
|
|
410
416
|
}
|
|
411
417
|
|
|
412
418
|
async function promptApp(): Promise<ScaffoldAppOptions> {
|
|
@@ -485,7 +491,7 @@ function detectInvokingPackageManager(): PackageManager {
|
|
|
485
491
|
return "npm"
|
|
486
492
|
}
|
|
487
493
|
|
|
488
|
-
function runInstall(dir: string, pm: PackageManager):
|
|
494
|
+
function runInstall(dir: string, pm: PackageManager): boolean {
|
|
489
495
|
info(`Installing dependencies with ${pm}...`)
|
|
490
496
|
const res = spawnSync(pm, ["install"], {
|
|
491
497
|
cwd: dir,
|
|
@@ -494,6 +500,29 @@ function runInstall(dir: string, pm: PackageManager): void {
|
|
|
494
500
|
})
|
|
495
501
|
if (res.status !== 0 || res.error) {
|
|
496
502
|
warn(`Dependency install did not complete (run "${pm} install" manually).`)
|
|
503
|
+
return false
|
|
504
|
+
}
|
|
505
|
+
return true
|
|
506
|
+
}
|
|
507
|
+
|
|
508
|
+
async function ensureInitBinaries(dir: string): Promise<boolean> {
|
|
509
|
+
const previousCwd = process.cwd()
|
|
510
|
+
try {
|
|
511
|
+
process.chdir(dir)
|
|
512
|
+
const config = loadConfig(dir)
|
|
513
|
+
const result = await ensureComponentBinaries(config, dir)
|
|
514
|
+
if (!result.ok) {
|
|
515
|
+
reportComponentBinaryFailures(result.failures)
|
|
516
|
+
return false
|
|
517
|
+
}
|
|
518
|
+
return true
|
|
519
|
+
} catch (err) {
|
|
520
|
+
const message = err instanceof Error ? err.message : String(err)
|
|
521
|
+
warn(`Could not verify component binaries: ${message}`)
|
|
522
|
+
warn("Run manually from your project directory: supatype update")
|
|
523
|
+
return false
|
|
524
|
+
} finally {
|
|
525
|
+
process.chdir(previousCwd)
|
|
497
526
|
}
|
|
498
527
|
}
|
|
499
528
|
|
|
@@ -508,7 +537,11 @@ function writeKeys(dir: string): boolean {
|
|
|
508
537
|
|
|
509
538
|
// ─── Scaffold ──────────────────────────────────────────────────────────────--
|
|
510
539
|
|
|
511
|
-
function scaffold(
|
|
540
|
+
export function scaffold(
|
|
541
|
+
dir: string,
|
|
542
|
+
optsOrName: ScaffoldOptions | string,
|
|
543
|
+
deps: InitDependencyVersions = initDependencyVersionsFallback(),
|
|
544
|
+
): void {
|
|
512
545
|
const opts =
|
|
513
546
|
typeof optsOrName === "string" ? defaultScaffoldOptions(optsOrName) : optsOrName
|
|
514
547
|
const write = (rel: string, content: string) => {
|
|
@@ -520,9 +553,17 @@ function scaffold(dir: string, optsOrName: ScaffoldOptions | string): void {
|
|
|
520
553
|
|
|
521
554
|
const pkgPath = join(dir, "package.json")
|
|
522
555
|
if (!existsSync(pkgPath)) {
|
|
523
|
-
write("package.json", packageJsonTemplate(opts,
|
|
556
|
+
write("package.json", packageJsonTemplate(opts, deps))
|
|
524
557
|
} else {
|
|
525
|
-
|
|
558
|
+
try {
|
|
559
|
+
const existing = JSON.parse(readFileSync(pkgPath, "utf8")) as Record<string, unknown>
|
|
560
|
+
const merged = mergeSupatypePackageJson(existing, opts, deps)
|
|
561
|
+
writeFileSync(pkgPath, `${JSON.stringify(merged, null, 2)}\n`, "utf8")
|
|
562
|
+
file("updated", "package.json (added Supatype dependencies)")
|
|
563
|
+
} catch {
|
|
564
|
+
warn("Could not merge into package.json — add @supatype/cli and @supatype/types manually.")
|
|
565
|
+
file("skipped", "package.json (invalid JSON)")
|
|
566
|
+
}
|
|
526
567
|
}
|
|
527
568
|
|
|
528
569
|
write("supatype.config.ts", tsConfigTemplate(opts))
|
|
@@ -565,8 +606,13 @@ function scaffoldAppAssets(
|
|
|
565
606
|
|
|
566
607
|
if (opts.app.mode === "static") {
|
|
567
608
|
const staticRel = staticDirRelative(opts.app.staticDir)
|
|
609
|
+
if (opts.app.viteDevUrl && opts.productionTarget !== "later") {
|
|
610
|
+
write("dist/index.html", holding)
|
|
611
|
+
scaffoldVite(opts, write, holding)
|
|
612
|
+
return
|
|
613
|
+
}
|
|
568
614
|
write(`${staticRel}/index.html`, holding)
|
|
569
|
-
if (
|
|
615
|
+
if (opts.app.viteDevUrl) scaffoldVite(opts, write, holding)
|
|
570
616
|
return
|
|
571
617
|
}
|
|
572
618
|
|
|
@@ -609,7 +655,7 @@ function scaffoldHelloFunction(
|
|
|
609
655
|
|
|
610
656
|
// ─── Templates ───────────────────────────────────────────────────────────────
|
|
611
657
|
|
|
612
|
-
function packageJsonTemplate(opts: ScaffoldOptions,
|
|
658
|
+
function packageJsonTemplate(opts: ScaffoldOptions, deps: InitDependencyVersions): string {
|
|
613
659
|
const scripts: string[] = [
|
|
614
660
|
` "dev": "supatype dev"`,
|
|
615
661
|
` "push": "supatype push"`,
|
|
@@ -633,8 +679,8 @@ function packageJsonTemplate(opts: ScaffoldOptions, cliVersion: string): string
|
|
|
633
679
|
${scripts.join(",\n")}
|
|
634
680
|
},
|
|
635
681
|
"dependencies": {
|
|
636
|
-
"@supatype/cli": "^${
|
|
637
|
-
"@supatype/types": "^${
|
|
682
|
+
"@supatype/cli": "^${deps.cli}",
|
|
683
|
+
"@supatype/types": "^${deps.types}"
|
|
638
684
|
},
|
|
639
685
|
"devDependencies": {
|
|
640
686
|
${devDeps.join(",\n")}
|
|
@@ -701,20 +747,49 @@ function localConfigTemplate(app: ScaffoldAppOptions): string {
|
|
|
701
747
|
`const localConfig: Partial<SupatypeConfig> = {`,
|
|
702
748
|
` server: { mode: "dev" },`,
|
|
703
749
|
]
|
|
704
|
-
|
|
705
|
-
|
|
706
|
-
lines.push(
|
|
707
|
-
lines.push(` upstream: "${app.upstream ?? "http://localhost:3000"}",`)
|
|
708
|
-
lines.push(` start: "${app.start ?? "dev"}",`)
|
|
709
|
-
if (app.viteDevUrl) lines.push(` vite_dev_url: "${app.viteDevUrl}",`)
|
|
710
|
-
lines.push(` },`)
|
|
750
|
+
const localApp = localDevAppConfigLines(app)
|
|
751
|
+
if (localApp.length > 0) {
|
|
752
|
+
lines.push(...localApp)
|
|
711
753
|
}
|
|
712
754
|
lines.push(`}`, ``, `export default localConfig`, ``)
|
|
713
755
|
return lines.join("\n")
|
|
714
756
|
}
|
|
715
757
|
|
|
758
|
+
/** App block for supatype.local.config.ts (proxy + Vite during local dev). */
|
|
759
|
+
function localDevAppConfigLines(app: ScaffoldAppOptions): string[] {
|
|
760
|
+
if (app.mode === "proxy") {
|
|
761
|
+
return [
|
|
762
|
+
` app: {`,
|
|
763
|
+
` mode: "proxy",`,
|
|
764
|
+
` upstream: "${app.upstream ?? "http://localhost:3000"}",`,
|
|
765
|
+
` start: "${app.start ?? "dev"}",`,
|
|
766
|
+
...(app.viteDevUrl ? [` vite_dev_url: "${app.viteDevUrl}",`] : []),
|
|
767
|
+
` },`,
|
|
768
|
+
]
|
|
769
|
+
}
|
|
770
|
+
if (app.viteDevUrl) {
|
|
771
|
+
return [
|
|
772
|
+
` app: {`,
|
|
773
|
+
` mode: "proxy",`,
|
|
774
|
+
` upstream: "${app.viteDevUrl}",`,
|
|
775
|
+
` start: "vite",`,
|
|
776
|
+
` vite_dev_url: "${app.viteDevUrl}",`,
|
|
777
|
+
` },`,
|
|
778
|
+
]
|
|
779
|
+
}
|
|
780
|
+
return []
|
|
781
|
+
}
|
|
782
|
+
|
|
716
783
|
function appConfigLines(app: ScaffoldAppOptions, productionTarget: ProductionTarget): string[] {
|
|
717
784
|
if (app.mode === "static") {
|
|
785
|
+
if (productionTarget !== "later" && app.viteDevUrl) {
|
|
786
|
+
return [
|
|
787
|
+
` app: {`,
|
|
788
|
+
` mode: "static",`,
|
|
789
|
+
` static_dir: "./dist", // production build output`,
|
|
790
|
+
` },`,
|
|
791
|
+
]
|
|
792
|
+
}
|
|
718
793
|
const out = [
|
|
719
794
|
` app: {`,
|
|
720
795
|
` mode: "static",`,
|
|
@@ -774,7 +849,7 @@ function holdingPageTemplate(projectName: string): string {
|
|
|
774
849
|
<meta charset="UTF-8" />
|
|
775
850
|
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
|
776
851
|
<title>${name} — Supatype</title>
|
|
777
|
-
<meta name="description" content="A Supatype project. Define your types — we generate your
|
|
852
|
+
<meta name="description" content="A Supatype project. Define your types — we generate your platform." />
|
|
778
853
|
<link rel="preconnect" href="https://fonts.googleapis.com" />
|
|
779
854
|
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin />
|
|
780
855
|
<link href="https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700&display=swap" rel="stylesheet" />
|
|
@@ -909,6 +984,8 @@ export default defineConfig({
|
|
|
909
984
|
host: "127.0.0.1",
|
|
910
985
|
port: ${port},
|
|
911
986
|
strictPort: true,
|
|
987
|
+
// Docker Compose app proxy reaches the host as host.docker.internal.
|
|
988
|
+
allowedHosts: ["127.0.0.1", "localhost", "host.docker.internal"],
|
|
912
989
|
},
|
|
913
990
|
})
|
|
914
991
|
`
|
|
@@ -1185,11 +1262,13 @@ function printNextSteps(args: {
|
|
|
1185
1262
|
result: WizardResult
|
|
1186
1263
|
installed: boolean
|
|
1187
1264
|
keysGenerated: boolean
|
|
1265
|
+
binariesReady: boolean
|
|
1188
1266
|
}): void {
|
|
1189
|
-
const { name, result, installed, keysGenerated } = args
|
|
1267
|
+
const { name, result, installed, keysGenerated, binariesReady } = args
|
|
1190
1268
|
const steps: string[] = []
|
|
1191
1269
|
if (name) steps.push(`cd ${name}`)
|
|
1192
1270
|
if (!installed) steps.push(`${result.packageManager} install`)
|
|
1271
|
+
if (!binariesReady) steps.push("supatype update # download component binaries")
|
|
1193
1272
|
if (!keysGenerated) steps.push("supatype keys")
|
|
1194
1273
|
const kongHint =
|
|
1195
1274
|
result.provider === "docker" && result.kongPort !== undefined
|
|
@@ -12,7 +12,7 @@ import { targetFetch } from "../target-client.js"
|
|
|
12
12
|
import { error, info, plain } from "../ui/messages.js"
|
|
13
13
|
import { nextSteps } from "../ui/next-steps.js"
|
|
14
14
|
import { isInteractive } from "../ui/interactive.js"
|
|
15
|
-
import { ensureNotCancelled,
|
|
15
|
+
import { ensureNotCancelled, p, runClackFlow } from "../ui/prompts.js"
|
|
16
16
|
|
|
17
17
|
function resolveLinkToken(opts: {
|
|
18
18
|
token?: string
|
|
@@ -145,35 +145,36 @@ export async function runLinkAction(opts: {
|
|
|
145
145
|
let url = opts.url
|
|
146
146
|
|
|
147
147
|
if (isInteractive() && !project && !url) {
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
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,
|
|
148
|
+
await runClackFlow(async () => {
|
|
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
|
+
],
|
|
165
157
|
}),
|
|
166
|
-
)
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
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
|
+
})
|
|
177
178
|
}
|
|
178
179
|
|
|
179
180
|
const token = resolveLinkToken(opts)
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
import { existsSync } from "node:fs"
|
|
2
|
+
import { dirname, isAbsolute, join, resolve } from "node:path"
|
|
3
|
+
import { spawnSync } from "node:child_process"
|
|
4
|
+
import { VERSION_PIN_LOCAL } from "./binary-cache.js"
|
|
5
|
+
import { appendStackOutput, getActiveDevSession } from "./dev-session.js"
|
|
6
|
+
import { requireDockerDaemon } from "./docker-runtime.js"
|
|
7
|
+
import type { SupatypeProjectConfig } from "./project-config.js"
|
|
8
|
+
|
|
9
|
+
/** Docker tag for compose dev when `versions.server` is `local`. */
|
|
10
|
+
export const LOCAL_SERVER_DOCKER_IMAGE = "supatype/server:local-dev"
|
|
11
|
+
|
|
12
|
+
/** Find the server repo root (directory containing `Dockerfile`) from an overrides.server binary path. */
|
|
13
|
+
export function resolveServerSourceRoot(serverOverride: string, cwd: string): string | null {
|
|
14
|
+
const binaryPath = isAbsolute(serverOverride) ? serverOverride : resolve(cwd, serverOverride)
|
|
15
|
+
let dir = dirname(binaryPath)
|
|
16
|
+
for (let depth = 0; depth < 5; depth++) {
|
|
17
|
+
if (existsSync(join(dir, "Dockerfile"))) return dir
|
|
18
|
+
const parent = dirname(dir)
|
|
19
|
+
if (parent === dir) break
|
|
20
|
+
dir = parent
|
|
21
|
+
}
|
|
22
|
+
return null
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
/**
|
|
26
|
+
* When `versions.server` is `local`, build a Linux server image from the source tree
|
|
27
|
+
* next to `overrides.server` so compose dev matches the contributor's binary.
|
|
28
|
+
*/
|
|
29
|
+
export async function ensureLocalServerDockerImage(
|
|
30
|
+
cwd: string,
|
|
31
|
+
config: SupatypeProjectConfig,
|
|
32
|
+
brand?: { intro?: string },
|
|
33
|
+
): Promise<string | undefined> {
|
|
34
|
+
if (config.versions?.server !== VERSION_PIN_LOCAL) return undefined
|
|
35
|
+
|
|
36
|
+
const override = config.overrides?.server?.trim()
|
|
37
|
+
if (!override) return undefined
|
|
38
|
+
|
|
39
|
+
const root = resolveServerSourceRoot(override, cwd)
|
|
40
|
+
if (!root) {
|
|
41
|
+
console.warn(
|
|
42
|
+
`[supatype] ⚠ versions.server is "local" but no Dockerfile found near ${override}. ` +
|
|
43
|
+
"Compose will use the default supatype/server:latest image.",
|
|
44
|
+
)
|
|
45
|
+
return undefined
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
requireDockerDaemon(brand?.intro ? { brand: { intro: brand.intro } } : undefined)
|
|
49
|
+
const dockerfile = join(root, "Dockerfile")
|
|
50
|
+
console.log(`[supatype] Building local server Docker image from ${root}…`)
|
|
51
|
+
const result = spawnSync(
|
|
52
|
+
"docker",
|
|
53
|
+
["build", "--progress=plain", "-t", LOCAL_SERVER_DOCKER_IMAGE, "-f", dockerfile, root],
|
|
54
|
+
{ encoding: "utf8", stdio: "pipe" },
|
|
55
|
+
)
|
|
56
|
+
const tui = getActiveDevSession()?.isTui() ?? false
|
|
57
|
+
if (!tui) {
|
|
58
|
+
appendStackOutput(result.stdout, "log")
|
|
59
|
+
appendStackOutput(result.stderr, result.status === 0 ? "log" : "error")
|
|
60
|
+
} else if (result.status !== 0) {
|
|
61
|
+
appendStackOutput(result.stderr || result.stdout || "docker build failed", "error")
|
|
62
|
+
}
|
|
63
|
+
if (result.status !== 0) {
|
|
64
|
+
throw new Error(`docker build failed for local server (exit ${result.status ?? "unknown"})`)
|
|
65
|
+
}
|
|
66
|
+
console.log(`[supatype] Local server image ready: ${LOCAL_SERVER_DOCKER_IMAGE}`)
|
|
67
|
+
return LOCAL_SERVER_DOCKER_IMAGE
|
|
68
|
+
}
|