checks.js 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575
  1. // import { $ZodType } from "./schemas.js";
  2. import * as core from "./core.js";
  3. import * as regexes from "./regexes.js";
  4. import * as util from "./util.js";
  5. export const $ZodCheck = /*@__PURE__*/ core.$constructor("$ZodCheck", (inst, def) => {
  6. var _a;
  7. inst._zod ?? (inst._zod = {});
  8. inst._zod.def = def;
  9. (_a = inst._zod).onattach ?? (_a.onattach = []);
  10. });
  11. const numericOriginMap = {
  12. number: "number",
  13. bigint: "bigint",
  14. object: "date",
  15. };
  16. export const $ZodCheckLessThan = /*@__PURE__*/ core.$constructor("$ZodCheckLessThan", (inst, def) => {
  17. $ZodCheck.init(inst, def);
  18. const origin = numericOriginMap[typeof def.value];
  19. inst._zod.onattach.push((inst) => {
  20. const bag = inst._zod.bag;
  21. const curr = (def.inclusive ? bag.maximum : bag.exclusiveMaximum) ?? Number.POSITIVE_INFINITY;
  22. if (def.value < curr) {
  23. if (def.inclusive)
  24. bag.maximum = def.value;
  25. else
  26. bag.exclusiveMaximum = def.value;
  27. }
  28. });
  29. inst._zod.check = (payload) => {
  30. if (def.inclusive ? payload.value <= def.value : payload.value < def.value) {
  31. return;
  32. }
  33. payload.issues.push({
  34. origin,
  35. code: "too_big",
  36. maximum: typeof def.value === "object" ? def.value.getTime() : def.value,
  37. input: payload.value,
  38. inclusive: def.inclusive,
  39. inst,
  40. continue: !def.abort,
  41. });
  42. };
  43. });
  44. export const $ZodCheckGreaterThan = /*@__PURE__*/ core.$constructor("$ZodCheckGreaterThan", (inst, def) => {
  45. $ZodCheck.init(inst, def);
  46. const origin = numericOriginMap[typeof def.value];
  47. inst._zod.onattach.push((inst) => {
  48. const bag = inst._zod.bag;
  49. const curr = (def.inclusive ? bag.minimum : bag.exclusiveMinimum) ?? Number.NEGATIVE_INFINITY;
  50. if (def.value > curr) {
  51. if (def.inclusive)
  52. bag.minimum = def.value;
  53. else
  54. bag.exclusiveMinimum = def.value;
  55. }
  56. });
  57. inst._zod.check = (payload) => {
  58. if (def.inclusive ? payload.value >= def.value : payload.value > def.value) {
  59. return;
  60. }
  61. payload.issues.push({
  62. origin,
  63. code: "too_small",
  64. minimum: typeof def.value === "object" ? def.value.getTime() : def.value,
  65. input: payload.value,
  66. inclusive: def.inclusive,
  67. inst,
  68. continue: !def.abort,
  69. });
  70. };
  71. });
  72. export const $ZodCheckMultipleOf =
  73. /*@__PURE__*/ core.$constructor("$ZodCheckMultipleOf", (inst, def) => {
  74. $ZodCheck.init(inst, def);
  75. inst._zod.onattach.push((inst) => {
  76. var _a;
  77. (_a = inst._zod.bag).multipleOf ?? (_a.multipleOf = def.value);
  78. });
  79. inst._zod.check = (payload) => {
  80. if (typeof payload.value !== typeof def.value)
  81. throw new Error("Cannot mix number and bigint in multiple_of check.");
  82. const isMultiple = typeof payload.value === "bigint"
  83. ? payload.value % def.value === BigInt(0)
  84. : util.floatSafeRemainder(payload.value, def.value) === 0;
  85. if (isMultiple)
  86. return;
  87. payload.issues.push({
  88. origin: typeof payload.value,
  89. code: "not_multiple_of",
  90. divisor: def.value,
  91. input: payload.value,
  92. inst,
  93. continue: !def.abort,
  94. });
  95. };
  96. });
  97. export const $ZodCheckNumberFormat = /*@__PURE__*/ core.$constructor("$ZodCheckNumberFormat", (inst, def) => {
  98. $ZodCheck.init(inst, def); // no format checks
  99. def.format = def.format || "float64";
  100. const isInt = def.format?.includes("int");
  101. const origin = isInt ? "int" : "number";
  102. const [minimum, maximum] = util.NUMBER_FORMAT_RANGES[def.format];
  103. inst._zod.onattach.push((inst) => {
  104. const bag = inst._zod.bag;
  105. bag.format = def.format;
  106. bag.minimum = minimum;
  107. bag.maximum = maximum;
  108. if (isInt)
  109. bag.pattern = regexes.integer;
  110. });
  111. inst._zod.check = (payload) => {
  112. const input = payload.value;
  113. if (isInt) {
  114. if (!Number.isInteger(input)) {
  115. // invalid_format issue
  116. // payload.issues.push({
  117. // expected: def.format,
  118. // format: def.format,
  119. // code: "invalid_format",
  120. // input,
  121. // inst,
  122. // });
  123. // invalid_type issue
  124. payload.issues.push({
  125. expected: origin,
  126. format: def.format,
  127. code: "invalid_type",
  128. continue: false,
  129. input,
  130. inst,
  131. });
  132. return;
  133. // not_multiple_of issue
  134. // payload.issues.push({
  135. // code: "not_multiple_of",
  136. // origin: "number",
  137. // input,
  138. // inst,
  139. // divisor: 1,
  140. // });
  141. }
  142. if (!Number.isSafeInteger(input)) {
  143. if (input > 0) {
  144. // too_big
  145. payload.issues.push({
  146. input,
  147. code: "too_big",
  148. maximum: Number.MAX_SAFE_INTEGER,
  149. note: "Integers must be within the safe integer range.",
  150. inst,
  151. origin,
  152. inclusive: true,
  153. continue: !def.abort,
  154. });
  155. }
  156. else {
  157. // too_small
  158. payload.issues.push({
  159. input,
  160. code: "too_small",
  161. minimum: Number.MIN_SAFE_INTEGER,
  162. note: "Integers must be within the safe integer range.",
  163. inst,
  164. origin,
  165. inclusive: true,
  166. continue: !def.abort,
  167. });
  168. }
  169. return;
  170. }
  171. }
  172. if (input < minimum) {
  173. payload.issues.push({
  174. origin: "number",
  175. input,
  176. code: "too_small",
  177. minimum,
  178. inclusive: true,
  179. inst,
  180. continue: !def.abort,
  181. });
  182. }
  183. if (input > maximum) {
  184. payload.issues.push({
  185. origin: "number",
  186. input,
  187. code: "too_big",
  188. maximum,
  189. inclusive: true,
  190. inst,
  191. continue: !def.abort,
  192. });
  193. }
  194. };
  195. });
  196. export const $ZodCheckBigIntFormat = /*@__PURE__*/ core.$constructor("$ZodCheckBigIntFormat", (inst, def) => {
  197. $ZodCheck.init(inst, def); // no format checks
  198. const [minimum, maximum] = util.BIGINT_FORMAT_RANGES[def.format];
  199. inst._zod.onattach.push((inst) => {
  200. const bag = inst._zod.bag;
  201. bag.format = def.format;
  202. bag.minimum = minimum;
  203. bag.maximum = maximum;
  204. });
  205. inst._zod.check = (payload) => {
  206. const input = payload.value;
  207. if (input < minimum) {
  208. payload.issues.push({
  209. origin: "bigint",
  210. input,
  211. code: "too_small",
  212. minimum: minimum,
  213. inclusive: true,
  214. inst,
  215. continue: !def.abort,
  216. });
  217. }
  218. if (input > maximum) {
  219. payload.issues.push({
  220. origin: "bigint",
  221. input,
  222. code: "too_big",
  223. maximum,
  224. inclusive: true,
  225. inst,
  226. continue: !def.abort,
  227. });
  228. }
  229. };
  230. });
  231. export const $ZodCheckMaxSize = /*@__PURE__*/ core.$constructor("$ZodCheckMaxSize", (inst, def) => {
  232. var _a;
  233. $ZodCheck.init(inst, def);
  234. (_a = inst._zod.def).when ?? (_a.when = (payload) => {
  235. const val = payload.value;
  236. return !util.nullish(val) && val.size !== undefined;
  237. });
  238. inst._zod.onattach.push((inst) => {
  239. const curr = (inst._zod.bag.maximum ?? Number.POSITIVE_INFINITY);
  240. if (def.maximum < curr)
  241. inst._zod.bag.maximum = def.maximum;
  242. });
  243. inst._zod.check = (payload) => {
  244. const input = payload.value;
  245. const size = input.size;
  246. if (size <= def.maximum)
  247. return;
  248. payload.issues.push({
  249. origin: util.getSizableOrigin(input),
  250. code: "too_big",
  251. maximum: def.maximum,
  252. inclusive: true,
  253. input,
  254. inst,
  255. continue: !def.abort,
  256. });
  257. };
  258. });
  259. export const $ZodCheckMinSize = /*@__PURE__*/ core.$constructor("$ZodCheckMinSize", (inst, def) => {
  260. var _a;
  261. $ZodCheck.init(inst, def);
  262. (_a = inst._zod.def).when ?? (_a.when = (payload) => {
  263. const val = payload.value;
  264. return !util.nullish(val) && val.size !== undefined;
  265. });
  266. inst._zod.onattach.push((inst) => {
  267. const curr = (inst._zod.bag.minimum ?? Number.NEGATIVE_INFINITY);
  268. if (def.minimum > curr)
  269. inst._zod.bag.minimum = def.minimum;
  270. });
  271. inst._zod.check = (payload) => {
  272. const input = payload.value;
  273. const size = input.size;
  274. if (size >= def.minimum)
  275. return;
  276. payload.issues.push({
  277. origin: util.getSizableOrigin(input),
  278. code: "too_small",
  279. minimum: def.minimum,
  280. inclusive: true,
  281. input,
  282. inst,
  283. continue: !def.abort,
  284. });
  285. };
  286. });
  287. export const $ZodCheckSizeEquals = /*@__PURE__*/ core.$constructor("$ZodCheckSizeEquals", (inst, def) => {
  288. var _a;
  289. $ZodCheck.init(inst, def);
  290. (_a = inst._zod.def).when ?? (_a.when = (payload) => {
  291. const val = payload.value;
  292. return !util.nullish(val) && val.size !== undefined;
  293. });
  294. inst._zod.onattach.push((inst) => {
  295. const bag = inst._zod.bag;
  296. bag.minimum = def.size;
  297. bag.maximum = def.size;
  298. bag.size = def.size;
  299. });
  300. inst._zod.check = (payload) => {
  301. const input = payload.value;
  302. const size = input.size;
  303. if (size === def.size)
  304. return;
  305. const tooBig = size > def.size;
  306. payload.issues.push({
  307. origin: util.getSizableOrigin(input),
  308. ...(tooBig ? { code: "too_big", maximum: def.size } : { code: "too_small", minimum: def.size }),
  309. inclusive: true,
  310. exact: true,
  311. input: payload.value,
  312. inst,
  313. continue: !def.abort,
  314. });
  315. };
  316. });
  317. export const $ZodCheckMaxLength = /*@__PURE__*/ core.$constructor("$ZodCheckMaxLength", (inst, def) => {
  318. var _a;
  319. $ZodCheck.init(inst, def);
  320. (_a = inst._zod.def).when ?? (_a.when = (payload) => {
  321. const val = payload.value;
  322. return !util.nullish(val) && val.length !== undefined;
  323. });
  324. inst._zod.onattach.push((inst) => {
  325. const curr = (inst._zod.bag.maximum ?? Number.POSITIVE_INFINITY);
  326. if (def.maximum < curr)
  327. inst._zod.bag.maximum = def.maximum;
  328. });
  329. inst._zod.check = (payload) => {
  330. const input = payload.value;
  331. const length = input.length;
  332. if (length <= def.maximum)
  333. return;
  334. const origin = util.getLengthableOrigin(input);
  335. payload.issues.push({
  336. origin,
  337. code: "too_big",
  338. maximum: def.maximum,
  339. inclusive: true,
  340. input,
  341. inst,
  342. continue: !def.abort,
  343. });
  344. };
  345. });
  346. export const $ZodCheckMinLength = /*@__PURE__*/ core.$constructor("$ZodCheckMinLength", (inst, def) => {
  347. var _a;
  348. $ZodCheck.init(inst, def);
  349. (_a = inst._zod.def).when ?? (_a.when = (payload) => {
  350. const val = payload.value;
  351. return !util.nullish(val) && val.length !== undefined;
  352. });
  353. inst._zod.onattach.push((inst) => {
  354. const curr = (inst._zod.bag.minimum ?? Number.NEGATIVE_INFINITY);
  355. if (def.minimum > curr)
  356. inst._zod.bag.minimum = def.minimum;
  357. });
  358. inst._zod.check = (payload) => {
  359. const input = payload.value;
  360. const length = input.length;
  361. if (length >= def.minimum)
  362. return;
  363. const origin = util.getLengthableOrigin(input);
  364. payload.issues.push({
  365. origin,
  366. code: "too_small",
  367. minimum: def.minimum,
  368. inclusive: true,
  369. input,
  370. inst,
  371. continue: !def.abort,
  372. });
  373. };
  374. });
  375. export const $ZodCheckLengthEquals = /*@__PURE__*/ core.$constructor("$ZodCheckLengthEquals", (inst, def) => {
  376. var _a;
  377. $ZodCheck.init(inst, def);
  378. (_a = inst._zod.def).when ?? (_a.when = (payload) => {
  379. const val = payload.value;
  380. return !util.nullish(val) && val.length !== undefined;
  381. });
  382. inst._zod.onattach.push((inst) => {
  383. const bag = inst._zod.bag;
  384. bag.minimum = def.length;
  385. bag.maximum = def.length;
  386. bag.length = def.length;
  387. });
  388. inst._zod.check = (payload) => {
  389. const input = payload.value;
  390. const length = input.length;
  391. if (length === def.length)
  392. return;
  393. const origin = util.getLengthableOrigin(input);
  394. const tooBig = length > def.length;
  395. payload.issues.push({
  396. origin,
  397. ...(tooBig ? { code: "too_big", maximum: def.length } : { code: "too_small", minimum: def.length }),
  398. inclusive: true,
  399. exact: true,
  400. input: payload.value,
  401. inst,
  402. continue: !def.abort,
  403. });
  404. };
  405. });
  406. export const $ZodCheckStringFormat = /*@__PURE__*/ core.$constructor("$ZodCheckStringFormat", (inst, def) => {
  407. var _a, _b;
  408. $ZodCheck.init(inst, def);
  409. inst._zod.onattach.push((inst) => {
  410. const bag = inst._zod.bag;
  411. bag.format = def.format;
  412. if (def.pattern) {
  413. bag.patterns ?? (bag.patterns = new Set());
  414. bag.patterns.add(def.pattern);
  415. }
  416. });
  417. if (def.pattern)
  418. (_a = inst._zod).check ?? (_a.check = (payload) => {
  419. def.pattern.lastIndex = 0;
  420. if (def.pattern.test(payload.value))
  421. return;
  422. payload.issues.push({
  423. origin: "string",
  424. code: "invalid_format",
  425. format: def.format,
  426. input: payload.value,
  427. ...(def.pattern ? { pattern: def.pattern.toString() } : {}),
  428. inst,
  429. continue: !def.abort,
  430. });
  431. });
  432. else
  433. (_b = inst._zod).check ?? (_b.check = () => { });
  434. });
  435. export const $ZodCheckRegex = /*@__PURE__*/ core.$constructor("$ZodCheckRegex", (inst, def) => {
  436. $ZodCheckStringFormat.init(inst, def);
  437. inst._zod.check = (payload) => {
  438. def.pattern.lastIndex = 0;
  439. if (def.pattern.test(payload.value))
  440. return;
  441. payload.issues.push({
  442. origin: "string",
  443. code: "invalid_format",
  444. format: "regex",
  445. input: payload.value,
  446. pattern: def.pattern.toString(),
  447. inst,
  448. continue: !def.abort,
  449. });
  450. };
  451. });
  452. export const $ZodCheckLowerCase = /*@__PURE__*/ core.$constructor("$ZodCheckLowerCase", (inst, def) => {
  453. def.pattern ?? (def.pattern = regexes.lowercase);
  454. $ZodCheckStringFormat.init(inst, def);
  455. });
  456. export const $ZodCheckUpperCase = /*@__PURE__*/ core.$constructor("$ZodCheckUpperCase", (inst, def) => {
  457. def.pattern ?? (def.pattern = regexes.uppercase);
  458. $ZodCheckStringFormat.init(inst, def);
  459. });
  460. export const $ZodCheckIncludes = /*@__PURE__*/ core.$constructor("$ZodCheckIncludes", (inst, def) => {
  461. $ZodCheck.init(inst, def);
  462. const escapedRegex = util.escapeRegex(def.includes);
  463. const pattern = new RegExp(typeof def.position === "number" ? `^.{${def.position}}${escapedRegex}` : escapedRegex);
  464. def.pattern = pattern;
  465. inst._zod.onattach.push((inst) => {
  466. const bag = inst._zod.bag;
  467. bag.patterns ?? (bag.patterns = new Set());
  468. bag.patterns.add(pattern);
  469. });
  470. inst._zod.check = (payload) => {
  471. if (payload.value.includes(def.includes, def.position))
  472. return;
  473. payload.issues.push({
  474. origin: "string",
  475. code: "invalid_format",
  476. format: "includes",
  477. includes: def.includes,
  478. input: payload.value,
  479. inst,
  480. continue: !def.abort,
  481. });
  482. };
  483. });
  484. export const $ZodCheckStartsWith = /*@__PURE__*/ core.$constructor("$ZodCheckStartsWith", (inst, def) => {
  485. $ZodCheck.init(inst, def);
  486. const pattern = new RegExp(`^${util.escapeRegex(def.prefix)}.*`);
  487. def.pattern ?? (def.pattern = pattern);
  488. inst._zod.onattach.push((inst) => {
  489. const bag = inst._zod.bag;
  490. bag.patterns ?? (bag.patterns = new Set());
  491. bag.patterns.add(pattern);
  492. });
  493. inst._zod.check = (payload) => {
  494. if (payload.value.startsWith(def.prefix))
  495. return;
  496. payload.issues.push({
  497. origin: "string",
  498. code: "invalid_format",
  499. format: "starts_with",
  500. prefix: def.prefix,
  501. input: payload.value,
  502. inst,
  503. continue: !def.abort,
  504. });
  505. };
  506. });
  507. export const $ZodCheckEndsWith = /*@__PURE__*/ core.$constructor("$ZodCheckEndsWith", (inst, def) => {
  508. $ZodCheck.init(inst, def);
  509. const pattern = new RegExp(`.*${util.escapeRegex(def.suffix)}$`);
  510. def.pattern ?? (def.pattern = pattern);
  511. inst._zod.onattach.push((inst) => {
  512. const bag = inst._zod.bag;
  513. bag.patterns ?? (bag.patterns = new Set());
  514. bag.patterns.add(pattern);
  515. });
  516. inst._zod.check = (payload) => {
  517. if (payload.value.endsWith(def.suffix))
  518. return;
  519. payload.issues.push({
  520. origin: "string",
  521. code: "invalid_format",
  522. format: "ends_with",
  523. suffix: def.suffix,
  524. input: payload.value,
  525. inst,
  526. continue: !def.abort,
  527. });
  528. };
  529. });
  530. ///////////////////////////////////
  531. ///// $ZodCheckProperty /////
  532. ///////////////////////////////////
  533. function handleCheckPropertyResult(result, payload, property) {
  534. if (result.issues.length) {
  535. payload.issues.push(...util.prefixIssues(property, result.issues));
  536. }
  537. }
  538. export const $ZodCheckProperty = /*@__PURE__*/ core.$constructor("$ZodCheckProperty", (inst, def) => {
  539. $ZodCheck.init(inst, def);
  540. inst._zod.check = (payload) => {
  541. const result = def.schema._zod.run({
  542. value: payload.value[def.property],
  543. issues: [],
  544. }, {});
  545. if (result instanceof Promise) {
  546. return result.then((result) => handleCheckPropertyResult(result, payload, def.property));
  547. }
  548. handleCheckPropertyResult(result, payload, def.property);
  549. return;
  550. };
  551. });
  552. export const $ZodCheckMimeType = /*@__PURE__*/ core.$constructor("$ZodCheckMimeType", (inst, def) => {
  553. $ZodCheck.init(inst, def);
  554. const mimeSet = new Set(def.mime);
  555. inst._zod.onattach.push((inst) => {
  556. inst._zod.bag.mime = def.mime;
  557. });
  558. inst._zod.check = (payload) => {
  559. if (mimeSet.has(payload.value.type))
  560. return;
  561. payload.issues.push({
  562. code: "invalid_value",
  563. values: def.mime,
  564. input: payload.value.type,
  565. inst,
  566. continue: !def.abort,
  567. });
  568. };
  569. });
  570. export const $ZodCheckOverwrite = /*@__PURE__*/ core.$constructor("$ZodCheckOverwrite", (inst, def) => {
  571. $ZodCheck.init(inst, def);
  572. inst._zod.check = (payload) => {
  573. payload.value = def.tx(payload.value);
  574. };
  575. });