Kuni国

@johnmorrisdotca/kuni 1.3.0 · 8 entry points · 72 exports

@johnmorrisdotca/kuni

Continent continentName CONTINENTS countries CountriesOptions country Country COUNTRY_CODES countryByName CountryCode countryName CountryNameOptions CountryOrder flag fold isCountryCode Language LANGUAGES Subdivision SubdivisionType subregionName VERSION

type Continent

type Continent = (typeof CONTINENTS)[number];

A continent's two letters: "AF", "AN", "AS", "EU", "NA", "OC" or "SA".

function continentName

continentName: (continent: Continent, language?: Language) => string | null

A continent's name, from CLDR.

  • continent One of the seven two-letter continents.
  • language "en" (the default) or "ja".

Returns The name; `null` for anything that is not one of the seven.

Example
import { continentName } from "@johnmorrisdotca/kuni";

continentName("AS");         // "Asia"
continentName("AS", "ja");   // "アジア"

const CONTINENTS

CONTINENTS: readonly ["AF", "AN", "AS", "EU", "NA", "OC", "SA"]

The seven continents, as two letters: Africa, Antarctica, Asia, Europe, North America, Oceania, South America.

Example
import { CONTINENTS, continentName } from "@johnmorrisdotca/kuni";

CONTINENTS.length; // 7
CONTINENTS.map((one) => continentName(one, "ja"))[0]; // "アフリカ"

function countries

countries: (options?: CountriesOptions) => readonly Country[]

Every country: the 249 ISO 3166-1 codes and Kosovo (XK). order: "en" sorts by the English name folded (accents and case set aside); order: "ja" by the Japanese name in kana, its reading where it is written in kanji, in plain kana order (not a full Japanese collation).

  • options `order`: "code" (the default), "en" or "ja".

Returns The 250 countries, the list and its objects frozen and shared.

Example
import { countries } from "@johnmorrisdotca/kuni";

countries().length;                          // 250
countries({ order: "en" })[0].name.en;       // "Afghanistan"
countries({ order: "ja" })[0].name.ja;       // "アイスランド"

type CountriesOptions

interface CountriesOptions

What countries() may be asked.

order?: CountryOrder | undefined
"code" (the default) is alpha-2 order; "en" and "ja" are by name, as `countries` says.

function country

country: (code: string) => Country | null

One country by its code.

  • code Alpha-2 ("JP", "jp"), alpha-3 ("JPN") or numeric ("392").

Returns The country, frozen; `null` for anything that is not one of the 250 codes.

Example
import { country } from "@johnmorrisdotca/kuni";

country("JP")?.name.en;     // "Japan"
country("jpn")?.alpha2;     // "JP"
country("392")?.name.ja;    // "日本"
country("JP")?.capital;     // { "en": "Tokyo", "ja": "東京" }
country("XX");              // null

type Country

interface Country

A country, or a territory with an ISO 3166-1 code of its own, as the lookups hand it out (frozen).

alpha2: string
ISO 3166-1 alpha-2, "JP"
alpha3: string
ISO 3166-1 alpha-3, "JPN"
numeric: string
ISO 3166-1 numeric, three digits, "392"
kind: "iso" | "user"
"user" for a user-assigned code in common use: Kosovo, XK
name: { en: string; ja: string; local?: string; }
CLDR's names; local is the country's own name, where it differs
shortName?: { en?: string; ja?: string; } | undefined
CLDR's short form: "US" and アメリカ for the United States
reading?: string | undefined
The Japanese name in hiragana, only where the name is written in kanji
flag: string
The flag emoji: the two regional-indicator letters of alpha2
continent: "AF" | "AN" | "AS" | "EU" | "NA" | "OC" | "SA"
The continent it is in, in the seven-continent model: "AS".
subregion?: string | undefined
The UN M49 subregion, three digits: "030" is Eastern Asia
callingCode?: string | undefined
The ITU country calling code, "+81"; "+1" for every member of the North American plan
currency?: string[] | undefined
ISO 4217 codes of the currencies in use now, from CLDR: ["JPY"]
tld?: string | undefined
The country-code top-level domain without its dot: "jp", and "uk" for GB
capital?: { en: string; ja: string; } | undefined
The capital's name: English from countries-list, Japanese from Wikidata
zones?: string[] | undefined
IANA time zones, from zone.tab, in its order: ["Asia/Tokyo"]
languages?: string[] | undefined
ISO 639-1 codes of the languages spoken, most used first
subdivisionType?: "atoll" | "autonomous-community" | "autonomous-region" | "borough" | "canton" | "capital-district" | "circuit" | "city" | "council-area" | "country" | "county" | "department" | "district" | "division" | "emirate" | "governorate" | "island" | "krai" | "metropolis" | "municipality" | "oblast" | "parish" | "prefecture" | "principal-area" | "province" | "quarter" | "region" | "republic" | "special-administrative-region" | "state" | "territory" | "unitary-authority" | "urban-prefecture" | "voivodeship" | "zone" | undefined
The kind most of its first-level subdivisions are
aliases?: string[] | undefined
Other names people use for it, in either language: "Holland", "UK", 米国
ioc?: string | undefined
The International Olympic Committee's country code, three letters and not always the alpha-3: "JPN", "GER" for Germany (DEU), "SUI" for Switzerland (CHE). From Wikidata (P984). Absent for the countries with no National Olympic Committee.

const COUNTRY_CODES

COUNTRY_CODES: readonly ["AD", "AE", "AF", "AG", "AI", "AL", "AM", "AO", "AQ", "AR", "AS", "AT", "AU", "AW", "AX", "AZ", "BA", "BB", "BD", "BE", "BF", "BG", "BH", "BI", "BJ", "BL", "BM", "BN", "BO", "BQ", "BR", "BS", "BT", "BV", "BW", "BY", "BZ", "CA", "CC", "CD", "CF", "CG", "CH", "CI", "CK", "CL", "CM", "CN", "CO", "CR", "CU", "CV", "CW", "CX", "CY", "CZ", "DE", "DJ", "DK", "DM", "DO", "DZ", "EC", "EE", "EG", "EH"…

The 250 country codes: the 249 ISO 3166-1 alpha-2 codes and XK for Kosovo, in alphabetical order.

Example
import { COUNTRY_CODES } from "@johnmorrisdotca/kuni/codes";

COUNTRY_CODES.length;   // 250
COUNTRY_CODES[0];       // "AD"

function countryByName

countryByName: (text: string) => Country | null

A country from what somebody typed: its name or short name in English or Japanese ("Germany", ドイツ, どいつ), its own name ("Deutschland"), a name it is also known by ("Holland", "UK", 米国), or a code. Case, accents, width, kana and punctuation do not matter.

  • text What was typed.

Returns The country, frozen; `null` when nothing matches, never a near miss.

Example
import { countryByName } from "@johnmorrisdotca/kuni";

countryByName("ドイツ")?.alpha2;          // "DE"
countryByName("Holland")?.name.ja;        // "オランダ"
countryByName("USA")?.alpha2;           // "US"
countryByName("cote d'ivoire")?.alpha2;   // "CI"
countryByName("Narnia");                  // null

type CountryCode

type CountryCode = (typeof COUNTRY_CODES)[number];

One of the 250 country codes, as a type: "JP" | "US" | ...

function countryName

countryName: (code: string, language?: Language, options?: CountryNameOptions) => string | null

A country's name in English or Japanese.

  • code Any code `country()` takes.
  • language "en" (the default) or "ja".
  • options `short: true` for the short form where CLDR has one ("UK", アメリカ).

Returns The name; `null` for a code that is not a country, or a language that is not one of the two.

Example
import { countryName } from "@johnmorrisdotca/kuni";

countryName("US");                         // "United States"
countryName("US", "ja", { short: true });  // "アメリカ"
countryName("GB", "en", { short: true });  // "UK"
countryName("XX");                         // null

type CountryNameOptions

interface CountryNameOptions

What countryName() may be asked.

short?: boolean | undefined
The short form where CLDR has one ("UK", アメリカ), the full name otherwise.

type CountryOrder

type CountryOrder = "code" | "en" | "ja";

The order countries() lists them in: "code" (alpha-2), "en" (by English name) or "ja" (by Japanese name, in kana).

function flag

flag: (code: string) => string | null

The flag of a country as an emoji: two regional-indicator letters, which most systems draw as the flag and some (Windows) as the two letters. Write the country's name beside it.

  • code Any code `country()` takes.

Returns The emoji; `null` for a code that is not a country.

Example
import { flag } from "@johnmorrisdotca/kuni";

flag("JP");   // "🇯🇵"
flag("XX");   // null

function fold

fold: (text: string) => string

What two ways of typing a name have in common: width (full-width letters to ASCII, half-width katakana to full), case, accents (except the two marks that make が and ぱ), katakana to hiragana, apostrophes dropped, and every other run of punctuation or space to one space. The lookups compare names folded, and so can a page.

  • text Any text.

Returns The text folded; "" for text that is only punctuation or space.

Example
import { fold } from "@johnmorrisdotca/kuni";

fold("Côte d'Ivoire");   // "cote divoire"
fold("USA");           // "usa"
fold("ドイツ");           // "どいつ"

function isCountryCode

isCountryCode: (value: unknown) => value is CountryCode

Whether a value is one of the 250 codes exactly as ISO writes it: two capital letters ("JP", and "XK" for Kosovo). Lower case is not a code here; country() in the main entry is the forgiving one.

  • value Anything.

Returns True for one of the 250 codes; false for anything else, a lower-case code included.

Example
import { isCountryCode } from "@johnmorrisdotca/kuni/codes";

isCountryCode("JP");   // true
isCountryCode("jp");   // false
isCountryCode("XX");   // false

type Language

type Language = (typeof LANGUAGES)[number];

A language every name is kept in: "en" or "ja".

const LANGUAGES

LANGUAGES: readonly ["en", "ja"]

The two languages every name is kept in.

Example
import { LANGUAGES } from "@johnmorrisdotca/kuni";

LANGUAGES; // ["en", "ja"]

type Subdivision

interface Subdivision

A subdivision of a country (a state, a province, a prefecture), with its ISO 3166-2 code, as the lookups hand it out (frozen).

code: string
ISO 3166-2, always in full: "JP-13", "CA-ON", "US-NY"
country: string
ISO 3166-1 alpha-2 of the country it is in: "JP"
shortCode: string
The part after the hyphen: "13", "ON", "NY"
type: "atoll" | "autonomous-community" | "autonomous-region" | "borough" | "canton" | "capital-district" | "circuit" | "city" | "council-area" | "country" | "county" | "department" | "district" | "division" | "emirate" | "governorate" | "island" | "krai" | "metropolis" | "municipality" | "oblast" | "parish" | "prefecture" | "principal-area" | "province" | "quarter" | "region" | "republic" | "special-administrative-region" | "state" | "territory" | "unitary-authority" | "urban-prefecture" | "voivodeship" | "zone" | null
What kind of place it is; null when no source says
level: 2 | 1 | 3
1 for a country's first division; 2 and 3 for those inside one (France's departments)
parent?: string | undefined
The code of the subdivision it is inside, for levels 2 and 3: "FR-ARA" for "FR-01"
name: { en: string; ja: string | null; }
ja is null where no source has a Japanese name, never a guess
reading?: string | undefined
The name in hiragana, for Japan's prefectures: "とうきょうと"

type SubdivisionType

type SubdivisionType = (typeof SUBDIVISION_TYPES)[number];

A kind of subdivision, in kebab case: "prefecture", "state", "autonomous-community".

function subregionName

subregionName: (subregion: string, language?: Language) => string | null

A UN M49 subregion's name, from CLDR.

  • subregion Three digits, as `Country.subregion` gives it: "030".
  • language "en" (the default) or "ja".

Returns The name; `null` for a code no country is in.

Example
import { subregionName } from "@johnmorrisdotca/kuni";

subregionName("030");         // "Eastern Asia"
subregionName("030", "ja");   // "東アジア"

const VERSION

VERSION: "1.3.0"

The package's version, the same as package.json's.

Example
import { VERSION } from "@johnmorrisdotca/kuni";

console.log(`kuni ${VERSION}`);

@johnmorrisdotca/kuni/codes

COUNTRY_CODES CountryCode isCountryCode

const COUNTRY_CODES

COUNTRY_CODES: readonly ["AD", "AE", "AF", "AG", "AI", "AL", "AM", "AO", "AQ", "AR", "AS", "AT", "AU", "AW", "AX", "AZ", "BA", "BB", "BD", "BE", "BF", "BG", "BH", "BI", "BJ", "BL", "BM", "BN", "BO", "BQ", "BR", "BS", "BT", "BV", "BW", "BY", "BZ", "CA", "CC", "CD", "CF", "CG", "CH", "CI", "CK", "CL", "CM", "CN", "CO", "CR", "CU", "CV", "CW", "CX", "CY", "CZ", "DE", "DJ", "DK", "DM", "DO", "DZ", "EC", "EE", "EG", "EH"…

The 250 country codes: the 249 ISO 3166-1 alpha-2 codes and XK for Kosovo, in alphabetical order.

Example
import { COUNTRY_CODES } from "@johnmorrisdotca/kuni/codes";

COUNTRY_CODES.length;   // 250
COUNTRY_CODES[0];       // "AD"

type CountryCode

type CountryCode = (typeof COUNTRY_CODES)[number];

One of the 250 country codes, as a type: "JP" | "US" | ...

function isCountryCode

isCountryCode: (value: unknown) => value is CountryCode

Whether a value is one of the 250 codes exactly as ISO writes it: two capital letters ("JP", and "XK" for Kosovo). Lower case is not a code here; country() in the main entry is the forgiving one.

  • value Anything.

Returns True for one of the 250 codes; false for anything else, a lower-case code included.

Example
import { isCountryCode } from "@johnmorrisdotca/kuni/codes";

isCountryCode("JP");   // true
isCountryCode("jp");   // false
isCountryCode("XX");   // false

@johnmorrisdotca/kuni/subdivisions

allSubdivisions Level subdivision Subdivision SUBDIVISION_TYPES subdivisionByName SubdivisionByNameOptions subdivisionByShortCode subdivisions subdivisionsByName SubdivisionsOptions SubdivisionType subdivisionTypeLabel

function allSubdivisions

allSubdivisions: () => readonly Subdivision[]

Every subdivision of every country, every level, in code order.

Returns The 5,050 subdivisions, frozen and shared.

Example
import { allSubdivisions } from "@johnmorrisdotca/kuni/subdivisions";

allSubdivisions().length;   // 5050

type Level

type Level = 1 | 2 | 3 | "all";

A level of subdivision: 1 for a country's first division, 2 and 3 for those inside one, or "all".

function subdivision

subdivision: (code: string) => Subdivision | null

One subdivision by its ISO 3166-2 code.

  • code The full code, either case: "JP-13", "ca-on".

Returns The subdivision, frozen; `null` for anything that is not one.

Example
import { subdivision } from "@johnmorrisdotca/kuni/subdivisions";

subdivision("JP-13")?.name.ja;   // "東京都"
subdivision("ca-on")?.name.en;   // "Ontario"
subdivision("FR-75C")?.parent;   // "FR-IDF"
subdivision("XX-99");            // null

type Subdivision

interface Subdivision

A subdivision of a country (a state, a province, a prefecture), with its ISO 3166-2 code, as the lookups hand it out (frozen).

code: string
ISO 3166-2, always in full: "JP-13", "CA-ON", "US-NY"
country: string
ISO 3166-1 alpha-2 of the country it is in: "JP"
shortCode: string
The part after the hyphen: "13", "ON", "NY"
type: "atoll" | "autonomous-community" | "autonomous-region" | "borough" | "canton" | "capital-district" | "circuit" | "city" | "council-area" | "country" | "county" | "department" | "district" | "division" | "emirate" | "governorate" | "island" | "krai" | "metropolis" | "municipality" | "oblast" | "parish" | "prefecture" | "principal-area" | "province" | "quarter" | "region" | "republic" | "special-administrative-region" | "state" | "territory" | "unitary-authority" | "urban-prefecture" | "voivodeship" | "zone" | null
What kind of place it is; null when no source says
level: 2 | 1 | 3
1 for a country's first division; 2 and 3 for those inside one (France's departments)
parent?: string | undefined
The code of the subdivision it is inside, for levels 2 and 3: "FR-ARA" for "FR-01"
name: { en: string; ja: string | null; }
ja is null where no source has a Japanese name, never a guess
reading?: string | undefined
The name in hiragana, for Japan's prefectures: "とうきょうと"

const SUBDIVISION_TYPES

SUBDIVISION_TYPES: readonly ["atoll", "autonomous-community", "autonomous-region", "borough", "canton", "capital-district", "circuit", "city", "council-area", "country", "county", "department", "district", "division", "emirate", "governorate", "island", "krai", "metropolis", "municipality", "oblast", "parish", "prefecture", "principal-area", "province", "quarter", "region", "republic", "special-administrative-region…

The kinds of subdivision, in kebab case. Most are read from what Wikidata says each place is an instance of; Japan's four come from the last character of the prefecture's name.

Example
import { SUBDIVISION_TYPES } from "@johnmorrisdotca/kuni/subdivisions";

SUBDIVISION_TYPES.includes("prefecture"); // true

function subdivisionByName

subdivisionByName: (text: string, options?: SubdivisionByNameOptions) => Subdivision | null

The one subdivision a typed name means. When the name is at more than one level, the highest level wins (a region over a department of the same name).

  • text What was typed: "Ontario", オンタリオ州, オンタリオ.
  • options `country` and `level`, to narrow the search.

Returns The subdivision, frozen; `null` when nothing matches, or when the name is still more than one place (Punjab is in India and in Pakistan): name the country.

Example
import { subdivisionByName } from "@johnmorrisdotca/kuni/subdivisions";

subdivisionByName("オンタリオ州", { country: "CA" })?.code;   // "CA-ON"
subdivisionByName("Punjab");                                 // null
subdivisionByName("Punjab", { country: "PK" })?.code;        // "PK-PB"

type SubdivisionByNameOptions

interface SubdivisionByNameOptions

What subdivisionByName() and subdivisionsByName() may be narrowed to.

country?: string | undefined
Only this country's subdivisions (alpha-2, either case).
level?: Level | undefined
Only this level; "all", the default, looks at every level.

function subdivisionByShortCode

subdivisionByShortCode: (countryCode: string, shortCode: string) => Subdivision | null

One subdivision by its country and the part of its code after the hyphen.

  • countryCode An alpha-2 code, either case.
  • shortCode The part after the hyphen: "ON", "13".

Returns The subdivision, frozen; `null` where the two make no code.

Example
import { subdivisionByShortCode } from "@johnmorrisdotca/kuni/subdivisions";

subdivisionByShortCode("CA", "ON")?.code;   // "CA-ON"
subdivisionByShortCode("JP", "99");         // null

function subdivisions

subdivisions: (countryCode: string, options?: SubdivisionsOptions) => readonly Subdivision[] | null

A country's subdivisions, in code order: the first level unless level asks for another or for "all".

  • countryCode An alpha-2 code, either case.
  • options `level`: 1 (the default), 2, 3 or "all".

Returns The list, frozen; an empty list for a country that has none (Antarctica); `null` for a code that is not a country.

Example
import { subdivisions } from "@johnmorrisdotca/kuni/subdivisions";

subdivisions("JP")?.length;                    // 47
subdivisions("FR")?.length;                    // 26
subdivisions("FR", { level: "all" })?.length;  // 124
subdivisions("XX");                            // null

function subdivisionsByName

subdivisionsByName: (text: string, options?: SubdivisionByNameOptions) => readonly Subdivision[]

Every subdivision a typed name could be, in code order: its English or Japanese name, its Japanese name without the word for its kind (オンタリオ, 東京), a prefecture's reading, or its full code. Folded as fold folds, so case, accents, width and kana do not matter.

  • text What was typed.
  • options `country` and `level`, to narrow the search.

Returns The subdivisions it could be, frozen; an empty list for none.

Example
import { subdivisionsByName } from "@johnmorrisdotca/kuni/subdivisions";

subdivisionsByName("Punjab").map((one) => one.code);   // ["IN-PB", "PK-PB"]
subdivisionsByName("とうきょうと").map((one) => one.code); // ["JP-13"]
subdivisionsByName("Narnia");                          // []

type SubdivisionsOptions

interface SubdivisionsOptions

What subdivisions() may be asked.

level?: Level | undefined
1 (the default) for the first division only; 2 or 3 for one deeper level; "all" for every level.

type SubdivisionType

type SubdivisionType = (typeof SUBDIVISION_TYPES)[number];

A kind of subdivision, in kebab case: "prefecture", "state", "autonomous-community".

function subdivisionTypeLabel

subdivisionTypeLabel: (code: string, language?: Language) => string | null

The word for a kind of subdivision. Given a subdivision's code, its own kind ("JP-13" is "metropolis", 都); given a country's code, the kind most of its first-level subdivisions are ("JP" is "prefecture", 県). In English the kind's name with spaces; in Japanese the word the names of that kind in that country end in.

  • code A subdivision's code ("JP-13") or a country's alpha-2 code ("JP").
  • language "en" (the default) or "ja".

Returns The word; `null` where the kind is not known, or, in Japanese, where the names do not agree on one.

Example
import { subdivisionTypeLabel } from "@johnmorrisdotca/kuni/subdivisions";

subdivisionTypeLabel("JP-13");          // "metropolis"
subdivisionTypeLabel("JP-13", "ja");    // "都"
subdivisionTypeLabel("CA", "ja");       // "州"
subdivisionTypeLabel("XX");             // null

@johnmorrisdotca/kuni/load

loadSubdivisions Subdivision

function loadSubdivisions

loadSubdivisions: (countryCode: string) => Promise<readonly Subdivision[] | null>

The subdivisions of one country, every level, in code order: the same list as

  • countryCode An alpha-2 code, either case.

Returns The list, frozen; an empty list for a country that has none (Antarctica); `null` for a code that is not a country.

Example
import { loadSubdivisions } from "@johnmorrisdotca/kuni/load";

(await loadSubdivisions("CA"))?.length;         // 13
(await loadSubdivisions("jp"))?.[12].name.ja;   // "東京都"
await loadSubdivisions("AQ");                   // []
await loadSubdivisions("XX");                   // null

type Subdivision

interface Subdivision

A subdivision of a country (a state, a province, a prefecture), with its ISO 3166-2 code, as the lookups hand it out (frozen).

code: string
ISO 3166-2, always in full: "JP-13", "CA-ON", "US-NY"
country: string
ISO 3166-1 alpha-2 of the country it is in: "JP"
shortCode: string
The part after the hyphen: "13", "ON", "NY"
type: "atoll" | "autonomous-community" | "autonomous-region" | "borough" | "canton" | "capital-district" | "circuit" | "city" | "council-area" | "country" | "county" | "department" | "district" | "division" | "emirate" | "governorate" | "island" | "krai" | "metropolis" | "municipality" | "oblast" | "parish" | "prefecture" | "principal-area" | "province" | "quarter" | "region" | "republic" | "special-administrative-region" | "state" | "territory" | "unitary-authority" | "urban-prefecture" | "voivodeship" | "zone" | null
What kind of place it is; null when no source says
level: 2 | 1 | 3
1 for a country's first division; 2 and 3 for those inside one (France's departments)
parent?: string | undefined
The code of the subdivision it is inside, for levels 2 and 3: "FR-ARA" for "FR-01"
name: { en: string; ja: string | null; }
ja is null where no source has a Japanese name, never a guess
reading?: string | undefined
The name in hiragana, for Japan's prefectures: "とうきょうと"

@johnmorrisdotca/kuni/facts

allFacts CountryFacts distanceKm DrivingSide facts FACTS_READ HourCycle LatLon MeasurementSystem PaperSize WeekStart

function allFacts

allFacts: () => readonly CountryFacts[]

The facts about every country, in alpha-2 order: one object for each of the 250 codes, the list and its objects frozen and shared. Plain numbers and codes, so a build script can write them out as JSON as they are.

Returns Every country's facts.

Example
import { allFacts } from "@johnmorrisdotca/kuni/facts";

const crowded = allFacts()
  .filter((one) => one.population !== null && one.areaKm2 !== null)
  .sort((a, b) => b.population! / b.areaKm2! - a.population! / a.areaKm2!)[0].alpha2; // "MC"

type CountryFacts

interface CountryFacts

The facts about one country, from the /facts entry: plain numbers and codes, null where a source has none.

alpha2: string
ISO 3166-1 alpha-2, "JP"
population: number | null
People, from Wikidata; null where there is no permanent population (Antarctica)
populationYear: number | null
The year the population is for; null only where the figure has none (0, uninhabited)
areaKm2: number | null
Area in square kilometres, from Wikidata
areaYear: number | null
The year the area is for, where Wikidata says; most areas carry no year
areaOf: "whole" | "land" | null
"land" where the only figure is for the land alone; null with no area
point: LatLon | null
Wikidata's coordinate location for the country: a representative point, not a computed centroid
capitalPoint: LatLon | null
The capital's coordinates; null where there is no capital
borders: readonly string[]
Alpha-2 codes of the countries it shares a land border with; [] for an island
drivingSide: DrivingSide | null
null where there are no public roads
weekStart: WeekStart
The first day of the week on a calendar there, from CLDR: "mon" for most, "sun" for the United States and Japan.
measurement: MeasurementSystem
The system of measurement in everyday use, from CLDR: "metric", or "US" and "UK".
paper: PaperSize
The paper size in everyday use, from CLDR: "A4", or "US-Letter" in the Americas' Letter countries.
hourCycle: HourCycle
The clock CLDR prefers there: "h12" (1 to 12, with AM and PM) or "h23" (0 to 23).

function distanceKm

distanceKm: (from: LatLon, to: LatLon) => number

The great-circle distance between two points, in kilometres, on a sphere of the earth's mean radius (6,371 km). Within about half a percent of the distance on the ground.

  • from A point, `{ lat, lon }` in degrees.
  • to Another point.

Returns The distance in kilometres.

Example
import { distanceKm, facts } from "@johnmorrisdotca/kuni/facts";

Math.round(distanceKm(facts("JP")!.capitalPoint!, facts("GB")!.capitalPoint!)); // 9558

type DrivingSide

type DrivingSide = "left" | "right";

The side of the road a country drives on.

function facts

facts: (code: string) => CountryFacts | null

The facts about one country, by its alpha-2 code in either case.

  • code An ISO 3166-1 alpha-2 code, "JP" or "jp"; for an alpha-3 or numeric code, pass `country(code)?.alpha2`.

Returns The country's facts, frozen; `null` for anything that is not one of the 250 codes.

Example
import { facts } from "@johnmorrisdotca/kuni/facts";

facts("JP")?.population;    // 123802000
facts("JP")?.populationYear; // 2024
facts("FR")?.borders;        // ["AD", "BE", "BR", "CH", "DE", "ES", "IT", "LU", "MC", "SR"]
facts("GB")?.drivingSide;    // "left"
facts("US")?.weekStart;      // "sun"
facts("XX");                 // null

const FACTS_READ

FACTS_READ: "2026-10-09"

The day the Wikidata snapshot was read: every figure in /facts is as Wikidata gave it on this day.

Example
import { FACTS_READ, facts } from "@johnmorrisdotca/kuni/facts";

console.log(`${facts("JP")?.population} people in ${facts("JP")?.populationYear}, as Wikidata gave it on ${FACTS_READ}`);

type HourCycle

type HourCycle = "h12" | "h23";

The clock in everyday use, named as an hour cycle is in JavaScript: "h12" is 1 to 12 with AM and PM, "h23" is 0 to 23.

type LatLon

interface LatLon

A point on the earth, in degrees: north and east are positive.

lat: number
Latitude in degrees, north positive: -90 to 90.
lon: number
Longitude in degrees, east positive: -180 to 180.

type MeasurementSystem

type MeasurementSystem = "metric" | "US" | "UK";

The system of measurement in everyday use, as CLDR writes it: the United States' and Britain's are their own.

type PaperSize

type PaperSize = "A4" | "US-Letter";

The paper size in everyday use, as CLDR writes it.

type WeekStart

type WeekStart = "mon" | "sun" | "sat" | "fri";

The first day of the week on a calendar there, as CLDR writes it.

@johnmorrisdotca/kuni/subdivision-facts

LatLon loadSubdivisionFacts SubdivisionFacts

type LatLon

interface LatLon

A point on the earth, in degrees: north and east are positive.

lat: number
Latitude in degrees, north positive: -90 to 90.
lon: number
Longitude in degrees, east positive: -180 to 180.

function loadSubdivisionFacts

loadSubdivisionFacts: (countryCode: string) => Promise<readonly SubdivisionFacts[] | null>

The facts about one country's subdivisions, every level, in code order: one object for each subdivision, with null for anything Wikidata does not give or gives two ways (docs/subdivision-facts.md counts them).

  • countryCode An ISO 3166-1 alpha-2 code, in either case.

Returns The list, frozen; an empty list for a country with no subdivisions (Antarctica); `null` for a code that is not a country.

Example
import { loadSubdivisionFacts } from "@johnmorrisdotca/kuni/subdivision-facts";

const prefectures = await loadSubdivisionFacts("JP");
prefectures?.[0].capital;    // { en: "Sapporo", ja: "札幌市", reading: "さっぽろし" }
prefectures?.[12].population; // 14264798, for Tokyo
prefectures?.[12].populationYear; // 2022
await loadSubdivisionFacts("AQ"); // []
await loadSubdivisionFacts("XX"); // null

type SubdivisionFacts

interface SubdivisionFacts

The facts about one subdivision, from the /subdivision-facts entry: null where Wikidata has none, or gives two.

code: string
ISO 3166-2, "JP-13"
capital: { en: string; ja: string | null; reading?: string; } | null
The seat of its government; reading in hiragana
capitalPoint: LatLon | null
The capital's coordinates
population: number | null
People, from Wikidata
populationYear: number | null
The year the population is for, where Wikidata says
areaKm2: number | null
Area in square kilometres, from Wikidata
areaYear: number | null
The year the area is for, where Wikidata says
point: LatLon | null
Wikidata's coordinate location for the subdivision

@johnmorrisdotca/kuni/groupings

grouping Grouping GROUPING_KINDS GroupingDateOptions GroupingKind GroupingMember GroupingName GroupingOther groupings groupingsOf GroupingsOptions GroupingSource GroupingStatus membersOf

function grouping

grouping: (id: string) => Grouping | null

One grouping by its id.

  • id The grouping's id: "eu", "nato", "m49-030", "continent-as", "middle-east", "jp-kanto".

Returns The grouping, frozen; `null` for an id that is not one.

Example
import { grouping } from "@johnmorrisdotca/kuni/groupings";

grouping("eu")?.members.length;    // 27
grouping("eu")?.name.ja;           // "欧州連合"
grouping("jp-kanto")?.members[5];  // "JP-13"
grouping("atlantis");              // null

type Grouping

interface Grouping

A grouping of countries, or of the subdivisions inside one country.

id: string
A stable id in kebab case: "eu", "m49-030", "continent-as", "jp-kanto".
kind: "continent" | "m49" | "membership" | "informal" | "subdivision"
What kind of grouping it is.
name: { en: string; ja: string; }
Its name in English and in Japanese.
shortName?: { en?: string; ja?: string; } | undefined
A short form where one is in use: "EU", "NATO", 国連.
reading?: string | undefined
The Japanese name in hiragana, where it is written with kanji.
otherNames?: readonly GroupingName[] | undefined
Other names it is known by, each in both languages with its reading: Kansai (関西地方) for the Kinki region.
informal: boolean
True for a grouping no body defines (the Middle East, Scandinavia), whose members follow the definition given.
country?: string | undefined
For a grouping of subdivisions: the alpha-2 code of the country they are in.
parent?: string | undefined
For a UN M49 area: the id of the area that holds it ("m49-142" for Eastern Asia).
sets?: readonly string[] | undefined
For a grouping of subdivisions: the sets it belongs to. The groupings of one set cover the country once.
members: readonly string[]
The members now: alpha-2 codes, or ISO 3166-2 codes for a grouping inside a country.
periods?: readonly GroupingMember[] | undefined
For an international body: every period of membership, current and former, with its dates.
others?: readonly GroupingOther[] | undefined
For an international body: countries that stand with it without being members.
definition: string
The definition the members follow.
note?: string | undefined
Where definitions disagree, or anything else a reader should know.
source: GroupingSource
Where the list comes from, and its terms.
asOf: string
The day the list was true, "2026-10-09".

const GROUPING_KINDS

GROUPING_KINDS: readonly ["continent", "m49", "membership", "informal", "subdivision"]

What kind of grouping it is: a continent, a UN M49 area, an international body's members, a well-known informal grouping, or a grouping of the subdivisions inside one country.

Example
import { GROUPING_KINDS, groupings } from "@johnmorrisdotca/kuni/groupings";

GROUPING_KINDS.map((kind) => groupings({ kind }).length)[0]; // 7

type GroupingDateOptions

interface GroupingDateOptions

What groupingsOf() and membersOf() may be asked.

on?: string | undefined
A day, "2015-06-30": an international body's members on that day rather than now. A member whose start Wikidata does not give counts from the start. Groupings that are not bodies have no dates, and the day changes nothing.
kind?: "continent" | "m49" | "membership" | "informal" | "subdivision" | undefined
Only groupings of this kind (for `groupingsOf`).

type GroupingKind

type GroupingKind = (typeof GROUPING_KINDS)[number];

What kind of grouping it is: "continent", "m49", "membership", "informal" or "subdivision".

type GroupingMember

interface GroupingMember

One period of membership of a body: a member from since (or a day Wikidata does not give) until until.

code: string
The member's alpha-2 code: "DE".
since: string | null
The day it joined, "1958-01-01", from Wikidata; `null` where Wikidata does not give the day.
until: string | null
The day it left, "2020-01-31"; `null` while it is a member.

type GroupingName

interface GroupingName

Another name a grouping goes by, in English and Japanese.

en: string
In English: "Kansai region".
ja: string
In Japanese: "関西地方".
reading?: string | undefined
The Japanese in hiragana, where it has kanji: "かんさいちほう".

type GroupingOther

interface GroupingOther

A country that stands with a body without being a member: a candidate, an associate, an observer or suspended.

code: string
The country's alpha-2 code.
status: GroupingStatus
How it stands.

function groupings

groupings: (options?: GroupingsOptions) => readonly Grouping[]

Every grouping, or those of one kind or inside one country, in a fixed order: continents, UN M49 areas, international bodies, informal groupings, then regions inside a country.

  • options `kind` to keep one kind, `country` to keep the groupings of one country's subdivisions.

Returns The groupings, frozen; an empty list where none match.

Example
import { groupings } from "@johnmorrisdotca/kuni/groupings";

groupings({ kind: "continent" }).map((one) => one.name.en); // ["Africa", "Antarctica", "Asia", "Europe", ...]
groupings({ country: "JP" }).length;                         // 10: the eight 地方, and the nine-region variant's two

function groupingsOf

groupingsOf: (code: string, options?: GroupingDateOptions) => readonly Grouping[]

The groupings a country, or a subdivision, is a member of: now, or on a given day.

  • code An alpha-2 code ("FR", either case) or an ISO 3166-2 code ("JP-13").
  • options `on` for a day in the past, `kind` to keep one kind.

Returns The groupings, frozen, in the order of `groupings()`; an empty list for a code in none, or not a code.

Example
import { groupingsOf } from "@johnmorrisdotca/kuni/groupings";

groupingsOf("GB", { kind: "membership" }).map((one) => one.id);                    // ["un", "nato", "g7", ...]
groupingsOf("GB", { kind: "membership", on: "2015-01-01" }).some((one) => one.id === "eu"); // true
groupingsOf("JP-13").map((one) => one.id);                                          // ["jp-kanto"]

type GroupingsOptions

interface GroupingsOptions

What groupings() may be narrowed to.

kind?: "continent" | "m49" | "membership" | "informal" | "subdivision" | undefined
Only groupings of this kind.
country?: string | undefined
Only groupings of the subdivisions inside this country (alpha-2, either case).

type GroupingSource

interface GroupingSource

Where a grouping's definition comes from, and the terms its list is under.

name: string
The source's name: "European Union, Countries".
url: string
Where to read it.
licence: string
The terms of the list as it is shipped here.

type GroupingStatus

type GroupingStatus = "candidate" | "associate" | "observer" | "suspended";

How a country stands with a body when it is not a member.

function membersOf

membersOf: (id: string, options?: GroupingDateOptions) => readonly string[] | null

The members of a grouping: now, or on a given day for an international body.

  • id The grouping's id.
  • options `on`, a day such as "2019-06-30".

Returns The members' codes, frozen; `null` for an id that is not a grouping.

Example
import { membersOf } from "@johnmorrisdotca/kuni/groupings";

membersOf("eu")?.includes("GB");                       // false
membersOf("eu", { on: "2019-06-30" })?.includes("GB"); // true
membersOf("us-pacific");                               // ["US-AK", "US-CA", "US-HI", "US-OR", "US-WA"]

@johnmorrisdotca/kuni/withdrawn

withdrawn WITHDRAWN_READ withdrawnCountries WithdrawnCountry

function withdrawn

withdrawn: (code: string) => readonly WithdrawnCountry[]

The withdrawn countries that held a code: the four-letter ISO 3166-3 code ("SUHH"), an alpha-2 ("SU"), an alpha-3 ("SUN") or a numeric code ("810"), in either case. A code can name more than one: "CS" was Czechoslovakia (CSHH) and then Serbia and Montenegro (CSXX), later first; and "BY" is a withdrawn country as well as a current one, which country("BY") answers on its own.

  • code Any code a withdrawn country held.

Returns The matching records, the one that was withdrawn last first; an empty list for anything else, and for the code of a current country that was never withdrawn.

Example
import { withdrawn } from "@johnmorrisdotca/kuni/withdrawn";

withdrawn("su")[0].name.en;        // "Soviet Union"
withdrawn("SU")[0].until;          // "1992"
withdrawn("YUCS")[0].successors;   // ["CS"]: itself withdrawn, and resolved by withdrawn("CS")
withdrawn("CS").map((one) => one.code); // ["CSXX", "CSHH"]
withdrawn("JP");                   // []

const WITHDRAWN_READ

WITHDRAWN_READ: "2026-10-10"

The day the Wikidata snapshot of the withdrawn codes was read.

Example
import { WITHDRAWN_READ } from "@johnmorrisdotca/kuni/withdrawn";

WITHDRAWN_READ; // "2026-10-10"

function withdrawnCountries

withdrawnCountries: () => readonly WithdrawnCountry[]

Every withdrawn country of ISO 3166-3, in order of its four-letter code. Never part of countries(), so a picker does not show them unless it asks.

Returns The 31 records, the list and its objects frozen and shared.

Example
import { withdrawnCountries } from "@johnmorrisdotca/kuni/withdrawn";

withdrawnCountries().length;                              // 31
withdrawnCountries().map((one) => one.alpha2).includes("SU"); // true

type WithdrawnCountry

interface WithdrawnCountry

A country that was withdrawn from ISO 3166-1, as ISO 3166-3 lists it (frozen).

code: string
The four-letter ISO 3166-3 code: "SUHH" for the Soviet Union. Its first two letters are the alpha-2 code.
alpha2: string
The ISO 3166-1 alpha-2 code it held: "SU".
alpha3?: string | undefined
The alpha-3 code it held, "SUN", as ISO 3166-3 lists it.
numeric?: string | undefined
The numeric code it held, "810"; absent where ISO 3166-3 lists none (Gilbert and Ellice Islands, New Hebrides).
name: { en: string; ja: string | null; }
Its name in English and Japanese; `ja` is `null` where Wikidata has none, never an English name copied in.
since: string
The year its code came into force, "1974" (a full day, "1974-12-15", where Wikidata gives one).
until: string
The year its code was withdrawn, "1992", or a full day, "1990-08-14".
successors: readonly string[]
The new codes ISO 3166-3 lists for it, in ISO's order: ["AM", "AZ", ...] for the Soviet Union. A successor may itself be withdrawn: Yugoslavia's is "CS", which `withdrawn("CS")` resolves to Serbia and Montenegro (CSXX) first and Czechoslovakia (CSHH) after it.
reusedBy?: string | undefined
Set when the alpha-2 code was later given to a current country, so that the code means two things in time: "BY" was the Byelorussian SSR and is Belarus. The value is that country's alpha-2 code. Absent for codes nobody has been given again (SU, YU, CS, DD, ZR, TP, AN, BU).