hanzio 3.0.0 → 3.1.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/README.md +114 -3
- package/dist/api-wrapper/connection-auth.d.ts +61 -0
- package/dist/cli/fields.d.ts +30 -0
- package/dist/cli/index.d.ts +122 -0
- package/dist/format/index.d.ts +91 -0
- package/dist/format/phone.d.ts +19 -0
- package/dist/http/index.d.ts +14 -0
- package/dist/i18n/catalog.d.ts +47 -0
- package/dist/i18n/check.d.ts +45 -0
- package/dist/i18n/cli.d.ts +2 -0
- package/dist/i18n/content-rules.d.ts +55 -0
- package/dist/i18n/i18next.d.ts +39 -0
- package/dist/i18n/index.d.ts +16 -1
- package/dist/i18n/locales.d.ts +62 -0
- package/dist/i18n/vite.d.ts +16 -0
- package/dist/i18n/vue.d.ts +93 -0
- package/dist/{index-kj1phgrx.js → index-29mmh343.js} +24 -1
- package/dist/{index-zbj9s3s3.js → index-2kz392vw.js} +1 -1
- package/dist/index-5n2e326q.js +409 -0
- package/dist/{index-hy7kbb99.js → index-5tzqfmnj.js} +1 -1
- package/dist/{index-0zvtcbzy.js → index-6f2w90pp.js} +69 -1
- package/dist/index-mq2qgc20.js +116 -0
- package/dist/index-najbyzpr.js +99 -0
- package/dist/index-nfvq3zax.js +475 -0
- package/dist/index-ww09bm49.js +250 -0
- package/dist/iso/countries.d.ts +262 -0
- package/dist/iso/currencies.d.ts +165 -0
- package/dist/iso/index.d.ts +4 -0
- package/dist/iso/languages.d.ts +195 -0
- package/dist/iso/phone-language.d.ts +5 -0
- package/dist/promise/index.d.ts +31 -0
- package/dist/redis/client.d.ts +49 -0
- package/dist/redis/concurrency-limit.d.ts +63 -0
- package/dist/redis/index.d.ts +3 -0
- package/dist/redis/lua-script.d.ts +13 -0
- package/dist/secrets/infisical-identity-file.d.ts +12 -0
- package/dist/src/api-wrapper/connection-auth.js +82 -0
- package/dist/src/api-wrapper/index.js +1 -1
- package/dist/src/cli/index.js +10 -0
- package/dist/src/format/index.js +79 -2
- package/dist/src/format/phone.js +21 -0
- package/dist/src/http/index.js +69 -0
- package/dist/src/i18n/check.js +15 -0
- package/dist/src/i18n/cli.js +71 -0
- package/dist/src/i18n/i18next.js +48 -0
- package/dist/src/i18n/index.js +16 -34
- package/dist/src/i18n/vite.js +25 -0
- package/dist/src/i18n/vue.js +51 -0
- package/dist/src/index.js +14 -4
- package/dist/src/iso/index.js +655 -0
- package/dist/src/redis/index.js +577 -0
- package/dist/src/secrets/index.js +78 -35
- package/dist/src/sitemap/index.js +1 -1
- package/dist/src/storage/index.js +8 -117
- package/dist/src/testing/index.js +348 -0
- package/dist/src/zod/index.js +20 -253
- package/dist/string/index.d.ts +21 -0
- package/dist/testing/connection-auth-contract.d.ts +43 -0
- package/dist/testing/helpers.d.ts +26 -0
- package/dist/testing/index.d.ts +5 -0
- package/dist/testing/module-mocker.d.ts +30 -0
- package/dist/testing/prisma.d.ts +30 -0
- package/dist/testing/window.d.ts +18 -0
- package/dist/zod/index.d.ts +10 -0
- package/dist/zod/introspect.d.ts +2 -1
- package/package.json +96 -2
- package/src/api-wrapper/README.md +52 -0
- package/src/api-wrapper/connection-auth.ts +142 -0
- package/src/cli/README.md +220 -0
- package/src/cli/fields.ts +213 -0
- package/src/cli/index.ts +533 -0
- package/src/format/README.md +82 -2
- package/src/format/index.ts +148 -0
- package/src/format/phone.ts +43 -0
- package/src/http/README.md +25 -0
- package/src/http/index.ts +94 -0
- package/src/i18n/README.md +206 -3
- package/src/i18n/catalog.ts +139 -0
- package/src/i18n/check.ts +376 -0
- package/src/i18n/cli.ts +90 -0
- package/src/i18n/content-rules.ts +179 -0
- package/src/i18n/i18next.ts +89 -0
- package/src/i18n/index.ts +34 -0
- package/src/i18n/locales.ts +135 -0
- package/src/i18n/vite.ts +40 -0
- package/src/i18n/vue.ts +82 -0
- package/src/index.ts +1 -1
- package/src/iso/README.md +44 -0
- package/src/iso/countries.ts +272 -0
- package/src/iso/currencies.ts +172 -0
- package/src/iso/index.ts +8 -0
- package/src/iso/languages.ts +208 -0
- package/src/iso/phone-language.ts +46 -0
- package/src/promise/index.ts +100 -0
- package/src/redis/README.md +112 -0
- package/src/redis/client.ts +239 -0
- package/src/redis/concurrency-limit.ts +591 -0
- package/src/redis/index.ts +15 -0
- package/src/redis/lua-script.ts +43 -0
- package/src/secrets/README.md +5 -1
- package/src/secrets/infisical-identity-file.ts +69 -0
- package/src/secrets/infisical.ts +18 -3
- package/src/string/index.ts +59 -0
- package/src/testing/README.md +119 -0
- package/src/testing/connection-auth-contract.ts +303 -0
- package/src/testing/helpers.ts +41 -0
- package/src/testing/index.ts +12 -0
- package/src/testing/module-mocker.ts +50 -0
- package/src/testing/prisma.ts +78 -0
- package/src/testing/window.ts +119 -0
- package/src/zod/index.ts +20 -0
- package/src/zod/introspect.ts +1 -1
package/dist/src/zod/index.js
CHANGED
|
@@ -1,261 +1,24 @@
|
|
|
1
|
+
import {
|
|
2
|
+
zodToTypeString2,
|
|
3
|
+
zodToExample2,
|
|
4
|
+
unwrapSchema2,
|
|
5
|
+
getEnumValues2,
|
|
6
|
+
getObjectShape2,
|
|
7
|
+
zodDefaults2
|
|
8
|
+
} from "../../index-ww09bm49.js";
|
|
1
9
|
import {
|
|
2
10
|
toArray2
|
|
3
|
-
} from "../../index-
|
|
11
|
+
} from "../../index-5tzqfmnj.js";
|
|
4
12
|
import {
|
|
5
13
|
ok2,
|
|
6
14
|
err2
|
|
7
|
-
} from "../../index-
|
|
15
|
+
} from "../../index-6f2w90pp.js";
|
|
8
16
|
import {
|
|
9
17
|
isRecord2
|
|
10
18
|
} from "../../index-8r2vdzjg.js";
|
|
11
19
|
|
|
12
20
|
// src/zod/index.ts
|
|
13
21
|
import { z as z3 } from "zod";
|
|
14
|
-
|
|
15
|
-
// src/zod/zodToTypeString.ts
|
|
16
|
-
var visiting = new Set;
|
|
17
|
-
function walk(schema, onCycle, fn) {
|
|
18
|
-
if (visiting.has(schema))
|
|
19
|
-
return onCycle;
|
|
20
|
-
visiting.add(schema);
|
|
21
|
-
try {
|
|
22
|
-
return fn(defOf(schema));
|
|
23
|
-
} finally {
|
|
24
|
-
visiting.delete(schema);
|
|
25
|
-
}
|
|
26
|
-
}
|
|
27
|
-
function defOf(schema) {
|
|
28
|
-
return schema._zod.def;
|
|
29
|
-
}
|
|
30
|
-
function pipeTarget(def) {
|
|
31
|
-
return defOf(def.out).type === "transform" ? def.in : def.out;
|
|
32
|
-
}
|
|
33
|
-
function literal(value) {
|
|
34
|
-
if (typeof value === "string")
|
|
35
|
-
return JSON.stringify(value);
|
|
36
|
-
return typeof value === "bigint" ? `${value}n` : String(value);
|
|
37
|
-
}
|
|
38
|
-
function wrap(type) {
|
|
39
|
-
return /[|&]/.test(type) ? `(${type})` : type;
|
|
40
|
-
}
|
|
41
|
-
function zodToTypeString(schema, indent = 0) {
|
|
42
|
-
return walk(schema, "unknown", (def) => {
|
|
43
|
-
const pad = " ".repeat(indent);
|
|
44
|
-
const innerPad = " ".repeat(indent + 1);
|
|
45
|
-
const render = (inner) => zodToTypeString(inner, indent);
|
|
46
|
-
switch (def.type) {
|
|
47
|
-
case "object": {
|
|
48
|
-
const entries = Object.entries(def.shape);
|
|
49
|
-
if (entries.length === 0)
|
|
50
|
-
return "{}";
|
|
51
|
-
const fields = entries.map(([key, value]) => {
|
|
52
|
-
const valueDef = defOf(value);
|
|
53
|
-
const isOptional = valueDef.type === "optional";
|
|
54
|
-
const typeStr = zodToTypeString(isOptional ? valueDef.innerType : value, indent + 1);
|
|
55
|
-
return `${innerPad}${key}${isOptional ? "?" : ""}: ${typeStr}`;
|
|
56
|
-
});
|
|
57
|
-
return `{
|
|
58
|
-
${fields.join(`
|
|
59
|
-
`)}
|
|
60
|
-
${pad}}`;
|
|
61
|
-
}
|
|
62
|
-
case "array":
|
|
63
|
-
return `${wrap(render(def.element))}[]`;
|
|
64
|
-
case "tuple": {
|
|
65
|
-
const items = def.items.map(render);
|
|
66
|
-
if (def.rest)
|
|
67
|
-
items.push(`...${wrap(render(def.rest))}[]`);
|
|
68
|
-
return `[${items.join(", ")}]`;
|
|
69
|
-
}
|
|
70
|
-
case "string":
|
|
71
|
-
case "number":
|
|
72
|
-
case "bigint":
|
|
73
|
-
case "boolean":
|
|
74
|
-
case "symbol":
|
|
75
|
-
case "null":
|
|
76
|
-
case "undefined":
|
|
77
|
-
case "void":
|
|
78
|
-
case "never":
|
|
79
|
-
case "any":
|
|
80
|
-
case "unknown":
|
|
81
|
-
return def.type;
|
|
82
|
-
case "date":
|
|
83
|
-
return "Date";
|
|
84
|
-
case "record":
|
|
85
|
-
return `Record<${render(def.keyType)}, ${render(def.valueType)}>`;
|
|
86
|
-
case "map":
|
|
87
|
-
return `Map<${render(def.keyType)}, ${render(def.valueType)}>`;
|
|
88
|
-
case "set":
|
|
89
|
-
return `Set<${render(def.valueType)}>`;
|
|
90
|
-
case "promise":
|
|
91
|
-
return `Promise<${render(def.innerType)}>`;
|
|
92
|
-
case "enum":
|
|
93
|
-
return Object.values(def.entries).map(literal).join(" | ");
|
|
94
|
-
case "literal":
|
|
95
|
-
return def.values.map(literal).join(" | ");
|
|
96
|
-
case "union":
|
|
97
|
-
return def.options.map(render).join(" | ");
|
|
98
|
-
case "intersection":
|
|
99
|
-
return `${wrap(render(def.left))} & ${wrap(render(def.right))}`;
|
|
100
|
-
case "optional":
|
|
101
|
-
return `${render(def.innerType)} | undefined`;
|
|
102
|
-
case "nullable":
|
|
103
|
-
return `${render(def.innerType)} | null`;
|
|
104
|
-
case "nonoptional": {
|
|
105
|
-
const innerDef = defOf(def.innerType);
|
|
106
|
-
return render(innerDef.type === "optional" ? innerDef.innerType : def.innerType);
|
|
107
|
-
}
|
|
108
|
-
case "default":
|
|
109
|
-
case "prefault":
|
|
110
|
-
case "catch":
|
|
111
|
-
case "readonly":
|
|
112
|
-
return render(def.innerType);
|
|
113
|
-
case "lazy":
|
|
114
|
-
return render(def.getter());
|
|
115
|
-
case "pipe":
|
|
116
|
-
return render(pipeTarget(def));
|
|
117
|
-
default:
|
|
118
|
-
return "unknown";
|
|
119
|
-
}
|
|
120
|
-
});
|
|
121
|
-
}
|
|
122
|
-
function zodToExample(schema) {
|
|
123
|
-
return walk(schema, null, (def) => {
|
|
124
|
-
switch (def.type) {
|
|
125
|
-
case "object": {
|
|
126
|
-
const result = {};
|
|
127
|
-
for (const [key, value] of Object.entries(def.shape)) {
|
|
128
|
-
if (defOf(value).type !== "optional") {
|
|
129
|
-
result[key] = zodToExample(value);
|
|
130
|
-
}
|
|
131
|
-
}
|
|
132
|
-
return result;
|
|
133
|
-
}
|
|
134
|
-
case "array":
|
|
135
|
-
return [zodToExample(def.element)];
|
|
136
|
-
case "set":
|
|
137
|
-
return [zodToExample(def.valueType)];
|
|
138
|
-
case "tuple":
|
|
139
|
-
return def.items.map(zodToExample);
|
|
140
|
-
case "string":
|
|
141
|
-
return "";
|
|
142
|
-
case "number":
|
|
143
|
-
case "bigint":
|
|
144
|
-
return 0;
|
|
145
|
-
case "boolean":
|
|
146
|
-
return false;
|
|
147
|
-
case "date":
|
|
148
|
-
return new Date(0).toISOString();
|
|
149
|
-
case "enum":
|
|
150
|
-
return Object.values(def.entries)[0];
|
|
151
|
-
case "literal":
|
|
152
|
-
return def.values[0];
|
|
153
|
-
case "union":
|
|
154
|
-
return zodToExample(def.options[0]);
|
|
155
|
-
case "intersection": {
|
|
156
|
-
const left = zodToExample(def.left);
|
|
157
|
-
const right = zodToExample(def.right);
|
|
158
|
-
return isRecord2(left) && isRecord2(right) ? { ...left, ...right } : left;
|
|
159
|
-
}
|
|
160
|
-
case "optional":
|
|
161
|
-
case "nullable":
|
|
162
|
-
case "nonoptional":
|
|
163
|
-
case "default":
|
|
164
|
-
case "prefault":
|
|
165
|
-
case "catch":
|
|
166
|
-
case "readonly":
|
|
167
|
-
case "promise":
|
|
168
|
-
return zodToExample(def.innerType);
|
|
169
|
-
case "lazy":
|
|
170
|
-
return zodToExample(def.getter());
|
|
171
|
-
case "pipe":
|
|
172
|
-
return zodToExample(pipeTarget(def));
|
|
173
|
-
case "record":
|
|
174
|
-
case "map":
|
|
175
|
-
return {};
|
|
176
|
-
default:
|
|
177
|
-
return null;
|
|
178
|
-
}
|
|
179
|
-
});
|
|
180
|
-
}
|
|
181
|
-
|
|
182
|
-
// src/zod/introspect.ts
|
|
183
|
-
function pipeInput(def) {
|
|
184
|
-
return defOf(def.in).type === "transform" ? def.out : def.in;
|
|
185
|
-
}
|
|
186
|
-
function unwrapOnce(def) {
|
|
187
|
-
switch (def.type) {
|
|
188
|
-
case "optional":
|
|
189
|
-
case "nullable":
|
|
190
|
-
case "default":
|
|
191
|
-
case "prefault":
|
|
192
|
-
case "nonoptional":
|
|
193
|
-
case "catch":
|
|
194
|
-
case "readonly":
|
|
195
|
-
return def.innerType;
|
|
196
|
-
case "lazy":
|
|
197
|
-
return def.getter();
|
|
198
|
-
case "pipe":
|
|
199
|
-
return pipeInput(def);
|
|
200
|
-
default:
|
|
201
|
-
return;
|
|
202
|
-
}
|
|
203
|
-
}
|
|
204
|
-
function unwrapSchema(schema) {
|
|
205
|
-
const inner = unwrapOnce(defOf(schema));
|
|
206
|
-
return inner ? unwrapSchema(inner) : schema;
|
|
207
|
-
}
|
|
208
|
-
function getEnumValues(schema) {
|
|
209
|
-
const def = defOf(unwrapSchema(schema));
|
|
210
|
-
return def.type === "enum" ? Object.values(def.entries).map(String) : undefined;
|
|
211
|
-
}
|
|
212
|
-
function getObjectShape(schema) {
|
|
213
|
-
const def = defOf(unwrapSchema(schema));
|
|
214
|
-
return def.type === "object" ? def.shape : undefined;
|
|
215
|
-
}
|
|
216
|
-
function zodDefaults(schema) {
|
|
217
|
-
return defaultFor(schema);
|
|
218
|
-
}
|
|
219
|
-
function defaultFor(schema) {
|
|
220
|
-
return walk(schema, undefined, (def) => {
|
|
221
|
-
switch (def.type) {
|
|
222
|
-
case "default":
|
|
223
|
-
case "prefault":
|
|
224
|
-
return def.defaultValue;
|
|
225
|
-
case "optional":
|
|
226
|
-
return;
|
|
227
|
-
case "nullable":
|
|
228
|
-
return null;
|
|
229
|
-
case "object": {
|
|
230
|
-
const result = {};
|
|
231
|
-
for (const [key, child] of Object.entries(def.shape)) {
|
|
232
|
-
result[key] = defaultFor(child);
|
|
233
|
-
}
|
|
234
|
-
return result;
|
|
235
|
-
}
|
|
236
|
-
case "array":
|
|
237
|
-
return [];
|
|
238
|
-
case "string":
|
|
239
|
-
return "";
|
|
240
|
-
case "number":
|
|
241
|
-
return 0;
|
|
242
|
-
case "bigint":
|
|
243
|
-
return 0n;
|
|
244
|
-
case "boolean":
|
|
245
|
-
return false;
|
|
246
|
-
case "enum":
|
|
247
|
-
return Object.values(def.entries)[0];
|
|
248
|
-
case "literal":
|
|
249
|
-
return def.values[0];
|
|
250
|
-
case "union":
|
|
251
|
-
return def.options[0] && defaultFor(def.options[0]);
|
|
252
|
-
default: {
|
|
253
|
-
const inner = unwrapOnce(def);
|
|
254
|
-
return inner && defaultFor(inner);
|
|
255
|
-
}
|
|
256
|
-
}
|
|
257
|
-
});
|
|
258
|
-
}
|
|
259
22
|
// src/zod/jsonToZodSchemaMapper.ts
|
|
260
23
|
import { z } from "zod";
|
|
261
24
|
function jsonToZodSchemaMapper(jsonObject, zodSchema, config) {
|
|
@@ -342,6 +105,8 @@ var zJsonValue = z3.lazy(() => z3.union([
|
|
|
342
105
|
zJsonObject
|
|
343
106
|
]));
|
|
344
107
|
var zJsonObject = z3.record(z3.string(), zJsonValue);
|
|
108
|
+
var E164_REGEX = /^\+[1-9]\d{6,14}$/;
|
|
109
|
+
var zOptionalE164 = z3.string().refine((value) => value === "" || E164_REGEX.test(value), "Phone number must be in E.164 format (e.g. +14155551234)").describe("E.164 phone number (e.g. +14155551234); empty string clears it").nullable().transform((value) => value || null);
|
|
345
110
|
function parseJson(text, schema) {
|
|
346
111
|
let value;
|
|
347
112
|
try {
|
|
@@ -359,12 +124,13 @@ function zSingleOrArray(schema) {
|
|
|
359
124
|
}
|
|
360
125
|
var normalizeSingleOrArray = toArray2;
|
|
361
126
|
export {
|
|
127
|
+
E164_REGEX,
|
|
362
128
|
asId,
|
|
363
129
|
createIdHelpers,
|
|
364
130
|
createMinMaxFilter,
|
|
365
131
|
createZId,
|
|
366
|
-
getEnumValues,
|
|
367
|
-
getObjectShape,
|
|
132
|
+
getEnumValues2 as getEnumValues,
|
|
133
|
+
getObjectShape2 as getObjectShape,
|
|
368
134
|
jsonToZodSchemaMapper,
|
|
369
135
|
normalizeSingleOrArray,
|
|
370
136
|
parseId,
|
|
@@ -372,12 +138,13 @@ export {
|
|
|
372
138
|
safeParseId,
|
|
373
139
|
toGtLtFilter,
|
|
374
140
|
toGteLteFilter,
|
|
375
|
-
unwrapSchema,
|
|
141
|
+
unwrapSchema2 as unwrapSchema,
|
|
376
142
|
zJsonObject,
|
|
377
143
|
zJsonValue,
|
|
144
|
+
zOptionalE164,
|
|
378
145
|
zSingleOrArray,
|
|
379
|
-
zodDefaults,
|
|
146
|
+
zodDefaults2 as zodDefaults,
|
|
380
147
|
zodMinMaxFilter,
|
|
381
|
-
zodToExample,
|
|
382
|
-
zodToTypeString
|
|
148
|
+
zodToExample2 as zodToExample,
|
|
149
|
+
zodToTypeString2 as zodToTypeString
|
|
383
150
|
};
|
package/dist/string/index.d.ts
CHANGED
|
@@ -79,3 +79,24 @@ export declare function initials(name: string | null | undefined, options?: {
|
|
|
79
79
|
}): string;
|
|
80
80
|
/** `JSON.parse` that returns a `Result` instead of throwing. */
|
|
81
81
|
export declare function safeJsonParse<T = unknown>(text: string): Result<T, SyntaxError>;
|
|
82
|
+
/** Escapes `& < > " '` for HTML or XML text and attribute values. */
|
|
83
|
+
export declare function escapeHtml(text: string): string;
|
|
84
|
+
/**
|
|
85
|
+
* Removes emoji and tidies the spacing they leave, so `'Hi there 👋, welcome'`
|
|
86
|
+
* becomes `'Hi there, welcome'`. Use it for text that is spoken (TTS drops
|
|
87
|
+
* emoji from the audio but not from the transcript). Text without emoji is
|
|
88
|
+
* returned unchanged.
|
|
89
|
+
*/
|
|
90
|
+
export declare function stripEmoji(text: string): string;
|
|
91
|
+
/**
|
|
92
|
+
* Lowercased extension of a file name or path, without the dot. `undefined`
|
|
93
|
+
* when there is none; like `path.extname`, a leading dot (`.env`) is not one.
|
|
94
|
+
*/
|
|
95
|
+
export declare function fileExtension(filename: string): string | undefined;
|
|
96
|
+
/**
|
|
97
|
+
* Normalizes a value the way a JSON round trip does: `undefined` properties
|
|
98
|
+
* are dropped, `Date`s become ISO strings and `NaN` becomes `null`. Top-level
|
|
99
|
+
* `undefined` becomes `null`. Use it before storing loosely typed data in a
|
|
100
|
+
* JSON column. Throws on `bigint` and circular references.
|
|
101
|
+
*/
|
|
102
|
+
export declare function toJsonValue(value: unknown): JsonValue;
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
export type ConnectionAuthContractInput = {
|
|
2
|
+
reset: () => void;
|
|
3
|
+
create: (fetchImpl: typeof fetch, variant?: string) => {
|
|
4
|
+
read: () => Promise<unknown>;
|
|
5
|
+
login: (options?: {
|
|
6
|
+
signal?: AbortSignal;
|
|
7
|
+
}) => Promise<string>;
|
|
8
|
+
};
|
|
9
|
+
identityChanges: string[];
|
|
10
|
+
isLogin: (url: string) => boolean;
|
|
11
|
+
loginResponse: (token: string) => Response;
|
|
12
|
+
readResponse: () => Response;
|
|
13
|
+
tokenHeader: string;
|
|
14
|
+
};
|
|
15
|
+
/**
|
|
16
|
+
* Registers the races every client built on `ConnectionAuthCache`
|
|
17
|
+
* (`hanzio/api-wrapper/connection-auth`) must survive, run through the real
|
|
18
|
+
* client and its transport: shared refreshes, rotated credentials, late 401s,
|
|
19
|
+
* aborted waiters and failed fresh logins. Await it at the top level of a
|
|
20
|
+
* `bun:test` file.
|
|
21
|
+
*
|
|
22
|
+
* - `create(fetch, variant)` builds a client on the given fetch. `variant` is
|
|
23
|
+
* one of `identityChanges` (a credential change that must force a new login),
|
|
24
|
+
* `'settings'` (a non-auth setting that must reuse the login), `'connection'`
|
|
25
|
+
* (another connection) or `'secret'` (a rotated secret).
|
|
26
|
+
* - `read()` makes one authenticated request; on a 401 it calls `reject` and
|
|
27
|
+
* retries once. `login()` forces a fresh login and resolves its token.
|
|
28
|
+
* - `reset()` clears the cache between tests.
|
|
29
|
+
* - `tokenHeader` is where requests carry the token; `'authorization'` means
|
|
30
|
+
* `Bearer <token>`.
|
|
31
|
+
*
|
|
32
|
+
* @example
|
|
33
|
+
* await connectionAuthContract({
|
|
34
|
+
* reset: () => authCache.clear(),
|
|
35
|
+
* create: (fetch, variant) => new ShopApi(credentialsFor(variant), fetch),
|
|
36
|
+
* identityChanges: ['apiKey', 'secret'],
|
|
37
|
+
* isLogin: (url) => url.endsWith('/oauth/token'),
|
|
38
|
+
* loginResponse: (token) => Response.json({ access_token: token, expires_in: 3600 }),
|
|
39
|
+
* readResponse: () => Response.json({ items: [] }),
|
|
40
|
+
* tokenHeader: 'authorization'
|
|
41
|
+
* })
|
|
42
|
+
*/
|
|
43
|
+
export declare function connectionAuthContract(input: ConnectionAuthContractInput): Promise<void>;
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
type LogMethod = (...args: unknown[]) => void;
|
|
2
|
+
export type NoopLogger = {
|
|
3
|
+
trace: LogMethod;
|
|
4
|
+
debug: LogMethod;
|
|
5
|
+
info: LogMethod;
|
|
6
|
+
warn: LogMethod;
|
|
7
|
+
error: LogMethod;
|
|
8
|
+
fatal: LogMethod;
|
|
9
|
+
bind: (...args: unknown[]) => NoopLogger;
|
|
10
|
+
child: (...args: unknown[]) => NoopLogger;
|
|
11
|
+
};
|
|
12
|
+
/** A logger that discards everything; `bind` and `child` return itself. */
|
|
13
|
+
export declare const noopLogger: NoopLogger;
|
|
14
|
+
/**
|
|
15
|
+
* Reads one argument from a mock's call history as `T`. Bun types
|
|
16
|
+
* `mock.calls` as `never[]` for loosely typed mocks.
|
|
17
|
+
*
|
|
18
|
+
* @example
|
|
19
|
+
* const input = mockCallArg<CreateUserInput>(createUser) // first call, first argument
|
|
20
|
+
*/
|
|
21
|
+
export declare function mockCallArg<T>(fn: {
|
|
22
|
+
mock: {
|
|
23
|
+
calls: unknown[][];
|
|
24
|
+
};
|
|
25
|
+
}, callIndex?: number, argIndex?: number): T;
|
|
26
|
+
export {};
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
export { type ConnectionAuthContractInput, connectionAuthContract } from './connection-auth-contract';
|
|
2
|
+
export { mockCallArg, type NoopLogger, noopLogger } from './helpers';
|
|
3
|
+
export { ModuleMocker } from './module-mocker';
|
|
4
|
+
export { createPrismaMock, type DeepMockedPrisma, type PrismaMethodMock } from './prisma';
|
|
5
|
+
export { createTestStorage, installWindowShim } from './window';
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
type ModuleExports = Record<string, unknown>;
|
|
2
|
+
/**
|
|
3
|
+
* `mock.module` that can be undone. Bun replaces a mocked module for the whole
|
|
4
|
+
* process and `mock.restore()` does not bring it back
|
|
5
|
+
* (https://github.com/oven-sh/bun/issues/7823), so one suite's stub silently
|
|
6
|
+
* leaks into every later suite.
|
|
7
|
+
*
|
|
8
|
+
* Mocks spread the module's real exports first, so exports you don't override
|
|
9
|
+
* keep working, and `clear()` re-registers the originals. Call it in
|
|
10
|
+
* `afterEach` or `afterAll`.
|
|
11
|
+
*
|
|
12
|
+
* Bun resolves specifiers relative to the file that registers the mock, so
|
|
13
|
+
* pass absolute paths or package names. A `resolve` function maps your own
|
|
14
|
+
* shorthand (an `@/` alias, a source-root-relative path) to absolute paths.
|
|
15
|
+
*
|
|
16
|
+
* @example
|
|
17
|
+
* const moduleMocker = new ModuleMocker((specifier) =>
|
|
18
|
+
* specifier.startsWith('@/') ? path.resolve(srcDir, specifier.slice(2)) : specifier
|
|
19
|
+
* )
|
|
20
|
+
* await moduleMocker.mock('@/lib/posthog', () => ({ captureException: mock() }))
|
|
21
|
+
* afterAll(() => moduleMocker.clear())
|
|
22
|
+
*/
|
|
23
|
+
export declare class ModuleMocker {
|
|
24
|
+
private readonly resolve;
|
|
25
|
+
private restorers;
|
|
26
|
+
constructor(resolve?: (specifier: string) => string);
|
|
27
|
+
mock(specifier: string, renderMocks: () => ModuleExports): Promise<void>;
|
|
28
|
+
clear(): void;
|
|
29
|
+
}
|
|
30
|
+
export {};
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import type { Mock, mock } from 'bun:test';
|
|
2
|
+
export type PrismaMethodMock = Mock<(...args: unknown[]) => Promise<unknown>>;
|
|
3
|
+
/**
|
|
4
|
+
* A Prisma client where every model delegate and every method is a Bun mock,
|
|
5
|
+
* created on first access, like `jest-mock-extended`'s `mockDeep()`.
|
|
6
|
+
* `$`-prefixed client methods (`$transaction`, `$queryRaw`) are mocks too.
|
|
7
|
+
*/
|
|
8
|
+
export type DeepMockedPrisma<Client> = {
|
|
9
|
+
[K in keyof Client]: Client[K] extends (...args: never[]) => unknown ? PrismaMethodMock : {
|
|
10
|
+
[Method in keyof Client[K]]: PrismaMethodMock;
|
|
11
|
+
};
|
|
12
|
+
} & {
|
|
13
|
+
/** Resets every mock created so far. Call it in `beforeEach`. */
|
|
14
|
+
$reset: () => void;
|
|
15
|
+
};
|
|
16
|
+
/**
|
|
17
|
+
* Builds a deep auto-mock of a Prisma client from Bun's `mock`. Register it
|
|
18
|
+
* with `mock.module` in place of the module that exports your client.
|
|
19
|
+
*
|
|
20
|
+
* @example
|
|
21
|
+
* import { mock } from 'bun:test'
|
|
22
|
+
* import type { prisma } from '../lib/prisma'
|
|
23
|
+
*
|
|
24
|
+
* export const prismaMock = createPrismaMock<typeof prisma>(mock)
|
|
25
|
+
* mock.module(prismaModulePath, () => ({ ...prismaExports, prisma: prismaMock }))
|
|
26
|
+
*
|
|
27
|
+
* prismaMock.user.findUnique.mockResolvedValue({ id: 'u1' })
|
|
28
|
+
* expect(prismaMock.user.findUnique).toHaveBeenCalledWith({ where: { id: 'u1' } })
|
|
29
|
+
*/
|
|
30
|
+
export declare function createPrismaMock<Client>(createMock: typeof mock): DeepMockedPrisma<Client>;
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
/** A complete in-memory `Storage` (`localStorage` / `sessionStorage`). */
|
|
2
|
+
export declare function createTestStorage(): Storage;
|
|
3
|
+
/**
|
|
4
|
+
* Installs a minimal `globalThis.window` for unit tests of browser-facing code
|
|
5
|
+
* that only probes `window` (`location`, `localStorage`, event listeners), and
|
|
6
|
+
* returns a `reset` to call in `afterEach`.
|
|
7
|
+
*
|
|
8
|
+
* Tests may assign a partial `window`. The shim keeps its own shape and copies
|
|
9
|
+
* `location`, `localStorage` and the listener functions from the assigned
|
|
10
|
+
* object, because libraries such as axios and PostHog read those at import
|
|
11
|
+
* time. It installs no `document`: Vue and PrismJS treat one as a full DOM.
|
|
12
|
+
*
|
|
13
|
+
* @example
|
|
14
|
+
* // test-setup.ts, preloaded through bunfig.toml
|
|
15
|
+
* const resetWindow = installWindowShim()
|
|
16
|
+
* afterEach(resetWindow)
|
|
17
|
+
*/
|
|
18
|
+
export declare function installWindowShim(href?: string): () => void;
|
package/dist/zod/index.d.ts
CHANGED
|
@@ -30,6 +30,16 @@ export declare function createIdHelpers<TypeNames extends string>(): {
|
|
|
30
30
|
/** Any JSON value (no `undefined`, `NaN` or `Infinity`). */
|
|
31
31
|
export declare const zJsonValue: z.ZodType<JsonValue>;
|
|
32
32
|
export declare const zJsonObject: z.ZodType<JsonObject>;
|
|
33
|
+
/** An E.164 phone number: `+`, then 7 to 15 digits with no leading zero. */
|
|
34
|
+
export declare const E164_REGEX: RegExp;
|
|
35
|
+
/**
|
|
36
|
+
* An optional E.164 phone number for forms: a cleared input submits `''`,
|
|
37
|
+
* which means "no number", so `''` and `null` both parse to `null`.
|
|
38
|
+
*
|
|
39
|
+
* Deliberately not `union([regex, literal('')])`: that serializes the empty
|
|
40
|
+
* literal as `enum: [""]`, which Gemini function declarations reject.
|
|
41
|
+
*/
|
|
42
|
+
export declare const zOptionalE164: z.ZodPipe<z.ZodNullable<z.ZodString>, z.ZodTransform<string | null, string | null>>;
|
|
33
43
|
/** `JSON.parse` + `schema.safeParse` without throwing. */
|
|
34
44
|
export declare function parseJson<S extends z.ZodType>(text: string, schema: S): Result<z.output<S>, SyntaxError | z.ZodError>;
|
|
35
45
|
export declare function zSingleOrArray<T extends z.ZodType>(schema: T): z.ZodUnion<readonly [z.ZodArray<T>, T]>;
|
package/dist/zod/introspect.d.ts
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import type { z } from 'zod';
|
|
2
|
-
import { type Schema } from './zodToTypeString';
|
|
2
|
+
import { type Def, type Schema } from './zodToTypeString';
|
|
3
|
+
export declare function unwrapOnce(def: Def): Schema | undefined;
|
|
3
4
|
/**
|
|
4
5
|
* Strips optional/nullable/default/prefault/nonoptional/catch/readonly/lazy
|
|
5
6
|
* wrappers and pipes (input side) until the schema that carries the shape.
|