@incodetech/core 0.0.0-dev-20261014-e4db9c02 → 0.0.0-dev-20261014-82c6fd33

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 (67) hide show
  1. package/dist/{FaceDetectionProvider-9IwB7jcM.esm.js → FaceDetectionProvider-CjWCKcIu.esm.js} +5 -5
  2. package/dist/ae-signature.esm.js +1 -1
  3. package/dist/{apiError-CFwIWUtz.esm.js → apiError-DgSftpa0.esm.js} +1 -1
  4. package/dist/authentication.esm.js +2 -2
  5. package/dist/{authenticationManager-DHrqI5Le.esm.js → authenticationManager--1lefT83.esm.js} +3 -3
  6. package/dist/{authenticationStateMachine-CDsC16Jn.esm.js → authenticationStateMachine-AVH_s6--.esm.js} +2 -2
  7. package/dist/{deepsightLoader-CWjI76eb.esm.js → deepsightLoader-Drgk4Jv9.esm.js} +4 -4
  8. package/dist/{deepsightService-Dq_9MGNi.esm.js → deepsightService-xMDI8RDs.esm.js} +1 -1
  9. package/dist/dynamic-forms.esm.js +2 -2
  10. package/dist/{dynamicFormsManager-CCzxliyj.esm.js → dynamicFormsManager-D7wWeNGK.esm.js} +1 -1
  11. package/dist/{dynamicFormsStateMachine-DVbgcw96.esm.js → dynamicFormsStateMachine-9sqWyWLc.esm.js} +1 -1
  12. package/dist/ekyb.esm.js +3 -3
  13. package/dist/{ekybManager-DtdNyCkV.esm.js → ekybManager-DLytGFSA.esm.js} +1 -1
  14. package/dist/{ekybStateMachine-Cd0nGdXM.esm.js → ekybStateMachine-fRzoh4AI.esm.js} +1 -1
  15. package/dist/ekyc.esm.js +3 -3
  16. package/dist/{ekycManager-DZH51PnN.esm.js → ekycManager-RaSSnmxD.esm.js} +1 -1
  17. package/dist/{ekycStateMachine-DnKlILfu.esm.js → ekycStateMachine-BqacNxVI.esm.js} +803 -1
  18. package/dist/{ekycUtils-3FIL6m1x.esm.js → ekycUtils-DrRSBMVL.esm.js} +28 -0
  19. package/dist/electronic-signature.esm.js +1 -1
  20. package/dist/{electronicSignatureManager-B_SHlY1L.esm.js → electronicSignatureManager-BR38Ogjf.esm.js} +1 -1
  21. package/dist/extensibility.d.ts +4 -4
  22. package/dist/extensibility.esm.js +11 -11
  23. package/dist/{faceCaptureManagerFactory-1uGiHaoF.esm.js → faceCaptureManagerFactory-B1BrC2K4.esm.js} +1 -1
  24. package/dist/{faceCaptureSetup-BYnZ3A8a.esm.js → faceCaptureSetup-Dmz6aiNH.esm.js} +3 -3
  25. package/dist/{feature-management-XxXkowCy.esm.js → feature-management-pS1G_jQ5.esm.js} +1 -1
  26. package/dist/feature-management.esm.js +1 -1
  27. package/dist/flow.d.ts +1 -1
  28. package/dist/flow.esm.js +3 -3
  29. package/dist/{flowCompletionService-OHsAMzl8.esm.js → flowCompletionService-CVBZUlWT.esm.js} +1 -1
  30. package/dist/{flowServices-D3b4BP89.esm.js → flowServices-CCPh3tqQ.esm.js} +5 -5
  31. package/dist/geolocation.esm.js +2 -2
  32. package/dist/{geolocationManager-DqI8ho5R.esm.js → geolocationManager-CG3nIRbs.esm.js} +1 -1
  33. package/dist/{geolocationStateMachine-Je2uPWor.esm.js → geolocationStateMachine-Z9o9iDIY.esm.js} +1 -1
  34. package/dist/id-selfie-flow.esm.js +7 -7
  35. package/dist/id.d.ts +2 -2
  36. package/dist/id.esm.js +3 -3
  37. package/dist/{idCaptureDefaults-BjP8SevF.esm.js → idCaptureDefaults-DlsyJMOW.esm.js} +1 -1
  38. package/dist/{idCaptureManager-DW3eER4t.d.ts → idCaptureManager-BY97SRCV.d.ts} +1 -1
  39. package/dist/{idCaptureManager-I5L_IVbR.esm.js → idCaptureManager-DmoOx0O5.esm.js} +3 -3
  40. package/dist/{idCaptureServices-t11U9Anc.esm.js → idCaptureServices-D55prH0r.esm.js} +3 -3
  41. package/dist/{idCaptureStateMachine-Dv1tDMKs.esm.js → idCaptureStateMachine-MV0CtrZ9.esm.js} +44 -21
  42. package/dist/identity-reuse.d.ts +1 -1
  43. package/dist/{identityReuseManager-ooAbp6Kc.d.ts → identityReuseManager-B1birg5X.d.ts} +4 -4
  44. package/dist/index.d.ts +1 -1
  45. package/dist/index.esm.js +1 -1
  46. package/dist/mandatory-consent.d.ts +1 -1
  47. package/dist/{mandatoryConsentManager-BkaLkcA2.d.ts → mandatoryConsentManager-DDixKrq0.d.ts} +4 -4
  48. package/dist/qe-signature.esm.js +1 -1
  49. package/dist/{runChildModule-9q7BQwPd.esm.js → runChildModule-DXNgGwGn.esm.js} +1 -1
  50. package/dist/{sdkVersion-g8ehOQhP.esm.js → sdkVersion-DM8nidSt.esm.js} +1 -1
  51. package/dist/selfie.esm.js +6 -6
  52. package/dist/{selfieErrorUtils-zRAt9WeG.esm.js → selfieErrorUtils-B3Gdyvaf.esm.js} +1 -1
  53. package/dist/{selfieManager-BVcizHEI.esm.js → selfieManager-gLy-_nNC.esm.js} +3 -3
  54. package/dist/{selfieStateMachine-CBkLfNU3.esm.js → selfieStateMachine-BiYWExHE.esm.js} +3 -3
  55. package/dist/{session-XeaMJEO1.esm.js → session-CtVdey6m.esm.js} +3 -3
  56. package/dist/session.esm.js +4 -4
  57. package/dist/{sessionInitializer-LBbZHbPK.esm.js → sessionInitializer-V3iatb38.esm.js} +3 -3
  58. package/dist/{setup-CkMpP7pu.esm.js → setup-C-Nol_jL.esm.js} +22 -5
  59. package/dist/{setup-oKDzNC62.d.ts → setup-lgkQ8dJW.d.ts} +11 -0
  60. package/dist/{trueSightService-DtuHbL0_.esm.js → trueSightService-D7fIDGRl.esm.js} +1 -1
  61. package/dist/{types-CwCWyBEi.d.ts → types-CyPUIpzf.d.ts} +19 -5
  62. package/dist/video-selfie.esm.js +3 -3
  63. package/dist/{videoSelfieCameraWarmer-pt56Pcfi.esm.js → videoSelfieCameraWarmer-MXduX5t-.esm.js} +4 -4
  64. package/dist/wasm.d.ts +1 -1
  65. package/dist/wasm.esm.js +2 -2
  66. package/dist/workflow.esm.js +16 -16
  67. package/package.json +6 -4
@@ -1,11 +1,146 @@
1
1
  import { t as api } from "./api-Bx3gKW_y.esm.js";
2
2
  import { t as endpoints } from "./endpoints-DHzlkQNe.esm.js";
3
- import { _ as STATE_CODE_HINTS, a as toEkycConfig, c as CITY_SOURCES, d as EMAIL_SOURCES, f as HOUSE_NO_SOURCES, g as POSTAL_CODE_SOURCES, h as ONE_OF_REQUIRED_GROUPS, i as resolveEkycSource, l as COUNTRY_CODE_OMITTED_SOURCES, m as NAME_SOURCES, n as getEKYCFields, o as ADDRESS_STATE_SOURCES, p as MIDDLE_NAME_SOURCES, r as isFieldOptional, s as APARTMENT_SOURCES, t as getEKYCCountry, u as COUNTRY_SELECTOR_DISABLED_SOURCES, v as STREET_SOURCES, y as TAX_ID_SOURCES } from "./ekycUtils-3FIL6m1x.esm.js";
3
+ import { _ as STATE_CODE_HINTS, a as toEkycConfig, c as CITY_SOURCES, d as EMAIL_SOURCES, f as HOUSE_NO_SOURCES, g as POSTAL_CODE_SOURCES, h as ONE_OF_REQUIRED_GROUPS, i as resolveEkycSource, l as COUNTRY_CODE_OMITTED_SOURCES, m as NAME_SOURCES, n as getEKYCFields, o as ADDRESS_STATE_SOURCES, p as MIDDLE_NAME_SOURCES, r as isFieldOptional, s as APARTMENT_SOURCES, t as getEKYCCountry, u as COUNTRY_SELECTOR_DISABLED_SOURCES, v as STREET_SOURCES, y as TAX_ID_SOURCES } from "./ekycUtils-DrRSBMVL.esm.js";
4
4
  import { i as assign, t as setup } from "./xstate.esm-DSajW7CJ.esm.js";
5
5
  import { n as fromPromise } from "./xstate-actors.esm-8Gzepa_A.esm.js";
6
6
  import { a as getPostalCodeMaxLength, c as STREET_LEVEL_REQUIRED_ERROR, d as usStateOptions, i as getPostalCodeErrorKey, l as fillFromSuggestion, n as FIXED_DIGIT_POSTAL_CODE_LENGTH, o as validatePostalCode, r as formatPostalCode, s as DYNAMIC_REQUIRED_KEY, t as debounceSearchActor, u as getStreetLevelErrorForSuggestion } from "./addressSearch-Bm8zTbQJ.esm.js";
7
7
  import { n as DateFormattingProvider, t as validateCPF } from "./cpf-uAZTPUBy.esm.js";
8
8
  import { n as loadPhoneValidation, t as getPhoneValidation } from "./phoneValidation-DnBcNUNh.esm.js";
9
+ //#region src/internal/forms/checkSupport.ts
10
+ const GROUP_POLICIES = /* @__PURE__ */ new Set(["hide", "forceShow"]);
11
+ /** Compares `major.minor` vocabulary versions. */
12
+ function compareVocabulary(a, b) {
13
+ const [aMajor = 0, aMinor = 0] = a.split(".").map(Number);
14
+ const [bMajor = 0, bMinor = 0] = b.split(".").map(Number);
15
+ return aMajor - bMajor || aMinor - bMinor;
16
+ }
17
+ /**
18
+ * Whether this build can use a definition. Any id it doesn't implement makes
19
+ * the definition unsupported, so the caller falls back to its bundled
20
+ * definition or current form. Presentation hints (widget, keyboard, autofill)
21
+ * never fail: an unknown hint falls back to the platform default.
22
+ */
23
+ function checkSupport(definition, ids) {
24
+ const problems = [];
25
+ const need = (category, known, id, path) => {
26
+ if (!known.has(id)) problems.push({
27
+ category,
28
+ id,
29
+ path
30
+ });
31
+ };
32
+ if (!ids.schemaVersions.includes(definition.schemaVersion)) problems.push({
33
+ category: "schemaVersion",
34
+ id: String(definition.schemaVersion),
35
+ path: "schemaVersion"
36
+ });
37
+ if (compareVocabulary(definition.vocabulary, ids.vocabulary) > 0) problems.push({
38
+ category: "vocabulary",
39
+ id: definition.vocabulary,
40
+ path: "vocabulary"
41
+ });
42
+ const checkField = (field, path) => {
43
+ need("kind", ids.kinds, field.kind, `${path}.kind`);
44
+ need("group", ids.groups, field.group, `${path}.group`);
45
+ field.rules?.forEach((rule, i) => need("rule", ids.rules, rule.id, `${path}.rules[${i}]`));
46
+ field.input?.format?.forEach((t, i) => need("transform", ids.transforms, t.id, `${path}.input.format[${i}]`));
47
+ field.payload?.transforms?.forEach((t, i) => need("transform", ids.transforms, t.id, `${path}.payload.transforms[${i}]`));
48
+ if (field.optionsRef) need("optionList", ids.optionLists, field.optionsRef, `${path}.optionsRef`);
49
+ if (field.suggestionsRef) need("optionList", ids.optionLists, field.suggestionsRef, `${path}.suggestionsRef`);
50
+ field.requiredWhen?.forEach((condition, i) => {
51
+ const keys = Object.keys(condition);
52
+ if (keys.length !== 1) problems.push({
53
+ category: "condition",
54
+ id: keys.join("+") || "(empty)",
55
+ path: `${path}.requiredWhen[${i}]`
56
+ });
57
+ for (const key of keys) need("condition", ids.conditions, key, `${path}.requiredWhen[${i}]`);
58
+ });
59
+ const lock = field.phone?.lockCountry;
60
+ if (typeof lock === "string" && lock !== "whenPhoneRisk") problems.push({
61
+ category: "phoneLock",
62
+ id: lock,
63
+ path: `${path}.phone`
64
+ });
65
+ };
66
+ definition.fields.forEach((field) => checkField(field, `fields.${field.name}`));
67
+ definition.groups?.forEach((policy) => {
68
+ need("group", ids.groups, policy.group, `groups.${policy.group}`);
69
+ if (!GROUP_POLICIES.has(policy.whenDisabled)) problems.push({
70
+ category: "groupPolicy",
71
+ id: policy.whenDisabled,
72
+ path: `groups.${policy.group}`
73
+ });
74
+ });
75
+ definition.groupRules?.forEach((rule, i) => need("groupRule", ids.groupRules, rule.id, `groupRules[${i}]`));
76
+ definition.collections?.forEach((collection) => {
77
+ need("group", ids.groups, collection.group, `collections.${collection.id}`);
78
+ collection.fields.forEach((field) => checkField(field, `collections.${collection.id}.fields.${field.name}`));
79
+ });
80
+ return problems.length === 0 ? { supported: true } : {
81
+ supported: false,
82
+ problems
83
+ };
84
+ }
85
+ //#endregion
86
+ //#region src/internal/forms/definitionSource.ts
87
+ const queryKey = ({ module, source, country }) => `${module}|${source ?? ""}|${country ?? ""}`;
88
+ /**
89
+ * The definitions bundled with this build. Matches module, source and country
90
+ * exactly, so a pair without its own definition keeps the current builder.
91
+ */
92
+ function createBundledDefinitionSource(definitions) {
93
+ const byQuery = new Map(Object.values(definitions).map((definition) => [queryKey(definition), definition]));
94
+ return { select: (query) => byQuery.get(queryKey(query)) };
95
+ }
96
+ //#endregion
97
+ //#region src/internal/forms/resolveForm.ts
98
+ const FORCE_SHOW = "forceShow";
99
+ const WHEN_PHONE_RISK = "whenPhoneRisk";
100
+ /**
101
+ * Resolves a definition against module configuration: which fields show,
102
+ * which are required, whether the phone is locked, and which group rules and
103
+ * collections apply. Pure and synchronous, so it runs inside an assign action.
104
+ *
105
+ * Call `checkSupport` first for any definition that wasn't bundled with this
106
+ * build; `resolveForm` ignores ids it doesn't know.
107
+ */
108
+ function resolveForm(definition, context) {
109
+ const forcedGroups = new Set((definition.groups ?? []).filter((policy) => policy.whenDisabled === FORCE_SHOW).map((policy) => policy.group));
110
+ const isOn = (group) => context.groups[group] === true;
111
+ const isShown = (group) => isOn(group) || forcedGroups.has(group);
112
+ const riskAddons = new Set(context.riskAddons ?? []);
113
+ const shownFields = definition.fields.filter((field) => isShown(field.group));
114
+ const shownNames = new Set(shownFields.map((field) => field.name));
115
+ const fields = shownFields.map((field) => {
116
+ const conditions = field.requiredWhen ?? [];
117
+ const addonRequired = conditions.some((condition) => condition.riskAddon !== void 0 && riskAddons.has(condition.riskAddon));
118
+ const requiredIfFilled = conditions.map((condition) => condition.fieldFilled).filter((name) => name !== void 0 && shownNames.has(name));
119
+ const lock = field.phone?.lockCountry;
120
+ return {
121
+ field,
122
+ required: field.required === true || addonRequired,
123
+ requiredIfFilled,
124
+ forced: !isOn(field.group),
125
+ phoneLocked: field.kind === "phone" && (lock === true || lock === WHEN_PHONE_RISK && context.phoneRisk === true)
126
+ };
127
+ });
128
+ const order = shownFields.map((field) => field.name);
129
+ return {
130
+ definition,
131
+ fields,
132
+ groupRules: (definition.groupRules ?? []).map((rule) => ({
133
+ rule,
134
+ fields: order.filter((name) => rule.fields.includes(name))
135
+ })).filter((resolved) => resolved.fields.length > 0),
136
+ collections: (definition.collections ?? []).filter((collection) => isShown(collection.group)).map((collection) => ({
137
+ collection,
138
+ min: collection.min ?? 0,
139
+ max: collection.max
140
+ }))
141
+ };
142
+ }
143
+ //#endregion
9
144
  //#region src/modules/ekyc/ekycValidators.ts
10
145
  async function loadPhoneValidator() {
11
146
  if (!await loadPhoneValidation()) throw new Error("Failed to load the phone validation rules");
@@ -124,6 +259,662 @@ function validateEkycField(values, fieldName, fields) {
124
259
  return evaluateRules(value, field.validation, field, values, validators);
125
260
  }
126
261
  //#endregion
262
+ //#region ../form-definitions/generated/ekyc.ts
263
+ const EKYC_DEFINITIONS = {
264
+ "ekyc/BR/BR_GOVT_1": {
265
+ schemaVersion: 1,
266
+ vocabulary: "1.0",
267
+ id: "ekyc/BR/BR_GOVT_1",
268
+ module: "ekyc",
269
+ country: "BR",
270
+ source: "BR_GOVT_1",
271
+ sections: [{ id: "address" }, { id: "driverLicense" }],
272
+ fields: [
273
+ {
274
+ name: "firstName",
275
+ kind: "text",
276
+ group: "name",
277
+ required: true,
278
+ label: { key: "verification.labels.firstName" },
279
+ placeholder: { key: "verification.placeholder.firstName" },
280
+ input: {
281
+ maxLength: 100,
282
+ autofill: "givenName"
283
+ }
284
+ },
285
+ {
286
+ name: "surName",
287
+ kind: "text",
288
+ group: "name",
289
+ required: true,
290
+ label: { key: "verification.labels.surName" },
291
+ placeholder: { key: "verification.placeholder.surname" },
292
+ input: {
293
+ maxLength: 100,
294
+ autofill: "familyName"
295
+ }
296
+ },
297
+ {
298
+ name: "dateOfBirth",
299
+ kind: "date",
300
+ group: "dateOfBirth",
301
+ required: true,
302
+ label: { key: "verification.labels.dateOfBirth" },
303
+ input: { autofill: "birthday" }
304
+ },
305
+ {
306
+ name: "email",
307
+ kind: "text",
308
+ group: "email",
309
+ required: true,
310
+ label: { key: "verification.labels.email" },
311
+ placeholder: { key: "verification.placeholder.email" },
312
+ input: {
313
+ keyboard: "email",
314
+ autofill: "email"
315
+ },
316
+ rules: [{ id: "emailFormat" }]
317
+ },
318
+ {
319
+ name: "phone",
320
+ kind: "phone",
321
+ group: "phone",
322
+ required: true,
323
+ label: { key: "verification.labels.phone" },
324
+ input: { autofill: "phone" },
325
+ phone: { lockCountry: "whenPhoneRisk" },
326
+ rules: [{ id: "phoneFormat" }],
327
+ payload: { transforms: [{ id: "e164" }] }
328
+ },
329
+ {
330
+ name: "taxId",
331
+ kind: "text",
332
+ group: "ssn",
333
+ required: true,
334
+ label: { key: "verification.labels.taxId" },
335
+ displayLabel: {
336
+ key: "verification.labels.cpf",
337
+ text: "CPF"
338
+ },
339
+ rules: [{ id: "cpf" }]
340
+ },
341
+ {
342
+ name: "nationality",
343
+ kind: "choice",
344
+ group: "nationality",
345
+ required: true,
346
+ widget: "select",
347
+ label: { key: "verification.labels.nationality" },
348
+ options: [
349
+ {
350
+ value: "brazilian",
351
+ label: { key: "verification.labels.brazilian" }
352
+ },
353
+ {
354
+ value: "naturalizedBrazilian",
355
+ label: { key: "verification.labels.naturalizedBrazilian" }
356
+ },
357
+ {
358
+ value: "foreigner",
359
+ label: { key: "verification.labels.foreigner" }
360
+ },
361
+ {
362
+ value: "brazilianBornAbroad",
363
+ label: { key: "verification.labels.brazilianBornAbroad" }
364
+ }
365
+ ],
366
+ payload: { transforms: [{ id: "uppercase" }] }
367
+ },
368
+ {
369
+ name: "last4SSN",
370
+ kind: "text",
371
+ group: "last4SSN",
372
+ required: true,
373
+ label: { key: "verification.labels.last4SSN" },
374
+ input: {
375
+ maxLength: 4,
376
+ keyboard: "numeric"
377
+ }
378
+ },
379
+ {
380
+ name: "idNum",
381
+ kind: "text",
382
+ group: "idNumber",
383
+ required: true,
384
+ label: { key: "verification.labels.idNum" },
385
+ input: { maxLength: 13 }
386
+ },
387
+ {
388
+ name: "idNum1",
389
+ kind: "text",
390
+ group: "idNumber1",
391
+ required: true,
392
+ label: { key: "verification.labels.idNum1" }
393
+ },
394
+ {
395
+ name: "gender",
396
+ kind: "choice",
397
+ group: "gender",
398
+ required: true,
399
+ widget: "radio",
400
+ label: { key: "verification.labels.gender" },
401
+ options: [{
402
+ value: "F",
403
+ label: { key: "common.female" }
404
+ }, {
405
+ value: "M",
406
+ label: { key: "common.male" }
407
+ }]
408
+ },
409
+ {
410
+ name: "panNumber",
411
+ kind: "text",
412
+ group: "panNumber",
413
+ required: true,
414
+ label: { key: "verification.labels.panNumber" },
415
+ input: { maxLength: 10 },
416
+ rules: [{
417
+ id: "exactLength",
418
+ params: { length: 10 }
419
+ }]
420
+ },
421
+ {
422
+ name: "houseNo",
423
+ kind: "text",
424
+ group: "address",
425
+ section: "address",
426
+ required: true,
427
+ label: { key: "verification.labels.houseNo" }
428
+ },
429
+ {
430
+ name: "street",
431
+ kind: "text",
432
+ group: "address",
433
+ section: "address",
434
+ required: true,
435
+ widget: "addressSearch",
436
+ label: { key: "verification.labels.street" },
437
+ input: { autofill: "addressLine1" },
438
+ rules: [{ id: "noPoBox" }]
439
+ },
440
+ {
441
+ name: "city",
442
+ kind: "text",
443
+ group: "address",
444
+ section: "address",
445
+ required: true,
446
+ label: { key: "verification.labels.city" },
447
+ input: { autofill: "addressLevel2" }
448
+ },
449
+ {
450
+ name: "state",
451
+ kind: "text",
452
+ group: "address",
453
+ section: "address",
454
+ required: true,
455
+ label: { key: "verification.labels.state" },
456
+ placeholder: {
457
+ key: "verification.placeholder.stateCode",
458
+ params: { states: "RJ, SP" }
459
+ },
460
+ input: { autofill: "addressLevel1" },
461
+ payload: { transforms: [{ id: "uppercase" }] }
462
+ },
463
+ {
464
+ name: "postalCode",
465
+ kind: "text",
466
+ group: "address",
467
+ section: "address",
468
+ required: true,
469
+ label: { key: "verification.labels.postalCode" },
470
+ input: {
471
+ maxLength: 9,
472
+ autofill: "postalCode"
473
+ },
474
+ rules: [{ id: "postalCodeFormat" }],
475
+ payload: { transforms: [{
476
+ id: "stripSeparators",
477
+ params: { chars: "- " }
478
+ }] }
479
+ },
480
+ {
481
+ name: "dlNumber",
482
+ kind: "text",
483
+ group: "dlNumber",
484
+ section: "driverLicense",
485
+ required: true,
486
+ label: { key: "verification.labels.dlNumber" }
487
+ },
488
+ {
489
+ name: "dlState",
490
+ kind: "choice",
491
+ group: "dlState",
492
+ section: "driverLicense",
493
+ required: true,
494
+ widget: "select",
495
+ label: { key: "verification.labels.dlState" },
496
+ placeholder: { key: "verification.placeholder.state" },
497
+ optionsRef: "US_STATES"
498
+ },
499
+ {
500
+ name: "dlExpireAt",
501
+ kind: "date",
502
+ group: "dlExpireAt",
503
+ section: "driverLicense",
504
+ required: true,
505
+ label: { key: "verification.labels.dlExpireAt" }
506
+ }
507
+ ],
508
+ submit: {
509
+ static: { plugins: ["kyc"] },
510
+ context: {
511
+ source: "source",
512
+ countryCode: "country"
513
+ }
514
+ }
515
+ },
516
+ "ekyc/US/US_CREDIT_TELCO": {
517
+ schemaVersion: 1,
518
+ vocabulary: "1.0",
519
+ id: "ekyc/US/US_CREDIT_TELCO",
520
+ module: "ekyc",
521
+ country: "US",
522
+ source: "US_CREDIT_TELCO",
523
+ sections: [{ id: "address" }, { id: "driverLicense" }],
524
+ groups: [{
525
+ group: "name",
526
+ whenDisabled: "forceShow"
527
+ }],
528
+ fields: [
529
+ {
530
+ name: "firstName",
531
+ kind: "text",
532
+ group: "name",
533
+ required: true,
534
+ label: { key: "verification.labels.firstName" },
535
+ placeholder: { key: "verification.placeholder.firstName" },
536
+ input: {
537
+ maxLength: 100,
538
+ autofill: "givenName"
539
+ }
540
+ },
541
+ {
542
+ name: "surName",
543
+ kind: "text",
544
+ group: "name",
545
+ required: true,
546
+ label: { key: "verification.labels.lastName" },
547
+ placeholder: { key: "verification.placeholder.lastName" },
548
+ input: {
549
+ maxLength: 100,
550
+ autofill: "familyName"
551
+ }
552
+ },
553
+ {
554
+ name: "dateOfBirth",
555
+ kind: "date",
556
+ group: "dateOfBirth",
557
+ label: { key: "verification.labels.dateOfBirth" },
558
+ input: { autofill: "birthday" }
559
+ },
560
+ {
561
+ name: "email",
562
+ kind: "text",
563
+ group: "email",
564
+ required: true,
565
+ label: { key: "verification.labels.email" },
566
+ placeholder: { key: "verification.placeholder.email" },
567
+ input: {
568
+ keyboard: "email",
569
+ autofill: "email"
570
+ },
571
+ rules: [{ id: "emailFormat" }]
572
+ },
573
+ {
574
+ name: "phone",
575
+ kind: "phone",
576
+ group: "phone",
577
+ label: { key: "verification.labels.phone" },
578
+ input: { autofill: "phone" },
579
+ phone: { lockCountry: true },
580
+ rules: [{ id: "phoneFormat" }],
581
+ payload: { transforms: [{ id: "e164" }] }
582
+ },
583
+ {
584
+ name: "ssn",
585
+ kind: "text",
586
+ group: "ssn",
587
+ widget: "masked",
588
+ label: { key: "verification.labels.ssn" },
589
+ input: {
590
+ maxLength: 11,
591
+ keyboard: "numeric"
592
+ },
593
+ rules: [{ id: "ssnFormat" }],
594
+ payload: { transforms: [{
595
+ id: "stripSeparators",
596
+ params: { chars: "-" }
597
+ }] }
598
+ },
599
+ {
600
+ name: "nationality",
601
+ kind: "text",
602
+ group: "nationality",
603
+ required: true,
604
+ label: { key: "verification.labels.nationality" },
605
+ payload: { transforms: [{ id: "uppercase" }] }
606
+ },
607
+ {
608
+ name: "last4SSN",
609
+ kind: "text",
610
+ group: "last4SSN",
611
+ required: true,
612
+ label: { key: "verification.labels.last4SSN" },
613
+ input: {
614
+ maxLength: 4,
615
+ keyboard: "numeric"
616
+ }
617
+ },
618
+ {
619
+ name: "idNum",
620
+ kind: "text",
621
+ group: "idNumber",
622
+ required: true,
623
+ label: { key: "verification.labels.idNum" },
624
+ input: { maxLength: 13 }
625
+ },
626
+ {
627
+ name: "idNum1",
628
+ kind: "text",
629
+ group: "idNumber1",
630
+ required: true,
631
+ label: { key: "verification.labels.idNum1" }
632
+ },
633
+ {
634
+ name: "gender",
635
+ kind: "choice",
636
+ group: "gender",
637
+ required: true,
638
+ widget: "radio",
639
+ label: { key: "verification.labels.gender" },
640
+ options: [{
641
+ value: "F",
642
+ label: { key: "common.female" }
643
+ }, {
644
+ value: "M",
645
+ label: { key: "common.male" }
646
+ }]
647
+ },
648
+ {
649
+ name: "panNumber",
650
+ kind: "text",
651
+ group: "panNumber",
652
+ required: true,
653
+ label: { key: "verification.labels.panNumber" },
654
+ input: { maxLength: 10 },
655
+ rules: [{
656
+ id: "exactLength",
657
+ params: { length: 10 }
658
+ }]
659
+ },
660
+ {
661
+ name: "street",
662
+ kind: "text",
663
+ group: "address",
664
+ section: "address",
665
+ widget: "addressSearch",
666
+ label: { key: "verification.labels.street" },
667
+ input: { autofill: "addressLine1" },
668
+ rules: [{ id: "noPoBox" }]
669
+ },
670
+ {
671
+ name: "apartment",
672
+ kind: "text",
673
+ group: "address",
674
+ section: "address",
675
+ label: { key: "verification.labels.apartment" },
676
+ placeholder: { key: "verification.placeholder.apartment" },
677
+ input: { autofill: "addressLine2" }
678
+ },
679
+ {
680
+ name: "city",
681
+ kind: "text",
682
+ group: "address",
683
+ section: "address",
684
+ label: { key: "verification.labels.city" },
685
+ input: { autofill: "addressLevel2" }
686
+ },
687
+ {
688
+ name: "state",
689
+ kind: "choice",
690
+ group: "address",
691
+ section: "address",
692
+ widget: "select",
693
+ label: { key: "verification.labels.chooseState" },
694
+ placeholder: { key: "verification.placeholder.state" },
695
+ input: { autofill: "addressLevel1" },
696
+ optionsRef: "US_STATES",
697
+ payload: { transforms: [{ id: "uppercase" }] }
698
+ },
699
+ {
700
+ name: "postalCode",
701
+ kind: "text",
702
+ group: "address",
703
+ section: "address",
704
+ label: { key: "verification.labels.zipCode" },
705
+ input: {
706
+ maxLength: 10,
707
+ autofill: "postalCode"
708
+ },
709
+ rules: [{ id: "postalCodeFormat" }],
710
+ payload: { transforms: [{
711
+ id: "stripSeparators",
712
+ params: { chars: "- " }
713
+ }] }
714
+ },
715
+ {
716
+ name: "dlNumber",
717
+ kind: "text",
718
+ group: "dlNumber",
719
+ section: "driverLicense",
720
+ required: true,
721
+ label: { key: "verification.labels.dlNumber" }
722
+ },
723
+ {
724
+ name: "dlState",
725
+ kind: "choice",
726
+ group: "dlState",
727
+ section: "driverLicense",
728
+ required: true,
729
+ widget: "select",
730
+ label: { key: "verification.labels.dlState" },
731
+ placeholder: { key: "verification.placeholder.state" },
732
+ optionsRef: "US_STATES"
733
+ },
734
+ {
735
+ name: "dlExpireAt",
736
+ kind: "date",
737
+ group: "dlExpireAt",
738
+ section: "driverLicense",
739
+ required: true,
740
+ label: { key: "verification.labels.dlExpireAt" }
741
+ }
742
+ ],
743
+ groupRules: [{
744
+ id: "oneOfRequired",
745
+ fields: ["dateOfBirth", "ssn"],
746
+ message: { key: "verification.errors.dobOrSsnRequired" }
747
+ }],
748
+ submit: {
749
+ static: { plugins: ["kyc"] },
750
+ context: {
751
+ source: "source",
752
+ countryCode: "country"
753
+ }
754
+ }
755
+ }
756
+ };
757
+ //#endregion
758
+ //#region src/modules/ekyc/ekycForm.ts
759
+ /**
760
+ * eKYC adapter for form definitions.
761
+ *
762
+ * Selects the bundled definition for a source and country, resolves it against
763
+ * the verification fields from module configuration, and projects the result
764
+ * to today's public `EkycFieldDef[]` shape, including the `validation` arrays
765
+ * today's validators run. A pair without a definition this projection can
766
+ * express keeps the current builder.
767
+ */
768
+ /** eKYC group id → the key `getEKYCFields` sets in `EkycVerificationFields`. */
769
+ const EKYC_GROUP_KEYS = {
770
+ name: "name",
771
+ dateOfBirth: "date of birth",
772
+ email: "email",
773
+ phone: "phone",
774
+ address: "address",
775
+ ssn: "SSN",
776
+ last4SSN: "last4SSN",
777
+ idNumber: "idNum",
778
+ idNumber1: "idNum1",
779
+ nationality: "nationality",
780
+ gender: "gender",
781
+ panNumber: "panNumber",
782
+ dlNumber: "dlNumber",
783
+ dlState: "dlState",
784
+ dlExpireAt: "dlExpireAt"
785
+ };
786
+ const OPTION_LISTS = { US_STATES: usStateOptions };
787
+ /** Vocabulary rules expressed as today's `EkycValidationRule` objects. */
788
+ const RULES = {
789
+ cpf: () => ({ type: "cpf" }),
790
+ ssnFormat: () => ({ type: "ssnFormat" }),
791
+ noPoBox: () => ({ type: "noPoBox" }),
792
+ emailFormat: () => ({ type: "emailFormat" }),
793
+ postalCodeFormat: ({ country }) => ({
794
+ type: "postalCodeFormat",
795
+ country
796
+ }),
797
+ phoneFormat: ({ country, required }) => ({
798
+ type: "phoneFormat",
799
+ country,
800
+ optional: !required
801
+ }),
802
+ exactLength: ({ params }) => ({
803
+ type: "exactLength",
804
+ length: Number(params.length)
805
+ })
806
+ };
807
+ /**
808
+ * What the projection can express today. Request-body transforms are listed
809
+ * because `buildSubmitPayload` already applies them; `requiredWhen` waits for
810
+ * decision B20, so no condition is supported yet.
811
+ */
812
+ const EKYC_SUPPORTED_IDS = {
813
+ schemaVersions: [1],
814
+ vocabulary: "1.0",
815
+ kinds: /* @__PURE__ */ new Set([
816
+ "text",
817
+ "date",
818
+ "choice",
819
+ "phone"
820
+ ]),
821
+ groups: new Set(Object.keys(EKYC_GROUP_KEYS)),
822
+ rules: new Set(Object.keys(RULES)),
823
+ transforms: /* @__PURE__ */ new Set([
824
+ "stripSeparators",
825
+ "e164",
826
+ "uppercase"
827
+ ]),
828
+ groupRules: /* @__PURE__ */ new Set(["oneOfRequired"]),
829
+ optionLists: new Set(Object.keys(OPTION_LISTS)),
830
+ conditions: /* @__PURE__ */ new Set()
831
+ };
832
+ /** Today's field shape only flags `middleName` as optional. */
833
+ const LEGACY_OPTIONAL_FLAG = /* @__PURE__ */ new Set(["middleName"]);
834
+ const projectable = /* @__PURE__ */ new WeakMap();
835
+ /** Whether every part of a definition maps onto today's `EkycFieldDef`. */
836
+ function isProjectableEkycDefinition(definition) {
837
+ let result = projectable.get(definition);
838
+ if (result === void 0) {
839
+ result = definition.module === "ekyc" && checkSupport(definition, EKYC_SUPPORTED_IDS).supported && (definition.groupRules ?? []).every((rule) => !rule.message || rule.message.key === "verification.errors.dobOrSsnRequired");
840
+ projectable.set(definition, result);
841
+ }
842
+ return result;
843
+ }
844
+ const bundled = createBundledDefinitionSource(EKYC_DEFINITIONS);
845
+ /** The bundled definition for exactly this source and country, if it is projectable. */
846
+ function selectEkycDefinition(source, country) {
847
+ const definition = bundled.select({
848
+ module: "ekyc",
849
+ source,
850
+ country
851
+ });
852
+ return definition && isProjectableEkycDefinition(definition) ? definition : void 0;
853
+ }
854
+ function toEkycResolveContext(verificationFields, enablePhoneRisk) {
855
+ return {
856
+ groups: Object.fromEntries(Object.entries(EKYC_GROUP_KEYS).map(([group, key]) => [group, Boolean(verificationFields[key])])),
857
+ phoneRisk: enablePhoneRisk
858
+ };
859
+ }
860
+ function fieldType(field) {
861
+ if (field.kind === "choice") return field.widget === "radio" ? "radio" : "dropdown";
862
+ return field.kind === "date" || field.kind === "phone" ? field.kind : "text";
863
+ }
864
+ function fieldOptions(field) {
865
+ if (field.optionsRef) return OPTION_LISTS[field.optionsRef];
866
+ return field.options?.map((option) => ({
867
+ value: option.value,
868
+ label: option.label.key
869
+ }));
870
+ }
871
+ function projectField(resolved, verificationFields, country) {
872
+ const { field, required } = resolved;
873
+ const groupKey = EKYC_GROUP_KEYS[field.group];
874
+ const source = groupKey && verificationFields[groupKey] || "user_input";
875
+ const def = {
876
+ name: field.name,
877
+ type: fieldType(field),
878
+ label: field.label.key,
879
+ source,
880
+ required
881
+ };
882
+ if (field.placeholder) {
883
+ def.placeholder = field.placeholder.key;
884
+ if (field.placeholder.params) def.placeholderParams = { ...field.placeholder.params };
885
+ }
886
+ if (field.displayLabel) def.displayLabel = field.displayLabel.text ?? field.displayLabel.key;
887
+ if (field.input?.maxLength !== void 0) def.maxLength = field.input.maxLength;
888
+ const options = fieldOptions(field);
889
+ if (options) def.options = options;
890
+ if (field.section) def.section = field.section;
891
+ if (field.kind === "phone") def.disableCountrySelector = resolved.phoneLocked;
892
+ if (LEGACY_OPTIONAL_FLAG.has(field.name)) def.optional = true;
893
+ const validation = required ? [{ type: "required" }] : [];
894
+ for (const rule of field.rules ?? []) {
895
+ const project = RULES[rule.id];
896
+ if (project) validation.push(project({
897
+ country,
898
+ required,
899
+ params: rule.params ?? {}
900
+ }));
901
+ }
902
+ if (validation.length > 0) def.validation = validation;
903
+ return def;
904
+ }
905
+ /**
906
+ * Projects a resolved definition to today's `EkycFieldDef[]`, identical to
907
+ * what `legacyBuildFieldDefs` returns for the same source and country.
908
+ */
909
+ function projectEkycFields(form, verificationFields, country) {
910
+ const defs = form.fields.map((resolved) => projectField(resolved, verificationFields, country));
911
+ for (const { fields } of form.groupRules) for (const def of defs) if (fields.includes(def.name)) def.validation = [{
912
+ type: "oneOfRequired",
913
+ fields: [...fields]
914
+ }, ...def.validation ?? []];
915
+ return defs;
916
+ }
917
+ //#endregion
127
918
  //#region src/modules/ekyc/ekycActions.ts
128
919
  const dateFormattingInstance = new DateFormattingProvider();
129
920
  function buildValidationRules(field, country, configSource) {
@@ -158,7 +949,18 @@ function applyOneOfRequiredGroups(defs, configSource) {
158
949
  }, ...def.validation ?? []];
159
950
  }
160
951
  }
952
+ /**
953
+ * Builds the form's field defs. A source with a form definition for exactly
954
+ * this country reads it (`packages/form-definitions/catalog/ekyc`); any other
955
+ * pair keeps the current builder.
956
+ */
161
957
  function buildFieldDefs(fields, configSource, country, enablePhoneRisk = false) {
958
+ const definition = selectEkycDefinition(configSource, country);
959
+ if (definition) return projectEkycFields(resolveForm(definition, toEkycResolveContext(fields, enablePhoneRisk)), fields, country);
960
+ return legacyBuildFieldDefs(fields, configSource, country, enablePhoneRisk);
961
+ }
962
+ /** The per-source builder for sources without a form definition yet. */
963
+ function legacyBuildFieldDefs(fields, configSource, country, enablePhoneRisk = false) {
162
964
  const defs = [];
163
965
  const add = (name, type, label, source, opts) => {
164
966
  if (source === false) return;