@prosopo/ipinfo 0.4.24 → 0.4.26

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 (101) hide show
  1. package/.turbo/turbo-build$colon$cjs.log +3 -3
  2. package/.turbo/{turbo-build.log → turbo-build$colon$esm.log} +8 -9
  3. package/.turbo/turbo-build$colon$tsc.log +9 -9
  4. package/.turbo/turbo-build$colon$types.log +1 -0
  5. package/CHANGELOG.md +25 -0
  6. package/dist/cjs/backends/ipapi.cjs +1 -0
  7. package/dist/{backends → esm/backends}/ipapi.js +1 -0
  8. package/dist/tsc/IpInfoService.d.ts.map +1 -0
  9. package/dist/tsc/IpInfoService.js +117 -0
  10. package/dist/tsc/IpInfoService.js.map +1 -0
  11. package/dist/tsc/backends/ipapi.d.ts.map +1 -0
  12. package/dist/tsc/backends/ipapi.js +114 -0
  13. package/dist/tsc/backends/ipapi.js.map +1 -0
  14. package/dist/tsc/backends/maxmind.d.ts.map +1 -0
  15. package/dist/tsc/backends/maxmind.js +209 -0
  16. package/dist/tsc/backends/maxmind.js.map +1 -0
  17. package/dist/tsc/index.d.ts.map +1 -0
  18. package/dist/tsc/index.js +5 -0
  19. package/dist/tsc/index.js.map +1 -0
  20. package/dist/tsc/lookupCache.d.ts.map +1 -0
  21. package/dist/tsc/lookupCache.js +42 -0
  22. package/dist/tsc/lookupCache.js.map +1 -0
  23. package/dist/tsc/tests/ipInfoService.unit.test.d.ts.map +1 -0
  24. package/dist/tsc/tests/ipInfoService.unit.test.js.map +1 -0
  25. package/dist/tsc/tests/ipapi.unit.test.d.ts.map +1 -0
  26. package/dist/{tests → tsc/tests}/ipapi.unit.test.js +17 -0
  27. package/dist/tsc/tests/ipapi.unit.test.js.map +1 -0
  28. package/dist/tsc/tests/ipinfo.test-d.d.ts.map +1 -0
  29. package/dist/tsc/tests/ipinfo.test-d.js.map +1 -0
  30. package/dist/tsc/tests/lookupCache.unit.test.d.ts.map +1 -0
  31. package/dist/tsc/tests/lookupCache.unit.test.js.map +1 -0
  32. package/dist/tsc/tests/maxmind.unit.test.d.ts.map +1 -0
  33. package/dist/tsc/tests/maxmind.unit.test.js.map +1 -0
  34. package/dist/tsc/types.d.ts.map +1 -0
  35. package/dist/tsc/types.js.map +1 -0
  36. package/dist/types/IpInfoService.d.ts +22 -0
  37. package/dist/types/IpInfoService.d.ts.map +1 -0
  38. package/dist/types/backends/ipapi.d.ts +20 -0
  39. package/dist/types/backends/ipapi.d.ts.map +1 -0
  40. package/dist/types/backends/maxmind.d.ts +23 -0
  41. package/dist/types/backends/maxmind.d.ts.map +1 -0
  42. package/dist/types/index.d.ts +10 -0
  43. package/dist/types/index.d.ts.map +1 -0
  44. package/dist/types/lookupCache.d.ts +15 -0
  45. package/dist/types/lookupCache.d.ts.map +1 -0
  46. package/dist/types/tests/ipInfoService.unit.test.d.ts +2 -0
  47. package/dist/types/tests/ipInfoService.unit.test.d.ts.map +1 -0
  48. package/dist/types/tests/ipapi.unit.test.d.ts +2 -0
  49. package/dist/types/tests/ipapi.unit.test.d.ts.map +1 -0
  50. package/dist/types/tests/ipinfo.test-d.d.ts +2 -0
  51. package/dist/types/tests/ipinfo.test-d.d.ts.map +1 -0
  52. package/dist/types/tests/lookupCache.unit.test.d.ts +2 -0
  53. package/dist/types/tests/lookupCache.unit.test.d.ts.map +1 -0
  54. package/dist/types/tests/maxmind.unit.test.d.ts +2 -0
  55. package/dist/types/tests/maxmind.unit.test.d.ts.map +1 -0
  56. package/dist/types/types.d.ts +18 -0
  57. package/dist/types/types.d.ts.map +1 -0
  58. package/package.json +11 -12
  59. package/dist/IpInfoService.d.ts.map +0 -1
  60. package/dist/IpInfoService.js.map +0 -1
  61. package/dist/backends/ipapi.d.ts.map +0 -1
  62. package/dist/backends/ipapi.js.map +0 -1
  63. package/dist/backends/maxmind.d.ts.map +0 -1
  64. package/dist/backends/maxmind.js.map +0 -1
  65. package/dist/index.d.ts.map +0 -1
  66. package/dist/index.js.map +0 -1
  67. package/dist/lookupCache.d.ts.map +0 -1
  68. package/dist/lookupCache.js.map +0 -1
  69. package/dist/tests/ipInfoService.unit.test.d.ts.map +0 -1
  70. package/dist/tests/ipInfoService.unit.test.js.map +0 -1
  71. package/dist/tests/ipapi.unit.test.d.ts.map +0 -1
  72. package/dist/tests/ipapi.unit.test.js.map +0 -1
  73. package/dist/tests/ipinfo.test-d.d.ts.map +0 -1
  74. package/dist/tests/ipinfo.test-d.js.map +0 -1
  75. package/dist/tests/lookupCache.unit.test.d.ts.map +0 -1
  76. package/dist/tests/lookupCache.unit.test.js.map +0 -1
  77. package/dist/tests/maxmind.unit.test.d.ts.map +0 -1
  78. package/dist/tests/maxmind.unit.test.js.map +0 -1
  79. package/dist/types.d.ts.map +0 -1
  80. package/dist/types.js.map +0 -1
  81. /package/dist/{IpInfoService.js → esm/IpInfoService.js} +0 -0
  82. /package/dist/{_virtual → esm/_virtual}/_rolldown/runtime.js +0 -0
  83. /package/dist/{backends → esm/backends}/maxmind.js +0 -0
  84. /package/dist/{index.js → esm/index.js} +0 -0
  85. /package/dist/{lookupCache.js → esm/lookupCache.js} +0 -0
  86. /package/dist/{IpInfoService.d.ts → tsc/IpInfoService.d.ts} +0 -0
  87. /package/dist/{backends → tsc/backends}/ipapi.d.ts +0 -0
  88. /package/dist/{backends → tsc/backends}/maxmind.d.ts +0 -0
  89. /package/dist/{index.d.ts → tsc/index.d.ts} +0 -0
  90. /package/dist/{lookupCache.d.ts → tsc/lookupCache.d.ts} +0 -0
  91. /package/dist/{tests → tsc/tests}/ipInfoService.unit.test.d.ts +0 -0
  92. /package/dist/{tests → tsc/tests}/ipInfoService.unit.test.js +0 -0
  93. /package/dist/{tests → tsc/tests}/ipapi.unit.test.d.ts +0 -0
  94. /package/dist/{tests → tsc/tests}/ipinfo.test-d.d.ts +0 -0
  95. /package/dist/{tests → tsc/tests}/ipinfo.test-d.js +0 -0
  96. /package/dist/{tests → tsc/tests}/lookupCache.unit.test.d.ts +0 -0
  97. /package/dist/{tests → tsc/tests}/lookupCache.unit.test.js +0 -0
  98. /package/dist/{tests → tsc/tests}/maxmind.unit.test.d.ts +0 -0
  99. /package/dist/{tests → tsc/tests}/maxmind.unit.test.js +0 -0
  100. /package/dist/{types.d.ts → tsc/types.d.ts} +0 -0
  101. /package/dist/{types.js → tsc/types.js} +0 -0
@@ -9,6 +9,7 @@ ViteCommonJSConfig: .
9
9
  '/home/runner/work/captcha/captcha/packages/util-crypto/tsconfig.json'
10
10
  ]
11
11
  }
12
+ The plugin "vite-tsconfig-paths" is detected. Vite now supports tsconfig paths resolution natively via the resolve.tsconfigPaths option. You can remove the plugin and set resolve.tsconfigPaths: true in your Vite config instead.
12
13
  {
13
14
  externals: [
14
15
  '@prosopo/logger',
@@ -18,7 +19,6 @@ ViteCommonJSConfig: .
18
19
  '@prosopo/util-crypto'
19
20
  ]
20
21
  }
21
- The plugin "vite-tsconfig-paths" is detected. Vite now supports tsconfig paths resolution natively via the resolve.tsconfigPaths option. You can remove the plugin and set resolve.tsconfigPaths: true in your Vite config instead.
22
22
  vite v8.1.6 building ssr environment for production...
23
23
  Bundle build started
24
24
  
@@ -28,7 +28,7 @@ computing gzip size...
28
28
  dist/cjs/index.cjs 0.66 kB │ gzip: 0.26 kB
29
29
  dist/cjs/lookupCache.cjs 1.64 kB │ gzip: 0.78 kB
30
30
  dist/cjs/IpInfoService.cjs 4.03 kB │ gzip: 1.47 kB
31
- dist/cjs/backends/ipapi.cjs 4.11 kB │ gzip: 1.75 kB
31
+ dist/cjs/backends/ipapi.cjs 4.14 kB │ gzip: 1.76 kB
32
32
  dist/cjs/backends/maxmind.cjs 5.92 kB │ gzip: 1.89 kB
33
33
 
34
- ✓ built in 58ms
34
+ ✓ built in 68ms
@@ -1,5 +1,4 @@
1
- $ pnpm run build:cross-env --mode ${NODE_ENV:-development}
2
- $ vite build --config vite.esm.config.ts --mode production
1
+ $ vite build --config vite.esm.config.ts --mode ${NODE_ENV:-development}
3
2
  ViteEsmConfig: .
4
3
  {
5
4
  tsConfigPaths: [
@@ -26,11 +25,11 @@ Bundle build started
26
25
  ✓ 6 modules transformed.
27
26
  rendering chunks...
28
27
  computing gzip size...
29
- dist/_virtual/_rolldown/runtime.js 0.04 kB │ gzip: 0.06 kB
30
- dist/index.js 0.39 kB │ gzip: 0.19 kB
31
- dist/lookupCache.js 1.60 kB │ gzip: 0.77 kB
32
- dist/IpInfoService.js 3.93 kB │ gzip: 1.46 kB
33
- dist/backends/ipapi.js 4.07 kB │ gzip: 1.75 kB
34
- dist/backends/maxmind.js 5.91 kB │ gzip: 1.89 kB
28
+ dist/esm/_virtual/_rolldown/runtime.js 0.04 kB │ gzip: 0.06 kB
29
+ dist/esm/index.js 0.39 kB │ gzip: 0.19 kB
30
+ dist/esm/lookupCache.js 1.60 kB │ gzip: 0.77 kB
31
+ dist/esm/IpInfoService.js 3.93 kB │ gzip: 1.46 kB
32
+ dist/esm/backends/ipapi.js 4.10 kB │ gzip: 1.75 kB
33
+ dist/esm/backends/maxmind.js 5.91 kB │ gzip: 1.89 kB
35
34
 
36
- ✓ built in 63ms
35
+ ✓ built in 40ms
@@ -1,5 +1,5 @@
1
1
  $ tsc --build --verbose
2
- 3:59:17 PM - Projects in this build:
2
+ 12:56:40 PM - Projects in this build:
3
3
  * ../../dev/config/tsconfig.json
4
4
  * ../util/tsconfig.json
5
5
  * ../logger/tsconfig.json
@@ -8,19 +8,19 @@ $ tsc --build --verbose
8
8
  * ../types/tsconfig.json
9
9
  * tsconfig.json
10
10
 
11
- 3:59:18 PM - Project '../../dev/config/tsconfig.json' is up to date because newest input '../../dev/config/src/webpack/webpack.config.ts' is older than output '../../dev/config/tsconfig.tsbuildinfo'
11
+ 12:56:40 PM - Project '../../dev/config/tsconfig.json' is up to date because newest input '../../dev/config/src/vite/vite.esm.config.ts' is older than output '../../dev/config/dist/tsc/tsconfig.tsbuildinfo'
12
12
 
13
- 3:59:18 PM - Project '../util/tsconfig.json' is up to date because newest input '../util/src/url.ts' is older than output '../util/tsconfig.tsbuildinfo'
13
+ 12:56:40 PM - Project '../util/tsconfig.json' is up to date because newest input '../util/src/url.ts' is older than output '../util/dist/tsc/tsconfig.tsbuildinfo'
14
14
 
15
- 3:59:18 PM - Project '../logger/tsconfig.json' is up to date because newest input '../logger/src/tests/loggerBrowser.unit.test.ts' is older than output '../logger/tsconfig.tsbuildinfo'
15
+ 12:56:40 PM - Project '../logger/tsconfig.json' is up to date because newest input '../logger/src/index.ts' is older than output '../logger/dist/tsc/tsconfig.tsbuildinfo'
16
16
 
17
- 3:59:18 PM - Project '../locale/tsconfig.json' is up to date because newest input '../locale/src/process.ts' is older than output '../locale/tsconfig.tsbuildinfo'
17
+ 12:56:40 PM - Project '../locale/tsconfig.json' is up to date because newest input '../locale/src/translator.ts' is older than output '../locale/dist/tsc/tsconfig.tsbuildinfo'
18
18
 
19
- 3:59:18 PM - Project '../util-crypto/tsconfig.json' is up to date because newest input '../util-crypto/src/types.ts' is older than output '../util-crypto/tsconfig.tsbuildinfo'
19
+ 12:56:40 PM - Project '../util-crypto/tsconfig.json' is up to date because newest input '../util-crypto/src/types.ts' is older than output '../util-crypto/dist/tsc/tsconfig.tsbuildinfo'
20
20
 
21
- 3:59:18 PM - Project '../types/tsconfig.json' is up to date because newest input '../types/src/types.test-d.ts' is older than output '../types/tsconfig.tsbuildinfo'
21
+ 12:56:40 PM - Project '../types/tsconfig.json' is up to date because newest input '../types/src/types.test-d.ts' is older than output '../types/dist/tsc/tsconfig.tsbuildinfo'
22
22
 
23
- 3:59:18 PM - Project 'tsconfig.json' is out of date because output file 'tsconfig.tsbuildinfo' does not exist
23
+ 12:56:40 PM - Project 'tsconfig.json' is out of date because output file 'dist/tsc/tsconfig.tsbuildinfo' does not exist
24
24
 
25
- 3:59:18 PM - Building project '/home/runner/work/captcha/captcha/packages/ipinfo/tsconfig.json'...
25
+ 12:56:40 PM - Building project '/home/runner/work/captcha/captcha/packages/ipinfo/tsconfig.json'...
26
26
 
@@ -0,0 +1 @@
1
+ $ tsc --project tsconfig.types.json
package/CHANGELOG.md CHANGED
@@ -1,5 +1,30 @@
1
1
  # @prosopo/ipinfo
2
2
 
3
+ ## 0.4.26
4
+ ### Patch Changes
5
+
6
+ - Updated dependencies [1966fc1]
7
+ - Updated dependencies [c69b636]
8
+ - Updated dependencies [78107d9]
9
+ - Updated dependencies [d6cc6fe]
10
+ - Updated dependencies [77bd891]
11
+ - Updated dependencies [76b6edd]
12
+ - @prosopo/logger@2.1.7
13
+ - @prosopo/types@5.20.0
14
+
15
+ ## 0.4.25
16
+ ### Patch Changes
17
+
18
+ - 2086040: Each kind of build now writes to its own folder under dist: dist/esm (vite ESM), dist/cjs (vite CommonJS), dist/types (declarations), dist/tsc (plain tsc), dist/bundle and dist/bundle-webpack (bundles) and dist/native (the Rust addons). Turbo caches each folder separately, so building one variant no longer overwrites or invalidates another. Package exports point at the new folders; anything importing a file from dist by path has to add the variant folder.
19
+
20
+ The Rust addons are no longer committed. They are built into dist/native, in debug for development and tests and fully optimised when NODE_ENV=production, so building them now needs a Rust toolchain.
21
+
22
+ Code that found the repo root or its certificates by climbing a fixed number of folders up from its own file now starts from its package's folder instead (new `packageDir` in @prosopo/util/node). The fixed count stopped working once the build output moved one folder deeper.
23
+ - Updated dependencies [2086040]
24
+ - Updated dependencies [915f30b]
25
+ - @prosopo/logger@2.1.6
26
+ - @prosopo/types@5.19.0
27
+
3
28
  ## 0.4.24
4
29
  ### Patch Changes
5
30
 
@@ -79,6 +79,7 @@ var IpapiBackend = class {
79
79
  isMobile: data.is_mobile,
80
80
  isSatellite: data.is_satellite,
81
81
  isCrawler: data.is_crawler,
82
+ crawlerName: data.crawler,
82
83
  providerName: data.company?.name || data.datacenter?.datacenter,
83
84
  providerType: data.company?.type || data.asn?.type,
84
85
  asnNumber: data.asn?.asn,
@@ -79,6 +79,7 @@ var IpapiBackend = class {
79
79
  isMobile: data.is_mobile,
80
80
  isSatellite: data.is_satellite,
81
81
  isCrawler: data.is_crawler,
82
+ crawlerName: data.crawler,
82
83
  providerName: data.company?.name || data.datacenter?.datacenter,
83
84
  providerType: data.company?.type || data.asn?.type,
84
85
  asnNumber: data.asn?.asn,
@@ -0,0 +1 @@
1
+ {"version":3,"file":"IpInfoService.d.ts","sourceRoot":"","sources":["../../src/IpInfoService.ts"],"names":[],"mappings":"AAcA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,gBAAgB,CAAC;AACrD,OAAO,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;AACnD,OAAO,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAC;AAEvD,OAAO,KAAK,EAAE,cAAc,EAAE,mBAAmB,EAAE,MAAM,YAAY,CAAC;AAMtE,wBAAgB,aAAa,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CA+BjD;AAQD,MAAM,WAAW,cAAc;IAC9B,OAAO,CAAC,EAAE,cAAc,GAAG,IAAI,CAAC;IAChC,KAAK,CAAC,EAAE,YAAY,GAAG,IAAI,CAAC;CAC5B;AAED,qBAAa,aAAc,YAAW,cAAc;IACnD,OAAO,CAAC,cAAc,CAA+B;IACrD,OAAO,CAAC,YAAY,CAA6B;IACjD,OAAO,CAAC,MAAM,CAAsB;IACpC,OAAO,CAAC,QAAQ,CAAC,KAAK,CAA0B;gBAEpC,MAAM,EAAE,mBAAmB,EAAE,QAAQ,CAAC,EAAE,cAAc;IA6B5D,UAAU,IAAI,OAAO,CAAC,IAAI,CAAC;IAcjC,WAAW,IAAI,OAAO;IAsBtB,OAAO,CAAC,EAAE,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS;IAMjC,MAAM,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,cAAc,CAAC;YAMnC,cAAc;CA4C5B"}
@@ -0,0 +1,117 @@
1
+ import { IpapiBackend } from "./backends/ipapi.js";
2
+ import { MaxMindBackend } from "./backends/maxmind.js";
3
+ import { LookupCache } from "./lookupCache.js";
4
+ export function isNonRoutable(ip) {
5
+ const normalized = ip.replace(/^::ffff:/i, "");
6
+ if (normalized.startsWith("127.") ||
7
+ normalized.startsWith("10.") ||
8
+ normalized.startsWith("192.168.") ||
9
+ normalized.startsWith("169.254.") ||
10
+ normalized === "0.0.0.0") {
11
+ return true;
12
+ }
13
+ if (normalized.startsWith("172.")) {
14
+ const second = Number.parseInt(normalized.split(".")[1] ?? "", 10);
15
+ if (second >= 16 && second <= 31)
16
+ return true;
17
+ }
18
+ if (normalized === "::1" || normalized === "::")
19
+ return true;
20
+ if (/^f[cd]/i.test(normalized))
21
+ return true;
22
+ if (/^fe[89ab]/i.test(normalized))
23
+ return true;
24
+ return false;
25
+ }
26
+ export class IpInfoService {
27
+ constructor(config, backends) {
28
+ this.maxmindBackend = null;
29
+ this.ipapiBackend = null;
30
+ this.config = config;
31
+ this.cache = config.lookupCache
32
+ ? new LookupCache(config.lookupCache)
33
+ : undefined;
34
+ if (backends) {
35
+ this.maxmindBackend = backends.maxmind ?? null;
36
+ this.ipapiBackend = backends.ipapi ?? null;
37
+ return;
38
+ }
39
+ if (config.maxmindCityDbPath || config.maxmindAsnDbPath) {
40
+ this.maxmindBackend = new MaxMindBackend({
41
+ cityDbPath: config.maxmindCityDbPath,
42
+ asnDbPath: config.maxmindAsnDbPath,
43
+ logger: config.logger,
44
+ });
45
+ }
46
+ if (config.ipapiUrl) {
47
+ this.ipapiBackend = new IpapiBackend({
48
+ baseUrl: config.ipapiUrl,
49
+ apiKey: config.ipapiKey,
50
+ logger: config.logger,
51
+ });
52
+ }
53
+ }
54
+ async initialize() {
55
+ if (this.maxmindBackend) {
56
+ await this.maxmindBackend.initialize();
57
+ }
58
+ this.config.logger?.info(() => ({
59
+ msg: "IpInfoService initialized",
60
+ data: {
61
+ maxmindAvailable: this.maxmindBackend?.isAvailable() ?? false,
62
+ ipapiAvailable: this.ipapiBackend?.isAvailable() ?? false,
63
+ },
64
+ }));
65
+ }
66
+ isAvailable() {
67
+ return ((this.maxmindBackend?.isAvailable() ?? false) ||
68
+ (this.ipapiBackend?.isAvailable() ?? false));
69
+ }
70
+ country(ip) {
71
+ if (isNonRoutable(ip))
72
+ return undefined;
73
+ if (!this.maxmindBackend?.isAvailable())
74
+ return undefined;
75
+ return this.maxmindBackend.countryCode(ip);
76
+ }
77
+ async lookup(ip) {
78
+ return this.cache
79
+ ? this.cache.getOrLookup(ip, (address) => this.lookupUncached(address))
80
+ : this.lookupUncached(ip);
81
+ }
82
+ async lookupUncached(ip) {
83
+ if (isNonRoutable(ip)) {
84
+ return {
85
+ isValid: false,
86
+ error: "Non-routable IP address",
87
+ ip,
88
+ };
89
+ }
90
+ if (this.ipapiBackend?.isAvailable()) {
91
+ const result = await this.ipapiBackend.lookup(ip);
92
+ if (result.isValid) {
93
+ return result;
94
+ }
95
+ this.config.logger?.debug(() => ({
96
+ msg: "ipapi.is lookup failed, falling back to MaxMind",
97
+ data: {
98
+ ip,
99
+ error: "error" in result ? result.error : "unknown",
100
+ },
101
+ }));
102
+ if (this.maxmindBackend?.isAvailable()) {
103
+ return this.maxmindBackend.lookup(ip);
104
+ }
105
+ return result;
106
+ }
107
+ if (this.maxmindBackend?.isAvailable()) {
108
+ return this.maxmindBackend.lookup(ip);
109
+ }
110
+ return {
111
+ isValid: false,
112
+ error: "No IP info backend available",
113
+ ip,
114
+ };
115
+ }
116
+ }
117
+ //# sourceMappingURL=IpInfoService.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"IpInfoService.js","sourceRoot":"","sources":["../../src/IpInfoService.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ipapi.d.ts","sourceRoot":"","sources":["../../../src/backends/ipapi.ts"],"names":[],"mappings":"AAcA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,iBAAiB,CAAC;AAC9C,OAAO,KAAK,EAEX,cAAc,EAEd,MAAM,gBAAgB,CAAC;AAMxB,eAAO,MAAM,kBAAkB,MAAM,CAAC;AAGtC,MAAM,MAAM,OAAO,GAAG,CACrB,GAAG,EAAE,MAAM,EACX,IAAI,EAAE,WAAW,KACb,OAAO,CAAC,UAAU,CAAC,QAAQ,CAAC,CAAC;AAElC,MAAM,WAAW,kBAAkB;IAClC,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,MAAM,CAAC,EAAE,MAAM,CAAC;IAEhB,KAAK,CAAC,EAAE,OAAO,CAAC;IAEhB,SAAS,CAAC,EAAE,MAAM,CAAC;CACnB;AAuBD,eAAO,MAAM,gBAAgB,UACrB,MAAM,GAAG,SAAS,KACvB,MAAM,GAAG,SAOX,CAAC;AAEF,qBAAa,YAAY;IACxB,OAAO,CAAC,MAAM,CAAqB;gBAEvB,MAAM,EAAE,kBAAkB;IAItC,WAAW,IAAI,OAAO;IAItB,OAAO,KAAK,SAAS,GAEpB;IAEK,MAAM,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,cAAc,CAAC;CA0GjD"}
@@ -0,0 +1,114 @@
1
+ export const DEFAULT_TIMEOUT_MS = 700;
2
+ export const parseAbuserScore = (score) => {
3
+ const head = score?.split(" ")[0];
4
+ if (!head) {
5
+ return undefined;
6
+ }
7
+ const parsed = Number.parseFloat(head);
8
+ return Number.isNaN(parsed) ? undefined : parsed;
9
+ };
10
+ export class IpapiBackend {
11
+ constructor(config) {
12
+ this.config = config;
13
+ }
14
+ isAvailable() {
15
+ return Boolean(this.config.baseUrl);
16
+ }
17
+ get timeoutMs() {
18
+ return this.config.timeoutMs ?? DEFAULT_TIMEOUT_MS;
19
+ }
20
+ async lookup(ip) {
21
+ try {
22
+ if (!ip || typeof ip !== "string") {
23
+ return {
24
+ isValid: false,
25
+ error: "Invalid IP address provided",
26
+ ip: ip || "undefined",
27
+ };
28
+ }
29
+ const body = { q: ip };
30
+ if (this.config.apiKey) {
31
+ body.key = this.config.apiKey;
32
+ }
33
+ const controller = new AbortController();
34
+ const timeoutId = setTimeout(() => controller.abort(), this.timeoutMs);
35
+ try {
36
+ const doFetch = this.config.fetch ?? globalThis.fetch;
37
+ const response = await doFetch(this.config.baseUrl, {
38
+ method: "POST",
39
+ headers: {
40
+ "Content-Type": "application/json",
41
+ Accept: "application/json",
42
+ },
43
+ body: JSON.stringify(body),
44
+ signal: controller.signal,
45
+ });
46
+ clearTimeout(timeoutId);
47
+ if (!response.ok) {
48
+ return {
49
+ isValid: false,
50
+ error: `API request failed with status ${response.status}: ${response.statusText}`,
51
+ ip,
52
+ };
53
+ }
54
+ const data = (await response.json());
55
+ if (data.is_bogon) {
56
+ return {
57
+ isValid: false,
58
+ error: "IP address is bogon (non-routable)",
59
+ ip,
60
+ };
61
+ }
62
+ const result = {
63
+ ip: data.ip,
64
+ isValid: true,
65
+ isVPN: data.is_vpn,
66
+ isTor: data.is_tor,
67
+ isProxy: data.is_proxy,
68
+ isDatacenter: data.is_datacenter,
69
+ isAbuser: data.is_abuser,
70
+ isMobile: data.is_mobile,
71
+ isSatellite: data.is_satellite,
72
+ isCrawler: data.is_crawler,
73
+ crawlerName: data.crawler,
74
+ providerName: data.company?.name || data.datacenter?.datacenter,
75
+ providerType: data.company?.type || data.asn?.type,
76
+ asnNumber: data.asn?.asn,
77
+ asnOrganization: data.asn?.org,
78
+ datacenterName: data.datacenter?.datacenter,
79
+ country: data.location?.country,
80
+ countryCode: data.location?.country_code,
81
+ region: data.location?.state,
82
+ city: data.location?.city,
83
+ latitude: data.location?.latitude,
84
+ longitude: data.location?.longitude,
85
+ timezone: data.location?.timezone,
86
+ vpnService: data.vpn?.service,
87
+ vpnType: data.vpn?.type,
88
+ abuserScore: parseAbuserScore(data.asn?.abuser_score),
89
+ companyAbuserScore: parseAbuserScore(data.company?.abuser_score),
90
+ };
91
+ return result;
92
+ }
93
+ catch (fetchError) {
94
+ clearTimeout(timeoutId);
95
+ if (fetchError instanceof Error && fetchError.name === "AbortError") {
96
+ return {
97
+ isValid: false,
98
+ error: `Request timed out after ${this.timeoutMs}ms`,
99
+ ip,
100
+ };
101
+ }
102
+ throw fetchError;
103
+ }
104
+ }
105
+ catch (error) {
106
+ return {
107
+ isValid: false,
108
+ error: `Network or parsing error: ${error instanceof Error ? error.message : String(error)}`,
109
+ ip,
110
+ };
111
+ }
112
+ }
113
+ }
114
+ //# sourceMappingURL=ipapi.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ipapi.js","sourceRoot":"","sources":["../../../src/backends/ipapi.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1 @@
1
+ {"version":3,"file":"maxmind.d.ts","sourceRoot":"","sources":["../../../src/backends/maxmind.ts"],"names":[],"mappings":"AAcA,OAAO,KAAK,EAAsB,WAAW,EAAE,MAAM,sBAAsB,CAAC;AAC5E,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;AAqBD,qBAAa,cAAc;IAC1B,OAAO,CAAC,UAAU,CAA4B;IAC9C,OAAO,CAAC,SAAS,CAA4B;IAC7C,OAAO,CAAC,aAAa,CAA4B;IACjD,OAAO,CAAC,MAAM,CAAuB;gBAEzB,MAAM,EAAE,oBAAoB;IAIlC,UAAU,IAAI,OAAO,CAAC,IAAI,CAAC;IAoCjC,WAAW,IAAI,OAAO;IAetB,WAAW,CAAC,EAAE,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS;IAyBrC,MAAM,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,cAAc,CAAC;CA8HjD;AAUD,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"}
@@ -0,0 +1,209 @@
1
+ const openReaderFromFile = async (dbPath) => {
2
+ const { Reader } = await import("@maxmind/geoip2-node");
3
+ return Reader.open(dbPath);
4
+ };
5
+ const BAD_METHOD_CALL_ERROR = "BadMethodCallError";
6
+ export class MaxMindBackend {
7
+ constructor(config) {
8
+ this.cityReader = null;
9
+ this.asnReader = null;
10
+ this.geoReaderKind = "unknown";
11
+ this.config = config;
12
+ }
13
+ async initialize() {
14
+ const openReader = this.config.openReader ?? openReaderFromFile;
15
+ if (this.config.cityDbPath) {
16
+ try {
17
+ this.cityReader = await openReader(this.config.cityDbPath);
18
+ this.config.logger?.info(() => ({
19
+ msg: "MaxMind City reader initialized",
20
+ data: { dbPath: this.config.cityDbPath },
21
+ }));
22
+ }
23
+ catch (error) {
24
+ this.config.logger?.warn(() => ({
25
+ msg: "Failed to initialize MaxMind City reader",
26
+ err: error,
27
+ data: { dbPath: this.config.cityDbPath },
28
+ }));
29
+ }
30
+ }
31
+ if (this.config.asnDbPath) {
32
+ try {
33
+ this.asnReader = await openReader(this.config.asnDbPath);
34
+ this.config.logger?.info(() => ({
35
+ msg: "MaxMind ASN reader initialized",
36
+ data: { dbPath: this.config.asnDbPath },
37
+ }));
38
+ }
39
+ catch (error) {
40
+ this.config.logger?.warn(() => ({
41
+ msg: "Failed to initialize MaxMind ASN reader",
42
+ err: error,
43
+ data: { dbPath: this.config.asnDbPath },
44
+ }));
45
+ }
46
+ }
47
+ }
48
+ isAvailable() {
49
+ return this.cityReader !== null || this.asnReader !== null;
50
+ }
51
+ countryCode(ip) {
52
+ if (!this.cityReader)
53
+ return undefined;
54
+ if (this.geoReaderKind !== "country") {
55
+ try {
56
+ const isoCode = this.cityReader.city(ip).country?.isoCode;
57
+ this.geoReaderKind = "city";
58
+ return isoCode;
59
+ }
60
+ catch (error) {
61
+ if (!isBadMethodCall(error)) {
62
+ return undefined;
63
+ }
64
+ this.geoReaderKind = "country";
65
+ }
66
+ }
67
+ try {
68
+ return this.cityReader.country(ip).country?.isoCode;
69
+ }
70
+ catch {
71
+ return undefined;
72
+ }
73
+ }
74
+ async lookup(ip) {
75
+ if (!this.isAvailable()) {
76
+ return {
77
+ isValid: false,
78
+ error: "MaxMind readers not initialized",
79
+ ip,
80
+ };
81
+ }
82
+ try {
83
+ let cityData;
84
+ let countryData;
85
+ let asnData;
86
+ if (this.cityReader) {
87
+ if (this.geoReaderKind !== "country") {
88
+ try {
89
+ cityData = this.cityReader.city(ip);
90
+ this.geoReaderKind = "city";
91
+ }
92
+ catch (error) {
93
+ if (isBadMethodCall(error)) {
94
+ this.geoReaderKind = "country";
95
+ this.config.logger?.warn(() => ({
96
+ msg: "MaxMind geo database is not a City database; falling back to country-level lookups",
97
+ data: { dbPath: this.config.cityDbPath },
98
+ err: error,
99
+ }));
100
+ }
101
+ else {
102
+ this.config.logger?.debug(() => ({
103
+ msg: "MaxMind City lookup failed",
104
+ data: { ip },
105
+ err: error,
106
+ }));
107
+ }
108
+ }
109
+ }
110
+ if (this.geoReaderKind === "country") {
111
+ try {
112
+ countryData = this.cityReader.country(ip);
113
+ }
114
+ catch (error) {
115
+ this.config.logger?.debug(() => ({
116
+ msg: "MaxMind Country lookup failed",
117
+ data: { ip },
118
+ err: error,
119
+ }));
120
+ }
121
+ }
122
+ }
123
+ if (this.asnReader) {
124
+ try {
125
+ asnData = this.asnReader.asn(ip);
126
+ }
127
+ catch (error) {
128
+ this.config.logger?.debug(() => ({
129
+ msg: "MaxMind ASN lookup failed",
130
+ data: { ip },
131
+ err: error,
132
+ }));
133
+ }
134
+ }
135
+ const geoData = cityData ?? countryData;
136
+ if (!geoData && !asnData) {
137
+ return {
138
+ isValid: false,
139
+ error: "No MaxMind data available for IP",
140
+ ip,
141
+ };
142
+ }
143
+ const result = {
144
+ ip,
145
+ isValid: true,
146
+ isVPN: geoData?.traits?.isAnonymousVpn ?? false,
147
+ isTor: geoData?.traits?.isTorExitNode ?? false,
148
+ isProxy: (geoData?.traits?.isPublicProxy ?? false) ||
149
+ (geoData?.traits?.isResidentialProxy ?? false),
150
+ isDatacenter: geoData?.traits?.isHostingProvider ?? false,
151
+ isAbuser: false,
152
+ isMobile: false,
153
+ isSatellite: geoData?.traits?.isSatelliteProvider ?? false,
154
+ isCrawler: false,
155
+ country: geoData?.country?.names?.en,
156
+ countryCode: geoData?.country?.isoCode,
157
+ region: cityData?.subdivisions?.[0]?.names?.en,
158
+ city: cityData?.city?.names?.en,
159
+ latitude: cityData?.location?.latitude,
160
+ longitude: cityData?.location?.longitude,
161
+ timezone: cityData?.location?.timeZone,
162
+ asnNumber: geoData?.traits?.autonomousSystemNumber ??
163
+ asnData?.autonomousSystemNumber,
164
+ asnOrganization: geoData?.traits?.autonomousSystemOrganization ??
165
+ asnData?.autonomousSystemOrganization,
166
+ providerName: geoData?.traits?.autonomousSystemOrganization ??
167
+ asnData?.autonomousSystemOrganization,
168
+ providerType: mapUserType(geoData?.traits?.userType),
169
+ };
170
+ return result;
171
+ }
172
+ catch (error) {
173
+ return {
174
+ isValid: false,
175
+ error: `MaxMind lookup error: ${error instanceof Error ? error.message : String(error)}`,
176
+ ip,
177
+ };
178
+ }
179
+ }
180
+ }
181
+ function isBadMethodCall(error) {
182
+ return error instanceof Error && error.name === BAD_METHOD_CALL_ERROR;
183
+ }
184
+ function mapUserType(userType) {
185
+ switch (userType) {
186
+ case "hosting":
187
+ case "content_delivery_network":
188
+ return "hosting";
189
+ case "college":
190
+ case "school":
191
+ case "library":
192
+ return "education";
193
+ case "government":
194
+ case "military":
195
+ return "government";
196
+ case "business":
197
+ return "business";
198
+ case "residential":
199
+ case "cellular":
200
+ case "dialup":
201
+ case "cafe":
202
+ case "traveler":
203
+ case "router":
204
+ return "isp";
205
+ default:
206
+ return undefined;
207
+ }
208
+ }
209
+ //# sourceMappingURL=maxmind.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"maxmind.js","sourceRoot":"","sources":["../../../src/backends/maxmind.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAcA,OAAO,EAAE,aAAa,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AAClE,YAAY,EAAE,cAAc,EAAE,MAAM,oBAAoB,CAAC;AAIzD,OAAO,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;AACnD,YAAY,EAAE,OAAO,EAAE,kBAAkB,EAAE,MAAM,qBAAqB,CAAC;AACvE,OAAO,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAC;AACvD,YAAY,EAAE,oBAAoB,EAAE,UAAU,EAAE,MAAM,uBAAuB,CAAC;AAC9E,YAAY,EAAE,cAAc,EAAE,mBAAmB,EAAE,MAAM,YAAY,CAAC;AACtE,OAAO,EAAE,oBAAoB,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC;AACrE,YAAY,EAAE,iBAAiB,EAAE,MAAM,kBAAkB,CAAC"}
@@ -0,0 +1,5 @@
1
+ export { IpInfoService, isNonRoutable } from "./IpInfoService.js";
2
+ export { IpapiBackend } from "./backends/ipapi.js";
3
+ export { MaxMindBackend } from "./backends/maxmind.js";
4
+ export { DEFAULT_LOOKUP_CACHE, LookupCache } from "./lookupCache.js";
5
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAcA,OAAO,EAAE,aAAa,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AAKlE,OAAO,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;AAEnD,OAAO,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAC;AAGvD,OAAO,EAAE,oBAAoB,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC"}
@@ -0,0 +1 @@
1
+ {"version":3,"file":"lookupCache.d.ts","sourceRoot":"","sources":["../../src/lookupCache.ts"],"names":[],"mappings":"AAcA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,gBAAgB,CAAC;AAErD,MAAM,MAAM,iBAAiB,GAAG;IAC/B,KAAK,EAAE,MAAM,CAAC;IACd,UAAU,EAAE,MAAM,CAAC;CACnB,CAAC;AAQF,eAAO,MAAM,oBAAoB,EAAE,iBAGlC,CAAC;AASF,qBAAa,WAAW;IAIX,OAAO,CAAC,QAAQ,CAAC,MAAM;IAHnC,OAAO,CAAC,QAAQ,CAAC,OAAO,CAA4B;IACpD,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAA8C;gBAE1C,MAAM,EAAE,iBAAiB;IAEhD,WAAW,CAChB,EAAE,EAAE,MAAM,EACV,MAAM,EAAE,CAAC,EAAE,EAAE,MAAM,KAAK,OAAO,CAAC,cAAc,CAAC,GAC7C,OAAO,CAAC,cAAc,CAAC;IAsB1B,OAAO,CAAC,KAAK;CAOb"}