@auxilium/datalynk-client 0.9.12 → 1.0.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.mjs CHANGED
@@ -74,6 +74,106 @@ class PromiseProgress extends Promise {
74
74
  return this.from(super.finally(res));
75
75
  }
76
76
  }
77
+ function formatDate(format = "YYYY-MM-DD H:mm", date = /* @__PURE__ */ new Date(), tz) {
78
+ const timezones = [
79
+ ["IDLW", -12],
80
+ ["SST", -11],
81
+ ["HST", -10],
82
+ ["AKST", -9],
83
+ ["PST", -8],
84
+ ["MST", -7],
85
+ ["CST", -6],
86
+ ["EST", -5],
87
+ ["AST", -4],
88
+ ["BRT", -3],
89
+ ["MAT", -2],
90
+ ["AZOT", -1],
91
+ ["UTC", 0],
92
+ ["CET", 1],
93
+ ["EET", 2],
94
+ ["MSK", 3],
95
+ ["AST", 4],
96
+ ["PKT", 5],
97
+ ["IST", 5.5],
98
+ ["BST", 6],
99
+ ["ICT", 7],
100
+ ["CST", 8],
101
+ ["JST", 9],
102
+ ["AEST", 10],
103
+ ["SBT", 11],
104
+ ["FJT", 12],
105
+ ["TOT", 13],
106
+ ["LINT", 14]
107
+ ];
108
+ function adjustTz(date2, gmt) {
109
+ const currentOffset = date2.getTimezoneOffset();
110
+ const adjustedOffset = gmt * 60;
111
+ return new Date(date2.getTime() + (adjustedOffset + currentOffset) * 6e4);
112
+ }
113
+ function day(num) {
114
+ return ["Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"][num] || "Unknown";
115
+ }
116
+ function doy(date2) {
117
+ const start = /* @__PURE__ */ new Date(`${date2.getFullYear()}-01-01 0:00:00`);
118
+ return Math.ceil((date2.getTime() - start.getTime()) / (1e3 * 60 * 60 * 24));
119
+ }
120
+ function month(num) {
121
+ return ["January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"][num] || "Unknown";
122
+ }
123
+ function suffix(num) {
124
+ if (num % 100 >= 11 && num % 100 <= 13) return `${num}th`;
125
+ switch (num % 10) {
126
+ case 1:
127
+ return `${num}st`;
128
+ case 2:
129
+ return `${num}nd`;
130
+ case 3:
131
+ return `${num}rd`;
132
+ default:
133
+ return `${num}th`;
134
+ }
135
+ }
136
+ function tzOffset(offset) {
137
+ const hours = ~~(offset / 60);
138
+ const minutes = offset % 60;
139
+ return (offset > 0 ? "-" : "") + `${hours}:${minutes.toString().padStart(2, "0")}`;
140
+ }
141
+ if (typeof date == "number" || typeof date == "string") date = new Date(date);
142
+ let t;
143
+ if (tz == null) tz = -(date.getTimezoneOffset() / 60);
144
+ t = timezones.find((t2) => isNaN(tz) ? t2[0] == tz : t2[1] == tz);
145
+ if (!t) throw new Error(`Unknown timezone: ${tz}`);
146
+ date = adjustTz(date, t[1]);
147
+ const tokens = {
148
+ "YYYY": date.getFullYear().toString(),
149
+ "YY": date.getFullYear().toString().slice(2),
150
+ "MMMM": month(date.getMonth()),
151
+ "MMM": month(date.getMonth()).slice(0, 3),
152
+ "MM": (date.getMonth() + 1).toString().padStart(2, "0"),
153
+ "M": (date.getMonth() + 1).toString(),
154
+ "DDD": doy(date).toString(),
155
+ "DD": date.getDate().toString().padStart(2, "0"),
156
+ "Do": suffix(date.getDate()),
157
+ "D": date.getDate().toString(),
158
+ "dddd": day(date.getDay()),
159
+ "ddd": day(date.getDay()).slice(0, 3),
160
+ "HH": date.getHours().toString().padStart(2, "0"),
161
+ "H": date.getHours().toString(),
162
+ "hh": (date.getHours() % 12 || 12).toString().padStart(2, "0"),
163
+ "h": (date.getHours() % 12 || 12).toString(),
164
+ "mm": date.getMinutes().toString().padStart(2, "0"),
165
+ "m": date.getMinutes().toString(),
166
+ "ss": date.getSeconds().toString().padStart(2, "0"),
167
+ "s": date.getSeconds().toString(),
168
+ "SSS": date.getMilliseconds().toString().padStart(3, "0"),
169
+ "A": date.getHours() >= 12 ? "PM" : "AM",
170
+ "a": date.getHours() >= 12 ? "pm" : "am",
171
+ "ZZ": tzOffset(t[1] * 60).replace(":", ""),
172
+ "Z": tzOffset(t[1] * 60),
173
+ "z": typeof tz == "string" ? tz : t[0]
174
+ };
175
+ return format.replace(/YYYY|YY|MMMM|MMM|MM|M|DDD|DD|Do|D|dddd|ddd|HH|H|hh|h|mm|m|ss|s|SSS|A|a|ZZ|Z|z/g, (token) => tokens[token]);
176
+ }
77
177
  class TypedEmitter {
78
178
  constructor() {
79
179
  __publicField2(this, "listeners", {});
@@ -293,6 +393,25 @@ function errorFromCode(code, message) {
293
393
  return new CustomError(message, code);
294
394
  }
295
395
  }
396
+ class HttpResponse extends Response {
397
+ constructor(resp, stream) {
398
+ const body = [204, 205, 304].includes(resp.status) ? null : stream;
399
+ super(body, {
400
+ headers: resp.headers,
401
+ status: resp.status,
402
+ statusText: resp.statusText
403
+ });
404
+ __publicField2(this, "data");
405
+ __publicField2(this, "ok");
406
+ __publicField2(this, "redirected");
407
+ __publicField2(this, "type");
408
+ __publicField2(this, "url");
409
+ this.ok = resp.ok;
410
+ this.redirected = resp.redirected;
411
+ this.type = resp.type;
412
+ this.url = resp.url;
413
+ }
414
+ }
296
415
  const _Http = class _Http2 {
297
416
  constructor(defaults = {}) {
298
417
  __publicField2(this, "interceptors", {});
@@ -321,8 +440,9 @@ const _Http = class _Http2 {
321
440
  request(opts = {}) {
322
441
  var _a;
323
442
  if (!this.url && !opts.url) throw new Error("URL needs to be set");
324
- let url = (((_a = opts.url) == null ? void 0 : _a.startsWith("http")) ? opts.url : (this.url || "") + (opts.url || "")).replace(/([^:]\/)\/+/g, "$1");
325
- if (opts.fragment) url.includes("#") ? url.replace(/#.*(\?|\n)/g, (match, arg1) => `#${opts.fragment}${arg1}`) : url += "#" + opts.fragment;
443
+ let url = ((_a = opts.url) == null ? void 0 : _a.startsWith("http")) ? opts.url : (this.url || "") + (opts.url || "");
444
+ url = url.replaceAll(/([^:]\/)\/+/g, "$1");
445
+ if (opts.fragment) url.includes("#") ? url.replace(/#.*(\?|\n)/g, (match, arg1) => `#${opts.fragment}${arg1}`) : `${url}#${opts.fragment}`;
326
446
  if (opts.query) {
327
447
  const q = Array.isArray(opts.query) ? opts.query : Object.keys(opts.query).map((k) => ({ key: k, value: opts.query[k] }));
328
448
  url += (url.includes("?") ? "&" : "?") + q.map((q2) => `${q2.key}=${q2.value}`).join("&");
@@ -364,13 +484,13 @@ const _Http = class _Http2 {
364
484
  push();
365
485
  }
366
486
  });
367
- resp.data = new Response(stream);
368
- if (opts.decode == null || opts.decode) {
487
+ resp = new HttpResponse(resp, stream);
488
+ if (opts.decode !== false) {
369
489
  const content = (_b = resp.headers.get("Content-Type")) == null ? void 0 : _b.toLowerCase();
370
- if (content == null ? void 0 : content.includes("form")) resp.data = await resp.data.formData();
371
- else if (content == null ? void 0 : content.includes("json")) resp.data = await resp.data.json();
372
- else if (content == null ? void 0 : content.includes("text")) resp.data = await resp.data.text();
373
- else if (content == null ? void 0 : content.includes("application")) resp.data = await resp.data.blob();
490
+ if (content == null ? void 0 : content.includes("form")) resp.data = await resp.formData();
491
+ else if (content == null ? void 0 : content.includes("json")) resp.data = await resp.json();
492
+ else if (content == null ? void 0 : content.includes("text")) resp.data = await resp.text();
493
+ else if (content == null ? void 0 : content.includes("application")) resp.data = await resp.blob();
374
494
  }
375
495
  if (resp.ok) res(resp);
376
496
  else rej(resp);
@@ -390,31 +510,13 @@ function jwtDecode(token) {
390
510
  }).join("")));
391
511
  }
392
512
  const CliEffects = {
393
- CLEAR: "\x1B[0m",
394
- BRIGHT: "\x1B[1m",
395
- DIM: "\x1B[2m",
396
- UNDERSCORE: "\x1B[4m",
397
- BLINK: "\x1B[5m",
398
- REVERSE: "\x1B[7m",
399
- HIDDEN: "\x1B[8m"
513
+ CLEAR: "\x1B[0m"
400
514
  };
401
515
  const CliForeground = {
402
- BLACK: "\x1B[30m",
403
516
  RED: "\x1B[31m",
404
- GREEN: "\x1B[32m",
405
517
  YELLOW: "\x1B[33m",
406
518
  BLUE: "\x1B[34m",
407
- MAGENTA: "\x1B[35m",
408
- CYAN: "\x1B[36m",
409
- LIGHT_GREY: "\x1B[37m",
410
- GREY: "\x1B[90m",
411
- LIGHT_RED: "\x1B[91m",
412
- LIGHT_GREEN: "\x1B[92m",
413
- LIGHT_YELLOW: "\x1B[93m",
414
- LIGHT_BLUE: "\x1B[94m",
415
- LIGHT_MAGENTA: "\x1B[95m",
416
- LIGHT_CYAN: "\x1B[96m",
417
- WHITE: "\x1B[97m"
519
+ LIGHT_GREY: "\x1B[37m"
418
520
  };
419
521
  const _Logger = class _Logger2 extends TypedEmitter {
420
522
  constructor(namespace) {
@@ -458,112 +560,6 @@ const _Logger = class _Logger2 extends TypedEmitter {
458
560
  }
459
561
  };
460
562
  __publicField2(_Logger, "LOG_LEVEL", 4);
461
- function formatDate(format = "YYYY-MM-DD H:mm", date = /* @__PURE__ */ new Date(), tz) {
462
- const timezones = [
463
- ["IDLW", -12],
464
- ["SST", -11],
465
- ["HST", -10],
466
- ["AKST", -9],
467
- ["PST", -8],
468
- ["MST", -7],
469
- ["CST", -6],
470
- ["EST", -5],
471
- ["AST", -4],
472
- ["BRT", -3],
473
- ["MAT", -2],
474
- ["AZOT", -1],
475
- ["UTC", 0],
476
- ["CET", 1],
477
- ["EET", 2],
478
- ["MSK", 3],
479
- ["AST", 4],
480
- ["PKT", 5],
481
- ["IST", 5.5],
482
- ["BST", 6],
483
- ["ICT", 7],
484
- ["CST", 8],
485
- ["JST", 9],
486
- ["AEST", 10],
487
- ["SBT", 11],
488
- ["FJT", 12],
489
- ["TOT", 13],
490
- ["LINT", 14]
491
- ];
492
- function adjustTz(date2, gmt) {
493
- const currentOffset = date2.getTimezoneOffset();
494
- const adjustedOffset = gmt * 60;
495
- return new Date(date2.getTime() + (adjustedOffset + currentOffset) * 6e4);
496
- }
497
- function day(num) {
498
- return ["Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"][num] || "Unknown";
499
- }
500
- function doy(date2) {
501
- const start = /* @__PURE__ */ new Date(`${date2.getFullYear()}-01-01 0:00:00`);
502
- return Math.ceil((date2.getTime() - start.getTime()) / (1e3 * 60 * 60 * 24));
503
- }
504
- function month(num) {
505
- return ["January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"][num] || "Unknown";
506
- }
507
- function suffix(num) {
508
- if (num % 100 >= 11 && num % 100 <= 13) return `${num}th`;
509
- switch (num % 10) {
510
- case 1:
511
- return `${num}st`;
512
- case 2:
513
- return `${num}nd`;
514
- case 3:
515
- return `${num}rd`;
516
- default:
517
- return `${num}th`;
518
- }
519
- }
520
- function tzOffset(offset) {
521
- const hours = ~~(offset / 60);
522
- const minutes = offset % 60;
523
- return (offset > 0 ? "-" : "") + `${hours}:${minutes.toString().padStart(2, "0")}`;
524
- }
525
- if (typeof date == "number" || typeof date == "string") date = new Date(date);
526
- let t;
527
- if (tz == null) tz = -(date.getTimezoneOffset() / 60);
528
- t = timezones.find((t2) => isNaN(tz) ? t2[0] == tz : t2[1] == tz);
529
- if (!t) throw new Error(`Unknown timezone: ${tz}`);
530
- date = adjustTz(date, t[1]);
531
- const tokens = {
532
- "YYYY": date.getFullYear().toString(),
533
- "YY": date.getFullYear().toString().slice(2),
534
- "MMMM": month(date.getMonth()),
535
- "MMM": month(date.getMonth()).slice(0, 3),
536
- "MM": (date.getMonth() + 1).toString().padStart(2, "0"),
537
- "M": (date.getMonth() + 1).toString(),
538
- "DDD": doy(date).toString(),
539
- "DD": date.getDate().toString().padStart(2, "0"),
540
- "Do": suffix(date.getDate()),
541
- "D": date.getDate().toString(),
542
- "dddd": day(date.getDay()),
543
- "ddd": day(date.getDay()).slice(0, 3),
544
- "HH": date.getHours().toString().padStart(2, "0"),
545
- "H": date.getHours().toString(),
546
- "hh": (date.getHours() % 12 || 12).toString().padStart(2, "0"),
547
- "h": (date.getHours() % 12 || 12).toString(),
548
- "mm": date.getMinutes().toString().padStart(2, "0"),
549
- "m": date.getMinutes().toString(),
550
- "ss": date.getSeconds().toString().padStart(2, "0"),
551
- "s": date.getSeconds().toString(),
552
- "SSS": date.getMilliseconds().toString().padStart(3, "0"),
553
- "A": date.getHours() >= 12 ? "PM" : "AM",
554
- "a": date.getHours() >= 12 ? "pm" : "am",
555
- "ZZ": tzOffset(t[1] * 60).replace(":", ""),
556
- "Z": tzOffset(t[1] * 60),
557
- "z": typeof tz == "string" ? tz : t[0]
558
- };
559
- return format.replace(/YYYY|YY|MMMM|MMM|MM|M|DDD|DD|Do|D|dddd|ddd|HH|H|hh|h|mm|m|ss|s|SSS|A|a|ZZ|Z|z/g, (token) => tokens[token]);
560
- }
561
- function sleep(ms) {
562
- return new Promise((res) => setTimeout(res, ms));
563
- }
564
- async function sleepWhile(fn, checkInterval = 100) {
565
- while (await fn()) await sleep(checkInterval);
566
- }
567
563
  var extendStatics = function(d, b) {
568
564
  extendStatics = Object.setPrototypeOf || { __proto__: [] } instanceof Array && function(d2, b2) {
569
565
  d2.__proto__ = b2;
@@ -783,11 +779,7 @@ function execFinalizer(finalizer) {
783
779
  }
784
780
  }
785
781
  var config = {
786
- onUnhandledError: null,
787
- onStoppedNotification: null,
788
- Promise: void 0,
789
- useDeprecatedSynchronousErrorHandling: false,
790
- useDeprecatedNextContext: false
782
+ Promise: void 0
791
783
  };
792
784
  var timeoutProvider = {
793
785
  setTimeout: function(handler, timeout) {
@@ -880,10 +872,6 @@ var Subscriber = function(_super) {
880
872
  };
881
873
  return Subscriber2;
882
874
  }(Subscription);
883
- var _bind = Function.prototype.bind;
884
- function bind(fn, thisArg) {
885
- return _bind.call(fn, thisArg);
886
- }
887
875
  var ConsumerObserver = function() {
888
876
  function ConsumerObserver2(partialObserver) {
889
877
  this.partialObserver = partialObserver;
@@ -934,18 +922,7 @@ var SafeSubscriber = function(_super) {
934
922
  complete: complete !== null && complete !== void 0 ? complete : void 0
935
923
  };
936
924
  } else {
937
- var context_1;
938
- if (_this && config.useDeprecatedNextContext) {
939
- context_1 = Object.create(observerOrNext);
940
- context_1.unsubscribe = function() {
941
- return _this.unsubscribe();
942
- };
943
- partialObserver = {
944
- next: observerOrNext.next && bind(observerOrNext.next, context_1),
945
- error: observerOrNext.error && bind(observerOrNext.error, context_1),
946
- complete: observerOrNext.complete && bind(observerOrNext.complete, context_1)
947
- };
948
- } else {
925
+ {
949
926
  partialObserver = observerOrNext;
950
927
  }
951
928
  }
@@ -1675,7 +1652,7 @@ class Auth {
1675
1652
  * @return {Promise<boolean>} True if system administrator
1676
1653
  */
1677
1654
  async isSysAdmin() {
1678
- return !!(await this.api.slice("sysadmin").select().where("auth_ref", "==", "$viewer").exec().keys()).length;
1655
+ return !!(await this.api.slice("sysadmin").select().where("auth_ref", "==", "$viewer").rows().exec()).length;
1679
1656
  }
1680
1657
  /**
1681
1658
  * Check if user is a table administrator
@@ -1683,7 +1660,7 @@ class Auth {
1683
1660
  * @return {Promise<boolean>} True if table administrator
1684
1661
  */
1685
1662
  async isTableAdmin() {
1686
- return !!(await this.api.slice("tableadmins").select().where("auth_ref", "==", "$viewer").exec().keys()).length;
1663
+ return !!(await this.api.slice("tableadmins").select().where("auth_ref", "==", "$viewer").rows().exec()).length;
1687
1664
  }
1688
1665
  /**
1689
1666
  * Check if user is a user administrator
@@ -1691,7 +1668,7 @@ class Auth {
1691
1668
  * @return {Promise<boolean>} True if user administrator
1692
1669
  */
1693
1670
  async isUserAdmin() {
1694
- return !!(await this.api.slice("useradmins").select().where("auth_ref", "==", "$viewer").exec().keys()).length;
1671
+ return !!(await this.api.slice("useradmins").select().where("auth_ref", "==", "$viewer").rows().exec()).length;
1695
1672
  }
1696
1673
  /**
1697
1674
  * Perform login and save the session token
@@ -1793,7 +1770,7 @@ class Files {
1793
1770
  this.url = `${this.api.url}file`;
1794
1771
  }
1795
1772
  associate(fileIds, slice, row, field, execute = true) {
1796
- const req = { [`${execute ? "!" : "$"}/tools/file/update`]: { row, field, slice, ids: fileIds } };
1773
+ const req = { [`${execute ? "!" : "$"}/tools/file/update`]: { slice, row, field, ids: fileIds } };
1797
1774
  if (execute) return this.api.request(req);
1798
1775
  return req;
1799
1776
  }
@@ -1832,7 +1809,7 @@ class Files {
1832
1809
  })).then(async (files2) => {
1833
1810
  if (associate) {
1834
1811
  let id = typeof associate.row == "number" ? associate.row : associate.row[associate.pk || "id"];
1835
- if (!id) id = await this.api.slice(associate.slice).insert(associate.row).exec().key();
1812
+ if (!id) id = await this.api.slice(associate.slice).insert(associate.row).id();
1836
1813
  await this.associate(files2.map((f2) => f2.id), associate == null ? void 0 : associate.slice, associate == null ? void 0 : associate.row, associate == null ? void 0 : associate.field);
1837
1814
  }
1838
1815
  return files2;
@@ -1992,112 +1969,6 @@ const Serializer = {
1992
1969
  }
1993
1970
  }
1994
1971
  };
1995
- class SlicePromise {
1996
- /**
1997
- * An object to provide helpers for Datalynk results
1998
- *
1999
- * @param slice
2000
- * @param {SliceResponse<T>} promise Datalynk promise to handle
2001
- */
2002
- constructor(slice, promise) {
2003
- this.slice = slice;
2004
- this.promise = promise;
2005
- }
2006
- /**
2007
- * Catch promise errors
2008
- */
2009
- catch(callback) {
2010
- return this.promise.catch(callback);
2011
- }
2012
- /**
2013
- * Count rows or fetch count alias result
2014
- */
2015
- async count() {
2016
- var _a, _b;
2017
- const rows = await this.rows();
2018
- if (typeof ((_a = rows == null ? void 0 : rows[0]) == null ? void 0 : _a["count"]) == "number") return (_b = rows == null ? void 0 : rows[0]) == null ? void 0 : _b["count"];
2019
- return rows.length;
2020
- }
2021
- /**
2022
- * Log the raw result to the console for inspection
2023
- */
2024
- debug() {
2025
- this.promise.then((resp) => console.log(resp));
2026
- return this;
2027
- }
2028
- /**
2029
- * Fields that failed
2030
- */
2031
- async failed() {
2032
- let resp = await this.promise;
2033
- return resp.failed;
2034
- }
2035
- /**
2036
- * Catch promise errors
2037
- */
2038
- finally(callback) {
2039
- return this.promise.finally(callback);
2040
- }
2041
- /**
2042
- * Fields that were ignored (Perms or readonly)
2043
- */
2044
- async ignored() {
2045
- let resp = await this.promise;
2046
- return resp["ignored-fields"];
2047
- }
2048
- /**
2049
- * ID of first affected row
2050
- */
2051
- async key() {
2052
- return (await this.keys())[0];
2053
- }
2054
- /**
2055
- * IDs of all affected rows
2056
- */
2057
- async keys() {
2058
- let resp = await this.promise;
2059
- return resp.keys;
2060
- }
2061
- /**
2062
- * Fields that were affected successfully
2063
- */
2064
- async granted() {
2065
- let resp = await this.promise;
2066
- return resp.granted;
2067
- }
2068
- /**
2069
- * First row of data
2070
- */
2071
- async row() {
2072
- return (await this.rows())[0];
2073
- }
2074
- /**
2075
- * All rows of data
2076
- */
2077
- async rows() {
2078
- let resp = await this.promise;
2079
- return resp.rows;
2080
- }
2081
- /**
2082
- * Handle as normal request
2083
- */
2084
- then(success, error) {
2085
- return this.promise.then(success, error);
2086
- }
2087
- /**
2088
- * Get the raw promise
2089
- */
2090
- toPromise() {
2091
- return this.promise;
2092
- }
2093
- /**
2094
- * Get the transaction ID
2095
- */
2096
- async transaction() {
2097
- let resp = await this.promise;
2098
- return resp.tx;
2099
- }
2100
- }
2101
1972
  const _Slice = class _Slice {
2102
1973
  /**
2103
1974
  * An object to aid in constructing requests
@@ -2107,11 +1978,25 @@ const _Slice = class _Slice {
2107
1978
  */
2108
1979
  constructor(slice, api) {
2109
1980
  __publicField(this, "operation");
1981
+ __publicField(this, "popField");
2110
1982
  __publicField(this, "request", {});
1983
+ /** Log response automatically */
1984
+ __publicField(this, "debugging");
2111
1985
  /** Unsubscribe from changes, undefined if not subscribed */
2112
1986
  __publicField(this, "unsubscribe");
2113
1987
  /** Cached slice data as an observable */
2114
1988
  __publicField(this, "cache$", new BehaviorSubject([]));
1989
+ /**
1990
+ * Whitelist and alias fields. Alias of `fields()`
1991
+ * @example
1992
+ * ```ts
1993
+ * const id: {id: number, field2: any}[] = await new Slice<T>(12345)
1994
+ * .select().alias({id: 'id', field1: 'field2'}).exec().keys();
1995
+ * ```
1996
+ * @param {object} aliasKeyVals List of properties to whitelist and what to rename them to
1997
+ * @return {Slice<T>}
1998
+ */
1999
+ __publicField(this, "alias", this.fields);
2115
2000
  this.slice = slice;
2116
2001
  this.api = api;
2117
2002
  }
@@ -2125,19 +2010,13 @@ const _Slice = class _Slice {
2125
2010
  }
2126
2011
  /** Get raw API request */
2127
2012
  get raw() {
2128
- return { [this.operation]: { slice: this.slice, ...this.request } };
2129
- }
2130
- /**
2131
- * Whitelist and alias fields. Alias for the fields functions
2132
- * @example
2133
- * ```ts
2134
- * const id: {id: number, field2: any}[] = await new Slice<T>(12345)
2135
- * .select().alias({id: 'id', field1: 'field2'}).exec().keys();
2136
- * ```
2137
- * @param {object} aliasKeyVals List of properties to whitelist and what to rename them to
2138
- */
2139
- alias(aliasKeyVals) {
2140
- return this.fields(aliasKeyVals);
2013
+ return clean({
2014
+ [this.operation]: {
2015
+ ...this.request,
2016
+ slice: this.slice
2017
+ },
2018
+ "$pop": this.popField ? this.popField : void 0
2019
+ });
2141
2020
  }
2142
2021
  /**
2143
2022
  * Add an 'AND' condition inside the where argument
@@ -2149,6 +2028,7 @@ const _Slice = class _Slice {
2149
2028
  * .where({field2: 2, field3: 3})
2150
2029
  * .exec().rows();
2151
2030
  * ```
2031
+ * @return {Slice<T>}
2152
2032
  */
2153
2033
  and() {
2154
2034
  var _a;
@@ -2166,17 +2046,20 @@ const _Slice = class _Slice {
2166
2046
  * .exec().count();
2167
2047
  * ```
2168
2048
  * @param {object | string} arg Count argument
2049
+ * @return {Slice<T>}
2169
2050
  */
2170
2051
  count(arg = "id") {
2171
2052
  this.operation = "$/slice/report";
2172
2053
  this.request.fields = { count: ["$count", typeof arg == "object" ? arg : ["$field", arg]] };
2173
- return this;
2054
+ return this.pop("rows:0:count");
2174
2055
  }
2175
2056
  /**
2176
2057
  * Output the formed request to the console for inspection
2058
+ * @param {boolean} enabled Enable/Disable console logging
2059
+ * @return {Slice<T>}
2177
2060
  */
2178
- debug() {
2179
- console.debug(this.request);
2061
+ debug(enabled = true) {
2062
+ this.debugging = enabled;
2180
2063
  return this;
2181
2064
  }
2182
2065
  /**
@@ -2186,6 +2069,7 @@ const _Slice = class _Slice {
2186
2069
  * await new Slice(12345).delete(id).exec();
2187
2070
  * ```
2188
2071
  * @param {number | number[]} id ID(s) to delete
2072
+ * @return {Slice<T>}
2189
2073
  */
2190
2074
  delete(id) {
2191
2075
  this.operation = "$/slice/delete";
@@ -2204,6 +2088,7 @@ const _Slice = class _Slice {
2204
2088
  * .exec().rows();
2205
2089
  * ```
2206
2090
  * @param formula Excel formula to use as where clause
2091
+ * @return {Slice<T>}
2207
2092
  */
2208
2093
  excel(formula) {
2209
2094
  this.where(["$excel", formula]);
@@ -2212,17 +2097,26 @@ const _Slice = class _Slice {
2212
2097
  /**
2213
2098
  * Compile the request and send it
2214
2099
  * @param {ApiRequestOptions} options API Request options
2215
- * @return {SlicePromise<T>}
2100
+ * @return {Promise<T = any>} API response
2216
2101
  */
2217
2102
  exec(options) {
2218
2103
  if (!this.operation) throw new Error("No operation chosen");
2219
- this.request.slice = this.slice;
2220
- return new SlicePromise(this, this.api.request({ [this.operation]: this.request }, options));
2104
+ return this.api.request(this.raw, options).then((resp) => {
2105
+ if (this.debugging) console.log(resp);
2106
+ return resp;
2107
+ });
2221
2108
  }
2222
2109
  fields(keys) {
2223
2110
  this.request.fields = Array.isArray(keys) ? keys.reduce((acc, key) => ({ ...acc, [key]: key }), {}) : keys;
2224
2111
  return this;
2225
2112
  }
2113
+ /**
2114
+ * Unwrap response returning the first ID
2115
+ * @return {Slice<T>}
2116
+ */
2117
+ id() {
2118
+ return this.pop("rows:0:id");
2119
+ }
2226
2120
  /**
2227
2121
  * Set the request type to insert
2228
2122
  * @example
@@ -2233,6 +2127,7 @@ const _Slice = class _Slice {
2233
2127
  * ]).exec().keys();
2234
2128
  * ```
2235
2129
  * @param {T | T[]} rows Rows to be inserted into the slice
2130
+ * @return {Slice<T>}
2236
2131
  */
2237
2132
  insert(rows) {
2238
2133
  this.operation = "$/slice/xinsert";
@@ -2249,9 +2144,11 @@ const _Slice = class _Slice {
2249
2144
  * .exec().rows();
2250
2145
  * ```
2251
2146
  * @param {number} num Number of rows to return
2147
+ * @return {Slice<T>}
2252
2148
  */
2253
2149
  limit(num) {
2254
2150
  this.request.limit = num;
2151
+ return this;
2255
2152
  }
2256
2153
  /**
2257
2154
  * Add an 'OR' condition inside the where argument
@@ -2265,6 +2162,7 @@ const _Slice = class _Slice {
2265
2162
  * .where(['$gt', ['$field', field4], 4)
2266
2163
  * .exec().rows();
2267
2164
  * ```
2165
+ * @return {Slice<T>}
2268
2166
  */
2269
2167
  or() {
2270
2168
  var _a;
@@ -2285,12 +2183,36 @@ const _Slice = class _Slice {
2285
2183
  * ```
2286
2184
  * @param {string} field property name
2287
2185
  * @param {boolean} ascending Sort in ascending or descending order
2186
+ * @return {Slice<T>}
2288
2187
  */
2289
2188
  order(field, ascending = true) {
2290
2189
  if (!this.request.order) this.request.order = [];
2291
2190
  this.request.order.push([ascending ? "$asc" : "$desc", ["$field", field]]);
2292
2191
  return this;
2293
2192
  }
2193
+ /**
2194
+ * Unwrap response, returning the field
2195
+ * @param {string} field Colon seperated path: `rows:0`
2196
+ * @return {Slice<T>}
2197
+ */
2198
+ pop(field) {
2199
+ this.popField = field;
2200
+ return this;
2201
+ }
2202
+ /**
2203
+ * Unwrap response returning the first row
2204
+ * @return {Slice<T>}
2205
+ */
2206
+ row() {
2207
+ return this.pop("rows:0");
2208
+ }
2209
+ /**
2210
+ * Unwrap response returning the rows
2211
+ * @return {Slice<T>}
2212
+ */
2213
+ rows() {
2214
+ return this.pop("rows");
2215
+ }
2294
2216
  /**
2295
2217
  * Set the request type to select
2296
2218
  * @example
@@ -2299,6 +2221,7 @@ const _Slice = class _Slice {
2299
2221
  * const row: T = new Slice<T>(12345).select(id).exec().row();
2300
2222
  * ```
2301
2223
  * @param {number | number[]} id ID(s) to select, leaving blank will return all rows
2224
+ * @return {Slice<T>}
2302
2225
  */
2303
2226
  select(id) {
2304
2227
  this.operation = "$/slice/report";
@@ -2320,10 +2243,10 @@ const _Slice = class _Slice {
2320
2243
  */
2321
2244
  sync(on = true) {
2322
2245
  if (on) {
2323
- new _Slice(this.slice, this.api).select().exec().rows().then((rows) => this.cache = rows);
2246
+ new _Slice(this.slice, this.api).select().rows().exec().then((rows) => this.cache = rows);
2324
2247
  if (!this.unsubscribe) this.unsubscribe = this.api.socket.sliceEvents(this.slice, (event) => {
2325
2248
  const ids = [...event.data.new, ...event.data.changed];
2326
- new _Slice(this.slice, this.api).select(ids).exec().rows().then((rows) => this.cache = [...this.cache.filter((c) => c.id != null && !ids.includes(c.id)), ...rows]);
2249
+ new _Slice(this.slice, this.api).select(ids).rows().exec().then((rows) => this.cache = [...this.cache.filter((c) => c.id != null && !ids.includes(c.id)), ...rows]);
2327
2250
  this.cache = this.cache.filter((v) => v.id && !event.data.lost.includes(v.id));
2328
2251
  });
2329
2252
  return this.cache$;
@@ -2342,6 +2265,7 @@ const _Slice = class _Slice {
2342
2265
  * ]).exec().keys();
2343
2266
  * ```
2344
2267
  * @param {T | T[]} rows Rows to be updated, each row must have an ID
2268
+ * @return {Slice<T>}
2345
2269
  */
2346
2270
  update(rows) {
2347
2271
  this.operation = "$/slice/xupdate";
@@ -2364,6 +2288,7 @@ const _Slice = class _Slice {
2364
2288
  * @param {string | object} field property to compare or a map of equality comparisons
2365
2289
  * @param {string} operator Operation to compare with. Accepts JS operators (>=, ==, !=, ...) as well as datalynk styax ($gte, $eq, $is, $not, ...)
2366
2290
  * @param {any} value value to compare against
2291
+ * @return {Slice<T>}
2367
2292
  */
2368
2293
  where(field, operator, value) {
2369
2294
  if (this.request.where && this.request.where[0] != "$or") this.and();
@@ -2402,6 +2327,7 @@ let Slice = _Slice;
2402
2327
  class Socket {
2403
2328
  constructor(api, options = {}) {
2404
2329
  __publicField(this, "listeners", []);
2330
+ // [ Callback, Re-subscribe ]
2405
2331
  __publicField(this, "retry");
2406
2332
  __publicField(this, "socket");
2407
2333
  __publicField(this, "open", false);
@@ -2422,9 +2348,9 @@ class Socket {
2422
2348
  * @param {SocketListener} fn Callback function
2423
2349
  * @return {Unsubscribe} Function to unsubscribe callback
2424
2350
  */
2425
- addListener(fn) {
2426
- this.listeners.push(fn);
2427
- return () => this.listeners = this.listeners.filter((l) => l != fn);
2351
+ addListener(fn, reconnect) {
2352
+ this.listeners.push([fn, reconnect]);
2353
+ return () => this.listeners = this.listeners.filter((l) => l[0] != fn);
2428
2354
  }
2429
2355
  /**
2430
2356
  * Close socket connection
@@ -2462,11 +2388,12 @@ class Socket {
2462
2388
  if (payload.connected) {
2463
2389
  this.open = true;
2464
2390
  console.debug("Datalynk socket: connected");
2391
+ this.listeners.forEach((l) => l[1]());
2465
2392
  } else {
2466
2393
  throw new Error(`Datalynk socket failed: ${payload.error}`);
2467
2394
  }
2468
2395
  } else {
2469
- this.listeners.forEach((l) => l(payload));
2396
+ this.listeners.forEach((l) => l[0](payload));
2470
2397
  }
2471
2398
  };
2472
2399
  }
@@ -2489,15 +2416,12 @@ class Socket {
2489
2416
  * @return {Unsubscribe} Run returned function to unsubscribe callback
2490
2417
  */
2491
2418
  sliceEvents(slice, callback) {
2492
- let cancelled = false;
2493
- sleepWhile(() => !this.open).then(() => {
2494
- if (!cancelled) this.send({ onSliceEvents: slice });
2495
- });
2419
+ const listen = () => this.send({ onSliceEvents: slice });
2420
+ if (this.open) listen();
2496
2421
  const unsubscribe = this.addListener((event) => {
2497
2422
  if (event.type == "sliceEvents" && event.data.slice == slice) callback(event);
2498
- });
2423
+ }, () => listen());
2499
2424
  return () => {
2500
- cancelled = true;
2501
2425
  this.send({ offSliceEvents: slice });
2502
2426
  unsubscribe();
2503
2427
  };
@@ -2552,9 +2476,8 @@ class Api {
2552
2476
  __publicField(this, "bundleOngoing", false);
2553
2477
  /** LocalStorage key for persisting logins */
2554
2478
  __publicField(this, "localStorageKey", "datalynk-token");
2555
- /** Pending requests */
2479
+ /** Pending requests cache */
2556
2480
  __publicField(this, "pending", {});
2557
- // Cache for ongoing requests
2558
2481
  /** Authentication helpers */
2559
2482
  __publicField(this, "auth", new Auth(this));
2560
2483
  /** File helpers */
@@ -2565,9 +2488,8 @@ class Api {
2565
2488
  __publicField(this, "socket");
2566
2489
  /** Superuser helpers */
2567
2490
  __publicField(this, "superuser", new Superuser(this));
2568
- /** API endpoint */
2491
+ /** API URL endpoint */
2569
2492
  __publicField(this, "url");
2570
- // API URL endpoint for requests
2571
2493
  /** API Session token */
2572
2494
  __publicField(this, "token$", new BehaviorSubject(null));
2573
2495
  this.options = options;
@@ -2647,10 +2569,21 @@ class Api {
2647
2569
  /**
2648
2570
  * Chain multiple requests to execute together
2649
2571
  * @param {Slice<any>} requests List of requests to chain
2650
- * @return {Promise<SlicePromise[]>} API Response
2572
+ * @return {Promise<any>} API Response
2651
2573
  */
2652
2574
  chain(...requests) {
2653
- return this.request({ "$/tools/action_chain": requests.flatMap((r) => r instanceof Slice ? r.raw : r) });
2575
+ const arr = requests.length == 1 && Array.isArray(requests[0]) ? requests[0] : requests;
2576
+ return this.request({ "$/tools/action_chain": arr.map((r) => {
2577
+ if (!(r instanceof Slice)) return r;
2578
+ const req = r.raw;
2579
+ Object.keys(req).forEach((key) => {
2580
+ if (key.startsWith("$/")) {
2581
+ req[key.replace("$", "!")] = req[key];
2582
+ delete req[key];
2583
+ }
2584
+ });
2585
+ return req;
2586
+ }) });
2654
2587
  }
2655
2588
  /**
2656
2589
  * Organize multiple requests into a single mapped request
@@ -2659,11 +2592,37 @@ class Api {
2659
2592
  */
2660
2593
  chainMap(request) {
2661
2594
  return this.request({ "$/tools/do": [
2662
- ...Object.entries(request).flatMap(([key, r]) => [key, r instanceof Slice ? r.raw : r]),
2595
+ ...Object.entries(request).flatMap(([key, r]) => {
2596
+ if (!(r instanceof Slice)) return [key, r];
2597
+ const req = r.raw;
2598
+ Object.keys(req).forEach((key2) => {
2599
+ if (key2.startsWith("$/")) {
2600
+ req[key2.replace("$", "!")] = req[key2];
2601
+ delete req[key2];
2602
+ }
2603
+ });
2604
+ return [key, req];
2605
+ }),
2663
2606
  "returnAllBoilerplate",
2664
2607
  { "$_": "*" }
2665
2608
  ] }, {});
2666
2609
  }
2610
+ /**
2611
+ * Exact same as `request` method, but logs the response in the console automatically
2612
+ *
2613
+ * @param {object | string} data Datalynk request as object or string
2614
+ * @param {ApiRequestOptions} options
2615
+ * @returns {Promise<any>} Datalynk response
2616
+ */
2617
+ debug(data, options = {}) {
2618
+ return this.request(data, options).then((data2) => {
2619
+ console.log(data2);
2620
+ return data2;
2621
+ }).catch((err) => {
2622
+ console.error(err);
2623
+ return err;
2624
+ });
2625
+ }
2667
2626
  /**
2668
2627
  * Send a request to Datalynk
2669
2628
  *
@@ -2678,7 +2637,7 @@ class Api {
2678
2637
  */
2679
2638
  request(data, options = {}) {
2680
2639
  data = typeof data == "string" ? { [data]: {} } : data;
2681
- if (options.force) {
2640
+ if (options.noOptimize) {
2682
2641
  return new Promise((res, rej) => {
2683
2642
  this._request(data, options).then((resp) => {
2684
2643
  (resp == null ? void 0 : resp.error) ? rej(resp) : res(resp);
@@ -2716,27 +2675,11 @@ class Api {
2716
2675
  * ```
2717
2676
  *
2718
2677
  * @param {number} slice Slice number the object will target
2719
- * @returns {Slice<T extends SliceMeta>} Object for making requests & caching rows
2678
+ * @returns {Slice<T = any>} Object for making requests & caching rows
2720
2679
  */
2721
2680
  slice(slice) {
2722
2681
  return new Slice(slice, this);
2723
2682
  }
2724
- /**
2725
- * Exact same as `request` method, but logs the response in the console automatically
2726
- *
2727
- * @param {object | string} data Datalynk request as object or string
2728
- * @param {ApiRequestOptions} options
2729
- * @returns {Promise<any>} Datalynk response
2730
- */
2731
- test(data, options = {}) {
2732
- return this.request(data, options).then((data2) => {
2733
- console.log(data2);
2734
- return data2;
2735
- }).catch((err) => {
2736
- console.error(err);
2737
- return err;
2738
- });
2739
- }
2740
2683
  }
2741
2684
  export {
2742
2685
  Api,
@@ -2746,7 +2689,6 @@ export {
2746
2689
  Pdf,
2747
2690
  Serializer,
2748
2691
  Slice,
2749
- SlicePromise,
2750
2692
  Socket,
2751
2693
  Superuser
2752
2694
  };