@tap-payments/auth-jsconnect 1.0.33 → 1.0.36

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 (37) hide show
  1. package/build/@types/form.d.ts +8 -1
  2. package/build/api/account.d.ts +15 -0
  3. package/build/api/account.js +9 -0
  4. package/build/api/data.d.ts +6 -0
  5. package/build/api/data.js +17 -0
  6. package/build/api/entity.d.ts +4 -4
  7. package/build/api/index.d.ts +10 -1
  8. package/build/api/index.js +5 -1
  9. package/build/components/AnimationFlow/BottomSheet.js +1 -1
  10. package/build/components/Input/Input.js +1 -1
  11. package/build/constants/api.d.ts +4 -0
  12. package/build/constants/api.js +9 -1
  13. package/build/constants/app.d.ts +5 -1
  14. package/build/constants/app.js +5 -1
  15. package/build/features/app/business/businessStore.d.ts +26 -5
  16. package/build/features/app/business/businessStore.js +221 -40
  17. package/build/features/app/connect/connectStore.d.ts +8 -2
  18. package/build/features/app/connect/connectStore.js +19 -1
  19. package/build/features/business/screens/Activities/Activities.js +12 -12
  20. package/build/features/business/screens/Activities/ActivitiesList.js +14 -4
  21. package/build/features/business/screens/Activities/SalesChannels.js +11 -2
  22. package/build/features/business/screens/Confirm/Confirm.js +3 -3
  23. package/build/features/business/screens/Customers/Customers.js +3 -2
  24. package/build/features/business/screens/IDBOD/IDBOD.js +1 -1
  25. package/build/features/business/screens/IDBOD/validation.js +2 -3
  26. package/build/features/business/screens/Success/Success.js +6 -0
  27. package/build/features/business/screens/Verify/Verify.js +2 -1
  28. package/build/features/connect/screens/Individual/Individual.js +6 -1
  29. package/build/features/connect/screens/Merchant/Merchant.js +6 -1
  30. package/build/features/connect/screens/Mobile/Mobile.js +6 -1
  31. package/build/features/connect/screens/NID/NID.js +6 -1
  32. package/build/features/connect/screens/OTP/OTP.js +6 -1
  33. package/build/features/connect/screens/OTP/OTPInput.js +0 -3
  34. package/build/features/connect/screens/Password/Password.js +6 -1
  35. package/build/features/shared/Button/Button.js +16 -11
  36. package/build/utils/string.js +2 -1
  37. package/package.json +1 -1
@@ -15,13 +15,13 @@ import { useSelector } from 'react-redux';
15
15
  import { styled } from '@mui/material/styles';
16
16
  import { useAppDispatch, useLanguage } from '../../../../hooks';
17
17
  import { useTranslation } from 'react-i18next';
18
- import { handleNextScreenStep, handlePrevScreenStep } from '../../../../app/settings';
18
+ import { handlePrevScreenStep } from '../../../../app/settings';
19
19
  import { FormProvider, useForm } from 'react-hook-form';
20
20
  import Form from '../../../../components/Form';
21
21
  import Input from '../../../shared/Input';
22
22
  import Button from '../../../shared/Button';
23
23
  import { ScreenContainer } from '../../../shared/Containers';
24
- import { businessSelector } from '../../../app/business/businessStore';
24
+ import { businessSelector, createAccount } from '../../../app/business/businessStore';
25
25
  import { BusinessType as BusinessTypeEnum } from '../../../../@types';
26
26
  var InputStyled = styled(Input)(function (_a) {
27
27
  var theme = _a.theme;
@@ -41,7 +41,7 @@ var Confirm = function () {
41
41
  var _a = data.businessInfo, licenseNumber = _a.licenseNumber, brandName = _a.brandName, legalName = _a.legalName;
42
42
  var isCR = data.businessTypeData.businessType === BusinessTypeEnum.CR;
43
43
  var onSubmit = function () {
44
- dispatch(handleNextScreenStep());
44
+ dispatch(createAccount());
45
45
  };
46
46
  var methods = useForm({
47
47
  defaultValues: data.businessInfo,
@@ -17,7 +17,7 @@ import { useTranslation } from 'react-i18next';
17
17
  import { useForm, FormProvider } from 'react-hook-form';
18
18
  import { yupResolver } from '@hookform/resolvers/yup';
19
19
  import { useAppDispatch } from '../../../../hooks';
20
- import { handleNextScreenStep, handlePrevScreenStep } from '../../../../app/settings';
20
+ import { handlePrevScreenStep } from '../../../../app/settings';
21
21
  import { CustomerInfoValidation } from './validation';
22
22
  import Form from '../../../../components/Form';
23
23
  import Button from '../../../shared/Button';
@@ -30,6 +30,7 @@ import RefundPolicy from './RefundPolicy';
30
30
  import TransactionPolicy from './TransactionPolicy';
31
31
  import { ScreenContainer } from '../../../shared/Containers';
32
32
  import Collapse from '../../../../components/Collapse';
33
+ import { updateCustomersInfo } from '../../../app/business/businessStore';
33
34
  var FormStyled = styled(Form)(function () { return ({
34
35
  display: 'flex',
35
36
  flexDirection: 'column'
@@ -56,7 +57,7 @@ var Customers = function (_a) {
56
57
  });
57
58
  var onSubmit = function (data) {
58
59
  console.log('data', data);
59
- dispatch(handleNextScreenStep());
60
+ dispatch(updateCustomersInfo(__assign(__assign({}, data), { isResend: false })));
60
61
  };
61
62
  var onBack = function () {
62
63
  dispatch(handlePrevScreenStep());
@@ -55,6 +55,6 @@ var IDBOD = function (_a) {
55
55
  dispatch(handlePrevScreenStep());
56
56
  };
57
57
  var disabled = !methods.formState.isValid || !!error;
58
- return (_jsx(ScreenContainer, { children: _jsx(FormProvider, __assign({}, methods, { children: _jsxs(FormStyled, __assign({ onSubmit: methods.handleSubmit(onSubmit) }, { children: [_jsx(Collapse, __assign({ in: !collapse }, { children: _jsx(ID, {}) })), _jsx(DOB, { onDateClicked: handleCollapseOpenClose }), _jsx(Collapse, __assign({ in: !collapse }, { children: _jsx(Button, __assign({ loading: loading, sx: { mt: 6 }, isAr: isAr, disabled: disabled, onClick: function () { return onBack(); }, error: t(error || '') }, { children: t('next') })) }))] })) })) }));
58
+ return (_jsx(ScreenContainer, { children: _jsx(FormProvider, __assign({}, methods, { children: _jsxs(FormStyled, __assign({ onSubmit: methods.handleSubmit(onSubmit) }, { children: [_jsx(Collapse, __assign({ in: !collapse }, { children: _jsx(ID, {}) })), _jsx(DOB, { onDateClicked: handleCollapseOpenClose }), _jsx(Collapse, __assign({ in: !collapse }, { children: _jsx(Button, __assign({ loading: loading, disableBack: true, isAr: isAr, disabled: disabled, onBackClicked: function () { return onBack(); }, error: t(error || '') }, { children: t('next') })) }))] })) })) }));
59
59
  };
60
60
  export default React.memo(IDBOD);
@@ -3,8 +3,7 @@ export var NIDValidationSchema = yup.object().shape({
3
3
  dob: yup.string().min(5).required('enter_valid_birth_date'),
4
4
  nid: yup
5
5
  .string()
6
- .matches(/^(1)([0-9]{1,})$/g, 'signup_invalid_national_id_format')
7
- .min(8, 'signup_invalid_national_id_format')
8
- .max(10, 'signup_invalid_national_id_format')
6
+ .matches(/^(1|2)([0-9]{1,})$/g, 'signup_invalid_national_id_format')
7
+ .min(10, 'signup_invalid_national_id')
9
8
  .required('signup_invalid_national_id')
10
9
  });
@@ -1,9 +1,15 @@
1
1
  import { jsx as _jsx } from "react/jsx-runtime";
2
2
  import * as React from 'react';
3
+ import { useAppDispatch } from '../../../../hooks';
3
4
  import { useTranslation } from 'react-i18next';
4
5
  import SuccessScreen from '../../../shared/SuccessScreen';
6
+ import { updateLeadSuccess } from '../../../app/business/businessStore';
5
7
  var Success = function (_a) {
6
8
  var t = useTranslation().t;
9
+ var dispatch = useAppDispatch();
10
+ React.useEffect(function () {
11
+ dispatch(updateLeadSuccess());
12
+ }, []);
7
13
  var onSuccess = function () {
8
14
  window.open('mailto:');
9
15
  };
@@ -20,6 +20,7 @@ import Box from '@mui/material/Box/Box';
20
20
  import { styled } from '@mui/material/styles';
21
21
  import { handlePrevScreenStep } from '../../../../app/settings';
22
22
  import { useLanguage } from '../../../../hooks';
23
+ import { maskPhone } from '../../../../utils';
23
24
  import Form from '../../../../components/Form';
24
25
  import Text from '../../../../components/Text';
25
26
  import { ScreenContainer } from '../../../shared/Containers';
@@ -69,6 +70,6 @@ var VerifyNumber = function (_a) {
69
70
  };
70
71
  var disabled = !methods.formState.isValid || !!error;
71
72
  var phone = ((_d = (_c = (_b = data.verify.responseBody) === null || _b === void 0 ? void 0 : _b.contact) === null || _c === void 0 ? void 0 : _c.phone) === null || _d === void 0 ? void 0 : _d.number) || '';
72
- return (_jsx(ScreenContainer, { children: _jsx(FormProvider, __assign({}, methods, { children: _jsxs(FormStyled, __assign({ onSubmit: methods.handleSubmit(onSubmit) }, { children: [_jsx(OTPTitleContainerStyled, { children: _jsxs(OTPTitleStyled, { children: [loading ? t('ide_otp_waiting_title') : t('ide_opt_sent_title'), !loading && phone && _jsx("span", __assign({ dir: 'ltr' }, { children: "".concat(phone) }))] }) }), _jsx(OTPInput, {}), _jsx(Button, __assign({ disableBack: true, onBackClicked: function () { return onBack(); }, disabled: disabled, type: 'submit', isAr: isAr, loading: loading, error: t(error || '') }, { children: t('next') }))] })) })) }));
73
+ return (_jsx(ScreenContainer, { children: _jsx(FormProvider, __assign({}, methods, { children: _jsxs(FormStyled, __assign({ onSubmit: methods.handleSubmit(onSubmit) }, { children: [_jsx(OTPTitleContainerStyled, { children: _jsxs(OTPTitleStyled, { children: [loading ? t('ide_otp_waiting_title') : t('ide_opt_sent_title'), !loading && phone && _jsx("span", __assign({ dir: 'ltr' }, { children: "".concat(maskPhone(phone)) }))] }) }), _jsx(OTPInput, {}), _jsx(Button, __assign({ disableBack: true, onBackClicked: function () { return onBack(); }, disabled: disabled, type: 'submit', isAr: isAr, loading: loading, error: t(error || '') }, { children: t('next') }))] })) })) }));
73
74
  };
74
75
  export default React.memo(VerifyNumber);
@@ -24,7 +24,7 @@ import { IndividualValidation, IndividualMobileValidation } from './validation';
24
24
  import Form from '../../../../components/Form';
25
25
  import Button from '../../../shared/Button';
26
26
  import { ScreenContainer } from '../../../shared/Containers';
27
- import { clearError, connectSelector, updateLeadIndividual } from '../../../app/connect/connectStore';
27
+ import { clearError, connectSelector, resetIndividualScreen, updateLeadIndividual } from '../../../app/connect/connectStore';
28
28
  import { useLanguage } from '../../../../hooks';
29
29
  import MobileNumber from './MobileNumber';
30
30
  import { countriesCode } from '../../../../constants';
@@ -58,6 +58,11 @@ var Individual = function (_a) {
58
58
  if (error)
59
59
  dispatch(clearError());
60
60
  }, [methods.formState.isValid]);
61
+ React.useEffect(function () {
62
+ return function () {
63
+ dispatch(resetIndividualScreen());
64
+ };
65
+ }, []);
61
66
  React.useEffect(function () {
62
67
  var name = individualData.name, email = individualData.email, mobile = individualData.mobile, countryCode = individualData.countryCode;
63
68
  if (!!name)
@@ -20,7 +20,7 @@ import { handlePrevScreenStep } from '../../../../app/settings';
20
20
  import Form from '../../../../components/Form';
21
21
  import { ScreenContainer } from '../../../shared/Containers';
22
22
  import Button from '../../../shared/Button';
23
- import { clearError, connectSelector, updateLeadBrand } from '../../../app/connect/connectStore';
23
+ import { clearError, connectSelector, resetMerchantScreen, updateLeadBrand } from '../../../app/connect/connectStore';
24
24
  import { useLanguage } from '../../../../hooks';
25
25
  import { MerchantValidationSchema } from './validation';
26
26
  import BrandName from './BrandName';
@@ -47,6 +47,11 @@ var Merchant = function (_a) {
47
47
  if (error)
48
48
  dispatch(clearError());
49
49
  }, [methods.formState.isValid]);
50
+ React.useEffect(function () {
51
+ return function () {
52
+ dispatch(resetMerchantScreen());
53
+ };
54
+ }, []);
50
55
  React.useEffect(function () {
51
56
  var _a, _b;
52
57
  if (((_b = (_a = data.brandData) === null || _a === void 0 ? void 0 : _a.responseBody) === null || _b === void 0 ? void 0 : _b.response_code) === '5')
@@ -23,7 +23,7 @@ import Button, { AbsherButton } from '../../../shared/Button';
23
23
  import { useAppDispatch } from '../../../../hooks';
24
24
  import { handlePrevScreenStep, settingsSelector } from '../../../../app/settings';
25
25
  import ScreenContainer from '../../../shared/Containers/ScreenContainer';
26
- import { clearError, connectSelector, createMobileAuth } from '../../../app/connect/connectStore';
26
+ import { clearError, resetMobileScreen, connectSelector, createMobileAuth } from '../../../app/connect/connectStore';
27
27
  import { useLanguage } from '../../../../hooks';
28
28
  import Divider from '@mui/material/Divider';
29
29
  import Text from '../../../../components/Text';
@@ -101,6 +101,11 @@ var Mobile = function (_a) {
101
101
  if (error)
102
102
  dispatch(clearError());
103
103
  }, [methods.formState.isValid]);
104
+ React.useEffect(function () {
105
+ return function () {
106
+ dispatch(resetMobileScreen());
107
+ };
108
+ }, []);
104
109
  var onSubmit = function (formData) {
105
110
  dispatch(createMobileAuth(__assign(__assign({}, formData), { isResend: false })));
106
111
  };
@@ -19,7 +19,7 @@ import { yupResolver } from '@hookform/resolvers/yup';
19
19
  import { NIDValidationSchema } from './validation';
20
20
  import { useAppDispatch, useLanguage } from '../../../../hooks';
21
21
  import { handlePrevScreenStep, settingsSelector } from '../../../../app/settings';
22
- import { clearError, connectSelector, createNIDAuth } from '../../../app/connect/connectStore';
22
+ import { clearError, resetNIDScreen, connectSelector, createNIDAuth } from '../../../app/connect/connectStore';
23
23
  import Form from '../../../../components/Form';
24
24
  import Button, { AbsherButton } from '../../../shared/Button';
25
25
  import { ScreenContainer } from '../../../shared/Containers';
@@ -73,6 +73,11 @@ var NID = function (_a) {
73
73
  React.useEffect(function () {
74
74
  handleClearError();
75
75
  }, [methods.formState.isValid]);
76
+ React.useEffect(function () {
77
+ return function () {
78
+ dispatch(resetNIDScreen());
79
+ };
80
+ }, []);
76
81
  var onSubmit = function (data) {
77
82
  dispatch(createNIDAuth(__assign(__assign({}, data), { isResend: false })));
78
83
  };
@@ -16,7 +16,7 @@ import { styled } from '@mui/material/styles';
16
16
  import * as React from 'react';
17
17
  import { useTranslation } from 'react-i18next';
18
18
  import Text from '../../../../components/Text';
19
- import { clearError, connectSelector, verifyAuth } from '../../../app/connect/connectStore';
19
+ import { clearError, connectSelector, resetOTPScreen, verifyAuth } from '../../../app/connect/connectStore';
20
20
  import Button from '../../../shared/Button';
21
21
  import { ScreenContainer } from '../../../shared/Containers';
22
22
  import { useAppDispatch } from '../../../../hooks';
@@ -63,6 +63,11 @@ var OTP = function () {
63
63
  if (error)
64
64
  dispatch(clearError());
65
65
  }, [methods.formState.isValid]);
66
+ React.useEffect(function () {
67
+ return function () {
68
+ dispatch(resetOTPScreen());
69
+ };
70
+ }, []);
66
71
  var onSubmit = function (formData) {
67
72
  dispatch(verifyAuth(formData));
68
73
  };
@@ -37,9 +37,6 @@ var OTPInput = function (_a) {
37
37
  var mobileData = data.mobileData;
38
38
  var nidData = data.nidData;
39
39
  var isAbsher = data.otpData.isAbsher;
40
- React.useEffect(function () {
41
- otpControl.field.onChange('');
42
- }, []);
43
40
  var handleOnOTPChange = function (otp) {
44
41
  otpControl.field.onChange(otp);
45
42
  };
@@ -18,7 +18,7 @@ import { useTranslation } from 'react-i18next';
18
18
  import { yupResolver } from '@hookform/resolvers/yup';
19
19
  import { styled } from '@mui/material/styles';
20
20
  import { handlePrevScreenStep } from '../../../../app/settings';
21
- import { clearError, connectSelector, createVerifyAuthPassword } from '../../../app/connect/connectStore';
21
+ import { clearError, connectSelector, createVerifyAuthPassword, resetPasswordScreen } from '../../../app/connect/connectStore';
22
22
  import Form from '../../../../components/Form';
23
23
  import Button from '../../../shared/Button';
24
24
  import { ScreenContainer } from '../../../shared/Containers';
@@ -46,6 +46,11 @@ var Password = function (_a) {
46
46
  if (error)
47
47
  dispatch(clearError());
48
48
  }, [methods.formState.isValid]);
49
+ React.useEffect(function () {
50
+ return function () {
51
+ dispatch(resetPasswordScreen());
52
+ };
53
+ }, []);
49
54
  var onSubmit = function (formData) {
50
55
  dispatch(createVerifyAuthPassword(formData));
51
56
  };
@@ -54,15 +54,23 @@ var ButtonBoxStyled = styled(Box)(function (_a) {
54
54
  return ({
55
55
  margin: theme.spacing(0, 2.5, 2.5, 2.5),
56
56
  marginBlockStart: theme.spacing(5),
57
- display: 'flex'
57
+ display: 'flex',
58
+ alignItems: 'center',
59
+ justifyContent: 'center'
58
60
  });
59
61
  });
60
- var ButtonStyled = styled(Button, { shouldForwardProp: function (prop) { return prop !== 'isBack'; } })(function (_a) {
61
- var theme = _a.theme, isBack = _a.isBack;
62
- return ({
63
- paddingInlineStart: theme.spacing(2.5),
64
- marginInlineStart: isBack ? theme.spacing(-5) : theme.spacing(0)
65
- });
62
+ var ButtonStyled = styled(Button, {
63
+ shouldForwardProp: function (prop) { return prop !== 'isBack' && prop !== 'isLoading'; }
64
+ })(function (_a) {
65
+ var theme = _a.theme, isBack = _a.isBack, isLoading = _a.isLoading;
66
+ return (__assign({ paddingInlineStart: theme.spacing(2.5), marginInlineStart: isBack ? theme.spacing(-5) : theme.spacing(0), paddingLeft: isLoading ? 8 : 'auto', paddingRight: isLoading ? 8 : 'auto', transition: theme.transitions.create(['width', 'padding'], {
67
+ easing: theme.transitions.easing.easeInOut,
68
+ duration: theme.transitions.duration.complex * 2
69
+ }) }, (isLoading && {
70
+ minWidth: 0,
71
+ width: theme.spacing(6),
72
+ borderRadius: 30
73
+ })));
66
74
  });
67
75
  var BackButtonStyled = styled(Button, { shouldForwardProp: function (prop) { return prop !== 'isAr'; } })(function (_a) {
68
76
  var theme = _a.theme, isAr = _a.isAr;
@@ -77,8 +85,5 @@ var BackButtonStyled = styled(Button, { shouldForwardProp: function (prop) { ret
77
85
  export default function CustomButton(_a) {
78
86
  var children = _a.children, disabled = _a.disabled, isAr = _a.isAr, loading = _a.loading, disableBack = _a.disableBack, onBackClicked = _a.onBackClicked, error = _a.error, props = __rest(_a, ["children", "disabled", "isAr", "loading", "disableBack", "onBackClicked", "error"]);
79
87
  var isBackEnabled = !disableBack && !loading;
80
- return (_jsxs(Fragment, { children: [_jsx(Collapse, __assign({ in: !!error }, { children: _jsx(Warning, __assign({ sx: { mb: 1 }, warningType: 'error' }, { children: error })) })), _jsxs(ButtonBoxStyled, { children: [isBackEnabled && (_jsx(BackButtonStyled, __assign({ onClick: function () { return onBackClicked === null || onBackClicked === void 0 ? void 0 : onBackClicked(); }, isAr: isAr, type: 'reset', startIcon: _jsx(BackIconStyled, { isAr: isAr, src: ICONS_NAMES.WHITE_ARROW }) }, props))), _jsx(ButtonStyled, __assign({ disabled: disabled || loading, type: 'submit', isBack: isBackEnabled, endIcon: _jsx(IconStyled, { isAr: isAr, src: ICONS_NAMES.WHITE_ARROW }), startIcon: _jsx(Loader, { style: {
81
- visibility: disableBack && !loading ? 'hidden' : loading ? 'visible' : 'hidden',
82
- display: !disableBack && !loading ? 'none' : 'block'
83
- }, innerColor: 'white', outerColor: 'white', size: 30, toggleAnimation: !!loading }) }, props, { children: _jsxs(Text, __assign({ sx: { marginInlineEnd: isBackEnabled ? '-24px' : '20px' } }, { children: [" ", children] })) }))] })] }));
88
+ return (_jsxs(Fragment, { children: [_jsx(Collapse, __assign({ in: !!error }, { children: _jsx(Warning, __assign({ sx: { mb: 1 }, warningType: 'error' }, { children: error })) })), _jsxs(ButtonBoxStyled, { children: [isBackEnabled && (_jsx(BackButtonStyled, __assign({ onClick: function () { return onBackClicked === null || onBackClicked === void 0 ? void 0 : onBackClicked(); }, isAr: isAr, type: 'reset', startIcon: _jsx(BackIconStyled, { isAr: isAr, src: ICONS_NAMES.WHITE_ARROW }) }, props))), _jsx(ButtonStyled, __assign({ disabled: disabled, isLoading: loading, type: !loading ? 'submit' : 'button', isBack: isBackEnabled, endIcon: !loading && _jsx(IconStyled, { isAr: isAr, src: ICONS_NAMES.WHITE_ARROW }) }, props, { children: !loading ? (_jsxs(Text, __assign({ sx: { marginInlineEnd: isBackEnabled ? '-24px' : '-15px' } }, { children: [" ", children] }))) : (_jsx(Loader, { innerColor: 'white', outerColor: 'white', size: 25, toggleAnimation: !!loading })) }))] })] }));
84
89
  }
@@ -60,6 +60,7 @@ export var capitalizeTheFirstLetterOfEachWord = function (words) {
60
60
  return separateWord.join(' ');
61
61
  };
62
62
  export var getRequestHeaders = function (deviceInfo) {
63
+ console.log(deviceInfo);
63
64
  var app = deviceInfo.app, browser = deviceInfo.browser, connection = deviceInfo.connection, device = deviceInfo.device, source = deviceInfo.source;
64
65
  return {
65
66
  al: encryptString(app.language || ''),
@@ -78,7 +79,7 @@ export var getRequestHeaders = function (deviceInfo) {
78
79
  bn: encryptString(browser.name || ''),
79
80
  bb: encryptString(''),
80
81
  bv: encryptString(browser.version || ''),
81
- bua: encryptString(browser.user_agent),
82
+ bua: encryptString((browser.user_agent || '').substring(0, 80)),
82
83
  bi: encryptString(browser.browser_id || ''),
83
84
  ci: encryptString(connection.ip || ''),
84
85
  cm: encryptString(connection.mac || ''),
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@tap-payments/auth-jsconnect",
3
- "version": "1.0.33",
3
+ "version": "1.0.36",
4
4
  "description": "connect library, auth",
5
5
  "private": false,
6
6
  "main": "build/index.js",