mmdb-lib 2.1.0 → 2.2.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/LICENSE CHANGED
@@ -1,6 +1,6 @@
1
1
  The MIT License (MIT)
2
2
 
3
- Copyright (c) 2022 Dmitry Shirokov
3
+ Copyright (c) 2025 Dmitry Shirokov
4
4
 
5
5
  Permission is hereby granted, free of charge, to any person obtaining a copy of
6
6
  this software and associated documentation files (the "Software"), to deal in
package/README.md CHANGED
@@ -30,6 +30,7 @@ Supported response types:
30
30
  - CountryResponse
31
31
  - CityResponse
32
32
  - AnonymousIPResponse
33
+ - AnonymousPlusResponse
33
34
  - AsnResponse
34
35
  - ConnectionTypeResponse
35
36
  - DomainResponse
@@ -63,4 +64,16 @@ MIT
63
64
 
64
65
  ## Contributing
65
66
 
66
- add a link
67
+ All contributions are welcome. Please make sure to add tests for your changes.
68
+
69
+ You need to initialise the repository with the following command:
70
+
71
+ ```shell
72
+ git submodule update --init --recursive
73
+ ```
74
+
75
+ Then you can run tests with:
76
+
77
+ ```shell
78
+ npm test
79
+ ```
package/lib/decoder.d.ts CHANGED
@@ -1,4 +1,3 @@
1
- /// <reference types="node" />
2
1
  import { Cache } from './types';
3
2
  interface Cursor {
4
3
  value: any;
package/lib/decoder.js CHANGED
@@ -3,9 +3,8 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
3
3
  return (mod && mod.__esModule) ? mod : { "default": mod };
4
4
  };
5
5
  Object.defineProperty(exports, "__esModule", { value: true });
6
- const assert_1 = __importDefault(require("assert"));
7
6
  const utils_1 = __importDefault(require("./utils"));
8
- (0, assert_1.default)(typeof BigInt !== 'undefined', 'Apparently you are using old version of node. Please upgrade to node 10.4.x or above.');
7
+ utils_1.default.assert(typeof BigInt !== 'undefined', 'Apparently you are using old version of node. Please upgrade to node 10.4.x or above.');
9
8
  var DataType;
10
9
  (function (DataType) {
11
10
  DataType[DataType["Extended"] = 0] = "Extended";
@@ -34,7 +33,8 @@ const cursor = (value, offset) => ({ value, offset });
34
33
  class Decoder {
35
34
  constructor(db, baseOffset = 0, cache = noCache) {
36
35
  this.telemetry = {};
37
- (0, assert_1.default)((this.db = db), 'Database buffer is required');
36
+ utils_1.default.assert(Boolean(db), 'Database buffer is required');
37
+ this.db = db;
38
38
  this.baseOffset = baseOffset;
39
39
  this.cache = cache;
40
40
  }
@@ -137,11 +137,10 @@ class Decoder {
137
137
  // At this point `size` is always 31.
138
138
  // If the value is 31, then the size is 65,821 + *the next three bytes after the
139
139
  // type specifying bytes as a single unsigned integer*.
140
- return cursor(65821 +
141
- utils_1.default.concat3(this.db[offset], this.db[offset + 1], this.db[offset + 2]), offset + 3);
140
+ return cursor(65821 + this.db.readUIntBE(offset, 3), offset + 3);
142
141
  }
143
142
  decodeBytes(offset, size) {
144
- return this.db.slice(offset, offset + size);
143
+ return this.db.subarray(offset, offset + size);
145
144
  }
146
145
  decodePointer(ctrlByte, offset) {
147
146
  // Pointers use the last five bits in the control byte to calculate the pointer value.
@@ -156,17 +155,17 @@ class Decoder {
156
155
  // If the size is 0, the pointer is built by appending the next byte to the last
157
156
  // three bits to produce an 11-bit value.
158
157
  if (pointerSize === 0) {
159
- packed = utils_1.default.concat2(ctrlByte & 7, this.db[offset]);
158
+ packed = ((ctrlByte & 7) << 8) | this.db[offset];
160
159
  // If the size is 1, the pointer is built by appending the next two bytes to the
161
160
  // last three bits to produce a 19-bit value + 2048.
162
161
  }
163
162
  else if (pointerSize === 1) {
164
- packed = utils_1.default.concat3(ctrlByte & 7, this.db[offset], this.db[offset + 1]);
163
+ packed = ((ctrlByte & 7) << 16) | this.db.readUInt16BE(offset);
165
164
  // If the size is 2, the pointer is built by appending the next three bytes to the
166
165
  // last three bits to produce a 27-bit value + 526336.
167
166
  }
168
167
  else if (pointerSize === 2) {
169
- packed = utils_1.default.concat4(ctrlByte & 7, this.db[offset], this.db[offset + 1], this.db[offset + 2]);
168
+ packed = ((ctrlByte & 7) << 24) | this.db.readUIntBE(offset, 3);
170
169
  // At next point `size` is always 3.
171
170
  // Finally, if the size is 3, the pointer's value is contained in the next four
172
171
  // bytes as a 32-bit value. In this case, the last three bits of the control byte
@@ -180,11 +179,11 @@ class Decoder {
180
179
  }
181
180
  decodeArray(size, offset) {
182
181
  let tmp;
183
- const array = [];
182
+ const array = new Array(size);
184
183
  for (let i = 0; i < size; i++) {
185
184
  tmp = this.decode(offset);
186
185
  offset = tmp.offset;
187
- array.push(tmp.value);
186
+ array[i] = tmp.value;
188
187
  }
189
188
  return cursor(array, offset);
190
189
  }
@@ -214,29 +213,28 @@ class Decoder {
214
213
  if (size === 0) {
215
214
  return 0;
216
215
  }
216
+ if (size < 4) {
217
+ return this.db.readUIntBE(offset, size);
218
+ }
217
219
  return this.db.readInt32BE(offset);
218
220
  }
219
221
  decodeUint(offset, size) {
220
- switch (size) {
221
- case 0:
222
- return 0;
223
- case 1:
224
- return this.db[offset];
225
- case 2:
226
- return utils_1.default.concat2(this.db[offset + 0], this.db[offset + 1]);
227
- case 3:
228
- return utils_1.default.concat3(this.db[offset + 0], this.db[offset + 1], this.db[offset + 2]);
229
- case 4:
230
- return utils_1.default.concat4(this.db[offset + 0], this.db[offset + 1], this.db[offset + 2], this.db[offset + 3]);
231
- case 8:
232
- return this.decodeBigUint(offset, size);
233
- case 16:
234
- return this.decodeBigUint(offset, size);
235
- }
236
- return 0;
222
+ if (size === 0) {
223
+ return 0;
224
+ }
225
+ if (size <= 6) {
226
+ return this.db.readUIntBE(offset, size);
227
+ }
228
+ if (size == 8) {
229
+ return this.db.readBigInt64BE(offset).toString();
230
+ }
231
+ if (size > 16) {
232
+ return 0;
233
+ }
234
+ return this.decodeBigUint(offset, size);
237
235
  }
238
236
  decodeString(offset, size) {
239
- return this.db.slice(offset, offset + size).toString();
237
+ return this.db.toString('utf8', offset, offset + size);
240
238
  }
241
239
  decodeBigUint(offset, size) {
242
240
  const buffer = Buffer.alloc(size);
package/lib/index.d.ts CHANGED
@@ -1,4 +1,3 @@
1
- /// <reference types="node" />
2
1
  import { Metadata } from './metadata';
3
2
  import { Response } from './reader/response';
4
3
  import { ReaderOptions } from './types';
package/lib/ip.d.ts CHANGED
@@ -1,6 +1,5 @@
1
- /// <reference types="node" />
2
1
  declare const _default: {
3
- bitAt: (rawAddress: number[] | Buffer, idx: number) => number;
2
+ bitAt: (rawAddress: Buffer | number[], idx: number) => number;
4
3
  parse: (ip: string) => number[];
5
4
  validate: (ip: string) => boolean;
6
5
  };
package/lib/metadata.d.ts CHANGED
@@ -1,4 +1,3 @@
1
- /// <reference types="node" />
2
1
  export interface Metadata {
3
2
  readonly binaryFormatMajorVersion: number;
4
3
  readonly binaryFormatMinorVersion: number;
package/lib/metadata.js CHANGED
@@ -4,7 +4,6 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
4
4
  };
5
5
  Object.defineProperty(exports, "__esModule", { value: true });
6
6
  exports.isLegacyFormat = exports.parseMetadata = void 0;
7
- const assert_1 = __importDefault(require("assert"));
8
7
  const decoder_1 = __importDefault(require("./decoder"));
9
8
  const utils_1 = __importDefault(require("./utils"));
10
9
  const METADATA_START_MARKER = Buffer.from('ABCDEF4D61784D696E642E636F6D', 'hex');
@@ -17,7 +16,7 @@ const parseMetadata = (db) => {
17
16
  ? utils_1.default.legacyErrorMessage
18
17
  : 'Cannot parse binary database');
19
18
  }
20
- (0, assert_1.default)([24, 28, 32].indexOf(metadata.record_size) > -1, 'Unsupported record size');
19
+ utils_1.default.assert([24, 28, 32].indexOf(metadata.record_size) > -1, 'Unsupported record size');
21
20
  return {
22
21
  binaryFormatMajorVersion: metadata.binary_format_major_version,
23
22
  binaryFormatMinorVersion: metadata.binary_format_minor_version,
@@ -96,6 +96,11 @@ export interface AnonymousIPResponse {
96
96
  readonly is_residential_proxy?: boolean;
97
97
  readonly is_tor_exit_node?: boolean;
98
98
  }
99
+ export interface AnonymousPlusResponse extends AnonymousIPResponse {
100
+ readonly anonymizer_confidence?: number;
101
+ readonly network_last_seen?: string;
102
+ readonly provider_name?: string;
103
+ }
99
104
  export interface AsnResponse {
100
105
  readonly autonomous_system_number: number;
101
106
  readonly autonomous_system_organization: string;
@@ -115,5 +120,5 @@ export interface IspResponse extends AsnResponse {
115
120
  readonly mobile_network_code?: string;
116
121
  readonly organization: string;
117
122
  }
118
- export type Response = CountryResponse | CityResponse | AnonymousIPResponse | AsnResponse | ConnectionTypeResponse | DomainResponse | IspResponse;
123
+ export type Response = CountryResponse | CityResponse | AnonymousIPResponse | AnonymousPlusResponse | AsnResponse | ConnectionTypeResponse | DomainResponse | IspResponse;
119
124
  export {};
@@ -1,4 +1,3 @@
1
- /// <reference types="node" />
2
1
  type NodeReader = (offset: number) => number;
3
2
  export interface Walker {
4
3
  left: NodeReader;
@@ -1,13 +1,9 @@
1
1
  "use strict";
2
- var __importDefault = (this && this.__importDefault) || function (mod) {
3
- return (mod && mod.__esModule) ? mod : { "default": mod };
4
- };
5
2
  Object.defineProperty(exports, "__esModule", { value: true });
6
- const utils_1 = __importDefault(require("../utils"));
7
- const readNodeRight24 = (db) => (offset) => utils_1.default.concat3(db[offset + 3], db[offset + 4], db[offset + 5]);
8
- const readNodeLeft24 = (db) => (offset) => utils_1.default.concat3(db[offset], db[offset + 1], db[offset + 2]);
9
- const readNodeLeft28 = (db) => (offset) => utils_1.default.concat4(db[offset + 3] >> 4, db[offset], db[offset + 1], db[offset + 2]);
10
- const readNodeRight28 = (db) => (offset) => utils_1.default.concat4(db[offset + 3] & 0x0f, db[offset + 4], db[offset + 5], db[offset + 6]);
3
+ const readNodeRight24 = (db) => (offset) => db.readUIntBE(offset + 3, 3);
4
+ const readNodeLeft24 = (db) => (offset) => db.readUIntBE(offset, 3);
5
+ const readNodeLeft28 = (db) => (offset) => ((db[offset + 3] & 0xf0) << 20) | db.readUIntBE(offset, 3);
6
+ const readNodeRight28 = (db) => (offset) => ((db[offset + 3] & 0x0f) << 24) | db.readUIntBE(offset + 4, 3);
11
7
  const readNodeLeft32 = (db) => (offset) => db.readUInt32BE(offset);
12
8
  const readNodeRight32 = (db) => (offset) => db.readUInt32BE(offset + 4);
13
9
  exports.default = (db, recordSize) => {
package/lib/utils.d.ts CHANGED
@@ -1,7 +1,5 @@
1
1
  declare const _default: {
2
- concat2: (a: number, b: number) => number;
3
- concat3: (a: number, b: number, c: number) => number;
4
- concat4: (a: number, b: number, c: number, d: number) => number;
2
+ assert: (condition: boolean, message: string) => void;
5
3
  legacyErrorMessage: string;
6
4
  };
7
5
  export default _default;
package/lib/utils.js CHANGED
@@ -1,21 +1,15 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- const concat2 = (a, b) => {
4
- return (a << 8) | b;
5
- };
6
- const concat3 = (a, b, c) => {
7
- return (a << 16) | (b << 8) | c;
8
- };
9
- const concat4 = (a, b, c, d) => {
10
- return (a << 24) | (b << 16) | (c << 8) | d;
11
- };
12
3
  const legacyErrorMessage = `Maxmind v2 module has changed API.\n\
13
4
  Upgrade instructions can be found here: \
14
5
  https://github.com/runk/node-maxmind/wiki/Migration-guide\n\
15
6
  If you want to use legacy library then explicitly install maxmind@1`;
7
+ const assert = (condition, message) => {
8
+ if (!condition) {
9
+ throw new Error(message);
10
+ }
11
+ };
16
12
  exports.default = {
17
- concat2,
18
- concat3,
19
- concat4,
13
+ assert,
20
14
  legacyErrorMessage,
21
15
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "mmdb-lib",
3
- "version": "2.1.0",
3
+ "version": "2.2.0",
4
4
  "homepage": "https://github.com/runk/mmdb-lib",
5
5
  "description": "Maxmind DB (MMDB) Library",
6
6
  "keywords": [
@@ -13,23 +13,21 @@
13
13
  "author": "Dmitry Shirokov <deadrunk@gmail.com>",
14
14
  "contributors": [
15
15
  "William Storey @horgh",
16
- "Uman Shahzad @UmanShahzad"
16
+ "Uman Shahzad @UmanShahzad",
17
+ "Gregory Oschwald @oschwald"
17
18
  ],
18
19
  "devDependencies": {
19
- "@types/ip-address": "6.0.0",
20
+ "@types/ip-address": "7.0.0",
20
21
  "@types/mocha": "^10.0.1",
21
- "@types/node": "20.10.3",
22
- "@types/sinon": "17.0.2",
23
- "@typescript-eslint/eslint-plugin": "^5.0.0",
24
- "@typescript-eslint/parser": "^5.0.0",
25
- "eslint": "^8.0.0",
26
- "ip-address": "9.0.5",
27
- "mocha": "^10.2.0",
28
- "prettier": "^3.0.0",
29
- "semantic-release": "^21.0.0",
30
- "sinon": "17.0.1",
22
+ "@types/node": "22.14.0",
23
+ "@types/sinon": "17.0.4",
24
+ "ip-address": "10.0.1",
25
+ "mocha": "^11.0.0",
26
+ "prettier": "^3.5.3",
27
+ "semantic-release": "^24.0.0",
28
+ "sinon": "20.0.0",
31
29
  "ts-node": "^10.4.0",
32
- "typescript": "5.3.2"
30
+ "typescript": "5.8.2"
33
31
  },
34
32
  "repository": {
35
33
  "type": "git",
@@ -51,11 +49,11 @@
51
49
  "license": "MIT",
52
50
  "scripts": {
53
51
  "build": "rm -rf lib/* && tsc",
54
- "lint": "eslint . --ext .ts",
55
- "lint:types": "tsc --noEmit",
52
+ "typecheck": "tsc --noEmit",
56
53
  "test": "mocha",
57
- "test-imports": "node test/imports/commonjs.js && node test/imports/esm.mjs && ts-node test/imports/typescript.ts",
54
+ "test:imports": "node test/imports/commonjs.js && node test/imports/esm.mjs && ts-node test/imports/typescript.ts",
58
55
  "format": "prettier --write src",
56
+ "format:check": "prettier --check src",
59
57
  "prepublish": "npm run build",
60
58
  "semantic-release": "semantic-release"
61
59
  }