# 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` 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 ```ts 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 ```ts 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>( (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` Return the full 209-entry country map. - **Returns:** A `Record` — 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` 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"`).