Skip to content

Commit

Permalink
Recognise regions of countries
Browse files Browse the repository at this point in the history
Refs #31
  • Loading branch information
thewilkybarkid committed Jul 11, 2024
1 parent ae92aca commit 6d5fc9b
Show file tree
Hide file tree
Showing 6 changed files with 42 additions and 10 deletions.
2 changes: 1 addition & 1 deletion .eslintrc.json
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@
"import/no-cycle": "error",
"import/no-duplicates": ["error", { "prefer-inline": true }],
"import/no-extraneous-dependencies": ["error"],
"import/no-internal-modules": ["error", { "allow": ["*/lib/*"] }],
"import/no-internal-modules": ["error", { "allow": ["*/lib/*", "world_countries_lists/data/**/*.json"] }],
"import/no-named-as-default": "off",
"import/no-named-as-default-member": "off",
"quotes": ["error", "single", { "avoidEscape": true }]
Expand Down
16 changes: 15 additions & 1 deletion package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

5 changes: 4 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -9,14 +9,17 @@
"@observablehq/framework": "^1.9.0",
"d3-dsv": "^3.0.1",
"d3-time-format": "^4.1.0",
"diacritics": "^1.3.0",
"effect": "^3.3.5",
"i18n-iso-countries": "^7.11.2",
"iso-639-1": "^3.1.2"
"iso-639-1": "^3.1.2",
"world_countries_lists": "^2.9.0"
},
"devDependencies": {
"@dotenvx/dotenvx": "^1.5.0",
"@trivago/prettier-plugin-sort-imports": "^4.3.0",
"@tsconfig/node20": "^20.1.4",
"@types/diacritics": "^1.3.3",
"@types/node": "^20.14.9",
"@typescript-eslint/eslint-plugin": "^7.14.1",
"@typescript-eslint/parser": "^7.14.1",
Expand Down
16 changes: 15 additions & 1 deletion src/lib/Iso3166.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
import { Schema } from '@effect/schema'
import diacritics from 'diacritics'
import { Array, Option, type Predicate, String, flow } from 'effect'
import iso3166 from 'i18n-iso-countries'
import subDivisions from 'world_countries_lists/data/subdivisions/subdivisions.json'

export type Alpha2Code = iso3166.Alpha2Code

Expand All @@ -14,6 +16,18 @@ export const guessCountry: (location: string) => Option.Option<Alpha2Code> = flo
String.replaceAll(/\((.+?)\)/g, ', $1'),
String.replaceAll(/( and | - )/gi, ', '),
location => Array.prepend(Array.map(location.split(',').reverse(), String.trim), location),
Array.findFirst(Option.liftNullable(location => iso3166.getAlpha2Code(location, 'en'))),
Array.findFirst(location =>
Option.fromNullable(iso3166.getAlpha2Code(location, 'en')).pipe(
Option.orElse(() =>
Option.map(
Array.findFirst(
subDivisions,
subDivision => diacritics.remove(location).toLowerCase() === subDivision.name.toLowerCase(),
),
subDivision => subDivision.country,
),
),
),
),
Option.filter(isAlpha2Code),
)
10 changes: 5 additions & 5 deletions test/Iso3166.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,37 +5,37 @@ import * as _ from '../src/lib/Iso3166.js'
describe('guessCountry', () => {
test.for([
['Algiers ( Algeria)', 'DZ'],
['Baylor College of Medicine, Houston, Texas', 'US'],
['Chicago, IL, USA', 'US'],
['Colorado - United States', 'US'],
['Czech Republic', 'CZ'],
['Czechia', 'CZ'],
['GHANA', 'GH'],
['London, Ontario', 'CA'],
['London, UK', 'GB'],
['London, United Kingdom', 'GB'],
['Québec', 'CA'],
['Rio de Janeiro, Brazil.', 'BR'],
['Sunnyvale, California', 'US'],
['UK', 'GB'],
['U.K.', 'GB'],
['United Kingdom', 'GB'],
['united states', 'US'],
['Washington, DC', 'US'],
])('guesses %s', ([input, expected]) => {
const actual = _.guessCountry(input)

expect(actual).toStrictEqual(Option.some(expected))
})

test.for([
'Baylor College of Medicine, Houston, Texas',
'Beijing University of Technology, Beijing 100124, PR China',
'Fayetteville GA (near Atlanta)',
'London',
'London, Ontario',
'Mars',
'New York City and Los Angeles',
'Québec',
'Southeast Asia',
'Sunnyvale, California',
'The UK',
'Washington, DC',
])("doesn't guess %s", input => {
const actual = _.guessCountry(input)

Expand Down
3 changes: 2 additions & 1 deletion tsconfig.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
{
"extends": "@tsconfig/node20/tsconfig.json",
"compilerOptions": {
"exactOptionalPropertyTypes": true
"exactOptionalPropertyTypes": true,
"resolveJsonModule": true
},
"include": ["src", "test", "*.ts"]
}

0 comments on commit 6d5fc9b

Please sign in to comment.