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