Options
Every validator takes an optional second argument, options, that controls how the input is normalised before checking. The same options work in JavaScript, Python and Rust, and in the playground’s options panel.
The options object
Section titled “The options object”{ strict: true, // default: true allowSpaces: false, // default: false allowHyphens: false, // default: false normalizeCountryCode: true, // default: true (mobile only) uppercase: true, // default: true (letter IDs only)}| Option | Default | What it does |
|---|---|---|
strict |
true |
true = strict mode, false = lenient mode (see below) |
allowSpaces |
false |
Strip all spaces before validating |
allowHyphens |
false |
Strip all hyphens before validating |
normalizeCountryCode |
true |
Mobile only: strip +91, 91 or 0 prefix before checking |
uppercase |
true |
Letter IDs only (PAN, GSTIN, IFSC, TAN, CIN, LLPIN, EPIC, vehicle): uppercase the input first |
Strict mode (default)
Section titled “Strict mode (default)”In strict mode the input must be (nearly) exactly as specified. The only normalisation that always happens:
- Letter IDs are uppercased (
aaapl1234c→AAAPL1234C). - Display separators that are part of the convention are accepted: spaces in Aadhaar (
2345 6789 0124), spaces/dashes in mobile and PIN codes, the hyphen in LLPIN (AAA-1234), and spaces/hyphens in vehicle plates (DL 01 AB 1234).
Anything else is rejected with INVALID_FORMAT:
import { validatePan } from 'indycheck';
validatePan('AAAPL 1234C');// { ok: false, code: 'INVALID_FORMAT',// reason_en: 'Spaces are not allowed in strict mode — set allowSpaces: true or use lenient mode (strict: false).' }
validatePan('AAAPL-1234C');// { ok: false, code: 'INVALID_FORMAT',// reason_en: 'Hyphens are not allowed in strict mode — …' }Use strict mode for APIs and stored data — it guarantees the value you accept is already canonical.
Lenient mode
Section titled “Lenient mode”Set strict: false and every normalisation turns on at once: spaces and hyphens are stripped, letter IDs are uppercased, and +91 is stripped from mobiles. It is a shortcut for { allowSpaces: true, allowHyphens: true, normalizeCountryCode: true, uppercase: true }.
validatePan('AAAPL-1234C', { strict: false }); // ok: truevalidatePan('aaapl1234c', { strict: false }); // ok: truevalidateGstin('27AAAPL1234C1Z E', { strict: false }); // ok: trueUse lenient mode for user-typed form input — people paste values with spaces, dashes and lowercase letters. Always store the returned normalized value, not the raw input.
Individual flags
Section titled “Individual flags”You can also turn flags on one at a time in strict mode:
// Spaces yes, hyphens still no:validatePan('AAAPL 1234C', { allowSpaces: true }); // ok: truevalidatePan('AAAPL-1234C', { allowSpaces: true }); // ok: false — INVALID_FORMAT
// Don't uppercase — lowercase input must now fail:validatePan('aaapl1234c', { uppercase: false }); // ok: false — INVALID_FORMATvalidatePan('AAAPL1234C', { uppercase: false }); // ok: true
// Don't strip the country code — the bare 10-digit number is required:validateMobile('+91 98765 43210', { normalizeCountryCode: false });// { ok: false, code: 'INVALID_FORMAT' }validateMobile('9876543210', { normalizeCountryCode: false }); // ok: trueWhich options affect which validator?
Section titled “Which options affect which validator?”| Validator | uppercase |
allowSpaces / allowHyphens |
normalizeCountryCode |
|---|---|---|---|
| PAN | ✅ | ✅ | — |
| Aadhaar | — | Always allowed | — |
| GSTIN | ✅ | ✅ | — |
| IFSC | ✅ | ✅ | — |
| UPI ID | — (case-sensitive, never changed) | ✅ in lenient mode | — |
| Mobile | — | Always allowed | ✅ |
| PIN code | — | Always allowed | — |
| TAN | ✅ | ✅ | — |
| CIN | ✅ | ✅ | — |
| LLPIN | ✅ | Hyphen always allowed | — |
| Voter ID (EPIC) | ✅ | ✅ | — |
| Vehicle | ✅ | Always allowed | — |
Python and Rust
Section titled “Python and Rust”from indycheck import validate_pan
validate_pan("AAAPL 1234C", {"allow_spaces": True}).ok # Truevalidate_pan("AAAPL-1234C", {"strict": False}).ok # Trueuse indycheck::{validate_pan, Options};
let opts = Options { strict: false, ..Default::default() };let r = validate_pan("AAAPL-1234C", opts);assert!(r.ok);