@prosopo/ipinfo 0.2.40 → 0.3.1

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.
Files changed (52) hide show
  1. package/.turbo/turbo-build$colon$cjs.log +12 -10
  2. package/.turbo/turbo-build$colon$tsc.log +10 -10
  3. package/.turbo/turbo-build.log +14 -11
  4. package/CHANGELOG.md +28 -0
  5. package/dist/IpInfoService.d.ts +8 -1
  6. package/dist/IpInfoService.d.ts.map +1 -1
  7. package/dist/IpInfoService.js +77 -84
  8. package/dist/IpInfoService.js.map +1 -1
  9. package/dist/_virtual/_rolldown/runtime.js +3 -0
  10. package/dist/backends/ipapi.d.ts +6 -0
  11. package/dist/backends/ipapi.d.ts.map +1 -1
  12. package/dist/backends/ipapi.js +117 -104
  13. package/dist/backends/ipapi.js.map +1 -1
  14. package/dist/backends/maxmind.d.ts +4 -0
  15. package/dist/backends/maxmind.d.ts.map +1 -1
  16. package/dist/backends/maxmind.js +126 -145
  17. package/dist/backends/maxmind.js.map +1 -1
  18. package/dist/cjs/IpInfoService.cjs +80 -86
  19. package/dist/cjs/backends/ipapi.cjs +118 -104
  20. package/dist/cjs/backends/maxmind.cjs +124 -165
  21. package/dist/cjs/index.cjs +7 -3
  22. package/dist/index.d.ts +6 -1
  23. package/dist/index.d.ts.map +1 -1
  24. package/dist/index.js +5 -4
  25. package/dist/index.js.map +1 -1
  26. package/dist/tests/ipInfoService.unit.test.d.ts +2 -0
  27. package/dist/tests/ipInfoService.unit.test.d.ts.map +1 -0
  28. package/dist/tests/ipInfoService.unit.test.js +244 -0
  29. package/dist/tests/ipInfoService.unit.test.js.map +1 -0
  30. package/dist/tests/ipapi.unit.test.d.ts +2 -0
  31. package/dist/tests/ipapi.unit.test.d.ts.map +1 -0
  32. package/dist/tests/ipapi.unit.test.js +337 -0
  33. package/dist/tests/ipapi.unit.test.js.map +1 -0
  34. package/dist/tests/ipinfo.test-d.d.ts +2 -0
  35. package/dist/tests/ipinfo.test-d.d.ts.map +1 -0
  36. package/dist/tests/ipinfo.test-d.js +97 -0
  37. package/dist/tests/ipinfo.test-d.js.map +1 -0
  38. package/dist/tests/maxmind.unit.test.d.ts +2 -0
  39. package/dist/tests/maxmind.unit.test.d.ts.map +1 -0
  40. package/dist/tests/maxmind.unit.test.js +391 -0
  41. package/dist/tests/maxmind.unit.test.js.map +1 -0
  42. package/package.json +10 -8
  43. package/src/IpInfoService.ts +19 -2
  44. package/src/backends/ipapi.ts +57 -10
  45. package/src/backends/maxmind.ts +22 -4
  46. package/src/index.ts +9 -1
  47. package/src/tests/ipInfoService.unit.test.ts +422 -0
  48. package/src/tests/ipapi.unit.test.ts +509 -0
  49. package/src/tests/ipinfo.test-d.ts +189 -0
  50. package/src/tests/maxmind.unit.test.ts +562 -0
  51. package/tsconfig.tsbuildinfo +1 -1
  52. package/vite.test.config.ts +18 -0
@@ -1,9 +1,12 @@
1
+ import type { ReaderModel } from "@maxmind/geoip2-node";
1
2
  import type { Logger } from "@prosopo/logger";
2
3
  import type { IPInfoResponse } from "@prosopo/types";
4
+ export type OpenReader = (dbPath: string) => Promise<ReaderModel>;
3
5
  export interface MaxMindBackendConfig {
4
6
  cityDbPath?: string;
5
7
  asnDbPath?: string;
6
8
  logger?: Logger;
9
+ openReader?: OpenReader;
7
10
  }
8
11
  export declare class MaxMindBackend {
9
12
  private cityReader;
@@ -14,4 +17,5 @@ export declare class MaxMindBackend {
14
17
  isAvailable(): boolean;
15
18
  lookup(ip: string): Promise<IPInfoResponse>;
16
19
  }
20
+ export type MaxMindUserType = "business" | "cafe" | "cellular" | "college" | "consumer_privacy_network" | "content_delivery_network" | "dialup" | "government" | "hosting" | "library" | "military" | "residential" | "router" | "school" | "search_engine_spider" | "traveler";
17
21
  //# sourceMappingURL=maxmind.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"maxmind.d.ts","sourceRoot":"","sources":["../../src/backends/maxmind.ts"],"names":[],"mappings":"AAeA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,iBAAiB,CAAC;AAC9C,OAAO,KAAK,EAAE,cAAc,EAAgB,MAAM,gBAAgB,CAAC;AAEnE,MAAM,WAAW,oBAAoB;IACpC,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,MAAM,CAAC,EAAE,MAAM,CAAC;CAChB;AAED,qBAAa,cAAc;IAC1B,OAAO,CAAC,UAAU,CAA4B;IAC9C,OAAO,CAAC,SAAS,CAA4B;IAC7C,OAAO,CAAC,MAAM,CAAuB;gBAEzB,MAAM,EAAE,oBAAoB;IAIlC,UAAU,IAAI,OAAO,CAAC,IAAI,CAAC;IAoCjC,WAAW,IAAI,OAAO;IAIhB,MAAM,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,cAAc,CAAC;CA8FjD"}
1
+ {"version":3,"file":"maxmind.d.ts","sourceRoot":"","sources":["../../src/backends/maxmind.ts"],"names":[],"mappings":"AAcA,OAAO,KAAK,EAAa,WAAW,EAAE,MAAM,sBAAsB,CAAC;AACnE,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,iBAAiB,CAAC;AAC9C,OAAO,KAAK,EAAE,cAAc,EAAgB,MAAM,gBAAgB,CAAC;AAOnE,MAAM,MAAM,UAAU,GAAG,CAAC,MAAM,EAAE,MAAM,KAAK,OAAO,CAAC,WAAW,CAAC,CAAC;AAWlE,MAAM,WAAW,oBAAoB;IACpC,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,MAAM,CAAC,EAAE,MAAM,CAAC;IAEhB,UAAU,CAAC,EAAE,UAAU,CAAC;CACxB;AAED,qBAAa,cAAc;IAC1B,OAAO,CAAC,UAAU,CAA4B;IAC9C,OAAO,CAAC,SAAS,CAA4B;IAC7C,OAAO,CAAC,MAAM,CAAuB;gBAEzB,MAAM,EAAE,oBAAoB;IAIlC,UAAU,IAAI,OAAO,CAAC,IAAI,CAAC;IAoCjC,WAAW,IAAI,OAAO;IAIhB,MAAM,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,cAAc,CAAC;CA8FjD;AAED,MAAM,MAAM,eAAe,GACxB,UAAU,GACV,MAAM,GACN,UAAU,GACV,SAAS,GACT,0BAA0B,GAC1B,0BAA0B,GAC1B,QAAQ,GACR,YAAY,GACZ,SAAS,GACT,SAAS,GACT,UAAU,GACV,aAAa,GACb,QAAQ,GACR,QAAQ,GACR,sBAAsB,GACtB,UAAU,CAAC"}
@@ -1,147 +1,128 @@
1
- class MaxMindBackend {
2
- constructor(config) {
3
- this.cityReader = null;
4
- this.asnReader = null;
5
- this.config = config;
6
- }
7
- async initialize() {
8
- const { Reader } = await import("@maxmind/geoip2-node");
9
- if (this.config.cityDbPath) {
10
- try {
11
- this.cityReader = await Reader.open(this.config.cityDbPath);
12
- this.config.logger?.info(() => ({
13
- msg: "MaxMind City reader initialized",
14
- data: { dbPath: this.config.cityDbPath }
15
- }));
16
- } catch (error) {
17
- this.config.logger?.warn(() => ({
18
- msg: "Failed to initialize MaxMind City reader",
19
- err: error,
20
- data: { dbPath: this.config.cityDbPath }
21
- }));
22
- }
23
- }
24
- if (this.config.asnDbPath) {
25
- try {
26
- this.asnReader = await Reader.open(this.config.asnDbPath);
27
- this.config.logger?.info(() => ({
28
- msg: "MaxMind ASN reader initialized",
29
- data: { dbPath: this.config.asnDbPath }
30
- }));
31
- } catch (error) {
32
- this.config.logger?.warn(() => ({
33
- msg: "Failed to initialize MaxMind ASN reader",
34
- err: error,
35
- data: { dbPath: this.config.asnDbPath }
36
- }));
37
- }
38
- }
39
- }
40
- isAvailable() {
41
- return this.cityReader !== null || this.asnReader !== null;
42
- }
43
- async lookup(ip) {
44
- if (!this.isAvailable()) {
45
- return {
46
- isValid: false,
47
- error: "MaxMind readers not initialized",
48
- ip
49
- };
50
- }
51
- try {
52
- let cityData;
53
- let asnData;
54
- if (this.cityReader) {
55
- try {
56
- cityData = this.cityReader.city(ip);
57
- } catch (error) {
58
- this.config.logger?.debug(() => ({
59
- msg: "MaxMind City lookup failed",
60
- data: { ip },
61
- err: error
62
- }));
63
- }
64
- }
65
- if (this.asnReader) {
66
- try {
67
- asnData = this.asnReader.asn(ip);
68
- } catch (error) {
69
- this.config.logger?.debug(() => ({
70
- msg: "MaxMind ASN lookup failed",
71
- data: { ip },
72
- err: error
73
- }));
74
- }
75
- }
76
- if (!cityData && !asnData) {
77
- return {
78
- isValid: false,
79
- error: "No MaxMind data available for IP",
80
- ip
81
- };
82
- }
83
- const result = {
84
- ip,
85
- isValid: true,
86
- // Threat indicators - GeoLite2 free DBs do not populate these
87
- isVPN: cityData?.traits?.isAnonymousVpn ?? false,
88
- isTor: cityData?.traits?.isTorExitNode ?? false,
89
- isProxy: (cityData?.traits?.isPublicProxy ?? false) || (cityData?.traits?.isResidentialProxy ?? false),
90
- isDatacenter: cityData?.traits?.isHostingProvider ?? false,
91
- isAbuser: false,
92
- isMobile: false,
93
- isSatellite: cityData?.traits?.isSatelliteProvider ?? false,
94
- isCrawler: false,
95
- // Geolocation from City DB
96
- country: cityData?.country?.names?.en,
97
- countryCode: cityData?.country?.isoCode,
98
- region: cityData?.subdivisions?.[0]?.names?.en,
99
- city: cityData?.city?.names?.en,
100
- latitude: cityData?.location?.latitude,
101
- longitude: cityData?.location?.longitude,
102
- timezone: cityData?.location?.timeZone,
103
- // ASN info - prefer City DB traits, fall back to ASN DB
104
- asnNumber: cityData?.traits?.autonomousSystemNumber ?? asnData?.autonomousSystemNumber,
105
- asnOrganization: cityData?.traits?.autonomousSystemOrganization ?? asnData?.autonomousSystemOrganization,
106
- // Provider info from ASN
107
- providerName: cityData?.traits?.autonomousSystemOrganization ?? asnData?.autonomousSystemOrganization,
108
- providerType: mapUserType(cityData?.traits?.userType)
109
- };
110
- return result;
111
- } catch (error) {
112
- return {
113
- isValid: false,
114
- error: `MaxMind lookup error: ${error instanceof Error ? error.message : String(error)}`,
115
- ip
116
- };
117
- }
118
- }
119
- }
1
+ //#region src/backends/maxmind.ts
2
+ var openReaderFromFile = async (dbPath) => {
3
+ const { Reader } = await import("@maxmind/geoip2-node");
4
+ return Reader.open(dbPath);
5
+ };
6
+ var MaxMindBackend = class {
7
+ constructor(config) {
8
+ this.cityReader = null;
9
+ this.asnReader = null;
10
+ this.config = config;
11
+ }
12
+ async initialize() {
13
+ const openReader = this.config.openReader ?? openReaderFromFile;
14
+ if (this.config.cityDbPath) try {
15
+ this.cityReader = await openReader(this.config.cityDbPath);
16
+ this.config.logger?.info(() => ({
17
+ msg: "MaxMind City reader initialized",
18
+ data: { dbPath: this.config.cityDbPath }
19
+ }));
20
+ } catch (error) {
21
+ this.config.logger?.warn(() => ({
22
+ msg: "Failed to initialize MaxMind City reader",
23
+ err: error,
24
+ data: { dbPath: this.config.cityDbPath }
25
+ }));
26
+ }
27
+ if (this.config.asnDbPath) try {
28
+ this.asnReader = await openReader(this.config.asnDbPath);
29
+ this.config.logger?.info(() => ({
30
+ msg: "MaxMind ASN reader initialized",
31
+ data: { dbPath: this.config.asnDbPath }
32
+ }));
33
+ } catch (error) {
34
+ this.config.logger?.warn(() => ({
35
+ msg: "Failed to initialize MaxMind ASN reader",
36
+ err: error,
37
+ data: { dbPath: this.config.asnDbPath }
38
+ }));
39
+ }
40
+ }
41
+ isAvailable() {
42
+ return this.cityReader !== null || this.asnReader !== null;
43
+ }
44
+ async lookup(ip) {
45
+ if (!this.isAvailable()) return {
46
+ isValid: false,
47
+ error: "MaxMind readers not initialized",
48
+ ip
49
+ };
50
+ try {
51
+ let cityData;
52
+ let asnData;
53
+ if (this.cityReader) try {
54
+ cityData = this.cityReader.city(ip);
55
+ } catch (error) {
56
+ this.config.logger?.debug(() => ({
57
+ msg: "MaxMind City lookup failed",
58
+ data: { ip },
59
+ err: error
60
+ }));
61
+ }
62
+ if (this.asnReader) try {
63
+ asnData = this.asnReader.asn(ip);
64
+ } catch (error) {
65
+ this.config.logger?.debug(() => ({
66
+ msg: "MaxMind ASN lookup failed",
67
+ data: { ip },
68
+ err: error
69
+ }));
70
+ }
71
+ if (!cityData && !asnData) return {
72
+ isValid: false,
73
+ error: "No MaxMind data available for IP",
74
+ ip
75
+ };
76
+ return {
77
+ ip,
78
+ isValid: true,
79
+ isVPN: cityData?.traits?.isAnonymousVpn ?? false,
80
+ isTor: cityData?.traits?.isTorExitNode ?? false,
81
+ isProxy: (cityData?.traits?.isPublicProxy ?? false) || (cityData?.traits?.isResidentialProxy ?? false),
82
+ isDatacenter: cityData?.traits?.isHostingProvider ?? false,
83
+ isAbuser: false,
84
+ isMobile: false,
85
+ isSatellite: cityData?.traits?.isSatelliteProvider ?? false,
86
+ isCrawler: false,
87
+ country: cityData?.country?.names?.en,
88
+ countryCode: cityData?.country?.isoCode,
89
+ region: cityData?.subdivisions?.[0]?.names?.en,
90
+ city: cityData?.city?.names?.en,
91
+ latitude: cityData?.location?.latitude,
92
+ longitude: cityData?.location?.longitude,
93
+ timezone: cityData?.location?.timeZone,
94
+ asnNumber: cityData?.traits?.autonomousSystemNumber ?? asnData?.autonomousSystemNumber,
95
+ asnOrganization: cityData?.traits?.autonomousSystemOrganization ?? asnData?.autonomousSystemOrganization,
96
+ providerName: cityData?.traits?.autonomousSystemOrganization ?? asnData?.autonomousSystemOrganization,
97
+ providerType: mapUserType(cityData?.traits?.userType)
98
+ };
99
+ } catch (error) {
100
+ return {
101
+ isValid: false,
102
+ error: `MaxMind lookup error: ${error instanceof Error ? error.message : String(error)}`,
103
+ ip
104
+ };
105
+ }
106
+ }
107
+ };
120
108
  function mapUserType(userType) {
121
- switch (userType) {
122
- case "hosting":
123
- case "content_delivery_network":
124
- return "hosting";
125
- case "college":
126
- case "school":
127
- case "library":
128
- return "education";
129
- case "government":
130
- case "military":
131
- return "government";
132
- case "business":
133
- return "business";
134
- case "residential":
135
- case "cellular":
136
- case "dialup":
137
- case "cafe":
138
- case "traveler":
139
- case "router":
140
- return "isp";
141
- default:
142
- return void 0;
143
- }
109
+ switch (userType) {
110
+ case "hosting":
111
+ case "content_delivery_network": return "hosting";
112
+ case "college":
113
+ case "school":
114
+ case "library": return "education";
115
+ case "government":
116
+ case "military": return "government";
117
+ case "business": return "business";
118
+ case "residential":
119
+ case "cellular":
120
+ case "dialup":
121
+ case "cafe":
122
+ case "traveler":
123
+ case "router": return "isp";
124
+ default: return;
125
+ }
144
126
  }
145
- export {
146
- MaxMindBackend
147
- };
127
+ //#endregion
128
+ export { MaxMindBackend };
@@ -1 +1 @@
1
- {"version":3,"file":"maxmind.js","sourceRoot":"","sources":["../../src/backends/maxmind.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"maxmind.js","sourceRoot":"","sources":["../../src/backends/maxmind.ts"],"names":[],"mappings":"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"}
@@ -1,89 +1,83 @@
1
- "use strict";
2
- Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
3
- const ipapi = require("./backends/ipapi.cjs");
4
- const maxmind = require("./backends/maxmind.cjs");
1
+ const require_ipapi = require("./backends/ipapi.cjs");
2
+ const require_maxmind = require("./backends/maxmind.cjs");
3
+ //#region src/IpInfoService.ts
4
+ /**
5
+ * Returns true for loopback, link-local, and private-range IPs that will
6
+ * never yield useful geolocation or threat data from any backend.
7
+ */
5
8
  function isNonRoutable(ip) {
6
- const normalized = ip.replace(/^::ffff:/i, "");
7
- if (normalized.startsWith("127.") || normalized.startsWith("10.") || normalized.startsWith("192.168.") || normalized.startsWith("169.254.") || normalized === "0.0.0.0") {
8
- return true;
9
- }
10
- if (normalized.startsWith("172.")) {
11
- const second = Number.parseInt(normalized.split(".")[1] ?? "", 10);
12
- if (second >= 16 && second <= 31) return true;
13
- }
14
- if (normalized === "::1" || normalized === "::") return true;
15
- if (/^f[cd]/i.test(normalized)) return true;
16
- if (/^fe[89ab]/i.test(normalized)) return true;
17
- return false;
18
- }
19
- class IpInfoService {
20
- constructor(config) {
21
- this.maxmindBackend = null;
22
- this.ipapiBackend = null;
23
- this.config = config;
24
- if (config.maxmindCityDbPath || config.maxmindAsnDbPath) {
25
- this.maxmindBackend = new maxmind.MaxMindBackend({
26
- cityDbPath: config.maxmindCityDbPath,
27
- asnDbPath: config.maxmindAsnDbPath,
28
- logger: config.logger
29
- });
30
- }
31
- if (config.ipapiUrl) {
32
- this.ipapiBackend = new ipapi.IpapiBackend({
33
- baseUrl: config.ipapiUrl,
34
- apiKey: config.ipapiKey,
35
- logger: config.logger
36
- });
37
- }
38
- }
39
- async initialize() {
40
- if (this.maxmindBackend) {
41
- await this.maxmindBackend.initialize();
42
- }
43
- this.config.logger?.info(() => ({
44
- msg: "IpInfoService initialized",
45
- data: {
46
- maxmindAvailable: this.maxmindBackend?.isAvailable() ?? false,
47
- ipapiAvailable: this.ipapiBackend?.isAvailable() ?? false
48
- }
49
- }));
50
- }
51
- isAvailable() {
52
- return (this.maxmindBackend?.isAvailable() ?? false) || (this.ipapiBackend?.isAvailable() ?? false);
53
- }
54
- async lookup(ip) {
55
- if (isNonRoutable(ip)) {
56
- return {
57
- isValid: false,
58
- error: "Non-routable IP address",
59
- ip
60
- };
61
- }
62
- if (this.ipapiBackend?.isAvailable()) {
63
- const result = await this.ipapiBackend.lookup(ip);
64
- if (result.isValid) {
65
- return result;
66
- }
67
- this.config.logger?.debug(() => ({
68
- msg: "ipapi.is lookup failed, falling back to MaxMind",
69
- data: {
70
- ip,
71
- error: "error" in result ? result.error : "unknown"
72
- }
73
- }));
74
- if (this.maxmindBackend?.isAvailable()) {
75
- return this.maxmindBackend.lookup(ip);
76
- }
77
- return result;
78
- }
79
- if (this.maxmindBackend?.isAvailable()) {
80
- return this.maxmindBackend.lookup(ip);
81
- }
82
- return {
83
- isValid: false,
84
- error: "No IP info backend available",
85
- ip
86
- };
87
- }
9
+ const normalized = ip.replace(/^::ffff:/i, "");
10
+ if (normalized.startsWith("127.") || normalized.startsWith("10.") || normalized.startsWith("192.168.") || normalized.startsWith("169.254.") || normalized === "0.0.0.0") return true;
11
+ if (normalized.startsWith("172.")) {
12
+ const second = Number.parseInt(normalized.split(".")[1] ?? "", 10);
13
+ if (second >= 16 && second <= 31) return true;
14
+ }
15
+ if (normalized === "::1" || normalized === "::") return true;
16
+ if (/^f[cd]/i.test(normalized)) return true;
17
+ if (/^fe[89ab]/i.test(normalized)) return true;
18
+ return false;
88
19
  }
20
+ var IpInfoService = class {
21
+ constructor(config, backends) {
22
+ this.maxmindBackend = null;
23
+ this.ipapiBackend = null;
24
+ this.config = config;
25
+ if (backends) {
26
+ this.maxmindBackend = backends.maxmind ?? null;
27
+ this.ipapiBackend = backends.ipapi ?? null;
28
+ return;
29
+ }
30
+ if (config.maxmindCityDbPath || config.maxmindAsnDbPath) this.maxmindBackend = new require_maxmind.MaxMindBackend({
31
+ cityDbPath: config.maxmindCityDbPath,
32
+ asnDbPath: config.maxmindAsnDbPath,
33
+ logger: config.logger
34
+ });
35
+ if (config.ipapiUrl) this.ipapiBackend = new require_ipapi.IpapiBackend({
36
+ baseUrl: config.ipapiUrl,
37
+ apiKey: config.ipapiKey,
38
+ logger: config.logger
39
+ });
40
+ }
41
+ async initialize() {
42
+ if (this.maxmindBackend) await this.maxmindBackend.initialize();
43
+ this.config.logger?.info(() => ({
44
+ msg: "IpInfoService initialized",
45
+ data: {
46
+ maxmindAvailable: this.maxmindBackend?.isAvailable() ?? false,
47
+ ipapiAvailable: this.ipapiBackend?.isAvailable() ?? false
48
+ }
49
+ }));
50
+ }
51
+ isAvailable() {
52
+ return (this.maxmindBackend?.isAvailable() ?? false) || (this.ipapiBackend?.isAvailable() ?? false);
53
+ }
54
+ async lookup(ip) {
55
+ if (isNonRoutable(ip)) return {
56
+ isValid: false,
57
+ error: "Non-routable IP address",
58
+ ip
59
+ };
60
+ if (this.ipapiBackend?.isAvailable()) {
61
+ const result = await this.ipapiBackend.lookup(ip);
62
+ if (result.isValid) return result;
63
+ this.config.logger?.debug(() => ({
64
+ msg: "ipapi.is lookup failed, falling back to MaxMind",
65
+ data: {
66
+ ip,
67
+ error: "error" in result ? result.error : "unknown"
68
+ }
69
+ }));
70
+ if (this.maxmindBackend?.isAvailable()) return this.maxmindBackend.lookup(ip);
71
+ return result;
72
+ }
73
+ if (this.maxmindBackend?.isAvailable()) return this.maxmindBackend.lookup(ip);
74
+ return {
75
+ isValid: false,
76
+ error: "No IP info backend available",
77
+ ip
78
+ };
79
+ }
80
+ };
81
+ //#endregion
89
82
  exports.IpInfoService = IpInfoService;
83
+ exports.isNonRoutable = isNonRoutable;