zod 3.24.3 → 3.24.4

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 CHANGED
@@ -37,13 +37,13 @@
37
37
  <br/>
38
38
  <br/>
39
39
 
40
- <h2 align="center">Featured sponsor: Fern</h2>
40
+ <h2 align="center">Featured sponsor: Stainless</h2>
41
41
 
42
42
  <div align="center">
43
- <a href="https://link.buildwithfern.com/zod-partnership">
43
+ <a href="https://www.stainless.com/?utm_source=zod">
44
44
  <picture width="95%" >
45
- <source media="(prefers-color-scheme: dark)" srcset="https://i.imgur.com/ntvK08h.png">
46
- <img alt="fern logo" src="https://i.imgur.com/pqyEkg5.png" width="95%">
45
+ <source media="(prefers-color-scheme: dark)" srcset="https://i.imgur.com/bjyoaHY.jpeg">
46
+ <img alt="stainless logo" src="https://i.imgur.com/bjyoaHY.jpeg" width="95%">
47
47
  </picture>
48
48
  </a>
49
49
  <br/>
@@ -53,7 +53,7 @@
53
53
  <!-- <hr/> -->
54
54
  <br/>
55
55
  <br/>
56
-
56
+
57
57
  ## Table of contents
58
58
 
59
59
  > These docs have been translated into [Chinese](./README_ZH.md) and [Korean](./README_KO.md).
@@ -216,7 +216,7 @@ Sponsorship at any level is appreciated and encouraged. If you built a paid prod
216
216
  <img alt="CodeRabbit logo" height="80px" src="https://github.com/user-attachments/assets/d791bc7d-dc60-4d55-9c31-97779839cb74">
217
217
  </picture>
218
218
  </a>
219
- <br />
219
+ <br />
220
220
  Cut code review time & bugs in half
221
221
  <br/>
222
222
  <a href="https://www.coderabbit.ai/" style="text-decoration:none;">coderabbit.ai</a>
@@ -241,7 +241,7 @@ Sponsorship at any level is appreciated and encouraged. If you built a paid prod
241
241
  <img alt="Courier logo" height="62px" src="https://github.com/user-attachments/assets/6b09506a-78de-47e8-a8c1-792efe31910a">
242
242
  </picture>
243
243
  </a>
244
- <br />
244
+ <br />
245
245
  The API platform for sending notifications
246
246
  <br/>
247
247
  <a href="https://www.courier.com/?utm_source=zod&utm_campaign=osssponsors" style="text-decoration:none;">courier.com</a>
@@ -257,7 +257,7 @@ Sponsorship at any level is appreciated and encouraged. If you built a paid prod
257
257
  <img alt="LibLab" height="62px" src="https://github.com/user-attachments/assets/3de0b617-5137-49c4-b72d-a033cbe602d8">
258
258
  </picture>
259
259
  </a>
260
- <br />
260
+ <br />
261
261
  Generate better SDKs for your APIs
262
262
  <br/>
263
263
  <a href="https://liblab.com/?utm_source=zod" style="text-decoration:none;">liblab.com</a>
@@ -275,7 +275,7 @@ Sponsorship at any level is appreciated and encouraged. If you built a paid prod
275
275
  <img alt="Neon" height="68px" src="https://github.com/user-attachments/assets/b5799fc8-81ff-4053-a1c3-b29adf85e7a1">
276
276
  </picture>
277
277
  </a>
278
- <br />
278
+ <br />
279
279
  Serverless Postgres — Ship faster
280
280
  <br/>
281
281
  <a href="https://neon.tech" style="text-decoration:none;">neon.tech</a>
@@ -291,7 +291,7 @@ Sponsorship at any level is appreciated and encouraged. If you built a paid prod
291
291
  <img alt="Retool" height="45px" src="https://github.com/colinhacks/zod/assets/3084745/5ef4c11b-efeb-4495-90a8-41b83f798600">
292
292
  </picture>
293
293
  </a>
294
- <br />
294
+ <br />
295
295
  Build AI apps and workflows with <a href="https://retool.com/products/ai?utm_source=github&utm_medium=referral&utm_campaign=zod">Retool AI</a>
296
296
  <br/>
297
297
  <a href="https://retool.com/?utm_source=github&utm_medium=referral&utm_campaign=zod" style="text-decoration:none;">retool.com</a>
@@ -309,7 +309,7 @@ Sponsorship at any level is appreciated and encouraged. If you built a paid prod
309
309
  <img alt="stainless" height="45px" src="https://github.com/colinhacks/zod/assets/3084745/e9444e44-d991-4bba-a697-dbcfad608e47">
310
310
  </picture>
311
311
  </a>
312
- <br />
312
+ <br />
313
313
  Generate best-in-class SDKs
314
314
  <br/>
315
315
  <a href="https://stainless.com" style="text-decoration:none;">stainless.com</a>
@@ -325,7 +325,7 @@ Sponsorship at any level is appreciated and encouraged. If you built a paid prod
325
325
  <img alt="speakeasy" height="40px" src="https://github.com/colinhacks/zod/assets/3084745/647524a4-22bb-4199-be70-404207a5a2b5">
326
326
  </picture>
327
327
  </a>
328
- <br />
328
+ <br />
329
329
  SDKs & Terraform providers for your API
330
330
  <br/>
331
331
  <a href="https://speakeasy.com/?utm_source=zod+docs" style="text-decoration:none;">speakeasy.com</a>
@@ -410,6 +410,11 @@ Sponsorship at any level is appreciated and encouraged. If you built a paid prod
410
410
  <br />
411
411
  <a style="text-decoration:none;" href="https://mux.link/zod" target="_blank">Mux</a>
412
412
  </td>
413
+ <td align="center">
414
+ <img src="https://avatars.githubusercontent.com/u/76428554?s=200&v=4" height="50px;" alt="Cybozu logo" />
415
+ <br />
416
+ <a style="text-decoration:none;" href="https://cybozu.co.jp/index.html" target="_blank">Cybozu</a>
417
+ </td>
413
418
  </tr>
414
419
  </table>
415
420
 
@@ -842,7 +847,7 @@ z.string().toUpperCase(); // toUpperCase
842
847
 
843
848
  // added in Zod 3.23
844
849
  z.string().date(); // ISO date format (YYYY-MM-DD)
845
- z.string().time(); // ISO time format (HH:mm:ss[.SSSSSS])
850
+ z.string().time(); // ISO time format (HH:mm:ss[.SSSSSS] or HH:mm)
846
851
  z.string().duration(); // ISO 8601 duration
847
852
  z.string().base64();
848
853
  ```
@@ -882,7 +887,7 @@ z.string().cidr({ message: "Invalid CIDR" });
882
887
 
883
888
  As you may have noticed, Zod string includes a few date/time related validations. These validations are regular expression based, so they are not as strict as a full date/time library. However, they are very convenient for validating user input.
884
889
 
885
- The `z.string().datetime()` method enforces ISO 8601; default is no timezone offsets and arbitrary sub-second decimal precision.
890
+ The `z.string().datetime()` method enforces ISO 8601; default is no timezone offsets and arbitrary sub-second decimal precision. Seconds may be omitted if precision is not set.
886
891
 
887
892
  ```ts
888
893
  const datetime = z.string().datetime();
@@ -890,6 +895,7 @@ const datetime = z.string().datetime();
890
895
  datetime.parse("2020-01-01T00:00:00Z"); // pass
891
896
  datetime.parse("2020-01-01T00:00:00.123Z"); // pass
892
897
  datetime.parse("2020-01-01T00:00:00.123456Z"); // pass (arbitrary precision)
898
+ datetime.parse("2020-01-01T00:00Z"); // pass (hours and minutes only)
893
899
  datetime.parse("2020-01-01T00:00:00+02:00"); // fail (no offsets allowed)
894
900
  ```
895
901
 
@@ -899,6 +905,7 @@ Timezone offsets can be allowed by setting the `offset` option to `true`.
899
905
  const datetime = z.string().datetime({ offset: true });
900
906
 
901
907
  datetime.parse("2020-01-01T00:00:00+02:00"); // pass
908
+ datetime.parse("2020-01-01T00:00+02:00"); // pass
902
909
  datetime.parse("2020-01-01T00:00:00.123+02:00"); // pass (millis optional)
903
910
  datetime.parse("2020-01-01T00:00:00.123+0200"); // pass (millis optional)
904
911
  datetime.parse("2020-01-01T00:00:00.123+02"); // pass (only offset hours)
@@ -910,6 +917,7 @@ Allow unqualified (timezone-less) datetimes with the `local` flag.
910
917
  ```ts
911
918
  const schema = z.string().datetime({ local: true });
912
919
  schema.parse("2020-01-01T00:00:00"); // pass
920
+ schema.parse("2020-01-01T00:00"); // pass
913
921
  ```
914
922
 
915
923
  You can additionally constrain the allowable `precision`. By default, arbitrary sub-second precision is supported (but optional).
@@ -919,6 +927,7 @@ const datetime = z.string().datetime({ precision: 3 });
919
927
 
920
928
  datetime.parse("2020-01-01T00:00:00.123Z"); // pass
921
929
  datetime.parse("2020-01-01T00:00:00Z"); // fail
930
+ datetime.parse("2020-01-01T00:00Z"); // fail
922
931
  datetime.parse("2020-01-01T00:00:00.123456Z"); // fail
923
932
  ```
924
933
 
@@ -940,13 +949,14 @@ date.parse("2020-01-32"); // fail
940
949
 
941
950
  > Added in Zod 3.23
942
951
 
943
- The `z.string().time()` method validates strings in the format `HH:MM:SS[.s+]`. The second can include arbitrary decimal precision. It does not allow timezone offsets of any kind.
952
+ The `z.string().time()` method validates strings in the format `HH:MM` or `HH:MM:SS[.s+]`. The second can include arbitrary decimal precision. It does not allow timezone offsets of any kind.
944
953
 
945
954
  ```ts
946
955
  const time = z.string().time();
947
956
 
948
957
  time.parse("00:00:00"); // pass
949
958
  time.parse("09:52:31"); // pass
959
+ time.parse("09:52"); // pass
950
960
  time.parse("23:59:59.9999999"); // pass (arbitrary precision)
951
961
 
952
962
  time.parse("00:00:00.123Z"); // fail (no `Z` allowed)
@@ -961,6 +971,7 @@ const time = z.string().time({ precision: 3 });
961
971
  time.parse("00:00:00.123"); // pass
962
972
  time.parse("00:00:00.123456"); // fail
963
973
  time.parse("00:00:00"); // fail
974
+ time.parse("00:00"); // fail
964
975
  ```
965
976
 
966
977
  ### IP addresses
@@ -2551,8 +2562,8 @@ numberWithRandomDefault.parse(undefined); // => 0.7223408162401552
2551
2562
 
2552
2563
  Conceptually, this is how Zod processes default values:
2553
2564
 
2554
- 1. If the input is `undefined`, the default value is returned
2555
- 2. Otherwise, the data is parsed using the base schema
2565
+ 1. If the input is `undefined`, the default value is substituted
2566
+ 2. Then the data is parsed using the base schema. Your default value will be parsed by the schema (including any potential transforms).
2556
2567
 
2557
2568
  ### `.describe`
2558
2569
 
package/lib/index.mjs CHANGED
@@ -961,15 +961,15 @@ const base64urlRegex = /^([0-9a-zA-Z-_]{4})*(([0-9a-zA-Z-_]{2}(==)?)|([0-9a-zA-Z
961
961
  const dateRegexSource = `((\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-((0[13578]|1[02])-(0[1-9]|[12]\\d|3[01])|(0[469]|11)-(0[1-9]|[12]\\d|30)|(02)-(0[1-9]|1\\d|2[0-8])))`;
962
962
  const dateRegex = new RegExp(`^${dateRegexSource}$`);
963
963
  function timeRegexSource(args) {
964
- // let regex = `\\d{2}:\\d{2}:\\d{2}`;
965
- let regex = `([01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d`;
964
+ let secondsRegexSource = `[0-5]\\d`;
966
965
  if (args.precision) {
967
- regex = `${regex}\\.\\d{${args.precision}}`;
966
+ secondsRegexSource = `${secondsRegexSource}\\.\\d{${args.precision}}`;
968
967
  }
969
968
  else if (args.precision == null) {
970
- regex = `${regex}(\\.\\d+)?`;
969
+ secondsRegexSource = `${secondsRegexSource}(\\.\\d+)?`;
971
970
  }
972
- return regex;
971
+ const secondsQuantifier = args.precision ? "+" : "?"; // require seconds if precision is nonzero
972
+ return `([01]\\d|2[0-3]):[0-5]\\d(:${secondsRegexSource})${secondsQuantifier}`;
973
973
  }
974
974
  function timeRegex(args) {
975
975
  return new RegExp(`^${timeRegexSource(args)}$`);
package/lib/index.umd.js CHANGED
@@ -967,15 +967,15 @@
967
967
  const dateRegexSource = `((\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-((0[13578]|1[02])-(0[1-9]|[12]\\d|3[01])|(0[469]|11)-(0[1-9]|[12]\\d|30)|(02)-(0[1-9]|1\\d|2[0-8])))`;
968
968
  const dateRegex = new RegExp(`^${dateRegexSource}$`);
969
969
  function timeRegexSource(args) {
970
- // let regex = `\\d{2}:\\d{2}:\\d{2}`;
971
- let regex = `([01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d`;
970
+ let secondsRegexSource = `[0-5]\\d`;
972
971
  if (args.precision) {
973
- regex = `${regex}\\.\\d{${args.precision}}`;
972
+ secondsRegexSource = `${secondsRegexSource}\\.\\d{${args.precision}}`;
974
973
  }
975
974
  else if (args.precision == null) {
976
- regex = `${regex}(\\.\\d+)?`;
975
+ secondsRegexSource = `${secondsRegexSource}(\\.\\d+)?`;
977
976
  }
978
- return regex;
977
+ const secondsQuantifier = args.precision ? "+" : "?"; // require seconds if precision is nonzero
978
+ return `([01]\\d|2[0-3]):[0-5]\\d(:${secondsRegexSource})${secondsQuantifier}`;
979
979
  }
980
980
  function timeRegex(args) {
981
981
  return new RegExp(`^${timeRegexSource(args)}$`);
package/lib/types.js CHANGED
@@ -432,15 +432,15 @@ const base64urlRegex = /^([0-9a-zA-Z-_]{4})*(([0-9a-zA-Z-_]{2}(==)?)|([0-9a-zA-Z
432
432
  const dateRegexSource = `((\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-((0[13578]|1[02])-(0[1-9]|[12]\\d|3[01])|(0[469]|11)-(0[1-9]|[12]\\d|30)|(02)-(0[1-9]|1\\d|2[0-8])))`;
433
433
  const dateRegex = new RegExp(`^${dateRegexSource}$`);
434
434
  function timeRegexSource(args) {
435
- // let regex = `\\d{2}:\\d{2}:\\d{2}`;
436
- let regex = `([01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d`;
435
+ let secondsRegexSource = `[0-5]\\d`;
437
436
  if (args.precision) {
438
- regex = `${regex}\\.\\d{${args.precision}}`;
437
+ secondsRegexSource = `${secondsRegexSource}\\.\\d{${args.precision}}`;
439
438
  }
440
439
  else if (args.precision == null) {
441
- regex = `${regex}(\\.\\d+)?`;
440
+ secondsRegexSource = `${secondsRegexSource}(\\.\\d+)?`;
442
441
  }
443
- return regex;
442
+ const secondsQuantifier = args.precision ? "+" : "?"; // require seconds if precision is nonzero
443
+ return `([01]\\d|2[0-3]):[0-5]\\d(:${secondsRegexSource})${secondsQuantifier}`;
444
444
  }
445
445
  function timeRegex(args) {
446
446
  return new RegExp(`^${timeRegexSource(args)}$`);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "zod",
3
- "version": "3.24.3",
3
+ "version": "3.24.4",
4
4
  "author": "Colin McDonnell <colin@colinhacks.com>",
5
5
  "repository": {
6
6
  "type": "git",
@@ -43,7 +43,7 @@
43
43
  "ts-morph": "^14.0.0",
44
44
  "ts-node": "^10.9.1",
45
45
  "tslib": "^2.3.1",
46
- "tsx": "^3.8.0",
46
+ "tsx": "^4.19.4",
47
47
  "typescript": "^5.0.0",
48
48
  "vitest": "^0.32.2"
49
49
  },