@supacloud/cli 0.113.0 → 0.114.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 CHANGED
@@ -9281,7 +9281,7 @@ var ACTION_POLICY = {
9281
9281
  local: ["list"]
9282
9282
  },
9283
9283
  database: {
9284
- read: ["list_tables", "describe_columns", "list_indexes", "list_constraints", "list_extensions", "extension_catalog", "rls_status", "rls_policies", "list_auth_users", "get_auth_user", "connections", "stats", "slow_queries", "list_migrations", "migration_inventory", "migration_import", "delivery_migration_plan", "project_url", "generate_types", "database_lint", "db_lint", "rpc_catalog", "list_rpcs"],
9284
+ read: ["list_tables", "describe_columns", "export_svadmin_schema", "list_indexes", "list_constraints", "list_extensions", "extension_catalog", "rls_status", "rls_policies", "list_auth_users", "get_auth_user", "connections", "stats", "slow_queries", "list_migrations", "migration_inventory", "migration_import", "delivery_migration_plan", "project_url", "generate_types", "database_lint", "db_lint", "rpc_catalog", "list_rpcs"],
9285
9285
  local: ["lint_migrations", "lint", "rebase_migrations"],
9286
9286
  write: ["query", "execute", "apply_migration", "push_migrations", "baseline_migrations", "create_table_rls", "enable_extension", "disable_extension"]
9287
9287
  },
@@ -12909,6 +12909,7 @@ function registerDatabaseTools(server, http, config = {}) {
12909
12909
  "query",
12910
12910
  "list_tables",
12911
12911
  "describe_columns",
12912
+ "export_svadmin_schema",
12912
12913
  "list_indexes",
12913
12914
  "list_constraints",
12914
12915
  "list_extensions",
@@ -13105,6 +13106,34 @@ Actions: ${allActions.join(", ")}${localOnly ? " (local-only mode)" : readOnly ?
13105
13106
  text = r.ok ? formatColumnsList(r.data, schema, args.table) : `❌ Failed (${r.status})`;
13106
13107
  break;
13107
13108
  }
13109
+ case "export_svadmin_schema": {
13110
+ if (!args.table)
13111
+ throw new Error("'table' required");
13112
+ const schemaLiteral = sqlStringLiteral(schema, "schema");
13113
+ const tableLiteral = sqlStringLiteral(args.table, "table");
13114
+ const qualifiedTable = `${quoteIdentifier(schema, "schema")}.${quoteIdentifier(args.table, "table")}`;
13115
+ const colSql = `SELECT column_name, data_type, is_nullable, column_default, character_maximum_length FROM information_schema.columns WHERE table_schema = ${schemaLiteral} AND table_name = ${tableLiteral} ORDER BY ordinal_position;`;
13116
+ const colRes = await execSql(colSql);
13117
+ if (!colRes.ok)
13118
+ throw new Error(`Failed to inspect columns (${colRes.status})`);
13119
+ const conSql = `SELECT conname as name, contype as type, pg_get_constraintdef(oid) as definition FROM pg_constraint WHERE connamespace = ${schemaLiteral}::regnamespace AND conrelid = ${qualifiedTable}::regclass;`;
13120
+ const conRes = await execSql(conSql);
13121
+ const cols = buildSvadminColumns(colRes.data, conRes.ok ? conRes.data : []);
13122
+ if (args.json) {
13123
+ return {
13124
+ content: [{
13125
+ type: "text",
13126
+ text: JSON.stringify({
13127
+ resource: args.table,
13128
+ sourceType: "databaseColumns",
13129
+ columns: cols
13130
+ }, null, 2)
13131
+ }]
13132
+ };
13133
+ }
13134
+ text = formatSvadminSchemaExport(args.table, cols);
13135
+ break;
13136
+ }
13108
13137
  case "list_indexes": {
13109
13138
  if (!args.table)
13110
13139
  throw new Error("'table' required");
@@ -13538,10 +13567,16 @@ ${riskReport}`
13538
13567
  });
13539
13568
  }
13540
13569
  function quoteIdentifier(value, label) {
13570
+ return `"${validatedIdentifier(value, label)}"`;
13571
+ }
13572
+ function sqlStringLiteral(value, label) {
13573
+ return `'${validatedIdentifier(value, label)}'`;
13574
+ }
13575
+ function validatedIdentifier(value, label) {
13541
13576
  if (typeof value !== "string" || !/^[A-Za-z_][A-Za-z0-9_]{0,62}$/.test(value)) {
13542
13577
  throw new Error(`Invalid ${label} identifier`);
13543
13578
  }
13544
- return `"${value}"`;
13579
+ return value;
13545
13580
  }
13546
13581
  function validateColumnDefinitions(value) {
13547
13582
  if (typeof value !== "string")
@@ -13713,6 +13748,67 @@ function formatConstraintList(data) {
13713
13748
  `).join(`
13714
13749
  `);
13715
13750
  }
13751
+ function buildSvadminColumns(colData, conData) {
13752
+ const colRows = responseRows(colData, _Object_({
13753
+ column_name: String2(),
13754
+ data_type: String2(),
13755
+ is_nullable: String2(),
13756
+ character_maximum_length: Optional(Union([Number2(), Null()])),
13757
+ column_default: Optional(Union([String2(), Null()]))
13758
+ }));
13759
+ const conRows = responseRows(conData, _Object_({
13760
+ name: String2(),
13761
+ type: String2(),
13762
+ definition: String2()
13763
+ }));
13764
+ const pkConstraint = conRows.find((c) => c.type === "p");
13765
+ const pkCols = new Set;
13766
+ if (pkConstraint) {
13767
+ const match = pkConstraint.definition.match(/\(([^)]+)\)/);
13768
+ if (match?.[1]) {
13769
+ match[1].split(",").map((s) => s.trim().replace(/"/g, "")).forEach((c) => pkCols.add(c));
13770
+ }
13771
+ }
13772
+ const fkMap = new Map;
13773
+ for (const c of conRows) {
13774
+ if (c.type === "f") {
13775
+ const match = c.definition.match(/FOREIGN KEY\s*\(([^)]+)\)\s*REFERENCES\s*([^(]+)/i);
13776
+ if (match?.[1] && match?.[2]) {
13777
+ const colName = match[1].trim().replace(/"/g, "");
13778
+ const refTable = match[2].trim().split(".").pop()?.replace(/"/g, "") ?? "";
13779
+ fkMap.set(colName, refTable);
13780
+ }
13781
+ }
13782
+ }
13783
+ return colRows.map((c) => {
13784
+ const isPrimary = pkCols.has(c.column_name) || c.column_name === "id";
13785
+ const ref = fkMap.get(c.column_name);
13786
+ return {
13787
+ name: c.column_name,
13788
+ type: c.data_type,
13789
+ nullable: c.is_nullable === "YES",
13790
+ isPrimary,
13791
+ ...c.column_default ? { defaultValue: c.column_default } : {},
13792
+ isForeignKey: Boolean(ref || c.column_name.endsWith("_id")),
13793
+ ...ref ? { referencesResource: ref } : {}
13794
+ };
13795
+ });
13796
+ }
13797
+ function formatSvadminSchemaExport(table, columns) {
13798
+ const jsonPayload = JSON.stringify(columns, null, 2);
13799
+ return `\uD83D\uDE80 SVAdmin Schema Definition for '${table}'
13800
+
13801
+ ` + `Pass this payload directly to svadmin_generateResource to produce complete UI components:
13802
+ ` + ` svadmin_generateResource({
13803
+ ` + ` resource: '${table}',
13804
+ ` + ` sourceType: 'databaseColumns',
13805
+ ` + ` payload: ${JSON.stringify(jsonPayload)}
13806
+ ` + ` })
13807
+
13808
+ ` + `Column Metadata (${columns.length} columns):
13809
+ ` + columns.map((c) => ` - ${c.name}: ${c.type}${c.isPrimary ? " [PK]" : ""}${c.isForeignKey ? ` [FK -> ${c.referencesResource ?? "inferred"}]` : ""}${c.nullable ? " (nullable)" : " (required)"}`).join(`
13810
+ `);
13811
+ }
13716
13812
  function formatExtensionList(data) {
13717
13813
  const rows = responseRows(data, _Object_({ name: String2(), version: String2(), schema: String2() }));
13718
13814
  if (!rows.length)
@@ -21995,7 +22091,7 @@ var starter_metadata_default = {
21995
22091
  generatedBy: "supacloud/starter-metadata-v1",
21996
22092
  packages: {
21997
22093
  compiler: {
21998
- version: "0.53.0"
22094
+ version: "0.53.1"
21999
22095
  },
22000
22096
  app: {
22001
22097
  version: "0.35.0",
@@ -33631,7 +33727,7 @@ async function runProjectDeployment(http, args) {
33631
33727
  // package.json
33632
33728
  var package_default = {
33633
33729
  name: "@supacloud/cli",
33634
- version: "0.113.0",
33730
+ version: "0.114.0",
33635
33731
  description: "Project-scoped CLI for SupaCloud users",
33636
33732
  type: "module",
33637
33733
  main: "./dist/index.js",
@@ -33683,7 +33779,7 @@ var package_default = {
33683
33779
  directory: "packages/cli"
33684
33780
  },
33685
33781
  dependencies: {
33686
- "@supacloud/compiler": "^0.53.0",
33782
+ "@supacloud/compiler": "^0.53.1",
33687
33783
  "@supacloud/delivery": "0.24.0",
33688
33784
  "@supacloud/db": "0.20.3",
33689
33785
  typebox: "1.4.3"
@@ -11,3 +11,14 @@ export declare function vectorWarningsForPendingMigrations(migrations: Array<{
11
11
  sql: string;
12
12
  }>, vectorEnabled: boolean | null): string[];
13
13
  export declare function registerDatabaseTools(server: ToolServer, http: HttpTransport | undefined, config?: DatabaseToolsConfig): void;
14
+ export interface SvadminColumnMeta {
15
+ name: string;
16
+ type: string;
17
+ nullable: boolean;
18
+ isPrimary: boolean;
19
+ defaultValue?: string | null;
20
+ isForeignKey: boolean;
21
+ referencesResource?: string;
22
+ }
23
+ export declare function buildSvadminColumns(colData: unknown, conData: unknown): SvadminColumnMeta[];
24
+ export declare function formatSvadminSchemaExport(table: string, columns: SvadminColumnMeta[]): string;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@supacloud/cli",
3
- "version": "0.113.0",
3
+ "version": "0.114.0",
4
4
  "description": "Project-scoped CLI for SupaCloud users",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
@@ -52,7 +52,7 @@
52
52
  "directory": "packages/cli"
53
53
  },
54
54
  "dependencies": {
55
- "@supacloud/compiler": "^0.53.0",
55
+ "@supacloud/compiler": "^0.53.1",
56
56
  "@supacloud/delivery": "0.24.0",
57
57
  "@supacloud/db": "0.20.3",
58
58
  "typebox": "1.4.3"