@auxilium/datalynk-client 1.0.20 → 1.1.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.
package/dist/index.cjs DELETED
@@ -1,2939 +0,0 @@
1
- (function(global2, factory) {
2
- typeof exports === "object" && typeof module !== "undefined" ? factory(exports) : typeof define === "function" && define.amd ? define(["exports"], factory) : (global2 = typeof globalThis !== "undefined" ? globalThis : global2 || self, factory(global2.utils = {}));
3
- })(this, function(exports2) {
4
- "use strict";var __defProp = Object.defineProperty;
5
- var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
6
- var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
7
-
8
- var __defProp2 = Object.defineProperty;
9
- var __defNormalProp2 = (obj, key, value) => key in obj ? __defProp2(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
10
- var __publicField2 = (obj, key, value) => __defNormalProp2(obj, typeof key !== "symbol" ? key + "" : key, value);
11
- function clean(obj, undefinedOnly = false) {
12
- if (obj == null) throw new Error("Cannot clean a NULL value");
13
- if (Array.isArray(obj)) {
14
- obj = obj.filter((o) => undefinedOnly ? o !== void 0 : o != null);
15
- } else {
16
- Object.entries(obj).forEach(([key, value]) => {
17
- if (undefinedOnly && value === void 0 || !undefinedOnly && value == null) delete obj[key];
18
- });
19
- }
20
- return obj;
21
- }
22
- function JSONAttemptParse(json) {
23
- try {
24
- return JSON.parse(json);
25
- } catch {
26
- return json;
27
- }
28
- }
29
- function JSONSanitize(obj, space) {
30
- const cache = [];
31
- return JSON.stringify(obj, (key, value) => {
32
- if (typeof value === "object" && value !== null) {
33
- if (cache.includes(value)) return "[Circular]";
34
- cache.push(value);
35
- }
36
- return value;
37
- }, space);
38
- }
39
- function makeArray(value) {
40
- return Array.isArray(value) ? value : [value];
41
- }
42
- function contrast(background) {
43
- const exploded = background == null ? void 0 : background.match(background.length >= 6 ? /[0-9a-fA-F]{2}/g : /[0-9a-fA-F]/g);
44
- if (!exploded || (exploded == null ? void 0 : exploded.length) < 3) return "black";
45
- const [r, g, b] = exploded.map((hex) => parseInt(hex.length == 1 ? `${hex}${hex}` : hex, 16));
46
- const luminance = (0.299 * r + 0.587 * g + 0.114 * b) / 255;
47
- return luminance > 0.5 ? "black" : "white";
48
- }
49
- class PromiseProgress extends Promise {
50
- constructor(executor) {
51
- super((resolve, reject) => executor(
52
- (value) => resolve(value),
53
- (reason) => reject(reason),
54
- (progress) => this.progress = progress
55
- ));
56
- __publicField2(this, "listeners", []);
57
- __publicField2(this, "_progress", 0);
58
- }
59
- get progress() {
60
- return this._progress;
61
- }
62
- set progress(p) {
63
- if (p == this._progress) return;
64
- this._progress = p;
65
- this.listeners.forEach((l) => l(p));
66
- }
67
- static from(promise) {
68
- if (promise instanceof PromiseProgress) return promise;
69
- return new PromiseProgress((res, rej) => promise.then((...args) => res(...args)).catch((...args) => rej(...args)));
70
- }
71
- from(promise) {
72
- const newPromise = PromiseProgress.from(promise);
73
- this.onProgress((p) => newPromise.progress = p);
74
- return newPromise;
75
- }
76
- onProgress(callback) {
77
- this.listeners.push(callback);
78
- return this;
79
- }
80
- then(res, rej) {
81
- const resp = super.then(res, rej);
82
- return this.from(resp);
83
- }
84
- catch(rej) {
85
- return this.from(super.catch(rej));
86
- }
87
- finally(res) {
88
- return this.from(super.finally(res));
89
- }
90
- }
91
- function formatDate(format = "YYYY-MM-DD H:mm", date = /* @__PURE__ */ new Date(), tz) {
92
- const timezones = [
93
- ["IDLW", -12],
94
- ["SST", -11],
95
- ["HST", -10],
96
- ["AKST", -9],
97
- ["PST", -8],
98
- ["MST", -7],
99
- ["CST", -6],
100
- ["EST", -5],
101
- ["AST", -4],
102
- ["BRT", -3],
103
- ["MAT", -2],
104
- ["AZOT", -1],
105
- ["UTC", 0],
106
- ["CET", 1],
107
- ["EET", 2],
108
- ["MSK", 3],
109
- ["AST", 4],
110
- ["PKT", 5],
111
- ["IST", 5.5],
112
- ["BST", 6],
113
- ["ICT", 7],
114
- ["CST", 8],
115
- ["JST", 9],
116
- ["AEST", 10],
117
- ["SBT", 11],
118
- ["FJT", 12],
119
- ["TOT", 13],
120
- ["LINT", 14]
121
- ];
122
- function adjustTz(date2, gmt) {
123
- const currentOffset = date2.getTimezoneOffset();
124
- const adjustedOffset = gmt * 60;
125
- return new Date(date2.getTime() + (adjustedOffset + currentOffset) * 6e4);
126
- }
127
- function day(num) {
128
- return ["Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"][num] || "Unknown";
129
- }
130
- function doy(date2) {
131
- const start = /* @__PURE__ */ new Date(`${date2.getFullYear()}-01-01 0:00:00`);
132
- return Math.ceil((date2.getTime() - start.getTime()) / (1e3 * 60 * 60 * 24));
133
- }
134
- function month(num) {
135
- return ["January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"][num] || "Unknown";
136
- }
137
- function suffix(num) {
138
- if (num % 100 >= 11 && num % 100 <= 13) return `${num}th`;
139
- switch (num % 10) {
140
- case 1:
141
- return `${num}st`;
142
- case 2:
143
- return `${num}nd`;
144
- case 3:
145
- return `${num}rd`;
146
- default:
147
- return `${num}th`;
148
- }
149
- }
150
- function tzOffset(offset) {
151
- const hours = ~~(offset / 60);
152
- const minutes = offset % 60;
153
- return (offset > 0 ? "-" : "") + `${hours}:${minutes.toString().padStart(2, "0")}`;
154
- }
155
- if (typeof date == "number" || typeof date == "string" || date == null) date = new Date(date);
156
- let t;
157
- if (tz == null) tz = -(date.getTimezoneOffset() / 60);
158
- t = timezones.find((t2) => isNaN(tz) ? t2[0] == tz : t2[1] == tz);
159
- if (!t) throw new Error(`Unknown timezone: ${tz}`);
160
- date = adjustTz(date, t[1]);
161
- const tokens = {
162
- "YYYY": date.getFullYear().toString(),
163
- "YY": date.getFullYear().toString().slice(2),
164
- "MMMM": month(date.getMonth()),
165
- "MMM": month(date.getMonth()).slice(0, 3),
166
- "MM": (date.getMonth() + 1).toString().padStart(2, "0"),
167
- "M": (date.getMonth() + 1).toString(),
168
- "DDD": doy(date).toString(),
169
- "DD": date.getDate().toString().padStart(2, "0"),
170
- "Do": suffix(date.getDate()),
171
- "D": date.getDate().toString(),
172
- "dddd": day(date.getDay()),
173
- "ddd": day(date.getDay()).slice(0, 3),
174
- "HH": date.getHours().toString().padStart(2, "0"),
175
- "H": date.getHours().toString(),
176
- "hh": (date.getHours() % 12 || 12).toString().padStart(2, "0"),
177
- "h": (date.getHours() % 12 || 12).toString(),
178
- "mm": date.getMinutes().toString().padStart(2, "0"),
179
- "m": date.getMinutes().toString(),
180
- "ss": date.getSeconds().toString().padStart(2, "0"),
181
- "s": date.getSeconds().toString(),
182
- "SSS": date.getMilliseconds().toString().padStart(3, "0"),
183
- "A": date.getHours() >= 12 ? "PM" : "AM",
184
- "a": date.getHours() >= 12 ? "pm" : "am",
185
- "ZZ": tzOffset(t[1] * 60).replace(":", ""),
186
- "Z": tzOffset(t[1] * 60),
187
- "z": typeof tz == "string" ? tz : t[0]
188
- };
189
- 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]);
190
- }
191
- class TypedEmitter {
192
- constructor() {
193
- __publicField2(this, "listeners", {});
194
- }
195
- static emit(event, ...args) {
196
- (this.listeners["*"] || []).forEach((l) => l(event, ...args));
197
- (this.listeners[event.toString()] || []).forEach((l) => l(...args));
198
- }
199
- static off(event, listener) {
200
- const e = event.toString();
201
- this.listeners[e] = (this.listeners[e] || []).filter((l) => l != listener);
202
- }
203
- static on(event, listener) {
204
- var _a;
205
- const e = event.toString();
206
- if (!this.listeners[e]) this.listeners[e] = [];
207
- (_a = this.listeners[e]) == null ? void 0 : _a.push(listener);
208
- return () => this.off(event, listener);
209
- }
210
- static once(event, listener) {
211
- return new Promise((res) => {
212
- const unsubscribe = this.on(event, (...args) => {
213
- res(args.length == 1 ? args[0] : args);
214
- if (listener) listener(...args);
215
- unsubscribe();
216
- });
217
- });
218
- }
219
- emit(event, ...args) {
220
- (this.listeners["*"] || []).forEach((l) => l(event, ...args));
221
- (this.listeners[event] || []).forEach((l) => l(...args));
222
- }
223
- off(event, listener) {
224
- this.listeners[event] = (this.listeners[event] || []).filter((l) => l != listener);
225
- }
226
- on(event, listener) {
227
- var _a;
228
- if (!this.listeners[event]) this.listeners[event] = [];
229
- (_a = this.listeners[event]) == null ? void 0 : _a.push(listener);
230
- return () => this.off(event, listener);
231
- }
232
- once(event, listener) {
233
- return new Promise((res) => {
234
- const unsubscribe = this.on(event, (...args) => {
235
- res(args.length == 1 ? args[0] : args);
236
- if (listener) listener(...args);
237
- unsubscribe();
238
- });
239
- });
240
- }
241
- }
242
- __publicField2(TypedEmitter, "listeners", {});
243
- class CustomError extends Error {
244
- constructor(message, code) {
245
- super(message);
246
- __publicField2(this, "_code");
247
- if (code != null) this._code = code;
248
- }
249
- get code() {
250
- return this._code || this.constructor.code;
251
- }
252
- set code(c) {
253
- this._code = c;
254
- }
255
- static from(err) {
256
- const code = Number(err.statusCode) ?? Number(err.code);
257
- const newErr = new this(err.message || err.toString());
258
- return Object.assign(newErr, {
259
- stack: err.stack,
260
- ...err,
261
- code: code ?? void 0
262
- });
263
- }
264
- static instanceof(err) {
265
- return err.constructor.code != void 0;
266
- }
267
- toString() {
268
- return this.message || super.toString();
269
- }
270
- }
271
- __publicField2(CustomError, "code", 500);
272
- class BadRequestError extends CustomError {
273
- constructor(message = "Bad Request") {
274
- super(message);
275
- }
276
- static instanceof(err) {
277
- return err.constructor.code == this.code;
278
- }
279
- }
280
- __publicField2(BadRequestError, "code", 400);
281
- class UnauthorizedError extends CustomError {
282
- constructor(message = "Unauthorized") {
283
- super(message);
284
- }
285
- static instanceof(err) {
286
- return err.constructor.code == this.code;
287
- }
288
- }
289
- __publicField2(UnauthorizedError, "code", 401);
290
- class PaymentRequiredError extends CustomError {
291
- constructor(message = "Payment Required") {
292
- super(message);
293
- }
294
- static instanceof(err) {
295
- return err.constructor.code == this.code;
296
- }
297
- }
298
- __publicField2(PaymentRequiredError, "code", 402);
299
- class ForbiddenError extends CustomError {
300
- constructor(message = "Forbidden") {
301
- super(message);
302
- }
303
- static instanceof(err) {
304
- return err.constructor.code == this.code;
305
- }
306
- }
307
- __publicField2(ForbiddenError, "code", 403);
308
- class NotFoundError extends CustomError {
309
- constructor(message = "Not Found") {
310
- super(message);
311
- }
312
- static instanceof(err) {
313
- return err.constructor.code == this.code;
314
- }
315
- }
316
- __publicField2(NotFoundError, "code", 404);
317
- class MethodNotAllowedError extends CustomError {
318
- constructor(message = "Method Not Allowed") {
319
- super(message);
320
- }
321
- static instanceof(err) {
322
- return err.constructor.code == this.code;
323
- }
324
- }
325
- __publicField2(MethodNotAllowedError, "code", 405);
326
- class NotAcceptableError extends CustomError {
327
- constructor(message = "Not Acceptable") {
328
- super(message);
329
- }
330
- static instanceof(err) {
331
- return err.constructor.code == this.code;
332
- }
333
- }
334
- __publicField2(NotAcceptableError, "code", 406);
335
- class InternalServerError extends CustomError {
336
- constructor(message = "Internal Server Error") {
337
- super(message);
338
- }
339
- static instanceof(err) {
340
- return err.constructor.code == this.code;
341
- }
342
- }
343
- __publicField2(InternalServerError, "code", 500);
344
- class NotImplementedError extends CustomError {
345
- constructor(message = "Not Implemented") {
346
- super(message);
347
- }
348
- static instanceof(err) {
349
- return err.constructor.code == this.code;
350
- }
351
- }
352
- __publicField2(NotImplementedError, "code", 501);
353
- class BadGatewayError extends CustomError {
354
- constructor(message = "Bad Gateway") {
355
- super(message);
356
- }
357
- static instanceof(err) {
358
- return err.constructor.code == this.code;
359
- }
360
- }
361
- __publicField2(BadGatewayError, "code", 502);
362
- class ServiceUnavailableError extends CustomError {
363
- constructor(message = "Service Unavailable") {
364
- super(message);
365
- }
366
- static instanceof(err) {
367
- return err.constructor.code == this.code;
368
- }
369
- }
370
- __publicField2(ServiceUnavailableError, "code", 503);
371
- class GatewayTimeoutError extends CustomError {
372
- constructor(message = "Gateway Timeout") {
373
- super(message);
374
- }
375
- static instanceof(err) {
376
- return err.constructor.code == this.code;
377
- }
378
- }
379
- __publicField2(GatewayTimeoutError, "code", 504);
380
- function errorFromCode(code, message) {
381
- switch (code) {
382
- case 400:
383
- return new BadRequestError(message);
384
- case 401:
385
- return new UnauthorizedError(message);
386
- case 402:
387
- return new PaymentRequiredError(message);
388
- case 403:
389
- return new ForbiddenError(message);
390
- case 404:
391
- return new NotFoundError(message);
392
- case 405:
393
- return new MethodNotAllowedError(message);
394
- case 406:
395
- return new NotAcceptableError(message);
396
- case 500:
397
- return new InternalServerError(message);
398
- case 501:
399
- return new NotImplementedError(message);
400
- case 502:
401
- return new BadGatewayError(message);
402
- case 503:
403
- return new ServiceUnavailableError(message);
404
- case 504:
405
- return new GatewayTimeoutError(message);
406
- default:
407
- return new CustomError(message, code);
408
- }
409
- }
410
- class HttpResponse extends Response {
411
- constructor(resp, stream) {
412
- const body = [204, 205, 304].includes(resp.status) ? null : stream;
413
- super(body, {
414
- headers: resp.headers,
415
- status: resp.status,
416
- statusText: resp.statusText
417
- });
418
- __publicField2(this, "data");
419
- __publicField2(this, "ok");
420
- __publicField2(this, "redirected");
421
- __publicField2(this, "type");
422
- __publicField2(this, "url");
423
- this.ok = resp.ok;
424
- this.redirected = resp.redirected;
425
- this.type = resp.type;
426
- this.url = resp.url;
427
- }
428
- }
429
- const _Http = class _Http2 {
430
- constructor(defaults = {}) {
431
- __publicField2(this, "interceptors", {});
432
- __publicField2(this, "headers", {});
433
- __publicField2(this, "url");
434
- this.url = defaults.url ?? null;
435
- this.headers = defaults.headers || {};
436
- if (defaults.interceptors) {
437
- defaults.interceptors.forEach((i) => _Http2.addInterceptor(i));
438
- }
439
- }
440
- static addInterceptor(fn2) {
441
- const key = Object.keys(_Http2.interceptors).length.toString();
442
- _Http2.interceptors[key] = fn2;
443
- return () => {
444
- _Http2.interceptors[key] = null;
445
- };
446
- }
447
- addInterceptor(fn2) {
448
- const key = Object.keys(this.interceptors).length.toString();
449
- this.interceptors[key] = fn2;
450
- return () => {
451
- this.interceptors[key] = null;
452
- };
453
- }
454
- request(opts = {}) {
455
- var _a;
456
- if (!this.url && !opts.url) throw new Error("URL needs to be set");
457
- let url = ((_a = opts.url) == null ? void 0 : _a.startsWith("http")) ? opts.url : (this.url || "") + (opts.url || "");
458
- url = url.replaceAll(/([^:]\/)\/+/g, "$1");
459
- if (opts.fragment) url.includes("#") ? url.replace(/#.*(\?|\n)/g, (match, arg1) => `#${opts.fragment}${arg1}`) : `${url}#${opts.fragment}`;
460
- if (opts.query) {
461
- const q = Array.isArray(opts.query) ? opts.query : Object.keys(opts.query).map((k) => ({ key: k, value: opts.query[k] }));
462
- url += (url.includes("?") ? "&" : "?") + q.map((q2) => `${q2.key}=${q2.value}`).join("&");
463
- }
464
- const headers = clean({
465
- "Content-Type": !opts.body ? void 0 : opts.body instanceof FormData ? "multipart/form-data" : "application/json",
466
- ..._Http2.headers,
467
- ...this.headers,
468
- ...opts.headers
469
- });
470
- if (typeof opts.body == "object" && opts.body != null && headers["Content-Type"] == "application/json")
471
- opts.body = JSON.stringify(opts.body);
472
- return new PromiseProgress((res, rej, prog) => {
473
- try {
474
- fetch(url, {
475
- headers,
476
- method: opts.method || (opts.body ? "POST" : "GET"),
477
- body: opts.body
478
- }).then(async (resp) => {
479
- var _a2, _b;
480
- for (let fn2 of [...Object.values(_Http2.interceptors), ...Object.values(this.interceptors)]) {
481
- await new Promise((res2) => fn2(resp, () => res2()));
482
- }
483
- const contentLength = resp.headers.get("Content-Length");
484
- const total = contentLength ? parseInt(contentLength, 10) : 0;
485
- let loaded = 0;
486
- const reader = (_a2 = resp.body) == null ? void 0 : _a2.getReader();
487
- const stream = new ReadableStream({
488
- start(controller) {
489
- function push() {
490
- reader == null ? void 0 : reader.read().then((event) => {
491
- if (event.done) return controller.close();
492
- loaded += event.value.byteLength;
493
- prog(loaded / total);
494
- controller.enqueue(event.value);
495
- push();
496
- }).catch((error) => controller.error(error));
497
- }
498
- push();
499
- }
500
- });
501
- resp = new HttpResponse(resp, stream);
502
- if (opts.decode !== false) {
503
- const content = (_b = resp.headers.get("Content-Type")) == null ? void 0 : _b.toLowerCase();
504
- if (content == null ? void 0 : content.includes("form")) resp.data = await resp.formData();
505
- else if (content == null ? void 0 : content.includes("json")) resp.data = await resp.json();
506
- else if (content == null ? void 0 : content.includes("text")) resp.data = await resp.text();
507
- else if (content == null ? void 0 : content.includes("application")) resp.data = await resp.blob();
508
- }
509
- if (resp.ok) res(resp);
510
- else rej(resp);
511
- }).catch((err) => rej(err));
512
- } catch (err) {
513
- rej(err);
514
- }
515
- });
516
- }
517
- };
518
- __publicField2(_Http, "interceptors", {});
519
- __publicField2(_Http, "headers", {});
520
- function decodeJwt(token) {
521
- const base64 = token.split(".")[1].replace(/-/g, "+").replace(/_/g, "/");
522
- return JSONAttemptParse(decodeURIComponent(atob(base64).split("").map(function(c) {
523
- return "%" + ("00" + c.charCodeAt(0).toString(16)).slice(-2);
524
- }).join("")));
525
- }
526
- const CliEffects = {
527
- CLEAR: "\x1B[0m"
528
- };
529
- const CliForeground = {
530
- RED: "\x1B[31m",
531
- YELLOW: "\x1B[33m",
532
- BLUE: "\x1B[34m",
533
- LIGHT_GREY: "\x1B[37m"
534
- };
535
- const _Logger = class _Logger2 extends TypedEmitter {
536
- constructor(namespace) {
537
- super();
538
- this.namespace = namespace;
539
- }
540
- format(...text) {
541
- const now = /* @__PURE__ */ new Date();
542
- const timestamp = `${now.getFullYear()}-${now.getMonth() + 1}-${now.getDate()} ${now.getHours().toString().padStart(2, "0")}:${now.getMinutes().toString().padStart(2, "0")}:${now.getSeconds().toString().padStart(2, "0")}.${now.getMilliseconds().toString().padEnd(3, "0")}`;
543
- return `${timestamp}${this.namespace ? ` [${this.namespace}]` : ""} ${text.map((t) => typeof t == "string" ? t : JSONSanitize(t, 2)).join(" ")}`;
544
- }
545
- debug(...args) {
546
- if (_Logger2.LOG_LEVEL < 4) return;
547
- const str = this.format(...args);
548
- _Logger2.emit(4, str);
549
- console.debug(CliForeground.LIGHT_GREY + str + CliEffects.CLEAR);
550
- }
551
- log(...args) {
552
- if (_Logger2.LOG_LEVEL < 3) return;
553
- const str = this.format(...args);
554
- _Logger2.emit(3, str);
555
- console.log(CliEffects.CLEAR + str);
556
- }
557
- info(...args) {
558
- if (_Logger2.LOG_LEVEL < 2) return;
559
- const str = this.format(...args);
560
- _Logger2.emit(2, str);
561
- console.info(CliForeground.BLUE + str + CliEffects.CLEAR);
562
- }
563
- warn(...args) {
564
- if (_Logger2.LOG_LEVEL < 1) return;
565
- const str = this.format(...args);
566
- _Logger2.emit(1, str);
567
- console.warn(CliForeground.YELLOW + str + CliEffects.CLEAR);
568
- }
569
- error(...args) {
570
- if (_Logger2.LOG_LEVEL < 0) return;
571
- const str = this.format(...args);
572
- _Logger2.emit(0, str);
573
- console.error(CliForeground.RED + str + CliEffects.CLEAR);
574
- }
575
- };
576
- __publicField2(_Logger, "LOG_LEVEL", 4);
577
- var commonjsGlobal = typeof globalThis !== "undefined" ? globalThis : typeof window !== "undefined" ? window : typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : {};
578
- var dist = {};
579
- var persist$1 = {};
580
- Object.defineProperty(persist$1, "__esModule", { value: true });
581
- persist$1.persist = persist$1.Persist = void 0;
582
- class Persist {
583
- /**
584
- * @param {string} key Primary key value will be stored under
585
- * @param {PersistOptions<T>} options Configure using {@link PersistOptions}
586
- */
587
- constructor(key, options = {}) {
588
- __publicField2(this, "key");
589
- __publicField2(this, "options");
590
- __publicField2(this, "storage");
591
- __publicField2(this, "watches", {});
592
- __publicField2(this, "_value");
593
- this.key = key;
594
- this.options = options;
595
- this.storage = options.storage || localStorage;
596
- this.load();
597
- }
598
- /** Current value or default if undefined */
599
- get value() {
600
- var _a;
601
- return this._value !== void 0 ? this._value : (_a = this.options) == null ? void 0 : _a.default;
602
- }
603
- /** Set value with proxy object wrapper to sync future changes */
604
- set value(v) {
605
- if (v == null || typeof v != "object")
606
- this._value = v;
607
- else
608
- this._value = new Proxy(v, {
609
- get: (target, p) => {
610
- const f = typeof target[p] == "function";
611
- if (!f)
612
- return target[p];
613
- return (...args) => {
614
- const value = target[p](...args);
615
- this.save();
616
- return value;
617
- };
618
- },
619
- set: (target, p, newValue) => {
620
- target[p] = newValue;
621
- this.save();
622
- return true;
623
- }
624
- });
625
- this.save();
626
- }
627
- /** Notify listeners of change */
628
- notify(value) {
629
- Object.values(this.watches).forEach((watch) => watch(value));
630
- }
631
- /** Delete value from storage */
632
- clear() {
633
- this.storage.removeItem(this.key);
634
- }
635
- /** Save current value to storage */
636
- save() {
637
- if (this._value === void 0)
638
- this.clear();
639
- else
640
- this.storage.setItem(this.key, JSON.stringify(this._value));
641
- this.notify(this.value);
642
- }
643
- /** Load value from storage */
644
- load() {
645
- if (this.storage[this.key] != void 0) {
646
- let value = JSON.parse(this.storage.getItem(this.key));
647
- if (value != null && typeof value == "object" && this.options.type)
648
- value.__proto__ = this.options.type.prototype;
649
- this.value = value;
650
- } else
651
- this.value = this.options.default || void 0;
652
- }
653
- /**
654
- * Callback function which is run when there are changes
655
- *
656
- * @param {(value: T) => any} fn Callback will run on each change; it's passed the next value & it's return is ignored
657
- * @returns {() => void} Function which will unsubscribe the watch/callback when called
658
- */
659
- watch(fn2) {
660
- const index = Object.keys(this.watches).length;
661
- this.watches[index] = fn2;
662
- return () => {
663
- delete this.watches[index];
664
- };
665
- }
666
- /**
667
- * Return value as JSON string
668
- *
669
- * @returns {string} Stringified object as JSON
670
- */
671
- toString() {
672
- return JSON.stringify(this.value);
673
- }
674
- /**
675
- * Return current value
676
- *
677
- * @returns {T} Current value
678
- */
679
- valueOf() {
680
- return this.value;
681
- }
682
- }
683
- persist$1.Persist = Persist;
684
- function persist(options) {
685
- return (target, prop) => {
686
- const key = (options == null ? void 0 : options.key) || `${target.constructor.name}.${prop.toString()}`;
687
- const wrapper = new Persist(key, options);
688
- Object.defineProperty(target, prop, {
689
- get: function() {
690
- return wrapper.value;
691
- },
692
- set: function(v) {
693
- wrapper.value = v;
694
- }
695
- });
696
- };
697
- }
698
- persist$1.persist = persist;
699
- var memoryStorage = {};
700
- Object.defineProperty(memoryStorage, "__esModule", { value: true });
701
- memoryStorage.MemoryStorage = void 0;
702
- class MemoryStorage {
703
- get length() {
704
- return Object.keys(this).length;
705
- }
706
- clear() {
707
- Object.keys(this).forEach((k) => this.removeItem(k));
708
- }
709
- getItem(key) {
710
- return this[key];
711
- }
712
- key(index) {
713
- return Object.keys(this)[index];
714
- }
715
- removeItem(key) {
716
- delete this[key];
717
- }
718
- setItem(key, value) {
719
- this[key] = value;
720
- }
721
- }
722
- memoryStorage.MemoryStorage = MemoryStorage;
723
- (function(exports3) {
724
- var __createBinding = commonjsGlobal && commonjsGlobal.__createBinding || (Object.create ? function(o, m, k, k2) {
725
- if (k2 === void 0) k2 = k;
726
- var desc = Object.getOwnPropertyDescriptor(m, k);
727
- if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
728
- desc = { enumerable: true, get: function() {
729
- return m[k];
730
- } };
731
- }
732
- Object.defineProperty(o, k2, desc);
733
- } : function(o, m, k, k2) {
734
- if (k2 === void 0) k2 = k;
735
- o[k2] = m[k];
736
- });
737
- var __exportStar = commonjsGlobal && commonjsGlobal.__exportStar || function(m, exports22) {
738
- for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports22, p)) __createBinding(exports22, m, p);
739
- };
740
- Object.defineProperty(exports3, "__esModule", { value: true });
741
- __exportStar(persist$1, exports3);
742
- __exportStar(memoryStorage, exports3);
743
- })(dist);
744
- var extendStatics = function(d, b) {
745
- extendStatics = Object.setPrototypeOf || { __proto__: [] } instanceof Array && function(d2, b2) {
746
- d2.__proto__ = b2;
747
- } || function(d2, b2) {
748
- for (var p in b2) if (Object.prototype.hasOwnProperty.call(b2, p)) d2[p] = b2[p];
749
- };
750
- return extendStatics(d, b);
751
- };
752
- function __extends(d, b) {
753
- if (typeof b !== "function" && b !== null)
754
- throw new TypeError("Class extends value " + String(b) + " is not a constructor or null");
755
- extendStatics(d, b);
756
- function __() {
757
- this.constructor = d;
758
- }
759
- d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
760
- }
761
- function __values(o) {
762
- var s = typeof Symbol === "function" && Symbol.iterator, m = s && o[s], i = 0;
763
- if (m) return m.call(o);
764
- if (o && typeof o.length === "number") return {
765
- next: function() {
766
- if (o && i >= o.length) o = void 0;
767
- return { value: o && o[i++], done: !o };
768
- }
769
- };
770
- throw new TypeError(s ? "Object is not iterable." : "Symbol.iterator is not defined.");
771
- }
772
- function __read(o, n) {
773
- var m = typeof Symbol === "function" && o[Symbol.iterator];
774
- if (!m) return o;
775
- var i = m.call(o), r, ar = [], e;
776
- try {
777
- while ((n === void 0 || n-- > 0) && !(r = i.next()).done) ar.push(r.value);
778
- } catch (error) {
779
- e = { error };
780
- } finally {
781
- try {
782
- if (r && !r.done && (m = i["return"])) m.call(i);
783
- } finally {
784
- if (e) throw e.error;
785
- }
786
- }
787
- return ar;
788
- }
789
- function __spreadArray(to, from, pack) {
790
- if (pack || arguments.length === 2) for (var i = 0, l = from.length, ar; i < l; i++) {
791
- if (ar || !(i in from)) {
792
- if (!ar) ar = Array.prototype.slice.call(from, 0, i);
793
- ar[i] = from[i];
794
- }
795
- }
796
- return to.concat(ar || Array.prototype.slice.call(from));
797
- }
798
- typeof SuppressedError === "function" ? SuppressedError : function(error, suppressed, message) {
799
- var e = new Error(message);
800
- return e.name = "SuppressedError", e.error = error, e.suppressed = suppressed, e;
801
- };
802
- function isFunction(value) {
803
- return typeof value === "function";
804
- }
805
- function createErrorClass(createImpl) {
806
- var _super = function(instance) {
807
- Error.call(instance);
808
- instance.stack = new Error().stack;
809
- };
810
- var ctorFunc = createImpl(_super);
811
- ctorFunc.prototype = Object.create(Error.prototype);
812
- ctorFunc.prototype.constructor = ctorFunc;
813
- return ctorFunc;
814
- }
815
- var UnsubscriptionError = createErrorClass(function(_super) {
816
- return function UnsubscriptionErrorImpl(errors) {
817
- _super(this);
818
- this.message = errors ? errors.length + " errors occurred during unsubscription:\n" + errors.map(function(err, i) {
819
- return i + 1 + ") " + err.toString();
820
- }).join("\n ") : "";
821
- this.name = "UnsubscriptionError";
822
- this.errors = errors;
823
- };
824
- });
825
- function arrRemove(arr, item) {
826
- if (arr) {
827
- var index = arr.indexOf(item);
828
- 0 <= index && arr.splice(index, 1);
829
- }
830
- }
831
- var Subscription = function() {
832
- function Subscription2(initialTeardown) {
833
- this.initialTeardown = initialTeardown;
834
- this.closed = false;
835
- this._parentage = null;
836
- this._finalizers = null;
837
- }
838
- Subscription2.prototype.unsubscribe = function() {
839
- var e_1, _a, e_2, _b;
840
- var errors;
841
- if (!this.closed) {
842
- this.closed = true;
843
- var _parentage = this._parentage;
844
- if (_parentage) {
845
- this._parentage = null;
846
- if (Array.isArray(_parentage)) {
847
- try {
848
- for (var _parentage_1 = __values(_parentage), _parentage_1_1 = _parentage_1.next(); !_parentage_1_1.done; _parentage_1_1 = _parentage_1.next()) {
849
- var parent_1 = _parentage_1_1.value;
850
- parent_1.remove(this);
851
- }
852
- } catch (e_1_1) {
853
- e_1 = { error: e_1_1 };
854
- } finally {
855
- try {
856
- if (_parentage_1_1 && !_parentage_1_1.done && (_a = _parentage_1.return)) _a.call(_parentage_1);
857
- } finally {
858
- if (e_1) throw e_1.error;
859
- }
860
- }
861
- } else {
862
- _parentage.remove(this);
863
- }
864
- }
865
- var initialFinalizer = this.initialTeardown;
866
- if (isFunction(initialFinalizer)) {
867
- try {
868
- initialFinalizer();
869
- } catch (e) {
870
- errors = e instanceof UnsubscriptionError ? e.errors : [e];
871
- }
872
- }
873
- var _finalizers = this._finalizers;
874
- if (_finalizers) {
875
- this._finalizers = null;
876
- try {
877
- for (var _finalizers_1 = __values(_finalizers), _finalizers_1_1 = _finalizers_1.next(); !_finalizers_1_1.done; _finalizers_1_1 = _finalizers_1.next()) {
878
- var finalizer = _finalizers_1_1.value;
879
- try {
880
- execFinalizer(finalizer);
881
- } catch (err) {
882
- errors = errors !== null && errors !== void 0 ? errors : [];
883
- if (err instanceof UnsubscriptionError) {
884
- errors = __spreadArray(__spreadArray([], __read(errors)), __read(err.errors));
885
- } else {
886
- errors.push(err);
887
- }
888
- }
889
- }
890
- } catch (e_2_1) {
891
- e_2 = { error: e_2_1 };
892
- } finally {
893
- try {
894
- if (_finalizers_1_1 && !_finalizers_1_1.done && (_b = _finalizers_1.return)) _b.call(_finalizers_1);
895
- } finally {
896
- if (e_2) throw e_2.error;
897
- }
898
- }
899
- }
900
- if (errors) {
901
- throw new UnsubscriptionError(errors);
902
- }
903
- }
904
- };
905
- Subscription2.prototype.add = function(teardown) {
906
- var _a;
907
- if (teardown && teardown !== this) {
908
- if (this.closed) {
909
- execFinalizer(teardown);
910
- } else {
911
- if (teardown instanceof Subscription2) {
912
- if (teardown.closed || teardown._hasParent(this)) {
913
- return;
914
- }
915
- teardown._addParent(this);
916
- }
917
- (this._finalizers = (_a = this._finalizers) !== null && _a !== void 0 ? _a : []).push(teardown);
918
- }
919
- }
920
- };
921
- Subscription2.prototype._hasParent = function(parent) {
922
- var _parentage = this._parentage;
923
- return _parentage === parent || Array.isArray(_parentage) && _parentage.includes(parent);
924
- };
925
- Subscription2.prototype._addParent = function(parent) {
926
- var _parentage = this._parentage;
927
- this._parentage = Array.isArray(_parentage) ? (_parentage.push(parent), _parentage) : _parentage ? [_parentage, parent] : parent;
928
- };
929
- Subscription2.prototype._removeParent = function(parent) {
930
- var _parentage = this._parentage;
931
- if (_parentage === parent) {
932
- this._parentage = null;
933
- } else if (Array.isArray(_parentage)) {
934
- arrRemove(_parentage, parent);
935
- }
936
- };
937
- Subscription2.prototype.remove = function(teardown) {
938
- var _finalizers = this._finalizers;
939
- _finalizers && arrRemove(_finalizers, teardown);
940
- if (teardown instanceof Subscription2) {
941
- teardown._removeParent(this);
942
- }
943
- };
944
- Subscription2.EMPTY = function() {
945
- var empty = new Subscription2();
946
- empty.closed = true;
947
- return empty;
948
- }();
949
- return Subscription2;
950
- }();
951
- var EMPTY_SUBSCRIPTION = Subscription.EMPTY;
952
- function isSubscription(value) {
953
- return value instanceof Subscription || value && "closed" in value && isFunction(value.remove) && isFunction(value.add) && isFunction(value.unsubscribe);
954
- }
955
- function execFinalizer(finalizer) {
956
- if (isFunction(finalizer)) {
957
- finalizer();
958
- } else {
959
- finalizer.unsubscribe();
960
- }
961
- }
962
- var config = {
963
- Promise: void 0
964
- };
965
- var timeoutProvider = {
966
- setTimeout: function(handler, timeout) {
967
- var args = [];
968
- for (var _i = 2; _i < arguments.length; _i++) {
969
- args[_i - 2] = arguments[_i];
970
- }
971
- return setTimeout.apply(void 0, __spreadArray([handler, timeout], __read(args)));
972
- },
973
- clearTimeout: function(handle) {
974
- return clearTimeout(handle);
975
- },
976
- delegate: void 0
977
- };
978
- function reportUnhandledError(err) {
979
- timeoutProvider.setTimeout(function() {
980
- {
981
- throw err;
982
- }
983
- });
984
- }
985
- function noop() {
986
- }
987
- function errorContext(cb) {
988
- {
989
- cb();
990
- }
991
- }
992
- var Subscriber = function(_super) {
993
- __extends(Subscriber2, _super);
994
- function Subscriber2(destination) {
995
- var _this = _super.call(this) || this;
996
- _this.isStopped = false;
997
- if (destination) {
998
- _this.destination = destination;
999
- if (isSubscription(destination)) {
1000
- destination.add(_this);
1001
- }
1002
- } else {
1003
- _this.destination = EMPTY_OBSERVER;
1004
- }
1005
- return _this;
1006
- }
1007
- Subscriber2.create = function(next, error, complete) {
1008
- return new SafeSubscriber(next, error, complete);
1009
- };
1010
- Subscriber2.prototype.next = function(value) {
1011
- if (this.isStopped) ;
1012
- else {
1013
- this._next(value);
1014
- }
1015
- };
1016
- Subscriber2.prototype.error = function(err) {
1017
- if (this.isStopped) ;
1018
- else {
1019
- this.isStopped = true;
1020
- this._error(err);
1021
- }
1022
- };
1023
- Subscriber2.prototype.complete = function() {
1024
- if (this.isStopped) ;
1025
- else {
1026
- this.isStopped = true;
1027
- this._complete();
1028
- }
1029
- };
1030
- Subscriber2.prototype.unsubscribe = function() {
1031
- if (!this.closed) {
1032
- this.isStopped = true;
1033
- _super.prototype.unsubscribe.call(this);
1034
- this.destination = null;
1035
- }
1036
- };
1037
- Subscriber2.prototype._next = function(value) {
1038
- this.destination.next(value);
1039
- };
1040
- Subscriber2.prototype._error = function(err) {
1041
- try {
1042
- this.destination.error(err);
1043
- } finally {
1044
- this.unsubscribe();
1045
- }
1046
- };
1047
- Subscriber2.prototype._complete = function() {
1048
- try {
1049
- this.destination.complete();
1050
- } finally {
1051
- this.unsubscribe();
1052
- }
1053
- };
1054
- return Subscriber2;
1055
- }(Subscription);
1056
- var ConsumerObserver = function() {
1057
- function ConsumerObserver2(partialObserver) {
1058
- this.partialObserver = partialObserver;
1059
- }
1060
- ConsumerObserver2.prototype.next = function(value) {
1061
- var partialObserver = this.partialObserver;
1062
- if (partialObserver.next) {
1063
- try {
1064
- partialObserver.next(value);
1065
- } catch (error) {
1066
- handleUnhandledError(error);
1067
- }
1068
- }
1069
- };
1070
- ConsumerObserver2.prototype.error = function(err) {
1071
- var partialObserver = this.partialObserver;
1072
- if (partialObserver.error) {
1073
- try {
1074
- partialObserver.error(err);
1075
- } catch (error) {
1076
- handleUnhandledError(error);
1077
- }
1078
- } else {
1079
- handleUnhandledError(err);
1080
- }
1081
- };
1082
- ConsumerObserver2.prototype.complete = function() {
1083
- var partialObserver = this.partialObserver;
1084
- if (partialObserver.complete) {
1085
- try {
1086
- partialObserver.complete();
1087
- } catch (error) {
1088
- handleUnhandledError(error);
1089
- }
1090
- }
1091
- };
1092
- return ConsumerObserver2;
1093
- }();
1094
- var SafeSubscriber = function(_super) {
1095
- __extends(SafeSubscriber2, _super);
1096
- function SafeSubscriber2(observerOrNext, error, complete) {
1097
- var _this = _super.call(this) || this;
1098
- var partialObserver;
1099
- if (isFunction(observerOrNext) || !observerOrNext) {
1100
- partialObserver = {
1101
- next: observerOrNext !== null && observerOrNext !== void 0 ? observerOrNext : void 0,
1102
- error: error !== null && error !== void 0 ? error : void 0,
1103
- complete: complete !== null && complete !== void 0 ? complete : void 0
1104
- };
1105
- } else {
1106
- {
1107
- partialObserver = observerOrNext;
1108
- }
1109
- }
1110
- _this.destination = new ConsumerObserver(partialObserver);
1111
- return _this;
1112
- }
1113
- return SafeSubscriber2;
1114
- }(Subscriber);
1115
- function handleUnhandledError(error) {
1116
- {
1117
- reportUnhandledError(error);
1118
- }
1119
- }
1120
- function defaultErrorHandler(err) {
1121
- throw err;
1122
- }
1123
- var EMPTY_OBSERVER = {
1124
- closed: true,
1125
- next: noop,
1126
- error: defaultErrorHandler,
1127
- complete: noop
1128
- };
1129
- var observable = function() {
1130
- return typeof Symbol === "function" && Symbol.observable || "@@observable";
1131
- }();
1132
- function identity(x) {
1133
- return x;
1134
- }
1135
- function pipeFromArray(fns) {
1136
- if (fns.length === 0) {
1137
- return identity;
1138
- }
1139
- if (fns.length === 1) {
1140
- return fns[0];
1141
- }
1142
- return function piped(input) {
1143
- return fns.reduce(function(prev, fn) {
1144
- return fn(prev);
1145
- }, input);
1146
- };
1147
- }
1148
- var Observable = function() {
1149
- function Observable2(subscribe) {
1150
- if (subscribe) {
1151
- this._subscribe = subscribe;
1152
- }
1153
- }
1154
- Observable2.prototype.lift = function(operator) {
1155
- var observable2 = new Observable2();
1156
- observable2.source = this;
1157
- observable2.operator = operator;
1158
- return observable2;
1159
- };
1160
- Observable2.prototype.subscribe = function(observerOrNext, error, complete) {
1161
- var _this = this;
1162
- var subscriber = isSubscriber(observerOrNext) ? observerOrNext : new SafeSubscriber(observerOrNext, error, complete);
1163
- errorContext(function() {
1164
- var _a = _this, operator = _a.operator, source = _a.source;
1165
- subscriber.add(operator ? operator.call(subscriber, source) : source ? _this._subscribe(subscriber) : _this._trySubscribe(subscriber));
1166
- });
1167
- return subscriber;
1168
- };
1169
- Observable2.prototype._trySubscribe = function(sink) {
1170
- try {
1171
- return this._subscribe(sink);
1172
- } catch (err) {
1173
- sink.error(err);
1174
- }
1175
- };
1176
- Observable2.prototype.forEach = function(next, promiseCtor) {
1177
- var _this = this;
1178
- promiseCtor = getPromiseCtor(promiseCtor);
1179
- return new promiseCtor(function(resolve, reject) {
1180
- var subscriber = new SafeSubscriber({
1181
- next: function(value) {
1182
- try {
1183
- next(value);
1184
- } catch (err) {
1185
- reject(err);
1186
- subscriber.unsubscribe();
1187
- }
1188
- },
1189
- error: reject,
1190
- complete: resolve
1191
- });
1192
- _this.subscribe(subscriber);
1193
- });
1194
- };
1195
- Observable2.prototype._subscribe = function(subscriber) {
1196
- var _a;
1197
- return (_a = this.source) === null || _a === void 0 ? void 0 : _a.subscribe(subscriber);
1198
- };
1199
- Observable2.prototype[observable] = function() {
1200
- return this;
1201
- };
1202
- Observable2.prototype.pipe = function() {
1203
- var operations = [];
1204
- for (var _i = 0; _i < arguments.length; _i++) {
1205
- operations[_i] = arguments[_i];
1206
- }
1207
- return pipeFromArray(operations)(this);
1208
- };
1209
- Observable2.prototype.toPromise = function(promiseCtor) {
1210
- var _this = this;
1211
- promiseCtor = getPromiseCtor(promiseCtor);
1212
- return new promiseCtor(function(resolve, reject) {
1213
- var value;
1214
- _this.subscribe(function(x) {
1215
- return value = x;
1216
- }, function(err) {
1217
- return reject(err);
1218
- }, function() {
1219
- return resolve(value);
1220
- });
1221
- });
1222
- };
1223
- Observable2.create = function(subscribe) {
1224
- return new Observable2(subscribe);
1225
- };
1226
- return Observable2;
1227
- }();
1228
- function getPromiseCtor(promiseCtor) {
1229
- var _a;
1230
- return (_a = promiseCtor !== null && promiseCtor !== void 0 ? promiseCtor : config.Promise) !== null && _a !== void 0 ? _a : Promise;
1231
- }
1232
- function isObserver(value) {
1233
- return value && isFunction(value.next) && isFunction(value.error) && isFunction(value.complete);
1234
- }
1235
- function isSubscriber(value) {
1236
- return value && value instanceof Subscriber || isObserver(value) && isSubscription(value);
1237
- }
1238
- function hasLift(source) {
1239
- return isFunction(source === null || source === void 0 ? void 0 : source.lift);
1240
- }
1241
- function operate(init) {
1242
- return function(source) {
1243
- if (hasLift(source)) {
1244
- return source.lift(function(liftedSource) {
1245
- try {
1246
- return init(liftedSource, this);
1247
- } catch (err) {
1248
- this.error(err);
1249
- }
1250
- });
1251
- }
1252
- throw new TypeError("Unable to lift unknown Observable type");
1253
- };
1254
- }
1255
- function createOperatorSubscriber(destination, onNext, onComplete, onError, onFinalize) {
1256
- return new OperatorSubscriber(destination, onNext, onComplete, onError, onFinalize);
1257
- }
1258
- var OperatorSubscriber = function(_super) {
1259
- __extends(OperatorSubscriber2, _super);
1260
- function OperatorSubscriber2(destination, onNext, onComplete, onError, onFinalize, shouldUnsubscribe) {
1261
- var _this = _super.call(this, destination) || this;
1262
- _this.onFinalize = onFinalize;
1263
- _this.shouldUnsubscribe = shouldUnsubscribe;
1264
- _this._next = onNext ? function(value) {
1265
- try {
1266
- onNext(value);
1267
- } catch (err) {
1268
- destination.error(err);
1269
- }
1270
- } : _super.prototype._next;
1271
- _this._error = onError ? function(err) {
1272
- try {
1273
- onError(err);
1274
- } catch (err2) {
1275
- destination.error(err2);
1276
- } finally {
1277
- this.unsubscribe();
1278
- }
1279
- } : _super.prototype._error;
1280
- _this._complete = onComplete ? function() {
1281
- try {
1282
- onComplete();
1283
- } catch (err) {
1284
- destination.error(err);
1285
- } finally {
1286
- this.unsubscribe();
1287
- }
1288
- } : _super.prototype._complete;
1289
- return _this;
1290
- }
1291
- OperatorSubscriber2.prototype.unsubscribe = function() {
1292
- var _a;
1293
- if (!this.shouldUnsubscribe || this.shouldUnsubscribe()) {
1294
- var closed_1 = this.closed;
1295
- _super.prototype.unsubscribe.call(this);
1296
- !closed_1 && ((_a = this.onFinalize) === null || _a === void 0 ? void 0 : _a.call(this));
1297
- }
1298
- };
1299
- return OperatorSubscriber2;
1300
- }(Subscriber);
1301
- var ObjectUnsubscribedError = createErrorClass(function(_super) {
1302
- return function ObjectUnsubscribedErrorImpl() {
1303
- _super(this);
1304
- this.name = "ObjectUnsubscribedError";
1305
- this.message = "object unsubscribed";
1306
- };
1307
- });
1308
- var Subject = function(_super) {
1309
- __extends(Subject2, _super);
1310
- function Subject2() {
1311
- var _this = _super.call(this) || this;
1312
- _this.closed = false;
1313
- _this.currentObservers = null;
1314
- _this.observers = [];
1315
- _this.isStopped = false;
1316
- _this.hasError = false;
1317
- _this.thrownError = null;
1318
- return _this;
1319
- }
1320
- Subject2.prototype.lift = function(operator) {
1321
- var subject = new AnonymousSubject(this, this);
1322
- subject.operator = operator;
1323
- return subject;
1324
- };
1325
- Subject2.prototype._throwIfClosed = function() {
1326
- if (this.closed) {
1327
- throw new ObjectUnsubscribedError();
1328
- }
1329
- };
1330
- Subject2.prototype.next = function(value) {
1331
- var _this = this;
1332
- errorContext(function() {
1333
- var e_1, _a;
1334
- _this._throwIfClosed();
1335
- if (!_this.isStopped) {
1336
- if (!_this.currentObservers) {
1337
- _this.currentObservers = Array.from(_this.observers);
1338
- }
1339
- try {
1340
- for (var _b = __values(_this.currentObservers), _c = _b.next(); !_c.done; _c = _b.next()) {
1341
- var observer = _c.value;
1342
- observer.next(value);
1343
- }
1344
- } catch (e_1_1) {
1345
- e_1 = { error: e_1_1 };
1346
- } finally {
1347
- try {
1348
- if (_c && !_c.done && (_a = _b.return)) _a.call(_b);
1349
- } finally {
1350
- if (e_1) throw e_1.error;
1351
- }
1352
- }
1353
- }
1354
- });
1355
- };
1356
- Subject2.prototype.error = function(err) {
1357
- var _this = this;
1358
- errorContext(function() {
1359
- _this._throwIfClosed();
1360
- if (!_this.isStopped) {
1361
- _this.hasError = _this.isStopped = true;
1362
- _this.thrownError = err;
1363
- var observers = _this.observers;
1364
- while (observers.length) {
1365
- observers.shift().error(err);
1366
- }
1367
- }
1368
- });
1369
- };
1370
- Subject2.prototype.complete = function() {
1371
- var _this = this;
1372
- errorContext(function() {
1373
- _this._throwIfClosed();
1374
- if (!_this.isStopped) {
1375
- _this.isStopped = true;
1376
- var observers = _this.observers;
1377
- while (observers.length) {
1378
- observers.shift().complete();
1379
- }
1380
- }
1381
- });
1382
- };
1383
- Subject2.prototype.unsubscribe = function() {
1384
- this.isStopped = this.closed = true;
1385
- this.observers = this.currentObservers = null;
1386
- };
1387
- Object.defineProperty(Subject2.prototype, "observed", {
1388
- get: function() {
1389
- var _a;
1390
- return ((_a = this.observers) === null || _a === void 0 ? void 0 : _a.length) > 0;
1391
- },
1392
- enumerable: false,
1393
- configurable: true
1394
- });
1395
- Subject2.prototype._trySubscribe = function(subscriber) {
1396
- this._throwIfClosed();
1397
- return _super.prototype._trySubscribe.call(this, subscriber);
1398
- };
1399
- Subject2.prototype._subscribe = function(subscriber) {
1400
- this._throwIfClosed();
1401
- this._checkFinalizedStatuses(subscriber);
1402
- return this._innerSubscribe(subscriber);
1403
- };
1404
- Subject2.prototype._innerSubscribe = function(subscriber) {
1405
- var _this = this;
1406
- var _a = this, hasError = _a.hasError, isStopped = _a.isStopped, observers = _a.observers;
1407
- if (hasError || isStopped) {
1408
- return EMPTY_SUBSCRIPTION;
1409
- }
1410
- this.currentObservers = null;
1411
- observers.push(subscriber);
1412
- return new Subscription(function() {
1413
- _this.currentObservers = null;
1414
- arrRemove(observers, subscriber);
1415
- });
1416
- };
1417
- Subject2.prototype._checkFinalizedStatuses = function(subscriber) {
1418
- var _a = this, hasError = _a.hasError, thrownError = _a.thrownError, isStopped = _a.isStopped;
1419
- if (hasError) {
1420
- subscriber.error(thrownError);
1421
- } else if (isStopped) {
1422
- subscriber.complete();
1423
- }
1424
- };
1425
- Subject2.prototype.asObservable = function() {
1426
- var observable2 = new Observable();
1427
- observable2.source = this;
1428
- return observable2;
1429
- };
1430
- Subject2.create = function(destination, source) {
1431
- return new AnonymousSubject(destination, source);
1432
- };
1433
- return Subject2;
1434
- }(Observable);
1435
- var AnonymousSubject = function(_super) {
1436
- __extends(AnonymousSubject2, _super);
1437
- function AnonymousSubject2(destination, source) {
1438
- var _this = _super.call(this) || this;
1439
- _this.destination = destination;
1440
- _this.source = source;
1441
- return _this;
1442
- }
1443
- AnonymousSubject2.prototype.next = function(value) {
1444
- var _a, _b;
1445
- (_b = (_a = this.destination) === null || _a === void 0 ? void 0 : _a.next) === null || _b === void 0 ? void 0 : _b.call(_a, value);
1446
- };
1447
- AnonymousSubject2.prototype.error = function(err) {
1448
- var _a, _b;
1449
- (_b = (_a = this.destination) === null || _a === void 0 ? void 0 : _a.error) === null || _b === void 0 ? void 0 : _b.call(_a, err);
1450
- };
1451
- AnonymousSubject2.prototype.complete = function() {
1452
- var _a, _b;
1453
- (_b = (_a = this.destination) === null || _a === void 0 ? void 0 : _a.complete) === null || _b === void 0 ? void 0 : _b.call(_a);
1454
- };
1455
- AnonymousSubject2.prototype._subscribe = function(subscriber) {
1456
- var _a, _b;
1457
- return (_b = (_a = this.source) === null || _a === void 0 ? void 0 : _a.subscribe(subscriber)) !== null && _b !== void 0 ? _b : EMPTY_SUBSCRIPTION;
1458
- };
1459
- return AnonymousSubject2;
1460
- }(Subject);
1461
- var BehaviorSubject = function(_super) {
1462
- __extends(BehaviorSubject2, _super);
1463
- function BehaviorSubject2(_value) {
1464
- var _this = _super.call(this) || this;
1465
- _this._value = _value;
1466
- return _this;
1467
- }
1468
- Object.defineProperty(BehaviorSubject2.prototype, "value", {
1469
- get: function() {
1470
- return this.getValue();
1471
- },
1472
- enumerable: false,
1473
- configurable: true
1474
- });
1475
- BehaviorSubject2.prototype._subscribe = function(subscriber) {
1476
- var subscription = _super.prototype._subscribe.call(this, subscriber);
1477
- !subscription.closed && subscriber.next(this._value);
1478
- return subscription;
1479
- };
1480
- BehaviorSubject2.prototype.getValue = function() {
1481
- var _a = this, hasError = _a.hasError, thrownError = _a.thrownError, _value = _a._value;
1482
- if (hasError) {
1483
- throw thrownError;
1484
- }
1485
- this._throwIfClosed();
1486
- return _value;
1487
- };
1488
- BehaviorSubject2.prototype.next = function(value) {
1489
- _super.prototype.next.call(this, this._value = value);
1490
- };
1491
- return BehaviorSubject2;
1492
- }(Subject);
1493
- function filter(predicate, thisArg) {
1494
- return operate(function(source, subscriber) {
1495
- var index = 0;
1496
- source.subscribe(createOperatorSubscriber(subscriber, function(value) {
1497
- return predicate.call(thisArg, value, index++) && subscriber.next(value);
1498
- }));
1499
- });
1500
- }
1501
- function distinctUntilChanged(comparator, keySelector) {
1502
- if (keySelector === void 0) {
1503
- keySelector = identity;
1504
- }
1505
- comparator = comparator !== null && comparator !== void 0 ? comparator : defaultCompare;
1506
- return operate(function(source, subscriber) {
1507
- var previousKey;
1508
- var first = true;
1509
- source.subscribe(createOperatorSubscriber(subscriber, function(value) {
1510
- var currentKey = keySelector(value);
1511
- if (first || !comparator(previousKey, currentKey)) {
1512
- first = false;
1513
- previousKey = currentKey;
1514
- subscriber.next(value);
1515
- }
1516
- }));
1517
- });
1518
- }
1519
- function defaultCompare(a, b) {
1520
- return a === b;
1521
- }
1522
- const _LoginPrompt = class _LoginPrompt {
1523
- constructor(api, spoke, options = {}) {
1524
- __publicField(this, "alert");
1525
- __publicField(this, "button");
1526
- __publicField(this, "form");
1527
- __publicField(this, "password");
1528
- __publicField(this, "persist");
1529
- __publicField(this, "username");
1530
- __publicField(this, "options");
1531
- __publicField(this, "_done");
1532
- /** Promise which resolves once login is complete */
1533
- __publicField(this, "done", new Promise((res) => {
1534
- this._done = res;
1535
- }));
1536
- this.api = api;
1537
- this.spoke = spoke;
1538
- this.options = {
1539
- title: this.spoke,
1540
- background: "#ffffff",
1541
- color: "#c83232",
1542
- textColor: "#000000",
1543
- ...clean(options, true)
1544
- };
1545
- this.close();
1546
- document.head.innerHTML += _LoginPrompt.css(this.options);
1547
- const div = document.createElement("div");
1548
- div.innerHTML = _LoginPrompt.template(this.options);
1549
- document.body.appendChild(div);
1550
- this.alert = document.querySelector("#datalynk-login-alert");
1551
- this.button = document.querySelector("#datalynk-login-form button");
1552
- this.form = document.querySelector("#datalynk-login-form");
1553
- this.password = document.querySelector('#datalynk-login-form input[name="password"]');
1554
- this.persist = document.querySelector('#datalynk-login-form input[name="persist"]');
1555
- this.username = document.querySelector('#datalynk-login-form input[name="username"]');
1556
- if (options.persist === false) this.persist.parentElement.remove();
1557
- this.form.onsubmit = (event) => this.login(event);
1558
- }
1559
- /** Close the login prompt */
1560
- close() {
1561
- var _a, _b;
1562
- (_a = document.querySelector("#datalynk-login-css")) == null ? void 0 : _a.remove();
1563
- (_b = document.querySelector("#datalynk-login")) == null ? void 0 : _b.remove();
1564
- }
1565
- /** Check if login prompt is still open */
1566
- isOpen() {
1567
- return !!document.querySelector("#datalynk-login");
1568
- }
1569
- /** Login form submit event */
1570
- login(event) {
1571
- event.preventDefault();
1572
- const data = new FormData(event.target);
1573
- this.alert.classList.add("hidden");
1574
- this.username.disabled = true;
1575
- this.password.disabled = true;
1576
- this.persist.disabled = true;
1577
- this.button.disabled = true;
1578
- return this.api.auth.login(
1579
- this.spoke,
1580
- data.get("username"),
1581
- data.get("password"),
1582
- { expire: this.persist.checked ? null : void 0 }
1583
- ).then((data2) => {
1584
- this.close();
1585
- this._done();
1586
- return data2;
1587
- }).catch((err) => {
1588
- this.alert.classList.remove("hidden");
1589
- this.alert.innerHTML = err.message;
1590
- this.password.value = "";
1591
- this.username.disabled = false;
1592
- this.password.disabled = false;
1593
- this.persist.disabled = false;
1594
- this.button.disabled = false;
1595
- });
1596
- }
1597
- };
1598
- /** Dynamically create CSS style */
1599
- __publicField(_LoginPrompt, "css", (options) => `
1600
- <style id="datalynk-login-styles">
1601
- @import url('https://fonts.cdnfonts.com/css/ar-blanca');
1602
-
1603
- #datalynk-login {
1604
- --theme-background: ${options.background};
1605
- --theme-container: #000000cc;
1606
- --theme-glow: ${options.glow || options.color};
1607
- --theme-primary: ${options.color};
1608
- --theme-text: ${options.textColor};;
1609
-
1610
- position: fixed;
1611
- left: 0;
1612
- top: 0;
1613
- right: 0;
1614
- bottom: 0;
1615
- background: var(--theme-background);
1616
- background-repeat: no-repeat;
1617
- background-size: cover;
1618
- font-family: sans-serif;
1619
- z-index: 1000;
1620
- }
1621
-
1622
- #datalynk-login .added-links {
1623
- color: var(--theme-text);
1624
- position: fixed;
1625
- bottom: 0;
1626
- right: 0;
1627
- padding: 0.25rem;
1628
- }
1629
-
1630
- #datalynk-login .added-links a, #datalynk-login .added-links a:hover, #datalynk-login .added-links a:visited {
1631
- color: var(--theme-text);
1632
- text-shadow: 0 0 10px black;
1633
- }
1634
-
1635
- #datalynk-login-alert {
1636
- padding: 0.75rem;
1637
- background: rgba(0,0,0,0.5);
1638
- color: white;
1639
- border-radius: 5px;
1640
- margin-bottom: 1rem;
1641
- border: grey 1px solid;
1642
- }
1643
-
1644
- #datalynk-login label {
1645
- color: white;
1646
- font-size: 20px;
1647
- }
1648
-
1649
- #datalynk-login input {
1650
- width: calc(100% - 20px);
1651
- padding: 12px 9px 9px 9px;
1652
- margin: 1px;
1653
- border: 1px solid #ddd;
1654
- border-radius: 5px;
1655
- background-color: white;
1656
- color: black;
1657
- }
1658
-
1659
- #datalynk-login .login-container {
1660
- position: fixed;
1661
- top: 50%;
1662
- left: 0;
1663
- right: 0;
1664
- transform: translateY(-50%);
1665
- }
1666
-
1667
- #datalynk-login .login-header {
1668
- display: flex;
1669
- justify-content: center;
1670
- align-items: center;
1671
- color: var(--theme-text);
1672
- text-align: center;
1673
- font-size: 32px;
1674
- margin-bottom: 2rem;
1675
- }
1676
-
1677
- #datalynk-login .login-content {
1678
- display: flex;
1679
- flex-direction: column;
1680
- align-items: center;
1681
- background: var(--theme-container);
1682
- border-top: var(--theme-glow) 1px solid;
1683
- box-shadow: 0 -10px 20px -10px var(--theme-glow);
1684
- }
1685
-
1686
- #datalynk-login .login-body {
1687
- padding: ${options.hideApps ? "3.5rem 0" : "3.5rem 0 1.5rem 0"};
1688
- width: 100%;
1689
- max-width: 400px;;
1690
- color: white;
1691
- }
1692
-
1693
- #datalynk-login input:disabled {
1694
- color: #333;
1695
- background-color: #ccc;
1696
- }
1697
-
1698
- #datalynk-login input[type="checkbox"] {
1699
- height: 15px;
1700
- margin: 0;
1701
- padding: 0;
1702
- accent-color: var(--theme-primary);
1703
- }
1704
-
1705
- #datalynk-login button {
1706
- background-color: var(--theme-primary);
1707
- background-image: none;
1708
- border: 0;
1709
- color: ${contrast(options.color)};
1710
- padding: 8px 24px;
1711
- border-radius: 5px;
1712
- }
1713
-
1714
- #datalynk-login button:disabled {
1715
- cursor: pointer;
1716
- filter: brightness(90%);
1717
- }
1718
-
1719
- #datalynk-login button:hover:not(:disabled) {
1720
- cursor: pointer;
1721
- filter: ${contrast(options.color) == "black" ? "brightness(105%)" : "brightness(80%)"};
1722
- }
1723
-
1724
- #datalynk-login .login-links{
1725
- display: flex;
1726
- padding: 0 0 1.5rem 0;
1727
- }
1728
-
1729
- #datalynk-login .login-links a {
1730
- text-decoration: none;
1731
- }
1732
-
1733
- #datalynk-login .login-links img {
1734
- width: 150px;
1735
- height: auto;
1736
- }
1737
-
1738
- #datalynk-login .hidden {
1739
- display: none;
1740
- }
1741
-
1742
- #datalynk-login .login-footer {
1743
- transform: translateY(-18px);
1744
- }
1745
-
1746
- #datalynk-login .sloped-div {
1747
- position: absolute;
1748
- height: 45px;
1749
- width: 200px;
1750
- background: var(--theme-container);
1751
- clip-path: polygon(0 20px, 100% 20px, 85% 60px, 15% 60px);
1752
- }
1753
- </style>`);
1754
- /** Dynamically create HTML */
1755
- __publicField(_LoginPrompt, "template", (options) => `
1756
- <div id="datalynk-login">
1757
- <div class="added-links">
1758
- ${(options.addLinks || []).map((link) => `<a href="${link.url || "#"}" target="_blank">${link.text}</a>`).join(" | ")}
1759
- </div>
1760
- <div class="login-container">
1761
- <div class="login-header">
1762
- ${options.title}
1763
- </div>
1764
- <div class="login-content">
1765
- <div class="login-body" style="max-width: 300px">
1766
- <div id="datalynk-login-alert" class="hidden"></div>
1767
- <form id="datalynk-login-form">
1768
- <div>
1769
- <label for="username">Email or Username</label>
1770
- <input id="username" name="username" type="text" autocomplete="username">
1771
- </div>
1772
- <br>
1773
- <div>
1774
- <label for="password">Password</label>
1775
- <input id="password" name="password" type="password" autocomplete="current-password">
1776
- </div>
1777
- <br>
1778
- <label style="display: block; margin-bottom: 0.75rem;">
1779
- <input type="checkbox" name="persist" style="width: 20px"> Stay Logged In
1780
- </label>
1781
- <button type="submit">Login</button>
1782
- </form>
1783
- </div>
1784
- ${options.hideApps ? "" : `
1785
- <div class="login-links" style="text-align: center">
1786
- <a href="https://itunes.apple.com/ca/app/auxilium-mobile/id1166379280?mt=8" target="_blank">
1787
- <img alt="App Store" src="https://datalynk.auxiliumgroup.com/api/js/auxilium/dijits/templates/login/_common/mobile_apple_transparent.png">
1788
- </a>
1789
- <a href="https://play.google.com/store/apps/details?id=com.auxilium.auxiliummobilesolutions&amp;hl=en" target="_blank">
1790
- <img alt="Playstore" src="https://datalynk.auxiliumgroup.com/api/js/auxilium/dijits/templates/login/_common/mobile_google_transparent.png">
1791
- </a>
1792
- </div>
1793
- `}
1794
- </div>
1795
- <div class="login-footer" style="position: relative; display: flex; align-items: center; justify-content: center;">
1796
- <div class="sloped-div"></div>
1797
- <a href="https://auxiliumgroup.com" target="_blank" style="position: relative; height: 40px; display: flex; align-items: center; text-decoration: none; font-family: 'AR BLANCA', serif; font-size: 26px; color: white;">
1798
- Au<span style="font-size: 52px; color: #c83232; margin-bottom: 5px">x</span>ilium
1799
- <span style="position: absolute; font-size: 10px; color: #c83232; top: 2px; right: 2px">Group</span>
1800
- </a>
1801
- </div>
1802
- </div>
1803
- </div>
1804
- `);
1805
- let LoginPrompt = _LoginPrompt;
1806
- class Auth {
1807
- constructor(api) {
1808
- /** Current user as an observable */
1809
- __publicField(this, "user$", new BehaviorSubject(void 0));
1810
- this.api = api;
1811
- this.api.token$.subscribe(async (token) => {
1812
- if (token === void 0) return;
1813
- this.user = await this.current(token);
1814
- });
1815
- }
1816
- /** Current user */
1817
- get user() {
1818
- return this.user$.getValue();
1819
- }
1820
- /** Set current user info */
1821
- set user(user) {
1822
- this.user$.next(user);
1823
- }
1824
- get spoke() {
1825
- var _a;
1826
- return ((_a = this.api.jwtPayload) == null ? void 0 : _a.realm) || null;
1827
- }
1828
- /**
1829
- * Get current user associated with API token
1830
- *
1831
- * @return {Promise<User | null>}
1832
- */
1833
- async current(token = this.api.token) {
1834
- var _a;
1835
- if (!token) return null;
1836
- else if (token == ((_a = this.user) == null ? void 0 : _a.token)) return this.user;
1837
- return this.api.request({ "$/auth/current": {} }, { token }).then((resp) => (resp == null ? void 0 : resp.login) ? resp : null);
1838
- }
1839
- /**
1840
- * Automatically handle sessions by checking localStorage & URL parameters for a token & prompting
1841
- * user with a login screen if required
1842
- *
1843
- * @param {string} spoke Desired spoke
1844
- * @param {LoginPromptOptions} options Aesthetic options
1845
- * @return {Promise<void>} Login complete
1846
- */
1847
- async handleLogin(spoke, options) {
1848
- var _a;
1849
- const urlToken = new URLSearchParams(location.search).get("datalynkToken");
1850
- if (urlToken) {
1851
- this.api.token = urlToken;
1852
- location.href = location.href.replace(/datalynkToken=.*?(&|$)/gm, "");
1853
- } else if (this.api.token) {
1854
- if (((_a = this.api.jwtPayload) == null ? void 0 : _a.realm) != spoke) {
1855
- this.api.token = null;
1856
- location.reload();
1857
- }
1858
- } else {
1859
- await this.loginPrompt(spoke, options).done;
1860
- location.reload();
1861
- }
1862
- }
1863
- /**
1864
- * Check whether user has a token
1865
- *
1866
- * @return {boolean} True if session token authenticated
1867
- */
1868
- isAuthenticated() {
1869
- return !!this.user && !this.user.guest;
1870
- }
1871
- /**
1872
- * Check if the current user is a guest
1873
- *
1874
- * @return {boolean} True if guest
1875
- */
1876
- isGuest() {
1877
- var _a;
1878
- return !!((_a = this.user) == null ? void 0 : _a.guest);
1879
- }
1880
- /**
1881
- * Check if user is a system administrator
1882
- *
1883
- * @return {Promise<boolean>} True if system administrator
1884
- */
1885
- async isSysAdmin() {
1886
- return !!(await this.api.slice("sysadmin").select().where("auth_ref", "==", "$viewer").rows().exec()).length;
1887
- }
1888
- /**
1889
- * Check if user is a table administrator
1890
- *
1891
- * @return {Promise<boolean>} True if table administrator
1892
- */
1893
- async isTableAdmin() {
1894
- return !!(await this.api.slice("tableadmins").select().where("auth_ref", "==", "$viewer").rows().exec()).length;
1895
- }
1896
- /**
1897
- * Check if user is a user administrator
1898
- *
1899
- * @return {Promise<boolean>} True if user administrator
1900
- */
1901
- async isUserAdmin() {
1902
- return !!(await this.api.slice("useradmins").select().where("auth_ref", "==", "$viewer").rows().exec()).length;
1903
- }
1904
- /**
1905
- * Perform login and save the session token
1906
- *
1907
- * @param {string} login Login username or email
1908
- * @param {string} password Password for account
1909
- * @param {string} spoke Override login spoke
1910
- * @param {twoFactor?: string, expire?: string} opts 2FA code & expire date (YYYY-MM-DD)
1911
- * @returns {Promise<User>} User account
1912
- */
1913
- login(spoke, login, password, opts) {
1914
- const date = /* @__PURE__ */ new Date();
1915
- date.setFullYear(date.getFullYear() + 1);
1916
- return fetch(`${this.api.url}login`, {
1917
- method: "POST",
1918
- headers: { "Content-Type": "application/json" },
1919
- body: JSON.stringify(clean({
1920
- realm: spoke.trim(),
1921
- login: login.trim(),
1922
- password: password.trim(),
1923
- secret: opts == null ? void 0 : opts.twoFactor,
1924
- expireAt: (opts == null ? void 0 : opts.expire) == null ? formatDate("YYYY-MM-DD", date) : opts == null ? void 0 : opts.expire,
1925
- dateFormat: "ISO8601"
1926
- }))
1927
- }).then(async (resp) => {
1928
- const data = await resp.json().catch(() => ({}));
1929
- if (!resp.ok || data["error"]) throw Object.assign(errorFromCode(resp.status, data.error) || {}, data);
1930
- this.api.token = data["token"];
1931
- return data;
1932
- });
1933
- }
1934
- /**
1935
- * Login as guest user
1936
- *
1937
- * @return {Promise<User>} Guest account
1938
- */
1939
- loginGuest() {
1940
- return fetch(`${this.api.url}guest`).then(async (resp) => {
1941
- const data = await resp.json().catch(() => ({}));
1942
- if (!resp.ok || data["error"]) throw Object.assign(errorFromCode(resp.status, data.error) || {}, data);
1943
- this.api.token = data["token"];
1944
- return data;
1945
- });
1946
- }
1947
- /**
1948
- * Create Login UI
1949
- *
1950
- * @param {string} spoke Desired spoke
1951
- * @param {LoginPromptOptions} options Aesthetic options
1952
- * @return {LoginPrompt} Login prompt
1953
- */
1954
- loginPrompt(spoke, options) {
1955
- return new LoginPrompt(this.api, spoke, options);
1956
- }
1957
- /**
1958
- * Logout current user
1959
- *
1960
- * @return {Promise<{closed: string, new: string}>}
1961
- */
1962
- logout() {
1963
- return this.api.request({ "$/auth/logout": {} }).then((resp) => {
1964
- this.api.token = null;
1965
- return resp;
1966
- });
1967
- }
1968
- /**
1969
- * Reset user account password
1970
- *
1971
- * @param {string} login User login
1972
- * @param {string} newPassword New password
1973
- * @param {string} code Reset code sent with `resetRequest`
1974
- * @return {Promise<any>} New session
1975
- */
1976
- reset(login, newPassword, code) {
1977
- return this.api.request({ "$/auth/mobile/rescue": {
1978
- user: login,
1979
- password: newPassword,
1980
- pin: code
1981
- } }).then((resp) => {
1982
- if (resp.token) this.api.token = resp.token;
1983
- return resp;
1984
- });
1985
- }
1986
- /**
1987
- * Request reset code for user
1988
- *
1989
- * @param {string} login User to reset
1990
- * @param {"email" | "sms" | "voice"} mode Method of sending reset code
1991
- * @return {Promise<any>} Unknown
1992
- */
1993
- resetRequest(login, mode) {
1994
- if (mode == "email") return this.api.request({ "$/auth/rescue_email": { user: { $or: { login, email: login } } } });
1995
- return this.api.request({ "$/auth/mobile/generate": { user: login, method: mode } });
1996
- }
1997
- }
1998
- class Files {
1999
- constructor(api) {
2000
- this.api = api;
2001
- }
2002
- associate(fileIds, slice, row, field, execute = true) {
2003
- const req = { [`${execute ? "!" : "$"}/tools/file/update`]: { slice, row, field, ids: fileIds } };
2004
- if (execute) return this.api.request(req);
2005
- return req;
2006
- }
2007
- /**
2008
- * Get an authenticated URL to fetch files from
2009
- *
2010
- * @param {number} id File ID
2011
- * @param {boolean} ignoreToken Ignore authentication
2012
- * @return {string} URL file can be viewed at
2013
- */
2014
- get(id, ignoreToken) {
2015
- return `${this.api.url}file?id=${id}${ignoreToken ? "" : `&token=${this.api.token}`}`;
2016
- }
2017
- /**
2018
- * Upload file(s) to the API & optionally associate them with a row
2019
- *
2020
- * @param {FileList | File | File[]} files Files to be uploaded
2021
- * @param {{slice: number, row: any, field: string, pk?: string}} associate Row to associate with
2022
- */
2023
- upload(files, associate) {
2024
- let f = files instanceof FileList ? Array.from(files) : makeArray(files);
2025
- return Promise.all(f.map((file) => {
2026
- const data = new FormData();
2027
- data.append("uploadedfiles[]", file, file.name);
2028
- return fetch(`${this.api.url}upload.php`, {
2029
- method: "POST",
2030
- headers: clean({ "Authorization": this.api.token ? `Bearer ${this.api.token}` : "" }),
2031
- body: data
2032
- }).then(async (resp) => {
2033
- const data2 = await resp.json().catch(() => ({}));
2034
- if (!resp.ok || data2["error"]) throw Object.assign(errorFromCode(resp.status, data2.error) || {}, data2);
2035
- return data2.files.uploadedfiles[0];
2036
- });
2037
- })).then(async (files2) => {
2038
- if (associate) {
2039
- let id = typeof associate.row == "number" ? associate.row : associate.row[associate.pk || "id"];
2040
- if (!id) id = await this.api.slice(associate.slice).insert(associate.row).id();
2041
- 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);
2042
- }
2043
- return files2;
2044
- });
2045
- }
2046
- }
2047
- class Pdf {
2048
- constructor(api) {
2049
- this.api = api;
2050
- }
2051
- /**
2052
- * Create a PDF from a public URL
2053
- * @param {string} url Target URL address
2054
- * @param {{slice: number, row: number, field: string} | null} associate Optionally associate PDF with a slice row
2055
- * @param {PdfOptions} options PDF options for rendering & uploading
2056
- * @return {Promise<any>} Either the PDF file number or the updated slice row response if associated
2057
- */
2058
- async fromUrl(url, associate, options = {}) {
2059
- return this.api.request({ "$/slice/utils/urlToPdf": { url, ...options } }).then((file) => {
2060
- if (associate) return this.api.files.associate(file, associate.slice, associate.row, associate.field);
2061
- return file;
2062
- });
2063
- }
2064
- }
2065
- const Serializer = {
2066
- /**
2067
- * From Datalynk syntax to JS
2068
- */
2069
- deserialize: {
2070
- /**
2071
- * Convert date time string to javascript date object
2072
- *
2073
- * @param {string} datetime datetime string (YYYY/MM/DD hh:mm:ss)
2074
- * @returns {Date} JS Date object
2075
- */
2076
- "$/tools/date": (datetime) => {
2077
- let a = datetime.split(/[^0-9]+/).map((part) => Number(part));
2078
- return new Date(a[0], a[1] - 1, a[2], a[3], a[4], a[5]);
2079
- },
2080
- /**
2081
- * Convert date string to javascript date object
2082
- *
2083
- * @param {string} date date string (YYYY/MM/DD)
2084
- * @returns {Date} JS Date object
2085
- */
2086
- "$/tools/date_strict": (date) => {
2087
- let a = date.split(/[^0-9]+/).map((part) => Number(part));
2088
- let d = new Date(a[0], a[1] - 1, a[2], 0, 0, 0);
2089
- d["hint"] = "date";
2090
- return d;
2091
- },
2092
- /**
2093
- * Convert time string to javascript date object
2094
- *
2095
- * @param {string} time time string (YYYY/MM/DD)
2096
- * @returns {Date} JS Date object
2097
- */
2098
- "$/tools/time_strict": (time) => {
2099
- let a = time.split(/[^0-9]+/).map((part) => Number(part));
2100
- let d = /* @__PURE__ */ new Date();
2101
- d.setHours(a[0]);
2102
- d.setMinutes(a[1]);
2103
- d.setSeconds(a[2]);
2104
- d["hint"] = "time";
2105
- return d;
2106
- },
2107
- /**
2108
- * Convert string to constant
2109
- *
2110
- * @param {string} constant string to be converted
2111
- * @returns {any} the actual constant
2112
- */
2113
- "$/tools/const": (constant) => {
2114
- let types = {
2115
- "infinity": Infinity,
2116
- "-infinity": -Infinity,
2117
- "nan": NaN
2118
- };
2119
- try {
2120
- return types[constant["$/tools/const"].toLowerCase()];
2121
- } catch (ignored) {
2122
- return void 0;
2123
- }
2124
- },
2125
- /**
2126
- * Large requests are formatted into parallel arrays
2127
- *
2128
- * @param {object} obj Object of metadata and data
2129
- * @returns {Array} Actual object reconstructed
2130
- */
2131
- "$/tools/dltable": function(obj) {
2132
- let meta = obj["meta"];
2133
- let col;
2134
- let fn = [];
2135
- for (let i in meta) {
2136
- col = meta[i];
2137
- fn.push("this['" + col.name + "'] = ");
2138
- if (col.cast == null) {
2139
- fn.push("a[" + i + "];\n");
2140
- } else if (col.cast === "num") {
2141
- fn.push("a[" + i + "] && parseFloat(a[" + i + "]);\n");
2142
- } else {
2143
- if (col["native"] === "date") {
2144
- fn.push("a[" + i + "] && dateParse(a[" + i + "]);\n");
2145
- fn.push("a[" + i + "] && (this['" + col.name + "'].hint = 'date');\n");
2146
- } else if (col["native"] === "time") {
2147
- fn.push("a[" + i + "] && timeParse(a[" + i + "]);\n");
2148
- fn.push("a[" + i + "] && (this['" + col.name + "'].hint = 'time');\n");
2149
- } else {
2150
- fn.push("a[" + i + "] && datetimeParse(a[" + i + "]);\n");
2151
- }
2152
- }
2153
- }
2154
- let dateTimeParse, dateParse, timeParse;
2155
- let now = /* @__PURE__ */ new Date();
2156
- let yyyy = now.getFullYear();
2157
- let mm = now.getMonth();
2158
- let dd = now.getDate();
2159
- dateTimeParse = function(dt) {
2160
- dt = dt.split(/[^0-9]+/);
2161
- return new Date(dt[0], dt[1] - 1, dt[2], dt[3], dt[4], dt[5]);
2162
- };
2163
- dateParse = function(d) {
2164
- d = d.split(/[- :]/);
2165
- let res2 = new Date(d[0], d[1] - 1, d[2], 0, 0, 0);
2166
- res2["hint"] = "date";
2167
- return res2;
2168
- };
2169
- timeParse = function(t) {
2170
- t = t.split(/[^0-9]+/, t);
2171
- let res2 = new Date(yyyy, mm, dd, t[0], t[1], t[2]);
2172
- res2["hint"] = "time";
2173
- return res2;
2174
- };
2175
- let ctor = Function("datetimeParse", "dateParse", "timeParse", "a", fn.join(""));
2176
- let res = [];
2177
- let rows = obj["rows"];
2178
- for (let i in rows) {
2179
- res[i] = new ctor(dateTimeParse, dateParse, timeParse, rows[i]);
2180
- }
2181
- res["meta"] = meta;
2182
- res["rowConstructor"] = ctor;
2183
- return res;
2184
- }
2185
- },
2186
- /**
2187
- * From JS to Datalynk syntax
2188
- */
2189
- serialize: {
2190
- /**
2191
- * Convert JS date to datalynk datetime string
2192
- */
2193
- "Date": (date) => {
2194
- return {
2195
- "$/tools/date": [date.getFullYear(), date.getMonth() + 1, date.getDate()].join("/") + " " + [date.getHours(), date.getMinutes(), date.getSeconds()].join(":")
2196
- };
2197
- }
2198
- }
2199
- };
2200
- const _Slice = class _Slice {
2201
- /**
2202
- * An object to aid in constructing requests
2203
- *
2204
- * @param {number} slice Slice ID to interact with
2205
- * @param {Api} api Api to send the requests through
2206
- */
2207
- constructor(slice, api) {
2208
- __publicField(this, "operation");
2209
- __publicField(this, "popField");
2210
- __publicField(this, "request", {});
2211
- /** Log response automatically */
2212
- __publicField(this, "debugging");
2213
- /** Unsubscribe from changes, undefined if not subscribed */
2214
- __publicField(this, "unsubscribe");
2215
- /** Cached slice data as an observable */
2216
- __publicField(this, "cache$", new BehaviorSubject([]));
2217
- /**
2218
- * Whitelist and alias fields. Alias of `fields()`
2219
- * @example
2220
- * ```ts
2221
- * const id: {id: number, field2: any}[] = await new Slice<T>(12345)
2222
- * .select().alias({id: 'id', field1: 'field2'}).exec().keys();
2223
- * ```
2224
- * @param {object} aliasKeyVals List of properties to whitelist and what to rename them to
2225
- * @return {Slice<T>}
2226
- */
2227
- __publicField(this, "alias", this.fields);
2228
- this.slice = slice;
2229
- this.api = api;
2230
- }
2231
- /** Cached slice data */
2232
- get cache() {
2233
- return this.cache$.getValue();
2234
- }
2235
- /** Set cached data & alert subscribers */
2236
- set cache(cache) {
2237
- this.cache$.next(cache);
2238
- }
2239
- /** Get raw API request */
2240
- get raw() {
2241
- return clean({
2242
- [this.operation]: {
2243
- ...this.request,
2244
- slice: this.slice
2245
- },
2246
- "$pop": this.popField ? this.popField : void 0
2247
- });
2248
- }
2249
- /**
2250
- * Add an 'AND' condition inside the where argument
2251
- * @example
2252
- * ```ts
2253
- * const rows: T[] = await new Slice<T>(12345).select()
2254
- * .where('field1', '>', 1)
2255
- * .and()
2256
- * .where({field2: 2, field3: 3})
2257
- * .exec().rows();
2258
- * ```
2259
- * @return {Slice<T>}
2260
- */
2261
- and() {
2262
- var _a;
2263
- if (((_a = this.request.where) == null ? void 0 : _a[0]) == "$and") return this;
2264
- if (this.request.where) this.request.where = ["$and", this.request.where];
2265
- else this.request.where = ["$and"];
2266
- return this;
2267
- }
2268
- /**
2269
- * Count the returned rows
2270
- * @example
2271
- * ```ts
2272
- * const count = await new Slice(12345).count()
2273
- * .where({field1: 1})
2274
- * .exec().count();
2275
- * ```
2276
- * @param {object | string} arg Count argument
2277
- * @return {Slice<T>}
2278
- */
2279
- count(arg = "id") {
2280
- this.operation = "$/slice/report";
2281
- this.request.fields = { count: ["$count", typeof arg == "object" ? arg : ["$field", arg]] };
2282
- return this.pop("rows:0:count");
2283
- }
2284
- /**
2285
- * Output the formed request to the console for inspection
2286
- * @param {boolean} enabled Enable/Disable console logging
2287
- * @return {Slice<T>}
2288
- */
2289
- debug(enabled = true) {
2290
- this.debugging = enabled;
2291
- return this;
2292
- }
2293
- /**
2294
- * Set the request type to delete
2295
- * @example
2296
- * ```ts
2297
- * await new Slice(12345).delete(id).exec();
2298
- * ```
2299
- * @param {number | number[]} id ID(s) to delete
2300
- * @return {Slice<T>}
2301
- */
2302
- delete(id) {
2303
- this.operation = "$/slice/delete";
2304
- if (id) {
2305
- if (Array.isArray(id)) this.where("id", "$in", id);
2306
- else this.where("id", "==", id);
2307
- }
2308
- return this;
2309
- }
2310
- /**
2311
- * Filter rows from slice based on an excel expression
2312
- * @example
2313
- * ```ts
2314
- * const rows: T[] = await new Slice<T>(12345).select()
2315
- * .excel('contains({property}, foobar)')
2316
- * .exec().rows();
2317
- * ```
2318
- * @param formula Excel formula to use as where clause
2319
- * @return {Slice<T>}
2320
- */
2321
- excel(formula) {
2322
- this.where(["$excel", formula]);
2323
- return this;
2324
- }
2325
- /**
2326
- * Compile the request and send it
2327
- * @param {ApiRequestOptions} options API Request options
2328
- * @return {Promise<T = any>} API response
2329
- */
2330
- exec(options) {
2331
- if (!this.operation) throw new Error("No operation chosen");
2332
- return this.api.request(this.raw, options).then((resp) => {
2333
- if (this.debugging) console.log(resp);
2334
- return resp;
2335
- });
2336
- }
2337
- fields(keys) {
2338
- this.request.fields = Array.isArray(keys) ? keys.reduce((acc, key) => ({ ...acc, [key]: key }), {}) : keys;
2339
- return this;
2340
- }
2341
- /**
2342
- * Unwrap response returning the first ID
2343
- * @return {Slice<T>}
2344
- */
2345
- id() {
2346
- return this.pop("rows:0:id");
2347
- }
2348
- /**
2349
- * Set the request type to insert
2350
- * @example
2351
- * ```ts
2352
- * const id: number = await new Slice<T>(12345).insert([
2353
- * {field1: 1},
2354
- * {field1: 2}
2355
- * ]).exec().keys();
2356
- * ```
2357
- * @param {T | T[]} rows Rows to be inserted into the slice
2358
- * @return {Slice<T>}
2359
- */
2360
- insert(rows) {
2361
- this.operation = "$/slice/xinsert";
2362
- if (!this.request.rows) this.request.rows = [];
2363
- if (Array.isArray(rows)) this.request.rows = this.request.rows.concat(rows);
2364
- else this.request.rows.push(rows);
2365
- return this;
2366
- }
2367
- /**
2368
- * Limit number of rows returned
2369
- * @example
2370
- * ```ts
2371
- * const rows: T[] = await new Slice<T>(12345).select().limit(10)
2372
- * .exec().rows();
2373
- * ```
2374
- * @param {number} num Number of rows to return
2375
- * @return {Slice<T>}
2376
- */
2377
- limit(num) {
2378
- this.request.limit = num;
2379
- return this;
2380
- }
2381
- /**
2382
- * Add an 'OR' condition inside the where argument
2383
- * @example
2384
- * ```ts
2385
- * const rows: T[] = await new Slice<T>(12345).select()
2386
- * .where('field1', '>', 1)
2387
- * .or()
2388
- * .where({field2: 2, field3: 3})
2389
- * .or()
2390
- * .where(['$gt', ['$field', field4], 4)
2391
- * .exec().rows();
2392
- * ```
2393
- * @return {Slice<T>}
2394
- */
2395
- or() {
2396
- var _a;
2397
- if (((_a = this.request.where) == null ? void 0 : _a[0]) == "$or") {
2398
- this.request.where.push(null);
2399
- return this;
2400
- }
2401
- if (this.request.where) this.request.where = ["$or", this.request.where, null];
2402
- else this.request.where = ["$or", null];
2403
- return this;
2404
- }
2405
- /**
2406
- * Order rows by a field
2407
- * @example
2408
- * ```ts
2409
- * const rows: T[] = new Slice<T>(12345).select().order('field1', true) // true = ascending
2410
- * .exec().rows();
2411
- * ```
2412
- * @param {string} field property name
2413
- * @param {boolean} ascending Sort in ascending or descending order
2414
- * @return {Slice<T>}
2415
- */
2416
- order(field, ascending = true) {
2417
- if (!this.request.order) this.request.order = [];
2418
- this.request.order.push([ascending ? "$asc" : "$desc", ["$field", field]]);
2419
- return this;
2420
- }
2421
- /**
2422
- * Unwrap response, returning the field
2423
- * @param {string} field Colon seperated path: `rows:0`
2424
- * @return {Slice<T>}
2425
- */
2426
- pop(field) {
2427
- this.popField = field;
2428
- return this;
2429
- }
2430
- /**
2431
- * Unwrap response returning the first row
2432
- * @return {Slice<T>}
2433
- */
2434
- row() {
2435
- return this.pop("rows:0");
2436
- }
2437
- /**
2438
- * Unwrap response returning the rows
2439
- * @return {Slice<T>}
2440
- */
2441
- rows() {
2442
- return this.pop("rows");
2443
- }
2444
- /**
2445
- * Save multiple rows to the slice, automatically inserts/updates
2446
- * @param {T} rows Rows to add to slice
2447
- * @returns {this<T>}
2448
- */
2449
- save(...rows) {
2450
- this.operation = "$/slice/multisave";
2451
- this.request.rows = rows;
2452
- return this;
2453
- }
2454
- /**
2455
- * Set the request type to select
2456
- * @example
2457
- * ```ts
2458
- * const rows: T[] = new Slice<T>(12345).select().exec().rows();
2459
- * const row: T = new Slice<T>(12345).select(id).exec().row();
2460
- * ```
2461
- * @param {number | number[]} id ID(s) to select, leaving blank will return all rows
2462
- * @return {Slice<T>}
2463
- */
2464
- select(id) {
2465
- this.operation = "$/slice/report";
2466
- if (id) {
2467
- if (Array.isArray(id)) this.where("id", "$in", id);
2468
- else this.where("id", "==", id);
2469
- }
2470
- return this;
2471
- }
2472
- /**
2473
- * Synchronize cache with server
2474
- * @example
2475
- * ```ts
2476
- * const slice: Slice = new Slice<T>(Slices.Contact);
2477
- * slice.sync().subscribe((rows: T[]) => {});
2478
- * ```
2479
- * @param {boolean} on Enable/disable events
2480
- * @return {BehaviorSubject<T[]>} Cache which can be subscribed to
2481
- */
2482
- sync(on = true) {
2483
- if (on) {
2484
- new _Slice(this.slice, this.api).select().rows().exec().then((rows) => this.cache = rows);
2485
- if (!this.unsubscribe) this.unsubscribe = this.api.socket.sliceEvents(this.slice, (event) => {
2486
- const ids = [...event.data.new, ...event.data.changed];
2487
- 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]);
2488
- this.cache = this.cache.filter((v) => v.id && !event.data.lost.includes(v.id));
2489
- });
2490
- return this.cache$;
2491
- } else if (this.unsubscribe) {
2492
- this.unsubscribe();
2493
- this.unsubscribe = null;
2494
- }
2495
- }
2496
- /**
2497
- * Set the request type to update
2498
- * @example
2499
- * ```ts
2500
- * const ids: number[] = await new Slice<Type>(12345).update([
2501
- * {id: 1, field1: 1},
2502
- * {id: 2, field1: 1}
2503
- * ]).exec().keys();
2504
- * ```
2505
- * @param {T | T[]} rows Rows to be updated, each row must have an ID
2506
- * @return {Slice<T>}
2507
- */
2508
- update(rows) {
2509
- this.operation = "$/slice/xupdate";
2510
- if (!this.request.rows) this.request.rows = [];
2511
- if (Array.isArray(rows)) this.request.rows = this.request.rows.concat(rows);
2512
- else this.request.rows.push(rows);
2513
- return this;
2514
- }
2515
- /**
2516
- * Add where condition to request
2517
- * @example
2518
- * ```ts
2519
- * const rows: T[] = await new Slice<T>(12345).select()
2520
- * .where('field1', '>', 1)
2521
- * .where({field2: 2, field3: 3}) // Automatic AND
2522
- * .or()
2523
- * .where(['$gt', ['$field', field4], 4)
2524
- * .exec().rows();
2525
- * ```
2526
- * @param {string | object} field property to compare or a map of equality comparisons
2527
- * @param {string} operator Operation to compare with. Accepts JS operators (>=, ==, !=, ...) as well as datalynk styax ($gte, $eq, $is, $not, ...)
2528
- * @param {any} value value to compare against
2529
- * @return {Slice<T>}
2530
- */
2531
- where(field, operator, value) {
2532
- if (this.request.where && this.request.where[0] != "$or") this.and();
2533
- const raw = Array.isArray(field);
2534
- if (typeof field == "object" && !raw) {
2535
- Object.entries(field).forEach(([key, value2]) => this.where(key, "==", value2));
2536
- } else {
2537
- const w = raw ? field : [(() => {
2538
- if (operator == "==") return "$eq";
2539
- if (operator == "!=") return "$neq";
2540
- if (operator == ">") return "$gt";
2541
- if (operator == ">=") return "$gte";
2542
- if (operator == "<") return "$lt";
2543
- if (operator == "<=") return "$lte";
2544
- if (operator == "!") return "$not";
2545
- if (operator == "%") return "$mod";
2546
- if (operator == null ? void 0 : operator.startsWith("$")) return operator;
2547
- throw new Error(`Unknown operator: ${operator}`);
2548
- })(), ["$field", field], value];
2549
- if (!this.request.where) this.request.where = w;
2550
- else {
2551
- if (this.request.where[0] == "$or") {
2552
- const i = this.request.where.length - 1;
2553
- if (this.request.where[i] == null) this.request.where[i] = w;
2554
- else {
2555
- if (this.request.where[i][0] == "$and") this.request.where[i].push(w);
2556
- else this.request.where[i] = ["$and", this.request.where[i], w];
2557
- }
2558
- } else this.request.where.push(w);
2559
- }
2560
- }
2561
- return this;
2562
- }
2563
- };
2564
- __publicField(_Slice, "api");
2565
- let Slice = _Slice;
2566
- class Socket {
2567
- constructor(api, options = {}) {
2568
- __publicField(this, "listeners", []);
2569
- // [ Callback, Re-subscribe ]
2570
- __publicField(this, "retry");
2571
- __publicField(this, "socket");
2572
- __publicField(this, "open", false);
2573
- this.api = api;
2574
- this.options = options;
2575
- if (!options.url && options.url !== false) {
2576
- const url = new URL(this.api.url.replace("http", "ws"));
2577
- url.port = "9390";
2578
- this.options.url = url.origin;
2579
- }
2580
- if (this.options.url !== false)
2581
- api.token$.pipe(filter((u) => u !== void 0), distinctUntilChanged()).subscribe(() => this.connect());
2582
- }
2583
- /**
2584
- * Add listener for all socket events
2585
- *
2586
- * @param {SocketListener} fn Callback function
2587
- * @return {Unsubscribe} Function to unsubscribe callback
2588
- */
2589
- addListener(fn, reconnect) {
2590
- this.listeners.push([fn, reconnect]);
2591
- return () => this.listeners = this.listeners.filter((l) => l[0] != fn);
2592
- }
2593
- /**
2594
- * Close socket connection
2595
- */
2596
- close() {
2597
- var _a;
2598
- if (this.open) console.debug("Datalynk socket: disconnected");
2599
- this.open = false;
2600
- (_a = this.socket) == null ? void 0 : _a.close();
2601
- this.socket = void 0;
2602
- if (this.retry) clearTimeout(this.retry);
2603
- this.retry = null;
2604
- }
2605
- /**
2606
- * Connect socket client to socket server
2607
- * @param {number} timeout Retry to connect every x seconds
2608
- */
2609
- connect(timeout = 30) {
2610
- if (this.options.url === false) return console.warn("Datalynk socket disabled");
2611
- if (this.open) this.close();
2612
- this.retry = setTimeout(() => {
2613
- if (this.open) return;
2614
- this.close();
2615
- this.connect();
2616
- }, timeout * 1e3);
2617
- if (navigator.onLine) {
2618
- this.socket = new WebSocket(this.options.url + (this.api.token ? `?token=${this.api.token}` : ""));
2619
- this.socket.onopen = () => clearTimeout(this.retry);
2620
- this.socket.onclose = () => {
2621
- if (this.open) this.connect(timeout);
2622
- };
2623
- this.socket.onmessage = (message) => {
2624
- const payload = JSON.parse(message.data);
2625
- if (payload.connected != void 0) {
2626
- if (payload.connected) {
2627
- this.open = true;
2628
- console.debug("Datalynk socket: connected");
2629
- this.listeners.forEach((l) => l[1]());
2630
- } else {
2631
- throw new Error(`Datalynk socket failed: ${payload.error}`);
2632
- }
2633
- } else {
2634
- this.listeners.forEach((l) => l[0](payload));
2635
- }
2636
- };
2637
- }
2638
- }
2639
- /**
2640
- * Send data to socket server
2641
- *
2642
- * @param payload Data that will be serialized
2643
- */
2644
- send(payload) {
2645
- var _a;
2646
- if (!this.open) throw new Error("Datalynk socket not connected");
2647
- (_a = this.socket) == null ? void 0 : _a.send(JSON.stringify(payload));
2648
- }
2649
- /**
2650
- * Run callback whenever the server notifies us of slice changes
2651
- *
2652
- * @param {number | number[]} slice Slice to subscribe to
2653
- * @param {SocketListener<SocketEventSlice>} callback Function to run on changes
2654
- * @return {Unsubscribe} Run returned function to unsubscribe callback
2655
- */
2656
- sliceEvents(slice, callback) {
2657
- const listen = () => this.send({ onSliceEvents: slice });
2658
- if (this.open) listen();
2659
- const unsubscribe = this.addListener((event) => {
2660
- if (event.type == "sliceEvents" && event.data.slice == slice) callback(event);
2661
- }, () => listen());
2662
- return () => {
2663
- this.send({ offSliceEvents: slice });
2664
- unsubscribe();
2665
- };
2666
- }
2667
- }
2668
- class Superuser {
2669
- constructor(api) {
2670
- this.api = api;
2671
- }
2672
- /**
2673
- * Switch to another user by ID
2674
- *
2675
- * @param {number} userId User ID
2676
- * @return {Promise<any>} New session
2677
- */
2678
- assume(userId) {
2679
- return this.api.request({ "$/report/users/become": { id: userId } }).then((resp) => {
2680
- if (resp.token) this.api.token = resp.token;
2681
- return resp;
2682
- });
2683
- }
2684
- /**
2685
- * Enable the superuser flag, required to make any of the requests in this helper
2686
- *
2687
- * @param {string} username Superuser account
2688
- * @param {string} password Superuser password
2689
- * @return {Promise<any>} Unknown
2690
- */
2691
- enable(username, password) {
2692
- return this.api.request({ "$/superuser/validate": {
2693
- name: username,
2694
- password
2695
- } });
2696
- }
2697
- }
2698
- const version = "1.0.20";
2699
- class Api {
2700
- /**
2701
- * Connect to Datalynk & send requests
2702
- *
2703
- * @example
2704
- * ```ts
2705
- * const api = new Api('https://spoke.auxiliumgroup.com');
2706
- * ```
2707
- *
2708
- * @param {string} url API URL
2709
- * @param {ApiOptions} options
2710
- */
2711
- constructor(url, options = {}) {
2712
- /** Current requests bundle */
2713
- __publicField(this, "bundle", []);
2714
- /** Bundle lifecycle tracking */
2715
- __publicField(this, "bundleOngoing", false);
2716
- /** LocalStorage key for persisting logins */
2717
- __publicField(this, "localStorageKey", "datalynk-token");
2718
- /** Pending requests cache */
2719
- __publicField(this, "pending", {});
2720
- /** API URL */
2721
- __publicField(this, "url");
2722
- /** Package version */
2723
- __publicField(this, "version", version);
2724
- /** API Session token */
2725
- __publicField(this, "token$", new BehaviorSubject(void 0));
2726
- /** Helpers */
2727
- /** Authentication */
2728
- __publicField(this, "auth");
2729
- /** File */
2730
- __publicField(this, "files");
2731
- /** PDF */
2732
- __publicField(this, "pdf");
2733
- /** Socket */
2734
- __publicField(this, "socket");
2735
- /** Superuser */
2736
- __publicField(this, "superuser");
2737
- this.options = options;
2738
- this.url = `${new URL(url).origin}/api/`;
2739
- this.options = {
2740
- bundleTime: 100,
2741
- origin: typeof location !== "undefined" ? location.host : "Unknown",
2742
- saveSession: true,
2743
- ...options
2744
- };
2745
- if (this.options.saveSession) {
2746
- if (localStorage == void 0) return;
2747
- this.token = localStorage.getItem(this.localStorageKey) || null;
2748
- this.token$.pipe(distinctUntilChanged()).subscribe((token) => {
2749
- if (token) localStorage.setItem(this.localStorageKey, token);
2750
- else localStorage.removeItem(this.localStorageKey);
2751
- });
2752
- }
2753
- Slice.api = this;
2754
- this.auth = new Auth(this);
2755
- this.files = new Files(this);
2756
- this.pdf = new Pdf(this);
2757
- this.superuser = new Superuser(this);
2758
- this.socket = new Socket(this, { url: options.socket });
2759
- }
2760
- get token() {
2761
- return this.token$.getValue();
2762
- }
2763
- set token(token) {
2764
- this.token$.next(token);
2765
- }
2766
- /** Get session info from JWT payload */
2767
- get jwtPayload() {
2768
- if (!this.token) return null;
2769
- return decodeJwt(this.token);
2770
- }
2771
- _request(req, options = {}) {
2772
- const token = options.token || this.token;
2773
- return fetch(this.url, {
2774
- method: "POST",
2775
- headers: clean({
2776
- Authorization: token ? `Bearer ${token}` : void 0,
2777
- "Content-Type": "application/json",
2778
- "X-Date-Return-Format": this.options.legacyDates ? void 0 : "ISO8601"
2779
- }),
2780
- body: JSON.stringify(Api.translateTokens(req))
2781
- }).then(async (resp) => {
2782
- let data = JSONAttemptParse(await resp.text());
2783
- if (!resp.ok || (data == null ? void 0 : data.error)) throw Object.assign(errorFromCode(resp.status, data.error), data);
2784
- if (!options.raw) data = Api.translateTokens(data);
2785
- return data;
2786
- });
2787
- }
2788
- /**
2789
- * Parses API request/response object for special Datalynk tokens & converts them to native JS objects
2790
- *
2791
- * @param obj An API request or response
2792
- * @return {Object} Api request or response with translated tokens
2793
- * @private
2794
- */
2795
- static translateTokens(obj) {
2796
- let dot = (obj2, param) => param.split(".").reduce((acc, index) => acc[index], obj2);
2797
- let queue = Object.keys(obj);
2798
- queue.forEach((key) => {
2799
- let val = dot(obj, key);
2800
- if (val !== null && typeof val == "object") {
2801
- Object.keys(val).forEach((index) => {
2802
- if (index in Serializer.deserialize) {
2803
- val = Serializer.deserialize[index](val[index]);
2804
- } else if (index in Serializer.serialize) {
2805
- val = Serializer.serialize[index](val[index]);
2806
- } else {
2807
- queue.push(`${key}.${index}`);
2808
- }
2809
- });
2810
- }
2811
- });
2812
- return obj;
2813
- }
2814
- /**
2815
- * Chain multiple requests to execute together
2816
- * @param {Slice<any>} requests List of requests to chain
2817
- * @return {Promise<any>} API Response
2818
- */
2819
- chain(...requests) {
2820
- const arr = requests.length == 1 && Array.isArray(requests[0]) ? requests[0] : requests;
2821
- return this.request({ "$/tools/action_chain": arr.map((r) => {
2822
- if (!(r instanceof Slice)) return r;
2823
- const req = r.raw;
2824
- Object.keys(req).forEach((key) => {
2825
- if (key.startsWith("$/")) {
2826
- req[key.replace("$", "!")] = req[key];
2827
- delete req[key];
2828
- }
2829
- });
2830
- return req;
2831
- }) });
2832
- }
2833
- /**
2834
- * Organize multiple requests into a single mapped request
2835
- * @param {{[p: string]: any}} request Map of requests
2836
- * @return {Promise<any>} Map of API Responses
2837
- */
2838
- chainMap(request) {
2839
- return this.request({ "$/tools/do": [
2840
- ...Object.entries(request).flatMap(([key, r]) => {
2841
- if (!(r instanceof Slice)) return [key, r];
2842
- const req = r.raw;
2843
- Object.keys(req).forEach((key2) => {
2844
- if (key2.startsWith("$/")) {
2845
- req[key2.replace("$", "!")] = req[key2];
2846
- delete req[key2];
2847
- }
2848
- });
2849
- return [key, req];
2850
- }),
2851
- "returnAllBoilerplate",
2852
- { "$_": "*" }
2853
- ] }, {});
2854
- }
2855
- /**
2856
- * Exact same as `request` method, but logs the response in the console automatically
2857
- *
2858
- * @param {object | string} data Datalynk request as object or string
2859
- * @param {ApiRequestOptions} options
2860
- * @returns {Promise<any>} Datalynk response
2861
- */
2862
- debug(data, options = {}) {
2863
- return this.request(data, options).then((data2) => {
2864
- console.log(data2);
2865
- return data2;
2866
- }).catch((err) => {
2867
- console.error(err);
2868
- return err;
2869
- });
2870
- }
2871
- /**
2872
- * Send a request to Datalynk
2873
- *
2874
- * @example
2875
- * ```ts
2876
- * const response = await api.request('$/auth/current');
2877
- * ```
2878
- *
2879
- * @param {object} data Request using Datalynk API syntax. Strings will be converted: '$/auth/current' -> {'$/auth/current': {}}
2880
- * @param {ApiRequestOptions} options
2881
- * @returns {Promise<any>} Datalynk response or error
2882
- */
2883
- request(data, options = {}) {
2884
- data = typeof data == "string" ? { [data]: {} } : data;
2885
- if (options.noOptimize) {
2886
- return new Promise((res, rej) => {
2887
- this._request(data, options).then((resp) => {
2888
- (resp == null ? void 0 : resp.error) ? rej(resp) : res(resp);
2889
- }).catch((err) => rej(err));
2890
- });
2891
- }
2892
- let key = JSON.stringify(data);
2893
- if (!this.pending[key]) {
2894
- this.pending[key] = new Promise((res, rej) => this.bundle.push({ data, res, rej }));
2895
- this.pending[key].catch().then(() => delete this.pending[key]);
2896
- if (!this.bundleOngoing) {
2897
- this.bundleOngoing = true;
2898
- setTimeout(() => {
2899
- let originalBundle = this.bundle;
2900
- this.bundle = [];
2901
- this.bundleOngoing = false;
2902
- data = originalBundle.map((row) => row.data);
2903
- this._request(data, options).then((resp) => {
2904
- if (!(resp instanceof Array)) resp = [resp];
2905
- resp.forEach((row, i) => (row == null ? void 0 : row.error) ? originalBundle[i].rej(row.error) : originalBundle[i].res(row));
2906
- }).catch((err) => originalBundle.forEach((req) => req.rej(err)));
2907
- }, this.options.bundleTime);
2908
- }
2909
- }
2910
- return this.pending[key];
2911
- }
2912
- /**
2913
- * Create a slice object using the API
2914
- *
2915
- * @example
2916
- * ```ts
2917
- * const contactsSlice = api.slice<Contacts>(12345);
2918
- * const allContacts = await contactsSlice.select().exec().rows();
2919
- * const unsubscribe = contactsSlice.sync().subscribe(rows => console.log(rows));
2920
- * ```
2921
- *
2922
- * @param {number} slice Slice number the object will target
2923
- * @returns {Slice<T = any>} Object for making requests & caching rows
2924
- */
2925
- slice(slice) {
2926
- return new Slice(slice, this);
2927
- }
2928
- }
2929
- exports2.Api = Api;
2930
- exports2.Auth = Auth;
2931
- exports2.Files = Files;
2932
- exports2.LoginPrompt = LoginPrompt;
2933
- exports2.Pdf = Pdf;
2934
- exports2.Serializer = Serializer;
2935
- exports2.Slice = Slice;
2936
- exports2.Socket = Socket;
2937
- exports2.Superuser = Superuser;
2938
- Object.defineProperty(exports2, Symbol.toStringTag, { value: "Module" });
2939
- });