@callsy/locale
v1.2.0
Published
Country locale data: from phone numbers to flags.
Downloads
74
Readme
@callsy/locale
A comprehensive locale data library for Node.js and TypeScript. Work seamlessly with countries, phone numbers, and languages using ISO standards, with built-in emoji support and zero runtime dependencies.
Features
- Three Powerful Classes: Work with countries, phone numbers, and languages through intuitive, fluent APIs.
- Zero Runtime Dependencies: Lightweight and secure with no external dependencies.
- 200+ Countries: Comprehensive coverage of ISO 3166-1 alpha-2 country codes with names, flags, and metadata.
- 200+ Languages: Full support for ISO 639 language codes including regional variants (e.g., en-US, fr-CA).
- 300+ US Area Codes: Detailed mapping of NANP area codes to US states for precise location identification.
- E.164 Phone Validation: Automatic validation and formatting of international phone numbers.
- Flag Emoji Support: Built-in flag emojis for countries and languages for rich UI experiences.
- Bidirectional Lookups: Convert seamlessly between codes, names, and related entities.
- TypeScript Ready: Fully typed with comprehensive IntelliSense support for a superior developer experience.
Installation
npm install @callsy/localeQuick Start
Work with countries, phone numbers, and languages using clean, intuitive APIs.
import { Country, Phone, Language } from '@callsy/locale'
// 1. Working with Countries
const usa = new Country('US')
console.log(usa.name()) // "United States"
console.log(usa.name({ includeEmoji: true })) // "🇺🇸 United States"
console.log(usa.emoji()) // "🇺🇸"
console.log(usa.continent()) // "NA"
console.log(usa.languages()) // ["en"]
// Or create from name
const france = Country.fromName('France')
console.log(france.iso2()) // "FR"
// 2. Working with Phone Numbers
const phone = new Phone('+1-415-555-0123')
console.log(phone.value()) // "+14155550123"
console.log(phone.country()) // "US"
console.log(phone.state()) // "CA"
console.log(phone.isE164()) // true
// Extract country information from phone
const phoneCountry = new Country(phone.country())
console.log(phoneCountry.name({ includeEmoji: true })) // "🇺🇸 United States"
// 3. Working with Languages
const english = new Language('en')
console.log(english.name()) // "English"
console.log(english.countries()) // ["US", "GB", "CA", ...]
// Regional language codes
const usEnglish = new Language('en-US')
console.log(usEnglish.name()) // "English (United States)"
// Or create from name
const spanish = Language.fromName('Spanish')
console.log(spanish.code()) // "es"Core Concepts
Working with Countries
The Country class provides comprehensive information about any country using its ISO 3166-1 alpha-2 code.
Creating a Country Instance:
// From ISO2 code (case-insensitive, whitespace-tolerant)
const usa = new Country('US')
const uk = new Country(' gb ') // Automatically normalized to "GB"
// From country name (case-sensitive, exact match required)
const canada = Country.fromName('Canada')Getting Country Information:
const japan = new Country('JP')
japan.iso2() // "JP"
japan.name() // "Japan"
japan.name({ includeEmoji: true }) // "🇯🇵 Japan"
japan.name({ includeCode: true }) // "Japan (JP)"
japan.name({ includeEmoji: true, includeCode: true }) // "🇯🇵 Japan (JP)"
japan.emoji() // "🇯🇵"
japan.continent() // "AS"
japan.languages() // ["ja"]Comparing Countries:
const us1 = new Country('US')
const us2 = new Country('us')
const gb = new Country('GB')
us1.equals(us2) // true
us1.equals(gb) // falseAccessing Raw Data:
// Access all static mappings directly
Country.isoToName['US'] // "United States"
Country.nameToIso['France'] // "FR"
Country.isoToFlag['DE'] // "🇩🇪"
Country.isoToCont['BR'] // "SA"
Country.isoToLang['CH'] // ["de", "fr", "it", "rm"]Working with Phone Numbers
The Phone class validates and extracts information from international phone numbers following the E.164 format.
Creating a Phone Instance:
// Automatically cleans and formats various inputs
const phone1 = new Phone('+1-415-555-0123') // Cleans to +14155550123
const phone2 = new Phone('1 (415) 555-0123') // Adds + if missing
const phone3 = new Phone('+442071234567') // UK number
// All non-digit characters are removed
const phone4 = new Phone('+1abc234def5678') // Becomes +12345678Extracting Phone Information:
const phone = new Phone('+14155551234')
phone.value() // "+14155551234"
phone.digits() // "14155551234"
phone.isE164() // true
phone.country() // "US" (extracts country from prefix)
phone.state() // "CA" (US-specific: extracts state from area code)
// For non-US numbers, state() returns null
const ukPhone = new Phone('+442071234567')
ukPhone.country() // "GB"
ukPhone.state() // nullUnderstanding NANP (North American Numbering Plan):
// The +1 prefix is shared by multiple countries
const nanpPhone = new Phone('+14165551234')
nanpPhone.country() // "US" (returns first match in NANP countries)
// Access all NANP countries
Phone.phoneToIso[1] // ["US", "CA", "AG", "AI", ...]US State Extraction:
// Extract US state from area code
const nyPhone = new Phone('+12125551234')
nyPhone.state() // "NY"
const caPhone = new Phone('+14155551234')
caPhone.state() // "CA"
// Access all US area codes
Phone.usAreaCodes['212'] // "NY"
Phone.usAreaCodes['415'] // "CA"Comparing Phone Numbers:
const phone1 = new Phone('+14155551234')
const phone2 = new Phone('1-415-555-1234') // Different format, same number
const phone3 = new Phone('+14155559999')
phone1.equals(phone2) // true (normalized comparison)
phone1.equals(phone3) // falseAccessing Raw Data:
// Access static mappings
Phone.isoToPhone['US'] // [1]
Phone.isoToPhone['GB'] // [44]
Phone.phoneToIso[1] // ["US", "CA", "AG", "AI", ...]
Phone.phoneCodes // [1268, 1264, ..., 44, 1] (sorted longest to shortest)
Phone.usAreaCodes['212'] // "NY"Working with Languages
The Language class handles ISO 639 language codes, including support for regional variants.
Creating a Language Instance:
// Basic language code (case-insensitive, whitespace-tolerant)
const english = new Language('en')
const french = new Language(' FR ') // Normalized to "fr"
// Regional variants (automatically formatted)
const usEnglish = new Language('en-us') // Normalized to "en-US"
const caFrench = new Language('fr-CA') // "fr-CA"
// From language name (case-sensitive, exact match)
const spanish = Language.fromName('Spanish')
const german = Language.fromName('German (Germany)') // Regional variantGetting Language Information:
const spanish = new Language('es')
spanish.code() // "es"
spanish.name() // "Spanish"
spanish.name({ includeEmoji: true }) // "🇪🇸 Spanish"
spanish.name({ includeCode: true }) // "Spanish (es)"
spanish.name({ includeEmoji: true, includeCode: true }) // "🇪🇸 Spanish (es)"
spanish.emoji() // "🇪🇸" (or "🌐" if no flag)
spanish.countries() // ["ES", "MX", "AR", ...] countries where Spanish is spokenWorking with Regional Variants:
const usEnglish = new Language('en-US')
const gbEnglish = new Language('en-GB')
usEnglish.name() // "English (United States)"
gbEnglish.name() // "English (United Kingdom)"
usEnglish.code() // "en-US"
gbEnglish.code() // "en-GB"
// Both regional variants share the same base language
const baseEnglish = new Language('en')
baseEnglish.name() // "English"Comparing Languages:
const en1 = new Language('en')
const en2 = new Language('EN')
const es = new Language('es')
en1.equals(en2) // true
en1.equals(es) // false
// Regional variants are different
const enUS = new Language('en-US')
const enGB = new Language('en-GB')
enUS.equals(enGB) // falseAccessing Raw Data:
// Access static mappings
Language.codeToName['en'] // "English"
Language.nameToCode['Spanish'] // "es"
Language.codeToFlag['fr'] // "🇫🇷"
Language.codeToCountries['en'] // ["US", "GB", "CA", ...] countries where English is spokenCommon Patterns
Bidirectional Lookups
Convert seamlessly between different representations:
// Country: Code ↔ Name
const countryCode = Country.nameToIso['United States'] // "US"
const countryName = Country.isoToName['US'] // "United States"
// Language: Code ↔ Name
const langCode = Language.nameToCode['English'] // "en"
const langName = Language.codeToName['en'] // "English"
// Phone: Country Code ↔ Phone Prefix
const phonePrefix = Phone.isoToPhone['US'] // [1]
const countries = Phone.phoneToIso[44] // ["GB"]Cross-Class Integration
Combine classes for powerful workflows:
// Extract country from phone number and get full details
const phone = new Phone('+442071234567')
const country = new Country(phone.country())
console.log(country.name({ includeEmoji: true })) // "🇬🇧 United Kingdom"
console.log(country.languages()) // ["en", "cy", "gd"]
// Get languages for a country and display them
const japan = new Country('JP')
const languages = japan.languages().map(code => {
const lang = new Language(code)
return lang.name({ includeEmoji: true })
})
console.log(languages) // ["🇯🇵 Japanese"]
// Validate phone number matches expected country
const usPhone = new Phone('+14155551234')
const usCountry = new Country('US')
const isMatch = usPhone.country() === usCountry.iso2() // trueError Handling
All classes throw descriptive errors for invalid inputs:
// Invalid country code
try {
new Country('XX')
} catch (error) {
// Error: "Unrecognised country code. Make sure you provide a valid ISO2 country code. Current value: "XX"."
}
// Invalid phone format
try {
new Phone('+123456789012345678') // Exceeds 15 digits
} catch (error) {
// Error: "Phone number must be in E164 format (e.g., +1234567890). Current value: "..."."
}
// Invalid language code
try {
new Language('xyz')
} catch (error) {
// Error: "Unrecognised language code. Make sure you provide a valid ISO 639 language code. Current value: "xyz"."
}
// Empty values
try {
new Country('')
} catch (error) {
// Error: "You must provide a country code. Value can not be empty. Current value: ""."
}License
ISC
