rn-prodeeplinks 0.0.1 → 0.0.2

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
@@ -130,6 +130,41 @@ const deepLink = new ProDeepLink({
130
130
  const result = await deepLink.getDeepLinkUrl();
131
131
  ```
132
132
 
133
+ ### Analytics & Tracking
134
+
135
+ This SDK can optionally send deep link analytics events to our tracking service.
136
+
137
+ - When a deep link is opened via React Native `Linking.getInitialURL()`, the SDK:
138
+ - Resolves the URL
139
+ - Collects device fingerprint data
140
+ - Sends an internal tracking event named `pro_track` with the resolved short URL and fingerprint
141
+ - When a deep link is resolved via the fingerprint API, the SDK:
142
+ - Resolves the URL from the server
143
+ - Sends the same `pro_track` event with the short URL and fingerprint
144
+
145
+ You can also send custom tracking events manually:
146
+
147
+ ```typescript
148
+ import {
149
+ trackAnalyticsEvent,
150
+ CustomDeepLinkAnalyticsEvent,
151
+ } from 'rn-prodeeplinks';
152
+
153
+ const event: CustomDeepLinkAnalyticsEvent = {
154
+ licenseKey: 'your-license-key',
155
+ eventType: 'deeplink',
156
+ eventName: 'pro_track',
157
+ category: 'custom',
158
+ action: 'open',
159
+ label: 'My custom event',
160
+ properties: {
161
+ shortUrl: 'https://your-short-url',
162
+ },
163
+ };
164
+
165
+ await trackAnalyticsEvent(event);
166
+ ```
167
+
133
168
  ## API Reference
134
169
 
135
170
  ### Functions
@@ -234,24 +269,16 @@ License keys are **NOT FREE**. You must:
234
269
  - Invalid or expired license keys will result in API errors
235
270
  - License keys cannot be shared or reused without authorization
236
271
 
237
- ### Custom License Validate API (Optional)
238
- For environments with a custom auth API, the license validate endpoint is:
239
-
240
- POST {{base_url}}{{api_prefix}}/custom-deep-link/license/validate
272
+ ### Custom License Validation (Optional)
241
273
 
242
- Example (Postman):
274
+ In most cases you should rely on the built‑in license validation handled by this SDK.
275
+ If you have your own backend that integrates with our license service, you can:
243
276
 
244
- ```
245
- POST '{{base_url}}{{api_prefix}}/custom-deep-link/license/validate'
246
- --header 'Content-Type: application/json'
247
- --body '{
248
- "licenseKey": "{{license_key}}",
249
- "domain": "acme.com",
250
- "ipAddress": "103.21.149.10"
251
- }'
252
- ```
277
+ - Call your backend from your app
278
+ - Let your backend talk to our license service
279
+ - Use the result in your own business logic
253
280
 
254
- This package exposes a helper to call this endpoint if needed. It does not interfere with the main deep link resolution flow.
281
+ The exact backend endpoint and payload are specific to your environment and are intentionally not exposed in this README.
255
282
 
256
283
  ## Error Handling
257
284
 
package/lib/api.d.ts CHANGED
@@ -20,5 +20,5 @@ export declare function validateLicenseInit(licenseKey: string): Promise<{
20
20
  status?: number;
21
21
  data?: LicenseValidationApiResponse;
22
22
  }>;
23
- export declare function matchFingerprintCustom(payload: FingerprintMatchPayload, baseUrl?: string): Promise<FingerprintMatchResponse>;
24
- export declare function trackCustomDeepLinkEvent(event: CustomDeepLinkAnalyticsEvent): Promise<any>;
23
+ export declare function matchFingerprintCustom(payload: FingerprintMatchPayload, baseUrl?: string, licenseKey?: string): Promise<FingerprintMatchResponse>;
24
+ export declare function trackCustomDeepLinkEvent(event: CustomDeepLinkAnalyticsEvent, licenseKey?: string): Promise<any>;
package/lib/api.js CHANGED
@@ -26,7 +26,7 @@ async function fetchDeepLinkUrl(licenseKey, fingerprint, apiEndpoint, timeout =
26
26
  };
27
27
  }
28
28
  const PACKAGE_NAME = 'react-native-pro-deeplink';
29
- const PACKAGE_VERSION = '0.0.1';
29
+ const PACKAGE_VERSION = '0.0.2';
30
30
  const payload = {
31
31
  licenseKey,
32
32
  fingerprint: fingerprint,
@@ -39,13 +39,14 @@ async function fetchDeepLinkUrl(licenseKey, fingerprint, apiEndpoint, timeout =
39
39
  const timeoutId = setTimeout(() => controller.abort(), timeout);
40
40
  try {
41
41
  const PACKAGE_NAME = 'react-native-pro-deeplink';
42
- const PACKAGE_VERSION = '0.0.1';
42
+ const PACKAGE_VERSION = '0.0.2';
43
43
  const response = await fetch(endpoint, {
44
44
  method: 'POST',
45
45
  headers: {
46
46
  'Content-Type': 'application/json',
47
47
  'X-Package-Name': PACKAGE_NAME,
48
48
  'X-Package-Version': PACKAGE_VERSION,
49
+ 'x-license-key': licenseKey,
49
50
  },
50
51
  body: JSON.stringify(payload),
51
52
  signal: controller.signal,
@@ -129,7 +130,10 @@ async function validateLicenseCustom(licenseKey, opts) {
129
130
  };
130
131
  const res = await fetch(endpoint, {
131
132
  method: 'POST',
132
- headers: { 'Content-Type': 'application/json' },
133
+ headers: {
134
+ 'Content-Type': 'application/json',
135
+ 'x-license-key': licenseKey,
136
+ },
133
137
  body: JSON.stringify(body),
134
138
  });
135
139
  const json = (await res.json().catch(() => ({})));
@@ -168,7 +172,7 @@ async function validateLicenseInit(licenseKey) {
168
172
  };
169
173
  }
170
174
  }
171
- async function matchFingerprintCustom(payload, baseUrl) {
175
+ async function matchFingerprintCustom(payload, baseUrl, licenseKey) {
172
176
  try {
173
177
  const base = (baseUrl || CUSTOM_API_BASE_URL).trim().replace(/\/+$/, '');
174
178
  const endpoint = `${base}/custom-deep-link/fingerprint/match`;
@@ -176,6 +180,7 @@ async function matchFingerprintCustom(payload, baseUrl) {
176
180
  method: 'POST',
177
181
  headers: {
178
182
  'Content-Type': 'application/json',
183
+ ...(licenseKey ? { 'x-license-key': licenseKey } : {}),
179
184
  },
180
185
  body: JSON.stringify(payload),
181
186
  });
@@ -190,12 +195,13 @@ async function matchFingerprintCustom(payload, baseUrl) {
190
195
  };
191
196
  }
192
197
  }
193
- async function trackCustomDeepLinkEvent(event) {
198
+ async function trackCustomDeepLinkEvent(event, licenseKey) {
194
199
  try {
195
200
  const res = await fetch(ANALYTICS_ENDPOINT, {
196
201
  method: 'POST',
197
202
  headers: {
198
203
  'Content-Type': 'application/json',
204
+ ...(licenseKey ? { 'x-license-key': licenseKey } : {}),
199
205
  },
200
206
  body: JSON.stringify(event),
201
207
  });
package/lib/index.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- import { InitConfig, DeepLinkResponse } from './types';
1
+ import { InitConfig, DeepLinkResponse, CustomDeepLinkAnalyticsEvent } from './types';
2
2
  /**
3
3
  * Initialize the deep link package with license key
4
4
  * This must be called before using getDeepLink()
@@ -53,7 +53,8 @@ export declare function isReady(): boolean;
53
53
  * Useful for testing or logout scenarios
54
54
  */
55
55
  export declare function reset(): void;
56
- export type { InitConfig, DeepLinkResponse } from './types';
56
+ export declare function trackAnalyticsEvent(event: CustomDeepLinkAnalyticsEvent): Promise<any>;
57
+ export type { InitConfig, DeepLinkResponse, CustomDeepLinkAnalyticsEvent } from './types';
57
58
  export declare class ProDeepLink {
58
59
  private licenseKey;
59
60
  constructor(config: InitConfig);
@@ -64,5 +65,6 @@ declare const _default: {
64
65
  getDeepLink: typeof getDeepLink;
65
66
  isReady: typeof isReady;
66
67
  reset: typeof reset;
68
+ trackAnalyticsEvent: typeof trackAnalyticsEvent;
67
69
  };
68
70
  export default _default;
package/lib/index.js CHANGED
@@ -5,6 +5,7 @@ exports.init = init;
5
5
  exports.getDeepLink = getDeepLink;
6
6
  exports.isReady = isReady;
7
7
  exports.reset = reset;
8
+ exports.trackAnalyticsEvent = trackAnalyticsEvent;
8
9
  const fingerprint_1 = require("./fingerprint");
9
10
  const api_1 = require("./api");
10
11
  const license_1 = require("./license");
@@ -60,6 +61,25 @@ async function init(config) {
60
61
  };
61
62
  }
62
63
  }
64
+ async function trackDeepLinkResolved(url, source, fingerprint) {
65
+ const event = {
66
+ eventType: 'deeplink',
67
+ eventName: 'pro_track',
68
+ category: source,
69
+ action: 'open',
70
+ label: url,
71
+ properties: {
72
+ shortUrl: url,
73
+ source,
74
+ fingerprint,
75
+ },
76
+ };
77
+ try {
78
+ await trackAnalyticsEvent(event);
79
+ }
80
+ catch {
81
+ }
82
+ }
63
83
  /**
64
84
  * Get deep link URL from server
65
85
  * This function automatically handles device fingerprinting internally
@@ -95,6 +115,12 @@ async function getDeepLink(callback) {
95
115
  // First: try to read deep link via Linking (if app opened by URL)
96
116
  const initialUrl = await react_native_1.Linking.getInitialURL();
97
117
  if (initialUrl) {
118
+ try {
119
+ const fingerprint = await (0, fingerprint_1.generateDeviceFingerprint)();
120
+ await trackDeepLinkResolved(initialUrl, 'linking', fingerprint);
121
+ }
122
+ catch {
123
+ }
98
124
  if (callback)
99
125
  callback(initialUrl);
100
126
  return { success: true, url: initialUrl };
@@ -104,6 +130,13 @@ async function getDeepLink(callback) {
104
130
  // Fetch deep link URL from API with retry mechanism
105
131
  const result = await (0, api_1.fetchDeepLinkUrlWithRetry)(storedLicenseKey, fingerprint, 3, // retry attempts
106
132
  DEFAULT_API_ENDPOINT);
133
+ if (result.success && result.url) {
134
+ try {
135
+ await trackDeepLinkResolved(result.url, 'api', fingerprint);
136
+ }
137
+ catch {
138
+ }
139
+ }
107
140
  // Call callback if provided and result is successful
108
141
  if (callback && result.success && result.url) {
109
142
  callback(result.url);
@@ -136,6 +169,10 @@ function reset() {
136
169
  storedLicenseKey = null;
137
170
  isInitialized = false;
138
171
  }
172
+ async function trackAnalyticsEvent(event) {
173
+ const licenseKey = storedLicenseKey;
174
+ return (0, api_1.trackCustomDeepLinkEvent)(event, licenseKey || undefined);
175
+ }
139
176
  // Keep backward compatibility - export class for advanced users (optional)
140
177
  class ProDeepLink {
141
178
  constructor(config) {
@@ -154,9 +191,17 @@ class ProDeepLink {
154
191
  };
155
192
  }
156
193
  const fingerprint = await (0, fingerprint_1.generateDeviceFingerprint)();
157
- return await (0, api_1.fetchDeepLinkUrlWithRetry)(this.licenseKey, fingerprint, 3, DEFAULT_API_ENDPOINT);
194
+ const result = await (0, api_1.fetchDeepLinkUrlWithRetry)(this.licenseKey, fingerprint, 3, DEFAULT_API_ENDPOINT);
195
+ if (result.success && result.url) {
196
+ try {
197
+ await trackDeepLinkResolved(result.url, 'api', fingerprint);
198
+ }
199
+ catch {
200
+ }
201
+ }
202
+ return result;
158
203
  }
159
204
  }
160
205
  exports.ProDeepLink = ProDeepLink;
161
206
  // Export default
162
- exports.default = { init, getDeepLink, isReady, reset };
207
+ exports.default = { init, getDeepLink, isReady, reset, trackAnalyticsEvent };
package/lib/types.d.ts CHANGED
@@ -70,7 +70,7 @@ export interface CustomDeepLinkAnalyticsDeviceInfo {
70
70
  [key: string]: any;
71
71
  }
72
72
  export interface CustomDeepLinkAnalyticsEvent {
73
- licenseKey: string;
73
+ licenseKey?: string;
74
74
  eventType: string;
75
75
  eventName: string;
76
76
  category?: string;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "rn-prodeeplinks",
3
- "version": "0.0.1",
3
+ "version": "0.0.2",
4
4
  "description": "Secure deep linking package with license key validation and device fingerprinting for React Native",
5
5
  "main": "lib/index.js",
6
6
  "types": "lib/index.d.ts",