From 8cfe993525c432aa06cba57af40f82ebb4abb67c Mon Sep 17 00:00:00 2001 From: Chris Wilkinson Date: Thu, 11 Jul 2024 11:48:37 +0100 Subject: [PATCH] Recognise major cities Refs #31 --- package-lock.json | 7 +++++++ package.json | 1 + src/lib/Iso3166.ts | 12 ++++++++++++ test/Iso3166.test.ts | 4 ++-- 4 files changed, 22 insertions(+), 2 deletions(-) diff --git a/package-lock.json b/package-lock.json index b06a80c..9e5ee5e 100644 --- a/package-lock.json +++ b/package-lock.json @@ -10,6 +10,7 @@ "@effect/schema": "^0.68.1", "@js-temporal/polyfill": "^0.4.4", "@observablehq/framework": "^1.9.0", + "@vvo/tzdb": "^6.141.0", "d3-dsv": "^3.0.1", "d3-time-format": "^4.1.0", "diacritics": "^1.3.0", @@ -358,6 +359,7 @@ }, "node_modules/@clack/prompts/node_modules/is-unicode-supported": { "version": "1.3.0", + "extraneous": true, "inBundle": true, "license": "MIT", "engines": { @@ -2378,6 +2380,11 @@ "@types/estree": "^1.0.0" } }, + "node_modules/@vvo/tzdb": { + "version": "6.141.0", + "resolved": "https://registry.npmjs.org/@vvo/tzdb/-/tzdb-6.141.0.tgz", + "integrity": "sha512-vpuv8Eo75WwW6oHygfSSJ8J2AIADlqoHu9HmKxD8Ey/hmRhxt0+/nEGbzBy/Y/Q1qsdgDj3kP3NRLr2082VzgA==" + }, "node_modules/acorn": { "version": "8.12.0", "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.12.0.tgz", diff --git a/package.json b/package.json index 83b3fff..b684d5a 100644 --- a/package.json +++ b/package.json @@ -7,6 +7,7 @@ "@effect/schema": "^0.68.1", "@js-temporal/polyfill": "^0.4.4", "@observablehq/framework": "^1.9.0", + "@vvo/tzdb": "^6.141.0", "d3-dsv": "^3.0.1", "d3-time-format": "^4.1.0", "diacritics": "^1.3.0", diff --git a/src/lib/Iso3166.ts b/src/lib/Iso3166.ts index 4298463..6c2a01e 100644 --- a/src/lib/Iso3166.ts +++ b/src/lib/Iso3166.ts @@ -1,4 +1,5 @@ import { Schema } from '@effect/schema' +import { rawTimeZones } from '@vvo/tzdb' import diacritics from 'diacritics' import { Array, Option, type Predicate, String, flow } from 'effect' import iso3166 from 'i18n-iso-countries' @@ -27,6 +28,17 @@ export const guessCountry: (location: string) => Option.Option = flo subDivision => subDivision.country, ), ), + Option.orElse(() => + Option.map( + Array.findFirst(rawTimeZones, timezone => + Array.some( + timezone.mainCities, + mainCity => diacritics.remove(location).toLowerCase() === diacritics.remove(mainCity).toLowerCase(), + ), + ), + timeZone => timeZone.countryCode, + ), + ), ), ), Option.filter(isAlpha2Code), diff --git a/test/Iso3166.test.ts b/test/Iso3166.test.ts index 002ffe8..4fb70a8 100644 --- a/test/Iso3166.test.ts +++ b/test/Iso3166.test.ts @@ -11,9 +11,11 @@ describe('guessCountry', () => { ['Czech Republic', 'CZ'], ['Czechia', 'CZ'], ['GHANA', 'GH'], + ['London', 'GB'], ['London, Ontario', 'CA'], ['London, UK', 'GB'], ['London, United Kingdom', 'GB'], + ['New York City and Los Angeles', 'US'], ['Québec', 'CA'], ['Rio de Janeiro, Brazil.', 'BR'], ['Sunnyvale, California', 'US'], @@ -31,9 +33,7 @@ describe('guessCountry', () => { test.for([ 'Beijing University of Technology, Beijing 100124, PR China', 'Fayetteville GA (near Atlanta)', - 'London', 'Mars', - 'New York City and Los Angeles', 'Southeast Asia', 'The UK', ])("doesn't guess %s", input => {