unshared-frontend-sdk 2.3.0 → 3.0.0-rc.14
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 +56 -35
- package/dist/browser.d.ts +43 -37
- package/dist/fingerprint-agent.d.ts +3 -2
- package/dist/index.cjs +1 -1
- package/dist/index.d.ts +1 -0
- package/dist/index.mjs +1 -1
- package/dist/index.umd.js +1 -1
- package/dist/shared-types.d.ts +148 -0
- package/package.json +3 -3
package/README.md
CHANGED
|
@@ -20,7 +20,7 @@ await client.init({
|
|
|
20
20
|
const { data } = await client.checkUser();
|
|
21
21
|
if (data?.is_user_flagged) {
|
|
22
22
|
await client.triggerEmailVerification(); // emails a 6-digit code
|
|
23
|
-
const result = await client.verify(codeFromUser); //
|
|
23
|
+
const result = await client.verify(codeFromUser); // -> { verified: true }
|
|
24
24
|
}
|
|
25
25
|
```
|
|
26
26
|
|
|
@@ -34,6 +34,12 @@ Direct-mode reads are protected server-side: the publishable key only answers fo
|
|
|
34
34
|
npm install unshared-frontend-sdk
|
|
35
35
|
```
|
|
36
36
|
|
|
37
|
+
The bundled fallback uses exact public npm dependency `unshared-fingerprint-lib@1.5.2`
|
|
38
|
+
(Node >=18.20 for installation/tooling). No vendored tarball is required. S3-first
|
|
39
|
+
loading remains the default. Version 1.5.2 filters components only in the library's
|
|
40
|
+
own `sendFingerprint` reporter; this SDK preserves complete raw collection results
|
|
41
|
+
and applies its existing payload-size policy instead.
|
|
42
|
+
|
|
37
43
|
Or via CDN (no build step) — see [CDN / UMD usage](#cdn--umd-usage) below for the complete example.
|
|
38
44
|
|
|
39
45
|
---
|
|
@@ -54,7 +60,7 @@ const fingerprint = await client.collect();
|
|
|
54
60
|
client.submitFingerprintEvent(fingerprint, { userId: currentUser?.id });
|
|
55
61
|
```
|
|
56
62
|
|
|
57
|
-
That's it. The SDK handles
|
|
63
|
+
That's it. The SDK handles timeouts and errors without throwing. Read-only calls may retry; Trigger and Verify never retry.
|
|
58
64
|
|
|
59
65
|
> **Using this SDK alongside the Node `unsharedBoundToUser` middleware (Tier 1)?** The middleware
|
|
60
66
|
> also auto-injects an inline fingerprint script into your HTML. That is expected — the two
|
|
@@ -79,7 +85,7 @@ new UnsharedBrowser({
|
|
|
79
85
|
| `baseUrl` | `string` | `undefined` | Proxy mode: base URL of your backend. Use `""` when your frontend and backend share the same domain. Omitting both `baseUrl` and `publishableKey` defaults to same-origin proxy mode (unless a key was baked into a client-specific build — see below). |
|
|
80
86
|
| `publishableKey` | `string` | — | Direct mode: publishable key (`upk_…`) issued by Unshared Labs. When set, events bypass your backend and go straight to the platform. |
|
|
81
87
|
| `apiUrl` | `string` | `https://api.unshared.ai` | Direct mode: Unshared Labs platform origin. |
|
|
82
|
-
| `maxRetries` | `number` | `3` |
|
|
88
|
+
| `maxRetries` | `number` | `3` | Retry budget for eligible operations |
|
|
83
89
|
| `timeout` | `number` | `30000` | Per-attempt timeout in milliseconds |
|
|
84
90
|
| `enableInterstitial` | `boolean` | `false` | Auto-render the interstitial modal when the user is flagged (via the `unshared:flagged` event); works in direct or proxy mode. See [Interstitial modal](#interstitial-modal). |
|
|
85
91
|
| `interstitialFlowType` | `string` | `email_verification` | Flow type requested for the auto-shown interstitial. |
|
|
@@ -125,6 +131,14 @@ Collect a browser fingerprint. Returns a `FingerprintWireFormat` object ready to
|
|
|
125
131
|
const fingerprint = await client.collect();
|
|
126
132
|
```
|
|
127
133
|
|
|
134
|
+
### `collectRaw()`
|
|
135
|
+
|
|
136
|
+
Collect the fingerprint library's complete JSON object without reducing it to the compatibility wire type.
|
|
137
|
+
|
|
138
|
+
```typescript
|
|
139
|
+
const rawFingerprint = await client.collectRaw();
|
|
140
|
+
```
|
|
141
|
+
|
|
128
142
|
---
|
|
129
143
|
|
|
130
144
|
### `submitFingerprintEvent(fingerprint, opts?)`
|
|
@@ -154,17 +168,50 @@ if (!result.success) {
|
|
|
154
168
|
|
|
155
169
|
---
|
|
156
170
|
|
|
171
|
+
### `submitFingerprint(payload)`
|
|
172
|
+
|
|
173
|
+
Submit any JSON object without reshaping or filtering unknown fields. Direct mode encrypts the complete object with the publishable key; proxy mode keeps the browser-to-customer hop plaintext so middleware can add trusted context before encrypting the final request to Unshared.
|
|
174
|
+
|
|
175
|
+
```typescript
|
|
176
|
+
await client.submitFingerprint({
|
|
177
|
+
fingerprint: await client.collectRaw(),
|
|
178
|
+
context: {
|
|
179
|
+
identity: { user_id: currentUser?.id },
|
|
180
|
+
event: { type: location.pathname + location.search },
|
|
181
|
+
},
|
|
182
|
+
});
|
|
183
|
+
```
|
|
184
|
+
|
|
185
|
+
The payload must be a non-null JSON object; arrays and primitives fail locally with `VALIDATION_ERROR`. Direct requests larger than 1 MiB fail locally with `REQUEST_TOO_LARGE`. Direct ingestion succeeds only on a strict `202` v3 acknowledgement.
|
|
186
|
+
|
|
187
|
+
Proxy submissions have a fixed **100 KiB (102,400 serialized UTF-8 bytes)** limit,
|
|
188
|
+
compatible with an upstream default `express.json()` without configuration or
|
|
189
|
+
middleware reordering. Structured submissions send the full snapshot if it fits;
|
|
190
|
+
otherwise they empty local/session storage lists while retaining all cookies, then
|
|
191
|
+
omit `context.browser_storage` if still too large. The complete raw fingerprint,
|
|
192
|
+
including future fields, and core identity/device/session/SDK/event metadata are
|
|
193
|
+
never trimmed. Oversized core payloads return `REQUEST_TOO_LARGE` without sending;
|
|
194
|
+
the inline submitter logs that code. Low-level `submitFingerprint(payload)` never
|
|
195
|
+
reduces arbitrary caller objects: it sends them exactly or rejects above 100 KiB.
|
|
196
|
+
Direct mode keeps full snapshots and its existing 1 MiB logical / 1.5 MiB encrypted
|
|
197
|
+
limits. Duplicate fingerprint caches and legacy queues are excluded from snapshots.
|
|
198
|
+
|
|
199
|
+
---
|
|
200
|
+
|
|
157
201
|
### Direct-mode API (requires `publishableKey`)
|
|
158
202
|
|
|
159
203
|
All four methods default to the identity captured by `init()` (email + stable fingerprint hash as deviceId); pass `{ email, deviceId }` to override. In proxy mode they return `error.code === 'DIRECT_MODE_REQUIRED'` — proxy-mode apps get these flows from their own backend middleware.
|
|
160
204
|
|
|
161
205
|
| Method | Retries | Returns |
|
|
162
206
|
|--------|---------|---------|
|
|
163
|
-
| `checkUser(opts?)` |
|
|
164
|
-
| `triggerEmailVerification(opts?)` | **never** (each call emails a code) | `{ next_allowed_at, retry_after_seconds }`;
|
|
165
|
-
| `verify(code, opts?)` | **never** (attempts are budgeted) |
|
|
207
|
+
| `checkUser(opts?)` | bounded availability failures only | `{ is_user_flagged, decision_id, decision_code }` |
|
|
208
|
+
| `triggerEmailVerification(opts?)` | **never** (each call emails a code) | `{ verification_id, next_allowed_at, retry_after_seconds }`; the SDK retains the challenge for `verify(...)` |
|
|
209
|
+
| `verify(code, opts?)` | **never** (attempts are budgeted) | Exact verified/not-verified result; UUIDv4 challenges and 6-digit OTPs are validated locally |
|
|
210
|
+
| `verifyEmail({ verification_id, code })` | **never** | Verification for an explicit challenge ID; reconciles flagged state when retained identity is available |
|
|
166
211
|
| `emailVerificationStatus(opts?)` | yes | `{ can_send: boolean, next_allowed_at }` |
|
|
167
212
|
|
|
213
|
+
V3 methods require exact success/error envelopes and endpoint-specific status/result shapes. After `verified: true`, the SDK performs one no-retry `checkUser` reconciliation; sticky flagged state is cleared only by a strict available unflagged decision, never by Verify alone or `CHECK_UNAVAILABLE`.
|
|
214
|
+
|
|
168
215
|
---
|
|
169
216
|
|
|
170
217
|
## Interstitial modal
|
|
@@ -248,7 +295,7 @@ const result = await client.submitFingerprintEvent(fingerprint);
|
|
|
248
295
|
// result.error.code === 'DELIVERY_FAILED'
|
|
249
296
|
```
|
|
250
297
|
|
|
251
|
-
|
|
298
|
+
Read-only direct calls retry eligible network and 5xx failures. Fingerprint ingestion, Trigger, and Verify are never retried because an ambiguous request may already have committed. Failed ingestion is not queued for replay.
|
|
252
299
|
|
|
253
300
|
---
|
|
254
301
|
|
|
@@ -257,7 +304,7 @@ Retries happen automatically on network errors, timeouts, and server errors (5xx
|
|
|
257
304
|
The UMD bundle exposes a `window.UnsharedBrowser` namespace object. Destructure the class from it first. If the bundle was built with `UNSHARED_PUBLISHABLE_API_KEY`, the client does not pass a key:
|
|
258
305
|
|
|
259
306
|
```html
|
|
260
|
-
<script src="https://unpkg.com/unshared-frontend-sdk@
|
|
307
|
+
<script src="https://unpkg.com/unshared-frontend-sdk@3.0.0/dist/index.umd.js"></script>
|
|
261
308
|
<script>
|
|
262
309
|
const { UnsharedBrowser } = window.UnsharedBrowser;
|
|
263
310
|
|
|
@@ -276,29 +323,6 @@ For proxy mode instead, pass `baseUrl` explicitly.
|
|
|
276
323
|
|
|
277
324
|
---
|
|
278
325
|
|
|
279
|
-
## Local retry queue encryption
|
|
280
|
-
|
|
281
|
-
When a fingerprint event still fails after all retry attempts, the browser SDK stores it in `localStorage` under `__unshared_event_queue` and retries it before the next regular fingerprint submission. Queue records are encrypted before storage so the event payload is not directly readable from browser devtools.
|
|
282
|
-
|
|
283
|
-
Encryption details:
|
|
284
|
-
|
|
285
|
-
- Algorithm: AES-GCM.
|
|
286
|
-
- IV: random 12-byte IV per queued event.
|
|
287
|
-
- Stored format: `v1:<base64 iv>:<base64 ciphertext>`.
|
|
288
|
-
- Queue key derivation:
|
|
289
|
-
|
|
290
|
-
```text
|
|
291
|
-
SHA-256("unshared-browser-queue:" + (publishableKey || baseUrl) + ":" + sessionId)
|
|
292
|
-
```
|
|
293
|
-
|
|
294
|
-
That SHA-256 digest is imported as the AES-GCM key through Web Crypto. The SDK does **not** use `API_KEY_ENCRYPTION_SECRET`; that kind of secret must stay server-side and must not be shipped in browser code.
|
|
295
|
-
|
|
296
|
-
This is intentionally best-effort local confidentiality, not a strong security boundary. In direct mode, the publishable key is public, and the session ID is browser-local state. That means the queue encryption protects against casual plaintext inspection of `localStorage`, but it does not protect against a user who can run JavaScript in their own browser context or inspect the loaded SDK. The browser SDK therefore treats queue encryption as obfuscation plus integrity protection for local retry data, not as secret storage.
|
|
297
|
-
|
|
298
|
-
Using the publishable key in this derivation is acceptable for this limited purpose because no server secret is available in the browser. It should not be described as making local data unrecoverable from the end user. If stronger browser-local protection is required, the SDK would need a different design, such as server-held queued events, short-lived server-issued wrapping keys, or platform storage that never exposes plaintext to arbitrary page JavaScript.
|
|
299
|
-
|
|
300
|
-
---
|
|
301
|
-
|
|
302
326
|
## Real-browser acceptance coverage
|
|
303
327
|
|
|
304
328
|
For Boston Globe style script-tag integration, split client-side browser tests into host-site flows and SDK-owned delivery behavior.
|
|
@@ -313,7 +337,4 @@ For Boston Globe style script-tag integration, split client-side browser tests i
|
|
|
313
337
|
| Password reset completion failures | Wrong current password; mismatched new-password entries; password-rule failures; missing required values. | Host-site auth behavior. Test in the client's browser suite. |
|
|
314
338
|
| Page navigation | Full page loads with script tag; link clicks; forward/back; refresh with same script tag injected. | SDK supports script-tag load, `init`, MPA `DOMContentLoaded`, and SPA route-change submission. Real-browser tests should assert the UMD bundle loads and the client page still renders. |
|
|
315
339
|
| Event firing | Event fires where applicable after user identity is present. | Implemented by `init`, `onRouteChange`, MPA listener, and direct/proxy submit endpoints. Covered by unit tests; should also be verified in real browser against mocked or test backend responses. |
|
|
316
|
-
| Retry |
|
|
317
|
-
| Encrypted local queue | After retry exhaustion, failed events are stored in local cache and are not directly readable as plaintext. | Implemented with AES-GCM encrypted `localStorage` queue and unit-tested. |
|
|
318
|
-
| Local queue storage failure | Storage unavailable, quota exceeded, or crypto unavailable. | Implemented as never-throw best effort; event returns delivery failure and storage failure is swallowed. Unit-tested for storage failure. |
|
|
319
|
-
| Queue flush | Stored events transmit on the next regular event opportunity. | Implemented by flushing the encrypted queue before the next fingerprint submission. Unit-tested. |
|
|
340
|
+
| Retry | Read-only checks may retry; ingestion, Trigger, and Verify make one attempt and are never queued. | Implemented and unit-tested. |
|
package/dist/browser.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { FingerprintWireFormat } from '
|
|
1
|
+
import type { CheckUserResult, FingerprintWireFormat, IngestResult, JSONObject, VerifyEmailRequest, VerifyEmailResult } from './shared-types';
|
|
2
2
|
export interface BrowserConfig {
|
|
3
3
|
/**
|
|
4
4
|
* Base URL of the customer's own backend.
|
|
@@ -78,11 +78,15 @@ export interface InitOptions {
|
|
|
78
78
|
export interface SubmitFingerprintOptions {
|
|
79
79
|
userId: string;
|
|
80
80
|
eventType?: string;
|
|
81
|
+
permanentDeviceId?: string;
|
|
81
82
|
}
|
|
82
83
|
export interface SubmitFingerprintResult {
|
|
83
84
|
hash: string;
|
|
84
85
|
stable_hash: string;
|
|
85
86
|
collected_at: string;
|
|
87
|
+
version: string;
|
|
88
|
+
event_id?: string;
|
|
89
|
+
endpoint_version?: 'v3';
|
|
86
90
|
}
|
|
87
91
|
export interface BrowserApiResult<T = unknown> {
|
|
88
92
|
success: boolean;
|
|
@@ -101,18 +105,22 @@ export interface BrowserApiResult<T = unknown> {
|
|
|
101
105
|
export interface DirectIdentityOptions {
|
|
102
106
|
email?: string;
|
|
103
107
|
deviceId?: string;
|
|
108
|
+
permanentDeviceId?: string;
|
|
109
|
+
stableHash?: string;
|
|
110
|
+
fullHash?: string;
|
|
104
111
|
}
|
|
105
|
-
export interface CheckUserData {
|
|
106
|
-
is_user_flagged: boolean;
|
|
112
|
+
export interface CheckUserData extends CheckUserResult {
|
|
107
113
|
}
|
|
108
114
|
export interface TriggerVerificationData {
|
|
109
115
|
message?: string;
|
|
116
|
+
verification_id?: string;
|
|
110
117
|
next_allowed_at?: string;
|
|
111
118
|
retry_after_seconds?: number;
|
|
112
119
|
}
|
|
113
120
|
export interface VerifyData {
|
|
114
121
|
verified: boolean;
|
|
115
122
|
reason?: string;
|
|
123
|
+
verification_scope?: 'email';
|
|
116
124
|
}
|
|
117
125
|
export interface VerificationStatusData {
|
|
118
126
|
can_send: boolean;
|
|
@@ -121,6 +129,11 @@ export interface VerificationStatusData {
|
|
|
121
129
|
export interface FlaggedInterceptorOptions {
|
|
122
130
|
onFlagged: () => void;
|
|
123
131
|
}
|
|
132
|
+
interface CollectedFingerprint {
|
|
133
|
+
raw: JSONObject;
|
|
134
|
+
wire: FingerprintWireFormat;
|
|
135
|
+
source: 'remote' | 'bundled';
|
|
136
|
+
}
|
|
124
137
|
/**
|
|
125
138
|
* Browser SDK for Unshared Labs.
|
|
126
139
|
*
|
|
@@ -153,12 +166,12 @@ export declare class UnsharedBrowser {
|
|
|
153
166
|
private readonly _resolveDeviceId?;
|
|
154
167
|
private _sessionId;
|
|
155
168
|
private _deviceId;
|
|
169
|
+
private _permanentDeviceId;
|
|
156
170
|
private _userId;
|
|
157
171
|
private _emailAddress;
|
|
158
172
|
/** True after init() with isPaidSubscriber:false — blocks every submission path. */
|
|
159
173
|
private _doNotCollect;
|
|
160
174
|
private _mpaHandler;
|
|
161
|
-
private _flushingQueue;
|
|
162
175
|
/** Interstitial auto-show config + live state. */
|
|
163
176
|
private readonly _enableInterstitial;
|
|
164
177
|
private readonly _interstitialFlowType;
|
|
@@ -211,17 +224,32 @@ export declare class UnsharedBrowser {
|
|
|
211
224
|
*/
|
|
212
225
|
collect(options?: {
|
|
213
226
|
exclude?: string[];
|
|
227
|
+
[key: string]: unknown;
|
|
214
228
|
}): Promise<FingerprintWireFormat>;
|
|
229
|
+
/** Returns the fingerprint agent's JSON object without selecting or renaming fields. */
|
|
230
|
+
collectRaw(options?: {
|
|
231
|
+
exclude?: string[];
|
|
232
|
+
[key: string]: unknown;
|
|
233
|
+
}): Promise<JSONObject>;
|
|
234
|
+
/** Collect once, keeping the agent's raw object separate from normalized SDK metadata. */
|
|
235
|
+
collectWithMetadata(options?: {
|
|
236
|
+
exclude?: string[];
|
|
237
|
+
[key: string]: unknown;
|
|
238
|
+
}): Promise<CollectedFingerprint>;
|
|
239
|
+
private _collectFingerprint;
|
|
215
240
|
/**
|
|
216
241
|
* Submit a fingerprint event directly.
|
|
217
242
|
* @deprecated Prefer sdk.init() and sdk.onRouteChange().
|
|
218
243
|
*/
|
|
219
244
|
submitFingerprintEvent(fingerprint: FingerprintWireFormat, opts: SubmitFingerprintOptions): Promise<BrowserApiResult<SubmitFingerprintResult>>;
|
|
245
|
+
/** Submit any JSON object to the v3 fingerprint endpoint without changing it. */
|
|
246
|
+
submitFingerprint(payload: JSONObject): Promise<BrowserApiResult<IngestResult>>;
|
|
220
247
|
/**
|
|
221
248
|
* Check whether the current user is flagged for account sharing.
|
|
222
249
|
* Direct mode only — proxy-mode apps get verdicts from their own backend.
|
|
223
250
|
*/
|
|
224
251
|
checkUser(opts?: DirectIdentityOptions): Promise<BrowserApiResult<CheckUserData>>;
|
|
252
|
+
private _checkUser;
|
|
225
253
|
/**
|
|
226
254
|
* Send a 6-digit verification code to the user's email.
|
|
227
255
|
* Never retried — each attempt sends a real email. Rate-limited responses
|
|
@@ -233,6 +261,8 @@ export declare class UnsharedBrowser {
|
|
|
233
261
|
* budgeted server-side to block brute force.
|
|
234
262
|
*/
|
|
235
263
|
verify(code: string, opts?: DirectIdentityOptions): Promise<BrowserApiResult<VerifyData>>;
|
|
264
|
+
verifyEmail(request: VerifyEmailRequest): Promise<BrowserApiResult<VerifyEmailResult>>;
|
|
265
|
+
private _verifyEmail;
|
|
236
266
|
/** Report the email-send cooldown state without sending anything. */
|
|
237
267
|
emailVerificationStatus(opts?: DirectIdentityOptions): Promise<BrowserApiResult<VerificationStatusData>>;
|
|
238
268
|
/**
|
|
@@ -268,7 +298,11 @@ export declare class UnsharedBrowser {
|
|
|
268
298
|
private _directApi;
|
|
269
299
|
private _getStoredEmail;
|
|
270
300
|
private _getCachedFingerprint;
|
|
301
|
+
private _getCachedRawFingerprint;
|
|
271
302
|
private _cacheFingerprint;
|
|
303
|
+
private _cacheRawFingerprint;
|
|
304
|
+
private _storedVerificationId;
|
|
305
|
+
private _storedVerificationIdentity;
|
|
272
306
|
private _shouldProcessPath;
|
|
273
307
|
private _submitEvent;
|
|
274
308
|
/**
|
|
@@ -278,39 +312,10 @@ export declare class UnsharedBrowser {
|
|
|
278
312
|
private _submitUrl;
|
|
279
313
|
private _attachMpaListener;
|
|
280
314
|
private _sendWithRetry;
|
|
281
|
-
private
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
private
|
|
285
|
-
/**
|
|
286
|
-
* Encrypt a PII field (user_id, email_address) for direct-mode requests:
|
|
287
|
-
* AES-256-GCM keyed by SHA-256(publishable key), emitted as
|
|
288
|
-
* `base64(iv):base64(authTag):base64(ciphertext)` — byte-compatible with the
|
|
289
|
-
* Node SDK's encryptData, so the platform's existing ciphertext detection and
|
|
290
|
-
* decryption handle it unchanged. Returns the plaintext when WebCrypto is
|
|
291
|
-
* unavailable or fails: the ingress accepts both and always (re-)encrypts PII
|
|
292
|
-
* with the company secret key before anything is stored.
|
|
293
|
-
*/
|
|
294
|
-
private _encryptPII;
|
|
295
|
-
private _queueKey;
|
|
296
|
-
private _encryptQueuedDelivery;
|
|
297
|
-
private _decryptQueuedDelivery;
|
|
298
|
-
private _readQueueRecords;
|
|
299
|
-
private _writeQueueRecords;
|
|
300
|
-
private _queueFailedDelivery;
|
|
301
|
-
/**
|
|
302
|
-
* Recover a batch orphaned by a crashed/killed tab mid-flush. A flush claims
|
|
303
|
-
* its batch by leasing it here BEFORE clearing the main queue (see
|
|
304
|
-
* _flushQueuedEvents); if the process dies before the `finally` that removes
|
|
305
|
-
* the lease runs, the claimed records would otherwise be lost forever. A
|
|
306
|
-
* STALE lease (older than INFLIGHT_LEASE_MS) is presumed orphaned and merged
|
|
307
|
-
* back into the main queue. A FRESH lease means another tab is genuinely
|
|
308
|
-
* mid-flight — leave it untouched, or this would recreate the double-send
|
|
309
|
-
* that the claim-then-clear scheme exists to prevent.
|
|
310
|
-
*/
|
|
311
|
-
private _recoverStaleInflightLease;
|
|
312
|
-
private _flushQueuedEvents;
|
|
313
|
-
private _buildBody;
|
|
315
|
+
private _buildIdentifiers;
|
|
316
|
+
private _buildEventPayload;
|
|
317
|
+
private _ensurePermanentDeviceId;
|
|
318
|
+
private _isSameOriginProxy;
|
|
314
319
|
}
|
|
315
320
|
/**
|
|
316
321
|
* Creates an Axios response error interceptor that calls onFlagged
|
|
@@ -338,3 +343,4 @@ export declare function createAxiosInterceptor(opts: FlaggedInterceptorOptions):
|
|
|
338
343
|
* ```
|
|
339
344
|
*/
|
|
340
345
|
export declare function createFetchInterceptor(originalFetch: typeof fetch, opts: FlaggedInterceptorOptions): typeof fetch;
|
|
346
|
+
export {};
|
|
@@ -1,5 +1,6 @@
|
|
|
1
|
-
import type { FingerprintConfig
|
|
2
|
-
|
|
1
|
+
import type { FingerprintConfig } from 'unshared-fingerprint-lib';
|
|
2
|
+
import type { JSONObject } from './shared-types';
|
|
3
|
+
export type GetFingerprint = (config?: FingerprintConfig) => Promise<JSONObject>;
|
|
3
4
|
export interface ResolvedAgent {
|
|
4
5
|
getFingerprint: GetFingerprint;
|
|
5
6
|
source: 'remote' | 'bundled';
|