@transfergratis/react-native-sdk 0.1.13 → 0.1.14
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/android/build.gradle +1 -1
- package/build/components/KYCElements/IDCardCapture.d.ts.map +1 -1
- package/build/components/KYCElements/IDCardCapture.js +2 -18
- package/build/components/KYCElements/IDCardCapture.js.map +1 -1
- package/build/components/KYCElements/VerificationProgressTemplate.js +1 -1
- package/build/components/KYCElements/VerificationProgressTemplate.js.map +1 -1
- package/build/components/TemplateKYCExample.js +0 -64
- package/build/components/TemplateKYCExample.js.map +1 -1
- package/build/hooks/useTemplateKYCFlow.d.ts.map +1 -1
- package/build/hooks/useTemplateKYCFlow.js +6 -12
- package/build/hooks/useTemplateKYCFlow.js.map +1 -1
- package/build/i18n/en/index.d.ts +1 -0
- package/build/i18n/en/index.d.ts.map +1 -1
- package/build/i18n/en/index.js +2 -1
- package/build/i18n/en/index.js.map +1 -1
- package/build/i18n/fr/index.d.ts +1 -0
- package/build/i18n/fr/index.d.ts.map +1 -1
- package/build/i18n/fr/index.js +2 -1
- package/build/i18n/fr/index.js.map +1 -1
- package/build/i18n/types.d.ts +1 -0
- package/build/i18n/types.d.ts.map +1 -1
- package/build/i18n/types.js.map +1 -1
- package/build/modules/camera/VisionCameraModule.d.ts.map +1 -1
- package/build/modules/camera/VisionCameraModule.js +24 -5
- package/build/modules/camera/VisionCameraModule.js.map +1 -1
- package/build/utils/pathToBase64.d.ts.map +1 -1
- package/build/utils/pathToBase64.js +8 -3
- package/build/utils/pathToBase64.js.map +1 -1
- package/package.json +1 -1
- package/src/components/KYCElements/IDCardCapture.tsx +2 -19
- package/src/components/KYCElements/VerificationProgressTemplate.tsx +1 -1
- package/src/components/TemplateKYCExample.tsx +0 -65
- package/src/hooks/useTemplateKYCFlow.tsx +7 -12
- package/src/i18n/en/index.ts +2 -1
- package/src/i18n/fr/index.ts +2 -1
- package/src/i18n/types.ts +1 -0
- package/src/modules/camera/VisionCameraModule.ts +26 -7
- package/src/utils/pathToBase64.ts +8 -3
|
@@ -8,9 +8,14 @@ export async function pathToBase64(uri) {
|
|
|
8
8
|
}
|
|
9
9
|
// Try Expo FileSystem if available (React Native + Expo)
|
|
10
10
|
try {
|
|
11
|
-
//
|
|
12
|
-
//
|
|
13
|
-
|
|
11
|
+
// Try legacy API first (Expo SDK 54+) to avoid deprecation warnings
|
|
12
|
+
// @ts-ignore - legacy export might not be in types
|
|
13
|
+
let FileSystem = require('expo-file-system/legacy');
|
|
14
|
+
if (!FileSystem?.readAsStringAsync) {
|
|
15
|
+
// Fall back to regular import for older versions
|
|
16
|
+
// eslint-disable-next-line @typescript-eslint/no-var-requires
|
|
17
|
+
FileSystem = require('expo-file-system');
|
|
18
|
+
}
|
|
14
19
|
if (FileSystem?.readAsStringAsync) {
|
|
15
20
|
const base64 = await FileSystem.readAsStringAsync(uri, { encoding: FileSystem.EncodingType.Base64 });
|
|
16
21
|
if (base64)
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"pathToBase64.js","sourceRoot":"","sources":["../../src/utils/pathToBase64.ts"],"names":[],"mappings":"AAAA,MAAM,CAAC,KAAK,UAAU,YAAY,CAAC,GAAW;IAC5C,IAAI,CAAC,GAAG;QAAE,MAAM,IAAI,KAAK,CAAC,+BAA+B,CAAC,CAAC;IAE3D,gDAAgD;IAChD,IAAI,GAAG,CAAC,UAAU,CAAC,OAAO,CAAC,EAAE,CAAC;QAC5B,MAAM,UAAU,GAAG,GAAG,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC;QACpC,OAAO,UAAU,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,SAAS,CAAC,UAAU,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC;IACjE,CAAC;IAED,yDAAyD;IACzD,IAAI,CAAC;QACH,
|
|
1
|
+
{"version":3,"file":"pathToBase64.js","sourceRoot":"","sources":["../../src/utils/pathToBase64.ts"],"names":[],"mappings":"AAAA,MAAM,CAAC,KAAK,UAAU,YAAY,CAAC,GAAW;IAC5C,IAAI,CAAC,GAAG;QAAE,MAAM,IAAI,KAAK,CAAC,+BAA+B,CAAC,CAAC;IAE3D,gDAAgD;IAChD,IAAI,GAAG,CAAC,UAAU,CAAC,OAAO,CAAC,EAAE,CAAC;QAC5B,MAAM,UAAU,GAAG,GAAG,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC;QACpC,OAAO,UAAU,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,SAAS,CAAC,UAAU,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC;IACjE,CAAC;IAED,yDAAyD;IACzD,IAAI,CAAC;QACH,oEAAoE;QACpE,mDAAmD;QACnD,IAAI,UAAU,GAAG,OAAO,CAAC,yBAAyB,CAAC,CAAC;QACpD,IAAI,CAAC,UAAU,EAAE,iBAAiB,EAAE,CAAC;YACnC,iDAAiD;YACjD,8DAA8D;YAC9D,UAAU,GAAG,OAAO,CAAC,kBAAkB,CAAC,CAAC;QAC3C,CAAC;QACD,IAAI,UAAU,EAAE,iBAAiB,EAAE,CAAC;YAClC,MAAM,MAAM,GAAG,MAAM,UAAU,CAAC,iBAAiB,CAAC,GAAG,EAAE,EAAE,QAAQ,EAAE,UAAU,CAAC,YAAY,CAAC,MAAM,EAAE,CAAC,CAAC;YACrG,IAAI,MAAM;gBAAE,OAAO,MAAM,CAAC;QAC5B,CAAC;IACH,CAAC;IAAC,OAAO,CAAC,EAAE,CAAC;QACX,yCAAyC;IAC3C,CAAC;IAED,yFAAyF;IACzF,IAAI,CAAC;QACH,MAAM,QAAQ,GAAG,MAAM,KAAK,CAAC,GAAG,CAAC,CAAC;QAClC,MAAM,IAAI,GAAG,MAAM,QAAQ,CAAC,IAAI,EAAE,CAAC;QACnC,MAAM,OAAO,GAAG,MAAM,IAAI,OAAO,CAAS,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE;YAC5D,MAAM,MAAM,GAAG,IAAI,UAAU,EAAE,CAAC;YAChC,MAAM,CAAC,SAAS,GAAG,GAAG,EAAE;gBACtB,IAAI,OAAO,MAAM,CAAC,MAAM,KAAK,QAAQ;oBAAE,OAAO,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;;oBACzD,MAAM,CAAC,IAAI,KAAK,CAAC,oCAAoC,CAAC,CAAC,CAAC;YAC/D,CAAC,CAAC;YACF,MAAM,CAAC,OAAO,GAAG,MAAM,CAAC;YACxB,MAAM,CAAC,aAAa,CAAC,IAAI,CAAC,CAAC;QAC7B,CAAC,CAAC,CAAC;QACH,MAAM,UAAU,GAAG,OAAO,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC;QACxC,OAAO,UAAU,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,SAAS,CAAC,UAAU,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC;IACzE,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,0BAA0B;IAC5B,CAAC;IAED,MAAM,IAAI,KAAK,CAAC,+CAA+C,CAAC,CAAC;AACnE,CAAC;AAED,eAAe,YAAY,CAAC","sourcesContent":["export async function pathToBase64(uri: string): Promise<string> {\n if (!uri) throw new Error('pathToBase64: uri is required');\n\n // If already a data URI, return the base64 part\n if (uri.startsWith('data:')) {\n const commaIndex = uri.indexOf(',');\n return commaIndex !== -1 ? uri.substring(commaIndex + 1) : uri;\n }\n\n // Try Expo FileSystem if available (React Native + Expo)\n try {\n // Try legacy API first (Expo SDK 54+) to avoid deprecation warnings\n // @ts-ignore - legacy export might not be in types\n let FileSystem = require('expo-file-system/legacy');\n if (!FileSystem?.readAsStringAsync) {\n // Fall back to regular import for older versions\n // eslint-disable-next-line @typescript-eslint/no-var-requires\n FileSystem = require('expo-file-system');\n }\n if (FileSystem?.readAsStringAsync) {\n const base64 = await FileSystem.readAsStringAsync(uri, { encoding: FileSystem.EncodingType.Base64 });\n if (base64) return base64;\n }\n } catch (_) {\n // ignore - fall back to other strategies\n }\n\n // Generic fetch + FileReader strategy (works on web; often works on RN for file:// URIs)\n try {\n const response = await fetch(uri);\n const blob = await response.blob();\n const dataUrl = await new Promise<string>((resolve, reject) => {\n const reader = new FileReader();\n reader.onloadend = () => {\n if (typeof reader.result === 'string') resolve(reader.result);\n else reject(new Error('Failed to convert blob to data URL'));\n };\n reader.onerror = reject;\n reader.readAsDataURL(blob);\n });\n const commaIndex = dataUrl.indexOf(',');\n return commaIndex !== -1 ? dataUrl.substring(commaIndex + 1) : dataUrl;\n } catch (err) {\n // continue to final error\n }\n\n throw new Error('pathToBase64: unable to convert uri to base64');\n}\n\nexport default pathToBase64;\n\n\n"]}
|
package/package.json
CHANGED
|
@@ -339,30 +339,13 @@ export const IDCardCapture: React.FC<IDCardCaptureProps> = ({
|
|
|
339
339
|
|
|
340
340
|
|
|
341
341
|
|
|
342
|
-
// const renderBboxOverlay = () => {
|
|
343
|
-
// const bbox: any = (silentCaptureResult as any)?.bbox;
|
|
344
|
-
// if (!bbox || !imageNaturalSize) return null;
|
|
345
|
-
// const containerWidth = Dimensions.get('window').width - 24 - 24; // approximate inner width accounting paddings/margins
|
|
346
|
-
// const containerHeight = 200;
|
|
347
|
-
// const scaleX = 1;
|
|
348
|
-
// const scaleY = 1;
|
|
349
|
-
// const left = Math.max(0, bbox.minX * scaleX);
|
|
350
|
-
// const top = Math.max(0, bbox.minY * scaleY);
|
|
351
|
-
// const width = Math.max(1, bbox.width * scaleX);
|
|
352
|
-
// const height = Math.max(1, bbox.height * scaleY);
|
|
353
|
-
// return (
|
|
354
|
-
// <View
|
|
355
|
-
// pointerEvents="none"
|
|
356
|
-
// style={{ position: 'absolute', left, top, width, height, borderColor: '#2DBD60', borderWidth: 2, borderStyle: 'solid', borderRadius: 6 }}
|
|
357
|
-
// />
|
|
358
|
-
// );
|
|
359
|
-
// };
|
|
360
|
-
|
|
361
342
|
|
|
362
343
|
|
|
363
344
|
|
|
364
345
|
const handleDocumentTypeSelection = (docType: GovernmentDocumentType) => {
|
|
365
346
|
setSelectedDocumentType({ type: docType, region: hasRegions(docType) ? '' : 'root' });
|
|
347
|
+
setSilentCaptureResult((prev) => ({ ...prev, templatePath: '', bbox: undefined, success: false, isAnalyzing: false, error: '', path: '', mrz: '', country: '', documentType: '' }));
|
|
348
|
+
setCapturedImages((prev) => ({ ...prev, front: { dir: '', file: '', mrz: '' }, back: { dir: '', file: '', mrz: '' } }));
|
|
366
349
|
};
|
|
367
350
|
const handleRegionSelection = (region: string) => {
|
|
368
351
|
setSelectedDocumentType((prev) => ({ ...prev, region: region }));
|
|
@@ -155,7 +155,7 @@ export const VerificationProgressTemplate: React.FC<VerificationProgressTemplate
|
|
|
155
155
|
<Text key={idx} style={styles.issueItem}>• {issue}</Text>
|
|
156
156
|
))}
|
|
157
157
|
</View>
|
|
158
|
-
<TouchableOpacity style={[styles.button, styles.primary]} onPress={() => actions.
|
|
158
|
+
<TouchableOpacity style={[styles.button, styles.primary]} onPress={() => actions.resetTemplate()}>
|
|
159
159
|
<Text style={styles.buttonText}>{t('kyc.verificationProgress.status.retry')}</Text>
|
|
160
160
|
</TouchableOpacity>
|
|
161
161
|
<TouchableOpacity style={[styles.button, styles.secondary]}>
|
|
@@ -260,68 +260,3 @@ const styles = StyleSheet.create({
|
|
|
260
260
|
flex: 1,
|
|
261
261
|
},
|
|
262
262
|
});
|
|
263
|
-
|
|
264
|
-
// Exemples de différents types de documents gouvernementaux supportés :
|
|
265
|
-
/*
|
|
266
|
-
export const documentTypeExamples = {
|
|
267
|
-
// Carte d'identité nationale
|
|
268
|
-
idCard: {
|
|
269
|
-
document_type: "id_card" as const,
|
|
270
|
-
labels: { en: "Upload your ID card", fr: "Téléversez votre carte d'identité" }
|
|
271
|
-
},
|
|
272
|
-
|
|
273
|
-
// Passeport
|
|
274
|
-
passport: {
|
|
275
|
-
document_type: "passport" as const,
|
|
276
|
-
labels: { en: "Upload your passport", fr: "Téléversez votre passeport" }
|
|
277
|
-
},
|
|
278
|
-
|
|
279
|
-
// Permis de conduire
|
|
280
|
-
driversLicense: {
|
|
281
|
-
document_type: "drivers_license" as const,
|
|
282
|
-
labels: { en: "Upload your driver's license", fr: "Téléversez votre permis de conduire" }
|
|
283
|
-
},
|
|
284
|
-
|
|
285
|
-
// Permis de séjour
|
|
286
|
-
residencePermit: {
|
|
287
|
-
document_type: "residence_permit" as const,
|
|
288
|
-
labels: { en: "Upload your residence permit", fr: "Téléversez votre permis de séjour" }
|
|
289
|
-
},
|
|
290
|
-
|
|
291
|
-
// Carte nationale d'identité
|
|
292
|
-
nationalId: {
|
|
293
|
-
document_type: "national_id" as const,
|
|
294
|
-
labels: { en: "Upload your national ID", fr: "Téléversez votre carte nationale d'identité" }
|
|
295
|
-
},
|
|
296
|
-
|
|
297
|
-
// Carte d'électeur
|
|
298
|
-
voterId: {
|
|
299
|
-
document_type: "voter_id" as const,
|
|
300
|
-
labels: { en: "Upload your voter ID", fr: "Téléversez votre carte d'électeur" }
|
|
301
|
-
},
|
|
302
|
-
|
|
303
|
-
// Carte militaire
|
|
304
|
-
militaryId: {
|
|
305
|
-
document_type: "military_id" as const,
|
|
306
|
-
labels: { en: "Upload your military ID", fr: "Téléversez votre carte militaire" }
|
|
307
|
-
},
|
|
308
|
-
|
|
309
|
-
// Carte d'étudiant
|
|
310
|
-
studentId: {
|
|
311
|
-
document_type: "student_id" as const,
|
|
312
|
-
labels: { en: "Upload your student ID", fr: "Téléversez votre carte d'étudiant" }
|
|
313
|
-
},
|
|
314
|
-
|
|
315
|
-
// Permis de travail
|
|
316
|
-
workPermit: {
|
|
317
|
-
document_type: "work_permit" as const,
|
|
318
|
-
labels: { en: "Upload your work permit", fr: "Téléversez votre permis de travail" }
|
|
319
|
-
},
|
|
320
|
-
|
|
321
|
-
// Autre document gouvernemental
|
|
322
|
-
other: {
|
|
323
|
-
document_type: "other" as const,
|
|
324
|
-
labels: { en: "Upload your government document", fr: "Téléversez votre document gouvernemental" }
|
|
325
|
-
}
|
|
326
|
-
};
|
|
327
|
-
*/
|
|
@@ -130,8 +130,8 @@ export const useTemplateKYCFlow = (
|
|
|
130
130
|
const templateWithReview = useMemo(() => ensureReviewSubmitStep(template), [template, ensureReviewSubmitStep]);
|
|
131
131
|
const templateWithReviewAndVerification = useMemo(() => ensureVerificationProgressStep(templateWithReview), [templateWithReview, ensureVerificationProgressStep]);
|
|
132
132
|
|
|
133
|
-
// État du flux
|
|
134
|
-
const
|
|
133
|
+
// État initial du flux
|
|
134
|
+
const buildInitialState = (): TemplateState => ({
|
|
135
135
|
template: templateWithReviewAndVerification,
|
|
136
136
|
currentComponentIndex: 0,
|
|
137
137
|
completedComponents: [],
|
|
@@ -151,6 +151,9 @@ export const useTemplateKYCFlow = (
|
|
|
151
151
|
status: 'idle',
|
|
152
152
|
},
|
|
153
153
|
});
|
|
154
|
+
|
|
155
|
+
// État du flux
|
|
156
|
+
const [state, setState] = useState<TemplateState>(() => buildInitialState());
|
|
154
157
|
const mapComponentTypeToAction = useCallback((type: TemplateComponent['type']): string | null => {
|
|
155
158
|
switch (type) {
|
|
156
159
|
case 'id_card':
|
|
@@ -594,16 +597,8 @@ export const useTemplateKYCFlow = (
|
|
|
594
597
|
|
|
595
598
|
// Réinitialiser le template
|
|
596
599
|
resetTemplate: useCallback(() => {
|
|
597
|
-
setState(
|
|
598
|
-
|
|
599
|
-
currentComponentIndex: 0,
|
|
600
|
-
completedComponents: [],
|
|
601
|
-
componentData: {},
|
|
602
|
-
errors: {},
|
|
603
|
-
isProcessing: false,
|
|
604
|
-
verification: { status: 'idle', result: undefined },
|
|
605
|
-
}));
|
|
606
|
-
}, []),
|
|
600
|
+
setState(buildInitialState());
|
|
601
|
+
}, [buildInitialState]),
|
|
607
602
|
|
|
608
603
|
// Changer la langue
|
|
609
604
|
setLanguage: useCallback((language: string) => {
|
package/src/i18n/en/index.ts
CHANGED
package/src/i18n/fr/index.ts
CHANGED
package/src/i18n/types.ts
CHANGED
|
@@ -2,6 +2,29 @@ import { Platform } from 'react-native';
|
|
|
2
2
|
import { Camera, CameraDevice, CameraPermissionStatus, PhotoFile } from 'react-native-vision-camera';
|
|
3
3
|
import * as FileSystem from "expo-file-system";
|
|
4
4
|
|
|
5
|
+
/**
|
|
6
|
+
* Backward-compatible file copy function
|
|
7
|
+
* Uses legacy API from expo-file-system/legacy if available (Expo SDK 54+)
|
|
8
|
+
* Falls back to regular copyAsync for older versions
|
|
9
|
+
*/
|
|
10
|
+
async function copyFileCompat(from: string, to: string): Promise<void> {
|
|
11
|
+
try {
|
|
12
|
+
// Try legacy API from expo-file-system/legacy (Expo SDK 54+)
|
|
13
|
+
// This avoids deprecation warnings while maintaining backward compatibility
|
|
14
|
+
// @ts-ignore - legacy export might not be in types
|
|
15
|
+
const LegacyFileSystem = require('expo-file-system/legacy');
|
|
16
|
+
if (LegacyFileSystem?.copyAsync) {
|
|
17
|
+
await LegacyFileSystem.copyAsync({ from, to });
|
|
18
|
+
return;
|
|
19
|
+
}
|
|
20
|
+
} catch (_) {
|
|
21
|
+
// Legacy export not available, fall through to regular import
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
// Fall back to regular copyAsync (for older Expo SDK versions < 54)
|
|
25
|
+
await FileSystem.copyAsync({ from, to });
|
|
26
|
+
}
|
|
27
|
+
|
|
5
28
|
export interface CameraCaptureResult {
|
|
6
29
|
success: boolean;
|
|
7
30
|
path?: string;
|
|
@@ -163,15 +186,11 @@ export class VisionCameraModule {
|
|
|
163
186
|
* Process photo capture result
|
|
164
187
|
*/
|
|
165
188
|
async processPhotoResult(photo: PhotoFile): Promise<CameraCaptureResult> {
|
|
189
|
+
try {
|
|
190
|
+
const newPath = FileSystem.documentDirectory + `photo_${Date.now()}.jpg`;
|
|
166
191
|
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
await FileSystem.copyAsync({
|
|
170
|
-
from: `file://${photo.path}`,
|
|
171
|
-
to: newPath,
|
|
172
|
-
});
|
|
192
|
+
await copyFileCompat(`file://${photo.path}`, newPath);
|
|
173
193
|
|
|
174
|
-
try {
|
|
175
194
|
return {
|
|
176
195
|
success: true,
|
|
177
196
|
path: newPath,
|
|
@@ -9,9 +9,14 @@ export async function pathToBase64(uri: string): Promise<string> {
|
|
|
9
9
|
|
|
10
10
|
// Try Expo FileSystem if available (React Native + Expo)
|
|
11
11
|
try {
|
|
12
|
-
//
|
|
13
|
-
//
|
|
14
|
-
|
|
12
|
+
// Try legacy API first (Expo SDK 54+) to avoid deprecation warnings
|
|
13
|
+
// @ts-ignore - legacy export might not be in types
|
|
14
|
+
let FileSystem = require('expo-file-system/legacy');
|
|
15
|
+
if (!FileSystem?.readAsStringAsync) {
|
|
16
|
+
// Fall back to regular import for older versions
|
|
17
|
+
// eslint-disable-next-line @typescript-eslint/no-var-requires
|
|
18
|
+
FileSystem = require('expo-file-system');
|
|
19
|
+
}
|
|
15
20
|
if (FileSystem?.readAsStringAsync) {
|
|
16
21
|
const base64 = await FileSystem.readAsStringAsync(uri, { encoding: FileSystem.EncodingType.Base64 });
|
|
17
22
|
if (base64) return base64;
|