@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
|
@@ -6,7 +6,11 @@ import { loadConfig } from "../config.js";
|
|
|
6
6
|
import { ensureBinary } from "../ensure-binary.js";
|
|
7
7
|
import { functionsPathCandidatesFromProject, preferredFunctionsPathFromProject, } from "../project-config.js";
|
|
8
8
|
import { discoverTsFunctionsInDir, generateFunctionsRouterSource, } from "../functions-router-gen.js";
|
|
9
|
-
import {
|
|
9
|
+
import { loadProjectLink } from "../link.js";
|
|
10
|
+
import { resolveTarget } from "../resolve-target.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";
|
|
10
14
|
// ─── Constants ───────────────────────────────────────────────────────────────
|
|
11
15
|
const SHARED_DIR = "_shared";
|
|
12
16
|
const ENV_LOCAL = ".env.local";
|
|
@@ -34,6 +38,7 @@ export function registerFunctions(program) {
|
|
|
34
38
|
.command("deploy")
|
|
35
39
|
.description("Deploy all functions (or --only <name> for one) to the linked project")
|
|
36
40
|
.option("--only <name>", "Deploy a single function")
|
|
41
|
+
.option("--env <name>", "Target environment when linked")
|
|
37
42
|
.option("--dry-run", "Show what would be deployed without deploying")
|
|
38
43
|
.action(async (opts) => {
|
|
39
44
|
await deploy(process.cwd(), opts);
|
|
@@ -93,7 +98,7 @@ function scaffoldFunction(cwd, name) {
|
|
|
93
98
|
const functionsDir = resolveFunctionsDir(cwd, "write");
|
|
94
99
|
const fnDir = resolve(functionsDir, name);
|
|
95
100
|
if (existsSync(fnDir)) {
|
|
96
|
-
|
|
101
|
+
error(`Function "${name}" already exists at ${relative(cwd, fnDir)}`);
|
|
97
102
|
process.exit(1);
|
|
98
103
|
}
|
|
99
104
|
mkdirSync(fnDir, { recursive: true });
|
|
@@ -131,11 +136,12 @@ export default async function handler(req: Request): Promise<Response> {
|
|
|
131
136
|
writeFileSync(envLocalPath, "# Local environment variables for edge functions\n# These are NOT committed to git\n# Set production env vars via: npx supatype functions env set KEY=value\n", "utf8");
|
|
132
137
|
}
|
|
133
138
|
const functionsDirLabel = relativeFunctionsDir(cwd, functionsDir);
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
+
info(`Created function: ${functionsDirLabel}/${name}/index.ts`);
|
|
140
|
+
nextSteps("Next steps:", [
|
|
141
|
+
"Local dev: npx supatype functions serve",
|
|
142
|
+
`Invoke: npx supatype functions invoke ${name}`,
|
|
143
|
+
"Deploy: npx supatype functions deploy",
|
|
144
|
+
]);
|
|
139
145
|
}
|
|
140
146
|
function resolveFunctionsDir(cwd, mode) {
|
|
141
147
|
try {
|
|
@@ -199,15 +205,15 @@ async function serve(cwd, opts) {
|
|
|
199
205
|
const functionsDirLabel = relativeFunctionsDir(cwd, functionsDir);
|
|
200
206
|
const routes = discoverTsFunctionsInDir(functionsDir);
|
|
201
207
|
if (routes.length === 0) {
|
|
202
|
-
|
|
203
|
-
|
|
208
|
+
error(`No functions found in ${functionsDirLabel}/`);
|
|
209
|
+
error("Create one with: npx supatype functions new <name>");
|
|
204
210
|
process.exit(1);
|
|
205
211
|
}
|
|
206
|
-
|
|
212
|
+
plain(`Discovered ${routes.length} function(s):`);
|
|
207
213
|
for (const fn of routes) {
|
|
208
|
-
|
|
214
|
+
plain(` /${fn.name} → ${relative(cwd, fn.entrypoint)}`);
|
|
209
215
|
}
|
|
210
|
-
|
|
216
|
+
plain();
|
|
211
217
|
// Generate a Deno entry script that routes requests to the correct function
|
|
212
218
|
const routerPath = resolve(functionsDir, ".serve-router.ts");
|
|
213
219
|
const routerScript = generateFunctionsRouterSource(routerPath, routes);
|
|
@@ -217,14 +223,15 @@ async function serve(cwd, opts) {
|
|
|
217
223
|
if (existsSync(envFilePath)) {
|
|
218
224
|
envArgs.push("--env-file", envFilePath);
|
|
219
225
|
}
|
|
220
|
-
|
|
221
|
-
|
|
226
|
+
info(`Serving functions at http://localhost:${opts.port}/functions/v1/`);
|
|
227
|
+
info("Watching for changes...");
|
|
228
|
+
plain();
|
|
222
229
|
let denoBin;
|
|
223
230
|
try {
|
|
224
231
|
denoBin = await ensureBinary("deno", config);
|
|
225
232
|
}
|
|
226
233
|
catch (err) {
|
|
227
|
-
|
|
234
|
+
error(`Could not provision Deno: ${err.message}`);
|
|
228
235
|
process.exit(1);
|
|
229
236
|
}
|
|
230
237
|
const result = spawnSync(denoBin, [
|
|
@@ -254,7 +261,7 @@ async function serve(cwd, opts) {
|
|
|
254
261
|
}
|
|
255
262
|
catch { /* ignore */ }
|
|
256
263
|
if (result.status !== 0) {
|
|
257
|
-
|
|
264
|
+
error("Function server exited with errors.");
|
|
258
265
|
process.exit(result.status ?? 1);
|
|
259
266
|
}
|
|
260
267
|
}
|
|
@@ -268,53 +275,99 @@ async function deploy(cwd, opts) {
|
|
|
268
275
|
const functionsDir = resolveFunctionsDir(cwd, "read");
|
|
269
276
|
const functionsDirLabel = relativeFunctionsDir(cwd, functionsDir);
|
|
270
277
|
if (opts.only) {
|
|
271
|
-
|
|
278
|
+
error(`Function "${opts.only}" not found in ${functionsDirLabel}/`);
|
|
272
279
|
}
|
|
273
280
|
else {
|
|
274
|
-
|
|
281
|
+
error(`No functions found in ${functionsDirLabel}/`);
|
|
275
282
|
}
|
|
276
283
|
process.exit(1);
|
|
277
284
|
}
|
|
278
285
|
if (opts.dryRun) {
|
|
279
|
-
|
|
286
|
+
plain("Dry run — the following functions would be deployed:\n");
|
|
280
287
|
for (const fn of fns) {
|
|
281
|
-
|
|
288
|
+
plain(` ${fn.name} → ${relative(cwd, fn.entrypoint)}`);
|
|
282
289
|
}
|
|
283
|
-
|
|
290
|
+
plain(`\nTotal: ${fns.length} function(s)`);
|
|
284
291
|
return;
|
|
285
292
|
}
|
|
293
|
+
const link = loadProjectLink(cwd);
|
|
294
|
+
if (link) {
|
|
295
|
+
try {
|
|
296
|
+
const target = resolveTarget(cwd, { env: opts.env });
|
|
297
|
+
if (target.mode !== "direct" && target.token) {
|
|
298
|
+
await deployViaTarget(cwd, target, fns);
|
|
299
|
+
return;
|
|
300
|
+
}
|
|
301
|
+
}
|
|
302
|
+
catch {
|
|
303
|
+
/* fall through to compose/local */
|
|
304
|
+
}
|
|
305
|
+
}
|
|
306
|
+
const { selfHostComposePaths } = await import("../self-host-compose.js");
|
|
286
307
|
const composePath = selfHostComposePaths(cwd).composePath;
|
|
287
308
|
if (existsSync(composePath)) {
|
|
288
309
|
await deploySelfHosted(cwd, fns);
|
|
289
310
|
return;
|
|
290
311
|
}
|
|
291
|
-
await deployCloud(cwd, fns);
|
|
312
|
+
await deployCloud(cwd, fns, opts.env);
|
|
292
313
|
}
|
|
293
314
|
async function deploySelfHosted(cwd, fns) {
|
|
294
|
-
|
|
295
|
-
|
|
315
|
+
info("Self-host Compose deployment.");
|
|
316
|
+
plain("Functions are served from your project functions/ directory (no bundle step).\n");
|
|
296
317
|
for (const fn of fns) {
|
|
297
|
-
|
|
318
|
+
plain(` ${fn.name} → ${relative(cwd, fn.entrypoint)}`);
|
|
298
319
|
}
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
320
|
+
plain(`\n${fns.length} function(s) ready on disk.`);
|
|
321
|
+
info("Restart the functions-worker container to load changes:");
|
|
322
|
+
plain(" supatype self-host compose restart functions-worker");
|
|
323
|
+
plain("\nKong → supatype-server → functions-worker (per-project worker).");
|
|
303
324
|
}
|
|
304
|
-
async function
|
|
325
|
+
async function deployViaTarget(cwd, target, fns) {
|
|
326
|
+
info(`Deploying to ${target.mode} project: ${target.projectRef} (${target.environment})`);
|
|
327
|
+
plain();
|
|
328
|
+
for (const fn of fns) {
|
|
329
|
+
const start = Date.now();
|
|
330
|
+
const source = readFunctionSource(fn);
|
|
331
|
+
try {
|
|
332
|
+
await targetFetch(target.apiBaseUrl, target.apiPrefix, {
|
|
333
|
+
method: "POST",
|
|
334
|
+
path: `/projects/${target.projectRef}/functions/deploy`,
|
|
335
|
+
body: {
|
|
336
|
+
functions: [{
|
|
337
|
+
name: fn.name,
|
|
338
|
+
source,
|
|
339
|
+
entrypoint: `${fn.name}/index.ts`,
|
|
340
|
+
}],
|
|
341
|
+
},
|
|
342
|
+
token: target.token,
|
|
343
|
+
orgId: target.orgId,
|
|
344
|
+
environment: target.mode === "cloud" ? target.environment : undefined,
|
|
345
|
+
});
|
|
346
|
+
const duration = Date.now() - start;
|
|
347
|
+
plain(` ${fn.name} ✓ deployed (${duration}ms)`);
|
|
348
|
+
}
|
|
349
|
+
catch (err) {
|
|
350
|
+
plain(` ${fn.name} ✗ ${err instanceof Error ? err.message : "unknown error"}`);
|
|
351
|
+
}
|
|
352
|
+
}
|
|
353
|
+
info(`Deployed ${fns.length} function(s)`);
|
|
354
|
+
void cwd;
|
|
355
|
+
}
|
|
356
|
+
async function deployCloud(cwd, fns, env) {
|
|
305
357
|
const { getLinkedProject, getCloudToken, getCloudApiUrl } = await loadCloudHelpers();
|
|
306
358
|
const linked = getLinkedProject(cwd);
|
|
307
359
|
if (!linked) {
|
|
308
|
-
|
|
360
|
+
error("No linked project. Run: npx supatype cloud link");
|
|
309
361
|
process.exit(1);
|
|
310
362
|
}
|
|
311
|
-
const token = getCloudToken();
|
|
363
|
+
const token = getCloudToken(cwd);
|
|
312
364
|
if (!token) {
|
|
313
|
-
|
|
365
|
+
error("Not logged in. Run: npx supatype cloud login");
|
|
314
366
|
process.exit(1);
|
|
315
367
|
}
|
|
316
|
-
const apiUrl = getCloudApiUrl();
|
|
317
|
-
|
|
368
|
+
const apiUrl = getCloudApiUrl(cwd);
|
|
369
|
+
info(`Deploying to project: ${linked.ref}`);
|
|
370
|
+
plain();
|
|
318
371
|
for (const fn of fns) {
|
|
319
372
|
const start = Date.now();
|
|
320
373
|
// Read source code
|
|
@@ -338,18 +391,18 @@ async function deployCloud(cwd, fns) {
|
|
|
338
391
|
});
|
|
339
392
|
if (!res.ok) {
|
|
340
393
|
const body = await res.json().catch(() => ({}));
|
|
341
|
-
|
|
394
|
+
plain(` ${fn.name} ✗ ${body["message"] ?? res.statusText}`);
|
|
342
395
|
continue;
|
|
343
396
|
}
|
|
344
397
|
const duration = Date.now() - start;
|
|
345
|
-
|
|
398
|
+
plain(` ${fn.name} ✓ deployed (${duration}ms)`);
|
|
346
399
|
}
|
|
347
400
|
catch (err) {
|
|
348
|
-
|
|
401
|
+
plain(` ${fn.name} ✗ ${err instanceof Error ? err.message : "unknown error"}`);
|
|
349
402
|
}
|
|
350
403
|
}
|
|
351
|
-
|
|
352
|
-
|
|
404
|
+
info(`Deployed ${fns.length} function(s)`);
|
|
405
|
+
info(`Invoke: https://${linked.ref}.supatype.dev/functions/v1/<name>`);
|
|
353
406
|
}
|
|
354
407
|
function readFunctionSource(fn) {
|
|
355
408
|
const stat = statSync(fn.absPath);
|
|
@@ -375,22 +428,22 @@ async function listFunctions(cwd) {
|
|
|
375
428
|
// Show local functions instead
|
|
376
429
|
const fns = discoverFunctions(cwd);
|
|
377
430
|
if (fns.length === 0) {
|
|
378
|
-
|
|
431
|
+
info("No functions found locally or remotely.");
|
|
379
432
|
return;
|
|
380
433
|
}
|
|
381
|
-
|
|
434
|
+
plain("Local functions (not linked to a cloud project):\n");
|
|
382
435
|
for (const fn of fns) {
|
|
383
|
-
|
|
436
|
+
plain(` ${fn.name.padEnd(30)} ${relative(cwd, fn.entrypoint)}`);
|
|
384
437
|
}
|
|
385
438
|
return;
|
|
386
439
|
}
|
|
387
|
-
const token = getCloudToken();
|
|
440
|
+
const token = getCloudToken(cwd);
|
|
388
441
|
if (!token) {
|
|
389
|
-
|
|
442
|
+
error("Not logged in. Run: npx supatype cloud login");
|
|
390
443
|
process.exit(1);
|
|
391
444
|
}
|
|
392
445
|
try {
|
|
393
|
-
const res = await fetch(`${getCloudApiUrl()}/api/v1/projects/${linked.ref}/functions`, {
|
|
446
|
+
const res = await fetch(`${getCloudApiUrl(cwd)}/api/v1/projects/${linked.ref}/functions`, {
|
|
394
447
|
headers: {
|
|
395
448
|
Authorization: `Bearer ${token}`,
|
|
396
449
|
"X-Org-Id": linked.orgId ?? "",
|
|
@@ -398,24 +451,24 @@ async function listFunctions(cwd) {
|
|
|
398
451
|
signal: AbortSignal.timeout(10_000),
|
|
399
452
|
});
|
|
400
453
|
if (!res.ok) {
|
|
401
|
-
|
|
454
|
+
error(`Failed to list functions: ${res.statusText}`);
|
|
402
455
|
process.exit(1);
|
|
403
456
|
}
|
|
404
457
|
const { data } = await res.json();
|
|
405
458
|
if (data.length === 0) {
|
|
406
|
-
|
|
459
|
+
info("No deployed functions.");
|
|
407
460
|
return;
|
|
408
461
|
}
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
462
|
+
plain("Deployed functions:\n");
|
|
463
|
+
plain(` ${"Name".padEnd(28)} ${"Last Deployed".padEnd(24)} ${"Invocations (24h)".padEnd(20)} Avg Duration`);
|
|
464
|
+
plain(` ${"─".repeat(28)} ${"─".repeat(24)} ${"─".repeat(20)} ${"─".repeat(12)}`);
|
|
412
465
|
for (const fn of data) {
|
|
413
466
|
const deployed = fn.deployedAt ? new Date(fn.deployedAt).toLocaleString() : "—";
|
|
414
|
-
|
|
467
|
+
plain(` ${fn.name.padEnd(28)} ${deployed.padEnd(24)} ${String(fn.invocations24h ?? 0).padEnd(20)} ${fn.avgDurationMs ?? 0}ms`);
|
|
415
468
|
}
|
|
416
469
|
}
|
|
417
470
|
catch (err) {
|
|
418
|
-
|
|
471
|
+
error(`Error: ${err instanceof Error ? err.message : "unknown"}`);
|
|
419
472
|
process.exit(1);
|
|
420
473
|
}
|
|
421
474
|
}
|
|
@@ -424,16 +477,16 @@ async function deleteFunction(cwd, name) {
|
|
|
424
477
|
const { getLinkedProject, getCloudToken, getCloudApiUrl } = await loadCloudHelpers();
|
|
425
478
|
const linked = getLinkedProject(cwd);
|
|
426
479
|
if (!linked) {
|
|
427
|
-
|
|
480
|
+
error("No linked project. Run: npx supatype cloud link");
|
|
428
481
|
process.exit(1);
|
|
429
482
|
}
|
|
430
|
-
const token = getCloudToken();
|
|
483
|
+
const token = getCloudToken(cwd);
|
|
431
484
|
if (!token) {
|
|
432
|
-
|
|
485
|
+
error("Not logged in. Run: npx supatype cloud login");
|
|
433
486
|
process.exit(1);
|
|
434
487
|
}
|
|
435
488
|
try {
|
|
436
|
-
const res = await fetch(`${getCloudApiUrl()}/api/v1/projects/${linked.ref}/functions/${name}`, {
|
|
489
|
+
const res = await fetch(`${getCloudApiUrl(cwd)}/api/v1/projects/${linked.ref}/functions/${name}`, {
|
|
437
490
|
method: "DELETE",
|
|
438
491
|
headers: {
|
|
439
492
|
Authorization: `Bearer ${token}`,
|
|
@@ -443,13 +496,13 @@ async function deleteFunction(cwd, name) {
|
|
|
443
496
|
});
|
|
444
497
|
if (!res.ok) {
|
|
445
498
|
const body = await res.json().catch(() => ({}));
|
|
446
|
-
|
|
499
|
+
error(`Failed to delete "${name}": ${body["message"] ?? res.statusText}`);
|
|
447
500
|
process.exit(1);
|
|
448
501
|
}
|
|
449
|
-
|
|
502
|
+
info(`Function "${name}" deleted. It will return 404 immediately.`);
|
|
450
503
|
}
|
|
451
504
|
catch (err) {
|
|
452
|
-
|
|
505
|
+
error(`Error: ${err instanceof Error ? err.message : "unknown"}`);
|
|
453
506
|
process.exit(1);
|
|
454
507
|
}
|
|
455
508
|
}
|
|
@@ -458,16 +511,16 @@ async function functionLogs(cwd, name, opts) {
|
|
|
458
511
|
const { getLinkedProject, getCloudToken, getCloudApiUrl } = await loadCloudHelpers();
|
|
459
512
|
const linked = getLinkedProject(cwd);
|
|
460
513
|
if (!linked) {
|
|
461
|
-
|
|
514
|
+
error("No linked project. Run: npx supatype cloud link");
|
|
462
515
|
process.exit(1);
|
|
463
516
|
}
|
|
464
|
-
const token = getCloudToken();
|
|
517
|
+
const token = getCloudToken(cwd);
|
|
465
518
|
if (!token) {
|
|
466
|
-
|
|
519
|
+
error("Not logged in. Run: npx supatype cloud login");
|
|
467
520
|
process.exit(1);
|
|
468
521
|
}
|
|
469
522
|
try {
|
|
470
|
-
const res = await fetch(`${getCloudApiUrl()}/api/v1/projects/${linked.ref}/functions/${name}/logs?since=${opts.since}`, {
|
|
523
|
+
const res = await fetch(`${getCloudApiUrl(cwd)}/api/v1/projects/${linked.ref}/functions/${name}/logs?since=${opts.since}`, {
|
|
471
524
|
headers: {
|
|
472
525
|
Authorization: `Bearer ${token}`,
|
|
473
526
|
"X-Org-Id": linked.orgId ?? "",
|
|
@@ -475,22 +528,22 @@ async function functionLogs(cwd, name, opts) {
|
|
|
475
528
|
signal: AbortSignal.timeout(10_000),
|
|
476
529
|
});
|
|
477
530
|
if (!res.ok) {
|
|
478
|
-
|
|
531
|
+
error(`Failed to fetch logs: ${res.statusText}`);
|
|
479
532
|
process.exit(1);
|
|
480
533
|
}
|
|
481
534
|
const { data } = await res.json();
|
|
482
535
|
if (data.length === 0) {
|
|
483
|
-
|
|
536
|
+
info(`No logs for "${name}" in the last ${opts.since}.`);
|
|
484
537
|
return;
|
|
485
538
|
}
|
|
486
539
|
for (const entry of data) {
|
|
487
540
|
const ts = new Date(entry.timestamp).toISOString().slice(11, 23);
|
|
488
541
|
const level = entry.level.toUpperCase().padEnd(5);
|
|
489
|
-
|
|
542
|
+
plain(`${ts} [${level}] ${entry.message}`);
|
|
490
543
|
}
|
|
491
544
|
}
|
|
492
545
|
catch (err) {
|
|
493
|
-
|
|
546
|
+
error(`Error: ${err instanceof Error ? err.message : "unknown"}`);
|
|
494
547
|
process.exit(1);
|
|
495
548
|
}
|
|
496
549
|
}
|
|
@@ -506,7 +559,7 @@ async function invoke(cwd, name, opts) {
|
|
|
506
559
|
const linked = getLinkedProject(cwd);
|
|
507
560
|
if (linked) {
|
|
508
561
|
url = `https://${linked.ref}.supatype.dev/functions/v1/${name}`;
|
|
509
|
-
const token = getCloudToken();
|
|
562
|
+
const token = getCloudToken(cwd);
|
|
510
563
|
if (token && opts.auth) {
|
|
511
564
|
headers["Authorization"] = `Bearer ${token}`;
|
|
512
565
|
}
|
|
@@ -527,7 +580,7 @@ async function invoke(cwd, name, opts) {
|
|
|
527
580
|
body = opts.data;
|
|
528
581
|
}
|
|
529
582
|
catch {
|
|
530
|
-
|
|
583
|
+
error("Invalid JSON data. Use --data '{\"key\": \"value\"}'");
|
|
531
584
|
process.exit(1);
|
|
532
585
|
}
|
|
533
586
|
const start = Date.now();
|
|
@@ -539,24 +592,24 @@ async function invoke(cwd, name, opts) {
|
|
|
539
592
|
});
|
|
540
593
|
const duration = Date.now() - start;
|
|
541
594
|
const responseBody = await res.text();
|
|
542
|
-
|
|
543
|
-
|
|
595
|
+
plain(`Status: ${res.status} (${duration}ms)`);
|
|
596
|
+
plain();
|
|
544
597
|
// Try to pretty-print JSON
|
|
545
598
|
try {
|
|
546
599
|
const json = JSON.parse(responseBody);
|
|
547
|
-
|
|
600
|
+
plain(JSON.stringify(json, null, 2));
|
|
548
601
|
}
|
|
549
602
|
catch {
|
|
550
|
-
|
|
603
|
+
plain(responseBody);
|
|
551
604
|
}
|
|
552
605
|
}
|
|
553
606
|
catch (err) {
|
|
554
607
|
if (err instanceof TypeError && err.message.includes("fetch")) {
|
|
555
|
-
|
|
556
|
-
|
|
608
|
+
error(`Cannot reach ${url}`);
|
|
609
|
+
error("Is the function server running? Start it with: npx supatype functions serve");
|
|
557
610
|
}
|
|
558
611
|
else {
|
|
559
|
-
|
|
612
|
+
error(`Error: ${err instanceof Error ? err.message : "unknown"}`);
|
|
560
613
|
}
|
|
561
614
|
process.exit(1);
|
|
562
615
|
}
|
|
@@ -569,11 +622,11 @@ async function envList(cwd) {
|
|
|
569
622
|
// Show local env vars
|
|
570
623
|
const envPath = resolve(resolveFunctionsDir(cwd, "read"), ENV_LOCAL);
|
|
571
624
|
if (!existsSync(envPath)) {
|
|
572
|
-
|
|
625
|
+
info("No environment variables configured.");
|
|
573
626
|
return;
|
|
574
627
|
}
|
|
575
628
|
const lines = readFileSync(envPath, "utf8").split("\n");
|
|
576
|
-
|
|
629
|
+
plain("Local environment variables:\n");
|
|
577
630
|
for (const line of lines) {
|
|
578
631
|
const trimmed = line.trim();
|
|
579
632
|
if (!trimmed || trimmed.startsWith("#"))
|
|
@@ -581,18 +634,18 @@ async function envList(cwd) {
|
|
|
581
634
|
const eqIdx = trimmed.indexOf("=");
|
|
582
635
|
if (eqIdx > 0) {
|
|
583
636
|
const key = trimmed.slice(0, eqIdx);
|
|
584
|
-
|
|
637
|
+
plain(` ${key} = ••••••••`);
|
|
585
638
|
}
|
|
586
639
|
}
|
|
587
640
|
return;
|
|
588
641
|
}
|
|
589
|
-
const token = getCloudToken();
|
|
642
|
+
const token = getCloudToken(cwd);
|
|
590
643
|
if (!token) {
|
|
591
|
-
|
|
644
|
+
error("Not logged in. Run: npx supatype cloud login");
|
|
592
645
|
process.exit(1);
|
|
593
646
|
}
|
|
594
647
|
try {
|
|
595
|
-
const res = await fetch(`${getCloudApiUrl()}/api/v1/projects/${linked.ref}/functions/env`, {
|
|
648
|
+
const res = await fetch(`${getCloudApiUrl(cwd)}/api/v1/projects/${linked.ref}/functions/env`, {
|
|
596
649
|
headers: {
|
|
597
650
|
Authorization: `Bearer ${token}`,
|
|
598
651
|
"X-Org-Id": linked.orgId ?? "",
|
|
@@ -600,28 +653,28 @@ async function envList(cwd) {
|
|
|
600
653
|
signal: AbortSignal.timeout(10_000),
|
|
601
654
|
});
|
|
602
655
|
if (!res.ok) {
|
|
603
|
-
|
|
656
|
+
error(`Failed to list env vars: ${res.statusText}`);
|
|
604
657
|
process.exit(1);
|
|
605
658
|
}
|
|
606
659
|
const { data } = await res.json();
|
|
607
660
|
if (data.length === 0) {
|
|
608
|
-
|
|
661
|
+
info("No environment variables set.");
|
|
609
662
|
return;
|
|
610
663
|
}
|
|
611
|
-
|
|
664
|
+
plain("Environment variables (values masked):\n");
|
|
612
665
|
for (const key of data) {
|
|
613
|
-
|
|
666
|
+
plain(` ${key} = ••••••••`);
|
|
614
667
|
}
|
|
615
668
|
}
|
|
616
669
|
catch (err) {
|
|
617
|
-
|
|
670
|
+
error(`Error: ${err instanceof Error ? err.message : "unknown"}`);
|
|
618
671
|
process.exit(1);
|
|
619
672
|
}
|
|
620
673
|
}
|
|
621
674
|
async function envSet(cwd, keyvalue) {
|
|
622
675
|
const eqIdx = keyvalue.indexOf("=");
|
|
623
676
|
if (eqIdx <= 0) {
|
|
624
|
-
|
|
677
|
+
error("Invalid format. Use: npx supatype functions env set KEY=value");
|
|
625
678
|
process.exit(1);
|
|
626
679
|
}
|
|
627
680
|
const key = keyvalue.slice(0, eqIdx);
|
|
@@ -641,16 +694,16 @@ async function envSet(cwd, keyvalue) {
|
|
|
641
694
|
content = content.trimEnd() + `\n${key}=${value}\n`;
|
|
642
695
|
}
|
|
643
696
|
writeFileSync(envPath, content, "utf8");
|
|
644
|
-
|
|
697
|
+
info(`Set ${key} in local env file.`);
|
|
645
698
|
return;
|
|
646
699
|
}
|
|
647
|
-
const token = getCloudToken();
|
|
700
|
+
const token = getCloudToken(cwd);
|
|
648
701
|
if (!token) {
|
|
649
|
-
|
|
702
|
+
error("Not logged in. Run: npx supatype cloud login");
|
|
650
703
|
process.exit(1);
|
|
651
704
|
}
|
|
652
705
|
try {
|
|
653
|
-
const res = await fetch(`${getCloudApiUrl()}/api/v1/projects/${linked.ref}/functions/env`, {
|
|
706
|
+
const res = await fetch(`${getCloudApiUrl(cwd)}/api/v1/projects/${linked.ref}/functions/env`, {
|
|
654
707
|
method: "POST",
|
|
655
708
|
headers: {
|
|
656
709
|
Authorization: `Bearer ${token}`,
|
|
@@ -662,13 +715,13 @@ async function envSet(cwd, keyvalue) {
|
|
|
662
715
|
});
|
|
663
716
|
if (!res.ok) {
|
|
664
717
|
const body = await res.json().catch(() => ({}));
|
|
665
|
-
|
|
718
|
+
error(`Failed to set env var: ${body["message"] ?? res.statusText}`);
|
|
666
719
|
process.exit(1);
|
|
667
720
|
}
|
|
668
|
-
|
|
721
|
+
info(`Set ${key} for project ${linked.ref}.`);
|
|
669
722
|
}
|
|
670
723
|
catch (err) {
|
|
671
|
-
|
|
724
|
+
error(`Error: ${err instanceof Error ? err.message : "unknown"}`);
|
|
672
725
|
process.exit(1);
|
|
673
726
|
}
|
|
674
727
|
}
|
|
@@ -678,23 +731,23 @@ async function envUnset(cwd, key) {
|
|
|
678
731
|
if (!linked) {
|
|
679
732
|
const envPath = resolve(resolveFunctionsDir(cwd, "read"), ENV_LOCAL);
|
|
680
733
|
if (!existsSync(envPath)) {
|
|
681
|
-
|
|
734
|
+
error("No local env file found.");
|
|
682
735
|
process.exit(1);
|
|
683
736
|
}
|
|
684
737
|
let content = readFileSync(envPath, "utf8");
|
|
685
738
|
const regex = new RegExp(`^${key}=.*\n?`, "m");
|
|
686
739
|
content = content.replace(regex, "");
|
|
687
740
|
writeFileSync(envPath, content, "utf8");
|
|
688
|
-
|
|
741
|
+
info(`Removed ${key} from local env file.`);
|
|
689
742
|
return;
|
|
690
743
|
}
|
|
691
|
-
const token = getCloudToken();
|
|
744
|
+
const token = getCloudToken(cwd);
|
|
692
745
|
if (!token) {
|
|
693
|
-
|
|
746
|
+
error("Not logged in. Run: npx supatype cloud login");
|
|
694
747
|
process.exit(1);
|
|
695
748
|
}
|
|
696
749
|
try {
|
|
697
|
-
const res = await fetch(`${getCloudApiUrl()}/api/v1/projects/${linked.ref}/functions/env/${key}`, {
|
|
750
|
+
const res = await fetch(`${getCloudApiUrl(cwd)}/api/v1/projects/${linked.ref}/functions/env/${key}`, {
|
|
698
751
|
method: "DELETE",
|
|
699
752
|
headers: {
|
|
700
753
|
Authorization: `Bearer ${token}`,
|
|
@@ -704,44 +757,44 @@ async function envUnset(cwd, key) {
|
|
|
704
757
|
});
|
|
705
758
|
if (!res.ok) {
|
|
706
759
|
const body = await res.json().catch(() => ({}));
|
|
707
|
-
|
|
760
|
+
error(`Failed to unset env var: ${body["message"] ?? res.statusText}`);
|
|
708
761
|
process.exit(1);
|
|
709
762
|
}
|
|
710
|
-
|
|
763
|
+
info(`Removed ${key} for project ${linked.ref}.`);
|
|
711
764
|
}
|
|
712
765
|
catch (err) {
|
|
713
|
-
|
|
766
|
+
error(`Error: ${err instanceof Error ? err.message : "unknown"}`);
|
|
714
767
|
process.exit(1);
|
|
715
768
|
}
|
|
716
769
|
}
|
|
717
770
|
async function loadCloudHelpers() {
|
|
718
|
-
// These helpers read the local .supatype/linked.json and auth token
|
|
719
771
|
return {
|
|
720
772
|
getLinkedProject(cwd) {
|
|
721
|
-
const
|
|
722
|
-
if (!
|
|
773
|
+
const link = loadProjectLink(cwd);
|
|
774
|
+
if (!link?.projectRef)
|
|
723
775
|
return null;
|
|
724
|
-
|
|
725
|
-
|
|
726
|
-
|
|
727
|
-
|
|
728
|
-
|
|
729
|
-
}
|
|
730
|
-
catch {
|
|
731
|
-
return null;
|
|
732
|
-
}
|
|
776
|
+
return {
|
|
777
|
+
ref: link.projectRef,
|
|
778
|
+
kind: link.kind,
|
|
779
|
+
...(link.orgId !== undefined ? { orgId: link.orgId } : {}),
|
|
780
|
+
};
|
|
733
781
|
},
|
|
734
|
-
getCloudToken() {
|
|
735
|
-
// Check env first, then config file
|
|
782
|
+
getCloudToken(cwd) {
|
|
736
783
|
if (process.env["SUPATYPE_ACCESS_TOKEN"]) {
|
|
737
784
|
return process.env["SUPATYPE_ACCESS_TOKEN"];
|
|
738
785
|
}
|
|
786
|
+
const link = loadProjectLink(cwd);
|
|
787
|
+
if (link?.token)
|
|
788
|
+
return link.token;
|
|
739
789
|
const tokenPath = resolve(process.env["HOME"] ?? process.env["USERPROFILE"] ?? "~", ".supatype/token");
|
|
740
790
|
if (!existsSync(tokenPath))
|
|
741
791
|
return null;
|
|
742
792
|
return readFileSync(tokenPath, "utf8").trim() || null;
|
|
743
793
|
},
|
|
744
|
-
getCloudApiUrl() {
|
|
794
|
+
getCloudApiUrl(cwd) {
|
|
795
|
+
const link = loadProjectLink(cwd);
|
|
796
|
+
if (link?.cloudApiUrl)
|
|
797
|
+
return link.cloudApiUrl;
|
|
745
798
|
return process.env["SUPATYPE_API_URL"] ?? "https://api.supatype.com";
|
|
746
799
|
},
|
|
747
800
|
};
|