zod 3.26.0-canary.20250703T011142 → 3.26.0-canary.20250703T025502

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.
Files changed (269) hide show
  1. package/package.json +4 -4
  2. package/src/index.ts +4 -0
  3. package/src/v3/ZodError.ts +330 -0
  4. package/src/v3/benchmarks/datetime.ts +58 -0
  5. package/src/v3/benchmarks/discriminatedUnion.ts +80 -0
  6. package/src/v3/benchmarks/index.ts +59 -0
  7. package/src/v3/benchmarks/ipv4.ts +57 -0
  8. package/src/v3/benchmarks/object.ts +69 -0
  9. package/src/v3/benchmarks/primitives.ts +162 -0
  10. package/src/v3/benchmarks/realworld.ts +63 -0
  11. package/src/v3/benchmarks/string.ts +55 -0
  12. package/src/v3/benchmarks/union.ts +80 -0
  13. package/src/v3/errors.ts +13 -0
  14. package/src/v3/external.ts +6 -0
  15. package/src/v3/helpers/enumUtil.ts +17 -0
  16. package/src/v3/helpers/errorUtil.ts +8 -0
  17. package/src/v3/helpers/parseUtil.ts +176 -0
  18. package/src/v3/helpers/partialUtil.ts +34 -0
  19. package/src/v3/helpers/typeAliases.ts +2 -0
  20. package/src/v3/helpers/util.ts +224 -0
  21. package/src/v3/index.ts +4 -0
  22. package/src/v3/locales/en.ts +124 -0
  23. package/src/v3/standard-schema.ts +113 -0
  24. package/src/v3/tests/Mocker.ts +54 -0
  25. package/src/v3/tests/all-errors.test.ts +157 -0
  26. package/src/v3/tests/anyunknown.test.ts +28 -0
  27. package/src/v3/tests/array.test.ts +71 -0
  28. package/src/v3/tests/async-parsing.test.ts +388 -0
  29. package/src/v3/tests/async-refinements.test.ts +46 -0
  30. package/src/v3/tests/base.test.ts +29 -0
  31. package/src/v3/tests/bigint.test.ts +55 -0
  32. package/src/v3/tests/branded.test.ts +53 -0
  33. package/src/v3/tests/catch.test.ts +220 -0
  34. package/src/v3/tests/coerce.test.ts +133 -0
  35. package/src/v3/tests/complex.test.ts +56 -0
  36. package/src/v3/tests/custom.test.ts +31 -0
  37. package/src/v3/tests/date.test.ts +32 -0
  38. package/src/v3/tests/deepmasking.test.ts +186 -0
  39. package/src/v3/tests/default.test.ts +112 -0
  40. package/src/v3/tests/description.test.ts +33 -0
  41. package/src/v3/tests/discriminated-unions.test.ts +315 -0
  42. package/src/v3/tests/enum.test.ts +80 -0
  43. package/src/v3/tests/error.test.ts +551 -0
  44. package/src/v3/tests/firstparty.test.ts +87 -0
  45. package/src/v3/tests/firstpartyschematypes.test.ts +21 -0
  46. package/src/v3/tests/function.test.ts +257 -0
  47. package/src/v3/tests/generics.test.ts +48 -0
  48. package/src/v3/tests/instanceof.test.ts +37 -0
  49. package/src/v3/tests/intersection.test.ts +110 -0
  50. package/src/v3/tests/language-server.source.ts +76 -0
  51. package/src/v3/tests/language-server.test.ts +207 -0
  52. package/src/v3/tests/literal.test.ts +36 -0
  53. package/src/v3/tests/map.test.ts +110 -0
  54. package/src/v3/tests/masking.test.ts +4 -0
  55. package/src/v3/tests/mocker.test.ts +19 -0
  56. package/src/v3/tests/nan.test.ts +21 -0
  57. package/src/v3/tests/nativeEnum.test.ts +87 -0
  58. package/src/v3/tests/nullable.test.ts +42 -0
  59. package/src/v3/tests/number.test.ts +176 -0
  60. package/src/v3/tests/object-augmentation.test.ts +29 -0
  61. package/src/v3/tests/object-in-es5-env.test.ts +29 -0
  62. package/src/v3/tests/object.test.ts +434 -0
  63. package/src/v3/tests/optional.test.ts +42 -0
  64. package/src/v3/tests/parseUtil.test.ts +23 -0
  65. package/src/v3/tests/parser.test.ts +41 -0
  66. package/src/v3/tests/partials.test.ts +243 -0
  67. package/src/v3/tests/pickomit.test.ts +111 -0
  68. package/src/v3/tests/pipeline.test.ts +29 -0
  69. package/src/v3/tests/preprocess.test.ts +186 -0
  70. package/src/v3/tests/primitive.test.ts +440 -0
  71. package/src/v3/tests/promise.test.ts +90 -0
  72. package/src/v3/tests/readonly.test.ts +194 -0
  73. package/src/v3/tests/record.test.ts +171 -0
  74. package/src/v3/tests/recursive.test.ts +197 -0
  75. package/src/v3/tests/refine.test.ts +313 -0
  76. package/src/v3/tests/safeparse.test.ts +27 -0
  77. package/src/v3/tests/set.test.ts +142 -0
  78. package/src/v3/tests/standard-schema.test.ts +83 -0
  79. package/src/v3/tests/string.test.ts +916 -0
  80. package/src/v3/tests/transformer.test.ts +233 -0
  81. package/src/v3/tests/tuple.test.ts +90 -0
  82. package/src/v3/tests/unions.test.ts +57 -0
  83. package/src/v3/tests/validations.test.ts +133 -0
  84. package/src/v3/tests/void.test.ts +15 -0
  85. package/src/v3/types.ts +5136 -0
  86. package/src/v4/classic/checks.ts +30 -0
  87. package/src/v4/classic/coerce.ts +27 -0
  88. package/src/v4/classic/compat.ts +66 -0
  89. package/src/v4/classic/errors.ts +75 -0
  90. package/src/v4/classic/external.ts +50 -0
  91. package/src/v4/classic/index.ts +5 -0
  92. package/src/v4/classic/iso.ts +90 -0
  93. package/src/v4/classic/parse.ts +33 -0
  94. package/src/v4/classic/schemas.ts +2055 -0
  95. package/src/v4/classic/tests/anyunknown.test.ts +26 -0
  96. package/src/v4/classic/tests/array.test.ts +264 -0
  97. package/src/v4/classic/tests/assignability.test.ts +210 -0
  98. package/src/v4/classic/tests/async-parsing.test.ts +381 -0
  99. package/src/v4/classic/tests/async-refinements.test.ts +68 -0
  100. package/src/v4/classic/tests/base.test.ts +7 -0
  101. package/src/v4/classic/tests/bigint.test.ts +54 -0
  102. package/src/v4/classic/tests/brand.test.ts +65 -0
  103. package/src/v4/classic/tests/catch.test.ts +252 -0
  104. package/src/v4/classic/tests/coalesce.test.ts +20 -0
  105. package/src/v4/classic/tests/coerce.test.ts +160 -0
  106. package/src/v4/classic/tests/continuability.test.ts +352 -0
  107. package/src/v4/classic/tests/custom.test.ts +40 -0
  108. package/src/v4/classic/tests/date.test.ts +31 -0
  109. package/src/v4/classic/tests/datetime.test.ts +296 -0
  110. package/src/v4/classic/tests/default.test.ts +313 -0
  111. package/src/v4/classic/tests/description.test.ts +32 -0
  112. package/src/v4/classic/tests/discriminated-unions.test.ts +592 -0
  113. package/src/v4/classic/tests/enum.test.ts +285 -0
  114. package/src/v4/classic/tests/error-utils.test.ts +527 -0
  115. package/src/v4/classic/tests/error.test.ts +711 -0
  116. package/src/v4/classic/tests/file.test.ts +91 -0
  117. package/src/v4/classic/tests/firstparty.test.ts +175 -0
  118. package/src/v4/classic/tests/function.test.ts +268 -0
  119. package/src/v4/classic/tests/generics.test.ts +72 -0
  120. package/src/v4/classic/tests/index.test.ts +829 -0
  121. package/src/v4/classic/tests/instanceof.test.ts +34 -0
  122. package/src/v4/classic/tests/intersection.test.ts +171 -0
  123. package/src/v4/classic/tests/json.test.ts +108 -0
  124. package/src/v4/classic/tests/lazy.test.ts +227 -0
  125. package/src/v4/classic/tests/literal.test.ts +92 -0
  126. package/src/v4/classic/tests/map.test.ts +196 -0
  127. package/src/v4/classic/tests/nan.test.ts +21 -0
  128. package/src/v4/classic/tests/nested-refine.test.ts +168 -0
  129. package/src/v4/classic/tests/nonoptional.test.ts +86 -0
  130. package/src/v4/classic/tests/nullable.test.ts +22 -0
  131. package/src/v4/classic/tests/number.test.ts +247 -0
  132. package/src/v4/classic/tests/object.test.ts +553 -0
  133. package/src/v4/classic/tests/optional.test.ts +103 -0
  134. package/src/v4/classic/tests/partial.test.ts +147 -0
  135. package/src/v4/classic/tests/pickomit.test.ts +127 -0
  136. package/src/v4/classic/tests/pipe.test.ts +81 -0
  137. package/src/v4/classic/tests/prefault.test.ts +37 -0
  138. package/src/v4/classic/tests/preprocess.test.ts +298 -0
  139. package/src/v4/classic/tests/primitive.test.ts +175 -0
  140. package/src/v4/classic/tests/promise.test.ts +81 -0
  141. package/src/v4/classic/tests/prototypes.test.ts +23 -0
  142. package/src/v4/classic/tests/readonly.test.ts +252 -0
  143. package/src/v4/classic/tests/record.test.ts +332 -0
  144. package/src/v4/classic/tests/recursive-types.test.ts +325 -0
  145. package/src/v4/classic/tests/refine.test.ts +423 -0
  146. package/src/v4/classic/tests/registries.test.ts +195 -0
  147. package/src/v4/classic/tests/set.test.ts +179 -0
  148. package/src/v4/classic/tests/standard-schema.test.ts +57 -0
  149. package/src/v4/classic/tests/string-formats.test.ts +109 -0
  150. package/src/v4/classic/tests/string.test.ts +881 -0
  151. package/src/v4/classic/tests/stringbool.test.ts +66 -0
  152. package/src/v4/classic/tests/template-literal.test.ts +758 -0
  153. package/src/v4/classic/tests/to-json-schema.test.ts +2182 -0
  154. package/src/v4/classic/tests/transform.test.ts +250 -0
  155. package/src/v4/classic/tests/tuple.test.ts +163 -0
  156. package/src/v4/classic/tests/union.test.ts +94 -0
  157. package/src/v4/classic/tests/validations.test.ts +283 -0
  158. package/src/v4/classic/tests/void.test.ts +12 -0
  159. package/src/v4/core/api.ts +1592 -0
  160. package/src/v4/core/checks.ts +1285 -0
  161. package/src/v4/core/config.ts +15 -0
  162. package/src/v4/core/core.ts +134 -0
  163. package/src/v4/core/doc.ts +44 -0
  164. package/src/v4/core/errors.ts +420 -0
  165. package/src/v4/core/function.ts +176 -0
  166. package/src/v4/core/index.ts +15 -0
  167. package/src/v4/core/json-schema.ts +143 -0
  168. package/src/v4/core/parse.ts +94 -0
  169. package/src/v4/core/regexes.ts +135 -0
  170. package/src/v4/core/registries.ts +86 -0
  171. package/src/v4/core/schemas.ts +3781 -0
  172. package/src/v4/core/standard-schema.ts +64 -0
  173. package/src/v4/core/tests/index.test.ts +46 -0
  174. package/src/v4/core/tests/locales/be.test.ts +124 -0
  175. package/src/v4/core/tests/locales/en.test.ts +22 -0
  176. package/src/v4/core/tests/locales/ru.test.ts +128 -0
  177. package/src/v4/core/tests/locales/tr.test.ts +69 -0
  178. package/src/v4/core/to-json-schema.ts +944 -0
  179. package/src/v4/core/util.ts +775 -0
  180. package/src/v4/core/versions.ts +5 -0
  181. package/src/v4/core/zsf.ts +323 -0
  182. package/src/v4/index.ts +4 -0
  183. package/src/v4/locales/ar.ts +125 -0
  184. package/src/v4/locales/az.ts +121 -0
  185. package/src/v4/locales/be.ts +184 -0
  186. package/src/v4/locales/ca.ts +127 -0
  187. package/src/v4/locales/cs.ts +142 -0
  188. package/src/v4/locales/de.ts +124 -0
  189. package/src/v4/locales/en.ts +127 -0
  190. package/src/v4/locales/es.ts +125 -0
  191. package/src/v4/locales/fa.ts +134 -0
  192. package/src/v4/locales/fi.ts +131 -0
  193. package/src/v4/locales/fr-CA.ts +126 -0
  194. package/src/v4/locales/fr.ts +124 -0
  195. package/src/v4/locales/he.ts +125 -0
  196. package/src/v4/locales/hu.ts +126 -0
  197. package/src/v4/locales/id.ts +125 -0
  198. package/src/v4/locales/index.ts +38 -0
  199. package/src/v4/locales/it.ts +125 -0
  200. package/src/v4/locales/ja.ts +122 -0
  201. package/src/v4/locales/kh.ts +126 -0
  202. package/src/v4/locales/ko.ts +131 -0
  203. package/src/v4/locales/mk.ts +127 -0
  204. package/src/v4/locales/ms.ts +124 -0
  205. package/src/v4/locales/nl.ts +126 -0
  206. package/src/v4/locales/no.ts +124 -0
  207. package/src/v4/locales/ota.ts +125 -0
  208. package/src/v4/locales/pl.ts +126 -0
  209. package/src/v4/locales/ps.ts +133 -0
  210. package/src/v4/locales/pt.ts +123 -0
  211. package/src/v4/locales/ru.ts +184 -0
  212. package/src/v4/locales/sl.ts +126 -0
  213. package/src/v4/locales/sv.ts +127 -0
  214. package/src/v4/locales/ta.ts +125 -0
  215. package/src/v4/locales/th.ts +126 -0
  216. package/src/v4/locales/tr.ts +121 -0
  217. package/src/v4/locales/ua.ts +126 -0
  218. package/src/v4/locales/ur.ts +126 -0
  219. package/src/v4/locales/vi.ts +125 -0
  220. package/src/v4/locales/zh-CN.ts +123 -0
  221. package/src/v4/locales/zh-TW.ts +125 -0
  222. package/src/v4/mini/checks.ts +32 -0
  223. package/src/v4/mini/coerce.ts +22 -0
  224. package/src/v4/mini/external.ts +40 -0
  225. package/src/v4/mini/index.ts +3 -0
  226. package/src/v4/mini/iso.ts +62 -0
  227. package/src/v4/mini/parse.ts +1 -0
  228. package/src/v4/mini/schemas.ts +1579 -0
  229. package/src/v4/mini/tests/assignability.test.ts +129 -0
  230. package/src/v4/mini/tests/brand.test.ts +51 -0
  231. package/src/v4/mini/tests/checks.test.ts +144 -0
  232. package/src/v4/mini/tests/computed.test.ts +36 -0
  233. package/src/v4/mini/tests/error.test.ts +22 -0
  234. package/src/v4/mini/tests/functions.test.ts +43 -0
  235. package/src/v4/mini/tests/index.test.ts +871 -0
  236. package/src/v4/mini/tests/number.test.ts +95 -0
  237. package/src/v4/mini/tests/object.test.ts +185 -0
  238. package/src/v4/mini/tests/prototypes.test.ts +43 -0
  239. package/src/v4/mini/tests/recursive-types.test.ts +275 -0
  240. package/src/v4/mini/tests/string.test.ts +293 -0
  241. package/src/v4-mini/index.ts +1 -0
  242. package/v4/classic/compat.cjs +1 -7
  243. package/v4/classic/compat.d.cts +0 -2
  244. package/v4/classic/compat.d.ts +0 -2
  245. package/v4/classic/compat.js +0 -6
  246. package/v4/classic/external.cjs +2 -1
  247. package/v4/classic/external.d.cts +1 -1
  248. package/v4/classic/external.d.ts +1 -1
  249. package/v4/classic/external.js +1 -1
  250. package/v4/classic/schemas.d.cts +4 -4
  251. package/v4/classic/schemas.d.ts +4 -4
  252. package/v4/core/api.cjs +11 -10
  253. package/v4/core/api.js +11 -10
  254. package/v4/core/checks.cjs +6 -4
  255. package/v4/core/checks.js +6 -4
  256. package/v4/core/core.cjs +5 -1
  257. package/v4/core/core.d.cts +2 -0
  258. package/v4/core/core.d.ts +2 -0
  259. package/v4/core/core.js +4 -0
  260. package/v4/core/schemas.cjs +12 -13
  261. package/v4/core/schemas.js +12 -13
  262. package/v4/core/util.cjs +3 -0
  263. package/v4/core/util.d.cts +1 -1
  264. package/v4/core/util.d.ts +1 -1
  265. package/v4/core/util.js +3 -0
  266. package/v4/mini/external.cjs +2 -1
  267. package/v4/mini/external.d.cts +1 -1
  268. package/v4/mini/external.d.ts +1 -1
  269. package/v4/mini/external.js +1 -1
@@ -0,0 +1,233 @@
1
+ // @ts-ignore TS6133
2
+ import { expect, test } from "vitest";
3
+
4
+ import * as z from "zod/v3";
5
+ import { util } from "../helpers/util.js";
6
+
7
+ const stringToNumber = z.string().transform((arg) => Number.parseFloat(arg));
8
+ // const numberToString = z
9
+ // .transformer(z.number())
10
+ // .transform((n) => String(n));
11
+ const asyncNumberToString = z.number().transform(async (n) => String(n));
12
+
13
+ test("transform ctx.addIssue with parse", () => {
14
+ const strs = ["foo", "bar"];
15
+
16
+ expect(() => {
17
+ z.string()
18
+ .transform((data, ctx) => {
19
+ const i = strs.indexOf(data);
20
+ if (i === -1) {
21
+ ctx.addIssue({
22
+ code: "custom",
23
+ message: `${data} is not one of our allowed strings`,
24
+ });
25
+ }
26
+ return data.length;
27
+ })
28
+ .parse("asdf");
29
+ }).toThrow(
30
+ JSON.stringify(
31
+ [
32
+ {
33
+ code: "custom",
34
+ message: "asdf is not one of our allowed strings",
35
+ path: [],
36
+ },
37
+ ],
38
+ null,
39
+ 2
40
+ )
41
+ );
42
+ });
43
+
44
+ test("transform ctx.addIssue with parseAsync", async () => {
45
+ const strs = ["foo", "bar"];
46
+
47
+ const result = await z
48
+ .string()
49
+ .transform(async (data, ctx) => {
50
+ const i = strs.indexOf(data);
51
+ if (i === -1) {
52
+ ctx.addIssue({
53
+ code: "custom",
54
+ message: `${data} is not one of our allowed strings`,
55
+ });
56
+ }
57
+ return data.length;
58
+ })
59
+ .safeParseAsync("asdf");
60
+
61
+ expect(JSON.parse(JSON.stringify(result))).toEqual({
62
+ success: false,
63
+ error: {
64
+ issues: [
65
+ {
66
+ code: "custom",
67
+ message: "asdf is not one of our allowed strings",
68
+ path: [],
69
+ },
70
+ ],
71
+ name: "ZodError",
72
+ },
73
+ });
74
+ });
75
+
76
+ test("z.NEVER in transform", () => {
77
+ const foo = z
78
+ .number()
79
+ .optional()
80
+ .transform((val, ctx) => {
81
+ if (!val) {
82
+ ctx.addIssue({ code: z.ZodIssueCode.custom, message: "bad" });
83
+ return z.NEVER;
84
+ }
85
+ return val;
86
+ });
87
+ type foo = z.infer<typeof foo>;
88
+ util.assertEqual<foo, number>(true);
89
+ const arg = foo.safeParse(undefined);
90
+ if (!arg.success) {
91
+ expect(arg.error.issues[0].message).toEqual("bad");
92
+ }
93
+ });
94
+
95
+ test("basic transformations", () => {
96
+ const r1 = z
97
+ .string()
98
+ .transform((data) => data.length)
99
+ .parse("asdf");
100
+ expect(r1).toEqual(4);
101
+ });
102
+
103
+ test("coercion", () => {
104
+ const numToString = z.number().transform((n) => String(n));
105
+ const data = z
106
+ .object({
107
+ id: numToString,
108
+ })
109
+ .parse({ id: 5 });
110
+
111
+ expect(data).toEqual({ id: "5" });
112
+ });
113
+
114
+ test("async coercion", async () => {
115
+ const numToString = z.number().transform(async (n) => String(n));
116
+ const data = await z
117
+ .object({
118
+ id: numToString,
119
+ })
120
+ .parseAsync({ id: 5 });
121
+
122
+ expect(data).toEqual({ id: "5" });
123
+ });
124
+
125
+ test("sync coercion async error", async () => {
126
+ expect(() =>
127
+ z
128
+ .object({
129
+ id: asyncNumberToString,
130
+ })
131
+ .parse({ id: 5 })
132
+ ).toThrow();
133
+ // expect(data).toEqual({ id: '5' });
134
+ });
135
+
136
+ test("default", () => {
137
+ const data = z.string().default("asdf").parse(undefined); // => "asdf"
138
+ expect(data).toEqual("asdf");
139
+ });
140
+
141
+ test("dynamic default", () => {
142
+ const data = z
143
+ .string()
144
+ .default(() => "string")
145
+ .parse(undefined); // => "asdf"
146
+ expect(data).toEqual("string");
147
+ });
148
+
149
+ test("default when property is null or undefined", () => {
150
+ const data = z
151
+ .object({
152
+ foo: z.boolean().nullable().default(true),
153
+ bar: z.boolean().default(true),
154
+ })
155
+ .parse({ foo: null });
156
+
157
+ expect(data).toEqual({ foo: null, bar: true });
158
+ });
159
+
160
+ test("default with falsy values", () => {
161
+ const schema = z.object({
162
+ emptyStr: z.string().default("def"),
163
+ zero: z.number().default(5),
164
+ falseBoolean: z.boolean().default(true),
165
+ });
166
+ const input = { emptyStr: "", zero: 0, falseBoolean: true };
167
+ const output = schema.parse(input);
168
+ // defaults are not supposed to be used
169
+ expect(output).toEqual(input);
170
+ });
171
+
172
+ test("object typing", () => {
173
+ const t1 = z.object({
174
+ stringToNumber,
175
+ });
176
+
177
+ type t1 = z.input<typeof t1>;
178
+ type t2 = z.output<typeof t1>;
179
+
180
+ util.assertEqual<t1, { stringToNumber: string }>(true);
181
+ util.assertEqual<t2, { stringToNumber: number }>(true);
182
+ });
183
+
184
+ test("transform method overloads", () => {
185
+ const t1 = z.string().transform((val) => val.toUpperCase());
186
+ expect(t1.parse("asdf")).toEqual("ASDF");
187
+
188
+ const t2 = z.string().transform((val) => val.length);
189
+ expect(t2.parse("asdf")).toEqual(4);
190
+ });
191
+
192
+ test("multiple transformers", () => {
193
+ const doubler = stringToNumber.transform((val) => {
194
+ return val * 2;
195
+ });
196
+ expect(doubler.parse("5")).toEqual(10);
197
+ });
198
+
199
+ test("short circuit on dirty", () => {
200
+ const schema = z
201
+ .string()
202
+ .refine(() => false)
203
+ .transform((val) => val.toUpperCase());
204
+ const result = schema.safeParse("asdf");
205
+ expect(result.success).toEqual(false);
206
+ if (!result.success) {
207
+ expect(result.error.issues[0].code).toEqual(z.ZodIssueCode.custom);
208
+ }
209
+
210
+ const result2 = schema.safeParse(1234);
211
+ expect(result2.success).toEqual(false);
212
+ if (!result2.success) {
213
+ expect(result2.error.issues[0].code).toEqual(z.ZodIssueCode.invalid_type);
214
+ }
215
+ });
216
+
217
+ test("async short circuit on dirty", async () => {
218
+ const schema = z
219
+ .string()
220
+ .refine(() => false)
221
+ .transform((val) => val.toUpperCase());
222
+ const result = await schema.spa("asdf");
223
+ expect(result.success).toEqual(false);
224
+ if (!result.success) {
225
+ expect(result.error.issues[0].code).toEqual(z.ZodIssueCode.custom);
226
+ }
227
+
228
+ const result2 = await schema.spa(1234);
229
+ expect(result2.success).toEqual(false);
230
+ if (!result2.success) {
231
+ expect(result2.error.issues[0].code).toEqual(z.ZodIssueCode.invalid_type);
232
+ }
233
+ });
@@ -0,0 +1,90 @@
1
+ // @ts-ignore TS6133
2
+ import { expect, test } from "vitest";
3
+
4
+ import * as z from "zod/v3";
5
+ import { ZodError } from "../ZodError.js";
6
+ import { util } from "../helpers/util.js";
7
+
8
+ const testTuple = z.tuple([z.string(), z.object({ name: z.literal("Rudy") }), z.array(z.literal("blue"))]);
9
+ const testData = ["asdf", { name: "Rudy" }, ["blue"]];
10
+ const badData = [123, { name: "Rudy2" }, ["blue", "red"]];
11
+
12
+ test("tuple inference", () => {
13
+ const args1 = z.tuple([z.string()]);
14
+ const returns1 = z.number();
15
+ const func1 = z.function(args1, returns1);
16
+ type func1 = z.TypeOf<typeof func1>;
17
+ util.assertEqual<func1, (k: string) => number>(true);
18
+ });
19
+
20
+ test("successful validation", () => {
21
+ const val = testTuple.parse(testData);
22
+ expect(val).toEqual(["asdf", { name: "Rudy" }, ["blue"]]);
23
+ });
24
+
25
+ test("successful async validation", async () => {
26
+ const val = await testTuple.parseAsync(testData);
27
+ return expect(val).toEqual(testData);
28
+ });
29
+
30
+ test("failed validation", () => {
31
+ const checker = () => {
32
+ testTuple.parse([123, { name: "Rudy2" }, ["blue", "red"]] as any);
33
+ };
34
+ try {
35
+ checker();
36
+ } catch (err) {
37
+ if (err instanceof ZodError) {
38
+ expect(err.issues.length).toEqual(3);
39
+ }
40
+ }
41
+ });
42
+
43
+ test("failed async validation", async () => {
44
+ const res = await testTuple.safeParse(badData);
45
+ expect(res.success).toEqual(false);
46
+ if (!res.success) {
47
+ expect(res.error.issues.length).toEqual(3);
48
+ }
49
+ // try {
50
+ // checker();
51
+ // } catch (err) {
52
+ // if (err instanceof ZodError) {
53
+ // expect(err.issues.length).toEqual(3);
54
+ // }
55
+ // }
56
+ });
57
+
58
+ test("tuple with transformers", () => {
59
+ const stringToNumber = z.string().transform((val) => val.length);
60
+ const val = z.tuple([stringToNumber]);
61
+
62
+ type t1 = z.input<typeof val>;
63
+ util.assertEqual<t1, [string]>(true);
64
+ type t2 = z.output<typeof val>;
65
+ util.assertEqual<t2, [number]>(true);
66
+ expect(val.parse(["1234"])).toEqual([4]);
67
+ });
68
+
69
+ test("tuple with rest schema", () => {
70
+ const myTuple = z.tuple([z.string(), z.number()]).rest(z.boolean());
71
+ expect(myTuple.parse(["asdf", 1234, true, false, true])).toEqual(["asdf", 1234, true, false, true]);
72
+
73
+ expect(myTuple.parse(["asdf", 1234])).toEqual(["asdf", 1234]);
74
+
75
+ expect(() => myTuple.parse(["asdf", 1234, "asdf"])).toThrow();
76
+ type t1 = z.output<typeof myTuple>;
77
+
78
+ util.assertEqual<t1, [string, number, ...boolean[]]>(true);
79
+ });
80
+
81
+ test("parse should fail given sparse array as tuple", () => {
82
+ expect(() => testTuple.parse(new Array(3))).toThrow();
83
+ });
84
+
85
+ // test('tuple with optional elements', () => {
86
+ // const result = z
87
+ // .tuple([z.string(), z.number().optional()])
88
+ // .safeParse(['asdf']);
89
+ // expect(result).toEqual(['asdf']);
90
+ // });
@@ -0,0 +1,57 @@
1
+ // @ts-ignore TS6133
2
+ import { expect, test } from "vitest";
3
+
4
+ import * as z from "zod/v3";
5
+
6
+ test("function parsing", () => {
7
+ const schema = z.union([z.string().refine(() => false), z.number().refine(() => false)]);
8
+ const result = schema.safeParse("asdf");
9
+ expect(result.success).toEqual(false);
10
+ });
11
+
12
+ test("union 2", () => {
13
+ const result = z.union([z.number(), z.string().refine(() => false)]).safeParse("a");
14
+ expect(result.success).toEqual(false);
15
+ });
16
+
17
+ test("return valid over invalid", () => {
18
+ const schema = z.union([
19
+ z.object({
20
+ email: z.string().email(),
21
+ }),
22
+ z.string(),
23
+ ]);
24
+ expect(schema.parse("asdf")).toEqual("asdf");
25
+ expect(schema.parse({ email: "asdlkjf@lkajsdf.com" })).toEqual({
26
+ email: "asdlkjf@lkajsdf.com",
27
+ });
28
+ });
29
+
30
+ test("return dirty result over aborted", () => {
31
+ const result = z.union([z.number(), z.string().refine(() => false)]).safeParse("a");
32
+ expect(result.success).toEqual(false);
33
+ if (!result.success) {
34
+ expect(result.error.issues).toEqual([
35
+ {
36
+ code: "custom",
37
+ message: "Invalid input",
38
+ path: [],
39
+ },
40
+ ]);
41
+ }
42
+ });
43
+
44
+ test("options getter", async () => {
45
+ const union = z.union([z.string(), z.number()]);
46
+ union.options[0].parse("asdf");
47
+ union.options[1].parse(1234);
48
+ await union.options[0].parseAsync("asdf");
49
+ await union.options[1].parseAsync(1234);
50
+ });
51
+
52
+ test("readonly union", async () => {
53
+ const options = [z.string(), z.number()] as const;
54
+ const union = z.union(options);
55
+ union.parse("asdf");
56
+ union.parse(12);
57
+ });
@@ -0,0 +1,133 @@
1
+ // @ts-ignore TS6133
2
+ import { expect, test } from "vitest";
3
+
4
+ import * as z from "zod/v3";
5
+
6
+ test("array min", async () => {
7
+ try {
8
+ await z.array(z.string()).min(4).parseAsync([]);
9
+ } catch (err) {
10
+ expect((err as z.ZodError).issues[0].message).toEqual("Array must contain at least 4 element(s)");
11
+ }
12
+ });
13
+
14
+ test("array max", async () => {
15
+ try {
16
+ await z.array(z.string()).max(2).parseAsync(["asdf", "asdf", "asdf"]);
17
+ } catch (err) {
18
+ expect((err as z.ZodError).issues[0].message).toEqual("Array must contain at most 2 element(s)");
19
+ }
20
+ });
21
+
22
+ test("array length", async () => {
23
+ try {
24
+ await z.array(z.string()).length(2).parseAsync(["asdf", "asdf", "asdf"]);
25
+ } catch (err) {
26
+ expect((err as z.ZodError).issues[0].message).toEqual("Array must contain exactly 2 element(s)");
27
+ }
28
+
29
+ try {
30
+ await z.array(z.string()).length(2).parseAsync(["asdf"]);
31
+ } catch (err) {
32
+ expect((err as z.ZodError).issues[0].message).toEqual("Array must contain exactly 2 element(s)");
33
+ }
34
+ });
35
+
36
+ test("string length", async () => {
37
+ try {
38
+ await z.string().length(4).parseAsync("asd");
39
+ } catch (err) {
40
+ expect((err as z.ZodError).issues[0].message).toEqual("String must contain exactly 4 character(s)");
41
+ }
42
+
43
+ try {
44
+ await z.string().length(4).parseAsync("asdaa");
45
+ } catch (err) {
46
+ expect((err as z.ZodError).issues[0].message).toEqual("String must contain exactly 4 character(s)");
47
+ }
48
+ });
49
+
50
+ test("string min", async () => {
51
+ try {
52
+ await z.string().min(4).parseAsync("asd");
53
+ } catch (err) {
54
+ expect((err as z.ZodError).issues[0].message).toEqual("String must contain at least 4 character(s)");
55
+ }
56
+ });
57
+
58
+ test("string max", async () => {
59
+ try {
60
+ await z.string().max(4).parseAsync("aasdfsdfsd");
61
+ } catch (err) {
62
+ expect((err as z.ZodError).issues[0].message).toEqual("String must contain at most 4 character(s)");
63
+ }
64
+ });
65
+
66
+ test("number min", async () => {
67
+ try {
68
+ await z.number().gte(3).parseAsync(2);
69
+ } catch (err) {
70
+ expect((err as z.ZodError).issues[0].message).toEqual("Number must be greater than or equal to 3");
71
+ }
72
+ });
73
+
74
+ test("number max", async () => {
75
+ try {
76
+ await z.number().lte(3).parseAsync(4);
77
+ } catch (err) {
78
+ expect((err as z.ZodError).issues[0].message).toEqual("Number must be less than or equal to 3");
79
+ }
80
+ });
81
+
82
+ test("number nonnegative", async () => {
83
+ try {
84
+ await z.number().nonnegative().parseAsync(-1);
85
+ } catch (err) {
86
+ expect((err as z.ZodError).issues[0].message).toEqual("Number must be greater than or equal to 0");
87
+ }
88
+ });
89
+
90
+ test("number nonpositive", async () => {
91
+ try {
92
+ await z.number().nonpositive().parseAsync(1);
93
+ } catch (err) {
94
+ expect((err as z.ZodError).issues[0].message).toEqual("Number must be less than or equal to 0");
95
+ }
96
+ });
97
+
98
+ test("number negative", async () => {
99
+ try {
100
+ await z.number().negative().parseAsync(1);
101
+ } catch (err) {
102
+ expect((err as z.ZodError).issues[0].message).toEqual("Number must be less than 0");
103
+ }
104
+ });
105
+
106
+ test("number positive", async () => {
107
+ try {
108
+ await z.number().positive().parseAsync(-1);
109
+ } catch (err) {
110
+ expect((err as z.ZodError).issues[0].message).toEqual("Number must be greater than 0");
111
+ }
112
+ });
113
+
114
+ test("instantiation", () => {
115
+ z.string().min(5);
116
+ z.string().max(5);
117
+ z.string().length(5);
118
+ z.string().email();
119
+ z.string().url();
120
+ z.string().uuid();
121
+ z.string().min(5, { message: "Must be 5 or more characters long" });
122
+ z.string().max(5, { message: "Must be 5 or fewer characters long" });
123
+ z.string().length(5, { message: "Must be exactly 5 characters long" });
124
+ z.string().email({ message: "Invalid email address." });
125
+ z.string().url({ message: "Invalid url" });
126
+ z.string().uuid({ message: "Invalid UUID" });
127
+ });
128
+
129
+ test("int", async () => {
130
+ const int = z.number().int();
131
+ int.parse(4);
132
+ expect(() => int.parse(3.5)).toThrow();
133
+ });
@@ -0,0 +1,15 @@
1
+ // @ts-ignore TS6133
2
+ import { expect, test } from "vitest";
3
+
4
+ import * as z from "zod/v3";
5
+ import { util } from "../helpers/util.js";
6
+ test("void", () => {
7
+ const v = z.void();
8
+ v.parse(undefined);
9
+
10
+ expect(() => v.parse(null)).toThrow();
11
+ expect(() => v.parse("")).toThrow();
12
+
13
+ type v = z.infer<typeof v>;
14
+ util.assertEqual<v, void>(true);
15
+ });