@ztimson/utils 0.27.10 → 0.27.12
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.cjs +521 -422
- package/dist/index.cjs.map +1 -1
- package/dist/index.mjs +516 -417
- package/dist/index.mjs.map +1 -1
- package/dist/path-events.d.ts +37 -11
- package/package.json +9 -9
package/dist/index.cjs
CHANGED
|
@@ -1,10 +1,7 @@
|
|
|
1
|
-
(function(
|
|
2
|
-
typeof exports === "object" && typeof module !== "undefined" ? factory(exports) : typeof define === "function" && define.amd ? define(["exports"], factory) : (
|
|
3
|
-
})(this, function(exports2) {
|
|
4
|
-
"use strict";
|
|
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
|
-
|
|
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";
|
|
8
5
|
class ArgParser {
|
|
9
6
|
/**
|
|
10
7
|
* Create a unix-like argument parser to extract flags from the argument list. Can also create help messages.
|
|
@@ -15,19 +12,12 @@ var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "sy
|
|
|
15
12
|
* @param {string[]} examples Additional examples to display
|
|
16
13
|
*/
|
|
17
14
|
constructor(name, desc, argList = [], examples = []) {
|
|
18
|
-
__publicField(this, "commands", []);
|
|
19
|
-
__publicField(this, "args", []);
|
|
20
|
-
__publicField(this, "flags", []);
|
|
21
|
-
__publicField(this, "defaults");
|
|
22
15
|
this.name = name;
|
|
23
16
|
this.desc = desc;
|
|
24
17
|
this.argList = argList;
|
|
25
18
|
this.examples = examples;
|
|
26
19
|
this.commands = argList.filter((arg) => arg instanceof ArgParser);
|
|
27
|
-
this.args = argList.filter((arg) =>
|
|
28
|
-
var _a;
|
|
29
|
-
return !(arg instanceof ArgParser) && !((_a = arg.flags) == null ? void 0 : _a.length);
|
|
30
|
-
});
|
|
20
|
+
this.args = argList.filter((arg) => !(arg instanceof ArgParser) && !arg.flags?.length);
|
|
31
21
|
this.flags = [
|
|
32
22
|
...argList.filter((arg) => !(arg instanceof ArgParser) && arg.flags && arg.flags.length),
|
|
33
23
|
{ name: "help", desc: "Display command's help message", flags: ["-h", "--help"], default: false }
|
|
@@ -40,6 +30,10 @@ var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "sy
|
|
|
40
30
|
`--help ${this.commands.length ? "[COMMAND]" : ""}`
|
|
41
31
|
].filter((e) => !!e);
|
|
42
32
|
}
|
|
33
|
+
commands = [];
|
|
34
|
+
args = [];
|
|
35
|
+
flags = [];
|
|
36
|
+
defaults;
|
|
43
37
|
/**
|
|
44
38
|
* Parse an array into an arguments dictionary using the configuration.
|
|
45
39
|
*
|
|
@@ -47,7 +41,6 @@ var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "sy
|
|
|
47
41
|
* @returns {object} Dictionary of arguments with defaults applied
|
|
48
42
|
*/
|
|
49
43
|
parse(args) {
|
|
50
|
-
var _a;
|
|
51
44
|
let extras = [], parsed = { ...this.defaults, "_error": [] }, queue = [...args];
|
|
52
45
|
while (queue.length) {
|
|
53
46
|
let arg = queue.splice(0, 1)[0];
|
|
@@ -57,10 +50,7 @@ var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "sy
|
|
|
57
50
|
arg = `-${arg[1]}`;
|
|
58
51
|
}
|
|
59
52
|
const combined = arg.split("=");
|
|
60
|
-
const argDef = this.flags.find((flag) =>
|
|
61
|
-
var _a2;
|
|
62
|
-
return (_a2 = flag.flags) == null ? void 0 : _a2.includes(combined[0] || arg);
|
|
63
|
-
});
|
|
53
|
+
const argDef = this.flags.find((flag) => flag.flags?.includes(combined[0] || arg));
|
|
64
54
|
if (argDef == null) {
|
|
65
55
|
extras.push(arg);
|
|
66
56
|
continue;
|
|
@@ -88,7 +78,7 @@ var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "sy
|
|
|
88
78
|
if (!arg.optional && !extras.length) parsed["_error"].push(`Argument missing: ${arg.name.toUpperCase()}`);
|
|
89
79
|
if (extras.length) parsed[arg.name] = extras.splice(0, 1)[0];
|
|
90
80
|
});
|
|
91
|
-
const extraKey =
|
|
81
|
+
const extraKey = this.args.find((arg) => arg.extras)?.name || "_extra";
|
|
92
82
|
parsed[extraKey] = extras;
|
|
93
83
|
return parsed;
|
|
94
84
|
}
|
|
@@ -111,8 +101,7 @@ ${opts.message || this.desc}`;
|
|
|
111
101
|
msg += "\n\nUsage: " + this.examples.map((ex) => `${this.name} ${ex}`).join("\n ");
|
|
112
102
|
if (this.args.length) msg += "\n\n " + this.args.map((arg) => `${arg.name.toUpperCase()}${spacer(arg.name)}${arg.desc}`).join("\n ");
|
|
113
103
|
msg += "\n\nOptions:\n " + this.flags.map((flag) => {
|
|
114
|
-
|
|
115
|
-
const flags = ((_a = flag.flags) == null ? void 0 : _a.join(", ")) || "";
|
|
104
|
+
const flags = flag.flags?.join(", ") || "";
|
|
116
105
|
return `${flags}${spacer(flags)}${flag.desc}`;
|
|
117
106
|
}).join("\n ");
|
|
118
107
|
if (this.commands.length) msg += "\n\nCommands:\n " + this.commands.map((command) => `${command.name}${spacer(command.name)}${command.desc}`).join("\n ");
|
|
@@ -155,7 +144,7 @@ ${opts.message || this.desc}`;
|
|
|
155
144
|
}
|
|
156
145
|
return result;
|
|
157
146
|
}
|
|
158
|
-
for (const d of deltas.flat()) base = applyDelta(base,
|
|
147
|
+
for (const d of deltas.flat()) base = applyDelta(base, d?.delta ?? d);
|
|
159
148
|
return base;
|
|
160
149
|
}
|
|
161
150
|
function calcDelta(old, updated) {
|
|
@@ -163,8 +152,8 @@ ${opts.message || this.desc}`;
|
|
|
163
152
|
const delta = {};
|
|
164
153
|
const isObj = (v) => v && typeof v === "object" && !Array.isArray(v);
|
|
165
154
|
for (const key of /* @__PURE__ */ new Set([...old ? Object.keys(old) : [], ...updated ? Object.keys(updated) : []])) {
|
|
166
|
-
const oldVal = old
|
|
167
|
-
const newVal = updated
|
|
155
|
+
const oldVal = old?.[key];
|
|
156
|
+
const newVal = updated?.[key];
|
|
168
157
|
if (isObj(oldVal) && isObj(newVal)) {
|
|
169
158
|
const nested = calcDelta(oldVal, newVal);
|
|
170
159
|
if (nested !== null && Object.keys(nested).length > 0) delta[key] = nested;
|
|
@@ -212,7 +201,7 @@ ${opts.message || this.desc}`;
|
|
|
212
201
|
if (obj == null || !prop) return void 0;
|
|
213
202
|
return prop.split(/[.[\]]/g).filter((prop2) => prop2.length).reduce((obj2, prop2, i, arr) => {
|
|
214
203
|
if (prop2[0] == '"' || prop2[0] == "'") prop2 = prop2.slice(1, -1);
|
|
215
|
-
if (!
|
|
204
|
+
if (!obj2?.hasOwnProperty(prop2)) {
|
|
216
205
|
if (set == void 0) return void 0;
|
|
217
206
|
obj2[prop2] = {};
|
|
218
207
|
}
|
|
@@ -309,7 +298,7 @@ ${opts.message || this.desc}`;
|
|
|
309
298
|
*/
|
|
310
299
|
constructor(elements = []) {
|
|
311
300
|
super();
|
|
312
|
-
if (!!
|
|
301
|
+
if (!!elements?.["forEach"])
|
|
313
302
|
elements.forEach((el) => this.add(el));
|
|
314
303
|
}
|
|
315
304
|
/**
|
|
@@ -462,23 +451,12 @@ ${opts.message || this.desc}`;
|
|
|
462
451
|
* @param options
|
|
463
452
|
*/
|
|
464
453
|
constructor(key, options = {}) {
|
|
465
|
-
__publicField(this, "_loading");
|
|
466
|
-
__publicField(this, "store", /* @__PURE__ */ new Map());
|
|
467
|
-
__publicField(this, "timers", /* @__PURE__ */ new Map());
|
|
468
|
-
__publicField(this, "lruOrder", []);
|
|
469
|
-
/** Whether cache is complete */
|
|
470
|
-
__publicField(this, "complete", false);
|
|
471
|
-
/** Await initial loading */
|
|
472
|
-
__publicField(this, "loading", new Promise((r) => this._loading = r));
|
|
473
|
-
/** Get all cached items */
|
|
474
|
-
__publicField(this, "values", this.all);
|
|
475
|
-
var _a, _b, _c, _d;
|
|
476
454
|
this.key = key;
|
|
477
455
|
this.options = options;
|
|
478
456
|
if (this.options.persistentStorage != null) {
|
|
479
457
|
if (typeof this.options.persistentStorage == "string")
|
|
480
458
|
this.options.persistentStorage = { storage: localStorage, key: this.options.persistentStorage };
|
|
481
|
-
if (
|
|
459
|
+
if (this.options.persistentStorage?.storage?.database != void 0) {
|
|
482
460
|
(async () => {
|
|
483
461
|
const persists = this.options.persistentStorage;
|
|
484
462
|
const table = await persists.storage.createTable({ name: persists.key, key: this.key });
|
|
@@ -486,7 +464,7 @@ ${opts.message || this.desc}`;
|
|
|
486
464
|
for (const row of rows) this.store.set(this.getKey(row), row);
|
|
487
465
|
this._loading();
|
|
488
466
|
})();
|
|
489
|
-
} else if (
|
|
467
|
+
} else if (this.options.persistentStorage?.storage?.getItem != void 0) {
|
|
490
468
|
const { storage, key: key2 } = this.options.persistentStorage;
|
|
491
469
|
const stored = storage.getItem(key2);
|
|
492
470
|
if (stored != null) {
|
|
@@ -513,6 +491,14 @@ ${opts.message || this.desc}`;
|
|
|
513
491
|
}
|
|
514
492
|
});
|
|
515
493
|
}
|
|
494
|
+
_loading;
|
|
495
|
+
store = /* @__PURE__ */ new Map();
|
|
496
|
+
timers = /* @__PURE__ */ new Map();
|
|
497
|
+
lruOrder = [];
|
|
498
|
+
/** Whether cache is complete */
|
|
499
|
+
complete = false;
|
|
500
|
+
/** Await initial loading */
|
|
501
|
+
loading = new Promise((r) => this._loading = r);
|
|
516
502
|
getKey(value) {
|
|
517
503
|
if (!this.key) throw new Error("No key defined");
|
|
518
504
|
if (value[this.key] === void 0) throw new Error(`${this.key.toString()} Doesn't exist on ${JSON.stringify(value, null, 2)}`);
|
|
@@ -520,10 +506,9 @@ ${opts.message || this.desc}`;
|
|
|
520
506
|
}
|
|
521
507
|
/** Save item to storage */
|
|
522
508
|
save(key) {
|
|
523
|
-
var _a, _b;
|
|
524
509
|
const persists = this.options.persistentStorage;
|
|
525
|
-
if (!!
|
|
526
|
-
if (
|
|
510
|
+
if (!!persists?.storage) {
|
|
511
|
+
if (persists.storage?.database != void 0) {
|
|
527
512
|
persists.storage.createTable({ name: persists.key, key: this.key }).then((table) => {
|
|
528
513
|
if (key !== void 0) {
|
|
529
514
|
const value = this.get(key, true);
|
|
@@ -534,7 +519,7 @@ ${opts.message || this.desc}`;
|
|
|
534
519
|
this.all(true).forEach((row) => table.add(row));
|
|
535
520
|
}
|
|
536
521
|
});
|
|
537
|
-
} else if (
|
|
522
|
+
} else if (persists.storage?.setItem != void 0) {
|
|
538
523
|
const obj = {};
|
|
539
524
|
for (const [k, v] of this.store.entries()) obj[k] = v;
|
|
540
525
|
persists.storage.setItem(persists.key, JSONSanitize(obj));
|
|
@@ -566,7 +551,7 @@ ${opts.message || this.desc}`;
|
|
|
566
551
|
const out = [];
|
|
567
552
|
for (const v of this.store.values()) {
|
|
568
553
|
const val = v;
|
|
569
|
-
if (expired || !
|
|
554
|
+
if (expired || !val?._expired) out.push(deepCopy(val));
|
|
570
555
|
}
|
|
571
556
|
return out;
|
|
572
557
|
}
|
|
@@ -611,7 +596,7 @@ ${opts.message || this.desc}`;
|
|
|
611
596
|
const out = [];
|
|
612
597
|
for (const [k, v] of this.store.entries()) {
|
|
613
598
|
const val = v;
|
|
614
|
-
if (expired || !
|
|
599
|
+
if (expired || !val?._expired) out.push([k, deepCopy(val)]);
|
|
615
600
|
}
|
|
616
601
|
return out;
|
|
617
602
|
}
|
|
@@ -641,7 +626,7 @@ ${opts.message || this.desc}`;
|
|
|
641
626
|
const raw = this.store.get(key);
|
|
642
627
|
if (raw == null) return null;
|
|
643
628
|
this.touchLRU(key);
|
|
644
|
-
const isExpired = raw
|
|
629
|
+
const isExpired = raw?._expired;
|
|
645
630
|
if (expired || !isExpired) return deepCopy(raw);
|
|
646
631
|
return null;
|
|
647
632
|
}
|
|
@@ -650,7 +635,7 @@ ${opts.message || this.desc}`;
|
|
|
650
635
|
const out = [];
|
|
651
636
|
for (const [k, v] of this.store.entries()) {
|
|
652
637
|
const val = v;
|
|
653
|
-
if (expired || !
|
|
638
|
+
if (expired || !val?._expired) out.push(k);
|
|
654
639
|
}
|
|
655
640
|
return out;
|
|
656
641
|
}
|
|
@@ -659,7 +644,7 @@ ${opts.message || this.desc}`;
|
|
|
659
644
|
const copy = {};
|
|
660
645
|
for (const [k, v] of this.store.entries()) {
|
|
661
646
|
const val = v;
|
|
662
|
-
if (expired || !
|
|
647
|
+
if (expired || !val?._expired) copy[k] = deepCopy(val);
|
|
663
648
|
}
|
|
664
649
|
return copy;
|
|
665
650
|
}
|
|
@@ -679,10 +664,12 @@ ${opts.message || this.desc}`;
|
|
|
679
664
|
}
|
|
680
665
|
return this;
|
|
681
666
|
}
|
|
667
|
+
/** Get all cached items */
|
|
668
|
+
values = this.all;
|
|
682
669
|
}
|
|
683
670
|
function contrast(background) {
|
|
684
|
-
const exploded = background
|
|
685
|
-
if (!exploded ||
|
|
671
|
+
const exploded = background?.match(background.length >= 6 ? /[0-9a-fA-F]{2}/g : /[0-9a-fA-F]/g);
|
|
672
|
+
if (!exploded || exploded?.length < 3) return "black";
|
|
686
673
|
const [r, g, b] = exploded.map((hex) => parseInt(hex.length == 1 ? `${hex}${hex}` : hex, 16));
|
|
687
674
|
const luminance = (0.299 * r + 0.587 * g + 0.114 * b) / 255;
|
|
688
675
|
return luminance > 0.5 ? "black" : "white";
|
|
@@ -788,7 +775,7 @@ ${opts.message || this.desc}`;
|
|
|
788
775
|
"(?:(?<protocol>[\\w\\d]+)\\:\\/\\/)?(?:(?<user>.+)\\@)?(?<host>(?<domain>[^:\\/\\?#@\\n]+)(?:\\:(?<port>\\d*))?)(?<path>\\/.*?)?(?:\\?(?<query>.*?))?(?:#(?<fragment>.*?))?$",
|
|
789
776
|
"gm"
|
|
790
777
|
).exec(url);
|
|
791
|
-
const groups =
|
|
778
|
+
const groups = processed?.groups ?? {};
|
|
792
779
|
const domains = groups.domain.split(".");
|
|
793
780
|
if (groups["port"] != null) groups.port = Number(groups.port);
|
|
794
781
|
if (domains.length > 2) {
|
|
@@ -860,7 +847,6 @@ ${opts.message || this.desc}`;
|
|
|
860
847
|
return /^[a-zA-Z0-9.!#$%&'*+/=?^_`{|}~-]+@[a-zA-Z0-9-]+(?:\.[a-zA-Z0-9-]+)*$/.test(email);
|
|
861
848
|
}
|
|
862
849
|
function fromCsv(csv, hasHeaders = true) {
|
|
863
|
-
var _a;
|
|
864
850
|
function parseLine(line) {
|
|
865
851
|
const columns = [];
|
|
866
852
|
let current = "", inQuotes2 = false;
|
|
@@ -891,7 +877,7 @@ ${opts.message || this.desc}`;
|
|
|
891
877
|
}
|
|
892
878
|
if (currentRow) rows.push(currentRow.trim());
|
|
893
879
|
let headers = hasHeaders ? rows.splice(0, 1)[0] : null;
|
|
894
|
-
if (headers) headers =
|
|
880
|
+
if (headers) headers = headers.match(/(?:[^,"']+|"(?:[^"]|"")*"|'(?:[^']|'')*')+/g)?.map((h) => h.trim());
|
|
895
881
|
return rows.map((r) => {
|
|
896
882
|
const props = parseLine(r);
|
|
897
883
|
const h = headers || Array(props.length).fill(null).map((_, i) => {
|
|
@@ -944,11 +930,10 @@ ${opts.message || this.desc}`;
|
|
|
944
930
|
return Math.ceil((date.getTime() - start.getTime()) / (1e3 * 60 * 60 * 24));
|
|
945
931
|
}
|
|
946
932
|
function formatDate(format = "YYYY-MM-DD H:mm", date = /* @__PURE__ */ new Date(), tz = "local") {
|
|
947
|
-
var _a;
|
|
948
933
|
if (typeof date === "number" || typeof date === "string") date = new Date(date);
|
|
949
934
|
if (isNaN(date.getTime())) throw new Error("Invalid date input");
|
|
950
935
|
const numericTz = typeof tz === "number";
|
|
951
|
-
const localTz = tz === "local" || !numericTz &&
|
|
936
|
+
const localTz = tz === "local" || !numericTz && tz.toLowerCase?.() === "local";
|
|
952
937
|
const tzName = localTz ? Intl.DateTimeFormat().resolvedOptions().timeZone : numericTz ? "UTC" : tz;
|
|
953
938
|
if (!numericTz && tzName !== "UTC") {
|
|
954
939
|
try {
|
|
@@ -1009,7 +994,6 @@ ${opts.message || this.desc}`;
|
|
|
1009
994
|
return n + (s[(v - 20) % 10] || s[v] || s[0]);
|
|
1010
995
|
}
|
|
1011
996
|
function getTZOffset() {
|
|
1012
|
-
var _a2, _b;
|
|
1013
997
|
if (numericTz) {
|
|
1014
998
|
const total = tz * 60;
|
|
1015
999
|
const hours = Math.floor(Math.abs(total) / 60);
|
|
@@ -1017,17 +1001,16 @@ ${opts.message || this.desc}`;
|
|
|
1017
1001
|
return `${tz >= 0 ? "+" : "-"}${String(hours).padStart(2, "0")}:${String(mins).padStart(2, "0")}`;
|
|
1018
1002
|
}
|
|
1019
1003
|
try {
|
|
1020
|
-
const offset =
|
|
1004
|
+
const offset = new Intl.DateTimeFormat("en-US", { timeZone: tzName, timeZoneName: "longOffset", hour: "2-digit", minute: "2-digit" }).formatToParts(date).find((p) => p.type === "timeZoneName")?.value.match(/([+-]\d{2}:\d{2})/)?.[1];
|
|
1021
1005
|
if (offset) return offset;
|
|
1022
1006
|
} catch {
|
|
1023
1007
|
}
|
|
1024
1008
|
return "+00:00";
|
|
1025
1009
|
}
|
|
1026
1010
|
function getTZAbbr() {
|
|
1027
|
-
var _a2;
|
|
1028
1011
|
if (numericTz && tz === 0) return "UTC";
|
|
1029
1012
|
try {
|
|
1030
|
-
return
|
|
1013
|
+
return new Intl.DateTimeFormat("en-US", { timeZone: tzName, timeZoneName: "short" }).formatToParts(date).find((p) => p.type === "timeZoneName")?.value || "";
|
|
1031
1014
|
} catch {
|
|
1032
1015
|
return tzName;
|
|
1033
1016
|
}
|
|
@@ -1090,10 +1073,7 @@ ${opts.message || this.desc}`;
|
|
|
1090
1073
|
second: "2-digit"
|
|
1091
1074
|
});
|
|
1092
1075
|
const parts = dtf.formatToParts(date);
|
|
1093
|
-
const get = (type) =>
|
|
1094
|
-
var _a;
|
|
1095
|
-
return Number((_a = parts.find((v) => v.type === type)) == null ? void 0 : _a.value);
|
|
1096
|
-
};
|
|
1076
|
+
const get = (type) => Number(parts.find((v) => v.type === type)?.value);
|
|
1097
1077
|
const y = get("year");
|
|
1098
1078
|
const mo = get("month");
|
|
1099
1079
|
const d = get("day");
|
|
@@ -1105,9 +1085,7 @@ ${opts.message || this.desc}`;
|
|
|
1105
1085
|
return Math.round((asLocal - asUTC) / 6e4);
|
|
1106
1086
|
}
|
|
1107
1087
|
class AsyncLock {
|
|
1108
|
-
|
|
1109
|
-
__publicField(this, "p", Promise.resolve());
|
|
1110
|
-
}
|
|
1088
|
+
p = Promise.resolve();
|
|
1111
1089
|
run(fn2) {
|
|
1112
1090
|
const res = this.p.then(fn2, fn2);
|
|
1113
1091
|
this.p = res.then(() => {
|
|
@@ -1118,11 +1096,6 @@ ${opts.message || this.desc}`;
|
|
|
1118
1096
|
}
|
|
1119
1097
|
class Database {
|
|
1120
1098
|
constructor(database, tables, version) {
|
|
1121
|
-
__publicField(this, "schemaLock", new AsyncLock());
|
|
1122
|
-
__publicField(this, "upgrading", false);
|
|
1123
|
-
__publicField(this, "connection");
|
|
1124
|
-
__publicField(this, "tables");
|
|
1125
|
-
__publicField(this, "waitForUpgrade", () => sleepWhile(() => this.upgrading));
|
|
1126
1099
|
this.database = database;
|
|
1127
1100
|
this.version = version;
|
|
1128
1101
|
this.connection = new Promise((resolve, reject) => {
|
|
@@ -1183,8 +1156,8 @@ ${opts.message || this.desc}`;
|
|
|
1183
1156
|
desired.difference(existingTables).forEach((name) => {
|
|
1184
1157
|
const t = this.tables.find(findByProp("name", name));
|
|
1185
1158
|
db.createObjectStore(name, {
|
|
1186
|
-
keyPath: t
|
|
1187
|
-
autoIncrement:
|
|
1159
|
+
keyPath: t?.key,
|
|
1160
|
+
autoIncrement: t?.autoIncrement || !t?.key
|
|
1188
1161
|
});
|
|
1189
1162
|
});
|
|
1190
1163
|
}
|
|
@@ -1193,9 +1166,14 @@ ${opts.message || this.desc}`;
|
|
|
1193
1166
|
};
|
|
1194
1167
|
});
|
|
1195
1168
|
}
|
|
1169
|
+
schemaLock = new AsyncLock();
|
|
1170
|
+
upgrading = false;
|
|
1171
|
+
connection;
|
|
1172
|
+
tables;
|
|
1196
1173
|
get ready() {
|
|
1197
1174
|
return !this.upgrading;
|
|
1198
1175
|
}
|
|
1176
|
+
waitForUpgrade = () => sleepWhile(() => this.upgrading);
|
|
1199
1177
|
async createTable(table) {
|
|
1200
1178
|
return this.schemaLock.run(async () => {
|
|
1201
1179
|
if (typeof table == "string") table = { name: table };
|
|
@@ -1231,9 +1209,6 @@ ${opts.message || this.desc}`;
|
|
|
1231
1209
|
}
|
|
1232
1210
|
class Table {
|
|
1233
1211
|
constructor(database, name, key = "id") {
|
|
1234
|
-
__publicField(this, "all", this.getAll);
|
|
1235
|
-
__publicField(this, "create", this.add);
|
|
1236
|
-
__publicField(this, "update", this.set);
|
|
1237
1212
|
this.database = database;
|
|
1238
1213
|
this.name = name;
|
|
1239
1214
|
this.key = key;
|
|
@@ -1255,12 +1230,14 @@ ${opts.message || this.desc}`;
|
|
|
1255
1230
|
add(value, key) {
|
|
1256
1231
|
return this.tx(this.name, (store) => store.add(value, key));
|
|
1257
1232
|
}
|
|
1233
|
+
all = this.getAll;
|
|
1258
1234
|
clear() {
|
|
1259
1235
|
return this.tx(this.name, (store) => store.clear());
|
|
1260
1236
|
}
|
|
1261
1237
|
count() {
|
|
1262
1238
|
return this.tx(this.name, (store) => store.count(), true);
|
|
1263
1239
|
}
|
|
1240
|
+
create = this.add;
|
|
1264
1241
|
delete(key) {
|
|
1265
1242
|
return this.tx(this.name, (store) => store.delete(key));
|
|
1266
1243
|
}
|
|
@@ -1287,17 +1264,11 @@ ${opts.message || this.desc}`;
|
|
|
1287
1264
|
if (!value[this.key]) return this.add(value);
|
|
1288
1265
|
return this.put(value);
|
|
1289
1266
|
}
|
|
1267
|
+
update = this.set;
|
|
1290
1268
|
}
|
|
1291
1269
|
class PromiseProgress extends Promise {
|
|
1292
|
-
|
|
1293
|
-
|
|
1294
|
-
(value) => resolve(value),
|
|
1295
|
-
(reason) => reject(reason),
|
|
1296
|
-
(progress) => this.progress = progress
|
|
1297
|
-
));
|
|
1298
|
-
__publicField(this, "listeners", []);
|
|
1299
|
-
__publicField(this, "_progress", 0);
|
|
1300
|
-
}
|
|
1270
|
+
listeners = [];
|
|
1271
|
+
_progress = 0;
|
|
1301
1272
|
get progress() {
|
|
1302
1273
|
return this._progress;
|
|
1303
1274
|
}
|
|
@@ -1306,6 +1277,13 @@ ${opts.message || this.desc}`;
|
|
|
1306
1277
|
this._progress = p;
|
|
1307
1278
|
this.listeners.forEach((l) => l(p));
|
|
1308
1279
|
}
|
|
1280
|
+
constructor(executor) {
|
|
1281
|
+
super((resolve, reject) => executor(
|
|
1282
|
+
(value) => resolve(value),
|
|
1283
|
+
(reason) => reject(reason),
|
|
1284
|
+
(progress) => this.progress = progress
|
|
1285
|
+
));
|
|
1286
|
+
}
|
|
1309
1287
|
static from(promise) {
|
|
1310
1288
|
if (promise instanceof PromiseProgress) return promise;
|
|
1311
1289
|
return new PromiseProgress((res, rej) => promise.then((...args) => res(...args)).catch((...args) => rej(...args)));
|
|
@@ -1388,9 +1366,8 @@ ${opts.message || this.desc}`;
|
|
|
1388
1366
|
});
|
|
1389
1367
|
}
|
|
1390
1368
|
class TypedEmitter {
|
|
1391
|
-
|
|
1392
|
-
|
|
1393
|
-
}
|
|
1369
|
+
static listeners = {};
|
|
1370
|
+
listeners = {};
|
|
1394
1371
|
static emit(event, ...args) {
|
|
1395
1372
|
(this.listeners["*"] || []).forEach((l) => l(event, ...args));
|
|
1396
1373
|
(this.listeners[event.toString()] || []).forEach((l) => l(...args));
|
|
@@ -1400,19 +1377,18 @@ ${opts.message || this.desc}`;
|
|
|
1400
1377
|
this.listeners[e] = (this.listeners[e] || []).filter((l) => l != listener);
|
|
1401
1378
|
}
|
|
1402
1379
|
static on(event, listener) {
|
|
1403
|
-
var _a;
|
|
1404
1380
|
const e = event.toString();
|
|
1405
1381
|
if (!this.listeners[e]) this.listeners[e] = [];
|
|
1406
|
-
|
|
1382
|
+
this.listeners[e]?.push(listener);
|
|
1407
1383
|
return () => this.off(event, listener);
|
|
1408
1384
|
}
|
|
1409
1385
|
static once(event, listener) {
|
|
1410
1386
|
return new Promise((res) => {
|
|
1411
|
-
const unsubscribe = this.on(event, (...args) => {
|
|
1387
|
+
const unsubscribe = this.on(event, ((...args) => {
|
|
1412
1388
|
res(args.length == 1 ? args[0] : args);
|
|
1413
1389
|
if (listener) listener(...args);
|
|
1414
1390
|
unsubscribe();
|
|
1415
|
-
});
|
|
1391
|
+
}));
|
|
1416
1392
|
});
|
|
1417
1393
|
}
|
|
1418
1394
|
emit(event, ...args) {
|
|
@@ -1423,34 +1399,33 @@ ${opts.message || this.desc}`;
|
|
|
1423
1399
|
this.listeners[event] = (this.listeners[event] || []).filter((l) => l != listener);
|
|
1424
1400
|
}
|
|
1425
1401
|
on(event, listener) {
|
|
1426
|
-
var _a;
|
|
1427
1402
|
if (!this.listeners[event]) this.listeners[event] = [];
|
|
1428
|
-
|
|
1403
|
+
this.listeners[event]?.push(listener);
|
|
1429
1404
|
return () => this.off(event, listener);
|
|
1430
1405
|
}
|
|
1431
1406
|
once(event, listener) {
|
|
1432
1407
|
return new Promise((res) => {
|
|
1433
|
-
const unsubscribe = this.on(event, (...args) => {
|
|
1408
|
+
const unsubscribe = this.on(event, ((...args) => {
|
|
1434
1409
|
res(args.length == 1 ? args[0] : args);
|
|
1435
1410
|
if (listener) listener(...args);
|
|
1436
1411
|
unsubscribe();
|
|
1437
|
-
});
|
|
1412
|
+
}));
|
|
1438
1413
|
});
|
|
1439
1414
|
}
|
|
1440
1415
|
}
|
|
1441
|
-
__publicField(TypedEmitter, "listeners", {});
|
|
1442
1416
|
class CustomError extends Error {
|
|
1443
|
-
|
|
1444
|
-
|
|
1445
|
-
__publicField(this, "_code");
|
|
1446
|
-
if (code != null) this._code = code;
|
|
1447
|
-
}
|
|
1417
|
+
static code = 500;
|
|
1418
|
+
_code;
|
|
1448
1419
|
get code() {
|
|
1449
1420
|
return this._code || this.constructor.code;
|
|
1450
1421
|
}
|
|
1451
1422
|
set code(c) {
|
|
1452
1423
|
this._code = c;
|
|
1453
1424
|
}
|
|
1425
|
+
constructor(message, code) {
|
|
1426
|
+
super(message);
|
|
1427
|
+
if (code != null) this._code = code;
|
|
1428
|
+
}
|
|
1454
1429
|
static from(err) {
|
|
1455
1430
|
const code = Number(err.statusCode) ?? Number(err.code);
|
|
1456
1431
|
const newErr = new this(err.message || err.toString());
|
|
@@ -1467,8 +1442,8 @@ ${opts.message || this.desc}`;
|
|
|
1467
1442
|
return this.message || super.toString();
|
|
1468
1443
|
}
|
|
1469
1444
|
}
|
|
1470
|
-
__publicField(CustomError, "code", 500);
|
|
1471
1445
|
class BadRequestError extends CustomError {
|
|
1446
|
+
static code = 400;
|
|
1472
1447
|
constructor(message = "Bad Request") {
|
|
1473
1448
|
super(message);
|
|
1474
1449
|
}
|
|
@@ -1476,8 +1451,8 @@ ${opts.message || this.desc}`;
|
|
|
1476
1451
|
return err.constructor.code == this.code;
|
|
1477
1452
|
}
|
|
1478
1453
|
}
|
|
1479
|
-
__publicField(BadRequestError, "code", 400);
|
|
1480
1454
|
class UnauthorizedError extends CustomError {
|
|
1455
|
+
static code = 401;
|
|
1481
1456
|
constructor(message = "Unauthorized") {
|
|
1482
1457
|
super(message);
|
|
1483
1458
|
}
|
|
@@ -1485,8 +1460,8 @@ ${opts.message || this.desc}`;
|
|
|
1485
1460
|
return err.constructor.code == this.code;
|
|
1486
1461
|
}
|
|
1487
1462
|
}
|
|
1488
|
-
__publicField(UnauthorizedError, "code", 401);
|
|
1489
1463
|
class PaymentRequiredError extends CustomError {
|
|
1464
|
+
static code = 402;
|
|
1490
1465
|
constructor(message = "Payment Required") {
|
|
1491
1466
|
super(message);
|
|
1492
1467
|
}
|
|
@@ -1494,8 +1469,8 @@ ${opts.message || this.desc}`;
|
|
|
1494
1469
|
return err.constructor.code == this.code;
|
|
1495
1470
|
}
|
|
1496
1471
|
}
|
|
1497
|
-
__publicField(PaymentRequiredError, "code", 402);
|
|
1498
1472
|
class ForbiddenError extends CustomError {
|
|
1473
|
+
static code = 403;
|
|
1499
1474
|
constructor(message = "Forbidden") {
|
|
1500
1475
|
super(message);
|
|
1501
1476
|
}
|
|
@@ -1503,8 +1478,8 @@ ${opts.message || this.desc}`;
|
|
|
1503
1478
|
return err.constructor.code == this.code;
|
|
1504
1479
|
}
|
|
1505
1480
|
}
|
|
1506
|
-
__publicField(ForbiddenError, "code", 403);
|
|
1507
1481
|
class NotFoundError extends CustomError {
|
|
1482
|
+
static code = 404;
|
|
1508
1483
|
constructor(message = "Not Found") {
|
|
1509
1484
|
super(message);
|
|
1510
1485
|
}
|
|
@@ -1512,8 +1487,8 @@ ${opts.message || this.desc}`;
|
|
|
1512
1487
|
return err.constructor.code == this.code;
|
|
1513
1488
|
}
|
|
1514
1489
|
}
|
|
1515
|
-
__publicField(NotFoundError, "code", 404);
|
|
1516
1490
|
class MethodNotAllowedError extends CustomError {
|
|
1491
|
+
static code = 405;
|
|
1517
1492
|
constructor(message = "Method Not Allowed") {
|
|
1518
1493
|
super(message);
|
|
1519
1494
|
}
|
|
@@ -1521,8 +1496,8 @@ ${opts.message || this.desc}`;
|
|
|
1521
1496
|
return err.constructor.code == this.code;
|
|
1522
1497
|
}
|
|
1523
1498
|
}
|
|
1524
|
-
__publicField(MethodNotAllowedError, "code", 405);
|
|
1525
1499
|
class NotAcceptableError extends CustomError {
|
|
1500
|
+
static code = 406;
|
|
1526
1501
|
constructor(message = "Not Acceptable") {
|
|
1527
1502
|
super(message);
|
|
1528
1503
|
}
|
|
@@ -1530,8 +1505,8 @@ ${opts.message || this.desc}`;
|
|
|
1530
1505
|
return err.constructor.code == this.code;
|
|
1531
1506
|
}
|
|
1532
1507
|
}
|
|
1533
|
-
__publicField(NotAcceptableError, "code", 406);
|
|
1534
1508
|
class InternalServerError extends CustomError {
|
|
1509
|
+
static code = 500;
|
|
1535
1510
|
constructor(message = "Internal Server Error") {
|
|
1536
1511
|
super(message);
|
|
1537
1512
|
}
|
|
@@ -1539,8 +1514,8 @@ ${opts.message || this.desc}`;
|
|
|
1539
1514
|
return err.constructor.code == this.code;
|
|
1540
1515
|
}
|
|
1541
1516
|
}
|
|
1542
|
-
__publicField(InternalServerError, "code", 500);
|
|
1543
1517
|
class NotImplementedError extends CustomError {
|
|
1518
|
+
static code = 501;
|
|
1544
1519
|
constructor(message = "Not Implemented") {
|
|
1545
1520
|
super(message);
|
|
1546
1521
|
}
|
|
@@ -1548,8 +1523,8 @@ ${opts.message || this.desc}`;
|
|
|
1548
1523
|
return err.constructor.code == this.code;
|
|
1549
1524
|
}
|
|
1550
1525
|
}
|
|
1551
|
-
__publicField(NotImplementedError, "code", 501);
|
|
1552
1526
|
class BadGatewayError extends CustomError {
|
|
1527
|
+
static code = 502;
|
|
1553
1528
|
constructor(message = "Bad Gateway") {
|
|
1554
1529
|
super(message);
|
|
1555
1530
|
}
|
|
@@ -1557,8 +1532,8 @@ ${opts.message || this.desc}`;
|
|
|
1557
1532
|
return err.constructor.code == this.code;
|
|
1558
1533
|
}
|
|
1559
1534
|
}
|
|
1560
|
-
__publicField(BadGatewayError, "code", 502);
|
|
1561
1535
|
class ServiceUnavailableError extends CustomError {
|
|
1536
|
+
static code = 503;
|
|
1562
1537
|
constructor(message = "Service Unavailable") {
|
|
1563
1538
|
super(message);
|
|
1564
1539
|
}
|
|
@@ -1566,8 +1541,8 @@ ${opts.message || this.desc}`;
|
|
|
1566
1541
|
return err.constructor.code == this.code;
|
|
1567
1542
|
}
|
|
1568
1543
|
}
|
|
1569
|
-
__publicField(ServiceUnavailableError, "code", 503);
|
|
1570
1544
|
class GatewayTimeoutError extends CustomError {
|
|
1545
|
+
static code = 504;
|
|
1571
1546
|
constructor(message = "Gateway Timeout") {
|
|
1572
1547
|
super(message);
|
|
1573
1548
|
}
|
|
@@ -1575,7 +1550,6 @@ ${opts.message || this.desc}`;
|
|
|
1575
1550
|
return err.constructor.code == this.code;
|
|
1576
1551
|
}
|
|
1577
1552
|
}
|
|
1578
|
-
__publicField(GatewayTimeoutError, "code", 504);
|
|
1579
1553
|
function errorFromCode(code, message) {
|
|
1580
1554
|
switch (code) {
|
|
1581
1555
|
case 400:
|
|
@@ -1607,6 +1581,11 @@ ${opts.message || this.desc}`;
|
|
|
1607
1581
|
}
|
|
1608
1582
|
}
|
|
1609
1583
|
class HttpResponse extends Response {
|
|
1584
|
+
data;
|
|
1585
|
+
ok;
|
|
1586
|
+
redirected;
|
|
1587
|
+
type;
|
|
1588
|
+
url;
|
|
1610
1589
|
constructor(resp, stream) {
|
|
1611
1590
|
const body = [204, 205, 304].includes(resp.status) ? null : stream;
|
|
1612
1591
|
super(body, {
|
|
@@ -1614,33 +1593,30 @@ ${opts.message || this.desc}`;
|
|
|
1614
1593
|
status: resp.status,
|
|
1615
1594
|
statusText: resp.statusText
|
|
1616
1595
|
});
|
|
1617
|
-
__publicField(this, "data");
|
|
1618
|
-
__publicField(this, "ok");
|
|
1619
|
-
__publicField(this, "redirected");
|
|
1620
|
-
__publicField(this, "type");
|
|
1621
|
-
__publicField(this, "url");
|
|
1622
1596
|
this.ok = resp.ok;
|
|
1623
1597
|
this.redirected = resp.redirected;
|
|
1624
1598
|
this.type = resp.type;
|
|
1625
1599
|
this.url = resp.url;
|
|
1626
1600
|
}
|
|
1627
1601
|
}
|
|
1628
|
-
|
|
1602
|
+
class Http {
|
|
1603
|
+
static interceptors = {};
|
|
1604
|
+
static headers = {};
|
|
1605
|
+
interceptors = {};
|
|
1606
|
+
headers = {};
|
|
1607
|
+
url;
|
|
1629
1608
|
constructor(defaults = {}) {
|
|
1630
|
-
__publicField(this, "interceptors", {});
|
|
1631
|
-
__publicField(this, "headers", {});
|
|
1632
|
-
__publicField(this, "url");
|
|
1633
1609
|
this.url = defaults.url ?? null;
|
|
1634
1610
|
this.headers = defaults.headers || {};
|
|
1635
1611
|
if (defaults.interceptors) {
|
|
1636
|
-
defaults.interceptors.forEach((i) =>
|
|
1612
|
+
defaults.interceptors.forEach((i) => Http.addInterceptor(i));
|
|
1637
1613
|
}
|
|
1638
1614
|
}
|
|
1639
1615
|
static addInterceptor(fn2) {
|
|
1640
|
-
const key = Object.keys(
|
|
1641
|
-
|
|
1616
|
+
const key = Object.keys(Http.interceptors).length.toString();
|
|
1617
|
+
Http.interceptors[key] = fn2;
|
|
1642
1618
|
return () => {
|
|
1643
|
-
|
|
1619
|
+
Http.interceptors[key] = null;
|
|
1644
1620
|
};
|
|
1645
1621
|
}
|
|
1646
1622
|
addInterceptor(fn2) {
|
|
@@ -1651,9 +1627,8 @@ ${opts.message || this.desc}`;
|
|
|
1651
1627
|
};
|
|
1652
1628
|
}
|
|
1653
1629
|
request(opts = {}) {
|
|
1654
|
-
var _a;
|
|
1655
1630
|
if (!this.url && !opts.url) throw new Error("URL needs to be set");
|
|
1656
|
-
let url =
|
|
1631
|
+
let url = opts.url?.startsWith("http") ? opts.url : (this.url || "") + (opts.url || "");
|
|
1657
1632
|
url = url.replaceAll(/([^:]\/)\/+/g, "$1");
|
|
1658
1633
|
if (opts.fragment) url.includes("#") ? url.replace(/#.*([?\n])/g, (match, arg1) => `#${opts.fragment}${arg1}`) : `${url}#${opts.fragment}`;
|
|
1659
1634
|
if (opts.query) {
|
|
@@ -1662,7 +1637,7 @@ ${opts.message || this.desc}`;
|
|
|
1662
1637
|
}
|
|
1663
1638
|
const headers = clean({
|
|
1664
1639
|
"Content-Type": !opts.body ? void 0 : opts.body instanceof FormData ? "multipart/form-data" : "application/json",
|
|
1665
|
-
...
|
|
1640
|
+
...Http.headers,
|
|
1666
1641
|
...this.headers,
|
|
1667
1642
|
...opts.headers
|
|
1668
1643
|
});
|
|
@@ -1675,18 +1650,17 @@ ${opts.message || this.desc}`;
|
|
|
1675
1650
|
method: opts.method || (opts.body ? "POST" : "GET"),
|
|
1676
1651
|
body: opts.body
|
|
1677
1652
|
}).then(async (resp) => {
|
|
1678
|
-
|
|
1679
|
-
for (let fn2 of [...Object.values(_Http.interceptors), ...Object.values(this.interceptors)]) {
|
|
1653
|
+
for (let fn2 of [...Object.values(Http.interceptors), ...Object.values(this.interceptors)]) {
|
|
1680
1654
|
await new Promise((res2) => fn2(resp, () => res2()));
|
|
1681
1655
|
}
|
|
1682
1656
|
const contentLength = resp.headers.get("Content-Length");
|
|
1683
1657
|
const total = contentLength ? parseInt(contentLength, 10) : 0;
|
|
1684
1658
|
let loaded = 0;
|
|
1685
|
-
const reader =
|
|
1659
|
+
const reader = resp.body?.getReader();
|
|
1686
1660
|
const stream = new ReadableStream({
|
|
1687
1661
|
start(controller) {
|
|
1688
1662
|
function push() {
|
|
1689
|
-
reader
|
|
1663
|
+
reader?.read().then((event) => {
|
|
1690
1664
|
if (event.done) return controller.close();
|
|
1691
1665
|
loaded += event.value.byteLength;
|
|
1692
1666
|
prog(loaded / total);
|
|
@@ -1699,11 +1673,11 @@ ${opts.message || this.desc}`;
|
|
|
1699
1673
|
});
|
|
1700
1674
|
resp = new HttpResponse(resp, stream);
|
|
1701
1675
|
if (opts.decode !== false) {
|
|
1702
|
-
const content =
|
|
1703
|
-
if (content
|
|
1704
|
-
else if (content
|
|
1705
|
-
else if (content
|
|
1706
|
-
else if (content
|
|
1676
|
+
const content = resp.headers.get("Content-Type")?.toLowerCase();
|
|
1677
|
+
if (content?.includes("form")) resp.data = await resp.formData();
|
|
1678
|
+
else if (content?.includes("json")) resp.data = await resp.json();
|
|
1679
|
+
else if (content?.includes("text")) resp.data = await resp.text();
|
|
1680
|
+
else if (content?.includes("application")) resp.data = await resp.blob();
|
|
1707
1681
|
}
|
|
1708
1682
|
if (resp.ok) res(resp);
|
|
1709
1683
|
else rej(resp);
|
|
@@ -1713,10 +1687,7 @@ ${opts.message || this.desc}`;
|
|
|
1713
1687
|
}
|
|
1714
1688
|
});
|
|
1715
1689
|
}
|
|
1716
|
-
}
|
|
1717
|
-
__publicField(_Http, "interceptors", {});
|
|
1718
|
-
__publicField(_Http, "headers", {});
|
|
1719
|
-
let Http = _Http;
|
|
1690
|
+
}
|
|
1720
1691
|
function createJwt(payload, signature = "unsigned") {
|
|
1721
1692
|
const header = Buffer.from(JSON.stringify({ alg: "HS256", typ: "JWT" })).toString("base64url");
|
|
1722
1693
|
const body = Buffer.from(JSON.stringify(payload)).toString("base64url");
|
|
@@ -1774,49 +1745,48 @@ ${opts.message || this.desc}`;
|
|
|
1774
1745
|
LOG_LEVEL2[LOG_LEVEL2["DEBUG"] = 4] = "DEBUG";
|
|
1775
1746
|
return LOG_LEVEL2;
|
|
1776
1747
|
})(LOG_LEVEL || {});
|
|
1777
|
-
|
|
1748
|
+
class Logger extends TypedEmitter {
|
|
1778
1749
|
constructor(namespace) {
|
|
1779
1750
|
super();
|
|
1780
1751
|
this.namespace = namespace;
|
|
1781
1752
|
}
|
|
1753
|
+
static LOG_LEVEL = 4;
|
|
1782
1754
|
format(...text) {
|
|
1783
1755
|
const now = /* @__PURE__ */ new Date();
|
|
1784
1756
|
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")}`;
|
|
1785
1757
|
return `${timestamp}${this.namespace ? ` [${this.namespace}]` : ""} ${text.map((t) => typeof t == "string" ? t : JSONSanitize(t, 2)).join(" ")}`;
|
|
1786
1758
|
}
|
|
1787
1759
|
debug(...args) {
|
|
1788
|
-
if (
|
|
1760
|
+
if (Logger.LOG_LEVEL < 4) return;
|
|
1789
1761
|
const str = this.format(...args);
|
|
1790
|
-
|
|
1762
|
+
Logger.emit(4, str);
|
|
1791
1763
|
console.debug(CliForeground.LIGHT_GREY + str + CliEffects.CLEAR);
|
|
1792
1764
|
}
|
|
1793
1765
|
log(...args) {
|
|
1794
|
-
if (
|
|
1766
|
+
if (Logger.LOG_LEVEL < 3) return;
|
|
1795
1767
|
const str = this.format(...args);
|
|
1796
|
-
|
|
1768
|
+
Logger.emit(3, str);
|
|
1797
1769
|
console.log(CliEffects.CLEAR + str);
|
|
1798
1770
|
}
|
|
1799
1771
|
info(...args) {
|
|
1800
|
-
if (
|
|
1772
|
+
if (Logger.LOG_LEVEL < 2) return;
|
|
1801
1773
|
const str = this.format(...args);
|
|
1802
|
-
|
|
1774
|
+
Logger.emit(2, str);
|
|
1803
1775
|
console.info(CliForeground.BLUE + str + CliEffects.CLEAR);
|
|
1804
1776
|
}
|
|
1805
1777
|
warn(...args) {
|
|
1806
|
-
if (
|
|
1778
|
+
if (Logger.LOG_LEVEL < 1) return;
|
|
1807
1779
|
const str = this.format(...args);
|
|
1808
|
-
|
|
1780
|
+
Logger.emit(1, str);
|
|
1809
1781
|
console.warn(CliForeground.YELLOW + str + CliEffects.CLEAR);
|
|
1810
1782
|
}
|
|
1811
1783
|
error(...args) {
|
|
1812
|
-
if (
|
|
1784
|
+
if (Logger.LOG_LEVEL < 0) return;
|
|
1813
1785
|
const str = this.format(...args);
|
|
1814
|
-
|
|
1786
|
+
Logger.emit(0, str);
|
|
1815
1787
|
console.error(CliForeground.RED + str + CliEffects.CLEAR);
|
|
1816
1788
|
}
|
|
1817
|
-
}
|
|
1818
|
-
__publicField(_Logger, "LOG_LEVEL", 4);
|
|
1819
|
-
let Logger = _Logger;
|
|
1789
|
+
}
|
|
1820
1790
|
function dec2Frac(num, maxDen = 1e3) {
|
|
1821
1791
|
let sign = Math.sign(num);
|
|
1822
1792
|
num = Math.abs(num);
|
|
@@ -1851,22 +1821,22 @@ ${opts.message || this.desc}`;
|
|
|
1851
1821
|
}
|
|
1852
1822
|
function consoleInterceptor(out = console, map) {
|
|
1853
1823
|
const logs = { debug: [], log: [], info: [], warn: [], error: [], stderr: [], stdout: [] };
|
|
1854
|
-
const cWrapper = (type) => (...args) => {
|
|
1824
|
+
const cWrapper = (type) => ((...args) => {
|
|
1855
1825
|
if (out) out[type](...args);
|
|
1856
1826
|
logs[type].push(...args);
|
|
1857
1827
|
if (type == "error") logs.stderr.push(...args);
|
|
1858
1828
|
else logs.stdout.push(...args);
|
|
1859
|
-
};
|
|
1829
|
+
});
|
|
1860
1830
|
return {
|
|
1861
|
-
debug:
|
|
1831
|
+
debug: map?.debug != "none" ? cWrapper(map?.debug || "debug") : () => {
|
|
1862
1832
|
},
|
|
1863
|
-
log:
|
|
1833
|
+
log: map?.log != "none" ? cWrapper(map?.log || "log") : () => {
|
|
1864
1834
|
},
|
|
1865
|
-
info:
|
|
1835
|
+
info: map?.info != "none" ? cWrapper(map?.info || "info") : () => {
|
|
1866
1836
|
},
|
|
1867
|
-
warn:
|
|
1837
|
+
warn: map?.warn != "none" ? cWrapper(map?.warn || "warn") : () => {
|
|
1868
1838
|
},
|
|
1869
|
-
error:
|
|
1839
|
+
error: map?.error != "none" ? cWrapper(map?.error || "error") : () => {
|
|
1870
1840
|
},
|
|
1871
1841
|
output: logs
|
|
1872
1842
|
};
|
|
@@ -1907,44 +1877,29 @@ ${opts.message || this.desc}`;
|
|
|
1907
1877
|
if (args[i]) combined.push(args[i]);
|
|
1908
1878
|
}
|
|
1909
1879
|
const [paths, methods] = combined.join("/").split(":");
|
|
1910
|
-
return PathEvent.toString(paths, methods
|
|
1880
|
+
return PathEvent.toString(paths, methods?.split(""));
|
|
1911
1881
|
}
|
|
1912
1882
|
class PathError extends Error {
|
|
1913
1883
|
}
|
|
1914
|
-
|
|
1915
|
-
|
|
1916
|
-
|
|
1917
|
-
|
|
1918
|
-
|
|
1919
|
-
|
|
1920
|
-
|
|
1921
|
-
|
|
1922
|
-
|
|
1923
|
-
|
|
1924
|
-
|
|
1925
|
-
|
|
1926
|
-
|
|
1927
|
-
|
|
1928
|
-
|
|
1929
|
-
|
|
1930
|
-
|
|
1931
|
-
|
|
1932
|
-
|
|
1933
|
-
}
|
|
1934
|
-
let [p, scope, method] = e.replaceAll(/\/{2,}/g, "/").split(":");
|
|
1935
|
-
if (!method) method = scope || "*";
|
|
1936
|
-
if (p == "*" || !p && method == "*") {
|
|
1937
|
-
p = "";
|
|
1938
|
-
method = "*";
|
|
1939
|
-
}
|
|
1940
|
-
let temp = p.split("/").filter((p2) => !!p2);
|
|
1941
|
-
this.module = temp.splice(0, 1)[0] || "";
|
|
1942
|
-
this.path = temp.join("/");
|
|
1943
|
-
this.fullPath = `${this.module}${this.module && this.path ? "/" : ""}${this.path}`;
|
|
1944
|
-
this.name = temp.pop() || "";
|
|
1945
|
-
this.methods = new ASet(method.split(""));
|
|
1946
|
-
_PathEvent.pathEventCache.set(e, this);
|
|
1947
|
-
}
|
|
1884
|
+
class PathEvent {
|
|
1885
|
+
/** First directory in path */
|
|
1886
|
+
module;
|
|
1887
|
+
/** Entire path, including the module & name */
|
|
1888
|
+
fullPath;
|
|
1889
|
+
/** Path including the name, excluding the module */
|
|
1890
|
+
path;
|
|
1891
|
+
/** Last segment of path */
|
|
1892
|
+
name;
|
|
1893
|
+
/** List of methods */
|
|
1894
|
+
methods;
|
|
1895
|
+
/** Whether this path contains glob patterns */
|
|
1896
|
+
hasGlob;
|
|
1897
|
+
/** Internal cache for PathEvent instances to avoid redundant parsing */
|
|
1898
|
+
static pathEventCache = /* @__PURE__ */ new Map();
|
|
1899
|
+
/** Cache for compiled permissions (path + required permissions → result) */
|
|
1900
|
+
static permissionCache = /* @__PURE__ */ new Map();
|
|
1901
|
+
/** Max size for permission cache before LRU eviction */
|
|
1902
|
+
static MAX_PERMISSION_CACHE_SIZE = 1e3;
|
|
1948
1903
|
/** All/Wildcard specified */
|
|
1949
1904
|
get all() {
|
|
1950
1905
|
return this.methods.has("*");
|
|
@@ -1966,6 +1921,13 @@ ${opts.message || this.desc}`;
|
|
|
1966
1921
|
set create(v) {
|
|
1967
1922
|
v ? this.methods.delete("n").delete("*").add("c") : this.methods.delete("c");
|
|
1968
1923
|
}
|
|
1924
|
+
/** Execute method specified */
|
|
1925
|
+
get execute() {
|
|
1926
|
+
return !this.methods.has("n") && (this.methods.has("*") || this.methods.has("x"));
|
|
1927
|
+
}
|
|
1928
|
+
set execute(v) {
|
|
1929
|
+
v ? this.methods.delete("n").delete("*").add("x") : this.methods.delete("x");
|
|
1930
|
+
}
|
|
1969
1931
|
/** Read method specified */
|
|
1970
1932
|
get read() {
|
|
1971
1933
|
return !this.methods.has("n") && (this.methods.has("*") || this.methods.has("r"));
|
|
@@ -1987,9 +1949,107 @@ ${opts.message || this.desc}`;
|
|
|
1987
1949
|
set delete(v) {
|
|
1988
1950
|
v ? this.methods.delete("n").delete("*").add("d") : this.methods.delete("d");
|
|
1989
1951
|
}
|
|
1952
|
+
constructor(e) {
|
|
1953
|
+
if (typeof e == "object") {
|
|
1954
|
+
Object.assign(this, e);
|
|
1955
|
+
return;
|
|
1956
|
+
}
|
|
1957
|
+
if (PathEvent.pathEventCache.has(e)) {
|
|
1958
|
+
Object.assign(this, PathEvent.pathEventCache.get(e));
|
|
1959
|
+
return;
|
|
1960
|
+
}
|
|
1961
|
+
let [p, method] = e.replaceAll(/\/{2,}/g, "/").split(":");
|
|
1962
|
+
if (!method) method = "*";
|
|
1963
|
+
if (p === "" || p === void 0) {
|
|
1964
|
+
this.module = "";
|
|
1965
|
+
this.path = "";
|
|
1966
|
+
this.fullPath = "";
|
|
1967
|
+
this.name = "";
|
|
1968
|
+
this.methods = new ASet(["n"]);
|
|
1969
|
+
this.hasGlob = false;
|
|
1970
|
+
PathEvent.pathEventCache.set(e, this);
|
|
1971
|
+
return;
|
|
1972
|
+
}
|
|
1973
|
+
if (p === "*") {
|
|
1974
|
+
this.module = "";
|
|
1975
|
+
this.path = "";
|
|
1976
|
+
this.fullPath = "**";
|
|
1977
|
+
this.name = "";
|
|
1978
|
+
this.methods = new ASet(["*"]);
|
|
1979
|
+
this.hasGlob = true;
|
|
1980
|
+
PathEvent.pathEventCache.set(e, this);
|
|
1981
|
+
return;
|
|
1982
|
+
}
|
|
1983
|
+
let temp = p.split("/").filter((p2) => !!p2);
|
|
1984
|
+
this.module = temp.splice(0, 1)[0] || "";
|
|
1985
|
+
this.path = temp.join("/");
|
|
1986
|
+
this.fullPath = `${this.module}${this.module && this.path ? "/" : ""}${this.path}`;
|
|
1987
|
+
this.name = temp.pop() || "";
|
|
1988
|
+
this.hasGlob = this.fullPath.includes("*");
|
|
1989
|
+
this.methods = new ASet(method.split(""));
|
|
1990
|
+
PathEvent.pathEventCache.set(e, this);
|
|
1991
|
+
}
|
|
1990
1992
|
/** Clear the cache of all PathEvents */
|
|
1991
1993
|
static clearCache() {
|
|
1992
|
-
|
|
1994
|
+
PathEvent.pathEventCache.clear();
|
|
1995
|
+
}
|
|
1996
|
+
/** Clear the permission cache */
|
|
1997
|
+
static clearPermissionCache() {
|
|
1998
|
+
PathEvent.permissionCache.clear();
|
|
1999
|
+
}
|
|
2000
|
+
/**
|
|
2001
|
+
* Score a path for specificity ranking (lower = more specific = higher priority)
|
|
2002
|
+
* @private
|
|
2003
|
+
*/
|
|
2004
|
+
static scoreSpecificity(path) {
|
|
2005
|
+
if (path === "**" || path === "") return Number.MAX_SAFE_INTEGER;
|
|
2006
|
+
const segments = path.split("/").filter((p) => !!p);
|
|
2007
|
+
let score = -segments.length;
|
|
2008
|
+
segments.forEach((seg) => {
|
|
2009
|
+
if (seg === "**") score += 0.5;
|
|
2010
|
+
else if (seg === "*") score += 0.25;
|
|
2011
|
+
});
|
|
2012
|
+
return score;
|
|
2013
|
+
}
|
|
2014
|
+
/**
|
|
2015
|
+
* Check if a path matches a glob pattern
|
|
2016
|
+
* @private
|
|
2017
|
+
*/
|
|
2018
|
+
static pathMatchesGlob(path, pattern) {
|
|
2019
|
+
if (pattern === path) return true;
|
|
2020
|
+
const pathParts = path.split("/").filter((p) => !!p);
|
|
2021
|
+
const patternParts = pattern.split("/").filter((p) => !!p);
|
|
2022
|
+
let pathIdx = 0;
|
|
2023
|
+
let patternIdx = 0;
|
|
2024
|
+
while (patternIdx < patternParts.length && pathIdx < pathParts.length) {
|
|
2025
|
+
const patternPart = patternParts[patternIdx];
|
|
2026
|
+
if (patternPart === "**") {
|
|
2027
|
+
if (patternIdx === patternParts.length - 1) {
|
|
2028
|
+
return true;
|
|
2029
|
+
}
|
|
2030
|
+
patternParts[patternIdx + 1];
|
|
2031
|
+
while (pathIdx < pathParts.length) {
|
|
2032
|
+
if (PathEvent.pathMatchesGlob(pathParts.slice(pathIdx).join("/"), patternParts.slice(patternIdx + 1).join("/"))) {
|
|
2033
|
+
return true;
|
|
2034
|
+
}
|
|
2035
|
+
pathIdx++;
|
|
2036
|
+
}
|
|
2037
|
+
return false;
|
|
2038
|
+
} else if (patternPart === "*") {
|
|
2039
|
+
pathIdx++;
|
|
2040
|
+
patternIdx++;
|
|
2041
|
+
} else {
|
|
2042
|
+
if (patternPart !== pathParts[pathIdx]) {
|
|
2043
|
+
return false;
|
|
2044
|
+
}
|
|
2045
|
+
pathIdx++;
|
|
2046
|
+
patternIdx++;
|
|
2047
|
+
}
|
|
2048
|
+
}
|
|
2049
|
+
if (patternIdx < patternParts.length) {
|
|
2050
|
+
return patternParts.slice(patternIdx).every((p) => p === "**");
|
|
2051
|
+
}
|
|
2052
|
+
return pathIdx === pathParts.length;
|
|
1993
2053
|
}
|
|
1994
2054
|
/**
|
|
1995
2055
|
* Combine multiple events into one parsed object. Longest path takes precedent, but all subsequent methods are
|
|
@@ -1999,38 +2059,58 @@ ${opts.message || this.desc}`;
|
|
|
1999
2059
|
* @return {PathEvent} Final combined permission
|
|
2000
2060
|
*/
|
|
2001
2061
|
static combine(...paths) {
|
|
2002
|
-
|
|
2003
|
-
const
|
|
2004
|
-
const
|
|
2005
|
-
|
|
2006
|
-
|
|
2007
|
-
|
|
2008
|
-
|
|
2009
|
-
|
|
2010
|
-
if (
|
|
2011
|
-
|
|
2012
|
-
|
|
2013
|
-
|
|
2014
|
-
|
|
2062
|
+
const parsed = paths.map((p) => p instanceof PathEvent ? p : new PathEvent(p));
|
|
2063
|
+
const sorted = parsed.toSorted((p1, p2) => {
|
|
2064
|
+
const score1 = PathEvent.scoreSpecificity(p1.fullPath);
|
|
2065
|
+
const score2 = PathEvent.scoreSpecificity(p2.fullPath);
|
|
2066
|
+
return score1 - score2;
|
|
2067
|
+
});
|
|
2068
|
+
let result = null;
|
|
2069
|
+
for (const p of sorted) {
|
|
2070
|
+
if (!result) {
|
|
2071
|
+
result = p;
|
|
2072
|
+
} else {
|
|
2073
|
+
if (result.fullPath.startsWith(p.fullPath)) {
|
|
2074
|
+
if (p.none) {
|
|
2075
|
+
break;
|
|
2076
|
+
}
|
|
2077
|
+
result.methods = new ASet([...result.methods, ...p.methods]);
|
|
2078
|
+
}
|
|
2079
|
+
}
|
|
2080
|
+
}
|
|
2081
|
+
return result || new PathEvent("");
|
|
2015
2082
|
}
|
|
2016
2083
|
/**
|
|
2017
2084
|
* Filter a set of paths based on the target
|
|
2018
2085
|
*
|
|
2019
2086
|
* @param {string | PathEvent | (string | PathEvent)[]} target Array of events that will filtered
|
|
2020
|
-
* @param filter {...PathEvent} Must
|
|
2021
|
-
* @return {
|
|
2087
|
+
* @param filter {...PathEvent} Must contain one of
|
|
2088
|
+
* @return {PathEvent[]} Filtered results
|
|
2022
2089
|
*/
|
|
2023
2090
|
static filter(target, ...filter) {
|
|
2024
|
-
const parsedTarget = makeArray(target).map((pe) => pe instanceof
|
|
2025
|
-
const parsedFilter = makeArray(filter).map((pe) => pe instanceof
|
|
2026
|
-
return parsedTarget.filter((t) =>
|
|
2027
|
-
const
|
|
2028
|
-
|
|
2029
|
-
|
|
2030
|
-
|
|
2031
|
-
|
|
2032
|
-
|
|
2033
|
-
|
|
2091
|
+
const parsedTarget = makeArray(target).map((pe) => pe instanceof PathEvent ? pe : new PathEvent(pe));
|
|
2092
|
+
const parsedFilter = makeArray(filter).map((pe) => pe instanceof PathEvent ? pe : new PathEvent(pe));
|
|
2093
|
+
return parsedTarget.filter((t) => {
|
|
2094
|
+
const combined = PathEvent.combine(t);
|
|
2095
|
+
return !!parsedFilter.find((r) => PathEvent.matches(r, combined));
|
|
2096
|
+
});
|
|
2097
|
+
}
|
|
2098
|
+
/**
|
|
2099
|
+
* Check if a filter pattern matches a target path
|
|
2100
|
+
* @private
|
|
2101
|
+
*/
|
|
2102
|
+
static matches(pattern, target) {
|
|
2103
|
+
if (pattern.fullPath === "" || target.fullPath === "") return false;
|
|
2104
|
+
if (pattern.fullPath === "*" || target.fullPath === "*") return pattern.methods.has("*") || target.methods.has("*") || pattern.methods.intersection(target.methods).length > 0;
|
|
2105
|
+
const methodsMatch = pattern.all || target.all || pattern.methods.intersection(target.methods).length > 0;
|
|
2106
|
+
if (!methodsMatch) return false;
|
|
2107
|
+
if (!pattern.hasGlob && !target.hasGlob) {
|
|
2108
|
+
return pattern.fullPath === target.fullPath;
|
|
2109
|
+
}
|
|
2110
|
+
if (pattern.hasGlob) {
|
|
2111
|
+
return this.pathMatchesGlob(target.fullPath, pattern.fullPath);
|
|
2112
|
+
}
|
|
2113
|
+
return this.pathMatchesGlob(pattern.fullPath, target.fullPath);
|
|
2034
2114
|
}
|
|
2035
2115
|
/**
|
|
2036
2116
|
* Squash 2 sets of paths & return true if any overlap is found
|
|
@@ -2040,44 +2120,38 @@ ${opts.message || this.desc}`;
|
|
|
2040
2120
|
* @return {boolean} Whether there is any overlap
|
|
2041
2121
|
*/
|
|
2042
2122
|
static has(target, ...has) {
|
|
2043
|
-
const parsedTarget = makeArray(target).map((pe) => pe instanceof
|
|
2044
|
-
const parsedRequired = makeArray(has).map((pe) => pe instanceof
|
|
2045
|
-
|
|
2046
|
-
|
|
2047
|
-
const p1 = r.fullPath.includes("*") ? r.fullPath.slice(0, r.fullPath.indexOf("*")) : r.fullPath;
|
|
2048
|
-
const p2 = t.fullPath.includes("*") ? t.fullPath.slice(0, t.fullPath.indexOf("*")) : t.fullPath;
|
|
2049
|
-
const scope = p1.startsWith(p2);
|
|
2050
|
-
const methods = r.all || t.all || r.methods.intersection(t.methods).length;
|
|
2051
|
-
return (wildcard || scope) && methods;
|
|
2052
|
-
}));
|
|
2123
|
+
const parsedTarget = makeArray(target).map((pe) => pe instanceof PathEvent ? pe : new PathEvent(pe));
|
|
2124
|
+
const parsedRequired = makeArray(has).map((pe) => pe instanceof PathEvent ? pe : new PathEvent(pe));
|
|
2125
|
+
const effectiveTarget = parsedTarget.length === 1 ? parsedTarget[0] : PathEvent.combine(...parsedTarget);
|
|
2126
|
+
return !!parsedRequired.find((r) => PathEvent.matches(r, effectiveTarget));
|
|
2053
2127
|
}
|
|
2054
2128
|
/**
|
|
2055
2129
|
* Squash 2 sets of paths & return true if the target has all paths
|
|
2056
2130
|
*
|
|
2057
2131
|
* @param {string | PathEvent | (string | PathEvent)[]} target Array of Events as strings or pre-parsed
|
|
2058
2132
|
* @param has Target must have all these paths
|
|
2059
|
-
* @return {boolean} Whether
|
|
2133
|
+
* @return {boolean} Whether all are present
|
|
2060
2134
|
*/
|
|
2061
2135
|
static hasAll(target, ...has) {
|
|
2062
|
-
return has.filter((h) =>
|
|
2136
|
+
return has.filter((h) => PathEvent.has(target, h)).length == has.length;
|
|
2063
2137
|
}
|
|
2064
2138
|
/**
|
|
2065
2139
|
* Same as `has` but raises an error if there is no overlap
|
|
2066
2140
|
*
|
|
2067
|
-
* @param {string | string[]} target Array of Events as strings or pre-parsed
|
|
2141
|
+
* @param {string | PathEvent | (string | PathEvent)[]} target Array of Events as strings or pre-parsed
|
|
2068
2142
|
* @param has Target must have at least one of these path
|
|
2069
2143
|
*/
|
|
2070
2144
|
static hasFatal(target, ...has) {
|
|
2071
|
-
if (!
|
|
2145
|
+
if (!PathEvent.has(target, ...has)) throw new PathError(`Requires one of: ${makeArray(has).join(", ")}`);
|
|
2072
2146
|
}
|
|
2073
2147
|
/**
|
|
2074
2148
|
* Same as `hasAll` but raises an error if the target is missing any paths
|
|
2075
2149
|
*
|
|
2076
|
-
* @param {string | string[]} target Array of Events as strings or pre-parsed
|
|
2150
|
+
* @param {string | PathEvent | (string | PathEvent)[]} target Array of Events as strings or pre-parsed
|
|
2077
2151
|
* @param has Target must have all these paths
|
|
2078
2152
|
*/
|
|
2079
2153
|
static hasAllFatal(target, ...has) {
|
|
2080
|
-
if (!
|
|
2154
|
+
if (!PathEvent.hasAll(target, ...has)) throw new PathError(`Requires all: ${makeArray(has).join(", ")}`);
|
|
2081
2155
|
}
|
|
2082
2156
|
/**
|
|
2083
2157
|
* Create event string from its components
|
|
@@ -2088,8 +2162,8 @@ ${opts.message || this.desc}`;
|
|
|
2088
2162
|
*/
|
|
2089
2163
|
static toString(path, methods) {
|
|
2090
2164
|
let p = makeArray(path).filter((p2) => !!p2).join("/");
|
|
2091
|
-
p = p
|
|
2092
|
-
if (methods
|
|
2165
|
+
p = p?.trim().replaceAll(/\/{2,}/g, "/").replaceAll(/(^\/|\/$)/g, "");
|
|
2166
|
+
if (methods?.length) p += `:${makeArray(methods).map((m) => m.toLowerCase()).join("")}`;
|
|
2093
2167
|
return p;
|
|
2094
2168
|
}
|
|
2095
2169
|
/**
|
|
@@ -2099,16 +2173,16 @@ ${opts.message || this.desc}`;
|
|
|
2099
2173
|
* @return {boolean} Whether there is any overlap
|
|
2100
2174
|
*/
|
|
2101
2175
|
has(...has) {
|
|
2102
|
-
return
|
|
2176
|
+
return PathEvent.has(this, ...has);
|
|
2103
2177
|
}
|
|
2104
2178
|
/**
|
|
2105
2179
|
* Squash 2 sets of paths & return true if the target has all paths
|
|
2106
2180
|
*
|
|
2107
2181
|
* @param has Target must have all these paths
|
|
2108
|
-
* @return {boolean} Whether
|
|
2182
|
+
* @return {boolean} Whether all are present
|
|
2109
2183
|
*/
|
|
2110
2184
|
hasAll(...has) {
|
|
2111
|
-
return
|
|
2185
|
+
return PathEvent.hasAll(this, ...has);
|
|
2112
2186
|
}
|
|
2113
2187
|
/**
|
|
2114
2188
|
* Same as `has` but raises an error if there is no overlap
|
|
@@ -2116,7 +2190,7 @@ ${opts.message || this.desc}`;
|
|
|
2116
2190
|
* @param has Target must have at least one of these path
|
|
2117
2191
|
*/
|
|
2118
2192
|
hasFatal(...has) {
|
|
2119
|
-
return
|
|
2193
|
+
return PathEvent.hasFatal(this, ...has);
|
|
2120
2194
|
}
|
|
2121
2195
|
/**
|
|
2122
2196
|
* Same as `hasAll` but raises an error if the target is missing any paths
|
|
@@ -2124,16 +2198,16 @@ ${opts.message || this.desc}`;
|
|
|
2124
2198
|
* @param has Target must have all these paths
|
|
2125
2199
|
*/
|
|
2126
2200
|
hasAllFatal(...has) {
|
|
2127
|
-
return
|
|
2201
|
+
return PathEvent.hasAllFatal(this, ...has);
|
|
2128
2202
|
}
|
|
2129
2203
|
/**
|
|
2130
2204
|
* Filter a set of paths based on this event
|
|
2131
2205
|
*
|
|
2132
2206
|
* @param {string | PathEvent | (string | PathEvent)[]} target Array of events that will filtered
|
|
2133
|
-
* @return {
|
|
2207
|
+
* @return {PathEvent[]} Filtered results
|
|
2134
2208
|
*/
|
|
2135
2209
|
filter(target) {
|
|
2136
|
-
return
|
|
2210
|
+
return PathEvent.filter(target, this);
|
|
2137
2211
|
}
|
|
2138
2212
|
/**
|
|
2139
2213
|
* Create event string from its components
|
|
@@ -2141,29 +2215,37 @@ ${opts.message || this.desc}`;
|
|
|
2141
2215
|
* @return {string} String representation of Event
|
|
2142
2216
|
*/
|
|
2143
2217
|
toString() {
|
|
2144
|
-
return
|
|
2218
|
+
return PathEvent.toString(this.fullPath, this.methods);
|
|
2145
2219
|
}
|
|
2146
|
-
}
|
|
2147
|
-
/** Internal cache for PathEvent instances to avoid redundant parsing */
|
|
2148
|
-
__publicField(_PathEvent, "pathEventCache", /* @__PURE__ */ new Map());
|
|
2149
|
-
let PathEvent = _PathEvent;
|
|
2220
|
+
}
|
|
2150
2221
|
class PathEventEmitter {
|
|
2151
2222
|
constructor(prefix = "") {
|
|
2152
|
-
__publicField(this, "listeners", []);
|
|
2153
2223
|
this.prefix = prefix;
|
|
2154
2224
|
}
|
|
2225
|
+
listeners = [];
|
|
2155
2226
|
emit(event, ...args) {
|
|
2156
2227
|
const parsed = event instanceof PathEvent ? event : new PathEvent(`${this.prefix}/${event}`);
|
|
2157
|
-
this.listeners.filter((l) => PathEvent.has(l[0], parsed)).forEach(
|
|
2228
|
+
this.listeners.filter((l) => PathEvent.has(l[0], parsed)).forEach((l) => l[1](parsed, ...args));
|
|
2158
2229
|
}
|
|
2159
2230
|
off(listener) {
|
|
2160
2231
|
this.listeners = this.listeners.filter((l) => l[1] != listener);
|
|
2161
2232
|
}
|
|
2162
2233
|
on(event, listener) {
|
|
2163
2234
|
makeArray(event).forEach((e) => {
|
|
2164
|
-
|
|
2235
|
+
let fullEvent;
|
|
2236
|
+
if (typeof e === "string") {
|
|
2237
|
+
if (e[0] === ":" && this.prefix) {
|
|
2238
|
+
fullEvent = `${this.prefix}${e}`;
|
|
2239
|
+
} else if (this.prefix) {
|
|
2240
|
+
fullEvent = `${this.prefix}/${e}`;
|
|
2241
|
+
} else {
|
|
2242
|
+
fullEvent = e;
|
|
2243
|
+
}
|
|
2244
|
+
} else {
|
|
2245
|
+
fullEvent = e instanceof PathEvent ? PathEvent.toString(e.fullPath, e.methods) : e;
|
|
2246
|
+
}
|
|
2165
2247
|
this.listeners.push([
|
|
2166
|
-
|
|
2248
|
+
new PathEvent(fullEvent),
|
|
2167
2249
|
listener
|
|
2168
2250
|
]);
|
|
2169
2251
|
});
|
|
@@ -2179,7 +2261,7 @@ ${opts.message || this.desc}`;
|
|
|
2179
2261
|
});
|
|
2180
2262
|
}
|
|
2181
2263
|
relayEvents(emitter) {
|
|
2182
|
-
emitter.on("
|
|
2264
|
+
emitter.on("**", (event, ...args) => this.emit(event, ...args));
|
|
2183
2265
|
}
|
|
2184
2266
|
}
|
|
2185
2267
|
function search(rows, search2, regex, transform = (r) => r) {
|
|
@@ -2209,9 +2291,9 @@ ${opts.message || this.desc}`;
|
|
|
2209
2291
|
case "!=":
|
|
2210
2292
|
return a != b;
|
|
2211
2293
|
case "+=":
|
|
2212
|
-
return a
|
|
2294
|
+
return a?.toString().includes(b);
|
|
2213
2295
|
case "-=":
|
|
2214
|
-
return !
|
|
2296
|
+
return !a?.toString().includes(b);
|
|
2215
2297
|
case ">":
|
|
2216
2298
|
return a > b;
|
|
2217
2299
|
case ">=":
|
|
@@ -2239,176 +2321,193 @@ ${opts.message || this.desc}`;
|
|
|
2239
2321
|
}).length == and.length;
|
|
2240
2322
|
});
|
|
2241
2323
|
}
|
|
2242
|
-
var commonjsGlobal = typeof globalThis !== "undefined" ? globalThis : typeof window !== "undefined" ? window : typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : {};
|
|
2243
2324
|
var dist = {};
|
|
2244
|
-
var persist
|
|
2245
|
-
|
|
2246
|
-
|
|
2247
|
-
|
|
2248
|
-
|
|
2249
|
-
|
|
2250
|
-
|
|
2251
|
-
|
|
2252
|
-
|
|
2253
|
-
|
|
2254
|
-
__publicField(this, "options");
|
|
2325
|
+
var persist = {};
|
|
2326
|
+
var hasRequiredPersist;
|
|
2327
|
+
function requirePersist() {
|
|
2328
|
+
if (hasRequiredPersist) return persist;
|
|
2329
|
+
hasRequiredPersist = 1;
|
|
2330
|
+
Object.defineProperty(persist, "__esModule", { value: true });
|
|
2331
|
+
persist.persist = persist.Persist = void 0;
|
|
2332
|
+
class Persist {
|
|
2333
|
+
key;
|
|
2334
|
+
options;
|
|
2255
2335
|
/** Backend service to store data, must implement `Storage` interface */
|
|
2256
|
-
|
|
2336
|
+
storage;
|
|
2257
2337
|
/** Listeners which should be notified on changes */
|
|
2258
|
-
|
|
2338
|
+
watches = {};
|
|
2259
2339
|
/** Private value field */
|
|
2260
|
-
|
|
2261
|
-
|
|
2262
|
-
|
|
2263
|
-
|
|
2264
|
-
|
|
2265
|
-
|
|
2266
|
-
|
|
2267
|
-
|
|
2268
|
-
|
|
2269
|
-
|
|
2270
|
-
|
|
2271
|
-
|
|
2272
|
-
|
|
2273
|
-
|
|
2274
|
-
|
|
2275
|
-
|
|
2276
|
-
|
|
2277
|
-
|
|
2278
|
-
|
|
2279
|
-
|
|
2280
|
-
|
|
2281
|
-
|
|
2282
|
-
|
|
2340
|
+
_value;
|
|
2341
|
+
/** Current value or default if undefined */
|
|
2342
|
+
get value() {
|
|
2343
|
+
return this._value !== void 0 ? this._value : this.options?.default;
|
|
2344
|
+
}
|
|
2345
|
+
/** Set value with proxy object wrapper to sync future changes */
|
|
2346
|
+
set value(v) {
|
|
2347
|
+
if (v == null || typeof v != "object")
|
|
2348
|
+
this._value = v;
|
|
2349
|
+
else
|
|
2350
|
+
this._value = new Proxy(v, {
|
|
2351
|
+
get: (target, p) => {
|
|
2352
|
+
const f = typeof target[p] == "function";
|
|
2353
|
+
if (!f)
|
|
2354
|
+
return target[p];
|
|
2355
|
+
return (...args) => {
|
|
2356
|
+
const value = target[p](...args);
|
|
2357
|
+
this.save();
|
|
2358
|
+
return value;
|
|
2359
|
+
};
|
|
2360
|
+
},
|
|
2361
|
+
set: (target, p, newValue) => {
|
|
2362
|
+
target[p] = newValue;
|
|
2283
2363
|
this.save();
|
|
2284
|
-
return
|
|
2285
|
-
}
|
|
2364
|
+
return true;
|
|
2365
|
+
}
|
|
2366
|
+
});
|
|
2367
|
+
this.save();
|
|
2368
|
+
}
|
|
2369
|
+
/**
|
|
2370
|
+
* @param {string} key Primary key value will be stored under
|
|
2371
|
+
* @param {PersistOptions<T>} options Configure using {@link PersistOptions}
|
|
2372
|
+
*/
|
|
2373
|
+
constructor(key, options = {}) {
|
|
2374
|
+
this.key = key;
|
|
2375
|
+
this.options = options;
|
|
2376
|
+
this.storage = options.storage || localStorage;
|
|
2377
|
+
this.load();
|
|
2378
|
+
}
|
|
2379
|
+
/** Notify listeners of change */
|
|
2380
|
+
notify(value) {
|
|
2381
|
+
Object.values(this.watches).forEach((watch) => watch(value));
|
|
2382
|
+
}
|
|
2383
|
+
/** Delete value from storage */
|
|
2384
|
+
clear() {
|
|
2385
|
+
this.storage.removeItem(this.key);
|
|
2386
|
+
}
|
|
2387
|
+
/** Save current value to storage */
|
|
2388
|
+
save() {
|
|
2389
|
+
if (this._value === void 0)
|
|
2390
|
+
this.clear();
|
|
2391
|
+
else
|
|
2392
|
+
this.storage.setItem(this.key, JSON.stringify(this._value));
|
|
2393
|
+
this.notify(this.value);
|
|
2394
|
+
}
|
|
2395
|
+
/** Load value from storage */
|
|
2396
|
+
load() {
|
|
2397
|
+
if (this.storage[this.key] != void 0) {
|
|
2398
|
+
let value = JSON.parse(this.storage.getItem(this.key));
|
|
2399
|
+
if (value != null && typeof value == "object" && this.options.type)
|
|
2400
|
+
value.__proto__ = this.options.type.prototype;
|
|
2401
|
+
this.value = value;
|
|
2402
|
+
} else
|
|
2403
|
+
this.value = this.options.default || void 0;
|
|
2404
|
+
}
|
|
2405
|
+
/**
|
|
2406
|
+
* Callback function which is run when there are changes
|
|
2407
|
+
*
|
|
2408
|
+
* @param {(value: T) => any} fn Callback will run on each change; it's passed the next value & it's return is ignored
|
|
2409
|
+
* @returns {() => void} Function which will unsubscribe the watch/callback when called
|
|
2410
|
+
*/
|
|
2411
|
+
watch(fn2) {
|
|
2412
|
+
const index = Object.keys(this.watches).length;
|
|
2413
|
+
this.watches[index] = fn2;
|
|
2414
|
+
return () => {
|
|
2415
|
+
delete this.watches[index];
|
|
2416
|
+
};
|
|
2417
|
+
}
|
|
2418
|
+
/**
|
|
2419
|
+
* Return value as JSON string
|
|
2420
|
+
*
|
|
2421
|
+
* @returns {string} Stringified object as JSON
|
|
2422
|
+
*/
|
|
2423
|
+
toString() {
|
|
2424
|
+
return JSON.stringify(this.value);
|
|
2425
|
+
}
|
|
2426
|
+
/**
|
|
2427
|
+
* Return current value
|
|
2428
|
+
*
|
|
2429
|
+
* @returns {T} Current value
|
|
2430
|
+
*/
|
|
2431
|
+
valueOf() {
|
|
2432
|
+
return this.value;
|
|
2433
|
+
}
|
|
2434
|
+
}
|
|
2435
|
+
persist.Persist = Persist;
|
|
2436
|
+
function persist$1(options) {
|
|
2437
|
+
return (target, prop) => {
|
|
2438
|
+
const key = options?.key || `${target.constructor.name}.${prop.toString()}`;
|
|
2439
|
+
const wrapper = new Persist(key, options);
|
|
2440
|
+
Object.defineProperty(target, prop, {
|
|
2441
|
+
get: function() {
|
|
2442
|
+
return wrapper.value;
|
|
2286
2443
|
},
|
|
2287
|
-
set: (
|
|
2288
|
-
|
|
2289
|
-
this.save();
|
|
2290
|
-
return true;
|
|
2444
|
+
set: function(v) {
|
|
2445
|
+
wrapper.value = v;
|
|
2291
2446
|
}
|
|
2292
2447
|
});
|
|
2293
|
-
this.save();
|
|
2294
|
-
}
|
|
2295
|
-
/** Notify listeners of change */
|
|
2296
|
-
notify(value) {
|
|
2297
|
-
Object.values(this.watches).forEach((watch) => watch(value));
|
|
2298
|
-
}
|
|
2299
|
-
/** Delete value from storage */
|
|
2300
|
-
clear() {
|
|
2301
|
-
this.storage.removeItem(this.key);
|
|
2302
|
-
}
|
|
2303
|
-
/** Save current value to storage */
|
|
2304
|
-
save() {
|
|
2305
|
-
if (this._value === void 0)
|
|
2306
|
-
this.clear();
|
|
2307
|
-
else
|
|
2308
|
-
this.storage.setItem(this.key, JSON.stringify(this._value));
|
|
2309
|
-
this.notify(this.value);
|
|
2310
|
-
}
|
|
2311
|
-
/** Load value from storage */
|
|
2312
|
-
load() {
|
|
2313
|
-
if (this.storage[this.key] != void 0) {
|
|
2314
|
-
let value = JSON.parse(this.storage.getItem(this.key));
|
|
2315
|
-
if (value != null && typeof value == "object" && this.options.type)
|
|
2316
|
-
value.__proto__ = this.options.type.prototype;
|
|
2317
|
-
this.value = value;
|
|
2318
|
-
} else
|
|
2319
|
-
this.value = this.options.default || void 0;
|
|
2320
|
-
}
|
|
2321
|
-
/**
|
|
2322
|
-
* Callback function which is run when there are changes
|
|
2323
|
-
*
|
|
2324
|
-
* @param {(value: T) => any} fn Callback will run on each change; it's passed the next value & it's return is ignored
|
|
2325
|
-
* @returns {() => void} Function which will unsubscribe the watch/callback when called
|
|
2326
|
-
*/
|
|
2327
|
-
watch(fn2) {
|
|
2328
|
-
const index = Object.keys(this.watches).length;
|
|
2329
|
-
this.watches[index] = fn2;
|
|
2330
|
-
return () => {
|
|
2331
|
-
delete this.watches[index];
|
|
2332
2448
|
};
|
|
2333
2449
|
}
|
|
2334
|
-
|
|
2335
|
-
|
|
2336
|
-
*
|
|
2337
|
-
* @returns {string} Stringified object as JSON
|
|
2338
|
-
*/
|
|
2339
|
-
toString() {
|
|
2340
|
-
return JSON.stringify(this.value);
|
|
2341
|
-
}
|
|
2342
|
-
/**
|
|
2343
|
-
* Return current value
|
|
2344
|
-
*
|
|
2345
|
-
* @returns {T} Current value
|
|
2346
|
-
*/
|
|
2347
|
-
valueOf() {
|
|
2348
|
-
return this.value;
|
|
2349
|
-
}
|
|
2350
|
-
}
|
|
2351
|
-
persist$1.Persist = Persist;
|
|
2352
|
-
function persist(options) {
|
|
2353
|
-
return (target, prop) => {
|
|
2354
|
-
const key = (options == null ? void 0 : options.key) || `${target.constructor.name}.${prop.toString()}`;
|
|
2355
|
-
const wrapper = new Persist(key, options);
|
|
2356
|
-
Object.defineProperty(target, prop, {
|
|
2357
|
-
get: function() {
|
|
2358
|
-
return wrapper.value;
|
|
2359
|
-
},
|
|
2360
|
-
set: function(v) {
|
|
2361
|
-
wrapper.value = v;
|
|
2362
|
-
}
|
|
2363
|
-
});
|
|
2364
|
-
};
|
|
2450
|
+
persist.persist = persist$1;
|
|
2451
|
+
return persist;
|
|
2365
2452
|
}
|
|
2366
|
-
persist$1.persist = persist;
|
|
2367
2453
|
var memoryStorage = {};
|
|
2368
|
-
|
|
2369
|
-
|
|
2370
|
-
|
|
2371
|
-
|
|
2372
|
-
|
|
2373
|
-
|
|
2374
|
-
|
|
2375
|
-
|
|
2376
|
-
|
|
2377
|
-
|
|
2378
|
-
|
|
2379
|
-
|
|
2380
|
-
|
|
2381
|
-
|
|
2382
|
-
|
|
2383
|
-
|
|
2384
|
-
|
|
2385
|
-
|
|
2386
|
-
|
|
2387
|
-
|
|
2454
|
+
var hasRequiredMemoryStorage;
|
|
2455
|
+
function requireMemoryStorage() {
|
|
2456
|
+
if (hasRequiredMemoryStorage) return memoryStorage;
|
|
2457
|
+
hasRequiredMemoryStorage = 1;
|
|
2458
|
+
Object.defineProperty(memoryStorage, "__esModule", { value: true });
|
|
2459
|
+
memoryStorage.MemoryStorage = void 0;
|
|
2460
|
+
class MemoryStorage {
|
|
2461
|
+
get length() {
|
|
2462
|
+
return Object.keys(this).length;
|
|
2463
|
+
}
|
|
2464
|
+
clear() {
|
|
2465
|
+
Object.keys(this).forEach((k) => this.removeItem(k));
|
|
2466
|
+
}
|
|
2467
|
+
getItem(key) {
|
|
2468
|
+
return this[key];
|
|
2469
|
+
}
|
|
2470
|
+
key(index) {
|
|
2471
|
+
return Object.keys(this)[index];
|
|
2472
|
+
}
|
|
2473
|
+
removeItem(key) {
|
|
2474
|
+
delete this[key];
|
|
2475
|
+
}
|
|
2476
|
+
setItem(key, value) {
|
|
2477
|
+
this[key] = value;
|
|
2478
|
+
}
|
|
2388
2479
|
}
|
|
2480
|
+
memoryStorage.MemoryStorage = MemoryStorage;
|
|
2481
|
+
return memoryStorage;
|
|
2482
|
+
}
|
|
2483
|
+
var hasRequiredDist;
|
|
2484
|
+
function requireDist() {
|
|
2485
|
+
if (hasRequiredDist) return dist;
|
|
2486
|
+
hasRequiredDist = 1;
|
|
2487
|
+
(function(exports$1) {
|
|
2488
|
+
var __createBinding = dist && dist.__createBinding || (Object.create ? (function(o, m, k, k2) {
|
|
2489
|
+
if (k2 === void 0) k2 = k;
|
|
2490
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
2491
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
2492
|
+
desc = { enumerable: true, get: function() {
|
|
2493
|
+
return m[k];
|
|
2494
|
+
} };
|
|
2495
|
+
}
|
|
2496
|
+
Object.defineProperty(o, k2, desc);
|
|
2497
|
+
}) : (function(o, m, k, k2) {
|
|
2498
|
+
if (k2 === void 0) k2 = k;
|
|
2499
|
+
o[k2] = m[k];
|
|
2500
|
+
}));
|
|
2501
|
+
var __exportStar = dist && dist.__exportStar || function(m, exports$12) {
|
|
2502
|
+
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports$12, p)) __createBinding(exports$12, m, p);
|
|
2503
|
+
};
|
|
2504
|
+
Object.defineProperty(exports$1, "__esModule", { value: true });
|
|
2505
|
+
__exportStar(requirePersist(), exports$1);
|
|
2506
|
+
__exportStar(requireMemoryStorage(), exports$1);
|
|
2507
|
+
})(dist);
|
|
2508
|
+
return dist;
|
|
2389
2509
|
}
|
|
2390
|
-
|
|
2391
|
-
(function(exports$1) {
|
|
2392
|
-
var __createBinding = commonjsGlobal && commonjsGlobal.__createBinding || (Object.create ? function(o, m, k, k2) {
|
|
2393
|
-
if (k2 === void 0) k2 = k;
|
|
2394
|
-
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
2395
|
-
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
2396
|
-
desc = { enumerable: true, get: function() {
|
|
2397
|
-
return m[k];
|
|
2398
|
-
} };
|
|
2399
|
-
}
|
|
2400
|
-
Object.defineProperty(o, k2, desc);
|
|
2401
|
-
} : function(o, m, k, k2) {
|
|
2402
|
-
if (k2 === void 0) k2 = k;
|
|
2403
|
-
o[k2] = m[k];
|
|
2404
|
-
});
|
|
2405
|
-
var __exportStar = commonjsGlobal && commonjsGlobal.__exportStar || function(m, exports$12) {
|
|
2406
|
-
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports$12, p)) __createBinding(exports$12, m, p);
|
|
2407
|
-
};
|
|
2408
|
-
Object.defineProperty(exports$1, "__esModule", { value: true });
|
|
2409
|
-
__exportStar(persist$1, exports$1);
|
|
2410
|
-
__exportStar(memoryStorage, exports$1);
|
|
2411
|
-
})(dist);
|
|
2510
|
+
requireDist();
|
|
2412
2511
|
exports2.ASet = ASet;
|
|
2413
2512
|
exports2.ArgParser = ArgParser;
|
|
2414
2513
|
exports2.BadGatewayError = BadGatewayError;
|
|
@@ -2521,5 +2620,5 @@ ${opts.message || this.desc}`;
|
|
|
2521
2620
|
exports2.validateEmail = validateEmail;
|
|
2522
2621
|
exports2.wordSegments = wordSegments;
|
|
2523
2622
|
Object.defineProperty(exports2, Symbol.toStringTag, { value: "Module" });
|
|
2524
|
-
});
|
|
2623
|
+
}));
|
|
2525
2624
|
//# sourceMappingURL=index.cjs.map
|