prostgles-types 4.0.113 → 4.0.115

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/lib/util.ts CHANGED
@@ -2,20 +2,24 @@ import { AnyObject, JoinMaker, JoinPath, TS_COLUMN_DATA_TYPES } from ".";
2
2
  import { md5 } from "./md5";
3
3
 
4
4
  export function asName(str: string) {
5
- if (str === null || str === undefined || !str.toString || !str.toString()) throw "Expecting a non empty string";
5
+ if (str === null || str === undefined || !str.toString || !str.toString())
6
+ throw "Expecting a non empty string";
6
7
 
7
8
  return `"${str.toString().replace(/"/g, `""`)}"`;
8
9
  }
9
10
 
10
- export const pickKeys = <T extends AnyObject, Include extends keyof T>(obj: T, keys: Include[] = [], onlyIfDefined = true): Pick<T, Include> => {
11
+ export const pickKeys = <T extends AnyObject, Include extends keyof T>(
12
+ obj: T,
13
+ keys: Include[] = [],
14
+ onlyIfDefined = true
15
+ ): Pick<T, Include> => {
11
16
  if (!keys.length) {
12
17
  return {} as T;
13
18
  }
14
19
  if (obj && keys.length) {
15
20
  let res = {} as T;
16
- keys.forEach(k => {
17
- if(onlyIfDefined && obj[k] === undefined){
18
-
21
+ keys.forEach((k) => {
22
+ if (onlyIfDefined && obj[k] === undefined) {
19
23
  } else {
20
24
  res[k] = obj[k];
21
25
  }
@@ -24,104 +28,120 @@ export const pickKeys = <T extends AnyObject, Include extends keyof T>(obj: T, k
24
28
  }
25
29
 
26
30
  return obj;
27
- }
31
+ };
28
32
 
29
- export function omitKeys<T extends AnyObject, Exclude extends keyof T>(obj: T, exclude: Exclude[]): Omit<T, Exclude> {
30
- return pickKeys(obj, getKeys(obj).filter(k => !exclude.includes(k as any)))
33
+ export function omitKeys<T extends AnyObject, Exclude extends keyof T>(
34
+ obj: T,
35
+ exclude: Exclude[]
36
+ ): Omit<T, Exclude> {
37
+ return pickKeys(
38
+ obj,
39
+ getKeys(obj).filter((k) => !exclude.includes(k as any))
40
+ );
31
41
  }
32
42
 
33
- export function filter<T extends AnyObject, ArrFilter extends Partial<T>>(array: T[], arrFilter: ArrFilter): T[] {
34
- return array.filter(d => Object.entries(arrFilter).every(([k, v]) => d[k] === v))
43
+ export function filter<T extends AnyObject, ArrFilter extends Partial<T>>(
44
+ array: T[],
45
+ arrFilter: ArrFilter
46
+ ): T[] {
47
+ return array.filter((d) => Object.entries(arrFilter).every(([k, v]) => d[k] === v));
35
48
  }
36
- export function find<T extends AnyObject, ArrFilter extends Partial<T>>(array: T[], arrFilter: ArrFilter): T | undefined {
49
+ export function find<T extends AnyObject, ArrFilter extends Partial<T>>(
50
+ array: T[],
51
+ arrFilter: ArrFilter
52
+ ): T | undefined {
37
53
  return filter(array, arrFilter)[0];
38
54
  }
39
- export function includes<Arr extends any[] | readonly any[], Elem extends Arr[number]>(array: Arr, elem: Elem): boolean {
40
- return array.some(v => v === elem);
55
+ export function includes<Arr extends any[] | readonly any[], Elem extends Arr[number]>(
56
+ array: Arr,
57
+ elem: Elem
58
+ ): boolean {
59
+ return array.some((v) => v === elem);
41
60
  }
42
61
 
43
62
  export function stableStringify(data: AnyObject, opts: any) {
44
63
  if (!opts) opts = {};
45
- if (typeof opts === 'function') opts = { cmp: opts };
46
- var cycles = (typeof opts.cycles === 'boolean') ? opts.cycles : false;
47
-
48
- var cmp = opts.cmp && (function (f) {
49
- return function (node: any) {
50
- return function (a: any, b: any) {
51
- var aobj = { key: a, value: node[a] };
52
- var bobj = { key: b, value: node[b] };
53
- return f(aobj, bobj);
64
+ if (typeof opts === "function") opts = { cmp: opts };
65
+ var cycles = typeof opts.cycles === "boolean" ? opts.cycles : false;
66
+
67
+ var cmp =
68
+ opts.cmp &&
69
+ (function (f) {
70
+ return function (node: any) {
71
+ return function (a: any, b: any) {
72
+ var aobj = { key: a, value: node[a] };
73
+ var bobj = { key: b, value: node[b] };
74
+ return f(aobj, bobj);
75
+ };
54
76
  };
55
- };
56
- })(opts.cmp);
77
+ })(opts.cmp);
57
78
 
58
79
  var seen: any[] = [];
59
80
  return (function stringify(node) {
60
- if (node && node.toJSON && typeof node.toJSON === 'function') {
81
+ if (node && node.toJSON && typeof node.toJSON === "function") {
61
82
  node = node.toJSON();
62
83
  }
63
84
 
64
85
  if (node === undefined) return;
65
- if (typeof node == 'number') return isFinite(node) ? '' + node : 'null';
66
- if (typeof node !== 'object') return JSON.stringify(node);
86
+ if (typeof node == "number") return isFinite(node) ? "" + node : "null";
87
+ if (typeof node !== "object") return JSON.stringify(node);
67
88
 
68
89
  var i, out;
69
90
  if (Array.isArray(node)) {
70
- out = '[';
91
+ out = "[";
71
92
  for (i = 0; i < node.length; i++) {
72
- if (i) out += ',';
73
- out += stringify(node[i]) || 'null';
93
+ if (i) out += ",";
94
+ out += stringify(node[i]) || "null";
74
95
  }
75
- return out + ']';
96
+ return out + "]";
76
97
  }
77
98
 
78
- if (node === null) return 'null';
99
+ if (node === null) return "null";
79
100
 
80
101
  if (seen.indexOf(node) !== -1) {
81
- if (cycles) return JSON.stringify('__cycle__');
82
- throw new TypeError('Converting circular structure to JSON');
102
+ if (cycles) return JSON.stringify("__cycle__");
103
+ throw new TypeError("Converting circular structure to JSON");
83
104
  }
84
105
 
85
106
  var seenIndex = seen.push(node) - 1;
86
107
  var keys = Object.keys(node).sort(cmp && cmp(node));
87
- out = '';
108
+ out = "";
88
109
  for (i = 0; i < keys.length; i++) {
89
110
  var key = keys[i]!;
90
111
  var value = stringify(node[key]);
91
112
 
92
113
  if (!value) continue;
93
- if (out) out += ',';
94
- out += JSON.stringify(key) + ':' + value;
114
+ if (out) out += ",";
115
+ out += JSON.stringify(key) + ":" + value;
95
116
  }
96
117
  seen.splice(seenIndex, 1);
97
- return '{' + out + '}';
118
+ return "{" + out + "}";
98
119
  })(data);
99
- };
100
-
120
+ }
101
121
 
102
122
  export type TextPatch = {
103
123
  from: number;
104
124
  to: number;
105
125
  text: string;
106
126
  md5: string;
107
- }
127
+ };
108
128
 
109
129
  export function getTextPatch(oldStr: string, newStr: string): TextPatch | string {
110
-
111
130
  /* Big change, no point getting diff */
112
131
  if (!oldStr || !newStr || !oldStr.trim().length || !newStr.trim().length) return newStr;
113
132
 
114
133
  /* Return no change if matching */
115
- if (oldStr === newStr) return {
116
- from: 0,
117
- to: 0,
118
- text: "",
119
- md5: md5(newStr)
120
- }
134
+ if (oldStr === newStr)
135
+ return {
136
+ from: 0,
137
+ to: 0,
138
+ text: "",
139
+ md5: md5(newStr),
140
+ };
121
141
 
122
142
  function findLastIdx(direction = 1) {
123
-
124
- let idx = direction < 1 ? -1 : 0, found = false;
143
+ let idx = direction < 1 ? -1 : 0,
144
+ found = false;
125
145
  while (!found && Math.abs(idx) <= newStr.length) {
126
146
  const args = direction < 1 ? [idx] : [0, idx];
127
147
 
@@ -142,21 +162,22 @@ export function getTextPatch(oldStr: string, newStr: string): TextPatch | string
142
162
  from,
143
163
  to,
144
164
  text: newStr.slice(from, toNew),
145
- md5: md5(newStr)
146
- }
165
+ md5: md5(newStr),
166
+ };
147
167
  }
148
168
 
149
-
150
169
  export function unpatchText(original: string | null, patch: TextPatch): string {
151
- if (!patch || typeof patch === "string") return (patch as unknown as string);
170
+ if (!patch || typeof patch === "string") return patch as unknown as string;
152
171
  const { from, to, text, md5: md5Hash } = patch;
153
172
  if (text === null || original === null) return text;
154
173
  let res = original.slice(0, from) + text + original.slice(to);
155
- if (md5Hash && md5(res) !== md5Hash) throw "Patch text error: Could not match md5 hash: (original/result) \n" + original + "\n" + res;
174
+ if (md5Hash && md5(res) !== md5Hash)
175
+ throw (
176
+ "Patch text error: Could not match md5 hash: (original/result) \n" + original + "\n" + res
177
+ );
156
178
  return res;
157
179
  }
158
180
 
159
-
160
181
  /* Replication */
161
182
  export type SyncTableInfo = {
162
183
  id_fields: string[];
@@ -214,14 +235,13 @@ export type WALItemsObj = Record<string, WALItem>;
214
235
  * This allows a high rate of optimistic updates on the client
215
236
  */
216
237
  export class WAL {
217
-
218
238
  /**
219
239
  * Instantly merged records for prepared for update
220
240
  */
221
241
  private changed: WALItemsObj = {};
222
242
 
223
243
  /**
224
- * Batch of records (removed from this.changed) that are currently being sent
244
+ * Batch of records (removed from this.changed) that are currently being sent
225
245
  */
226
246
  private sending: WALItemsObj = {};
227
247
 
@@ -231,18 +251,17 @@ export class WAL {
231
251
  private sentHistory: Record<string, AnyObject> = {};
232
252
 
233
253
  private options: WALConfig;
234
- private callbacks: { cb: Function, idStrs: string[] }[] = [];
254
+ private callbacks: { cb: Function; idStrs: string[] }[] = [];
235
255
 
236
256
  constructor(args: WALConfig) {
237
257
  this.options = { ...args };
238
258
  if (!this.options.orderBy) {
239
259
  const { synced_field, id_fields } = args;
240
- this.options.orderBy = [synced_field, ...id_fields.sort()]
241
- .map(fieldName => ({
242
- fieldName,
243
- tsDataType: fieldName === synced_field ? "number" : "string",
244
- asc: true
245
- }));
260
+ this.options.orderBy = [synced_field, ...id_fields.sort()].map((fieldName) => ({
261
+ fieldName,
262
+ tsDataType: fieldName === synced_field ? "number" : "string",
263
+ asc: true,
264
+ }));
246
265
  }
247
266
  }
248
267
 
@@ -250,27 +269,33 @@ export class WAL {
250
269
  const { orderBy } = this.options;
251
270
  if (!orderBy || !a || !b) return 0;
252
271
 
253
- return orderBy.map(ob => {
254
- /* TODO: add fullData to changed items + ensure orderBy is in select */
255
- if (!(ob.fieldName in a) || !(ob.fieldName in b)) {
256
- throw `Replication error: \n some orderBy fields missing from data`;
257
- }
258
- let v1 = ob.asc ? a[ob.fieldName] : b[ob.fieldName],
259
- v2 = ob.asc ? b[ob.fieldName] : a[ob.fieldName];
260
-
261
- let vNum = +v1 - +v2,
262
- vStr = v1 < v2 ? -1 : v1 == v2 ? 0 : 1;
263
- return (ob.tsDataType === "number" && Number.isFinite(vNum)) ? vNum : vStr
264
- }).find(v => v) || 0;
265
- }
272
+ return (
273
+ orderBy
274
+ .map((ob) => {
275
+ /* TODO: add fullData to changed items + ensure orderBy is in select */
276
+ if (!(ob.fieldName in a) || !(ob.fieldName in b)) {
277
+ throw `Replication error: \n some orderBy fields missing from data`;
278
+ }
279
+ let v1 = ob.asc ? a[ob.fieldName] : b[ob.fieldName],
280
+ v2 = ob.asc ? b[ob.fieldName] : a[ob.fieldName];
281
+
282
+ let vNum = +v1 - +v2,
283
+ vStr =
284
+ v1 < v2 ? -1
285
+ : v1 == v2 ? 0
286
+ : 1;
287
+ return ob.tsDataType === "number" && Number.isFinite(vNum) ? vNum : vStr;
288
+ })
289
+ .find((v) => v) || 0
290
+ );
291
+ };
266
292
 
267
293
  isSending(): boolean {
268
-
269
294
  const result = this.isOnSending || !(isEmpty(this.sending) && isEmpty(this.changed));
270
295
  if (this.options.DEBUG_MODE) {
271
- console.log(this.options.id, " CHECKING isSending ->", result)
296
+ console.log(this.options.id, " CHECKING isSending ->", result);
272
297
  }
273
- return result
298
+ return result;
274
299
  }
275
300
 
276
301
  /**
@@ -281,33 +306,38 @@ export class WAL {
281
306
  */
282
307
  isInHistory = (item: AnyObject): boolean => {
283
308
  if (!item) throw "Provide item";
284
- const itemSyncVal = item[this.options.synced_field]
285
- if (!Number.isFinite(+itemSyncVal)) throw "Provided item Synced field value is missing/invalid ";
309
+ const itemSyncVal = item[this.options.synced_field];
310
+ if (!Number.isFinite(+itemSyncVal))
311
+ throw "Provided item Synced field value is missing/invalid ";
286
312
 
287
313
  const existing = this.sentHistory[this.getIdStr(item)];
288
314
  const existingSyncVal = existing?.[this.options.synced_field];
289
315
  if (existing) {
290
- if (!Number.isFinite(+existingSyncVal)) throw "Provided historic item Synced field value is missing/invalid";
316
+ if (!Number.isFinite(+existingSyncVal))
317
+ throw "Provided historic item Synced field value is missing/invalid";
291
318
  if (+existingSyncVal === +itemSyncVal) {
292
- return true
319
+ return true;
293
320
  }
294
321
  }
295
322
  return false;
296
- }
323
+ };
297
324
 
298
325
  getIdStr(d: AnyObject): string {
299
- return this.options.id_fields.sort().map(key => `${d[key] || ""}`).join(".");
326
+ return this.options.id_fields
327
+ .sort()
328
+ .map((key) => `${d[key] || ""}`)
329
+ .join(".");
300
330
  }
301
331
  getIdObj(d: AnyObject): AnyObject {
302
332
  let res: AnyObject = {};
303
- this.options.id_fields.sort().map(key => {
333
+ this.options.id_fields.sort().map((key) => {
304
334
  res[key] = d[key];
305
335
  });
306
336
  return res;
307
337
  }
308
338
  getDeltaObj(d: AnyObject): AnyObject {
309
339
  let res: AnyObject = {};
310
- Object.keys(d).map(key => {
340
+ Object.keys(d).map((key) => {
311
341
  if (!this.options.id_fields.includes(key)) {
312
342
  res[key] = d[key];
313
343
  }
@@ -318,7 +348,7 @@ export class WAL {
318
348
  addData = (data: WALItem[]) => {
319
349
  if (isEmpty(this.changed) && this.options.onSendStart) this.options.onSendStart();
320
350
 
321
- data.map(d => {
351
+ data.map((d) => {
322
352
  const { initial, current, delta } = { ...d };
323
353
  if (!current) throw "Expecting { current: object, initial?: object }";
324
354
  const idStr = this.getIdStr(current);
@@ -327,24 +357,31 @@ export class WAL {
327
357
  this.changed[idStr] ??= { initial, current, delta };
328
358
  this.changed[idStr]!.current = {
329
359
  ...this.changed[idStr]!.current,
330
- ...current
360
+ ...current,
331
361
  };
332
362
  this.changed[idStr]!.delta = {
333
363
  ...this.changed[idStr]!.delta,
334
- ...delta
364
+ ...delta,
335
365
  };
336
366
  });
337
367
  this.sendItems();
338
- }
368
+ };
339
369
 
340
370
  isOnSending = false;
341
371
  isSendingTimeout?: ReturnType<typeof setTimeout> = undefined;
342
372
  willDeleteHistory?: ReturnType<typeof setTimeout> = undefined;
343
373
  private sendItems = async () => {
344
- const { DEBUG_MODE, onSend, onSendEnd, batch_size, throttle, historyAgeSeconds = 2 } = this.options;
374
+ const {
375
+ DEBUG_MODE,
376
+ onSend,
377
+ onSendEnd,
378
+ batch_size,
379
+ throttle,
380
+ historyAgeSeconds = 2,
381
+ } = this.options;
345
382
 
346
383
  // Sending data. stop here
347
- if (this.isSendingTimeout || this.sending && !isEmpty(this.sending)) return;
384
+ if (this.isSendingTimeout || (this.sending && !isEmpty(this.sending))) return;
348
385
 
349
386
  // Nothing to send. stop here
350
387
  if (!this.changed || isEmpty(this.changed)) return;
@@ -360,7 +397,7 @@ export class WAL {
360
397
  Object.keys(this.changed)
361
398
  .sort((a, b) => this.sort(this.changed[a]!.current, this.changed[b]!.current))
362
399
  .slice(0, batch_size)
363
- .map(key => {
400
+ .map((key) => {
364
401
  let item = { ...this.changed[key] } as WALItem;
365
402
  this.sending[key] = { ...item };
366
403
  walBatch.push({ ...item });
@@ -370,24 +407,24 @@ export class WAL {
370
407
 
371
408
  delete this.changed[key];
372
409
  });
373
- batchItems = walBatch.map(d => {
410
+ batchItems = walBatch.map((d) => {
374
411
  let result: AnyObject = {};
375
- Object.keys(d.current).map(k => {
412
+ Object.keys(d.current).map((k) => {
376
413
  const oldVal = d.initial?.[k];
377
414
  const newVal = d.current[k];
378
415
  /** Send only id fields and delta */
379
- if(
416
+ if (
380
417
  [this.options.synced_field, ...this.options.id_fields].includes(k) ||
381
418
  !areEqual(oldVal, newVal)
382
- ){
419
+ ) {
383
420
  result[k] = newVal;
384
421
  }
385
- })
422
+ });
386
423
  return result;
387
424
  });
388
425
 
389
426
  if (DEBUG_MODE) {
390
- console.log(this.options.id, " SENDING lr->", batchItems[batchItems.length - 1])
427
+ console.log(this.options.id, " SENDING lr->", batchItems[batchItems.length - 1]);
391
428
  }
392
429
 
393
430
  // Throttle next data send
@@ -400,12 +437,11 @@ export class WAL {
400
437
  }, throttle);
401
438
  }
402
439
 
403
-
404
440
  let error: any;
405
441
  this.isOnSending = true;
406
442
  try {
407
443
  /* Deleted data should be sent normally through await db.table.delete(...) */
408
- await onSend(batchItems, walBatch);//, deletedData);
444
+ await onSend(batchItems, walBatch); //, deletedData);
409
445
 
410
446
  /**
411
447
  * Keep history if required
@@ -414,7 +450,7 @@ export class WAL {
414
450
  this.sentHistory = {
415
451
  ...this.sentHistory,
416
452
  ...batchObj,
417
- }
453
+ };
418
454
  /**
419
455
  * Delete history after some time
420
456
  */
@@ -427,7 +463,7 @@ export class WAL {
427
463
  }
428
464
  } catch (err) {
429
465
  error = err;
430
- console.error("WAL onSend failed:", err, batchItems, walBatch)
466
+ console.error("WAL onSend failed:", err, batchItems, walBatch);
431
467
  }
432
468
  this.isOnSending = false;
433
469
 
@@ -435,17 +471,17 @@ export class WAL {
435
471
  if (this.callbacks.length) {
436
472
  const ids = Object.keys(this.sending);
437
473
  this.callbacks.forEach((c, i) => {
438
- c.idStrs = c.idStrs.filter(id => ids.includes(id));
474
+ c.idStrs = c.idStrs.filter((id) => ids.includes(id));
439
475
  if (!c.idStrs.length) {
440
476
  c.cb(error);
441
477
  }
442
478
  });
443
- this.callbacks = this.callbacks.filter(cb => cb.idStrs.length)
479
+ this.callbacks = this.callbacks.filter((cb) => cb.idStrs.length);
444
480
  }
445
481
 
446
482
  this.sending = {};
447
483
  if (DEBUG_MODE) {
448
- console.log(this.options.id, " SENT lr->", batchItems[batchItems.length - 1])
484
+ console.log(this.options.id, " SENT lr->", batchItems[batchItems.length - 1]);
449
485
  }
450
486
  if (!isEmpty(this.changed)) {
451
487
  this.sendItems();
@@ -453,17 +489,15 @@ export class WAL {
453
489
  if (onSendEnd) onSendEnd(batchItems, walBatch, error);
454
490
  }
455
491
  };
456
- };
492
+ }
457
493
 
458
494
  export function isEmpty(obj?: any): boolean {
459
495
  for (var v in obj) return false;
460
496
  return true;
461
497
  }
462
498
 
463
-
464
499
  /* Get nested property from an object */
465
500
  export function get(obj: any, propertyPath: string | string[]): any {
466
-
467
501
  let p = propertyPath,
468
502
  o = obj;
469
503
 
@@ -471,84 +505,93 @@ export function get(obj: any, propertyPath: string | string[]): any {
471
505
  if (typeof p === "string") p = p.split(".");
472
506
  return p.reduce((xs, x) => {
473
507
  if (xs && xs[x]) {
474
- return xs[x]
508
+ return xs[x];
475
509
  } else {
476
510
  return undefined;
477
511
  }
478
512
  }, o);
479
513
  }
480
514
 
481
-
482
- export const getObjectEntries = <T extends Record<string, any>> (obj: T): [keyof T, T[keyof T]][] => {
515
+ export const getObjectEntries = <T extends Record<string, any>>(
516
+ obj: T
517
+ ): [keyof T, T[keyof T]][] => {
483
518
  return Object.entries(obj) as [keyof T, T[keyof T]][];
484
- }
519
+ };
485
520
 
486
- function areEqual(a: any, b: any){
487
- if(a === b) return true;
488
- if(["number", "string", "boolean"].includes(typeof a)){
521
+ function areEqual(a: any, b: any) {
522
+ if (a === b) return true;
523
+ if (["number", "string", "boolean"].includes(typeof a)) {
489
524
  return a === b;
490
525
  }
491
526
  return JSON.stringify(a) === JSON.stringify(b);
492
527
  }
493
528
 
494
-
495
529
  export function isObject(obj: any | undefined): obj is Record<string, any> {
496
530
  return Boolean(obj && typeof obj === "object" && !Array.isArray(obj));
497
531
  }
498
- export function isDefined<T>(v: T | undefined | void): v is T { return v !== undefined && v !== null }
532
+ export function isDefined<T>(v: T | undefined | void): v is T {
533
+ return v !== undefined && v !== null;
534
+ }
499
535
 
500
- export function getKeys<T extends AnyObject>(o: T): Array<keyof T>{
501
- return Object.keys(o) as any
536
+ export function getKeys<T extends AnyObject>(o: T): Array<keyof T> {
537
+ return Object.keys(o) as any;
502
538
  }
503
539
 
504
- export type Explode<T> = keyof T extends infer K
505
- ? K extends unknown
506
- ? { [I in keyof T]: I extends K ? T[I] : never }
507
- : never
540
+ export type Explode<T> =
541
+ keyof T extends infer K ?
542
+ K extends unknown ?
543
+ { [I in keyof T]: I extends K ? T[I] : never }
544
+ : never
508
545
  : never;
509
546
  export type AtMostOne<T> = Explode<Partial<T>>;
510
- export type AtLeastOne<T, U = {[K in keyof T]: Pick<T, K> }> = Partial<T> & U[keyof U]
547
+ export type AtLeastOne<T, U = { [K in keyof T]: Pick<T, K> }> = Partial<T> & U[keyof U];
511
548
  export type ExactlyOne<T> = AtMostOne<T> & AtLeastOne<T>;
512
549
 
513
-
514
550
  type UnionKeys<T> = T extends T ? keyof T : never;
515
- type StrictUnionHelper<T, TAll> = T extends any ? T & Partial<Record<Exclude<UnionKeys<TAll>, keyof T>, never>> : never;
551
+ type StrictUnionHelper<T, TAll> =
552
+ T extends any ? T & Partial<Record<Exclude<UnionKeys<TAll>, keyof T>, never>> : never;
516
553
  export type StrictUnion<T> = StrictUnionHelper<T, T>;
517
554
 
518
555
  /**
519
556
  * @deprecated
520
557
  * use tryCatchV2 instead
521
558
  */
522
- export const tryCatch = async <T extends AnyObject>(func: () => T | Promise<T>):
523
- Promise<T & { hasError?: false; error?: undefined; duration: number; } | Partial<Record<keyof T, undefined>> & { hasError: true; error: unknown; duration: number; }> => {
559
+ export const tryCatch = async <T extends AnyObject>(
560
+ func: () => T | Promise<T>
561
+ ): Promise<
562
+ | (T & { hasError?: false; error?: undefined; duration: number })
563
+ | (Partial<Record<keyof T, undefined>> & { hasError: true; error: unknown; duration: number })
564
+ > => {
524
565
  const startTime = Date.now();
525
566
  try {
526
567
  const res = await func();
527
568
  return {
528
569
  ...res,
529
570
  duration: Date.now() - startTime,
530
- }
531
- } catch(error){
532
- return {
571
+ };
572
+ } catch (error) {
573
+ return {
533
574
  error,
534
575
  hasError: true,
535
- duration: Date.now() - startTime,
576
+ duration: Date.now() - startTime,
536
577
  } as any;
537
578
  }
538
- }
579
+ };
539
580
 
540
- type TryCatchResult<T> =
541
- | { data: T; hasError?: false; error?: undefined; duration: number; }
542
- | { data?: undefined; hasError: true; error: unknown; duration: number; }
581
+ type TryCatchResult<T> =
582
+ | { data: T; hasError?: false; error?: undefined; duration: number }
583
+ | { data?: undefined; hasError: true; error: unknown; duration: number };
543
584
 
544
- export const tryCatchV2 = <T,>(func: () => T | Promise<T>): T extends Promise<T>? Promise<TryCatchResult<Awaited<T>>> : TryCatchResult<T> => {
585
+ export const tryCatchV2 = <T>(
586
+ func: () => T | Promise<T>
587
+ ): T extends Promise<T> ? Promise<TryCatchResult<Awaited<T>>> : TryCatchResult<T> => {
545
588
  const startTime = Date.now();
546
589
  try {
547
590
  const dataOrResult = func();
548
- if(dataOrResult instanceof Promise){
591
+ if (dataOrResult instanceof Promise) {
549
592
  return new Promise(async (resolve, reject) => {
550
593
  const duration = Date.now() - startTime;
551
- const data = await dataOrResult
594
+ const data = await dataOrResult;
552
595
  resolve({
553
596
  data,
554
597
  duration,
@@ -559,48 +602,47 @@ export const tryCatchV2 = <T,>(func: () => T | Promise<T>): T extends Promise<T>
559
602
  data: dataOrResult,
560
603
  duration: Date.now() - startTime,
561
604
  } as any;
562
- } catch(error){
605
+ } catch (error) {
563
606
  console.error(error);
564
- return {
607
+ return {
565
608
  error,
566
609
  hasError: true,
567
- duration: Date.now() - startTime,
610
+ duration: Date.now() - startTime,
568
611
  } as any;
569
612
  }
570
- }
613
+ };
571
614
 
572
615
  export const getJoinHandlers = (tableName: string) => {
573
616
  const getJoinFunc = (isLeft: boolean, expectsOne: boolean): JoinMaker => {
574
- return (filter: Parameters<JoinMaker<AnyObject>>[0], select: Parameters<JoinMaker<AnyObject>>[1], options: Parameters<JoinMaker<AnyObject>>[2] = {}) => {
617
+ return (
618
+ filter: Parameters<JoinMaker<AnyObject>>[0],
619
+ select: Parameters<JoinMaker<AnyObject>>[1],
620
+ options: Parameters<JoinMaker<AnyObject>>[2] = {}
621
+ ) => {
575
622
  // return makeJoin(isLeft, filter, select, expectsOne? { ...options, limit: 1 } : options);
576
623
  return {
577
624
  [isLeft ? "$leftJoin" : "$innerJoin"]: options.path ?? tableName,
578
625
  filter,
579
- ... omitKeys(options, ["path", "select"]),
626
+ ...omitKeys(options, ["path", "select"]),
580
627
  select,
581
- }
582
- }
583
- }
628
+ };
629
+ };
630
+ };
584
631
 
585
632
  return {
586
633
  innerJoin: getJoinFunc(false, false),
587
634
  leftJoin: getJoinFunc(true, false),
588
635
  innerJoinOne: getJoinFunc(false, true),
589
636
  leftJoinOne: getJoinFunc(true, true),
590
- }
591
- }
637
+ };
638
+ };
592
639
 
593
640
  export type ParsedJoinPath = Required<JoinPath>;
594
641
  export const reverseJoinOn = (on: ParsedJoinPath["on"]) => {
595
- return on.map(constraint =>
596
- Object.fromEntries(
597
- Object.entries(constraint)
598
- .map(([left, right]) =>
599
- [right, left]
600
- )
601
- )
642
+ return on.map((constraint) =>
643
+ Object.fromEntries(Object.entries(constraint).map(([left, right]) => [right, left]))
602
644
  );
603
- }
645
+ };
604
646
 
605
647
  /**
606
648
  * result = [
@@ -609,16 +651,16 @@ export const reverseJoinOn = (on: ParsedJoinPath["on"]) => {
609
651
  * ]
610
652
  */
611
653
  export const reverseParsedPath = (parsedPath: ParsedJoinPath[], table: string) => {
612
- const newPPath: ParsedJoinPath[] = [
613
- { table, on: [{}] },
614
- ...(parsedPath ?? [])
615
- ]
616
- return newPPath.map((pp, i) => {
617
- const nextPath = newPPath[i+1];
618
- if(!nextPath) return undefined;
619
- return {
620
- table: pp.table,
621
- on: reverseJoinOn(nextPath.on)
622
- }
623
- }).filter(isDefined).reverse();
624
- }
654
+ const newPPath: ParsedJoinPath[] = [{ table, on: [{}] }, ...(parsedPath ?? [])];
655
+ return newPPath
656
+ .map((pp, i) => {
657
+ const nextPath = newPPath[i + 1];
658
+ if (!nextPath) return undefined;
659
+ return {
660
+ table: pp.table,
661
+ on: reverseJoinOn(nextPath.on),
662
+ };
663
+ })
664
+ .filter(isDefined)
665
+ .reverse();
666
+ };