nexusql 0.6.2 → 0.7.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/README.md +19 -14
- package/dist/cli.js +46 -16
- package/dist/cli.js.map +1 -1
- package/dist/index.d.ts +5 -1
- package/dist/index.js +41 -14
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.d.ts
CHANGED
|
@@ -186,6 +186,7 @@ interface MigraResult {
|
|
|
186
186
|
*/
|
|
187
187
|
declare function runMigra(fromUrl: string, toUrl: string, options?: {
|
|
188
188
|
unsafe?: boolean;
|
|
189
|
+
schemas?: string[];
|
|
189
190
|
}): MigraResult;
|
|
190
191
|
/**
|
|
191
192
|
* Filter out schema_migrations table from migration SQL.
|
|
@@ -193,10 +194,13 @@ declare function runMigra(fromUrl: string, toUrl: string, options?: {
|
|
|
193
194
|
declare function filterSchemaMigrations(sql: string): string;
|
|
194
195
|
|
|
195
196
|
interface NexusqlConfig {
|
|
196
|
-
|
|
197
|
+
dbmlFile: string;
|
|
198
|
+
/** @deprecated Use dbmlFile instead */
|
|
199
|
+
schema?: string;
|
|
197
200
|
migrations: string;
|
|
198
201
|
extensions: string[];
|
|
199
202
|
databaseUrl?: string;
|
|
203
|
+
targetDbSchemas?: string[];
|
|
200
204
|
}
|
|
201
205
|
/**
|
|
202
206
|
* Load configuration from nexusql.config.js or defaults.
|
package/dist/index.js
CHANGED
|
@@ -2109,6 +2109,11 @@ function runMigra(fromUrl, toUrl, options = {}) {
|
|
|
2109
2109
|
if (options.unsafe) {
|
|
2110
2110
|
args.push("--unsafe");
|
|
2111
2111
|
}
|
|
2112
|
+
if (options.schemas?.length) {
|
|
2113
|
+
for (const schema of options.schemas) {
|
|
2114
|
+
args.push("--schema", schema);
|
|
2115
|
+
}
|
|
2116
|
+
}
|
|
2112
2117
|
try {
|
|
2113
2118
|
const output = execFileSync("migra", args, {
|
|
2114
2119
|
encoding: "utf-8",
|
|
@@ -2136,9 +2141,10 @@ import { join as join2 } from "path";
|
|
|
2136
2141
|
import { pathToFileURL } from "url";
|
|
2137
2142
|
import { config as loadDotenv } from "dotenv";
|
|
2138
2143
|
var DEFAULT_CONFIG = {
|
|
2139
|
-
|
|
2144
|
+
dbmlFile: "./schema.dbml",
|
|
2140
2145
|
migrations: "./db/migrations",
|
|
2141
|
-
extensions: ["uuid-ossp"]
|
|
2146
|
+
extensions: ["uuid-ossp"],
|
|
2147
|
+
targetDbSchemas: ["public"]
|
|
2142
2148
|
};
|
|
2143
2149
|
async function loadConfig(cwd = process.cwd()) {
|
|
2144
2150
|
loadDotenv();
|
|
@@ -2152,30 +2158,42 @@ async function loadConfig(cwd = process.cwd()) {
|
|
|
2152
2158
|
} catch {
|
|
2153
2159
|
}
|
|
2154
2160
|
}
|
|
2155
|
-
|
|
2161
|
+
const finalConfig = {
|
|
2156
2162
|
...DEFAULT_CONFIG,
|
|
2157
2163
|
...userConfig,
|
|
2158
2164
|
databaseUrl: process.env.DATABASE_URL || userConfig.databaseUrl
|
|
2159
2165
|
};
|
|
2166
|
+
if (userConfig.schema && !userConfig.dbmlFile) {
|
|
2167
|
+
console.warn(
|
|
2168
|
+
"Warning: 'schema' config option is deprecated. Use 'dbmlFile' instead."
|
|
2169
|
+
);
|
|
2170
|
+
finalConfig.dbmlFile = userConfig.schema;
|
|
2171
|
+
}
|
|
2172
|
+
return finalConfig;
|
|
2160
2173
|
}
|
|
2161
2174
|
function getDatabaseUrl(config) {
|
|
2162
2175
|
const url = config.databaseUrl || process.env.DATABASE_URL;
|
|
2163
2176
|
if (!url) {
|
|
2164
|
-
throw new Error(
|
|
2177
|
+
throw new Error(
|
|
2178
|
+
"DATABASE_URL not set. Set it in .env or nexusql.config.js"
|
|
2179
|
+
);
|
|
2165
2180
|
}
|
|
2166
2181
|
return url;
|
|
2167
2182
|
}
|
|
2168
2183
|
function generateConfigTemplate() {
|
|
2169
2184
|
return `/** @type {import('nexusql').NexusqlConfig} */
|
|
2170
|
-
|
|
2185
|
+
module.exports = {
|
|
2171
2186
|
// Path to your DBML schema file
|
|
2172
|
-
|
|
2187
|
+
dbmlFile: './schema.dbml',
|
|
2173
2188
|
|
|
2174
2189
|
// Directory for migration files
|
|
2175
2190
|
migrations: './db/migrations',
|
|
2176
2191
|
|
|
2177
2192
|
// PostgreSQL extensions to install in temp database
|
|
2178
2193
|
extensions: ['uuid-ossp'],
|
|
2194
|
+
|
|
2195
|
+
// Restrict to specific PostgreSQL schemas (optional, default: ['public'])
|
|
2196
|
+
// targetDbSchemas: ['public'],
|
|
2179
2197
|
};
|
|
2180
2198
|
`;
|
|
2181
2199
|
}
|
|
@@ -3563,7 +3581,7 @@ async function gen(options = {}) {
|
|
|
3563
3581
|
const db = new Database(databaseUrl);
|
|
3564
3582
|
const spinner = ora();
|
|
3565
3583
|
spinner.start("Reading DBML schema...");
|
|
3566
|
-
const schemaPath = resolve(config.
|
|
3584
|
+
const schemaPath = resolve(config.dbmlFile);
|
|
3567
3585
|
let dbmlContent;
|
|
3568
3586
|
try {
|
|
3569
3587
|
dbmlContent = readFileSync2(schemaPath, "utf-8");
|
|
@@ -3599,10 +3617,17 @@ async function gen(options = {}) {
|
|
|
3599
3617
|
Tables in temp database: ${tables.join(", ")}`));
|
|
3600
3618
|
}
|
|
3601
3619
|
spinner.start("Generating migration diff...");
|
|
3620
|
+
const targetDbSchemas = config.targetDbSchemas;
|
|
3621
|
+
if (targetDbSchemas?.length) {
|
|
3622
|
+
console.log(
|
|
3623
|
+
source_default.dim(`
|
|
3624
|
+
Restricting to schemas: ${targetDbSchemas.join(", ")}`)
|
|
3625
|
+
);
|
|
3626
|
+
}
|
|
3602
3627
|
const migraResult = runMigra(
|
|
3603
3628
|
db.getConnectionUrl(),
|
|
3604
3629
|
tempDb.getConnectionUrl(),
|
|
3605
|
-
{ unsafe: true }
|
|
3630
|
+
{ unsafe: true, schemas: targetDbSchemas }
|
|
3606
3631
|
);
|
|
3607
3632
|
migrationSql = filterSchemaMigrations(migraResult.sql);
|
|
3608
3633
|
if (migraResult.hasChanges) {
|
|
@@ -3611,7 +3636,8 @@ Tables in temp database: ${tables.join(", ")}`));
|
|
|
3611
3636
|
spinner.info("No schema changes detected");
|
|
3612
3637
|
}
|
|
3613
3638
|
spinner.start("Checking comment changes...");
|
|
3614
|
-
|
|
3639
|
+
spinner.start("Checking comment changes...");
|
|
3640
|
+
const commentSql = await getCommentChanges(db, tempDb, targetDbSchemas);
|
|
3615
3641
|
if (commentSql) {
|
|
3616
3642
|
migrationSql = migrationSql ? `${migrationSql}
|
|
3617
3643
|
|
|
@@ -3625,8 +3651,8 @@ ${commentSql}`;
|
|
|
3625
3651
|
try {
|
|
3626
3652
|
await db.dropDatabase(tempDbName);
|
|
3627
3653
|
spinner.succeed("Cleaned up temp database");
|
|
3628
|
-
} catch {
|
|
3629
|
-
spinner.warn(
|
|
3654
|
+
} catch (error) {
|
|
3655
|
+
spinner.warn(`Failed to cleanup temp database: ${error}`);
|
|
3630
3656
|
}
|
|
3631
3657
|
}
|
|
3632
3658
|
const finalSql = migrationSql || "-- No changes detected";
|
|
@@ -3640,7 +3666,8 @@ Migration SQL written to: ${options.output}`));
|
|
|
3640
3666
|
}
|
|
3641
3667
|
return finalSql;
|
|
3642
3668
|
}
|
|
3643
|
-
async function getCommentChanges(currentDb, targetDb) {
|
|
3669
|
+
async function getCommentChanges(currentDb, targetDb, schemas) {
|
|
3670
|
+
const schemaFilter = schemas && schemas.length > 0 ? `AND c.table_schema IN (${schemas.map((s) => `'${s}'`).join(", ")})` : "";
|
|
3644
3671
|
const commentQuery = `
|
|
3645
3672
|
SELECT
|
|
3646
3673
|
format('COMMENT ON COLUMN %I.%I IS %L;',
|
|
@@ -3655,8 +3682,8 @@ async function getCommentChanges(currentDb, targetDb) {
|
|
|
3655
3682
|
JOIN pg_catalog.pg_class pc ON pc.relname = c.table_name
|
|
3656
3683
|
JOIN pg_catalog.pg_namespace pn ON pn.oid = pc.relnamespace AND pn.nspname = c.table_schema
|
|
3657
3684
|
LEFT JOIN pg_catalog.pg_description pgd ON pgd.objoid = pc.oid AND pgd.objsubid = c.ordinal_position
|
|
3658
|
-
WHERE c.
|
|
3659
|
-
|
|
3685
|
+
WHERE c.table_name != 'schema_migrations'
|
|
3686
|
+
${schemaFilter}
|
|
3660
3687
|
ORDER BY c.table_name, c.ordinal_position;
|
|
3661
3688
|
`;
|
|
3662
3689
|
const [currentComments, targetComments] = await Promise.all([
|