zod-ir
v1.4.0
Published
Essential Zod validators for Iranian specific data (National Code, Card Number, Mobile)
Downloads
1,449
Maintainers
Readme
Features ✨
- ✅ National Code: Validates using the official checksum algorithm.
- 🏢 Shenase Melli: Validates Legal Person ID (Company ID).
- 💳 Bank Card: Validates 16-digit card numbers (Luhn algorithm).
- 🚗 License Plate: Validates Iranian car plates and Detects City/Province.
- 🧾 Bill & Payment ID: Validates Utility Bills (Water, Electricity, Gas, etc.) and Calculates Amount.
- 📱 Mobile Number: Validates
09xx,+989xx,9xx. - 🏦 Sheba (IBAN): Validates structure and checksum (ISO 7064).
- ✈️ Passport: Validates Iranian Passport numbers.
- 📮 Postal Code: Validates 10-digit Iranian postal codes.
- ☎️ Landline: Validates fixed line numbers with area codes.
- 🔄 Auto-fix Digits: Automatically converts Persian/Arabic digits and characters (ي, ك) to standard English.
- 🎨 Metadata Extraction: Extract Bank Name/Color/Logo, Operator, Bill Type, and Plate Location.
- 🌍 Bilingual: Built-in error messages in Persian and English.
Installation 📦
npm install zod zod-ir
# or
pnpm add zod zod-ir
# or
yarn add zod zod-irUsage 🚀
- Basic Validation & Auto-Fix This example shows how to validate a form and automatically convert Persian digits (e.g., ۰۹۱۲) to English.
import { z } from "zod";
import {
zMelliCode,
zIranianMobile,
zCardNumber,
zBillId,
zPaymentId,
zPlateNumber,
preprocessNumber,
} from "zod-ir";
const UserSchema = z.object({
// 1. National Code with Auto-Fix (Converts ۱۲۳ -> 123)
nationalCode: preprocessNumber(zMelliCode()),
// 2. Mobile (Strict Mode: Must start with 0)
mobile: zIranianMobile({ strictZero: true }),
// 3. Bank Card
card: zCardNumber(),
// 4. Car Plate (e.g., 12B345-11 or ۱۲ب۳۴۵-۱۱)
plate: zPlateNumber(),
// 5. Bill & Payment ID
billId: zBillId(),
paymentId: zPaymentId(),
});- Extracting Metadata (New ✨) You can extract useful information like Bank Name, Color, Bill Type, Amount, or Plate Location.
import {
getBankInfo,
getMobileOperator,
getBillInfo,
getPlateInfo,
} from "zod-ir";
// 🏦 Bank Info
const bank = getBankInfo("6037991155667788");
if (bank) {
console.log(bank.name); // "Melli"
console.log(bank.label); // "ملی"
console.log(bank.color); // "#EF3F3E" (Great for UI backgrounds!)
console.log(bank.logo); // URL to bank logo
}
// 🚗 Plate Info
const plate = getPlateInfo("64م322-23");
if (plate) {
console.log(plate.province); // "اصفهان"
console.log(plate.city); // "نایین"
}
// 🧾 Bill Info (Water, Electricity, Gas...)
// Returns bill type, validity, and calculates amount from payment ID
const bill = getBillInfo("9006117002129", "60240335");
if (bill) {
console.log(bill.type.label); // "برق"
console.log(bill.formattedAmount); // "602,000" (Rials)
console.log(bill.isValid); // true
}- Usage with React Hook Form 📋
import { useForm } from "react-hook-form";
import { zodResolver } from "@hookform/resolvers/zod";
import { z } from "zod";
import { zMelliCode, preprocessNumber } from "zod-ir";
const schema = z.object({
// Automatically fixes Persian digits typed by user
nationalId: preprocessNumber(zMelliCode({ message: "کد ملی صحیح نیست" })),
});
export default function MyForm() {
const {
register,
handleSubmit,
formState: { errors },
} = useForm({
resolver: zodResolver(schema),
});
return (
<form onSubmit={handleSubmit((d) => console.log(d))}>
<input
{...register("nationalId")}
placeholder="کد ملی (حتی فارسی)"
dir="auto"
/>
<p style={{ color: "red" }}>{errors.nationalId?.message}</p>
<button type="submit">Submit</button>
</form>
);
}API Reference 📚
| Validator | Description |
| :----------------- | :----------------------------------------------------------------- |
| zMelliCode | Validates Iranian National Code (Melli Code). |
| zShenaseMelli | Validates Legal Person ID (Company ID). |
| zCardNumber | Validates 16-digit bank card numbers (Luhn). |
| zIranianMobile | Validates Iranian mobile numbers. |
| zSheba | Validates IBAN (Sheba) structure and checksum. |
| zPassport | Validates Iranian Passport numbers. |
| zPostalCode | Validates 10-digit Iranian postal codes. |
| zLandline | Validates landline phone numbers with area codes. |
| zBillId | Validates Bill ID (Shenase Ghabz). |
| zPaymentId | Validates Payment ID (Shenase Pardakht). |
| zPlateNumber | Validates Vehicle License Plate. |
| preprocessNumber | Utility: Wraps any validator to convert Persian digits to English. |
Options Interface
All validators accept an optional configuration object to customize behavior.
| Name | Type | Description |
| :----------- | :-------------------- | :--------------------------------------------------------- |
| message | string | Custom error message to display when validation fails. |
| locale | "fa", "en" | Language for the default error message (defaults to "fa"). |
| strictZero | boolean, optional | (Mobile Only) If true, input must start with 0. |
Metadata Helpers (New)
| Function | Return Type | Description |
| :--------------------------- | :------------------------------------------- | ------------------------------------------------------------------------------ |
| getBankInfo(card) | { name, label, color, logo, formatted } | Returns bank details including Logo URL from card number.number. |
| getMobileOperator(mobile) | { name, label, logo } | Returns operator (MCI, Irancell...) including Logo URL from mobile number. |
| getBillInfo(billId, payId) | { type, amount, formattedAmount, isValid } | Bill type (Water/Gas...), calculates amount. number. |
| getPlateInfo(plate) | { province, city } | Province and City of the plate. number. |
| verifyAndNormalize(str) | string | Converts Persian/Arabic digits & chars (ي, ك) to standard English. |
Contributing
Contributions are welcome! Please open an issue or submit a pull request for any improvements or bug fixes.
This project uses PNPM. To get started, clone the repo and run:
pnpm installCredits 🙏
- Bank and Operator logos are courtesy of Zegond's Logos Project.
License
MIT
