zod 3.17.4 → 3.17.5

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
@@ -453,6 +453,8 @@ z.string().url();
453
453
  z.string().uuid();
454
454
  z.string().cuid();
455
455
  z.string().regex(regex);
456
+ z.string().startsWith(string);
457
+ z.string().endsWith(string);
456
458
 
457
459
  // trim whitespace
458
460
  z.string().trim();
@@ -484,6 +486,8 @@ z.string().length(5, { message: "Must be exactly 5 characters long" });
484
486
  z.string().email({ message: "Invalid email address" });
485
487
  z.string().url({ message: "Invalid url" });
486
488
  z.string().uuid({ message: "Invalid UUID" });
489
+ z.string().startsWith("https://", { message: "Must provide secure URL" });
490
+ z.string().endsWith(".com", { message: "Only .com domains allowed" });
487
491
  ```
488
492
 
489
493
  ## 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;
package/lib/ZodError.js CHANGED
@@ -165,10 +165,23 @@ const defaultErrorMap = (issue, _ctx) => {
165
165
  message = `Invalid date`;
166
166
  break;
167
167
  case exports.ZodIssueCode.invalid_string:
168
- if (issue.validation !== "regex")
168
+ if (typeof issue.validation === "object") {
169
+ if ("startsWith" in issue.validation) {
170
+ message = `Invalid input: must start with "${issue.validation.startsWith}"`;
171
+ }
172
+ else if ("endsWith" in issue.validation) {
173
+ message = `Invalid input: must start with "${issue.validation.endsWith}"`;
174
+ }
175
+ else {
176
+ util_1.util.assertNever(issue.validation);
177
+ }
178
+ }
179
+ else if (issue.validation !== "regex") {
169
180
  message = `Invalid ${issue.validation}`;
170
- else
181
+ }
182
+ else {
171
183
  message = "Invalid";
184
+ }
172
185
  break;
173
186
  case exports.ZodIssueCode.too_small:
174
187
  if (issue.type === "array")
package/lib/index.mjs CHANGED
@@ -278,10 +278,23 @@ const defaultErrorMap = (issue, _ctx) => {
278
278
  message = `Invalid date`;
279
279
  break;
280
280
  case ZodIssueCode.invalid_string:
281
- if (issue.validation !== "regex")
281
+ if (typeof issue.validation === "object") {
282
+ if ("startsWith" in issue.validation) {
283
+ message = `Invalid input: must start with "${issue.validation.startsWith}"`;
284
+ }
285
+ else if ("endsWith" in issue.validation) {
286
+ message = `Invalid input: must start with "${issue.validation.endsWith}"`;
287
+ }
288
+ else {
289
+ util.assertNever(issue.validation);
290
+ }
291
+ }
292
+ else if (issue.validation !== "regex") {
282
293
  message = `Invalid ${issue.validation}`;
283
- else
294
+ }
295
+ else {
284
296
  message = "Invalid";
297
+ }
285
298
  break;
286
299
  case ZodIssueCode.too_small:
287
300
  if (issue.type === "array")
@@ -823,6 +836,28 @@ class ZodString extends ZodType {
823
836
  else if (check.kind === "trim") {
824
837
  input.data = input.data.trim();
825
838
  }
839
+ else if (check.kind === "startsWith") {
840
+ if (!input.data.startsWith(check.value)) {
841
+ ctx = this._getOrReturnCtx(input, ctx);
842
+ addIssueToContext(ctx, {
843
+ code: ZodIssueCode.invalid_string,
844
+ validation: { startsWith: check.value },
845
+ message: check.message,
846
+ });
847
+ status.dirty();
848
+ }
849
+ }
850
+ else if (check.kind === "endsWith") {
851
+ if (!input.data.endsWith(check.value)) {
852
+ ctx = this._getOrReturnCtx(input, ctx);
853
+ addIssueToContext(ctx, {
854
+ code: ZodIssueCode.invalid_string,
855
+ validation: { endsWith: check.value },
856
+ message: check.message,
857
+ });
858
+ status.dirty();
859
+ }
860
+ }
826
861
  else {
827
862
  util.assertNever(check);
828
863
  }
@@ -854,6 +889,20 @@ class ZodString extends ZodType {
854
889
  ...errorUtil.errToObj(message),
855
890
  });
856
891
  }
892
+ startsWith(value, message) {
893
+ return this._addCheck({
894
+ kind: "startsWith",
895
+ value: value,
896
+ ...errorUtil.errToObj(message),
897
+ });
898
+ }
899
+ endsWith(value, message) {
900
+ return this._addCheck({
901
+ kind: "endsWith",
902
+ value: value,
903
+ ...errorUtil.errToObj(message),
904
+ });
905
+ }
857
906
  min(minLength, message) {
858
907
  return this._addCheck({
859
908
  kind: "min",
package/lib/index.umd.js CHANGED
@@ -284,10 +284,23 @@
284
284
  message = `Invalid date`;
285
285
  break;
286
286
  case ZodIssueCode.invalid_string:
287
- if (issue.validation !== "regex")
287
+ if (typeof issue.validation === "object") {
288
+ if ("startsWith" in issue.validation) {
289
+ message = `Invalid input: must start with "${issue.validation.startsWith}"`;
290
+ }
291
+ else if ("endsWith" in issue.validation) {
292
+ message = `Invalid input: must start with "${issue.validation.endsWith}"`;
293
+ }
294
+ else {
295
+ util.assertNever(issue.validation);
296
+ }
297
+ }
298
+ else if (issue.validation !== "regex") {
288
299
  message = `Invalid ${issue.validation}`;
289
- else
300
+ }
301
+ else {
290
302
  message = "Invalid";
303
+ }
291
304
  break;
292
305
  case ZodIssueCode.too_small:
293
306
  if (issue.type === "array")
@@ -829,6 +842,28 @@
829
842
  else if (check.kind === "trim") {
830
843
  input.data = input.data.trim();
831
844
  }
845
+ else if (check.kind === "startsWith") {
846
+ if (!input.data.startsWith(check.value)) {
847
+ ctx = this._getOrReturnCtx(input, ctx);
848
+ addIssueToContext(ctx, {
849
+ code: ZodIssueCode.invalid_string,
850
+ validation: { startsWith: check.value },
851
+ message: check.message,
852
+ });
853
+ status.dirty();
854
+ }
855
+ }
856
+ else if (check.kind === "endsWith") {
857
+ if (!input.data.endsWith(check.value)) {
858
+ ctx = this._getOrReturnCtx(input, ctx);
859
+ addIssueToContext(ctx, {
860
+ code: ZodIssueCode.invalid_string,
861
+ validation: { endsWith: check.value },
862
+ message: check.message,
863
+ });
864
+ status.dirty();
865
+ }
866
+ }
832
867
  else {
833
868
  util.assertNever(check);
834
869
  }
@@ -860,6 +895,20 @@
860
895
  ...errorUtil.errToObj(message),
861
896
  });
862
897
  }
898
+ startsWith(value, message) {
899
+ return this._addCheck({
900
+ kind: "startsWith",
901
+ value: value,
902
+ ...errorUtil.errToObj(message),
903
+ });
904
+ }
905
+ endsWith(value, message) {
906
+ return this._addCheck({
907
+ kind: "endsWith",
908
+ value: value,
909
+ ...errorUtil.errToObj(message),
910
+ });
911
+ }
863
912
  min(minLength, message) {
864
913
  return this._addCheck({
865
914
  kind: "min",
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;
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",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "zod",
3
- "version": "3.17.4",
3
+ "version": "3.17.5",
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",