11import axios from "axios" ;
2+ import { convertCountryCode } from "../utils/libs/convertCountry" ;
3+ import { capitalizeFirstLetter } from "../utils/libs/capitalizeFirstLetter" ;
24axios . defaults . baseURL = "https://disease.sh/v3/covid-19" ;
35
4- let countryCodes : { [ key : string ] : string } = { } ;
5- ( async ( ) => {
6- countryCodes = ( await axios . get ( "http://country.io/names.json" ) ) . data ;
7- } ) ( ) ;
8-
9- export interface PlainData {
10- data : {
11- [ key : string ] : string ;
12- } ;
13- metainfo : {
14- [ key : string ] : number | string ;
15- } ;
16- }
17-
186/**
197 * @param isPlain Set to true to recieve an object containing the responses instead of the rows
208 * @returns an object containing the data and metainfo **if isPlain is set to true**
219 * @returns an array in the format of [timestamp, rows] **if isPlain is set to false**
2210 */
23- export const getAllInfo : (
24- isPlain ?: boolean
25- ) => Promise < [ number , ( string [ ] | string ) [ ] ] | PlainData > = async (
26- isPlain = false
27- ) => {
11+ export const getAllInfo : ( ) => Promise < {
12+ updated : number ;
13+ data : {
14+ cases : number ;
15+ deaths : number ;
16+ recovered : number ;
17+ deathRate : number ;
18+ recoveryRate : number ;
19+ } ;
20+ } > = async ( ) => {
2821 let { data : globalData } = await axios . get ( "/all" ) ;
2922 let { cases, deaths, recovered, updated } = globalData ;
23+ let deathRate = ( deaths / cases ) * 100 ;
24+ let recoveryRate = ( recovered / cases ) * 100 ;
3025
31- let mortalityPercentage = ( ( deaths / cases ) * 100 ) . toFixed ( 2 ) + "%" ;
32- let recoveredPercentage = ( ( recovered / cases ) * 100 ) . toFixed ( 2 ) + "%" ;
33-
34- [ cases , deaths , recovered ] = [ cases , deaths , recovered ] . map ( ( num : number ) =>
35- num . toLocaleString ( "en-US" , { maximumFractionDigits : 0 } )
36- ) ;
37-
38- // Return object containing information if isPlain is set to true
39- if ( isPlain ) {
40- return {
41- data : {
42- Cases : cases ,
43- Deaths : deaths ,
44- "Mortality %" : mortalityPercentage ,
45- Recovered : recovered ,
46- "Recovered %" : recoveredPercentage ,
47- } ,
48- metainfo : {
49- updated,
50- } ,
51- } ;
52- }
53-
54- // Return rows if isPlain is set to false
55- // prettier-ignore
56- return [ updated , [
57- [ "Cases" . magenta , "Deaths" . red , "Recovered" . green , "Mortality %" . red , "Recovered %" . green ] ,
58- [ cases , deaths , recovered , mortalityPercentage , recoveredPercentage ] ] ]
26+ return {
27+ updated,
28+ data : {
29+ cases,
30+ deaths,
31+ recovered,
32+ deathRate,
33+ recoveryRate,
34+ } ,
35+ } ;
5936} ;
6037
6138/**
@@ -65,107 +42,108 @@ export const getAllInfo: (
6542 * @returns an array in the format of [timestamp, API countryname, formal countryname, rows[]] **if isPlain is false**
6643 */
6744export const getCountryInfo : (
68- country : string ,
69- isPlain ?: boolean
70- ) => Promise <
71- [ number , string , string , ( string [ ] | string ) [ ] ] | PlainData
72- > = async ( country , isPlain ) => {
73- // Wait 1 second for countryCodes to initialize, needed for CLI
74- if ( Object . keys ( countryCodes ) . length === 0 ) {
75- await new Promise ( ( resolve ) => {
76- setTimeout ( resolve , 1000 ) ;
77- } ) ;
78- }
79-
80- country =
81- country . length < 3 ? countryCodes [ country . toUpperCase ( ) ] : country ; // Convert country code to country name
82-
83- if ( country === undefined || typeof country === "undefined" )
84- throw new Error ( `Cannot find provided country` ) ;
45+ country : string
46+ ) => Promise < {
47+ updated : number ;
48+ formalCountryName : string ;
49+ apiCountryName : string ;
50+ data : {
51+ cases : number ;
52+ todayCases : number ;
53+ active : number ;
54+ recovered : number ;
55+ deaths : number ;
56+ todayDeaths : number ;
57+ critical : number ;
58+ deathRate : number ;
59+ recoveryRate : number ;
60+ casesPerOneMillion : number ;
61+ } ;
62+ } > = async ( country ) => {
63+ // Convert country to country code
64+ country = await convertCountryCode ( country ) ;
65+ let formalCountryName = capitalizeFirstLetter ( country ) ;
8566
8667 try {
8768 let { data : countryData } = await axios . get ( `/countries/${ country } ` ) ;
8869 // prettier-ignore
89- let { country : countryName , updated, cases, deaths, recovered, active, casesPerOneMillion, todayCases, todayDeaths, critical} = countryData ;
90-
91- let mortalityPercentage = ( ( deaths / cases ) * 100 ) . toFixed ( 2 ) + "%" ;
92- let recoveredPercentage = ( ( recovered / cases ) * 100 ) . toFixed ( 2 ) + "%" ;
93-
94- // prettier-ignore
95- [ cases , deaths , recovered , active , casesPerOneMillion , todayCases , todayDeaths , critical ] =
96- [ cases , deaths , recovered , active , casesPerOneMillion , todayCases , todayDeaths , critical ,
97- ] . map ( ( num : number ) =>
98- num . toLocaleString ( "en-US" , { maximumFractionDigits : 0 } )
99- ) ;
100-
101- // Return object containing information if isPlain is set to true
102- if ( isPlain ) {
103- return {
104- data : {
105- Cases : cases ,
106- "Today Cases" : todayCases ,
107- Active : active ,
108- Recovered : recovered ,
109- Deaths : deaths ,
110- "Today Deaths" : todayDeaths ,
111- Critical : critical ,
112- "Mortality %" : mortalityPercentage ,
113- "Recovery %" : recoveredPercentage ,
114- "Cases/Million" : casesPerOneMillion ,
115- } ,
116- metainfo : {
117- updated,
118- countryName,
119- } ,
120- } ;
121- }
70+ let { country : apiCountryName , updated, cases, deaths, recovered, active, casesPerOneMillion, todayCases, todayDeaths, critical} = countryData ;
71+ let deathRate = ( deaths / cases ) * 100 ;
72+ let recoveryRate = ( recovered / cases ) * 100 ;
12273
123- //prettier-ignore
124- return [ updated , country , countryName , [
125- [ "Cases" . magenta , "Deaths" . red , "Recovered" . green , "Active" . blue , "Cases/Million" . blue , ] ,
126- [ cases , deaths , recovered , active , casesPerOneMillion , ] ,
127- [ "Today Cases" . magenta , "Today Deaths" . red , "Critical" . red , "Mortaility %" . red , "Recovery %" . green ] ,
128- [ todayCases , todayDeaths , critical , mortalityPercentage , recoveredPercentage ] ]
129- ]
74+ return {
75+ updated,
76+ formalCountryName,
77+ apiCountryName,
78+ // prettier-ignore
79+ data : {
80+ cases, todayCases, active, recovered, deaths, todayDeaths, critical, deathRate, recoveryRate, casesPerOneMillion
81+ } ,
82+ } ;
13083 } catch {
13184 throw new Error ( `Cannot find the provided country` ) ;
13285 }
13386} ;
13487
135- /**
136- * Get historical info about a country / the world
137- * @param mode - mode that the user requested
138- * @param country - countryname that the user requested, leave blank to get world data
139- * @returns an object containing date and chartData properties
140- */
141- export const getHistorical : (
142- mode : "cases" | "deaths" | "recovered" ,
88+ type getHistoricalMode = "cases" | "deaths" | "recovered" | "all" ;
89+
90+ // prettier-ignore
91+ export async function getHistorical < T extends getHistoricalMode > (
92+ mode : T ,
14393 country ?: string
144- ) => Promise < {
94+ ) : Promise <
95+ T extends "all" ? {
96+ date : string ;
97+ chartData : {
98+ [ key : string ] : {
99+ [ key : string ] : number ;
100+ } ;
101+ } ;
102+ } : {
103+ date : string ;
104+ chartData : number [ ] ;
105+ }
106+ > ;
107+
108+ export async function getHistorical (
109+ mode : getHistoricalMode ,
110+ country = "all"
111+ ) : Promise < {
145112 date : string ;
146- chart : number [ ] ;
147- } > = async ( mode , country = "all" ) => {
113+ chartData :
114+ | number [ ]
115+ | {
116+ [ key : string ] : {
117+ [ key : string ] : number ;
118+ } ;
119+ } ;
120+ } > {
148121 const { data : historicalData } = await axios . get ( `/historical/${ country } ` ) ;
149122
150- const data : {
151- [ key : string ] : number ;
152- } =
153- country === "all"
154- ? historicalData [ mode ]
155- : historicalData [ "timeline" ] [ mode ] ;
123+ // Get all the modes
124+ let chartData =
125+ country === "all" ? historicalData : historicalData [ "timeline" ] ;
126+
127+ // If the user did not select all, then get the mode they wanted
128+ if ( mode !== "all" ) chartData = chartData [ mode ] ;
156129
157130 // Get first and last date
158- const dates = Object . keys ( data ) ;
131+ const dates = Object . keys ( mode === "all" ? chartData [ "cases" ] : chartData ) ;
159132
160133 // Label for chart
161134 const date = `${
162135 mode . charAt ( 0 ) . toUpperCase ( ) + mode . slice ( 1 )
163136 } from ${ dates . shift ( ) } to ${ dates . pop ( ) } `;
164137
165- const chartData = Object . values ( data ) ;
166-
167- return {
168- date,
169- chart : chartData ,
170- } ;
171- } ;
138+ if ( mode === "all" ) {
139+ return {
140+ date,
141+ chartData,
142+ } ;
143+ } else {
144+ return {
145+ date,
146+ chartData : Object . values ( chartData ) as number [ ] ,
147+ } ;
148+ }
149+ }
0 commit comments