@supatype/cli 0.1.0 → 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 +121 -86
- 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 +28 -1
- package/dist/commands/admin.d.ts.map +1 -1
- package/dist/commands/admin.js +290 -112
- 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 +28 -22
- package/dist/commands/dev.js.map +1 -1
- package/dist/commands/init.d.ts +8 -4
- package/dist/commands/init.d.ts.map +1 -1
- package/dist/commands/init.js +278 -139
- 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/commands/push.js +3 -3
- package/dist/commands/push.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 +10 -0
- package/dist/compose-rename.d.ts.map +1 -0
- package/dist/compose-rename.js +64 -0
- package/dist/compose-rename.js.map +1 -0
- package/dist/dev-compose.d.ts.map +1 -1
- package/dist/dev-compose.js +138 -97
- 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 +27 -0
- package/dist/dev-ports.d.ts.map +1 -0
- package/dist/dev-ports.js +178 -0
- package/dist/dev-ports.js.map +1 -0
- 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 +25 -0
- package/dist/dev-session-lock.d.ts.map +1 -0
- package/dist/dev-session-lock.js +78 -0
- package/dist/dev-session-lock.js.map +1 -0
- 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 +20 -2
- package/dist/dev-shutdown.d.ts.map +1 -1
- package/dist/dev-shutdown.js +88 -10
- 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/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/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 +24 -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 +11 -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 +380 -137
- package/src/commands/cache.ts +105 -5
- package/src/commands/dev.ts +29 -21
- package/src/commands/init.ts +217 -46
- package/src/commands/link-helpers.ts +30 -29
- package/src/commands/push.ts +3 -3
- package/src/compose-local-server-image.ts +68 -0
- package/src/compose-rename.ts +73 -0
- package/src/dev-compose.ts +175 -96
- package/src/dev-log-bus.ts +18 -0
- package/src/dev-log-filter.ts +42 -0
- package/src/dev-ports.ts +223 -0
- package/src/dev-ready-panel.ts +63 -0
- package/src/dev-session-lock.ts +98 -0
- package/src/dev-session.ts +98 -18
- package/src/dev-shutdown.ts +114 -9
- 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/env-file.ts +37 -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 +23 -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/admin-ensure.test.ts +59 -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-ports.test.ts +41 -0
- package/tests/dev-ready-panel.test.ts +20 -0
- package/tests/dev-session-lock.test.ts +54 -0
- package/tests/dev-ui.test.ts +66 -3
- 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/dist/commands/init.js
CHANGED
|
@@ -1,27 +1,17 @@
|
|
|
1
1
|
import { existsSync, mkdirSync, readFileSync, writeFileSync } from "node:fs";
|
|
2
|
-
import { resolve, join,
|
|
3
|
-
import { fileURLToPath } from "node:url";
|
|
2
|
+
import { resolve, join, basename } from "node:path";
|
|
4
3
|
import { spawnSync } from "node:child_process";
|
|
5
|
-
import
|
|
4
|
+
import { p, runClackFlow } from "../ui/clack.js";
|
|
6
5
|
import { ensureNotCancelled, printLogo } from "../ui/prompts.js";
|
|
7
6
|
import { generateAndWriteKeys } from "./keys.js";
|
|
8
7
|
import { file, error, info, plain, warn } from "../ui/messages.js";
|
|
9
8
|
import { nextSteps } from "../ui/next-steps.js";
|
|
10
9
|
import { probeDockerDaemon, reportDockerUnavailable } from "../docker-runtime.js";
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
function cliPackageVersion() {
|
|
17
|
-
try {
|
|
18
|
-
const pkg = JSON.parse(readFileSync(CLI_PACKAGE_JSON, "utf8"));
|
|
19
|
-
return pkg.version ?? "0.1.0";
|
|
20
|
-
}
|
|
21
|
-
catch {
|
|
22
|
-
return "0.1.0";
|
|
23
|
-
}
|
|
24
|
-
}
|
|
10
|
+
import { loadConfig } from "../config.js";
|
|
11
|
+
import { ensureComponentBinaries, reportComponentBinaryFailures, } from "../ensure-component-binaries.js";
|
|
12
|
+
import { mergeSupatypePackageJson } from "../init-package-json.js";
|
|
13
|
+
import { cliPackageVersion } from "../cli-package-version.js";
|
|
14
|
+
import { initDependencyVersionsFallback, resolveInitDependencyVersions, } from "../init-dependency-versions.js";
|
|
25
15
|
const STORAGE_PROVIDER_OPTIONS = [
|
|
26
16
|
{ value: "local", label: "Local", hint: "storage you host yourself (MinIO)" },
|
|
27
17
|
{ value: "s3", label: "S3", hint: "external bucket (AWS S3 or compatible)" },
|
|
@@ -63,6 +53,9 @@ export function registerInit(program) {
|
|
|
63
53
|
.option("-y, --defaults", "Skip all prompts and use sensible defaults")
|
|
64
54
|
.option("--no-install", "Do not run the package manager install step")
|
|
65
55
|
.option("--no-keys", "Do not generate ANON_KEY / SERVICE_ROLE_KEY")
|
|
56
|
+
.option("--admin-email <email>", "First admin panel user email (written to .env)")
|
|
57
|
+
.option("--admin-password <password>", "First admin panel user password (written to .env)")
|
|
58
|
+
.option("--no-admin", "Do not configure a first admin user")
|
|
66
59
|
.action(async (name, opts) => {
|
|
67
60
|
const dir = name ? resolve(process.cwd(), name) : process.cwd();
|
|
68
61
|
if (name && existsSync(dir)) {
|
|
@@ -84,132 +77,191 @@ export function registerInit(program) {
|
|
|
84
77
|
install: true,
|
|
85
78
|
generateKeys: true,
|
|
86
79
|
};
|
|
80
|
+
if (result.provider === "docker") {
|
|
81
|
+
const { findNextFreePort } = await import("../dev-ports.js");
|
|
82
|
+
const { COMPOSE_DEV_KONG_PORT } = await import("../project-config.js");
|
|
83
|
+
result.kongPort = await findNextFreePort(COMPOSE_DEV_KONG_PORT);
|
|
84
|
+
}
|
|
85
|
+
if (!opts.admin && opts.adminEmail && opts.adminPassword) {
|
|
86
|
+
result.adminEmail = opts.adminEmail;
|
|
87
|
+
result.adminPassword = opts.adminPassword;
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
if (opts.admin === false) {
|
|
91
|
+
delete result.adminEmail;
|
|
92
|
+
delete result.adminPassword;
|
|
93
|
+
}
|
|
94
|
+
else if (opts.adminEmail && opts.adminPassword) {
|
|
95
|
+
result.adminEmail = opts.adminEmail;
|
|
96
|
+
result.adminPassword = opts.adminPassword;
|
|
87
97
|
}
|
|
88
98
|
// CLI flags override wizard / default action choices.
|
|
89
99
|
const doInstall = opts.install !== false && result.install;
|
|
90
100
|
const doKeys = opts.keys !== false && result.generateKeys;
|
|
91
101
|
if (name)
|
|
92
102
|
mkdirSync(dir, { recursive: true });
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
103
|
+
const deps = await resolveInitDependencyVersions();
|
|
104
|
+
const runningCli = cliPackageVersion();
|
|
105
|
+
if (deps.cli !== runningCli || deps.types !== runningCli) {
|
|
106
|
+
info(`Using published npm versions: @supatype/cli ^${deps.cli}, @supatype/types ^${deps.types}`);
|
|
107
|
+
}
|
|
108
|
+
scaffold(dir, result, deps);
|
|
109
|
+
const installOk = doInstall ? runInstall(dir, result.packageManager) : true;
|
|
110
|
+
const binariesReady = installOk ? await ensureInitBinaries(dir) : false;
|
|
111
|
+
if (doInstall && !installOk) {
|
|
112
|
+
warn("Skipping component binary check until dependencies install successfully.");
|
|
113
|
+
}
|
|
96
114
|
const keysGenerated = doKeys ? writeKeys(dir) : false;
|
|
97
115
|
warnDockerUnavailableForProvider(result.provider);
|
|
98
116
|
printNextSteps({
|
|
99
117
|
name,
|
|
100
118
|
result,
|
|
101
|
-
installed: doInstall,
|
|
119
|
+
installed: doInstall && installOk,
|
|
102
120
|
keysGenerated,
|
|
121
|
+
binariesReady,
|
|
103
122
|
});
|
|
104
123
|
});
|
|
105
124
|
}
|
|
106
125
|
// ─── Wizard ──────────────────────────────────────────────────────────────────
|
|
107
126
|
async function runWizard(defaultName, defaultTarget) {
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
127
|
+
return runClackFlow(async () => {
|
|
128
|
+
p.intro("Create a new Supatype project");
|
|
129
|
+
const projectName = ensureNotCancelled(await p.text({
|
|
130
|
+
message: "Project name",
|
|
131
|
+
defaultValue: defaultName,
|
|
132
|
+
placeholder: defaultName,
|
|
133
|
+
})).trim() || defaultName;
|
|
134
|
+
const packageManager = ensureNotCancelled(await p.select({
|
|
135
|
+
message: "Package manager",
|
|
136
|
+
initialValue: detectInvokingPackageManager(),
|
|
137
|
+
options: [
|
|
138
|
+
{ value: "npm", label: "npm" },
|
|
139
|
+
{ value: "pnpm", label: "pnpm" },
|
|
140
|
+
{ value: "yarn", label: "yarn" },
|
|
141
|
+
{ value: "bun", label: "bun" },
|
|
142
|
+
],
|
|
143
|
+
}));
|
|
144
|
+
const productionTarget = ensureNotCancelled(await p.select({
|
|
145
|
+
message: "Where will this run in production?",
|
|
146
|
+
initialValue: defaultTarget,
|
|
147
|
+
options: [
|
|
148
|
+
{ value: "cloud", label: "Supatype Cloud", hint: "managed; deploy via supatype link" },
|
|
149
|
+
{ value: "self-host", label: "Self-host", hint: "your own server with TLS" },
|
|
150
|
+
{ value: "later", label: "Decide later", hint: "local development only for now" },
|
|
151
|
+
],
|
|
152
|
+
}));
|
|
153
|
+
let domain;
|
|
154
|
+
let tlsEmail;
|
|
155
|
+
if (productionTarget === "self-host") {
|
|
156
|
+
domain = ensureNotCancelled(await p.text({
|
|
157
|
+
message: "Production domain for ACME TLS (optional, can set later)",
|
|
158
|
+
placeholder: "api.example.com",
|
|
159
|
+
defaultValue: "",
|
|
160
|
+
})).trim();
|
|
161
|
+
if (domain) {
|
|
162
|
+
tlsEmail =
|
|
163
|
+
ensureNotCancelled(await p.text({
|
|
164
|
+
message: "Email for Let's Encrypt (HTTPS) certificates",
|
|
165
|
+
placeholder: "you@example.com",
|
|
166
|
+
defaultValue: "",
|
|
167
|
+
})).trim() || undefined;
|
|
168
|
+
}
|
|
169
|
+
}
|
|
170
|
+
const provider = ensureNotCancelled(await p.select({
|
|
171
|
+
message: "How should Postgres and the server run for local development?",
|
|
172
|
+
initialValue: "docker",
|
|
173
|
+
options: [
|
|
174
|
+
{ value: "docker", label: "Docker", hint: "Docker Compose stack (recommended)" },
|
|
175
|
+
{ value: "native", label: "Native", hint: "host Postgres + server binaries, no Docker" },
|
|
176
|
+
],
|
|
177
|
+
}));
|
|
178
|
+
let kongPort;
|
|
179
|
+
if (provider === "docker") {
|
|
180
|
+
const { promptKongPortChoice } = await import("../dev-ports.js");
|
|
181
|
+
kongPort = await promptKongPortChoice();
|
|
182
|
+
}
|
|
183
|
+
const schemaPath = ensureNotCancelled(await p.text({
|
|
184
|
+
message: "Where should your schema live?",
|
|
185
|
+
defaultValue: "schema/index.ts",
|
|
186
|
+
placeholder: "schema/index.ts",
|
|
187
|
+
})).trim() || "schema/index.ts";
|
|
188
|
+
const app = await promptApp();
|
|
189
|
+
const email = ensureNotCancelled(await p.select({
|
|
190
|
+
message: "Email provider",
|
|
191
|
+
initialValue: "console",
|
|
192
|
+
options: [
|
|
193
|
+
{ value: "console", label: "console", hint: "log emails to the terminal (dev)" },
|
|
194
|
+
{ value: "smtp", label: "SMTP" },
|
|
195
|
+
{ value: "resend", label: "Resend" },
|
|
196
|
+
{ value: "ses", label: "Amazon SES" },
|
|
197
|
+
],
|
|
198
|
+
}));
|
|
199
|
+
const storageLocal = ensureNotCancelled(await p.select({
|
|
200
|
+
message: "Local storage (for development)?",
|
|
201
|
+
initialValue: "local",
|
|
202
|
+
options: STORAGE_PROVIDER_OPTIONS,
|
|
203
|
+
}));
|
|
204
|
+
const storageProduction = ensureNotCancelled(await p.select({
|
|
205
|
+
message: "Production storage?",
|
|
206
|
+
initialValue: "local",
|
|
207
|
+
options: STORAGE_PROVIDER_OPTIONS,
|
|
208
|
+
}));
|
|
209
|
+
const helloFunction = ensureNotCancelled(await p.confirm({
|
|
210
|
+
message: "Create a hello-world edge function?",
|
|
211
|
+
initialValue: false,
|
|
212
|
+
}));
|
|
213
|
+
const install = ensureNotCancelled(await p.confirm({
|
|
214
|
+
message: `Install dependencies with ${packageManager} now?`,
|
|
215
|
+
initialValue: true,
|
|
216
|
+
}));
|
|
217
|
+
const generateKeys = ensureNotCancelled(await p.confirm({
|
|
218
|
+
message: "Generate ANON_KEY and SERVICE_ROLE_KEY now?",
|
|
219
|
+
initialValue: true,
|
|
220
|
+
}));
|
|
221
|
+
let adminEmail;
|
|
222
|
+
let adminPassword;
|
|
223
|
+
const createAdmin = ensureNotCancelled(await p.confirm({
|
|
224
|
+
message: "Create an admin user for /admin?",
|
|
225
|
+
initialValue: true,
|
|
226
|
+
}));
|
|
227
|
+
if (createAdmin) {
|
|
228
|
+
adminEmail =
|
|
143
229
|
ensureNotCancelled(await p.text({
|
|
144
|
-
message: "
|
|
230
|
+
message: "Admin email",
|
|
145
231
|
placeholder: "you@example.com",
|
|
146
232
|
defaultValue: "",
|
|
147
233
|
})).trim() || undefined;
|
|
234
|
+
if (adminEmail) {
|
|
235
|
+
adminPassword =
|
|
236
|
+
ensureNotCancelled(await p.text({
|
|
237
|
+
message: "Admin password (min 8 chars)",
|
|
238
|
+
defaultValue: "",
|
|
239
|
+
})).trim() || undefined;
|
|
240
|
+
if (adminPassword && adminPassword.length < 8) {
|
|
241
|
+
adminPassword = undefined;
|
|
242
|
+
}
|
|
243
|
+
}
|
|
148
244
|
}
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
{ value: "smtp", label: "SMTP" },
|
|
170
|
-
{ value: "resend", label: "Resend" },
|
|
171
|
-
{ value: "ses", label: "Amazon SES" },
|
|
172
|
-
],
|
|
173
|
-
}));
|
|
174
|
-
const storageLocal = ensureNotCancelled(await p.select({
|
|
175
|
-
message: "Local storage (for development)?",
|
|
176
|
-
initialValue: "local",
|
|
177
|
-
options: STORAGE_PROVIDER_OPTIONS,
|
|
178
|
-
}));
|
|
179
|
-
const storageProduction = ensureNotCancelled(await p.select({
|
|
180
|
-
message: "Production storage?",
|
|
181
|
-
initialValue: "local",
|
|
182
|
-
options: STORAGE_PROVIDER_OPTIONS,
|
|
183
|
-
}));
|
|
184
|
-
const helloFunction = ensureNotCancelled(await p.confirm({
|
|
185
|
-
message: "Create a hello-world edge function?",
|
|
186
|
-
initialValue: false,
|
|
187
|
-
}));
|
|
188
|
-
const install = ensureNotCancelled(await p.confirm({
|
|
189
|
-
message: `Install dependencies with ${packageManager} now?`,
|
|
190
|
-
initialValue: true,
|
|
191
|
-
}));
|
|
192
|
-
const generateKeys = ensureNotCancelled(await p.confirm({
|
|
193
|
-
message: "Generate ANON_KEY and SERVICE_ROLE_KEY now?",
|
|
194
|
-
initialValue: true,
|
|
195
|
-
}));
|
|
196
|
-
p.outro("Setting up your project...");
|
|
197
|
-
return {
|
|
198
|
-
projectName,
|
|
199
|
-
provider,
|
|
200
|
-
productionTarget,
|
|
201
|
-
...(domain !== undefined ? { domain } : {}),
|
|
202
|
-
...(tlsEmail !== undefined ? { tlsEmail } : {}),
|
|
203
|
-
schemaPath,
|
|
204
|
-
app,
|
|
205
|
-
email,
|
|
206
|
-
storageLocal,
|
|
207
|
-
storageProduction,
|
|
208
|
-
helloFunction,
|
|
209
|
-
packageManager,
|
|
210
|
-
install,
|
|
211
|
-
generateKeys,
|
|
212
|
-
};
|
|
245
|
+
p.outro("Setting up your project...");
|
|
246
|
+
return {
|
|
247
|
+
projectName,
|
|
248
|
+
provider,
|
|
249
|
+
...(kongPort !== undefined ? { kongPort } : {}),
|
|
250
|
+
productionTarget,
|
|
251
|
+
...(domain !== undefined ? { domain } : {}),
|
|
252
|
+
...(tlsEmail !== undefined ? { tlsEmail } : {}),
|
|
253
|
+
schemaPath,
|
|
254
|
+
app,
|
|
255
|
+
email,
|
|
256
|
+
storageLocal,
|
|
257
|
+
storageProduction,
|
|
258
|
+
helloFunction,
|
|
259
|
+
packageManager,
|
|
260
|
+
install,
|
|
261
|
+
generateKeys,
|
|
262
|
+
...(adminEmail && adminPassword ? { adminEmail, adminPassword } : {}),
|
|
263
|
+
};
|
|
264
|
+
});
|
|
213
265
|
}
|
|
214
266
|
async function promptApp() {
|
|
215
267
|
const mode = ensureNotCancelled(await p.select({
|
|
@@ -279,6 +331,30 @@ function runInstall(dir, pm) {
|
|
|
279
331
|
});
|
|
280
332
|
if (res.status !== 0 || res.error) {
|
|
281
333
|
warn(`Dependency install did not complete (run "${pm} install" manually).`);
|
|
334
|
+
return false;
|
|
335
|
+
}
|
|
336
|
+
return true;
|
|
337
|
+
}
|
|
338
|
+
async function ensureInitBinaries(dir) {
|
|
339
|
+
const previousCwd = process.cwd();
|
|
340
|
+
try {
|
|
341
|
+
process.chdir(dir);
|
|
342
|
+
const config = loadConfig(dir);
|
|
343
|
+
const result = await ensureComponentBinaries(config, dir);
|
|
344
|
+
if (!result.ok) {
|
|
345
|
+
reportComponentBinaryFailures(result.failures);
|
|
346
|
+
return false;
|
|
347
|
+
}
|
|
348
|
+
return true;
|
|
349
|
+
}
|
|
350
|
+
catch (err) {
|
|
351
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
352
|
+
warn(`Could not verify component binaries: ${message}`);
|
|
353
|
+
warn("Run manually from your project directory: supatype update");
|
|
354
|
+
return false;
|
|
355
|
+
}
|
|
356
|
+
finally {
|
|
357
|
+
process.chdir(previousCwd);
|
|
282
358
|
}
|
|
283
359
|
}
|
|
284
360
|
function writeKeys(dir) {
|
|
@@ -290,7 +366,7 @@ function writeKeys(dir) {
|
|
|
290
366
|
return true;
|
|
291
367
|
}
|
|
292
368
|
// ─── Scaffold ──────────────────────────────────────────────────────────────--
|
|
293
|
-
function scaffold(dir, optsOrName) {
|
|
369
|
+
export function scaffold(dir, optsOrName, deps = initDependencyVersionsFallback()) {
|
|
294
370
|
const opts = typeof optsOrName === "string" ? defaultScaffoldOptions(optsOrName) : optsOrName;
|
|
295
371
|
const write = (rel, content) => {
|
|
296
372
|
const full = join(dir, rel);
|
|
@@ -300,10 +376,19 @@ function scaffold(dir, optsOrName) {
|
|
|
300
376
|
};
|
|
301
377
|
const pkgPath = join(dir, "package.json");
|
|
302
378
|
if (!existsSync(pkgPath)) {
|
|
303
|
-
write("package.json", packageJsonTemplate(opts,
|
|
379
|
+
write("package.json", packageJsonTemplate(opts, deps));
|
|
304
380
|
}
|
|
305
381
|
else {
|
|
306
|
-
|
|
382
|
+
try {
|
|
383
|
+
const existing = JSON.parse(readFileSync(pkgPath, "utf8"));
|
|
384
|
+
const merged = mergeSupatypePackageJson(existing, opts, deps);
|
|
385
|
+
writeFileSync(pkgPath, `${JSON.stringify(merged, null, 2)}\n`, "utf8");
|
|
386
|
+
file("updated", "package.json (added Supatype dependencies)");
|
|
387
|
+
}
|
|
388
|
+
catch {
|
|
389
|
+
warn("Could not merge into package.json — add @supatype/cli and @supatype/types manually.");
|
|
390
|
+
file("skipped", "package.json (invalid JSON)");
|
|
391
|
+
}
|
|
307
392
|
}
|
|
308
393
|
write("supatype.config.ts", tsConfigTemplate(opts));
|
|
309
394
|
if (opts.productionTarget !== "later") {
|
|
@@ -340,8 +425,13 @@ function scaffoldAppAssets(opts, write) {
|
|
|
340
425
|
const hasVite = Boolean(opts.app.viteDevUrl);
|
|
341
426
|
if (opts.app.mode === "static") {
|
|
342
427
|
const staticRel = staticDirRelative(opts.app.staticDir);
|
|
428
|
+
if (opts.app.viteDevUrl && opts.productionTarget !== "later") {
|
|
429
|
+
write("dist/index.html", holding);
|
|
430
|
+
scaffoldVite(opts, write, holding);
|
|
431
|
+
return;
|
|
432
|
+
}
|
|
343
433
|
write(`${staticRel}/index.html`, holding);
|
|
344
|
-
if (
|
|
434
|
+
if (opts.app.viteDevUrl)
|
|
345
435
|
scaffoldVite(opts, write, holding);
|
|
346
436
|
return;
|
|
347
437
|
}
|
|
@@ -373,7 +463,7 @@ function scaffoldHelloFunction(dir, write) {
|
|
|
373
463
|
}
|
|
374
464
|
}
|
|
375
465
|
// ─── Templates ───────────────────────────────────────────────────────────────
|
|
376
|
-
function packageJsonTemplate(opts,
|
|
466
|
+
function packageJsonTemplate(opts, deps) {
|
|
377
467
|
const scripts = [
|
|
378
468
|
` "dev": "supatype dev"`,
|
|
379
469
|
` "push": "supatype push"`,
|
|
@@ -397,8 +487,8 @@ function packageJsonTemplate(opts, cliVersion) {
|
|
|
397
487
|
${scripts.join(",\n")}
|
|
398
488
|
},
|
|
399
489
|
"dependencies": {
|
|
400
|
-
"@supatype/cli": "^${
|
|
401
|
-
"@supatype/types": "^${
|
|
490
|
+
"@supatype/cli": "^${deps.cli}",
|
|
491
|
+
"@supatype/types": "^${deps.types}"
|
|
402
492
|
},
|
|
403
493
|
"devDependencies": {
|
|
404
494
|
${devDeps.join(",\n")}
|
|
@@ -460,20 +550,47 @@ function localConfigTemplate(app) {
|
|
|
460
550
|
`const localConfig: Partial<SupatypeConfig> = {`,
|
|
461
551
|
` server: { mode: "dev" },`,
|
|
462
552
|
];
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
lines.push(
|
|
466
|
-
lines.push(` upstream: "${app.upstream ?? "http://localhost:3000"}",`);
|
|
467
|
-
lines.push(` start: "${app.start ?? "dev"}",`);
|
|
468
|
-
if (app.viteDevUrl)
|
|
469
|
-
lines.push(` vite_dev_url: "${app.viteDevUrl}",`);
|
|
470
|
-
lines.push(` },`);
|
|
553
|
+
const localApp = localDevAppConfigLines(app);
|
|
554
|
+
if (localApp.length > 0) {
|
|
555
|
+
lines.push(...localApp);
|
|
471
556
|
}
|
|
472
557
|
lines.push(`}`, ``, `export default localConfig`, ``);
|
|
473
558
|
return lines.join("\n");
|
|
474
559
|
}
|
|
560
|
+
/** App block for supatype.local.config.ts (proxy + Vite during local dev). */
|
|
561
|
+
function localDevAppConfigLines(app) {
|
|
562
|
+
if (app.mode === "proxy") {
|
|
563
|
+
return [
|
|
564
|
+
` app: {`,
|
|
565
|
+
` mode: "proxy",`,
|
|
566
|
+
` upstream: "${app.upstream ?? "http://localhost:3000"}",`,
|
|
567
|
+
` start: "${app.start ?? "dev"}",`,
|
|
568
|
+
...(app.viteDevUrl ? [` vite_dev_url: "${app.viteDevUrl}",`] : []),
|
|
569
|
+
` },`,
|
|
570
|
+
];
|
|
571
|
+
}
|
|
572
|
+
if (app.viteDevUrl) {
|
|
573
|
+
return [
|
|
574
|
+
` app: {`,
|
|
575
|
+
` mode: "proxy",`,
|
|
576
|
+
` upstream: "${app.viteDevUrl}",`,
|
|
577
|
+
` start: "vite",`,
|
|
578
|
+
` vite_dev_url: "${app.viteDevUrl}",`,
|
|
579
|
+
` },`,
|
|
580
|
+
];
|
|
581
|
+
}
|
|
582
|
+
return [];
|
|
583
|
+
}
|
|
475
584
|
function appConfigLines(app, productionTarget) {
|
|
476
585
|
if (app.mode === "static") {
|
|
586
|
+
if (productionTarget !== "later" && app.viteDevUrl) {
|
|
587
|
+
return [
|
|
588
|
+
` app: {`,
|
|
589
|
+
` mode: "static",`,
|
|
590
|
+
` static_dir: "./dist", // production build output`,
|
|
591
|
+
` },`,
|
|
592
|
+
];
|
|
593
|
+
}
|
|
477
594
|
const out = [
|
|
478
595
|
` app: {`,
|
|
479
596
|
` mode: "static",`,
|
|
@@ -532,7 +649,7 @@ function holdingPageTemplate(projectName) {
|
|
|
532
649
|
<meta charset="UTF-8" />
|
|
533
650
|
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
|
534
651
|
<title>${name} — Supatype</title>
|
|
535
|
-
<meta name="description" content="A Supatype project. Define your types — we generate your
|
|
652
|
+
<meta name="description" content="A Supatype project. Define your types — we generate your platform." />
|
|
536
653
|
<link rel="preconnect" href="https://fonts.googleapis.com" />
|
|
537
654
|
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin />
|
|
538
655
|
<link href="https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700&display=swap" rel="stylesheet" />
|
|
@@ -667,6 +784,8 @@ export default defineConfig({
|
|
|
667
784
|
host: "127.0.0.1",
|
|
668
785
|
port: ${port},
|
|
669
786
|
strictPort: true,
|
|
787
|
+
// Docker Compose app proxy reaches the host as host.docker.internal.
|
|
788
|
+
allowedHosts: ["127.0.0.1", "localhost", "host.docker.internal"],
|
|
670
789
|
},
|
|
671
790
|
})
|
|
672
791
|
`;
|
|
@@ -728,8 +847,20 @@ ANON_KEY=
|
|
|
728
847
|
SERVICE_ROLE_KEY=`);
|
|
729
848
|
sections.push(`# Site URL (used by GoTrue for email redirects)
|
|
730
849
|
SITE_URL=http://localhost:3000`);
|
|
850
|
+
if (opts.provider === "docker" && opts.kongPort !== undefined) {
|
|
851
|
+
const apiUrl = `http://localhost:${opts.kongPort}`;
|
|
852
|
+
sections.push(`# Local API gateway (Kong) — unique per project so multiple stacks can run concurrently
|
|
853
|
+
SUPATYPE_KONG_PORT=${opts.kongPort}
|
|
854
|
+
PUBLIC_SUPATYPE_URL=${apiUrl}
|
|
855
|
+
API_EXTERNAL_URL=${apiUrl}`);
|
|
856
|
+
}
|
|
731
857
|
sections.push(emailEnvSection(opts.email, opts.projectName));
|
|
732
858
|
sections.push(storageEnvSections(opts.storageLocal, opts.storageProduction));
|
|
859
|
+
if (opts.adminEmail && opts.adminPassword) {
|
|
860
|
+
sections.push(`# First admin for /admin — consumed on first supatype dev or push (password removed after use)
|
|
861
|
+
SUPATYPE_ADMIN_EMAIL=${opts.adminEmail}
|
|
862
|
+
SUPATYPE_ADMIN_PASSWORD=${opts.adminPassword}`);
|
|
863
|
+
}
|
|
733
864
|
sections.push(`# Self-host compose uses the same DATABASE_URL when Postgres is published on localhost:5432`);
|
|
734
865
|
return sections.join("\n\n") + "\n";
|
|
735
866
|
}
|
|
@@ -893,16 +1024,24 @@ function warnDockerUnavailableForProvider(provider) {
|
|
|
893
1024
|
plain();
|
|
894
1025
|
}
|
|
895
1026
|
function printNextSteps(args) {
|
|
896
|
-
const { name, result, installed, keysGenerated } = args;
|
|
1027
|
+
const { name, result, installed, keysGenerated, binariesReady } = args;
|
|
897
1028
|
const steps = [];
|
|
898
1029
|
if (name)
|
|
899
1030
|
steps.push(`cd ${name}`);
|
|
900
1031
|
if (!installed)
|
|
901
1032
|
steps.push(`${result.packageManager} install`);
|
|
1033
|
+
if (!binariesReady)
|
|
1034
|
+
steps.push("supatype update # download component binaries");
|
|
902
1035
|
if (!keysGenerated)
|
|
903
1036
|
steps.push("supatype keys");
|
|
904
|
-
|
|
1037
|
+
const kongHint = result.provider === "docker" && result.kongPort !== undefined
|
|
1038
|
+
? `supatype dev # Docker Compose stack (Kong :${result.kongPort})`
|
|
1039
|
+
: "supatype dev # Docker Compose stack (Kong :18473)";
|
|
1040
|
+
steps.push(kongHint);
|
|
905
1041
|
steps.push("supatype push # apply schema + generate types");
|
|
1042
|
+
if (result.adminEmail) {
|
|
1043
|
+
steps.push(" # first admin user is created on dev or push");
|
|
1044
|
+
}
|
|
906
1045
|
if (result.helloFunction) {
|
|
907
1046
|
steps.push("supatype functions serve # run edge functions locally");
|
|
908
1047
|
}
|