@codedartdev/coinsentry-sdk 0.1.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 (66) hide show
  1. package/README.md +271 -0
  2. package/dist/brand/config.d.ts +78 -0
  3. package/dist/brand/config.d.ts.map +1 -0
  4. package/dist/brand/config.js +274 -0
  5. package/dist/brand/config.js.map +1 -0
  6. package/dist/brand/index.d.ts +4 -0
  7. package/dist/brand/index.d.ts.map +1 -0
  8. package/dist/brand/index.js +2 -0
  9. package/dist/brand/index.js.map +1 -0
  10. package/dist/brand/types.d.ts +122 -0
  11. package/dist/brand/types.d.ts.map +1 -0
  12. package/dist/brand/types.js +2 -0
  13. package/dist/brand/types.js.map +1 -0
  14. package/dist/client.d.ts +169 -0
  15. package/dist/client.d.ts.map +1 -0
  16. package/dist/client.js +239 -0
  17. package/dist/client.js.map +1 -0
  18. package/dist/errors.d.ts +32 -0
  19. package/dist/errors.d.ts.map +1 -0
  20. package/dist/errors.js +143 -0
  21. package/dist/errors.js.map +1 -0
  22. package/dist/guards.d.ts +12 -0
  23. package/dist/guards.d.ts.map +1 -0
  24. package/dist/guards.js +76 -0
  25. package/dist/guards.js.map +1 -0
  26. package/dist/http.d.ts +38 -0
  27. package/dist/http.d.ts.map +1 -0
  28. package/dist/http.js +175 -0
  29. package/dist/http.js.map +1 -0
  30. package/dist/index.d.ts +16 -0
  31. package/dist/index.d.ts.map +1 -0
  32. package/dist/index.js +8 -0
  33. package/dist/index.js.map +1 -0
  34. package/dist/kyc/config.d.ts +20 -0
  35. package/dist/kyc/config.d.ts.map +1 -0
  36. package/dist/kyc/config.js +224 -0
  37. package/dist/kyc/config.js.map +1 -0
  38. package/dist/kyc/flow.d.ts +37 -0
  39. package/dist/kyc/flow.d.ts.map +1 -0
  40. package/dist/kyc/flow.js +329 -0
  41. package/dist/kyc/flow.js.map +1 -0
  42. package/dist/kyc/index.d.ts +6 -0
  43. package/dist/kyc/index.d.ts.map +1 -0
  44. package/dist/kyc/index.js +4 -0
  45. package/dist/kyc/index.js.map +1 -0
  46. package/dist/kyc/locale.d.ts +17 -0
  47. package/dist/kyc/locale.d.ts.map +1 -0
  48. package/dist/kyc/locale.js +40 -0
  49. package/dist/kyc/locale.js.map +1 -0
  50. package/dist/kyc/types.d.ts +289 -0
  51. package/dist/kyc/types.d.ts.map +1 -0
  52. package/dist/kyc/types.js +2 -0
  53. package/dist/kyc/types.js.map +1 -0
  54. package/dist/products.d.ts +280 -0
  55. package/dist/products.d.ts.map +1 -0
  56. package/dist/products.js +302 -0
  57. package/dist/products.js.map +1 -0
  58. package/dist/realtime.d.ts +33 -0
  59. package/dist/realtime.d.ts.map +1 -0
  60. package/dist/realtime.js +28 -0
  61. package/dist/realtime.js.map +1 -0
  62. package/dist/types.d.ts +145 -0
  63. package/dist/types.d.ts.map +1 -0
  64. package/dist/types.js +2 -0
  65. package/dist/types.js.map +1 -0
  66. package/package.json +46 -0
@@ -0,0 +1,224 @@
1
+ export function normalizeStringList(value) {
2
+ if (Array.isArray(value)) {
3
+ return value.flatMap((item) => normalizeStringList(item));
4
+ }
5
+ if (typeof value === 'string') {
6
+ return value
7
+ .split(',')
8
+ .map((item) => item.trim())
9
+ .filter(Boolean);
10
+ }
11
+ return [];
12
+ }
13
+ export function normalizeClientFlowStep(step) {
14
+ return {
15
+ ...step,
16
+ required_fields: normalizeStringList(step.required_fields),
17
+ required_documents: normalizeStringList(step.required_documents),
18
+ entity_types: normalizeStringList(step.entity_types),
19
+ document_type_options: normalizeStringList(step.document_type_options),
20
+ };
21
+ }
22
+ export function normalizeClientFlow(value) {
23
+ if (!Array.isArray(value))
24
+ return [];
25
+ return value
26
+ .filter((step) => Boolean(step && typeof step === 'object'))
27
+ .map(normalizeClientFlowStep);
28
+ }
29
+ export function normalizeDocumentTypeChoices(value) {
30
+ if (Array.isArray(value)) {
31
+ return value.flatMap((item) => {
32
+ if (item && typeof item === 'object') {
33
+ const record = item;
34
+ const optionValue = String(record.value ?? '').trim();
35
+ if (!optionValue)
36
+ return [];
37
+ return [{
38
+ value: optionValue,
39
+ label: String(record.label ?? optionValue).trim() || optionValue,
40
+ }];
41
+ }
42
+ if (typeof item === 'string') {
43
+ const optionValue = item.trim();
44
+ return optionValue ? [{ value: optionValue, label: optionValue }] : [];
45
+ }
46
+ return [];
47
+ });
48
+ }
49
+ return normalizeStringList(value).map((optionValue) => ({
50
+ value: optionValue,
51
+ label: optionValue,
52
+ }));
53
+ }
54
+ export function uniqueDocumentChoices(choices) {
55
+ const seen = new Set();
56
+ return choices.filter((choice) => {
57
+ const value = choice.value.trim();
58
+ if (!value || seen.has(value))
59
+ return false;
60
+ seen.add(value);
61
+ return true;
62
+ });
63
+ }
64
+ export function getKycPrefill(requirements) {
65
+ if (!requirements)
66
+ return {};
67
+ const kycForm = requirements.kyc_form;
68
+ if (kycForm?.prefill && typeof kycForm.prefill === 'object')
69
+ return kycForm.prefill;
70
+ if (requirements.form_prefill && typeof requirements.form_prefill === 'object')
71
+ return requirements.form_prefill;
72
+ return {};
73
+ }
74
+ function uniqueStrings(values) {
75
+ return Array.from(new Set(values.map((value) => value.trim()).filter(Boolean)));
76
+ }
77
+ function normalizeFieldName(value) {
78
+ return value.trim().toLowerCase();
79
+ }
80
+ function recordValue(value) {
81
+ return value && typeof value === 'object' ? value : {};
82
+ }
83
+ const PREFILL_FIELD_ALIASES = {
84
+ birth_date: ['birth_date', 'date_of_birth'],
85
+ date_of_birth: ['date_of_birth', 'birth_date'],
86
+ document_number: ['document_number', 'tax_id'],
87
+ tax_id: ['tax_id', 'document_number'],
88
+ };
89
+ const STRONG_READ_ONLY_LIST_KEYS = [
90
+ 'locked_fields',
91
+ 'strong_read_only_fields',
92
+ 'force_read_only_fields',
93
+ 'forced_read_only_fields',
94
+ 'hard_read_only_fields',
95
+ ];
96
+ const STRONG_READ_ONLY_MAP_KEYS = [
97
+ 'field_locks',
98
+ 'read_only_locks',
99
+ ];
100
+ function prefillAliasesForField(field) {
101
+ const normalized = normalizeFieldName(field);
102
+ return PREFILL_FIELD_ALIASES[normalized] ?? [normalized];
103
+ }
104
+ export function hasRealKycPrefillValue(value) {
105
+ if (value === null || value === undefined)
106
+ return false;
107
+ if (typeof value === 'string') {
108
+ const trimmed = value.trim();
109
+ if (!trimmed || trimmed.includes('*'))
110
+ return false;
111
+ return /[A-Za-z0-9]/.test(trimmed);
112
+ }
113
+ if (typeof value === 'number')
114
+ return Number.isFinite(value);
115
+ if (typeof value === 'boolean')
116
+ return true;
117
+ if (Array.isArray(value))
118
+ return value.length > 0;
119
+ if (typeof value === 'object')
120
+ return Object.keys(value).length > 0;
121
+ return false;
122
+ }
123
+ function hasRealKycPrefillForField(requirements, field) {
124
+ const prefill = getKycPrefill(requirements);
125
+ return prefillAliasesForField(field).some((alias) => hasRealKycPrefillValue(prefill[alias]));
126
+ }
127
+ export function getKycReadOnlyFields(requirements) {
128
+ if (!requirements)
129
+ return [];
130
+ const kycFormFields = normalizeStringList(requirements.kyc_form?.read_only_fields);
131
+ return uniqueStrings([
132
+ ...kycFormFields,
133
+ ...normalizeStringList(requirements.read_only_fields),
134
+ ]);
135
+ }
136
+ function getKycStrongReadOnlyFields(requirements) {
137
+ if (!requirements)
138
+ return [];
139
+ const kycForm = recordValue(requirements.kyc_form);
140
+ const topLevel = recordValue(requirements);
141
+ const listFields = STRONG_READ_ONLY_LIST_KEYS.flatMap((key) => [
142
+ ...normalizeStringList(kycForm[key]),
143
+ ...normalizeStringList(topLevel[key]),
144
+ ]);
145
+ const mapFields = STRONG_READ_ONLY_MAP_KEYS.flatMap((key) => [
146
+ ...strongReadOnlyFieldsFromMap(kycForm[key]),
147
+ ...strongReadOnlyFieldsFromMap(topLevel[key]),
148
+ ]);
149
+ return uniqueStrings([...listFields, ...mapFields]);
150
+ }
151
+ function strongReadOnlyFieldsFromMap(value) {
152
+ const locks = recordValue(value);
153
+ return Object.entries(locks).flatMap(([field, lock]) => {
154
+ if (lock === true)
155
+ return [field];
156
+ if (typeof lock !== 'string')
157
+ return [];
158
+ const normalized = lock.trim().toLowerCase();
159
+ return ['strong', 'hard', 'locked', 'force', 'forced', 'read_only'].includes(normalized)
160
+ ? [field]
161
+ : [];
162
+ });
163
+ }
164
+ export function isKycFieldReadOnly(requirements, field) {
165
+ const normalizedField = normalizeFieldName(field);
166
+ const strongReadOnlyFields = getKycStrongReadOnlyFields(requirements).map(normalizeFieldName);
167
+ if (strongReadOnlyFields.includes(normalizedField))
168
+ return true;
169
+ const readOnlyFields = getKycReadOnlyFields(requirements).map(normalizeFieldName);
170
+ return readOnlyFields.includes(normalizedField)
171
+ && hasRealKycPrefillForField(requirements, normalizedField);
172
+ }
173
+ export function shouldLockKycFiscalDocumentField(options) {
174
+ return options.configuredReadOnly
175
+ && options.normalized.length > 0
176
+ && options.isValid;
177
+ }
178
+ function getConfigClientFlow(config) {
179
+ const record = config && typeof config === 'object' ? config : {};
180
+ return [
181
+ ...normalizeClientFlow(record.client_flow),
182
+ ...normalizeClientFlow(record.compliance_config?.client_flow),
183
+ ...normalizeClientFlow(record.flow_config?.compliance_config?.client_flow),
184
+ ];
185
+ }
186
+ export function getRegistrationDocumentConfig(config) {
187
+ const record = config && typeof config === 'object' ? config : {};
188
+ const direct = record.registration_document;
189
+ if (direct && typeof direct === 'object') {
190
+ return direct;
191
+ }
192
+ const flowConfig = record.flow_config && typeof record.flow_config === 'object'
193
+ ? record.flow_config
194
+ : {};
195
+ const nested = flowConfig.registration_document;
196
+ if (nested && typeof nested === 'object') {
197
+ return nested;
198
+ }
199
+ return null;
200
+ }
201
+ export function getRegistrationTaxIdField(config) {
202
+ const field = String(getRegistrationDocumentConfig(config)?.field ?? 'tax_id').trim();
203
+ return field || 'tax_id';
204
+ }
205
+ export function shouldCollectRegistrationTaxId(config) {
206
+ const registrationDocument = getRegistrationDocumentConfig(config);
207
+ if (registrationDocument?.collect_tax_id === true)
208
+ return true;
209
+ return getConfigClientFlow(config).some((step) => step.screen === 'account' && step.collect_tax_id === true);
210
+ }
211
+ export function isRegistrationTaxIdRequired(config) {
212
+ const registrationDocument = getRegistrationDocumentConfig(config);
213
+ const taxIdField = getRegistrationTaxIdField(config);
214
+ if (registrationDocument?.collect_tax_id === true && registrationDocument.required === true) {
215
+ return true;
216
+ }
217
+ return getConfigClientFlow(config).some((step) => {
218
+ if (step.screen !== 'account')
219
+ return false;
220
+ const requiredFields = normalizeStringList(step.required_fields);
221
+ return requiredFields.includes(taxIdField) || requiredFields.includes('tax_id');
222
+ });
223
+ }
224
+ //# sourceMappingURL=config.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"config.js","sourceRoot":"","sources":["../../src/kyc/config.ts"],"names":[],"mappings":"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","sourcesContent":["import type {\n ClientFlowStep,\n DocumentTypeChoice,\n KycRequirements,\n KycFormPrefill,\n RegistrationDocumentConfig,\n} from './types.js';\n\nexport function normalizeStringList(value: unknown): string[] {\n if (Array.isArray(value)) {\n return value.flatMap((item) => normalizeStringList(item));\n }\n\n if (typeof value === 'string') {\n return value\n .split(',')\n .map((item) => item.trim())\n .filter(Boolean);\n }\n\n return [];\n}\n\nexport function normalizeClientFlowStep(step: ClientFlowStep): ClientFlowStep {\n return {\n ...step,\n required_fields: normalizeStringList(step.required_fields),\n required_documents: normalizeStringList(step.required_documents),\n entity_types: normalizeStringList(step.entity_types) as ClientFlowStep['entity_types'],\n document_type_options: normalizeStringList(step.document_type_options),\n };\n}\n\nexport function normalizeClientFlow(value: unknown): ClientFlowStep[] {\n if (!Array.isArray(value)) return [];\n return value\n .filter((step): step is ClientFlowStep => Boolean(step && typeof step === 'object'))\n .map(normalizeClientFlowStep);\n}\n\nexport function normalizeDocumentTypeChoices(value: unknown): DocumentTypeChoice[] {\n if (Array.isArray(value)) {\n return value.flatMap((item) => {\n if (item && typeof item === 'object') {\n const record = item as Record<string, unknown>;\n const optionValue = String(record.value ?? '').trim();\n if (!optionValue) return [];\n return [{\n value: optionValue,\n label: String(record.label ?? optionValue).trim() || optionValue,\n }];\n }\n\n if (typeof item === 'string') {\n const optionValue = item.trim();\n return optionValue ? [{ value: optionValue, label: optionValue }] : [];\n }\n\n return [];\n });\n }\n\n return normalizeStringList(value).map((optionValue) => ({\n value: optionValue,\n label: optionValue,\n }));\n}\n\nexport function uniqueDocumentChoices(choices: DocumentTypeChoice[]): DocumentTypeChoice[] {\n const seen = new Set<string>();\n return choices.filter((choice) => {\n const value = choice.value.trim();\n if (!value || seen.has(value)) return false;\n seen.add(value);\n return true;\n });\n}\n\nexport function getKycPrefill(requirements: KycRequirements | null): KycFormPrefill {\n if (!requirements) return {};\n const kycForm = requirements.kyc_form;\n if (kycForm?.prefill && typeof kycForm.prefill === 'object') return kycForm.prefill;\n if (requirements.form_prefill && typeof requirements.form_prefill === 'object') return requirements.form_prefill;\n return {};\n}\n\nfunction uniqueStrings(values: string[]): string[] {\n return Array.from(new Set(values.map((value) => value.trim()).filter(Boolean)));\n}\n\nfunction normalizeFieldName(value: string): string {\n return value.trim().toLowerCase();\n}\n\nfunction recordValue(value: unknown): Record<string, unknown> {\n return value && typeof value === 'object' ? value as Record<string, unknown> : {};\n}\n\nconst PREFILL_FIELD_ALIASES: Record<string, string[]> = {\n birth_date: ['birth_date', 'date_of_birth'],\n date_of_birth: ['date_of_birth', 'birth_date'],\n document_number: ['document_number', 'tax_id'],\n tax_id: ['tax_id', 'document_number'],\n};\n\nconst STRONG_READ_ONLY_LIST_KEYS = [\n 'locked_fields',\n 'strong_read_only_fields',\n 'force_read_only_fields',\n 'forced_read_only_fields',\n 'hard_read_only_fields',\n];\n\nconst STRONG_READ_ONLY_MAP_KEYS = [\n 'field_locks',\n 'read_only_locks',\n];\n\nfunction prefillAliasesForField(field: string): string[] {\n const normalized = normalizeFieldName(field);\n return PREFILL_FIELD_ALIASES[normalized] ?? [normalized];\n}\n\nexport function hasRealKycPrefillValue(value: unknown): boolean {\n if (value === null || value === undefined) return false;\n\n if (typeof value === 'string') {\n const trimmed = value.trim();\n if (!trimmed || trimmed.includes('*')) return false;\n return /[A-Za-z0-9]/.test(trimmed);\n }\n\n if (typeof value === 'number') return Number.isFinite(value);\n if (typeof value === 'boolean') return true;\n if (Array.isArray(value)) return value.length > 0;\n if (typeof value === 'object') return Object.keys(value).length > 0;\n\n return false;\n}\n\nfunction hasRealKycPrefillForField(requirements: KycRequirements | null, field: string): boolean {\n const prefill = getKycPrefill(requirements);\n return prefillAliasesForField(field).some((alias) => hasRealKycPrefillValue(prefill[alias]));\n}\n\nexport function getKycReadOnlyFields(requirements: KycRequirements | null): string[] {\n if (!requirements) return [];\n const kycFormFields = normalizeStringList(requirements.kyc_form?.read_only_fields);\n return uniqueStrings([\n ...kycFormFields,\n ...normalizeStringList(requirements.read_only_fields),\n ]);\n}\n\nfunction getKycStrongReadOnlyFields(requirements: KycRequirements | null): string[] {\n if (!requirements) return [];\n\n const kycForm = recordValue(requirements.kyc_form);\n const topLevel = recordValue(requirements);\n const listFields = STRONG_READ_ONLY_LIST_KEYS.flatMap((key) => [\n ...normalizeStringList(kycForm[key]),\n ...normalizeStringList(topLevel[key]),\n ]);\n const mapFields = STRONG_READ_ONLY_MAP_KEYS.flatMap((key) => [\n ...strongReadOnlyFieldsFromMap(kycForm[key]),\n ...strongReadOnlyFieldsFromMap(topLevel[key]),\n ]);\n\n return uniqueStrings([...listFields, ...mapFields]);\n}\n\nfunction strongReadOnlyFieldsFromMap(value: unknown): string[] {\n const locks = recordValue(value);\n\n return Object.entries(locks).flatMap(([field, lock]) => {\n if (lock === true) return [field];\n if (typeof lock !== 'string') return [];\n\n const normalized = lock.trim().toLowerCase();\n return ['strong', 'hard', 'locked', 'force', 'forced', 'read_only'].includes(normalized)\n ? [field]\n : [];\n });\n}\n\nexport function isKycFieldReadOnly(requirements: KycRequirements | null, field: string): boolean {\n const normalizedField = normalizeFieldName(field);\n const strongReadOnlyFields = getKycStrongReadOnlyFields(requirements).map(normalizeFieldName);\n if (strongReadOnlyFields.includes(normalizedField)) return true;\n\n const readOnlyFields = getKycReadOnlyFields(requirements).map(normalizeFieldName);\n return readOnlyFields.includes(normalizedField)\n && hasRealKycPrefillForField(requirements, normalizedField);\n}\n\nexport function shouldLockKycFiscalDocumentField(options: {\n configuredReadOnly: boolean;\n normalized: string;\n isValid: boolean;\n}): boolean {\n return options.configuredReadOnly\n && options.normalized.length > 0\n && options.isValid;\n}\n\nfunction getConfigClientFlow(config: unknown): ClientFlowStep[] {\n const record = config && typeof config === 'object' ? config as Record<string, unknown> : {};\n return [\n ...normalizeClientFlow(record.client_flow),\n ...normalizeClientFlow((record.compliance_config as Record<string, unknown> | undefined)?.client_flow),\n ...normalizeClientFlow(\n ((record.flow_config as Record<string, unknown> | undefined)?.compliance_config as Record<string, unknown> | undefined)?.client_flow\n ),\n ];\n}\n\nexport function getRegistrationDocumentConfig(config: unknown): RegistrationDocumentConfig | null {\n const record = config && typeof config === 'object' ? config as Record<string, unknown> : {};\n const direct = record.registration_document;\n if (direct && typeof direct === 'object') {\n return direct as RegistrationDocumentConfig;\n }\n\n const flowConfig = record.flow_config && typeof record.flow_config === 'object'\n ? record.flow_config as Record<string, unknown>\n : {};\n const nested = flowConfig.registration_document;\n if (nested && typeof nested === 'object') {\n return nested as RegistrationDocumentConfig;\n }\n\n return null;\n}\n\nexport function getRegistrationTaxIdField(config: unknown): string {\n const field = String(getRegistrationDocumentConfig(config)?.field ?? 'tax_id').trim();\n return field || 'tax_id';\n}\n\nexport function shouldCollectRegistrationTaxId(config: unknown): boolean {\n const registrationDocument = getRegistrationDocumentConfig(config);\n if (registrationDocument?.collect_tax_id === true) return true;\n\n return getConfigClientFlow(config).some((step) =>\n step.screen === 'account' && step.collect_tax_id === true\n );\n}\n\nexport function isRegistrationTaxIdRequired(config: unknown): boolean {\n const registrationDocument = getRegistrationDocumentConfig(config);\n const taxIdField = getRegistrationTaxIdField(config);\n\n if (registrationDocument?.collect_tax_id === true && registrationDocument.required === true) {\n return true;\n }\n\n return getConfigClientFlow(config).some((step) => {\n if (step.screen !== 'account') return false;\n const requiredFields = normalizeStringList(step.required_fields);\n return requiredFields.includes(taxIdField) || requiredFields.includes('tax_id');\n });\n}\n"]}
@@ -0,0 +1,37 @@
1
+ import type { ClientFlowStep, KycCustomerType, KycFlowEntityType, KycFlowSnapshot, KycOverviewData, KycRequirements, KycVerificationData } from './types.js';
2
+ export declare const VIRTUAL_REVIEW_STEP: ClientFlowStep;
3
+ export declare function normalizeCustomerType(value: unknown): KycCustomerType;
4
+ export declare function flowEntityTypeForCustomerType(customerType: KycCustomerType): KycFlowEntityType;
5
+ export declare function getRequirementsClientFlow(requirements: KycRequirements | null | undefined): ClientFlowStep[];
6
+ export declare function hasKycClientFlow(requirements: KycRequirements | null | undefined): boolean;
7
+ export declare function hasResolvedKycRequirements(requirements: KycRequirements | null | undefined): requirements is KycRequirements;
8
+ export declare function getComplianceSteps(requirements: KycRequirements | null | undefined, customerType: KycCustomerType): ClientFlowStep[];
9
+ export declare function ensureReviewStep(steps: ClientFlowStep[], customerType: KycCustomerType): ClientFlowStep[];
10
+ export declare function isUniversalStepCompleted(step: ClientFlowStep, status: KycVerificationData | null | undefined): boolean;
11
+ export declare function resolveActiveKycStep(params: {
12
+ requirements: KycRequirements | null | undefined;
13
+ status: KycVerificationData | null | undefined;
14
+ customerType: KycCustomerType;
15
+ }): ClientFlowStep | null;
16
+ export declare function canOpenUniversalStep(params: {
17
+ step: ClientFlowStep;
18
+ steps: ClientFlowStep[];
19
+ activeStep: ClientFlowStep | null;
20
+ status: KycVerificationData | null | undefined;
21
+ }): boolean;
22
+ export declare function findStepByMissing(steps: ClientFlowStep[], missingStep?: string, missingScreen?: string): ClientFlowStep | null;
23
+ export declare function getKycProgress(params: {
24
+ steps: ClientFlowStep[];
25
+ status: KycVerificationData | null | undefined;
26
+ }): number;
27
+ export declare function requirementsFromOverview(overview: KycOverviewData | null | undefined): KycRequirements | null;
28
+ export declare function preserveSsrKycRequirementsAnchor(anchor: KycRequirements, overviewRequirements: KycRequirements | null): KycRequirements;
29
+ export declare function mergeKycRequirementsWithAnchor(nextRequirements: KycRequirements, anchor: KycRequirements | null): KycRequirements;
30
+ export declare function statusFromOverview(overview: KycOverviewData | null | undefined): KycVerificationData | null;
31
+ export declare function resolveKycFlowSnapshot(input: {
32
+ overview?: KycOverviewData | null;
33
+ anchorRequirements?: KycRequirements | null;
34
+ }): KycFlowSnapshot;
35
+ export declare function isKycFlowSnapshotConfigured(snapshot: KycFlowSnapshot | null | undefined): boolean;
36
+ export declare function isKycOverviewFlowConfigured(overview: KycOverviewData | null | undefined): boolean;
37
+ //# sourceMappingURL=flow.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"flow.d.ts","sourceRoot":"","sources":["../../src/kyc/flow.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,329 @@
1
+ export const VIRTUAL_REVIEW_STEP = {
2
+ key: 'review',
3
+ title: 'Review',
4
+ phase: 'compliance',
5
+ screen: 'review',
6
+ description: 'Review and submit verification.',
7
+ endpoint: '/api/v1/kyc/submit',
8
+ required_fields: [],
9
+ required_documents: [],
10
+ entity_types: ['PF', 'PJ'],
11
+ blocking: true,
12
+ };
13
+ function asRecord(value) {
14
+ return value && typeof value === 'object' ? value : {};
15
+ }
16
+ function normalizeClientFlow(value) {
17
+ if (!Array.isArray(value))
18
+ return [];
19
+ return value
20
+ .filter((step) => Boolean(step && typeof step === 'object'))
21
+ .flatMap((step) => {
22
+ const key = typeof step.key === 'string' ? step.key.trim() : '';
23
+ const screen = typeof step.screen === 'string' ? step.screen.trim() : '';
24
+ const phase = step.phase === 'registration' || step.phase === 'compliance'
25
+ ? step.phase
26
+ : 'compliance';
27
+ if (!key || !screen)
28
+ return [];
29
+ return [{
30
+ ...step,
31
+ key,
32
+ title: typeof step.title === 'string' && step.title.trim() ? step.title : key,
33
+ phase,
34
+ screen: screen,
35
+ endpoint: typeof step.endpoint === 'string' ? step.endpoint : undefined,
36
+ required_fields: Array.isArray(step.required_fields) ? step.required_fields.map(String) : [],
37
+ required_documents: Array.isArray(step.required_documents) ? step.required_documents.map(String) : [],
38
+ entity_types: normalizeEntityTypes(step.entity_types),
39
+ blocking: step.blocking !== false,
40
+ }];
41
+ });
42
+ }
43
+ function normalizeEntityTypes(value) {
44
+ if (!Array.isArray(value) || value.length === 0)
45
+ return ['PF', 'PJ'];
46
+ const entityTypes = value
47
+ .map((item) => String(item).trim().toUpperCase())
48
+ .filter((item) => item === 'PF' || item === 'PJ');
49
+ return entityTypes.length > 0 ? entityTypes : ['PF', 'PJ'];
50
+ }
51
+ function normalizeJurisdictionCode(value) {
52
+ const normalized = String(value ?? '').trim().toUpperCase();
53
+ return /^[A-Z]{2}$/.test(normalized) ? normalized : undefined;
54
+ }
55
+ function normalizeDocumentTypes(requirements) {
56
+ const value = requirements?.document_types;
57
+ const list = Array.isArray(value)
58
+ ? value
59
+ : typeof value === 'string'
60
+ ? value.split(',')
61
+ : [];
62
+ return Array.from(new Set(list
63
+ .map((type) => String(type).trim().toLowerCase())
64
+ .filter(Boolean))).sort();
65
+ }
66
+ function sameDocumentTypes(nextRequirements, anchor) {
67
+ const nextTypes = normalizeDocumentTypes(nextRequirements);
68
+ const anchorTypes = normalizeDocumentTypes(anchor);
69
+ if (nextTypes.length === 0 || anchorTypes.length === 0)
70
+ return true;
71
+ if (nextTypes.length !== anchorTypes.length)
72
+ return false;
73
+ return nextTypes.every((type, index) => type === anchorTypes[index]);
74
+ }
75
+ function anchorMatchesRequirements(nextRequirements, anchor) {
76
+ const nextJurisdiction = normalizeJurisdictionCode(nextRequirements.jurisdiction_code ?? nextRequirements.code);
77
+ const anchorJurisdiction = normalizeJurisdictionCode(anchor.jurisdiction_code ?? anchor.code);
78
+ if (nextJurisdiction && anchorJurisdiction && nextJurisdiction !== anchorJurisdiction)
79
+ return false;
80
+ if (nextRequirements.customer_type
81
+ && anchor.customer_type
82
+ && nextRequirements.customer_type !== anchor.customer_type) {
83
+ return false;
84
+ }
85
+ return sameDocumentTypes(nextRequirements, anchor);
86
+ }
87
+ export function normalizeCustomerType(value) {
88
+ const normalized = String(value ?? '').trim().toLowerCase();
89
+ return ['company', 'pj', 'business', 'legal_entity'].includes(normalized)
90
+ ? 'company'
91
+ : 'individual';
92
+ }
93
+ export function flowEntityTypeForCustomerType(customerType) {
94
+ return customerType === 'company' ? 'PJ' : 'PF';
95
+ }
96
+ export function getRequirementsClientFlow(requirements) {
97
+ if (!requirements)
98
+ return [];
99
+ const direct = normalizeClientFlow(requirements.client_flow);
100
+ if (direct.length > 0)
101
+ return direct;
102
+ const nested = normalizeClientFlow(requirements.compliance_config?.client_flow);
103
+ if (nested.length > 0)
104
+ return nested;
105
+ return normalizeClientFlow(requirements.flow_config?.compliance_config?.client_flow);
106
+ }
107
+ export function hasKycClientFlow(requirements) {
108
+ return getRequirementsClientFlow(requirements).length > 0;
109
+ }
110
+ export function hasResolvedKycRequirements(requirements) {
111
+ return Boolean(requirements && hasKycClientFlow(requirements));
112
+ }
113
+ export function getComplianceSteps(requirements, customerType) {
114
+ const entityType = flowEntityTypeForCustomerType(customerType);
115
+ return getRequirementsClientFlow(requirements)
116
+ .filter((step) => step.phase === 'compliance')
117
+ .filter((step) => (step.entity_types?.length ? step.entity_types : ['PF', 'PJ']).includes(entityType));
118
+ }
119
+ export function ensureReviewStep(steps, customerType) {
120
+ if (steps.length === 0 || steps.some((step) => step.screen === 'review'))
121
+ return steps;
122
+ return [
123
+ ...steps,
124
+ {
125
+ ...VIRTUAL_REVIEW_STEP,
126
+ entity_types: [flowEntityTypeForCustomerType(customerType)],
127
+ },
128
+ ];
129
+ }
130
+ export function isUniversalStepCompleted(step, status) {
131
+ if (!status)
132
+ return false;
133
+ return status.completed_flow_steps?.includes(step.key) ?? false;
134
+ }
135
+ function flowStateStepKey(status) {
136
+ return status?.flow_state?.required_action?.step_key
137
+ ?? status?.flow_state?.target_flow_step
138
+ ?? status?.flow_state?.current_step?.key
139
+ ?? status?.flow_state?.target_step
140
+ ?? null;
141
+ }
142
+ export function resolveActiveKycStep(params) {
143
+ if (getRequirementsClientFlow(params.requirements).length === 0)
144
+ return null;
145
+ const steps = ensureReviewStep(getComplianceSteps(params.requirements, params.customerType), params.customerType);
146
+ if (steps.length === 0)
147
+ return null;
148
+ if (params.status?.status === 'pending_review' || params.status?.status === 'under_review')
149
+ return null;
150
+ if (params.status?.status === 'approved')
151
+ return null;
152
+ const flowStateKey = flowStateStepKey(params.status);
153
+ if (flowStateKey) {
154
+ const configuredStep = steps.find((step) => step.key === flowStateKey);
155
+ if (configuredStep)
156
+ return configuredStep;
157
+ }
158
+ if (params.status?.status === 'rejected' || params.status?.status === 'requires_resubmission') {
159
+ return steps.find((step) => step.screen !== 'review' && !isUniversalStepCompleted(step, params.status))
160
+ ?? steps.find((step) => step.screen === 'review')
161
+ ?? steps[0];
162
+ }
163
+ for (const step of steps) {
164
+ if (step.screen === 'review')
165
+ continue;
166
+ if (isUniversalStepCompleted(step, params.status))
167
+ continue;
168
+ if (step.blocking !== false)
169
+ return step;
170
+ }
171
+ return steps.find((step) => step.screen === 'review') ?? steps[steps.length - 1];
172
+ }
173
+ export function canOpenUniversalStep(params) {
174
+ const index = params.steps.findIndex((step) => step.key === params.step.key);
175
+ if (index < 0)
176
+ return false;
177
+ if (params.activeStep?.key === params.step.key)
178
+ return true;
179
+ if (isUniversalStepCompleted(params.step, params.status))
180
+ return true;
181
+ const firstIncompleteIndex = params.steps.findIndex((step) => step.screen !== 'review' && !isUniversalStepCompleted(step, params.status));
182
+ if (params.step.screen === 'review')
183
+ return firstIncompleteIndex === -1;
184
+ if (firstIncompleteIndex === -1)
185
+ return true;
186
+ return index <= firstIncompleteIndex;
187
+ }
188
+ export function findStepByMissing(steps, missingStep, missingScreen) {
189
+ if (!missingStep && !missingScreen)
190
+ return null;
191
+ return steps.find((step) => (missingStep && step.key === missingStep)
192
+ || (missingScreen && step.screen === missingScreen)) ?? null;
193
+ }
194
+ export function getKycProgress(params) {
195
+ if (params.steps.length === 0)
196
+ return 0;
197
+ const completed = params.steps.filter((step) => step.screen === 'review'
198
+ ? params.status?.status === 'pending_review'
199
+ || params.status?.status === 'under_review'
200
+ || params.status?.status === 'approved'
201
+ : isUniversalStepCompleted(step, params.status)).length;
202
+ return Math.min(100, Math.round((completed / params.steps.length) * 100));
203
+ }
204
+ export function requirementsFromOverview(overview) {
205
+ if (!overview)
206
+ return null;
207
+ const overviewRequirements = asRecord(overview.requirements);
208
+ const overviewFlowConfig = asRecord(overview.flow_config);
209
+ const requirementFlowConfig = asRecord(overviewRequirements.flow_config);
210
+ const flowConfig = {
211
+ ...overviewFlowConfig,
212
+ ...requirementFlowConfig,
213
+ };
214
+ const requirementsSource = Object.keys(overviewRequirements).length > 0
215
+ ? overviewRequirements
216
+ : flowConfig;
217
+ if (Object.keys(requirementsSource).length === 0)
218
+ return null;
219
+ const flowComplianceConfig = asRecord(asRecord(flowConfig).compliance_config);
220
+ const requirementsComplianceConfig = asRecord(requirementsSource.compliance_config);
221
+ const directClientFlow = normalizeClientFlow(overview.client_flow);
222
+ const clientFlow = directClientFlow.length > 0
223
+ ? directClientFlow
224
+ : [
225
+ ...normalizeClientFlow(requirementsSource.client_flow),
226
+ ...normalizeClientFlow(requirementsComplianceConfig.client_flow),
227
+ ...normalizeClientFlow(flowComplianceConfig.client_flow),
228
+ ];
229
+ const flowState = overview.flow_state ?? overview.status?.flow_state ?? null;
230
+ const jurisdiction = asRecord(requirementsSource.jurisdiction ?? flowConfig.jurisdiction);
231
+ const resolvedLocale = String(requirementsSource.locale
232
+ ?? asRecord(overview).locale
233
+ ?? flowConfig.locale
234
+ ?? jurisdiction.locale
235
+ ?? '').trim() || undefined;
236
+ return {
237
+ ...flowConfig,
238
+ ...requirementsSource,
239
+ jurisdiction_code: normalizeJurisdictionCode(requirementsSource.jurisdiction_code
240
+ ?? requirementsSource.code
241
+ ?? flowState?.jurisdiction_code),
242
+ customer_type: requirementsSource.customer_type
243
+ ?? normalizeCustomerType(flowState?.entity_type),
244
+ locale: resolvedLocale,
245
+ flow_config: {
246
+ ...flowConfig,
247
+ compliance_config: {
248
+ ...flowComplianceConfig,
249
+ client_flow: clientFlow,
250
+ },
251
+ },
252
+ compliance_config: {
253
+ ...flowComplianceConfig,
254
+ ...requirementsComplianceConfig,
255
+ client_flow: clientFlow,
256
+ },
257
+ client_flow: clientFlow,
258
+ };
259
+ }
260
+ export function preserveSsrKycRequirementsAnchor(anchor, overviewRequirements) {
261
+ const anchorClientFlow = getRequirementsClientFlow(anchor);
262
+ return {
263
+ ...anchor,
264
+ kyc_form: overviewRequirements?.kyc_form ?? anchor.kyc_form,
265
+ form_prefill: overviewRequirements?.form_prefill ?? anchor.form_prefill,
266
+ read_only_fields: overviewRequirements?.read_only_fields ?? anchor.read_only_fields,
267
+ client_flow: anchorClientFlow,
268
+ flow_config: {
269
+ ...(anchor.flow_config ?? {}),
270
+ compliance_config: {
271
+ ...(anchor.flow_config?.compliance_config ?? {}),
272
+ client_flow: anchorClientFlow,
273
+ },
274
+ },
275
+ compliance_config: {
276
+ ...(anchor.compliance_config ?? {}),
277
+ client_flow: anchorClientFlow,
278
+ },
279
+ };
280
+ }
281
+ export function mergeKycRequirementsWithAnchor(nextRequirements, anchor) {
282
+ if (!anchor)
283
+ return nextRequirements;
284
+ const anchorClientFlow = getRequirementsClientFlow(anchor);
285
+ const nextClientFlow = getRequirementsClientFlow(nextRequirements);
286
+ const canUseAnchor = anchorClientFlow.length > 0
287
+ && nextClientFlow.length === 0
288
+ && anchorMatchesRequirements(nextRequirements, anchor);
289
+ if (!canUseAnchor)
290
+ return nextRequirements;
291
+ return preserveSsrKycRequirementsAnchor(anchor, nextRequirements);
292
+ }
293
+ export function statusFromOverview(overview) {
294
+ return overview?.status ?? null;
295
+ }
296
+ export function resolveKycFlowSnapshot(input) {
297
+ const overviewRequirements = requirementsFromOverview(input.overview);
298
+ const requirements = overviewRequirements
299
+ ? mergeKycRequirementsWithAnchor(overviewRequirements, input.anchorRequirements ?? null)
300
+ : input.anchorRequirements ?? null;
301
+ const status = statusFromOverview(input.overview);
302
+ const customerType = normalizeCustomerType(requirements?.customer_type
303
+ ?? status?.flow_state?.entity_type);
304
+ const jurisdictionCode = normalizeJurisdictionCode(requirements?.jurisdiction_code
305
+ ?? requirements?.code
306
+ ?? status?.flow_state?.jurisdiction_code);
307
+ const hasConfiguredClientFlow = getRequirementsClientFlow(requirements).length > 0;
308
+ const steps = hasConfiguredClientFlow
309
+ ? ensureReviewStep(getComplianceSteps(requirements, customerType), customerType)
310
+ : [];
311
+ const activeStep = resolveActiveKycStep({ requirements, status, customerType });
312
+ return {
313
+ activeStep,
314
+ steps,
315
+ requirements,
316
+ status,
317
+ customerType,
318
+ jurisdictionCode,
319
+ progress: getKycProgress({ steps, status }),
320
+ configMissing: Boolean(requirements && !hasConfiguredClientFlow),
321
+ };
322
+ }
323
+ export function isKycFlowSnapshotConfigured(snapshot) {
324
+ return Boolean(snapshot && !snapshot.configMissing && snapshot.steps.length > 0);
325
+ }
326
+ export function isKycOverviewFlowConfigured(overview) {
327
+ return isKycFlowSnapshotConfigured(resolveKycFlowSnapshot({ overview }));
328
+ }
329
+ //# sourceMappingURL=flow.js.map