@teknyo/sl_nic_validator
Version:
Validate Sri Lankan NIC numbers for old and new formats (JavaScript & TypeScript).
295 lines (294 loc) • 10.7 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.isSimpleValidNIC = isSimpleValidNIC;
exports.isFullValidNIC = isFullValidNIC;
exports.getSimpleValidNICInfo = getSimpleValidNICInfo;
exports.getFullValidNICInfo = getFullValidNICInfo;
exports.getNICGender = getNICGender;
exports.getNICBirthYear = getNICBirthYear;
exports.getNICDayOfYear = getNICDayOfYear;
exports.getNICBirthMonth = getNICBirthMonth;
exports.getNICBirthDay = getNICBirthDay;
exports.getFullNICDetails = getFullNICDetails;
const constants_1 = require("./constants");
/**
* Validate Sri Lankan NIC Number (old and new formats)
*
* Old NIC: 9 digits + 'V' or 'X' (e.g., 123456789V)
* New NIC: 12 digits (e.g., 200012345678)
*
* @param {string} nic - The NIC number to validate.
* @returns {boolean} Returns `true` if the NIC is valid, otherwise `false`.
*/
function isSimpleValidNIC(nic) {
if (typeof nic !== 'string')
return false;
nic = nic.trim().toUpperCase();
return constants_1.NEW_NIC_REGEX.test(nic) || constants_1.OLD_NIC_REGEX.test(nic);
}
/**
* Validate Sri Lankan NIC Number (old and new formats)
*
* Old NIC: 9 digits + 'V' or 'X' (e.g., 123456789V)
* New NIC: 12 digits (e.g., 200012345678)
*
* @param {string} nic - The NIC number to validate.
* @returns {boolean} Returns `true` if the NIC is valid, otherwise `false`.
*/
function isFullValidNIC(nic) {
if (typeof nic !== 'string')
return false;
nic = nic.trim().toUpperCase();
if (constants_1.OLD_NIC_REGEX.test(nic))
return validateOldNIC(nic).valid;
if (constants_1.NEW_NIC_REGEX.test(nic))
return validateNewNIC(nic).valid;
return false;
}
/**
* Validates a Sri Lankan old format NIC number.
*
* Rules:
* - First 2 digits: birth year (from 1900).
* - Next 3 digits: day of the year (001–366).
* If the value is above 500, it indicates a female and is adjusted by subtracting 500.
* - Day must be within the valid range (1–366).
*
* @param {string} nic - NIC in the old format (10 characters).
* @returns {boolean} Returns true if valid, otherwise false.
*/
function validateOldNIC(nic) {
const year = parseInt(nic.slice(0, 2), 10) + 1900;
let day = parseInt(nic.slice(2, 5), 10);
if (isNaN(year) || isNaN(day))
return { valid: false, error: 'Invalid year or day number' };
if (day > 500)
day -= 500;
if (day < 1 || day > 366)
return { valid: false, error: 'Invalid day number for old NIC' };
return { valid: true };
}
/**
* Validates a Sri Lankan new format NIC number.
*
* Rules:
* - First 4 digits: birth year (e.g., 2000).
* - Next 3 digits: day of the year (001–366).
* If the value is above 500, it indicates a female and is adjusted by subtracting 500.
* - Day must be within the valid range (1–366).
* - Year must be between 1900 and current year.
*
* @param {string} nic - NIC in the new format (12 characters).
* @returns {boolean} Returns true if valid, otherwise false.
*/
function validateNewNIC(nic) {
const year = parseInt(nic.slice(0, 4), 10);
let day = parseInt(nic.slice(4, 7), 10);
if (isNaN(year) || isNaN(day))
return { valid: false, error: 'Invalid year or day number' };
if (year < 1900 || year > new Date().getFullYear())
return { valid: false, error: 'Unrealistic birth year' };
if (day > 500)
day -= 500;
if (day < 1 || day > 366)
return { valid: false, error: 'Invalid day number for new NIC' };
return { valid: true };
}
/**
* Get detailed information about a Sri Lankan NIC number.
*
* Supports both old and new format.
*
* @param nic - The NIC number as a string (with or without formatting).
* @returns An object containing:
* - `nic`: Trimmed and formatted NIC string.
* - `isValid`: Whether the NIC is valid according to format and rules.
* - `type`: `"old"` | `"new"` if valid, otherwise `null`.
*/
function getSimpleValidNICInfo(nic) {
var _a;
const trimmed = (_a = nic === null || nic === void 0 ? void 0 : nic.trim().toUpperCase()) !== null && _a !== void 0 ? _a : '';
const isValid = isSimpleValidNIC(trimmed);
return {
nic: trimmed,
isValid,
type: isValid ? (trimmed.length === constants_1.NEW_NIC_LENGTH ? 'new' : 'old') : null,
error: trimmed ? '' : 'NIC is empty'
};
}
/**
* Get detailed information about a Sri Lankan NIC number.
*
* Supports both old and new format.
*
* @param nic - The NIC number as a string (with or without formatting).
* @returns An object containing:
* - `nic`: Trimmed and formatted NIC string.
* - `isValid`: Whether the NIC is valid according to format and rules.
* - `type`: `"old"` | `"new"` if valid, otherwise `null`.
* - `error`: Validation error.
*/
function getFullValidNICInfo(nic) {
var _a;
const trimmed = (_a = nic === null || nic === void 0 ? void 0 : nic.trim().toUpperCase()) !== null && _a !== void 0 ? _a : '';
if (!trimmed)
return { nic: '', isValid: false, type: null, error: 'NIC is empty' };
if (constants_1.OLD_NIC_REGEX.test(trimmed)) {
const { valid, error } = validateOldNIC(trimmed);
return { nic: trimmed, isValid: valid, type: valid ? 'old' : null, ...(error && { error }) };
}
if (constants_1.NEW_NIC_REGEX.test(trimmed)) {
const { valid, error } = validateNewNIC(trimmed);
return { nic: trimmed, isValid: valid, type: valid ? 'new' : null, ...(error && { error }) };
}
return { nic: trimmed, isValid: false, type: null, error: 'NIC format is invalid' };
}
/**
* Extract gender from NIC day segment.
* @param dayOfYear - The day part from NIC (e.g. 123 or 623)
* @returns 'male' or 'female'
*/
function getNICGender(nic) {
nic = nic.trim();
let dayStr;
if (nic.length === constants_1.OLD_NIC_LENGTH)
dayStr = nic.slice(2, 5);
else if (nic.length === constants_1.NEW_NIC_LENGTH)
dayStr = nic.slice(4, 7);
else
return null;
let day = parseInt(dayStr, 10);
if (isNaN(day))
return null;
return day == null ? null : day > 500 ? 'female' : 'male';
}
/**
* Extract full birth year from NIC.
* @param nic - NIC number
* @returns number representing birth year
*/
function getNICBirthYear(nic) {
nic = nic.trim();
if (nic.length === constants_1.OLD_NIC_LENGTH)
return 1900 + parseInt(nic.slice(0, 2), 10);
if (nic.length === constants_1.NEW_NIC_LENGTH)
return parseInt(nic.slice(0, 4), 10);
return null;
}
/**
* Extract day of year from NIC number (used to determine birth month & day).
* @param nic - NIC number
* @returns day of year (1–366), or null if invalid
*/
function getNICDayOfYear(nic) {
nic = nic.trim();
let dayStr;
if (nic.length === constants_1.OLD_NIC_LENGTH)
dayStr = nic.slice(2, 5);
else if (nic.length === constants_1.NEW_NIC_LENGTH)
dayStr = nic.slice(4, 7);
else
return null;
let day = parseInt(dayStr, 10);
if (isNaN(day))
return null;
return day > 500 ? day - 500 : day;
}
/**
* Get the birth month from NIC year and day-of-year.
* @param year - full birth year
* @param dayOfYear - day of the year (1–366)
* @returns month number (1–12) or null if invalid
*/
function getNICBirthMonth(nic) {
const year = getNICBirthYear(nic);
const day = getNICDayOfYear(nic);
if (!year || !day || day < 1 || day > 366)
return null;
const date = new Date(year, 0);
date.setDate(day);
return date.getMonth() + 1;
}
/**
* Get the birth day of the month from NIC year and day-of-year.
* @param year - full birth year
* @param dayOfYear - day of the year (1–366)
* @returns day number (1–31) or null if invalid
*/
function getNICBirthDay(nic) {
const year = getNICBirthYear(nic);
const day = getNICDayOfYear(nic);
if (!year || !day || day < 1 || day > 366)
return null;
const date = new Date(year, 0);
date.setDate(day);
return date.getDate();
}
/**
* Extracts detailed information from a Sri Lankan NIC number (old or new format).
*
* This function validates the NIC format and parses out the birth year, birth month,
* birth day, gender, and NIC type. It also returns validation errors if any.
*
* @param {string} nic - The Sri Lankan National Identity Card number to be validated and parsed.
* @returns {NICDetails} An object containing:
* - nic: The trimmed and uppercased NIC string.
* - isValid: Boolean indicating if the NIC is valid.
* - type: 'old' for old NIC format, 'new' for new NIC format, or null if invalid format.
* - gender: 'male' or 'female' inferred from the NIC, or null if invalid.
* - birthYear: Full 4-digit birth year (e.g. 1985) or null if invalid.
* - birthMonth: Birth month (1-12) or null if invalid.
* - birthDay: Birth day of month (1-31) or null if invalid.
* - error: Optional string describing the validation error if NIC is invalid.
*/
function getFullNICDetails(nic) {
var _a;
const trimmed = (_a = nic === null || nic === void 0 ? void 0 : nic.trim().toUpperCase()) !== null && _a !== void 0 ? _a : '';
const isOld = constants_1.OLD_NIC_REGEX.test(trimmed);
const isNew = constants_1.NEW_NIC_REGEX.test(trimmed);
if (!isOld && !isNew) {
return {
nic: trimmed,
isValid: false,
type: null,
gender: null,
birthYear: null,
birthMonth: null,
birthDay: null,
error: 'NIC format is invalid'
};
}
const type = isOld ? 'old' : 'new';
const birthYear = getNICBirthYear(trimmed);
const dayOfYearRaw = isOld ? parseInt(trimmed.slice(2, 5), 10) : parseInt(trimmed.slice(4, 7), 10);
const dayOfYear = getNICDayOfYear(trimmed);
if (birthYear == null || dayOfYearRaw == null ||
isNaN(birthYear) || isNaN(dayOfYearRaw) ||
birthYear < 1900 || birthYear > new Date().getFullYear() ||
dayOfYearRaw < 1 || dayOfYearRaw > 866 ||
dayOfYear == null || dayOfYear < 1 || dayOfYear > 366) {
return {
nic: trimmed,
isValid: false,
type,
gender: null,
birthYear,
birthMonth: null,
birthDay: null,
error: 'Invalid birth year or day of year'
};
}
const gender = getNICGender(trimmed);
const birthMonth = getNICBirthMonth(trimmed);
const birthDay = getNICBirthDay(trimmed);
return {
nic: trimmed,
isValid: true,
type,
gender,
birthYear,
birthMonth,
birthDay,
error: undefined
};
}