supatool 0.4.2 → 0.4.3
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/sync/definitionExtractor.js +38 -16
- package/package.json +1 -1
|
@@ -355,6 +355,26 @@ async function fetchFunctions(client, spinner, progress, schemas = ['public']) {
|
|
|
355
355
|
timestamp: Math.floor(Date.now() / 1000)
|
|
356
356
|
});
|
|
357
357
|
}
|
|
358
|
+
// Detect overloaded functions (same schema.name, different signatures)
|
|
359
|
+
const nameCount = new Map();
|
|
360
|
+
for (const row of result.rows) {
|
|
361
|
+
const key = `${row.schema_name}.${row.name}`;
|
|
362
|
+
const sig = `${row.name}(${row.identity_args || ''})`;
|
|
363
|
+
if (!nameCount.has(key))
|
|
364
|
+
nameCount.set(key, []);
|
|
365
|
+
nameCount.get(key).push(sig);
|
|
366
|
+
}
|
|
367
|
+
const overloads = [...nameCount.entries()].filter(([, sigs]) => sigs.length > 1);
|
|
368
|
+
if (overloads.length > 0) {
|
|
369
|
+
console.warn('\n⚠ Overloaded RPC functions detected (same name, different signatures):');
|
|
370
|
+
for (const [key, sigs] of overloads) {
|
|
371
|
+
console.warn(` ${key}`);
|
|
372
|
+
for (const sig of sigs) {
|
|
373
|
+
console.warn(` - ${sig}`);
|
|
374
|
+
}
|
|
375
|
+
}
|
|
376
|
+
console.warn(' Note: Only the last definition will be written to the output file.\n');
|
|
377
|
+
}
|
|
358
378
|
return functions;
|
|
359
379
|
}
|
|
360
380
|
/**
|
|
@@ -843,19 +863,21 @@ async function generateCreateTableDDL(client, tableName, schemaName = 'public')
|
|
|
843
863
|
const [columnsResult, primaryKeyResult, tableCommentResult, columnCommentsResult, uniqueConstraintResult, foreignKeyResult] = await Promise.all([
|
|
844
864
|
// Get column info
|
|
845
865
|
client.query(`
|
|
846
|
-
SELECT
|
|
866
|
+
SELECT
|
|
847
867
|
c.column_name,
|
|
848
868
|
c.data_type,
|
|
849
869
|
c.udt_name,
|
|
850
870
|
c.character_maximum_length,
|
|
851
871
|
c.is_nullable,
|
|
852
872
|
c.column_default,
|
|
873
|
+
c.is_generated,
|
|
874
|
+
c.generation_expression,
|
|
853
875
|
pg_catalog.format_type(a.atttypid, a.atttypmod) AS full_type
|
|
854
876
|
FROM information_schema.columns c
|
|
855
877
|
JOIN pg_class cl ON cl.relname = c.table_name
|
|
856
878
|
JOIN pg_namespace ns ON ns.nspname = c.table_schema AND ns.oid = cl.relnamespace
|
|
857
879
|
JOIN pg_attribute a ON a.attrelid = cl.oid AND a.attname = c.column_name
|
|
858
|
-
WHERE c.table_schema = $1
|
|
880
|
+
WHERE c.table_schema = $1
|
|
859
881
|
AND c.table_name = $2
|
|
860
882
|
ORDER BY c.ordinal_position
|
|
861
883
|
`, [schemaName, tableName]),
|
|
@@ -951,13 +973,19 @@ async function generateCreateTableDDL(client, tableName, schemaName = 'public')
|
|
|
951
973
|
if (col.character_maximum_length) {
|
|
952
974
|
colDef += `(${col.character_maximum_length})`;
|
|
953
975
|
}
|
|
954
|
-
//
|
|
955
|
-
if (col.
|
|
956
|
-
colDef +=
|
|
976
|
+
// Generated column
|
|
977
|
+
if (col.is_generated === 'ALWAYS') {
|
|
978
|
+
colDef += ` GENERATED ALWAYS AS (${col.generation_expression}) STORED`;
|
|
957
979
|
}
|
|
958
|
-
|
|
959
|
-
|
|
960
|
-
|
|
980
|
+
else {
|
|
981
|
+
// NOT NULL constraint
|
|
982
|
+
if (col.is_nullable === 'NO') {
|
|
983
|
+
colDef += ' NOT NULL';
|
|
984
|
+
}
|
|
985
|
+
// Default value
|
|
986
|
+
if (col.column_default) {
|
|
987
|
+
colDef += ` DEFAULT ${col.column_default}`;
|
|
988
|
+
}
|
|
961
989
|
}
|
|
962
990
|
columnDefs.push(colDef);
|
|
963
991
|
}
|
|
@@ -1109,13 +1137,7 @@ async function saveDefinitionsByType(definitions, outputDir, separateDirectories
|
|
|
1109
1137
|
if (!fs.existsSync(targetDir)) {
|
|
1110
1138
|
fs.mkdirSync(targetDir, { recursive: true });
|
|
1111
1139
|
}
|
|
1112
|
-
|
|
1113
|
-
if (def.type === 'function') {
|
|
1114
|
-
fileName = `fn_${def.name}.sql`;
|
|
1115
|
-
}
|
|
1116
|
-
else {
|
|
1117
|
-
fileName = `${def.name}.sql`;
|
|
1118
|
-
}
|
|
1140
|
+
const fileName = `${def.name}.sql`;
|
|
1119
1141
|
const filePath = path.join(targetDir, fileName);
|
|
1120
1142
|
const ddlWithNewline = def.ddl.endsWith('\n') ? def.ddl : def.ddl + '\n';
|
|
1121
1143
|
await fsPromises.writeFile(filePath, headerComment + ddlWithNewline);
|
|
@@ -1175,7 +1197,7 @@ async function generateIndexFile(definitions, outputDir, separateDirectories = t
|
|
|
1175
1197
|
// Build relative path per file (schema/type/file when multiSchema)
|
|
1176
1198
|
const getRelPath = (def) => {
|
|
1177
1199
|
const typeDir = separateDirectories ? (typeDirNames[def.type] ?? def.type) : '.';
|
|
1178
|
-
const fileName =
|
|
1200
|
+
const fileName = `${def.name}.sql`;
|
|
1179
1201
|
if (multiSchema && def.schema) {
|
|
1180
1202
|
return `${def.schema}/${typeDir}/${fileName}`;
|
|
1181
1203
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "supatool",
|
|
3
|
-
"version": "0.4.
|
|
3
|
+
"version": "0.4.3",
|
|
4
4
|
"description": "CLI for Supabase: extract schema (tables, views, RLS, RPC) to files + llms.txt for LLM, deploy local schema, seed export. CRUD code gen deprecated.",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"types": "dist/index.d.ts",
|