11import isString from 'lodash/isString' ;
22import isArray from 'lodash/isArray' ;
33import isIP from 'is-ip' ;
4- import axios , { AxiosError , AxiosResponse } from 'axios' ;
4+ import axios , { AxiosError } from 'axios' ;
55import urljoin from 'url-join' ;
66import LRU from 'lru-cache' ;
77
88const CACHE_MAX = 4096 ; // max number of items
99const CACHE_MAX_AGE = 1000 * 60 * 60 * 24 ; // 24 hours
1010const cache = new LRU < string , LookupResponse > ( { max : CACHE_MAX , maxAge : CACHE_MAX_AGE } ) ;
1111const DEFAULT_IP = 'DEFAULT_IP' ;
12- const VALID_FIELDS = [ 'ip' , 'is_eu' , 'city' , 'region' , 'region_code' , 'country_name' , 'country_code' , 'continent_name' , 'continent_code' , 'latitude' , 'longitude' , 'asn' , 'organisation' , 'postal' , 'calling_code' , 'flag' , 'emoji_flag' , 'emoji_unicode' , 'carrier' , 'languages' , 'currency' , 'time_zone' , 'threat' , 'count' , 'status' ] ;
12+ const VALID_FIELDS = [
13+ 'ip' ,
14+ 'is_eu' ,
15+ 'city' ,
16+ 'region' ,
17+ 'region_code' ,
18+ 'country_name' ,
19+ 'country_code' ,
20+ 'continent_name' ,
21+ 'continent_code' ,
22+ 'latitude' ,
23+ 'longitude' ,
24+ 'asn' ,
25+ 'organisation' ,
26+ 'postal' ,
27+ 'calling_code' ,
28+ 'flag' ,
29+ 'emoji_flag' ,
30+ 'emoji_unicode' ,
31+ 'carrier' ,
32+ 'languages' ,
33+ 'currency' ,
34+ 'time_zone' ,
35+ 'threat' ,
36+ 'count' ,
37+ 'status' ,
38+ ] ;
1339const BASE_URL = 'https://api.ipdata.co/' ;
1440
15- function isValidIP ( ip : string ) {
41+ function isValidIP ( ip : string ) : boolean {
1642 return ip === DEFAULT_IP || isIP ( ip ) ;
1743}
1844
19- function isValidSelectField ( field : string ) {
45+ function isValidSelectField ( field : string ) : boolean {
2046 const index = VALID_FIELDS . indexOf ( field ) ;
2147
2248 if ( index === - 1 ) {
@@ -26,27 +52,27 @@ function isValidSelectField(field: string) {
2652 return true ;
2753}
2854
29- function isValidFields ( fields : string [ ] ) {
55+ function isValidFields ( fields : string [ ] ) : boolean {
3056 if ( ! isArray ( fields ) ) {
3157 throw new Error ( 'Fields should be an array.' ) ;
3258 }
3359
34- for ( const field of fields ) {
60+ fields . forEach ( field => {
3561 const index = VALID_FIELDS . indexOf ( field ) ;
3662 if ( index === - 1 ) {
3763 throw new Error ( `${ field } is not a valid field.` ) ;
3864 }
39- }
65+ } ) ;
4066
4167 return true ;
4268}
4369
44- export function clearCache ( ip ?: string ) {
45- if ( isValidIP ( ip ) ) {
46- return cache . del ( ip ) ;
47- }
48- return cache . reset ( ) ;
49- }
70+ // export function clearCache(ip?: string): void {
71+ // if (isValidIP(ip)) {
72+ // return cache.del(ip);
73+ // }
74+ // return cache.reset();
75+ // }
5076
5177export interface LookupResponse {
5278 ip : string ;
@@ -101,15 +127,21 @@ export interface LookupResponse {
101127}
102128
103129export interface BulkLookupResponse {
104- responses : LookupResponse [ ] ,
130+ responses : LookupResponse [ ] ;
105131 status : number ;
106132}
107133
134+ // eslint-disable-next-line @typescript-eslint/interface-name-prefix
135+ interface IPDataParams {
136+ 'api-key' : string ;
137+ fields ?: string ;
138+ }
139+
108140export default class IPData {
109141 apiKey ?: string ;
110142 useCache ?: boolean ;
111143
112- constructor ( apiKey : string , useCache : boolean = true ) {
144+ constructor ( apiKey : string , useCache = true ) {
113145 if ( ! isString ( apiKey ) ) {
114146 throw new Error ( 'An API key is required.' ) ;
115147 }
@@ -119,7 +151,7 @@ export default class IPData {
119151 }
120152
121153 async lookup ( ip ?: string , selectField ?: string , fields ?: string [ ] ) : Promise < LookupResponse > {
122- const params : any = { 'api-key' : this . apiKey } ;
154+ const params : IPDataParams = { 'api-key' : this . apiKey } ;
123155 let url = ip ? urljoin ( BASE_URL , ip ) : BASE_URL ;
124156
125157 if ( ip && ! isValidIP ( ip ) ) {
@@ -147,38 +179,37 @@ export default class IPData {
147179 let data = { ...response . data , status : response . status } ;
148180
149181 if ( selectField ) {
150- data = { 'select_field' : response . data , status : response . status } ;
182+ data = { [ selectField ] : response . data , status : response . status } ;
151183 }
152184
153- if ( this . useCache ) {
185+ if ( ( ! selectField || ! fields ) && this . useCache ) {
154186 cache . set ( ip || DEFAULT_IP , data ) ;
155187 } else {
156188 return data ;
157189 }
158190 } catch ( e ) {
159191 const { response } = e as AxiosError ;
160192 if ( response ) {
161- return { ...response . data , status : response . status }
162- } else {
163- throw e ;
193+ return { ...response . data , status : response . status } ;
164194 }
195+ throw e ;
165196 }
166197
167198 return cache . get ( ip || DEFAULT_IP ) ;
168199 }
169200
170201 async bulkLookup ( ips : string [ ] , fields ?: string [ ] ) : Promise < BulkLookupResponse > {
171- const params : any = { 'api-key' : this . apiKey } ;
202+ const params : IPDataParams = { 'api-key' : this . apiKey } ;
172203
173204 if ( ips . length < 2 ) {
174205 throw new Error ( 'Bulk Lookup requires more than 1 IP Address in the payload.' ) ;
175206 }
176207
177- for ( const ip of ips ) {
208+ ips . forEach ( ip => {
178209 if ( ! isValidIP ( ip ) ) {
179210 throw new Error ( `${ ip } is an invalid IP address.` ) ;
180211 }
181- }
212+ } ) ;
182213
183214 if ( fields && isValidFields ( fields ) ) {
184215 params . fields = fields . join ( ',' ) ;
@@ -191,9 +222,8 @@ export default class IPData {
191222 const { response } = e as AxiosError ;
192223 if ( response ) {
193224 return { ...response . data , status : response . status } ;
194- } else {
195- throw e ;
196225 }
226+ throw e ;
197227 }
198228 }
199229}
0 commit comments