@naturalcycles/db-lib 9.4.1 → 9.5.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.
@@ -11,7 +11,6 @@ import {
11
11
  _truncate,
12
12
  _typeCast,
13
13
  _uniqBy,
14
- AnyObject,
15
14
  AppError,
16
15
  AsyncMapper,
17
16
  BaseDBEntity,
@@ -21,10 +20,9 @@ import {
21
20
  JsonSchemaRootObject,
22
21
  ObjectWithId,
23
22
  pMap,
24
- Saved,
25
23
  SKIP,
26
24
  UnixTimestampMillisNumber,
27
- UnsavedId,
25
+ Unsaved,
28
26
  ZodSchema,
29
27
  ZodValidationError,
30
28
  zSafeValidate,
@@ -77,12 +75,8 @@ const isCI = !!process.env['CI']
77
75
  * BM = Backend model (optimized for API access)
78
76
  * TM = Transport model (optimized to be sent over the wire)
79
77
  */
80
- export class CommonDao<
81
- BM extends BaseDBEntity,
82
- DBM extends BaseDBEntity = BM,
83
- TM extends AnyObject = BM,
84
- > {
85
- constructor(public cfg: CommonDaoCfg<BM, DBM, TM>) {
78
+ export class CommonDao<BM extends BaseDBEntity, DBM extends BaseDBEntity = BM> {
79
+ constructor(public cfg: CommonDaoCfg<BM, DBM>) {
86
80
  this.cfg = {
87
81
  // Default is to NOT log in AppEngine and in CI,
88
82
  // otherwise to log Operations
@@ -100,11 +94,10 @@ export class CommonDao<
100
94
  beforeDBMValidate: dbm => dbm,
101
95
  beforeDBMToBM: dbm => dbm as any,
102
96
  beforeBMToDBM: bm => bm as any,
103
- beforeBMToTM: bm => bm as any,
104
97
  anonymize: dbm => dbm,
105
98
  onValidationError: err => err,
106
99
  ...cfg.hooks,
107
- } satisfies Partial<CommonDaoHooks<BM, DBM, TM>>,
100
+ } satisfies Partial<CommonDaoHooks<BM, DBM>>,
108
101
  }
109
102
 
110
103
  if (this.cfg.generateId) {
@@ -115,7 +108,7 @@ export class CommonDao<
115
108
  }
116
109
 
117
110
  // CREATE
118
- create(part: Partial<BM> = {}, opt: CommonDaoOptions = {}): Saved<BM> {
111
+ create(part: Partial<BM> = {}, opt: CommonDaoOptions = {}): BM {
119
112
  const bm = this.cfg.hooks!.beforeCreate!(part)
120
113
  // First assignIdCreatedUpdated, then validate!
121
114
  this.assignIdCreatedUpdated(bm, opt)
@@ -124,14 +117,14 @@ export class CommonDao<
124
117
 
125
118
  // GET
126
119
  async getById(id: undefined | null, opt?: CommonDaoOptions): Promise<null>
127
- async getById(id?: string | null, opt?: CommonDaoOptions): Promise<Saved<BM> | null>
128
- async getById(id?: string | null, opt: CommonDaoOptions = {}): Promise<Saved<BM> | null> {
120
+ async getById(id?: string | null, opt?: CommonDaoOptions): Promise<BM | null>
121
+ async getById(id?: string | null, opt: CommonDaoOptions = {}): Promise<BM | null> {
129
122
  if (!id) return null
130
123
  const op = `getById(${id})`
131
124
  const table = opt.table || this.cfg.table
132
125
  const started = this.logStarted(op, table)
133
126
 
134
- let dbm = (await (opt.tx || this.cfg.db).getByIds<Saved<DBM>>(table, [id]))[0]
127
+ let dbm = (await (opt.tx || this.cfg.db).getByIds<DBM>(table, [id]))[0]
135
128
  if (dbm && !opt.raw && this.cfg.hooks!.afterLoad) {
136
129
  dbm = (await this.cfg.hooks!.afterLoad(dbm)) || undefined
137
130
  }
@@ -141,11 +134,7 @@ export class CommonDao<
141
134
  return bm || null
142
135
  }
143
136
 
144
- async getByIdOrEmpty(
145
- id: string,
146
- part: Partial<BM> = {},
147
- opt?: CommonDaoOptions,
148
- ): Promise<Saved<BM>> {
137
+ async getByIdOrEmpty(id: string, part: Partial<BM> = {}, opt?: CommonDaoOptions): Promise<BM> {
149
138
  const bm = await this.getById(id, opt)
150
139
  if (bm) return bm
151
140
 
@@ -156,7 +145,7 @@ export class CommonDao<
156
145
  id: string,
157
146
  part: Partial<BM> = {},
158
147
  opt?: CommonDaoOptions,
159
- ): Promise<Saved<DBM>> {
148
+ ): Promise<DBM> {
160
149
  const dbm = await this.getByIdAsDBM(id, opt)
161
150
  if (dbm) return dbm
162
151
 
@@ -165,13 +154,13 @@ export class CommonDao<
165
154
  }
166
155
 
167
156
  async getByIdAsDBM(id: undefined | null, opt?: CommonDaoOptions): Promise<null>
168
- async getByIdAsDBM(id?: string | null, opt?: CommonDaoOptions): Promise<Saved<DBM> | null>
169
- async getByIdAsDBM(id?: string | null, opt: CommonDaoOptions = {}): Promise<Saved<DBM> | null> {
157
+ async getByIdAsDBM(id?: string | null, opt?: CommonDaoOptions): Promise<DBM | null>
158
+ async getByIdAsDBM(id?: string | null, opt: CommonDaoOptions = {}): Promise<DBM | null> {
170
159
  if (!id) return null
171
160
  const op = `getByIdAsDBM(${id})`
172
161
  const table = opt.table || this.cfg.table
173
162
  const started = this.logStarted(op, table)
174
- let [dbm] = await (opt.tx || this.cfg.db).getByIds<Saved<DBM>>(table, [id])
163
+ let [dbm] = await (opt.tx || this.cfg.db).getByIds<DBM>(table, [id])
175
164
  if (dbm && !opt.raw && this.cfg.hooks!.afterLoad) {
176
165
  dbm = (await this.cfg.hooks!.afterLoad(dbm)) || undefined
177
166
  }
@@ -183,34 +172,12 @@ export class CommonDao<
183
172
  return dbm || null
184
173
  }
185
174
 
186
- async getByIdAsTM(id: undefined | null, opt?: CommonDaoOptions): Promise<null>
187
- async getByIdAsTM(id?: string | null, opt?: CommonDaoOptions): Promise<TM | null>
188
- async getByIdAsTM(id?: string | null, opt: CommonDaoOptions = {}): Promise<TM | null> {
189
- if (!id) return null
190
- const op = `getByIdAsTM(${id})`
191
- const table = opt.table || this.cfg.table
192
- const started = this.logStarted(op, table)
193
- let [dbm] = await (opt.tx || this.cfg.db).getByIds<Saved<DBM>>(table, [id])
194
- if (dbm && !opt.raw && this.cfg.hooks!.afterLoad) {
195
- dbm = (await this.cfg.hooks!.afterLoad(dbm)) || undefined
196
- }
197
-
198
- if (opt.raw) {
199
- this.logResult(started, op, dbm, table)
200
- return (dbm as any) || null
201
- }
202
- const bm = await this.dbmToBM(dbm, opt)
203
- const tm = this.bmToTM(bm, opt)
204
- this.logResult(started, op, tm, table)
205
- return tm || null
206
- }
207
-
208
- async getByIds(ids: string[], opt: CommonDaoOptions = {}): Promise<Saved<BM>[]> {
175
+ async getByIds(ids: string[], opt: CommonDaoOptions = {}): Promise<BM[]> {
209
176
  if (!ids.length) return []
210
177
  const op = `getByIds ${ids.length} id(s) (${_truncate(ids.slice(0, 10).join(', '), 50)})`
211
178
  const table = opt.table || this.cfg.table
212
179
  const started = this.logStarted(op, table)
213
- let dbms = await (opt.tx || this.cfg.db).getByIds<Saved<DBM>>(table, ids)
180
+ let dbms = await (opt.tx || this.cfg.db).getByIds<DBM>(table, ids)
214
181
  if (!opt.raw && this.cfg.hooks!.afterLoad && dbms.length) {
215
182
  dbms = (await pMap(dbms, async dbm => await this.cfg.hooks!.afterLoad!(dbm))).filter(
216
183
  _isTruthy,
@@ -222,12 +189,12 @@ export class CommonDao<
222
189
  return bms
223
190
  }
224
191
 
225
- async getByIdsAsDBM(ids: string[], opt: CommonDaoOptions = {}): Promise<Saved<DBM>[]> {
192
+ async getByIdsAsDBM(ids: string[], opt: CommonDaoOptions = {}): Promise<DBM[]> {
226
193
  if (!ids.length) return []
227
194
  const op = `getByIdsAsDBM ${ids.length} id(s) (${_truncate(ids.slice(0, 10).join(', '), 50)})`
228
195
  const table = opt.table || this.cfg.table
229
196
  const started = this.logStarted(op, table)
230
- let dbms = await (opt.tx || this.cfg.db).getByIds<Saved<DBM>>(table, ids)
197
+ let dbms = await (opt.tx || this.cfg.db).getByIds<DBM>(table, ids)
231
198
  if (!opt.raw && this.cfg.hooks!.afterLoad && dbms.length) {
232
199
  dbms = (await pMap(dbms, async dbm => await this.cfg.hooks!.afterLoad!(dbm))).filter(
233
200
  _isTruthy,
@@ -238,7 +205,7 @@ export class CommonDao<
238
205
  return dbms
239
206
  }
240
207
 
241
- async requireById(id: string, opt: CommonDaoOptions = {}): Promise<Saved<BM>> {
208
+ async requireById(id: string, opt: CommonDaoOptions = {}): Promise<BM> {
242
209
  const r = await this.getById(id, opt)
243
210
  if (!r) {
244
211
  this.throwRequiredError(id, opt)
@@ -246,7 +213,7 @@ export class CommonDao<
246
213
  return r
247
214
  }
248
215
 
249
- async requireByIdAsDBM(id: string, opt: CommonDaoOptions = {}): Promise<Saved<DBM>> {
216
+ async requireByIdAsDBM(id: string, opt: CommonDaoOptions = {}): Promise<DBM> {
250
217
  const r = await this.getByIdAsDBM(id, opt)
251
218
  if (!r) {
252
219
  this.throwRequiredError(id, opt)
@@ -295,16 +262,16 @@ export class CommonDao<
295
262
  }
296
263
  }
297
264
 
298
- async getBy(by: keyof DBM, value: any, limit = 0, opt?: CommonDaoOptions): Promise<Saved<BM>[]> {
265
+ async getBy(by: keyof DBM, value: any, limit = 0, opt?: CommonDaoOptions): Promise<BM[]> {
299
266
  return await this.query().filterEq(by, value).limit(limit).runQuery(opt)
300
267
  }
301
268
 
302
- async getOneBy(by: keyof DBM, value: any, opt?: CommonDaoOptions): Promise<Saved<BM> | null> {
269
+ async getOneBy(by: keyof DBM, value: any, opt?: CommonDaoOptions): Promise<BM | null> {
303
270
  const [bm] = await this.query().filterEq(by, value).limit(1).runQuery(opt)
304
271
  return bm || null
305
272
  }
306
273
 
307
- async getAll(opt?: CommonDaoOptions): Promise<Saved<BM>[]> {
274
+ async getAll(opt?: CommonDaoOptions): Promise<BM[]> {
308
275
  return await this.query().runQuery(opt)
309
276
  }
310
277
 
@@ -312,11 +279,11 @@ export class CommonDao<
312
279
  /**
313
280
  * Pass `table` to override table
314
281
  */
315
- query(table?: string): RunnableDBQuery<BM, DBM, TM> {
316
- return new RunnableDBQuery<BM, DBM, TM>(this, table)
282
+ query(table?: string): RunnableDBQuery<BM, DBM> {
283
+ return new RunnableDBQuery<BM, DBM>(this, table)
317
284
  }
318
285
 
319
- async runQuery(q: DBQuery<DBM>, opt?: CommonDaoOptions): Promise<Saved<BM>[]> {
286
+ async runQuery(q: DBQuery<DBM>, opt?: CommonDaoOptions): Promise<BM[]> {
320
287
  const { rows } = await this.runQueryExtended(q, opt)
321
288
  return rows
322
289
  }
@@ -338,21 +305,18 @@ export class CommonDao<
338
305
  * Does deduplication by id.
339
306
  * Order is not guaranteed, as queries run in parallel.
340
307
  */
341
- async runUnionQueries(queries: DBQuery<DBM>[], opt?: CommonDaoOptions): Promise<Saved<BM>[]> {
308
+ async runUnionQueries(queries: DBQuery<DBM>[], opt?: CommonDaoOptions): Promise<BM[]> {
342
309
  const results = (
343
310
  await pMap(queries, async q => (await this.runQueryExtended(q, opt)).rows)
344
311
  ).flat()
345
312
  return _uniqBy(results, r => r.id)
346
313
  }
347
314
 
348
- async runQueryExtended(
349
- q: DBQuery<DBM>,
350
- opt: CommonDaoOptions = {},
351
- ): Promise<RunQueryResult<Saved<BM>>> {
315
+ async runQueryExtended(q: DBQuery<DBM>, opt: CommonDaoOptions = {}): Promise<RunQueryResult<BM>> {
352
316
  q.table = opt.table || q.table
353
317
  const op = `runQuery(${q.pretty()})`
354
318
  const started = this.logStarted(op, q.table)
355
- let { rows, ...queryResult } = await this.cfg.db.runQuery<Saved<DBM>>(q, opt)
319
+ let { rows, ...queryResult } = await this.cfg.db.runQuery<DBM>(q, opt)
356
320
  const partialQuery = !!q._selectedFieldNames
357
321
  if (!opt.raw && this.cfg.hooks!.afterLoad && rows.length) {
358
322
  rows = (await pMap(rows, async dbm => await this.cfg.hooks!.afterLoad!(dbm))).filter(
@@ -368,7 +332,7 @@ export class CommonDao<
368
332
  }
369
333
  }
370
334
 
371
- async runQueryAsDBM(q: DBQuery<DBM>, opt?: CommonDaoOptions): Promise<Saved<DBM>[]> {
335
+ async runQueryAsDBM(q: DBQuery<DBM>, opt?: CommonDaoOptions): Promise<DBM[]> {
372
336
  const { rows } = await this.runQueryExtendedAsDBM(q, opt)
373
337
  return rows
374
338
  }
@@ -376,11 +340,11 @@ export class CommonDao<
376
340
  async runQueryExtendedAsDBM(
377
341
  q: DBQuery<DBM>,
378
342
  opt: CommonDaoOptions = {},
379
- ): Promise<RunQueryResult<Saved<DBM>>> {
343
+ ): Promise<RunQueryResult<DBM>> {
380
344
  q.table = opt.table || q.table
381
345
  const op = `runQueryAsDBM(${q.pretty()})`
382
346
  const started = this.logStarted(op, q.table)
383
- let { rows, ...queryResult } = await this.cfg.db.runQuery<Saved<DBM>>(q, opt)
347
+ let { rows, ...queryResult } = await this.cfg.db.runQuery<DBM>(q, opt)
384
348
  if (!opt.raw && this.cfg.hooks!.afterLoad && rows.length) {
385
349
  rows = (await pMap(rows, async dbm => await this.cfg.hooks!.afterLoad!(dbm))).filter(
386
350
  _isTruthy,
@@ -393,35 +357,6 @@ export class CommonDao<
393
357
  return { rows: dbms, ...queryResult }
394
358
  }
395
359
 
396
- async runQueryAsTM(q: DBQuery<DBM>, opt?: CommonDaoOptions): Promise<TM[]> {
397
- const { rows } = await this.runQueryExtendedAsTM(q, opt)
398
- return rows
399
- }
400
-
401
- async runQueryExtendedAsTM(
402
- q: DBQuery<DBM>,
403
- opt: CommonDaoOptions = {},
404
- ): Promise<RunQueryResult<TM>> {
405
- q.table = opt.table || q.table
406
- const op = `runQueryAsTM(${q.pretty()})`
407
- const started = this.logStarted(op, q.table)
408
- let { rows, ...queryResult } = await this.cfg.db.runQuery<Saved<DBM>>(q, opt)
409
- if (!opt.raw && this.cfg.hooks!.afterLoad && rows.length) {
410
- rows = (await pMap(rows, async dbm => await this.cfg.hooks!.afterLoad!(dbm))).filter(
411
- _isTruthy,
412
- )
413
- }
414
-
415
- const partialQuery = !!q._selectedFieldNames
416
- const tms =
417
- partialQuery || opt.raw ? (rows as any[]) : this.bmsToTM(await this.dbmsToBM(rows, opt), opt)
418
- this.logResult(started, op, tms, q.table)
419
- return {
420
- rows: tms,
421
- ...queryResult,
422
- }
423
- }
424
-
425
360
  async runQueryCount(q: DBQuery<DBM>, opt: CommonDaoOptions = {}): Promise<number> {
426
361
  q.table = opt.table || q.table
427
362
  const op = `runQueryCount(${q.pretty()})`
@@ -435,8 +370,8 @@ export class CommonDao<
435
370
 
436
371
  async streamQueryForEach(
437
372
  q: DBQuery<DBM>,
438
- mapper: AsyncMapper<Saved<BM>, void>,
439
- opt: CommonDaoStreamForEachOptions<Saved<BM>> = {},
373
+ mapper: AsyncMapper<BM, void>,
374
+ opt: CommonDaoStreamForEachOptions<BM> = {},
440
375
  ): Promise<void> {
441
376
  q.table = opt.table || q.table
442
377
  opt.skipValidation = opt.skipValidation !== false // default true
@@ -450,7 +385,7 @@ export class CommonDao<
450
385
 
451
386
  await _pipeline([
452
387
  this.cfg.db.streamQuery<DBM>(q, opt),
453
- transformMap<Saved<DBM>, Saved<BM>>(
388
+ transformMap<DBM, BM>(
454
389
  async dbm => {
455
390
  count++
456
391
  if (partialQuery || opt.raw) return dbm as any
@@ -466,7 +401,7 @@ export class CommonDao<
466
401
  errorMode: opt.errorMode,
467
402
  },
468
403
  ),
469
- transformMap<Saved<BM>, void>(mapper, {
404
+ transformMap<BM, void>(mapper, {
470
405
  ...opt,
471
406
  predicate: _passthroughPredicate, // to be able to logProgress
472
407
  }),
@@ -485,7 +420,7 @@ export class CommonDao<
485
420
 
486
421
  async streamQueryAsDBMForEach(
487
422
  q: DBQuery<DBM>,
488
- mapper: AsyncMapper<Saved<DBM>, void>,
423
+ mapper: AsyncMapper<DBM, void>,
489
424
  opt: CommonDaoStreamForEachOptions<DBM> = {},
490
425
  ): Promise<void> {
491
426
  q.table = opt.table || q.table
@@ -516,7 +451,7 @@ export class CommonDao<
516
451
  errorMode: opt.errorMode,
517
452
  },
518
453
  ),
519
- transformMap<Saved<DBM>, void>(mapper, {
454
+ transformMap<DBM, void>(mapper, {
520
455
  ...opt,
521
456
  predicate: _passthroughPredicate, // to be able to logProgress
522
457
  }),
@@ -536,10 +471,7 @@ export class CommonDao<
536
471
  /**
537
472
  * Stream as Readable, to be able to .pipe() it further with support of backpressure.
538
473
  */
539
- streamQueryAsDBM(
540
- q: DBQuery<DBM>,
541
- opt: CommonDaoStreamOptions<DBM> = {},
542
- ): ReadableTyped<Saved<DBM>> {
474
+ streamQueryAsDBM(q: DBQuery<DBM>, opt: CommonDaoStreamOptions<DBM> = {}): ReadableTyped<DBM> {
543
475
  q.table = opt.table || q.table
544
476
  opt.skipValidation = opt.skipValidation !== false // default true
545
477
  opt.skipConversion = opt.skipConversion !== false // default true
@@ -553,7 +485,7 @@ export class CommonDao<
553
485
  return stream
554
486
  .on('error', err => stream.emit('error', err))
555
487
  .pipe(
556
- transformMap<any, Saved<DBM>>(
488
+ transformMap<any, DBM>(
557
489
  async dbm => {
558
490
  if (this.cfg.hooks!.afterLoad) {
559
491
  dbm = (await this.cfg.hooks!.afterLoad(dbm))!
@@ -578,10 +510,7 @@ export class CommonDao<
578
510
  *
579
511
  * You can do `.pipe(transformNoOp)` to make it "valid again".
580
512
  */
581
- streamQuery(
582
- q: DBQuery<DBM>,
583
- opt: CommonDaoStreamOptions<Saved<BM>> = {},
584
- ): ReadableTyped<Saved<BM>> {
513
+ streamQuery(q: DBQuery<DBM>, opt: CommonDaoStreamOptions<BM> = {}): ReadableTyped<BM> {
585
514
  q.table = opt.table || q.table
586
515
  opt.skipValidation = opt.skipValidation !== false // default true
587
516
  opt.skipConversion = opt.skipConversion !== false // default true
@@ -595,10 +524,10 @@ export class CommonDao<
595
524
  stream
596
525
  // optimization: 1 validation is enough
597
526
  // .pipe(transformMap<any, DBM>(dbm => this.anyToDBM(dbm, opt), safeOpt))
598
- // .pipe(transformMap<DBM, Saved<BM>>(dbm => this.dbmToBM(dbm, opt), safeOpt))
527
+ // .pipe(transformMap<DBM, BM>(dbm => this.dbmToBM(dbm, opt), safeOpt))
599
528
  .on('error', err => stream.emit('error', err))
600
529
  .pipe(
601
- transformMap<Saved<DBM>, Saved<BM>>(
530
+ transformMap<DBM, BM>(
602
531
  async dbm => {
603
532
  if (this.cfg.hooks!.afterLoad) {
604
533
  dbm = (await this.cfg.hooks!.afterLoad(dbm))!
@@ -632,7 +561,7 @@ export class CommonDao<
632
561
  .streamQuery<DBM>(q.select(['id']), opt)
633
562
  .on('error', err => stream.emit('error', err))
634
563
  .pipe(
635
- transformMapSimple<Saved<DBM>, string>(r => r.id, {
564
+ transformMapSimple<DBM, string>(r => r.id, {
636
565
  errorMode: ErrorMode.SUPPRESS, // cause .pipe() cannot propagate errors
637
566
  }),
638
567
  )
@@ -654,7 +583,7 @@ export class CommonDao<
654
583
 
655
584
  await _pipeline([
656
585
  this.cfg.db.streamQuery<DBM>(q.select(['id']), opt),
657
- transformMapSimple<Saved<DBM>, string>(r => {
586
+ transformMapSimple<DBM, string>(r => {
658
587
  count++
659
588
  return r.id
660
589
  }),
@@ -701,17 +630,17 @@ export class CommonDao<
701
630
  /**
702
631
  * Mutates with id, created, updated
703
632
  */
704
- async save(bm: UnsavedId<BM>, opt: CommonDaoSaveOptions<BM, DBM> = {}): Promise<Saved<BM>> {
633
+ async save(bm: Unsaved<BM>, opt: CommonDaoSaveOptions<BM, DBM> = {}): Promise<BM> {
705
634
  this.requireWriteAccess()
706
635
 
707
636
  if (opt.skipIfEquals && _deepJsonEquals(bm, opt.skipIfEquals)) {
708
637
  // Skipping the save operation
709
- return bm as Saved<BM>
638
+ return bm as BM
710
639
  }
711
640
 
712
641
  const idWasGenerated = !bm.id && this.cfg.generateId
713
642
  this.assignIdCreatedUpdated(bm, opt) // mutates
714
- _typeCast<Saved<BM>>(bm)
643
+ _typeCast<BM>(bm)
715
644
  let dbm = await this.bmToDBM(bm, opt)
716
645
 
717
646
  if (this.cfg.hooks!.beforeSave) {
@@ -751,11 +680,7 @@ export class CommonDao<
751
680
  * Similar to `save` with skipIfEquals.
752
681
  * Similar to `patch`, but doesn't load the object from the Database.
753
682
  */
754
- async savePatch(
755
- bm: BM,
756
- patch: Partial<BM>,
757
- opt: CommonDaoSaveBatchOptions<DBM>,
758
- ): Promise<Saved<BM>> {
683
+ async savePatch(bm: BM, patch: Partial<BM>, opt: CommonDaoSaveBatchOptions<DBM>): Promise<BM> {
759
684
  const patched: BM = {
760
685
  ...bm,
761
686
  ...patch,
@@ -763,7 +688,7 @@ export class CommonDao<
763
688
 
764
689
  if (_deepJsonEquals(bm, patched)) {
765
690
  // Skipping the save operation, as data is the same
766
- return bm as Saved<BM>
691
+ return bm
767
692
  }
768
693
 
769
694
  // Actually apply the patch by mutating the original object (by design)
@@ -785,7 +710,7 @@ export class CommonDao<
785
710
  id: string,
786
711
  patch: Partial<BM>,
787
712
  opt: CommonDaoSaveBatchOptions<DBM> = {},
788
- ): Promise<Saved<BM>> {
713
+ ): Promise<BM> {
789
714
  if (this.cfg.patchInTransaction && !opt.tx) {
790
715
  // patchInTransaction means that we should run this op in Transaction
791
716
  // But if opt.tx is passed - means that we are already in a Transaction,
@@ -793,7 +718,7 @@ export class CommonDao<
793
718
  return await this.patchByIdInTransaction(id, patch, opt)
794
719
  }
795
720
 
796
- let patched: Saved<BM>
721
+ let patched: BM
797
722
  const loaded = await this.getById(id, opt)
798
723
 
799
724
  if (loaded) {
@@ -817,7 +742,7 @@ export class CommonDao<
817
742
  id: string,
818
743
  patch: Partial<BM>,
819
744
  opt?: CommonDaoSaveBatchOptions<DBM>,
820
- ): Promise<Saved<BM>> {
745
+ ): Promise<BM> {
821
746
  return await this.runInTransaction(async daoTx => {
822
747
  return await this.patchById(id, patch, { ...opt, tx: daoTx.tx })
823
748
  })
@@ -829,11 +754,7 @@ export class CommonDao<
829
754
  * Otherwise, similar behavior as patchById.
830
755
  * It still loads the row from the DB.
831
756
  */
832
- async patch(
833
- bm: BM,
834
- patch: Partial<BM>,
835
- opt: CommonDaoSaveBatchOptions<DBM> = {},
836
- ): Promise<Saved<BM>> {
757
+ async patch(bm: BM, patch: Partial<BM>, opt: CommonDaoSaveBatchOptions<DBM> = {}): Promise<BM> {
837
758
  if (this.cfg.patchInTransaction && !opt.tx) {
838
759
  // patchInTransaction means that we should run this op in Transaction
839
760
  // But if opt.tx is passed - means that we are already in a Transaction,
@@ -848,7 +769,7 @@ export class CommonDao<
848
769
 
849
770
  if (_deepJsonEquals(loaded, bm)) {
850
771
  // Skipping the save operation, as data is the same
851
- return bm as Saved<BM>
772
+ return bm
852
773
  }
853
774
 
854
775
  // Make `bm` exactly the same as `loaded`
@@ -867,22 +788,19 @@ export class CommonDao<
867
788
  bm: BM,
868
789
  patch: Partial<BM>,
869
790
  opt?: CommonDaoSaveBatchOptions<DBM>,
870
- ): Promise<Saved<BM>> {
791
+ ): Promise<BM> {
871
792
  return await this.runInTransaction(async daoTx => {
872
793
  return await this.patch(bm, patch, { ...opt, tx: daoTx.tx })
873
794
  })
874
795
  }
875
796
 
876
- async saveAsDBM(
877
- dbm: UnsavedId<DBM>,
878
- opt: CommonDaoSaveBatchOptions<DBM> = {},
879
- ): Promise<Saved<DBM>> {
797
+ async saveAsDBM(dbm: Unsaved<DBM>, opt: CommonDaoSaveBatchOptions<DBM> = {}): Promise<DBM> {
880
798
  this.requireWriteAccess()
881
799
  const table = opt.table || this.cfg.table
882
800
 
883
801
  // assigning id in case it misses the id
884
802
  // will override/set `updated` field, unless opts.preserveUpdated is set
885
- let row = dbm as Saved<DBM>
803
+ let row = dbm as DBM
886
804
  if (!opt.raw) {
887
805
  const idWasGenerated = !dbm.id && this.cfg.generateId
888
806
  this.assignIdCreatedUpdated(dbm, opt) // mutates
@@ -899,7 +817,7 @@ export class CommonDao<
899
817
 
900
818
  if (this.cfg.hooks!.beforeSave) {
901
819
  row = (await this.cfg.hooks!.beforeSave(row))!
902
- if (row === null) return dbm as Saved<DBM>
820
+ if (row === null) return dbm as DBM
903
821
  }
904
822
 
905
823
  await (opt.tx || this.cfg.db).saveBatch(table, [row], {
@@ -916,10 +834,7 @@ export class CommonDao<
916
834
  return row
917
835
  }
918
836
 
919
- async saveBatch(
920
- bms: UnsavedId<BM>[],
921
- opt: CommonDaoSaveBatchOptions<DBM> = {},
922
- ): Promise<Saved<BM>[]> {
837
+ async saveBatch(bms: Unsaved<BM>[], opt: CommonDaoSaveBatchOptions<DBM> = {}): Promise<BM[]> {
923
838
  if (!bms.length) return []
924
839
  this.requireWriteAccess()
925
840
  const table = opt.table || this.cfg.table
@@ -960,20 +875,20 @@ export class CommonDao<
960
875
 
961
876
  this.logSaveResult(started, op, table)
962
877
 
963
- return bms as Saved<BM>[]
878
+ return bms as BM[]
964
879
  }
965
880
 
966
881
  async saveBatchAsDBM(
967
- dbms: UnsavedId<DBM>[],
882
+ dbms: Unsaved<DBM>[],
968
883
  opt: CommonDaoSaveBatchOptions<DBM> = {},
969
- ): Promise<Saved<DBM>[]> {
884
+ ): Promise<DBM[]> {
970
885
  if (!dbms.length) return []
971
886
  this.requireWriteAccess()
972
887
  const table = opt.table || this.cfg.table
973
- let rows = dbms as Saved<DBM>[]
888
+ let rows = dbms as DBM[]
974
889
  if (!opt.raw) {
975
890
  dbms.forEach(dbm => this.assignIdCreatedUpdated(dbm, opt)) // mutates
976
- rows = this.anyToDBMs(dbms as Saved<DBM>[], opt)
891
+ rows = this.anyToDBMs(dbms as DBM[], opt)
977
892
  if (opt.ensureUniqueId) throw new AppError('ensureUniqueId is not supported in saveBatch')
978
893
  }
979
894
  if (this.cfg.immutable && !opt.allowMutability && !opt.saveMethod) {
@@ -1034,7 +949,7 @@ export class CommonDao<
1034
949
  const { batchSize = 500, batchConcurrency = 16, errorMode } = opt
1035
950
 
1036
951
  return [
1037
- transformMap<BM, Saved<DBM>>(
952
+ transformMap<BM, DBM>(
1038
953
  async bm => {
1039
954
  this.assignIdCreatedUpdated(bm, opt) // mutates
1040
955
 
@@ -1191,8 +1106,8 @@ export class CommonDao<
1191
1106
  // CONVERSIONS
1192
1107
 
1193
1108
  async dbmToBM(_dbm: undefined, opt?: CommonDaoOptions): Promise<undefined>
1194
- async dbmToBM(_dbm?: DBM, opt?: CommonDaoOptions): Promise<Saved<BM>>
1195
- async dbmToBM(_dbm?: DBM, opt: CommonDaoOptions = {}): Promise<Saved<BM> | undefined> {
1109
+ async dbmToBM(_dbm?: DBM, opt?: CommonDaoOptions): Promise<BM>
1110
+ async dbmToBM(_dbm?: DBM, opt: CommonDaoOptions = {}): Promise<BM | undefined> {
1196
1111
  if (!_dbm) return
1197
1112
 
1198
1113
  // optimization: no need to run full joi DBM validation, cause BM validation will be run
@@ -1211,7 +1126,7 @@ export class CommonDao<
1211
1126
  return this.validateAndConvert(bm, this.cfg.bmSchema, DBModelType.BM, opt)
1212
1127
  }
1213
1128
 
1214
- async dbmsToBM(dbms: DBM[], opt: CommonDaoOptions = {}): Promise<Saved<BM>[]> {
1129
+ async dbmsToBM(dbms: DBM[], opt: CommonDaoOptions = {}): Promise<BM[]> {
1215
1130
  return await pMap(dbms, async dbm => await this.dbmToBM(dbm, opt))
1216
1131
  }
1217
1132
 
@@ -1220,8 +1135,8 @@ export class CommonDao<
1220
1135
  * Returns DBM (new reference).
1221
1136
  */
1222
1137
  async bmToDBM(bm: undefined, opt?: CommonDaoOptions): Promise<undefined>
1223
- async bmToDBM(bm?: BM, opt?: CommonDaoOptions): Promise<Saved<DBM>>
1224
- async bmToDBM(bm?: BM, opt?: CommonDaoOptions): Promise<Saved<DBM> | undefined> {
1138
+ async bmToDBM(bm?: BM, opt?: CommonDaoOptions): Promise<DBM>
1139
+ async bmToDBM(bm?: BM, opt?: CommonDaoOptions): Promise<DBM | undefined> {
1225
1140
  if (bm === undefined) return
1226
1141
 
1227
1142
  // optimization: no need to run the BM validation, since DBM will be validated anyway
@@ -1240,14 +1155,14 @@ export class CommonDao<
1240
1155
  return this.validateAndConvert(dbm, this.cfg.dbmSchema, DBModelType.DBM, opt)
1241
1156
  }
1242
1157
 
1243
- async bmsToDBM(bms: BM[], opt: CommonDaoOptions = {}): Promise<Saved<DBM>[]> {
1158
+ async bmsToDBM(bms: BM[], opt: CommonDaoOptions = {}): Promise<DBM[]> {
1244
1159
  // try/catch?
1245
1160
  return await pMap(bms, async bm => await this.bmToDBM(bm, opt))
1246
1161
  }
1247
1162
 
1248
1163
  anyToDBM(dbm: undefined, opt?: CommonDaoOptions): undefined
1249
- anyToDBM(dbm?: any, opt?: CommonDaoOptions): Saved<DBM>
1250
- anyToDBM(dbm?: DBM, opt: CommonDaoOptions = {}): Saved<DBM> | undefined {
1164
+ anyToDBM(dbm?: any, opt?: CommonDaoOptions): DBM
1165
+ anyToDBM(dbm?: DBM, opt: CommonDaoOptions = {}): DBM | undefined {
1251
1166
  if (!dbm) return
1252
1167
 
1253
1168
  // this shouldn't be happening on load! but should on save!
@@ -1263,32 +1178,10 @@ export class CommonDao<
1263
1178
  return this.validateAndConvert(dbm, this.cfg.dbmSchema, DBModelType.DBM, opt)
1264
1179
  }
1265
1180
 
1266
- anyToDBMs(entities: DBM[], opt: CommonDaoOptions = {}): Saved<DBM>[] {
1181
+ anyToDBMs(entities: DBM[], opt: CommonDaoOptions = {}): DBM[] {
1267
1182
  return entities.map(entity => this.anyToDBM(entity, opt))
1268
1183
  }
1269
1184
 
1270
- bmToTM(bm: undefined, opt?: CommonDaoOptions): TM | undefined
1271
- bmToTM(bm?: BM, opt?: CommonDaoOptions): TM
1272
- bmToTM(bm?: BM, opt?: CommonDaoOptions): TM | undefined {
1273
- if (bm === undefined) return
1274
-
1275
- // optimization: 1 validation is enough
1276
- // Validate/convert BM
1277
- // bm gets assigned to the new reference
1278
- // bm = this.validateAndConvert(bm, this.cfg.bmSchema, DBModelType.BM, opt)
1279
-
1280
- // BM > TM
1281
- const tm = this.cfg.hooks!.beforeBMToTM!(bm)
1282
-
1283
- // Validate/convert DBM
1284
- return this.validateAndConvert(tm, this.cfg.tmSchema, DBModelType.TM, opt)
1285
- }
1286
-
1287
- bmsToTM(bms: BM[], opt: CommonDaoOptions = {}): TM[] {
1288
- // try/catch?
1289
- return bms.map(bm => this.bmToTM(bm, opt))
1290
- }
1291
-
1292
1185
  /**
1293
1186
  * Returns *converted value*.
1294
1187
  * Validates (unless `skipValidation=true` passed).
@@ -1298,7 +1191,7 @@ export class CommonDao<
1298
1191
  validateAndConvert<T>(
1299
1192
  obj: Partial<T>,
1300
1193
  schema: ObjectSchema<T> | AjvSchema<T> | ZodSchema<T> | undefined,
1301
- modelType: DBModelType,
1194
+ modelType?: DBModelType,
1302
1195
  opt: CommonDaoOptions = {},
1303
1196
  ): any {
1304
1197
  // `raw` option completely bypasses any processing
@@ -1488,18 +1381,18 @@ export class CommonDaoTransaction {
1488
1381
  }
1489
1382
 
1490
1383
  async getById<BM extends BaseDBEntity, DBM extends BaseDBEntity>(
1491
- dao: CommonDao<BM, DBM, any>,
1384
+ dao: CommonDao<BM, DBM>,
1492
1385
  id?: string | null,
1493
1386
  opt?: CommonDaoOptions,
1494
- ): Promise<Saved<BM> | null> {
1387
+ ): Promise<BM | null> {
1495
1388
  return await dao.getById(id, { ...opt, tx: this.tx })
1496
1389
  }
1497
1390
 
1498
1391
  async getByIds<BM extends BaseDBEntity, DBM extends BaseDBEntity>(
1499
- dao: CommonDao<BM, DBM, any>,
1392
+ dao: CommonDao<BM, DBM>,
1500
1393
  ids: string[],
1501
1394
  opt?: CommonDaoOptions,
1502
- ): Promise<Saved<BM>[]> {
1395
+ ): Promise<BM[]> {
1503
1396
  return await dao.getByIds(ids, { ...opt, tx: this.tx })
1504
1397
  }
1505
1398
 
@@ -1508,7 +1401,7 @@ export class CommonDaoTransaction {
1508
1401
  // dao: CommonDao<BM, DBM, any>,
1509
1402
  // q: DBQuery<DBM>,
1510
1403
  // opt?: CommonDaoOptions,
1511
- // ): Promise<Saved<BM>[]> {
1404
+ // ): Promise<BM[]> {
1512
1405
  // try {
1513
1406
  // return await dao.runQuery(q, { ...opt, tx: this.tx })
1514
1407
  // } catch (err) {
@@ -1518,18 +1411,18 @@ export class CommonDaoTransaction {
1518
1411
  // }
1519
1412
 
1520
1413
  async save<BM extends BaseDBEntity, DBM extends BaseDBEntity>(
1521
- dao: CommonDao<BM, DBM, any>,
1522
- bm: UnsavedId<BM>,
1414
+ dao: CommonDao<BM, DBM>,
1415
+ bm: Unsaved<BM>,
1523
1416
  opt?: CommonDaoSaveBatchOptions<DBM>,
1524
- ): Promise<Saved<BM>> {
1417
+ ): Promise<BM> {
1525
1418
  return (await this.saveBatch(dao, [bm], opt))[0]!
1526
1419
  }
1527
1420
 
1528
1421
  async saveBatch<BM extends BaseDBEntity, DBM extends BaseDBEntity>(
1529
- dao: CommonDao<BM, DBM, any>,
1530
- bms: UnsavedId<BM>[],
1422
+ dao: CommonDao<BM, DBM>,
1423
+ bms: Unsaved<BM>[],
1531
1424
  opt?: CommonDaoSaveBatchOptions<DBM>,
1532
- ): Promise<Saved<BM>[]> {
1425
+ ): Promise<BM[]> {
1533
1426
  return await dao.saveBatch(bms, { ...opt, tx: this.tx })
1534
1427
  }
1535
1428