@ztimson/momentum 0.42.3 → 0.44.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.mjs CHANGED
@@ -34,6 +34,100 @@ function Lt(r, t) {
34
34
  function ft(r) {
35
35
  return Array.isArray(r) ? r : [r];
36
36
  }
37
+ class B extends Array {
38
+ /** Number of elements in set */
39
+ get size() {
40
+ return this.length;
41
+ }
42
+ /**
43
+ * Array to create set from, duplicate values will be removed
44
+ * @param {T[]} elements Elements which will be added to set
45
+ */
46
+ constructor(t = []) {
47
+ super(), t != null && t.forEach && t.forEach((e) => this.add(e));
48
+ }
49
+ /**
50
+ * Add elements to set if unique
51
+ * @param items
52
+ */
53
+ add(...t) {
54
+ t.filter((e) => !this.has(e)).forEach((e) => this.push(e));
55
+ }
56
+ /**
57
+ * Delete elements from set
58
+ * @param items Elements that will be deleted
59
+ */
60
+ delete(...t) {
61
+ t.forEach((e) => {
62
+ const n = this.indexOf(e);
63
+ n != -1 && this.slice(n, 1);
64
+ });
65
+ }
66
+ /**
67
+ * Create list of elements this set has which the comparison set does not
68
+ * @param {ASet<T>} set Set to compare against
69
+ * @return {ASet<T>} Different elements
70
+ */
71
+ difference(t) {
72
+ return new B(this.filter((e) => !t.has(e)));
73
+ }
74
+ /**
75
+ * Check if set includes element
76
+ * @param {T} el Element to look for
77
+ * @return {boolean} True if element was found, false otherwise
78
+ */
79
+ has(t) {
80
+ return this.indexOf(t) != -1;
81
+ }
82
+ /**
83
+ * Create list of elements this set has in common with the comparison set
84
+ * @param {ASet<T>} set Set to compare against
85
+ * @return {boolean} Set of common elements
86
+ */
87
+ intersection(t) {
88
+ return new B(this.filter((e) => t.has(e)));
89
+ }
90
+ /**
91
+ * Check if this set has no elements in common with the comparison set
92
+ * @param {ASet<T>} set Set to compare against
93
+ * @return {boolean} True if nothing in common, false otherwise
94
+ */
95
+ isDisjointFrom(t) {
96
+ return this.intersection(t).size == 0;
97
+ }
98
+ /**
99
+ * Check if all elements in this set are included in the comparison set
100
+ * @param {ASet<T>} set Set to compare against
101
+ * @return {boolean} True if all elements are included, false otherwise
102
+ */
103
+ isSubsetOf(t) {
104
+ return this.findIndex((e) => !t.has(e)) == -1;
105
+ }
106
+ /**
107
+ * Check if all elements from comparison set are included in this set
108
+ * @param {ASet<T>} set Set to compare against
109
+ * @return {boolean} True if all elements are included, false otherwise
110
+ */
111
+ isSuperset(t) {
112
+ return t.findIndex((e) => !this.has(e)) == -1;
113
+ }
114
+ /**
115
+ * Create list of elements that are only in one set but not both (XOR)
116
+ * @param {ASet<T>} set Set to compare against
117
+ * @return {ASet<T>} New set of unique elements
118
+ */
119
+ symmetricDifference(t) {
120
+ return new B([...this.difference(t), ...t.difference(this)]);
121
+ }
122
+ /**
123
+ * Create joined list of elements included in this & the comparison set
124
+ * @param {ASet<T>} set Set join
125
+ * @return {ASet<T>} New set of both previous sets combined
126
+ */
127
+ union(t) {
128
+ return new B([...this, ...t]);
129
+ }
130
+ }
37
131
  class Dt {
38
132
  /**
39
133
  * Create new cache
@@ -190,6 +284,11 @@ function Ut(r = {}) {
190
284
  }, document.body.appendChild(e), e.click();
191
285
  });
192
286
  }
287
+ function qt(r, t = /* @__PURE__ */ new Date()) {
288
+ (typeof t == "number" || typeof t == "string") && (t = new Date(t));
289
+ const e = `${t.getFullYear()}-${(t.getMonth() + 1).toString().padStart(2, "0")}-${t.getDate().toString().padStart(2, "0")}_${t.getHours().toString().padStart(2, "0")}-${t.getMinutes().toString().padStart(2, "0")}-${t.getSeconds().toString().padStart(2, "0")}`;
290
+ return e;
291
+ }
193
292
  function Ft(r) {
194
293
  return new E((t, e, n) => {
195
294
  const s = new XMLHttpRequest(), o = new FormData();
@@ -448,7 +547,7 @@ const x = {
448
547
  BLINK: "\x1B[5m",
449
548
  REVERSE: "\x1B[7m",
450
549
  HIDDEN: "\x1B[8m"
451
- }, j = {
550
+ }, $ = {
452
551
  BLACK: "\x1B[30m",
453
552
  RED: "\x1B[31m",
454
553
  GREEN: "\x1B[32m",
@@ -484,7 +583,7 @@ const g = class g2 extends _ {
484
583
  debug(...t) {
485
584
  if (g2.LOG_LEVEL < 4) return;
486
585
  const e = this.format(...t);
487
- g2.emit(4, e), console.debug(j.LIGHT_GREY + e + x.CLEAR);
586
+ g2.emit(4, e), console.debug($.LIGHT_GREY + e + x.CLEAR);
488
587
  }
489
588
  log(...t) {
490
589
  if (g2.LOG_LEVEL < 3) return;
@@ -494,21 +593,21 @@ const g = class g2 extends _ {
494
593
  info(...t) {
495
594
  if (g2.LOG_LEVEL < 2) return;
496
595
  const e = this.format(...t);
497
- g2.emit(2, e), console.info(j.BLUE + e + x.CLEAR);
596
+ g2.emit(2, e), console.info($.BLUE + e + x.CLEAR);
498
597
  }
499
598
  warn(...t) {
500
599
  if (g2.LOG_LEVEL < 1) return;
501
600
  const e = this.format(...t);
502
- g2.emit(1, e), console.warn(j.YELLOW + e + x.CLEAR);
601
+ g2.emit(1, e), console.warn($.YELLOW + e + x.CLEAR);
503
602
  }
504
603
  error(...t) {
505
604
  if (g2.LOG_LEVEL < 0) return;
506
605
  const e = this.format(...t);
507
- g2.emit(0, e), console.error(j.RED + e + x.CLEAR);
606
+ g2.emit(0, e), console.error($.RED + e + x.CLEAR);
508
607
  }
509
608
  };
510
609
  c(g, "LOG_LEVEL", 4);
511
- var $ = typeof globalThis < "u" ? globalThis : typeof window < "u" ? window : typeof global < "u" ? global : typeof self < "u" ? self : {}, xt = {}, S = {};
610
+ var j = typeof globalThis < "u" ? globalThis : typeof window < "u" ? window : typeof global < "u" ? global : typeof self < "u" ? self : {}, xt = {}, S = {};
512
611
  Object.defineProperty(S, "__esModule", { value: true });
513
612
  S.persist = S.Persist = void 0;
514
613
  class st {
@@ -628,7 +727,7 @@ class At {
628
727
  }
629
728
  L.MemoryStorage = At;
630
729
  (function(r) {
631
- var t = $ && $.__createBinding || (Object.create ? function(n, s, o, i) {
730
+ var t = j && j.__createBinding || (Object.create ? function(n, s, o, i) {
632
731
  i === void 0 && (i = o);
633
732
  var a = Object.getOwnPropertyDescriptor(s, o);
634
733
  (!a || ("get" in a ? !s.__esModule : a.writable || a.configurable)) && (a = { enumerable: true, get: function() {
@@ -636,22 +735,120 @@ L.MemoryStorage = At;
636
735
  } }), Object.defineProperty(n, i, a);
637
736
  } : function(n, s, o, i) {
638
737
  i === void 0 && (i = o), n[i] = s[o];
639
- }), e = $ && $.__exportStar || function(n, s) {
738
+ }), e = j && j.__exportStar || function(n, s) {
640
739
  for (var o in n) o !== "default" && !Object.prototype.hasOwnProperty.call(s, o) && t(s, n, o);
641
740
  };
642
741
  Object.defineProperty(r, "__esModule", { value: true }), e(S, r), e(L, r);
643
742
  })(xt);
743
+ function combinePathedEvents(...paths) {
744
+ let hitNone = false;
745
+ const combined = paths.map((p2) => typeof p2 == "string" ? parsePathedEvent(p2) : p2).toSorted((p1, p2) => {
746
+ const l1 = p1.fullPath.length, l2 = p2.fullPath.length;
747
+ return l1 < l2 ? 1 : l1 > l2 ? -1 : 0;
748
+ }).reduce((acc, p2) => {
749
+ if (p2.none) hitNone = true;
750
+ if (!acc) return p2;
751
+ if (hitNone) return acc;
752
+ if (p2.all) acc.all = true;
753
+ if (p2.all || p2.create) acc.create = true;
754
+ if (p2.all || p2.read) acc.read = true;
755
+ if (p2.all || p2.update) acc.update = true;
756
+ if (p2.all || p2.delete) acc.delete = true;
757
+ if (p2.all || p2.execute) acc.execute = true;
758
+ acc.methods = [...acc.methods, ...p2.methods];
759
+ return acc;
760
+ }, null);
761
+ if (combined.all) combined.methods = ["*"];
762
+ if (combined.none) combined.methods = ["n"];
763
+ combined.methods = new B(combined.methods);
764
+ combined.full = pathedEvent(combined.fullPath, ...combined.methods);
765
+ return combined;
766
+ }
767
+ function hasPath(target, ...anyPath) {
768
+ const parsedRequired = anyPath.map(parsePathedEvent);
769
+ const parsedTarget = ft(target).map(parsePathedEvent);
770
+ return !!parsedRequired.find((r) => {
771
+ if (r.all) return true;
772
+ const filtered = parsedTarget.filter((p2) => r.fullPath.startsWith(p2.fullPath));
773
+ if (!filtered.length) return false;
774
+ const combined = combinePathedEvents(...filtered);
775
+ return !combined.none && (combined.all || new B(combined.methods).intersection(new B(r.methods)).length);
776
+ });
777
+ }
778
+ function hasPathFatal(target, ...paths) {
779
+ if (!hasPath(target, ...paths)) throw new Error(`Missing permission: ${paths.join(", ")}`);
780
+ }
781
+ function pathedEvent(path, ...methods) {
782
+ var _a;
783
+ let p2 = ft(path).map((p22) => p22 == null ? void 0 : p22.toString()).filter((p22) => !!p22).map((p22) => p22 == null ? void 0 : p22.replaceAll(/(^\/|\/$)/g, "")).join("/");
784
+ if (methods.length) p2 += `:${methods.join("")}`;
785
+ return (_a = p2 == null ? void 0 : p2.replaceAll("//", "/")) == null ? void 0 : _a.trim();
786
+ }
787
+ function parsePathedEvent(path) {
788
+ var _a;
789
+ if (typeof path == "object") return path;
790
+ let [p2, scope, method] = path.split(":");
791
+ if (!method) method = scope || "*";
792
+ if (p2 == "*" || !p2 && method == "*") {
793
+ p2 = "";
794
+ method = "*";
795
+ }
796
+ let temp = p2.split("/").filter((p22) => !!p22);
797
+ return {
798
+ full: path,
799
+ module: ((_a = temp.splice(0, 1)[0]) == null ? void 0 : _a.toLowerCase()) || "",
800
+ fullPath: p2,
801
+ path: temp.join("/"),
802
+ methods: method.split(""),
803
+ all: method == null ? void 0 : method.includes("*"),
804
+ none: method == null ? void 0 : method.includes("n"),
805
+ create: !(method == null ? void 0 : method.includes("n")) && ((method == null ? void 0 : method.includes("*")) || (method == null ? void 0 : method.includes("w")) || (method == null ? void 0 : method.includes("c"))),
806
+ read: !(method == null ? void 0 : method.includes("n")) && ((method == null ? void 0 : method.includes("*")) || (method == null ? void 0 : method.includes("r"))),
807
+ update: !(method == null ? void 0 : method.includes("n")) && ((method == null ? void 0 : method.includes("*")) || (method == null ? void 0 : method.includes("w")) || (method == null ? void 0 : method.includes("u"))),
808
+ delete: !(method == null ? void 0 : method.includes("n")) && ((method == null ? void 0 : method.includes("*")) || (method == null ? void 0 : method.includes("w")) || (method == null ? void 0 : method.includes("d"))),
809
+ execute: !(method == null ? void 0 : method.includes("n")) && ((method == null ? void 0 : method.includes("*")) || (method == null ? void 0 : method.includes("x")))
810
+ };
811
+ }
812
+ class PathedEventEmitter {
813
+ constructor() {
814
+ __publicField(this, "listeners", []);
815
+ }
816
+ emit(event, ...args) {
817
+ const parsed = parsePathedEvent(event);
818
+ this.listeners.filter((l) => hasPath(l[0], event)).forEach((l) => l[1](parsed, ...args));
819
+ }
820
+ off(listener) {
821
+ this.listeners = this.listeners.filter((l) => l[1] != listener);
822
+ }
823
+ on(event, listener) {
824
+ ft(event).forEach((e) => this.listeners.push([parsePathedEvent(e), listener]));
825
+ return () => this.off(listener);
826
+ }
827
+ once(event, listener) {
828
+ return new Promise((res) => {
829
+ const unsubscribe = this.on(event, (event2, ...args) => {
830
+ res(args);
831
+ if (listener) listener(event2, ...args);
832
+ unsubscribe();
833
+ });
834
+ });
835
+ }
836
+ relayEvents(emitter) {
837
+ emitter.on("*", (event, ...args) => this.emit(event, ...args));
838
+ }
839
+ }
644
840
  class Api extends F {
645
841
  constructor(url = location.origin, opts = {}) {
646
842
  opts.url = url;
647
843
  super(opts);
648
- __publicField(this, "emitter", new _());
844
+ __publicField(this, "emitter", new PathedEventEmitter());
649
845
  __publicField(this, "pending", {});
650
846
  __publicField(this, "_token", null);
651
847
  __publicField(this, "emit", this.emitter.emit.bind(this.emitter));
652
848
  __publicField(this, "off", this.emitter.off.bind(this.emitter));
653
849
  __publicField(this, "on", this.emitter.on.bind(this.emitter));
654
850
  __publicField(this, "once", this.emitter.once.bind(this.emitter));
851
+ __publicField(this, "relayEvents", this.emitter.relayEvents.bind(this.emitter));
655
852
  this.url = url;
656
853
  this.opts = opts;
657
854
  }
@@ -662,26 +859,27 @@ class Api extends F {
662
859
  if (token == this._token) return;
663
860
  this._token = token;
664
861
  this.headers["Authorization"] = token ? `Bearer ${token}` : null;
665
- this.emit("token", token);
862
+ this.emit(pathedEvent("api/token", "u"), token);
666
863
  }
667
864
  healthcheck() {
668
- return this.request({ url: "/api/healthcheck" });
669
- }
670
- path(...children) {
671
- return children.filter((p2) => !!p2).join("/").replaceAll("//", "/");
865
+ return this.request({ url: "/api/healthcheck" }).then((resp) => {
866
+ this.emit(pathedEvent("api/healthcheck", "r"), resp);
867
+ return resp;
868
+ });
672
869
  }
673
870
  request(options) {
674
871
  const key = Lt(options);
872
+ const method = options.method == "GET" ? "r" : options.method == "POST" ? "c" : options.method == "DELETE" ? "d" : "u";
675
873
  if (this.pending[key] != null) return this.pending[key];
676
874
  this.pending[key] = super.request(options).then((resp) => {
677
- this.emit("response", resp, options);
875
+ this.emit(pathedEvent("api/response", method), resp, options);
678
876
  return resp.data;
679
877
  }).catch((err) => {
680
878
  const e = (err == null ? void 0 : err.data) || err;
681
- this.emit("rejected", e, options);
879
+ this.emit(pathedEvent("api/error", method), e, options);
682
880
  throw e;
683
881
  }).finally(() => delete this.pending[key]);
684
- this.emit("request", this.pending[key], options);
882
+ this.emit(pathedEvent("api/request", method), this.pending[key], options);
685
883
  return this.pending[key];
686
884
  }
687
885
  }
@@ -695,7 +893,7 @@ var ActionType = /* @__PURE__ */ ((ActionType2) => {
695
893
  ActionType2[ActionType2["PUT"] = 6] = "PUT";
696
894
  return ActionType2;
697
895
  })(ActionType || {});
698
- class Actions extends _ {
896
+ class Actions extends PathedEventEmitter {
699
897
  constructor(api) {
700
898
  super();
701
899
  __publicField(this, "api");
@@ -703,80 +901,86 @@ class Actions extends _ {
703
901
  this.api = typeof api == "string" ? new Api(api) : api;
704
902
  }
705
903
  delete(id) {
706
- return this.api.request({ url: `/api/actions/${id}`, method: "DELETE" }).then(() => {
904
+ if (!id) throw new Error("Cannot delete action, missing ID");
905
+ return this.api.request({ url: `/api/` + pathedEvent(["actions", id]), method: "DELETE" }).then(() => {
707
906
  this.cache.delete(id);
708
- this.emit("delete", id);
907
+ this.emit(pathedEvent(["actions", id], "d"), id);
709
908
  });
710
909
  }
711
910
  all() {
712
911
  return this.api.request({ url: `/api/actions` }).then((resp) => {
713
912
  this.cache.addAll(resp);
714
- this.emit("all", resp || []);
913
+ this.emit(pathedEvent("actions", "r"), resp || []);
715
914
  return resp;
716
915
  });
717
916
  }
718
917
  read(id, reload = false) {
918
+ if (!id) throw new Error("Cannot read action, missing ID");
719
919
  const cached = this.cache.get(id);
720
920
  if (!reload && cached) return Promise.resolve(cached);
721
- return this.api.request({ url: `/api/actions/${id}` }).then((action) => {
921
+ return this.api.request({ url: `/api/` + pathedEvent(["actions", id]) }).then((action) => {
722
922
  if (action) this.cache.add(action);
723
- this.emit("read", action);
923
+ this.emit(pathedEvent(["actions", id], "r"), action);
724
924
  return action;
725
925
  });
726
926
  }
727
927
  run(path, opts = {}) {
728
- return this.api.request({ url: (`/api/actions/run/` + path).replaceAll("//", "/"), ...opts }).then((resp) => {
729
- this.emit("execute", path, resp);
928
+ if (!path) throw new Error("Cannot run action, missing path");
929
+ return this.api.request({ url: `/api/` + pathedEvent(["actions/run", path]), ...opts }).then((resp) => {
930
+ this.emit(pathedEvent(["actions/run", path], "x"), resp);
730
931
  return resp;
731
932
  });
732
933
  }
733
934
  runById(action, opts = {}) {
734
- const id = typeof action == "string" ? action : action._id;
735
- return this.api.request({ url: "/api/actions/run-by-id/" + id, method: "POST", ...opts }).then((resp) => {
736
- this.emit("execute", typeof action == "string" ? action : action._id, resp);
935
+ const id = typeof action == "string" ? action : action == null ? void 0 : action._id;
936
+ if (!id) throw new Error("Cannot run action, missing ID");
937
+ return this.api.request({ url: "/api/" + pathedEvent(["actions/run-by-id", id]), method: "POST", ...opts }).then((resp) => {
938
+ this.emit(pathedEvent(["actions/run-by-id", id], "x"), resp);
737
939
  return resp;
738
940
  });
739
941
  }
740
942
  update(action) {
741
943
  return this.api.request({
742
- url: `/api/actions${action._id ? `/${action._id}` : ""}`,
944
+ url: `/api/` + pathedEvent(["actions", action._id]),
743
945
  method: "POST",
744
946
  body: action
745
947
  }).then((action2) => {
746
948
  if (action2) this.cache.add(action2);
747
- this.emit("update", action2);
949
+ this.emit(pathedEvent(["actions", action2._id], "u"), action2);
748
950
  return action2;
749
951
  });
750
952
  }
751
953
  }
752
- class Ai extends _ {
954
+ class Ai extends PathedEventEmitter {
753
955
  constructor(api) {
754
956
  super();
755
957
  __publicField(this, "api");
756
958
  this.api = typeof api == "string" ? new Api(api) : api;
757
959
  }
758
960
  ask(question, context) {
961
+ if (!question) throw new Error("Cannot ask AI, missing question");
759
962
  return this.api.request({ url: `/api/ai`, method: "POST", body: {
760
963
  question,
761
964
  context
762
965
  } }).then((resp) => {
763
- this.emit("ask", question, context, resp);
966
+ this.emit(pathedEvent("ai", "c"), question, context, resp);
764
967
  return resp;
765
968
  });
766
969
  }
767
970
  clear() {
768
- return this.api.request({ url: "/api/ai", method: "DELETE" });
971
+ return this.api.request({ url: "/api/ai", method: "DELETE" }).then(() => this.emit(pathedEvent("ai", "d")));
769
972
  }
770
973
  }
771
- class Analytics extends _ {
974
+ class Analytics extends PathedEventEmitter {
772
975
  constructor(api) {
773
976
  super();
774
977
  __publicField(this, "api");
775
978
  this.api = typeof api == "string" ? new Api(api) : api;
776
979
  }
777
980
  ipTrace(ip) {
981
+ if (!ip) throw new Error("Cannot trace, missing IP");
778
982
  return this.api.request({ url: `/api/analytics/trace?ip=${ip}` }).then((resp) => {
779
- this.emit("ipTrace", ip, resp);
983
+ this.emit(pathedEvent("analytics/trace", "r"), ip, resp);
780
984
  return resp;
781
985
  });
782
986
  }
@@ -799,7 +1003,7 @@ class Totp {
799
1003
  }) });
800
1004
  }
801
1005
  }
802
- class Auth extends _ {
1006
+ class Auth extends PathedEventEmitter {
803
1007
  constructor(api, opts = {}) {
804
1008
  super();
805
1009
  __publicField(this, "api");
@@ -822,10 +1026,10 @@ class Auth extends _ {
822
1026
  "/api/auth/totp"
823
1027
  ];
824
1028
  if (resp.status == 401 && !blacklist.find((url) => resp.url.includes(url)))
825
- this.emit("sessionExpired");
1029
+ this.emit(pathedEvent("auth/session-expired", "d"));
826
1030
  next();
827
1031
  });
828
- this.api.on("token", (token) => {
1032
+ this.api.on("api/token", (event, token) => {
829
1033
  var _a;
830
1034
  if ((_a = this.opts) == null ? void 0 : _a.persist) {
831
1035
  if (token) localStorage.setItem(this.storageKey, token);
@@ -849,15 +1053,18 @@ class Auth extends _ {
849
1053
  set user(user) {
850
1054
  if (!A(this.user, user)) {
851
1055
  this._user = user ? user : null;
852
- this.emit("user", this._user);
1056
+ this.emit(pathedEvent("auth/user", "u"), this._user);
853
1057
  }
854
1058
  }
855
1059
  knownHost(host = location.origin) {
856
1060
  if (host.startsWith("/")) return Promise.resolve();
857
- return this.api.request({ url: `/api/auth/known-host?host=${encodeURI(new URL(host).origin)}` }).then(() => {
1061
+ return this.api.request({ url: `/api/auth/known-host?host=${encodeURI(new URL(host).origin)}` }).then(() => this.emit(pathedEvent("auth/known-host", "r"), host, true)).catch((err) => {
1062
+ this.emit(pathedEvent("auth/known-host", "r"), host, false);
1063
+ throw err;
858
1064
  });
859
1065
  }
860
1066
  login(username, password, totp) {
1067
+ if (!username || !password) throw new Error("Cannot login, missing username or password");
861
1068
  return this.api.request({
862
1069
  url: "/api/auth/login",
863
1070
  headers: { Authorization: void 0 },
@@ -869,8 +1076,8 @@ class Auth extends _ {
869
1076
  }
870
1077
  }).then(async (resp) => {
871
1078
  this.api.token = (resp == null ? void 0 : resp.token) || null;
872
- const user = await this.once("user");
873
- this.emit("login", user);
1079
+ const user = await this.once("auth/user");
1080
+ this.emit(pathedEvent(["auth/login", username], "x"), user);
874
1081
  return user;
875
1082
  });
876
1083
  }
@@ -893,16 +1100,18 @@ class Auth extends _ {
893
1100
  logout() {
894
1101
  this.api.token = null;
895
1102
  this.user = null;
896
- this.emit("logout");
1103
+ this.emit(pathedEvent("auth/logout", "d"));
897
1104
  }
898
1105
  async register(u) {
899
1106
  var _a;
1107
+ if (!u.username || !u.password) throw new Error("Cannot register user, missing username or password");
900
1108
  const user = await this.api.request({ url: "/api/auth/register", body: { ...u } });
901
1109
  if ((_a = user == null ? void 0 : user.image) == null ? void 0 : _a.startsWith("/")) user.image = `${this.api.url}${user.image}?token=${this.api.token}`;
902
- this.emit("register", user);
1110
+ this.emit(pathedEvent("auth/register", "c"), user);
903
1111
  return user;
904
1112
  }
905
1113
  reset(emailOrPass, token) {
1114
+ if (!emailOrPass) throw new Error("Cannot reset password, missing email or token");
906
1115
  return this.api.request({
907
1116
  url: "/api/auth/reset",
908
1117
  headers: { "Authorization": token ? `Bearer ${token}` : void 0 },
@@ -911,8 +1120,7 @@ class Auth extends _ {
911
1120
  password: token ? emailOrPass : void 0
912
1121
  }
913
1122
  }).then(() => {
914
- if (token) this.emit("reset", token);
915
- else this.emit("resetRequest", emailOrPass);
1123
+ this.emit(pathedEvent("auth/reset", token ? "u" : "c"), token || emailOrPass);
916
1124
  });
917
1125
  }
918
1126
  async session(token, set = false) {
@@ -921,25 +1129,29 @@ class Auth extends _ {
921
1129
  url: "/api/auth/session",
922
1130
  headers: token ? { "Authorization": `Bearer ${token}` } : void 0
923
1131
  });
1132
+ this.emit(pathedEvent("auth/session", "r"), session);
924
1133
  if (set) {
925
1134
  this.api.token = token;
926
1135
  if (session == null ? void 0 : session.user) session.user.image = `${this.api.url}${session.user.image}?token=${this.api.token}`;
927
1136
  this.user = (session == null ? void 0 : session.user) || null;
928
- if (session) this.emit("login", session.user);
1137
+ if (session) this.emit(pathedEvent("auth/login", "c"), session.user);
929
1138
  }
930
1139
  return session;
931
1140
  }
932
1141
  async updatePassword(username, password, oldPassword) {
1142
+ if (!username || !password) throw new Error("Cannot update password, missing username or password");
933
1143
  return this.api.request({
934
1144
  url: "/api/auth/password",
935
1145
  body: { username, password, oldPassword }
936
1146
  }).then((resp) => {
1147
+ this.emit(pathedEvent("auth/reset", "u"), resp == null ? void 0 : resp.token);
937
1148
  if (resp == null ? void 0 : resp.token) this.api.token = resp.token;
938
1149
  });
939
1150
  }
940
1151
  }
941
- class Client {
1152
+ class Client extends PathedEventEmitter {
942
1153
  constructor(settings) {
1154
+ super();
943
1155
  __publicField(this, "_platform");
944
1156
  __publicField(this, "_pwa");
945
1157
  this.settings = settings;
@@ -966,7 +1178,7 @@ class Client {
966
1178
  }
967
1179
  async inject(reload = false) {
968
1180
  var _a, _b, _c, _d, _e, _f, _g, _h;
969
- const settings = await this.settings.all();
1181
+ const settings = await this.settings.all(false, reload);
970
1182
  if (!document.querySelector('meta[name="mobile-web-app-capable"]')) {
971
1183
  const meta = document.createElement("meta");
972
1184
  meta.name = "mobile-web-app-capable";
@@ -1038,6 +1250,7 @@ class Client {
1038
1250
  if (!dismissed && !this.pwa && this.mobile) this.pwaPrompt();
1039
1251
  }, 500);
1040
1252
  }
1253
+ this.emit(pathedEvent("client/inject", "c"));
1041
1254
  }
1042
1255
  pwaPrompt(platform) {
1043
1256
  const url = this.settings.api.url;
@@ -1154,88 +1367,101 @@ class Client {
1154
1367
  setTimeout(() => {
1155
1368
  prompt.remove();
1156
1369
  backdrop.remove();
1370
+ this.emit(pathedEvent("client/pwa", "d"), platform);
1157
1371
  }, 500);
1158
1372
  };
1159
1373
  prompt.append(close);
1160
1374
  backdrop.append(prompt);
1161
1375
  document.body.append(backdrop);
1376
+ this.emit(pathedEvent("client/pwa", "c"), platform);
1162
1377
  }
1163
1378
  }
1164
- class Data extends _ {
1379
+ class Data extends PathedEventEmitter {
1165
1380
  constructor(api) {
1166
1381
  super();
1167
1382
  __publicField(this, "api");
1168
1383
  this.api = typeof api == "string" ? new Api(api) : api;
1169
1384
  }
1170
1385
  create(collection, document2) {
1386
+ if (!collection || !document2) throw new Error("Cannot create document, missing collection or document");
1171
1387
  return this.api.request({
1172
- url: `/api/data/${collection.replaceAll(/(^\/|\/$)/g, "")}`,
1388
+ url: `/api/` + pathedEvent(["data", collection]),
1173
1389
  method: "POST",
1174
1390
  body: document2
1175
1391
  }).then((resp) => {
1176
- this.emit("create", collection, resp);
1392
+ this.emit(pathedEvent(["data", collection], "c"), collection, resp);
1177
1393
  return resp;
1178
1394
  });
1179
1395
  }
1180
1396
  read(collection, id) {
1181
- return this.api.request({ url: `/api/data/${collection.replaceAll(/(^\/|\/$)/g, "")}/${id ?? ""}` }).then((resp) => {
1182
- this.emit("read", collection, resp);
1397
+ if (!collection) throw new Error("Cannot read documents, missing collection");
1398
+ return this.api.request({ url: `/api/` + pathedEvent(["data", collection, id]) }).then((resp) => {
1399
+ this.emit(pathedEvent(["data", collection, id], "r"), collection, resp);
1183
1400
  return resp;
1184
1401
  });
1185
1402
  }
1186
1403
  update(collection, document2, append = true) {
1404
+ if (!collection || !document2) throw new Error("Cannot update document, missing collection or document");
1187
1405
  if (!document2._id) return this.create(collection, document2);
1188
1406
  return this.api.request({
1189
- url: `/api/data/${collection.replaceAll(/(^\/|\/$)/g, "")}/${document2._id}`,
1407
+ url: `/api/` + pathedEvent(["data", collection, document2._id]),
1190
1408
  method: append ? "PATCH" : "PUT",
1191
1409
  body: document2
1192
1410
  }).then((resp) => {
1193
- this.emit("update", collection, resp);
1411
+ this.emit(pathedEvent(["data", collection, document2._id], "u"), collection, resp);
1194
1412
  return resp;
1195
1413
  });
1196
1414
  }
1197
1415
  delete(collection, id) {
1416
+ if (!collection || !id) throw new Error("Cannot delete document, missing collection or ID");
1198
1417
  return this.api.request({
1199
- url: `/api/data/${collection.replaceAll(/(^\/|\/$)/g, "")}/${id}`,
1418
+ url: `/api/` + pathedEvent(["data", collection, id]),
1200
1419
  method: "DELETE"
1201
- }).then(() => this.emit("delete", collection, id));
1420
+ }).then(() => this.emit(pathedEvent(["data", collection, id], "d"), collection, id));
1202
1421
  }
1203
1422
  raw(collection, query) {
1204
- return this.api.request({ url: `/api/data/${collection.replaceAll(/(^\/|\/$)/g, "")}`, body: query }).then((resp) => {
1205
- this.emit("raw", collection, query, resp);
1423
+ if (!collection || !query) throw new Error("Cannot execute raw query, missing collection or query");
1424
+ const mode = query.operand.startsWith("find") ? "r" : query.operand == "insert" ? "c" : query.operand.startsWith("delete") ? "d" : "u";
1425
+ return this.api.request({ url: `/api/` + pathedEvent(["data/raw", collection]) + "?raw", body: query }).then((resp) => {
1426
+ this.emit(pathedEvent(["data", collection], mode), collection, query, resp);
1206
1427
  return resp;
1207
1428
  });
1208
1429
  }
1209
- deleteSchema(collection) {
1210
- return this.api.request({ url: `/api/data/schema/${collection.replaceAll(/(^\/|\/$)/g, "")}`, method: "DELETE" });
1430
+ deleteSchema(path) {
1431
+ if (!path) throw new Error("Cannot delete schema, missing collection path");
1432
+ return this.api.request({ url: `/api/` + pathedEvent(["schema", path]), method: "DELETE" }).then(() => this.emit(pathedEvent(["schema", path], "d"), path));
1211
1433
  }
1212
1434
  getSchema(pathOrTree) {
1213
- let url = "/api/data/schema";
1214
- if (typeof pathOrTree == "string") url += `/${pathOrTree.replaceAll(/(^\/|\/$)/g, "")}`;
1215
- else if (typeof pathOrTree == "boolean") url += `?tree=${pathOrTree}`;
1216
- return this.api.request({ url });
1435
+ return this.api.request({ url: "/api/" + pathedEvent(["schema", typeof pathOrTree == "string" ? pathOrTree : ""]) + (pathOrTree === true ? `?tree=${pathOrTree}` : "") }).then((resp) => {
1436
+ this.emit(pathedEvent(["schema", typeof pathOrTree == "string" ? pathOrTree : ""], "r"), resp);
1437
+ return resp;
1438
+ });
1217
1439
  }
1218
1440
  setSchema(schema) {
1219
- if (!schema.path) throw new Error("Unable to create schema, missing path");
1220
- return this.api.request({ url: `/api/data/schema/${schema.path.replaceAll(/(^\/|\/$)/g, "")}`, body: schema });
1441
+ if (!schema.path) throw new Error("Cannot update schema, missing collection path");
1442
+ return this.api.request({ url: "/api/" + pathedEvent(["schema", schema.path]), body: schema }).then((resp) => {
1443
+ this.emit(pathedEvent(["schema", schema.path], schema._id ? "u" : "c"), resp);
1444
+ return resp;
1445
+ });
1221
1446
  }
1222
1447
  }
1223
- class Email extends _ {
1448
+ class Email extends PathedEventEmitter {
1224
1449
  constructor(api) {
1225
1450
  super();
1226
1451
  __publicField(this, "api");
1227
1452
  this.api = typeof api == "string" ? new Api(api) : api;
1228
1453
  }
1229
1454
  send(email) {
1230
- let url = "/api/email";
1231
- if (typeof email.body == "object") url += `/${email.body.template}`;
1232
- return this.api.request({ url, body: email }).then((resp) => {
1233
- this.emit("sent", email, resp);
1455
+ var _a;
1456
+ if (!email.to && !email.bcc || !email.body) throw new Error("Cannot send email, missing address or body");
1457
+ return this.api.request({ url: "/api/" + pathedEvent(["email", (_a = email.body) == null ? void 0 : _a.template]), body: email }).then((resp) => {
1458
+ var _a2;
1459
+ this.emit(pathedEvent(["email", (_a2 = email.body) == null ? void 0 : _a2.template], "c"), email, resp);
1234
1460
  return resp;
1235
1461
  });
1236
1462
  }
1237
1463
  }
1238
- class Groups extends _ {
1464
+ class Groups extends PathedEventEmitter {
1239
1465
  constructor(api) {
1240
1466
  super();
1241
1467
  __publicField(this, "api");
@@ -1243,46 +1469,52 @@ class Groups extends _ {
1243
1469
  }
1244
1470
  all() {
1245
1471
  return this.api.request({ url: `/api/groups` }).then((resp) => {
1246
- this.emit("all", resp || []);
1472
+ this.emit(pathedEvent("groups", "r"), resp || []);
1247
1473
  return resp;
1248
1474
  });
1249
1475
  }
1250
1476
  create(group) {
1477
+ if (!group.name) throw new Error("Cannot create group, missing name");
1251
1478
  return this.api.request({
1252
1479
  url: `/api/groups/${group.name}`,
1253
1480
  method: "POST",
1254
1481
  body: group
1255
1482
  }).then((resp) => {
1256
- this.emit("create", resp);
1483
+ this.emit(pathedEvent(["groups", group.name], "c"), resp);
1257
1484
  return resp;
1258
1485
  });
1259
1486
  }
1260
1487
  read(name) {
1261
- return this.api.request({ url: `/api/groups/${name}` }).then((resp) => {
1262
- this.emit("read", resp);
1488
+ if (!name) throw new Error("Cannot read group, missing name");
1489
+ return this.api.request({ url: `/api/` + pathedEvent(["groups", name]) }).then((resp) => {
1490
+ this.emit(pathedEvent(["groups", name], "r"), resp);
1263
1491
  return resp;
1264
1492
  });
1265
1493
  }
1266
1494
  update(group) {
1495
+ if (!group.name) throw new Error("Cannot update group, missing name");
1267
1496
  return this.api.request({
1268
- url: `/api/groups/${group.name}`,
1497
+ url: `/api/` + pathedEvent(["groups", group.name]),
1269
1498
  method: "PATCH",
1270
1499
  body: group
1271
1500
  }).then((resp) => {
1272
- this.emit("update", resp);
1501
+ this.emit(pathedEvent(["groups", group.name], "u"), resp);
1273
1502
  return resp;
1274
1503
  });
1275
1504
  }
1276
1505
  delete(name) {
1506
+ if (!name) throw new Error("Cannot delete group, missing name");
1277
1507
  return this.api.request({
1278
- url: `/api/groups/${name}`,
1508
+ url: `/api/` + pathedEvent(["groups", name]),
1279
1509
  method: "DELETE"
1280
- }).then(() => this.emit("delete", name));
1510
+ }).then(() => this.emit(pathedEvent(["groups", name], "d")));
1281
1511
  }
1282
1512
  }
1283
- class Logger {
1284
- constructor(api, logLevel) {
1513
+ class Logger extends PathedEventEmitter {
1514
+ constructor(api, namespace, logLevel) {
1515
+ super();
1285
1516
  __publicField(this, "api");
1517
+ this.namespace = namespace;
1286
1518
  this.api = typeof api == "string" ? new Api(api) : api;
1287
1519
  if (logLevel != null && logLevel != "NONE") {
1288
1520
  window.addEventListener("error", (event) => {
@@ -1313,47 +1545,44 @@ ${log}`;
1313
1545
  }
1314
1546
  };
1315
1547
  }
1316
- clearClientLogs() {
1317
- return this.api.request({ url: `/api/logs/client`, method: "DELETE" });
1548
+ createLog(log, namespace = this.namespace) {
1549
+ return this.api.request({ url: `/api/` + pathedEvent(["logs", namespace]), body: log }).then(() => this.emit(pathedEvent(["logs", namespace], "c"), log)).catch(() => {
1550
+ });
1551
+ }
1552
+ clearLogs(namespace = this.namespace) {
1553
+ return this.api.request({ url: `/api/` + pathedEvent(["logs", namespace]), method: "DELETE" }).then(() => this.emit(pathedEvent(["logs", namespace], "d")));
1318
1554
  }
1319
1555
  clearServerLogs() {
1320
- return this.api.request({ url: `/api/logs/server`, method: "DELETE" });
1556
+ return this.clearLogs("server");
1321
1557
  }
1322
- clientLogs(length, page) {
1558
+ getLogs(length, page, namespace = this.namespace) {
1559
+ if (!namespace) throw new Error("Cannot get logs, missing namespace");
1323
1560
  const query = [length ? `length=${length}` : void 0, page ? `page=${page}` : void 0].filter((v) => !!v).join("&");
1324
- return this.api.request({ url: `/api/logs/client${query ? `?${query}` : ""}` }).then((resp) => resp);
1561
+ return this.api.request({ url: `/api/` + pathedEvent(["logs", namespace]) + (query ? `?${query}` : "") }).then((logs) => {
1562
+ this.emit(pathedEvent(["logs", namespace], "r"), logs);
1563
+ return logs;
1564
+ });
1325
1565
  }
1326
- serverLogs(length, page) {
1327
- const query = [length ? `length=${length}` : void 0, page ? `page=${page}` : void 0].filter((v) => !!v).join("&");
1328
- return this.api.request({ url: `/api/logs/server${query ? `?${query}` : ""}` }).then((resp) => resp);
1566
+ getServerLogs(length, page) {
1567
+ return this.getLogs(length, page, "server");
1329
1568
  }
1330
- debug(...logs) {
1331
- return this.api.request({ url: `/api/logs/client`, body: this.buildLog(yt.DEBUG, logs) }).then(() => {
1332
- }).catch(() => {
1333
- });
1569
+ debug(log, namespace = this.namespace) {
1570
+ return this.createLog(this.buildLog(yt.DEBUG, log), namespace);
1334
1571
  }
1335
- log(...logs) {
1336
- return this.api.request({ url: `/api/logs/client`, body: this.buildLog(yt.LOG, logs) }).then(() => {
1337
- }).catch(() => {
1338
- });
1572
+ log(log, namespace = this.namespace) {
1573
+ return this.createLog(this.buildLog(yt.LOG, log), namespace);
1339
1574
  }
1340
- info(...logs) {
1341
- return this.api.request({ url: `/api/logs/client`, body: this.buildLog(yt.INFO, logs) }).then(() => {
1342
- }).catch(() => {
1343
- });
1575
+ info(log, namespace = this.namespace) {
1576
+ return this.createLog(this.buildLog(yt.INFO, log), namespace);
1344
1577
  }
1345
- warn(...logs) {
1346
- return this.api.request({ url: `/api/logs/client`, body: this.buildLog(yt.WARN, logs) }).then(() => {
1347
- }).catch(() => {
1348
- });
1578
+ warn(log, namespace = this.namespace) {
1579
+ return this.createLog(this.buildLog(yt.WARN, log), namespace);
1349
1580
  }
1350
- error(...logs) {
1351
- return this.api.request({ url: `/api/logs/client`, body: this.buildLog(yt.ERROR, logs) }).then(() => {
1352
- }).catch(() => {
1353
- });
1581
+ error(log, namespace = this.namespace) {
1582
+ return this.createLog(this.buildLog(yt.ERROR, log), namespace);
1354
1583
  }
1355
1584
  }
1356
- class Payments extends _ {
1585
+ class Payments extends PathedEventEmitter {
1357
1586
  constructor(api, secret) {
1358
1587
  super();
1359
1588
  __publicField(this, "api");
@@ -1371,11 +1600,12 @@ class Payments extends _ {
1371
1600
  setup();
1372
1601
  }
1373
1602
  async create(amount, custom = {}) {
1603
+ if (!amount) throw new Error("Please specify a valid amount`");
1374
1604
  const request = await this.api.request({ url: "/api/payments", body: {
1375
1605
  amount,
1376
1606
  custom
1377
1607
  } });
1378
- this.emit("create", amount, custom, request.data.clientSecret);
1608
+ this.emit(pathedEvent("payments", "c"), amount, custom, request.data.clientSecret);
1379
1609
  return request.data.clientSecret;
1380
1610
  }
1381
1611
  async createForm(element, amount, custom) {
@@ -1389,35 +1619,42 @@ class Payments extends _ {
1389
1619
  });
1390
1620
  }
1391
1621
  async history(username) {
1392
- const history = await this.api.request({ url: `/api/payments${username ? `/${username}` : ""}` });
1393
- this.emit("history", username || null, history);
1622
+ const history = await this.api.request({ url: `/api/` + pathedEvent("payments", username) });
1623
+ this.emit(pathedEvent(["payments", username], "r"), username, history);
1394
1624
  return history;
1395
1625
  }
1396
1626
  }
1397
- class Pdf extends _ {
1627
+ class Pdf extends PathedEventEmitter {
1398
1628
  constructor(api) {
1399
1629
  super();
1400
1630
  __publicField(this, "api");
1401
1631
  this.api = typeof api == "string" ? new Api(api) : api;
1402
1632
  }
1403
- async handleResponse(resp, fileName) {
1404
- const blob = await resp.blob();
1405
- if (fileName) {
1406
- const url = URL.createObjectURL(blob);
1407
- dt(url, fileName.endsWith(".pdf") ? fileName : fileName + ".pdf");
1408
- URL.revokeObjectURL(url);
1409
- }
1410
- this.emit("create", blob);
1411
- return blob;
1633
+ createPdf(body, options) {
1634
+ return this.api.request({ url: `/api/pdf`, body: { ...body, options }, decode: false }).then(async (resp) => {
1635
+ const blob = await resp.blob();
1636
+ if (options == null ? void 0 : options.download) {
1637
+ let filename = (options == null ? void 0 : options.filename) || qt();
1638
+ if (!filename.endsWith(".pdf")) filename += ".pdf";
1639
+ const url = URL.createObjectURL(blob);
1640
+ dt(url, filename);
1641
+ URL.revokeObjectURL(url);
1642
+ }
1643
+ this.emit(pathedEvent("pdf", "c"), body, options, blob);
1644
+ return blob;
1645
+ });
1412
1646
  }
1413
- fromHtml(content, opts = {}) {
1414
- return this.api.request({ url: `/api/pdf`, body: { html: content }, decode: false }).then((resp) => this.handleResponse(resp, opts.download ? opts.fileName || (/* @__PURE__ */ new Date()).toISOString() : void 0));
1647
+ fromHtml(html, options = {}) {
1648
+ if (!html) throw new Error("Cannot create PDF, missing HTML");
1649
+ return this.createPdf({ html }, options);
1415
1650
  }
1416
- fromTemplate(template, data, opts = {}) {
1417
- return this.api.request({ url: `/api/pdf${template}`, body: data, decode: false }).then((resp) => this.handleResponse(resp, opts.download ? opts.fileName || (/* @__PURE__ */ new Date()).toISOString() : void 0));
1651
+ fromTemplate(template, data, options = {}) {
1652
+ if (!template) throw new Error("Cannot create PDF, missing template");
1653
+ return this.createPdf({ template, data }, options);
1418
1654
  }
1419
- fromUrl(url, opts = {}) {
1420
- return this.api.request({ url: `/api/pdf`, body: { url }, decode: false }).then((resp) => this.handleResponse(resp, opts.download ? opts.fileName || (/* @__PURE__ */ new Date()).toISOString() : void 0));
1655
+ fromUrl(url, options = {}) {
1656
+ if (!url) throw new Error("Cannot create PDF, missing URL");
1657
+ return this.createPdf({ url }, options);
1421
1658
  }
1422
1659
  }
1423
1660
  const _Socket = class _Socket {
@@ -1428,7 +1665,7 @@ const _Socket = class _Socket {
1428
1665
  __publicField(this, "open", false);
1429
1666
  this.api = typeof api == "string" ? new Api(api) : api;
1430
1667
  this.url = this.api.url.replace("http", "ws");
1431
- this.api.on("token", () => this.connect());
1668
+ this.api.on("api/token", () => this.connect());
1432
1669
  this.connect();
1433
1670
  }
1434
1671
  close() {
@@ -1467,126 +1704,127 @@ const _Socket = class _Socket {
1467
1704
  };
1468
1705
  __publicField(_Socket, "timeout", 1e4);
1469
1706
  let Socket = _Socket;
1470
- class Storage extends _ {
1707
+ class Storage extends PathedEventEmitter {
1471
1708
  constructor(api) {
1472
1709
  super();
1473
1710
  __publicField(this, "api");
1474
1711
  this.api = typeof api == "string" ? new Api(api) : api;
1475
1712
  }
1476
- copy(path) {
1477
- const url = this.api.path(path.startsWith("/api/storage/") ? "" : "/api/storage/", path);
1478
- return this.api.request({ url, method: "PUT" }).then((resp) => {
1479
- this.emit("copy", path, resp);
1713
+ copy(source, destination) {
1714
+ if (!source || !destination) throw new Error("Cannot copy file or folder, missing source or destination");
1715
+ return this.api.request({ url: "/api/" + pathedEvent(["storage", destination]), body: { from: source } }).then((resp) => {
1716
+ this.emit(pathedEvent(["storage", destination], "c"), source, destination, resp);
1480
1717
  return resp;
1481
1718
  });
1482
1719
  }
1483
1720
  delete(path) {
1484
- const url = this.api.path(path.startsWith("/api/storage/") ? "" : "/api/storage/", path);
1485
- return this.api.request({ url, method: "DELETE" }).then(() => {
1486
- this.emit("delete", url);
1721
+ if (!path) throw new Error("Cannot delete file or folder, missing path");
1722
+ return this.api.request({ url: "/api/" + pathedEvent(["storage", path]), method: "DELETE" }).then(() => {
1723
+ this.emit(pathedEvent(["storage", path], "d"), path);
1487
1724
  });
1488
1725
  }
1489
1726
  download(path, opts = {}) {
1490
- const url = this.api.path(path.startsWith("/api/storage/") ? "" : "/api/storage/", path);
1491
- return this.api.request({ ...opts, url, decode: false }).then(async (response) => {
1727
+ if (!path) throw new Error("Cannot download file, missing path");
1728
+ return this.api.request({ ...opts, url: "/api/" + pathedEvent(["storage", path]), decode: false }).then(async (response) => {
1492
1729
  const blob = await response.blob();
1493
1730
  const name = opts.downloadAs || path.split("/").pop();
1494
- this.emit("download", path, blob);
1731
+ this.emit(pathedEvent(["storage", path], "r"), path, blob);
1495
1732
  Gt(blob, name);
1496
1733
  return response;
1497
1734
  });
1498
1735
  }
1499
1736
  list(path) {
1500
- const url = this.api.path(path.startsWith("/api/storage/") ? "" : "/api/storage/", path);
1501
- return this.api.request({ url: url + "?list" }).then((resp) => {
1502
- this.emit("list", path, resp);
1737
+ if (!path) path = "/";
1738
+ return this.api.request({ url: "/api/" + pathedEvent(["storage", path]) + "?list" }).then((resp) => {
1739
+ this.emit(pathedEvent(["storage", path], "r"), path, resp);
1503
1740
  return resp;
1504
1741
  });
1505
1742
  }
1506
1743
  open(path, target = "_blank") {
1507
- const url = this.api.path(path.startsWith("/api/storage/") ? "" : "/api/storage/", path);
1508
- const link = `${this.api.url}${url}${this.api.token ? `?token=${this.api.token}` : ""}`;
1744
+ if (!path) throw new Error("Cannot download file, missing path");
1745
+ const link = `${this.api.url}/api/${pathedEvent(["storage", path])}${this.api.token ? `?token=${this.api.token}` : ""}`;
1509
1746
  if (!target) return link;
1510
- this.emit("open", path);
1747
+ this.emit(pathedEvent(["storage", path], "r"), path);
1511
1748
  return window.open(link, target);
1512
1749
  }
1513
1750
  mkdir(path) {
1514
- const url = this.api.path(path.startsWith("/api/storage/") ? "" : "/api/storage/", path);
1515
- return this.api.request({ url: url + "?directory", method: "POST" }).then((resp) => {
1516
- this.emit("mkdir", path, resp);
1751
+ if (!path) throw new Error("Cannot make directory, missing path");
1752
+ return this.api.request({ url: "/api/" + pathedEvent(["storage", path]), body: { directory: true } }).then((resp) => {
1753
+ this.emit(pathedEvent(["storage", path], "c"), path, resp);
1517
1754
  return resp;
1518
1755
  });
1519
1756
  }
1520
- move(from, to) {
1521
- if (from == to) return this.list(to);
1522
- const url = this.api.path(from.startsWith("/api/storage/") ? "" : "/api/storage/", from);
1523
- return this.api.request({ url, method: "PATCH", body: { move: to } }).then((resp) => {
1524
- this.emit("move", from, to, resp);
1757
+ move(source, destination) {
1758
+ if (!source || !destination) throw new Error("Cannot move file or folder, missing source or destination");
1759
+ if (source == destination) return this.list(destination);
1760
+ return this.api.request({ url: "/api/" + pathedEvent(["storage", source]), method: "PATCH", body: { move: destination } }).then((resp) => {
1761
+ this.emit(pathedEvent(["storage", source], "u"), source, destination, resp);
1525
1762
  return resp;
1526
1763
  });
1527
1764
  }
1528
- upload(files, opts = "") {
1765
+ upload(files, opts) {
1529
1766
  return new E(async (res, rej, prog) => {
1530
1767
  if (!files) files = await Ut(typeof opts == "object" ? opts : void 0);
1531
1768
  if (!files || Array.isArray(files) && !files.length) return [];
1532
- const path = this.api.path("/api/storage/", typeof opts == "string" ? opts : opts.path || "");
1769
+ const path = (opts && typeof opts == "object" ? opts == null ? void 0 : opts.path : opts) || "/";
1533
1770
  return Ft({
1534
- url: `${this.api.url}${path}`,
1771
+ url: `${this.api.url}/api/${pathedEvent(["storage", path])}`,
1535
1772
  files: ft(files),
1536
1773
  headers: this.api.headers
1537
1774
  }).onProgress((p2) => {
1538
1775
  prog(p2);
1539
1776
  }).then((resp) => {
1540
- this.emit("upload", resp);
1777
+ this.emit(pathedEvent(["storage", path], "c"), resp);
1541
1778
  res(resp);
1542
1779
  }).catch((err) => rej(err));
1543
1780
  });
1544
1781
  }
1545
1782
  }
1546
- class Users extends _ {
1783
+ class Users extends PathedEventEmitter {
1547
1784
  constructor(api) {
1548
1785
  super();
1549
1786
  __publicField(this, "api");
1550
- __publicField(this, "listed", false);
1551
1787
  __publicField(this, "cache", new Dt("username"));
1552
1788
  this.api = typeof api == "string" ? new Api(api) : api;
1553
1789
  }
1554
1790
  delete(username) {
1791
+ if (!username) throw new Error("Cannot delete user, missing username");
1555
1792
  return this.api.request({
1556
- url: `/api/users/${username}`,
1793
+ url: "/api/" + pathedEvent(["users", username]),
1557
1794
  method: "DELETE"
1558
1795
  }).then(() => {
1559
1796
  this.cache.delete(username);
1560
- this.emit("delete", username);
1797
+ this.emit(pathedEvent(["users", username], "d"), username);
1561
1798
  });
1562
1799
  }
1563
1800
  async all(reload = false) {
1564
1801
  if (!reload && this.cache.complete) return this.cache.all();
1565
- return this.api.request({ url: `/api/users` }).then((resp) => {
1802
+ return this.api.request({ url: "/api/" + pathedEvent("users") }).then((resp) => {
1566
1803
  resp == null ? void 0 : resp.forEach((r) => {
1567
1804
  r.image = this.api.url + r.image + `?token=${this.api.token}`;
1568
1805
  return r;
1569
1806
  });
1570
1807
  this.cache.addAll(resp);
1571
- this.listed = true;
1572
- this.emit("all", resp || []);
1808
+ this.emit(pathedEvent("users", "r"), resp || []);
1573
1809
  return resp;
1574
1810
  });
1575
1811
  }
1576
1812
  async read(username, reload = false) {
1813
+ if (!username) throw new Error("Cannot read user, missing username");
1577
1814
  if (!reload && this.cache.get(username)) return this.cache.get(username);
1578
- return this.api.request({ url: `/api/users/${username}` }).then((resp) => {
1815
+ return this.api.request({ url: "/api/" + pathedEvent(["users", username]) }).then((resp) => {
1579
1816
  if (resp) {
1580
1817
  resp.image = this.api.url + resp.image + `?token=${this.api.token}`;
1581
1818
  this.cache.add(resp);
1582
1819
  }
1583
- this.emit("read", resp);
1820
+ this.emit(pathedEvent(["users", username], "r"), resp);
1584
1821
  return resp;
1585
1822
  });
1586
1823
  }
1587
1824
  update(user) {
1825
+ if (!user.username) throw new Error("Cannot update user, missing username");
1588
1826
  return this.api.request({
1589
- url: `/api/users/${user.username}`,
1827
+ url: `/api/` + pathedEvent(["users", user.username]),
1590
1828
  method: "PATCH",
1591
1829
  body: user
1592
1830
  }).then((resp) => {
@@ -1594,22 +1832,23 @@ class Users extends _ {
1594
1832
  resp.image = this.api.url + resp.image + `?token=${this.api.token}`;
1595
1833
  this.cache.add(resp);
1596
1834
  }
1597
- this.emit(resp._id ? "update" : "create", resp);
1835
+ this.emit(pathedEvent(["users", user.username], resp._id ? "u" : "c"), resp);
1598
1836
  return resp;
1599
1837
  });
1600
1838
  }
1601
1839
  uploadImage(username, file) {
1840
+ if (!username || !file) throw new Error("Cannot update user image, missing username or file");
1602
1841
  return Ft({
1603
- url: this.api.url + `/api/users/${username}/image`,
1842
+ url: this.api.url + `/api/` + pathedEvent(["users", username, "image"]),
1604
1843
  files: [file],
1605
1844
  headers: this.api.headers
1606
1845
  }).then((resp) => {
1607
- this.emit("image", username, file);
1846
+ this.emit(pathedEvent(["users", username, "image"], "u"), username, file);
1608
1847
  return resp;
1609
1848
  });
1610
1849
  }
1611
1850
  }
1612
- class Settings extends _ {
1851
+ class Settings extends PathedEventEmitter {
1613
1852
  constructor(api) {
1614
1853
  super();
1615
1854
  __publicField(this, "api");
@@ -1620,59 +1859,64 @@ class Settings extends _ {
1620
1859
  if (!reload && !detailed && this.cache.complete) return this.cache;
1621
1860
  return this.api.request({ url: `/api/settings` + (detailed ? "?detailed" : "") }).then((resp) => {
1622
1861
  if (resp) Object.keys(resp).forEach((key) => this.cache.set(key, detailed ? resp[key].value : resp[key]));
1623
- this.emit("all", resp || []);
1862
+ this.emit(pathedEvent("settings", "r"), resp || []);
1624
1863
  return resp;
1625
1864
  });
1626
1865
  }
1627
1866
  delete(key) {
1628
- return this.api.request({ url: `/api/settings/${key}`, method: "DELETE" }).then(() => {
1867
+ if (!key) throw new Error("Cannot delete setting, missing key");
1868
+ return this.api.request({ url: `/api/` + pathedEvent(["settings", key]), method: "DELETE" }).then(() => {
1629
1869
  this.cache.delete(key);
1630
- this.emit("delete", key);
1870
+ this.emit(pathedEvent(["settings", key], "d"), key);
1631
1871
  });
1632
1872
  }
1633
1873
  read(key, reload = false) {
1874
+ if (!key) throw new Error("Cannot read setting, missing key");
1634
1875
  if (!reload && this.cache.get(key)) return this.cache.get(key);
1635
- return this.api.request({ url: `/api/settings/${key}` }).then((variable) => {
1876
+ return this.api.request({ url: `/api/` + pathedEvent(["settings", key]) }).then((variable) => {
1636
1877
  if (variable) this.cache.set(variable.key, variable.value);
1637
- this.emit("read", variable);
1878
+ this.emit(pathedEvent(["settings", key], "r"), variable);
1638
1879
  return variable;
1639
1880
  });
1640
1881
  }
1641
1882
  update(variable) {
1642
- return this.api.request({ url: `/api/settings/${variable.key}`, body: variable }).then((variable2) => {
1883
+ if (!variable.key) throw new Error("Cannot update setting, missing key");
1884
+ return this.api.request({ url: `/api/` + pathedEvent(["settings", variable.key]), body: variable }).then((variable2) => {
1643
1885
  if (variable2) this.cache.set(variable2.key, variable2.value);
1644
- this.emit("update", variable2);
1886
+ this.emit(`/api/` + pathedEvent(["settings", variable2.key], variable2._id ? "u" : "c"), variable2);
1645
1887
  return variable2;
1646
1888
  });
1647
1889
  }
1648
1890
  }
1649
- class Static extends _ {
1891
+ class Static extends PathedEventEmitter {
1650
1892
  constructor(api) {
1651
1893
  super();
1652
1894
  __publicField(this, "api");
1653
1895
  this.api = typeof api == "string" ? new Api(api) : api;
1654
1896
  }
1655
1897
  delete(path) {
1656
- return this.api.request({ url: `/api/static/${path}`, method: "DELETE" }).then(() => {
1657
- this.emit("delete", path);
1898
+ if (!path) throw new Error("Cannot delete static asset, missing path");
1899
+ return this.api.request({ url: `/api/` + pathedEvent(["static", path]), method: "DELETE" }).then(() => {
1900
+ this.emit(pathedEvent(["static", path], "d"), path);
1658
1901
  });
1659
1902
  }
1660
1903
  upload(files, path = "/") {
1904
+ if (!files) throw new Error("Cannot upload static assets, missing file");
1661
1905
  return new E(async (res, rej, prog) => {
1662
1906
  return Ft({
1663
- url: this.api.url + ("/api/static/" + path).replaceAll("//", "/"),
1907
+ url: this.api.url + "/api/" + pathedEvent(["static", path]),
1664
1908
  files: ft(files),
1665
1909
  headers: this.api.headers
1666
1910
  }).onProgress((p2) => {
1667
1911
  prog(p2);
1668
1912
  }).then((resp) => {
1669
- this.emit("upload", resp);
1913
+ this.emit(pathedEvent(["static", path], "c"), resp);
1670
1914
  res(resp);
1671
1915
  }).catch((err) => rej(err));
1672
1916
  });
1673
1917
  }
1674
1918
  }
1675
- class Momentum extends _ {
1919
+ class Momentum extends PathedEventEmitter {
1676
1920
  constructor(url, opts) {
1677
1921
  super();
1678
1922
  __publicField(this, "api");
@@ -1703,7 +1947,7 @@ class Momentum extends _ {
1703
1947
  this.data = new Data(this.api);
1704
1948
  this.email = new Email(this.api);
1705
1949
  this.groups = new Groups(this.api);
1706
- this.logger = new Logger(this.api, opts == null ? void 0 : opts.logLevel);
1950
+ this.logger = new Logger(this.api, "client", opts == null ? void 0 : opts.logLevel);
1707
1951
  if (opts == null ? void 0 : opts.stripeSecret) this.payments = new Payments(this.api, opts.stripeSecret);
1708
1952
  this.pdf = new Pdf(this.api);
1709
1953
  this.settings = new Settings(this.api);
@@ -1712,24 +1956,25 @@ class Momentum extends _ {
1712
1956
  this.storage = new Storage(this.api);
1713
1957
  this.client = new Client(this.settings);
1714
1958
  this.users = new Users(this.api);
1715
- this.api.on("*", (event, ...args) => this.emit(`Api:${event}`, ...args));
1716
- this.actions.on("*", (event, ...args) => this.emit(`Actions:${event}`, ...args));
1717
- this.auth.on("*", (event, ...args) => this.emit(`Auth:${event}`, ...args));
1718
- this.data.on("*", (event, ...args) => this.emit(`Data:${event}`, ...args));
1719
- this.email.on("*", (event, ...args) => this.emit(`Email:${event}`, ...args));
1720
- this.groups.on("*", (event, ...args) => this.emit(`Groups:${event}`, ...args));
1721
- if (this.payments) this.payments.on("*", (event, ...args) => this.emit(`Payments:${event}`, ...args));
1722
- this.pdf.on("*", (event, ...args) => this.emit(`Pdf:${event}`, ...args));
1723
- this.settings.on("*", (event, ...args) => this.emit(`Settings:${event}`, ...args));
1724
- this.static.on("*", (event, ...args) => this.emit(`Static:${event}`, ...args));
1725
- this.storage.on("*", (event, ...args) => this.emit(`Storage:${event}`, ...args));
1726
- this.users.on("*", (event, ...args) => this.emit(`Users:${event}`, ...args));
1727
- this.users.on("*", (event, ...args) => {
1728
- const u = ft(args[0]).find((u2) => {
1729
- var _a;
1730
- return (u2 == null ? void 0 : u2._id) == ((_a = this.auth.user) == null ? void 0 : _a._id);
1731
- });
1732
- if (u) this.auth.user = u;
1959
+ this.relayEvents(this.actions);
1960
+ this.relayEvents(this.ai);
1961
+ this.relayEvents(this.analytics);
1962
+ this.relayEvents(this.api);
1963
+ this.relayEvents(this.auth);
1964
+ this.relayEvents(this.client);
1965
+ this.relayEvents(this.data);
1966
+ this.relayEvents(this.email);
1967
+ this.relayEvents(this.groups);
1968
+ this.relayEvents(this.logger);
1969
+ if (this.payments) this.relayEvents(this.payments);
1970
+ this.relayEvents(this.pdf);
1971
+ this.relayEvents(this.settings);
1972
+ this.relayEvents(this.static);
1973
+ this.relayEvents(this.storage);
1974
+ this.relayEvents(this.users);
1975
+ this.users.on(`*`, () => {
1976
+ if (!this.auth.user) return;
1977
+ this.auth.user = this.users.cache.get(this.auth.user.username);
1733
1978
  });
1734
1979
  }
1735
1980
  }
@@ -1746,6 +1991,7 @@ export {
1746
1991
  Groups,
1747
1992
  Logger,
1748
1993
  Momentum,
1994
+ PathedEventEmitter,
1749
1995
  Payments,
1750
1996
  Pdf,
1751
1997
  Settings,
@@ -1753,5 +1999,10 @@ export {
1753
1999
  Static,
1754
2000
  Storage,
1755
2001
  Totp,
1756
- Users
2002
+ Users,
2003
+ combinePathedEvents,
2004
+ hasPath,
2005
+ hasPathFatal,
2006
+ parsePathedEvent,
2007
+ pathedEvent
1757
2008
  };