npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

zod-ir

v1.6.6

Published

Zod validators for Iranian data types such as Melli/national code, sheba, phone, passport, etc.

Readme

📖 Read the Full Documentation on daxra.ir

Why zod-ir? 🚀

Building forms for Iranian applications often involves validating specific local data structures like national codes, bank cards, and Sheba numbers. zod-ir seamlessly integrates these validations into Zod, while also offering powerful Data Extraction tools and a superior Developer Experience.

Key Features ✨

  • 🧠 Smart Extraction: go beyound validation and extract metadata. (get bank name from card number and city from landline/postal code).
  • 🛠 Standalone & Reusable: Use validators either inside Zod schemas or as standalone utility functions.
  • Zero Dependencies: No heavy dependencies— lightweight and tree-shakeable.
  • 🔗 Compatibility: Fully compatible with your existing Zod version (v3 and v4).
  • 🧪 Battle-Tested: 100% test coverage for critical algorithms (national code, IBAN, etc.).

Feature Highlights 🌟

  • Smart Financial: auto-detects card number vs. Sheba (IBAN) and returns the corresponding bank info and logo.
  • Jalali Date: validates Persian dates with precise Leap Year (Kabisa) calculation.
  • Crypto Support: native validation for TRC20, ERC20, and Bitcoin.
  • Vehicle: validates license plates and detects province/city.
  • Contact: smartly detect the phone number operator (MCI, Irancell), landline, and postal code (smart city detection).

Installation 📦

npm install zod zod-ir
# or
pnpm add zod zod-ir
# or
yarn add zod zod-ir

Usage: Standalone Mode (Utilities) ⚒️

You don't need to use Zod! zod-ir exports all validation logic as pure functions—perfect for backend utilities or non-form logic.

import { isMelliCode, getBankInfo, getLandlineInfo } from 'zod-ir';

// Validate national code anywhere
if (isMelliCode('0023456789')) {
  console.log('Valid user.');
}

// Extract details from bank card number
const bank = getBankInfo('6219861012345678');
console.log(bank.name); // "Saman"
console.log(bank.color); // "#46a0e6"

// Extract location from landline phone number
const location = getLandlineInfo('02122334455');
console.log(location.province_fa); // "تهران"

Usage: Zod Schema Mode 💡

  1. Smart Contact and Address Validate landlines and postal codes, and automatically extract province/city in both Persian and English.
import * as z from 'zod';
import { zLandline, zPostalCode, getLandlineInfo, getPostalCodeInfo } from 'zod-ir';

const ValidationSchema = z.object({
  phone: zLandline({ message: 'Invalid landline number.' }),
  zip: zPostalCode(),
});

const phoneInfo = getLandlineInfo('02122334455');
console.log(phoneInfo);
/*
  {
    province: "Tehran",
    city: "Tehran",
    province_fa: "تهران",
    city_fa: "تهران"
  }
*/

// Extract metadata from postal code (smart range matching)
const zipInfo = getPostalCodeInfo('8391853612');
/*
  {
    province: { name: "اصفهان", slug: "Isfahan" },
    city: { name_fa: "نائین", name_en: "Naein" }
  }
*/
  1. Smart Financial Validation Don't ask users for either card number or Sheba—use zFinancial to accept both!
import * as z from 'zod';
import { zFinancial, getFinancialInfo } from 'zod-ir';

const ValidationSchema = z.object({
  destination: zFinancial({ message: 'Invalid card number or Sheba.' }),
});

// Extract metadata (bank name, Logo, type)
const info = getFinancialInfo('6037991155667788');
// OR
const infoSheba = getFinancialInfo('IR120170000000123456789012');

console.log(info);
/*
  {
    type: "card", // or "sheba"
    isValid: true,
    bank: {
      name: "Melli",
      label: "ملی",
      color: "#EF3F3E",
      logo: "https://.../melli.svg",
      formatted: "6037-9911-..."
    }
  }
*/
  1. Crypto Wallet Validation Perfect for Fintech and exchange apps. Supports TRC20 (USDT), ERC20, and BTC.
import { zCrypto, getCryptoInfo } from 'zod-ir';

const ValidationSchema = z.object({
  // Accept any valid wallet (TRX, ETH, BTC)
  anyWallet: zCrypto(),

  // Strict: only accept Tether (TRC20)
  usdtWallet: zCrypto({
    ticker: 'TRX',
    message: 'Only TRC20 addresses are allowed.',
  }),
});

const details = getCryptoInfo('TR7NHqjeKQxGTCi8q8ZY4pL8otSzgjLj6t');
console.log(details);
/*
  {
    ticker: "TRX",
    network: "TRC20",
    isValid: true
  }
*/
  1. Jalali Date Validation Validates Persian dates mathematically, checking days in each month and leap years.
import { zJalaliDate } from 'zod-ir';

const ValidationSchema = z.object({
  birthDate: zJalaliDate({ message: 'Invalid date.' }),
});

// ✅ Valid (Leap Year)
ValidationSchema.parse({ birthDate: '1403/12/30' });

// ❌ Invalid (1402 is not a Leap Year)
ValidationSchema.parse({ birthDate: '1402/12/30' });
  1. Comprehensive Form Example A full registration form handling Auto-fix (Persian digits), Mobile, and National Code.
import * as z from 'zod';
import {
  zMelliCode,
  zIranianMobile,
  zCardNumber,
  zBillId,
  zPaymentId,
  zPlateNumber,
  preprocessNumber, // Converts "۱۲۳" to 123
} from 'zod-ir';

const UserSchema = z.object({
  // Auto-convert Persian digits before validation
  nationalCode: preprocessNumber(zMelliCode()),

  mobile: zIranianMobile({ strictZero: true }),
  card: zCardNumber(),
  plate: zPlateNumber(), // e.g., "12م345-11"

  // Utility Bill
  billId: zBillId(),
  paymentId: zPaymentId(),
});
  1. Smart Currency ₿ Automatically validates, parses, and formats currency input. It handles Persian text, numbers, and formatted strings (mixed).
import { zToman, transformToCurrency, numberToText } from 'zod-ir';

const ValidationSchema = z.object({
  // Accepts inputs such as "2.5 میلیون" ,"2,500,000" ,"دو میلیون و پانصد"
  price: zToman({
    min: 1000,
    max: 50_000_000,
    message: 'Amount must be between 1,000 and 50 Million Tomans.',
  }),
});

// --- Utility Functions for UI ---

// Convert text/mixed to number (useful for database storage)
console.log(transformToCurrency('2 میلیون و پانصد')); // 2500000
console.log(transformToCurrency('سی صد')); // 300 (Auto-fixes typos)

// Convert number to Persian text (useful for UI display)
console.log(numberToText(2500000)); // "دو میلیون و پانصد هزار"

Metadata Helpers 🛠️

zod-ir isn't just for validation—it also provides rich metadata for your UI. | Function | Return Type | Description | | :------------------------ | :--------------------------- | ------------------------------------------------------ | | getFinancialInfo(val) | { type, bank, isValid } | Smart! Detects card or Sheba, returns bank logo/color. | | getBankInfo(card) | { name, label, logo, ... } | Details for card numbers. | | getCryptoInfo(addr) | { ticker, network } | Detects TRC20, ERC20, and BTC networks. | | getMobileOperator(num) | { name, label, logo } | Returns the operator (MCI, Irancell) and the Logo. | | getBillInfo(id, payId) | { type, amount, ... } | Bill type (water, gas), amount calculation, validity. | | getPlateInfo(plate) | { province, city } | Province and city of the license plate. | | getJalaliDateInfo(date) | { year, month, isLeap } | Deconstructs Jalali date and checks for Leap Years. | | getLandlineInfo(num) | { province, city, ... } | Returns province/city (FA & EN) for landlines. | | getPostalCodeInfo(code) | { province, city } | Returns province/city based on the postal code. |

API Reference 📚

Identity & Contact | Validator | Description | | :--------------- | :------------------------------- | | zMelliCode | National code (Melli code) | | zShenaseMelli | Legal person ID (company) | | zPassport | Iranian passport | | zIranianMobile | Mobile number (09xx, +989xx) | | zPostalCode | 10-digit postal code | | zLandline | Landline phone number (021xx...) |

Financial & Assets | Validator | Description | | :------------- | :----------------------------------------- | | zFinancial | Smart input (card number or Sheba) | | zCardNumber | Bank card number (16 digits) | | zSheba | IBAN (Sheba) | | zCrypto | Crypto wallet (TRX, ETH, BTC) | | zBillId | Utility bill ID | | zPaymentId | Utility payment ID | | zPlateNumber | Vehicle license plate | | zJalaliDate | Persian date (YYYY/MM/DD) | | zToman | Automatically validates the currency input |

Versining Policy 🏷️

This project adheres to The Semantic Versioning Standard.

Contributing 🤝🏻

Any form of contribution is always appreciated! Please refer to the CONTRIBUTING.md file.

Credits 🙏🏻

Bank and operator logos are courtesy of Zegond's Logos Project.

Funding 🌱

zod-ir is an open-source project and free to use. If it saved you some time and you'd like to say thanks, you can support its development via crypto currency transactions. It's completely optional and highly appreciated!

  • USDT (TRC20) / TRX: TWtnFa4xpvH9BvciSzw4hqXUDCibWhcYxX
  • Bitcoin: bc1qf2ry7mpnvncwapgu0al3wkxm4jxecac3s3pmf0

License 📃

MIT License © 2026-PRESENT — Reza Kheradmandi