nexusql 0.6.2 → 0.8.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.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
- schema: string;
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
@@ -1793,6 +1793,12 @@ var Database = class _Database {
1793
1793
  * Drop a database if it exists.
1794
1794
  */
1795
1795
  async dropDatabase(name) {
1796
+ await this.exec(`
1797
+ SELECT pg_terminate_backend(pg_stat_activity.pid)
1798
+ FROM pg_stat_activity
1799
+ WHERE pg_stat_activity.datname = '${name}'
1800
+ AND pid <> pg_backend_pid();
1801
+ `);
1796
1802
  await this.exec(`DROP DATABASE IF EXISTS "${name}";`);
1797
1803
  }
1798
1804
  /**
@@ -2109,6 +2115,11 @@ function runMigra(fromUrl, toUrl, options = {}) {
2109
2115
  if (options.unsafe) {
2110
2116
  args.push("--unsafe");
2111
2117
  }
2118
+ if (options.schemas?.length) {
2119
+ for (const schema of options.schemas) {
2120
+ args.push("--schema", schema);
2121
+ }
2122
+ }
2112
2123
  try {
2113
2124
  const output = execFileSync("migra", args, {
2114
2125
  encoding: "utf-8",
@@ -2136,9 +2147,10 @@ import { join as join2 } from "path";
2136
2147
  import { pathToFileURL } from "url";
2137
2148
  import { config as loadDotenv } from "dotenv";
2138
2149
  var DEFAULT_CONFIG = {
2139
- schema: "./schema.dbml",
2150
+ dbmlFile: "./schema.dbml",
2140
2151
  migrations: "./db/migrations",
2141
- extensions: ["uuid-ossp"]
2152
+ extensions: ["uuid-ossp"],
2153
+ targetDbSchemas: ["public"]
2142
2154
  };
2143
2155
  async function loadConfig(cwd = process.cwd()) {
2144
2156
  loadDotenv();
@@ -2152,30 +2164,42 @@ async function loadConfig(cwd = process.cwd()) {
2152
2164
  } catch {
2153
2165
  }
2154
2166
  }
2155
- return {
2167
+ const finalConfig = {
2156
2168
  ...DEFAULT_CONFIG,
2157
2169
  ...userConfig,
2158
2170
  databaseUrl: process.env.DATABASE_URL || userConfig.databaseUrl
2159
2171
  };
2172
+ if (userConfig.schema && !userConfig.dbmlFile) {
2173
+ console.warn(
2174
+ "Warning: 'schema' config option is deprecated. Use 'dbmlFile' instead."
2175
+ );
2176
+ finalConfig.dbmlFile = userConfig.schema;
2177
+ }
2178
+ return finalConfig;
2160
2179
  }
2161
2180
  function getDatabaseUrl(config) {
2162
2181
  const url = config.databaseUrl || process.env.DATABASE_URL;
2163
2182
  if (!url) {
2164
- throw new Error("DATABASE_URL not set. Set it in .env or nexusql.config.js");
2183
+ throw new Error(
2184
+ "DATABASE_URL not set. Set it in .env or nexusql.config.js"
2185
+ );
2165
2186
  }
2166
2187
  return url;
2167
2188
  }
2168
2189
  function generateConfigTemplate() {
2169
2190
  return `/** @type {import('nexusql').NexusqlConfig} */
2170
- export default {
2191
+ module.exports = {
2171
2192
  // Path to your DBML schema file
2172
- schema: './schema.dbml',
2193
+ dbmlFile: './schema.dbml',
2173
2194
 
2174
2195
  // Directory for migration files
2175
2196
  migrations: './db/migrations',
2176
2197
 
2177
2198
  // PostgreSQL extensions to install in temp database
2178
2199
  extensions: ['uuid-ossp'],
2200
+
2201
+ // Restrict to specific PostgreSQL schemas (optional, default: ['public'])
2202
+ // targetDbSchemas: ['public'],
2179
2203
  };
2180
2204
  `;
2181
2205
  }
@@ -3563,7 +3587,7 @@ async function gen(options = {}) {
3563
3587
  const db = new Database(databaseUrl);
3564
3588
  const spinner = ora();
3565
3589
  spinner.start("Reading DBML schema...");
3566
- const schemaPath = resolve(config.schema);
3590
+ const schemaPath = resolve(config.dbmlFile);
3567
3591
  let dbmlContent;
3568
3592
  try {
3569
3593
  dbmlContent = readFileSync2(schemaPath, "utf-8");
@@ -3599,10 +3623,17 @@ async function gen(options = {}) {
3599
3623
  Tables in temp database: ${tables.join(", ")}`));
3600
3624
  }
3601
3625
  spinner.start("Generating migration diff...");
3626
+ const targetDbSchemas = config.targetDbSchemas;
3627
+ if (targetDbSchemas?.length) {
3628
+ console.log(
3629
+ source_default.dim(`
3630
+ Restricting to schemas: ${targetDbSchemas.join(", ")}`)
3631
+ );
3632
+ }
3602
3633
  const migraResult = runMigra(
3603
3634
  db.getConnectionUrl(),
3604
3635
  tempDb.getConnectionUrl(),
3605
- { unsafe: true }
3636
+ { unsafe: true, schemas: targetDbSchemas }
3606
3637
  );
3607
3638
  migrationSql = filterSchemaMigrations(migraResult.sql);
3608
3639
  if (migraResult.hasChanges) {
@@ -3611,7 +3642,8 @@ Tables in temp database: ${tables.join(", ")}`));
3611
3642
  spinner.info("No schema changes detected");
3612
3643
  }
3613
3644
  spinner.start("Checking comment changes...");
3614
- const commentSql = await getCommentChanges(db, tempDb);
3645
+ spinner.start("Checking comment changes...");
3646
+ const commentSql = await getCommentChanges(db, tempDb, targetDbSchemas);
3615
3647
  if (commentSql) {
3616
3648
  migrationSql = migrationSql ? `${migrationSql}
3617
3649
 
@@ -3625,8 +3657,8 @@ ${commentSql}`;
3625
3657
  try {
3626
3658
  await db.dropDatabase(tempDbName);
3627
3659
  spinner.succeed("Cleaned up temp database");
3628
- } catch {
3629
- spinner.warn("Failed to cleanup temp database");
3660
+ } catch (error) {
3661
+ spinner.warn(`Failed to cleanup temp database: ${error}`);
3630
3662
  }
3631
3663
  }
3632
3664
  const finalSql = migrationSql || "-- No changes detected";
@@ -3640,7 +3672,8 @@ Migration SQL written to: ${options.output}`));
3640
3672
  }
3641
3673
  return finalSql;
3642
3674
  }
3643
- async function getCommentChanges(currentDb, targetDb) {
3675
+ async function getCommentChanges(currentDb, targetDb, schemas) {
3676
+ const schemaFilter = schemas && schemas.length > 0 ? `AND c.table_schema IN (${schemas.map((s) => `'${s}'`).join(", ")})` : "";
3644
3677
  const commentQuery = `
3645
3678
  SELECT
3646
3679
  format('COMMENT ON COLUMN %I.%I IS %L;',
@@ -3655,8 +3688,8 @@ async function getCommentChanges(currentDb, targetDb) {
3655
3688
  JOIN pg_catalog.pg_class pc ON pc.relname = c.table_name
3656
3689
  JOIN pg_catalog.pg_namespace pn ON pn.oid = pc.relnamespace AND pn.nspname = c.table_schema
3657
3690
  LEFT JOIN pg_catalog.pg_description pgd ON pgd.objoid = pc.oid AND pgd.objsubid = c.ordinal_position
3658
- WHERE c.table_schema = 'public'
3659
- AND c.table_name != 'schema_migrations'
3691
+ WHERE c.table_name != 'schema_migrations'
3692
+ ${schemaFilter}
3660
3693
  ORDER BY c.table_name, c.ordinal_position;
3661
3694
  `;
3662
3695
  const [currentComments, targetComments] = await Promise.all([