react-native-kalapa-ekyc 1.1.3 → 1.2.1
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/README.md +540 -144
- package/android/.gradle/8.9/checksums/checksums.lock +0 -0
- package/android/.gradle/8.9/dependencies-accessors/gc.properties +0 -0
- package/android/.gradle/8.9/fileChanges/last-build.bin +0 -0
- package/android/.gradle/8.9/fileHashes/fileHashes.lock +0 -0
- package/android/.gradle/8.9/gc.properties +0 -0
- package/android/build.gradle +10 -8
- package/android/src/main/java/com/reactnativekalapaekyc/KalapaEkycModule.java +76 -60
- package/ios/KalapaEkyc.m +35 -14
- package/ios/KalapaEkyc.xcodeproj/project.xcworkspace/xcuserdata/iosdev.xcuserdatad/UserInterfaceState.xcuserstate +0 -0
- package/ios/KalapaEkyc.xcodeproj/project.xcworkspace/xcuserdata/leo.xcuserdatad/UserInterfaceState.xcuserstate +0 -0
- package/lib/commonjs/index.js +38 -0
- package/lib/commonjs/index.js.map +1 -0
- package/lib/module/index.js +32 -0
- package/lib/module/index.js.map +1 -0
- package/lib/typescript/index.d.ts +2 -0
- package/package.json +11 -12
- package/react-native-kalapa-ekyc.podspec +1 -0
- package/src/KalapaResult.ts +326 -0
- package/src/index.tsx +4 -1
|
@@ -0,0 +1,326 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* KalapaResult - Simplified and standardized result parser for NFC-only mode
|
|
3
|
+
* Handles both Android and iOS response formats
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
export interface SelfieData {
|
|
7
|
+
is_matched: boolean;
|
|
8
|
+
matching_score: number;
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
export interface NfcData {
|
|
12
|
+
// Personal Information
|
|
13
|
+
name: string;
|
|
14
|
+
id_number: string;
|
|
15
|
+
old_id_number: string;
|
|
16
|
+
date_of_birth: string;
|
|
17
|
+
date_of_expiry: string;
|
|
18
|
+
date_of_issuance: string;
|
|
19
|
+
gender: string;
|
|
20
|
+
nationality: string;
|
|
21
|
+
nation: string;
|
|
22
|
+
|
|
23
|
+
// Address Information
|
|
24
|
+
address: string;
|
|
25
|
+
hometown: string;
|
|
26
|
+
|
|
27
|
+
// Family Information
|
|
28
|
+
father_name: string;
|
|
29
|
+
mother_name: string;
|
|
30
|
+
spouse_name: string;
|
|
31
|
+
|
|
32
|
+
// Additional Information
|
|
33
|
+
religion: string;
|
|
34
|
+
personal_identification: string;
|
|
35
|
+
|
|
36
|
+
// Technical Data
|
|
37
|
+
face_image: string; // Base64 image from NFC chip
|
|
38
|
+
mrz: string;
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
export interface AddressEntities {
|
|
42
|
+
district: string;
|
|
43
|
+
ward: string;
|
|
44
|
+
province: string;
|
|
45
|
+
unknown: string;
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
export interface MrzDataFields {
|
|
49
|
+
birthday?: string;
|
|
50
|
+
doe?: string;
|
|
51
|
+
gender?: string;
|
|
52
|
+
id_number?: string;
|
|
53
|
+
name?: string;
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
export interface MrzDataError {
|
|
57
|
+
code: number;
|
|
58
|
+
message: string;
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
export interface MrzData {
|
|
62
|
+
data?: {
|
|
63
|
+
fields?: MrzDataFields;
|
|
64
|
+
raw_mrz?: string;
|
|
65
|
+
};
|
|
66
|
+
error?: MrzDataError;
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
export interface QrCodeData {
|
|
70
|
+
decoded_text?: string;
|
|
71
|
+
stage?: number;
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
export interface QrCode {
|
|
75
|
+
data?: QrCodeData;
|
|
76
|
+
error?: {
|
|
77
|
+
code: number;
|
|
78
|
+
message: string;
|
|
79
|
+
};
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
export type DecisionType = 'APPROVED' | 'MANUAL' | 'REJECTED' | 'UNKNOWN';
|
|
83
|
+
|
|
84
|
+
export class KalapaResult {
|
|
85
|
+
// Root level common fields
|
|
86
|
+
public birthday!: string;
|
|
87
|
+
public country!: string;
|
|
88
|
+
public decision!: DecisionType;
|
|
89
|
+
public doe!: string; // Date of expiry
|
|
90
|
+
public doi!: string; // Date of issuance
|
|
91
|
+
public ethnicity!: string;
|
|
92
|
+
public features!: string;
|
|
93
|
+
public gender!: string;
|
|
94
|
+
public home!: string;
|
|
95
|
+
public home_entities!: AddressEntities;
|
|
96
|
+
public id_number!: string;
|
|
97
|
+
public mrz_data!: MrzData | null;
|
|
98
|
+
public name!: string;
|
|
99
|
+
public national!: string;
|
|
100
|
+
public nfc_data!: NfcData;
|
|
101
|
+
public poi!: string;
|
|
102
|
+
public qr_code!: QrCode | null;
|
|
103
|
+
public religion!: string;
|
|
104
|
+
public resident!: string;
|
|
105
|
+
public resident_entities!: AddressEntities;
|
|
106
|
+
public selfie_data!: SelfieData;
|
|
107
|
+
public session!: string;
|
|
108
|
+
public type!: string;
|
|
109
|
+
public rawResult: any;
|
|
110
|
+
|
|
111
|
+
constructor(rawResult: any) {
|
|
112
|
+
this.rawResult = rawResult;
|
|
113
|
+
this._parseResult();
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
private _parseResult(): void {
|
|
117
|
+
// Handle both wrapped (kalapa_result) and unwrapped responses
|
|
118
|
+
const kalapaData = this.rawResult?.kalapa_result || this.rawResult || {};
|
|
119
|
+
|
|
120
|
+
// Parse root level common fields
|
|
121
|
+
this.birthday = kalapaData.birthday || '';
|
|
122
|
+
this.country = kalapaData.country || '';
|
|
123
|
+
this.decision = (kalapaData.decision || 'UNKNOWN') as DecisionType;
|
|
124
|
+
this.doe = kalapaData.doe || '';
|
|
125
|
+
this.doi = kalapaData.doi || '';
|
|
126
|
+
this.ethnicity = kalapaData.ethnicity || '';
|
|
127
|
+
this.features = kalapaData.features || '';
|
|
128
|
+
this.gender = kalapaData.gender || '';
|
|
129
|
+
this.home = kalapaData.home || '';
|
|
130
|
+
this.home_entities = {
|
|
131
|
+
district: kalapaData.home_entities?.district || '',
|
|
132
|
+
ward: kalapaData.home_entities?.ward || '',
|
|
133
|
+
province: kalapaData.home_entities?.province || '',
|
|
134
|
+
unknown: kalapaData.home_entities?.unknown || ''
|
|
135
|
+
};
|
|
136
|
+
// Handle both idNumber (Android) and id_number (iOS)
|
|
137
|
+
this.id_number = kalapaData.id_number || kalapaData.idNumber || '';
|
|
138
|
+
this.name = kalapaData.name || '';
|
|
139
|
+
this.national = kalapaData.national || '';
|
|
140
|
+
this.poi = kalapaData.poi || '';
|
|
141
|
+
this.religion = kalapaData.religion || '';
|
|
142
|
+
this.resident = kalapaData.resident || '';
|
|
143
|
+
this.resident_entities = {
|
|
144
|
+
district: kalapaData.resident_entities?.district || '',
|
|
145
|
+
ward: kalapaData.resident_entities?.ward || '',
|
|
146
|
+
province: kalapaData.resident_entities?.province || '',
|
|
147
|
+
unknown: kalapaData.resident_entities?.unknown || ''
|
|
148
|
+
};
|
|
149
|
+
this.session = kalapaData.session || '';
|
|
150
|
+
this.type = kalapaData.type || '';
|
|
151
|
+
|
|
152
|
+
// Parse MRZ data (available on both platforms)
|
|
153
|
+
const mrzRaw = kalapaData.mrz_data;
|
|
154
|
+
if (mrzRaw && typeof mrzRaw === 'object' && mrzRaw !== null) {
|
|
155
|
+
this.mrz_data = {
|
|
156
|
+
data: mrzRaw.data ? {
|
|
157
|
+
fields: mrzRaw.data.fields || {},
|
|
158
|
+
raw_mrz: mrzRaw.data.raw_mrz || ''
|
|
159
|
+
} : undefined,
|
|
160
|
+
error: mrzRaw.error ? {
|
|
161
|
+
code: mrzRaw.error.code || 0,
|
|
162
|
+
message: mrzRaw.error.message || ''
|
|
163
|
+
} : undefined
|
|
164
|
+
};
|
|
165
|
+
} else {
|
|
166
|
+
this.mrz_data = null;
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
// Parse QR code data (available on both platforms)
|
|
170
|
+
const qrRaw = kalapaData.qr_code;
|
|
171
|
+
if (qrRaw && typeof qrRaw === 'object' && qrRaw !== null) {
|
|
172
|
+
this.qr_code = {
|
|
173
|
+
data: qrRaw.data ? {
|
|
174
|
+
decoded_text: qrRaw.data.decoded_text || '',
|
|
175
|
+
stage: qrRaw.data.stage || undefined
|
|
176
|
+
} : undefined,
|
|
177
|
+
error: qrRaw.error ? {
|
|
178
|
+
code: qrRaw.error.code || 0,
|
|
179
|
+
message: qrRaw.error.message || ''
|
|
180
|
+
} : undefined
|
|
181
|
+
};
|
|
182
|
+
} else {
|
|
183
|
+
this.qr_code = null;
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
// Parse selfie data (identical structure on both platforms)
|
|
187
|
+
const selfieRaw = kalapaData.selfie_data || {};
|
|
188
|
+
this.selfie_data = {
|
|
189
|
+
is_matched: selfieRaw.is_matched || false,
|
|
190
|
+
matching_score: selfieRaw.matching_score || 0
|
|
191
|
+
};
|
|
192
|
+
|
|
193
|
+
// Parse NFC data (core fields available on both platforms)
|
|
194
|
+
const nfcRaw = kalapaData.nfc_data || {};
|
|
195
|
+
this.nfc_data = {
|
|
196
|
+
// Personal Information
|
|
197
|
+
name: nfcRaw.name || '',
|
|
198
|
+
id_number: nfcRaw.id_number || '',
|
|
199
|
+
old_id_number: nfcRaw.old_id_number || '',
|
|
200
|
+
date_of_birth: nfcRaw.date_of_birth || '',
|
|
201
|
+
date_of_expiry: nfcRaw.date_of_expiry || '',
|
|
202
|
+
date_of_issuance: nfcRaw.date_of_issuance || '',
|
|
203
|
+
gender: nfcRaw.gender || '',
|
|
204
|
+
nationality: nfcRaw.nationality || '',
|
|
205
|
+
nation: nfcRaw.nation || '',
|
|
206
|
+
|
|
207
|
+
// Address Information
|
|
208
|
+
address: nfcRaw.address || '',
|
|
209
|
+
hometown: nfcRaw.hometown || '',
|
|
210
|
+
|
|
211
|
+
// Family Information
|
|
212
|
+
father_name: nfcRaw.father_name || '',
|
|
213
|
+
mother_name: nfcRaw.mother_name || '',
|
|
214
|
+
spouse_name: nfcRaw.spouse_name || '',
|
|
215
|
+
|
|
216
|
+
// Additional Information
|
|
217
|
+
religion: nfcRaw.religion || '',
|
|
218
|
+
personal_identification: nfcRaw.personal_identification || '',
|
|
219
|
+
|
|
220
|
+
// Technical Data
|
|
221
|
+
face_image: nfcRaw.face_image || '', // Base64 image from NFC chip
|
|
222
|
+
mrz: nfcRaw.mrz || '',
|
|
223
|
+
};
|
|
224
|
+
}
|
|
225
|
+
|
|
226
|
+
// Convenience methods
|
|
227
|
+
public isApproved(): boolean {
|
|
228
|
+
return this.decision === 'APPROVED';
|
|
229
|
+
}
|
|
230
|
+
|
|
231
|
+
public isManualReview(): boolean {
|
|
232
|
+
return this.decision === 'MANUAL';
|
|
233
|
+
}
|
|
234
|
+
|
|
235
|
+
public isRejected(): boolean {
|
|
236
|
+
return this.decision === 'REJECTED';
|
|
237
|
+
}
|
|
238
|
+
|
|
239
|
+
public isFaceMatched(): boolean {
|
|
240
|
+
return this.selfie_data.is_matched === true;
|
|
241
|
+
}
|
|
242
|
+
|
|
243
|
+
public getFaceMatchingScore(): number {
|
|
244
|
+
return this.selfie_data.matching_score;
|
|
245
|
+
}
|
|
246
|
+
|
|
247
|
+
// Get formatted display name
|
|
248
|
+
public getDisplayName(): string {
|
|
249
|
+
return this.nfc_data.name || 'N/A';
|
|
250
|
+
}
|
|
251
|
+
|
|
252
|
+
// Get formatted ID number
|
|
253
|
+
public getIdNumber(): string {
|
|
254
|
+
return this.nfc_data.id_number || 'N/A';
|
|
255
|
+
}
|
|
256
|
+
|
|
257
|
+
// Get formatted date of birth
|
|
258
|
+
public getDateOfBirth(): string {
|
|
259
|
+
return this.nfc_data.date_of_birth || 'N/A';
|
|
260
|
+
}
|
|
261
|
+
|
|
262
|
+
// Get face image (Base64)
|
|
263
|
+
public getFaceImage(): string {
|
|
264
|
+
return this.nfc_data.face_image;
|
|
265
|
+
}
|
|
266
|
+
|
|
267
|
+
// Export essential data as plain object
|
|
268
|
+
public toJSON(): {
|
|
269
|
+
birthday: string;
|
|
270
|
+
country: string;
|
|
271
|
+
decision: DecisionType;
|
|
272
|
+
doe: string;
|
|
273
|
+
doi: string;
|
|
274
|
+
ethnicity: string;
|
|
275
|
+
features: string;
|
|
276
|
+
gender: string;
|
|
277
|
+
home: string;
|
|
278
|
+
home_entities: AddressEntities;
|
|
279
|
+
id_number: string;
|
|
280
|
+
mrz_data: MrzData | null;
|
|
281
|
+
name: string;
|
|
282
|
+
national: string;
|
|
283
|
+
nfc_data: NfcData;
|
|
284
|
+
poi: string;
|
|
285
|
+
qr_code: QrCode | null;
|
|
286
|
+
religion: string;
|
|
287
|
+
resident: string;
|
|
288
|
+
resident_entities: AddressEntities;
|
|
289
|
+
selfie_data: SelfieData;
|
|
290
|
+
session: string;
|
|
291
|
+
type: string;
|
|
292
|
+
} {
|
|
293
|
+
return {
|
|
294
|
+
birthday: this.birthday,
|
|
295
|
+
country: this.country,
|
|
296
|
+
decision: this.decision,
|
|
297
|
+
doe: this.doe,
|
|
298
|
+
doi: this.doi,
|
|
299
|
+
ethnicity: this.ethnicity,
|
|
300
|
+
features: this.features,
|
|
301
|
+
gender: this.gender,
|
|
302
|
+
home: this.home,
|
|
303
|
+
home_entities: this.home_entities,
|
|
304
|
+
id_number: this.id_number,
|
|
305
|
+
mrz_data: this.mrz_data,
|
|
306
|
+
name: this.name,
|
|
307
|
+
national: this.national,
|
|
308
|
+
nfc_data: this.nfc_data,
|
|
309
|
+
poi: this.poi,
|
|
310
|
+
qr_code: this.qr_code,
|
|
311
|
+
religion: this.religion,
|
|
312
|
+
resident: this.resident,
|
|
313
|
+
resident_entities: this.resident_entities,
|
|
314
|
+
selfie_data: this.selfie_data,
|
|
315
|
+
session: this.session,
|
|
316
|
+
type: this.type
|
|
317
|
+
};
|
|
318
|
+
}
|
|
319
|
+
|
|
320
|
+
// Static factory method to create from raw result
|
|
321
|
+
public static fromRawResult(rawResult: any): KalapaResult {
|
|
322
|
+
return new KalapaResult(rawResult);
|
|
323
|
+
}
|
|
324
|
+
}
|
|
325
|
+
|
|
326
|
+
export default KalapaResult;
|
package/src/index.tsx
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { NativeModules } from 'react-native';
|
|
2
|
+
import KalapaResult from './KalapaResult';
|
|
2
3
|
|
|
3
4
|
const { KalapaEkyc } = NativeModules;
|
|
4
5
|
|
|
@@ -23,7 +24,7 @@ interface KalapaResult {
|
|
|
23
24
|
// Parse the result
|
|
24
25
|
const parsedResult = JSON.parse(result.kalapa_result);
|
|
25
26
|
|
|
26
|
-
// Return enhanced result with
|
|
27
|
+
// Return enhanced result with parsed kalapa_result
|
|
27
28
|
return {
|
|
28
29
|
...result,
|
|
29
30
|
kalapa_result: parsedResult,
|
|
@@ -34,4 +35,6 @@ interface KalapaResult {
|
|
|
34
35
|
}
|
|
35
36
|
};
|
|
36
37
|
|
|
38
|
+
// Export both the main module and KalapaResult class
|
|
39
|
+
export { KalapaResult };
|
|
37
40
|
export default ExtendedKalapaEkyc;
|