zod 3.17.4 → 3.17.7

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
@@ -313,6 +313,7 @@ There are a growing number of tools that are built atop or support Zod natively!
313
313
  - [`prisma-zod-generator`](https://github.com/omar-dulaimi/prisma-zod-generator): Emit Zod schemas from your Prisma schema.
314
314
  - [`prisma-trpc-generator`](https://github.com/omar-dulaimi/prisma-trpc-generator): Emit fully implemented tRPC routers and their validation schemas using Zod.
315
315
  - [`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.
316
+ - [`zod-xlsx`](https://github.com/sidwebworks/zod-xlsx): A xlsx based resource validator using Zod schemas.
316
317
  - [`remix-domains`](https://github.com/SeasonedSoftware/remix-domains/): Improves end-to-end type safety in [Remix](https://remix.run/) by leveraging Zod to parse the framework's inputs such as FormData, URLSearchParams, etc.
317
318
 
318
319
  #### Form integrations
@@ -351,7 +352,7 @@ pnpm add zod # pnpm
351
352
 
352
353
  ### Deno
353
354
 
354
- Unlike Node, Deno relies on direct URL imports instead of a package manager like npm. Zod is available on [deno.land/x](deno.land/x). The latest version can be imported like so:
355
+ Unlike Node, Deno relies on direct URL imports instead of a package manager like NPM. Zod is available on [deno.land/x](https://deno.land/x). The latest version can be imported like so:
355
356
 
356
357
  ```ts
357
358
  import { z } from "https://deno.land/x/zod/mod.ts";
@@ -360,7 +361,7 @@ import { z } from "https://deno.land/x/zod/mod.ts";
360
361
  You can also specify a particular version:
361
362
 
362
363
  ```ts
363
- import { z } from from "https://deno.land/x/zod@v3.16.1/mod.ts"
364
+ import { z } from "https://deno.land/x/zod@v3.16.1/mod.ts";
364
365
  ```
365
366
 
366
367
  > The rest of this README assumes you are using npm and importing directly from the `"zod"` package.
@@ -438,7 +439,7 @@ const tru = z.literal(true);
438
439
  tuna.value; // "tuna"
439
440
  ```
440
441
 
441
- > Currently there is no support for Date or bigint literals in Zod. If you have a use case for this feature, please file an issue.
442
+ > Currently there is no support for Date literals in Zod. If you have a use case for this feature, please file an issue.
442
443
 
443
444
  ## Strings
444
445
 
@@ -453,6 +454,8 @@ z.string().url();
453
454
  z.string().uuid();
454
455
  z.string().cuid();
455
456
  z.string().regex(regex);
457
+ z.string().startsWith(string);
458
+ z.string().endsWith(string);
456
459
 
457
460
  // trim whitespace
458
461
  z.string().trim();
@@ -484,6 +487,8 @@ z.string().length(5, { message: "Must be exactly 5 characters long" });
484
487
  z.string().email({ message: "Invalid email address" });
485
488
  z.string().url({ message: "Invalid url" });
486
489
  z.string().uuid({ message: "Invalid UUID" });
490
+ z.string().startsWith("https://", { message: "Must provide secure URL" });
491
+ z.string().endsWith(".com", { message: "Only .com domains allowed" });
487
492
  ```
488
493
 
489
494
  ## Numbers
package/lib/ZodError.d.ts CHANGED
@@ -68,7 +68,11 @@ export interface ZodInvalidReturnTypeIssue extends ZodIssueBase {
68
68
  export interface ZodInvalidDateIssue extends ZodIssueBase {
69
69
  code: typeof ZodIssueCode.invalid_date;
70
70
  }
71
- export declare type StringValidation = "email" | "url" | "uuid" | "regex" | "cuid";
71
+ export declare type StringValidation = "email" | "url" | "uuid" | "regex" | "cuid" | {
72
+ startsWith: string;
73
+ } | {
74
+ endsWith: string;
75
+ };
72
76
  export interface ZodInvalidStringIssue extends ZodIssueBase {
73
77
  code: typeof ZodIssueCode.invalid_string;
74
78
  validation: StringValidation;
@@ -146,8 +150,8 @@ export declare type ZodErrorMap = typeof defaultErrorMap;
146
150
  export declare const defaultErrorMap: (issue: ZodIssueOptionalMessage, _ctx: ErrorMapCtx) => {
147
151
  message: string;
148
152
  };
149
- export declare let overrideErrorMap: (issue: ZodIssueOptionalMessage, _ctx: ErrorMapCtx) => {
153
+ export declare function setErrorMap(map: ZodErrorMap): void;
154
+ export declare function getErrorMap(): (issue: ZodIssueOptionalMessage, _ctx: ErrorMapCtx) => {
150
155
  message: string;
151
156
  };
152
- export declare const setErrorMap: (map: ZodErrorMap) => void;
153
157
  export {};
package/lib/ZodError.js CHANGED
@@ -1,6 +1,7 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.setErrorMap = exports.overrideErrorMap = exports.defaultErrorMap = exports.ZodError = exports.quotelessJson = exports.ZodIssueCode = void 0;
3
+ exports.getErrorMap = exports.setErrorMap = 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",
@@ -101,7 +102,7 @@ class ZodError extends Error {
101
102
  return this.message;
102
103
  }
103
104
  get message() {
104
- return JSON.stringify(this.issues, null, 2);
105
+ return JSON.stringify(this.issues, parseUtil_1.jsonStringifyReplacer, 2);
105
106
  }
106
107
  get isEmpty() {
107
108
  return this.issues.length === 0;
@@ -141,7 +142,7 @@ const defaultErrorMap = (issue, _ctx) => {
141
142
  }
142
143
  break;
143
144
  case exports.ZodIssueCode.invalid_literal:
144
- message = `Invalid literal value, expected ${JSON.stringify(issue.expected)}`;
145
+ message = `Invalid literal value, expected ${JSON.stringify(issue.expected, parseUtil_1.jsonStringifyReplacer)}`;
145
146
  break;
146
147
  case exports.ZodIssueCode.unrecognized_keys:
147
148
  message = `Unrecognized key(s) in object: ${util_1.util.joinValues(issue.keys, ", ")}`;
@@ -165,10 +166,23 @@ const defaultErrorMap = (issue, _ctx) => {
165
166
  message = `Invalid date`;
166
167
  break;
167
168
  case exports.ZodIssueCode.invalid_string:
168
- if (issue.validation !== "regex")
169
+ if (typeof issue.validation === "object") {
170
+ if ("startsWith" in issue.validation) {
171
+ message = `Invalid input: must start with "${issue.validation.startsWith}"`;
172
+ }
173
+ else if ("endsWith" in issue.validation) {
174
+ message = `Invalid input: must start with "${issue.validation.endsWith}"`;
175
+ }
176
+ else {
177
+ util_1.util.assertNever(issue.validation);
178
+ }
179
+ }
180
+ else if (issue.validation !== "regex") {
169
181
  message = `Invalid ${issue.validation}`;
170
- else
182
+ }
183
+ else {
171
184
  message = "Invalid";
185
+ }
172
186
  break;
173
187
  case exports.ZodIssueCode.too_small:
174
188
  if (issue.type === "array")
@@ -206,8 +220,12 @@ const defaultErrorMap = (issue, _ctx) => {
206
220
  return { message };
207
221
  };
208
222
  exports.defaultErrorMap = defaultErrorMap;
209
- exports.overrideErrorMap = exports.defaultErrorMap;
210
- const setErrorMap = (map) => {
211
- exports.overrideErrorMap = map;
212
- };
223
+ let overrideErrorMap = exports.defaultErrorMap;
224
+ function setErrorMap(map) {
225
+ overrideErrorMap = map;
226
+ }
213
227
  exports.setErrorMap = setErrorMap;
228
+ function getErrorMap() {
229
+ return overrideErrorMap;
230
+ }
231
+ exports.getErrorMap = getErrorMap;
@@ -76,3 +76,4 @@ export declare const isAborted: (x: ParseReturnType<any>) => x is INVALID;
76
76
  export declare const isDirty: <T>(x: ParseReturnType<T>) => x is OK<T> | DIRTY<T>;
77
77
  export declare const isValid: <T>(x: ParseReturnType<T>) => x is OK<T> | DIRTY<T>;
78
78
  export declare const isAsync: <T>(x: ParseReturnType<T>) => x is AsyncParseReturnType<T>;
79
+ export declare const jsonStringifyReplacer: (_: string, value: any) => any;
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.isAsync = exports.isValid = exports.isDirty = exports.isAborted = exports.OK = exports.DIRTY = exports.INVALID = exports.ParseStatus = exports.addIssueToContext = exports.EMPTY_PATH = exports.makeIssue = void 0;
3
+ exports.jsonStringifyReplacer = exports.isAsync = exports.isValid = exports.isDirty = exports.isAborted = exports.OK = exports.DIRTY = exports.INVALID = exports.ParseStatus = exports.addIssueToContext = exports.EMPTY_PATH = exports.makeIssue = void 0;
4
4
  const ZodError_1 = require("../ZodError");
5
5
  const makeIssue = (params) => {
6
6
  const { data, path, errorMaps, issueData } = params;
@@ -33,7 +33,7 @@ function addIssueToContext(ctx, issueData) {
33
33
  errorMaps: [
34
34
  ctx.common.contextualErrorMap,
35
35
  ctx.schemaErrorMap,
36
- ZodError_1.overrideErrorMap,
36
+ ZodError_1.getErrorMap(),
37
37
  ZodError_1.defaultErrorMap,
38
38
  ].filter((x) => !!x),
39
39
  });
@@ -108,3 +108,10 @@ const isValid = (x) => x.status === "valid";
108
108
  exports.isValid = isValid;
109
109
  const isAsync = (x) => typeof Promise !== undefined && x instanceof Promise;
110
110
  exports.isAsync = isAsync;
111
+ const jsonStringifyReplacer = (_, value) => {
112
+ if (typeof value === "bigint") {
113
+ return value.toString();
114
+ }
115
+ return value;
116
+ };
117
+ exports.jsonStringifyReplacer = jsonStringifyReplacer;
@@ -1,5 +1,6 @@
1
1
  export declare namespace util {
2
2
  type AssertEqual<T, Expected> = [T] extends [Expected] ? [Expected] extends [T] ? true : false : false;
3
+ function assertEqual<A, B>(_cond: AssertEqual<A, B>): void;
3
4
  function assertNever(_x: never): never;
4
5
  type Omit<T, K extends keyof T> = Pick<T, Exclude<keyof T, K>>;
5
6
  type OmitKeys<T, K extends string> = Pick<T, Exclude<keyof T, K>>;
@@ -3,6 +3,8 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.getParsedType = exports.ZodParsedType = exports.util = void 0;
4
4
  var util;
5
5
  (function (util) {
6
+ function assertEqual(_cond) { }
7
+ util.assertEqual = assertEqual;
6
8
  function assertNever(_x) {
7
9
  throw new Error();
8
10
  }
package/lib/index.mjs CHANGED
@@ -1,5 +1,7 @@
1
1
  var util;
2
2
  (function (util) {
3
+ function assertEqual(_cond) { }
4
+ util.assertEqual = assertEqual;
3
5
  function assertNever(_x) {
4
6
  throw new Error();
5
7
  }
@@ -215,7 +217,7 @@ class ZodError extends Error {
215
217
  return this.message;
216
218
  }
217
219
  get message() {
218
- return JSON.stringify(this.issues, null, 2);
220
+ return JSON.stringify(this.issues, jsonStringifyReplacer, 2);
219
221
  }
220
222
  get isEmpty() {
221
223
  return this.issues.length === 0;
@@ -254,7 +256,7 @@ const defaultErrorMap = (issue, _ctx) => {
254
256
  }
255
257
  break;
256
258
  case ZodIssueCode.invalid_literal:
257
- message = `Invalid literal value, expected ${JSON.stringify(issue.expected)}`;
259
+ message = `Invalid literal value, expected ${JSON.stringify(issue.expected, jsonStringifyReplacer)}`;
258
260
  break;
259
261
  case ZodIssueCode.unrecognized_keys:
260
262
  message = `Unrecognized key(s) in object: ${util.joinValues(issue.keys, ", ")}`;
@@ -278,10 +280,23 @@ const defaultErrorMap = (issue, _ctx) => {
278
280
  message = `Invalid date`;
279
281
  break;
280
282
  case ZodIssueCode.invalid_string:
281
- if (issue.validation !== "regex")
283
+ if (typeof issue.validation === "object") {
284
+ if ("startsWith" in issue.validation) {
285
+ message = `Invalid input: must start with "${issue.validation.startsWith}"`;
286
+ }
287
+ else if ("endsWith" in issue.validation) {
288
+ message = `Invalid input: must start with "${issue.validation.endsWith}"`;
289
+ }
290
+ else {
291
+ util.assertNever(issue.validation);
292
+ }
293
+ }
294
+ else if (issue.validation !== "regex") {
282
295
  message = `Invalid ${issue.validation}`;
283
- else
296
+ }
297
+ else {
284
298
  message = "Invalid";
299
+ }
285
300
  break;
286
301
  case ZodIssueCode.too_small:
287
302
  if (issue.type === "array")
@@ -319,9 +334,12 @@ const defaultErrorMap = (issue, _ctx) => {
319
334
  return { message };
320
335
  };
321
336
  let overrideErrorMap = defaultErrorMap;
322
- const setErrorMap = (map) => {
337
+ function setErrorMap(map) {
323
338
  overrideErrorMap = map;
324
- };
339
+ }
340
+ function getErrorMap() {
341
+ return overrideErrorMap;
342
+ }
325
343
 
326
344
  const makeIssue = (params) => {
327
345
  const { data, path, errorMaps, issueData } = params;
@@ -353,7 +371,7 @@ function addIssueToContext(ctx, issueData) {
353
371
  errorMaps: [
354
372
  ctx.common.contextualErrorMap,
355
373
  ctx.schemaErrorMap,
356
- overrideErrorMap,
374
+ getErrorMap(),
357
375
  defaultErrorMap,
358
376
  ].filter((x) => !!x),
359
377
  });
@@ -420,6 +438,12 @@ const isAborted = (x) => x.status === "aborted";
420
438
  const isDirty = (x) => x.status === "dirty";
421
439
  const isValid = (x) => x.status === "valid";
422
440
  const isAsync = (x) => typeof Promise !== undefined && x instanceof Promise;
441
+ const jsonStringifyReplacer = (_, value) => {
442
+ if (typeof value === "bigint") {
443
+ return value.toString();
444
+ }
445
+ return value;
446
+ };
423
447
 
424
448
  var errorUtil;
425
449
  (function (errorUtil) {
@@ -823,6 +847,28 @@ class ZodString extends ZodType {
823
847
  else if (check.kind === "trim") {
824
848
  input.data = input.data.trim();
825
849
  }
850
+ else if (check.kind === "startsWith") {
851
+ if (!input.data.startsWith(check.value)) {
852
+ ctx = this._getOrReturnCtx(input, ctx);
853
+ addIssueToContext(ctx, {
854
+ code: ZodIssueCode.invalid_string,
855
+ validation: { startsWith: check.value },
856
+ message: check.message,
857
+ });
858
+ status.dirty();
859
+ }
860
+ }
861
+ else if (check.kind === "endsWith") {
862
+ if (!input.data.endsWith(check.value)) {
863
+ ctx = this._getOrReturnCtx(input, ctx);
864
+ addIssueToContext(ctx, {
865
+ code: ZodIssueCode.invalid_string,
866
+ validation: { endsWith: check.value },
867
+ message: check.message,
868
+ });
869
+ status.dirty();
870
+ }
871
+ }
826
872
  else {
827
873
  util.assertNever(check);
828
874
  }
@@ -854,6 +900,20 @@ class ZodString extends ZodType {
854
900
  ...errorUtil.errToObj(message),
855
901
  });
856
902
  }
903
+ startsWith(value, message) {
904
+ return this._addCheck({
905
+ kind: "startsWith",
906
+ value: value,
907
+ ...errorUtil.errToObj(message),
908
+ });
909
+ }
910
+ endsWith(value, message) {
911
+ return this._addCheck({
912
+ kind: "endsWith",
913
+ value: value,
914
+ ...errorUtil.errToObj(message),
915
+ });
916
+ }
857
917
  min(minLength, message) {
858
918
  return this._addCheck({
859
919
  kind: "min",
@@ -2254,7 +2314,7 @@ class ZodFunction extends ZodType {
2254
2314
  errorMaps: [
2255
2315
  ctx.common.contextualErrorMap,
2256
2316
  ctx.schemaErrorMap,
2257
- overrideErrorMap,
2317
+ getErrorMap(),
2258
2318
  defaultErrorMap,
2259
2319
  ].filter((x) => !!x),
2260
2320
  issueData: {
@@ -2270,7 +2330,7 @@ class ZodFunction extends ZodType {
2270
2330
  errorMaps: [
2271
2331
  ctx.common.contextualErrorMap,
2272
2332
  ctx.schemaErrorMap,
2273
- overrideErrorMap,
2333
+ getErrorMap(),
2274
2334
  defaultErrorMap,
2275
2335
  ].filter((x) => !!x),
2276
2336
  issueData: {
@@ -2834,6 +2894,7 @@ var mod = /*#__PURE__*/Object.freeze({
2834
2894
  isDirty: isDirty,
2835
2895
  isValid: isValid,
2836
2896
  isAsync: isAsync,
2897
+ jsonStringifyReplacer: jsonStringifyReplacer,
2837
2898
  ZodType: ZodType,
2838
2899
  ZodString: ZodString,
2839
2900
  ZodNumber: ZodNumber,
@@ -2914,8 +2975,8 @@ var mod = /*#__PURE__*/Object.freeze({
2914
2975
  quotelessJson: quotelessJson,
2915
2976
  ZodError: ZodError,
2916
2977
  defaultErrorMap: defaultErrorMap,
2917
- get overrideErrorMap () { return overrideErrorMap; },
2918
- setErrorMap: setErrorMap
2978
+ setErrorMap: setErrorMap,
2979
+ getErrorMap: getErrorMap
2919
2980
  });
2920
2981
 
2921
- export { DIRTY, EMPTY_PATH, INVALID, OK, ParseStatus, ZodType as Schema, ZodAny, ZodArray, ZodBigInt, ZodBoolean, ZodDate, ZodDefault, ZodDiscriminatedUnion, ZodEffects, ZodEnum, ZodError, ZodFirstPartyTypeKind, ZodFunction, ZodIntersection, ZodIssueCode, ZodLazy, ZodLiteral, ZodMap, ZodNaN, ZodNativeEnum, ZodNever, ZodNull, ZodNullable, ZodNumber, ZodObject, ZodOptional, ZodParsedType, ZodPromise, ZodRecord, ZodType as ZodSchema, ZodSet, ZodString, ZodEffects as ZodTransformer, ZodTuple, ZodType, ZodUndefined, ZodUnion, ZodUnknown, ZodVoid, addIssueToContext, anyType as any, arrayType as array, bigIntType as bigint, booleanType as boolean, custom, dateType as date, mod as default, defaultErrorMap, discriminatedUnionType as discriminatedUnion, effectsType as effect, enumType as enum, functionType as function, getParsedType, instanceOfType as instanceof, intersectionType as intersection, isAborted, isAsync, isDirty, isValid, late, lazyType as lazy, literalType as literal, makeIssue, mapType as map, nanType as nan, nativeEnumType as nativeEnum, neverType as never, nullType as null, nullableType as nullable, numberType as number, objectType as object, objectUtil, oboolean, onumber, optionalType as optional, ostring, overrideErrorMap, preprocessType as preprocess, promiseType as promise, quotelessJson, recordType as record, setType as set, setErrorMap, strictObjectType as strictObject, stringType as string, effectsType as transformer, tupleType as tuple, undefinedType as undefined, unionType as union, unknownType as unknown, voidType as void, mod as z };
2982
+ export { DIRTY, EMPTY_PATH, INVALID, OK, ParseStatus, ZodType as Schema, ZodAny, ZodArray, ZodBigInt, ZodBoolean, ZodDate, ZodDefault, ZodDiscriminatedUnion, ZodEffects, ZodEnum, ZodError, ZodFirstPartyTypeKind, ZodFunction, ZodIntersection, ZodIssueCode, ZodLazy, ZodLiteral, ZodMap, ZodNaN, ZodNativeEnum, ZodNever, ZodNull, ZodNullable, ZodNumber, ZodObject, ZodOptional, ZodParsedType, ZodPromise, ZodRecord, ZodType as ZodSchema, ZodSet, ZodString, ZodEffects as ZodTransformer, ZodTuple, ZodType, ZodUndefined, ZodUnion, ZodUnknown, ZodVoid, addIssueToContext, anyType as any, arrayType as array, bigIntType as bigint, booleanType as boolean, custom, dateType as date, mod as default, defaultErrorMap, discriminatedUnionType as discriminatedUnion, effectsType as effect, enumType as enum, functionType as function, getErrorMap, getParsedType, instanceOfType as instanceof, intersectionType as intersection, isAborted, isAsync, isDirty, isValid, jsonStringifyReplacer, late, lazyType as lazy, literalType as literal, makeIssue, mapType as map, nanType as nan, nativeEnumType as nativeEnum, neverType as never, nullType as null, nullableType as nullable, numberType as number, objectType as object, objectUtil, oboolean, onumber, optionalType as optional, ostring, preprocessType as preprocess, promiseType as promise, quotelessJson, recordType as record, setType as set, setErrorMap, strictObjectType as strictObject, stringType as string, effectsType as transformer, tupleType as tuple, undefinedType as undefined, unionType as union, unknownType as unknown, voidType as void, mod as z };
package/lib/index.umd.js CHANGED
@@ -6,6 +6,8 @@
6
6
 
7
7
  var util;
8
8
  (function (util) {
9
+ function assertEqual(_cond) { }
10
+ util.assertEqual = assertEqual;
9
11
  function assertNever(_x) {
10
12
  throw new Error();
11
13
  }
@@ -221,7 +223,7 @@
221
223
  return this.message;
222
224
  }
223
225
  get message() {
224
- return JSON.stringify(this.issues, null, 2);
226
+ return JSON.stringify(this.issues, jsonStringifyReplacer, 2);
225
227
  }
226
228
  get isEmpty() {
227
229
  return this.issues.length === 0;
@@ -260,7 +262,7 @@
260
262
  }
261
263
  break;
262
264
  case ZodIssueCode.invalid_literal:
263
- message = `Invalid literal value, expected ${JSON.stringify(issue.expected)}`;
265
+ message = `Invalid literal value, expected ${JSON.stringify(issue.expected, jsonStringifyReplacer)}`;
264
266
  break;
265
267
  case ZodIssueCode.unrecognized_keys:
266
268
  message = `Unrecognized key(s) in object: ${util.joinValues(issue.keys, ", ")}`;
@@ -284,10 +286,23 @@
284
286
  message = `Invalid date`;
285
287
  break;
286
288
  case ZodIssueCode.invalid_string:
287
- if (issue.validation !== "regex")
289
+ if (typeof issue.validation === "object") {
290
+ if ("startsWith" in issue.validation) {
291
+ message = `Invalid input: must start with "${issue.validation.startsWith}"`;
292
+ }
293
+ else if ("endsWith" in issue.validation) {
294
+ message = `Invalid input: must start with "${issue.validation.endsWith}"`;
295
+ }
296
+ else {
297
+ util.assertNever(issue.validation);
298
+ }
299
+ }
300
+ else if (issue.validation !== "regex") {
288
301
  message = `Invalid ${issue.validation}`;
289
- else
302
+ }
303
+ else {
290
304
  message = "Invalid";
305
+ }
291
306
  break;
292
307
  case ZodIssueCode.too_small:
293
308
  if (issue.type === "array")
@@ -324,10 +339,13 @@
324
339
  }
325
340
  return { message };
326
341
  };
327
- exports.overrideErrorMap = defaultErrorMap;
328
- const setErrorMap = (map) => {
329
- exports.overrideErrorMap = map;
330
- };
342
+ let overrideErrorMap = defaultErrorMap;
343
+ function setErrorMap(map) {
344
+ overrideErrorMap = map;
345
+ }
346
+ function getErrorMap() {
347
+ return overrideErrorMap;
348
+ }
331
349
 
332
350
  const makeIssue = (params) => {
333
351
  const { data, path, errorMaps, issueData } = params;
@@ -359,7 +377,7 @@
359
377
  errorMaps: [
360
378
  ctx.common.contextualErrorMap,
361
379
  ctx.schemaErrorMap,
362
- exports.overrideErrorMap,
380
+ getErrorMap(),
363
381
  defaultErrorMap,
364
382
  ].filter((x) => !!x),
365
383
  });
@@ -426,6 +444,12 @@
426
444
  const isDirty = (x) => x.status === "dirty";
427
445
  const isValid = (x) => x.status === "valid";
428
446
  const isAsync = (x) => typeof Promise !== undefined && x instanceof Promise;
447
+ const jsonStringifyReplacer = (_, value) => {
448
+ if (typeof value === "bigint") {
449
+ return value.toString();
450
+ }
451
+ return value;
452
+ };
429
453
 
430
454
  var errorUtil;
431
455
  (function (errorUtil) {
@@ -829,6 +853,28 @@
829
853
  else if (check.kind === "trim") {
830
854
  input.data = input.data.trim();
831
855
  }
856
+ else if (check.kind === "startsWith") {
857
+ if (!input.data.startsWith(check.value)) {
858
+ ctx = this._getOrReturnCtx(input, ctx);
859
+ addIssueToContext(ctx, {
860
+ code: ZodIssueCode.invalid_string,
861
+ validation: { startsWith: check.value },
862
+ message: check.message,
863
+ });
864
+ status.dirty();
865
+ }
866
+ }
867
+ else if (check.kind === "endsWith") {
868
+ if (!input.data.endsWith(check.value)) {
869
+ ctx = this._getOrReturnCtx(input, ctx);
870
+ addIssueToContext(ctx, {
871
+ code: ZodIssueCode.invalid_string,
872
+ validation: { endsWith: check.value },
873
+ message: check.message,
874
+ });
875
+ status.dirty();
876
+ }
877
+ }
832
878
  else {
833
879
  util.assertNever(check);
834
880
  }
@@ -860,6 +906,20 @@
860
906
  ...errorUtil.errToObj(message),
861
907
  });
862
908
  }
909
+ startsWith(value, message) {
910
+ return this._addCheck({
911
+ kind: "startsWith",
912
+ value: value,
913
+ ...errorUtil.errToObj(message),
914
+ });
915
+ }
916
+ endsWith(value, message) {
917
+ return this._addCheck({
918
+ kind: "endsWith",
919
+ value: value,
920
+ ...errorUtil.errToObj(message),
921
+ });
922
+ }
863
923
  min(minLength, message) {
864
924
  return this._addCheck({
865
925
  kind: "min",
@@ -2260,7 +2320,7 @@
2260
2320
  errorMaps: [
2261
2321
  ctx.common.contextualErrorMap,
2262
2322
  ctx.schemaErrorMap,
2263
- exports.overrideErrorMap,
2323
+ getErrorMap(),
2264
2324
  defaultErrorMap,
2265
2325
  ].filter((x) => !!x),
2266
2326
  issueData: {
@@ -2276,7 +2336,7 @@
2276
2336
  errorMaps: [
2277
2337
  ctx.common.contextualErrorMap,
2278
2338
  ctx.schemaErrorMap,
2279
- exports.overrideErrorMap,
2339
+ getErrorMap(),
2280
2340
  defaultErrorMap,
2281
2341
  ].filter((x) => !!x),
2282
2342
  issueData: {
@@ -2840,6 +2900,7 @@
2840
2900
  isDirty: isDirty,
2841
2901
  isValid: isValid,
2842
2902
  isAsync: isAsync,
2903
+ jsonStringifyReplacer: jsonStringifyReplacer,
2843
2904
  ZodType: ZodType,
2844
2905
  ZodString: ZodString,
2845
2906
  ZodNumber: ZodNumber,
@@ -2920,8 +2981,8 @@
2920
2981
  quotelessJson: quotelessJson,
2921
2982
  ZodError: ZodError,
2922
2983
  defaultErrorMap: defaultErrorMap,
2923
- get overrideErrorMap () { return exports.overrideErrorMap; },
2924
- setErrorMap: setErrorMap
2984
+ setErrorMap: setErrorMap,
2985
+ getErrorMap: getErrorMap
2925
2986
  });
2926
2987
 
2927
2988
  exports.DIRTY = DIRTY;
@@ -2980,6 +3041,7 @@
2980
3041
  exports.effect = effectsType;
2981
3042
  exports["enum"] = enumType;
2982
3043
  exports["function"] = functionType;
3044
+ exports.getErrorMap = getErrorMap;
2983
3045
  exports.getParsedType = getParsedType;
2984
3046
  exports["instanceof"] = instanceOfType;
2985
3047
  exports.intersection = intersectionType;
@@ -2987,6 +3049,7 @@
2987
3049
  exports.isAsync = isAsync;
2988
3050
  exports.isDirty = isDirty;
2989
3051
  exports.isValid = isValid;
3052
+ exports.jsonStringifyReplacer = jsonStringifyReplacer;
2990
3053
  exports.late = late;
2991
3054
  exports.lazy = lazyType;
2992
3055
  exports.literal = literalType;
package/lib/types.d.ts CHANGED
@@ -98,6 +98,14 @@ declare type ZodStringCheck = {
98
98
  } | {
99
99
  kind: "cuid";
100
100
  message?: string;
101
+ } | {
102
+ kind: "startsWith";
103
+ value: string;
104
+ message?: string;
105
+ } | {
106
+ kind: "endsWith";
107
+ value: string;
108
+ message?: string;
101
109
  } | {
102
110
  kind: "regex";
103
111
  regex: RegExp;
@@ -121,6 +129,8 @@ export declare class ZodString extends ZodType<string, ZodStringDef> {
121
129
  uuid(message?: errorUtil.ErrMessage): ZodString;
122
130
  cuid(message?: errorUtil.ErrMessage): ZodString;
123
131
  regex(regex: RegExp, message?: errorUtil.ErrMessage): ZodString;
132
+ startsWith(value: string, message?: errorUtil.ErrMessage): ZodString;
133
+ endsWith(value: string, message?: errorUtil.ErrMessage): ZodString;
124
134
  min(minLength: number, message?: errorUtil.ErrMessage): ZodString;
125
135
  max(maxLength: number, message?: errorUtil.ErrMessage): ZodString;
126
136
  length(len: number, message?: errorUtil.ErrMessage): ZodString;
@@ -508,9 +518,9 @@ export declare class ZodFunction<Args extends ZodTuple<any, any>, Returns extend
508
518
  returnType(): Returns;
509
519
  args<Items extends Parameters<typeof ZodTuple["create"]>[0]>(...items: Items): ZodFunction<ZodTuple<Items, ZodUnknown>, Returns>;
510
520
  returns<NewReturnType extends ZodType<any, any>>(returnType: NewReturnType): ZodFunction<Args, NewReturnType>;
511
- implement<F extends InnerTypeOfFunction<Args, Returns>>(func: F): F;
521
+ implement<F extends InnerTypeOfFunction<Args, Returns>>(func: F): ReturnType<F> extends Returns["_output"] ? (...args: Args["_input"]) => ReturnType<F> : OuterTypeOfFunction<Args, Returns>;
512
522
  strictImplement(func: InnerTypeOfFunction<Args, Returns>): InnerTypeOfFunction<Args, Returns>;
513
- validate: <F extends InnerTypeOfFunction<Args, Returns>>(func: F) => F;
523
+ validate: <F extends InnerTypeOfFunction<Args, Returns>>(func: F) => ReturnType<F> extends Returns["_output"] ? (...args: Args["_input"]) => ReturnType<F> : OuterTypeOfFunction<Args, Returns>;
514
524
  static create: <T extends ZodTuple<any, any> = ZodTuple<[], ZodUnknown>, U extends ZodTypeAny = ZodUnknown>(args?: T | undefined, returns?: U | undefined, params?: RawCreateParams) => ZodFunction<T, U>;
515
525
  }
516
526
  export interface ZodLazyDef<T extends ZodTypeAny = ZodTypeAny> extends ZodTypeDef {
package/lib/types.js CHANGED
@@ -405,6 +405,28 @@ class ZodString extends ZodType {
405
405
  else if (check.kind === "trim") {
406
406
  input.data = input.data.trim();
407
407
  }
408
+ else if (check.kind === "startsWith") {
409
+ if (!input.data.startsWith(check.value)) {
410
+ ctx = this._getOrReturnCtx(input, ctx);
411
+ parseUtil_1.addIssueToContext(ctx, {
412
+ code: ZodError_1.ZodIssueCode.invalid_string,
413
+ validation: { startsWith: check.value },
414
+ message: check.message,
415
+ });
416
+ status.dirty();
417
+ }
418
+ }
419
+ else if (check.kind === "endsWith") {
420
+ if (!input.data.endsWith(check.value)) {
421
+ ctx = this._getOrReturnCtx(input, ctx);
422
+ parseUtil_1.addIssueToContext(ctx, {
423
+ code: ZodError_1.ZodIssueCode.invalid_string,
424
+ validation: { endsWith: check.value },
425
+ message: check.message,
426
+ });
427
+ status.dirty();
428
+ }
429
+ }
408
430
  else {
409
431
  util_1.util.assertNever(check);
410
432
  }
@@ -436,6 +458,20 @@ class ZodString extends ZodType {
436
458
  ...errorUtil_1.errorUtil.errToObj(message),
437
459
  });
438
460
  }
461
+ startsWith(value, message) {
462
+ return this._addCheck({
463
+ kind: "startsWith",
464
+ value: value,
465
+ ...errorUtil_1.errorUtil.errToObj(message),
466
+ });
467
+ }
468
+ endsWith(value, message) {
469
+ return this._addCheck({
470
+ kind: "endsWith",
471
+ value: value,
472
+ ...errorUtil_1.errorUtil.errToObj(message),
473
+ });
474
+ }
439
475
  min(minLength, message) {
440
476
  return this._addCheck({
441
477
  kind: "min",
@@ -1857,7 +1893,7 @@ class ZodFunction extends ZodType {
1857
1893
  errorMaps: [
1858
1894
  ctx.common.contextualErrorMap,
1859
1895
  ctx.schemaErrorMap,
1860
- ZodError_1.overrideErrorMap,
1896
+ ZodError_1.getErrorMap(),
1861
1897
  ZodError_1.defaultErrorMap,
1862
1898
  ].filter((x) => !!x),
1863
1899
  issueData: {
@@ -1873,7 +1909,7 @@ class ZodFunction extends ZodType {
1873
1909
  errorMaps: [
1874
1910
  ctx.common.contextualErrorMap,
1875
1911
  ctx.schemaErrorMap,
1876
- ZodError_1.overrideErrorMap,
1912
+ ZodError_1.getErrorMap(),
1877
1913
  ZodError_1.defaultErrorMap,
1878
1914
  ].filter((x) => !!x),
1879
1915
  issueData: {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "zod",
3
- "version": "3.17.4",
3
+ "version": "3.17.7",
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",