zod 3.14.5 → 3.16.0

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
@@ -293,6 +293,9 @@ There are a growing number of tools that are built atop or support Zod natively!
293
293
  - [`fastify-type-provider-zod`](https://github.com/turkerdev/fastify-type-provider-zod): Create Fastify type providers from Zod schemas
294
294
  - [`Supervillain`](https://github.com/Southclaws/supervillain): Generate Zod schemas from your Go structs
295
295
  - [`zod-to-openapi`](https://github.com/asteasolutions/zod-to-openapi): Generate full OpenAPI (Swagger) docs from Zod, including schemas, endpoints & parameters
296
+ - [`prisma-zod-generator`](https://github.com/omar-dulaimi/prisma-zod-generator): Emit Zod schemas from your Prisma schema.
297
+ - [`prisma-trpc-generator`](https://github.com/omar-dulaimi/prisma-trpc-generator): Emit fully implemented tRPC routers and their validation schemas using Zod.
298
+ - [`nestjs-graphql-zod`](https://github.com/incetarik/nestjs-graphql-zod): Generates NestJS GraphQL model classes from Zod schemas dynamically and provides GraphQL method decorators working with Zod schemas.
296
299
 
297
300
  ### Form integrations
298
301
 
@@ -1353,7 +1356,7 @@ All Zod schemas contain certain methods.
1353
1356
 
1354
1357
  Given any Zod schema, you can call its `.parse` method to check `data` is valid. If it is, a value is returned with full type information! Otherwise, an error is thrown.
1355
1358
 
1356
- > IMPORTANT: In Zod 2 and Zod 1.11+, the value returned by `.parse` is a _deep clone_ of the variable you passed in. This was also the case in zod@1.4 and earlier.
1359
+ > IMPORTANT: The value returned by `.parse` is a _deep clone_ of the variable you passed in.
1357
1360
 
1358
1361
  ```ts
1359
1362
  const stringSchema = z.string();
@@ -1602,7 +1605,28 @@ const stringToNumber = z.string().transform((val) => myString.length);
1602
1605
  stringToNumber.parse("string"); // => 6
1603
1606
  ```
1604
1607
 
1605
- > ⚠️ Transform functions must not throw. Make sure to use refinements before the transform to make sure the input can be parsed by the transform.
1608
+ > ⚠️ Transform functions must not throw. Make sure to use refinements before the transform or addIssue within the transform to make sure the input can be parsed by the transform.
1609
+
1610
+ #### Validating during transform
1611
+
1612
+ Similar to `superRefine`, `transform` can optionally take a `ctx`. This allows you to simultaneously
1613
+ validate and transform the value, which can be simpler than chaining `refine` and `validate`.
1614
+ When calling `ctx.addIssue` make sure to still return a value of the correct type otherwise the inferred type will include `undefined`.
1615
+
1616
+ ```ts
1617
+ const Strings = z
1618
+ .string()
1619
+ .transform((val, ctx) => {
1620
+ const parsed = parseInt(val);
1621
+ if (isNaN(parsed)) {
1622
+ ctx.addIssue({
1623
+ code: z.ZodIssueCode.custom,
1624
+ message: "Not a number",
1625
+ });
1626
+ }
1627
+ return parsed;
1628
+ });
1629
+ ```
1606
1630
 
1607
1631
  #### Chaining order
1608
1632
 
package/lib/ZodError.d.ts CHANGED
@@ -54,6 +54,7 @@ export interface ZodInvalidUnionDiscriminatorIssue extends ZodIssueBase {
54
54
  options: Primitive[];
55
55
  }
56
56
  export interface ZodInvalidEnumValueIssue extends ZodIssueBase {
57
+ received: string | number;
57
58
  code: typeof ZodIssueCode.invalid_enum_value;
58
59
  options: (string | number)[];
59
60
  }
@@ -110,7 +111,9 @@ export declare type ZodFormattedError<T, U = string> = {
110
111
  _errors: U[];
111
112
  } & (T extends [any, ...any[]] ? {
112
113
  [K in keyof T]?: ZodFormattedError<T[K]>;
113
- } : T extends any[] ? ZodFormattedError<T[number]>[] : T extends object ? {
114
+ } : T extends any[] ? {
115
+ [k: number]: ZodFormattedError<T[number]>;
116
+ } : T extends object ? {
114
117
  [K in keyof T]?: ZodFormattedError<T[K]>;
115
118
  } : unknown);
116
119
  export declare type inferFormattedError<T extends ZodType<any, any, any>, U = string> = ZodFormattedError<TypeOf<T>, U>;
package/lib/ZodError.js CHANGED
@@ -1,6 +1,7 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.setErrorMap = exports.overrideErrorMap = exports.defaultErrorMap = exports.ZodError = exports.quotelessJson = exports.ZodIssueCode = void 0;
4
+ const parseUtil_1 = require("./helpers/parseUtil");
4
5
  const util_1 = require("./helpers/util");
5
6
  exports.ZodIssueCode = util_1.util.arrayToEnum([
6
7
  "invalid_type",
@@ -75,14 +76,14 @@ class ZodError extends Error {
75
76
  const el = issue.path[i];
76
77
  const terminal = i === issue.path.length - 1;
77
78
  if (!terminal) {
78
- if (typeof el === "string") {
79
- curr[el] = curr[el] || { _errors: [] };
80
- }
81
- else if (typeof el === "number") {
82
- const errorArray = [];
83
- errorArray._errors = [];
84
- curr[el] = curr[el] || errorArray;
85
- }
79
+ curr[el] = curr[el] || { _errors: [] };
80
+ // if (typeof el === "string") {
81
+ // curr[el] = curr[el] || { _errors: [] };
82
+ // } else if (typeof el === "number") {
83
+ // const errorArray: any = [];
84
+ // errorArray._errors = [];
85
+ // curr[el] = curr[el] || errorArray;
86
+ // }
86
87
  }
87
88
  else {
88
89
  curr[el] = curr[el] || { _errors: [] };
@@ -133,7 +134,7 @@ const defaultErrorMap = (issue, _ctx) => {
133
134
  let message;
134
135
  switch (issue.code) {
135
136
  case exports.ZodIssueCode.invalid_type:
136
- if (issue.received === "undefined") {
137
+ if (issue.received === parseUtil_1.ZodParsedType.undefined) {
137
138
  message = "Required";
138
139
  }
139
140
  else {
@@ -144,22 +145,16 @@ const defaultErrorMap = (issue, _ctx) => {
144
145
  message = `Invalid literal value, expected ${JSON.stringify(issue.expected)}`;
145
146
  break;
146
147
  case exports.ZodIssueCode.unrecognized_keys:
147
- message = `Unrecognized key(s) in object: ${issue.keys
148
- .map((k) => `'${k}'`)
149
- .join(", ")}`;
148
+ message = `Unrecognized key(s) in object: ${util_1.util.joinValues(issue.keys, ", ")}`;
150
149
  break;
151
150
  case exports.ZodIssueCode.invalid_union:
152
151
  message = `Invalid input`;
153
152
  break;
154
153
  case exports.ZodIssueCode.invalid_union_discriminator:
155
- message = `Invalid discriminator value. Expected ${issue.options
156
- .map((val) => (typeof val === "string" ? `'${val}'` : val))
157
- .join(" | ")}`;
154
+ message = `Invalid discriminator value. Expected ${util_1.util.joinValues(issue.options)}`;
158
155
  break;
159
156
  case exports.ZodIssueCode.invalid_enum_value:
160
- message = `Invalid enum value. Expected ${issue.options
161
- .map((val) => (typeof val === "string" ? `'${val}'` : val))
162
- .join(" | ")}`;
157
+ message = `Invalid enum value. Expected ${util_1.util.joinValues(issue.options)}, received '${issue.received}'`;
163
158
  break;
164
159
  case exports.ZodIssueCode.invalid_arguments:
165
160
  message = `Invalid function arguments`;
@@ -15,4 +15,5 @@ export declare namespace util {
15
15
  }>;
16
16
  type noUndefined<T> = T extends undefined ? never : T;
17
17
  const isInteger: NumberConstructor["isInteger"];
18
+ function joinValues<T extends any[]>(array: T, separator?: string): string;
18
19
  }
@@ -48,4 +48,10 @@ var util;
48
48
  util.isInteger = typeof Number.isInteger === "function"
49
49
  ? (val) => Number.isInteger(val) // eslint-disable-line ban/ban
50
50
  : (val) => typeof val === "number" && isFinite(val) && Math.floor(val) === val;
51
+ function joinValues(array, separator = " | ") {
52
+ return array
53
+ .map((val) => (typeof val === "string" ? `'${val}'` : val))
54
+ .join(separator);
55
+ }
56
+ util.joinValues = joinValues;
51
57
  })(util = exports.util || (exports.util = {}));
package/lib/index.mjs CHANGED
@@ -45,6 +45,12 @@ var util;
45
45
  util.isInteger = typeof Number.isInteger === "function"
46
46
  ? (val) => Number.isInteger(val) // eslint-disable-line ban/ban
47
47
  : (val) => typeof val === "number" && isFinite(val) && Math.floor(val) === val;
48
+ function joinValues(array, separator = " | ") {
49
+ return array
50
+ .map((val) => (typeof val === "string" ? `'${val}'` : val))
51
+ .join(separator);
52
+ }
53
+ util.joinValues = joinValues;
48
54
  })(util || (util = {}));
49
55
 
50
56
  const ZodIssueCode = util.arrayToEnum([
@@ -119,14 +125,14 @@ class ZodError extends Error {
119
125
  const el = issue.path[i];
120
126
  const terminal = i === issue.path.length - 1;
121
127
  if (!terminal) {
122
- if (typeof el === "string") {
123
- curr[el] = curr[el] || { _errors: [] };
124
- }
125
- else if (typeof el === "number") {
126
- const errorArray = [];
127
- errorArray._errors = [];
128
- curr[el] = curr[el] || errorArray;
129
- }
128
+ curr[el] = curr[el] || { _errors: [] };
129
+ // if (typeof el === "string") {
130
+ // curr[el] = curr[el] || { _errors: [] };
131
+ // } else if (typeof el === "number") {
132
+ // const errorArray: any = [];
133
+ // errorArray._errors = [];
134
+ // curr[el] = curr[el] || errorArray;
135
+ // }
130
136
  }
131
137
  else {
132
138
  curr[el] = curr[el] || { _errors: [] };
@@ -176,7 +182,7 @@ const defaultErrorMap = (issue, _ctx) => {
176
182
  let message;
177
183
  switch (issue.code) {
178
184
  case ZodIssueCode.invalid_type:
179
- if (issue.received === "undefined") {
185
+ if (issue.received === ZodParsedType.undefined) {
180
186
  message = "Required";
181
187
  }
182
188
  else {
@@ -187,22 +193,16 @@ const defaultErrorMap = (issue, _ctx) => {
187
193
  message = `Invalid literal value, expected ${JSON.stringify(issue.expected)}`;
188
194
  break;
189
195
  case ZodIssueCode.unrecognized_keys:
190
- message = `Unrecognized key(s) in object: ${issue.keys
191
- .map((k) => `'${k}'`)
192
- .join(", ")}`;
196
+ message = `Unrecognized key(s) in object: ${util.joinValues(issue.keys, ", ")}`;
193
197
  break;
194
198
  case ZodIssueCode.invalid_union:
195
199
  message = `Invalid input`;
196
200
  break;
197
201
  case ZodIssueCode.invalid_union_discriminator:
198
- message = `Invalid discriminator value. Expected ${issue.options
199
- .map((val) => (typeof val === "string" ? `'${val}'` : val))
200
- .join(" | ")}`;
202
+ message = `Invalid discriminator value. Expected ${util.joinValues(issue.options)}`;
201
203
  break;
202
204
  case ZodIssueCode.invalid_enum_value:
203
- message = `Invalid enum value. Expected ${issue.options
204
- .map((val) => (typeof val === "string" ? `'${val}'` : val))
205
- .join(" | ")}`;
205
+ message = `Invalid enum value. Expected ${util.joinValues(issue.options)}, received '${issue.received}'`;
206
206
  break;
207
207
  case ZodIssueCode.invalid_arguments:
208
208
  message = `Invalid function arguments`;
@@ -2390,11 +2390,23 @@ function createZodEnum(values) {
2390
2390
  }
2391
2391
  class ZodEnum extends ZodType {
2392
2392
  _parse(input) {
2393
+ if (typeof input.data !== "string") {
2394
+ const ctx = this._getOrReturnCtx(input);
2395
+ const expectedValues = this._def.values;
2396
+ addIssueToContext(ctx, {
2397
+ expected: util.joinValues(expectedValues),
2398
+ received: ctx.parsedType,
2399
+ code: ZodIssueCode.invalid_type,
2400
+ });
2401
+ return INVALID;
2402
+ }
2393
2403
  if (this._def.values.indexOf(input.data) === -1) {
2394
2404
  const ctx = this._getOrReturnCtx(input);
2405
+ const expectedValues = this._def.values;
2395
2406
  addIssueToContext(ctx, {
2407
+ received: ctx.data,
2396
2408
  code: ZodIssueCode.invalid_enum_value,
2397
- options: this._def.values,
2409
+ options: expectedValues,
2398
2410
  });
2399
2411
  return INVALID;
2400
2412
  }
@@ -2429,11 +2441,23 @@ ZodEnum.create = createZodEnum;
2429
2441
  class ZodNativeEnum extends ZodType {
2430
2442
  _parse(input) {
2431
2443
  const nativeEnumValues = util.getValidEnumValues(this._def.values);
2444
+ const ctx = this._getOrReturnCtx(input);
2445
+ if (ctx.parsedType !== ZodParsedType.string &&
2446
+ ctx.parsedType !== ZodParsedType.number) {
2447
+ const expectedValues = util.objectValues(nativeEnumValues);
2448
+ addIssueToContext(ctx, {
2449
+ expected: util.joinValues(expectedValues),
2450
+ received: ctx.parsedType,
2451
+ code: ZodIssueCode.invalid_type,
2452
+ });
2453
+ return INVALID;
2454
+ }
2432
2455
  if (nativeEnumValues.indexOf(input.data) === -1) {
2433
- const ctx = this._getOrReturnCtx(input);
2456
+ const expectedValues = util.objectValues(nativeEnumValues);
2434
2457
  addIssueToContext(ctx, {
2458
+ received: ctx.data,
2435
2459
  code: ZodIssueCode.invalid_enum_value,
2436
- options: util.objectValues(nativeEnumValues),
2460
+ options: expectedValues,
2437
2461
  });
2438
2462
  return INVALID;
2439
2463
  }
@@ -2506,22 +2530,22 @@ class ZodEffects extends ZodType {
2506
2530
  });
2507
2531
  }
2508
2532
  }
2533
+ const checkCtx = {
2534
+ addIssue: (arg) => {
2535
+ addIssueToContext(ctx, arg);
2536
+ if (arg.fatal) {
2537
+ status.abort();
2538
+ }
2539
+ else {
2540
+ status.dirty();
2541
+ }
2542
+ },
2543
+ get path() {
2544
+ return ctx.path;
2545
+ },
2546
+ };
2547
+ checkCtx.addIssue = checkCtx.addIssue.bind(checkCtx);
2509
2548
  if (effect.type === "refinement") {
2510
- const checkCtx = {
2511
- addIssue: (arg) => {
2512
- addIssueToContext(ctx, arg);
2513
- if (arg.fatal) {
2514
- status.abort();
2515
- }
2516
- else {
2517
- status.dirty();
2518
- }
2519
- },
2520
- get path() {
2521
- return ctx.path;
2522
- },
2523
- };
2524
- checkCtx.addIssue = checkCtx.addIssue.bind(checkCtx);
2525
2549
  const executeRefinement = (acc
2526
2550
  // effect: RefinementEffect<any>
2527
2551
  ) => {
@@ -2575,11 +2599,11 @@ class ZodEffects extends ZodType {
2575
2599
  // }
2576
2600
  if (!isValid(base))
2577
2601
  return base;
2578
- const result = effect.transform(base.value);
2602
+ const result = effect.transform(base.value, checkCtx);
2579
2603
  if (result instanceof Promise) {
2580
2604
  throw new Error(`Asynchronous transform encountered during synchronous parse operation. Use .parseAsync instead.`);
2581
2605
  }
2582
- return OK(result);
2606
+ return { status: status.value, value: result };
2583
2607
  }
2584
2608
  else {
2585
2609
  return this._def.schema
@@ -2591,7 +2615,7 @@ class ZodEffects extends ZodType {
2591
2615
  // if (base.status === "dirty") {
2592
2616
  // return { status: "dirty", value: base.value };
2593
2617
  // }
2594
- return Promise.resolve(effect.transform(base.value)).then(OK);
2618
+ return Promise.resolve(effect.transform(base.value, checkCtx)).then((result) => ({ status: status.value, value: result }));
2595
2619
  });
2596
2620
  }
2597
2621
  }
package/lib/index.umd.js CHANGED
@@ -51,6 +51,12 @@
51
51
  util.isInteger = typeof Number.isInteger === "function"
52
52
  ? (val) => Number.isInteger(val) // eslint-disable-line ban/ban
53
53
  : (val) => typeof val === "number" && isFinite(val) && Math.floor(val) === val;
54
+ function joinValues(array, separator = " | ") {
55
+ return array
56
+ .map((val) => (typeof val === "string" ? `'${val}'` : val))
57
+ .join(separator);
58
+ }
59
+ util.joinValues = joinValues;
54
60
  })(util || (util = {}));
55
61
 
56
62
  const ZodIssueCode = util.arrayToEnum([
@@ -125,14 +131,14 @@
125
131
  const el = issue.path[i];
126
132
  const terminal = i === issue.path.length - 1;
127
133
  if (!terminal) {
128
- if (typeof el === "string") {
129
- curr[el] = curr[el] || { _errors: [] };
130
- }
131
- else if (typeof el === "number") {
132
- const errorArray = [];
133
- errorArray._errors = [];
134
- curr[el] = curr[el] || errorArray;
135
- }
134
+ curr[el] = curr[el] || { _errors: [] };
135
+ // if (typeof el === "string") {
136
+ // curr[el] = curr[el] || { _errors: [] };
137
+ // } else if (typeof el === "number") {
138
+ // const errorArray: any = [];
139
+ // errorArray._errors = [];
140
+ // curr[el] = curr[el] || errorArray;
141
+ // }
136
142
  }
137
143
  else {
138
144
  curr[el] = curr[el] || { _errors: [] };
@@ -182,7 +188,7 @@
182
188
  let message;
183
189
  switch (issue.code) {
184
190
  case ZodIssueCode.invalid_type:
185
- if (issue.received === "undefined") {
191
+ if (issue.received === ZodParsedType.undefined) {
186
192
  message = "Required";
187
193
  }
188
194
  else {
@@ -193,22 +199,16 @@
193
199
  message = `Invalid literal value, expected ${JSON.stringify(issue.expected)}`;
194
200
  break;
195
201
  case ZodIssueCode.unrecognized_keys:
196
- message = `Unrecognized key(s) in object: ${issue.keys
197
- .map((k) => `'${k}'`)
198
- .join(", ")}`;
202
+ message = `Unrecognized key(s) in object: ${util.joinValues(issue.keys, ", ")}`;
199
203
  break;
200
204
  case ZodIssueCode.invalid_union:
201
205
  message = `Invalid input`;
202
206
  break;
203
207
  case ZodIssueCode.invalid_union_discriminator:
204
- message = `Invalid discriminator value. Expected ${issue.options
205
- .map((val) => (typeof val === "string" ? `'${val}'` : val))
206
- .join(" | ")}`;
208
+ message = `Invalid discriminator value. Expected ${util.joinValues(issue.options)}`;
207
209
  break;
208
210
  case ZodIssueCode.invalid_enum_value:
209
- message = `Invalid enum value. Expected ${issue.options
210
- .map((val) => (typeof val === "string" ? `'${val}'` : val))
211
- .join(" | ")}`;
211
+ message = `Invalid enum value. Expected ${util.joinValues(issue.options)}, received '${issue.received}'`;
212
212
  break;
213
213
  case ZodIssueCode.invalid_arguments:
214
214
  message = `Invalid function arguments`;
@@ -2396,11 +2396,23 @@
2396
2396
  }
2397
2397
  class ZodEnum extends ZodType {
2398
2398
  _parse(input) {
2399
+ if (typeof input.data !== "string") {
2400
+ const ctx = this._getOrReturnCtx(input);
2401
+ const expectedValues = this._def.values;
2402
+ addIssueToContext(ctx, {
2403
+ expected: util.joinValues(expectedValues),
2404
+ received: ctx.parsedType,
2405
+ code: ZodIssueCode.invalid_type,
2406
+ });
2407
+ return INVALID;
2408
+ }
2399
2409
  if (this._def.values.indexOf(input.data) === -1) {
2400
2410
  const ctx = this._getOrReturnCtx(input);
2411
+ const expectedValues = this._def.values;
2401
2412
  addIssueToContext(ctx, {
2413
+ received: ctx.data,
2402
2414
  code: ZodIssueCode.invalid_enum_value,
2403
- options: this._def.values,
2415
+ options: expectedValues,
2404
2416
  });
2405
2417
  return INVALID;
2406
2418
  }
@@ -2435,11 +2447,23 @@
2435
2447
  class ZodNativeEnum extends ZodType {
2436
2448
  _parse(input) {
2437
2449
  const nativeEnumValues = util.getValidEnumValues(this._def.values);
2450
+ const ctx = this._getOrReturnCtx(input);
2451
+ if (ctx.parsedType !== ZodParsedType.string &&
2452
+ ctx.parsedType !== ZodParsedType.number) {
2453
+ const expectedValues = util.objectValues(nativeEnumValues);
2454
+ addIssueToContext(ctx, {
2455
+ expected: util.joinValues(expectedValues),
2456
+ received: ctx.parsedType,
2457
+ code: ZodIssueCode.invalid_type,
2458
+ });
2459
+ return INVALID;
2460
+ }
2438
2461
  if (nativeEnumValues.indexOf(input.data) === -1) {
2439
- const ctx = this._getOrReturnCtx(input);
2462
+ const expectedValues = util.objectValues(nativeEnumValues);
2440
2463
  addIssueToContext(ctx, {
2464
+ received: ctx.data,
2441
2465
  code: ZodIssueCode.invalid_enum_value,
2442
- options: util.objectValues(nativeEnumValues),
2466
+ options: expectedValues,
2443
2467
  });
2444
2468
  return INVALID;
2445
2469
  }
@@ -2512,22 +2536,22 @@
2512
2536
  });
2513
2537
  }
2514
2538
  }
2539
+ const checkCtx = {
2540
+ addIssue: (arg) => {
2541
+ addIssueToContext(ctx, arg);
2542
+ if (arg.fatal) {
2543
+ status.abort();
2544
+ }
2545
+ else {
2546
+ status.dirty();
2547
+ }
2548
+ },
2549
+ get path() {
2550
+ return ctx.path;
2551
+ },
2552
+ };
2553
+ checkCtx.addIssue = checkCtx.addIssue.bind(checkCtx);
2515
2554
  if (effect.type === "refinement") {
2516
- const checkCtx = {
2517
- addIssue: (arg) => {
2518
- addIssueToContext(ctx, arg);
2519
- if (arg.fatal) {
2520
- status.abort();
2521
- }
2522
- else {
2523
- status.dirty();
2524
- }
2525
- },
2526
- get path() {
2527
- return ctx.path;
2528
- },
2529
- };
2530
- checkCtx.addIssue = checkCtx.addIssue.bind(checkCtx);
2531
2555
  const executeRefinement = (acc
2532
2556
  // effect: RefinementEffect<any>
2533
2557
  ) => {
@@ -2581,11 +2605,11 @@
2581
2605
  // }
2582
2606
  if (!isValid(base))
2583
2607
  return base;
2584
- const result = effect.transform(base.value);
2608
+ const result = effect.transform(base.value, checkCtx);
2585
2609
  if (result instanceof Promise) {
2586
2610
  throw new Error(`Asynchronous transform encountered during synchronous parse operation. Use .parseAsync instead.`);
2587
2611
  }
2588
- return OK(result);
2612
+ return { status: status.value, value: result };
2589
2613
  }
2590
2614
  else {
2591
2615
  return this._def.schema
@@ -2597,7 +2621,7 @@
2597
2621
  // if (base.status === "dirty") {
2598
2622
  // return { status: "dirty", value: base.value };
2599
2623
  // }
2600
- return Promise.resolve(effect.transform(base.value)).then(OK);
2624
+ return Promise.resolve(effect.transform(base.value, checkCtx)).then((result) => ({ status: status.value, value: result }));
2601
2625
  });
2602
2626
  }
2603
2627
  }
package/lib/types.d.ts CHANGED
@@ -71,7 +71,7 @@ export declare abstract class ZodType<Output = any, Def extends ZodTypeDef = Zod
71
71
  promise(): ZodPromise<this>;
72
72
  or<T extends ZodTypeAny>(option: T): ZodUnion<[this, T]>;
73
73
  and<T extends ZodTypeAny>(incoming: T): ZodIntersection<this, T>;
74
- transform<NewOut>(transform: (arg: Output) => NewOut | Promise<NewOut>): ZodEffects<this, NewOut>;
74
+ transform<NewOut>(transform: (arg: Output, ctx: RefinementCtx) => NewOut | Promise<NewOut>): ZodEffects<this, NewOut>;
75
75
  default(def: util.noUndefined<Input>): ZodDefault<this>;
76
76
  default(def: () => util.noUndefined<Input>): ZodDefault<this>;
77
77
  describe(description: string): this;
@@ -267,28 +267,28 @@ export declare class ZodArray<T extends ZodTypeAny, Cardinality extends ArrayCar
267
267
  }
268
268
  export declare type ZodNonEmptyArray<T extends ZodTypeAny> = ZodArray<T, "atleastone">;
269
269
  export declare namespace objectUtil {
270
- type MergeShapes<U extends ZodRawShape, V extends ZodRawShape> = {
270
+ export type MergeShapes<U extends ZodRawShape, V extends ZodRawShape> = {
271
271
  [k in Exclude<keyof U, keyof V>]: U[k];
272
272
  } & V;
273
+ type optionalKeys<T extends object> = {
274
+ [k in keyof T]: undefined extends T[k] ? k : never;
275
+ }[keyof T];
273
276
  type requiredKeys<T extends object> = {
274
277
  [k in keyof T]: undefined extends T[k] ? never : k;
275
278
  }[keyof T];
276
- type addQuestionMarks<T extends object> = {
277
- [k in keyof T]?: T[k];
278
- } & {
279
- [k in requiredKeys<T>]: T[k];
280
- };
281
- type identity<T> = T;
282
- type flatten<T extends object> = identity<{
279
+ export type addQuestionMarks<T extends object> = Partial<Pick<T, optionalKeys<T>>> & Pick<T, requiredKeys<T>>;
280
+ export type identity<T> = T;
281
+ export type flatten<T extends object> = identity<{
283
282
  [k in keyof T]: T[k];
284
283
  }>;
285
- type noNeverKeys<T extends ZodRawShape> = {
284
+ export type noNeverKeys<T extends ZodRawShape> = {
286
285
  [k in keyof T]: [T[k]] extends [never] ? never : k;
287
286
  }[keyof T];
288
- type noNever<T extends ZodRawShape> = identity<{
287
+ export type noNever<T extends ZodRawShape> = identity<{
289
288
  [k in noNeverKeys<T>]: k extends keyof T ? T[k] : never;
290
289
  }>;
291
- const mergeShapes: <U extends ZodRawShape, T extends ZodRawShape>(first: U, second: T) => T & U;
290
+ export const mergeShapes: <U extends ZodRawShape, T extends ZodRawShape>(first: U, second: T) => T & U;
291
+ export {};
292
292
  }
293
293
  export declare type extendShape<A, B> = Omit<A, keyof B> & B;
294
294
  declare type UnknownKeysParam = "passthrough" | "strict" | "strip";
@@ -569,7 +569,7 @@ export declare type RefinementEffect<T> = {
569
569
  };
570
570
  export declare type TransformEffect<T> = {
571
571
  type: "transform";
572
- transform: (arg: T) => any;
572
+ transform: (arg: T, ctx: RefinementCtx) => any;
573
573
  };
574
574
  export declare type PreprocessEffect<T> = {
575
575
  type: "preprocess";
package/lib/types.js CHANGED
@@ -1996,11 +1996,23 @@ function createZodEnum(values) {
1996
1996
  }
1997
1997
  class ZodEnum extends ZodType {
1998
1998
  _parse(input) {
1999
+ if (typeof input.data !== "string") {
2000
+ const ctx = this._getOrReturnCtx(input);
2001
+ const expectedValues = this._def.values;
2002
+ (0, parseUtil_1.addIssueToContext)(ctx, {
2003
+ expected: util_1.util.joinValues(expectedValues),
2004
+ received: ctx.parsedType,
2005
+ code: ZodError_1.ZodIssueCode.invalid_type,
2006
+ });
2007
+ return parseUtil_1.INVALID;
2008
+ }
1999
2009
  if (this._def.values.indexOf(input.data) === -1) {
2000
2010
  const ctx = this._getOrReturnCtx(input);
2011
+ const expectedValues = this._def.values;
2001
2012
  (0, parseUtil_1.addIssueToContext)(ctx, {
2013
+ received: ctx.data,
2002
2014
  code: ZodError_1.ZodIssueCode.invalid_enum_value,
2003
- options: this._def.values,
2015
+ options: expectedValues,
2004
2016
  });
2005
2017
  return parseUtil_1.INVALID;
2006
2018
  }
@@ -2036,11 +2048,23 @@ ZodEnum.create = createZodEnum;
2036
2048
  class ZodNativeEnum extends ZodType {
2037
2049
  _parse(input) {
2038
2050
  const nativeEnumValues = util_1.util.getValidEnumValues(this._def.values);
2051
+ const ctx = this._getOrReturnCtx(input);
2052
+ if (ctx.parsedType !== parseUtil_1.ZodParsedType.string &&
2053
+ ctx.parsedType !== parseUtil_1.ZodParsedType.number) {
2054
+ const expectedValues = util_1.util.objectValues(nativeEnumValues);
2055
+ (0, parseUtil_1.addIssueToContext)(ctx, {
2056
+ expected: util_1.util.joinValues(expectedValues),
2057
+ received: ctx.parsedType,
2058
+ code: ZodError_1.ZodIssueCode.invalid_type,
2059
+ });
2060
+ return parseUtil_1.INVALID;
2061
+ }
2039
2062
  if (nativeEnumValues.indexOf(input.data) === -1) {
2040
- const ctx = this._getOrReturnCtx(input);
2063
+ const expectedValues = util_1.util.objectValues(nativeEnumValues);
2041
2064
  (0, parseUtil_1.addIssueToContext)(ctx, {
2065
+ received: ctx.data,
2042
2066
  code: ZodError_1.ZodIssueCode.invalid_enum_value,
2043
- options: util_1.util.objectValues(nativeEnumValues),
2067
+ options: expectedValues,
2044
2068
  });
2045
2069
  return parseUtil_1.INVALID;
2046
2070
  }
@@ -2115,22 +2139,22 @@ class ZodEffects extends ZodType {
2115
2139
  });
2116
2140
  }
2117
2141
  }
2142
+ const checkCtx = {
2143
+ addIssue: (arg) => {
2144
+ (0, parseUtil_1.addIssueToContext)(ctx, arg);
2145
+ if (arg.fatal) {
2146
+ status.abort();
2147
+ }
2148
+ else {
2149
+ status.dirty();
2150
+ }
2151
+ },
2152
+ get path() {
2153
+ return ctx.path;
2154
+ },
2155
+ };
2156
+ checkCtx.addIssue = checkCtx.addIssue.bind(checkCtx);
2118
2157
  if (effect.type === "refinement") {
2119
- const checkCtx = {
2120
- addIssue: (arg) => {
2121
- (0, parseUtil_1.addIssueToContext)(ctx, arg);
2122
- if (arg.fatal) {
2123
- status.abort();
2124
- }
2125
- else {
2126
- status.dirty();
2127
- }
2128
- },
2129
- get path() {
2130
- return ctx.path;
2131
- },
2132
- };
2133
- checkCtx.addIssue = checkCtx.addIssue.bind(checkCtx);
2134
2158
  const executeRefinement = (acc
2135
2159
  // effect: RefinementEffect<any>
2136
2160
  ) => {
@@ -2184,11 +2208,11 @@ class ZodEffects extends ZodType {
2184
2208
  // }
2185
2209
  if (!(0, parseUtil_1.isValid)(base))
2186
2210
  return base;
2187
- const result = effect.transform(base.value);
2211
+ const result = effect.transform(base.value, checkCtx);
2188
2212
  if (result instanceof Promise) {
2189
2213
  throw new Error(`Asynchronous transform encountered during synchronous parse operation. Use .parseAsync instead.`);
2190
2214
  }
2191
- return (0, parseUtil_1.OK)(result);
2215
+ return { status: status.value, value: result };
2192
2216
  }
2193
2217
  else {
2194
2218
  return this._def.schema
@@ -2200,7 +2224,7 @@ class ZodEffects extends ZodType {
2200
2224
  // if (base.status === "dirty") {
2201
2225
  // return { status: "dirty", value: base.value };
2202
2226
  // }
2203
- return Promise.resolve(effect.transform(base.value)).then(parseUtil_1.OK);
2227
+ return Promise.resolve(effect.transform(base.value, checkCtx)).then((result) => ({ status: status.value, value: result }));
2204
2228
  });
2205
2229
  }
2206
2230
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "zod",
3
- "version": "3.14.5",
3
+ "version": "3.16.0",
4
4
  "description": "TypeScript-first schema declaration and validation library with static type inference",
5
5
  "main": "./lib/index.js",
6
6
  "types": "./index.d.ts",