@dynamicore/jumio-sdk 1.0.0 → 1.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.
@@ -1,85 +1,80 @@
1
1
  import axios from 'axios';
2
2
 
3
- // src/core/errors.ts
4
- var JumioError = class extends Error {
5
- isJumioError = true;
6
- statusCode;
7
- rawData;
8
- code;
9
- constructor(message, options) {
10
- super(message);
11
- this.name = "JumioError";
12
- this.statusCode = options?.statusCode;
13
- this.rawData = options?.rawData;
14
- this.code = options?.code;
15
- if (options?.cause) {
16
- this.cause = options.cause;
17
- }
18
- }
3
+ var __defProp = Object.defineProperty;
4
+ var __getOwnPropNames = Object.getOwnPropertyNames;
5
+ var __esm = (fn, res) => function __init() {
6
+ return fn && (res = (0, fn[__getOwnPropNames(fn)[0]])(fn = 0)), res;
19
7
  };
20
- var JumioTimeoutError = class extends JumioError {
21
- constructor(message = "El servicio de verificaci\xF3n de Jumio excedi\xF3 el tiempo l\xEDmite de espera.", rawData) {
22
- super(message, { code: "TIMEOUT", rawData });
23
- this.name = "JumioTimeoutError";
24
- }
25
- };
26
- var JumioNetworkError = class extends JumioError {
27
- constructor(message = "No fue posible comunicarse con los servidores de validaci\xF3n de identidad.", cause) {
28
- super(message, { code: "NETWORK_ERROR", cause });
29
- this.name = "JumioNetworkError";
30
- }
31
- };
32
- var JumioValidationError = class extends JumioError {
33
- constructor(message = "El documento no pudo ser validado o fue rechazado por Jumio.", rawData) {
34
- super(message, { code: "VALIDATION_FAILED", rawData });
35
- this.name = "JumioValidationError";
36
- }
37
- };
38
- var JumioImageProcessingError = class extends JumioError {
39
- constructor(message, cause) {
40
- super(message, { code: "IMAGE_PROCESSING_ERROR", cause });
41
- this.name = "JumioImageProcessingError";
42
- }
43
- };
44
- var JumioPollingTimeoutError = class extends JumioError {
45
- attempts;
46
- constructor(attempts, message = "La validaci\xF3n sigue en proceso. Por favor verifica nuevamente m\xE1s tarde.", rawData) {
47
- super(message, { code: "POLLING_TIMEOUT", rawData });
48
- this.name = "JumioPollingTimeoutError";
49
- this.attempts = attempts;
50
- }
51
- };
52
- var JumioAbortError = class extends JumioError {
53
- constructor(message = "La operaci\xF3n de validaci\xF3n de Jumio fue cancelada.") {
54
- super(message, { code: "ABORTED" });
55
- this.name = "JumioAbortError";
56
- }
8
+ var __export = (target, all) => {
9
+ for (var name in all)
10
+ __defProp(target, name, { get: all[name], enumerable: true });
57
11
  };
12
+
13
+ // src/core/errors.ts
58
14
  function isJumioError(error) {
59
15
  return error instanceof JumioError || typeof error === "object" && error !== null && "isJumioError" in error && error.isJumioError === true;
60
16
  }
17
+ var JumioError, JumioTimeoutError, JumioNetworkError, JumioValidationError, JumioImageProcessingError, JumioPollingTimeoutError, JumioAbortError;
18
+ var init_errors = __esm({
19
+ "src/core/errors.ts"() {
20
+ JumioError = class extends Error {
21
+ isJumioError = true;
22
+ statusCode;
23
+ rawData;
24
+ code;
25
+ constructor(message, options) {
26
+ super(message);
27
+ this.name = "JumioError";
28
+ this.statusCode = options?.statusCode;
29
+ this.rawData = options?.rawData;
30
+ this.code = options?.code;
31
+ if (options?.cause) {
32
+ this.cause = options.cause;
33
+ }
34
+ }
35
+ };
36
+ JumioTimeoutError = class extends JumioError {
37
+ constructor(message = "El servicio de verificaci\xF3n de Jumio excedi\xF3 el tiempo l\xEDmite de espera.", rawData) {
38
+ super(message, { code: "TIMEOUT", rawData });
39
+ this.name = "JumioTimeoutError";
40
+ }
41
+ };
42
+ JumioNetworkError = class extends JumioError {
43
+ constructor(message = "No fue posible comunicarse con los servidores de validaci\xF3n de identidad.", cause) {
44
+ super(message, { code: "NETWORK_ERROR", cause });
45
+ this.name = "JumioNetworkError";
46
+ }
47
+ };
48
+ JumioValidationError = class extends JumioError {
49
+ constructor(message = "El documento no pudo ser validado o fue rechazado por Jumio.", rawData) {
50
+ super(message, { code: "VALIDATION_FAILED", rawData });
51
+ this.name = "JumioValidationError";
52
+ }
53
+ };
54
+ JumioImageProcessingError = class extends JumioError {
55
+ constructor(message, cause) {
56
+ super(message, { code: "IMAGE_PROCESSING_ERROR", cause });
57
+ this.name = "JumioImageProcessingError";
58
+ }
59
+ };
60
+ JumioPollingTimeoutError = class extends JumioError {
61
+ attempts;
62
+ constructor(attempts, message = "La validaci\xF3n sigue en proceso. Por favor verifica nuevamente m\xE1s tarde.", rawData) {
63
+ super(message, { code: "POLLING_TIMEOUT", rawData });
64
+ this.name = "JumioPollingTimeoutError";
65
+ this.attempts = attempts;
66
+ }
67
+ };
68
+ JumioAbortError = class extends JumioError {
69
+ constructor(message = "La operaci\xF3n de validaci\xF3n de Jumio fue cancelada.") {
70
+ super(message, { code: "ABORTED" });
71
+ this.name = "JumioAbortError";
72
+ }
73
+ };
74
+ }
75
+ });
61
76
 
62
77
  // src/core/envelope.ts
63
- var FINAL_JUMIO_STATUSES = [
64
- "PROCESSED",
65
- "APPROVED_VERIFIED",
66
- "REJECTED",
67
- "FAILED",
68
- "ERROR",
69
- "DENIED",
70
- "EXPIRED",
71
- "ABANDONED",
72
- "DONE",
73
- "COMPLETED",
74
- "NOT_READABLE",
75
- "FRAUD",
76
- "UNSUPPORTED_ID_TYPE"
77
- ];
78
- var APPROVED_JUMIO_STATUSES = [
79
- "APPROVED_VERIFIED",
80
- "DONE",
81
- "COMPLETED"
82
- ];
83
78
  function toLowerText(value) {
84
79
  return String(value ?? "").trim().toLowerCase();
85
80
  }
@@ -87,10 +82,13 @@ function toUpperText(value) {
87
82
  return String(value ?? "").trim().toUpperCase();
88
83
  }
89
84
  function extractEnvelopeData(responseData) {
90
- if (responseData && typeof responseData === "object" && "data" in responseData) {
91
- const candidate = responseData.data;
92
- if (candidate !== void 0) {
93
- return candidate;
85
+ if (responseData && typeof responseData === "object") {
86
+ const obj = responseData;
87
+ if ("data" in obj && obj.data !== void 0) {
88
+ return obj.data;
89
+ }
90
+ if ("values" in obj && obj.values !== void 0) {
91
+ return obj.values;
94
92
  }
95
93
  }
96
94
  return responseData;
@@ -161,6 +159,48 @@ function resolveVerificationValidity(data, fallbackStatus) {
161
159
  }
162
160
  return isApprovedJumioStatus(fallbackStatus);
163
161
  }
162
+ function encodeUrlToBase64UrlSafe(url) {
163
+ try {
164
+ let base64;
165
+ if (typeof Buffer !== "undefined") {
166
+ base64 = Buffer.from(url, "utf-8").toString("base64");
167
+ } else if (typeof TextEncoder !== "undefined") {
168
+ const encoder = new TextEncoder();
169
+ const data = encoder.encode(url);
170
+ base64 = btoa(String.fromCharCode(...new Uint8Array(data)));
171
+ } else {
172
+ base64 = btoa(url);
173
+ }
174
+ return base64.replace(/\+/g, "-").replace(/\//g, "_").replace(/=+$/, "");
175
+ } catch {
176
+ return null;
177
+ }
178
+ }
179
+ var FINAL_JUMIO_STATUSES, APPROVED_JUMIO_STATUSES;
180
+ var init_envelope = __esm({
181
+ "src/core/envelope.ts"() {
182
+ FINAL_JUMIO_STATUSES = [
183
+ "PROCESSED",
184
+ "APPROVED_VERIFIED",
185
+ "REJECTED",
186
+ "FAILED",
187
+ "ERROR",
188
+ "DENIED",
189
+ "EXPIRED",
190
+ "ABANDONED",
191
+ "DONE",
192
+ "COMPLETED",
193
+ "NOT_READABLE",
194
+ "FRAUD",
195
+ "UNSUPPORTED_ID_TYPE"
196
+ ];
197
+ APPROVED_JUMIO_STATUSES = [
198
+ "APPROVED_VERIFIED",
199
+ "DONE",
200
+ "COMPLETED"
201
+ ];
202
+ }
203
+ });
164
204
 
165
205
  // src/core/retry.ts
166
206
  function delay(ms, signal) {
@@ -232,8 +272,273 @@ async function withRetry(operation, options = {}) {
232
272
  }
233
273
  throw lastError;
234
274
  }
275
+ var init_retry = __esm({
276
+ "src/core/retry.ts"() {
277
+ init_envelope();
278
+ init_errors();
279
+ }
280
+ });
281
+
282
+ // src/core/webflow.ts
283
+ var webflow_exports = {};
284
+ __export(webflow_exports, {
285
+ buildRedirectUrl: () => buildRedirectUrl,
286
+ parseWebflowReturnParams: () => parseWebflowReturnParams,
287
+ pollWebflowStatus: () => pollWebflowStatus,
288
+ resolveWebflowResult: () => resolveWebflowResult,
289
+ startWebflowSession: () => startWebflowSession
290
+ });
291
+ function buildRedirectUrl(returnUrl, proxyUrl) {
292
+ if (!proxyUrl) {
293
+ return returnUrl;
294
+ }
295
+ const encoded = encodeUrlToBase64UrlSafe(returnUrl);
296
+ if (!encoded) {
297
+ throw new JumioValidationError(
298
+ `No fue posible codificar la URL de retorno: "${returnUrl}"`
299
+ );
300
+ }
301
+ const normalizedProxy = proxyUrl.endsWith("/") ? proxyUrl : `${proxyUrl}/`;
302
+ return `${normalizedProxy}${encoded}`;
303
+ }
304
+ function parseWebflowReturnParams(source) {
305
+ let searchString;
306
+ if (!source) {
307
+ if (typeof window !== "undefined" && window.location) {
308
+ searchString = window.location.search;
309
+ } else {
310
+ return { allParams: {} };
311
+ }
312
+ } else if (typeof source === "string") {
313
+ const questionIdx = source.indexOf("?");
314
+ searchString = questionIdx >= 0 ? source.slice(questionIdx) : "";
315
+ } else if (source instanceof URLSearchParams) {
316
+ searchString = `?${source.toString()}`;
317
+ } else {
318
+ const hrefSearch = source.href ? (() => {
319
+ try {
320
+ return new URL(source.href).search;
321
+ } catch {
322
+ return "";
323
+ }
324
+ })() : "";
325
+ searchString = source.search ?? hrefSearch;
326
+ }
327
+ const params = new URLSearchParams(searchString);
328
+ const allParams = {};
329
+ params.forEach((value, key) => {
330
+ allParams[key] = value;
331
+ });
332
+ const accountId = params.get("accountId") ?? void 0;
333
+ let workflowId = params.get("workflowExecutionId") ?? params.get("workflowId") ?? void 0;
334
+ const rawStatus = params.get("status") ?? void 0;
335
+ if (rawStatus && (!accountId || !workflowId)) {
336
+ const statusParts = rawStatus.split("?");
337
+ const nestedSearch = statusParts.length > 1 ? `?${statusParts.slice(1).join("?")}` : "";
338
+ if (nestedSearch && nestedSearch !== "?") {
339
+ const nestedParams = new URLSearchParams(nestedSearch);
340
+ nestedParams.forEach((value, key) => {
341
+ if (!allParams[key]) allParams[key] = value;
342
+ });
343
+ if (!workflowId) {
344
+ workflowId = nestedParams.get("workflowExecutionId") ?? nestedParams.get("workflowId") ?? workflowId;
345
+ }
346
+ }
347
+ }
348
+ return {
349
+ accountId: accountId || void 0,
350
+ workflowId: workflowId || void 0,
351
+ rawStatus,
352
+ allParams
353
+ };
354
+ }
355
+ function resolveWebflowResult(rawData, accountId, workflowId) {
356
+ if (!rawData || typeof rawData !== "object") return null;
357
+ const data = rawData;
358
+ if (data.valid === true) {
359
+ return {
360
+ valid: true,
361
+ status: String(data.workflowStatus ?? data.status ?? "APPROVED_VERIFIED"),
362
+ decision: data.decision,
363
+ extraction: data.extraction,
364
+ accountId,
365
+ workflowId,
366
+ data: rawData
367
+ };
368
+ }
369
+ if (data.valid === false) {
370
+ return {
371
+ valid: false,
372
+ status: String(data.workflowStatus ?? data.status ?? "REJECTED"),
373
+ decision: data.decision,
374
+ accountId,
375
+ workflowId,
376
+ data: rawData,
377
+ errorMessage: extractJumioMessage(rawData) || "El documento fue rechazado durante la verificacion."
378
+ };
379
+ }
380
+ const capData = data;
381
+ const decisionType = capData?.decision?.type;
382
+ const extractionArr = capData?.capabilities?.extraction ?? [];
383
+ const extraction = extractionArr[0];
384
+ const isExtractionEmpty = extraction !== void 0 && Object.keys(extraction).length === 0;
385
+ if (decisionType === "REJECTED") {
386
+ return {
387
+ valid: false,
388
+ status: "REJECTED",
389
+ decision: decisionType,
390
+ accountId,
391
+ workflowId,
392
+ data: rawData,
393
+ errorMessage: extractJumioMessage(rawData) || "El documento fue rechazado por Jumio."
394
+ };
395
+ }
396
+ if (extraction && !isExtractionEmpty) {
397
+ const isApproved = decisionType === "PASSED" || decisionType === "WARNING";
398
+ return {
399
+ valid: isApproved,
400
+ status: isApproved ? decisionType ?? "PASSED" : decisionType ?? "REJECTED",
401
+ decision: decisionType,
402
+ extraction,
403
+ accountId,
404
+ workflowId,
405
+ data: rawData,
406
+ ...!isApproved ? {
407
+ errorMessage: extractJumioMessage(rawData) || "La verificacion no fue aprobada."
408
+ } : {}
409
+ };
410
+ }
411
+ return null;
412
+ }
413
+ async function pollWebflowStatus(http, params, options = {}) {
414
+ const config = http.getConfig();
415
+ const maxAttempts = options.maxAttempts ?? config.maxPollingAttempts ?? 20;
416
+ const intervalMs = options.pollingIntervalMs ?? config.pollingIntervalMs ?? 1e4;
417
+ const signal = options.signal;
418
+ let lastRawData = {};
419
+ for (let attempt = 1; attempt <= maxAttempts; attempt++) {
420
+ if (signal?.aborted) {
421
+ throw new JumioAbortError();
422
+ }
423
+ const responseData = await withRetry(
424
+ () => http.getVerificationStatus(params.accountId, params.workflowId, {
425
+ signal,
426
+ timeout: config.statusTimeout,
427
+ clientId: params.clientId
428
+ }),
429
+ {
430
+ maxRetries: config.maxRetries ?? 3,
431
+ initialDelayMs: config.retryDelayMs ?? 800,
432
+ signal
433
+ }
434
+ );
435
+ const firstLevel = extractEnvelopeData(responseData);
436
+ const statusData = extractNestedData(firstLevel) ?? {};
437
+ lastRawData = statusData;
438
+ options.onAttempt?.(attempt, maxAttempts, statusData);
439
+ const result = resolveWebflowResult(
440
+ statusData,
441
+ params.accountId,
442
+ params.workflowId
443
+ );
444
+ if (result !== null) {
445
+ return result;
446
+ }
447
+ if (attempt < maxAttempts) {
448
+ await delay(intervalMs, signal);
449
+ }
450
+ }
451
+ const lastMessage = extractJumioMessage(lastRawData) || "La verificacion Jumio sigue en proceso. Intenta nuevamente en unos momentos.";
452
+ throw new JumioPollingTimeoutError(maxAttempts, lastMessage, lastRawData);
453
+ }
454
+ async function startWebflowSession(http, config, input) {
455
+ const {
456
+ clientId,
457
+ successUrl,
458
+ errorUrl,
459
+ useRedirectProxy = false,
460
+ autoRedirect = false,
461
+ openInNewTab = false,
462
+ signal
463
+ } = input;
464
+ if (!clientId?.trim()) {
465
+ throw new JumioValidationError(
466
+ "Se requiere un identificador de cliente valido (clientId)."
467
+ );
468
+ }
469
+ if (!successUrl?.trim()) {
470
+ throw new JumioValidationError("Se requiere la URL de exito (successUrl).");
471
+ }
472
+ if (!errorUrl?.trim()) {
473
+ throw new JumioValidationError("Se requiere la URL de error (errorUrl).");
474
+ }
475
+ if (signal?.aborted) {
476
+ throw new JumioAbortError();
477
+ }
478
+ const proxyUrl = useRedirectProxy ? config.redirectProxyUrl ?? void 0 : void 0;
479
+ const finalSuccessUrl = buildRedirectUrl(successUrl, proxyUrl);
480
+ const finalErrorUrl = buildRedirectUrl(errorUrl, proxyUrl);
481
+ try {
482
+ const responseData = await withRetry(
483
+ () => http.postVerification(
484
+ {
485
+ client: clientId.trim(),
486
+ successUrl: finalSuccessUrl,
487
+ errorUrl: finalErrorUrl
488
+ },
489
+ { signal, timeout: config.requestTimeout }
490
+ ),
491
+ {
492
+ maxRetries: config.maxRetries ?? 3,
493
+ initialDelayMs: config.retryDelayMs ?? 800,
494
+ signal
495
+ }
496
+ );
497
+ const firstLevel = extractEnvelopeData(responseData);
498
+ const payload = extractNestedData(firstLevel) ?? {};
499
+ const href = payload?.href;
500
+ if (!href) {
501
+ throw new JumioError(
502
+ extractJumioMessage(payload) || "El backend no devolvio la URL de verificacion de Jumio (href).",
503
+ { rawData: payload }
504
+ );
505
+ }
506
+ const result = {
507
+ href,
508
+ accountId: payload?.accountId,
509
+ workflowId: payload?.workflowId,
510
+ data: payload
511
+ };
512
+ if (typeof window !== "undefined") {
513
+ if (openInNewTab) {
514
+ const win = window.open(href, "_blank");
515
+ if (!win || win.closed || typeof win.closed === "undefined") {
516
+ window.location.href = href;
517
+ }
518
+ } else if (autoRedirect) {
519
+ window.location.href = href;
520
+ }
521
+ }
522
+ return result;
523
+ } catch (err) {
524
+ throw err;
525
+ }
526
+ }
527
+ var init_webflow = __esm({
528
+ "src/core/webflow.ts"() {
529
+ init_envelope();
530
+ init_errors();
531
+ init_retry();
532
+ }
533
+ });
534
+
535
+ // src/core/index.ts
536
+ init_errors();
537
+ init_envelope();
538
+ init_retry();
235
539
 
236
540
  // src/core/image.ts
541
+ init_errors();
237
542
  function stripDataUrlPrefix(dataUrl) {
238
543
  if (!dataUrl) return "";
239
544
  const commaIndex = dataUrl.indexOf(",");
@@ -389,6 +694,10 @@ async function resolveImageSourceToBase64(source, s3Signer, signal) {
389
694
  }
390
695
  throw new JumioImageProcessingError("Tipo de dato de imagen no soportado.");
391
696
  }
697
+
698
+ // src/core/http.ts
699
+ init_errors();
700
+ init_envelope();
392
701
  var JumioHttpClient = class {
393
702
  client;
394
703
  config;
@@ -504,6 +813,7 @@ var JumioHttpClient = class {
504
813
  }
505
814
  /**
506
815
  * Ejecuta una petición GET para consultar el estado actual de una verificación de INE.
816
+ * Soporta un `clientId` opcional requerido por algunos endpoints de DynamiCore (p. ej. Hosted Webflow).
507
817
  */
508
818
  async getVerificationStatus(accountId, workflowId, options) {
509
819
  if (options?.signal?.aborted) {
@@ -513,12 +823,16 @@ var JumioHttpClient = class {
513
823
  const dynamicHeaders = await this.resolveHeaders();
514
824
  const endpoint = this.config.endpoint || "/marketplace/apps/jumio";
515
825
  const timeout = options?.timeout ?? this.config.statusTimeout ?? 12e4;
826
+ const queryParams = {
827
+ type: "ine",
828
+ accountId,
829
+ workflowId
830
+ };
831
+ if (options?.clientId) {
832
+ queryParams.clientId = options.clientId;
833
+ }
516
834
  const response = await this.client.get(endpoint, {
517
- params: {
518
- type: "ine",
519
- accountId,
520
- workflowId
521
- },
835
+ params: queryParams,
522
836
  headers: dynamicHeaders,
523
837
  timeout,
524
838
  signal: options?.signal
@@ -534,6 +848,9 @@ var JumioHttpClient = class {
534
848
  };
535
849
 
536
850
  // src/core/polling.ts
851
+ init_envelope();
852
+ init_errors();
853
+ init_retry();
537
854
  async function pollJumioStatus(http, accountId, workflowId, options = {}) {
538
855
  const config = http.getConfig();
539
856
  const maxAttempts = options.maxAttempts ?? config.maxPollingAttempts ?? 20;
@@ -589,7 +906,14 @@ async function pollJumioStatus(http, accountId, workflowId, options = {}) {
589
906
  throw new JumioPollingTimeoutError(maxAttempts, lastMessage, lastData);
590
907
  }
591
908
 
909
+ // src/core/index.ts
910
+ init_webflow();
911
+
592
912
  // src/core/client.ts
913
+ init_envelope();
914
+ init_errors();
915
+ init_retry();
916
+ init_webflow();
593
917
  var JumioClient = class {
594
918
  http;
595
919
  config;
@@ -729,11 +1053,110 @@ var JumioClient = class {
729
1053
  onStatusResolved?.(finalResult);
730
1054
  return finalResult;
731
1055
  }
1056
+ // ─────────────────────────────────────────────────────────────────────────
1057
+ // Hosted Webflow (Redirección)
1058
+ // ─────────────────────────────────────────────────────────────────────────
1059
+ /**
1060
+ * Construye la URL de redirección de retorno para el flujo Hosted Webflow.
1061
+ *
1062
+ * Si el cliente está configurado con un `redirectProxyUrl` y `useProxy` es `true`,
1063
+ * la URL de retorno se codifica en Base64 URL-safe y se adjunta al proxy.
1064
+ *
1065
+ * @param returnUrl URL de la aplicación a la que Jumio redirigirá tras la verificación.
1066
+ * @param useProxy Si es `true` y hay `redirectProxyUrl` configurado, usa el proxy.
1067
+ * @returns URL de redirección construida.
1068
+ */
1069
+ buildRedirectUrl(returnUrl, useProxy = false) {
1070
+ const proxyUrl = useProxy ? this.config.redirectProxyUrl ?? void 0 : void 0;
1071
+ return buildRedirectUrl(returnUrl, proxyUrl);
1072
+ }
1073
+ /**
1074
+ * Inicia el flujo Hosted Webflow solicitando al backend de DynamiCore la URL
1075
+ * de verificación de Jumio (`href`).
1076
+ *
1077
+ * El usuario debe ser redirigido a esa URL para completar la verificación en la
1078
+ * página oficial de Jumio. Al terminar, Jumio redirige de vuelta a la aplicación
1079
+ * con `accountId` y `workflowExecutionId` como query params.
1080
+ *
1081
+ * @param input Parámetros del flujo: `clientId`, `successUrl`, `errorUrl`, opciones de proxy y redirección.
1082
+ * @returns `StartWebflowResult` con la URL de Jumio (`href`) y datos adicionales.
1083
+ *
1084
+ * @example
1085
+ * ```ts
1086
+ * const { href } = await client.startWebflow({
1087
+ * clientId: "usr_123",
1088
+ * successUrl: "https://app.example.com/verify/success",
1089
+ * errorUrl: "https://app.example.com/verify/error",
1090
+ * });
1091
+ * window.location.href = href;
1092
+ * ```
1093
+ */
1094
+ async startWebflow(input) {
1095
+ return startWebflowSession(this.http, this.config, input);
1096
+ }
1097
+ /**
1098
+ * Extrae los parámetros de seguimiento de Jumio de la URL de retorno.
1099
+ *
1100
+ * Jumio añade `accountId` y `workflowExecutionId` (o `workflowId`) como query
1101
+ * params al redirigir de vuelta a la aplicación tras la verificación.
1102
+ *
1103
+ * @param source URL completa, `URLSearchParams`, objeto con `search`/`href`, o nada para leer `window.location`.
1104
+ * @returns `WebflowReturnParams` con `accountId`, `workflowId`, `rawStatus` y todos los params.
1105
+ *
1106
+ * @example En React, en el componente de retorno:
1107
+ * ```ts
1108
+ * const { accountId, workflowId } = client.parseWebflowReturnParams(window.location.href);
1109
+ * ```
1110
+ */
1111
+ parseWebflowReturnParams(source) {
1112
+ return parseWebflowReturnParams(source);
1113
+ }
1114
+ /**
1115
+ * Consulta una única vez el estado actual de la verificación del flujo Hosted Webflow.
1116
+ *
1117
+ * @param input Parámetros de consulta: `accountId`, `workflowId`, y `clientId` opcional.
1118
+ * @returns `WebflowResult | null` — `null` si la verificación aún está pendiente.
1119
+ */
1120
+ async getWebflowStatus(input) {
1121
+ const { accountId, workflowId, clientId, signal } = input;
1122
+ const responseData = await this.http.getVerificationStatus(accountId, workflowId, {
1123
+ signal,
1124
+ timeout: this.config.statusTimeout,
1125
+ clientId
1126
+ });
1127
+ const firstLevel = extractEnvelopeData(responseData);
1128
+ const statusData = extractNestedData(firstLevel) ?? {};
1129
+ const { resolveWebflowResult: resolveWebflowResult2 } = await Promise.resolve().then(() => (init_webflow(), webflow_exports));
1130
+ return resolveWebflowResult2(statusData, accountId, workflowId);
1131
+ }
1132
+ /**
1133
+ * Sondea periódicamente el estado de verificación de un flujo Hosted Webflow de Jumio.
1134
+ *
1135
+ * Continúa consultando hasta obtener un resultado definitivo o agotar los intentos.
1136
+ *
1137
+ * @param params `accountId`, `workflowId` y `clientId` opcional.
1138
+ * @param options Opciones de sondeo (`maxAttempts`, `pollingIntervalMs`, `signal`, `onAttempt`).
1139
+ * @returns `WebflowResult` con el resultado definitivo.
1140
+ *
1141
+ * @example
1142
+ * ```ts
1143
+ * // En el componente de retorno, tras leer los params de la URL:
1144
+ * const result = await client.pollWebflowStatus({ accountId, workflowId, clientId });
1145
+ * if (result.valid) {
1146
+ * console.log("Verificación aprobada:", result.extraction);
1147
+ * } else {
1148
+ * console.warn("Rechazado:", result.errorMessage);
1149
+ * }
1150
+ * ```
1151
+ */
1152
+ async pollWebflowStatus(params, options) {
1153
+ return pollWebflowStatus(this.http, params, options);
1154
+ }
732
1155
  };
733
1156
  function createJumioClient(config) {
734
1157
  return new JumioClient(config);
735
1158
  }
736
1159
 
737
- export { APPROVED_JUMIO_STATUSES, FINAL_JUMIO_STATUSES, JumioAbortError, JumioClient, JumioError, JumioHttpClient, JumioImageProcessingError, JumioNetworkError, JumioPollingTimeoutError, JumioTimeoutError, JumioValidationError, arrayBufferToBase64, blobToBase64, createJumioClient, delay, extractEnvelopeData, extractJumioMessage, extractNestedData, fetchUrlAsBase64, isApprovedJumioStatus, isBase64String, isFinalJumioStatus, isJumioError, isPassedJumioDecision, normalizeSignedUrl, pollJumioStatus, resolveImageSourceToBase64, resolveVerificationValidity, shouldRetryJumio, stripDataUrlPrefix, toLowerText, toUpperText, withRetry };
1160
+ export { APPROVED_JUMIO_STATUSES, FINAL_JUMIO_STATUSES, JumioAbortError, JumioClient, JumioError, JumioHttpClient, JumioImageProcessingError, JumioNetworkError, JumioPollingTimeoutError, JumioTimeoutError, JumioValidationError, arrayBufferToBase64, blobToBase64, buildRedirectUrl, createJumioClient, delay, encodeUrlToBase64UrlSafe, extractEnvelopeData, extractJumioMessage, extractNestedData, fetchUrlAsBase64, isApprovedJumioStatus, isBase64String, isFinalJumioStatus, isJumioError, isPassedJumioDecision, normalizeSignedUrl, parseWebflowReturnParams, pollJumioStatus, pollWebflowStatus, resolveImageSourceToBase64, resolveVerificationValidity, resolveWebflowResult, shouldRetryJumio, startWebflowSession, stripDataUrlPrefix, toLowerText, toUpperText, withRetry };
738
1161
  //# sourceMappingURL=index.mjs.map
739
1162
  //# sourceMappingURL=index.mjs.map