zod-ir 1.1.0 → 1.1.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -1,2 +1,2 @@
1
- "use strict";var l=Object.defineProperty;var m=Object.getOwnPropertyDescriptor;var x=Object.getOwnPropertyNames;var C=Object.prototype.hasOwnProperty;var I=(t,e)=>{for(var n in e)l(t,n,{get:e[n],enumerable:!0})},O=(t,e,n,s)=>{if(e&&typeof e=="object"||typeof e=="function")for(let r of x(e))!C.call(t,r)&&r!==n&&l(t,r,{get:()=>e[r],enumerable:!(s=m(e,r))||s.enumerable});return t};var M=t=>O(l({},"__esModule",{value:!0}),t);var N={};I(N,{isCardNumber:()=>f,isIranianMobile:()=>d,isLandline:()=>g,isMelliCode:()=>p,isPostalCode:()=>b,isSheba:()=>u,zCardNumber:()=>R,zIranianMobile:()=>$,zLandline:()=>z,zMelliCode:()=>h,zPostalCode:()=>E,zSheba:()=>B});module.exports=M(N);var a=require("zod");function p(t){if(!/^\d{10}$/.test(t))return!1;let e=parseInt(t[9]);if(/^(\d)\1+$/.test(t))return!1;let n=t.substring(0,9).split("").reduce((s,r,i)=>s+parseInt(r)*(10-i),0)%11;return n<2?e===n:e===11-n}function f(t){let e=t.replace(/[\-\s]/g,"");if(!/^\d{16}$/.test(e))return!1;let n=0,s=!1;for(let r=e.length-1;r>=0;r--){let i=parseInt(e[r]);s&&(i*=2,i>9&&(i-=9)),n+=i,s=!s}return n%10===0}function d(t,{strictZero:e="optional"}={}){let n="9\\d{9}",s="";return e===!0?s=`^0${n}$`:e===!1?s=`^${n}$`:s=`^(?:0|\\+98)?${n}$`,new RegExp(s).test(t)}function u(t){let e=t.toUpperCase().replace(/[\-\s]/g,"");if(e.length!==26||!e.startsWith("IR"))return!1;let n=e.substring(4)+"1827"+e.substring(2,4),s=Array.from(n).map(r=>parseInt(r,36)).reduce((r,i)=>{let c=(i<10,i);return(+(r+""+c)%97).toString()},"");return parseInt(s)===1}function b(t){return!(!/^\d{10}$/.test(t)||t.startsWith("0"))}function g(t){return/^0\d{2}\d{8}$/.test(t)}var S={fa:{melliCode:"\u06A9\u062F \u0645\u0644\u06CC \u0646\u0627\u0645\u0639\u062A\u0628\u0631 \u0627\u0633\u062A",cardNumber:"\u0634\u0645\u0627\u0631\u0647 \u06A9\u0627\u0631\u062A \u0646\u0627\u0645\u0639\u062A\u0628\u0631 \u0627\u0633\u062A",mobile:"\u0634\u0645\u0627\u0631\u0647 \u0645\u0648\u0628\u0627\u06CC\u0644 \u0646\u0627\u0645\u0639\u062A\u0628\u0631 \u0627\u0633\u062A",sheba:"\u0634\u0645\u0627\u0631\u0647 \u0634\u0628\u0627 \u0646\u0627\u0645\u0639\u062A\u0628\u0631 \u0627\u0633\u062A",postalCode:"\u06A9\u062F \u067E\u0633\u062A\u06CC \u0646\u0627\u0645\u0639\u062A\u0628\u0631 \u0627\u0633\u062A",landline:"\u0634\u0645\u0627\u0631\u0647 \u062A\u0644\u0641\u0646 \u062B\u0627\u0628\u062A \u0646\u0627\u0645\u0639\u062A\u0628\u0631 \u0627\u0633\u062A"},en:{melliCode:"Invalid national code",cardNumber:"Invalid card number",mobile:"Invalid mobile number",sheba:"Invalid Sheba (IBAN) number",postalCode:"Invalid postal code",landline:"Invalid landline number"}},o=(t,e)=>{if(e?.message)return e.message;let n=e?.locale||"fa";return S[n][t]};var h=t=>a.z.string().refine(e=>p(e),{message:o("melliCode",t)}),R=t=>a.z.string().refine(e=>f(e),{message:o("cardNumber",t)}),$=t=>a.z.string().refine(e=>d(e,{strictZero:t?.strictZero}),{message:o("mobile",t)}),B=t=>a.z.string().refine(e=>u(e),{message:o("sheba",t)}),E=t=>a.z.string().refine(e=>b(e),{message:o("postalCode",t)}),z=t=>a.z.string().refine(e=>g(e),{message:o("landline",t)});0&&(module.exports={isCardNumber,isIranianMobile,isLandline,isMelliCode,isPostalCode,isSheba,zCardNumber,zIranianMobile,zLandline,zMelliCode,zPostalCode,zSheba});
1
+ "use strict";var l=Object.defineProperty;var b=Object.getOwnPropertyDescriptor;var m=Object.getOwnPropertyNames;var x=Object.prototype.hasOwnProperty;var C=(t,e)=>{for(var n in e)l(t,n,{get:e[n],enumerable:!0})},I=(t,e,n,s)=>{if(e&&typeof e=="object"||typeof e=="function")for(let i of m(e))!x.call(t,i)&&i!==n&&l(t,i,{get:()=>e[i],enumerable:!(s=b(e,i))||s.enumerable});return t};var S=t=>I(l({},"__esModule",{value:!0}),t);var z={};C(z,{isCardNumber:()=>d,isIranianMobile:()=>c,isLandline:()=>u,isMelliCode:()=>p,isPostalCode:()=>f,isSheba:()=>g,zCardNumber:()=>h,zIranianMobile:()=>B,zLandline:()=>E,zMelliCode:()=>M,zPostalCode:()=>$,zSheba:()=>R});module.exports=S(z);var a=require("zod");function p(t){if(!/^\d{10}$/.test(t)||/^(\d)\1+$/.test(t))return!1;let e=parseInt(t[9]),n=t.substring(0,9).split("").reduce((s,i,o)=>s+parseInt(i)*(10-o),0)%11;return n<2?e===n:e===11-n}function d(t){let e=t.replace(/[\-\s]/g,"");if(!/^\d{16}$/.test(e))return!1;let n=0,s=!1;for(let i=e.length-1;i>=0;i--){let o=parseInt(e[i]);s&&(o*=2,o>9&&(o-=9)),n+=o,s=!s}return n%10===0}function c(t,{strictZero:e="optional"}={}){let n="9\\d{9}",s="";return e===!0?s=`^0${n}$`:e===!1?s=`^${n}$`:s=`^(?:0|\\+98)?${n}$`,new RegExp(s).test(t)}function g(t){let e=t.toUpperCase().replace(/[\-\s]/g,"");if(e.length!==26||!e.startsWith("IR"))return!1;let s=(e.substring(4)+e.substring(0,4)).split("").map(i=>{let o=i.charCodeAt(0);return o>=48&&o<=57?i:(o-55).toString()}).join("");try{return BigInt(s)%BigInt(97)===BigInt(1)}catch{return!1}}function f(t){return/^[1-9]\d{9}$/.test(t)}function u(t){return/^0\d{2}\d{8}$/.test(t)}var O={fa:{melliCode:"\u06A9\u062F \u0645\u0644\u06CC \u0646\u0627\u0645\u0639\u062A\u0628\u0631 \u0627\u0633\u062A",cardNumber:"\u0634\u0645\u0627\u0631\u0647 \u06A9\u0627\u0631\u062A \u0646\u0627\u0645\u0639\u062A\u0628\u0631 \u0627\u0633\u062A",mobile:"\u0634\u0645\u0627\u0631\u0647 \u0645\u0648\u0628\u0627\u06CC\u0644 \u0646\u0627\u0645\u0639\u062A\u0628\u0631 \u0627\u0633\u062A",sheba:"\u0634\u0645\u0627\u0631\u0647 \u0634\u0628\u0627 \u0646\u0627\u0645\u0639\u062A\u0628\u0631 \u0627\u0633\u062A",postalCode:"\u06A9\u062F \u067E\u0633\u062A\u06CC \u0646\u0627\u0645\u0639\u062A\u0628\u0631 \u0627\u0633\u062A",landline:"\u0634\u0645\u0627\u0631\u0647 \u062A\u0644\u0641\u0646 \u062B\u0627\u0628\u062A \u0646\u0627\u0645\u0639\u062A\u0628\u0631 \u0627\u0633\u062A"},en:{melliCode:"Invalid national code",cardNumber:"Invalid card number",mobile:"Invalid mobile number",sheba:"Invalid Sheba (IBAN) number",postalCode:"Invalid postal code",landline:"Invalid landline number"}},r=(t,e)=>{if(e?.message)return e.message;let n=e?.locale||"fa";return O[n][t]};var M=t=>a.z.string().refine(e=>p(e),{message:r("melliCode",t)}),h=t=>a.z.string().refine(e=>d(e),{message:r("cardNumber",t)}),B=t=>a.z.string().refine(e=>c(e,{strictZero:t?.strictZero}),{message:r("mobile",t)}),R=t=>a.z.string().refine(e=>g(e),{message:r("sheba",t)}),$=t=>a.z.string().refine(e=>f(e),{message:r("postalCode",t)}),E=t=>a.z.string().refine(e=>u(e),{message:r("landline",t)});0&&(module.exports={isCardNumber,isIranianMobile,isLandline,isMelliCode,isPostalCode,isSheba,zCardNumber,zIranianMobile,zLandline,zMelliCode,zPostalCode,zSheba});
2
2
  //# sourceMappingURL=index.js.map
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/index.ts","../src/utils.ts","../src/constants.ts"],"sourcesContent":["import { z } from \"zod\";\nimport {\n isMelliCode,\n isCardNumber,\n isIranianMobile,\n isSheba,\n isPostalCode,\n isLandline,\n} from \"./utils\";\nimport { getMessage, BaseOptions } from \"./constants\";\n\nexport const zMelliCode = (options?: BaseOptions) =>\n z.string().refine((val) => isMelliCode(val), {\n message: getMessage(\"melliCode\", options),\n });\n\nexport const zCardNumber = (options?: BaseOptions) =>\n z.string().refine((val) => isCardNumber(val), {\n message: getMessage(\"cardNumber\", options),\n });\n\ninterface MobileOptions extends BaseOptions {\n strictZero?: boolean | \"optional\";\n}\n\nexport const zIranianMobile = (options?: MobileOptions) =>\n z\n .string()\n .refine(\n (val) => isIranianMobile(val, { strictZero: options?.strictZero }),\n {\n message: getMessage(\"mobile\", options),\n }\n );\n\nexport const zSheba = (options?: BaseOptions) =>\n z.string().refine((val) => isSheba(val), {\n message: getMessage(\"sheba\", options),\n });\n\nexport const zPostalCode = (options?: BaseOptions) =>\n z.string().refine((val) => isPostalCode(val), {\n message: getMessage(\"postalCode\", options),\n });\n\nexport const zLandline = (options?: BaseOptions) =>\n z.string().refine((val) => isLandline(val), {\n message: getMessage(\"landline\", options),\n });\n\nexport {\n isMelliCode,\n isCardNumber,\n isIranianMobile,\n isSheba,\n isPostalCode,\n isLandline,\n};\n","export function isMelliCode(code: string): boolean {\n if (!/^\\d{10}$/.test(code)) return false;\n\n const check = parseInt(code[9]);\n if (/^(\\d)\\1+$/.test(code)) return false;\n\n const sum =\n code\n .substring(0, 9)\n .split(\"\")\n .reduce((acc, x, i) => acc + parseInt(x) * (10 - i), 0) % 11;\n\n return sum < 2 ? check === sum : check === 11 - sum;\n}\n\nexport function isCardNumber(code: string): boolean {\n const sanitized = code.replace(/[\\-\\s]/g, \"\");\n if (!/^\\d{16}$/.test(sanitized)) return false;\n\n let sum = 0;\n let shouldDouble = false;\n\n for (let i = sanitized.length - 1; i >= 0; i--) {\n let digit = parseInt(sanitized[i]);\n\n if (shouldDouble) {\n digit *= 2;\n if (digit > 9) digit -= 9;\n }\n\n sum += digit;\n shouldDouble = !shouldDouble;\n }\n\n return sum % 10 === 0;\n}\n\ninterface MobileValidationOptions {\n strictZero?: boolean | \"optional\";\n}\n\nexport function isIranianMobile(\n mobile: string,\n { strictZero = \"optional\" }: MobileValidationOptions = {}\n): boolean {\n const corePattern = \"9\\\\d{9}\";\n let pattern = \"\";\n\n if (strictZero === true) {\n pattern = `^0${corePattern}$`;\n } else if (strictZero === false) {\n pattern = `^${corePattern}$`;\n } else {\n pattern = `^(?:0|\\\\+98)?${corePattern}$`;\n }\n\n return new RegExp(pattern).test(mobile);\n}\n\nexport function isSheba(code: string): boolean {\n const iban = code.toUpperCase().replace(/[\\-\\s]/g, \"\");\n\n if (iban.length !== 26) return false;\n if (!iban.startsWith(\"IR\")) return false;\n\n const newStr = iban.substring(4) + \"1827\" + iban.substring(2, 4);\n\n const remainder = Array.from(newStr)\n .map((c) => parseInt(c, 36))\n .reduce((remainder, value) => {\n const v = value < 10 ? value : value;\n return (Number(remainder + \"\" + v) % 97).toString();\n }, \"\");\n\n return parseInt(remainder) === 1;\n}\n\nexport function isPostalCode(code: string): boolean {\n if (!/^\\d{10}$/.test(code)) return false;\n if (code.startsWith(\"0\")) return false;\n return true;\n}\n\nexport function isLandline(code: string): boolean {\n return /^0\\d{2}\\d{8}$/.test(code);\n}\n","export const ERROR_MESSAGES = {\n fa: {\n melliCode: \"کد ملی نامعتبر است\",\n cardNumber: \"شماره کارت نامعتبر است\",\n mobile: \"شماره موبایل نامعتبر است\",\n sheba: \"شماره شبا نامعتبر است\",\n postalCode: \"کد پستی نامعتبر است\",\n landline: \"شماره تلفن ثابت نامعتبر است\",\n },\n en: {\n melliCode: \"Invalid national code\",\n cardNumber: \"Invalid card number\",\n mobile: \"Invalid mobile number\",\n sheba: \"Invalid Sheba (IBAN) number\",\n postalCode: \"Invalid postal code\",\n landline: \"Invalid landline number\",\n },\n} as const;\n\nexport type Language = keyof typeof ERROR_MESSAGES;\n\nexport interface BaseOptions {\n message?: string;\n locale?: Language;\n}\n\nexport const getMessage = (\n key: keyof (typeof ERROR_MESSAGES)[\"fa\"],\n options?: BaseOptions\n): string => {\n if (options?.message) return options.message;\n const lang = options?.locale || \"fa\";\n return ERROR_MESSAGES[lang][key];\n};\n"],"mappings":"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","names":["index_exports","__export","isCardNumber","isIranianMobile","isLandline","isMelliCode","isPostalCode","isSheba","zCardNumber","zIranianMobile","zLandline","zMelliCode","zPostalCode","zSheba","__toCommonJS","import_zod","isMelliCode","code","check","sum","acc","x","isCardNumber","sanitized","shouldDouble","i","digit","isIranianMobile","mobile","strictZero","corePattern","pattern","isSheba","iban","newStr","remainder","c","value","v","isPostalCode","isLandline","ERROR_MESSAGES","getMessage","key","options","lang","zMelliCode","options","val","isMelliCode","getMessage","zCardNumber","isCardNumber","zIranianMobile","isIranianMobile","zSheba","isSheba","zPostalCode","isPostalCode","zLandline","isLandline"]}
1
+ {"version":3,"sources":["../src/index.ts","../src/utils.ts","../src/constants.ts"],"sourcesContent":["import { z } from \"zod\";\nimport {\n isMelliCode,\n isCardNumber,\n isIranianMobile,\n isSheba,\n isPostalCode,\n isLandline,\n} from \"./utils\";\nimport { getMessage, BaseOptions } from \"./constants\";\n\nexport const zMelliCode = (options?: BaseOptions) =>\n z.string().refine((val) => isMelliCode(val), {\n message: getMessage(\"melliCode\", options),\n });\n\nexport const zCardNumber = (options?: BaseOptions) =>\n z.string().refine((val) => isCardNumber(val), {\n message: getMessage(\"cardNumber\", options),\n });\n\ninterface MobileOptions extends BaseOptions {\n strictZero?: boolean | \"optional\";\n}\n\nexport const zIranianMobile = (options?: MobileOptions) =>\n z\n .string()\n .refine(\n (val) => isIranianMobile(val, { strictZero: options?.strictZero }),\n {\n message: getMessage(\"mobile\", options),\n }\n );\n\nexport const zSheba = (options?: BaseOptions) =>\n z.string().refine((val) => isSheba(val), {\n message: getMessage(\"sheba\", options),\n });\n\nexport const zPostalCode = (options?: BaseOptions) =>\n z.string().refine((val) => isPostalCode(val), {\n message: getMessage(\"postalCode\", options),\n });\n\nexport const zLandline = (options?: BaseOptions) =>\n z.string().refine((val) => isLandline(val), {\n message: getMessage(\"landline\", options),\n });\n\nexport {\n isMelliCode,\n isCardNumber,\n isIranianMobile,\n isSheba,\n isPostalCode,\n isLandline,\n};\n","export function isMelliCode(code: string): boolean {\n if (!/^\\d{10}$/.test(code)) return false;\n if (/^(\\d)\\1+$/.test(code)) return false;\n\n const check = parseInt(code[9]);\n const sum =\n code\n .substring(0, 9)\n .split(\"\")\n .reduce((acc, x, i) => acc + parseInt(x) * (10 - i), 0) % 11;\n\n return sum < 2 ? check === sum : check === 11 - sum;\n}\n\nexport function isCardNumber(code: string): boolean {\n const sanitized = code.replace(/[\\-\\s]/g, \"\");\n if (!/^\\d{16}$/.test(sanitized)) return false;\n\n let sum = 0;\n let shouldDouble = false;\n\n for (let i = sanitized.length - 1; i >= 0; i--) {\n let digit = parseInt(sanitized[i]);\n\n if (shouldDouble) {\n digit *= 2;\n if (digit > 9) digit -= 9;\n }\n\n sum += digit;\n shouldDouble = !shouldDouble;\n }\n\n return sum % 10 === 0;\n}\n\ninterface MobileValidationOptions {\n strictZero?: boolean | \"optional\";\n}\n\nexport function isIranianMobile(\n mobile: string,\n { strictZero = \"optional\" }: MobileValidationOptions = {}\n): boolean {\n const corePattern = \"9\\\\d{9}\";\n let pattern = \"\";\n\n if (strictZero === true) {\n pattern = `^0${corePattern}$`;\n } else if (strictZero === false) {\n pattern = `^${corePattern}$`;\n } else {\n pattern = `^(?:0|\\\\+98)?${corePattern}$`;\n }\n\n return new RegExp(pattern).test(mobile);\n}\n\nexport function isSheba(code: string): boolean {\n const iban = code.toUpperCase().replace(/[\\-\\s]/g, \"\");\n\n if (iban.length !== 26 || !iban.startsWith(\"IR\")) return false;\n\n const newStr = iban.substring(4) + iban.substring(0, 4);\n\n const numericString = newStr\n .split(\"\")\n .map((char) => {\n const code = char.charCodeAt(0);\n return code >= 48 && code <= 57 ? char : (code - 55).toString();\n })\n .join(\"\");\n\n try {\n const remainder = BigInt(numericString) % BigInt(97);\n return remainder === BigInt(1);\n } catch {\n return false;\n }\n}\n\nexport function isPostalCode(code: string): boolean {\n return /^[1-9]\\d{9}$/.test(code);\n}\n\nexport function isLandline(code: string): boolean {\n return /^0\\d{2}\\d{8}$/.test(code);\n}\n","export const ERROR_MESSAGES = {\n fa: {\n melliCode: \"کد ملی نامعتبر است\",\n cardNumber: \"شماره کارت نامعتبر است\",\n mobile: \"شماره موبایل نامعتبر است\",\n sheba: \"شماره شبا نامعتبر است\",\n postalCode: \"کد پستی نامعتبر است\",\n landline: \"شماره تلفن ثابت نامعتبر است\",\n },\n en: {\n melliCode: \"Invalid national code\",\n cardNumber: \"Invalid card number\",\n mobile: \"Invalid mobile number\",\n sheba: \"Invalid Sheba (IBAN) number\",\n postalCode: \"Invalid postal code\",\n landline: \"Invalid landline number\",\n },\n} as const;\n\nexport type Language = keyof typeof ERROR_MESSAGES;\n\nexport interface BaseOptions {\n message?: string;\n locale?: Language;\n}\n\nexport const getMessage = (\n key: keyof (typeof ERROR_MESSAGES)[\"fa\"],\n options?: BaseOptions\n): string => {\n if (options?.message) return options.message;\n const lang = options?.locale || \"fa\";\n return ERROR_MESSAGES[lang][key];\n};\n"],"mappings":"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","names":["index_exports","__export","isCardNumber","isIranianMobile","isLandline","isMelliCode","isPostalCode","isSheba","zCardNumber","zIranianMobile","zLandline","zMelliCode","zPostalCode","zSheba","__toCommonJS","import_zod","isMelliCode","code","check","sum","acc","x","i","isCardNumber","sanitized","shouldDouble","digit","isIranianMobile","mobile","strictZero","corePattern","pattern","isSheba","iban","numericString","char","isPostalCode","isLandline","ERROR_MESSAGES","getMessage","key","options","lang","zMelliCode","options","val","isMelliCode","getMessage","zCardNumber","isCardNumber","zIranianMobile","isIranianMobile","zSheba","isSheba","zPostalCode","isPostalCode","zLandline","isLandline"]}
package/dist/index.mjs CHANGED
@@ -1,2 +1,2 @@
1
- import{z as a}from"zod";function l(e){if(!/^\d{10}$/.test(e))return!1;let t=parseInt(e[9]);if(/^(\d)\1+$/.test(e))return!1;let n=e.substring(0,9).split("").reduce((s,i,r)=>s+parseInt(i)*(10-r),0)%11;return n<2?t===n:t===11-n}function p(e){let t=e.replace(/[\-\s]/g,"");if(!/^\d{16}$/.test(t))return!1;let n=0,s=!1;for(let i=t.length-1;i>=0;i--){let r=parseInt(t[i]);s&&(r*=2,r>9&&(r-=9)),n+=r,s=!s}return n%10===0}function f(e,{strictZero:t="optional"}={}){let n="9\\d{9}",s="";return t===!0?s=`^0${n}$`:t===!1?s=`^${n}$`:s=`^(?:0|\\+98)?${n}$`,new RegExp(s).test(e)}function d(e){let t=e.toUpperCase().replace(/[\-\s]/g,"");if(t.length!==26||!t.startsWith("IR"))return!1;let n=t.substring(4)+"1827"+t.substring(2,4),s=Array.from(n).map(i=>parseInt(i,36)).reduce((i,r)=>{let g=(r<10,r);return(+(i+""+g)%97).toString()},"");return parseInt(s)===1}function u(e){return!(!/^\d{10}$/.test(e)||e.startsWith("0"))}function b(e){return/^0\d{2}\d{8}$/.test(e)}var c={fa:{melliCode:"\u06A9\u062F \u0645\u0644\u06CC \u0646\u0627\u0645\u0639\u062A\u0628\u0631 \u0627\u0633\u062A",cardNumber:"\u0634\u0645\u0627\u0631\u0647 \u06A9\u0627\u0631\u062A \u0646\u0627\u0645\u0639\u062A\u0628\u0631 \u0627\u0633\u062A",mobile:"\u0634\u0645\u0627\u0631\u0647 \u0645\u0648\u0628\u0627\u06CC\u0644 \u0646\u0627\u0645\u0639\u062A\u0628\u0631 \u0627\u0633\u062A",sheba:"\u0634\u0645\u0627\u0631\u0647 \u0634\u0628\u0627 \u0646\u0627\u0645\u0639\u062A\u0628\u0631 \u0627\u0633\u062A",postalCode:"\u06A9\u062F \u067E\u0633\u062A\u06CC \u0646\u0627\u0645\u0639\u062A\u0628\u0631 \u0627\u0633\u062A",landline:"\u0634\u0645\u0627\u0631\u0647 \u062A\u0644\u0641\u0646 \u062B\u0627\u0628\u062A \u0646\u0627\u0645\u0639\u062A\u0628\u0631 \u0627\u0633\u062A"},en:{melliCode:"Invalid national code",cardNumber:"Invalid card number",mobile:"Invalid mobile number",sheba:"Invalid Sheba (IBAN) number",postalCode:"Invalid postal code",landline:"Invalid landline number"}},o=(e,t)=>{if(t?.message)return t.message;let n=t?.locale||"fa";return c[n][e]};var S=e=>a.string().refine(t=>l(t),{message:o("melliCode",e)}),h=e=>a.string().refine(t=>p(t),{message:o("cardNumber",e)}),R=e=>a.string().refine(t=>f(t,{strictZero:e?.strictZero}),{message:o("mobile",e)}),$=e=>a.string().refine(t=>d(t),{message:o("sheba",e)}),B=e=>a.string().refine(t=>u(t),{message:o("postalCode",e)}),E=e=>a.string().refine(t=>b(t),{message:o("landline",e)});export{p as isCardNumber,f as isIranianMobile,b as isLandline,l as isMelliCode,u as isPostalCode,d as isSheba,h as zCardNumber,R as zIranianMobile,E as zLandline,S as zMelliCode,B as zPostalCode,$ as zSheba};
1
+ import{z as a}from"zod";function l(t){if(!/^\d{10}$/.test(t)||/^(\d)\1+$/.test(t))return!1;let e=parseInt(t[9]),n=t.substring(0,9).split("").reduce((s,o,i)=>s+parseInt(o)*(10-i),0)%11;return n<2?e===n:e===11-n}function p(t){let e=t.replace(/[\-\s]/g,"");if(!/^\d{16}$/.test(e))return!1;let n=0,s=!1;for(let o=e.length-1;o>=0;o--){let i=parseInt(e[o]);s&&(i*=2,i>9&&(i-=9)),n+=i,s=!s}return n%10===0}function d(t,{strictZero:e="optional"}={}){let n="9\\d{9}",s="";return e===!0?s=`^0${n}$`:e===!1?s=`^${n}$`:s=`^(?:0|\\+98)?${n}$`,new RegExp(s).test(t)}function c(t){let e=t.toUpperCase().replace(/[\-\s]/g,"");if(e.length!==26||!e.startsWith("IR"))return!1;let s=(e.substring(4)+e.substring(0,4)).split("").map(o=>{let i=o.charCodeAt(0);return i>=48&&i<=57?o:(i-55).toString()}).join("");try{return BigInt(s)%BigInt(97)===BigInt(1)}catch{return!1}}function g(t){return/^[1-9]\d{9}$/.test(t)}function f(t){return/^0\d{2}\d{8}$/.test(t)}var u={fa:{melliCode:"\u06A9\u062F \u0645\u0644\u06CC \u0646\u0627\u0645\u0639\u062A\u0628\u0631 \u0627\u0633\u062A",cardNumber:"\u0634\u0645\u0627\u0631\u0647 \u06A9\u0627\u0631\u062A \u0646\u0627\u0645\u0639\u062A\u0628\u0631 \u0627\u0633\u062A",mobile:"\u0634\u0645\u0627\u0631\u0647 \u0645\u0648\u0628\u0627\u06CC\u0644 \u0646\u0627\u0645\u0639\u062A\u0628\u0631 \u0627\u0633\u062A",sheba:"\u0634\u0645\u0627\u0631\u0647 \u0634\u0628\u0627 \u0646\u0627\u0645\u0639\u062A\u0628\u0631 \u0627\u0633\u062A",postalCode:"\u06A9\u062F \u067E\u0633\u062A\u06CC \u0646\u0627\u0645\u0639\u062A\u0628\u0631 \u0627\u0633\u062A",landline:"\u0634\u0645\u0627\u0631\u0647 \u062A\u0644\u0641\u0646 \u062B\u0627\u0628\u062A \u0646\u0627\u0645\u0639\u062A\u0628\u0631 \u0627\u0633\u062A"},en:{melliCode:"Invalid national code",cardNumber:"Invalid card number",mobile:"Invalid mobile number",sheba:"Invalid Sheba (IBAN) number",postalCode:"Invalid postal code",landline:"Invalid landline number"}},r=(t,e)=>{if(e?.message)return e.message;let n=e?.locale||"fa";return u[n][t]};var O=t=>a.string().refine(e=>l(e),{message:r("melliCode",t)}),M=t=>a.string().refine(e=>p(e),{message:r("cardNumber",t)}),h=t=>a.string().refine(e=>d(e,{strictZero:t?.strictZero}),{message:r("mobile",t)}),B=t=>a.string().refine(e=>c(e),{message:r("sheba",t)}),R=t=>a.string().refine(e=>g(e),{message:r("postalCode",t)}),$=t=>a.string().refine(e=>f(e),{message:r("landline",t)});export{p as isCardNumber,d as isIranianMobile,f as isLandline,l as isMelliCode,g as isPostalCode,c as isSheba,M as zCardNumber,h as zIranianMobile,$ as zLandline,O as zMelliCode,R as zPostalCode,B as zSheba};
2
2
  //# sourceMappingURL=index.mjs.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/index.ts","../src/utils.ts","../src/constants.ts"],"sourcesContent":["import { z } from \"zod\";\nimport {\n isMelliCode,\n isCardNumber,\n isIranianMobile,\n isSheba,\n isPostalCode,\n isLandline,\n} from \"./utils\";\nimport { getMessage, BaseOptions } from \"./constants\";\n\nexport const zMelliCode = (options?: BaseOptions) =>\n z.string().refine((val) => isMelliCode(val), {\n message: getMessage(\"melliCode\", options),\n });\n\nexport const zCardNumber = (options?: BaseOptions) =>\n z.string().refine((val) => isCardNumber(val), {\n message: getMessage(\"cardNumber\", options),\n });\n\ninterface MobileOptions extends BaseOptions {\n strictZero?: boolean | \"optional\";\n}\n\nexport const zIranianMobile = (options?: MobileOptions) =>\n z\n .string()\n .refine(\n (val) => isIranianMobile(val, { strictZero: options?.strictZero }),\n {\n message: getMessage(\"mobile\", options),\n }\n );\n\nexport const zSheba = (options?: BaseOptions) =>\n z.string().refine((val) => isSheba(val), {\n message: getMessage(\"sheba\", options),\n });\n\nexport const zPostalCode = (options?: BaseOptions) =>\n z.string().refine((val) => isPostalCode(val), {\n message: getMessage(\"postalCode\", options),\n });\n\nexport const zLandline = (options?: BaseOptions) =>\n z.string().refine((val) => isLandline(val), {\n message: getMessage(\"landline\", options),\n });\n\nexport {\n isMelliCode,\n isCardNumber,\n isIranianMobile,\n isSheba,\n isPostalCode,\n isLandline,\n};\n","export function isMelliCode(code: string): boolean {\n if (!/^\\d{10}$/.test(code)) return false;\n\n const check = parseInt(code[9]);\n if (/^(\\d)\\1+$/.test(code)) return false;\n\n const sum =\n code\n .substring(0, 9)\n .split(\"\")\n .reduce((acc, x, i) => acc + parseInt(x) * (10 - i), 0) % 11;\n\n return sum < 2 ? check === sum : check === 11 - sum;\n}\n\nexport function isCardNumber(code: string): boolean {\n const sanitized = code.replace(/[\\-\\s]/g, \"\");\n if (!/^\\d{16}$/.test(sanitized)) return false;\n\n let sum = 0;\n let shouldDouble = false;\n\n for (let i = sanitized.length - 1; i >= 0; i--) {\n let digit = parseInt(sanitized[i]);\n\n if (shouldDouble) {\n digit *= 2;\n if (digit > 9) digit -= 9;\n }\n\n sum += digit;\n shouldDouble = !shouldDouble;\n }\n\n return sum % 10 === 0;\n}\n\ninterface MobileValidationOptions {\n strictZero?: boolean | \"optional\";\n}\n\nexport function isIranianMobile(\n mobile: string,\n { strictZero = \"optional\" }: MobileValidationOptions = {}\n): boolean {\n const corePattern = \"9\\\\d{9}\";\n let pattern = \"\";\n\n if (strictZero === true) {\n pattern = `^0${corePattern}$`;\n } else if (strictZero === false) {\n pattern = `^${corePattern}$`;\n } else {\n pattern = `^(?:0|\\\\+98)?${corePattern}$`;\n }\n\n return new RegExp(pattern).test(mobile);\n}\n\nexport function isSheba(code: string): boolean {\n const iban = code.toUpperCase().replace(/[\\-\\s]/g, \"\");\n\n if (iban.length !== 26) return false;\n if (!iban.startsWith(\"IR\")) return false;\n\n const newStr = iban.substring(4) + \"1827\" + iban.substring(2, 4);\n\n const remainder = Array.from(newStr)\n .map((c) => parseInt(c, 36))\n .reduce((remainder, value) => {\n const v = value < 10 ? value : value;\n return (Number(remainder + \"\" + v) % 97).toString();\n }, \"\");\n\n return parseInt(remainder) === 1;\n}\n\nexport function isPostalCode(code: string): boolean {\n if (!/^\\d{10}$/.test(code)) return false;\n if (code.startsWith(\"0\")) return false;\n return true;\n}\n\nexport function isLandline(code: string): boolean {\n return /^0\\d{2}\\d{8}$/.test(code);\n}\n","export const ERROR_MESSAGES = {\n fa: {\n melliCode: \"کد ملی نامعتبر است\",\n cardNumber: \"شماره کارت نامعتبر است\",\n mobile: \"شماره موبایل نامعتبر است\",\n sheba: \"شماره شبا نامعتبر است\",\n postalCode: \"کد پستی نامعتبر است\",\n landline: \"شماره تلفن ثابت نامعتبر است\",\n },\n en: {\n melliCode: \"Invalid national code\",\n cardNumber: \"Invalid card number\",\n mobile: \"Invalid mobile number\",\n sheba: \"Invalid Sheba (IBAN) number\",\n postalCode: \"Invalid postal code\",\n landline: \"Invalid landline number\",\n },\n} as const;\n\nexport type Language = keyof typeof ERROR_MESSAGES;\n\nexport interface BaseOptions {\n message?: string;\n locale?: Language;\n}\n\nexport const getMessage = (\n key: keyof (typeof ERROR_MESSAGES)[\"fa\"],\n options?: BaseOptions\n): string => {\n if (options?.message) return options.message;\n const lang = options?.locale || \"fa\";\n return ERROR_MESSAGES[lang][key];\n};\n"],"mappings":"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","names":["z","isMelliCode","code","check","sum","acc","x","i","isCardNumber","sanitized","shouldDouble","digit","isIranianMobile","mobile","strictZero","corePattern","pattern","isSheba","iban","newStr","remainder","c","value","v","isPostalCode","isLandline","ERROR_MESSAGES","getMessage","key","options","lang","zMelliCode","options","z","val","isMelliCode","getMessage","zCardNumber","isCardNumber","zIranianMobile","isIranianMobile","zSheba","isSheba","zPostalCode","isPostalCode","zLandline","isLandline"]}
1
+ {"version":3,"sources":["../src/index.ts","../src/utils.ts","../src/constants.ts"],"sourcesContent":["import { z } from \"zod\";\nimport {\n isMelliCode,\n isCardNumber,\n isIranianMobile,\n isSheba,\n isPostalCode,\n isLandline,\n} from \"./utils\";\nimport { getMessage, BaseOptions } from \"./constants\";\n\nexport const zMelliCode = (options?: BaseOptions) =>\n z.string().refine((val) => isMelliCode(val), {\n message: getMessage(\"melliCode\", options),\n });\n\nexport const zCardNumber = (options?: BaseOptions) =>\n z.string().refine((val) => isCardNumber(val), {\n message: getMessage(\"cardNumber\", options),\n });\n\ninterface MobileOptions extends BaseOptions {\n strictZero?: boolean | \"optional\";\n}\n\nexport const zIranianMobile = (options?: MobileOptions) =>\n z\n .string()\n .refine(\n (val) => isIranianMobile(val, { strictZero: options?.strictZero }),\n {\n message: getMessage(\"mobile\", options),\n }\n );\n\nexport const zSheba = (options?: BaseOptions) =>\n z.string().refine((val) => isSheba(val), {\n message: getMessage(\"sheba\", options),\n });\n\nexport const zPostalCode = (options?: BaseOptions) =>\n z.string().refine((val) => isPostalCode(val), {\n message: getMessage(\"postalCode\", options),\n });\n\nexport const zLandline = (options?: BaseOptions) =>\n z.string().refine((val) => isLandline(val), {\n message: getMessage(\"landline\", options),\n });\n\nexport {\n isMelliCode,\n isCardNumber,\n isIranianMobile,\n isSheba,\n isPostalCode,\n isLandline,\n};\n","export function isMelliCode(code: string): boolean {\n if (!/^\\d{10}$/.test(code)) return false;\n if (/^(\\d)\\1+$/.test(code)) return false;\n\n const check = parseInt(code[9]);\n const sum =\n code\n .substring(0, 9)\n .split(\"\")\n .reduce((acc, x, i) => acc + parseInt(x) * (10 - i), 0) % 11;\n\n return sum < 2 ? check === sum : check === 11 - sum;\n}\n\nexport function isCardNumber(code: string): boolean {\n const sanitized = code.replace(/[\\-\\s]/g, \"\");\n if (!/^\\d{16}$/.test(sanitized)) return false;\n\n let sum = 0;\n let shouldDouble = false;\n\n for (let i = sanitized.length - 1; i >= 0; i--) {\n let digit = parseInt(sanitized[i]);\n\n if (shouldDouble) {\n digit *= 2;\n if (digit > 9) digit -= 9;\n }\n\n sum += digit;\n shouldDouble = !shouldDouble;\n }\n\n return sum % 10 === 0;\n}\n\ninterface MobileValidationOptions {\n strictZero?: boolean | \"optional\";\n}\n\nexport function isIranianMobile(\n mobile: string,\n { strictZero = \"optional\" }: MobileValidationOptions = {}\n): boolean {\n const corePattern = \"9\\\\d{9}\";\n let pattern = \"\";\n\n if (strictZero === true) {\n pattern = `^0${corePattern}$`;\n } else if (strictZero === false) {\n pattern = `^${corePattern}$`;\n } else {\n pattern = `^(?:0|\\\\+98)?${corePattern}$`;\n }\n\n return new RegExp(pattern).test(mobile);\n}\n\nexport function isSheba(code: string): boolean {\n const iban = code.toUpperCase().replace(/[\\-\\s]/g, \"\");\n\n if (iban.length !== 26 || !iban.startsWith(\"IR\")) return false;\n\n const newStr = iban.substring(4) + iban.substring(0, 4);\n\n const numericString = newStr\n .split(\"\")\n .map((char) => {\n const code = char.charCodeAt(0);\n return code >= 48 && code <= 57 ? char : (code - 55).toString();\n })\n .join(\"\");\n\n try {\n const remainder = BigInt(numericString) % BigInt(97);\n return remainder === BigInt(1);\n } catch {\n return false;\n }\n}\n\nexport function isPostalCode(code: string): boolean {\n return /^[1-9]\\d{9}$/.test(code);\n}\n\nexport function isLandline(code: string): boolean {\n return /^0\\d{2}\\d{8}$/.test(code);\n}\n","export const ERROR_MESSAGES = {\n fa: {\n melliCode: \"کد ملی نامعتبر است\",\n cardNumber: \"شماره کارت نامعتبر است\",\n mobile: \"شماره موبایل نامعتبر است\",\n sheba: \"شماره شبا نامعتبر است\",\n postalCode: \"کد پستی نامعتبر است\",\n landline: \"شماره تلفن ثابت نامعتبر است\",\n },\n en: {\n melliCode: \"Invalid national code\",\n cardNumber: \"Invalid card number\",\n mobile: \"Invalid mobile number\",\n sheba: \"Invalid Sheba (IBAN) number\",\n postalCode: \"Invalid postal code\",\n landline: \"Invalid landline number\",\n },\n} as const;\n\nexport type Language = keyof typeof ERROR_MESSAGES;\n\nexport interface BaseOptions {\n message?: string;\n locale?: Language;\n}\n\nexport const getMessage = (\n key: keyof (typeof ERROR_MESSAGES)[\"fa\"],\n options?: BaseOptions\n): string => {\n if (options?.message) return options.message;\n const lang = options?.locale || \"fa\";\n return ERROR_MESSAGES[lang][key];\n};\n"],"mappings":"AAAA,OAAS,KAAAA,MAAS,MCAX,SAASC,EAAYC,EAAuB,CAEjD,GADI,CAAC,WAAW,KAAKA,CAAI,GACrB,YAAY,KAAKA,CAAI,EAAG,MAAO,GAEnC,IAAMC,EAAQ,SAASD,EAAK,CAAC,CAAC,EACxBE,EACJF,EACG,UAAU,EAAG,CAAC,EACd,MAAM,EAAE,EACR,OAAO,CAACG,EAAKC,EAAG,IAAMD,EAAM,SAASC,CAAC,GAAK,GAAK,GAAI,CAAC,EAAI,GAE9D,OAAOF,EAAM,EAAID,IAAUC,EAAMD,IAAU,GAAKC,CAClD,CAEO,SAASG,EAAaL,EAAuB,CAClD,IAAMM,EAAYN,EAAK,QAAQ,UAAW,EAAE,EAC5C,GAAI,CAAC,WAAW,KAAKM,CAAS,EAAG,MAAO,GAExC,IAAIJ,EAAM,EACNK,EAAe,GAEnB,QAASC,EAAIF,EAAU,OAAS,EAAGE,GAAK,EAAGA,IAAK,CAC9C,IAAIC,EAAQ,SAASH,EAAUE,CAAC,CAAC,EAE7BD,IACFE,GAAS,EACLA,EAAQ,IAAGA,GAAS,IAG1BP,GAAOO,EACPF,EAAe,CAACA,CAClB,CAEA,OAAOL,EAAM,KAAO,CACtB,CAMO,SAASQ,EACdC,EACA,CAAE,WAAAC,EAAa,UAAW,EAA6B,CAAC,EAC/C,CACT,IAAMC,EAAc,UAChBC,EAAU,GAEd,OAAIF,IAAe,GACjBE,EAAU,KAAKD,CAAW,IACjBD,IAAe,GACxBE,EAAU,IAAID,CAAW,IAEzBC,EAAU,gBAAgBD,CAAW,IAGhC,IAAI,OAAOC,CAAO,EAAE,KAAKH,CAAM,CACxC,CAEO,SAASI,EAAQf,EAAuB,CAC7C,IAAMgB,EAAOhB,EAAK,YAAY,EAAE,QAAQ,UAAW,EAAE,EAErD,GAAIgB,EAAK,SAAW,IAAM,CAACA,EAAK,WAAW,IAAI,EAAG,MAAO,GAIzD,IAAMC,GAFSD,EAAK,UAAU,CAAC,EAAIA,EAAK,UAAU,EAAG,CAAC,GAGnD,MAAM,EAAE,EACR,IAAKE,GAAS,CACb,IAAMlB,EAAOkB,EAAK,WAAW,CAAC,EAC9B,OAAOlB,GAAQ,IAAMA,GAAQ,GAAKkB,GAAQlB,EAAO,IAAI,SAAS,CAChE,CAAC,EACA,KAAK,EAAE,EAEV,GAAI,CAEF,OADkB,OAAOiB,CAAa,EAAI,OAAO,EAAE,IAC9B,OAAO,CAAC,CAC/B,MAAQ,CACN,MAAO,EACT,CACF,CAEO,SAASE,EAAanB,EAAuB,CAClD,MAAO,eAAe,KAAKA,CAAI,CACjC,CAEO,SAASoB,EAAWpB,EAAuB,CAChD,MAAO,gBAAgB,KAAKA,CAAI,CAClC,CCvFO,IAAMqB,EAAiB,CAC5B,GAAI,CACF,UAAW,gGACX,WAAY,wHACZ,OAAQ,oIACR,MAAO,kHACP,WAAY,sGACZ,SAAU,gJACZ,EACA,GAAI,CACF,UAAW,wBACX,WAAY,sBACZ,OAAQ,wBACR,MAAO,8BACP,WAAY,sBACZ,SAAU,yBACZ,CACF,EASaC,EAAa,CACxBC,EACAC,IACW,CACX,GAAIA,GAAS,QAAS,OAAOA,EAAQ,QACrC,IAAMC,EAAOD,GAAS,QAAU,KAChC,OAAOH,EAAeI,CAAI,EAAEF,CAAG,CACjC,EFtBO,IAAMG,EAAcC,GACzBC,EAAE,OAAO,EAAE,OAAQC,GAAQC,EAAYD,CAAG,EAAG,CAC3C,QAASE,EAAW,YAAaJ,CAAO,CAC1C,CAAC,EAEUK,EAAeL,GAC1BC,EAAE,OAAO,EAAE,OAAQC,GAAQI,EAAaJ,CAAG,EAAG,CAC5C,QAASE,EAAW,aAAcJ,CAAO,CAC3C,CAAC,EAMUO,EAAkBP,GAC7BC,EACG,OAAO,EACP,OACEC,GAAQM,EAAgBN,EAAK,CAAE,WAAYF,GAAS,UAAW,CAAC,EACjE,CACE,QAASI,EAAW,SAAUJ,CAAO,CACvC,CACF,EAESS,EAAUT,GACrBC,EAAE,OAAO,EAAE,OAAQC,GAAQQ,EAAQR,CAAG,EAAG,CACvC,QAASE,EAAW,QAASJ,CAAO,CACtC,CAAC,EAEUW,EAAeX,GAC1BC,EAAE,OAAO,EAAE,OAAQC,GAAQU,EAAaV,CAAG,EAAG,CAC5C,QAASE,EAAW,aAAcJ,CAAO,CAC3C,CAAC,EAEUa,EAAab,GACxBC,EAAE,OAAO,EAAE,OAAQC,GAAQY,EAAWZ,CAAG,EAAG,CAC1C,QAASE,EAAW,WAAYJ,CAAO,CACzC,CAAC","names":["z","isMelliCode","code","check","sum","acc","x","isCardNumber","sanitized","shouldDouble","i","digit","isIranianMobile","mobile","strictZero","corePattern","pattern","isSheba","iban","numericString","char","isPostalCode","isLandline","ERROR_MESSAGES","getMessage","key","options","lang","zMelliCode","options","z","val","isMelliCode","getMessage","zCardNumber","isCardNumber","zIranianMobile","isIranianMobile","zSheba","isSheba","zPostalCode","isPostalCode","zLandline","isLandline"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "zod-ir",
3
- "version": "1.1.0",
3
+ "version": "1.1.1",
4
4
  "description": "Essential Zod validators for Iranian specific data (National Code, Card Number, Mobile)",
5
5
  "main": "./dist/index.js",
6
6
  "module": "./dist/index.mjs",