pakistani-cnic-formatter-aroma 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/cnic.js +110 -0
- package/package.json +13 -0
package/cnic.js
ADDED
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview Pakistan CNIC Utility Module providing validation, formatting, masking,
|
|
3
|
+
* and data extraction (province and gender) based on NADRA CNIC specifications.
|
|
4
|
+
* @module pakistani-cnic-formatter
|
|
5
|
+
* @author Aroma Areej
|
|
6
|
+
* @license ISC
|
|
7
|
+
*/
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* Removes all non-digit characters from the provided CNIC input.
|
|
11
|
+
*
|
|
12
|
+
* @private
|
|
13
|
+
* @param {string|number} input - The raw CNIC input string or number.
|
|
14
|
+
* @returns {string} A string containing only numeric digits.
|
|
15
|
+
*/
|
|
16
|
+
function cleanCNIC(input) {
|
|
17
|
+
return String(input || '').replace(/\D/g, '');
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
/**
|
|
21
|
+
* Formats a raw CNIC string into the standard Pakistani format (XXXXX-XXXXXXX-X).
|
|
22
|
+
*
|
|
23
|
+
* @public
|
|
24
|
+
* @param {string|number} input - The raw CNIC input to format.
|
|
25
|
+
* @returns {string} The formatted CNIC string, or the original input if it does not contain exactly 13 digits.
|
|
26
|
+
*/
|
|
27
|
+
function format(input) {
|
|
28
|
+
const cleaned = cleanCNIC(input);
|
|
29
|
+
if (cleaned.length !== 13) return input;
|
|
30
|
+
return `${cleaned.slice(0, 5)}-${cleaned.slice(5, 12)}-${cleaned.slice(12)}`;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
/**
|
|
34
|
+
* Masks the middle 7 digits of a CNIC for privacy and security purposes.
|
|
35
|
+
*
|
|
36
|
+
* @public
|
|
37
|
+
* @param {string|number} input - The raw CNIC input to mask.
|
|
38
|
+
* @param {string} [maskChar='*'] - The character used for masking the middle section.
|
|
39
|
+
* @returns {string} The masked CNIC string (e.g., 35202-*******-1), or the original input if invalid.
|
|
40
|
+
*/
|
|
41
|
+
function mask(input, maskChar = '*') {
|
|
42
|
+
const cleaned = cleanCNIC(input);
|
|
43
|
+
if (cleaned.length !== 13) return input;
|
|
44
|
+
|
|
45
|
+
const prefix = cleaned.slice(0, 5);
|
|
46
|
+
const middleMask = maskChar.repeat(7);
|
|
47
|
+
const suffix = cleaned.slice(12);
|
|
48
|
+
|
|
49
|
+
return `${prefix}-${middleMask}-${suffix}`;
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
/**
|
|
53
|
+
* Validates a CNIC number and extracts regional and demographic information
|
|
54
|
+
* such as the issuing province/region and gender based on the national numbering scheme.
|
|
55
|
+
*
|
|
56
|
+
* @public
|
|
57
|
+
* @param {string|number} input - The CNIC input string or number to validate and analyze.
|
|
58
|
+
* @returns {Object} An object containing validation status, error messages, raw/formatted/masked values, province, and gender.
|
|
59
|
+
*/
|
|
60
|
+
function validate(input) {
|
|
61
|
+
const cleaned = cleanCNIC(input);
|
|
62
|
+
|
|
63
|
+
// Validate that the CNIC strictly contains 13 numeric digits
|
|
64
|
+
if (cleaned.length !== 13) {
|
|
65
|
+
return {
|
|
66
|
+
isValid: false,
|
|
67
|
+
error: 'CNIC must be exactly 13 digits long.',
|
|
68
|
+
raw: cleaned,
|
|
69
|
+
formatted: null,
|
|
70
|
+
masked: null,
|
|
71
|
+
province: null,
|
|
72
|
+
gender: null
|
|
73
|
+
};
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
// Map the first digit of the CNIC to its respective administrative region or province
|
|
77
|
+
const provinceMap = {
|
|
78
|
+
'1': 'Khyber Pakhtunkhwa',
|
|
79
|
+
'2': 'FATA',
|
|
80
|
+
'3': 'Punjab',
|
|
81
|
+
'4': 'Sindh',
|
|
82
|
+
'5': 'Balochistan',
|
|
83
|
+
'6': 'Islamabad',
|
|
84
|
+
'7': 'Gilgit-Baltistan',
|
|
85
|
+
'8': 'Azad Jammu & Kashmir'
|
|
86
|
+
};
|
|
87
|
+
|
|
88
|
+
const firstDigit = cleaned[0];
|
|
89
|
+
const province = provinceMap[firstDigit] || 'Unknown Region';
|
|
90
|
+
|
|
91
|
+
// Determine gender from the final 13th digit (Even = Female, Odd = Male)
|
|
92
|
+
const lastDigit = parseInt(cleaned[12], 10);
|
|
93
|
+
const gender = (lastDigit % 2 === 0) ? 'Female' : 'Male';
|
|
94
|
+
|
|
95
|
+
return {
|
|
96
|
+
isValid: true,
|
|
97
|
+
error: null,
|
|
98
|
+
raw: cleaned,
|
|
99
|
+
formatted: format(cleaned),
|
|
100
|
+
masked: mask(cleaned),
|
|
101
|
+
province: province,
|
|
102
|
+
gender: gender
|
|
103
|
+
};
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
module.exports = {
|
|
107
|
+
validate,
|
|
108
|
+
format,
|
|
109
|
+
mask
|
|
110
|
+
};
|
package/package.json
ADDED
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "pakistani-cnic-formatter-aroma",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"description": "",
|
|
5
|
+
"main": "cnic.js",
|
|
6
|
+
"scripts": {
|
|
7
|
+
"test": "echo \"Error: no test specified\" && exit 1"
|
|
8
|
+
},
|
|
9
|
+
"keywords": [],
|
|
10
|
+
"author": "Aroma Areej",
|
|
11
|
+
"license": "ISC",
|
|
12
|
+
"type": "commonjs"
|
|
13
|
+
}
|