@luciq/react-native 18.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (239) hide show
  1. package/CHANGELOG.md +5 -0
  2. package/FONTS_SETUP_GUIDE.md +521 -0
  3. package/Gemfile +1 -0
  4. package/Gemfile.lock +11 -0
  5. package/LICENSE +21 -0
  6. package/README.md +148 -0
  7. package/RNLuciq.podspec +21 -0
  8. package/android/build.gradle +88 -0
  9. package/android/gradle.properties +4 -0
  10. package/android/jacoco.gradle +52 -0
  11. package/android/native.gradle +7 -0
  12. package/android/proguard-rules.txt +1 -0
  13. package/android/sourcemaps.gradle +255 -0
  14. package/android/src/main/AndroidManifest.xml +4 -0
  15. package/android/src/main/java/ai/luciq/reactlibrary/ArgsRegistry.java +278 -0
  16. package/android/src/main/java/ai/luciq/reactlibrary/Constants.java +20 -0
  17. package/android/src/main/java/ai/luciq/reactlibrary/RNLuciq.java +328 -0
  18. package/android/src/main/java/ai/luciq/reactlibrary/RNLuciqAPMModule.java +392 -0
  19. package/android/src/main/java/ai/luciq/reactlibrary/RNLuciqBugReportingModule.java +444 -0
  20. package/android/src/main/java/ai/luciq/reactlibrary/RNLuciqCrashReportingModule.java +169 -0
  21. package/android/src/main/java/ai/luciq/reactlibrary/RNLuciqFeatureRequestsModule.java +98 -0
  22. package/android/src/main/java/ai/luciq/reactlibrary/RNLuciqNetworkLoggerModule.java +195 -0
  23. package/android/src/main/java/ai/luciq/reactlibrary/RNLuciqReactnativeModule.java +1611 -0
  24. package/android/src/main/java/ai/luciq/reactlibrary/RNLuciqReactnativePackage.java +41 -0
  25. package/android/src/main/java/ai/luciq/reactlibrary/RNLuciqRepliesModule.java +298 -0
  26. package/android/src/main/java/ai/luciq/reactlibrary/RNLuciqSessionReplayModule.java +213 -0
  27. package/android/src/main/java/ai/luciq/reactlibrary/RNLuciqSurveysModule.java +237 -0
  28. package/android/src/main/java/ai/luciq/reactlibrary/utils/ArrayUtil.java +167 -0
  29. package/android/src/main/java/ai/luciq/reactlibrary/utils/EventEmitterModule.java +35 -0
  30. package/android/src/main/java/ai/luciq/reactlibrary/utils/LuciqUtil.java +58 -0
  31. package/android/src/main/java/ai/luciq/reactlibrary/utils/MainThreadHandler.java +13 -0
  32. package/android/src/main/java/ai/luciq/reactlibrary/utils/MapUtil.java +171 -0
  33. package/android/src/main/java/ai/luciq/reactlibrary/utils/RNTouchedViewExtractor.java +167 -0
  34. package/android/src/main/java/ai/luciq/reactlibrary/utils/ReportUtil.java +67 -0
  35. package/app.plugin.js +1 -0
  36. package/babel.config.js +3 -0
  37. package/bin/commands/MigrateCommand.d.ts +6 -0
  38. package/bin/commands/UploadEasUpdatesSourcemaps.d.ts +2 -0
  39. package/bin/commands/UploadSoFiles.d.ts +6 -0
  40. package/bin/commands/UploadSourcemaps.d.ts +2 -0
  41. package/bin/config/migration-config.json +125 -0
  42. package/bin/index.d.ts +2 -0
  43. package/bin/index.js +19179 -0
  44. package/bin/upload/index.d.ts +4 -0
  45. package/bin/upload/migrate.d.ts +14 -0
  46. package/bin/upload/uploadEasUpdatesSourcemaps.d.ts +21 -0
  47. package/bin/upload/uploadSoFiles.d.ts +21 -0
  48. package/bin/upload/uploadSourcemaps.d.ts +21 -0
  49. package/cli/commands/MigrateCommand.ts +32 -0
  50. package/cli/commands/UploadEasUpdatesSourcemaps.ts +34 -0
  51. package/cli/commands/UploadSoFiles.ts +38 -0
  52. package/cli/commands/UploadSourcemaps.ts +40 -0
  53. package/cli/config/migration-config.json +125 -0
  54. package/cli/index.ts +21 -0
  55. package/cli/upload/index.ts +4 -0
  56. package/cli/upload/migrate.ts +271 -0
  57. package/cli/upload/uploadEasUpdatesSourcemaps.ts +74 -0
  58. package/cli/upload/uploadSoFiles.ts +112 -0
  59. package/cli/upload/uploadSourcemaps.ts +73 -0
  60. package/dangerfile.ts +44 -0
  61. package/dist/index.d.ts +19 -0
  62. package/dist/index.js +14 -0
  63. package/dist/models/FeatureFlag.d.ts +11 -0
  64. package/dist/models/FeatureFlag.js +1 -0
  65. package/dist/models/LuciqConfig.d.ts +42 -0
  66. package/dist/models/LuciqConfig.js +1 -0
  67. package/dist/models/NonFatalOptions.d.ts +15 -0
  68. package/dist/models/NonFatalOptions.js +1 -0
  69. package/dist/models/OverAirUpdate.d.ts +12 -0
  70. package/dist/models/OverAirUpdate.js +1 -0
  71. package/dist/models/Report.d.ts +70 -0
  72. package/dist/models/Report.js +109 -0
  73. package/dist/models/ReproConfig.d.ts +27 -0
  74. package/dist/models/ReproConfig.js +1 -0
  75. package/dist/models/SessionMetadata.d.ts +55 -0
  76. package/dist/models/SessionMetadata.js +1 -0
  77. package/dist/models/ThemeConfig.d.ts +27 -0
  78. package/dist/models/ThemeConfig.js +1 -0
  79. package/dist/models/W3cExternalTraceAttributes.d.ts +22 -0
  80. package/dist/models/W3cExternalTraceAttributes.js +1 -0
  81. package/dist/modules/APM.d.ts +77 -0
  82. package/dist/modules/APM.js +104 -0
  83. package/dist/modules/BugReporting.d.ts +138 -0
  84. package/dist/modules/BugReporting.js +202 -0
  85. package/dist/modules/CrashReporting.d.ts +19 -0
  86. package/dist/modules/CrashReporting.js +40 -0
  87. package/dist/modules/FeatureRequests.d.ts +20 -0
  88. package/dist/modules/FeatureRequests.js +28 -0
  89. package/dist/modules/Luciq.d.ts +362 -0
  90. package/dist/modules/Luciq.js +797 -0
  91. package/dist/modules/NetworkLogger.d.ts +52 -0
  92. package/dist/modules/NetworkLogger.js +208 -0
  93. package/dist/modules/Replies.d.ts +78 -0
  94. package/dist/modules/Replies.js +121 -0
  95. package/dist/modules/SessionReplay.d.ts +78 -0
  96. package/dist/modules/SessionReplay.js +98 -0
  97. package/dist/modules/Surveys.d.ts +75 -0
  98. package/dist/modules/Surveys.js +101 -0
  99. package/dist/native/NativeAPM.d.ts +18 -0
  100. package/dist/native/NativeAPM.js +4 -0
  101. package/dist/native/NativeBugReporting.d.ts +32 -0
  102. package/dist/native/NativeBugReporting.js +10 -0
  103. package/dist/native/NativeConstants.d.ts +182 -0
  104. package/dist/native/NativeConstants.js +1 -0
  105. package/dist/native/NativeCrashReporting.d.ts +18 -0
  106. package/dist/native/NativeCrashReporting.js +2 -0
  107. package/dist/native/NativeFeatureRequests.d.ts +8 -0
  108. package/dist/native/NativeFeatureRequests.js +2 -0
  109. package/dist/native/NativeLuciq.d.ts +86 -0
  110. package/dist/native/NativeLuciq.js +10 -0
  111. package/dist/native/NativeNetworkLogger.d.ts +21 -0
  112. package/dist/native/NativeNetworkLogger.js +14 -0
  113. package/dist/native/NativePackage.d.ts +21 -0
  114. package/dist/native/NativePackage.js +2 -0
  115. package/dist/native/NativeReplies.d.ts +21 -0
  116. package/dist/native/NativeReplies.js +8 -0
  117. package/dist/native/NativeSessionReplay.d.ts +16 -0
  118. package/dist/native/NativeSessionReplay.js +8 -0
  119. package/dist/native/NativeSurveys.d.ts +22 -0
  120. package/dist/native/NativeSurveys.js +9 -0
  121. package/dist/utils/AppStatesHandler.d.ts +3 -0
  122. package/dist/utils/AppStatesHandler.js +16 -0
  123. package/dist/utils/Enums.d.ts +244 -0
  124. package/dist/utils/Enums.js +266 -0
  125. package/dist/utils/FeatureFlags.d.ts +7 -0
  126. package/dist/utils/FeatureFlags.js +24 -0
  127. package/dist/utils/LuciqConstants.d.ts +14 -0
  128. package/dist/utils/LuciqConstants.js +15 -0
  129. package/dist/utils/LuciqUtils.d.ts +97 -0
  130. package/dist/utils/LuciqUtils.js +301 -0
  131. package/dist/utils/UnhandledRejectionTracking.d.ts +9 -0
  132. package/dist/utils/UnhandledRejectionTracking.js +99 -0
  133. package/dist/utils/XhrNetworkInterceptor.d.ts +39 -0
  134. package/dist/utils/XhrNetworkInterceptor.js +253 -0
  135. package/dist/utils/config.d.ts +5 -0
  136. package/dist/utils/config.js +6 -0
  137. package/dist/utils/logger.d.ts +10 -0
  138. package/dist/utils/logger.js +39 -0
  139. package/expo.d.ts +1 -0
  140. package/expo.js +1 -0
  141. package/ios/RNLuciq/ArgsRegistry.h +32 -0
  142. package/ios/RNLuciq/ArgsRegistry.m +276 -0
  143. package/ios/RNLuciq/LuciqAPMBridge.h +26 -0
  144. package/ios/RNLuciq/LuciqAPMBridge.m +99 -0
  145. package/ios/RNLuciq/LuciqBugReportingBridge.h +60 -0
  146. package/ios/RNLuciq/LuciqBugReportingBridge.m +241 -0
  147. package/ios/RNLuciq/LuciqCrashReportingBridge.h +18 -0
  148. package/ios/RNLuciq/LuciqCrashReportingBridge.m +68 -0
  149. package/ios/RNLuciq/LuciqFeatureRequestsBridge.h +30 -0
  150. package/ios/RNLuciq/LuciqFeatureRequestsBridge.m +61 -0
  151. package/ios/RNLuciq/LuciqNetworkLoggerBridge.h +44 -0
  152. package/ios/RNLuciq/LuciqNetworkLoggerBridge.m +206 -0
  153. package/ios/RNLuciq/LuciqReactBridge.h +151 -0
  154. package/ios/RNLuciq/LuciqReactBridge.m +548 -0
  155. package/ios/RNLuciq/LuciqRepliesBridge.h +40 -0
  156. package/ios/RNLuciq/LuciqRepliesBridge.m +80 -0
  157. package/ios/RNLuciq/LuciqSessionReplayBridge.h +32 -0
  158. package/ios/RNLuciq/LuciqSessionReplayBridge.m +107 -0
  159. package/ios/RNLuciq/LuciqSurveysBridge.h +46 -0
  160. package/ios/RNLuciq/LuciqSurveysBridge.m +107 -0
  161. package/ios/RNLuciq/RCTConvert+LuciqEnums.h +18 -0
  162. package/ios/RNLuciq/RCTConvert+LuciqEnums.m +127 -0
  163. package/ios/RNLuciq/RNLuciq.h +35 -0
  164. package/ios/RNLuciq/RNLuciq.m +107 -0
  165. package/ios/RNLuciq/Util/LCQAPM+PrivateAPIs.h +15 -0
  166. package/ios/RNLuciq/Util/LCQCrashReporting+CP.h +13 -0
  167. package/ios/RNLuciq/Util/LCQNetworkLogger+CP.h +68 -0
  168. package/ios/RNLuciq/Util/Luciq+CP.h +12 -0
  169. package/ios/RNLuciq.xcodeproj/project.pbxproj +352 -0
  170. package/ios/native.rb +12 -0
  171. package/ios/sourcemaps.sh +120 -0
  172. package/migrate.js +569 -0
  173. package/package.json +92 -0
  174. package/plugin/build/index.js +42078 -0
  175. package/plugin/src/index.ts +5 -0
  176. package/plugin/src/pluginProps.ts +6 -0
  177. package/plugin/src/withLuciq.ts +51 -0
  178. package/plugin/src/withLuciqAndroid.ts +99 -0
  179. package/plugin/src/withLuciqIOS.ts +109 -0
  180. package/plugin/tsconfig.json +7 -0
  181. package/react-native.config.js +16 -0
  182. package/scripts/customize-ios-endpoints.sh +28 -0
  183. package/scripts/dream-11-delete-unused-features.sh +62 -0
  184. package/scripts/find-token.js +58 -0
  185. package/scripts/find-token.sh +70 -0
  186. package/scripts/notify-github.sh +15 -0
  187. package/scripts/replace.js +58 -0
  188. package/scripts/snapshot-comment.md +15 -0
  189. package/scripts/snapshot-version.sh +11 -0
  190. package/src/index.ts +40 -0
  191. package/src/models/FeatureFlag.ts +12 -0
  192. package/src/models/LuciqConfig.ts +48 -0
  193. package/src/models/NonFatalOptions.ts +16 -0
  194. package/src/models/OverAirUpdate.ts +14 -0
  195. package/src/models/Report.ts +124 -0
  196. package/src/models/ReproConfig.ts +31 -0
  197. package/src/models/SessionMetadata.ts +57 -0
  198. package/src/models/ThemeConfig.ts +34 -0
  199. package/src/models/W3cExternalTraceAttributes.ts +22 -0
  200. package/src/modules/APM.ts +117 -0
  201. package/src/modules/BugReporting.ts +254 -0
  202. package/src/modules/CrashReporting.ts +54 -0
  203. package/src/modules/FeatureRequests.ts +32 -0
  204. package/src/modules/Luciq.ts +934 -0
  205. package/src/modules/NetworkLogger.ts +270 -0
  206. package/src/modules/Replies.ts +137 -0
  207. package/src/modules/SessionReplay.ts +111 -0
  208. package/src/modules/Surveys.ts +118 -0
  209. package/src/native/NativeAPM.ts +51 -0
  210. package/src/native/NativeBugReporting.ts +70 -0
  211. package/src/native/NativeConstants.ts +215 -0
  212. package/src/native/NativeCrashReporting.ts +29 -0
  213. package/src/native/NativeFeatureRequests.ts +12 -0
  214. package/src/native/NativeLuciq.ts +179 -0
  215. package/src/native/NativeNetworkLogger.ts +42 -0
  216. package/src/native/NativePackage.ts +25 -0
  217. package/src/native/NativeReplies.ts +34 -0
  218. package/src/native/NativeSessionReplay.ts +21 -0
  219. package/src/native/NativeSurveys.ts +34 -0
  220. package/src/promise.d.ts +11 -0
  221. package/src/utils/AppStatesHandler.ts +19 -0
  222. package/src/utils/Enums.ts +266 -0
  223. package/src/utils/FeatureFlags.ts +33 -0
  224. package/src/utils/LuciqConstants.ts +24 -0
  225. package/src/utils/LuciqUtils.ts +417 -0
  226. package/src/utils/UnhandledRejectionTracking.ts +118 -0
  227. package/src/utils/XhrNetworkInterceptor.ts +333 -0
  228. package/src/utils/config.ts +7 -0
  229. package/src/utils/logger.ts +54 -0
  230. package/tsconfig.json +32 -0
  231. package/tsconfig.test.json +4 -0
  232. package/tsconfig.upload.json +10 -0
  233. package/upload/index.d.ts +4 -0
  234. package/upload/index.js +17314 -0
  235. package/upload/migrate.d.ts +14 -0
  236. package/upload/package.json +5 -0
  237. package/upload/uploadEasUpdatesSourcemaps.d.ts +21 -0
  238. package/upload/uploadSoFiles.d.ts +21 -0
  239. package/upload/uploadSourcemaps.d.ts +21 -0
@@ -0,0 +1,417 @@
1
+ import { Platform } from 'react-native';
2
+ import parseErrorStackLib, {
3
+ ExtendedError,
4
+ StackFrame,
5
+ } from 'react-native/Libraries/Core/Devtools/parseErrorStack';
6
+
7
+ import type { NavigationState as NavigationStateV5, PartialState } from '@react-navigation/native';
8
+ import type { NavigationState as NavigationStateV4 } from 'react-navigation';
9
+
10
+ import type { CrashData } from '../native/NativeCrashReporting';
11
+ import { NativeCrashReporting } from '../native/NativeCrashReporting';
12
+ import type { NetworkData } from './XhrNetworkInterceptor';
13
+ import { NativeLuciq } from '../native/NativeLuciq';
14
+ import { NativeAPM } from '../native/NativeAPM';
15
+ import * as NetworkLogger from '../modules/NetworkLogger';
16
+ import {
17
+ NativeNetworkLogger,
18
+ NativeNetworkLoggerEvent,
19
+ NetworkListenerType,
20
+ NetworkLoggerEmitter,
21
+ } from '../native/NativeNetworkLogger';
22
+
23
+ type ApmNetworkFlags = {
24
+ isNativeInterceptionFeatureEnabled: boolean;
25
+ hasAPMNetworkPlugin: boolean;
26
+ shouldEnableNativeInterception: boolean;
27
+ };
28
+
29
+ let apmFlags: ApmNetworkFlags = {
30
+ isNativeInterceptionFeatureEnabled: false,
31
+ hasAPMNetworkPlugin: false,
32
+ shouldEnableNativeInterception: false,
33
+ };
34
+
35
+ export function setApmNetworkFlagsIfChanged(flags: ApmNetworkFlags): boolean {
36
+ if (
37
+ flags.hasAPMNetworkPlugin === apmFlags.hasAPMNetworkPlugin &&
38
+ flags.isNativeInterceptionFeatureEnabled === apmFlags.isNativeInterceptionFeatureEnabled &&
39
+ flags.shouldEnableNativeInterception === apmFlags.shouldEnableNativeInterception
40
+ ) {
41
+ return false;
42
+ }
43
+ apmFlags = flags;
44
+ return true;
45
+ }
46
+
47
+ export const parseErrorStack = (error: ExtendedError): StackFrame[] => {
48
+ return parseErrorStackLib(error);
49
+ };
50
+
51
+ export const getCrashDataFromError = (error: Error) => {
52
+ const jsStackTrace = getStackTrace(error);
53
+
54
+ const jsonObject: CrashData = {
55
+ message: error.name + ' - ' + error.message,
56
+ e_message: error.message,
57
+ e_name: error.name,
58
+ os: Platform.OS,
59
+ platform: 'react_native',
60
+ exception: jsStackTrace,
61
+ };
62
+ return jsonObject;
63
+ };
64
+
65
+ export const getActiveRouteName = (navigationState: NavigationStateV4): string | null => {
66
+ if (!navigationState) {
67
+ return null;
68
+ }
69
+ const route = navigationState.routes[navigationState.index];
70
+ // dive into nested navigators
71
+ if (route.routes) {
72
+ return getActiveRouteName(route);
73
+ }
74
+ return route.routeName;
75
+ };
76
+
77
+ export function getFullRoute(state: NavigationStateV5 | PartialState<NavigationStateV5>): string {
78
+ try {
79
+ if (!state.routes[state.index!].state) {
80
+ return state.routes[state.index!].name;
81
+ }
82
+ return getFullRoute(state.routes[state.index!].state!);
83
+ } catch (e) {
84
+ return '';
85
+ }
86
+ }
87
+
88
+ export const getStackTrace = (e: ExtendedError): StackFrame[] => {
89
+ let jsStackTrace;
90
+ if (Platform.hasOwnProperty('constants')) {
91
+ // RN version >= 0.63
92
+ if (Platform.constants.reactNativeVersion.minor >= 64) {
93
+ // RN version >= 0.64 -> Stacktrace as string
94
+ // @ts-ignore
95
+ jsStackTrace = parseErrorStackLib(e.stack);
96
+ }
97
+ // RN version == 0.63 -> Stacktrace as string
98
+ else {
99
+ jsStackTrace = parseErrorStackLib(e);
100
+ }
101
+ }
102
+ // RN version < 0.63 -> Stacktrace as string
103
+ else {
104
+ jsStackTrace = parseErrorStackLib(e);
105
+ }
106
+ return jsStackTrace;
107
+ };
108
+
109
+ export const captureJsErrors = () => {
110
+ if (!process.env.JEST_WORKER_ID) {
111
+ if (__DEV__) {
112
+ return;
113
+ }
114
+ }
115
+
116
+ const originalErrorHandler = ErrorUtils.getGlobalHandler();
117
+
118
+ const luciqErrorHandler = (err: any, _isFatal?: boolean): Promise<void> => {
119
+ return sendCrashReport(err, NativeCrashReporting.sendJSCrash);
120
+ };
121
+
122
+ ErrorUtils.setGlobalHandler(async (err, isFatal) => {
123
+ await luciqErrorHandler(err, isFatal);
124
+
125
+ if (process.env.JEST_WORKER_ID) {
126
+ return;
127
+ }
128
+ originalErrorHandler(err, isFatal);
129
+ });
130
+ };
131
+
132
+ export const stringifyIfNotString = (input: unknown) => {
133
+ return typeof input === 'string' ? input : JSON.stringify(input);
134
+ };
135
+
136
+ /**
137
+ * Sends crash report to Luciq's servers based on @param sendFunction
138
+ *
139
+ * @param error Error object to be sent to Luciq's servers
140
+ * @param remoteSenderCallback Function to send the crash report to Luciq's servers
141
+ *
142
+ * @example
143
+ * `sendCrashReport(error, NativeCrashReporting.sendHandledJSCrash);`
144
+ * or
145
+ * `sendCrashReport(error, NativeCrashReporting.sendJSCrash);`
146
+ *
147
+ */
148
+ export async function sendCrashReport(
149
+ error: ExtendedError,
150
+ remoteSenderCallback: (json: CrashData | string) => Promise<void>,
151
+ ) {
152
+ const jsonObject = getCrashDataFromError(error);
153
+
154
+ if (Platform.OS === 'android') {
155
+ return remoteSenderCallback(JSON.stringify(jsonObject));
156
+ }
157
+
158
+ return remoteSenderCallback(jsonObject);
159
+ }
160
+ /**
161
+ * Generate random 32 bit unsigned integer Hexadecimal (8 chars) lower case letters
162
+ * Should not return all zeros
163
+ */
164
+ export const generateTracePartialId = () => {
165
+ let randomNumber: number;
166
+ let hexString: string;
167
+
168
+ do {
169
+ randomNumber = Math.floor(Math.random() * 0xffffffff);
170
+ hexString = randomNumber.toString(16).padStart(8, '0');
171
+ } while (hexString === '00000000');
172
+
173
+ return { numberPartilId: randomNumber, hexStringPartialId: hexString.toLowerCase() };
174
+ };
175
+ /**
176
+ * Generate W3C header in the format of {version}-{trace-id}-{parent-id}-{trace-flag}
177
+ * @param networkStartTime
178
+ * @returns w3c header
179
+ */
180
+ export const generateW3CHeader = (networkStartTime: number) => {
181
+ const { hexStringPartialId, numberPartilId } = generateTracePartialId();
182
+
183
+ const TRACESTATE = '4942472d';
184
+ const VERSION = '00';
185
+ const TRACE_FLAG = '01';
186
+
187
+ const timestampInSeconds = Math.floor(networkStartTime.valueOf() / 1000);
188
+ const hexaDigitsTimestamp = timestampInSeconds.toString(16).toLowerCase();
189
+ const traceId = `${hexaDigitsTimestamp}${hexStringPartialId}${hexaDigitsTimestamp}${hexStringPartialId}`;
190
+ const parentId = `${TRACESTATE}${hexStringPartialId}`;
191
+
192
+ return {
193
+ timestampInSeconds,
194
+ partialId: numberPartilId,
195
+ w3cHeader: `${VERSION}-${traceId}-${parentId}-${TRACE_FLAG}`,
196
+ };
197
+ };
198
+
199
+ export function isContentTypeNotAllowed(contentType: string) {
200
+ const allowed = [
201
+ 'application/protobuf',
202
+ 'application/json',
203
+ 'application/xml',
204
+ 'text/xml',
205
+ 'text/html',
206
+ 'text/plain',
207
+ ];
208
+
209
+ return allowed.every((type) => !contentType.includes(type));
210
+ }
211
+
212
+ export const reportNetworkLog = (network: NetworkData) => {
213
+ if (Platform.OS === 'android') {
214
+ const requestHeaders = JSON.stringify(network.requestHeaders);
215
+ const responseHeaders = JSON.stringify(network.responseHeaders);
216
+
217
+ NativeLuciq.networkLogAndroid(
218
+ network.url,
219
+ network.requestBody,
220
+ network.responseBody,
221
+ network.method,
222
+ network.responseCode,
223
+ requestHeaders,
224
+ responseHeaders,
225
+ network.duration,
226
+ );
227
+ if (
228
+ !apmFlags.isNativeInterceptionFeatureEnabled ||
229
+ !apmFlags.hasAPMNetworkPlugin ||
230
+ !apmFlags.shouldEnableNativeInterception
231
+ ) {
232
+ NativeAPM.networkLogAndroid(
233
+ network.startTime,
234
+ network.duration,
235
+ requestHeaders,
236
+ network.requestBody,
237
+ network.requestBodySize,
238
+ network.method,
239
+ network.url,
240
+ network.requestContentType,
241
+ responseHeaders,
242
+ network.responseBody,
243
+ network.responseBodySize,
244
+ network.responseCode,
245
+ network.contentType,
246
+ network.errorDomain,
247
+ {
248
+ isW3cHeaderFound: network.isW3cHeaderFound,
249
+ partialId: network.partialId,
250
+ networkStartTimeInSeconds: network.networkStartTimeInSeconds,
251
+ w3cGeneratedHeader: network.w3cGeneratedHeader,
252
+ w3cCaughtHeader: network.w3cCaughtHeader,
253
+ },
254
+ network.gqlQueryName,
255
+ network.serverErrorMessage,
256
+ );
257
+ }
258
+ } else {
259
+ NativeLuciq.networkLogIOS(
260
+ network.url,
261
+ network.method,
262
+ network.requestBody,
263
+ network.requestBodySize,
264
+ network.responseBody,
265
+ network.responseBodySize,
266
+ network.responseCode,
267
+ network.requestHeaders,
268
+ network.responseHeaders,
269
+ network.contentType,
270
+ network.errorDomain,
271
+ network.errorCode,
272
+ network.startTime,
273
+ network.duration,
274
+ network.gqlQueryName,
275
+ network.serverErrorMessage,
276
+ {
277
+ isW3cHeaderFound: network.isW3cHeaderFound,
278
+ partialId: network.partialId,
279
+ networkStartTimeInSeconds: network.networkStartTimeInSeconds,
280
+ w3cGeneratedHeader: network.w3cGeneratedHeader,
281
+ w3cCaughtHeader: network.w3cCaughtHeader,
282
+ },
283
+ );
284
+ }
285
+ };
286
+
287
+ /**
288
+ * @internal
289
+ * This method is for internal use only.
290
+ */
291
+ export function registerObfuscationListener() {
292
+ NetworkLogger.registerNetworkLogsListener(
293
+ NetworkListenerType.obfuscation,
294
+ async (networkSnapshot) => {
295
+ const _networkDataObfuscationHandler = NetworkLogger.getNetworkDataObfuscationHandler();
296
+ if (_networkDataObfuscationHandler) {
297
+ networkSnapshot = await _networkDataObfuscationHandler(networkSnapshot);
298
+ }
299
+ updateNetworkLogSnapshot(networkSnapshot);
300
+ },
301
+ );
302
+ }
303
+
304
+ /**
305
+ * @internal
306
+ * This method is for internal use only.
307
+ */
308
+ export function registerFilteringListener(filterExpression: string) {
309
+ NetworkLogger.registerNetworkLogsListener(
310
+ NetworkListenerType.filtering,
311
+ async (networkSnapshot) => {
312
+ // eslint-disable-next-line no-new-func
313
+ const predicate = Function('network', 'return ' + filterExpression);
314
+ const value = predicate(networkSnapshot);
315
+ if (Platform.OS === 'ios') {
316
+ // For iOS True == Request will be saved, False == will be ignored
317
+ NativeNetworkLogger.setNetworkLoggingRequestFilterPredicateIOS(networkSnapshot.id, !value);
318
+ } else {
319
+ // For Android Setting the [url] to an empty string will ignore the request;
320
+ if (value) {
321
+ networkSnapshot.url = '';
322
+ updateNetworkLogSnapshot(networkSnapshot);
323
+ }
324
+ }
325
+ },
326
+ );
327
+ }
328
+
329
+ /**
330
+ * @internal
331
+ * This method is for internal use only.
332
+ */
333
+ export function registerFilteringAndObfuscationListener(filterExpression: string) {
334
+ NetworkLogger.registerNetworkLogsListener(NetworkListenerType.both, async (networkSnapshot) => {
335
+ // eslint-disable-next-line no-new-func
336
+ const predicate = Function('network', 'return ' + filterExpression);
337
+ const value = predicate(networkSnapshot);
338
+ if (Platform.OS === 'ios') {
339
+ // For iOS True == Request will be saved, False == will be ignored
340
+ NativeNetworkLogger.setNetworkLoggingRequestFilterPredicateIOS(networkSnapshot.id, !value);
341
+ } else {
342
+ // For Android Setting the [url] to an empty string will ignore the request;
343
+ if (value) {
344
+ networkSnapshot.url = '';
345
+ updateNetworkLogSnapshot(networkSnapshot);
346
+ }
347
+ }
348
+ if (!value) {
349
+ const _networkDataObfuscationHandler = NetworkLogger.getNetworkDataObfuscationHandler();
350
+ if (_networkDataObfuscationHandler) {
351
+ networkSnapshot = await _networkDataObfuscationHandler(networkSnapshot);
352
+ }
353
+ updateNetworkLogSnapshot(networkSnapshot);
354
+ }
355
+ });
356
+ }
357
+
358
+ /**
359
+ * @internal
360
+ * This method is for internal use only.
361
+ */
362
+ export function checkNetworkRequestHandlers() {
363
+ const obfuscationHandler = NetworkLogger.getNetworkDataObfuscationHandler();
364
+ const hasFilterExpression = NetworkLogger.hasRequestFilterExpression();
365
+
366
+ if (hasFilterExpression && obfuscationHandler) {
367
+ // Register listener that handles both (Filtering & Obfuscation)
368
+ registerFilteringAndObfuscationListener(NetworkLogger.getRequestFilterExpression());
369
+ return;
370
+ }
371
+ if (obfuscationHandler) {
372
+ // Register listener that handles only (Obfuscation)
373
+ registerObfuscationListener();
374
+ return;
375
+ }
376
+
377
+ if (hasFilterExpression) {
378
+ // Register listener that handles only (Filtering)
379
+ registerFilteringListener(NetworkLogger.getRequestFilterExpression());
380
+ return;
381
+ }
382
+ }
383
+ export function resetNativeObfuscationListener() {
384
+ if (Platform.OS === 'android') {
385
+ NativeNetworkLogger.resetNetworkLogsListener();
386
+ }
387
+ NetworkLoggerEmitter.removeAllListeners(NativeNetworkLoggerEvent.NETWORK_LOGGER_HANDLER);
388
+ }
389
+
390
+ /**
391
+ * @internal
392
+ * This method is for internal use only.
393
+ */
394
+ export function updateNetworkLogSnapshot(networkSnapshot: NetworkData) {
395
+ NativeNetworkLogger.updateNetworkLogSnapshot(
396
+ networkSnapshot.url,
397
+ networkSnapshot.id,
398
+ networkSnapshot.requestBody,
399
+ networkSnapshot.responseBody,
400
+ networkSnapshot.responseCode ?? 200,
401
+ networkSnapshot.requestHeaders,
402
+ networkSnapshot.responseHeaders,
403
+ );
404
+ }
405
+
406
+ export default {
407
+ parseErrorStack,
408
+ captureJsErrors,
409
+ getActiveRouteName,
410
+ getFullRoute,
411
+ getStackTrace,
412
+ stringifyIfNotString,
413
+ sendCrashReport,
414
+ reportNetworkLog,
415
+ generateTracePartialId,
416
+ generateW3CHeader,
417
+ };
@@ -0,0 +1,118 @@
1
+ import tracking, { RejectionTrackingOptions } from 'promise/setimmediate/rejection-tracking';
2
+ import { sendCrashReport } from './LuciqUtils';
3
+ import { NativeCrashReporting } from '../native/NativeCrashReporting';
4
+ import { NonFatalErrorLevel } from './Enums';
5
+ import { Logger } from './logger';
6
+
7
+ export interface HermesInternalType {
8
+ enablePromiseRejectionTracker?: (options?: RejectionTrackingOptions) => void;
9
+ hasPromise?: () => boolean;
10
+ }
11
+
12
+ /**
13
+ * A typed version of the `HermesInternal` global object with the properties
14
+ * we use.
15
+ */
16
+ function _getHermes(): HermesInternalType | null {
17
+ return (global as any).HermesInternal;
18
+ }
19
+
20
+ /**
21
+ * Checks whether the Promise object is provided by Hermes.
22
+ *
23
+ * @returns whether the `Promise` object is provided by Hermes.
24
+ */
25
+ function _isHermesPromise() {
26
+ const hermes = _getHermes();
27
+ const hasPromise = hermes?.hasPromise?.() === true;
28
+ const canTrack = hermes?.enablePromiseRejectionTracker != null;
29
+
30
+ return hasPromise && canTrack;
31
+ }
32
+
33
+ /**
34
+ * Enables unhandled Promise rejection tracking in Hermes.
35
+ *
36
+ * @param options Rejection tracking options.
37
+ */
38
+ function _enableHermesRejectionTracking(options?: RejectionTrackingOptions) {
39
+ const hermes = _getHermes();
40
+
41
+ hermes!.enablePromiseRejectionTracker!(options);
42
+ }
43
+
44
+ /**
45
+ * Enables unhandled Promise rejection tracking in the default `promise` polyfill.
46
+ *
47
+ * @param options Rejection tracking options.
48
+ */
49
+ function _enableDefaultRejectionTracking(options?: RejectionTrackingOptions) {
50
+ tracking.enable(options);
51
+ }
52
+
53
+ /**
54
+ * Tracks whether an unhandled Promise rejection happens and reports it.
55
+ */
56
+ export function captureUnhandledRejections() {
57
+ const options: RejectionTrackingOptions = {
58
+ allRejections: true,
59
+ onUnhandled: _onUnhandled,
60
+ };
61
+
62
+ if (_isHermesPromise()) {
63
+ _enableHermesRejectionTracking(options);
64
+ } else {
65
+ _enableDefaultRejectionTracking(options);
66
+ }
67
+ }
68
+
69
+ /**
70
+ * The callback passed in the rejection tracking options to report unhandled
71
+ * Promise rejection
72
+ */
73
+ function _onUnhandled(id: number, rejection: unknown) {
74
+ _originalOnUnhandled(id, rejection);
75
+
76
+ if (__DEV__) {
77
+ return;
78
+ }
79
+
80
+ if (rejection instanceof Error) {
81
+ sendCrashReport(rejection, (error) =>
82
+ NativeCrashReporting.sendHandledJSCrash(error, null, null, NonFatalErrorLevel.error),
83
+ );
84
+ }
85
+ }
86
+
87
+ /* istanbul ignore next */
88
+ /**
89
+ * The default unhandled promise rejection handler set by React Native.
90
+ *
91
+ * In fact, this is copied from the React Native repo but modified to work well
92
+ * with our static analysis setup.
93
+ *
94
+ * https://github.com/facebook/react-native/blob/f2447e6048a6b519c3333767d950dbf567149b75/packages/react-native/Libraries/promiseRejectionTrackingOptions.js#L15-L49
95
+ */
96
+ function _originalOnUnhandled(id: number, rejection: unknown = {}) {
97
+ let message: string;
98
+ let stack: string | undefined;
99
+
100
+ const stringValue = Object.prototype.toString.call(rejection);
101
+ if (stringValue === '[object Error]') {
102
+ message = Error.prototype.toString.call(rejection);
103
+ const error = rejection as Error;
104
+ stack = error.stack;
105
+ } else {
106
+ try {
107
+ message = require('pretty-format')(rejection);
108
+ } catch {
109
+ message = typeof rejection === 'string' ? rejection : JSON.stringify(rejection);
110
+ }
111
+ }
112
+
113
+ const warning =
114
+ `Possible Unhandled Promise Rejection (id: ${id}):\n` +
115
+ `${message ?? ''}\n` +
116
+ (stack == null ? '' : stack);
117
+ Logger.warn(warning);
118
+ }