@finspringinnovations/fdsdk 0.0.4 → 0.0.6
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/lib/api/baseApi.js +17 -6
- package/lib/api/masterDataApi.js +21 -1
- package/lib/api/workflowApi.js +46 -1
- package/lib/config/appDataConfig.d.ts +5 -0
- package/lib/hooks/usePaymentSSE.d.ts +7 -1
- package/lib/hooks/usePaymentSSE.js +287 -63
- package/lib/navigation/RootNavigator.js +10 -2
- package/lib/screens/AadhaarVerification.js +2 -2
- package/lib/screens/FDCalculator.js +6 -2
- package/lib/screens/FDList.js +37 -64
- package/lib/screens/Payment.js +159 -27
- package/lib/screens/PaymentStatus.js +139 -25
- package/lib/screens/ReviewKYC.js +45 -97
- package/lib/utils/sseParser.js +19 -3
- package/package.json +1 -1
- package/src/api/baseApi.ts +19 -6
- package/src/api/masterDataApi.ts +21 -3
- package/src/api/workflowApi.ts +50 -1
- package/src/config/appDataConfig.ts +5 -0
- package/src/hooks/usePaymentSSE.ts +307 -66
- package/src/navigation/RootNavigator.tsx +8 -2
- package/src/screens/AadhaarVerification.tsx +2 -2
- package/src/screens/FDCalculator.tsx +7 -2
- package/src/screens/FDList.tsx +37 -76
- package/src/screens/Payment.tsx +181 -38
- package/src/screens/PaymentStatus.tsx +158 -43
- package/src/screens/ReviewKYC.tsx +94 -170
- package/src/utils/sseParser.ts +20 -4
package/lib/screens/ReviewKYC.js
CHANGED
|
@@ -162,7 +162,6 @@ const ReviewKYC = ({ onGoBack, onContinue, initialData, }) => {
|
|
|
162
162
|
const [fieldErrors, setFieldErrors] = (0, react_1.useState)({});
|
|
163
163
|
// State to track marital status dropdown visibility
|
|
164
164
|
const [showMaritalStatusMenu, setShowMaritalStatusMenu] = (0, react_1.useState)(false);
|
|
165
|
-
const [isGoingBack, setIsGoingBack] = (0, react_1.useState)(false);
|
|
166
165
|
// Ref to track currently focused text input
|
|
167
166
|
const focusedTextInputRef = (0, react_1.useRef)(null);
|
|
168
167
|
// Refs for each text field
|
|
@@ -229,23 +228,12 @@ const ReviewKYC = ({ onGoBack, onContinue, initialData, }) => {
|
|
|
229
228
|
// Validate individual field and set error
|
|
230
229
|
const validateField = (field, value) => {
|
|
231
230
|
if (!value || value.trim().length === 0) {
|
|
232
|
-
// Use "District" for area field
|
|
233
|
-
if (field === 'area') {
|
|
234
|
-
return 'District is required';
|
|
235
|
-
}
|
|
236
231
|
return `${field.charAt(0).toUpperCase() + field.slice(1)} is required`;
|
|
237
232
|
}
|
|
238
233
|
// Minimum 2 characters validation for text fields (excluding PAN, pincode, dateOfBirth, maritalStatus)
|
|
239
234
|
const textFields = ['area', 'city', 'addressLine1', 'addressLine2', 'state', 'country'];
|
|
240
235
|
if (textFields.includes(field)) {
|
|
241
236
|
if (value.trim().length < 2) {
|
|
242
|
-
// Use "Address" for addressLine1 and addressLine2
|
|
243
|
-
if (field === 'addressLine1' || field === 'addressLine2') {
|
|
244
|
-
return 'Address must be at least 2 characters';
|
|
245
|
-
}
|
|
246
|
-
else if (field === 'area') {
|
|
247
|
-
return 'District must be at least 2 characters';
|
|
248
|
-
}
|
|
249
237
|
return `${field.charAt(0).toUpperCase() + field.slice(1)} must be at least 2 characters`;
|
|
250
238
|
}
|
|
251
239
|
}
|
|
@@ -271,7 +259,7 @@ const ReviewKYC = ({ onGoBack, onContinue, initialData, }) => {
|
|
|
271
259
|
if (!error)
|
|
272
260
|
return null;
|
|
273
261
|
return (react_1.default.createElement(react_native_1.View, { style: styles.errorContainer },
|
|
274
|
-
|
|
262
|
+
react_1.default.createElement(Ionicons_1.default, { name: "warning", size: 16, color: colors.error || '#FF0000', style: styles.errorIcon }),
|
|
275
263
|
react_1.default.createElement(react_native_1.Text, { style: styles.errorText }, error)));
|
|
276
264
|
};
|
|
277
265
|
// Enhanced field validation functions
|
|
@@ -446,6 +434,7 @@ const ReviewKYC = ({ onGoBack, onContinue, initialData, }) => {
|
|
|
446
434
|
return;
|
|
447
435
|
}
|
|
448
436
|
const data = (0, globalData_1.getGlobalData)();
|
|
437
|
+
console.log('panRapidNumber global data check', data, panRapidNumber);
|
|
449
438
|
// Decide next screen based on panrapidnumber existence
|
|
450
439
|
if (panRapidNumber && data.completeFDData) {
|
|
451
440
|
(0, helpers_1.navigate)('PayNow', { fdData: fdDataFromRoute });
|
|
@@ -466,12 +455,7 @@ const ReviewKYC = ({ onGoBack, onContinue, initialData, }) => {
|
|
|
466
455
|
}
|
|
467
456
|
};
|
|
468
457
|
const renderInputField = (label, value, field, placeholder, editable = true, variant = 'text', maxLength, textInputRef) => (react_1.default.createElement(react_native_1.View, null,
|
|
469
|
-
react_1.default.createElement(TextFieldWithLabel_1.default, { label: label, value: value, onChangeText: (text) => updateField(field, text), placeholder: placeholder, editable: editable, variant: variant, maxLength: maxLength, keyboardType: variant === 'numeric' ? 'numeric' : variant === 'email' ? 'email-address' : 'default', autoCapitalize: variant === 'email' ? 'none' : 'words', onFocus: () => textInputRef && handleFieldFocus(textInputRef), textInputRef: textInputRef
|
|
470
|
-
if (textInputRef === null || textInputRef === void 0 ? void 0 : textInputRef.current) {
|
|
471
|
-
textInputRef.current.blur();
|
|
472
|
-
}
|
|
473
|
-
react_native_1.Keyboard.dismiss();
|
|
474
|
-
} }),
|
|
458
|
+
react_1.default.createElement(TextFieldWithLabel_1.default, { label: label, value: value, onChangeText: (text) => updateField(field, text), placeholder: placeholder, editable: editable, variant: variant, maxLength: maxLength, keyboardType: variant === 'numeric' ? 'numeric' : variant === 'email' ? 'email-address' : 'default', autoCapitalize: variant === 'email' ? 'none' : 'words', onFocus: () => textInputRef && handleFieldFocus(textInputRef), textInputRef: textInputRef }),
|
|
475
459
|
renderFieldError(field)));
|
|
476
460
|
const renderMaritalStatusDropdown = () => {
|
|
477
461
|
return (react_1.default.createElement(react_native_1.View, null,
|
|
@@ -493,93 +477,59 @@ const ReviewKYC = ({ onGoBack, onContinue, initialData, }) => {
|
|
|
493
477
|
const renderDateField = (label, value, field, editable = true, textInputRef) => (react_1.default.createElement(react_native_1.View, null,
|
|
494
478
|
react_1.default.createElement(TextFieldWithLabel_1.default, { label: label, value: value, onChangeText: (text) => updateField(field, text), variant: "date", placeholder: "DD/MM/YYYY", maxLength: 10, dateFormat: "DD/MM/YYYY", editable: editable, onFocus: () => textInputRef && handleFieldFocus(textInputRef), textInputRef: textInputRef, onDatePress: () => {
|
|
495
479
|
// TODO: Implement date picker if needed
|
|
496
|
-
}, returnKeyType: "done", onSubmitEditing: () => {
|
|
497
|
-
if (textInputRef === null || textInputRef === void 0 ? void 0 : textInputRef.current) {
|
|
498
|
-
textInputRef.current.blur();
|
|
499
|
-
}
|
|
500
|
-
react_native_1.Keyboard.dismiss();
|
|
501
480
|
} }),
|
|
502
481
|
renderFieldError(field)));
|
|
503
|
-
|
|
504
|
-
|
|
505
|
-
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
|
|
515
|
-
|
|
516
|
-
|
|
517
|
-
|
|
518
|
-
|
|
519
|
-
|
|
520
|
-
|
|
521
|
-
|
|
522
|
-
|
|
523
|
-
}
|
|
524
|
-
|
|
525
|
-
|
|
526
|
-
(0, react_1.useEffect)(() => {
|
|
527
|
-
if (react_native_1.Platform.OS !== 'android')
|
|
528
|
-
return;
|
|
529
|
-
const onHardwareBackPress = () => {
|
|
530
|
-
handleBackPress();
|
|
531
|
-
return true; // Prevent default behavior
|
|
532
|
-
};
|
|
533
|
-
const backHandler = react_native_1.BackHandler.addEventListener('hardwareBackPress', onHardwareBackPress);
|
|
534
|
-
return () => backHandler.remove();
|
|
535
|
-
}, [defaultProviderId, workflowInstanceId, applicationId, entityId]);
|
|
536
|
-
return (react_1.default.createElement(SafeAreaWrapper_1.default, { includeTop: false, bottomPadding: 25, statusBarColor: "#000000", statusBarStyle: "light-content" },
|
|
537
|
-
react_1.default.createElement(components_1.Header, { title: "Review KYC", onBackPress: handleBackPress, backgroundColor: colors.primary }),
|
|
538
|
-
react_1.default.createElement(react_native_1.KeyboardAvoidingView, { behavior: react_native_1.Platform.OS === 'ios' ? 'padding' : undefined, style: styles.keyboardAvoidingView, keyboardVerticalOffset: react_native_1.Platform.OS === 'ios' ? 0 : 0 },
|
|
539
|
-
react_1.default.createElement(react_native_1.ScrollView, { style: styles.container, showsVerticalScrollIndicator: false, scrollEnabled: !isLoadingPanRapid, keyboardShouldPersistTaps: "handled", contentContainerStyle: styles.scrollContent },
|
|
540
|
-
react_1.default.createElement(react_native_1.TouchableWithoutFeedback, { onPress: isLoadingPanRapid ? undefined : closeDropdown },
|
|
482
|
+
return (react_1.default.createElement(SafeAreaWrapper_1.default, { includeTop: false, bottomPadding: 25, statusBarColor: "#f8f9fa", statusBarStyle: "dark-content" },
|
|
483
|
+
react_1.default.createElement(components_1.Header, { title: "Review KYC", onBackPress: async () => {
|
|
484
|
+
try {
|
|
485
|
+
const userInfo = (0, appDataConfig_1.getUserInfoForAPI)();
|
|
486
|
+
await previousState({
|
|
487
|
+
providerId: defaultProviderId,
|
|
488
|
+
workflowInstanceId,
|
|
489
|
+
userreferenceid: userInfo.userReferenceId,
|
|
490
|
+
applicationid: applicationId,
|
|
491
|
+
entityid: entityId,
|
|
492
|
+
});
|
|
493
|
+
}
|
|
494
|
+
catch (e) {
|
|
495
|
+
// Handle error silently
|
|
496
|
+
}
|
|
497
|
+
finally {
|
|
498
|
+
//onGoBack?.();
|
|
499
|
+
(0, helpers_1.navigate)('FDCalculator');
|
|
500
|
+
}
|
|
501
|
+
}, backgroundColor: colors.primary }),
|
|
502
|
+
react_1.default.createElement(react_native_1.ScrollView, { style: styles.container, showsVerticalScrollIndicator: false, scrollEnabled: !isLoadingPanRapid },
|
|
503
|
+
react_1.default.createElement(react_native_1.TouchableWithoutFeedback, { onPress: isLoadingPanRapid ? undefined : closeDropdown },
|
|
504
|
+
react_1.default.createElement(react_native_1.View, null,
|
|
541
505
|
react_1.default.createElement(react_native_1.View, null,
|
|
542
|
-
react_1.default.createElement(
|
|
543
|
-
|
|
544
|
-
|
|
545
|
-
|
|
546
|
-
|
|
547
|
-
|
|
548
|
-
|
|
549
|
-
|
|
550
|
-
|
|
551
|
-
|
|
552
|
-
|
|
553
|
-
|
|
554
|
-
|
|
555
|
-
|
|
556
|
-
|
|
557
|
-
|
|
558
|
-
|
|
559
|
-
react_1.default.createElement(react_native_1.
|
|
560
|
-
react_1.default.createElement(react_native_1.TouchableOpacity, { style: styles.checkbox, onPress: () => updateField('useExistingAddress', !kycData.useExistingAddress) },
|
|
561
|
-
react_1.default.createElement(react_native_1.View, { style: [
|
|
562
|
-
styles.checkboxBox,
|
|
563
|
-
kycData.useExistingAddress && styles.checkboxChecked
|
|
564
|
-
] }, kycData.useExistingAddress ? (react_1.default.createElement(react_native_1.Image, { source: { uri: (themeName === 'dark') ? base64Images_1.base64Images.checkBoxDark : base64Images_1.base64Images.filledCheckBox }, resizeMode: "cover", width: 20, height: 20 })) : ((themeName === 'dark') ? (react_1.default.createElement(react_native_1.Image, { source: { uri: base64Images_1.base64Images.unCheckBoxDark }, resizeMode: "cover", width: 20, height: 20 })) : null))),
|
|
565
|
-
react_1.default.createElement(react_native_1.Text, { style: styles.checkboxText }, "For existing customers, we'll use the address from our records. For new customers, the address from your Aadhar card will be used. To update, please raise a service request with valid address proof.")))))),
|
|
506
|
+
react_1.default.createElement(TextFieldWithLabel_1.default, { label: "Pan Card", value: kycData.panCard, onChangeText: (text) => updateField('panCard', text), placeholder: "Enter PAN Card", editable: false, variant: "text", maxLength: 10, keyboardType: "default", autoCapitalize: "characters", onFocus: () => handleFieldFocus(panCardRef), textInputRef: panCardRef }),
|
|
507
|
+
renderFieldError('panCard')),
|
|
508
|
+
renderDateField('Date of Birth', kycData.dateOfBirth, 'dateOfBirth', false, dateOfBirthRef),
|
|
509
|
+
renderMaritalStatusDropdown(),
|
|
510
|
+
renderInputField('Area', kycData.area, 'area', 'Enter Area', true, 'text', 50, areaRef),
|
|
511
|
+
renderInputField('City', kycData.city, 'city', 'Enter City', true, 'text', 30, cityRef),
|
|
512
|
+
renderInputField('Address line 1', kycData.addressLine1, 'addressLine1', 'Enter Address Line 1', true, 'text', 100, addressLine1Ref),
|
|
513
|
+
renderInputField('Address line 2', kycData.addressLine2, 'addressLine2', 'Enter Address Line 2', true, 'text', 100, addressLine2Ref),
|
|
514
|
+
renderInputField('Pincode', kycData.pincode, 'pincode', 'Enter Pincode', true, 'numeric', 6, pincodeRef),
|
|
515
|
+
renderInputField('State', kycData.state, 'state', 'Enter State', true, 'text', undefined, stateRef),
|
|
516
|
+
renderInputField('Country', kycData.country, 'country', 'Enter Country', true, 'text', undefined, countryRef),
|
|
517
|
+
react_1.default.createElement(react_native_1.View, { style: styles.checkboxContainer },
|
|
518
|
+
react_1.default.createElement(react_native_1.TouchableOpacity, { style: styles.checkbox, onPress: () => updateField('useExistingAddress', !kycData.useExistingAddress) },
|
|
519
|
+
react_1.default.createElement(react_native_1.View, { style: [
|
|
520
|
+
styles.checkboxBox,
|
|
521
|
+
kycData.useExistingAddress && styles.checkboxChecked
|
|
522
|
+
] }, kycData.useExistingAddress ? (react_1.default.createElement(react_native_1.Image, { source: { uri: (themeName === 'dark') ? base64Images_1.base64Images.checkBoxDark : base64Images_1.base64Images.filledCheckBox }, resizeMode: "cover", width: 20, height: 20 })) : ((themeName === 'dark') ? (react_1.default.createElement(react_native_1.Image, { source: { uri: base64Images_1.base64Images.unCheckBoxDark }, resizeMode: "cover", width: 20, height: 20 })) : null))),
|
|
523
|
+
react_1.default.createElement(react_native_1.Text, { style: styles.checkboxText }, "For existing customers, we'll use the address from our records. For new customers, the address from your Aadhar card will be used. To update, please raise a service request with valid address proof."))))),
|
|
566
524
|
react_1.default.createElement(ActionButton_1.default, { title: "Continue", onPress: handleContinue, disabled: !kycData.useExistingAddress || isLoadingPanRapid || !validateForm(), loading: isLoadingPanRapid }),
|
|
567
|
-
isLoadingPanRapid && (react_1.default.createElement(react_native_1.View, { style: styles.loadingOverlay, pointerEvents: "auto" }))
|
|
568
|
-
isGoingBack && (react_1.default.createElement(react_native_1.View, { style: styles.loadingOverlay, pointerEvents: "auto" },
|
|
569
|
-
react_1.default.createElement(react_native_1.ActivityIndicator, { size: "large", color: colors.primary })))));
|
|
525
|
+
isLoadingPanRapid && (react_1.default.createElement(react_native_1.View, { style: styles.loadingOverlay, pointerEvents: "auto" }))));
|
|
570
526
|
};
|
|
571
527
|
const createStyles = (colors, typography, themeName) => react_native_1.StyleSheet.create({
|
|
572
|
-
keyboardAvoidingView: {
|
|
573
|
-
flex: 1,
|
|
574
|
-
},
|
|
575
528
|
container: {
|
|
576
529
|
flex: 1,
|
|
577
530
|
paddingHorizontal: 16,
|
|
578
531
|
paddingTop: 20,
|
|
579
532
|
},
|
|
580
|
-
scrollContent: {
|
|
581
|
-
flexGrow: 1,
|
|
582
|
-
},
|
|
583
533
|
checkboxContainer: {
|
|
584
534
|
flexDirection: 'row',
|
|
585
535
|
alignItems: 'flex-start',
|
|
@@ -652,8 +602,6 @@ const createStyles = (colors, typography, themeName) => react_native_1.StyleShee
|
|
|
652
602
|
right: 0,
|
|
653
603
|
bottom: 0,
|
|
654
604
|
backgroundColor: 'rgba(0, 0, 0, 0.3)',
|
|
655
|
-
justifyContent: 'center',
|
|
656
|
-
alignItems: 'center',
|
|
657
605
|
zIndex: 1000,
|
|
658
606
|
},
|
|
659
607
|
});
|
package/lib/utils/sseParser.js
CHANGED
|
@@ -4,10 +4,26 @@ exports.parseSSEBuffer = parseSSEBuffer;
|
|
|
4
4
|
function parseSSEBuffer(buffer, chunk) {
|
|
5
5
|
const results = [];
|
|
6
6
|
buffer.value += chunk;
|
|
7
|
-
let idx;
|
|
8
|
-
|
|
7
|
+
let idx = -1;
|
|
8
|
+
let delimiterLength = 0;
|
|
9
|
+
const findDelimiter = () => {
|
|
10
|
+
const unixIdx = buffer.value.indexOf('\n\n');
|
|
11
|
+
const windowsIdx = buffer.value.indexOf('\r\n\r\n');
|
|
12
|
+
if (windowsIdx >= 0 && (unixIdx < 0 || windowsIdx < unixIdx)) {
|
|
13
|
+
idx = windowsIdx;
|
|
14
|
+
delimiterLength = 4;
|
|
15
|
+
return true;
|
|
16
|
+
}
|
|
17
|
+
if (unixIdx >= 0) {
|
|
18
|
+
idx = unixIdx;
|
|
19
|
+
delimiterLength = 2;
|
|
20
|
+
return true;
|
|
21
|
+
}
|
|
22
|
+
return false;
|
|
23
|
+
};
|
|
24
|
+
while (findDelimiter()) {
|
|
9
25
|
const block = buffer.value.slice(0, idx);
|
|
10
|
-
buffer.value = buffer.value.slice(idx +
|
|
26
|
+
buffer.value = buffer.value.slice(idx + delimiterLength);
|
|
11
27
|
let eventType = 'message';
|
|
12
28
|
const dataparts = [];
|
|
13
29
|
for (const line of block.split(/\r?\n/)) {
|
package/package.json
CHANGED
package/src/api/baseApi.ts
CHANGED
|
@@ -339,6 +339,11 @@ const baseQueryWithEncryption: BaseQueryFn<
|
|
|
339
339
|
baseUrl: apiConfig.baseUrl,
|
|
340
340
|
timeout: apiConfig.timeout,
|
|
341
341
|
prepareHeaders: (headers, { getState }) => {
|
|
342
|
+
// Disable HTTP-level caching for all SDK API calls
|
|
343
|
+
headers.set('Cache-Control', 'no-cache, no-store, must-revalidate');
|
|
344
|
+
headers.set('Pragma', 'no-cache');
|
|
345
|
+
headers.set('Expires', '0');
|
|
346
|
+
|
|
342
347
|
const token = (getState() as any)?.auth?.token;
|
|
343
348
|
if (token) headers.set('authorization', `Bearer ${token}`);
|
|
344
349
|
|
|
@@ -439,9 +444,14 @@ const baseQueryWithEncryption: BaseQueryFn<
|
|
|
439
444
|
// Log response
|
|
440
445
|
const duration = Date.now() - timestamp;
|
|
441
446
|
|
|
447
|
+
const statusFromMeta = result.meta?.response?.status;
|
|
448
|
+
const statusFromError = typeof result.error?.status === 'number' ? result.error.status : undefined;
|
|
449
|
+
const status = statusFromMeta ?? statusFromError ?? (result.error ? 0 : 200);
|
|
450
|
+
const statusText = result.meta?.response?.statusText || (result.error ? 'ERROR' : 'OK');
|
|
451
|
+
|
|
442
452
|
const responseLogData: ResponseLogData = {
|
|
443
|
-
status
|
|
444
|
-
statusText
|
|
453
|
+
status,
|
|
454
|
+
statusText,
|
|
445
455
|
headers: {},
|
|
446
456
|
data: result.data,
|
|
447
457
|
timestamp: Date.now(),
|
|
@@ -454,8 +464,7 @@ const baseQueryWithEncryption: BaseQueryFn<
|
|
|
454
464
|
|
|
455
465
|
// Log response details in DEV mode (AFTER decryption)
|
|
456
466
|
if (__DEV__) {
|
|
457
|
-
const
|
|
458
|
-
const isSuccess = status >= 200 && status < 300;
|
|
467
|
+
const isSuccess = !result.error && status >= 200 && status < 300;
|
|
459
468
|
|
|
460
469
|
console.log('═══════════════════════════════════════════════════════════════');
|
|
461
470
|
console.log(isSuccess ? '✅ [ShriramSDK] API RESPONSE - SUCCESS' : '❌ [ShriramSDK] API RESPONSE - ERROR');
|
|
@@ -464,7 +473,7 @@ const baseQueryWithEncryption: BaseQueryFn<
|
|
|
464
473
|
console.log('🔗 Endpoint:', url);
|
|
465
474
|
console.log('📌 Full URL:', `${apiConfig.baseUrl}${url}`);
|
|
466
475
|
console.log('🔧 Method:', method);
|
|
467
|
-
console.log('📊 Status:', status,
|
|
476
|
+
console.log('📊 Status:', status, statusText);
|
|
468
477
|
console.log('⏱️ Duration:', `${duration}ms`);
|
|
469
478
|
console.log('🔐 Encryption:', currentEncryptionState ? 'Enabled' : 'Disabled');
|
|
470
479
|
console.log('🆔 Request ID:', requestId);
|
|
@@ -507,7 +516,11 @@ export const baseApi = createApi({
|
|
|
507
516
|
baseQuery: baseQueryWithEncryption,
|
|
508
517
|
tagTypes: ['InterestRate'],
|
|
509
518
|
endpoints: () => ({}),
|
|
519
|
+
keepUnusedDataFor: 0,
|
|
520
|
+
refetchOnMountOrArgChange: true,
|
|
521
|
+
refetchOnFocus: true,
|
|
522
|
+
refetchOnReconnect: true,
|
|
510
523
|
});
|
|
511
524
|
|
|
512
525
|
// Export hooks
|
|
513
|
-
export const { usePrefetch } = baseApi;
|
|
526
|
+
export const { usePrefetch } = baseApi;
|
package/src/api/masterDataApi.ts
CHANGED
|
@@ -12,17 +12,35 @@ export const masterDataApi = baseApi.injectEndpoints({
|
|
|
12
12
|
const request = {
|
|
13
13
|
url: 'masterdata',
|
|
14
14
|
method: 'GET' as const,
|
|
15
|
+
cache: 'no-store' as const,
|
|
15
16
|
headers: {
|
|
16
17
|
workflowInstanceId: '{{workflowInstanceId}}',
|
|
17
18
|
'x-api-key': '{{X-API-KEY}}',
|
|
18
19
|
encryptdecrypt: 'false',
|
|
20
|
+
'Cache-Control': 'no-cache, no-store, must-revalidate',
|
|
21
|
+
Pragma: 'no-cache',
|
|
22
|
+
Expires: '0',
|
|
19
23
|
provider: providerId || '{{shriramprovider}}',
|
|
20
24
|
},
|
|
21
25
|
};
|
|
22
26
|
return request;
|
|
23
27
|
},
|
|
24
|
-
transformResponse: (response) => {
|
|
25
|
-
return response;
|
|
28
|
+
transformResponse: (response: any) => {
|
|
29
|
+
if (response == null) return response;
|
|
30
|
+
// If API returns a JSON string, parse it
|
|
31
|
+
let data = response;
|
|
32
|
+
if (typeof response === 'string') {
|
|
33
|
+
try {
|
|
34
|
+
data = JSON.parse(response);
|
|
35
|
+
} catch {
|
|
36
|
+
return response;
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
// Unwrap { data: ... } so consumers get a consistent shape
|
|
40
|
+
if (typeof data === 'object' && data !== null && 'data' in data && Object.keys(data).length === 1) {
|
|
41
|
+
return data.data;
|
|
42
|
+
}
|
|
43
|
+
return data;
|
|
26
44
|
},
|
|
27
45
|
}),
|
|
28
46
|
}),
|
|
@@ -31,4 +49,4 @@ export const masterDataApi = baseApi.injectEndpoints({
|
|
|
31
49
|
|
|
32
50
|
export const {
|
|
33
51
|
useGetMasterDataQuery
|
|
34
|
-
} = masterDataApi;
|
|
52
|
+
} = masterDataApi;
|
package/src/api/workflowApi.ts
CHANGED
|
@@ -9,6 +9,38 @@ export interface TerminateWorkflowRequest {
|
|
|
9
9
|
|
|
10
10
|
export type TerminateWorkflowResponse = any; // Replace with concrete type when available
|
|
11
11
|
|
|
12
|
+
const TASK_ID_TO_CAPTION: Record<string, string> = {
|
|
13
|
+
'11042': 'SHRIRAM_V1_S1_T1_START',
|
|
14
|
+
'11043': 'SHRIRAM_V1_S1_T2_GET_PERSONAL_DETAILS_AND_BASIC_FD_INFO',
|
|
15
|
+
'11044': 'SHRIRAM_V1_S1_T3_END',
|
|
16
|
+
'11050': 'SHRIRAM_V1_S2_T1_KYC_START',
|
|
17
|
+
'11051': 'SHRIRAM_V1_S2_T2_CHECK_FOR_PAN_RAPID_STATUS',
|
|
18
|
+
'11052': 'SHRIRAM_V1_S2_T3_CHECK_IF_AADHAAR_ALREADY_VERIFIED',
|
|
19
|
+
'11045': 'SHRIRAM_V1_S2_T4_SEND_AADHAR_OTP',
|
|
20
|
+
'11046': 'SHRIRAM_V1_S2_T5_CHECK_FOR_OTP',
|
|
21
|
+
'11047': 'SHRIRAM_V1_S2_T6_VALIDATE_AADHAR_OTP',
|
|
22
|
+
'11053': 'SHRIRAM_V1_S2_T7_AADHAAR_VERIFIED',
|
|
23
|
+
'11049': 'SHRIRAM_V1_S2_T8_TERMINATE_TASK_AND_WORKFLOW_AFTER_KYC_RETRIES',
|
|
24
|
+
'11048': 'SHRIRAM_V1_S2_T9_KYC_END',
|
|
25
|
+
'11054': 'SHRIRAM_V1_S3_T1_OCCUPATION_START',
|
|
26
|
+
'11055': 'SHRIRAM_V1_S3_T2_CAPTURE_OCCUPATION_DETAILS',
|
|
27
|
+
'11056': 'SHRIRAM_V1_S3_T3_OCCUPATION_END',
|
|
28
|
+
'11057': 'SHRIRAM_V1_S4_T1_NOMINEE_START',
|
|
29
|
+
'11058': 'SHRIRAM_V1_S4_T2_CAPTURE_NOMINEE_DETAILS',
|
|
30
|
+
'11059': 'SHRIRAM_V1_S4_T3_NOMINEE_END',
|
|
31
|
+
'11060': 'SHRIRAM_V1_S5_T1_BANK_DETAILS_START',
|
|
32
|
+
'11061': 'SHRIRAM_V1_S5_T2_CAPTURE_BANK_DETAILS',
|
|
33
|
+
'11062': 'SHRIRAM_V1_S5_T3_BANK_DETAILS_END',
|
|
34
|
+
'11063': 'SHRIRAM_V1_S6_T1_FD_CREATION_START',
|
|
35
|
+
'11064': 'SHRIRAM_V1_S6_T2_CREATE_FD',
|
|
36
|
+
'11065': 'SHRIRAM_V1_S6_T3_FD_CREATION_END',
|
|
37
|
+
'11069': 'SHRIRAM_V1_S7_T1_PAYMENT_START',
|
|
38
|
+
'11068': 'SHRIRAM_V1_S7_T2_PAYMENT',
|
|
39
|
+
'11067': 'SHRIRAM_V1_S7_T3_CHECK_FOR_PAYMENT_STATUS',
|
|
40
|
+
'11070': 'SHRIRAM_V1_S7_T4_TERMINATE_TASK_AND_WORKFLOW_AFTER_PAYMENT_RETRIES',
|
|
41
|
+
'11066': 'SHRIRAM_V1_S7_T5_PAYMENT_END',
|
|
42
|
+
};
|
|
43
|
+
|
|
12
44
|
export const workflowApi = baseApi.injectEndpoints({
|
|
13
45
|
endpoints: (builder) => ({
|
|
14
46
|
terminateWorkflow: builder.mutation<
|
|
@@ -37,11 +69,28 @@ export const workflowApi = baseApi.injectEndpoints({
|
|
|
37
69
|
updateTask: builder.mutation<any, any>({
|
|
38
70
|
query: (body) => {
|
|
39
71
|
const { providerId, workflowInstanceId, userreferenceid, applicationid, entityid, ...requestBody } = body;
|
|
72
|
+
const normalizedRequestBody = { ...requestBody } as Record<string, any>;
|
|
73
|
+
|
|
74
|
+
// Backend now expects caption-based field name.
|
|
75
|
+
// Keep compatibility if any caller still passes targetTaskId.
|
|
76
|
+
if (!normalizedRequestBody.targetTaskCaption && normalizedRequestBody.targetTaskId) {
|
|
77
|
+
normalizedRequestBody.targetTaskCaption = normalizedRequestBody.targetTaskId;
|
|
78
|
+
delete normalizedRequestBody.targetTaskId;
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
// Normalize numeric task IDs to caption values if provided.
|
|
82
|
+
if (normalizedRequestBody.targetTaskCaption !== undefined && normalizedRequestBody.targetTaskCaption !== null) {
|
|
83
|
+
const key = String(normalizedRequestBody.targetTaskCaption).trim();
|
|
84
|
+
if (TASK_ID_TO_CAPTION[key]) {
|
|
85
|
+
normalizedRequestBody.targetTaskCaption = TASK_ID_TO_CAPTION[key];
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
|
|
40
89
|
return {
|
|
41
90
|
url: 'taskflow/update',
|
|
42
91
|
method: 'POST',
|
|
43
92
|
body: {
|
|
44
|
-
...
|
|
93
|
+
...normalizedRequestBody,
|
|
45
94
|
workflowInstanceId: workflowInstanceId,
|
|
46
95
|
},
|
|
47
96
|
headers: {
|
|
@@ -6,6 +6,11 @@ export interface EnvironmentData {
|
|
|
6
6
|
apiKey?: string;
|
|
7
7
|
encryptionKey?: string;
|
|
8
8
|
enableLogging?: boolean;
|
|
9
|
+
sseMinimalLogs?: boolean;
|
|
10
|
+
enableVerboseSSELogging?: boolean;
|
|
11
|
+
sseReconnectAttempts?: number;
|
|
12
|
+
sseReconnectDelayMs?: number;
|
|
13
|
+
sseConnectTimeoutMs?: number;
|
|
9
14
|
}
|
|
10
15
|
|
|
11
16
|
/**
|