const limitErrorMessage = 'You have exceeded the number of requests' ; const MAX_AGE = 86400 ; interface IGeoData { readonly city : string ; readonly country : string ; readonly lat : number ; readonly lon : number ; } function toGeoData ( res ) { return res . then ( ( ip ) => { return < IGeoData > { city : '' , country : ip . alpha2 , lat : ip . geo . latitude , lon : ip . geo . longitude , } ; } ) . catch ( ( ) => < IGeoData > { } ) ; } async function ipInfo ( ip ) { if ( IPINFO . trim ( ) . length === 0 || IPINFO . trim ( ) . toLowerCase ( ) == 'false' ) { return < IGeoData > { } ; } let cache = await caches . open ( 'ips' ) ; const url = `https://api.ipgeolocationapi.com/geolocate/${ ip }` ; const key = new Request ( url , { method : 'GET' , headers : { 'Content-Type' : 'application/json' } , } ) ; let cachedResponse = await cache . match ( key ) ; if ( cachedResponse ) { return toGeoData ( cachedResponse . clone ( ) . json ( ) ) ; } const res = await fetch ( url ) ; let str = await res . clone ( ) . text ( ) ; if ( res . status == 200 ) { let cachedRes = new Response ( str , res ) ; cachedRes . headers . set ( 'Cache-Control' , `max-age=${ MAX_AGE }` ) ; cache . put ( key , cachedRes . clone ( ) ) ; return toGeoData ( cachedRes . json ( ) ) ; } else if ( res . status === 429 ) { throw new Error ( limitErrorMessage ) ; } else { throw new Error ( `Unexpected response: ${ res . text ( ) }` ) ; } return < IGeoData > { } ; } export { ipInfo , IGeoData as GeoData } ;