@supacloud/cli 0.34.2 → 0.35.0
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 +94 -8
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -6463,7 +6463,7 @@ var ACTION_POLICY = {
|
|
|
6463
6463
|
local: ["list"]
|
|
6464
6464
|
},
|
|
6465
6465
|
database: {
|
|
6466
|
-
read: ["list_tables", "describe_columns", "list_indexes", "list_constraints", "list_extensions", "rls_status", "rls_policies", "list_auth_users", "get_auth_user", "connections", "stats", "slow_queries", "list_migrations", "migration_inventory", "project_url", "generate_types"],
|
|
6466
|
+
read: ["list_tables", "describe_columns", "list_indexes", "list_constraints", "list_extensions", "rls_status", "rls_policies", "list_auth_users", "get_auth_user", "connections", "stats", "slow_queries", "list_migrations", "migration_inventory", "project_url", "generate_types", "database_lint", "db_lint", "rpc_catalog", "list_rpcs"],
|
|
6467
6467
|
local: ["lint_migrations", "lint"],
|
|
6468
6468
|
write: ["query", "apply_migration", "push_migrations", "baseline_migrations", "create_table_rls"]
|
|
6469
6469
|
},
|
|
@@ -8090,7 +8090,11 @@ function registerDatabaseTools(server, http, config = {}) {
|
|
|
8090
8090
|
"list_migrations",
|
|
8091
8091
|
"migration_inventory",
|
|
8092
8092
|
"project_url",
|
|
8093
|
-
"generate_types"
|
|
8093
|
+
"generate_types",
|
|
8094
|
+
"database_lint",
|
|
8095
|
+
"db_lint",
|
|
8096
|
+
"rpc_catalog",
|
|
8097
|
+
"list_rpcs"
|
|
8094
8098
|
];
|
|
8095
8099
|
const writeActions = ["apply_migration", "push_migrations", "baseline_migrations", "create_table_rls"];
|
|
8096
8100
|
const remoteActions = [...readActions, ...localActions];
|
|
@@ -8103,13 +8107,13 @@ Actions: ${allActions.join(", ")}${localOnly ? " (local-only mode)" : readOnly ?
|
|
|
8103
8107
|
file: optional(Type.String(), "[query/apply_migration/lint_migrations/lint] Read SQL from local file path (avoids shell escaping issues with $$ and multi-statement DDL)"),
|
|
8104
8108
|
dir: optional(Type.String(), "[push_migrations/baseline_migrations/lint_migrations/lint] Directory containing .sql migration files (default: supabase/migrations)"),
|
|
8105
8109
|
dry_run: optional(Type.Boolean(), "[push_migrations/baseline_migrations] Preview changes without applying them"),
|
|
8106
|
-
strict: optional(Type.Boolean(), "[push_migrations/lint_migrations/lint] Exit with error if high-risk
|
|
8107
|
-
fail_on_high: optional(Type.Boolean(), "[push_migrations/lint_migrations/lint] Alias for --strict"),
|
|
8110
|
+
strict: optional(Type.Boolean(), "[push_migrations/lint_migrations/lint/database_lint] Exit with error if high-risk issues or migrations are detected"),
|
|
8111
|
+
fail_on_high: optional(Type.Boolean(), "[push_migrations/lint_migrations/lint/database_lint] Alias for --strict"),
|
|
8108
8112
|
fail_on_medium: optional(Type.Boolean(), "[push_migrations/lint_migrations/lint] Exit with error if medium-risk or high-risk migrations are detected"),
|
|
8109
|
-
json: optional(Type.Boolean(), "[lint_migrations/lint] Output structured JSON analysis"),
|
|
8110
|
-
schema: optional(Type.String(), "[describe_columns/list_indexes/list_constraints/rls_status/rls_policies/create_table_rls] Schema name (default: public)"),
|
|
8113
|
+
json: optional(Type.Boolean(), "[lint_migrations/lint/database_lint/rpc_catalog] Output structured JSON analysis"),
|
|
8114
|
+
schema: optional(Type.String(), "[describe_columns/list_indexes/list_constraints/rls_status/rls_policies/create_table_rls/database_lint] Schema name (default: public)"),
|
|
8111
8115
|
table: optional(Type.String(), "[describe_columns/indexes/constraints/rls_*] Table name"),
|
|
8112
|
-
schemas: optional(Type.Array(Type.String()), "[list_tables/generate_types] Schemas array"),
|
|
8116
|
+
schemas: optional(Type.Array(Type.String()), "[list_tables/generate_types/rpc_catalog] Schemas array"),
|
|
8113
8117
|
user_id: optional(Type.String(), "[get_auth_user] User UUID"),
|
|
8114
8118
|
limit: optional(Type.Number(), "[list_auth_users] Max users (default: 20)"),
|
|
8115
8119
|
name: optional(Type.String(), "[apply_migration] Migration name"),
|
|
@@ -8510,6 +8514,41 @@ ${riskReport}`
|
|
|
8510
8514
|
text = `✅ Table '${schema}.${args.table}' created with RLS (${policyMode === "owner" ? "auth.uid() owner policy" : "deny-all by default"})`;
|
|
8511
8515
|
break;
|
|
8512
8516
|
}
|
|
8517
|
+
case "database_lint":
|
|
8518
|
+
case "db_lint": {
|
|
8519
|
+
const targetSchema = args.schema || "public";
|
|
8520
|
+
const safeRef = projectRefPathSegment(ref, "database_lint");
|
|
8521
|
+
const r = await managementHttp().get(`/v1/projects/${safeRef}/database/linter?schema=${encodeURIComponent(targetSchema)}`);
|
|
8522
|
+
if (!r.ok) {
|
|
8523
|
+
return { content: [{ type: "text", text: `❌ Database lint request failed (${r.status})` }], isError: true };
|
|
8524
|
+
}
|
|
8525
|
+
if (args.json) {
|
|
8526
|
+
text = JSON.stringify(r.data, null, 2);
|
|
8527
|
+
} else {
|
|
8528
|
+
text = formatDatabaseLintReport(r.data);
|
|
8529
|
+
}
|
|
8530
|
+
const strict = args.strict === true || args.fail_on_high === true;
|
|
8531
|
+
const dangerCount = r.data?.danger_count || 0;
|
|
8532
|
+
if (strict && dangerCount > 0) {
|
|
8533
|
+
return { content: [{ type: "text", text }], isError: true };
|
|
8534
|
+
}
|
|
8535
|
+
break;
|
|
8536
|
+
}
|
|
8537
|
+
case "rpc_catalog":
|
|
8538
|
+
case "list_rpcs": {
|
|
8539
|
+
const schemasList = args.schemas && args.schemas.length > 0 ? args.schemas : args.schema ? [args.schema] : ["public", "api"];
|
|
8540
|
+
const safeRef = projectRefPathSegment(ref, "rpc_catalog");
|
|
8541
|
+
const r = await managementHttp().get(`/v1/projects/${safeRef}/database/rpc-catalog?schemas=${encodeURIComponent(schemasList.join(","))}`);
|
|
8542
|
+
if (!r.ok) {
|
|
8543
|
+
return { content: [{ type: "text", text: `❌ RPC catalog request failed (${r.status})` }], isError: true };
|
|
8544
|
+
}
|
|
8545
|
+
if (args.json) {
|
|
8546
|
+
text = JSON.stringify(r.data, null, 2);
|
|
8547
|
+
} else {
|
|
8548
|
+
text = formatRpcCatalog(r.data);
|
|
8549
|
+
}
|
|
8550
|
+
break;
|
|
8551
|
+
}
|
|
8513
8552
|
default:
|
|
8514
8553
|
text = `❌ Unknown action: ${action}`;
|
|
8515
8554
|
}
|
|
@@ -8552,6 +8591,53 @@ function buildRlsPolicySql(qualifiedTable, policyMode, ownerColumnValue) {
|
|
|
8552
8591
|
CREATE POLICY "SupaCloud owner update" ON ${qualifiedTable} FOR UPDATE TO authenticated USING (${predicate}) WITH CHECK (${predicate});
|
|
8553
8592
|
CREATE POLICY "SupaCloud owner delete" ON ${qualifiedTable} FOR DELETE TO authenticated USING (${predicate});`;
|
|
8554
8593
|
}
|
|
8594
|
+
function formatDatabaseLintReport(data) {
|
|
8595
|
+
if (!data || typeof data !== "object")
|
|
8596
|
+
return JSON.stringify(data, null, 2);
|
|
8597
|
+
const d = data;
|
|
8598
|
+
if (!d.issues || d.issues.length === 0) {
|
|
8599
|
+
return "✅ Database Lint: No issues found! Schema follows best practices for RLS, primary keys, and function security.";
|
|
8600
|
+
}
|
|
8601
|
+
const lines = [];
|
|
8602
|
+
const icon = (d.danger_count || 0) > 0 ? "\uD83D\uDD34" : (d.warning_count || 0) > 0 ? "\uD83D\uDFE1" : "ℹ️";
|
|
8603
|
+
lines.push(`${icon} Database Lint (${d.schema || "public"}): ${d.total_issues} issue(s) detected [${d.danger_count || 0} Danger, ${d.warning_count || 0} Warning, ${d.info_count || 0} Info]`);
|
|
8604
|
+
lines.push("");
|
|
8605
|
+
for (const issue of d.issues) {
|
|
8606
|
+
const itemIcon = issue.severity === "danger" ? "\uD83D\uDD34" : issue.severity === "warning" ? "\uD83D\uDFE1" : "ℹ️";
|
|
8607
|
+
lines.push(` ${itemIcon} [${issue.severity.toUpperCase()}] ${issue.schema_name}.${issue.object_name} (${issue.type})`);
|
|
8608
|
+
lines.push(` Detail: ${issue.detail}`);
|
|
8609
|
+
lines.push(` Recommendation: ${issue.recommendation}`);
|
|
8610
|
+
if (issue.fix_sql) {
|
|
8611
|
+
lines.push(` Fix SQL: ${issue.fix_sql}`);
|
|
8612
|
+
}
|
|
8613
|
+
lines.push("");
|
|
8614
|
+
}
|
|
8615
|
+
return lines.join(`
|
|
8616
|
+
`).trimEnd();
|
|
8617
|
+
}
|
|
8618
|
+
function formatRpcCatalog(data) {
|
|
8619
|
+
if (!data || typeof data !== "object")
|
|
8620
|
+
return JSON.stringify(data, null, 2);
|
|
8621
|
+
const d = data;
|
|
8622
|
+
if (!d.rpcs || d.rpcs.length === 0) {
|
|
8623
|
+
return `No RPC functions found in schema(s): ${(d.schemas || []).join(", ")}`;
|
|
8624
|
+
}
|
|
8625
|
+
const lines = [];
|
|
8626
|
+
lines.push(`\uD83D\uDCCB RPC Catalog (${d.total_rpcs || d.rpcs.length} total: ${d.commands || 0} commands, ${d.queries || 0} queries, ${d.internal || 0} internal)`);
|
|
8627
|
+
lines.push("");
|
|
8628
|
+
for (const rpc of d.rpcs) {
|
|
8629
|
+
const kindBadge = rpc.inferred_kind === "command" ? "⚡ [COMMAND]" : rpc.inferred_kind === "query" ? "\uD83D\uDD0D [QUERY]" : "\uD83D\uDD12 [INTERNAL]";
|
|
8630
|
+
const secBadge = rpc.security === "DEFINER" ? "\uD83D\uDEE1️ DEFINER" : "\uD83D\uDC64 INVOKER";
|
|
8631
|
+
lines.push(` ${kindBadge} ${rpc.schema_name}.${rpc.function_name}(${rpc.identity_args}) -> ${rpc.return_type}`);
|
|
8632
|
+
lines.push(` Security: ${secBadge} | Volatility: ${rpc.volatility}${rpc.search_path ? ` | search_path: ${rpc.search_path}` : ""}`);
|
|
8633
|
+
const tagEntries = Object.entries(rpc.smart_tags || {});
|
|
8634
|
+
if (tagEntries.length > 0) {
|
|
8635
|
+
lines.push(` Tags: ${tagEntries.map(([k, v]) => `@${k}${v === true ? "" : ` ${v}`}`).join(", ")}`);
|
|
8636
|
+
}
|
|
8637
|
+
}
|
|
8638
|
+
return lines.join(`
|
|
8639
|
+
`);
|
|
8640
|
+
}
|
|
8555
8641
|
function formatSqlResult(data) {
|
|
8556
8642
|
if (!data || typeof data !== "object")
|
|
8557
8643
|
return JSON.stringify(data, null, 2);
|
|
@@ -14869,7 +14955,7 @@ function registerReleaseTools(server, http, options = {}) {
|
|
|
14869
14955
|
// package.json
|
|
14870
14956
|
var package_default = {
|
|
14871
14957
|
name: "@supacloud/cli",
|
|
14872
|
-
version: "0.
|
|
14958
|
+
version: "0.35.0",
|
|
14873
14959
|
description: "Project-scoped CLI for SupaCloud users",
|
|
14874
14960
|
type: "module",
|
|
14875
14961
|
main: "./dist/index.js",
|