hanzio 1.2.0 → 2.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +786 -239
- package/dist/api-wrapper/builders.d.ts +4 -3
- package/dist/api-wrapper/create-client.d.ts +1 -1
- package/dist/api-wrapper/describe.d.ts +16 -0
- package/dist/api-wrapper/endpoint.d.ts +18 -0
- package/dist/api-wrapper/errors.d.ts +39 -2
- package/dist/api-wrapper/index.d.ts +5 -0
- package/dist/api-wrapper/otel.d.ts +44 -0
- package/dist/api-wrapper/paginate.d.ts +12 -0
- package/dist/api-wrapper/redaction.d.ts +2 -0
- package/dist/api-wrapper/shared.d.ts +16 -2
- package/dist/api-wrapper/testing.d.ts +23 -0
- package/dist/api-wrapper/transport.d.ts +4 -5
- package/dist/api-wrapper/types.d.ts +103 -18
- package/dist/array/index.d.ts +50 -4
- package/dist/cache/createCache.d.ts +31 -0
- package/dist/cache/index.d.ts +19 -2
- package/dist/color/contrast.d.ts +40 -0
- package/dist/color/index.d.ts +2 -0
- package/dist/{math → color}/metricsSeriesColors.d.ts +14 -7
- package/dist/cool-console-log/index.d.ts +34 -5
- package/dist/crypto/encoding.d.ts +18 -0
- package/dist/crypto/hash.d.ts +33 -0
- package/dist/crypto/index.d.ts +4 -0
- package/dist/crypto/sealer.d.ts +25 -0
- package/dist/crypto/webhook.d.ts +20 -0
- package/dist/date/index.d.ts +46 -2
- package/dist/emitter/index.d.ts +21 -0
- package/dist/error/index.d.ts +12 -0
- package/dist/format/index.d.ts +102 -0
- package/dist/function/index.d.ts +60 -0
- package/dist/guard/index.d.ts +20 -0
- package/dist/i18n/index.d.ts +37 -0
- package/dist/index-0zvtcbzy.js +224 -0
- package/dist/index-8r2vdzjg.js +87 -0
- package/dist/index-hy7kbb99.js +157 -0
- package/dist/index-hyt6c56h.js +290 -0
- package/dist/{src/secrets/infisical.js → index-j1ybktbr.js} +500 -538
- package/dist/index-k9yx6bne.js +89 -0
- package/dist/index-kj1phgrx.js +169 -0
- package/dist/index-ktynw3vs.js +37 -0
- package/dist/index-mnkcfyx8.js +78 -0
- package/dist/{p-queue/index.js → index-pwt0dz63.js} +7 -11
- package/dist/index-rp5pqghz.js +157 -0
- package/dist/index-w882zry3.js +29 -0
- package/dist/index.d.ts +7 -7
- package/dist/jwt/index.d.ts +50 -2
- package/dist/math/index.d.ts +2 -2
- package/dist/math/linearRegressionTrend.d.ts +14 -1
- package/dist/math/scale.d.ts +8 -0
- package/dist/object/index.d.ts +19 -0
- package/dist/p-queue/index.d.ts +1 -1
- package/dist/promise/index.d.ts +97 -2
- package/dist/secrets/core.d.ts +7 -0
- package/dist/secrets/index.d.ts +3 -1
- package/dist/secrets/public-config.d.ts +7 -0
- package/dist/secrets/vite.d.ts +1 -0
- package/dist/secrets/worker.d.ts +1 -0
- package/dist/sitemap/index.d.ts +48 -6
- package/dist/src/api-wrapper/index.js +60 -1130
- package/dist/src/api-wrapper/testing.js +20 -0
- package/dist/{cool-console-log → src/cool-console-log}/index.js +80 -33
- package/dist/src/crypto/index.js +195 -0
- package/dist/src/format/index.js +211 -0
- package/dist/src/i18n/index.js +36 -0
- package/dist/src/index.js +739 -3145
- package/dist/src/jwt/index.js +138 -92
- package/dist/src/p-queue/index.js +9 -437
- package/dist/src/secrets/index.js +50 -1428
- package/dist/src/secrets/vite.js +10 -39
- package/dist/src/secrets/worker.js +14 -273
- package/dist/src/sitemap/index.js +183 -511
- package/dist/src/storage/index.js +119 -0
- package/dist/src/zod/index.js +340 -167
- package/dist/state/index.d.ts +21 -0
- package/dist/storage/index.d.ts +58 -0
- package/dist/string/index.d.ts +75 -2
- package/dist/typedswitch/index.d.ts +31 -24
- package/dist/types/index.d.ts +11 -0
- package/dist/url/index.d.ts +50 -1
- package/dist/zod/index.d.ts +32 -3
- package/dist/zod/introspect.d.ts +19 -0
- package/dist/zod/jsonToZodSchemaMapper.d.ts +3 -1
- package/dist/zod/zodMinMaxFilter.d.ts +22 -3
- package/dist/zod/zodToTypeString.d.ts +8 -3
- package/package.json +78 -7
- package/src/api-wrapper/actions-impl.ts +11 -72
- package/src/api-wrapper/builders.ts +32 -25
- package/src/api-wrapper/create-client.ts +171 -41
- package/src/api-wrapper/describe.ts +157 -0
- package/src/api-wrapper/endpoint.ts +26 -0
- package/src/api-wrapper/error-reporting.ts +7 -1
- package/src/api-wrapper/errors.ts +107 -2
- package/src/api-wrapper/headers.ts +11 -6
- package/src/api-wrapper/index.ts +5 -0
- package/src/api-wrapper/otel.ts +139 -0
- package/src/api-wrapper/paginate.ts +28 -0
- package/src/api-wrapper/redaction.ts +42 -0
- package/src/api-wrapper/shared.ts +21 -2
- package/src/api-wrapper/testing.ts +48 -0
- package/src/api-wrapper/transport.ts +41 -43
- package/src/api-wrapper/types.ts +185 -18
- package/src/array/index.ts +195 -42
- package/src/cache/createCache.ts +157 -0
- package/src/cache/index.ts +132 -147
- package/src/color/contrast.ts +163 -0
- package/src/color/index.ts +22 -0
- package/src/{math → color}/metricsSeriesColors.ts +47 -49
- package/src/cool-console-log/index.ts +128 -41
- package/src/crypto/encoding.ts +83 -0
- package/src/crypto/hash.ts +170 -0
- package/src/crypto/index.ts +26 -0
- package/src/crypto/sealer.ts +168 -0
- package/src/crypto/webhook.ts +86 -0
- package/src/date/index.ts +109 -34
- package/src/emitter/index.ts +82 -0
- package/src/error/index.ts +63 -0
- package/src/format/index.ts +389 -0
- package/src/function/index.ts +201 -0
- package/src/guard/index.ts +80 -0
- package/src/i18n/index.ts +125 -0
- package/src/index.ts +11 -7
- package/src/jwt/index.ts +199 -125
- package/src/math/index.ts +5 -10
- package/src/math/linearRegressionTrend.ts +33 -8
- package/src/math/scale.ts +17 -0
- package/src/object/index.ts +99 -0
- package/src/p-queue/index.ts +2 -0
- package/src/promise/index.ts +304 -9
- package/src/secrets/core.ts +72 -16
- package/src/secrets/index.ts +16 -4
- package/src/secrets/public-config.ts +47 -0
- package/src/secrets/vite.ts +2 -0
- package/src/secrets/worker.ts +2 -0
- package/src/sitemap/index.ts +293 -130
- package/src/state/index.ts +133 -81
- package/src/storage/index.ts +187 -0
- package/src/string/index.ts +261 -23
- package/src/typedswitch/index.ts +58 -38
- package/src/types/index.ts +14 -0
- package/src/url/index.ts +146 -1
- package/src/zod/index.ts +105 -9
- package/src/zod/introspect.ts +103 -0
- package/src/zod/jsonToZodSchemaMapper.ts +44 -21
- package/src/zod/zodMinMaxFilter.ts +37 -13
- package/src/zod/zodToTypeString.ts +184 -181
- package/dist/api-wrapper/index.js +0 -250
- package/dist/gzip/index.d.ts +0 -2
- package/dist/gzip/index.js +0 -16
- package/dist/index.js +0 -1823
- package/dist/jwt/index.js +0 -19
- package/dist/sitemap/index.js +0 -552
- package/dist/src/gzip/index.js +0 -16
- package/dist/src/secrets/loaders.js +0 -1529
- package/dist/zod/index.js +0 -210
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
export type PlaceholderValue = string | number;
|
|
2
|
+
type Chars<S extends string> = S extends `${infer C}${infer Rest}` ? C | Chars<Rest> : never;
|
|
3
|
+
type Letter = Chars<'abcdefghijklmnopqrstuvwxyz'>;
|
|
4
|
+
type WordChar = Letter | Uppercase<Letter> | Chars<'0123456789_'>;
|
|
5
|
+
type IsWord<S extends string> = S extends `${infer C}${infer Rest}` ? C extends WordChar ? Rest extends '' ? true : IsWord<Rest> : false : false;
|
|
6
|
+
type AfterLastBrace<S extends string> = S extends `${string}{${infer Rest}` ? AfterLastBrace<Rest> : S;
|
|
7
|
+
type ExtractNames<S extends string, Found extends string = never> = S extends `${string}{${infer Body}}${infer Rest}` ? ExtractNames<Rest, Found | (IsWord<AfterLastBrace<Body>> extends true ? AfterLastBrace<Body> : never)> : Found;
|
|
8
|
+
/** `'Hi {name}, you have {count}'` → `'name' | 'count'`; `string` for non-literal templates. */
|
|
9
|
+
export type PlaceholderNames<S extends string> = string extends S ? string : ExtractNames<S>;
|
|
10
|
+
export type PlaceholderParams<S extends string> = Record<PlaceholderNames<S>, PlaceholderValue>;
|
|
11
|
+
/** Params argument: required with placeholders, absent without, optional for non-literal templates. */
|
|
12
|
+
export type PlaceholderArgs<S extends string> = string extends S ? [params?: PlaceholderParams<S>] : [PlaceholderNames<S>] extends [never] ? [] : [params: PlaceholderParams<S>];
|
|
13
|
+
/** Unique placeholder names in order of first appearance. */
|
|
14
|
+
export declare function extractPlaceholders<S extends string>(template: S): PlaceholderNames<S>[];
|
|
15
|
+
/**
|
|
16
|
+
* Replaces `{name}` placeholders with `params`. Placeholders without a
|
|
17
|
+
* (non-null) param are left as-is. There is no escape syntax.
|
|
18
|
+
*/
|
|
19
|
+
export declare function interpolate<S extends string>(template: S, ...args: PlaceholderArgs<S>): string;
|
|
20
|
+
export type Messages = {
|
|
21
|
+
readonly [key: string]: string | Messages;
|
|
22
|
+
};
|
|
23
|
+
/** Dot-path keys of the string leaves: `{ a: { b: 'x' } }` → `'a.b'`. */
|
|
24
|
+
export type MessageKeys<T> = {
|
|
25
|
+
[K in keyof T & string]: T[K] extends string ? K : `${K}.${MessageKeys<T[K]>}`;
|
|
26
|
+
}[keyof T & string];
|
|
27
|
+
/** Message at a dot-path key. */
|
|
28
|
+
export type MessageAt<T, K extends string> = K extends keyof T ? T[K] : K extends `${infer Head}.${infer Rest}` ? Head extends keyof T ? MessageAt<T[Head], Rest> : never : never;
|
|
29
|
+
/** `{ a: { b: 'x' } }` → `{ 'a.b': 'x' }` */
|
|
30
|
+
export declare function flattenMessages<const T extends Messages>(messages: T): Record<MessageKeys<T>, string>;
|
|
31
|
+
/**
|
|
32
|
+
* Typed `t(key, params)` over a nested messages object. With literal messages
|
|
33
|
+
* (inline `const` objects), params are required exactly when the message has
|
|
34
|
+
* placeholders. Unknown keys at runtime return the key.
|
|
35
|
+
*/
|
|
36
|
+
export declare function createTranslator<const T extends Messages>(messages: T): <K extends MessageKeys<T>>(key: K, ...args: PlaceholderArgs<Extract<MessageAt<T, K>, string>>) => string;
|
|
37
|
+
export {};
|
|
@@ -0,0 +1,224 @@
|
|
|
1
|
+
// src/promise/index.ts
|
|
2
|
+
function ok2(data) {
|
|
3
|
+
return { ok: true, data, error: null };
|
|
4
|
+
}
|
|
5
|
+
function err2(error) {
|
|
6
|
+
return { ok: false, data: null, error };
|
|
7
|
+
}
|
|
8
|
+
function isSuccess2(result) {
|
|
9
|
+
return result.ok;
|
|
10
|
+
}
|
|
11
|
+
function isFailure2(result) {
|
|
12
|
+
return !result.ok;
|
|
13
|
+
}
|
|
14
|
+
function unwrapResult2(result) {
|
|
15
|
+
if (result.ok)
|
|
16
|
+
return result.data;
|
|
17
|
+
throw result.error;
|
|
18
|
+
}
|
|
19
|
+
function backgroundPromise2(promiseFactory, options = {}) {
|
|
20
|
+
const run = () => {
|
|
21
|
+
promiseFactory().then(() => options.onSuccess?.()).catch((error) => options.onError?.(error));
|
|
22
|
+
};
|
|
23
|
+
if (options.scheduler) {
|
|
24
|
+
options.scheduler(run);
|
|
25
|
+
return;
|
|
26
|
+
}
|
|
27
|
+
run();
|
|
28
|
+
}
|
|
29
|
+
function backgroundPromiseSync2(promiseFactory, options = {}) {
|
|
30
|
+
backgroundPromise2(promiseFactory, {
|
|
31
|
+
...options,
|
|
32
|
+
scheduler: options.scheduler ?? queueMicrotask
|
|
33
|
+
});
|
|
34
|
+
}
|
|
35
|
+
function promiseTimeout2(ms, options = {}) {
|
|
36
|
+
const { signal } = options;
|
|
37
|
+
return new Promise((resolve, reject) => {
|
|
38
|
+
if (signal?.aborted) {
|
|
39
|
+
reject(signal.reason);
|
|
40
|
+
return;
|
|
41
|
+
}
|
|
42
|
+
const onAbort = () => {
|
|
43
|
+
clearTimeout(timer);
|
|
44
|
+
reject(signal?.reason);
|
|
45
|
+
};
|
|
46
|
+
const timer = setTimeout(() => {
|
|
47
|
+
signal?.removeEventListener("abort", onAbort);
|
|
48
|
+
resolve();
|
|
49
|
+
}, ms);
|
|
50
|
+
signal?.addEventListener("abort", onAbort, { once: true });
|
|
51
|
+
});
|
|
52
|
+
}
|
|
53
|
+
async function tryCatch2(input) {
|
|
54
|
+
try {
|
|
55
|
+
return ok2(await (typeof input === "function" ? input() : input));
|
|
56
|
+
} catch (error) {
|
|
57
|
+
return err2(error);
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
class PromiseTimeoutError2 extends Error {
|
|
62
|
+
timeoutMs;
|
|
63
|
+
constructor(timeoutMs, message) {
|
|
64
|
+
super(message ?? `Promise timed out after ${timeoutMs}ms`);
|
|
65
|
+
this.name = "PromiseTimeoutError";
|
|
66
|
+
this.timeoutMs = timeoutMs;
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
async function withTimeout2(input, ms, options = {}) {
|
|
70
|
+
const controller = new AbortController;
|
|
71
|
+
const onAbort = () => controller.abort(options.signal?.reason);
|
|
72
|
+
if (options.signal?.aborted)
|
|
73
|
+
onAbort();
|
|
74
|
+
else
|
|
75
|
+
options.signal?.addEventListener("abort", onAbort, { once: true });
|
|
76
|
+
const timer = setTimeout(() => controller.abort(new PromiseTimeoutError2(ms, options.message)), ms);
|
|
77
|
+
let rejectOnAbort = () => {};
|
|
78
|
+
try {
|
|
79
|
+
const aborted = new Promise((_, reject) => {
|
|
80
|
+
rejectOnAbort = () => reject(controller.signal.reason);
|
|
81
|
+
controller.signal.addEventListener("abort", rejectOnAbort, { once: true });
|
|
82
|
+
});
|
|
83
|
+
if (controller.signal.aborted)
|
|
84
|
+
throw controller.signal.reason;
|
|
85
|
+
const promise = typeof input === "function" ? input(controller.signal) : input;
|
|
86
|
+
return await Promise.race([promise, aborted]);
|
|
87
|
+
} finally {
|
|
88
|
+
clearTimeout(timer);
|
|
89
|
+
options.signal?.removeEventListener("abort", onAbort);
|
|
90
|
+
controller.signal.removeEventListener("abort", rejectOnAbort);
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
function exponentialBackoff2(attempt, options = {}) {
|
|
94
|
+
const {
|
|
95
|
+
baseMs = 300,
|
|
96
|
+
maxMs = 30000,
|
|
97
|
+
jitter = true,
|
|
98
|
+
jitterRatio = 0.25,
|
|
99
|
+
random = Math.random
|
|
100
|
+
} = options;
|
|
101
|
+
const delay = Math.min(maxMs, baseMs * 2 ** Math.max(0, attempt - 1));
|
|
102
|
+
if (jitter === "partial")
|
|
103
|
+
return Math.round(delay * (1 + jitterRatio * random()));
|
|
104
|
+
return jitter ? Math.round(random() * delay) : delay;
|
|
105
|
+
}
|
|
106
|
+
async function retry2(fn, options = {}) {
|
|
107
|
+
const { retries = 3, delayMs, shouldRetry, onRetry, signal } = options;
|
|
108
|
+
for (let attempt = 0;; attempt++) {
|
|
109
|
+
signal?.throwIfAborted();
|
|
110
|
+
try {
|
|
111
|
+
return await fn({ attempt, signal });
|
|
112
|
+
} catch (error) {
|
|
113
|
+
const nextAttempt = attempt + 1;
|
|
114
|
+
if (attempt >= retries || shouldRetry?.(error, nextAttempt) === false) {
|
|
115
|
+
throw error;
|
|
116
|
+
}
|
|
117
|
+
const delay = delayMs === undefined ? exponentialBackoff2(nextAttempt) : typeof delayMs === "function" ? delayMs(nextAttempt, error) : delayMs;
|
|
118
|
+
onRetry?.(error, nextAttempt, delay);
|
|
119
|
+
await promiseTimeout2(delay, { signal });
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
async function pMap2(items, fn, options = {}) {
|
|
124
|
+
const { concurrency = Number.POSITIVE_INFINITY, signal } = options;
|
|
125
|
+
if (!(concurrency >= 1)) {
|
|
126
|
+
throw new Error("Concurrency must be at least 1");
|
|
127
|
+
}
|
|
128
|
+
const list = [...items];
|
|
129
|
+
const results = new Array(list.length);
|
|
130
|
+
let next = 0;
|
|
131
|
+
const worker = async () => {
|
|
132
|
+
while (next < list.length) {
|
|
133
|
+
signal?.throwIfAborted();
|
|
134
|
+
const index = next++;
|
|
135
|
+
results[index] = await fn(list[index], index);
|
|
136
|
+
}
|
|
137
|
+
};
|
|
138
|
+
await Promise.all(Array.from({ length: Math.min(concurrency, list.length) }, worker));
|
|
139
|
+
return results;
|
|
140
|
+
}
|
|
141
|
+
var clock = () => globalThis.performance?.now() ?? Date.now();
|
|
142
|
+
function startTimer2() {
|
|
143
|
+
const start = clock();
|
|
144
|
+
return () => clock() - start;
|
|
145
|
+
}
|
|
146
|
+
async function timed2(fn) {
|
|
147
|
+
const elapsed = startTimer2();
|
|
148
|
+
const result = await fn();
|
|
149
|
+
return { result, durationMs: elapsed() };
|
|
150
|
+
}
|
|
151
|
+
function anySignal2(...signals) {
|
|
152
|
+
const list = signals.filter((signal) => signal !== undefined);
|
|
153
|
+
if (list.length === 1)
|
|
154
|
+
return list[0];
|
|
155
|
+
if (typeof AbortSignal.any === "function")
|
|
156
|
+
return AbortSignal.any(list);
|
|
157
|
+
const controller = new AbortController;
|
|
158
|
+
const aborted = list.find((signal) => signal.aborted);
|
|
159
|
+
if (aborted) {
|
|
160
|
+
controller.abort(aborted.reason);
|
|
161
|
+
return controller.signal;
|
|
162
|
+
}
|
|
163
|
+
const onAbort = (event) => {
|
|
164
|
+
for (const signal of list)
|
|
165
|
+
signal.removeEventListener("abort", onAbort);
|
|
166
|
+
controller.abort(event.target.reason);
|
|
167
|
+
};
|
|
168
|
+
for (const signal of list)
|
|
169
|
+
signal.addEventListener("abort", onAbort);
|
|
170
|
+
return controller.signal;
|
|
171
|
+
}
|
|
172
|
+
function timeoutSignal2(ms, signal) {
|
|
173
|
+
if (typeof AbortSignal.timeout === "function") {
|
|
174
|
+
return anySignal2(AbortSignal.timeout(ms), signal);
|
|
175
|
+
}
|
|
176
|
+
const controller = new AbortController;
|
|
177
|
+
setTimeout(() => {
|
|
178
|
+
const reason = new Error("The operation timed out.");
|
|
179
|
+
reason.name = "TimeoutError";
|
|
180
|
+
controller.abort(reason);
|
|
181
|
+
}, ms);
|
|
182
|
+
return anySignal2(controller.signal, signal);
|
|
183
|
+
}
|
|
184
|
+
async function raceAbort2(promise, signal) {
|
|
185
|
+
if (!signal)
|
|
186
|
+
return promise;
|
|
187
|
+
let onAbort = () => {};
|
|
188
|
+
const aborted = new Promise((_, reject) => {
|
|
189
|
+
onAbort = () => reject(signal.reason);
|
|
190
|
+
if (signal.aborted)
|
|
191
|
+
onAbort();
|
|
192
|
+
else
|
|
193
|
+
signal.addEventListener("abort", onAbort, { once: true });
|
|
194
|
+
});
|
|
195
|
+
try {
|
|
196
|
+
return await Promise.race([aborted, promise]);
|
|
197
|
+
} finally {
|
|
198
|
+
signal.removeEventListener("abort", onAbort);
|
|
199
|
+
}
|
|
200
|
+
}
|
|
201
|
+
function createLatestGuard2() {
|
|
202
|
+
let current = 0;
|
|
203
|
+
const isCurrent = (token) => token === current;
|
|
204
|
+
return {
|
|
205
|
+
next: () => ++current,
|
|
206
|
+
isCurrent,
|
|
207
|
+
invalidate: () => {
|
|
208
|
+
current++;
|
|
209
|
+
},
|
|
210
|
+
async run(fn) {
|
|
211
|
+
const token = ++current;
|
|
212
|
+
try {
|
|
213
|
+
const value = await fn();
|
|
214
|
+
return isCurrent(token) ? { stale: false, value } : { stale: true };
|
|
215
|
+
} catch (error) {
|
|
216
|
+
if (!isCurrent(token))
|
|
217
|
+
return { stale: true };
|
|
218
|
+
throw error;
|
|
219
|
+
}
|
|
220
|
+
}
|
|
221
|
+
};
|
|
222
|
+
}
|
|
223
|
+
|
|
224
|
+
export { ok2, err2, isSuccess2, isFailure2, unwrapResult2, backgroundPromise2, backgroundPromiseSync2, promiseTimeout2, tryCatch2, PromiseTimeoutError2, withTimeout2, exponentialBackoff2, retry2, pMap2, startTimer2, timed2, anySignal2, timeoutSignal2, raceAbort2, createLatestGuard2 };
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
// src/error/index.ts
|
|
2
|
+
class InvariantError2 extends Error {
|
|
3
|
+
name = "InvariantError";
|
|
4
|
+
}
|
|
5
|
+
function getErrorMessage2(error, fallback = "") {
|
|
6
|
+
let message;
|
|
7
|
+
if (typeof error === "string")
|
|
8
|
+
message = error;
|
|
9
|
+
else if (typeof error === "object" && error !== null && "message" in error && typeof error.message === "string")
|
|
10
|
+
message = error.message;
|
|
11
|
+
else {
|
|
12
|
+
try {
|
|
13
|
+
message = String(error);
|
|
14
|
+
} catch {
|
|
15
|
+
message = "";
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
return message || fallback;
|
|
19
|
+
}
|
|
20
|
+
function toError2(error, prefix) {
|
|
21
|
+
if (error instanceof Error && !prefix)
|
|
22
|
+
return error;
|
|
23
|
+
const message = getErrorMessage2(error);
|
|
24
|
+
return new Error(prefix ? `${prefix}: ${message}` : message, {
|
|
25
|
+
cause: error
|
|
26
|
+
});
|
|
27
|
+
}
|
|
28
|
+
function fail(message, fallback) {
|
|
29
|
+
throw typeof message === "function" ? message() : new InvariantError2(message ?? fallback);
|
|
30
|
+
}
|
|
31
|
+
function must2(value, message) {
|
|
32
|
+
if (value === null || value === undefined) {
|
|
33
|
+
fail(message, "Expected value to be defined");
|
|
34
|
+
}
|
|
35
|
+
return value;
|
|
36
|
+
}
|
|
37
|
+
function invariant2(condition, message) {
|
|
38
|
+
if (!condition)
|
|
39
|
+
fail(message, "Invariant failed");
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
// src/guard/index.ts
|
|
43
|
+
function isRecord2(value) {
|
|
44
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
45
|
+
}
|
|
46
|
+
function isPlainObject2(value) {
|
|
47
|
+
if (!isRecord2(value))
|
|
48
|
+
return false;
|
|
49
|
+
const prototype = Object.getPrototypeOf(value);
|
|
50
|
+
return prototype === Object.prototype || prototype === null;
|
|
51
|
+
}
|
|
52
|
+
function isDefined2(value) {
|
|
53
|
+
return value !== null && value !== undefined;
|
|
54
|
+
}
|
|
55
|
+
function isTruthy2(value) {
|
|
56
|
+
return Boolean(value);
|
|
57
|
+
}
|
|
58
|
+
function isString2(value) {
|
|
59
|
+
return typeof value === "string";
|
|
60
|
+
}
|
|
61
|
+
function isNumber2(value) {
|
|
62
|
+
return typeof value === "number" && !Number.isNaN(value);
|
|
63
|
+
}
|
|
64
|
+
function isBoolean2(value) {
|
|
65
|
+
return typeof value === "boolean";
|
|
66
|
+
}
|
|
67
|
+
function isFunction2(value) {
|
|
68
|
+
return typeof value === "function";
|
|
69
|
+
}
|
|
70
|
+
function isOneOf2(list, ...value) {
|
|
71
|
+
if (value.length === 0)
|
|
72
|
+
return (item) => list.includes(item);
|
|
73
|
+
return list.includes(value[0]);
|
|
74
|
+
}
|
|
75
|
+
function hasKey2(object, key) {
|
|
76
|
+
return Object.hasOwn(object, key);
|
|
77
|
+
}
|
|
78
|
+
function isNonEmpty2(array) {
|
|
79
|
+
return array.length > 0;
|
|
80
|
+
}
|
|
81
|
+
function nonEmpty2(array, message = "Expected a non-empty array") {
|
|
82
|
+
if (!isNonEmpty2(array))
|
|
83
|
+
throw new InvariantError2(message);
|
|
84
|
+
return [...array];
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
export { InvariantError2, getErrorMessage2, toError2, must2, invariant2, isRecord2, isPlainObject2, isDefined2, isTruthy2, isString2, isNumber2, isBoolean2, isFunction2, isOneOf2, hasKey2, isNonEmpty2, nonEmpty2 };
|
|
@@ -0,0 +1,157 @@
|
|
|
1
|
+
import {
|
|
2
|
+
stableStringify2
|
|
3
|
+
} from "./index-kj1phgrx.js";
|
|
4
|
+
|
|
5
|
+
// src/array/index.ts
|
|
6
|
+
function chunkArray2(array, chunkSize) {
|
|
7
|
+
if (!Number.isInteger(chunkSize) || chunkSize <= 0) {
|
|
8
|
+
throw new Error("Chunk size must be a positive integer");
|
|
9
|
+
}
|
|
10
|
+
const chunks = [];
|
|
11
|
+
for (let index = 0;index < array.length; index += chunkSize) {
|
|
12
|
+
chunks.push(array.slice(index, index + chunkSize));
|
|
13
|
+
}
|
|
14
|
+
return chunks;
|
|
15
|
+
}
|
|
16
|
+
function findArrayDifferenceByKey2(current, next, key, options = {}) {
|
|
17
|
+
const { isEqual } = options;
|
|
18
|
+
const getKey = (item) => String(typeof key === "function" ? key(item) : item[key]);
|
|
19
|
+
const currentByKey = new Map(current.map((item) => [getKey(item), item]));
|
|
20
|
+
const matchedKeys = new Set;
|
|
21
|
+
const newItems = [];
|
|
22
|
+
const upsertItems = [];
|
|
23
|
+
const updateItems = [];
|
|
24
|
+
const unchangedItems = [];
|
|
25
|
+
for (const item of next) {
|
|
26
|
+
const itemKey = getKey(item);
|
|
27
|
+
if (!currentByKey.has(itemKey)) {
|
|
28
|
+
newItems.push(item);
|
|
29
|
+
continue;
|
|
30
|
+
}
|
|
31
|
+
matchedKeys.add(itemKey);
|
|
32
|
+
upsertItems.push(item);
|
|
33
|
+
if (isEqual) {
|
|
34
|
+
const target = isEqual(currentByKey.get(itemKey), item) ? unchangedItems : updateItems;
|
|
35
|
+
target.push(item);
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
const difference = {
|
|
39
|
+
new: newItems,
|
|
40
|
+
upsert: upsertItems,
|
|
41
|
+
delete: current.filter((item) => !matchedKeys.has(getKey(item)))
|
|
42
|
+
};
|
|
43
|
+
return isEqual ? { ...difference, update: updateItems, unchanged: unchangedItems } : difference;
|
|
44
|
+
}
|
|
45
|
+
function getUniqueValues2(array) {
|
|
46
|
+
const seen = new Map;
|
|
47
|
+
for (const element of array) {
|
|
48
|
+
const key = stableStringify2(element);
|
|
49
|
+
if (!seen.has(key)) {
|
|
50
|
+
seen.set(key, element);
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
return Array.from(seen.values());
|
|
54
|
+
}
|
|
55
|
+
function compact2(array) {
|
|
56
|
+
return array.filter((item) => item != null);
|
|
57
|
+
}
|
|
58
|
+
function getUniqueValuesByKey2(array, keyOrFn) {
|
|
59
|
+
const seen = new Set;
|
|
60
|
+
const result = [];
|
|
61
|
+
for (const item of array) {
|
|
62
|
+
const value = typeof keyOrFn === "function" ? keyOrFn(item) : item[keyOrFn];
|
|
63
|
+
if (seen.has(value))
|
|
64
|
+
continue;
|
|
65
|
+
seen.add(value);
|
|
66
|
+
result.push(item);
|
|
67
|
+
}
|
|
68
|
+
return result;
|
|
69
|
+
}
|
|
70
|
+
function groupBy2(array, keyOrFn) {
|
|
71
|
+
const result = {};
|
|
72
|
+
for (const item of array) {
|
|
73
|
+
const groupKey = typeof keyOrFn === "function" ? keyOrFn(item) : item[keyOrFn];
|
|
74
|
+
result[groupKey] ??= [];
|
|
75
|
+
result[groupKey].push(item);
|
|
76
|
+
}
|
|
77
|
+
return result;
|
|
78
|
+
}
|
|
79
|
+
function countBy2(array, keyOrFn) {
|
|
80
|
+
const result = {};
|
|
81
|
+
for (const item of array) {
|
|
82
|
+
const groupKey = typeof keyOrFn === "function" ? keyOrFn(item) : item[keyOrFn];
|
|
83
|
+
result[groupKey] = (result[groupKey] ?? 0) + 1;
|
|
84
|
+
}
|
|
85
|
+
return result;
|
|
86
|
+
}
|
|
87
|
+
function keyBy2(array, keyOrFn) {
|
|
88
|
+
const result = {};
|
|
89
|
+
for (const item of array) {
|
|
90
|
+
const recordKey = typeof keyOrFn === "function" ? keyOrFn(item) : item[keyOrFn];
|
|
91
|
+
result[recordKey] = item;
|
|
92
|
+
}
|
|
93
|
+
return result;
|
|
94
|
+
}
|
|
95
|
+
function partition2(array, predicate) {
|
|
96
|
+
const matched = [];
|
|
97
|
+
const unmatched = [];
|
|
98
|
+
array.forEach((item, index) => {
|
|
99
|
+
if (predicate(item, index)) {
|
|
100
|
+
matched.push(item);
|
|
101
|
+
} else {
|
|
102
|
+
unmatched.push(item);
|
|
103
|
+
}
|
|
104
|
+
});
|
|
105
|
+
return [matched, unmatched];
|
|
106
|
+
}
|
|
107
|
+
function pickItemsInArray2(array, key, values) {
|
|
108
|
+
return array.filter((item) => values.includes(item[key]));
|
|
109
|
+
}
|
|
110
|
+
function toArray2(value) {
|
|
111
|
+
if (value == null)
|
|
112
|
+
return [];
|
|
113
|
+
if (Array.isArray(value))
|
|
114
|
+
return [...value];
|
|
115
|
+
return [value];
|
|
116
|
+
}
|
|
117
|
+
function sumBy2(array, keyOrFn) {
|
|
118
|
+
let sum = 0;
|
|
119
|
+
for (const item of array) {
|
|
120
|
+
const value = typeof keyOrFn === "function" ? keyOrFn(item) : item[keyOrFn];
|
|
121
|
+
sum += value ?? 0;
|
|
122
|
+
}
|
|
123
|
+
return sum;
|
|
124
|
+
}
|
|
125
|
+
function sortBy2(array, ...criteria) {
|
|
126
|
+
const comparators = (criteria.length ? criteria : [(item) => item]).map((criterion) => {
|
|
127
|
+
const { by, order } = typeof criterion === "object" ? criterion : { by: criterion, order: "asc" };
|
|
128
|
+
const select = (item) => typeof by === "function" ? by(item) : item[by];
|
|
129
|
+
const direction = order === "desc" ? -1 : 1;
|
|
130
|
+
return (left, right) => {
|
|
131
|
+
const a = select(left);
|
|
132
|
+
const b = select(right);
|
|
133
|
+
if (a == null || b == null)
|
|
134
|
+
return a == null ? b == null ? 0 : 1 : -1;
|
|
135
|
+
return a < b ? -direction : a > b ? direction : 0;
|
|
136
|
+
};
|
|
137
|
+
});
|
|
138
|
+
return [...array].sort((left, right) => {
|
|
139
|
+
for (const compare of comparators) {
|
|
140
|
+
const result = compare(left, right);
|
|
141
|
+
if (result !== 0)
|
|
142
|
+
return result;
|
|
143
|
+
}
|
|
144
|
+
return 0;
|
|
145
|
+
});
|
|
146
|
+
}
|
|
147
|
+
function range2(start, end, step) {
|
|
148
|
+
const from = end === undefined ? 0 : start;
|
|
149
|
+
const to = end ?? start;
|
|
150
|
+
const increment = step ?? (to < from ? -1 : 1);
|
|
151
|
+
if (increment === 0)
|
|
152
|
+
throw new Error("Step must not be zero");
|
|
153
|
+
const length = Math.max(Math.ceil((to - from) / increment), 0);
|
|
154
|
+
return Array.from({ length }, (_, index) => from + index * increment);
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
export { chunkArray2, findArrayDifferenceByKey2, getUniqueValues2, compact2, getUniqueValuesByKey2, groupBy2, countBy2, keyBy2, partition2, pickItemsInArray2, toArray2, sumBy2, sortBy2, range2 };
|