@prosopo/ipinfo 0.2.14 → 0.2.15

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.
@@ -0,0 +1,34 @@
1
+
2
+ > @prosopo/ipinfo@0.2.15 build:cjs
3
+ > NODE_ENV=${NODE_ENV:-development}; vite build --config vite.cjs.config.ts --mode $NODE_ENV
4
+
5
+ ViteCommonJSConfig: .
6
+ {
7
+ tsConfigPaths: [
8
+ '/home/runner/work/captcha/captcha/packages/logger/tsconfig.json',
9
+ '/home/runner/work/captcha/captcha/packages/util/tsconfig.json',
10
+ '/home/runner/work/captcha/captcha/packages/types/tsconfig.json',
11
+ '/home/runner/work/captcha/captcha/packages/locale/tsconfig.json',
12
+ '/home/runner/work/captcha/captcha/packages/util-crypto/tsconfig.json'
13
+ ]
14
+ }
15
+ {
16
+ externals: [
17
+ '@prosopo/logger',
18
+ '@prosopo/util',
19
+ '@prosopo/types',
20
+ '@prosopo/locale',
21
+ '@prosopo/util-crypto'
22
+ ]
23
+ }
24
+ vite v6.4.1 building SSR bundle for production...
25
+ Bundle build started
26
+ transforming...
27
+ Build end
28
+ ✓ 4 modules transformed.
29
+ rendering chunks...
30
+ dist/cjs/index.cjs 0.19 kB
31
+ dist/cjs/IpInfoService.cjs 2.77 kB
32
+ dist/cjs/backends/ipapi.cjs 3.24 kB
33
+ dist/cjs/backends/maxmind.cjs 5.70 kB
34
+ ✓ built in 178ms
@@ -1,27 +1,29 @@
1
1
 
2
- > @prosopo/ipinfo@0.2.10 build:tsc
2
+ > @prosopo/ipinfo@0.2.15 build:tsc
3
3
  > tsc --build --verbose
4
4
 
5
- 17:33:58 - Projects in this build:
5
+ 10:13:12 AM - Projects in this build:
6
6
  * ../../dev/config/tsconfig.json
7
- * ../locale/tsconfig.json
8
7
  * ../util/tsconfig.json
8
+ * ../logger/tsconfig.json
9
+ * ../locale/tsconfig.json
9
10
  * ../util-crypto/tsconfig.json
10
11
  * ../types/tsconfig.json
11
- * ../common/tsconfig.json
12
12
  * tsconfig.json
13
13
 
14
- 17:33:58 - Project '../../dev/config/tsconfig.json' is up to date because newest input '../../dev/config/src/vite/vite.backend.config.ts' is older than output '../../dev/config/tsconfig.tsbuildinfo'
14
+ 10:13:12 AM - 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'
15
+
16
+ 10:13:12 AM - Project '../util/tsconfig.json' is up to date because newest input '../util/src/url.ts' is older than output '../util/tsconfig.tsbuildinfo'
15
17
 
16
- 17:33:58 - Project '../locale/tsconfig.json' is up to date because newest input '../locale/src/locales/tr/translation.json' is older than output '../locale/tsconfig.tsbuildinfo'
18
+ 10:13:12 AM - Project '../logger/tsconfig.json' is up to date because newest input '../logger/src/index.ts' is older than output '../logger/tsconfig.tsbuildinfo'
17
19
 
18
- 17:33:58 - Project '../util/tsconfig.json' is up to date because newest input '../util/src/url.ts' is older than output '../util/tsconfig.tsbuildinfo'
20
+ 10:13:12 AM - Project '../locale/tsconfig.json' is up to date because newest input '../locale/src/util.ts' is older than output '../locale/tsconfig.tsbuildinfo'
19
21
 
20
- 17:33:58 - 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'
22
+ 10:13:12 AM - 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'
21
23
 
22
- 17:33:58 - Project '../types/tsconfig.json' is up to date because newest input '../types/src/provider/database.ts' is older than output '../types/tsconfig.tsbuildinfo'
24
+ 10:13:12 AM - Project '../types/tsconfig.json' is up to date because newest input '../types/src/procaptcha/api.ts' is older than output '../types/tsconfig.tsbuildinfo'
23
25
 
24
- 17:33:58 - Project '../common/tsconfig.json' is up to date because newest input '../common/src/error.ts' is older than output '../common/tsconfig.tsbuildinfo'
26
+ 10:13:12 AM - Project 'tsconfig.json' is out of date because output file 'tsconfig.tsbuildinfo' does not exist
25
27
 
26
- 17:33:58 - Project 'tsconfig.json' is up to date because newest input 'src/IpInfoService.ts' is older than output 'tsconfig.tsbuildinfo'
28
+ 10:13:12 AM - Building project '/home/runner/work/captcha/captcha/packages/ipinfo/tsconfig.json'...
27
29
 
@@ -1,38 +1,38 @@
1
-
2
-
3
- > @prosopo/ipinfo@0.2.11 build
4
- > npm run build:cross-env -- --mode ${NODE_ENV:-development}
5
-
6
-
7
- > @prosopo/ipinfo@0.2.11 build:cross-env
8
- > vite build --config vite.esm.config.ts --mode production
9
-
10
- ViteEsmConfig: .
11
- {
12
- tsConfigPaths: [
13
- '/home/chris/dev/prosopo/captcha-private2/captcha/packages/logger/tsconfig.json',
14
- '/home/chris/dev/prosopo/captcha-private2/captcha/packages/types/tsconfig.json',
15
- '/home/chris/dev/prosopo/captcha-private2/captcha/packages/locale/tsconfig.json',
16
- '/home/chris/dev/prosopo/captcha-private2/captcha/packages/util/tsconfig.json',
17
- '/home/chris/dev/prosopo/captcha-private2/captcha/packages/util-crypto/tsconfig.json'
18
- ]
19
- }
20
- {
21
- externals: [
22
- '@prosopo/logger',
23
- '@prosopo/types',
24
- '@prosopo/locale',
25
- '@prosopo/util',
26
- '@prosopo/util-crypto'
27
- ]
28
- }
29
- vite v6.4.1 building SSR bundle for production...
30
- Bundle build started
31
- transforming (1) src/index.tsBuild end
32
- ✓ 4 modules transformed.
33
- rendering chunks (1)...rendering chunks (2)...rendering chunks (3)...rendering chunks (4)...dist/index.js 0.08 kB
34
- dist/IpInfoService.js 2.67 kB
35
- dist/backends/ipapi.js 3.14 kB
36
- dist/backends/maxmind.js 4.44 kB
37
- ✓ built in 142ms
38
- ⠙⠙
1
+
2
+ > @prosopo/ipinfo@0.2.15 build
3
+ > npm run build:cross-env -- --mode ${NODE_ENV:-development}
4
+
5
+
6
+ > @prosopo/ipinfo@0.2.15 build:cross-env
7
+ > vite build --config vite.esm.config.ts --mode production
8
+
9
+ ViteEsmConfig: .
10
+ {
11
+ tsConfigPaths: [
12
+ '/home/runner/work/captcha/captcha/packages/logger/tsconfig.json',
13
+ '/home/runner/work/captcha/captcha/packages/util/tsconfig.json',
14
+ '/home/runner/work/captcha/captcha/packages/types/tsconfig.json',
15
+ '/home/runner/work/captcha/captcha/packages/locale/tsconfig.json',
16
+ '/home/runner/work/captcha/captcha/packages/util-crypto/tsconfig.json'
17
+ ]
18
+ }
19
+ {
20
+ externals: [
21
+ '@prosopo/logger',
22
+ '@prosopo/util',
23
+ '@prosopo/types',
24
+ '@prosopo/locale',
25
+ '@prosopo/util-crypto'
26
+ ]
27
+ }
28
+ vite v6.4.1 building SSR bundle for production...
29
+ Bundle build started
30
+ transforming...
31
+ Build end
32
+ ✓ 4 modules transformed.
33
+ rendering chunks...
34
+ dist/index.js 0.08 kB
35
+ dist/IpInfoService.js 2.67 kB
36
+ dist/backends/ipapi.js 3.14 kB
37
+ dist/backends/maxmind.js 4.44 kB
38
+ ✓ built in 228ms
package/CHANGELOG.md CHANGED
@@ -1,5 +1,12 @@
1
1
  # @prosopo/ipinfo
2
2
 
3
+ ## 0.2.15
4
+ ### Patch Changes
5
+
6
+ - 9b18b31: Bump @prosopo/ipinfo so npm accepts the trusted-publishing publish. Version 0.2.14 was previously burned on the registry; this republishes at 0.2.15.
7
+ - Updated dependencies [b03dad1]
8
+ - @prosopo/types@4.3.1
9
+
3
10
  ## 0.2.14
4
11
  ### Patch Changes
5
12
 
@@ -1,96 +1,89 @@
1
1
  import { IpapiBackend } from "./backends/ipapi.js";
2
2
  import { MaxMindBackend } from "./backends/maxmind.js";
3
3
  function isNonRoutable(ip) {
4
- const normalized = ip.replace(/^::ffff:/i, "");
5
- if (normalized.startsWith("127.") ||
6
- normalized.startsWith("10.") ||
7
- normalized.startsWith("192.168.") ||
8
- normalized.startsWith("169.254.") ||
9
- normalized === "0.0.0.0") {
10
- return true;
11
- }
12
- if (normalized.startsWith("172.")) {
13
- const second = Number.parseInt(normalized.split(".")[1] ?? "", 10);
14
- if (second >= 16 && second <= 31)
15
- return true;
16
- }
17
- if (normalized === "::1" || normalized === "::")
18
- return true;
19
- if (/^f[cd]/i.test(normalized))
20
- return true;
21
- if (/^fe[89ab]/i.test(normalized))
22
- return true;
23
- return false;
4
+ const normalized = ip.replace(/^::ffff:/i, "");
5
+ if (normalized.startsWith("127.") || normalized.startsWith("10.") || normalized.startsWith("192.168.") || normalized.startsWith("169.254.") || normalized === "0.0.0.0") {
6
+ return true;
7
+ }
8
+ if (normalized.startsWith("172.")) {
9
+ const second = Number.parseInt(normalized.split(".")[1] ?? "", 10);
10
+ if (second >= 16 && second <= 31) return true;
11
+ }
12
+ if (normalized === "::1" || normalized === "::") return true;
13
+ if (/^f[cd]/i.test(normalized)) return true;
14
+ if (/^fe[89ab]/i.test(normalized)) return true;
15
+ return false;
24
16
  }
25
- export class IpInfoService {
26
- constructor(config) {
27
- this.maxmindBackend = null;
28
- this.ipapiBackend = null;
29
- this.config = config;
30
- if (config.maxmindCityDbPath || config.maxmindAsnDbPath) {
31
- this.maxmindBackend = new MaxMindBackend({
32
- cityDbPath: config.maxmindCityDbPath,
33
- asnDbPath: config.maxmindAsnDbPath,
34
- logger: config.logger,
35
- });
36
- }
37
- if (config.ipapiUrl) {
38
- this.ipapiBackend = new IpapiBackend({
39
- baseUrl: config.ipapiUrl,
40
- apiKey: config.ipapiKey,
41
- logger: config.logger,
42
- });
43
- }
17
+ class IpInfoService {
18
+ constructor(config) {
19
+ this.maxmindBackend = null;
20
+ this.ipapiBackend = null;
21
+ this.config = config;
22
+ if (config.maxmindCityDbPath || config.maxmindAsnDbPath) {
23
+ this.maxmindBackend = new MaxMindBackend({
24
+ cityDbPath: config.maxmindCityDbPath,
25
+ asnDbPath: config.maxmindAsnDbPath,
26
+ logger: config.logger
27
+ });
44
28
  }
45
- async initialize() {
46
- if (this.maxmindBackend) {
47
- await this.maxmindBackend.initialize();
48
- }
49
- this.config.logger?.info(() => ({
50
- msg: "IpInfoService initialized",
51
- data: {
52
- maxmindAvailable: this.maxmindBackend?.isAvailable() ?? false,
53
- ipapiAvailable: this.ipapiBackend?.isAvailable() ?? false,
54
- },
55
- }));
29
+ if (config.ipapiUrl) {
30
+ this.ipapiBackend = new IpapiBackend({
31
+ baseUrl: config.ipapiUrl,
32
+ apiKey: config.ipapiKey,
33
+ logger: config.logger
34
+ });
56
35
  }
57
- isAvailable() {
58
- return ((this.maxmindBackend?.isAvailable() ?? false) ||
59
- (this.ipapiBackend?.isAvailable() ?? false));
36
+ }
37
+ async initialize() {
38
+ if (this.maxmindBackend) {
39
+ await this.maxmindBackend.initialize();
60
40
  }
61
- async lookup(ip) {
62
- if (isNonRoutable(ip)) {
63
- return {
64
- isValid: false,
65
- error: "Non-routable IP address",
66
- ip,
67
- };
68
- }
69
- if (this.ipapiBackend?.isAvailable()) {
70
- const result = await this.ipapiBackend.lookup(ip);
71
- if (result.isValid) {
72
- return result;
73
- }
74
- this.config.logger?.debug(() => ({
75
- msg: "ipapi.is lookup failed, falling back to MaxMind",
76
- data: {
77
- ip,
78
- error: "error" in result ? result.error : "unknown",
79
- },
80
- }));
81
- if (this.maxmindBackend?.isAvailable()) {
82
- return this.maxmindBackend.lookup(ip);
83
- }
84
- return result;
85
- }
86
- if (this.maxmindBackend?.isAvailable()) {
87
- return this.maxmindBackend.lookup(ip);
41
+ this.config.logger?.info(() => ({
42
+ msg: "IpInfoService initialized",
43
+ data: {
44
+ maxmindAvailable: this.maxmindBackend?.isAvailable() ?? false,
45
+ ipapiAvailable: this.ipapiBackend?.isAvailable() ?? false
46
+ }
47
+ }));
48
+ }
49
+ isAvailable() {
50
+ return (this.maxmindBackend?.isAvailable() ?? false) || (this.ipapiBackend?.isAvailable() ?? false);
51
+ }
52
+ async lookup(ip) {
53
+ if (isNonRoutable(ip)) {
54
+ return {
55
+ isValid: false,
56
+ error: "Non-routable IP address",
57
+ ip
58
+ };
59
+ }
60
+ if (this.ipapiBackend?.isAvailable()) {
61
+ const result = await this.ipapiBackend.lookup(ip);
62
+ if (result.isValid) {
63
+ return result;
64
+ }
65
+ this.config.logger?.debug(() => ({
66
+ msg: "ipapi.is lookup failed, falling back to MaxMind",
67
+ data: {
68
+ ip,
69
+ error: "error" in result ? result.error : "unknown"
88
70
  }
89
- return {
90
- isValid: false,
91
- error: "No IP info backend available",
92
- ip,
93
- };
71
+ }));
72
+ if (this.maxmindBackend?.isAvailable()) {
73
+ return this.maxmindBackend.lookup(ip);
74
+ }
75
+ return result;
76
+ }
77
+ if (this.maxmindBackend?.isAvailable()) {
78
+ return this.maxmindBackend.lookup(ip);
94
79
  }
80
+ return {
81
+ isValid: false,
82
+ error: "No IP info backend available",
83
+ ip
84
+ };
85
+ }
95
86
  }
96
- //# sourceMappingURL=IpInfoService.js.map
87
+ export {
88
+ IpInfoService
89
+ };
@@ -1,100 +1,104 @@
1
1
  const TIMEOUT_MS = 700;
2
- export class IpapiBackend {
3
- constructor(config) {
4
- this.config = config;
5
- }
6
- isAvailable() {
7
- return Boolean(this.config.baseUrl);
8
- }
9
- async lookup(ip) {
10
- try {
11
- if (!ip || typeof ip !== "string") {
12
- return {
13
- isValid: false,
14
- error: "Invalid IP address provided",
15
- ip: ip || "undefined",
16
- };
17
- }
18
- const body = { q: ip };
19
- if (this.config.apiKey) {
20
- body.key = this.config.apiKey;
21
- }
22
- const controller = new AbortController();
23
- const timeoutId = setTimeout(() => controller.abort(), TIMEOUT_MS);
24
- try {
25
- const response = await fetch(this.config.baseUrl, {
26
- method: "POST",
27
- headers: {
28
- "Content-Type": "application/json",
29
- Accept: "application/json",
30
- },
31
- body: JSON.stringify(body),
32
- signal: controller.signal,
33
- });
34
- clearTimeout(timeoutId);
35
- if (!response.ok) {
36
- return {
37
- isValid: false,
38
- error: `API request failed with status ${response.status}: ${response.statusText}`,
39
- ip,
40
- };
41
- }
42
- const data = (await response.json());
43
- if (data.is_bogon) {
44
- return {
45
- isValid: false,
46
- error: "IP address is bogon (non-routable)",
47
- ip,
48
- };
49
- }
50
- const result = {
51
- ip: data.ip,
52
- isValid: true,
53
- isVPN: data.is_vpn,
54
- isTor: data.is_tor,
55
- isProxy: data.is_proxy,
56
- isDatacenter: data.is_datacenter,
57
- isAbuser: data.is_abuser,
58
- isMobile: data.is_mobile,
59
- isSatellite: data.is_satellite,
60
- isCrawler: data.is_crawler,
61
- providerName: data.company?.name || data.datacenter?.datacenter,
62
- providerType: data.company?.type || data.asn?.type,
63
- asnNumber: data.asn?.asn,
64
- asnOrganization: data.asn?.org,
65
- country: data.location?.country,
66
- countryCode: data.location?.country_code,
67
- region: data.location?.state,
68
- city: data.location?.city,
69
- latitude: data.location?.latitude,
70
- longitude: data.location?.longitude,
71
- timezone: data.location?.timezone,
72
- vpnService: data.vpn?.service,
73
- vpnType: data.vpn?.type,
74
- abuserScore: Number.parseFloat(data.asn?.abuser_score.split(" ")[0] || "0"),
75
- companyAbuserScore: Number.parseFloat(data.company?.abuser_score.split(" ")[0] || "0"),
76
- };
77
- return result;
78
- }
79
- catch (fetchError) {
80
- clearTimeout(timeoutId);
81
- if (fetchError instanceof Error && fetchError.name === "AbortError") {
82
- return {
83
- isValid: false,
84
- error: `Request timed out after ${TIMEOUT_MS}ms`,
85
- ip,
86
- };
87
- }
88
- throw fetchError;
89
- }
2
+ class IpapiBackend {
3
+ constructor(config) {
4
+ this.config = config;
5
+ }
6
+ isAvailable() {
7
+ return Boolean(this.config.baseUrl);
8
+ }
9
+ async lookup(ip) {
10
+ try {
11
+ if (!ip || typeof ip !== "string") {
12
+ return {
13
+ isValid: false,
14
+ error: "Invalid IP address provided",
15
+ ip: ip || "undefined"
16
+ };
17
+ }
18
+ const body = { q: ip };
19
+ if (this.config.apiKey) {
20
+ body.key = this.config.apiKey;
21
+ }
22
+ const controller = new AbortController();
23
+ const timeoutId = setTimeout(() => controller.abort(), TIMEOUT_MS);
24
+ try {
25
+ const response = await fetch(this.config.baseUrl, {
26
+ method: "POST",
27
+ headers: {
28
+ "Content-Type": "application/json",
29
+ Accept: "application/json"
30
+ },
31
+ body: JSON.stringify(body),
32
+ signal: controller.signal
33
+ });
34
+ clearTimeout(timeoutId);
35
+ if (!response.ok) {
36
+ return {
37
+ isValid: false,
38
+ error: `API request failed with status ${response.status}: ${response.statusText}`,
39
+ ip
40
+ };
41
+ }
42
+ const data = await response.json();
43
+ if (data.is_bogon) {
44
+ return {
45
+ isValid: false,
46
+ error: "IP address is bogon (non-routable)",
47
+ ip
48
+ };
90
49
  }
91
- catch (error) {
92
- return {
93
- isValid: false,
94
- error: `Network or parsing error: ${error instanceof Error ? error.message : String(error)}`,
95
- ip,
96
- };
50
+ const result = {
51
+ ip: data.ip,
52
+ isValid: true,
53
+ isVPN: data.is_vpn,
54
+ isTor: data.is_tor,
55
+ isProxy: data.is_proxy,
56
+ isDatacenter: data.is_datacenter,
57
+ isAbuser: data.is_abuser,
58
+ isMobile: data.is_mobile,
59
+ isSatellite: data.is_satellite,
60
+ isCrawler: data.is_crawler,
61
+ providerName: data.company?.name || data.datacenter?.datacenter,
62
+ providerType: data.company?.type || data.asn?.type,
63
+ asnNumber: data.asn?.asn,
64
+ asnOrganization: data.asn?.org,
65
+ country: data.location?.country,
66
+ countryCode: data.location?.country_code,
67
+ region: data.location?.state,
68
+ city: data.location?.city,
69
+ latitude: data.location?.latitude,
70
+ longitude: data.location?.longitude,
71
+ timezone: data.location?.timezone,
72
+ vpnService: data.vpn?.service,
73
+ vpnType: data.vpn?.type,
74
+ abuserScore: Number.parseFloat(
75
+ data.asn?.abuser_score.split(" ")[0] || "0"
76
+ ),
77
+ companyAbuserScore: Number.parseFloat(
78
+ data.company?.abuser_score.split(" ")[0] || "0"
79
+ )
80
+ };
81
+ return result;
82
+ } catch (fetchError) {
83
+ clearTimeout(timeoutId);
84
+ if (fetchError instanceof Error && fetchError.name === "AbortError") {
85
+ return {
86
+ isValid: false,
87
+ error: `Request timed out after ${TIMEOUT_MS}ms`,
88
+ ip
89
+ };
97
90
  }
91
+ throw fetchError;
92
+ }
93
+ } catch (error) {
94
+ return {
95
+ isValid: false,
96
+ error: `Network or parsing error: ${error instanceof Error ? error.message : String(error)}`,
97
+ ip
98
+ };
98
99
  }
100
+ }
99
101
  }
100
- //# sourceMappingURL=ipapi.js.map
102
+ export {
103
+ IpapiBackend
104
+ };