@ztimson/utils 0.28.15 → 0.28.17

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 CHANGED
@@ -2,6 +2,193 @@
2
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
3
  })(this, (function(exports2) {
4
4
  "use strict";
5
+ var dist = {};
6
+ var persist = {};
7
+ var hasRequiredPersist;
8
+ function requirePersist() {
9
+ if (hasRequiredPersist) return persist;
10
+ hasRequiredPersist = 1;
11
+ Object.defineProperty(persist, "__esModule", { value: true });
12
+ persist.persist = persist.Persist = void 0;
13
+ class Persist {
14
+ key;
15
+ options;
16
+ /** Backend service to store data, must implement `Storage` interface */
17
+ storage;
18
+ /** Listeners which should be notified on changes */
19
+ watches = {};
20
+ /** Private value field */
21
+ _value;
22
+ /** Current value or default if undefined */
23
+ get value() {
24
+ return this._value !== void 0 ? this._value : this.options?.default;
25
+ }
26
+ /** Set value with proxy object wrapper to sync future changes */
27
+ set value(v) {
28
+ if (v == null || typeof v != "object")
29
+ this._value = v;
30
+ else
31
+ this._value = new Proxy(v, {
32
+ get: (target, p) => {
33
+ const f = typeof target[p] == "function";
34
+ if (!f)
35
+ return target[p];
36
+ return (...args) => {
37
+ const value = target[p](...args);
38
+ this.save();
39
+ return value;
40
+ };
41
+ },
42
+ set: (target, p, newValue) => {
43
+ target[p] = newValue;
44
+ this.save();
45
+ return true;
46
+ }
47
+ });
48
+ this.save();
49
+ }
50
+ /**
51
+ * @param {string} key Primary key value will be stored under
52
+ * @param {PersistOptions<T>} options Configure using {@link PersistOptions}
53
+ */
54
+ constructor(key, options = {}) {
55
+ this.key = key;
56
+ this.options = options;
57
+ this.storage = options.storage || localStorage;
58
+ this.load();
59
+ }
60
+ /** Notify listeners of change */
61
+ notify(value) {
62
+ Object.values(this.watches).forEach((watch) => watch(value));
63
+ }
64
+ /** Delete value from storage */
65
+ clear() {
66
+ this.storage.removeItem(this.key);
67
+ }
68
+ /** Save current value to storage */
69
+ save() {
70
+ if (this._value === void 0)
71
+ this.clear();
72
+ else
73
+ this.storage.setItem(this.key, JSON.stringify(this._value));
74
+ this.notify(this.value);
75
+ }
76
+ /** Load value from storage */
77
+ load() {
78
+ if (this.storage[this.key] != void 0) {
79
+ let value = JSON.parse(this.storage.getItem(this.key));
80
+ if (value != null && typeof value == "object" && this.options.type)
81
+ value.__proto__ = this.options.type.prototype;
82
+ this.value = value;
83
+ } else
84
+ this.value = this.options.default || void 0;
85
+ }
86
+ /**
87
+ * Callback function which is run when there are changes
88
+ *
89
+ * @param {(value: T) => any} fn Callback will run on each change; it's passed the next value & it's return is ignored
90
+ * @returns {() => void} Function which will unsubscribe the watch/callback when called
91
+ */
92
+ watch(fn2) {
93
+ const index = Object.keys(this.watches).length;
94
+ this.watches[index] = fn2;
95
+ return () => {
96
+ delete this.watches[index];
97
+ };
98
+ }
99
+ /**
100
+ * Return value as JSON string
101
+ *
102
+ * @returns {string} Stringified object as JSON
103
+ */
104
+ toString() {
105
+ return JSON.stringify(this.value);
106
+ }
107
+ /**
108
+ * Return current value
109
+ *
110
+ * @returns {T} Current value
111
+ */
112
+ valueOf() {
113
+ return this.value;
114
+ }
115
+ }
116
+ persist.Persist = Persist;
117
+ function persist$1(options) {
118
+ return (target, prop) => {
119
+ const key = options?.key || `${target.constructor.name}.${prop.toString()}`;
120
+ const wrapper = new Persist(key, options);
121
+ Object.defineProperty(target, prop, {
122
+ get: function() {
123
+ return wrapper.value;
124
+ },
125
+ set: function(v) {
126
+ wrapper.value = v;
127
+ }
128
+ });
129
+ };
130
+ }
131
+ persist.persist = persist$1;
132
+ return persist;
133
+ }
134
+ var memoryStorage = {};
135
+ var hasRequiredMemoryStorage;
136
+ function requireMemoryStorage() {
137
+ if (hasRequiredMemoryStorage) return memoryStorage;
138
+ hasRequiredMemoryStorage = 1;
139
+ Object.defineProperty(memoryStorage, "__esModule", { value: true });
140
+ memoryStorage.MemoryStorage = void 0;
141
+ class MemoryStorage {
142
+ get length() {
143
+ return Object.keys(this).length;
144
+ }
145
+ clear() {
146
+ Object.keys(this).forEach((k) => this.removeItem(k));
147
+ }
148
+ getItem(key) {
149
+ return this[key];
150
+ }
151
+ key(index) {
152
+ return Object.keys(this)[index];
153
+ }
154
+ removeItem(key) {
155
+ delete this[key];
156
+ }
157
+ setItem(key, value) {
158
+ this[key] = value;
159
+ }
160
+ }
161
+ memoryStorage.MemoryStorage = MemoryStorage;
162
+ return memoryStorage;
163
+ }
164
+ var hasRequiredDist;
165
+ function requireDist() {
166
+ if (hasRequiredDist) return dist;
167
+ hasRequiredDist = 1;
168
+ (function(exports$1) {
169
+ var __createBinding = dist && dist.__createBinding || (Object.create ? (function(o, m, k, k2) {
170
+ if (k2 === void 0) k2 = k;
171
+ var desc = Object.getOwnPropertyDescriptor(m, k);
172
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
173
+ desc = { enumerable: true, get: function() {
174
+ return m[k];
175
+ } };
176
+ }
177
+ Object.defineProperty(o, k2, desc);
178
+ }) : (function(o, m, k, k2) {
179
+ if (k2 === void 0) k2 = k;
180
+ o[k2] = m[k];
181
+ }));
182
+ var __exportStar = dist && dist.__exportStar || function(m, exports$12) {
183
+ for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports$12, p)) __createBinding(exports$12, m, p);
184
+ };
185
+ Object.defineProperty(exports$1, "__esModule", { value: true });
186
+ __exportStar(requirePersist(), exports$1);
187
+ __exportStar(requireMemoryStorage(), exports$1);
188
+ })(dist);
189
+ return dist;
190
+ }
191
+ requireDist();
5
192
  class ArgParser {
6
193
  /**
7
194
  * Create a unix-like argument parser to extract flags from the argument list. Can also create help messages.
@@ -30,6 +217,10 @@
30
217
  `--help ${this.commands.length ? "[COMMAND]" : ""}`
31
218
  ].filter((e) => !!e);
32
219
  }
220
+ name;
221
+ desc;
222
+ argList;
223
+ examples;
33
224
  commands = [];
34
225
  args = [];
35
226
  flags = [];
@@ -493,6 +684,8 @@ ${opts.message || this.desc}`;
493
684
  }
494
685
  });
495
686
  }
687
+ key;
688
+ options;
496
689
  _loading;
497
690
  store = /* @__PURE__ */ new Map();
498
691
  timers = /* @__PURE__ */ new Map();
@@ -773,6 +966,9 @@ ${opts.message || this.desc}`;
773
966
  const pascal = pascalCase(str);
774
967
  return pascal.charAt(0).toLowerCase() + pascal.slice(1);
775
968
  }
969
+ function decodeHtml(html) {
970
+ return html.replace(/&nbsp;/g, " ").replace(/&quot;/g, '"').replace(/&apos;/g, "'").replace(/&lt;/g, "<").replace(/&gt;/g, ">").replace(/&cent;/g, "¢").replace(/&pound;/g, "£").replace(/&yen;/g, "¥").replace(/&euro;/g, "€").replace(/&copy;/g, "©").replace(/&reg;/g, "®").replace(/&trade;/g, "™").replace(/&times;/g, "×").replace(/&divide;/g, "÷").replace(/&#(\d+);/g, (match, dec) => String.fromCharCode(dec)).replace(/&#x([0-9a-fA-F]+);/g, (match, hex) => String.fromCharCode(parseInt(hex, 16))).replace(/&amp;/g, "&");
971
+ }
776
972
  function formatBytes(bytes, decimals = 2) {
777
973
  if (bytes === 0) return "0 Bytes";
778
974
  const k = 1024;
@@ -1275,6 +1471,8 @@ ${opts.message || this.desc}`;
1275
1471
  };
1276
1472
  });
1277
1473
  }
1474
+ database;
1475
+ version;
1278
1476
  schemaLock = new AsyncLock();
1279
1477
  upgrading = false;
1280
1478
  connection;
@@ -1326,6 +1524,9 @@ ${opts.message || this.desc}`;
1326
1524
  if (!exists) this.database.createTable(this.name);
1327
1525
  });
1328
1526
  }
1527
+ database;
1528
+ name;
1529
+ key;
1329
1530
  async tx(table, fn2, readonly = false) {
1330
1531
  await this.database.waitForUpgrade();
1331
1532
  const db = await this.database.connection;
@@ -1868,6 +2069,7 @@ ${opts.message || this.desc}`;
1868
2069
  super();
1869
2070
  this.namespace = namespace;
1870
2071
  }
2072
+ namespace;
1871
2073
  static LOG_LEVEL = 4;
1872
2074
  format(...text) {
1873
2075
  const now = /* @__PURE__ */ new Date();
@@ -2298,6 +2500,7 @@ ${opts.message || this.desc}`;
2298
2500
  constructor(prefix = "") {
2299
2501
  this.prefix = prefix;
2300
2502
  }
2503
+ prefix;
2301
2504
  listeners = [];
2302
2505
  emit(event, ...args) {
2303
2506
  const parsed = event instanceof PathEvent ? event : new PathEvent(`${this.prefix}/${event}`);
@@ -2810,193 +3013,114 @@ ${err.message || err.toString()}`);
2810
3013
  };
2811
3014
  }
2812
3015
  }
2813
- var dist = {};
2814
- var persist = {};
2815
- var hasRequiredPersist;
2816
- function requirePersist() {
2817
- if (hasRequiredPersist) return persist;
2818
- hasRequiredPersist = 1;
2819
- Object.defineProperty(persist, "__esModule", { value: true });
2820
- persist.persist = persist.Persist = void 0;
2821
- class Persist {
2822
- key;
2823
- options;
2824
- /** Backend service to store data, must implement `Storage` interface */
2825
- storage;
2826
- /** Listeners which should be notified on changes */
2827
- watches = {};
2828
- /** Private value field */
2829
- _value;
2830
- /** Current value or default if undefined */
2831
- get value() {
2832
- return this._value !== void 0 ? this._value : this.options?.default;
2833
- }
2834
- /** Set value with proxy object wrapper to sync future changes */
2835
- set value(v) {
2836
- if (v == null || typeof v != "object")
2837
- this._value = v;
2838
- else
2839
- this._value = new Proxy(v, {
2840
- get: (target, p) => {
2841
- const f = typeof target[p] == "function";
2842
- if (!f)
2843
- return target[p];
2844
- return (...args) => {
2845
- const value = target[p](...args);
2846
- this.save();
2847
- return value;
2848
- };
2849
- },
2850
- set: (target, p, newValue) => {
2851
- target[p] = newValue;
2852
- this.save();
2853
- return true;
2854
- }
2855
- });
2856
- this.save();
2857
- }
2858
- /**
2859
- * @param {string} key Primary key value will be stored under
2860
- * @param {PersistOptions<T>} options Configure using {@link PersistOptions}
2861
- */
2862
- constructor(key, options = {}) {
2863
- this.key = key;
2864
- this.options = options;
2865
- this.storage = options.storage || localStorage;
2866
- this.load();
2867
- }
2868
- /** Notify listeners of change */
2869
- notify(value) {
2870
- Object.values(this.watches).forEach((watch) => watch(value));
2871
- }
2872
- /** Delete value from storage */
2873
- clear() {
2874
- this.storage.removeItem(this.key);
2875
- }
2876
- /** Save current value to storage */
2877
- save() {
2878
- if (this._value === void 0)
2879
- this.clear();
2880
- else
2881
- this.storage.setItem(this.key, JSON.stringify(this._value));
2882
- this.notify(this.value);
2883
- }
2884
- /** Load value from storage */
2885
- load() {
2886
- if (this.storage[this.key] != void 0) {
2887
- let value = JSON.parse(this.storage.getItem(this.key));
2888
- if (value != null && typeof value == "object" && this.options.type)
2889
- value.__proto__ = this.options.type.prototype;
2890
- this.value = value;
2891
- } else
2892
- this.value = this.options.default || void 0;
2893
- }
2894
- /**
2895
- * Callback function which is run when there are changes
2896
- *
2897
- * @param {(value: T) => any} fn Callback will run on each change; it's passed the next value & it's return is ignored
2898
- * @returns {() => void} Function which will unsubscribe the watch/callback when called
2899
- */
2900
- watch(fn2) {
2901
- const index = Object.keys(this.watches).length;
2902
- this.watches[index] = fn2;
2903
- return () => {
2904
- delete this.watches[index];
2905
- };
2906
- }
2907
- /**
2908
- * Return value as JSON string
2909
- *
2910
- * @returns {string} Stringified object as JSON
2911
- */
2912
- toString() {
2913
- return JSON.stringify(this.value);
2914
- }
2915
- /**
2916
- * Return current value
2917
- *
2918
- * @returns {T} Current value
2919
- */
2920
- valueOf() {
2921
- return this.value;
3016
+ function fromXml(xml) {
3017
+ xml = xml.trim();
3018
+ let pos = 0;
3019
+ function parseNode() {
3020
+ skipWhitespace();
3021
+ if (xml[pos] !== "<") return parseText();
3022
+ pos++;
3023
+ if (xml[pos] === "?") {
3024
+ parseDeclaration();
3025
+ return parseNode();
3026
+ }
3027
+ if (xml[pos] === "!") {
3028
+ parseComment();
3029
+ return parseNode();
3030
+ }
3031
+ const tagName = parseTagName();
3032
+ const attributes = parseAttributes();
3033
+ skipWhitespace();
3034
+ if (xml[pos] === "/" && xml[pos + 1] === ">") {
3035
+ pos += 2;
3036
+ return { tag: tagName, attributes, children: [] };
3037
+ }
3038
+ pos++;
3039
+ const children = [];
3040
+ while (pos < xml.length) {
3041
+ skipWhitespace();
3042
+ if (xml[pos] === "<" && xml[pos + 1] === "/") {
3043
+ pos += 2;
3044
+ parseTagName();
3045
+ skipWhitespace();
3046
+ pos++;
3047
+ break;
3048
+ }
3049
+ const child = parseNode();
3050
+ if (child) children.push(child);
3051
+ }
3052
+ return { tag: tagName, attributes, children };
3053
+ }
3054
+ function parseTagName() {
3055
+ let name = "";
3056
+ while (pos < xml.length && /[a-zA-Z0-9_:-]/.test(xml[pos])) name += xml[pos++];
3057
+ return name;
3058
+ }
3059
+ function parseAttributes() {
3060
+ const attrs = {};
3061
+ while (pos < xml.length) {
3062
+ skipWhitespace();
3063
+ if (xml[pos] === ">" || xml[pos] === "/") break;
3064
+ const name = parseTagName();
3065
+ skipWhitespace();
3066
+ if (xml[pos] === "=") {
3067
+ pos++;
3068
+ skipWhitespace();
3069
+ const quote = xml[pos++];
3070
+ let value = "";
3071
+ while (xml[pos] !== quote) value += xml[pos++];
3072
+ pos++;
3073
+ attrs[name] = escapeXml(value, true);
3074
+ }
2922
3075
  }
3076
+ return attrs;
2923
3077
  }
2924
- persist.Persist = Persist;
2925
- function persist$1(options) {
2926
- return (target, prop) => {
2927
- const key = options?.key || `${target.constructor.name}.${prop.toString()}`;
2928
- const wrapper = new Persist(key, options);
2929
- Object.defineProperty(target, prop, {
2930
- get: function() {
2931
- return wrapper.value;
2932
- },
2933
- set: function(v) {
2934
- wrapper.value = v;
2935
- }
2936
- });
2937
- };
3078
+ function parseText() {
3079
+ let text = "";
3080
+ while (pos < xml.length && xml[pos] !== "<") text += xml[pos++];
3081
+ text = text.trim();
3082
+ return text ? escapeXml(text, true) : null;
2938
3083
  }
2939
- persist.persist = persist$1;
2940
- return persist;
3084
+ function parseDeclaration() {
3085
+ while (xml[pos] !== ">") pos++;
3086
+ pos++;
3087
+ }
3088
+ function parseComment() {
3089
+ while (!(xml[pos] === "-" && xml[pos + 1] === "-" && xml[pos + 2] === ">")) pos++;
3090
+ pos += 3;
3091
+ }
3092
+ function skipWhitespace() {
3093
+ while (pos < xml.length && /\s/.test(xml[pos])) pos++;
3094
+ }
3095
+ return parseNode();
2941
3096
  }
2942
- var memoryStorage = {};
2943
- var hasRequiredMemoryStorage;
2944
- function requireMemoryStorage() {
2945
- if (hasRequiredMemoryStorage) return memoryStorage;
2946
- hasRequiredMemoryStorage = 1;
2947
- Object.defineProperty(memoryStorage, "__esModule", { value: true });
2948
- memoryStorage.MemoryStorage = void 0;
2949
- class MemoryStorage {
2950
- get length() {
2951
- return Object.keys(this).length;
2952
- }
2953
- clear() {
2954
- Object.keys(this).forEach((k) => this.removeItem(k));
2955
- }
2956
- getItem(key) {
2957
- return this[key];
2958
- }
2959
- key(index) {
2960
- return Object.keys(this)[index];
2961
- }
2962
- removeItem(key) {
2963
- delete this[key];
2964
- }
2965
- setItem(key, value) {
2966
- this[key] = value;
2967
- }
3097
+ function toXml(obj, indent = "") {
3098
+ if (typeof obj === "string") return escapeXml(obj);
3099
+ const { tag, attributes = {}, children = [] } = obj;
3100
+ let xml = `${indent}<${tag}`;
3101
+ for (const [key, value] of Object.entries(attributes))
3102
+ xml += ` ${key}="${escapeXml(value)}"`;
3103
+ if (children.length === 0) {
3104
+ xml += " />";
3105
+ return xml;
2968
3106
  }
2969
- memoryStorage.MemoryStorage = MemoryStorage;
2970
- return memoryStorage;
3107
+ xml += ">";
3108
+ const hasComplexChildren = children.some((c) => typeof c === "object");
3109
+ for (const child of children) {
3110
+ if (hasComplexChildren) xml += "\n";
3111
+ xml += toXml(child, hasComplexChildren ? indent + " " : "");
3112
+ }
3113
+ if (hasComplexChildren) xml += `
3114
+ ${indent}`;
3115
+ xml += `</${tag}>`;
3116
+ return xml;
2971
3117
  }
2972
- var hasRequiredDist;
2973
- function requireDist() {
2974
- if (hasRequiredDist) return dist;
2975
- hasRequiredDist = 1;
2976
- (function(exports$1) {
2977
- var __createBinding = dist && dist.__createBinding || (Object.create ? (function(o, m, k, k2) {
2978
- if (k2 === void 0) k2 = k;
2979
- var desc = Object.getOwnPropertyDescriptor(m, k);
2980
- if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
2981
- desc = { enumerable: true, get: function() {
2982
- return m[k];
2983
- } };
2984
- }
2985
- Object.defineProperty(o, k2, desc);
2986
- }) : (function(o, m, k, k2) {
2987
- if (k2 === void 0) k2 = k;
2988
- o[k2] = m[k];
2989
- }));
2990
- var __exportStar = dist && dist.__exportStar || function(m, exports$12) {
2991
- for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports$12, p)) __createBinding(exports$12, m, p);
2992
- };
2993
- Object.defineProperty(exports$1, "__esModule", { value: true });
2994
- __exportStar(requirePersist(), exports$1);
2995
- __exportStar(requireMemoryStorage(), exports$1);
2996
- })(dist);
2997
- return dist;
3118
+ function escapeXml(str, decode = false) {
3119
+ if (decode) {
3120
+ return str.replace(/&lt;/g, "<").replace(/&gt;/g, ">").replace(/&quot;/g, '"').replace(/&apos;/g, "'").replace(/&amp;/g, "&");
3121
+ }
3122
+ return str.replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;").replace(/"/g, "&quot;").replace(/'/g, "&apos;");
2998
3123
  }
2999
- requireDist();
3000
3124
  exports2.ASet = ASet;
3001
3125
  exports2.ArgParser = ArgParser;
3002
3126
  exports2.BadGatewayError = BadGatewayError;
@@ -3054,6 +3178,7 @@ ${err.message || err.toString()}`);
3054
3178
  exports2.dayOfYear = dayOfYear;
3055
3179
  exports2.dec2Frac = dec2Frac;
3056
3180
  exports2.dec2Hex = dec2Hex;
3181
+ exports2.decodeHtml = decodeHtml;
3057
3182
  exports2.decodeJwt = decodeJwt;
3058
3183
  exports2.deepCopy = deepCopy;
3059
3184
  exports2.deepMerge = deepMerge;
@@ -3063,6 +3188,7 @@ ${err.message || err.toString()}`);
3063
3188
  exports2.encodeQuery = encodeQuery;
3064
3189
  exports2.errorFromCode = errorFromCode;
3065
3190
  exports2.escapeRegex = escapeRegex;
3191
+ exports2.escapeXml = escapeXml;
3066
3192
  exports2.fileBrowser = fileBrowser;
3067
3193
  exports2.fileText = fileText;
3068
3194
  exports2.findByProp = findByProp;
@@ -3077,6 +3203,7 @@ ${err.message || err.toString()}`);
3077
3203
  exports2.formatPhoneNumber = formatPhoneNumber;
3078
3204
  exports2.frac2Dec = frac2Dec;
3079
3205
  exports2.fromCsv = fromCsv;
3206
+ exports2.fromXml = fromXml;
3080
3207
  exports2.gravatar = gravatar;
3081
3208
  exports2.hex2Int = hex2Int;
3082
3209
  exports2.hue2rgb = hue2rgb;
@@ -3117,6 +3244,7 @@ ${err.message || err.toString()}`);
3117
3244
  exports2.timestampFilename = timestampFilename;
3118
3245
  exports2.timezoneOffset = timezoneOffset;
3119
3246
  exports2.toCsv = toCsv;
3247
+ exports2.toXml = toXml;
3120
3248
  exports2.uploadWithProgress = uploadWithProgress;
3121
3249
  exports2.validateEmail = validateEmail;
3122
3250
  exports2.wordSegments = wordSegments;