@mdfrough/cnic-validator
Version:
An Angular library to validate and format Pakistani CNIC numbers with masking and pipe support.
147 lines (138 loc) • 6.27 kB
JavaScript
import * as i0 from '@angular/core';
import { Directive, HostListener, Pipe, NgModule } from '@angular/core';
import { NG_VALIDATORS } from '@angular/forms';
class CnicValidatorDirective {
validate(control) {
const value = control.value;
if (!value || /^(\d{5}-\d{7}-\d{1}|\d{13})$/.test(value)) {
return null;
}
return { invalidCnic: true };
}
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.1.0", ngImport: i0, type: CnicValidatorDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive });
static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "20.1.0", type: CnicValidatorDirective, isStandalone: true, selector: "[cnicValidator]", providers: [{
provide: NG_VALIDATORS,
useExisting: CnicValidatorDirective,
multi: true
}], ngImport: i0 });
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.0", ngImport: i0, type: CnicValidatorDirective, decorators: [{
type: Directive,
args: [{
selector: '[cnicValidator]',
standalone: true,
providers: [{
provide: NG_VALIDATORS,
useExisting: CnicValidatorDirective,
multi: true
}]
}]
}] });
class CnicMaskDirective {
el;
constructor(el) {
this.el = el;
}
onInput(event) {
const input = this.el.nativeElement;
let digits = input.value.replace(/\D/g, '');
if (digits.length > 13)
digits = digits.slice(0, 13);
let formatted = digits;
if (digits.length >= 6 && digits.length <= 12)
formatted = digits.replace(/^(\d{5})(\d+)/, '$1-$2');
if (digits.length === 13)
formatted = digits.replace(/^(\d{5})(\d{7})(\d{1})$/, '$1-$2-$3');
input.value = formatted;
// Dispatch input event so Angular form updates
input.dispatchEvent(new Event('input', { bubbles: true }));
}
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.1.0", ngImport: i0, type: CnicMaskDirective, deps: [{ token: i0.ElementRef }], target: i0.ɵɵFactoryTarget.Directive });
static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "20.1.0", type: CnicMaskDirective, isStandalone: true, selector: "[cnicMask]", host: { listeners: { "input": "onInput($event)" } }, ngImport: i0 });
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.0", ngImport: i0, type: CnicMaskDirective, decorators: [{
type: Directive,
args: [{
selector: '[cnicMask]',
standalone: true
}]
}], ctorParameters: () => [{ type: i0.ElementRef }], propDecorators: { onInput: [{
type: HostListener,
args: ['input', ['$event']]
}] } });
class CnicPipe {
transform(value) {
if (!value)
return '';
// remove all non-digits
const cleaned = value.replace(/\D/g, '').slice(0, 13); // ✅ only keep first 13 digits
if (cleaned.length < 13)
return cleaned;
return `${cleaned.slice(0, 5)}-${cleaned.slice(5, 12)}-${cleaned.slice(12)}`;
}
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.1.0", ngImport: i0, type: CnicPipe, deps: [], target: i0.ɵɵFactoryTarget.Pipe });
static ɵpipe = i0.ɵɵngDeclarePipe({ minVersion: "14.0.0", version: "20.1.0", ngImport: i0, type: CnicPipe, isStandalone: true, name: "cnic" });
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.0", ngImport: i0, type: CnicPipe, decorators: [{
type: Pipe,
args: [{
name: 'cnic',
standalone: true
}]
}] });
class CnicValidatorModule {
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.1.0", ngImport: i0, type: CnicValidatorModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule });
static ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "20.1.0", ngImport: i0, type: CnicValidatorModule, imports: [CnicValidatorDirective,
CnicMaskDirective,
CnicPipe], exports: [CnicValidatorDirective,
CnicMaskDirective,
CnicPipe] });
static ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "20.1.0", ngImport: i0, type: CnicValidatorModule });
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.0", ngImport: i0, type: CnicValidatorModule, decorators: [{
type: NgModule,
args: [{
declarations: [],
imports: [
CnicValidatorDirective,
CnicMaskDirective,
CnicPipe
],
exports: [
CnicValidatorDirective,
CnicMaskDirective,
CnicPipe
]
}]
}] });
function isValidCnic(value) {
return /^(\d{5}-\d{7}-\d{1}|\d{13})$/.test(value);
}
function parseCnic(cnic) {
const cleaned = cnic.replace(/\D/g, '');
if (cleaned.length !== 13)
return null;
const regionCode = cleaned.slice(0, 5);
const serial = cleaned.slice(5, 12);
const lastDigit = parseInt(cleaned.slice(12), 10);
const gender = isNaN(lastDigit)
? 'Unknown'
: lastDigit % 2 === 0
? 'Female'
: 'Male';
// ...gender+serial logic
return { regionCode, serial, gender };
}
function cnicValidatorFn(control) {
const value = control.value;
const cnicRegex = /^(\d{5}-\d{7}-\d{1}|\d{13})$/;
if (!value || cnicRegex.test(value)) {
return null;
}
return { invalidCnic: true };
}
/**
* Generated bundle index. Do not edit.
*/
export { CnicMaskDirective, CnicPipe, CnicValidatorDirective, CnicValidatorModule, cnicValidatorFn, isValidCnic, parseCnic };
//# sourceMappingURL=mdfrough-cnic-validator.mjs.map