@supacloud/cli 0.3.4 → 0.3.6

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 (2) hide show
  1. package/dist/index.js +74 -8
  2. package/package.json +1 -1
package/dist/index.js CHANGED
@@ -4194,26 +4194,69 @@ function detectSource(sources) {
4194
4194
  return present.has("env") ? "env" : "dotenv";
4195
4195
  return "mixed";
4196
4196
  }
4197
+ function normalizeUrl(value) {
4198
+ const trimmed = value.trim().replace(/\/+$/, "");
4199
+ if (!trimmed)
4200
+ return "";
4201
+ try {
4202
+ return new URL(trimmed).toString().replace(/\/+$/, "");
4203
+ } catch {
4204
+ return "";
4205
+ }
4206
+ }
4207
+ function hostFromUrl(value) {
4208
+ try {
4209
+ return new URL(value).hostname;
4210
+ } catch {
4211
+ return "";
4212
+ }
4213
+ }
4214
+ function inferManagementApiUrlFromSupabaseUrl(value, projectRef = "") {
4215
+ const normalized = normalizeUrl(value);
4216
+ if (!normalized)
4217
+ return "";
4218
+ const url = new URL(normalized);
4219
+ const host = url.hostname;
4220
+ if (host.startsWith("api.")) {
4221
+ url.hostname = `studio.${host.slice("api.".length)}`;
4222
+ return url.toString().replace(/\/+$/, "");
4223
+ }
4224
+ const ref = projectRef.trim();
4225
+ if (ref && host.startsWith(`${ref}.api.`)) {
4226
+ url.hostname = `studio-${ref}.${host.slice(`${ref}.api.`.length)}`;
4227
+ return url.toString().replace(/\/+$/, "");
4228
+ }
4229
+ const managedHostMatch = host.match(/^([a-z0-9-]+)\.api\.(.+)$/i);
4230
+ if (managedHostMatch) {
4231
+ url.hostname = `studio-${managedHostMatch[1]}.${managedHostMatch[2]}`;
4232
+ return url.toString().replace(/\/+$/, "");
4233
+ }
4234
+ return normalized;
4235
+ }
4197
4236
  function resolveSupaCloudContext(env = process.env, cwd = process.cwd()) {
4198
4237
  const dotenv = readDotEnvFile(cwd);
4199
- const inferredUrl = pickValue(env, dotenv, ["SUPABASE_URL", "SUPACLOUD_API_URL"]);
4238
+ const supabaseUrl = pickValue(env, dotenv, ["SUPABASE_URL"]);
4239
+ const explicitApiUrl = pickValue(env, dotenv, ["SUPACLOUD_API_URL", "SUPACLOUD_MANAGEMENT_API_URL", "MANAGEMENT_API_URL"]);
4200
4240
  const inferredToken = pickValue(env, dotenv, ["SUPABASE_SERVICE_ROLE_KEY", "SUPACLOUD_API_TOKEN"]);
4241
+ const projectRef = pickValue(env, dotenv, ["SUPACLOUD_PROJECT_REF", "X_PROJECT_REF"]).value;
4201
4242
  const hostFromEnv = env.SUPACLOUD_HOST;
4202
- const hostFromUrl = inferredUrl.value ? new URL(inferredUrl.value).hostname : "";
4243
+ const normalizedSupabaseUrl = normalizeUrl(supabaseUrl.value);
4244
+ const apiUrl = normalizeUrl(explicitApiUrl.value) || inferManagementApiUrlFromSupabaseUrl(normalizedSupabaseUrl, projectRef) || (hostFromEnv ? `http://${hostFromEnv}:9090` : "");
4245
+ const resolvedHostFromUrl = hostFromUrl(apiUrl || normalizedSupabaseUrl);
4203
4246
  return {
4204
- host: hostFromEnv ?? hostFromUrl,
4247
+ host: hostFromEnv ?? resolvedHostFromUrl,
4205
4248
  sshUser: env.SUPACLOUD_SSH_USER ?? "root",
4206
4249
  sshPort: parseInt(env.SUPACLOUD_SSH_PORT ?? "22", 10),
4207
4250
  sshKey: env.SUPACLOUD_SSH_KEY ?? resolve(homedir(), ".ssh", "id_rsa"),
4208
4251
  sshPass: env.SUPACLOUD_SSH_PASS ?? "",
4209
- apiUrl: env.SUPACLOUD_API_URL ?? (inferredUrl.value ? inferredUrl.value.replace(/\/+$/, "") : hostFromEnv ? `http://${hostFromEnv}:9090` : ""),
4252
+ apiUrl,
4210
4253
  apiToken: env.SUPACLOUD_API_TOKEN ?? inferredToken.value,
4211
- projectRef: env.SUPACLOUD_PROJECT_REF ?? "",
4254
+ projectRef,
4212
4255
  readOnly: env.SUPACLOUD_READ_ONLY === "true",
4213
- inferredSupabaseUrl: inferredUrl.value,
4256
+ inferredSupabaseUrl: normalizedSupabaseUrl,
4214
4257
  inferredServiceRoleKey: inferredToken.value,
4215
4258
  source: detectSource([
4216
- inferredUrl.value ? inferredUrl.source : "none",
4259
+ supabaseUrl.value || explicitApiUrl.value ? supabaseUrl.value ? supabaseUrl.source : explicitApiUrl.source : "none",
4217
4260
  inferredToken.value ? inferredToken.source : "none"
4218
4261
  ])
4219
4262
  };
@@ -5312,6 +5355,29 @@ var backgroundRoutesSchema = exports_external.preprocess((value) => {
5312
5355
  }
5313
5356
  }
5314
5357
  }));
5358
+ var secretsSchema = exports_external.preprocess((value) => {
5359
+ if (typeof value !== "string")
5360
+ return value;
5361
+ const trimmed = value.trim();
5362
+ if (!trimmed)
5363
+ return [];
5364
+ if (trimmed.startsWith("[")) {
5365
+ try {
5366
+ return JSON.parse(trimmed);
5367
+ } catch {
5368
+ return trimmed;
5369
+ }
5370
+ }
5371
+ return trimmed.split(",").map((entry) => {
5372
+ const separator = entry.indexOf("=");
5373
+ if (separator <= 0)
5374
+ return { name: entry.trim(), value: "" };
5375
+ return {
5376
+ name: entry.slice(0, separator).trim(),
5377
+ value: entry.slice(separator + 1)
5378
+ };
5379
+ }).filter((entry) => entry.name);
5380
+ }, exports_external.array(exports_external.object({ name: exports_external.string(), value: exports_external.string() })).optional());
5315
5381
  function registerAdvancedTools(server, http) {
5316
5382
  server.tool("edge_functions", `Edge Function management (Deno/Bun serverless). Server auto-bundles dependencies.
5317
5383
  Actions: list, deploy, deploy_bundle, config, source, delete, check`, {
@@ -5431,7 +5497,7 @@ ${await updateFunctionConfig()}` : `✅ Function ${slug} bundle deployed (${Obje
5431
5497
  Actions: list, upsert, delete`, {
5432
5498
  action: exports_external.enum(["list", "upsert", "delete"]).describe("Action"),
5433
5499
  ref: exports_external.string().describe("Project ref"),
5434
- secrets: exports_external.array(exports_external.object({ name: exports_external.string(), value: exports_external.string() })).optional().describe("[upsert] Secret list: [{name:'KEY', value:'...'}]"),
5500
+ secrets: secretsSchema.describe("[upsert] Secret list as JSON array or KEY=VALUE,KEY2=VALUE2"),
5435
5501
  name: exports_external.string().optional().describe("[delete] Secret name to delete")
5436
5502
  }, async (args) => {
5437
5503
  const { action, ref, secrets, name } = args;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@supacloud/cli",
3
- "version": "0.3.4",
3
+ "version": "0.3.6",
4
4
  "description": "Project-scoped CLI for SupaCloud users",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",