@ztimson/utils 0.26.26 → 0.27.1
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 +149 -151
- package/dist/index.cjs.map +1 -1
- package/dist/index.mjs +149 -151
- package/dist/index.mjs.map +1 -1
- package/dist/math.d.ts +10 -0
- package/dist/objects.d.ts +5 -5
- package/dist/time.d.ts +3 -0
- package/package.json +1 -1
package/dist/index.mjs
CHANGED
|
@@ -117,44 +117,33 @@ ${opts.message || this.desc}`;
|
|
|
117
117
|
`;
|
|
118
118
|
}
|
|
119
119
|
}
|
|
120
|
-
function
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
target[key] = {};
|
|
130
|
-
applyDeltas(target[key], [value]);
|
|
131
|
-
} else {
|
|
132
|
-
target[key] = value;
|
|
133
|
-
}
|
|
134
|
-
}
|
|
120
|
+
function applyDelta(base, deltas) {
|
|
121
|
+
if (deltas === null) return null;
|
|
122
|
+
if (typeof base !== "object" || base === null) return deltas === void 0 ? base : deltas;
|
|
123
|
+
const result = Array.isArray(base) ? [...base] : { ...base };
|
|
124
|
+
for (const key in deltas) {
|
|
125
|
+
const val = deltas[key];
|
|
126
|
+
if (val === void 0) delete result[key];
|
|
127
|
+
else if (typeof val === "object" && val !== null && !Array.isArray(val)) result[key] = applyDelta(result[key], val);
|
|
128
|
+
else result[key] = val;
|
|
135
129
|
}
|
|
136
|
-
return
|
|
130
|
+
return result;
|
|
137
131
|
}
|
|
138
|
-
function calcDelta(old,
|
|
132
|
+
function calcDelta(old, updated) {
|
|
133
|
+
if (updated == null) return null;
|
|
139
134
|
const delta = {};
|
|
140
|
-
const
|
|
141
|
-
for (const key of keys) {
|
|
142
|
-
const
|
|
143
|
-
const
|
|
144
|
-
if (
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
if (JSON.stringify(val1) !== JSON.stringify(val2)) delta[key] = val1;
|
|
150
|
-
} else if (typeof val1 === "object" && typeof val2 === "object" && val1 && val2) {
|
|
151
|
-
const nested = calcDelta(val1, val2);
|
|
152
|
-
if (Object.keys(nested).length) delta[key] = nested;
|
|
153
|
-
} else if (val1 !== val2) {
|
|
154
|
-
delta[key] = val1;
|
|
135
|
+
const isObj = (v) => v && typeof v === "object" && !Array.isArray(v);
|
|
136
|
+
for (const key of /* @__PURE__ */ new Set([...old ? Object.keys(old) : [], ...updated ? Object.keys(updated) : []])) {
|
|
137
|
+
const oldVal = old == null ? void 0 : old[key];
|
|
138
|
+
const newVal = updated == null ? void 0 : updated[key];
|
|
139
|
+
if (isObj(oldVal) && isObj(newVal)) {
|
|
140
|
+
const nested = calcDelta(oldVal, newVal);
|
|
141
|
+
if (nested !== null && Object.keys(nested).length > 0) delta[key] = nested;
|
|
142
|
+
} else if (JSON.stringify(oldVal) !== JSON.stringify(newVal)) {
|
|
143
|
+
delta[key] = newVal;
|
|
155
144
|
}
|
|
156
145
|
}
|
|
157
|
-
return delta;
|
|
146
|
+
return Object.keys(delta).length === 0 ? {} : delta;
|
|
158
147
|
}
|
|
159
148
|
function clean(obj, undefinedOnly = false) {
|
|
160
149
|
if (obj == null) throw new Error("Cannot clean a NULL value");
|
|
@@ -896,6 +885,33 @@ function toCsv(target, flatten = true) {
|
|
|
896
885
|
}).join(","))
|
|
897
886
|
].join("\n");
|
|
898
887
|
}
|
|
888
|
+
function dec2Frac(num, maxDen = 1e3) {
|
|
889
|
+
let sign = Math.sign(num);
|
|
890
|
+
num = Math.abs(num);
|
|
891
|
+
if (Number.isInteger(num)) return sign * num + "";
|
|
892
|
+
let closest = { n: 0, d: 1, diff: Math.abs(num) };
|
|
893
|
+
for (let d = 1; d <= maxDen; d++) {
|
|
894
|
+
let n = Math.round(num * d);
|
|
895
|
+
let diff = Math.abs(num - n / d);
|
|
896
|
+
if (diff < closest.diff) {
|
|
897
|
+
closest = { n, d, diff };
|
|
898
|
+
if (diff < 1e-8) break;
|
|
899
|
+
}
|
|
900
|
+
}
|
|
901
|
+
let integer = Math.floor(closest.n / closest.d);
|
|
902
|
+
let numerator = closest.n - integer * closest.d;
|
|
903
|
+
return (sign < 0 ? "-" : "") + (integer ? integer + " " : "") + (numerator ? numerator + "/" + closest.d : "");
|
|
904
|
+
}
|
|
905
|
+
function fracToDec(frac) {
|
|
906
|
+
let split = frac.split(" ");
|
|
907
|
+
const whole = split.length == 2 ? Number(split[0]) : 0;
|
|
908
|
+
split = split.pop().split("/");
|
|
909
|
+
return whole + Number(split[0]) / Number(split[1]);
|
|
910
|
+
}
|
|
911
|
+
function numSuffix(n) {
|
|
912
|
+
const s = ["th", "st", "nd", "rd"], v = n % 100;
|
|
913
|
+
return `${n}${s[(v - 20) % 10] || s[v] || s[0]}`;
|
|
914
|
+
}
|
|
899
915
|
function adjustedInterval(cb, ms) {
|
|
900
916
|
let cancel = false, timeout = null;
|
|
901
917
|
const p = async () => {
|
|
@@ -911,103 +927,101 @@ function adjustedInterval(cb, ms) {
|
|
|
911
927
|
if (timeout) clearTimeout(timeout);
|
|
912
928
|
};
|
|
913
929
|
}
|
|
914
|
-
function
|
|
915
|
-
|
|
916
|
-
|
|
917
|
-
|
|
918
|
-
|
|
919
|
-
|
|
920
|
-
|
|
921
|
-
|
|
922
|
-
|
|
923
|
-
|
|
924
|
-
|
|
925
|
-
|
|
926
|
-
|
|
927
|
-
|
|
928
|
-
|
|
929
|
-
|
|
930
|
-
|
|
931
|
-
|
|
932
|
-
|
|
933
|
-
|
|
934
|
-
|
|
935
|
-
|
|
936
|
-
|
|
937
|
-
|
|
938
|
-
|
|
939
|
-
|
|
940
|
-
|
|
941
|
-
|
|
942
|
-
|
|
943
|
-
|
|
944
|
-
|
|
945
|
-
|
|
946
|
-
|
|
947
|
-
const
|
|
948
|
-
|
|
949
|
-
|
|
950
|
-
|
|
951
|
-
|
|
952
|
-
|
|
953
|
-
|
|
954
|
-
const
|
|
955
|
-
|
|
956
|
-
}
|
|
957
|
-
|
|
958
|
-
|
|
959
|
-
|
|
960
|
-
|
|
961
|
-
|
|
962
|
-
|
|
963
|
-
|
|
964
|
-
|
|
965
|
-
|
|
966
|
-
|
|
967
|
-
|
|
968
|
-
|
|
969
|
-
|
|
970
|
-
|
|
930
|
+
function dayOfWeek(d) {
|
|
931
|
+
return ["Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"][d];
|
|
932
|
+
}
|
|
933
|
+
function dayOfYear(date) {
|
|
934
|
+
const start = new Date(Date.UTC(date.getUTCFullYear(), 0, 1));
|
|
935
|
+
return Math.ceil((date.getTime() - start.getTime()) / (1e3 * 60 * 60 * 24));
|
|
936
|
+
}
|
|
937
|
+
function formatDate(format = "YYYY-MM-DD H:mm", date = /* @__PURE__ */ new Date(), tz = "local") {
|
|
938
|
+
var _a;
|
|
939
|
+
if (typeof date === "number" || typeof date === "string") date = new Date(date);
|
|
940
|
+
if (isNaN(date.getTime())) throw new Error("Invalid date input");
|
|
941
|
+
const numericTz = typeof tz === "number";
|
|
942
|
+
const localTz = tz === "local" || !numericTz && ((_a = tz.toLowerCase) == null ? void 0 : _a.call(tz)) === "local";
|
|
943
|
+
const tzName = localTz ? Intl.DateTimeFormat().resolvedOptions().timeZone : numericTz ? "UTC" : tz;
|
|
944
|
+
if (!numericTz && tzName !== "UTC") {
|
|
945
|
+
try {
|
|
946
|
+
new Intl.DateTimeFormat("en-US", { timeZone: tzName }).format();
|
|
947
|
+
} catch {
|
|
948
|
+
throw new Error(`Invalid timezone: ${tzName}`);
|
|
949
|
+
}
|
|
950
|
+
}
|
|
951
|
+
let zonedDate = new Date(date);
|
|
952
|
+
if (!numericTz && tzName !== "UTC") {
|
|
953
|
+
const parts = new Intl.DateTimeFormat("en-US", {
|
|
954
|
+
timeZone: tzName,
|
|
955
|
+
year: "numeric",
|
|
956
|
+
month: "2-digit",
|
|
957
|
+
day: "2-digit",
|
|
958
|
+
hour: "2-digit",
|
|
959
|
+
minute: "2-digit",
|
|
960
|
+
second: "2-digit",
|
|
961
|
+
hour12: false
|
|
962
|
+
}).formatToParts(date);
|
|
963
|
+
const get2 = (type) => {
|
|
964
|
+
var _a2;
|
|
965
|
+
return (_a2 = parts.find((p) => p.type === type)) == null ? void 0 : _a2.value;
|
|
966
|
+
};
|
|
967
|
+
const build = `${get2("year")}-${get2("month")}-${get2("day")}T${get2("hour")}:${get2("minute")}:${get2("second")}Z`;
|
|
968
|
+
zonedDate = new Date(build);
|
|
969
|
+
} else if (numericTz || tzName === "UTC") {
|
|
970
|
+
const offset = numericTz ? tz : 0;
|
|
971
|
+
zonedDate = new Date(date.getTime() + offset * 60 * 60 * 1e3);
|
|
972
|
+
}
|
|
973
|
+
const get = (fn2) => numericTz || tzName === "UTC" ? zonedDate[`getUTC${fn2}`]() : zonedDate[`get${fn2}`]();
|
|
974
|
+
function getTZOffset() {
|
|
975
|
+
var _a2, _b;
|
|
976
|
+
if (numericTz) {
|
|
977
|
+
const total = tz * 60;
|
|
978
|
+
const hours = Math.floor(Math.abs(total) / 60);
|
|
979
|
+
const mins = Math.abs(total) % 60;
|
|
980
|
+
return `${tz >= 0 ? "+" : "-"}${String(hours).padStart(2, "0")}:${String(mins).padStart(2, "0")}`;
|
|
981
|
+
}
|
|
982
|
+
try {
|
|
983
|
+
const offset = (_b = (_a2 = new Intl.DateTimeFormat("en-US", { timeZone: tzName, timeZoneName: "longOffset", hour: "2-digit", minute: "2-digit" }).formatToParts(date).find((p) => p.type === "timeZoneName")) == null ? void 0 : _a2.value.match(/([+-]\d{2}:\d{2})/)) == null ? void 0 : _b[1];
|
|
984
|
+
if (offset) return offset;
|
|
985
|
+
} catch {
|
|
986
|
+
}
|
|
987
|
+
return "+00:00";
|
|
988
|
+
}
|
|
989
|
+
function getTZAbbr() {
|
|
990
|
+
var _a2;
|
|
991
|
+
if (numericTz && tz === 0) return "UTC";
|
|
992
|
+
try {
|
|
993
|
+
return ((_a2 = new Intl.DateTimeFormat("en-US", { timeZone: tzName, timeZoneName: "short" }).formatToParts(date).find((p) => p.type === "timeZoneName")) == null ? void 0 : _a2.value) || "";
|
|
994
|
+
} catch {
|
|
995
|
+
return tzName;
|
|
971
996
|
}
|
|
972
997
|
}
|
|
973
|
-
function tzOffset(offset) {
|
|
974
|
-
const hours = ~~(offset / 60);
|
|
975
|
-
const minutes = offset % 60;
|
|
976
|
-
return (offset > 0 ? "-" : "") + `${hours}:${minutes.toString().padStart(2, "0")}`;
|
|
977
|
-
}
|
|
978
|
-
if (typeof date == "number" || typeof date == "string" || date == null) date = new Date(date);
|
|
979
|
-
let t;
|
|
980
|
-
if (tz == null) tz = -(date.getTimezoneOffset() / 60);
|
|
981
|
-
t = timezones.find((t2) => isNaN(tz) ? t2[0] == tz : t2[1] == tz);
|
|
982
|
-
if (!t) throw new Error(`Unknown timezone: ${tz}`);
|
|
983
|
-
date = adjustTz(date, t[1]);
|
|
984
998
|
const tokens = {
|
|
985
|
-
|
|
986
|
-
|
|
987
|
-
|
|
988
|
-
|
|
989
|
-
|
|
990
|
-
|
|
991
|
-
|
|
992
|
-
|
|
993
|
-
|
|
994
|
-
|
|
995
|
-
|
|
996
|
-
|
|
997
|
-
|
|
998
|
-
|
|
999
|
-
|
|
1000
|
-
|
|
1001
|
-
|
|
1002
|
-
|
|
1003
|
-
|
|
1004
|
-
|
|
1005
|
-
|
|
1006
|
-
|
|
1007
|
-
|
|
1008
|
-
|
|
1009
|
-
|
|
1010
|
-
|
|
999
|
+
YYYY: get("FullYear").toString(),
|
|
1000
|
+
YY: get("FullYear").toString().slice(2),
|
|
1001
|
+
MMMM: month(get("Month")),
|
|
1002
|
+
MMM: month(get("Month")).slice(0, 3),
|
|
1003
|
+
MM: (get("Month") + 1).toString().padStart(2, "0"),
|
|
1004
|
+
M: (get("Month") + 1).toString(),
|
|
1005
|
+
DDD: dayOfYear(zonedDate).toString(),
|
|
1006
|
+
DD: get("Date").toString().padStart(2, "0"),
|
|
1007
|
+
Do: numSuffix(get("Date")),
|
|
1008
|
+
D: get("Date").toString(),
|
|
1009
|
+
dddd: dayOfWeek(get("Day")),
|
|
1010
|
+
ddd: dayOfWeek(get("Day")).slice(0, 3),
|
|
1011
|
+
HH: get("Hours").toString().padStart(2, "0"),
|
|
1012
|
+
H: get("Hours").toString(),
|
|
1013
|
+
hh: (get("Hours") % 12 || 12).toString().padStart(2, "0"),
|
|
1014
|
+
h: (get("Hours") % 12 || 12).toString(),
|
|
1015
|
+
mm: get("Minutes").toString().padStart(2, "0"),
|
|
1016
|
+
m: get("Minutes").toString(),
|
|
1017
|
+
ss: get("Seconds").toString().padStart(2, "0"),
|
|
1018
|
+
s: get("Seconds").toString(),
|
|
1019
|
+
SSS: get("Milliseconds").toString().padStart(3, "0"),
|
|
1020
|
+
A: get("Hours") >= 12 ? "PM" : "AM",
|
|
1021
|
+
a: get("Hours") >= 12 ? "pm" : "am",
|
|
1022
|
+
ZZ: getTZOffset().replace(":", ""),
|
|
1023
|
+
Z: getTZOffset(),
|
|
1024
|
+
z: getTZAbbr()
|
|
1011
1025
|
};
|
|
1012
1026
|
return format.replace(/YYYY|YY|MMMM|MMM|MM|M|DDD|DD|Do|D|dddd|ddd|HH|H|hh|h|mm|m|ss|s|SSS|A|a|ZZ|Z|z/g, (token) => tokens[token]);
|
|
1013
1027
|
}
|
|
@@ -1015,6 +1029,9 @@ function instantInterval(fn2, interval) {
|
|
|
1015
1029
|
fn2();
|
|
1016
1030
|
return setInterval(fn2, interval);
|
|
1017
1031
|
}
|
|
1032
|
+
function month(m) {
|
|
1033
|
+
return ["January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"][m];
|
|
1034
|
+
}
|
|
1018
1035
|
function sleep(ms) {
|
|
1019
1036
|
return new Promise((res) => setTimeout(res, ms));
|
|
1020
1037
|
}
|
|
@@ -1763,29 +1780,6 @@ const _Logger = class _Logger extends TypedEmitter {
|
|
|
1763
1780
|
};
|
|
1764
1781
|
__publicField(_Logger, "LOG_LEVEL", 4);
|
|
1765
1782
|
let Logger = _Logger;
|
|
1766
|
-
function dec2Frac(num, maxDen = 1e3) {
|
|
1767
|
-
let sign = Math.sign(num);
|
|
1768
|
-
num = Math.abs(num);
|
|
1769
|
-
if (Number.isInteger(num)) return sign * num + "";
|
|
1770
|
-
let closest = { n: 0, d: 1, diff: Math.abs(num) };
|
|
1771
|
-
for (let d = 1; d <= maxDen; d++) {
|
|
1772
|
-
let n = Math.round(num * d);
|
|
1773
|
-
let diff = Math.abs(num - n / d);
|
|
1774
|
-
if (diff < closest.diff) {
|
|
1775
|
-
closest = { n, d, diff };
|
|
1776
|
-
if (diff < 1e-8) break;
|
|
1777
|
-
}
|
|
1778
|
-
}
|
|
1779
|
-
let integer = Math.floor(closest.n / closest.d);
|
|
1780
|
-
let numerator = closest.n - integer * closest.d;
|
|
1781
|
-
return (sign < 0 ? "-" : "") + (integer ? integer + " " : "") + (numerator ? numerator + "/" + closest.d : "");
|
|
1782
|
-
}
|
|
1783
|
-
function fracToDec(frac) {
|
|
1784
|
-
let split = frac.split(" ");
|
|
1785
|
-
const whole = split.length == 2 ? Number(split[0]) : 0;
|
|
1786
|
-
split = split.pop().split("/");
|
|
1787
|
-
return whole + Number(split[0]) / Number(split[1]);
|
|
1788
|
-
}
|
|
1789
1783
|
function compareVersions(target, vs) {
|
|
1790
1784
|
const [tMajor, tMinor, tPatch] = target.split(".").map((v) => +v.replace(/[^0-9]/g, ""));
|
|
1791
1785
|
const [vMajor, vMinor, vPatch] = vs.split(".").map((v) => +v.replace(/[^0-9]/g, ""));
|
|
@@ -2370,7 +2364,7 @@ export {
|
|
|
2370
2364
|
UnauthorizedError,
|
|
2371
2365
|
addUnique,
|
|
2372
2366
|
adjustedInterval,
|
|
2373
|
-
|
|
2367
|
+
applyDelta,
|
|
2374
2368
|
arrayDiff,
|
|
2375
2369
|
calcDelta,
|
|
2376
2370
|
camelCase,
|
|
@@ -2379,6 +2373,8 @@ export {
|
|
|
2379
2373
|
compareVersions,
|
|
2380
2374
|
contrast,
|
|
2381
2375
|
createJwt,
|
|
2376
|
+
dayOfWeek,
|
|
2377
|
+
dayOfYear,
|
|
2382
2378
|
dec2Frac,
|
|
2383
2379
|
decodeJwt,
|
|
2384
2380
|
deepCopy,
|
|
@@ -2415,6 +2411,8 @@ export {
|
|
|
2415
2411
|
matchAll,
|
|
2416
2412
|
md5,
|
|
2417
2413
|
mixin,
|
|
2414
|
+
month,
|
|
2415
|
+
numSuffix,
|
|
2418
2416
|
pad,
|
|
2419
2417
|
parseUrl,
|
|
2420
2418
|
pascalCase,
|