@supacloud/cli 0.14.0 → 0.14.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.
Files changed (2) hide show
  1. package/dist/index.js +37 -58
  2. package/package.json +1 -1
package/dist/index.js CHANGED
@@ -6087,6 +6087,11 @@ function schemaProperties(schema) {
6087
6087
  }
6088
6088
 
6089
6089
  // src/shared/cli.ts
6090
+ function cliToolResultIsError(toolResult) {
6091
+ if (toolResult.isError === true)
6092
+ return true;
6093
+ return toolResult.content?.some((chunk) => chunk.type === "text" && chunk.text?.trimStart().startsWith("❌") === true) ?? false;
6094
+ }
6090
6095
  function coerceCliValue(value) {
6091
6096
  if (value === "true")
6092
6097
  return true;
@@ -6193,7 +6198,7 @@ async function runCli(cliTools, args, options = {}) {
6193
6198
  } else {
6194
6199
  console.log(JSON.stringify(result, null, 2));
6195
6200
  }
6196
- process.exit(result && typeof result === "object" && "isError" in result && result.isError === true ? 1 : 0);
6201
+ process.exit(cliToolResultIsError(result) ? 1 : 0);
6197
6202
  } catch (error) {
6198
6203
  const message = error instanceof Error ? error.message : String(error);
6199
6204
  console.error(`❌ Error: ${message}`);
@@ -6330,29 +6335,46 @@ function resolveSupaCloudContext(env = process.env, cwd = process.cwd()) {
6330
6335
  var DEFAULT_TIMEOUT = 30000;
6331
6336
  var MAX_RETRIES = 2;
6332
6337
  var RETRY_BASE_DELAY = 500;
6333
- async function fetchWithRetry(url, options, retries = MAX_RETRIES) {
6338
+ function isRetryableMethod(method) {
6339
+ const normalizedMethod = (method ?? "GET").toUpperCase();
6340
+ return normalizedMethod === "GET" || normalizedMethod === "HEAD";
6341
+ }
6342
+ function isRetryableError(error) {
6343
+ if (!(error instanceof Error))
6344
+ return false;
6345
+ const networkError = error;
6346
+ return networkError.name === "AbortError" || networkError.code === "ECONNREFUSED" || networkError.code === "ECONNRESET";
6347
+ }
6348
+ async function fetchWithTimeout(url, options) {
6349
+ const controller = new AbortController;
6350
+ const timeout = setTimeout(() => controller.abort(), DEFAULT_TIMEOUT);
6351
+ try {
6352
+ return await fetch(url, {
6353
+ ...options,
6354
+ signal: controller.signal
6355
+ });
6356
+ } finally {
6357
+ clearTimeout(timeout);
6358
+ }
6359
+ }
6360
+ async function fetchWithRetry(url, options) {
6361
+ const retries = isRetryableMethod(options.method) ? MAX_RETRIES : 0;
6334
6362
  for (let attempt = 0;attempt <= retries; attempt++) {
6335
6363
  try {
6336
- const controller = new AbortController;
6337
- const timeout = setTimeout(() => controller.abort(), DEFAULT_TIMEOUT);
6338
- const res = await fetch(url, {
6339
- ...options,
6340
- signal: controller.signal
6341
- });
6342
- clearTimeout(timeout);
6343
- if (res.status >= 500 && attempt < retries) {
6364
+ const res = await fetchWithTimeout(url, options);
6365
+ if (res.status >= 500 && res.status < 600 && attempt < retries) {
6344
6366
  const delay = RETRY_BASE_DELAY * Math.pow(2, attempt);
6345
6367
  await new Promise((r) => setTimeout(r, delay));
6346
6368
  continue;
6347
6369
  }
6348
6370
  return res;
6349
- } catch (err) {
6350
- if (attempt < retries && (err.name === "AbortError" || err.code === "ECONNREFUSED" || err.code === "ECONNRESET")) {
6371
+ } catch (error) {
6372
+ if (attempt < retries && isRetryableError(error)) {
6351
6373
  const delay = RETRY_BASE_DELAY * Math.pow(2, attempt);
6352
6374
  await new Promise((r) => setTimeout(r, delay));
6353
6375
  continue;
6354
6376
  }
6355
- throw err;
6377
+ throw error;
6356
6378
  }
6357
6379
  }
6358
6380
  throw new Error("Unreachable");
@@ -6889,8 +6911,7 @@ Actions: ${allActions.join(", ")}${readOnly ? " (read-only mode)" : ""}`, {
6889
6911
  `);
6890
6912
  break;
6891
6913
  }
6892
- const baselineSql = buildMigrationBaselineSql(missing);
6893
- const baselineResult = await execSql(baselineSql, "migration");
6914
+ const baselineResult = await http.post(`/v1/projects/${ref}/database/migrations/baseline`, { migrations: missing.map(({ name, version }) => ({ name, version })) });
6894
6915
  text = baselineResult.ok ? [
6895
6916
  `✅ Migration baseline completed for ${dir}`,
6896
6917
  `Marked applied: ${missing.length}`,
@@ -6958,48 +6979,6 @@ function buildRlsPolicySql(qualifiedTable, policyMode, ownerColumnValue) {
6958
6979
  CREATE POLICY "SupaCloud owner update" ON ${qualifiedTable} FOR UPDATE TO authenticated USING (${predicate}) WITH CHECK (${predicate});
6959
6980
  CREATE POLICY "SupaCloud owner delete" ON ${qualifiedTable} FOR DELETE TO authenticated USING (${predicate});`;
6960
6981
  }
6961
- function sqlString(value) {
6962
- return `'${value.replace(/'/g, "''")}'`;
6963
- }
6964
- function buildMigrationBaselineSql(migrations) {
6965
- const values = migrations.map(({ name, version }) => `(${version}, ${sqlString(name)}, ARRAY[${sqlString(`baseline:${name}`)}]::text[])`).join(`,
6966
- `);
6967
- return `
6968
- CREATE SCHEMA IF NOT EXISTS supabase_migrations;
6969
-
6970
- CREATE TABLE IF NOT EXISTS supabase_migrations.schema_migrations (
6971
- version BIGINT PRIMARY KEY,
6972
- statements TEXT[],
6973
- name TEXT
6974
- );
6975
-
6976
- CREATE TABLE IF NOT EXISTS public.schema_migrations (
6977
- version VARCHAR(255) PRIMARY KEY,
6978
- statements TEXT[],
6979
- name TEXT
6980
- );
6981
-
6982
- WITH baseline(version, name, statements) AS (
6983
- VALUES
6984
- ${values}
6985
- )
6986
- INSERT INTO supabase_migrations.schema_migrations (version, statements, name)
6987
- SELECT version, statements, name FROM baseline
6988
- ON CONFLICT (version) DO UPDATE
6989
- SET statements = EXCLUDED.statements,
6990
- name = EXCLUDED.name;
6991
-
6992
- WITH baseline(version, name, statements) AS (
6993
- VALUES
6994
- ${values}
6995
- )
6996
- INSERT INTO public.schema_migrations (version, statements, name)
6997
- SELECT version::text, statements, name FROM baseline
6998
- ON CONFLICT (version) DO UPDATE
6999
- SET statements = EXCLUDED.statements,
7000
- name = EXCLUDED.name;
7001
- `.trim();
7002
- }
7003
6982
  function formatSqlResult(data) {
7004
6983
  if (!data || typeof data !== "object")
7005
6984
  return JSON.stringify(data, null, 2);
@@ -9872,7 +9851,7 @@ async function main() {
9872
9851
  console.log(chunk.text);
9873
9852
  }
9874
9853
  }
9875
- if (result.isError === true)
9854
+ if (cliToolResultIsError(result))
9876
9855
  process.exitCode = 1;
9877
9856
  return;
9878
9857
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@supacloud/cli",
3
- "version": "0.14.0",
3
+ "version": "0.14.2",
4
4
  "description": "Project-scoped CLI for SupaCloud users",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",