geoip-lite2 2.2.8-beta.1 → 2.2.8-beta.2

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.
package/dist/main.js CHANGED
@@ -1 +1 @@
1
- const{open:e,fstat:t,read:r,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:E,cmp:g}=require('./utils.js'),m=require('./fsWatcher.js'),{version:S}=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 t=e.indexOf('\0');return-1===t?e:e.substring(0,t)},T=(e,t,r,n)=>{const i=[];for(let o=0;o<2;o++)i.push(e.readUInt32BE(t*r+16*n+4*o));return i},w=e=>{let t,r,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 t=0;t<u.length;t++)if(e>=u[t][0]&&e<=u[t][1])return null;for(;;){t=Math.round((i-n)/2)+n;const u=t*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(r=l.readUInt32BE(u+8),-1>>>0>r){const e=r*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?t===n?n=i:i=n:o>e?i=t:a<e&&(n=t)}},A=['0:0:0:0:0:FFFF:','::FFFF:'];function q(f){let u,c;const d={...F};if('function'==typeof arguments[0])s.series([i=>{s.series([t=>{e(P.cityNames,'r',(e,r)=>{u=r,t(e)})},e=>{t(u,(t,r)=>{c=r.size,d.locationBuffer=Buffer.alloc(c),e(t)})},e=>{r(u,d.locationBuffer,0,c,0,e)},e=>{n(u,e)},t=>{e(P.city,'r',(e,r)=>{u=r,t(e)})},e=>{t(u,(t,r)=>{c=r.size,e(t)})}],r=>{if(r){if('ENOENT'!==r.code&&'EBADF'!==r.code)throw r;e(P.country,'r',(e,r)=>{e?i(e):(u=r,t(u,(e,t)=>{c=t.size,d.recordSize=10,i()}))})}else i()})},()=>{d.mainBuffer=Buffer.alloc(c),s.series([e=>{r(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)throw{code:'EMPTY_FILE'};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 O(f){let u,c;const d={...L};if('function'==typeof arguments[0])s.series([r=>{s.series([t=>{e(P.city6,'r',(e,r)=>{u=r,t(e)})},e=>{t(u,(t,r)=>{c=r.size,e(t)})}],n=>{if(n){if('ENOENT'!==n.code&&'EBADF'!==n.code)throw n;e(P.country6,'r',(e,n)=>{e?r(e):(u=n,t(u,(e,t)=>{c=t.size,d.recordSize=34,r()}))})}else r()})},()=>{d.mainBuffer=Buffer.alloc(c),s.series([e=>{r(u,d.mainBuffer,0,c,0,e)},e=>{n(u,e)}],e=>{e||(d.lastLine=c/d.recordSize-1,D=d),f(e)})}]);else{try{if(u=i(P.city6,'r'),c=o(u).size,0===c)throw{code:'EMPTY_FILE'}}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}}module.exports={cmp:g,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 t=(e=>{const t=e.toUpperCase();for(let e=0;e<A.length;e++){const r=A[e];if(0===t.indexOf(r))return t.substring(r.length)}return null})(e);return t?w(d(t)):(e=>{const t=D.mainBuffer,r=D.recordSize,n=U.locationBuffer,i=U.locationRecordSize,o={range:[null,null],country:'',region:'',city:'',ll:[0,0],metro:null,area:null,eu:'',timezone:''};D.lastIP=T(t,D.lastLine,r,1),D.firstIP=T(t,0,r,0);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(t,a,r,0),s=T(t,a,r,1),y(c,e)<=0&&y(s,e)>=0){const e=a*r;if(34===r)o.country=N(t.toString('utf8',e+32,e+34));else if(l=t.readUInt32BE(e+32),-1>>>0>l){const r=l*i;o.country=N(n.toString('utf8',r,r+2)),o.region=N(n.toString('utf8',r+2,r+5)),o.metro=n.readInt32BE(r+5),o.ll[0]=t.readInt32BE(e+36)/1e4,o.ll[1]=t.readInt32BE(e+40)/1e4,o.area=t.readUInt32BE(e+44),o.eu=N(n.toString('utf8',r+9,r+10)),o.timezone=N(n.toString('utf8',r+10,r+42)),o.city=N(n.toString('utf8',r+42,r+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)?E(e):e,startWatchingDataUpdate:e=>{m.makeFsWatchFilter(z,p,6e4,async()=>{await s.series([e=>{q(e)},e=>{O(e)}],e)})},stopWatchingDataUpdate:()=>m.stopWatching(z),clear:()=>{U={...F},D={...L}},reloadDataSync:()=>{q(),O()},reloadData:async e=>{await s.series([e=>{q(e)},e=>{O(e)}],e)},version:S},q(),O();
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();
package/dist/utils.js CHANGED
@@ -1 +1 @@
1
- const t=module.exports={};t.aton4=t=>{const r=t.split('.');return(parseInt(r[0],10)<<24>>>0)+(parseInt(r[1],10)<<16>>>0)+(parseInt(r[2],10)<<8>>>0)+(parseInt(r[3],10)>>>0)},t.aton6=t=>{const r=(t=t.replace(/"/g,'').split(':')).length-1;let e;if(''===t[r]&&(t[r]=0),r<7)for(t.length=8,e=r;e>=0&&''!==t[e];e--)t[7-r+e]=t[e];for(e=0;e<8;e++)t[e]?t[e]=parseInt(t[e],16):t[e]=0;const n=[];for(e=0;e<4;e++)n.push((t[2*e]<<16)+t[2*e+1]>>>0);return n},t.cmp=(t,r)=>'number'==typeof t&&'number'==typeof r?t<r?-1:t>r?1:0:t instanceof Array&&r instanceof Array?this.cmp6(t,r):null,t.cmp6=(t,r)=>{for(let e=0;e<2;e++){if(t[e]<r[e])return-1;if(t[e]>r[e])return 1}return 0},t.isPrivateIP=t=>{const r=t.toString();return r.startsWith('10.')||r.startsWith('192.168.')||r.startsWith('172.16.')||r.startsWith('127.')||r.startsWith('169.254.')||r.startsWith('fc00:')||r.startsWith('fe80:')},t.ntoa4=t=>((t=t.toString())>>>24&255)+'.'+(t>>>16&255)+'.'+(t>>>8&255)+'.'+(255&t),t.ntoa6=t=>{let r='[';for(let e=0;e<t.length;e++)r+=(t[e]>>>16).toString(16)+':',r+=(65535&t[e]).toString(16)+':';return r=r.replace(/:$/,']').replace(/:0+/g,':').replace(/::+/,'::'),r};
1
+ const t=module.exports={};t.aton4=t=>{const r=t.split('.');return(parseInt(r[0],10)<<24>>>0)+(parseInt(r[1],10)<<16>>>0)+(parseInt(r[2],10)<<8>>>0)+(parseInt(r[3],10)>>>0)},t.ntoa4=t=>(t>>>24&255)+'.'+(t>>>16&255)+'.'+(t>>>8&255)+'.'+(255&t),t.aton6=t=>{const r=(t=t.replace(/"/g,'').split(':')).length-1;let e;if(''===t[r]&&(t[r]=0),r<7)for(t.length=8,e=r;e>=0&&''!==t[e];e--)t[7-r+e]=t[e];for(e=0;e<8;e++)t[e]?t[e]=parseInt(t[e],16):t[e]=0;const n=[];for(e=0;e<4;e++)n.push((t[2*e]<<16)+t[2*e+1]>>>0);return n},t.ntoa6=t=>{let r='[';for(let e=0;e<t.length;e++)r+=(t[e]>>>16).toString(16)+':',r+=(65535&t[e]).toString(16)+':';return r=r.replace(/:$/,']').replace(/:0+/g,':').replace(/::+/,'::'),r},t.cmp=(r,e)=>'number'==typeof r&&'number'==typeof e?r<e?-1:r>e?1:0:r instanceof Array&&e instanceof Array?t.cmp6(r,e):null,t.cmp6=(t,r)=>{for(let e=0;e<2;e++){if(t[e]<r[e])return-1;if(t[e]>r[e])return 1}return 0},t.isPrivateIP=t=>{const r=t.toString();return r.startsWith('10.')||r.startsWith('192.168.')||r.startsWith('172.16.')||r.startsWith('127.')||r.startsWith('169.254.')||r.startsWith('fc00:')||r.startsWith('fe80:')};
package/index.d.ts CHANGED
@@ -2,12 +2,12 @@ interface GeoIp2Location {
2
2
  range: [number | null, number | null];
3
3
  country: string;
4
4
  region: string;
5
- eu: '0' | '1';
5
+ eu: '0' | '1' | '';
6
6
  timezone: string;
7
7
  city: string;
8
8
  ll: [number | null, number | null];
9
- metro: number;
10
- area: number;
9
+ metro: number | null;
10
+ area: number | null;
11
11
  }
12
12
 
13
13
  export function lookup(ip: string | number): GeoIp2Location | null;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "geoip-lite2",
3
- "version": "2.2.8-beta.1",
3
+ "version": "2.2.8-beta.2",
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",
@@ -79,14 +79,14 @@
79
79
  "adm-zip": "^0.5.16",
80
80
  "async": "^3.2.6",
81
81
  "iconv-lite": "0.7.0",
82
- "ip-address": "^10.0.1",
82
+ "ip-address": "^10.1.0",
83
83
  "rimraf": "^6.1.0"
84
84
  },
85
85
  "devDependencies": {
86
86
  "@eslint/js": "^9.39.1",
87
87
  "globals": "^16.5.0",
88
88
  "jest": "^30.2.0",
89
- "terser": "^5.44.0"
89
+ "terser": "^5.44.1"
90
90
  },
91
91
  "engines": {
92
92
  "node": ">=10.3.0"
package/tools/updatedb.js CHANGED
@@ -1,7 +1,14 @@
1
- // Fetches and converts MaxMind lite databases
1
+ // ============================================================================
2
+ // GeoIP Database Updater
3
+ // Fetches and converts MaxMind GeoLite2 databases
4
+ // ============================================================================
2
5
 
3
6
  'use strict';
4
7
 
8
+ // ============================================================================
9
+ // Dependencies
10
+ // ============================================================================
11
+
5
12
  const { name, version } = require('../package.json');
6
13
  const UserAgent = `Mozilla/5.0 (compatible; ${name}/${version}; +https://github.com/sefinek/geoip-lite2)`;
7
14
 
@@ -19,6 +26,10 @@ const AdmZip = require('adm-zip');
19
26
  const utils = require('../lib/utils.js');
20
27
  const { Address6, Address4 } = require('ip-address');
21
28
 
29
+ // ============================================================================
30
+ // Configuration
31
+ // ============================================================================
32
+
22
33
  const args = process.argv.slice(2);
23
34
  let license_key = args.find(arg => arg.match(/^license_key=[a-zA-Z0-9]+/) !== null);
24
35
  if (typeof license_key === 'undefined' && typeof process.env.LICENSE_KEY !== 'undefined') {
@@ -67,6 +78,10 @@ const databases = [{
67
78
  dest: ['geoip-city-names.dat', 'geoip-city.dat', 'geoip-city6.dat'],
68
79
  }];
69
80
 
81
+ // ============================================================================
82
+ // Utility Functions
83
+ // ============================================================================
84
+
70
85
  function mkdir(dirName) {
71
86
  const dir = path.dirname(dirName);
72
87
  if (!fs.existsSync(dir)) fs.mkdirSync(dir);
@@ -118,6 +133,10 @@ function CSVtoArray(text) {
118
133
  return a;
119
134
  }
120
135
 
136
+ // ============================================================================
137
+ // HTTP Configuration
138
+ // ============================================================================
139
+
121
140
  function getHTTPOptions(downloadUrl) {
122
141
  const parsedUrl = new URL(downloadUrl);
123
142
  const options = {
@@ -140,6 +159,10 @@ function getHTTPOptions(downloadUrl) {
140
159
  return options;
141
160
  }
142
161
 
162
+ // ============================================================================
163
+ // Database Download Functions
164
+ // ============================================================================
165
+
143
166
  function check(database, cb) {
144
167
  if (args.indexOf('force') !== -1) {
145
168
  // We are forcing database upgrade,
@@ -156,6 +179,8 @@ function check(database, cb) {
156
179
 
157
180
  console.log('Checking', database.fileName);
158
181
 
182
+ const client = https.get(getHTTPOptions(checksumUrl), onResponse);
183
+
159
184
  function onResponse(response) {
160
185
  const status = response.statusCode;
161
186
  if ([301, 302, 303, 307, 308].includes(status)) {
@@ -190,8 +215,6 @@ function check(database, cb) {
190
215
  cb(null, database);
191
216
  });
192
217
  }
193
-
194
- var client = https.get(getHTTPOptions(checksumUrl), onResponse);
195
218
  });
196
219
  }
197
220
 
@@ -208,6 +231,8 @@ function fetch(database, cb) {
208
231
 
209
232
  console.log('Fetching', fileName);
210
233
 
234
+ const client = https.get(getHTTPOptions(downloadUrl), onResponse);
235
+
211
236
  function onResponse(response) {
212
237
  const status = response.statusCode;
213
238
  if ([301, 302, 303, 307, 308].includes(status)) {
@@ -235,8 +260,6 @@ function fetch(database, cb) {
235
260
 
236
261
  mkdir(tmpFile);
237
262
 
238
- var client = https.get(getHTTPOptions(downloadUrl), onResponse);
239
-
240
263
  process.stdout.write(`Retrieving ${fileName}...`);
241
264
  }
242
265
 
@@ -292,8 +315,22 @@ function processLookupCountry(src, cb) {
292
315
  });
293
316
  }
294
317
 
318
+ // ============================================================================
319
+ // Data Processing Functions
320
+ // ============================================================================
321
+
295
322
  async function processCountryData(src, dest) {
296
323
  let lines = 0;
324
+ const dataFile = path.join(dataPath, dest);
325
+ const tmpDataFile = path.join(tmpPath, src);
326
+
327
+ rimraf(dataFile);
328
+ mkdir(dataFile);
329
+
330
+ process.stdout.write('\nProcessing data (may take a moment)...');
331
+ let tstart = Date.now();
332
+ const datFile = fs.createWriteStream(dataFile);
333
+
297
334
  function processLine(line) {
298
335
  const fields = CSVtoArray(line);
299
336
  if (!fields || fields.length < 6) return console.warn('weird line: %s::', line);
@@ -353,16 +390,6 @@ async function processCountryData(src, dest) {
353
390
  }
354
391
  }
355
392
 
356
- const dataFile = path.join(dataPath, dest);
357
- const tmpDataFile = path.join(tmpPath, src);
358
-
359
- rimraf(dataFile);
360
- mkdir(dataFile);
361
-
362
- process.stdout.write('\nProcessing data (may take a moment)...');
363
- var tstart = Date.now();
364
- var datFile = fs.createWriteStream(dataFile);
365
-
366
393
  const rl = readline.createInterface({ input: fs.createReadStream(tmpDataFile), crlfDelay: Infinity });
367
394
  let i = 0;
368
395
  for await (const line of rl) {
@@ -376,6 +403,15 @@ async function processCountryData(src, dest) {
376
403
 
377
404
  async function processCityData(src, dest) {
378
405
  let lines = 0;
406
+ const dataFile = path.join(dataPath, dest);
407
+ const tmpDataFile = path.join(tmpPath, src);
408
+
409
+ rimraf(dataFile);
410
+
411
+ process.stdout.write('\nProcessing data (may take a moment)...');
412
+ let tstart = Date.now();
413
+ const datFile = fs.createWriteStream(dataFile);
414
+
379
415
  async function processLine(line) {
380
416
  if (line.match(/^Copyright/) || !line.match(/\d/)) return;
381
417
 
@@ -462,15 +498,6 @@ async function processCityData(src, dest) {
462
498
  }
463
499
  }
464
500
 
465
- const dataFile = path.join(dataPath, dest);
466
- const tmpDataFile = path.join(tmpPath, src);
467
-
468
- rimraf(dataFile);
469
-
470
- process.stdout.write('\nProcessing data (may take a moment)...');
471
- var tstart = Date.now();
472
- var datFile = fs.createWriteStream(dataFile);
473
-
474
501
  const rl = readline.createInterface({ input: fs.createReadStream(tmpDataFile), crlfDelay: Infinity });
475
502
  let i = 0;
476
503
  for await (const line of rl) {
@@ -484,6 +511,13 @@ async function processCityData(src, dest) {
484
511
  function processCityDataNames(src, dest, cb) {
485
512
  let locId = null;
486
513
  let linesCount = 0;
514
+ const dataFile = path.join(dataPath, dest);
515
+ const tmpDataFile = path.join(tmpPath, src);
516
+
517
+ rimraf(dataFile);
518
+
519
+ const datFile = fs.openSync(dataFile, 'w');
520
+
487
521
  function processLine(line) {
488
522
  if (line.match(/^Copyright/) || !line.match(/\d/)) return;
489
523
 
@@ -519,13 +553,6 @@ function processCityDataNames(src, dest, cb) {
519
553
  linesCount++;
520
554
  }
521
555
 
522
- const dataFile = path.join(dataPath, dest);
523
- const tmpDataFile = path.join(tmpPath, src);
524
-
525
- rimraf(dataFile);
526
-
527
- var datFile = fs.openSync(dataFile, 'w');
528
-
529
556
  const rl = readline.createInterface({ input: fs.createReadStream(tmpDataFile).pipe(decodeStream('utf-8')), output: process.stdout, terminal: false });
530
557
 
531
558
  let lineCount = 0;
@@ -538,6 +565,10 @@ function processCityDataNames(src, dest, cb) {
538
565
  rl.on('close', cb);
539
566
  }
540
567
 
568
+ // ============================================================================
569
+ // Main Processing Dispatcher
570
+ // ============================================================================
571
+
541
572
  function processData(database, cb) {
542
573
  if (database.skip) return cb(null, database);
543
574
 
@@ -573,6 +604,10 @@ function processData(database, cb) {
573
604
  }
574
605
  }
575
606
 
607
+ // ============================================================================
608
+ // Checksum Management
609
+ // ============================================================================
610
+
576
611
  function updateChecksum(database, cb) {
577
612
  if (database.skip || !database.checkValue) return cb(); // Don't need to update checksums because it was not fetched or did not change
578
613
 
@@ -582,6 +617,10 @@ function updateChecksum(database, cb) {
582
617
  });
583
618
  }
584
619
 
620
+ // ============================================================================
621
+ // Main Execution Flow
622
+ // ============================================================================
623
+
585
624
  if (!license_key) {
586
625
  console.error('ERROR: Missing license_key');
587
626
  process.exit(1);