@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
package/migrate.js ADDED
@@ -0,0 +1,569 @@
1
+ #!/usr/bin/env node
2
+
3
+ const fs = require('fs');
4
+ const path = require('path');
5
+ const { execSync } = require('child_process');
6
+
7
+ // -----------------------------------
8
+ // Configuration
9
+ // -----------------------------------
10
+
11
+ // Multiple refactor methods with multiple search-replace pairs
12
+ const REFACTOR_METHODS = [
13
+ {
14
+ name: 'Instabug to Luciq',
15
+ description: 'Replace all instances of Instabug with Luciq',
16
+ searchReplace: [
17
+ { search: 'Instabug', replacement: 'Luciq' },
18
+ { search: 'instabug', replacement: 'luciq' },
19
+ { search: 'INSTABUG', replacement: 'LUCIQ' },
20
+ { search: 'IBG', replacement: 'LCQ' },
21
+ { search: 'ibg', replacement: 'lcq' },
22
+ ],
23
+ targetExtensions: [
24
+ '.h',
25
+ '.m',
26
+ '.plist',
27
+ '.pbxproj',
28
+ '.xcscheme',
29
+ '.sh',
30
+ '.java',
31
+ '.kt',
32
+ '.ts',
33
+ '.tsx',
34
+ '.js',
35
+ '.jsx',
36
+ '.json',
37
+ '.xml',
38
+ '.gradle',
39
+ '.properties',
40
+ '.md',
41
+ '.txt',
42
+ ],
43
+ ignoredDirs: [
44
+ 'node_modules',
45
+ 'build',
46
+ 'Pods',
47
+ 'vendor',
48
+ '.git',
49
+ 'dist',
50
+ 'coverage',
51
+ '.next',
52
+ '.nuxt',
53
+ 'target',
54
+ ],
55
+ enabled: true,
56
+ },
57
+ {
58
+ name: 'Package Name Update',
59
+ description: 'Update package names and references',
60
+ searchReplace: [
61
+ { search: 'com.instabug', replacement: 'ai.luciq' },
62
+ { search: 'com.instabug.reactlibrary', replacement: 'ai.luciq.reactlibrary' },
63
+ { search: 'RNInstabug', replacement: 'RNLuciq' },
64
+ { search: 'rninstabug', replacement: 'rnluciq' },
65
+ ],
66
+ targetExtensions: [
67
+ '.java',
68
+ '.kt',
69
+ '.xml',
70
+ '.gradle',
71
+ '.properties',
72
+ '.ts',
73
+ '.tsx',
74
+ '.js',
75
+ '.jsx',
76
+ '.json',
77
+ ],
78
+ ignoredDirs: ['node_modules', 'build', 'Pods', 'vendor', '.git', 'dist', 'coverage'],
79
+ enabled: false,
80
+ },
81
+ {
82
+ name: 'File Extension Cleanup',
83
+ description: 'Clean up file extensions and references',
84
+ searchReplace: [
85
+ { search: '.instabug', replacement: '.luciq' },
86
+ { search: '_instabug', replacement: '_luciq' },
87
+ { search: 'instabug_', replacement: 'luciq_' },
88
+ ],
89
+ targetExtensions: [
90
+ '.ts',
91
+ '.tsx',
92
+ '.js',
93
+ '.jsx',
94
+ '.json',
95
+ '.xml',
96
+ '.gradle',
97
+ '.properties',
98
+ '.md',
99
+ '.txt',
100
+ ],
101
+ ignoredDirs: ['node_modules', 'build', 'Pods', 'vendor', '.git', 'dist', 'coverage'],
102
+ enabled: false,
103
+ },
104
+ ];
105
+
106
+ // Global settings
107
+ const GLOBAL_SETTINGS = {
108
+ enableGitCheck: false,
109
+ backupBeforeRefactor: false,
110
+ dryRun: false,
111
+ maxFileSize: 10 * 1024 * 1024, // 10MB
112
+ verbose: true,
113
+ };
114
+
115
+ // -----------------------------------
116
+ // Utility Functions
117
+ // -----------------------------------
118
+
119
+ function checkGitClean() {
120
+ if (!GLOBAL_SETTINGS.enableGitCheck) {
121
+ return;
122
+ }
123
+
124
+ try {
125
+ const status = execSync('git status --porcelain').toString();
126
+ if (status.trim()) {
127
+ console.error('āŒ Uncommitted changes detected. Please commit or stash your changes first.');
128
+ process.exit(1);
129
+ }
130
+ } catch (error) {
131
+ console.warn('āš ļø Git check failed, continuing without git validation...');
132
+ }
133
+ }
134
+
135
+ function isIgnored(filePath, ignoredDirs) {
136
+ return ignoredDirs.some((dir) => filePath.split(path.sep).includes(dir));
137
+ }
138
+
139
+ function casePreservingReplace(str, searchReplace) {
140
+ let result = str;
141
+
142
+ for (const { search, replacement } of searchReplace) {
143
+ result = result.replace(new RegExp(search, 'gi'), (match) => {
144
+ if (match === match.toUpperCase()) {
145
+ return replacement.toUpperCase();
146
+ }
147
+ if (match[0] === match[0].toUpperCase()) {
148
+ return replacement[0].toUpperCase() + replacement.slice(1);
149
+ }
150
+ return replacement.toLowerCase();
151
+ });
152
+ }
153
+
154
+ return result;
155
+ }
156
+
157
+ function createBackup(filePath) {
158
+ if (!GLOBAL_SETTINGS.backupBeforeRefactor) {
159
+ return;
160
+ }
161
+
162
+ const backupPath = `${filePath}.backup.${Date.now()}`;
163
+ try {
164
+ fs.copyFileSync(filePath, backupPath);
165
+ if (GLOBAL_SETTINGS.verbose) {
166
+ console.log(`šŸ’¾ Backup created: ${backupPath}`);
167
+ }
168
+ } catch (error) {
169
+ console.warn(`āš ļø Failed to create backup for ${filePath}:`, error.message);
170
+ }
171
+ }
172
+
173
+ // -----------------------------------
174
+ // File Processing
175
+ // -----------------------------------
176
+
177
+ function processFile(filePath, method) {
178
+ if (isIgnored(filePath, method.ignoredDirs)) {
179
+ return;
180
+ }
181
+
182
+ try {
183
+ const stats = fs.statSync(filePath);
184
+ if (stats.size > GLOBAL_SETTINGS.maxFileSize) {
185
+ if (GLOBAL_SETTINGS.verbose) {
186
+ console.log(
187
+ `ā­ļø Skipping large file: ${filePath} (${(stats.size / 1024 / 1024).toFixed(2)}MB)`,
188
+ );
189
+ }
190
+ return;
191
+ }
192
+
193
+ const content = fs.readFileSync(filePath, 'utf8');
194
+ const newContent = casePreservingReplace(content, method.searchReplace);
195
+
196
+ if (newContent !== content) {
197
+ if (GLOBAL_SETTINGS.dryRun) {
198
+ console.log(`šŸ“ [${method.name}] Would update content: ${filePath}`);
199
+ return;
200
+ }
201
+
202
+ createBackup(filePath);
203
+ fs.writeFileSync(filePath, newContent, 'utf8');
204
+ console.log(`šŸ“ [${method.name}] Updated content: ${filePath}`);
205
+ }
206
+
207
+ const dir = path.dirname(filePath);
208
+ const fileName = path.basename(filePath);
209
+ const newFileName = casePreservingReplace(fileName, method.searchReplace);
210
+
211
+ if (fileName !== newFileName) {
212
+ const newPath = path.join(dir, newFileName);
213
+ if (!fs.existsSync(newPath)) {
214
+ if (GLOBAL_SETTINGS.dryRun) {
215
+ console.log(`šŸ“ [${method.name}] Would rename file: ${filePath} → ${newPath}`);
216
+ return;
217
+ }
218
+
219
+ fs.renameSync(filePath, newPath);
220
+ console.log(`šŸ“ [${method.name}] Renamed file: ${filePath} → ${newPath}`);
221
+ } else {
222
+ console.warn(
223
+ `āš ļø [${method.name}] Skipping file rename: ${filePath} → ${newPath} (target exists)`,
224
+ );
225
+ }
226
+ }
227
+ } catch (error) {
228
+ console.error(`āŒ Error processing file ${filePath}:`, error.message);
229
+ }
230
+ }
231
+
232
+ // -----------------------------------
233
+ // Folder Rename
234
+ // -----------------------------------
235
+
236
+ function renameFolderIfNeeded(dirPath, method) {
237
+ if (isIgnored(dirPath, method.ignoredDirs)) {
238
+ return dirPath;
239
+ }
240
+
241
+ try {
242
+ const parentDir = path.dirname(dirPath);
243
+ const currentFolder = path.basename(dirPath);
244
+ const newFolder = casePreservingReplace(currentFolder, method.searchReplace);
245
+
246
+ if (currentFolder !== newFolder) {
247
+ const newPath = path.join(parentDir, newFolder);
248
+
249
+ // Check if target already exists
250
+ if (fs.existsSync(newPath)) {
251
+ console.warn(
252
+ `āš ļø [${method.name}] Skipping folder rename: ${dirPath} → ${newPath} (target exists)`,
253
+ );
254
+ return dirPath;
255
+ }
256
+
257
+ // Check if we can actually rename the directory
258
+ try {
259
+ // Test if we can read the directory
260
+ fs.accessSync(dirPath, fs.constants.R_OK);
261
+ } catch (error) {
262
+ console.warn(`āš ļø [${method.name}] Cannot access directory for rename: ${dirPath}`);
263
+ return dirPath;
264
+ }
265
+
266
+ if (GLOBAL_SETTINGS.dryRun) {
267
+ console.log(`šŸ“‚ [${method.name}] Would rename folder: ${dirPath} → ${newPath}`);
268
+ return dirPath;
269
+ }
270
+
271
+ // Perform the rename
272
+ fs.renameSync(dirPath, newPath);
273
+ console.log(`šŸ“‚ [${method.name}] Renamed folder: ${dirPath} → ${newPath}`);
274
+ return newPath;
275
+ }
276
+ } catch (error) {
277
+ console.error(`āŒ Error renaming folder ${dirPath}:`, error.message);
278
+ }
279
+
280
+ return dirPath;
281
+ }
282
+
283
+ // -----------------------------------
284
+ // Recursive Walk
285
+ // -----------------------------------
286
+
287
+ function walkAndRename(dirPath, method) {
288
+ if (isIgnored(dirPath, method.ignoredDirs)) {
289
+ return;
290
+ }
291
+
292
+ try {
293
+ const entries = fs.readdirSync(dirPath, { withFileTypes: true });
294
+
295
+ // Process children (files and subdirectories)
296
+ for (const entry of entries) {
297
+ const fullPath = path.join(dirPath, entry.name);
298
+ if (entry.isDirectory()) {
299
+ // Recursively process subdirectories for files only
300
+ walkAndRename(fullPath, method);
301
+ } else if (method.targetExtensions.includes(path.extname(entry.name))) {
302
+ // Process files
303
+ processFile(fullPath, method);
304
+ }
305
+ }
306
+
307
+ // Note: Directory renaming is now handled separately in processDirectories()
308
+ } catch (error) {
309
+ console.error(`āŒ Error processing directory ${dirPath}:`, error.message);
310
+ }
311
+ }
312
+
313
+ // -----------------------------------
314
+ // Main Directory Processing
315
+ // -----------------------------------
316
+
317
+ function processDirectories(method) {
318
+ console.log(`\nšŸ“‚ Processing directories for method: ${method.name}`);
319
+
320
+ // Get all directories that need to be processed
321
+ const directoriesToProcess = [];
322
+
323
+ function collectDirectories(currentPath, depth = 0) {
324
+ if (isIgnored(currentPath, method.ignoredDirs) || depth > 20) {
325
+ // Prevent infinite recursion
326
+ return;
327
+ }
328
+
329
+ try {
330
+ const entries = fs.readdirSync(currentPath, { withFileTypes: true });
331
+
332
+ for (const entry of entries) {
333
+ if (entry.isDirectory()) {
334
+ const fullPath = path.join(currentPath, entry.name);
335
+ directoriesToProcess.push(fullPath);
336
+ collectDirectories(fullPath, depth + 1);
337
+ }
338
+ }
339
+ } catch (error) {
340
+ if (GLOBAL_SETTINGS.verbose) {
341
+ console.log(`āš ļø [${method.name}] Could not read directory: ${currentPath}`);
342
+ }
343
+ }
344
+ }
345
+
346
+ // Collect all directories first
347
+ collectDirectories(process.cwd());
348
+
349
+ if (directoriesToProcess.length === 0) {
350
+ console.log(` No directories to process for method: ${method.name}`);
351
+ return;
352
+ }
353
+
354
+ console.log(` Found ${directoriesToProcess.length} directories to process`);
355
+
356
+ // Sort directories by depth (deepest first) to avoid conflicts
357
+ directoriesToProcess.sort((a, b) => {
358
+ const depthA = a.split(path.sep).length;
359
+ const depthB = b.split(path.sep).length;
360
+ return depthB - depthA;
361
+ });
362
+
363
+ let renamedCount = 0;
364
+ let skippedCount = 0;
365
+
366
+ // Process directories from deepest to shallowest
367
+ for (const dirPath of directoriesToProcess) {
368
+ try {
369
+ if (fs.existsSync(dirPath)) {
370
+ // Check if directory still exists
371
+ const originalPath = dirPath;
372
+ const newPath = renameFolderIfNeeded(dirPath, method);
373
+
374
+ if (newPath !== originalPath) {
375
+ renamedCount++;
376
+ } else {
377
+ skippedCount++;
378
+ }
379
+ }
380
+ } catch (error) {
381
+ if (GLOBAL_SETTINGS.verbose) {
382
+ console.log(`āš ļø [${method.name}] Could not process directory: ${dirPath}`);
383
+ }
384
+ }
385
+ }
386
+
387
+ console.log(
388
+ ` Directory processing complete: ${renamedCount} renamed, ${skippedCount} unchanged`,
389
+ );
390
+ }
391
+
392
+ // -----------------------------------
393
+ // Method Execution
394
+ // -----------------------------------
395
+
396
+ function executeMethod(method) {
397
+ if (!method.enabled) {
398
+ if (GLOBAL_SETTINGS.verbose) {
399
+ console.log(`ā­ļø Skipping disabled method: ${method.name}`);
400
+ }
401
+ return;
402
+ }
403
+
404
+ console.log(`\nšŸš€ Starting method: ${method.name}`);
405
+ if (method.description) {
406
+ console.log(` Description: ${method.description}`);
407
+ }
408
+ console.log(` Search/Replace pairs: ${method.searchReplace.length}`);
409
+ console.log(` Target extensions: ${method.targetExtensions.join(', ')}`);
410
+ console.log(` Ignored directories: ${method.ignoredDirs.join(', ')}`);
411
+
412
+ const startTime = Date.now();
413
+
414
+ // First process all files
415
+ console.log(`\nšŸ“ Processing files for method: ${method.name}`);
416
+ walkAndRename(process.cwd(), method);
417
+
418
+ // Then process directories (renaming them if needed)
419
+ processDirectories(method);
420
+
421
+ const endTime = Date.now();
422
+
423
+ console.log(`āœ… Method "${method.name}" completed in ${endTime - startTime}ms`);
424
+ }
425
+
426
+ function executeAllMethods() {
427
+ const enabledMethods = REFACTOR_METHODS.filter((method) => method.enabled);
428
+
429
+ if (enabledMethods.length === 0) {
430
+ console.log(
431
+ 'āš ļø No enabled methods found. Please enable at least one method in the configuration.',
432
+ );
433
+ return;
434
+ }
435
+
436
+ console.log(`šŸŽÆ Executing ${enabledMethods.length} enabled method(s)...`);
437
+
438
+ if (GLOBAL_SETTINGS.dryRun) {
439
+ console.log('šŸ” DRY RUN MODE - No changes will be made');
440
+ }
441
+
442
+ for (const method of enabledMethods) {
443
+ try {
444
+ executeMethod(method);
445
+ } catch (error) {
446
+ console.error(`āŒ Error executing method "${method.name}":`, error.message);
447
+ }
448
+ }
449
+ }
450
+
451
+ // -----------------------------------
452
+ // CLI Arguments
453
+ // -----------------------------------
454
+
455
+ function parseArguments() {
456
+ const args = process.argv.slice(2);
457
+
458
+ if (args.includes('--help') || args.includes('-h')) {
459
+ console.log(`
460
+ Usage: node script.js [options]
461
+
462
+ Options:
463
+ --help, -h Show this help message
464
+ --list-methods List all configured methods
465
+ --enable-method <name> Enable a specific method by name
466
+ --disable-method <name> Disable a specific method by name
467
+ --dry-run Show what would be changed without making changes
468
+ --git-check Enable git clean check
469
+ --backup Create backups before making changes
470
+ --verbose Enable verbose output
471
+ --quiet Disable verbose output
472
+ `);
473
+ process.exit(0);
474
+ }
475
+
476
+ if (args.includes('--list-methods')) {
477
+ console.log('\nšŸ“‹ Available Methods:');
478
+ REFACTOR_METHODS.forEach((method, index) => {
479
+ const status = method.enabled ? 'āœ… Enabled' : 'āŒ Disabled';
480
+ console.log(`\n${index + 1}. ${method.name} (${status})`);
481
+ if (method.description) {
482
+ console.log(` Description: ${method.description}`);
483
+ }
484
+ console.log(' Search/Replace pairs:');
485
+ method.searchReplace.forEach(({ search, replacement }) => {
486
+ console.log(` "${search}" → "${replacement}"`);
487
+ });
488
+ });
489
+ process.exit(0);
490
+ }
491
+
492
+ if (args.includes('--enable-method')) {
493
+ const methodIndex = args.indexOf('--enable-method');
494
+ const methodName = args[methodIndex + 1];
495
+ const method = REFACTOR_METHODS.find((m) => m.name === methodName);
496
+
497
+ if (method) {
498
+ method.enabled = true;
499
+ console.log(`āœ… Enabled method: ${methodName}`);
500
+ } else {
501
+ console.error(`āŒ Method not found: ${methodName}`);
502
+ process.exit(1);
503
+ }
504
+ }
505
+
506
+ if (args.includes('--disable-method')) {
507
+ const methodIndex = args.indexOf('--disable-method');
508
+ const methodName = args[methodIndex + 1];
509
+ const method = REFACTOR_METHODS.find((m) => m.name === methodName);
510
+
511
+ if (method) {
512
+ method.enabled = false;
513
+ console.log(`āŒ Disabled method: ${methodName}`);
514
+ } else {
515
+ console.error(`āŒ Method not found: ${methodName}`);
516
+ process.exit(1);
517
+ }
518
+ }
519
+
520
+ if (args.includes('--dry-run')) {
521
+ GLOBAL_SETTINGS.dryRun = true;
522
+ console.log('šŸ” Dry run mode enabled');
523
+ }
524
+
525
+ if (args.includes('--git-check')) {
526
+ GLOBAL_SETTINGS.enableGitCheck = true;
527
+ console.log('šŸ”’ Git check enabled');
528
+ }
529
+
530
+ if (args.includes('--backup')) {
531
+ GLOBAL_SETTINGS.backupBeforeRefactor = true;
532
+ console.log('šŸ’¾ Backup mode enabled');
533
+ }
534
+
535
+ if (args.includes('--verbose')) {
536
+ GLOBAL_SETTINGS.verbose = true;
537
+ console.log('šŸ“¢ Verbose mode enabled');
538
+ }
539
+
540
+ if (args.includes('--quiet')) {
541
+ GLOBAL_SETTINGS.verbose = false;
542
+ console.log('šŸ”‡ Quiet mode enabled');
543
+ }
544
+ }
545
+
546
+ // -----------------------------------
547
+ // Main
548
+ // -----------------------------------
549
+
550
+ function main() {
551
+ console.log('šŸ”„ Multi-Method Refactor Script');
552
+ console.log('================================');
553
+
554
+ parseArguments();
555
+ checkGitClean();
556
+ executeAllMethods();
557
+
558
+ if (GLOBAL_SETTINGS.dryRun) {
559
+ console.log('\nšŸ” Dry run completed. No changes were made.');
560
+ } else {
561
+ console.log('\nšŸŽ‰ All methods completed successfully!');
562
+ }
563
+ }
564
+
565
+ if (require.main === module) {
566
+ main();
567
+ }
568
+
569
+ module.exports = { REFACTOR_METHODS, executeMethod, executeAllMethods, GLOBAL_SETTINGS };
package/package.json ADDED
@@ -0,0 +1,92 @@
1
+ {
2
+ "name": "@luciq/react-native",
3
+ "description": "Luciq is the Agentic Observability Platform built for Mobile.",
4
+ "version": "18.0.0",
5
+ "author": "Luciq (https://luciq.ai)",
6
+ "repository": "github:luciqai/luciq-reactnative-sdk",
7
+ "homepage": "https://www.luciq.ai/platforms/react-native",
8
+ "bugs": "https://github.com/luciqai/luciq-reactnative-sdk/issues",
9
+ "license": "MIT",
10
+ "main": "dist/index",
11
+ "types": "dist/index.d.ts",
12
+ "react-native": "src/index.ts",
13
+ "bin": {
14
+ "luciq": "bin/index.js"
15
+ },
16
+ "keywords": [
17
+ "react-native",
18
+ "luciq",
19
+ "debugging",
20
+ "errors",
21
+ "exceptions",
22
+ "logging",
23
+ "reporting",
24
+ "feedback"
25
+ ],
26
+ "scripts": {
27
+ "lint": "eslint . --ignore-path .gitignore",
28
+ "lint:fix": "yarn lint --fix",
29
+ "lint:ci": "yarn lint --max-warnings=0",
30
+ "format": "prettier --check . --ignore-path .gitignore",
31
+ "format:fix": "prettier --write . --ignore-path .gitignore",
32
+ "test": "jest",
33
+ "build": "yarn build:lib && yarn build:cli",
34
+ "build:lib": "tsc",
35
+ "build:cli": "npx rollup -c rollup.config.js --bundleConfigAsCjs",
36
+ "example": "yarn --cwd examples/default",
37
+ "pods": "cd examples/default && pod-install --quiet",
38
+ "bootstrap": "yarn example && yarn && yarn pods"
39
+ },
40
+ "peerDependencies": {
41
+ "react": ">=16.8.6",
42
+ "react-native": ">=0.60.0"
43
+ },
44
+ "devDependencies": {
45
+ "@apollo/client": "^3.7.0",
46
+ "@instabug/danger-plugin-coverage": "Instabug/danger-plugin-coverage",
47
+ "@react-native-community/eslint-config": "^3.1.0",
48
+ "@react-navigation/native": "^6.1.7",
49
+ "@rollup/plugin-commonjs": "^25.0.3",
50
+ "@rollup/plugin-json": "^6.0.0",
51
+ "@rollup/plugin-node-resolve": "^15.0.1",
52
+ "@rollup/plugin-typescript": "^11.0.0",
53
+ "@trivago/prettier-plugin-sort-imports": "^4.2.0",
54
+ "@types/jest": "^29.5.3",
55
+ "@types/minimatch": "3.0.4",
56
+ "@types/node": "^20.4.8",
57
+ "@types/react-native": "^0.72.2",
58
+ "axios": "1.11.0",
59
+ "babel-core": "7.0.0-bridge.0",
60
+ "babel-jest": "^29.6.2",
61
+ "commander": "^11.0.0",
62
+ "danger": "^11.2.5",
63
+ "eslint": "^8.24.0",
64
+ "eslint-plugin-jsdoc": "^48.1.0",
65
+ "eslint-plugin-prettier": "^5.0.0",
66
+ "esprima": "^4.0.1",
67
+ "expo": "^50.0.0",
68
+ "form-data": "^4.0.0",
69
+ "jest": "^29.6.2",
70
+ "metro-react-native-babel-preset": "0.77.0",
71
+ "nock": "^13.2.9",
72
+ "pod-install": "^0.1.38",
73
+ "prettier": "^3.0.1",
74
+ "react": "^18.2.0",
75
+ "react-native": "^0.72.3",
76
+ "react-native-navigation": "7.36.0",
77
+ "react-navigation": "^4.4.4",
78
+ "rollup": "^3.27.2",
79
+ "rollup-plugin-cleanup": "^3.2.1",
80
+ "rollup-plugin-copy": "^3.5.0",
81
+ "rollup-plugin-preserve-shebang": "^1.0.1",
82
+ "ts-jest": "^29.1.1",
83
+ "typescript": "^4.8.4",
84
+ "wait-for-expect": "^3.0.2",
85
+ "xhr2": "^0.2.1"
86
+ },
87
+ "peerDependenciesMeta": {
88
+ "expo": {
89
+ "optional": true
90
+ }
91
+ }
92
+ }