zod 3.17.7 → 3.17.8

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
@@ -550,14 +550,32 @@ const isActive = z.boolean({
550
550
 
551
551
  ## Dates
552
552
 
553
- z.date() accepts a date, not a date string
553
+ Use z.date() to validate `Date` instances.
554
554
 
555
555
  ```ts
556
556
  z.date().safeParse(new Date()); // success: true
557
557
  z.date().safeParse("2022-01-12T00:00:00.000Z"); // success: false
558
558
  ```
559
559
 
560
- To allow for dates or date strings, you can use preprocess
560
+ You can customize certain error messages when creating a boolean schema.
561
+
562
+ ```ts
563
+ const myDateSchema = z.date({
564
+ required_error: "Please select a date and time",
565
+ invalid_type_error: "That's not a date!",
566
+ });
567
+ ```
568
+
569
+ Zod provides a handful of date-specific validations.
570
+
571
+ ```ts
572
+ z.date().min(new Date("1900-01-01"), { message: "Too old" });
573
+ z.date().max(new Date(), { message: "Too young!" });
574
+ ```
575
+
576
+ **Supporting date strings**
577
+
578
+ To write a schema that accepts either a `Date` or a date string, use (`z.preprocess`)[#preprocess].
561
579
 
562
580
  ```ts
563
581
  const dateSchema = z.preprocess((arg) => {
package/lib/ZodError.d.ts CHANGED
@@ -81,13 +81,13 @@ export interface ZodTooSmallIssue extends ZodIssueBase {
81
81
  code: typeof ZodIssueCode.too_small;
82
82
  minimum: number;
83
83
  inclusive: boolean;
84
- type: "array" | "string" | "number" | "set";
84
+ type: "array" | "string" | "number" | "set" | "date";
85
85
  }
86
86
  export interface ZodTooBigIssue extends ZodIssueBase {
87
87
  code: typeof ZodIssueCode.too_big;
88
88
  maximum: number;
89
89
  inclusive: boolean;
90
- type: "array" | "string" | "number" | "set";
90
+ type: "array" | "string" | "number" | "set" | "date";
91
91
  }
92
92
  export interface ZodInvalidIntersectionTypesIssue extends ZodIssueBase {
93
93
  code: typeof ZodIssueCode.invalid_intersection_types;
package/lib/ZodError.js CHANGED
@@ -191,6 +191,8 @@ const defaultErrorMap = (issue, _ctx) => {
191
191
  message = `String must contain ${issue.inclusive ? `at least` : `over`} ${issue.minimum} character(s)`;
192
192
  else if (issue.type === "number")
193
193
  message = `Number must be greater than ${issue.inclusive ? `or equal to ` : ``}${issue.minimum}`;
194
+ else if (issue.type === "date")
195
+ message = `Date must be greater than ${issue.inclusive ? `or equal to ` : ``}${new Date(issue.minimum)}`;
194
196
  else
195
197
  message = "Invalid input";
196
198
  break;
@@ -201,6 +203,8 @@ const defaultErrorMap = (issue, _ctx) => {
201
203
  message = `String must contain ${issue.inclusive ? `at most` : `under`} ${issue.maximum} character(s)`;
202
204
  else if (issue.type === "number")
203
205
  message = `Number must be less than ${issue.inclusive ? `or equal to ` : ``}${issue.maximum}`;
206
+ else if (issue.type === "date")
207
+ message = `Date must be smaller than ${issue.inclusive ? `or equal to ` : ``}${new Date(issue.maximum)}`;
204
208
  else
205
209
  message = "Invalid input";
206
210
  break;
package/lib/index.mjs CHANGED
@@ -305,6 +305,8 @@ const defaultErrorMap = (issue, _ctx) => {
305
305
  message = `String must contain ${issue.inclusive ? `at least` : `over`} ${issue.minimum} character(s)`;
306
306
  else if (issue.type === "number")
307
307
  message = `Number must be greater than ${issue.inclusive ? `or equal to ` : ``}${issue.minimum}`;
308
+ else if (issue.type === "date")
309
+ message = `Date must be greater than ${issue.inclusive ? `or equal to ` : ``}${new Date(issue.minimum)}`;
308
310
  else
309
311
  message = "Invalid input";
310
312
  break;
@@ -315,6 +317,8 @@ const defaultErrorMap = (issue, _ctx) => {
315
317
  message = `String must contain ${issue.inclusive ? `at most` : `under`} ${issue.maximum} character(s)`;
316
318
  else if (issue.type === "number")
317
319
  message = `Number must be less than ${issue.inclusive ? `or equal to ` : ``}${issue.maximum}`;
320
+ else if (issue.type === "date")
321
+ message = `Date must be smaller than ${issue.inclusive ? `or equal to ` : ``}${new Date(issue.maximum)}`;
318
322
  else
319
323
  message = "Invalid input";
320
324
  break;
@@ -1231,14 +1235,88 @@ class ZodDate extends ZodType {
1231
1235
  });
1232
1236
  return INVALID;
1233
1237
  }
1238
+ const status = new ParseStatus();
1239
+ let ctx = undefined;
1240
+ for (const check of this._def.checks) {
1241
+ if (check.kind === "min") {
1242
+ if (input.data.getTime() < check.value) {
1243
+ ctx = this._getOrReturnCtx(input, ctx);
1244
+ addIssueToContext(ctx, {
1245
+ code: ZodIssueCode.too_small,
1246
+ message: check.message,
1247
+ inclusive: true,
1248
+ minimum: check.value,
1249
+ type: "date",
1250
+ });
1251
+ status.dirty();
1252
+ }
1253
+ }
1254
+ else if (check.kind === "max") {
1255
+ if (input.data.getTime() > check.value) {
1256
+ ctx = this._getOrReturnCtx(input, ctx);
1257
+ addIssueToContext(ctx, {
1258
+ code: ZodIssueCode.too_big,
1259
+ message: check.message,
1260
+ inclusive: true,
1261
+ maximum: check.value,
1262
+ type: "date",
1263
+ });
1264
+ status.dirty();
1265
+ }
1266
+ }
1267
+ else {
1268
+ util.assertNever(check);
1269
+ }
1270
+ }
1234
1271
  return {
1235
- status: "valid",
1272
+ status: status.value,
1236
1273
  value: new Date(input.data.getTime()),
1237
1274
  };
1238
1275
  }
1276
+ _addCheck(check) {
1277
+ return new ZodDate({
1278
+ ...this._def,
1279
+ checks: [...this._def.checks, check],
1280
+ });
1281
+ }
1282
+ min(minDate, message) {
1283
+ return this._addCheck({
1284
+ kind: "min",
1285
+ value: minDate.getTime(),
1286
+ message: errorUtil.toString(message),
1287
+ });
1288
+ }
1289
+ max(maxDate, message) {
1290
+ return this._addCheck({
1291
+ kind: "max",
1292
+ value: maxDate.getTime(),
1293
+ message: errorUtil.toString(message),
1294
+ });
1295
+ }
1296
+ get minDate() {
1297
+ let min = null;
1298
+ for (const ch of this._def.checks) {
1299
+ if (ch.kind === "min") {
1300
+ if (min === null || ch.value > min)
1301
+ min = ch.value;
1302
+ }
1303
+ }
1304
+ return min != null ? new Date(min) : null;
1305
+ }
1306
+ get maxDate() {
1307
+ let max = null;
1308
+ for (const ch of this._def.checks) {
1309
+ if (ch.kind === "max") {
1310
+ if (max === null || ch.value < max)
1311
+ max = ch.value;
1312
+ }
1313
+ }
1314
+ return max != null ? new Date(max) : null;
1315
+ }
1239
1316
  }
1240
1317
  ZodDate.create = (params) => {
1241
1318
  return new ZodDate({
1319
+ checks: [],
1242
1320
  typeName: ZodFirstPartyTypeKind.ZodDate,
1243
1321
  ...processCreateParams(params),
1244
1322
  });
package/lib/index.umd.js CHANGED
@@ -311,6 +311,8 @@
311
311
  message = `String must contain ${issue.inclusive ? `at least` : `over`} ${issue.minimum} character(s)`;
312
312
  else if (issue.type === "number")
313
313
  message = `Number must be greater than ${issue.inclusive ? `or equal to ` : ``}${issue.minimum}`;
314
+ else if (issue.type === "date")
315
+ message = `Date must be greater than ${issue.inclusive ? `or equal to ` : ``}${new Date(issue.minimum)}`;
314
316
  else
315
317
  message = "Invalid input";
316
318
  break;
@@ -321,6 +323,8 @@
321
323
  message = `String must contain ${issue.inclusive ? `at most` : `under`} ${issue.maximum} character(s)`;
322
324
  else if (issue.type === "number")
323
325
  message = `Number must be less than ${issue.inclusive ? `or equal to ` : ``}${issue.maximum}`;
326
+ else if (issue.type === "date")
327
+ message = `Date must be smaller than ${issue.inclusive ? `or equal to ` : ``}${new Date(issue.maximum)}`;
324
328
  else
325
329
  message = "Invalid input";
326
330
  break;
@@ -1237,14 +1241,88 @@
1237
1241
  });
1238
1242
  return INVALID;
1239
1243
  }
1244
+ const status = new ParseStatus();
1245
+ let ctx = undefined;
1246
+ for (const check of this._def.checks) {
1247
+ if (check.kind === "min") {
1248
+ if (input.data.getTime() < check.value) {
1249
+ ctx = this._getOrReturnCtx(input, ctx);
1250
+ addIssueToContext(ctx, {
1251
+ code: ZodIssueCode.too_small,
1252
+ message: check.message,
1253
+ inclusive: true,
1254
+ minimum: check.value,
1255
+ type: "date",
1256
+ });
1257
+ status.dirty();
1258
+ }
1259
+ }
1260
+ else if (check.kind === "max") {
1261
+ if (input.data.getTime() > check.value) {
1262
+ ctx = this._getOrReturnCtx(input, ctx);
1263
+ addIssueToContext(ctx, {
1264
+ code: ZodIssueCode.too_big,
1265
+ message: check.message,
1266
+ inclusive: true,
1267
+ maximum: check.value,
1268
+ type: "date",
1269
+ });
1270
+ status.dirty();
1271
+ }
1272
+ }
1273
+ else {
1274
+ util.assertNever(check);
1275
+ }
1276
+ }
1240
1277
  return {
1241
- status: "valid",
1278
+ status: status.value,
1242
1279
  value: new Date(input.data.getTime()),
1243
1280
  };
1244
1281
  }
1282
+ _addCheck(check) {
1283
+ return new ZodDate({
1284
+ ...this._def,
1285
+ checks: [...this._def.checks, check],
1286
+ });
1287
+ }
1288
+ min(minDate, message) {
1289
+ return this._addCheck({
1290
+ kind: "min",
1291
+ value: minDate.getTime(),
1292
+ message: errorUtil.toString(message),
1293
+ });
1294
+ }
1295
+ max(maxDate, message) {
1296
+ return this._addCheck({
1297
+ kind: "max",
1298
+ value: maxDate.getTime(),
1299
+ message: errorUtil.toString(message),
1300
+ });
1301
+ }
1302
+ get minDate() {
1303
+ let min = null;
1304
+ for (const ch of this._def.checks) {
1305
+ if (ch.kind === "min") {
1306
+ if (min === null || ch.value > min)
1307
+ min = ch.value;
1308
+ }
1309
+ }
1310
+ return min != null ? new Date(min) : null;
1311
+ }
1312
+ get maxDate() {
1313
+ let max = null;
1314
+ for (const ch of this._def.checks) {
1315
+ if (ch.kind === "max") {
1316
+ if (max === null || ch.value < max)
1317
+ max = ch.value;
1318
+ }
1319
+ }
1320
+ return max != null ? new Date(max) : null;
1321
+ }
1245
1322
  }
1246
1323
  ZodDate.create = (params) => {
1247
1324
  return new ZodDate({
1325
+ checks: [],
1248
1326
  typeName: exports.ZodFirstPartyTypeKind.ZodDate,
1249
1327
  ...processCreateParams(params),
1250
1328
  });
package/lib/types.d.ts CHANGED
@@ -214,11 +214,26 @@ export declare class ZodBoolean extends ZodType<boolean, ZodBooleanDef> {
214
214
  _parse(input: ParseInput): ParseReturnType<boolean>;
215
215
  static create: (params?: RawCreateParams) => ZodBoolean;
216
216
  }
217
+ declare type ZodDateCheck = {
218
+ kind: "min";
219
+ value: number;
220
+ message?: string;
221
+ } | {
222
+ kind: "max";
223
+ value: number;
224
+ message?: string;
225
+ };
217
226
  export interface ZodDateDef extends ZodTypeDef {
227
+ checks: ZodDateCheck[];
218
228
  typeName: ZodFirstPartyTypeKind.ZodDate;
219
229
  }
220
230
  export declare class ZodDate extends ZodType<Date, ZodDateDef> {
221
231
  _parse(input: ParseInput): ParseReturnType<this["_output"]>;
232
+ _addCheck(check: ZodDateCheck): ZodDate;
233
+ min(minDate: Date, message?: errorUtil.ErrMessage): ZodDate;
234
+ max(maxDate: Date, message?: errorUtil.ErrMessage): ZodDate;
235
+ get minDate(): Date | null;
236
+ get maxDate(): Date | null;
222
237
  static create: (params?: RawCreateParams) => ZodDate;
223
238
  }
224
239
  export interface ZodUndefinedDef extends ZodTypeDef {
package/lib/types.js CHANGED
@@ -793,15 +793,89 @@ class ZodDate extends ZodType {
793
793
  });
794
794
  return parseUtil_1.INVALID;
795
795
  }
796
+ const status = new parseUtil_1.ParseStatus();
797
+ let ctx = undefined;
798
+ for (const check of this._def.checks) {
799
+ if (check.kind === "min") {
800
+ if (input.data.getTime() < check.value) {
801
+ ctx = this._getOrReturnCtx(input, ctx);
802
+ parseUtil_1.addIssueToContext(ctx, {
803
+ code: ZodError_1.ZodIssueCode.too_small,
804
+ message: check.message,
805
+ inclusive: true,
806
+ minimum: check.value,
807
+ type: "date",
808
+ });
809
+ status.dirty();
810
+ }
811
+ }
812
+ else if (check.kind === "max") {
813
+ if (input.data.getTime() > check.value) {
814
+ ctx = this._getOrReturnCtx(input, ctx);
815
+ parseUtil_1.addIssueToContext(ctx, {
816
+ code: ZodError_1.ZodIssueCode.too_big,
817
+ message: check.message,
818
+ inclusive: true,
819
+ maximum: check.value,
820
+ type: "date",
821
+ });
822
+ status.dirty();
823
+ }
824
+ }
825
+ else {
826
+ util_1.util.assertNever(check);
827
+ }
828
+ }
796
829
  return {
797
- status: "valid",
830
+ status: status.value,
798
831
  value: new Date(input.data.getTime()),
799
832
  };
800
833
  }
834
+ _addCheck(check) {
835
+ return new ZodDate({
836
+ ...this._def,
837
+ checks: [...this._def.checks, check],
838
+ });
839
+ }
840
+ min(minDate, message) {
841
+ return this._addCheck({
842
+ kind: "min",
843
+ value: minDate.getTime(),
844
+ message: errorUtil_1.errorUtil.toString(message),
845
+ });
846
+ }
847
+ max(maxDate, message) {
848
+ return this._addCheck({
849
+ kind: "max",
850
+ value: maxDate.getTime(),
851
+ message: errorUtil_1.errorUtil.toString(message),
852
+ });
853
+ }
854
+ get minDate() {
855
+ let min = null;
856
+ for (const ch of this._def.checks) {
857
+ if (ch.kind === "min") {
858
+ if (min === null || ch.value > min)
859
+ min = ch.value;
860
+ }
861
+ }
862
+ return min != null ? new Date(min) : null;
863
+ }
864
+ get maxDate() {
865
+ let max = null;
866
+ for (const ch of this._def.checks) {
867
+ if (ch.kind === "max") {
868
+ if (max === null || ch.value < max)
869
+ max = ch.value;
870
+ }
871
+ }
872
+ return max != null ? new Date(max) : null;
873
+ }
801
874
  }
802
875
  exports.ZodDate = ZodDate;
803
876
  ZodDate.create = (params) => {
804
877
  return new ZodDate({
878
+ checks: [],
805
879
  typeName: ZodFirstPartyTypeKind.ZodDate,
806
880
  ...processCreateParams(params),
807
881
  });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "zod",
3
- "version": "3.17.7",
3
+ "version": "3.17.8",
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",