@incodetech/core 2.0.1 → 2.1.0-rc.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.
Files changed (218) hide show
  1. package/dist/{BrowserStorageProvider-CuOW1Er2.esm.js → BrowserStorageProvider-BpJM-gIl.esm.js} +8 -1
  2. package/dist/{IpifyProvider-D7jx52AL.esm.js → IpifyProvider-D4LWD15E.esm.js} +28 -0
  3. package/dist/{MotionSensorProvider-4v7xkqAp.esm.js → MotionSensorProvider-Bx7Mpzt0.esm.js} +63 -13
  4. package/dist/{OpenViduRecordingProvider-CMu6XVdc.esm.js → OpenViduRecordingProvider-O4GjBseO.esm.js} +1 -1
  5. package/dist/StateMachine-BC_nGvrc.d.ts +2 -0
  6. package/dist/StreamCanvasCapture-ImiDQdVA.esm.js +118 -0
  7. package/dist/StreamCanvasCapture-yyl20qd9.d.ts +152 -0
  8. package/dist/{BaseWasmProvider-C_DLEI40.esm.js → WasmUtilProvider-CiEN7Gjn.esm.js} +183 -11
  9. package/dist/{addressSearch-BpTbTWCa.esm.js → addressSearch-DvmWXKZg.esm.js} +63 -57
  10. package/dist/{ae-signature-DDDZmWXj.esm.js → ae-signature-BFZta3TZ.esm.js} +1 -1
  11. package/dist/ae-signature.d.ts +3 -3
  12. package/dist/ae-signature.esm.js +6 -5
  13. package/dist/antifraud.d.ts +5 -46
  14. package/dist/antifraud.esm.js +6 -43
  15. package/dist/antifraudManager-CkV4u-LE.esm.js +55 -0
  16. package/dist/antifraudManager-CznnhyvD.d.ts +63 -0
  17. package/dist/{antifraudStateMachine-O0TMf6yc.esm.js → antifraudStateMachine-Ccrb-Jxc.esm.js} +2 -2
  18. package/dist/apiError-B-j-gyDx.esm.js +51 -0
  19. package/dist/authentication.d.ts +13 -11
  20. package/dist/authentication.esm.js +26 -22
  21. package/dist/{authenticationManager-C83GNIhl.d.ts → authenticationManager-CIVY80H9.d.ts} +4 -4
  22. package/dist/{authenticationManager-5M-fKzXx.esm.js → authenticationManager-ZNotsWnC.esm.js} +6 -6
  23. package/dist/{authenticationStateMachine-BMZqatiF.esm.js → authenticationStateMachine-DksVbF_H.esm.js} +21 -9
  24. package/dist/{backCameraStream-DMdMeGk2.esm.js → backCameraStream-D7Wo4Nbx.esm.js} +95 -7
  25. package/dist/{session-CrkWAs-q.esm.js → browserSimulation-B1dWiXp7.esm.js} +61 -476
  26. package/dist/camera.d.ts +4 -3
  27. package/dist/camera.esm.js +4 -3
  28. package/dist/canvas-SKcRBxsk.esm.js +230 -0
  29. package/dist/consent.d.ts +4 -398
  30. package/dist/consent.esm.js +6 -77
  31. package/dist/consentManager-BLd51QiW.d.ts +419 -0
  32. package/dist/consentManager-BYo9Nu1r.esm.js +90 -0
  33. package/dist/{consentStateMachine-CCT-B60O.esm.js → consentStateMachine-BG3yL8aC.esm.js} +9 -6
  34. package/dist/cpf-ocr.d.ts +4 -199
  35. package/dist/cpf-ocr.esm.js +8 -177
  36. package/dist/cpfOcrManager-BnieFXuG.d.ts +216 -0
  37. package/dist/cpfOcrManager-sSKegxox.esm.js +190 -0
  38. package/dist/cross-document-data-match.d.ts +1 -1
  39. package/dist/cross-document-data-match.esm.js +4 -4
  40. package/dist/curp-validation.d.ts +8 -158
  41. package/dist/curp-validation.esm.js +6 -108
  42. package/dist/curpValidationManager-CFem6zP9.esm.js +122 -0
  43. package/dist/curpValidationManager-RttixpIc.d.ts +184 -0
  44. package/dist/{curpValidationStateMachine-CitWLr2c.esm.js → curpValidationStateMachine-B7V_qp66.esm.js} +20 -13
  45. package/dist/custom-fields.d.ts +2 -2
  46. package/dist/custom-fields.esm.js +4 -4
  47. package/dist/custom-watchlist.d.ts +1 -1
  48. package/dist/custom-watchlist.esm.js +4 -41
  49. package/dist/customWatchlistStateMachine-HmFybXLX.esm.js +50 -0
  50. package/dist/{deepsightLoader-Cm4JIT_z.esm.js → deepsightLoader-65k1Appi.esm.js} +19 -10
  51. package/dist/{deepsightService-CEVxzehb.d.ts → deepsightService-B7ShOkWL.d.ts} +8 -160
  52. package/dist/deepsightService-CrHmvx8X.esm.js +276 -0
  53. package/dist/device.esm.js +4 -3
  54. package/dist/document-capture.d.ts +995 -86
  55. package/dist/document-capture.esm.js +34 -8
  56. package/dist/document-upload.d.ts +47 -47
  57. package/dist/document-upload.esm.js +7 -7
  58. package/dist/{documentCaptureStateMachine-BqzTDy9k.esm.js → documentCaptureStateMachine-WYV1r9le.esm.js} +90 -6
  59. package/dist/dynamic-forms.d.ts +20 -5
  60. package/dist/dynamic-forms.esm.js +150 -61
  61. package/dist/ekyb.d.ts +32 -13
  62. package/dist/ekyb.esm.js +25 -15
  63. package/dist/{ekybStateMachine-CyMx_kg-.esm.js → ekybStateMachine-aYixw2sL.esm.js} +319 -207
  64. package/dist/ekyc.d.ts +10 -78
  65. package/dist/ekyc.esm.js +17 -12
  66. package/dist/{ekycStateMachine-oeO0Iekd.esm.js → ekycStateMachine-CXbpaJJn.esm.js} +201 -113
  67. package/dist/electronic-signature.d.ts +3 -3
  68. package/dist/electronic-signature.esm.js +5 -4
  69. package/dist/{electronicSignatureManager-D9OHzTpG.esm.js → electronicSignatureManager-BaECdJ1u.esm.js} +91 -23
  70. package/dist/email.d.ts +4 -3
  71. package/dist/email.esm.js +6 -5
  72. package/dist/{emailManager-wAV0LE-H.esm.js → emailManager--D5G3ChB.esm.js} +30 -7
  73. package/dist/{emailManager-DIfnS5g1.d.ts → emailManager-lAzDoQOs.d.ts} +66 -8
  74. package/dist/{emailStateMachine-DOf4j58N.esm.js → emailStateMachine-CxTOMAjC.esm.js} +46 -11
  75. package/dist/{endpoints-CnN3SyDa.esm.js → endpoints-BeTK0Mlt.esm.js} +6 -3
  76. package/dist/{events-D6-e4vok.esm.js → events-Dvvriq9l.esm.js} +3 -1
  77. package/dist/events.d.ts +2 -0
  78. package/dist/events.esm.js +1 -1
  79. package/dist/extensibility.d.ts +32 -16
  80. package/dist/extensibility.esm.js +55 -33
  81. package/dist/face-match.d.ts +32 -2
  82. package/dist/face-match.esm.js +5 -5
  83. package/dist/{faceCaptureManagerFactory-yqtpxjnN.d.ts → faceCaptureManagerFactory-C_hRHx8a.d.ts} +35 -11
  84. package/dist/{faceCaptureManagerFactory-Dh2PdGlF.esm.js → faceCaptureManagerFactory-kqbUqtrr.esm.js} +21 -5
  85. package/dist/{faceCaptureSetup-B3faSpYA.esm.js → faceCaptureSetup-CtvHWd3x.esm.js} +68 -183
  86. package/dist/{faceMatchStateMachine-DNFrxTFS.esm.js → faceMatchStateMachine-DdGXUBnx.esm.js} +60 -6
  87. package/dist/field-comparison.d.ts +4 -0
  88. package/dist/field-comparison.esm.js +7 -0
  89. package/dist/fieldComparisonManager-Bu5TaSr3.d.ts +76 -0
  90. package/dist/fieldComparisonManager-COGI2ARD.esm.js +162 -0
  91. package/dist/fiscal-qr.d.ts +59 -0
  92. package/dist/fiscal-qr.esm.js +323 -0
  93. package/dist/flow-events.d.ts +6 -5
  94. package/dist/flow.d.ts +23 -15
  95. package/dist/flow.esm.js +63 -17
  96. package/dist/flowCompletionService-BdR2cGgB.d.ts +19 -0
  97. package/dist/flowCompletionService-DdGojV9K.esm.js +20 -0
  98. package/dist/{flowServices-PiNsxLfK.esm.js → flowServices-BTuHLHVr.esm.js} +10 -5
  99. package/dist/geolocation.d.ts +4 -4
  100. package/dist/geolocation.esm.js +6 -6
  101. package/dist/{geolocationStateMachine-asasuHY2.esm.js → geolocationStateMachine-Dvh7X0wF.esm.js} +5 -5
  102. package/dist/getBrowser-C8DP7oTB.esm.js +8 -0
  103. package/dist/{getBrowser-BSXUTWXw.esm.js → getDeviceClass-C0olyNFS.esm.js} +1 -8
  104. package/dist/{getDeviceClass-BSntT9_j.esm.js → getDeviceClass-C8Do2qYu.esm.js} +1 -1
  105. package/dist/government-validation.d.ts +28 -8
  106. package/dist/government-validation.esm.js +19 -8
  107. package/dist/{governmentValidationStateMachine-BDDYrJTo.esm.js → governmentValidationStateMachine-DcJ-BfsC.esm.js} +35 -77
  108. package/dist/home.d.ts +15 -14
  109. package/dist/home.esm.js +2 -2
  110. package/dist/http-Cai3IoLS.esm.js +0 -0
  111. package/dist/http.esm.js +1 -0
  112. package/dist/id-ocr.d.ts +54 -54
  113. package/dist/id-ocr.esm.js +5 -5
  114. package/dist/id-verification.d.ts +27 -27
  115. package/dist/id-verification.esm.js +4 -4
  116. package/dist/id.d.ts +12 -10
  117. package/dist/id.esm.js +36 -26
  118. package/dist/{idCaptureManager-Fyd0eam-.d.ts → idCaptureManager-D-QYESvF.d.ts} +28 -14
  119. package/dist/{idCaptureManager-D0ktk7Hh.esm.js → idCaptureManager-DGVv5l1_.esm.js} +22 -7
  120. package/dist/{idCaptureStateMachine-dwlBUjbC.esm.js → idCaptureStateMachine-DHi7HydI.esm.js} +172 -123
  121. package/dist/{idOcrStateMachine-YbjjC_Gg.esm.js → idOcrStateMachine-CDQ5d_VM.esm.js} +4 -4
  122. package/dist/{idVerificationStateMachine-xbw9HP1Z.esm.js → idVerificationStateMachine-kRxwImzO.esm.js} +2 -2
  123. package/dist/identity-reuse.d.ts +4 -530
  124. package/dist/identity-reuse.esm.js +8 -274
  125. package/dist/identityReuseManager-C6n_97dw.esm.js +95 -0
  126. package/dist/identityReuseManager-DwLtVzUn.d.ts +428 -0
  127. package/dist/identityReuseStateMachine-BfE5YiEr.esm.js +148 -0
  128. package/dist/{index-BcRG8rtJ.d.ts → index-B5hPA0Bg.d.ts} +2 -2
  129. package/dist/{index-ChHWNH48.d.ts → index-B9NysVDB.d.ts} +469 -195
  130. package/dist/index.d.ts +2 -2
  131. package/dist/index.esm.js +10 -8
  132. package/dist/{invokeOnCaptureCallback-rc6kBHo5.esm.js → invokeOnCaptureCallback-ygByVdnn.esm.js} +1 -1
  133. package/dist/{lib-BB0B_qQX.esm.js → lib-BY67lgbq.esm.js} +1 -1
  134. package/dist/mandatory-consent.d.ts +8 -412
  135. package/dist/mandatory-consent.esm.js +6 -76
  136. package/dist/mandatoryConsentManager-H6D18cZB.esm.js +89 -0
  137. package/dist/mandatoryConsentManager-KfIlURRY.d.ts +429 -0
  138. package/dist/{mandatoryConsentStateMachine-Cnco1jvn.esm.js → mandatoryConsentStateMachine-DtQNW1ji.esm.js} +6 -6
  139. package/dist/openviduLazy-B8L--0oe.esm.js +3 -0
  140. package/dist/{openviduLazy-Cok70ZSg.esm.js → openviduLazy-Dh14JNJc.esm.js} +2 -2
  141. package/dist/otp-CGMdUzBC.esm.js +33 -0
  142. package/dist/otp-DF5A0sFx.d.ts +8 -0
  143. package/dist/permissionGuards-C1ispV96.esm.js +23 -0
  144. package/dist/permissionServices-CG3bMSfG.esm.js +130 -0
  145. package/dist/phone.d.ts +4 -3
  146. package/dist/phone.esm.js +6 -5
  147. package/dist/{phoneManager-DAJbGhlY.esm.js → phoneManager-BmF-0Ez4.esm.js} +30 -7
  148. package/dist/{phoneManager-B6M30hKE.d.ts → phoneManager-fPmIBYQK.d.ts} +65 -7
  149. package/dist/{phoneStateMachine-CuPARRaT.esm.js → phoneStateMachine-BiV0yoEx.esm.js} +46 -11
  150. package/dist/{qe-signature-DFo_Cc-I.esm.js → qe-signature-CUYPcHVo.esm.js} +1 -1
  151. package/dist/qe-signature.d.ts +3 -3
  152. package/dist/qe-signature.esm.js +6 -5
  153. package/dist/{recordingService-Ig2UgbLv.esm.js → recordingService-Bn9EdCmz.esm.js} +197 -179
  154. package/dist/redirect-to-mobile.d.ts +6 -104
  155. package/dist/redirect-to-mobile.esm.js +6 -99
  156. package/dist/redirectToMobileManager-BNe3IzC_.d.ts +178 -0
  157. package/dist/redirectToMobileManager-Dy3t7o0C.esm.js +159 -0
  158. package/dist/{redirectToMobileStateMachine-BOEqe46A.esm.js → redirectToMobileStateMachine-DyAdRxfP.esm.js} +28 -19
  159. package/dist/{runChildModule-CqqwqAkW.esm.js → runChildModule-CuoHZ1cx.esm.js} +35 -3
  160. package/dist/selfie.d.ts +13 -11
  161. package/dist/selfie.esm.js +27 -23
  162. package/dist/{selfieManager-Duisl7qN.esm.js → selfieManager-BjCoKRy0.esm.js} +6 -6
  163. package/dist/{selfieManager-D0lSgd-J.d.ts → selfieManager-dUbKRzOh.d.ts} +4 -4
  164. package/dist/{selfieStateMachine-D76whWEf.esm.js → selfieStateMachine-b4F2q9zw.esm.js} +5 -3
  165. package/dist/session-DoVb-OcB.esm.js +152 -0
  166. package/dist/session.d.ts +37 -5
  167. package/dist/session.esm.js +12 -7
  168. package/dist/sessionInitializer-B8H5MsXM.esm.js +366 -0
  169. package/dist/{setup-C5AITV8m.d.ts → setup-BbkprdVv.d.ts} +57 -6
  170. package/dist/{setup-DPPAxmXf.esm.js → setup-BqEfrdja.esm.js} +162 -24
  171. package/dist/signature.d.ts +2 -2
  172. package/dist/signature.esm.js +4 -4
  173. package/dist/{signatureStateMachine-B5-QVUve.esm.js → signatureStateMachine-C5qqYLRz.esm.js} +3 -3
  174. package/dist/stats-BMNUG1AU.esm.js +41 -0
  175. package/dist/stats.d.ts +13 -2
  176. package/dist/stats.esm.js +3 -2
  177. package/dist/trust-graph.d.ts +33 -4
  178. package/dist/trust-graph.esm.js +21 -15
  179. package/dist/{types-CFV9G_7j.d.ts → types-Bj9hdFjU.d.ts} +1 -1
  180. package/dist/{types-BP1m8VRw.d.ts → types-DOUhndhT.d.ts} +14 -2
  181. package/dist/types-DsnEVMhr.esm.js +34 -0
  182. package/dist/types-DvGZI7BF.d.ts +131 -0
  183. package/dist/{types-B06Ypu2F.d.ts → types-NuT8ftBV.d.ts} +1 -1
  184. package/dist/types-ya0LN_MX.d.ts +5 -0
  185. package/dist/{warmup-CEcppFiS.d.ts → warmup-Dg8Lh-50.d.ts} +8 -0
  186. package/dist/wasm.d.ts +6 -4
  187. package/dist/wasm.esm.js +11 -9
  188. package/dist/watchlist-for-business.d.ts +1 -1
  189. package/dist/watchlist-for-business.esm.js +5 -73
  190. package/dist/watchlist.d.ts +1 -1
  191. package/dist/watchlist.esm.js +4 -41
  192. package/dist/watchlistForBusinessStateMachine-DMl8j2Ov.esm.js +74 -0
  193. package/dist/watchlistStateMachine-DmQlqI6L.esm.js +50 -0
  194. package/dist/workflow.d.ts +150 -97
  195. package/dist/workflow.esm.js +156 -80
  196. package/package.json +19 -1
  197. package/dist/StateMachine-BCQrZJhf.d.ts +0 -2
  198. package/dist/WasmUtilProvider-j98OJf-S.esm.js +0 -114
  199. package/dist/browserSimulation-gxD8cSpM.esm.js +0 -20
  200. package/dist/deepsightService-O74l4Y__.esm.js +0 -489
  201. package/dist/displayErrors-DqJ_IbsG.d.ts +0 -39
  202. package/dist/flowCompletionService-DhkT4SRY.d.ts +0 -10
  203. package/dist/flowCompletionService-P54yzGvA.esm.js +0 -13
  204. package/dist/openviduLazy-Cm0XFh_v.esm.js +0 -3
  205. package/dist/permissionServices-D_i6nzEw.esm.js +0 -50
  206. package/dist/stats-CIfiPzb1.esm.js +0 -16
  207. package/dist/types-CAD4va6a.d.ts +0 -5
  208. package/dist/watchlistServices-DMbUhkBX.esm.js +0 -12
  209. /package/dist/{Actor-CI32dTbG.d.ts → Actor-Y0_Fj-KL.d.ts} +0 -0
  210. /package/dist/{ITimerCapability-C67ZRskg.esm.js → ITimerCapability-CB0I1Uf2.esm.js} +0 -0
  211. /package/dist/{Manager-C8PrhBOx.d.ts → Manager-BHn8wH8K.d.ts} +0 -0
  212. /package/dist/{camera-PA2Ljri3.esm.js → camera-DJWm3V4g.esm.js} +0 -0
  213. /package/dist/{camera-DBSxa6ML.d.ts → camera-SRBpPq2X.d.ts} +0 -0
  214. /package/dist/{chunk-CRF6K_H_.esm.js → chunk-CMUKZ2uL.esm.js} +0 -0
  215. /package/dist/{cpf-PPz2Njto.esm.js → cpf-BRzggV8G.esm.js} +0 -0
  216. /package/dist/{dateUtils-UoN5xswP.esm.js → dateUtils-AksLQmgV.esm.js} +0 -0
  217. /package/dist/{platform-CfrjKhmi.esm.js → platform-SKvEfCBh.esm.js} +0 -0
  218. /package/dist/{xstate.esm-B70JrNqo.esm.js → xstate.esm-C9wncMQa.esm.js} +0 -0
@@ -1,7 +1,8 @@
1
1
  import "./api-CESGtpbH.esm.js";
2
- import "./events-D6-e4vok.esm.js";
3
- import "./endpoints-CnN3SyDa.esm.js";
4
- import "./xstate.esm-B70JrNqo.esm.js";
5
- import { a as areAllConsented, i as QE_CONSENT_KEYS, n as electronicSignatureMachine, o as getConsentKeys, r as AE_CONSENT_KEYS, s as getDefaultConsentChecks, t as createElectronicSignatureManager } from "./electronicSignatureManager-D9OHzTpG.esm.js";
2
+ import "./events-Dvvriq9l.esm.js";
3
+ import "./endpoints-BeTK0Mlt.esm.js";
4
+ import "./xstate.esm-C9wncMQa.esm.js";
5
+ import "./apiError-B-j-gyDx.esm.js";
6
+ import { a as areAllConsented, i as QE_CONSENT_KEYS, n as electronicSignatureMachine, o as getConsentKeys, r as AE_CONSENT_KEYS, s as getDefaultConsentChecks, t as createElectronicSignatureManager } from "./electronicSignatureManager-BaECdJ1u.esm.js";
6
7
 
7
8
  export { AE_CONSENT_KEYS, QE_CONSENT_KEYS, areAllConsented, createElectronicSignatureManager, electronicSignatureMachine, getConsentKeys, getDefaultConsentChecks };
@@ -1,7 +1,8 @@
1
1
  import { t as api } from "./api-CESGtpbH.esm.js";
2
- import { n as eventModuleNames, o as createManagerInstrumentation } from "./events-D6-e4vok.esm.js";
3
- import { t as endpoints } from "./endpoints-CnN3SyDa.esm.js";
4
- import { a as fromPromise, c as createManager, r as assign, s as createActor, t as setup } from "./xstate.esm-B70JrNqo.esm.js";
2
+ import { n as eventModuleNames, o as createManagerInstrumentation } from "./events-Dvvriq9l.esm.js";
3
+ import { t as endpoints } from "./endpoints-BeTK0Mlt.esm.js";
4
+ import { a as fromPromise, c as createManager, r as assign, s as createActor, t as setup } from "./xstate.esm-C9wncMQa.esm.js";
5
+ import { n as toIncodeApiError, t as IncodeApiError } from "./apiError-B-j-gyDx.esm.js";
5
6
 
6
7
  //#region ../infra/src/http/externalFetch.ts
7
8
  async function externalFetch(config) {
@@ -27,12 +28,14 @@ function getSignEndpoint(variant) {
27
28
  }
28
29
  async function signDocument(documentRef, variant, signal) {
29
30
  const endpoint = getSignEndpoint(variant);
30
- const res = await api.post(endpoint, {
31
- documentRef,
32
- userConsented: true
33
- }, { signal });
34
- if (!res.ok) throw new Error(`POST ${endpoint} failed: ${res.status} ${res.statusText}`);
35
- return res.data;
31
+ try {
32
+ return (await api.post(endpoint, {
33
+ documentRef,
34
+ userConsented: true
35
+ }, { signal })).data;
36
+ } catch (error) {
37
+ toIncodeApiError(endpoint, error);
38
+ }
36
39
  }
37
40
  async function generateUploadUrl(signal) {
38
41
  const res = await api.post(endpoints.aesGenerateUploadUrl, {}, { signal });
@@ -55,11 +58,16 @@ const fetchUnsignedDocsActor = fromPromise(async ({ signal }) => fetchUnsignedDo
55
58
  const signDocumentsActor = fromPromise(async ({ input, signal }) => {
56
59
  return (await Promise.all(input.documents.map((doc) => signDocument(doc.documentRef, input.variant, signal)))).map((r) => ({ signedDocumentUrl: r.signedDocumentUrl }));
57
60
  });
58
- const uploadDocumentActor = fromPromise(async ({ input, signal }) => {
61
+ /**
62
+ * Generates the upload destination. `POST /generateDocumentUploadUrl` creates a
63
+ * server-side document, so this must run at most once per session — the machine
64
+ * caches the result and reuses it across upload retries.
65
+ */
66
+ const generateUploadUrlActor = fromPromise(async ({ signal }) => generateUploadUrl(signal));
67
+ const uploadFileActor = fromPromise(async ({ input, signal }) => {
59
68
  const fileData = input.getFileData();
60
69
  if (!fileData) throw new Error("No file data available for upload");
61
- const { preSignedUrl } = await generateUploadUrl(signal);
62
- await uploadDocumentFile(preSignedUrl, fileData, signal);
70
+ await uploadDocumentFile(input.preSignedUrl, fileData, signal);
63
71
  });
64
72
 
65
73
  //#endregion
@@ -89,6 +97,26 @@ function areAllConsented(checks) {
89
97
 
90
98
  //#endregion
91
99
  //#region src/modules/electronic-signature/electronicSignatureStateMachine.ts
100
+ /**
101
+ * The `/process/sign` (and `/process/signQes`) endpoint can fail in many ways,
102
+ * but only three of them are recoverable by retrying with the same payload:
103
+ * - HTTP 500 (transient backend failure)
104
+ * - HTTP 409 (signing conflict — typically resolves on retry)
105
+ * - HTTP 400 with a body message containing "Signature failed"
106
+ * (recoverable signing-pipeline error; other 400s mean the request itself
107
+ * is bad and a retry will fail identically).
108
+ *
109
+ * All other failures (auth, validation, network, etc.) are surfaced as a
110
+ * terminal `failed` state so the host receives `onError` immediately instead
111
+ * of being offered a Try Again that cannot succeed.
112
+ */
113
+ function isRetryableSignError(error) {
114
+ if (!(error instanceof IncodeApiError)) return false;
115
+ if (error.httpStatus === 500) return true;
116
+ if (error.httpStatus === 409) return true;
117
+ if (error.httpStatus === 400 && error.message.includes("Signature failed")) return true;
118
+ return false;
119
+ }
92
120
  const electronicSignatureMachine = setup({
93
121
  types: {
94
122
  context: {},
@@ -98,7 +126,8 @@ const electronicSignatureMachine = setup({
98
126
  actors: {
99
127
  fetchUnsignedDocs: fetchUnsignedDocsActor,
100
128
  signDocuments: signDocumentsActor,
101
- uploadDocument: uploadDocumentActor
129
+ generateUploadUrl: generateUploadUrlActor,
130
+ uploadFile: uploadFileActor
102
131
  },
103
132
  actions: {
104
133
  setDocuments: assign(({ event }) => {
@@ -117,6 +146,10 @@ const electronicSignatureMachine = setup({
117
146
  fileUrl
118
147
  };
119
148
  }),
149
+ setUploadUrl: assign(({ event }) => {
150
+ const { output } = event;
151
+ return { preSignedUrl: output.preSignedUrl };
152
+ }),
120
153
  updateConsent: assign(({ context, event }) => {
121
154
  const { name, checked } = event;
122
155
  return { consentChecks: {
@@ -131,7 +164,7 @@ const electronicSignatureMachine = setup({
131
164
  errorFromUpload: ({ context }) => context.errorSource === "upload",
132
165
  errorFromSigning: ({ context }) => context.errorSource === "signing",
133
166
  shouldUpload: ({ context }) => context.config.uploadDocument === true,
134
- shouldDownload: ({ context }) => context.config.downloadDocument === true,
167
+ hasUploadUrl: ({ context }) => context.preSignedUrl !== null,
135
168
  allConsented: ({ context }) => areAllConsented(context.consentChecks),
136
169
  hasDocuments: ({ event }) => {
137
170
  const { output } = event;
@@ -144,7 +177,8 @@ const electronicSignatureMachine = setup({
144
177
  allSignedAndDownload: ({ context, event }) => {
145
178
  const { output } = event;
146
179
  return output.every((d) => !!d.signedDocumentUrl) && context.config.downloadDocument === true;
147
- }
180
+ },
181
+ isRetryableSignError: ({ event }) => isRetryableSignError(event.error)
148
182
  }
149
183
  }).createMachine({
150
184
  id: "electronicSignature",
@@ -157,6 +191,7 @@ const electronicSignatureMachine = setup({
157
191
  fileName: null,
158
192
  fileSize: null,
159
193
  fileUrl: null,
194
+ preSignedUrl: null,
160
195
  consentChecks: getDefaultConsentChecks(input.config.variant ?? "ae"),
161
196
  viewingDocumentUrl: null,
162
197
  errorMessage: "",
@@ -183,13 +218,34 @@ const electronicSignatureMachine = setup({
183
218
  fileUrl: () => null
184
219
  })
185
220
  },
186
- CONFIRM_FILE: { target: "uploadingFile" },
221
+ CONFIRM_FILE: [{
222
+ target: "uploadingFile",
223
+ guard: "hasUploadUrl"
224
+ }, { target: "generatingUploadUrl" }],
187
225
  CLOSE: { target: "closed" }
188
226
  } },
227
+ generatingUploadUrl: { invoke: {
228
+ id: "generateUploadUrl",
229
+ src: "generateUploadUrl",
230
+ onDone: {
231
+ target: "uploadingFile",
232
+ actions: "setUploadUrl"
233
+ },
234
+ onError: {
235
+ target: "error",
236
+ actions: assign(({ event }) => ({
237
+ errorMessage: String(event.error ?? "aes.error"),
238
+ errorSource: "upload"
239
+ }))
240
+ }
241
+ } },
189
242
  uploadingFile: { invoke: {
190
- id: "uploadDocument",
191
- src: "uploadDocument",
192
- input: ({ context }) => ({ getFileData: context.getFileData }),
243
+ id: "uploadFile",
244
+ src: "uploadFile",
245
+ input: ({ context }) => ({
246
+ preSignedUrl: context.preSignedUrl,
247
+ getFileData: context.getFileData
248
+ }),
193
249
  onDone: { target: "fetchingDocs" },
194
250
  onError: {
195
251
  target: "error",
@@ -257,13 +313,20 @@ const electronicSignatureMachine = setup({
257
313
  })
258
314
  }
259
315
  ],
260
- onError: {
316
+ onError: [{
261
317
  target: "error",
318
+ guard: "isRetryableSignError",
262
319
  actions: assign(({ event }) => ({
263
320
  errorMessage: String(event.error ?? "aes.error"),
264
321
  errorSource: "signing"
265
322
  }))
266
- }
323
+ }, {
324
+ target: "failed",
325
+ actions: assign(({ event }) => ({
326
+ errorMessage: String(event.error ?? "aes.error"),
327
+ errorSource: "signing"
328
+ }))
329
+ }]
267
330
  } },
268
331
  success: { after: { 3e3: "finished" } },
269
332
  successDownload: { on: {
@@ -302,7 +365,8 @@ const electronicSignatureMachine = setup({
302
365
  CLOSE: { target: "closed" }
303
366
  } },
304
367
  finished: { type: "final" },
305
- closed: { type: "final" }
368
+ closed: { type: "final" },
369
+ failed: { type: "final" }
306
370
  }
307
371
  });
308
372
 
@@ -319,7 +383,7 @@ function createElectronicSignatureActor(options) {
319
383
  //#region src/modules/electronic-signature/electronicSignatureManager.ts
320
384
  function mapState(snapshot) {
321
385
  const { context } = snapshot;
322
- if (snapshot.matches("idle") || snapshot.matches("fetchingDocs") || snapshot.matches("uploadingFile")) return { status: "loading" };
386
+ if (snapshot.matches("idle") || snapshot.matches("fetchingDocs") || snapshot.matches("generatingUploadUrl") || snapshot.matches("uploadingFile")) return { status: "loading" };
323
387
  if (snapshot.matches("uploading")) return {
324
388
  status: "uploading",
325
389
  fileName: context.fileName
@@ -347,6 +411,10 @@ function mapState(snapshot) {
347
411
  status: "error",
348
412
  errorMessage: context.errorMessage
349
413
  };
414
+ if (snapshot.matches("failed")) return {
415
+ status: "failed",
416
+ errorMessage: context.errorMessage
417
+ };
350
418
  if (snapshot.matches("finished")) return { status: "finished" };
351
419
  if (snapshot.matches("closed")) return { status: "closed" };
352
420
  throw new Error(`Unhandled electronic-signature state: ${JSON.stringify(snapshot.value)}`);
package/dist/email.d.ts CHANGED
@@ -1,4 +1,5 @@
1
- import "./Manager-C8PrhBOx.js";
2
- import "./Actor-CI32dTbG.js";
3
- import { a as emailMachine, n as EmailState, o as EmailConfig, r as createEmailManager, t as EmailManager } from "./emailManager-DIfnS5g1.js";
1
+ import "./Manager-BHn8wH8K.js";
2
+ import "./Actor-Y0_Fj-KL.js";
3
+ import { n as EmailState, o as emailMachine, r as createEmailManager, s as EmailConfig, t as EmailManager } from "./emailManager-lAzDoQOs.js";
4
+ import "./otp-DF5A0sFx.js";
4
5
  export { type EmailConfig, type EmailManager, type EmailState, createEmailManager, emailMachine };
package/dist/email.esm.js CHANGED
@@ -1,9 +1,10 @@
1
1
  import "./BrowserTimerProvider-DhNc_x02.esm.js";
2
2
  import "./api-CESGtpbH.esm.js";
3
- import "./events-D6-e4vok.esm.js";
4
- import "./endpoints-CnN3SyDa.esm.js";
5
- import "./xstate.esm-B70JrNqo.esm.js";
6
- import { t as emailMachine } from "./emailStateMachine-DOf4j58N.esm.js";
7
- import { t as createEmailManager } from "./emailManager-wAV0LE-H.esm.js";
3
+ import "./events-Dvvriq9l.esm.js";
4
+ import "./endpoints-BeTK0Mlt.esm.js";
5
+ import "./xstate.esm-C9wncMQa.esm.js";
6
+ import { t as emailMachine } from "./emailStateMachine-CxTOMAjC.esm.js";
7
+ import "./otp-CGMdUzBC.esm.js";
8
+ import { t as createEmailManager } from "./emailManager--D5G3ChB.esm.js";
8
9
 
9
10
  export { createEmailManager, emailMachine };
@@ -1,6 +1,7 @@
1
- import { n as eventModuleNames, o as createManagerInstrumentation } from "./events-D6-e4vok.esm.js";
2
- import { c as createManager, s as createActor } from "./xstate.esm-B70JrNqo.esm.js";
3
- import { t as emailMachine } from "./emailStateMachine-DOf4j58N.esm.js";
1
+ import { n as eventModuleNames, o as createManagerInstrumentation } from "./events-Dvvriq9l.esm.js";
2
+ import { c as createManager, s as createActor } from "./xstate.esm-C9wncMQa.esm.js";
3
+ import { t as emailMachine } from "./emailStateMachine-CxTOMAjC.esm.js";
4
+ import { t as OTP_CODE_LENGTH } from "./otp-CGMdUzBC.esm.js";
4
5
 
5
6
  //#region src/modules/email/emailActor.ts
6
7
  function createEmailActor(options) {
@@ -105,28 +106,44 @@ function mapState(snapshot) {
105
106
  status: "inputting",
106
107
  prefilledEmail: context.prefilledEmail,
107
108
  emailError: context.emailError,
109
+ validationErrors: context.validationErrors,
110
+ isValid: Object.keys(context.validationErrors ?? {}).length === 0,
108
111
  otpVerification: context.config.otpVerification
109
112
  };
110
113
  if (typedSnapshot.matches("submitting")) return { status: "submitting" };
111
- if (typedSnapshot.matches("resendingOtp")) return { status: "resendingOtp" };
114
+ if (typedSnapshot.matches("resendingOtp")) return {
115
+ status: "resendingOtp",
116
+ otpCode: context.otpCode,
117
+ otpLength: OTP_CODE_LENGTH
118
+ };
112
119
  if (typedSnapshot.matches("sendingInitialOtp")) return { status: "sendingInitialOtp" };
113
120
  if (typedSnapshot.matches("awaitingOtp")) return {
114
121
  status: "awaitingOtp",
115
122
  resendTimer: context.resendTimer,
116
123
  canResend: !context.resendTimerActive,
117
- attemptsRemaining: context.attemptsRemaining
124
+ attemptsRemaining: context.attemptsRemaining,
125
+ otpCode: context.otpCode,
126
+ otpLength: OTP_CODE_LENGTH,
127
+ otpValidationErrors: context.otpValidationErrors,
128
+ isOtpValid: Object.keys(context.otpValidationErrors ?? {}).length === 0
118
129
  };
119
130
  if (typedSnapshot.matches("verifyingOtp")) return {
120
131
  status: "verifyingOtp",
121
132
  resendTimer: context.resendTimer,
122
- canResend: !context.resendTimerActive
133
+ canResend: !context.resendTimerActive,
134
+ otpCode: context.otpCode,
135
+ otpLength: OTP_CODE_LENGTH
123
136
  };
124
137
  if (typedSnapshot.matches("otpError")) return {
125
138
  status: "otpError",
126
139
  otpError: context.otpError ?? "Invalid OTP code",
127
140
  attemptsRemaining: context.attemptsRemaining,
128
141
  resendTimer: context.resendTimer,
129
- canResend: !context.resendTimerActive
142
+ canResend: !context.resendTimerActive,
143
+ otpCode: context.otpCode,
144
+ otpLength: OTP_CODE_LENGTH,
145
+ otpValidationErrors: context.otpValidationErrors,
146
+ isOtpValid: Object.keys(context.otpValidationErrors ?? {}).length === 0
130
147
  };
131
148
  if (typedSnapshot.matches("finished")) return { status: "finished" };
132
149
  if (typedSnapshot.matches("error")) return {
@@ -147,6 +164,9 @@ function createApi({ actor, trackElementClicked }) {
147
164
  isValid
148
165
  });
149
166
  },
167
+ validateEmail() {
168
+ actor.send({ type: "VALIDATE_EMAIL" });
169
+ },
150
170
  submit() {
151
171
  trackElementClicked?.("submit");
152
172
  actor.send({ type: "SUBMIT" });
@@ -157,6 +177,9 @@ function createApi({ actor, trackElementClicked }) {
157
177
  code
158
178
  });
159
179
  },
180
+ validateOtp() {
181
+ actor.send({ type: "VALIDATE_OTP" });
182
+ },
160
183
  submitOtp(code) {
161
184
  trackElementClicked?.("submitOtp");
162
185
  actor.send({
@@ -1,5 +1,6 @@
1
- import { t as Manager } from "./Manager-C8PrhBOx.js";
2
- import { t as ActorRefFrom } from "./Actor-CI32dTbG.js";
1
+ import { t as Manager } from "./Manager-BHn8wH8K.js";
2
+ import { t as ActorRefFrom } from "./Actor-Y0_Fj-KL.js";
3
+ import { t as OtpValidationErrors } from "./otp-DF5A0sFx.js";
3
4
 
4
5
  //#region src/modules/email/types.d.ts
5
6
 
@@ -49,6 +50,9 @@ type EmailConfig = {
49
50
  */
50
51
  maxOtpAttempts?: number;
51
52
  };
53
+ type EmailValidationErrors = {
54
+ email?: string;
55
+ };
52
56
  //#endregion
53
57
  //#region src/modules/email/emailStateMachine.d.ts
54
58
 
@@ -73,13 +77,17 @@ type EmailLoadingPrefillState = {
73
77
  /**
74
78
  * Ready for email input - use `setEmail()` and `submit()`
75
79
  * @property prefilledEmail - Pre-populated email address (if prefill enabled)
76
- * @property emailError - Validation error message if email was rejected
80
+ * @property emailError - Server-side validation error message if email was rejected
81
+ * @property validationErrors - Client-side validation errors (e.g. invalid/empty email). Surfaced on blur and submit.
82
+ * @property isValid - True iff `validationErrors` is empty. Optimistic semantic: starts true on initial render.
77
83
  * @property otpVerification - Whether OTP email verification is enabled (from module config). When omitted, treat as `false`.
78
84
  */
79
85
  type EmailInputtingState = {
80
86
  status: 'inputting';
81
87
  prefilledEmail?: string;
82
88
  emailError?: string;
89
+ validationErrors?: EmailValidationErrors;
90
+ isValid: boolean;
83
91
  otpVerification?: boolean;
84
92
  };
85
93
  /** Email address is being submitted to the backend */
@@ -89,6 +97,10 @@ type EmailSubmittingState = {
89
97
  /** OTP is being sent to the email address */
90
98
  type EmailResendingOtpState = {
91
99
  status: 'resendingOtp';
100
+ /** The OTP code entered so far (controlled-input value, kept visible while disabled) */
101
+ otpCode: string;
102
+ /** Expected OTP length (owned by Core) */
103
+ otpLength: number;
92
104
  };
93
105
  /** OTP is being sent initialy to the email address */
94
106
  type EmailSendingInitialOtpState = {
@@ -99,22 +111,34 @@ type EmailSendingInitialOtpState = {
99
111
  * @property resendTimer - Seconds remaining before resend is allowed
100
112
  * @property canResend - Whether the resend button should be enabled
101
113
  * @property attemptsRemaining - Number of OTP verification attempts left
114
+ * @property otpCode - The OTP code entered so far (controlled-input value)
115
+ * @property otpLength - Expected OTP length (owned by Core; the UI should not hardcode it)
116
+ * @property otpValidationErrors - Client-side OTP errors (e.g. incomplete code). Surfaced on blur and submit.
117
+ * @property isOtpValid - True iff `otpValidationErrors` is empty. Optimistic semantic: starts true.
102
118
  */
103
119
  type EmailAwaitingOtpState = {
104
120
  status: 'awaitingOtp';
105
121
  resendTimer: number;
106
122
  canResend: boolean;
107
123
  attemptsRemaining: number;
124
+ otpCode: string;
125
+ otpLength: number;
126
+ otpValidationErrors?: OtpValidationErrors;
127
+ isOtpValid: boolean;
108
128
  };
109
129
  /**
110
130
  * OTP code is being verified against the backend
111
131
  * @property resendTimer - Seconds remaining on resend cooldown (unchanged while verifying)
112
132
  * @property canResend - Whether resend is allowed (cooldown finished)
133
+ * @property otpCode - The code being verified (controlled-input value, kept visible while disabled)
134
+ * @property otpLength - Expected OTP length (owned by Core)
113
135
  */
114
136
  type EmailVerifyingOtpState = {
115
137
  status: 'verifyingOtp';
116
138
  resendTimer: number;
117
139
  canResend: boolean;
140
+ otpCode: string;
141
+ otpLength: number;
118
142
  };
119
143
  /**
120
144
  * OTP verification failed - user can retry with `submitOtp()`
@@ -122,6 +146,10 @@ type EmailVerifyingOtpState = {
122
146
  * @property attemptsRemaining - Number of remaining attempts before lockout
123
147
  * @property resendTimer - Seconds remaining on resend cooldown (same as awaiting OTP)
124
148
  * @property canResend - Whether resend is allowed (cooldown finished)
149
+ * @property otpCode - The OTP code entered so far (controlled-input value)
150
+ * @property otpLength - Expected OTP length (owned by Core)
151
+ * @property otpValidationErrors - Client-side OTP errors (e.g. incomplete code). Server `otpError` takes precedence in the UI.
152
+ * @property isOtpValid - True iff `otpValidationErrors` is empty. Optimistic semantic: starts true.
125
153
  */
126
154
  type EmailOtpErrorState = {
127
155
  status: 'otpError';
@@ -129,6 +157,10 @@ type EmailOtpErrorState = {
129
157
  attemptsRemaining: number;
130
158
  resendTimer: number;
131
159
  canResend: boolean;
160
+ otpCode: string;
161
+ otpLength: number;
162
+ otpValidationErrors?: OtpValidationErrors;
163
+ isOtpValid: boolean;
132
164
  };
133
165
  /** Email verification completed successfully */
134
166
  type EmailFinishedState = {
@@ -218,10 +250,16 @@ declare function createEmailManager(options: CreateEmailActorOptions): Manager<E
218
250
  * ```
219
251
  */
220
252
  setEmail(email: string, isValid: boolean): void;
253
+ /**
254
+ * Validates the current email address (e.g., on blur).
255
+ * Populates or clears `validationErrors.email` on the 'inputting' state.
256
+ */
257
+ validateEmail(): void;
221
258
  /**
222
259
  * Submits the email address for verification.
223
- * Requires a valid email address to be set via `setEmail()`.
224
- * Transitions to 'submitting', then to 'sendingInitialOtp' or 'success' (if no OTP).
260
+ * Runs full validation first: if the email is empty or invalid, populates
261
+ * `validationErrors` and stays on 'inputting'; otherwise transitions to
262
+ * 'submitting', then to 'sendingInitialOtp' or 'finished' (if no OTP).
225
263
  */
226
264
  submit(): void;
227
265
  /**
@@ -231,6 +269,12 @@ declare function createEmailManager(options: CreateEmailActorOptions): Manager<E
231
269
  * @param code - The OTP code entered by the user
232
270
  */
233
271
  setOtpCode(code: string): void;
272
+ /**
273
+ * Validates the current OTP code (e.g. on blur), without submitting.
274
+ * Populates or clears `otpValidationErrors.otp` on the 'awaitingOtp' /
275
+ * 'otpError' states (incomplete code → `isOtpValid` becomes false).
276
+ */
277
+ validateOtp(): void;
234
278
  /**
235
279
  * Sets and submits the OTP code in one call.
236
280
  * Should be called when state is 'awaitingOtp' or 'otpError'.
@@ -286,10 +330,16 @@ declare function createEmailManagerFromActor(actor: EmailActor): Manager<EmailSt
286
330
  * ```
287
331
  */
288
332
  setEmail(email: string, isValid: boolean): void;
333
+ /**
334
+ * Validates the current email address (e.g., on blur).
335
+ * Populates or clears `validationErrors.email` on the 'inputting' state.
336
+ */
337
+ validateEmail(): void;
289
338
  /**
290
339
  * Submits the email address for verification.
291
- * Requires a valid email address to be set via `setEmail()`.
292
- * Transitions to 'submitting', then to 'sendingInitialOtp' or 'success' (if no OTP).
340
+ * Runs full validation first: if the email is empty or invalid, populates
341
+ * `validationErrors` and stays on 'inputting'; otherwise transitions to
342
+ * 'submitting', then to 'sendingInitialOtp' or 'finished' (if no OTP).
293
343
  */
294
344
  submit(): void;
295
345
  /**
@@ -299,6 +349,12 @@ declare function createEmailManagerFromActor(actor: EmailActor): Manager<EmailSt
299
349
  * @param code - The OTP code entered by the user
300
350
  */
301
351
  setOtpCode(code: string): void;
352
+ /**
353
+ * Validates the current OTP code (e.g. on blur), without submitting.
354
+ * Populates or clears `otpValidationErrors.otp` on the 'awaitingOtp' /
355
+ * 'otpError' states (incomplete code → `isOtpValid` becomes false).
356
+ */
357
+ validateOtp(): void;
302
358
  /**
303
359
  * Sets and submits the OTP code in one call.
304
360
  * Should be called when state is 'awaitingOtp' or 'otpError'.
@@ -340,8 +396,10 @@ declare function createEmailManagerFromActor(actor: EmailActor): Manager<EmailSt
340
396
  * @property stop - Stops the manager and cleans up resources
341
397
  * @property load - Initializes the verification flow
342
398
  * @property setEmail - Sets the email address
399
+ * @property validateEmail - Validates the current email (e.g. on blur)
343
400
  * @property submit - Submits the email address
344
401
  * @property setOtpCode - Sets OTP code without submitting
402
+ * @property validateOtp - Validates the current OTP (e.g. on blur)
345
403
  * @property submitOtp - Sets and submits OTP code
346
404
  * @property resendOtp - Requests new OTP code
347
405
  * @property back - Returns to email input from OTP screen
@@ -349,4 +407,4 @@ declare function createEmailManagerFromActor(actor: EmailActor): Manager<EmailSt
349
407
  */
350
408
  type EmailManager = ReturnType<typeof createEmailManager>;
351
409
  //#endregion
352
- export { emailMachine as a, createEmailManagerFromActor as i, EmailState as n, EmailConfig as o, createEmailManager as r, EmailManager as t };
410
+ export { EmailActor as a, createEmailManagerFromActor as i, EmailState as n, emailMachine as o, createEmailManager as r, EmailConfig as s, EmailManager as t };
@@ -1,7 +1,8 @@
1
1
  import { t as BrowserTimerProvider } from "./BrowserTimerProvider-DhNc_x02.esm.js";
2
2
  import { t as api } from "./api-CESGtpbH.esm.js";
3
- import { t as endpoints } from "./endpoints-CnN3SyDa.esm.js";
4
- import { a as fromPromise, i as fromCallback, r as assign, t as setup } from "./xstate.esm-B70JrNqo.esm.js";
3
+ import { t as endpoints } from "./endpoints-BeTK0Mlt.esm.js";
4
+ import { a as fromPromise, i as fromCallback, r as assign, t as setup } from "./xstate.esm-C9wncMQa.esm.js";
5
+ import { n as computeOtpValidationErrors, r as isOtpComplete } from "./otp-CGMdUzBC.esm.js";
5
6
 
6
7
  //#region src/modules/email/emailServices.ts
7
8
  function getEmailServerFailureReason(error, invalidStatus) {
@@ -41,6 +42,10 @@ function getErrorMessage(error) {
41
42
  if (error instanceof Error) return error.message;
42
43
  return String(error);
43
44
  }
45
+ function computeEmailValidationErrors(context) {
46
+ if (context.email.trim().length === 0 || !context.isValid) return { email: "invalidEmail" };
47
+ return {};
48
+ }
44
49
  const RESEND_TIMER_SECONDS = 30;
45
50
  const emailMachine = setup({
46
51
  types: {
@@ -86,17 +91,31 @@ const emailMachine = setup({
86
91
  return {
87
92
  email: e.email,
88
93
  isValid: e.isValid,
89
- emailError: void 0
94
+ emailError: void 0,
95
+ validationErrors: void 0
90
96
  };
91
97
  }),
98
+ validateEmailField: assign(({ context }) => {
99
+ const errors = computeEmailValidationErrors(context);
100
+ return { validationErrors: errors.email ? errors : void 0 };
101
+ }),
102
+ computeValidationResult: assign(({ context }) => {
103
+ const errors = computeEmailValidationErrors(context);
104
+ return { validationErrors: errors.email ? errors : void 0 };
105
+ }),
92
106
  setEmailError: assign(({ event }) => ({ emailError: getErrorMessage(event.error) })),
93
107
  setError: assign(({ event }) => ({ error: getErrorMessage(event.error) })),
94
108
  clearError: assign({ error: () => void 0 }),
95
109
  clearEmailError: assign({ emailError: () => void 0 }),
96
110
  setOtpCode: assign(({ event }) => ({
97
111
  otpCode: event.code,
98
- otpError: void 0
112
+ otpError: void 0,
113
+ otpValidationErrors: void 0
99
114
  })),
115
+ validateOtpField: assign(({ context }) => {
116
+ const errors = computeOtpValidationErrors(context.otpCode);
117
+ return { otpValidationErrors: errors.otp ? errors : void 0 };
118
+ }),
100
119
  setOtpError: assign(({ context, event }) => ({
101
120
  otpError: getErrorMessage(event.error),
102
121
  attemptsRemaining: context.attemptsRemaining - 1
@@ -104,7 +123,8 @@ const emailMachine = setup({
104
123
  setOtpRequestError: assign(({ event }) => ({ otpError: getErrorMessage(event.error) })),
105
124
  clearOtpError: assign({
106
125
  otpError: () => void 0,
107
- otpCode: () => ""
126
+ otpCode: () => "",
127
+ otpValidationErrors: () => void 0
108
128
  }),
109
129
  startResendTimer: assign({
110
130
  resendTimer: () => RESEND_TIMER_SECONDS,
@@ -122,10 +142,12 @@ const emailMachine = setup({
122
142
  email: "",
123
143
  isValid: false,
124
144
  emailError: void 0,
145
+ validationErrors: void 0,
125
146
  prefilledEmail: void 0,
126
147
  error: void 0,
127
148
  otpCode: "",
128
149
  otpError: void 0,
150
+ otpValidationErrors: void 0,
129
151
  attemptsRemaining: context.config.maxOtpAttempts ?? 3,
130
152
  resendTimer: 0,
131
153
  resendTimerActive: false
@@ -134,8 +156,9 @@ const emailMachine = setup({
134
156
  guards: {
135
157
  hasPrefill: ({ context }) => context.config.prefill === true,
136
158
  hasOtpVerification: ({ context }) => context.config.otpVerification,
137
- isValidEmail: ({ context }) => context.isValid,
159
+ hasNoValidationErrors: ({ context }) => !context.validationErrors || Object.keys(context.validationErrors).length === 0,
138
160
  hasAttemptsRemaining: ({ context }) => context.attemptsRemaining > 1,
161
+ hasCompleteOtp: ({ context }) => isOtpComplete(context.otpCode),
139
162
  canResend: ({ context }) => !context.resendTimerActive
140
163
  }
141
164
  }).createMachine({
@@ -146,10 +169,12 @@ const emailMachine = setup({
146
169
  email: "",
147
170
  isValid: false,
148
171
  emailError: void 0,
172
+ validationErrors: void 0,
149
173
  prefilledEmail: void 0,
150
174
  error: void 0,
151
175
  otpCode: "",
152
176
  otpError: void 0,
177
+ otpValidationErrors: void 0,
153
178
  attemptsRemaining: input.config.maxOtpAttempts ?? 3,
154
179
  resendTimer: 0,
155
180
  resendTimerActive: false
@@ -170,12 +195,17 @@ const emailMachine = setup({
170
195
  } },
171
196
  inputting: { on: {
172
197
  EMAIL_CHANGED: { actions: "setEmail" },
173
- SUBMIT: {
198
+ VALIDATE_EMAIL: { actions: "validateEmailField" },
199
+ SUBMIT: { target: "validatingSubmit" }
200
+ } },
201
+ validatingSubmit: {
202
+ entry: "computeValidationResult",
203
+ always: [{
204
+ guard: "hasNoValidationErrors",
174
205
  target: "submitting",
175
- guard: "isValidEmail",
176
206
  actions: "clearEmailError"
177
- }
178
- } },
207
+ }, { target: "inputting" }]
208
+ },
179
209
  submitting: { invoke: {
180
210
  id: "submitEmail",
181
211
  src: "submitEmail",
@@ -222,7 +252,11 @@ const emailMachine = setup({
222
252
  on: {
223
253
  TICK: { actions: "tickResendTimer" },
224
254
  OTP_CHANGED: { actions: "setOtpCode" },
225
- VERIFY_OTP: { target: "verifyingOtp" },
255
+ VALIDATE_OTP: { actions: "validateOtpField" },
256
+ VERIFY_OTP: [{
257
+ guard: "hasCompleteOtp",
258
+ target: "verifyingOtp"
259
+ }, { actions: "validateOtpField" }],
226
260
  RESEND_OTP: {
227
261
  target: "resendingOtp",
228
262
  guard: "canResend"
@@ -273,6 +307,7 @@ const emailMachine = setup({
273
307
  target: "awaitingOtp",
274
308
  actions: "setOtpCode"
275
309
  },
310
+ VALIDATE_OTP: { actions: "validateOtpField" },
276
311
  RESEND_OTP: {
277
312
  target: "resendingOtp",
278
313
  guard: "canResend"