1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
|
import * as nano from "https://deno.land/x/[email protected]/mod.ts";
import { environment } from "./environment/environment.ts";
import { Country } from "./models/country.model.ts";
export class Countries {
list: Country[] = [];
names: string[] = [];
query = environment.queries;
async sync(config?: { force: boolean }): Promise<Country[]> {
const lastSynced = localStorage.getItem("lastSynced");
const savedCountries = localStorage.getItem("countries");
const week = environment.syncInterval * 23 * 60 * 60 * 1000;
if (
!savedCountries ||
!lastSynced ||
config?.force ||
Date.now() - Number(lastSynced) > week
) {
console.log(
nano.cyan("Syncronizing countries database..."),
config?.force
? ""
: `\nThis will only happen every ${environment.syncInterval} days`
);
// Fetch and parse countries data from API
const response = await fetch(environment.baseUrl + this.query);
const countries = (await response.json()) as Country[];
this.list = countries;
localStorage.setItem("countries", JSON.stringify(countries));
localStorage.setItem("lastSynced", JSON.stringify(Date.now()));
console.log("Synced successfully");
} else {
this.list = JSON.parse(savedCountries);
}
this.names = this.list.map((c) => c.name.common);
return this.list;
}
find(name: string): Country {
// Replace snake case or kebab case with whitespaces
name = name.toLowerCase().replace(/-|_/g, " ");
// Find exact match first, then fall back to fuzzy match
const country = this.list.find((c) => {
const countryName = c.name.common.toLocaleLowerCase();
return countryName === name || countryName.includes(name);
});
if (!country) {
throw Error(`Cannot find country named ${name}`);
}
return country;
}
print(name: string) {
const country = this.find(name);
let currencies = [];
let iteration = 0;
for (const currencyAbbr in country.currencies) {
iteration++;
const currency = country.currencies[currencyAbbr];
currencies.push(
`${iteration > 1 ? "\t\t " : ""}${currency.name} [${
currency.symbol
}](${currencyAbbr})\n`
);
}
let languages = [];
for (const langAbbr in country.languages) {
languages.push(country.languages[langAbbr] + " ");
}
console.log(
nano.cyan("\nCountry:\t"),
country.flag,
country.name.common,
nano.green("\nLanguages:\t"),
...languages,
nano.green("\nCapital:\t"),
country.capital[0],
nano.green("\nRegion:\t\t"),
country.region,
nano.green("\nPopulation:\t"),
country.population.toLocaleString(),
nano.green("\nCurrencies:\t"),
...currencies
);
}
random(): string {
const randomNum = Math.floor(Math.random() * this.names.length);
return this.names[randomNum];
}
}
|