ts-ip2region2 1.2.2 → 1.4.0
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/README.md +86 -2
- package/data/checksums.json +4 -0
- package/data/ip2region.7z +0 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +49 -4
- package/dist/index.js.map +1 -1
- package/package.json +34 -15
- package/scripts/extract.js +58 -0
package/README.md
CHANGED
|
@@ -1,7 +1,15 @@
|
|
|
1
1
|
# ts-ip2region2
|
|
2
2
|
|
|
3
|
+
[](https://badge.fury.io/js/ts-ip2region2)
|
|
4
|
+
[](https://opensource.org/licenses/Apache-2.0)
|
|
5
|
+
[](https://github.com/Steven-Qiang/ts-ip2region2/actions)
|
|
6
|
+
|
|
7
|
+
[English](README.md) | [中文](README_CN.md)
|
|
8
|
+
|
|
3
9
|
High-performance Node.js native addon for ip2region xdb query with IPv4/IPv6 support. Written in TypeScript with full type definitions.
|
|
4
10
|
|
|
11
|
+
> **Note**: This project is based on the official [ip2region C client](https://github.com/lionsoul2014/ip2region/tree/master/binding/c) with enhanced TypeScript support.
|
|
12
|
+
|
|
5
13
|
## Features
|
|
6
14
|
|
|
7
15
|
- 🚀 **High Performance** - Native C++ implementation with microsecond-level response
|
|
@@ -10,15 +18,19 @@ High-performance Node.js native addon for ip2region xdb query with IPv4/IPv6 sup
|
|
|
10
18
|
- 🔒 **Memory Safe** - Automatic resource management prevents memory leaks
|
|
11
19
|
- 📝 **TypeScript** - Complete TypeScript type definitions included
|
|
12
20
|
- 🔧 **Cross Platform** - Works on Windows, Linux, and macOS
|
|
13
|
-
- 📦 **
|
|
21
|
+
- 📦 **Auto-Updated Data** - Database files are automatically synced daily
|
|
14
22
|
|
|
15
23
|
## Installation
|
|
16
24
|
|
|
17
25
|
```bash
|
|
18
26
|
npm install ts-ip2region2
|
|
27
|
+
# or
|
|
28
|
+
pnpm add ts-ip2region2
|
|
29
|
+
# or
|
|
30
|
+
yarn add ts-ip2region2
|
|
19
31
|
```
|
|
20
32
|
|
|
21
|
-
|
|
33
|
+
> **Database Included**: Database files are now bundled and automatically extracted during installation.
|
|
22
34
|
|
|
23
35
|
## Quick Start
|
|
24
36
|
|
|
@@ -69,6 +81,29 @@ new Ip2Region(dbPath: string, options?: Ip2RegionOptions)
|
|
|
69
81
|
- `Ip2Region.verify(dbPath: string): boolean` - Verify xdb file
|
|
70
82
|
- `Ip2Region.verifyDetailed(dbPath: string): VerifyResult` - Verify with detailed info
|
|
71
83
|
|
|
84
|
+
### Type Definitions
|
|
85
|
+
|
|
86
|
+
```typescript
|
|
87
|
+
interface SearchResult {
|
|
88
|
+
region: string; // Geographic location
|
|
89
|
+
ioCount: number; // Number of IO operations
|
|
90
|
+
took: number; // Query time in microseconds
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
interface Ip2RegionOptions {
|
|
94
|
+
cachePolicy?: 'file' | 'vectorIndex' | 'content';
|
|
95
|
+
ipVersion?: 'v4' | 'v6';
|
|
96
|
+
}
|
|
97
|
+
```
|
|
98
|
+
|
|
99
|
+
## Cache Strategies
|
|
100
|
+
|
|
101
|
+
| Strategy | Performance | Use Case |
|
|
102
|
+
|----------|-------------|----------|
|
|
103
|
+
| `file` | Good | Memory-constrained environments |
|
|
104
|
+
| `vectorIndex` | Better | General use (recommended) |
|
|
105
|
+
| `content` | Best | High-concurrency scenarios |
|
|
106
|
+
|
|
72
107
|
## Performance Benchmark
|
|
73
108
|
|
|
74
109
|
Benchmark results on Windows x64 with Node.js v22.14.0 (10,000 iterations):
|
|
@@ -98,6 +133,55 @@ Run benchmark yourself:
|
|
|
98
133
|
npm run benchmark
|
|
99
134
|
```
|
|
100
135
|
|
|
136
|
+
## Examples
|
|
137
|
+
|
|
138
|
+
```bash
|
|
139
|
+
# Build and run example
|
|
140
|
+
npm run example
|
|
141
|
+
|
|
142
|
+
# Build and run tests
|
|
143
|
+
npm test
|
|
144
|
+
|
|
145
|
+
# Build native addon
|
|
146
|
+
npm run build
|
|
147
|
+
|
|
148
|
+
# Compile TypeScript
|
|
149
|
+
npm run compile
|
|
150
|
+
```
|
|
151
|
+
|
|
152
|
+
## Project Structure
|
|
153
|
+
|
|
154
|
+
```
|
|
155
|
+
ts-ip2region2/
|
|
156
|
+
├── src/ # TypeScript source code
|
|
157
|
+
│ └── index.ts # Main TypeScript API
|
|
158
|
+
├── dist/ # Compiled JavaScript output
|
|
159
|
+
│ ├── index.js
|
|
160
|
+
│ ├── index.d.ts
|
|
161
|
+
│ └── ...
|
|
162
|
+
├── data/ # Bundled xdb database files
|
|
163
|
+
│ ├── checksums.json
|
|
164
|
+
│ └── ip2region.7z
|
|
165
|
+
├── extracted/ # Extracted database files
|
|
166
|
+
│ ├── ip2region_v4.xdb
|
|
167
|
+
│ └── ip2region_v6.xdb
|
|
168
|
+
├── ip2region/ # Original ip2region C source
|
|
169
|
+
│ ├── xdb_api.h
|
|
170
|
+
│ ├── xdb_util.c
|
|
171
|
+
│ └── xdb_searcher.c
|
|
172
|
+
├── scripts/ # Build and utility scripts
|
|
173
|
+
├── addon.cpp # Node.js addon implementation
|
|
174
|
+
├── binding.gyp # Build configuration
|
|
175
|
+
├── example.js # JavaScript example
|
|
176
|
+
├── tsconfig.json # TypeScript configuration
|
|
177
|
+
├── package.json
|
|
178
|
+
└── README.md
|
|
179
|
+
```
|
|
180
|
+
|
|
181
|
+
## Contributing
|
|
182
|
+
|
|
183
|
+
Contributions are welcome! Please feel free to submit a Pull Request.
|
|
184
|
+
|
|
101
185
|
## License
|
|
102
186
|
|
|
103
187
|
Apache-2.0
|
|
Binary file
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAiBA,MAAM,WAAW,YAAY;IACzB,6CAA6C;IAC7C,MAAM,EAAE,MAAM,CAAC;IACf,8BAA8B;IAC9B,OAAO,EAAE,MAAM,CAAC;IAChB,iCAAiC;IACjC,IAAI,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,WAAW,gBAAgB;IAC7B,yDAAyD;IACzD,WAAW,CAAC,EAAE,MAAM,GAAG,aAAa,GAAG,SAAS,CAAC;IACjD,8BAA8B;IAC9B,SAAS,CAAC,EAAE,IAAI,GAAG,IAAI,CAAC;CAC3B;AAED,MAAM,WAAW,YAAY;IACzB,0BAA0B;IAC1B,KAAK,EAAE,OAAO,CAAC;IACf,iBAAiB;IACjB,SAAS,EAAE,MAAM,CAAC;CACrB;AAED,MAAM,CAAC,OAAO,OAAO,SAAS;IAC1B,OAAO,CAAC,QAAQ,CAAM;IACtB,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAS;IAChC,OAAO,CAAC,QAAQ,CAAC,OAAO,CAA6B;IAErD;;;;OAIG;gBACS,eAAe,CAAC,EAAE,MAAM,GAAG,gBAAgB,EAAE,OAAO,CAAC,EAAE,gBAAgB;IAkCnF;;;;OAIG;IACH,MAAM,CAAC,EAAE,EAAE,MAAM,GAAG,YAAY;IAOhC;;OAEG;IACH,KAAK,IAAI,IAAI;IAIb;;;;OAIG;IACH,MAAM,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO;IAQtC;;;;OAIG;IACH,MAAM,CAAC,cAAc,CAAC,MAAM,EAAE,MAAM,GAAG,YAAY;IAOnD;;;OAGG;IACH,UAAU,IAAI,QAAQ,CAAC,gBAAgB,CAAC;IAIxC;;;OAGG;IACH,SAAS,IAAI,MAAM;CAGtB;AAED,OAAO,EAAE,SAAS,EAAE,CAAA"}
|
package/dist/index.js
CHANGED
|
@@ -1,8 +1,53 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
+
var ownKeys = function(o) {
|
|
20
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
+
var ar = [];
|
|
22
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
+
return ar;
|
|
24
|
+
};
|
|
25
|
+
return ownKeys(o);
|
|
26
|
+
};
|
|
27
|
+
return function (mod) {
|
|
28
|
+
if (mod && mod.__esModule) return mod;
|
|
29
|
+
var result = {};
|
|
30
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
+
__setModuleDefault(result, mod);
|
|
32
|
+
return result;
|
|
33
|
+
};
|
|
34
|
+
})();
|
|
2
35
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
36
|
exports.Ip2Region = void 0;
|
|
4
37
|
const addon = require('../build/Release/ip2region.node');
|
|
5
|
-
const
|
|
38
|
+
const path = __importStar(require("path"));
|
|
39
|
+
const fs = __importStar(require("fs"));
|
|
40
|
+
function getDataPaths() {
|
|
41
|
+
const dataDir = path.join(__dirname, '..', 'extracted');
|
|
42
|
+
return {
|
|
43
|
+
v4: path.join(dataDir, 'ip2region_v4.xdb'),
|
|
44
|
+
v6: path.join(dataDir, 'ip2region_v6.xdb')
|
|
45
|
+
};
|
|
46
|
+
}
|
|
47
|
+
function isDataExtracted() {
|
|
48
|
+
const paths = getDataPaths();
|
|
49
|
+
return fs.existsSync(paths.v4) && fs.existsSync(paths.v6);
|
|
50
|
+
}
|
|
6
51
|
class Ip2Region {
|
|
7
52
|
/**
|
|
8
53
|
* Create ip2region searcher instance
|
|
@@ -26,10 +71,10 @@ class Ip2Region {
|
|
|
26
71
|
ipVersion: finalOptions.ipVersion || 'v4',
|
|
27
72
|
};
|
|
28
73
|
if (!dbPath) {
|
|
29
|
-
if (!
|
|
30
|
-
throw new Error('
|
|
74
|
+
if (!isDataExtracted()) {
|
|
75
|
+
throw new Error('Database files not found. Run "npm run postinstall" or "node scripts/extract.js" to extract bundled data.');
|
|
31
76
|
}
|
|
32
|
-
const dataPaths =
|
|
77
|
+
const dataPaths = getDataPaths();
|
|
33
78
|
this.dbPath = this.options.ipVersion === 'v6' ? dataPaths.v6 : dataPaths.v4;
|
|
34
79
|
}
|
|
35
80
|
else {
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA,MAAM,KAAK,GAAG,OAAO,CAAC,iCAAiC,CAAC,CAAC;AACzD,2CAA6B;AAC7B,uCAAyB;AAEzB,SAAS,YAAY;IACnB,MAAM,OAAO,GAAG,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE,IAAI,EAAE,WAAW,CAAC,CAAC;IACxD,OAAO;QACL,EAAE,EAAE,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,kBAAkB,CAAC;QAC1C,EAAE,EAAE,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,kBAAkB,CAAC;KAC3C,CAAC;AACJ,CAAC;AAED,SAAS,eAAe;IACtB,MAAM,KAAK,GAAG,YAAY,EAAE,CAAC;IAC7B,OAAO,EAAE,CAAC,UAAU,CAAC,KAAK,CAAC,EAAE,CAAC,IAAI,EAAE,CAAC,UAAU,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC;AAC5D,CAAC;AAyBD,MAAqB,SAAS;IAK1B;;;;OAIG;IACH,YAAY,eAA2C,EAAE,OAA0B;QAC/E,IAAI,MAA0B,CAAC;QAC/B,IAAI,YAA8B,CAAC;QAEnC,2DAA2D;QAC3D,IAAI,OAAO,eAAe,KAAK,QAAQ,IAAI,eAAe,KAAK,IAAI,EAAE,CAAC;YAClE,MAAM,GAAG,SAAS,CAAC;YACnB,YAAY,GAAG,eAAe,CAAC;QACnC,CAAC;aAAM,CAAC;YACJ,MAAM,GAAG,eAAe,CAAC;YACzB,YAAY,GAAG,OAAO,IAAI,EAAE,CAAC;QACjC,CAAC;QAED,IAAI,CAAC,OAAO,GAAG;YACX,WAAW,EAAE,YAAY,CAAC,WAAW,IAAI,aAAa;YACtD,SAAS,EAAE,YAAY,CAAC,SAAS,IAAI,IAAI;SAC5C,CAAC;QAEF,IAAI,CAAC,MAAM,EAAE,CAAC;YACV,IAAI,CAAC,eAAe,EAAE,EAAE,CAAC;gBACrB,MAAM,IAAI,KAAK,CAAC,2GAA2G,CAAC,CAAC;YACjI,CAAC;YACD,MAAM,SAAS,GAAG,YAAY,EAAE,CAAC;YACjC,IAAI,CAAC,MAAM,GAAG,IAAI,CAAC,OAAO,CAAC,SAAS,KAAK,IAAI,CAAC,CAAC,CAAC,SAAS,CAAC,EAAE,CAAC,CAAC,CAAC,SAAS,CAAC,EAAE,CAAC;QAChF,CAAC;aAAM,CAAC;YACJ,IAAI,OAAO,MAAM,KAAK,QAAQ,EAAE,CAAC;gBAC7B,MAAM,IAAI,SAAS,CAAC,gCAAgC,CAAC,CAAC;YAC1D,CAAC;YACD,IAAI,CAAC,MAAM,GAAG,MAAM,CAAC;QACzB,CAAC;QAED,IAAI,CAAC,QAAQ,GAAG,IAAI,KAAK,CAAC,iBAAiB,CAAC,IAAI,CAAC,MAAM,EAAE,IAAI,CAAC,OAAO,CAAC,CAAC;IAC3E,CAAC;IAED;;;;OAIG;IACH,MAAM,CAAC,EAAU;QACb,IAAI,CAAC,EAAE,IAAI,OAAO,EAAE,KAAK,QAAQ,EAAE,CAAC;YAChC,MAAM,IAAI,SAAS,CAAC,uCAAuC,CAAC,CAAC;QACjE,CAAC;QACD,OAAO,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC;IACpC,CAAC;IAED;;OAEG;IACH,KAAK;QACD,IAAI,CAAC,QAAQ,CAAC,KAAK,EAAE,CAAC;IAC1B,CAAC;IAED;;;;OAIG;IACH,MAAM,CAAC,MAAM,CAAC,MAAc;QACxB,IAAI,CAAC,MAAM,IAAI,OAAO,MAAM,KAAK,QAAQ,EAAE,CAAC;YACxC,MAAM,IAAI,SAAS,CAAC,0CAA0C,CAAC,CAAC;QACpE,CAAC;QACD,MAAM,MAAM,GAAG,KAAK,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC;QACvC,OAAO,MAAM,CAAC,KAAK,CAAC;IACxB,CAAC;IAED;;;;OAIG;IACH,MAAM,CAAC,cAAc,CAAC,MAAc;QAChC,IAAI,CAAC,MAAM,IAAI,OAAO,MAAM,KAAK,QAAQ,EAAE,CAAC;YACxC,MAAM,IAAI,SAAS,CAAC,0CAA0C,CAAC,CAAC;QACpE,CAAC;QACD,OAAO,KAAK,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC;IACnC,CAAC;IAED;;;OAGG;IACH,UAAU;QACN,OAAO,EAAE,GAAG,IAAI,CAAC,OAAO,EAAE,CAAC;IAC/B,CAAC;IAED;;;OAGG;IACH,SAAS;QACL,OAAO,IAAI,CAAC,MAAM,CAAC;IACvB,CAAC;CACJ;AAvGD,4BAuGC;AAEQ,8BAAS"}
|
package/package.json
CHANGED
|
@@ -1,9 +1,26 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "ts-ip2region2",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.4.0",
|
|
4
4
|
"description": "TypeScript-first ip2region implementation with native Node.js addon. Ultra-fast IPv4/IPv6 geolocation queries.",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"types": "dist/index.d.ts",
|
|
7
|
+
"packageManager": "pnpm@10.29.2",
|
|
8
|
+
"scripts": {
|
|
9
|
+
"build": "node-gyp rebuild",
|
|
10
|
+
"compile": "tsc",
|
|
11
|
+
"build:all": "pnpm run build && pnpm run compile",
|
|
12
|
+
"rebuild": "node-gyp rebuild",
|
|
13
|
+
"clean": "node-gyp clean",
|
|
14
|
+
"test": "pnpm run build:all && node scripts/test.js",
|
|
15
|
+
"benchmark": "node scripts/benchmark.js",
|
|
16
|
+
"example": "pnpm run build:all && node example.js",
|
|
17
|
+
"sync": "node scripts/sync-data.js --no-exit-code",
|
|
18
|
+
"sync-check": "node scripts/sync-data.js",
|
|
19
|
+
"postinstall": "node scripts/extract.js",
|
|
20
|
+
"semantic-release": "semantic-release",
|
|
21
|
+
"semantic-release:dry": "semantic-release --dry-run",
|
|
22
|
+
"prepublishOnly": "pnpm run build:all"
|
|
23
|
+
},
|
|
7
24
|
"keywords": [
|
|
8
25
|
"typescript",
|
|
9
26
|
"ip2region",
|
|
@@ -19,8 +36,7 @@
|
|
|
19
36
|
"license": "Apache-2.0",
|
|
20
37
|
"repository": {
|
|
21
38
|
"type": "git",
|
|
22
|
-
"url": "git+https://github.com/Steven-Qiang/ts-ip2region2.git"
|
|
23
|
-
"directory": "packages/ts-ip2region2"
|
|
39
|
+
"url": "git+https://github.com/Steven-Qiang/ts-ip2region2.git"
|
|
24
40
|
},
|
|
25
41
|
"bugs": {
|
|
26
42
|
"url": "https://github.com/Steven-Qiang/ts-ip2region2/issues"
|
|
@@ -28,11 +44,21 @@
|
|
|
28
44
|
"homepage": "https://github.com/Steven-Qiang/ts-ip2region2#readme",
|
|
29
45
|
"dependencies": {
|
|
30
46
|
"node-addon-api": "^8.5.0",
|
|
31
|
-
"
|
|
47
|
+
"7zip-bin": "^5.2.0",
|
|
48
|
+
"node-7z": "^3.0.0"
|
|
32
49
|
},
|
|
33
50
|
"devDependencies": {
|
|
51
|
+
"@semantic-release/changelog": "^6.0.3",
|
|
52
|
+
"@semantic-release/commit-analyzer": "^13.0.1",
|
|
53
|
+
"@semantic-release/git": "^10.0.1",
|
|
54
|
+
"@semantic-release/github": "^12.0.5",
|
|
55
|
+
"@semantic-release/npm": "^13.1.4",
|
|
56
|
+
"@semantic-release/release-notes-generator": "^14.1.0",
|
|
34
57
|
"@types/node": "^25.2.2",
|
|
58
|
+
"@types/node-7z": "^2.1.11",
|
|
35
59
|
"node-gyp": "^12.2.0",
|
|
60
|
+
"progress": "^2.0.3",
|
|
61
|
+
"semantic-release": "^25.0.3",
|
|
36
62
|
"typescript": "^5.9.3"
|
|
37
63
|
},
|
|
38
64
|
"engines": {
|
|
@@ -52,6 +78,9 @@
|
|
|
52
78
|
"addon.cpp",
|
|
53
79
|
"ip2region/**/*",
|
|
54
80
|
"binding.gyp",
|
|
81
|
+
"data/checksums.json",
|
|
82
|
+
"data/ip2region.7z",
|
|
83
|
+
"scripts/extract.js",
|
|
55
84
|
"README.md"
|
|
56
85
|
],
|
|
57
86
|
"gypfile": true,
|
|
@@ -59,15 +88,5 @@
|
|
|
59
88
|
"access": "public",
|
|
60
89
|
"registry": "https://registry.npmjs.org/",
|
|
61
90
|
"provenance": true
|
|
62
|
-
},
|
|
63
|
-
"scripts": {
|
|
64
|
-
"build": "node-gyp rebuild",
|
|
65
|
-
"compile": "tsc",
|
|
66
|
-
"build:all": "pnpm run build && pnpm run compile",
|
|
67
|
-
"rebuild": "node-gyp rebuild",
|
|
68
|
-
"clean": "node-gyp clean",
|
|
69
|
-
"test": "pnpm run build:all && node test.js",
|
|
70
|
-
"benchmark": "node benchmark.js",
|
|
71
|
-
"example": "pnpm run build:all && node example.js"
|
|
72
91
|
}
|
|
73
|
-
}
|
|
92
|
+
}
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
const path = require('path');
|
|
2
|
+
const fs = require('fs');
|
|
3
|
+
const { extractFull } = require('node-7z');
|
|
4
|
+
const sevenBin = require('7zip-bin');
|
|
5
|
+
|
|
6
|
+
async function extractData() {
|
|
7
|
+
const packageDir = path.dirname(__dirname);
|
|
8
|
+
const archivePath = path.join(packageDir, 'data', 'ip2region.7z');
|
|
9
|
+
const extractDir = path.join(packageDir, 'extracted');
|
|
10
|
+
|
|
11
|
+
if (!fs.existsSync(archivePath)) {
|
|
12
|
+
console.error('Archive file not found:', archivePath);
|
|
13
|
+
process.exit(1);
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
if (fs.existsSync(extractDir)) {
|
|
17
|
+
console.log('Data already extracted');
|
|
18
|
+
return;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
console.log('Extracting ip2region database files...');
|
|
22
|
+
|
|
23
|
+
try {
|
|
24
|
+
fs.mkdirSync(extractDir, { recursive: true });
|
|
25
|
+
|
|
26
|
+
if (process.platform !== 'win32') {
|
|
27
|
+
try {
|
|
28
|
+
fs.chmodSync(sevenBin.path7za, 0o755);
|
|
29
|
+
} catch (chmodError) {
|
|
30
|
+
console.warn('Could not set executable permissions on 7zip binary:', chmodError);
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
const stream = extractFull(archivePath, extractDir, {
|
|
35
|
+
$bin: sevenBin.path7za,
|
|
36
|
+
recursive: true
|
|
37
|
+
});
|
|
38
|
+
|
|
39
|
+
await new Promise((resolve, reject) => {
|
|
40
|
+
stream.on('end', () => {
|
|
41
|
+
console.log('Extraction completed successfully');
|
|
42
|
+
resolve();
|
|
43
|
+
});
|
|
44
|
+
|
|
45
|
+
stream.on('error', (err) => {
|
|
46
|
+
console.error('Extraction failed:', err);
|
|
47
|
+
reject(err);
|
|
48
|
+
});
|
|
49
|
+
});
|
|
50
|
+
} catch (error) {
|
|
51
|
+
console.error('Failed to extract data:', error);
|
|
52
|
+
process.exit(1);
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
if (require.main === module) {
|
|
57
|
+
extractData().catch(console.error);
|
|
58
|
+
}
|