geoip-lite2 2.2.8-beta.3 → 2.2.8-beta.6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1 +1 @@
1
- f4a4c624512ef085feded9b74f5a797c1fedfae6c9a31d1a2c65462e23338d24 GeoLite2-City-CSV_20251107.zip
1
+ e6e3de413a870dd57e1801fbf3f3123c0798aee81c6c01dad9da53fcb023bc00 GeoLite2-City-CSV_20251121.zip
@@ -1 +1 @@
1
- f6acd69d1aae734a4ccf1130d6133c99042c716ff814a4cc045b2109406c543b GeoLite2-Country-CSV_20251107.zip
1
+ 098468175e0cecd62499b0430c8876e412471df27c32f8c7a2618b8e90025708 GeoLite2-Country-CSV_20251121.zip
Binary file
Binary file
Binary file
Binary file
Binary file
package/dist/main.js CHANGED
@@ -1 +1 @@
1
- const{open:e,fstat:r,read:t,close:n,openSync:i,fstatSync:o,readSync:a,closeSync:l}=require('node:fs'),{join:f,resolve:u}=require('node:path'),{isIP:c}=require('node:net'),s=require('async'),{aton4:d,aton6:B,cmp6:y,ntoa4:I,ntoa6:m,cmp:E}=require('./utils.js'),S=require('./fsWatcher.js'),{version:g}=require('../package.json'),z='dataWatcher',p=u(__dirname,global.geoDataDir||process.env.GEODATADIR||'../data/'),P={city:f(p,'geoip-city.dat'),city6:f(p,'geoip-city6.dat'),cityNames:f(p,'geoip-city-names.dat'),country:f(p,'geoip-country.dat'),country6:f(p,'geoip-country6.dat')},h=[[d('10.0.0.0'),d('10.255.255.255')],[d('172.16.0.0'),d('172.31.255.255')],[d('192.168.0.0'),d('192.168.255.255')]],F={firstIP:null,lastIP:null,lastLine:0,locationBuffer:null,locationRecordSize:88,mainBuffer:null,recordSize:24},L={firstIP:null,lastIP:null,lastLine:0,mainBuffer:null,recordSize:48};let U={...F},D={...L};const N=e=>{const r=e.indexOf('\0');return-1===r?e:e.substring(0,r)},T=(e,r,t,n)=>{const i=[];for(let o=0;o<2;o++)i.push(e.readUInt32BE(r*t+16*n+4*o));return i},w=e=>{let r,t,n=0,i=U.lastLine,o=U.lastIP,a=U.firstIP;const l=U.mainBuffer,f=U.locationBuffer,u=h,c=U.recordSize,s=U.locationRecordSize,d={range:[null,null],country:'',region:'',eu:'',timezone:'',city:'',ll:[null,null],metro:null,area:null};if(e>U.lastIP||e<U.firstIP)return null;for(let r=0;r<u.length;r++)if(e>=u[r][0]&&e<=u[r][1])return null;for(;;){r=Math.round((i-n)/2)+n;const u=r*c;if(o=l.readUInt32BE(u),a=l.readUInt32BE(u+4),o<=e&&a>=e){if(d.range=[o,a],10===c)d.country=l.toString('utf8',u+8,u+10);else if(t=l.readUInt32BE(u+8),-1>>>0>t){const e=t*s;d.country=N(f.toString('utf8',e,e+2)),d.region=N(f.toString('utf8',e+2,e+5)),d.metro=f.readInt32BE(e+5),d.ll[0]=l.readInt32BE(u+12)/1e4,d.ll[1]=l.readInt32BE(u+16)/1e4,d.area=l.readUInt32BE(u+20),d.eu=N(f.toString('utf8',e+9,e+10)),d.timezone=N(f.toString('utf8',e+10,e+42)),d.city=N(f.toString('utf8',e+42,e+s))}return d}if(n===i)return null;n===i-1?r===n?n=i:i=n:o>e?i=r:a<e&&(n=r)}};function A(f){let u,c;const d={...F};if('function'==typeof arguments[0])s.series([i=>{s.series([r=>{e(P.cityNames,'r',(e,t)=>{u=t,r(e)})},e=>{r(u,(r,t)=>{c=t.size,d.locationBuffer=Buffer.alloc(c),e(r)})},e=>{t(u,d.locationBuffer,0,c,0,e)},e=>{n(u,e)},r=>{e(P.city,'r',(e,t)=>{u=t,r(e)})},e=>{r(u,(r,t)=>{c=t.size,e(r)})}],t=>{if(t){if('ENOENT'!==t.code&&'EBADF'!==t.code)throw t;e(P.country,'r',(e,t)=>{e?i(e):(u=t,r(u,(e,r)=>{c=r.size,d.recordSize=10,i()}))})}else i()})},()=>{d.mainBuffer=Buffer.alloc(c),s.series([e=>{t(u,d.mainBuffer,0,c,0,e)},e=>{n(u,e)}],e=>{e||(d.lastLine=c/d.recordSize-1,d.lastIP=d.mainBuffer.readUInt32BE(d.lastLine*d.recordSize+4),d.firstIP=d.mainBuffer.readUInt32BE(0),U=d),f(e)})}]);else{try{if(u=i(P.cityNames,'r'),c=o(u).size,0===c){const e=new Error('Empty file');throw e.code='EMPTY_FILE',e}U.locationBuffer=Buffer.alloc(c),a(u,U.locationBuffer,0,c,0),l(u),u=i(P.city,'r'),c=o(u).size}catch(e){if('ENOENT'!==e.code&&'EBADF'!==e.code&&'EMPTY_FILE'!==e.code)throw e;u=i(P.country,'r'),c=o(u).size,U.recordSize=10}U.mainBuffer=Buffer.alloc(c),a(u,U.mainBuffer,0,c,0),l(u),U.lastLine=c/U.recordSize-1,U.lastIP=U.mainBuffer.readUInt32BE(U.lastLine*U.recordSize+4),U.firstIP=U.mainBuffer.readUInt32BE(0)}}function W(f){let u,c;const d={...L};if('function'==typeof arguments[0])s.series([t=>{s.series([r=>{e(P.city6,'r',(e,t)=>{u=t,r(e)})},e=>{r(u,(r,t)=>{c=t.size,e(r)})}],n=>{if(n){if('ENOENT'!==n.code&&'EBADF'!==n.code)throw n;e(P.country6,'r',(e,n)=>{e?t(e):(u=n,r(u,(e,r)=>{c=r.size,d.recordSize=34,t()}))})}else t()})},()=>{d.mainBuffer=Buffer.alloc(c),s.series([e=>{t(u,d.mainBuffer,0,c,0,e)},e=>{n(u,e)}],e=>{e||(d.lastLine=c/d.recordSize-1,d.lastIP=T(d.mainBuffer,d.lastLine,d.recordSize,1),d.firstIP=T(d.mainBuffer,0,d.recordSize,0),D=d),f(e)})}]);else{try{if(u=i(P.city6,'r'),c=o(u).size,0===c){const e=new Error('Empty file');throw e.code='EMPTY_FILE',e}}catch(e){if('ENOENT'!==e.code&&'EBADF'!==e.code&&'EMPTY_FILE'!==e.code)throw e;u=i(P.country6,'r'),c=o(u).size,D.recordSize=34}D.mainBuffer=Buffer.alloc(c),a(u,D.mainBuffer,0,c,0),l(u),D.lastLine=c/D.recordSize-1,D.lastIP=T(D.mainBuffer,D.lastLine,D.recordSize,1),D.firstIP=T(D.mainBuffer,0,D.recordSize,0)}}module.exports={cmp:E,lookup:e=>{if(!e)return null;if('number'==typeof e)return w(e);if(4===c(e))return w(d(e));if(6===c(e)){const r=(e=>{const r=e.toUpperCase();return r.startsWith("0:0:0:0:0:FFFF:")?r.substring(15):r.startsWith("::FFFF:")?r.substring(7):null})(e);return r?w(d(r)):(e=>{const r=D.mainBuffer,t=D.recordSize,n=U.locationBuffer,i=U.locationRecordSize,o={range:[null,null],country:'',region:'',city:'',ll:[0,0],metro:null,area:null,eu:'',timezone:''};let a,l,f=0,u=D.lastLine,c=D.lastIP,s=D.firstIP;if(y(e,D.lastIP)>0||y(e,D.firstIP)<0)return null;for(;;){if(a=Math.round((u-f)/2)+f,c=T(r,a,t,0),s=T(r,a,t,1),y(c,e)<=0&&y(s,e)>=0){const e=a*t;if(34===t)o.country=N(r.toString('utf8',e+32,e+34));else if(l=r.readUInt32BE(e+32),-1>>>0>l){const t=l*i;o.country=N(n.toString('utf8',t,t+2)),o.region=N(n.toString('utf8',t+2,t+5)),o.metro=n.readInt32BE(t+5),o.ll[0]=r.readInt32BE(e+36)/1e4,o.ll[1]=r.readInt32BE(e+40)/1e4,o.area=r.readUInt32BE(e+44),o.eu=N(n.toString('utf8',t+9,t+10)),o.timezone=N(n.toString('utf8',t+10,t+42)),o.city=N(n.toString('utf8',t+42,t+i))}return o}if(f===u)return null;f===u-1?a===f?f=u:u=f:y(c,e)>0?u=a:y(s,e)<0&&(f=a)}})(B(e))}return null},pretty:e=>'string'==typeof e?e:'number'==typeof e?I(e):Array.isArray(e)?m(e):e,startWatchingDataUpdate:e=>{S.makeFsWatchFilter(z,p,6e4,()=>{s.series([e=>{A(e)},e=>{W(e)}],e)})},stopWatchingDataUpdate:()=>S.stopWatching(z),clear:()=>{U={...F},D={...L}},reloadDataSync:()=>{A(),W()},reloadData:e=>{s.series([e=>{A(e)},e=>{W(e)}],e)},version:g},A(),W();
1
+ const{open:e,fstat:r,read:t,close:n,openSync:i,fstatSync:o,readSync:a,closeSync:l}=require('node:fs'),{join:f,resolve:u}=require('node:path'),{isIP:c}=require('node:net'),s=require('async'),{aton4:d,aton6:B,cmp6:y,ntoa4:I,ntoa6:m,cmp:E}=require('./utils.js'),S=require('./fsWatcher.js'),{version:g}=require('../package.json'),z='dataWatcher',p=u(__dirname,global.geoDataDir||process.env.GEODATADIR||'../data/'),P={city:f(p,'geoip-city.dat'),city6:f(p,'geoip-city6.dat'),cityNames:f(p,'geoip-city-names.dat'),country:f(p,'geoip-country.dat'),country6:f(p,'geoip-country6.dat')},h=[[d('10.0.0.0'),d('10.255.255.255')],[d('172.16.0.0'),d('172.31.255.255')],[d('192.168.0.0'),d('192.168.255.255')]],F={firstIP:null,lastIP:null,lastLine:0,locationBuffer:null,locationRecordSize:88,mainBuffer:null,recordSize:24},L={firstIP:null,lastIP:null,lastLine:0,mainBuffer:null,recordSize:48};let U={...F},D={...L};const N=e=>{const r=e.indexOf('\0');return-1===r?e:e.substring(0,r)},T=(e,r,t,n)=>{const i=[];for(let o=0;o<2;o++)i.push(e.readUInt32BE(r*t+16*n+4*o));return i},w=e=>{let r,t,n=0,i=U.lastLine,o=U.lastIP,a=U.firstIP;const l=U.mainBuffer,f=U.locationBuffer,u=h,c=U.recordSize,s=U.locationRecordSize,d={range:[null,null],country:'',region:'',eu:'',timezone:'',city:'',ll:[null,null],metro:null,area:null};if(e>U.lastIP||e<U.firstIP)return null;for(let r=0;r<u.length;r++)if(e>=u[r][0]&&e<=u[r][1])return null;for(;;){r=Math.round((i-n)/2)+n;const u=r*c;if(o=l.readUInt32BE(u),a=l.readUInt32BE(u+4),o<=e&&a>=e){if(d.range=[o,a],10===c)d.country=l.toString('utf8',u+8,u+10);else if(t=l.readUInt32BE(u+8),-1>>>0>t){const e=t*s;d.country=N(f.toString('utf8',e,e+2)),d.region=N(f.toString('utf8',e+2,e+5)),d.metro=f.readInt32BE(e+5),d.ll[0]=l.readInt32BE(u+12)/1e4,d.ll[1]=l.readInt32BE(u+16)/1e4,d.area=l.readUInt32BE(u+20),d.eu=N(f.toString('utf8',e+9,e+10)),d.timezone=N(f.toString('utf8',e+10,e+42)),d.city=N(f.toString('utf8',e+42,e+s))}return d}if(n===i)return null;n===i-1?r===n?n=i:i=n:o>e?i=r:a<e&&(n=r)}};function A(f){let u,c;const d={...F};if('function'==typeof arguments[0])s.series([i=>{s.series([r=>{e(P.cityNames,'r',(e,t)=>{u=t,r(e)})},e=>{r(u,(r,t)=>{c=t.size,d.locationBuffer=Buffer.alloc(c),e(r)})},e=>{t(u,d.locationBuffer,0,c,0,e)},e=>{n(u,e)},r=>{e(P.city,'r',(e,t)=>{u=t,r(e)})},e=>{r(u,(r,t)=>{c=t.size,e(r)})}],t=>{if(t){if('ENOENT'!==t.code&&'EBADF'!==t.code)throw t;e(P.country,'r',(e,t)=>{e?i(e):(u=t,r(u,(e,r)=>{c=r.size,d.recordSize=10,i()}))})}else i()})},()=>{d.mainBuffer=Buffer.alloc(c),s.series([e=>{t(u,d.mainBuffer,0,c,0,e)},e=>{n(u,e)}],e=>{e||(d.lastLine=c/d.recordSize-1,d.lastIP=d.mainBuffer.readUInt32BE(d.lastLine*d.recordSize+4),d.firstIP=d.mainBuffer.readUInt32BE(0),U=d),f(e)})}]);else{try{if(u=i(P.cityNames,'r'),c=o(u).size,0===c){const e=new Error('Empty file');throw e.code='EMPTY_FILE',e}U.locationBuffer=Buffer.alloc(c),a(u,U.locationBuffer,0,c,0),l(u),u=i(P.city,'r'),c=o(u).size}catch(e){if('ENOENT'!==e.code&&'EBADF'!==e.code&&'EMPTY_FILE'!==e.code)throw e;u=i(P.country,'r'),c=o(u).size,U.recordSize=10}U.mainBuffer=Buffer.alloc(c),a(u,U.mainBuffer,0,c,0),l(u),U.lastLine=c/U.recordSize-1,U.lastIP=U.mainBuffer.readUInt32BE(U.lastLine*U.recordSize+4),U.firstIP=U.mainBuffer.readUInt32BE(0)}}function W(f){let u,c;const d={...L};if('function'==typeof arguments[0])s.series([t=>{s.series([r=>{e(P.city6,'r',(e,t)=>{u=t,r(e)})},e=>{r(u,(r,t)=>{c=t.size,e(r)})}],n=>{if(n){if('ENOENT'!==n.code&&'EBADF'!==n.code)throw n;e(P.country6,'r',(e,n)=>{e?t(e):(u=n,r(u,(e,r)=>{c=r.size,d.recordSize=34,t()}))})}else t()})},()=>{d.mainBuffer=Buffer.alloc(c),s.series([e=>{t(u,d.mainBuffer,0,c,0,e)},e=>{n(u,e)}],e=>{e||(d.lastLine=c/d.recordSize-1,d.lastIP=T(d.mainBuffer,d.lastLine,d.recordSize,1),d.firstIP=T(d.mainBuffer,0,d.recordSize,0),D=d),f(e)})}]);else{try{if(u=i(P.city6,'r'),c=o(u).size,0===c){const e=new Error('Empty file');throw e.code='EMPTY_FILE',e}}catch(e){if('ENOENT'!==e.code&&'EBADF'!==e.code&&'EMPTY_FILE'!==e.code)throw e;u=i(P.country6,'r'),c=o(u).size,D.recordSize=34}D.mainBuffer=Buffer.alloc(c),a(u,D.mainBuffer,0,c,0),l(u),D.lastLine=c/D.recordSize-1,D.lastIP=T(D.mainBuffer,D.lastLine,D.recordSize,1),D.firstIP=T(D.mainBuffer,0,D.recordSize,0)}}module.exports={cmp:E,lookup:e=>{if(!e)return null;if('number'==typeof e)return w(e);if(4===c(e))return w(d(e));if(6===c(e)){const r=(e=>{const r=e.toUpperCase();return r.startsWith("0:0:0:0:0:FFFF:")?r.substring(15):r.startsWith("::FFFF:")?r.substring(7):null})(e);return r?w(d(r)):(e=>{const r=D.mainBuffer,t=D.recordSize,n=U.locationBuffer,i=U.locationRecordSize,o={range:[null,null],country:'',region:'',eu:'',timezone:'',city:'',ll:[null,null],metro:null,area:null};let a,l,f=0,u=D.lastLine,c=D.lastIP,s=D.firstIP;if(y(e,D.lastIP)>0||y(e,D.firstIP)<0)return null;for(;;){if(a=Math.round((u-f)/2)+f,c=T(r,a,t,0),s=T(r,a,t,1),y(c,e)<=0&&y(s,e)>=0){const e=a*t;if(34===t)o.country=N(r.toString('utf8',e+32,e+34));else if(l=r.readUInt32BE(e+32),-1>>>0>l){const t=l*i;o.country=N(n.toString('utf8',t,t+2)),o.region=N(n.toString('utf8',t+2,t+5)),o.metro=n.readInt32BE(t+5),o.ll[0]=r.readInt32BE(e+36)/1e4,o.ll[1]=r.readInt32BE(e+40)/1e4,o.area=r.readUInt32BE(e+44),o.eu=N(n.toString('utf8',t+9,t+10)),o.timezone=N(n.toString('utf8',t+10,t+42)),o.city=N(n.toString('utf8',t+42,t+i))}return o}if(f===u)return null;f===u-1?a===f?f=u:u=f:y(c,e)>0?u=a:y(s,e)<0&&(f=a)}})(B(e))}return null},pretty:e=>'string'==typeof e?e:'number'==typeof e?I(e):Array.isArray(e)?m(e):e,startWatchingDataUpdate:e=>{S.makeFsWatchFilter(z,p,6e4,()=>{s.series([e=>{A(e)},e=>{W(e)}],e)})},stopWatchingDataUpdate:()=>S.stopWatching(z),clear:()=>{U={...F},D={...L}},reloadDataSync:()=>{A(),W()},reloadData:e=>{s.series([e=>{A(e)},e=>{W(e)}],e)},version:g},A(),W();
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "geoip-lite2",
3
- "version": "2.2.8-beta.3",
3
+ "version": "2.2.8-beta.6",
4
4
  "description": "A light weight native JavaScript implementation of GeoIP API from MaxMind. Improved and faster version by Sefinek.",
5
5
  "keywords": [
6
6
  "city",
@@ -68,6 +68,8 @@
68
68
  "README.md"
69
69
  ],
70
70
  "scripts": {
71
+ "lint": "eslint .",
72
+ "lint:fix": "eslint . --fix",
71
73
  "minify": "node minify.js",
72
74
  "test": "jest test",
73
75
  "up": "ncu -u && npm install && npm update && npm audit fix",
@@ -80,7 +82,7 @@
80
82
  "async": "^3.2.6",
81
83
  "iconv-lite": "0.7.0",
82
84
  "ip-address": "^10.1.0",
83
- "rimraf": "^6.1.0"
85
+ "rimraf": "^6.1.2"
84
86
  },
85
87
  "devDependencies": {
86
88
  "@eslint/js": "^9.39.1",
@@ -89,6 +91,6 @@
89
91
  "terser": "^5.44.1"
90
92
  },
91
93
  "engines": {
92
- "node": ">=10.3.0"
94
+ "node": ">=20.0.0"
93
95
  }
94
96
  }
package/tools/updatedb.js CHANGED
@@ -32,12 +32,10 @@ const { Address6, Address4 } = require('ip-address');
32
32
 
33
33
  // Logging utility for consistent and readable output
34
34
  const log = {
35
- info: (msg, ...logArgs) => console.log('[INFO]', msg, ...logArgs),
36
- success: (msg, ...logArgs) => console.log('[SUCCESS]', msg, ...logArgs),
37
- warn: (msg, ...logArgs) => console.warn('[WARN]', msg, ...logArgs),
38
- error: (msg, ...logArgs) => console.error('[ERROR]', msg, ...logArgs),
39
- progress: (msg) => process.stdout.write(`[INFO] ${msg}... `),
40
- done: () => console.log('Done'),
35
+ info: (msg, ...logArgs) => console.log(`[INFO] ${msg}`, ...logArgs),
36
+ success: (msg, ...logArgs) => console.log(`[SUCCESS] ${msg}`, ...logArgs),
37
+ warn: (msg, ...logArgs) => console.warn(`[WARN] ${msg}`, ...logArgs),
38
+ error: (msg, ...logArgs) => console.error(`[ERROR] ${msg}`, ...logArgs),
41
39
  };
42
40
 
43
41
  // ============================================================================
@@ -114,8 +112,8 @@ function tryFixingLine(line) {
114
112
  pos1 = pos2;
115
113
  pos2 = line.indexOf(',', pos1 + 1);
116
114
  if (pos2 < 0) pos2 = line.length;
117
- if (line.indexOf('\'', (pos1 || 0)) > -1 && line.indexOf('\'', pos1) < pos2 && line[pos1 + 1] != '"' && line[pos2 - 1] != '"') {
118
- line = line.substr(0, pos1 + 1) + '"' + line.substr(pos1 + 1, pos2 - pos1 - 1) + '"' + line.substr(pos2, line.length - pos2);
115
+ if (line.indexOf('\'', (pos1 || 0)) > -1 && line.indexOf('\'', pos1) < pos2 && line[pos1 + 1] !== '"' && line[pos2 - 1] !== '"') {
116
+ line = line.substring(0, pos1 + 1) + '"' + line.substring(pos1 + 1, pos2) + '"' + line.substring(pos2);
119
117
  pos2 = line.indexOf(',', pos2 + 1);
120
118
  if (pos2 < 0) pos2 = line.length;
121
119
  }
@@ -267,14 +265,12 @@ function fetch(database, cb) {
267
265
  }
268
266
 
269
267
  tmpFilePipe.on('close', () => {
270
- log.done();
268
+ log.info(`Retrieved ${fileName}`);
271
269
  cb(null, tmpFile, fileName, database);
272
270
  });
273
271
  }
274
272
 
275
273
  mkdir(tmpFile);
276
-
277
- log.progress(`Retrieving ${fileName}`);
278
274
  }
279
275
 
280
276
  function extract(tmpFile, tmpFileName, database, cb) {
@@ -283,7 +279,7 @@ function extract(tmpFile, tmpFileName, database, cb) {
283
279
  if (path.extname(tmpFileName) !== '.zip') {
284
280
  cb(null, database);
285
281
  } else {
286
- log.progress('Extracting ' + tmpFileName);
282
+ log.info('Extracting ' + tmpFileName);
287
283
  const zip = new AdmZip(tmpFile);
288
284
  const zipEntries = zip.getEntries();
289
285
 
@@ -297,7 +293,7 @@ function extract(tmpFile, tmpFileName, database, cb) {
297
293
  fs.writeFileSync(destinationPath, entry.getData());
298
294
  });
299
295
 
300
- log.done();
296
+ log.info('Extracted ' + tmpFileName);
301
297
  cb(null, database);
302
298
  }
303
299
  }
@@ -313,7 +309,7 @@ function processLookupCountry(src, cb) {
313
309
  }
314
310
  const tmpDataFile = path.join(tmpPath, src);
315
311
 
316
- log.progress('Processing lookup data (this may take a moment)');
312
+ log.info('Processing lookup data');
317
313
 
318
314
  const rl = readline.createInterface({ input: fs.createReadStream(tmpDataFile).pipe(decodeStream('latin1')), output: process.stdout, terminal: false });
319
315
 
@@ -324,7 +320,7 @@ function processLookupCountry(src, cb) {
324
320
  });
325
321
 
326
322
  rl.on('close', () => {
327
- log.done();
323
+ log.info('Processed lookup data');
328
324
  cb();
329
325
  });
330
326
  }
@@ -341,8 +337,7 @@ async function processCountryData(src, dest) {
341
337
  rimraf(dataFile);
342
338
  mkdir(dataFile);
343
339
 
344
- process.stdout.write('\n');
345
- log.progress('Processing country data (this may take a moment)');
340
+ log.info('Processing country data');
346
341
  let tstart = Date.now();
347
342
  const datFile = fs.createWriteStream(dataFile);
348
343
 
@@ -380,8 +375,8 @@ async function processCountryData(src, dest) {
380
375
  bsz = 10;
381
376
 
382
377
  rngip = new Address4(fields[0]);
383
- sip = parseInt(rngip.startAddress().bigInt(), 10);
384
- eip = parseInt(rngip.endAddress().bigInt(), 10);
378
+ sip = parseInt(rngip.startAddress().bigInt().toString(), 10);
379
+ eip = parseInt(rngip.endAddress().bigInt().toString(), 10);
385
380
 
386
381
  b = Buffer.alloc(bsz);
387
382
  b.fill(0);
@@ -392,7 +387,7 @@ async function processCountryData(src, dest) {
392
387
  b.write(cc, bsz - 2);
393
388
  if (Date.now() - tstart > 5000) {
394
389
  tstart = Date.now();
395
- process.stdout.write(`\nStill working (${lines})...`);
390
+ log.info(`Processing country data (${lines} entries)`);
396
391
  }
397
392
 
398
393
  if (datFile._writableState.needDrain) {
@@ -405,15 +400,53 @@ async function processCountryData(src, dest) {
405
400
  }
406
401
  }
407
402
 
408
- const rl = readline.createInterface({ input: fs.createReadStream(tmpDataFile), crlfDelay: Infinity });
409
- let i = 0;
410
- for await (const line of rl) {
411
- i++;
412
- if (i === 1) continue;
413
- await processLine(line);
414
- }
403
+ await new Promise((resolve, reject) => {
404
+ const rl = readline.createInterface({ input: fs.createReadStream(tmpDataFile), crlfDelay: Infinity });
405
+ let settled = false;
406
+ let i = 0;
407
+
408
+ function finish(err) {
409
+ if (settled) return;
410
+ settled = true;
411
+ if (!rl.closed) rl.close();
412
+ if (err) reject(err);
413
+ else resolve();
414
+ }
415
+
416
+ function resume() {
417
+ if (!settled && !rl.closed) rl.resume();
418
+ }
419
+
420
+ rl.on('line', line => {
421
+ rl.pause();
422
+ i++;
423
+ if (i === 1) {
424
+ resume();
425
+ return;
426
+ }
427
+
428
+ let result;
429
+ try {
430
+ result = processLine(line);
431
+ } catch (err) {
432
+ finish(err);
433
+ return;
434
+ }
435
+
436
+ if (result && typeof result.then === 'function') {
437
+ result.then(() => {
438
+ resume();
439
+ }).catch(finish);
440
+ } else {
441
+ resume();
442
+ }
443
+ });
444
+
445
+ rl.on('close', () => finish());
446
+ rl.on('error', finish);
447
+ });
415
448
  datFile.close();
416
- log.done();
449
+ log.info('Processed country data');
417
450
  }
418
451
 
419
452
  async function processCityData(src, dest) {
@@ -423,8 +456,7 @@ async function processCityData(src, dest) {
423
456
 
424
457
  rimraf(dataFile);
425
458
 
426
- process.stdout.write('\n');
427
- log.progress('Processing city data (this may take a moment)');
459
+ log.info('Processing city data');
428
460
  let tstart = Date.now();
429
461
  const datFile = fs.createWriteStream(dataFile);
430
462
 
@@ -482,8 +514,8 @@ async function processCityData(src, dest) {
482
514
  bsz = 24;
483
515
 
484
516
  rngip = new Address4(fields[0]);
485
- sip = parseInt(rngip.startAddress().bigInt(), 10);
486
- eip = parseInt(rngip.endAddress().bigInt(), 10);
517
+ sip = parseInt(rngip.startAddress().bigInt().toString(), 10);
518
+ eip = parseInt(rngip.endAddress().bigInt().toString(), 10);
487
519
  locId = parseInt(fields[1], 10);
488
520
  locId = cityLookup[locId];
489
521
  b = Buffer.alloc(bsz);
@@ -502,7 +534,7 @@ async function processCityData(src, dest) {
502
534
 
503
535
  if (Date.now() - tstart > 5000) {
504
536
  tstart = Date.now();
505
- process.stdout.write('\n[INFO] Processing... (' + lines + ' entries) ');
537
+ log.info(`Processing city data (${lines} entries)`);
506
538
  }
507
539
 
508
540
  if (datFile._writableState.needDrain) {
@@ -514,13 +546,51 @@ async function processCityData(src, dest) {
514
546
  }
515
547
  }
516
548
 
517
- const rl = readline.createInterface({ input: fs.createReadStream(tmpDataFile), crlfDelay: Infinity });
518
- let i = 0;
519
- for await (const line of rl) {
520
- i++;
521
- if (i === 1) continue;
522
- await processLine(line);
523
- }
549
+ await new Promise((resolve, reject) => {
550
+ const rl = readline.createInterface({ input: fs.createReadStream(tmpDataFile), crlfDelay: Infinity });
551
+ let settled = false;
552
+ let i = 0;
553
+
554
+ function finish(err) {
555
+ if (settled) return;
556
+ settled = true;
557
+ if (!rl.closed) rl.close();
558
+ if (err) reject(err);
559
+ else resolve();
560
+ }
561
+
562
+ function resume() {
563
+ if (!settled && !rl.closed) rl.resume();
564
+ }
565
+
566
+ rl.on('line', line => {
567
+ rl.pause();
568
+ i++;
569
+ if (i === 1) {
570
+ resume();
571
+ return;
572
+ }
573
+
574
+ let result;
575
+ try {
576
+ result = processLine(line);
577
+ } catch (err) {
578
+ finish(err);
579
+ return;
580
+ }
581
+
582
+ if (result && typeof result.then === 'function') {
583
+ result.then(() => {
584
+ resume();
585
+ }).catch(finish);
586
+ } else {
587
+ resume();
588
+ }
589
+ });
590
+
591
+ rl.on('close', () => finish());
592
+ rl.on('error', finish);
593
+ });
524
594
  datFile.close();
525
595
  }
526
596
 
@@ -610,11 +680,10 @@ function processData(database, cb) {
610
680
  } else if (type === 'city') {
611
681
  processCityDataNames(src[0], dest[0], () => {
612
682
  processCityData(src[1], dest[1]).then(() => {
613
- process.stdout.write('\n');
614
- log.info('City IPv4 data processed');
683
+ log.info('Processed city IPv4 data');
615
684
  return processCityData(src[2], dest[2]);
616
685
  }).then(() => {
617
- log.info('City IPv6 data processed');
686
+ log.info('Processed city IPv6 data');
618
687
  cb(null, database);
619
688
  });
620
689
  });
@@ -653,10 +722,9 @@ async.eachSeries(databases, (database, nextDatabase) => {
653
722
  log.error('Failed to update databases from MaxMind!', err);
654
723
  process.exit(1);
655
724
  } else {
656
- process.stdout.write('\n');
657
725
  log.success('All databases have been successfully updated from MaxMind');
658
726
  if (args.indexOf('debug') !== -1) {
659
- console.debug('Notice: temporary files are not deleted for debug purposes');
727
+ log.info('Debug mode: temporary files preserved at ' + tmpPath);
660
728
  } else {
661
729
  rimraf(tmpPath);
662
730
  }