node-ipdox 1.0.4 → 1.0.5

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 CHANGED
@@ -69,7 +69,7 @@ export interface IPDOXResponse {
69
69
  isTOR: boolean; // Boolean indicating if the IP address is a TOR node (might be undefined)
70
70
  isProxy: boolean; // Boolean indicating if the IP address is a proxy (might be undefined)
71
71
  };
72
- timeZone: string; // Time zone
72
+ timeZone?: string; // Time zone
73
73
  source: string; // Source API
74
74
  }
75
75
  ```
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,50 @@
1
+ "use strict";
2
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
3
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
4
+ return new (P || (P = Promise))(function (resolve, reject) {
5
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
6
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
7
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
8
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
9
+ });
10
+ };
11
+ Object.defineProperty(exports, "__esModule", { value: true });
12
+ const vitest_1 = require("vitest");
13
+ const index_1 = require("../index");
14
+ const RUN = process.env.RUN_INTEGRATION === "1";
15
+ const TEST_IP = process.env.TEST_IP || "8.8.8.8";
16
+ // Run only when explicitly enabled
17
+ (RUN ? vitest_1.describe : vitest_1.describe.skip)("Integration: real providers", () => {
18
+ (0, vitest_1.it)("ipwho.is", () => __awaiter(void 0, void 0, void 0, function* () {
19
+ const ipdox = new index_1.IPDox({ maxRetries: 1 });
20
+ // @ts-expect-error call provider directly to avoid randomness
21
+ const r = yield ipdox.fetchIPWhoDotIs(TEST_IP);
22
+ (0, vitest_1.expect)(r).toBeTruthy();
23
+ (0, vitest_1.expect)(r.source).toBe("ipwho.is");
24
+ (0, vitest_1.expect)(r.ip).toBeTypeOf("string");
25
+ }), 20000);
26
+ (0, vitest_1.it)("ip-api.com", () => __awaiter(void 0, void 0, void 0, function* () {
27
+ const ipdox = new index_1.IPDox({ maxRetries: 1 });
28
+ // @ts-expect-error call provider directly to avoid randomness
29
+ const r = yield ipdox.fetchIPHyphenAPIDotCom(TEST_IP);
30
+ (0, vitest_1.expect)(r).toBeTruthy();
31
+ (0, vitest_1.expect)(r.source).toBe("ip-api.com");
32
+ (0, vitest_1.expect)(r.ip).toBeTypeOf("string");
33
+ }), 20000);
34
+ (0, vitest_1.it)("freeipapi.com", () => __awaiter(void 0, void 0, void 0, function* () {
35
+ const ipdox = new index_1.IPDox({ maxRetries: 1 });
36
+ // @ts-expect-error call provider directly to avoid randomness
37
+ const r = yield ipdox.fetchFreeIPAPIDotCom(TEST_IP);
38
+ (0, vitest_1.expect)(r).toBeTruthy();
39
+ (0, vitest_1.expect)(r.source).toBe("freeipapi.com");
40
+ (0, vitest_1.expect)(r.ip).toBeTypeOf("string");
41
+ }), 20000);
42
+ (0, vitest_1.it)("ipapi.co", () => __awaiter(void 0, void 0, void 0, function* () {
43
+ const ipdox = new index_1.IPDox({ maxRetries: 1 });
44
+ // @ts-expect-error call provider directly to avoid randomness
45
+ const r = yield ipdox.fetchIPAPIDotCo(TEST_IP);
46
+ (0, vitest_1.expect)(r).toBeTruthy();
47
+ (0, vitest_1.expect)(r.source).toBe("ipapi.co");
48
+ (0, vitest_1.expect)(r.ip).toBeTypeOf("string");
49
+ }), 20000);
50
+ });
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,86 @@
1
+ "use strict";
2
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
3
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
4
+ return new (P || (P = Promise))(function (resolve, reject) {
5
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
6
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
7
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
8
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
9
+ });
10
+ };
11
+ var __importDefault = (this && this.__importDefault) || function (mod) {
12
+ return (mod && mod.__esModule) ? mod : { "default": mod };
13
+ };
14
+ Object.defineProperty(exports, "__esModule", { value: true });
15
+ const vitest_1 = require("vitest");
16
+ const axios_1 = __importDefault(require("axios"));
17
+ const index_1 = require("./index");
18
+ vitest_1.vi.mock("axios");
19
+ const mockedAxios = axios_1.default;
20
+ (0, vitest_1.describe)("IPDox", () => {
21
+ (0, vitest_1.beforeEach)(() => {
22
+ vitest_1.vi.clearAllMocks();
23
+ });
24
+ (0, vitest_1.it)("returns undefined for empty ip", () => __awaiter(void 0, void 0, void 0, function* () {
25
+ const ipdox = new index_1.IPDox();
26
+ const res = yield ipdox.doxIP({ ip: "" });
27
+ (0, vitest_1.expect)(res).toBeUndefined();
28
+ }));
29
+ (0, vitest_1.it)("formats response from ipwho.is provider", () => __awaiter(void 0, void 0, void 0, function* () {
30
+ const ipdox = new index_1.IPDox({ maxRetries: 1 });
31
+ mockedAxios.get = vitest_1.vi.fn().mockResolvedValue({
32
+ data: {
33
+ success: true,
34
+ ip: "8.8.8.8",
35
+ country_code: "US",
36
+ city: "Mountain View",
37
+ continent_code: "NA",
38
+ latitude: 37.386,
39
+ longitude: -122.0838,
40
+ postal: "94039",
41
+ connection: { isp: "Google LLC" },
42
+ timezone: { id: "America/Los_Angeles" }
43
+ }
44
+ });
45
+ // Call provider directly to avoid randomness
46
+ // @ts-expect-error Accessing class method for test
47
+ const r = yield ipdox.fetchIPWhoDotIs("8.8.8.8");
48
+ (0, vitest_1.expect)(r).toMatchObject({
49
+ ip: "8.8.8.8",
50
+ country: "US",
51
+ city: "Mountain View",
52
+ continent: "NA",
53
+ latitude: 37.386,
54
+ longitude: -122.0838,
55
+ zip: "94039",
56
+ isp: "Google LLC",
57
+ timeZone: "America/Los_Angeles",
58
+ source: "ipwho.is"
59
+ });
60
+ }));
61
+ (0, vitest_1.it)("caches responses by ip", () => __awaiter(void 0, void 0, void 0, function* () {
62
+ const ipdox = new index_1.IPDox({ maxRetries: 1 });
63
+ mockedAxios.get = vitest_1.vi.fn().mockResolvedValue({
64
+ data: {
65
+ success: true,
66
+ ip: "1.1.1.1",
67
+ country_code: "AU",
68
+ city: "Sydney",
69
+ continent_code: "OC",
70
+ latitude: -33.86,
71
+ longitude: 151.21,
72
+ postal: "2000",
73
+ connection: { isp: "Cloudflare" },
74
+ timezone: { id: "Australia/Sydney" }
75
+ }
76
+ });
77
+ // @ts-expect-error Accessing class method for test
78
+ const r1 = yield ipdox.fetchIPWhoDotIs("1.1.1.1");
79
+ (0, vitest_1.expect)(r1).toBeTruthy();
80
+ // Second call should be served from cache; axios.get should not be called again if provider is called through cache path
81
+ // @ts-expect-error Use cache via public doxIP path
82
+ ipdox.cache.set("1.1.1.1", r1);
83
+ const r2 = yield ipdox.doxIP({ ip: "1.1.1.1" });
84
+ (0, vitest_1.expect)(r2).toEqual(r1);
85
+ }));
86
+ });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "node-ipdox",
3
- "version": "1.0.4",
3
+ "version": "1.0.5",
4
4
  "description": "node-ipdox is a Node.js library for GeoIP lookup, leveraging various free GeoIP APIs. It provides a unified response format and incorporates local caching to minimize duplicate requests.",
5
5
  "author": "Mikel Calvo <contact@mikecalvo.net> (www.mikelcalvo.net)",
6
6
  "keywords": [
@@ -15,28 +15,26 @@
15
15
  "license": "ISC",
16
16
  "readmeFilename": "README.md",
17
17
  "homepage": "https://github.com/mikelcalvo/ipdox#readme",
18
- "bugs": {
19
- "url": "https://github.com/mikelcalvo/ipdox/issues"
20
- },
18
+ "bugs": { "url": "https://github.com/mikelcalvo/ipdox/issues" },
21
19
  "main": "./dist/index.js",
22
20
  "types": "./dist/index.d.ts",
23
21
  "files": ["dist"],
24
22
  "scripts": {
25
- "test": "echo \"Error: no test specified\" && exit 1",
26
- "format": "prettier --write \"**/*.ts\" \"**/*.js\" \"**/*.json\"",
23
+ "test": "vitest run",
24
+ "test:watch": "vitest",
25
+ "test:integration": "RUN_INTEGRATION=1 vitest run src/integration/ipdox.providers.int.test.ts",
26
+ "format": "prettier --write \"**/*.ts\" \"**/*.js\" \"**/*.json\" --ignore-path .prettierignore",
27
27
  "build": "tsc"
28
28
  },
29
29
  "repository": {
30
30
  "type": "git",
31
31
  "url": "git+https://github.com/mikelcalvo/node-ipdox.git"
32
32
  },
33
- "dependencies": {
34
- "axios": "1.7.2",
35
- "lru-cache": "^10.2.2"
36
- },
33
+ "dependencies": { "axios": "1.11.0", "lru-cache": "^11.1.0" },
37
34
  "devDependencies": {
38
- "@types/node": "20.14.2",
39
- "prettier": "3.3.2",
40
- "typescript": "^5.4.5"
35
+ "@types/node": "24.3.0",
36
+ "prettier": "3.6.2",
37
+ "typescript": "^5.9.2",
38
+ "vitest": "3.2.4"
41
39
  }
42
40
  }