user-analytics-tracker 4.3.0 → 4.5.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/CHANGELOG.md +16 -0
- package/README.md +16 -8
- package/dist/index.cjs.js +34 -15
- package/dist/index.cjs.js.map +1 -1
- package/dist/index.d.cts +26 -11
- package/dist/index.d.ts +26 -11
- package/dist/index.esm.js +34 -15
- package/dist/index.esm.js.map +1 -1
- package/package.json +1 -1
package/dist/index.d.cts
CHANGED
|
@@ -137,6 +137,7 @@ interface AnalyticsConfig {
|
|
|
137
137
|
apiKey?: string;
|
|
138
138
|
baseUrl?: string;
|
|
139
139
|
timeout?: number;
|
|
140
|
+
ip?: string;
|
|
140
141
|
};
|
|
141
142
|
fieldStorage?: {
|
|
142
143
|
ipLocation?: FieldStorageConfig$1;
|
|
@@ -254,22 +255,28 @@ declare class DeviceDetector {
|
|
|
254
255
|
*
|
|
255
256
|
* 1) Browser / client-side:
|
|
256
257
|
* - Do NOT pass an IP. Call getCompleteIPLocation(config) with no IP.
|
|
257
|
-
* - The request goes: user's browser →
|
|
258
|
-
*
|
|
259
|
-
* - For config.apiKey: avoid hardcoding. Use a build-time env var or omit (free tier).
|
|
258
|
+
* - The request goes: user's browser → API; the API sees the visitor's IP and returns it.
|
|
259
|
+
* - For config.apiKey: use env var or omit (free tier).
|
|
260
260
|
*
|
|
261
261
|
* 2) Server-side (Node/Express/Next etc.):
|
|
262
|
-
* - Get the visitor's IP
|
|
263
|
-
* -
|
|
264
|
-
* - Keep apiKey in process.env
|
|
262
|
+
* - Get the visitor's IP with getIPFromRequest(req), then call getIPLocation(userIp, config).
|
|
263
|
+
* - Or pass ip + apiKey in config: getCompleteIPLocation({ baseUrl, apiKey, ip: userIp }).
|
|
264
|
+
* - Keep apiKey in process.env; never commit it.
|
|
265
|
+
*
|
|
266
|
+
* 3) Paid subscription (e.g. ipwhois.pro):
|
|
267
|
+
* - URL format: https://ipwhois.pro/{IP}?key=YOUR_API_KEY
|
|
268
|
+
* - Pass baseUrl: 'https://ipwhois.pro', apiKey, and ip when you have the IP.
|
|
265
269
|
*/
|
|
266
270
|
/**
|
|
267
271
|
* IP Geolocation configuration interface
|
|
272
|
+
* Supports ipwho.is (free/paid) and ipwhois.pro (paid: baseUrl/{IP}?key=API_KEY)
|
|
268
273
|
*/
|
|
269
274
|
interface IPGeolocationConfig {
|
|
270
275
|
apiKey?: string;
|
|
271
276
|
baseUrl?: string;
|
|
272
277
|
timeout?: number;
|
|
278
|
+
/** When provided (e.g. server-side or paid flow), lookup this IP. URL becomes baseUrl/{ip}?key=API_KEY */
|
|
279
|
+
ip?: string;
|
|
273
280
|
}
|
|
274
281
|
/**
|
|
275
282
|
* Get complete IP location data from ipwho.is API (HIGH PRIORITY)
|
|
@@ -280,13 +287,17 @@ interface IPGeolocationConfig {
|
|
|
280
287
|
*
|
|
281
288
|
* @example
|
|
282
289
|
* ```typescript
|
|
283
|
-
* // Without API key (free tier)
|
|
290
|
+
* // Without API key (free tier) - auto-detect requestor IP
|
|
284
291
|
* const location = await getCompleteIPLocation();
|
|
285
292
|
*
|
|
286
|
-
* // With API key (
|
|
293
|
+
* // With API key (higher rate limits)
|
|
294
|
+
* const location = await getCompleteIPLocation({ apiKey: '<key>', baseUrl: 'https://ipwho.is' });
|
|
295
|
+
*
|
|
296
|
+
* // Paid / server-side: provide IP + API key (e.g. ipwhois.pro)
|
|
287
297
|
* const location = await getCompleteIPLocation({
|
|
288
|
-
*
|
|
289
|
-
*
|
|
298
|
+
* baseUrl: 'https://ipwhois.pro',
|
|
299
|
+
* apiKey: '<key>',
|
|
300
|
+
* ip: '203.0.113.42',
|
|
290
301
|
* });
|
|
291
302
|
* ```
|
|
292
303
|
*/
|
|
@@ -322,8 +333,12 @@ declare function getPublicIP(config?: IPGeolocationConfig): Promise<string | nul
|
|
|
322
333
|
* const location = await getIPLocation('203.0.113.42');
|
|
323
334
|
*
|
|
324
335
|
* // With API key
|
|
336
|
+
* const location = await getIPLocation('203.0.113.42', { apiKey: '<key>' });
|
|
337
|
+
*
|
|
338
|
+
* // Paid ipwhois.pro: same URL format baseUrl/{IP}?key=API_KEY
|
|
325
339
|
* const location = await getIPLocation('203.0.113.42', {
|
|
326
|
-
*
|
|
340
|
+
* baseUrl: 'https://ipwhois.pro',
|
|
341
|
+
* apiKey: '<key>',
|
|
327
342
|
* });
|
|
328
343
|
* ```
|
|
329
344
|
*
|
package/dist/index.d.ts
CHANGED
|
@@ -137,6 +137,7 @@ interface AnalyticsConfig {
|
|
|
137
137
|
apiKey?: string;
|
|
138
138
|
baseUrl?: string;
|
|
139
139
|
timeout?: number;
|
|
140
|
+
ip?: string;
|
|
140
141
|
};
|
|
141
142
|
fieldStorage?: {
|
|
142
143
|
ipLocation?: FieldStorageConfig$1;
|
|
@@ -254,22 +255,28 @@ declare class DeviceDetector {
|
|
|
254
255
|
*
|
|
255
256
|
* 1) Browser / client-side:
|
|
256
257
|
* - Do NOT pass an IP. Call getCompleteIPLocation(config) with no IP.
|
|
257
|
-
* - The request goes: user's browser →
|
|
258
|
-
*
|
|
259
|
-
* - For config.apiKey: avoid hardcoding. Use a build-time env var or omit (free tier).
|
|
258
|
+
* - The request goes: user's browser → API; the API sees the visitor's IP and returns it.
|
|
259
|
+
* - For config.apiKey: use env var or omit (free tier).
|
|
260
260
|
*
|
|
261
261
|
* 2) Server-side (Node/Express/Next etc.):
|
|
262
|
-
* - Get the visitor's IP
|
|
263
|
-
* -
|
|
264
|
-
* - Keep apiKey in process.env
|
|
262
|
+
* - Get the visitor's IP with getIPFromRequest(req), then call getIPLocation(userIp, config).
|
|
263
|
+
* - Or pass ip + apiKey in config: getCompleteIPLocation({ baseUrl, apiKey, ip: userIp }).
|
|
264
|
+
* - Keep apiKey in process.env; never commit it.
|
|
265
|
+
*
|
|
266
|
+
* 3) Paid subscription (e.g. ipwhois.pro):
|
|
267
|
+
* - URL format: https://ipwhois.pro/{IP}?key=YOUR_API_KEY
|
|
268
|
+
* - Pass baseUrl: 'https://ipwhois.pro', apiKey, and ip when you have the IP.
|
|
265
269
|
*/
|
|
266
270
|
/**
|
|
267
271
|
* IP Geolocation configuration interface
|
|
272
|
+
* Supports ipwho.is (free/paid) and ipwhois.pro (paid: baseUrl/{IP}?key=API_KEY)
|
|
268
273
|
*/
|
|
269
274
|
interface IPGeolocationConfig {
|
|
270
275
|
apiKey?: string;
|
|
271
276
|
baseUrl?: string;
|
|
272
277
|
timeout?: number;
|
|
278
|
+
/** When provided (e.g. server-side or paid flow), lookup this IP. URL becomes baseUrl/{ip}?key=API_KEY */
|
|
279
|
+
ip?: string;
|
|
273
280
|
}
|
|
274
281
|
/**
|
|
275
282
|
* Get complete IP location data from ipwho.is API (HIGH PRIORITY)
|
|
@@ -280,13 +287,17 @@ interface IPGeolocationConfig {
|
|
|
280
287
|
*
|
|
281
288
|
* @example
|
|
282
289
|
* ```typescript
|
|
283
|
-
* // Without API key (free tier)
|
|
290
|
+
* // Without API key (free tier) - auto-detect requestor IP
|
|
284
291
|
* const location = await getCompleteIPLocation();
|
|
285
292
|
*
|
|
286
|
-
* // With API key (
|
|
293
|
+
* // With API key (higher rate limits)
|
|
294
|
+
* const location = await getCompleteIPLocation({ apiKey: '<key>', baseUrl: 'https://ipwho.is' });
|
|
295
|
+
*
|
|
296
|
+
* // Paid / server-side: provide IP + API key (e.g. ipwhois.pro)
|
|
287
297
|
* const location = await getCompleteIPLocation({
|
|
288
|
-
*
|
|
289
|
-
*
|
|
298
|
+
* baseUrl: 'https://ipwhois.pro',
|
|
299
|
+
* apiKey: '<key>',
|
|
300
|
+
* ip: '203.0.113.42',
|
|
290
301
|
* });
|
|
291
302
|
* ```
|
|
292
303
|
*/
|
|
@@ -322,8 +333,12 @@ declare function getPublicIP(config?: IPGeolocationConfig): Promise<string | nul
|
|
|
322
333
|
* const location = await getIPLocation('203.0.113.42');
|
|
323
334
|
*
|
|
324
335
|
* // With API key
|
|
336
|
+
* const location = await getIPLocation('203.0.113.42', { apiKey: '<key>' });
|
|
337
|
+
*
|
|
338
|
+
* // Paid ipwhois.pro: same URL format baseUrl/{IP}?key=API_KEY
|
|
325
339
|
* const location = await getIPLocation('203.0.113.42', {
|
|
326
|
-
*
|
|
340
|
+
* baseUrl: 'https://ipwhois.pro',
|
|
341
|
+
* apiKey: '<key>',
|
|
327
342
|
* });
|
|
328
343
|
* ```
|
|
329
344
|
*
|
package/dist/index.esm.js
CHANGED
|
@@ -621,13 +621,17 @@ function checkAndSetLocationConsent(msisdn) {
|
|
|
621
621
|
*
|
|
622
622
|
* @example
|
|
623
623
|
* ```typescript
|
|
624
|
-
* // Without API key (free tier)
|
|
624
|
+
* // Without API key (free tier) - auto-detect requestor IP
|
|
625
625
|
* const location = await getCompleteIPLocation();
|
|
626
626
|
*
|
|
627
|
-
* // With API key (
|
|
627
|
+
* // With API key (higher rate limits)
|
|
628
|
+
* const location = await getCompleteIPLocation({ apiKey: '<key>', baseUrl: 'https://ipwho.is' });
|
|
629
|
+
*
|
|
630
|
+
* // Paid / server-side: provide IP + API key (e.g. ipwhois.pro)
|
|
628
631
|
* const location = await getCompleteIPLocation({
|
|
629
|
-
*
|
|
630
|
-
*
|
|
632
|
+
* baseUrl: 'https://ipwhois.pro',
|
|
633
|
+
* apiKey: '<key>',
|
|
634
|
+
* ip: '203.0.113.42',
|
|
631
635
|
* });
|
|
632
636
|
* ```
|
|
633
637
|
*/
|
|
@@ -640,17 +644,25 @@ async function getCompleteIPLocation(config) {
|
|
|
640
644
|
const baseUrl = config?.baseUrl || 'https://ipwho.is';
|
|
641
645
|
const timeout = config?.timeout || 5000;
|
|
642
646
|
const apiKey = config?.apiKey;
|
|
647
|
+
const configIp = config?.ip?.trim();
|
|
643
648
|
try {
|
|
644
|
-
// Build URL
|
|
649
|
+
// Build URL: baseUrl/{IP}?key=API_KEY when IP provided (paid/server-side); else baseUrl/ or baseUrl?key=...
|
|
645
650
|
let url = baseUrl.endsWith('/') ? baseUrl.slice(0, -1) : baseUrl;
|
|
646
|
-
|
|
647
|
-
|
|
648
|
-
url +=
|
|
651
|
+
if (configIp) {
|
|
652
|
+
// Paid / server-side: lookup specific IP. Format: https://ipwhois.pro/{IP}?key=YOUR_API_KEY
|
|
653
|
+
url += `/${encodeURIComponent(configIp)}`;
|
|
654
|
+
if (apiKey) {
|
|
655
|
+
url += `?key=${encodeURIComponent(apiKey)}`;
|
|
656
|
+
}
|
|
649
657
|
}
|
|
650
658
|
else {
|
|
659
|
+
// Auto-detect requestor IP (root path + optional key)
|
|
651
660
|
url += '/';
|
|
661
|
+
if (apiKey) {
|
|
662
|
+
url += `?key=${encodeURIComponent(apiKey)}`;
|
|
663
|
+
}
|
|
652
664
|
}
|
|
653
|
-
// Call
|
|
665
|
+
// Call API: with IP path it returns that IP's location; without path it returns requestor's IP
|
|
654
666
|
// This is the HIGH PRIORITY source - gets IP, location, connection, timezone, flag, etc. in one call
|
|
655
667
|
const response = await fetch(url, {
|
|
656
668
|
method: 'GET',
|
|
@@ -730,6 +742,10 @@ async function getCompleteIPLocation(config) {
|
|
|
730
742
|
* ```
|
|
731
743
|
*/
|
|
732
744
|
async function getPublicIP(config) {
|
|
745
|
+
// When consumer provides IP (paid/server-side), return it without fetching
|
|
746
|
+
if (config?.ip?.trim()) {
|
|
747
|
+
return config.ip.trim();
|
|
748
|
+
}
|
|
733
749
|
// Try to get complete location first (includes IP)
|
|
734
750
|
const completeLocation = await getCompleteIPLocation(config);
|
|
735
751
|
if (completeLocation?.ip) {
|
|
@@ -740,7 +756,7 @@ async function getPublicIP(config) {
|
|
|
740
756
|
const baseUrl = config?.baseUrl || 'https://ipwho.is';
|
|
741
757
|
const timeout = config?.timeout || 5000;
|
|
742
758
|
const apiKey = config?.apiKey;
|
|
743
|
-
// Build URL with optional API key
|
|
759
|
+
// Build URL with optional API key (auto-detect requestor IP)
|
|
744
760
|
let url = baseUrl.endsWith('/') ? baseUrl.slice(0, -1) : baseUrl;
|
|
745
761
|
if (apiKey) {
|
|
746
762
|
url += `?key=${encodeURIComponent(apiKey)}`;
|
|
@@ -787,8 +803,12 @@ async function getPublicIP(config) {
|
|
|
787
803
|
* const location = await getIPLocation('203.0.113.42');
|
|
788
804
|
*
|
|
789
805
|
* // With API key
|
|
806
|
+
* const location = await getIPLocation('203.0.113.42', { apiKey: '<key>' });
|
|
807
|
+
*
|
|
808
|
+
* // Paid ipwhois.pro: same URL format baseUrl/{IP}?key=API_KEY
|
|
790
809
|
* const location = await getIPLocation('203.0.113.42', {
|
|
791
|
-
*
|
|
810
|
+
* baseUrl: 'https://ipwhois.pro',
|
|
811
|
+
* apiKey: '<key>',
|
|
792
812
|
* });
|
|
793
813
|
* ```
|
|
794
814
|
*
|
|
@@ -812,14 +832,13 @@ async function getIPLocation(ip, config) {
|
|
|
812
832
|
const baseUrl = config?.baseUrl || 'https://ipwho.is';
|
|
813
833
|
const timeout = config?.timeout || 5000;
|
|
814
834
|
const apiKey = config?.apiKey;
|
|
815
|
-
// Build URL
|
|
835
|
+
// Build URL: baseUrl/{IP}?key=API_KEY (same format as ipwhois.pro paid: https://ipwhois.pro/{IP}?key=YOUR_API_KEY)
|
|
816
836
|
let url = baseUrl.endsWith('/') ? baseUrl.slice(0, -1) : baseUrl;
|
|
817
|
-
url += `/${ip}`;
|
|
818
|
-
// Add API key as query parameter if provided
|
|
837
|
+
url += `/${encodeURIComponent(ip)}`;
|
|
819
838
|
if (apiKey) {
|
|
820
839
|
url += `?key=${encodeURIComponent(apiKey)}`;
|
|
821
840
|
}
|
|
822
|
-
// Using ipwho.is API
|
|
841
|
+
// Using ipwho.is / ipwhois.pro API
|
|
823
842
|
const response = await fetch(url, {
|
|
824
843
|
method: 'GET',
|
|
825
844
|
headers: {
|