UNPKG

country-to-iso

Version:

Convert inconsistent country names and codes into ISO 3166-1 alpha-2.

146 lines (121 loc) 4.33 kB
import * as fs from "fs"; import * as path from "path"; import * as countryJs from "countryjs"; import * as countryList from "country-list"; import * as isoCountries from "i18n-iso-countries"; interface CountryData { alpha2: string; alpha3: string; names: Array<string> } const alphabet = "ABCDEFGHIJKLMNOPQRSTUVWXYZ".split(""); const dataDir = path.join(__dirname, "..", "..", "..", "data"); const countryDir = path.join(dataDir, "country"); const alpha2File = path.join(dataDir, "iso-alpha-2.json"); const alpha3File = path.join(dataDir, "iso-alpha-3.json"); const alpha23File = path.join(dataDir, "iso-alpha-2-to-3.json"); const namesSeen : { [key: string]: string } = {}; const alpha2s: Array<string> = [] const alpha3s: {[key: string]: string} = {} const alpha23s: {[key: string]: string} = {} const loadCountryFile = function(file: string, alpha2: string, alpha3: string): CountryData { let data : CountryData = { alpha2, alpha3, names: [] }; try { const stat = fs.lstatSync(file); if (stat.isFile()) { data = JSON.parse(fs.readFileSync(file).toString()); } } catch (err: any) { // Ignore file doesn't exist error as we'll create it if (err.code !== "ENOENT") { console.log(file); throw err; } } return data; } const getCountryInfo = function(code: string) { let alpha2 = null; let alpha3 = null; const names = []; // Source from "countryjs" const info = countryJs.info(code); if (info) { alpha2 = info.ISO.alpha2; alpha3 = info.ISO.alpha3; names.push(info.name); names.push(info.nativeName); for (const alt of info.altSpellings) { names.push(alt); } } // Source from "country-list" const countryListName = countryList.getName(code); if (countryListName) { alpha2 = code; names.push(countryListName); } // Source from "i18n-iso-countries" const isoNames = isoCountries.getName(code, "en", { select: "all" }); if (Array.isArray(isoNames)) { isoNames.forEach(name => names.push(name)); } // Populate alpha 3 if not found yet if (alpha2 && !alpha3) { alpha3 = isoCountries.alpha2ToAlpha3(code); } return { alpha2, alpha3, names }; } const processCountryCode = function(code: string) { const countryFile = path.join(countryDir, `${code}.json`); let data : CountryData = getCountryInfo(code); // Attempt to load country data from this library if (!data.alpha2) { data = loadCountryFile(countryFile, data.alpha2, data.alpha3); } if (data.alpha2) { // ISO 3166 alpha2s.push(data.alpha2); alpha3s[data.alpha3] = data.alpha2; alpha23s[data.alpha2] = data.alpha3; // Load existing data data = loadCountryFile(countryFile, data.alpha2, data.alpha3); // Populate a set so we don't duplicate const namesSet = new Set(data.names); namesSet.add(data.alpha2); namesSet.add(data.alpha3); data.names.forEach((name) => namesSet.add(name)); // Empty names array so we don't duplicate data.names = []; // Put names back into names array for (const name of namesSet) { if (typeof name === 'string' && name.length > 1) { if (namesSeen[name]) { console.log(`CLASH! "${name}" [${data.alpha2}] has been seen for ${namesSeen[name]}`); } else { data.names.push(name); namesSeen[name] = data.alpha2; } } } fs.writeFileSync(countryFile, JSON.stringify(data, null, 2)); } } const seed = function() { for (const letter1 of alphabet) { for (const letter2 of alphabet) { processCountryCode(`${letter1}${letter2}`); } } fs.writeFileSync(alpha2File, JSON.stringify(alpha2s, null, 2)); fs.writeFileSync(alpha3File, JSON.stringify(alpha3s, null, 2)); fs.writeFileSync(alpha23File, JSON.stringify(alpha23s, null, 2)); console.log("Seed complete..."); console.log(`* Countries: ${alpha2s.length};`); console.log(`* Names: ${Object.keys(namesSeen).length}`); } seed();