DEV Community

Cover image for Mastering Iranian Data Validation in Zod: From Regex to Enterprise Metadata
Reza Kheradmandi
Reza Kheradmandi

Posted on

Mastering Iranian Data Validation in Zod: From Regex to Enterprise Metadata

If you are building a React, Next.js, or Node.js application for the Iranian market, you have definitely faced this challenge: Validating local data structures.

Things like National Code (Code Melli), Bank Cards, IBAN (Sheba), and Postal Codes follow complex algorithms (Luhn, ISO 7064, etc.).

Usually, developers handle this in two ways:

  1. Copy-pasting complex Regex patterns (Error-prone).
  2. Using heavy legacy libraries and manually connecting them to Zod using refine.

Neither is ideal for a modern TypeScript stack. That's why I built zod-ir, which is now officially part of the Zod Ecosystem.

Why zod-ir? (It's not just validation)

In the latest release (v1.5.4), zod-ir shifted focus from simple validation (true/false) to Smart Data Extraction.

Imagine a form where the user enters a landline number, and you automatically detect their Province and City. Or they enter a card number, and you instantly show their Bank Logo.

1. Installation

It has zero dependencies and works as a peer dependency to Zod.

npm install zod zod-ir
Enter fullscreen mode Exit fullscreen mode

2. The "Smart" Validation

Here is a real-world example of a user registration schema. Notice how clean the code is:

import { z } from "zod";
import { 
  zMelliCode, 
  zIranianMobile, 
  zLandline, 
  zCardNumber,
  getLandlineInfo 
} from "zod-ir";

const UserSchema = z.object({
  // Validates National Code algorithm
  nationalId: zMelliCode({ message: "Invalid National Code" }),

  // Validates mobile prefixes (09xx)
  mobile: zIranianMobile(),

  // Validates Landline AND we can extract city later
  phone: zLandline(),

  // Validates Card Number (Luhn)
  card: zCardNumber(),
});
Enter fullscreen mode Exit fullscreen mode

3. Extracting Metadata (The Cool Part)

Validation is boring. Let's get data!

Feature A: Auto-detect City from Landline Don't ask users for their city if they provided a phone number.

import { getLandlineInfo } from "zod-ir";

const info = getLandlineInfo("02122334455");

console.log(info);
/* Output:
{
  province: "Tehran",
  city: "Tehran",
  province_fa: "تهران",
  city_fa: "تهران"
}
*/
Enter fullscreen mode Exit fullscreen mode

Feature B: Bank Information Get the bank name, color, and logo from a card number.

import { getBankInfo } from "zod-ir";

const bank = getBankInfo("6219861012345678");
// Returns: { name: "Saman", color: "#46a0e6", logo: "..." }
Enter fullscreen mode Exit fullscreen mode

4. Enterprise Ready?

Yes. I designed zod-ir to address common enterprise concerns:

Standalone Usage: You don't HAVE to use Zod. All validators (like isMelliCode) are exported as pure functions for backend use.

Tree-Shakable: If you only import isIranianMobile, the heavy bank database won't be included in your bundle.

Type-Safe: First-class TypeScript support.

Conclusion
If you are using Zod, stop writing manual regex for Iranian data. zod-ir gives you validation, transformation, and metadata extraction in one lightweight package.

Give it a try and let me know what you think!

🔗 Github: https://github.com/Reza-kh80/zod-ir

Top comments (0)