@auxilium/datalynk-client 1.2.4 → 1.2.5
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/api.d.ts +206 -0
- package/dist/api.d.ts.map +1 -0
- package/dist/auth.d.ts +174 -0
- package/dist/auth.d.ts.map +1 -0
- package/dist/files.d.ts +65 -0
- package/dist/files.d.ts.map +1 -0
- package/dist/index.d.ts +13 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +3779 -0
- package/dist/index.mjs +3779 -0
- package/dist/login-prompt.d.ts +76 -0
- package/dist/login-prompt.d.ts.map +1 -0
- package/dist/meta.d.ts +464 -0
- package/dist/meta.d.ts.map +1 -0
- package/dist/pdf.d.ts +42 -0
- package/dist/pdf.d.ts.map +1 -0
- package/dist/pwa.d.ts +14 -0
- package/dist/pwa.d.ts.map +1 -0
- package/dist/serializer.d.ts +55 -0
- package/dist/serializer.d.ts.map +1 -0
- package/dist/service.worker.d.ts +2 -0
- package/dist/service.worker.d.ts.map +1 -0
- package/dist/service.worker.js +15 -0
- package/dist/service.worker.mjs +14 -0
- package/dist/slice.d.ts +299 -0
- package/dist/slice.d.ts.map +1 -0
- package/dist/socket.d.ts +95 -0
- package/dist/socket.d.ts.map +1 -0
- package/dist/superuser.d.ts +24 -0
- package/dist/superuser.d.ts.map +1 -0
- package/dist/themes.d.ts +55 -0
- package/dist/themes.d.ts.map +1 -0
- package/dist/webrtc.d.ts +50 -0
- package/dist/webrtc.d.ts.map +1 -0
- package/package.json +1 -1
package/dist/index.js
ADDED
|
@@ -0,0 +1,3779 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __defProp = Object.defineProperty;
|
|
3
|
+
var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
|
|
4
|
+
var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
|
|
5
|
+
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
6
|
+
var __defProp2 = Object.defineProperty;
|
|
7
|
+
var __defNormalProp2 = (obj, key, value) => key in obj ? __defProp2(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
|
|
8
|
+
var __publicField2 = (obj, key, value) => __defNormalProp2(obj, typeof key !== "symbol" ? key + "" : key, value);
|
|
9
|
+
function clean(obj, undefinedOnly = false) {
|
|
10
|
+
if (obj == null) throw new Error("Cannot clean a NULL value");
|
|
11
|
+
if (Array.isArray(obj)) {
|
|
12
|
+
obj = obj.filter((o) => undefinedOnly ? o !== void 0 : o != null);
|
|
13
|
+
} else {
|
|
14
|
+
Object.entries(obj).forEach(([key, value]) => {
|
|
15
|
+
if (undefinedOnly && value === void 0 || !undefinedOnly && value == null) delete obj[key];
|
|
16
|
+
});
|
|
17
|
+
}
|
|
18
|
+
return obj;
|
|
19
|
+
}
|
|
20
|
+
function deepCopy(value) {
|
|
21
|
+
try {
|
|
22
|
+
return structuredClone(value);
|
|
23
|
+
} catch {
|
|
24
|
+
return JSON.parse(JSONSanitize(value));
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
function dotNotation(obj, prop, set) {
|
|
28
|
+
if (obj == null || !prop) return void 0;
|
|
29
|
+
return prop.split(/[.[\]]/g).filter((prop2) => prop2.length).reduce((obj2, prop2, i, arr) => {
|
|
30
|
+
if (prop2[0] == '"' || prop2[0] == "'") prop2 = prop2.slice(1, -1);
|
|
31
|
+
if (!(obj2 == null ? void 0 : obj2.hasOwnProperty(prop2))) {
|
|
32
|
+
return void 0;
|
|
33
|
+
}
|
|
34
|
+
return obj2[prop2];
|
|
35
|
+
}, obj);
|
|
36
|
+
}
|
|
37
|
+
function isEqual(a, b) {
|
|
38
|
+
const ta = typeof a, tb = typeof b;
|
|
39
|
+
if (ta != "object" || a == null || (tb != "object" || b == null))
|
|
40
|
+
return ta == "function" && tb == "function" ? a.toString() == b.toString() : a === b;
|
|
41
|
+
const keys = Object.keys(a);
|
|
42
|
+
if (keys.length != Object.keys(b).length) return false;
|
|
43
|
+
return Object.keys(a).every((key) => isEqual(a[key], b[key]));
|
|
44
|
+
}
|
|
45
|
+
function JSONAttemptParse(json) {
|
|
46
|
+
try {
|
|
47
|
+
return JSON.parse(json);
|
|
48
|
+
} catch {
|
|
49
|
+
return json;
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
function JSONSanitize(obj, space) {
|
|
53
|
+
const cache = [];
|
|
54
|
+
return JSON.stringify(obj, (key, value) => {
|
|
55
|
+
if (typeof value === "object" && value !== null) {
|
|
56
|
+
if (cache.includes(value)) return "[Circular]";
|
|
57
|
+
cache.push(value);
|
|
58
|
+
}
|
|
59
|
+
return value;
|
|
60
|
+
}, space);
|
|
61
|
+
}
|
|
62
|
+
class ASet extends Array {
|
|
63
|
+
/** Number of elements in set */
|
|
64
|
+
get size() {
|
|
65
|
+
return this.length;
|
|
66
|
+
}
|
|
67
|
+
/**
|
|
68
|
+
* Array to create set from, duplicate values will be removed
|
|
69
|
+
* @param {T[]} elements Elements which will be added to set
|
|
70
|
+
*/
|
|
71
|
+
constructor(elements = []) {
|
|
72
|
+
super();
|
|
73
|
+
if (!!(elements == null ? void 0 : elements["forEach"]))
|
|
74
|
+
elements.forEach((el) => this.add(el));
|
|
75
|
+
}
|
|
76
|
+
/**
|
|
77
|
+
* Add elements to set if unique
|
|
78
|
+
* @param items
|
|
79
|
+
*/
|
|
80
|
+
add(...items) {
|
|
81
|
+
items.filter((el) => !this.has(el)).forEach((el) => this.push(el));
|
|
82
|
+
return this;
|
|
83
|
+
}
|
|
84
|
+
/**
|
|
85
|
+
* Remove all elements
|
|
86
|
+
*/
|
|
87
|
+
clear() {
|
|
88
|
+
this.splice(0, this.length);
|
|
89
|
+
return this;
|
|
90
|
+
}
|
|
91
|
+
/**
|
|
92
|
+
* Delete elements from set
|
|
93
|
+
* @param items Elements that will be deleted
|
|
94
|
+
*/
|
|
95
|
+
delete(...items) {
|
|
96
|
+
items.forEach((el) => {
|
|
97
|
+
const index = this.indexOf(el);
|
|
98
|
+
if (index != -1) this.splice(index, 1);
|
|
99
|
+
});
|
|
100
|
+
return this;
|
|
101
|
+
}
|
|
102
|
+
/**
|
|
103
|
+
* Create list of elements this set has which the comparison set does not
|
|
104
|
+
* @param {ASet<T>} set Set to compare against
|
|
105
|
+
* @return {ASet<T>} Different elements
|
|
106
|
+
*/
|
|
107
|
+
difference(set) {
|
|
108
|
+
return new ASet(this.filter((el) => !set.has(el)));
|
|
109
|
+
}
|
|
110
|
+
/**
|
|
111
|
+
* Check if set includes element
|
|
112
|
+
* @param {T} el Element to look for
|
|
113
|
+
* @return {boolean} True if element was found, false otherwise
|
|
114
|
+
*/
|
|
115
|
+
has(el) {
|
|
116
|
+
return this.indexOf(el) != -1;
|
|
117
|
+
}
|
|
118
|
+
/**
|
|
119
|
+
* Find index number of element, or -1 if it doesn't exist. Matches by equality not reference
|
|
120
|
+
*
|
|
121
|
+
* @param {T} search Element to find
|
|
122
|
+
* @param {number} fromIndex Starting index position
|
|
123
|
+
* @return {number} Element index number or -1 if missing
|
|
124
|
+
*/
|
|
125
|
+
indexOf(search2, fromIndex) {
|
|
126
|
+
return super.findIndex((el) => isEqual(el, search2), fromIndex);
|
|
127
|
+
}
|
|
128
|
+
/**
|
|
129
|
+
* Create list of elements this set has in common with the comparison set
|
|
130
|
+
* @param {ASet<T>} set Set to compare against
|
|
131
|
+
* @return {boolean} Set of common elements
|
|
132
|
+
*/
|
|
133
|
+
intersection(set) {
|
|
134
|
+
return new ASet(this.filter((el) => set.has(el)));
|
|
135
|
+
}
|
|
136
|
+
/**
|
|
137
|
+
* Check if this set has no elements in common with the comparison set
|
|
138
|
+
* @param {ASet<T>} set Set to compare against
|
|
139
|
+
* @return {boolean} True if nothing in common, false otherwise
|
|
140
|
+
*/
|
|
141
|
+
isDisjointFrom(set) {
|
|
142
|
+
return this.intersection(set).size == 0;
|
|
143
|
+
}
|
|
144
|
+
/**
|
|
145
|
+
* Check if all elements in this set are included in the comparison set
|
|
146
|
+
* @param {ASet<T>} set Set to compare against
|
|
147
|
+
* @return {boolean} True if all elements are included, false otherwise
|
|
148
|
+
*/
|
|
149
|
+
isSubsetOf(set) {
|
|
150
|
+
return this.findIndex((el) => !set.has(el)) == -1;
|
|
151
|
+
}
|
|
152
|
+
/**
|
|
153
|
+
* Check if all elements from comparison set are included in this set
|
|
154
|
+
* @param {ASet<T>} set Set to compare against
|
|
155
|
+
* @return {boolean} True if all elements are included, false otherwise
|
|
156
|
+
*/
|
|
157
|
+
isSuperset(set) {
|
|
158
|
+
return set.findIndex((el) => !this.has(el)) == -1;
|
|
159
|
+
}
|
|
160
|
+
/**
|
|
161
|
+
* Create list of elements that are only in one set but not both (XOR)
|
|
162
|
+
* @param {ASet<T>} set Set to compare against
|
|
163
|
+
* @return {ASet<T>} New set of unique elements
|
|
164
|
+
*/
|
|
165
|
+
symmetricDifference(set) {
|
|
166
|
+
return new ASet([...this.difference(set), ...set.difference(this)]);
|
|
167
|
+
}
|
|
168
|
+
/**
|
|
169
|
+
* Create joined list of elements included in this & the comparison set
|
|
170
|
+
* @param {ASet<T>} set Set join
|
|
171
|
+
* @return {ASet<T>} New set of both previous sets combined
|
|
172
|
+
*/
|
|
173
|
+
union(set) {
|
|
174
|
+
return new ASet([...this, ...set]);
|
|
175
|
+
}
|
|
176
|
+
}
|
|
177
|
+
function sortByProp(prop, reverse = false) {
|
|
178
|
+
return function(a, b) {
|
|
179
|
+
const aVal = dotNotation(a, prop);
|
|
180
|
+
const bVal = dotNotation(b, prop);
|
|
181
|
+
if (typeof aVal == "number" && typeof bVal == "number")
|
|
182
|
+
return (reverse ? -1 : 1) * (aVal - bVal);
|
|
183
|
+
if (aVal > bVal) return reverse ? -1 : 1;
|
|
184
|
+
if (aVal < bVal) return reverse ? 1 : -1;
|
|
185
|
+
return 0;
|
|
186
|
+
};
|
|
187
|
+
}
|
|
188
|
+
function makeArray(value) {
|
|
189
|
+
return Array.isArray(value) ? value : [value];
|
|
190
|
+
}
|
|
191
|
+
class Database {
|
|
192
|
+
constructor(database, tables, version2) {
|
|
193
|
+
__publicField2(this, "connection");
|
|
194
|
+
__publicField2(this, "tables");
|
|
195
|
+
this.database = database;
|
|
196
|
+
this.version = version2;
|
|
197
|
+
this.connection = new Promise((resolve, reject) => {
|
|
198
|
+
const req = indexedDB.open(this.database, this.version);
|
|
199
|
+
this.tables = tables.map((t) => {
|
|
200
|
+
t = typeof t == "object" ? t : { name: t };
|
|
201
|
+
return { ...t, name: t.name.toString() };
|
|
202
|
+
});
|
|
203
|
+
const tableNames = new ASet(this.tables.map((t) => t.name));
|
|
204
|
+
req.onerror = () => reject(req.error);
|
|
205
|
+
req.onsuccess = () => {
|
|
206
|
+
const db = req.result;
|
|
207
|
+
if (tableNames.symmetricDifference(new ASet(Array.from(db.objectStoreNames))).length) {
|
|
208
|
+
db.close();
|
|
209
|
+
Object.assign(this, new Database(this.database, this.tables, db.version + 1));
|
|
210
|
+
} else {
|
|
211
|
+
this.version = db.version;
|
|
212
|
+
resolve(db);
|
|
213
|
+
}
|
|
214
|
+
};
|
|
215
|
+
req.onupgradeneeded = () => {
|
|
216
|
+
const db = req.result;
|
|
217
|
+
const existingTables = new ASet(Array.from(db.objectStoreNames));
|
|
218
|
+
existingTables.difference(tableNames).forEach((name) => db.deleteObjectStore(name));
|
|
219
|
+
tableNames.difference(existingTables).forEach((name) => db.createObjectStore(name));
|
|
220
|
+
};
|
|
221
|
+
});
|
|
222
|
+
}
|
|
223
|
+
includes(name) {
|
|
224
|
+
return !!this.tables.find((t) => t.name == name.toString());
|
|
225
|
+
}
|
|
226
|
+
table(name) {
|
|
227
|
+
return new Table(this, name.toString());
|
|
228
|
+
}
|
|
229
|
+
}
|
|
230
|
+
class Table {
|
|
231
|
+
constructor(database, name) {
|
|
232
|
+
this.database = database;
|
|
233
|
+
this.name = name;
|
|
234
|
+
}
|
|
235
|
+
async tx(table, fn2, readonly = false) {
|
|
236
|
+
const db = await this.database.connection;
|
|
237
|
+
const tx = db.transaction(table, readonly ? "readonly" : "readwrite");
|
|
238
|
+
const store = tx.objectStore(table);
|
|
239
|
+
return new Promise((resolve, reject) => {
|
|
240
|
+
const request = fn2(store);
|
|
241
|
+
request.onsuccess = () => resolve(request.result);
|
|
242
|
+
request.onerror = () => reject(request.error);
|
|
243
|
+
});
|
|
244
|
+
}
|
|
245
|
+
add(value, key) {
|
|
246
|
+
return this.tx(this.name, (store) => store.add(value, key));
|
|
247
|
+
}
|
|
248
|
+
count() {
|
|
249
|
+
return this.tx(this.name, (store) => store.count(), true);
|
|
250
|
+
}
|
|
251
|
+
put(key, value) {
|
|
252
|
+
return this.tx(this.name, (store) => store.put(value, key));
|
|
253
|
+
}
|
|
254
|
+
getAll() {
|
|
255
|
+
return this.tx(this.name, (store) => store.getAll(), true);
|
|
256
|
+
}
|
|
257
|
+
getAllKeys() {
|
|
258
|
+
return this.tx(this.name, (store) => store.getAllKeys(), true);
|
|
259
|
+
}
|
|
260
|
+
get(key) {
|
|
261
|
+
return this.tx(this.name, (store) => store.get(key), true);
|
|
262
|
+
}
|
|
263
|
+
delete(key) {
|
|
264
|
+
return this.tx(this.name, (store) => store.delete(key));
|
|
265
|
+
}
|
|
266
|
+
clear() {
|
|
267
|
+
return this.tx(this.name, (store) => store.clear());
|
|
268
|
+
}
|
|
269
|
+
}
|
|
270
|
+
function contrast(background) {
|
|
271
|
+
const exploded = background == null ? void 0 : background.match(background.length >= 6 ? /[0-9a-fA-F]{2}/g : /[0-9a-fA-F]/g);
|
|
272
|
+
if (!exploded || (exploded == null ? void 0 : exploded.length) < 3) return "black";
|
|
273
|
+
const [r, g, b] = exploded.map((hex) => parseInt(hex.length == 1 ? `${hex}${hex}` : hex, 16));
|
|
274
|
+
const luminance = (0.299 * r + 0.587 * g + 0.114 * b) / 255;
|
|
275
|
+
return luminance > 0.5 ? "black" : "white";
|
|
276
|
+
}
|
|
277
|
+
const LETTER_LIST = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
|
|
278
|
+
const NUMBER_LIST = "0123456789";
|
|
279
|
+
const SYMBOL_LIST = "~`!@#$%^&*()_-+={[}]|\\:;\"'<,>.?/";
|
|
280
|
+
function randomStringBuilder(length, letters = false, numbers = false, symbols = false) {
|
|
281
|
+
if (!letters && !numbers && !symbols) throw new Error("Must enable at least one: letters, numbers, symbols");
|
|
282
|
+
return Array(length).fill(null).map(() => {
|
|
283
|
+
let c;
|
|
284
|
+
do {
|
|
285
|
+
const type = ~~(Math.random() * 3);
|
|
286
|
+
if (letters && type == 0) {
|
|
287
|
+
c = LETTER_LIST[~~(Math.random() * LETTER_LIST.length)];
|
|
288
|
+
} else if (numbers && type == 1) {
|
|
289
|
+
c = NUMBER_LIST[~~(Math.random() * NUMBER_LIST.length)];
|
|
290
|
+
} else if (symbols && type == 2) {
|
|
291
|
+
c = SYMBOL_LIST[~~(Math.random() * SYMBOL_LIST.length)];
|
|
292
|
+
}
|
|
293
|
+
} while (!c);
|
|
294
|
+
return c;
|
|
295
|
+
}).join("");
|
|
296
|
+
}
|
|
297
|
+
class PromiseProgress extends Promise {
|
|
298
|
+
constructor(executor) {
|
|
299
|
+
super((resolve, reject) => executor(
|
|
300
|
+
(value) => resolve(value),
|
|
301
|
+
(reason) => reject(reason),
|
|
302
|
+
(progress) => this.progress = progress
|
|
303
|
+
));
|
|
304
|
+
__publicField2(this, "listeners", []);
|
|
305
|
+
__publicField2(this, "_progress", 0);
|
|
306
|
+
}
|
|
307
|
+
get progress() {
|
|
308
|
+
return this._progress;
|
|
309
|
+
}
|
|
310
|
+
set progress(p) {
|
|
311
|
+
if (p == this._progress) return;
|
|
312
|
+
this._progress = p;
|
|
313
|
+
this.listeners.forEach((l) => l(p));
|
|
314
|
+
}
|
|
315
|
+
static from(promise) {
|
|
316
|
+
if (promise instanceof PromiseProgress) return promise;
|
|
317
|
+
return new PromiseProgress((res, rej) => promise.then((...args) => res(...args)).catch((...args) => rej(...args)));
|
|
318
|
+
}
|
|
319
|
+
from(promise) {
|
|
320
|
+
const newPromise = PromiseProgress.from(promise);
|
|
321
|
+
this.onProgress((p) => newPromise.progress = p);
|
|
322
|
+
return newPromise;
|
|
323
|
+
}
|
|
324
|
+
onProgress(callback) {
|
|
325
|
+
this.listeners.push(callback);
|
|
326
|
+
return this;
|
|
327
|
+
}
|
|
328
|
+
then(res, rej) {
|
|
329
|
+
const resp = super.then(res, rej);
|
|
330
|
+
return this.from(resp);
|
|
331
|
+
}
|
|
332
|
+
catch(rej) {
|
|
333
|
+
return this.from(super.catch(rej));
|
|
334
|
+
}
|
|
335
|
+
finally(res) {
|
|
336
|
+
return this.from(super.finally(res));
|
|
337
|
+
}
|
|
338
|
+
}
|
|
339
|
+
class TypedEmitter {
|
|
340
|
+
constructor() {
|
|
341
|
+
__publicField2(this, "listeners", {});
|
|
342
|
+
}
|
|
343
|
+
static emit(event, ...args) {
|
|
344
|
+
(this.listeners["*"] || []).forEach((l) => l(event, ...args));
|
|
345
|
+
(this.listeners[event.toString()] || []).forEach((l) => l(...args));
|
|
346
|
+
}
|
|
347
|
+
static off(event, listener) {
|
|
348
|
+
const e = event.toString();
|
|
349
|
+
this.listeners[e] = (this.listeners[e] || []).filter((l) => l != listener);
|
|
350
|
+
}
|
|
351
|
+
static on(event, listener) {
|
|
352
|
+
var _a;
|
|
353
|
+
const e = event.toString();
|
|
354
|
+
if (!this.listeners[e]) this.listeners[e] = [];
|
|
355
|
+
(_a = this.listeners[e]) == null ? void 0 : _a.push(listener);
|
|
356
|
+
return () => this.off(event, listener);
|
|
357
|
+
}
|
|
358
|
+
static once(event, listener) {
|
|
359
|
+
return new Promise((res) => {
|
|
360
|
+
const unsubscribe = this.on(event, (...args) => {
|
|
361
|
+
res(args.length == 1 ? args[0] : args);
|
|
362
|
+
if (listener) listener(...args);
|
|
363
|
+
unsubscribe();
|
|
364
|
+
});
|
|
365
|
+
});
|
|
366
|
+
}
|
|
367
|
+
emit(event, ...args) {
|
|
368
|
+
(this.listeners["*"] || []).forEach((l) => l(event, ...args));
|
|
369
|
+
(this.listeners[event] || []).forEach((l) => l(...args));
|
|
370
|
+
}
|
|
371
|
+
off(event, listener) {
|
|
372
|
+
this.listeners[event] = (this.listeners[event] || []).filter((l) => l != listener);
|
|
373
|
+
}
|
|
374
|
+
on(event, listener) {
|
|
375
|
+
var _a;
|
|
376
|
+
if (!this.listeners[event]) this.listeners[event] = [];
|
|
377
|
+
(_a = this.listeners[event]) == null ? void 0 : _a.push(listener);
|
|
378
|
+
return () => this.off(event, listener);
|
|
379
|
+
}
|
|
380
|
+
once(event, listener) {
|
|
381
|
+
return new Promise((res) => {
|
|
382
|
+
const unsubscribe = this.on(event, (...args) => {
|
|
383
|
+
res(args.length == 1 ? args[0] : args);
|
|
384
|
+
if (listener) listener(...args);
|
|
385
|
+
unsubscribe();
|
|
386
|
+
});
|
|
387
|
+
});
|
|
388
|
+
}
|
|
389
|
+
}
|
|
390
|
+
__publicField2(TypedEmitter, "listeners", {});
|
|
391
|
+
class CustomError extends Error {
|
|
392
|
+
constructor(message, code) {
|
|
393
|
+
super(message);
|
|
394
|
+
__publicField2(this, "_code");
|
|
395
|
+
if (code != null) this._code = code;
|
|
396
|
+
}
|
|
397
|
+
get code() {
|
|
398
|
+
return this._code || this.constructor.code;
|
|
399
|
+
}
|
|
400
|
+
set code(c) {
|
|
401
|
+
this._code = c;
|
|
402
|
+
}
|
|
403
|
+
static from(err) {
|
|
404
|
+
const code = Number(err.statusCode) ?? Number(err.code);
|
|
405
|
+
const newErr = new this(err.message || err.toString());
|
|
406
|
+
return Object.assign(newErr, {
|
|
407
|
+
stack: err.stack,
|
|
408
|
+
...err,
|
|
409
|
+
code: code ?? void 0
|
|
410
|
+
});
|
|
411
|
+
}
|
|
412
|
+
static instanceof(err) {
|
|
413
|
+
return err.constructor.code != void 0;
|
|
414
|
+
}
|
|
415
|
+
toString() {
|
|
416
|
+
return this.message || super.toString();
|
|
417
|
+
}
|
|
418
|
+
}
|
|
419
|
+
__publicField2(CustomError, "code", 500);
|
|
420
|
+
class BadRequestError extends CustomError {
|
|
421
|
+
constructor(message = "Bad Request") {
|
|
422
|
+
super(message);
|
|
423
|
+
}
|
|
424
|
+
static instanceof(err) {
|
|
425
|
+
return err.constructor.code == this.code;
|
|
426
|
+
}
|
|
427
|
+
}
|
|
428
|
+
__publicField2(BadRequestError, "code", 400);
|
|
429
|
+
class UnauthorizedError extends CustomError {
|
|
430
|
+
constructor(message = "Unauthorized") {
|
|
431
|
+
super(message);
|
|
432
|
+
}
|
|
433
|
+
static instanceof(err) {
|
|
434
|
+
return err.constructor.code == this.code;
|
|
435
|
+
}
|
|
436
|
+
}
|
|
437
|
+
__publicField2(UnauthorizedError, "code", 401);
|
|
438
|
+
class PaymentRequiredError extends CustomError {
|
|
439
|
+
constructor(message = "Payment Required") {
|
|
440
|
+
super(message);
|
|
441
|
+
}
|
|
442
|
+
static instanceof(err) {
|
|
443
|
+
return err.constructor.code == this.code;
|
|
444
|
+
}
|
|
445
|
+
}
|
|
446
|
+
__publicField2(PaymentRequiredError, "code", 402);
|
|
447
|
+
class ForbiddenError extends CustomError {
|
|
448
|
+
constructor(message = "Forbidden") {
|
|
449
|
+
super(message);
|
|
450
|
+
}
|
|
451
|
+
static instanceof(err) {
|
|
452
|
+
return err.constructor.code == this.code;
|
|
453
|
+
}
|
|
454
|
+
}
|
|
455
|
+
__publicField2(ForbiddenError, "code", 403);
|
|
456
|
+
class NotFoundError extends CustomError {
|
|
457
|
+
constructor(message = "Not Found") {
|
|
458
|
+
super(message);
|
|
459
|
+
}
|
|
460
|
+
static instanceof(err) {
|
|
461
|
+
return err.constructor.code == this.code;
|
|
462
|
+
}
|
|
463
|
+
}
|
|
464
|
+
__publicField2(NotFoundError, "code", 404);
|
|
465
|
+
class MethodNotAllowedError extends CustomError {
|
|
466
|
+
constructor(message = "Method Not Allowed") {
|
|
467
|
+
super(message);
|
|
468
|
+
}
|
|
469
|
+
static instanceof(err) {
|
|
470
|
+
return err.constructor.code == this.code;
|
|
471
|
+
}
|
|
472
|
+
}
|
|
473
|
+
__publicField2(MethodNotAllowedError, "code", 405);
|
|
474
|
+
class NotAcceptableError extends CustomError {
|
|
475
|
+
constructor(message = "Not Acceptable") {
|
|
476
|
+
super(message);
|
|
477
|
+
}
|
|
478
|
+
static instanceof(err) {
|
|
479
|
+
return err.constructor.code == this.code;
|
|
480
|
+
}
|
|
481
|
+
}
|
|
482
|
+
__publicField2(NotAcceptableError, "code", 406);
|
|
483
|
+
class InternalServerError extends CustomError {
|
|
484
|
+
constructor(message = "Internal Server Error") {
|
|
485
|
+
super(message);
|
|
486
|
+
}
|
|
487
|
+
static instanceof(err) {
|
|
488
|
+
return err.constructor.code == this.code;
|
|
489
|
+
}
|
|
490
|
+
}
|
|
491
|
+
__publicField2(InternalServerError, "code", 500);
|
|
492
|
+
class NotImplementedError extends CustomError {
|
|
493
|
+
constructor(message = "Not Implemented") {
|
|
494
|
+
super(message);
|
|
495
|
+
}
|
|
496
|
+
static instanceof(err) {
|
|
497
|
+
return err.constructor.code == this.code;
|
|
498
|
+
}
|
|
499
|
+
}
|
|
500
|
+
__publicField2(NotImplementedError, "code", 501);
|
|
501
|
+
class BadGatewayError extends CustomError {
|
|
502
|
+
constructor(message = "Bad Gateway") {
|
|
503
|
+
super(message);
|
|
504
|
+
}
|
|
505
|
+
static instanceof(err) {
|
|
506
|
+
return err.constructor.code == this.code;
|
|
507
|
+
}
|
|
508
|
+
}
|
|
509
|
+
__publicField2(BadGatewayError, "code", 502);
|
|
510
|
+
class ServiceUnavailableError extends CustomError {
|
|
511
|
+
constructor(message = "Service Unavailable") {
|
|
512
|
+
super(message);
|
|
513
|
+
}
|
|
514
|
+
static instanceof(err) {
|
|
515
|
+
return err.constructor.code == this.code;
|
|
516
|
+
}
|
|
517
|
+
}
|
|
518
|
+
__publicField2(ServiceUnavailableError, "code", 503);
|
|
519
|
+
class GatewayTimeoutError extends CustomError {
|
|
520
|
+
constructor(message = "Gateway Timeout") {
|
|
521
|
+
super(message);
|
|
522
|
+
}
|
|
523
|
+
static instanceof(err) {
|
|
524
|
+
return err.constructor.code == this.code;
|
|
525
|
+
}
|
|
526
|
+
}
|
|
527
|
+
__publicField2(GatewayTimeoutError, "code", 504);
|
|
528
|
+
function errorFromCode(code, message) {
|
|
529
|
+
switch (code) {
|
|
530
|
+
case 400:
|
|
531
|
+
return new BadRequestError(message);
|
|
532
|
+
case 401:
|
|
533
|
+
return new UnauthorizedError(message);
|
|
534
|
+
case 402:
|
|
535
|
+
return new PaymentRequiredError(message);
|
|
536
|
+
case 403:
|
|
537
|
+
return new ForbiddenError(message);
|
|
538
|
+
case 404:
|
|
539
|
+
return new NotFoundError(message);
|
|
540
|
+
case 405:
|
|
541
|
+
return new MethodNotAllowedError(message);
|
|
542
|
+
case 406:
|
|
543
|
+
return new NotAcceptableError(message);
|
|
544
|
+
case 500:
|
|
545
|
+
return new InternalServerError(message);
|
|
546
|
+
case 501:
|
|
547
|
+
return new NotImplementedError(message);
|
|
548
|
+
case 502:
|
|
549
|
+
return new BadGatewayError(message);
|
|
550
|
+
case 503:
|
|
551
|
+
return new ServiceUnavailableError(message);
|
|
552
|
+
case 504:
|
|
553
|
+
return new GatewayTimeoutError(message);
|
|
554
|
+
default:
|
|
555
|
+
return new CustomError(message, code);
|
|
556
|
+
}
|
|
557
|
+
}
|
|
558
|
+
class HttpResponse extends Response {
|
|
559
|
+
constructor(resp, stream) {
|
|
560
|
+
const body = [204, 205, 304].includes(resp.status) ? null : stream;
|
|
561
|
+
super(body, {
|
|
562
|
+
headers: resp.headers,
|
|
563
|
+
status: resp.status,
|
|
564
|
+
statusText: resp.statusText
|
|
565
|
+
});
|
|
566
|
+
__publicField2(this, "data");
|
|
567
|
+
__publicField2(this, "ok");
|
|
568
|
+
__publicField2(this, "redirected");
|
|
569
|
+
__publicField2(this, "type");
|
|
570
|
+
__publicField2(this, "url");
|
|
571
|
+
this.ok = resp.ok;
|
|
572
|
+
this.redirected = resp.redirected;
|
|
573
|
+
this.type = resp.type;
|
|
574
|
+
this.url = resp.url;
|
|
575
|
+
}
|
|
576
|
+
}
|
|
577
|
+
const _Http = class _Http2 {
|
|
578
|
+
constructor(defaults = {}) {
|
|
579
|
+
__publicField2(this, "interceptors", {});
|
|
580
|
+
__publicField2(this, "headers", {});
|
|
581
|
+
__publicField2(this, "url");
|
|
582
|
+
this.url = defaults.url ?? null;
|
|
583
|
+
this.headers = defaults.headers || {};
|
|
584
|
+
if (defaults.interceptors) {
|
|
585
|
+
defaults.interceptors.forEach((i) => _Http2.addInterceptor(i));
|
|
586
|
+
}
|
|
587
|
+
}
|
|
588
|
+
static addInterceptor(fn2) {
|
|
589
|
+
const key = Object.keys(_Http2.interceptors).length.toString();
|
|
590
|
+
_Http2.interceptors[key] = fn2;
|
|
591
|
+
return () => {
|
|
592
|
+
_Http2.interceptors[key] = null;
|
|
593
|
+
};
|
|
594
|
+
}
|
|
595
|
+
addInterceptor(fn2) {
|
|
596
|
+
const key = Object.keys(this.interceptors).length.toString();
|
|
597
|
+
this.interceptors[key] = fn2;
|
|
598
|
+
return () => {
|
|
599
|
+
this.interceptors[key] = null;
|
|
600
|
+
};
|
|
601
|
+
}
|
|
602
|
+
request(opts = {}) {
|
|
603
|
+
var _a;
|
|
604
|
+
if (!this.url && !opts.url) throw new Error("URL needs to be set");
|
|
605
|
+
let url = ((_a = opts.url) == null ? void 0 : _a.startsWith("http")) ? opts.url : (this.url || "") + (opts.url || "");
|
|
606
|
+
url = url.replaceAll(/([^:]\/)\/+/g, "$1");
|
|
607
|
+
if (opts.fragment) url.includes("#") ? url.replace(/#.*(\?|\n)/g, (match, arg1) => `#${opts.fragment}${arg1}`) : `${url}#${opts.fragment}`;
|
|
608
|
+
if (opts.query) {
|
|
609
|
+
const q = Array.isArray(opts.query) ? opts.query : Object.keys(opts.query).map((k) => ({ key: k, value: opts.query[k] }));
|
|
610
|
+
url += (url.includes("?") ? "&" : "?") + q.map((q2) => `${q2.key}=${q2.value}`).join("&");
|
|
611
|
+
}
|
|
612
|
+
const headers = clean({
|
|
613
|
+
"Content-Type": !opts.body ? void 0 : opts.body instanceof FormData ? "multipart/form-data" : "application/json",
|
|
614
|
+
..._Http2.headers,
|
|
615
|
+
...this.headers,
|
|
616
|
+
...opts.headers
|
|
617
|
+
});
|
|
618
|
+
if (typeof opts.body == "object" && opts.body != null && headers["Content-Type"] == "application/json")
|
|
619
|
+
opts.body = JSON.stringify(opts.body);
|
|
620
|
+
return new PromiseProgress((res, rej, prog) => {
|
|
621
|
+
try {
|
|
622
|
+
fetch(url, {
|
|
623
|
+
headers,
|
|
624
|
+
method: opts.method || (opts.body ? "POST" : "GET"),
|
|
625
|
+
body: opts.body
|
|
626
|
+
}).then(async (resp) => {
|
|
627
|
+
var _a2, _b;
|
|
628
|
+
for (let fn2 of [...Object.values(_Http2.interceptors), ...Object.values(this.interceptors)]) {
|
|
629
|
+
await new Promise((res2) => fn2(resp, () => res2()));
|
|
630
|
+
}
|
|
631
|
+
const contentLength = resp.headers.get("Content-Length");
|
|
632
|
+
const total = contentLength ? parseInt(contentLength, 10) : 0;
|
|
633
|
+
let loaded = 0;
|
|
634
|
+
const reader = (_a2 = resp.body) == null ? void 0 : _a2.getReader();
|
|
635
|
+
const stream = new ReadableStream({
|
|
636
|
+
start(controller) {
|
|
637
|
+
function push() {
|
|
638
|
+
reader == null ? void 0 : reader.read().then((event) => {
|
|
639
|
+
if (event.done) return controller.close();
|
|
640
|
+
loaded += event.value.byteLength;
|
|
641
|
+
prog(loaded / total);
|
|
642
|
+
controller.enqueue(event.value);
|
|
643
|
+
push();
|
|
644
|
+
}).catch((error) => controller.error(error));
|
|
645
|
+
}
|
|
646
|
+
push();
|
|
647
|
+
}
|
|
648
|
+
});
|
|
649
|
+
resp = new HttpResponse(resp, stream);
|
|
650
|
+
if (opts.decode !== false) {
|
|
651
|
+
const content = (_b = resp.headers.get("Content-Type")) == null ? void 0 : _b.toLowerCase();
|
|
652
|
+
if (content == null ? void 0 : content.includes("form")) resp.data = await resp.formData();
|
|
653
|
+
else if (content == null ? void 0 : content.includes("json")) resp.data = await resp.json();
|
|
654
|
+
else if (content == null ? void 0 : content.includes("text")) resp.data = await resp.text();
|
|
655
|
+
else if (content == null ? void 0 : content.includes("application")) resp.data = await resp.blob();
|
|
656
|
+
}
|
|
657
|
+
if (resp.ok) res(resp);
|
|
658
|
+
else rej(resp);
|
|
659
|
+
}).catch((err) => rej(err));
|
|
660
|
+
} catch (err) {
|
|
661
|
+
rej(err);
|
|
662
|
+
}
|
|
663
|
+
});
|
|
664
|
+
}
|
|
665
|
+
};
|
|
666
|
+
__publicField2(_Http, "interceptors", {});
|
|
667
|
+
__publicField2(_Http, "headers", {});
|
|
668
|
+
function decodeJwt(token) {
|
|
669
|
+
const base64 = token.split(".")[1].replace(/-/g, "+").replace(/_/g, "/");
|
|
670
|
+
return JSONAttemptParse(decodeURIComponent(atob(base64).split("").map(function(c) {
|
|
671
|
+
return "%" + ("00" + c.charCodeAt(0).toString(16)).slice(-2);
|
|
672
|
+
}).join("")));
|
|
673
|
+
}
|
|
674
|
+
const CliEffects = {
|
|
675
|
+
CLEAR: "\x1B[0m"
|
|
676
|
+
};
|
|
677
|
+
const CliForeground = {
|
|
678
|
+
RED: "\x1B[31m",
|
|
679
|
+
YELLOW: "\x1B[33m",
|
|
680
|
+
BLUE: "\x1B[34m",
|
|
681
|
+
LIGHT_GREY: "\x1B[37m"
|
|
682
|
+
};
|
|
683
|
+
const _Logger = class _Logger2 extends TypedEmitter {
|
|
684
|
+
constructor(namespace) {
|
|
685
|
+
super();
|
|
686
|
+
this.namespace = namespace;
|
|
687
|
+
}
|
|
688
|
+
format(...text) {
|
|
689
|
+
const now = /* @__PURE__ */ new Date();
|
|
690
|
+
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")}`;
|
|
691
|
+
return `${timestamp}${this.namespace ? ` [${this.namespace}]` : ""} ${text.map((t) => typeof t == "string" ? t : JSONSanitize(t, 2)).join(" ")}`;
|
|
692
|
+
}
|
|
693
|
+
debug(...args) {
|
|
694
|
+
if (_Logger2.LOG_LEVEL < 4) return;
|
|
695
|
+
const str = this.format(...args);
|
|
696
|
+
_Logger2.emit(4, str);
|
|
697
|
+
console.debug(CliForeground.LIGHT_GREY + str + CliEffects.CLEAR);
|
|
698
|
+
}
|
|
699
|
+
log(...args) {
|
|
700
|
+
if (_Logger2.LOG_LEVEL < 3) return;
|
|
701
|
+
const str = this.format(...args);
|
|
702
|
+
_Logger2.emit(3, str);
|
|
703
|
+
console.log(CliEffects.CLEAR + str);
|
|
704
|
+
}
|
|
705
|
+
info(...args) {
|
|
706
|
+
if (_Logger2.LOG_LEVEL < 2) return;
|
|
707
|
+
const str = this.format(...args);
|
|
708
|
+
_Logger2.emit(2, str);
|
|
709
|
+
console.info(CliForeground.BLUE + str + CliEffects.CLEAR);
|
|
710
|
+
}
|
|
711
|
+
warn(...args) {
|
|
712
|
+
if (_Logger2.LOG_LEVEL < 1) return;
|
|
713
|
+
const str = this.format(...args);
|
|
714
|
+
_Logger2.emit(1, str);
|
|
715
|
+
console.warn(CliForeground.YELLOW + str + CliEffects.CLEAR);
|
|
716
|
+
}
|
|
717
|
+
error(...args) {
|
|
718
|
+
if (_Logger2.LOG_LEVEL < 0) return;
|
|
719
|
+
const str = this.format(...args);
|
|
720
|
+
_Logger2.emit(0, str);
|
|
721
|
+
console.error(CliForeground.RED + str + CliEffects.CLEAR);
|
|
722
|
+
}
|
|
723
|
+
};
|
|
724
|
+
__publicField2(_Logger, "LOG_LEVEL", 4);
|
|
725
|
+
var commonjsGlobal = typeof globalThis !== "undefined" ? globalThis : typeof window !== "undefined" ? window : typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : {};
|
|
726
|
+
var dist = {};
|
|
727
|
+
var persist$1 = {};
|
|
728
|
+
Object.defineProperty(persist$1, "__esModule", { value: true });
|
|
729
|
+
persist$1.persist = persist$1.Persist = void 0;
|
|
730
|
+
class Persist {
|
|
731
|
+
/**
|
|
732
|
+
* @param {string} key Primary key value will be stored under
|
|
733
|
+
* @param {PersistOptions<T>} options Configure using {@link PersistOptions}
|
|
734
|
+
*/
|
|
735
|
+
constructor(key, options = {}) {
|
|
736
|
+
__publicField2(this, "key");
|
|
737
|
+
__publicField2(this, "options");
|
|
738
|
+
__publicField2(this, "storage");
|
|
739
|
+
__publicField2(this, "watches", {});
|
|
740
|
+
__publicField2(this, "_value");
|
|
741
|
+
this.key = key;
|
|
742
|
+
this.options = options;
|
|
743
|
+
this.storage = options.storage || localStorage;
|
|
744
|
+
this.load();
|
|
745
|
+
}
|
|
746
|
+
/** Current value or default if undefined */
|
|
747
|
+
get value() {
|
|
748
|
+
var _a;
|
|
749
|
+
return this._value !== void 0 ? this._value : (_a = this.options) == null ? void 0 : _a.default;
|
|
750
|
+
}
|
|
751
|
+
/** Set value with proxy object wrapper to sync future changes */
|
|
752
|
+
set value(v) {
|
|
753
|
+
if (v == null || typeof v != "object")
|
|
754
|
+
this._value = v;
|
|
755
|
+
else
|
|
756
|
+
this._value = new Proxy(v, {
|
|
757
|
+
get: (target, p) => {
|
|
758
|
+
const f = typeof target[p] == "function";
|
|
759
|
+
if (!f)
|
|
760
|
+
return target[p];
|
|
761
|
+
return (...args) => {
|
|
762
|
+
const value = target[p](...args);
|
|
763
|
+
this.save();
|
|
764
|
+
return value;
|
|
765
|
+
};
|
|
766
|
+
},
|
|
767
|
+
set: (target, p, newValue) => {
|
|
768
|
+
target[p] = newValue;
|
|
769
|
+
this.save();
|
|
770
|
+
return true;
|
|
771
|
+
}
|
|
772
|
+
});
|
|
773
|
+
this.save();
|
|
774
|
+
}
|
|
775
|
+
/** Notify listeners of change */
|
|
776
|
+
notify(value) {
|
|
777
|
+
Object.values(this.watches).forEach((watch) => watch(value));
|
|
778
|
+
}
|
|
779
|
+
/** Delete value from storage */
|
|
780
|
+
clear() {
|
|
781
|
+
this.storage.removeItem(this.key);
|
|
782
|
+
}
|
|
783
|
+
/** Save current value to storage */
|
|
784
|
+
save() {
|
|
785
|
+
if (this._value === void 0)
|
|
786
|
+
this.clear();
|
|
787
|
+
else
|
|
788
|
+
this.storage.setItem(this.key, JSON.stringify(this._value));
|
|
789
|
+
this.notify(this.value);
|
|
790
|
+
}
|
|
791
|
+
/** Load value from storage */
|
|
792
|
+
load() {
|
|
793
|
+
if (this.storage[this.key] != void 0) {
|
|
794
|
+
let value = JSON.parse(this.storage.getItem(this.key));
|
|
795
|
+
if (value != null && typeof value == "object" && this.options.type)
|
|
796
|
+
value.__proto__ = this.options.type.prototype;
|
|
797
|
+
this.value = value;
|
|
798
|
+
} else
|
|
799
|
+
this.value = this.options.default || void 0;
|
|
800
|
+
}
|
|
801
|
+
/**
|
|
802
|
+
* Callback function which is run when there are changes
|
|
803
|
+
*
|
|
804
|
+
* @param {(value: T) => any} fn Callback will run on each change; it's passed the next value & it's return is ignored
|
|
805
|
+
* @returns {() => void} Function which will unsubscribe the watch/callback when called
|
|
806
|
+
*/
|
|
807
|
+
watch(fn2) {
|
|
808
|
+
const index = Object.keys(this.watches).length;
|
|
809
|
+
this.watches[index] = fn2;
|
|
810
|
+
return () => {
|
|
811
|
+
delete this.watches[index];
|
|
812
|
+
};
|
|
813
|
+
}
|
|
814
|
+
/**
|
|
815
|
+
* Return value as JSON string
|
|
816
|
+
*
|
|
817
|
+
* @returns {string} Stringified object as JSON
|
|
818
|
+
*/
|
|
819
|
+
toString() {
|
|
820
|
+
return JSON.stringify(this.value);
|
|
821
|
+
}
|
|
822
|
+
/**
|
|
823
|
+
* Return current value
|
|
824
|
+
*
|
|
825
|
+
* @returns {T} Current value
|
|
826
|
+
*/
|
|
827
|
+
valueOf() {
|
|
828
|
+
return this.value;
|
|
829
|
+
}
|
|
830
|
+
}
|
|
831
|
+
persist$1.Persist = Persist;
|
|
832
|
+
function persist(options) {
|
|
833
|
+
return (target, prop) => {
|
|
834
|
+
const key = (options == null ? void 0 : options.key) || `${target.constructor.name}.${prop.toString()}`;
|
|
835
|
+
const wrapper = new Persist(key, options);
|
|
836
|
+
Object.defineProperty(target, prop, {
|
|
837
|
+
get: function() {
|
|
838
|
+
return wrapper.value;
|
|
839
|
+
},
|
|
840
|
+
set: function(v) {
|
|
841
|
+
wrapper.value = v;
|
|
842
|
+
}
|
|
843
|
+
});
|
|
844
|
+
};
|
|
845
|
+
}
|
|
846
|
+
persist$1.persist = persist;
|
|
847
|
+
var memoryStorage = {};
|
|
848
|
+
Object.defineProperty(memoryStorage, "__esModule", { value: true });
|
|
849
|
+
memoryStorage.MemoryStorage = void 0;
|
|
850
|
+
class MemoryStorage {
|
|
851
|
+
get length() {
|
|
852
|
+
return Object.keys(this).length;
|
|
853
|
+
}
|
|
854
|
+
clear() {
|
|
855
|
+
Object.keys(this).forEach((k) => this.removeItem(k));
|
|
856
|
+
}
|
|
857
|
+
getItem(key) {
|
|
858
|
+
return this[key];
|
|
859
|
+
}
|
|
860
|
+
key(index) {
|
|
861
|
+
return Object.keys(this)[index];
|
|
862
|
+
}
|
|
863
|
+
removeItem(key) {
|
|
864
|
+
delete this[key];
|
|
865
|
+
}
|
|
866
|
+
setItem(key, value) {
|
|
867
|
+
this[key] = value;
|
|
868
|
+
}
|
|
869
|
+
}
|
|
870
|
+
memoryStorage.MemoryStorage = MemoryStorage;
|
|
871
|
+
(function(exports2) {
|
|
872
|
+
var __createBinding = commonjsGlobal && commonjsGlobal.__createBinding || (Object.create ? function(o, m, k, k2) {
|
|
873
|
+
if (k2 === void 0) k2 = k;
|
|
874
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
875
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
876
|
+
desc = { enumerable: true, get: function() {
|
|
877
|
+
return m[k];
|
|
878
|
+
} };
|
|
879
|
+
}
|
|
880
|
+
Object.defineProperty(o, k2, desc);
|
|
881
|
+
} : function(o, m, k, k2) {
|
|
882
|
+
if (k2 === void 0) k2 = k;
|
|
883
|
+
o[k2] = m[k];
|
|
884
|
+
});
|
|
885
|
+
var __exportStar = commonjsGlobal && commonjsGlobal.__exportStar || function(m, exports22) {
|
|
886
|
+
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports22, p)) __createBinding(exports22, m, p);
|
|
887
|
+
};
|
|
888
|
+
Object.defineProperty(exports2, "__esModule", { value: true });
|
|
889
|
+
__exportStar(persist$1, exports2);
|
|
890
|
+
__exportStar(memoryStorage, exports2);
|
|
891
|
+
})(dist);
|
|
892
|
+
var extendStatics = function(d, b) {
|
|
893
|
+
extendStatics = Object.setPrototypeOf || { __proto__: [] } instanceof Array && function(d2, b2) {
|
|
894
|
+
d2.__proto__ = b2;
|
|
895
|
+
} || function(d2, b2) {
|
|
896
|
+
for (var p in b2) if (Object.prototype.hasOwnProperty.call(b2, p)) d2[p] = b2[p];
|
|
897
|
+
};
|
|
898
|
+
return extendStatics(d, b);
|
|
899
|
+
};
|
|
900
|
+
function __extends(d, b) {
|
|
901
|
+
if (typeof b !== "function" && b !== null)
|
|
902
|
+
throw new TypeError("Class extends value " + String(b) + " is not a constructor or null");
|
|
903
|
+
extendStatics(d, b);
|
|
904
|
+
function __() {
|
|
905
|
+
this.constructor = d;
|
|
906
|
+
}
|
|
907
|
+
d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
|
|
908
|
+
}
|
|
909
|
+
function __values(o) {
|
|
910
|
+
var s = typeof Symbol === "function" && Symbol.iterator, m = s && o[s], i = 0;
|
|
911
|
+
if (m) return m.call(o);
|
|
912
|
+
if (o && typeof o.length === "number") return {
|
|
913
|
+
next: function() {
|
|
914
|
+
if (o && i >= o.length) o = void 0;
|
|
915
|
+
return { value: o && o[i++], done: !o };
|
|
916
|
+
}
|
|
917
|
+
};
|
|
918
|
+
throw new TypeError(s ? "Object is not iterable." : "Symbol.iterator is not defined.");
|
|
919
|
+
}
|
|
920
|
+
function __read(o, n) {
|
|
921
|
+
var m = typeof Symbol === "function" && o[Symbol.iterator];
|
|
922
|
+
if (!m) return o;
|
|
923
|
+
var i = m.call(o), r, ar = [], e;
|
|
924
|
+
try {
|
|
925
|
+
while ((n === void 0 || n-- > 0) && !(r = i.next()).done) ar.push(r.value);
|
|
926
|
+
} catch (error) {
|
|
927
|
+
e = { error };
|
|
928
|
+
} finally {
|
|
929
|
+
try {
|
|
930
|
+
if (r && !r.done && (m = i["return"])) m.call(i);
|
|
931
|
+
} finally {
|
|
932
|
+
if (e) throw e.error;
|
|
933
|
+
}
|
|
934
|
+
}
|
|
935
|
+
return ar;
|
|
936
|
+
}
|
|
937
|
+
function __spreadArray(to, from, pack) {
|
|
938
|
+
if (pack || arguments.length === 2) for (var i = 0, l = from.length, ar; i < l; i++) {
|
|
939
|
+
if (ar || !(i in from)) {
|
|
940
|
+
if (!ar) ar = Array.prototype.slice.call(from, 0, i);
|
|
941
|
+
ar[i] = from[i];
|
|
942
|
+
}
|
|
943
|
+
}
|
|
944
|
+
return to.concat(ar || Array.prototype.slice.call(from));
|
|
945
|
+
}
|
|
946
|
+
typeof SuppressedError === "function" ? SuppressedError : function(error, suppressed, message) {
|
|
947
|
+
var e = new Error(message);
|
|
948
|
+
return e.name = "SuppressedError", e.error = error, e.suppressed = suppressed, e;
|
|
949
|
+
};
|
|
950
|
+
function isFunction(value) {
|
|
951
|
+
return typeof value === "function";
|
|
952
|
+
}
|
|
953
|
+
function createErrorClass(createImpl) {
|
|
954
|
+
var _super = function(instance) {
|
|
955
|
+
Error.call(instance);
|
|
956
|
+
instance.stack = new Error().stack;
|
|
957
|
+
};
|
|
958
|
+
var ctorFunc = createImpl(_super);
|
|
959
|
+
ctorFunc.prototype = Object.create(Error.prototype);
|
|
960
|
+
ctorFunc.prototype.constructor = ctorFunc;
|
|
961
|
+
return ctorFunc;
|
|
962
|
+
}
|
|
963
|
+
var UnsubscriptionError = createErrorClass(function(_super) {
|
|
964
|
+
return function UnsubscriptionErrorImpl(errors) {
|
|
965
|
+
_super(this);
|
|
966
|
+
this.message = errors ? errors.length + " errors occurred during unsubscription:\n" + errors.map(function(err, i) {
|
|
967
|
+
return i + 1 + ") " + err.toString();
|
|
968
|
+
}).join("\n ") : "";
|
|
969
|
+
this.name = "UnsubscriptionError";
|
|
970
|
+
this.errors = errors;
|
|
971
|
+
};
|
|
972
|
+
});
|
|
973
|
+
function arrRemove(arr, item) {
|
|
974
|
+
if (arr) {
|
|
975
|
+
var index = arr.indexOf(item);
|
|
976
|
+
0 <= index && arr.splice(index, 1);
|
|
977
|
+
}
|
|
978
|
+
}
|
|
979
|
+
var Subscription = function() {
|
|
980
|
+
function Subscription2(initialTeardown) {
|
|
981
|
+
this.initialTeardown = initialTeardown;
|
|
982
|
+
this.closed = false;
|
|
983
|
+
this._parentage = null;
|
|
984
|
+
this._finalizers = null;
|
|
985
|
+
}
|
|
986
|
+
Subscription2.prototype.unsubscribe = function() {
|
|
987
|
+
var e_1, _a, e_2, _b;
|
|
988
|
+
var errors;
|
|
989
|
+
if (!this.closed) {
|
|
990
|
+
this.closed = true;
|
|
991
|
+
var _parentage = this._parentage;
|
|
992
|
+
if (_parentage) {
|
|
993
|
+
this._parentage = null;
|
|
994
|
+
if (Array.isArray(_parentage)) {
|
|
995
|
+
try {
|
|
996
|
+
for (var _parentage_1 = __values(_parentage), _parentage_1_1 = _parentage_1.next(); !_parentage_1_1.done; _parentage_1_1 = _parentage_1.next()) {
|
|
997
|
+
var parent_1 = _parentage_1_1.value;
|
|
998
|
+
parent_1.remove(this);
|
|
999
|
+
}
|
|
1000
|
+
} catch (e_1_1) {
|
|
1001
|
+
e_1 = { error: e_1_1 };
|
|
1002
|
+
} finally {
|
|
1003
|
+
try {
|
|
1004
|
+
if (_parentage_1_1 && !_parentage_1_1.done && (_a = _parentage_1.return)) _a.call(_parentage_1);
|
|
1005
|
+
} finally {
|
|
1006
|
+
if (e_1) throw e_1.error;
|
|
1007
|
+
}
|
|
1008
|
+
}
|
|
1009
|
+
} else {
|
|
1010
|
+
_parentage.remove(this);
|
|
1011
|
+
}
|
|
1012
|
+
}
|
|
1013
|
+
var initialFinalizer = this.initialTeardown;
|
|
1014
|
+
if (isFunction(initialFinalizer)) {
|
|
1015
|
+
try {
|
|
1016
|
+
initialFinalizer();
|
|
1017
|
+
} catch (e) {
|
|
1018
|
+
errors = e instanceof UnsubscriptionError ? e.errors : [e];
|
|
1019
|
+
}
|
|
1020
|
+
}
|
|
1021
|
+
var _finalizers = this._finalizers;
|
|
1022
|
+
if (_finalizers) {
|
|
1023
|
+
this._finalizers = null;
|
|
1024
|
+
try {
|
|
1025
|
+
for (var _finalizers_1 = __values(_finalizers), _finalizers_1_1 = _finalizers_1.next(); !_finalizers_1_1.done; _finalizers_1_1 = _finalizers_1.next()) {
|
|
1026
|
+
var finalizer = _finalizers_1_1.value;
|
|
1027
|
+
try {
|
|
1028
|
+
execFinalizer(finalizer);
|
|
1029
|
+
} catch (err) {
|
|
1030
|
+
errors = errors !== null && errors !== void 0 ? errors : [];
|
|
1031
|
+
if (err instanceof UnsubscriptionError) {
|
|
1032
|
+
errors = __spreadArray(__spreadArray([], __read(errors)), __read(err.errors));
|
|
1033
|
+
} else {
|
|
1034
|
+
errors.push(err);
|
|
1035
|
+
}
|
|
1036
|
+
}
|
|
1037
|
+
}
|
|
1038
|
+
} catch (e_2_1) {
|
|
1039
|
+
e_2 = { error: e_2_1 };
|
|
1040
|
+
} finally {
|
|
1041
|
+
try {
|
|
1042
|
+
if (_finalizers_1_1 && !_finalizers_1_1.done && (_b = _finalizers_1.return)) _b.call(_finalizers_1);
|
|
1043
|
+
} finally {
|
|
1044
|
+
if (e_2) throw e_2.error;
|
|
1045
|
+
}
|
|
1046
|
+
}
|
|
1047
|
+
}
|
|
1048
|
+
if (errors) {
|
|
1049
|
+
throw new UnsubscriptionError(errors);
|
|
1050
|
+
}
|
|
1051
|
+
}
|
|
1052
|
+
};
|
|
1053
|
+
Subscription2.prototype.add = function(teardown) {
|
|
1054
|
+
var _a;
|
|
1055
|
+
if (teardown && teardown !== this) {
|
|
1056
|
+
if (this.closed) {
|
|
1057
|
+
execFinalizer(teardown);
|
|
1058
|
+
} else {
|
|
1059
|
+
if (teardown instanceof Subscription2) {
|
|
1060
|
+
if (teardown.closed || teardown._hasParent(this)) {
|
|
1061
|
+
return;
|
|
1062
|
+
}
|
|
1063
|
+
teardown._addParent(this);
|
|
1064
|
+
}
|
|
1065
|
+
(this._finalizers = (_a = this._finalizers) !== null && _a !== void 0 ? _a : []).push(teardown);
|
|
1066
|
+
}
|
|
1067
|
+
}
|
|
1068
|
+
};
|
|
1069
|
+
Subscription2.prototype._hasParent = function(parent2) {
|
|
1070
|
+
var _parentage = this._parentage;
|
|
1071
|
+
return _parentage === parent2 || Array.isArray(_parentage) && _parentage.includes(parent2);
|
|
1072
|
+
};
|
|
1073
|
+
Subscription2.prototype._addParent = function(parent2) {
|
|
1074
|
+
var _parentage = this._parentage;
|
|
1075
|
+
this._parentage = Array.isArray(_parentage) ? (_parentage.push(parent2), _parentage) : _parentage ? [_parentage, parent2] : parent2;
|
|
1076
|
+
};
|
|
1077
|
+
Subscription2.prototype._removeParent = function(parent2) {
|
|
1078
|
+
var _parentage = this._parentage;
|
|
1079
|
+
if (_parentage === parent2) {
|
|
1080
|
+
this._parentage = null;
|
|
1081
|
+
} else if (Array.isArray(_parentage)) {
|
|
1082
|
+
arrRemove(_parentage, parent2);
|
|
1083
|
+
}
|
|
1084
|
+
};
|
|
1085
|
+
Subscription2.prototype.remove = function(teardown) {
|
|
1086
|
+
var _finalizers = this._finalizers;
|
|
1087
|
+
_finalizers && arrRemove(_finalizers, teardown);
|
|
1088
|
+
if (teardown instanceof Subscription2) {
|
|
1089
|
+
teardown._removeParent(this);
|
|
1090
|
+
}
|
|
1091
|
+
};
|
|
1092
|
+
Subscription2.EMPTY = function() {
|
|
1093
|
+
var empty = new Subscription2();
|
|
1094
|
+
empty.closed = true;
|
|
1095
|
+
return empty;
|
|
1096
|
+
}();
|
|
1097
|
+
return Subscription2;
|
|
1098
|
+
}();
|
|
1099
|
+
var EMPTY_SUBSCRIPTION = Subscription.EMPTY;
|
|
1100
|
+
function isSubscription(value) {
|
|
1101
|
+
return value instanceof Subscription || value && "closed" in value && isFunction(value.remove) && isFunction(value.add) && isFunction(value.unsubscribe);
|
|
1102
|
+
}
|
|
1103
|
+
function execFinalizer(finalizer) {
|
|
1104
|
+
if (isFunction(finalizer)) {
|
|
1105
|
+
finalizer();
|
|
1106
|
+
} else {
|
|
1107
|
+
finalizer.unsubscribe();
|
|
1108
|
+
}
|
|
1109
|
+
}
|
|
1110
|
+
var config = {
|
|
1111
|
+
Promise: void 0
|
|
1112
|
+
};
|
|
1113
|
+
var timeoutProvider = {
|
|
1114
|
+
setTimeout: function(handler, timeout) {
|
|
1115
|
+
var args = [];
|
|
1116
|
+
for (var _i = 2; _i < arguments.length; _i++) {
|
|
1117
|
+
args[_i - 2] = arguments[_i];
|
|
1118
|
+
}
|
|
1119
|
+
return setTimeout.apply(void 0, __spreadArray([handler, timeout], __read(args)));
|
|
1120
|
+
},
|
|
1121
|
+
clearTimeout: function(handle) {
|
|
1122
|
+
return clearTimeout(handle);
|
|
1123
|
+
},
|
|
1124
|
+
delegate: void 0
|
|
1125
|
+
};
|
|
1126
|
+
function reportUnhandledError(err) {
|
|
1127
|
+
timeoutProvider.setTimeout(function() {
|
|
1128
|
+
{
|
|
1129
|
+
throw err;
|
|
1130
|
+
}
|
|
1131
|
+
});
|
|
1132
|
+
}
|
|
1133
|
+
function noop() {
|
|
1134
|
+
}
|
|
1135
|
+
function errorContext(cb) {
|
|
1136
|
+
{
|
|
1137
|
+
cb();
|
|
1138
|
+
}
|
|
1139
|
+
}
|
|
1140
|
+
var Subscriber = function(_super) {
|
|
1141
|
+
__extends(Subscriber2, _super);
|
|
1142
|
+
function Subscriber2(destination) {
|
|
1143
|
+
var _this = _super.call(this) || this;
|
|
1144
|
+
_this.isStopped = false;
|
|
1145
|
+
if (destination) {
|
|
1146
|
+
_this.destination = destination;
|
|
1147
|
+
if (isSubscription(destination)) {
|
|
1148
|
+
destination.add(_this);
|
|
1149
|
+
}
|
|
1150
|
+
} else {
|
|
1151
|
+
_this.destination = EMPTY_OBSERVER;
|
|
1152
|
+
}
|
|
1153
|
+
return _this;
|
|
1154
|
+
}
|
|
1155
|
+
Subscriber2.create = function(next, error, complete) {
|
|
1156
|
+
return new SafeSubscriber(next, error, complete);
|
|
1157
|
+
};
|
|
1158
|
+
Subscriber2.prototype.next = function(value) {
|
|
1159
|
+
if (this.isStopped) ;
|
|
1160
|
+
else {
|
|
1161
|
+
this._next(value);
|
|
1162
|
+
}
|
|
1163
|
+
};
|
|
1164
|
+
Subscriber2.prototype.error = function(err) {
|
|
1165
|
+
if (this.isStopped) ;
|
|
1166
|
+
else {
|
|
1167
|
+
this.isStopped = true;
|
|
1168
|
+
this._error(err);
|
|
1169
|
+
}
|
|
1170
|
+
};
|
|
1171
|
+
Subscriber2.prototype.complete = function() {
|
|
1172
|
+
if (this.isStopped) ;
|
|
1173
|
+
else {
|
|
1174
|
+
this.isStopped = true;
|
|
1175
|
+
this._complete();
|
|
1176
|
+
}
|
|
1177
|
+
};
|
|
1178
|
+
Subscriber2.prototype.unsubscribe = function() {
|
|
1179
|
+
if (!this.closed) {
|
|
1180
|
+
this.isStopped = true;
|
|
1181
|
+
_super.prototype.unsubscribe.call(this);
|
|
1182
|
+
this.destination = null;
|
|
1183
|
+
}
|
|
1184
|
+
};
|
|
1185
|
+
Subscriber2.prototype._next = function(value) {
|
|
1186
|
+
this.destination.next(value);
|
|
1187
|
+
};
|
|
1188
|
+
Subscriber2.prototype._error = function(err) {
|
|
1189
|
+
try {
|
|
1190
|
+
this.destination.error(err);
|
|
1191
|
+
} finally {
|
|
1192
|
+
this.unsubscribe();
|
|
1193
|
+
}
|
|
1194
|
+
};
|
|
1195
|
+
Subscriber2.prototype._complete = function() {
|
|
1196
|
+
try {
|
|
1197
|
+
this.destination.complete();
|
|
1198
|
+
} finally {
|
|
1199
|
+
this.unsubscribe();
|
|
1200
|
+
}
|
|
1201
|
+
};
|
|
1202
|
+
return Subscriber2;
|
|
1203
|
+
}(Subscription);
|
|
1204
|
+
var ConsumerObserver = function() {
|
|
1205
|
+
function ConsumerObserver2(partialObserver) {
|
|
1206
|
+
this.partialObserver = partialObserver;
|
|
1207
|
+
}
|
|
1208
|
+
ConsumerObserver2.prototype.next = function(value) {
|
|
1209
|
+
var partialObserver = this.partialObserver;
|
|
1210
|
+
if (partialObserver.next) {
|
|
1211
|
+
try {
|
|
1212
|
+
partialObserver.next(value);
|
|
1213
|
+
} catch (error) {
|
|
1214
|
+
handleUnhandledError(error);
|
|
1215
|
+
}
|
|
1216
|
+
}
|
|
1217
|
+
};
|
|
1218
|
+
ConsumerObserver2.prototype.error = function(err) {
|
|
1219
|
+
var partialObserver = this.partialObserver;
|
|
1220
|
+
if (partialObserver.error) {
|
|
1221
|
+
try {
|
|
1222
|
+
partialObserver.error(err);
|
|
1223
|
+
} catch (error) {
|
|
1224
|
+
handleUnhandledError(error);
|
|
1225
|
+
}
|
|
1226
|
+
} else {
|
|
1227
|
+
handleUnhandledError(err);
|
|
1228
|
+
}
|
|
1229
|
+
};
|
|
1230
|
+
ConsumerObserver2.prototype.complete = function() {
|
|
1231
|
+
var partialObserver = this.partialObserver;
|
|
1232
|
+
if (partialObserver.complete) {
|
|
1233
|
+
try {
|
|
1234
|
+
partialObserver.complete();
|
|
1235
|
+
} catch (error) {
|
|
1236
|
+
handleUnhandledError(error);
|
|
1237
|
+
}
|
|
1238
|
+
}
|
|
1239
|
+
};
|
|
1240
|
+
return ConsumerObserver2;
|
|
1241
|
+
}();
|
|
1242
|
+
var SafeSubscriber = function(_super) {
|
|
1243
|
+
__extends(SafeSubscriber2, _super);
|
|
1244
|
+
function SafeSubscriber2(observerOrNext, error, complete) {
|
|
1245
|
+
var _this = _super.call(this) || this;
|
|
1246
|
+
var partialObserver;
|
|
1247
|
+
if (isFunction(observerOrNext) || !observerOrNext) {
|
|
1248
|
+
partialObserver = {
|
|
1249
|
+
next: observerOrNext !== null && observerOrNext !== void 0 ? observerOrNext : void 0,
|
|
1250
|
+
error: error !== null && error !== void 0 ? error : void 0,
|
|
1251
|
+
complete: complete !== null && complete !== void 0 ? complete : void 0
|
|
1252
|
+
};
|
|
1253
|
+
} else {
|
|
1254
|
+
{
|
|
1255
|
+
partialObserver = observerOrNext;
|
|
1256
|
+
}
|
|
1257
|
+
}
|
|
1258
|
+
_this.destination = new ConsumerObserver(partialObserver);
|
|
1259
|
+
return _this;
|
|
1260
|
+
}
|
|
1261
|
+
return SafeSubscriber2;
|
|
1262
|
+
}(Subscriber);
|
|
1263
|
+
function handleUnhandledError(error) {
|
|
1264
|
+
{
|
|
1265
|
+
reportUnhandledError(error);
|
|
1266
|
+
}
|
|
1267
|
+
}
|
|
1268
|
+
function defaultErrorHandler(err) {
|
|
1269
|
+
throw err;
|
|
1270
|
+
}
|
|
1271
|
+
var EMPTY_OBSERVER = {
|
|
1272
|
+
closed: true,
|
|
1273
|
+
next: noop,
|
|
1274
|
+
error: defaultErrorHandler,
|
|
1275
|
+
complete: noop
|
|
1276
|
+
};
|
|
1277
|
+
var observable = function() {
|
|
1278
|
+
return typeof Symbol === "function" && Symbol.observable || "@@observable";
|
|
1279
|
+
}();
|
|
1280
|
+
function identity(x) {
|
|
1281
|
+
return x;
|
|
1282
|
+
}
|
|
1283
|
+
function pipeFromArray(fns) {
|
|
1284
|
+
if (fns.length === 0) {
|
|
1285
|
+
return identity;
|
|
1286
|
+
}
|
|
1287
|
+
if (fns.length === 1) {
|
|
1288
|
+
return fns[0];
|
|
1289
|
+
}
|
|
1290
|
+
return function piped(input) {
|
|
1291
|
+
return fns.reduce(function(prev, fn) {
|
|
1292
|
+
return fn(prev);
|
|
1293
|
+
}, input);
|
|
1294
|
+
};
|
|
1295
|
+
}
|
|
1296
|
+
var Observable = function() {
|
|
1297
|
+
function Observable2(subscribe) {
|
|
1298
|
+
if (subscribe) {
|
|
1299
|
+
this._subscribe = subscribe;
|
|
1300
|
+
}
|
|
1301
|
+
}
|
|
1302
|
+
Observable2.prototype.lift = function(operator) {
|
|
1303
|
+
var observable2 = new Observable2();
|
|
1304
|
+
observable2.source = this;
|
|
1305
|
+
observable2.operator = operator;
|
|
1306
|
+
return observable2;
|
|
1307
|
+
};
|
|
1308
|
+
Observable2.prototype.subscribe = function(observerOrNext, error, complete) {
|
|
1309
|
+
var _this = this;
|
|
1310
|
+
var subscriber = isSubscriber(observerOrNext) ? observerOrNext : new SafeSubscriber(observerOrNext, error, complete);
|
|
1311
|
+
errorContext(function() {
|
|
1312
|
+
var _a = _this, operator = _a.operator, source = _a.source;
|
|
1313
|
+
subscriber.add(operator ? operator.call(subscriber, source) : source ? _this._subscribe(subscriber) : _this._trySubscribe(subscriber));
|
|
1314
|
+
});
|
|
1315
|
+
return subscriber;
|
|
1316
|
+
};
|
|
1317
|
+
Observable2.prototype._trySubscribe = function(sink) {
|
|
1318
|
+
try {
|
|
1319
|
+
return this._subscribe(sink);
|
|
1320
|
+
} catch (err) {
|
|
1321
|
+
sink.error(err);
|
|
1322
|
+
}
|
|
1323
|
+
};
|
|
1324
|
+
Observable2.prototype.forEach = function(next, promiseCtor) {
|
|
1325
|
+
var _this = this;
|
|
1326
|
+
promiseCtor = getPromiseCtor(promiseCtor);
|
|
1327
|
+
return new promiseCtor(function(resolve, reject) {
|
|
1328
|
+
var subscriber = new SafeSubscriber({
|
|
1329
|
+
next: function(value) {
|
|
1330
|
+
try {
|
|
1331
|
+
next(value);
|
|
1332
|
+
} catch (err) {
|
|
1333
|
+
reject(err);
|
|
1334
|
+
subscriber.unsubscribe();
|
|
1335
|
+
}
|
|
1336
|
+
},
|
|
1337
|
+
error: reject,
|
|
1338
|
+
complete: resolve
|
|
1339
|
+
});
|
|
1340
|
+
_this.subscribe(subscriber);
|
|
1341
|
+
});
|
|
1342
|
+
};
|
|
1343
|
+
Observable2.prototype._subscribe = function(subscriber) {
|
|
1344
|
+
var _a;
|
|
1345
|
+
return (_a = this.source) === null || _a === void 0 ? void 0 : _a.subscribe(subscriber);
|
|
1346
|
+
};
|
|
1347
|
+
Observable2.prototype[observable] = function() {
|
|
1348
|
+
return this;
|
|
1349
|
+
};
|
|
1350
|
+
Observable2.prototype.pipe = function() {
|
|
1351
|
+
var operations = [];
|
|
1352
|
+
for (var _i = 0; _i < arguments.length; _i++) {
|
|
1353
|
+
operations[_i] = arguments[_i];
|
|
1354
|
+
}
|
|
1355
|
+
return pipeFromArray(operations)(this);
|
|
1356
|
+
};
|
|
1357
|
+
Observable2.prototype.toPromise = function(promiseCtor) {
|
|
1358
|
+
var _this = this;
|
|
1359
|
+
promiseCtor = getPromiseCtor(promiseCtor);
|
|
1360
|
+
return new promiseCtor(function(resolve, reject) {
|
|
1361
|
+
var value;
|
|
1362
|
+
_this.subscribe(function(x) {
|
|
1363
|
+
return value = x;
|
|
1364
|
+
}, function(err) {
|
|
1365
|
+
return reject(err);
|
|
1366
|
+
}, function() {
|
|
1367
|
+
return resolve(value);
|
|
1368
|
+
});
|
|
1369
|
+
});
|
|
1370
|
+
};
|
|
1371
|
+
Observable2.create = function(subscribe) {
|
|
1372
|
+
return new Observable2(subscribe);
|
|
1373
|
+
};
|
|
1374
|
+
return Observable2;
|
|
1375
|
+
}();
|
|
1376
|
+
function getPromiseCtor(promiseCtor) {
|
|
1377
|
+
var _a;
|
|
1378
|
+
return (_a = promiseCtor !== null && promiseCtor !== void 0 ? promiseCtor : config.Promise) !== null && _a !== void 0 ? _a : Promise;
|
|
1379
|
+
}
|
|
1380
|
+
function isObserver(value) {
|
|
1381
|
+
return value && isFunction(value.next) && isFunction(value.error) && isFunction(value.complete);
|
|
1382
|
+
}
|
|
1383
|
+
function isSubscriber(value) {
|
|
1384
|
+
return value && value instanceof Subscriber || isObserver(value) && isSubscription(value);
|
|
1385
|
+
}
|
|
1386
|
+
function hasLift(source) {
|
|
1387
|
+
return isFunction(source === null || source === void 0 ? void 0 : source.lift);
|
|
1388
|
+
}
|
|
1389
|
+
function operate(init) {
|
|
1390
|
+
return function(source) {
|
|
1391
|
+
if (hasLift(source)) {
|
|
1392
|
+
return source.lift(function(liftedSource) {
|
|
1393
|
+
try {
|
|
1394
|
+
return init(liftedSource, this);
|
|
1395
|
+
} catch (err) {
|
|
1396
|
+
this.error(err);
|
|
1397
|
+
}
|
|
1398
|
+
});
|
|
1399
|
+
}
|
|
1400
|
+
throw new TypeError("Unable to lift unknown Observable type");
|
|
1401
|
+
};
|
|
1402
|
+
}
|
|
1403
|
+
function createOperatorSubscriber(destination, onNext, onComplete, onError, onFinalize) {
|
|
1404
|
+
return new OperatorSubscriber(destination, onNext, onComplete, onError, onFinalize);
|
|
1405
|
+
}
|
|
1406
|
+
var OperatorSubscriber = function(_super) {
|
|
1407
|
+
__extends(OperatorSubscriber2, _super);
|
|
1408
|
+
function OperatorSubscriber2(destination, onNext, onComplete, onError, onFinalize, shouldUnsubscribe) {
|
|
1409
|
+
var _this = _super.call(this, destination) || this;
|
|
1410
|
+
_this.onFinalize = onFinalize;
|
|
1411
|
+
_this.shouldUnsubscribe = shouldUnsubscribe;
|
|
1412
|
+
_this._next = onNext ? function(value) {
|
|
1413
|
+
try {
|
|
1414
|
+
onNext(value);
|
|
1415
|
+
} catch (err) {
|
|
1416
|
+
destination.error(err);
|
|
1417
|
+
}
|
|
1418
|
+
} : _super.prototype._next;
|
|
1419
|
+
_this._error = onError ? function(err) {
|
|
1420
|
+
try {
|
|
1421
|
+
onError(err);
|
|
1422
|
+
} catch (err2) {
|
|
1423
|
+
destination.error(err2);
|
|
1424
|
+
} finally {
|
|
1425
|
+
this.unsubscribe();
|
|
1426
|
+
}
|
|
1427
|
+
} : _super.prototype._error;
|
|
1428
|
+
_this._complete = onComplete ? function() {
|
|
1429
|
+
try {
|
|
1430
|
+
onComplete();
|
|
1431
|
+
} catch (err) {
|
|
1432
|
+
destination.error(err);
|
|
1433
|
+
} finally {
|
|
1434
|
+
this.unsubscribe();
|
|
1435
|
+
}
|
|
1436
|
+
} : _super.prototype._complete;
|
|
1437
|
+
return _this;
|
|
1438
|
+
}
|
|
1439
|
+
OperatorSubscriber2.prototype.unsubscribe = function() {
|
|
1440
|
+
var _a;
|
|
1441
|
+
if (!this.shouldUnsubscribe || this.shouldUnsubscribe()) {
|
|
1442
|
+
var closed_1 = this.closed;
|
|
1443
|
+
_super.prototype.unsubscribe.call(this);
|
|
1444
|
+
!closed_1 && ((_a = this.onFinalize) === null || _a === void 0 ? void 0 : _a.call(this));
|
|
1445
|
+
}
|
|
1446
|
+
};
|
|
1447
|
+
return OperatorSubscriber2;
|
|
1448
|
+
}(Subscriber);
|
|
1449
|
+
var ObjectUnsubscribedError = createErrorClass(function(_super) {
|
|
1450
|
+
return function ObjectUnsubscribedErrorImpl() {
|
|
1451
|
+
_super(this);
|
|
1452
|
+
this.name = "ObjectUnsubscribedError";
|
|
1453
|
+
this.message = "object unsubscribed";
|
|
1454
|
+
};
|
|
1455
|
+
});
|
|
1456
|
+
var Subject = function(_super) {
|
|
1457
|
+
__extends(Subject2, _super);
|
|
1458
|
+
function Subject2() {
|
|
1459
|
+
var _this = _super.call(this) || this;
|
|
1460
|
+
_this.closed = false;
|
|
1461
|
+
_this.currentObservers = null;
|
|
1462
|
+
_this.observers = [];
|
|
1463
|
+
_this.isStopped = false;
|
|
1464
|
+
_this.hasError = false;
|
|
1465
|
+
_this.thrownError = null;
|
|
1466
|
+
return _this;
|
|
1467
|
+
}
|
|
1468
|
+
Subject2.prototype.lift = function(operator) {
|
|
1469
|
+
var subject = new AnonymousSubject(this, this);
|
|
1470
|
+
subject.operator = operator;
|
|
1471
|
+
return subject;
|
|
1472
|
+
};
|
|
1473
|
+
Subject2.prototype._throwIfClosed = function() {
|
|
1474
|
+
if (this.closed) {
|
|
1475
|
+
throw new ObjectUnsubscribedError();
|
|
1476
|
+
}
|
|
1477
|
+
};
|
|
1478
|
+
Subject2.prototype.next = function(value) {
|
|
1479
|
+
var _this = this;
|
|
1480
|
+
errorContext(function() {
|
|
1481
|
+
var e_1, _a;
|
|
1482
|
+
_this._throwIfClosed();
|
|
1483
|
+
if (!_this.isStopped) {
|
|
1484
|
+
if (!_this.currentObservers) {
|
|
1485
|
+
_this.currentObservers = Array.from(_this.observers);
|
|
1486
|
+
}
|
|
1487
|
+
try {
|
|
1488
|
+
for (var _b = __values(_this.currentObservers), _c = _b.next(); !_c.done; _c = _b.next()) {
|
|
1489
|
+
var observer = _c.value;
|
|
1490
|
+
observer.next(value);
|
|
1491
|
+
}
|
|
1492
|
+
} catch (e_1_1) {
|
|
1493
|
+
e_1 = { error: e_1_1 };
|
|
1494
|
+
} finally {
|
|
1495
|
+
try {
|
|
1496
|
+
if (_c && !_c.done && (_a = _b.return)) _a.call(_b);
|
|
1497
|
+
} finally {
|
|
1498
|
+
if (e_1) throw e_1.error;
|
|
1499
|
+
}
|
|
1500
|
+
}
|
|
1501
|
+
}
|
|
1502
|
+
});
|
|
1503
|
+
};
|
|
1504
|
+
Subject2.prototype.error = function(err) {
|
|
1505
|
+
var _this = this;
|
|
1506
|
+
errorContext(function() {
|
|
1507
|
+
_this._throwIfClosed();
|
|
1508
|
+
if (!_this.isStopped) {
|
|
1509
|
+
_this.hasError = _this.isStopped = true;
|
|
1510
|
+
_this.thrownError = err;
|
|
1511
|
+
var observers = _this.observers;
|
|
1512
|
+
while (observers.length) {
|
|
1513
|
+
observers.shift().error(err);
|
|
1514
|
+
}
|
|
1515
|
+
}
|
|
1516
|
+
});
|
|
1517
|
+
};
|
|
1518
|
+
Subject2.prototype.complete = function() {
|
|
1519
|
+
var _this = this;
|
|
1520
|
+
errorContext(function() {
|
|
1521
|
+
_this._throwIfClosed();
|
|
1522
|
+
if (!_this.isStopped) {
|
|
1523
|
+
_this.isStopped = true;
|
|
1524
|
+
var observers = _this.observers;
|
|
1525
|
+
while (observers.length) {
|
|
1526
|
+
observers.shift().complete();
|
|
1527
|
+
}
|
|
1528
|
+
}
|
|
1529
|
+
});
|
|
1530
|
+
};
|
|
1531
|
+
Subject2.prototype.unsubscribe = function() {
|
|
1532
|
+
this.isStopped = this.closed = true;
|
|
1533
|
+
this.observers = this.currentObservers = null;
|
|
1534
|
+
};
|
|
1535
|
+
Object.defineProperty(Subject2.prototype, "observed", {
|
|
1536
|
+
get: function() {
|
|
1537
|
+
var _a;
|
|
1538
|
+
return ((_a = this.observers) === null || _a === void 0 ? void 0 : _a.length) > 0;
|
|
1539
|
+
},
|
|
1540
|
+
enumerable: false,
|
|
1541
|
+
configurable: true
|
|
1542
|
+
});
|
|
1543
|
+
Subject2.prototype._trySubscribe = function(subscriber) {
|
|
1544
|
+
this._throwIfClosed();
|
|
1545
|
+
return _super.prototype._trySubscribe.call(this, subscriber);
|
|
1546
|
+
};
|
|
1547
|
+
Subject2.prototype._subscribe = function(subscriber) {
|
|
1548
|
+
this._throwIfClosed();
|
|
1549
|
+
this._checkFinalizedStatuses(subscriber);
|
|
1550
|
+
return this._innerSubscribe(subscriber);
|
|
1551
|
+
};
|
|
1552
|
+
Subject2.prototype._innerSubscribe = function(subscriber) {
|
|
1553
|
+
var _this = this;
|
|
1554
|
+
var _a = this, hasError = _a.hasError, isStopped = _a.isStopped, observers = _a.observers;
|
|
1555
|
+
if (hasError || isStopped) {
|
|
1556
|
+
return EMPTY_SUBSCRIPTION;
|
|
1557
|
+
}
|
|
1558
|
+
this.currentObservers = null;
|
|
1559
|
+
observers.push(subscriber);
|
|
1560
|
+
return new Subscription(function() {
|
|
1561
|
+
_this.currentObservers = null;
|
|
1562
|
+
arrRemove(observers, subscriber);
|
|
1563
|
+
});
|
|
1564
|
+
};
|
|
1565
|
+
Subject2.prototype._checkFinalizedStatuses = function(subscriber) {
|
|
1566
|
+
var _a = this, hasError = _a.hasError, thrownError = _a.thrownError, isStopped = _a.isStopped;
|
|
1567
|
+
if (hasError) {
|
|
1568
|
+
subscriber.error(thrownError);
|
|
1569
|
+
} else if (isStopped) {
|
|
1570
|
+
subscriber.complete();
|
|
1571
|
+
}
|
|
1572
|
+
};
|
|
1573
|
+
Subject2.prototype.asObservable = function() {
|
|
1574
|
+
var observable2 = new Observable();
|
|
1575
|
+
observable2.source = this;
|
|
1576
|
+
return observable2;
|
|
1577
|
+
};
|
|
1578
|
+
Subject2.create = function(destination, source) {
|
|
1579
|
+
return new AnonymousSubject(destination, source);
|
|
1580
|
+
};
|
|
1581
|
+
return Subject2;
|
|
1582
|
+
}(Observable);
|
|
1583
|
+
var AnonymousSubject = function(_super) {
|
|
1584
|
+
__extends(AnonymousSubject2, _super);
|
|
1585
|
+
function AnonymousSubject2(destination, source) {
|
|
1586
|
+
var _this = _super.call(this) || this;
|
|
1587
|
+
_this.destination = destination;
|
|
1588
|
+
_this.source = source;
|
|
1589
|
+
return _this;
|
|
1590
|
+
}
|
|
1591
|
+
AnonymousSubject2.prototype.next = function(value) {
|
|
1592
|
+
var _a, _b;
|
|
1593
|
+
(_b = (_a = this.destination) === null || _a === void 0 ? void 0 : _a.next) === null || _b === void 0 ? void 0 : _b.call(_a, value);
|
|
1594
|
+
};
|
|
1595
|
+
AnonymousSubject2.prototype.error = function(err) {
|
|
1596
|
+
var _a, _b;
|
|
1597
|
+
(_b = (_a = this.destination) === null || _a === void 0 ? void 0 : _a.error) === null || _b === void 0 ? void 0 : _b.call(_a, err);
|
|
1598
|
+
};
|
|
1599
|
+
AnonymousSubject2.prototype.complete = function() {
|
|
1600
|
+
var _a, _b;
|
|
1601
|
+
(_b = (_a = this.destination) === null || _a === void 0 ? void 0 : _a.complete) === null || _b === void 0 ? void 0 : _b.call(_a);
|
|
1602
|
+
};
|
|
1603
|
+
AnonymousSubject2.prototype._subscribe = function(subscriber) {
|
|
1604
|
+
var _a, _b;
|
|
1605
|
+
return (_b = (_a = this.source) === null || _a === void 0 ? void 0 : _a.subscribe(subscriber)) !== null && _b !== void 0 ? _b : EMPTY_SUBSCRIPTION;
|
|
1606
|
+
};
|
|
1607
|
+
return AnonymousSubject2;
|
|
1608
|
+
}(Subject);
|
|
1609
|
+
var BehaviorSubject = function(_super) {
|
|
1610
|
+
__extends(BehaviorSubject2, _super);
|
|
1611
|
+
function BehaviorSubject2(_value) {
|
|
1612
|
+
var _this = _super.call(this) || this;
|
|
1613
|
+
_this._value = _value;
|
|
1614
|
+
return _this;
|
|
1615
|
+
}
|
|
1616
|
+
Object.defineProperty(BehaviorSubject2.prototype, "value", {
|
|
1617
|
+
get: function() {
|
|
1618
|
+
return this.getValue();
|
|
1619
|
+
},
|
|
1620
|
+
enumerable: false,
|
|
1621
|
+
configurable: true
|
|
1622
|
+
});
|
|
1623
|
+
BehaviorSubject2.prototype._subscribe = function(subscriber) {
|
|
1624
|
+
var subscription = _super.prototype._subscribe.call(this, subscriber);
|
|
1625
|
+
!subscription.closed && subscriber.next(this._value);
|
|
1626
|
+
return subscription;
|
|
1627
|
+
};
|
|
1628
|
+
BehaviorSubject2.prototype.getValue = function() {
|
|
1629
|
+
var _a = this, hasError = _a.hasError, thrownError = _a.thrownError, _value = _a._value;
|
|
1630
|
+
if (hasError) {
|
|
1631
|
+
throw thrownError;
|
|
1632
|
+
}
|
|
1633
|
+
this._throwIfClosed();
|
|
1634
|
+
return _value;
|
|
1635
|
+
};
|
|
1636
|
+
BehaviorSubject2.prototype.next = function(value) {
|
|
1637
|
+
_super.prototype.next.call(this, this._value = value);
|
|
1638
|
+
};
|
|
1639
|
+
return BehaviorSubject2;
|
|
1640
|
+
}(Subject);
|
|
1641
|
+
var EmptyError = createErrorClass(function(_super) {
|
|
1642
|
+
return function EmptyErrorImpl() {
|
|
1643
|
+
_super(this);
|
|
1644
|
+
this.name = "EmptyError";
|
|
1645
|
+
this.message = "no elements in sequence";
|
|
1646
|
+
};
|
|
1647
|
+
});
|
|
1648
|
+
function lastValueFrom(source, config2) {
|
|
1649
|
+
return new Promise(function(resolve, reject) {
|
|
1650
|
+
var _hasValue = false;
|
|
1651
|
+
var _value;
|
|
1652
|
+
source.subscribe({
|
|
1653
|
+
next: function(value) {
|
|
1654
|
+
_value = value;
|
|
1655
|
+
_hasValue = true;
|
|
1656
|
+
},
|
|
1657
|
+
error: reject,
|
|
1658
|
+
complete: function() {
|
|
1659
|
+
if (_hasValue) {
|
|
1660
|
+
resolve(_value);
|
|
1661
|
+
} else {
|
|
1662
|
+
reject(new EmptyError());
|
|
1663
|
+
}
|
|
1664
|
+
}
|
|
1665
|
+
});
|
|
1666
|
+
});
|
|
1667
|
+
}
|
|
1668
|
+
function filter(predicate, thisArg) {
|
|
1669
|
+
return operate(function(source, subscriber) {
|
|
1670
|
+
var index = 0;
|
|
1671
|
+
source.subscribe(createOperatorSubscriber(subscriber, function(value) {
|
|
1672
|
+
return predicate.call(thisArg, value, index++) && subscriber.next(value);
|
|
1673
|
+
}));
|
|
1674
|
+
});
|
|
1675
|
+
}
|
|
1676
|
+
function distinctUntilChanged(comparator, keySelector) {
|
|
1677
|
+
if (keySelector === void 0) {
|
|
1678
|
+
keySelector = identity;
|
|
1679
|
+
}
|
|
1680
|
+
comparator = comparator !== null && comparator !== void 0 ? comparator : defaultCompare;
|
|
1681
|
+
return operate(function(source, subscriber) {
|
|
1682
|
+
var previousKey;
|
|
1683
|
+
var first = true;
|
|
1684
|
+
source.subscribe(createOperatorSubscriber(subscriber, function(value) {
|
|
1685
|
+
var currentKey = keySelector(value);
|
|
1686
|
+
if (first || !comparator(previousKey, currentKey)) {
|
|
1687
|
+
first = false;
|
|
1688
|
+
previousKey = currentKey;
|
|
1689
|
+
subscriber.next(value);
|
|
1690
|
+
}
|
|
1691
|
+
}));
|
|
1692
|
+
});
|
|
1693
|
+
}
|
|
1694
|
+
function defaultCompare(a, b) {
|
|
1695
|
+
return a === b;
|
|
1696
|
+
}
|
|
1697
|
+
function skip(count) {
|
|
1698
|
+
return filter(function(_, index) {
|
|
1699
|
+
return count <= index;
|
|
1700
|
+
});
|
|
1701
|
+
}
|
|
1702
|
+
function takeWhile(predicate, inclusive) {
|
|
1703
|
+
return operate(function(source, subscriber) {
|
|
1704
|
+
var index = 0;
|
|
1705
|
+
source.subscribe(createOperatorSubscriber(subscriber, function(value) {
|
|
1706
|
+
var result = predicate(value, index++);
|
|
1707
|
+
(result || inclusive) && subscriber.next(value);
|
|
1708
|
+
!result && subscriber.complete();
|
|
1709
|
+
}));
|
|
1710
|
+
});
|
|
1711
|
+
}
|
|
1712
|
+
async function getTheme(spoke, scope) {
|
|
1713
|
+
let theme = await fetch(`https://${spoke}.auxiliumgroup.com/api/js/auxilium/dijits/templates/login/${spoke}/theme.json`).then((res) => res.json()).catch(() => null);
|
|
1714
|
+
if (scope && theme != null && theme[scope]) theme = { ...theme, ...theme[scope] };
|
|
1715
|
+
return {
|
|
1716
|
+
found: !!theme,
|
|
1717
|
+
background: `https://${spoke}.auxiliumgroup.com/static/js/auxilium/dijits/templates/login/${spoke}/background.jpg`,
|
|
1718
|
+
backgroundColor: void 0,
|
|
1719
|
+
color: "#c83232",
|
|
1720
|
+
glow: "#c83232",
|
|
1721
|
+
logo: `https://${spoke}.auxiliumgroup.com/static/js/auxilium/dijits/templates/login/${spoke}/logo.png`,
|
|
1722
|
+
hideApps: false,
|
|
1723
|
+
persist: true,
|
|
1724
|
+
title: spoke.toUpperCase(),
|
|
1725
|
+
textColor: "white",
|
|
1726
|
+
titleFontFamily: "sans-serif",
|
|
1727
|
+
titleFontUrl: "https://fonts.cdnfonts.com/css/ar-blanca",
|
|
1728
|
+
titleFontSize: "45px",
|
|
1729
|
+
titleTextShadow: "0 0 3px black",
|
|
1730
|
+
subtitle: "",
|
|
1731
|
+
subtitleFontFamily: "sans-serif",
|
|
1732
|
+
subtitleFontUrl: "",
|
|
1733
|
+
subtitleFontSize: "36px",
|
|
1734
|
+
subtitleTextColor: "white",
|
|
1735
|
+
subtitleTextShadow: "0 0 3px black",
|
|
1736
|
+
...theme || {}
|
|
1737
|
+
};
|
|
1738
|
+
}
|
|
1739
|
+
const _LoginPrompt = class _LoginPrompt {
|
|
1740
|
+
constructor(api, spoke, options = {}) {
|
|
1741
|
+
__publicField(this, "alert");
|
|
1742
|
+
__publicField(this, "button");
|
|
1743
|
+
__publicField(this, "form");
|
|
1744
|
+
__publicField(this, "password");
|
|
1745
|
+
__publicField(this, "persist");
|
|
1746
|
+
__publicField(this, "username");
|
|
1747
|
+
__publicField(this, "_done");
|
|
1748
|
+
/** Promise which resolves once login is complete */
|
|
1749
|
+
__publicField(this, "done", new Promise((res) => {
|
|
1750
|
+
this._done = res;
|
|
1751
|
+
}));
|
|
1752
|
+
this.api = api;
|
|
1753
|
+
this.spoke = spoke;
|
|
1754
|
+
this.options = options;
|
|
1755
|
+
this.themeDefaults().then(() => this.render());
|
|
1756
|
+
}
|
|
1757
|
+
async render() {
|
|
1758
|
+
this.close();
|
|
1759
|
+
document.head.innerHTML += _LoginPrompt.css(this.options);
|
|
1760
|
+
const div = document.createElement("div");
|
|
1761
|
+
div.innerHTML = _LoginPrompt.template(this.options);
|
|
1762
|
+
document.body.appendChild(div);
|
|
1763
|
+
this.alert = document.querySelector("#datalynk-login-alert");
|
|
1764
|
+
this.button = document.querySelector("#datalynk-login-form button");
|
|
1765
|
+
this.form = document.querySelector("#datalynk-login-form");
|
|
1766
|
+
this.password = document.querySelector('#datalynk-login-form input[name="password"]');
|
|
1767
|
+
this.persist = document.querySelector('#datalynk-login-form input[name="persist"]');
|
|
1768
|
+
this.username = document.querySelector('#datalynk-login-form input[name="username"]');
|
|
1769
|
+
if (this.options.persist === false) this.persist.parentElement.remove();
|
|
1770
|
+
this.form.onsubmit = (event) => this.login(event);
|
|
1771
|
+
}
|
|
1772
|
+
async themeDefaults() {
|
|
1773
|
+
const theme = await getTheme(this.spoke, "login");
|
|
1774
|
+
this.options = {
|
|
1775
|
+
logoOnly: !this.options.title && !theme.found,
|
|
1776
|
+
...theme,
|
|
1777
|
+
...clean(this.options, true)
|
|
1778
|
+
};
|
|
1779
|
+
}
|
|
1780
|
+
/** Close the login prompt */
|
|
1781
|
+
close() {
|
|
1782
|
+
var _a, _b;
|
|
1783
|
+
(_a = document.querySelector("#datalynk-login-css")) == null ? void 0 : _a.remove();
|
|
1784
|
+
(_b = document.querySelector("#datalynk-login")) == null ? void 0 : _b.remove();
|
|
1785
|
+
}
|
|
1786
|
+
/** Check if login prompt is still open */
|
|
1787
|
+
isOpen() {
|
|
1788
|
+
return !!document.querySelector("#datalynk-login");
|
|
1789
|
+
}
|
|
1790
|
+
/** Login form submit event */
|
|
1791
|
+
login(event) {
|
|
1792
|
+
event.preventDefault();
|
|
1793
|
+
const data = new FormData(event.target);
|
|
1794
|
+
this.alert.classList.add("hidden");
|
|
1795
|
+
this.username.disabled = true;
|
|
1796
|
+
this.password.disabled = true;
|
|
1797
|
+
this.persist.disabled = true;
|
|
1798
|
+
this.button.disabled = true;
|
|
1799
|
+
return this.api.auth.login(
|
|
1800
|
+
this.spoke,
|
|
1801
|
+
data.get("username"),
|
|
1802
|
+
data.get("password"),
|
|
1803
|
+
{ expire: this.persist.checked ? null : void 0 }
|
|
1804
|
+
).then((data2) => {
|
|
1805
|
+
this.close();
|
|
1806
|
+
this._done();
|
|
1807
|
+
return data2;
|
|
1808
|
+
}).catch((err) => {
|
|
1809
|
+
this.alert.classList.remove("hidden");
|
|
1810
|
+
this.alert.innerHTML = err.message;
|
|
1811
|
+
this.password.value = "";
|
|
1812
|
+
this.username.disabled = false;
|
|
1813
|
+
this.password.disabled = false;
|
|
1814
|
+
this.persist.disabled = false;
|
|
1815
|
+
this.button.disabled = false;
|
|
1816
|
+
});
|
|
1817
|
+
}
|
|
1818
|
+
};
|
|
1819
|
+
/** Dynamically create CSS style */
|
|
1820
|
+
__publicField(_LoginPrompt, "css", (options) => `
|
|
1821
|
+
<style id="datalynk-login-styles">
|
|
1822
|
+
@import url('https://fonts.cdnfonts.com/css/ar-blanca');
|
|
1823
|
+
${options.titleFontUrl ? `@import url('${options.titleFontUrl}');` : ""}
|
|
1824
|
+
${options.subtitleFontUrl ? `@import url('${options.subtitleFontUrl}');` : ""}
|
|
1825
|
+
|
|
1826
|
+
#datalynk-login {
|
|
1827
|
+
--theme-background: ${options.backgroundColor ? options.backgroundColor : `url(${options.background})`};
|
|
1828
|
+
--theme-container: #000000cc;
|
|
1829
|
+
--theme-glow: ${options.glow || options.color};
|
|
1830
|
+
--theme-primary: ${options.color};
|
|
1831
|
+
--theme-text: ${options.textColor};
|
|
1832
|
+
|
|
1833
|
+
position: fixed;
|
|
1834
|
+
left: 0;
|
|
1835
|
+
top: 0;
|
|
1836
|
+
right: 0;
|
|
1837
|
+
bottom: 0;
|
|
1838
|
+
background: var(--theme-background);
|
|
1839
|
+
background-repeat: no-repeat;
|
|
1840
|
+
background-size: cover;
|
|
1841
|
+
font-family: sans-serif;
|
|
1842
|
+
z-index: 1000;
|
|
1843
|
+
}
|
|
1844
|
+
|
|
1845
|
+
#datalynk-login .added-links {
|
|
1846
|
+
color: var(--theme-text);
|
|
1847
|
+
position: fixed;
|
|
1848
|
+
bottom: 0;
|
|
1849
|
+
right: 0;
|
|
1850
|
+
padding: 0.25rem;
|
|
1851
|
+
}
|
|
1852
|
+
|
|
1853
|
+
#datalynk-login .added-links a, #datalynk-login .added-links a:hover, #datalynk-login .added-links a:visited {
|
|
1854
|
+
color: var(--theme-text);
|
|
1855
|
+
text-shadow: 0 0 10px black;
|
|
1856
|
+
}
|
|
1857
|
+
|
|
1858
|
+
#datalynk-login-alert {
|
|
1859
|
+
padding: 0.75rem;
|
|
1860
|
+
background: rgba(0,0,0,0.5);
|
|
1861
|
+
color: white;
|
|
1862
|
+
border-radius: 5px;
|
|
1863
|
+
margin-bottom: 1rem;
|
|
1864
|
+
border: grey 1px solid;
|
|
1865
|
+
}
|
|
1866
|
+
|
|
1867
|
+
#datalynk-login label {
|
|
1868
|
+
color: white;
|
|
1869
|
+
font-size: 20px;
|
|
1870
|
+
}
|
|
1871
|
+
|
|
1872
|
+
#datalynk-login input {
|
|
1873
|
+
width: calc(100% - 20px);
|
|
1874
|
+
padding: 12px 9px 9px 9px;
|
|
1875
|
+
margin: 1px;
|
|
1876
|
+
border: 1px solid #ddd;
|
|
1877
|
+
border-radius: 5px;
|
|
1878
|
+
background-color: white;
|
|
1879
|
+
color: black;
|
|
1880
|
+
}
|
|
1881
|
+
|
|
1882
|
+
#datalynk-login .login-container {
|
|
1883
|
+
position: fixed;
|
|
1884
|
+
top: 50%;
|
|
1885
|
+
left: 0;
|
|
1886
|
+
right: 0;
|
|
1887
|
+
transform: translateY(-50%);
|
|
1888
|
+
}
|
|
1889
|
+
|
|
1890
|
+
#datalynk-login .login-header {
|
|
1891
|
+
display: flex;
|
|
1892
|
+
justify-content: center;
|
|
1893
|
+
align-items: center;
|
|
1894
|
+
color: var(--theme-text);
|
|
1895
|
+
text-align: center;
|
|
1896
|
+
font-size: 32px;
|
|
1897
|
+
margin-bottom: 2rem;
|
|
1898
|
+
}
|
|
1899
|
+
|
|
1900
|
+
#datalynk-login .login-title {
|
|
1901
|
+
font-family: ${options.titleFontFamily || "sans-serif"};
|
|
1902
|
+
font-size: ${options.titleFontSize || "32px"};
|
|
1903
|
+
${options.titleTextShadow ? `text-shadow: ${options.titleTextShadow};` : ""}
|
|
1904
|
+
}
|
|
1905
|
+
|
|
1906
|
+
#datalynk-login .login-subtitle {
|
|
1907
|
+
font-family: ${options.subtitleFontFamily || "sans-serif"};
|
|
1908
|
+
font-size: ${options.subtitleFontSize || "20px"};
|
|
1909
|
+
color: ${options.subtitleTextColor || "white"};
|
|
1910
|
+
${options.subtitleTextShadow ? `text-shadow: ${options.subtitleTextShadow};` : ""}
|
|
1911
|
+
margin-top: 0.5rem;
|
|
1912
|
+
}
|
|
1913
|
+
|
|
1914
|
+
#datalynk-login .login-content {
|
|
1915
|
+
display: flex;
|
|
1916
|
+
flex-direction: column;
|
|
1917
|
+
align-items: center;
|
|
1918
|
+
background: var(--theme-container);
|
|
1919
|
+
border-top: var(--theme-glow) 1px solid;
|
|
1920
|
+
box-shadow: 0 -10px 20px -10px var(--theme-glow);
|
|
1921
|
+
}
|
|
1922
|
+
|
|
1923
|
+
#datalynk-login .login-body {
|
|
1924
|
+
padding: ${options.hideApps ? "3.5rem 0" : "3.5rem 0 1.5rem 0"};
|
|
1925
|
+
width: 100%;
|
|
1926
|
+
max-width: 400px;;
|
|
1927
|
+
color: white;
|
|
1928
|
+
}
|
|
1929
|
+
|
|
1930
|
+
#datalynk-login input:disabled {
|
|
1931
|
+
color: #333;
|
|
1932
|
+
background-color: #ccc;
|
|
1933
|
+
}
|
|
1934
|
+
|
|
1935
|
+
#datalynk-login input[type="checkbox"] {
|
|
1936
|
+
height: 15px;
|
|
1937
|
+
margin: 0;
|
|
1938
|
+
padding: 0;
|
|
1939
|
+
accent-color: var(--theme-primary);
|
|
1940
|
+
}
|
|
1941
|
+
|
|
1942
|
+
#datalynk-login button {
|
|
1943
|
+
background-color: var(--theme-primary);
|
|
1944
|
+
background-image: none;
|
|
1945
|
+
border: 0;
|
|
1946
|
+
color: ${contrast(options.color)};
|
|
1947
|
+
padding: 8px 24px;
|
|
1948
|
+
border-radius: 5px;
|
|
1949
|
+
}
|
|
1950
|
+
|
|
1951
|
+
#datalynk-login button:disabled {
|
|
1952
|
+
cursor: pointer;
|
|
1953
|
+
filter: brightness(90%);
|
|
1954
|
+
}
|
|
1955
|
+
|
|
1956
|
+
#datalynk-login button:hover:not(:disabled) {
|
|
1957
|
+
cursor: pointer;
|
|
1958
|
+
filter: ${contrast(options.color) == "black" ? "brightness(105%)" : "brightness(80%)"};
|
|
1959
|
+
}
|
|
1960
|
+
|
|
1961
|
+
#datalynk-login .login-links{
|
|
1962
|
+
display: flex;
|
|
1963
|
+
padding: 0 0 1.5rem 0;
|
|
1964
|
+
}
|
|
1965
|
+
|
|
1966
|
+
#datalynk-login .login-links a {
|
|
1967
|
+
text-decoration: none;
|
|
1968
|
+
}
|
|
1969
|
+
|
|
1970
|
+
#datalynk-login .login-links img {
|
|
1971
|
+
width: 150px;
|
|
1972
|
+
height: auto;
|
|
1973
|
+
}
|
|
1974
|
+
|
|
1975
|
+
#datalynk-login .hidden {
|
|
1976
|
+
display: none;
|
|
1977
|
+
}
|
|
1978
|
+
|
|
1979
|
+
#datalynk-login .login-footer {
|
|
1980
|
+
transform: translateY(-18px);
|
|
1981
|
+
}
|
|
1982
|
+
|
|
1983
|
+
#datalynk-login .sloped-div {
|
|
1984
|
+
position: absolute;
|
|
1985
|
+
height: 45px;
|
|
1986
|
+
width: 200px;
|
|
1987
|
+
background: var(--theme-container);
|
|
1988
|
+
clip-path: polygon(0 20px, 100% 20px, 85% 60px, 15% 60px);
|
|
1989
|
+
}
|
|
1990
|
+
</style>`);
|
|
1991
|
+
/** Dynamically create HTML */
|
|
1992
|
+
__publicField(_LoginPrompt, "template", (options) => `
|
|
1993
|
+
<div id="datalynk-login">
|
|
1994
|
+
<!-- Used to check if image is valid -->
|
|
1995
|
+
${!options.backgroundColor ? `
|
|
1996
|
+
<img src="${options.background}" onerror="document.querySelector('#datalynk-login').style.backgroundImage = 'url(https://datalynk.auxiliumgroup.com/static/js/auxilium/dijits/templates/login/datalynk/background.jpg)'" style="width: 0; height: 0;"/>
|
|
1997
|
+
` : ""}
|
|
1998
|
+
|
|
1999
|
+
<div class="added-links">
|
|
2000
|
+
${(options.addLinks || []).map((link) => `<a href="${link.url || "#"}" target="_blank">${link.text}</a>`).join(" | ")}
|
|
2001
|
+
</div>
|
|
2002
|
+
<div class="login-container">
|
|
2003
|
+
<div class="login-header">
|
|
2004
|
+
${options.logo ? `<img alt="Logo" src="${options.logo}" class="login-logo" style="height: 100px; width: auto;" onerror="this.style.display='none'" ${options.logoOnly ? `onload="document.querySelector('.login-title').remove()"` : ""}>` : ""}
|
|
2005
|
+
<div style="display: flex; flex-direction: column; align-items: center; margin-left: 0.5rem;">
|
|
2006
|
+
<span class="login-title">${options.title || ""}</span>
|
|
2007
|
+
${options.subtitle ? `<span class="login-subtitle">${options.subtitle}</span>` : ""}
|
|
2008
|
+
</div>
|
|
2009
|
+
</div>
|
|
2010
|
+
<div class="login-content">
|
|
2011
|
+
<div class="login-body" style="max-width: 300px">
|
|
2012
|
+
<div id="datalynk-login-alert" class="hidden"></div>
|
|
2013
|
+
<form id="datalynk-login-form">
|
|
2014
|
+
<div>
|
|
2015
|
+
<label for="username">Email or Username</label>
|
|
2016
|
+
<input id="username" name="username" type="text" autocomplete="username">
|
|
2017
|
+
</div>
|
|
2018
|
+
<br>
|
|
2019
|
+
<div>
|
|
2020
|
+
<label for="password">Password</label>
|
|
2021
|
+
<input id="password" name="password" type="password" autocomplete="current-password">
|
|
2022
|
+
</div>
|
|
2023
|
+
<br>
|
|
2024
|
+
<label style="display: block; margin-bottom: 0.75rem;">
|
|
2025
|
+
<input type="checkbox" name="persist" style="width: 20px"> Stay Logged In
|
|
2026
|
+
</label>
|
|
2027
|
+
<button type="submit">Login</button>
|
|
2028
|
+
</form>
|
|
2029
|
+
</div>
|
|
2030
|
+
${options.hideApps ? "" : `
|
|
2031
|
+
<div class="login-links" style="text-align: center">
|
|
2032
|
+
<a href="https://itunes.apple.com/ca/app/auxilium-mobile/id1166379280?mt=8" target="_blank">
|
|
2033
|
+
<img alt="App Store" src="https://datalynk.auxiliumgroup.com/api/js/auxilium/dijits/templates/login/_common/mobile_apple_transparent.png">
|
|
2034
|
+
</a>
|
|
2035
|
+
<a href="https://play.google.com/store/apps/details?id=com.auxilium.auxiliummobilesolutions&hl=en" target="_blank">
|
|
2036
|
+
<img alt="Playstore" src="https://datalynk.auxiliumgroup.com/api/js/auxilium/dijits/templates/login/_common/mobile_google_transparent.png">
|
|
2037
|
+
</a>
|
|
2038
|
+
</div>
|
|
2039
|
+
`}
|
|
2040
|
+
</div>
|
|
2041
|
+
<div class="login-footer" style="position: relative; display: flex; align-items: center; justify-content: center;">
|
|
2042
|
+
<div class="sloped-div"></div>
|
|
2043
|
+
<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;">
|
|
2044
|
+
Au<span style="font-size: 52px; color: #c83232; margin-bottom: 5px">x</span>ilium
|
|
2045
|
+
<span style="position: absolute; font-size: 10px; color: #c83232; top: 2px; right: 2px">Group</span>
|
|
2046
|
+
</a>
|
|
2047
|
+
</div>
|
|
2048
|
+
</div>
|
|
2049
|
+
</div>
|
|
2050
|
+
`);
|
|
2051
|
+
let LoginPrompt = _LoginPrompt;
|
|
2052
|
+
class Auth {
|
|
2053
|
+
constructor(api) {
|
|
2054
|
+
__publicField(this, "onlinePrompt");
|
|
2055
|
+
/** Current user as an observable */
|
|
2056
|
+
__publicField(this, "user$", new BehaviorSubject(void 0));
|
|
2057
|
+
var _a;
|
|
2058
|
+
this.api = api;
|
|
2059
|
+
this.api.token$.subscribe(async (token) => {
|
|
2060
|
+
if (token === void 0) return;
|
|
2061
|
+
this.user = await this.current(token);
|
|
2062
|
+
});
|
|
2063
|
+
if ((_a = this.api.options.offline) == null ? void 0 : _a.length)
|
|
2064
|
+
this.user$.pipe(filter((u) => u !== void 0)).subscribe((u) => localStorage.setItem("datalynk-user", JSON.stringify(u)));
|
|
2065
|
+
}
|
|
2066
|
+
/** Current user */
|
|
2067
|
+
get user() {
|
|
2068
|
+
return this.user$.getValue();
|
|
2069
|
+
}
|
|
2070
|
+
/** Set current user info */
|
|
2071
|
+
set user(user) {
|
|
2072
|
+
this.user$.next(user);
|
|
2073
|
+
}
|
|
2074
|
+
get spoke() {
|
|
2075
|
+
var _a;
|
|
2076
|
+
return ((_a = this.api.jwtPayload) == null ? void 0 : _a.realm) || null;
|
|
2077
|
+
}
|
|
2078
|
+
/**
|
|
2079
|
+
* Get current user associated with API token
|
|
2080
|
+
*
|
|
2081
|
+
* @return {Promise<User | null>}
|
|
2082
|
+
*/
|
|
2083
|
+
async current(token = this.api.token) {
|
|
2084
|
+
var _a;
|
|
2085
|
+
if (!token) return null;
|
|
2086
|
+
else if (token == ((_a = this.user) == null ? void 0 : _a.token)) return this.user;
|
|
2087
|
+
else if (typeof navigator != "undefined" && !navigator.onLine && typeof localStorage != "undefined" && localStorage.getItem("datalynk-user"))
|
|
2088
|
+
return JSON.parse(localStorage.getItem("datalynk-user"));
|
|
2089
|
+
return this.api.request([{ "$/auth/current": {} }, { "$/env/me": {} }], { token }).then((resp) => resp[0] || resp[1] ? { ...resp[0], ...resp[1] } : null);
|
|
2090
|
+
}
|
|
2091
|
+
/**
|
|
2092
|
+
* Automatically handle sessions by checking localStorage & URL parameters for a token & prompting
|
|
2093
|
+
* user with a login screen if required
|
|
2094
|
+
*
|
|
2095
|
+
* @param {string} spoke Desired spoke
|
|
2096
|
+
* @param {LoginPromptOptions} options Aesthetic options
|
|
2097
|
+
* @return {Promise<void>} Login complete
|
|
2098
|
+
*/
|
|
2099
|
+
async handleLogin(spoke, options) {
|
|
2100
|
+
var _a, _b;
|
|
2101
|
+
if (this.onlinePrompt) window.removeEventListener("online", this.onlinePrompt);
|
|
2102
|
+
if ((_a = this.api.options.offline) == null ? void 0 : _a.length) window.removeEventListener("online", this.onlinePrompt = () => this.handleLogin(spoke, options));
|
|
2103
|
+
const urlToken = new URLSearchParams(location.search).get("datalynkToken");
|
|
2104
|
+
if (urlToken) {
|
|
2105
|
+
this.api.token = urlToken;
|
|
2106
|
+
location.href = location.href.replace(/datalynkToken=.*?(&|$)/gm, "");
|
|
2107
|
+
} else if (this.api.token && !this.api.expired) {
|
|
2108
|
+
if (((_b = this.api.jwtPayload) == null ? void 0 : _b.realm) != spoke) {
|
|
2109
|
+
this.api.token = null;
|
|
2110
|
+
location.reload();
|
|
2111
|
+
}
|
|
2112
|
+
} else {
|
|
2113
|
+
this.api.token = null;
|
|
2114
|
+
await this.loginPrompt(spoke, options).done;
|
|
2115
|
+
location.reload();
|
|
2116
|
+
}
|
|
2117
|
+
}
|
|
2118
|
+
/**
|
|
2119
|
+
* Check whether user has a token
|
|
2120
|
+
*
|
|
2121
|
+
* @return {boolean} True if session token authenticated
|
|
2122
|
+
*/
|
|
2123
|
+
isAuthenticated() {
|
|
2124
|
+
return !!this.user && !this.user.guest;
|
|
2125
|
+
}
|
|
2126
|
+
/**
|
|
2127
|
+
* Check if the current user is a guest
|
|
2128
|
+
*
|
|
2129
|
+
* @return {boolean} True if guest
|
|
2130
|
+
*/
|
|
2131
|
+
isGuest() {
|
|
2132
|
+
var _a;
|
|
2133
|
+
return !!((_a = this.user) == null ? void 0 : _a.guest);
|
|
2134
|
+
}
|
|
2135
|
+
/**
|
|
2136
|
+
* Check if user is a system administrator
|
|
2137
|
+
*
|
|
2138
|
+
* @return {Promise<boolean>} True if system administrator
|
|
2139
|
+
*/
|
|
2140
|
+
async isSysAdmin() {
|
|
2141
|
+
return !!(await this.api.slice("sysadmin").select().where("auth_ref", "==", "$viewer").rows().exec()).length;
|
|
2142
|
+
}
|
|
2143
|
+
/**
|
|
2144
|
+
* Check if user is a table administrator
|
|
2145
|
+
*
|
|
2146
|
+
* @return {Promise<boolean>} True if table administrator
|
|
2147
|
+
*/
|
|
2148
|
+
async isTableAdmin() {
|
|
2149
|
+
return !!(await this.api.slice("tableadmins").select().where("auth_ref", "==", "$viewer").rows().exec()).length;
|
|
2150
|
+
}
|
|
2151
|
+
/**
|
|
2152
|
+
* Check if user is a user administrator
|
|
2153
|
+
*
|
|
2154
|
+
* @return {Promise<boolean>} True if user administrator
|
|
2155
|
+
*/
|
|
2156
|
+
async isUserAdmin() {
|
|
2157
|
+
return !!(await this.api.slice("useradmins").select().where("auth_ref", "==", "$viewer").rows().exec()).length;
|
|
2158
|
+
}
|
|
2159
|
+
/**
|
|
2160
|
+
* Perform login and save the session token
|
|
2161
|
+
*
|
|
2162
|
+
* @param {string} login Login username or email
|
|
2163
|
+
* @param {string} password Password for account
|
|
2164
|
+
* @param {string} spoke Override login spoke
|
|
2165
|
+
* @param {twoFactor?: string, expire?: string} opts 2FA code & expire date (YYYY-MM-DD)
|
|
2166
|
+
* @returns {Promise<User>} User account
|
|
2167
|
+
*/
|
|
2168
|
+
login(spoke, login, password, opts) {
|
|
2169
|
+
const date = /* @__PURE__ */ new Date();
|
|
2170
|
+
date.setFullYear(date.getFullYear() + 1);
|
|
2171
|
+
return fetch(`${this.api.url}login`, {
|
|
2172
|
+
method: "POST",
|
|
2173
|
+
headers: { "Content-Type": "application/json" },
|
|
2174
|
+
body: JSON.stringify(clean({
|
|
2175
|
+
realm: spoke.trim(),
|
|
2176
|
+
login: login.trim(),
|
|
2177
|
+
password: password.trim(),
|
|
2178
|
+
secret: opts == null ? void 0 : opts.twoFactor,
|
|
2179
|
+
expireAt: (opts == null ? void 0 : opts.expire) == null ? `${date.getFullYear()}-${(date.getMonth() + 1).toString().padStart(2, "0")}-${date.getDate().toString().padStart(2, "0")}` : opts == null ? void 0 : opts.expire,
|
|
2180
|
+
dateFormat: "ISO8601"
|
|
2181
|
+
}))
|
|
2182
|
+
}).then(async (resp) => {
|
|
2183
|
+
const data = await resp.json().catch(() => ({}));
|
|
2184
|
+
if (!resp.ok || data["error"]) throw Object.assign(errorFromCode(resp.status, data.error) || {}, data);
|
|
2185
|
+
this.api.token = data["token"];
|
|
2186
|
+
return data;
|
|
2187
|
+
});
|
|
2188
|
+
}
|
|
2189
|
+
/**
|
|
2190
|
+
* Login as guest user
|
|
2191
|
+
*
|
|
2192
|
+
* @return {Promise<User>} Guest account
|
|
2193
|
+
*/
|
|
2194
|
+
loginGuest() {
|
|
2195
|
+
return fetch(`${this.api.url}guest`).then(async (resp) => {
|
|
2196
|
+
const data = await resp.json().catch(() => ({}));
|
|
2197
|
+
if (!resp.ok || data["error"]) throw Object.assign(errorFromCode(resp.status, data.error) || {}, data);
|
|
2198
|
+
this.api.token = data["token"];
|
|
2199
|
+
return data;
|
|
2200
|
+
});
|
|
2201
|
+
}
|
|
2202
|
+
/**
|
|
2203
|
+
* Create Login UI
|
|
2204
|
+
*
|
|
2205
|
+
* @param {string} spoke Desired spoke
|
|
2206
|
+
* @param {LoginPromptOptions} options Aesthetic options
|
|
2207
|
+
* @return {LoginPrompt} Login prompt
|
|
2208
|
+
*/
|
|
2209
|
+
loginPrompt(spoke, options) {
|
|
2210
|
+
return new LoginPrompt(this.api, spoke, options);
|
|
2211
|
+
}
|
|
2212
|
+
/**
|
|
2213
|
+
* Logout current user
|
|
2214
|
+
*
|
|
2215
|
+
* @return {Promise<{closed: string, new: string}>}
|
|
2216
|
+
*/
|
|
2217
|
+
logout(reload = true) {
|
|
2218
|
+
localStorage.removeItem("datalynk-user");
|
|
2219
|
+
return this.api.request({ "$/auth/logout": {} }).then((resp) => {
|
|
2220
|
+
if (reload) location.reload();
|
|
2221
|
+
this.api.token = null;
|
|
2222
|
+
return resp;
|
|
2223
|
+
});
|
|
2224
|
+
}
|
|
2225
|
+
/**
|
|
2226
|
+
* Reset user account password
|
|
2227
|
+
*
|
|
2228
|
+
* @param {string} login User login
|
|
2229
|
+
* @param {string} newPassword New password
|
|
2230
|
+
* @param {string} code Reset code sent with `resetRequest`
|
|
2231
|
+
* @return {Promise<any>} New session
|
|
2232
|
+
*/
|
|
2233
|
+
reset(login, newPassword, code) {
|
|
2234
|
+
return this.api.request({
|
|
2235
|
+
"$/auth/mobile/rescue": {
|
|
2236
|
+
user: login,
|
|
2237
|
+
password: newPassword,
|
|
2238
|
+
pin: code
|
|
2239
|
+
}
|
|
2240
|
+
}).then((resp) => {
|
|
2241
|
+
if (resp.token) this.api.token = resp.token;
|
|
2242
|
+
return resp;
|
|
2243
|
+
});
|
|
2244
|
+
}
|
|
2245
|
+
/**
|
|
2246
|
+
* Request reset code for user
|
|
2247
|
+
*
|
|
2248
|
+
* @param {string} login User to reset
|
|
2249
|
+
* @param {"email" | "sms" | "voice"} mode Method of sending reset code
|
|
2250
|
+
* @return {Promise<any>} Unknown
|
|
2251
|
+
*/
|
|
2252
|
+
resetRequest(login, mode) {
|
|
2253
|
+
if (mode == "email") return this.api.request({ "$/auth/rescue_email": { user: { $or: { login, email: login } } } });
|
|
2254
|
+
return this.api.request({ "$/auth/mobile/generate": { user: login, method: mode } });
|
|
2255
|
+
}
|
|
2256
|
+
}
|
|
2257
|
+
class PWA {
|
|
2258
|
+
constructor(api) {
|
|
2259
|
+
this.api = api;
|
|
2260
|
+
}
|
|
2261
|
+
get iframe() {
|
|
2262
|
+
return (parent == null ? void 0 : parent.location) != location;
|
|
2263
|
+
}
|
|
2264
|
+
get mobile() {
|
|
2265
|
+
return ["android", "ios"].includes(this.platform);
|
|
2266
|
+
}
|
|
2267
|
+
get platform() {
|
|
2268
|
+
const userAgent = navigator.userAgent || navigator.vendor;
|
|
2269
|
+
if (/windows/i.test(userAgent)) return "windows";
|
|
2270
|
+
else if (/android/i.test(userAgent)) return "android";
|
|
2271
|
+
else if (/iPad|iPhone|iPod/.test(userAgent)) return "ios";
|
|
2272
|
+
else if (/macintosh|mac os x/i.test(userAgent)) return "mac";
|
|
2273
|
+
else if (/linux/i.test(userAgent)) return "linux";
|
|
2274
|
+
else return "unknown";
|
|
2275
|
+
}
|
|
2276
|
+
get pwa() {
|
|
2277
|
+
return matchMedia("(display-mode: standalone)").matches || (navigator == null ? void 0 : navigator.standalone) || document.referrer.includes("android-app://");
|
|
2278
|
+
}
|
|
2279
|
+
/** Setup the PWA */
|
|
2280
|
+
async setup(manifest = {}) {
|
|
2281
|
+
const meta = (key, name, value) => {
|
|
2282
|
+
const exists = document.querySelector(`meta[${key}="${name}"]`);
|
|
2283
|
+
if (value === void 0 || exists) return exists;
|
|
2284
|
+
const meta2 = document.createElement("meta");
|
|
2285
|
+
meta2.setAttribute(key, name);
|
|
2286
|
+
meta2.content = value;
|
|
2287
|
+
document.head.append(meta2);
|
|
2288
|
+
};
|
|
2289
|
+
meta("name", "mobile-web-app-capable", "yes");
|
|
2290
|
+
meta("name", "apple-mobile-web-app-status-bar-style", "default");
|
|
2291
|
+
meta("name", "apple-mobile-web-app-title", this.api.options.name);
|
|
2292
|
+
meta("name", "apple-touch-icon", `https://datalynk-client.scarborough.auxilium.world/logo.png`);
|
|
2293
|
+
meta("name", "apple-touch-startup-image", `https://datalynk-client.scarborough.auxilium.world/logo.png`);
|
|
2294
|
+
if (!document.querySelector('link[rel="manifest"]')) {
|
|
2295
|
+
const link = document.createElement("link");
|
|
2296
|
+
link.setAttribute("rel", "manifest");
|
|
2297
|
+
link.setAttribute("href", `${this.api.url}/manifest?json=${encodeURI(JSON.stringify({
|
|
2298
|
+
name: this.api.options.name,
|
|
2299
|
+
short_name: this.api.options.name,
|
|
2300
|
+
start_url: location.origin + location.pathname,
|
|
2301
|
+
...this.api.options.manifest,
|
|
2302
|
+
...manifest
|
|
2303
|
+
}))}`);
|
|
2304
|
+
document.head.append(link);
|
|
2305
|
+
}
|
|
2306
|
+
if (!this.iframe && !this.pwa && this.platform != "mac") setTimeout(() => {
|
|
2307
|
+
const dismissed = !!localStorage.getItem(`${this.api.options.name}:pwa`);
|
|
2308
|
+
if (!dismissed) this.prompt();
|
|
2309
|
+
}, 6e4);
|
|
2310
|
+
}
|
|
2311
|
+
/** Prompt user to install the app */
|
|
2312
|
+
async prompt(platform) {
|
|
2313
|
+
if (document.querySelector(".pwa-prompt")) return;
|
|
2314
|
+
this.api.url;
|
|
2315
|
+
const android = (platform || this.platform) == "android";
|
|
2316
|
+
let style = document.querySelector("style.pwa");
|
|
2317
|
+
if (!style) {
|
|
2318
|
+
style = document.createElement("style");
|
|
2319
|
+
style.innerHTML = `
|
|
2320
|
+
.pwa-prompt-backdrop {
|
|
2321
|
+
position: fixed;
|
|
2322
|
+
display: relative;
|
|
2323
|
+
left: 0;
|
|
2324
|
+
top: 0;
|
|
2325
|
+
right: 0;
|
|
2326
|
+
bottom: 0;
|
|
2327
|
+
background: rgba(0,0,0,.5);
|
|
2328
|
+
z-index: 9999;
|
|
2329
|
+
animation: fadeIn 0.5s ease-in-out forwards;
|
|
2330
|
+
opacity: 0;
|
|
2331
|
+
}
|
|
2332
|
+
.pwa-prompt-backdrop.exit {
|
|
2333
|
+
animation: fadeOut 0.5s ease-in-out forwards !important;
|
|
2334
|
+
}
|
|
2335
|
+
.pwa-prompt {
|
|
2336
|
+
position: fixed;
|
|
2337
|
+
background: #fff;
|
|
2338
|
+
color: black;
|
|
2339
|
+
bottom: 0;
|
|
2340
|
+
left: 50%;
|
|
2341
|
+
width: min(100vw, 450px);
|
|
2342
|
+
transform: translate(-50%, 0);
|
|
2343
|
+
animation: slideUp 0.5s ease-in-out forwards;
|
|
2344
|
+
}
|
|
2345
|
+
.pwa-prompt.exit {
|
|
2346
|
+
animation: slideDown 0.5s ease-in-out forwards !important;
|
|
2347
|
+
}
|
|
2348
|
+
.pwa-prompt img {
|
|
2349
|
+
width: 18px;
|
|
2350
|
+
height: 18px;
|
|
2351
|
+
}
|
|
2352
|
+
.pwa-prompt h1 {
|
|
2353
|
+
font-size: 1.25rem;
|
|
2354
|
+
font-weight: bold;
|
|
2355
|
+
}
|
|
2356
|
+
.pwa-prompt-close {
|
|
2357
|
+
position: absolute;
|
|
2358
|
+
right: 5px;
|
|
2359
|
+
top: 10px;
|
|
2360
|
+
background: transparent;
|
|
2361
|
+
border: none;
|
|
2362
|
+
cursor: pointer;
|
|
2363
|
+
}
|
|
2364
|
+
|
|
2365
|
+
@keyframes fadeIn {
|
|
2366
|
+
from { opacity: 0; }
|
|
2367
|
+
to { opacity: 1; }
|
|
2368
|
+
}
|
|
2369
|
+
@keyframes fadeOut {
|
|
2370
|
+
from { opacity: 1; }
|
|
2371
|
+
to { opacity: 0; }
|
|
2372
|
+
}
|
|
2373
|
+
|
|
2374
|
+
@keyframes slideUp {
|
|
2375
|
+
from { transform: translate(-50%, 100%); }
|
|
2376
|
+
to { transform: translate(-50%, 0); }
|
|
2377
|
+
}
|
|
2378
|
+
@keyframes slideDown {
|
|
2379
|
+
from { transform: translate(-50%, 0); }
|
|
2380
|
+
to { transform: translate(-50%, 100%); }
|
|
2381
|
+
}
|
|
2382
|
+
`;
|
|
2383
|
+
document.head.append(style);
|
|
2384
|
+
}
|
|
2385
|
+
const backdrop = document.createElement("div");
|
|
2386
|
+
backdrop.classList.add("pwa-prompt-backdrop");
|
|
2387
|
+
const prompt = document.createElement("div");
|
|
2388
|
+
prompt.classList.add("pwa-prompt");
|
|
2389
|
+
prompt.innerHTML = `
|
|
2390
|
+
<div style="display: flex; padding: 1rem; align-items: center">
|
|
2391
|
+
<img src="https://datalynk-client.scarborough.auxilium.world/logo.png" alt="Logo" style="height: 40px; width: auto; margin-right: .5rem;" />
|
|
2392
|
+
<h1 style="margin: 0">Install ${this.api.options.name}</h1>
|
|
2393
|
+
</div>
|
|
2394
|
+
<div style="display: flex; flex-direction: column; align-items: center">
|
|
2395
|
+
<div style="border-top: 2px solid #00000020; border-bottom: 2px solid #00000020; padding: 0 1rem">
|
|
2396
|
+
<p style="margin-top: 1rem; text-align: center">This website can be installed as an App! Add it to your home screen for quick access & fullscreen use.</p>
|
|
2397
|
+
</div>
|
|
2398
|
+
<table style="margin: 1.5rem 0">
|
|
2399
|
+
<tr>
|
|
2400
|
+
<td style="width: 50px; text-align: center">
|
|
2401
|
+
${android ? '<svg xmlns="http://www.w3.org/2000/svg" height="24px" viewBox="0 -960 960 960" width="24px" fill="black" style="transform: scale(1.5)"><path d="M480-160q-33 0-56.5-23.5T400-240q0-33 23.5-56.5T480-320q33 0 56.5 23.5T560-240q0 33-23.5 56.5T480-160Zm0-240q-33 0-56.5-23.5T400-480q0-33 23.5-56.5T480-560q33 0 56.5 23.5T560-480q0 33-23.5 56.5T480-400Zm0-240q-33 0-56.5-23.5T400-720q0-33 23.5-56.5T480-800q33 0 56.5 23.5T560-720q0 33-23.5 56.5T480-640Z"/></svg>' : '<svg viewBox="0 0 566 670" xmlns="http://www.w3.org/2000/svg" fill="#0B76FC" height="40px"><path d="M255 12c4-4 10-8 16-8s12 3 16 8l94 89c3 4 6 7 8 12 2 6 0 14-5 19-7 8-20 9-28 2l-7-7-57-60 2 54v276c0 12-10 22-22 22-12 1-24-10-23-22V110l1-43-60 65c-5 5-13 8-21 6a19 19 0 0 1-16-17c-1-7 2-13 7-18l95-91z" /><path d="M43 207c16-17 40-23 63-23h83v46h-79c-12 0-25 3-33 13-8 9-10 21-10 33v260c0 13 0 27 6 38 5 12 18 18 30 19l14 1h302c14 0 28 0 40-8 11-7 16-21 16-34V276c0-11-2-24-9-33-8-10-22-13-34-13h-78v-46h75c13 0 25 1 37 4 16 4 31 13 41 27 11 17 14 37 14 57v280c0 20-3 41-15 58a71 71 0 0 1-45 27c-11 2-23 3-34 3H109c-19-1-40-4-56-15-14-9-23-23-27-38-4-12-5-25-5-38V270c1-22 6-47 22-63z" /></svg>'}
|
|
2402
|
+
</td>
|
|
2403
|
+
<td>
|
|
2404
|
+
<p style="margin: 1rem 0">1) ${android ? "Open the dropdown menu" : 'Press the "Share" button'}</p>
|
|
2405
|
+
</td>
|
|
2406
|
+
</tr>
|
|
2407
|
+
<tr>
|
|
2408
|
+
<td style="width: 50px; text-align: center">
|
|
2409
|
+
${android ? '<svg xmlns="http://www.w3.org/2000/svg" height="24px" viewBox="0 -960 960 960" width="24px" fill="black" style="transform: scale(-1.5, 1.5)"><path d="M280-40q-33 0-56.5-23.5T200-120v-720q0-33 23.5-56.5T280-920h280v80H280v40h280v80H280v480h400v-80h80v200q0 33-23.5 56.5T680-40H280Zm0-120v40h400v-40H280Zm440-240L520-600l56-56 104 104v-288h80v288l104-104 56 56-200 200ZM280-800v-40 40Zm0 640v40-40Z"/></svg>' : '<svg viewBox="0 0 578 584" xmlns="http://www.w3.org/2000/svg" fill="black" height="34px"><path d="M101 35l19-1h333c12 0 23 0 35 3 17 3 34 12 44 27 13 16 16 38 16 58v329c0 19 0 39-8 57a65 65 0 0 1-37 37c-18 7-38 7-57 7H130c-21 1-44 0-63-10-14-7-25-20-30-34-6-15-8-30-8-45V121c1-21 5-44 19-61 13-16 33-23 53-25m7 46c-10 1-19 6-24 14-7 8-9 20-9 31v334c0 12 2 25 10 34 9 10 23 12 35 12h336c14 1 30-3 38-15 6-9 8-20 8-31V125c0-12-2-24-10-33-9-9-22-12-35-12H121l-13 1z" /><path d="M271 161c9-11 31-10 38 4 3 5 3 11 3 17v87h88c7 0 16 1 21 7 6 6 7 14 6 22a21 21 0 0 1-10 14c-5 4-11 5-17 5h-88v82c0 7-1 15-6 20-10 10-29 10-37-2-3-6-4-13-4-19v-81h-87c-8-1-17-3-23-9-5-6-6-15-4-22a21 21 0 0 1 11-14c6-3 13-3 19-3h84v-88c0-7 1-14 6-20z" /></svg>'}
|
|
2410
|
+
</td>
|
|
2411
|
+
<td>
|
|
2412
|
+
<p style="margin: 1rem 0">2) Press "Add to Home Screen"</p>
|
|
2413
|
+
</td>
|
|
2414
|
+
</tr>
|
|
2415
|
+
</table>
|
|
2416
|
+
</div>`;
|
|
2417
|
+
const close = document.createElement("button");
|
|
2418
|
+
close.classList.add("pwa-prompt-close");
|
|
2419
|
+
close.innerText = "x";
|
|
2420
|
+
close.onclick = () => {
|
|
2421
|
+
prompt.classList.add("exit");
|
|
2422
|
+
backdrop.classList.add("exit");
|
|
2423
|
+
localStorage.setItem(`${this.api.options.name}:pwa`, "dismissed");
|
|
2424
|
+
setTimeout(() => {
|
|
2425
|
+
prompt.remove();
|
|
2426
|
+
backdrop.remove();
|
|
2427
|
+
}, 500);
|
|
2428
|
+
};
|
|
2429
|
+
prompt.append(close);
|
|
2430
|
+
backdrop.append(prompt);
|
|
2431
|
+
document.body.append(backdrop);
|
|
2432
|
+
}
|
|
2433
|
+
}
|
|
2434
|
+
class Files {
|
|
2435
|
+
constructor(api) {
|
|
2436
|
+
this.api = api;
|
|
2437
|
+
}
|
|
2438
|
+
associate(fileIds, slice, row, field, execute = true) {
|
|
2439
|
+
const req = { [`${execute ? "!" : "$"}/tools/file/update`]: { slice, row, field, ids: fileIds } };
|
|
2440
|
+
if (execute) return this.api.request(req);
|
|
2441
|
+
return req;
|
|
2442
|
+
}
|
|
2443
|
+
/**
|
|
2444
|
+
* Get an authenticated URL to fetch files from
|
|
2445
|
+
*
|
|
2446
|
+
* @param {number} id File ID
|
|
2447
|
+
* @param {boolean} ignoreToken Ignore authentication
|
|
2448
|
+
* @return {string} URL file can be viewed at
|
|
2449
|
+
*/
|
|
2450
|
+
get(id, ignoreToken) {
|
|
2451
|
+
return `${this.api.url}file?id=${id}${ignoreToken ? "" : `&token=${this.api.token}`}`;
|
|
2452
|
+
}
|
|
2453
|
+
/**
|
|
2454
|
+
* Upload file(s) to the API & optionally associate them with a row
|
|
2455
|
+
*
|
|
2456
|
+
* @param {FileList | File | File[]} files Files to be uploaded
|
|
2457
|
+
* @param {{slice: number, row: any, field: string, pk?: string}} associate Row to associate with
|
|
2458
|
+
*/
|
|
2459
|
+
upload(files, associate) {
|
|
2460
|
+
let f = files instanceof FileList ? Array.from(files) : makeArray(files);
|
|
2461
|
+
return Promise.all(f.map((file) => {
|
|
2462
|
+
const data = new FormData();
|
|
2463
|
+
data.append("uploadedfiles[]", file, file.name);
|
|
2464
|
+
return fetch(`${this.api.url}upload.php`, {
|
|
2465
|
+
method: "POST",
|
|
2466
|
+
headers: clean({ "Authorization": this.api.token ? `Bearer ${this.api.token}` : "" }),
|
|
2467
|
+
body: data
|
|
2468
|
+
}).then(async (resp) => {
|
|
2469
|
+
const data2 = await resp.json().catch(() => ({}));
|
|
2470
|
+
if (!resp.ok || data2["error"]) throw Object.assign(errorFromCode(resp.status, data2.error) || {}, data2);
|
|
2471
|
+
return data2.files.uploadedfiles[0];
|
|
2472
|
+
});
|
|
2473
|
+
})).then(async (files2) => {
|
|
2474
|
+
if (associate) {
|
|
2475
|
+
let id = typeof associate.row == "number" ? associate.row : associate.row[associate.pk || "id"];
|
|
2476
|
+
if (!id) id = await this.api.slice(associate.slice).insert(associate.row).id().exec();
|
|
2477
|
+
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);
|
|
2478
|
+
}
|
|
2479
|
+
return files2;
|
|
2480
|
+
});
|
|
2481
|
+
}
|
|
2482
|
+
}
|
|
2483
|
+
class Pdf {
|
|
2484
|
+
constructor(api) {
|
|
2485
|
+
this.api = api;
|
|
2486
|
+
}
|
|
2487
|
+
/**
|
|
2488
|
+
* Create a PDF from a public URL
|
|
2489
|
+
* @param {string} url Target URL address
|
|
2490
|
+
* @param {{slice: number, row: number, field: string} | null} associate Optionally associate PDF with a slice row
|
|
2491
|
+
* @param {PdfOptions} options PDF options for rendering & uploading
|
|
2492
|
+
* @return {Promise<any>} Either the PDF file number or the updated slice row response if associated
|
|
2493
|
+
*/
|
|
2494
|
+
async fromUrl(url, associate, options = {}) {
|
|
2495
|
+
return this.api.request({ "$/slice/utils/urlToPdf": { url, ...options } }).then((file) => {
|
|
2496
|
+
if (associate) return this.api.files.associate(file, associate.slice, associate.row, associate.field);
|
|
2497
|
+
return file;
|
|
2498
|
+
});
|
|
2499
|
+
}
|
|
2500
|
+
}
|
|
2501
|
+
const Serializer = {
|
|
2502
|
+
/**
|
|
2503
|
+
* From Datalynk syntax to JS
|
|
2504
|
+
*/
|
|
2505
|
+
deserialize: {
|
|
2506
|
+
/**
|
|
2507
|
+
* Convert date time string to javascript date object
|
|
2508
|
+
*
|
|
2509
|
+
* @param {string} datetime datetime string (YYYY/MM/DD hh:mm:ss)
|
|
2510
|
+
* @returns {Date} JS Date object
|
|
2511
|
+
*/
|
|
2512
|
+
"$/tools/date": (datetime) => {
|
|
2513
|
+
let a = datetime.split(/[^0-9]+/).map((part) => Number(part));
|
|
2514
|
+
return new Date(a[0], a[1] - 1, a[2], a[3], a[4], a[5]);
|
|
2515
|
+
},
|
|
2516
|
+
/**
|
|
2517
|
+
* Convert date string to javascript date object
|
|
2518
|
+
*
|
|
2519
|
+
* @param {string} date date string (YYYY/MM/DD)
|
|
2520
|
+
* @returns {Date} JS Date object
|
|
2521
|
+
*/
|
|
2522
|
+
"$/tools/date_strict": (date) => {
|
|
2523
|
+
let a = date.split(/[^0-9]+/).map((part) => Number(part));
|
|
2524
|
+
let d = new Date(a[0], a[1] - 1, a[2], 0, 0, 0);
|
|
2525
|
+
d["hint"] = "date";
|
|
2526
|
+
return d;
|
|
2527
|
+
},
|
|
2528
|
+
/**
|
|
2529
|
+
* Convert time string to javascript date object
|
|
2530
|
+
*
|
|
2531
|
+
* @param {string} time time string (YYYY/MM/DD)
|
|
2532
|
+
* @returns {Date} JS Date object
|
|
2533
|
+
*/
|
|
2534
|
+
"$/tools/time_strict": (time) => {
|
|
2535
|
+
let a = time.split(/[^0-9]+/).map((part) => Number(part));
|
|
2536
|
+
let d = /* @__PURE__ */ new Date();
|
|
2537
|
+
d.setHours(a[0]);
|
|
2538
|
+
d.setMinutes(a[1]);
|
|
2539
|
+
d.setSeconds(a[2]);
|
|
2540
|
+
d["hint"] = "time";
|
|
2541
|
+
return d;
|
|
2542
|
+
},
|
|
2543
|
+
/**
|
|
2544
|
+
* Convert string to constant
|
|
2545
|
+
*
|
|
2546
|
+
* @param {string} constant string to be converted
|
|
2547
|
+
* @returns {any} the actual constant
|
|
2548
|
+
*/
|
|
2549
|
+
"$/tools/const": (constant) => {
|
|
2550
|
+
let types = {
|
|
2551
|
+
"infinity": Infinity,
|
|
2552
|
+
"-infinity": -Infinity,
|
|
2553
|
+
"nan": NaN
|
|
2554
|
+
};
|
|
2555
|
+
try {
|
|
2556
|
+
return types[constant["$/tools/const"].toLowerCase()];
|
|
2557
|
+
} catch (ignored) {
|
|
2558
|
+
return void 0;
|
|
2559
|
+
}
|
|
2560
|
+
},
|
|
2561
|
+
/**
|
|
2562
|
+
* Large requests are formatted into parallel arrays
|
|
2563
|
+
*
|
|
2564
|
+
* @param {object} obj Object of metadata and data
|
|
2565
|
+
* @returns {Array} Actual object reconstructed
|
|
2566
|
+
*/
|
|
2567
|
+
"$/tools/dltable": function(obj) {
|
|
2568
|
+
let meta = obj["meta"];
|
|
2569
|
+
let col;
|
|
2570
|
+
let fn = [];
|
|
2571
|
+
for (let i in meta) {
|
|
2572
|
+
col = meta[i];
|
|
2573
|
+
fn.push("this['" + col.name + "'] = ");
|
|
2574
|
+
if (col.cast == null) {
|
|
2575
|
+
fn.push("a[" + i + "];\n");
|
|
2576
|
+
} else if (col.cast === "num") {
|
|
2577
|
+
fn.push("a[" + i + "] && parseFloat(a[" + i + "]);\n");
|
|
2578
|
+
} else {
|
|
2579
|
+
if (col["native"] === "date") {
|
|
2580
|
+
fn.push("a[" + i + "] && dateParse(a[" + i + "]);\n");
|
|
2581
|
+
fn.push("a[" + i + "] && (this['" + col.name + "'].hint = 'date');\n");
|
|
2582
|
+
} else if (col["native"] === "time") {
|
|
2583
|
+
fn.push("a[" + i + "] && timeParse(a[" + i + "]);\n");
|
|
2584
|
+
fn.push("a[" + i + "] && (this['" + col.name + "'].hint = 'time');\n");
|
|
2585
|
+
} else {
|
|
2586
|
+
fn.push("a[" + i + "] && datetimeParse(a[" + i + "]);\n");
|
|
2587
|
+
}
|
|
2588
|
+
}
|
|
2589
|
+
}
|
|
2590
|
+
let dateTimeParse, dateParse, timeParse;
|
|
2591
|
+
let now = /* @__PURE__ */ new Date();
|
|
2592
|
+
let yyyy = now.getFullYear();
|
|
2593
|
+
let mm = now.getMonth();
|
|
2594
|
+
let dd = now.getDate();
|
|
2595
|
+
dateTimeParse = function(dt) {
|
|
2596
|
+
dt = dt.split(/[^0-9]+/);
|
|
2597
|
+
return new Date(dt[0], dt[1] - 1, dt[2], dt[3], dt[4], dt[5]);
|
|
2598
|
+
};
|
|
2599
|
+
dateParse = function(d) {
|
|
2600
|
+
d = d.split(/[- :]/);
|
|
2601
|
+
let res2 = new Date(d[0], d[1] - 1, d[2], 0, 0, 0);
|
|
2602
|
+
res2["hint"] = "date";
|
|
2603
|
+
return res2;
|
|
2604
|
+
};
|
|
2605
|
+
timeParse = function(t) {
|
|
2606
|
+
t = t.split(/[^0-9]+/, t);
|
|
2607
|
+
let res2 = new Date(yyyy, mm, dd, t[0], t[1], t[2]);
|
|
2608
|
+
res2["hint"] = "time";
|
|
2609
|
+
return res2;
|
|
2610
|
+
};
|
|
2611
|
+
let ctor = Function("datetimeParse", "dateParse", "timeParse", "a", fn.join(""));
|
|
2612
|
+
let res = [];
|
|
2613
|
+
let rows = obj["rows"];
|
|
2614
|
+
for (let i in rows) {
|
|
2615
|
+
res[i] = new ctor(dateTimeParse, dateParse, timeParse, rows[i]);
|
|
2616
|
+
}
|
|
2617
|
+
res["meta"] = meta;
|
|
2618
|
+
res["rowConstructor"] = ctor;
|
|
2619
|
+
return res;
|
|
2620
|
+
}
|
|
2621
|
+
},
|
|
2622
|
+
/**
|
|
2623
|
+
* From JS to Datalynk syntax
|
|
2624
|
+
*/
|
|
2625
|
+
serialize: {
|
|
2626
|
+
/**
|
|
2627
|
+
* Convert JS date to datalynk datetime string
|
|
2628
|
+
*/
|
|
2629
|
+
"Date": (date) => {
|
|
2630
|
+
return {
|
|
2631
|
+
"$/tools/date": [date.getFullYear(), date.getMonth() + 1, date.getDate()].join("/") + " " + [date.getHours(), date.getMinutes(), date.getSeconds()].join(":")
|
|
2632
|
+
};
|
|
2633
|
+
}
|
|
2634
|
+
}
|
|
2635
|
+
};
|
|
2636
|
+
class ApiCall {
|
|
2637
|
+
constructor(api, slice) {
|
|
2638
|
+
__publicField(this, "operation");
|
|
2639
|
+
__publicField(this, "popField");
|
|
2640
|
+
__publicField(this, "request", {});
|
|
2641
|
+
/** Log response automatically */
|
|
2642
|
+
__publicField(this, "debugging");
|
|
2643
|
+
/**
|
|
2644
|
+
* Whitelist and alias fields. Alias of `fields()`
|
|
2645
|
+
* @example
|
|
2646
|
+
* ```ts
|
|
2647
|
+
* const id: {id: number, field2: any}[] = await new Slice<T>(12345)
|
|
2648
|
+
* .select().alias({id: 'id', field1: 'field2'}).exec().keys();
|
|
2649
|
+
* ```
|
|
2650
|
+
* @param {object} aliasKeyVals List of properties to whitelist and what to rename them to
|
|
2651
|
+
* @return {Slice<T>}
|
|
2652
|
+
*/
|
|
2653
|
+
__publicField(this, "alias", this.fields);
|
|
2654
|
+
this.api = api;
|
|
2655
|
+
this.slice = slice;
|
|
2656
|
+
}
|
|
2657
|
+
/** Get raw API request */
|
|
2658
|
+
get raw() {
|
|
2659
|
+
return clean({
|
|
2660
|
+
[this.operation]: {
|
|
2661
|
+
...this.request,
|
|
2662
|
+
slice: this.slice
|
|
2663
|
+
},
|
|
2664
|
+
"$pop": this.popField ? this.popField : void 0
|
|
2665
|
+
});
|
|
2666
|
+
}
|
|
2667
|
+
/**
|
|
2668
|
+
* Add an 'AND' condition inside the where argument
|
|
2669
|
+
* @example
|
|
2670
|
+
* ```ts
|
|
2671
|
+
* const rows: T[] = await new Slice<T>(12345).select()
|
|
2672
|
+
* .where('field1', '>', 1)
|
|
2673
|
+
* .and()
|
|
2674
|
+
* .where({field2: 2, field3: 3})
|
|
2675
|
+
* .exec().rows();
|
|
2676
|
+
* ```
|
|
2677
|
+
* @return {Slice<T>}
|
|
2678
|
+
*/
|
|
2679
|
+
and() {
|
|
2680
|
+
var _a;
|
|
2681
|
+
if (((_a = this.request.where) == null ? void 0 : _a[0]) == "$and") return this;
|
|
2682
|
+
if (this.request.where) this.request.where = ["$and", this.request.where];
|
|
2683
|
+
else this.request.where = ["$and"];
|
|
2684
|
+
return this;
|
|
2685
|
+
}
|
|
2686
|
+
/**
|
|
2687
|
+
* Count the returned rows
|
|
2688
|
+
* @example
|
|
2689
|
+
* ```ts
|
|
2690
|
+
* const count = await new Slice(12345).count()
|
|
2691
|
+
* .where({field1: 1})
|
|
2692
|
+
* .exec().count();
|
|
2693
|
+
* ```
|
|
2694
|
+
* @param {object | string} arg Count argument
|
|
2695
|
+
* @return {Slice<T>}
|
|
2696
|
+
*/
|
|
2697
|
+
count(arg = "id") {
|
|
2698
|
+
this.operation = "$/slice/report";
|
|
2699
|
+
this.request.fields = { count: ["$count", typeof arg == "object" ? arg : ["$field", arg]] };
|
|
2700
|
+
return this.pop("rows:0:count");
|
|
2701
|
+
}
|
|
2702
|
+
/**
|
|
2703
|
+
* Output the formed request to the console for inspection
|
|
2704
|
+
* @param {boolean} enabled Enable/Disable console logging
|
|
2705
|
+
* @return {Slice<T>}
|
|
2706
|
+
*/
|
|
2707
|
+
debug(enabled = true) {
|
|
2708
|
+
this.debugging = enabled;
|
|
2709
|
+
return this;
|
|
2710
|
+
}
|
|
2711
|
+
/**
|
|
2712
|
+
* Set the request type to delete
|
|
2713
|
+
* @example
|
|
2714
|
+
* ```ts
|
|
2715
|
+
* await new Slice(12345).delete(id).exec();
|
|
2716
|
+
* ```
|
|
2717
|
+
* @param {number | number[]} id ID(s) to delete
|
|
2718
|
+
* @return {Slice<T>}
|
|
2719
|
+
*/
|
|
2720
|
+
delete(id) {
|
|
2721
|
+
this.operation = "$/slice/delete";
|
|
2722
|
+
if (id) {
|
|
2723
|
+
if (Array.isArray(id)) this.where("id", "$in", id);
|
|
2724
|
+
else this.where("id", "==", id);
|
|
2725
|
+
}
|
|
2726
|
+
return this;
|
|
2727
|
+
}
|
|
2728
|
+
/**
|
|
2729
|
+
* Filter rows from slice based on an excel expression
|
|
2730
|
+
* @example
|
|
2731
|
+
* ```ts
|
|
2732
|
+
* const rows: T[] = await new Slice<T>(12345).select()
|
|
2733
|
+
* .excel('contains({property}, foobar)')
|
|
2734
|
+
* .exec().rows();
|
|
2735
|
+
* ```
|
|
2736
|
+
* @param formula Excel formula to use as where clause
|
|
2737
|
+
* @return {Slice<T>}
|
|
2738
|
+
*/
|
|
2739
|
+
excel(formula) {
|
|
2740
|
+
this.where(["$excel", formula]);
|
|
2741
|
+
return this;
|
|
2742
|
+
}
|
|
2743
|
+
/**
|
|
2744
|
+
* Compile the request and send it
|
|
2745
|
+
* @param {ApiRequestOptions} options API Request options
|
|
2746
|
+
* @return {Promise<T = any>} API response
|
|
2747
|
+
*/
|
|
2748
|
+
exec(options) {
|
|
2749
|
+
if (!this.operation) throw new Error("No operation chosen");
|
|
2750
|
+
const request = this.raw;
|
|
2751
|
+
return this.api.request(request, options).then((resp) => {
|
|
2752
|
+
if (this.debugging) console.log(resp);
|
|
2753
|
+
return resp;
|
|
2754
|
+
});
|
|
2755
|
+
}
|
|
2756
|
+
fields(keys) {
|
|
2757
|
+
this.request.fields = Array.isArray(keys) ? keys.reduce((acc, key) => ({ ...acc, [key]: key }), {}) : keys;
|
|
2758
|
+
return this;
|
|
2759
|
+
}
|
|
2760
|
+
/**
|
|
2761
|
+
* Unwrap response returning the first ID
|
|
2762
|
+
* @return {Slice<T>}
|
|
2763
|
+
*/
|
|
2764
|
+
id() {
|
|
2765
|
+
return this.pop("rows:0:id");
|
|
2766
|
+
}
|
|
2767
|
+
/**
|
|
2768
|
+
* Set the request type to insert
|
|
2769
|
+
* @example
|
|
2770
|
+
* ```ts
|
|
2771
|
+
* const id: number = await new Slice<T>(12345).insert([
|
|
2772
|
+
* {field1: 1},
|
|
2773
|
+
* {field1: 2}
|
|
2774
|
+
* ]).exec().keys();
|
|
2775
|
+
* ```
|
|
2776
|
+
* @param {T | T[]} rows Rows to be inserted into the slice
|
|
2777
|
+
* @return {Slice<T>}
|
|
2778
|
+
*/
|
|
2779
|
+
insert(rows) {
|
|
2780
|
+
this.operation = "$/slice/xinsert";
|
|
2781
|
+
if (!this.request.rows) this.request.rows = [];
|
|
2782
|
+
if (Array.isArray(rows)) this.request.rows = this.request.rows.concat(rows);
|
|
2783
|
+
else this.request.rows.push(rows);
|
|
2784
|
+
return this;
|
|
2785
|
+
}
|
|
2786
|
+
/**
|
|
2787
|
+
* Limit number of rows returned
|
|
2788
|
+
* @example
|
|
2789
|
+
* ```ts
|
|
2790
|
+
* const rows: T[] = await new Slice<T>(12345).select().limit(10)
|
|
2791
|
+
* .exec().rows();
|
|
2792
|
+
* ```
|
|
2793
|
+
* @param {number} num Number of rows to return
|
|
2794
|
+
* @return {Slice<T>}
|
|
2795
|
+
*/
|
|
2796
|
+
limit(num) {
|
|
2797
|
+
this.request.limit = num;
|
|
2798
|
+
return this;
|
|
2799
|
+
}
|
|
2800
|
+
/**
|
|
2801
|
+
* Add an 'OR' condition inside the where argument
|
|
2802
|
+
* @example
|
|
2803
|
+
* ```ts
|
|
2804
|
+
* const rows: T[] = await new Slice<T>(12345).select()
|
|
2805
|
+
* .where('field1', '>', 1)
|
|
2806
|
+
* .or()
|
|
2807
|
+
* .where({field2: 2, field3: 3})
|
|
2808
|
+
* .or()
|
|
2809
|
+
* .where(['$gt', ['$field', field4], 4)
|
|
2810
|
+
* .exec().rows();
|
|
2811
|
+
* ```
|
|
2812
|
+
* @return {Slice<T>}
|
|
2813
|
+
*/
|
|
2814
|
+
or() {
|
|
2815
|
+
var _a;
|
|
2816
|
+
if (((_a = this.request.where) == null ? void 0 : _a[0]) == "$or") {
|
|
2817
|
+
this.request.where.push(null);
|
|
2818
|
+
return this;
|
|
2819
|
+
}
|
|
2820
|
+
if (this.request.where) this.request.where = ["$or", this.request.where, null];
|
|
2821
|
+
else this.request.where = ["$or", null];
|
|
2822
|
+
return this;
|
|
2823
|
+
}
|
|
2824
|
+
/**
|
|
2825
|
+
* Order rows by a field
|
|
2826
|
+
* @example
|
|
2827
|
+
* ```ts
|
|
2828
|
+
* const rows: T[] = new Slice<T>(12345).select().order('field1', true) // true = ascending
|
|
2829
|
+
* .exec().rows();
|
|
2830
|
+
* ```
|
|
2831
|
+
* @param {string} field property name
|
|
2832
|
+
* @param {boolean} ascending Sort in ascending or descending order
|
|
2833
|
+
* @return {Slice<T>}
|
|
2834
|
+
*/
|
|
2835
|
+
order(field, ascending = true) {
|
|
2836
|
+
if (!this.request.order) this.request.order = [];
|
|
2837
|
+
this.request.order.push([ascending ? "$asc" : "$desc", ["$field", field]]);
|
|
2838
|
+
return this;
|
|
2839
|
+
}
|
|
2840
|
+
/**
|
|
2841
|
+
* Unwrap response, returning the field
|
|
2842
|
+
* @param {string} field Colon seperated path: `rows:0`
|
|
2843
|
+
* @return {Slice<T>}
|
|
2844
|
+
*/
|
|
2845
|
+
pop(field) {
|
|
2846
|
+
this.popField = field;
|
|
2847
|
+
return this;
|
|
2848
|
+
}
|
|
2849
|
+
/**
|
|
2850
|
+
* Unwrap response returning the first row
|
|
2851
|
+
* @return {Slice<T>}
|
|
2852
|
+
*/
|
|
2853
|
+
row() {
|
|
2854
|
+
return this.pop("rows:0");
|
|
2855
|
+
}
|
|
2856
|
+
/**
|
|
2857
|
+
* Unwrap response returning the rows
|
|
2858
|
+
* @return {Slice<T>}
|
|
2859
|
+
*/
|
|
2860
|
+
rows() {
|
|
2861
|
+
return this.pop("rows");
|
|
2862
|
+
}
|
|
2863
|
+
/**
|
|
2864
|
+
* Save multiple rows to the slice, automatically inserts/updates
|
|
2865
|
+
* @param {T} rows Rows to add to slice
|
|
2866
|
+
* @returns {this<T>}
|
|
2867
|
+
*/
|
|
2868
|
+
save(rows) {
|
|
2869
|
+
this.operation = "$/slice/multisave";
|
|
2870
|
+
this.request.rows = makeArray(rows);
|
|
2871
|
+
return this;
|
|
2872
|
+
}
|
|
2873
|
+
/**
|
|
2874
|
+
* Set the request type to select
|
|
2875
|
+
* @example
|
|
2876
|
+
* ```ts
|
|
2877
|
+
* const rows: T[] = new Slice<T>(12345).select().exec().rows();
|
|
2878
|
+
* const row: T = new Slice<T>(12345).select(id).exec().row();
|
|
2879
|
+
* ```
|
|
2880
|
+
* @param {number | number[]} id ID(s) to select, leaving blank will return all rows
|
|
2881
|
+
* @return {Slice<T>}
|
|
2882
|
+
*/
|
|
2883
|
+
select(id) {
|
|
2884
|
+
this.operation = "$/slice/report";
|
|
2885
|
+
if (id) {
|
|
2886
|
+
if (Array.isArray(id)) this.where("id", "$in", id);
|
|
2887
|
+
else this.where("id", "==", id);
|
|
2888
|
+
}
|
|
2889
|
+
return this;
|
|
2890
|
+
}
|
|
2891
|
+
/**
|
|
2892
|
+
* Set the request type to update
|
|
2893
|
+
* @example
|
|
2894
|
+
* ```ts
|
|
2895
|
+
* const ids: number[] = await new Slice<Type>(12345).update([
|
|
2896
|
+
* {id: 1, field1: 1},
|
|
2897
|
+
* {id: 2, field1: 1}
|
|
2898
|
+
* ]).exec().keys();
|
|
2899
|
+
* ```
|
|
2900
|
+
* @param {T | T[]} rows Rows to be updated, each row must have an ID
|
|
2901
|
+
* @return {Slice<T>}
|
|
2902
|
+
*/
|
|
2903
|
+
update(rows) {
|
|
2904
|
+
this.operation = "$/slice/xupdate";
|
|
2905
|
+
if (!this.request.rows) this.request.rows = [];
|
|
2906
|
+
if (Array.isArray(rows)) this.request.rows = this.request.rows.concat(rows);
|
|
2907
|
+
else this.request.rows.push(rows);
|
|
2908
|
+
return this;
|
|
2909
|
+
}
|
|
2910
|
+
/**
|
|
2911
|
+
* Add where condition to request
|
|
2912
|
+
* @example
|
|
2913
|
+
* ```ts
|
|
2914
|
+
* const rows: T[] = await new Slice<T>(12345).select()
|
|
2915
|
+
* .where('field1', '>', 1)
|
|
2916
|
+
* .where({field2: 2, field3: 3}) // Automatic AND
|
|
2917
|
+
* .or()
|
|
2918
|
+
* .where(['$gt', ['$field', field4], 4)
|
|
2919
|
+
* .exec().rows();
|
|
2920
|
+
* ```
|
|
2921
|
+
* @param {string | object} field property to compare or a map of equality comparisons
|
|
2922
|
+
* @param {string} operator Operation to compare with. Accepts JS operators (>=, ==, !=, ...) as well as datalynk styax ($gte, $eq, $is, $not, ...)
|
|
2923
|
+
* @param {any} value value to compare against
|
|
2924
|
+
* @return {Slice<T>}
|
|
2925
|
+
*/
|
|
2926
|
+
where(field, operator, value) {
|
|
2927
|
+
if (this.request.where && this.request.where[0] != "$or") this.and();
|
|
2928
|
+
const raw = Array.isArray(field);
|
|
2929
|
+
if (typeof field == "object" && !raw) {
|
|
2930
|
+
Object.entries(field).forEach(([key, value2]) => this.where(key, "==", value2));
|
|
2931
|
+
} else {
|
|
2932
|
+
const w = raw ? field : [(() => {
|
|
2933
|
+
if (operator == null ? void 0 : operator.startsWith("$")) return operator;
|
|
2934
|
+
if (operator == "==") return "$eq";
|
|
2935
|
+
if (operator == "!=") return "$neq";
|
|
2936
|
+
if (operator == ">") return "$gt";
|
|
2937
|
+
if (operator == ">=") return "$gte";
|
|
2938
|
+
if (operator == "<") return "$lt";
|
|
2939
|
+
if (operator == "<=") return "$lte";
|
|
2940
|
+
if (operator == "!") return "$not";
|
|
2941
|
+
if (operator == "%") return "$mod";
|
|
2942
|
+
if (operator == null ? void 0 : operator.startsWith("$")) return operator;
|
|
2943
|
+
throw new Error(`Unknown operator: ${operator}`);
|
|
2944
|
+
})(), ["$field", field], value];
|
|
2945
|
+
if (!this.request.where) this.request.where = w;
|
|
2946
|
+
else {
|
|
2947
|
+
if (this.request.where[0] == "$or") {
|
|
2948
|
+
const i = this.request.where.length - 1;
|
|
2949
|
+
if (this.request.where[i] == null) this.request.where[i] = w;
|
|
2950
|
+
else {
|
|
2951
|
+
if (this.request.where[i][0] == "$and") this.request.where[i].push(w);
|
|
2952
|
+
else this.request.where[i] = ["$and", this.request.where[i], w];
|
|
2953
|
+
}
|
|
2954
|
+
} else this.request.where.push(w);
|
|
2955
|
+
}
|
|
2956
|
+
}
|
|
2957
|
+
return this;
|
|
2958
|
+
}
|
|
2959
|
+
}
|
|
2960
|
+
class Slice {
|
|
2961
|
+
/**
|
|
2962
|
+
* An object to aid in constructing requests
|
|
2963
|
+
*
|
|
2964
|
+
* @param {number} slice Slice ID to interact with
|
|
2965
|
+
* @param {Api} api Api to send the requests through
|
|
2966
|
+
*/
|
|
2967
|
+
constructor(slice, api) {
|
|
2968
|
+
__publicField(this, "table");
|
|
2969
|
+
__publicField(this, "info");
|
|
2970
|
+
__publicField(this, "pendingInsert", 0);
|
|
2971
|
+
/** Unsubscribe from changes, undefined if not subscribed */
|
|
2972
|
+
__publicField(this, "unsubscribe");
|
|
2973
|
+
/** Cached slice data as an observable */
|
|
2974
|
+
__publicField(this, "cache$", new BehaviorSubject([]));
|
|
2975
|
+
var _a;
|
|
2976
|
+
this.slice = slice;
|
|
2977
|
+
this.api = api;
|
|
2978
|
+
if (this.offlineEnabled) {
|
|
2979
|
+
this.table = (_a = api.database) == null ? void 0 : _a.table(slice.toString());
|
|
2980
|
+
this.table.getAll().then((resp) => this.cache = resp);
|
|
2981
|
+
this.cache$.pipe(skip(1)).subscribe(async (cache) => {
|
|
2982
|
+
var _a2;
|
|
2983
|
+
await ((_a2 = this.table) == null ? void 0 : _a2.clear());
|
|
2984
|
+
await Promise.all(cache.map((c) => {
|
|
2985
|
+
var _a3;
|
|
2986
|
+
return (_a3 = this.table) == null ? void 0 : _a3.put(c.id, c);
|
|
2987
|
+
}));
|
|
2988
|
+
this.fixIncrement();
|
|
2989
|
+
});
|
|
2990
|
+
this.sync();
|
|
2991
|
+
window.addEventListener("online", async () => {
|
|
2992
|
+
if (this.api.expired) await lastValueFrom(this.api.auth.user$.pipe(skip(1), takeWhile((u) => !u || this.api.expired, true)));
|
|
2993
|
+
this.pushChanges();
|
|
2994
|
+
});
|
|
2995
|
+
}
|
|
2996
|
+
}
|
|
2997
|
+
/** Cached slice data */
|
|
2998
|
+
get cache() {
|
|
2999
|
+
return this.cache$.getValue();
|
|
3000
|
+
}
|
|
3001
|
+
/** Set cached data & alert subscribers */
|
|
3002
|
+
set cache(cache) {
|
|
3003
|
+
this.cache$.next(cache);
|
|
3004
|
+
}
|
|
3005
|
+
/** Is slice offline support enabled */
|
|
3006
|
+
get offlineEnabled() {
|
|
3007
|
+
var _a;
|
|
3008
|
+
return (_a = this.api.database) == null ? void 0 : _a.includes(this.slice.toString());
|
|
3009
|
+
}
|
|
3010
|
+
fixIncrement() {
|
|
3011
|
+
var _a;
|
|
3012
|
+
this.pendingInsert = ((_a = this.cache.toSorted(sortByProp("id")).pop()) == null ? void 0 : _a["id"]) || 0;
|
|
3013
|
+
}
|
|
3014
|
+
execWrapper(call) {
|
|
3015
|
+
const onlineExec = call.exec.bind(call);
|
|
3016
|
+
return () => {
|
|
3017
|
+
if (this.offlineEnabled && navigator && !(navigator == null ? void 0 : navigator.onLine)) {
|
|
3018
|
+
const where = (row, condition) => {
|
|
3019
|
+
if (Array.isArray(condition) ? !condition.length : condition == null) return true;
|
|
3020
|
+
if (!Array.isArray(condition)) return condition;
|
|
3021
|
+
if (condition[0] == "$field") return row[condition[1]];
|
|
3022
|
+
if (condition[0] == "$not") return !where(row, condition.slice(1));
|
|
3023
|
+
if (condition[0] == "$and") return condition.slice(1).filter((v) => where(row, v)).length == condition.length - 1;
|
|
3024
|
+
if (condition[0] == "$or") return !!condition.slice(1).find((v) => where(row, v));
|
|
3025
|
+
if (condition[0] == "$eq") return where(row, condition[1]) == where(row, condition[2]);
|
|
3026
|
+
if (condition[0] == "$neq") return where(row, condition[1]) != where(row, condition[2]);
|
|
3027
|
+
if (condition[0] == "$gt") return where(row, condition[1]) > where(row, condition[2]);
|
|
3028
|
+
if (condition[0] == "$gte") return where(row, condition[1]) >= where(row, condition[2]);
|
|
3029
|
+
if (condition[0] == "$lt") return where(row, condition[1]) < where(row, condition[2]);
|
|
3030
|
+
if (condition[0] == "$lte") return where(row, condition[1]) <= where(row, condition[2]);
|
|
3031
|
+
if (condition[0] == "$mod") return where(row, condition[1]) % where(row, condition[2]);
|
|
3032
|
+
return condition[0];
|
|
3033
|
+
};
|
|
3034
|
+
let request = call.raw, resp = {};
|
|
3035
|
+
if (request["$/slice/delete"]) {
|
|
3036
|
+
const found = this.cache.filter((r) => where(r, request["$/slice/delete"]["where"])).map((r) => r.id);
|
|
3037
|
+
this.cache = this.cache.map((r) => found.includes(r.id) ? { ...r, _sync: "delete" } : r);
|
|
3038
|
+
resp = {
|
|
3039
|
+
affected: found.length,
|
|
3040
|
+
"ignored-keys": [],
|
|
3041
|
+
keys: found,
|
|
3042
|
+
tx: null
|
|
3043
|
+
};
|
|
3044
|
+
} else if (request["$/slice/report"]) {
|
|
3045
|
+
resp["rows"] = deepCopy(this.cache).filter((r) => (r == null ? void 0 : r._sync) != "delete").filter((r) => r && where(r, request["$/slice/report"]["where"]));
|
|
3046
|
+
if (request["order"]) resp["rows"] = resp["rows"].toSorted(sortByProp(request["order"][1][1], request["order"] == "$desc"));
|
|
3047
|
+
if (request["limit"]) resp["rows"] = resp["rows"].slice(0, request["limit"]);
|
|
3048
|
+
if (request["fields"]) {
|
|
3049
|
+
if (request["fields"]["$count"]) resp["rows"] = { count: resp["rows"].length };
|
|
3050
|
+
else resp["rows"] = resp["rows"].map((r) => Object.entries(request["fields"]).reduce((acc, [k, v]) => ({
|
|
3051
|
+
...acc,
|
|
3052
|
+
[v]: r[k]
|
|
3053
|
+
}), {}));
|
|
3054
|
+
}
|
|
3055
|
+
} else if (request["$/slice/xinsert"]) {
|
|
3056
|
+
const rows = request["$/slice/xinsert"]["rows"].map((r) => ({
|
|
3057
|
+
...r,
|
|
3058
|
+
id: -++this.pendingInsert,
|
|
3059
|
+
_sync: "insert"
|
|
3060
|
+
}));
|
|
3061
|
+
this.cache = [...this.cache, ...rows];
|
|
3062
|
+
resp = {
|
|
3063
|
+
failed: [],
|
|
3064
|
+
granted: rows.map((r) => Object.keys(r).reduce((acc, key) => ({ ...acc, [key]: true }), {})),
|
|
3065
|
+
"ignored-fields": [],
|
|
3066
|
+
keys: rows.map((r) => r.id),
|
|
3067
|
+
publish: 1,
|
|
3068
|
+
tx: null
|
|
3069
|
+
};
|
|
3070
|
+
} else if (request["$/slice/xupdate"]) {
|
|
3071
|
+
const ids = request["$/slice/xupdate"]["rows"].map((r) => r.id);
|
|
3072
|
+
this.cache = [
|
|
3073
|
+
...this.cache.filter((c) => !ids.includes(c.id)),
|
|
3074
|
+
...request["$/slice/xupdate"]["rows"].map((r) => ({ ...r, _sync: "update" }))
|
|
3075
|
+
].toSorted(sortByProp("id"));
|
|
3076
|
+
resp = {
|
|
3077
|
+
failed: [],
|
|
3078
|
+
granted: request["$/slice/xupdate"]["rows"].map((r) => Object.keys(r).reduce((acc, key) => ({
|
|
3079
|
+
...acc,
|
|
3080
|
+
[key]: true
|
|
3081
|
+
}), {})),
|
|
3082
|
+
"ignored-fields": [],
|
|
3083
|
+
keys: request["$/slice/xupdate"]["rows"].map((r) => r.id),
|
|
3084
|
+
publish: 1,
|
|
3085
|
+
tx: null
|
|
3086
|
+
};
|
|
3087
|
+
}
|
|
3088
|
+
if (request["$pop"]) {
|
|
3089
|
+
resp = request["$pop"].split(":").reduce((acc, key) => acc[JSONAttemptParse(key)], resp);
|
|
3090
|
+
}
|
|
3091
|
+
return Promise.resolve(resp);
|
|
3092
|
+
} else {
|
|
3093
|
+
return onlineExec();
|
|
3094
|
+
}
|
|
3095
|
+
};
|
|
3096
|
+
}
|
|
3097
|
+
async pushChanges() {
|
|
3098
|
+
if (this.offlineEnabled && navigator && navigator.onLine) {
|
|
3099
|
+
await Promise.allSettled(
|
|
3100
|
+
this.cache.values().map((value) => {
|
|
3101
|
+
if (value._sync == "delete") {
|
|
3102
|
+
return this.delete(value.id).exec();
|
|
3103
|
+
} else if (value._sync == "insert") {
|
|
3104
|
+
return this.insert({ ...value, id: void 0, _sync: void 0 }).exec();
|
|
3105
|
+
} else if (value._sync == "update") {
|
|
3106
|
+
return this.update({
|
|
3107
|
+
...value,
|
|
3108
|
+
_sync: void 0
|
|
3109
|
+
}).where("_updatedDate", "==", value.modified).exec();
|
|
3110
|
+
}
|
|
3111
|
+
}).filter((r) => !!r)
|
|
3112
|
+
);
|
|
3113
|
+
}
|
|
3114
|
+
}
|
|
3115
|
+
/**
|
|
3116
|
+
* Get slice information
|
|
3117
|
+
* @param reload Ignore cache & reload info
|
|
3118
|
+
* @return {Promise<SliceInfo>}
|
|
3119
|
+
*/
|
|
3120
|
+
async getInfo(reload) {
|
|
3121
|
+
var _a, _b, _c;
|
|
3122
|
+
const getType = (field) => {
|
|
3123
|
+
if (field.options) {
|
|
3124
|
+
let t = field.options.split("|").map((o) => `'${o}'`).join(" | ");
|
|
3125
|
+
if (field.type == "control_checkbox") t = `(${t})[]`;
|
|
3126
|
+
return t;
|
|
3127
|
+
}
|
|
3128
|
+
if (field.type == "control_checkbox" || field.type == "boolean") return "boolean";
|
|
3129
|
+
if (field.type == "control_new_date" || field.type == "control_new_time" || field.type == "control_new_datetime" || field.type == "Date")
|
|
3130
|
+
return "Date";
|
|
3131
|
+
if (field.type == "control_number" || field.type == "number") return "number";
|
|
3132
|
+
return "string";
|
|
3133
|
+
};
|
|
3134
|
+
if (this.info && !reload) return Promise.resolve(this.info);
|
|
3135
|
+
this.info = await this.api.request({ "$/slice/fetch": { slice: this.slice } });
|
|
3136
|
+
const fields = ((_c = (_b = (_a = this.info) == null ? void 0 : _a.meta) == null ? void 0 : _b.presentation) == null ? void 0 : _c.fields) ? Object.values(this.info.meta.presentation.fields) : [];
|
|
3137
|
+
this.info.types = fields.filter((value) => value.id != void 0).map((value) => {
|
|
3138
|
+
var _a2;
|
|
3139
|
+
return {
|
|
3140
|
+
key: value.id.toString(),
|
|
3141
|
+
options: (_a2 = value.options) == null ? void 0 : _a2.split("|"),
|
|
3142
|
+
readonly: !!value.readonly || value.id.startsWith("fid") || ["id", "creatorRef", "created", "modifierRef", "modified"].includes(value.id),
|
|
3143
|
+
required: !!value.required,
|
|
3144
|
+
type: getType(value)
|
|
3145
|
+
};
|
|
3146
|
+
});
|
|
3147
|
+
return this.info;
|
|
3148
|
+
}
|
|
3149
|
+
/**
|
|
3150
|
+
* Synchronize cache with server
|
|
3151
|
+
* @example
|
|
3152
|
+
* ```ts
|
|
3153
|
+
* const slice: Slice = new Slice<T>(Slices.Contact);
|
|
3154
|
+
* slice.sync().subscribe((rows: T[]) => {});
|
|
3155
|
+
* ```
|
|
3156
|
+
* @param {boolean} on Enable/disable events
|
|
3157
|
+
* @return {BehaviorSubject<T[]>} Cache which can be subscribed to
|
|
3158
|
+
*/
|
|
3159
|
+
sync(on = true) {
|
|
3160
|
+
if (on) {
|
|
3161
|
+
this.pushChanges().then(() => this.select().rows().exec().then((rows) => this.cache = rows));
|
|
3162
|
+
if (!this.unsubscribe) this.unsubscribe = this.api.socket.sliceEvents(this.slice, (event) => {
|
|
3163
|
+
const ids = [...event.data.new, ...event.data.changed];
|
|
3164
|
+
this.select(ids).rows().exec().then((rows) => this.cache = [...this.cache.filter((c) => c.id != null && !ids.includes(c.id)), ...rows]);
|
|
3165
|
+
this.cache = this.cache.filter((v) => v.id && !event.data.lost.includes(v.id));
|
|
3166
|
+
});
|
|
3167
|
+
return this.cache$;
|
|
3168
|
+
} else if (this.unsubscribe) {
|
|
3169
|
+
this.unsubscribe();
|
|
3170
|
+
this.unsubscribe = null;
|
|
3171
|
+
}
|
|
3172
|
+
}
|
|
3173
|
+
// Transaction wrapper =============================================================================================
|
|
3174
|
+
/**
|
|
3175
|
+
* {@inheritDoc ApiCall.count}
|
|
3176
|
+
*/
|
|
3177
|
+
count(arg = "id") {
|
|
3178
|
+
const call = new ApiCall(this.api, this.slice);
|
|
3179
|
+
call.exec = this.execWrapper(call);
|
|
3180
|
+
return call.count(arg);
|
|
3181
|
+
}
|
|
3182
|
+
/**
|
|
3183
|
+
* {@inheritDoc ApiCall.delete}
|
|
3184
|
+
*/
|
|
3185
|
+
delete(id) {
|
|
3186
|
+
const call = new ApiCall(this.api, this.slice);
|
|
3187
|
+
call.exec = this.execWrapper(call);
|
|
3188
|
+
return call.delete(id);
|
|
3189
|
+
}
|
|
3190
|
+
/**
|
|
3191
|
+
* {@inheritDoc ApiCall.insert}
|
|
3192
|
+
*/
|
|
3193
|
+
insert(rows) {
|
|
3194
|
+
const call = new ApiCall(this.api, this.slice);
|
|
3195
|
+
call.exec = this.execWrapper(call);
|
|
3196
|
+
return call.insert(rows);
|
|
3197
|
+
}
|
|
3198
|
+
/**
|
|
3199
|
+
* {@inheritDoc ApiCall.save}
|
|
3200
|
+
*/
|
|
3201
|
+
save(rows) {
|
|
3202
|
+
const call = new ApiCall(this.api, this.slice);
|
|
3203
|
+
call.exec = this.execWrapper(call);
|
|
3204
|
+
return call.save(rows);
|
|
3205
|
+
}
|
|
3206
|
+
/**
|
|
3207
|
+
* {@inheritDoc ApiCall.select}
|
|
3208
|
+
*/
|
|
3209
|
+
select(id) {
|
|
3210
|
+
const call = new ApiCall(this.api, this.slice);
|
|
3211
|
+
call.exec = this.execWrapper(call);
|
|
3212
|
+
return call.select(id);
|
|
3213
|
+
}
|
|
3214
|
+
/**
|
|
3215
|
+
* {@inheritDoc ApiCall.update}
|
|
3216
|
+
*/
|
|
3217
|
+
update(rows) {
|
|
3218
|
+
const call = new ApiCall(this.api, this.slice);
|
|
3219
|
+
call.exec = this.execWrapper(call);
|
|
3220
|
+
return call.update(rows);
|
|
3221
|
+
}
|
|
3222
|
+
}
|
|
3223
|
+
class Socket {
|
|
3224
|
+
constructor(api, options = {}) {
|
|
3225
|
+
__publicField(this, "listeners", []);
|
|
3226
|
+
// [ Callback, Re-subscribe ]
|
|
3227
|
+
__publicField(this, "retry");
|
|
3228
|
+
__publicField(this, "socket");
|
|
3229
|
+
__publicField(this, "open", false);
|
|
3230
|
+
this.api = api;
|
|
3231
|
+
this.options = options;
|
|
3232
|
+
if (!options.url && options.url !== false) {
|
|
3233
|
+
const url = new URL(this.api.url.replace("http", "ws"));
|
|
3234
|
+
url.port = "9390";
|
|
3235
|
+
this.options.url = url.origin;
|
|
3236
|
+
}
|
|
3237
|
+
if (this.options.url !== false)
|
|
3238
|
+
api.token$.pipe(filter((u) => u !== void 0), distinctUntilChanged()).subscribe(() => this.connect());
|
|
3239
|
+
}
|
|
3240
|
+
/**
|
|
3241
|
+
* Add listener for all socket events
|
|
3242
|
+
*
|
|
3243
|
+
* @param {SocketListener} fn Callback function
|
|
3244
|
+
*
|
|
3245
|
+
*
|
|
3246
|
+
*
|
|
3247
|
+
*
|
|
3248
|
+
* @return {Unsubscribe} Function to unsubscribe callback
|
|
3249
|
+
*/
|
|
3250
|
+
addListener(fn, reconnect) {
|
|
3251
|
+
this.listeners.push([fn, reconnect]);
|
|
3252
|
+
if (this.open) reconnect();
|
|
3253
|
+
return () => this.listeners = this.listeners.filter((l) => l[0] != fn);
|
|
3254
|
+
}
|
|
3255
|
+
/**
|
|
3256
|
+
* Close socket connection
|
|
3257
|
+
*/
|
|
3258
|
+
close() {
|
|
3259
|
+
var _a;
|
|
3260
|
+
if (this.open) console.debug("Datalynk socket: disconnected");
|
|
3261
|
+
this.open = false;
|
|
3262
|
+
(_a = this.socket) == null ? void 0 : _a.close();
|
|
3263
|
+
this.socket = void 0;
|
|
3264
|
+
if (this.retry) clearTimeout(this.retry);
|
|
3265
|
+
this.retry = null;
|
|
3266
|
+
}
|
|
3267
|
+
/**
|
|
3268
|
+
* Connect socket client to socket server
|
|
3269
|
+
* @param {number} timeout Retry to connect every x seconds
|
|
3270
|
+
*/
|
|
3271
|
+
connect(timeout = 30) {
|
|
3272
|
+
if (this.options.url === false) return console.warn("Datalynk socket disabled");
|
|
3273
|
+
if (this.open) this.close();
|
|
3274
|
+
this.retry = setTimeout(() => {
|
|
3275
|
+
if (this.open) return;
|
|
3276
|
+
this.close();
|
|
3277
|
+
this.connect();
|
|
3278
|
+
}, timeout * 1e3);
|
|
3279
|
+
if (navigator.onLine) {
|
|
3280
|
+
this.socket = new WebSocket(this.options.url + (this.api.token ? `?token=${this.api.token}&origin=${location.href}` : ""));
|
|
3281
|
+
this.socket.onopen = () => clearTimeout(this.retry);
|
|
3282
|
+
this.socket.onclose = () => {
|
|
3283
|
+
if (this.open) this.connect(timeout);
|
|
3284
|
+
};
|
|
3285
|
+
this.socket.onmessage = (message) => {
|
|
3286
|
+
const payload = JSON.parse(message.data);
|
|
3287
|
+
if (payload.connected != void 0) {
|
|
3288
|
+
if (payload.connected) {
|
|
3289
|
+
this.open = true;
|
|
3290
|
+
console.debug("Datalynk socket: connected");
|
|
3291
|
+
this.listeners.forEach((l) => l[1]());
|
|
3292
|
+
} else {
|
|
3293
|
+
throw new Error(`Datalynk socket failed: ${payload.error}`);
|
|
3294
|
+
}
|
|
3295
|
+
} else {
|
|
3296
|
+
this.listeners.forEach((l) => l[0](payload));
|
|
3297
|
+
}
|
|
3298
|
+
};
|
|
3299
|
+
}
|
|
3300
|
+
}
|
|
3301
|
+
/**
|
|
3302
|
+
* Send data to socket server
|
|
3303
|
+
*
|
|
3304
|
+
* @param payload Data that will be serialized
|
|
3305
|
+
*/
|
|
3306
|
+
send(payload) {
|
|
3307
|
+
var _a;
|
|
3308
|
+
if (!this.open) throw new Error("Datalynk socket not connected");
|
|
3309
|
+
(_a = this.socket) == null ? void 0 : _a.send(JSON.stringify(payload));
|
|
3310
|
+
}
|
|
3311
|
+
/**
|
|
3312
|
+
* Run callback whenever the server notifies us of slice changes
|
|
3313
|
+
*
|
|
3314
|
+
* @param {number | number[]} slice Slice to subscribe to
|
|
3315
|
+
* @param {SocketListener<SocketEventSlice>} callback Function to run on changes
|
|
3316
|
+
* @return {Unsubscribe} Run returned function to unsubscribe callback
|
|
3317
|
+
*/
|
|
3318
|
+
sliceEvents(slice, callback) {
|
|
3319
|
+
const unsubscribe = this.addListener((event) => {
|
|
3320
|
+
if (event.type == "sliceEvents" && event.data.slice == slice) callback(event);
|
|
3321
|
+
}, () => this.send({ onSliceEvents: slice }));
|
|
3322
|
+
return () => {
|
|
3323
|
+
this.send({ offSliceEvents: slice });
|
|
3324
|
+
unsubscribe();
|
|
3325
|
+
};
|
|
3326
|
+
}
|
|
3327
|
+
}
|
|
3328
|
+
class Superuser {
|
|
3329
|
+
constructor(api) {
|
|
3330
|
+
this.api = api;
|
|
3331
|
+
}
|
|
3332
|
+
/**
|
|
3333
|
+
* Switch to another user by ID
|
|
3334
|
+
*
|
|
3335
|
+
* @param {number} userId User ID
|
|
3336
|
+
* @return {Promise<any>} New session
|
|
3337
|
+
*/
|
|
3338
|
+
assume(userId) {
|
|
3339
|
+
return this.api.request({ "$/report/users/become": { id: userId } }).then((resp) => {
|
|
3340
|
+
if (resp.token) this.api.token = resp.token;
|
|
3341
|
+
return resp;
|
|
3342
|
+
});
|
|
3343
|
+
}
|
|
3344
|
+
/**
|
|
3345
|
+
* Enable the superuser flag, required to make any of the requests in this helper
|
|
3346
|
+
*
|
|
3347
|
+
* @param {string} username Superuser account
|
|
3348
|
+
* @param {string} password Superuser password
|
|
3349
|
+
* @return {Promise<any>} Unknown
|
|
3350
|
+
*/
|
|
3351
|
+
enable(username, password) {
|
|
3352
|
+
return this.api.request({ "$/superuser/validate": {
|
|
3353
|
+
name: username,
|
|
3354
|
+
password
|
|
3355
|
+
} });
|
|
3356
|
+
}
|
|
3357
|
+
}
|
|
3358
|
+
const version = "1.2.5";
|
|
3359
|
+
class WebRtc {
|
|
3360
|
+
constructor(api) {
|
|
3361
|
+
__publicField(this, "ice");
|
|
3362
|
+
var _a, _b, _c, _d, _e, _f;
|
|
3363
|
+
this.api = api;
|
|
3364
|
+
this.ice = [
|
|
3365
|
+
...((_b = (_a = api.options) == null ? void 0 : _a.webrtc) == null ? void 0 : _b.ice) || [],
|
|
3366
|
+
{ urls: ["stun:" + ((_c = this.api.options.webrtc) == null ? void 0 : _c.url)] },
|
|
3367
|
+
clean({
|
|
3368
|
+
urls: ["turn:" + ((_d = this.api.options.webrtc) == null ? void 0 : _d.url)],
|
|
3369
|
+
username: (_e = this.api.options.webrtc) == null ? void 0 : _e.username,
|
|
3370
|
+
credential: (_f = this.api.options.webrtc) == null ? void 0 : _f.password
|
|
3371
|
+
})
|
|
3372
|
+
];
|
|
3373
|
+
}
|
|
3374
|
+
async answer(offer, stream) {
|
|
3375
|
+
const rtc = new RTCPeerConnection({ iceServers: this.ice });
|
|
3376
|
+
stream.getTracks().forEach((track) => rtc.addTrack(track, stream));
|
|
3377
|
+
await rtc.setRemoteDescription(new RTCSessionDescription(offer));
|
|
3378
|
+
const answer = await rtc.createAnswer();
|
|
3379
|
+
await rtc.setLocalDescription(answer);
|
|
3380
|
+
await new Promise((res) => {
|
|
3381
|
+
if (rtc.iceGatheringState === "complete") return res();
|
|
3382
|
+
rtc.onicegatheringstatechange = () => {
|
|
3383
|
+
if (rtc.iceGatheringState === "complete") res();
|
|
3384
|
+
};
|
|
3385
|
+
});
|
|
3386
|
+
return rtc;
|
|
3387
|
+
}
|
|
3388
|
+
async offer(stream) {
|
|
3389
|
+
const rtc = new RTCPeerConnection({ iceServers: this.ice });
|
|
3390
|
+
stream.getTracks().forEach((track) => rtc.addTrack(track, stream));
|
|
3391
|
+
await rtc.setLocalDescription(await rtc.createOffer());
|
|
3392
|
+
await new Promise((res) => {
|
|
3393
|
+
if (rtc.iceGatheringState === "complete") return res();
|
|
3394
|
+
rtc.onicegatheringstatechange = () => {
|
|
3395
|
+
if (rtc.iceGatheringState === "complete") res();
|
|
3396
|
+
};
|
|
3397
|
+
});
|
|
3398
|
+
return rtc;
|
|
3399
|
+
}
|
|
3400
|
+
/**
|
|
3401
|
+
* Create a new WebRTC connection to a room
|
|
3402
|
+
* @param {string} id Room ID
|
|
3403
|
+
* @param {boolean} audio Stream local audio to room/peers
|
|
3404
|
+
* @param {boolean} video Stream local video to room/peers
|
|
3405
|
+
* @returns {Promise<WebRTCSession>} Connection session
|
|
3406
|
+
*/
|
|
3407
|
+
async connect(id = randomStringBuilder(16, true, true), audio = true, video = true) {
|
|
3408
|
+
const session = {
|
|
3409
|
+
open: true,
|
|
3410
|
+
id,
|
|
3411
|
+
uid: randomStringBuilder(8, true, true),
|
|
3412
|
+
peers: {},
|
|
3413
|
+
stream: await navigator.mediaDevices.getUserMedia({ audio, video }),
|
|
3414
|
+
disconnect: null,
|
|
3415
|
+
onConnected: null
|
|
3416
|
+
};
|
|
3417
|
+
const handleTracks = (session2, uid) => {
|
|
3418
|
+
if (!session2.open || !session2.onConnected) return;
|
|
3419
|
+
const peer = session2.peers[uid];
|
|
3420
|
+
const streams = peer.connection.getRemoteStreams();
|
|
3421
|
+
if (streams[0]) session2.onConnected(peer, streams[0]);
|
|
3422
|
+
else peer.connection.ontrack = ({ streams: streams2 }) => {
|
|
3423
|
+
if (session2.open && session2.onConnected) session2.onConnected(peer, streams2[0]);
|
|
3424
|
+
};
|
|
3425
|
+
};
|
|
3426
|
+
const unsubscribe = this.api.socket.addListener(async (event) => {
|
|
3427
|
+
var _a, _b, _c, _d;
|
|
3428
|
+
const key = Object.keys(event)[0];
|
|
3429
|
+
if (key == `webrtc/${id}`) {
|
|
3430
|
+
if (event[key].connected) {
|
|
3431
|
+
const payload = event[key].connected;
|
|
3432
|
+
session.peers[payload.uid] = {
|
|
3433
|
+
uid: payload.uid,
|
|
3434
|
+
username: payload.username,
|
|
3435
|
+
connection: await this.offer(session.stream)
|
|
3436
|
+
};
|
|
3437
|
+
this.api.socket.send({ [`webrtc/${id}`]: { offer: {
|
|
3438
|
+
to: payload.uid,
|
|
3439
|
+
uid: session.uid,
|
|
3440
|
+
username: (_a = this.api.auth.user) == null ? void 0 : _a.login,
|
|
3441
|
+
offer: session.peers[payload.uid].connection.localDescription
|
|
3442
|
+
} } });
|
|
3443
|
+
} else if (event[key].disconnected) {
|
|
3444
|
+
session.peers[event[key].disconnected.uid].connection.close();
|
|
3445
|
+
delete session.peers[event[key].disconnected.uid];
|
|
3446
|
+
} else if (event[key].offer && event[key].offer.to == session.uid) {
|
|
3447
|
+
const payload = event[key].offer;
|
|
3448
|
+
session.peers[payload.uid] = {
|
|
3449
|
+
uid: payload.uid,
|
|
3450
|
+
username: payload.username,
|
|
3451
|
+
connection: await this.answer(payload.offer, session.stream)
|
|
3452
|
+
};
|
|
3453
|
+
this.api.socket.send({ [`webrtc/${id}`]: { answer: {
|
|
3454
|
+
to: payload.uid,
|
|
3455
|
+
uid: session.uid,
|
|
3456
|
+
username: (_b = this.api.auth.user) == null ? void 0 : _b.login,
|
|
3457
|
+
answer: session.peers[payload.uid].connection.localDescription
|
|
3458
|
+
} } });
|
|
3459
|
+
handleTracks(session, payload.uid);
|
|
3460
|
+
} else if (event[key].answer && event[key].answer.to == session.uid) {
|
|
3461
|
+
(_d = (_c = session.peers[event[key].answer.uid]) == null ? void 0 : _c.connection) == null ? void 0 : _d.setRemoteDescription(new RTCSessionDescription(event[key].answer.answer));
|
|
3462
|
+
handleTracks(session, event[key].answer.uid);
|
|
3463
|
+
}
|
|
3464
|
+
}
|
|
3465
|
+
}, () => {
|
|
3466
|
+
var _a;
|
|
3467
|
+
return this.api.socket.send({ [`webrtc/${id}`]: { connected: { uid: session.uid, username: (_a = this.api.auth.user) == null ? void 0 : _a.login } } });
|
|
3468
|
+
});
|
|
3469
|
+
session.disconnect = () => {
|
|
3470
|
+
var _a;
|
|
3471
|
+
session.open = false;
|
|
3472
|
+
session.peers = {};
|
|
3473
|
+
this.api.socket.send({ [`webrtc/${id}`]: { disconnected: { uid: session.uid, username: (_a = this.api.auth.user) == null ? void 0 : _a.login } } });
|
|
3474
|
+
unsubscribe();
|
|
3475
|
+
};
|
|
3476
|
+
return session;
|
|
3477
|
+
}
|
|
3478
|
+
}
|
|
3479
|
+
const _Api = class _Api {
|
|
3480
|
+
/**
|
|
3481
|
+
* Connect to Datalynk & send requests
|
|
3482
|
+
*
|
|
3483
|
+
* @example
|
|
3484
|
+
* ```ts
|
|
3485
|
+
* const api = new Api('https://spoke.auxiliumgroup.com');
|
|
3486
|
+
* ```
|
|
3487
|
+
*
|
|
3488
|
+
* @param {string} origin API URL
|
|
3489
|
+
* @param {ApiOptions} options
|
|
3490
|
+
*/
|
|
3491
|
+
constructor(origin, options = {}) {
|
|
3492
|
+
/** Current requests bundle */
|
|
3493
|
+
__publicField(this, "bundle", []);
|
|
3494
|
+
/** Bundle lifecycle tracking */
|
|
3495
|
+
__publicField(this, "bundleOngoing", false);
|
|
3496
|
+
/** LocalStorage key for persisting logins */
|
|
3497
|
+
__publicField(this, "localStorageKey", "datalynk-token");
|
|
3498
|
+
/** Pending requests cache */
|
|
3499
|
+
__publicField(this, "pending", {});
|
|
3500
|
+
/** Helpers */
|
|
3501
|
+
/** Authentication */
|
|
3502
|
+
__publicField(this, "auth");
|
|
3503
|
+
/** File */
|
|
3504
|
+
__publicField(this, "files");
|
|
3505
|
+
/** PDF */
|
|
3506
|
+
__publicField(this, "pdf");
|
|
3507
|
+
/** PWA setup & prompt */
|
|
3508
|
+
__publicField(this, "pwa");
|
|
3509
|
+
/** Socket */
|
|
3510
|
+
__publicField(this, "socket");
|
|
3511
|
+
/** Superuser */
|
|
3512
|
+
__publicField(this, "superuser");
|
|
3513
|
+
/** WebRTC */
|
|
3514
|
+
__publicField(this, "webrtc");
|
|
3515
|
+
/** Offline database */
|
|
3516
|
+
__publicField(this, "database");
|
|
3517
|
+
/** Options */
|
|
3518
|
+
__publicField(this, "options");
|
|
3519
|
+
/** Created slices */
|
|
3520
|
+
__publicField(this, "sliceCache", /* @__PURE__ */ new Map());
|
|
3521
|
+
/** API URL */
|
|
3522
|
+
__publicField(this, "url");
|
|
3523
|
+
/** Client library version */
|
|
3524
|
+
__publicField(this, "version", version);
|
|
3525
|
+
/** API Session token */
|
|
3526
|
+
__publicField(this, "token$", new BehaviorSubject(void 0));
|
|
3527
|
+
var _a, _b;
|
|
3528
|
+
this.origin = origin;
|
|
3529
|
+
this.url = `${new URL(origin).origin}/api/`;
|
|
3530
|
+
this.options = {
|
|
3531
|
+
manifest: {},
|
|
3532
|
+
name: typeof document != "undefined" ? document.title : "Datalynk",
|
|
3533
|
+
offline: [],
|
|
3534
|
+
origin: typeof location !== "undefined" ? location.host : "Unknown",
|
|
3535
|
+
saveSession: true,
|
|
3536
|
+
serviceWorker: "/service.worker.mjs",
|
|
3537
|
+
...options,
|
|
3538
|
+
webrtc: {
|
|
3539
|
+
url: "scarborough.auxilium.world:3478",
|
|
3540
|
+
username: "auxilium-webrtc",
|
|
3541
|
+
password: "UU3qkD95Tg54eF",
|
|
3542
|
+
...options.webrtc || {}
|
|
3543
|
+
}
|
|
3544
|
+
};
|
|
3545
|
+
if (this.options.saveSession) {
|
|
3546
|
+
if (localStorage == void 0) return;
|
|
3547
|
+
this.token = localStorage.getItem(this.localStorageKey) || null;
|
|
3548
|
+
this.token$.pipe(distinctUntilChanged()).subscribe((token) => {
|
|
3549
|
+
if (token) localStorage.setItem(this.localStorageKey, token);
|
|
3550
|
+
else localStorage.removeItem(this.localStorageKey);
|
|
3551
|
+
});
|
|
3552
|
+
}
|
|
3553
|
+
this.socket = new Socket(this, { url: options.socket });
|
|
3554
|
+
this.auth = new Auth(this);
|
|
3555
|
+
this.files = new Files(this);
|
|
3556
|
+
this.pdf = new Pdf(this);
|
|
3557
|
+
this.pwa = new PWA(this);
|
|
3558
|
+
this.superuser = new Superuser(this);
|
|
3559
|
+
this.webrtc = new WebRtc(this);
|
|
3560
|
+
if ((_a = this.options.offline) == null ? void 0 : _a.length) {
|
|
3561
|
+
this.pwa.setup();
|
|
3562
|
+
if (typeof indexedDB == "undefined") throw new Error("Cannot enable offline support, indexedDB is not available in this environment");
|
|
3563
|
+
this.database = new Database("datalynk", this.options.offline);
|
|
3564
|
+
(_b = this.options.offline) == null ? void 0 : _b.forEach((id) => this.slice(id));
|
|
3565
|
+
if (this.options.serviceWorker && typeof navigator["serviceWorker"] != "undefined") {
|
|
3566
|
+
navigator.serviceWorker.getRegistration(this.options.serviceWorker).then((reg) => reg ?? navigator.serviceWorker.register(this.options.serviceWorker, { scope: "/", type: "module" }));
|
|
3567
|
+
}
|
|
3568
|
+
}
|
|
3569
|
+
}
|
|
3570
|
+
/** Get session info from JWT payload */
|
|
3571
|
+
get jwtPayload() {
|
|
3572
|
+
if (!this.token) return null;
|
|
3573
|
+
return decodeJwt(this.token);
|
|
3574
|
+
}
|
|
3575
|
+
/** Is token expired */
|
|
3576
|
+
get expired() {
|
|
3577
|
+
var _a;
|
|
3578
|
+
return (((_a = this.jwtPayload) == null ? void 0 : _a.exp) ?? Infinity) * 1e3 <= Date.now();
|
|
3579
|
+
}
|
|
3580
|
+
/** Logged in spoke */
|
|
3581
|
+
get spoke() {
|
|
3582
|
+
var _a;
|
|
3583
|
+
return (_a = this.jwtPayload) == null ? void 0 : _a.realm;
|
|
3584
|
+
}
|
|
3585
|
+
get token() {
|
|
3586
|
+
return this.token$.getValue();
|
|
3587
|
+
}
|
|
3588
|
+
set token(token) {
|
|
3589
|
+
this.token$.next(token);
|
|
3590
|
+
}
|
|
3591
|
+
_request(req, options = {}) {
|
|
3592
|
+
const token = options.token || this.token;
|
|
3593
|
+
return fetch(this.url, {
|
|
3594
|
+
method: "POST",
|
|
3595
|
+
headers: clean({
|
|
3596
|
+
Authorization: token ? `Bearer ${token}` : void 0,
|
|
3597
|
+
"Content-Type": "application/json",
|
|
3598
|
+
"X-Date-Return-Format": this.options.legacyDates ? void 0 : "ISO8601"
|
|
3599
|
+
}),
|
|
3600
|
+
body: JSON.stringify(_Api.translateTokens(req))
|
|
3601
|
+
}).then(async (resp) => {
|
|
3602
|
+
let data = JSONAttemptParse(await resp.text());
|
|
3603
|
+
if (!resp.ok || (data == null ? void 0 : data.error)) throw Object.assign(errorFromCode(resp.status, data.error), data);
|
|
3604
|
+
if (!options.raw) data = _Api.translateTokens(data);
|
|
3605
|
+
return data;
|
|
3606
|
+
});
|
|
3607
|
+
}
|
|
3608
|
+
/**
|
|
3609
|
+
* Get list of slices
|
|
3610
|
+
* @return {Promise<number[]>}
|
|
3611
|
+
*/
|
|
3612
|
+
getSlices() {
|
|
3613
|
+
return this.request({ "$/tools/action_chain": [
|
|
3614
|
+
{ "!/env/me": {} },
|
|
3615
|
+
{ "!/slice/permissionsLite": {} },
|
|
3616
|
+
{ "!/tools/column": { "col": "id", "rows": { "$_": "1:rows" } } }
|
|
3617
|
+
] });
|
|
3618
|
+
}
|
|
3619
|
+
/**
|
|
3620
|
+
* Parses API request/response object for special Datalynk tokens & converts them to native JS objects
|
|
3621
|
+
*
|
|
3622
|
+
* @param obj An API request or response
|
|
3623
|
+
* @return {Object} Api request or response with translated tokens
|
|
3624
|
+
* @private
|
|
3625
|
+
*/
|
|
3626
|
+
static translateTokens(obj) {
|
|
3627
|
+
let dot = (obj2, param) => param.split(".").reduce((acc, index) => acc[index], obj2);
|
|
3628
|
+
let queue = Object.keys(obj);
|
|
3629
|
+
queue.forEach((key) => {
|
|
3630
|
+
let val = dot(obj, key);
|
|
3631
|
+
if (val !== null && typeof val == "object") {
|
|
3632
|
+
Object.keys(val).forEach((index) => {
|
|
3633
|
+
if (index in Serializer.deserialize) {
|
|
3634
|
+
val = Serializer.deserialize[index](val[index]);
|
|
3635
|
+
} else if (index in Serializer.serialize) {
|
|
3636
|
+
val = Serializer.serialize[index](val[index]);
|
|
3637
|
+
} else if (val[index] == "Yes") {
|
|
3638
|
+
val[index] = true;
|
|
3639
|
+
} else if (val[index] == "No") {
|
|
3640
|
+
val[index] = false;
|
|
3641
|
+
} else {
|
|
3642
|
+
queue.push(`${key}.${index}`);
|
|
3643
|
+
}
|
|
3644
|
+
});
|
|
3645
|
+
}
|
|
3646
|
+
});
|
|
3647
|
+
return obj;
|
|
3648
|
+
}
|
|
3649
|
+
/**
|
|
3650
|
+
* Chain multiple requests to execute together
|
|
3651
|
+
* @param {Slice<any>} requests List of requests to chain
|
|
3652
|
+
* @return {Promise<any>} API Response
|
|
3653
|
+
*/
|
|
3654
|
+
chain(...requests) {
|
|
3655
|
+
const arr = requests.length == 1 && Array.isArray(requests[0]) ? requests[0] : requests;
|
|
3656
|
+
return this.request({ "$/tools/action_chain": arr.map((r) => {
|
|
3657
|
+
if (!(r instanceof ApiCall)) return r;
|
|
3658
|
+
const req = r.raw;
|
|
3659
|
+
Object.keys(req).forEach((key) => {
|
|
3660
|
+
if (key.startsWith("$/")) {
|
|
3661
|
+
req[key.replace("$", "!")] = req[key];
|
|
3662
|
+
delete req[key];
|
|
3663
|
+
}
|
|
3664
|
+
});
|
|
3665
|
+
return req;
|
|
3666
|
+
}) });
|
|
3667
|
+
}
|
|
3668
|
+
/**
|
|
3669
|
+
* Organize multiple requests into a single mapped request
|
|
3670
|
+
* @param {{[p: string]: any}} request Map of requests
|
|
3671
|
+
* @return {Promise<any>} Map of API Responses
|
|
3672
|
+
*/
|
|
3673
|
+
chainMap(request) {
|
|
3674
|
+
return this.request({ "$/tools/do": [
|
|
3675
|
+
...Object.entries(request).flatMap(([key, r]) => {
|
|
3676
|
+
if (!(r instanceof ApiCall)) return [key, r];
|
|
3677
|
+
const req = r.raw;
|
|
3678
|
+
Object.keys(req).forEach((key2) => {
|
|
3679
|
+
if (key2.startsWith("$/")) {
|
|
3680
|
+
req[key2.replace("$", "!")] = req[key2];
|
|
3681
|
+
delete req[key2];
|
|
3682
|
+
}
|
|
3683
|
+
});
|
|
3684
|
+
return [key, req];
|
|
3685
|
+
}),
|
|
3686
|
+
"returnAllBoilerplate",
|
|
3687
|
+
{ "$_": "*" }
|
|
3688
|
+
] }, {});
|
|
3689
|
+
}
|
|
3690
|
+
/**
|
|
3691
|
+
* Exact same as `request` method, but logs the response in the console automatically
|
|
3692
|
+
*
|
|
3693
|
+
* @param {object | string} data Datalynk request as object or string
|
|
3694
|
+
* @param {ApiRequestOptions} options
|
|
3695
|
+
* @returns {Promise<any>} Datalynk response
|
|
3696
|
+
*/
|
|
3697
|
+
debug(data, options = {}) {
|
|
3698
|
+
return this.request(data, options).then((data2) => {
|
|
3699
|
+
console.log(data2);
|
|
3700
|
+
return data2;
|
|
3701
|
+
}).catch((err) => {
|
|
3702
|
+
console.error(err);
|
|
3703
|
+
return err;
|
|
3704
|
+
});
|
|
3705
|
+
}
|
|
3706
|
+
/**
|
|
3707
|
+
* Send a request to Datalynk
|
|
3708
|
+
*
|
|
3709
|
+
* @example
|
|
3710
|
+
* ```ts
|
|
3711
|
+
* const response = await api.request('$/auth/current');
|
|
3712
|
+
* ```
|
|
3713
|
+
*
|
|
3714
|
+
* @param {object} data Request using Datalynk API syntax. Strings will be converted: '$/auth/current' -> {'$/auth/current': {}}
|
|
3715
|
+
* @param {ApiRequestOptions} options
|
|
3716
|
+
* @returns {Promise<any>} Datalynk response or error
|
|
3717
|
+
*/
|
|
3718
|
+
request(data, options = {}) {
|
|
3719
|
+
data = typeof data == "string" ? { [data]: {} } : data;
|
|
3720
|
+
if (options.noOptimize) {
|
|
3721
|
+
return new Promise((res, rej) => {
|
|
3722
|
+
this._request(data, options).then((resp) => {
|
|
3723
|
+
(resp == null ? void 0 : resp.error) ? rej(resp) : res(resp);
|
|
3724
|
+
}).catch((err) => rej(err));
|
|
3725
|
+
});
|
|
3726
|
+
}
|
|
3727
|
+
let key = JSON.stringify(data);
|
|
3728
|
+
if (!this.pending[key]) {
|
|
3729
|
+
this.pending[key] = new Promise((res, rej) => this.bundle.push({ data, res, rej }));
|
|
3730
|
+
this.pending[key].catch().then(() => delete this.pending[key]);
|
|
3731
|
+
if (!this.bundleOngoing) {
|
|
3732
|
+
this.bundleOngoing = true;
|
|
3733
|
+
setTimeout(() => {
|
|
3734
|
+
let originalBundle = this.bundle;
|
|
3735
|
+
this.bundle = [];
|
|
3736
|
+
this.bundleOngoing = false;
|
|
3737
|
+
data = originalBundle.map((row) => row.data);
|
|
3738
|
+
this._request(data, options).then((resp) => {
|
|
3739
|
+
if (!(resp instanceof Array)) resp = [resp];
|
|
3740
|
+
resp.forEach((row, i) => (row == null ? void 0 : row.error) ? originalBundle[i].rej(row.error) : originalBundle[i].res(row));
|
|
3741
|
+
}).catch((err) => originalBundle.forEach((req) => req.rej(err)));
|
|
3742
|
+
}, this.options.bundleTime);
|
|
3743
|
+
}
|
|
3744
|
+
}
|
|
3745
|
+
return this.pending[key];
|
|
3746
|
+
}
|
|
3747
|
+
/**
|
|
3748
|
+
* Create a slice object using the API
|
|
3749
|
+
*
|
|
3750
|
+
* @example
|
|
3751
|
+
* ```ts
|
|
3752
|
+
* const contactsSlice = api.slice<Contacts>(12345);
|
|
3753
|
+
* const allContacts = await contactsSlice.select().exec().rows();
|
|
3754
|
+
* const unsubscribe = contactsSlice.sync().subscribe(rows => console.log(rows));
|
|
3755
|
+
* ```
|
|
3756
|
+
*
|
|
3757
|
+
* @param {number} id Slice ID the object will target
|
|
3758
|
+
* @returns {Slice<T = any>} Object for making requests & caching rows
|
|
3759
|
+
*/
|
|
3760
|
+
slice(id) {
|
|
3761
|
+
if (!this.sliceCache.has(+id)) this.sliceCache.set(+id, new Slice(id, this));
|
|
3762
|
+
return this.sliceCache.get(+id);
|
|
3763
|
+
}
|
|
3764
|
+
};
|
|
3765
|
+
/** Client library version */
|
|
3766
|
+
__publicField(_Api, "version", version);
|
|
3767
|
+
let Api = _Api;
|
|
3768
|
+
exports.Api = Api;
|
|
3769
|
+
exports.ApiCall = ApiCall;
|
|
3770
|
+
exports.Auth = Auth;
|
|
3771
|
+
exports.Files = Files;
|
|
3772
|
+
exports.LoginPrompt = LoginPrompt;
|
|
3773
|
+
exports.PWA = PWA;
|
|
3774
|
+
exports.Pdf = Pdf;
|
|
3775
|
+
exports.Serializer = Serializer;
|
|
3776
|
+
exports.Slice = Slice;
|
|
3777
|
+
exports.Socket = Socket;
|
|
3778
|
+
exports.Superuser = Superuser;
|
|
3779
|
+
exports.getTheme = getTheme;
|