@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,270 @@
1
+ import type { RequestHandler } from '@apollo/client';
2
+
3
+ import LuciqConstants from '../utils/LuciqConstants';
4
+ import xhr, { NetworkData, ProgressCallback } from '../utils/XhrNetworkInterceptor';
5
+ import { LuciqRNConfig } from '../utils/config';
6
+ import { Logger } from '../utils/logger';
7
+ import { NativeLuciq } from '../native/NativeLuciq';
8
+ import {
9
+ isContentTypeNotAllowed,
10
+ registerFilteringAndObfuscationListener,
11
+ registerFilteringListener,
12
+ registerObfuscationListener,
13
+ reportNetworkLog,
14
+ } from '../utils/LuciqUtils';
15
+ import {
16
+ NativeNetworkLogger,
17
+ NativeNetworkLoggerEvent,
18
+ NetworkListenerType,
19
+ NetworkLoggerEmitter,
20
+ } from '../native/NativeNetworkLogger';
21
+ import { Platform } from 'react-native';
22
+
23
+ export type { NetworkData };
24
+
25
+ export type NetworkDataObfuscationHandler = (data: NetworkData) => Promise<NetworkData>;
26
+ let _networkDataObfuscationHandler: NetworkDataObfuscationHandler | null | undefined;
27
+ let _requestFilterExpression = 'false';
28
+ let _isNativeInterceptionEnabled = false;
29
+ let _networkListener: NetworkListenerType | null = null;
30
+ let hasFilterExpression = false;
31
+
32
+ function getPortFromUrl(url: string) {
33
+ const portMatch = url.match(/:(\d+)(?=\/|$)/);
34
+ return portMatch ? portMatch[1] : null;
35
+ }
36
+
37
+ /**
38
+ * Sets whether network logs should be sent with bug reports.
39
+ * It is enabled by default.
40
+ * @param isEnabled
41
+ */
42
+ export const setEnabled = (isEnabled: boolean) => {
43
+ if (isEnabled) {
44
+ xhr.enableInterception();
45
+ xhr.setOnDoneCallback(async (network) => {
46
+ // eslint-disable-next-line no-new-func
47
+ const predicate = Function('network', 'return ' + _requestFilterExpression);
48
+
49
+ if (!predicate(network)) {
50
+ const MAX_NETWORK_BODY_SIZE_IN_BYTES = await NativeLuciq.getNetworkBodyMaxSize();
51
+ try {
52
+ if (_networkDataObfuscationHandler) {
53
+ network = await _networkDataObfuscationHandler(network);
54
+ }
55
+
56
+ if (__DEV__) {
57
+ const urlPort = getPortFromUrl(network.url);
58
+ if (urlPort === LuciqRNConfig.metroDevServerPort) {
59
+ return;
60
+ }
61
+ }
62
+ if (network.requestBodySize > MAX_NETWORK_BODY_SIZE_IN_BYTES) {
63
+ network.requestBody = `${LuciqConstants.MAX_REQUEST_BODY_SIZE_EXCEEDED_MESSAGE}${
64
+ MAX_NETWORK_BODY_SIZE_IN_BYTES / 1024
65
+ } Kb`;
66
+ Logger.warn(
67
+ 'LCQ-RN:',
68
+ `${LuciqConstants.MAX_REQUEST_BODY_SIZE_EXCEEDED_MESSAGE}${
69
+ MAX_NETWORK_BODY_SIZE_IN_BYTES / 1024
70
+ } Kb`,
71
+ );
72
+ }
73
+
74
+ if (network.responseBodySize > MAX_NETWORK_BODY_SIZE_IN_BYTES) {
75
+ network.responseBody = `${LuciqConstants.MAX_RESPONSE_BODY_SIZE_EXCEEDED_MESSAGE}${
76
+ MAX_NETWORK_BODY_SIZE_IN_BYTES / 1024
77
+ } Kb`;
78
+ Logger.warn(
79
+ 'LCQ-RN:',
80
+ `${LuciqConstants.MAX_RESPONSE_BODY_SIZE_EXCEEDED_MESSAGE}${
81
+ MAX_NETWORK_BODY_SIZE_IN_BYTES / 1024
82
+ } Kb`,
83
+ );
84
+ }
85
+
86
+ if (network.requestBody && isContentTypeNotAllowed(network.requestContentType)) {
87
+ network.requestBody = `Body is omitted because content type ${network.requestContentType} isn't supported`;
88
+ Logger.warn(
89
+ `LCQ-RN: The request body for the network request with URL ${network.url} has been omitted because the content type ${network.requestContentType} isn't supported.`,
90
+ );
91
+ }
92
+
93
+ if (network.responseBody && isContentTypeNotAllowed(network.contentType)) {
94
+ network.responseBody = `Body is omitted because content type ${network.contentType} isn't supported`;
95
+ Logger.warn(
96
+ `LCQ-RN: The response body for the network request with URL ${network.url} has been omitted because the content type ${network.contentType} isn't supported.`,
97
+ );
98
+ }
99
+
100
+ reportNetworkLog(network);
101
+ } catch (e) {
102
+ Logger.error(e);
103
+ }
104
+ }
105
+ });
106
+ } else {
107
+ xhr.disableInterception();
108
+ }
109
+ };
110
+
111
+ /**
112
+ * @internal
113
+ * Sets whether enabling or disabling native network interception.
114
+ * It is disabled by default.
115
+ * @param isEnabled
116
+ */
117
+ export const setNativeInterceptionEnabled = (isEnabled: boolean) => {
118
+ _isNativeInterceptionEnabled = isEnabled;
119
+ };
120
+
121
+ export const getNetworkDataObfuscationHandler = () => _networkDataObfuscationHandler;
122
+
123
+ export const getRequestFilterExpression = () => _requestFilterExpression;
124
+
125
+ export const hasRequestFilterExpression = () => hasFilterExpression;
126
+
127
+ /**
128
+ * Obfuscates any response data.
129
+ * @param handler
130
+ */
131
+ export const setNetworkDataObfuscationHandler = (
132
+ handler?: NetworkDataObfuscationHandler | null | undefined,
133
+ ) => {
134
+ _networkDataObfuscationHandler = handler;
135
+ if (_isNativeInterceptionEnabled && Platform.OS === 'ios') {
136
+ if (hasFilterExpression) {
137
+ registerFilteringAndObfuscationListener(_requestFilterExpression);
138
+ } else {
139
+ registerObfuscationListener();
140
+ }
141
+ }
142
+ };
143
+
144
+ /**
145
+ * Omit requests from being logged based on either their request or response details
146
+ * @param expression
147
+ */
148
+ export const setRequestFilterExpression = (expression: string) => {
149
+ _requestFilterExpression = expression;
150
+ hasFilterExpression = true;
151
+
152
+ if (_isNativeInterceptionEnabled && Platform.OS === 'ios') {
153
+ if (_networkDataObfuscationHandler) {
154
+ registerFilteringAndObfuscationListener(_requestFilterExpression);
155
+ } else {
156
+ registerFilteringListener(_requestFilterExpression);
157
+ }
158
+ }
159
+ };
160
+
161
+ /**
162
+ * Returns progress in terms of totalBytesSent and totalBytesExpectedToSend a network request.
163
+ * @param handler
164
+ */
165
+ export const setProgressHandlerForRequest = (handler: ProgressCallback) => {
166
+ xhr.setOnProgressCallback(handler);
167
+ };
168
+
169
+ export const apolloLinkRequestHandler: RequestHandler = (operation, forward) => {
170
+ try {
171
+ operation.setContext((context: Record<string, any>) => {
172
+ const newHeaders: Record<string, any> = context.headers ?? {};
173
+ newHeaders[LuciqConstants.GRAPHQL_HEADER] = operation.operationName;
174
+ return { headers: newHeaders };
175
+ });
176
+ } catch (e) {
177
+ Logger.error(e);
178
+ }
179
+
180
+ return forward(operation);
181
+ };
182
+
183
+ /**
184
+ * Sets whether network body logs will be captured or not.
185
+ * @param isEnabled
186
+ */
187
+ export const setNetworkLogBodyEnabled = (isEnabled: boolean) => {
188
+ NativeLuciq.setNetworkLogBodyEnabled(isEnabled);
189
+ };
190
+
191
+ /**
192
+ * @internal
193
+ * Exported for internal/testing purposes only.
194
+ */
195
+ export const resetNetworkListener = () => {
196
+ if (process.env.NODE_ENV === 'test') {
197
+ _networkListener = null;
198
+ NativeNetworkLogger.resetNetworkLogsListener();
199
+ } else {
200
+ Logger.error(
201
+ `${LuciqConstants.LCQ_APM_TAG}: The \`resetNetworkListener()\` method is intended solely for testing purposes.`,
202
+ );
203
+ }
204
+ };
205
+
206
+ /**
207
+ * @internal
208
+ * Exported for internal/testing purposes only.
209
+ */
210
+ export const registerNetworkLogsListener = (
211
+ type: NetworkListenerType,
212
+ handler?: (networkSnapshot: NetworkData) => void,
213
+ ) => {
214
+ if (Platform.OS === 'ios') {
215
+ // remove old listeners
216
+ if (NetworkLoggerEmitter.listenerCount(NativeNetworkLoggerEvent.NETWORK_LOGGER_HANDLER) > 0) {
217
+ NetworkLoggerEmitter.removeAllListeners(NativeNetworkLoggerEvent.NETWORK_LOGGER_HANDLER);
218
+ }
219
+
220
+ if (_networkListener == null) {
221
+ // set new listener.
222
+ _networkListener = type;
223
+ } else {
224
+ // attach a new listener to the existing one.
225
+ _networkListener = NetworkListenerType.both;
226
+ }
227
+ }
228
+
229
+ NetworkLoggerEmitter.addListener(
230
+ NativeNetworkLoggerEvent.NETWORK_LOGGER_HANDLER,
231
+ (networkSnapshot) => {
232
+ // Mapping the data [Native -> React-Native].
233
+ const { id, url, requestHeader, requestBody, responseHeader, response, responseCode } =
234
+ networkSnapshot;
235
+
236
+ const networkSnapshotObj: NetworkData = {
237
+ id: id,
238
+ url: url,
239
+ requestBody: requestBody,
240
+ requestHeaders: requestHeader,
241
+ method: '',
242
+ responseBody: response,
243
+ responseCode: responseCode,
244
+ responseHeaders: responseHeader,
245
+ contentType: '',
246
+ duration: 0,
247
+ requestBodySize: 0,
248
+ responseBodySize: 0,
249
+ errorDomain: '',
250
+ errorCode: 0,
251
+ startTime: 0,
252
+ serverErrorMessage: '',
253
+ requestContentType: '',
254
+ isW3cHeaderFound: true,
255
+ networkStartTimeInSeconds: 0,
256
+ partialId: 0,
257
+ w3cCaughtHeader: '',
258
+ w3cGeneratedHeader: '',
259
+ };
260
+ if (handler) {
261
+ handler(networkSnapshotObj);
262
+ }
263
+ },
264
+ );
265
+ if (Platform.OS === 'ios') {
266
+ NativeNetworkLogger.registerNetworkLogsListener(_networkListener ?? NetworkListenerType.both);
267
+ } else {
268
+ NativeNetworkLogger.registerNetworkLogsListener();
269
+ }
270
+ };
@@ -0,0 +1,137 @@
1
+ import { Platform } from 'react-native';
2
+
3
+ import { NativeEvents, NativeReplies, emitter } from '../native/NativeReplies';
4
+
5
+ /**
6
+ * Enables and disables everything related to receiving replies.
7
+ * @param isEnabled
8
+ */
9
+ export const setEnabled = (isEnabled: boolean) => {
10
+ NativeReplies.setEnabled(isEnabled);
11
+ };
12
+
13
+ /**
14
+ * Tells whether the user has chats already or not.
15
+ */
16
+ export const hasChats = async (): Promise<boolean> => {
17
+ const result = await NativeReplies.hasChats();
18
+
19
+ return result;
20
+ };
21
+
22
+ /**
23
+ * Manual invocation for replies.
24
+ */
25
+ export const show = () => {
26
+ NativeReplies.show();
27
+ };
28
+
29
+ /**
30
+ * Sets a block of code that gets executed when a new message is received.
31
+ * @param handler A callback that gets executed when a new message is received.
32
+ */
33
+ export const setOnNewReplyReceivedHandler = (handler: () => void) => {
34
+ emitter.addListener(NativeEvents.ON_REPLY_RECEIVED_HANDLER, handler);
35
+ NativeReplies.setOnNewReplyReceivedHandler(handler);
36
+ };
37
+
38
+ /**
39
+ * Returns the number of unread messages the user currently has.
40
+ * Use this method to get the number of unread messages the user
41
+ * has, then possibly notify them about it with your own UI.
42
+ * Notifications count, or -1 in case the SDK has not been initialized.
43
+ */
44
+ export const getUnreadRepliesCount = async (): Promise<number> => {
45
+ const count = await NativeReplies.getUnreadRepliesCount();
46
+
47
+ return count;
48
+ };
49
+
50
+ /**
51
+ * Enables/disables showing in-app notifications when the user receives a
52
+ * new message.
53
+ * @param isEnabled A boolean to set whether
54
+ * notifications are enabled or disabled.
55
+ */
56
+ export const setInAppNotificationsEnabled = (isEnabled: boolean) => {
57
+ NativeReplies.setInAppNotificationEnabled(isEnabled);
58
+ };
59
+
60
+ /**
61
+ * Set whether new in app notification received will play a small sound notification
62
+ * or not (Default is {@code false})
63
+ * @android
64
+ *
65
+ * @param isEnabled desired state of conversation sounds
66
+ */
67
+ export const setInAppNotificationSound = (isEnabled: boolean) => {
68
+ if (Platform.OS === 'android') {
69
+ NativeReplies.setInAppNotificationSound(isEnabled);
70
+ }
71
+ };
72
+
73
+ /**
74
+ * Enables/disables the use of push notifications in the SDK.
75
+ * Defaults to YES.
76
+ * @param isEnabled A boolean to indicate whether push notifications are enabled or disabled.
77
+ */
78
+ export const setPushNotificationsEnabled = (isEnabled: boolean) => {
79
+ NativeReplies.setPushNotificationsEnabled(isEnabled);
80
+ };
81
+
82
+ /**
83
+ * Set the GCM registration token to Luciq
84
+ *
85
+ * @param token the GCM registration token
86
+ */
87
+ export const setPushNotificationRegistrationTokenAndroid = (token: string) => {
88
+ if (Platform.OS === 'android') {
89
+ NativeReplies.setPushNotificationRegistrationToken(token);
90
+ }
91
+ };
92
+
93
+ /**
94
+ * Show in-app Messaging's notifications
95
+ *
96
+ * @param data the data bundle related to Luciq
97
+ */
98
+ export const showNotificationAndroid = (data: Record<string, string>) => {
99
+ if (Platform.OS === 'android') {
100
+ NativeReplies.showNotification(data);
101
+ }
102
+ };
103
+
104
+ /**
105
+ * Set the push notification's icon that will be shown with Luciq notifications
106
+ *
107
+ * @param resourceId the notification icon resource ID
108
+ */
109
+ export const setNotificationIconAndroid = (resourceId: number) => {
110
+ if (Platform.OS === 'android') {
111
+ NativeReplies.setNotificationIcon(resourceId);
112
+ }
113
+ };
114
+
115
+ /**
116
+ * Set a notification channel id to a notification channel that notifications
117
+ * can be posted to.
118
+ *
119
+ * @param id an id to a notification channel that notifications
120
+ */
121
+ export const setPushNotificationChannelIdAndroid = (id: string) => {
122
+ if (Platform.OS === 'android') {
123
+ NativeReplies.setPushNotificationChannelId(id);
124
+ }
125
+ };
126
+
127
+ /**
128
+ * Set whether new system notification received will play the default sound from
129
+ * RingtoneManager or not (Default is {@code false})
130
+ *
131
+ * @param isEnabled desired state of conversation sounds
132
+ */
133
+ export const setSystemReplyNotificationSoundEnabledAndroid = (isEnabled: boolean) => {
134
+ if (Platform.OS === 'android') {
135
+ NativeReplies.setSystemReplyNotificationSoundEnabled(isEnabled);
136
+ }
137
+ };
@@ -0,0 +1,111 @@
1
+ import { NativeSessionReplay, NativeEvents, emitter } from '../native/NativeSessionReplay';
2
+ import type { SessionMetadata } from '../models/SessionMetadata';
3
+ /**
4
+ * Enables or disables Session Replay for your Luciq integration.
5
+ *
6
+ * By default, Session Replay is enabled if it is available in your current plan
7
+ *
8
+ * @param isEnabled
9
+ *
10
+ * @example
11
+ * ```ts
12
+ * SessionReplay.setEnabled(true);
13
+ * ```
14
+ */
15
+ export const setEnabled = (isEnabled: boolean) => {
16
+ NativeSessionReplay.setEnabled(isEnabled);
17
+ };
18
+
19
+ /**
20
+ * Enables or disables network logs for Session Replay.
21
+ *
22
+ * By default, network logs are enabled.
23
+ *
24
+ * @param isEnabled
25
+ *
26
+ * @example
27
+ * ```ts
28
+ * SessionReplay.setNetworkLogsEnabled(true);
29
+ * ```
30
+ */
31
+ export const setNetworkLogsEnabled = (isEnabled: boolean) => {
32
+ NativeSessionReplay.setNetworkLogsEnabled(isEnabled);
33
+ };
34
+
35
+ /**
36
+ * Enables or disables Luciq logs for Session Replay.
37
+ *
38
+ * By default, Luciq logs are enabled.
39
+ *
40
+ * @param isEnabled
41
+ *
42
+ * @example
43
+ * ```ts
44
+ * SessionReplay.setLuciqLogsEnabled(true);
45
+ * ```
46
+ */
47
+ export const setLuciqLogsEnabled = (isEnabled: boolean) => {
48
+ NativeSessionReplay.setLuciqLogsEnabled(isEnabled);
49
+ };
50
+
51
+ /**
52
+ * Enables or disables capturing of user steps for Session Replay.
53
+ *
54
+ * By default, user steps are enabled.
55
+ *
56
+ * @param isEnabled
57
+ *
58
+ * @example
59
+ * ```ts
60
+ * SessionReplay.setUserStepsEnabled(true);
61
+ * ```
62
+ */
63
+ export const setUserStepsEnabled = (isEnabled: boolean) => {
64
+ NativeSessionReplay.setUserStepsEnabled(isEnabled);
65
+ };
66
+
67
+ /**
68
+ * Retrieves current session's replay link.
69
+ *
70
+ * @example
71
+ * ```ts
72
+ * SessionReplay.getSessionReplayLink();
73
+ * ```
74
+ */
75
+ export const getSessionReplayLink = async (): Promise<string> => {
76
+ return NativeSessionReplay.getSessionReplayLink();
77
+ };
78
+
79
+ /**
80
+ * Set a callback for whether this session should sync
81
+ *
82
+ * @param handler
83
+
84
+ * @example
85
+ * ```ts
86
+ * SessionReplay.setSyncCallback((metadata) => {
87
+ * return metadata.device == "Xiaomi M2007J3SY" &&
88
+ * metadata.os == "OS Level 33" &&
89
+ * metadata.appVersion == "3.1.4 (4)" ||
90
+ * metadata.sessionDurationInSeconds > 20;
91
+ * });
92
+ * ```
93
+ */
94
+ export const setSyncCallback = async (
95
+ handler: (payload: SessionMetadata) => boolean,
96
+ ): Promise<void> => {
97
+ emitter.addListener(NativeEvents.SESSION_REPLAY_ON_SYNC_CALLBACK_INVOCATION, (payload) => {
98
+ const result = handler(payload);
99
+ const shouldSync = Boolean(result);
100
+
101
+ if (typeof result !== 'boolean') {
102
+ console.warn(
103
+ `LCQ-RN: The callback passed to SessionReplay.setSyncCallback was expected to return a boolean but returned "${result}". The value has been cast to boolean, proceeding with ${shouldSync}.`,
104
+ );
105
+ }
106
+
107
+ NativeSessionReplay.evaluateSync(shouldSync);
108
+ });
109
+
110
+ return NativeSessionReplay.setSyncCallback();
111
+ };
@@ -0,0 +1,118 @@
1
+ import { Platform } from 'react-native';
2
+
3
+ import { NativeEvents, NativeSurveys, emitter } from '../native/NativeSurveys';
4
+ import type { Survey } from '../native/NativeSurveys';
5
+
6
+ export type { Survey };
7
+
8
+ /**
9
+ * Sets whether surveys are enabled or not.
10
+ * If you disable surveys on the SDK but still have active surveys on your Luciq dashboard,
11
+ * those surveys are still going to be sent to the device, but are not going to be
12
+ * shown automatically.
13
+ * To manually display any available surveys, call `Luciq.showSurveyIfAvailable()`.
14
+ * Defaults to `true`.
15
+ * @param isEnabled A boolean to set whether Luciq Surveys is enabled or disabled.
16
+ */
17
+ export const setEnabled = (isEnabled: boolean) => {
18
+ NativeSurveys.setEnabled(isEnabled);
19
+ };
20
+
21
+ /**
22
+ * Shows one of the surveys that were not shown before, that also have conditions
23
+ * that match the current device/user.
24
+ * Does nothing if there are no available surveys or if a survey has already been shown
25
+ * in the current session.
26
+ */
27
+ export const showSurveyIfAvailable = () => {
28
+ NativeSurveys.showSurveysIfAvailable();
29
+ };
30
+
31
+ /**
32
+ * Returns an array containing the available surveys.
33
+ */
34
+ export const getAvailableSurveys = async (): Promise<Survey[] | null> => {
35
+ const surveys = await NativeSurveys.getAvailableSurveys();
36
+
37
+ return surveys;
38
+ };
39
+
40
+ /**
41
+ * Sets whether auto surveys showing are enabled or not.
42
+ * @param autoShowingSurveysEnabled A boolean to indicate whether the
43
+ * surveys auto showing are enabled or not.
44
+ */
45
+ export const setAutoShowingEnabled = (autoShowingSurveysEnabled: boolean) => {
46
+ NativeSurveys.setAutoShowingEnabled(autoShowingSurveysEnabled);
47
+ };
48
+
49
+ /**
50
+ * Sets a block of code to be executed just before the survey's UI is presented.
51
+ * This block is executed on the UI thread. Could be used for performing any UI changes before
52
+ * the survey's UI is shown.
53
+ * @param onShowHandler - A block of code that gets executed before
54
+ * presenting the survey's UI.
55
+ */
56
+ export const setOnShowHandler = (onShowHandler: () => void) => {
57
+ emitter.addListener(NativeEvents.WILL_SHOW_SURVEY_HANDLER, onShowHandler);
58
+ NativeSurveys.setOnShowHandler(onShowHandler);
59
+ };
60
+
61
+ /**
62
+ * Sets a block of code to be executed right after the survey's UI is dismissed.
63
+ * This block is executed on the UI thread. Could be used for performing any UI
64
+ * changes after the survey's UI is dismissed.
65
+ * @param onDismissHandler - A block of code that gets executed after
66
+ * the survey's UI is dismissed.
67
+ */
68
+ export const setOnDismissHandler = (onDismissHandler: () => void) => {
69
+ emitter.addListener(NativeEvents.DID_DISMISS_SURVEY_HANDLER, onDismissHandler);
70
+ NativeSurveys.setOnDismissHandler(onDismissHandler);
71
+ };
72
+
73
+ /**
74
+ * Shows survey with a specific token.
75
+ * Does nothing if there are no available surveys with that specific token.
76
+ * Answered and cancelled surveys won't show up again.
77
+ * @param surveyToken - A String with a survey token.
78
+ *
79
+ */
80
+ export const showSurvey = (surveyToken: string) => {
81
+ NativeSurveys.showSurvey(surveyToken);
82
+ };
83
+
84
+ /**
85
+ * Returns true if the survey with a specific token was answered before.
86
+ * Will return false if the token does not exist or if the survey was not answered before.
87
+ * @param surveyToken - A String with a survey token.
88
+ * the survey has been responded to or not.
89
+ *
90
+ */
91
+ export const hasRespondedToSurvey = async (surveyToken: string): Promise<boolean | null> => {
92
+ const hasResponded = await NativeSurveys.hasRespondedToSurvey(surveyToken);
93
+
94
+ return hasResponded;
95
+ };
96
+
97
+ /**
98
+ * Setting an option for all the surveys to show a welcome screen before
99
+ * the user starts taking the survey.
100
+ * @param shouldShowWelcomeScreen A boolean for setting whether the
101
+ * welcome screen should show.
102
+ */
103
+ export const setShouldShowWelcomeScreen = (shouldShowWelcomeScreen: boolean) => {
104
+ NativeSurveys.setShouldShowWelcomeScreen(shouldShowWelcomeScreen);
105
+ };
106
+
107
+ /**
108
+ * iOS Only
109
+ * Sets url for the published iOS app on AppStore, You can redirect
110
+ * NPS Surveys or AppRating Surveys to AppStore to let users rate your app on AppStore itself.
111
+ * @param appStoreURL A String url for the published iOS app on AppStore
112
+ */
113
+
114
+ export const setAppStoreURL = (appStoreURL: string) => {
115
+ if (Platform.OS === 'ios') {
116
+ NativeSurveys.setAppStoreURL(appStoreURL);
117
+ }
118
+ };
@@ -0,0 +1,51 @@
1
+ import type { NativeModule } from 'react-native';
2
+ import { NativeEventEmitter } from 'react-native';
3
+
4
+ import type { W3cExternalTraceAttributes } from '../models/W3cExternalTraceAttributes';
5
+ import { NativeModules } from './NativePackage';
6
+
7
+ export interface ApmNativeModule extends NativeModule {
8
+ // Essential APIs //
9
+ setEnabled(isEnabled: boolean): void;
10
+
11
+ // Network APIs //
12
+ networkLogAndroid(
13
+ requestStartTime: number,
14
+ requestDuration: number,
15
+ requestHeaders: string,
16
+ requestBody: string,
17
+ requestBodySize: number,
18
+ requestMethod: string,
19
+ requestUrl: string,
20
+ requestContentType: string,
21
+ responseHeaders: string,
22
+ responseBody: string | null,
23
+ responseBodySize: number,
24
+ statusCode: number,
25
+ responseContentType: string,
26
+ errorDomain: string,
27
+ w3cExternalTraceAttributes: W3cExternalTraceAttributes,
28
+ gqlQueryName?: string,
29
+ serverErrorMessage?: string,
30
+ ): void;
31
+
32
+ // App Launches APIs //
33
+ setAppLaunchEnabled(isEnabled: boolean): void;
34
+ endAppLaunch(): void;
35
+
36
+ // Execution Traces APIs //
37
+ // App Flows APIs //
38
+ startFlow(name: string): void;
39
+ endFlow(name: string): void;
40
+ setFlowAttribute(name: string, key: string, value?: string | null): void;
41
+
42
+ // UI Traces APIs //
43
+ setAutoUITraceEnabled(isEnabled: boolean): void;
44
+ startUITrace(name: string): void;
45
+ endUITrace(): void;
46
+ lcqSleep(): void;
47
+ }
48
+
49
+ export const NativeAPM = NativeModules.LCQAPM;
50
+
51
+ export const emitter = new NativeEventEmitter(NativeAPM);