@incodetech/core 2.0.0-alpha.8 → 2.0.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 (184) hide show
  1. package/dist/Actor-CI32dTbG.d.ts +2 -0
  2. package/dist/BaseWasmProvider-C_DLEI40.esm.js +1118 -0
  3. package/dist/BrowserStorageProvider-CuOW1Er2.esm.js +55 -0
  4. package/dist/BrowserTimerProvider-DhNc_x02.esm.js +22 -0
  5. package/dist/ITimerCapability-C67ZRskg.esm.js +7 -0
  6. package/dist/IpifyProvider-D7jx52AL.esm.js +139 -0
  7. package/dist/MotionSensorProvider-4v7xkqAp.esm.js +254 -0
  8. package/dist/OpenViduRecordingProvider-CMu6XVdc.esm.js +87 -0
  9. package/dist/StateMachine-BCQrZJhf.d.ts +2 -0
  10. package/dist/WasmUtilProvider-j98OJf-S.esm.js +114 -0
  11. package/dist/addressSearch-BpTbTWCa.esm.js +430 -0
  12. package/dist/ae-signature-DDDZmWXj.esm.js +12 -0
  13. package/dist/ae-signature.d.ts +25 -0
  14. package/dist/ae-signature.esm.js +8 -0
  15. package/dist/antifraud.d.ts +57 -0
  16. package/dist/antifraud.esm.js +45 -0
  17. package/dist/antifraudStateMachine-O0TMf6yc.esm.js +39 -0
  18. package/dist/api-CESGtpbH.esm.js +53 -0
  19. package/dist/authentication.d.ts +12 -0
  20. package/dist/authentication.esm.js +25 -0
  21. package/dist/authenticationManager-5M-fKzXx.esm.js +67 -0
  22. package/dist/authenticationManager-C83GNIhl.d.ts +66 -0
  23. package/dist/authenticationStateMachine-BMZqatiF.esm.js +139 -0
  24. package/dist/backCameraStream-DMdMeGk2.esm.js +346 -0
  25. package/dist/browserSimulation-gxD8cSpM.esm.js +20 -0
  26. package/dist/camera-DBSxa6ML.d.ts +4 -0
  27. package/dist/camera-PA2Ljri3.esm.js +22 -0
  28. package/dist/camera.d.ts +15 -0
  29. package/dist/camera.esm.js +5 -0
  30. package/dist/consent.d.ts +398 -0
  31. package/dist/consent.esm.js +79 -0
  32. package/dist/consentStateMachine-CCT-B60O.esm.js +151 -0
  33. package/dist/cpf-PPz2Njto.esm.js +38 -0
  34. package/dist/cpf-ocr.d.ts +204 -0
  35. package/dist/cpf-ocr.esm.js +177 -0
  36. package/dist/cross-document-data-match.d.ts +34 -0
  37. package/dist/cross-document-data-match.esm.js +71 -0
  38. package/dist/curp-validation.d.ts +188 -0
  39. package/dist/curp-validation.esm.js +110 -0
  40. package/dist/curpValidationStateMachine-CitWLr2c.esm.js +595 -0
  41. package/dist/custom-fields.d.ts +115 -0
  42. package/dist/custom-fields.esm.js +177 -0
  43. package/dist/custom-watchlist.d.ts +66 -0
  44. package/dist/custom-watchlist.esm.js +86 -0
  45. package/dist/dateUtils-UoN5xswP.esm.js +23 -0
  46. package/dist/deepsightLoader-Cm4JIT_z.esm.js +52 -0
  47. package/dist/deepsightService-CEVxzehb.d.ts +412 -0
  48. package/dist/deepsightService-O74l4Y__.esm.js +489 -0
  49. package/dist/device.d.ts +46 -0
  50. package/dist/device.esm.js +106 -0
  51. package/dist/displayErrors-DqJ_IbsG.d.ts +39 -0
  52. package/dist/document-capture.d.ts +906 -0
  53. package/dist/document-capture.esm.js +156 -0
  54. package/dist/document-upload.d.ts +331 -0
  55. package/dist/document-upload.esm.js +203 -0
  56. package/dist/documentCaptureStateMachine-BqzTDy9k.esm.js +394 -0
  57. package/dist/dynamic-forms.d.ts +178 -0
  58. package/dist/dynamic-forms.esm.js +323 -0
  59. package/dist/ekyb.d.ts +148 -0
  60. package/dist/ekyb.esm.js +127 -0
  61. package/dist/ekybStateMachine-B59rQjgj.esm.js +674 -0
  62. package/dist/ekyc.d.ts +164 -0
  63. package/dist/ekyc.esm.js +104 -0
  64. package/dist/ekycStateMachine-oeO0Iekd.esm.js +10626 -0
  65. package/dist/electronic-signature.d.ts +4 -0
  66. package/dist/electronic-signature.esm.js +7 -0
  67. package/dist/electronicSignatureManager-D9OHzTpG.esm.js +428 -0
  68. package/dist/email.d.ts +3 -263
  69. package/dist/email.esm.js +7 -477
  70. package/dist/emailManager-DIfnS5g1.d.ts +352 -0
  71. package/dist/emailManager-wAV0LE-H.esm.js +238 -0
  72. package/dist/emailStateMachine-DOf4j58N.esm.js +292 -0
  73. package/dist/endpoints-CnN3SyDa.esm.js +87 -0
  74. package/dist/events-D6-e4vok.esm.js +596 -0
  75. package/dist/events.d.ts +265 -0
  76. package/dist/events.esm.js +4 -0
  77. package/dist/extensibility.d.ts +122 -0
  78. package/dist/extensibility.esm.js +43 -0
  79. package/dist/face-match.d.ts +228 -0
  80. package/dist/face-match.esm.js +173 -0
  81. package/dist/faceCaptureManagerFactory-Dh2PdGlF.esm.js +290 -0
  82. package/dist/faceCaptureManagerFactory-yqtpxjnN.d.ts +690 -0
  83. package/dist/faceCaptureSetup-B3faSpYA.esm.js +873 -0
  84. package/dist/faceMatchStateMachine-DNFrxTFS.esm.js +127 -0
  85. package/dist/flow-events.d.ts +6 -0
  86. package/dist/flow-events.esm.js +0 -0
  87. package/dist/flow.d.ts +101 -321
  88. package/dist/flow.esm.js +370 -173
  89. package/dist/flowCompletionService-DhkT4SRY.d.ts +10 -0
  90. package/dist/flowCompletionService-P54yzGvA.esm.js +13 -0
  91. package/dist/flowServices-DTsm-Vf1.esm.js +188 -0
  92. package/dist/geolocation.d.ts +127 -0
  93. package/dist/geolocation.esm.js +89 -0
  94. package/dist/geolocationStateMachine-asasuHY2.esm.js +105 -0
  95. package/dist/getBrowser-BSXUTWXw.esm.js +41 -0
  96. package/dist/getDeviceClass-BSntT9_j.esm.js +14 -0
  97. package/dist/government-validation.d.ts +67 -0
  98. package/dist/government-validation.esm.js +81 -0
  99. package/dist/governmentValidationStateMachine-BDDYrJTo.esm.js +271 -0
  100. package/dist/home.d.ts +99 -0
  101. package/dist/home.esm.js +61 -0
  102. package/dist/http.d.ts +68 -0
  103. package/dist/http.esm.js +3 -0
  104. package/dist/id-ocr.d.ts +635 -0
  105. package/dist/id-ocr.esm.js +86 -0
  106. package/dist/id-verification.d.ts +190 -0
  107. package/dist/id-verification.esm.js +43 -0
  108. package/dist/id.d.ts +24 -0
  109. package/dist/id.esm.js +164 -0
  110. package/dist/idCaptureManager-B9TGA5dq.d.ts +956 -0
  111. package/dist/idCaptureManager-DMK0GIt3.esm.js +581 -0
  112. package/dist/idCaptureStateMachine-Bq0fVZXl.esm.js +2954 -0
  113. package/dist/idOcrStateMachine-YbjjC_Gg.esm.js +388 -0
  114. package/dist/idVerificationStateMachine-xbw9HP1Z.esm.js +71 -0
  115. package/dist/identity-reuse.d.ts +530 -0
  116. package/dist/identity-reuse.esm.js +274 -0
  117. package/dist/index-BLKtMA0g.d.ts +1177 -0
  118. package/dist/index-BcRG8rtJ.d.ts +97 -0
  119. package/dist/index.d.ts +3 -226
  120. package/dist/index.esm.js +11 -154
  121. package/dist/invokeOnCaptureCallback-rc6kBHo5.esm.js +30 -0
  122. package/dist/{lib-Bu9XGMBW.esm.js → lib-BB0B_qQX.esm.js} +801 -2
  123. package/dist/mandatory-consent.d.ts +412 -0
  124. package/dist/mandatory-consent.esm.js +78 -0
  125. package/dist/mandatoryConsentStateMachine-Cnco1jvn.esm.js +126 -0
  126. package/dist/openviduLazy-Cm0XFh_v.esm.js +3 -0
  127. package/dist/openviduLazy-Cok70ZSg.esm.js +12 -0
  128. package/dist/permissionServices-D_i6nzEw.esm.js +50 -0
  129. package/dist/phone.d.ts +3 -291
  130. package/dist/phone.esm.js +7 -548
  131. package/dist/phoneManager-B6M30hKE.d.ts +397 -0
  132. package/dist/phoneManager-DAJbGhlY.esm.js +256 -0
  133. package/dist/phoneStateMachine-CuPARRaT.esm.js +351 -0
  134. package/dist/platform-CfrjKhmi.esm.js +83 -0
  135. package/dist/qe-signature-DFo_Cc-I.esm.js +12 -0
  136. package/dist/qe-signature.d.ts +25 -0
  137. package/dist/qe-signature.esm.js +8 -0
  138. package/dist/recordingService-Ig2UgbLv.esm.js +1003 -0
  139. package/dist/redirect-to-mobile.d.ts +107 -0
  140. package/dist/redirect-to-mobile.esm.js +102 -0
  141. package/dist/redirectToMobileStateMachine-BOEqe46A.esm.js +249 -0
  142. package/dist/runChildModule-CqqwqAkW.esm.js +219 -0
  143. package/dist/selfie.d.ts +21 -754
  144. package/dist/selfie.esm.js +113 -962
  145. package/dist/selfieManager-D0lSgd-J.d.ts +68 -0
  146. package/dist/selfieManager-Duisl7qN.esm.js +60 -0
  147. package/dist/selfieStateMachine-D76whWEf.esm.js +68 -0
  148. package/dist/session-BS-d_vuE.esm.js +3206 -0
  149. package/dist/session.d.ts +217 -0
  150. package/dist/session.esm.js +9 -0
  151. package/dist/setup-Buy-hyj4.esm.js +887 -0
  152. package/dist/setup-C5AITV8m.d.ts +254 -0
  153. package/dist/signature.d.ts +94 -0
  154. package/dist/signature.esm.js +66 -0
  155. package/dist/signatureStateMachine-B5-QVUve.esm.js +132 -0
  156. package/dist/stats-CIfiPzb1.esm.js +16 -0
  157. package/dist/stats.d.ts +16 -0
  158. package/dist/stats.esm.js +4 -0
  159. package/dist/trust-graph.d.ts +54 -0
  160. package/dist/trust-graph.esm.js +56 -0
  161. package/dist/types-B06Ypu2F.d.ts +49 -0
  162. package/dist/types-BP1m8VRw.d.ts +340 -0
  163. package/dist/types-CFV9G_7j.d.ts +24 -0
  164. package/dist/{warmup-CEJTfxQr.d.ts → warmup-CEcppFiS.d.ts} +11 -3
  165. package/dist/wasm.d.ts +15 -0
  166. package/dist/wasm.esm.js +12 -0
  167. package/dist/watchlist-for-business.d.ts +79 -0
  168. package/dist/watchlist-for-business.esm.js +148 -0
  169. package/dist/watchlist.d.ts +62 -0
  170. package/dist/watchlist.esm.js +86 -0
  171. package/dist/watchlistServices-DMbUhkBX.esm.js +12 -0
  172. package/dist/workflow.d.ts +907 -0
  173. package/dist/workflow.esm.js +702 -0
  174. package/dist/{xstate.esm-B_rda9yU.esm.js → xstate.esm-B70JrNqo.esm.js} +144 -1
  175. package/package.json +203 -6
  176. package/dist/OpenViduLogger-BdPfiZO6.esm.js +0 -3
  177. package/dist/OpenViduLogger-CQyDxBvM.esm.js +0 -803
  178. package/dist/StateMachine-DRE1oH2B.d.ts +0 -2
  179. package/dist/addEvent-W0ORK0jT.esm.js +0 -16
  180. package/dist/endpoints-BSTFaHYo.esm.js +0 -1706
  181. package/dist/permissionServices-I6vX6DBy.esm.js +0 -72
  182. /package/dist/{Manager-BGfxEmyv.d.ts → Manager-C8PrhBOx.d.ts} +0 -0
  183. /package/dist/{chunk-C_Yo44FK.esm.js → chunk-CRF6K_H_.esm.js} +0 -0
  184. /package/dist/{types-iZi2rawo.d.ts → types-CAD4va6a.d.ts} +0 -0
@@ -0,0 +1,110 @@
1
+ import "./api-CESGtpbH.esm.js";
2
+ import { n as eventModuleNames, o as createManagerInstrumentation } from "./events-D6-e4vok.esm.js";
3
+ import "./endpoints-CnN3SyDa.esm.js";
4
+ import { c as createManager, s as createActor } from "./xstate.esm-B70JrNqo.esm.js";
5
+ import { i as mexicanStates, n as ENTER_CURP_FIELD, r as GENERATE_CURP_FIELDS, t as curpValidationMachine } from "./curpValidationStateMachine-CitWLr2c.esm.js";
6
+
7
+ //#region src/modules/curp-validation/curpValidationActor.ts
8
+ function createCurpValidationActor(options) {
9
+ return createActor(curpValidationMachine, { input: { config: options.config } }).start();
10
+ }
11
+
12
+ //#endregion
13
+ //#region src/modules/curp-validation/curpValidationManager.ts
14
+ const hasNoErrors = (errors) => Object.keys(errors ?? {}).length === 0;
15
+ function mapState(snapshot) {
16
+ const typedSnapshot = snapshot;
17
+ const { context } = typedSnapshot;
18
+ if (typedSnapshot.matches("idle")) return { status: "idle" };
19
+ if (typedSnapshot.matches("loading")) return { status: "loading" };
20
+ if (typedSnapshot.matches("enterCurp")) return {
21
+ status: "enterCurp",
22
+ curp: context.curp,
23
+ isValid: hasNoErrors(context.enterCurpValidationErrors),
24
+ validationErrors: context.enterCurpValidationErrors
25
+ };
26
+ if (typedSnapshot.matches("verifying")) return { status: "verifying" };
27
+ if (typedSnapshot.matches("success")) return { status: "success" };
28
+ if (typedSnapshot.matches("failure")) return {
29
+ status: "failure",
30
+ retriesLeft: context.retriesLeft
31
+ };
32
+ if (typedSnapshot.matches("generateCurp")) return {
33
+ status: "generateCurp",
34
+ form: context.generateForm,
35
+ isValid: hasNoErrors(context.generateCurpValidationErrors),
36
+ validationErrors: context.generateCurpValidationErrors
37
+ };
38
+ if (typedSnapshot.matches("generating")) return { status: "generating" };
39
+ if (typedSnapshot.matches("confirmCurp")) return {
40
+ status: "confirmCurp",
41
+ curp: context.curp
42
+ };
43
+ if (typedSnapshot.matches("generateError")) return {
44
+ status: "generateError",
45
+ retriesLeft: context.retriesLeft
46
+ };
47
+ if (typedSnapshot.matches("finished")) return { status: "finished" };
48
+ if (typedSnapshot.matches("closed")) return { status: "closed" };
49
+ return { status: "idle" };
50
+ }
51
+ function createApi({ actor, trackElementClicked }) {
52
+ return {
53
+ load() {
54
+ actor.send({ type: "LOAD" });
55
+ },
56
+ setCurp(curp) {
57
+ actor.send({
58
+ type: "SET_CURP",
59
+ curp
60
+ });
61
+ },
62
+ validateField(field) {
63
+ actor.send({
64
+ type: "VALIDATE_FIELD",
65
+ field
66
+ });
67
+ },
68
+ verify() {
69
+ trackElementClicked?.("verify");
70
+ actor.send({ type: "VERIFY" });
71
+ },
72
+ switchToGenerate() {
73
+ trackElementClicked?.("switchToGenerate");
74
+ actor.send({ type: "SWITCH_TO_GENERATE" });
75
+ },
76
+ setGenerateForm(form) {
77
+ actor.send({
78
+ type: "SET_GENERATE_FORM",
79
+ form
80
+ });
81
+ },
82
+ generate() {
83
+ trackElementClicked?.("generate");
84
+ actor.send({ type: "GENERATE" });
85
+ },
86
+ confirmGenerated() {
87
+ trackElementClicked?.("confirmGenerated");
88
+ actor.send({ type: "CONFIRM" });
89
+ },
90
+ retry() {
91
+ trackElementClicked?.("retry");
92
+ actor.send({ type: "RETRY" });
93
+ },
94
+ close() {
95
+ trackElementClicked?.("close");
96
+ actor.send({ type: "CLOSE" });
97
+ }
98
+ };
99
+ }
100
+ function createCurpValidationManager(options) {
101
+ return createManager({
102
+ actor: createCurpValidationActor(options),
103
+ mapState,
104
+ createApi,
105
+ instrumentation: createManagerInstrumentation(eventModuleNames.curpValidation)
106
+ });
107
+ }
108
+
109
+ //#endregion
110
+ export { ENTER_CURP_FIELD, GENERATE_CURP_FIELDS, createCurpValidationManager, curpValidationMachine, mexicanStates };
@@ -0,0 +1,595 @@
1
+ import { t as api } from "./api-CESGtpbH.esm.js";
2
+ import { t as endpoints } from "./endpoints-CnN3SyDa.esm.js";
3
+ import { a as fromPromise, r as assign, t as setup } from "./xstate.esm-B70JrNqo.esm.js";
4
+
5
+ //#region src/modules/curp-validation/curpValidationUtils.ts
6
+ const CURP_PATTERN = /^([A-Z][AEIOUX][A-Z]{2}\d{2}(?:0[1-9]|1[0-2])(?:0[1-9]|[12]\d|3[01])[HMX](?:AS|B[CS]|C[CLMSH]|D[FG]|G[TR]|HG|JC|M[CNS]|N[ETL]|OC|PL|Q[TR]|S[PLR]|T[CSL]|VZ|YN|ZS)[B-DF-HJ-NP-TV-Z]{3}[A-Z\d])(\d)$/;
7
+ const CURP_LENGTH = 18;
8
+ function isValidCurp(curp) {
9
+ return typeof curp === "string" && curp.length === CURP_LENGTH && CURP_PATTERN.test(curp.toUpperCase());
10
+ }
11
+ /** Convert YYYY-MM-DD to DD/MM/YYYY for the API */
12
+ function formatDateForApi(date) {
13
+ const [year, month, day] = date.split("-");
14
+ return `${day}/${month}/${year}`;
15
+ }
16
+ const mexicanStates = [
17
+ {
18
+ value: "NE",
19
+ label: "Born Abroad"
20
+ },
21
+ {
22
+ value: "AS",
23
+ label: "Aguascalientes"
24
+ },
25
+ {
26
+ value: "BC",
27
+ label: "Baja California"
28
+ },
29
+ {
30
+ value: "BS",
31
+ label: "Baja California Sur"
32
+ },
33
+ {
34
+ value: "CC",
35
+ label: "Campeche"
36
+ },
37
+ {
38
+ value: "CL",
39
+ label: "Coahuila de Zaragoza"
40
+ },
41
+ {
42
+ value: "CM",
43
+ label: "Colima"
44
+ },
45
+ {
46
+ value: "CS",
47
+ label: "Chiapas"
48
+ },
49
+ {
50
+ value: "CH",
51
+ label: "Chihuahua"
52
+ },
53
+ {
54
+ value: "DF",
55
+ label: "Distrito Federal"
56
+ },
57
+ {
58
+ value: "DG",
59
+ label: "Durango"
60
+ },
61
+ {
62
+ value: "GT",
63
+ label: "Guanajuato"
64
+ },
65
+ {
66
+ value: "GR",
67
+ label: "Guerrero"
68
+ },
69
+ {
70
+ value: "HG",
71
+ label: "Hidalgo"
72
+ },
73
+ {
74
+ value: "JC",
75
+ label: "Jalisco"
76
+ },
77
+ {
78
+ value: "MC",
79
+ label: "Estado de México"
80
+ },
81
+ {
82
+ value: "MN",
83
+ label: "Michoacan de Ocampo"
84
+ },
85
+ {
86
+ value: "MS",
87
+ label: "Morelos"
88
+ },
89
+ {
90
+ value: "NT",
91
+ label: "Nayarit"
92
+ },
93
+ {
94
+ value: "NL",
95
+ label: "Nuevo León"
96
+ },
97
+ {
98
+ value: "OC",
99
+ label: "Oaxaca"
100
+ },
101
+ {
102
+ value: "PL",
103
+ label: "Puebla"
104
+ },
105
+ {
106
+ value: "QT",
107
+ label: "Queretaro de Arteaga"
108
+ },
109
+ {
110
+ value: "QR",
111
+ label: "Quintana Roo"
112
+ },
113
+ {
114
+ value: "SP",
115
+ label: "San Luis Potosi"
116
+ },
117
+ {
118
+ value: "SL",
119
+ label: "Sinaloa"
120
+ },
121
+ {
122
+ value: "SR",
123
+ label: "Sonora"
124
+ },
125
+ {
126
+ value: "TC",
127
+ label: "Tabasco"
128
+ },
129
+ {
130
+ value: "TS",
131
+ label: "Tamaulipas"
132
+ },
133
+ {
134
+ value: "TL",
135
+ label: "Tlaxcala"
136
+ },
137
+ {
138
+ value: "VZ",
139
+ label: "Veracruz"
140
+ },
141
+ {
142
+ value: "YN",
143
+ label: "Yucatan"
144
+ },
145
+ {
146
+ value: "ZS",
147
+ label: "Zacatecas"
148
+ }
149
+ ];
150
+
151
+ //#endregion
152
+ //#region src/modules/curp-validation/curpValidationServices.ts
153
+ async function fetchOcrData(signal) {
154
+ const res = await api.get(endpoints.ocrData, { signal });
155
+ if (!res.ok) throw new Error(`GET ${endpoints.ocrData} failed: ${res.status} ${res.statusText}`);
156
+ return res.data;
157
+ }
158
+ async function addCurp(curp, signal) {
159
+ const res = await api.post(endpoints.addCurp, { curp }, { signal });
160
+ if (!res.ok) throw new Error(`POST ${endpoints.addCurp} failed: ${res.status} ${res.statusText}`);
161
+ return res.data;
162
+ }
163
+ async function addCurpV2(form, signal) {
164
+ const payload = {
165
+ name: form.name,
166
+ firstLastName: form.firstLastName,
167
+ secondLastName: form.secondLastName,
168
+ gender: form.gender,
169
+ birthDate: formatDateForApi(form.birthDate),
170
+ state: form.birthState
171
+ };
172
+ const res = await api.post(endpoints.addCurpV2, payload, { signal });
173
+ if (!res.ok) throw new Error(`POST ${endpoints.addCurpV2} failed: ${res.status} ${res.statusText}`);
174
+ return res.data;
175
+ }
176
+
177
+ //#endregion
178
+ //#region src/modules/curp-validation/curpFields.ts
179
+ /**
180
+ * Declarative schema for the CURP generation form.
181
+ *
182
+ * `secondLastName` is intentionally optional: many people in Mexico have
183
+ * only a single paternal surname. It carries no validation rules.
184
+ */
185
+ const GENERATE_CURP_FIELDS = [
186
+ {
187
+ key: "name",
188
+ labelKey: "curp.labels.firstName",
189
+ type: "text",
190
+ required: true,
191
+ autoComplete: "given-name",
192
+ validation: [{ type: "required" }]
193
+ },
194
+ {
195
+ key: "firstLastName",
196
+ labelKey: "curp.labels.firstLast",
197
+ type: "text",
198
+ required: true,
199
+ validation: [{ type: "required" }]
200
+ },
201
+ {
202
+ key: "secondLastName",
203
+ labelKey: "curp.labels.secondLast",
204
+ type: "text",
205
+ required: false
206
+ },
207
+ {
208
+ key: "gender",
209
+ labelKey: "curp.labels.genderV2",
210
+ type: "dropdown",
211
+ required: true,
212
+ validation: [{ type: "required" }]
213
+ },
214
+ {
215
+ key: "birthDate",
216
+ labelKey: "curp.labels.dob",
217
+ type: "date",
218
+ required: true,
219
+ validation: [{ type: "required" }]
220
+ },
221
+ {
222
+ key: "birthState",
223
+ labelKey: "curp.labels.birthState",
224
+ type: "dropdown",
225
+ required: true,
226
+ validation: [{ type: "required" }]
227
+ }
228
+ ];
229
+ /**
230
+ * Config for the single field on the CURP entry gateway screen.
231
+ *
232
+ * Validation contains only `curpFormat` — there is intentionally no
233
+ * `required` rule. The user can legitimately leave this field empty
234
+ * and use the "I don't have my CURP" button to switch to the Generate
235
+ * flow; surfacing a "required" error on blur of an empty field would
236
+ * be misleading.
237
+ *
238
+ * The Continue button on this screen is gated by a UI-level no-op guard
239
+ * (`curp.length === 0`) instead, which lives in `curpInput.tsx`.
240
+ */
241
+ const ENTER_CURP_FIELD = {
242
+ key: "curp",
243
+ labelKey: "curp.placeholder.curp",
244
+ validation: [{ type: "curpFormat" }]
245
+ };
246
+
247
+ //#endregion
248
+ //#region src/modules/curp-validation/curpValidators.ts
249
+ /**
250
+ * Registry of pure validator functions keyed by rule type.
251
+ *
252
+ * Each validator returns an i18n key when the value violates the rule,
253
+ * or `undefined` when the rule passes. Order of evaluation for a field
254
+ * is the order rules appear in that field's `validation` array; the
255
+ * first failing rule wins.
256
+ */
257
+ const createValidators = () => ({
258
+ required: (value) => value.trim().length === 0 ? "curp.errors.fieldRequired" : void 0,
259
+ curpFormat: (value) => {
260
+ if (value.trim().length === 0) return void 0;
261
+ return isValidCurp(value) ? void 0 : "curp.errors.invalidCurpFormat";
262
+ }
263
+ });
264
+ const normalizeFieldValue = (value) => typeof value === "string" ? value : String(value ?? "");
265
+ const evaluateRules = (value, validation, validators) => {
266
+ if (!validation) return void 0;
267
+ for (const rule of validation) {
268
+ const error = validators[rule.type](value);
269
+ if (error) return error;
270
+ }
271
+ };
272
+ /**
273
+ * Runs every Generate-CURP field through its validation rules and returns
274
+ * a map of field-key → first failing i18n error key. Fields that pass are
275
+ * absent from the result. An empty object signals "no errors".
276
+ */
277
+ const validateGenerateCurpForm = (data, fields) => {
278
+ const validators = createValidators();
279
+ return fields.reduce((errors, field) => {
280
+ const error = evaluateRules(normalizeFieldValue(data[field.key]), field.validation, validators);
281
+ if (error) errors[field.key] = error;
282
+ return errors;
283
+ }, {});
284
+ };
285
+ /**
286
+ * Runs a single Generate-CURP field through its validation rules.
287
+ * Returns the first failing i18n error key, or `undefined`.
288
+ */
289
+ const validateGenerateCurpField = (data, fieldKey, fields) => {
290
+ const field = fields.find((f) => f.key === fieldKey);
291
+ if (!field) return void 0;
292
+ const validators = createValidators();
293
+ return evaluateRules(normalizeFieldValue(data[fieldKey]), field.validation, validators);
294
+ };
295
+ /**
296
+ * Runs the single CURP-entry field through its validation rules.
297
+ * Used by both the on-blur validator and the submit-click validator
298
+ * on the CURP entry gateway screen.
299
+ */
300
+ const validateEnterCurpField = (curp, field = ENTER_CURP_FIELD) => {
301
+ const validators = createValidators();
302
+ return evaluateRules(normalizeFieldValue(curp), field.validation, validators);
303
+ };
304
+
305
+ //#endregion
306
+ //#region src/modules/curp-validation/curpValidationStateMachine.ts
307
+ const DEFAULT_GENERATE_FORM = {
308
+ name: "",
309
+ firstLastName: "",
310
+ secondLastName: "",
311
+ gender: "",
312
+ birthDate: "",
313
+ birthState: ""
314
+ };
315
+ const removeKey = (errors, key) => {
316
+ if (!errors?.[key]) return errors;
317
+ const next = { ...errors };
318
+ delete next[key];
319
+ return Object.keys(next).length > 0 ? next : void 0;
320
+ };
321
+ const removeKeys = (errors, keys) => {
322
+ if (!errors) return void 0;
323
+ const next = { ...errors };
324
+ for (const key of keys) delete next[key];
325
+ return Object.keys(next).length > 0 ? next : void 0;
326
+ };
327
+ const upsertKey = (errors, key, message) => {
328
+ const next = { ...errors ?? {} };
329
+ if (message) next[key] = message;
330
+ else delete next[key];
331
+ return Object.keys(next).length > 0 ? next : void 0;
332
+ };
333
+ const curpValidationMachine = setup({
334
+ types: {
335
+ context: {},
336
+ events: {},
337
+ input: {}
338
+ },
339
+ actors: {
340
+ fetchOcrData: fromPromise(async ({ signal }) => {
341
+ return fetchOcrData(signal);
342
+ }),
343
+ verifyCurp: fromPromise(async ({ input, signal }) => {
344
+ return addCurp(input.curp, signal);
345
+ }),
346
+ generateCurpActor: fromPromise(async ({ input, signal }) => {
347
+ return addCurpV2(input.form, signal);
348
+ })
349
+ },
350
+ actions: {
351
+ setCurpFromOcr: assign(({ event }) => {
352
+ return { curp: (event.output?.curp ?? "").toUpperCase() };
353
+ }),
354
+ setCurp: assign(({ event }) => {
355
+ return { curp: event.curp.toUpperCase() };
356
+ }),
357
+ clearEnterCurpFieldError: assign(({ context }) => ({ enterCurpValidationErrors: removeKey(context.enterCurpValidationErrors, "curp") })),
358
+ validateEnterCurpFieldAction: assign(({ context }) => ({ enterCurpValidationErrors: upsertKey(context.enterCurpValidationErrors, "curp", validateEnterCurpField(context.curp)) })),
359
+ computeEnterCurpValidationResult: assign(({ context }) => {
360
+ const message = validateEnterCurpField(context.curp);
361
+ return { enterCurpValidationErrors: message ? { curp: message } : void 0 };
362
+ }),
363
+ resetEnterCurpValidationErrors: assign({ enterCurpValidationErrors: () => void 0 }),
364
+ setGenerateForm: assign(({ context, event }) => {
365
+ const e = event;
366
+ return {
367
+ generateForm: {
368
+ ...context.generateForm,
369
+ ...e.form
370
+ },
371
+ generateCurpValidationErrors: removeKeys(context.generateCurpValidationErrors, Object.keys(e.form))
372
+ };
373
+ }),
374
+ validateGenerateCurpFieldAction: assign(({ context, event }) => {
375
+ if (event.type !== "VALIDATE_FIELD") return {};
376
+ if (event.field === "curp") return {};
377
+ const message = validateGenerateCurpField(context.generateForm, event.field, GENERATE_CURP_FIELDS);
378
+ return { generateCurpValidationErrors: upsertKey(context.generateCurpValidationErrors, event.field, message) };
379
+ }),
380
+ computeGenerateValidationResult: assign(({ context }) => {
381
+ const errors = validateGenerateCurpForm(context.generateForm, GENERATE_CURP_FIELDS);
382
+ return { generateCurpValidationErrors: Object.keys(errors).length > 0 ? errors : void 0 };
383
+ }),
384
+ resetGenerateCurpValidationErrors: assign({ generateCurpValidationErrors: () => void 0 }),
385
+ setGeneratedCurp: assign(({ event }) => {
386
+ const curp = event.output?.curp ?? "";
387
+ return {
388
+ generatedCurp: curp,
389
+ curp
390
+ };
391
+ }),
392
+ decrementRetries: assign(({ context }) => ({ retriesLeft: Math.max(0, context.retriesLeft - 1) })),
393
+ setFromGenerate: assign({ fromGenerate: () => true }),
394
+ clearFromGenerate: assign({ fromGenerate: () => false }),
395
+ setError: assign(({ event }) => ({ error: String(event.error) }))
396
+ },
397
+ guards: {
398
+ hasPrefillFromOcr: ({ context }) => context.config.prefillFromOcr !== false,
399
+ hasOcrCurp: ({ event }) => {
400
+ return !!event.output?.curp?.trim();
401
+ },
402
+ canRetry: ({ context }) => context.retriesLeft > 0,
403
+ isDeceased: ({ event }) => {
404
+ return event.output?.deceasedStatus === "DECEASED";
405
+ },
406
+ isScrapingFallback: ({ event }) => {
407
+ return event.output?.result === "Attempting validation by scraping method";
408
+ },
409
+ isGenerateSuccess: ({ event }) => {
410
+ const output = event.output;
411
+ return !!(output?.success && output?.curp);
412
+ },
413
+ isVerifySuccess: ({ event }) => {
414
+ return event.output?.success === true;
415
+ },
416
+ shouldVerify: ({ context }) => context.curp.trim().length > 0 && Object.keys(context.enterCurpValidationErrors ?? {}).length === 0,
417
+ isGenerateFormValidGuard: ({ context }) => Object.keys(context.generateCurpValidationErrors ?? {}).length === 0
418
+ }
419
+ }).createMachine({
420
+ id: "curpValidation",
421
+ initial: "idle",
422
+ context: ({ input }) => ({
423
+ config: input.config,
424
+ curp: "",
425
+ generateForm: { ...DEFAULT_GENERATE_FORM },
426
+ retriesLeft: input.config.maxRetries ?? 1,
427
+ generatedCurp: void 0,
428
+ error: void 0,
429
+ fromGenerate: false
430
+ }),
431
+ states: {
432
+ idle: { on: {
433
+ LOAD: [{
434
+ target: "loading",
435
+ guard: "hasPrefillFromOcr"
436
+ }, { target: "enterCurp" }],
437
+ CLOSE: "closed"
438
+ } },
439
+ loading: {
440
+ invoke: {
441
+ id: "fetchOcrData",
442
+ src: "fetchOcrData",
443
+ onDone: [{
444
+ target: "verifying",
445
+ guard: "hasOcrCurp",
446
+ actions: "setCurpFromOcr"
447
+ }, { target: "enterCurp" }],
448
+ onError: { target: "enterCurp" }
449
+ },
450
+ on: { CLOSE: "closed" }
451
+ },
452
+ enterCurp: {
453
+ entry: "resetEnterCurpValidationErrors",
454
+ initial: "inputting",
455
+ states: {
456
+ inputting: { on: {
457
+ SET_CURP: { actions: ["setCurp", "clearEnterCurpFieldError"] },
458
+ VALIDATE_FIELD: {
459
+ guard: ({ event }) => event.field === "curp",
460
+ actions: "validateEnterCurpFieldAction"
461
+ },
462
+ VERIFY: { target: "validatingVerify" },
463
+ SWITCH_TO_GENERATE: {
464
+ target: "#curpValidation.generateCurp",
465
+ actions: "setFromGenerate"
466
+ }
467
+ } },
468
+ validatingVerify: {
469
+ entry: "computeEnterCurpValidationResult",
470
+ always: [{
471
+ guard: "shouldVerify",
472
+ target: "#curpValidation.verifying"
473
+ }, { target: "inputting" }]
474
+ }
475
+ },
476
+ on: { CLOSE: "#curpValidation.closed" }
477
+ },
478
+ verifying: {
479
+ invoke: {
480
+ id: "verifyCurp",
481
+ src: "verifyCurp",
482
+ input: ({ context }) => ({ curp: context.curp }),
483
+ onDone: [{
484
+ target: "success",
485
+ guard: "isVerifySuccess"
486
+ }, {
487
+ target: "failure",
488
+ actions: "decrementRetries"
489
+ }],
490
+ onError: {
491
+ target: "failure",
492
+ actions: ["decrementRetries", "setError"]
493
+ }
494
+ },
495
+ on: { CLOSE: "closed" }
496
+ },
497
+ success: {
498
+ after: { 3e3: "finished" },
499
+ on: { CLOSE: "closed" }
500
+ },
501
+ failure: {
502
+ on: {
503
+ RETRY: [{
504
+ target: "generateCurp",
505
+ guard: ({ context }) => context.retriesLeft > 0 && context.fromGenerate
506
+ }, {
507
+ target: "enterCurp",
508
+ guard: ({ context }) => context.retriesLeft > 0 && !context.fromGenerate,
509
+ actions: "clearFromGenerate"
510
+ }],
511
+ CLOSE: "closed"
512
+ },
513
+ after: { 3e3: [{
514
+ target: "finished",
515
+ guard: ({ context }) => context.retriesLeft <= 0
516
+ }] }
517
+ },
518
+ generateCurp: {
519
+ entry: "resetGenerateCurpValidationErrors",
520
+ initial: "inputting",
521
+ states: {
522
+ inputting: { on: {
523
+ SET_GENERATE_FORM: { actions: "setGenerateForm" },
524
+ VALIDATE_FIELD: {
525
+ guard: ({ event }) => event.field !== "curp",
526
+ actions: "validateGenerateCurpFieldAction"
527
+ },
528
+ GENERATE: { target: "validatingGenerate" }
529
+ } },
530
+ validatingGenerate: {
531
+ entry: "computeGenerateValidationResult",
532
+ always: [{
533
+ guard: "isGenerateFormValidGuard",
534
+ target: "#curpValidation.generating"
535
+ }, { target: "inputting" }]
536
+ }
537
+ },
538
+ on: { CLOSE: "#curpValidation.closed" }
539
+ },
540
+ generating: {
541
+ invoke: {
542
+ id: "generateCurpActor",
543
+ src: "generateCurpActor",
544
+ input: ({ context }) => ({ form: context.generateForm }),
545
+ onDone: [
546
+ {
547
+ target: "finished",
548
+ guard: "isScrapingFallback"
549
+ },
550
+ {
551
+ target: "finished",
552
+ guard: "isDeceased"
553
+ },
554
+ {
555
+ target: "confirmCurp",
556
+ guard: "isGenerateSuccess",
557
+ actions: "setGeneratedCurp"
558
+ },
559
+ {
560
+ target: "generateError",
561
+ actions: "setFromGenerate"
562
+ }
563
+ ],
564
+ onError: {
565
+ target: "generateError",
566
+ actions: ["setFromGenerate", "setError"]
567
+ }
568
+ },
569
+ on: { CLOSE: "closed" }
570
+ },
571
+ confirmCurp: { on: {
572
+ CONFIRM: { target: "verifying" },
573
+ CLOSE: "closed"
574
+ } },
575
+ generateError: {
576
+ on: {
577
+ RETRY: {
578
+ target: "generateCurp",
579
+ guard: "canRetry",
580
+ actions: "decrementRetries"
581
+ },
582
+ CLOSE: "closed"
583
+ },
584
+ after: { 3e3: [{
585
+ target: "finished",
586
+ guard: ({ context }) => context.retriesLeft <= 0
587
+ }] }
588
+ },
589
+ finished: { type: "final" },
590
+ closed: { type: "final" }
591
+ }
592
+ });
593
+
594
+ //#endregion
595
+ export { mexicanStates as i, ENTER_CURP_FIELD as n, GENERATE_CURP_FIELDS as r, curpValidationMachine as t };