@luciq/react-native 18.0.0 → 18.2.0-13120-SNAPSHOT

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 (45) hide show
  1. package/CHANGELOG.md +30 -0
  2. package/README.md +0 -2
  3. package/RNLuciq.podspec +2 -1
  4. package/android/build.gradle +1 -2
  5. package/android/native.gradle +2 -1
  6. package/android/src/main/java/ai/luciq/reactlibrary/ArgsRegistry.java +1 -0
  7. package/android/src/main/java/ai/luciq/reactlibrary/RNLuciqBugReportingModule.java +23 -1
  8. package/bin/config/migration-config.json +5 -5
  9. package/bin/index.js +3 -8
  10. package/cli/config/migration-config.json +5 -5
  11. package/cli/upload/migrate.ts +2 -8
  12. package/dangerfile.ts +1 -1
  13. package/dist/index.d.ts +2 -1
  14. package/dist/index.js +2 -1
  15. package/dist/models/ProactiveReportingConfigs.d.ts +10 -0
  16. package/dist/models/ProactiveReportingConfigs.js +22 -0
  17. package/dist/modules/BugReporting.d.ts +6 -0
  18. package/dist/modules/BugReporting.js +7 -0
  19. package/dist/native/NativeBugReporting.d.ts +1 -0
  20. package/dist/native/NativeConstants.d.ts +1 -0
  21. package/dist/native/NativeCrashReporting.d.ts +8 -0
  22. package/dist/utils/Enums.d.ts +2 -1
  23. package/dist/utils/Enums.js +1 -0
  24. package/dist/utils/LuciqConstants.d.ts +2 -0
  25. package/dist/utils/LuciqConstants.js +2 -0
  26. package/dist/utils/LuciqUtils.js +17 -0
  27. package/dist/utils/XhrNetworkInterceptor.js +9 -4
  28. package/ios/RNLuciq/ArgsRegistry.m +2 -1
  29. package/ios/RNLuciq/LuciqAPMBridge.h +0 -2
  30. package/ios/RNLuciq/LuciqBugReportingBridge.h +2 -0
  31. package/ios/RNLuciq/LuciqBugReportingBridge.m +8 -0
  32. package/ios/native.rb +1 -1
  33. package/package.json +1 -2
  34. package/plugin/build/index.js +482 -367
  35. package/src/index.ts +6 -0
  36. package/src/models/ProactiveReportingConfigs.ts +37 -0
  37. package/src/modules/BugReporting.ts +13 -1
  38. package/src/native/NativeBugReporting.ts +6 -0
  39. package/src/native/NativeConstants.ts +1 -0
  40. package/src/native/NativeCrashReporting.ts +8 -0
  41. package/src/utils/Enums.ts +1 -0
  42. package/src/utils/LuciqConstants.ts +4 -0
  43. package/src/utils/LuciqUtils.ts +18 -1
  44. package/src/utils/XhrNetworkInterceptor.ts +9 -5
  45. package/upload/index.js +3 -8
package/src/index.ts CHANGED
@@ -10,6 +10,10 @@ import * as FeatureRequests from './modules/FeatureRequests';
10
10
  import * as Luciq from './modules/Luciq';
11
11
  import * as NetworkLogger from './modules/NetworkLogger';
12
12
  import type { NetworkData, NetworkDataObfuscationHandler } from './modules/NetworkLogger';
13
+ import {
14
+ createProactiveReportingConfig,
15
+ type ProactiveReportingConfigOptions,
16
+ } from './models/ProactiveReportingConfigs';
13
17
  import * as Replies from './modules/Replies';
14
18
  import type { Survey } from './modules/Surveys';
15
19
  import * as Surveys from './modules/Surveys';
@@ -27,6 +31,8 @@ export {
27
31
  SessionReplay,
28
32
  Replies,
29
33
  Surveys,
34
+ ProactiveReportingConfigOptions,
35
+ createProactiveReportingConfig,
30
36
  };
31
37
  export type {
32
38
  LuciqConfig,
@@ -0,0 +1,37 @@
1
+ import { Logger } from '../utils/logger';
2
+ import LuciqConstants from '../utils/LuciqConstants';
3
+
4
+ export interface ProactiveReportingConfigOptions {
5
+ gapBetweenModals: number;
6
+ modalDelayAfterDetection: number;
7
+ enabled: boolean;
8
+ }
9
+
10
+ export function createProactiveReportingConfig(
11
+ {
12
+ gapBetweenModals = 24,
13
+ modalDelayAfterDetection = 20,
14
+ enabled = true,
15
+ }: ProactiveReportingConfigOptions = {
16
+ gapBetweenModals: 24,
17
+ modalDelayAfterDetection: 20,
18
+ enabled: true,
19
+ },
20
+ ) {
21
+ // Validation and defaults
22
+ if (gapBetweenModals <= 0) {
23
+ Logger.warn(LuciqConstants.GAP_MODEL_ERROR_MESSAGE);
24
+ gapBetweenModals = 24; // Use default value if invalid
25
+ }
26
+
27
+ if (modalDelayAfterDetection <= 0) {
28
+ Logger.warn(LuciqConstants.MODAL_DETECTION_ERROR_MESSAGE);
29
+ modalDelayAfterDetection = 20; // Use default value if invalid
30
+ }
31
+
32
+ return {
33
+ gapBetweenModals,
34
+ modalDelayAfterDetection,
35
+ enabled,
36
+ };
37
+ }
@@ -1,7 +1,7 @@
1
1
  import { Platform } from 'react-native';
2
2
 
3
3
  import { NativeBugReporting, NativeEvents, emitter } from '../native/NativeBugReporting';
4
-
4
+ import type { ProactiveReportingConfigOptions } from '../models/ProactiveReportingConfigs';
5
5
  import type {
6
6
  DismissType,
7
7
  ExtendedBugReportMode,
@@ -252,3 +252,15 @@ export const setCommentMinimumCharacterCount = (limit: number, reportTypes?: Rep
252
252
  NativeBugReporting.setCommentMinimumCharacterCount(limit, reportTypes ?? []);
253
253
  }
254
254
  };
255
+
256
+ /**
257
+ ** prompts end users to submit their feedback after our SDK automatically detects a frustrating experience.
258
+ * @param config configuration of proActive bug report.
259
+ */
260
+ export const setProactiveReportingConfigurations = (config: ProactiveReportingConfigOptions) => {
261
+ NativeBugReporting.setProactiveReportingConfigurations(
262
+ config.enabled,
263
+ config.gapBetweenModals,
264
+ config.modalDelayAfterDetection,
265
+ );
266
+ };
@@ -57,6 +57,12 @@ export interface BugReportingNativeModule extends NativeModule {
57
57
  checked: boolean,
58
58
  actionType?: userConsentActionType,
59
59
  ): void;
60
+
61
+ setProactiveReportingConfigurations(
62
+ enabled: boolean,
63
+ gapBetweenModals: number,
64
+ modalDelayAfterDetection: number,
65
+ ): void;
60
66
  }
61
67
 
62
68
  export const NativeBugReporting = NativeModules.LCQBugReporting;
@@ -28,6 +28,7 @@ interface NativeUserConsentActionType {
28
28
  dropAutoCapturedMedia: any;
29
29
  dropLogs: any;
30
30
  noChat: any;
31
+ noAutomaticBugGrouping: any;
31
32
  }
32
33
  interface NativeInvocationEvent {
33
34
  invocationEventNone: any;
@@ -11,8 +11,16 @@ export interface CrashData {
11
11
  os: (typeof Platform)['OS'];
12
12
  platform: 'react_native';
13
13
  exception: StackFrame[];
14
+ cause_crash?: CauseCrashData;
14
15
  }
15
16
 
17
+ export interface CauseCrashData {
18
+ message: string;
19
+ e_message: string;
20
+ e_name: string;
21
+ exception: StackFrame[];
22
+ cause_crash?: CauseCrashData;
23
+ }
16
24
  export interface CrashReportingNativeModule extends NativeModule {
17
25
  setEnabled(isEnabled: boolean): void;
18
26
  sendJSCrash(data: CrashData | string): Promise<void>;
@@ -20,6 +20,7 @@ export enum userConsentActionType {
20
20
  dropAutoCapturedMedia = constants.dropAutoCapturedMedia,
21
21
  dropLogs = constants.dropLogs,
22
22
  noChat = constants.noChat,
23
+ noAutomaticBugGrouping = constants.noAutomaticBugGrouping,
23
24
  }
24
25
 
25
26
  /**
@@ -12,6 +12,10 @@ const LuciqConstants = {
12
12
  REMOVE_USER_ATTRIBUTES_ERROR_TYPE_MESSAGE:
13
13
  'LCQ-RN: Expected key and value passed to removeUserAttribute to be of type string',
14
14
  DEFAULT_METRO_PORT: '8081',
15
+ GAP_MODEL_ERROR_MESSAGE:
16
+ 'gapBetweenModals must be a positive number. Using default value of 24 seconds.',
17
+ MODAL_DETECTION_ERROR_MESSAGE:
18
+ 'modalDelayAfterDetection must be a positive number. Using default value of 20 seconds.',
15
19
  LCQ_APM_TAG: 'LCQ-APM: ',
16
20
  SWITCHED_TO_NATIVE_INTERCEPTION_MESSAGE:
17
21
  'Android Plugin Detected. Switched to Native Interception.',
@@ -7,7 +7,7 @@ import parseErrorStackLib, {
7
7
  import type { NavigationState as NavigationStateV5, PartialState } from '@react-navigation/native';
8
8
  import type { NavigationState as NavigationStateV4 } from 'react-navigation';
9
9
 
10
- import type { CrashData } from '../native/NativeCrashReporting';
10
+ import type { CauseCrashData, CrashData } from '../native/NativeCrashReporting';
11
11
  import { NativeCrashReporting } from '../native/NativeCrashReporting';
12
12
  import type { NetworkData } from './XhrNetworkInterceptor';
13
13
  import { NativeLuciq } from '../native/NativeLuciq';
@@ -59,6 +59,23 @@ export const getCrashDataFromError = (error: Error) => {
59
59
  platform: 'react_native',
60
60
  exception: jsStackTrace,
61
61
  };
62
+ // Recursively attach inner_crash objects (up to 3 levels)
63
+ let currentError: any = error;
64
+ let level = 0;
65
+ let parentCrash: CauseCrashData | CrashData = jsonObject;
66
+ while (currentError.cause && level < 3) {
67
+ const cause = currentError.cause as Error;
68
+ const innerCrash: CauseCrashData = {
69
+ message: `${cause.name} - ${cause.message}`,
70
+ e_message: cause.message,
71
+ e_name: cause.name,
72
+ exception: getStackTrace(cause),
73
+ };
74
+ parentCrash.cause_crash = innerCrash;
75
+ parentCrash = innerCrash;
76
+ currentError = cause;
77
+ level++;
78
+ }
62
79
  return jsonObject;
63
80
  };
64
81
 
@@ -275,11 +275,15 @@ export default {
275
275
  cloneNetwork.gqlQueryName = '';
276
276
  }
277
277
  if (cloneNetwork.responseBody) {
278
- const responseObj = JSON.parse(cloneNetwork.responseBody);
279
-
280
- if (responseObj.errors) {
281
- cloneNetwork.serverErrorMessage = 'GraphQLError';
282
- } else {
278
+ try {
279
+ const responseObj = JSON.parse(cloneNetwork.responseBody);
280
+
281
+ if (responseObj.errors) {
282
+ cloneNetwork.serverErrorMessage = 'GraphQLError';
283
+ } else {
284
+ cloneNetwork.serverErrorMessage = '';
285
+ }
286
+ } catch (_error) {
283
287
  cloneNetwork.serverErrorMessage = '';
284
288
  }
285
289
  }
package/upload/index.js CHANGED
@@ -12834,7 +12834,7 @@ FormData$1.prototype._error = function (err) {
12834
12834
  FormData$1.prototype.toString = function () {
12835
12835
  return '[object FormData]';
12836
12836
  };
12837
- setToStringTag(FormData$1, 'FormData');
12837
+ setToStringTag(FormData$1.prototype, 'FormData');
12838
12838
  var form_data = FormData$1;
12839
12839
  var FormData$2 = getDefaultExportFromCjs(form_data);
12840
12840
 
@@ -17155,8 +17155,6 @@ const migrate = async (opts) => {
17155
17155
  // Sort methods by priority (lower number = higher priority)
17156
17156
  const sortedMethods = enabledMethods.sort((a, b) => (a.priority || 999) - (b.priority || 999));
17157
17157
  if (!opts.silent) {
17158
- console.log('🔄 Starting migration with all enabled methods');
17159
- console.log(`📝 Found ${sortedMethods.length} enabled method(s):`);
17160
17158
  sortedMethods.forEach((method) => {
17161
17159
  console.log(` - ${method.name}: ${method.description}`);
17162
17160
  });
@@ -17256,13 +17254,13 @@ function processFile(filePath, method, dryRun, silent) {
17256
17254
  if (newContent !== content) {
17257
17255
  if (dryRun) {
17258
17256
  if (!silent) {
17259
- console.log(`📝 [${method.name}] Would update content: ${filePath}`);
17257
+ console.log(`📝 Update content: ${filePath}`);
17260
17258
  }
17261
17259
  return;
17262
17260
  }
17263
17261
  fs$1.writeFileSync(filePath, newContent, 'utf8');
17264
17262
  if (!silent) {
17265
- console.log(`📝 [${method.name}] Updated content: ${filePath}`);
17263
+ console.log(`📝 Update content: ${filePath}`);
17266
17264
  }
17267
17265
  }
17268
17266
  }
@@ -17301,9 +17299,6 @@ async function executeAllMethods(methods, dryRun, silent) {
17301
17299
  }
17302
17300
  async function executeMethod(method, dryRun, silent) {
17303
17301
  const startDir = process.cwd();
17304
- if (!silent) {
17305
- console.log(`🚀 Executing method: ${method.name}`);
17306
- }
17307
17302
  walkDirectory(startDir, method, dryRun, silent);
17308
17303
  }
17309
17304