react-native-inapp-inspector 2.3.14 → 2.3.15

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 (65) hide show
  1. package/dist/commonjs/components/AnimatedEntrance.js +3 -3
  2. package/dist/commonjs/components/ConsoleLogCard.js +174 -100
  3. package/dist/commonjs/components/Inspector/ConsoleTab.js +25 -16
  4. package/dist/commonjs/components/Inspector/CrashTab.js +19 -5
  5. package/dist/commonjs/components/Inspector/DeviceInfoTab.js +198 -98
  6. package/dist/commonjs/components/Inspector/InspectorHeader.js +2 -2
  7. package/dist/commonjs/components/Inspector/MainScreen.js +56 -56
  8. package/dist/commonjs/components/Inspector/NetworkTab.js +1 -335
  9. package/dist/commonjs/components/Inspector/PerformanceTab.js +32 -6
  10. package/dist/commonjs/components/Inspector/ReduxTab.js +3 -1
  11. package/dist/commonjs/components/Inspector/StorageTab.js +23 -5
  12. package/dist/commonjs/components/JsonViewer.js +14 -2
  13. package/dist/commonjs/components/LogCard.js +428 -227
  14. package/dist/commonjs/constants/version.d.ts +1 -1
  15. package/dist/commonjs/constants/version.js +1 -1
  16. package/dist/commonjs/customHooks/analyticsLogger.js +1 -1
  17. package/dist/commonjs/customHooks/consoleLogger.js +34 -2
  18. package/dist/commonjs/customHooks/crashHandler.js +1 -1
  19. package/dist/commonjs/customHooks/networkLogger.js +184 -26
  20. package/dist/commonjs/helpers/searchQueryParser.d.ts +1 -1
  21. package/dist/commonjs/helpers/searchQueryParser.js +37 -291
  22. package/dist/commonjs/index.js +141 -27
  23. package/dist/esm/components/AnimatedEntrance.js +3 -3
  24. package/dist/esm/components/ConsoleLogCard.js +141 -100
  25. package/dist/esm/components/Inspector/ConsoleTab.js +25 -16
  26. package/dist/esm/components/Inspector/CrashTab.js +19 -5
  27. package/dist/esm/components/Inspector/DeviceInfoTab.js +198 -98
  28. package/dist/esm/components/Inspector/InspectorHeader.js +3 -3
  29. package/dist/esm/components/Inspector/MainScreen.js +56 -56
  30. package/dist/esm/components/Inspector/NetworkTab.js +2 -336
  31. package/dist/esm/components/Inspector/PerformanceTab.js +32 -6
  32. package/dist/esm/components/Inspector/ReduxTab.js +3 -1
  33. package/dist/esm/components/Inspector/StorageTab.js +23 -5
  34. package/dist/esm/components/JsonViewer.js +14 -2
  35. package/dist/esm/components/LogCard.js +422 -221
  36. package/dist/esm/constants/version.d.ts +1 -1
  37. package/dist/esm/constants/version.js +1 -1
  38. package/dist/esm/customHooks/analyticsLogger.js +1 -1
  39. package/dist/esm/customHooks/consoleLogger.js +34 -2
  40. package/dist/esm/customHooks/crashHandler.js +1 -1
  41. package/dist/esm/customHooks/networkLogger.js +184 -26
  42. package/dist/esm/helpers/searchQueryParser.d.ts +1 -1
  43. package/dist/esm/helpers/searchQueryParser.js +37 -291
  44. package/dist/esm/index.js +141 -27
  45. package/package.json +1 -1
  46. package/src/components/AnimatedEntrance.tsx +3 -3
  47. package/src/components/ConsoleLogCard.tsx +154 -103
  48. package/src/components/Inspector/ConsoleTab.tsx +27 -18
  49. package/src/components/Inspector/CrashTab.tsx +19 -5
  50. package/src/components/Inspector/DeviceInfoTab.tsx +224 -102
  51. package/src/components/Inspector/InspectorHeader.tsx +5 -3
  52. package/src/components/Inspector/MainScreen.tsx +2 -3
  53. package/src/components/Inspector/NetworkTab.tsx +1 -402
  54. package/src/components/Inspector/PerformanceTab.tsx +36 -7
  55. package/src/components/Inspector/ReduxTab.tsx +9 -1
  56. package/src/components/Inspector/StorageTab.tsx +27 -7
  57. package/src/components/JsonViewer.tsx +15 -2
  58. package/src/components/LogCard.tsx +528 -339
  59. package/src/constants/version.ts +1 -1
  60. package/src/customHooks/analyticsLogger.ts +1 -1
  61. package/src/customHooks/consoleLogger.ts +36 -3
  62. package/src/customHooks/crashHandler.ts +1 -1
  63. package/src/customHooks/networkLogger.ts +214 -26
  64. package/src/helpers/searchQueryParser.ts +40 -285
  65. package/src/index.tsx +332 -211
@@ -7,320 +7,75 @@ export interface SearchQueryOptions {
7
7
  }
8
8
 
9
9
  /**
10
- * Parses query strings like `method:POST is:error slow:>1s status:200 auth`
11
- * and checks whether a given NetworkLog matches all tokens against the specified scope.
10
+ * Universal substring search for NetworkLog.
11
+ * Checks whether a given NetworkLog matches all query keywords across all log fields.
12
12
  */
13
13
  export function matchNetworkLogQuery(
14
14
  log: NetworkLog,
15
15
  searchQuery: string,
16
16
  routePath?: string,
17
- options?: SearchQueryOptions,
17
+ _options?: SearchQueryOptions,
18
18
  ): boolean {
19
19
  if (!searchQuery || searchQuery.trim().length === 0) return true;
20
20
 
21
- // Split tokens by spaces or commas while respecting quotes
22
- const rawTokens =
23
- searchQuery.trim().match(/(?:[^\s,"']+|"[^"]*"|'[^']*')+/g) || [];
24
-
21
+ const rawTokens = searchQuery.trim().toLowerCase().split(/\s+/).filter(Boolean);
25
22
  if (rawTokens.length === 0) return true;
26
23
 
27
- const isCaseSensitive = Boolean(options?.isCaseSensitive);
28
- const isRegex = Boolean(options?.isRegex);
29
- const scope = options?.scope || 'all';
30
-
31
- const methodRaw = log.method || '';
32
- const urlRaw = log.url || '';
24
+ const methodRaw = (log.method || '').toLowerCase();
25
+ const urlRaw = (log.url || '').toLowerCase();
26
+ const statusStr = log.status != null ? String(log.status).toLowerCase() : 'pending';
33
27
  const statusNum =
34
28
  typeof log.status === 'number'
35
29
  ? log.status
36
30
  : log.status != null
37
31
  ? parseInt(String(log.status), 10)
38
32
  : null;
39
- const statusStr = log.status != null ? String(log.status) : 'pending';
40
- const durationNum = log.duration || 0;
41
- const clientRaw = log.client || '';
42
- const callerRaw = log.caller || '';
33
+ const clientRaw = (log.client || '').toLowerCase();
34
+ const callerRaw = (log.caller || '').toLowerCase();
35
+ const pathRaw = (routePath || (log as any)?.routeInfo?.path || '').toLowerCase();
36
+
43
37
  const reqRaw =
44
38
  typeof log.request === 'string'
45
- ? log.request
39
+ ? log.request.toLowerCase()
46
40
  : log.request != null
47
- ? JSON.stringify(log.request)
41
+ ? JSON.stringify(log.request).toLowerCase()
48
42
  : '';
49
43
  const resRaw =
50
44
  typeof log.response === 'string'
51
- ? log.response
45
+ ? log.response.toLowerCase()
52
46
  : log.response != null
53
- ? JSON.stringify(log.response)
47
+ ? JSON.stringify(log.response).toLowerCase()
54
48
  : '';
55
49
  const reqHeadersRaw = log.requestHeaders
56
- ? JSON.stringify(log.requestHeaders)
50
+ ? JSON.stringify(log.requestHeaders).toLowerCase()
57
51
  : '';
58
52
  const resHeadersRaw = log.responseHeaders
59
- ? JSON.stringify(log.responseHeaders)
53
+ ? JSON.stringify(log.responseHeaders).toLowerCase()
60
54
  : '';
61
- const pathRaw = routePath || (log as any)?.routeInfo?.path || '';
62
-
63
- // Construct search corpus based on active scope
64
- const getScopedCorpus = (caseSens: boolean): string => {
65
- let parts: string[] = [];
66
- if (scope === 'url') {
67
- parts = [methodRaw, urlRaw, pathRaw, callerRaw];
68
- } else if (scope === 'reqBody') {
69
- parts = [reqRaw];
70
- } else if (scope === 'resBody') {
71
- parts = [resRaw];
72
- } else if (scope === 'headers') {
73
- parts = [reqHeadersRaw, resHeadersRaw];
74
- } else {
75
- parts = [
76
- methodRaw,
77
- urlRaw,
78
- statusStr,
79
- pathRaw,
80
- callerRaw,
81
- clientRaw,
82
- reqRaw,
83
- resRaw,
84
- reqHeadersRaw,
85
- resHeadersRaw,
86
- ];
87
- }
88
- const combined = parts.join(' ');
89
- return caseSens ? combined : combined.toLowerCase();
90
- };
91
-
92
- const targetCorpus = getScopedCorpus(isCaseSensitive);
93
-
94
- const methodStr = methodRaw.toLowerCase();
95
- const urlStr = urlRaw.toLowerCase();
96
- const clientStr = clientRaw.toLowerCase();
97
- const callerStr = callerRaw.toLowerCase();
98
- const reqStr = reqRaw.toLowerCase();
99
- const resStr = resRaw.toLowerCase();
100
- const reqHeadersStr = reqHeadersRaw.toLowerCase();
101
- const resHeadersStr = resHeadersRaw.toLowerCase();
102
- const pathStr = pathRaw.toLowerCase();
103
-
104
- for (const rawToken of rawTokens) {
105
- const token = rawToken.replace(/^["']|["']$/g, '').trim();
106
- if (!token) continue;
107
-
108
- const lowerToken = token.toLowerCase();
109
-
110
- // 1. method:<VAL> or m:<VAL>
111
- if (lowerToken.startsWith('method:') || lowerToken.startsWith('m:')) {
112
- const targetMethod = lowerToken.replace(/^(method:|m:)/, '').trim();
113
- if (targetMethod.startsWith('!')) {
114
- if (methodStr === targetMethod.slice(1)) return false;
115
- } else {
116
- if (methodStr !== targetMethod) return false;
117
- }
118
- continue;
119
- }
120
-
121
- // 2. status:<VAL> or s:<VAL>
122
- if (lowerToken.startsWith('status:') || lowerToken.startsWith('s:')) {
123
- const val = lowerToken.replace(/^(status:|s:)/, '').trim();
124
- if (val === 'pending' || val === 'loading') {
125
- if (log.status != null) return false;
126
- } else if (val.startsWith('>=')) {
127
- const threshold = parseInt(val.slice(2), 10);
128
- if (isNaN(threshold) || statusNum === null || statusNum < threshold) return false;
129
- } else if (val.startsWith('>')) {
130
- const threshold = parseInt(val.slice(1), 10);
131
- if (isNaN(threshold) || statusNum === null || statusNum <= threshold) return false;
132
- } else if (val.startsWith('<=')) {
133
- const threshold = parseInt(val.slice(2), 10);
134
- if (isNaN(threshold) || statusNum === null || statusNum > threshold) return false;
135
- } else if (val.startsWith('<')) {
136
- const threshold = parseInt(val.slice(1), 10);
137
- if (isNaN(threshold) || statusNum === null || statusNum >= threshold) return false;
138
- } else if (val.endsWith('xx') || val.endsWith('x')) {
139
- const prefix = val.replace(/x/g, '');
140
- if (!statusStr.startsWith(prefix)) return false;
141
- } else {
142
- const targetCode = parseInt(val, 10);
143
- if (!isNaN(targetCode)) {
144
- if (statusNum !== targetCode) return false;
145
- } else if (!statusStr.includes(val)) {
146
- return false;
147
- }
148
- }
149
- continue;
150
- }
151
-
152
- // 3. is:<FLAG>
153
- if (lowerToken.startsWith('is:')) {
154
- const flag = lowerToken.slice(3).trim();
155
- if (
156
- flag === 'error' ||
157
- flag === 'failed' ||
158
- flag === 'err' ||
159
- flag === 'fail'
160
- ) {
161
- const isErr =
162
- log.status === 0 || (statusNum !== null && statusNum >= 400);
163
- if (!isErr) return false;
164
- } else if (flag === 'success' || flag === 'ok' || flag === '2xx') {
165
- const isSuccess = statusNum !== null && statusNum >= 200 && statusNum < 300;
166
- if (!isSuccess) return false;
167
- } else if (flag === 'pending' || flag === 'loading') {
168
- if (log.status != null) return false;
169
- } else if (flag === 'slow') {
170
- if (durationNum < 1000) return false;
171
- } else if (flag === 'fast') {
172
- if (durationNum >= 200) return false;
173
- } else if (flag === 'graphql' || flag === 'gql') {
174
- const isGql =
175
- urlStr.includes('graphql') ||
176
- clientStr === 'graphql' ||
177
- clientStr === 'apollo';
178
- if (!isGql) return false;
179
- } else if (flag === 'https') {
180
- if (!urlStr.startsWith('https')) return false;
181
- } else if (flag === 'http') {
182
- if (urlStr.startsWith('https') || !urlStr.startsWith('http'))
183
- return false;
184
- } else if (flag === 'json') {
185
- const isJson =
186
- reqHeadersStr.includes('application/json') ||
187
- resHeadersStr.includes('application/json') ||
188
- urlStr.includes('.json');
189
- if (!isJson) return false;
190
- } else if (flag === 'image') {
191
- const isImg =
192
- resHeadersStr.includes('image/') ||
193
- /\.(png|jpe?g|gif|webp|svg)/i.test(urlStr);
194
- if (!isImg) return false;
195
- }
196
- continue;
197
- }
198
-
199
- // 4. slow:<DURATION> or dur:<DURATION> or duration:<DURATION>
200
- if (
201
- lowerToken.startsWith('slow:') ||
202
- lowerToken.startsWith('dur:') ||
203
- lowerToken.startsWith('duration:')
204
- ) {
205
- const val = lowerToken.replace(/^(slow:|dur:|duration:)/, '').trim();
206
- let thresholdMs = 0;
207
- let isGreater = true;
208
55
 
209
- let cleanVal = val;
210
- if (val.startsWith('>=')) {
211
- isGreater = true;
212
- cleanVal = val.slice(2);
213
- } else if (val.startsWith('>')) {
214
- isGreater = true;
215
- cleanVal = val.slice(1);
216
- } else if (val.startsWith('<=')) {
217
- isGreater = false;
218
- cleanVal = val.slice(2);
219
- } else if (val.startsWith('<')) {
220
- isGreater = false;
221
- cleanVal = val.slice(1);
222
- }
223
-
224
- if (cleanVal.endsWith('s') && !cleanVal.endsWith('ms')) {
225
- thresholdMs = parseFloat(cleanVal.slice(0, -1)) * 1000;
226
- } else if (cleanVal.endsWith('ms')) {
227
- thresholdMs = parseFloat(cleanVal.slice(0, -2));
228
- } else {
229
- thresholdMs = parseFloat(cleanVal);
230
- }
231
-
232
- if (!isNaN(thresholdMs)) {
233
- if (isGreater) {
234
- if (durationNum < thresholdMs) return false;
235
- } else {
236
- if (durationNum > thresholdMs) return false;
237
- }
238
- }
239
- continue;
240
- }
241
-
242
- // 5. client:<CLIENT> or c:<CLIENT>
243
- if (lowerToken.startsWith('client:') || lowerToken.startsWith('c:')) {
244
- const targetClient = lowerToken.replace(/^(client:|c:)/, '').trim();
245
- if (!clientStr.includes(targetClient)) return false;
246
- continue;
247
- }
248
-
249
- // 6. domain:<DOMAIN> or d:<DOMAIN>
250
- if (lowerToken.startsWith('domain:') || lowerToken.startsWith('d:')) {
251
- const targetDomain = lowerToken.replace(/^(domain:|d:)/, '').trim();
252
- if (!urlStr.includes(targetDomain)) return false;
253
- continue;
254
- }
255
-
256
- // 7. path:<PATH> or p:<PATH> or page:<PAGE>
257
- if (
258
- lowerToken.startsWith('path:') ||
259
- lowerToken.startsWith('p:') ||
260
- lowerToken.startsWith('page:')
261
- ) {
262
- const targetPath = lowerToken
263
- .replace(/^(path:|p:|page:)/, '')
264
- .trim();
265
- if (
266
- !urlStr.includes(targetPath) &&
267
- !pathStr.includes(targetPath) &&
268
- !callerStr.includes(targetPath)
269
- ) {
270
- return false;
271
- }
272
- continue;
56
+ const corpus = [
57
+ methodRaw,
58
+ urlRaw,
59
+ statusStr,
60
+ pathRaw,
61
+ callerRaw,
62
+ clientRaw,
63
+ reqRaw,
64
+ resRaw,
65
+ reqHeadersRaw,
66
+ resHeadersRaw,
67
+ ].join(' ');
68
+
69
+ return rawTokens.every(token => {
70
+ if (corpus.includes(token)) return true;
71
+ // Error status keywords
72
+ if (token === 'error' || token === 'failed' || token === 'err' || token === 'fail') {
73
+ return log.status === 0 || (statusNum !== null && statusNum >= 400);
273
74
  }
274
-
275
- // 8. req:<TERM> or body:<TERM>
276
- if (lowerToken.startsWith('req:') || lowerToken.startsWith('body:')) {
277
- const target = lowerToken.replace(/^(req:|body:)/, '').trim();
278
- if (!reqStr.includes(target)) return false;
279
- continue;
280
- }
281
-
282
- // 9. res:<TERM>
283
- if (lowerToken.startsWith('res:')) {
284
- const target = lowerToken.slice(4).trim();
285
- if (!resStr.includes(target)) return false;
286
- continue;
287
- }
288
-
289
- // 10. header:<TERM> or h:<TERM>
290
- if (lowerToken.startsWith('header:') || lowerToken.startsWith('h:')) {
291
- const target = lowerToken.replace(/^(header:|h:)/, '').trim();
292
- if (!reqHeadersStr.includes(target) && !resHeadersStr.includes(target)) {
293
- return false;
294
- }
295
- continue;
296
- }
297
-
298
- // 11. Generic Match (handles Regex, Case-sensitivity, and Scoped corpus)
299
- if (isRegex) {
300
- try {
301
- const re = new RegExp(token, isCaseSensitive ? '' : 'i');
302
- if (!re.test(targetCorpus)) return false;
303
- } catch {
304
- const queryTerm = isCaseSensitive ? token : lowerToken;
305
- if (!targetCorpus.includes(queryTerm)) return false;
306
- }
307
- } else {
308
- const queryTerm = isCaseSensitive ? token : lowerToken;
309
- if (!targetCorpus.includes(queryTerm)) {
310
- // Special case: if user typed "error" / "failed", check error status
311
- if (
312
- queryTerm === 'error' ||
313
- queryTerm === 'failed' ||
314
- queryTerm === 'fail'
315
- ) {
316
- const isErr =
317
- log.status === 0 || (statusNum !== null && statusNum >= 400);
318
- if (isErr) continue;
319
- }
320
- return false;
321
- }
75
+ // Success status keywords
76
+ if (token === 'success' || token === 'ok' || token === '2xx') {
77
+ return statusNum !== null && statusNum >= 200 && statusNum < 300;
322
78
  }
323
- }
324
-
325
- return true;
79
+ return false;
80
+ });
326
81
  }