@momo-kits/foundation 0.89.4-tracking.18 → 0.89.5-beta.10

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.
@@ -7,11 +7,6 @@ import {InputDropDownProps} from './index';
7
7
  import {Icon} from '../Icon';
8
8
  import {Loader} from '../Loader';
9
9
  import {Styles} from '../Consts';
10
- import {formatComponentName} from '../Application/utils';
11
-
12
- const {
13
- ScreenContext,
14
- } = require('react-native/Libraries/Components/ScreenContext');
15
10
 
16
11
  const InputDropDown = ({
17
12
  value,
@@ -31,13 +26,10 @@ const InputDropDown = ({
31
26
  leadingIcon,
32
27
  leadingIconColor,
33
28
  style,
34
- params,
35
- componentId,
36
29
  ...props
37
30
  }: InputDropDownProps) => {
38
31
  const {theme} = useContext(ApplicationContext);
39
32
  const full = !!value || !!placeholder;
40
- const screenInfo = useContext<any>(ScreenContext);
41
33
 
42
34
  const renderIcon = (color: string | undefined) => {
43
35
  if (loading) {
@@ -112,22 +104,10 @@ const InputDropDown = ({
112
104
  };
113
105
 
114
106
  return (
115
- <ScreenContext.Provider
116
- value={{
117
- ...screenInfo,
118
- componentName: 'InputOTP',
119
- params,
120
- state: 'enabled',
121
- componentLabel: formatComponentName(floatingValue || ''),
122
- componentId,
123
- }}>
124
- <TouchableOpacity
125
- onPress={onPress}
126
- style={[style, full && styles.wrapper]}>
127
- {renderInputView()}
128
- <ErrorView errorMessage={errorMessage} errorSpacing={errorSpacing} />
129
- </TouchableOpacity>
130
- </ScreenContext.Provider>
107
+ <TouchableOpacity onPress={onPress} style={[style, full && styles.wrapper]}>
108
+ {renderInputView()}
109
+ <ErrorView errorMessage={errorMessage} errorSpacing={errorSpacing} />
110
+ </TouchableOpacity>
131
111
  );
132
112
  };
133
113
 
@@ -18,11 +18,6 @@ import {ErrorView, FloatingView, getBorderColor, getSizeStyle} from './common';
18
18
  import {InputMoneyProps} from './index';
19
19
  import {Icon} from '../Icon';
20
20
  import {formatMoneyToNumber, formatNumberToMoney} from './utils';
21
- import {formatComponentName} from '../Application/utils';
22
-
23
- const {
24
- ScreenContext,
25
- } = require('react-native/Libraries/Components/ScreenContext');
26
21
 
27
22
  const InputMoney = forwardRef(
28
23
  (
@@ -41,9 +36,7 @@ const InputMoney = forwardRef(
41
36
  required = false,
42
37
  errorSpacing,
43
38
  style,
44
- params,
45
39
  defaultValue = '',
46
- componentId,
47
40
  ...props
48
41
  }: InputMoneyProps,
49
42
  ref,
@@ -51,7 +44,6 @@ const InputMoney = forwardRef(
51
44
  const {theme} = useContext(ApplicationContext);
52
45
  const [focused, setFocused] = useState(false);
53
46
  const inputRef = (ref as React.RefObject<TextInput>) ?? useRef<TextInput>();
54
- const screenInfo = useContext<any>(ScreenContext);
55
47
 
56
48
  const validateText = (text: string) => {
57
49
  const valueFormat = formatMoneyToNumber(text, 'đ');
@@ -159,34 +151,11 @@ const InputMoney = forwardRef(
159
151
  );
160
152
  };
161
153
 
162
- let inputState = 'active';
163
-
164
- if (value && value?.length > 0) {
165
- inputState = 'filled';
166
- }
167
- if (errorMessage && errorMessage?.length > 0) {
168
- inputState = 'error';
169
- }
170
-
171
- if (disabled) {
172
- inputState = 'disabled';
173
- }
174
-
175
154
  return (
176
- <ScreenContext.Provider
177
- value={{
178
- ...screenInfo,
179
- componentName: 'InputMoney',
180
- params,
181
- componentLabel: formatComponentName(floatingValue || ''),
182
- state: inputState,
183
- componentId,
184
- }}>
185
- <View style={[style, styles.wrapper]}>
186
- {renderInputView()}
187
- <ErrorView errorMessage={errorMessage} errorSpacing={errorSpacing} />
188
- </View>
189
- </ScreenContext.Provider>
155
+ <View style={[style, styles.wrapper]}>
156
+ {renderInputView()}
157
+ <ErrorView errorMessage={errorMessage} errorSpacing={errorSpacing} />
158
+ </View>
190
159
  );
191
160
  },
192
161
  );
@@ -21,11 +21,6 @@ import styles from './styles';
21
21
  import {ErrorView, getBorderColor} from './common';
22
22
  import {ApplicationContext} from '../Application';
23
23
  import {Spacing} from '../Consts';
24
- import {formatComponentName} from '../Application/utils';
25
-
26
- const {
27
- ScreenContext,
28
- } = require('react-native/Libraries/Components/ScreenContext');
29
24
 
30
25
  const OTPCaret: FC<CaretProps> = ({index, length}) => {
31
26
  const DURATION = 300;
@@ -83,9 +78,7 @@ const InputOTP = forwardRef(
83
78
  onFocus,
84
79
  onBlur,
85
80
  dataType = 'number',
86
- params,
87
81
  style,
88
- componentId,
89
82
  ...props
90
83
  }: InputOTPProps,
91
84
  ref,
@@ -95,7 +88,6 @@ const InputOTP = forwardRef(
95
88
  const [focused, setFocused] = useState(false);
96
89
  const inputRef = useRef<TextInput>(null);
97
90
  const {theme} = useContext(ApplicationContext);
98
- const screenInfo = useContext<any>(ScreenContext);
99
91
 
100
92
  useImperativeHandle(ref, () => ({
101
93
  onChangeText: (text: string) => {
@@ -229,23 +221,13 @@ const InputOTP = forwardRef(
229
221
  };
230
222
 
231
223
  return (
232
- <ScreenContext.Provider
233
- value={{
234
- ...screenInfo,
235
- componentName: 'InputOTP',
236
- params,
237
- componentLabel: formatComponentName(floatingValue || ''),
238
- state: 'enabled',
239
- componentId,
240
- }}>
241
- <TouchableOpacity
242
- activeOpacity={1}
243
- onPress={onFocusInput}
244
- style={[style, styles.otpWrapper]}>
245
- {renderInputView()}
246
- <ErrorView errorMessage={errorMessage} errorSpacing={errorSpacing} />
247
- </TouchableOpacity>
248
- </ScreenContext.Provider>
224
+ <TouchableOpacity
225
+ activeOpacity={1}
226
+ onPress={onFocusInput}
227
+ style={[style, styles.otpWrapper]}>
228
+ {renderInputView()}
229
+ <ErrorView errorMessage={errorMessage} errorSpacing={errorSpacing} />
230
+ </TouchableOpacity>
249
231
  );
250
232
  },
251
233
  );
@@ -13,10 +13,6 @@ import {Icon} from '../Icon';
13
13
  import {Text} from '../Text';
14
14
  import {checkTyping} from './utils';
15
15
 
16
- const {
17
- ScreenContext,
18
- } = require('react-native/Libraries/Components/ScreenContext');
19
-
20
16
  const InputSearch = forwardRef(
21
17
  (
22
18
  {
@@ -32,9 +28,7 @@ const InputSearch = forwardRef(
32
28
  style,
33
29
  defaultValue,
34
30
  onPressButtonText,
35
- hasColorBG = true,
36
- params,
37
- componentId,
31
+ hasColorBG = true,
38
32
  ...props
39
33
  }: InputSearchProps,
40
34
  ref,
@@ -43,7 +37,6 @@ const InputSearch = forwardRef(
43
37
  const [focused, setFocused] = useState(false);
44
38
  const [haveValue, setHaveValue] = useState(!!value || !!defaultValue);
45
39
  const inputRef = (ref as React.RefObject<TextInput>) ?? useRef<TextInput>();
46
- const screenInfo = useContext<any>(ScreenContext);
47
40
 
48
41
  const _onFocus = (e: NativeSyntheticEvent<TextInputFocusEventData>) => {
49
42
  setFocused(true);
@@ -124,56 +117,33 @@ const InputSearch = forwardRef(
124
117
  );
125
118
  };
126
119
 
127
- let inputState = 'empty';
128
-
129
- if (focused) {
130
- inputState = 'focus';
131
- }
132
-
133
- if (value && value?.length > 0) {
134
- inputState = 'filled';
135
- }
136
-
137
- const backgroundColor = hasColorBG
138
- ? theme.colors.background.default
139
- : theme.colors.background.surface;
120
+ const backgroundColor = hasColorBG ? theme.colors.background.default : theme.colors.background.surface
140
121
 
141
122
  return (
142
- <ScreenContext.Provider
143
- value={{
144
- ...screenInfo,
145
- componentName: 'InputSearch',
146
- params,
147
- state: inputState,
148
- componentId,
149
- }}>
150
- <View style={[style, styles.searchInputContainer]}>
151
- <View
152
- style={[
153
- styles.searchInputWrapper,
154
- {
155
- backgroundColor,
156
- },
157
- ]}>
158
- <Icon
159
- source={'navigation_search'}
160
- size={24}
161
- color={theme.colors.text.hint}
162
- />
163
- {renderInputView()}
164
- {renderIconView()}
165
- </View>
166
- {showButtonText && (
167
- <TouchableOpacity onPress={onPressButtonText}>
168
- <Text
169
- typography={'action_default_bold'}
170
- style={styles.textButton}>
171
- {buttonText}
172
- </Text>
173
- </TouchableOpacity>
174
- )}
123
+ <View style={[style, styles.searchInputContainer]}>
124
+ <View
125
+ style={[
126
+ styles.searchInputWrapper,
127
+ {
128
+ backgroundColor,
129
+ }
130
+ ]}>
131
+ <Icon
132
+ source={'navigation_search'}
133
+ size={24}
134
+ color={theme.colors.text.hint}
135
+ />
136
+ {renderInputView()}
137
+ {renderIconView()}
175
138
  </View>
176
- </ScreenContext.Provider>
139
+ {showButtonText && (
140
+ <TouchableOpacity onPress={onPressButtonText}>
141
+ <Text typography={'action_default_bold'} style={styles.textButton}>
142
+ {buttonText}
143
+ </Text>
144
+ </TouchableOpacity>
145
+ )}
146
+ </View>
177
147
  );
178
148
  },
179
149
  );
package/Input/index.tsx CHANGED
@@ -80,9 +80,6 @@ export interface InputProps extends TextInputProps {
80
80
  fontWeight?: 'Regular' | 'Bold';
81
81
 
82
82
  onPressIcon?: () => void;
83
-
84
- params?: any;
85
- componentId?: string;
86
83
  }
87
84
 
88
85
  type InputPropsWithoutSizeAndIcon = Omit<
@@ -124,14 +121,7 @@ export interface InputSearchProps extends TextInputProps {
124
121
  */
125
122
  icon?: string;
126
123
 
127
- /**
128
- *
129
- */
130
- hasColorBG?: boolean;
131
-
132
- params?: any;
133
-
134
- componentId?: string;
124
+ hasColorBG?: boolean
135
125
  }
136
126
 
137
127
  export interface InputMoneyProps extends InputPropsWithoutPlaceholder {}
@@ -255,22 +245,7 @@ export interface InputDropDownProps {
255
245
  */
256
246
  leadingIconColor?: string;
257
247
 
258
- /**
259
- * Optional. params for element tracking.
260
- */
261
- params?: {
262
- [key: string]: any;
263
- };
264
-
265
- /**
266
- * component id for element tracking.
267
- */
268
- componentId?: string;
269
-
270
- /**
271
- * Optional. Represents the style of the InputDropDown component.
272
- */
273
- style?: ViewStyle | ViewStyle[];
248
+ style: ViewStyle | ViewStyle[];
274
249
  }
275
250
 
276
251
  export {Input, InputTextArea, InputSearch, InputMoney, InputOTP, InputDropDown};
package/Radio/index.tsx CHANGED
@@ -6,11 +6,6 @@ import {Text} from '../Text';
6
6
  import styles from './styles';
7
7
  import {ApplicationContext} from '../Application';
8
8
  import {Spacing} from '../Consts';
9
- import {formatNameLength} from '../Application/utils';
10
-
11
- const {
12
- ScreenContext,
13
- } = require('react-native/Libraries/Components/ScreenContext');
14
9
 
15
10
  const Radio: FC<RadioProps> = ({
16
11
  value,
@@ -19,11 +14,8 @@ const Radio: FC<RadioProps> = ({
19
14
  onChange,
20
15
  label,
21
16
  style,
22
- params,
23
- componentId,
24
17
  }) => {
25
18
  const {theme} = useContext(ApplicationContext);
26
- const screenInfo = useContext<any>(ScreenContext);
27
19
  const selected = value === groupValue;
28
20
  let disabledStyle = {};
29
21
  let checkBoxStyle = {
@@ -46,38 +38,26 @@ const Radio: FC<RadioProps> = ({
46
38
  }
47
39
 
48
40
  return (
49
- <ScreenContext.Provider
50
- value={{
51
- ...screenInfo,
52
- componentName: 'Button',
53
- params,
54
- state: disabled ? 'disabled' : 'enabled',
55
- componentId,
56
- componentLabel: formatNameLength(label || ''),
57
- componentValue: value,
58
- action: 'click',
59
- }}>
60
- <TouchableOpacity
61
- onPress={onChange}
62
- disabled={disabled}
41
+ <TouchableOpacity
42
+ onPress={onChange}
43
+ disabled={disabled}
44
+ style={[
45
+ style,
46
+ {
47
+ flexDirection: 'row',
48
+ alignItems: 'center',
49
+ },
50
+ ]}>
51
+ <View
63
52
  style={[
64
- style,
65
- {
66
- flexDirection: 'row',
67
- alignItems: 'center',
68
- },
69
- ]}>
70
- <View
71
- style={[
72
- styles.radio,
73
- checkBoxStyle,
74
- disabledStyle,
75
- {marginRight: label ? Spacing.XS : 0},
76
- ]}
77
- />
78
- {!!label && <Text typography={'body_default_regular'}>{label}</Text>}
79
- </TouchableOpacity>
80
- </ScreenContext.Provider>
53
+ styles.radio,
54
+ checkBoxStyle,
55
+ disabledStyle,
56
+ {marginRight: label ? Spacing.XS : 0},
57
+ ]}
58
+ />
59
+ {!!label && <Text typography={'body_default_regular'}>{label}</Text>}
60
+ </TouchableOpacity>
81
61
  );
82
62
  };
83
63
 
package/Radio/types.ts CHANGED
@@ -35,9 +35,4 @@ export type RadioProps = {
35
35
  * Accepts an object of style properties.
36
36
  */
37
37
  style?: ViewStyle;
38
-
39
-
40
- params?: any
41
-
42
- componentId?: string
43
38
  };
package/Switch/index.tsx CHANGED
@@ -1,17 +1,11 @@
1
- import React, {FC, useContext} from 'react';
1
+ import React, {FC} from 'react';
2
2
  import {TouchableOpacity, View} from 'react-native';
3
3
  import {SwitchProps} from './types';
4
4
  import styles from './styles';
5
5
  import {Colors} from '../Consts';
6
6
 
7
- const {
8
- ScreenContext,
9
- } = require('react-native/Libraries/Components/ScreenContext');
10
-
11
7
  const Switch: FC<SwitchProps> = props => {
12
- const {value, onChange, disabled, style, params, componentId} = props;
13
- const screenInfo = useContext<any>(ScreenContext);
14
-
8
+ const {value, onChange, disabled, style} = props;
15
9
  const circleBackgroundColor = value ? Colors.black_01 : Colors.black_03;
16
10
  const circleAlign = value ? 'flex-end' : 'flex-start';
17
11
 
@@ -21,29 +15,18 @@ const Switch: FC<SwitchProps> = props => {
21
15
  }
22
16
 
23
17
  return (
24
- <ScreenContext.Provider
25
- value={{
26
- ...screenInfo,
27
- componentName: 'Button',
28
- params,
29
- state: disabled ? 'disabled' : 'enabled',
30
- componentId,
31
- componentValue: value,
32
- action: 'click',
33
- }}>
34
- <TouchableOpacity
35
- disabled={disabled}
36
- onPress={() => onChange?.(!value)}
37
- style={[
38
- style,
39
- styles.container,
40
- {backgroundColor, alignItems: circleAlign},
41
- ]}>
42
- <View style={[styles.circle, {backgroundColor: circleBackgroundColor}]}>
43
- <View style={[styles.circleSmall, {backgroundColor}]} />
44
- </View>
45
- </TouchableOpacity>
46
- </ScreenContext.Provider>
18
+ <TouchableOpacity
19
+ disabled={disabled}
20
+ onPress={() => onChange?.(!value)}
21
+ style={[
22
+ style,
23
+ styles.container,
24
+ {backgroundColor, alignItems: circleAlign},
25
+ ]}>
26
+ <View style={[styles.circle, {backgroundColor: circleBackgroundColor}]}>
27
+ <View style={[styles.circleSmall, {backgroundColor}]} />
28
+ </View>
29
+ </TouchableOpacity>
47
30
  );
48
31
  };
49
32
 
package/Switch/types.ts CHANGED
@@ -23,8 +23,4 @@ export type SwitchProps = {
23
23
  * Accepts an object of style properties.
24
24
  */
25
25
  style?: ViewStyle;
26
-
27
- params?: any
28
-
29
- componentId?: string
30
26
  };
package/code-scanner.js CHANGED
@@ -1,51 +1,138 @@
1
1
  const scanner = require('react-scanner');
2
+ const fs = require('fs');
2
3
  const path = require('path');
3
4
 
4
- const scan = async config => {
5
- return await scanner.run(config);
5
+ const scan = async (config) => {
6
+ return await scanner.run(config);
6
7
  };
7
8
 
8
- const calcSum = array => {
9
- return array.reduce((a, b) => a + b, 0);
9
+ const calcSum = (array) => {
10
+ return array.reduce((a, b) => a + b, 0);
10
11
  };
11
12
 
12
- const calculateAdoptionRate = (kitJsonPath, miniappJsonPath) => {
13
- const kitJson = require(kitJsonPath);
14
- const miniAppJson = require(miniappJsonPath);
15
- const numOfKitComponents = calcSum(Object.values(kitJson));
16
- const numOfMiniAppComponents = calcSum(Object.values(miniAppJson));
17
- const adoptionRate = (numOfKitComponents / numOfMiniAppComponents) * 100;
18
- console.log("Number of kit's components: ", numOfKitComponents);
19
- console.log("Number of miniapp's components: ", numOfMiniAppComponents);
20
- console.log('Adoption rate: ', adoptionRate);
13
+ const calculateAdoptionRate = async (branchName , kitJsonPath , miniappJsonPath , reactNativeJsonPath , fsJsonPath ) => {
14
+ const kitJson = require(kitJsonPath);
15
+ const miniAppJson = require(miniappJsonPath);
16
+ const reactNativeJson = require(reactNativeJsonPath);
17
+ const fsJson = require(fsJsonPath);
18
+
19
+ const numOfKitComponents = calcSum(Object.values(kitJson));
20
+ const numOfMiniAppComponents = calcSum(Object.values(miniAppJson));
21
+ const numOfReactNativeComponents = calcSum(Object.values(reactNativeJson));
22
+ const numOfFSComponents = calcSum(Object.values(fsJson));
23
+
24
+ const adoptionRate = ((numOfKitComponents + numOfReactNativeComponents + numOfFSComponents) / numOfMiniAppComponents) * 100;
25
+
26
+ return {
27
+ miniAppName: branchName,
28
+ numOfKitComponents: numOfKitComponents,
29
+ numOfMiniAppComponents: numOfMiniAppComponents,
30
+ numOfReactNativeComponents: numOfReactNativeComponents,
31
+ numOfFSComponents: numOfFSComponents,
32
+ adoptionRate: adoptionRate.toFixed(2) + '%'
33
+ }
21
34
  };
22
35
 
36
+ function ensureFileExists(filePath , defaultContent = {}) {
37
+ if (!fs.existsSync(filePath)) {
38
+ fs.mkdirSync(path.dirname(filePath), { recursive: true });
39
+ fs.writeFileSync(filePath, JSON.stringify(defaultContent, null, 2));
40
+ }
41
+ }
42
+
43
+ const sendMessage = ({
44
+ numOfKitComponents,
45
+ numOfMiniAppComponents,
46
+ numOfFSComponents,
47
+ numOfReactNativeComponents,
48
+ adoptionRate,
49
+ miniAppName = ''
50
+ }) => {
51
+ const url = 'https://chat.googleapis.com/v1/spaces/AAAAL9P6G8M/messages?key=AIzaSyDdI0hCZtE6vySjMm-WEfRq3CPzqKqqsHI&token=fnwfYuH_u0KicBnKTSSm9S0qV6azJH5v6URm8HR7V2g';
52
+
53
+ const data = {
54
+ text: `MiniApp: ${miniAppName}\nNumber of kit's components: ${numOfKitComponents}\nNumber of miniapp's components: ${numOfMiniAppComponents}\nNumber of FS's components: ${numOfFSComponents}\nNumber of React Native's components: ${numOfReactNativeComponents}\nAdoption rate: ${adoptionRate}`
55
+ };
56
+
57
+ fetch(url, {
58
+ method: 'POST',
59
+ headers: {
60
+ 'Content-Type': 'application/json'
61
+ },
62
+ body: JSON.stringify(data)
63
+ })
64
+ .then(response => response.json())
65
+ .then(data => {
66
+ console.log('Success:', data);
67
+ })
68
+ .catch((error) => {
69
+ console.error('Error:', error);
70
+ });
71
+ }
72
+
23
73
  const main = async () => {
24
- const [scanPath, kitJsonRelativePath, miniappJsonRelativePath] =
25
- process.argv.slice(2);
26
-
27
- const kitJsonPath = path.resolve(process.cwd(), kitJsonRelativePath);
28
- const miniappJsonPath = path.resolve(process.cwd(), miniappJsonRelativePath);
29
-
30
- const config1 = {
31
- crawlFrom: scanPath,
32
- includeSubComponents: true,
33
- importedFrom: /@momo-kits\/.+/,
34
- processors: [['count-components', {outputTo: kitJsonPath}]],
35
- rootDir: './',
36
- };
37
-
38
- const config2 = {
39
- crawlFrom: scanPath,
40
- includeSubComponents: true,
41
- processors: [['count-components', {outputTo: miniappJsonPath}]],
42
- rootDir: './',
43
- };
44
-
45
- await scan(config1);
46
- await scan(config2);
47
-
48
- calculateAdoptionRate(kitJsonPath, miniappJsonPath);
74
+ const rootPath = `${__dirname}/../../../`
75
+ const branchName = process.argv[2] || "";
76
+ const removedHead = branchName.replace("remotes/origin/", "");
77
+ const removedTail = removedHead.replace("/master", "");
78
+ const scanPath = path.join(rootPath, 'src')
79
+ const kitJsonPath = path.join(rootPath, './scan/kit.json')
80
+ const miniappJsonPath = path.join(rootPath, './scan/miniapp.json')
81
+ const reactNativeJsonPath = path.join(rootPath, './scan/RN.json')
82
+ const fsJsonPath = path.join(rootPath, './scan/verLib.json')
83
+
84
+ const allKitsReg = /@momo-kits/;
85
+ const fsReg = /^(?:@fs-mobile-platform\/(components|investment|screens)|@miniapp-platform\/(components|foundation))$/;
86
+ const RNReg = 'react-native'
87
+
88
+ const config1 = {
89
+ crawlFrom: scanPath,
90
+ includeSubComponents: true,
91
+ importedFrom: allKitsReg,
92
+ processors: [['count-components', { outputTo: kitJsonPath }]],
93
+ rootDir: process.cwd(),
94
+ };
95
+
96
+ const config2 = {
97
+ crawlFrom: scanPath,
98
+ includeSubComponents: true,
99
+ processors: [['count-components', { outputTo: miniappJsonPath }]],
100
+ rootDir: process.cwd(),
101
+ };
102
+
103
+ const config3 = {
104
+ crawlFrom: scanPath,
105
+ includeSubComponents: true,
106
+ importedFrom: RNReg,
107
+ processors: [['count-components', { outputTo: reactNativeJsonPath }]],
108
+ rootDir: process.cwd(),
109
+ };
110
+
111
+ const config4 = {
112
+ crawlFrom: scanPath,
113
+ includeSubComponents: true,
114
+ importedFrom: fsReg,
115
+ processors: [['count-components', { outputTo: fsJsonPath }]],
116
+ rootDir: process.cwd(),
117
+ };
118
+
119
+ try {
120
+ ensureFileExists(kitJsonPath, {});
121
+ ensureFileExists(miniappJsonPath, {});
122
+ ensureFileExists(reactNativeJsonPath, {});
123
+ ensureFileExists(fsJsonPath, {});
124
+
125
+ await scan(config1);
126
+ await scan(config2);
127
+ await scan(config3);
128
+ await scan(config4);
129
+
130
+ const result = await calculateAdoptionRate(removedTail, kitJsonPath, miniappJsonPath, reactNativeJsonPath, fsJsonPath);
131
+ sendMessage(result)
132
+ console.log(result)
133
+ } catch (error) {
134
+ console.error("Error during scan or calculation:", error);
135
+ }
49
136
  };
50
137
 
51
- main().catch(console.error);
138
+ main();