@ztimson/momentum 0.53.1 → 0.58.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +200 -148
- package/bin/build-models.mjs +28 -37
- package/dist/actions.d.ts +32 -43
- package/dist/actions.d.ts.map +1 -1
- package/dist/ai.d.ts +38 -17
- package/dist/ai.d.ts.map +1 -1
- package/dist/analytics.d.ts +169 -36
- package/dist/analytics.d.ts.map +1 -1
- package/dist/api.d.ts +22 -22
- package/dist/api.d.ts.map +1 -1
- package/dist/asset-controller.d.ts +92 -0
- package/dist/asset-controller.d.ts.map +1 -0
- package/dist/audit.d.ts +22 -0
- package/dist/audit.d.ts.map +1 -0
- package/dist/auth.d.ts +39 -92
- package/dist/auth.d.ts.map +1 -1
- package/dist/call.d.ts +39 -0
- package/dist/call.d.ts.map +1 -0
- package/dist/captcha.d.ts +14 -0
- package/dist/captcha.d.ts.map +1 -0
- package/dist/client.d.ts +44 -33
- package/dist/client.d.ts.map +1 -1
- package/dist/core.d.ts +50 -21
- package/dist/core.d.ts.map +1 -1
- package/dist/data.d.ts +59 -77
- package/dist/data.d.ts.map +1 -1
- package/dist/dialog.d.ts +11 -0
- package/dist/dialog.d.ts.map +1 -0
- package/dist/discounts.d.ts +8 -12
- package/dist/discounts.d.ts.map +1 -1
- package/dist/email.d.ts +19 -19
- package/dist/email.d.ts.map +1 -1
- package/dist/forms.d.ts +6 -13
- package/dist/forms.d.ts.map +1 -1
- package/dist/groups.d.ts +22 -16
- package/dist/groups.d.ts.map +1 -1
- package/dist/index.d.ts +13 -3
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +4446 -0
- package/dist/index.mjs +3422 -1731
- package/dist/logger.d.ts +78 -48
- package/dist/logger.d.ts.map +1 -1
- package/dist/momentum.d.ts +69 -15
- package/dist/momentum.d.ts.map +1 -1
- package/dist/momentum.worker.d.mts +2 -0
- package/dist/momentum.worker.d.mts.map +1 -0
- package/dist/momentum.worker.mjs +103 -0
- package/dist/notifications.d.ts +39 -0
- package/dist/notifications.d.ts.map +1 -0
- package/dist/pdf.d.ts +31 -14
- package/dist/pdf.d.ts.map +1 -1
- package/dist/products.d.ts +47 -0
- package/dist/products.d.ts.map +1 -0
- package/dist/routes.d.ts +40 -0
- package/dist/routes.d.ts.map +1 -0
- package/dist/schemas.d.ts +79 -0
- package/dist/schemas.d.ts.map +1 -0
- package/dist/settings.d.ts +30 -14
- package/dist/settings.d.ts.map +1 -1
- package/dist/sms.d.ts +14 -0
- package/dist/sms.d.ts.map +1 -0
- package/dist/sockets.d.ts +21 -10
- package/dist/sockets.d.ts.map +1 -1
- package/dist/static.d.ts +4 -2
- package/dist/static.d.ts.map +1 -1
- package/dist/storage.d.ts +103 -24
- package/dist/storage.d.ts.map +1 -1
- package/dist/templates.d.ts +23 -0
- package/dist/templates.d.ts.map +1 -0
- package/dist/tokens.d.ts +50 -0
- package/dist/tokens.d.ts.map +1 -0
- package/dist/totp.d.ts +45 -0
- package/dist/totp.d.ts.map +1 -0
- package/dist/transactions.d.ts +153 -0
- package/dist/transactions.d.ts.map +1 -0
- package/dist/users.d.ts +63 -25
- package/dist/users.d.ts.map +1 -1
- package/dist/webRtc.d.ts +39 -0
- package/dist/webRtc.d.ts.map +1 -0
- package/package.json +53 -43
- package/dist/index.cjs +0 -2755
- package/dist/momentum.worker.js +0 -16
- package/dist/payments.d.ts +0 -184
- package/dist/payments.d.ts.map +0 -1
- package/dist/phone.d.ts +0 -19
- package/dist/phone.d.ts.map +0 -1
package/dist/index.cjs
DELETED
|
@@ -1,2755 +0,0 @@
|
|
|
1
|
-
(function(global, factory) {
|
|
2
|
-
typeof exports === "object" && typeof module !== "undefined" ? factory(exports) : typeof define === "function" && define.amd ? define(["exports"], factory) : (global = typeof globalThis !== "undefined" ? globalThis : global || self, factory(global.utils = {}));
|
|
3
|
-
})(this, function(exports2) {
|
|
4
|
-
"use strict";var __defProp = Object.defineProperty;
|
|
5
|
-
var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
|
|
6
|
-
var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
|
|
7
|
-
|
|
8
|
-
var __defProp2 = Object.defineProperty;
|
|
9
|
-
var __defNormalProp2 = (obj, key, value2) => key in obj ? __defProp2(obj, key, { enumerable: true, configurable: true, writable: true, value: value2 }) : obj[key] = value2;
|
|
10
|
-
var __publicField2 = (obj, key, value2) => __defNormalProp2(obj, typeof key !== "symbol" ? key + "" : key, value2);
|
|
11
|
-
function clean(obj, undefinedOnly = false) {
|
|
12
|
-
if (obj == null) throw new Error("Cannot clean a NULL value");
|
|
13
|
-
if (Array.isArray(obj)) {
|
|
14
|
-
obj = obj.filter((o) => o != null);
|
|
15
|
-
} else {
|
|
16
|
-
Object.entries(obj).forEach(([key, value2]) => {
|
|
17
|
-
if (undefinedOnly && value2 === void 0 || !undefinedOnly && value2 == null) delete obj[key];
|
|
18
|
-
});
|
|
19
|
-
}
|
|
20
|
-
return obj;
|
|
21
|
-
}
|
|
22
|
-
function deepCopy(value2) {
|
|
23
|
-
try {
|
|
24
|
-
return structuredClone(value2);
|
|
25
|
-
} catch {
|
|
26
|
-
return JSON.parse(JSONSanitize(value2));
|
|
27
|
-
}
|
|
28
|
-
}
|
|
29
|
-
function isEqual(a2, b2) {
|
|
30
|
-
const ta = typeof a2, tb = typeof b2;
|
|
31
|
-
if (ta != "object" || a2 == null || (tb != "object" || b2 == null))
|
|
32
|
-
return ta == "function" && tb == "function" ? a2.toString() == b2.toString() : a2 === b2;
|
|
33
|
-
const keys = Object.keys(a2);
|
|
34
|
-
if (keys.length != Object.keys(b2).length) return false;
|
|
35
|
-
return Object.keys(a2).every((key) => isEqual(a2[key], b2[key]));
|
|
36
|
-
}
|
|
37
|
-
function JSONAttemptParse(json) {
|
|
38
|
-
try {
|
|
39
|
-
return JSON.parse(json);
|
|
40
|
-
} catch {
|
|
41
|
-
return json;
|
|
42
|
-
}
|
|
43
|
-
}
|
|
44
|
-
function JSONSanitize(obj, space) {
|
|
45
|
-
return JSON.stringify(obj, (key, value2) => {
|
|
46
|
-
return value2;
|
|
47
|
-
}, space);
|
|
48
|
-
}
|
|
49
|
-
function makeArray(value2) {
|
|
50
|
-
return Array.isArray(value2) ? value2 : [value2];
|
|
51
|
-
}
|
|
52
|
-
class ASet extends Array {
|
|
53
|
-
/** Number of elements in set */
|
|
54
|
-
get size() {
|
|
55
|
-
return this.length;
|
|
56
|
-
}
|
|
57
|
-
/**
|
|
58
|
-
* Array to create set from, duplicate values will be removed
|
|
59
|
-
* @param {T[]} elements Elements which will be added to set
|
|
60
|
-
*/
|
|
61
|
-
constructor(elements = []) {
|
|
62
|
-
super();
|
|
63
|
-
if (!!(elements == null ? void 0 : elements["forEach"]))
|
|
64
|
-
elements.forEach((el) => this.add(el));
|
|
65
|
-
}
|
|
66
|
-
/**
|
|
67
|
-
* Add elements to set if unique
|
|
68
|
-
* @param items
|
|
69
|
-
*/
|
|
70
|
-
add(...items) {
|
|
71
|
-
items.filter((el) => !this.has(el)).forEach((el) => this.push(el));
|
|
72
|
-
return this;
|
|
73
|
-
}
|
|
74
|
-
/**
|
|
75
|
-
* Delete elements from set
|
|
76
|
-
* @param items Elements that will be deleted
|
|
77
|
-
*/
|
|
78
|
-
delete(...items) {
|
|
79
|
-
items.forEach((el) => {
|
|
80
|
-
const index = this.indexOf(el);
|
|
81
|
-
if (index != -1) this.splice(index, 1);
|
|
82
|
-
});
|
|
83
|
-
return this;
|
|
84
|
-
}
|
|
85
|
-
/**
|
|
86
|
-
* Create list of elements this set has which the comparison set does not
|
|
87
|
-
* @param {ASet<T>} set Set to compare against
|
|
88
|
-
* @return {ASet<T>} Different elements
|
|
89
|
-
*/
|
|
90
|
-
difference(set) {
|
|
91
|
-
return new ASet(this.filter((el) => !set.has(el)));
|
|
92
|
-
}
|
|
93
|
-
/**
|
|
94
|
-
* Check if set includes element
|
|
95
|
-
* @param {T} el Element to look for
|
|
96
|
-
* @return {boolean} True if element was found, false otherwise
|
|
97
|
-
*/
|
|
98
|
-
has(el) {
|
|
99
|
-
return this.indexOf(el) != -1;
|
|
100
|
-
}
|
|
101
|
-
/**
|
|
102
|
-
* Find index number of element, or -1 if it doesn't exist. Matches by equality not reference
|
|
103
|
-
*
|
|
104
|
-
* @param {T} search Element to find
|
|
105
|
-
* @param {number} fromIndex Starting index position
|
|
106
|
-
* @return {number} Element index number or -1 if missing
|
|
107
|
-
*/
|
|
108
|
-
indexOf(search2, fromIndex) {
|
|
109
|
-
return super.findIndex((el) => isEqual(el, search2), fromIndex);
|
|
110
|
-
}
|
|
111
|
-
/**
|
|
112
|
-
* Create list of elements this set has in common with the comparison set
|
|
113
|
-
* @param {ASet<T>} set Set to compare against
|
|
114
|
-
* @return {boolean} Set of common elements
|
|
115
|
-
*/
|
|
116
|
-
intersection(set) {
|
|
117
|
-
return new ASet(this.filter((el) => set.has(el)));
|
|
118
|
-
}
|
|
119
|
-
/**
|
|
120
|
-
* Check if this set has no elements in common with the comparison set
|
|
121
|
-
* @param {ASet<T>} set Set to compare against
|
|
122
|
-
* @return {boolean} True if nothing in common, false otherwise
|
|
123
|
-
*/
|
|
124
|
-
isDisjointFrom(set) {
|
|
125
|
-
return this.intersection(set).size == 0;
|
|
126
|
-
}
|
|
127
|
-
/**
|
|
128
|
-
* Check if all elements in this set are included in the comparison set
|
|
129
|
-
* @param {ASet<T>} set Set to compare against
|
|
130
|
-
* @return {boolean} True if all elements are included, false otherwise
|
|
131
|
-
*/
|
|
132
|
-
isSubsetOf(set) {
|
|
133
|
-
return this.findIndex((el) => !set.has(el)) == -1;
|
|
134
|
-
}
|
|
135
|
-
/**
|
|
136
|
-
* Check if all elements from comparison set are included in this set
|
|
137
|
-
* @param {ASet<T>} set Set to compare against
|
|
138
|
-
* @return {boolean} True if all elements are included, false otherwise
|
|
139
|
-
*/
|
|
140
|
-
isSuperset(set) {
|
|
141
|
-
return set.findIndex((el) => !this.has(el)) == -1;
|
|
142
|
-
}
|
|
143
|
-
/**
|
|
144
|
-
* Create list of elements that are only in one set but not both (XOR)
|
|
145
|
-
* @param {ASet<T>} set Set to compare against
|
|
146
|
-
* @return {ASet<T>} New set of unique elements
|
|
147
|
-
*/
|
|
148
|
-
symmetricDifference(set) {
|
|
149
|
-
return new ASet([...this.difference(set), ...set.difference(this)]);
|
|
150
|
-
}
|
|
151
|
-
/**
|
|
152
|
-
* Create joined list of elements included in this & the comparison set
|
|
153
|
-
* @param {ASet<T>} set Set join
|
|
154
|
-
* @return {ASet<T>} New set of both previous sets combined
|
|
155
|
-
*/
|
|
156
|
-
union(set) {
|
|
157
|
-
return new ASet([...this, ...set]);
|
|
158
|
-
}
|
|
159
|
-
}
|
|
160
|
-
class Cache {
|
|
161
|
-
/**
|
|
162
|
-
* Create new cache
|
|
163
|
-
*
|
|
164
|
-
* @param {keyof T} key Default property to use as primary key
|
|
165
|
-
* @param options
|
|
166
|
-
*/
|
|
167
|
-
constructor(key, options = {}) {
|
|
168
|
-
__publicField2(this, "store", {});
|
|
169
|
-
__publicField2(this, "complete", false);
|
|
170
|
-
__publicField2(this, "values", this.all());
|
|
171
|
-
this.key = key;
|
|
172
|
-
this.options = options;
|
|
173
|
-
if (options.storageKey && !options.storage && typeof Storage !== "undefined")
|
|
174
|
-
options.storage = localStorage;
|
|
175
|
-
if (options.storageKey && options.storage) {
|
|
176
|
-
const stored = options.storage.getItem(options.storageKey);
|
|
177
|
-
if (stored) {
|
|
178
|
-
try {
|
|
179
|
-
Object.assign(this.store, JSON.parse(stored));
|
|
180
|
-
} catch {
|
|
181
|
-
}
|
|
182
|
-
}
|
|
183
|
-
}
|
|
184
|
-
return new Proxy(this, {
|
|
185
|
-
get: (target, prop2) => {
|
|
186
|
-
if (prop2 in target) return target[prop2];
|
|
187
|
-
return deepCopy(target.store[prop2]);
|
|
188
|
-
},
|
|
189
|
-
set: (target, prop2, value2) => {
|
|
190
|
-
if (prop2 in target) target[prop2] = value2;
|
|
191
|
-
else this.set(prop2, value2);
|
|
192
|
-
return true;
|
|
193
|
-
}
|
|
194
|
-
});
|
|
195
|
-
}
|
|
196
|
-
getKey(value2) {
|
|
197
|
-
if (!this.key) throw new Error("No key defined");
|
|
198
|
-
return value2[this.key];
|
|
199
|
-
}
|
|
200
|
-
/**
|
|
201
|
-
* Get all cached items
|
|
202
|
-
*
|
|
203
|
-
* @return {T[]} Array of items
|
|
204
|
-
*/
|
|
205
|
-
all() {
|
|
206
|
-
return deepCopy(Object.values(this.store));
|
|
207
|
-
}
|
|
208
|
-
/**
|
|
209
|
-
* Add a new item to the cache. Like set, but finds key automatically
|
|
210
|
-
*
|
|
211
|
-
* @param {T} value Item to add to cache
|
|
212
|
-
* @param {number | undefined} ttl Override default expiry
|
|
213
|
-
* @return {this}
|
|
214
|
-
*/
|
|
215
|
-
add(value2, ttl = this.ttl) {
|
|
216
|
-
const key = this.getKey(value2);
|
|
217
|
-
this.set(key, value2, ttl);
|
|
218
|
-
return this;
|
|
219
|
-
}
|
|
220
|
-
/**
|
|
221
|
-
* Add several rows to the cache
|
|
222
|
-
*
|
|
223
|
-
* @param {T[]} rows Several items that will be cached using the default key
|
|
224
|
-
* @param complete Mark cache as complete & reliable, defaults to true
|
|
225
|
-
* @return {this}
|
|
226
|
-
*/
|
|
227
|
-
addAll(rows2, complete = true) {
|
|
228
|
-
rows2.forEach((r2) => this.add(r2));
|
|
229
|
-
this.complete = complete;
|
|
230
|
-
return this;
|
|
231
|
-
}
|
|
232
|
-
/**
|
|
233
|
-
* Remove all keys from cache
|
|
234
|
-
*/
|
|
235
|
-
clear() {
|
|
236
|
-
this.store = {};
|
|
237
|
-
}
|
|
238
|
-
/**
|
|
239
|
-
* Delete an item from the cache
|
|
240
|
-
*
|
|
241
|
-
* @param {K} key Item's primary key
|
|
242
|
-
*/
|
|
243
|
-
delete(key) {
|
|
244
|
-
delete this.store[key];
|
|
245
|
-
if (this.options.storageKey && this.options.storage)
|
|
246
|
-
this.options.storage.setItem(this.options.storageKey, JSON.stringify(this.store));
|
|
247
|
-
}
|
|
248
|
-
/**
|
|
249
|
-
* Return cache as an array of key-value pairs
|
|
250
|
-
* @return {[K, T][]} Key-value pairs array
|
|
251
|
-
*/
|
|
252
|
-
entries() {
|
|
253
|
-
return Object.entries(this.store);
|
|
254
|
-
}
|
|
255
|
-
/**
|
|
256
|
-
* Get item from the cache
|
|
257
|
-
* @param {K} key Key to lookup
|
|
258
|
-
* @return {T} Cached item
|
|
259
|
-
*/
|
|
260
|
-
get(key) {
|
|
261
|
-
return deepCopy(this.store[key]);
|
|
262
|
-
}
|
|
263
|
-
/**
|
|
264
|
-
* Get a list of cached keys
|
|
265
|
-
*
|
|
266
|
-
* @return {K[]} Array of keys
|
|
267
|
-
*/
|
|
268
|
-
keys() {
|
|
269
|
-
return Object.keys(this.store);
|
|
270
|
-
}
|
|
271
|
-
/**
|
|
272
|
-
* Get map of cached items
|
|
273
|
-
*
|
|
274
|
-
* @return {Record<K, T>}
|
|
275
|
-
*/
|
|
276
|
-
map() {
|
|
277
|
-
return deepCopy(this.store);
|
|
278
|
-
}
|
|
279
|
-
/**
|
|
280
|
-
* Add an item to the cache manually specifying the key
|
|
281
|
-
*
|
|
282
|
-
* @param {K} key Key item will be cached under
|
|
283
|
-
* @param {T} value Item to cache
|
|
284
|
-
* @param {number | undefined} ttl Override default expiry in seconds
|
|
285
|
-
* @return {this}
|
|
286
|
-
*/
|
|
287
|
-
set(key, value2, ttl = this.options.ttl) {
|
|
288
|
-
this.store[key] = value2;
|
|
289
|
-
if (this.options.storageKey && this.options.storage)
|
|
290
|
-
this.options.storage.setItem(this.options.storageKey, JSON.stringify(this.store));
|
|
291
|
-
if (ttl) setTimeout(() => {
|
|
292
|
-
this.complete = false;
|
|
293
|
-
this.delete(key);
|
|
294
|
-
}, ttl * 1e3);
|
|
295
|
-
return this;
|
|
296
|
-
}
|
|
297
|
-
}
|
|
298
|
-
function blackOrWhite(background) {
|
|
299
|
-
const exploded = background == null ? void 0 : background.match(background.length >= 6 ? /\w\w/g : /\w/g);
|
|
300
|
-
if (!exploded) return "black";
|
|
301
|
-
const [r2, g, b2] = exploded.map((hex) => parseInt(hex, 16));
|
|
302
|
-
const luminance = (0.299 * r2 + 0.587 * g + 0.114 * b2) / 255;
|
|
303
|
-
return luminance > 0.5 ? "black" : "white";
|
|
304
|
-
}
|
|
305
|
-
class PromiseProgress extends Promise {
|
|
306
|
-
constructor(executor) {
|
|
307
|
-
super((resolve, reject) => executor(
|
|
308
|
-
(value2) => resolve(value2),
|
|
309
|
-
(reason) => reject(reason),
|
|
310
|
-
(progress) => this.progress = progress
|
|
311
|
-
));
|
|
312
|
-
__publicField2(this, "listeners", []);
|
|
313
|
-
__publicField2(this, "_progress", 0);
|
|
314
|
-
}
|
|
315
|
-
get progress() {
|
|
316
|
-
return this._progress;
|
|
317
|
-
}
|
|
318
|
-
set progress(p2) {
|
|
319
|
-
if (p2 == this._progress) return;
|
|
320
|
-
this._progress = p2;
|
|
321
|
-
this.listeners.forEach((l) => l(p2));
|
|
322
|
-
}
|
|
323
|
-
static from(promise) {
|
|
324
|
-
if (promise instanceof PromiseProgress) return promise;
|
|
325
|
-
return new PromiseProgress((res, rej) => promise.then((...args) => res(...args)).catch((...args) => rej(...args)));
|
|
326
|
-
}
|
|
327
|
-
from(promise) {
|
|
328
|
-
const newPromise = PromiseProgress.from(promise);
|
|
329
|
-
this.onProgress((p2) => newPromise.progress = p2);
|
|
330
|
-
return newPromise;
|
|
331
|
-
}
|
|
332
|
-
onProgress(callback) {
|
|
333
|
-
this.listeners.push(callback);
|
|
334
|
-
return this;
|
|
335
|
-
}
|
|
336
|
-
then(res, rej) {
|
|
337
|
-
const resp = super.then(res, rej);
|
|
338
|
-
return this.from(resp);
|
|
339
|
-
}
|
|
340
|
-
catch(rej) {
|
|
341
|
-
return this.from(super.catch(rej));
|
|
342
|
-
}
|
|
343
|
-
finally(res) {
|
|
344
|
-
return this.from(super.finally(res));
|
|
345
|
-
}
|
|
346
|
-
}
|
|
347
|
-
function formatDate(format = "YYYY-MM-DD H:mm", date = /* @__PURE__ */ new Date(), tz) {
|
|
348
|
-
const timezones = [
|
|
349
|
-
["IDLW", -12],
|
|
350
|
-
["SST", -11],
|
|
351
|
-
["HST", -10],
|
|
352
|
-
["AKST", -9],
|
|
353
|
-
["PST", -8],
|
|
354
|
-
["MST", -7],
|
|
355
|
-
["CST", -6],
|
|
356
|
-
["EST", -5],
|
|
357
|
-
["AST", -4],
|
|
358
|
-
["BRT", -3],
|
|
359
|
-
["MAT", -2],
|
|
360
|
-
["AZOT", -1],
|
|
361
|
-
["UTC", 0],
|
|
362
|
-
["CET", 1],
|
|
363
|
-
["EET", 2],
|
|
364
|
-
["MSK", 3],
|
|
365
|
-
["AST", 4],
|
|
366
|
-
["PKT", 5],
|
|
367
|
-
["IST", 5.5],
|
|
368
|
-
["BST", 6],
|
|
369
|
-
["ICT", 7],
|
|
370
|
-
["CST", 8],
|
|
371
|
-
["JST", 9],
|
|
372
|
-
["AEST", 10],
|
|
373
|
-
["SBT", 11],
|
|
374
|
-
["FJT", 12],
|
|
375
|
-
["TOT", 13],
|
|
376
|
-
["LINT", 14]
|
|
377
|
-
];
|
|
378
|
-
function adjustTz(date2, gmt) {
|
|
379
|
-
const currentOffset = date2.getTimezoneOffset();
|
|
380
|
-
const adjustedOffset = gmt * 60;
|
|
381
|
-
return new Date(date2.getTime() + (adjustedOffset + currentOffset) * 6e4);
|
|
382
|
-
}
|
|
383
|
-
function day(num) {
|
|
384
|
-
return ["Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"][num] || "Unknown";
|
|
385
|
-
}
|
|
386
|
-
function doy(date2) {
|
|
387
|
-
const start = /* @__PURE__ */ new Date(`${date2.getFullYear()}-01-01 0:00:00`);
|
|
388
|
-
return Math.ceil((date2.getTime() - start.getTime()) / (1e3 * 60 * 60 * 24));
|
|
389
|
-
}
|
|
390
|
-
function month(num) {
|
|
391
|
-
return ["January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"][num] || "Unknown";
|
|
392
|
-
}
|
|
393
|
-
function suffix(num) {
|
|
394
|
-
if (num % 100 >= 11 && num % 100 <= 13) return `${num}th`;
|
|
395
|
-
switch (num % 10) {
|
|
396
|
-
case 1:
|
|
397
|
-
return `${num}st`;
|
|
398
|
-
case 2:
|
|
399
|
-
return `${num}nd`;
|
|
400
|
-
case 3:
|
|
401
|
-
return `${num}rd`;
|
|
402
|
-
default:
|
|
403
|
-
return `${num}th`;
|
|
404
|
-
}
|
|
405
|
-
}
|
|
406
|
-
function tzOffset(offset) {
|
|
407
|
-
const hours = ~~(offset / 60);
|
|
408
|
-
const minutes = offset % 60;
|
|
409
|
-
return (offset > 0 ? "-" : "") + `${hours}:${minutes.toString().padStart(2, "0")}`;
|
|
410
|
-
}
|
|
411
|
-
if (typeof date == "number" || typeof date == "string") date = new Date(date);
|
|
412
|
-
let t;
|
|
413
|
-
if (tz == null) tz = -(date.getTimezoneOffset() / 60);
|
|
414
|
-
t = timezones.find((t2) => isNaN(tz) ? t2[0] == tz : t2[1] == tz);
|
|
415
|
-
if (!t) throw new Error(`Unknown timezone: ${tz}`);
|
|
416
|
-
date = adjustTz(date, t[1]);
|
|
417
|
-
const tokens = {
|
|
418
|
-
"YYYY": date.getFullYear().toString(),
|
|
419
|
-
"YY": date.getFullYear().toString().slice(2),
|
|
420
|
-
"MMMM": month(date.getMonth()),
|
|
421
|
-
"MMM": month(date.getMonth()).slice(0, 3),
|
|
422
|
-
"MM": (date.getMonth() + 1).toString().padStart(2, "0"),
|
|
423
|
-
"M": (date.getMonth() + 1).toString(),
|
|
424
|
-
"DDD": doy(date).toString(),
|
|
425
|
-
"DD": date.getDate().toString().padStart(2, "0"),
|
|
426
|
-
"Do": suffix(date.getDate()),
|
|
427
|
-
"D": date.getDate().toString(),
|
|
428
|
-
"dddd": day(date.getDay()),
|
|
429
|
-
"ddd": day(date.getDay()).slice(0, 3),
|
|
430
|
-
"HH": date.getHours().toString().padStart(2, "0"),
|
|
431
|
-
"H": date.getHours().toString(),
|
|
432
|
-
"hh": (date.getHours() % 12 || 12).toString().padStart(2, "0"),
|
|
433
|
-
"h": (date.getHours() % 12 || 12).toString(),
|
|
434
|
-
"mm": date.getMinutes().toString().padStart(2, "0"),
|
|
435
|
-
"m": date.getMinutes().toString(),
|
|
436
|
-
"ss": date.getSeconds().toString().padStart(2, "0"),
|
|
437
|
-
"s": date.getSeconds().toString(),
|
|
438
|
-
"SSS": date.getMilliseconds().toString().padStart(3, "0"),
|
|
439
|
-
"A": date.getHours() >= 12 ? "PM" : "AM",
|
|
440
|
-
"a": date.getHours() >= 12 ? "pm" : "am",
|
|
441
|
-
"ZZ": tzOffset(t[1] * 60).replace(":", ""),
|
|
442
|
-
"Z": tzOffset(t[1] * 60),
|
|
443
|
-
"z": typeof tz == "string" ? tz : t[0]
|
|
444
|
-
};
|
|
445
|
-
return format.replace(/YYYY|YY|MMMM|MMM|MM|M|DDD|DD|Do|D|dddd|ddd|HH|H|hh|h|mm|m|ss|s|SSS|A|a|ZZ|Z|z/g, (token) => tokens[token]);
|
|
446
|
-
}
|
|
447
|
-
function downloadFile(blob, name) {
|
|
448
|
-
if (!(blob instanceof Blob)) blob = new Blob(makeArray(blob));
|
|
449
|
-
const url = URL.createObjectURL(blob);
|
|
450
|
-
downloadUrl(url, name);
|
|
451
|
-
URL.revokeObjectURL(url);
|
|
452
|
-
}
|
|
453
|
-
function downloadUrl(href, name) {
|
|
454
|
-
const a2 = document.createElement("a");
|
|
455
|
-
a2.href = href;
|
|
456
|
-
a2.download = name || href.split("/").pop();
|
|
457
|
-
document.body.appendChild(a2);
|
|
458
|
-
a2.click();
|
|
459
|
-
document.body.removeChild(a2);
|
|
460
|
-
}
|
|
461
|
-
function fileBrowser(options = {}) {
|
|
462
|
-
return new Promise((res) => {
|
|
463
|
-
const input = document.createElement("input");
|
|
464
|
-
input.type = "file";
|
|
465
|
-
input.accept = options.accept || "*";
|
|
466
|
-
input.style.display = "none";
|
|
467
|
-
input.multiple = !!options.multiple;
|
|
468
|
-
input.onblur = input.onchange = async () => {
|
|
469
|
-
res(Array.from(input.files));
|
|
470
|
-
input.remove();
|
|
471
|
-
};
|
|
472
|
-
document.body.appendChild(input);
|
|
473
|
-
input.click();
|
|
474
|
-
});
|
|
475
|
-
}
|
|
476
|
-
function timestampFilename(name, date = /* @__PURE__ */ new Date()) {
|
|
477
|
-
if (typeof date == "number" || typeof date == "string") date = new Date(date);
|
|
478
|
-
const timestamp = formatDate("YYYY-MM-DD_HH:mm:ss", date);
|
|
479
|
-
return timestamp;
|
|
480
|
-
}
|
|
481
|
-
function uploadWithProgress(options) {
|
|
482
|
-
return new PromiseProgress((res, rej, prog) => {
|
|
483
|
-
const xhr = new XMLHttpRequest();
|
|
484
|
-
const formData2 = new FormData();
|
|
485
|
-
options.files.forEach((f) => formData2.append("file", f));
|
|
486
|
-
xhr.withCredentials = !!options.withCredentials;
|
|
487
|
-
xhr.upload.addEventListener("progress", (event) => event.lengthComputable ? prog(event.loaded / event.total) : null);
|
|
488
|
-
xhr.addEventListener("loadend", () => res(JSONAttemptParse(xhr.responseText)));
|
|
489
|
-
xhr.addEventListener("error", () => rej(JSONAttemptParse(xhr.responseText)));
|
|
490
|
-
xhr.addEventListener("timeout", () => rej({ error: "Request timed out" }));
|
|
491
|
-
xhr.open("POST", options.url);
|
|
492
|
-
Object.entries(options.headers || {}).forEach(([key, value2]) => xhr.setRequestHeader(key, value2));
|
|
493
|
-
xhr.send(formData2);
|
|
494
|
-
});
|
|
495
|
-
}
|
|
496
|
-
class TypedEmitter {
|
|
497
|
-
constructor() {
|
|
498
|
-
__publicField2(this, "listeners", {});
|
|
499
|
-
}
|
|
500
|
-
static emit(event, ...args) {
|
|
501
|
-
(this.listeners["*"] || []).forEach((l) => l(event, ...args));
|
|
502
|
-
(this.listeners[event.toString()] || []).forEach((l) => l(...args));
|
|
503
|
-
}
|
|
504
|
-
static off(event, listener) {
|
|
505
|
-
const e = event.toString();
|
|
506
|
-
this.listeners[e] = (this.listeners[e] || []).filter((l) => l === listener);
|
|
507
|
-
}
|
|
508
|
-
static on(event, listener) {
|
|
509
|
-
var _a;
|
|
510
|
-
const e = event.toString();
|
|
511
|
-
if (!this.listeners[e]) this.listeners[e] = [];
|
|
512
|
-
(_a = this.listeners[e]) == null ? void 0 : _a.push(listener);
|
|
513
|
-
return () => this.off(event, listener);
|
|
514
|
-
}
|
|
515
|
-
static once(event, listener) {
|
|
516
|
-
return new Promise((res) => {
|
|
517
|
-
const unsubscribe = this.on(event, (...args) => {
|
|
518
|
-
res(args.length == 1 ? args[0] : args);
|
|
519
|
-
if (listener) listener(...args);
|
|
520
|
-
unsubscribe();
|
|
521
|
-
});
|
|
522
|
-
});
|
|
523
|
-
}
|
|
524
|
-
emit(event, ...args) {
|
|
525
|
-
(this.listeners["*"] || []).forEach((l) => l(event, ...args));
|
|
526
|
-
(this.listeners[event] || []).forEach((l) => l(...args));
|
|
527
|
-
}
|
|
528
|
-
off(event, listener) {
|
|
529
|
-
this.listeners[event] = (this.listeners[event] || []).filter((l) => l === listener);
|
|
530
|
-
}
|
|
531
|
-
on(event, listener) {
|
|
532
|
-
var _a;
|
|
533
|
-
if (!this.listeners[event]) this.listeners[event] = [];
|
|
534
|
-
(_a = this.listeners[event]) == null ? void 0 : _a.push(listener);
|
|
535
|
-
return () => this.off(event, listener);
|
|
536
|
-
}
|
|
537
|
-
once(event, listener) {
|
|
538
|
-
return new Promise((res) => {
|
|
539
|
-
const unsubscribe = this.on(event, (...args) => {
|
|
540
|
-
res(args.length == 1 ? args[0] : args);
|
|
541
|
-
if (listener) listener(...args);
|
|
542
|
-
unsubscribe();
|
|
543
|
-
});
|
|
544
|
-
});
|
|
545
|
-
}
|
|
546
|
-
}
|
|
547
|
-
__publicField2(TypedEmitter, "listeners", {});
|
|
548
|
-
class CustomError extends Error {
|
|
549
|
-
constructor(message, code) {
|
|
550
|
-
super(message);
|
|
551
|
-
__publicField2(this, "_code");
|
|
552
|
-
if (code != null) this._code = code;
|
|
553
|
-
}
|
|
554
|
-
get code() {
|
|
555
|
-
return this._code || this.constructor.code;
|
|
556
|
-
}
|
|
557
|
-
set code(c) {
|
|
558
|
-
this._code = c;
|
|
559
|
-
}
|
|
560
|
-
static from(err) {
|
|
561
|
-
const code = Number(err.statusCode) ?? Number(err.code);
|
|
562
|
-
const newErr = new this(err.message || err.toString());
|
|
563
|
-
return Object.assign(newErr, {
|
|
564
|
-
stack: err.stack,
|
|
565
|
-
...err,
|
|
566
|
-
code: code ?? void 0
|
|
567
|
-
});
|
|
568
|
-
}
|
|
569
|
-
static instanceof(err) {
|
|
570
|
-
return err.constructor.code != void 0;
|
|
571
|
-
}
|
|
572
|
-
toString() {
|
|
573
|
-
return this.message || super.toString();
|
|
574
|
-
}
|
|
575
|
-
}
|
|
576
|
-
__publicField2(CustomError, "code", 500);
|
|
577
|
-
class BadRequestError extends CustomError {
|
|
578
|
-
constructor(message = "Bad Request") {
|
|
579
|
-
super(message);
|
|
580
|
-
}
|
|
581
|
-
static instanceof(err) {
|
|
582
|
-
return err.constructor.code == this.code;
|
|
583
|
-
}
|
|
584
|
-
}
|
|
585
|
-
__publicField2(BadRequestError, "code", 400);
|
|
586
|
-
class UnauthorizedError extends CustomError {
|
|
587
|
-
constructor(message = "Unauthorized") {
|
|
588
|
-
super(message);
|
|
589
|
-
}
|
|
590
|
-
static instanceof(err) {
|
|
591
|
-
return err.constructor.code == this.code;
|
|
592
|
-
}
|
|
593
|
-
}
|
|
594
|
-
__publicField2(UnauthorizedError, "code", 401);
|
|
595
|
-
class PaymentRequiredError extends CustomError {
|
|
596
|
-
constructor(message = "Payment Required") {
|
|
597
|
-
super(message);
|
|
598
|
-
}
|
|
599
|
-
static instanceof(err) {
|
|
600
|
-
return err.constructor.code == this.code;
|
|
601
|
-
}
|
|
602
|
-
}
|
|
603
|
-
__publicField2(PaymentRequiredError, "code", 402);
|
|
604
|
-
class ForbiddenError extends CustomError {
|
|
605
|
-
constructor(message = "Forbidden") {
|
|
606
|
-
super(message);
|
|
607
|
-
}
|
|
608
|
-
static instanceof(err) {
|
|
609
|
-
return err.constructor.code == this.code;
|
|
610
|
-
}
|
|
611
|
-
}
|
|
612
|
-
__publicField2(ForbiddenError, "code", 403);
|
|
613
|
-
class NotFoundError extends CustomError {
|
|
614
|
-
constructor(message = "Not Found") {
|
|
615
|
-
super(message);
|
|
616
|
-
}
|
|
617
|
-
static instanceof(err) {
|
|
618
|
-
return err.constructor.code == this.code;
|
|
619
|
-
}
|
|
620
|
-
}
|
|
621
|
-
__publicField2(NotFoundError, "code", 404);
|
|
622
|
-
class MethodNotAllowedError extends CustomError {
|
|
623
|
-
constructor(message = "Method Not Allowed") {
|
|
624
|
-
super(message);
|
|
625
|
-
}
|
|
626
|
-
static instanceof(err) {
|
|
627
|
-
return err.constructor.code == this.code;
|
|
628
|
-
}
|
|
629
|
-
}
|
|
630
|
-
__publicField2(MethodNotAllowedError, "code", 405);
|
|
631
|
-
class NotAcceptableError extends CustomError {
|
|
632
|
-
constructor(message = "Not Acceptable") {
|
|
633
|
-
super(message);
|
|
634
|
-
}
|
|
635
|
-
static instanceof(err) {
|
|
636
|
-
return err.constructor.code == this.code;
|
|
637
|
-
}
|
|
638
|
-
}
|
|
639
|
-
__publicField2(NotAcceptableError, "code", 406);
|
|
640
|
-
class InternalServerError extends CustomError {
|
|
641
|
-
constructor(message = "Internal Server Error") {
|
|
642
|
-
super(message);
|
|
643
|
-
}
|
|
644
|
-
static instanceof(err) {
|
|
645
|
-
return err.constructor.code == this.code;
|
|
646
|
-
}
|
|
647
|
-
}
|
|
648
|
-
__publicField2(InternalServerError, "code", 500);
|
|
649
|
-
class NotImplementedError extends CustomError {
|
|
650
|
-
constructor(message = "Not Implemented") {
|
|
651
|
-
super(message);
|
|
652
|
-
}
|
|
653
|
-
static instanceof(err) {
|
|
654
|
-
return err.constructor.code == this.code;
|
|
655
|
-
}
|
|
656
|
-
}
|
|
657
|
-
__publicField2(NotImplementedError, "code", 501);
|
|
658
|
-
class BadGatewayError extends CustomError {
|
|
659
|
-
constructor(message = "Bad Gateway") {
|
|
660
|
-
super(message);
|
|
661
|
-
}
|
|
662
|
-
static instanceof(err) {
|
|
663
|
-
return err.constructor.code == this.code;
|
|
664
|
-
}
|
|
665
|
-
}
|
|
666
|
-
__publicField2(BadGatewayError, "code", 502);
|
|
667
|
-
class ServiceUnavailableError extends CustomError {
|
|
668
|
-
constructor(message = "Service Unavailable") {
|
|
669
|
-
super(message);
|
|
670
|
-
}
|
|
671
|
-
static instanceof(err) {
|
|
672
|
-
return err.constructor.code == this.code;
|
|
673
|
-
}
|
|
674
|
-
}
|
|
675
|
-
__publicField2(ServiceUnavailableError, "code", 503);
|
|
676
|
-
class GatewayTimeoutError extends CustomError {
|
|
677
|
-
constructor(message = "Gateway Timeout") {
|
|
678
|
-
super(message);
|
|
679
|
-
}
|
|
680
|
-
static instanceof(err) {
|
|
681
|
-
return err.constructor.code == this.code;
|
|
682
|
-
}
|
|
683
|
-
}
|
|
684
|
-
__publicField2(GatewayTimeoutError, "code", 504);
|
|
685
|
-
class HttpResponse extends Response {
|
|
686
|
-
constructor(resp, stream) {
|
|
687
|
-
super(stream, { headers: resp.headers, status: resp.status, statusText: resp.statusText });
|
|
688
|
-
__publicField2(this, "data");
|
|
689
|
-
__publicField2(this, "ok");
|
|
690
|
-
__publicField2(this, "redirected");
|
|
691
|
-
__publicField2(this, "type");
|
|
692
|
-
__publicField2(this, "url");
|
|
693
|
-
this.ok = resp.ok;
|
|
694
|
-
this.redirected = resp.redirected;
|
|
695
|
-
this.type = resp.type;
|
|
696
|
-
this.url = resp.url;
|
|
697
|
-
}
|
|
698
|
-
}
|
|
699
|
-
const _Http = class _Http2 {
|
|
700
|
-
constructor(defaults = {}) {
|
|
701
|
-
__publicField2(this, "interceptors", {});
|
|
702
|
-
__publicField2(this, "headers", {});
|
|
703
|
-
__publicField2(this, "url");
|
|
704
|
-
this.url = defaults.url ?? null;
|
|
705
|
-
this.headers = defaults.headers || {};
|
|
706
|
-
if (defaults.interceptors) {
|
|
707
|
-
defaults.interceptors.forEach((i) => _Http2.addInterceptor(i));
|
|
708
|
-
}
|
|
709
|
-
}
|
|
710
|
-
static addInterceptor(fn) {
|
|
711
|
-
const key = Object.keys(_Http2.interceptors).length.toString();
|
|
712
|
-
_Http2.interceptors[key] = fn;
|
|
713
|
-
return () => {
|
|
714
|
-
_Http2.interceptors[key] = null;
|
|
715
|
-
};
|
|
716
|
-
}
|
|
717
|
-
addInterceptor(fn) {
|
|
718
|
-
const key = Object.keys(this.interceptors).length.toString();
|
|
719
|
-
this.interceptors[key] = fn;
|
|
720
|
-
return () => {
|
|
721
|
-
this.interceptors[key] = null;
|
|
722
|
-
};
|
|
723
|
-
}
|
|
724
|
-
request(opts = {}) {
|
|
725
|
-
var _a;
|
|
726
|
-
if (!this.url && !opts.url) throw new Error("URL needs to be set");
|
|
727
|
-
let url = (((_a = opts.url) == null ? void 0 : _a.startsWith("http")) ? opts.url : (this.url || "") + (opts.url || "")).replace(/([^:]\/)\/+/g, "$1");
|
|
728
|
-
if (opts.fragment) url.includes("#") ? url.replace(/#.*(\?|\n)/g, (match, arg1) => `#${opts.fragment}${arg1}`) : url += "#" + opts.fragment;
|
|
729
|
-
if (opts.query) {
|
|
730
|
-
const q = Array.isArray(opts.query) ? opts.query : Object.keys(opts.query).map((k) => ({ key: k, value: opts.query[k] }));
|
|
731
|
-
url += (url.includes("?") ? "&" : "?") + q.map((q2) => `${q2.key}=${q2.value}`).join("&");
|
|
732
|
-
}
|
|
733
|
-
const headers = clean({
|
|
734
|
-
"Content-Type": !opts.body ? void 0 : opts.body instanceof FormData ? "multipart/form-data" : "application/json",
|
|
735
|
-
..._Http2.headers,
|
|
736
|
-
...this.headers,
|
|
737
|
-
...opts.headers
|
|
738
|
-
});
|
|
739
|
-
if (typeof opts.body == "object" && opts.body != null && headers["Content-Type"] == "application/json")
|
|
740
|
-
opts.body = JSON.stringify(opts.body);
|
|
741
|
-
return new PromiseProgress((res, rej, prog) => {
|
|
742
|
-
try {
|
|
743
|
-
fetch(url, {
|
|
744
|
-
headers,
|
|
745
|
-
method: opts.method || (opts.body ? "POST" : "GET"),
|
|
746
|
-
body: opts.body
|
|
747
|
-
}).then(async (resp) => {
|
|
748
|
-
var _a2, _b;
|
|
749
|
-
for (let fn of [...Object.values(_Http2.interceptors), ...Object.values(this.interceptors)]) {
|
|
750
|
-
await new Promise((res2) => fn(resp, () => res2()));
|
|
751
|
-
}
|
|
752
|
-
const contentLength = resp.headers.get("Content-Length");
|
|
753
|
-
const total = contentLength ? parseInt(contentLength, 10) : 0;
|
|
754
|
-
let loaded = 0;
|
|
755
|
-
const reader = (_a2 = resp.body) == null ? void 0 : _a2.getReader();
|
|
756
|
-
const stream = new ReadableStream({
|
|
757
|
-
start(controller) {
|
|
758
|
-
function push() {
|
|
759
|
-
reader == null ? void 0 : reader.read().then((event) => {
|
|
760
|
-
if (event.done) return controller.close();
|
|
761
|
-
loaded += event.value.byteLength;
|
|
762
|
-
prog(loaded / total);
|
|
763
|
-
controller.enqueue(event.value);
|
|
764
|
-
push();
|
|
765
|
-
}).catch((error) => controller.error(error));
|
|
766
|
-
}
|
|
767
|
-
push();
|
|
768
|
-
}
|
|
769
|
-
});
|
|
770
|
-
resp = new HttpResponse(resp, stream);
|
|
771
|
-
if (opts.decode !== false) {
|
|
772
|
-
const content = (_b = resp.headers.get("Content-Type")) == null ? void 0 : _b.toLowerCase();
|
|
773
|
-
if (content == null ? void 0 : content.includes("form")) resp.data = await resp.formData();
|
|
774
|
-
else if (content == null ? void 0 : content.includes("json")) resp.data = await resp.json();
|
|
775
|
-
else if (content == null ? void 0 : content.includes("text")) resp.data = await resp.text();
|
|
776
|
-
else if (content == null ? void 0 : content.includes("application")) resp.data = await resp.blob();
|
|
777
|
-
}
|
|
778
|
-
if (resp.ok) res(resp);
|
|
779
|
-
else rej(resp);
|
|
780
|
-
}).catch((err) => rej(err));
|
|
781
|
-
} catch (err) {
|
|
782
|
-
rej(err);
|
|
783
|
-
}
|
|
784
|
-
});
|
|
785
|
-
}
|
|
786
|
-
};
|
|
787
|
-
__publicField2(_Http, "interceptors", {});
|
|
788
|
-
__publicField2(_Http, "headers", {});
|
|
789
|
-
let Http = _Http;
|
|
790
|
-
const CliEffects = {
|
|
791
|
-
CLEAR: "\x1B[0m"
|
|
792
|
-
};
|
|
793
|
-
const CliForeground = {
|
|
794
|
-
RED: "\x1B[31m",
|
|
795
|
-
YELLOW: "\x1B[33m",
|
|
796
|
-
BLUE: "\x1B[34m",
|
|
797
|
-
LIGHT_GREY: "\x1B[37m"
|
|
798
|
-
};
|
|
799
|
-
var LOG_LEVEL = /* @__PURE__ */ ((LOG_LEVEL2) => {
|
|
800
|
-
LOG_LEVEL2[LOG_LEVEL2["ERROR"] = 0] = "ERROR";
|
|
801
|
-
LOG_LEVEL2[LOG_LEVEL2["WARN"] = 1] = "WARN";
|
|
802
|
-
LOG_LEVEL2[LOG_LEVEL2["INFO"] = 2] = "INFO";
|
|
803
|
-
LOG_LEVEL2[LOG_LEVEL2["LOG"] = 3] = "LOG";
|
|
804
|
-
LOG_LEVEL2[LOG_LEVEL2["DEBUG"] = 4] = "DEBUG";
|
|
805
|
-
return LOG_LEVEL2;
|
|
806
|
-
})(LOG_LEVEL || {});
|
|
807
|
-
const _Logger = class _Logger2 extends TypedEmitter {
|
|
808
|
-
constructor(namespace) {
|
|
809
|
-
super();
|
|
810
|
-
this.namespace = namespace;
|
|
811
|
-
}
|
|
812
|
-
format(...text) {
|
|
813
|
-
const now = /* @__PURE__ */ new Date();
|
|
814
|
-
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")}`;
|
|
815
|
-
return `${timestamp}${this.namespace ? ` [${this.namespace}]` : ""} ${text.map((t) => typeof t == "string" ? t : JSONSanitize(t, 2)).join(" ")}`;
|
|
816
|
-
}
|
|
817
|
-
debug(...args) {
|
|
818
|
-
if (_Logger2.LOG_LEVEL < 4) return;
|
|
819
|
-
const str = this.format(...args);
|
|
820
|
-
_Logger2.emit(4, str);
|
|
821
|
-
console.debug(CliForeground.LIGHT_GREY + str + CliEffects.CLEAR);
|
|
822
|
-
}
|
|
823
|
-
log(...args) {
|
|
824
|
-
if (_Logger2.LOG_LEVEL < 3) return;
|
|
825
|
-
const str = this.format(...args);
|
|
826
|
-
_Logger2.emit(3, str);
|
|
827
|
-
console.log(CliEffects.CLEAR + str);
|
|
828
|
-
}
|
|
829
|
-
info(...args) {
|
|
830
|
-
if (_Logger2.LOG_LEVEL < 2) return;
|
|
831
|
-
const str = this.format(...args);
|
|
832
|
-
_Logger2.emit(2, str);
|
|
833
|
-
console.info(CliForeground.BLUE + str + CliEffects.CLEAR);
|
|
834
|
-
}
|
|
835
|
-
warn(...args) {
|
|
836
|
-
if (_Logger2.LOG_LEVEL < 1) return;
|
|
837
|
-
const str = this.format(...args);
|
|
838
|
-
_Logger2.emit(1, str);
|
|
839
|
-
console.warn(CliForeground.YELLOW + str + CliEffects.CLEAR);
|
|
840
|
-
}
|
|
841
|
-
error(...args) {
|
|
842
|
-
if (_Logger2.LOG_LEVEL < 0) return;
|
|
843
|
-
const str = this.format(...args);
|
|
844
|
-
_Logger2.emit(0, str);
|
|
845
|
-
console.error(CliForeground.RED + str + CliEffects.CLEAR);
|
|
846
|
-
}
|
|
847
|
-
};
|
|
848
|
-
__publicField2(_Logger, "LOG_LEVEL", 4);
|
|
849
|
-
function PE(str, ...args) {
|
|
850
|
-
const combined = [];
|
|
851
|
-
for (let i = 0; i < str.length || i < args.length; i++) {
|
|
852
|
-
if (str[i]) combined.push(str[i]);
|
|
853
|
-
if (args[i]) combined.push(args[i]);
|
|
854
|
-
}
|
|
855
|
-
return new PathEvent(combined.join(""));
|
|
856
|
-
}
|
|
857
|
-
function PES(str, ...args) {
|
|
858
|
-
let combined = [];
|
|
859
|
-
for (let i = 0; i < str.length || i < args.length; i++) {
|
|
860
|
-
if (str[i]) combined.push(str[i]);
|
|
861
|
-
if (args[i]) combined.push(args[i]);
|
|
862
|
-
}
|
|
863
|
-
const [paths, methods] = combined.join("").split(":");
|
|
864
|
-
return PathEvent.toString(paths, methods == null ? void 0 : methods.split(""));
|
|
865
|
-
}
|
|
866
|
-
class PathError extends Error {
|
|
867
|
-
}
|
|
868
|
-
class PathEvent {
|
|
869
|
-
constructor(Event) {
|
|
870
|
-
__publicField2(this, "module");
|
|
871
|
-
__publicField2(this, "fullPath");
|
|
872
|
-
__publicField2(this, "path");
|
|
873
|
-
__publicField2(this, "name");
|
|
874
|
-
__publicField2(this, "methods");
|
|
875
|
-
var _a;
|
|
876
|
-
if (typeof Event == "object") return Object.assign(this, Event);
|
|
877
|
-
let [p2, scope, method] = Event.replaceAll(/\/{2,}/g, "/").split(":");
|
|
878
|
-
if (!method) method = scope || "*";
|
|
879
|
-
if (p2 == "*" || !p2 && method == "*") {
|
|
880
|
-
p2 = "";
|
|
881
|
-
method = "*";
|
|
882
|
-
}
|
|
883
|
-
let temp = p2.split("/").filter((p22) => !!p22);
|
|
884
|
-
this.module = ((_a = temp.splice(0, 1)[0]) == null ? void 0 : _a.toLowerCase()) || "";
|
|
885
|
-
this.fullPath = p2;
|
|
886
|
-
this.path = temp.join("/");
|
|
887
|
-
this.name = temp.pop() || "";
|
|
888
|
-
this.methods = new ASet(method.split(""));
|
|
889
|
-
}
|
|
890
|
-
/** All/Wildcard specified */
|
|
891
|
-
get all() {
|
|
892
|
-
return this.methods.has("*");
|
|
893
|
-
}
|
|
894
|
-
set all(v2) {
|
|
895
|
-
v2 ? new ASet(["*"]) : this.methods.delete("*");
|
|
896
|
-
}
|
|
897
|
-
/** None specified */
|
|
898
|
-
get none() {
|
|
899
|
-
return this.methods.has("n");
|
|
900
|
-
}
|
|
901
|
-
set none(v2) {
|
|
902
|
-
v2 ? this.methods = new ASet(["n"]) : this.methods.delete("n");
|
|
903
|
-
}
|
|
904
|
-
/** Create method specified */
|
|
905
|
-
get create() {
|
|
906
|
-
return !this.methods.has("n") && (this.methods.has("*") || this.methods.has("c"));
|
|
907
|
-
}
|
|
908
|
-
set create(v2) {
|
|
909
|
-
v2 ? this.methods.delete("n").add("c") : this.methods.delete("c");
|
|
910
|
-
}
|
|
911
|
-
/** Read method specified */
|
|
912
|
-
get read() {
|
|
913
|
-
return !this.methods.has("n") && (this.methods.has("*") || this.methods.has("r"));
|
|
914
|
-
}
|
|
915
|
-
set read(v2) {
|
|
916
|
-
v2 ? this.methods.delete("n").add("r") : this.methods.delete("r");
|
|
917
|
-
}
|
|
918
|
-
/** Update method specified */
|
|
919
|
-
get update() {
|
|
920
|
-
return !this.methods.has("n") && (this.methods.has("*") || this.methods.has("u"));
|
|
921
|
-
}
|
|
922
|
-
set update(v2) {
|
|
923
|
-
v2 ? this.methods.delete("n").add("u") : this.methods.delete("u");
|
|
924
|
-
}
|
|
925
|
-
/** Delete method specified */
|
|
926
|
-
get delete() {
|
|
927
|
-
return !this.methods.has("n") && (this.methods.has("*") || this.methods.has("d"));
|
|
928
|
-
}
|
|
929
|
-
set delete(v2) {
|
|
930
|
-
v2 ? this.methods.delete("n").add("d") : this.methods.delete("d");
|
|
931
|
-
}
|
|
932
|
-
/**
|
|
933
|
-
* Combine multiple events into one parsed object. Longest path takes precedent, but all subsequent methods are
|
|
934
|
-
* combined until a "none" is reached
|
|
935
|
-
*
|
|
936
|
-
* @param {string | PathEvent} paths Events as strings or pre-parsed
|
|
937
|
-
* @return {PathEvent} Final combined permission
|
|
938
|
-
*/
|
|
939
|
-
static combine(...paths) {
|
|
940
|
-
let hitNone = false;
|
|
941
|
-
const combined = paths.map((p2) => new PathEvent(p2)).toSorted((p1, p2) => {
|
|
942
|
-
const l1 = p1.fullPath.length, l2 = p2.fullPath.length;
|
|
943
|
-
return l1 < l2 ? 1 : l1 > l2 ? -1 : 0;
|
|
944
|
-
}).reduce((acc, p2) => {
|
|
945
|
-
if (p2.none) hitNone = true;
|
|
946
|
-
if (!acc) return p2;
|
|
947
|
-
if (hitNone) return acc;
|
|
948
|
-
acc.methods = [...acc.methods, ...p2.methods];
|
|
949
|
-
return acc;
|
|
950
|
-
}, null);
|
|
951
|
-
combined.methods = new ASet(combined.methods);
|
|
952
|
-
return combined;
|
|
953
|
-
}
|
|
954
|
-
/**
|
|
955
|
-
* Filter a set of paths based on the target
|
|
956
|
-
*
|
|
957
|
-
* @param {string | PathEvent | (string | PathEvent)[]} target Array of events that will filtered
|
|
958
|
-
* @param filter {...PathEvent} Must container one of
|
|
959
|
-
* @return {boolean} Whether there is any overlap
|
|
960
|
-
*/
|
|
961
|
-
static filter(target, ...filter) {
|
|
962
|
-
const parsedTarget = makeArray(target).map((pe) => new PathEvent(pe));
|
|
963
|
-
const parsedFind = makeArray(filter).map((pe) => new PathEvent(pe));
|
|
964
|
-
return parsedTarget.filter((t) => {
|
|
965
|
-
if (!t.fullPath && t.all) return true;
|
|
966
|
-
return !!parsedFind.find((f) => (t.fullPath.startsWith(f.fullPath) || f.fullPath.startsWith(t.fullPath)) && (f.all || t.all || t.methods.intersection(f.methods).length));
|
|
967
|
-
});
|
|
968
|
-
}
|
|
969
|
-
/**
|
|
970
|
-
* Squash 2 sets of paths & return true if any overlap is found
|
|
971
|
-
*
|
|
972
|
-
* @param {string | PathEvent | (string | PathEvent)[]} target Array of Events as strings or pre-parsed
|
|
973
|
-
* @param has Target must have at least one of these path
|
|
974
|
-
* @return {boolean} Whether there is any overlap
|
|
975
|
-
*/
|
|
976
|
-
static has(target, ...has) {
|
|
977
|
-
const parsedRequired = makeArray(has).map((pe) => new PathEvent(pe));
|
|
978
|
-
const parsedTarget = makeArray(target).map((pe) => new PathEvent(pe));
|
|
979
|
-
return !!parsedRequired.find((r2) => {
|
|
980
|
-
if (!r2.fullPath && r2.all) return true;
|
|
981
|
-
const filtered = parsedTarget.filter((p2) => r2.fullPath.startsWith(p2.fullPath));
|
|
982
|
-
if (!filtered.length) return false;
|
|
983
|
-
const combined = PathEvent.combine(...filtered);
|
|
984
|
-
return !combined.none && (combined.all || r2.all) || combined.methods.intersection(r2.methods).length;
|
|
985
|
-
});
|
|
986
|
-
}
|
|
987
|
-
/**
|
|
988
|
-
* Squash 2 sets of paths & return true if the target has all paths
|
|
989
|
-
*
|
|
990
|
-
* @param {string | PathEvent | (string | PathEvent)[]} target Array of Events as strings or pre-parsed
|
|
991
|
-
* @param has Target must have all these paths
|
|
992
|
-
* @return {boolean} Whether there is any overlap
|
|
993
|
-
*/
|
|
994
|
-
static hasAll(target, ...has) {
|
|
995
|
-
return has.filter((h) => PathEvent.has(target, h)).length == has.length;
|
|
996
|
-
}
|
|
997
|
-
/**
|
|
998
|
-
* Same as `has` but raises an error if there is no overlap
|
|
999
|
-
*
|
|
1000
|
-
* @param {string | string[]} target Array of Events as strings or pre-parsed
|
|
1001
|
-
* @param has Target must have at least one of these path
|
|
1002
|
-
*/
|
|
1003
|
-
static hasFatal(target, ...has) {
|
|
1004
|
-
if (!PathEvent.has(target, ...has)) throw new PathError(`Requires one of: ${makeArray(has).join(", ")}`);
|
|
1005
|
-
}
|
|
1006
|
-
/**
|
|
1007
|
-
* Same as `hasAll` but raises an error if the target is missing any paths
|
|
1008
|
-
*
|
|
1009
|
-
* @param {string | string[]} target Array of Events as strings or pre-parsed
|
|
1010
|
-
* @param has Target must have all these paths
|
|
1011
|
-
*/
|
|
1012
|
-
static hasAllFatal(target, ...has) {
|
|
1013
|
-
if (!PathEvent.hasAll(target, ...has)) throw new PathError(`Requires all: ${makeArray(has).join(", ")}`);
|
|
1014
|
-
}
|
|
1015
|
-
/**
|
|
1016
|
-
* Create event string from its components
|
|
1017
|
-
*
|
|
1018
|
-
* @param {string | string[]} path Event path
|
|
1019
|
-
* @param {Method} methods Event method
|
|
1020
|
-
* @return {string} String representation of Event
|
|
1021
|
-
*/
|
|
1022
|
-
static toString(path, methods) {
|
|
1023
|
-
let p2 = makeArray(path).filter((p22) => p22 != null).join("/");
|
|
1024
|
-
p2 = p2 == null ? void 0 : p2.trim().replaceAll(/\/{2,}/g, "/").replaceAll(/(^\/|\/$)/g, "");
|
|
1025
|
-
if (methods == null ? void 0 : methods.length) p2 += `:${makeArray(methods).map((m) => m.toLowerCase()).join("")}`;
|
|
1026
|
-
return p2;
|
|
1027
|
-
}
|
|
1028
|
-
/**
|
|
1029
|
-
* Filter a set of paths based on this event
|
|
1030
|
-
*
|
|
1031
|
-
* @param {string | PathEvent | (string | PathEvent)[]} target Array of events that will filtered
|
|
1032
|
-
* @return {boolean} Whether there is any overlap
|
|
1033
|
-
*/
|
|
1034
|
-
filter(target) {
|
|
1035
|
-
return PathEvent.filter(target, this);
|
|
1036
|
-
}
|
|
1037
|
-
/**
|
|
1038
|
-
* Create event string from its components
|
|
1039
|
-
*
|
|
1040
|
-
* @return {string} String representation of Event
|
|
1041
|
-
*/
|
|
1042
|
-
toString() {
|
|
1043
|
-
return PathEvent.toString(this.fullPath, this.methods);
|
|
1044
|
-
}
|
|
1045
|
-
}
|
|
1046
|
-
class PathEventEmitter {
|
|
1047
|
-
constructor() {
|
|
1048
|
-
__publicField2(this, "listeners", []);
|
|
1049
|
-
}
|
|
1050
|
-
emit(event, ...args) {
|
|
1051
|
-
const parsed = new PathEvent(event);
|
|
1052
|
-
this.listeners.filter((l) => PathEvent.has(l[0], event)).forEach(async (l) => l[1](parsed, ...args));
|
|
1053
|
-
}
|
|
1054
|
-
off(listener) {
|
|
1055
|
-
this.listeners = this.listeners.filter((l) => l[1] != listener);
|
|
1056
|
-
}
|
|
1057
|
-
on(event, listener) {
|
|
1058
|
-
makeArray(event).forEach((e) => this.listeners.push([new PathEvent(e), listener]));
|
|
1059
|
-
return () => this.off(listener);
|
|
1060
|
-
}
|
|
1061
|
-
once(event, listener) {
|
|
1062
|
-
return new Promise((res) => {
|
|
1063
|
-
const unsubscribe = this.on(event, (event2, ...args) => {
|
|
1064
|
-
res(args.length < 2 ? args[0] : args);
|
|
1065
|
-
if (listener) listener(event2, ...args);
|
|
1066
|
-
unsubscribe();
|
|
1067
|
-
});
|
|
1068
|
-
});
|
|
1069
|
-
}
|
|
1070
|
-
relayEvents(emitter) {
|
|
1071
|
-
emitter.on("*", (event, ...args) => this.emit(event, ...args));
|
|
1072
|
-
}
|
|
1073
|
-
}
|
|
1074
|
-
class Api extends Http {
|
|
1075
|
-
constructor(url = location.origin, opts = {}) {
|
|
1076
|
-
super({ ...(opts == null ? void 0 : opts.http) || {}, url });
|
|
1077
|
-
__publicField(this, "emitter", new PathEventEmitter());
|
|
1078
|
-
__publicField(this, "pending", {});
|
|
1079
|
-
__publicField(this, "storageKey");
|
|
1080
|
-
__publicField(this, "host");
|
|
1081
|
-
__publicField(this, "_token", null);
|
|
1082
|
-
__publicField(this, "emit", this.emitter.emit.bind(this.emitter));
|
|
1083
|
-
__publicField(this, "off", this.emitter.off.bind(this.emitter));
|
|
1084
|
-
__publicField(this, "on", this.emitter.on.bind(this.emitter));
|
|
1085
|
-
__publicField(this, "once", this.emitter.once.bind(this.emitter));
|
|
1086
|
-
__publicField(this, "relayEvents", this.emitter.relayEvents.bind(this.emitter));
|
|
1087
|
-
this.url = url;
|
|
1088
|
-
this.opts = opts;
|
|
1089
|
-
this.host = new URL(url).host;
|
|
1090
|
-
this.storageKey = `momentum:token:${this.host}`;
|
|
1091
|
-
if (opts.persist && localStorage) {
|
|
1092
|
-
const token = localStorage.getItem(this.storageKey);
|
|
1093
|
-
if (token) this.token = token;
|
|
1094
|
-
}
|
|
1095
|
-
}
|
|
1096
|
-
get sameOrigin() {
|
|
1097
|
-
if (typeof window == "undefined" || !(window == null ? void 0 : window.location)) return false;
|
|
1098
|
-
return window.location.host == this.host;
|
|
1099
|
-
}
|
|
1100
|
-
/** Current API token */
|
|
1101
|
-
get token() {
|
|
1102
|
-
return this._token;
|
|
1103
|
-
}
|
|
1104
|
-
set token(token) {
|
|
1105
|
-
if (token == this._token) return;
|
|
1106
|
-
this._token = token;
|
|
1107
|
-
this.headers["Authorization"] = token ? `Bearer ${token}` : null;
|
|
1108
|
-
if (this.opts.persist && localStorage) {
|
|
1109
|
-
if (token) localStorage.setItem(this.storageKey, token);
|
|
1110
|
-
else localStorage.removeItem(this.storageKey);
|
|
1111
|
-
}
|
|
1112
|
-
this.emit(PES`api/token:${token ? "u" : "d"}`, token);
|
|
1113
|
-
}
|
|
1114
|
-
/**
|
|
1115
|
-
* Fetch current Momentum status
|
|
1116
|
-
* @return {Promise<Health>}
|
|
1117
|
-
*/
|
|
1118
|
-
healthcheck() {
|
|
1119
|
-
return this.request({ url: "/api/healthcheck" }).then((resp) => {
|
|
1120
|
-
this.emit(PES`api/healthcheck:r`, resp);
|
|
1121
|
-
return resp;
|
|
1122
|
-
});
|
|
1123
|
-
}
|
|
1124
|
-
/**
|
|
1125
|
-
* Create API request
|
|
1126
|
-
* @param {HttpRequestOptions} options Request options
|
|
1127
|
-
* @return {Promise} Response
|
|
1128
|
-
*/
|
|
1129
|
-
request(options) {
|
|
1130
|
-
const key = JSONSanitize(options);
|
|
1131
|
-
const method = options.method == "GET" ? "r" : options.method == "POST" ? "c" : options.method == "DELETE" ? "d" : "u";
|
|
1132
|
-
if (this.pending[key] != null) return this.pending[key];
|
|
1133
|
-
this.pending[key] = super.request({ ...options, credentials: "include" }).then((response) => {
|
|
1134
|
-
this.emit(PES`api/response:${method}`, { request: options, response });
|
|
1135
|
-
return options.decode === false ? response : response.data;
|
|
1136
|
-
}).catch((err) => {
|
|
1137
|
-
const e = (err == null ? void 0 : err.data) || err;
|
|
1138
|
-
this.emit(PES`api/error:${method}`, { request: options, error: e });
|
|
1139
|
-
throw e;
|
|
1140
|
-
}).finally(() => delete this.pending[key]);
|
|
1141
|
-
this.emit(PES`api/request:${method}`, { request: options, response: this.pending[key] });
|
|
1142
|
-
return this.pending[key];
|
|
1143
|
-
}
|
|
1144
|
-
}
|
|
1145
|
-
var ActionType = /* @__PURE__ */ ((ActionType2) => {
|
|
1146
|
-
ActionType2[ActionType2["CRON"] = 0] = "CRON";
|
|
1147
|
-
ActionType2[ActionType2["EVENT"] = 1] = "EVENT";
|
|
1148
|
-
ActionType2[ActionType2["DELETE"] = 2] = "DELETE";
|
|
1149
|
-
ActionType2[ActionType2["GET"] = 3] = "GET";
|
|
1150
|
-
ActionType2[ActionType2["PATCH"] = 4] = "PATCH";
|
|
1151
|
-
ActionType2[ActionType2["POST"] = 5] = "POST";
|
|
1152
|
-
ActionType2[ActionType2["PUT"] = 6] = "PUT";
|
|
1153
|
-
return ActionType2;
|
|
1154
|
-
})(ActionType || {});
|
|
1155
|
-
class Actions extends PathEventEmitter {
|
|
1156
|
-
constructor(api) {
|
|
1157
|
-
super();
|
|
1158
|
-
__publicField(this, "api");
|
|
1159
|
-
__publicField(this, "cache", new Cache("_id"));
|
|
1160
|
-
this.api = typeof api == "string" ? new Api(api) : api;
|
|
1161
|
-
}
|
|
1162
|
-
/**
|
|
1163
|
-
* All saved actions
|
|
1164
|
-
* @param {boolean} reload Will use cached response if false
|
|
1165
|
-
* @return {Promise<Action[]>} List of saved actions
|
|
1166
|
-
*/
|
|
1167
|
-
async all(reload) {
|
|
1168
|
-
if (!reload && this.cache.complete) return this.cache.all();
|
|
1169
|
-
return this.api.request({ url: `/api/` + PES`actions` }).then((resp) => {
|
|
1170
|
-
this.cache.addAll(resp);
|
|
1171
|
-
this.emit(PES`actions:r`, resp || []);
|
|
1172
|
-
return resp;
|
|
1173
|
-
});
|
|
1174
|
-
}
|
|
1175
|
-
/**
|
|
1176
|
-
* Manually trigger an actions execution
|
|
1177
|
-
* @param {string} id Action ID
|
|
1178
|
-
* @param {HttpRequestOptions} opts Additional arguments
|
|
1179
|
-
* @return {Promise<ActionResult>} All action output including console logs & return
|
|
1180
|
-
*/
|
|
1181
|
-
debug(id, opts = {}) {
|
|
1182
|
-
return this.api.request({ url: "/api/" + PES`actions/debug/${id}`, method: "POST", ...opts });
|
|
1183
|
-
}
|
|
1184
|
-
/**
|
|
1185
|
-
* Delete an existing action
|
|
1186
|
-
* @param {string} id Action ID
|
|
1187
|
-
* @return {Promise<void>} Delete complete
|
|
1188
|
-
*/
|
|
1189
|
-
delete(id) {
|
|
1190
|
-
if (!id) throw new Error("Cannot delete action, missing ID");
|
|
1191
|
-
return this.api.request({ url: `/api/` + PES`actions/${id}`, method: "DELETE" }).then(() => {
|
|
1192
|
-
this.cache.delete(id);
|
|
1193
|
-
this.emit(PES`actions/${id}:d`, id);
|
|
1194
|
-
});
|
|
1195
|
-
}
|
|
1196
|
-
/**
|
|
1197
|
-
* Fetch action info
|
|
1198
|
-
* @param {string} id Action ID
|
|
1199
|
-
* @param {boolean} reload Will use cached response if false
|
|
1200
|
-
* @return {Promise<Action | null>} Requested action
|
|
1201
|
-
*/
|
|
1202
|
-
read(id, reload) {
|
|
1203
|
-
if (!id) throw new Error("Cannot read action, missing ID");
|
|
1204
|
-
const cached = this.cache.get(id);
|
|
1205
|
-
if (!reload && cached) return Promise.resolve(cached);
|
|
1206
|
-
return this.api.request({ url: `/api/` + PES`actions/${id}` }).then((action) => {
|
|
1207
|
-
if (action) this.cache.add(action);
|
|
1208
|
-
this.emit(PES`actions/${id}:r`, action);
|
|
1209
|
-
return action;
|
|
1210
|
-
});
|
|
1211
|
-
}
|
|
1212
|
-
/**
|
|
1213
|
-
* Run an HTTP action
|
|
1214
|
-
* @param {string} path HTTP path excluding `/api/actions/run`
|
|
1215
|
-
* @param {HttpRequestOptions} opts HTTP options
|
|
1216
|
-
* @return {Promise<T>} HTTP response
|
|
1217
|
-
*/
|
|
1218
|
-
run(path, opts = {}) {
|
|
1219
|
-
return this.api.request({ ...opts, url: "/api/" + PES`actions/run/${path}` });
|
|
1220
|
-
}
|
|
1221
|
-
/**
|
|
1222
|
-
* Update an action
|
|
1223
|
-
* @param {Action} action The new action
|
|
1224
|
-
* @return {Promise<Action>} Saved action
|
|
1225
|
-
*/
|
|
1226
|
-
update(action) {
|
|
1227
|
-
return this.api.request({
|
|
1228
|
-
url: `/api/` + PES`actions/${action._id}`,
|
|
1229
|
-
method: "POST",
|
|
1230
|
-
body: action
|
|
1231
|
-
}).then((action2) => {
|
|
1232
|
-
if (action2) this.cache.add(action2);
|
|
1233
|
-
this.emit(PES`actions/${action2._id}:u`, action2);
|
|
1234
|
-
return action2;
|
|
1235
|
-
});
|
|
1236
|
-
}
|
|
1237
|
-
}
|
|
1238
|
-
class Ai extends PathEventEmitter {
|
|
1239
|
-
constructor(api) {
|
|
1240
|
-
super();
|
|
1241
|
-
__publicField(this, "api");
|
|
1242
|
-
this.api = typeof api == "string" ? new Api(api) : api;
|
|
1243
|
-
}
|
|
1244
|
-
/**
|
|
1245
|
-
* Ask the AI assistant a question
|
|
1246
|
-
* @param {string} question Users question
|
|
1247
|
-
* @param {any} context Additional data to aid response
|
|
1248
|
-
* @return {Promise<string>} AI's response
|
|
1249
|
-
*/
|
|
1250
|
-
ask(question, context) {
|
|
1251
|
-
if (!question) throw new Error("Cannot ask AI, missing question");
|
|
1252
|
-
return this.api.request({ url: `/api/` + PES`ai`, method: "POST", body: {
|
|
1253
|
-
question,
|
|
1254
|
-
context
|
|
1255
|
-
} }).then((response) => {
|
|
1256
|
-
this.emit(PES`ai:c`, { question, context, response });
|
|
1257
|
-
return response;
|
|
1258
|
-
});
|
|
1259
|
-
}
|
|
1260
|
-
/**
|
|
1261
|
-
* Clear AI assistant memory & context
|
|
1262
|
-
* @return {Promise<void>} Resolves once complete
|
|
1263
|
-
*/
|
|
1264
|
-
clear() {
|
|
1265
|
-
return this.api.request({ url: "/api/" + PES`ai`, method: "DELETE" }).then(() => this.emit(PES`ai:d`, this.api.token));
|
|
1266
|
-
}
|
|
1267
|
-
/**
|
|
1268
|
-
* Current chat history
|
|
1269
|
-
* @return {Promise<{role: string, content: string}[]>}
|
|
1270
|
-
*/
|
|
1271
|
-
history() {
|
|
1272
|
-
return this.api.request({ url: "/api/" + PES`ai` }).then((resp) => {
|
|
1273
|
-
this.emit(PES`ai:r`, resp);
|
|
1274
|
-
return resp;
|
|
1275
|
-
});
|
|
1276
|
-
}
|
|
1277
|
-
/**
|
|
1278
|
-
* Get model info
|
|
1279
|
-
* @return {Promise<{host: string, model: string}>} Model Info
|
|
1280
|
-
*/
|
|
1281
|
-
info() {
|
|
1282
|
-
return this.api.request({ url: "/api/ai/info" });
|
|
1283
|
-
}
|
|
1284
|
-
}
|
|
1285
|
-
class Analytics extends PathEventEmitter {
|
|
1286
|
-
constructor(api) {
|
|
1287
|
-
super();
|
|
1288
|
-
__publicField(this, "api");
|
|
1289
|
-
this.api = typeof api == "string" ? new Api(api) : api;
|
|
1290
|
-
}
|
|
1291
|
-
/**
|
|
1292
|
-
* Perform IP trace
|
|
1293
|
-
* @param {string} ip IP address to trace
|
|
1294
|
-
* @return {Promise<IpTrace>} Trace results
|
|
1295
|
-
*/
|
|
1296
|
-
ipTrace(ip) {
|
|
1297
|
-
if (!ip) throw new Error("Cannot trace, missing IP");
|
|
1298
|
-
return this.api.request({ url: `/api/` + PES`analytics/trace/${ip}` }).then((resp) => {
|
|
1299
|
-
this.emit(PES`analytics/trace/${ip}:r`, resp);
|
|
1300
|
-
return resp;
|
|
1301
|
-
});
|
|
1302
|
-
}
|
|
1303
|
-
}
|
|
1304
|
-
class Token extends PathEventEmitter {
|
|
1305
|
-
constructor(api) {
|
|
1306
|
-
super();
|
|
1307
|
-
this.api = api;
|
|
1308
|
-
}
|
|
1309
|
-
/**
|
|
1310
|
-
* Fetch all tokens for user
|
|
1311
|
-
* @param {string} username User to search
|
|
1312
|
-
* @return {Promise<UserToken[]>} List of tokens
|
|
1313
|
-
*/
|
|
1314
|
-
all(username) {
|
|
1315
|
-
return this.api.request({ url: "/" + PES`api/auth/tokens/${username}` }).then((resp) => {
|
|
1316
|
-
this.emit(PES`token/${username}:r`, resp);
|
|
1317
|
-
return resp;
|
|
1318
|
-
});
|
|
1319
|
-
}
|
|
1320
|
-
/**
|
|
1321
|
-
* Create a new user token
|
|
1322
|
-
* @param {{name: string, owner: string, expire: null | Date}} token Token settings
|
|
1323
|
-
* @return {Promise<UserToken>} Crated token
|
|
1324
|
-
*/
|
|
1325
|
-
create(token) {
|
|
1326
|
-
return this.api.request({ url: "/" + PES`api/auth/tokens/${token.owner}`, body: token }).then((resp) => {
|
|
1327
|
-
this.emit(PES`token/${token.owner}:c`, token);
|
|
1328
|
-
return resp;
|
|
1329
|
-
});
|
|
1330
|
-
}
|
|
1331
|
-
/**
|
|
1332
|
-
* Delete an existing user token
|
|
1333
|
-
* @param {string} id Token ID
|
|
1334
|
-
* @return {Promise<void>} Resolves once complete
|
|
1335
|
-
*/
|
|
1336
|
-
delete(id) {
|
|
1337
|
-
return this.api.request({ url: "/" + PES`api/auth/tokens/${id}`, method: "DELETE" }).then(() => this.emit(PES`token/${id}:d`, id));
|
|
1338
|
-
}
|
|
1339
|
-
}
|
|
1340
|
-
class Totp {
|
|
1341
|
-
constructor(api) {
|
|
1342
|
-
/**
|
|
1343
|
-
* Enable 2FA for user
|
|
1344
|
-
* @param {string} username User to reset
|
|
1345
|
-
* @return {Promise<void>} Resolves once complete
|
|
1346
|
-
*/
|
|
1347
|
-
__publicField(this, "enable", this.reset);
|
|
1348
|
-
this.api = api;
|
|
1349
|
-
}
|
|
1350
|
-
/**
|
|
1351
|
-
* Disable 2FA for user
|
|
1352
|
-
* @param {string} username User to disable 2FA for
|
|
1353
|
-
* @return {Promise<void>} Resolves once complete
|
|
1354
|
-
*/
|
|
1355
|
-
disable(username) {
|
|
1356
|
-
return this.api.request({ url: "/" + PES`api/auth/totp/${username}`, method: "DELETE" });
|
|
1357
|
-
}
|
|
1358
|
-
/**
|
|
1359
|
-
* Reset users 2FA
|
|
1360
|
-
* @param {string} username User to reset
|
|
1361
|
-
* @return {Promise<void>} Resolves once complete
|
|
1362
|
-
*/
|
|
1363
|
-
reset(username) {
|
|
1364
|
-
return this.api.request({ url: "/" + PES`api/auth/totp/${username}`, method: "POST" });
|
|
1365
|
-
}
|
|
1366
|
-
/**
|
|
1367
|
-
* Setup 2FA authentication method
|
|
1368
|
-
* @param {string} username User to setup
|
|
1369
|
-
* @param {string} method Authenticator type
|
|
1370
|
-
* @param {string | null} totp null to being process, 2FA code to validate method
|
|
1371
|
-
* @return {Promise<void>} Resolves once complete
|
|
1372
|
-
*/
|
|
1373
|
-
setup(username, method = "app", totp) {
|
|
1374
|
-
return this.api.request({ url: "/" + PES`api/auth/totp/${username}`, body: clean({
|
|
1375
|
-
method,
|
|
1376
|
-
totp
|
|
1377
|
-
}) });
|
|
1378
|
-
}
|
|
1379
|
-
}
|
|
1380
|
-
class Auth extends PathEventEmitter {
|
|
1381
|
-
constructor(api, opts = {}) {
|
|
1382
|
-
super();
|
|
1383
|
-
__publicField(this, "api");
|
|
1384
|
-
/** Manage user tokens */
|
|
1385
|
-
__publicField(this, "token");
|
|
1386
|
-
/** Manage user 2FA */
|
|
1387
|
-
__publicField(this, "totp");
|
|
1388
|
-
__publicField(this, "_permissions", []);
|
|
1389
|
-
__publicField(this, "_user");
|
|
1390
|
-
// Permission helpers
|
|
1391
|
-
__publicField(this, "filter", (...events) => PathEvent.filter(this.permissions, ...events));
|
|
1392
|
-
__publicField(this, "has", (...events) => PathEvent.has(this.permissions, ...events));
|
|
1393
|
-
__publicField(this, "hasAll", (...events) => PathEvent.hasAll(this.permissions, ...events));
|
|
1394
|
-
__publicField(this, "hasFatal", (...events) => PathEvent.hasFatal(this.permissions, ...events));
|
|
1395
|
-
__publicField(this, "hasAllFatal", (...events) => PathEvent.hasAllFatal(this.permissions, ...events));
|
|
1396
|
-
this.opts = opts;
|
|
1397
|
-
this.api = typeof api == "string" ? new Api(api) : api;
|
|
1398
|
-
this.token = new Token(this.api);
|
|
1399
|
-
this.totp = new Totp(this.api);
|
|
1400
|
-
this.relayEvents(this.token);
|
|
1401
|
-
this.opts = {
|
|
1402
|
-
loginUrl: this.api.url + "/ui/login",
|
|
1403
|
-
...this.opts
|
|
1404
|
-
};
|
|
1405
|
-
this.api.addInterceptor((resp, next) => {
|
|
1406
|
-
const blacklist = [
|
|
1407
|
-
"/api/auth/login",
|
|
1408
|
-
"/api/auth/password",
|
|
1409
|
-
"/api/auth/totp"
|
|
1410
|
-
];
|
|
1411
|
-
if (resp.status == 401 && !blacklist.find((url) => resp.url.includes(url)))
|
|
1412
|
-
this.emit(PES`auth/session-expired:d`, this.api.token);
|
|
1413
|
-
next();
|
|
1414
|
-
});
|
|
1415
|
-
if (this.api.token) this.session(this.api.token, true);
|
|
1416
|
-
else this.user = null;
|
|
1417
|
-
this.api.on("api/token", (event, token) => {
|
|
1418
|
-
if (token) this.session(token, true).catch(() => {
|
|
1419
|
-
});
|
|
1420
|
-
else this.user = null;
|
|
1421
|
-
});
|
|
1422
|
-
}
|
|
1423
|
-
/** Get current user permissions */
|
|
1424
|
-
get permissions() {
|
|
1425
|
-
return this._permissions;
|
|
1426
|
-
}
|
|
1427
|
-
set permissions(perms) {
|
|
1428
|
-
this._permissions = perms;
|
|
1429
|
-
this.emit(PES`auth/permissions:u`, this._permissions);
|
|
1430
|
-
}
|
|
1431
|
-
/** Get current user, undefined if not yet initialized */
|
|
1432
|
-
get user() {
|
|
1433
|
-
return this._user;
|
|
1434
|
-
}
|
|
1435
|
-
/** Update user info without changing the session */
|
|
1436
|
-
set user(user) {
|
|
1437
|
-
if (!isEqual(this.user, user)) {
|
|
1438
|
-
this._user = user ? user : null;
|
|
1439
|
-
this.emit(PES`auth/user:u`, this._user);
|
|
1440
|
-
}
|
|
1441
|
-
}
|
|
1442
|
-
/**
|
|
1443
|
-
* Check if origin is recognized & whitelisted
|
|
1444
|
-
* @param {string} host Origin to check
|
|
1445
|
-
* @return {Promise<void>} Resolves in known, 401 code otherwise
|
|
1446
|
-
*/
|
|
1447
|
-
knownHost(host = location.origin) {
|
|
1448
|
-
if (host.startsWith("/")) return Promise.resolve();
|
|
1449
|
-
return this.api.request({ url: `/api/auth/known-host?host=${encodeURI(new URL(host).origin)}` });
|
|
1450
|
-
}
|
|
1451
|
-
/**
|
|
1452
|
-
* Login a user & return the account
|
|
1453
|
-
* @param {string} username username
|
|
1454
|
-
* @param {string} password user's password
|
|
1455
|
-
* @param {{totp: string, expire: null | number | Date}} opts 2FA code and expiry options (null to never expire)
|
|
1456
|
-
* @return {Promise<User | null>} User account on success
|
|
1457
|
-
*/
|
|
1458
|
-
login(username, password, opts) {
|
|
1459
|
-
if (!username || !password) throw new Error("Cannot login, missing username or password");
|
|
1460
|
-
return this.api.request({
|
|
1461
|
-
url: "/api/auth/login",
|
|
1462
|
-
headers: { Authorization: void 0 },
|
|
1463
|
-
method: "POST",
|
|
1464
|
-
body: clean({
|
|
1465
|
-
username: username.trim(),
|
|
1466
|
-
password: password.trim(),
|
|
1467
|
-
...opts
|
|
1468
|
-
}, true)
|
|
1469
|
-
}).then(async (resp) => {
|
|
1470
|
-
this.api.token = (resp == null ? void 0 : resp.token) || null;
|
|
1471
|
-
const user = await this.once("auth/user");
|
|
1472
|
-
this.emit(PES`auth/login/${username}:u`, user);
|
|
1473
|
-
return user;
|
|
1474
|
-
});
|
|
1475
|
-
}
|
|
1476
|
-
/**
|
|
1477
|
-
* Login via Momentum single sign on
|
|
1478
|
-
* @param {string} host Host origin attempting to login
|
|
1479
|
-
* @return {Promise<string>} Token on success
|
|
1480
|
-
*/
|
|
1481
|
-
loginRedirect(host = location.origin) {
|
|
1482
|
-
return new Promise((res, rej) => {
|
|
1483
|
-
var _a;
|
|
1484
|
-
let origin = new URL(this.opts.loginUrl).origin, listener, win;
|
|
1485
|
-
window.addEventListener("message", listener = (event) => {
|
|
1486
|
-
const data = (event == null ? void 0 : event.data) || {};
|
|
1487
|
-
if (event.origin != origin || data.sender != origin) return;
|
|
1488
|
-
if (!data.token) return rej("Unknown response from login");
|
|
1489
|
-
this.api.token = data.token;
|
|
1490
|
-
window.removeEventListener("message", listener);
|
|
1491
|
-
win.close();
|
|
1492
|
-
res(data.token);
|
|
1493
|
-
});
|
|
1494
|
-
win = window.open(encodeURI(`${(_a = this.opts) == null ? void 0 : _a.loginUrl}?redirect=postmessage&host=${host}`), "_blank");
|
|
1495
|
-
if (!win) {
|
|
1496
|
-
window.removeEventListener("message", listener);
|
|
1497
|
-
return rej("Unable to open login");
|
|
1498
|
-
}
|
|
1499
|
-
});
|
|
1500
|
-
}
|
|
1501
|
-
/**
|
|
1502
|
-
* Logout current user
|
|
1503
|
-
*/
|
|
1504
|
-
logout() {
|
|
1505
|
-
this.emit(PES`auth/logout:d`, this.user);
|
|
1506
|
-
this.api.token = null;
|
|
1507
|
-
this.api.request({ url: "/api/auth/logout", method: "DELETE" });
|
|
1508
|
-
this.user = null;
|
|
1509
|
-
}
|
|
1510
|
-
/**
|
|
1511
|
-
* Create a new user with login
|
|
1512
|
-
* @param {Partial<User> & {password: string}} user User data with password
|
|
1513
|
-
* @return {Promise<User>} Registered user data
|
|
1514
|
-
*/
|
|
1515
|
-
async register(user) {
|
|
1516
|
-
var _a;
|
|
1517
|
-
if (!user.username || !user.password) throw new Error("Cannot register user, missing username or password");
|
|
1518
|
-
const u = await this.api.request({ url: "/api/auth/register", body: { ...user } });
|
|
1519
|
-
if ((_a = u == null ? void 0 : u.image) == null ? void 0 : _a.startsWith("/")) u.image = `${this.api.url}${u.image}${!this.api.sameOrigin && this.api.token ? `?token=${this.api.token}` : ""}`;
|
|
1520
|
-
this.user = u;
|
|
1521
|
-
this.permissions = [];
|
|
1522
|
-
this.emit(PES`auth/register:u`, u);
|
|
1523
|
-
return u;
|
|
1524
|
-
}
|
|
1525
|
-
reset(emailOrPass, token) {
|
|
1526
|
-
if (!emailOrPass) throw new Error("Cannot reset password, missing email or token");
|
|
1527
|
-
return this.api.request({
|
|
1528
|
-
url: "/api/auth/reset",
|
|
1529
|
-
headers: { "Authorization": token ? `Bearer ${token}` : void 0 },
|
|
1530
|
-
body: {
|
|
1531
|
-
email: token ? void 0 : emailOrPass,
|
|
1532
|
-
password: token ? emailOrPass : void 0
|
|
1533
|
-
}
|
|
1534
|
-
}).then(() => {
|
|
1535
|
-
this.emit(PES`auth/reset:${token ? "u" : "c"}`, token || emailOrPass);
|
|
1536
|
-
});
|
|
1537
|
-
}
|
|
1538
|
-
/**
|
|
1539
|
-
* Get session information
|
|
1540
|
-
* @param {string} token Token to fetch session info for
|
|
1541
|
-
* @param {boolean} set Set as current active session
|
|
1542
|
-
* @return {Promise<{token: string, user: User, permissions: string[], custom: any} | null>} Session information
|
|
1543
|
-
*/
|
|
1544
|
-
async session(token, set = false) {
|
|
1545
|
-
if (!token) token = this.api.token;
|
|
1546
|
-
const session = await this.api.request({
|
|
1547
|
-
url: "/api/auth/session",
|
|
1548
|
-
headers: token ? { "Authorization": `Bearer ${token}` } : void 0
|
|
1549
|
-
});
|
|
1550
|
-
this.emit(PES`auth/session:r`, session);
|
|
1551
|
-
if (set) {
|
|
1552
|
-
this.api.token = token;
|
|
1553
|
-
if (session == null ? void 0 : session.user) session.user.image = `${this.api.url}${session.user.image}${!this.api.sameOrigin && this.api.token ? `?token=${this.api.token}` : ""}`;
|
|
1554
|
-
this.user = (session == null ? void 0 : session.user) || null;
|
|
1555
|
-
this.permissions = (session == null ? void 0 : session.permissions) || [];
|
|
1556
|
-
if (session) this.emit(PES`auth/login:c`, session.user);
|
|
1557
|
-
}
|
|
1558
|
-
return session;
|
|
1559
|
-
}
|
|
1560
|
-
/**
|
|
1561
|
-
* Update password for user
|
|
1562
|
-
* @param {string} username User to reset
|
|
1563
|
-
* @param {string} password New user password
|
|
1564
|
-
* @param {string} oldPassword Old password for validation
|
|
1565
|
-
* @return {Promise<void>} Resolves once complete
|
|
1566
|
-
*/
|
|
1567
|
-
async updatePassword(username, password, oldPassword) {
|
|
1568
|
-
if (!username || !password) throw new Error("Cannot update password, missing username or password");
|
|
1569
|
-
return this.api.request({
|
|
1570
|
-
url: "/api/auth/password",
|
|
1571
|
-
body: { username, password, oldPassword }
|
|
1572
|
-
}).then((resp) => {
|
|
1573
|
-
this.emit(PES`auth/reset:u`, resp == null ? void 0 : resp.token);
|
|
1574
|
-
if (resp == null ? void 0 : resp.token) this.api.token = resp.token;
|
|
1575
|
-
});
|
|
1576
|
-
}
|
|
1577
|
-
}
|
|
1578
|
-
class Client extends PathEventEmitter {
|
|
1579
|
-
constructor(api, settings) {
|
|
1580
|
-
super();
|
|
1581
|
-
__publicField(this, "_notifications", false);
|
|
1582
|
-
__publicField(this, "_platform");
|
|
1583
|
-
__publicField(this, "_pwa");
|
|
1584
|
-
this.api = api;
|
|
1585
|
-
this.settings = settings;
|
|
1586
|
-
this.pushSubscription.then((resp) => this.notifications = !!resp);
|
|
1587
|
-
}
|
|
1588
|
-
/** Check if iframed */
|
|
1589
|
-
get iframe() {
|
|
1590
|
-
return (parent == null ? void 0 : parent.location) != location;
|
|
1591
|
-
}
|
|
1592
|
-
/** Check if mobile device */
|
|
1593
|
-
get mobile() {
|
|
1594
|
-
return ["android", "ios"].includes(this.platform);
|
|
1595
|
-
}
|
|
1596
|
-
/** Are notifications enabled */
|
|
1597
|
-
get notifications() {
|
|
1598
|
-
return this._notifications;
|
|
1599
|
-
}
|
|
1600
|
-
set notifications(enabled) {
|
|
1601
|
-
this._notifications = enabled;
|
|
1602
|
-
this.emit(PES`client/notifications:${enabled ? "c" : "d"}`, enabled);
|
|
1603
|
-
}
|
|
1604
|
-
/** Get the current platform type */
|
|
1605
|
-
get platform() {
|
|
1606
|
-
if (!this._platform) {
|
|
1607
|
-
const userAgent = navigator.userAgent || navigator.vendor;
|
|
1608
|
-
if (/windows/i.test(userAgent)) this._platform = "windows";
|
|
1609
|
-
else if (/android/i.test(userAgent)) this._platform = "android";
|
|
1610
|
-
else if (/iPad|iPhone|iPod/.test(userAgent)) this._platform = "ios";
|
|
1611
|
-
else if (/macintosh|mac os x/i.test(userAgent)) this._platform = "mac";
|
|
1612
|
-
else if (/linux/i.test(userAgent)) this._platform = "linux";
|
|
1613
|
-
else this._platform = "unknown";
|
|
1614
|
-
}
|
|
1615
|
-
return this._platform;
|
|
1616
|
-
}
|
|
1617
|
-
/** Get Push Subscription info */
|
|
1618
|
-
get pushSubscription() {
|
|
1619
|
-
var _a;
|
|
1620
|
-
if (!((_a = navigator.serviceWorker) == null ? void 0 : _a.controller)) return Promise.resolve(null);
|
|
1621
|
-
return navigator.serviceWorker.ready.then((sw) => {
|
|
1622
|
-
var _a2;
|
|
1623
|
-
return (_a2 = sw == null ? void 0 : sw.pushManager) == null ? void 0 : _a2.getSubscription();
|
|
1624
|
-
});
|
|
1625
|
-
}
|
|
1626
|
-
/** Check if running as a PWA */
|
|
1627
|
-
get pwa() {
|
|
1628
|
-
if (this._pwa == null)
|
|
1629
|
-
this._pwa = matchMedia("(display-mode: standalone)").matches || (navigator == null ? void 0 : navigator.standalone) || document.referrer.includes("android-app://");
|
|
1630
|
-
return this._pwa;
|
|
1631
|
-
}
|
|
1632
|
-
/**
|
|
1633
|
-
* Inject the client theme settings, meta tags & PWA prompt
|
|
1634
|
-
* @param opts Injection options: reload - use cached settings or reload; pwa - disabled auto pwa prompt
|
|
1635
|
-
* @return {Promise<void>} Resolves on completion
|
|
1636
|
-
*/
|
|
1637
|
-
async init(opts = {}) {
|
|
1638
|
-
var _a, _b, _c, _d, _e, _f, _g, _h, _i;
|
|
1639
|
-
opts = {
|
|
1640
|
-
reload: void 0,
|
|
1641
|
-
pwa: true,
|
|
1642
|
-
...opts
|
|
1643
|
-
};
|
|
1644
|
-
const meta = (key, name, value) => {
|
|
1645
|
-
const exists = document.querySelector(`meta[${key}="${name}"]`);
|
|
1646
|
-
if (value === void 0 || exists) return exists;
|
|
1647
|
-
const meta2 = document.createElement("meta");
|
|
1648
|
-
meta2.setAttribute(key, name);
|
|
1649
|
-
meta2.content = value;
|
|
1650
|
-
document.head.append(meta2);
|
|
1651
|
-
};
|
|
1652
|
-
if (!this.settings.cache.keys().length) opts.reload = true;
|
|
1653
|
-
let settings = await (opts.reload ? this.settings.all(false, true) : this.settings.cache);
|
|
1654
|
-
if (opts.reload == null) this.settings.all(false, true).then(() => this.init({ reload: false }));
|
|
1655
|
-
if (settings["title"]) document.querySelectorAll(".momentum-title").forEach((el) => el.innerText = el.innerText.includes("|") ? `${el.innerText.split("|")[0].trim()} | ${settings["title"]}` : settings["title"]);
|
|
1656
|
-
if (settings["description"]) document.querySelectorAll(".momentum-description").forEach((el) => el.innerText = settings["description"]);
|
|
1657
|
-
if (settings["version"]) document.querySelectorAll(".momentum-version").forEach((el) => el.innerText = settings["version"]);
|
|
1658
|
-
if (settings["logo"]) document.querySelectorAll(".momentum-logo").forEach((el) => el.src = settings["logo"]);
|
|
1659
|
-
meta("name", "description", settings["description"]);
|
|
1660
|
-
meta("itemprop", "name", settings["title"]);
|
|
1661
|
-
meta("itemprop", "description", settings["description"]);
|
|
1662
|
-
meta("itemprop", "image", `${settings["public_url"]}/favicon.png`);
|
|
1663
|
-
meta("property", "og:type", "website");
|
|
1664
|
-
meta("property", "og:url", settings["public_url"]);
|
|
1665
|
-
meta("property", "og:image", `${settings["public_url"]}/favicon.png`);
|
|
1666
|
-
meta("property", "og:title", settings["title"]);
|
|
1667
|
-
meta("property", "og:description", settings["description"]);
|
|
1668
|
-
meta("name", "twitter:card", "summary_large_image");
|
|
1669
|
-
meta("name", "twitter:title", settings["title"]);
|
|
1670
|
-
meta("name", "twitter:description", settings["description"]);
|
|
1671
|
-
meta("name", "twitter:image", `${settings["public_url"]}/favicon.png`);
|
|
1672
|
-
if (settings["pwa"]) {
|
|
1673
|
-
meta("name", "mobile-web-app-capable", "yes");
|
|
1674
|
-
meta("name", "apple-mobile-web-app-status-bar-style", "default");
|
|
1675
|
-
meta("name", "apple-mobile-web-app-title", settings["title"]);
|
|
1676
|
-
meta("name", "apple-touch-icon", `${settings["public_url"]}/favicon.png`);
|
|
1677
|
-
meta("name", "apple-touch-startup-image", `${settings["public_url"]}/favicon.png`);
|
|
1678
|
-
if (!document.querySelector('link[rel="manifest"]')) {
|
|
1679
|
-
const link = document.createElement("link");
|
|
1680
|
-
link.setAttribute("rel", "manifest");
|
|
1681
|
-
link.setAttribute("href", this.settings.api.url + "/manifest.json");
|
|
1682
|
-
document.head.append(link);
|
|
1683
|
-
}
|
|
1684
|
-
if (opts.pwa && !this.iframe && !this.pwa && this.mobile) setTimeout(() => {
|
|
1685
|
-
const dismissed = !!localStorage.getItem("momentum:install-prompt");
|
|
1686
|
-
if (!dismissed) this.pwaPrompt();
|
|
1687
|
-
}, 6e4);
|
|
1688
|
-
}
|
|
1689
|
-
meta("name", "theme-color", (_a = settings["theme"]) == null ? void 0 : _a.background);
|
|
1690
|
-
document.body.classList.add(((_b = settings["theme"]) == null ? void 0 : _b.darkMode) ? "theme-dark" : "theme-light");
|
|
1691
|
-
document.body.classList.remove(((_c = settings["theme"]) == null ? void 0 : _c.darkMode) ? "theme-light" : "theme-dark");
|
|
1692
|
-
const style = document.querySelector("style.momentum-theme") || document.createElement("style");
|
|
1693
|
-
style.classList.add("momentum-theme");
|
|
1694
|
-
style.innerHTML = `
|
|
1695
|
-
:root {
|
|
1696
|
-
--theme-backdrop: ${(_d = settings["theme"]) == null ? void 0 : _d.background} !important;
|
|
1697
|
-
--theme-primary: ${(_e = settings["theme"]) == null ? void 0 : _e.primary} !important;
|
|
1698
|
-
--theme-accent: ${(_f = settings["theme"]) == null ? void 0 : _f.accent} !important;
|
|
1699
|
-
--theme-contrast: ${blackOrWhite((_g = settings["theme"]) == null ? void 0 : _g.background)} !important;
|
|
1700
|
-
--theme-primary-contrast: ${blackOrWhite((_h = settings["theme"]) == null ? void 0 : _h.primary)} !important;
|
|
1701
|
-
--theme-accent-contrast: ${blackOrWhite((_i = settings["theme"]) == null ? void 0 : _i.accent)} !important;
|
|
1702
|
-
}
|
|
1703
|
-
`;
|
|
1704
|
-
if (!style.parentElement) document.head.append(style);
|
|
1705
|
-
this.emit(PES`client/inject:c`, this.platform);
|
|
1706
|
-
}
|
|
1707
|
-
/**
|
|
1708
|
-
* Create UI prompt for user to install as PWA
|
|
1709
|
-
* @param platform Platform prompt, leave blank to auto-detect
|
|
1710
|
-
*/
|
|
1711
|
-
pwaPrompt(platform) {
|
|
1712
|
-
if (document.querySelector(".momentum-pwa-prompt")) return;
|
|
1713
|
-
const url = this.settings.api.url;
|
|
1714
|
-
const settings = this.settings.cache;
|
|
1715
|
-
const android = (platform || this.platform) == "android";
|
|
1716
|
-
let style = document.querySelector("style.momentum-pwa");
|
|
1717
|
-
if (!style) {
|
|
1718
|
-
style = document.createElement("style");
|
|
1719
|
-
style.innerHTML = `
|
|
1720
|
-
.momentum-pwa-prompt-backdrop {
|
|
1721
|
-
position: fixed;
|
|
1722
|
-
display: relative;
|
|
1723
|
-
left: 0;
|
|
1724
|
-
top: 0;
|
|
1725
|
-
right: 0;
|
|
1726
|
-
bottom: 0;
|
|
1727
|
-
background: rgba(0,0,0,.5);
|
|
1728
|
-
z-index: 9999;
|
|
1729
|
-
animation: fadeIn 0.5s ease-in-out forwards;
|
|
1730
|
-
opacity: 0;
|
|
1731
|
-
}
|
|
1732
|
-
.momentum-pwa-prompt-backdrop.exit {
|
|
1733
|
-
animation: fadeOut 0.5s ease-in-out forwards !important;
|
|
1734
|
-
}
|
|
1735
|
-
.momentum-pwa-prompt {
|
|
1736
|
-
position: fixed;
|
|
1737
|
-
background: #fff;
|
|
1738
|
-
color: black;
|
|
1739
|
-
bottom: 0;
|
|
1740
|
-
left: 50%;
|
|
1741
|
-
width: min(100vw, 450px);
|
|
1742
|
-
transform: translate(-50%, 0);
|
|
1743
|
-
animation: slideUp 0.5s ease-in-out forwards;
|
|
1744
|
-
}
|
|
1745
|
-
.momentum-pwa-prompt.exit {
|
|
1746
|
-
animation: slideDown 0.5s ease-in-out forwards !important;
|
|
1747
|
-
}
|
|
1748
|
-
.momentum-pwa-prompt img {
|
|
1749
|
-
width: 18px;
|
|
1750
|
-
height: 18px;
|
|
1751
|
-
}
|
|
1752
|
-
.momentum-pwa-prompt h1 {
|
|
1753
|
-
font-size: 1.25rem;
|
|
1754
|
-
font-weight: bold;
|
|
1755
|
-
}
|
|
1756
|
-
.momentum-pwa-prompt-close {
|
|
1757
|
-
position: absolute;
|
|
1758
|
-
right: 5px;
|
|
1759
|
-
top: 10px;
|
|
1760
|
-
background: transparent;
|
|
1761
|
-
border: none;
|
|
1762
|
-
cursor: pointer;
|
|
1763
|
-
}
|
|
1764
|
-
|
|
1765
|
-
@keyframes fadeIn {
|
|
1766
|
-
from { opacity: 0; }
|
|
1767
|
-
to { opacity: 1; }
|
|
1768
|
-
}
|
|
1769
|
-
@keyframes fadeOut {
|
|
1770
|
-
from { opacity: 1; }
|
|
1771
|
-
to { opacity: 0; }
|
|
1772
|
-
}
|
|
1773
|
-
|
|
1774
|
-
@keyframes slideUp {
|
|
1775
|
-
from { transform: translate(-50%, 100%); }
|
|
1776
|
-
to { transform: translate(-50%, 0); }
|
|
1777
|
-
}
|
|
1778
|
-
@keyframes slideDown {
|
|
1779
|
-
from { transform: translate(-50%, 0); }
|
|
1780
|
-
to { transform: translate(-50%, 100%); }
|
|
1781
|
-
}
|
|
1782
|
-
`;
|
|
1783
|
-
document.head.append(style);
|
|
1784
|
-
}
|
|
1785
|
-
const backdrop = document.createElement("div");
|
|
1786
|
-
backdrop.classList.add("momentum-pwa-prompt-backdrop");
|
|
1787
|
-
const prompt = document.createElement("div");
|
|
1788
|
-
prompt.classList.add("momentum-pwa-prompt");
|
|
1789
|
-
prompt.innerHTML = `
|
|
1790
|
-
<div style="display: flex; padding: 1rem; align-items: center">
|
|
1791
|
-
<img src="${settings.logo.startsWith("/") ? url : ""}${settings.logo}" alt="Logo" style="height: 40px; width: auto; margin-right: .5rem;" />
|
|
1792
|
-
<h1 style="margin: 0">Install ${settings.title}</h1>
|
|
1793
|
-
</div>
|
|
1794
|
-
<div style="display: flex; flex-direction: column; align-items: center">
|
|
1795
|
-
<div style="border-top: 2px solid #00000020; border-bottom: 2px solid #00000020; padding: 0 1rem">
|
|
1796
|
-
<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>
|
|
1797
|
-
</div>
|
|
1798
|
-
<table style="margin: 1.5rem 0">
|
|
1799
|
-
<tr>
|
|
1800
|
-
<td style="width: 50px; text-align: center">
|
|
1801
|
-
${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>'}
|
|
1802
|
-
</td>
|
|
1803
|
-
<td>
|
|
1804
|
-
<p style="margin: 1rem 0">1) ${android ? "Open the dropdown menu" : 'Press the "Share" button'}</p>
|
|
1805
|
-
</td>
|
|
1806
|
-
</tr>
|
|
1807
|
-
<tr>
|
|
1808
|
-
<td style="width: 50px; text-align: center">
|
|
1809
|
-
${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>'}
|
|
1810
|
-
</td>
|
|
1811
|
-
<td>
|
|
1812
|
-
<p style="margin: 1rem 0">2) Press "Add to Home Screen"</p>
|
|
1813
|
-
</td>
|
|
1814
|
-
</tr>
|
|
1815
|
-
</table>
|
|
1816
|
-
</div>`;
|
|
1817
|
-
const close = document.createElement("button");
|
|
1818
|
-
close.classList.add("momentum-pwa-prompt-close");
|
|
1819
|
-
close.innerText = "x";
|
|
1820
|
-
close.onclick = () => {
|
|
1821
|
-
prompt.classList.add("exit");
|
|
1822
|
-
backdrop.classList.add("exit");
|
|
1823
|
-
localStorage.setItem("momentum:install-prompt", "dismissed");
|
|
1824
|
-
setTimeout(() => {
|
|
1825
|
-
prompt.remove();
|
|
1826
|
-
backdrop.remove();
|
|
1827
|
-
this.emit(PES`client/pwa:d`, platform);
|
|
1828
|
-
}, 500);
|
|
1829
|
-
};
|
|
1830
|
-
prompt.append(close);
|
|
1831
|
-
backdrop.append(prompt);
|
|
1832
|
-
document.body.append(backdrop);
|
|
1833
|
-
this.emit(PES`client/pwa:c`, platform);
|
|
1834
|
-
}
|
|
1835
|
-
/**
|
|
1836
|
-
* Enable device notifications
|
|
1837
|
-
* @return {Promise<null>} Resolves on success
|
|
1838
|
-
*/
|
|
1839
|
-
async enableNotifications() {
|
|
1840
|
-
const granted = await Notification.requestPermission();
|
|
1841
|
-
if (!granted) return null;
|
|
1842
|
-
const sw = await navigator.serviceWorker.ready;
|
|
1843
|
-
const subscription = (await sw.pushManager.subscribe({
|
|
1844
|
-
userVisibleOnly: true,
|
|
1845
|
-
applicationServerKey: this.settings.cache["push_public_key"]
|
|
1846
|
-
})).toJSON();
|
|
1847
|
-
return this.api.request({ url: "/api/notifications", body: subscription }).then(() => this.notifications = true);
|
|
1848
|
-
}
|
|
1849
|
-
/**
|
|
1850
|
-
* Disable device notifications
|
|
1851
|
-
* @return {Promise<void>} Resolves on success
|
|
1852
|
-
*/
|
|
1853
|
-
async disableNotifications() {
|
|
1854
|
-
var _a;
|
|
1855
|
-
const subscription = await this.pushSubscription;
|
|
1856
|
-
subscription == null ? void 0 : subscription.unsubscribe();
|
|
1857
|
-
return this.api.request({ url: "/api/notifications", method: "DELETE", body: {
|
|
1858
|
-
p256dh: (_a = subscription == null ? void 0 : subscription.toJSON().keys) == null ? void 0 : _a["p256dh"]
|
|
1859
|
-
} }).then(() => this.notifications = false);
|
|
1860
|
-
}
|
|
1861
|
-
}
|
|
1862
|
-
class Schemas extends PathEventEmitter {
|
|
1863
|
-
constructor(api) {
|
|
1864
|
-
super();
|
|
1865
|
-
this.api = api;
|
|
1866
|
-
}
|
|
1867
|
-
delete(path) {
|
|
1868
|
-
if (!path) throw new Error("Cannot delete schema, missing collection path");
|
|
1869
|
-
return this.api.request({ url: `/api/` + PES`schema/${path}`, method: "DELETE" }).then(() => this.emit(PES`schema/${path}:d`, path));
|
|
1870
|
-
}
|
|
1871
|
-
read(pathOrTree) {
|
|
1872
|
-
return this.api.request({ url: "/api/" + PES`schema/${typeof pathOrTree == "string" ? pathOrTree : ""}` + (pathOrTree === true ? `?tree=${pathOrTree}` : "") }).then((resp) => {
|
|
1873
|
-
this.emit(PES`schema/${typeof pathOrTree == "string" ? pathOrTree : ""}:r`, resp);
|
|
1874
|
-
return resp;
|
|
1875
|
-
});
|
|
1876
|
-
}
|
|
1877
|
-
update(schema) {
|
|
1878
|
-
if (!schema.path) throw new Error("Cannot update schema, missing collection path");
|
|
1879
|
-
return this.api.request({ url: "/api/" + PES`schema/${schema.path}`, body: schema }).then((resp) => {
|
|
1880
|
-
this.emit(PES`schema/${schema.path}:${schema._id ? "u" : "c"}`, resp);
|
|
1881
|
-
return resp;
|
|
1882
|
-
});
|
|
1883
|
-
}
|
|
1884
|
-
}
|
|
1885
|
-
class Data extends PathEventEmitter {
|
|
1886
|
-
constructor(api) {
|
|
1887
|
-
super();
|
|
1888
|
-
__publicField(this, "api");
|
|
1889
|
-
__publicField(this, "schema");
|
|
1890
|
-
this.api = typeof api == "string" ? new Api(api) : api;
|
|
1891
|
-
this.schema = new Schemas(this.api);
|
|
1892
|
-
}
|
|
1893
|
-
create(collection, document2) {
|
|
1894
|
-
if (!collection || !document2) throw new Error("Cannot create document, missing collection or document");
|
|
1895
|
-
return this.api.request({
|
|
1896
|
-
url: `/api/` + PES`data/${collection}`,
|
|
1897
|
-
method: "POST",
|
|
1898
|
-
body: document2
|
|
1899
|
-
}).then((resp) => {
|
|
1900
|
-
this.emit(PES`data/${collection}:c`, resp);
|
|
1901
|
-
return resp;
|
|
1902
|
-
});
|
|
1903
|
-
}
|
|
1904
|
-
delete(collection, id) {
|
|
1905
|
-
if (!collection || !id) throw new Error("Cannot delete document, missing collection or ID");
|
|
1906
|
-
return this.api.request({
|
|
1907
|
-
url: `/api/` + PES`data/${collection}/${id}`,
|
|
1908
|
-
method: "DELETE"
|
|
1909
|
-
}).then(() => this.emit(PES`data/${collection}/${id}:d`, id));
|
|
1910
|
-
}
|
|
1911
|
-
read(collection, id) {
|
|
1912
|
-
if (!collection) throw new Error("Cannot read documents, missing collection");
|
|
1913
|
-
return this.api.request({ url: `/api/` + PES`data/${collection}/${id}` }).then((resp) => {
|
|
1914
|
-
this.emit(PES`data/${collection}/${id}:r`, collection, resp);
|
|
1915
|
-
return resp;
|
|
1916
|
-
});
|
|
1917
|
-
}
|
|
1918
|
-
update(collection, document2, append) {
|
|
1919
|
-
if (!collection || !document2) throw new Error("Cannot update document, missing collection or document");
|
|
1920
|
-
return this.api.request({
|
|
1921
|
-
url: `/api/` + PES`data/${collection}/${document2._id}`,
|
|
1922
|
-
method: append ? "PATCH" : "PUT",
|
|
1923
|
-
body: document2
|
|
1924
|
-
}).then((resp) => {
|
|
1925
|
-
this.emit(PES`data/${collection}/${document2._id}:u`, resp);
|
|
1926
|
-
return resp;
|
|
1927
|
-
});
|
|
1928
|
-
}
|
|
1929
|
-
raw(collection, query) {
|
|
1930
|
-
if (!collection || !query) throw new Error("Cannot execute raw query, missing collection or query");
|
|
1931
|
-
const mode = query.operand.startsWith("find") ? "r" : query.operand == "insert" ? "c" : query.operand.startsWith("delete") ? "d" : "u";
|
|
1932
|
-
return this.api.request({ url: `/api/` + PES`data/${collection}` + "?raw", body: query }).then((resp) => {
|
|
1933
|
-
this.emit(PES`data/${collection}:${mode}`, resp);
|
|
1934
|
-
return resp;
|
|
1935
|
-
});
|
|
1936
|
-
}
|
|
1937
|
-
}
|
|
1938
|
-
class Discounts extends PathEventEmitter {
|
|
1939
|
-
constructor(api) {
|
|
1940
|
-
super();
|
|
1941
|
-
this.api = api;
|
|
1942
|
-
}
|
|
1943
|
-
all() {
|
|
1944
|
-
return this.api.request({
|
|
1945
|
-
url: `/api/payments/discounts`,
|
|
1946
|
-
method: "GET"
|
|
1947
|
-
}).then((resp) => {
|
|
1948
|
-
this.emit(`discounts:r`, resp);
|
|
1949
|
-
return resp;
|
|
1950
|
-
});
|
|
1951
|
-
}
|
|
1952
|
-
create(discount) {
|
|
1953
|
-
return this.api.request({
|
|
1954
|
-
url: "/api/payments/discounts",
|
|
1955
|
-
method: "POST",
|
|
1956
|
-
body: discount
|
|
1957
|
-
}).then((resp) => {
|
|
1958
|
-
this.emit(`discounts/${resp.code}:c`, resp);
|
|
1959
|
-
return resp;
|
|
1960
|
-
});
|
|
1961
|
-
}
|
|
1962
|
-
delete(discount) {
|
|
1963
|
-
const code = typeof discount == "string" ? discount : discount.code;
|
|
1964
|
-
return this.api.request({
|
|
1965
|
-
url: `/api/payments/discounts/${code}`,
|
|
1966
|
-
method: "DELETE"
|
|
1967
|
-
}).then(() => {
|
|
1968
|
-
this.emit(`discounts/${code}:d`, code);
|
|
1969
|
-
});
|
|
1970
|
-
}
|
|
1971
|
-
read(code) {
|
|
1972
|
-
return this.api.request({
|
|
1973
|
-
url: `/api/payments/discounts/${code}`,
|
|
1974
|
-
method: "GET"
|
|
1975
|
-
}).then((resp) => {
|
|
1976
|
-
this.emit(`discounts/${code}:r`, resp);
|
|
1977
|
-
return resp;
|
|
1978
|
-
});
|
|
1979
|
-
}
|
|
1980
|
-
update(discount) {
|
|
1981
|
-
return this.api.request({
|
|
1982
|
-
url: "/api/payments/discounts",
|
|
1983
|
-
method: "PATCH",
|
|
1984
|
-
body: discount
|
|
1985
|
-
}).then((resp) => {
|
|
1986
|
-
this.emit(`discounts/${resp.code}:u`, resp);
|
|
1987
|
-
return resp;
|
|
1988
|
-
});
|
|
1989
|
-
}
|
|
1990
|
-
}
|
|
1991
|
-
class Email extends PathEventEmitter {
|
|
1992
|
-
constructor(api) {
|
|
1993
|
-
super();
|
|
1994
|
-
__publicField(this, "api");
|
|
1995
|
-
this.api = typeof api == "string" ? new Api(api) : api;
|
|
1996
|
-
}
|
|
1997
|
-
/**
|
|
1998
|
-
* Send Email
|
|
1999
|
-
* @param {Mail} email Email to send
|
|
2000
|
-
* @return {Promise<any>} Response
|
|
2001
|
-
*/
|
|
2002
|
-
send(email) {
|
|
2003
|
-
if (!email.to && !email.bcc || !email.body) throw new Error("Cannot send email, missing address or body");
|
|
2004
|
-
return this.api.request({ url: "/api/email", body: email }).then((response) => {
|
|
2005
|
-
var _a;
|
|
2006
|
-
this.emit(PES`email/${(_a = email.body) == null ? void 0 : _a.template}:c`, { email, response });
|
|
2007
|
-
return response;
|
|
2008
|
-
});
|
|
2009
|
-
}
|
|
2010
|
-
}
|
|
2011
|
-
class Forms extends PathEventEmitter {
|
|
2012
|
-
constructor(api) {
|
|
2013
|
-
super();
|
|
2014
|
-
__publicField(this, "api");
|
|
2015
|
-
__publicField(this, "cache", new Cache("_id"));
|
|
2016
|
-
this.api = typeof api == "string" ? new Api(api) : api;
|
|
2017
|
-
}
|
|
2018
|
-
all(pathOrTree) {
|
|
2019
|
-
return this.api.request({ url: "/api/" + PES`forms/${typeof pathOrTree == "string" ? pathOrTree : ""}` + (pathOrTree === true ? `?tree=${pathOrTree}` : "") }).then((resp) => {
|
|
2020
|
-
this.emit(PES`forms/${typeof pathOrTree == "string" ? pathOrTree : ""}:r`, resp);
|
|
2021
|
-
return resp;
|
|
2022
|
-
});
|
|
2023
|
-
}
|
|
2024
|
-
delete(key) {
|
|
2025
|
-
if (!key) throw new Error("Cannot delete form, missing path");
|
|
2026
|
-
return this.api.request({ url: `/api/` + PES`forms/${key}`, method: "DELETE" }).then(() => {
|
|
2027
|
-
this.cache.delete(key);
|
|
2028
|
-
this.emit(PES`forms/${key}:d`, key);
|
|
2029
|
-
});
|
|
2030
|
-
}
|
|
2031
|
-
read(path, reload = false) {
|
|
2032
|
-
if (!path) throw new Error("Cannot read form, missing path");
|
|
2033
|
-
if (!reload && this.cache.get(path)) return Promise.resolve(this.cache.get(path));
|
|
2034
|
-
return this.api.request({ url: `/api/` + PES`forms/${path}` }).then((form) => {
|
|
2035
|
-
if (form) this.cache.add(form);
|
|
2036
|
-
this.emit(PES`forms/${path}:r`, form);
|
|
2037
|
-
return form;
|
|
2038
|
-
});
|
|
2039
|
-
}
|
|
2040
|
-
update(form) {
|
|
2041
|
-
if (!form.path) throw new Error("Cannot update form, missing path");
|
|
2042
|
-
return this.api.request({ url: `/api/` + PES`forms/${form.path}`, body: form }).then((f) => {
|
|
2043
|
-
if (f) this.cache.add(f);
|
|
2044
|
-
this.emit(`/api/` + PES`settings/${form.path}:${form._id ? "u" : "c"}`, f);
|
|
2045
|
-
return f;
|
|
2046
|
-
});
|
|
2047
|
-
}
|
|
2048
|
-
}
|
|
2049
|
-
class Groups extends PathEventEmitter {
|
|
2050
|
-
constructor(api) {
|
|
2051
|
-
super();
|
|
2052
|
-
__publicField(this, "api");
|
|
2053
|
-
__publicField(this, "cache", new Cache("name"));
|
|
2054
|
-
this.api = typeof api == "string" ? new Api(api) : api;
|
|
2055
|
-
}
|
|
2056
|
-
async all(reload) {
|
|
2057
|
-
if (!reload && this.cache.complete) return this.cache.all();
|
|
2058
|
-
return this.api.request({ url: `/api/` + PES`groups` }).then((resp) => {
|
|
2059
|
-
this.cache.addAll(resp);
|
|
2060
|
-
this.emit(PES`groups:r`, resp || []);
|
|
2061
|
-
return resp;
|
|
2062
|
-
});
|
|
2063
|
-
}
|
|
2064
|
-
delete(name) {
|
|
2065
|
-
if (!name) throw new Error("Cannot delete group, missing name");
|
|
2066
|
-
return this.api.request({
|
|
2067
|
-
url: `/api/` + PES`groups/${name}`,
|
|
2068
|
-
method: "DELETE"
|
|
2069
|
-
}).then(() => {
|
|
2070
|
-
this.cache.delete(name);
|
|
2071
|
-
this.emit(PES`groups/${name}:d`);
|
|
2072
|
-
});
|
|
2073
|
-
}
|
|
2074
|
-
create(group) {
|
|
2075
|
-
if (!group.name) throw new Error("Cannot create group, missing name");
|
|
2076
|
-
return this.api.request({
|
|
2077
|
-
url: `/api/` + PES`groups/${group.name}`,
|
|
2078
|
-
method: "POST",
|
|
2079
|
-
body: group
|
|
2080
|
-
}).then((resp) => {
|
|
2081
|
-
this.cache.add(resp);
|
|
2082
|
-
this.emit(PES`groups/${group.name}:c`, resp);
|
|
2083
|
-
return resp;
|
|
2084
|
-
});
|
|
2085
|
-
}
|
|
2086
|
-
async read(name, reload) {
|
|
2087
|
-
if (!name) throw new Error("Cannot read group, missing name");
|
|
2088
|
-
if (!reload && this.cache.get(name)) return this.cache.get(name);
|
|
2089
|
-
return this.api.request({ url: `/api/` + PES`groups/${name}` }).then((resp) => {
|
|
2090
|
-
this.cache.add(resp);
|
|
2091
|
-
this.emit(PES`groups/${name}:r`, resp);
|
|
2092
|
-
return resp;
|
|
2093
|
-
});
|
|
2094
|
-
}
|
|
2095
|
-
update(group) {
|
|
2096
|
-
if (!group.name) throw new Error("Cannot update group, missing name");
|
|
2097
|
-
return this.api.request({
|
|
2098
|
-
url: `/api/` + PES`groups/${group.name}`,
|
|
2099
|
-
method: "PATCH",
|
|
2100
|
-
body: group
|
|
2101
|
-
}).then((resp) => {
|
|
2102
|
-
this.cache.add(resp);
|
|
2103
|
-
this.emit(PES`groups/${group.name}:u`, resp);
|
|
2104
|
-
return resp;
|
|
2105
|
-
});
|
|
2106
|
-
}
|
|
2107
|
-
}
|
|
2108
|
-
class Logger extends PathEventEmitter {
|
|
2109
|
-
constructor(api, channel, logLevel) {
|
|
2110
|
-
super();
|
|
2111
|
-
__publicField(this, "api");
|
|
2112
|
-
__publicField(this, "console", {
|
|
2113
|
-
debug: console.debug,
|
|
2114
|
-
log: console.log,
|
|
2115
|
-
info: console.info,
|
|
2116
|
-
warn: console.warn,
|
|
2117
|
-
error: console.error
|
|
2118
|
-
});
|
|
2119
|
-
this.channel = channel;
|
|
2120
|
-
if (channel.toLowerCase() == "server") throw new Error('"Server" namespace is reserved');
|
|
2121
|
-
this.api = typeof api == "string" ? new Api(api) : api;
|
|
2122
|
-
if (logLevel != null && logLevel && logLevel != "NONE") {
|
|
2123
|
-
if (LOG_LEVEL[logLevel] >= 0) {
|
|
2124
|
-
console.error = (...args) => {
|
|
2125
|
-
this.console.error(...args);
|
|
2126
|
-
this.error(args);
|
|
2127
|
-
};
|
|
2128
|
-
window.addEventListener("unhandledrejection", async (event) => {
|
|
2129
|
-
var _a, _b, _c, _d;
|
|
2130
|
-
let log = ((_a = event.reason) == null ? void 0 : _a.stack) || event.reason;
|
|
2131
|
-
if ((_b = event.reason) == null ? void 0 : _b.url)
|
|
2132
|
-
log = `${event.reason.method} ${event.reason.url} -> ${event.reason.code}
|
|
2133
|
-
|
|
2134
|
-
${log}`;
|
|
2135
|
-
((_c = event.reason) == null ? void 0 : _c.code) == null || ((_d = event.reason) == null ? void 0 : _d.code) >= 500 ? this.error(log) : this.warn(log);
|
|
2136
|
-
});
|
|
2137
|
-
}
|
|
2138
|
-
if (LOG_LEVEL[logLevel] >= 1) {
|
|
2139
|
-
console.warn = (...args) => {
|
|
2140
|
-
this.console.warn(...args);
|
|
2141
|
-
this.warn(args);
|
|
2142
|
-
};
|
|
2143
|
-
}
|
|
2144
|
-
if (LOG_LEVEL[logLevel] >= 2) {
|
|
2145
|
-
console.info = (...args) => {
|
|
2146
|
-
this.console.info(...args);
|
|
2147
|
-
this.info(args);
|
|
2148
|
-
};
|
|
2149
|
-
}
|
|
2150
|
-
if (LOG_LEVEL[logLevel] >= 3) {
|
|
2151
|
-
console.log = (...args) => {
|
|
2152
|
-
this.console.log(...args);
|
|
2153
|
-
this.log(args);
|
|
2154
|
-
};
|
|
2155
|
-
}
|
|
2156
|
-
if (LOG_LEVEL[logLevel] >= 4) {
|
|
2157
|
-
console.debug = (...args) => {
|
|
2158
|
-
this.console.debug(...args);
|
|
2159
|
-
this.debug(args);
|
|
2160
|
-
};
|
|
2161
|
-
}
|
|
2162
|
-
}
|
|
2163
|
-
}
|
|
2164
|
-
buildLog(level, log) {
|
|
2165
|
-
return {
|
|
2166
|
-
time: (/* @__PURE__ */ new Date()).getTime(),
|
|
2167
|
-
level,
|
|
2168
|
-
log,
|
|
2169
|
-
ctx: {
|
|
2170
|
-
cores: (navigator == null ? void 0 : navigator.hardwareConcurrency) ?? null,
|
|
2171
|
-
mem: (navigator == null ? void 0 : navigator.deviceMemory) ?? null,
|
|
2172
|
-
res: [window.innerWidth, window.innerHeight],
|
|
2173
|
-
url: location.href
|
|
2174
|
-
}
|
|
2175
|
-
};
|
|
2176
|
-
}
|
|
2177
|
-
create(log, channel = this.channel) {
|
|
2178
|
-
if (channel.toLowerCase() == "server") throw new Error('"Server" namespace is reserved');
|
|
2179
|
-
return this.api.request({ url: `/api/` + PES`logs/${channel}`, body: log }).then(() => this.emit(PES`logs/${channel}:c`, log)).catch(() => {
|
|
2180
|
-
});
|
|
2181
|
-
}
|
|
2182
|
-
channels() {
|
|
2183
|
-
return this.api.request({ url: "/api/" + PES`logs/channels` });
|
|
2184
|
-
}
|
|
2185
|
-
delete(channel = this.channel) {
|
|
2186
|
-
return this.api.request({ url: `/api/` + PES`logs/${channel}`, method: "DELETE" }).then(() => this.emit(PES`logs/${channel}:d`));
|
|
2187
|
-
}
|
|
2188
|
-
read(channel = this.channel) {
|
|
2189
|
-
return this.api.request({ url: `/api/` + PES`logs/${channel}` }).then((logs) => {
|
|
2190
|
-
this.emit(PES`logs/${channel}:r`, logs);
|
|
2191
|
-
return logs;
|
|
2192
|
-
});
|
|
2193
|
-
}
|
|
2194
|
-
// Console =========================================================================================================
|
|
2195
|
-
debug(log, channel = this.channel) {
|
|
2196
|
-
return this.create(this.buildLog(LOG_LEVEL.DEBUG, log), channel);
|
|
2197
|
-
}
|
|
2198
|
-
log(log, channel = this.channel) {
|
|
2199
|
-
return this.create(this.buildLog(LOG_LEVEL.LOG, log), channel);
|
|
2200
|
-
}
|
|
2201
|
-
info(log, channel = this.channel) {
|
|
2202
|
-
return this.create(this.buildLog(LOG_LEVEL.INFO, log), channel);
|
|
2203
|
-
}
|
|
2204
|
-
warn(log, channel = this.channel) {
|
|
2205
|
-
return this.create(this.buildLog(LOG_LEVEL.WARN, log), channel);
|
|
2206
|
-
}
|
|
2207
|
-
error(log, channel = this.channel) {
|
|
2208
|
-
return this.create(this.buildLog(LOG_LEVEL.ERROR, log), channel);
|
|
2209
|
-
}
|
|
2210
|
-
}
|
|
2211
|
-
class Payments extends PathEventEmitter {
|
|
2212
|
-
constructor(api, opts = {}) {
|
|
2213
|
-
super();
|
|
2214
|
-
__publicField(this, "api");
|
|
2215
|
-
__publicField(this, "discounts");
|
|
2216
|
-
/** Stripe object */
|
|
2217
|
-
__publicField(this, "stripe");
|
|
2218
|
-
/** Public stripe token */
|
|
2219
|
-
__publicField(this, "token");
|
|
2220
|
-
this.opts = opts;
|
|
2221
|
-
this.api = typeof api == "string" ? new Api(api) : api;
|
|
2222
|
-
this.opts = {
|
|
2223
|
-
paymentUrl: this.api.url + "/ui/payments/checkout",
|
|
2224
|
-
...this.opts
|
|
2225
|
-
};
|
|
2226
|
-
this.discounts = new Discounts(this.api);
|
|
2227
|
-
this.relayEvents(this.discounts);
|
|
2228
|
-
}
|
|
2229
|
-
/**
|
|
2230
|
-
* Initialize stripe API
|
|
2231
|
-
* @return {Promise<any>} Returns stripe API
|
|
2232
|
-
* @private
|
|
2233
|
-
*/
|
|
2234
|
-
async init() {
|
|
2235
|
-
await new Promise((res) => {
|
|
2236
|
-
if (this.stripe) return res(window["Stripe"]);
|
|
2237
|
-
const stripeScript = document.createElement("script");
|
|
2238
|
-
stripeScript.src = "https://js.stripe.com/v3/";
|
|
2239
|
-
stripeScript.setAttribute("crossorigin", "anonymous");
|
|
2240
|
-
stripeScript.onload = () => res();
|
|
2241
|
-
document.head.appendChild(stripeScript);
|
|
2242
|
-
}).then(() => this.stripe = window["Stripe"]);
|
|
2243
|
-
return this.stripe(this.token);
|
|
2244
|
-
}
|
|
2245
|
-
/**
|
|
2246
|
-
* Create a stripe client secret to complete transaction
|
|
2247
|
-
* @param {string} id Transaction ID
|
|
2248
|
-
* @return {Promise<string>} Client secret
|
|
2249
|
-
* @private
|
|
2250
|
-
*/
|
|
2251
|
-
createSecret(id) {
|
|
2252
|
-
return this.api.request({ url: `/api/payments/init/${id || ""}`, method: "POST" }).then((resp) => resp.token);
|
|
2253
|
-
}
|
|
2254
|
-
/**
|
|
2255
|
-
* Create/Update a transaction
|
|
2256
|
-
* @param {Optional<Transaction, "subtotal" | "total">} transaction Transaction information
|
|
2257
|
-
* @return {Promise<string>} Completed translation information
|
|
2258
|
-
*/
|
|
2259
|
-
checkout(transaction) {
|
|
2260
|
-
return this.api.request({
|
|
2261
|
-
url: `/api/payments/transactions/${transaction._id || ""}`,
|
|
2262
|
-
method: transaction._id ? "PATCH" : "POST",
|
|
2263
|
-
body: transaction
|
|
2264
|
-
}).then((resp) => {
|
|
2265
|
-
this.emit(PES`payments:c`, resp);
|
|
2266
|
-
return resp;
|
|
2267
|
-
});
|
|
2268
|
-
}
|
|
2269
|
-
/**
|
|
2270
|
-
* Get translation history
|
|
2271
|
-
* @param {string} username Limit history to user
|
|
2272
|
-
* @return {Promise<Transaction[]>} List of translations
|
|
2273
|
-
*/
|
|
2274
|
-
async history(username) {
|
|
2275
|
-
return this.api.request({ url: `/api/payments/transactions/${username || ""}` }).then((resp) => {
|
|
2276
|
-
this.emit(PES`payments/${username}:r`, resp);
|
|
2277
|
-
return resp;
|
|
2278
|
-
});
|
|
2279
|
-
}
|
|
2280
|
-
/**
|
|
2281
|
-
* Send recipient transaction receipt or invoice
|
|
2282
|
-
* @param {string} id Translation ID
|
|
2283
|
-
* @return {Promise<void>} Returns once complete
|
|
2284
|
-
*/
|
|
2285
|
-
notify(id) {
|
|
2286
|
-
return this.api.request({ url: `/api/payments/notify/${id || ""}`, method: "POST" });
|
|
2287
|
-
}
|
|
2288
|
-
/**
|
|
2289
|
-
* Retrieve a list of available products
|
|
2290
|
-
* @param {string | number} id Limit to specific product
|
|
2291
|
-
* @return {Promise<any>} List of products or single product if ID is used
|
|
2292
|
-
*/
|
|
2293
|
-
products(id) {
|
|
2294
|
-
return this.api.request({ url: `/api/payments/products/${id || ""}` }).then((resp) => {
|
|
2295
|
-
this.emit(PES`products/${id ?? ""}:r`, resp);
|
|
2296
|
-
return resp;
|
|
2297
|
-
});
|
|
2298
|
-
}
|
|
2299
|
-
/**
|
|
2300
|
-
* Process payment programmatically
|
|
2301
|
-
* @param {string} id Transaction ID
|
|
2302
|
-
* @param {Card} card Credit card information
|
|
2303
|
-
* @return {Promise<any>} Stripe confirmation
|
|
2304
|
-
*/
|
|
2305
|
-
async payment(id, card) {
|
|
2306
|
-
const [client, secret] = await Promise.all([this.init(), this.createSecret(id)]);
|
|
2307
|
-
return client.confirmPayment({
|
|
2308
|
-
clientSecret: secret,
|
|
2309
|
-
confirmParams: {
|
|
2310
|
-
payment_method: {
|
|
2311
|
-
card: { ...card, details: void 0 },
|
|
2312
|
-
billing_details: card.details || {}
|
|
2313
|
-
}
|
|
2314
|
-
}
|
|
2315
|
-
});
|
|
2316
|
-
}
|
|
2317
|
-
/**
|
|
2318
|
-
* Process payment using Stripe form
|
|
2319
|
-
* @param {string} id Transaction ID
|
|
2320
|
-
* @param {string} element DOM element to inject form into
|
|
2321
|
-
* @return {Promise<() => Promise<any>>} Callback to submit form
|
|
2322
|
-
*/
|
|
2323
|
-
async paymentForm(id, element) {
|
|
2324
|
-
const [client, secret] = await Promise.all([this.init(), this.createSecret(id)]);
|
|
2325
|
-
const form = client.elements({ clientSecret: secret });
|
|
2326
|
-
form.create("payment").mount(element);
|
|
2327
|
-
return (redirect = location.href) => client.confirmPayment({
|
|
2328
|
-
elements: form,
|
|
2329
|
-
redirect: "if_required",
|
|
2330
|
-
confirmParams: { return_url: redirect + "?payment_status=success" }
|
|
2331
|
-
});
|
|
2332
|
-
}
|
|
2333
|
-
/**
|
|
2334
|
-
* Complete payment via Momentum's payment page
|
|
2335
|
-
* @param {string} id Transaction ID
|
|
2336
|
-
* @param {string} host Host origin attempting to login
|
|
2337
|
-
* @return {Promise<string>} Translation ID on success
|
|
2338
|
-
*/
|
|
2339
|
-
paymentRedirect(id, host = location.origin) {
|
|
2340
|
-
return new Promise(async (res, rej) => {
|
|
2341
|
-
var _a;
|
|
2342
|
-
let origin = new URL(this.opts.paymentUrl).origin, listener, win;
|
|
2343
|
-
window.addEventListener("message", listener = (event) => {
|
|
2344
|
-
const data = (event == null ? void 0 : event.data) || {};
|
|
2345
|
-
if (event.origin != origin || data.sender != origin) return;
|
|
2346
|
-
if (!data.response) return rej("Unknown response from payment page");
|
|
2347
|
-
window.removeEventListener("message", listener);
|
|
2348
|
-
win.close();
|
|
2349
|
-
res(data.response);
|
|
2350
|
-
});
|
|
2351
|
-
win = window.open(encodeURI(`${(_a = this.opts) == null ? void 0 : _a.paymentUrl}?token=${id}&host=${host}`), "_blank");
|
|
2352
|
-
if (!win) {
|
|
2353
|
-
window.removeEventListener("message", listener);
|
|
2354
|
-
return rej("Unable to open payment page");
|
|
2355
|
-
}
|
|
2356
|
-
});
|
|
2357
|
-
}
|
|
2358
|
-
/**
|
|
2359
|
-
* Refund a transaction
|
|
2360
|
-
* @param {string} id Transaction number to refund
|
|
2361
|
-
* @return {PromiseProgress<any>}
|
|
2362
|
-
*/
|
|
2363
|
-
refund(id) {
|
|
2364
|
-
return this.api.request({ url: `/api/payments/transactions/${id || ""}`, method: "DELETE" }).then((resp) => {
|
|
2365
|
-
this.emit(PES`products/${id ?? ""}:d`, resp);
|
|
2366
|
-
return resp;
|
|
2367
|
-
});
|
|
2368
|
-
}
|
|
2369
|
-
}
|
|
2370
|
-
class Pdf extends PathEventEmitter {
|
|
2371
|
-
constructor(api) {
|
|
2372
|
-
super();
|
|
2373
|
-
__publicField(this, "api");
|
|
2374
|
-
this.api = typeof api == "string" ? new Api(api) : api;
|
|
2375
|
-
}
|
|
2376
|
-
createPdf(body, options) {
|
|
2377
|
-
return this.api.request({ url: `/api/` + PES`pdf`, body: { ...body, options } }).then(async (resp) => {
|
|
2378
|
-
if (options == null ? void 0 : options.download) {
|
|
2379
|
-
let filename = (options == null ? void 0 : options.filename) || timestampFilename();
|
|
2380
|
-
if (!filename.endsWith(".pdf")) filename += ".pdf";
|
|
2381
|
-
downloadFile(resp, filename);
|
|
2382
|
-
}
|
|
2383
|
-
this.emit(PES`pdf:c`, resp);
|
|
2384
|
-
return resp;
|
|
2385
|
-
});
|
|
2386
|
-
}
|
|
2387
|
-
fromHtml(html, options = {}) {
|
|
2388
|
-
if (!html) throw new Error("Cannot create PDF, missing HTML");
|
|
2389
|
-
return this.createPdf({ html }, options);
|
|
2390
|
-
}
|
|
2391
|
-
fromTemplate(template, data, options = {}) {
|
|
2392
|
-
if (!template) throw new Error("Cannot create PDF, missing template");
|
|
2393
|
-
return this.createPdf({ template, data }, options);
|
|
2394
|
-
}
|
|
2395
|
-
fromUrl(url, options = {}) {
|
|
2396
|
-
if (!url) throw new Error("Cannot create PDF, missing URL");
|
|
2397
|
-
return this.createPdf({ url }, options);
|
|
2398
|
-
}
|
|
2399
|
-
}
|
|
2400
|
-
class Phone extends PathEventEmitter {
|
|
2401
|
-
constructor(api) {
|
|
2402
|
-
super();
|
|
2403
|
-
__publicField(this, "api");
|
|
2404
|
-
this.api = typeof api == "string" ? new Api(api) : api;
|
|
2405
|
-
}
|
|
2406
|
-
sms(message) {
|
|
2407
|
-
return this.api.request({ url: "/api/" + PES`phone/sms`, body: message }).then((resp) => this.emit(PES`sms/${message.to}`, resp));
|
|
2408
|
-
}
|
|
2409
|
-
voice(message) {
|
|
2410
|
-
return this.api.request({ url: "/api/" + PES`phone/voice`, body: message }).then((resp) => this.emit(PES`voice/${message.to}`, resp));
|
|
2411
|
-
}
|
|
2412
|
-
}
|
|
2413
|
-
const _Socket = class _Socket {
|
|
2414
|
-
constructor(api) {
|
|
2415
|
-
__publicField(this, "api");
|
|
2416
|
-
__publicField(this, "url");
|
|
2417
|
-
__publicField(this, "connection");
|
|
2418
|
-
__publicField(this, "open", false);
|
|
2419
|
-
this.api = typeof api == "string" ? new Api(api) : api;
|
|
2420
|
-
this.url = this.api.url.replace("http", "ws");
|
|
2421
|
-
this.api.on("api/token", () => this.connect());
|
|
2422
|
-
this.connect();
|
|
2423
|
-
}
|
|
2424
|
-
close() {
|
|
2425
|
-
var _a;
|
|
2426
|
-
if (this.open) console.debug("Disconnected from Momentum");
|
|
2427
|
-
this.open = false;
|
|
2428
|
-
(_a = this.connection) == null ? void 0 : _a.close();
|
|
2429
|
-
this.connection = void 0;
|
|
2430
|
-
}
|
|
2431
|
-
connect() {
|
|
2432
|
-
if (this.open) this.close();
|
|
2433
|
-
if (navigator.onLine) {
|
|
2434
|
-
this.connection = new WebSocket(this.url + (this.api.token ? `?token=${this.api.token}` : ""));
|
|
2435
|
-
this.connection.onclose = this.close;
|
|
2436
|
-
this.connection.onmessage = this.handle;
|
|
2437
|
-
this.connection.onopen = () => {
|
|
2438
|
-
this.open = true;
|
|
2439
|
-
clearTimeout(timeout);
|
|
2440
|
-
console.debug("Connected to Momentum");
|
|
2441
|
-
};
|
|
2442
|
-
}
|
|
2443
|
-
const timeout = setTimeout(() => {
|
|
2444
|
-
if (this.open) return;
|
|
2445
|
-
this.close();
|
|
2446
|
-
this.connect();
|
|
2447
|
-
}, _Socket.pollingSpeed);
|
|
2448
|
-
}
|
|
2449
|
-
handle(...args) {
|
|
2450
|
-
console.log(args);
|
|
2451
|
-
}
|
|
2452
|
-
send(channel, payload) {
|
|
2453
|
-
var _a;
|
|
2454
|
-
(_a = this.connection) == null ? void 0 : _a.send(JSON.stringify({
|
|
2455
|
-
token: this.api.token,
|
|
2456
|
-
channel,
|
|
2457
|
-
payload
|
|
2458
|
-
}));
|
|
2459
|
-
}
|
|
2460
|
-
};
|
|
2461
|
-
__publicField(_Socket, "pollingSpeed", 3e4);
|
|
2462
|
-
let Socket = _Socket;
|
|
2463
|
-
let Storage$1 = class Storage extends PathEventEmitter {
|
|
2464
|
-
constructor(api, path = "storage") {
|
|
2465
|
-
super();
|
|
2466
|
-
__publicField(this, "api");
|
|
2467
|
-
this.path = path;
|
|
2468
|
-
this.api = typeof api == "string" ? new Api(api) : api;
|
|
2469
|
-
}
|
|
2470
|
-
copy(source, destination) {
|
|
2471
|
-
if (!source || !destination) throw new Error("Cannot copy file or folder, missing source or destination");
|
|
2472
|
-
return this.api.request({ url: "/api/" + PES`${this.path}/${destination}`, body: { from: source } }).then((response) => {
|
|
2473
|
-
this.emit(PES`${this.path}/${destination}:c`, response);
|
|
2474
|
-
return response;
|
|
2475
|
-
});
|
|
2476
|
-
}
|
|
2477
|
-
delete(path) {
|
|
2478
|
-
if (!path) throw new Error("Cannot delete file or folder, missing path");
|
|
2479
|
-
return this.api.request({ url: "/api/" + PES`${this.path}/${path}`, method: "DELETE" }).then(() => {
|
|
2480
|
-
this.emit(PES`${this.path}/${path}:d`, path);
|
|
2481
|
-
});
|
|
2482
|
-
}
|
|
2483
|
-
download(path, opts = {}) {
|
|
2484
|
-
if (!path) throw new Error("Cannot download file, missing path");
|
|
2485
|
-
return this.api.request({ ...opts, url: "/api/" + PES`${this.path}/${path}`, decode: false }).then(async (response) => {
|
|
2486
|
-
const blob = await response.blob();
|
|
2487
|
-
const name = opts.downloadAs || path.split("/").pop();
|
|
2488
|
-
this.emit(PES`${this.path}/${path}:r`, blob);
|
|
2489
|
-
downloadFile(blob, name);
|
|
2490
|
-
return response;
|
|
2491
|
-
});
|
|
2492
|
-
}
|
|
2493
|
-
list(path) {
|
|
2494
|
-
if (!path) path = "/";
|
|
2495
|
-
return this.api.request({ url: "/api/" + PES`${this.path}/${path}` + "?list" }).then((resp) => {
|
|
2496
|
-
this.emit(PES`${this.path}/${path}:r`, resp);
|
|
2497
|
-
return resp;
|
|
2498
|
-
});
|
|
2499
|
-
}
|
|
2500
|
-
open(path, target = "_blank") {
|
|
2501
|
-
if (!path) throw new Error("Cannot download file, missing path");
|
|
2502
|
-
const link = `${this.api.url}/api/` + PES`${this.path}/${path}${!this.api.sameOrigin && this.api.token ? `?token=${this.api.token}` : ""}`;
|
|
2503
|
-
if (!target) return link;
|
|
2504
|
-
this.emit(PES`${this.path}/${path}:r`, path);
|
|
2505
|
-
return window.open(link, target);
|
|
2506
|
-
}
|
|
2507
|
-
mkdir(path) {
|
|
2508
|
-
if (!path) throw new Error("Cannot make directory, missing path");
|
|
2509
|
-
return this.api.request({ url: "/api/" + PES`${this.path}/${path}`, body: { directory: true } }).then((resp) => {
|
|
2510
|
-
this.emit(PES`${this.path}/${path}:c`, resp);
|
|
2511
|
-
return resp;
|
|
2512
|
-
});
|
|
2513
|
-
}
|
|
2514
|
-
move(source, destination) {
|
|
2515
|
-
if (!source || !destination) throw new Error("Cannot move file or folder, missing source or destination");
|
|
2516
|
-
if (source == destination) return this.list(destination);
|
|
2517
|
-
return this.api.request({ url: "/api/" + PES`${this.path}/${source}`, method: "PATCH", body: { move: destination } }).then((response) => {
|
|
2518
|
-
this.emit(PES`${this.path}/${source}:u`, response);
|
|
2519
|
-
return response;
|
|
2520
|
-
});
|
|
2521
|
-
}
|
|
2522
|
-
upload(files, opts) {
|
|
2523
|
-
return new PromiseProgress(async (res, rej, prog) => {
|
|
2524
|
-
if (!files) files = await fileBrowser(typeof opts == "object" ? opts : void 0);
|
|
2525
|
-
if (!files || Array.isArray(files) && !files.length) return [];
|
|
2526
|
-
const path = (opts && typeof opts == "object" ? opts == null ? void 0 : opts.path : opts) || "/";
|
|
2527
|
-
return uploadWithProgress({
|
|
2528
|
-
url: `${this.api.url}/api/` + PES`${this.path}/${path}`,
|
|
2529
|
-
files: makeArray(files),
|
|
2530
|
-
headers: this.api.headers
|
|
2531
|
-
}).onProgress((p) => {
|
|
2532
|
-
prog(p);
|
|
2533
|
-
}).then((resp) => {
|
|
2534
|
-
this.emit(PES`${this.path}/${path}:c`, resp);
|
|
2535
|
-
res(resp);
|
|
2536
|
-
}).catch((err) => rej(err));
|
|
2537
|
-
});
|
|
2538
|
-
}
|
|
2539
|
-
};
|
|
2540
|
-
class Users extends PathEventEmitter {
|
|
2541
|
-
constructor(api) {
|
|
2542
|
-
super();
|
|
2543
|
-
__publicField(this, "api");
|
|
2544
|
-
__publicField(this, "cache", new Cache("username"));
|
|
2545
|
-
this.api = typeof api == "string" ? new Api(api) : api;
|
|
2546
|
-
}
|
|
2547
|
-
async all(reload) {
|
|
2548
|
-
if (!reload && this.cache.complete) return this.cache.all();
|
|
2549
|
-
return this.api.request({ url: "/api/" + PES`users` }).then((resp) => {
|
|
2550
|
-
resp == null ? void 0 : resp.forEach((r) => {
|
|
2551
|
-
r.image = `${this.api.url}${r.image}${!this.api.sameOrigin && this.api.token ? `?token=${this.api.token}` : ""}`;
|
|
2552
|
-
return r;
|
|
2553
|
-
});
|
|
2554
|
-
this.cache.addAll(resp);
|
|
2555
|
-
this.emit(PES`users:r`, resp || []);
|
|
2556
|
-
return resp;
|
|
2557
|
-
});
|
|
2558
|
-
}
|
|
2559
|
-
delete(username) {
|
|
2560
|
-
if (!username) throw new Error("Cannot delete user, missing username");
|
|
2561
|
-
return this.api.request({
|
|
2562
|
-
url: "/api/" + PES`users/${username}`,
|
|
2563
|
-
method: "DELETE"
|
|
2564
|
-
}).then(() => {
|
|
2565
|
-
this.cache.delete(username);
|
|
2566
|
-
this.emit(PES`users/${username}:d`, username);
|
|
2567
|
-
});
|
|
2568
|
-
}
|
|
2569
|
-
async read(username, reload) {
|
|
2570
|
-
if (!username) throw new Error("Cannot read user, missing username");
|
|
2571
|
-
if (!reload && this.cache.get(username)) return this.cache.get(username);
|
|
2572
|
-
return this.api.request({ url: "/api/" + PES`users/${username}` }).then((resp) => {
|
|
2573
|
-
if (resp) {
|
|
2574
|
-
resp.image = `${this.api.url}${resp.image}${!this.api.sameOrigin && this.api.token ? `?token=${this.api.token}` : ""}`;
|
|
2575
|
-
this.cache.add(resp);
|
|
2576
|
-
}
|
|
2577
|
-
this.emit(PES`users/${username}:r`, resp);
|
|
2578
|
-
return resp;
|
|
2579
|
-
});
|
|
2580
|
-
}
|
|
2581
|
-
update(user) {
|
|
2582
|
-
if (!user.username) throw new Error("Cannot update user, missing username");
|
|
2583
|
-
return this.api.request({
|
|
2584
|
-
url: `/api/` + PES`users/${user.username}`,
|
|
2585
|
-
method: "PATCH",
|
|
2586
|
-
body: user
|
|
2587
|
-
}).then((resp) => {
|
|
2588
|
-
if (resp) {
|
|
2589
|
-
resp.image = this.api.url + resp.image + `?token=${this.api.token}`;
|
|
2590
|
-
this.cache.add(resp);
|
|
2591
|
-
}
|
|
2592
|
-
this.emit(PES`users/${user.username}:${resp._id ? "u" : "c"}`, resp);
|
|
2593
|
-
return resp;
|
|
2594
|
-
});
|
|
2595
|
-
}
|
|
2596
|
-
uploadImage(username, file) {
|
|
2597
|
-
if (!username || !file) throw new Error("Cannot update user image, missing username or file");
|
|
2598
|
-
return uploadWithProgress({
|
|
2599
|
-
url: this.api.url + `/api/` + PES`users/${username}/image`,
|
|
2600
|
-
files: [file],
|
|
2601
|
-
headers: this.api.headers
|
|
2602
|
-
});
|
|
2603
|
-
}
|
|
2604
|
-
}
|
|
2605
|
-
class Settings extends PathEventEmitter {
|
|
2606
|
-
constructor(api) {
|
|
2607
|
-
super();
|
|
2608
|
-
__publicField(this, "api");
|
|
2609
|
-
__publicField(this, "cache");
|
|
2610
|
-
this.api = typeof api == "string" ? new Api(api) : api;
|
|
2611
|
-
this.cache = new Cache("key", { storageKey: `momentum:settings:${this.api.host}` });
|
|
2612
|
-
this.api.on("api/token", () => this.all(false, true));
|
|
2613
|
-
}
|
|
2614
|
-
async all(detailed, reload) {
|
|
2615
|
-
if (!reload && !detailed && this.cache.complete) return this.cache;
|
|
2616
|
-
return this.api.request({ url: `/api/` + PES`settings` + (detailed ? "?detailed" : "") }).then((resp) => {
|
|
2617
|
-
this.cache.clear();
|
|
2618
|
-
if (resp) Object.keys(resp).forEach((key) => this.cache.set(key, detailed ? resp[key].value : resp[key]));
|
|
2619
|
-
this.cache.complete = true;
|
|
2620
|
-
this.emit(PES`settings:r`, resp || []);
|
|
2621
|
-
return resp;
|
|
2622
|
-
});
|
|
2623
|
-
}
|
|
2624
|
-
delete(key) {
|
|
2625
|
-
if (!key) throw new Error("Cannot delete setting, missing key");
|
|
2626
|
-
return this.api.request({ url: `/api/` + PES`settings/${key}`, method: "DELETE" }).then(() => {
|
|
2627
|
-
this.cache.delete(key);
|
|
2628
|
-
this.emit(PES`settings/${key}:d`, key);
|
|
2629
|
-
});
|
|
2630
|
-
}
|
|
2631
|
-
read(key, reload = false) {
|
|
2632
|
-
if (!key) throw new Error("Cannot read setting, missing key");
|
|
2633
|
-
if (!reload && this.cache.get(key)) return this.cache.get(key);
|
|
2634
|
-
return this.api.request({ url: `/api/` + PES`settings/${key}` }).then((variable) => {
|
|
2635
|
-
if (variable) this.cache.set(variable.key, variable.value);
|
|
2636
|
-
this.emit(PES`settings/${key}:r`, variable);
|
|
2637
|
-
return variable;
|
|
2638
|
-
});
|
|
2639
|
-
}
|
|
2640
|
-
update(variable) {
|
|
2641
|
-
if (!variable.key) throw new Error("Cannot update setting, missing key");
|
|
2642
|
-
return this.api.request({ url: `/api/` + PES`settings/${variable.key}`, body: variable }).then((variable2) => {
|
|
2643
|
-
if (variable2) this.cache.set(variable2.key, variable2.value);
|
|
2644
|
-
this.emit(`/api/` + PES`settings/${variable2.key}:${variable2._id ? "u" : "c"}`, variable2);
|
|
2645
|
-
return variable2;
|
|
2646
|
-
});
|
|
2647
|
-
}
|
|
2648
|
-
}
|
|
2649
|
-
class Static extends Storage$1 {
|
|
2650
|
-
constructor(api) {
|
|
2651
|
-
super(api, "static");
|
|
2652
|
-
}
|
|
2653
|
-
}
|
|
2654
|
-
class Momentum extends PathEventEmitter {
|
|
2655
|
-
constructor(url, opts) {
|
|
2656
|
-
super();
|
|
2657
|
-
__publicField(this, "api");
|
|
2658
|
-
__publicField(this, "actions");
|
|
2659
|
-
__publicField(this, "ai");
|
|
2660
|
-
__publicField(this, "analytics");
|
|
2661
|
-
__publicField(this, "auth");
|
|
2662
|
-
__publicField(this, "client");
|
|
2663
|
-
__publicField(this, "data");
|
|
2664
|
-
__publicField(this, "email");
|
|
2665
|
-
__publicField(this, "forms");
|
|
2666
|
-
__publicField(this, "groups");
|
|
2667
|
-
__publicField(this, "logger");
|
|
2668
|
-
__publicField(this, "payments");
|
|
2669
|
-
__publicField(this, "phone");
|
|
2670
|
-
__publicField(this, "pdf");
|
|
2671
|
-
__publicField(this, "settings");
|
|
2672
|
-
__publicField(this, "socket");
|
|
2673
|
-
__publicField(this, "static");
|
|
2674
|
-
__publicField(this, "storage");
|
|
2675
|
-
__publicField(this, "users");
|
|
2676
|
-
this.api = new Api(url, opts);
|
|
2677
|
-
this.actions = new Actions(this.api);
|
|
2678
|
-
this.ai = new Ai(this.api);
|
|
2679
|
-
this.analytics = new Analytics(this.api);
|
|
2680
|
-
this.auth = new Auth(this.api, opts);
|
|
2681
|
-
this.data = new Data(this.api);
|
|
2682
|
-
this.email = new Email(this.api);
|
|
2683
|
-
this.forms = new Forms(this.api);
|
|
2684
|
-
this.groups = new Groups(this.api);
|
|
2685
|
-
this.logger = new Logger(this.api, (opts == null ? void 0 : opts.app) || "client", opts == null ? void 0 : opts.logLevel);
|
|
2686
|
-
this.payments = new Payments(this.api);
|
|
2687
|
-
this.pdf = new Pdf(this.api);
|
|
2688
|
-
this.phone = new Phone(this.api);
|
|
2689
|
-
this.settings = new Settings(this.api);
|
|
2690
|
-
if (opts == null ? void 0 : opts.socket) this.socket = new Socket(this.api);
|
|
2691
|
-
this.static = new Static(this.api);
|
|
2692
|
-
this.storage = new Storage$1(this.api);
|
|
2693
|
-
this.client = new Client(this.api, this.settings);
|
|
2694
|
-
this.users = new Users(this.api);
|
|
2695
|
-
this.relayEvents(this.actions);
|
|
2696
|
-
this.relayEvents(this.ai);
|
|
2697
|
-
this.relayEvents(this.analytics);
|
|
2698
|
-
this.relayEvents(this.api);
|
|
2699
|
-
this.relayEvents(this.auth);
|
|
2700
|
-
this.relayEvents(this.client);
|
|
2701
|
-
this.relayEvents(this.data);
|
|
2702
|
-
this.relayEvents(this.email);
|
|
2703
|
-
this.relayEvents(this.groups);
|
|
2704
|
-
this.relayEvents(this.logger);
|
|
2705
|
-
this.relayEvents(this.payments);
|
|
2706
|
-
this.relayEvents(this.pdf);
|
|
2707
|
-
this.relayEvents(this.phone);
|
|
2708
|
-
this.relayEvents(this.settings);
|
|
2709
|
-
this.relayEvents(this.static);
|
|
2710
|
-
this.relayEvents(this.storage);
|
|
2711
|
-
this.relayEvents(this.users);
|
|
2712
|
-
this.users.on(`*`, () => {
|
|
2713
|
-
if (!this.auth.user) return;
|
|
2714
|
-
const cached = this.users.cache.get(this.auth.user.username);
|
|
2715
|
-
if (cached) this.auth.user = cached;
|
|
2716
|
-
});
|
|
2717
|
-
this.settings.on("settings:r", (event, value) => {
|
|
2718
|
-
var _a;
|
|
2719
|
-
this.payments.token = ((_a = value["stripe_token"]) == null ? void 0 : _a.value) || value["stripe_token"];
|
|
2720
|
-
});
|
|
2721
|
-
if ((opts == null ? void 0 : opts.worker) !== false && "serviceWorker" in navigator) {
|
|
2722
|
-
navigator.serviceWorker.register((opts == null ? void 0 : opts.worker) || "/momentum.worker.js").catch(() => console.warn("Unable to load momentum worker, some features may be limited."));
|
|
2723
|
-
}
|
|
2724
|
-
}
|
|
2725
|
-
}
|
|
2726
|
-
exports2.ActionType = ActionType;
|
|
2727
|
-
exports2.Actions = Actions;
|
|
2728
|
-
exports2.Ai = Ai;
|
|
2729
|
-
exports2.Analytics = Analytics;
|
|
2730
|
-
exports2.Api = Api;
|
|
2731
|
-
exports2.Auth = Auth;
|
|
2732
|
-
exports2.Client = Client;
|
|
2733
|
-
exports2.Data = Data;
|
|
2734
|
-
exports2.Discounts = Discounts;
|
|
2735
|
-
exports2.Email = Email;
|
|
2736
|
-
exports2.Forms = Forms;
|
|
2737
|
-
exports2.Groups = Groups;
|
|
2738
|
-
exports2.Logger = Logger;
|
|
2739
|
-
exports2.Momentum = Momentum;
|
|
2740
|
-
exports2.PE = PE;
|
|
2741
|
-
exports2.PES = PES;
|
|
2742
|
-
exports2.PathEvent = PathEvent;
|
|
2743
|
-
exports2.PathEventEmitter = PathEventEmitter;
|
|
2744
|
-
exports2.Payments = Payments;
|
|
2745
|
-
exports2.Pdf = Pdf;
|
|
2746
|
-
exports2.Phone = Phone;
|
|
2747
|
-
exports2.Settings = Settings;
|
|
2748
|
-
exports2.Socket = Socket;
|
|
2749
|
-
exports2.Static = Static;
|
|
2750
|
-
exports2.Storage = Storage$1;
|
|
2751
|
-
exports2.Token = Token;
|
|
2752
|
-
exports2.Totp = Totp;
|
|
2753
|
-
exports2.Users = Users;
|
|
2754
|
-
Object.defineProperty(exports2, Symbol.toStringTag, { value: "Module" });
|
|
2755
|
-
});
|