@banzamel/mineralui 1.11.1 → 2.0.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.
Files changed (61) hide show
  1. package/README.md +1 -1
  2. package/dist/MConflictIllustration-DfNfvv7Q.cjs +2 -0
  3. package/dist/MConflictIllustration-DfNfvv7Q.cjs.map +1 -0
  4. package/dist/{MConflictIllustration-Ctggjn7z.js → MConflictIllustration-Drsm8_8C.js} +41 -99
  5. package/dist/MConflictIllustration-Drsm8_8C.js.map +1 -0
  6. package/dist/{cards-CvgcQCAP.js → cards-C2t-pM0r.js} +12 -11
  7. package/dist/cards-C2t-pM0r.js.map +1 -0
  8. package/dist/{cards-O0osWbUF.cjs → cards-D7_hH3Q8.cjs} +2 -2
  9. package/dist/cards-D7_hH3Q8.cjs.map +1 -0
  10. package/dist/cards.cjs +1 -1
  11. package/dist/cards.js +1 -1
  12. package/dist/components/inputs/MInputUrl/MInputUrl.d.ts +3 -0
  13. package/dist/components/inputs/MInputUrl/MInputUrl.types.d.ts +27 -0
  14. package/dist/components/inputs/MInputUrl/index.d.ts +2 -0
  15. package/dist/components/inputs/index.d.ts +2 -0
  16. package/dist/{dropdowns-C9jREjLg.js → dropdowns-BJ8s18h2.js} +2 -2
  17. package/dist/dropdowns-BJ8s18h2.js.map +1 -0
  18. package/dist/{dropdowns-BP2HBR-x.cjs → dropdowns-BLd4lyr6.cjs} +2 -2
  19. package/dist/dropdowns-BLd4lyr6.cjs.map +1 -0
  20. package/dist/dropdowns.cjs +1 -1
  21. package/dist/dropdowns.js +1 -1
  22. package/dist/{form-D5F1kTIA.cjs → form-Bni0Gf_s.cjs} +2 -2
  23. package/dist/{form-D5F1kTIA.cjs.map → form-Bni0Gf_s.cjs.map} +1 -1
  24. package/dist/{form-CWoOQ_qo.js → form-CFhDAU18.js} +2 -2
  25. package/dist/{form-CWoOQ_qo.js.map → form-CFhDAU18.js.map} +1 -1
  26. package/dist/form.cjs +1 -1
  27. package/dist/form.js +1 -1
  28. package/dist/i18n/frameworkTexts.d.ts +0 -29
  29. package/dist/illustrations/index.d.ts +0 -1
  30. package/dist/illustrations.cjs +1 -1
  31. package/dist/illustrations.js +2 -2
  32. package/dist/index.cjs +1 -1
  33. package/dist/index.js +42 -42
  34. package/dist/inputs-BpdfT9Hp.cjs +2 -0
  35. package/dist/inputs-BpdfT9Hp.cjs.map +1 -0
  36. package/dist/{inputs-bbwdb6m3.js → inputs-CyDoEfL3.js} +333 -284
  37. package/dist/inputs-CyDoEfL3.js.map +1 -0
  38. package/dist/inputs.cjs +1 -1
  39. package/dist/inputs.js +3 -3
  40. package/dist/style-runtime.cjs +1 -1
  41. package/dist/style-runtime.js +1 -1
  42. package/dist/styles.css +1 -1
  43. package/dist/utils/validators.d.ts +14 -0
  44. package/dist/utils.cjs +1 -1
  45. package/dist/utils.js +2 -2
  46. package/dist/{validators-DRhikiAi.cjs → validators-B6yWdsu2.cjs} +2 -2
  47. package/dist/{validators-DRhikiAi.cjs.map → validators-B6yWdsu2.cjs.map} +1 -1
  48. package/dist/{validators-D5OCyV2h.js → validators-DVYOtFnw.js} +19 -2
  49. package/dist/{validators-D5OCyV2h.js.map → validators-DVYOtFnw.js.map} +1 -1
  50. package/package.json +1 -1
  51. package/dist/MConflictIllustration-CfYeZVmf.cjs +0 -2
  52. package/dist/MConflictIllustration-CfYeZVmf.cjs.map +0 -1
  53. package/dist/MConflictIllustration-Ctggjn7z.js.map +0 -1
  54. package/dist/cards-CvgcQCAP.js.map +0 -1
  55. package/dist/cards-O0osWbUF.cjs.map +0 -1
  56. package/dist/dropdowns-BP2HBR-x.cjs.map +0 -1
  57. package/dist/dropdowns-C9jREjLg.js.map +0 -1
  58. package/dist/illustrations/scenes/MCookieConsentIllustration.d.ts +0 -2
  59. package/dist/inputs-D38ib0gM.cjs +0 -2
  60. package/dist/inputs-D38ib0gM.cjs.map +0 -1
  61. package/dist/inputs-bbwdb6m3.js.map +0 -1
@@ -27,3 +27,17 @@ export declare function parseDateString(value: string, format?: DateFormat): Dat
27
27
  export declare function validateDate(value: string, options?: DateValidationOptions): ValidationResult;
28
28
  export { validatePostCode } from './postalCodes';
29
29
  export { validateCardNumber } from './creditCards';
30
+ export interface UrlValidationOptions {
31
+ /**
32
+ * Allowed URL protocols (without trailing colon). When the value carries a
33
+ * protocol, it must be one of these. Defaults to `['http', 'https']`.
34
+ */
35
+ protocols?: string[];
36
+ /**
37
+ * When `true` (default), the value must include a protocol from `protocols`.
38
+ * When `false`, a protocol-less value (e.g. `example.com/path`) still passes
39
+ * as long as it parses as a URL after a synthetic `https://` prefix.
40
+ */
41
+ requireProtocol?: boolean;
42
+ }
43
+ export declare function validateUrl(value: string, options?: UrlValidationOptions): ValidationResult;
package/dist/utils.cjs CHANGED
@@ -1,3 +1,3 @@
1
1
  const {ensureStyles}=require('./style-runtime.cjs')
2
2
  ensureStyles()
3
- Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});const e=require(`./cn-CU5TNITO.cjs`),t=require(`./validators-DRhikiAi.cjs`),n=require(`./creditCards-D_HwRUBz.cjs`),r=require(`./formatters-CNjg_h7-.cjs`),i=require(`./dateUtils-Dq1vaA-D.cjs`),a=require(`./relativeTime-DgYBUaVm.cjs`),o=require(`./useGhostText-BFaUUKid.cjs`),s=require(`./licensing-sRHTvX0B.cjs`),c=require(`./useKeyboardNav-CtGPfQX7.cjs`),l=require(`./useInteractionEffect-BH2dgQla.cjs`);exports.addMonths=i.t,exports.addYears=i.n,exports.adjustCursorAfterFormat=r.t,exports.capitalizeWords=r.n,exports.cn=e.t,exports.composeValidators=t.t,exports.creditCardBrands=n.t,exports.daysInMonth=i.i,exports.detectCardBrand=n.n,exports.firstDayOfMonth=i.a,exports.formatAbsoluteTime=a.t,exports.formatCardNumber=n.r,exports.formatCurrency=r.r,exports.formatDate=i.o,exports.formatIBAN=r.a,exports.formatNIP=r.o,exports.formatPhone=r.s,exports.formatPostCode=t._,exports.formatRelativeTime=a.n,exports.formatTime=i.c,exports.getAutoUpdateInterval=a.r,exports.getDayNames=i.u,exports.getMineralComponentLicense=s.t,exports.getMineralComponentPlan=s.n,exports.getMonthNames=i.d,exports.getPostCodeRule=t.v,exports.getRelativeTimeValue=a.i,exports.isDateInRange=i.f,exports.isMineralProComponent=s.r,exports.isSameDay=i.p,exports.mineralComponentLicenses=s.i,exports.mineralProComponents=s.a,exports.parseCurrencyToNumber=r.c,exports.parseDate=i.m,exports.parseRelativeThreshold=a.a,exports.parseTime=i.h,exports.postCodeCountries=t.y,exports.postCodeRules=t.b,exports.stripCardNumber=n.i,exports.stripNonAlphanumeric=r.l,exports.stripNonDigits=r.u,exports.stripTime=i._,exports.toDate=a.o,exports.unformatIBAN=r.d,exports.useClickOutside=s.o,exports.useDebounce=o.n,exports.useDebouncedCallback=o.r,exports.useGhostText=o.t,exports.useInteractionEffect=l.t,exports.useKeyboardNav=c.t,exports.validateCardNumber=n.a,exports.validateEmail=t.o,exports.validateIBAN=t.s,exports.validateMaxLength=t.c,exports.validateMinLength=t.l,exports.validateNIP=t.u,exports.validatePESEL=t.d,exports.validatePattern=t.f,exports.validatePhone=t.p,exports.validatePostCode=t.x,exports.validateREGON=t.m,exports.validateRange=t.h,exports.validateRequired=t.g;
3
+ Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});const e=require(`./cn-CU5TNITO.cjs`),t=require(`./validators-B6yWdsu2.cjs`),n=require(`./creditCards-D_HwRUBz.cjs`),r=require(`./formatters-CNjg_h7-.cjs`),i=require(`./dateUtils-Dq1vaA-D.cjs`),a=require(`./relativeTime-DgYBUaVm.cjs`),o=require(`./useGhostText-BFaUUKid.cjs`),s=require(`./licensing-sRHTvX0B.cjs`),c=require(`./useKeyboardNav-CtGPfQX7.cjs`),l=require(`./useInteractionEffect-BH2dgQla.cjs`);exports.addMonths=i.t,exports.addYears=i.n,exports.adjustCursorAfterFormat=r.t,exports.capitalizeWords=r.n,exports.cn=e.t,exports.composeValidators=t.t,exports.creditCardBrands=n.t,exports.daysInMonth=i.i,exports.detectCardBrand=n.n,exports.firstDayOfMonth=i.a,exports.formatAbsoluteTime=a.t,exports.formatCardNumber=n.r,exports.formatCurrency=r.r,exports.formatDate=i.o,exports.formatIBAN=r.a,exports.formatNIP=r.o,exports.formatPhone=r.s,exports.formatPostCode=t.v,exports.formatRelativeTime=a.n,exports.formatTime=i.c,exports.getAutoUpdateInterval=a.r,exports.getDayNames=i.u,exports.getMineralComponentLicense=s.t,exports.getMineralComponentPlan=s.n,exports.getMonthNames=i.d,exports.getPostCodeRule=t.y,exports.getRelativeTimeValue=a.i,exports.isDateInRange=i.f,exports.isMineralProComponent=s.r,exports.isSameDay=i.p,exports.mineralComponentLicenses=s.i,exports.mineralProComponents=s.a,exports.parseCurrencyToNumber=r.c,exports.parseDate=i.m,exports.parseRelativeThreshold=a.a,exports.parseTime=i.h,exports.postCodeCountries=t.b,exports.postCodeRules=t.x,exports.stripCardNumber=n.i,exports.stripNonAlphanumeric=r.l,exports.stripNonDigits=r.u,exports.stripTime=i._,exports.toDate=a.o,exports.unformatIBAN=r.d,exports.useClickOutside=s.o,exports.useDebounce=o.n,exports.useDebouncedCallback=o.r,exports.useGhostText=o.t,exports.useInteractionEffect=l.t,exports.useKeyboardNav=c.t,exports.validateCardNumber=n.a,exports.validateEmail=t.o,exports.validateIBAN=t.s,exports.validateMaxLength=t.c,exports.validateMinLength=t.l,exports.validateNIP=t.u,exports.validatePESEL=t.d,exports.validatePattern=t.f,exports.validatePhone=t.p,exports.validatePostCode=t.S,exports.validateREGON=t.m,exports.validateRange=t.h,exports.validateRequired=t.g;
package/dist/utils.js CHANGED
@@ -1,7 +1,7 @@
1
1
  import {ensureStyles} from './style-runtime.js'
2
2
  ensureStyles()
3
3
  import { t as e } from "./cn-YER3QsV1.js";
4
- import { _ as t, b as n, c as r, d as i, f as a, g as o, h as s, l as c, m as l, o as u, p as d, s as f, t as p, u as m, v as h, x as g, y as _ } from "./validators-D5OCyV2h.js";
4
+ import { S as t, b as n, c as r, d as i, f as a, g as o, h as s, l as c, m as l, o as u, p as d, s as f, t as p, u as m, v as h, x as g, y as _ } from "./validators-DVYOtFnw.js";
5
5
  import { a as v, i as y, n as b, r as x, t as S } from "./creditCards-D_iWmtG6.js";
6
6
  import { a as C, c as w, d as T, l as E, n as D, o as O, r as k, s as A, t as j, u as M } from "./formatters-T0vvjMtB.js";
7
7
  import { _ as N, a as P, c as F, d as I, f as L, h as R, i as z, m as B, n as V, o as H, p as U, t as W, u as G } from "./dateUtils-CUY6CRCf.js";
@@ -10,4 +10,4 @@ import { n as Q, r as $, t as ee } from "./useGhostText-DG0bzcao.js";
10
10
  import { a as te, i as ne, n as re, o as ie, r as ae, t as oe } from "./licensing-f5KYVz7D.js";
11
11
  import { t as se } from "./useKeyboardNav-iEXOdEMB.js";
12
12
  import { t as ce } from "./useInteractionEffect-DtpbVd77.js";
13
- export { W as addMonths, V as addYears, j as adjustCursorAfterFormat, D as capitalizeWords, e as cn, p as composeValidators, S as creditCardBrands, z as daysInMonth, b as detectCardBrand, P as firstDayOfMonth, Z as formatAbsoluteTime, x as formatCardNumber, k as formatCurrency, H as formatDate, C as formatIBAN, O as formatNIP, A as formatPhone, t as formatPostCode, J as formatRelativeTime, F as formatTime, X as getAutoUpdateInterval, G as getDayNames, oe as getMineralComponentLicense, re as getMineralComponentPlan, I as getMonthNames, h as getPostCodeRule, q as getRelativeTimeValue, L as isDateInRange, ae as isMineralProComponent, U as isSameDay, ne as mineralComponentLicenses, te as mineralProComponents, w as parseCurrencyToNumber, B as parseDate, K as parseRelativeThreshold, R as parseTime, _ as postCodeCountries, n as postCodeRules, y as stripCardNumber, E as stripNonAlphanumeric, M as stripNonDigits, N as stripTime, Y as toDate, T as unformatIBAN, ie as useClickOutside, Q as useDebounce, $ as useDebouncedCallback, ee as useGhostText, ce as useInteractionEffect, se as useKeyboardNav, v as validateCardNumber, u as validateEmail, f as validateIBAN, r as validateMaxLength, c as validateMinLength, m as validateNIP, i as validatePESEL, a as validatePattern, d as validatePhone, g as validatePostCode, l as validateREGON, s as validateRange, o as validateRequired };
13
+ export { W as addMonths, V as addYears, j as adjustCursorAfterFormat, D as capitalizeWords, e as cn, p as composeValidators, S as creditCardBrands, z as daysInMonth, b as detectCardBrand, P as firstDayOfMonth, Z as formatAbsoluteTime, x as formatCardNumber, k as formatCurrency, H as formatDate, C as formatIBAN, O as formatNIP, A as formatPhone, h as formatPostCode, J as formatRelativeTime, F as formatTime, X as getAutoUpdateInterval, G as getDayNames, oe as getMineralComponentLicense, re as getMineralComponentPlan, I as getMonthNames, _ as getPostCodeRule, q as getRelativeTimeValue, L as isDateInRange, ae as isMineralProComponent, U as isSameDay, ne as mineralComponentLicenses, te as mineralProComponents, w as parseCurrencyToNumber, B as parseDate, K as parseRelativeThreshold, R as parseTime, n as postCodeCountries, g as postCodeRules, y as stripCardNumber, E as stripNonAlphanumeric, M as stripNonDigits, N as stripTime, Y as toDate, T as unformatIBAN, ie as useClickOutside, Q as useDebounce, $ as useDebouncedCallback, ee as useGhostText, ce as useInteractionEffect, se as useKeyboardNav, v as validateCardNumber, u as validateEmail, f as validateIBAN, r as validateMaxLength, c as validateMinLength, m as validateNIP, i as validatePESEL, a as validatePattern, d as validatePhone, t as validatePostCode, l as validateREGON, s as validateRange, o as validateRequired };
@@ -1,2 +1,2 @@
1
- var e={valid:!0};function t(e){return e.toUpperCase().replace(/[^A-Z0-9]/g,``)}function n(e){let t=e.replace(/\D/g,``).slice(0,5);return t.length<=2?t:`${t.slice(0,2)}-${t.slice(2)}`}function r(e){let t=e.replace(/\D/g,``).slice(0,9);return t.length<=5?t:`${t.slice(0,5)}-${t.slice(5)}`}function i(e,t){return e.replace(/\D/g,``).slice(0,t)}function a(e){return t(e).slice(0,6).split(``).map((e,t)=>t===3?` ${e}`:e).join(``)}function o(e){let n=t(e).slice(0,7);return n.length<=3?n:`${n.slice(0,n.length-3)} ${n.slice(-3)}`}function s(e){let n=t(e).slice(0,6);return n.length<=4?n:`${n.slice(0,4)} ${n.slice(4)}`}var c={PL:{countryCode:`PL`,label:`Poland`,placeholder:`12-345`,example:`00-001`,inputMode:`numeric`,maxLength:6,regex:/^\d{2}-\d{3}$/,sanitize:e=>e.replace(/\D/g,``).slice(0,5),format:n,message:`Use the Polish format XX-XXX`},DE:{countryCode:`DE`,label:`Germany`,placeholder:`12345`,example:`10115`,inputMode:`numeric`,maxLength:5,regex:/^\d{5}$/,sanitize:e=>e.replace(/\D/g,``).slice(0,5),format:e=>i(e,5),message:`Use a 5-digit German postal code`},FR:{countryCode:`FR`,label:`France`,placeholder:`75001`,example:`75001`,inputMode:`numeric`,maxLength:5,regex:/^\d{5}$/,sanitize:e=>e.replace(/\D/g,``).slice(0,5),format:e=>i(e,5),message:`Use a 5-digit French postal code`},ES:{countryCode:`ES`,label:`Spain`,placeholder:`28013`,example:`28013`,inputMode:`numeric`,maxLength:5,regex:/^\d{5}$/,sanitize:e=>e.replace(/\D/g,``).slice(0,5),format:e=>i(e,5),message:`Use a 5-digit Spanish postal code`},IT:{countryCode:`IT`,label:`Italy`,placeholder:`00184`,example:`00184`,inputMode:`numeric`,maxLength:5,regex:/^\d{5}$/,sanitize:e=>e.replace(/\D/g,``).slice(0,5),format:e=>i(e,5),message:`Use a 5-digit Italian postal code`},US:{countryCode:`US`,label:`United States`,placeholder:`12345 or 12345-6789`,example:`10001`,inputMode:`numeric`,maxLength:10,regex:/^\d{5}(?:-\d{4})?$/,sanitize:e=>e.replace(/\D/g,``).slice(0,9),format:r,message:`Use ZIP or ZIP+4 format`},CA:{countryCode:`CA`,label:`Canada`,placeholder:`A1A 1A1`,example:`M5V 3L9`,inputMode:`text`,maxLength:7,regex:/^[A-Z]\d[A-Z] \d[A-Z]\d$/,sanitize:e=>t(e).slice(0,6),format:a,message:`Use the Canadian format A1A 1A1`},GB:{countryCode:`GB`,label:`United Kingdom`,placeholder:`SW1A 1AA`,example:`SW1A 1AA`,inputMode:`text`,maxLength:8,regex:/^[A-Z]{1,2}\d[A-Z\d]? \d[A-Z]{2}$/,sanitize:e=>t(e).slice(0,7),format:o,message:`Use a valid UK postcode`},NL:{countryCode:`NL`,label:`Netherlands`,placeholder:`1234 AB`,example:`1012 AB`,inputMode:`text`,maxLength:7,regex:/^\d{4} [A-Z]{2}$/,sanitize:e=>t(e).slice(0,6),format:s,message:`Use the Dutch format 1234 AB`}},l=Object.values(c).map(({countryCode:e,label:t})=>({value:e,label:t}));function u(e=`PL`){return c[e.toUpperCase()]??c.PL}function d(e,t=`PL`){let n=u(t);return n.format(n.sanitize(e))}function f(t,n=`PL`){if(!t)return e;let r=u(n),i=r.format(r.sanitize(t));return r.regex.test(i)?e:{valid:!1,error:r.message}}var p={valid:!0},m=e=>({valid:!1,error:e});function h(e){return e.trim().length>0?p:m(`This field is required`)}function g(e){return t=>t.length>=e?p:m(`Minimum ${e} characters`)}function _(e){return t=>t.length<=e?p:m(`Maximum ${e} characters`)}function v(e,t){return n=>e.test(n)?p:m(t??`Invalid format`)}function y(e,t){return n=>{let r=parseFloat(n);return isNaN(r)?m(`Must be a number`):e!==void 0&&r<e?m(`Minimum value is ${e}`):t!==void 0&&r>t?m(`Maximum value is ${t}`):p}}var b=/^[a-zA-Z0-9.!#$%&'*+/=?^_`{|}~-]+@[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(?:\.[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)*$/;function x(e){return e?b.test(e)?p:m(`Invalid email address`):p}var S={PL:9,DE:10,US:10,GB:10,FR:9,CZ:9,SK:9};function C(e,t){if(!e)return p;let n=e.replace(/\D/g,``);if(n.length<7)return m(`Phone number too short`);if(n.length>15)return m(`Phone number too long`);if(t){let e=S[t.toUpperCase()];if(e&&n.length!==e)return m(`Phone number should have ${e} digits`)}return p}var w={AL:28,AD:24,AT:20,AZ:28,BH:22,BY:28,BE:16,BA:20,BR:29,BG:22,CR:22,HR:21,CY:28,CZ:24,DK:18,DO:28,EG:29,SV:28,EE:20,FO:18,FI:18,FR:27,GE:22,DE:22,GI:23,GR:27,GL:18,GT:28,HU:28,IS:26,IQ:23,IE:22,IL:23,IT:27,JO:30,KZ:20,XK:20,KW:30,LV:21,LB:28,LI:21,LT:20,LU:20,MT:31,MR:27,MU:30,MD:24,MC:27,ME:22,NL:18,MK:19,NO:15,PK:24,PS:29,PL:28,PT:25,QA:29,RO:24,LC:32,SM:27,SA:24,RS:22,SC:31,SK:24,SI:19,ES:24,SE:24,CH:21,TL:23,TN:24,TR:26,UA:29,AE:23,GB:22,VA:22,VG:24},T=Object.keys(w).sort();function E(e){return w[e.toUpperCase()]??null}function D(e){let t=0;for(let n=0;n<e.length;n++)t=(t*10+parseInt(e[n],10))%97;return t}function O(e){if(!e)return p;let t=e.replace(/\s/g,``).toUpperCase();if(t.length<2)return m(`IBAN too short`);let n=t.slice(0,2),r=w[n];return r?t.length===r?D((t.slice(4)+t.slice(0,4)).replace(/[A-Z]/g,e=>String(e.charCodeAt(0)-55)))===1?p:m(`Invalid IBAN checksum`):m(`IBAN for ${n} should have ${r} characters`):m(`Unknown IBAN country code`)}var k=[6,5,7,2,3,4,5,6,7];function A(e){if(!e)return p;let t=e.replace(/\D/g,``);if(t.length!==10)return m(`NIP must have 10 digits`);let n=0;for(let e=0;e<9;e++)n+=parseInt(t[e],10)*k[e];let r=n%11;return r===10?m(`Invalid NIP`):r===parseInt(t[9],10)?p:m(`Invalid NIP checksum`)}var j=[1,3,7,9,1,3,7,9,1,3];function M(e){if(!e)return p;let t=e.replace(/\D/g,``);if(t.length!==11)return m(`PESEL must have 11 digits`);let n=0;for(let e=0;e<10;e++)n+=parseInt(t[e],10)*j[e];return(10-n%10)%10===parseInt(t[10],10)?p:m(`Invalid PESEL checksum`)}var N=[8,9,2,3,4,5,6,7],P=[2,4,8,5,0,9,7,3,6,1,2,4,8];function F(e){if(!e)return p;let t=e.replace(/\D/g,``);if(t.length!==9&&t.length!==14)return m(`REGON must have 9 or 14 digits`);let n=t.length===9?N:P,r=0;for(let e=0;e<n.length;e++)r+=parseInt(t[e],10)*n[e];return(r%11==10?0:r%11)===parseInt(t[t.length-1],10)?p:m(`Invalid REGON checksum`)}function I(...e){return t=>{for(let n of e){let e=n(t);if(!e.valid)return e}return p}}function L(e,t=`DD/MM/YYYY`){let n=e.replace(/\D/g,``);if(n.length!==8)return null;let r,i,a;if(t===`DD/MM/YYYY`?(r=parseInt(n.slice(0,2),10),i=parseInt(n.slice(2,4),10),a=parseInt(n.slice(4,8),10)):t===`MM/DD/YYYY`?(i=parseInt(n.slice(0,2),10),r=parseInt(n.slice(2,4),10),a=parseInt(n.slice(4,8),10)):(a=parseInt(n.slice(0,4),10),i=parseInt(n.slice(4,6),10),r=parseInt(n.slice(6,8),10)),i<1||i>12||r<1||r>31||a<1)return null;let o=new Date(a,i-1,r);return o.getFullYear()!==a||o.getMonth()!==i-1||o.getDate()!==r?null:o}function R(e,t={}){if(!e)return p;let{format:n=`DD/MM/YYYY`,minDate:r,maxDate:i}=t;if(e.replace(/\D/g,``).length!==8)return m(`Incomplete date`);let a=L(e,n);return a?r&&a<new Date(r.getFullYear(),r.getMonth(),r.getDate())?m(`Date is too early`):i&&a>new Date(i.getFullYear(),i.getMonth(),i.getDate())?m(`Date is too far in the future`):p:m(`Invalid date`)}Object.defineProperty(exports,`_`,{enumerable:!0,get:function(){return d}}),Object.defineProperty(exports,`a`,{enumerable:!0,get:function(){return R}}),Object.defineProperty(exports,`b`,{enumerable:!0,get:function(){return c}}),Object.defineProperty(exports,`c`,{enumerable:!0,get:function(){return _}}),Object.defineProperty(exports,`d`,{enumerable:!0,get:function(){return M}}),Object.defineProperty(exports,`f`,{enumerable:!0,get:function(){return v}}),Object.defineProperty(exports,`g`,{enumerable:!0,get:function(){return h}}),Object.defineProperty(exports,`h`,{enumerable:!0,get:function(){return y}}),Object.defineProperty(exports,`i`,{enumerable:!0,get:function(){return L}}),Object.defineProperty(exports,`l`,{enumerable:!0,get:function(){return g}}),Object.defineProperty(exports,`m`,{enumerable:!0,get:function(){return F}}),Object.defineProperty(exports,`n`,{enumerable:!0,get:function(){return E}}),Object.defineProperty(exports,`o`,{enumerable:!0,get:function(){return x}}),Object.defineProperty(exports,`p`,{enumerable:!0,get:function(){return C}}),Object.defineProperty(exports,`r`,{enumerable:!0,get:function(){return T}}),Object.defineProperty(exports,`s`,{enumerable:!0,get:function(){return O}}),Object.defineProperty(exports,`t`,{enumerable:!0,get:function(){return I}}),Object.defineProperty(exports,`u`,{enumerable:!0,get:function(){return A}}),Object.defineProperty(exports,`v`,{enumerable:!0,get:function(){return u}}),Object.defineProperty(exports,`x`,{enumerable:!0,get:function(){return f}}),Object.defineProperty(exports,`y`,{enumerable:!0,get:function(){return l}});
2
- //# sourceMappingURL=validators-DRhikiAi.cjs.map
1
+ var e={valid:!0};function t(e){return e.toUpperCase().replace(/[^A-Z0-9]/g,``)}function n(e){let t=e.replace(/\D/g,``).slice(0,5);return t.length<=2?t:`${t.slice(0,2)}-${t.slice(2)}`}function r(e){let t=e.replace(/\D/g,``).slice(0,9);return t.length<=5?t:`${t.slice(0,5)}-${t.slice(5)}`}function i(e,t){return e.replace(/\D/g,``).slice(0,t)}function a(e){return t(e).slice(0,6).split(``).map((e,t)=>t===3?` ${e}`:e).join(``)}function o(e){let n=t(e).slice(0,7);return n.length<=3?n:`${n.slice(0,n.length-3)} ${n.slice(-3)}`}function s(e){let n=t(e).slice(0,6);return n.length<=4?n:`${n.slice(0,4)} ${n.slice(4)}`}var c={PL:{countryCode:`PL`,label:`Poland`,placeholder:`12-345`,example:`00-001`,inputMode:`numeric`,maxLength:6,regex:/^\d{2}-\d{3}$/,sanitize:e=>e.replace(/\D/g,``).slice(0,5),format:n,message:`Use the Polish format XX-XXX`},DE:{countryCode:`DE`,label:`Germany`,placeholder:`12345`,example:`10115`,inputMode:`numeric`,maxLength:5,regex:/^\d{5}$/,sanitize:e=>e.replace(/\D/g,``).slice(0,5),format:e=>i(e,5),message:`Use a 5-digit German postal code`},FR:{countryCode:`FR`,label:`France`,placeholder:`75001`,example:`75001`,inputMode:`numeric`,maxLength:5,regex:/^\d{5}$/,sanitize:e=>e.replace(/\D/g,``).slice(0,5),format:e=>i(e,5),message:`Use a 5-digit French postal code`},ES:{countryCode:`ES`,label:`Spain`,placeholder:`28013`,example:`28013`,inputMode:`numeric`,maxLength:5,regex:/^\d{5}$/,sanitize:e=>e.replace(/\D/g,``).slice(0,5),format:e=>i(e,5),message:`Use a 5-digit Spanish postal code`},IT:{countryCode:`IT`,label:`Italy`,placeholder:`00184`,example:`00184`,inputMode:`numeric`,maxLength:5,regex:/^\d{5}$/,sanitize:e=>e.replace(/\D/g,``).slice(0,5),format:e=>i(e,5),message:`Use a 5-digit Italian postal code`},US:{countryCode:`US`,label:`United States`,placeholder:`12345 or 12345-6789`,example:`10001`,inputMode:`numeric`,maxLength:10,regex:/^\d{5}(?:-\d{4})?$/,sanitize:e=>e.replace(/\D/g,``).slice(0,9),format:r,message:`Use ZIP or ZIP+4 format`},CA:{countryCode:`CA`,label:`Canada`,placeholder:`A1A 1A1`,example:`M5V 3L9`,inputMode:`text`,maxLength:7,regex:/^[A-Z]\d[A-Z] \d[A-Z]\d$/,sanitize:e=>t(e).slice(0,6),format:a,message:`Use the Canadian format A1A 1A1`},GB:{countryCode:`GB`,label:`United Kingdom`,placeholder:`SW1A 1AA`,example:`SW1A 1AA`,inputMode:`text`,maxLength:8,regex:/^[A-Z]{1,2}\d[A-Z\d]? \d[A-Z]{2}$/,sanitize:e=>t(e).slice(0,7),format:o,message:`Use a valid UK postcode`},NL:{countryCode:`NL`,label:`Netherlands`,placeholder:`1234 AB`,example:`1012 AB`,inputMode:`text`,maxLength:7,regex:/^\d{4} [A-Z]{2}$/,sanitize:e=>t(e).slice(0,6),format:s,message:`Use the Dutch format 1234 AB`}},l=Object.values(c).map(({countryCode:e,label:t})=>({value:e,label:t}));function u(e=`PL`){return c[e.toUpperCase()]??c.PL}function d(e,t=`PL`){let n=u(t);return n.format(n.sanitize(e))}function f(t,n=`PL`){if(!t)return e;let r=u(n),i=r.format(r.sanitize(t));return r.regex.test(i)?e:{valid:!1,error:r.message}}var p={valid:!0},m=e=>({valid:!1,error:e});function h(e){return e.trim().length>0?p:m(`This field is required`)}function g(e){return t=>t.length>=e?p:m(`Minimum ${e} characters`)}function _(e){return t=>t.length<=e?p:m(`Maximum ${e} characters`)}function v(e,t){return n=>e.test(n)?p:m(t??`Invalid format`)}function y(e,t){return n=>{let r=parseFloat(n);return isNaN(r)?m(`Must be a number`):e!==void 0&&r<e?m(`Minimum value is ${e}`):t!==void 0&&r>t?m(`Maximum value is ${t}`):p}}var b=/^[a-zA-Z0-9.!#$%&'*+/=?^_`{|}~-]+@[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(?:\.[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)*$/;function x(e){return e?b.test(e)?p:m(`Invalid email address`):p}var S={PL:9,DE:10,US:10,GB:10,FR:9,CZ:9,SK:9};function C(e,t){if(!e)return p;let n=e.replace(/\D/g,``);if(n.length<7)return m(`Phone number too short`);if(n.length>15)return m(`Phone number too long`);if(t){let e=S[t.toUpperCase()];if(e&&n.length!==e)return m(`Phone number should have ${e} digits`)}return p}var w={AL:28,AD:24,AT:20,AZ:28,BH:22,BY:28,BE:16,BA:20,BR:29,BG:22,CR:22,HR:21,CY:28,CZ:24,DK:18,DO:28,EG:29,SV:28,EE:20,FO:18,FI:18,FR:27,GE:22,DE:22,GI:23,GR:27,GL:18,GT:28,HU:28,IS:26,IQ:23,IE:22,IL:23,IT:27,JO:30,KZ:20,XK:20,KW:30,LV:21,LB:28,LI:21,LT:20,LU:20,MT:31,MR:27,MU:30,MD:24,MC:27,ME:22,NL:18,MK:19,NO:15,PK:24,PS:29,PL:28,PT:25,QA:29,RO:24,LC:32,SM:27,SA:24,RS:22,SC:31,SK:24,SI:19,ES:24,SE:24,CH:21,TL:23,TN:24,TR:26,UA:29,AE:23,GB:22,VA:22,VG:24},T=Object.keys(w).sort();function E(e){return w[e.toUpperCase()]??null}function D(e){let t=0;for(let n=0;n<e.length;n++)t=(t*10+parseInt(e[n],10))%97;return t}function O(e){if(!e)return p;let t=e.replace(/\s/g,``).toUpperCase();if(t.length<2)return m(`IBAN too short`);let n=t.slice(0,2),r=w[n];return r?t.length===r?D((t.slice(4)+t.slice(0,4)).replace(/[A-Z]/g,e=>String(e.charCodeAt(0)-55)))===1?p:m(`Invalid IBAN checksum`):m(`IBAN for ${n} should have ${r} characters`):m(`Unknown IBAN country code`)}var k=[6,5,7,2,3,4,5,6,7];function A(e){if(!e)return p;let t=e.replace(/\D/g,``);if(t.length!==10)return m(`NIP must have 10 digits`);let n=0;for(let e=0;e<9;e++)n+=parseInt(t[e],10)*k[e];let r=n%11;return r===10?m(`Invalid NIP`):r===parseInt(t[9],10)?p:m(`Invalid NIP checksum`)}var j=[1,3,7,9,1,3,7,9,1,3];function M(e){if(!e)return p;let t=e.replace(/\D/g,``);if(t.length!==11)return m(`PESEL must have 11 digits`);let n=0;for(let e=0;e<10;e++)n+=parseInt(t[e],10)*j[e];return(10-n%10)%10===parseInt(t[10],10)?p:m(`Invalid PESEL checksum`)}var N=[8,9,2,3,4,5,6,7],P=[2,4,8,5,0,9,7,3,6,1,2,4,8];function F(e){if(!e)return p;let t=e.replace(/\D/g,``);if(t.length!==9&&t.length!==14)return m(`REGON must have 9 or 14 digits`);let n=t.length===9?N:P,r=0;for(let e=0;e<n.length;e++)r+=parseInt(t[e],10)*n[e];return(r%11==10?0:r%11)===parseInt(t[t.length-1],10)?p:m(`Invalid REGON checksum`)}function I(...e){return t=>{for(let n of e){let e=n(t);if(!e.valid)return e}return p}}function L(e,t=`DD/MM/YYYY`){let n=e.replace(/\D/g,``);if(n.length!==8)return null;let r,i,a;if(t===`DD/MM/YYYY`?(r=parseInt(n.slice(0,2),10),i=parseInt(n.slice(2,4),10),a=parseInt(n.slice(4,8),10)):t===`MM/DD/YYYY`?(i=parseInt(n.slice(0,2),10),r=parseInt(n.slice(2,4),10),a=parseInt(n.slice(4,8),10)):(a=parseInt(n.slice(0,4),10),i=parseInt(n.slice(4,6),10),r=parseInt(n.slice(6,8),10)),i<1||i>12||r<1||r>31||a<1)return null;let o=new Date(a,i-1,r);return o.getFullYear()!==a||o.getMonth()!==i-1||o.getDate()!==r?null:o}function R(e,t={}){if(!e)return p;let{format:n=`DD/MM/YYYY`,minDate:r,maxDate:i}=t;if(e.replace(/\D/g,``).length!==8)return m(`Incomplete date`);let a=L(e,n);return a?r&&a<new Date(r.getFullYear(),r.getMonth(),r.getDate())?m(`Date is too early`):i&&a>new Date(i.getFullYear(),i.getMonth(),i.getDate())?m(`Date is too far in the future`):p:m(`Invalid date`)}function z(e,t={}){if(!e)return p;let{protocols:n=[`http`,`https`],requireProtocol:r=!0}=t,i=/^[a-zA-Z][a-zA-Z0-9+.-]*:/.test(e);if(!i&&r)return m(`URL must start with ${n.map(e=>`${e}://`).join(` or `)}`);let a=i?e:`https://${e}`,o;try{o=new URL(a)}catch{return m(`Invalid URL`)}if(!o.hostname)return m(`Invalid URL`);if(i&&n.length>0){let e=o.protocol.replace(/:$/,``);if(!n.includes(e))return m(`Protocol "${e}" is not allowed`)}return p}Object.defineProperty(exports,`S`,{enumerable:!0,get:function(){return f}}),Object.defineProperty(exports,`_`,{enumerable:!0,get:function(){return z}}),Object.defineProperty(exports,`a`,{enumerable:!0,get:function(){return R}}),Object.defineProperty(exports,`b`,{enumerable:!0,get:function(){return l}}),Object.defineProperty(exports,`c`,{enumerable:!0,get:function(){return _}}),Object.defineProperty(exports,`d`,{enumerable:!0,get:function(){return M}}),Object.defineProperty(exports,`f`,{enumerable:!0,get:function(){return v}}),Object.defineProperty(exports,`g`,{enumerable:!0,get:function(){return h}}),Object.defineProperty(exports,`h`,{enumerable:!0,get:function(){return y}}),Object.defineProperty(exports,`i`,{enumerable:!0,get:function(){return L}}),Object.defineProperty(exports,`l`,{enumerable:!0,get:function(){return g}}),Object.defineProperty(exports,`m`,{enumerable:!0,get:function(){return F}}),Object.defineProperty(exports,`n`,{enumerable:!0,get:function(){return E}}),Object.defineProperty(exports,`o`,{enumerable:!0,get:function(){return x}}),Object.defineProperty(exports,`p`,{enumerable:!0,get:function(){return C}}),Object.defineProperty(exports,`r`,{enumerable:!0,get:function(){return T}}),Object.defineProperty(exports,`s`,{enumerable:!0,get:function(){return O}}),Object.defineProperty(exports,`t`,{enumerable:!0,get:function(){return I}}),Object.defineProperty(exports,`u`,{enumerable:!0,get:function(){return A}}),Object.defineProperty(exports,`v`,{enumerable:!0,get:function(){return d}}),Object.defineProperty(exports,`x`,{enumerable:!0,get:function(){return c}}),Object.defineProperty(exports,`y`,{enumerable:!0,get:function(){return u}});
2
+ //# sourceMappingURL=validators-B6yWdsu2.cjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"validators-DRhikiAi.cjs","names":[],"sources":["../src/utils/postalCodes.ts","../src/utils/validators.ts"],"sourcesContent":["import type {ValidationResult} from './validators'\n\nexport interface PostCodeRule {\n countryCode: string\n label: string\n placeholder: string\n example: string\n inputMode: 'text' | 'numeric'\n maxLength: number\n regex: RegExp\n sanitize: (value: string) => string\n format: (value: string) => string\n message: string\n}\n\nconst OK_RESULT: ValidationResult = {valid: true}\n\n// Reuse one sanitizer for countries that mix letters and digits.\nfunction keepLettersAndDigits(value: string): string {\n return value.toUpperCase().replace(/[^A-Z0-9]/g, '')\n}\n\n// Apply the common Polish XX-XXX postcode shape.\nfunction formatPlPostCode(value: string): string {\n const digits = value.replace(/\\D/g, '').slice(0, 5)\n\n if (digits.length <= 2) {\n return digits\n }\n\n return `${digits.slice(0, 2)}-${digits.slice(2)}`\n}\n\n// Support ZIP and ZIP+4 with the same formatter.\nfunction formatUsPostCode(value: string): string {\n const digits = value.replace(/\\D/g, '').slice(0, 9)\n\n if (digits.length <= 5) {\n return digits\n }\n\n return `${digits.slice(0, 5)}-${digits.slice(5)}`\n}\n\n// Clamp countries that only need a fixed number of digits.\nfunction formatFixedDigits(value: string, maxLength: number): string {\n return value.replace(/\\D/g, '').slice(0, maxLength)\n}\n\n// Insert the standard center space used by Canadian post codes.\nfunction formatCaPostCode(value: string): string {\n const clean = keepLettersAndDigits(value).slice(0, 6)\n const chars = clean.split('')\n\n return chars\n .map((char, index) => {\n if (index === 3) {\n return ` ${char}`\n }\n\n return char\n })\n .join('')\n}\n\n// Split the outward and inward parts of a UK postcode.\nfunction formatGbPostCode(value: string): string {\n const clean = keepLettersAndDigits(value).slice(0, 7)\n\n if (clean.length <= 3) {\n return clean\n }\n\n return `${clean.slice(0, clean.length - 3)} ${clean.slice(-3)}`\n}\n\n// Split Dutch codes into four digits and two letters.\nfunction formatNlPostCode(value: string): string {\n const clean = keepLettersAndDigits(value).slice(0, 6)\n\n if (clean.length <= 4) {\n return clean\n }\n\n return `${clean.slice(0, 4)} ${clean.slice(4)}`\n}\n\nexport const postCodeRules: Record<string, PostCodeRule> = {\n PL: {\n countryCode: 'PL',\n label: 'Poland',\n placeholder: '12-345',\n example: '00-001',\n inputMode: 'numeric',\n maxLength: 6,\n regex: /^\\d{2}-\\d{3}$/,\n sanitize: (value) => value.replace(/\\D/g, '').slice(0, 5),\n format: formatPlPostCode,\n message: 'Use the Polish format XX-XXX',\n },\n DE: {\n countryCode: 'DE',\n label: 'Germany',\n placeholder: '12345',\n example: '10115',\n inputMode: 'numeric',\n maxLength: 5,\n regex: /^\\d{5}$/,\n sanitize: (value) => value.replace(/\\D/g, '').slice(0, 5),\n format: (value) => formatFixedDigits(value, 5),\n message: 'Use a 5-digit German postal code',\n },\n FR: {\n countryCode: 'FR',\n label: 'France',\n placeholder: '75001',\n example: '75001',\n inputMode: 'numeric',\n maxLength: 5,\n regex: /^\\d{5}$/,\n sanitize: (value) => value.replace(/\\D/g, '').slice(0, 5),\n format: (value) => formatFixedDigits(value, 5),\n message: 'Use a 5-digit French postal code',\n },\n ES: {\n countryCode: 'ES',\n label: 'Spain',\n placeholder: '28013',\n example: '28013',\n inputMode: 'numeric',\n maxLength: 5,\n regex: /^\\d{5}$/,\n sanitize: (value) => value.replace(/\\D/g, '').slice(0, 5),\n format: (value) => formatFixedDigits(value, 5),\n message: 'Use a 5-digit Spanish postal code',\n },\n IT: {\n countryCode: 'IT',\n label: 'Italy',\n placeholder: '00184',\n example: '00184',\n inputMode: 'numeric',\n maxLength: 5,\n regex: /^\\d{5}$/,\n sanitize: (value) => value.replace(/\\D/g, '').slice(0, 5),\n format: (value) => formatFixedDigits(value, 5),\n message: 'Use a 5-digit Italian postal code',\n },\n US: {\n countryCode: 'US',\n label: 'United States',\n placeholder: '12345 or 12345-6789',\n example: '10001',\n inputMode: 'numeric',\n maxLength: 10,\n regex: /^\\d{5}(?:-\\d{4})?$/,\n sanitize: (value) => value.replace(/\\D/g, '').slice(0, 9),\n format: formatUsPostCode,\n message: 'Use ZIP or ZIP+4 format',\n },\n CA: {\n countryCode: 'CA',\n label: 'Canada',\n placeholder: 'A1A 1A1',\n example: 'M5V 3L9',\n inputMode: 'text',\n maxLength: 7,\n regex: /^[A-Z]\\d[A-Z] \\d[A-Z]\\d$/,\n sanitize: (value) => keepLettersAndDigits(value).slice(0, 6),\n format: formatCaPostCode,\n message: 'Use the Canadian format A1A 1A1',\n },\n GB: {\n countryCode: 'GB',\n label: 'United Kingdom',\n placeholder: 'SW1A 1AA',\n example: 'SW1A 1AA',\n inputMode: 'text',\n maxLength: 8,\n regex: /^[A-Z]{1,2}\\d[A-Z\\d]? \\d[A-Z]{2}$/,\n sanitize: (value) => keepLettersAndDigits(value).slice(0, 7),\n format: formatGbPostCode,\n message: 'Use a valid UK postcode',\n },\n NL: {\n countryCode: 'NL',\n label: 'Netherlands',\n placeholder: '1234 AB',\n example: '1012 AB',\n inputMode: 'text',\n maxLength: 7,\n regex: /^\\d{4} [A-Z]{2}$/,\n sanitize: (value) => keepLettersAndDigits(value).slice(0, 6),\n format: formatNlPostCode,\n message: 'Use the Dutch format 1234 AB',\n },\n}\n\nexport const postCodeCountries = Object.values(postCodeRules).map(({countryCode, label}) => ({\n value: countryCode,\n label,\n}))\n\n// Return the active postal rule or fall back to Poland for deterministic behavior.\nexport function getPostCodeRule(countryCode: string = 'PL'): PostCodeRule {\n return postCodeRules[countryCode.toUpperCase()] ?? postCodeRules.PL\n}\n\n// Keep postal input values aligned with the selected country format.\nexport function formatPostCode(value: string, countryCode: string = 'PL'): string {\n const rule = getPostCodeRule(countryCode)\n return rule.format(rule.sanitize(value))\n}\n\n// Validate the user-visible postal code against the selected country rule.\nexport function validatePostCode(value: string, countryCode: string = 'PL'): ValidationResult {\n if (!value) {\n return OK_RESULT\n }\n\n const rule = getPostCodeRule(countryCode)\n const formatted = rule.format(rule.sanitize(value))\n\n if (!rule.regex.test(formatted)) {\n return {valid: false, error: rule.message}\n }\n\n return OK_RESULT\n}\n","export interface ValidationResult {\n valid: boolean\n error?: string\n}\n\nexport type ValidatorFn = (value: string) => ValidationResult\n\nconst ok: ValidationResult = {valid: true}\nconst fail = (error: string): ValidationResult => ({valid: false, error})\n\n// Ensure the field is not empty after trimming user input.\nexport function validateRequired(value: string): ValidationResult {\n return value.trim().length > 0 ? ok : fail('This field is required')\n}\n\n// Build a validator that enforces a minimum string length.\nexport function validateMinLength(min: number): ValidatorFn {\n return (value: string) => (value.length >= min ? ok : fail(`Minimum ${min} characters`))\n}\n\n// Build a validator that enforces a maximum string length.\nexport function validateMaxLength(max: number): ValidatorFn {\n return (value: string) => (value.length <= max ? ok : fail(`Maximum ${max} characters`))\n}\n\n// Build a validator around a custom regular expression.\nexport function validatePattern(pattern: RegExp, message?: string): ValidatorFn {\n return (value: string) => (pattern.test(value) ? ok : fail(message ?? 'Invalid format'))\n}\n\n// Validate numeric input against optional min and max bounds.\nexport function validateRange(min?: number, max?: number): ValidatorFn {\n return (value: string) => {\n const num = parseFloat(value)\n if (isNaN(num)) return fail('Must be a number')\n if (min !== undefined && num < min) return fail(`Minimum value is ${min}`)\n if (max !== undefined && num > max) return fail(`Maximum value is ${max}`)\n return ok\n }\n}\n\n// === Email ===\n\nconst EMAIL_RE =\n /^[a-zA-Z0-9.!#$%&'*+/=?^_`{|}~-]+@[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(?:\\.[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)*$/\n\n// Validate email format while allowing empty optional fields.\nexport function validateEmail(value: string): ValidationResult {\n if (!value) return ok\n return EMAIL_RE.test(value) ? ok : fail('Invalid email address')\n}\n\n// === Phone ===\n\nconst PHONE_LENGTH: Record<string, number> = {\n PL: 9,\n DE: 10,\n US: 10,\n GB: 10,\n FR: 9,\n CZ: 9,\n SK: 9,\n}\n\n// Validate a phone number with optional country-specific digit counts.\nexport function validatePhone(value: string, countryCode?: string): ValidationResult {\n if (!value) return ok\n const digits = value.replace(/\\D/g, '')\n if (digits.length < 7) return fail('Phone number too short')\n if (digits.length > 15) return fail('Phone number too long')\n if (countryCode) {\n const expected = PHONE_LENGTH[countryCode.toUpperCase()]\n if (expected && digits.length !== expected) {\n return fail(`Phone number should have ${expected} digits`)\n }\n }\n return ok\n}\n\n// === IBAN (MOD-97, ISO 13616) ===\n\nconst IBAN_LENGTHS: Record<string, number> = {\n AL: 28,\n AD: 24,\n AT: 20,\n AZ: 28,\n BH: 22,\n BY: 28,\n BE: 16,\n BA: 20,\n BR: 29,\n BG: 22,\n CR: 22,\n HR: 21,\n CY: 28,\n CZ: 24,\n DK: 18,\n DO: 28,\n EG: 29,\n SV: 28,\n EE: 20,\n FO: 18,\n FI: 18,\n FR: 27,\n GE: 22,\n DE: 22,\n GI: 23,\n GR: 27,\n GL: 18,\n GT: 28,\n HU: 28,\n IS: 26,\n IQ: 23,\n IE: 22,\n IL: 23,\n IT: 27,\n JO: 30,\n KZ: 20,\n XK: 20,\n KW: 30,\n LV: 21,\n LB: 28,\n LI: 21,\n LT: 20,\n LU: 20,\n MT: 31,\n MR: 27,\n MU: 30,\n MD: 24,\n MC: 27,\n ME: 22,\n NL: 18,\n MK: 19,\n NO: 15,\n PK: 24,\n PS: 29,\n PL: 28,\n PT: 25,\n QA: 29,\n RO: 24,\n LC: 32,\n SM: 27,\n SA: 24,\n RS: 22,\n SC: 31,\n SK: 24,\n SI: 19,\n ES: 24,\n SE: 24,\n CH: 21,\n TL: 23,\n TN: 24,\n TR: 26,\n UA: 29,\n AE: 23,\n GB: 22,\n VA: 22,\n VG: 24,\n}\n\n// Sorted list of supported ISO IBAN country codes for selection UIs.\nexport const ibanCountries: string[] = Object.keys(IBAN_LENGTHS).sort()\n\n// Look up the expected IBAN length for a country code or return null if unknown.\nexport function getIbanCountryLength(countryCode: string): number | null {\n return IBAN_LENGTHS[countryCode.toUpperCase()] ?? null\n}\n\n// Run the MOD-97 remainder calculation on a numeric IBAN representation.\nfunction mod97(numStr: string): number {\n let remainder = 0\n for (let i = 0; i < numStr.length; i++) {\n remainder = (remainder * 10 + parseInt(numStr[i], 10)) % 97\n }\n return remainder\n}\n\n// Validate a full IBAN using country length rules and the MOD-97 checksum.\nexport function validateIBAN(value: string): ValidationResult {\n if (!value) return ok\n const iban = value.replace(/\\s/g, '').toUpperCase()\n\n if (iban.length < 2) return fail('IBAN too short')\n\n const countryCode = iban.slice(0, 2)\n const expectedLength = IBAN_LENGTHS[countryCode]\n\n if (!expectedLength) return fail('Unknown IBAN country code')\n if (iban.length !== expectedLength) {\n return fail(`IBAN for ${countryCode} should have ${expectedLength} characters`)\n }\n\n // MOD-97 check: move first 4 chars to end, convert letters to numbers\n const rearranged = iban.slice(4) + iban.slice(0, 4)\n const numStr = rearranged.replace(/[A-Z]/g, (ch) => String(ch.charCodeAt(0) - 55))\n\n return mod97(numStr) === 1 ? ok : fail('Invalid IBAN checksum')\n}\n\n// === NIP (Polish Tax ID) ===\n\nconst NIP_WEIGHTS = [6, 5, 7, 2, 3, 4, 5, 6, 7]\n\n// Validate a Polish NIP number with its weighted checksum.\nexport function validateNIP(value: string): ValidationResult {\n if (!value) return ok\n const digits = value.replace(/\\D/g, '')\n if (digits.length !== 10) return fail('NIP must have 10 digits')\n\n let sum = 0\n for (let i = 0; i < 9; i++) {\n sum += parseInt(digits[i], 10) * NIP_WEIGHTS[i]\n }\n const checkDigit = sum % 11\n if (checkDigit === 10) return fail('Invalid NIP')\n return checkDigit === parseInt(digits[9], 10) ? ok : fail('Invalid NIP checksum')\n}\n\n// === PESEL ===\n\nconst PESEL_WEIGHTS = [1, 3, 7, 9, 1, 3, 7, 9, 1, 3]\n\n// Validate a Polish PESEL number with its checksum algorithm.\nexport function validatePESEL(value: string): ValidationResult {\n if (!value) return ok\n const digits = value.replace(/\\D/g, '')\n if (digits.length !== 11) return fail('PESEL must have 11 digits')\n\n let sum = 0\n for (let i = 0; i < 10; i++) {\n sum += parseInt(digits[i], 10) * PESEL_WEIGHTS[i]\n }\n const checkDigit = (10 - (sum % 10)) % 10\n return checkDigit === parseInt(digits[10], 10) ? ok : fail('Invalid PESEL checksum')\n}\n\n// === REGON ===\n\nconst REGON9_WEIGHTS = [8, 9, 2, 3, 4, 5, 6, 7]\nconst REGON14_WEIGHTS = [2, 4, 8, 5, 0, 9, 7, 3, 6, 1, 2, 4, 8]\n\n// Validate REGON numbers in both the 9-digit and 14-digit variants.\nexport function validateREGON(value: string): ValidationResult {\n if (!value) return ok\n const digits = value.replace(/\\D/g, '')\n\n if (digits.length !== 9 && digits.length !== 14) {\n return fail('REGON must have 9 or 14 digits')\n }\n\n const weights = digits.length === 9 ? REGON9_WEIGHTS : REGON14_WEIGHTS\n let sum = 0\n for (let i = 0; i < weights.length; i++) {\n sum += parseInt(digits[i], 10) * weights[i]\n }\n const checkDigit = sum % 11 === 10 ? 0 : sum % 11\n const lastDigit = parseInt(digits[digits.length - 1], 10)\n return checkDigit === lastDigit ? ok : fail('Invalid REGON checksum')\n}\n\n// === Compose validators ===\n\n// Run validators in order and stop at the first failure.\nexport function composeValidators(...validators: ValidatorFn[]): ValidatorFn {\n return (value: string) => {\n for (const validator of validators) {\n const result = validator(value)\n if (!result.valid) return result\n }\n return ok\n }\n}\n\n// === Date (DD/MM/YYYY, MM/DD/YYYY, YYYY/MM/DD) ===\n\nexport type DateFormat = 'DD/MM/YYYY' | 'MM/DD/YYYY' | 'YYYY/MM/DD'\n\ninterface DateValidationOptions {\n format?: DateFormat\n minDate?: Date\n maxDate?: Date\n}\n\n// Parse a date string in the given format into a Date or null.\nexport function parseDateString(value: string, format: DateFormat = 'DD/MM/YYYY'): Date | null {\n const digits = value.replace(/\\D/g, '')\n if (digits.length !== 8) return null\n\n let day: number, month: number, year: number\n if (format === 'DD/MM/YYYY') {\n day = parseInt(digits.slice(0, 2), 10)\n month = parseInt(digits.slice(2, 4), 10)\n year = parseInt(digits.slice(4, 8), 10)\n } else if (format === 'MM/DD/YYYY') {\n month = parseInt(digits.slice(0, 2), 10)\n day = parseInt(digits.slice(2, 4), 10)\n year = parseInt(digits.slice(4, 8), 10)\n } else {\n year = parseInt(digits.slice(0, 4), 10)\n month = parseInt(digits.slice(4, 6), 10)\n day = parseInt(digits.slice(6, 8), 10)\n }\n\n if (month < 1 || month > 12) return null\n if (day < 1 || day > 31) return null\n if (year < 1) return null\n\n const date = new Date(year, month - 1, day)\n // Verify the date didn't overflow (e.g. Feb 30 → Mar 2)\n if (date.getFullYear() !== year || date.getMonth() !== month - 1 || date.getDate() !== day) {\n return null\n }\n return date\n}\n\n// Validate a date string with optional range constraints.\nexport function validateDate(value: string, options: DateValidationOptions = {}): ValidationResult {\n if (!value) return ok\n const {format = 'DD/MM/YYYY', minDate, maxDate} = options\n\n const digits = value.replace(/\\D/g, '')\n if (digits.length !== 8) return fail('Incomplete date')\n\n const date = parseDateString(value, format)\n if (!date) return fail('Invalid date')\n\n if (minDate) {\n const min = new Date(minDate.getFullYear(), minDate.getMonth(), minDate.getDate())\n if (date < min) return fail('Date is too early')\n }\n if (maxDate) {\n const max = new Date(maxDate.getFullYear(), maxDate.getMonth(), maxDate.getDate())\n if (date > max) return fail('Date is too far in the future')\n }\n\n return ok\n}\n\nexport {validatePostCode} from './postalCodes'\nexport {validateCardNumber} from './creditCards'\n"],"mappings":"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"}
1
+ {"version":3,"file":"validators-B6yWdsu2.cjs","names":[],"sources":["../src/utils/postalCodes.ts","../src/utils/validators.ts"],"sourcesContent":["import type {ValidationResult} from './validators'\n\nexport interface PostCodeRule {\n countryCode: string\n label: string\n placeholder: string\n example: string\n inputMode: 'text' | 'numeric'\n maxLength: number\n regex: RegExp\n sanitize: (value: string) => string\n format: (value: string) => string\n message: string\n}\n\nconst OK_RESULT: ValidationResult = {valid: true}\n\n// Reuse one sanitizer for countries that mix letters and digits.\nfunction keepLettersAndDigits(value: string): string {\n return value.toUpperCase().replace(/[^A-Z0-9]/g, '')\n}\n\n// Apply the common Polish XX-XXX postcode shape.\nfunction formatPlPostCode(value: string): string {\n const digits = value.replace(/\\D/g, '').slice(0, 5)\n\n if (digits.length <= 2) {\n return digits\n }\n\n return `${digits.slice(0, 2)}-${digits.slice(2)}`\n}\n\n// Support ZIP and ZIP+4 with the same formatter.\nfunction formatUsPostCode(value: string): string {\n const digits = value.replace(/\\D/g, '').slice(0, 9)\n\n if (digits.length <= 5) {\n return digits\n }\n\n return `${digits.slice(0, 5)}-${digits.slice(5)}`\n}\n\n// Clamp countries that only need a fixed number of digits.\nfunction formatFixedDigits(value: string, maxLength: number): string {\n return value.replace(/\\D/g, '').slice(0, maxLength)\n}\n\n// Insert the standard center space used by Canadian post codes.\nfunction formatCaPostCode(value: string): string {\n const clean = keepLettersAndDigits(value).slice(0, 6)\n const chars = clean.split('')\n\n return chars\n .map((char, index) => {\n if (index === 3) {\n return ` ${char}`\n }\n\n return char\n })\n .join('')\n}\n\n// Split the outward and inward parts of a UK postcode.\nfunction formatGbPostCode(value: string): string {\n const clean = keepLettersAndDigits(value).slice(0, 7)\n\n if (clean.length <= 3) {\n return clean\n }\n\n return `${clean.slice(0, clean.length - 3)} ${clean.slice(-3)}`\n}\n\n// Split Dutch codes into four digits and two letters.\nfunction formatNlPostCode(value: string): string {\n const clean = keepLettersAndDigits(value).slice(0, 6)\n\n if (clean.length <= 4) {\n return clean\n }\n\n return `${clean.slice(0, 4)} ${clean.slice(4)}`\n}\n\nexport const postCodeRules: Record<string, PostCodeRule> = {\n PL: {\n countryCode: 'PL',\n label: 'Poland',\n placeholder: '12-345',\n example: '00-001',\n inputMode: 'numeric',\n maxLength: 6,\n regex: /^\\d{2}-\\d{3}$/,\n sanitize: (value) => value.replace(/\\D/g, '').slice(0, 5),\n format: formatPlPostCode,\n message: 'Use the Polish format XX-XXX',\n },\n DE: {\n countryCode: 'DE',\n label: 'Germany',\n placeholder: '12345',\n example: '10115',\n inputMode: 'numeric',\n maxLength: 5,\n regex: /^\\d{5}$/,\n sanitize: (value) => value.replace(/\\D/g, '').slice(0, 5),\n format: (value) => formatFixedDigits(value, 5),\n message: 'Use a 5-digit German postal code',\n },\n FR: {\n countryCode: 'FR',\n label: 'France',\n placeholder: '75001',\n example: '75001',\n inputMode: 'numeric',\n maxLength: 5,\n regex: /^\\d{5}$/,\n sanitize: (value) => value.replace(/\\D/g, '').slice(0, 5),\n format: (value) => formatFixedDigits(value, 5),\n message: 'Use a 5-digit French postal code',\n },\n ES: {\n countryCode: 'ES',\n label: 'Spain',\n placeholder: '28013',\n example: '28013',\n inputMode: 'numeric',\n maxLength: 5,\n regex: /^\\d{5}$/,\n sanitize: (value) => value.replace(/\\D/g, '').slice(0, 5),\n format: (value) => formatFixedDigits(value, 5),\n message: 'Use a 5-digit Spanish postal code',\n },\n IT: {\n countryCode: 'IT',\n label: 'Italy',\n placeholder: '00184',\n example: '00184',\n inputMode: 'numeric',\n maxLength: 5,\n regex: /^\\d{5}$/,\n sanitize: (value) => value.replace(/\\D/g, '').slice(0, 5),\n format: (value) => formatFixedDigits(value, 5),\n message: 'Use a 5-digit Italian postal code',\n },\n US: {\n countryCode: 'US',\n label: 'United States',\n placeholder: '12345 or 12345-6789',\n example: '10001',\n inputMode: 'numeric',\n maxLength: 10,\n regex: /^\\d{5}(?:-\\d{4})?$/,\n sanitize: (value) => value.replace(/\\D/g, '').slice(0, 9),\n format: formatUsPostCode,\n message: 'Use ZIP or ZIP+4 format',\n },\n CA: {\n countryCode: 'CA',\n label: 'Canada',\n placeholder: 'A1A 1A1',\n example: 'M5V 3L9',\n inputMode: 'text',\n maxLength: 7,\n regex: /^[A-Z]\\d[A-Z] \\d[A-Z]\\d$/,\n sanitize: (value) => keepLettersAndDigits(value).slice(0, 6),\n format: formatCaPostCode,\n message: 'Use the Canadian format A1A 1A1',\n },\n GB: {\n countryCode: 'GB',\n label: 'United Kingdom',\n placeholder: 'SW1A 1AA',\n example: 'SW1A 1AA',\n inputMode: 'text',\n maxLength: 8,\n regex: /^[A-Z]{1,2}\\d[A-Z\\d]? \\d[A-Z]{2}$/,\n sanitize: (value) => keepLettersAndDigits(value).slice(0, 7),\n format: formatGbPostCode,\n message: 'Use a valid UK postcode',\n },\n NL: {\n countryCode: 'NL',\n label: 'Netherlands',\n placeholder: '1234 AB',\n example: '1012 AB',\n inputMode: 'text',\n maxLength: 7,\n regex: /^\\d{4} [A-Z]{2}$/,\n sanitize: (value) => keepLettersAndDigits(value).slice(0, 6),\n format: formatNlPostCode,\n message: 'Use the Dutch format 1234 AB',\n },\n}\n\nexport const postCodeCountries = Object.values(postCodeRules).map(({countryCode, label}) => ({\n value: countryCode,\n label,\n}))\n\n// Return the active postal rule or fall back to Poland for deterministic behavior.\nexport function getPostCodeRule(countryCode: string = 'PL'): PostCodeRule {\n return postCodeRules[countryCode.toUpperCase()] ?? postCodeRules.PL\n}\n\n// Keep postal input values aligned with the selected country format.\nexport function formatPostCode(value: string, countryCode: string = 'PL'): string {\n const rule = getPostCodeRule(countryCode)\n return rule.format(rule.sanitize(value))\n}\n\n// Validate the user-visible postal code against the selected country rule.\nexport function validatePostCode(value: string, countryCode: string = 'PL'): ValidationResult {\n if (!value) {\n return OK_RESULT\n }\n\n const rule = getPostCodeRule(countryCode)\n const formatted = rule.format(rule.sanitize(value))\n\n if (!rule.regex.test(formatted)) {\n return {valid: false, error: rule.message}\n }\n\n return OK_RESULT\n}\n","export interface ValidationResult {\n valid: boolean\n error?: string\n}\n\nexport type ValidatorFn = (value: string) => ValidationResult\n\nconst ok: ValidationResult = {valid: true}\nconst fail = (error: string): ValidationResult => ({valid: false, error})\n\n// Ensure the field is not empty after trimming user input.\nexport function validateRequired(value: string): ValidationResult {\n return value.trim().length > 0 ? ok : fail('This field is required')\n}\n\n// Build a validator that enforces a minimum string length.\nexport function validateMinLength(min: number): ValidatorFn {\n return (value: string) => (value.length >= min ? ok : fail(`Minimum ${min} characters`))\n}\n\n// Build a validator that enforces a maximum string length.\nexport function validateMaxLength(max: number): ValidatorFn {\n return (value: string) => (value.length <= max ? ok : fail(`Maximum ${max} characters`))\n}\n\n// Build a validator around a custom regular expression.\nexport function validatePattern(pattern: RegExp, message?: string): ValidatorFn {\n return (value: string) => (pattern.test(value) ? ok : fail(message ?? 'Invalid format'))\n}\n\n// Validate numeric input against optional min and max bounds.\nexport function validateRange(min?: number, max?: number): ValidatorFn {\n return (value: string) => {\n const num = parseFloat(value)\n if (isNaN(num)) return fail('Must be a number')\n if (min !== undefined && num < min) return fail(`Minimum value is ${min}`)\n if (max !== undefined && num > max) return fail(`Maximum value is ${max}`)\n return ok\n }\n}\n\n// === Email ===\n\nconst EMAIL_RE =\n /^[a-zA-Z0-9.!#$%&'*+/=?^_`{|}~-]+@[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(?:\\.[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)*$/\n\n// Validate email format while allowing empty optional fields.\nexport function validateEmail(value: string): ValidationResult {\n if (!value) return ok\n return EMAIL_RE.test(value) ? ok : fail('Invalid email address')\n}\n\n// === Phone ===\n\nconst PHONE_LENGTH: Record<string, number> = {\n PL: 9,\n DE: 10,\n US: 10,\n GB: 10,\n FR: 9,\n CZ: 9,\n SK: 9,\n}\n\n// Validate a phone number with optional country-specific digit counts.\nexport function validatePhone(value: string, countryCode?: string): ValidationResult {\n if (!value) return ok\n const digits = value.replace(/\\D/g, '')\n if (digits.length < 7) return fail('Phone number too short')\n if (digits.length > 15) return fail('Phone number too long')\n if (countryCode) {\n const expected = PHONE_LENGTH[countryCode.toUpperCase()]\n if (expected && digits.length !== expected) {\n return fail(`Phone number should have ${expected} digits`)\n }\n }\n return ok\n}\n\n// === IBAN (MOD-97, ISO 13616) ===\n\nconst IBAN_LENGTHS: Record<string, number> = {\n AL: 28,\n AD: 24,\n AT: 20,\n AZ: 28,\n BH: 22,\n BY: 28,\n BE: 16,\n BA: 20,\n BR: 29,\n BG: 22,\n CR: 22,\n HR: 21,\n CY: 28,\n CZ: 24,\n DK: 18,\n DO: 28,\n EG: 29,\n SV: 28,\n EE: 20,\n FO: 18,\n FI: 18,\n FR: 27,\n GE: 22,\n DE: 22,\n GI: 23,\n GR: 27,\n GL: 18,\n GT: 28,\n HU: 28,\n IS: 26,\n IQ: 23,\n IE: 22,\n IL: 23,\n IT: 27,\n JO: 30,\n KZ: 20,\n XK: 20,\n KW: 30,\n LV: 21,\n LB: 28,\n LI: 21,\n LT: 20,\n LU: 20,\n MT: 31,\n MR: 27,\n MU: 30,\n MD: 24,\n MC: 27,\n ME: 22,\n NL: 18,\n MK: 19,\n NO: 15,\n PK: 24,\n PS: 29,\n PL: 28,\n PT: 25,\n QA: 29,\n RO: 24,\n LC: 32,\n SM: 27,\n SA: 24,\n RS: 22,\n SC: 31,\n SK: 24,\n SI: 19,\n ES: 24,\n SE: 24,\n CH: 21,\n TL: 23,\n TN: 24,\n TR: 26,\n UA: 29,\n AE: 23,\n GB: 22,\n VA: 22,\n VG: 24,\n}\n\n// Sorted list of supported ISO IBAN country codes for selection UIs.\nexport const ibanCountries: string[] = Object.keys(IBAN_LENGTHS).sort()\n\n// Look up the expected IBAN length for a country code or return null if unknown.\nexport function getIbanCountryLength(countryCode: string): number | null {\n return IBAN_LENGTHS[countryCode.toUpperCase()] ?? null\n}\n\n// Run the MOD-97 remainder calculation on a numeric IBAN representation.\nfunction mod97(numStr: string): number {\n let remainder = 0\n for (let i = 0; i < numStr.length; i++) {\n remainder = (remainder * 10 + parseInt(numStr[i], 10)) % 97\n }\n return remainder\n}\n\n// Validate a full IBAN using country length rules and the MOD-97 checksum.\nexport function validateIBAN(value: string): ValidationResult {\n if (!value) return ok\n const iban = value.replace(/\\s/g, '').toUpperCase()\n\n if (iban.length < 2) return fail('IBAN too short')\n\n const countryCode = iban.slice(0, 2)\n const expectedLength = IBAN_LENGTHS[countryCode]\n\n if (!expectedLength) return fail('Unknown IBAN country code')\n if (iban.length !== expectedLength) {\n return fail(`IBAN for ${countryCode} should have ${expectedLength} characters`)\n }\n\n // MOD-97 check: move first 4 chars to end, convert letters to numbers\n const rearranged = iban.slice(4) + iban.slice(0, 4)\n const numStr = rearranged.replace(/[A-Z]/g, (ch) => String(ch.charCodeAt(0) - 55))\n\n return mod97(numStr) === 1 ? ok : fail('Invalid IBAN checksum')\n}\n\n// === NIP (Polish Tax ID) ===\n\nconst NIP_WEIGHTS = [6, 5, 7, 2, 3, 4, 5, 6, 7]\n\n// Validate a Polish NIP number with its weighted checksum.\nexport function validateNIP(value: string): ValidationResult {\n if (!value) return ok\n const digits = value.replace(/\\D/g, '')\n if (digits.length !== 10) return fail('NIP must have 10 digits')\n\n let sum = 0\n for (let i = 0; i < 9; i++) {\n sum += parseInt(digits[i], 10) * NIP_WEIGHTS[i]\n }\n const checkDigit = sum % 11\n if (checkDigit === 10) return fail('Invalid NIP')\n return checkDigit === parseInt(digits[9], 10) ? ok : fail('Invalid NIP checksum')\n}\n\n// === PESEL ===\n\nconst PESEL_WEIGHTS = [1, 3, 7, 9, 1, 3, 7, 9, 1, 3]\n\n// Validate a Polish PESEL number with its checksum algorithm.\nexport function validatePESEL(value: string): ValidationResult {\n if (!value) return ok\n const digits = value.replace(/\\D/g, '')\n if (digits.length !== 11) return fail('PESEL must have 11 digits')\n\n let sum = 0\n for (let i = 0; i < 10; i++) {\n sum += parseInt(digits[i], 10) * PESEL_WEIGHTS[i]\n }\n const checkDigit = (10 - (sum % 10)) % 10\n return checkDigit === parseInt(digits[10], 10) ? ok : fail('Invalid PESEL checksum')\n}\n\n// === REGON ===\n\nconst REGON9_WEIGHTS = [8, 9, 2, 3, 4, 5, 6, 7]\nconst REGON14_WEIGHTS = [2, 4, 8, 5, 0, 9, 7, 3, 6, 1, 2, 4, 8]\n\n// Validate REGON numbers in both the 9-digit and 14-digit variants.\nexport function validateREGON(value: string): ValidationResult {\n if (!value) return ok\n const digits = value.replace(/\\D/g, '')\n\n if (digits.length !== 9 && digits.length !== 14) {\n return fail('REGON must have 9 or 14 digits')\n }\n\n const weights = digits.length === 9 ? REGON9_WEIGHTS : REGON14_WEIGHTS\n let sum = 0\n for (let i = 0; i < weights.length; i++) {\n sum += parseInt(digits[i], 10) * weights[i]\n }\n const checkDigit = sum % 11 === 10 ? 0 : sum % 11\n const lastDigit = parseInt(digits[digits.length - 1], 10)\n return checkDigit === lastDigit ? ok : fail('Invalid REGON checksum')\n}\n\n// === Compose validators ===\n\n// Run validators in order and stop at the first failure.\nexport function composeValidators(...validators: ValidatorFn[]): ValidatorFn {\n return (value: string) => {\n for (const validator of validators) {\n const result = validator(value)\n if (!result.valid) return result\n }\n return ok\n }\n}\n\n// === Date (DD/MM/YYYY, MM/DD/YYYY, YYYY/MM/DD) ===\n\nexport type DateFormat = 'DD/MM/YYYY' | 'MM/DD/YYYY' | 'YYYY/MM/DD'\n\ninterface DateValidationOptions {\n format?: DateFormat\n minDate?: Date\n maxDate?: Date\n}\n\n// Parse a date string in the given format into a Date or null.\nexport function parseDateString(value: string, format: DateFormat = 'DD/MM/YYYY'): Date | null {\n const digits = value.replace(/\\D/g, '')\n if (digits.length !== 8) return null\n\n let day: number, month: number, year: number\n if (format === 'DD/MM/YYYY') {\n day = parseInt(digits.slice(0, 2), 10)\n month = parseInt(digits.slice(2, 4), 10)\n year = parseInt(digits.slice(4, 8), 10)\n } else if (format === 'MM/DD/YYYY') {\n month = parseInt(digits.slice(0, 2), 10)\n day = parseInt(digits.slice(2, 4), 10)\n year = parseInt(digits.slice(4, 8), 10)\n } else {\n year = parseInt(digits.slice(0, 4), 10)\n month = parseInt(digits.slice(4, 6), 10)\n day = parseInt(digits.slice(6, 8), 10)\n }\n\n if (month < 1 || month > 12) return null\n if (day < 1 || day > 31) return null\n if (year < 1) return null\n\n const date = new Date(year, month - 1, day)\n // Verify the date didn't overflow (e.g. Feb 30 → Mar 2)\n if (date.getFullYear() !== year || date.getMonth() !== month - 1 || date.getDate() !== day) {\n return null\n }\n return date\n}\n\n// Validate a date string with optional range constraints.\nexport function validateDate(value: string, options: DateValidationOptions = {}): ValidationResult {\n if (!value) return ok\n const {format = 'DD/MM/YYYY', minDate, maxDate} = options\n\n const digits = value.replace(/\\D/g, '')\n if (digits.length !== 8) return fail('Incomplete date')\n\n const date = parseDateString(value, format)\n if (!date) return fail('Invalid date')\n\n if (minDate) {\n const min = new Date(minDate.getFullYear(), minDate.getMonth(), minDate.getDate())\n if (date < min) return fail('Date is too early')\n }\n if (maxDate) {\n const max = new Date(maxDate.getFullYear(), maxDate.getMonth(), maxDate.getDate())\n if (date > max) return fail('Date is too far in the future')\n }\n\n return ok\n}\n\nexport {validatePostCode} from './postalCodes'\nexport {validateCardNumber} from './creditCards'\n\n// === URL ===\n\nexport interface UrlValidationOptions {\n /**\n * Allowed URL protocols (without trailing colon). When the value carries a\n * protocol, it must be one of these. Defaults to `['http', 'https']`.\n */\n protocols?: string[]\n /**\n * When `true` (default), the value must include a protocol from `protocols`.\n * When `false`, a protocol-less value (e.g. `example.com/path`) still passes\n * as long as it parses as a URL after a synthetic `https://` prefix.\n */\n requireProtocol?: boolean\n}\n\n// Validate a URL while allowing empty optional fields. Uses the native URL\n// parser so we get IDN, port, query and fragment handling for free. The\n// protocol whitelist defaults to http/https — pass `protocols: []` to accept\n// any scheme.\nexport function validateUrl(value: string, options: UrlValidationOptions = {}): ValidationResult {\n if (!value) return ok\n\n const {protocols = ['http', 'https'], requireProtocol = true} = options\n\n const hasScheme = /^[a-zA-Z][a-zA-Z0-9+.-]*:/.test(value)\n if (!hasScheme && requireProtocol) {\n return fail(`URL must start with ${protocols.map((p) => `${p}://`).join(' or ')}`)\n }\n\n const candidate = hasScheme ? value : `https://${value}`\n\n let parsed: URL\n try {\n parsed = new URL(candidate)\n } catch {\n return fail('Invalid URL')\n }\n\n // Reject the parsed URL when it has no host (e.g. `https://`) — those slip\n // past `new URL()` silently in some engines.\n if (!parsed.hostname) return fail('Invalid URL')\n\n if (hasScheme && protocols.length > 0) {\n const scheme = parsed.protocol.replace(/:$/, '')\n if (!protocols.includes(scheme)) {\n return fail(`Protocol \"${scheme}\" is not allowed`)\n }\n }\n\n return ok\n}\n"],"mappings":"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"}
@@ -390,7 +390,24 @@ function R(e, t = {}) {
390
390
  let a = L(e, n);
391
391
  return a ? r && a < new Date(r.getFullYear(), r.getMonth(), r.getDate()) ? m("Date is too early") : i && a > new Date(i.getFullYear(), i.getMonth(), i.getDate()) ? m("Date is too far in the future") : p : m("Invalid date");
392
392
  }
393
+ function z(e, t = {}) {
394
+ if (!e) return p;
395
+ let { protocols: n = ["http", "https"], requireProtocol: r = !0 } = t, i = /^[a-zA-Z][a-zA-Z0-9+.-]*:/.test(e);
396
+ if (!i && r) return m(`URL must start with ${n.map((e) => `${e}://`).join(" or ")}`);
397
+ let a = i ? e : `https://${e}`, o;
398
+ try {
399
+ o = new URL(a);
400
+ } catch {
401
+ return m("Invalid URL");
402
+ }
403
+ if (!o.hostname) return m("Invalid URL");
404
+ if (i && n.length > 0) {
405
+ let e = o.protocol.replace(/:$/, "");
406
+ if (!n.includes(e)) return m(`Protocol "${e}" is not allowed`);
407
+ }
408
+ return p;
409
+ }
393
410
  //#endregion
394
- export { d as _, R as a, c as b, _ as c, M as d, v as f, h as g, y as h, L as i, g as l, F as m, E as n, x as o, C as p, T as r, O as s, I as t, A as u, u as v, f as x, l as y };
411
+ export { f as S, z as _, R as a, l as b, _ as c, M as d, v as f, h as g, y as h, L as i, g as l, F as m, E as n, x as o, C as p, T as r, O as s, I as t, A as u, d as v, c as x, u as y };
395
412
 
396
- //# sourceMappingURL=validators-D5OCyV2h.js.map
413
+ //# sourceMappingURL=validators-DVYOtFnw.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"validators-D5OCyV2h.js","names":[],"sources":["../src/utils/postalCodes.ts","../src/utils/validators.ts"],"sourcesContent":["import type {ValidationResult} from './validators'\n\nexport interface PostCodeRule {\n countryCode: string\n label: string\n placeholder: string\n example: string\n inputMode: 'text' | 'numeric'\n maxLength: number\n regex: RegExp\n sanitize: (value: string) => string\n format: (value: string) => string\n message: string\n}\n\nconst OK_RESULT: ValidationResult = {valid: true}\n\n// Reuse one sanitizer for countries that mix letters and digits.\nfunction keepLettersAndDigits(value: string): string {\n return value.toUpperCase().replace(/[^A-Z0-9]/g, '')\n}\n\n// Apply the common Polish XX-XXX postcode shape.\nfunction formatPlPostCode(value: string): string {\n const digits = value.replace(/\\D/g, '').slice(0, 5)\n\n if (digits.length <= 2) {\n return digits\n }\n\n return `${digits.slice(0, 2)}-${digits.slice(2)}`\n}\n\n// Support ZIP and ZIP+4 with the same formatter.\nfunction formatUsPostCode(value: string): string {\n const digits = value.replace(/\\D/g, '').slice(0, 9)\n\n if (digits.length <= 5) {\n return digits\n }\n\n return `${digits.slice(0, 5)}-${digits.slice(5)}`\n}\n\n// Clamp countries that only need a fixed number of digits.\nfunction formatFixedDigits(value: string, maxLength: number): string {\n return value.replace(/\\D/g, '').slice(0, maxLength)\n}\n\n// Insert the standard center space used by Canadian post codes.\nfunction formatCaPostCode(value: string): string {\n const clean = keepLettersAndDigits(value).slice(0, 6)\n const chars = clean.split('')\n\n return chars\n .map((char, index) => {\n if (index === 3) {\n return ` ${char}`\n }\n\n return char\n })\n .join('')\n}\n\n// Split the outward and inward parts of a UK postcode.\nfunction formatGbPostCode(value: string): string {\n const clean = keepLettersAndDigits(value).slice(0, 7)\n\n if (clean.length <= 3) {\n return clean\n }\n\n return `${clean.slice(0, clean.length - 3)} ${clean.slice(-3)}`\n}\n\n// Split Dutch codes into four digits and two letters.\nfunction formatNlPostCode(value: string): string {\n const clean = keepLettersAndDigits(value).slice(0, 6)\n\n if (clean.length <= 4) {\n return clean\n }\n\n return `${clean.slice(0, 4)} ${clean.slice(4)}`\n}\n\nexport const postCodeRules: Record<string, PostCodeRule> = {\n PL: {\n countryCode: 'PL',\n label: 'Poland',\n placeholder: '12-345',\n example: '00-001',\n inputMode: 'numeric',\n maxLength: 6,\n regex: /^\\d{2}-\\d{3}$/,\n sanitize: (value) => value.replace(/\\D/g, '').slice(0, 5),\n format: formatPlPostCode,\n message: 'Use the Polish format XX-XXX',\n },\n DE: {\n countryCode: 'DE',\n label: 'Germany',\n placeholder: '12345',\n example: '10115',\n inputMode: 'numeric',\n maxLength: 5,\n regex: /^\\d{5}$/,\n sanitize: (value) => value.replace(/\\D/g, '').slice(0, 5),\n format: (value) => formatFixedDigits(value, 5),\n message: 'Use a 5-digit German postal code',\n },\n FR: {\n countryCode: 'FR',\n label: 'France',\n placeholder: '75001',\n example: '75001',\n inputMode: 'numeric',\n maxLength: 5,\n regex: /^\\d{5}$/,\n sanitize: (value) => value.replace(/\\D/g, '').slice(0, 5),\n format: (value) => formatFixedDigits(value, 5),\n message: 'Use a 5-digit French postal code',\n },\n ES: {\n countryCode: 'ES',\n label: 'Spain',\n placeholder: '28013',\n example: '28013',\n inputMode: 'numeric',\n maxLength: 5,\n regex: /^\\d{5}$/,\n sanitize: (value) => value.replace(/\\D/g, '').slice(0, 5),\n format: (value) => formatFixedDigits(value, 5),\n message: 'Use a 5-digit Spanish postal code',\n },\n IT: {\n countryCode: 'IT',\n label: 'Italy',\n placeholder: '00184',\n example: '00184',\n inputMode: 'numeric',\n maxLength: 5,\n regex: /^\\d{5}$/,\n sanitize: (value) => value.replace(/\\D/g, '').slice(0, 5),\n format: (value) => formatFixedDigits(value, 5),\n message: 'Use a 5-digit Italian postal code',\n },\n US: {\n countryCode: 'US',\n label: 'United States',\n placeholder: '12345 or 12345-6789',\n example: '10001',\n inputMode: 'numeric',\n maxLength: 10,\n regex: /^\\d{5}(?:-\\d{4})?$/,\n sanitize: (value) => value.replace(/\\D/g, '').slice(0, 9),\n format: formatUsPostCode,\n message: 'Use ZIP or ZIP+4 format',\n },\n CA: {\n countryCode: 'CA',\n label: 'Canada',\n placeholder: 'A1A 1A1',\n example: 'M5V 3L9',\n inputMode: 'text',\n maxLength: 7,\n regex: /^[A-Z]\\d[A-Z] \\d[A-Z]\\d$/,\n sanitize: (value) => keepLettersAndDigits(value).slice(0, 6),\n format: formatCaPostCode,\n message: 'Use the Canadian format A1A 1A1',\n },\n GB: {\n countryCode: 'GB',\n label: 'United Kingdom',\n placeholder: 'SW1A 1AA',\n example: 'SW1A 1AA',\n inputMode: 'text',\n maxLength: 8,\n regex: /^[A-Z]{1,2}\\d[A-Z\\d]? \\d[A-Z]{2}$/,\n sanitize: (value) => keepLettersAndDigits(value).slice(0, 7),\n format: formatGbPostCode,\n message: 'Use a valid UK postcode',\n },\n NL: {\n countryCode: 'NL',\n label: 'Netherlands',\n placeholder: '1234 AB',\n example: '1012 AB',\n inputMode: 'text',\n maxLength: 7,\n regex: /^\\d{4} [A-Z]{2}$/,\n sanitize: (value) => keepLettersAndDigits(value).slice(0, 6),\n format: formatNlPostCode,\n message: 'Use the Dutch format 1234 AB',\n },\n}\n\nexport const postCodeCountries = Object.values(postCodeRules).map(({countryCode, label}) => ({\n value: countryCode,\n label,\n}))\n\n// Return the active postal rule or fall back to Poland for deterministic behavior.\nexport function getPostCodeRule(countryCode: string = 'PL'): PostCodeRule {\n return postCodeRules[countryCode.toUpperCase()] ?? postCodeRules.PL\n}\n\n// Keep postal input values aligned with the selected country format.\nexport function formatPostCode(value: string, countryCode: string = 'PL'): string {\n const rule = getPostCodeRule(countryCode)\n return rule.format(rule.sanitize(value))\n}\n\n// Validate the user-visible postal code against the selected country rule.\nexport function validatePostCode(value: string, countryCode: string = 'PL'): ValidationResult {\n if (!value) {\n return OK_RESULT\n }\n\n const rule = getPostCodeRule(countryCode)\n const formatted = rule.format(rule.sanitize(value))\n\n if (!rule.regex.test(formatted)) {\n return {valid: false, error: rule.message}\n }\n\n return OK_RESULT\n}\n","export interface ValidationResult {\n valid: boolean\n error?: string\n}\n\nexport type ValidatorFn = (value: string) => ValidationResult\n\nconst ok: ValidationResult = {valid: true}\nconst fail = (error: string): ValidationResult => ({valid: false, error})\n\n// Ensure the field is not empty after trimming user input.\nexport function validateRequired(value: string): ValidationResult {\n return value.trim().length > 0 ? ok : fail('This field is required')\n}\n\n// Build a validator that enforces a minimum string length.\nexport function validateMinLength(min: number): ValidatorFn {\n return (value: string) => (value.length >= min ? ok : fail(`Minimum ${min} characters`))\n}\n\n// Build a validator that enforces a maximum string length.\nexport function validateMaxLength(max: number): ValidatorFn {\n return (value: string) => (value.length <= max ? ok : fail(`Maximum ${max} characters`))\n}\n\n// Build a validator around a custom regular expression.\nexport function validatePattern(pattern: RegExp, message?: string): ValidatorFn {\n return (value: string) => (pattern.test(value) ? ok : fail(message ?? 'Invalid format'))\n}\n\n// Validate numeric input against optional min and max bounds.\nexport function validateRange(min?: number, max?: number): ValidatorFn {\n return (value: string) => {\n const num = parseFloat(value)\n if (isNaN(num)) return fail('Must be a number')\n if (min !== undefined && num < min) return fail(`Minimum value is ${min}`)\n if (max !== undefined && num > max) return fail(`Maximum value is ${max}`)\n return ok\n }\n}\n\n// === Email ===\n\nconst EMAIL_RE =\n /^[a-zA-Z0-9.!#$%&'*+/=?^_`{|}~-]+@[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(?:\\.[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)*$/\n\n// Validate email format while allowing empty optional fields.\nexport function validateEmail(value: string): ValidationResult {\n if (!value) return ok\n return EMAIL_RE.test(value) ? ok : fail('Invalid email address')\n}\n\n// === Phone ===\n\nconst PHONE_LENGTH: Record<string, number> = {\n PL: 9,\n DE: 10,\n US: 10,\n GB: 10,\n FR: 9,\n CZ: 9,\n SK: 9,\n}\n\n// Validate a phone number with optional country-specific digit counts.\nexport function validatePhone(value: string, countryCode?: string): ValidationResult {\n if (!value) return ok\n const digits = value.replace(/\\D/g, '')\n if (digits.length < 7) return fail('Phone number too short')\n if (digits.length > 15) return fail('Phone number too long')\n if (countryCode) {\n const expected = PHONE_LENGTH[countryCode.toUpperCase()]\n if (expected && digits.length !== expected) {\n return fail(`Phone number should have ${expected} digits`)\n }\n }\n return ok\n}\n\n// === IBAN (MOD-97, ISO 13616) ===\n\nconst IBAN_LENGTHS: Record<string, number> = {\n AL: 28,\n AD: 24,\n AT: 20,\n AZ: 28,\n BH: 22,\n BY: 28,\n BE: 16,\n BA: 20,\n BR: 29,\n BG: 22,\n CR: 22,\n HR: 21,\n CY: 28,\n CZ: 24,\n DK: 18,\n DO: 28,\n EG: 29,\n SV: 28,\n EE: 20,\n FO: 18,\n FI: 18,\n FR: 27,\n GE: 22,\n DE: 22,\n GI: 23,\n GR: 27,\n GL: 18,\n GT: 28,\n HU: 28,\n IS: 26,\n IQ: 23,\n IE: 22,\n IL: 23,\n IT: 27,\n JO: 30,\n KZ: 20,\n XK: 20,\n KW: 30,\n LV: 21,\n LB: 28,\n LI: 21,\n LT: 20,\n LU: 20,\n MT: 31,\n MR: 27,\n MU: 30,\n MD: 24,\n MC: 27,\n ME: 22,\n NL: 18,\n MK: 19,\n NO: 15,\n PK: 24,\n PS: 29,\n PL: 28,\n PT: 25,\n QA: 29,\n RO: 24,\n LC: 32,\n SM: 27,\n SA: 24,\n RS: 22,\n SC: 31,\n SK: 24,\n SI: 19,\n ES: 24,\n SE: 24,\n CH: 21,\n TL: 23,\n TN: 24,\n TR: 26,\n UA: 29,\n AE: 23,\n GB: 22,\n VA: 22,\n VG: 24,\n}\n\n// Sorted list of supported ISO IBAN country codes for selection UIs.\nexport const ibanCountries: string[] = Object.keys(IBAN_LENGTHS).sort()\n\n// Look up the expected IBAN length for a country code or return null if unknown.\nexport function getIbanCountryLength(countryCode: string): number | null {\n return IBAN_LENGTHS[countryCode.toUpperCase()] ?? null\n}\n\n// Run the MOD-97 remainder calculation on a numeric IBAN representation.\nfunction mod97(numStr: string): number {\n let remainder = 0\n for (let i = 0; i < numStr.length; i++) {\n remainder = (remainder * 10 + parseInt(numStr[i], 10)) % 97\n }\n return remainder\n}\n\n// Validate a full IBAN using country length rules and the MOD-97 checksum.\nexport function validateIBAN(value: string): ValidationResult {\n if (!value) return ok\n const iban = value.replace(/\\s/g, '').toUpperCase()\n\n if (iban.length < 2) return fail('IBAN too short')\n\n const countryCode = iban.slice(0, 2)\n const expectedLength = IBAN_LENGTHS[countryCode]\n\n if (!expectedLength) return fail('Unknown IBAN country code')\n if (iban.length !== expectedLength) {\n return fail(`IBAN for ${countryCode} should have ${expectedLength} characters`)\n }\n\n // MOD-97 check: move first 4 chars to end, convert letters to numbers\n const rearranged = iban.slice(4) + iban.slice(0, 4)\n const numStr = rearranged.replace(/[A-Z]/g, (ch) => String(ch.charCodeAt(0) - 55))\n\n return mod97(numStr) === 1 ? ok : fail('Invalid IBAN checksum')\n}\n\n// === NIP (Polish Tax ID) ===\n\nconst NIP_WEIGHTS = [6, 5, 7, 2, 3, 4, 5, 6, 7]\n\n// Validate a Polish NIP number with its weighted checksum.\nexport function validateNIP(value: string): ValidationResult {\n if (!value) return ok\n const digits = value.replace(/\\D/g, '')\n if (digits.length !== 10) return fail('NIP must have 10 digits')\n\n let sum = 0\n for (let i = 0; i < 9; i++) {\n sum += parseInt(digits[i], 10) * NIP_WEIGHTS[i]\n }\n const checkDigit = sum % 11\n if (checkDigit === 10) return fail('Invalid NIP')\n return checkDigit === parseInt(digits[9], 10) ? ok : fail('Invalid NIP checksum')\n}\n\n// === PESEL ===\n\nconst PESEL_WEIGHTS = [1, 3, 7, 9, 1, 3, 7, 9, 1, 3]\n\n// Validate a Polish PESEL number with its checksum algorithm.\nexport function validatePESEL(value: string): ValidationResult {\n if (!value) return ok\n const digits = value.replace(/\\D/g, '')\n if (digits.length !== 11) return fail('PESEL must have 11 digits')\n\n let sum = 0\n for (let i = 0; i < 10; i++) {\n sum += parseInt(digits[i], 10) * PESEL_WEIGHTS[i]\n }\n const checkDigit = (10 - (sum % 10)) % 10\n return checkDigit === parseInt(digits[10], 10) ? ok : fail('Invalid PESEL checksum')\n}\n\n// === REGON ===\n\nconst REGON9_WEIGHTS = [8, 9, 2, 3, 4, 5, 6, 7]\nconst REGON14_WEIGHTS = [2, 4, 8, 5, 0, 9, 7, 3, 6, 1, 2, 4, 8]\n\n// Validate REGON numbers in both the 9-digit and 14-digit variants.\nexport function validateREGON(value: string): ValidationResult {\n if (!value) return ok\n const digits = value.replace(/\\D/g, '')\n\n if (digits.length !== 9 && digits.length !== 14) {\n return fail('REGON must have 9 or 14 digits')\n }\n\n const weights = digits.length === 9 ? REGON9_WEIGHTS : REGON14_WEIGHTS\n let sum = 0\n for (let i = 0; i < weights.length; i++) {\n sum += parseInt(digits[i], 10) * weights[i]\n }\n const checkDigit = sum % 11 === 10 ? 0 : sum % 11\n const lastDigit = parseInt(digits[digits.length - 1], 10)\n return checkDigit === lastDigit ? ok : fail('Invalid REGON checksum')\n}\n\n// === Compose validators ===\n\n// Run validators in order and stop at the first failure.\nexport function composeValidators(...validators: ValidatorFn[]): ValidatorFn {\n return (value: string) => {\n for (const validator of validators) {\n const result = validator(value)\n if (!result.valid) return result\n }\n return ok\n }\n}\n\n// === Date (DD/MM/YYYY, MM/DD/YYYY, YYYY/MM/DD) ===\n\nexport type DateFormat = 'DD/MM/YYYY' | 'MM/DD/YYYY' | 'YYYY/MM/DD'\n\ninterface DateValidationOptions {\n format?: DateFormat\n minDate?: Date\n maxDate?: Date\n}\n\n// Parse a date string in the given format into a Date or null.\nexport function parseDateString(value: string, format: DateFormat = 'DD/MM/YYYY'): Date | null {\n const digits = value.replace(/\\D/g, '')\n if (digits.length !== 8) return null\n\n let day: number, month: number, year: number\n if (format === 'DD/MM/YYYY') {\n day = parseInt(digits.slice(0, 2), 10)\n month = parseInt(digits.slice(2, 4), 10)\n year = parseInt(digits.slice(4, 8), 10)\n } else if (format === 'MM/DD/YYYY') {\n month = parseInt(digits.slice(0, 2), 10)\n day = parseInt(digits.slice(2, 4), 10)\n year = parseInt(digits.slice(4, 8), 10)\n } else {\n year = parseInt(digits.slice(0, 4), 10)\n month = parseInt(digits.slice(4, 6), 10)\n day = parseInt(digits.slice(6, 8), 10)\n }\n\n if (month < 1 || month > 12) return null\n if (day < 1 || day > 31) return null\n if (year < 1) return null\n\n const date = new Date(year, month - 1, day)\n // Verify the date didn't overflow (e.g. Feb 30 → Mar 2)\n if (date.getFullYear() !== year || date.getMonth() !== month - 1 || date.getDate() !== day) {\n return null\n }\n return date\n}\n\n// Validate a date string with optional range constraints.\nexport function validateDate(value: string, options: DateValidationOptions = {}): ValidationResult {\n if (!value) return ok\n const {format = 'DD/MM/YYYY', minDate, maxDate} = options\n\n const digits = value.replace(/\\D/g, '')\n if (digits.length !== 8) return fail('Incomplete date')\n\n const date = parseDateString(value, format)\n if (!date) return fail('Invalid date')\n\n if (minDate) {\n const min = new Date(minDate.getFullYear(), minDate.getMonth(), minDate.getDate())\n if (date < min) return fail('Date is too early')\n }\n if (maxDate) {\n const max = new Date(maxDate.getFullYear(), maxDate.getMonth(), maxDate.getDate())\n if (date > max) return fail('Date is too far in the future')\n }\n\n return ok\n}\n\nexport {validatePostCode} from './postalCodes'\nexport {validateCardNumber} from './creditCards'\n"],"mappings":"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"}
1
+ {"version":3,"file":"validators-DVYOtFnw.js","names":[],"sources":["../src/utils/postalCodes.ts","../src/utils/validators.ts"],"sourcesContent":["import type {ValidationResult} from './validators'\n\nexport interface PostCodeRule {\n countryCode: string\n label: string\n placeholder: string\n example: string\n inputMode: 'text' | 'numeric'\n maxLength: number\n regex: RegExp\n sanitize: (value: string) => string\n format: (value: string) => string\n message: string\n}\n\nconst OK_RESULT: ValidationResult = {valid: true}\n\n// Reuse one sanitizer for countries that mix letters and digits.\nfunction keepLettersAndDigits(value: string): string {\n return value.toUpperCase().replace(/[^A-Z0-9]/g, '')\n}\n\n// Apply the common Polish XX-XXX postcode shape.\nfunction formatPlPostCode(value: string): string {\n const digits = value.replace(/\\D/g, '').slice(0, 5)\n\n if (digits.length <= 2) {\n return digits\n }\n\n return `${digits.slice(0, 2)}-${digits.slice(2)}`\n}\n\n// Support ZIP and ZIP+4 with the same formatter.\nfunction formatUsPostCode(value: string): string {\n const digits = value.replace(/\\D/g, '').slice(0, 9)\n\n if (digits.length <= 5) {\n return digits\n }\n\n return `${digits.slice(0, 5)}-${digits.slice(5)}`\n}\n\n// Clamp countries that only need a fixed number of digits.\nfunction formatFixedDigits(value: string, maxLength: number): string {\n return value.replace(/\\D/g, '').slice(0, maxLength)\n}\n\n// Insert the standard center space used by Canadian post codes.\nfunction formatCaPostCode(value: string): string {\n const clean = keepLettersAndDigits(value).slice(0, 6)\n const chars = clean.split('')\n\n return chars\n .map((char, index) => {\n if (index === 3) {\n return ` ${char}`\n }\n\n return char\n })\n .join('')\n}\n\n// Split the outward and inward parts of a UK postcode.\nfunction formatGbPostCode(value: string): string {\n const clean = keepLettersAndDigits(value).slice(0, 7)\n\n if (clean.length <= 3) {\n return clean\n }\n\n return `${clean.slice(0, clean.length - 3)} ${clean.slice(-3)}`\n}\n\n// Split Dutch codes into four digits and two letters.\nfunction formatNlPostCode(value: string): string {\n const clean = keepLettersAndDigits(value).slice(0, 6)\n\n if (clean.length <= 4) {\n return clean\n }\n\n return `${clean.slice(0, 4)} ${clean.slice(4)}`\n}\n\nexport const postCodeRules: Record<string, PostCodeRule> = {\n PL: {\n countryCode: 'PL',\n label: 'Poland',\n placeholder: '12-345',\n example: '00-001',\n inputMode: 'numeric',\n maxLength: 6,\n regex: /^\\d{2}-\\d{3}$/,\n sanitize: (value) => value.replace(/\\D/g, '').slice(0, 5),\n format: formatPlPostCode,\n message: 'Use the Polish format XX-XXX',\n },\n DE: {\n countryCode: 'DE',\n label: 'Germany',\n placeholder: '12345',\n example: '10115',\n inputMode: 'numeric',\n maxLength: 5,\n regex: /^\\d{5}$/,\n sanitize: (value) => value.replace(/\\D/g, '').slice(0, 5),\n format: (value) => formatFixedDigits(value, 5),\n message: 'Use a 5-digit German postal code',\n },\n FR: {\n countryCode: 'FR',\n label: 'France',\n placeholder: '75001',\n example: '75001',\n inputMode: 'numeric',\n maxLength: 5,\n regex: /^\\d{5}$/,\n sanitize: (value) => value.replace(/\\D/g, '').slice(0, 5),\n format: (value) => formatFixedDigits(value, 5),\n message: 'Use a 5-digit French postal code',\n },\n ES: {\n countryCode: 'ES',\n label: 'Spain',\n placeholder: '28013',\n example: '28013',\n inputMode: 'numeric',\n maxLength: 5,\n regex: /^\\d{5}$/,\n sanitize: (value) => value.replace(/\\D/g, '').slice(0, 5),\n format: (value) => formatFixedDigits(value, 5),\n message: 'Use a 5-digit Spanish postal code',\n },\n IT: {\n countryCode: 'IT',\n label: 'Italy',\n placeholder: '00184',\n example: '00184',\n inputMode: 'numeric',\n maxLength: 5,\n regex: /^\\d{5}$/,\n sanitize: (value) => value.replace(/\\D/g, '').slice(0, 5),\n format: (value) => formatFixedDigits(value, 5),\n message: 'Use a 5-digit Italian postal code',\n },\n US: {\n countryCode: 'US',\n label: 'United States',\n placeholder: '12345 or 12345-6789',\n example: '10001',\n inputMode: 'numeric',\n maxLength: 10,\n regex: /^\\d{5}(?:-\\d{4})?$/,\n sanitize: (value) => value.replace(/\\D/g, '').slice(0, 9),\n format: formatUsPostCode,\n message: 'Use ZIP or ZIP+4 format',\n },\n CA: {\n countryCode: 'CA',\n label: 'Canada',\n placeholder: 'A1A 1A1',\n example: 'M5V 3L9',\n inputMode: 'text',\n maxLength: 7,\n regex: /^[A-Z]\\d[A-Z] \\d[A-Z]\\d$/,\n sanitize: (value) => keepLettersAndDigits(value).slice(0, 6),\n format: formatCaPostCode,\n message: 'Use the Canadian format A1A 1A1',\n },\n GB: {\n countryCode: 'GB',\n label: 'United Kingdom',\n placeholder: 'SW1A 1AA',\n example: 'SW1A 1AA',\n inputMode: 'text',\n maxLength: 8,\n regex: /^[A-Z]{1,2}\\d[A-Z\\d]? \\d[A-Z]{2}$/,\n sanitize: (value) => keepLettersAndDigits(value).slice(0, 7),\n format: formatGbPostCode,\n message: 'Use a valid UK postcode',\n },\n NL: {\n countryCode: 'NL',\n label: 'Netherlands',\n placeholder: '1234 AB',\n example: '1012 AB',\n inputMode: 'text',\n maxLength: 7,\n regex: /^\\d{4} [A-Z]{2}$/,\n sanitize: (value) => keepLettersAndDigits(value).slice(0, 6),\n format: formatNlPostCode,\n message: 'Use the Dutch format 1234 AB',\n },\n}\n\nexport const postCodeCountries = Object.values(postCodeRules).map(({countryCode, label}) => ({\n value: countryCode,\n label,\n}))\n\n// Return the active postal rule or fall back to Poland for deterministic behavior.\nexport function getPostCodeRule(countryCode: string = 'PL'): PostCodeRule {\n return postCodeRules[countryCode.toUpperCase()] ?? postCodeRules.PL\n}\n\n// Keep postal input values aligned with the selected country format.\nexport function formatPostCode(value: string, countryCode: string = 'PL'): string {\n const rule = getPostCodeRule(countryCode)\n return rule.format(rule.sanitize(value))\n}\n\n// Validate the user-visible postal code against the selected country rule.\nexport function validatePostCode(value: string, countryCode: string = 'PL'): ValidationResult {\n if (!value) {\n return OK_RESULT\n }\n\n const rule = getPostCodeRule(countryCode)\n const formatted = rule.format(rule.sanitize(value))\n\n if (!rule.regex.test(formatted)) {\n return {valid: false, error: rule.message}\n }\n\n return OK_RESULT\n}\n","export interface ValidationResult {\n valid: boolean\n error?: string\n}\n\nexport type ValidatorFn = (value: string) => ValidationResult\n\nconst ok: ValidationResult = {valid: true}\nconst fail = (error: string): ValidationResult => ({valid: false, error})\n\n// Ensure the field is not empty after trimming user input.\nexport function validateRequired(value: string): ValidationResult {\n return value.trim().length > 0 ? ok : fail('This field is required')\n}\n\n// Build a validator that enforces a minimum string length.\nexport function validateMinLength(min: number): ValidatorFn {\n return (value: string) => (value.length >= min ? ok : fail(`Minimum ${min} characters`))\n}\n\n// Build a validator that enforces a maximum string length.\nexport function validateMaxLength(max: number): ValidatorFn {\n return (value: string) => (value.length <= max ? ok : fail(`Maximum ${max} characters`))\n}\n\n// Build a validator around a custom regular expression.\nexport function validatePattern(pattern: RegExp, message?: string): ValidatorFn {\n return (value: string) => (pattern.test(value) ? ok : fail(message ?? 'Invalid format'))\n}\n\n// Validate numeric input against optional min and max bounds.\nexport function validateRange(min?: number, max?: number): ValidatorFn {\n return (value: string) => {\n const num = parseFloat(value)\n if (isNaN(num)) return fail('Must be a number')\n if (min !== undefined && num < min) return fail(`Minimum value is ${min}`)\n if (max !== undefined && num > max) return fail(`Maximum value is ${max}`)\n return ok\n }\n}\n\n// === Email ===\n\nconst EMAIL_RE =\n /^[a-zA-Z0-9.!#$%&'*+/=?^_`{|}~-]+@[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(?:\\.[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)*$/\n\n// Validate email format while allowing empty optional fields.\nexport function validateEmail(value: string): ValidationResult {\n if (!value) return ok\n return EMAIL_RE.test(value) ? ok : fail('Invalid email address')\n}\n\n// === Phone ===\n\nconst PHONE_LENGTH: Record<string, number> = {\n PL: 9,\n DE: 10,\n US: 10,\n GB: 10,\n FR: 9,\n CZ: 9,\n SK: 9,\n}\n\n// Validate a phone number with optional country-specific digit counts.\nexport function validatePhone(value: string, countryCode?: string): ValidationResult {\n if (!value) return ok\n const digits = value.replace(/\\D/g, '')\n if (digits.length < 7) return fail('Phone number too short')\n if (digits.length > 15) return fail('Phone number too long')\n if (countryCode) {\n const expected = PHONE_LENGTH[countryCode.toUpperCase()]\n if (expected && digits.length !== expected) {\n return fail(`Phone number should have ${expected} digits`)\n }\n }\n return ok\n}\n\n// === IBAN (MOD-97, ISO 13616) ===\n\nconst IBAN_LENGTHS: Record<string, number> = {\n AL: 28,\n AD: 24,\n AT: 20,\n AZ: 28,\n BH: 22,\n BY: 28,\n BE: 16,\n BA: 20,\n BR: 29,\n BG: 22,\n CR: 22,\n HR: 21,\n CY: 28,\n CZ: 24,\n DK: 18,\n DO: 28,\n EG: 29,\n SV: 28,\n EE: 20,\n FO: 18,\n FI: 18,\n FR: 27,\n GE: 22,\n DE: 22,\n GI: 23,\n GR: 27,\n GL: 18,\n GT: 28,\n HU: 28,\n IS: 26,\n IQ: 23,\n IE: 22,\n IL: 23,\n IT: 27,\n JO: 30,\n KZ: 20,\n XK: 20,\n KW: 30,\n LV: 21,\n LB: 28,\n LI: 21,\n LT: 20,\n LU: 20,\n MT: 31,\n MR: 27,\n MU: 30,\n MD: 24,\n MC: 27,\n ME: 22,\n NL: 18,\n MK: 19,\n NO: 15,\n PK: 24,\n PS: 29,\n PL: 28,\n PT: 25,\n QA: 29,\n RO: 24,\n LC: 32,\n SM: 27,\n SA: 24,\n RS: 22,\n SC: 31,\n SK: 24,\n SI: 19,\n ES: 24,\n SE: 24,\n CH: 21,\n TL: 23,\n TN: 24,\n TR: 26,\n UA: 29,\n AE: 23,\n GB: 22,\n VA: 22,\n VG: 24,\n}\n\n// Sorted list of supported ISO IBAN country codes for selection UIs.\nexport const ibanCountries: string[] = Object.keys(IBAN_LENGTHS).sort()\n\n// Look up the expected IBAN length for a country code or return null if unknown.\nexport function getIbanCountryLength(countryCode: string): number | null {\n return IBAN_LENGTHS[countryCode.toUpperCase()] ?? null\n}\n\n// Run the MOD-97 remainder calculation on a numeric IBAN representation.\nfunction mod97(numStr: string): number {\n let remainder = 0\n for (let i = 0; i < numStr.length; i++) {\n remainder = (remainder * 10 + parseInt(numStr[i], 10)) % 97\n }\n return remainder\n}\n\n// Validate a full IBAN using country length rules and the MOD-97 checksum.\nexport function validateIBAN(value: string): ValidationResult {\n if (!value) return ok\n const iban = value.replace(/\\s/g, '').toUpperCase()\n\n if (iban.length < 2) return fail('IBAN too short')\n\n const countryCode = iban.slice(0, 2)\n const expectedLength = IBAN_LENGTHS[countryCode]\n\n if (!expectedLength) return fail('Unknown IBAN country code')\n if (iban.length !== expectedLength) {\n return fail(`IBAN for ${countryCode} should have ${expectedLength} characters`)\n }\n\n // MOD-97 check: move first 4 chars to end, convert letters to numbers\n const rearranged = iban.slice(4) + iban.slice(0, 4)\n const numStr = rearranged.replace(/[A-Z]/g, (ch) => String(ch.charCodeAt(0) - 55))\n\n return mod97(numStr) === 1 ? ok : fail('Invalid IBAN checksum')\n}\n\n// === NIP (Polish Tax ID) ===\n\nconst NIP_WEIGHTS = [6, 5, 7, 2, 3, 4, 5, 6, 7]\n\n// Validate a Polish NIP number with its weighted checksum.\nexport function validateNIP(value: string): ValidationResult {\n if (!value) return ok\n const digits = value.replace(/\\D/g, '')\n if (digits.length !== 10) return fail('NIP must have 10 digits')\n\n let sum = 0\n for (let i = 0; i < 9; i++) {\n sum += parseInt(digits[i], 10) * NIP_WEIGHTS[i]\n }\n const checkDigit = sum % 11\n if (checkDigit === 10) return fail('Invalid NIP')\n return checkDigit === parseInt(digits[9], 10) ? ok : fail('Invalid NIP checksum')\n}\n\n// === PESEL ===\n\nconst PESEL_WEIGHTS = [1, 3, 7, 9, 1, 3, 7, 9, 1, 3]\n\n// Validate a Polish PESEL number with its checksum algorithm.\nexport function validatePESEL(value: string): ValidationResult {\n if (!value) return ok\n const digits = value.replace(/\\D/g, '')\n if (digits.length !== 11) return fail('PESEL must have 11 digits')\n\n let sum = 0\n for (let i = 0; i < 10; i++) {\n sum += parseInt(digits[i], 10) * PESEL_WEIGHTS[i]\n }\n const checkDigit = (10 - (sum % 10)) % 10\n return checkDigit === parseInt(digits[10], 10) ? ok : fail('Invalid PESEL checksum')\n}\n\n// === REGON ===\n\nconst REGON9_WEIGHTS = [8, 9, 2, 3, 4, 5, 6, 7]\nconst REGON14_WEIGHTS = [2, 4, 8, 5, 0, 9, 7, 3, 6, 1, 2, 4, 8]\n\n// Validate REGON numbers in both the 9-digit and 14-digit variants.\nexport function validateREGON(value: string): ValidationResult {\n if (!value) return ok\n const digits = value.replace(/\\D/g, '')\n\n if (digits.length !== 9 && digits.length !== 14) {\n return fail('REGON must have 9 or 14 digits')\n }\n\n const weights = digits.length === 9 ? REGON9_WEIGHTS : REGON14_WEIGHTS\n let sum = 0\n for (let i = 0; i < weights.length; i++) {\n sum += parseInt(digits[i], 10) * weights[i]\n }\n const checkDigit = sum % 11 === 10 ? 0 : sum % 11\n const lastDigit = parseInt(digits[digits.length - 1], 10)\n return checkDigit === lastDigit ? ok : fail('Invalid REGON checksum')\n}\n\n// === Compose validators ===\n\n// Run validators in order and stop at the first failure.\nexport function composeValidators(...validators: ValidatorFn[]): ValidatorFn {\n return (value: string) => {\n for (const validator of validators) {\n const result = validator(value)\n if (!result.valid) return result\n }\n return ok\n }\n}\n\n// === Date (DD/MM/YYYY, MM/DD/YYYY, YYYY/MM/DD) ===\n\nexport type DateFormat = 'DD/MM/YYYY' | 'MM/DD/YYYY' | 'YYYY/MM/DD'\n\ninterface DateValidationOptions {\n format?: DateFormat\n minDate?: Date\n maxDate?: Date\n}\n\n// Parse a date string in the given format into a Date or null.\nexport function parseDateString(value: string, format: DateFormat = 'DD/MM/YYYY'): Date | null {\n const digits = value.replace(/\\D/g, '')\n if (digits.length !== 8) return null\n\n let day: number, month: number, year: number\n if (format === 'DD/MM/YYYY') {\n day = parseInt(digits.slice(0, 2), 10)\n month = parseInt(digits.slice(2, 4), 10)\n year = parseInt(digits.slice(4, 8), 10)\n } else if (format === 'MM/DD/YYYY') {\n month = parseInt(digits.slice(0, 2), 10)\n day = parseInt(digits.slice(2, 4), 10)\n year = parseInt(digits.slice(4, 8), 10)\n } else {\n year = parseInt(digits.slice(0, 4), 10)\n month = parseInt(digits.slice(4, 6), 10)\n day = parseInt(digits.slice(6, 8), 10)\n }\n\n if (month < 1 || month > 12) return null\n if (day < 1 || day > 31) return null\n if (year < 1) return null\n\n const date = new Date(year, month - 1, day)\n // Verify the date didn't overflow (e.g. Feb 30 → Mar 2)\n if (date.getFullYear() !== year || date.getMonth() !== month - 1 || date.getDate() !== day) {\n return null\n }\n return date\n}\n\n// Validate a date string with optional range constraints.\nexport function validateDate(value: string, options: DateValidationOptions = {}): ValidationResult {\n if (!value) return ok\n const {format = 'DD/MM/YYYY', minDate, maxDate} = options\n\n const digits = value.replace(/\\D/g, '')\n if (digits.length !== 8) return fail('Incomplete date')\n\n const date = parseDateString(value, format)\n if (!date) return fail('Invalid date')\n\n if (minDate) {\n const min = new Date(minDate.getFullYear(), minDate.getMonth(), minDate.getDate())\n if (date < min) return fail('Date is too early')\n }\n if (maxDate) {\n const max = new Date(maxDate.getFullYear(), maxDate.getMonth(), maxDate.getDate())\n if (date > max) return fail('Date is too far in the future')\n }\n\n return ok\n}\n\nexport {validatePostCode} from './postalCodes'\nexport {validateCardNumber} from './creditCards'\n\n// === URL ===\n\nexport interface UrlValidationOptions {\n /**\n * Allowed URL protocols (without trailing colon). When the value carries a\n * protocol, it must be one of these. Defaults to `['http', 'https']`.\n */\n protocols?: string[]\n /**\n * When `true` (default), the value must include a protocol from `protocols`.\n * When `false`, a protocol-less value (e.g. `example.com/path`) still passes\n * as long as it parses as a URL after a synthetic `https://` prefix.\n */\n requireProtocol?: boolean\n}\n\n// Validate a URL while allowing empty optional fields. Uses the native URL\n// parser so we get IDN, port, query and fragment handling for free. The\n// protocol whitelist defaults to http/https — pass `protocols: []` to accept\n// any scheme.\nexport function validateUrl(value: string, options: UrlValidationOptions = {}): ValidationResult {\n if (!value) return ok\n\n const {protocols = ['http', 'https'], requireProtocol = true} = options\n\n const hasScheme = /^[a-zA-Z][a-zA-Z0-9+.-]*:/.test(value)\n if (!hasScheme && requireProtocol) {\n return fail(`URL must start with ${protocols.map((p) => `${p}://`).join(' or ')}`)\n }\n\n const candidate = hasScheme ? value : `https://${value}`\n\n let parsed: URL\n try {\n parsed = new URL(candidate)\n } catch {\n return fail('Invalid URL')\n }\n\n // Reject the parsed URL when it has no host (e.g. `https://`) — those slip\n // past `new URL()` silently in some engines.\n if (!parsed.hostname) return fail('Invalid URL')\n\n if (hasScheme && protocols.length > 0) {\n const scheme = parsed.protocol.replace(/:$/, '')\n if (!protocols.includes(scheme)) {\n return fail(`Protocol \"${scheme}\" is not allowed`)\n }\n }\n\n return ok\n}\n"],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@banzamel/mineralui",
3
- "version": "1.11.1",
3
+ "version": "2.0.0",
4
4
  "description": "Modern React UI component framework with mineral dark aesthetic",
5
5
  "type": "module",
6
6
  "main": "dist/index.cjs",