Files
skills/docs/localization/i18n/locale-data/src/countries/countries.md
2026-05-29 08:20:56 +01:00

4.4 KiB

countries

(no submodules)

Purpose

Provides typed lookup functions over the static ISO 3166-1 alpha-2 country dataset (209 entries). The module is designed for high-frequency read access — data is held in a single frozen object (COUNTRIES_DATA) and all lookups run in O(1) or O(n) time with zero I/O. Every getCountry call emits an OTel counter increment, enabling production observability for cache-hit analysis and anomaly detection on invalid code injection attempts.

Features

  • getCountry(code) — O(1) lookup by ISO 3166-1 alpha-2 code; throws a typed LocaleDataError for unknown codes.
  • getAllCountries() — Returns the full Record<string, CountryItem> reference; O(1), no copy allocation.
  • getCountriesByContinent(continent) — Filters by two-letter continent code ("EU", "AS", "AF", "NA", "SA", "OC", "AN"); returns empty array for unknown codes.
  • getCountriesByCurrency(currency) — Matches against comma-separated ISO 4217 currency codes in each entry (e.g. "CHE,CHF,CHW"); returns empty array for unknown currencies.
  • OTel instrumentation — locale_data.country.lookups counter with result: "found" | "not_found".
  • Zod schemas — CountryCodeSchema (2-char uppercase) and re-exported CountryItemSchema.

Usage: Basic Example

import { getCountry, getAllCountries } from "@suaveplan/locale-data/countries";

// Look up a single country
const us = getCountry("US");
console.log(us.name);    // "United States"
console.log(us.phone);   // "1"
console.log(us.emoji);   // "🇺🇸"

// Get all countries
const all = getAllCountries();
console.log(Object.keys(all).length); // 209

Usage: Advanced Example

import {
  getCountry,
  getCountriesByContinent,
  getCountriesByCurrency,
} from "@suaveplan/locale-data/countries";
import { LocaleDataError, LOCALE_DATA_CODES } from "@suaveplan/locale-data/errors";

// Error handling
try {
  const country = getCountry("ZZ");
} catch (err) {
  if (err instanceof LocaleDataError && err.code === LOCALE_DATA_CODES["COUNTRY.NOT_FOUND"]) {
    console.warn("Unknown country code");
  }
}

// Filter by continent
const europeanCountries = getCountriesByContinent("EU");
console.log(europeanCountries.length); // ~40

// Find all Eurozone members (use single-currency entries + multi-currency)
const eurozoneMembers = getCountriesByCurrency("EUR");
console.log(eurozoneMembers.map((c) => c.name));

// Group by continent
import { getAllCountries } from "@suaveplan/locale-data/countries";
const byContinent = Object.entries(getAllCountries()).reduce<Record<string, string[]>>(
  (acc, [code, c]) => {
    (acc[c.continent] ??= []).push(code);
    return acc;
  },
  {}
);

API Reference

getCountry(code: string): CountryItem

Look up a country by its ISO 3166-1 alpha-2 code.

  • Parameters: code — case-sensitive two-letter code (e.g. "US", "DE").
  • Returns: The matching CountryItem.
  • Throws: LocaleDataError (LOCALE_DATA/COUNTRY.NOT_FOUND) when the code is not found.
  • OTel: Increments locale_data.country.lookups with result: "found" or "not_found".

getAllCountries(): Record<string, CountryItem>

Return the full 209-entry country map.

  • Returns: A Record<string, CountryItem> — the same reference each call.
  • Note: Do not mutate the returned object.

getCountriesByContinent(continent: string): CountryItem[]

Filter countries by continent code.

  • Parameters: continent — "EU" | "AS" | "AF" | "NA" | "SA" | "OC" | "AN".
  • Returns: Array of matching CountryItem values; empty array for unknown codes.

getCountriesByCurrency(currency: string): CountryItem[]

Filter countries by ISO 4217 currency code.

  • Parameters: currency — e.g. "EUR", "USD", "CHF".
  • Returns: Array of matching CountryItem values; handles comma-separated multi-currency entries; empty array if no match.

Implementation Notes

Data is stored in countries.data.ts as a plain Record<string, CountryItem> const to keep the implementation file under the 300-line hard limit. The data file is excluded from coverage measurement because it contains no executable logic — only export const. The getCountriesByCurrency function splits on commas to support countries with composite currency fields like Switzerland ("CHE,CHF,CHW"), Bolivia ("BOB,BOV"), and Cuba ("CUC,CUP").