hanzio 1.2.0 → 2.0.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-181e6vfw.js +29 -0
- package/dist/index-8r2vdzjg.js +87 -0
- package/dist/index-hy7kbb99.js +157 -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-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-srt06xd2.js +15 -0
- package/dist/index-wjyb9bsd.js +263 -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/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 +44 -1428
- package/dist/src/secrets/vite.js +6 -39
- package/dist/src/secrets/worker.js +10 -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/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,263 @@
|
|
|
1
|
+
import {
|
|
2
|
+
SecretLoadError2
|
|
3
|
+
} from "./index-srt06xd2.js";
|
|
4
|
+
|
|
5
|
+
// src/secrets/environment.ts
|
|
6
|
+
function getProcessEnvironment() {
|
|
7
|
+
return typeof process === "undefined" ? undefined : process.env;
|
|
8
|
+
}
|
|
9
|
+
function resolveSecretEnvironment(option, env) {
|
|
10
|
+
const explicit = typeof option === "function" ? option() : option;
|
|
11
|
+
if (typeof explicit === "object" && explicit !== null) {
|
|
12
|
+
if (typeof explicit.slug !== "string" || !/^[a-zA-Z0-9][a-zA-Z0-9_-]*$/.test(explicit.slug)) {
|
|
13
|
+
throw new SecretLoadError2("CONFIGURATION", "Custom secret environment requires a valid slug.");
|
|
14
|
+
}
|
|
15
|
+
return explicit.slug;
|
|
16
|
+
}
|
|
17
|
+
const selected = explicit ?? env?.SECRETS_ENV;
|
|
18
|
+
if (selected !== undefined) {
|
|
19
|
+
if (selected === "production" || selected === "prod") {
|
|
20
|
+
return "prod";
|
|
21
|
+
}
|
|
22
|
+
if (selected === "development" || selected === "dev") {
|
|
23
|
+
return "dev";
|
|
24
|
+
}
|
|
25
|
+
if (selected === "staging") {
|
|
26
|
+
return "staging";
|
|
27
|
+
}
|
|
28
|
+
throw new SecretLoadError2("CONFIGURATION", "Invalid secret environment. Use dev, staging, prod, or an explicit { slug } option.");
|
|
29
|
+
}
|
|
30
|
+
if (env?.NODE_ENV === "production" || env?.NODE_ENV === "prod") {
|
|
31
|
+
return "prod";
|
|
32
|
+
}
|
|
33
|
+
if (env?.NODE_ENV === "staging") {
|
|
34
|
+
return "staging";
|
|
35
|
+
}
|
|
36
|
+
return "dev";
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
// src/secrets/deadline.ts
|
|
40
|
+
async function withSecretDeadline(options, operation) {
|
|
41
|
+
const timeoutMs = options.timeoutMs ?? 30000;
|
|
42
|
+
if (!Number.isFinite(timeoutMs) || timeoutMs <= 0 || timeoutMs > 2147483647) {
|
|
43
|
+
throw new SecretLoadError2("CONFIGURATION", "Secret timeoutMs must be a positive finite timer duration.");
|
|
44
|
+
}
|
|
45
|
+
const controller = new AbortController;
|
|
46
|
+
const cancel = () => controller.abort(new SecretLoadError2("ABORTED", "Secret loading was cancelled."));
|
|
47
|
+
if (options.signal?.aborted) {
|
|
48
|
+
cancel();
|
|
49
|
+
} else {
|
|
50
|
+
options.signal?.addEventListener("abort", cancel, { once: true });
|
|
51
|
+
}
|
|
52
|
+
const timer = setTimeout(() => controller.abort(new SecretLoadError2("TIMEOUT", `Secret loading timed out after ${timeoutMs}ms.`)), timeoutMs);
|
|
53
|
+
let rejectOnAbort = () => {};
|
|
54
|
+
try {
|
|
55
|
+
const aborted = new Promise((_, reject) => {
|
|
56
|
+
rejectOnAbort = () => reject(controller.signal.reason);
|
|
57
|
+
controller.signal.addEventListener("abort", rejectOnAbort, { once: true });
|
|
58
|
+
});
|
|
59
|
+
if (controller.signal.aborted) {
|
|
60
|
+
throw controller.signal.reason;
|
|
61
|
+
}
|
|
62
|
+
return await Promise.race([operation(controller.signal), aborted]);
|
|
63
|
+
} finally {
|
|
64
|
+
clearTimeout(timer);
|
|
65
|
+
options.signal?.removeEventListener("abort", cancel);
|
|
66
|
+
controller.signal.removeEventListener("abort", rejectOnAbort);
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
// src/secrets/core.ts
|
|
71
|
+
var registryKey = Symbol.for("hanzio.secrets.environmentWrites.v1");
|
|
72
|
+
var shared = globalThis;
|
|
73
|
+
var environmentWrites = shared[registryKey] ?? new WeakMap;
|
|
74
|
+
shared[registryKey] = environmentWrites;
|
|
75
|
+
var defaultLogger = {
|
|
76
|
+
info: (message, attrs) => console.log(`${message} environment=${attrs.environment} count=${attrs.count} source=${attrs.source} durationMs=${attrs.durationMs}`, { sources: attrs.sources }),
|
|
77
|
+
error: (message, attrs) => console.error(message, attrs)
|
|
78
|
+
};
|
|
79
|
+
function readOverrides(keys, env) {
|
|
80
|
+
if (!env) {
|
|
81
|
+
return {};
|
|
82
|
+
}
|
|
83
|
+
const writes = environmentWrites.get(env);
|
|
84
|
+
return Object.fromEntries(keys.flatMap((key) => {
|
|
85
|
+
const value = Object.hasOwn(env, key) ? env[key] : undefined;
|
|
86
|
+
if (writes?.has(key)) {
|
|
87
|
+
if (writes.get(key) === value) {
|
|
88
|
+
return [];
|
|
89
|
+
}
|
|
90
|
+
writes.delete(key);
|
|
91
|
+
}
|
|
92
|
+
return value ? [[key, value]] : [];
|
|
93
|
+
}));
|
|
94
|
+
}
|
|
95
|
+
async function defineSecretSet2(keys, options, environmentVariables) {
|
|
96
|
+
const keySet = [...new Set(keys)];
|
|
97
|
+
const environment = resolveSecretEnvironment(options.environment, environmentVariables);
|
|
98
|
+
const logger = options.logger === false ? undefined : options.logger ?? defaultLogger;
|
|
99
|
+
let cached;
|
|
100
|
+
let parsed;
|
|
101
|
+
let sources;
|
|
102
|
+
let inFlight;
|
|
103
|
+
const log = (level, message, attributes) => {
|
|
104
|
+
try {
|
|
105
|
+
logger?.[level](message, attributes);
|
|
106
|
+
} catch {}
|
|
107
|
+
};
|
|
108
|
+
const loadSnapshot = async (request, signal) => {
|
|
109
|
+
const local = readOverrides(keySet, environmentVariables);
|
|
110
|
+
const missing = keySet.filter((key) => !Object.hasOwn(local, key));
|
|
111
|
+
let loaderSource = options.loader.source ?? "custom loader";
|
|
112
|
+
let loaded = {};
|
|
113
|
+
if (missing.length) {
|
|
114
|
+
try {
|
|
115
|
+
loaded = await options.loader({
|
|
116
|
+
keys: missing,
|
|
117
|
+
environment,
|
|
118
|
+
signal,
|
|
119
|
+
timeoutMs: request.timeoutMs ?? options.timeoutMs ?? 30000,
|
|
120
|
+
reportSource: (source) => {
|
|
121
|
+
loaderSource = source;
|
|
122
|
+
}
|
|
123
|
+
});
|
|
124
|
+
} catch (error) {
|
|
125
|
+
if (error instanceof SecretLoadError2) {
|
|
126
|
+
throw error;
|
|
127
|
+
}
|
|
128
|
+
throw new SecretLoadError2("LOADER", "Secret loader failed.");
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
const overrides = readOverrides(keySet, environmentVariables);
|
|
132
|
+
const next = Object.fromEntries(keySet.map((key) => {
|
|
133
|
+
if (Object.hasOwn(overrides, key)) {
|
|
134
|
+
return [key, overrides[key]];
|
|
135
|
+
}
|
|
136
|
+
if (Object.hasOwn(loaded, key)) {
|
|
137
|
+
return [key, loaded[key]];
|
|
138
|
+
}
|
|
139
|
+
return [key, undefined];
|
|
140
|
+
}));
|
|
141
|
+
const missingKeys = keySet.filter((key) => typeof next[key] !== "string" || !next[key]);
|
|
142
|
+
if (missingKeys.length) {
|
|
143
|
+
throw new SecretLoadError2("MISSING_SECRETS", `Missing secrets: ${missingKeys.join(", ")}`);
|
|
144
|
+
}
|
|
145
|
+
let nextParsed;
|
|
146
|
+
try {
|
|
147
|
+
nextParsed = options.schema ? await options.schema.parseAsync({ ...next }) : { ...next };
|
|
148
|
+
nextParsed = structuredClone(nextParsed);
|
|
149
|
+
} catch {
|
|
150
|
+
throw new SecretLoadError2("VALIDATION", "Secret schema validation failed. Check the configured schema; values are omitted.");
|
|
151
|
+
}
|
|
152
|
+
signal.throwIfAborted();
|
|
153
|
+
const nextSources = Object.fromEntries(keySet.map((key) => [
|
|
154
|
+
key,
|
|
155
|
+
Object.hasOwn(overrides, key) ? "process.env" : loaderSource
|
|
156
|
+
]));
|
|
157
|
+
if (options.writeToProcessEnv !== false && environmentVariables) {
|
|
158
|
+
let writes = environmentWrites.get(environmentVariables);
|
|
159
|
+
if (!writes) {
|
|
160
|
+
writes = new Map;
|
|
161
|
+
environmentWrites.set(environmentVariables, writes);
|
|
162
|
+
}
|
|
163
|
+
for (const key of keySet) {
|
|
164
|
+
if (Object.hasOwn(overrides, key)) {
|
|
165
|
+
continue;
|
|
166
|
+
}
|
|
167
|
+
environmentVariables[key] = next[key];
|
|
168
|
+
writes.set(key, next[key]);
|
|
169
|
+
}
|
|
170
|
+
}
|
|
171
|
+
cached = next;
|
|
172
|
+
parsed = nextParsed;
|
|
173
|
+
sources = nextSources;
|
|
174
|
+
};
|
|
175
|
+
const load = (request = {}) => {
|
|
176
|
+
if (inFlight) {
|
|
177
|
+
return inFlight;
|
|
178
|
+
}
|
|
179
|
+
inFlight = (async () => {
|
|
180
|
+
const start = Date.now();
|
|
181
|
+
try {
|
|
182
|
+
await withSecretDeadline({
|
|
183
|
+
timeoutMs: request.timeoutMs ?? options.timeoutMs,
|
|
184
|
+
signal: request.signal ?? options.signal
|
|
185
|
+
}, (signal) => loadSnapshot(request, signal));
|
|
186
|
+
const sourceCounts = new Map;
|
|
187
|
+
for (const key of keySet) {
|
|
188
|
+
const source = sources[key];
|
|
189
|
+
sourceCounts.set(source, (sourceCounts.get(source) ?? 0) + 1);
|
|
190
|
+
}
|
|
191
|
+
const counts = Object.fromEntries(sourceCounts);
|
|
192
|
+
log("info", "Loaded secrets", {
|
|
193
|
+
environment,
|
|
194
|
+
count: keySet.length,
|
|
195
|
+
durationMs: Date.now() - start,
|
|
196
|
+
source: Object.keys(counts).join(" + ") || "none",
|
|
197
|
+
sources: counts
|
|
198
|
+
});
|
|
199
|
+
} catch (error) {
|
|
200
|
+
const safe = error instanceof SecretLoadError2 ? error : new SecretLoadError2("LOADER", "Secret loading failed.");
|
|
201
|
+
log("error", "Secret loading failed", {
|
|
202
|
+
environment,
|
|
203
|
+
count: keySet.length,
|
|
204
|
+
durationMs: Date.now() - start,
|
|
205
|
+
code: safe.code
|
|
206
|
+
});
|
|
207
|
+
throw safe;
|
|
208
|
+
}
|
|
209
|
+
})().finally(() => {
|
|
210
|
+
inFlight = undefined;
|
|
211
|
+
});
|
|
212
|
+
return inFlight;
|
|
213
|
+
};
|
|
214
|
+
const secretSet = {
|
|
215
|
+
secret(key) {
|
|
216
|
+
if (!Object.hasOwn(cached, key)) {
|
|
217
|
+
throw new SecretLoadError2("MISSING_SECRETS", `Secret ${key} not found`);
|
|
218
|
+
}
|
|
219
|
+
return cached[key];
|
|
220
|
+
},
|
|
221
|
+
secrets: () => ({ ...cached }),
|
|
222
|
+
parsed: () => structuredClone(parsed),
|
|
223
|
+
sources: () => ({ ...sources }),
|
|
224
|
+
async reload(request) {
|
|
225
|
+
await load(request);
|
|
226
|
+
return secretSet;
|
|
227
|
+
}
|
|
228
|
+
};
|
|
229
|
+
await load();
|
|
230
|
+
return secretSet;
|
|
231
|
+
}
|
|
232
|
+
|
|
233
|
+
// src/secrets/worker-loader.ts
|
|
234
|
+
function cloudflareWorkerEnvLoader2(workerEnv) {
|
|
235
|
+
const loader = async (ctx) => {
|
|
236
|
+
const out = Object.create(null);
|
|
237
|
+
for (const key of ctx.keys) {
|
|
238
|
+
const str = workerBindingToString(Object.hasOwn(workerEnv, key) ? workerEnv[key] : undefined);
|
|
239
|
+
if (str !== undefined) {
|
|
240
|
+
out[key] = str;
|
|
241
|
+
}
|
|
242
|
+
}
|
|
243
|
+
return out;
|
|
244
|
+
};
|
|
245
|
+
return Object.assign(loader, { source: "Cloudflare Worker bindings" });
|
|
246
|
+
}
|
|
247
|
+
function workerBindingToString(value) {
|
|
248
|
+
if (value === undefined || value === null) {
|
|
249
|
+
return;
|
|
250
|
+
}
|
|
251
|
+
if (typeof value === "string") {
|
|
252
|
+
return value === "" ? undefined : value;
|
|
253
|
+
}
|
|
254
|
+
if (typeof value === "number" || typeof value === "boolean" || typeof value === "bigint") {
|
|
255
|
+
return String(value);
|
|
256
|
+
}
|
|
257
|
+
if (typeof value === "object") {
|
|
258
|
+
return JSON.stringify(value);
|
|
259
|
+
}
|
|
260
|
+
return String(value);
|
|
261
|
+
}
|
|
262
|
+
|
|
263
|
+
export { withSecretDeadline, getProcessEnvironment, resolveSecretEnvironment, defineSecretSet2, cloudflareWorkerEnvLoader2 };
|
package/dist/index.d.ts
CHANGED
|
@@ -5,12 +5,12 @@ export * from './promise';
|
|
|
5
5
|
export * from './cache';
|
|
6
6
|
export * from './state';
|
|
7
7
|
export * from './math';
|
|
8
|
+
export * from './color';
|
|
8
9
|
export * from './date';
|
|
9
10
|
export * from './url';
|
|
10
|
-
export * from './
|
|
11
|
-
export * from './
|
|
12
|
-
export * from './
|
|
13
|
-
export * from './
|
|
14
|
-
export * from './
|
|
15
|
-
export * from './
|
|
16
|
-
export * from './secrets';
|
|
11
|
+
export * from './error';
|
|
12
|
+
export * from './guard';
|
|
13
|
+
export * from './object';
|
|
14
|
+
export * from './types';
|
|
15
|
+
export * from './function';
|
|
16
|
+
export * from './emitter';
|
package/dist/jwt/index.d.ts
CHANGED
|
@@ -1,3 +1,51 @@
|
|
|
1
|
+
import type { Result } from '../promise';
|
|
1
2
|
export type JWTPayload = Record<string, unknown>;
|
|
2
|
-
export
|
|
3
|
-
export
|
|
3
|
+
export type JwtAlgorithm = 'HS256' | 'HS384' | 'HS512';
|
|
4
|
+
export type JwtHeader = {
|
|
5
|
+
alg: string;
|
|
6
|
+
typ?: string;
|
|
7
|
+
} & Record<string, unknown>;
|
|
8
|
+
export type JwtSignOptions = {
|
|
9
|
+
/** Seconds from now until `exp`. */
|
|
10
|
+
expiresIn?: number;
|
|
11
|
+
/** Seconds from now until `nbf`. */
|
|
12
|
+
notBefore?: number;
|
|
13
|
+
issuer?: string;
|
|
14
|
+
audience?: string | string[];
|
|
15
|
+
/** Default: `'HS256'` */
|
|
16
|
+
algorithm?: JwtAlgorithm;
|
|
17
|
+
};
|
|
18
|
+
export type JwtVerifyOptions = {
|
|
19
|
+
/** Clock skew tolerance for `exp`/`nbf`, in seconds. Default: 0 */
|
|
20
|
+
leewaySec?: number;
|
|
21
|
+
/** Required `iss` value. */
|
|
22
|
+
issuer?: string;
|
|
23
|
+
/** Required `aud` value (matches a string `aud` or an entry of an array `aud`). */
|
|
24
|
+
audience?: string;
|
|
25
|
+
/** Accepted header `alg` values. Default: all of HS256/HS384/HS512. */
|
|
26
|
+
algorithms?: JwtAlgorithm[];
|
|
27
|
+
};
|
|
28
|
+
export type JwtVerifyErrorCode = 'malformed' | 'unsupported_alg' | 'invalid_signature' | 'expired' | 'not_yet_valid' | 'invalid_issuer' | 'invalid_audience';
|
|
29
|
+
export declare class JwtVerifyError extends Error {
|
|
30
|
+
readonly code: JwtVerifyErrorCode;
|
|
31
|
+
constructor(code: JwtVerifyErrorCode);
|
|
32
|
+
}
|
|
33
|
+
/**
|
|
34
|
+
* Signs `payload` as a compact JWS. `iat` is always set to now.
|
|
35
|
+
* Claims derived from `options` (`exp`, `nbf`, `iss`, `aud`) override the same
|
|
36
|
+
* claims in `payload`; payload claims are kept when the option is not given.
|
|
37
|
+
*/
|
|
38
|
+
export declare function jwtSign<Payload extends JWTPayload>(payload: Payload, secret: string, options?: JwtSignOptions): Promise<string>;
|
|
39
|
+
/** Verifies a token. Returns `null` for any failure; use `jwtVerifyResult` for the reason. */
|
|
40
|
+
export declare function jwtVerify<Payload extends JWTPayload>(token: string, secret: string, options?: JwtVerifyOptions): Promise<Payload | null>;
|
|
41
|
+
/**
|
|
42
|
+
* Verifies signature, `exp`/`nbf` and optional `iss`/`aud`.
|
|
43
|
+
* Token problems are returned as a failed `Result`; configuration problems
|
|
44
|
+
* (no Web Crypto, empty secret) throw.
|
|
45
|
+
*/
|
|
46
|
+
export declare function jwtVerifyResult<Payload extends JWTPayload>(token: string, secret: string, options?: JwtVerifyOptions): Promise<Result<Payload, JwtVerifyError>>;
|
|
47
|
+
/** Decodes header and payload WITHOUT verifying the signature. Never trust the result for auth. */
|
|
48
|
+
export declare function jwtDecode<Payload extends JWTPayload = JWTPayload>(token: string): {
|
|
49
|
+
header: JwtHeader;
|
|
50
|
+
payload: Payload;
|
|
51
|
+
} | null;
|
package/dist/math/index.d.ts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
export { linearRegressionTrend } from './linearRegressionTrend';
|
|
2
|
-
export {
|
|
1
|
+
export { type LinearRegression, linearRegression, linearRegressionTrend } from './linearRegressionTrend';
|
|
2
|
+
export { clamp, lerp, normalize } from './scale';
|
|
@@ -1,5 +1,18 @@
|
|
|
1
|
+
export type LinearRegression = {
|
|
2
|
+
slope: number;
|
|
3
|
+
intercept: number;
|
|
4
|
+
/** Coefficient of determination (0..1). 1 when all values are equal (exact fit). */
|
|
5
|
+
r2: number;
|
|
6
|
+
/** Fitted y for each index. */
|
|
7
|
+
fitted: number[];
|
|
8
|
+
};
|
|
1
9
|
/**
|
|
2
10
|
* Least-squares linear regression for y at x = 0, 1, …, n − 1.
|
|
3
|
-
* Returns
|
|
11
|
+
* Returns `null` if n < 2 or any input is non-finite.
|
|
12
|
+
*/
|
|
13
|
+
export declare function linearRegression(values: number[]): LinearRegression | null;
|
|
14
|
+
/**
|
|
15
|
+
* Fitted y for each index of `values` (see `linearRegression`), or [] if n < 2
|
|
16
|
+
* or any input is non-finite.
|
|
4
17
|
*/
|
|
5
18
|
export declare function linearRegressionTrend(values: number[]): number[];
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
export declare function clamp(value: number, min: number, max: number): number;
|
|
2
|
+
/** Linear interpolation: `t = 0` → `start`, `t = 1` → `end`. */
|
|
3
|
+
export declare function lerp(start: number, end: number, t: number): number;
|
|
4
|
+
/**
|
|
5
|
+
* Position of `value` within `[min, max]` as 0..1 (clamped). Returns 0 when
|
|
6
|
+
* the range is empty.
|
|
7
|
+
*/
|
|
8
|
+
export declare function normalize(value: number, min: number, max: number): number;
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
/** `Object.keys` typed as the object's string keys. */
|
|
2
|
+
export declare function typedKeys<T extends object>(object: T): (keyof T & string)[];
|
|
3
|
+
/** `Object.entries` typed as `[key, value]` pairs per key. */
|
|
4
|
+
export declare function typedEntries<T extends object>(object: T): {
|
|
5
|
+
[K in keyof T & string]: [K, T[K]];
|
|
6
|
+
}[keyof T & string][];
|
|
7
|
+
/** `Object.fromEntries` typed as `Record<K, V>`. */
|
|
8
|
+
export declare function typedFromEntries<const K extends PropertyKey, V>(entries: Iterable<readonly [K, V]>): Record<K, V>;
|
|
9
|
+
/** Builds a record with one entry per key. */
|
|
10
|
+
export declare function recordFromKeys<const K extends PropertyKey, V>(keys: readonly K[], fn: (key: K) => V): Record<K, V>;
|
|
11
|
+
export declare function mapValues<T extends object, R>(object: T, fn: (value: T[keyof T & string], key: keyof T & string) => R): Record<keyof T & string, R>;
|
|
12
|
+
export declare function pick<T extends object, const K extends keyof T>(object: T, keys: readonly K[]): Pick<T, K>;
|
|
13
|
+
export declare function omit<T extends object, const K extends keyof T>(object: T, keys: readonly K[]): Omit<T, K>;
|
|
14
|
+
type Path = string | readonly (string | number)[];
|
|
15
|
+
/** Reads a nested value by dot path (`a.b.0.c`) or segment array; undefined when missing. */
|
|
16
|
+
export declare function getAtPath(object: unknown, path: Path): unknown;
|
|
17
|
+
/** Writes a nested value in place, creating arrays for numeric segments and objects otherwise. */
|
|
18
|
+
export declare function setAtPath(object: object, path: Path, value: unknown): void;
|
|
19
|
+
export {};
|
package/dist/p-queue/index.d.ts
CHANGED
package/dist/promise/index.d.ts
CHANGED
|
@@ -4,18 +4,113 @@ export type BackgroundPromiseOptions = {
|
|
|
4
4
|
scheduler?: (callback: () => void) => void;
|
|
5
5
|
};
|
|
6
6
|
export type Success<T> = {
|
|
7
|
+
ok: true;
|
|
7
8
|
data: T;
|
|
8
9
|
error: null;
|
|
9
10
|
};
|
|
10
11
|
export type Failure<E> = {
|
|
12
|
+
ok: false;
|
|
11
13
|
data: null;
|
|
12
14
|
error: E;
|
|
13
15
|
};
|
|
14
16
|
export type Result<T, E = Error> = Success<T> | Failure<E>;
|
|
17
|
+
export declare function ok<T>(data: T): Success<T>;
|
|
18
|
+
export declare function err<E>(error: E): Failure<E>;
|
|
15
19
|
export declare function isSuccess<T, E>(result: Result<T, E>): result is Success<T>;
|
|
16
20
|
export declare function isFailure<T, E>(result: Result<T, E>): result is Failure<E>;
|
|
17
21
|
export declare function unwrapResult<T, E>(result: Result<T, E>): T;
|
|
18
22
|
export declare function backgroundPromise<T>(promiseFactory: () => Promise<T>, options?: BackgroundPromiseOptions): void;
|
|
19
23
|
export declare function backgroundPromiseSync<T>(promiseFactory: () => Promise<T>, options?: BackgroundPromiseOptions): void;
|
|
20
|
-
|
|
21
|
-
export declare function
|
|
24
|
+
/** Resolves after `ms`; rejects with `signal.reason` if the signal aborts first. */
|
|
25
|
+
export declare function promiseTimeout(ms: number, options?: {
|
|
26
|
+
signal?: AbortSignal;
|
|
27
|
+
}): Promise<void>;
|
|
28
|
+
/**
|
|
29
|
+
* Accepts a promise or a function; sync throws inside the function are
|
|
30
|
+
* captured too.
|
|
31
|
+
*/
|
|
32
|
+
export declare function tryCatch<T, E = Error>(input: Promise<T> | (() => T | Promise<T>)): Promise<Result<T, E>>;
|
|
33
|
+
export declare class PromiseTimeoutError extends Error {
|
|
34
|
+
readonly timeoutMs: number;
|
|
35
|
+
constructor(timeoutMs: number, message?: string);
|
|
36
|
+
}
|
|
37
|
+
/**
|
|
38
|
+
* Rejects with `PromiseTimeoutError` after `ms`, or with `signal.reason` when
|
|
39
|
+
* the signal aborts. Pass a function to receive a signal that aborts on
|
|
40
|
+
* timeout, so the underlying work can stop too.
|
|
41
|
+
*/
|
|
42
|
+
export declare function withTimeout<T>(input: Promise<T> | ((signal: AbortSignal) => Promise<T>), ms: number, options?: {
|
|
43
|
+
signal?: AbortSignal;
|
|
44
|
+
message?: string;
|
|
45
|
+
}): Promise<T>;
|
|
46
|
+
export type BackoffOptions = {
|
|
47
|
+
/** Delay for the first retry (default 300ms). */
|
|
48
|
+
baseMs?: number;
|
|
49
|
+
/** Upper bound for any delay (default 30s). */
|
|
50
|
+
maxMs?: number;
|
|
51
|
+
/**
|
|
52
|
+
* `true`/`'full'`: random delay in [0, computed] (default).
|
|
53
|
+
* `'partial'`: computed plus 0–`jitterRatio` extra (may exceed `maxMs`).
|
|
54
|
+
*/
|
|
55
|
+
jitter?: boolean | 'full' | 'partial';
|
|
56
|
+
/** Max extra fraction for `'partial'` jitter (default 0.25). */
|
|
57
|
+
jitterRatio?: number;
|
|
58
|
+
/** Source of randomness in [0, 1) (default `Math.random`). */
|
|
59
|
+
random?: () => number;
|
|
60
|
+
};
|
|
61
|
+
/** Exponential backoff delay for a 1-based retry attempt. */
|
|
62
|
+
export declare function exponentialBackoff(attempt: number, options?: BackoffOptions): number;
|
|
63
|
+
export type RetryOptions = {
|
|
64
|
+
/** Retries after the first attempt (default 3). */
|
|
65
|
+
retries?: number;
|
|
66
|
+
/** Delay before retry `attempt` (1-based). Default: `exponentialBackoff`. */
|
|
67
|
+
delayMs?: number | ((attempt: number, error: unknown) => number);
|
|
68
|
+
/** Return false to stop retrying and rethrow (default: always retry). */
|
|
69
|
+
shouldRetry?: (error: unknown, attempt: number) => boolean;
|
|
70
|
+
onRetry?: (error: unknown, attempt: number, delayMs: number) => void;
|
|
71
|
+
signal?: AbortSignal;
|
|
72
|
+
};
|
|
73
|
+
export declare function retry<T>(fn: (context: {
|
|
74
|
+
attempt: number;
|
|
75
|
+
signal?: AbortSignal;
|
|
76
|
+
}) => Promise<T> | T, options?: RetryOptions): Promise<T>;
|
|
77
|
+
/** Maps with bounded concurrency; results keep input order. */
|
|
78
|
+
export declare function pMap<T, R>(items: Iterable<T>, fn: (item: T, index: number) => Promise<R> | R, options?: {
|
|
79
|
+
concurrency?: number;
|
|
80
|
+
signal?: AbortSignal;
|
|
81
|
+
}): Promise<R[]>;
|
|
82
|
+
/** Starts a clock; call the returned function to read elapsed ms. */
|
|
83
|
+
export declare function startTimer(): () => number;
|
|
84
|
+
/** Runs `fn` and reports how long it took (throws pass through). */
|
|
85
|
+
export declare function timed<T>(fn: () => Promise<T> | T): Promise<{
|
|
86
|
+
result: T;
|
|
87
|
+
durationMs: number;
|
|
88
|
+
}>;
|
|
89
|
+
/**
|
|
90
|
+
* Aborts when any input aborts, with that signal's `reason`. Undefined inputs
|
|
91
|
+
* are skipped; no inputs gives a signal that never aborts.
|
|
92
|
+
*/
|
|
93
|
+
export declare function anySignal(...signals: (AbortSignal | undefined)[]): AbortSignal;
|
|
94
|
+
/** Aborts with a `TimeoutError` after `ms`, or earlier if `signal` aborts. */
|
|
95
|
+
export declare function timeoutSignal(ms: number, signal?: AbortSignal): AbortSignal;
|
|
96
|
+
/**
|
|
97
|
+
* Settles like `promise`, but rejects with `signal.reason` as soon as the
|
|
98
|
+
* signal aborts. The underlying work is not cancelled.
|
|
99
|
+
*/
|
|
100
|
+
export declare function raceAbort<T>(promise: Promise<T>, signal: AbortSignal | undefined): Promise<T>;
|
|
101
|
+
export type LatestGuard = {
|
|
102
|
+
/** Starts a new generation; earlier tokens become stale. */
|
|
103
|
+
next(): number;
|
|
104
|
+
isCurrent(token: number): boolean;
|
|
105
|
+
/** Marks every outstanding token stale. */
|
|
106
|
+
invalidate(): void;
|
|
107
|
+
/** Runs `fn` under a new token; stale results and errors become `{ stale: true }`. */
|
|
108
|
+
run<T>(fn: () => Promise<T> | T): Promise<{
|
|
109
|
+
stale: true;
|
|
110
|
+
} | {
|
|
111
|
+
stale: false;
|
|
112
|
+
value: T;
|
|
113
|
+
}>;
|
|
114
|
+
};
|
|
115
|
+
/** Ignores results of async work superseded by a newer call. */
|
|
116
|
+
export declare function createLatestGuard(): LatestGuard;
|
package/dist/sitemap/index.d.ts
CHANGED
|
@@ -1,14 +1,56 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
1
|
+
/** Substring, RegExp, or predicate. */
|
|
2
|
+
export type SitemapUrlFilter = string | RegExp | ((url: string) => boolean);
|
|
3
|
+
export interface SitemapOptions {
|
|
4
|
+
/** Only follow nested sitemaps (from a `<sitemapindex>`) that match. */
|
|
5
|
+
filterIndexes?: SitemapUrlFilter;
|
|
6
|
+
/** Only keep page URLs (from a `<urlset>`) that match. */
|
|
7
|
+
filterUrls?: SitemapUrlFilter;
|
|
3
8
|
concurrency?: number;
|
|
4
9
|
maxDepth?: number;
|
|
10
|
+
/** Stop once this many URLs have been collected. */
|
|
11
|
+
maxUrls?: number;
|
|
12
|
+
/** Per-request timeout in ms. */
|
|
5
13
|
timeout?: number;
|
|
14
|
+
userAgent?: string;
|
|
15
|
+
fetch?: typeof fetch;
|
|
16
|
+
/** Called for failed robots.txt/sitemap requests. Defaults to `console.warn`. */
|
|
17
|
+
onError?: (url: string, error: unknown) => void;
|
|
18
|
+
/** Drop page URLs that robots.txt disallows for `userAgent`. Defaults to `false`. */
|
|
19
|
+
respectRobots?: boolean;
|
|
6
20
|
}
|
|
21
|
+
/** The robots.txt rules that apply to one user agent. */
|
|
22
|
+
export interface RobotsRules {
|
|
23
|
+
allow: string[];
|
|
24
|
+
disallow: string[];
|
|
25
|
+
/** Every `Sitemap:` line, whatever group it is in. */
|
|
26
|
+
sitemaps: string[];
|
|
27
|
+
crawlDelaySec?: number;
|
|
28
|
+
}
|
|
29
|
+
export interface SitemapEntry {
|
|
30
|
+
loc: string;
|
|
31
|
+
lastmod?: string;
|
|
32
|
+
}
|
|
33
|
+
/**
|
|
34
|
+
* Parses robots.txt for one user agent (RFC 9309): the groups naming its
|
|
35
|
+
* product token (case-insensitive, versions ignored), else the `*` groups.
|
|
36
|
+
* Several matching groups are merged. Empty `Allow`/`Disallow` values are dropped.
|
|
37
|
+
*/
|
|
38
|
+
export declare function parseRobotsTxt(body: string, userAgent?: string): RobotsRules;
|
|
39
|
+
/**
|
|
40
|
+
* Whether `url` (absolute, or a path) may be crawled under `rules` (RFC 9309):
|
|
41
|
+
* the longest matching pattern wins and `Allow` wins a tie. Patterns support
|
|
42
|
+
* `*` and a trailing `$`, and match the path plus query string.
|
|
43
|
+
*/
|
|
44
|
+
export declare function isAllowedByRobots(rules: Pick<RobotsRules, 'allow' | 'disallow'>, url: string): boolean;
|
|
45
|
+
/**
|
|
46
|
+
* Gets all entries (`loc` + optional `lastmod`) from a domain by discovering and crawling its sitemaps
|
|
47
|
+
* @param domain - The root domain (e.g., 'example.com' or 'https://example.com')
|
|
48
|
+
* @throws When no sitemap can be discovered
|
|
49
|
+
*/
|
|
50
|
+
export declare const getDomainSitemapEntries: (domain: string, options?: SitemapOptions) => Promise<SitemapEntry[]>;
|
|
7
51
|
/**
|
|
8
52
|
* Gets all URLs from a domain by discovering and crawling its sitemaps
|
|
9
|
-
* @param domain - The root domain (e.g., 'https://example.com')
|
|
10
|
-
* @
|
|
11
|
-
* @returns Promise<string[]> - Array of unique URLs found in the sitemap
|
|
53
|
+
* @param domain - The root domain (e.g., 'example.com' or 'https://example.com')
|
|
54
|
+
* @returns Array of unique URLs found in the sitemap
|
|
12
55
|
*/
|
|
13
56
|
export declare const getDomainSitemap: (domain: string, options?: SitemapOptions) => Promise<string[]>;
|
|
14
|
-
export {};
|