@glideidentity/web-client-sdk 4.4.8-beta.1 → 4.4.8-beta.3

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 (36) hide show
  1. package/dist/adapters/react/usePhoneAuth.d.ts +1 -1
  2. package/dist/adapters/vue/useClient.d.ts +3 -3
  3. package/dist/adapters/vue/usePhoneAuth.d.ts +1 -1
  4. package/dist/browser/web-client-sdk.min.js +1 -1
  5. package/dist/core/phone-auth/api-types.d.ts +112 -27
  6. package/dist/core/phone-auth/client.d.ts +13 -11
  7. package/dist/core/phone-auth/client.js +263 -248
  8. package/dist/core/phone-auth/index.d.ts +1 -1
  9. package/dist/core/phone-auth/index.js +7 -2
  10. package/dist/core/phone-auth/strategies/desktop.d.ts +1 -0
  11. package/dist/core/phone-auth/strategies/desktop.js +64 -18
  12. package/dist/core/phone-auth/strategies/link.js +97 -5
  13. package/dist/core/phone-auth/type-guards.d.ts +61 -43
  14. package/dist/core/phone-auth/type-guards.js +82 -44
  15. package/dist/core/phone-auth/ui/modal.js +14 -1
  16. package/dist/core/version.js +1 -1
  17. package/dist/esm/adapters/react/usePhoneAuth.d.ts +1 -1
  18. package/dist/esm/adapters/vue/useClient.d.ts +3 -3
  19. package/dist/esm/adapters/vue/usePhoneAuth.d.ts +1 -1
  20. package/dist/esm/core/phone-auth/api-types.d.ts +112 -27
  21. package/dist/esm/core/phone-auth/client.d.ts +13 -11
  22. package/dist/esm/core/phone-auth/client.js +263 -248
  23. package/dist/esm/core/phone-auth/index.d.ts +1 -1
  24. package/dist/esm/core/phone-auth/index.js +3 -1
  25. package/dist/esm/core/phone-auth/strategies/desktop.d.ts +1 -0
  26. package/dist/esm/core/phone-auth/strategies/desktop.js +64 -18
  27. package/dist/esm/core/phone-auth/strategies/link.js +97 -5
  28. package/dist/esm/core/phone-auth/type-guards.d.ts +61 -43
  29. package/dist/esm/core/phone-auth/type-guards.js +76 -41
  30. package/dist/esm/core/phone-auth/ui/modal.js +14 -1
  31. package/dist/esm/core/version.js +1 -1
  32. package/dist/esm/index.d.ts +2 -2
  33. package/dist/esm/index.js +3 -1
  34. package/dist/index.d.ts +2 -2
  35. package/dist/index.js +7 -2
  36. package/package.json +1 -1
@@ -3,4 +3,6 @@ export * from './types';
3
3
  export { PhoneAuthErrorCode, isPhoneAuthError, isUserError, getUserMessage, isErrorCode, getRetryDelay, isRetryableError, serializeError, createErrorBreadcrumb } from './error-utils';
4
4
  export { validatePhoneNumber, validatePlmn, validateUseCaseRequirements, validateConsentData, validateNonce } from './validation-utils';
5
5
  export { MobileDebugConsole } from './ui/mobile-debug-console';
6
- export { isHeadlessResult, isCredential, isLinkStrategy, isTS43Strategy, isDesktopStrategy, getStrategy, requiresPolling, requiresUserAction } from './type-guards';
6
+ export { isExtendedResponse, isCredential, isAuthCredential, isLinkStrategy, isTS43Strategy, isDesktopStrategy, getStrategy, hasPollingControls, hasTrigger,
7
+ // Deprecated aliases
8
+ isHeadlessResult, requiresPolling, requiresUserAction } from './type-guards';
@@ -55,6 +55,7 @@ export declare class DesktopHandler implements StrategyHandler {
55
55
  private pollingAttempts;
56
56
  private isCancelled;
57
57
  private onCancel?;
58
+ private pollingReject?;
58
59
  /**
59
60
  * Maps backend HTTP status codes to client status
60
61
  * @param httpStatus HTTP status code from backend
@@ -57,7 +57,20 @@ export class DesktopHandler {
57
57
  if (desktopData && desktopData.data && typeof desktopData.data === 'object') {
58
58
  const innerData = desktopData.data;
59
59
  // Try to extract from inner data
60
- qrCode = innerData.qr_code_image || innerData.qr_code;
60
+ // Support both single QR (qr_code_image) and dual-platform QR (ios/android)
61
+ if (innerData.ios_qr_image || innerData.android_qr_image) {
62
+ // Dual-platform QR format
63
+ qrCode = {
64
+ iosQRCode: innerData.ios_qr_image,
65
+ androidQRCode: innerData.android_qr_image,
66
+ iosUrl: innerData.ios_url,
67
+ androidUrl: innerData.android_url
68
+ };
69
+ }
70
+ else {
71
+ // Single QR format (legacy)
72
+ qrCode = innerData.qr_code_image || innerData.qr_code;
73
+ }
61
74
  sessionId = innerData.session_id;
62
75
  pollingEndpoint = innerData.status_url;
63
76
  pollingInterval = innerData.polling_interval;
@@ -84,33 +97,44 @@ export class DesktopHandler {
84
97
  options.onQRCodeReady(qrCode);
85
98
  }
86
99
  // Use polling endpoint with this priority:
87
- // 1. Developer-provided endpoint from options
100
+ // 1. Developer-provided endpoint from options (highest priority)
88
101
  // 2. Backend-provided endpoint
89
- // 3. Error if none available
90
- const finalPollingEndpoint = (options === null || options === void 0 ? void 0 : options.pollingEndpoint) || pollingEndpoint;
91
- // If no polling endpoint available, return QR code data and let the app handle the rest
102
+ // 3. Hardcoded fallback
103
+ console.log('[Desktop QR] Polling endpoint selection:');
104
+ console.log(' - options?.pollingEndpoint:', options === null || options === void 0 ? void 0 : options.pollingEndpoint);
105
+ console.log(' - backend pollingEndpoint:', pollingEndpoint);
106
+ let finalPollingEndpoint = options === null || options === void 0 ? void 0 : options.pollingEndpoint;
107
+ let endpointSource = 'options';
92
108
  if (!finalPollingEndpoint) {
93
- return {
94
- authenticated: false,
95
- session: data.session,
96
- error: 'No polling endpoint provided - configure endpoints.polling or ensure backend provides status_url'
97
- };
109
+ finalPollingEndpoint = pollingEndpoint; // Backend-provided status_url
110
+ endpointSource = 'backend';
98
111
  }
112
+ if (!finalPollingEndpoint) {
113
+ // Use hardcoded fallback - this will be constructed in the polling function
114
+ console.log('[Desktop QR] No polling endpoint provided, will use hardcoded fallback');
115
+ endpointSource = 'fallback';
116
+ }
117
+ console.log('[Desktop QR] Selected endpoint:', finalPollingEndpoint, 'from source:', endpointSource);
99
118
  // Start polling for authentication status
100
119
  const finalPollingInterval = (options === null || options === void 0 ? void 0 : options.pollingInterval) || pollingInterval || 2000;
101
120
  const maxAttempts = (options === null || options === void 0 ? void 0 : options.maxPollingAttempts) || 150; // Default to 5 minutes
102
- return this.startPolling(finalPollingEndpoint, sessionId, finalPollingInterval, maxAttempts, expiresIn || 300, // Default 5 minutes expiry
103
- options);
121
+ console.log(`[Desktop QR] Starting polling - endpoint source: ${endpointSource}, interval: ${finalPollingInterval}ms, max attempts: ${maxAttempts}`);
122
+ return this.startPolling(finalPollingEndpoint || '', // Pass empty string if undefined, will use fallback
123
+ sessionId, finalPollingInterval, maxAttempts, expiresIn || 300, // Default 5 minutes expiry
124
+ options, endpointSource // Pass the endpoint source for logging
125
+ );
104
126
  });
105
127
  }
106
128
  /**
107
129
  * Start polling for authentication status
108
130
  */
109
- startPolling(endpoint, sessionId, interval, maxAttempts, expiresIn, options) {
110
- return __awaiter(this, void 0, void 0, function* () {
131
+ startPolling(endpoint_1, sessionId_1, interval_1, maxAttempts_1, expiresIn_1, options_1) {
132
+ return __awaiter(this, arguments, void 0, function* (endpoint, sessionId, interval, maxAttempts, expiresIn, options, endpointSource = 'unknown') {
111
133
  const startTime = Date.now();
112
134
  const expiryTime = startTime + (expiresIn * 1000);
113
135
  return new Promise((resolve, reject) => {
136
+ // Store the reject function so we can call it from cancel()
137
+ this.pollingReject = reject;
114
138
  const poll = () => __awaiter(this, void 0, void 0, function* () {
115
139
  try {
116
140
  // Check if cancelled
@@ -125,9 +149,10 @@ export class DesktopHandler {
125
149
  message: 'Authentication cancelled'
126
150
  });
127
151
  }
128
- resolve({
129
- authenticated: false,
130
- error: 'Authentication cancelled'
152
+ // Reject the promise with a cancellation error
153
+ reject({
154
+ code: 'USER_DENIED',
155
+ message: 'Authentication cancelled by user'
131
156
  });
132
157
  return;
133
158
  }
@@ -175,12 +200,19 @@ export class DesktopHandler {
175
200
  const url = new URL(endpoint);
176
201
  statusUrl = `${url.protocol}//${url.host}/public/public/status/${sessionId}`;
177
202
  }
203
+ else if (endpoint && endpoint !== '') {
204
+ // Relative path provided (e.g. '/api/phone-auth/status')
205
+ // Append session ID to the provided endpoint
206
+ statusUrl = `${endpoint}/${sessionId}`;
207
+ }
178
208
  else {
179
- // Use relative path that will be proxied through the app's server
209
+ // No endpoint provided - use hardcoded fallback
180
210
  // This ensures it goes through the same domain and uses the app's API configuration
181
211
  statusUrl = `/api/phone-auth/status/${sessionId}`;
182
212
  }
183
213
  // Poll the public endpoint - no authentication required
214
+ console.log(`[Desktop QR] Polling status (attempt ${this.pollingAttempts}/${maxAttempts})`);
215
+ console.log(`[Desktop QR] Using ${endpointSource} endpoint: ${statusUrl}`);
184
216
  const response = yield fetch(statusUrl, {
185
217
  method: 'GET',
186
218
  headers: {
@@ -188,6 +220,7 @@ export class DesktopHandler {
188
220
  // No Authorization header needed for public endpoint
189
221
  }
190
222
  });
223
+ console.log(`[Desktop QR] Status response: ${response.status} ${response.statusText}`);
191
224
  // Backend Status Code Mapping:
192
225
  // - 200 OK: Session exists (body has 'pending' or 'completed' status)
193
226
  // - 410 Gone: Session expired after timeout
@@ -215,6 +248,7 @@ export class DesktopHandler {
215
248
  });
216
249
  }
217
250
  // Return the session data for next steps
251
+ this.pollingReject = undefined; // Clear the reject function on success
218
252
  resolve({
219
253
  authenticated: true,
220
254
  credential: result.credential || result.session_key || sessionId,
@@ -339,10 +373,12 @@ export class DesktopHandler {
339
373
  */
340
374
  stopPolling() {
341
375
  if (this.pollingIntervalId) {
376
+ console.log('[Desktop QR] Stopping polling');
342
377
  clearInterval(this.pollingIntervalId);
343
378
  this.pollingIntervalId = undefined;
344
379
  }
345
380
  this.pollingAttempts = 0;
381
+ // Don't clear pollingReject here - it's needed by cancel()
346
382
  }
347
383
  /**
348
384
  * Format response for backend processing
@@ -374,15 +410,25 @@ export class DesktopHandler {
374
410
  this.stopPolling();
375
411
  this.isCancelled = false;
376
412
  this.onCancel = undefined;
413
+ this.pollingReject = undefined;
377
414
  }
378
415
  /**
379
416
  * Cancel the ongoing authentication
380
417
  */
381
418
  cancel() {
382
419
  var _a;
420
+ console.log('[Desktop QR] Cancelling authentication');
383
421
  this.isCancelled = true;
384
422
  this.stopPolling();
385
423
  (_a = this.onCancel) === null || _a === void 0 ? void 0 : _a.call(this);
424
+ // Immediately reject the polling promise
425
+ if (this.pollingReject) {
426
+ this.pollingReject({
427
+ code: 'USER_DENIED',
428
+ message: 'Authentication cancelled by user'
429
+ });
430
+ this.pollingReject = undefined;
431
+ }
386
432
  }
387
433
  }
388
434
  /**
@@ -23,12 +23,21 @@ export class LinkHandler {
23
23
  */
24
24
  invoke(data, options) {
25
25
  return __awaiter(this, void 0, void 0, function* () {
26
+ console.log('[Link Auth] 🔗 SDK Version: 4.4.8-beta.2 (with enhanced error logging)');
27
+ console.log('[Link Auth] 🔗 invoke() called with data:', JSON.stringify(data, null, 2));
28
+ console.log('[Link Auth] Options:', options ? JSON.stringify({
29
+ pollingInterval: options.pollingInterval,
30
+ maxPollingAttempts: options.maxPollingAttempts,
31
+ pollingEndpoint: options.pollingEndpoint
32
+ }) : 'none');
26
33
  // Extract link data from prepare response
27
34
  const linkData = data.data;
28
35
  if (!linkData || !linkData.url) {
29
36
  throw new Error('Invalid link data: missing URL');
30
37
  }
31
38
  const sessionKey = data.session.session_key;
39
+ console.log('[Link Auth] Session key:', sessionKey);
40
+ console.log('[Link Auth] Link URL:', linkData.url);
32
41
  // Open authentication app without navigating away from current page
33
42
  this.openAuthenticationLink(linkData.url);
34
43
  // Notify that link was opened
@@ -60,12 +69,19 @@ export class LinkHandler {
60
69
  const interval = (options === null || options === void 0 ? void 0 : options.pollingInterval) || 2000; // Fixed 2 second interval
61
70
  const maxAttempts = (options === null || options === void 0 ? void 0 : options.maxPollingAttempts) || 150; // 5 minutes with 2s interval
62
71
  let attempts = 0;
72
+ console.log('[Link Auth] 🚀 Starting polling:', {
73
+ sessionKey,
74
+ interval: `${interval}ms`,
75
+ maxAttempts,
76
+ linkDataAvailable: !!linkData
77
+ });
63
78
  return new Promise((resolve, reject) => {
64
79
  this.isPolling = true;
65
80
  const poll = () => __awaiter(this, void 0, void 0, function* () {
66
81
  if (!this.isPolling) {
67
82
  return; // Polling was stopped
68
83
  }
84
+ let statusUrl = ''; // Declare at function scope for catch block access
69
85
  try {
70
86
  attempts++;
71
87
  // Check max attempts
@@ -84,16 +100,54 @@ export class LinkHandler {
84
100
  return;
85
101
  }
86
102
  // Build public status endpoint URL
87
- let statusUrl;
88
- // First priority: use status_url from link data if provided
89
- if (linkData.status_url) {
90
- statusUrl = linkData.status_url;
91
- console.log('[Link Auth] Using status URL from link data:', statusUrl);
103
+ // Use the same priority logic as Desktop strategy:
104
+ // 1. options?.pollingEndpoint (already contains invoke options OR client config from client.ts)
105
+ // 2. Backend-provided status_url from linkData
106
+ // 3. Hardcoded fallback to API server
107
+ let endpoint = options === null || options === void 0 ? void 0 : options.pollingEndpoint;
108
+ let endpointSource = 'options';
109
+ if (!endpoint && linkData.status_url) {
110
+ endpoint = linkData.status_url;
111
+ endpointSource = 'backend';
112
+ }
113
+ console.log('[Link Auth] Polling endpoint selection:');
114
+ console.log(' - options?.pollingEndpoint:', options === null || options === void 0 ? void 0 : options.pollingEndpoint);
115
+ console.log(' - linkData.status_url:', linkData.status_url);
116
+ console.log(' - selected endpoint:', endpoint, 'from source:', endpointSource);
117
+ // Build the status URL based on endpoint format (same as Desktop)
118
+ if (endpoint && (endpoint.startsWith('http://') || endpoint.startsWith('https://'))) {
119
+ // Full URL provided
120
+ if (endpoint.includes('{{session_id}}')) {
121
+ statusUrl = endpoint.replace('{{session_id}}', sessionKey);
122
+ }
123
+ else if (!endpoint.includes(sessionKey)) {
124
+ // If it doesn't already contain the session ID, check if it's a base URL
125
+ const url = new URL(endpoint);
126
+ statusUrl = `${url.protocol}//${url.host}/public/public/status/${sessionKey}`;
127
+ }
128
+ else {
129
+ statusUrl = endpoint;
130
+ }
131
+ }
132
+ else if (endpoint && endpoint !== '') {
133
+ // Relative path provided (e.g. '/api/phone-auth/status')
134
+ const origin = typeof window !== 'undefined' ? window.location.origin : '';
135
+ if (endpoint.includes('{{session_id}}')) {
136
+ statusUrl = origin + endpoint.replace('{{session_id}}', sessionKey);
137
+ }
138
+ else {
139
+ // Append session ID to the provided endpoint
140
+ statusUrl = origin + endpoint + '/' + sessionKey;
141
+ }
92
142
  }
93
143
  else {
144
+ // No endpoint provided - use hardcoded fallback
94
145
  statusUrl = `https://api.glideidentity.app/public/public/status/${sessionKey}`;
146
+ endpointSource = 'fallback';
95
147
  }
148
+ console.log(`[Link Auth] Using ${endpointSource} endpoint: ${statusUrl}`);
96
149
  // Poll public status endpoint - no authentication required
150
+ console.log(`[Link Auth] Polling status (attempt ${attempts}/${maxAttempts}): ${statusUrl}`);
97
151
  const response = yield fetch(statusUrl, {
98
152
  method: 'GET',
99
153
  headers: {
@@ -101,12 +155,16 @@ export class LinkHandler {
101
155
  // No Authorization header needed for public endpoint
102
156
  }
103
157
  });
158
+ console.log(`[Link Auth] Poll response - Status: ${response.status}, OK: ${response.ok}`);
104
159
  // Handle based on HTTP status code
105
160
  if (response.status === 200) {
106
161
  // Session is active (pending or completed)
107
162
  const result = yield response.json();
163
+ console.log('[Link Auth] Poll response data:', JSON.stringify(result, null, 2));
108
164
  if (result.status === 'completed') {
109
165
  // Authentication completed successfully
166
+ console.log('[Link Auth] ✅ Authentication COMPLETED! Session:', sessionKey);
167
+ console.log('[Link Auth] Full completion result:', JSON.stringify(result, null, 2));
110
168
  this.stopPolling();
111
169
  // Authentication completed successfully
112
170
  if (options === null || options === void 0 ? void 0 : options.onStatusUpdate) {
@@ -131,6 +189,7 @@ export class LinkHandler {
131
189
  }
132
190
  else if (result.status === 'pending') {
133
191
  // Continue polling
192
+ console.log('[Link Auth] Status still pending, continuing to poll...');
134
193
  if (options === null || options === void 0 ? void 0 : options.onStatusUpdate) {
135
194
  options.onStatusUpdate({
136
195
  status: 'pending',
@@ -138,9 +197,14 @@ export class LinkHandler {
138
197
  });
139
198
  }
140
199
  }
200
+ else {
201
+ // Unexpected status value
202
+ console.log('[Link Auth] ⚠️ Unexpected status value:', result.status, 'Full result:', JSON.stringify(result, null, 2));
203
+ }
141
204
  }
142
205
  else if (response.status === 410) {
143
206
  // Session expired
207
+ console.log('[Link Auth] ❌ Session expired (410)');
144
208
  this.stopPolling();
145
209
  const errorData = yield response.json().catch(() => ({ message: 'Session expired' }));
146
210
  if (options === null || options === void 0 ? void 0 : options.onTimeout) {
@@ -156,8 +220,10 @@ export class LinkHandler {
156
220
  }
157
221
  else if (response.status === 422) {
158
222
  // Authentication failed
223
+ console.log('[Link Auth] ❌ Authentication failed (422)');
159
224
  this.stopPolling();
160
225
  const errorData = yield response.json().catch(() => ({ message: 'Authentication failed' }));
226
+ console.log('[Link Auth] Error data:', JSON.stringify(errorData, null, 2));
161
227
  const isUserCancelled = errorData.code === 'USER_CANCELLED';
162
228
  const errorMsg = isUserCancelled
163
229
  ? 'User cancelled authentication'
@@ -173,6 +239,7 @@ export class LinkHandler {
173
239
  }
174
240
  else if (response.status === 404) {
175
241
  // Session not found
242
+ console.log('[Link Auth] ❌ Session not found (404)');
176
243
  this.stopPolling();
177
244
  if (options === null || options === void 0 ? void 0 : options.onStatusUpdate) {
178
245
  options.onStatusUpdate({
@@ -184,16 +251,40 @@ export class LinkHandler {
184
251
  }
185
252
  else if (response.status === 400) {
186
253
  // Invalid session key
254
+ console.log('[Link Auth] ❌ Invalid session key (400)');
187
255
  this.stopPolling();
188
256
  const errorData = yield response.json().catch(() => ({ message: 'Invalid session key' }));
257
+ console.log('[Link Auth] Error data:', JSON.stringify(errorData, null, 2));
189
258
  reject(new Error(errorData.message || 'Invalid session key'));
190
259
  }
191
260
  else {
192
261
  // Unexpected status - continue polling
262
+ console.log('[Link Auth] ⚠️ Unexpected HTTP status:', response.status, 'continuing to poll...');
263
+ try {
264
+ const body = yield response.text();
265
+ console.log('[Link Auth] Response body:', body);
266
+ }
267
+ catch (e) {
268
+ console.log('[Link Auth] Could not read response body');
269
+ }
193
270
  }
194
271
  }
195
272
  catch (error) {
196
273
  // Network or other error - continue polling
274
+ console.error('[Link Auth] 🔴 Polling error:', error.message || error);
275
+ console.error('[Link Auth] Error details:', {
276
+ name: error.name,
277
+ message: error.message,
278
+ stack: error.stack,
279
+ statusUrl: statusUrl,
280
+ attempt: attempts,
281
+ error: error
282
+ });
283
+ // Check if it's a CORS error (common on mobile)
284
+ if (error.message && error.message.toLowerCase().includes('failed')) {
285
+ console.error('[Link Auth] ⚠️ Possible CORS issue. Status URL:', statusUrl);
286
+ console.error('[Link Auth] Make sure the API endpoint allows CORS from your ngrok domain');
287
+ }
197
288
  if (options === null || options === void 0 ? void 0 : options.onStatusUpdate) {
198
289
  options.onStatusUpdate({
199
290
  status: 'pending',
@@ -213,6 +304,7 @@ export class LinkHandler {
213
304
  * Stop polling
214
305
  */
215
306
  stopPolling() {
307
+ console.log('[Link Auth] 🏁 Stopping polling');
216
308
  this.isPolling = false;
217
309
  if (this.pollingInterval) {
218
310
  clearInterval(this.pollingInterval);
@@ -4,29 +4,29 @@
4
4
  * These utilities help developers work with the SDK responses in a type-safe way
5
5
  * without having to write their own type checking logic.
6
6
  */
7
- import type { HeadlessResult } from './api-types';
7
+ import type { AnyExtendedResponse, DesktopExtendedResponse, LinkExtendedResponse, TS43ExtendedResponse, AuthCredential } from './api-types';
8
8
  /**
9
- * Type guard to check if the result is a HeadlessResult (headless mode)
10
- * or a Credential (UI mode).
9
+ * Type guard to check if the result is an ExtendedResponse (extended mode)
10
+ * or a Credential (standard mode).
11
11
  *
12
12
  * @example
13
13
  * ```typescript
14
- * const result = await invokeSecurePrompt(sdkRequest);
14
+ * const result = await invokeSecurePrompt(sdkRequest, { executionMode: 'extended' });
15
15
  *
16
- * if (isHeadlessResult(result)) {
17
- * // TypeScript knows this is HeadlessResult
16
+ * if (isExtendedResponse(result)) {
17
+ * // TypeScript knows this is ExtendedResponse
18
18
  * console.log(result.strategy);
19
- * await result.trigger();
19
+ * await result.cancel();
20
20
  * } else {
21
21
  * // TypeScript knows this is a Credential
22
22
  * const processedResult = await verifyPhoneNumberCredential(result, session);
23
23
  * }
24
24
  * ```
25
25
  */
26
- export declare function isHeadlessResult(result: any): result is HeadlessResult;
26
+ export declare function isExtendedResponse(result: any): result is AnyExtendedResponse;
27
27
  /**
28
- * Type guard to check if the result is a Credential (UI mode response).
29
- * A credential is either a string token or an object without HeadlessResult properties.
28
+ * Type guard to check if the result is a Credential (standard mode response).
29
+ * A credential is either a string token or an object without ExtendedResponse properties.
30
30
  *
31
31
  * @example
32
32
  * ```typescript
@@ -40,55 +40,61 @@ export declare function isCredential(result: any): result is string | {
40
40
  [aggregator_id: string]: string | string[];
41
41
  };
42
42
  /**
43
- * Type guard to check if a HeadlessResult is using the Link strategy.
43
+ * Type guard to check if the result is an AuthCredential object.
44
+ *
45
+ * @example
46
+ * ```typescript
47
+ * if (isAuthCredential(result)) {
48
+ * console.log(result.credential);
49
+ * console.log(result.authenticated);
50
+ * }
51
+ * ```
52
+ */
53
+ export declare function isAuthCredential(result: any): result is AuthCredential;
54
+ /**
55
+ * Type guard to check if an ExtendedResponse is using the Link strategy.
44
56
  * Link strategy involves opening an app link (App Clip on iOS, app on Android).
45
57
  *
46
58
  * @example
47
59
  * ```typescript
48
- * if (isHeadlessResult(result) && isLinkStrategy(result)) {
49
- * // Show custom button for opening app
50
- * myButton.onclick = () => result.trigger();
51
- * await result.pollingPromise;
60
+ * if (isExtendedResponse(result) && isLinkStrategy(result)) {
61
+ * // Re-trigger app opening if needed
62
+ * result.trigger();
63
+ * await result.credential;
52
64
  * }
53
65
  * ```
54
66
  */
55
- export declare function isLinkStrategy(result: HeadlessResult): result is HeadlessResult & {
56
- strategy: 'link';
57
- };
67
+ export declare function isLinkStrategy(result: AnyExtendedResponse): result is LinkExtendedResponse;
58
68
  /**
59
- * Type guard to check if a HeadlessResult is using the TS43 strategy.
69
+ * Type guard to check if an ExtendedResponse is using the TS43 strategy.
60
70
  * TS43 strategy uses the browser's Digital Credentials API.
61
71
  *
62
72
  * @example
63
73
  * ```typescript
64
- * if (isHeadlessResult(result) && isTS43Strategy(result)) {
65
- * // Invoke credential API immediately or on button click
66
- * const credential = await result.trigger();
74
+ * if (isExtendedResponse(result) && isTS43Strategy(result)) {
75
+ * // Re-trigger credential request if needed
76
+ * await result.trigger();
67
77
  * }
68
78
  * ```
69
79
  */
70
- export declare function isTS43Strategy(result: HeadlessResult): result is HeadlessResult & {
71
- strategy: 'ts43';
72
- };
80
+ export declare function isTS43Strategy(result: AnyExtendedResponse): result is TS43ExtendedResponse;
73
81
  /**
74
- * Type guard to check if a HeadlessResult is using the Desktop strategy.
82
+ * Type guard to check if an ExtendedResponse is using the Desktop strategy.
75
83
  * Desktop strategy involves QR codes for cross-device authentication.
76
84
  *
77
85
  * @example
78
86
  * ```typescript
79
- * if (isHeadlessResult(result) && isDesktopStrategy(result)) {
87
+ * if (isExtendedResponse(result) && isDesktopStrategy(result)) {
80
88
  * // Show custom QR code UI
81
- * displayQRCode(result.qrCodeUrl);
82
- * await result.pollingPromise;
89
+ * displayQRCode(result.qr_code_data);
90
+ * await result.start_polling();
83
91
  * }
84
92
  * ```
85
93
  */
86
- export declare function isDesktopStrategy(result: HeadlessResult): result is HeadlessResult & {
87
- strategy: 'desktop';
88
- };
94
+ export declare function isDesktopStrategy(result: AnyExtendedResponse): result is DesktopExtendedResponse;
89
95
  /**
90
96
  * Helper function to safely get the authentication strategy from any result.
91
- * Returns undefined if the result is not a HeadlessResult.
97
+ * Returns undefined if the result is not an ExtendedResponse.
92
98
  *
93
99
  * @example
94
100
  * ```typescript
@@ -100,26 +106,38 @@ export declare function isDesktopStrategy(result: HeadlessResult): result is Hea
100
106
  */
101
107
  export declare function getStrategy(result: any): 'link' | 'ts43' | 'desktop' | undefined;
102
108
  /**
103
- * Helper function to determine if a result requires polling.
104
- * Link and Desktop strategies require polling, TS43 does not.
109
+ * Helper function to determine if a result has polling controls.
110
+ * Link and Desktop strategies have polling controls in extended mode.
105
111
  *
106
112
  * @example
107
113
  * ```typescript
108
- * if (requiresPolling(result)) {
109
- * await result.pollingPromise;
114
+ * if (hasPollingControls(result)) {
115
+ * await result.start_polling();
110
116
  * }
111
117
  * ```
112
118
  */
113
- export declare function requiresPolling(result: any): boolean;
119
+ export declare function hasPollingControls(result: any): boolean;
114
120
  /**
115
- * Helper function to determine if a result requires user interaction.
116
- * All headless strategies require some form of user interaction.
121
+ * Helper function to determine if a result has a trigger method.
122
+ * Link and TS43 strategies have trigger methods in extended mode.
117
123
  *
118
124
  * @example
119
125
  * ```typescript
120
- * if (requiresUserAction(result)) {
121
- * showActionButton();
126
+ * if (hasTrigger(result)) {
127
+ * result.trigger();
122
128
  * }
123
129
  * ```
124
130
  */
125
- export declare function requiresUserAction(result: any): boolean;
131
+ export declare function hasTrigger(result: any): boolean;
132
+ /**
133
+ * @deprecated Use isExtendedResponse instead
134
+ */
135
+ export declare const isHeadlessResult: typeof isExtendedResponse;
136
+ /**
137
+ * @deprecated Use hasPollingControls instead
138
+ */
139
+ export declare const requiresPolling: typeof hasPollingControls;
140
+ /**
141
+ * @deprecated This function is no longer needed as extended mode handles user actions differently
142
+ */
143
+ export declare const requiresUserAction: (result: any) => boolean;