@supacloud/cli 0.14.3 → 0.14.4

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.
Files changed (3) hide show
  1. package/README.md +12 -0
  2. package/dist/index.js +52 -12
  3. package/package.json +1 -1
package/README.md CHANGED
@@ -68,8 +68,20 @@ supacloud-cli frontend list --ref abc123
68
68
  supacloud-cli branch create --name feature-orders --data_mode schema_only
69
69
  supacloud-cli branch promotion_plan --branch_ref preview123
70
70
  supacloud-cli branch promote --branch_ref preview123 --plan_checksum <sha256>
71
+ supacloud-cli edge_functions deploy --ref abc123 --slug hello --path ./supabase/functions/hello
72
+ supacloud-cli edge_functions deploy_bundle --ref abc123 --slug hello --files '{"index.ts":"export default { fetch: () => new Response(\"ok\") }"}'
73
+ supacloud-cli edge_functions source --ref abc123 --slug hello --output ./hello.ts
71
74
  ```
72
75
 
76
+ `edge_functions deploy --path` bundles local TypeScript and dependencies with
77
+ Bun and runs a local syntax check before upload. The Management API validates and
78
+ normalizes the final server-side artifact against the multi-tenant Edge Runtime
79
+ module policy consistently for CLI, Web Console, and direct API deployments.
80
+ `deploy_bundle --files` accepts a JSON object in shell usage.
81
+ Use `source --output <file>` for large Functions so terminal or automation output
82
+ limits cannot truncate the original TS/JS source code. The destination must not
83
+ already exist.
84
+
73
85
  Branch promotion is migration-first. `branch promotion_plan` prints pending
74
86
  versions, names, statement counts, and checksums without echoing SQL into terminal
75
87
  logs; review the migration files or the Web Console SQL view before approval.
package/dist/index.js CHANGED
@@ -6155,15 +6155,18 @@ async function runCli(cliTools, args, options = {}) {
6155
6155
  console.error(`❌ Unknown command: ${toolName}`);
6156
6156
  console.error(`Available commands:
6157
6157
  ${formatAvailableCommands()}`);
6158
- process.exit(1);
6158
+ process.exitCode = 1;
6159
+ return;
6159
6160
  }
6160
6161
  if (args.length === 1 || args[1] === "--help" || args[1] === "-h") {
6161
6162
  console.error(formatToolHelp(toolName, tool));
6162
- process.exit(0);
6163
+ process.exitCode = 0;
6164
+ return;
6163
6165
  }
6164
6166
  if (args.length > 2 && !args[1].startsWith("--") && (args[2] === "--help" || args[2] === "-h")) {
6165
6167
  console.error(formatActionHelp(toolName, args[1], tool));
6166
- process.exit(0);
6168
+ process.exitCode = 0;
6169
+ return;
6167
6170
  }
6168
6171
  const parsedArgs = {};
6169
6172
  let startIdx = 1;
@@ -6198,14 +6201,14 @@ async function runCli(cliTools, args, options = {}) {
6198
6201
  } else {
6199
6202
  console.log(JSON.stringify(result, null, 2));
6200
6203
  }
6201
- process.exit(cliToolResultIsError(result) ? 1 : 0);
6204
+ process.exitCode = cliToolResultIsError(result) ? 1 : 0;
6202
6205
  } catch (error) {
6203
6206
  const message = error instanceof Error ? error.message : String(error);
6204
6207
  console.error(`❌ Error: ${message}`);
6205
6208
  if (message.includes("required")) {
6206
6209
  console.error(`Hint: Pass arguments like --ref YOUR_REF`);
6207
6210
  }
6208
- process.exit(1);
6211
+ process.exitCode = 1;
6209
6212
  }
6210
6213
  }
6211
6214
 
@@ -7524,6 +7527,19 @@ function parseBackgroundRoutes(value) {
7524
7527
  }
7525
7528
  }
7526
7529
  var backgroundRoutesSchema = Type.Optional(decodedSchema(Type.Union([Type.String(), Type.Array(Type.String())]), Type.Array(Type.String()), parseBackgroundRoutes));
7530
+ var functionFilesRecordSchema = Type.Record(Type.String(), Type.String());
7531
+ function parseFunctionFiles(input) {
7532
+ if (typeof input !== "string")
7533
+ return input;
7534
+ try {
7535
+ return JSON.parse(input);
7536
+ } catch (error) {
7537
+ if (!(error instanceof SyntaxError))
7538
+ throw error;
7539
+ throw new Error("Invalid files JSON object");
7540
+ }
7541
+ }
7542
+ var functionFilesSchema = decodedSchema(Type.Union([Type.String(), functionFilesRecordSchema]), functionFilesRecordSchema, parseFunctionFiles);
7527
7543
  var secretListSchema = Type.Array(Type.Object({ name: Type.String(), value: Type.String() }));
7528
7544
  function parseSecrets(value) {
7529
7545
  if (Array.isArray(value))
@@ -7565,6 +7581,12 @@ function confirmedFunctionConfig(payload, expected) {
7565
7581
  }
7566
7582
  return true;
7567
7583
  }
7584
+ function functionSourceCode(payload) {
7585
+ if (!payload || typeof payload !== "object" || Array.isArray(payload))
7586
+ return null;
7587
+ const code = payload.code;
7588
+ return typeof code === "string" ? code : null;
7589
+ }
7568
7590
  function registerAdvancedTools(server, http) {
7569
7591
  server.tool("edge_functions", `Edge Function management (Deno/Bun serverless). Server auto-bundles dependencies.
7570
7592
  Actions: list, deploy, deploy_bundle, config, source, delete, check`, {
@@ -7573,13 +7595,14 @@ Actions: list, deploy, deploy_bundle, config, source, delete, check`, {
7573
7595
  slug: optional(Type.String(), "[deploy/deploy_bundle/config/source/delete/check] Function name"),
7574
7596
  code: optional(Type.String(), "[deploy/check] Function source code (TypeScript)"),
7575
7597
  path: optional(Type.String(), "[deploy/check] Local file path to read code from (alternative to code)"),
7576
- files: optional(Type.Record(Type.String(), Type.String()), "[deploy_bundle] File map: { 'index.ts': '...', '_shared/x.ts': '...' }"),
7598
+ output: optional(Type.String(), "[source] Write source to this local file instead of stdout; the file must not already exist"),
7599
+ files: optional(functionFilesSchema, "[deploy_bundle] File map as a JSON object: { 'index.ts': '...', '_shared/x.ts': '...' }"),
7577
7600
  entrypoint: optional(Type.String(), "[deploy_bundle] Entrypoint file (default: index.ts)"),
7578
7601
  minify: optional(Type.Boolean(), "[deploy/deploy_bundle] Minify bundle"),
7579
7602
  verify_jwt: optional(Type.Boolean(), "[deploy/deploy_bundle/config] Set JWT verification for this function"),
7580
7603
  background_routes: withDescription(backgroundRoutesSchema, "[deploy/deploy_bundle/config] Background route paths; pass comma-separated or JSON array in CLI")
7581
7604
  }, async (args) => {
7582
- const { action, ref, slug, path: pathArg, files, entrypoint, minify, verify_jwt, background_routes } = args;
7605
+ const { action, ref, slug, path: pathArg, output, files, entrypoint, minify, verify_jwt, background_routes } = args;
7583
7606
  let code = args.code;
7584
7607
  const need = (f, v) => {
7585
7608
  if (!v)
@@ -7628,8 +7651,9 @@ ${e.stderr || e.message}` };
7628
7651
  if (pathArg && !code) {
7629
7652
  try {
7630
7653
  code = await bundleEdgeFunctionPath(pathArg);
7631
- } catch (e) {
7632
- throw new Error(`Failed to bundle/read path ${pathArg}: ${e.message}`);
7654
+ } catch (error) {
7655
+ const message = error instanceof Error ? error.message : String(error);
7656
+ throw new Error(`Failed to bundle/read path ${pathArg}: ${message}`);
7633
7657
  }
7634
7658
  }
7635
7659
  switch (action) {
@@ -7687,7 +7711,22 @@ ${deployCheck.err}`;
7687
7711
  case "source":
7688
7712
  need("slug", slug);
7689
7713
  const sr = await http.get(`/v1/projects/${ref}/functions/${slug}/source`);
7690
- text = sr.ok ? JSON.stringify(sr.data, null, 2) : `❌ Not found (${sr.status})`;
7714
+ if (!sr.ok) {
7715
+ text = `❌ Not found (${sr.status})`;
7716
+ break;
7717
+ }
7718
+ if (!output) {
7719
+ text = JSON.stringify(sr.data, null, 2);
7720
+ break;
7721
+ }
7722
+ const sourceCode = functionSourceCode(sr.data);
7723
+ if (sourceCode === null) {
7724
+ text = "❌ Source response did not contain a string code field";
7725
+ break;
7726
+ }
7727
+ const outputPath = resolve2(output);
7728
+ writeFileSync(outputPath, sourceCode, { flag: "wx" });
7729
+ text = `✅ Function ${slug} source written to ${outputPath} (${Buffer.byteLength(sourceCode)} bytes)`;
7691
7730
  break;
7692
7731
  case "delete":
7693
7732
  need("slug", slug);
@@ -9872,7 +9911,8 @@ async function main() {
9872
9911
  const args = process.argv.slice(2);
9873
9912
  if (args.length === 0 || args[0] === "--help" || args[0] === "-h") {
9874
9913
  printHelp();
9875
- process.exit(0);
9914
+ process.exitCode = 0;
9915
+ return;
9876
9916
  }
9877
9917
  const cliTools = createCliTools();
9878
9918
  if (args.length === 1 && !["ai", "supabase"].includes(args[0]) && cliTools[args[0]]) {
@@ -9894,5 +9934,5 @@ async function main() {
9894
9934
  }
9895
9935
  main().catch((error) => {
9896
9936
  console.error(`${commandName} failed:`, error);
9897
- process.exit(1);
9937
+ process.exitCode = 1;
9898
9938
  });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@supacloud/cli",
3
- "version": "0.14.3",
3
+ "version": "0.14.4",
4
4
  "description": "Project-scoped CLI for SupaCloud users",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",