ts-ip2region2 1.0.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 ADDED
@@ -0,0 +1,120 @@
1
+ # ip2region Node.js Addon (TypeScript)
2
+
3
+ [English](README.md) | [中文](README_CN.md)
4
+
5
+ High-performance Node.js native addon for ip2region xdb query with IPv4/IPv6 support. Written in TypeScript with full type definitions.
6
+
7
+ > **Note**: This project is adapted from the official [ip2region C binding](https://github.com/lionsoul2014/ip2region/tree/master/binding/c) and enhanced with TypeScript support.
8
+
9
+ ## Features
10
+
11
+ - 🚀 **High Performance** - Native C++ implementation with microsecond-level response
12
+ - 🌐 **IPv4 & IPv6** - Full support for both IPv4 and IPv6 address queries
13
+ - 💾 **Multiple Cache Strategies** - file/vectorIndex/content caching options
14
+ - 🔒 **Memory Safe** - Automatic resource management prevents memory leaks
15
+ - 📝 **TypeScript** - Complete TypeScript type definitions included
16
+ - 🔧 **Cross Platform** - Works on Windows, Linux, and macOS
17
+
18
+ ## Installation
19
+
20
+ ```bash
21
+ npm install
22
+ npm run build:all
23
+ ```
24
+
25
+ > **Database Required**: Download the xdb database files from [ip2region data](https://github.com/lionsoul2014/ip2region/tree/master/data) before using.
26
+
27
+ ## Quick Start
28
+
29
+ ```typescript
30
+ import Ip2Region from 'ip2region-nodejs';
31
+
32
+ // Create searcher instance
33
+ const searcher = new Ip2Region('./data/ip2region_v4.xdb', {
34
+ cachePolicy: 'vectorIndex', // file/vectorIndex/content
35
+ ipVersion: 'v4' // v4/v6
36
+ });
37
+
38
+ // Query IP address
39
+ const result = searcher.search('8.8.8.8');
40
+ console.log(result);
41
+ // Output: { region: 'United States|0|0|Level3', ioCount: 3, took: 1000 }
42
+
43
+ // Clean up
44
+ searcher.close();
45
+ ```
46
+
47
+ ## API Reference
48
+
49
+ ### Constructor
50
+ ```typescript
51
+ new Ip2Region(dbPath: string, options?: Ip2RegionOptions)
52
+ ```
53
+
54
+ ### Methods
55
+ - `search(ip: string): SearchResult` - Query IP address location
56
+ - `close(): void` - Release resources
57
+
58
+ ### Static Methods
59
+ - `Ip2Region.verify(dbPath: string): boolean` - Verify xdb file
60
+ - `Ip2Region.verifyDetailed(dbPath: string): VerifyResult` - Verify with detailed info
61
+
62
+ ### Types
63
+ ```typescript
64
+ interface SearchResult {
65
+ region: string; // Geographic location
66
+ ioCount: number; // IO operation count
67
+ took: number; // Query time in microseconds
68
+ }
69
+
70
+ interface Ip2RegionOptions {
71
+ cachePolicy?: 'file' | 'vectorIndex' | 'content';
72
+ ipVersion?: 'v4' | 'v6';
73
+ }
74
+ ```
75
+
76
+ ## Cache Strategies
77
+
78
+ | Strategy | Memory | Performance | Use Case |
79
+ |----------|--------|-------------|----------|
80
+ | `file` | Minimal | Good | Memory-constrained |
81
+ | `vectorIndex` | Medium | Better | General use (recommended) |
82
+ | `content` | High | Best | High-concurrency |
83
+
84
+ ## Examples
85
+
86
+ ```bash
87
+ # Run TypeScript example
88
+ npm run example
89
+
90
+ # Run TypeScript tests
91
+ npm test
92
+ ```
93
+
94
+ ## Project Structure
95
+
96
+ ```
97
+ ip2region-nodejs/
98
+ ├── src/ # TypeScript source code
99
+ │ ├── index.ts # Main TypeScript API
100
+ │ ├── example.ts # TypeScript example
101
+ │ └── test.ts # TypeScript tests
102
+ ├── dist/ # Compiled JavaScript output
103
+ │ ├── index.js
104
+ │ ├── index.d.ts
105
+ │ └── ...
106
+ ├── ip2region/ # Original ip2region C source code
107
+ │ ├── xdb_api.h
108
+ │ ├── xdb_util.c
109
+ │ └── xdb_searcher.c
110
+ ├── addon.cpp # Node.js addon implementation
111
+ ├── binding.gyp # Build configuration
112
+ ├── tsconfig.json # TypeScript configuration
113
+ ├── package.json
114
+ └── README.md
115
+ ```
116
+
117
+ ## License
118
+
119
+ Apache-2.0
120
+
package/README_CN.md ADDED
@@ -0,0 +1,119 @@
1
+ # ip2region Node.js Addon (TypeScript)
2
+
3
+ [English](README.md) | [中文](README_CN.md)
4
+
5
+ 高性能的 ip2region xdb 查询 Node.js 原生扩展,支持 IPv4/IPv6。使用 TypeScript 编写,包含完整的类型定义。
6
+
7
+ > **说明**: 本项目基于官方 [ip2region C语言客户端](https://github.com/lionsoul2014/ip2region/tree/master/binding/c) 改造,并增强了 TypeScript 支持。
8
+
9
+ ## 特性
10
+
11
+ - 🚀 **高性能** - 原生 C++ 实现,微秒级响应
12
+ - 🌐 **IPv4 & IPv6** - 完全支持 IPv4 和 IPv6 地址查询
13
+ - 💾 **多种缓存策略** - file/vectorIndex/content 缓存选项
14
+ - 🔒 **内存安全** - 自动资源管理,防止内存泄漏
15
+ - 📝 **TypeScript** - 包含完整的 TypeScript 类型定义
16
+ - 🔧 **跨平台** - 支持 Windows、Linux 和 macOS
17
+
18
+ ## 安装
19
+
20
+ ```bash
21
+ npm install
22
+ npm run build:all
23
+ ```
24
+
25
+ > **需要数据库**: 使用前请从 [ip2region data](https://github.com/lionsoul2014/ip2region/tree/master/data) 下载 xdb 数据库文件。
26
+
27
+ ## 快速开始
28
+
29
+ ```typescript
30
+ import Ip2Region from 'ip2region-nodejs';
31
+
32
+ // 创建查询器实例
33
+ const searcher = new Ip2Region('./data/ip2region_v4.xdb', {
34
+ cachePolicy: 'vectorIndex', // file/vectorIndex/content
35
+ ipVersion: 'v4' // v4/v6
36
+ });
37
+
38
+ // 查询IP地址
39
+ const result = searcher.search('8.8.8.8');
40
+ console.log(result);
41
+ // 输出: { region: 'United States|0|0|Level3', ioCount: 3, took: 1000 }
42
+
43
+ // 清理资源
44
+ searcher.close();
45
+ ```
46
+
47
+ ## API 参考
48
+
49
+ ### 构造函数
50
+ ```typescript
51
+ new Ip2Region(dbPath: string, options?: Ip2RegionOptions)
52
+ ```
53
+
54
+ ### 方法
55
+ - `search(ip: string): SearchResult` - 查询IP地址位置
56
+ - `close(): void` - 释放资源
57
+
58
+ ### 静态方法
59
+ - `Ip2Region.verify(dbPath: string): boolean` - 验证xdb文件
60
+ - `Ip2Region.verifyDetailed(dbPath: string): VerifyResult` - 验证并返回详细信息
61
+
62
+ ### 类型定义
63
+ ```typescript
64
+ interface SearchResult {
65
+ region: string; // 地理位置
66
+ ioCount: number; // IO操作次数
67
+ took: number; // 查询耗时(微秒)
68
+ }
69
+
70
+ interface Ip2RegionOptions {
71
+ cachePolicy?: 'file' | 'vectorIndex' | 'content';
72
+ ipVersion?: 'v4' | 'v6';
73
+ }
74
+ ```
75
+
76
+ ## 缓存策略
77
+
78
+ | 策略 | 内存占用 | 性能 | 使用场景 |
79
+ |------|----------|------|----------|
80
+ | `file` | 最小 | 良好 | 内存受限环境 |
81
+ | `vectorIndex` | 中等 | 更好 | 一般使用(推荐) |
82
+ | `content` | 较高 | 最佳 | 高并发场景 |
83
+
84
+ ## 示例
85
+
86
+ ```bash
87
+ # 运行 TypeScript 示例
88
+ npm run example
89
+
90
+ # 运行 TypeScript 测试
91
+ npm test
92
+ ```
93
+
94
+ ## 项目结构
95
+
96
+ ```
97
+ ip2region-nodejs/
98
+ ├── src/ # TypeScript 源代码
99
+ │ ├── index.ts # 主要 TypeScript API
100
+ │ ├── example.ts # TypeScript 示例
101
+ │ └── test.ts # TypeScript 测试
102
+ ├── dist/ # 编译后的 JavaScript 输出
103
+ │ ├── index.js
104
+ │ ├── index.d.ts
105
+ │ └── ...
106
+ ├── ip2region/ # 原始 ip2region C 源代码
107
+ │ ├── xdb_api.h
108
+ │ ├── xdb_util.c
109
+ │ └── xdb_searcher.c
110
+ ├── addon.cpp # Node.js 扩展实现
111
+ ├── binding.gyp # 构建配置
112
+ ├── tsconfig.json # TypeScript 配置
113
+ ├── package.json
114
+ └── README.md
115
+ ```
116
+
117
+ ## 许可证
118
+
119
+ Apache-2.0
package/addon.cpp ADDED
@@ -0,0 +1,258 @@
1
+ #ifndef WIN32_LEAN_AND_MEAN
2
+ #define WIN32_LEAN_AND_MEAN
3
+ #endif
4
+
5
+ #include <napi.h>
6
+
7
+ extern "C" {
8
+ #include "ip2region/xdb_api.h"
9
+ }
10
+
11
+ #include <memory>
12
+
13
+ class Ip2RegionSearcher : public Napi::ObjectWrap<Ip2RegionSearcher> {
14
+ public:
15
+ static Napi::Object Init(Napi::Env env, Napi::Object exports);
16
+ Ip2RegionSearcher(const Napi::CallbackInfo& info);
17
+ ~Ip2RegionSearcher();
18
+
19
+ private:
20
+ static Napi::FunctionReference constructor;
21
+
22
+ Napi::Value Search(const Napi::CallbackInfo& info);
23
+ Napi::Value Close(const Napi::CallbackInfo& info);
24
+
25
+ xdb_searcher_t searcher;
26
+ xdb_vector_index_t* v_index;
27
+ xdb_content_t* c_buffer;
28
+ bool is_initialized;
29
+ };
30
+
31
+ Napi::FunctionReference Ip2RegionSearcher::constructor;
32
+
33
+ Napi::Object Ip2RegionSearcher::Init(Napi::Env env, Napi::Object exports) {
34
+ Napi::HandleScope scope(env);
35
+
36
+ Napi::Function func = DefineClass(env, "Ip2RegionSearcher", {
37
+ InstanceMethod("search", &Ip2RegionSearcher::Search),
38
+ InstanceMethod("close", &Ip2RegionSearcher::Close)
39
+ });
40
+
41
+ constructor = Napi::Persistent(func);
42
+ constructor.SuppressDestruct();
43
+
44
+ exports.Set("Ip2RegionSearcher", func);
45
+ return exports;
46
+ }
47
+
48
+ Ip2RegionSearcher::Ip2RegionSearcher(const Napi::CallbackInfo& info)
49
+ : Napi::ObjectWrap<Ip2RegionSearcher>(info), v_index(nullptr), c_buffer(nullptr), is_initialized(false) {
50
+
51
+ Napi::Env env = info.Env();
52
+ Napi::HandleScope scope(env);
53
+
54
+ if (info.Length() < 1) {
55
+ Napi::TypeError::New(env, "Expected at least 1 argument").ThrowAsJavaScriptException();
56
+ return;
57
+ }
58
+
59
+ if (!info[0].IsString()) {
60
+ Napi::TypeError::New(env, "Expected string for db_path").ThrowAsJavaScriptException();
61
+ return;
62
+ }
63
+
64
+ std::string db_path = info[0].As<Napi::String>().Utf8Value();
65
+ std::string cache_policy = "vectorIndex";
66
+ std::string ip_version = "v4";
67
+
68
+ if (info.Length() > 1 && info[1].IsObject()) {
69
+ Napi::Object options = info[1].As<Napi::Object>();
70
+
71
+ if (options.Has("cachePolicy")) {
72
+ cache_policy = options.Get("cachePolicy").As<Napi::String>().Utf8Value();
73
+ }
74
+
75
+ if (options.Has("ipVersion")) {
76
+ ip_version = options.Get("ipVersion").As<Napi::String>().Utf8Value();
77
+ }
78
+ }
79
+
80
+ // 初始化winsock (Windows)
81
+ int err = xdb_init_winsock();
82
+ if (err != 0) {
83
+ Napi::Error::New(env, "Failed to init winsock").ThrowAsJavaScriptException();
84
+ return;
85
+ }
86
+
87
+ // 验证xdb文件 (跳过严格验证,因为某些xdb文件可能有兼容性问题)
88
+ // err = xdb_verify_from_file(db_path.c_str());
89
+ // if (err != 0) {
90
+ // std::string error_msg = "Failed to verify xdb file, error code: " + std::to_string(err);
91
+ // Napi::Error::New(env, error_msg).ThrowAsJavaScriptException();
92
+ // return;
93
+ // }
94
+
95
+ // 确定IP版本
96
+ xdb_version_t* version;
97
+ if (ip_version == "v4" || ip_version == "ipv4") {
98
+ version = XDB_IPv4;
99
+ } else if (ip_version == "v6" || ip_version == "ipv6") {
100
+ version = XDB_IPv6;
101
+ } else {
102
+ Napi::Error::New(env, "Invalid IP version").ThrowAsJavaScriptException();
103
+ return;
104
+ }
105
+
106
+ // 根据缓存策略初始化searcher
107
+ if (cache_policy == "file") {
108
+ err = xdb_new_with_file_only(version, &searcher, db_path.c_str());
109
+ } else if (cache_policy == "vectorIndex") {
110
+ v_index = xdb_load_vector_index_from_file(db_path.c_str());
111
+ if (v_index == nullptr) {
112
+ Napi::Error::New(env, "Failed to load vector index").ThrowAsJavaScriptException();
113
+ return;
114
+ }
115
+ err = xdb_new_with_vector_index(version, &searcher, db_path.c_str(), v_index);
116
+ } else if (cache_policy == "content") {
117
+ c_buffer = xdb_load_content_from_file(db_path.c_str());
118
+ if (c_buffer == nullptr) {
119
+ Napi::Error::New(env, "Failed to load content").ThrowAsJavaScriptException();
120
+ return;
121
+ }
122
+ err = xdb_new_with_buffer(version, &searcher, c_buffer);
123
+ } else {
124
+ Napi::Error::New(env, "Invalid cache policy").ThrowAsJavaScriptException();
125
+ return;
126
+ }
127
+
128
+ if (err != 0) {
129
+ Napi::Error::New(env, "Failed to create searcher").ThrowAsJavaScriptException();
130
+ return;
131
+ }
132
+
133
+ is_initialized = true;
134
+ }
135
+
136
+ Ip2RegionSearcher::~Ip2RegionSearcher() {
137
+ if (is_initialized) {
138
+ xdb_close(&searcher);
139
+
140
+ if (v_index != nullptr) {
141
+ xdb_free_vector_index(v_index);
142
+ }
143
+
144
+ if (c_buffer != nullptr) {
145
+ xdb_free_content(c_buffer);
146
+ }
147
+
148
+ xdb_clean_winsock();
149
+ }
150
+ }
151
+
152
+ Napi::Value Ip2RegionSearcher::Search(const Napi::CallbackInfo& info) {
153
+ Napi::Env env = info.Env();
154
+ Napi::HandleScope scope(env);
155
+
156
+ if (!is_initialized) {
157
+ Napi::Error::New(env, "Searcher not initialized").ThrowAsJavaScriptException();
158
+ return env.Null();
159
+ }
160
+
161
+ if (info.Length() < 1 || !info[0].IsString()) {
162
+ Napi::TypeError::New(env, "Expected string for IP address").ThrowAsJavaScriptException();
163
+ return env.Null();
164
+ }
165
+
166
+ std::string ip_string = info[0].As<Napi::String>().Utf8Value();
167
+
168
+ xdb_region_buffer_t region;
169
+ int err = xdb_region_buffer_init(&region, nullptr, 0);
170
+ if (err != 0) {
171
+ Napi::Error::New(env, "Failed to init region buffer").ThrowAsJavaScriptException();
172
+ return env.Null();
173
+ }
174
+
175
+ long start_time = xdb_now();
176
+ err = xdb_search_by_string(&searcher, ip_string.c_str(), &region);
177
+ long cost_time = xdb_now() - start_time;
178
+
179
+ if (err != 0) {
180
+ xdb_region_buffer_free(&region);
181
+ Napi::Error::New(env, "Search failed").ThrowAsJavaScriptException();
182
+ return env.Null();
183
+ }
184
+
185
+ Napi::Object result = Napi::Object::New(env);
186
+ result.Set("region", Napi::String::New(env, region.value ? region.value : ""));
187
+ result.Set("ioCount", Napi::Number::New(env, xdb_get_io_count(&searcher)));
188
+ result.Set("took", Napi::Number::New(env, cost_time));
189
+
190
+ xdb_region_buffer_free(&region);
191
+ return result;
192
+ }
193
+
194
+ Napi::Value Ip2RegionSearcher::Close(const Napi::CallbackInfo& info) {
195
+ Napi::Env env = info.Env();
196
+
197
+ if (is_initialized) {
198
+ xdb_close(&searcher);
199
+
200
+ if (v_index != nullptr) {
201
+ xdb_free_vector_index(v_index);
202
+ v_index = nullptr;
203
+ }
204
+
205
+ if (c_buffer != nullptr) {
206
+ xdb_free_content(c_buffer);
207
+ c_buffer = nullptr;
208
+ }
209
+
210
+ xdb_clean_winsock();
211
+ is_initialized = false;
212
+ }
213
+
214
+ return env.Undefined();
215
+ }
216
+
217
+ // 静态函数用于验证xdb文件
218
+ Napi::Value VerifyXdb(const Napi::CallbackInfo& info) {
219
+ Napi::Env env = info.Env();
220
+
221
+ if (info.Length() < 1 || !info[0].IsString()) {
222
+ Napi::TypeError::New(env, "Expected string for db_path").ThrowAsJavaScriptException();
223
+ return env.Null();
224
+ }
225
+
226
+ std::string db_path = info[0].As<Napi::String>().Utf8Value();
227
+
228
+ int err = 0;
229
+ FILE *handle = fopen(db_path.c_str(), "rb");
230
+ if (handle == NULL) {
231
+ err = -1;
232
+ } else {
233
+ // 加载header
234
+ xdb_header_t *header = xdb_load_header(handle);
235
+ if (header == NULL) {
236
+ err = 1;
237
+ } else {
238
+ // =只检查header是否正常加载
239
+ err = 0; // header加载成功即认为文件有效
240
+ xdb_free_header(header);
241
+ }
242
+ fclose(handle);
243
+ }
244
+
245
+ Napi::Object result = Napi::Object::New(env);
246
+ result.Set("valid", Napi::Boolean::New(env, err == 0));
247
+ result.Set("errorCode", Napi::Number::New(env, err));
248
+
249
+ return result;
250
+ }
251
+
252
+ Napi::Object Init(Napi::Env env, Napi::Object exports) {
253
+ Ip2RegionSearcher::Init(env, exports);
254
+ exports.Set("verifyXdb", Napi::Function::New(env, VerifyXdb));
255
+ return exports;
256
+ }
257
+
258
+ NODE_API_MODULE(ip2region, Init)
package/binding.gyp ADDED
@@ -0,0 +1,30 @@
1
+ {
2
+ "targets": [
3
+ {
4
+ "target_name": "ip2region",
5
+ "sources": [
6
+ "addon.cpp",
7
+ "ip2region/xdb_util.c",
8
+ "ip2region/xdb_searcher.c"
9
+ ],
10
+ "include_dirs": [
11
+ "<!@(node -p \"require('node-addon-api').include\")",
12
+ ".",
13
+ "ip2region"
14
+ ],
15
+ "dependencies": [
16
+ "<!(node -p \"require('node-addon-api').gyp\")"
17
+ ],
18
+ "defines": [
19
+ "NAPI_DISABLE_CPP_EXCEPTIONS"
20
+ ],
21
+ "conditions": [
22
+ ["OS=='win'", {
23
+ "libraries": [
24
+ "ws2_32.lib"
25
+ ]
26
+ }]
27
+ ]
28
+ }
29
+ ]
30
+ }
@@ -0,0 +1,53 @@
1
+ export interface SearchResult {
2
+ /** 地理位置信息字符串 */
3
+ region: string;
4
+ /** IO操作次数 */
5
+ ioCount: number;
6
+ /** 查询耗时(微秒) */
7
+ took: number;
8
+ }
9
+ export interface Ip2RegionOptions {
10
+ /** 缓存策略: 'file' | 'vectorIndex' | 'content' */
11
+ cachePolicy?: 'file' | 'vectorIndex' | 'content';
12
+ /** IP版本: 'v4' | 'v6' */
13
+ ipVersion?: 'v4' | 'v6';
14
+ }
15
+ export interface VerifyResult {
16
+ /** 验证结果 */
17
+ valid: boolean;
18
+ /** 错误代码 */
19
+ errorCode: number;
20
+ }
21
+ export default class Ip2Region {
22
+ private searcher;
23
+ /**
24
+ * 创建ip2region查询器实例
25
+ * @param dbPath xdb数据库文件路径
26
+ * @param options 配置选项
27
+ */
28
+ constructor(dbPath: string, options?: Ip2RegionOptions);
29
+ /**
30
+ * 查询IP地址对应的地理位置信息
31
+ * @param ip IP地址字符串(支持IPv4和IPv6)
32
+ * @returns 查询结果
33
+ */
34
+ search(ip: string): SearchResult;
35
+ /**
36
+ * 关闭查询器并释放资源
37
+ */
38
+ close(): void;
39
+ /**
40
+ * 验证xdb文件的有效性
41
+ * @param dbPath xdb文件路径
42
+ * @returns 验证结果
43
+ */
44
+ static verify(dbPath: string): boolean;
45
+ /**
46
+ * 验证xdb文件并返回详细信息
47
+ * @param dbPath xdb文件路径
48
+ * @returns 包含 valid 和 errorCode 的对象
49
+ */
50
+ static verifyDetailed(dbPath: string): VerifyResult;
51
+ }
52
+ export { Ip2Region };
53
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAEA,MAAM,WAAW,YAAY;IACzB,gBAAgB;IAChB,MAAM,EAAE,MAAM,CAAC;IACf,aAAa;IACb,OAAO,EAAE,MAAM,CAAC;IAChB,eAAe;IACf,IAAI,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,WAAW,gBAAgB;IAC7B,+CAA+C;IAC/C,WAAW,CAAC,EAAE,MAAM,GAAG,aAAa,GAAG,SAAS,CAAC;IACjD,wBAAwB;IACxB,SAAS,CAAC,EAAE,IAAI,GAAG,IAAI,CAAC;CAC3B;AAED,MAAM,WAAW,YAAY;IACzB,WAAW;IACX,KAAK,EAAE,OAAO,CAAC;IACf,WAAW;IACX,SAAS,EAAE,MAAM,CAAC;CACrB;AAED,MAAM,CAAC,OAAO,OAAO,SAAS;IAC1B,OAAO,CAAC,QAAQ,CAAM;IAEtB;;;;OAIG;gBACS,MAAM,EAAE,MAAM,EAAE,OAAO,GAAE,gBAAqB;IAI1D;;;;OAIG;IACH,MAAM,CAAC,EAAE,EAAE,MAAM,GAAG,YAAY;IAIhC;;OAEG;IACH,KAAK,IAAI,IAAI;IAIb;;;;OAIG;IACH,MAAM,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO;IAKtC;;;;OAIG;IACH,MAAM,CAAC,cAAc,CAAC,MAAM,EAAE,MAAM,GAAG,YAAY;CAGtD;AAED,OAAO,EAAE,SAAS,EAAE,CAAA"}
package/dist/index.js ADDED
@@ -0,0 +1,48 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.Ip2Region = void 0;
4
+ const addon = require('../build/Release/ip2region.node');
5
+ class Ip2Region {
6
+ /**
7
+ * 创建ip2region查询器实例
8
+ * @param dbPath xdb数据库文件路径
9
+ * @param options 配置选项
10
+ */
11
+ constructor(dbPath, options = {}) {
12
+ this.searcher = new addon.Ip2RegionSearcher(dbPath, options);
13
+ }
14
+ /**
15
+ * 查询IP地址对应的地理位置信息
16
+ * @param ip IP地址字符串(支持IPv4和IPv6)
17
+ * @returns 查询结果
18
+ */
19
+ search(ip) {
20
+ return this.searcher.search(ip);
21
+ }
22
+ /**
23
+ * 关闭查询器并释放资源
24
+ */
25
+ close() {
26
+ this.searcher.close();
27
+ }
28
+ /**
29
+ * 验证xdb文件的有效性
30
+ * @param dbPath xdb文件路径
31
+ * @returns 验证结果
32
+ */
33
+ static verify(dbPath) {
34
+ const result = addon.verifyXdb(dbPath);
35
+ return result.valid;
36
+ }
37
+ /**
38
+ * 验证xdb文件并返回详细信息
39
+ * @param dbPath xdb文件路径
40
+ * @returns 包含 valid 和 errorCode 的对象
41
+ */
42
+ static verifyDetailed(dbPath) {
43
+ return addon.verifyXdb(dbPath);
44
+ }
45
+ }
46
+ exports.default = Ip2Region;
47
+ exports.Ip2Region = Ip2Region;
48
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";;;AAAA,MAAM,KAAK,GAAG,OAAO,CAAC,iCAAiC,CAAC,CAAC;AAyBzD,MAAqB,SAAS;IAG1B;;;;OAIG;IACH,YAAY,MAAc,EAAE,UAA4B,EAAE;QACtD,IAAI,CAAC,QAAQ,GAAG,IAAI,KAAK,CAAC,iBAAiB,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACjE,CAAC;IAED;;;;OAIG;IACH,MAAM,CAAC,EAAU;QACb,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,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,OAAO,KAAK,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC;IACnC,CAAC;CACJ;AA9CD,4BA8CC;AAEQ,8BAAS"}
@@ -0,0 +1,27 @@
1
+ all: xdb_searcher test_util
2
+
3
+ xdb_searcher: xdb_api.h xdb_util.c xdb_searcher.c main.c
4
+ gcc -Wall -O2 -I./ xdb_util.c xdb_searcher.c main.c -o xdb_searcher
5
+
6
+ test_util: xdb_api.h xdb_util.c test_util.c
7
+ gcc -Wall -O2 -I./ xdb_util.c test_util.c -o test_util
8
+
9
+ xdb_searcher.o: xdb_searcher.c
10
+ gcc -Wall -c xdb_searcher.c
11
+
12
+ xdb_util.o: xdb_util.c
13
+ gcc -Wall -c xdb_util.c
14
+
15
+ xdb_searcher_lib: xdb_util.o xdb_searcher.o
16
+ mkdir -p build/lib
17
+ mkdir -p build/include
18
+ ar -rc build/lib/libxdb.a `find . -name *.o`
19
+ cp xdb_api.h build/include
20
+
21
+ clean:
22
+ find ./ -name \*.o | xargs rm -f
23
+ find ./ -name test_util | xargs rm -f
24
+ find ./ -name xdb_searcher | xargs rm -f
25
+ rm -rf build
26
+
27
+ .PHONY: all clean xdb_searcher test_util