Files
rdapper/scripts/generate-countries.mjs
jake 3595e5b42c refactor: replace runtime Intl.DisplayNames with a static CLDR-generated country table
- Add `scripts/generate-countries.mjs` to enumerate all current ISO 3166-1 alpha-2 codes via CLDR and emit `src/lib/countries-data.ts`; retired, exceptionally-reserved, and CLDR-only pseudo codes are explicitly excluded, XK (Kosovo) is kept
- Replace the live `Intl.DisplayNames` calls in `countries.ts` with a direct lookup against the generated `COUNTRY_NAMES` record, eliminating variance between Node/ICU versions
- Build the reverse `nameToCode` map from `COUNTRY_NAMES` entries instead of a double-nested loop over the alphabet
- Fix `countryCodeFromName` to fall through to `ALIASES` for two-letter inputs that aren't valid codes (e.g. `"UK"` → `"GB"`)
- Add `myanmar` / `"myanmar burma"` aliases so the CLDR-style name and the legacy WHOIS variant both resolve to `MM`
- Extend `countries.test.ts` to assert pinned names, XK presence, retired/reserved code exclusion, and `UK` alias behaviour
2026-09-19 23:14:43 -04:00

65 lines
1.6 KiB
JavaScript

// Regenerates src/lib/countries-data.ts from the local runtime's ICU (CLDR) region names.
// Usage: node scripts/generate-countries.mjs
import { writeFileSync } from "node:fs";
const dn = new Intl.DisplayNames(["en"], { type: "region" });
// CLDR also knows reserved, retired and pseudo codes that aren't current ISO 3166-1 countries.
// Keep only current ISO 3166-1 alpha-2 codes plus XK (Kosovo, the de-facto user-assigned code).
const EXCLUDE = new Set([
"AC",
"CP",
"DG",
"EA",
"EU",
"EZ",
"IC",
"TA",
"UN", // exceptionally reserved
"AN",
"BU",
"CQ",
"CS",
"DD",
"DY",
"FX",
"HV",
"NH",
"RH",
"SU",
"TP",
"VD",
"YD",
"YU",
"ZR", // retired
"UK", // reserved for GB; WHOIS "UK" is handled as an alias in countries.ts
"QO",
"XA",
"XB", // CLDR-only pseudo territories
]);
const entries = [];
for (let a = 65; a <= 90; a++) {
for (let b = 65; b <= 90; b++) {
const code = String.fromCharCode(a, b);
if (EXCLUDE.has(code)) continue;
let name;
try {
name = dn.of(code);
} catch {
continue;
}
if (!name || name === code || name === "Unknown Region") continue;
entries.push([code, name]);
}
}
const body = entries.map(([c, n]) => ` ${c}: ${JSON.stringify(n)},`).join("\n");
writeFileSync(
new URL("../src/lib/countries-data.ts", import.meta.url),
`// Generated by scripts/generate-countries.mjs from CLDR (Unicode license). Do not edit by hand.\n` +
`export const COUNTRY_NAMES: Record<string, string> = {\n${body}\n};\n`,
);
console.log(
`Wrote ${entries.length} countries (Node ${process.version}, ICU ${process.versions.icu}, CLDR ${process.versions.cldr})`,
);