@prashanttiw/pramana
v1.1.0
Published
High-performance, zero-dependency, algorithmic validation library for the Indian context (Aadhaar, PAN, GSTIN, IFSC, Pincode).
Maintainers
Readme
Pramana (प्रमाण)
Pramana is a high-performance, zero-dependency, production-ready validation library for Indian identity and financial documents. It validates not just the format but the actual mathematical checksums to ensure 100% accuracy.
Pramana means "evidence" or "proof" in Sanskrit—because validation should be based on actual algorithms, not just pattern matching.
🚀 Features
- Zero Dependencies: No external runtime dependencies. Pure TypeScript/JavaScript.
- Algorithm-Based Validation: Not just regex patterns—implements actual mathematical verification.
- Aadhaar: Verhoeff algorithm (detects all single-digit errors)
- GSTIN: Mod-36 checksum algorithm
- PAN: Structural validation + entity type verification
- IFSC: Bank code whitelist validation
- Pincode: Postal circle validation
- Production-Ready: 86 comprehensive tests (100% pass rate), 0 vulnerabilities
- Modular & Tree-Shakable: Import only what you need
- TypeScript Support: Full type definitions included
- Zod Integration: Optional pre-built Zod schemas available
📦 Installation
npm install @prashanttiw/pramanaOptional: Zod Support
If you want to use Zod schemas for form validation:
npm install zodZod is an optional peer dependency—use it only if you need schema validation.
💻 Quick Start
Basic Validation
import {
isValidAadhaar,
isValidPAN,
isValidGSTIN,
isValidIFSC,
isValidPincode
} from '@prashanttiw/pramana';
// Aadhaar (12 digits with Verhoeff checksum)
isValidAadhaar('999999990019'); // true
isValidAadhaar('12345678901'); // false (invalid checksum)
// PAN (10 chars: structure + entity type validation)
isValidPAN('ABCPE1234F'); // true (P = Person)
isValidPAN('ABCCD1234F'); // true (C = Company)
isValidPAN('ABC1234567'); // false (invalid structure)
// GSTIN (15 chars with Mod-36 checksum)
isValidGSTIN('29ABCDE1234F1Z5'); // true
isValidGSTIN('29ABCDE1234F1Z0'); // false (invalid checksum)
// IFSC (11 chars with valid bank code)
isValidIFSC('SBIN0012345'); // true
isValidIFSC('XXXX0012345'); // false (invalid bank code)
// Pincode (6 digits with valid postal circle)
isValidPincode('110001'); // true (Delhi)
isValidPincode('990000'); // false (invalid postal circle)Get Information
Some validators can extract additional information:
import {
getGSTINInfo,
getPANInfo,
getPincodeInfo
} from '@prashanttiw/pramana/validators';
// Extract state from GSTIN
const gstin = getGSTINInfo('29ABCDE1234F1Z5');
console.log(gstin.state); // "Karnataka"
// Extract entity type from PAN
const pan = getPANInfo('ABCPE1234F');
console.log(pan.category); // "Person"
// Extract region from Pincode
const pincode = getPincodeInfo('110001');
console.log(pincode.region); // "Delhi"With Zod (Form Validation)
import { z } from 'zod';
import { aadhaarSchema, panSchema, gstinSchema } from '@prashanttiw/pramana/zod';
// Create a schema combining Pramana validators with other fields
const UserSchema = z.object({
name: z.string().min(1, 'Name is required'),
email: z.string().email(),
aadhaar: aadhaarSchema,
pan: panSchema.optional(),
gstin: gstinSchema.optional()
});
// Use it in your form
try {
const result = UserSchema.parse({
name: 'Aditya',
email: '[email protected]',
aadhaar: '999999990019'
});
console.log('Valid user:', result);
} catch (error) {
console.error('Validation errors:', error.errors);
}📚 API Reference
Validators
| Document | Function | Description |
|----------|----------|-------------|
| Aadhaar | isValidAadhaar(input) | Validates 12-digit UID using Verhoeff algorithm |
| PAN | isValidPAN(input) | Validates 10-char format + 4th char entity type |
| GSTIN | isValidGSTIN(input) | Validates 15-char format + Mod-36 checksum |
| IFSC | isValidIFSC(input) | Validates 11-char + bank code whitelist |
| Pincode | isValidPincode(input) | Validates 6-digit + postal circle mapping |
Info Extractors
// Extract metadata from documents
getGSTINInfo(gstin) // { state: string }
getPANInfo(pan) // { category: string }
getPincodeInfo(pincode)// { region: string }Input Validation
All validators:
- ✅ Accept only strings
- ✅ Reject null/undefined
- ✅ Reject empty strings
- ✅ Reject whitespace-containing inputs
- ✅ Return
falsefor invalid inputs (no exceptions thrown)
📚 Documentation Roadmap
Not sure where to start? This table maps your needs to the right documentation:
| I want to... | Resource | Description | |---|---|---| | Get started quickly | README.md (this file) | Installation, quick-start examples, basic usage | | Learn how validators work | README.md - How It Works | Algorithm explanations for each validator | | Use in my project | README.md - Quick Start | Copy-paste code examples and usage patterns | | Integrate with Zod | README.md - Quick Start | Form validation with Zod schemas | | Understand the architecture | COMPLETE_PROJECT_GUIDE.md | Full project structure, validators, algorithms, and design | | See all validators & info extractors | COMPLETE_PROJECT_GUIDE.md - API Reference | Complete function documentation with examples | | Contribute code | CONTRIBUTING.md | Development setup, PR process, testing requirements | | Report a bug | CONTRIBUTING.md - Report Bugs | Structured bug report template and guidelines | | Request a new validator | CONTRIBUTING.md - Feature Requests | How to propose new Indian document validators | | Report security issues | CONTRIBUTING.md - Security | Responsible disclosure process ([email protected]) | | Understand the code style | CONTRIBUTING.md - Style Guide | TypeScript standards, naming conventions, documentation | | Learn git workflow | CONTRIBUTING.md - Commit Guidelines | Conventional Commits, SemVer, branch naming | | Set up development environment | CONTRIBUTING.md - Development Setup | Step-by-step local setup with npm link testing | | See what changed in latest version | TECHNICAL_CHANGES_SUMMARY.md | Audit history, refactoring details, test coverage growth | | Understand the audit process | DEPLOYMENT_AUDIT_REPORT.md | Pre-deployment findings, quality metrics, security checklist | | View test coverage & metrics | DEPLOYMENT_AUDIT_REPORT.md - Quality Metrics | 86 tests (100% pass), 0 vulnerabilities, full type safety | | Get inspired by contributors | CONTRIBUTORS.md | Recognition of all community members who helped | | Join the community | CONTRIBUTING.md - Community | Discord, GitHub Discussions, Twitter, and more | | Troubleshoot issues | CONTRIBUTING.md - Troubleshooting | Common problems and their solutions | | Learn about validators in detail | CONTRIBUTING.md - Learning Resources | References to algorithms, government specs, and tutorials |
Quick Navigation by Role
👤 User/Developer → Start with README.md and Quick Start
🔧 Contributor → Read CONTRIBUTING.md and Development Setup
📋 Bug Reporter → Check CONTRIBUTING.md - Report Bugs and use bug_report.md template
✨ Feature Proposer → See CONTRIBUTING.md - Feature Requests and feature_request.md template
🏗️ Architect/Deep Diver → Explore COMPLETE_PROJECT_GUIDE.md for full architecture
🔐 Security Researcher → Read CONTRIBUTING.md - Security for responsible disclosure
🤝 Can't Find What You Need?
If you can't find the answer in our documentation:
- Check GitHub Discussions - Ask your question or start a conversation with the community
- Review Troubleshooting Guide - Common issues and solutions
- Search GitHub Issues - Your question might have been answered already
- Report a Bug or Request a Feature - We're here to help!
We're committed to making Pramana accessible to everyone. Don't hesitate to reach out! 💬
� How It Works (Technical Deep Dive)
Unlike naive libraries that just use regex patterns, Pramana implements actual mathematical algorithms:
Aadhaar Validation
- Algorithm: Verhoeff Checksum
- What it does: The last digit of an Aadhaar is a check digit. The Verhoeff algorithm can detect:
- All single-digit errors
- All transposition errors (e.g.,
123↔132)
- Why it matters: A fake number like
123456789012might look valid but fails the checksum - Reference: Verhoeff Algorithm (Wikipedia)
PAN Validation
- Algorithm: Structural + Entity Type Validation
- Format:
AABCP9999Awhere:- 1-5: Letters (PAN holder surname or first two letters of name)
- 6-8: Digits (birth year of individual or registration year)
- 9: Entity type (P=Person, C=Company, H=HUF, F=Firm, etc.)
- 10: Check digit (letter)
- What we validate: Format structure + valid entity type in 9th position
GSTIN Validation
- Algorithm: Mod-36 Checksum
- What it does: The 15th character is a check digit calculated from the first 14 characters
- Formula: Character at position 15 = mod(36 - (sum of weighted values), 36)
- Why it matters: Prevents typos and ensures authenticity
- Reference: GST India Official
IFSC Validation
- Algorithm: Bank Code Whitelist
- What it does: Validates against a curated list of major Indian bank codes
- Why it matters: Catches typos (e.g.,
SBIIinstead ofSBIN) - Coverage: 100+ major bank codes
Pincode Validation
- Algorithm: Postal Circle Mapping
- What it does: Validates first 2 digits against real postal circles
- Example:
11****= Delhi,40****= Maharashtra - Why it matters: Prevents invalid geographic codes like
99****
�🛠️ Development
Project Structure
src/
├── validators/ # Business logic (Aadhaar, PAN, GSTIN, etc.)
├── utils/ # Core algorithms (Verhoeff, Mod-36, Checksum)
├── data/ # Reference data (Bank codes, Postal circles, GST states)
├── zod/ # Zod schema integration (optional)
└── index.ts # Main entry pointBuild & Test
# Install dependencies
npm install
# Run tests (86 tests, 100% pass rate)
npm test
# Build for production (CJS + ESM)
npm run build
# Type check
npm run lintBuild Output
dist/
├── index.js # CommonJS build
├── index.mjs # ES Module build
├── index.d.ts # TypeScript declarations
└── zod/ # Zod integration build� Documentation
For more information, see:
- COMPLETE_PROJECT_GUIDE.md - Full project architecture and features
- TECHNICAL_CHANGES_SUMMARY.md - Implementation details
- DEPLOYMENT_AUDIT_REPORT.md - Quality metrics and test results
❓ FAQ
Q: What if validation fails?
A: Validators return false for invalid input. No exceptions thrown. It's safe to use without try-catch.
const result = isValidAadhaar(userInput);
if (!result) {
// Show error message to user
}Q: How do I use this with React?
A: Combine with Zod for real-time validation:
import { aadhaarSchema } from '@prashanttiw/pramana/zod';
// In your form handler
const validationResult = aadhaarSchema.safeParse(userInput);
if (!validationResult.success) {
setError(validationResult.error.message);
}Q: Can I validate partially?
A: No. All validators require complete, valid input. This ensures accuracy.
Q: What about performance?
A: All validations are O(n) where n is input length. No external API calls. Validation completes in <1ms.
Q: Do you store data?
A: No. Pramana is client-side only. No data is sent anywhere.
Q: Are test documents (999999990019) always valid?
A: No. Test documents are valid IDs that pass all checks but are reserved for testing purposes. Don't use them in production.
🤝 Contributing
Contributions welcome! Here's how:
- Fork the repository
- Create a feature branch:
git checkout -b feature/your-feature - Make your changes and add tests
- Ensure all tests pass:
npm test - Submit a pull request
Development Guidelines:
- All code must be TypeScript
- Tests must cover 100% of new code
- Follow existing code style
- Update README if adding new validators
📊 Quality Metrics
- ✅ 86 tests (100% passing)
- ✅ 0 vulnerabilities (npm audit clean)
- ✅ 0 dependencies (zero runtime dependencies)
- ✅ 100% tree-shakable (only import what you use)
- ✅ Full TypeScript support (strict mode)
- ✅ Cross-platform (Node.js, browsers, Edge functions)
🔮 Roadmap
Phase 2
- [ ] Voter ID (EPIC) validation
- [ ] Driving License validation
- [ ] UAN (Universal Account Number) validation
- [ ] CIN (Corporate Identity Number) validation
- [ ] Vehicle Registration Number validation
Phase 3
- [ ] Performance benchmarks & optimization
- [ ] Batch validation API
- [ ] Additional metadata extraction
- [ ] CLI tool for batch validation
📜 License
ISC License - See LICENSE file for details
❤️ Authors
Pramana is maintained by the community. Contributions from developers across India are welcome!
Made with ❤️ for India 🇮🇳
