pqb 0.72.0 → 0.72.1

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.js CHANGED
@@ -15,7 +15,7 @@ var __copyProps = (to, from, except, desc) => {
15
15
  }
16
16
  return to;
17
17
  };
18
- var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", {
18
+ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(isNodeMode || !mod || !mod.__esModule || !__hasOwnProp.call(mod, "default") ? __defProp(target, "default", {
19
19
  value: mod,
20
20
  enumerable: true
21
21
  }) : target, mod));
@@ -2314,6 +2314,17 @@ const make = (_op) => {
2314
2314
  (q.chain ??= []).push(_op, val || value);
2315
2315
  if (getValueParser(q.parsers)) setValueParser(q, void 0);
2316
2316
  q.getColumn = BooleanColumn.instance;
2317
+ if (this instanceof Expression && this.result) {
2318
+ let column;
2319
+ if (this.result.value?.data.name) {
2320
+ column = Object.create(BooleanColumn.instance);
2321
+ column.data = {
2322
+ ...column.data,
2323
+ name: this.result.value.data.name
2324
+ };
2325
+ } else column = BooleanColumn.instance;
2326
+ this.result.value = column;
2327
+ }
2317
2328
  return setQueryOperators(this, boolean);
2318
2329
  }, { _op });
2319
2330
  };
@@ -2820,7 +2831,8 @@ var SimpleRawSQL = class extends RawSql {
2820
2831
  };
2821
2832
  const raw$1 = (sql) => new SimpleRawSQL(sql);
2822
2833
  const makeTimestamps = (timestamp) => {
2823
- const nowRaw = raw$1(getDefaultNowFn());
2834
+ const now = getDefaultNowFn();
2835
+ const nowRaw = raw$1(now);
2824
2836
  const updatedAt = timestamp().default(nowRaw);
2825
2837
  let updater;
2826
2838
  updatedAt.data.modifyQuery = (q, column) => {
@@ -2853,7 +2865,7 @@ const timestampHelpers = {
2853
2865
  };
2854
2866
  const defaultSrid = 4326;
2855
2867
  const encode = ({ srid = defaultSrid, lon, lat }) => {
2856
- const arr = new Uint8Array(25);
2868
+ const arr = /* @__PURE__ */ new Uint8Array(25);
2857
2869
  const view = new DataView(arr.buffer);
2858
2870
  view.setInt8(0, 1);
2859
2871
  view.setInt8(1, 1);
@@ -2882,7 +2894,7 @@ var PostgisGeographyPointColumn = class extends Column {
2882
2894
  }
2883
2895
  };
2884
2896
  const parse = (input) => {
2885
- const bytes = new Uint8Array(20);
2897
+ const bytes = /* @__PURE__ */ new Uint8Array(20);
2886
2898
  for (let i = 0; i < 40; i += 2) bytes[i / 2] = parseInt(input.slice(10 + i, 12 + i), 16);
2887
2899
  const view = new DataView(bytes.buffer);
2888
2900
  const srid = view.getUint32(0, true);
@@ -3827,7 +3839,8 @@ var QueryTransaction = class QueryTransaction {
3827
3839
  return QueryTransaction.prototype.transaction.call(this, cb);
3828
3840
  }
3829
3841
  isInTransaction() {
3830
- return isInUserTransaction(this.internal.asyncStorage.getStore());
3842
+ const trx = this.internal.asyncStorage.getStore();
3843
+ return isInUserTransaction(trx);
3831
3844
  }
3832
3845
  /**
3833
3846
  * Schedules a hook to run after the outermost transaction commits:
@@ -5687,7 +5700,8 @@ const resolveCallbacksInArgs = (q, args) => {
5687
5700
  qb.q.and = qb.q.or = qb.q.scopes = void 0;
5688
5701
  qb.q.subQuery = 1;
5689
5702
  _setSubQueryAliases(qb);
5690
- args[i] = prepareSubQueryForSql(q, resolveSubQueryCallback(qb, arg));
5703
+ const resolved = resolveSubQueryCallback(qb, arg);
5704
+ args[i] = prepareSubQueryForSql(q, resolved);
5691
5705
  } else if (arg.constructor === Object) {
5692
5706
  const copy = args[i] = { ...arg };
5693
5707
  for (const key in arg) {
@@ -6459,7 +6473,8 @@ var Where = class {
6459
6473
  * @param args - no arguments needed when the first argument is a relation name, or conditions to join the table with.
6460
6474
  */
6461
6475
  whereNotExists(arg, ...args) {
6462
- return _queryWhereNotExists(_clone(this), arg, args);
6476
+ const q = _clone(this);
6477
+ return _queryWhereNotExists(q, arg, args);
6463
6478
  }
6464
6479
  /**
6465
6480
  * Acts as `whereExists`, but prepends the condition with `OR` and negates it with `NOT`:
@@ -6606,7 +6621,11 @@ const tableColumnToSql = (ctx, queryData, shape, table, key, quotedAs, select, a
6606
6621
  const columnToSqlNotSelect = (ctx, data, shape, column, quotedAs, useSelectList) => columnToSql(ctx, data, shape, column, quotedAs, void 0, void 0, void 0, useSelectList, true);
6607
6622
  const columnToSql = (ctx, data, shape, column, quotedAs, select, as, jsonList, useSelectList, skipValueToArray) => {
6608
6623
  let index = column.indexOf(".");
6609
- if (index !== -1) return tableColumnToSql(ctx, data, shape, column.slice(0, index), column.slice(index + 1), quotedAs, select, as, jsonList, skipValueToArray);
6624
+ if (index !== -1) {
6625
+ const table = column.slice(0, index);
6626
+ const key = column.slice(index + 1);
6627
+ return tableColumnToSql(ctx, data, shape, table, key, quotedAs, select, as, jsonList, skipValueToArray);
6628
+ }
6610
6629
  return simpleColumnToSQL(ctx, data, shape, column, shape[column], quotedAs, select, as, jsonList, useSelectList, void 0, skipValueToArray);
6611
6630
  };
6612
6631
  const rawOrColumnToSql = (ctx, data, shape, expr, quotedAs, select, skipValueToArray) => {
@@ -6849,11 +6868,20 @@ const _addToHookSelectWithTable = (query, selects, table) => {
6849
6868
  };
6850
6869
  const moveQueryToCte = (ctx, query, type, dontAddTableHook) => {
6851
6870
  const { returnType } = query.q;
6871
+ const throwOnNotFound = returnType === "valueOrThrow";
6852
6872
  let valueAs;
6853
6873
  if (returnType === "value" || returnType === "valueOrThrow" || returnType === "pluck") {
6854
6874
  const first = query.q.select[0];
6855
- if (first instanceof SelectItemExpression && typeof first.item === "string") valueAs = first.item;
6856
- else {
6875
+ if (first instanceof SelectItemExpression && typeof first.item === "string") {
6876
+ const columnName = first.result.value?.data.name;
6877
+ if (columnName && columnName !== first.item) {
6878
+ query = _clone(query);
6879
+ query.q.returnType = "one";
6880
+ query.q.select = [{ selectAs: { [first.item]: first } }];
6881
+ if (throwOnNotFound && query.q.type !== "upsert") query.q.cteThrowOnNotFound = true;
6882
+ }
6883
+ valueAs = first.item;
6884
+ } else {
6857
6885
  query = _clone(query);
6858
6886
  query.q.returnType = "one";
6859
6887
  query.q.select = [{ selectAs: { value: query.q.select[0] } }];
@@ -6910,7 +6938,7 @@ const addTableHook = (ctx, q, data, select, hookPurpose, dontAddTableHook) => {
6910
6938
  const afterUpdateCommit = data.afterUpdateCommit;
6911
6939
  const afterSaveCommit = data.afterSaveCommit;
6912
6940
  const afterDeleteCommit = data.afterDeleteCommit;
6913
- const throwOnNotFound = hookPurpose !== "Create" && (data.returnType === "oneOrThrow" || data.returnType === "valueOrThrow");
6941
+ const throwOnNotFound = hookPurpose !== "Create" && (data.cteThrowOnNotFound || data.returnType === "oneOrThrow" || data.returnType === "valueOrThrow");
6914
6942
  const hasAfterHook = afterCreate || afterUpdate || afterSave || afterDelete || afterCreateCommit || afterUpdateCommit || afterSaveCommit || afterDeleteCommit;
6915
6943
  if (!select && !hasAfterHook && !throwOnNotFound) return;
6916
6944
  const tableHook = {
@@ -6935,7 +6963,8 @@ const addTableHook = (ctx, q, data, select, hookPurpose, dontAddTableHook) => {
6935
6963
  tableHook,
6936
6964
  throwOnNotFound
6937
6965
  };
6938
- const cteHooks = setCteHooks(ctx, throwOnNotFound || !!tableHook.select);
6966
+ const hasSelect = throwOnNotFound || !!tableHook.select;
6967
+ const cteHooks = setCteHooks(ctx, hasSelect);
6939
6968
  (cteHooks.tableHooks ??= {})[ctx.cteName] ??= item;
6940
6969
  }
6941
6970
  } else ctx.topCtx.tableHook = tableHook;
@@ -7328,7 +7357,8 @@ const processWhere = (ands, ctx, table, query, data, quotedAs) => {
7328
7357
  const value = data[key];
7329
7358
  if (value === void 0) continue;
7330
7359
  if (key === "AND") {
7331
- const sql = processAnds(toArray(value), ctx, table, query, quotedAs);
7360
+ const arr = toArray(value);
7361
+ const sql = processAnds(arr, ctx, table, query, quotedAs);
7332
7362
  if (sql) ands.push(sql);
7333
7363
  } else if (key === "OR") {
7334
7364
  const sqls = value.map(toArray).reduce((acc, and) => {
@@ -8971,7 +9001,9 @@ const _queryCreate = (q, data) => {
8971
9001
  };
8972
9002
  const _queryInsert = (query, data) => {
8973
9003
  throwIfReadOnly(query);
8974
- return insert(query, handleOneData(query, data, createCtx()));
9004
+ const ctx = createCtx();
9005
+ const obj = handleOneData(query, data, ctx);
9006
+ return insert(query, obj);
8975
9007
  };
8976
9008
  const _queryCreateMany = (q, data) => {
8977
9009
  throwIfReadOnly(q);
@@ -8980,7 +9012,8 @@ const _queryCreateMany = (q, data) => {
8980
9012
  };
8981
9013
  const _queryInsertMany = (q, data) => {
8982
9014
  throwIfReadOnly(q);
8983
- let result = insert(q, handleManyData(q, data, createCtx()), true);
9015
+ const ctx = createCtx();
9016
+ let result = insert(q, handleManyData(q, data, ctx), true);
8984
9017
  if (!data.length) result = result.none();
8985
9018
  return result;
8986
9019
  };
@@ -9584,7 +9617,8 @@ const toSql = (table, type, topCtx, isSubSql, cteName, calledByThen, dontAddTabl
9584
9617
  upsertOrCreate.q.or = upsertOrCreate.q.scopes = void 0;
9585
9618
  upsertOrCreate.q.and = [new RawSql(`NOT EXISTS (SELECT 1 FROM "${as}")`)];
9586
9619
  if (query.upsertInsert) {
9587
- _queryInsert(upsertOrCreate, query.upsertInsert());
9620
+ const insertData = query.upsertInsert();
9621
+ _queryInsert(upsertOrCreate, insertData);
9588
9622
  upsertOrCreate.q.type = "upsert";
9589
9623
  }
9590
9624
  upsertOrCreate.q.with = query.upsertCreateWith;
@@ -9697,7 +9731,8 @@ const cteToSqlGiveAs = (ctx, item, type, dontAddTableHook) => {
9697
9731
  let as;
9698
9732
  if (typeof item.n === "string") as = item.n;
9699
9733
  else if (ctx === ctx.topCtx) {
9700
- as = setFreeAlias((ctx.topCtx.topCTE ??= newTopCte(ctx)).names, "q", true);
9734
+ const topCTE = ctx.topCtx.topCTE ??= newTopCte(ctx);
9735
+ as = setFreeAlias(topCTE.names, "q", true);
9701
9736
  item.n(as);
9702
9737
  } else throw new Error("not implemented yet");
9703
9738
  if (item.q) inner = getSqlText(toSql(item.q, type, ctx.topCtx, true, as, void 0, dontAddTableHook));
@@ -10821,12 +10856,15 @@ var OnMethods = class {
10821
10856
  const setSelectRelation = (q) => {
10822
10857
  q.selectRelation = true;
10823
10858
  };
10824
- const addParsersForSelectJoined = (q, arg, as = arg) => {
10859
+ const addParsersForSelectJoinedWildcard = (q, arg, as = arg) => {
10825
10860
  const parsers = q.q.joinedParsers?.[arg];
10826
10861
  if (parsers) setParserToQuery(q.q, as, (row) => parseRecord(parsers, row));
10827
10862
  const batchParsers = q.q.joinedBatchParsers?.[arg];
10828
10863
  if (batchParsers) pushQueryArrayImmutable(q, "batchParsers", batchParsers.map((x) => ({
10829
- path: [{ key: as }, ...x.path],
10864
+ path: [{
10865
+ key: as,
10866
+ returnType: "one"
10867
+ }, ...x.path],
10830
10868
  fn: x.fn
10831
10869
  })));
10832
10870
  };
@@ -11008,7 +11046,8 @@ const processSelectAsArg = (q, selectAs, as, key, arg, columnAlias, outerReturnT
11008
11046
  subQuery = value;
11009
11047
  } else subQuery = value.json(false);
11010
11048
  else subQuery = value;
11011
- const as = _joinLateral(q, innerJoinLateral || query.q.returnType === "valueOrThrow" ? "JOIN" : "LEFT JOIN", subQuery, key, innerJoinLateral && returnType !== "one" && returnType !== "oneOrThrow");
11049
+ const joinLateral = innerJoinLateral || query.q.returnType === "valueOrThrow";
11050
+ const as = _joinLateral(q, joinLateral ? "JOIN" : "LEFT JOIN", subQuery, key, innerJoinLateral && returnType !== "one" && returnType !== "oneOrThrow");
11012
11051
  if (as) value.q.joinedForSelect = _copyQueryAliasToQuery(value, q, as);
11013
11052
  }
11014
11053
  if (value.q.getColumn?.data.skipValueToArray) value.q.notFoundDefault ??= null;
@@ -11040,7 +11079,7 @@ const setParserForSelectedString = (query, arg, as, columnAs, columnAlias) => {
11040
11079
  const table = getFullColumnTable(query, arg, index, as);
11041
11080
  const column = arg.slice(index + 1);
11042
11081
  if (column === "*") {
11043
- addParsersForSelectJoined(query, table, columnAs);
11082
+ addParsersForSelectJoinedWildcard(query, table, columnAs);
11044
11083
  return table === as ? column : arg;
11045
11084
  }
11046
11085
  if (table === as) return selectColumn(query, q, column, columnAs, columnAlias);
@@ -12466,7 +12505,7 @@ const _prependWithOnUpsertCreate = (q, name, query) => {
12466
12505
  q.q.upsertCreateWith = q.q.with;
12467
12506
  q.q.with = prev;
12468
12507
  };
12469
- const mergableObjects = new Set([
12508
+ const mergableObjects = /* @__PURE__ */ new Set([
12470
12509
  "selectShape",
12471
12510
  "withShapes",
12472
12511
  "defaultParsers",
@@ -12478,7 +12517,7 @@ const mergableObjects = new Set([
12478
12517
  "joinedBatchParsers",
12479
12518
  "selectedComputeds"
12480
12519
  ]);
12481
- const dontMergeArrays = new Set(["selectAllColumns"]);
12520
+ const dontMergeArrays = /* @__PURE__ */ new Set(["selectAllColumns"]);
12482
12521
  var MergeQueryMethods = class {
12483
12522
  merge(q) {
12484
12523
  const query = _clone(this);
@@ -12492,20 +12531,18 @@ var MergeQueryMethods = class {
12492
12531
  case "number":
12493
12532
  a[key] = value;
12494
12533
  break;
12495
- case "object":
12496
- if (Array.isArray(value)) {
12497
- if (!dontMergeArrays.has(key)) a[key] = a[key] ? [...a[key], ...value] : value;
12498
- } else if (mergableObjects.has(key)) a[key] = a[key] ? {
12499
- ...a[key],
12500
- ...value
12501
- } : value;
12502
- else if (key === "union") a[key] = a[key] ? {
12503
- b: a[key].b,
12504
- u: [...a[key].u, ...value.u]
12505
- } : value;
12506
- else if (value instanceof Set) a[key] = a[key] ? new Set([...a[key], ...value]) : value;
12507
- else a[key] = value;
12508
- break;
12534
+ case "object": if (Array.isArray(value)) {
12535
+ if (!dontMergeArrays.has(key)) a[key] = a[key] ? [...a[key], ...value] : value;
12536
+ } else if (mergableObjects.has(key)) a[key] = a[key] ? {
12537
+ ...a[key],
12538
+ ...value
12539
+ } : value;
12540
+ else if (key === "union") a[key] = a[key] ? {
12541
+ b: a[key].b,
12542
+ u: [...a[key].u, ...value.u]
12543
+ } : value;
12544
+ else if (value instanceof Set) a[key] = a[key] ? /* @__PURE__ */ new Set([...a[key], ...value]) : value;
12545
+ else a[key] = value;
12509
12546
  }
12510
12547
  }
12511
12548
  if (b.returnType) a.returnType = b.returnType;
@@ -13483,7 +13520,8 @@ var QueryMethods = class {
13483
13520
  * @param args - SQL expression
13484
13521
  */
13485
13522
  findBySql(...args) {
13486
- return _queryTake(_queryWhereSql(_clone(this), args));
13523
+ const q = _clone(this);
13524
+ return _queryTake(_queryWhereSql(q, args));
13487
13525
  }
13488
13526
  /**
13489
13527
  * Finds a single record by the primary key (id), returns `undefined` when not found.
@@ -14023,7 +14061,8 @@ var Db = class extends QueryMethods {
14023
14061
  if (options.noPrimaryKey === "error") throw new Error(message);
14024
14062
  else logger.warn(message);
14025
14063
  }
14026
- this.columns = Object.keys(shape);
14064
+ const columns = Object.keys(shape);
14065
+ this.columns = columns;
14027
14066
  if (options.computed) applyComputedColumns(this, options.computed);
14028
14067
  if (prepareSelectAll) {
14029
14068
  const selectAllShape = this.q.selectAllShape = {};
@@ -14479,6 +14518,12 @@ var Rollback = class extends Error {};
14479
14518
  const trxForTest = Symbol("trxForTest");
14480
14519
  const argToDb = (arg) => "$qb" in arg ? arg.$qb : arg;
14481
14520
  const testTransaction = {
14521
+ /**
14522
+ * Start a test transaction.
14523
+ * The returned promise is resolved immediately when transaction starts, not waiting for it to end.
14524
+ *
14525
+ * @param arg - ORM instance or a queryable instance (such as db.someTable).
14526
+ */
14482
14527
  start(arg) {
14483
14528
  const db = argToDb(arg);
14484
14529
  const { asyncStorage } = db.internal;
@@ -14514,6 +14559,11 @@ const testTransaction = {
14514
14559
  });
14515
14560
  });
14516
14561
  },
14562
+ /**
14563
+ * Rollback a test transaction.
14564
+ *
14565
+ * @param arg - the same ORM or query argument passed into the `testTransaction.start`.
14566
+ */
14517
14567
  rollback(arg) {
14518
14568
  const db = argToDb(arg);
14519
14569
  const data = db.internal[trxForTest];
@@ -14523,6 +14573,12 @@ const testTransaction = {
14523
14573
  last.reject?.(new Rollback());
14524
14574
  return last.promise;
14525
14575
  },
14576
+ /**
14577
+ * Will roll back the current `testTransaction` (won't have any effect if it was rolled back already),
14578
+ * and if there's no nested test transactions left, it will close the db connection.
14579
+ *
14580
+ * @param arg - the same ORM or query argument passed into the `testTransaction.start`.
14581
+ */
14526
14582
  async close(arg) {
14527
14583
  const db = argToDb(arg);
14528
14584
  await this.rollback(db);