zod 4.3.0-canary.20251216T172808 → 4.3.0-canary.20251222T195342
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/package.json +1 -1
- package/src/v4/classic/schemas.ts +4 -2
- package/src/v4/classic/tests/brand.test.ts +43 -0
- package/src/v4/classic/tests/string.test.ts +21 -0
- package/src/v4/core/core.ts +10 -2
- package/src/v4/mini/schemas.ts +2 -2
- package/src/v4/mini/tests/brand.test.ts +43 -0
- package/v4/classic/schemas.d.cts +2 -2
- package/v4/classic/schemas.d.ts +2 -2
- package/v4/core/core.d.cts +14 -1
- package/v4/core/core.d.ts +14 -1
- package/v4/mini/schemas.d.cts +1 -1
- package/v4/mini/schemas.d.ts +1 -1
package/package.json
CHANGED
|
@@ -48,7 +48,9 @@ export interface ZodType<
|
|
|
48
48
|
: ["Incompatible schema"]
|
|
49
49
|
): this;
|
|
50
50
|
|
|
51
|
-
brand<T extends PropertyKey = PropertyKey
|
|
51
|
+
brand<T extends PropertyKey = PropertyKey, Dir extends "in" | "out" | "inout" = "out">(
|
|
52
|
+
value?: T
|
|
53
|
+
): PropertyKey extends T ? this : core.$ZodBranded<this, T, Dir>;
|
|
52
54
|
|
|
53
55
|
// parsing
|
|
54
56
|
parse(data: unknown, params?: core.ParseContext<core.$ZodIssue>): core.output<this>;
|
|
@@ -253,7 +255,7 @@ export interface _ZodString<T extends core.$ZodStringInternals<unknown> = core.$
|
|
|
253
255
|
|
|
254
256
|
// miscellaneous checks
|
|
255
257
|
regex(regex: RegExp, params?: string | core.$ZodCheckRegexParams): this;
|
|
256
|
-
includes(value: string, params?: core.$ZodCheckIncludesParams): this;
|
|
258
|
+
includes(value: string, params?: string | core.$ZodCheckIncludesParams): this;
|
|
257
259
|
startsWith(value: string, params?: string | core.$ZodCheckStartsWithParams): this;
|
|
258
260
|
endsWith(value: string, params?: string | core.$ZodCheckEndsWithParams): this;
|
|
259
261
|
min(minLength: number, params?: string | core.$ZodCheckMinLengthParams): this;
|
|
@@ -61,3 +61,46 @@ test("branded record", () => {
|
|
|
61
61
|
type recordWithBrandedNumberKeys = z.infer<typeof recordWithBrandedNumberKeys>;
|
|
62
62
|
expectTypeOf<recordWithBrandedNumberKeys>().toEqualTypeOf<Record<string & z.core.$brand<"SomeBrand">, number>>();
|
|
63
63
|
});
|
|
64
|
+
|
|
65
|
+
test("brand direction: out (default)", () => {
|
|
66
|
+
const schema = z.string().brand<"A">();
|
|
67
|
+
type Input = z.input<typeof schema>;
|
|
68
|
+
type Output = z.output<typeof schema>;
|
|
69
|
+
|
|
70
|
+
// output is branded
|
|
71
|
+
expectTypeOf<Output>().toEqualTypeOf<string & z.$brand<"A">>();
|
|
72
|
+
// input is NOT branded (default behavior)
|
|
73
|
+
expectTypeOf<Input>().toEqualTypeOf<string>();
|
|
74
|
+
});
|
|
75
|
+
|
|
76
|
+
test("brand direction: out (explicit)", () => {
|
|
77
|
+
const schema = z.string().brand<"A", "out">();
|
|
78
|
+
type Input = z.input<typeof schema>;
|
|
79
|
+
type Output = z.output<typeof schema>;
|
|
80
|
+
|
|
81
|
+
// output is branded
|
|
82
|
+
expectTypeOf<Output>().toEqualTypeOf<string & z.$brand<"A">>();
|
|
83
|
+
// input is NOT branded
|
|
84
|
+
expectTypeOf<Input>().toEqualTypeOf<string>();
|
|
85
|
+
});
|
|
86
|
+
|
|
87
|
+
test("brand direction: in", () => {
|
|
88
|
+
const schema = z.string().brand<"A", "in">();
|
|
89
|
+
type Input = z.input<typeof schema>;
|
|
90
|
+
type Output = z.output<typeof schema>;
|
|
91
|
+
|
|
92
|
+
// input is branded
|
|
93
|
+
expectTypeOf<Input>().toEqualTypeOf<string & z.$brand<"A">>();
|
|
94
|
+
// output is NOT branded
|
|
95
|
+
expectTypeOf<Output>().toEqualTypeOf<string>();
|
|
96
|
+
});
|
|
97
|
+
|
|
98
|
+
test("brand direction: inout", () => {
|
|
99
|
+
const schema = z.string().brand<"A", "inout">();
|
|
100
|
+
type Input = z.input<typeof schema>;
|
|
101
|
+
type Output = z.output<typeof schema>;
|
|
102
|
+
|
|
103
|
+
// both are branded
|
|
104
|
+
expectTypeOf<Input>().toEqualTypeOf<string & z.$brand<"A">>();
|
|
105
|
+
expectTypeOf<Output>().toEqualTypeOf<string & z.$brand<"A">>();
|
|
106
|
+
});
|
|
@@ -35,6 +35,27 @@ test("includes", () => {
|
|
|
35
35
|
expect(() => includesFromIndex2.parse("XincludesXX")).toThrow();
|
|
36
36
|
});
|
|
37
37
|
|
|
38
|
+
test("includes with string error message", () => {
|
|
39
|
+
const schema = z.string().includes("test", "must contain test");
|
|
40
|
+
schema.parse("this is a test");
|
|
41
|
+
|
|
42
|
+
expect(schema.safeParse("this is invalid")).toMatchInlineSnapshot(`
|
|
43
|
+
{
|
|
44
|
+
"error": [ZodError: [
|
|
45
|
+
{
|
|
46
|
+
"origin": "string",
|
|
47
|
+
"code": "invalid_format",
|
|
48
|
+
"format": "includes",
|
|
49
|
+
"includes": "test",
|
|
50
|
+
"path": [],
|
|
51
|
+
"message": "must contain test"
|
|
52
|
+
}
|
|
53
|
+
]],
|
|
54
|
+
"success": false,
|
|
55
|
+
}
|
|
56
|
+
`);
|
|
57
|
+
});
|
|
58
|
+
|
|
38
59
|
test("startswith/endswith", () => {
|
|
39
60
|
startsWith.parse("startsWithX");
|
|
40
61
|
endsWith.parse("XendsWith");
|
package/src/v4/core/core.ts
CHANGED
|
@@ -82,8 +82,16 @@ export type $brand<T extends string | number | symbol = string | number | symbol
|
|
|
82
82
|
[$brand]: { [k in T]: true };
|
|
83
83
|
};
|
|
84
84
|
|
|
85
|
-
export type $ZodBranded<
|
|
86
|
-
|
|
85
|
+
export type $ZodBranded<
|
|
86
|
+
T extends schemas.SomeType,
|
|
87
|
+
Brand extends string | number | symbol,
|
|
88
|
+
Dir extends "in" | "out" | "inout" = "out",
|
|
89
|
+
> = T &
|
|
90
|
+
(Dir extends "inout"
|
|
91
|
+
? { _zod: { input: input<T> & $brand<Brand>; output: output<T> & $brand<Brand> } }
|
|
92
|
+
: Dir extends "in"
|
|
93
|
+
? { _zod: { input: input<T> & $brand<Brand> } }
|
|
94
|
+
: { _zod: { output: output<T> & $brand<Brand> } });
|
|
87
95
|
|
|
88
96
|
export class $ZodAsyncError extends Error {
|
|
89
97
|
constructor() {
|
package/src/v4/mini/schemas.ts
CHANGED
|
@@ -20,9 +20,9 @@ export interface ZodMiniType<
|
|
|
20
20
|
: [core.$replace<R["_meta"], this>]
|
|
21
21
|
: ["Incompatible schema"]
|
|
22
22
|
): this;
|
|
23
|
-
brand<T extends PropertyKey = PropertyKey>(
|
|
23
|
+
brand<T extends PropertyKey = PropertyKey, Dir extends "in" | "out" | "inout" = "out">(
|
|
24
24
|
value?: T
|
|
25
|
-
): PropertyKey extends T ? this : this
|
|
25
|
+
): PropertyKey extends T ? this : core.$ZodBranded<this, T, Dir>;
|
|
26
26
|
|
|
27
27
|
def: Internals["def"];
|
|
28
28
|
|
|
@@ -49,3 +49,46 @@ test("branded types", () => {
|
|
|
49
49
|
// @ts-expect-error
|
|
50
50
|
doStuff({ name: "hello there!" });
|
|
51
51
|
});
|
|
52
|
+
|
|
53
|
+
test("brand direction: out (default)", () => {
|
|
54
|
+
const schema = z.string().brand<"A">();
|
|
55
|
+
type Input = z.input<typeof schema>;
|
|
56
|
+
type Output = z.output<typeof schema>;
|
|
57
|
+
|
|
58
|
+
// output is branded
|
|
59
|
+
expectTypeOf<Output>().toEqualTypeOf<string & z.$brand<"A">>();
|
|
60
|
+
// input is NOT branded (default behavior)
|
|
61
|
+
expectTypeOf<Input>().toEqualTypeOf<string>();
|
|
62
|
+
});
|
|
63
|
+
|
|
64
|
+
test("brand direction: out (explicit)", () => {
|
|
65
|
+
const schema = z.string().brand<"A", "out">();
|
|
66
|
+
type Input = z.input<typeof schema>;
|
|
67
|
+
type Output = z.output<typeof schema>;
|
|
68
|
+
|
|
69
|
+
// output is branded
|
|
70
|
+
expectTypeOf<Output>().toEqualTypeOf<string & z.$brand<"A">>();
|
|
71
|
+
// input is NOT branded
|
|
72
|
+
expectTypeOf<Input>().toEqualTypeOf<string>();
|
|
73
|
+
});
|
|
74
|
+
|
|
75
|
+
test("brand direction: in", () => {
|
|
76
|
+
const schema = z.string().brand<"A", "in">();
|
|
77
|
+
type Input = z.input<typeof schema>;
|
|
78
|
+
type Output = z.output<typeof schema>;
|
|
79
|
+
|
|
80
|
+
// input is branded
|
|
81
|
+
expectTypeOf<Input>().toEqualTypeOf<string & z.$brand<"A">>();
|
|
82
|
+
// output is NOT branded
|
|
83
|
+
expectTypeOf<Output>().toEqualTypeOf<string>();
|
|
84
|
+
});
|
|
85
|
+
|
|
86
|
+
test("brand direction: inout", () => {
|
|
87
|
+
const schema = z.string().brand<"A", "inout">();
|
|
88
|
+
type Input = z.input<typeof schema>;
|
|
89
|
+
type Output = z.output<typeof schema>;
|
|
90
|
+
|
|
91
|
+
// both are branded
|
|
92
|
+
expectTypeOf<Input>().toEqualTypeOf<string & z.$brand<"A">>();
|
|
93
|
+
expectTypeOf<Output>().toEqualTypeOf<string & z.$brand<"A">>();
|
|
94
|
+
});
|
package/v4/classic/schemas.d.cts
CHANGED
|
@@ -20,7 +20,7 @@ export interface ZodType<out Output = unknown, out Input = unknown, out Internal
|
|
|
20
20
|
parent: boolean;
|
|
21
21
|
}): this;
|
|
22
22
|
register<R extends core.$ZodRegistry>(registry: R, ...meta: this extends R["_schema"] ? undefined extends R["_meta"] ? [core.$replace<R["_meta"], this>?] : [core.$replace<R["_meta"], this>] : ["Incompatible schema"]): this;
|
|
23
|
-
brand<T extends PropertyKey = PropertyKey>(value?: T): PropertyKey extends T ? this : core.$ZodBranded<this, T>;
|
|
23
|
+
brand<T extends PropertyKey = PropertyKey, Dir extends "in" | "out" | "inout" = "out">(value?: T): PropertyKey extends T ? this : core.$ZodBranded<this, T, Dir>;
|
|
24
24
|
parse(data: unknown, params?: core.ParseContext<core.$ZodIssue>): core.output<this>;
|
|
25
25
|
safeParse(data: unknown, params?: core.ParseContext<core.$ZodIssue>): parse.ZodSafeParseResult<core.output<this>>;
|
|
26
26
|
parseAsync(data: unknown, params?: core.ParseContext<core.$ZodIssue>): Promise<core.output<this>>;
|
|
@@ -86,7 +86,7 @@ export interface _ZodString<T extends core.$ZodStringInternals<unknown> = core.$
|
|
|
86
86
|
minLength: number | null;
|
|
87
87
|
maxLength: number | null;
|
|
88
88
|
regex(regex: RegExp, params?: string | core.$ZodCheckRegexParams): this;
|
|
89
|
-
includes(value: string, params?: core.$ZodCheckIncludesParams): this;
|
|
89
|
+
includes(value: string, params?: string | core.$ZodCheckIncludesParams): this;
|
|
90
90
|
startsWith(value: string, params?: string | core.$ZodCheckStartsWithParams): this;
|
|
91
91
|
endsWith(value: string, params?: string | core.$ZodCheckEndsWithParams): this;
|
|
92
92
|
min(minLength: number, params?: string | core.$ZodCheckMinLengthParams): this;
|
package/v4/classic/schemas.d.ts
CHANGED
|
@@ -20,7 +20,7 @@ export interface ZodType<out Output = unknown, out Input = unknown, out Internal
|
|
|
20
20
|
parent: boolean;
|
|
21
21
|
}): this;
|
|
22
22
|
register<R extends core.$ZodRegistry>(registry: R, ...meta: this extends R["_schema"] ? undefined extends R["_meta"] ? [core.$replace<R["_meta"], this>?] : [core.$replace<R["_meta"], this>] : ["Incompatible schema"]): this;
|
|
23
|
-
brand<T extends PropertyKey = PropertyKey>(value?: T): PropertyKey extends T ? this : core.$ZodBranded<this, T>;
|
|
23
|
+
brand<T extends PropertyKey = PropertyKey, Dir extends "in" | "out" | "inout" = "out">(value?: T): PropertyKey extends T ? this : core.$ZodBranded<this, T, Dir>;
|
|
24
24
|
parse(data: unknown, params?: core.ParseContext<core.$ZodIssue>): core.output<this>;
|
|
25
25
|
safeParse(data: unknown, params?: core.ParseContext<core.$ZodIssue>): parse.ZodSafeParseResult<core.output<this>>;
|
|
26
26
|
parseAsync(data: unknown, params?: core.ParseContext<core.$ZodIssue>): Promise<core.output<this>>;
|
|
@@ -86,7 +86,7 @@ export interface _ZodString<T extends core.$ZodStringInternals<unknown> = core.$
|
|
|
86
86
|
minLength: number | null;
|
|
87
87
|
maxLength: number | null;
|
|
88
88
|
regex(regex: RegExp, params?: string | core.$ZodCheckRegexParams): this;
|
|
89
|
-
includes(value: string, params?: core.$ZodCheckIncludesParams): this;
|
|
89
|
+
includes(value: string, params?: string | core.$ZodCheckIncludesParams): this;
|
|
90
90
|
startsWith(value: string, params?: string | core.$ZodCheckStartsWithParams): this;
|
|
91
91
|
endsWith(value: string, params?: string | core.$ZodCheckEndsWithParams): this;
|
|
92
92
|
min(minLength: number, params?: string | core.$ZodCheckMinLengthParams): this;
|
package/v4/core/core.d.cts
CHANGED
|
@@ -22,7 +22,20 @@ export type $brand<T extends string | number | symbol = string | number | symbol
|
|
|
22
22
|
[k in T]: true;
|
|
23
23
|
};
|
|
24
24
|
};
|
|
25
|
-
export type $ZodBranded<T extends schemas.SomeType, Brand extends string | number | symbol
|
|
25
|
+
export type $ZodBranded<T extends schemas.SomeType, Brand extends string | number | symbol, Dir extends "in" | "out" | "inout" = "out"> = T & (Dir extends "inout" ? {
|
|
26
|
+
_zod: {
|
|
27
|
+
input: input<T> & $brand<Brand>;
|
|
28
|
+
output: output<T> & $brand<Brand>;
|
|
29
|
+
};
|
|
30
|
+
} : Dir extends "in" ? {
|
|
31
|
+
_zod: {
|
|
32
|
+
input: input<T> & $brand<Brand>;
|
|
33
|
+
};
|
|
34
|
+
} : {
|
|
35
|
+
_zod: {
|
|
36
|
+
output: output<T> & $brand<Brand>;
|
|
37
|
+
};
|
|
38
|
+
});
|
|
26
39
|
export declare class $ZodAsyncError extends Error {
|
|
27
40
|
constructor();
|
|
28
41
|
}
|
package/v4/core/core.d.ts
CHANGED
|
@@ -22,7 +22,20 @@ export type $brand<T extends string | number | symbol = string | number | symbol
|
|
|
22
22
|
[k in T]: true;
|
|
23
23
|
};
|
|
24
24
|
};
|
|
25
|
-
export type $ZodBranded<T extends schemas.SomeType, Brand extends string | number | symbol
|
|
25
|
+
export type $ZodBranded<T extends schemas.SomeType, Brand extends string | number | symbol, Dir extends "in" | "out" | "inout" = "out"> = T & (Dir extends "inout" ? {
|
|
26
|
+
_zod: {
|
|
27
|
+
input: input<T> & $brand<Brand>;
|
|
28
|
+
output: output<T> & $brand<Brand>;
|
|
29
|
+
};
|
|
30
|
+
} : Dir extends "in" ? {
|
|
31
|
+
_zod: {
|
|
32
|
+
input: input<T> & $brand<Brand>;
|
|
33
|
+
};
|
|
34
|
+
} : {
|
|
35
|
+
_zod: {
|
|
36
|
+
output: output<T> & $brand<Brand>;
|
|
37
|
+
};
|
|
38
|
+
});
|
|
26
39
|
export declare class $ZodAsyncError extends Error {
|
|
27
40
|
constructor();
|
|
28
41
|
}
|
package/v4/mini/schemas.d.cts
CHANGED
|
@@ -8,7 +8,7 @@ export interface ZodMiniType<out Output = unknown, out Input = unknown, out Inte
|
|
|
8
8
|
parent: boolean;
|
|
9
9
|
}): this;
|
|
10
10
|
register<R extends core.$ZodRegistry>(registry: R, ...meta: this extends R["_schema"] ? undefined extends R["_meta"] ? [core.$replace<R["_meta"], this>?] : [core.$replace<R["_meta"], this>] : ["Incompatible schema"]): this;
|
|
11
|
-
brand<T extends PropertyKey = PropertyKey>(value?: T): PropertyKey extends T ? this : this
|
|
11
|
+
brand<T extends PropertyKey = PropertyKey, Dir extends "in" | "out" | "inout" = "out">(value?: T): PropertyKey extends T ? this : core.$ZodBranded<this, T, Dir>;
|
|
12
12
|
def: Internals["def"];
|
|
13
13
|
parse(data: unknown, params?: core.ParseContext<core.$ZodIssue>): core.output<this>;
|
|
14
14
|
safeParse(data: unknown, params?: core.ParseContext<core.$ZodIssue>): util.SafeParseResult<core.output<this>>;
|
package/v4/mini/schemas.d.ts
CHANGED
|
@@ -8,7 +8,7 @@ export interface ZodMiniType<out Output = unknown, out Input = unknown, out Inte
|
|
|
8
8
|
parent: boolean;
|
|
9
9
|
}): this;
|
|
10
10
|
register<R extends core.$ZodRegistry>(registry: R, ...meta: this extends R["_schema"] ? undefined extends R["_meta"] ? [core.$replace<R["_meta"], this>?] : [core.$replace<R["_meta"], this>] : ["Incompatible schema"]): this;
|
|
11
|
-
brand<T extends PropertyKey = PropertyKey>(value?: T): PropertyKey extends T ? this : this
|
|
11
|
+
brand<T extends PropertyKey = PropertyKey, Dir extends "in" | "out" | "inout" = "out">(value?: T): PropertyKey extends T ? this : core.$ZodBranded<this, T, Dir>;
|
|
12
12
|
def: Internals["def"];
|
|
13
13
|
parse(data: unknown, params?: core.ParseContext<core.$ZodIssue>): core.output<this>;
|
|
14
14
|
safeParse(data: unknown, params?: core.ParseContext<core.$ZodIssue>): util.SafeParseResult<core.output<this>>;
|