@embeddable.com/sdk-utils 0.7.3-next.0 → 0.7.4-next.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.
@@ -1,3 +1,3 @@
1
- import { ZodIssue } from "zod/lib/ZodError";
1
+ import { ZodIssue } from "zod";
2
2
  export declare const errorFormatter: (issues: ZodIssue[]) => string[];
3
3
  export declare const formatErrorPath: (path: (string | number)[]) => string;
package/lib/index.esm.js CHANGED
@@ -212,6 +212,9 @@ const ZodIssueCode = util.arrayToEnum([
212
212
  "not_finite",
213
213
  ]);
214
214
  class ZodError extends Error {
215
+ get errors() {
216
+ return this.issues;
217
+ }
215
218
  constructor(issues) {
216
219
  super();
217
220
  this.issues = [];
@@ -232,9 +235,6 @@ class ZodError extends Error {
232
235
  this.name = "ZodError";
233
236
  this.issues = issues;
234
237
  }
235
- get errors() {
236
- return this.issues;
237
- }
238
238
  format(_mapper) {
239
239
  const mapper = _mapper ||
240
240
  function (issue) {
@@ -486,9 +486,9 @@ function addIssueToContext(ctx, issueData) {
486
486
  data: ctx.data,
487
487
  path: ctx.path,
488
488
  errorMaps: [
489
- ctx.common.contextualErrorMap,
490
- ctx.schemaErrorMap,
491
- overrideMap,
489
+ ctx.common.contextualErrorMap, // contextual error map is first priority
490
+ ctx.schemaErrorMap, // then schema-bound map if available
491
+ overrideMap, // then global override map
492
492
  overrideMap === errorMap ? undefined : errorMap, // then global default map
493
493
  ].filter((x) => !!x),
494
494
  });
@@ -661,35 +661,6 @@ function processCreateParams(params) {
661
661
  return { errorMap: customMap, description };
662
662
  }
663
663
  class ZodType {
664
- constructor(def) {
665
- /** Alias of safeParseAsync */
666
- this.spa = this.safeParseAsync;
667
- this._def = def;
668
- this.parse = this.parse.bind(this);
669
- this.safeParse = this.safeParse.bind(this);
670
- this.parseAsync = this.parseAsync.bind(this);
671
- this.safeParseAsync = this.safeParseAsync.bind(this);
672
- this.spa = this.spa.bind(this);
673
- this.refine = this.refine.bind(this);
674
- this.refinement = this.refinement.bind(this);
675
- this.superRefine = this.superRefine.bind(this);
676
- this.optional = this.optional.bind(this);
677
- this.nullable = this.nullable.bind(this);
678
- this.nullish = this.nullish.bind(this);
679
- this.array = this.array.bind(this);
680
- this.promise = this.promise.bind(this);
681
- this.or = this.or.bind(this);
682
- this.and = this.and.bind(this);
683
- this.transform = this.transform.bind(this);
684
- this.brand = this.brand.bind(this);
685
- this.default = this.default.bind(this);
686
- this.catch = this.catch.bind(this);
687
- this.describe = this.describe.bind(this);
688
- this.pipe = this.pipe.bind(this);
689
- this.readonly = this.readonly.bind(this);
690
- this.isNullable = this.isNullable.bind(this);
691
- this.isOptional = this.isOptional.bind(this);
692
- }
693
664
  get description() {
694
665
  return this._def.description;
695
666
  }
@@ -753,6 +724,48 @@ class ZodType {
753
724
  const result = this._parseSync({ data, path: ctx.path, parent: ctx });
754
725
  return handleResult(ctx, result);
755
726
  }
727
+ "~validate"(data) {
728
+ var _a, _b;
729
+ const ctx = {
730
+ common: {
731
+ issues: [],
732
+ async: !!this["~standard"].async,
733
+ },
734
+ path: [],
735
+ schemaErrorMap: this._def.errorMap,
736
+ parent: null,
737
+ data,
738
+ parsedType: getParsedType(data),
739
+ };
740
+ if (!this["~standard"].async) {
741
+ try {
742
+ const result = this._parseSync({ data, path: [], parent: ctx });
743
+ return isValid(result)
744
+ ? {
745
+ value: result.value,
746
+ }
747
+ : {
748
+ issues: ctx.common.issues,
749
+ };
750
+ }
751
+ catch (err) {
752
+ if ((_b = (_a = err === null || err === undefined ? undefined : err.message) === null || _a === undefined ? undefined : _a.toLowerCase()) === null || _b === undefined ? undefined : _b.includes("encountered")) {
753
+ this["~standard"].async = true;
754
+ }
755
+ ctx.common = {
756
+ issues: [],
757
+ async: true,
758
+ };
759
+ }
760
+ }
761
+ return this._parseAsync({ data, path: [], parent: ctx }).then((result) => isValid(result)
762
+ ? {
763
+ value: result.value,
764
+ }
765
+ : {
766
+ issues: ctx.common.issues,
767
+ });
768
+ }
756
769
  async parseAsync(data, params) {
757
770
  const result = await this.safeParseAsync(data, params);
758
771
  if (result.success)
@@ -839,6 +852,40 @@ class ZodType {
839
852
  superRefine(refinement) {
840
853
  return this._refinement(refinement);
841
854
  }
855
+ constructor(def) {
856
+ /** Alias of safeParseAsync */
857
+ this.spa = this.safeParseAsync;
858
+ this._def = def;
859
+ this.parse = this.parse.bind(this);
860
+ this.safeParse = this.safeParse.bind(this);
861
+ this.parseAsync = this.parseAsync.bind(this);
862
+ this.safeParseAsync = this.safeParseAsync.bind(this);
863
+ this.spa = this.spa.bind(this);
864
+ this.refine = this.refine.bind(this);
865
+ this.refinement = this.refinement.bind(this);
866
+ this.superRefine = this.superRefine.bind(this);
867
+ this.optional = this.optional.bind(this);
868
+ this.nullable = this.nullable.bind(this);
869
+ this.nullish = this.nullish.bind(this);
870
+ this.array = this.array.bind(this);
871
+ this.promise = this.promise.bind(this);
872
+ this.or = this.or.bind(this);
873
+ this.and = this.and.bind(this);
874
+ this.transform = this.transform.bind(this);
875
+ this.brand = this.brand.bind(this);
876
+ this.default = this.default.bind(this);
877
+ this.catch = this.catch.bind(this);
878
+ this.describe = this.describe.bind(this);
879
+ this.pipe = this.pipe.bind(this);
880
+ this.readonly = this.readonly.bind(this);
881
+ this.isNullable = this.isNullable.bind(this);
882
+ this.isOptional = this.isOptional.bind(this);
883
+ this["~standard"] = {
884
+ version: 1,
885
+ vendor: "zod",
886
+ validate: (data) => this["~validate"](data),
887
+ };
888
+ }
842
889
  optional() {
843
890
  return ZodOptional.create(this, this._def);
844
891
  }
@@ -849,7 +896,7 @@ class ZodType {
849
896
  return this.nullable().optional();
850
897
  }
851
898
  array() {
852
- return ZodArray.create(this, this._def);
899
+ return ZodArray.create(this);
853
900
  }
854
901
  promise() {
855
902
  return ZodPromise.create(this, this._def);
@@ -915,11 +962,12 @@ class ZodType {
915
962
  }
916
963
  const cuidRegex = /^c[^\s-]{8,}$/i;
917
964
  const cuid2Regex = /^[0-9a-z]+$/;
918
- const ulidRegex = /^[0-9A-HJKMNP-TV-Z]{26}$/;
965
+ const ulidRegex = /^[0-9A-HJKMNP-TV-Z]{26}$/i;
919
966
  // const uuidRegex =
920
967
  // /^([a-f0-9]{8}-[a-f0-9]{4}-[1-5][a-f0-9]{3}-[a-f0-9]{4}-[a-f0-9]{12}|00000000-0000-0000-0000-000000000000)$/i;
921
968
  const uuidRegex = /^[0-9a-fA-F]{8}\b-[0-9a-fA-F]{4}\b-[0-9a-fA-F]{4}\b-[0-9a-fA-F]{4}\b-[0-9a-fA-F]{12}$/i;
922
969
  const nanoidRegex = /^[a-z0-9_-]{21}$/i;
970
+ const jwtRegex = /^[A-Za-z0-9-_]+\.[A-Za-z0-9-_]+\.[A-Za-z0-9-_]*$/;
923
971
  const durationRegex = /^[-+]?P(?!$)(?:(?:[-+]?\d+Y)|(?:[-+]?\d+[.,]\d+Y$))?(?:(?:[-+]?\d+M)|(?:[-+]?\d+[.,]\d+M$))?(?:(?:[-+]?\d+W)|(?:[-+]?\d+[.,]\d+W$))?(?:(?:[-+]?\d+D)|(?:[-+]?\d+[.,]\d+D$))?(?:T(?=[\d+-])(?:(?:[-+]?\d+H)|(?:[-+]?\d+[.,]\d+H$))?(?:(?:[-+]?\d+M)|(?:[-+]?\d+[.,]\d+M$))?(?:[-+]?\d+(?:[.,]\d+)?S)?)??$/;
924
972
  // from https://stackoverflow.com/a/46181/1550155
925
973
  // old version: too slow, didn't support unicode
@@ -941,9 +989,15 @@ const _emojiRegex = `^(\\p{Extended_Pictographic}|\\p{Emoji_Component})+$`;
941
989
  let emojiRegex;
942
990
  // faster, simpler, safer
943
991
  const ipv4Regex = /^(?:(?:25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9][0-9]|[0-9])\.){3}(?:25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9][0-9]|[0-9])$/;
944
- const ipv6Regex = /^(([a-f0-9]{1,4}:){7}|::([a-f0-9]{1,4}:){0,6}|([a-f0-9]{1,4}:){1}:([a-f0-9]{1,4}:){0,5}|([a-f0-9]{1,4}:){2}:([a-f0-9]{1,4}:){0,4}|([a-f0-9]{1,4}:){3}:([a-f0-9]{1,4}:){0,3}|([a-f0-9]{1,4}:){4}:([a-f0-9]{1,4}:){0,2}|([a-f0-9]{1,4}:){5}:([a-f0-9]{1,4}:){0,1})([a-f0-9]{1,4}|(((25[0-5])|(2[0-4][0-9])|(1[0-9]{2})|([0-9]{1,2}))\.){3}((25[0-5])|(2[0-4][0-9])|(1[0-9]{2})|([0-9]{1,2})))$/;
992
+ const ipv4CidrRegex = /^(?:(?:25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9][0-9]|[0-9])\.){3}(?:25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9][0-9]|[0-9])\/(3[0-2]|[12]?[0-9])$/;
993
+ // const ipv6Regex =
994
+ // /^(([a-f0-9]{1,4}:){7}|::([a-f0-9]{1,4}:){0,6}|([a-f0-9]{1,4}:){1}:([a-f0-9]{1,4}:){0,5}|([a-f0-9]{1,4}:){2}:([a-f0-9]{1,4}:){0,4}|([a-f0-9]{1,4}:){3}:([a-f0-9]{1,4}:){0,3}|([a-f0-9]{1,4}:){4}:([a-f0-9]{1,4}:){0,2}|([a-f0-9]{1,4}:){5}:([a-f0-9]{1,4}:){0,1})([a-f0-9]{1,4}|(((25[0-5])|(2[0-4][0-9])|(1[0-9]{2})|([0-9]{1,2}))\.){3}((25[0-5])|(2[0-4][0-9])|(1[0-9]{2})|([0-9]{1,2})))$/;
995
+ const ipv6Regex = /^(([0-9a-fA-F]{1,4}:){7,7}[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,7}:|([0-9a-fA-F]{1,4}:){1,6}:[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,5}(:[0-9a-fA-F]{1,4}){1,2}|([0-9a-fA-F]{1,4}:){1,4}(:[0-9a-fA-F]{1,4}){1,3}|([0-9a-fA-F]{1,4}:){1,3}(:[0-9a-fA-F]{1,4}){1,4}|([0-9a-fA-F]{1,4}:){1,2}(:[0-9a-fA-F]{1,4}){1,5}|[0-9a-fA-F]{1,4}:((:[0-9a-fA-F]{1,4}){1,6})|:((:[0-9a-fA-F]{1,4}){1,7}|:)|fe80:(:[0-9a-fA-F]{0,4}){0,4}%[0-9a-zA-Z]{1,}|::(ffff(:0{1,4}){0,1}:){0,1}((25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])\.){3,3}(25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])|([0-9a-fA-F]{1,4}:){1,4}:((25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])\.){3,3}(25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9]))$/;
996
+ const ipv6CidrRegex = /^(([0-9a-fA-F]{1,4}:){7,7}[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,7}:|([0-9a-fA-F]{1,4}:){1,6}:[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,5}(:[0-9a-fA-F]{1,4}){1,2}|([0-9a-fA-F]{1,4}:){1,4}(:[0-9a-fA-F]{1,4}){1,3}|([0-9a-fA-F]{1,4}:){1,3}(:[0-9a-fA-F]{1,4}){1,4}|([0-9a-fA-F]{1,4}:){1,2}(:[0-9a-fA-F]{1,4}){1,5}|[0-9a-fA-F]{1,4}:((:[0-9a-fA-F]{1,4}){1,6})|:((:[0-9a-fA-F]{1,4}){1,7}|:)|fe80:(:[0-9a-fA-F]{0,4}){0,4}%[0-9a-zA-Z]{1,}|::(ffff(:0{1,4}){0,1}:){0,1}((25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])\.){3,3}(25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])|([0-9a-fA-F]{1,4}:){1,4}:((25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])\.){3,3}(25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9]))\/(12[0-8]|1[01][0-9]|[1-9]?[0-9])$/;
945
997
  // https://stackoverflow.com/questions/7860392/determine-if-string-is-in-base64-using-javascript
946
998
  const base64Regex = /^([0-9a-zA-Z+/]{4})*(([0-9a-zA-Z+/]{2}==)|([0-9a-zA-Z+/]{3}=))?$/;
999
+ // https://base64.guru/standards/base64url
1000
+ const base64urlRegex = /^([0-9a-zA-Z-_]{4})*(([0-9a-zA-Z-_]{2}(==)?)|([0-9a-zA-Z-_]{3}(=)?))?$/;
947
1001
  // simple
948
1002
  // const dateRegexSource = `\\d{4}-\\d{2}-\\d{2}`;
949
1003
  // no leap year validation
@@ -984,6 +1038,38 @@ function isValidIP(ip, version) {
984
1038
  }
985
1039
  return false;
986
1040
  }
1041
+ function isValidJWT(jwt, alg) {
1042
+ if (!jwtRegex.test(jwt))
1043
+ return false;
1044
+ try {
1045
+ const [header] = jwt.split(".");
1046
+ // Convert base64url to base64
1047
+ const base64 = header
1048
+ .replace(/-/g, "+")
1049
+ .replace(/_/g, "/")
1050
+ .padEnd(header.length + ((4 - (header.length % 4)) % 4), "=");
1051
+ const decoded = JSON.parse(atob(base64));
1052
+ if (typeof decoded !== "object" || decoded === null)
1053
+ return false;
1054
+ if (!decoded.typ || !decoded.alg)
1055
+ return false;
1056
+ if (alg && decoded.alg !== alg)
1057
+ return false;
1058
+ return true;
1059
+ }
1060
+ catch (_a) {
1061
+ return false;
1062
+ }
1063
+ }
1064
+ function isValidCidr(ip, version) {
1065
+ if ((version === "v4" || !version) && ipv4CidrRegex.test(ip)) {
1066
+ return true;
1067
+ }
1068
+ if ((version === "v6" || !version) && ipv6CidrRegex.test(ip)) {
1069
+ return true;
1070
+ }
1071
+ return false;
1072
+ }
987
1073
  class ZodString extends ZodType {
988
1074
  _parse(input) {
989
1075
  if (this._def.coerce) {
@@ -1265,6 +1351,28 @@ class ZodString extends ZodType {
1265
1351
  status.dirty();
1266
1352
  }
1267
1353
  }
1354
+ else if (check.kind === "jwt") {
1355
+ if (!isValidJWT(input.data, check.alg)) {
1356
+ ctx = this._getOrReturnCtx(input, ctx);
1357
+ addIssueToContext(ctx, {
1358
+ validation: "jwt",
1359
+ code: ZodIssueCode.invalid_string,
1360
+ message: check.message,
1361
+ });
1362
+ status.dirty();
1363
+ }
1364
+ }
1365
+ else if (check.kind === "cidr") {
1366
+ if (!isValidCidr(input.data, check.version)) {
1367
+ ctx = this._getOrReturnCtx(input, ctx);
1368
+ addIssueToContext(ctx, {
1369
+ validation: "cidr",
1370
+ code: ZodIssueCode.invalid_string,
1371
+ message: check.message,
1372
+ });
1373
+ status.dirty();
1374
+ }
1375
+ }
1268
1376
  else if (check.kind === "base64") {
1269
1377
  if (!base64Regex.test(input.data)) {
1270
1378
  ctx = this._getOrReturnCtx(input, ctx);
@@ -1276,6 +1384,17 @@ class ZodString extends ZodType {
1276
1384
  status.dirty();
1277
1385
  }
1278
1386
  }
1387
+ else if (check.kind === "base64url") {
1388
+ if (!base64urlRegex.test(input.data)) {
1389
+ ctx = this._getOrReturnCtx(input, ctx);
1390
+ addIssueToContext(ctx, {
1391
+ validation: "base64url",
1392
+ code: ZodIssueCode.invalid_string,
1393
+ message: check.message,
1394
+ });
1395
+ status.dirty();
1396
+ }
1397
+ }
1279
1398
  else {
1280
1399
  util.assertNever(check);
1281
1400
  }
@@ -1322,9 +1441,22 @@ class ZodString extends ZodType {
1322
1441
  base64(message) {
1323
1442
  return this._addCheck({ kind: "base64", ...errorUtil.errToObj(message) });
1324
1443
  }
1444
+ base64url(message) {
1445
+ // base64url encoding is a modification of base64 that can safely be used in URLs and filenames
1446
+ return this._addCheck({
1447
+ kind: "base64url",
1448
+ ...errorUtil.errToObj(message),
1449
+ });
1450
+ }
1451
+ jwt(options) {
1452
+ return this._addCheck({ kind: "jwt", ...errorUtil.errToObj(options) });
1453
+ }
1325
1454
  ip(options) {
1326
1455
  return this._addCheck({ kind: "ip", ...errorUtil.errToObj(options) });
1327
1456
  }
1457
+ cidr(options) {
1458
+ return this._addCheck({ kind: "cidr", ...errorUtil.errToObj(options) });
1459
+ }
1328
1460
  datetime(options) {
1329
1461
  var _a, _b;
1330
1462
  if (typeof options === "string") {
@@ -1415,8 +1547,7 @@ class ZodString extends ZodType {
1415
1547
  });
1416
1548
  }
1417
1549
  /**
1418
- * @deprecated Use z.string().min(1) instead.
1419
- * @see {@link ZodString.min}
1550
+ * Equivalent to `.min(1)`
1420
1551
  */
1421
1552
  nonempty(message) {
1422
1553
  return this.min(1, errorUtil.errToObj(message));
@@ -1478,9 +1609,16 @@ class ZodString extends ZodType {
1478
1609
  get isIP() {
1479
1610
  return !!this._def.checks.find((ch) => ch.kind === "ip");
1480
1611
  }
1612
+ get isCIDR() {
1613
+ return !!this._def.checks.find((ch) => ch.kind === "cidr");
1614
+ }
1481
1615
  get isBase64() {
1482
1616
  return !!this._def.checks.find((ch) => ch.kind === "base64");
1483
1617
  }
1618
+ get isBase64url() {
1619
+ // base64url encoding is a modification of base64 that can safely be used in URLs and filenames
1620
+ return !!this._def.checks.find((ch) => ch.kind === "base64url");
1621
+ }
1484
1622
  get minLength() {
1485
1623
  let min = null;
1486
1624
  for (const ch of this._def.checks) {
@@ -1773,17 +1911,16 @@ class ZodBigInt extends ZodType {
1773
1911
  }
1774
1912
  _parse(input) {
1775
1913
  if (this._def.coerce) {
1776
- input.data = BigInt(input.data);
1914
+ try {
1915
+ input.data = BigInt(input.data);
1916
+ }
1917
+ catch (_a) {
1918
+ return this._getInvalidInput(input);
1919
+ }
1777
1920
  }
1778
1921
  const parsedType = this._getType(input);
1779
1922
  if (parsedType !== ZodParsedType.bigint) {
1780
- const ctx = this._getOrReturnCtx(input);
1781
- addIssueToContext(ctx, {
1782
- code: ZodIssueCode.invalid_type,
1783
- expected: ZodParsedType.bigint,
1784
- received: ctx.parsedType,
1785
- });
1786
- return INVALID;
1923
+ return this._getInvalidInput(input);
1787
1924
  }
1788
1925
  let ctx = undefined;
1789
1926
  const status = new ParseStatus();
@@ -1837,6 +1974,15 @@ class ZodBigInt extends ZodType {
1837
1974
  }
1838
1975
  return { status: status.value, value: input.data };
1839
1976
  }
1977
+ _getInvalidInput(input) {
1978
+ const ctx = this._getOrReturnCtx(input);
1979
+ addIssueToContext(ctx, {
1980
+ code: ZodIssueCode.invalid_type,
1981
+ expected: ZodParsedType.bigint,
1982
+ received: ctx.parsedType,
1983
+ });
1984
+ return INVALID;
1985
+ }
1840
1986
  gte(value, message) {
1841
1987
  return this.setLimit("min", value, true, errorUtil.toString(message));
1842
1988
  }