supatool 0.6.3 → 0.6.5

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.
@@ -885,7 +885,9 @@ async function generateCreateTableDDL(client, tableName, schemaName = 'public')
885
885
  SELECT column_name
886
886
  FROM information_schema.table_constraints tc
887
887
  JOIN information_schema.key_column_usage kcu
888
- ON tc.constraint_name = kcu.constraint_name
888
+ ON tc.constraint_catalog = kcu.constraint_catalog
889
+ AND tc.constraint_schema = kcu.constraint_schema
890
+ AND tc.constraint_name = kcu.constraint_name
889
891
  WHERE tc.table_schema = $1
890
892
  AND tc.table_name = $2
891
893
  AND tc.constraint_type = 'PRIMARY KEY'
@@ -919,7 +921,9 @@ async function generateCreateTableDDL(client, tableName, schemaName = 'public')
919
921
  string_agg(kcu.column_name, ', ' ORDER BY kcu.ordinal_position) as columns
920
922
  FROM information_schema.table_constraints tc
921
923
  JOIN information_schema.key_column_usage kcu
922
- ON tc.constraint_name = kcu.constraint_name
924
+ ON tc.constraint_catalog = kcu.constraint_catalog
925
+ AND tc.constraint_schema = kcu.constraint_schema
926
+ AND tc.constraint_name = kcu.constraint_name
923
927
  WHERE tc.table_schema = $1
924
928
  AND tc.table_name = $2
925
929
  AND tc.constraint_type = 'UNIQUE'
@@ -1360,7 +1364,7 @@ async function generateIndexFile(definitions, outputDir, separateDirectories = t
1360
1364
  }
1361
1365
  : undefined
1362
1366
  };
1363
- writeFileIfChanged(path.join(outputDir, 'schema_index.json'), JSON.stringify(schemaIndex, null, 2) + '\n');
1367
+ writeFileIfChanged(path.join(outputDir, 'schema_index.json'), JSON.stringify(schemaIndex, null, 2));
1364
1368
  // schema_summary.md (one-file overview for AI) — include RLS status per table
1365
1369
  let summaryMd = '# Schema summary\n\n';
1366
1370
  const tableDefs = definitions.filter(d => d.type === 'table' || d.type === 'view');
@@ -1396,6 +1400,7 @@ async function generateIndexFile(definitions, outputDir, separateDirectories = t
1396
1400
  writeFileIfChanged(path.join(outputDir, 'schema_summary.md'), summaryMd);
1397
1401
  // RLS disabled tables warning doc (tables only; RLS enabled with 0 policies is not warned)
1398
1402
  const rlsNotEnabled = tableRlsStatus.filter(s => !s.rlsEnabled);
1403
+ const rlsWarningsPath = path.join(outputDir, 'rls_warnings.md');
1399
1404
  if (rlsNotEnabled.length > 0) {
1400
1405
  let warnMd = '# Tables with RLS disabled (warning)\n\n';
1401
1406
  warnMd += 'The following tables do not have Row Level Security enabled.\n';
@@ -1404,7 +1409,11 @@ async function generateIndexFile(definitions, outputDir, separateDirectories = t
1404
1409
  rlsNotEnabled.forEach(s => {
1405
1410
  warnMd += `| ${s.schema} | ${s.table} |\n`;
1406
1411
  });
1407
- writeFileIfChanged(path.join(outputDir, 'rls_warnings.md'), warnMd);
1412
+ writeFileIfChanged(rlsWarningsPath, warnMd);
1413
+ }
1414
+ else if (fs.existsSync(rlsWarningsPath)) {
1415
+ // All RLS issues resolved — remove stale warning file
1416
+ fs.unlinkSync(rlsWarningsPath);
1408
1417
  }
1409
1418
  }
1410
1419
  /**
@@ -1536,7 +1545,10 @@ async function extractDefinitions(options) {
1536
1545
  cronJobs: { current: 0, total: 0 },
1537
1546
  customTypes: { current: 0, total: 0 }
1538
1547
  };
1539
- if (all) {
1548
+ // --schema-only implies full extraction of all object types for the target schema,
1549
+ // so that --force does not incorrectly delete rpc/cron/types files.
1550
+ const effectiveAll = all || schemaOnly;
1551
+ if (effectiveAll) {
1540
1552
  // Get total count for each object type first
1541
1553
  spinner.text = 'Counting database objects...';
1542
1554
  // Get total tables/views count
@@ -1598,7 +1610,7 @@ async function extractDefinitions(options) {
1598
1610
  AND t.typname NOT LIKE '_%'
1599
1611
  `);
1600
1612
  progress.customTypes.total = parseInt(typesCountResult.rows[0].count);
1601
- // When --all: fetch all objects (sequential)
1613
+ // When --all / --schema-only: fetch all objects (sequential)
1602
1614
  const tables = await fetchTableDefinitions(client, spinner, progress, schemas);
1603
1615
  const rlsPolicies = await fetchRlsPolicies(client, spinner, progress, schemas);
1604
1616
  const functions = await fetchFunctions(client, spinner, progress, schemas);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "supatool",
3
- "version": "0.6.3",
3
+ "version": "0.6.5",
4
4
  "description": "CLI for PostgreSQL (Cloud SQL / Supabase): extract schema to files, deploy schema diffs, apply migrations, seed export.",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",
@@ -9,7 +9,7 @@
9
9
  },
10
10
  "scripts": {
11
11
  "build": "tsc",
12
- "test": "npm run build && node test/smoke.js",
12
+ "test": "npm run build && node test/smoke.js && node test/definition-extractor.js",
13
13
  "start": "tsx src/bin/supatool.ts",
14
14
  "local": "tsx src/bin/supatool.ts"
15
15
  },