zod 4.4.0 → 4.4.2
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 +0 -17
- package/package.json +1 -1
- package/src/v3/tests/all-errors.test.ts +3 -3
- package/src/v3/tests/object.test.ts +5 -5
- package/src/v3/tests/partials.test.ts +3 -3
- package/src/v4/classic/schemas.ts +23 -3
- package/src/v4/classic/tests/assignability.test.ts +6 -0
- package/src/v4/classic/tests/discriminated-unions.test.ts +3 -0
- package/src/v4/classic/tests/preprocess-types.test.ts +26 -0
- package/src/v4/classic/tests/preprocess.test.ts +44 -0
- package/src/v4/classic/tests/to-json-schema.test.ts +22 -0
- package/src/v4/classic/tests/tuple.test.ts +30 -13
- package/src/v4/core/api.ts +6 -4
- package/src/v4/core/json-schema-processors.ts +2 -1
- package/src/v4/core/schemas.ts +53 -23
- package/src/v4/core/to-json-schema.ts +1 -0
- package/src/v4/core/versions.ts +1 -1
- package/src/v4/mini/schemas.ts +1 -1
- package/src/v4/mini/tests/index.test.ts +5 -0
- package/v4/classic/schemas.cjs +10 -2
- package/v4/classic/schemas.d.cts +8 -2
- package/v4/classic/schemas.d.ts +8 -2
- package/v4/classic/schemas.js +9 -1
- package/v4/core/api.d.cts +6 -4
- package/v4/core/api.d.ts +6 -4
- package/v4/core/json-schema-processors.cjs +2 -1
- package/v4/core/json-schema-processors.js +2 -1
- package/v4/core/schemas.cjs +27 -25
- package/v4/core/schemas.d.cts +13 -0
- package/v4/core/schemas.d.ts +13 -0
- package/v4/core/schemas.js +26 -24
- package/v4/core/to-json-schema.cjs +2 -0
- package/v4/core/to-json-schema.js +2 -0
- package/v4/core/versions.cjs +1 -1
- package/v4/core/versions.js +1 -1
- package/v4/mini/schemas.d.cts +1 -1
- package/v4/mini/schemas.d.ts +1 -1
package/README.md
CHANGED
|
@@ -31,23 +31,6 @@
|
|
|
31
31
|
<br/>
|
|
32
32
|
<br/>
|
|
33
33
|
|
|
34
|
-
<h2 align="center">Featured sponsor: Jazz</h2>
|
|
35
|
-
|
|
36
|
-
<div align="center">
|
|
37
|
-
<a href="https://jazz.tools/?utm_source=zod">
|
|
38
|
-
<picture width="85%" >
|
|
39
|
-
<source media="(prefers-color-scheme: dark)" srcset="https://raw.githubusercontent.com/garden-co/jazz/938f6767e46cdfded60e50d99bf3b533f4809c68/homepage/homepage/public/Zod%20sponsor%20message.png">
|
|
40
|
-
<img alt="jazz logo" src="https://raw.githubusercontent.com/garden-co/jazz/938f6767e46cdfded60e50d99bf3b533f4809c68/homepage/homepage/public/Zod%20sponsor%20message.png" width="85%">
|
|
41
|
-
</picture>
|
|
42
|
-
</a>
|
|
43
|
-
<br/>
|
|
44
|
-
<p><sub>Learn more about <a target="_blank" rel="noopener noreferrer" href="mailto:sponsorship@colinhacks.com">featured sponsorships</a></sub></p>
|
|
45
|
-
</div>
|
|
46
|
-
|
|
47
|
-
<br/>
|
|
48
|
-
<br/>
|
|
49
|
-
<br/>
|
|
50
|
-
|
|
51
34
|
### [Read the docs →](https://zod.dev/api)
|
|
52
35
|
|
|
53
36
|
<br/>
|
package/package.json
CHANGED
|
@@ -16,7 +16,7 @@ type TestFormErrors = z.inferFlattenedErrors<typeof Test>;
|
|
|
16
16
|
test("default flattened errors type inference", () => {
|
|
17
17
|
type TestTypeErrors = {
|
|
18
18
|
formErrors: string[];
|
|
19
|
-
fieldErrors: { [P in keyof z.TypeOf<typeof Test>]?: string[]
|
|
19
|
+
fieldErrors: { [P in keyof z.TypeOf<typeof Test>]?: string[] };
|
|
20
20
|
};
|
|
21
21
|
|
|
22
22
|
util.assertEqual<z.inferFlattenedErrors<typeof Test>, TestTypeErrors>(true);
|
|
@@ -28,7 +28,7 @@ test("custom flattened errors type inference", () => {
|
|
|
28
28
|
type TestTypeErrors = {
|
|
29
29
|
formErrors: ErrorType[];
|
|
30
30
|
fieldErrors: {
|
|
31
|
-
[P in keyof z.TypeOf<typeof Test>]?: ErrorType[]
|
|
31
|
+
[P in keyof z.TypeOf<typeof Test>]?: ErrorType[];
|
|
32
32
|
};
|
|
33
33
|
};
|
|
34
34
|
|
|
@@ -40,7 +40,7 @@ test("custom flattened errors type inference", () => {
|
|
|
40
40
|
test("form errors type inference", () => {
|
|
41
41
|
type TestTypeErrors = {
|
|
42
42
|
formErrors: string[];
|
|
43
|
-
fieldErrors: { [P in keyof z.TypeOf<typeof Test>]?: string[]
|
|
43
|
+
fieldErrors: { [P in keyof z.TypeOf<typeof Test>]?: string[] };
|
|
44
44
|
};
|
|
45
45
|
|
|
46
46
|
util.assertEqual<z.inferFlattenedErrors<typeof Test>, TestTypeErrors>(true);
|
|
@@ -212,9 +212,9 @@ test("inferred merged object type with optional properties", async () => {
|
|
|
212
212
|
.object({ a: z.string(), b: z.string().optional() })
|
|
213
213
|
.merge(z.object({ a: z.string().optional(), b: z.string() }));
|
|
214
214
|
type Merged = z.infer<typeof Merged>;
|
|
215
|
-
util.assertEqual<Merged, { a?: string; b: string }>(true);
|
|
215
|
+
util.assertEqual<Merged, { a?: string | undefined; b: string }>(true);
|
|
216
216
|
// todo
|
|
217
|
-
// util.assertEqual<Merged, { a?: string; b: string }>(true);
|
|
217
|
+
// util.assertEqual<Merged, { a?: string | undefined; b: string }>(true);
|
|
218
218
|
});
|
|
219
219
|
|
|
220
220
|
test("inferred unioned object type with optional properties", async () => {
|
|
@@ -223,7 +223,7 @@ test("inferred unioned object type with optional properties", async () => {
|
|
|
223
223
|
z.object({ a: z.string().optional(), b: z.string() }),
|
|
224
224
|
]);
|
|
225
225
|
type Unioned = z.infer<typeof Unioned>;
|
|
226
|
-
util.assertEqual<Unioned, { a: string; b?: string } | { a?: string; b: string }>(true);
|
|
226
|
+
util.assertEqual<Unioned, { a: string; b?: string | undefined } | { a?: string | undefined; b: string }>(true);
|
|
227
227
|
});
|
|
228
228
|
|
|
229
229
|
test("inferred enum type", async () => {
|
|
@@ -245,13 +245,13 @@ test("inferred enum type", async () => {
|
|
|
245
245
|
test("inferred partial object type with optional properties", async () => {
|
|
246
246
|
const Partial = z.object({ a: z.string(), b: z.string().optional() }).partial();
|
|
247
247
|
type Partial = z.infer<typeof Partial>;
|
|
248
|
-
util.assertEqual<Partial, { a?: string; b?: string }>(true);
|
|
248
|
+
util.assertEqual<Partial, { a?: string | undefined; b?: string | undefined }>(true);
|
|
249
249
|
});
|
|
250
250
|
|
|
251
251
|
test("inferred picked object type with optional properties", async () => {
|
|
252
252
|
const Picked = z.object({ a: z.string(), b: z.string().optional() }).pick({ b: true });
|
|
253
253
|
type Picked = z.infer<typeof Picked>;
|
|
254
|
-
util.assertEqual<Picked, { b?: string }>(true);
|
|
254
|
+
util.assertEqual<Picked, { b?: string | undefined }>(true);
|
|
255
255
|
});
|
|
256
256
|
|
|
257
257
|
test("inferred type for unknown/any keys", () => {
|
|
@@ -21,7 +21,7 @@ test("shallow inference", () => {
|
|
|
21
21
|
name?: string | undefined;
|
|
22
22
|
age?: number | undefined;
|
|
23
23
|
outer?: { inner: string } | undefined;
|
|
24
|
-
array?: { asdf: string }[];
|
|
24
|
+
array?: { asdf: string }[] | undefined;
|
|
25
25
|
};
|
|
26
26
|
util.assertEqual<shallow, correct>(true);
|
|
27
27
|
});
|
|
@@ -41,7 +41,7 @@ test("deep partial inference", () => {
|
|
|
41
41
|
asdf.parse("asdf");
|
|
42
42
|
type deep = z.infer<typeof deep>;
|
|
43
43
|
type correct = {
|
|
44
|
-
array?: { asdf?: string }[];
|
|
44
|
+
array?: { asdf?: string | undefined }[] | undefined;
|
|
45
45
|
name?: string | undefined;
|
|
46
46
|
age?: number | undefined;
|
|
47
47
|
outer?: { inner?: string | undefined } | undefined;
|
|
@@ -118,7 +118,7 @@ test("deep partial inference", () => {
|
|
|
118
118
|
asdf?: string | undefined;
|
|
119
119
|
}[]
|
|
120
120
|
| undefined;
|
|
121
|
-
tuple?: [{ value?: string }] | undefined;
|
|
121
|
+
tuple?: [{ value?: string | undefined }] | undefined;
|
|
122
122
|
};
|
|
123
123
|
util.assertEqual<expected, partialed>(true);
|
|
124
124
|
});
|
|
@@ -1617,7 +1617,7 @@ export const ZodDiscriminatedUnion: core.$constructor<ZodDiscriminatedUnion> = /
|
|
|
1617
1617
|
);
|
|
1618
1618
|
|
|
1619
1619
|
export function discriminatedUnion<
|
|
1620
|
-
Types extends readonly [core.$ZodTypeDiscriminable
|
|
1620
|
+
Types extends readonly [core.$ZodTypeDiscriminable<Disc>, ...core.$ZodTypeDiscriminable<Disc>[]],
|
|
1621
1621
|
Disc extends string,
|
|
1622
1622
|
>(
|
|
1623
1623
|
discriminator: Disc,
|
|
@@ -2361,6 +2361,22 @@ export function invertCodec<A extends core.SomeType, B extends core.SomeType>(co
|
|
|
2361
2361
|
}) as any;
|
|
2362
2362
|
}
|
|
2363
2363
|
|
|
2364
|
+
// ZodPreprocess
|
|
2365
|
+
export interface ZodPreprocess<B extends core.SomeType = core.$ZodType>
|
|
2366
|
+
extends ZodPipe<core.$ZodTransform, B>,
|
|
2367
|
+
core.$ZodPreprocess<B> {
|
|
2368
|
+
"~standard": ZodStandardSchemaWithJSON<this>;
|
|
2369
|
+
_zod: core.$ZodPreprocessInternals<B>;
|
|
2370
|
+
def: core.$ZodPreprocessDef<B>;
|
|
2371
|
+
}
|
|
2372
|
+
export const ZodPreprocess: core.$constructor<ZodPreprocess> = /*@__PURE__*/ core.$constructor(
|
|
2373
|
+
"ZodPreprocess",
|
|
2374
|
+
(inst, def) => {
|
|
2375
|
+
ZodPipe.init(inst, def);
|
|
2376
|
+
core.$ZodPreprocess.init(inst, def);
|
|
2377
|
+
}
|
|
2378
|
+
);
|
|
2379
|
+
|
|
2364
2380
|
// ZodReadonly
|
|
2365
2381
|
export interface ZodReadonly<T extends core.SomeType = core.$ZodType>
|
|
2366
2382
|
extends _ZodType<core.$ZodReadonlyInternals<T>>,
|
|
@@ -2645,6 +2661,10 @@ export function json(params?: string | core.$ZodCustomParams): ZodJSONSchema {
|
|
|
2645
2661
|
export function preprocess<A, U extends core.SomeType, B = unknown>(
|
|
2646
2662
|
fn: (arg: B, ctx: core.$RefinementCtx) => A,
|
|
2647
2663
|
schema: U
|
|
2648
|
-
):
|
|
2649
|
-
return
|
|
2664
|
+
): ZodPreprocess<U> {
|
|
2665
|
+
return new ZodPreprocess({
|
|
2666
|
+
type: "pipe",
|
|
2667
|
+
in: transform(fn as any) as any as core.$ZodTransform,
|
|
2668
|
+
out: schema as any as core.$ZodType,
|
|
2669
|
+
}) as any;
|
|
2650
2670
|
}
|
|
@@ -143,6 +143,12 @@ test("assignability", () => {
|
|
|
143
143
|
z.unknown().pipe(z.number()) satisfies z.core.$ZodPipe;
|
|
144
144
|
z.unknown().pipe(z.number()) satisfies z.ZodPipe;
|
|
145
145
|
|
|
146
|
+
// $ZodPreprocess
|
|
147
|
+
z.preprocess((v) => v, z.number()) satisfies z.core.$ZodPreprocess;
|
|
148
|
+
z.preprocess((v) => v, z.number()) satisfies z.ZodPreprocess;
|
|
149
|
+
z.preprocess((v) => v, z.number()) satisfies z.core.$ZodPipe<z.core.$ZodTransform, z.ZodNumber>;
|
|
150
|
+
z.preprocess((v) => v, z.number()) satisfies z.ZodPipe<z.core.$ZodTransform, z.ZodNumber>;
|
|
151
|
+
|
|
146
152
|
// $ZodSuccess
|
|
147
153
|
z.success(z.string()) satisfies z.core.$ZodSuccess;
|
|
148
154
|
z.success(z.string()) satisfies z.ZodSuccess;
|
|
@@ -264,6 +264,9 @@ test("valid discriminator value, invalid data", () => {
|
|
|
264
264
|
});
|
|
265
265
|
|
|
266
266
|
test("wrong schema - missing discriminator", () => {
|
|
267
|
+
// @ts-expect-error missing discriminator property
|
|
268
|
+
z.discriminatedUnion("type", [z.object({ value: z.string() })]);
|
|
269
|
+
|
|
267
270
|
try {
|
|
268
271
|
z.discriminatedUnion("type", [
|
|
269
272
|
z.object({ type: z.literal("a"), a: z.string() }),
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import { expectTypeOf, test } from "vitest";
|
|
2
|
+
import * as z from "zod/v4";
|
|
3
|
+
|
|
4
|
+
test("ZodPreprocess<B> assignable to ZodPipe<$ZodTransform, B>", () => {
|
|
5
|
+
const pre = z.preprocess((v) => v, z.string().optional());
|
|
6
|
+
const _asPipe: z.ZodPipe<z.core.$ZodTransform, z.ZodOptional<z.ZodString>> = pre;
|
|
7
|
+
const _asCorePipe: z.core.$ZodPipe<z.core.$ZodTransform, z.ZodOptional<z.ZodString>> = pre;
|
|
8
|
+
expectTypeOf(_asPipe).toMatchTypeOf<z.ZodPipe>();
|
|
9
|
+
expectTypeOf(_asCorePipe).toMatchTypeOf<z.core.$ZodPipe>();
|
|
10
|
+
});
|
|
11
|
+
|
|
12
|
+
test("ZodPreprocess optin/optout defer to B", () => {
|
|
13
|
+
const optionalInside = z.preprocess((v) => v, z.string().optional());
|
|
14
|
+
expectTypeOf<(typeof optionalInside)["_zod"]["optin"]>().toEqualTypeOf<"optional">();
|
|
15
|
+
expectTypeOf<(typeof optionalInside)["_zod"]["optout"]>().toEqualTypeOf<"optional">();
|
|
16
|
+
|
|
17
|
+
const required = z.preprocess((v) => v, z.string());
|
|
18
|
+
expectTypeOf<(typeof required)["_zod"]["optin"]>().toEqualTypeOf<"optional" | undefined>();
|
|
19
|
+
expectTypeOf<(typeof required)["_zod"]["optout"]>().toEqualTypeOf<"optional" | undefined>();
|
|
20
|
+
});
|
|
21
|
+
|
|
22
|
+
test("ZodPreprocess input/output inference", () => {
|
|
23
|
+
const pre = z.preprocess((v) => v, z.number().optional());
|
|
24
|
+
expectTypeOf<z.output<typeof pre>>().toEqualTypeOf<number | undefined>();
|
|
25
|
+
expectTypeOf<z.input<typeof pre>>().toEqualTypeOf<unknown>();
|
|
26
|
+
});
|
|
@@ -280,3 +280,47 @@ test("perform transform with non-fatal issues", () => {
|
|
|
280
280
|
]]
|
|
281
281
|
`);
|
|
282
282
|
});
|
|
283
|
+
|
|
284
|
+
// https://github.com/colinhacks/zod/issues/5917
|
|
285
|
+
test("optional propagates through preprocess inside object", () => {
|
|
286
|
+
const outer = z.object({ x: z.preprocess((v) => v, z.number()).optional() });
|
|
287
|
+
const inner = z.object({ x: z.preprocess((v) => v, z.number().optional()) });
|
|
288
|
+
|
|
289
|
+
expect(outer.safeParse({}).success).toBe(true);
|
|
290
|
+
expect(inner.safeParse({}).success).toBe(true);
|
|
291
|
+
|
|
292
|
+
expect(outer.safeParse({ x: 1 })).toEqual({ success: true, data: { x: 1 } });
|
|
293
|
+
expect(inner.safeParse({ x: 1 })).toEqual({ success: true, data: { x: 1 } });
|
|
294
|
+
|
|
295
|
+
expect(inner._zod.def.shape.x._zod.optin).toBe("optional");
|
|
296
|
+
expect(inner._zod.def.shape.x._zod.optout).toBe("optional");
|
|
297
|
+
});
|
|
298
|
+
|
|
299
|
+
test("preprocess is a structural subtype of ZodPipe", () => {
|
|
300
|
+
const schema = z.preprocess((v) => v, z.string());
|
|
301
|
+
expect(schema).toBeInstanceOf(z.ZodPipe);
|
|
302
|
+
expect(schema).toBeInstanceOf(z.ZodPreprocess);
|
|
303
|
+
expect(schema._zod.def.type).toBe("pipe");
|
|
304
|
+
});
|
|
305
|
+
|
|
306
|
+
test("preprocess does not propagate values/propValues from inner schema", () => {
|
|
307
|
+
const inner = z.preprocess((v) => v, z.literal("test"));
|
|
308
|
+
expect(inner._zod.values).toBeUndefined();
|
|
309
|
+
expect(inner._zod.propValues).toBeUndefined();
|
|
310
|
+
});
|
|
311
|
+
|
|
312
|
+
test("preprocess as discriminator throws at construction (no propValues to inherit)", () => {
|
|
313
|
+
const schema = z.discriminatedUnion("kind", [
|
|
314
|
+
z.object({ kind: z.preprocess((v: any) => String(v).toUpperCase(), z.literal("A")), a: z.string() }),
|
|
315
|
+
z.object({ kind: z.preprocess((v: any) => String(v).toUpperCase(), z.literal("B")), b: z.number() }),
|
|
316
|
+
]);
|
|
317
|
+
expect(() => schema.parse({ kind: "a", a: "x" })).toThrow(/Invalid discriminated union option/);
|
|
318
|
+
});
|
|
319
|
+
|
|
320
|
+
test("preprocess as record key does not restrict accepted keys", () => {
|
|
321
|
+
const schema = z.record(
|
|
322
|
+
z.preprocess((v: any) => String(v).toLowerCase(), z.enum(["a", "b"])),
|
|
323
|
+
z.string()
|
|
324
|
+
);
|
|
325
|
+
expect(schema.safeParse({ A: "x", B: "y" })).toEqual({ success: true, data: { a: "x", b: "y" } });
|
|
326
|
+
});
|
|
@@ -2896,6 +2896,28 @@ test("use output type for preprocess", () => {
|
|
|
2896
2896
|
`);
|
|
2897
2897
|
});
|
|
2898
2898
|
|
|
2899
|
+
test("strip output-side examples from input JSON schema for codec", () => {
|
|
2900
|
+
const codec = z
|
|
2901
|
+
.codec(z.string(), z.number(), { decode: (s) => Number(s), encode: (n) => String(n) })
|
|
2902
|
+
.meta({ examples: [42] });
|
|
2903
|
+
|
|
2904
|
+
expect(z.toJSONSchema(codec, { io: "input" })).toMatchInlineSnapshot(`
|
|
2905
|
+
{
|
|
2906
|
+
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
|
2907
|
+
"type": "string",
|
|
2908
|
+
}
|
|
2909
|
+
`);
|
|
2910
|
+
expect(z.toJSONSchema(codec, { io: "output" })).toMatchInlineSnapshot(`
|
|
2911
|
+
{
|
|
2912
|
+
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
|
2913
|
+
"examples": [
|
|
2914
|
+
42,
|
|
2915
|
+
],
|
|
2916
|
+
"type": "number",
|
|
2917
|
+
}
|
|
2918
|
+
`);
|
|
2919
|
+
});
|
|
2920
|
+
|
|
2899
2921
|
// test("isTransforming", () => {
|
|
2900
2922
|
// const tx = z.core.isTransforming;
|
|
2901
2923
|
// expect(tx(z.string())).toEqual(false);
|
|
@@ -282,11 +282,10 @@ test("tuple result is dense when optional precedes a default", () => {
|
|
|
282
282
|
expect(1 in out && 3 in out).toEqual(true);
|
|
283
283
|
});
|
|
284
284
|
|
|
285
|
-
test("tuple
|
|
286
|
-
// An
|
|
287
|
-
//
|
|
288
|
-
//
|
|
289
|
-
// happily fill in slots after a slot it just decided was missing/invalid.
|
|
285
|
+
test("tuple truncates absent optional rejections only when the output tail is optional", () => {
|
|
286
|
+
// An absent optional-output slot can only be swallowed when every later
|
|
287
|
+
// output slot is optional too. If a later default would make the output tail
|
|
288
|
+
// required, truncating would violate the tuple's output type.
|
|
290
289
|
const refusesUndefined = z
|
|
291
290
|
.string()
|
|
292
291
|
.optional()
|
|
@@ -294,13 +293,15 @@ test("tuple breaks and truncates on first absent-optional rejection", () => {
|
|
|
294
293
|
|
|
295
294
|
const trailingDefault = z.tuple([z.string(), refusesUndefined, z.string().default("d")]);
|
|
296
295
|
const r1 = trailingDefault.safeParse(["alpha"]);
|
|
297
|
-
expect(r1.success).toBe(
|
|
298
|
-
expect(r1.
|
|
296
|
+
expect(r1.success).toBe(false);
|
|
297
|
+
expect(r1.error!.issues[0].path).toEqual([1]);
|
|
299
298
|
|
|
300
|
-
// Optional slots BEFORE the rejected one
|
|
301
|
-
//
|
|
299
|
+
// Optional slots BEFORE the rejected one still cannot hide a later required
|
|
300
|
+
// output slot.
|
|
302
301
|
const beforeReject = z.tuple([z.string(), z.string().optional(), refusesUndefined, z.string().default("d")]);
|
|
303
|
-
|
|
302
|
+
const r2 = beforeReject.safeParse(["alpha"]);
|
|
303
|
+
expect(r2.success).toBe(false);
|
|
304
|
+
expect(r2.error!.issues[0].path).toEqual([2]);
|
|
304
305
|
|
|
305
306
|
// No default after — truncate still applies, no spurious issue surfaces.
|
|
306
307
|
const noTrailingDefault = z.tuple([z.string(), refusesUndefined]);
|
|
@@ -309,7 +310,7 @@ test("tuple breaks and truncates on first absent-optional rejection", () => {
|
|
|
309
310
|
expect(r3.data).toEqual(["alpha"]);
|
|
310
311
|
});
|
|
311
312
|
|
|
312
|
-
test("tuple
|
|
313
|
+
test("tuple rejects absent optional before required output under async parse", async () => {
|
|
313
314
|
const refusesUndefined = z
|
|
314
315
|
.string()
|
|
315
316
|
.optional()
|
|
@@ -317,8 +318,24 @@ test("tuple breaks on absent-optional rejection under async parse", async () =>
|
|
|
317
318
|
|
|
318
319
|
const schema = z.tuple([z.string(), refusesUndefined, z.string().default("d")]);
|
|
319
320
|
const r = await schema.safeParseAsync(["alpha"]);
|
|
320
|
-
expect(r.success).toBe(
|
|
321
|
-
expect(r.
|
|
321
|
+
expect(r.success).toBe(false);
|
|
322
|
+
expect(r.error!.issues[0].path).toEqual([1]);
|
|
323
|
+
});
|
|
324
|
+
|
|
325
|
+
test("tuple rejects absent exact optional before defaulted output", () => {
|
|
326
|
+
const schema = z.tuple([z.string(), z.string().exactOptional(), z.string().default("fallback")]);
|
|
327
|
+
expectTypeOf<typeof schema._output>().toEqualTypeOf<[string, string, string]>();
|
|
328
|
+
|
|
329
|
+
const missingExact = schema.safeParse(["alpha"]);
|
|
330
|
+
expect(missingExact.success).toBe(false);
|
|
331
|
+
expect(missingExact.error!.issues[0].path).toEqual([1]);
|
|
332
|
+
|
|
333
|
+
expect(schema.parse(["alpha", "bravo"])).toEqual(["alpha", "bravo", "fallback"]);
|
|
334
|
+
expect(schema.safeParse(["alpha", undefined]).success).toBe(false);
|
|
335
|
+
|
|
336
|
+
// With no later required output slot, exact optional still behaves like an
|
|
337
|
+
// omitted tuple tail and truncates cleanly.
|
|
338
|
+
expect(z.tuple([z.string(), z.string().exactOptional(), z.string().optional()]).parse(["alpha"])).toEqual(["alpha"]);
|
|
322
339
|
});
|
|
323
340
|
|
|
324
341
|
test("tuple preserves explicit undefined inside input even for optional-out schemas", () => {
|
package/src/v4/core/api.ts
CHANGED
|
@@ -1207,17 +1207,19 @@ export function _xor<const T extends readonly schemas.$ZodObject[]>(
|
|
|
1207
1207
|
}
|
|
1208
1208
|
|
|
1209
1209
|
// ZodDiscriminatedUnion
|
|
1210
|
-
export interface $ZodTypeDiscriminableInternals extends
|
|
1210
|
+
export interface $ZodTypeDiscriminableInternals<Disc extends string = string>
|
|
1211
|
+
extends schemas.$ZodTypeInternals<unknown, { [K in Disc]?: unknown }> {
|
|
1211
1212
|
propValues: util.PropValues;
|
|
1212
1213
|
}
|
|
1213
1214
|
|
|
1214
|
-
export interface $ZodTypeDiscriminable extends schemas.$ZodType {
|
|
1215
|
-
_zod: $ZodTypeDiscriminableInternals
|
|
1215
|
+
export interface $ZodTypeDiscriminable<Disc extends string = string> extends schemas.$ZodType {
|
|
1216
|
+
_zod: $ZodTypeDiscriminableInternals<Disc>;
|
|
1216
1217
|
}
|
|
1218
|
+
|
|
1217
1219
|
export type $ZodDiscriminatedUnionParams = TypeParams<schemas.$ZodDiscriminatedUnion, "options" | "discriminator">;
|
|
1218
1220
|
// @__NO_SIDE_EFFECTS__
|
|
1219
1221
|
export function _discriminatedUnion<
|
|
1220
|
-
Types extends [$ZodTypeDiscriminable
|
|
1222
|
+
Types extends [$ZodTypeDiscriminable<Disc>, ...$ZodTypeDiscriminable<Disc>[]],
|
|
1221
1223
|
Disc extends string,
|
|
1222
1224
|
>(
|
|
1223
1225
|
Class: util.SchemaClass<schemas.$ZodDiscriminatedUnion>,
|
|
@@ -525,7 +525,8 @@ export const catchProcessor: Processor<schemas.$ZodCatch> = (schema, ctx, json,
|
|
|
525
525
|
|
|
526
526
|
export const pipeProcessor: Processor<schemas.$ZodPipe> = (schema, ctx, _json, params) => {
|
|
527
527
|
const def = schema._zod.def as schemas.$ZodPipeDef;
|
|
528
|
-
const
|
|
528
|
+
const inIsTransform = def.in._zod.traits.has("$ZodTransform");
|
|
529
|
+
const innerType = ctx.io === "input" ? (inIsTransform ? def.out : def.in) : def.out;
|
|
529
530
|
process(innerType, ctx as any, params);
|
|
530
531
|
const seen = ctx.seen.get(schema)!;
|
|
531
532
|
seen.ref = innerType;
|
package/src/v4/core/schemas.ts
CHANGED
|
@@ -2677,14 +2677,14 @@ export const $ZodTuple: core.$constructor<$ZodTuple> = /*@__PURE__*/ core.$const
|
|
|
2677
2677
|
payload.value = [];
|
|
2678
2678
|
const proms: Promise<any>[] = [];
|
|
2679
2679
|
|
|
2680
|
-
const
|
|
2681
|
-
const
|
|
2680
|
+
const optinStart = getTupleOptStart(items, "optin");
|
|
2681
|
+
const optoutStart = getTupleOptStart(items, "optout");
|
|
2682
2682
|
|
|
2683
2683
|
if (!def.rest) {
|
|
2684
|
-
if (input.length <
|
|
2684
|
+
if (input.length < optinStart) {
|
|
2685
2685
|
payload.issues.push({
|
|
2686
2686
|
code: "too_small",
|
|
2687
|
-
minimum:
|
|
2687
|
+
minimum: optinStart,
|
|
2688
2688
|
inclusive: true,
|
|
2689
2689
|
input,
|
|
2690
2690
|
inst,
|
|
@@ -2706,9 +2706,8 @@ export const $ZodTuple: core.$constructor<$ZodTuple> = /*@__PURE__*/ core.$const
|
|
|
2706
2706
|
|
|
2707
2707
|
// Run every item in parallel, collecting results into an indexed
|
|
2708
2708
|
// array. The post-processing in `handleTupleResults` walks them in
|
|
2709
|
-
// order so it can
|
|
2710
|
-
//
|
|
2711
|
-
// any later defaults must NOT fire.
|
|
2709
|
+
// order so it can decide whether an absent optional-output error can
|
|
2710
|
+
// truncate the tail or must be reported to preserve required output.
|
|
2712
2711
|
const itemResults: ParsePayload[] = new Array(items.length);
|
|
2713
2712
|
for (let i = 0; i < items.length; i++) {
|
|
2714
2713
|
const r = items[i]._zod.run({ value: input[i], issues: [] }, ctx);
|
|
@@ -2737,11 +2736,20 @@ export const $ZodTuple: core.$constructor<$ZodTuple> = /*@__PURE__*/ core.$const
|
|
|
2737
2736
|
}
|
|
2738
2737
|
}
|
|
2739
2738
|
|
|
2740
|
-
if (proms.length)
|
|
2741
|
-
|
|
2739
|
+
if (proms.length) {
|
|
2740
|
+
return Promise.all(proms).then(() => handleTupleResults(itemResults, payload, items, input, optoutStart));
|
|
2741
|
+
}
|
|
2742
|
+
return handleTupleResults(itemResults, payload, items, input, optoutStart);
|
|
2742
2743
|
};
|
|
2743
2744
|
});
|
|
2744
2745
|
|
|
2746
|
+
function getTupleOptStart(items: readonly $ZodType[], key: "optin" | "optout") {
|
|
2747
|
+
for (let i = items.length - 1; i >= 0; i--) {
|
|
2748
|
+
if (items[i]._zod[key] !== "optional") return i + 1;
|
|
2749
|
+
}
|
|
2750
|
+
return 0;
|
|
2751
|
+
}
|
|
2752
|
+
|
|
2745
2753
|
function handleTupleResult(result: ParsePayload, final: ParsePayload<any[]>, index: number) {
|
|
2746
2754
|
if (result.issues.length) {
|
|
2747
2755
|
final.issues.push(...util.prefixIssues(index, result.issues));
|
|
@@ -2749,30 +2757,21 @@ function handleTupleResult(result: ParsePayload, final: ParsePayload<any[]>, ind
|
|
|
2749
2757
|
final.value[index] = result.value;
|
|
2750
2758
|
}
|
|
2751
2759
|
|
|
2752
|
-
// Post-processes the per-item results collected by the tuple parser.
|
|
2753
|
-
// `optStart` is intentionally NOT consulted here — it's an input-length
|
|
2754
|
-
// concern handled by the `too_small` precheck at the top of parse. This
|
|
2755
|
-
// step is purely about output shaping, which is governed by `optout`:
|
|
2756
|
-
// a `.default()` tail item sits inside the optStart region (its `optin`
|
|
2757
|
-
// is optional), but it must NOT be dropped or have its errors swallowed
|
|
2758
|
-
// because it materializes a defined value (`optout !== "optional"`).
|
|
2759
2760
|
function handleTupleResults(
|
|
2760
2761
|
itemResults: ParsePayload[],
|
|
2761
2762
|
final: ParsePayload<any[]>,
|
|
2762
2763
|
items: readonly $ZodType[],
|
|
2763
|
-
input: unknown[]
|
|
2764
|
+
input: unknown[],
|
|
2765
|
+
optoutStart: number
|
|
2764
2766
|
) {
|
|
2765
2767
|
// Walk results in order. Mirror $ZodObject's swallow-on-absent-optional
|
|
2766
|
-
// rule, but
|
|
2767
|
-
//
|
|
2768
|
-
// so we truncate the result there and stop processing — including
|
|
2769
|
-
// skipping any later defaults.
|
|
2768
|
+
// rule, but only after `optoutStart`: the first index where the output
|
|
2769
|
+
// tuple tail can be absent.
|
|
2770
2770
|
for (let i = 0; i < items.length; i++) {
|
|
2771
2771
|
const r = itemResults[i];
|
|
2772
|
-
const isOptionalOut = items[i]._zod.optout === "optional";
|
|
2773
2772
|
const isPresent = i < input.length;
|
|
2774
2773
|
if (r.issues.length) {
|
|
2775
|
-
if (
|
|
2774
|
+
if (!isPresent && i >= optoutStart) {
|
|
2776
2775
|
final.value.length = i;
|
|
2777
2776
|
break;
|
|
2778
2777
|
}
|
|
@@ -4119,6 +4118,37 @@ function handleCodecTxResult(left: ParsePayload, value: any, nextSchema: SomeTyp
|
|
|
4119
4118
|
return nextSchema._zod.run({ value, issues: left.issues }, ctx);
|
|
4120
4119
|
}
|
|
4121
4120
|
|
|
4121
|
+
/////////////////////////////////////////////////
|
|
4122
|
+
/////////////////////////////////////////////////
|
|
4123
|
+
////////// //////////
|
|
4124
|
+
////////// $ZodPreprocess //////////
|
|
4125
|
+
////////// //////////
|
|
4126
|
+
/////////////////////////////////////////////////
|
|
4127
|
+
/////////////////////////////////////////////////
|
|
4128
|
+
export interface $ZodPreprocessDef<B extends SomeType = $ZodType> extends $ZodPipeDef<$ZodTransform, B> {
|
|
4129
|
+
in: $ZodTransform;
|
|
4130
|
+
out: B;
|
|
4131
|
+
}
|
|
4132
|
+
|
|
4133
|
+
export interface $ZodPreprocessInternals<B extends SomeType = $ZodType> extends $ZodPipeInternals<$ZodTransform, B> {
|
|
4134
|
+
def: $ZodPreprocessDef<B>;
|
|
4135
|
+
optin: B["_zod"]["optin"];
|
|
4136
|
+
optout: B["_zod"]["optout"];
|
|
4137
|
+
}
|
|
4138
|
+
|
|
4139
|
+
export interface $ZodPreprocess<B extends SomeType = $ZodType> extends $ZodPipe<$ZodTransform, B> {
|
|
4140
|
+
_zod: $ZodPreprocessInternals<B>;
|
|
4141
|
+
}
|
|
4142
|
+
|
|
4143
|
+
export const $ZodPreprocess: core.$constructor<$ZodPreprocess> = /*@__PURE__*/ core.$constructor(
|
|
4144
|
+
"$ZodPreprocess",
|
|
4145
|
+
(inst, def) => {
|
|
4146
|
+
$ZodPipe.init(inst, def);
|
|
4147
|
+
util.defineLazy(inst._zod, "optin", () => def.out._zod.optin);
|
|
4148
|
+
util.defineLazy(inst._zod, "optout", () => def.out._zod.optout);
|
|
4149
|
+
}
|
|
4150
|
+
);
|
|
4151
|
+
|
|
4122
4152
|
////////////////////////////////////////////
|
|
4123
4153
|
////////////////////////////////////////////
|
|
4124
4154
|
////////// //////////
|
|
@@ -561,6 +561,7 @@ function isTransforming(
|
|
|
561
561
|
return isTransforming(def.keyType, ctx) || isTransforming(def.valueType, ctx);
|
|
562
562
|
}
|
|
563
563
|
if (def.type === "pipe") {
|
|
564
|
+
if (_schema._zod.traits.has("$ZodCodec")) return true;
|
|
564
565
|
return isTransforming(def.in, ctx) || isTransforming(def.out, ctx);
|
|
565
566
|
}
|
|
566
567
|
|
package/src/v4/core/versions.ts
CHANGED
package/src/v4/mini/schemas.ts
CHANGED
|
@@ -1083,7 +1083,7 @@ export const ZodMiniDiscriminatedUnion: core.$constructor<ZodMiniDiscriminatedUn
|
|
|
1083
1083
|
|
|
1084
1084
|
// @__NO_SIDE_EFFECTS__
|
|
1085
1085
|
export function discriminatedUnion<
|
|
1086
|
-
Types extends readonly [core.$ZodTypeDiscriminable
|
|
1086
|
+
Types extends readonly [core.$ZodTypeDiscriminable<Disc>, ...core.$ZodTypeDiscriminable<Disc>[]],
|
|
1087
1087
|
Disc extends string,
|
|
1088
1088
|
>(
|
|
1089
1089
|
discriminator: Disc,
|
|
@@ -247,6 +247,11 @@ test("z.union([]) / z.xor([]) / z.discriminatedUnion(_, []) construct and reject
|
|
|
247
247
|
}
|
|
248
248
|
});
|
|
249
249
|
|
|
250
|
+
test("z.discriminatedUnion rejects object options missing the discriminator at type level", () => {
|
|
251
|
+
// @ts-expect-error missing discriminator property
|
|
252
|
+
z.discriminatedUnion("type", [z.object({ value: z.string() })]);
|
|
253
|
+
});
|
|
254
|
+
|
|
250
255
|
test("z.intersection", () => {
|
|
251
256
|
const a = z.intersection(z.object({ a: z.string() }), z.object({ b: z.number() }));
|
|
252
257
|
expect(z.parse(a, { a: "hello", b: 123 })).toEqual({ a: "hello", b: 123 });
|
package/v4/classic/schemas.cjs
CHANGED
|
@@ -24,7 +24,7 @@ var __importStar = (this && this.__importStar) || function (mod) {
|
|
|
24
24
|
};
|
|
25
25
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
26
26
|
exports.ZodLiteral = exports.ZodEnum = exports.ZodSet = exports.ZodMap = exports.ZodRecord = exports.ZodTuple = exports.ZodIntersection = exports.ZodDiscriminatedUnion = exports.ZodXor = exports.ZodUnion = exports.ZodObject = exports.ZodArray = exports.ZodDate = exports.ZodVoid = exports.ZodNever = exports.ZodUnknown = exports.ZodAny = exports.ZodNull = exports.ZodUndefined = exports.ZodSymbol = exports.ZodBigIntFormat = exports.ZodBigInt = exports.ZodBoolean = exports.ZodNumberFormat = exports.ZodNumber = exports.ZodCustomStringFormat = exports.ZodJWT = exports.ZodE164 = exports.ZodBase64URL = exports.ZodBase64 = exports.ZodCIDRv6 = exports.ZodCIDRv4 = exports.ZodIPv6 = exports.ZodMAC = exports.ZodIPv4 = exports.ZodKSUID = exports.ZodXID = exports.ZodULID = exports.ZodCUID2 = exports.ZodCUID = exports.ZodNanoID = exports.ZodEmoji = exports.ZodURL = exports.ZodUUID = exports.ZodGUID = exports.ZodEmail = exports.ZodStringFormat = exports.ZodString = exports._ZodString = exports.ZodType = void 0;
|
|
27
|
-
exports.stringbool = exports.meta = exports.describe = exports.ZodCustom = exports.ZodFunction = exports.ZodPromise = exports.ZodLazy = exports.ZodTemplateLiteral = exports.ZodReadonly = exports.ZodCodec = exports.ZodPipe = exports.ZodNaN = exports.ZodCatch = exports.ZodSuccess = exports.ZodNonOptional = exports.ZodPrefault = exports.ZodDefault = exports.ZodNullable = exports.ZodExactOptional = exports.ZodOptional = exports.ZodTransform = exports.ZodFile = void 0;
|
|
27
|
+
exports.stringbool = exports.meta = exports.describe = exports.ZodCustom = exports.ZodFunction = exports.ZodPromise = exports.ZodLazy = exports.ZodTemplateLiteral = exports.ZodReadonly = exports.ZodPreprocess = exports.ZodCodec = exports.ZodPipe = exports.ZodNaN = exports.ZodCatch = exports.ZodSuccess = exports.ZodNonOptional = exports.ZodPrefault = exports.ZodDefault = exports.ZodNullable = exports.ZodExactOptional = exports.ZodOptional = exports.ZodTransform = exports.ZodFile = void 0;
|
|
28
28
|
exports.string = string;
|
|
29
29
|
exports.email = email;
|
|
30
30
|
exports.guid = guid;
|
|
@@ -1372,6 +1372,10 @@ function invertCodec(codec) {
|
|
|
1372
1372
|
reverseTransform: def.transform,
|
|
1373
1373
|
});
|
|
1374
1374
|
}
|
|
1375
|
+
exports.ZodPreprocess = core.$constructor("ZodPreprocess", (inst, def) => {
|
|
1376
|
+
exports.ZodPipe.init(inst, def);
|
|
1377
|
+
core.$ZodPreprocess.init(inst, def);
|
|
1378
|
+
});
|
|
1375
1379
|
exports.ZodReadonly = core.$constructor("ZodReadonly", (inst, def) => {
|
|
1376
1380
|
core.$ZodReadonly.init(inst, def);
|
|
1377
1381
|
exports.ZodType.init(inst, def);
|
|
@@ -1497,5 +1501,9 @@ function json(params) {
|
|
|
1497
1501
|
}
|
|
1498
1502
|
// preprocess
|
|
1499
1503
|
function preprocess(fn, schema) {
|
|
1500
|
-
return
|
|
1504
|
+
return new exports.ZodPreprocess({
|
|
1505
|
+
type: "pipe",
|
|
1506
|
+
in: transform(fn),
|
|
1507
|
+
out: schema,
|
|
1508
|
+
});
|
|
1501
1509
|
}
|
package/v4/classic/schemas.d.cts
CHANGED
|
@@ -511,7 +511,7 @@ export interface ZodDiscriminatedUnion<Options extends readonly core.SomeType[]
|
|
|
511
511
|
def: core.$ZodDiscriminatedUnionDef<Options, Disc>;
|
|
512
512
|
}
|
|
513
513
|
export declare const ZodDiscriminatedUnion: core.$constructor<ZodDiscriminatedUnion>;
|
|
514
|
-
export declare function discriminatedUnion<Types extends readonly [core.$ZodTypeDiscriminable
|
|
514
|
+
export declare function discriminatedUnion<Types extends readonly [core.$ZodTypeDiscriminable<Disc>, ...core.$ZodTypeDiscriminable<Disc>[]], Disc extends string>(discriminator: Disc, options: Types, params?: string | core.$ZodDiscriminatedUnionParams): ZodDiscriminatedUnion<Types, Disc>;
|
|
515
515
|
export interface ZodIntersection<A extends core.SomeType = core.$ZodType, B extends core.SomeType = core.$ZodType> extends _ZodType<core.$ZodIntersectionInternals<A, B>>, core.$ZodIntersection<A, B> {
|
|
516
516
|
"~standard": ZodStandardSchemaWithJSON<this>;
|
|
517
517
|
}
|
|
@@ -674,6 +674,12 @@ export declare function codec<const A extends core.SomeType, B extends core.Some
|
|
|
674
674
|
encode: (value: core.input<B>, payload: core.ParsePayload<core.input<B>>) => core.util.MaybeAsync<core.output<A>>;
|
|
675
675
|
}): ZodCodec<A, B>;
|
|
676
676
|
export declare function invertCodec<A extends core.SomeType, B extends core.SomeType>(codec: ZodCodec<A, B>): ZodCodec<B, A>;
|
|
677
|
+
export interface ZodPreprocess<B extends core.SomeType = core.$ZodType> extends ZodPipe<core.$ZodTransform, B>, core.$ZodPreprocess<B> {
|
|
678
|
+
"~standard": ZodStandardSchemaWithJSON<this>;
|
|
679
|
+
_zod: core.$ZodPreprocessInternals<B>;
|
|
680
|
+
def: core.$ZodPreprocessDef<B>;
|
|
681
|
+
}
|
|
682
|
+
export declare const ZodPreprocess: core.$constructor<ZodPreprocess>;
|
|
677
683
|
export interface ZodReadonly<T extends core.SomeType = core.$ZodType> extends _ZodType<core.$ZodReadonlyInternals<T>>, core.$ZodReadonly<T> {
|
|
678
684
|
"~standard": ZodStandardSchemaWithJSON<this>;
|
|
679
685
|
unwrap(): T;
|
|
@@ -758,4 +764,4 @@ export interface ZodJSONSchema extends _ZodJSONSchema {
|
|
|
758
764
|
_zod: ZodJSONSchemaInternals;
|
|
759
765
|
}
|
|
760
766
|
export declare function json(params?: string | core.$ZodCustomParams): ZodJSONSchema;
|
|
761
|
-
export declare function preprocess<A, U extends core.SomeType, B = unknown>(fn: (arg: B, ctx: core.$RefinementCtx) => A, schema: U):
|
|
767
|
+
export declare function preprocess<A, U extends core.SomeType, B = unknown>(fn: (arg: B, ctx: core.$RefinementCtx) => A, schema: U): ZodPreprocess<U>;
|
package/v4/classic/schemas.d.ts
CHANGED
|
@@ -511,7 +511,7 @@ export interface ZodDiscriminatedUnion<Options extends readonly core.SomeType[]
|
|
|
511
511
|
def: core.$ZodDiscriminatedUnionDef<Options, Disc>;
|
|
512
512
|
}
|
|
513
513
|
export declare const ZodDiscriminatedUnion: core.$constructor<ZodDiscriminatedUnion>;
|
|
514
|
-
export declare function discriminatedUnion<Types extends readonly [core.$ZodTypeDiscriminable
|
|
514
|
+
export declare function discriminatedUnion<Types extends readonly [core.$ZodTypeDiscriminable<Disc>, ...core.$ZodTypeDiscriminable<Disc>[]], Disc extends string>(discriminator: Disc, options: Types, params?: string | core.$ZodDiscriminatedUnionParams): ZodDiscriminatedUnion<Types, Disc>;
|
|
515
515
|
export interface ZodIntersection<A extends core.SomeType = core.$ZodType, B extends core.SomeType = core.$ZodType> extends _ZodType<core.$ZodIntersectionInternals<A, B>>, core.$ZodIntersection<A, B> {
|
|
516
516
|
"~standard": ZodStandardSchemaWithJSON<this>;
|
|
517
517
|
}
|
|
@@ -674,6 +674,12 @@ export declare function codec<const A extends core.SomeType, B extends core.Some
|
|
|
674
674
|
encode: (value: core.input<B>, payload: core.ParsePayload<core.input<B>>) => core.util.MaybeAsync<core.output<A>>;
|
|
675
675
|
}): ZodCodec<A, B>;
|
|
676
676
|
export declare function invertCodec<A extends core.SomeType, B extends core.SomeType>(codec: ZodCodec<A, B>): ZodCodec<B, A>;
|
|
677
|
+
export interface ZodPreprocess<B extends core.SomeType = core.$ZodType> extends ZodPipe<core.$ZodTransform, B>, core.$ZodPreprocess<B> {
|
|
678
|
+
"~standard": ZodStandardSchemaWithJSON<this>;
|
|
679
|
+
_zod: core.$ZodPreprocessInternals<B>;
|
|
680
|
+
def: core.$ZodPreprocessDef<B>;
|
|
681
|
+
}
|
|
682
|
+
export declare const ZodPreprocess: core.$constructor<ZodPreprocess>;
|
|
677
683
|
export interface ZodReadonly<T extends core.SomeType = core.$ZodType> extends _ZodType<core.$ZodReadonlyInternals<T>>, core.$ZodReadonly<T> {
|
|
678
684
|
"~standard": ZodStandardSchemaWithJSON<this>;
|
|
679
685
|
unwrap(): T;
|
|
@@ -758,4 +764,4 @@ export interface ZodJSONSchema extends _ZodJSONSchema {
|
|
|
758
764
|
_zod: ZodJSONSchemaInternals;
|
|
759
765
|
}
|
|
760
766
|
export declare function json(params?: string | core.$ZodCustomParams): ZodJSONSchema;
|
|
761
|
-
export declare function preprocess<A, U extends core.SomeType, B = unknown>(fn: (arg: B, ctx: core.$RefinementCtx) => A, schema: U):
|
|
767
|
+
export declare function preprocess<A, U extends core.SomeType, B = unknown>(fn: (arg: B, ctx: core.$RefinementCtx) => A, schema: U): ZodPreprocess<U>;
|
package/v4/classic/schemas.js
CHANGED
|
@@ -1255,6 +1255,10 @@ export function invertCodec(codec) {
|
|
|
1255
1255
|
reverseTransform: def.transform,
|
|
1256
1256
|
});
|
|
1257
1257
|
}
|
|
1258
|
+
export const ZodPreprocess = /*@__PURE__*/ core.$constructor("ZodPreprocess", (inst, def) => {
|
|
1259
|
+
ZodPipe.init(inst, def);
|
|
1260
|
+
core.$ZodPreprocess.init(inst, def);
|
|
1261
|
+
});
|
|
1258
1262
|
export const ZodReadonly = /*@__PURE__*/ core.$constructor("ZodReadonly", (inst, def) => {
|
|
1259
1263
|
core.$ZodReadonly.init(inst, def);
|
|
1260
1264
|
ZodType.init(inst, def);
|
|
@@ -1381,5 +1385,9 @@ export function json(params) {
|
|
|
1381
1385
|
}
|
|
1382
1386
|
// preprocess
|
|
1383
1387
|
export function preprocess(fn, schema) {
|
|
1384
|
-
return
|
|
1388
|
+
return new ZodPreprocess({
|
|
1389
|
+
type: "pipe",
|
|
1390
|
+
in: transform(fn),
|
|
1391
|
+
out: schema,
|
|
1392
|
+
});
|
|
1385
1393
|
}
|
package/v4/core/api.d.cts
CHANGED
|
@@ -225,14 +225,16 @@ export type $ZodUnionParams = TypeParams<schemas.$ZodUnion, "options">;
|
|
|
225
225
|
export declare function _union<const T extends readonly schemas.$ZodObject[]>(Class: util.SchemaClass<schemas.$ZodUnion>, options: T, params?: string | $ZodUnionParams): schemas.$ZodUnion<T>;
|
|
226
226
|
export type $ZodXorParams = TypeParams<schemas.$ZodXor, "options">;
|
|
227
227
|
export declare function _xor<const T extends readonly schemas.$ZodObject[]>(Class: util.SchemaClass<schemas.$ZodXor>, options: T, params?: string | $ZodXorParams): schemas.$ZodXor<T>;
|
|
228
|
-
export interface $ZodTypeDiscriminableInternals extends schemas.$ZodTypeInternals {
|
|
228
|
+
export interface $ZodTypeDiscriminableInternals<Disc extends string = string> extends schemas.$ZodTypeInternals<unknown, {
|
|
229
|
+
[K in Disc]?: unknown;
|
|
230
|
+
}> {
|
|
229
231
|
propValues: util.PropValues;
|
|
230
232
|
}
|
|
231
|
-
export interface $ZodTypeDiscriminable extends schemas.$ZodType {
|
|
232
|
-
_zod: $ZodTypeDiscriminableInternals
|
|
233
|
+
export interface $ZodTypeDiscriminable<Disc extends string = string> extends schemas.$ZodType {
|
|
234
|
+
_zod: $ZodTypeDiscriminableInternals<Disc>;
|
|
233
235
|
}
|
|
234
236
|
export type $ZodDiscriminatedUnionParams = TypeParams<schemas.$ZodDiscriminatedUnion, "options" | "discriminator">;
|
|
235
|
-
export declare function _discriminatedUnion<Types extends [$ZodTypeDiscriminable
|
|
237
|
+
export declare function _discriminatedUnion<Types extends [$ZodTypeDiscriminable<Disc>, ...$ZodTypeDiscriminable<Disc>[]], Disc extends string>(Class: util.SchemaClass<schemas.$ZodDiscriminatedUnion>, discriminator: Disc, options: Types, params?: string | $ZodDiscriminatedUnionParams): schemas.$ZodDiscriminatedUnion<Types, Disc>;
|
|
236
238
|
export type $ZodIntersectionParams = TypeParams<schemas.$ZodIntersection, "left" | "right">;
|
|
237
239
|
export declare function _intersection<T extends schemas.$ZodObject, U extends schemas.$ZodObject>(Class: util.SchemaClass<schemas.$ZodIntersection>, left: T, right: U): schemas.$ZodIntersection<T, U>;
|
|
238
240
|
export type $ZodTupleParams = TypeParams<schemas.$ZodTuple, "items" | "rest">;
|
package/v4/core/api.d.ts
CHANGED
|
@@ -225,14 +225,16 @@ export type $ZodUnionParams = TypeParams<schemas.$ZodUnion, "options">;
|
|
|
225
225
|
export declare function _union<const T extends readonly schemas.$ZodObject[]>(Class: util.SchemaClass<schemas.$ZodUnion>, options: T, params?: string | $ZodUnionParams): schemas.$ZodUnion<T>;
|
|
226
226
|
export type $ZodXorParams = TypeParams<schemas.$ZodXor, "options">;
|
|
227
227
|
export declare function _xor<const T extends readonly schemas.$ZodObject[]>(Class: util.SchemaClass<schemas.$ZodXor>, options: T, params?: string | $ZodXorParams): schemas.$ZodXor<T>;
|
|
228
|
-
export interface $ZodTypeDiscriminableInternals extends schemas.$ZodTypeInternals {
|
|
228
|
+
export interface $ZodTypeDiscriminableInternals<Disc extends string = string> extends schemas.$ZodTypeInternals<unknown, {
|
|
229
|
+
[K in Disc]?: unknown;
|
|
230
|
+
}> {
|
|
229
231
|
propValues: util.PropValues;
|
|
230
232
|
}
|
|
231
|
-
export interface $ZodTypeDiscriminable extends schemas.$ZodType {
|
|
232
|
-
_zod: $ZodTypeDiscriminableInternals
|
|
233
|
+
export interface $ZodTypeDiscriminable<Disc extends string = string> extends schemas.$ZodType {
|
|
234
|
+
_zod: $ZodTypeDiscriminableInternals<Disc>;
|
|
233
235
|
}
|
|
234
236
|
export type $ZodDiscriminatedUnionParams = TypeParams<schemas.$ZodDiscriminatedUnion, "options" | "discriminator">;
|
|
235
|
-
export declare function _discriminatedUnion<Types extends [$ZodTypeDiscriminable
|
|
237
|
+
export declare function _discriminatedUnion<Types extends [$ZodTypeDiscriminable<Disc>, ...$ZodTypeDiscriminable<Disc>[]], Disc extends string>(Class: util.SchemaClass<schemas.$ZodDiscriminatedUnion>, discriminator: Disc, options: Types, params?: string | $ZodDiscriminatedUnionParams): schemas.$ZodDiscriminatedUnion<Types, Disc>;
|
|
236
238
|
export type $ZodIntersectionParams = TypeParams<schemas.$ZodIntersection, "left" | "right">;
|
|
237
239
|
export declare function _intersection<T extends schemas.$ZodObject, U extends schemas.$ZodObject>(Class: util.SchemaClass<schemas.$ZodIntersection>, left: T, right: U): schemas.$ZodIntersection<T, U>;
|
|
238
240
|
export type $ZodTupleParams = TypeParams<schemas.$ZodTuple, "items" | "rest">;
|
|
@@ -525,7 +525,8 @@ const catchProcessor = (schema, ctx, json, params) => {
|
|
|
525
525
|
exports.catchProcessor = catchProcessor;
|
|
526
526
|
const pipeProcessor = (schema, ctx, _json, params) => {
|
|
527
527
|
const def = schema._zod.def;
|
|
528
|
-
const
|
|
528
|
+
const inIsTransform = def.in._zod.traits.has("$ZodTransform");
|
|
529
|
+
const innerType = ctx.io === "input" ? (inIsTransform ? def.out : def.in) : def.out;
|
|
529
530
|
(0, to_json_schema_js_1.process)(innerType, ctx, params);
|
|
530
531
|
const seen = ctx.seen.get(schema);
|
|
531
532
|
seen.ref = innerType;
|
|
@@ -487,7 +487,8 @@ export const catchProcessor = (schema, ctx, json, params) => {
|
|
|
487
487
|
};
|
|
488
488
|
export const pipeProcessor = (schema, ctx, _json, params) => {
|
|
489
489
|
const def = schema._zod.def;
|
|
490
|
-
const
|
|
490
|
+
const inIsTransform = def.in._zod.traits.has("$ZodTransform");
|
|
491
|
+
const innerType = ctx.io === "input" ? (inIsTransform ? def.out : def.in) : def.out;
|
|
491
492
|
process(innerType, ctx, params);
|
|
492
493
|
const seen = ctx.seen.get(schema);
|
|
493
494
|
seen.ref = innerType;
|
package/v4/core/schemas.cjs
CHANGED
|
@@ -24,7 +24,7 @@ var __importStar = (this && this.__importStar) || function (mod) {
|
|
|
24
24
|
};
|
|
25
25
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
26
26
|
exports.$ZodTuple = exports.$ZodIntersection = exports.$ZodDiscriminatedUnion = exports.$ZodXor = exports.$ZodUnion = exports.$ZodObjectJIT = exports.$ZodObject = exports.$ZodArray = exports.$ZodDate = exports.$ZodVoid = exports.$ZodNever = exports.$ZodUnknown = exports.$ZodAny = exports.$ZodNull = exports.$ZodUndefined = exports.$ZodSymbol = exports.$ZodBigIntFormat = exports.$ZodBigInt = exports.$ZodBoolean = exports.$ZodNumberFormat = exports.$ZodNumber = exports.$ZodCustomStringFormat = exports.$ZodJWT = exports.$ZodE164 = exports.$ZodBase64URL = exports.$ZodBase64 = exports.$ZodCIDRv6 = exports.$ZodCIDRv4 = exports.$ZodMAC = exports.$ZodIPv6 = exports.$ZodIPv4 = exports.$ZodISODuration = exports.$ZodISOTime = exports.$ZodISODate = exports.$ZodISODateTime = exports.$ZodKSUID = exports.$ZodXID = exports.$ZodULID = exports.$ZodCUID2 = exports.$ZodCUID = exports.$ZodNanoID = exports.$ZodEmoji = exports.$ZodURL = exports.$ZodEmail = exports.$ZodUUID = exports.$ZodGUID = exports.$ZodStringFormat = exports.$ZodString = exports.clone = exports.$ZodType = void 0;
|
|
27
|
-
exports.$ZodCustom = exports.$ZodLazy = exports.$ZodPromise = exports.$ZodFunction = exports.$ZodTemplateLiteral = exports.$ZodReadonly = exports.$ZodCodec = exports.$ZodPipe = exports.$ZodNaN = exports.$ZodCatch = exports.$ZodSuccess = exports.$ZodNonOptional = exports.$ZodPrefault = exports.$ZodDefault = exports.$ZodNullable = exports.$ZodExactOptional = exports.$ZodOptional = exports.$ZodTransform = exports.$ZodFile = exports.$ZodLiteral = exports.$ZodEnum = exports.$ZodSet = exports.$ZodMap = exports.$ZodRecord = void 0;
|
|
27
|
+
exports.$ZodCustom = exports.$ZodLazy = exports.$ZodPromise = exports.$ZodFunction = exports.$ZodTemplateLiteral = exports.$ZodReadonly = exports.$ZodPreprocess = exports.$ZodCodec = exports.$ZodPipe = exports.$ZodNaN = exports.$ZodCatch = exports.$ZodSuccess = exports.$ZodNonOptional = exports.$ZodPrefault = exports.$ZodDefault = exports.$ZodNullable = exports.$ZodExactOptional = exports.$ZodOptional = exports.$ZodTransform = exports.$ZodFile = exports.$ZodLiteral = exports.$ZodEnum = exports.$ZodSet = exports.$ZodMap = exports.$ZodRecord = void 0;
|
|
28
28
|
exports.isValidBase64 = isValidBase64;
|
|
29
29
|
exports.isValidBase64URL = isValidBase64URL;
|
|
30
30
|
exports.isValidJWT = isValidJWT;
|
|
@@ -1344,13 +1344,13 @@ exports.$ZodTuple = core.$constructor("$ZodTuple", (inst, def) => {
|
|
|
1344
1344
|
}
|
|
1345
1345
|
payload.value = [];
|
|
1346
1346
|
const proms = [];
|
|
1347
|
-
const
|
|
1348
|
-
const
|
|
1347
|
+
const optinStart = getTupleOptStart(items, "optin");
|
|
1348
|
+
const optoutStart = getTupleOptStart(items, "optout");
|
|
1349
1349
|
if (!def.rest) {
|
|
1350
|
-
if (input.length <
|
|
1350
|
+
if (input.length < optinStart) {
|
|
1351
1351
|
payload.issues.push({
|
|
1352
1352
|
code: "too_small",
|
|
1353
|
-
minimum:
|
|
1353
|
+
minimum: optinStart,
|
|
1354
1354
|
inclusive: true,
|
|
1355
1355
|
input,
|
|
1356
1356
|
inst,
|
|
@@ -1371,9 +1371,8 @@ exports.$ZodTuple = core.$constructor("$ZodTuple", (inst, def) => {
|
|
|
1371
1371
|
}
|
|
1372
1372
|
// Run every item in parallel, collecting results into an indexed
|
|
1373
1373
|
// array. The post-processing in `handleTupleResults` walks them in
|
|
1374
|
-
// order so it can
|
|
1375
|
-
//
|
|
1376
|
-
// any later defaults must NOT fire.
|
|
1374
|
+
// order so it can decide whether an absent optional-output error can
|
|
1375
|
+
// truncate the tail or must be reported to preserve required output.
|
|
1377
1376
|
const itemResults = new Array(items.length);
|
|
1378
1377
|
for (let i = 0; i < items.length; i++) {
|
|
1379
1378
|
const r = items[i]._zod.run({ value: input[i], issues: [] }, ctx);
|
|
@@ -1400,36 +1399,34 @@ exports.$ZodTuple = core.$constructor("$ZodTuple", (inst, def) => {
|
|
|
1400
1399
|
}
|
|
1401
1400
|
}
|
|
1402
1401
|
}
|
|
1403
|
-
if (proms.length)
|
|
1404
|
-
return Promise.all(proms).then(() => handleTupleResults(itemResults, payload, items, input));
|
|
1405
|
-
|
|
1402
|
+
if (proms.length) {
|
|
1403
|
+
return Promise.all(proms).then(() => handleTupleResults(itemResults, payload, items, input, optoutStart));
|
|
1404
|
+
}
|
|
1405
|
+
return handleTupleResults(itemResults, payload, items, input, optoutStart);
|
|
1406
1406
|
};
|
|
1407
1407
|
});
|
|
1408
|
+
function getTupleOptStart(items, key) {
|
|
1409
|
+
for (let i = items.length - 1; i >= 0; i--) {
|
|
1410
|
+
if (items[i]._zod[key] !== "optional")
|
|
1411
|
+
return i + 1;
|
|
1412
|
+
}
|
|
1413
|
+
return 0;
|
|
1414
|
+
}
|
|
1408
1415
|
function handleTupleResult(result, final, index) {
|
|
1409
1416
|
if (result.issues.length) {
|
|
1410
1417
|
final.issues.push(...util.prefixIssues(index, result.issues));
|
|
1411
1418
|
}
|
|
1412
1419
|
final.value[index] = result.value;
|
|
1413
1420
|
}
|
|
1414
|
-
|
|
1415
|
-
// `optStart` is intentionally NOT consulted here — it's an input-length
|
|
1416
|
-
// concern handled by the `too_small` precheck at the top of parse. This
|
|
1417
|
-
// step is purely about output shaping, which is governed by `optout`:
|
|
1418
|
-
// a `.default()` tail item sits inside the optStart region (its `optin`
|
|
1419
|
-
// is optional), but it must NOT be dropped or have its errors swallowed
|
|
1420
|
-
// because it materializes a defined value (`optout !== "optional"`).
|
|
1421
|
-
function handleTupleResults(itemResults, final, items, input) {
|
|
1421
|
+
function handleTupleResults(itemResults, final, items, input, optoutStart) {
|
|
1422
1422
|
// Walk results in order. Mirror $ZodObject's swallow-on-absent-optional
|
|
1423
|
-
// rule, but
|
|
1424
|
-
//
|
|
1425
|
-
// so we truncate the result there and stop processing — including
|
|
1426
|
-
// skipping any later defaults.
|
|
1423
|
+
// rule, but only after `optoutStart`: the first index where the output
|
|
1424
|
+
// tuple tail can be absent.
|
|
1427
1425
|
for (let i = 0; i < items.length; i++) {
|
|
1428
1426
|
const r = itemResults[i];
|
|
1429
|
-
const isOptionalOut = items[i]._zod.optout === "optional";
|
|
1430
1427
|
const isPresent = i < input.length;
|
|
1431
1428
|
if (r.issues.length) {
|
|
1432
|
-
if (
|
|
1429
|
+
if (!isPresent && i >= optoutStart) {
|
|
1433
1430
|
final.value.length = i;
|
|
1434
1431
|
break;
|
|
1435
1432
|
}
|
|
@@ -2056,6 +2053,11 @@ function handleCodecTxResult(left, value, nextSchema, ctx) {
|
|
|
2056
2053
|
}
|
|
2057
2054
|
return nextSchema._zod.run({ value, issues: left.issues }, ctx);
|
|
2058
2055
|
}
|
|
2056
|
+
exports.$ZodPreprocess = core.$constructor("$ZodPreprocess", (inst, def) => {
|
|
2057
|
+
exports.$ZodPipe.init(inst, def);
|
|
2058
|
+
util.defineLazy(inst._zod, "optin", () => def.out._zod.optin);
|
|
2059
|
+
util.defineLazy(inst._zod, "optout", () => def.out._zod.optout);
|
|
2060
|
+
});
|
|
2059
2061
|
exports.$ZodReadonly = core.$constructor("$ZodReadonly", (inst, def) => {
|
|
2060
2062
|
exports.$ZodType.init(inst, def);
|
|
2061
2063
|
util.defineLazy(inst._zod, "propValues", () => def.innerType._zod.propValues);
|
package/v4/core/schemas.d.cts
CHANGED
|
@@ -1030,6 +1030,19 @@ export interface $ZodCodec<A extends SomeType = $ZodType, B extends SomeType = $
|
|
|
1030
1030
|
_zod: $ZodCodecInternals<A, B>;
|
|
1031
1031
|
}
|
|
1032
1032
|
export declare const $ZodCodec: core.$constructor<$ZodCodec>;
|
|
1033
|
+
export interface $ZodPreprocessDef<B extends SomeType = $ZodType> extends $ZodPipeDef<$ZodTransform, B> {
|
|
1034
|
+
in: $ZodTransform;
|
|
1035
|
+
out: B;
|
|
1036
|
+
}
|
|
1037
|
+
export interface $ZodPreprocessInternals<B extends SomeType = $ZodType> extends $ZodPipeInternals<$ZodTransform, B> {
|
|
1038
|
+
def: $ZodPreprocessDef<B>;
|
|
1039
|
+
optin: B["_zod"]["optin"];
|
|
1040
|
+
optout: B["_zod"]["optout"];
|
|
1041
|
+
}
|
|
1042
|
+
export interface $ZodPreprocess<B extends SomeType = $ZodType> extends $ZodPipe<$ZodTransform, B> {
|
|
1043
|
+
_zod: $ZodPreprocessInternals<B>;
|
|
1044
|
+
}
|
|
1045
|
+
export declare const $ZodPreprocess: core.$constructor<$ZodPreprocess>;
|
|
1033
1046
|
export interface $ZodReadonlyDef<T extends SomeType = $ZodType> extends $ZodTypeDef {
|
|
1034
1047
|
type: "readonly";
|
|
1035
1048
|
innerType: T;
|
package/v4/core/schemas.d.ts
CHANGED
|
@@ -1030,6 +1030,19 @@ export interface $ZodCodec<A extends SomeType = $ZodType, B extends SomeType = $
|
|
|
1030
1030
|
_zod: $ZodCodecInternals<A, B>;
|
|
1031
1031
|
}
|
|
1032
1032
|
export declare const $ZodCodec: core.$constructor<$ZodCodec>;
|
|
1033
|
+
export interface $ZodPreprocessDef<B extends SomeType = $ZodType> extends $ZodPipeDef<$ZodTransform, B> {
|
|
1034
|
+
in: $ZodTransform;
|
|
1035
|
+
out: B;
|
|
1036
|
+
}
|
|
1037
|
+
export interface $ZodPreprocessInternals<B extends SomeType = $ZodType> extends $ZodPipeInternals<$ZodTransform, B> {
|
|
1038
|
+
def: $ZodPreprocessDef<B>;
|
|
1039
|
+
optin: B["_zod"]["optin"];
|
|
1040
|
+
optout: B["_zod"]["optout"];
|
|
1041
|
+
}
|
|
1042
|
+
export interface $ZodPreprocess<B extends SomeType = $ZodType> extends $ZodPipe<$ZodTransform, B> {
|
|
1043
|
+
_zod: $ZodPreprocessInternals<B>;
|
|
1044
|
+
}
|
|
1045
|
+
export declare const $ZodPreprocess: core.$constructor<$ZodPreprocess>;
|
|
1033
1046
|
export interface $ZodReadonlyDef<T extends SomeType = $ZodType> extends $ZodTypeDef {
|
|
1034
1047
|
type: "readonly";
|
|
1035
1048
|
innerType: T;
|
package/v4/core/schemas.js
CHANGED
|
@@ -1313,13 +1313,13 @@ export const $ZodTuple = /*@__PURE__*/ core.$constructor("$ZodTuple", (inst, def
|
|
|
1313
1313
|
}
|
|
1314
1314
|
payload.value = [];
|
|
1315
1315
|
const proms = [];
|
|
1316
|
-
const
|
|
1317
|
-
const
|
|
1316
|
+
const optinStart = getTupleOptStart(items, "optin");
|
|
1317
|
+
const optoutStart = getTupleOptStart(items, "optout");
|
|
1318
1318
|
if (!def.rest) {
|
|
1319
|
-
if (input.length <
|
|
1319
|
+
if (input.length < optinStart) {
|
|
1320
1320
|
payload.issues.push({
|
|
1321
1321
|
code: "too_small",
|
|
1322
|
-
minimum:
|
|
1322
|
+
minimum: optinStart,
|
|
1323
1323
|
inclusive: true,
|
|
1324
1324
|
input,
|
|
1325
1325
|
inst,
|
|
@@ -1340,9 +1340,8 @@ export const $ZodTuple = /*@__PURE__*/ core.$constructor("$ZodTuple", (inst, def
|
|
|
1340
1340
|
}
|
|
1341
1341
|
// Run every item in parallel, collecting results into an indexed
|
|
1342
1342
|
// array. The post-processing in `handleTupleResults` walks them in
|
|
1343
|
-
// order so it can
|
|
1344
|
-
//
|
|
1345
|
-
// any later defaults must NOT fire.
|
|
1343
|
+
// order so it can decide whether an absent optional-output error can
|
|
1344
|
+
// truncate the tail or must be reported to preserve required output.
|
|
1346
1345
|
const itemResults = new Array(items.length);
|
|
1347
1346
|
for (let i = 0; i < items.length; i++) {
|
|
1348
1347
|
const r = items[i]._zod.run({ value: input[i], issues: [] }, ctx);
|
|
@@ -1369,36 +1368,34 @@ export const $ZodTuple = /*@__PURE__*/ core.$constructor("$ZodTuple", (inst, def
|
|
|
1369
1368
|
}
|
|
1370
1369
|
}
|
|
1371
1370
|
}
|
|
1372
|
-
if (proms.length)
|
|
1373
|
-
return Promise.all(proms).then(() => handleTupleResults(itemResults, payload, items, input));
|
|
1374
|
-
|
|
1371
|
+
if (proms.length) {
|
|
1372
|
+
return Promise.all(proms).then(() => handleTupleResults(itemResults, payload, items, input, optoutStart));
|
|
1373
|
+
}
|
|
1374
|
+
return handleTupleResults(itemResults, payload, items, input, optoutStart);
|
|
1375
1375
|
};
|
|
1376
1376
|
});
|
|
1377
|
+
function getTupleOptStart(items, key) {
|
|
1378
|
+
for (let i = items.length - 1; i >= 0; i--) {
|
|
1379
|
+
if (items[i]._zod[key] !== "optional")
|
|
1380
|
+
return i + 1;
|
|
1381
|
+
}
|
|
1382
|
+
return 0;
|
|
1383
|
+
}
|
|
1377
1384
|
function handleTupleResult(result, final, index) {
|
|
1378
1385
|
if (result.issues.length) {
|
|
1379
1386
|
final.issues.push(...util.prefixIssues(index, result.issues));
|
|
1380
1387
|
}
|
|
1381
1388
|
final.value[index] = result.value;
|
|
1382
1389
|
}
|
|
1383
|
-
|
|
1384
|
-
// `optStart` is intentionally NOT consulted here — it's an input-length
|
|
1385
|
-
// concern handled by the `too_small` precheck at the top of parse. This
|
|
1386
|
-
// step is purely about output shaping, which is governed by `optout`:
|
|
1387
|
-
// a `.default()` tail item sits inside the optStart region (its `optin`
|
|
1388
|
-
// is optional), but it must NOT be dropped or have its errors swallowed
|
|
1389
|
-
// because it materializes a defined value (`optout !== "optional"`).
|
|
1390
|
-
function handleTupleResults(itemResults, final, items, input) {
|
|
1390
|
+
function handleTupleResults(itemResults, final, items, input, optoutStart) {
|
|
1391
1391
|
// Walk results in order. Mirror $ZodObject's swallow-on-absent-optional
|
|
1392
|
-
// rule, but
|
|
1393
|
-
//
|
|
1394
|
-
// so we truncate the result there and stop processing — including
|
|
1395
|
-
// skipping any later defaults.
|
|
1392
|
+
// rule, but only after `optoutStart`: the first index where the output
|
|
1393
|
+
// tuple tail can be absent.
|
|
1396
1394
|
for (let i = 0; i < items.length; i++) {
|
|
1397
1395
|
const r = itemResults[i];
|
|
1398
|
-
const isOptionalOut = items[i]._zod.optout === "optional";
|
|
1399
1396
|
const isPresent = i < input.length;
|
|
1400
1397
|
if (r.issues.length) {
|
|
1401
|
-
if (
|
|
1398
|
+
if (!isPresent && i >= optoutStart) {
|
|
1402
1399
|
final.value.length = i;
|
|
1403
1400
|
break;
|
|
1404
1401
|
}
|
|
@@ -2025,6 +2022,11 @@ function handleCodecTxResult(left, value, nextSchema, ctx) {
|
|
|
2025
2022
|
}
|
|
2026
2023
|
return nextSchema._zod.run({ value, issues: left.issues }, ctx);
|
|
2027
2024
|
}
|
|
2025
|
+
export const $ZodPreprocess = /*@__PURE__*/ core.$constructor("$ZodPreprocess", (inst, def) => {
|
|
2026
|
+
$ZodPipe.init(inst, def);
|
|
2027
|
+
util.defineLazy(inst._zod, "optin", () => def.out._zod.optin);
|
|
2028
|
+
util.defineLazy(inst._zod, "optout", () => def.out._zod.optout);
|
|
2029
|
+
});
|
|
2028
2030
|
export const $ZodReadonly = /*@__PURE__*/ core.$constructor("$ZodReadonly", (inst, def) => {
|
|
2029
2031
|
$ZodType.init(inst, def);
|
|
2030
2032
|
util.defineLazy(inst._zod, "propValues", () => def.innerType._zod.propValues);
|
|
@@ -407,6 +407,8 @@ function isTransforming(_schema, _ctx) {
|
|
|
407
407
|
return isTransforming(def.keyType, ctx) || isTransforming(def.valueType, ctx);
|
|
408
408
|
}
|
|
409
409
|
if (def.type === "pipe") {
|
|
410
|
+
if (_schema._zod.traits.has("$ZodCodec"))
|
|
411
|
+
return true;
|
|
410
412
|
return isTransforming(def.in, ctx) || isTransforming(def.out, ctx);
|
|
411
413
|
}
|
|
412
414
|
if (def.type === "object") {
|
|
@@ -400,6 +400,8 @@ function isTransforming(_schema, _ctx) {
|
|
|
400
400
|
return isTransforming(def.keyType, ctx) || isTransforming(def.valueType, ctx);
|
|
401
401
|
}
|
|
402
402
|
if (def.type === "pipe") {
|
|
403
|
+
if (_schema._zod.traits.has("$ZodCodec"))
|
|
404
|
+
return true;
|
|
403
405
|
return isTransforming(def.in, ctx) || isTransforming(def.out, ctx);
|
|
404
406
|
}
|
|
405
407
|
if (def.type === "object") {
|
package/v4/core/versions.cjs
CHANGED
package/v4/core/versions.js
CHANGED
package/v4/mini/schemas.d.cts
CHANGED
|
@@ -260,7 +260,7 @@ export interface ZodMiniDiscriminatedUnion<Options extends readonly SomeType[] =
|
|
|
260
260
|
_zod: core.$ZodDiscriminatedUnionInternals<Options, Disc>;
|
|
261
261
|
}
|
|
262
262
|
export declare const ZodMiniDiscriminatedUnion: core.$constructor<ZodMiniDiscriminatedUnion>;
|
|
263
|
-
export declare function discriminatedUnion<Types extends readonly [core.$ZodTypeDiscriminable
|
|
263
|
+
export declare function discriminatedUnion<Types extends readonly [core.$ZodTypeDiscriminable<Disc>, ...core.$ZodTypeDiscriminable<Disc>[]], Disc extends string>(discriminator: Disc, options: Types, params?: string | core.$ZodDiscriminatedUnionParams): ZodMiniDiscriminatedUnion<Types, Disc>;
|
|
264
264
|
export interface ZodMiniIntersection<A extends SomeType = core.$ZodType, B extends SomeType = core.$ZodType> extends _ZodMiniType<core.$ZodIntersectionInternals<A, B>> {
|
|
265
265
|
}
|
|
266
266
|
export declare const ZodMiniIntersection: core.$constructor<ZodMiniIntersection>;
|
package/v4/mini/schemas.d.ts
CHANGED
|
@@ -260,7 +260,7 @@ export interface ZodMiniDiscriminatedUnion<Options extends readonly SomeType[] =
|
|
|
260
260
|
_zod: core.$ZodDiscriminatedUnionInternals<Options, Disc>;
|
|
261
261
|
}
|
|
262
262
|
export declare const ZodMiniDiscriminatedUnion: core.$constructor<ZodMiniDiscriminatedUnion>;
|
|
263
|
-
export declare function discriminatedUnion<Types extends readonly [core.$ZodTypeDiscriminable
|
|
263
|
+
export declare function discriminatedUnion<Types extends readonly [core.$ZodTypeDiscriminable<Disc>, ...core.$ZodTypeDiscriminable<Disc>[]], Disc extends string>(discriminator: Disc, options: Types, params?: string | core.$ZodDiscriminatedUnionParams): ZodMiniDiscriminatedUnion<Types, Disc>;
|
|
264
264
|
export interface ZodMiniIntersection<A extends SomeType = core.$ZodType, B extends SomeType = core.$ZodType> extends _ZodMiniType<core.$ZodIntersectionInternals<A, B>> {
|
|
265
265
|
}
|
|
266
266
|
export declare const ZodMiniIntersection: core.$constructor<ZodMiniIntersection>;
|