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.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));
@@ -755,6 +755,9 @@ var Column = class {
755
755
  as(column) {
756
756
  return setColumnData(this, "as", column);
757
757
  }
758
+ brand(_token) {
759
+ return this;
760
+ }
758
761
  input(fn) {
759
762
  const cloned = Object.create(this);
760
763
  cloned.inputSchema = fn(this.inputSchema);
@@ -2314,6 +2317,17 @@ const make = (_op) => {
2314
2317
  (q.chain ??= []).push(_op, val || value);
2315
2318
  if (getValueParser(q.parsers)) setValueParser(q, void 0);
2316
2319
  q.getColumn = BooleanColumn.instance;
2320
+ if (this instanceof Expression && this.result) {
2321
+ let column;
2322
+ if (this.result.value?.data.name) {
2323
+ column = Object.create(BooleanColumn.instance);
2324
+ column.data = {
2325
+ ...column.data,
2326
+ name: this.result.value.data.name
2327
+ };
2328
+ } else column = BooleanColumn.instance;
2329
+ this.result.value = column;
2330
+ }
2317
2331
  return setQueryOperators(this, boolean);
2318
2332
  }, { _op });
2319
2333
  };
@@ -2820,7 +2834,8 @@ var SimpleRawSQL = class extends RawSql {
2820
2834
  };
2821
2835
  const raw$1 = (sql) => new SimpleRawSQL(sql);
2822
2836
  const makeTimestamps = (timestamp) => {
2823
- const nowRaw = raw$1(getDefaultNowFn());
2837
+ const now = getDefaultNowFn();
2838
+ const nowRaw = raw$1(now);
2824
2839
  const updatedAt = timestamp().default(nowRaw);
2825
2840
  let updater;
2826
2841
  updatedAt.data.modifyQuery = (q, column) => {
@@ -2853,7 +2868,7 @@ const timestampHelpers = {
2853
2868
  };
2854
2869
  const defaultSrid = 4326;
2855
2870
  const encode = ({ srid = defaultSrid, lon, lat }) => {
2856
- const arr = new Uint8Array(25);
2871
+ const arr = /* @__PURE__ */ new Uint8Array(25);
2857
2872
  const view = new DataView(arr.buffer);
2858
2873
  view.setInt8(0, 1);
2859
2874
  view.setInt8(1, 1);
@@ -2882,7 +2897,7 @@ var PostgisGeographyPointColumn = class extends Column {
2882
2897
  }
2883
2898
  };
2884
2899
  const parse = (input) => {
2885
- const bytes = new Uint8Array(20);
2900
+ const bytes = /* @__PURE__ */ new Uint8Array(20);
2886
2901
  for (let i = 0; i < 40; i += 2) bytes[i / 2] = parseInt(input.slice(10 + i, 12 + i), 16);
2887
2902
  const view = new DataView(bytes.buffer);
2888
2903
  const srid = view.getUint32(0, true);
@@ -3827,7 +3842,8 @@ var QueryTransaction = class QueryTransaction {
3827
3842
  return QueryTransaction.prototype.transaction.call(this, cb);
3828
3843
  }
3829
3844
  isInTransaction() {
3830
- return isInUserTransaction(this.internal.asyncStorage.getStore());
3845
+ const trx = this.internal.asyncStorage.getStore();
3846
+ return isInUserTransaction(trx);
3831
3847
  }
3832
3848
  /**
3833
3849
  * Schedules a hook to run after the outermost transaction commits:
@@ -5687,7 +5703,8 @@ const resolveCallbacksInArgs = (q, args) => {
5687
5703
  qb.q.and = qb.q.or = qb.q.scopes = void 0;
5688
5704
  qb.q.subQuery = 1;
5689
5705
  _setSubQueryAliases(qb);
5690
- args[i] = prepareSubQueryForSql(q, resolveSubQueryCallback(qb, arg));
5706
+ const resolved = resolveSubQueryCallback(qb, arg);
5707
+ args[i] = prepareSubQueryForSql(q, resolved);
5691
5708
  } else if (arg.constructor === Object) {
5692
5709
  const copy = args[i] = { ...arg };
5693
5710
  for (const key in arg) {
@@ -6459,7 +6476,8 @@ var Where = class {
6459
6476
  * @param args - no arguments needed when the first argument is a relation name, or conditions to join the table with.
6460
6477
  */
6461
6478
  whereNotExists(arg, ...args) {
6462
- return _queryWhereNotExists(_clone(this), arg, args);
6479
+ const q = _clone(this);
6480
+ return _queryWhereNotExists(q, arg, args);
6463
6481
  }
6464
6482
  /**
6465
6483
  * Acts as `whereExists`, but prepends the condition with `OR` and negates it with `NOT`:
@@ -6606,7 +6624,11 @@ const tableColumnToSql = (ctx, queryData, shape, table, key, quotedAs, select, a
6606
6624
  const columnToSqlNotSelect = (ctx, data, shape, column, quotedAs, useSelectList) => columnToSql(ctx, data, shape, column, quotedAs, void 0, void 0, void 0, useSelectList, true);
6607
6625
  const columnToSql = (ctx, data, shape, column, quotedAs, select, as, jsonList, useSelectList, skipValueToArray) => {
6608
6626
  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);
6627
+ if (index !== -1) {
6628
+ const table = column.slice(0, index);
6629
+ const key = column.slice(index + 1);
6630
+ return tableColumnToSql(ctx, data, shape, table, key, quotedAs, select, as, jsonList, skipValueToArray);
6631
+ }
6610
6632
  return simpleColumnToSQL(ctx, data, shape, column, shape[column], quotedAs, select, as, jsonList, useSelectList, void 0, skipValueToArray);
6611
6633
  };
6612
6634
  const rawOrColumnToSql = (ctx, data, shape, expr, quotedAs, select, skipValueToArray) => {
@@ -6849,11 +6871,20 @@ const _addToHookSelectWithTable = (query, selects, table) => {
6849
6871
  };
6850
6872
  const moveQueryToCte = (ctx, query, type, dontAddTableHook) => {
6851
6873
  const { returnType } = query.q;
6874
+ const throwOnNotFound = returnType === "valueOrThrow";
6852
6875
  let valueAs;
6853
6876
  if (returnType === "value" || returnType === "valueOrThrow" || returnType === "pluck") {
6854
6877
  const first = query.q.select[0];
6855
- if (first instanceof SelectItemExpression && typeof first.item === "string") valueAs = first.item;
6856
- else {
6878
+ if (first instanceof SelectItemExpression && typeof first.item === "string") {
6879
+ const columnName = first.result.value?.data.name;
6880
+ if (columnName && columnName !== first.item) {
6881
+ query = _clone(query);
6882
+ query.q.returnType = "one";
6883
+ query.q.select = [{ selectAs: { [first.item]: first } }];
6884
+ if (throwOnNotFound && query.q.type !== "upsert") query.q.cteThrowOnNotFound = true;
6885
+ }
6886
+ valueAs = first.item;
6887
+ } else {
6857
6888
  query = _clone(query);
6858
6889
  query.q.returnType = "one";
6859
6890
  query.q.select = [{ selectAs: { value: query.q.select[0] } }];
@@ -6910,7 +6941,7 @@ const addTableHook = (ctx, q, data, select, hookPurpose, dontAddTableHook) => {
6910
6941
  const afterUpdateCommit = data.afterUpdateCommit;
6911
6942
  const afterSaveCommit = data.afterSaveCommit;
6912
6943
  const afterDeleteCommit = data.afterDeleteCommit;
6913
- const throwOnNotFound = hookPurpose !== "Create" && (data.returnType === "oneOrThrow" || data.returnType === "valueOrThrow");
6944
+ const throwOnNotFound = hookPurpose !== "Create" && (data.cteThrowOnNotFound || data.returnType === "oneOrThrow" || data.returnType === "valueOrThrow");
6914
6945
  const hasAfterHook = afterCreate || afterUpdate || afterSave || afterDelete || afterCreateCommit || afterUpdateCommit || afterSaveCommit || afterDeleteCommit;
6915
6946
  if (!select && !hasAfterHook && !throwOnNotFound) return;
6916
6947
  const tableHook = {
@@ -6935,7 +6966,8 @@ const addTableHook = (ctx, q, data, select, hookPurpose, dontAddTableHook) => {
6935
6966
  tableHook,
6936
6967
  throwOnNotFound
6937
6968
  };
6938
- const cteHooks = setCteHooks(ctx, throwOnNotFound || !!tableHook.select);
6969
+ const hasSelect = throwOnNotFound || !!tableHook.select;
6970
+ const cteHooks = setCteHooks(ctx, hasSelect);
6939
6971
  (cteHooks.tableHooks ??= {})[ctx.cteName] ??= item;
6940
6972
  }
6941
6973
  } else ctx.topCtx.tableHook = tableHook;
@@ -7328,7 +7360,8 @@ const processWhere = (ands, ctx, table, query, data, quotedAs) => {
7328
7360
  const value = data[key];
7329
7361
  if (value === void 0) continue;
7330
7362
  if (key === "AND") {
7331
- const sql = processAnds(toArray(value), ctx, table, query, quotedAs);
7363
+ const arr = toArray(value);
7364
+ const sql = processAnds(arr, ctx, table, query, quotedAs);
7332
7365
  if (sql) ands.push(sql);
7333
7366
  } else if (key === "OR") {
7334
7367
  const sqls = value.map(toArray).reduce((acc, and) => {
@@ -8971,7 +9004,9 @@ const _queryCreate = (q, data) => {
8971
9004
  };
8972
9005
  const _queryInsert = (query, data) => {
8973
9006
  throwIfReadOnly(query);
8974
- return insert(query, handleOneData(query, data, createCtx()));
9007
+ const ctx = createCtx();
9008
+ const obj = handleOneData(query, data, ctx);
9009
+ return insert(query, obj);
8975
9010
  };
8976
9011
  const _queryCreateMany = (q, data) => {
8977
9012
  throwIfReadOnly(q);
@@ -8980,7 +9015,8 @@ const _queryCreateMany = (q, data) => {
8980
9015
  };
8981
9016
  const _queryInsertMany = (q, data) => {
8982
9017
  throwIfReadOnly(q);
8983
- let result = insert(q, handleManyData(q, data, createCtx()), true);
9018
+ const ctx = createCtx();
9019
+ let result = insert(q, handleManyData(q, data, ctx), true);
8984
9020
  if (!data.length) result = result.none();
8985
9021
  return result;
8986
9022
  };
@@ -9584,7 +9620,8 @@ const toSql = (table, type, topCtx, isSubSql, cteName, calledByThen, dontAddTabl
9584
9620
  upsertOrCreate.q.or = upsertOrCreate.q.scopes = void 0;
9585
9621
  upsertOrCreate.q.and = [new RawSql(`NOT EXISTS (SELECT 1 FROM "${as}")`)];
9586
9622
  if (query.upsertInsert) {
9587
- _queryInsert(upsertOrCreate, query.upsertInsert());
9623
+ const insertData = query.upsertInsert();
9624
+ _queryInsert(upsertOrCreate, insertData);
9588
9625
  upsertOrCreate.q.type = "upsert";
9589
9626
  }
9590
9627
  upsertOrCreate.q.with = query.upsertCreateWith;
@@ -9697,7 +9734,8 @@ const cteToSqlGiveAs = (ctx, item, type, dontAddTableHook) => {
9697
9734
  let as;
9698
9735
  if (typeof item.n === "string") as = item.n;
9699
9736
  else if (ctx === ctx.topCtx) {
9700
- as = setFreeAlias((ctx.topCtx.topCTE ??= newTopCte(ctx)).names, "q", true);
9737
+ const topCTE = ctx.topCtx.topCTE ??= newTopCte(ctx);
9738
+ as = setFreeAlias(topCTE.names, "q", true);
9701
9739
  item.n(as);
9702
9740
  } else throw new Error("not implemented yet");
9703
9741
  if (item.q) inner = getSqlText(toSql(item.q, type, ctx.topCtx, true, as, void 0, dontAddTableHook));
@@ -10821,12 +10859,15 @@ var OnMethods = class {
10821
10859
  const setSelectRelation = (q) => {
10822
10860
  q.selectRelation = true;
10823
10861
  };
10824
- const addParsersForSelectJoined = (q, arg, as = arg) => {
10862
+ const addParsersForSelectJoinedWildcard = (q, arg, as = arg) => {
10825
10863
  const parsers = q.q.joinedParsers?.[arg];
10826
10864
  if (parsers) setParserToQuery(q.q, as, (row) => parseRecord(parsers, row));
10827
10865
  const batchParsers = q.q.joinedBatchParsers?.[arg];
10828
10866
  if (batchParsers) pushQueryArrayImmutable(q, "batchParsers", batchParsers.map((x) => ({
10829
- path: [{ key: as }, ...x.path],
10867
+ path: [{
10868
+ key: as,
10869
+ returnType: "one"
10870
+ }, ...x.path],
10830
10871
  fn: x.fn
10831
10872
  })));
10832
10873
  };
@@ -11008,7 +11049,8 @@ const processSelectAsArg = (q, selectAs, as, key, arg, columnAlias, outerReturnT
11008
11049
  subQuery = value;
11009
11050
  } else subQuery = value.json(false);
11010
11051
  else subQuery = value;
11011
- const as = _joinLateral(q, innerJoinLateral || query.q.returnType === "valueOrThrow" ? "JOIN" : "LEFT JOIN", subQuery, key, innerJoinLateral && returnType !== "one" && returnType !== "oneOrThrow");
11052
+ const joinLateral = innerJoinLateral || query.q.returnType === "valueOrThrow";
11053
+ const as = _joinLateral(q, joinLateral ? "JOIN" : "LEFT JOIN", subQuery, key, innerJoinLateral && returnType !== "one" && returnType !== "oneOrThrow");
11012
11054
  if (as) value.q.joinedForSelect = _copyQueryAliasToQuery(value, q, as);
11013
11055
  }
11014
11056
  if (value.q.getColumn?.data.skipValueToArray) value.q.notFoundDefault ??= null;
@@ -11040,7 +11082,7 @@ const setParserForSelectedString = (query, arg, as, columnAs, columnAlias) => {
11040
11082
  const table = getFullColumnTable(query, arg, index, as);
11041
11083
  const column = arg.slice(index + 1);
11042
11084
  if (column === "*") {
11043
- addParsersForSelectJoined(query, table, columnAs);
11085
+ addParsersForSelectJoinedWildcard(query, table, columnAs);
11044
11086
  return table === as ? column : arg;
11045
11087
  }
11046
11088
  if (table === as) return selectColumn(query, q, column, columnAs, columnAlias);
@@ -12466,7 +12508,7 @@ const _prependWithOnUpsertCreate = (q, name, query) => {
12466
12508
  q.q.upsertCreateWith = q.q.with;
12467
12509
  q.q.with = prev;
12468
12510
  };
12469
- const mergableObjects = new Set([
12511
+ const mergableObjects = /* @__PURE__ */ new Set([
12470
12512
  "selectShape",
12471
12513
  "withShapes",
12472
12514
  "defaultParsers",
@@ -12478,7 +12520,7 @@ const mergableObjects = new Set([
12478
12520
  "joinedBatchParsers",
12479
12521
  "selectedComputeds"
12480
12522
  ]);
12481
- const dontMergeArrays = new Set(["selectAllColumns"]);
12523
+ const dontMergeArrays = /* @__PURE__ */ new Set(["selectAllColumns"]);
12482
12524
  var MergeQueryMethods = class {
12483
12525
  merge(q) {
12484
12526
  const query = _clone(this);
@@ -12492,20 +12534,18 @@ var MergeQueryMethods = class {
12492
12534
  case "number":
12493
12535
  a[key] = value;
12494
12536
  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;
12537
+ case "object": if (Array.isArray(value)) {
12538
+ if (!dontMergeArrays.has(key)) a[key] = a[key] ? [...a[key], ...value] : value;
12539
+ } else if (mergableObjects.has(key)) a[key] = a[key] ? {
12540
+ ...a[key],
12541
+ ...value
12542
+ } : value;
12543
+ else if (key === "union") a[key] = a[key] ? {
12544
+ b: a[key].b,
12545
+ u: [...a[key].u, ...value.u]
12546
+ } : value;
12547
+ else if (value instanceof Set) a[key] = a[key] ? /* @__PURE__ */ new Set([...a[key], ...value]) : value;
12548
+ else a[key] = value;
12509
12549
  }
12510
12550
  }
12511
12551
  if (b.returnType) a.returnType = b.returnType;
@@ -13483,7 +13523,8 @@ var QueryMethods = class {
13483
13523
  * @param args - SQL expression
13484
13524
  */
13485
13525
  findBySql(...args) {
13486
- return _queryTake(_queryWhereSql(_clone(this), args));
13526
+ const q = _clone(this);
13527
+ return _queryTake(_queryWhereSql(q, args));
13487
13528
  }
13488
13529
  /**
13489
13530
  * Finds a single record by the primary key (id), returns `undefined` when not found.
@@ -14023,7 +14064,8 @@ var Db = class extends QueryMethods {
14023
14064
  if (options.noPrimaryKey === "error") throw new Error(message);
14024
14065
  else logger.warn(message);
14025
14066
  }
14026
- this.columns = Object.keys(shape);
14067
+ const columns = Object.keys(shape);
14068
+ this.columns = columns;
14027
14069
  if (options.computed) applyComputedColumns(this, options.computed);
14028
14070
  if (prepareSelectAll) {
14029
14071
  const selectAllShape = this.q.selectAllShape = {};
@@ -14479,6 +14521,12 @@ var Rollback = class extends Error {};
14479
14521
  const trxForTest = Symbol("trxForTest");
14480
14522
  const argToDb = (arg) => "$qb" in arg ? arg.$qb : arg;
14481
14523
  const testTransaction = {
14524
+ /**
14525
+ * Start a test transaction.
14526
+ * The returned promise is resolved immediately when transaction starts, not waiting for it to end.
14527
+ *
14528
+ * @param arg - ORM instance or a queryable instance (such as db.someTable).
14529
+ */
14482
14530
  start(arg) {
14483
14531
  const db = argToDb(arg);
14484
14532
  const { asyncStorage } = db.internal;
@@ -14514,6 +14562,11 @@ const testTransaction = {
14514
14562
  });
14515
14563
  });
14516
14564
  },
14565
+ /**
14566
+ * Rollback a test transaction.
14567
+ *
14568
+ * @param arg - the same ORM or query argument passed into the `testTransaction.start`.
14569
+ */
14517
14570
  rollback(arg) {
14518
14571
  const db = argToDb(arg);
14519
14572
  const data = db.internal[trxForTest];
@@ -14523,6 +14576,12 @@ const testTransaction = {
14523
14576
  last.reject?.(new Rollback());
14524
14577
  return last.promise;
14525
14578
  },
14579
+ /**
14580
+ * Will roll back the current `testTransaction` (won't have any effect if it was rolled back already),
14581
+ * and if there's no nested test transactions left, it will close the db connection.
14582
+ *
14583
+ * @param arg - the same ORM or query argument passed into the `testTransaction.start`.
14584
+ */
14526
14585
  async close(arg) {
14527
14586
  const db = argToDb(arg);
14528
14587
  await this.rollback(db);