@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.
- package/dist/index.js +74 -8
- 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
|
|
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
|
|
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 ??
|
|
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
|
|
4252
|
+
apiUrl,
|
|
4210
4253
|
apiToken: env.SUPACLOUD_API_TOKEN ?? inferredToken.value,
|
|
4211
|
-
projectRef
|
|
4254
|
+
projectRef,
|
|
4212
4255
|
readOnly: env.SUPACLOUD_READ_ONLY === "true",
|
|
4213
|
-
inferredSupabaseUrl:
|
|
4256
|
+
inferredSupabaseUrl: normalizedSupabaseUrl,
|
|
4214
4257
|
inferredServiceRoleKey: inferredToken.value,
|
|
4215
4258
|
source: detectSource([
|
|
4216
|
-
|
|
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:
|
|
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;
|