From 498bfe67b40a80bb4b4fb858b71f1e8aefd32fee Mon Sep 17 00:00:00 2001 From: Ahmed Mahmoud <68241710+a7medev@users.noreply.github.com> Date: Wed, 13 Dec 2023 18:58:03 +0200 Subject: [PATCH 01/30] feat(example): add user steps demos (#1047) Jira ID: IBGCRASH-20289 --- examples/default/babel.config.js | 1 + examples/default/index.js | 1 + examples/default/ios/Podfile.lock | 46 ++++++ examples/default/package.json | 3 + examples/default/src/App.tsx | 20 ++- examples/default/src/components/Screen.tsx | 2 +- examples/default/src/components/Section.tsx | 20 +++ examples/default/src/images/logo.png | Bin 0 -> 86249 bytes examples/default/src/navigation/HomeStack.tsx | 38 +++++ examples/default/src/screens/HomeScreen.tsx | 1 + .../user-steps/BasicComponentsScreen.tsx | 134 ++++++++++++++++++ .../src/screens/user-steps/FlatListScreen.tsx | 38 +++++ .../src/screens/user-steps/GesturesScreen.tsx | 93 ++++++++++++ .../screens/user-steps/ScrollViewScreen.tsx | 37 +++++ .../screens/user-steps/SectionListScreen.tsx | 40 ++++++ .../screens/user-steps/UserStepsScreen.tsx | 20 +++ examples/default/src/utils/createList.ts | 3 + .../default/src/utils/useDelayedRefresh.ts | 18 +++ examples/default/yarn.lock | 118 ++++++++++++++- 19 files changed, 623 insertions(+), 10 deletions(-) create mode 100644 examples/default/src/components/Section.tsx create mode 100644 examples/default/src/images/logo.png create mode 100644 examples/default/src/screens/user-steps/BasicComponentsScreen.tsx create mode 100644 examples/default/src/screens/user-steps/FlatListScreen.tsx create mode 100644 examples/default/src/screens/user-steps/GesturesScreen.tsx create mode 100644 examples/default/src/screens/user-steps/ScrollViewScreen.tsx create mode 100644 examples/default/src/screens/user-steps/SectionListScreen.tsx create mode 100644 examples/default/src/screens/user-steps/UserStepsScreen.tsx create mode 100644 examples/default/src/utils/createList.ts create mode 100644 examples/default/src/utils/useDelayedRefresh.ts diff --git a/examples/default/babel.config.js b/examples/default/babel.config.js index f842b77fcf..983e075de7 100644 --- a/examples/default/babel.config.js +++ b/examples/default/babel.config.js @@ -1,3 +1,4 @@ module.exports = { presets: ['module:metro-react-native-babel-preset'], + plugins: ['react-native-reanimated/plugin'], }; diff --git a/examples/default/index.js b/examples/default/index.js index ab752cb6e3..9733db05ea 100644 --- a/examples/default/index.js +++ b/examples/default/index.js @@ -1,3 +1,4 @@ +import 'react-native-gesture-handler'; import { AppRegistry } from 'react-native'; import { name as appName } from './app.json'; diff --git a/examples/default/ios/Podfile.lock b/examples/default/ios/Podfile.lock index 4e63cac81d..4ba008d477 100644 --- a/examples/default/ios/Podfile.lock +++ b/examples/default/ios/Podfile.lock @@ -379,6 +379,8 @@ PODS: - glog - react-native-safe-area-context (4.7.1): - React-Core + - react-native-slider (4.4.3): + - React-Core - React-NativeModulesApple (0.72.3): - hermes-engine - React-callinvoker @@ -489,9 +491,41 @@ PODS: - React-jsi (= 0.72.3) - React-logger (= 0.72.3) - React-perflogger (= 0.72.3) + - RNGestureHandler (2.13.4): + - RCT-Folly (= 2021.07.22.00) + - React-Core - RNInstabug (12.4.0): - Instabug (= 12.4.0) - React-Core + - RNReanimated (3.5.4): + - DoubleConversion + - FBLazyVector + - glog + - hermes-engine + - RCT-Folly + - RCTRequired + - RCTTypeSafety + - React-callinvoker + - React-Core + - React-Core/DevSupport + - React-Core/RCTWebSocket + - React-CoreModules + - React-cxxreact + - React-hermes + - React-jsi + - React-jsiexecutor + - React-jsinspector + - React-RCTActionSheet + - React-RCTAnimation + - React-RCTAppDelegate + - React-RCTBlob + - React-RCTImage + - React-RCTLinking + - React-RCTNetwork + - React-RCTSettings + - React-RCTText + - ReactCommon/turbomodule/core + - Yoga - RNScreens (3.24.0): - React-Core - React-RCTImage @@ -552,6 +586,7 @@ DEPENDENCIES: - React-jsinspector (from `../node_modules/react-native/ReactCommon/jsinspector`) - React-logger (from `../node_modules/react-native/ReactCommon/logger`) - react-native-safe-area-context (from `../node_modules/react-native-safe-area-context`) + - "react-native-slider (from `../node_modules/@react-native-community/slider`)" - React-NativeModulesApple (from `../node_modules/react-native/ReactCommon/react/nativemodule/core/platform/ios`) - React-perflogger (from `../node_modules/react-native/ReactCommon/reactperflogger`) - React-RCTActionSheet (from `../node_modules/react-native/Libraries/ActionSheetIOS`) @@ -569,7 +604,9 @@ DEPENDENCIES: - React-runtimescheduler (from `../node_modules/react-native/ReactCommon/react/renderer/runtimescheduler`) - React-utils (from `../node_modules/react-native/ReactCommon/react/utils`) - ReactCommon/turbomodule/core (from `../node_modules/react-native/ReactCommon`) + - RNGestureHandler (from `../node_modules/react-native-gesture-handler`) - RNInstabug (from `../node_modules/instabug-reactnative`) + - RNReanimated (from `../node_modules/react-native-reanimated`) - RNScreens (from `../node_modules/react-native-screens`) - RNSVG (from `../node_modules/react-native-svg`) - RNVectorIcons (from `../node_modules/react-native-vector-icons`) @@ -640,6 +677,8 @@ EXTERNAL SOURCES: :path: "../node_modules/react-native/ReactCommon/logger" react-native-safe-area-context: :path: "../node_modules/react-native-safe-area-context" + react-native-slider: + :path: "../node_modules/@react-native-community/slider" React-NativeModulesApple: :path: "../node_modules/react-native/ReactCommon/react/nativemodule/core/platform/ios" React-perflogger: @@ -674,8 +713,12 @@ EXTERNAL SOURCES: :path: "../node_modules/react-native/ReactCommon/react/utils" ReactCommon: :path: "../node_modules/react-native/ReactCommon" + RNGestureHandler: + :path: "../node_modules/react-native-gesture-handler" RNInstabug: :path: "../node_modules/instabug-reactnative" + RNReanimated: + :path: "../node_modules/react-native-reanimated" RNScreens: :path: "../node_modules/react-native-screens" RNSVG: @@ -722,6 +765,7 @@ SPEC CHECKSUMS: React-jsinspector: b511447170f561157547bc0bef3f169663860be7 React-logger: c5b527272d5f22eaa09bb3c3a690fee8f237ae95 react-native-safe-area-context: 9697629f7b2cda43cf52169bb7e0767d330648c2 + react-native-slider: 1cdd6ba29675df21f30544253bf7351d3c2d68c4 React-NativeModulesApple: c57f3efe0df288a6532b726ad2d0322a9bf38472 React-perflogger: 6bd153e776e6beed54c56b0847e1220a3ff92ba5 React-RCTActionSheet: c0b62af44e610e69d9a2049a682f5dba4e9dff17 @@ -739,7 +783,9 @@ SPEC CHECKSUMS: React-runtimescheduler: 837c1bebd2f84572db17698cd702ceaf585b0d9a React-utils: bcb57da67eec2711f8b353f6e3d33bd8e4b2efa3 ReactCommon: 3ccb8fb14e6b3277e38c73b0ff5e4a1b8db017a9 + RNGestureHandler: 6e46dde1f87e5f018a54fe5d40cd0e0b942b49ee RNInstabug: ae604474d8e74d7bd2bee96ccbcfd9d7e12a61fe + RNReanimated: ab2e96c6d5591c3dfbb38a464f54c8d17fb34a87 RNScreens: b21dc57dfa2b710c30ec600786a3fc223b1b92e7 RNSVG: 80584470ff1ffc7994923ea135a3e5ad825546b9 RNVectorIcons: 8b5bb0fa61d54cd2020af4f24a51841ce365c7e9 diff --git a/examples/default/package.json b/examples/default/package.json index 26592d3f75..6a8ed709b0 100644 --- a/examples/default/package.json +++ b/examples/default/package.json @@ -9,6 +9,7 @@ "lint": "eslint ." }, "dependencies": { + "@react-native-community/slider": "^4.4.3", "@react-navigation/bottom-tabs": "^6.5.7", "@react-navigation/native": "^6.1.6", "@react-navigation/native-stack": "^6.9.12", @@ -16,6 +17,8 @@ "native-base": "^3.4.28", "react": "18.2.0", "react-native": "0.72.3", + "react-native-gesture-handler": "^2.13.4", + "react-native-reanimated": "^3.5.4", "react-native-safe-area-context": "^4.5.3", "react-native-screens": "^3.20.0", "react-native-svg": "^13.9.0", diff --git a/examples/default/src/App.tsx b/examples/default/src/App.tsx index fbd116e5aa..6dff03618d 100644 --- a/examples/default/src/App.tsx +++ b/examples/default/src/App.tsx @@ -1,5 +1,7 @@ import React, { useEffect } from 'react'; +import { StyleSheet } from 'react-native'; +import { GestureHandlerRootView } from 'react-native-gesture-handler'; import { NavigationContainer } from '@react-navigation/native'; import Instabug, { InvocationEvent, LogLevel } from 'instabug-reactnative'; import { NativeBaseProvider } from 'native-base'; @@ -18,10 +20,18 @@ export const App: React.FC = () => { }, []); return ( - - - - - + + + + + + + ); }; + +const styles = StyleSheet.create({ + root: { + flex: 1, + }, +}); diff --git a/examples/default/src/components/Screen.tsx b/examples/default/src/components/Screen.tsx index 63745b8cbe..c0f296aaa8 100644 --- a/examples/default/src/components/Screen.tsx +++ b/examples/default/src/components/Screen.tsx @@ -4,7 +4,7 @@ import { VStack } from 'native-base'; export const Screen: React.FC = ({ children }) => { return ( - + {children} ); diff --git a/examples/default/src/components/Section.tsx b/examples/default/src/components/Section.tsx new file mode 100644 index 0000000000..eed7586e2b --- /dev/null +++ b/examples/default/src/components/Section.tsx @@ -0,0 +1,20 @@ +import React from 'react'; +import { Heading, VStack } from 'native-base'; + +interface SectionProps { + title: string; + flex?: number; + children?: React.ReactNode; +} + +export const Section: React.FC = ({ title, flex, children }) => { + return ( + + + {title} + + + {children} + + ); +}; diff --git a/examples/default/src/images/logo.png b/examples/default/src/images/logo.png new file mode 100644 index 0000000000000000000000000000000000000000..4d71f0134cab6ac5c50752cf93a65142090e8db2 GIT binary patch literal 86249 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 @@ -41,6 +53,32 @@ export const HomeStackNavigator: React.FC = () => { /> + + + + + + ); }; diff --git a/examples/default/src/screens/HomeScreen.tsx b/examples/default/src/screens/HomeScreen.tsx index cf74a1d435..8ec8bd65f7 100644 --- a/examples/default/src/screens/HomeScreen.tsx +++ b/examples/default/src/screens/HomeScreen.tsx @@ -16,6 +16,7 @@ export const HomeScreen: React.FC navigation.navigate('FeatureRequests')} /> navigation.navigate('Replies')} /> navigation.navigate('Surveys')} /> + navigation.navigate('UserSteps')} /> ); }; diff --git a/examples/default/src/screens/user-steps/BasicComponentsScreen.tsx b/examples/default/src/screens/user-steps/BasicComponentsScreen.tsx new file mode 100644 index 0000000000..4149ad5e80 --- /dev/null +++ b/examples/default/src/screens/user-steps/BasicComponentsScreen.tsx @@ -0,0 +1,134 @@ +import React, { useState } from 'react'; +import { + Alert, + Button, + Image, + Pressable, + StyleSheet, + Text, + TextInput, + TouchableOpacity, + Switch, + useWindowDimensions, + ActivityIndicator, +} from 'react-native'; +import Slider from '@react-native-community/slider'; +import { Center, HStack, ScrollView, VStack } from 'native-base'; + +import { Screen } from '../../components/Screen'; +import { Section } from '../../components/Section'; +import { nativeBaseTheme } from '../../theme/nativeBaseTheme'; + +/** + * A screen that demonstates the usage of user steps with basic React Native components. + * + * This specific screen doesn't use NativeBase in some parts since we need to focus on + * capturing React Native provided components rather than implementations built on top of it. + */ +export const BasicComponentsScreen: React.FC = () => { + const [isSwitchOn, setIsSwitchOn] = useState(false); + const { width } = useWindowDimensions(); + + const onPress = (label: string) => { + return () => { + Alert.alert(`Pressed "${label}"`); + }; + }; + + return ( + + +
+ + Lorem ipsum, dolor sit amet consectetur adipisicing elit. Alias tempore inventore quas + cum cupiditate ratione, iusto itaque natus maiores fugit. + +
+ +
+
+ +
+
+ +
+ +
+ +
+ +
+ +
+ + + Is Switch On + +
+ +
+ +
+ +
+ +
+
+
+ ); +}; + +const formControlStyles = StyleSheet.create({ + formControl: { + paddingVertical: 16, + paddingHorizontal: 24, + fontSize: 16, + borderRadius: 5, + }, +}); + +const styles = StyleSheet.create({ + text: { + fontSize: 16, + lineHeight: 24, + }, + image: { + resizeMode: 'contain', + }, + textInput: StyleSheet.flatten([ + formControlStyles.formControl, + { + backgroundColor: 'white', + borderWidth: 1, + borderColor: '#ccc', + }, + ]), + buttonText: { + color: 'white', + textAlign: 'center', + fontWeight: 'bold', + }, + button: StyleSheet.flatten([ + formControlStyles.formControl, + { + backgroundColor: nativeBaseTheme.colors.primary[600], + }, + ]), +}); diff --git a/examples/default/src/screens/user-steps/FlatListScreen.tsx b/examples/default/src/screens/user-steps/FlatListScreen.tsx new file mode 100644 index 0000000000..7ab8caa2ef --- /dev/null +++ b/examples/default/src/screens/user-steps/FlatListScreen.tsx @@ -0,0 +1,38 @@ +import React from 'react'; +import { FlatList, RefreshControl } from 'react-native'; +import { Skeleton } from 'native-base'; + +import { Screen } from '../../components/Screen'; +import { Section } from '../../components/Section'; +import { createList } from '../../utils/createList'; +import { useDelayedRefresh } from '../../utils/useDelayedRefresh'; + +export const FlatListScreen: React.FC = () => { + const { refreshing, onRefresh } = useDelayedRefresh(); + + return ( + +
+ item.toString()} + renderItem={() => ( + + )} + /> +
+ +
+ } + data={createList(20)} + keyExtractor={(item) => item.toString()} + renderItem={() => ( + + )} + /> +
+
+ ); +}; diff --git a/examples/default/src/screens/user-steps/GesturesScreen.tsx b/examples/default/src/screens/user-steps/GesturesScreen.tsx new file mode 100644 index 0000000000..655a85b8de --- /dev/null +++ b/examples/default/src/screens/user-steps/GesturesScreen.tsx @@ -0,0 +1,93 @@ +import React from 'react'; +import { Alert, ScrollView } from 'react-native'; + +import Animated, { runOnJS, useAnimatedStyle, useSharedValue } from 'react-native-reanimated'; +import { Gesture, GestureDetector, Swipeable } from 'react-native-gesture-handler'; +import { Box, Center, Text } from 'native-base'; + +import { Screen } from '../../components/Screen'; +import { Section } from '../../components/Section'; + +const AnimatedBox = Animated.createAnimatedComponent(Box); + +export const GesturesScreen: React.FC = () => { + const showAlert = (message: string) => { + Alert.alert(message); + }; + + const tapGesture = Gesture.Tap() + .maxDuration(250) + .onStart(() => { + runOnJS(showAlert)('Tapped.'); + }); + + const doubleTapGesture = Gesture.Tap() + .maxDuration(250) + .numberOfTaps(2) + .onStart(() => { + runOnJS(showAlert)('Double tapped.'); + }); + + const scale = useSharedValue(1); + const savedScale = useSharedValue(1); + const pinchGesture = Gesture.Pinch() + .onUpdate((e) => { + scale.value = savedScale.value * e.scale; + }) + .onEnd(() => { + savedScale.value = scale.value; + }); + const pinchStyle = useAnimatedStyle(() => ({ transform: [{ scale: scale.value }] })); + + return ( + + +
+ +
+ + Tap + +
+
+
+ +
+ +
+ + Double Tap + +
+
+
+ +
+ } + renderRightActions={() => }> +
+ + Swipe + +
+
+
+ +
+
+ + + +
+
+
+
+ ); +}; diff --git a/examples/default/src/screens/user-steps/ScrollViewScreen.tsx b/examples/default/src/screens/user-steps/ScrollViewScreen.tsx new file mode 100644 index 0000000000..f0eab8e3ff --- /dev/null +++ b/examples/default/src/screens/user-steps/ScrollViewScreen.tsx @@ -0,0 +1,37 @@ +import React from 'react'; + +import { Screen } from '../../components/Screen'; +import { RefreshControl, ScrollView } from 'react-native'; +import { VStack, Skeleton, HStack } from 'native-base'; +import { createList } from '../../utils/createList'; +import { Section } from '../../components/Section'; +import { useDelayedRefresh } from '../../utils/useDelayedRefresh'; + +export const ScrollViewScreen: React.FC = () => { + const { refreshing, onRefresh } = useDelayedRefresh(); + + return ( + +
+ + + {createList(10).map((num) => ( + + ))} + + +
+ +
+ }> + + {createList(20).map((num) => ( + + ))} + + +
+
+ ); +}; diff --git a/examples/default/src/screens/user-steps/SectionListScreen.tsx b/examples/default/src/screens/user-steps/SectionListScreen.tsx new file mode 100644 index 0000000000..f392129b08 --- /dev/null +++ b/examples/default/src/screens/user-steps/SectionListScreen.tsx @@ -0,0 +1,40 @@ +import React from 'react'; +import { RefreshControl, SectionList } from 'react-native'; +import { Heading, Skeleton } from 'native-base'; + +import { Screen } from '../../components/Screen'; +import { createList } from '../../utils/createList'; +import { useDelayedRefresh } from '../../utils/useDelayedRefresh'; + +const sections = [ + { + title: 'Section A', + data: createList(10), + }, + { + title: 'Section B', + data: createList(10), + }, +]; + +export const SectionListScreen: React.FC = () => { + const { refreshing, onRefresh } = useDelayedRefresh(); + + return ( + + } + sections={sections} + keyExtractor={(item) => item.toString()} + renderSectionHeader={(info) => ( + + {info.section.title} + + )} + renderItem={() => ( + + )} + /> + + ); +}; diff --git a/examples/default/src/screens/user-steps/UserStepsScreen.tsx b/examples/default/src/screens/user-steps/UserStepsScreen.tsx new file mode 100644 index 0000000000..219cd5bbd6 --- /dev/null +++ b/examples/default/src/screens/user-steps/UserStepsScreen.tsx @@ -0,0 +1,20 @@ +import React from 'react'; + +import { ListTile } from '../../components/ListTile'; +import { Screen } from '../../components/Screen'; +import type { HomeStackParamList } from '../../navigation/HomeStack'; +import type { NativeStackScreenProps } from '@react-navigation/native-stack'; + +export const UserStepsScreen: React.FC> = ({ + navigation, +}) => { + return ( + + navigation.navigate('BasicComponents')} /> + navigation.navigate('ScrollView')} /> + navigation.navigate('FlatList')} /> + navigation.navigate('SectionList')} /> + navigation.navigate('Gestures')} /> + + ); +}; diff --git a/examples/default/src/utils/createList.ts b/examples/default/src/utils/createList.ts new file mode 100644 index 0000000000..1719c2d75c --- /dev/null +++ b/examples/default/src/utils/createList.ts @@ -0,0 +1,3 @@ +export function createList(length: number) { + return Array.from({ length }, (_, i) => i + 1); +} diff --git a/examples/default/src/utils/useDelayedRefresh.ts b/examples/default/src/utils/useDelayedRefresh.ts new file mode 100644 index 0000000000..813acc0c94 --- /dev/null +++ b/examples/default/src/utils/useDelayedRefresh.ts @@ -0,0 +1,18 @@ +import { useState } from 'react'; + +export function useDelayedRefresh() { + const [refreshing, setIsRefreshing] = useState(false); + + const onRefresh = () => { + if (refreshing) { + return; + } + + setIsRefreshing(true); + setTimeout(() => { + setIsRefreshing(false); + }, 1000); + }; + + return { refreshing, onRefresh }; +} diff --git a/examples/default/yarn.lock b/examples/default/yarn.lock index 9a695546a7..3ac196cf5a 100644 --- a/examples/default/yarn.lock +++ b/examples/default/yarn.lock @@ -93,7 +93,7 @@ "@babel/helper-split-export-declaration" "^7.22.6" semver "^6.3.1" -"@babel/helper-create-class-features-plugin@^7.22.11": +"@babel/helper-create-class-features-plugin@^7.22.11", "@babel/helper-create-class-features-plugin@^7.22.15": version "7.22.15" resolved "https://registry.yarnpkg.com/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.22.15.tgz#97a61b385e57fe458496fad19f8e63b63c867de4" integrity sha512-jKkwA59IXcvSaiK2UN45kKwSC9o+KuoXsBDvHvU/7BecYIp8GQ2UwrVvFgJASUT+hBnwJx6MhvMCuMzwZZ7jlg== @@ -133,6 +133,11 @@ resolved "https://registry.yarnpkg.com/@babel/helper-environment-visitor/-/helper-environment-visitor-7.22.5.tgz#f06dd41b7c1f44e1f8da6c4055b41ab3a09a7e98" integrity sha512-XGmhECfVA/5sAt+H+xpSg0mfrHq6FzNr9Oxh7PSEBBRUb/mL7Kz3NICXb194rCqAEdxkhPT1a88teizAFyvk8Q== +"@babel/helper-environment-visitor@^7.22.20": + version "7.22.20" + resolved "https://registry.yarnpkg.com/@babel/helper-environment-visitor/-/helper-environment-visitor-7.22.20.tgz#96159db61d34a29dba454c959f5ae4a649ba9167" + integrity sha512-zfedSIzFhat/gFhWfHtgWvlec0nqB9YEIVrpuwjruLlXfUSnA8cJB0miHKwqDnQ7d32aKo2xt88/xZptwxbfhA== + "@babel/helper-function-name@^7.22.5": version "7.22.5" resolved "https://registry.yarnpkg.com/@babel/helper-function-name/-/helper-function-name-7.22.5.tgz#ede300828905bb15e582c037162f99d5183af1be" @@ -162,6 +167,13 @@ dependencies: "@babel/types" "^7.22.5" +"@babel/helper-module-imports@^7.22.15": + version "7.22.15" + resolved "https://registry.yarnpkg.com/@babel/helper-module-imports/-/helper-module-imports-7.22.15.tgz#16146307acdc40cc00c3b2c647713076464bdbf0" + integrity sha512-0pYVBnDKZO2fnSPCrgM/6WMc7eS20Fbok+0r88fp+YtWVLZrp4CkafFGIp+W0VKw4a22sgebPT99y+FDNMdP4w== + dependencies: + "@babel/types" "^7.22.15" + "@babel/helper-module-imports@^7.22.5": version "7.22.5" resolved "https://registry.yarnpkg.com/@babel/helper-module-imports/-/helper-module-imports-7.22.5.tgz#1a8f4c9f4027d23f520bd76b364d44434a72660c" @@ -180,6 +192,17 @@ "@babel/helper-split-export-declaration" "^7.22.6" "@babel/helper-validator-identifier" "^7.22.5" +"@babel/helper-module-transforms@^7.23.0": + version "7.23.0" + resolved "https://registry.yarnpkg.com/@babel/helper-module-transforms/-/helper-module-transforms-7.23.0.tgz#3ec246457f6c842c0aee62a01f60739906f7047e" + integrity sha512-WhDWw1tdrlT0gMgUJSlX0IQvoO1eN279zrAUbVB+KpV2c3Tylz8+GnKOLllCS6Z/iZQEyVYxhZVUdPTqs2YYPw== + dependencies: + "@babel/helper-environment-visitor" "^7.22.20" + "@babel/helper-module-imports" "^7.22.15" + "@babel/helper-simple-access" "^7.22.5" + "@babel/helper-split-export-declaration" "^7.22.6" + "@babel/helper-validator-identifier" "^7.22.20" + "@babel/helper-optimise-call-expression@^7.22.5": version "7.22.5" resolved "https://registry.yarnpkg.com/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.22.5.tgz#f21531a9ccbff644fdd156b4077c16ff0c3f609e" @@ -246,6 +269,11 @@ resolved "https://registry.yarnpkg.com/@babel/helper-validator-identifier/-/helper-validator-identifier-7.22.5.tgz#9544ef6a33999343c8740fa51350f30eeaaaf193" integrity sha512-aJXu+6lErq8ltp+JhkJUfk1MTGyuA4v7f3pA+BJ5HLfNC6nAQ0Cpi9uOquUj8Hehg0aUiHzWQbOVJGao6ztBAQ== +"@babel/helper-validator-option@^7.22.15": + version "7.22.15" + resolved "https://registry.yarnpkg.com/@babel/helper-validator-option/-/helper-validator-option-7.22.15.tgz#694c30dfa1d09a6534cdfcafbe56789d36aba040" + integrity sha512-bMn7RmyFjY/mdECUbgn9eoSY4vqvacUnS9i9vGAGttgFWesO6B4CYWA7XlpbWgBt71iv/hfbPlynohStqnu5hA== + "@babel/helper-validator-option@^7.22.5": version "7.22.5" resolved "https://registry.yarnpkg.com/@babel/helper-validator-option/-/helper-validator-option-7.22.5.tgz#de52000a15a177413c8234fa3a8af4ee8102d0ac" @@ -741,6 +769,15 @@ "@babel/helper-plugin-utils" "^7.22.5" "@babel/helper-simple-access" "^7.22.5" +"@babel/plugin-transform-modules-commonjs@^7.23.0": + version "7.23.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.23.0.tgz#b3dba4757133b2762c00f4f94590cf6d52602481" + integrity sha512-32Xzss14/UVc7k9g775yMIvkVK8xwKE0DPdP5JTapr3+Z9w4tzeOuLNY6BXDQR6BdnzIlXnCGAzsk/ICHBLVWQ== + dependencies: + "@babel/helper-module-transforms" "^7.23.0" + "@babel/helper-plugin-utils" "^7.22.5" + "@babel/helper-simple-access" "^7.22.5" + "@babel/plugin-transform-modules-systemjs@^7.22.5": version "7.22.5" resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-systemjs/-/plugin-transform-modules-systemjs-7.22.5.tgz#18c31410b5e579a0092638f95c896c2a98a5d496" @@ -790,6 +827,13 @@ "@babel/helper-plugin-utils" "^7.22.5" "@babel/plugin-syntax-numeric-separator" "^7.10.4" +"@babel/plugin-transform-object-assign@^7.16.7": + version "7.22.5" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-object-assign/-/plugin-transform-object-assign-7.22.5.tgz#290c1b9555dcea48bb2c29ad94237777600d04f9" + integrity sha512-iDhx9ARkXq4vhZ2CYOSnQXkmxkDgosLi3J8Z17mKz7LyzthtkdVchLD7WZ3aXeCuvJDOW3+1I5TpJmwIbF9MKQ== + dependencies: + "@babel/helper-plugin-utils" "^7.22.5" + "@babel/plugin-transform-object-rest-spread@^7.22.5": version "7.22.5" resolved "https://registry.yarnpkg.com/@babel/plugin-transform-object-rest-spread/-/plugin-transform-object-rest-spread-7.22.5.tgz#9686dc3447df4753b0b2a2fae7e8bc33cdc1f2e1" @@ -963,6 +1007,16 @@ dependencies: "@babel/helper-plugin-utils" "^7.22.5" +"@babel/plugin-transform-typescript@^7.22.15": + version "7.22.15" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-typescript/-/plugin-transform-typescript-7.22.15.tgz#15adef906451d86349eb4b8764865c960eb54127" + integrity sha512-1uirS0TnijxvQLnlv5wQBwOX3E1wCFX7ITv+9pBV2wKEk4K+M5tqDaoNXnTH8tjEIYHLO98MwiTWO04Ggz4XuA== + dependencies: + "@babel/helper-annotate-as-pure" "^7.22.5" + "@babel/helper-create-class-features-plugin" "^7.22.15" + "@babel/helper-plugin-utils" "^7.22.5" + "@babel/plugin-syntax-typescript" "^7.22.5" + "@babel/plugin-transform-typescript@^7.22.5", "@babel/plugin-transform-typescript@^7.5.0": version "7.22.9" resolved "https://registry.yarnpkg.com/@babel/plugin-transform-typescript/-/plugin-transform-typescript-7.22.9.tgz#91e08ad1eb1028ecc62662a842e93ecfbf3c7234" @@ -1121,6 +1175,17 @@ "@babel/plugin-transform-modules-commonjs" "^7.22.5" "@babel/plugin-transform-typescript" "^7.22.5" +"@babel/preset-typescript@^7.16.7": + version "7.23.2" + resolved "https://registry.yarnpkg.com/@babel/preset-typescript/-/preset-typescript-7.23.2.tgz#c8de488130b7081f7e1482936ad3de5b018beef4" + integrity sha512-u4UJc1XsS1GhIGteM8rnGiIvf9rJpiVgMEeCnwlLA7WJPC+jcXWJAGxYmeqs5hOZD8BbAfnV5ezBOxQbb4OUxA== + dependencies: + "@babel/helper-plugin-utils" "^7.22.5" + "@babel/helper-validator-option" "^7.22.15" + "@babel/plugin-syntax-jsx" "^7.22.5" + "@babel/plugin-transform-modules-commonjs" "^7.23.0" + "@babel/plugin-transform-typescript" "^7.22.15" + "@babel/register@^7.13.16": version "7.22.5" resolved "https://registry.yarnpkg.com/@babel/register/-/register-7.22.5.tgz#e4d8d0f615ea3233a27b5c6ada6750ee59559939" @@ -1178,7 +1243,7 @@ "@babel/helper-validator-identifier" "^7.22.5" to-fast-properties "^2.0.0" -"@babel/types@^7.23.0": +"@babel/types@^7.22.15", "@babel/types@^7.23.0": version "7.23.0" resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.23.0.tgz#8c1f020c9df0e737e4e247c0619f58c68458aaeb" integrity sha512-0oIyUfKoI3mSqMvsxBdclDwxXKXAUA8v/apZbc+iSyARYou1o8ZGDxbUYyLFoW2arqS2jDGqJuZvv1d/io1axg== @@ -1192,6 +1257,13 @@ resolved "https://registry.yarnpkg.com/@bcoe/v8-coverage/-/v8-coverage-0.2.3.tgz#75a2e8b51cb758a7553d6804a5932d7aace75c39" integrity sha512-0hYQ8SB4Db5zvZB4axdMHGwEaQjkZzFjQiN9LVYvIFB2nSUHW9tYpxWriPrWDASIxiaXax83REcLxuSdnGPZtw== +"@egjs/hammerjs@^2.0.17": + version "2.0.17" + resolved "https://registry.yarnpkg.com/@egjs/hammerjs/-/hammerjs-2.0.17.tgz#5dc02af75a6a06e4c2db0202cae38c9263895124" + integrity sha512-XQsZgjm2EcVUiZQf11UBJQfmZeEmOW8DpI1gsFeln6w0ae0ii4dMQEQ0kjl6DspdWX1aGY1/loyXnP0JS06e/A== + dependencies: + "@types/hammerjs" "^2.0.36" + "@formatjs/ecma402-abstract@1.17.0": version "1.17.0" resolved "https://registry.yarnpkg.com/@formatjs/ecma402-abstract/-/ecma402-abstract-1.17.0.tgz#2ce191a3bde4c65c6684e03fa247062a4a294b9e" @@ -2126,6 +2198,11 @@ prompts "^2.4.0" semver "^6.3.0" +"@react-native-community/slider@^4.4.3": + version "4.4.3" + resolved "https://registry.yarnpkg.com/@react-native-community/slider/-/slider-4.4.3.tgz#9b9dc639b88f5bfda72bd72a9dff55cbf9f777ed" + integrity sha512-WdjvGtqJfqcCiLwtbzie53Z/H6w6dIfRHhlW832D89ySAdE5DxLAsqRhDOG0eacuAxxEB+T9sGCkVMD0fa3aBg== + "@react-native/assets-registry@^0.72.0": version "0.72.0" resolved "https://registry.yarnpkg.com/@react-native/assets-registry/-/assets-registry-0.72.0.tgz#c82a76a1d86ec0c3907be76f7faf97a32bbed05d" @@ -2779,6 +2856,11 @@ dependencies: "@types/node" "*" +"@types/hammerjs@^2.0.36": + version "2.0.43" + resolved "https://registry.yarnpkg.com/@types/hammerjs/-/hammerjs-2.0.43.tgz#8660dd1e0e5fd979395e2f999e670cdb9484d1e9" + integrity sha512-wqxfwHk83RS7+6OpytGdo5wqkqtvx+bGaIs1Rwm5NrtQHUfL4OgWs/5p0OipmjmT+fexePh37Ek+mqIpdNjQKA== + "@types/istanbul-lib-coverage@*", "@types/istanbul-lib-coverage@^2.0.0", "@types/istanbul-lib-coverage@^2.0.1": version "2.0.4" resolved "https://registry.yarnpkg.com/@types/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.4.tgz#8467d4b3c087805d63580480890791277ce35c44" @@ -4189,6 +4271,13 @@ hermes-profile-transformer@^0.0.6: dependencies: source-map "^0.7.3" +hoist-non-react-statics@^3.3.0: + version "3.3.2" + resolved "https://registry.yarnpkg.com/hoist-non-react-statics/-/hoist-non-react-statics-3.3.2.tgz#ece0acaf71d62c2969c2ec59feff42a4b1a85b45" + integrity sha512-/gGivxi8JPKWNm/W0jSmzcMPpfpPLc3dY/6GxhX2hQ9iGj3aDfklV4ET7NjKpSinLpJ5vafa9iiGIEZg10SfBw== + dependencies: + react-is "^16.7.0" + html-escaper@^2.0.0: version "2.0.2" resolved "https://registry.yarnpkg.com/html-escaper/-/html-escaper-2.0.2.tgz#dfd60027da36a36dfcbe236262c00a5822681453" @@ -5071,7 +5160,7 @@ lodash.uniqueid@^4.0.1: resolved "https://registry.yarnpkg.com/lodash.uniqueid/-/lodash.uniqueid-4.0.1.tgz#3268f26a7c88e4f4b1758d679271814e31fa5b26" integrity sha512-GQQWaIeGlL6DIIr06kj1j6sSmBxyNMwI8kaX9aKpHR/XsMTiaXDVPNPAkiboOTK9OJpTJF/dXT3xYoFQnj386Q== -lodash@^4.17.11: +lodash@^4.17.11, lodash@^4.17.21: version "4.17.21" resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.21.tgz#679591c564c3bffaae8454cf0b3df370c3d6911c" integrity sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg== @@ -6230,7 +6319,7 @@ react-freeze@^1.0.0: resolved "https://registry.yarnpkg.com/react-is/-/react-is-18.2.0.tgz#199431eeaaa2e09f86427efbb4f1473edb47609b" integrity sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w== -react-is@^16.13.0, react-is@^16.13.1: +react-is@^16.13.0, react-is@^16.13.1, react-is@^16.7.0: version "16.13.1" resolved "https://registry.yarnpkg.com/react-is/-/react-is-16.13.1.tgz#789729a4dc36de2999dc156dd6c1d9c18cea56a4" integrity sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ== @@ -6240,6 +6329,27 @@ react-is@^17.0.1: resolved "https://registry.yarnpkg.com/react-is/-/react-is-17.0.2.tgz#e691d4a8e9c789365655539ab372762b0efb54f0" integrity sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w== +react-native-gesture-handler@^2.13.4: + version "2.13.4" + resolved "https://registry.yarnpkg.com/react-native-gesture-handler/-/react-native-gesture-handler-2.13.4.tgz#6a99384330278c4488bcfc7f1814be3e0d7401fd" + integrity sha512-smpYOVbvWABpq2H+lmDnfOLCTH934aUPO1w2/pQXvm1j+M/vmGQmvgRDJOpXcks17HLtNNKXD6tcODf3aPqDfA== + dependencies: + "@egjs/hammerjs" "^2.0.17" + hoist-non-react-statics "^3.3.0" + invariant "^2.2.4" + lodash "^4.17.21" + prop-types "^15.7.2" + +react-native-reanimated@^3.5.4: + version "3.5.4" + resolved "https://registry.yarnpkg.com/react-native-reanimated/-/react-native-reanimated-3.5.4.tgz#a6c2b0c43b6dad246f5d276213974afedb8e3fc7" + integrity sha512-8we9LLDO1o4Oj9/DICeEJ2K1tjfqkJagqQUglxeUAkol/HcEJ6PGxIrpBcNryLqCDYEcu6FZWld/FzizBIw6bg== + dependencies: + "@babel/plugin-transform-object-assign" "^7.16.7" + "@babel/preset-typescript" "^7.16.7" + convert-source-map "^2.0.0" + invariant "^2.2.4" + react-native-safe-area-context@^4.5.3: version "4.7.1" resolved "https://registry.yarnpkg.com/react-native-safe-area-context/-/react-native-safe-area-context-4.7.1.tgz#b7be2d68dee909717cfa439bb5c7966042d231e8" From 8675d6f338e9da9f931fbb22a273a683a371dff2 Mon Sep 17 00:00:00 2001 From: Abdelhamid Nasser <38096011+abdelhamid-f-nasser@users.noreply.github.com> Date: Sun, 7 Jan 2024 15:21:11 +0200 Subject: [PATCH 02/30] docs: update changelog headers for date and compare link fixes (#1063) Jira ID: MOB-13255 --- CHANGELOG.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index b844d758c6..935609d048 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,6 @@ # Changelog -## [12.4.0](https://github.com/Instabug/Instabug-React-Native/compare/v12.2.0...v12.4.0) (December 6, 2023) +## [12.4.0](https://github.com/Instabug/Instabug-React-Native/compare/v12.2.0...v12.4.0) (December 7, 2023) ### Changed @@ -12,7 +12,7 @@ - Fix an issue with `Instabug.init` on Android causing the app to crash while trying to get the current `Application` instance through the current activity which can be `null` in some cases by utilizing the React context instead ([#1069](https://github.com/Instabug/Instabug-React-Native/pull/1069)). - Fix an issue with unhandled JavaScript crashes not getting linked with the current session causing inaccurate session metrics ([#1071](https://github.com/Instabug/Instabug-React-Native/pull/1071)). -## [12.2.0](https://github.com/Instabug/Instabug-React-Native/compare/v12.2.0...v12.1.0) +## [12.2.0](https://github.com/Instabug/Instabug-React-Native/compare/v12.1.0...v12.2.0) (November 14, 2023) ### Added @@ -29,7 +29,7 @@ - Fix an issue with unhandled JavaScript crashes being reported as native iOS crashes ([#1054](https://github.com/Instabug/Instabug-React-Native/pull/1054)) - Re-enable screenshot capturing for Crash Reporting and Session Replay by removing redundant mapping ([#1055](https://github.com/Instabug/Instabug-React-Native/pull/1055)). -## [12.1.0](https://github.com/Instabug/Instabug-React-Native/compare/v12.1.0...v11.14.0) +## [12.1.0](https://github.com/Instabug/Instabug-React-Native/compare/v11.14.0...v12.1.0) (October 3, 2023) ### Added From 4c7ce2d6e3370aa3b7f802ee5532ab16fd9e4d40 Mon Sep 17 00:00:00 2001 From: Abdelhamid Nasser <38096011+abdelhamid-f-nasser@users.noreply.github.com> Date: Mon, 8 Jan 2024 15:44:04 +0200 Subject: [PATCH 03/30] chore: fix react native boost install via patch (#1087) Jira ID: MOB-13588 --- examples/default/ios/Podfile.lock | 6 +- examples/default/package.json | 4 +- .../default/patches/react-native+0.72.3.patch | 13 ++ examples/default/yarn.lock | 210 +++++++++++++++++- 4 files changed, 228 insertions(+), 5 deletions(-) create mode 100644 examples/default/patches/react-native+0.72.3.patch diff --git a/examples/default/ios/Podfile.lock b/examples/default/ios/Podfile.lock index 4ba008d477..39064049aa 100644 --- a/examples/default/ios/Podfile.lock +++ b/examples/default/ios/Podfile.lock @@ -75,7 +75,7 @@ PODS: - hermes-engine/Pre-built (0.72.3) - Instabug (12.4.0) - libevent (2.1.12) - - OCMock (3.9.1) + - OCMock (3.9.3) - OpenSSL-Universal (1.1.1100) - RCT-Folly (2021.07.22.00): - boost @@ -729,7 +729,7 @@ EXTERNAL SOURCES: :path: "../node_modules/react-native/ReactCommon/yoga" SPEC CHECKSUMS: - boost: 57d2868c099736d80fcd648bf211b4431e51a558 + boost: 7dcd2de282d72e344012f7d6564d024930a6a440 CocoaAsyncSocket: 065fd1e645c7abab64f7a6a2007a48038fdc6a99 DoubleConversion: 5189b271737e1565bdce30deb4a08d647e3f5f54 FBLazyVector: 4cce221dd782d3ff7c4172167bba09d58af67ccb @@ -747,7 +747,7 @@ SPEC CHECKSUMS: hermes-engine: 10fbd3f62405c41ea07e71973ea61e1878d07322 Instabug: 83bde9d7d4b582ea8f14935f79f1ce39af55e149 libevent: 4049cae6c81cdb3654a443be001fb9bdceff7913 - OCMock: 9491e4bec59e0b267d52a9184ff5605995e74be8 + OCMock: 300b1b1b9155cb6378660b981c2557448830bdc6 OpenSSL-Universal: ebc357f1e6bc71fa463ccb2fe676756aff50e88c RCT-Folly: 424b8c9a7a0b9ab2886ffe9c3b041ef628fd4fb1 RCTRequired: a2faf4bad4e438ca37b2040cb8f7799baa065c18 diff --git a/examples/default/package.json b/examples/default/package.json index 6a8ed709b0..608dd04396 100644 --- a/examples/default/package.json +++ b/examples/default/package.json @@ -6,7 +6,8 @@ "android": "react-native run-android", "ios": "react-native run-ios", "start": "react-native start", - "lint": "eslint ." + "lint": "eslint .", + "postinstall": "patch-package" }, "dependencies": { "@react-native-community/slider": "^4.4.3", @@ -37,6 +38,7 @@ "detox": "^20.9.0", "jest": "^29.2.1", "metro-react-native-babel-preset": "0.77.0", + "patch-package": "^8.0.0", "react-test-renderer": "18.2.0", "ts-jest": "^29.1.0", "typescript": "5.1.6" diff --git a/examples/default/patches/react-native+0.72.3.patch b/examples/default/patches/react-native+0.72.3.patch new file mode 100644 index 0000000000..e8b2e89654 --- /dev/null +++ b/examples/default/patches/react-native+0.72.3.patch @@ -0,0 +1,13 @@ +diff --git a/node_modules/react-native/third-party-podspecs/boost.podspec b/node_modules/react-native/third-party-podspecs/boost.podspec +index 3d9331c..bbbb738 100644 +--- a/node_modules/react-native/third-party-podspecs/boost.podspec ++++ b/node_modules/react-native/third-party-podspecs/boost.podspec +@@ -10,7 +10,7 @@ Pod::Spec.new do |spec| + spec.homepage = 'http://www.boost.org' + spec.summary = 'Boost provides free peer-reviewed portable C++ source libraries.' + spec.authors = 'Rene Rivera' +- spec.source = { :http => 'https://boostorg.jfrog.io/artifactory/main/release/1.76.0/source/boost_1_76_0.tar.bz2', ++ spec.source = { :http => 'https://archives.boost.io/release/1.76.0/source/boost_1_76_0.tar.bz2', + :sha256 => 'f0397ba6e982c4450f27bf32a2a83292aba035b827a5623a14636ea583318c41' } + + # Pinning to the same version as React.podspec. diff --git a/examples/default/yarn.lock b/examples/default/yarn.lock index 3ac196cf5a..f036714d72 100644 --- a/examples/default/yarn.lock +++ b/examples/default/yarn.lock @@ -2965,6 +2965,11 @@ dependencies: "@types/yargs-parser" "*" +"@yarnpkg/lockfile@^1.1.0": + version "1.1.0" + resolved "https://registry.npmjs.org/@yarnpkg/lockfile/-/lockfile-1.1.0.tgz#e77a97fbd345b76d83245edcd17d393b1b41fb31" + integrity sha512-GpSwvyXOcOOlV70vbnzjj4fW5xW/FdUF6nQEt1ENy7m4ZCczi1+/buVUPAqmGfqznsORNFzUMjctTIp8a9tuCQ== + abort-controller@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/abort-controller/-/abort-controller-3.0.0.tgz#eaf54d53b62bae4138e809ca225c8439a6efb392" @@ -3092,6 +3097,11 @@ async@^3.2.2: resolved "https://registry.yarnpkg.com/async/-/async-3.2.4.tgz#2d22e00f8cddeb5fde5dd33522b56d1cf569a81c" integrity sha512-iAB+JbDEGXhyIUavoDl9WP/Jj106Kz9DEn1DPgYw5ruDn0e3Wgi3sKFm55sASdGBNOQB8F59d9qQ7deqrHA8wQ== +at-least-node@^1.0.0: + version "1.0.0" + resolved "https://registry.npmjs.org/at-least-node/-/at-least-node-1.0.0.tgz#602cd4b46e844ad4effc92a8011a3c46e0238dc2" + integrity sha512-+q/t7Ekv1EDY2l6Gda6LLiX14rU9TV20Wa3ofeQmwPFZbOMo9DXrLbOjFaaclkXKWidIaopwAObQDqwWtGUjqg== + babel-core@^7.0.0-bridge.0: version "7.0.0-bridge.0" resolved "https://registry.yarnpkg.com/babel-core/-/babel-core-7.0.0-bridge.0.tgz#95a492ddd90f9b4e9a4a1da14eb335b87b634ece" @@ -3346,6 +3356,15 @@ caf@^15.0.1: resolved "https://registry.yarnpkg.com/caf/-/caf-15.0.1.tgz#28f1f17bd93dc4b5d95207ad07066eddf4768160" integrity sha512-Xp/IK6vMwujxWZXra7djdYzPdPnEQKa7Mudu2wZgDQ3TJry1I0TgtjEgwZHpoBcMp68j4fb0/FZ1SJyMEgJrXQ== +call-bind@^1.0.5: + version "1.0.5" + resolved "https://registry.npmjs.org/call-bind/-/call-bind-1.0.5.tgz#6fa2b7845ce0ea49bf4d8b9ef64727a2c2e2e513" + integrity sha512-C3nQxfFZxFRVoJoGKKI8y3MOEo129NQ+FgQ08iye+Mk4zNZZGdjfs06bVTr+DBSlA66Q2VEcMki/cUCP4SercQ== + dependencies: + function-bind "^1.1.2" + get-intrinsic "^1.2.1" + set-function-length "^1.1.1" + caller-callsite@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/caller-callsite/-/caller-callsite-2.0.0.tgz#847e0fce0a223750a9a027c54b33731ad3154134" @@ -3426,6 +3445,11 @@ ci-info@^3.2.0: resolved "https://registry.yarnpkg.com/ci-info/-/ci-info-3.8.0.tgz#81408265a5380c929f0bc665d62256628ce9ef91" integrity sha512-eXTggHWSooYhq49F2opQhuHWgzucfF2YgODK4e1566GQs5BIfP30B0oenwBJHfWxAs2fyPB1s7Mg949zLf61Yw== +ci-info@^3.7.0: + version "3.9.0" + resolved "https://registry.npmjs.org/ci-info/-/ci-info-3.9.0.tgz#4279a62028a7b1f262f3473fc9605f5e218c59b4" + integrity sha512-NIxF55hv4nSqQswkAeiOi1r83xy8JldOFDTWiug55KBu9Jnblncd2U6ViHmYgHf01TPZS77NJBhBMKdWj9HQMQ== + cjs-module-lexer@^1.0.0: version "1.2.3" resolved "https://registry.yarnpkg.com/cjs-module-lexer/-/cjs-module-lexer-1.2.3.tgz#6c370ab19f8a3394e318fe682686ec0ac684d107" @@ -3740,6 +3764,15 @@ defaults@^1.0.3: dependencies: clone "^1.0.2" +define-data-property@^1.1.1: + version "1.1.1" + resolved "https://registry.npmjs.org/define-data-property/-/define-data-property-1.1.1.tgz#c35f7cd0ab09883480d12ac5cb213715587800b3" + integrity sha512-E7uGkTzkk1d0ByLeSc6ZsFS79Axg+m1P/VsgYsxHgiuc3tFSj+MjMIwe90FC4lOAZzNBdY7kkO2P2wKdsQ1vgQ== + dependencies: + get-intrinsic "^1.2.1" + gopd "^1.0.1" + has-property-descriptors "^1.0.0" + denodeify@^1.2.1: version "1.2.1" resolved "https://registry.yarnpkg.com/denodeify/-/denodeify-1.2.1.tgz#3a36287f5034e699e7577901052c2e6c94251631" @@ -4096,6 +4129,13 @@ find-up@^5.0.0: locate-path "^6.0.0" path-exists "^4.0.0" +find-yarn-workspace-root@^2.0.0: + version "2.0.0" + resolved "https://registry.npmjs.org/find-yarn-workspace-root/-/find-yarn-workspace-root-2.0.0.tgz#f47fb8d239c900eb78179aa81b66673eac88f7bd" + integrity sha512-1IMnbjt4KzsQfnhnzNd8wUEgXZ44IzZaZmnLYx7D5FZlaHt2gW20Cri8Q+E/t5tIj4+epTBub+2Zxu/vNILzqQ== + dependencies: + micromatch "^4.0.2" + flat@^5.0.2: version "5.0.2" resolved "https://registry.yarnpkg.com/flat/-/flat-5.0.2.tgz#8ca6fe332069ffa9d324c327198c598259ceb241" @@ -4139,6 +4179,16 @@ fs-extra@^8.1.0: jsonfile "^4.0.0" universalify "^0.1.0" +fs-extra@^9.0.0: + version "9.1.0" + resolved "https://registry.npmjs.org/fs-extra/-/fs-extra-9.1.0.tgz#5954460c764a8da2094ba3554bf839e6b9a7c86d" + integrity sha512-hcg3ZmepS30/7BSFqRvoo3DOMQu7IjqxO5nCDt+zM9XWjb33Wg7ziNT+Qvqbuc3+gWpzO02JubVyk2G4Zvo1OQ== + dependencies: + at-least-node "^1.0.0" + graceful-fs "^4.2.0" + jsonfile "^6.0.1" + universalify "^2.0.0" + fs.realpath@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/fs.realpath/-/fs.realpath-1.0.0.tgz#1504ad2523158caa40db4a2787cb01411994ea4f" @@ -4154,6 +4204,11 @@ function-bind@^1.1.1: resolved "https://registry.yarnpkg.com/function-bind/-/function-bind-1.1.1.tgz#a56899d3ea3c9bab874bb9773b7c5ede92f4895d" integrity sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A== +function-bind@^1.1.2: + version "1.1.2" + resolved "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz#2c02d864d97f3ea6c8830c464cbd11ab6eab7a1c" + integrity sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA== + funpermaproxy@^1.1.0: version "1.1.0" resolved "https://registry.yarnpkg.com/funpermaproxy/-/funpermaproxy-1.1.0.tgz#39cb0b8bea908051e4608d8a414f1d87b55bf557" @@ -4169,6 +4224,16 @@ get-caller-file@^2.0.1, get-caller-file@^2.0.5: resolved "https://registry.yarnpkg.com/get-caller-file/-/get-caller-file-2.0.5.tgz#4f94412a82db32f36e3b0b9741f8a97feb031f7e" integrity sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg== +get-intrinsic@^1.1.3, get-intrinsic@^1.2.1, get-intrinsic@^1.2.2: + version "1.2.2" + resolved "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.2.2.tgz#281b7622971123e1ef4b3c90fd7539306da93f3b" + integrity sha512-0gSo4ml/0j98Y3lngkFEot/zhiCeWsbYIlZ+uZOVgzLyLaUw7wxUL+nCTP0XJvJg1AXulJRI3UJi8GsbDuxdGA== + dependencies: + function-bind "^1.1.2" + has-proto "^1.0.1" + has-symbols "^1.0.3" + hasown "^2.0.0" + get-package-type@^0.1.0: version "0.1.0" resolved "https://registry.yarnpkg.com/get-package-type/-/get-package-type-0.1.0.tgz#8de2d803cff44df3bc6c456e6668b36c3926e11a" @@ -4218,6 +4283,13 @@ globals@^11.1.0: resolved "https://registry.yarnpkg.com/globals/-/globals-11.12.0.tgz#ab8795338868a0babd8525758018c2a7eb95c42e" integrity sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA== +gopd@^1.0.1: + version "1.0.1" + resolved "https://registry.npmjs.org/gopd/-/gopd-1.0.1.tgz#29ff76de69dac7489b7c0918a5788e56477c332c" + integrity sha512-d65bNlIadxvpb/A2abVdlqKqV563juRnZ1Wtk6s1sIR8uNsXR70xqIzVqxVf1eTqDunwT2MkczEeaezCKTZhwA== + dependencies: + get-intrinsic "^1.1.3" + graceful-fs@^4.1.11, graceful-fs@^4.1.3, graceful-fs@^4.1.6, graceful-fs@^4.2.0, graceful-fs@^4.2.4, graceful-fs@^4.2.9: version "4.2.11" resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.2.11.tgz#4183e4e8bf08bb6e05bbb2f7d2e0c8f712ca40e3" @@ -4233,6 +4305,23 @@ has-flag@^4.0.0: resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-4.0.0.tgz#944771fd9c81c81265c4d6941860da06bb59479b" integrity sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ== +has-property-descriptors@^1.0.0: + version "1.0.1" + resolved "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.1.tgz#52ba30b6c5ec87fd89fa574bc1c39125c6f65340" + integrity sha512-VsX8eaIewvas0xnvinAe9bw4WfIeODpGYikiWYLH+dma0Jw6KHYqWiWfhQlgOVK8D6PvjubK5Uc4P0iIhIcNVg== + dependencies: + get-intrinsic "^1.2.2" + +has-proto@^1.0.1: + version "1.0.1" + resolved "https://registry.npmjs.org/has-proto/-/has-proto-1.0.1.tgz#1885c1305538958aff469fef37937c22795408e0" + integrity sha512-7qE+iP+O+bgF9clE5+UoBFzE65mlBiVj3tKCrlNQ0Ogwm0BjpT/gK4SlLYDMybDh5I3TCTKnPPa0oMG7JDYrhg== + +has-symbols@^1.0.3: + version "1.0.3" + resolved "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.3.tgz#bb7b2c4349251dce87b125f7bdf874aa7c8b39f8" + integrity sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A== + has@^1.0.3: version "1.0.3" resolved "https://registry.yarnpkg.com/has/-/has-1.0.3.tgz#722d7cbfc1f6aa8241f16dd814e011e1f41e8796" @@ -4240,6 +4329,13 @@ has@^1.0.3: dependencies: function-bind "^1.1.1" +hasown@^2.0.0: + version "2.0.0" + resolved "https://registry.npmjs.org/hasown/-/hasown-2.0.0.tgz#f4c513d454a57b7c7e1650778de226b11700546c" + integrity sha512-vUptKVTpIJhcczKBbgnS+RtcuYMB8+oNzPK2/Hp3hanz8JmpATdmmgLgSaadVREkDm+e2giHwY3ZRkyjSIDDFA== + dependencies: + function-bind "^1.1.2" + hermes-estree@0.12.0: version "0.12.0" resolved "https://registry.yarnpkg.com/hermes-estree/-/hermes-estree-0.12.0.tgz#8a289f9aee854854422345e6995a48613bac2ca8" @@ -4411,6 +4507,11 @@ is-directory@^0.3.1: resolved "https://registry.yarnpkg.com/is-directory/-/is-directory-0.3.1.tgz#61339b6f2475fc772fd9c9d83f5c8575dc154ae1" integrity sha512-yVChGzahRFvbkscn2MlwGismPO12i9+znNruC5gVEntG3qu0xQMzsGg/JFbrsqDOHtHFPci+V5aP5T9I+yeKqw== +is-docker@^2.0.0: + version "2.2.1" + resolved "https://registry.npmjs.org/is-docker/-/is-docker-2.2.1.tgz#33eeabe23cfe86f14bde4408a02c0cfb853acdaa" + integrity sha512-F+i2BKsFrH66iaUFc0woD8sLy8getkwTwtOBjvs56Cx4CgJDeKQeqfz8wAYiSb8JOprWhHH5p77PbmYCvvUuXQ== + is-fullwidth-code-point@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz#a3b30a5c4f199183167aaab93beefae3ddfb654f" @@ -4463,6 +4564,18 @@ is-wsl@^1.1.0: resolved "https://registry.yarnpkg.com/is-wsl/-/is-wsl-1.1.0.tgz#1f16e4aa22b04d1336b66188a66af3c600c3a66d" integrity sha512-gfygJYZ2gLTDlmbWMI0CE2MwnFzSN/2SZfkMlItC4K/JBlsWVDB0bO6XhqcY13YXE7iMcAJnzTCJjPiTeJJ0Mw== +is-wsl@^2.1.1: + version "2.2.0" + resolved "https://registry.npmjs.org/is-wsl/-/is-wsl-2.2.0.tgz#74a4c76e77ca9fd3f932f290c17ea326cd157271" + integrity sha512-fKzAra0rGJUUBwGBgNkHZuToZcn+TtXHpeCgmkMJMMYx1sQDYaCSyjJBSCa2nH1DGm7s3n1oBnohoVTBaN7Lww== + dependencies: + is-docker "^2.0.0" + +isarray@^2.0.5: + version "2.0.5" + resolved "https://registry.npmjs.org/isarray/-/isarray-2.0.5.tgz#8af1e4c1221244cc62459faf38940d4e644a5723" + integrity sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw== + isarray@~1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/isarray/-/isarray-1.0.0.tgz#bb935d48582cba168c06834957a54a3e07124f11" @@ -5022,6 +5135,16 @@ json-schema-traverse@^1.0.0: resolved "https://registry.yarnpkg.com/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz#ae7bcb3656ab77a73ba5c49bf654f38e6b6860e2" integrity sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug== +json-stable-stringify@^1.0.2: + version "1.1.0" + resolved "https://registry.npmjs.org/json-stable-stringify/-/json-stable-stringify-1.1.0.tgz#43d39c7c8da34bfaf785a61a56808b0def9f747d" + integrity sha512-zfA+5SuwYN2VWqN1/5HZaDzQKLJHaBVMZIIM+wuYjdptkaQsqzDdqjqf+lZZJUuJq1aanHiY8LhH8LmH+qBYJA== + dependencies: + call-bind "^1.0.5" + isarray "^2.0.5" + jsonify "^0.0.1" + object-keys "^1.1.1" + json5@^2.2.2, json5@^2.2.3: version "2.2.3" resolved "https://registry.yarnpkg.com/json5/-/json5-2.2.3.tgz#78cd6f1a19bdc12b73db5ad0c61efd66c1e29283" @@ -5043,11 +5166,23 @@ jsonfile@^6.0.1: optionalDependencies: graceful-fs "^4.1.6" +jsonify@^0.0.1: + version "0.0.1" + resolved "https://registry.npmjs.org/jsonify/-/jsonify-0.0.1.tgz#2aa3111dae3d34a0f151c63f3a45d995d9420978" + integrity sha512-2/Ki0GcmuqSrgFyelQq9M05y7PS0mEwuIzrf3f1fPqkVDVRvZrPZtVSMHxdgo8Aq0sxAOb/cr2aqqA3LeWHVPg== + kind-of@^6.0.2: version "6.0.3" resolved "https://registry.yarnpkg.com/kind-of/-/kind-of-6.0.3.tgz#07c05034a6c349fa06e24fa35aa76db4580ce4dd" integrity sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw== +klaw-sync@^6.0.0: + version "6.0.0" + resolved "https://registry.npmjs.org/klaw-sync/-/klaw-sync-6.0.0.tgz#1fd2cfd56ebb6250181114f0a581167099c2b28c" + integrity sha512-nIeuVSzdCCs6TDPTqI8w1Yre34sSq7AkZ4B3sfOBbI2CgVSB4Du4aLQijFU2+lhAFCwt9+42Hel6lQNIv6AntQ== + dependencies: + graceful-fs "^4.1.11" + kleur@^3.0.3: version "3.0.3" resolved "https://registry.yarnpkg.com/kleur/-/kleur-3.0.3.tgz#a79c9ecc86ee1ce3fa6206d1216c501f147fc07e" @@ -5750,7 +5885,7 @@ metro@0.79.1: ws "^7.5.1" yargs "^17.6.2" -micromatch@^4.0.4: +micromatch@^4.0.2, micromatch@^4.0.4: version "4.0.5" resolved "https://registry.yarnpkg.com/micromatch/-/micromatch-4.0.5.tgz#bc8999a7cbbf77cdc89f132f6e467051b49090c6" integrity sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA== @@ -6016,6 +6151,11 @@ object-assign@^4.1.0, object-assign@^4.1.1: resolved "https://registry.yarnpkg.com/object-assign/-/object-assign-4.1.1.tgz#2109adc7965887cfc05cbbd442cac8bfbb360863" integrity sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg== +object-keys@^1.1.1: + version "1.1.1" + resolved "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz#1c47f272df277f3b1daf061677d9c82e2322c60e" + integrity sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA== + on-finished@2.4.1: version "2.4.1" resolved "https://registry.yarnpkg.com/on-finished/-/on-finished-2.4.1.tgz#58c8c44116e54845ad57f14ab10b03533184ac3f" @@ -6056,6 +6196,14 @@ open@^6.2.0: dependencies: is-wsl "^1.1.0" +open@^7.4.2: + version "7.4.2" + resolved "https://registry.npmjs.org/open/-/open-7.4.2.tgz#b8147e26dcf3e426316c730089fd71edd29c2321" + integrity sha512-MVHddDVweXZF3awtlAS+6pgKLlm/JgxZ90+/NBurBoQctVOOB/zDdVjcyPzQ+0laDGbsWgrRkflI65sQeOgT9Q== + dependencies: + is-docker "^2.0.0" + is-wsl "^2.1.1" + ora@^5.4.1: version "5.4.1" resolved "https://registry.yarnpkg.com/ora/-/ora-5.4.1.tgz#1b2678426af4ac4a509008e5e4ac9e9959db9e18" @@ -6071,6 +6219,11 @@ ora@^5.4.1: strip-ansi "^6.0.0" wcwidth "^1.0.1" +os-tmpdir@~1.0.2: + version "1.0.2" + resolved "https://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz#bbe67406c79aa85c5cfec766fe5734555dfa1274" + integrity sha512-D2FR03Vir7FIu45XBY20mTb+/ZSWB00sjU9jdQXt83gDrI4Ztz5Fs7/yy74g2N5SVQY4xY1qDr4rNddwYRVX0g== + p-limit@^2.0.0, p-limit@^2.2.0: version "2.3.0" resolved "https://registry.yarnpkg.com/p-limit/-/p-limit-2.3.0.tgz#3dd33c647a214fdfffd835933eb086da0dc21db1" @@ -6134,6 +6287,27 @@ parseurl@~1.3.3: resolved "https://registry.yarnpkg.com/parseurl/-/parseurl-1.3.3.tgz#9da19e7bee8d12dff0513ed5b76957793bc2e8d4" integrity sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ== +patch-package@^8.0.0: + version "8.0.0" + resolved "https://registry.npmjs.org/patch-package/-/patch-package-8.0.0.tgz#d191e2f1b6e06a4624a0116bcb88edd6714ede61" + integrity sha512-da8BVIhzjtgScwDJ2TtKsfT5JFWz1hYoBl9rUQ1f38MC2HwnEIkK8VN3dKMKcP7P7bvvgzNDbfNHtx3MsQb5vA== + dependencies: + "@yarnpkg/lockfile" "^1.1.0" + chalk "^4.1.2" + ci-info "^3.7.0" + cross-spawn "^7.0.3" + find-yarn-workspace-root "^2.0.0" + fs-extra "^9.0.0" + json-stable-stringify "^1.0.2" + klaw-sync "^6.0.0" + minimist "^1.2.6" + open "^7.4.2" + rimraf "^2.6.3" + semver "^7.5.3" + slash "^2.0.0" + tmp "^0.0.33" + yaml "^2.2.2" + path-exists@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/path-exists/-/path-exists-3.0.0.tgz#ce0ebeaa5f78cb18925ea7d810d7b59b010fd515" @@ -6594,6 +6768,13 @@ retry@^0.12.0: resolved "https://registry.yarnpkg.com/retry/-/retry-0.12.0.tgz#1b42a6266a21f07421d1b0b54b7dc167b01c013b" integrity sha512-9LkiTwjUh6rT555DtE9rTX+BKByPfrMzEAtnlEtdEwr3Nkffwiihqe2bWADg+OQRjt9gl6ICdmB/ZFDCGAtSow== +rimraf@^2.6.3: + version "2.7.1" + resolved "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz#35797f13a7fdadc566142c29d4f07ccad483e3ec" + integrity sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w== + dependencies: + glob "^7.1.3" + rimraf@^3.0.2: version "3.0.2" resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-3.0.2.tgz#f1a5402ba6220ad52cc1282bac1ae3aa49fd061a" @@ -6714,6 +6895,16 @@ set-blocking@^2.0.0: resolved "https://registry.yarnpkg.com/set-blocking/-/set-blocking-2.0.0.tgz#045f9782d011ae9a6803ddd382b24392b3d890f7" integrity sha512-KiKBS8AnWGEyLzofFfmvKwpdPzqiy16LvQfK3yv/fVH7Bj13/wl3JSR1J+rfgRE9q7xUJK4qvgS8raSOeLUehw== +set-function-length@^1.1.1: + version "1.1.1" + resolved "https://registry.npmjs.org/set-function-length/-/set-function-length-1.1.1.tgz#4bc39fafb0307224a33e106a7d35ca1218d659ed" + integrity sha512-VoaqjbBJKiWtg4yRcKBQ7g7wnGnLV3M8oLvVWwOk2PdYY6PEFegR1vezXR0tw6fZGF9csVakIRjrJiy2veSBFQ== + dependencies: + define-data-property "^1.1.1" + get-intrinsic "^1.2.1" + gopd "^1.0.1" + has-property-descriptors "^1.0.0" + setprototypeof@1.2.0: version "1.2.0" resolved "https://registry.yarnpkg.com/setprototypeof/-/setprototypeof-1.2.0.tgz#66c9a24a73f9fc28cbe66b09fed3d33dcaf1b424" @@ -6760,6 +6951,11 @@ sisteransi@^1.0.5: resolved "https://registry.yarnpkg.com/sisteransi/-/sisteransi-1.0.5.tgz#134d681297756437cc05ca01370d3a7a571075ed" integrity sha512-bLGGlR1QxBcynn2d5YmDX4MGjlZvy2MRBDRNHLJ8VI6l6+9FUiyTFNJ0IveOSP0bcXgVDPRcfGqA0pjaqUpfVg== +slash@^2.0.0: + version "2.0.0" + resolved "https://registry.npmjs.org/slash/-/slash-2.0.0.tgz#de552851a1759df3a8f206535442f5ec4ddeab44" + integrity sha512-ZYKh3Wh2z1PpEXWr0MpSBZ0V6mZHAQfYevttO11c51CaWjGTaadiKZ+wVt1PbMlDV5qhMFslpZCemhwOK7C89A== + slash@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/slash/-/slash-3.0.0.tgz#6539be870c165adbd5240220dbe361f1bc4d4634" @@ -7026,6 +7222,13 @@ tinycolor2@^1.4.2: resolved "https://registry.yarnpkg.com/tinycolor2/-/tinycolor2-1.6.0.tgz#f98007460169b0263b97072c5ae92484ce02d09e" integrity sha512-XPaBkWQJdsf3pLKJV9p4qN/S+fm2Oj8AIPo1BTUhg5oxkvm9+SVEGFdhyOz7tTdUTfvxMiAs4sp6/eZO2Ew+pw== +tmp@^0.0.33: + version "0.0.33" + resolved "https://registry.npmjs.org/tmp/-/tmp-0.0.33.tgz#6d34335889768d21b2bcda0aa277ced3b1bfadf9" + integrity sha512-jRCJlojKnZ3addtTOjdIqoRuPEKBvNXcGYqzO6zWZX8KfKEpnGY5jfggJQ3EjKuu8D4bJRr0y+cYJFmYbImXGw== + dependencies: + os-tmpdir "~1.0.2" + tmpl@1.0.5: version "1.0.5" resolved "https://registry.yarnpkg.com/tmpl/-/tmpl-1.0.5.tgz#8683e0b902bb9c20c4f726e3c0b69f36518c07cc" @@ -7364,6 +7567,11 @@ yaml@^2.2.1: resolved "https://registry.yarnpkg.com/yaml/-/yaml-2.3.1.tgz#02fe0975d23cd441242aa7204e09fc28ac2ac33b" integrity sha512-2eHWfjaoXgTBC2jNM1LRef62VQa0umtvRiDSk6HSzW7RvS5YtkabJrwYLLEKWBc8a5U2PTSCs+dJjUTJdlHsWQ== +yaml@^2.2.2: + version "2.3.4" + resolved "https://registry.npmjs.org/yaml/-/yaml-2.3.4.tgz#53fc1d514be80aabf386dc6001eb29bf3b7523b2" + integrity sha512-8aAvwVUSHpfEqTQ4w/KMlf3HcRdt50E5ODIQJBw1fQ5RL34xabzxtUlzTXVqc4rkZsPbvrXKWnABCD7kWSmocA== + yargs-parser@^18.1.2: version "18.1.3" resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-18.1.3.tgz#be68c4975c6b2abf469236b0c870362fab09a7b0" From e545cf1f9cc8535b95f9e5e122732d4e43ca80d0 Mon Sep 17 00:00:00 2001 From: Abdelhamid Nasser <38096011+abdelhamid-f-nasser@users.noreply.github.com> Date: Tue, 9 Jan 2024 01:35:20 +0200 Subject: [PATCH 04/30] fix(android): resolve `JsonException` handling error (#1089) Jira ID: MOB-13598 --- .../main/java/com/instabug/reactlibrary/utils/ReportUtil.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/android/src/main/java/com/instabug/reactlibrary/utils/ReportUtil.java b/android/src/main/java/com/instabug/reactlibrary/utils/ReportUtil.java index 69fdde015e..a44da18822 100644 --- a/android/src/main/java/com/instabug/reactlibrary/utils/ReportUtil.java +++ b/android/src/main/java/com/instabug/reactlibrary/utils/ReportUtil.java @@ -70,7 +70,7 @@ public static WritableArray parseConsoleLogs(ArrayList
consoleLogs) { for(int i = 0; i < consoleLogs.size(); i++) { try { writableArray.pushString(consoleLogs.get(i).toJson()); - } catch (JSONException e) { + } catch (Exception e) { e.printStackTrace(); } From 524e8072e6a924a0ae72cdc77e86f32edd5b4598 Mon Sep 17 00:00:00 2001 From: Abdelhamid Nasser <38096011+abdelhamid-f-nasser@users.noreply.github.com> Date: Mon, 8 Jan 2024 19:44:47 +0200 Subject: [PATCH 05/30] chore(ios): bump sdk to v12.5.0 (#1085) Jira ID: MOB-13556 --- CHANGELOG.md | 6 ++++++ examples/default/ios/Podfile.lock | 8 ++++---- ios/native.rb | 2 +- 3 files changed, 11 insertions(+), 5 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 935609d048..116d137bcb 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,11 @@ # Changelog +## [Unreleased](https://github.com/Instabug/Instabug-React-Native/compare/v12.4.0...dev) + +### Changed + +- Bump Instabug iOS SDK to v12.5.0 ([#1085](https://github.com/Instabug/Instabug-React-Native/pull/1085)). [See release notes](https://github.com/instabug/instabug-ios/releases/tag/12.5.0). + ## [12.4.0](https://github.com/Instabug/Instabug-React-Native/compare/v12.2.0...v12.4.0) (December 7, 2023) ### Changed diff --git a/examples/default/ios/Podfile.lock b/examples/default/ios/Podfile.lock index 39064049aa..230d764977 100644 --- a/examples/default/ios/Podfile.lock +++ b/examples/default/ios/Podfile.lock @@ -73,7 +73,7 @@ PODS: - hermes-engine (0.72.3): - hermes-engine/Pre-built (= 0.72.3) - hermes-engine/Pre-built (0.72.3) - - Instabug (12.4.0) + - Instabug (12.5.0) - libevent (2.1.12) - OCMock (3.9.3) - OpenSSL-Universal (1.1.1100) @@ -495,7 +495,7 @@ PODS: - RCT-Folly (= 2021.07.22.00) - React-Core - RNInstabug (12.4.0): - - Instabug (= 12.4.0) + - Instabug (= 12.5.0) - React-Core - RNReanimated (3.5.4): - DoubleConversion @@ -745,7 +745,7 @@ SPEC CHECKSUMS: fmt: ff9d55029c625d3757ed641535fd4a75fedc7ce9 glog: 04b94705f318337d7ead9e6d17c019bd9b1f6b1b hermes-engine: 10fbd3f62405c41ea07e71973ea61e1878d07322 - Instabug: 83bde9d7d4b582ea8f14935f79f1ce39af55e149 + Instabug: 7c7421ae87838010b47a60d9b56378be2482ab64 libevent: 4049cae6c81cdb3654a443be001fb9bdceff7913 OCMock: 300b1b1b9155cb6378660b981c2557448830bdc6 OpenSSL-Universal: ebc357f1e6bc71fa463ccb2fe676756aff50e88c @@ -784,7 +784,7 @@ SPEC CHECKSUMS: React-utils: bcb57da67eec2711f8b353f6e3d33bd8e4b2efa3 ReactCommon: 3ccb8fb14e6b3277e38c73b0ff5e4a1b8db017a9 RNGestureHandler: 6e46dde1f87e5f018a54fe5d40cd0e0b942b49ee - RNInstabug: ae604474d8e74d7bd2bee96ccbcfd9d7e12a61fe + RNInstabug: 085f44cee15e8ea660bad3ce17ea575adb5ae5ce RNReanimated: ab2e96c6d5591c3dfbb38a464f54c8d17fb34a87 RNScreens: b21dc57dfa2b710c30ec600786a3fc223b1b92e7 RNSVG: 80584470ff1ffc7994923ea135a3e5ad825546b9 diff --git a/ios/native.rb b/ios/native.rb index 0b6e557526..ae1809f4d1 100644 --- a/ios/native.rb +++ b/ios/native.rb @@ -1,4 +1,4 @@ -$instabug = { :version => '12.4.0' } +$instabug = { :version => '12.5.0' } def use_instabug! (spec = nil) version = $instabug[:version] From 7d3c28b90d4fb71849012c1189503ae80f4057b1 Mon Sep 17 00:00:00 2001 From: Abdelhamid Nasser <38096011+abdelhamid-f-nasser@users.noreply.github.com> Date: Mon, 8 Jan 2024 20:01:33 +0200 Subject: [PATCH 06/30] chore(android): bump sdk to v12.5.1 (#1088) Jira ID: MOB-13556 --- CHANGELOG.md | 1 + android/native.gradle | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 116d137bcb..0e27d7641c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,7 @@ ### Changed - Bump Instabug iOS SDK to v12.5.0 ([#1085](https://github.com/Instabug/Instabug-React-Native/pull/1085)). [See release notes](https://github.com/instabug/instabug-ios/releases/tag/12.5.0). +- Bump Instabug Android SDK to v12.5.1 ([#1088](https://github.com/Instabug/Instabug-React-Native/pull/1085)). See release notes for [v12.5.0](https://github.com/Instabug/android/releases/tag/v12.5.0) and [v12.5.1](https://github.com/Instabug/android/releases/tag/v12.5.1). ## [12.4.0](https://github.com/Instabug/Instabug-React-Native/compare/v12.2.0...v12.4.0) (December 7, 2023) diff --git a/android/native.gradle b/android/native.gradle index af50eeab91..5cdb2c0688 100644 --- a/android/native.gradle +++ b/android/native.gradle @@ -1,5 +1,5 @@ project.ext.instabug = [ - version: '12.4.1' + version: '12.5.1' ] dependencies { From 547fa3622ea9ad80e4e0e31535056ad767bbe061 Mon Sep 17 00:00:00 2001 From: Abdelhamid Nasser <38096011+abdelhamid-f-nasser@users.noreply.github.com> Date: Tue, 9 Jan 2024 03:06:29 +0200 Subject: [PATCH 07/30] fix(android): remove current view update delay (#1080) Jira ID: MOB-13396 --- CHANGELOG.md | 4 + .../RNInstabugReactnativeModule.java | 23 +++++ .../RNInstabugReactnativeModuleTest.java | 12 +++ src/modules/Instabug.ts | 20 ++++ src/native/NativeInstabug.ts | 1 + test/mocks/mockInstabug.ts | 1 + test/modules/Instabug.spec.ts | 92 ++++++++++++++++++- 7 files changed, 152 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 0e27d7641c..f6fb6ab8c6 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,10 @@ - Bump Instabug iOS SDK to v12.5.0 ([#1085](https://github.com/Instabug/Instabug-React-Native/pull/1085)). [See release notes](https://github.com/instabug/instabug-ios/releases/tag/12.5.0). - Bump Instabug Android SDK to v12.5.1 ([#1088](https://github.com/Instabug/Instabug-React-Native/pull/1085)). See release notes for [v12.5.0](https://github.com/Instabug/android/releases/tag/v12.5.0) and [v12.5.1](https://github.com/Instabug/android/releases/tag/v12.5.1). +### Fixed + +- Fix a delay issue in reporting the 'Current View' that resulted in displaying outdated values ([#1080](https://github.com/Instabug/Instabug-React-Native/pull/1080)). + ## [12.4.0](https://github.com/Instabug/Instabug-React-Native/compare/v12.2.0...v12.4.0) (December 7, 2023) ### Changed diff --git a/android/src/main/java/com/instabug/reactlibrary/RNInstabugReactnativeModule.java b/android/src/main/java/com/instabug/reactlibrary/RNInstabugReactnativeModule.java index d412c62a6d..46814e53ec 100644 --- a/android/src/main/java/com/instabug/reactlibrary/RNInstabugReactnativeModule.java +++ b/android/src/main/java/com/instabug/reactlibrary/RNInstabugReactnativeModule.java @@ -916,6 +916,29 @@ public void execute(NativeViewHierarchyManager nativeViewHierarchyManager) { }); } + /** + * Reports that the screen name been changed (Current View). + * + * @param screenName string containing the screen name + * + */ + @ReactMethod + public void reportCurrentViewChange(final String screenName) { + MainThreadHandler.runOnMainThread(new Runnable() { + @Override + public void run() { + try { + Method method = getMethod(Class.forName("com.instabug.library.Instabug"), "reportCurrentViewChange", String.class); + if (method != null) { + method.invoke(null, screenName); + } + } catch (Exception e) { + e.printStackTrace(); + } + } + }); + } + /** * Reports that the screen has been changed (Repro Steps) the screen sent to this method will be the 'current view' on the dashboard * diff --git a/android/src/test/java/com/instabug/reactlibrary/RNInstabugReactnativeModuleTest.java b/android/src/test/java/com/instabug/reactlibrary/RNInstabugReactnativeModuleTest.java index 1426f9a1f8..148d71d512 100644 --- a/android/src/test/java/com/instabug/reactlibrary/RNInstabugReactnativeModuleTest.java +++ b/android/src/test/java/com/instabug/reactlibrary/RNInstabugReactnativeModuleTest.java @@ -482,6 +482,18 @@ public void tearDown() { } } + @Test + public void givenString$reportCurrentViewChange_whenQuery_thenShouldCallNativeApiWithString() throws Exception { + // when + rnModule.reportCurrentViewChange("screen"); + Method privateStringMethod = getMethod(Class.forName("com.instabug.library.Instabug"), "reportCurrentViewChange", String.class); + privateStringMethod.setAccessible(true); + + // then + verify(Instabug.class, VerificationModeFactory.times(1)); + privateStringMethod.invoke("reportCurrentViewChange","screen"); + } + @Test public void givenString$reportScreenChange_whenQuery_thenShouldCallNativeApiWithString() throws Exception { // when diff --git a/src/modules/Instabug.ts b/src/modules/Instabug.ts index 0d1c4092a4..399464f0d0 100644 --- a/src/modules/Instabug.ts +++ b/src/modules/Instabug.ts @@ -34,6 +34,23 @@ export const setEnabled = (isEnabled: boolean) => { NativeInstabug.setEnabled(isEnabled); }; +/** + * Reports that the screen name been changed (Current View field on dashboard). + * only for android. + * + * Normally reportScreenChange handles taking a screenshot for reproduction + * steps and the Current View field on the dashboard. But we've faced issues + * in android where we needed to separate them, that's why we only call it + * for android. + * + * @param screenName string containing the screen name + */ +function reportCurrentViewForAndroid(screenName: string | null) { + if (Platform.OS === 'android' && screenName != null) { + NativeInstabug.reportCurrentViewChange(screenName); + } +} + /** * Initializes the SDK. * This is the main SDK method that does all the magic. This is the only @@ -55,6 +72,7 @@ export const init = (config: InstabugConfig) => { _isFirstScreen = true; _currentScreen = firstScreen; + reportCurrentViewForAndroid(firstScreen); setTimeout(() => { if (_currentScreen === firstScreen) { NativeInstabug.reportScreenChange(firstScreen); @@ -458,6 +476,7 @@ export const onNavigationStateChange = ( const prevScreen = InstabugUtils.getActiveRouteName(prevState); if (prevScreen !== currentScreen) { + reportCurrentViewForAndroid(currentScreen); if (_currentScreen != null && _currentScreen !== firstScreen) { NativeInstabug.reportScreenChange(_currentScreen); _currentScreen = null; @@ -478,6 +497,7 @@ export const onStateChange = (state?: NavigationStateV5) => { } const currentScreen = InstabugUtils.getFullRoute(state); + reportCurrentViewForAndroid(currentScreen); if (_currentScreen !== null && _currentScreen !== firstScreen) { NativeInstabug.reportScreenChange(_currentScreen); _currentScreen = null; diff --git a/src/native/NativeInstabug.ts b/src/native/NativeInstabug.ts index 23d41e3426..14b306554f 100644 --- a/src/native/NativeInstabug.ts +++ b/src/native/NativeInstabug.ts @@ -44,6 +44,7 @@ export interface InstabugNativeModule extends NativeModule { ): void; setTrackUserSteps(isEnabled: boolean): void; reportScreenChange(firstScreen: string): void; + reportCurrentViewChange(screenName: string): void; addPrivateView(nativeTag: number | null): void; removePrivateView(nativeTag: number | null): void; diff --git a/test/mocks/mockInstabug.ts b/test/mocks/mockInstabug.ts index f7d975eee1..6353cf64c7 100644 --- a/test/mocks/mockInstabug.ts +++ b/test/mocks/mockInstabug.ts @@ -47,6 +47,7 @@ const mockInstabug: InstabugNativeModule = { show: jest.fn(), setPreSendingHandler: jest.fn(), reportScreenChange: jest.fn(), + reportCurrentViewChange: jest.fn(), addExperiments: jest.fn(), removeExperiments: jest.fn(), clearAllExperiments: jest.fn(), diff --git a/test/modules/Instabug.spec.ts b/test/modules/Instabug.spec.ts index 2d928253a8..06f0e770af 100644 --- a/test/modules/Instabug.spec.ts +++ b/test/modules/Instabug.spec.ts @@ -109,6 +109,33 @@ describe('Instabug Module', () => { }); }); + // eslint-disable-next-line jest/no-disabled-tests + it.skip('onNavigationStateChange should call the native method reportCurrentViewChange on Android Platform', async () => { + Platform.OS = 'android'; + InstabugUtils.getActiveRouteName = jest.fn().mockImplementation((screenName) => screenName); + + // @ts-ignore + Instabug.onNavigationStateChange('home', 'settings'); + + await waitForExpect(() => { + expect(NativeInstabug.reportCurrentViewChange).toBeCalledTimes(1); + expect(NativeInstabug.reportCurrentViewChange).toBeCalledWith('settings'); + }); + }); + + // eslint-disable-next-line jest/no-disabled-tests + it.skip('onNavigationStateChange should not call the native method reportCurrentViewChange on iOS Platform', async () => { + Platform.OS = 'ios'; + InstabugUtils.getActiveRouteName = jest.fn().mockImplementation((screenName) => screenName); + + // @ts-ignore + Instabug.onNavigationStateChange('home', 'settings'); + + await waitForExpect(() => { + expect(NativeInstabug.reportCurrentViewChange).not.toBeCalled(); + }); + }); + it('onNavigationStateChange should not call the native method reportScreenChange if screen is the same', (done) => { InstabugUtils.getActiveRouteName = jest.fn().mockImplementation((screenName) => screenName); @@ -122,7 +149,20 @@ describe('Instabug Module', () => { }, 1500); }); - it('onNavigationStateChange should call the native method reportScreenChange immediatly if _currentScreen is set', async () => { + it('onNavigationStateChange should not call the native method reportCurrentViewChange if screen is the same', (done) => { + InstabugUtils.getActiveRouteName = jest.fn().mockImplementation((screenName) => screenName); + + // @ts-ignore + Instabug.onNavigationStateChange('home', 'home'); + + // Wait for 1.5s as reportScreenChange is delayed by 1s + setTimeout(() => { + expect(NativeInstabug.reportCurrentViewChange).not.toBeCalled(); + done(); + }, 1500); + }); + + it('onNavigationStateChange should call the native method reportScreenChange immediately if _currentScreen is set', async () => { InstabugUtils.getActiveRouteName = jest.fn().mockImplementation((screenName) => screenName); // sets _currentScreen and waits for 1s as _currentScreen is null @@ -150,6 +190,31 @@ describe('Instabug Module', () => { }); }); + // eslint-disable-next-line jest/no-disabled-tests + it.skip('onStateChange should call the native method reportCurrentViewChange on Android Platform', async () => { + Platform.OS = 'android'; + const state = { routes: [{ name: 'ScreenName' }], index: 0 }; + // @ts-ignore + Instabug.onStateChange(state); + + await waitForExpect(() => { + expect(NativeInstabug.reportCurrentViewChange).toBeCalledTimes(1); + expect(NativeInstabug.reportCurrentViewChange).toBeCalledWith('ScreenName'); + }); + }); + + // eslint-disable-next-line jest/no-disabled-tests + it.skip('onStateChange should not call the native method reportCurrentViewChange on iOS Platform', async () => { + Platform.OS = 'ios'; + const state = { routes: [{ name: 'ScreenName' }], index: 0 }; + // @ts-ignore + Instabug.onStateChange(state); + + await waitForExpect(() => { + expect(NativeInstabug.reportCurrentViewChange).not.toBeCalled(); + }); + }); + it('onStateChange should call the native method reportScreenChange immediately if _currentScreen is set', async () => { // sets _currentScreen and waits for 1s as _currentScreen is null const state = { routes: [{ name: 'ScreenName' }], index: 0 }; @@ -195,6 +260,31 @@ describe('Instabug Module', () => { }); }); + it('init should call reportCurrentViewChange on Android Platform', async () => { + Platform.OS = 'android'; + Instabug.init({ + token: 'some-token', + invocationEvents: [InvocationEvent.none], + }); + + await waitForExpect(() => { + expect(NativeInstabug.reportCurrentViewChange).toBeCalledTimes(1); + expect(NativeInstabug.reportCurrentViewChange).toBeCalledWith('Initial Screen'); + }); + }); + + it('init should not call reportCurrentViewChange on ios Platform', async () => { + Platform.OS = 'ios'; + Instabug.init({ + token: 'some-token', + invocationEvents: [InvocationEvent.none], + }); + + await waitForExpect(() => { + expect(NativeInstabug.reportCurrentViewChange).not.toBeCalled(); + }); + }); + it('should call the native method setUserData', () => { const userData = 'userData'; Instabug.setUserData(userData); From 7d0e4c0b959ab04f919babce47335e42d6fb7035 Mon Sep 17 00:00:00 2001 From: AbdElHamid Nasser Date: Fri, 3 Nov 2023 08:26:48 +0200 Subject: [PATCH 08/30] chore(android): integrate packages conflict snapshot This resolves the obfuscation issue resolved here [[INSD-10355] Fix obfuscation issue at instabug-apm-okhttp-interceptor #5390](https://github.com/Instabug/android/pull/5390) --- android/build.gradle | 11 +++++++++++ android/native.gradle | 2 +- 2 files changed, 12 insertions(+), 1 deletion(-) diff --git a/android/build.gradle b/android/build.gradle index 1773a81d11..e06e5ad397 100644 --- a/android/build.gradle +++ b/android/build.gradle @@ -4,6 +4,17 @@ apply from: './jacoco.gradle' apply from: './native.gradle' apply from: './sourcemaps.gradle' + +rootProject.allprojects { + repositories { + google() + jcenter() + maven { + url 'https://oss.sonatype.org/content/repositories/snapshots' + } + } +} + String getExtOrDefault(String name) { def defaultPropertyKey = 'InstabugReactNative_' + name if (rootProject.ext.has(name)) { diff --git a/android/native.gradle b/android/native.gradle index 5cdb2c0688..681d85d7af 100644 --- a/android/native.gradle +++ b/android/native.gradle @@ -1,5 +1,5 @@ project.ext.instabug = [ - version: '12.5.1' + version: '12.2.0.5390171-SNAPSHOT' ] dependencies { From ba6e86ce729ace23f0c15d2613c366304646b9bf Mon Sep 17 00:00:00 2001 From: AbdElHamid Nasser Date: Tue, 14 Nov 2023 22:33:26 +0200 Subject: [PATCH 09/30] chore(android): integrate early crashes snapshot This resolves the early crashes capturing not working on android resolved here [[Bug][IBGCRASH-20553] Fixing crashes early capturing. #5412](https://github.com/Instabug/android/pull/5412). --- android/native.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/android/native.gradle b/android/native.gradle index 681d85d7af..8e1de8159d 100644 --- a/android/native.gradle +++ b/android/native.gradle @@ -1,5 +1,5 @@ project.ext.instabug = [ - version: '12.2.0.5390171-SNAPSHOT' + version: '12.2.0.5428088-SNAPSHOT' ] dependencies { From 52ccf5109b9cba8f03048d863e6728bd16cf0b4d Mon Sep 17 00:00:00 2001 From: AbdElHamid Nasser Date: Fri, 3 Nov 2023 06:58:06 +0200 Subject: [PATCH 10/30] fix: disable namespace support for AGP 7.3.0 --- android/build.gradle | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/android/build.gradle b/android/build.gradle index e06e5ad397..e0d19227a5 100644 --- a/android/build.gradle +++ b/android/build.gradle @@ -24,12 +24,12 @@ String getExtOrDefault(String name) { } static boolean supportsNamespace() { - def parsed = com.android.Version.ANDROID_GRADLE_PLUGIN_VERSION.tokenize('.') - def major = parsed[0].toInteger() - def minor = parsed[1].toInteger() +// def parsed = com.android.Version.ANDROID_GRADLE_PLUGIN_VERSION.tokenize('.') +// def major = parsed[0].toInteger() +// def minor = parsed[1].toInteger() - // Namespace support was added in 7.3.0 - return (major == 7 && minor >= 3) || major >= 8 + // Namespace support was added in 7.3.0 (disabled for now) + return false } void updateManifestPackage() { From 5ea430be6a65f78714477df2a1fe8bb9e5945b85 Mon Sep 17 00:00:00 2001 From: AbdElHamid Nasser Date: Fri, 17 Nov 2023 21:42:41 +0200 Subject: [PATCH 11/30] chore(ios): integrate crashes attachment snapshot --- RNInstabug.podspec | 2 +- examples/default/ios/Podfile | 2 +- examples/default/ios/Podfile.lock | 68 ++++++------------------------- 3 files changed, 14 insertions(+), 58 deletions(-) diff --git a/RNInstabug.podspec b/RNInstabug.podspec index 40c480f4cb..21ae5fc720 100644 --- a/RNInstabug.podspec +++ b/RNInstabug.podspec @@ -16,5 +16,5 @@ Pod::Spec.new do |s| s.source_files = "ios/**/*.{h,m,mm}" s.dependency 'React-Core' - use_instabug!(s) + s.dependency 'Instabug' end diff --git a/examples/default/ios/Podfile b/examples/default/ios/Podfile index b47b0b248c..f9f1186896 100644 --- a/examples/default/ios/Podfile +++ b/examples/default/ios/Podfile @@ -26,7 +26,7 @@ target 'InstabugExample' do # Flags change depending on the env values. flags = get_default_flags() - + pod ‘Instabug’, :podspec => ’https://ios-releases.instabug.com/custom/fix_crashes_screenshot_attachments_pods/12.2.0/Instabug.podspec' use_react_native!( :path => config[:reactNativePath], # Hermes is now enabled by default. Disable by setting this flag to false. diff --git a/examples/default/ios/Podfile.lock b/examples/default/ios/Podfile.lock index 230d764977..17f82a0820 100644 --- a/examples/default/ios/Podfile.lock +++ b/examples/default/ios/Podfile.lock @@ -73,9 +73,9 @@ PODS: - hermes-engine (0.72.3): - hermes-engine/Pre-built (= 0.72.3) - hermes-engine/Pre-built (0.72.3) - - Instabug (12.5.0) + - Instabug (12.2.0) - libevent (2.1.12) - - OCMock (3.9.3) + - OCMock (3.9.1) - OpenSSL-Universal (1.1.1100) - RCT-Folly (2021.07.22.00): - boost @@ -379,8 +379,6 @@ PODS: - glog - react-native-safe-area-context (4.7.1): - React-Core - - react-native-slider (4.4.3): - - React-Core - React-NativeModulesApple (0.72.3): - hermes-engine - React-callinvoker @@ -491,41 +489,9 @@ PODS: - React-jsi (= 0.72.3) - React-logger (= 0.72.3) - React-perflogger (= 0.72.3) - - RNGestureHandler (2.13.4): - - RCT-Folly (= 2021.07.22.00) - - React-Core - - RNInstabug (12.4.0): - - Instabug (= 12.5.0) - - React-Core - - RNReanimated (3.5.4): - - DoubleConversion - - FBLazyVector - - glog - - hermes-engine - - RCT-Folly - - RCTRequired - - RCTTypeSafety - - React-callinvoker + - RNInstabug (12.2.0): + - Instabug - React-Core - - React-Core/DevSupport - - React-Core/RCTWebSocket - - React-CoreModules - - React-cxxreact - - React-hermes - - React-jsi - - React-jsiexecutor - - React-jsinspector - - React-RCTActionSheet - - React-RCTAnimation - - React-RCTAppDelegate - - React-RCTBlob - - React-RCTImage - - React-RCTLinking - - React-RCTNetwork - - React-RCTSettings - - React-RCTText - - ReactCommon/turbomodule/core - - Yoga - RNScreens (3.24.0): - React-Core - React-RCTImage @@ -565,6 +531,7 @@ DEPENDENCIES: - FlipperKit/SKIOSNetworkPlugin (= 0.182.0) - glog (from `../node_modules/react-native/third-party-podspecs/glog.podspec`) - hermes-engine (from `../node_modules/react-native/sdks/hermes-engine/hermes-engine.podspec`) + - Instabug (from `https://ios-releases.instabug.com/custom/fix_crashes_screenshot_attachments_pods/12.2.0/Instabug.podspec`) - libevent (~> 2.1.12) - OCMock - OpenSSL-Universal (= 1.1.1100) @@ -586,7 +553,6 @@ DEPENDENCIES: - React-jsinspector (from `../node_modules/react-native/ReactCommon/jsinspector`) - React-logger (from `../node_modules/react-native/ReactCommon/logger`) - react-native-safe-area-context (from `../node_modules/react-native-safe-area-context`) - - "react-native-slider (from `../node_modules/@react-native-community/slider`)" - React-NativeModulesApple (from `../node_modules/react-native/ReactCommon/react/nativemodule/core/platform/ios`) - React-perflogger (from `../node_modules/react-native/ReactCommon/reactperflogger`) - React-RCTActionSheet (from `../node_modules/react-native/Libraries/ActionSheetIOS`) @@ -604,9 +570,7 @@ DEPENDENCIES: - React-runtimescheduler (from `../node_modules/react-native/ReactCommon/react/renderer/runtimescheduler`) - React-utils (from `../node_modules/react-native/ReactCommon/react/utils`) - ReactCommon/turbomodule/core (from `../node_modules/react-native/ReactCommon`) - - RNGestureHandler (from `../node_modules/react-native-gesture-handler`) - RNInstabug (from `../node_modules/instabug-reactnative`) - - RNReanimated (from `../node_modules/react-native-reanimated`) - RNScreens (from `../node_modules/react-native-screens`) - RNSVG (from `../node_modules/react-native-svg`) - RNVectorIcons (from `../node_modules/react-native-vector-icons`) @@ -624,7 +588,6 @@ SPEC REPOS: - Flipper-PeerTalk - FlipperKit - fmt - - Instabug - libevent - OCMock - OpenSSL-Universal @@ -645,6 +608,8 @@ EXTERNAL SOURCES: hermes-engine: :podspec: "../node_modules/react-native/sdks/hermes-engine/hermes-engine.podspec" :tag: hermes-2023-03-20-RNv0.72.0-49794cfc7c81fb8f69fd60c3bbf85a7480cc5a77 + Instabug: + :podspec: https://ios-releases.instabug.com/custom/fix_crashes_screenshot_attachments_pods/12.2.0/Instabug.podspec RCT-Folly: :podspec: "../node_modules/react-native/third-party-podspecs/RCT-Folly.podspec" RCTRequired: @@ -677,8 +642,6 @@ EXTERNAL SOURCES: :path: "../node_modules/react-native/ReactCommon/logger" react-native-safe-area-context: :path: "../node_modules/react-native-safe-area-context" - react-native-slider: - :path: "../node_modules/@react-native-community/slider" React-NativeModulesApple: :path: "../node_modules/react-native/ReactCommon/react/nativemodule/core/platform/ios" React-perflogger: @@ -713,12 +676,8 @@ EXTERNAL SOURCES: :path: "../node_modules/react-native/ReactCommon/react/utils" ReactCommon: :path: "../node_modules/react-native/ReactCommon" - RNGestureHandler: - :path: "../node_modules/react-native-gesture-handler" RNInstabug: :path: "../node_modules/instabug-reactnative" - RNReanimated: - :path: "../node_modules/react-native-reanimated" RNScreens: :path: "../node_modules/react-native-screens" RNSVG: @@ -729,7 +688,7 @@ EXTERNAL SOURCES: :path: "../node_modules/react-native/ReactCommon/yoga" SPEC CHECKSUMS: - boost: 7dcd2de282d72e344012f7d6564d024930a6a440 + boost: 57d2868c099736d80fcd648bf211b4431e51a558 CocoaAsyncSocket: 065fd1e645c7abab64f7a6a2007a48038fdc6a99 DoubleConversion: 5189b271737e1565bdce30deb4a08d647e3f5f54 FBLazyVector: 4cce221dd782d3ff7c4172167bba09d58af67ccb @@ -745,9 +704,9 @@ SPEC CHECKSUMS: fmt: ff9d55029c625d3757ed641535fd4a75fedc7ce9 glog: 04b94705f318337d7ead9e6d17c019bd9b1f6b1b hermes-engine: 10fbd3f62405c41ea07e71973ea61e1878d07322 - Instabug: 7c7421ae87838010b47a60d9b56378be2482ab64 + Instabug: 9810332cc836f15363c6139d815dab3f99a7bf15 libevent: 4049cae6c81cdb3654a443be001fb9bdceff7913 - OCMock: 300b1b1b9155cb6378660b981c2557448830bdc6 + OCMock: 9491e4bec59e0b267d52a9184ff5605995e74be8 OpenSSL-Universal: ebc357f1e6bc71fa463ccb2fe676756aff50e88c RCT-Folly: 424b8c9a7a0b9ab2886ffe9c3b041ef628fd4fb1 RCTRequired: a2faf4bad4e438ca37b2040cb8f7799baa065c18 @@ -765,7 +724,6 @@ SPEC CHECKSUMS: React-jsinspector: b511447170f561157547bc0bef3f169663860be7 React-logger: c5b527272d5f22eaa09bb3c3a690fee8f237ae95 react-native-safe-area-context: 9697629f7b2cda43cf52169bb7e0767d330648c2 - react-native-slider: 1cdd6ba29675df21f30544253bf7351d3c2d68c4 React-NativeModulesApple: c57f3efe0df288a6532b726ad2d0322a9bf38472 React-perflogger: 6bd153e776e6beed54c56b0847e1220a3ff92ba5 React-RCTActionSheet: c0b62af44e610e69d9a2049a682f5dba4e9dff17 @@ -783,9 +741,7 @@ SPEC CHECKSUMS: React-runtimescheduler: 837c1bebd2f84572db17698cd702ceaf585b0d9a React-utils: bcb57da67eec2711f8b353f6e3d33bd8e4b2efa3 ReactCommon: 3ccb8fb14e6b3277e38c73b0ff5e4a1b8db017a9 - RNGestureHandler: 6e46dde1f87e5f018a54fe5d40cd0e0b942b49ee - RNInstabug: 085f44cee15e8ea660bad3ce17ea575adb5ae5ce - RNReanimated: ab2e96c6d5591c3dfbb38a464f54c8d17fb34a87 + RNInstabug: 012b859e28e68ba275d2cd58b44ff997431d065f RNScreens: b21dc57dfa2b710c30ec600786a3fc223b1b92e7 RNSVG: 80584470ff1ffc7994923ea135a3e5ad825546b9 RNVectorIcons: 8b5bb0fa61d54cd2020af4f24a51841ce365c7e9 @@ -793,6 +749,6 @@ SPEC CHECKSUMS: Yoga: 8796b55dba14d7004f980b54bcc9833ee45b28ce YogaKit: f782866e155069a2cca2517aafea43200b01fd5a -PODFILE CHECKSUM: d169b4508f413ff5d69cdf38428960e0828e6282 +PODFILE CHECKSUM: f7940f1a1d813eda921bb2171b9e5376b9e829b5 COCOAPODS: 1.11.3 From b1cdf9e4a58c718e476d4de9f74c6005e98af6a2 Mon Sep 17 00:00:00 2001 From: AbdElHamid Nasser Date: Fri, 17 Nov 2023 21:43:04 +0200 Subject: [PATCH 12/30] chore(android): integrate crashes attachment logs snapshot --- android/native.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/android/native.gradle b/android/native.gradle index 8e1de8159d..3cfc94e24a 100644 --- a/android/native.gradle +++ b/android/native.gradle @@ -1,5 +1,5 @@ project.ext.instabug = [ - version: '12.2.0.5428088-SNAPSHOT' + version: '12.2.0.5448807-SNAPSHOT' ] dependencies { From d2825aff9c2220f1b4ff11726743b7bb48fb6de8 Mon Sep 17 00:00:00 2001 From: AbdElHamid Nasser Date: Mon, 27 Nov 2023 22:28:29 +0200 Subject: [PATCH 13/30] chore(android): integrate crash linking to V3 fix snapshot The snapshot resolves the issue where the RN fatal crashes were not properly linked with their corresponding V3 sessions. (12.3.1) This also incorporporates the first ANR fix [here](https://instabug.atlassian.net/browse/INSD-10492). Android PR: [\[INSD-10481\] fix RN unhandled exception is not linked to v3 session #5466](https://github.com/Instabug/android/pull/5466) --- android/native.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/android/native.gradle b/android/native.gradle index 3cfc94e24a..fc3c72c451 100644 --- a/android/native.gradle +++ b/android/native.gradle @@ -1,5 +1,5 @@ project.ext.instabug = [ - version: '12.2.0.5448807-SNAPSHOT' + version: '12.3.1.5466421-SNAPSHOT' ] dependencies { From 78237d3c43aa35ae6d48309b6a59ced9027a7dbc Mon Sep 17 00:00:00 2001 From: AbdElHamid Nasser Date: Thu, 30 Nov 2023 02:17:43 +0200 Subject: [PATCH 14/30] chore(android): Integrate ANR_CP_reportScreenChange snapshot - [ANR #3](https://instabug.atlassian.net/browse/INSD-10497) --- .circleci/config.yml | 1 - android/native.gradle | 2 +- 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index ac8a53781b..a7d80b3a17 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -367,7 +367,6 @@ workflows: - e2e_android - hold_generate_snapshot: type: approval - requires: *release_dependencies - generate_snapshot: requires: - hold_generate_snapshot diff --git a/android/native.gradle b/android/native.gradle index fc3c72c451..c1f7dca75f 100644 --- a/android/native.gradle +++ b/android/native.gradle @@ -1,5 +1,5 @@ project.ext.instabug = [ - version: '12.3.1.5466421-SNAPSHOT' + version: '12.3.1.5474838-SNAPSHOT' ] dependencies { From 03d3a5e4c575d9683a19379c14734b0487bd9fb6 Mon Sep 17 00:00:00 2001 From: Ahmed Mahmoud Date: Mon, 4 Dec 2023 00:10:35 +0200 Subject: [PATCH 15/30] chore(android): integrate revert ANR in report screen change snapshot --- android/native.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/android/native.gradle b/android/native.gradle index c1f7dca75f..745b02f6e3 100644 --- a/android/native.gradle +++ b/android/native.gradle @@ -1,5 +1,5 @@ project.ext.instabug = [ - version: '12.3.1.5474838-SNAPSHOT' + version: '12.4.0.5483989-SNAPSHOT' ] dependencies { From a4da3b66c22c0122b9783afb913b246ae9cf18ab Mon Sep 17 00:00:00 2001 From: AbdElHamid Nasser Date: Thu, 7 Dec 2023 19:19:28 +0200 Subject: [PATCH 16/30] chore(android): integrate ANR snapshot --- android/native.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/android/native.gradle b/android/native.gradle index 745b02f6e3..8a893b44d5 100644 --- a/android/native.gradle +++ b/android/native.gradle @@ -1,5 +1,5 @@ project.ext.instabug = [ - version: '12.4.0.5483989-SNAPSHOT' + version: '12.4.0.5496002-SNAPSHOT' ] dependencies { From 90af8a1575b3a0475f1422706d797cf06d04679b Mon Sep 17 00:00:00 2001 From: AbdElHamid Nasser Date: Thu, 7 Dec 2023 19:44:16 +0200 Subject: [PATCH 17/30] chore: update Podfile.lock --- examples/default/ios/Podfile.lock | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/examples/default/ios/Podfile.lock b/examples/default/ios/Podfile.lock index 17f82a0820..edf5363a41 100644 --- a/examples/default/ios/Podfile.lock +++ b/examples/default/ios/Podfile.lock @@ -489,7 +489,7 @@ PODS: - React-jsi (= 0.72.3) - React-logger (= 0.72.3) - React-perflogger (= 0.72.3) - - RNInstabug (12.2.0): + - RNInstabug (12.4.0): - Instabug - React-Core - RNScreens (3.24.0): @@ -741,7 +741,7 @@ SPEC CHECKSUMS: React-runtimescheduler: 837c1bebd2f84572db17698cd702ceaf585b0d9a React-utils: bcb57da67eec2711f8b353f6e3d33bd8e4b2efa3 ReactCommon: 3ccb8fb14e6b3277e38c73b0ff5e4a1b8db017a9 - RNInstabug: 012b859e28e68ba275d2cd58b44ff997431d065f + RNInstabug: a0c5e130f55637d0e41d4070f7cb37f1798d7226 RNScreens: b21dc57dfa2b710c30ec600786a3fc223b1b92e7 RNSVG: 80584470ff1ffc7994923ea135a3e5ad825546b9 RNVectorIcons: 8b5bb0fa61d54cd2020af4f24a51841ce365c7e9 From 0241ed52ecb158b1bc0044b117de36e842e84207 Mon Sep 17 00:00:00 2001 From: AbdElHamid Nasser Date: Mon, 11 Dec 2023 03:28:37 +0200 Subject: [PATCH 18/30] chore(ios): integrate code push snapshot [[IBGCRASH-15935] Support Code push version #3983](https://github.com/Instabug/ios/pull/3983/files#diff-b36a36734f07e9242812623731188102ff0aa71c5c477b6b65616dcf301da15a) --- examples/default/ios/Podfile | 2 +- examples/default/ios/Podfile.lock | 10 +++++----- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/examples/default/ios/Podfile b/examples/default/ios/Podfile index f9f1186896..2a118cb9d1 100644 --- a/examples/default/ios/Podfile +++ b/examples/default/ios/Podfile @@ -26,7 +26,7 @@ target 'InstabugExample' do # Flags change depending on the env values. flags = get_default_flags() - pod ‘Instabug’, :podspec => ’https://ios-releases.instabug.com/custom/fix_crashes_screenshot_attachments_pods/12.2.0/Instabug.podspec' + pod 'Instabug', :podspec => 'https://ios-releases.instabug.com/custom/fearure-crashes-add-code-push-version/12.4.0/Instabug.podspec' use_react_native!( :path => config[:reactNativePath], # Hermes is now enabled by default. Disable by setting this flag to false. diff --git a/examples/default/ios/Podfile.lock b/examples/default/ios/Podfile.lock index edf5363a41..18114c871d 100644 --- a/examples/default/ios/Podfile.lock +++ b/examples/default/ios/Podfile.lock @@ -73,7 +73,7 @@ PODS: - hermes-engine (0.72.3): - hermes-engine/Pre-built (= 0.72.3) - hermes-engine/Pre-built (0.72.3) - - Instabug (12.2.0) + - Instabug (12.4.0) - libevent (2.1.12) - OCMock (3.9.1) - OpenSSL-Universal (1.1.1100) @@ -531,7 +531,7 @@ DEPENDENCIES: - FlipperKit/SKIOSNetworkPlugin (= 0.182.0) - glog (from `../node_modules/react-native/third-party-podspecs/glog.podspec`) - hermes-engine (from `../node_modules/react-native/sdks/hermes-engine/hermes-engine.podspec`) - - Instabug (from `https://ios-releases.instabug.com/custom/fix_crashes_screenshot_attachments_pods/12.2.0/Instabug.podspec`) + - Instabug (from `https://ios-releases.instabug.com/custom/fearure-crashes-add-code-push-version/12.4.0/Instabug.podspec`) - libevent (~> 2.1.12) - OCMock - OpenSSL-Universal (= 1.1.1100) @@ -609,7 +609,7 @@ EXTERNAL SOURCES: :podspec: "../node_modules/react-native/sdks/hermes-engine/hermes-engine.podspec" :tag: hermes-2023-03-20-RNv0.72.0-49794cfc7c81fb8f69fd60c3bbf85a7480cc5a77 Instabug: - :podspec: https://ios-releases.instabug.com/custom/fix_crashes_screenshot_attachments_pods/12.2.0/Instabug.podspec + :podspec: https://ios-releases.instabug.com/custom/fearure-crashes-add-code-push-version/12.4.0/Instabug.podspec RCT-Folly: :podspec: "../node_modules/react-native/third-party-podspecs/RCT-Folly.podspec" RCTRequired: @@ -704,7 +704,7 @@ SPEC CHECKSUMS: fmt: ff9d55029c625d3757ed641535fd4a75fedc7ce9 glog: 04b94705f318337d7ead9e6d17c019bd9b1f6b1b hermes-engine: 10fbd3f62405c41ea07e71973ea61e1878d07322 - Instabug: 9810332cc836f15363c6139d815dab3f99a7bf15 + Instabug: ff8167e76606e3a0f0907495eaf0fda045701e27 libevent: 4049cae6c81cdb3654a443be001fb9bdceff7913 OCMock: 9491e4bec59e0b267d52a9184ff5605995e74be8 OpenSSL-Universal: ebc357f1e6bc71fa463ccb2fe676756aff50e88c @@ -749,6 +749,6 @@ SPEC CHECKSUMS: Yoga: 8796b55dba14d7004f980b54bcc9833ee45b28ce YogaKit: f782866e155069a2cca2517aafea43200b01fd5a -PODFILE CHECKSUM: f7940f1a1d813eda921bb2171b9e5376b9e829b5 +PODFILE CHECKSUM: 981fe961279ed821d35acf584e71ab178474642e COCOAPODS: 1.11.3 From f45155022d43b607dbe375ae44980e721f79067d Mon Sep 17 00:00:00 2001 From: AbdElHamid Nasser Date: Mon, 11 Dec 2023 03:28:46 +0200 Subject: [PATCH 19/30] chore(android): integrate code push snapshot [[IBGCRASH-15934] Adding code push support. #4576](https://github.com/Instabug/android/pull/4576/files#diff-1c57a7b8eaa74ef47af7bda392e42f434ec316e464f9a793e6acdb476d831578) --- android/native.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/android/native.gradle b/android/native.gradle index 8a893b44d5..3b43421690 100644 --- a/android/native.gradle +++ b/android/native.gradle @@ -1,5 +1,5 @@ project.ext.instabug = [ - version: '12.4.0.5496002-SNAPSHOT' + version: '12.4.0.4576085-SNAPSHOT' ] dependencies { From 9ae9276a80bfaa358384ad9452bfc61b46064c7f Mon Sep 17 00:00:00 2001 From: AbdElHamid Nasser Date: Mon, 11 Dec 2023 16:28:58 +0200 Subject: [PATCH 20/30] feat(android): support code push --- .../com/instabug/reactlibrary/RNInstabug.java | 115 ++++++++++++++- .../RNInstabugReactnativeModule.java | 20 ++- .../instabug/reactlibrary/RNInstabugTest.java | 134 ++++++++++++++++++ 3 files changed, 266 insertions(+), 3 deletions(-) diff --git a/android/src/main/java/com/instabug/reactlibrary/RNInstabug.java b/android/src/main/java/com/instabug/reactlibrary/RNInstabug.java index 7ea469ddbf..9b6348ab43 100644 --- a/android/src/main/java/com/instabug/reactlibrary/RNInstabug.java +++ b/android/src/main/java/com/instabug/reactlibrary/RNInstabug.java @@ -18,7 +18,7 @@ public class RNInstabug { private static RNInstabug instance; - + private RNInstabug() {} @@ -133,4 +133,117 @@ public void setBaseUrlForDeprecationLogs() { e.printStackTrace(); } } + + public static class Builder { + + /** + * Application instance to initialize Instabug. + */ + private Application application; + + /** + * The application token obtained from the Instabug dashboard. + */ + private String applicationToken; + + /** + * The level of detail in logs that you want to print. + */ + private int logLevel = LogLevel.ERROR; + + /** + * The Code Push version to be used for all reports. + */ + private String codePushVersion; + + /** + * The events that trigger the SDK's user interface. + */ + private InstabugInvocationEvent[] invocationEvents; + + + /** + * Initialize Instabug SDK with application token + * + * @param application Application object for initialization of library + * @param applicationToken The app's identifying token, available on your dashboard. + */ + public Builder(Application application, String applicationToken) { + this.application = application; + this.applicationToken = applicationToken; + } + + /** + * Initialize Instabug SDK with application token and invocation trigger events + * + * @param application Application object for initialization of library + * @param applicationToken The app's identifying token, available on your dashboard. + * @param invocationEvents The events that trigger the SDK's user interface. + *

Choose from the available events listed in {@link InstabugInvocationEvent}.

+ */ + public Builder(Application application, String applicationToken, InstabugInvocationEvent... invocationEvents) { + this.application = application; + this.applicationToken = applicationToken; + this.invocationEvents = invocationEvents; + } + + /** + * Sets the filtering level for printed SDK logs. + * + * @param logLevel The log filtering level to be set. + * Choose from {@link LogLevel} constants: + * {@link LogLevel#NONE}, {@link LogLevel#ERROR}, {@link LogLevel#DEBUG}, or {@link LogLevel#VERBOSE}. + *

Default level is {@link LogLevel#ERROR}.

+ */ + public Builder setLogLevel(int logLevel) { + this.logLevel = logLevel; + return this; + } + + /** + * Sets Code Push version to be used for all reports. + * + * @param codePushVersion the Code Push version to work with. + */ + public Builder setCodePushVersion(String codePushVersion) { + this.codePushVersion = codePushVersion; + return this; + } + + /** + * Sets the invocation triggering events for the SDK's user interface + * + * @param invocationEvents The events that trigger the SDK's user interface. + * Choose from the available events listed in {@link InstabugInvocationEvent}. + */ + public Builder setInvocationEvents(InstabugInvocationEvent... invocationEvents) { + this.invocationEvents = invocationEvents; + return this; + } + + /** + * Builds the Instabug instance with the provided configurations. + */ + public void build() { + try { + RNInstabug.getInstance().setBaseUrlForDeprecationLogs(); + RNInstabug.getInstance().setCurrentPlatform(); + + Instabug.Builder instabugBuilder = new Instabug.Builder(application, applicationToken) + .setInvocationEvents(invocationEvents) + .setSdkDebugLogsLevel(logLevel); + + if (codePushVersion != null) { + instabugBuilder.setCodePushVersion(codePushVersion); + } + + instabugBuilder.build(); + + // Temporarily disabling APM hot launches + APM.setHotAppLaunchEnabled(false); + } catch (Exception e) { + e.printStackTrace(); + } + } + } } diff --git a/android/src/main/java/com/instabug/reactlibrary/RNInstabugReactnativeModule.java b/android/src/main/java/com/instabug/reactlibrary/RNInstabugReactnativeModule.java index 46814e53ec..6692a25972 100644 --- a/android/src/main/java/com/instabug/reactlibrary/RNInstabugReactnativeModule.java +++ b/android/src/main/java/com/instabug/reactlibrary/RNInstabugReactnativeModule.java @@ -50,6 +50,8 @@ import java.util.Locale; import java.util.Map; +import javax.annotation.Nullable; + /** * The type Rn instabug reactnative module. @@ -117,9 +119,16 @@ public void run() { * Initializes the SDK. * @param token The token that identifies the app. You can find it on your dashboard. * @param invocationEventValues The events that invoke the SDK's UI. + * @param logLevel The level of detail in logs that you want to print. + * @param codePushVersion The Code Push version to be used for all reports. */ @ReactMethod - public void init(final String token, final ReadableArray invocationEventValues, final String logLevel) { + public void init( + final String token, + final ReadableArray invocationEventValues, + final String logLevel, + @Nullable final String codePushVersion + ) { MainThreadHandler.runOnMainThread(new Runnable() { @Override public void run() { @@ -130,7 +139,14 @@ public void run() { final Application application = (Application) reactContext.getApplicationContext(); - RNInstabug.getInstance().init(application, token, parsedLogLevel, invocationEvents); + RNInstabug.Builder builder = new RNInstabug.Builder(application, token) + .setInvocationEvents(invocationEvents) + .setLogLevel(parsedLogLevel); + + if(codePushVersion != null) { + builder.setCodePushVersion(codePushVersion); + } + builder.build(); } }); } diff --git a/android/src/test/java/com/instabug/reactlibrary/RNInstabugTest.java b/android/src/test/java/com/instabug/reactlibrary/RNInstabugTest.java index df169df1e1..fde1fc8d01 100644 --- a/android/src/test/java/com/instabug/reactlibrary/RNInstabugTest.java +++ b/android/src/test/java/com/instabug/reactlibrary/RNInstabugTest.java @@ -10,6 +10,7 @@ import static org.mockito.Mockito.mockStatic; import static org.mockito.Mockito.spy; import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.verifyNoMoreInteractions; import static org.mockito.Mockito.when; import android.app.Application; @@ -112,6 +113,139 @@ public void testSetDeprecationBaseUrl() { reflected.verify(() -> MockReflected.setBaseUrl(any())); } + + @Test + public void testBuildWithoutLogLevelShouldSetLogLevelToError() { + final String token = "fde...."; + + + MockedConstruction mInstabugBuilder = mockConstruction(Instabug.Builder.class, (mock, context) -> { + String actualToken = (String) context.arguments().get(1); + // Initializes Instabug with the correct token + assertEquals(token, actualToken); + when(mock.setSdkDebugLogsLevel(anyInt())).thenReturn(mock); + when(mock.setInvocationEvents(any())).thenReturn(mock); + }); + + new RNInstabug.Builder(mContext, token) + .build(); + + Instabug.Builder builder = mInstabugBuilder.constructed().get(0); + + verify(builder).setSdkDebugLogsLevel(LogLevel.ERROR); + verify(builder).setInvocationEvents(null); + verify(builder).build(); + + +// verify(sut).setBaseUrlForDeprecationLogs(); +// verify(sut).setCurrentPlatform(); + + + mInstabugBuilder.close(); + } + + @Test + public void testBuildWithVerboseLogLevel() { + final String token = "fde...."; + final int logLevel = LogLevel.VERBOSE; + + + MockedConstruction mInstabugBuilder = mockConstruction(Instabug.Builder.class, (mock, context) -> { + String actualToken = (String) context.arguments().get(1); + // Initializes Instabug with the correct token + assertEquals(token, actualToken); + when(mock.setSdkDebugLogsLevel(anyInt())).thenReturn(mock); + when(mock.setInvocationEvents(any())).thenReturn(mock); + }); + + new RNInstabug.Builder(mContext, token) + .setLogLevel(logLevel) + .build(); + + Instabug.Builder builder = mInstabugBuilder.constructed().get(0); + + verify(builder).setSdkDebugLogsLevel(logLevel); + verify(builder).setInvocationEvents(null); + verify(builder).build(); + + + verify(sut).setBaseUrlForDeprecationLogs(); + verify(sut).setCurrentPlatform(); + + + mInstabugBuilder.close(); + } + + @Test + public void testBuildWithInvocationEvents() { + final InstabugInvocationEvent[] invocationEvents = new InstabugInvocationEvent[]{InstabugInvocationEvent.FLOATING_BUTTON}; + final String token = "fde...."; + + + MockedConstruction mInstabugBuilder = mockConstruction(Instabug.Builder.class, (mock, context) -> { + String actualToken = (String) context.arguments().get(1); + // Initializes Instabug with the correct token + assertEquals(token, actualToken); + when(mock.setSdkDebugLogsLevel(anyInt())).thenReturn(mock); + when(mock.setInvocationEvents(any())).thenReturn(mock); + }); + + new RNInstabug.Builder(mContext, token) + .setInvocationEvents(invocationEvents) + .build(); + + Instabug.Builder builder = mInstabugBuilder.constructed().get(0); + + verify(builder).setSdkDebugLogsLevel(LogLevel.ERROR); + verify(builder).setInvocationEvents(invocationEvents); + verify(builder).build(); + + +// verify(sut).setBaseUrlForDeprecationLogs(); +// verify(sut).setCurrentPlatform(); + + + mInstabugBuilder.close(); + } + + @Test + public void testBuildWithCodePushVersion() { + final InstabugInvocationEvent[] invocationEvents = new InstabugInvocationEvent[]{InstabugInvocationEvent.FLOATING_BUTTON}; + final String token = "fde...."; + final String codePushVersion = "1.0.0(1)"; + + + MockedConstruction mInstabugBuilder = mockConstruction(Instabug.Builder.class, (mock, context) -> { + String actualToken = (String) context.arguments().get(1); + // Initializes Instabug with the correct token + assertEquals(token, actualToken); + when(mock.setSdkDebugLogsLevel(anyInt())).thenReturn(mock); + when(mock.setInvocationEvents(any())).thenReturn(mock); + when(mock.setCodePushVersion(any())).thenReturn(mock); + }); + + new RNInstabug.Builder(mContext, token) + .setLogLevel(LogLevel.ERROR) + .setInvocationEvents(null) + .setCodePushVersion(codePushVersion) + .build(); + + Instabug.Builder builder = mInstabugBuilder.constructed().get(0); + + verify(builder).setSdkDebugLogsLevel(LogLevel.ERROR); + verify(builder).setCodePushVersion(codePushVersion); + verify(builder).setInvocationEvents(null); + verify(builder).build(); + + +// verify(sut).setBaseUrlForDeprecationLogs(); +// verify(sut).setCurrentPlatform(); + + verifyNoMoreInteractions(sut); + + + mInstabugBuilder.close(); + } } From 1fe20cc6c9758ef80cd138c92ec6822da9b63bc7 Mon Sep 17 00:00:00 2001 From: AbdElHamid Nasser Date: Mon, 11 Dec 2023 16:29:18 +0200 Subject: [PATCH 21/30] feat(ios): support code push --- .../default/ios/InstabugTests/InstabugSampleTests.m | 7 ++++++- examples/default/ios/InstabugTests/RNInstabugTests.m | 7 +++++++ ios/RNInstabug/InstabugReactBridge.h | 2 +- ios/RNInstabug/InstabugReactBridge.m | 11 +++++++++-- ios/RNInstabug/RNInstabug.h | 11 +++++++++++ ios/RNInstabug/RNInstabug.m | 4 ++++ 6 files changed, 38 insertions(+), 4 deletions(-) diff --git a/examples/default/ios/InstabugTests/InstabugSampleTests.m b/examples/default/ios/InstabugTests/InstabugSampleTests.m index 2e6445b5ba..05e085ee3d 100644 --- a/examples/default/ios/InstabugTests/InstabugSampleTests.m +++ b/examples/default/ios/InstabugTests/InstabugSampleTests.m @@ -65,12 +65,17 @@ - (void)testSetEnabled { } - (void)testInit { + id mock = OCMClassMock([Instabug class]); IBGInvocationEvent floatingButtonInvocationEvent = IBGInvocationEventFloatingButton; NSString *appToken = @"app_token"; + NSString *codePushVersion = @"1.0.0(1)"; NSArray *invocationEvents = [NSArray arrayWithObjects:[NSNumber numberWithInteger:floatingButtonInvocationEvent], nil]; IBGSDKDebugLogsLevel sdkDebugLogsLevel = IBGSDKDebugLogsLevelDebug; + + OCMStub([mock setCodePushVersion:codePushVersion]); - [self.instabugBridge init:appToken invocationEvents:invocationEvents debugLogsLevel:sdkDebugLogsLevel]; + [self.instabugBridge init:appToken invocationEvents:invocationEvents debugLogsLevel:sdkDebugLogsLevel codePushVersion:codePushVersion]; + OCMVerify([mock setCodePushVersion:codePushVersion]); OCMVerify([self.mRNInstabug initWithToken:appToken invocationEvents:floatingButtonInvocationEvent debugLogsLevel:sdkDebugLogsLevel]); } diff --git a/examples/default/ios/InstabugTests/RNInstabugTests.m b/examples/default/ios/InstabugTests/RNInstabugTests.m index 9ceed36621..7f1ddcd00f 100644 --- a/examples/default/ios/InstabugTests/RNInstabugTests.m +++ b/examples/default/ios/InstabugTests/RNInstabugTests.m @@ -68,4 +68,11 @@ - (void)testInitWithLogsLevel { OCMVerify([self.mIBGNetworkLogger setEnabled:YES]); } +- (void) testSetCodePushVersion { + NSString *codePushVersion = @"1.0.0(1)"; + [RNInstabug setCodePushVersion:codePushVersion]; + + OCMVerify([self.mInstabug setCodePushVersion:codePushVersion]); +} + @end diff --git a/ios/RNInstabug/InstabugReactBridge.h b/ios/RNInstabug/InstabugReactBridge.h index cc90bb86c1..24baf146a3 100644 --- a/ios/RNInstabug/InstabugReactBridge.h +++ b/ios/RNInstabug/InstabugReactBridge.h @@ -27,7 +27,7 @@ - (void)setEnabled:(BOOL)isEnabled; -- (void)init:(NSString *)token invocationEvents:(NSArray *)invocationEventsArray debugLogsLevel:(IBGSDKDebugLogsLevel)sdkDebugLogsLevel; +- (void)init:(NSString *)token invocationEvents:(NSArray *)invocationEventsArray debugLogsLevel:(IBGSDKDebugLogsLevel)sdkDebugLogsLevel codePushVersion:(NSString *)codePushVersion; - (void)setUserData:(NSString *)userData; diff --git a/ios/RNInstabug/InstabugReactBridge.m b/ios/RNInstabug/InstabugReactBridge.m index bf97d0ff99..ed512fe328 100644 --- a/ios/RNInstabug/InstabugReactBridge.m +++ b/ios/RNInstabug/InstabugReactBridge.m @@ -37,14 +37,21 @@ - (dispatch_queue_t)methodQueue { Instabug.enabled = isEnabled; } -RCT_EXPORT_METHOD(init:(NSString *)token invocationEvents:(NSArray*)invocationEventsArray debugLogsLevel:(IBGSDKDebugLogsLevel)sdkDebugLogsLevel) { +RCT_EXPORT_METHOD(init:(NSString *)token + invocationEvents:(NSArray *)invocationEventsArray + debugLogsLevel:(IBGSDKDebugLogsLevel)sdkDebugLogsLevel + codePushVersion:(NSString *)codePushVersion) { IBGInvocationEvent invocationEvents = 0; for (NSNumber *boxedValue in invocationEventsArray) { invocationEvents |= [boxedValue intValue]; } - [RNInstabug initWithToken:token invocationEvents:invocationEvents debugLogsLevel:sdkDebugLogsLevel]; + [Instabug setCodePushVersion:codePushVersion]; + + [RNInstabug initWithToken:token + invocationEvents:invocationEvents + debugLogsLevel:sdkDebugLogsLevel]; } RCT_EXPORT_METHOD(setReproStepsConfig:(IBGUserStepsMode)bugMode :(IBGUserStepsMode)crashMode:(IBGUserStepsMode)sessionReplayMode) { diff --git a/ios/RNInstabug/RNInstabug.h b/ios/RNInstabug/RNInstabug.h index b18b4d41fa..e42b38844b 100644 --- a/ios/RNInstabug/RNInstabug.h +++ b/ios/RNInstabug/RNInstabug.h @@ -8,6 +8,17 @@ + (void)initWithToken:(NSString *)token invocationEvents:(IBGInvocationEvent)invocationEvents debugLogsLevel:(IBGSDKDebugLogsLevel)debugLogsLevel; + (void)initWithToken:(NSString *)token invocationEvents:(IBGInvocationEvent)invocationEvents; +/** + @brief Set codePush version before starting the SDK. + + @discussion Sets Code Push version to be used for all reports. + should be called from `-[UIApplicationDelegate application:didFinishLaunchingWithOptions:]` + and before `startWithToken`. + + @param codePushVersion the Code Push version to be used for all reports. + */ ++ (void)setCodePushVersion:(NSString *)codePushVersion; + @end #endif /* RNInstabug_h */ diff --git a/ios/RNInstabug/RNInstabug.m b/ios/RNInstabug/RNInstabug.m index 209670a5ee..e79b33334d 100644 --- a/ios/RNInstabug/RNInstabug.m +++ b/ios/RNInstabug/RNInstabug.m @@ -49,6 +49,10 @@ + (void)initWithToken:(NSString *)token [self initWithToken:token invocationEvents:invocationEvents]; } ++ (void)setCodePushVersion:(NSString *)codePushVersion { + [Instabug setCodePushVersion:codePushVersion]; +} + // Note: This function is used to bridge IBGNSLog with RCTLogFunction. // This log function should not be used externally and is only an implementation detail. void RNIBGLog(IBGLogLevel logLevel, NSString *format, ...) { From 067554d4817a9c62ce71b106b276474cae971d2a Mon Sep 17 00:00:00 2001 From: AbdElHamid Nasser Date: Mon, 11 Dec 2023 16:29:58 +0200 Subject: [PATCH 22/30] feat: support code push --- src/models/InstabugConfig.ts | 5 +++++ src/modules/Instabug.ts | 1 + src/native/NativeInstabug.ts | 7 ++++++- test/modules/Instabug.spec.ts | 2 ++ 4 files changed, 14 insertions(+), 1 deletion(-) diff --git a/src/models/InstabugConfig.ts b/src/models/InstabugConfig.ts index 36770c94a0..0eda7a3187 100644 --- a/src/models/InstabugConfig.ts +++ b/src/models/InstabugConfig.ts @@ -13,4 +13,9 @@ export interface InstabugConfig { * An optional LogLevel to indicate the verbosity of SDK logs. Default is Error. */ debugLogsLevel?: LogLevel; + + /** + * An optional code push version to be used for all reports. + */ + codePushVersion?: string; } diff --git a/src/modules/Instabug.ts b/src/modules/Instabug.ts index 399464f0d0..cf0debc9a9 100644 --- a/src/modules/Instabug.ts +++ b/src/modules/Instabug.ts @@ -67,6 +67,7 @@ export const init = (config: InstabugConfig) => { config.token, config.invocationEvents, config.debugLogsLevel ?? LogLevel.error, + config.codePushVersion, ); _isFirstScreen = true; diff --git a/src/native/NativeInstabug.ts b/src/native/NativeInstabug.ts index 14b306554f..b8b1d912f3 100644 --- a/src/native/NativeInstabug.ts +++ b/src/native/NativeInstabug.ts @@ -19,7 +19,12 @@ export interface InstabugNativeModule extends NativeModule { // Essential APIs // setEnabled(isEnabled: boolean): void; - init(token: string, invocationEvents: InvocationEvent[], debugLogsLevel: LogLevel): void; + init( + token: string, + invocationEvents: InvocationEvent[], + debugLogsLevel: LogLevel, + codePushVersion?: string, + ): void; show(): void; // Misc APIs // diff --git a/test/modules/Instabug.spec.ts b/test/modules/Instabug.spec.ts index 06f0e770af..c8019c1ea8 100644 --- a/test/modules/Instabug.spec.ts +++ b/test/modules/Instabug.spec.ts @@ -237,6 +237,7 @@ describe('Instabug Module', () => { token: 'some-token', invocationEvents: [InvocationEvent.floatingButton, InvocationEvent.shake], debugLogsLevel: LogLevel.debug, + codePushVersion: '1.1.0', }; Instabug.init(instabugConfig); @@ -245,6 +246,7 @@ describe('Instabug Module', () => { instabugConfig.token, instabugConfig.invocationEvents, instabugConfig.debugLogsLevel, + instabugConfig.codePushVersion, ); }); From d87f14a7a4cbe687220883866689b235427ad369 Mon Sep 17 00:00:00 2001 From: Ahmed Mahmoud Date: Mon, 11 Dec 2023 23:14:02 +0200 Subject: [PATCH 23/30] chore(android): integrate current view discrepancy fix snapshot --- android/native.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/android/native.gradle b/android/native.gradle index 3b43421690..55a799e493 100644 --- a/android/native.gradle +++ b/android/native.gradle @@ -1,5 +1,5 @@ project.ext.instabug = [ - version: '12.4.0.4576085-SNAPSHOT' + version: '12.4.0.5503557-SNAPSHOT' ] dependencies { From aa988eb69196185c68acf1afc1acb64437770a0f Mon Sep 17 00:00:00 2001 From: Ahmed Mahmoud Date: Tue, 12 Dec 2023 22:41:42 +0200 Subject: [PATCH 24/30] Revert "chore(android): integrate current view discrepancy fix snapshot" This reverts commit 9f2db1981032250379cb0d82e4dc3738249788ee. --- android/native.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/android/native.gradle b/android/native.gradle index 55a799e493..3b43421690 100644 --- a/android/native.gradle +++ b/android/native.gradle @@ -1,5 +1,5 @@ project.ext.instabug = [ - version: '12.4.0.5503557-SNAPSHOT' + version: '12.4.0.4576085-SNAPSHOT' ] dependencies { From 0b4bfc60cacfa3bc00934e1ff417811d81df155a Mon Sep 17 00:00:00 2001 From: Ahmed Mahmoud Date: Tue, 12 Dec 2023 22:43:36 +0200 Subject: [PATCH 25/30] chore(ios): integrate crash fix snapshot --- examples/default/ios/Podfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/default/ios/Podfile b/examples/default/ios/Podfile index 2a118cb9d1..32c0968386 100644 --- a/examples/default/ios/Podfile +++ b/examples/default/ios/Podfile @@ -26,7 +26,7 @@ target 'InstabugExample' do # Flags change depending on the env values. flags = get_default_flags() - pod 'Instabug', :podspec => 'https://ios-releases.instabug.com/custom/fearure-crashes-add-code-push-version/12.4.0/Instabug.podspec' + pod 'Instabug', :podspec => 'https://ios-releases.instabug.com/custom/custom_build-session_replay_crash_code_push/12.4.1/Instabug.podspec' use_react_native!( :path => config[:reactNativePath], # Hermes is now enabled by default. Disable by setting this flag to false. From 4698a3a96ac004d6d679ff554795d85f65eed71d Mon Sep 17 00:00:00 2001 From: Ahmed Mahmoud Date: Tue, 12 Dec 2023 22:52:00 +0200 Subject: [PATCH 26/30] chore(ios): update podfile lock --- examples/default/ios/Podfile.lock | 56 ++++++++++++++++++++++++++++--- 1 file changed, 51 insertions(+), 5 deletions(-) diff --git a/examples/default/ios/Podfile.lock b/examples/default/ios/Podfile.lock index 18114c871d..483a8e4a91 100644 --- a/examples/default/ios/Podfile.lock +++ b/examples/default/ios/Podfile.lock @@ -73,7 +73,7 @@ PODS: - hermes-engine (0.72.3): - hermes-engine/Pre-built (= 0.72.3) - hermes-engine/Pre-built (0.72.3) - - Instabug (12.4.0) + - Instabug (12.4.1) - libevent (2.1.12) - OCMock (3.9.1) - OpenSSL-Universal (1.1.1100) @@ -379,6 +379,8 @@ PODS: - glog - react-native-safe-area-context (4.7.1): - React-Core + - react-native-slider (4.4.3): + - React-Core - React-NativeModulesApple (0.72.3): - hermes-engine - React-callinvoker @@ -489,9 +491,41 @@ PODS: - React-jsi (= 0.72.3) - React-logger (= 0.72.3) - React-perflogger (= 0.72.3) + - RNGestureHandler (2.13.4): + - RCT-Folly (= 2021.07.22.00) + - React-Core - RNInstabug (12.4.0): - Instabug - React-Core + - RNReanimated (3.5.4): + - DoubleConversion + - FBLazyVector + - glog + - hermes-engine + - RCT-Folly + - RCTRequired + - RCTTypeSafety + - React-callinvoker + - React-Core + - React-Core/DevSupport + - React-Core/RCTWebSocket + - React-CoreModules + - React-cxxreact + - React-hermes + - React-jsi + - React-jsiexecutor + - React-jsinspector + - React-RCTActionSheet + - React-RCTAnimation + - React-RCTAppDelegate + - React-RCTBlob + - React-RCTImage + - React-RCTLinking + - React-RCTNetwork + - React-RCTSettings + - React-RCTText + - ReactCommon/turbomodule/core + - Yoga - RNScreens (3.24.0): - React-Core - React-RCTImage @@ -531,7 +565,7 @@ DEPENDENCIES: - FlipperKit/SKIOSNetworkPlugin (= 0.182.0) - glog (from `../node_modules/react-native/third-party-podspecs/glog.podspec`) - hermes-engine (from `../node_modules/react-native/sdks/hermes-engine/hermes-engine.podspec`) - - Instabug (from `https://ios-releases.instabug.com/custom/fearure-crashes-add-code-push-version/12.4.0/Instabug.podspec`) + - Instabug (from `https://ios-releases.instabug.com/custom/custom_build-session_replay_crash_code_push/12.4.1/Instabug.podspec`) - libevent (~> 2.1.12) - OCMock - OpenSSL-Universal (= 1.1.1100) @@ -553,6 +587,7 @@ DEPENDENCIES: - React-jsinspector (from `../node_modules/react-native/ReactCommon/jsinspector`) - React-logger (from `../node_modules/react-native/ReactCommon/logger`) - react-native-safe-area-context (from `../node_modules/react-native-safe-area-context`) + - "react-native-slider (from `../node_modules/@react-native-community/slider`)" - React-NativeModulesApple (from `../node_modules/react-native/ReactCommon/react/nativemodule/core/platform/ios`) - React-perflogger (from `../node_modules/react-native/ReactCommon/reactperflogger`) - React-RCTActionSheet (from `../node_modules/react-native/Libraries/ActionSheetIOS`) @@ -570,7 +605,9 @@ DEPENDENCIES: - React-runtimescheduler (from `../node_modules/react-native/ReactCommon/react/renderer/runtimescheduler`) - React-utils (from `../node_modules/react-native/ReactCommon/react/utils`) - ReactCommon/turbomodule/core (from `../node_modules/react-native/ReactCommon`) + - RNGestureHandler (from `../node_modules/react-native-gesture-handler`) - RNInstabug (from `../node_modules/instabug-reactnative`) + - RNReanimated (from `../node_modules/react-native-reanimated`) - RNScreens (from `../node_modules/react-native-screens`) - RNSVG (from `../node_modules/react-native-svg`) - RNVectorIcons (from `../node_modules/react-native-vector-icons`) @@ -609,7 +646,7 @@ EXTERNAL SOURCES: :podspec: "../node_modules/react-native/sdks/hermes-engine/hermes-engine.podspec" :tag: hermes-2023-03-20-RNv0.72.0-49794cfc7c81fb8f69fd60c3bbf85a7480cc5a77 Instabug: - :podspec: https://ios-releases.instabug.com/custom/fearure-crashes-add-code-push-version/12.4.0/Instabug.podspec + :podspec: https://ios-releases.instabug.com/custom/custom_build-session_replay_crash_code_push/12.4.1/Instabug.podspec RCT-Folly: :podspec: "../node_modules/react-native/third-party-podspecs/RCT-Folly.podspec" RCTRequired: @@ -642,6 +679,8 @@ EXTERNAL SOURCES: :path: "../node_modules/react-native/ReactCommon/logger" react-native-safe-area-context: :path: "../node_modules/react-native-safe-area-context" + react-native-slider: + :path: "../node_modules/@react-native-community/slider" React-NativeModulesApple: :path: "../node_modules/react-native/ReactCommon/react/nativemodule/core/platform/ios" React-perflogger: @@ -676,8 +715,12 @@ EXTERNAL SOURCES: :path: "../node_modules/react-native/ReactCommon/react/utils" ReactCommon: :path: "../node_modules/react-native/ReactCommon" + RNGestureHandler: + :path: "../node_modules/react-native-gesture-handler" RNInstabug: :path: "../node_modules/instabug-reactnative" + RNReanimated: + :path: "../node_modules/react-native-reanimated" RNScreens: :path: "../node_modules/react-native-screens" RNSVG: @@ -704,7 +747,7 @@ SPEC CHECKSUMS: fmt: ff9d55029c625d3757ed641535fd4a75fedc7ce9 glog: 04b94705f318337d7ead9e6d17c019bd9b1f6b1b hermes-engine: 10fbd3f62405c41ea07e71973ea61e1878d07322 - Instabug: ff8167e76606e3a0f0907495eaf0fda045701e27 + Instabug: 93587190c3c8fab583fbc2052da79d3e8b13b4a5 libevent: 4049cae6c81cdb3654a443be001fb9bdceff7913 OCMock: 9491e4bec59e0b267d52a9184ff5605995e74be8 OpenSSL-Universal: ebc357f1e6bc71fa463ccb2fe676756aff50e88c @@ -724,6 +767,7 @@ SPEC CHECKSUMS: React-jsinspector: b511447170f561157547bc0bef3f169663860be7 React-logger: c5b527272d5f22eaa09bb3c3a690fee8f237ae95 react-native-safe-area-context: 9697629f7b2cda43cf52169bb7e0767d330648c2 + react-native-slider: 1cdd6ba29675df21f30544253bf7351d3c2d68c4 React-NativeModulesApple: c57f3efe0df288a6532b726ad2d0322a9bf38472 React-perflogger: 6bd153e776e6beed54c56b0847e1220a3ff92ba5 React-RCTActionSheet: c0b62af44e610e69d9a2049a682f5dba4e9dff17 @@ -741,7 +785,9 @@ SPEC CHECKSUMS: React-runtimescheduler: 837c1bebd2f84572db17698cd702ceaf585b0d9a React-utils: bcb57da67eec2711f8b353f6e3d33bd8e4b2efa3 ReactCommon: 3ccb8fb14e6b3277e38c73b0ff5e4a1b8db017a9 + RNGestureHandler: 6e46dde1f87e5f018a54fe5d40cd0e0b942b49ee RNInstabug: a0c5e130f55637d0e41d4070f7cb37f1798d7226 + RNReanimated: ab2e96c6d5591c3dfbb38a464f54c8d17fb34a87 RNScreens: b21dc57dfa2b710c30ec600786a3fc223b1b92e7 RNSVG: 80584470ff1ffc7994923ea135a3e5ad825546b9 RNVectorIcons: 8b5bb0fa61d54cd2020af4f24a51841ce365c7e9 @@ -749,6 +795,6 @@ SPEC CHECKSUMS: Yoga: 8796b55dba14d7004f980b54bcc9833ee45b28ce YogaKit: f782866e155069a2cca2517aafea43200b01fd5a -PODFILE CHECKSUM: 981fe961279ed821d35acf584e71ab178474642e +PODFILE CHECKSUM: 9612538673471471f31d8b5157bc47906ea267f5 COCOAPODS: 1.11.3 From 44138e0c3a419a359df0b5f241745ed995d76441 Mon Sep 17 00:00:00 2001 From: AbdElHamid Nasser Date: Wed, 13 Dec 2023 20:04:01 +0200 Subject: [PATCH 27/30] chore(android): integrate `reportCurrentViewChange` API snapshot --- android/native.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/android/native.gradle b/android/native.gradle index 3b43421690..51409c6baa 100644 --- a/android/native.gradle +++ b/android/native.gradle @@ -1,5 +1,5 @@ project.ext.instabug = [ - version: '12.4.0.4576085-SNAPSHOT' + version: '12.4.0.5503778-SNAPSHOT' ] dependencies { From 2c4eca6a292685b40733f8576fc7e1bccb887b65 Mon Sep 17 00:00:00 2001 From: AbdElHamid Nasser Date: Sat, 16 Dec 2023 01:58:35 +0200 Subject: [PATCH 28/30] refactor(ios): remove re-initialization guard --- ios/RNInstabug/RNInstabug.m | 5 ----- 1 file changed, 5 deletions(-) diff --git a/ios/RNInstabug/RNInstabug.m b/ios/RNInstabug/RNInstabug.m index e79b33334d..378835f72d 100644 --- a/ios/RNInstabug/RNInstabug.m +++ b/ios/RNInstabug/RNInstabug.m @@ -14,11 +14,6 @@ + (void)reset { } + (void)initWithToken:(NSString *)token invocationEvents:(IBGInvocationEvent)invocationEvents { - // Initialization is performed only once to avoid unexpected behavior. - if (didInit) { - NSLog(@"IBG-RN: Skipped iOS SDK re-initialization"); - return; - } didInit = YES; From 2a408ed5ccaea82b21e78eed9c6d704f4712b804 Mon Sep 17 00:00:00 2001 From: AbdElHamid Nasser Date: Sat, 16 Dec 2023 02:03:54 +0200 Subject: [PATCH 29/30] chore(ios): integrate code push fix Allows calling `setCodePushVersion` after native iOS `init` from the RN `init` side. Before then it was not registering the version. --- examples/default/ios/Podfile | 2 +- examples/default/ios/Podfile.lock | 12 ++++++------ 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/examples/default/ios/Podfile b/examples/default/ios/Podfile index 32c0968386..acaf5db699 100644 --- a/examples/default/ios/Podfile +++ b/examples/default/ios/Podfile @@ -26,7 +26,7 @@ target 'InstabugExample' do # Flags change depending on the env values. flags = get_default_flags() - pod 'Instabug', :podspec => 'https://ios-releases.instabug.com/custom/custom_build-session_replay_crash_code_push/12.4.1/Instabug.podspec' + pod 'Instabug', :podspec => 'https://ios-releases.instabug.com/custom/custom-build-force-set-codepush/12.4.3/Instabug.podspec' use_react_native!( :path => config[:reactNativePath], # Hermes is now enabled by default. Disable by setting this flag to false. diff --git a/examples/default/ios/Podfile.lock b/examples/default/ios/Podfile.lock index 483a8e4a91..f426c19d2d 100644 --- a/examples/default/ios/Podfile.lock +++ b/examples/default/ios/Podfile.lock @@ -73,7 +73,7 @@ PODS: - hermes-engine (0.72.3): - hermes-engine/Pre-built (= 0.72.3) - hermes-engine/Pre-built (0.72.3) - - Instabug (12.4.1) + - Instabug (12.4.3) - libevent (2.1.12) - OCMock (3.9.1) - OpenSSL-Universal (1.1.1100) @@ -565,7 +565,7 @@ DEPENDENCIES: - FlipperKit/SKIOSNetworkPlugin (= 0.182.0) - glog (from `../node_modules/react-native/third-party-podspecs/glog.podspec`) - hermes-engine (from `../node_modules/react-native/sdks/hermes-engine/hermes-engine.podspec`) - - Instabug (from `https://ios-releases.instabug.com/custom/custom_build-session_replay_crash_code_push/12.4.1/Instabug.podspec`) + - Instabug (from `https://ios-releases.instabug.com/custom/custom-build-force-set-codepush/12.4.3/Instabug.podspec`) - libevent (~> 2.1.12) - OCMock - OpenSSL-Universal (= 1.1.1100) @@ -646,7 +646,7 @@ EXTERNAL SOURCES: :podspec: "../node_modules/react-native/sdks/hermes-engine/hermes-engine.podspec" :tag: hermes-2023-03-20-RNv0.72.0-49794cfc7c81fb8f69fd60c3bbf85a7480cc5a77 Instabug: - :podspec: https://ios-releases.instabug.com/custom/custom_build-session_replay_crash_code_push/12.4.1/Instabug.podspec + :podspec: https://ios-releases.instabug.com/custom/custom-build-force-set-codepush/12.4.3/Instabug.podspec RCT-Folly: :podspec: "../node_modules/react-native/third-party-podspecs/RCT-Folly.podspec" RCTRequired: @@ -747,7 +747,7 @@ SPEC CHECKSUMS: fmt: ff9d55029c625d3757ed641535fd4a75fedc7ce9 glog: 04b94705f318337d7ead9e6d17c019bd9b1f6b1b hermes-engine: 10fbd3f62405c41ea07e71973ea61e1878d07322 - Instabug: 93587190c3c8fab583fbc2052da79d3e8b13b4a5 + Instabug: a45124475f99fb282c4765c632b17b3b3bb1d625 libevent: 4049cae6c81cdb3654a443be001fb9bdceff7913 OCMock: 9491e4bec59e0b267d52a9184ff5605995e74be8 OpenSSL-Universal: ebc357f1e6bc71fa463ccb2fe676756aff50e88c @@ -795,6 +795,6 @@ SPEC CHECKSUMS: Yoga: 8796b55dba14d7004f980b54bcc9833ee45b28ce YogaKit: f782866e155069a2cca2517aafea43200b01fd5a -PODFILE CHECKSUM: 9612538673471471f31d8b5157bc47906ea267f5 +PODFILE CHECKSUM: 52f1fceaac9b4e47ad2048fb3af43584062fb977 -COCOAPODS: 1.11.3 +COCOAPODS: 1.13.0 From 208e3e794cd8734b748b394ee20003a8afd30571 Mon Sep 17 00:00:00 2001 From: AbdElHamid Nasser Date: Wed, 20 Dec 2023 14:44:58 +0200 Subject: [PATCH 30/30] chore(ios): add logs for CodePush --- ios/RNInstabug/InstabugReactBridge.m | 1 + package.json | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/ios/RNInstabug/InstabugReactBridge.m b/ios/RNInstabug/InstabugReactBridge.m index ed512fe328..2483caa9f7 100644 --- a/ios/RNInstabug/InstabugReactBridge.m +++ b/ios/RNInstabug/InstabugReactBridge.m @@ -48,6 +48,7 @@ - (dispatch_queue_t)methodQueue { } [Instabug setCodePushVersion:codePushVersion]; + NSLog(@“[Instabug] CodePush: %@“, codePushVersion); [RNInstabug initWithToken:token invocationEvents:invocationEvents diff --git a/package.json b/package.json index 75fa384939..57d91b63cb 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "instabug-reactnative", "description": "React Native plugin for integrating the Instabug SDK", - "version": "12.4.0", + "version": "12.4.3", "author": "Instabug (https://instabug.com)", "repository": "github:Instabug/Instabug-React-Native", "homepage": "https://www.instabug.com/platforms/react-native",