@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.
- package/dist/{FaceDetectionProvider-9IwB7jcM.esm.js → FaceDetectionProvider-CjWCKcIu.esm.js} +5 -5
- package/dist/ae-signature.esm.js +1 -1
- package/dist/{apiError-CFwIWUtz.esm.js → apiError-DgSftpa0.esm.js} +1 -1
- package/dist/authentication.esm.js +2 -2
- package/dist/{authenticationManager-DHrqI5Le.esm.js → authenticationManager--1lefT83.esm.js} +3 -3
- package/dist/{authenticationStateMachine-CDsC16Jn.esm.js → authenticationStateMachine-AVH_s6--.esm.js} +2 -2
- package/dist/{deepsightLoader-CWjI76eb.esm.js → deepsightLoader-Drgk4Jv9.esm.js} +4 -4
- package/dist/{deepsightService-Dq_9MGNi.esm.js → deepsightService-xMDI8RDs.esm.js} +1 -1
- package/dist/dynamic-forms.esm.js +2 -2
- package/dist/{dynamicFormsManager-CCzxliyj.esm.js → dynamicFormsManager-D7wWeNGK.esm.js} +1 -1
- package/dist/{dynamicFormsStateMachine-DVbgcw96.esm.js → dynamicFormsStateMachine-9sqWyWLc.esm.js} +1 -1
- package/dist/ekyb.esm.js +3 -3
- package/dist/{ekybManager-DtdNyCkV.esm.js → ekybManager-DLytGFSA.esm.js} +1 -1
- package/dist/{ekybStateMachine-Cd0nGdXM.esm.js → ekybStateMachine-fRzoh4AI.esm.js} +1 -1
- package/dist/ekyc.esm.js +3 -3
- package/dist/{ekycManager-DZH51PnN.esm.js → ekycManager-RaSSnmxD.esm.js} +1 -1
- package/dist/{ekycStateMachine-DnKlILfu.esm.js → ekycStateMachine-BqacNxVI.esm.js} +803 -1
- package/dist/{ekycUtils-3FIL6m1x.esm.js → ekycUtils-DrRSBMVL.esm.js} +28 -0
- package/dist/electronic-signature.esm.js +1 -1
- package/dist/{electronicSignatureManager-B_SHlY1L.esm.js → electronicSignatureManager-BR38Ogjf.esm.js} +1 -1
- package/dist/extensibility.d.ts +4 -4
- package/dist/extensibility.esm.js +11 -11
- package/dist/{faceCaptureManagerFactory-1uGiHaoF.esm.js → faceCaptureManagerFactory-B1BrC2K4.esm.js} +1 -1
- package/dist/{faceCaptureSetup-BYnZ3A8a.esm.js → faceCaptureSetup-Dmz6aiNH.esm.js} +3 -3
- package/dist/{feature-management-XxXkowCy.esm.js → feature-management-pS1G_jQ5.esm.js} +1 -1
- package/dist/feature-management.esm.js +1 -1
- package/dist/flow.d.ts +1 -1
- package/dist/flow.esm.js +3 -3
- package/dist/{flowCompletionService-OHsAMzl8.esm.js → flowCompletionService-CVBZUlWT.esm.js} +1 -1
- package/dist/{flowServices-D3b4BP89.esm.js → flowServices-CCPh3tqQ.esm.js} +5 -5
- package/dist/geolocation.esm.js +2 -2
- package/dist/{geolocationManager-DqI8ho5R.esm.js → geolocationManager-CG3nIRbs.esm.js} +1 -1
- package/dist/{geolocationStateMachine-Je2uPWor.esm.js → geolocationStateMachine-Z9o9iDIY.esm.js} +1 -1
- package/dist/id-selfie-flow.esm.js +7 -7
- package/dist/id.d.ts +2 -2
- package/dist/id.esm.js +3 -3
- package/dist/{idCaptureDefaults-BjP8SevF.esm.js → idCaptureDefaults-DlsyJMOW.esm.js} +1 -1
- package/dist/{idCaptureManager-DW3eER4t.d.ts → idCaptureManager-BY97SRCV.d.ts} +1 -1
- package/dist/{idCaptureManager-I5L_IVbR.esm.js → idCaptureManager-DmoOx0O5.esm.js} +3 -3
- package/dist/{idCaptureServices-t11U9Anc.esm.js → idCaptureServices-D55prH0r.esm.js} +3 -3
- package/dist/{idCaptureStateMachine-Dv1tDMKs.esm.js → idCaptureStateMachine-MV0CtrZ9.esm.js} +44 -21
- package/dist/identity-reuse.d.ts +1 -1
- package/dist/{identityReuseManager-ooAbp6Kc.d.ts → identityReuseManager-B1birg5X.d.ts} +4 -4
- package/dist/index.d.ts +1 -1
- package/dist/index.esm.js +1 -1
- package/dist/mandatory-consent.d.ts +1 -1
- package/dist/{mandatoryConsentManager-BkaLkcA2.d.ts → mandatoryConsentManager-DDixKrq0.d.ts} +4 -4
- package/dist/qe-signature.esm.js +1 -1
- package/dist/{runChildModule-9q7BQwPd.esm.js → runChildModule-DXNgGwGn.esm.js} +1 -1
- package/dist/{sdkVersion-g8ehOQhP.esm.js → sdkVersion-DM8nidSt.esm.js} +1 -1
- package/dist/selfie.esm.js +6 -6
- package/dist/{selfieErrorUtils-zRAt9WeG.esm.js → selfieErrorUtils-B3Gdyvaf.esm.js} +1 -1
- package/dist/{selfieManager-BVcizHEI.esm.js → selfieManager-gLy-_nNC.esm.js} +3 -3
- package/dist/{selfieStateMachine-CBkLfNU3.esm.js → selfieStateMachine-BiYWExHE.esm.js} +3 -3
- package/dist/{session-XeaMJEO1.esm.js → session-CtVdey6m.esm.js} +3 -3
- package/dist/session.esm.js +4 -4
- package/dist/{sessionInitializer-LBbZHbPK.esm.js → sessionInitializer-V3iatb38.esm.js} +3 -3
- package/dist/{setup-CkMpP7pu.esm.js → setup-C-Nol_jL.esm.js} +22 -5
- package/dist/{setup-oKDzNC62.d.ts → setup-lgkQ8dJW.d.ts} +11 -0
- package/dist/{trueSightService-DtuHbL0_.esm.js → trueSightService-D7fIDGRl.esm.js} +1 -1
- package/dist/{types-CwCWyBEi.d.ts → types-CyPUIpzf.d.ts} +19 -5
- package/dist/video-selfie.esm.js +3 -3
- package/dist/{videoSelfieCameraWarmer-pt56Pcfi.esm.js → videoSelfieCameraWarmer-MXduX5t-.esm.js} +4 -4
- package/dist/wasm.d.ts +1 -1
- package/dist/wasm.esm.js +2 -2
- package/dist/workflow.esm.js +16 -16
- 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-
|
|
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;
|