@transfergratis/react-native-sdk 0.1.23 → 0.1.24

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 (137) hide show
  1. package/android/src/main/AndroidManifest.xml +9 -4
  2. package/build/components/EnhancedCameraView.d.ts.map +1 -1
  3. package/build/components/EnhancedCameraView.js +26 -3
  4. package/build/components/EnhancedCameraView.js.map +1 -1
  5. package/build/components/EnhancedCameraView.web.d.ts.map +1 -1
  6. package/build/components/EnhancedCameraView.web.js +21 -0
  7. package/build/components/EnhancedCameraView.web.js.map +1 -1
  8. package/build/components/KYCElements/CameraCapture.d.ts.map +1 -1
  9. package/build/components/KYCElements/CameraCapture.js +4 -3
  10. package/build/components/KYCElements/CameraCapture.js.map +1 -1
  11. package/build/components/KYCElements/CountrySelectionTemplate.d.ts +5 -2
  12. package/build/components/KYCElements/CountrySelectionTemplate.d.ts.map +1 -1
  13. package/build/components/KYCElements/CountrySelectionTemplate.js +360 -101
  14. package/build/components/KYCElements/CountrySelectionTemplate.js.map +1 -1
  15. package/build/components/KYCElements/FileUpload.d.ts.map +1 -1
  16. package/build/components/KYCElements/FileUpload.js +5 -4
  17. package/build/components/KYCElements/FileUpload.js.map +1 -1
  18. package/build/components/KYCElements/FileUploadTemplate.d.ts.map +1 -1
  19. package/build/components/KYCElements/FileUploadTemplate.js +5 -4
  20. package/build/components/KYCElements/FileUploadTemplate.js.map +1 -1
  21. package/build/components/KYCElements/IDCardCapture.d.ts.map +1 -1
  22. package/build/components/KYCElements/IDCardCapture.js +193 -237
  23. package/build/components/KYCElements/IDCardCapture.js.map +1 -1
  24. package/build/components/KYCElements/LocationCaptureTemplate.d.ts.map +1 -1
  25. package/build/components/KYCElements/LocationCaptureTemplate.js +78 -37
  26. package/build/components/KYCElements/LocationCaptureTemplate.js.map +1 -1
  27. package/build/components/KYCElements/OrientationVideoCapture.js +3 -2
  28. package/build/components/KYCElements/OrientationVideoCapture.js.map +1 -1
  29. package/build/components/KYCElements/OrientationVideoCaptureEnhanced.js +3 -2
  30. package/build/components/KYCElements/OrientationVideoCaptureEnhanced.js.map +1 -1
  31. package/build/components/KYCElements/OrientationVideoCaptureFinal.js +3 -2
  32. package/build/components/KYCElements/OrientationVideoCaptureFinal.js.map +1 -1
  33. package/build/components/KYCElements/SelfieCapture.d.ts.map +1 -1
  34. package/build/components/KYCElements/SelfieCapture.js +4 -3
  35. package/build/components/KYCElements/SelfieCapture.js.map +1 -1
  36. package/build/components/KYCElements/SelfieCaptureTemplate.d.ts.map +1 -1
  37. package/build/components/KYCElements/SelfieCaptureTemplate.js +182 -39
  38. package/build/components/KYCElements/SelfieCaptureTemplate.js.map +1 -1
  39. package/build/components/KYCElements/WelcomeTemplate.d.ts +12 -0
  40. package/build/components/KYCElements/WelcomeTemplate.d.ts.map +1 -0
  41. package/build/components/KYCElements/WelcomeTemplate.js +243 -0
  42. package/build/components/KYCElements/WelcomeTemplate.js.map +1 -0
  43. package/build/components/TemplateKYCExample.d.ts +4 -2
  44. package/build/components/TemplateKYCExample.d.ts.map +1 -1
  45. package/build/components/TemplateKYCExample.js +5 -69
  46. package/build/components/TemplateKYCExample.js.map +1 -1
  47. package/build/components/TemplateKYCFlowRefactored.d.ts +2 -1
  48. package/build/components/TemplateKYCFlowRefactored.d.ts.map +1 -1
  49. package/build/components/TemplateKYCFlowRefactored.js +95 -10
  50. package/build/components/TemplateKYCFlowRefactored.js.map +1 -1
  51. package/build/components/example/DynamicTemplateExample.d.ts +10 -0
  52. package/build/components/example/DynamicTemplateExample.d.ts.map +1 -0
  53. package/build/components/example/DynamicTemplateExample.js +241 -0
  54. package/build/components/example/DynamicTemplateExample.js.map +1 -0
  55. package/build/config/allowedDomains.d.ts +30 -0
  56. package/build/config/allowedDomains.d.ts.map +1 -0
  57. package/build/config/allowedDomains.js +127 -0
  58. package/build/config/allowedDomains.js.map +1 -0
  59. package/build/hooks/useTemplateKYCFlow.d.ts.map +1 -1
  60. package/build/hooks/useTemplateKYCFlow.js +31 -11
  61. package/build/hooks/useTemplateKYCFlow.js.map +1 -1
  62. package/build/hooks/useTemplateLoader.d.ts +14 -0
  63. package/build/hooks/useTemplateLoader.d.ts.map +1 -0
  64. package/build/hooks/useTemplateLoader.js +85 -0
  65. package/build/hooks/useTemplateLoader.js.map +1 -0
  66. package/build/i18n/en/index.d.ts +9 -0
  67. package/build/i18n/en/index.d.ts.map +1 -1
  68. package/build/i18n/en/index.js +9 -0
  69. package/build/i18n/en/index.js.map +1 -1
  70. package/build/i18n/fr/index.d.ts +9 -0
  71. package/build/i18n/fr/index.d.ts.map +1 -1
  72. package/build/i18n/fr/index.js +9 -0
  73. package/build/i18n/fr/index.js.map +1 -1
  74. package/build/index.d.ts +5 -0
  75. package/build/index.d.ts.map +1 -1
  76. package/build/index.js +8 -0
  77. package/build/index.js.map +1 -1
  78. package/build/modules/api/CardAuthentification.js +1 -0
  79. package/build/modules/api/CardAuthentification.js.map +1 -1
  80. package/build/modules/api/KYCService.d.ts.map +1 -1
  81. package/build/modules/api/KYCService.js +7 -2
  82. package/build/modules/api/KYCService.js.map +1 -1
  83. package/build/modules/api/TemplateService.d.ts +45 -0
  84. package/build/modules/api/TemplateService.d.ts.map +1 -0
  85. package/build/modules/api/TemplateService.js +145 -0
  86. package/build/modules/api/TemplateService.js.map +1 -0
  87. package/build/types/KYC.types.d.ts +144 -4
  88. package/build/types/KYC.types.d.ts.map +1 -1
  89. package/build/types/KYC.types.js +15 -0
  90. package/build/types/KYC.types.js.map +1 -1
  91. package/build/utils/cropByObb.d.ts +1 -0
  92. package/build/utils/cropByObb.d.ts.map +1 -1
  93. package/build/utils/cropByObb.js +70 -0
  94. package/build/utils/cropByObb.js.map +1 -1
  95. package/build/utils/platformAlert.d.ts +20 -0
  96. package/build/utils/platformAlert.d.ts.map +1 -0
  97. package/build/utils/platformAlert.js +67 -0
  98. package/build/utils/platformAlert.js.map +1 -0
  99. package/build/utils/template-transformer.d.ts +10 -0
  100. package/build/utils/template-transformer.d.ts.map +1 -0
  101. package/build/utils/template-transformer.js +353 -0
  102. package/build/utils/template-transformer.js.map +1 -0
  103. package/build/web/WebKYCEntry.d.ts.map +1 -1
  104. package/build/web/WebKYCEntry.js +102 -20
  105. package/build/web/WebKYCEntry.js.map +1 -1
  106. package/package.json +1 -1
  107. package/src/components/EnhancedCameraView.tsx +31 -2
  108. package/src/components/EnhancedCameraView.web.tsx +24 -0
  109. package/src/components/KYCElements/CameraCapture.tsx +4 -3
  110. package/src/components/KYCElements/CountrySelectionTemplate.tsx +410 -113
  111. package/src/components/KYCElements/FileUpload.tsx +5 -4
  112. package/src/components/KYCElements/FileUploadTemplate.tsx +5 -4
  113. package/src/components/KYCElements/IDCardCapture.tsx +196 -254
  114. package/src/components/KYCElements/LocationCaptureTemplate.tsx +95 -44
  115. package/src/components/KYCElements/OrientationVideoCapture.tsx +2 -2
  116. package/src/components/KYCElements/OrientationVideoCaptureEnhanced.tsx +2 -2
  117. package/src/components/KYCElements/OrientationVideoCaptureFinal.tsx +2 -2
  118. package/src/components/KYCElements/SelfieCapture.tsx +4 -3
  119. package/src/components/KYCElements/SelfieCaptureTemplate.tsx +195 -41
  120. package/src/components/KYCElements/WelcomeTemplate.tsx +289 -0
  121. package/src/components/TemplateKYCExample.tsx +16 -72
  122. package/src/components/TemplateKYCFlowRefactored.tsx +122 -12
  123. package/src/components/example/DynamicTemplateExample.tsx +289 -0
  124. package/src/config/allowedDomains.ts +152 -0
  125. package/src/hooks/useTemplateKYCFlow.tsx +33 -11
  126. package/src/hooks/useTemplateLoader.ts +102 -0
  127. package/src/i18n/en/index.ts +10 -0
  128. package/src/i18n/fr/index.ts +9 -0
  129. package/src/index.ts +11 -0
  130. package/src/modules/api/CardAuthentification.ts +1 -1
  131. package/src/modules/api/KYCService.ts +12 -8
  132. package/src/modules/api/TemplateService.ts +167 -0
  133. package/src/types/KYC.types.ts +188 -3
  134. package/src/utils/cropByObb.ts +83 -3
  135. package/src/utils/platformAlert.ts +85 -0
  136. package/src/utils/template-transformer.ts +433 -0
  137. package/src/web/WebKYCEntry.tsx +122 -24
@@ -1 +1 @@
1
- {"version":3,"file":"cropByObb.js","sourceRoot":"","sources":["../../src/utils/cropByObb.ts"],"names":[],"mappings":"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","sourcesContent":["import { Image as RNImage, Platform } from 'react-native';\nimport * as ImageManipulator from \"expo-image-manipulator\";\n\ntype Point = [number, number];\n\n// Compute axis-aligned bounding box from oriented quadrilateral\nfunction computeAabb(points: Point[]) {\n const xs = points.map(p => p[0]);\n const ys = points.map(p => p[1]);\n const minX = Math.min(...xs);\n const minY = Math.min(...ys);\n const maxX = Math.max(...xs);\n const maxY = Math.max(...ys);\n return { minX, minY, maxX, maxY, width: maxX - minX, height: maxY - minY };\n}\n\n// Web-only crop using Canvas; returns dataURL (base64)\nasync function cropWeb(uri: string, points: Point[]): Promise<string> {\n return new Promise((resolve, reject) => {\n const img = new Image();\n img.crossOrigin = 'anonymous';\n img.onload = () => {\n const { minX, minY, width, height } = computeAabb(points);\n const canvas = document.createElement('canvas');\n canvas.width = Math.max(1, Math.round(width));\n canvas.height = Math.max(1, Math.round(height));\n const ctx = canvas.getContext('2d');\n if (!ctx) return reject(new Error('Canvas context not available'));\n ctx.drawImage(\n img,\n minX, // sx\n minY, // sy\n width, // sw\n height, // sh\n 0,\n 0,\n canvas.width,\n canvas.height\n );\n resolve(canvas.toDataURL('image/jpeg', 0.92));\n };\n img.onerror = (e) => reject(e);\n img.src = uri;\n });\n}\n\n// Fallback: return original for native (no dependency added); caller can still use bbox to draw overlay\nexport async function cropByObb(uri: string, cardObb: any): Promise<{ base64?: string; bbox?: { minX: number; minY: number; width: number; height: number } }> {\n try {\n // card_obb format: [ [ [p1,p2,p3,p4], score ] ]\n const first = Array.isArray(cardObb) ? cardObb[0] : null;\n const points = Array.isArray(first?.[0]) ? (first[0] as Point[]) : null;\n if (!points || points.length !== 4) return {};\n\n const { minX, minY, width, height } = computeAabb(points);\n\n if (Platform.OS === 'web') {\n const base64 = await cropWeb(uri, points);\n return { base64, bbox: { minX, minY, width, height } };\n }\n // Native: return bbox only; keep base64 undefined\n return { bbox: { minX, minY, width, height } };\n } catch (e) {\n return {};\n }\n}\n\n\n\n\n// exemple d'appel :\nexport async function cropImageWithBBox(uri: string, bbox: any) {\n // 1️⃣ Récupère la taille originale de l'image\n await RNImage.getSize(uri, (width, height) => {\n console.log(\"Image originale:\", width, height);\n });\n\n // // 2️⃣ Suppose que ton bbox vient d'une image affichée dans `displayedSize`\n // const scaleX = originalWidth / displayedSize.width;\n // const scaleY = originalHeight / displayedSize.height;\n\n // 3️⃣ Convertir le bbox à la taille réelle scale 0.10 = 10%\n const crop = {\n originX: bbox.minX ,\n originY: bbox.minY ,\n width: bbox.width ,\n height: bbox.height,\n };\n\n // 4️⃣ Appliquer le crop\n const result = await ImageManipulator.manipulateAsync(\n uri,\n [{ crop }],\n { compress: 1, format: ImageManipulator.SaveFormat.PNG }\n );\n\n console.log(\"Image recadrée:\", result.uri);\n return result.uri;\n}\n"]}
1
+ {"version":3,"file":"cropByObb.js","sourceRoot":"","sources":["../../src/utils/cropByObb.ts"],"names":[],"mappings":"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","sourcesContent":["import { Image as RNImage, Platform } from 'react-native';\nimport * as ImageManipulator from \"expo-image-manipulator\";\nimport { truncateFields } from '../modules/api/KYCService';\nimport { logger } from './logger';\n\ntype Point = [number, number];\n\n// Compute axis-aligned bounding box from oriented quadrilateral\nfunction computeAabb(points: Point[]) {\n const xs = points.map(p => p[0]);\n const ys = points.map(p => p[1]);\n const minX = Math.min(...xs);\n const minY = Math.min(...ys);\n const maxX = Math.max(...xs);\n const maxY = Math.max(...ys);\n return { minX, minY, maxX, maxY, width: maxX - minX, height: maxY - minY };\n}\n\n// Web-only crop using Canvas; returns dataURL (base64)\nasync function cropWeb(uri: string, points: Point[]): Promise<string> {\n return new Promise((resolve, reject) => {\n const img = new Image();\n img.crossOrigin = 'anonymous';\n img.onload = () => {\n const { minX, minY, width, height } = computeAabb(points);\n const canvas = document.createElement('canvas');\n canvas.width = Math.max(1, Math.round(width));\n canvas.height = Math.max(1, Math.round(height));\n const ctx = canvas.getContext('2d');\n if (!ctx) return reject(new Error('Canvas context not available'));\n ctx.drawImage(\n img,\n minX, // sx\n minY, // sy\n width, // sw\n height, // sh\n 0,\n 0,\n canvas.width,\n canvas.height\n );\n resolve(canvas.toDataURL('image/jpeg', 0.92));\n };\n img.onerror = (e) => reject(e);\n img.src = uri;\n });\n}\n\n// Fallback: return original for native (no dependency added); caller can still use bbox to draw overlay\nexport async function cropByObb(uri: string, cardObb: any): Promise<{ base64?: string; bbox?: { minX: number; minY: number; width: number; height: number } }> {\n try {\n // card_obb format: [ [ [p1,p2,p3,p4], score ] ]\n const first = Array.isArray(cardObb) ? cardObb[0] : null;\n const points = Array.isArray(first?.[0]) ? (first[0] as Point[]) : null;\n if (!points || points.length !== 4) return {};\n\n const { minX, minY, width, height } = computeAabb(points);\n\n if (Platform.OS === 'web') {\n const base64 = await cropWeb(uri, points);\n return { base64, bbox: { minX, minY, width, height } };\n }\n // Native: return bbox only; keep base64 undefined\n return { bbox: { minX, minY, width, height } };\n } catch (e) {\n return {};\n }\n}\n\n\n\n\n// exemple d'appel :\nexport async function cropImageWithBBox(uri: string, bbox: any) {\n // 1️⃣ Récupère la taille originale de l'image\n await RNImage.getSize(uri, (width, height) => {\n console.log(\"Image originale:\", width, height);\n });\n\n // // 2️⃣ Suppose que ton bbox vient d'une image affichée dans `displayedSize`\n // const scaleX = originalWidth / displayedSize.width;\n // const scaleY = originalHeight / displayedSize.height;\n\n // 3️⃣ Convertir le bbox à la taille réelle scale 0.10 = 10%\n const crop = {\n originX: bbox.minX,\n originY: bbox.minY,\n width: bbox.width,\n height: bbox.height,\n };\n\n // 4️⃣ Appliquer le crop\n // @ts-ignore - manipulateAsync is deprecated but still functional, new API (useImageManipulator) is a React hook and not suitable for utility functions\n const result = await ImageManipulator.manipulateAsync(\n uri,\n [{ crop }],\n { compress: 1, format: ImageManipulator.SaveFormat.PNG }\n );\n\n console.log(\"Image recadrée:\", result.uri);\n return result.uri;\n}\n\n// Fonction pour rogner avec une tolérance de 10% autour du bbox\nexport async function cropImageWithBBoxWithTolerance(uri: string, bbox: any, tolerance: number = 0.1): Promise<string> {\n console.log(\"cropImageWithBBoxWithTolerance\", JSON.stringify(truncateFields({ uri, bbox, tolerance }), null, 2));\n \n return new Promise<string>((resolve, reject) => {\n let isResolved = false;\n \n // Timeout de sécurité (15 secondes)\n const timeout = setTimeout(() => {\n if (!isResolved) {\n isResolved = true;\n console.warn(\"Timeout lors du rognage avec tolérance, utilisation de l'image originale\");\n resolve(uri); // Retourner l'URI original en cas de timeout\n }\n }, 15000);\n\n // 1️⃣ Récupère la taille originale de l'image\n RNImage.getSize(uri, (imageWidth, imageHeight) => {\n if (isResolved) return;\n \n // 2️⃣ Calculer la tolérance en pixels (10% de chaque côté)\n const toleranceX = bbox.width * tolerance;\n const toleranceY = bbox.height * tolerance;\n\n // 3️⃣ Ajuster le bbox avec la tolérance\n // Calculer les nouvelles coordonnées avec tolérance\n const newMinX = Math.max(0, bbox.minX - toleranceX);\n const newMinY = Math.max(0, bbox.minY - toleranceY);\n const newMaxX = Math.min(imageWidth, bbox.minX + bbox.width + toleranceX);\n const newMaxY = Math.min(imageHeight, bbox.minY + bbox.height + toleranceY);\n\n // Calculer la largeur et hauteur finales\n const finalWidth = newMaxX - newMinX;\n const finalHeight = newMaxY - newMinY;\n\n const crop = {\n originX: newMinX,\n originY: newMinY,\n width: finalWidth,\n height: finalHeight,\n };\n\n logger.log(\"cropImageWithBBoxWithTolerance - crop params\", JSON.stringify(truncateFields({ uri, crop, tolerance, imageWidth, imageHeight }), null, 2));\n\n // 4️⃣ Appliquer le crop avec tolérance\n // @ts-ignore - manipulateAsync is deprecated but still functional, new API (useImageManipulator) is a React hook and not suitable for utility functions\n ImageManipulator.manipulateAsync(\n uri,\n [{ crop }],\n { compress: 0.95, format: ImageManipulator.SaveFormat.JPEG }\n )\n .then((result) => {\n if (isResolved) return;\n isResolved = true;\n clearTimeout(timeout);\n console.log(\"Image recadrée avec tolérance:\", result.uri);\n resolve(result.uri);\n })\n .catch((error) => {\n if (isResolved) return;\n isResolved = true;\n clearTimeout(timeout);\n console.error(\"Erreur lors du rognage avec tolérance:\", error);\n // En cas d'erreur, retourner l'URI original au lieu de rejeter\n resolve(uri);\n });\n }, (error) => {\n if (isResolved) return;\n isResolved = true;\n clearTimeout(timeout);\n console.error(\"Erreur lors de la récupération de la taille de l'image:\", error);\n // En cas d'erreur, retourner l'URI original au lieu de rejeter\n resolve(uri);\n });\n });\n}\n"]}
@@ -0,0 +1,20 @@
1
+ export interface AlertButton {
2
+ text?: string;
3
+ onPress?: () => void;
4
+ style?: 'default' | 'cancel' | 'destructive';
5
+ }
6
+ /**
7
+ * Platform-aware alert helper that works on both native and web platforms
8
+ * On web, uses window.confirm/window.alert since Alert.alert is not supported
9
+ * On native, uses the standard Alert.alert
10
+ */
11
+ export declare const showAlert: (title: string, message?: string, buttons?: AlertButton[]) => void;
12
+ /**
13
+ * Simplified confirm dialog for yes/no scenarios
14
+ */
15
+ export declare const showConfirm: (title: string, message: string, onConfirm: () => void, onCancel?: () => void) => void;
16
+ /**
17
+ * Simple alert with just an OK button
18
+ */
19
+ export declare const showSimpleAlert: (title: string, message?: string, onPress?: () => void) => void;
20
+ //# sourceMappingURL=platformAlert.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"platformAlert.d.ts","sourceRoot":"","sources":["../../src/utils/platformAlert.ts"],"names":[],"mappings":"AAEA,MAAM,WAAW,WAAW;IAC1B,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,OAAO,CAAC,EAAE,MAAM,IAAI,CAAC;IACrB,KAAK,CAAC,EAAE,SAAS,GAAG,QAAQ,GAAG,aAAa,CAAC;CAC9C;AAED;;;;GAIG;AACH,eAAO,MAAM,SAAS,GACpB,OAAO,MAAM,EACb,UAAU,MAAM,EAChB,UAAU,WAAW,EAAE,KACtB,IAgCF,CAAC;AAEF;;GAEG;AACH,eAAO,MAAM,WAAW,GACtB,OAAO,MAAM,EACb,SAAS,MAAM,EACf,WAAW,MAAM,IAAI,EACrB,WAAW,MAAM,IAAI,KACpB,IAYF,CAAC;AAEF;;GAEG;AACH,eAAO,MAAM,eAAe,GAAI,OAAO,MAAM,EAAE,UAAU,MAAM,EAAE,UAAU,MAAM,IAAI,KAAG,IAOvF,CAAC"}
@@ -0,0 +1,67 @@
1
+ import { Platform, Alert } from 'react-native';
2
+ /**
3
+ * Platform-aware alert helper that works on both native and web platforms
4
+ * On web, uses window.confirm/window.alert since Alert.alert is not supported
5
+ * On native, uses the standard Alert.alert
6
+ */
7
+ export const showAlert = (title, message, buttons) => {
8
+ if (Platform.OS === 'web') {
9
+ // Web implementation using native browser dialogs
10
+ const fullMessage = message ? `${title}\n\n${message}` : title;
11
+ if (buttons && buttons.length > 1) {
12
+ // Multiple buttons - use confirm dialog
13
+ const confirmed = window.confirm(fullMessage);
14
+ if (confirmed) {
15
+ // Find and call the primary/positive button callback
16
+ const confirmButton = buttons.find(btn => btn.style !== 'cancel' && btn.onPress);
17
+ confirmButton?.onPress?.();
18
+ }
19
+ else {
20
+ // Find and call the cancel button callback
21
+ const cancelButton = buttons.find(btn => btn.style === 'cancel');
22
+ cancelButton?.onPress?.();
23
+ }
24
+ }
25
+ else if (buttons && buttons.length === 1) {
26
+ // Single button - use alert dialog
27
+ window.alert(fullMessage);
28
+ buttons[0]?.onPress?.();
29
+ }
30
+ else {
31
+ // No buttons - just show alert
32
+ window.alert(fullMessage);
33
+ }
34
+ }
35
+ else {
36
+ // Native implementation - use standard Alert.alert
37
+ Alert.alert(title, message, buttons);
38
+ }
39
+ };
40
+ /**
41
+ * Simplified confirm dialog for yes/no scenarios
42
+ */
43
+ export const showConfirm = (title, message, onConfirm, onCancel) => {
44
+ showAlert(title, message, [
45
+ {
46
+ text: 'Cancel',
47
+ style: 'cancel',
48
+ onPress: onCancel,
49
+ },
50
+ {
51
+ text: 'OK',
52
+ onPress: onConfirm,
53
+ },
54
+ ]);
55
+ };
56
+ /**
57
+ * Simple alert with just an OK button
58
+ */
59
+ export const showSimpleAlert = (title, message, onPress) => {
60
+ showAlert(title, message, [
61
+ {
62
+ text: 'OK',
63
+ onPress,
64
+ },
65
+ ]);
66
+ };
67
+ //# sourceMappingURL=platformAlert.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"platformAlert.js","sourceRoot":"","sources":["../../src/utils/platformAlert.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,KAAK,EAAE,MAAM,cAAc,CAAC;AAQ/C;;;;GAIG;AACH,MAAM,CAAC,MAAM,SAAS,GAAG,CACvB,KAAa,EACb,OAAgB,EAChB,OAAuB,EACjB,EAAE;IACR,IAAI,QAAQ,CAAC,EAAE,KAAK,KAAK,EAAE,CAAC;QAC1B,kDAAkD;QAClD,MAAM,WAAW,GAAG,OAAO,CAAC,CAAC,CAAC,GAAG,KAAK,OAAO,OAAO,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC;QAE/D,IAAI,OAAO,IAAI,OAAO,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YAClC,wCAAwC;YACxC,MAAM,SAAS,GAAG,MAAM,CAAC,OAAO,CAAC,WAAW,CAAC,CAAC;YAE9C,IAAI,SAAS,EAAE,CAAC;gBACd,qDAAqD;gBACrD,MAAM,aAAa,GAAG,OAAO,CAAC,IAAI,CAChC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,KAAK,KAAK,QAAQ,IAAI,GAAG,CAAC,OAAO,CAC7C,CAAC;gBACF,aAAa,EAAE,OAAO,EAAE,EAAE,CAAC;YAC7B,CAAC;iBAAM,CAAC;gBACN,2CAA2C;gBAC3C,MAAM,YAAY,GAAG,OAAO,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,KAAK,KAAK,QAAQ,CAAC,CAAC;gBACjE,YAAY,EAAE,OAAO,EAAE,EAAE,CAAC;YAC5B,CAAC;QACH,CAAC;aAAM,IAAI,OAAO,IAAI,OAAO,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YAC3C,mCAAmC;YACnC,MAAM,CAAC,KAAK,CAAC,WAAW,CAAC,CAAC;YAC1B,OAAO,CAAC,CAAC,CAAC,EAAE,OAAO,EAAE,EAAE,CAAC;QAC1B,CAAC;aAAM,CAAC;YACN,+BAA+B;YAC/B,MAAM,CAAC,KAAK,CAAC,WAAW,CAAC,CAAC;QAC5B,CAAC;IACH,CAAC;SAAM,CAAC;QACN,mDAAmD;QACnD,KAAK,CAAC,KAAK,CAAC,KAAK,EAAE,OAAO,EAAE,OAAO,CAAC,CAAC;IACvC,CAAC;AACH,CAAC,CAAC;AAEF;;GAEG;AACH,MAAM,CAAC,MAAM,WAAW,GAAG,CACzB,KAAa,EACb,OAAe,EACf,SAAqB,EACrB,QAAqB,EACf,EAAE;IACR,SAAS,CAAC,KAAK,EAAE,OAAO,EAAE;QACxB;YACE,IAAI,EAAE,QAAQ;YACd,KAAK,EAAE,QAAQ;YACf,OAAO,EAAE,QAAQ;SAClB;QACD;YACE,IAAI,EAAE,IAAI;YACV,OAAO,EAAE,SAAS;SACnB;KACF,CAAC,CAAC;AACL,CAAC,CAAC;AAEF;;GAEG;AACH,MAAM,CAAC,MAAM,eAAe,GAAG,CAAC,KAAa,EAAE,OAAgB,EAAE,OAAoB,EAAQ,EAAE;IAC7F,SAAS,CAAC,KAAK,EAAE,OAAO,EAAE;QACxB;YACE,IAAI,EAAE,IAAI;YACV,OAAO;SACR;KACF,CAAC,CAAC;AACL,CAAC,CAAC","sourcesContent":["import { Platform, Alert } from 'react-native';\n\nexport interface AlertButton {\n text?: string;\n onPress?: () => void;\n style?: 'default' | 'cancel' | 'destructive';\n}\n\n/**\n * Platform-aware alert helper that works on both native and web platforms\n * On web, uses window.confirm/window.alert since Alert.alert is not supported\n * On native, uses the standard Alert.alert\n */\nexport const showAlert = (\n title: string,\n message?: string,\n buttons?: AlertButton[]\n): void => {\n if (Platform.OS === 'web') {\n // Web implementation using native browser dialogs\n const fullMessage = message ? `${title}\\n\\n${message}` : title;\n\n if (buttons && buttons.length > 1) {\n // Multiple buttons - use confirm dialog\n const confirmed = window.confirm(fullMessage);\n \n if (confirmed) {\n // Find and call the primary/positive button callback\n const confirmButton = buttons.find(\n btn => btn.style !== 'cancel' && btn.onPress\n );\n confirmButton?.onPress?.();\n } else {\n // Find and call the cancel button callback\n const cancelButton = buttons.find(btn => btn.style === 'cancel');\n cancelButton?.onPress?.();\n }\n } else if (buttons && buttons.length === 1) {\n // Single button - use alert dialog\n window.alert(fullMessage);\n buttons[0]?.onPress?.();\n } else {\n // No buttons - just show alert\n window.alert(fullMessage);\n }\n } else {\n // Native implementation - use standard Alert.alert\n Alert.alert(title, message, buttons);\n }\n};\n\n/**\n * Simplified confirm dialog for yes/no scenarios\n */\nexport const showConfirm = (\n title: string,\n message: string,\n onConfirm: () => void,\n onCancel?: () => void\n): void => {\n showAlert(title, message, [\n {\n text: 'Cancel',\n style: 'cancel',\n onPress: onCancel,\n },\n {\n text: 'OK',\n onPress: onConfirm,\n },\n ]);\n};\n\n/**\n * Simple alert with just an OK button\n */\nexport const showSimpleAlert = (title: string, message?: string, onPress?: () => void): void => {\n showAlert(title, message, [\n {\n text: 'OK',\n onPress,\n },\n ]);\n};\n\n"]}
@@ -0,0 +1,10 @@
1
+ import { BackendKYCTemplate, KYCTemplate } from '../types/KYC.types';
2
+ /**
3
+ * Transform backend template to SDK template format
4
+ */
5
+ export declare function transformBackendTemplateToSDK(backendTemplate: BackendKYCTemplate): KYCTemplate;
6
+ /**
7
+ * Validate transformed template
8
+ */
9
+ export declare function validateTransformedTemplate(template: KYCTemplate): boolean;
10
+ //# sourceMappingURL=template-transformer.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"template-transformer.d.ts","sourceRoot":"","sources":["../../src/utils/template-transformer.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,kBAAkB,EAElB,WAAW,EAaZ,MAAM,oBAAoB,CAAC;AAiS5B;;GAEG;AACH,wBAAgB,6BAA6B,CAC3C,eAAe,EAAE,kBAAkB,GAClC,WAAW,CAgGb;AAED;;GAEG;AACH,wBAAgB,2BAA2B,CAAC,QAAQ,EAAE,WAAW,GAAG,OAAO,CAqB1E"}
@@ -0,0 +1,353 @@
1
+ import { logger } from './logger';
2
+ /**
3
+ * Hash a string to a number (simple hash function)
4
+ */
5
+ function hashStringToNumber(str) {
6
+ let hash = 0;
7
+ for (let i = 0; i < str.length; i++) {
8
+ const char = str.charCodeAt(i);
9
+ hash = ((hash << 5) - hash) + char;
10
+ hash = hash & hash; // Convert to 32-bit integer
11
+ }
12
+ return Math.abs(hash);
13
+ }
14
+ /**
15
+ * Map backend component types to SDK component types
16
+ */
17
+ const COMPONENT_TYPE_MAPPING = {
18
+ 'welcome': 'welcome',
19
+ 'government-id': 'id_card',
20
+ 'selfie-capture': 'selfie',
21
+ 'location-capture': 'location',
22
+ 'review-submit': 'review_submit',
23
+ 'verification-progress': 'verification_progress',
24
+ 'file-upload': 'file_upload',
25
+ 'country-selection': 'country_selection',
26
+ };
27
+ /**
28
+ * Transform backend translations to SDK labels and instructions
29
+ */
30
+ function transformTranslations(translations, defaultLanguage = 'en') {
31
+ const labels = { en: '', fr: '' };
32
+ const instructions = { en: '', fr: '' };
33
+ // Extract title as label
34
+ if (translations.en?.title)
35
+ labels.en = translations.en.title;
36
+ if (translations.fr?.title)
37
+ labels.fr = translations.fr.title;
38
+ // Extract instructions
39
+ if (translations.en?.instructions)
40
+ instructions.en = translations.en.instructions;
41
+ if (translations.fr?.instructions)
42
+ instructions.fr = translations.fr.instructions;
43
+ // Fallback to description if instructions not available
44
+ if (!instructions.en && translations.en?.description) {
45
+ instructions.en = translations.en.description;
46
+ }
47
+ if (!instructions.fr && translations.fr?.description) {
48
+ instructions.fr = translations.fr.description;
49
+ }
50
+ // Support other languages
51
+ Object.keys(translations).forEach((lang) => {
52
+ if (lang !== 'en' && lang !== 'fr' && translations[lang]) {
53
+ labels[lang] = translations[lang]?.title || '';
54
+ instructions[lang] = translations[lang]?.instructions || translations[lang]?.description || '';
55
+ }
56
+ });
57
+ return { labels, instructions };
58
+ }
59
+ /**
60
+ * Transform UI configuration
61
+ */
62
+ function transformUI(translations) {
63
+ const buttonText = { en: '', fr: '' };
64
+ if (translations.en?.buttonText)
65
+ buttonText.en = translations.en.buttonText;
66
+ if (translations.fr?.buttonText)
67
+ buttonText.fr = translations.fr.buttonText;
68
+ // Support other languages
69
+ Object.keys(translations).forEach((lang) => {
70
+ if (lang !== 'en' && lang !== 'fr' && translations[lang]?.buttonText) {
71
+ buttonText[lang] = translations[lang].buttonText;
72
+ }
73
+ });
74
+ return {
75
+ buttonText,
76
+ themeColor: '#2DBD60', // Default theme color
77
+ };
78
+ }
79
+ /**
80
+ * Transform welcome config
81
+ */
82
+ function transformWelcomeConfig(config) {
83
+ return {
84
+ subtitle: config.subtitle,
85
+ buttonText: config.buttonText,
86
+ requirements: config.requirements || [],
87
+ estimatedTime: config.estimatedTime,
88
+ consentOptions: config.consentOptions || {
89
+ showPrivacyPolicy: true,
90
+ showTermsOfService: true,
91
+ showMarketingConsent: false,
92
+ },
93
+ welcomeMessage: config.welcomeMessage,
94
+ showEstimatedTime: config.showEstimatedTime !== false,
95
+ };
96
+ }
97
+ /**
98
+ * Transform government ID config to IDCardConfig
99
+ */
100
+ function transformGovernmentIdConfig(config) {
101
+ const documentTypes = config.documentTypes || ['passport', 'nationalId'];
102
+ const sides = [];
103
+ if (config.requiredSides === 'front-back' || config.requiredSides === 'both') {
104
+ sides.push('front', 'back');
105
+ }
106
+ else if (config.requiredSides === 'front') {
107
+ sides.push('front');
108
+ }
109
+ else if (config.requiredSides === 'back') {
110
+ sides.push('back');
111
+ }
112
+ else {
113
+ // Default to both sides
114
+ sides.push('front', 'back');
115
+ }
116
+ const idCardConfig = {
117
+ sides,
118
+ allowed_formats: ['jpg', 'jpeg', 'png'],
119
+ max_size_mb: 10,
120
+ document_types: documentTypes.map((dt) => {
121
+ const mapping = {
122
+ 'passport': 'passport',
123
+ 'nationalId': 'national_id',
124
+ 'driversLicense': 'drivers_licence',
125
+ 'identityCard': 'identity_card',
126
+ };
127
+ return mapping[dt] || dt;
128
+ }),
129
+ };
130
+ // Add bbox configs if available
131
+ if (config.cameraOverlay?.bbox) {
132
+ const bbox = config.cameraOverlay.bbox;
133
+ idCardConfig.bbox_configs = {};
134
+ documentTypes.forEach((dt) => {
135
+ const docType = dt;
136
+ idCardConfig.bbox_configs[docType] = {
137
+ xMin: bbox.xMin || 20,
138
+ yMin: bbox.yMin || 140,
139
+ xMax: bbox.xMax || 370,
140
+ yMax: bbox.yMax || 340,
141
+ borderColor: bbox.borderColor || '#2DBD60',
142
+ borderWidth: bbox.borderWidth || 3,
143
+ cornerRadius: bbox.cornerRadius || 8,
144
+ };
145
+ });
146
+ }
147
+ // Store additional backend-specific config in a way that can be accessed
148
+ idCardConfig.authenticationMethods = config.authenticationMethods;
149
+ idCardConfig.documentTypesByCountry = config.documentTypesByCountry;
150
+ idCardConfig.selectedCountries = config.selectedCountries;
151
+ idCardConfig.instructionsByDocumentType = config.instructionsByDocumentType;
152
+ idCardConfig.cameraSettings = config.cameraSettings;
153
+ idCardConfig.validationRules = config.validationRules;
154
+ return idCardConfig;
155
+ }
156
+ /**
157
+ * Transform location capture config
158
+ */
159
+ function transformLocationConfig(config) {
160
+ return {
161
+ accuracy: config.accuracy || 'high',
162
+ required: config.required !== false,
163
+ };
164
+ }
165
+ /**
166
+ * Transform selfie capture config
167
+ */
168
+ function transformSelfieConfig(config) {
169
+ return {
170
+ liveness_check: config.livenessEnabled !== false,
171
+ max_attempts: config.maxAttempts || 5,
172
+ orientations: config.orientations || ['center'],
173
+ };
174
+ }
175
+ /**
176
+ * Transform component config based on type
177
+ */
178
+ function transformComponentConfig(type, backendConfig) {
179
+ switch (type) {
180
+ case 'welcome':
181
+ return transformWelcomeConfig(backendConfig);
182
+ case 'id_card':
183
+ return transformGovernmentIdConfig(backendConfig);
184
+ case 'location':
185
+ return transformLocationConfig(backendConfig);
186
+ case 'selfie':
187
+ return transformSelfieConfig(backendConfig);
188
+ case 'file_upload':
189
+ return {
190
+ allowed_formats: backendConfig.allowed_formats || ['jpg', 'jpeg', 'png', 'pdf'],
191
+ max_size_mb: backendConfig.max_size_mb || 10,
192
+ required: backendConfig.required !== false,
193
+ };
194
+ case 'country_selection':
195
+ return {
196
+ allowed_countries: backendConfig.allowed_countries || [],
197
+ default_country: backendConfig.default_country || '',
198
+ required: backendConfig.required !== false,
199
+ };
200
+ default:
201
+ return backendConfig;
202
+ }
203
+ }
204
+ /**
205
+ * Transform a single backend component to SDK component
206
+ */
207
+ function transformComponent(backendComponent, componentIndex) {
208
+ const mappedType = COMPONENT_TYPE_MAPPING[backendComponent.type];
209
+ if (!mappedType) {
210
+ logger.warn(`Unknown component type: ${backendComponent.type}, defaulting to initialization`);
211
+ }
212
+ const componentId = hashStringToNumber(backendComponent.id);
213
+ const { labels, instructions } = transformTranslations(backendComponent.translations);
214
+ const ui = transformUI(backendComponent.translations);
215
+ const config = transformComponentConfig(mappedType || 'initialization', backendComponent.config);
216
+ // For components with multiple sides (like id_card), create nested structure
217
+ let finalLabels = labels;
218
+ let finalInstructions = instructions;
219
+ let finalUI = ui;
220
+ if (mappedType === 'id_card' && backendComponent.config.requiredSides === 'front-back') {
221
+ // Create separate labels/instructions for front and back
222
+ finalLabels = {
223
+ front: {
224
+ en: backendComponent.translations.en?.title || labels.en,
225
+ fr: backendComponent.translations.fr?.title || labels.fr,
226
+ },
227
+ back: {
228
+ en: `${labels.en} (Back)`,
229
+ fr: `${labels.fr} (Verso)`,
230
+ },
231
+ };
232
+ finalInstructions = {
233
+ front: instructions,
234
+ back: instructions,
235
+ };
236
+ finalUI = {
237
+ front: ui,
238
+ back: ui,
239
+ };
240
+ }
241
+ return {
242
+ id: componentId,
243
+ type: mappedType || 'initialization',
244
+ order: backendComponent.order,
245
+ labels: finalLabels,
246
+ instructions: finalInstructions,
247
+ ui: finalUI,
248
+ config,
249
+ required: backendComponent.required !== false,
250
+ };
251
+ }
252
+ /**
253
+ * Transform backend template to SDK template format
254
+ */
255
+ export function transformBackendTemplateToSDK(backendTemplate) {
256
+ try {
257
+ // Validate backend template
258
+ if (!backendTemplate.id || !backendTemplate.name || !Array.isArray(backendTemplate.components)) {
259
+ throw new Error('Invalid backend template structure');
260
+ }
261
+ // Sort components by order
262
+ const sortedComponents = [...backendTemplate.components].sort((a, b) => a.order - b.order);
263
+ // Transform each component
264
+ const transformedComponents = sortedComponents.map((comp, index) => transformComponent(comp, index));
265
+ // Auto-create country_selection component before id_card if government-id has selection data
266
+ // Check if country_selection already exists in backend template
267
+ const hasCountrySelectionInBackend = sortedComponents.some(c => c.type === 'country-selection');
268
+ if (!hasCountrySelectionInBackend) {
269
+ // Find the first government-id component with selection data
270
+ const govIdWithSelection = sortedComponents.find(backendComp => backendComp.type === 'government-id' &&
271
+ backendComp.config && (backendComp.config.selectedCountries ||
272
+ backendComp.config.documentTypesByCountry));
273
+ if (govIdWithSelection) {
274
+ // Find the corresponding transformed id_card component
275
+ const transformedIdCard = transformedComponents.find(c => hashStringToNumber(govIdWithSelection.id) === c.id);
276
+ if (transformedIdCard) {
277
+ // Create a country_selection component before id_card
278
+ const countrySelectionComponent = {
279
+ id: hashStringToNumber(`${govIdWithSelection.id}-country-selection`),
280
+ type: 'country_selection',
281
+ order: transformedIdCard.order - 0.5, // Insert before id_card
282
+ labels: {
283
+ en: govIdWithSelection.translations.en?.title || 'Select Country and Document',
284
+ fr: govIdWithSelection.translations.fr?.title || 'Sélectionnez le pays et le document',
285
+ },
286
+ instructions: {
287
+ en: 'Please select your country and document type',
288
+ fr: 'Veuillez sélectionner votre pays et le type de document',
289
+ },
290
+ ui: {
291
+ themeColor: '#2DBD60',
292
+ buttonText: {
293
+ en: 'Continue',
294
+ fr: 'Continuer',
295
+ },
296
+ },
297
+ config: {
298
+ allowed_countries: govIdWithSelection.config.selectedCountries || [],
299
+ default_country: '',
300
+ required: true,
301
+ },
302
+ };
303
+ // Insert country_selection before id_card in transformedComponents
304
+ const idCardIndex = transformedComponents.indexOf(transformedIdCard);
305
+ transformedComponents.splice(idCardIndex, 0, countrySelectionComponent);
306
+ }
307
+ }
308
+ }
309
+ // Re-assign order values sequentially after insertion
310
+ transformedComponents.forEach((comp, index) => {
311
+ comp.order = index + 1;
312
+ });
313
+ // Create SDK template
314
+ const sdkTemplate = {
315
+ id: hashStringToNumber(backendTemplate.id),
316
+ name: backendTemplate.name,
317
+ description: backendTemplate.description || {
318
+ en: '',
319
+ fr: '',
320
+ },
321
+ version: backendTemplate.version || '1.0.0',
322
+ components: transformedComponents,
323
+ };
324
+ logger.log(`Template transformed: ${backendTemplate.id} -> ${sdkTemplate.id} with ${transformedComponents.length} components`);
325
+ return sdkTemplate;
326
+ }
327
+ catch (error) {
328
+ logger.error('Error transforming template:', error);
329
+ throw new Error(`Failed to transform template: ${error.message}`);
330
+ }
331
+ }
332
+ /**
333
+ * Validate transformed template
334
+ */
335
+ export function validateTransformedTemplate(template) {
336
+ if (!template.id || !template.name || !Array.isArray(template.components)) {
337
+ return false;
338
+ }
339
+ if (!template.name.en || !template.name.fr) {
340
+ return false;
341
+ }
342
+ // Validate each component
343
+ for (const component of template.components) {
344
+ if (!component.id || !component.type || typeof component.order !== 'number') {
345
+ return false;
346
+ }
347
+ if (!component.labels || !component.instructions || !component.config) {
348
+ return false;
349
+ }
350
+ }
351
+ return true;
352
+ }
353
+ //# sourceMappingURL=template-transformer.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"template-transformer.js","sourceRoot":"","sources":["../../src/utils/template-transformer.ts"],"names":[],"mappings":"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","sourcesContent":["import {\n BackendKYCTemplate,\n BackendTemplateComponent,\n KYCTemplate,\n TemplateComponent,\n LocalizedText,\n ComponentUI,\n IDCardConfig,\n LocationConfig,\n SelfieConfig,\n FileUploadConfig,\n CountrySelectionConfig,\n ComponentConfig,\n WelcomeConfig,\n GovernmentDocumentType,\n GovernmentIdConfig,\n} from '../types/KYC.types';\nimport { logger } from './logger';\n\n/**\n * Hash a string to a number (simple hash function)\n */\nfunction hashStringToNumber(str: string): number {\n let hash = 0;\n for (let i = 0; i < str.length; i++) {\n const char = str.charCodeAt(i);\n hash = ((hash << 5) - hash) + char;\n hash = hash & hash; // Convert to 32-bit integer\n }\n return Math.abs(hash);\n}\n\n/**\n * Map backend component types to SDK component types\n */\nconst COMPONENT_TYPE_MAPPING: Record<string, TemplateComponent['type']> = {\n 'welcome': 'welcome',\n 'government-id': 'id_card',\n 'selfie-capture': 'selfie',\n 'location-capture': 'location',\n 'review-submit': 'review_submit',\n 'verification-progress': 'verification_progress',\n 'file-upload': 'file_upload',\n 'country-selection': 'country_selection',\n};\n\n/**\n * Transform backend translations to SDK labels and instructions\n */\nfunction transformTranslations(\n translations: BackendTemplateComponent['translations'],\n defaultLanguage: string = 'en'\n): { labels: LocalizedText; instructions: LocalizedText } {\n const labels: LocalizedText = { en: '', fr: '' };\n const instructions: LocalizedText = { en: '', fr: '' };\n\n // Extract title as label\n if (translations.en?.title) labels.en = translations.en.title;\n if (translations.fr?.title) labels.fr = translations.fr.title;\n\n // Extract instructions\n if (translations.en?.instructions) instructions.en = translations.en.instructions;\n if (translations.fr?.instructions) instructions.fr = translations.fr.instructions;\n\n // Fallback to description if instructions not available\n if (!instructions.en && translations.en?.description) {\n instructions.en = translations.en.description;\n }\n if (!instructions.fr && translations.fr?.description) {\n instructions.fr = translations.fr.description;\n }\n\n // Support other languages\n Object.keys(translations).forEach((lang) => {\n if (lang !== 'en' && lang !== 'fr' && translations[lang]) {\n labels[lang] = translations[lang]?.title || '';\n instructions[lang] = translations[lang]?.instructions || translations[lang]?.description || '';\n }\n });\n\n return { labels, instructions };\n}\n\n/**\n * Transform UI configuration\n */\nfunction transformUI(translations: BackendTemplateComponent['translations']): ComponentUI {\n const buttonText: LocalizedText = { en: '', fr: '' };\n\n if (translations.en?.buttonText) buttonText.en = translations.en.buttonText;\n if (translations.fr?.buttonText) buttonText.fr = translations.fr.buttonText;\n\n // Support other languages\n Object.keys(translations).forEach((lang) => {\n if (lang !== 'en' && lang !== 'fr' && translations[lang]?.buttonText) {\n buttonText[lang] = translations[lang]!.buttonText!;\n }\n });\n\n return {\n buttonText,\n themeColor: '#2DBD60', // Default theme color\n };\n}\n\n/**\n * Transform welcome config\n */\nfunction transformWelcomeConfig(config: any): WelcomeConfig {\n return {\n subtitle: config.subtitle,\n buttonText: config.buttonText,\n requirements: config.requirements || [],\n estimatedTime: config.estimatedTime,\n consentOptions: config.consentOptions || {\n showPrivacyPolicy: true,\n showTermsOfService: true,\n showMarketingConsent: false,\n },\n welcomeMessage: config.welcomeMessage,\n showEstimatedTime: config.showEstimatedTime !== false,\n } as WelcomeConfig;\n}\n\n/**\n * Transform government ID config to IDCardConfig\n */\nfunction transformGovernmentIdConfig(config: any): IDCardConfig {\n const documentTypes: string[] = config.documentTypes || ['passport', 'nationalId'];\n const sides: string[] = [];\n\n if (config.requiredSides === 'front-back' || config.requiredSides === 'both') {\n sides.push('front', 'back');\n } else if (config.requiredSides === 'front') {\n sides.push('front');\n } else if (config.requiredSides === 'back') {\n sides.push('back');\n } else {\n // Default to both sides\n sides.push('front', 'back');\n }\n\n const idCardConfig: IDCardConfig = {\n sides,\n allowed_formats: ['jpg', 'jpeg', 'png'],\n max_size_mb: 10,\n document_types: documentTypes.map((dt: string) => {\n const mapping: Record<string, any> = {\n 'passport': 'passport',\n 'nationalId': 'national_id',\n 'driversLicense': 'drivers_licence',\n 'identityCard': 'identity_card',\n };\n return mapping[dt] || dt;\n }) as any[],\n };\n\n // Add bbox configs if available\n if (config.cameraOverlay?.bbox) {\n const bbox = config.cameraOverlay.bbox;\n idCardConfig.bbox_configs = {} as Record<GovernmentDocumentType, {\n xMin: number;\n yMin: number;\n xMax: number;\n yMax: number;\n borderColor?: string;\n borderWidth?: number;\n cornerRadius?: number;\n }>;\n documentTypes.forEach((dt: string) => {\n const docType = dt as GovernmentDocumentType;\n (idCardConfig.bbox_configs as any)[docType] = {\n xMin: bbox.xMin || 20,\n yMin: bbox.yMin || 140,\n xMax: bbox.xMax || 370,\n yMax: bbox.yMax || 340,\n borderColor: bbox.borderColor || '#2DBD60',\n borderWidth: bbox.borderWidth || 3,\n cornerRadius: bbox.cornerRadius || 8,\n };\n });\n }\n\n // Store additional backend-specific config in a way that can be accessed\n (idCardConfig as any).authenticationMethods = config.authenticationMethods;\n (idCardConfig as any).documentTypesByCountry = config.documentTypesByCountry;\n (idCardConfig as any).selectedCountries = config.selectedCountries;\n (idCardConfig as any).instructionsByDocumentType = config.instructionsByDocumentType;\n (idCardConfig as any).cameraSettings = config.cameraSettings;\n (idCardConfig as any).validationRules = config.validationRules;\n\n return idCardConfig;\n}\n\n/**\n * Transform location capture config\n */\nfunction transformLocationConfig(config: any): LocationConfig {\n return {\n accuracy: config.accuracy || 'high',\n required: config.required !== false,\n } as LocationConfig;\n}\n\n/**\n * Transform selfie capture config\n */\nfunction transformSelfieConfig(config: any): SelfieConfig {\n return {\n liveness_check: config.livenessEnabled !== false,\n max_attempts: config.maxAttempts || 5,\n orientations: config.orientations || ['center'],\n } as SelfieConfig;\n}\n\n/**\n * Transform component config based on type\n */\nfunction transformComponentConfig(\n type: TemplateComponent['type'],\n backendConfig: any\n): ComponentConfig {\n switch (type) {\n case 'welcome':\n return transformWelcomeConfig(backendConfig);\n case 'id_card':\n return transformGovernmentIdConfig(backendConfig);\n case 'location':\n return transformLocationConfig(backendConfig);\n case 'selfie':\n return transformSelfieConfig(backendConfig);\n case 'file_upload':\n return {\n allowed_formats: backendConfig.allowed_formats || ['jpg', 'jpeg', 'png', 'pdf'],\n max_size_mb: backendConfig.max_size_mb || 10,\n required: backendConfig.required !== false,\n } as FileUploadConfig;\n case 'country_selection':\n return {\n allowed_countries: backendConfig.allowed_countries || [],\n default_country: backendConfig.default_country || '',\n required: backendConfig.required !== false,\n } as CountrySelectionConfig;\n default:\n return backendConfig as ComponentConfig;\n }\n}\n\n/**\n * Transform a single backend component to SDK component\n */\nfunction transformComponent(\n backendComponent: BackendTemplateComponent,\n componentIndex: number\n): TemplateComponent {\n const mappedType = COMPONENT_TYPE_MAPPING[backendComponent.type];\n\n if (!mappedType) {\n logger.warn(`Unknown component type: ${backendComponent.type}, defaulting to initialization`);\n }\n\n const componentId = hashStringToNumber(backendComponent.id);\n const { labels, instructions } = transformTranslations(backendComponent.translations);\n const ui = transformUI(backendComponent.translations);\n const config = transformComponentConfig(mappedType || 'initialization', backendComponent.config);\n\n // For components with multiple sides (like id_card), create nested structure\n let finalLabels: LocalizedText | Record<string, LocalizedText> = labels;\n let finalInstructions: LocalizedText | Record<string, LocalizedText> = instructions;\n let finalUI: ComponentUI | Record<string, ComponentUI> = ui;\n\n if (mappedType === 'id_card' && (backendComponent.config as GovernmentIdConfig).requiredSides === 'front-back') {\n // Create separate labels/instructions for front and back\n finalLabels = {\n front: {\n en: backendComponent.translations.en?.title || labels.en,\n fr: backendComponent.translations.fr?.title || labels.fr,\n },\n back: {\n en: `${labels.en} (Back)`,\n fr: `${labels.fr} (Verso)`,\n },\n };\n finalInstructions = {\n front: instructions,\n back: instructions,\n };\n finalUI = {\n front: ui,\n back: ui,\n };\n }\n\n return {\n id: componentId,\n type: mappedType || 'initialization',\n order: backendComponent.order,\n labels: finalLabels,\n instructions: finalInstructions,\n ui: finalUI,\n config,\n required: backendComponent.required !== false,\n } as TemplateComponent;\n}\n\n/**\n * Transform backend template to SDK template format\n */\nexport function transformBackendTemplateToSDK(\n backendTemplate: BackendKYCTemplate\n): KYCTemplate {\n try {\n // Validate backend template\n if (!backendTemplate.id || !backendTemplate.name || !Array.isArray(backendTemplate.components)) {\n throw new Error('Invalid backend template structure');\n }\n\n // Sort components by order\n const sortedComponents = [...backendTemplate.components].sort(\n (a, b) => a.order - b.order\n );\n\n // Transform each component\n const transformedComponents = sortedComponents.map((comp, index) =>\n transformComponent(comp, index)\n );\n\n // Auto-create country_selection component before id_card if government-id has selection data\n // Check if country_selection already exists in backend template\n const hasCountrySelectionInBackend = sortedComponents.some(c => (c as any).type === 'country-selection');\n \n if (!hasCountrySelectionInBackend) {\n // Find the first government-id component with selection data\n const govIdWithSelection = sortedComponents.find(backendComp => \n backendComp.type === 'government-id' && \n backendComp.config && (\n (backendComp.config as any).selectedCountries ||\n (backendComp.config as any).documentTypesByCountry\n )\n );\n \n if (govIdWithSelection) {\n // Find the corresponding transformed id_card component\n const transformedIdCard = transformedComponents.find(c => \n hashStringToNumber(govIdWithSelection.id) === c.id\n );\n \n if (transformedIdCard) {\n // Create a country_selection component before id_card\n const countrySelectionComponent: TemplateComponent = {\n id: hashStringToNumber(`${govIdWithSelection.id}-country-selection`),\n type: 'country_selection',\n order: transformedIdCard.order - 0.5, // Insert before id_card\n labels: {\n en: govIdWithSelection.translations.en?.title || 'Select Country and Document',\n fr: govIdWithSelection.translations.fr?.title || 'Sélectionnez le pays et le document',\n },\n instructions: {\n en: 'Please select your country and document type',\n fr: 'Veuillez sélectionner votre pays et le type de document',\n },\n ui: {\n themeColor: '#2DBD60',\n buttonText: {\n en: 'Continue',\n fr: 'Continuer',\n },\n } as ComponentUI,\n config: {\n allowed_countries: (govIdWithSelection.config as any).selectedCountries || [],\n default_country: '',\n required: true,\n } as CountrySelectionConfig,\n };\n \n // Insert country_selection before id_card in transformedComponents\n const idCardIndex = transformedComponents.indexOf(transformedIdCard);\n transformedComponents.splice(idCardIndex, 0, countrySelectionComponent);\n }\n }\n }\n \n // Re-assign order values sequentially after insertion\n transformedComponents.forEach((comp, index) => {\n comp.order = index + 1;\n });\n\n // Create SDK template\n const sdkTemplate: KYCTemplate = {\n id: hashStringToNumber(backendTemplate.id),\n name: backendTemplate.name as LocalizedText,\n description: backendTemplate.description || {\n en: '',\n fr: '',\n },\n version: backendTemplate.version || '1.0.0',\n components: transformedComponents,\n };\n\n logger.log(`Template transformed: ${backendTemplate.id} -> ${sdkTemplate.id} with ${transformedComponents.length} components`);\n\n return sdkTemplate;\n } catch (error: any) {\n logger.error('Error transforming template:', error);\n throw new Error(`Failed to transform template: ${error.message}`);\n }\n}\n\n/**\n * Validate transformed template\n */\nexport function validateTransformedTemplate(template: KYCTemplate): boolean {\n if (!template.id || !template.name || !Array.isArray(template.components)) {\n return false;\n }\n\n if (!template.name.en || !template.name.fr) {\n return false;\n }\n\n // Validate each component\n for (const component of template.components) {\n if (!component.id || !component.type || typeof component.order !== 'number') {\n return false;\n }\n\n if (!component.labels || !component.instructions || !component.config) {\n return false;\n }\n }\n\n return true;\n}"]}
@@ -1 +1 @@
1
- {"version":3,"file":"WebKYCEntry.d.ts","sourceRoot":"","sources":["../../src/web/WebKYCEntry.tsx"],"names":[],"mappings":"AAAA,OAAO,KAA2C,MAAM,OAAO,CAAC;AAOhE,UAAU,gBAAgB;IACxB,UAAU,CAAC,EAAE,CAAC,IAAI,EAAE,GAAG,KAAK,IAAI,CAAC;IACjC,OAAO,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;IAClC,QAAQ,CAAC,EAAE,MAAM,IAAI,CAAC;CACvB;AAUD,QAAA,MAAM,WAAW,EAAE,KAAK,CAAC,EAAE,CAAC,gBAAgB,CA2K3C,CAAC;AAsBF,eAAe,WAAW,CAAC"}
1
+ {"version":3,"file":"WebKYCEntry.d.ts","sourceRoot":"","sources":["../../src/web/WebKYCEntry.tsx"],"names":[],"mappings":"AAAA,OAAO,KAA2C,MAAM,OAAO,CAAC;AAQhE,UAAU,gBAAgB;IACxB,UAAU,CAAC,EAAE,CAAC,IAAI,EAAE,GAAG,KAAK,IAAI,CAAC;IACjC,OAAO,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;IAClC,QAAQ,CAAC,EAAE,MAAM,IAAI,CAAC;CACvB;AAiBD,QAAA,MAAM,WAAW,EAAE,KAAK,CAAC,EAAE,CAAC,gBAAgB,CAiO3C,CAAC;AA0DF,eAAe,WAAW,CAAC"}