Skip to content

Commit 31bf133

Browse files
authored
Merge pull request #69 from mm-david/master
Allow downloading any MaxMind database
2 parents 162b179 + c4f94a7 commit 31bf133

5 files changed

Lines changed: 91 additions & 42 deletions

File tree

README.md

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
# node-geolite2
22

3-
Maxmind's GeoLite2 Free Databases download helper.
3+
Maxmind's GeoLite2 Free Databases download helper. Also supports Maxmind's paid GeoIP2 databases.
44

55
## Configuration
66

@@ -27,21 +27,21 @@ If you don't have access to the environment variables during installation, you c
2727

2828
Beware of security risks of adding keys and secrets to your repository!
2929

30-
**Note:** For backwards compatibility, the account ID is currently optional. When not provided we fall back to using legacy Maxmind download URLs with only the license key. However, this behavior may become unsupported in the future so adding an account ID is recommended.
30+
**Note:** For backwards compatibility, the account ID is currently optional. When not provided we fall back to using legacy Maxmind download URLs with only the license key. However, this behavior may become unsupported in the future so adding an account ID is recommended.
3131

3232
### Selecting databases to download
3333

3434
You can select the dbs you want downloaded by adding a `selected-dbs` property on `geolite2` via `package.json`.
3535

36-
`selected-dbs` must be an array of strings, one or more of the values `City`, `Country`, `ASN`.
36+
`selected-dbs` must be an array of edition IDs. For example, `GeoIP2-Enterprise`, `GeoIP2-City`, `GeoLite2-City`, etc (downloading paid databases requires an active subscription).
3737

38-
If `selected-dbs` is unset, or is set but empty, all dbs will be downloaded.
38+
If `selected-dbs` is unset, or is set but empty, all the free GeoLite dbs will be downloaded.
3939

4040
```jsonc
4141
{
4242
...
4343
"geolite2": {
44-
"selected-dbs": ["City", "Country", "ASN"]
44+
"selected-dbs": ["GeoLite2-City", "GeoLite2-Country", "GeoLite2-ASN"]
4545
}
4646
...
4747
}
@@ -53,7 +53,9 @@ If `selected-dbs` is unset, or is set but empty, all dbs will be downloaded.
5353
var geolite2 = require('geolite2');
5454
var maxmind = require('maxmind');
5555

56-
var lookup = maxmind.openSync(geolite2.paths.city); // or geolite2.paths.country or geolite2.paths.asn
56+
// The database paths are available under geolite2.paths using the full edition
57+
// ID, e.g. geolite2.paths['GeoLite2-ASN']
58+
var lookup = maxmind.openSync(geolite2.paths['GeoLite2-City']);
5759
var city = lookup.get('66.6.44.4');
5860
```
5961

index.js

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,10 +3,21 @@ const path = require('path');
33
const { getSelectedDbs } = require('./utils');
44
const selected = getSelectedDbs();
55

6-
const makePath = (type) => path.resolve(__dirname, `dbs/GeoLite2-${type}.mmdb`);
6+
const makePath = (edition) => path.resolve(__dirname, `dbs/${edition}.mmdb`);
77

88
const paths = selected.reduce((a, c) => {
9-
a[c.toLowerCase()] = makePath(c);
9+
const aliases = {
10+
'GeoLite2-ASN': 'asn',
11+
'GeoLite2-City': 'city',
12+
'GeoLite2-Country': 'country',
13+
};
14+
// The keys are the database names.
15+
a[c] = makePath(c);
16+
// For backward compatibility, we also populate the 'city', 'asn', and
17+
// 'country' keys for GeoLite databases.
18+
if (c in aliases) {
19+
a[aliases[c]] = makePath(c);
20+
}
1021
return a;
1122
}, {});
1223

scripts/postinstall.js

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -50,10 +50,7 @@ const link = (edition) =>
5050
? `https://download.maxmind.com/geoip/databases/${edition}/download?suffix=tar.gz`
5151
: `https://download.maxmind.com/app/geoip_download?edition_id=${edition}&license_key=${licenseKey}&suffix=tar.gz`;
5252

53-
const selected = getSelectedDbs();
54-
const editionIds = ['City', 'Country', 'ASN']
55-
.filter((e) => selected.includes(e))
56-
.map((e) => `GeoLite2-${e}`);
53+
const editionIds = getSelectedDbs();
5754

5855
const downloadPath = path.join(__dirname, '..', 'dbs');
5956

test/index.js

Lines changed: 16 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -3,21 +3,21 @@ const fs = require('fs');
33
const geolite2 = require('../');
44

55
describe('geolite2', function () {
6-
it('should return a valid city db path', function () {
7-
var stat = fs.statSync(geolite2.paths.city);
8-
assert(stat.size > 1e6);
9-
assert(stat.ctime);
10-
});
6+
const keys = [
7+
'GeoLite2-ASN',
8+
'GeoLite2-City',
9+
'GeoLite2-Country',
10+
// Legacy aliases:
11+
'city',
12+
'country',
13+
'asn',
14+
];
1115

12-
it('should return a valid country db path', function () {
13-
var stat = fs.statSync(geolite2.paths.country);
14-
assert(stat.size > 1e6);
15-
assert(stat.ctime);
16-
});
17-
18-
it('should return a valid ASN db path', function () {
19-
var stat = fs.statSync(geolite2.paths.asn);
20-
assert(stat.size > 1e6);
21-
assert(stat.ctime);
22-
});
16+
keys.forEach((key) =>
17+
it(`should return a database path for ${key}`, () => {
18+
var stat = fs.statSync(geolite2.paths[key]);
19+
assert(stat.size > 1e6);
20+
assert(stat.ctime);
21+
}),
22+
);
2323
});

utils.js

Lines changed: 53 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -68,44 +68,83 @@ const getLicense = () => {
6868
};
6969

7070
const getSelectedDbs = () => {
71-
const valids = ['City', 'Country', 'ASN'];
71+
const aliases = ['ASN', 'City', 'Country'];
72+
const defaultEditions = ['GeoLite2-ASN', 'GeoLite2-City', 'GeoLite2-Country'];
73+
const validEditions = [
74+
'GeoIP-Anonymous-Plus',
75+
'GeoIP-Network-Optimization-City',
76+
'GeoIP2-Anonymous-IP',
77+
'GeoIP2-City',
78+
'GeoIP2-City-Africa',
79+
'GeoIP2-City-Asia-Pacific',
80+
'GeoIP2-City-Europe',
81+
'GeoIP2-City-North-America',
82+
'GeoIP2-City-Shield',
83+
'GeoIP2-City-South-America',
84+
'GeoIP2-Connection-Type',
85+
'GeoIP2-Country',
86+
'GeoIP2-Country-Shield',
87+
'GeoIP2-DensityIncome',
88+
'GeoIP2-Domain',
89+
'GeoIP2-Enterprise',
90+
'GeoIP2-Enterprise-Shield',
91+
'GeoIP2-IP-Risk',
92+
'GeoIP2-ISP',
93+
'GeoIP2-Precision-Enterprise',
94+
'GeoIP2-Precision-Enterprise-Shield',
95+
'GeoIP2-Static-IP-Score',
96+
'GeoIP2-User-Connection-Type',
97+
'GeoIP2-User-Count',
98+
'GeoLite2-ASN',
99+
'GeoLite2-City',
100+
'GeoLite2-Country',
101+
];
72102

73103
const config = getConfig();
74-
const selected =
104+
const selectedWithPossibleAliases =
75105
config != null && config['selected-dbs'] != null
76106
? config['selected-dbs']
77-
: valids;
107+
: defaultEditions;
78108

79-
if (!Array.isArray(selected)) {
80-
console.error('selected-dbs property must have be an array.');
109+
if (!Array.isArray(selectedWithPossibleAliases)) {
110+
console.error('selected-dbs property must be an array.');
81111
process.exit(1);
82112
}
83113

84-
if (selected.length === 0) return valids;
114+
if (selectedWithPossibleAliases.length === 0) return defaultEditions;
85115

86-
const validValuesText = valids.join(', ');
87-
if (selected.length > valids.length) {
116+
const selectedEditions = selectedWithPossibleAliases.map((element) => {
117+
index = aliases.indexOf(element);
118+
if (index > -1) {
119+
return `GeoLite2-${element}`;
120+
} else {
121+
return element;
122+
}
123+
});
124+
125+
const validValuesText = validEditions.join(', ');
126+
if (selectedEditions.length > validEditions.length) {
88127
console.error(
89128
'Property selected-dbs has too many values, there are only %d valid values: %s',
90-
valids.length,
91-
validValuesText
129+
validEditions.length,
130+
validValuesText,
92131
);
93132
process.exit(1);
94133
}
95134

96-
for (const value of selected) {
97-
const index = valids.indexOf(value);
135+
for (const value of selectedEditions) {
136+
const index = validEditions.indexOf(value);
98137
if (index === -1) {
99138
console.error(
100139
'Invalid value in selected-dbs: %s The only valid values are: %s',
101140
value,
102-
validValuesText
141+
validValuesText,
103142
);
104143
process.exit(1);
105144
}
106145
}
107146

108-
return selected;
147+
return selectedEditions;
109148
};
110149

111150
module.exports = {

0 commit comments

Comments
 (0)