UNPKG

powr-sdk-api

Version:

Shared API core library for PowrStack projects. Zero dependencies - works with Express, Next.js API routes, and other frameworks. All features are optional and install only what you need.

112 lines (110 loc) 3.9 kB
"use strict"; const { parsePhoneNumberFromString, getCountries, getCountryCallingCode } = require('libphonenumber-js'); const DEFAULT_COUNTRY = 'IN'; const DEFAULT_COUNTRY_CODE = '91'; const CALLING_CODE_TO_COUNTRY = { '91': 'IN', '1': 'US', '44': 'GB', '971': 'AE', '65': 'SG', '61': 'AU' }; function digitsOnly(value) { return (value || '').replace(/\D/g, ''); } function parsePhone(input, defaultCountry = DEFAULT_COUNTRY) { var _parsed, _parsed2, _parsed3; if (!input || typeof input !== 'string' || input.includes('@')) return null; const trimmed = input.trim(); if (!trimmed) return null; let parsed = parsePhoneNumberFromString(trimmed); if (!((_parsed = parsed) !== null && _parsed !== void 0 && _parsed.isValid())) { parsed = parsePhoneNumberFromString(trimmed, defaultCountry); } if (!((_parsed2 = parsed) !== null && _parsed2 !== void 0 && _parsed2.isValid()) && !trimmed.startsWith('+')) { parsed = parsePhoneNumberFromString(`+${digitsOnly(trimmed)}`); } return (_parsed3 = parsed) !== null && _parsed3 !== void 0 && _parsed3.isValid() ? parsed : null; } function normalizePhone(input, defaultCountry = DEFAULT_COUNTRY) { if (!input || typeof input !== 'string') return ''; if (input.includes('@')) return input.trim(); const parsed = parsePhone(input, defaultCountry); return parsed ? parsed.format('E.164') : ''; } /** * Normalize a phone for DB storage. When the input has trailing junk * (e.g. "7903658469 welcome"), extracts digits and parses those. * Returns null when no valid phone can be derived — never returns raw input. */ function coercePhoneForStorage(input, defaultCountry = DEFAULT_COUNTRY) { if (!input || typeof input !== 'string') return null; if (input.includes('@')) return null; const trimmed = input.trim(); if (!trimmed) return null; const direct = normalizePhone(trimmed, defaultCountry); if (direct) return direct; const digits = digitsOnly(trimmed); if (!digits) return null; return normalizePhone(digits, defaultCountry) || null; } function isValidPhone(input, defaultCountry = DEFAULT_COUNTRY) { if (!input || typeof input !== 'string' || input.includes('@')) return false; return !!parsePhone(input, defaultCountry); } function getLocalPhoneNumber(input, defaultCountry = DEFAULT_COUNTRY) { const parsed = parsePhone(input, defaultCountry); return parsed ? parsed.nationalNumber : digitsOnly(input).slice(-15); } function legacyIndiaVariants(input) { const digits = digitsOnly(input); if (!digits) return []; const variants = new Set(); if (digits.length === 10) { variants.add(digits); variants.add(`91${digits}`); variants.add(`+91${digits}`); variants.add(`0${digits}`); } if (digits.length === 12 && digits.startsWith('91')) { const local = digits.slice(2); variants.add(local); variants.add(`+${digits}`); variants.add(digits); variants.add(`0${local}`); } return [...variants]; } function getPhoneLookupVariants(input, defaultCountry = DEFAULT_COUNTRY) { if (!input || typeof input !== 'string') return []; if (input.includes('@')) return [input.trim()]; const variants = new Set([input.trim()]); const parsed = parsePhone(input, defaultCountry); if (parsed) { const e164 = parsed.format('E.164'); variants.add(e164); variants.add(e164.replace(/^\+/, '')); variants.add(parsed.nationalNumber); variants.add(`+${parsed.countryCallingCode}${parsed.nationalNumber}`); variants.add(`${parsed.countryCallingCode}${parsed.nationalNumber}`); } legacyIndiaVariants(input).forEach(v => variants.add(v)); return [...variants].filter(Boolean); } module.exports = { DEFAULT_COUNTRY, DEFAULT_COUNTRY_CODE, normalizePhone, coercePhoneForStorage, getLocalPhoneNumber, isValidPhone, getPhoneLookupVariants, parsePhone, getCountries, getCountryCallingCode };