react-native-ai-debugger 1.6.16 → 1.8.1
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/README.md +8 -1
- package/build/__tests__/unit/exec.test.d.ts +2 -0
- package/build/__tests__/unit/exec.test.d.ts.map +1 -0
- package/build/__tests__/unit/exec.test.js +54 -0
- package/build/__tests__/unit/exec.test.js.map +1 -0
- package/build/__tests__/unit/focusedInput.test.d.ts +2 -0
- package/build/__tests__/unit/focusedInput.test.d.ts.map +1 -0
- package/build/__tests__/unit/focusedInput.test.js +58 -0
- package/build/__tests__/unit/focusedInput.test.js.map +1 -0
- package/build/__tests__/unit/focusedInputTools.test.d.ts +2 -0
- package/build/__tests__/unit/focusedInputTools.test.d.ts.map +1 -0
- package/build/__tests__/unit/focusedInputTools.test.js +79 -0
- package/build/__tests__/unit/focusedInputTools.test.js.map +1 -0
- package/build/__tests__/unit/tap.test.js +46 -0
- package/build/__tests__/unit/tap.test.js.map +1 -1
- package/build/core/android.d.ts +3 -3
- package/build/core/android.d.ts.map +1 -1
- package/build/core/android.js +21 -14
- package/build/core/android.js.map +1 -1
- package/build/core/appDetection.d.ts +7 -0
- package/build/core/appDetection.d.ts.map +1 -1
- package/build/core/appDetection.js +38 -17
- package/build/core/appDetection.js.map +1 -1
- package/build/core/componentSearch.d.ts +38 -0
- package/build/core/componentSearch.d.ts.map +1 -0
- package/build/core/componentSearch.js +419 -0
- package/build/core/componentSearch.js.map +1 -0
- package/build/core/componentTree.d.ts +12 -0
- package/build/core/componentTree.d.ts.map +1 -0
- package/build/core/componentTree.js +275 -0
- package/build/core/componentTree.js.map +1 -0
- package/build/core/connection.d.ts +1 -0
- package/build/core/connection.d.ts.map +1 -1
- package/build/core/connection.js +99 -89
- package/build/core/connection.js.map +1 -1
- package/build/core/debugGlobals.d.ts +5 -0
- package/build/core/debugGlobals.d.ts.map +1 -0
- package/build/core/debugGlobals.js +300 -0
- package/build/core/debugGlobals.js.map +1 -0
- package/build/core/errors.d.ts +14 -0
- package/build/core/errors.d.ts.map +1 -0
- package/build/core/errors.js +17 -0
- package/build/core/errors.js.map +1 -0
- package/build/core/exec.d.ts +22 -0
- package/build/core/exec.d.ts.map +1 -0
- package/build/core/exec.js +54 -0
- package/build/core/exec.js.map +1 -0
- package/build/core/executor.d.ts +7 -204
- package/build/core/executor.d.ts.map +1 -1
- package/build/core/executor.js +10 -4103
- package/build/core/executor.js.map +1 -1
- package/build/core/focusedInput.d.ts +27 -0
- package/build/core/focusedInput.d.ts.map +1 -0
- package/build/core/focusedInput.js +110 -0
- package/build/core/focusedInput.js.map +1 -0
- package/build/core/focusedInputTools.d.ts +21 -0
- package/build/core/focusedInputTools.d.ts.map +1 -0
- package/build/core/focusedInputTools.js +51 -0
- package/build/core/focusedInputTools.js.map +1 -0
- package/build/core/guides.d.ts.map +1 -1
- package/build/core/guides.js +15 -2
- package/build/core/guides.js.map +1 -1
- package/build/core/index.d.ts +4 -3
- package/build/core/index.d.ts.map +1 -1
- package/build/core/index.js +4 -3
- package/build/core/index.js.map +1 -1
- package/build/core/inspector.d.ts +50 -0
- package/build/core/inspector.d.ts.map +1 -0
- package/build/core/inspector.js +604 -0
- package/build/core/inspector.js.map +1 -0
- package/build/core/ios.d.ts +8 -0
- package/build/core/ios.d.ts.map +1 -1
- package/build/core/ios.js +142 -2
- package/build/core/ios.js.map +1 -1
- package/build/core/jsExecute.d.ts +27 -0
- package/build/core/jsExecute.d.ts.map +1 -0
- package/build/core/jsExecute.js +453 -0
- package/build/core/jsExecute.js.map +1 -0
- package/build/core/ocr.d.ts +13 -0
- package/build/core/ocr.d.ts.map +1 -1
- package/build/core/ocr.js +37 -15
- package/build/core/ocr.js.map +1 -1
- package/build/core/posthog.d.ts.map +1 -1
- package/build/core/posthog.js +7 -1
- package/build/core/posthog.js.map +1 -1
- package/build/core/pressables.d.ts +44 -0
- package/build/core/pressables.d.ts.map +1 -0
- package/build/core/pressables.js +1480 -0
- package/build/core/pressables.js.map +1 -0
- package/build/core/register.d.ts +8 -0
- package/build/core/register.d.ts.map +1 -0
- package/build/core/register.js +216 -0
- package/build/core/register.js.map +1 -0
- package/build/core/screenLayout.d.ts +52 -0
- package/build/core/screenLayout.d.ts.map +1 -0
- package/build/core/screenLayout.js +828 -0
- package/build/core/screenLayout.js.map +1 -0
- package/build/core/toolHelpers.d.ts +24 -0
- package/build/core/toolHelpers.d.ts.map +1 -0
- package/build/core/toolHelpers.js +118 -0
- package/build/core/toolHelpers.js.map +1 -0
- package/build/core/types.d.ts +11 -6
- package/build/core/types.d.ts.map +1 -1
- package/build/index.d.ts +2 -4
- package/build/index.d.ts.map +1 -1
- package/build/index.js +37 -4313
- package/build/index.js.map +1 -1
- package/build/pro/tap.d.ts +51 -5
- package/build/pro/tap.d.ts.map +1 -1
- package/build/pro/tap.js +457 -54
- package/build/pro/tap.js.map +1 -1
- package/build/tools/accountTools.d.ts +2 -0
- package/build/tools/accountTools.d.ts.map +1 -1
- package/build/tools/accountTools.js +5 -0
- package/build/tools/accountTools.js.map +1 -1
- package/build/tools/bundleTools.d.ts +3 -0
- package/build/tools/bundleTools.d.ts.map +1 -0
- package/build/tools/bundleTools.js +368 -0
- package/build/tools/bundleTools.js.map +1 -0
- package/build/tools/componentTools.d.ts +3 -0
- package/build/tools/componentTools.d.ts.map +1 -0
- package/build/tools/componentTools.js +639 -0
- package/build/tools/componentTools.js.map +1 -0
- package/build/tools/connectionTools.d.ts +3 -0
- package/build/tools/connectionTools.d.ts.map +1 -0
- package/build/tools/connectionTools.js +564 -0
- package/build/tools/connectionTools.js.map +1 -0
- package/build/tools/deviceTools.d.ts +3 -0
- package/build/tools/deviceTools.d.ts.map +1 -0
- package/build/tools/deviceTools.js +296 -0
- package/build/tools/deviceTools.js.map +1 -0
- package/build/tools/executionTools.d.ts +3 -0
- package/build/tools/executionTools.d.ts.map +1 -0
- package/build/tools/executionTools.js +173 -0
- package/build/tools/executionTools.js.map +1 -0
- package/build/tools/interactionTools.d.ts +3 -0
- package/build/tools/interactionTools.d.ts.map +1 -0
- package/build/tools/interactionTools.js +414 -0
- package/build/tools/interactionTools.js.map +1 -0
- package/build/tools/logTools.d.ts +3 -0
- package/build/tools/logTools.d.ts.map +1 -0
- package/build/tools/logTools.js +371 -0
- package/build/tools/logTools.js.map +1 -0
- package/build/tools/metaTools.d.ts +7 -0
- package/build/tools/metaTools.d.ts.map +1 -0
- package/build/tools/metaTools.js +205 -0
- package/build/tools/metaTools.js.map +1 -0
- package/build/tools/networkTools.d.ts +3 -0
- package/build/tools/networkTools.d.ts.map +1 -0
- package/build/tools/networkTools.js +478 -0
- package/build/tools/networkTools.js.map +1 -0
- package/build/tools/reduxTools.d.ts +3 -0
- package/build/tools/reduxTools.d.ts.map +1 -0
- package/build/tools/reduxTools.js +83 -0
- package/build/tools/reduxTools.js.map +1 -0
- package/build/tools/screenshotTools.d.ts +3 -0
- package/build/tools/screenshotTools.d.ts.map +1 -0
- package/build/tools/screenshotTools.js +606 -0
- package/build/tools/screenshotTools.js.map +1 -0
- package/package.json +1 -1
|
@@ -0,0 +1,419 @@
|
|
|
1
|
+
import { executeInApp } from "./jsExecute.js";
|
|
2
|
+
import { formatSummaryToTonl } from "./screenLayout.js";
|
|
3
|
+
function formatFoundComponentsToTonl(components) {
|
|
4
|
+
const lines = ["#found{component,path,depth,key,layout}"];
|
|
5
|
+
for (const c of components) {
|
|
6
|
+
const layout = c.layout
|
|
7
|
+
? Object.entries(c.layout)
|
|
8
|
+
.map(([k, v]) => `${k}:${v}`)
|
|
9
|
+
.join(";")
|
|
10
|
+
: "";
|
|
11
|
+
lines.push(`${c.component}|${c.path}|${c.depth}|${c.key || ""}|${layout}`);
|
|
12
|
+
}
|
|
13
|
+
return lines.join("\n");
|
|
14
|
+
}
|
|
15
|
+
/**
|
|
16
|
+
* Get the React component tree from the running app.
|
|
17
|
+
* This traverses the fiber tree to extract component hierarchy with names.
|
|
18
|
+
*/
|
|
19
|
+
/**
|
|
20
|
+
* Get layout data for visible components on the current screen.
|
|
21
|
+
* Uses measureInWindow to get actual screen positions and filters
|
|
22
|
+
* to only components within the viewport.
|
|
23
|
+
*
|
|
24
|
+
* Two-step approach (same as inspectAtPoint):
|
|
25
|
+
* Step 1: Walk fiber tree, dispatch measureInWindow on host components
|
|
26
|
+
* Step 2: After 300ms, read measurements, filter by viewport, build results
|
|
27
|
+
*/
|
|
28
|
+
/**
|
|
29
|
+
* Inspect a specific component by name, returning its props, state, and layout.
|
|
30
|
+
*/
|
|
31
|
+
export async function inspectComponent(componentName, options = {}) {
|
|
32
|
+
const { index = 0, includeState = true, includeChildren = false, childrenDepth = 1, shortPath = true, simplifyHooks = true, device } = options;
|
|
33
|
+
const escapedName = componentName.replace(/'/g, "\\'");
|
|
34
|
+
const expression = `
|
|
35
|
+
(function() {
|
|
36
|
+
const hook = globalThis.__REACT_DEVTOOLS_GLOBAL_HOOK__;
|
|
37
|
+
if (!hook) return { error: 'React DevTools hook not found.' };
|
|
38
|
+
|
|
39
|
+
let roots = [];
|
|
40
|
+
if (hook.getFiberRoots) {
|
|
41
|
+
roots = [...(hook.getFiberRoots(1) || [])];
|
|
42
|
+
}
|
|
43
|
+
if (roots.length === 0 && hook.renderers) {
|
|
44
|
+
for (const [id] of hook.renderers) {
|
|
45
|
+
const r = hook.getFiberRoots ? [...(hook.getFiberRoots(id) || [])] : [];
|
|
46
|
+
if (r.length > 0) { roots = r; break; }
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
if (roots.length === 0) return { error: 'No fiber roots found.' };
|
|
50
|
+
|
|
51
|
+
const targetName = '${escapedName}';
|
|
52
|
+
const targetIndex = ${index};
|
|
53
|
+
const includeState = ${includeState};
|
|
54
|
+
const includeChildren = ${includeChildren};
|
|
55
|
+
const childrenDepth = ${childrenDepth};
|
|
56
|
+
const shortPath = ${shortPath};
|
|
57
|
+
const simplifyHooks = ${simplifyHooks};
|
|
58
|
+
const pathSegments = 3;
|
|
59
|
+
|
|
60
|
+
function getComponentName(fiber) {
|
|
61
|
+
if (!fiber || !fiber.type) return null;
|
|
62
|
+
if (typeof fiber.type === 'string') return fiber.type;
|
|
63
|
+
return fiber.type.displayName || fiber.type.name || null;
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
function formatPath(pathArray) {
|
|
67
|
+
if (!shortPath || pathArray.length <= pathSegments) {
|
|
68
|
+
return pathArray.join(' > ');
|
|
69
|
+
}
|
|
70
|
+
return '... > ' + pathArray.slice(-pathSegments).join(' > ');
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
function extractStyles(style) {
|
|
74
|
+
try {
|
|
75
|
+
if (!style) return null;
|
|
76
|
+
const merged = Array.isArray(style)
|
|
77
|
+
? Object.assign({}, ...style.filter(Boolean).map(s => {
|
|
78
|
+
try { return typeof s === 'object' ? s : {}; }
|
|
79
|
+
catch { return {}; }
|
|
80
|
+
}))
|
|
81
|
+
: (typeof style === 'object' ? style : {});
|
|
82
|
+
return Object.keys(merged).length > 0 ? merged : null;
|
|
83
|
+
} catch { return { _note: '[Contains animated styles]' }; }
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
function serializeValue(val, depth = 0) {
|
|
87
|
+
if (depth > 3) return '[Max depth]';
|
|
88
|
+
if (val === null) return null;
|
|
89
|
+
if (val === undefined) return undefined;
|
|
90
|
+
if (typeof val === 'function') return '[Function]';
|
|
91
|
+
if (typeof val !== 'object') return val;
|
|
92
|
+
if (Array.isArray(val)) {
|
|
93
|
+
if (val.length > 10) return '[Array(' + val.length + ')]';
|
|
94
|
+
return val.map(v => serializeValue(v, depth + 1));
|
|
95
|
+
}
|
|
96
|
+
// Object
|
|
97
|
+
const keys = Object.keys(val);
|
|
98
|
+
if (keys.length > 20) return '[Object(' + keys.length + ' keys)]';
|
|
99
|
+
const result = {};
|
|
100
|
+
for (const k of keys) {
|
|
101
|
+
try {
|
|
102
|
+
result[k] = serializeValue(val[k], depth + 1);
|
|
103
|
+
} catch {
|
|
104
|
+
result[k] = '[Animated Value]';
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
return result;
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
function getChildTree(fiber, depth) {
|
|
111
|
+
if (!fiber || depth <= 0) return null;
|
|
112
|
+
const children = [];
|
|
113
|
+
let child = fiber?.child;
|
|
114
|
+
while (child && children.length < 30) {
|
|
115
|
+
const name = getComponentName(child);
|
|
116
|
+
if (name) {
|
|
117
|
+
if (depth === 1) {
|
|
118
|
+
// Just names for depth 1
|
|
119
|
+
children.push(name);
|
|
120
|
+
} else {
|
|
121
|
+
// Tree structure for depth > 1
|
|
122
|
+
const nestedChildren = getChildTree(child, depth - 1);
|
|
123
|
+
children.push(nestedChildren ? { component: name, children: nestedChildren } : name);
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
child = child.sibling;
|
|
127
|
+
}
|
|
128
|
+
return children.length > 0 ? children : null;
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
const matches = [];
|
|
132
|
+
|
|
133
|
+
function findComponent(fiber, path) {
|
|
134
|
+
if (!fiber) return;
|
|
135
|
+
|
|
136
|
+
const name = getComponentName(fiber);
|
|
137
|
+
if (name === targetName) {
|
|
138
|
+
matches.push({ fiber, path: [...path, name] });
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
let child = fiber.child;
|
|
142
|
+
while (child) {
|
|
143
|
+
const childName = getComponentName(child);
|
|
144
|
+
findComponent(child, childName ? [...path, childName] : path);
|
|
145
|
+
child = child.sibling;
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
findComponent(roots[0].current, []);
|
|
150
|
+
|
|
151
|
+
if (matches.length === 0) {
|
|
152
|
+
return { error: 'Component "' + targetName + '" not found in the component tree.' };
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
if (targetIndex >= matches.length) {
|
|
156
|
+
return { error: 'Component "' + targetName + '" found ' + matches.length + ' times, but index ' + targetIndex + ' requested.' };
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
const { fiber, path } = matches[targetIndex];
|
|
160
|
+
|
|
161
|
+
const result = {
|
|
162
|
+
component: targetName,
|
|
163
|
+
path: formatPath(path),
|
|
164
|
+
instancesFound: matches.length,
|
|
165
|
+
instanceIndex: targetIndex
|
|
166
|
+
};
|
|
167
|
+
|
|
168
|
+
// Props (excluding children)
|
|
169
|
+
if (fiber.memoizedProps) {
|
|
170
|
+
const props = {};
|
|
171
|
+
for (const key of Object.keys(fiber.memoizedProps)) {
|
|
172
|
+
if (key === 'children') continue;
|
|
173
|
+
try {
|
|
174
|
+
props[key] = serializeValue(fiber.memoizedProps[key]);
|
|
175
|
+
} catch {
|
|
176
|
+
props[key] = '[Animated Value]';
|
|
177
|
+
}
|
|
178
|
+
}
|
|
179
|
+
result.props = props;
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
// Style separately for clarity
|
|
183
|
+
try {
|
|
184
|
+
if (fiber.memoizedProps?.style) {
|
|
185
|
+
result.style = extractStyles(fiber.memoizedProps.style);
|
|
186
|
+
}
|
|
187
|
+
} catch {
|
|
188
|
+
result.style = { _note: '[Contains animated styles]' };
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
// State (for hooks, this is a linked list)
|
|
192
|
+
if (includeState && fiber.memoizedState) {
|
|
193
|
+
// Simplified hook value serialization
|
|
194
|
+
function serializeHookValue(val, depth = 0) {
|
|
195
|
+
try {
|
|
196
|
+
if (depth > 2) return '[...]';
|
|
197
|
+
if (val === null || val === undefined) return val;
|
|
198
|
+
if (typeof val === 'function') return '[Function]';
|
|
199
|
+
if (typeof val !== 'object') return val;
|
|
200
|
+
// Skip React internal structures (effects, refs with destroy/create)
|
|
201
|
+
if (val.create && val.destroy !== undefined) return '[Effect]';
|
|
202
|
+
if (val.inst && val.deps) return '[Effect]';
|
|
203
|
+
if (val.current !== undefined && Object.keys(val).length === 1) {
|
|
204
|
+
// Ref object - just show current value
|
|
205
|
+
return { current: serializeHookValue(val.current, depth + 1) };
|
|
206
|
+
}
|
|
207
|
+
if (Array.isArray(val)) {
|
|
208
|
+
if (val.length > 5) return '[Array(' + val.length + ')]';
|
|
209
|
+
return val.slice(0, 5).map(v => serializeHookValue(v, depth + 1));
|
|
210
|
+
}
|
|
211
|
+
const keys = Object.keys(val);
|
|
212
|
+
if (keys.length > 10) return '[Object(' + keys.length + ' keys)]';
|
|
213
|
+
const result = {};
|
|
214
|
+
for (const k of keys.slice(0, 10)) {
|
|
215
|
+
try {
|
|
216
|
+
result[k] = serializeHookValue(val[k], depth + 1);
|
|
217
|
+
} catch {
|
|
218
|
+
result[k] = '[Animated Value]';
|
|
219
|
+
}
|
|
220
|
+
}
|
|
221
|
+
return result;
|
|
222
|
+
} catch { return '[Animated Value]'; }
|
|
223
|
+
}
|
|
224
|
+
|
|
225
|
+
// For function components with hooks
|
|
226
|
+
const states = [];
|
|
227
|
+
let state = fiber.memoizedState;
|
|
228
|
+
let hookIndex = 0;
|
|
229
|
+
while (state && hookIndex < 20) {
|
|
230
|
+
if (state.memoizedState !== undefined) {
|
|
231
|
+
const hookVal = simplifyHooks
|
|
232
|
+
? serializeHookValue(state.memoizedState)
|
|
233
|
+
: serializeValue(state.memoizedState);
|
|
234
|
+
// Skip effect hooks in simplified mode
|
|
235
|
+
if (!simplifyHooks || (hookVal !== '[Effect]' && hookVal !== undefined)) {
|
|
236
|
+
states.push({
|
|
237
|
+
hookIndex,
|
|
238
|
+
value: hookVal
|
|
239
|
+
});
|
|
240
|
+
}
|
|
241
|
+
}
|
|
242
|
+
state = state.next;
|
|
243
|
+
hookIndex++;
|
|
244
|
+
}
|
|
245
|
+
if (states.length > 0) result.hooks = states;
|
|
246
|
+
|
|
247
|
+
// For class components, memoizedState is the state object directly
|
|
248
|
+
if (states.length === 0 && typeof fiber.memoizedState === 'object') {
|
|
249
|
+
result.state = serializeValue(fiber.memoizedState);
|
|
250
|
+
}
|
|
251
|
+
}
|
|
252
|
+
|
|
253
|
+
// Children tree (depth controlled by childrenDepth)
|
|
254
|
+
if (includeChildren) {
|
|
255
|
+
result.children = getChildTree(fiber, childrenDepth);
|
|
256
|
+
}
|
|
257
|
+
|
|
258
|
+
return result;
|
|
259
|
+
})()
|
|
260
|
+
`;
|
|
261
|
+
return executeInApp(expression, false, {}, device);
|
|
262
|
+
}
|
|
263
|
+
/**
|
|
264
|
+
* Find all components matching a name pattern and return summary info.
|
|
265
|
+
*/
|
|
266
|
+
export async function findComponents(pattern, options = {}) {
|
|
267
|
+
const { maxResults = 20, includeLayout = false, shortPath = true, summary = false, format = "tonl", device } = options;
|
|
268
|
+
const escapedPattern = pattern.replace(/'/g, "\\'").replace(/\\/g, "\\\\");
|
|
269
|
+
const expression = `
|
|
270
|
+
(function() {
|
|
271
|
+
const hook = globalThis.__REACT_DEVTOOLS_GLOBAL_HOOK__;
|
|
272
|
+
if (!hook) return { error: 'React DevTools hook not found.' };
|
|
273
|
+
|
|
274
|
+
let roots = [];
|
|
275
|
+
if (hook.getFiberRoots) {
|
|
276
|
+
roots = [...(hook.getFiberRoots(1) || [])];
|
|
277
|
+
}
|
|
278
|
+
if (roots.length === 0 && hook.renderers) {
|
|
279
|
+
for (const [id] of hook.renderers) {
|
|
280
|
+
const r = hook.getFiberRoots ? [...(hook.getFiberRoots(id) || [])] : [];
|
|
281
|
+
if (r.length > 0) { roots = r; break; }
|
|
282
|
+
}
|
|
283
|
+
}
|
|
284
|
+
if (roots.length === 0) return { error: 'No fiber roots found.' };
|
|
285
|
+
|
|
286
|
+
const pattern = '${escapedPattern}';
|
|
287
|
+
const regex = new RegExp(pattern, 'i');
|
|
288
|
+
const maxResults = ${maxResults};
|
|
289
|
+
const includeLayout = ${includeLayout};
|
|
290
|
+
const shortPath = ${shortPath};
|
|
291
|
+
const summaryMode = ${summary};
|
|
292
|
+
const pathSegments = 3;
|
|
293
|
+
|
|
294
|
+
function getComponentName(fiber) {
|
|
295
|
+
if (!fiber || !fiber.type) return null;
|
|
296
|
+
if (typeof fiber.type === 'string') return fiber.type;
|
|
297
|
+
return fiber.type.displayName || fiber.type.name || null;
|
|
298
|
+
}
|
|
299
|
+
|
|
300
|
+
function formatPath(pathArray) {
|
|
301
|
+
if (!shortPath || pathArray.length <= pathSegments) {
|
|
302
|
+
return pathArray.join(' > ');
|
|
303
|
+
}
|
|
304
|
+
return '... > ' + pathArray.slice(-pathSegments).join(' > ');
|
|
305
|
+
}
|
|
306
|
+
|
|
307
|
+
function extractLayoutStyles(style) {
|
|
308
|
+
try {
|
|
309
|
+
if (!style) return null;
|
|
310
|
+
const merged = Array.isArray(style)
|
|
311
|
+
? Object.assign({}, ...style.filter(Boolean).map(s => {
|
|
312
|
+
try { return typeof s === 'object' ? s : {}; }
|
|
313
|
+
catch { return {}; }
|
|
314
|
+
}))
|
|
315
|
+
: (typeof style === 'object' ? style : {});
|
|
316
|
+
|
|
317
|
+
const layout = {};
|
|
318
|
+
const keys = ['padding', 'paddingTop', 'paddingBottom', 'paddingLeft', 'paddingRight',
|
|
319
|
+
'paddingHorizontal', 'paddingVertical', 'margin', 'marginTop', 'marginBottom',
|
|
320
|
+
'marginLeft', 'marginRight', 'marginHorizontal', 'marginVertical',
|
|
321
|
+
'width', 'height', 'flex', 'flexDirection', 'justifyContent', 'alignItems'];
|
|
322
|
+
for (const k of keys) {
|
|
323
|
+
if (merged[k] !== undefined) layout[k] = merged[k];
|
|
324
|
+
}
|
|
325
|
+
return Object.keys(layout).length > 0 ? layout : null;
|
|
326
|
+
} catch { return null; }
|
|
327
|
+
}
|
|
328
|
+
|
|
329
|
+
const results = [];
|
|
330
|
+
|
|
331
|
+
function search(fiber, path, depth) {
|
|
332
|
+
if (!fiber || results.length >= maxResults) return;
|
|
333
|
+
|
|
334
|
+
try {
|
|
335
|
+
var name = getComponentName(fiber);
|
|
336
|
+
if (name && regex.test(name)) {
|
|
337
|
+
var entry = {
|
|
338
|
+
component: name,
|
|
339
|
+
path: formatPath(path),
|
|
340
|
+
depth
|
|
341
|
+
};
|
|
342
|
+
|
|
343
|
+
if (fiber.memoizedProps && fiber.memoizedProps.testID) entry.testID = fiber.memoizedProps.testID;
|
|
344
|
+
if (fiber.key) entry.key = fiber.key;
|
|
345
|
+
|
|
346
|
+
if (includeLayout && fiber.memoizedProps && fiber.memoizedProps.style) {
|
|
347
|
+
try {
|
|
348
|
+
var layout = extractLayoutStyles(fiber.memoizedProps.style);
|
|
349
|
+
if (layout) entry.layout = layout;
|
|
350
|
+
} catch(e) {}
|
|
351
|
+
}
|
|
352
|
+
|
|
353
|
+
results.push(entry);
|
|
354
|
+
}
|
|
355
|
+
|
|
356
|
+
var child = fiber.child;
|
|
357
|
+
while (child && results.length < maxResults) {
|
|
358
|
+
var childName = getComponentName(child);
|
|
359
|
+
search(child, childName ? path.concat([childName]) : path, depth + 1);
|
|
360
|
+
child = child.sibling;
|
|
361
|
+
}
|
|
362
|
+
} catch(e) {
|
|
363
|
+
try {
|
|
364
|
+
var child = fiber.child;
|
|
365
|
+
while (child && results.length < maxResults) {
|
|
366
|
+
search(child, path, depth + 1);
|
|
367
|
+
child = child.sibling;
|
|
368
|
+
}
|
|
369
|
+
} catch(e2) {}
|
|
370
|
+
}
|
|
371
|
+
}
|
|
372
|
+
|
|
373
|
+
search(roots[0].current, [], 0);
|
|
374
|
+
|
|
375
|
+
if (summaryMode) {
|
|
376
|
+
const counts = {};
|
|
377
|
+
for (const r of results) {
|
|
378
|
+
counts[r.component] = (counts[r.component] || 0) + 1;
|
|
379
|
+
}
|
|
380
|
+
const sorted = Object.entries(counts)
|
|
381
|
+
.sort((a, b) => b[1] - a[1])
|
|
382
|
+
.map(([name, count]) => ({ component: name, count }));
|
|
383
|
+
return {
|
|
384
|
+
pattern,
|
|
385
|
+
totalMatches: results.length,
|
|
386
|
+
uniqueComponents: sorted.length,
|
|
387
|
+
components: sorted
|
|
388
|
+
};
|
|
389
|
+
}
|
|
390
|
+
|
|
391
|
+
return {
|
|
392
|
+
pattern,
|
|
393
|
+
found: results.length,
|
|
394
|
+
components: results
|
|
395
|
+
};
|
|
396
|
+
})()
|
|
397
|
+
`;
|
|
398
|
+
const result = await executeInApp(expression, false, {}, device);
|
|
399
|
+
if (format === "tonl" && result.success && result.result) {
|
|
400
|
+
try {
|
|
401
|
+
const parsed = JSON.parse(result.result);
|
|
402
|
+
if (parsed.components) {
|
|
403
|
+
if (parsed.totalMatches !== undefined) {
|
|
404
|
+
const tonl = formatSummaryToTonl(parsed.components, parsed.totalMatches);
|
|
405
|
+
return { success: true, result: `pattern: ${parsed.pattern}\n${tonl}` };
|
|
406
|
+
}
|
|
407
|
+
else {
|
|
408
|
+
const tonl = formatFoundComponentsToTonl(parsed.components);
|
|
409
|
+
return { success: true, result: `pattern: ${parsed.pattern}\nfound: ${parsed.found}\n${tonl}` };
|
|
410
|
+
}
|
|
411
|
+
}
|
|
412
|
+
}
|
|
413
|
+
catch {
|
|
414
|
+
// If parsing fails, return original result
|
|
415
|
+
}
|
|
416
|
+
}
|
|
417
|
+
return result;
|
|
418
|
+
}
|
|
419
|
+
//# sourceMappingURL=componentSearch.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"componentSearch.js","sourceRoot":"","sources":["../../src/core/componentSearch.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import type { ExecutionResult } from "./types.js";
|
|
2
|
+
export declare function getComponentTree(options?: {
|
|
3
|
+
maxDepth?: number;
|
|
4
|
+
includeProps?: boolean;
|
|
5
|
+
includeStyles?: boolean;
|
|
6
|
+
hideInternals?: boolean;
|
|
7
|
+
format?: "json" | "tonl";
|
|
8
|
+
structureOnly?: boolean;
|
|
9
|
+
focusedOnly?: boolean;
|
|
10
|
+
device?: string;
|
|
11
|
+
}): Promise<ExecutionResult>;
|
|
12
|
+
//# sourceMappingURL=componentTree.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"componentTree.d.ts","sourceRoot":"","sources":["../../src/core/componentTree.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,YAAY,CAAC;AA4DlD,wBAAsB,gBAAgB,CAClC,OAAO,GAAE;IACL,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,YAAY,CAAC,EAAE,OAAO,CAAC;IACvB,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB,MAAM,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;IACzB,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,MAAM,CAAC,EAAE,MAAM,CAAC;CACd,GACP,OAAO,CAAC,eAAe,CAAC,CAuP1B"}
|