pqb 0.72.0 → 0.72.2

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.mjs CHANGED
@@ -732,6 +732,9 @@ var Column = class {
732
732
  as(column) {
733
733
  return setColumnData(this, "as", column);
734
734
  }
735
+ brand(_token) {
736
+ return this;
737
+ }
735
738
  input(fn) {
736
739
  const cloned = Object.create(this);
737
740
  cloned.inputSchema = fn(this.inputSchema);
@@ -2291,6 +2294,17 @@ const make = (_op) => {
2291
2294
  (q.chain ??= []).push(_op, val || value);
2292
2295
  if (getValueParser(q.parsers)) setValueParser(q, void 0);
2293
2296
  q.getColumn = BooleanColumn.instance;
2297
+ if (this instanceof Expression && this.result) {
2298
+ let column;
2299
+ if (this.result.value?.data.name) {
2300
+ column = Object.create(BooleanColumn.instance);
2301
+ column.data = {
2302
+ ...column.data,
2303
+ name: this.result.value.data.name
2304
+ };
2305
+ } else column = BooleanColumn.instance;
2306
+ this.result.value = column;
2307
+ }
2294
2308
  return setQueryOperators(this, boolean);
2295
2309
  }, { _op });
2296
2310
  };
@@ -2797,7 +2811,8 @@ var SimpleRawSQL = class extends RawSql {
2797
2811
  };
2798
2812
  const raw$1 = (sql) => new SimpleRawSQL(sql);
2799
2813
  const makeTimestamps = (timestamp) => {
2800
- const nowRaw = raw$1(getDefaultNowFn());
2814
+ const now = getDefaultNowFn();
2815
+ const nowRaw = raw$1(now);
2801
2816
  const updatedAt = timestamp().default(nowRaw);
2802
2817
  let updater;
2803
2818
  updatedAt.data.modifyQuery = (q, column) => {
@@ -2830,7 +2845,7 @@ const timestampHelpers = {
2830
2845
  };
2831
2846
  const defaultSrid = 4326;
2832
2847
  const encode = ({ srid = defaultSrid, lon, lat }) => {
2833
- const arr = new Uint8Array(25);
2848
+ const arr = /* @__PURE__ */ new Uint8Array(25);
2834
2849
  const view = new DataView(arr.buffer);
2835
2850
  view.setInt8(0, 1);
2836
2851
  view.setInt8(1, 1);
@@ -2859,7 +2874,7 @@ var PostgisGeographyPointColumn = class extends Column {
2859
2874
  }
2860
2875
  };
2861
2876
  const parse = (input) => {
2862
- const bytes = new Uint8Array(20);
2877
+ const bytes = /* @__PURE__ */ new Uint8Array(20);
2863
2878
  for (let i = 0; i < 40; i += 2) bytes[i / 2] = parseInt(input.slice(10 + i, 12 + i), 16);
2864
2879
  const view = new DataView(bytes.buffer);
2865
2880
  const srid = view.getUint32(0, true);
@@ -3804,7 +3819,8 @@ var QueryTransaction = class QueryTransaction {
3804
3819
  return QueryTransaction.prototype.transaction.call(this, cb);
3805
3820
  }
3806
3821
  isInTransaction() {
3807
- return isInUserTransaction(this.internal.asyncStorage.getStore());
3822
+ const trx = this.internal.asyncStorage.getStore();
3823
+ return isInUserTransaction(trx);
3808
3824
  }
3809
3825
  /**
3810
3826
  * Schedules a hook to run after the outermost transaction commits:
@@ -5664,7 +5680,8 @@ const resolveCallbacksInArgs = (q, args) => {
5664
5680
  qb.q.and = qb.q.or = qb.q.scopes = void 0;
5665
5681
  qb.q.subQuery = 1;
5666
5682
  _setSubQueryAliases(qb);
5667
- args[i] = prepareSubQueryForSql(q, resolveSubQueryCallback(qb, arg));
5683
+ const resolved = resolveSubQueryCallback(qb, arg);
5684
+ args[i] = prepareSubQueryForSql(q, resolved);
5668
5685
  } else if (arg.constructor === Object) {
5669
5686
  const copy = args[i] = { ...arg };
5670
5687
  for (const key in arg) {
@@ -6436,7 +6453,8 @@ var Where = class {
6436
6453
  * @param args - no arguments needed when the first argument is a relation name, or conditions to join the table with.
6437
6454
  */
6438
6455
  whereNotExists(arg, ...args) {
6439
- return _queryWhereNotExists(_clone(this), arg, args);
6456
+ const q = _clone(this);
6457
+ return _queryWhereNotExists(q, arg, args);
6440
6458
  }
6441
6459
  /**
6442
6460
  * Acts as `whereExists`, but prepends the condition with `OR` and negates it with `NOT`:
@@ -6583,7 +6601,11 @@ const tableColumnToSql = (ctx, queryData, shape, table, key, quotedAs, select, a
6583
6601
  const columnToSqlNotSelect = (ctx, data, shape, column, quotedAs, useSelectList) => columnToSql(ctx, data, shape, column, quotedAs, void 0, void 0, void 0, useSelectList, true);
6584
6602
  const columnToSql = (ctx, data, shape, column, quotedAs, select, as, jsonList, useSelectList, skipValueToArray) => {
6585
6603
  let index = column.indexOf(".");
6586
- if (index !== -1) return tableColumnToSql(ctx, data, shape, column.slice(0, index), column.slice(index + 1), quotedAs, select, as, jsonList, skipValueToArray);
6604
+ if (index !== -1) {
6605
+ const table = column.slice(0, index);
6606
+ const key = column.slice(index + 1);
6607
+ return tableColumnToSql(ctx, data, shape, table, key, quotedAs, select, as, jsonList, skipValueToArray);
6608
+ }
6587
6609
  return simpleColumnToSQL(ctx, data, shape, column, shape[column], quotedAs, select, as, jsonList, useSelectList, void 0, skipValueToArray);
6588
6610
  };
6589
6611
  const rawOrColumnToSql = (ctx, data, shape, expr, quotedAs, select, skipValueToArray) => {
@@ -6826,11 +6848,20 @@ const _addToHookSelectWithTable = (query, selects, table) => {
6826
6848
  };
6827
6849
  const moveQueryToCte = (ctx, query, type, dontAddTableHook) => {
6828
6850
  const { returnType } = query.q;
6851
+ const throwOnNotFound = returnType === "valueOrThrow";
6829
6852
  let valueAs;
6830
6853
  if (returnType === "value" || returnType === "valueOrThrow" || returnType === "pluck") {
6831
6854
  const first = query.q.select[0];
6832
- if (first instanceof SelectItemExpression && typeof first.item === "string") valueAs = first.item;
6833
- else {
6855
+ if (first instanceof SelectItemExpression && typeof first.item === "string") {
6856
+ const columnName = first.result.value?.data.name;
6857
+ if (columnName && columnName !== first.item) {
6858
+ query = _clone(query);
6859
+ query.q.returnType = "one";
6860
+ query.q.select = [{ selectAs: { [first.item]: first } }];
6861
+ if (throwOnNotFound && query.q.type !== "upsert") query.q.cteThrowOnNotFound = true;
6862
+ }
6863
+ valueAs = first.item;
6864
+ } else {
6834
6865
  query = _clone(query);
6835
6866
  query.q.returnType = "one";
6836
6867
  query.q.select = [{ selectAs: { value: query.q.select[0] } }];
@@ -6887,7 +6918,7 @@ const addTableHook = (ctx, q, data, select, hookPurpose, dontAddTableHook) => {
6887
6918
  const afterUpdateCommit = data.afterUpdateCommit;
6888
6919
  const afterSaveCommit = data.afterSaveCommit;
6889
6920
  const afterDeleteCommit = data.afterDeleteCommit;
6890
- const throwOnNotFound = hookPurpose !== "Create" && (data.returnType === "oneOrThrow" || data.returnType === "valueOrThrow");
6921
+ const throwOnNotFound = hookPurpose !== "Create" && (data.cteThrowOnNotFound || data.returnType === "oneOrThrow" || data.returnType === "valueOrThrow");
6891
6922
  const hasAfterHook = afterCreate || afterUpdate || afterSave || afterDelete || afterCreateCommit || afterUpdateCommit || afterSaveCommit || afterDeleteCommit;
6892
6923
  if (!select && !hasAfterHook && !throwOnNotFound) return;
6893
6924
  const tableHook = {
@@ -6912,7 +6943,8 @@ const addTableHook = (ctx, q, data, select, hookPurpose, dontAddTableHook) => {
6912
6943
  tableHook,
6913
6944
  throwOnNotFound
6914
6945
  };
6915
- const cteHooks = setCteHooks(ctx, throwOnNotFound || !!tableHook.select);
6946
+ const hasSelect = throwOnNotFound || !!tableHook.select;
6947
+ const cteHooks = setCteHooks(ctx, hasSelect);
6916
6948
  (cteHooks.tableHooks ??= {})[ctx.cteName] ??= item;
6917
6949
  }
6918
6950
  } else ctx.topCtx.tableHook = tableHook;
@@ -7305,7 +7337,8 @@ const processWhere = (ands, ctx, table, query, data, quotedAs) => {
7305
7337
  const value = data[key];
7306
7338
  if (value === void 0) continue;
7307
7339
  if (key === "AND") {
7308
- const sql = processAnds(toArray(value), ctx, table, query, quotedAs);
7340
+ const arr = toArray(value);
7341
+ const sql = processAnds(arr, ctx, table, query, quotedAs);
7309
7342
  if (sql) ands.push(sql);
7310
7343
  } else if (key === "OR") {
7311
7344
  const sqls = value.map(toArray).reduce((acc, and) => {
@@ -8948,7 +8981,9 @@ const _queryCreate = (q, data) => {
8948
8981
  };
8949
8982
  const _queryInsert = (query, data) => {
8950
8983
  throwIfReadOnly(query);
8951
- return insert(query, handleOneData(query, data, createCtx()));
8984
+ const ctx = createCtx();
8985
+ const obj = handleOneData(query, data, ctx);
8986
+ return insert(query, obj);
8952
8987
  };
8953
8988
  const _queryCreateMany = (q, data) => {
8954
8989
  throwIfReadOnly(q);
@@ -8957,7 +8992,8 @@ const _queryCreateMany = (q, data) => {
8957
8992
  };
8958
8993
  const _queryInsertMany = (q, data) => {
8959
8994
  throwIfReadOnly(q);
8960
- let result = insert(q, handleManyData(q, data, createCtx()), true);
8995
+ const ctx = createCtx();
8996
+ let result = insert(q, handleManyData(q, data, ctx), true);
8961
8997
  if (!data.length) result = result.none();
8962
8998
  return result;
8963
8999
  };
@@ -9561,7 +9597,8 @@ const toSql = (table, type, topCtx, isSubSql, cteName, calledByThen, dontAddTabl
9561
9597
  upsertOrCreate.q.or = upsertOrCreate.q.scopes = void 0;
9562
9598
  upsertOrCreate.q.and = [new RawSql(`NOT EXISTS (SELECT 1 FROM "${as}")`)];
9563
9599
  if (query.upsertInsert) {
9564
- _queryInsert(upsertOrCreate, query.upsertInsert());
9600
+ const insertData = query.upsertInsert();
9601
+ _queryInsert(upsertOrCreate, insertData);
9565
9602
  upsertOrCreate.q.type = "upsert";
9566
9603
  }
9567
9604
  upsertOrCreate.q.with = query.upsertCreateWith;
@@ -9674,7 +9711,8 @@ const cteToSqlGiveAs = (ctx, item, type, dontAddTableHook) => {
9674
9711
  let as;
9675
9712
  if (typeof item.n === "string") as = item.n;
9676
9713
  else if (ctx === ctx.topCtx) {
9677
- as = setFreeAlias((ctx.topCtx.topCTE ??= newTopCte(ctx)).names, "q", true);
9714
+ const topCTE = ctx.topCtx.topCTE ??= newTopCte(ctx);
9715
+ as = setFreeAlias(topCTE.names, "q", true);
9678
9716
  item.n(as);
9679
9717
  } else throw new Error("not implemented yet");
9680
9718
  if (item.q) inner = getSqlText(toSql(item.q, type, ctx.topCtx, true, as, void 0, dontAddTableHook));
@@ -10798,12 +10836,15 @@ var OnMethods = class {
10798
10836
  const setSelectRelation = (q) => {
10799
10837
  q.selectRelation = true;
10800
10838
  };
10801
- const addParsersForSelectJoined = (q, arg, as = arg) => {
10839
+ const addParsersForSelectJoinedWildcard = (q, arg, as = arg) => {
10802
10840
  const parsers = q.q.joinedParsers?.[arg];
10803
10841
  if (parsers) setParserToQuery(q.q, as, (row) => parseRecord(parsers, row));
10804
10842
  const batchParsers = q.q.joinedBatchParsers?.[arg];
10805
10843
  if (batchParsers) pushQueryArrayImmutable(q, "batchParsers", batchParsers.map((x) => ({
10806
- path: [{ key: as }, ...x.path],
10844
+ path: [{
10845
+ key: as,
10846
+ returnType: "one"
10847
+ }, ...x.path],
10807
10848
  fn: x.fn
10808
10849
  })));
10809
10850
  };
@@ -10985,7 +11026,8 @@ const processSelectAsArg = (q, selectAs, as, key, arg, columnAlias, outerReturnT
10985
11026
  subQuery = value;
10986
11027
  } else subQuery = value.json(false);
10987
11028
  else subQuery = value;
10988
- const as = _joinLateral(q, innerJoinLateral || query.q.returnType === "valueOrThrow" ? "JOIN" : "LEFT JOIN", subQuery, key, innerJoinLateral && returnType !== "one" && returnType !== "oneOrThrow");
11029
+ const joinLateral = innerJoinLateral || query.q.returnType === "valueOrThrow";
11030
+ const as = _joinLateral(q, joinLateral ? "JOIN" : "LEFT JOIN", subQuery, key, innerJoinLateral && returnType !== "one" && returnType !== "oneOrThrow");
10989
11031
  if (as) value.q.joinedForSelect = _copyQueryAliasToQuery(value, q, as);
10990
11032
  }
10991
11033
  if (value.q.getColumn?.data.skipValueToArray) value.q.notFoundDefault ??= null;
@@ -11017,7 +11059,7 @@ const setParserForSelectedString = (query, arg, as, columnAs, columnAlias) => {
11017
11059
  const table = getFullColumnTable(query, arg, index, as);
11018
11060
  const column = arg.slice(index + 1);
11019
11061
  if (column === "*") {
11020
- addParsersForSelectJoined(query, table, columnAs);
11062
+ addParsersForSelectJoinedWildcard(query, table, columnAs);
11021
11063
  return table === as ? column : arg;
11022
11064
  }
11023
11065
  if (table === as) return selectColumn(query, q, column, columnAs, columnAlias);
@@ -12443,7 +12485,7 @@ const _prependWithOnUpsertCreate = (q, name, query) => {
12443
12485
  q.q.upsertCreateWith = q.q.with;
12444
12486
  q.q.with = prev;
12445
12487
  };
12446
- const mergableObjects = new Set([
12488
+ const mergableObjects = /* @__PURE__ */ new Set([
12447
12489
  "selectShape",
12448
12490
  "withShapes",
12449
12491
  "defaultParsers",
@@ -12455,7 +12497,7 @@ const mergableObjects = new Set([
12455
12497
  "joinedBatchParsers",
12456
12498
  "selectedComputeds"
12457
12499
  ]);
12458
- const dontMergeArrays = new Set(["selectAllColumns"]);
12500
+ const dontMergeArrays = /* @__PURE__ */ new Set(["selectAllColumns"]);
12459
12501
  var MergeQueryMethods = class {
12460
12502
  merge(q) {
12461
12503
  const query = _clone(this);
@@ -12469,20 +12511,18 @@ var MergeQueryMethods = class {
12469
12511
  case "number":
12470
12512
  a[key] = value;
12471
12513
  break;
12472
- case "object":
12473
- if (Array.isArray(value)) {
12474
- if (!dontMergeArrays.has(key)) a[key] = a[key] ? [...a[key], ...value] : value;
12475
- } else if (mergableObjects.has(key)) a[key] = a[key] ? {
12476
- ...a[key],
12477
- ...value
12478
- } : value;
12479
- else if (key === "union") a[key] = a[key] ? {
12480
- b: a[key].b,
12481
- u: [...a[key].u, ...value.u]
12482
- } : value;
12483
- else if (value instanceof Set) a[key] = a[key] ? new Set([...a[key], ...value]) : value;
12484
- else a[key] = value;
12485
- break;
12514
+ case "object": if (Array.isArray(value)) {
12515
+ if (!dontMergeArrays.has(key)) a[key] = a[key] ? [...a[key], ...value] : value;
12516
+ } else if (mergableObjects.has(key)) a[key] = a[key] ? {
12517
+ ...a[key],
12518
+ ...value
12519
+ } : value;
12520
+ else if (key === "union") a[key] = a[key] ? {
12521
+ b: a[key].b,
12522
+ u: [...a[key].u, ...value.u]
12523
+ } : value;
12524
+ else if (value instanceof Set) a[key] = a[key] ? /* @__PURE__ */ new Set([...a[key], ...value]) : value;
12525
+ else a[key] = value;
12486
12526
  }
12487
12527
  }
12488
12528
  if (b.returnType) a.returnType = b.returnType;
@@ -13460,7 +13500,8 @@ var QueryMethods = class {
13460
13500
  * @param args - SQL expression
13461
13501
  */
13462
13502
  findBySql(...args) {
13463
- return _queryTake(_queryWhereSql(_clone(this), args));
13503
+ const q = _clone(this);
13504
+ return _queryTake(_queryWhereSql(q, args));
13464
13505
  }
13465
13506
  /**
13466
13507
  * Finds a single record by the primary key (id), returns `undefined` when not found.
@@ -14000,7 +14041,8 @@ var Db = class extends QueryMethods {
14000
14041
  if (options.noPrimaryKey === "error") throw new Error(message);
14001
14042
  else logger.warn(message);
14002
14043
  }
14003
- this.columns = Object.keys(shape);
14044
+ const columns = Object.keys(shape);
14045
+ this.columns = columns;
14004
14046
  if (options.computed) applyComputedColumns(this, options.computed);
14005
14047
  if (prepareSelectAll) {
14006
14048
  const selectAllShape = this.q.selectAllShape = {};
@@ -14456,6 +14498,12 @@ var Rollback = class extends Error {};
14456
14498
  const trxForTest = Symbol("trxForTest");
14457
14499
  const argToDb = (arg) => "$qb" in arg ? arg.$qb : arg;
14458
14500
  const testTransaction = {
14501
+ /**
14502
+ * Start a test transaction.
14503
+ * The returned promise is resolved immediately when transaction starts, not waiting for it to end.
14504
+ *
14505
+ * @param arg - ORM instance or a queryable instance (such as db.someTable).
14506
+ */
14459
14507
  start(arg) {
14460
14508
  const db = argToDb(arg);
14461
14509
  const { asyncStorage } = db.internal;
@@ -14491,6 +14539,11 @@ const testTransaction = {
14491
14539
  });
14492
14540
  });
14493
14541
  },
14542
+ /**
14543
+ * Rollback a test transaction.
14544
+ *
14545
+ * @param arg - the same ORM or query argument passed into the `testTransaction.start`.
14546
+ */
14494
14547
  rollback(arg) {
14495
14548
  const db = argToDb(arg);
14496
14549
  const data = db.internal[trxForTest];
@@ -14500,6 +14553,12 @@ const testTransaction = {
14500
14553
  last.reject?.(new Rollback());
14501
14554
  return last.promise;
14502
14555
  },
14556
+ /**
14557
+ * Will roll back the current `testTransaction` (won't have any effect if it was rolled back already),
14558
+ * and if there's no nested test transactions left, it will close the db connection.
14559
+ *
14560
+ * @param arg - the same ORM or query argument passed into the `testTransaction.start`.
14561
+ */
14503
14562
  async close(arg) {
14504
14563
  const db = argToDb(arg);
14505
14564
  await this.rollback(db);