Skip to content

Commit 3971b76

Browse files
committed
Added Country class to query country information and Region class to lookup the ISO 3166-2 subdivision code for country code and region name
1 parent 4310332 commit 3971b76

File tree

5 files changed

+215
-5
lines changed

5 files changed

+215
-5
lines changed

README.md

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -198,3 +198,49 @@ for (const x of cidr) {
198198
console.log(tools.cidrToIPV4("10.123.80.0/12"));
199199
console.log(tools.cidrToIPV6("2002:1234::abcd:ffff:c0a8:101/62"));
200200
```
201+
202+
## COUNTRY CLASS
203+
204+
## Methods
205+
Below are the methods supported in this module.
206+
207+
|Method Name|Description|
208+
|---|---|
209+
|getCountryInfo(countryCode)|Returns the country information.|
210+
211+
## Usage
212+
213+
```javascript
214+
const {Country} = require("ip2location-nodejs");
215+
216+
let country = new Country("./IP2LOCATION-COUNTRY-INFORMATION-BASIC.CSV");
217+
218+
country.getCountryInfo("US").then(country_info => {
219+
console.log(country_info);
220+
});
221+
222+
country.getCountryInfo("").then(country_info => {
223+
console.log(country_info);
224+
});
225+
```
226+
227+
## REGION CLASS
228+
229+
## Methods
230+
Below are the methods supported in this module.
231+
232+
|Method Name|Description|
233+
|---|---|
234+
|getRegionCode(countryCode, regionName)|Returns the region code for the supplied country code and region name.|
235+
236+
## Usage
237+
238+
```javascript
239+
const {Region} = require("ip2location-nodejs");
240+
241+
let region = new Region("./IP2LOCATION-ISO3166-2.CSV");
242+
243+
region.getRegionCode("US", "California").then(region_code => {
244+
console.log(region_code);
245+
});
246+
```

package.json

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "ip2location-nodejs",
3-
"version": "9.3.1",
3+
"version": "9.4.1",
44
"description": "IP2Location geolocation component",
55
"keywords": [
66
"ip2location",
@@ -22,7 +22,8 @@
2222
"types": "src/ip2location.d.ts",
2323
"license": "MIT",
2424
"dependencies": {
25-
"big-integer": "^1.6.47"
25+
"big-integer": "^1.6.47",
26+
"csv-parser": "^3.0.0"
2627
},
2728
"repository": {
2829
"type": "git",

src/ip2location.d.ts

Lines changed: 34 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -493,4 +493,37 @@ export class IPTools {
493493
* @returns The array with the starting and ending IPv6 addresses.
494494
*/
495495
cidrToIPV6(cidr: string): string[];
496-
}
496+
}
497+
declare class Country {
498+
/**
499+
* Read the country information CSV file and parse the data.
500+
*
501+
* @param csvFile The full path to the country information CSV file.
502+
*/
503+
constructor(csvFile: any);
504+
/**
505+
* Retrieves the country information.
506+
*
507+
* @param countryCode The country code to get the country information.
508+
* @returns The country information.
509+
*/
510+
getCountryInfo(countryCode?: string): Promise<any[]>;
511+
#private;
512+
}
513+
declare class Region {
514+
/**
515+
* Read the region information CSV file and parse the data.
516+
*
517+
* @param csvFile The full path to the region information CSV file.
518+
*/
519+
constructor(csvFile: any);
520+
/**
521+
* Retrieves the region code for the country code and region name.
522+
*
523+
* @param countryCode The country code to get the region code.
524+
* @param regionName The region name to get the region code.
525+
* @returns The region code.
526+
*/
527+
getRegionCode(countryCode?: string, regionName?: string): Promise<any>;
528+
#private;
529+
}

src/ip2location.js

Lines changed: 115 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,10 @@ var net = require("net");
22
var fs = require("fs");
33
var bigInt = require("big-integer");
44
var https = require("https");
5+
const csv = require("csv-parser");
56

67
// For BIN queries
7-
const VERSION = "9.3.1";
8+
const VERSION = "9.4.1";
89
const MAX_INDEX = 65536;
910
const COUNTRY_POSITION = [
1011
0, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
@@ -1533,8 +1534,121 @@ class IPTools {
15331534
}
15341535
}
15351536

1537+
// Country class
1538+
class Country {
1539+
#fields = Array();
1540+
#records = {};
1541+
#fd;
1542+
#ready = false;
1543+
1544+
constructor(csvFile) {
1545+
if (!fs.existsSync(csvFile)) {
1546+
throw new Error("The CSV file " + csvFile + " is not found.");
1547+
}
1548+
try {
1549+
fs.createReadStream(csvFile)
1550+
.pipe(csv(true))
1551+
.on("data", (data) => {
1552+
if (data.country_code) {
1553+
this.#records[data.country_code] = data;
1554+
} else {
1555+
throw new Error("Invalid country information CSV file.");
1556+
}
1557+
})
1558+
.on("end", () => {
1559+
this.#ready = true;
1560+
});
1561+
} catch (err) {
1562+
throw new Error("Unable to read " + csvFile + ".");
1563+
}
1564+
}
1565+
1566+
// Get country information
1567+
async getCountryInfo(countryCode = "") {
1568+
while (!this.#ready) {
1569+
await new Promise((resolve) => setTimeout(resolve, 100));
1570+
}
1571+
countryCode = countryCode.trim();
1572+
let results = Array();
1573+
if (Object.keys(this.#records).length === 0) {
1574+
throw new Error("No record available.");
1575+
}
1576+
if (countryCode != "") {
1577+
if (this.#records[countryCode]) {
1578+
results.push(this.#records[countryCode]);
1579+
}
1580+
} else {
1581+
for (const elem in this.#records) {
1582+
results.push(this.#records[elem]);
1583+
}
1584+
}
1585+
return results;
1586+
}
1587+
}
1588+
1589+
// Region class
1590+
class Region {
1591+
#fields = Array();
1592+
#records = {};
1593+
#fd;
1594+
#ready = false;
1595+
1596+
constructor(csvFile) {
1597+
if (!fs.existsSync(csvFile)) {
1598+
throw new Error("The CSV file " + csvFile + " is not found.");
1599+
}
1600+
try {
1601+
fs.createReadStream(csvFile)
1602+
.pipe(csv(true))
1603+
.on("data", (data) => {
1604+
if (data.subdivision_name) {
1605+
if (!this.#records[data.country_code]) {
1606+
this.#records[data.country_code] = Array();
1607+
}
1608+
this.#records[data.country_code].push({
1609+
code: data.code,
1610+
name: data.subdivision_name,
1611+
});
1612+
} else {
1613+
throw new Error("Invalid region information CSV file.");
1614+
}
1615+
})
1616+
.on("end", () => {
1617+
this.#ready = true;
1618+
});
1619+
} catch (err) {
1620+
throw new Error("Unable to read " + csvFile + ".");
1621+
}
1622+
}
1623+
1624+
// Get region code
1625+
async getRegionCode(countryCode = "", regionName = "") {
1626+
while (!this.#ready) {
1627+
await new Promise((resolve) => setTimeout(resolve, 100));
1628+
}
1629+
countryCode = countryCode.trim();
1630+
regionName = regionName.trim();
1631+
if (Object.keys(this.#records).length === 0) {
1632+
throw new Error("No record available.");
1633+
}
1634+
if (this.#records[countryCode]) {
1635+
for (let x = 0; x < this.#records[countryCode].length; x++) {
1636+
let elem = this.#records[countryCode][x];
1637+
if (regionName.toUpperCase() == elem.name.toUpperCase()) {
1638+
return elem.code;
1639+
}
1640+
}
1641+
return null;
1642+
} else {
1643+
return null;
1644+
}
1645+
}
1646+
}
1647+
15361648
module.exports = {
15371649
IP2Location: IP2Location,
15381650
IP2LocationWebService: IP2LocationWebService,
15391651
IPTools: IPTools,
1652+
Country: Country,
1653+
Region: Region,
15401654
};

src/test.js

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
const {IP2Location, IP2LocationWebService, IPTools} = require("ip2location-nodejs");
1+
const {IP2Location, IP2LocationWebService, IPTools, Country, Region} = require("ip2location-nodejs");
22

33
let ip2location = new IP2Location();
44

@@ -84,3 +84,19 @@ for (const x of cidr) {
8484
}
8585
console.log(tools.cidrToIPV4("10.123.80.0/12"));
8686
console.log(tools.cidrToIPV6("2002:1234::abcd:ffff:c0a8:101/62"));
87+
88+
let country = new Country("./IP2LOCATION-COUNTRY-INFORMATION-BASIC.CSV");
89+
90+
country.getCountryInfo("US").then(country_info => {
91+
console.log(country_info);
92+
});
93+
94+
country.getCountryInfo("").then(country_info => {
95+
console.log(country_info);
96+
});
97+
98+
let region = new Region("./IP2LOCATION-ISO3166-2.CSV");
99+
100+
region.getRegionCode("US", "California").then(region_code => {
101+
console.log(region_code);
102+
});

0 commit comments

Comments
 (0)