Skip to content

Commit 9a34a3a

Browse files
colinhacksCopilot
andauthored
Zod 4.0.11 (#4981)
* Implement z.hostname(). Closes #3589. * Add benchmarks * Improve recursion for intersections. Closes #4714 * Improve offset regex. Closes #3883 * Fix multipleOf at high precisions. Fixes #3486 * Undeprecate superRefine, update docs * Update packages/bench/single-element-enum.ts Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> * Update packages/bench/single-element-enum.ts Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> * Clean up * Fix lint * Docs * Update zshy * 4.0.11 * Update zshy * Update zshy * Skip types in resolution tests --------- Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
1 parent c762dbb commit 9a34a3a

27 files changed

+472
-173
lines changed

‎package.json

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
"@biomejs/biome": "^1.9.4",
2020
"@types/benchmark": "^2.1.5",
2121
"@types/semver": "^7.7.0",
22+
"@web-std/file": "^3.0.3",
2223
"arktype": "^2.1.19",
2324
"benchmark": "^2.1.4",
2425
"chalk": "^5.4.1",
@@ -32,8 +33,6 @@
3233
"mitata": "^0.1.14",
3334
"prettier": "^3.5.3",
3435
"recheck": "^4.5.0",
35-
"@web-std/file": "^3.0.3",
36-
3736
"rolldown": "1.0.0-beta.18",
3837
"rollup": "^4.39.0",
3938
"semver": "^7.7.2",
@@ -47,7 +46,7 @@
4746
"vitest": "^2.1.9",
4847
"zod": "workspace:*",
4948
"zod3": "npm:zod@~3.24.0",
50-
"zshy": "^0.0.14"
49+
"zshy": "^0.3.3"
5150
},
5251
"lint-staged": {
5352
"packages/*/src/**/*.ts": [

‎packages/bench/benchUtil.ts

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,12 @@
1-
import * as zNew from "zod/v4";
2-
import * as zOld from "zod3";
1+
import * as zodNext from "../zod/src/index.js";
2+
import * as zod4 from "zod4";
3+
import * as zod3 from "zod3";
34

4-
export function makeSchema<T>(factory: (z: typeof zNew) => T) {
5+
export {zod3, zod4, zodNext}
6+
export function makeSchema<T>(factory: (z: typeof zod4) => T) {
57
return {
6-
zod3: factory(zOld as any) as T,
7-
zod4: factory(zNew as any) as T,
8+
zod3: factory(zod3 as any) as T,
9+
zod4: factory(zod4 as any) as T,
810
// zod4Ts: factory(zodNewTs as any),
911
};
1012
}

‎packages/bench/object-moltar.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,8 +14,8 @@ const z3Schema = z3.object({
1414
foo: z3.string(),
1515
num: z3.number(),
1616
bool: z3.boolean(),
17-
}).strict()
18-
}).strict();
17+
})
18+
})
1919

2020
const z4LibSchema = z4lib.object({
2121
number: z4lib.number(),

‎packages/bench/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
"valibot": "^1.0.0",
88
"zod": "workspace:*",
99
"zod3": "npm:zod@~3.24.0",
10-
"zod4": "npm:zod@3.25.68"
10+
"zod4": "npm:zod@4.0.8"
1111
},
1212
"scripts": {
1313
"bench": "tsx --conditions @zod/source index.ts"

‎packages/bench/single-element-enum.ts

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
2+
3+
import { metabench } from "./metabench.js";
4+
import { zod4, zodNext } from "./benchUtil.js";
5+
6+
7+
8+
console.log("Single-element enum benchmarking");
9+
10+
const z4LibSchema = zod4.enum(['a']);
11+
12+
const z4Schema = zodNext.enum(['a']);
13+
14+
15+
const DATA = Array.from({ length: 10000 }, () => 'a');
16+
17+
console.log(z4Schema.parse(DATA[0]));
18+
console.log(z4LibSchema.parse(DATA[0]));
19+
20+
const bench = metabench("single-element enum parse", {
21+
22+
zodNext() {
23+
for(const _ of DATA) z4LibSchema.parse("a");
24+
},
25+
zod4(){
26+
for(const _ of DATA) z4Schema.parse("a");
27+
}
28+
29+
});
30+
31+
await bench.run();

‎packages/bench/single-item-union.ts

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
2+
3+
import { metabench } from "./metabench.js";
4+
import { randomString, zod4, zodNext } from "./benchUtil.js";
5+
6+
7+
8+
console.log("Single item union");
9+
10+
const z4LibSchema = zod4.union([
11+
zod4.object({ value: zod4.string() })
12+
]);
13+
14+
const z4Schema = zodNext.union([
15+
zodNext.object({ value: zodNext.string() })
16+
])
17+
18+
19+
const DATA = Array.from({ length: 100 }, () => ({ value: randomString(15) }));
20+
21+
console.log(z4Schema.parse(DATA[0]));
22+
console.log(z4LibSchema.parse(DATA[0]));
23+
24+
const bench = metabench("single item union", {
25+
26+
zodNext() {
27+
z4LibSchema.parse({value:"asdfadfs"});
28+
},
29+
zod4(){
30+
z4Schema.parse({value:"asdfadfs"});
31+
}
32+
33+
});
34+
35+
await bench.run();

‎packages/docs/content/api.mdx

Lines changed: 68 additions & 60 deletions
Original file line numberDiff line numberDiff line change
@@ -228,6 +228,7 @@ To validate against some common string formats:
228228
z.email();
229229
z.uuid();
230230
z.url();
231+
z.hostname();
231232
z.emoji(); // validates a single emoji character
232233
z.base64();
233234
z.base64url();
@@ -2145,70 +2146,73 @@ schema.parse({
21452146

21462147

21472148
### `.superRefine()`
2148-
2149-
<Callout type="warn">
2150-
In Zod 4, `.superRefine()` has been deprecated in favor of `.check()`
2151-
2152-
<Accordions>
2153-
<Accordion title="View .superRefine() example">
21542149

2155-
<Tabs groupId="lib" items={["Zod", "Zod Mini"]}>
2156-
<Tab value="Zod">
2157-
```ts
2158-
const UniqueStringArray = z.array(z.string()).superRefine((val, ctx) => {
2159-
if (val.length > 3) {
2160-
ctx.addIssue({
2161-
code: "too_big",
2162-
maximum: 3,
2163-
origin: "array",
2164-
inclusive: true,
2165-
message: "Too many items 😡",
2166-
input: val,
2167-
});
2168-
}
2169-
2170-
if (val.length !== new Set(val).size) {
2171-
ctx.addIssue({
2172-
code: "custom",
2173-
message: `No duplicates allowed.`,
2174-
input: val,
2175-
});
2176-
}
2150+
2151+
The regular `.refine` API only generates a single issue with a `"custom"` error code, but `.superRefine()` makes it possible to create multiple issues using any of Zod's [internal issue types](https://github.com/colinhacks/zod/blob/main/packages/zod/src/v4/core/errors.ts).
2152+
2153+
<Tabs groupId="lib" items={["Zod", "Zod Mini"]}>
2154+
<Tab value="Zod">
2155+
```ts
2156+
const UniqueStringArray = z.array(z.string()).superRefine((val, ctx) => {
2157+
if (val.length > 3) {
2158+
ctx.addIssue({
2159+
code: "too_big",
2160+
maximum: 3,
2161+
origin: "array",
2162+
inclusive: true,
2163+
message: "Too many items 😡",
2164+
input: val,
21772165
});
2178-
```
2179-
</Tab>
2180-
<Tab value="Zod Mini">
2181-
```ts
2182-
// no equivalent, use `.check(checkFn)` instead
2183-
2184-
2185-
2186-
2187-
2188-
2189-
2190-
2191-
2192-
2193-
2194-
2195-
2196-
2197-
2198-
2199-
2200-
2201-
2202-
```
2203-
</Tab>
2204-
</Tabs>
2205-
</Accordion>
2206-
</Accordions>
2207-
</Callout>
2166+
}
2167+
2168+
if (val.length !== new Set(val).size) {
2169+
ctx.addIssue({
2170+
code: "custom",
2171+
message: `No duplicates allowed.`,
2172+
input: val,
2173+
});
2174+
}
2175+
});
2176+
2177+
2178+
```
2179+
</Tab>
2180+
<Tab value="Zod Mini">
2181+
```ts
2182+
const UniqueStringArray = z.array(z.string()).check(
2183+
z.superRefine((val, ctx) => {
2184+
if (val.length > 3) {
2185+
ctx.addIssue({
2186+
code: "too_big",
2187+
maximum: 3,
2188+
origin: "array",
2189+
inclusive: true,
2190+
message: "Too many items 😡",
2191+
input: val,
2192+
});
2193+
}
2194+
2195+
if (val.length !== new Set(val).size) {
2196+
ctx.addIssue({
2197+
code: "custom",
2198+
message: `No duplicates allowed.`,
2199+
input: val,
2200+
});
2201+
}
2202+
})
2203+
);
2204+
```
2205+
</Tab>
2206+
</Tabs>
22082207

22092208
### `.check()`
22102209

2210+
<Callout>
2211+
**Note** — The `.check()` API is a more low-level API that's generally more complex than `.superRefine()`. It can be faster in performance-sensitive code paths, but it's also more verbose.
2212+
</Callout>
22112213

2214+
<Accordions>
2215+
<Accordion title="View example">
22122216
The `.refine()` API is syntactic sugar atop a more versatile (and verbose) API called `.check()`. You can use this API to create multiple issues in a single refinement or have full control of the generated issue objects.
22132217

22142218
<Tabs groupId="lib" items={["Zod", "Zod Mini"]}>
@@ -2267,8 +2271,8 @@ const UniqueStringArray = z.array(z.string()).check((ctx) => {
22672271
```
22682272
</Tab>
22692273
</Tabs>
2270-
2271-
The regular `.refine` API only generates issues with a `"custom"` error code, but `.check()` makes it possible to throw other issue types. For more information on Zod's internal issue types, read the [Error customization](./error-customization) docs.
2274+
</Accordion>
2275+
</Accordions>
22722276

22732277
## Pipes
22742278

@@ -2317,6 +2321,10 @@ z.parse(castToString, true); // => "true"
23172321
</Tab>
23182322
</Tabs>
23192323

2324+
<Callout type="warn">
2325+
Refinement functions should never throw. Thrown errors are not caught by Zod.
2326+
</Callout>
2327+
23202328
{/* The output type of the schema is inferred from the transform function:
23212329
23222330
<Tabs groupId="lib" items={["Zod", "Zod Mini"]}>

‎packages/resolution/tsconfig.build.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,8 @@
66
"rootDir": "./src",
77
"declaration": true,
88
"emitDeclarationOnly": false,
9-
"skipLibCheck": false
9+
"skipLibCheck": false,
10+
"types": []
1011
},
1112
"include": ["src/*.ts", "src/*.mts", "src/*.cts"],
1213
}

‎packages/zod/jsr.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "@zod/zod",
3-
"version": "4.0.10",
3+
"version": "4.0.11",
44
"exports": {
55
"./package.json": "./package.json",
66
".": "./src/index.ts",

‎packages/zod/package.json

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "zod",
3-
"version": "4.0.10",
3+
"version": "4.0.11",
44
"type": "module",
55
"author": "Colin McDonnell <zod@colinhacks.com>",
66
"description": "TypeScript-first schema declaration and validation library with static type inference",
@@ -41,9 +41,9 @@
4141
"./v4/locales": "./src/v4/locales/index.ts",
4242
"./v4/locales/*": "./src/v4/locales/*"
4343
},
44-
"sourceDialects": [
45-
"@zod/source"
46-
]
44+
"conditions": {
45+
"@zod/source": "src"
46+
}
4747
},
4848
"exports": {
4949
"./package.json": "./package.json",

0 commit comments

Comments
 (0)