Created
March 5, 2024 00:57
-
-
Save g4rcez/ce62dab60448eefd97562a65563225dd to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import axios from "axios"; | |
export type Country = { | |
name: Name; | |
tld?: string[]; | |
cca2: string; | |
ccn3?: string; | |
cca3: string; | |
cioc?: string; | |
independent?: boolean; | |
status: Status; | |
unMember: boolean; | |
currencies?: Currencies; | |
idd: Idd; | |
capital?: string[]; | |
altSpellings: string[]; | |
region: Region; | |
subregion?: string; | |
languages?: { [key: string]: string }; | |
translations: { [key: string]: Translation }; | |
latlng: number[]; | |
landlocked: boolean; | |
area: number; | |
demonyms?: Demonyms; | |
flag: string; | |
maps: Maps; | |
population: number; | |
gini?: { [key: string]: number }; | |
fifa?: string; | |
car: Car; | |
timezones: string[]; | |
continents: Continent[]; | |
flags: Flags; | |
coatOfArms: CoatOfArms; | |
startOfWeek: StartOfWeek; | |
capitalInfo: CapitalInfo; | |
postalCode?: PostalCode; | |
borders?: string[]; | |
} | |
export type CapitalInfo = { | |
latlng?: number[]; | |
} | |
export type Car = { | |
signs?: string[]; | |
side: Side; | |
} | |
export type Side = "left" | "right"; | |
export type CoatOfArms = { | |
png?: string; | |
svg?: string; | |
} | |
export type Continent = "Europe" | "Africa" | "North America" | "Oceania" | "South America" | "Asia" | "Antarctica"; | |
export type Currencies = { | |
EUR?: Aed; | |
ERN?: Aed; | |
LRD?: Aed; | |
BMD?: Aed; | |
CKD?: Aed; | |
NZD?: Aed; | |
SOS?: Aed; | |
ZMW?: Aed; | |
VES?: Aed; | |
TMT?: Aed; | |
ALL?: Aed; | |
GBP?: Aed; | |
SDG?: BAM; | |
USD?: Aed; | |
XAF?: Aed; | |
AZN?: Aed; | |
KES?: Aed; | |
XOF?: Aed; | |
VND?: Aed; | |
AFN?: Aed; | |
GTQ?: Aed; | |
KWD?: Aed; | |
STN?: Aed; | |
KGS?: Aed; | |
PLN?: Aed; | |
GHS?: Aed; | |
AMD?: Aed; | |
JEP?: Aed; | |
XCD?: Aed; | |
TJS?: Aed; | |
ETB?: Aed; | |
DZD?: Aed; | |
MAD?: Aed; | |
MRU?: Aed; | |
AUD?: Aed; | |
BND?: Aed; | |
SGD?: Aed; | |
RON?: Aed; | |
NOK?: Aed; | |
BYN?: Aed; | |
PAB?: Aed; | |
CZK?: Aed; | |
PKR?: Aed; | |
PEN?: Aed; | |
BBD?: Aed; | |
DKK?: Aed; | |
HUF?: Aed; | |
KMF?: Aed; | |
BDT?: Aed; | |
FJD?: Aed; | |
CNY?: Aed; | |
COP?: Aed; | |
MVR?: Aed; | |
MYR?: Aed; | |
KYD?: Aed; | |
PYG?: Aed; | |
UYU?: Aed; | |
ZAR?: Aed; | |
VUV?: Aed; | |
SEK?: Aed; | |
LBP?: Aed; | |
CLP?: Aed; | |
BZD?: Aed; | |
GYD?: Aed; | |
MNT?: Aed; | |
TVD?: Aed; | |
DOP?: Aed; | |
BOB?: Aed; | |
NPR?: Aed; | |
TWD?: Aed; | |
BGN?: Aed; | |
MDL?: Aed; | |
IMP?: Aed; | |
BTN?: Aed; | |
INR?: Aed; | |
KHR?: Aed; | |
HTG?: Aed; | |
CVE?: Aed; | |
GEL?: Aed; | |
BIF?: Aed; | |
BSD?: Aed; | |
MUR?: Aed; | |
LYD?: Aed; | |
MWK?: Aed; | |
MXN?: Aed; | |
SZL?: Aed; | |
PGK?: Aed; | |
CHF?: Aed; | |
RUB?: Aed; | |
ILS?: Aed; | |
UGX?: Aed; | |
TOP?: Aed; | |
AED?: Aed; | |
SRD?: Aed; | |
UZS?: Aed; | |
SAR?: Aed; | |
EGP?: Aed; | |
MGA?: Aed; | |
XPF?: Aed; | |
CAD?: Aed; | |
GMD?: Aed; | |
TTD?: Aed; | |
SCR?: Aed; | |
JPY?: Aed; | |
BRL?: Aed; | |
SYP?: Aed; | |
SHP?: Aed; | |
TZS?: Aed; | |
IRR?: Aed; | |
KRW?: Aed; | |
WST?: Aed; | |
JMD?: Aed; | |
NIO?: Aed; | |
GNF?: Aed; | |
PHP?: Aed; | |
NAD?: Aed; | |
CRC?: Aed; | |
BAM?: BAM; | |
MOP?: Aed; | |
MZN?: Aed; | |
KPW?: Aed; | |
UAH?: Aed; | |
IQD?: Aed; | |
AOA?: Aed; | |
SLL?: Aed; | |
CUC?: Aed; | |
CUP?: Aed; | |
RSD?: Aed; | |
FOK?: Aed; | |
JOD?: Aed; | |
TRY?: Aed; | |
KID?: Aed; | |
KZT?: Aed; | |
GIP?: Aed; | |
ISK?: Aed; | |
QAR?: Aed; | |
MMK?: Aed; | |
THB?: Aed; | |
AWG?: Aed; | |
NGN?: Aed; | |
BHD?: Aed; | |
LAK?: Aed; | |
DJF?: Aed; | |
SBD?: Aed; | |
ANG?: Aed; | |
FKP?: Aed; | |
BWP?: Aed; | |
GGP?: Aed; | |
ZWL?: Aed; | |
LSL?: Aed; | |
ARS?: Aed; | |
YER?: Aed; | |
CDF?: Aed; | |
OMR?: Aed; | |
IDR?: Aed; | |
RWF?: Aed; | |
MKD?: Aed; | |
TND?: Aed; | |
SSP?: Aed; | |
HNL?: Aed; | |
LKR?: Aed; | |
HKD?: Aed; | |
} | |
export type Aed = { | |
name: string; | |
symbol: string; | |
} | |
export type BAM = { | |
name: string; | |
} | |
export type Demonyms = { | |
eng: Eng; | |
fra?: Eng; | |
} | |
export type Eng = { | |
f: string; | |
m: string; | |
} | |
export type Flags = { | |
png: string; | |
svg: string; | |
alt?: string; | |
} | |
export type Idd = { | |
root?: string; | |
suffixes?: string[]; | |
} | |
export type Maps = { | |
googleMaps: string; | |
openStreetMaps: string; | |
} | |
export type Name = { | |
common: string; | |
official: string; | |
nativeName?: { [key: string]: Translation }; | |
} | |
export type Translation = { | |
official: string; | |
common: string; | |
} | |
export type PostalCode = { | |
format: string; | |
regex?: string; | |
} | |
export type Region = "Europe" | "Africa" | "Americas" | "Oceania" | "Asia" | "Antarctic"; | |
export type StartOfWeek = "monday" | "sunday" | "saturday"; | |
export type Status = "officially-assigned" | "user-assigned"; | |
const sort = <Item extends object, K extends keyof Item | ((i: Item) => string)>(list: Item[], key: K) => { | |
if (typeof key === "function") return list.toSorted((a, b) => key(a).localeCompare(key(b))); | |
if (typeof key === "string") return list.toSorted((a, b) => ((a as any)[key]).localeCompare((b as any)[key])); | |
return list; | |
} | |
const chars = sort([ | |
{ name: "Sokka" }, | |
{ name: "Zuko" }, | |
{ name: "Aang" }, | |
], "name") | |
async function requestCountries(fields: string[] | undefined = undefined) { | |
const response = await axios.get<Country[]>("https://restcountries.com/v3.1/all", { | |
params: { fields } | |
}); | |
const sortedCountries = sort(response.data, (item) => item.name.common); | |
return sortedCountries; | |
} | |
type Response = { | |
items: Country[]; | |
nextPage: number; | |
page: number; | |
pageSize: number; | |
previousPage: number; | |
totalItems: number; | |
} | |
type N = number | undefined; | |
const countryService = async (page: N, pageSize: N, fields: string[] | undefined = undefined): Promise<Response> => { | |
const countries = await requestCountries(fields); | |
const pagination = { | |
page: page ? Math.min(Math.max(page, 0), 0) : 0, | |
pageSize: pageSize ? Math.min(Math.max(pageSize, 50), 0) : 50, | |
} | |
const totalItems = Math.ceil(countries.length / pagination.pageSize) | |
return { | |
totalItems, | |
nextPage: pagination.page + 1, | |
previousPage: Math.max(pagination.page - 1, 0), | |
page: pagination.page, | |
pageSize: pagination.pageSize, | |
items: countries.slice( | |
pagination.page * pagination.pageSize, // 10 * 50 => 500 | |
(pagination.page * pagination.pageSize) + pagination.pageSize, // (10 * 50) + 50 => 550 | |
) | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment