nigerian-mobile-validator
Version:
The most rigorous, up-to-date library for validating Nigerian mobile numbers. Fully NCC-compliant, and security-focused, with enterprise-grade features to prevent the business risks of validation failures in regulated industries.
335 lines (334 loc) • 22.6 kB
JavaScript
"use strict";
// src/numbering-plan/mobile-numbering-plan.ts
Object.defineProperty(exports, "__esModule", { value: true });
exports.MobileNumberingPlan = void 0;
const network_access_code_1 = require("./network-access-code");
const telco_number_allocation_1 = require("./telco-number-allocation");
const telco_1 = require("./telco");
/**
* Represents the official NCC mobile numbering plan for Nigeria.
* Last updated based on March 2025 NCC data.
*/
class MobileNumberingPlan {
constructor() {
this.networkCodeMap = new Map();
this.initialized = false;
}
/**
* Searches the national mobile numbering plan for the number range to which
* the given local number belongs.
*
* @param localNumber The local number to search for
* @returns The TelcoNumberAllocation if found, null otherwise
*/
search(localNumber) {
this.lazyInitialize();
// Extract network code (first 3 digits)
const numericNetworkCode = Math.floor(localNumber / 10000000);
// Check it's a valid code by getting the NetworkAccessCode enum value using the utility method
const networkCode = network_access_code_1.NetworkAccessCodeUtil.getByNetworkCode(numericNetworkCode);
// If network code is invalid, return null
if (!networkCode) {
return null;
}
// Get allocations for this network code
let telcoNumberAllocations = this.networkCodeMap.get(networkCode);
// If allocations array exists but is empty, load the data
if (telcoNumberAllocations && telcoNumberAllocations.length === 0) {
this.loadNetworkCodeData(networkCode);
telcoNumberAllocations = this.networkCodeMap.get(networkCode);
}
// If network code doesn't exist or has no allocations
if (!telcoNumberAllocations || telcoNumberAllocations.length === 0) {
return null;
}
// For network codes with multiple ranges, check each range
for (const telcoNumberAllocation of telcoNumberAllocations) {
if (telcoNumberAllocation.localNumberRange.isWithinRange(localNumber)) {
return telcoNumberAllocation;
}
}
return null;
}
/**
* Initialize the map structure without loading all the data
*/
lazyInitialize() {
if (this.initialized)
return;
// Set up empty map entries for each network code using the enum as source of truth
Object.values(network_access_code_1.NetworkAccessCode)
.filter(value => typeof value === 'number')
.forEach(code => {
this.networkCodeMap.set(code, []);
});
this.initialized = true;
}
/**
* Load data for a specific network code
*
* This method implements a lazy loading strategy to optimize performance.
* Instead of loading the entire numbering plan at initialization (which would
* cause startup delays), we only load data for specific network codes when
* they are first encountered during a search operation.
*
* The workflow is:
* 1. When a search is performed, we check if we have allocation data for the network code
* 2. If the array exists but is empty, we call this method to load just that network code's data
* 3. This keeps memory usage low and avoids unnecessary initialization time
*
* @param networkCode The network code to load allocation data for
*/
loadNetworkCodeData(networkCode) {
switch (networkCode) {
case network_access_code_1.NetworkAccessCode.n700:
this.networkCodeMap.set(700, [
new telco_number_allocation_1.TelcoNumberAllocation(network_access_code_1.NetworkAccessCode.n700, telco_1.Telco.SharedVAS, { subscriberNumberLowerbound: 0, subscriberNumberUpperbound: 9999999 })
]);
break;
case network_access_code_1.NetworkAccessCode.n701:
this.networkCodeMap.set(701, [
new telco_number_allocation_1.TelcoNumberAllocation(network_access_code_1.NetworkAccessCode.n701, telco_1.Telco.Airtel, { subscriberNumberLowerbound: 0, subscriberNumberUpperbound: 9999999 })
]);
break;
case network_access_code_1.NetworkAccessCode.n702:
// Complex allocation based on March 2025 data
this.networkCodeMap.set(702, [
// 0702 0000000-0999999: Allocated to Smile
new telco_number_allocation_1.TelcoNumberAllocation(network_access_code_1.NetworkAccessCode.n702, telco_1.Telco.Smile, { subscriberNumberLowerbound: 0, subscriberNumberUpperbound: 999999 }),
// 0702 1000000-1999999: Returned
new telco_number_allocation_1.TelcoNumberAllocation(network_access_code_1.NetworkAccessCode.n702, telco_1.Telco.Returned, { subscriberNumberLowerbound: 1000000, subscriberNumberUpperbound: 1999999 }),
// 0702 2000000-2000199: Interconnect Clearinghouse
new telco_number_allocation_1.TelcoNumberAllocation(network_access_code_1.NetworkAccessCode.n702, telco_1.Telco.InterconnectClearinghouse, { subscriberNumberLowerbound: 2000000, subscriberNumberUpperbound: 2000199 }),
// 0702 2000200-2999999: Withdrawn
new telco_number_allocation_1.TelcoNumberAllocation(network_access_code_1.NetworkAccessCode.n702, telco_1.Telco.Withdrawn, { subscriberNumberLowerbound: 2000200, subscriberNumberUpperbound: 2999999 }),
// 0702 3000000-3999999: Openskys
new telco_number_allocation_1.TelcoNumberAllocation(network_access_code_1.NetworkAccessCode.n702, telco_1.Telco.Openskys, { subscriberNumberLowerbound: 3000000, subscriberNumberUpperbound: 3999999 }),
// 0702 4000000-4999999: Withdrawn
new telco_number_allocation_1.TelcoNumberAllocation(network_access_code_1.NetworkAccessCode.n702, telco_1.Telco.Withdrawn, { subscriberNumberLowerbound: 4000000, subscriberNumberUpperbound: 4999999 }),
// 0702 5000000-6999999: Visafone (now MTN)
new telco_number_allocation_1.TelcoNumberAllocation(network_access_code_1.NetworkAccessCode.n702, telco_1.Telco.Visafone, { subscriberNumberLowerbound: 5000000, subscriberNumberUpperbound: 6999999 }),
// 0702 7000000-9999999: Withdrawn
new telco_number_allocation_1.TelcoNumberAllocation(network_access_code_1.NetworkAccessCode.n702, telco_1.Telco.Withdrawn, { subscriberNumberLowerbound: 7000000, subscriberNumberUpperbound: 9999999 })
]);
break;
case network_access_code_1.NetworkAccessCode.n703:
this.networkCodeMap.set(703, [
new telco_number_allocation_1.TelcoNumberAllocation(network_access_code_1.NetworkAccessCode.n703, telco_1.Telco.MTN, { subscriberNumberLowerbound: 0, subscriberNumberUpperbound: 9999999 })
]);
break;
case network_access_code_1.NetworkAccessCode.n704:
this.networkCodeMap.set(704, [
new telco_number_allocation_1.TelcoNumberAllocation(network_access_code_1.NetworkAccessCode.n704, telco_1.Telco.MTN, { subscriberNumberLowerbound: 0, subscriberNumberUpperbound: 9999999 })
]);
break;
case network_access_code_1.NetworkAccessCode.n705:
this.networkCodeMap.set(705, [
new telco_number_allocation_1.TelcoNumberAllocation(network_access_code_1.NetworkAccessCode.n705, telco_1.Telco.Globacom, { subscriberNumberLowerbound: 0, subscriberNumberUpperbound: 9999999 })
]);
break;
case network_access_code_1.NetworkAccessCode.n706:
this.networkCodeMap.set(706, [
new telco_number_allocation_1.TelcoNumberAllocation(network_access_code_1.NetworkAccessCode.n706, telco_1.Telco.MTN, { subscriberNumberLowerbound: 0, subscriberNumberUpperbound: 9999999 })
]);
break;
case network_access_code_1.NetworkAccessCode.n707:
this.networkCodeMap.set(707, [
new telco_number_allocation_1.TelcoNumberAllocation(network_access_code_1.NetworkAccessCode.n707, telco_1.Telco.MTN, { subscriberNumberLowerbound: 0, subscriberNumberUpperbound: 9999999 })
]);
break;
case network_access_code_1.NetworkAccessCode.n708:
this.networkCodeMap.set(708, [
new telco_number_allocation_1.TelcoNumberAllocation(network_access_code_1.NetworkAccessCode.n708, telco_1.Telco.Airtel, { subscriberNumberLowerbound: 0, subscriberNumberUpperbound: 9999999 })
]);
break;
case network_access_code_1.NetworkAccessCode.n709:
this.networkCodeMap.set(709, [
new telco_number_allocation_1.TelcoNumberAllocation(network_access_code_1.NetworkAccessCode.n709, telco_1.Telco.Withdrawn, { subscriberNumberLowerbound: 0, subscriberNumberUpperbound: 9999999 })
]);
break;
case network_access_code_1.NetworkAccessCode.n710:
// New in March 2025 data - Telewyz
this.networkCodeMap.set(710, [
new telco_number_allocation_1.TelcoNumberAllocation(network_access_code_1.NetworkAccessCode.n710, telco_1.Telco.Telewyz, { subscriberNumberLowerbound: 0, subscriberNumberUpperbound: 9999999 })
]);
break;
case network_access_code_1.NetworkAccessCode.n800:
this.networkCodeMap.set(800, [
new telco_number_allocation_1.TelcoNumberAllocation(network_access_code_1.NetworkAccessCode.n800, telco_1.Telco.SharedVAS, { subscriberNumberLowerbound: 0, subscriberNumberUpperbound: 9999999 })
]);
break;
case network_access_code_1.NetworkAccessCode.n801:
this.networkCodeMap.set(801, [
new telco_number_allocation_1.TelcoNumberAllocation(network_access_code_1.NetworkAccessCode.n801, telco_1.Telco.Mafab, { subscriberNumberLowerbound: 0, subscriberNumberUpperbound: 9999999 })
]);
break;
case network_access_code_1.NetworkAccessCode.n802:
this.networkCodeMap.set(802, [
new telco_number_allocation_1.TelcoNumberAllocation(network_access_code_1.NetworkAccessCode.n802, telco_1.Telco.Airtel, { subscriberNumberLowerbound: 0, subscriberNumberUpperbound: 9999999 })
]);
break;
case network_access_code_1.NetworkAccessCode.n803:
this.networkCodeMap.set(803, [
new telco_number_allocation_1.TelcoNumberAllocation(network_access_code_1.NetworkAccessCode.n803, telco_1.Telco.MTN, { subscriberNumberLowerbound: 0, subscriberNumberUpperbound: 9999999 })
]);
break;
case network_access_code_1.NetworkAccessCode.n804:
this.networkCodeMap.set(804, [
new telco_number_allocation_1.TelcoNumberAllocation(network_access_code_1.NetworkAccessCode.n804, telco_1.Telco.MTel, { subscriberNumberLowerbound: 0, subscriberNumberUpperbound: 9999999 })
]);
break;
case network_access_code_1.NetworkAccessCode.n805:
this.networkCodeMap.set(805, [
new telco_number_allocation_1.TelcoNumberAllocation(network_access_code_1.NetworkAccessCode.n805, telco_1.Telco.Globacom, { subscriberNumberLowerbound: 0, subscriberNumberUpperbound: 9999999 })
]);
break;
case network_access_code_1.NetworkAccessCode.n806:
this.networkCodeMap.set(806, [
new telco_number_allocation_1.TelcoNumberAllocation(network_access_code_1.NetworkAccessCode.n806, telco_1.Telco.MTN, { subscriberNumberLowerbound: 0, subscriberNumberUpperbound: 9999999 })
]);
break;
case network_access_code_1.NetworkAccessCode.n807:
this.networkCodeMap.set(807, [
new telco_number_allocation_1.TelcoNumberAllocation(network_access_code_1.NetworkAccessCode.n807, telco_1.Telco.Globacom, { subscriberNumberLowerbound: 0, subscriberNumberUpperbound: 9999999 })
]);
break;
case network_access_code_1.NetworkAccessCode.n808:
this.networkCodeMap.set(808, [
new telco_number_allocation_1.TelcoNumberAllocation(network_access_code_1.NetworkAccessCode.n808, telco_1.Telco.Airtel, { subscriberNumberLowerbound: 0, subscriberNumberUpperbound: 9999999 })
]);
break;
case network_access_code_1.NetworkAccessCode.n809:
this.networkCodeMap.set(809, [
new telco_number_allocation_1.TelcoNumberAllocation(network_access_code_1.NetworkAccessCode.n809, telco_1.Telco.NineMobile, { subscriberNumberLowerbound: 0, subscriberNumberUpperbound: 9999999 })
]);
break;
case network_access_code_1.NetworkAccessCode.n810:
this.networkCodeMap.set(810, [
new telco_number_allocation_1.TelcoNumberAllocation(network_access_code_1.NetworkAccessCode.n810, telco_1.Telco.MTN, { subscriberNumberLowerbound: 0, subscriberNumberUpperbound: 9999999 })
]);
break;
case network_access_code_1.NetworkAccessCode.n811:
this.networkCodeMap.set(811, [
new telco_number_allocation_1.TelcoNumberAllocation(network_access_code_1.NetworkAccessCode.n811, telco_1.Telco.Globacom, { subscriberNumberLowerbound: 0, subscriberNumberUpperbound: 9999999 })
]);
break;
case network_access_code_1.NetworkAccessCode.n812:
this.networkCodeMap.set(812, [
new telco_number_allocation_1.TelcoNumberAllocation(network_access_code_1.NetworkAccessCode.n812, telco_1.Telco.Airtel, { subscriberNumberLowerbound: 0, subscriberNumberUpperbound: 9999999 })
]);
break;
case network_access_code_1.NetworkAccessCode.n813:
this.networkCodeMap.set(813, [
new telco_number_allocation_1.TelcoNumberAllocation(network_access_code_1.NetworkAccessCode.n813, telco_1.Telco.MTN, { subscriberNumberLowerbound: 0, subscriberNumberUpperbound: 9999999 })
]);
break;
case network_access_code_1.NetworkAccessCode.n814:
this.networkCodeMap.set(814, [
new telco_number_allocation_1.TelcoNumberAllocation(network_access_code_1.NetworkAccessCode.n814, telco_1.Telco.MTN, { subscriberNumberLowerbound: 0, subscriberNumberUpperbound: 9999999 })
]);
break;
case network_access_code_1.NetworkAccessCode.n815:
this.networkCodeMap.set(815, [
new telco_number_allocation_1.TelcoNumberAllocation(network_access_code_1.NetworkAccessCode.n815, telco_1.Telco.Globacom, { subscriberNumberLowerbound: 0, subscriberNumberUpperbound: 9999999 })
]);
break;
case network_access_code_1.NetworkAccessCode.n816:
this.networkCodeMap.set(816, [
new telco_number_allocation_1.TelcoNumberAllocation(network_access_code_1.NetworkAccessCode.n816, telco_1.Telco.MTN, { subscriberNumberLowerbound: 0, subscriberNumberUpperbound: 9999999 })
]);
break;
case network_access_code_1.NetworkAccessCode.n817:
this.networkCodeMap.set(817, [
new telco_number_allocation_1.TelcoNumberAllocation(network_access_code_1.NetworkAccessCode.n817, telco_1.Telco.NineMobile, { subscriberNumberLowerbound: 0, subscriberNumberUpperbound: 9999999 })
]);
break;
case network_access_code_1.NetworkAccessCode.n818:
this.networkCodeMap.set(818, [
new telco_number_allocation_1.TelcoNumberAllocation(network_access_code_1.NetworkAccessCode.n818, telco_1.Telco.NineMobile, { subscriberNumberLowerbound: 0, subscriberNumberUpperbound: 9999999 })
]);
break;
case network_access_code_1.NetworkAccessCode.n900:
this.networkCodeMap.set(900, [
new telco_number_allocation_1.TelcoNumberAllocation(network_access_code_1.NetworkAccessCode.n900, telco_1.Telco.Reserved, { subscriberNumberLowerbound: 0, subscriberNumberUpperbound: 9999999 })
]);
break;
case network_access_code_1.NetworkAccessCode.n901:
this.networkCodeMap.set(901, [
new telco_number_allocation_1.TelcoNumberAllocation(network_access_code_1.NetworkAccessCode.n901, telco_1.Telco.Airtel, { subscriberNumberLowerbound: 0, subscriberNumberUpperbound: 9999999 })
]);
break;
case network_access_code_1.NetworkAccessCode.n902:
this.networkCodeMap.set(902, [
new telco_number_allocation_1.TelcoNumberAllocation(network_access_code_1.NetworkAccessCode.n902, telco_1.Telco.Airtel, { subscriberNumberLowerbound: 0, subscriberNumberUpperbound: 9999999 })
]);
break;
case network_access_code_1.NetworkAccessCode.n903:
this.networkCodeMap.set(903, [
new telco_number_allocation_1.TelcoNumberAllocation(network_access_code_1.NetworkAccessCode.n903, telco_1.Telco.MTN, { subscriberNumberLowerbound: 0, subscriberNumberUpperbound: 9999999 })
]);
break;
case network_access_code_1.NetworkAccessCode.n904:
this.networkCodeMap.set(904, [
new telco_number_allocation_1.TelcoNumberAllocation(network_access_code_1.NetworkAccessCode.n904, telco_1.Telco.Airtel, { subscriberNumberLowerbound: 0, subscriberNumberUpperbound: 9999999 })
]);
break;
case network_access_code_1.NetworkAccessCode.n905:
this.networkCodeMap.set(905, [
new telco_number_allocation_1.TelcoNumberAllocation(network_access_code_1.NetworkAccessCode.n905, telco_1.Telco.Globacom, { subscriberNumberLowerbound: 0, subscriberNumberUpperbound: 9999999 })
]);
break;
case network_access_code_1.NetworkAccessCode.n906:
this.networkCodeMap.set(906, [
new telco_number_allocation_1.TelcoNumberAllocation(network_access_code_1.NetworkAccessCode.n906, telco_1.Telco.MTN, { subscriberNumberLowerbound: 0, subscriberNumberUpperbound: 9999999 })
]);
break;
case network_access_code_1.NetworkAccessCode.n907:
this.networkCodeMap.set(907, [
new telco_number_allocation_1.TelcoNumberAllocation(network_access_code_1.NetworkAccessCode.n907, telco_1.Telco.Airtel, { subscriberNumberLowerbound: 0, subscriberNumberUpperbound: 9999999 })
]);
break;
case network_access_code_1.NetworkAccessCode.n908:
this.networkCodeMap.set(908, [
new telco_number_allocation_1.TelcoNumberAllocation(network_access_code_1.NetworkAccessCode.n908, telco_1.Telco.NineMobile, { subscriberNumberLowerbound: 0, subscriberNumberUpperbound: 9999999 })
]);
break;
case network_access_code_1.NetworkAccessCode.n909:
this.networkCodeMap.set(909, [
new telco_number_allocation_1.TelcoNumberAllocation(network_access_code_1.NetworkAccessCode.n909, telco_1.Telco.NineMobile, { subscriberNumberLowerbound: 0, subscriberNumberUpperbound: 9999999 })
]);
break;
case network_access_code_1.NetworkAccessCode.n911:
this.networkCodeMap.set(911, [
new telco_number_allocation_1.TelcoNumberAllocation(network_access_code_1.NetworkAccessCode.n911, telco_1.Telco.Airtel, { subscriberNumberLowerbound: 0, subscriberNumberUpperbound: 9999999 })
]);
break;
case network_access_code_1.NetworkAccessCode.n912:
this.networkCodeMap.set(912, [
new telco_number_allocation_1.TelcoNumberAllocation(network_access_code_1.NetworkAccessCode.n912, telco_1.Telco.Airtel, { subscriberNumberLowerbound: 0, subscriberNumberUpperbound: 9999999 })
]);
break;
case network_access_code_1.NetworkAccessCode.n913:
this.networkCodeMap.set(913, [
new telco_number_allocation_1.TelcoNumberAllocation(network_access_code_1.NetworkAccessCode.n913, telco_1.Telco.MTN, { subscriberNumberLowerbound: 0, subscriberNumberUpperbound: 9999999 })
]);
break;
case network_access_code_1.NetworkAccessCode.n914:
this.networkCodeMap.set(914, [
new telco_number_allocation_1.TelcoNumberAllocation(network_access_code_1.NetworkAccessCode.n914, telco_1.Telco.MTN, { subscriberNumberLowerbound: 0, subscriberNumberUpperbound: 9999999 })
]);
break;
case network_access_code_1.NetworkAccessCode.n915:
this.networkCodeMap.set(915, [
new telco_number_allocation_1.TelcoNumberAllocation(network_access_code_1.NetworkAccessCode.n915, telco_1.Telco.Globacom, { subscriberNumberLowerbound: 0, subscriberNumberUpperbound: 9999999 })
]);
break;
case network_access_code_1.NetworkAccessCode.n916:
this.networkCodeMap.set(916, [
new telco_number_allocation_1.TelcoNumberAllocation(network_access_code_1.NetworkAccessCode.n916, telco_1.Telco.MTN, { subscriberNumberLowerbound: 0, subscriberNumberUpperbound: 9999999 })
]);
break;
}
}
}
exports.MobileNumberingPlan = MobileNumberingPlan;