@phonecheck/phone-number-validator-js
Version:
Verify phone number, validate format, checking carrier name, geo and timezone infos.
111 lines (108 loc) • 2.98 kB
JavaScript
export * from 'libphonenumber-js';
import { readFileSync } from 'node:fs';
import { join } from 'node:path';
import { deserialize } from 'bson';
import { lru } from 'tiny-lru';
const DEFAULT_CACHE_SIZE = 100;
let codeDataCache = lru(DEFAULT_CACHE_SIZE);
function getCode(dataPath, nationalNumber) {
if (!dataPath || !nationalNumber) {
return null;
}
try {
let data = codeDataCache.get(dataPath);
if (!data) {
const bData = readFileSync(dataPath);
data = deserialize(bData);
codeDataCache.set(dataPath, data);
}
let prefix = nationalNumber;
while (prefix.length > 0) {
const description = data[prefix];
if (description) {
return description;
}
prefix = prefix.substring(0, prefix.length - 1);
}
} catch (err) {
if (process.env.NODE_ENV !== "production") {
console.error(`Error loading data from ${dataPath}:`, err);
}
}
return null;
}
function getLocalizedData(resourceType, phonenumber, locale, fallbackLocale = "en") {
var _a, _b;
if (!phonenumber) {
return null;
}
const nationalNumber = (_a = phonenumber.nationalNumber) == null ? void 0 : _a.toString();
const countryCallingCode = (_b = phonenumber.countryCallingCode) == null ? void 0 : _b.toString();
if (!nationalNumber || !countryCallingCode) {
return null;
}
let dataPath = join(
__dirname,
"../resources/",
resourceType,
locale,
`${countryCallingCode}.bson`
);
const code = getCode(dataPath, nationalNumber);
if (code) {
return code;
}
if (locale !== fallbackLocale) {
dataPath = join(
__dirname,
"../resources/",
resourceType,
fallbackLocale,
`${countryCallingCode}.bson`
);
return getCode(dataPath, nationalNumber);
}
return null;
}
function geocoder(phonenumber, locale = "en") {
return getLocalizedData("geocodes", phonenumber, locale, "en");
}
function carrier(phonenumber, locale = "en") {
return getLocalizedData("carrier", phonenumber, locale, "en");
}
function timezones(phonenumber) {
if (!phonenumber || !phonenumber.number) {
return null;
}
let nr = phonenumber.number.toString();
if (!nr) {
return null;
}
nr = nr.replace(/^\+/, "");
const dataPath = join(__dirname, "../resources/timezones.bson");
const zones = getCode(dataPath, nr);
if (typeof zones === "string" && zones.length > 0) {
return zones.split("&").filter((zone) => zone.length > 0);
}
return null;
}
function clearCache() {
codeDataCache.clear();
}
function getCacheSize() {
return codeDataCache.size;
}
function setCacheSize(size) {
const oldCache = codeDataCache;
codeDataCache = lru(size);
const entries = oldCache.entries();
entries.reverse();
for (const [key, value] of entries) {
if (codeDataCache.size < size) {
codeDataCache.set(key, value);
} else {
break;
}
}
}
export { carrier, clearCache, geocoder, getCacheSize, setCacheSize, timezones };