@@ -7,7 +7,6 @@ import LRU from 'lru-cache';
77
88const CACHE_MAX = 4096 ; // max number of items
99const CACHE_MAX_AGE = 1000 * 60 * 60 * 24 ; // 24 hours
10- const cache = new LRU < string , LookupResponse > ( { max : CACHE_MAX , maxAge : CACHE_MAX_AGE } ) ;
1110const DEFAULT_IP = 'DEFAULT_IP' ;
1211const VALID_FIELDS = [
1312 'ip' ,
@@ -67,12 +66,10 @@ function isValidFields(fields: string[]): boolean {
6766 return true ;
6867}
6968
70- // export function clearCache(ip?: string): void {
71- // if (isValidIP(ip)) {
72- // return cache.del(ip);
73- // }
74- // return cache.reset();
75- // }
69+ export interface CacheConfig {
70+ max ?: number ;
71+ maxAge ?: number ;
72+ }
7673
7774export interface LookupResponse {
7875 ip : string ;
@@ -139,15 +136,15 @@ interface IPDataParams {
139136
140137export default class IPData {
141138 apiKey ?: string ;
142- useCache ?: boolean ;
139+ cache ?: LRU < string , LookupResponse > ;
143140
144- constructor ( apiKey : string , useCache = true ) {
141+ constructor ( apiKey : string , cacheConfig ?: CacheConfig ) {
145142 if ( ! isString ( apiKey ) ) {
146143 throw new Error ( 'An API key is required.' ) ;
147144 }
148145
149146 this . apiKey = apiKey ;
150- this . useCache = useCache === true ;
147+ this . cache = new LRU < string , LookupResponse > ( { max : CACHE_MAX , maxAge : CACHE_MAX_AGE , ... cacheConfig } ) ;
151148 }
152149
153150 async lookup ( ip ?: string , selectField ?: string , fields ?: string [ ] ) : Promise < LookupResponse > {
@@ -158,8 +155,8 @@ export default class IPData {
158155 throw new Error ( `${ ip } is an invalid IP address.` ) ;
159156 }
160157
161- if ( this . useCache && cache . has ( ip || DEFAULT_IP ) ) {
162- return cache . get ( ip || DEFAULT_IP ) ;
158+ if ( this . cache . has ( ip || DEFAULT_IP ) ) {
159+ return this . cache . get ( ip || DEFAULT_IP ) ;
163160 }
164161
165162 if ( selectField && fields ) {
@@ -182,11 +179,7 @@ export default class IPData {
182179 data = { [ selectField ] : response . data , status : response . status } ;
183180 }
184181
185- if ( ( ! selectField || ! fields ) && this . useCache ) {
186- cache . set ( ip || DEFAULT_IP , data ) ;
187- } else {
188- return data ;
189- }
182+ this . cache . set ( ip || DEFAULT_IP , data ) ;
190183 } catch ( e ) {
191184 const { response } = e as AxiosError ;
192185 if ( response ) {
@@ -195,11 +188,13 @@ export default class IPData {
195188 throw e ;
196189 }
197190
198- return cache . get ( ip || DEFAULT_IP ) ;
191+ return this . cache . get ( ip || DEFAULT_IP ) ;
199192 }
200193
201194 async bulkLookup ( ips : string [ ] , fields ?: string [ ] ) : Promise < BulkLookupResponse > {
202195 const params : IPDataParams = { 'api-key' : this . apiKey } ;
196+ const responses : LookupResponse [ ] = [ ] ;
197+ const bulk = [ ] ;
203198
204199 if ( ips . length < 2 ) {
205200 throw new Error ( 'Bulk Lookup requires more than 1 IP Address in the payload.' ) ;
@@ -209,15 +204,30 @@ export default class IPData {
209204 if ( ! isValidIP ( ip ) ) {
210205 throw new Error ( `${ ip } is an invalid IP address.` ) ;
211206 }
207+
208+ if ( this . cache . has ( ip ) ) {
209+ responses . push ( this . cache . get ( ip ) ) ;
210+ } else {
211+ bulk . push ( ip ) ;
212+ }
212213 } ) ;
213214
214215 if ( fields && isValidFields ( fields ) ) {
215216 params . fields = fields . join ( ',' ) ;
216217 }
217218
218219 try {
219- const response = await axios . post ( urljoin ( BASE_URL , 'bulk' ) , ips , { params } ) ;
220- return { responses : response . data , status : response . status } ;
220+ let result : BulkLookupResponse = { responses, status : 200 } ;
221+
222+ if ( bulk . length > 0 ) {
223+ const response = await axios . post ( urljoin ( BASE_URL , 'bulk' ) , bulk , { params } ) ;
224+ response . data . forEach ( info => {
225+ this . cache . set ( info . ip , info ) ;
226+ } ) ;
227+ result = { responses : [ ...responses , ...response . data ] , status : response . status } ;
228+ }
229+
230+ return result ;
221231 } catch ( e ) {
222232 const { response } = e as AxiosError ;
223233 if ( response ) {
0 commit comments