tempest-db-js 0.6.0 → 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/dist/bin.js CHANGED
@@ -1,6 +1,6 @@
1
1
  #!/usr/bin/env node
2
- import { runMigrationCli, diffSchema, replaySchema, reflectSchema, detectRenames } from './chunk-KOW3LSWP.js';
3
- import './chunk-G7O5DCCC.js';
2
+ import { runMigrationCli, diffSchema, replaySchema, reflectSchema, detectRenames } from './chunk-SI4CLSF7.js';
3
+ import './chunk-4AWUP7BM.js';
4
4
  import { existsSync } from 'fs';
5
5
  import { resolve } from 'path';
6
6
  import { createInterface } from 'readline/promises';
@@ -608,6 +608,21 @@ function assertWritableValues(model, values, clause) {
608
608
  }
609
609
  if (issues.length > 0) throw new ValidationError(model.tablename, issues);
610
610
  }
611
+ function assertConsistentRows(model, rows) {
612
+ if (rows.length < 2) return;
613
+ const union = /* @__PURE__ */ new Set();
614
+ for (const row of rows) for (const key of Object.keys(row)) union.add(key);
615
+ const inconsistent = [...union].filter((key) => rows.some((row) => !(key in row)));
616
+ if (inconsistent.length === 0) return;
617
+ const columns = columnsOf(model);
618
+ const defaulted = inconsistent.filter((key) => columns[key]?.flags.hasDefault);
619
+ if (defaulted.length === 0) return;
620
+ const named = defaulted.map((c) => `"${c}"`).join(", ");
621
+ const verb = defaulted.length === 1 ? "has" : "have";
622
+ throw new ValidationError(model.tablename, [
623
+ `values: ${named} ${verb} a default but is missing from some rows of this multi-row insert \u2014 every row shares one column list, so the omitting rows would be written as NULL instead of taking the default. Give the column in every row, or insert the rows separately.`
624
+ ]);
625
+ }
611
626
  function describeValue(value) {
612
627
  if (typeof value === "function") return "a function";
613
628
  if (Array.isArray(value)) return "an array";
@@ -630,11 +645,13 @@ var InsertBuilder = class _InsertBuilder {
630
645
  * @param rows One row, or an array of rows.
631
646
  * @returns A builder carrying the rows.
632
647
  * @throws ValidationError When a value is not a column value the dialect can
633
- * bind (see the `sql` helpers for writing an expression instead).
648
+ * bind (see the `sql` helpers for writing an expression instead), or when the
649
+ * rows of a multi-row insert disagree about a column that has a default.
634
650
  */
635
651
  values(rows) {
636
652
  const list = Array.isArray(rows) ? rows : [rows];
637
653
  for (const row of list) assertWritableValues(this.source, row, "values");
654
+ assertConsistentRows(this.source, list);
638
655
  return this.with({ values: list });
639
656
  }
640
657
  /**
@@ -936,6 +953,18 @@ var Params = class {
936
953
  return this.placeholder(this.values.length);
937
954
  }
938
955
  };
956
+ function insertColumns(rows) {
957
+ const columns = [];
958
+ const seen = /* @__PURE__ */ new Set();
959
+ for (const row of rows) {
960
+ for (const key of Object.keys(row)) {
961
+ if (seen.has(key)) continue;
962
+ seen.add(key);
963
+ columns.push(key);
964
+ }
965
+ }
966
+ return columns;
967
+ }
939
968
  function insertHasExpression(node) {
940
969
  for (const row of node.values) {
941
970
  for (const value of Object.values(row)) {
@@ -1165,7 +1194,7 @@ var BaseDialect = class _BaseDialect {
1165
1194
  * SQL order, so placeholder positions stay correct.
1166
1195
  */
1167
1196
  compileInsert(node, params) {
1168
- const columns = node.values.length > 0 ? Object.keys(node.values[0]) : [];
1197
+ const columns = insertColumns(node.values);
1169
1198
  const conflict = node.onConflict;
1170
1199
  const cacheable = conflict?.targetWhere === void 0 && conflict?.updateWhere === void 0 && !insertHasExpression(node);
1171
1200
  if (!cacheable) return this.compileInsertDirect(node, columns, params);
@@ -1974,10 +2003,18 @@ var NodeSqliteDriver = class _NodeSqliteDriver {
1974
2003
  constructor(database) {
1975
2004
  this.db = database;
1976
2005
  }
1977
- /** Open a `node:sqlite` database at the given path (or `:memory:`). */
1978
- static open(path) {
2006
+ /**
2007
+ * Open a `node:sqlite` database at the given path (or `:memory:`).
2008
+ *
2009
+ * @param path The database file, or `":memory:"`.
2010
+ * @param options Passed straight to `DatabaseSync` (`readOnly`, `timeout`, …).
2011
+ * @returns A driver over the open handle.
2012
+ */
2013
+ static open(path, options) {
1979
2014
  const { DatabaseSync } = nodeRequire("node:sqlite");
1980
- return new _NodeSqliteDriver(new DatabaseSync(path));
2015
+ return new _NodeSqliteDriver(
2016
+ options ? new DatabaseSync(path, { ...options }) : new DatabaseSync(path)
2017
+ );
1981
2018
  }
1982
2019
  /** Return the cached prepared statement for `sql`, preparing it on first use. */
1983
2020
  // biome-ignore lint/suspicious/noExplicitAny: statement type is unavailable here.
@@ -2456,6 +2493,13 @@ var AsyncSession = class _AsyncSession {
2456
2493
  await this.close();
2457
2494
  }
2458
2495
  };
2496
+ function emitNotice(logger, notice) {
2497
+ if (!logger) return;
2498
+ try {
2499
+ logger(notice);
2500
+ } catch {
2501
+ }
2502
+ }
2459
2503
  var SyncEngine = class {
2460
2504
  constructor(driver, logger) {
2461
2505
  this.driver = driver;
@@ -2523,8 +2567,8 @@ function asAsync(driver) {
2523
2567
  } : {}
2524
2568
  };
2525
2569
  }
2526
- function openSqliteDriver(path, _options) {
2527
- return NodeSqliteDriver.open(path);
2570
+ function openSqliteDriver(path, options) {
2571
+ return NodeSqliteDriver.open(path, options?.driverOptions);
2528
2572
  }
2529
2573
  function createSyncEngine(url, options) {
2530
2574
  const parsed = parseDatabaseUrl(url);
@@ -2534,7 +2578,7 @@ function createSyncEngine(url, options) {
2534
2578
  );
2535
2579
  }
2536
2580
  return new SyncEngine(
2537
- openSqliteDriver(parsed.database ?? ":memory:"),
2581
+ openSqliteDriver(parsed.database ?? ":memory:", options),
2538
2582
  options?.onQuery
2539
2583
  );
2540
2584
  }
@@ -2542,20 +2586,20 @@ function createEngine(url, options) {
2542
2586
  const parsed = parseDatabaseUrl(url);
2543
2587
  if (parsed.dialect === "sqlite") {
2544
2588
  return new AsyncEngine(
2545
- asAsync(openSqliteDriver(parsed.database ?? ":memory:")),
2589
+ asAsync(openSqliteDriver(parsed.database ?? ":memory:", options)),
2546
2590
  "sqlite",
2547
2591
  options?.onQuery
2548
2592
  );
2549
2593
  }
2550
2594
  if (parsed.dialect === "mysql") {
2551
2595
  return new AsyncEngine(
2552
- createMysqlDriver(parsed.raw, options?.pool),
2596
+ createMysqlDriver(parsed.raw, options),
2553
2597
  "mysql",
2554
2598
  options?.onQuery
2555
2599
  );
2556
2600
  }
2557
2601
  return new AsyncEngine(
2558
- createPostgresDriver(parsed.raw, options?.pool),
2602
+ createPostgresDriver(parsed.raw, options),
2559
2603
  "postgresql",
2560
2604
  options?.onQuery
2561
2605
  );
@@ -2575,7 +2619,8 @@ function toMysqlResult(rows) {
2575
2619
  const header = rows;
2576
2620
  return { rows: [], changes: header.affectedRows ?? 0 };
2577
2621
  }
2578
- function createMysqlDriver(url, pool) {
2622
+ function createMysqlDriver(url, options) {
2623
+ const pool = options?.pool;
2579
2624
  let poolHandle;
2580
2625
  const ensure = async () => {
2581
2626
  if (poolHandle) return;
@@ -2588,6 +2633,7 @@ function createMysqlDriver(url, pool) {
2588
2633
  if (pool?.size !== void 0) opts.connectionLimit = pool.size;
2589
2634
  if (pool?.idleTimeoutMs !== void 0) opts.idleTimeout = pool.idleTimeoutMs;
2590
2635
  if (pool?.connectTimeoutMs !== void 0) opts.connectTimeout = pool.connectTimeoutMs;
2636
+ Object.assign(opts, options?.driverOptions ?? {});
2591
2637
  poolHandle = mod.createPool(opts);
2592
2638
  };
2593
2639
  const runOn = async (queryable, sql2, params) => {
@@ -2621,7 +2667,8 @@ function toPostgresResult(rows) {
2621
2667
  const arr = rows;
2622
2668
  return { rows: Array.from(arr), changes: arr.count ?? arr.length };
2623
2669
  }
2624
- function createPostgresDriver(url, pool) {
2670
+ function createPostgresDriver(url, options) {
2671
+ const pool = options?.pool;
2625
2672
  let client;
2626
2673
  const ensure = async () => {
2627
2674
  if (client) return;
@@ -2637,6 +2684,8 @@ function createPostgresDriver(url, pool) {
2637
2684
  if (pool?.connectTimeoutMs !== void 0) {
2638
2685
  opts.connect_timeout = Math.ceil(pool.connectTimeoutMs / 1e3);
2639
2686
  }
2687
+ opts.onnotice = (notice) => emitNotice(options?.onNotice, notice);
2688
+ Object.assign(opts, options?.driverOptions ?? {});
2640
2689
  client = (mod.default ?? mod)(url, opts);
2641
2690
  };
2642
2691
  return {
@@ -3023,5 +3072,5 @@ function dbColumn(names, prop) {
3023
3072
  }
3024
3073
 
3025
3074
  export { ActiveRecord, Agg, AsyncEngine, AsyncResult, AsyncSession, BaseDialect, BaseRepository, Column, DeleteBuilder, Expression, InsertBuilder, InvalidDatabaseUrl, JoinBuilder, Model, MysqlDialect, NoResultError, NodeSqliteDriver, OPERATORS, Params, PostgresDialect, QueryExecutionError, RecordNotFound, SelectBuilder, SqliteDialect, SyncEngine, SyncResult, SyncSession, UpdateBuilder, ValidationError, activeRecord, and, avg, belongsTo, col, column, columnNamesOf, columnPropsOf, columnsOf, count, createEngine, createSyncEngine, dbColumn, del, detectDialect, fn, foreignKey, fromDict, getDialect, hasMany, insert, isCondition, isExpression, isSqlExpression, isSubquery, join, loadRelations, max, min, not, or, parse, parseDatabaseUrl, renderPortableToken, select, sql, stringify, sum, toAsyncDriver, toCondNode, toDict, toJSON, toSnakeCase, unique, update, val };
3026
- //# sourceMappingURL=chunk-G7O5DCCC.js.map
3027
- //# sourceMappingURL=chunk-G7O5DCCC.js.map
3075
+ //# sourceMappingURL=chunk-4AWUP7BM.js.map
3076
+ //# sourceMappingURL=chunk-4AWUP7BM.js.map