assistsx-js 0.2.1 → 0.2.3

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.
@@ -0,0 +1,4331 @@
1
+ // src/step-flow/outcome.ts
2
+ function flowEvent(name) {
3
+ return { type: "event", name };
4
+ }
5
+ function flowRepeat() {
6
+ return { type: "repeat" };
7
+ }
8
+ function flowEnd() {
9
+ return { type: "end" };
10
+ }
11
+
12
+ // src/step-flow/payload.ts
13
+ function asFlowData(step) {
14
+ return step.data;
15
+ }
16
+ function getFlowPayload(step) {
17
+ const data = asFlowData(step);
18
+ const payload = data.payload;
19
+ if (payload !== null && payload !== void 0 && typeof payload === "object" && !Array.isArray(payload)) {
20
+ return payload;
21
+ }
22
+ return {};
23
+ }
24
+ function assignFlowPayload(step, partial) {
25
+ const data = asFlowData(step);
26
+ const current = getFlowPayload(step);
27
+ data.payload = { ...current, ...partial };
28
+ }
29
+
30
+ // src/step-flow/legacy-handoff.ts
31
+ function createFinishHandoff(dispatcher, nextState) {
32
+ return async (step) => {
33
+ const data = step.data;
34
+ if (!data.__flow) {
35
+ data.__flow = { state: nextState };
36
+ } else {
37
+ data.__flow.state = nextState;
38
+ }
39
+ return step.next(dispatcher);
40
+ };
41
+ }
42
+ function createLaunchState(dispatcher, launchImpl, nextState, legacyDataKeys = ["appName", "packageName"]) {
43
+ return {
44
+ run: async (step) => {
45
+ const payload = getFlowPayload(step);
46
+ for (const key of legacyDataKeys) {
47
+ if (payload[key] !== void 0) {
48
+ step.data[key] = payload[key];
49
+ }
50
+ }
51
+ step.data.finishMethod = createFinishHandoff(
52
+ dispatcher,
53
+ nextState
54
+ );
55
+ return { type: "legacy", impl: launchImpl };
56
+ },
57
+ on: {}
58
+ };
59
+ }
60
+
61
+ // src/bounds.ts
62
+ var Bounds = class _Bounds {
63
+ // 构造函数
64
+ constructor(left, top, right, bottom, width, height, centerX, centerY, exactCenterX, exactCenterY, isEmpty) {
65
+ this.left = left;
66
+ this.top = top;
67
+ this.right = right;
68
+ this.bottom = bottom;
69
+ this.width = width;
70
+ this.height = height;
71
+ this.centerX = centerX;
72
+ this.centerY = centerY;
73
+ this.exactCenterX = exactCenterX;
74
+ this.exactCenterY = exactCenterY;
75
+ this.isEmpty = isEmpty;
76
+ }
77
+ /**
78
+ * 判断该 Bounds 是否在屏幕内(满足基本几何有效性)
79
+ * @returns {boolean}
80
+ */
81
+ isInScreen() {
82
+ return this.centerX > 0 && this.centerY > 0 && this.height > 0 && this.width > 0;
83
+ }
84
+ // 从普通对象创建 Bounds 实例
85
+ static from(data) {
86
+ return new _Bounds(
87
+ data.left,
88
+ data.top,
89
+ data.right,
90
+ data.bottom,
91
+ data.width,
92
+ data.height,
93
+ data.centerX,
94
+ data.centerY,
95
+ data.exactCenterX,
96
+ data.exactCenterY,
97
+ data.isEmpty
98
+ );
99
+ }
100
+ // 从 JSON 字符串创建实例
101
+ static fromJSON(json) {
102
+ const data = JSON.parse(json);
103
+ return _Bounds.from(data);
104
+ }
105
+ static fromData(data) {
106
+ if (data == null) {
107
+ return new _Bounds(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, true);
108
+ }
109
+ if (typeof data !== "object" || Array.isArray(data)) {
110
+ throw new Error(
111
+ `Bounds.fromData: Expected object, but got ${typeof data}. Value: ${JSON.stringify(data)}`
112
+ );
113
+ }
114
+ return new _Bounds(
115
+ data.left,
116
+ data.top,
117
+ data.right,
118
+ data.bottom,
119
+ data.width,
120
+ data.height,
121
+ data.centerX,
122
+ data.centerY,
123
+ data.exactCenterX,
124
+ data.exactCenterY,
125
+ data.isEmpty
126
+ );
127
+ }
128
+ // 转换为普通对象
129
+ toJSON() {
130
+ return {
131
+ left: this.left,
132
+ top: this.top,
133
+ right: this.right,
134
+ bottom: this.bottom,
135
+ width: this.width,
136
+ height: this.height,
137
+ centerX: this.centerX,
138
+ centerY: this.centerY,
139
+ exactCenterX: this.exactCenterX,
140
+ exactCenterY: this.exactCenterY,
141
+ isEmpty: this.isEmpty
142
+ };
143
+ }
144
+ // 克隆方法
145
+ clone() {
146
+ return new _Bounds(
147
+ this.left,
148
+ this.top,
149
+ this.right,
150
+ this.bottom,
151
+ this.width,
152
+ this.height,
153
+ this.centerX,
154
+ this.centerY,
155
+ this.exactCenterX,
156
+ this.exactCenterY,
157
+ this.isEmpty
158
+ );
159
+ }
160
+ };
161
+
162
+ // src/call-method.ts
163
+ var CallMethod = {
164
+ takeScreenshot: "takeScreenshot",
165
+ takeScreenshotSave: "takeScreenshotSave",
166
+ takeScreenshotToFile: "takeScreenshotToFile",
167
+ overlayToast: "overlayToast",
168
+ setNodeText: "setNodeText",
169
+ findByTags: "findByTags",
170
+ findById: "findById",
171
+ findByText: "findByText",
172
+ findByTextAllMatch: "findByTextAllMatch",
173
+ containsText: "containsText",
174
+ getAllText: "getAllText",
175
+ findFirstParentByTags: "findFirstParentByTags",
176
+ getAllNodes: "getAllNodes",
177
+ getNodes: "getNodes",
178
+ findFirstParentClickable: "findFirstParentClickable",
179
+ getChildren: "getChildren",
180
+ getBoundsInScreen: "getBoundsInScreen",
181
+ isVisible: "isVisible",
182
+ click: "click",
183
+ longClick: "longClick",
184
+ back: "back",
185
+ home: "home",
186
+ notifications: "notifications",
187
+ recentApps: "recentApps",
188
+ paste: "paste",
189
+ focus: "focus",
190
+ selectionText: "selectionText",
191
+ scrollForward: "scrollForward",
192
+ launchApp: "launchApp",
193
+ getPackageName: "getPackageName",
194
+ getScreenSize: "getScreenSize",
195
+ getAppScreenSize: "getAppScreenSize",
196
+ scrollBackward: "scrollBackward",
197
+ setOverlayFlags: "setOverlayFlags",
198
+ scanQR: "scanQR",
199
+ loadWebViewOverlay: "loadWebViewOverlay",
200
+ closeOverlay: "closeOverlay",
201
+ recognizeTextInScreenshot: "recognizeTextInScreenshot",
202
+ clickByGesture: "clickByGesture",
203
+ clickNodeByGesture: "clickNodeByGesture",
204
+ doubleClickNodeByGesture: "doubleClickNodeByGesture",
205
+ performLinearGesture: "performLinearGesture",
206
+ longPressGestureAutoPaste: "longPressGestureAutoPaste",
207
+ getAppInfo: "getAppInfo",
208
+ getMacAddress: "getMacAddress",
209
+ getAndroidID: "getAndroidID",
210
+ getUniqueDeviceId: "getUniqueDeviceId",
211
+ addAccessibilityEventFilter: "addAccessibilityEventFilter",
212
+ setAccessibilityEventFilters: "setAccessibilityEventFilters",
213
+ httpRequest: "httpRequest",
214
+ getDeviceInfo: "getDeviceInfo",
215
+ getNetworkType: "getNetworkType",
216
+ isAppInstalled: "isAppInstalled",
217
+ getClipboardLatestText: "getClipboardLatestText",
218
+ getClipboardText: "getClipboardText",
219
+ openUrlInBrowser: "openUrlInBrowser",
220
+ keepScreenOn: "keepScreenOn",
221
+ clearKeepScreenOn: "clearKeepScreenOn",
222
+ download: "download",
223
+ audioPlayFromFile: "audioPlayFromFile",
224
+ audioStop: "audioStop",
225
+ audioPlayRingtone: "audioPlayRingtone",
226
+ audioStopRingtone: "audioStopRingtone",
227
+ // 通讯录相关方法
228
+ addContact: "addContact",
229
+ getAllContacts: "getAllContacts",
230
+ // 节点树相关方法
231
+ saveRootNodeTreeJson: "saveRootNodeTreeJson"
232
+ };
233
+
234
+ // src/call-response.ts
235
+ var CallResponse = class {
236
+ constructor(code, data, callbackId) {
237
+ this.code = code;
238
+ this.data = data;
239
+ this.callbackId = callbackId;
240
+ }
241
+ // 判断是否成功
242
+ isSuccess() {
243
+ return this.code === 0;
244
+ }
245
+ // 获取数据,如果数据为空则抛出错误
246
+ getData() {
247
+ if (this.data === null) {
248
+ throw new Error("Data is null");
249
+ }
250
+ return this.data;
251
+ }
252
+ // 获取数据,如果数据为空则返回默认值
253
+ getDataOrNull() {
254
+ return this.data;
255
+ }
256
+ // 获取数据,如果数据为空则返回默认值
257
+ getDataOrDefault(defaultValue) {
258
+ var _a2;
259
+ return (_a2 = this.data) != null ? _a2 : defaultValue;
260
+ }
261
+ };
262
+
263
+ // src/utils.ts
264
+ function generateUUID() {
265
+ return "xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace(/[xy]/g, function(c) {
266
+ const r = Math.random() * 16 | 0;
267
+ const v = c === "x" ? r : r & 3 | 8;
268
+ return v.toString(16);
269
+ });
270
+ }
271
+ function decodeBase64UTF8(base64) {
272
+ const binary = atob(base64);
273
+ const bytes = new Uint8Array(binary.length);
274
+ for (let i = 0; i < binary.length; i++) {
275
+ bytes[i] = binary.charCodeAt(i);
276
+ }
277
+ return new TextDecoder("utf-8").decode(bytes);
278
+ }
279
+
280
+ // src/app-info.ts
281
+ var AppInfo = class _AppInfo {
282
+ constructor(isSystem = false, minSdkVersion = 0, name = "", packageName = "", targetSdkVersion = 0, versionCode = 0, versionName = "") {
283
+ this.isSystem = isSystem;
284
+ this.minSdkVersion = minSdkVersion;
285
+ this.name = name;
286
+ this.packageName = packageName;
287
+ this.targetSdkVersion = targetSdkVersion;
288
+ this.versionCode = versionCode;
289
+ this.versionName = versionName;
290
+ }
291
+ /**
292
+ * 从JSON对象创建AppInfo实例
293
+ * @param data JSON对象
294
+ * @returns AppInfo实例
295
+ */
296
+ static fromJSON(data) {
297
+ var _a2, _b, _c, _d, _e, _f, _g;
298
+ return new _AppInfo(
299
+ (_a2 = data.isSystem) != null ? _a2 : false,
300
+ (_b = data.minSdkVersion) != null ? _b : 0,
301
+ (_c = data.name) != null ? _c : "",
302
+ (_d = data.packageName) != null ? _d : "",
303
+ (_e = data.targetSdkVersion) != null ? _e : 0,
304
+ (_f = data.versionCode) != null ? _f : 0,
305
+ (_g = data.versionName) != null ? _g : ""
306
+ );
307
+ }
308
+ /**
309
+ * 转换为JSON对象
310
+ * @returns JSON对象
311
+ */
312
+ toJSON() {
313
+ return {
314
+ isSystem: this.isSystem,
315
+ minSdkVersion: this.minSdkVersion,
316
+ name: this.name,
317
+ packageName: this.packageName,
318
+ targetSdkVersion: this.targetSdkVersion,
319
+ versionCode: this.versionCode,
320
+ versionName: this.versionName
321
+ };
322
+ }
323
+ };
324
+
325
+ // src/device-info.ts
326
+ var DeviceInfo = class _DeviceInfo {
327
+ constructor(uniqueDeviceId = "", androidID = "", macAddress = "", isDeviceRooted = false, manufacturer = "", model = "", sdkVersionCode = 0, sdkVersionName = "", abiList = [], isAdbEnabled = false, isDevelopmentSettingsEnabled = false, isEmulator = false, isTablet = false) {
328
+ this.uniqueDeviceId = uniqueDeviceId;
329
+ this.androidID = androidID;
330
+ this.macAddress = macAddress;
331
+ this.isDeviceRooted = isDeviceRooted;
332
+ this.manufacturer = manufacturer;
333
+ this.model = model;
334
+ this.sdkVersionCode = sdkVersionCode;
335
+ this.sdkVersionName = sdkVersionName;
336
+ this.abiList = abiList;
337
+ this.isAdbEnabled = isAdbEnabled;
338
+ this.isDevelopmentSettingsEnabled = isDevelopmentSettingsEnabled;
339
+ this.isEmulator = isEmulator;
340
+ this.isTablet = isTablet;
341
+ }
342
+ /**
343
+ * 从JSON对象创建DeviceInfo实例
344
+ * @param data JSON对象
345
+ * @returns DeviceInfo实例
346
+ */
347
+ static fromJSON(data) {
348
+ var _a2, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k, _l, _m;
349
+ return new _DeviceInfo(
350
+ (_a2 = data.uniqueDeviceId) != null ? _a2 : "",
351
+ (_b = data.androidID) != null ? _b : "",
352
+ (_c = data.macAddress) != null ? _c : "",
353
+ (_d = data.isDeviceRooted) != null ? _d : false,
354
+ (_e = data.manufacturer) != null ? _e : "",
355
+ (_f = data.model) != null ? _f : "",
356
+ (_g = data.sdkVersionCode) != null ? _g : 0,
357
+ (_h = data.sdkVersionName) != null ? _h : "",
358
+ (_i = data.abiList) != null ? _i : [],
359
+ (_j = data.isAdbEnabled) != null ? _j : false,
360
+ (_k = data.isDevelopmentSettingsEnabled) != null ? _k : false,
361
+ (_l = data.isEmulator) != null ? _l : false,
362
+ (_m = data.isTablet) != null ? _m : false
363
+ );
364
+ }
365
+ /**
366
+ * 转换为JSON对象
367
+ * @returns JSON对象
368
+ */
369
+ toJSON() {
370
+ return {
371
+ uniqueDeviceId: this.uniqueDeviceId,
372
+ androidID: this.androidID,
373
+ macAddress: this.macAddress,
374
+ isDeviceRooted: this.isDeviceRooted,
375
+ manufacturer: this.manufacturer,
376
+ model: this.model,
377
+ sdkVersionCode: this.sdkVersionCode,
378
+ sdkVersionName: this.sdkVersionName,
379
+ abiList: this.abiList,
380
+ isAdbEnabled: this.isAdbEnabled,
381
+ isDevelopmentSettingsEnabled: this.isDevelopmentSettingsEnabled,
382
+ isEmulator: this.isEmulator,
383
+ isTablet: this.isTablet
384
+ };
385
+ }
386
+ };
387
+
388
+ // src/assistsx-async.ts
389
+ var AssistsXAsync = class {
390
+ /**
391
+ * 执行异步调用
392
+ * @param method 方法名
393
+ * @param args 参数对象
394
+ * @param timeout 超时时间(秒),默认30秒
395
+ * @returns Promise<调用响应>
396
+ */
397
+ static async asyncCall(method, {
398
+ args,
399
+ node,
400
+ nodes,
401
+ timeout = 30
402
+ } = {}) {
403
+ const uuid = generateUUID();
404
+ const params = {
405
+ method,
406
+ arguments: args ? args : void 0,
407
+ node: node ? node : void 0,
408
+ nodes: nodes ? nodes : void 0,
409
+ callbackId: uuid
410
+ };
411
+ const promise = new Promise((resolve) => {
412
+ callbacks.set(uuid, (data) => {
413
+ resolve(data);
414
+ });
415
+ setTimeout(() => {
416
+ callbacks.delete(uuid);
417
+ resolve(new CallResponse(0, null, uuid));
418
+ }, timeout * 1e3);
419
+ });
420
+ const result = window.assistsxAsync.call(JSON.stringify(params));
421
+ const promiseResult = await promise;
422
+ if (typeof promiseResult === "string") {
423
+ const responseData = JSON.parse(promiseResult);
424
+ const response = new CallResponse(
425
+ responseData.code,
426
+ responseData.data,
427
+ responseData.callbackId
428
+ );
429
+ return response;
430
+ }
431
+ throw new Error("Call failed");
432
+ }
433
+ /**
434
+ * 设置悬浮窗标志
435
+ * @param flags 标志
436
+ * @param timeout 超时时间(秒),默认30秒
437
+ * @returns 是否设置成功
438
+ */
439
+ static async setOverlayFlags(flags, timeout) {
440
+ const response = await this.asyncCall(CallMethod.setOverlayFlags, {
441
+ args: { flags },
442
+ timeout
443
+ });
444
+ return response.getDataOrDefault(false);
445
+ }
446
+ /**
447
+ * 设置悬浮窗标志
448
+ * @param flags 标志
449
+ * @param timeout 超时时间(秒),默认30秒
450
+ * @returns 是否设置成功
451
+ */
452
+ static async setOverlayFlagList(flags, timeout) {
453
+ const response = await this.asyncCall(CallMethod.setOverlayFlags, {
454
+ args: { flags },
455
+ timeout
456
+ });
457
+ return response.getDataOrDefault(false);
458
+ }
459
+ /**
460
+ * 获取所有符合条件的节点
461
+ * @param filterClass 类名过滤
462
+ * @param filterViewId 视图ID过滤
463
+ * @param filterDes 描述过滤
464
+ * @param filterText 文本过滤
465
+ * @param timeout 超时时间(秒),默认30秒
466
+ * @returns 节点数组
467
+ */
468
+ static async getAllNodes({
469
+ filterClass,
470
+ filterViewId,
471
+ filterDes,
472
+ filterText,
473
+ timeout,
474
+ scope
475
+ } = {}) {
476
+ const response = await this.asyncCall(CallMethod.getAllNodes, {
477
+ args: {
478
+ filterClass,
479
+ filterViewId,
480
+ filterDes,
481
+ filterText,
482
+ ...scope !== void 0 ? { scope } : {}
483
+ },
484
+ timeout
485
+ });
486
+ const data = response.getDataOrDefault([]);
487
+ if (!Array.isArray(data)) {
488
+ throw new Error(
489
+ `AssistsXAsync.getAllNodes: Expected array, but got ${typeof data}. Value: ${JSON.stringify(data)}`
490
+ );
491
+ }
492
+ return Node.fromJSONArray(data);
493
+ }
494
+ /**
495
+ * 设置节点文本
496
+ * @param node 目标节点
497
+ * @param text 要设置的文本
498
+ * @param timeout 超时时间(秒),默认30秒
499
+ * @returns 是否设置成功
500
+ */
501
+ static async setNodeText(node, text, timeout) {
502
+ const response = await this.asyncCall(CallMethod.setNodeText, {
503
+ args: { text },
504
+ node,
505
+ timeout
506
+ });
507
+ return response.getDataOrDefault(false);
508
+ }
509
+ /**
510
+ * 对指定节点进行截图
511
+ * @param nodes 要截图的节点数组
512
+ * @param overlayHiddenScreenshotDelayMillis 截图延迟时间(毫秒)
513
+ * @param timeout 超时时间(秒),默认30秒
514
+ * @returns 截图路径数组
515
+ */
516
+ static async takeScreenshotNodes(nodes, overlayHiddenScreenshotDelayMillis = 250, timeout) {
517
+ const response = await this.asyncCall(CallMethod.takeScreenshot, {
518
+ nodes,
519
+ args: { overlayHiddenScreenshotDelayMillis },
520
+ timeout
521
+ });
522
+ const data = response.getDataOrDefault({ images: [] });
523
+ return data.images;
524
+ }
525
+ /**
526
+ * 保存全屏截图到文件
527
+ * @param options 截图保存选项
528
+ * @param options.filePath 文件路径(可选,不提供则自动生成)
529
+ * @param options.format 图片格式,支持 "PNG"、"JPEG"、"JPG"、"WEBP",默认为 "PNG"
530
+ * @param options.overlayHiddenScreenshotDelayMillis 截图延迟时间(毫秒),默认为 250
531
+ * @param options.timeout 超时时间(秒),默认30秒
532
+ * @returns 保存的文件路径
533
+ */
534
+ static async takeScreenshotSave(options = {}) {
535
+ const {
536
+ filePath,
537
+ format = "PNG",
538
+ overlayHiddenScreenshotDelayMillis = 250,
539
+ timeout
540
+ } = options;
541
+ const response = await this.asyncCall(CallMethod.takeScreenshotSave, {
542
+ args: {
543
+ filePath,
544
+ format,
545
+ overlayHiddenScreenshotDelayMillis
546
+ },
547
+ timeout
548
+ });
549
+ const data = response.getDataOrDefault({ file: "" });
550
+ return data.file;
551
+ }
552
+ /**
553
+ * 保存截图到文件(支持多个节点)
554
+ * @param options 截图保存选项
555
+ * @param options.nodes 要截图的节点数组(可选,不提供则保存全屏截图)
556
+ * @param options.filePath 文件路径(可选,不提供则自动生成。多个节点时会自动添加索引后缀)
557
+ * @param options.format 图片格式,支持 "PNG"、"JPEG"、"JPG"、"WEBP",默认为 "PNG"
558
+ * @param options.overlayHiddenScreenshotDelayMillis 截图延迟时间(毫秒),默认为 250
559
+ * @param options.timeout 超时时间(秒),默认30秒
560
+ * @returns 保存的文件路径数组
561
+ */
562
+ static async takeScreenshotToFile(options = {}) {
563
+ const {
564
+ nodes,
565
+ filePath,
566
+ format = "PNG",
567
+ overlayHiddenScreenshotDelayMillis = 250,
568
+ timeout
569
+ } = options;
570
+ const response = await this.asyncCall(CallMethod.takeScreenshotToFile, {
571
+ nodes,
572
+ args: {
573
+ filePath,
574
+ format,
575
+ overlayHiddenScreenshotDelayMillis
576
+ },
577
+ timeout
578
+ });
579
+ const data = response.getDataOrDefault({ files: [] });
580
+ if (!Array.isArray(data.files)) {
581
+ throw new Error(
582
+ `AssistsXAsync.takeScreenshotToFile: Expected files array, but got ${typeof data.files}. Value: ${JSON.stringify(data.files)}`
583
+ );
584
+ }
585
+ return data.files;
586
+ }
587
+ /**
588
+ * 截图识别文本
589
+ * @param param0 识别参数
590
+ * @returns 截图识别结果
591
+ */
592
+ static async recognizeTextInScreenshot(targetText, options = {}) {
593
+ const {
594
+ rotationDegrees = 0,
595
+ overlayHiddenScreenshotDelayMillis = 250,
596
+ restoreOverlay = true,
597
+ region,
598
+ timeout
599
+ } = options;
600
+ const response = await this.asyncCall(
601
+ CallMethod.recognizeTextInScreenshot,
602
+ {
603
+ args: {
604
+ targetText,
605
+ rotationDegrees,
606
+ overlayHiddenScreenshotDelayMillis,
607
+ restoreOverlay,
608
+ region
609
+ },
610
+ timeout
611
+ }
612
+ );
613
+ return response.getDataOrDefault({
614
+ fullText: "",
615
+ processingTimeMillis: 0,
616
+ positions: []
617
+ });
618
+ }
619
+ static async scanQR(timeout) {
620
+ const response = await this.asyncCall(CallMethod.scanQR, { timeout });
621
+ const data = response.getDataOrDefault({ value: "" });
622
+ return data.value;
623
+ }
624
+ static async loadWebViewOverlay(url, options = {}) {
625
+ const {
626
+ initialWidth,
627
+ initialHeight,
628
+ initialX,
629
+ initialY,
630
+ minWidth,
631
+ minHeight,
632
+ maxWidth,
633
+ maxHeight,
634
+ initialCenter,
635
+ showTopOperationArea,
636
+ showBottomOperationArea,
637
+ backgroundColor,
638
+ timeout
639
+ } = options;
640
+ const response = await this.asyncCall(CallMethod.loadWebViewOverlay, {
641
+ args: {
642
+ url,
643
+ initialWidth,
644
+ initialHeight,
645
+ initialX,
646
+ initialY,
647
+ minWidth,
648
+ minHeight,
649
+ maxWidth,
650
+ maxHeight,
651
+ initialCenter,
652
+ showTopOperationArea,
653
+ showBottomOperationArea,
654
+ backgroundColor
655
+ },
656
+ timeout
657
+ });
658
+ const data = response.getDataOrDefault({});
659
+ return data;
660
+ }
661
+ /**
662
+ * 关闭当前 WebView 悬浮窗
663
+ * @param timeout 超时时间(秒),默认30秒
664
+ * @returns 是否关闭成功(当前页面在悬浮窗内时返回 true,否则 false)
665
+ */
666
+ static async closeOverlay(timeout) {
667
+ const response = await this.asyncCall(CallMethod.closeOverlay, {
668
+ timeout
669
+ });
670
+ return response.getDataOrDefault(false);
671
+ }
672
+ /**
673
+ * 点击节点
674
+ * @param node 要点击的节点
675
+ * @param timeout 超时时间(秒),默认30秒
676
+ * @returns 是否点击成功
677
+ */
678
+ static async click(node, timeout) {
679
+ const response = await this.asyncCall(CallMethod.click, { node, timeout });
680
+ return response.getDataOrDefault(false);
681
+ }
682
+ /**
683
+ * 长按节点
684
+ * @param node 要长按的节点
685
+ * @param timeout 超时时间(秒),默认30秒
686
+ * @returns 是否长按成功
687
+ */
688
+ static async longClick(node, timeout) {
689
+ const response = await this.asyncCall(CallMethod.longClick, {
690
+ node,
691
+ timeout
692
+ });
693
+ return response.getDataOrDefault(false);
694
+ }
695
+ /**
696
+ * 启动应用
697
+ * @param packageName 应用包名
698
+ * @param timeout 超时时间(秒),默认30秒
699
+ * @returns 是否启动成功
700
+ */
701
+ static async launchApp(packageName, timeout) {
702
+ const response = await this.asyncCall(CallMethod.launchApp, {
703
+ args: { packageName },
704
+ timeout
705
+ });
706
+ return response.getDataOrDefault(false);
707
+ }
708
+ static async getPackageName(timeoutOrOptions) {
709
+ const normalized = typeof timeoutOrOptions === "number" ? { timeout: timeoutOrOptions } : timeoutOrOptions != null ? timeoutOrOptions : {};
710
+ const { timeout, scope } = normalized;
711
+ const response = await this.asyncCall(CallMethod.getPackageName, {
712
+ args: scope !== void 0 ? { scope } : void 0,
713
+ timeout
714
+ });
715
+ return response.getDataOrDefault("");
716
+ }
717
+ /**
718
+ * 显示悬浮提示
719
+ * @param text 提示文本
720
+ * @param delay 显示时长(毫秒)
721
+ * @param timeout 超时时间(秒),默认30秒
722
+ * @returns 是否显示成功
723
+ */
724
+ static async overlayToast(text, delay = 2e3, timeout) {
725
+ const response = await this.asyncCall(CallMethod.overlayToast, {
726
+ args: { text, delay },
727
+ timeout
728
+ });
729
+ return response.getDataOrDefault(false);
730
+ }
731
+ /**
732
+ * 通过ID查找节点
733
+ * @param id 节点ID
734
+ * @param filterClass 类名过滤
735
+ * @param filterText 文本过滤
736
+ * @param filterDes 描述过滤
737
+ * @param node 父节点范围
738
+ * @param timeout 超时时间(秒),默认30秒
739
+ * @returns 节点数组
740
+ */
741
+ static async findById(id, {
742
+ filterClass,
743
+ filterText,
744
+ filterDes,
745
+ node,
746
+ timeout,
747
+ scope
748
+ } = {}) {
749
+ const response = await this.asyncCall(CallMethod.findById, {
750
+ args: {
751
+ id,
752
+ filterClass,
753
+ filterText,
754
+ filterDes,
755
+ ...scope !== void 0 ? { scope } : {}
756
+ },
757
+ node,
758
+ timeout
759
+ });
760
+ const data = response.getDataOrDefault([]);
761
+ if (!Array.isArray(data)) {
762
+ throw new Error(
763
+ `AssistsXAsync.findById: Expected array, but got ${typeof data}. Value: ${JSON.stringify(data)}`
764
+ );
765
+ }
766
+ return Node.fromJSONArray(data);
767
+ }
768
+ /**
769
+ * 通过文本查找节点
770
+ * @param text 要查找的文本
771
+ * @param filterClass 类名过滤
772
+ * @param filterViewId 视图ID过滤
773
+ * @param filterDes 描述过滤
774
+ * @param node 父节点范围
775
+ * @param timeout 超时时间(秒),默认30秒
776
+ * @returns 节点数组
777
+ */
778
+ static async findByText(text, {
779
+ filterClass,
780
+ filterViewId,
781
+ filterDes,
782
+ node,
783
+ timeout,
784
+ scope
785
+ } = {}) {
786
+ const response = await this.asyncCall(CallMethod.findByText, {
787
+ args: {
788
+ text,
789
+ filterClass,
790
+ filterViewId,
791
+ filterDes,
792
+ ...scope !== void 0 ? { scope } : {}
793
+ },
794
+ node,
795
+ timeout
796
+ });
797
+ const data = response.getDataOrDefault([]);
798
+ if (!Array.isArray(data)) {
799
+ throw new Error(
800
+ `AssistsXAsync.findByText: Expected array, but got ${typeof data}. Value: ${JSON.stringify(data)}`
801
+ );
802
+ }
803
+ return Node.fromJSONArray(data);
804
+ }
805
+ /**
806
+ * 通过标签查找节点
807
+ * @param className 类名
808
+ * @param filterText 文本过滤
809
+ * @param filterViewId 视图ID过滤
810
+ * @param filterDes 描述过滤
811
+ * @param node 父节点范围
812
+ * @param timeout 超时时间(秒),默认30秒
813
+ * @returns 节点数组
814
+ */
815
+ static async findByTags(className, {
816
+ filterText,
817
+ filterViewId,
818
+ filterDes,
819
+ node,
820
+ timeout,
821
+ scope
822
+ } = {}) {
823
+ const response = await this.asyncCall(CallMethod.findByTags, {
824
+ args: {
825
+ className,
826
+ filterText,
827
+ filterViewId,
828
+ filterDes,
829
+ ...scope !== void 0 ? { scope } : {}
830
+ },
831
+ node,
832
+ timeout
833
+ });
834
+ const data = response.getDataOrDefault([]);
835
+ if (!Array.isArray(data)) {
836
+ throw new Error(
837
+ `AssistsXAsync.findByTags: Expected array, but got ${typeof data}. Value: ${JSON.stringify(data)}`
838
+ );
839
+ }
840
+ return Node.fromJSONArray(data);
841
+ }
842
+ static async findByTextAllMatch(text, timeoutOrOptions) {
843
+ const normalized = typeof timeoutOrOptions === "number" ? { timeout: timeoutOrOptions } : timeoutOrOptions != null ? timeoutOrOptions : {};
844
+ const { timeout, scope } = normalized;
845
+ const response = await this.asyncCall(CallMethod.findByTextAllMatch, {
846
+ args: {
847
+ text,
848
+ ...scope !== void 0 ? { scope } : {}
849
+ },
850
+ timeout
851
+ });
852
+ const data = response.getDataOrDefault([]);
853
+ if (!Array.isArray(data)) {
854
+ throw new Error(
855
+ `AssistsXAsync.findByTextAllMatch: Expected array, but got ${typeof data}. Value: ${JSON.stringify(data)}`
856
+ );
857
+ }
858
+ return Node.fromJSONArray(data);
859
+ }
860
+ /**
861
+ * 检查是否包含指定文本
862
+ * @param text 要检查的文本
863
+ * @param timeout 超时时间(秒),默认30秒
864
+ * @returns 是否包含
865
+ */
866
+ static async containsText(text, timeout) {
867
+ const response = await this.asyncCall(CallMethod.containsText, {
868
+ args: { text },
869
+ timeout
870
+ });
871
+ return response.getDataOrDefault(false);
872
+ }
873
+ /**
874
+ * 获取所有文本
875
+ * @param timeout 超时时间(秒),默认30秒
876
+ * @returns 文本数组
877
+ */
878
+ static async getAllText(timeout) {
879
+ const response = await this.asyncCall(CallMethod.getAllText, { timeout });
880
+ const data = response.getDataOrDefault([]);
881
+ if (!Array.isArray(data)) {
882
+ throw new Error(
883
+ `AssistsXAsync.getAllText: Expected array, but got ${typeof data}. Value: ${JSON.stringify(data)}`
884
+ );
885
+ }
886
+ return data;
887
+ }
888
+ /**
889
+ * 查找第一个匹配标签的父节点
890
+ * @param className 类名
891
+ * @param timeout 超时时间(秒),默认30秒
892
+ * @returns 父节点
893
+ */
894
+ static async findFirstParentByTags(node, className, timeout) {
895
+ const response = await this.asyncCall(CallMethod.findFirstParentByTags, {
896
+ args: { className },
897
+ node,
898
+ timeout
899
+ });
900
+ return Node.create(response.getDataOrDefault({}));
901
+ }
902
+ /**
903
+ * 获取节点的所有子节点
904
+ * @param node 父节点
905
+ * @param timeout 超时时间(秒),默认30秒
906
+ * @returns 子节点数组
907
+ */
908
+ static async getNodes(node, timeout) {
909
+ const response = await this.asyncCall(CallMethod.getNodes, {
910
+ node,
911
+ timeout
912
+ });
913
+ const data = response.getDataOrDefault([]);
914
+ if (!Array.isArray(data)) {
915
+ throw new Error(
916
+ `AssistsXAsync.getNodes: Expected array, but got ${typeof data}. Value: ${JSON.stringify(data)}`
917
+ );
918
+ }
919
+ return Node.fromJSONArray(data);
920
+ }
921
+ /**
922
+ * 获取节点的直接子节点
923
+ * @param node 父节点
924
+ * @param timeout 超时时间(秒),默认30秒
925
+ * @returns 子节点数组
926
+ */
927
+ static async getChildren(node, timeout) {
928
+ const response = await this.asyncCall(CallMethod.getChildren, {
929
+ node,
930
+ timeout
931
+ });
932
+ const data = response.getDataOrDefault([]);
933
+ if (!Array.isArray(data)) {
934
+ throw new Error(
935
+ `AssistsXAsync.getChildren: Expected array, but got ${typeof data}. Value: ${JSON.stringify(data)}`
936
+ );
937
+ }
938
+ return Node.fromJSONArray(data);
939
+ }
940
+ /**
941
+ * 查找第一个可点击的父节点
942
+ * @param node 起始节点
943
+ * @param timeout 超时时间(秒),默认30秒
944
+ * @returns 可点击的父节点
945
+ */
946
+ static async findFirstParentClickable(node, timeout) {
947
+ const response = await this.asyncCall(CallMethod.findFirstParentClickable, {
948
+ node,
949
+ timeout
950
+ });
951
+ return Node.create(response.getDataOrDefault({}));
952
+ }
953
+ /**
954
+ * 获取节点在屏幕中的边界
955
+ * @param node 目标节点
956
+ * @param timeout 超时时间(秒),默认30秒
957
+ * @returns 边界对象
958
+ */
959
+ static async getBoundsInScreen(node, timeout) {
960
+ const response = await this.asyncCall(CallMethod.getBoundsInScreen, {
961
+ node,
962
+ timeout
963
+ });
964
+ return Bounds.fromData(response.getDataOrDefault({}));
965
+ }
966
+ /**
967
+ * 检查节点是否可见
968
+ * @param node 目标节点
969
+ * @param compareNode 比较节点
970
+ * @param isFullyByCompareNode 是否完全可见
971
+ * @param timeout 超时时间(秒),默认30秒
972
+ * @returns 是否可见
973
+ */
974
+ static async isVisible(node, {
975
+ compareNode,
976
+ isFullyByCompareNode,
977
+ timeout
978
+ } = {}) {
979
+ const response = await this.asyncCall(CallMethod.isVisible, {
980
+ node,
981
+ args: { compareNode, isFullyByCompareNode },
982
+ timeout
983
+ });
984
+ return response.getDataOrDefault(false);
985
+ }
986
+ /**
987
+ * 执行点击手势
988
+ * @param x 横坐标
989
+ * @param y 纵坐标
990
+ * @param duration 持续时间
991
+ * @param timeout 超时时间(秒),默认30秒
992
+ * @returns 是否成功
993
+ */
994
+ static async clickByGesture(x, y, duration, timeout) {
995
+ const response = await this.asyncCall(CallMethod.clickByGesture, {
996
+ args: { x, y, duration },
997
+ timeout
998
+ });
999
+ return response.getDataOrDefault(false);
1000
+ }
1001
+ /**
1002
+ * 返回操作
1003
+ * @param timeout 超时时间(秒),默认30秒
1004
+ * @returns 是否成功
1005
+ */
1006
+ static async back(timeout) {
1007
+ const response = await this.asyncCall(CallMethod.back, { timeout });
1008
+ return response.getDataOrDefault(false);
1009
+ }
1010
+ /**
1011
+ * 回到主页
1012
+ * @param timeout 超时时间(秒),默认30秒
1013
+ * @returns 是否成功
1014
+ */
1015
+ static async home(timeout) {
1016
+ const response = await this.asyncCall(CallMethod.home, { timeout });
1017
+ return response.getDataOrDefault(false);
1018
+ }
1019
+ /**
1020
+ * 打开通知栏
1021
+ * @param timeout 超时时间(秒),默认30秒
1022
+ * @returns 是否成功
1023
+ */
1024
+ static async notifications(timeout) {
1025
+ const response = await this.asyncCall(CallMethod.notifications, {
1026
+ timeout
1027
+ });
1028
+ return response.getDataOrDefault(false);
1029
+ }
1030
+ /**
1031
+ * 显示最近应用
1032
+ * @param timeout 超时时间(秒),默认30秒
1033
+ * @returns 是否成功
1034
+ */
1035
+ static async recentApps(timeout) {
1036
+ const response = await this.asyncCall(CallMethod.recentApps, { timeout });
1037
+ return response.getDataOrDefault(false);
1038
+ }
1039
+ /**
1040
+ * 在节点中粘贴文本
1041
+ * @param node 目标节点
1042
+ * @param text 要粘贴的文本
1043
+ * @param timeout 超时时间(秒),默认30秒
1044
+ * @returns 是否成功
1045
+ */
1046
+ static async paste(node, text, timeout) {
1047
+ const response = await this.asyncCall(CallMethod.paste, {
1048
+ args: { text },
1049
+ node,
1050
+ timeout
1051
+ });
1052
+ return response.getDataOrDefault(false);
1053
+ }
1054
+ static async focus(node, timeout) {
1055
+ const response = await this.asyncCall(CallMethod.focus, { node, timeout });
1056
+ return response.getDataOrDefault(false);
1057
+ }
1058
+ /**
1059
+ * 选择文本
1060
+ * @param node 目标节点
1061
+ * @param selectionStart 选择起始位置
1062
+ * @param selectionEnd 选择结束位置
1063
+ * @param timeout 超时时间(秒),默认30秒
1064
+ * @returns 是否成功
1065
+ */
1066
+ static async selectionText(node, selectionStart, selectionEnd, timeout) {
1067
+ const response = await this.asyncCall(CallMethod.selectionText, {
1068
+ args: { selectionStart, selectionEnd },
1069
+ node,
1070
+ timeout
1071
+ });
1072
+ return response.getDataOrDefault(false);
1073
+ }
1074
+ /**
1075
+ * 向前滚动
1076
+ * @param node 可滚动节点
1077
+ * @param timeout 超时时间(秒),默认30秒
1078
+ * @returns 是否成功
1079
+ */
1080
+ static async scrollForward(node, timeout) {
1081
+ const response = await this.asyncCall(CallMethod.scrollForward, {
1082
+ node,
1083
+ timeout
1084
+ });
1085
+ return response.getDataOrDefault(false);
1086
+ }
1087
+ /**
1088
+ * 向后滚动
1089
+ * @param node 可滚动节点
1090
+ * @param timeout 超时时间(秒),默认30秒
1091
+ * @returns 是否成功
1092
+ */
1093
+ static async scrollBackward(node, timeout) {
1094
+ const response = await this.asyncCall(CallMethod.scrollBackward, {
1095
+ node,
1096
+ timeout
1097
+ });
1098
+ return response.getDataOrDefault(false);
1099
+ }
1100
+ /**
1101
+ * 对节点执行点击手势
1102
+ * @param node 目标节点
1103
+ * @param offsetX X轴偏移
1104
+ * @param offsetY Y轴偏移
1105
+ * @param switchWindowIntervalDelay 窗口切换延迟
1106
+ * @param clickDuration 点击持续时间
1107
+ * @param timeout 超时时间(秒),默认30秒
1108
+ * @returns 是否成功
1109
+ */
1110
+ static async clickNodeByGesture(node, {
1111
+ offsetX,
1112
+ offsetY,
1113
+ switchWindowIntervalDelay,
1114
+ clickDuration,
1115
+ timeout
1116
+ } = {}) {
1117
+ const response = await this.asyncCall(CallMethod.clickNodeByGesture, {
1118
+ node,
1119
+ args: { offsetX, offsetY, switchWindowIntervalDelay, clickDuration },
1120
+ timeout
1121
+ });
1122
+ return response.getDataOrDefault(false);
1123
+ }
1124
+ /**
1125
+ * 对节点执行双击手势
1126
+ * @param node 目标节点
1127
+ * @param offsetX X轴偏移
1128
+ * @param offsetY Y轴偏移
1129
+ * @param switchWindowIntervalDelay 窗口切换延迟
1130
+ * @param clickDuration 点击持续时间
1131
+ * @param clickInterval 点击间隔
1132
+ * @param timeout 超时时间(秒),默认30秒
1133
+ * @returns 是否成功
1134
+ */
1135
+ static async doubleClickNodeByGesture(node, {
1136
+ offsetX,
1137
+ offsetY,
1138
+ switchWindowIntervalDelay,
1139
+ clickDuration,
1140
+ clickInterval,
1141
+ timeout
1142
+ } = {}) {
1143
+ const response = await this.asyncCall(CallMethod.doubleClickNodeByGesture, {
1144
+ node,
1145
+ args: {
1146
+ offsetX,
1147
+ offsetY,
1148
+ switchWindowIntervalDelay,
1149
+ clickDuration,
1150
+ clickInterval
1151
+ },
1152
+ timeout
1153
+ });
1154
+ return response.getDataOrDefault(false);
1155
+ }
1156
+ /**
1157
+ * 执行线型手势
1158
+ * @param startPoint
1159
+ * @param endPoint
1160
+ * @param param2
1161
+ * @param timeout 超时时间(秒),默认30秒
1162
+ * @returns
1163
+ */
1164
+ static async performLinearGesture(startPoint, endPoint, { duration, timeout } = {}) {
1165
+ const response = await this.asyncCall(CallMethod.performLinearGesture, {
1166
+ args: { startPoint, endPoint, duration },
1167
+ timeout
1168
+ });
1169
+ return response.getDataOrDefault(false);
1170
+ }
1171
+ static async longPressNodeByGestureAutoPaste(node, text, {
1172
+ matchedPackageName,
1173
+ matchedText,
1174
+ timeoutMillis,
1175
+ longPressDuration,
1176
+ timeout
1177
+ } = { matchedText: "\u7C98\u8D34", timeoutMillis: 1500, longPressDuration: 600 }) {
1178
+ const response = await this.asyncCall(
1179
+ CallMethod.longPressGestureAutoPaste,
1180
+ {
1181
+ node,
1182
+ args: {
1183
+ text,
1184
+ matchedPackageName,
1185
+ matchedText,
1186
+ timeoutMillis,
1187
+ longPressDuration
1188
+ },
1189
+ timeout
1190
+ }
1191
+ );
1192
+ return response.getDataOrDefault(false);
1193
+ }
1194
+ static async longPressGestureAutoPaste(point, text, {
1195
+ matchedPackageName,
1196
+ matchedText,
1197
+ timeoutMillis,
1198
+ longPressDuration,
1199
+ timeout
1200
+ } = { matchedText: "\u7C98\u8D34", timeoutMillis: 1500, longPressDuration: 600 }) {
1201
+ const response = await this.asyncCall(
1202
+ CallMethod.longPressGestureAutoPaste,
1203
+ {
1204
+ args: {
1205
+ point,
1206
+ text,
1207
+ matchedPackageName,
1208
+ matchedText,
1209
+ timeoutMillis,
1210
+ longPressDuration
1211
+ },
1212
+ timeout
1213
+ }
1214
+ );
1215
+ return response.getDataOrDefault(false);
1216
+ }
1217
+ static async getAppInfo(packageName, timeout) {
1218
+ const response = await this.asyncCall(CallMethod.getAppInfo, {
1219
+ args: { packageName },
1220
+ timeout
1221
+ });
1222
+ return AppInfo.fromJSON(response.getDataOrDefault({}));
1223
+ }
1224
+ static async getUniqueDeviceId(timeout) {
1225
+ const response = await this.asyncCall(CallMethod.getUniqueDeviceId, {
1226
+ timeout
1227
+ });
1228
+ return response.getDataOrDefault("");
1229
+ }
1230
+ static async getAndroidID(timeout) {
1231
+ const response = await this.asyncCall(CallMethod.getAndroidID, { timeout });
1232
+ return response.getDataOrDefault("");
1233
+ }
1234
+ static async getMacAddress(timeout) {
1235
+ const response = await this.asyncCall(CallMethod.getMacAddress, {
1236
+ timeout
1237
+ });
1238
+ return response.getDataOrDefault({});
1239
+ }
1240
+ static async getDeviceInfo(timeout) {
1241
+ const response = await this.asyncCall(CallMethod.getDeviceInfo, {
1242
+ timeout
1243
+ });
1244
+ return DeviceInfo.fromJSON(response.getDataOrDefault({}));
1245
+ }
1246
+ /**
1247
+ * 获取屏幕尺寸
1248
+ * @param timeout 超时时间(秒),默认30秒
1249
+ * @returns 屏幕尺寸对象
1250
+ */
1251
+ static async getScreenSize(timeout) {
1252
+ const response = await this.asyncCall(CallMethod.getScreenSize, {
1253
+ timeout
1254
+ });
1255
+ return response.getDataOrDefault({});
1256
+ }
1257
+ /**
1258
+ * 获取应用窗口尺寸
1259
+ * @param timeout 超时时间(秒),默认30秒
1260
+ * @returns 应用窗口尺寸对象
1261
+ */
1262
+ static async getAppScreenSize(timeout) {
1263
+ const response = await this.asyncCall(CallMethod.getAppScreenSize, {
1264
+ timeout
1265
+ });
1266
+ return response.getDataOrDefault({});
1267
+ }
1268
+ /**
1269
+ * 在浏览器中打开URL
1270
+ * @param url 要打开的URL
1271
+ * @param timeout 超时时间(秒),默认30秒
1272
+ * @returns 是否成功打开
1273
+ */
1274
+ static async openUrlInBrowser(url, timeout) {
1275
+ const response = await this.asyncCall(CallMethod.openUrlInBrowser, {
1276
+ args: { url },
1277
+ timeout
1278
+ });
1279
+ return response.getDataOrDefault(false);
1280
+ }
1281
+ static async download(url, timeout) {
1282
+ const response = await this.asyncCall(CallMethod.download, {
1283
+ args: { url },
1284
+ timeout
1285
+ });
1286
+ return response.getDataOrDefault(null);
1287
+ }
1288
+ static async audioPlayFromFile(filePath, {
1289
+ volume = void 0,
1290
+ useAbsoluteVolume = false,
1291
+ timeout = 30
1292
+ }) {
1293
+ const response = await this.asyncCall(CallMethod.audioPlayFromFile, {
1294
+ args: { filePath, volume, useAbsoluteVolume },
1295
+ timeout
1296
+ });
1297
+ return response.getDataOrDefault(null);
1298
+ }
1299
+ static async audioStop({
1300
+ timeout = 30
1301
+ }) {
1302
+ const response = await this.asyncCall(CallMethod.audioStop, {
1303
+ timeout
1304
+ });
1305
+ return response.getDataOrDefault(false);
1306
+ }
1307
+ /**
1308
+ * 播放系统电话铃声
1309
+ * @param timeout 超时时间(秒),默认30秒
1310
+ * @returns 播放结果消息
1311
+ */
1312
+ static async audioPlayRingtone({
1313
+ timeout = 30
1314
+ }) {
1315
+ const response = await this.asyncCall(CallMethod.audioPlayRingtone, {
1316
+ timeout
1317
+ });
1318
+ return response.getDataOrDefault("");
1319
+ }
1320
+ /**
1321
+ * 停止播放系统电话铃声
1322
+ * @param timeout 超时时间(秒),默认30秒
1323
+ * @returns 停止结果消息
1324
+ */
1325
+ static async audioStopRingtone({
1326
+ timeout = 30
1327
+ }) {
1328
+ const response = await this.asyncCall(CallMethod.audioStopRingtone, {
1329
+ timeout
1330
+ });
1331
+ return response.getDataOrDefault("");
1332
+ }
1333
+ /**
1334
+ * 添加联系人
1335
+ * @param name 联系人姓名(必填)
1336
+ * @param phoneNumber 电话号码(必填)
1337
+ * @param timeout 超时时间(秒),默认30秒
1338
+ * @returns 是否添加成功
1339
+ */
1340
+ static async addContact(name, phoneNumber, timeout) {
1341
+ const response = await this.asyncCall(CallMethod.addContact, {
1342
+ args: { name, phoneNumber },
1343
+ timeout
1344
+ });
1345
+ return response.getDataOrDefault(false);
1346
+ }
1347
+ /**
1348
+ * 获取所有联系人
1349
+ * @param timeout 超时时间(秒),默认30秒
1350
+ * @returns 联系人列表
1351
+ */
1352
+ static async getAllContacts(timeout) {
1353
+ const response = await this.asyncCall(CallMethod.getAllContacts, {
1354
+ timeout
1355
+ });
1356
+ const data = response.getDataOrDefault([]);
1357
+ if (!Array.isArray(data)) {
1358
+ throw new Error(
1359
+ `AssistsXAsync.getAllContacts: Expected array, but got ${typeof data}. Value: ${JSON.stringify(data)}`
1360
+ );
1361
+ }
1362
+ return data;
1363
+ }
1364
+ /**
1365
+ * 保存根节点树为JSON文件
1366
+ * @param options 保存选项
1367
+ * @param options.filePath 文件路径(可选,不提供则自动生成)
1368
+ * @param options.prettyPrint 是否格式化输出,默认为 true
1369
+ * @param options.timeout 超时时间(秒),默认30秒
1370
+ * @param options.scope 节点查找范围(可选)
1371
+ * @returns 保存的文件路径
1372
+ */
1373
+ static async saveRootNodeTreeJson(options = {}) {
1374
+ const {
1375
+ filePath,
1376
+ prettyPrint = true,
1377
+ timeout,
1378
+ scope
1379
+ } = options;
1380
+ const response = await this.asyncCall(CallMethod.saveRootNodeTreeJson, {
1381
+ args: {
1382
+ filePath,
1383
+ prettyPrint,
1384
+ ...scope !== void 0 ? { scope } : {}
1385
+ },
1386
+ timeout
1387
+ });
1388
+ const data = response.getDataOrDefault({ file: "" });
1389
+ return data.file;
1390
+ }
1391
+ /**
1392
+ * 获取剪贴板文本内容
1393
+ * @param timeout 超时时间(秒),默认30秒
1394
+ * @returns 剪贴板文本内容,如果获取失败则返回空字符串
1395
+ */
1396
+ static async getClipboardText(timeout) {
1397
+ const response = await this.asyncCall(CallMethod.getClipboardText, {
1398
+ timeout
1399
+ });
1400
+ const data = response.getDataOrDefault({ text: "" });
1401
+ return data.text || "";
1402
+ }
1403
+ /**
1404
+ * 发送HTTP请求
1405
+ * @param options 请求选项
1406
+ * @returns HTTP响应
1407
+ */
1408
+ // public static async httpRequest(
1409
+ // options: HttpRequestOptions
1410
+ // ): Promise<HttpResponse> {
1411
+ // const { url, method = "GET", headers, body, timeout = 30 } = options;
1412
+ // const response = await this.asyncCall(CallMethod.httpRequest, {
1413
+ // args: { url, method, headers, body, timeout },
1414
+ // });
1415
+ // return response.getDataOrDefault({
1416
+ // statusCode: -1,
1417
+ // statusMessage: "",
1418
+ // body: "",
1419
+ // headers: {},
1420
+ // });
1421
+ // }
1422
+ };
1423
+
1424
+ // src/node-async.ts
1425
+ var NodeAsync = class {
1426
+ /**
1427
+ * 构造函数
1428
+ * @param node Node实例
1429
+ */
1430
+ constructor(node) {
1431
+ this.node = node;
1432
+ }
1433
+ /**
1434
+ * 查找第一个匹配标签的父节点
1435
+ * @param className 类名
1436
+ * @returns 父节点
1437
+ */
1438
+ async findFirstParentByTags(className) {
1439
+ Step.assert(this.node.stepId);
1440
+ const node = await AssistsXAsync.findFirstParentByTags(
1441
+ this.node,
1442
+ className
1443
+ );
1444
+ Step.assert(this.node.stepId);
1445
+ return node;
1446
+ }
1447
+ /**
1448
+ * 对节点执行点击手势
1449
+ * @param offsetX X轴偏移
1450
+ * @param offsetY Y轴偏移
1451
+ * @param switchWindowIntervalDelay 窗口切换延迟
1452
+ * @param clickDuration 点击持续时间
1453
+ * @returns 是否点击成功
1454
+ */
1455
+ async clickNodeByGesture({
1456
+ offsetX,
1457
+ offsetY,
1458
+ switchWindowIntervalDelay,
1459
+ clickDuration
1460
+ } = {}) {
1461
+ Step.assert(this.node.stepId);
1462
+ const result = await AssistsXAsync.clickNodeByGesture(this.node, {
1463
+ offsetX,
1464
+ offsetY,
1465
+ switchWindowIntervalDelay,
1466
+ clickDuration
1467
+ });
1468
+ Step.assert(this.node.stepId);
1469
+ return result;
1470
+ }
1471
+ /**
1472
+ * 对节点执行双击手势
1473
+ * @param offsetX X轴偏移
1474
+ * @param offsetY Y轴偏移
1475
+ * @param switchWindowIntervalDelay 窗口切换延迟
1476
+ * @param clickDuration 点击持续时间
1477
+ * @param clickInterval 点击间隔
1478
+ * @returns 是否双击成功
1479
+ */
1480
+ async doubleClickNodeByGesture({
1481
+ offsetX,
1482
+ offsetY,
1483
+ switchWindowIntervalDelay,
1484
+ clickDuration,
1485
+ clickInterval
1486
+ } = {}) {
1487
+ Step.assert(this.node.stepId);
1488
+ const result = await AssistsXAsync.doubleClickNodeByGesture(this.node, {
1489
+ offsetX,
1490
+ offsetY,
1491
+ switchWindowIntervalDelay,
1492
+ clickDuration,
1493
+ clickInterval
1494
+ });
1495
+ Step.assert(this.node.stepId);
1496
+ return result;
1497
+ }
1498
+ async longPressNodeByGestureAutoPaste(text, {
1499
+ matchedPackageName,
1500
+ matchedText,
1501
+ timeoutMillis,
1502
+ longPressDuration
1503
+ } = { matchedText: "\u7C98\u8D34", timeoutMillis: 1500, longPressDuration: 600 }) {
1504
+ Step.assert(this.node.stepId);
1505
+ const result = await AssistsXAsync.longPressNodeByGestureAutoPaste(
1506
+ this.node,
1507
+ text,
1508
+ {
1509
+ matchedPackageName,
1510
+ matchedText,
1511
+ timeoutMillis,
1512
+ longPressDuration
1513
+ }
1514
+ );
1515
+ Step.assert(this.node.stepId);
1516
+ return result;
1517
+ }
1518
+ /**
1519
+ * 在当前节点范围内通过标签查找节点
1520
+ * @param className 类名
1521
+ * @param filterText 文本过滤
1522
+ * @param filterViewId 视图ID过滤
1523
+ * @param filterDes 描述过滤
1524
+ * @returns 节点数组
1525
+ */
1526
+ async findByTags(className, {
1527
+ filterText,
1528
+ filterViewId,
1529
+ filterDes
1530
+ } = {}) {
1531
+ Step.assert(this.node.stepId);
1532
+ const result = await AssistsXAsync.findByTags(className, {
1533
+ filterText,
1534
+ filterViewId,
1535
+ filterDes,
1536
+ node: this.node
1537
+ });
1538
+ Step.assignIdsToNodes(result, this.node.stepId);
1539
+ Step.assert(this.node.stepId);
1540
+ return result;
1541
+ }
1542
+ /**
1543
+ * 在当前节点范围内通过ID查找节点
1544
+ * @param id 节点ID
1545
+ * @param filterClass 类名过滤
1546
+ * @param filterText 文本过滤
1547
+ * @param filterDes 描述过滤
1548
+ * @returns 节点数组
1549
+ */
1550
+ async findById(id, {
1551
+ filterClass,
1552
+ filterText,
1553
+ filterDes
1554
+ } = {}) {
1555
+ Step.assert(this.node.stepId);
1556
+ const result = await AssistsXAsync.findById(id, {
1557
+ filterClass,
1558
+ filterText,
1559
+ filterDes,
1560
+ node: this.node
1561
+ });
1562
+ Step.assignIdsToNodes(result, this.node.stepId);
1563
+ Step.assert(this.node.stepId);
1564
+ return result;
1565
+ }
1566
+ /**
1567
+ * 在当前节点范围内通过文本查找节点
1568
+ * @param text 要查找的文本
1569
+ * @param filterClass 类名过滤
1570
+ * @param filterViewId 视图ID过滤
1571
+ * @param filterDes 描述过滤
1572
+ * @returns 节点数组
1573
+ */
1574
+ async findByText(text, {
1575
+ filterClass,
1576
+ filterViewId,
1577
+ filterDes
1578
+ } = {}) {
1579
+ Step.assert(this.node.stepId);
1580
+ const result = await AssistsXAsync.findByText(text, {
1581
+ filterClass,
1582
+ filterViewId,
1583
+ filterDes,
1584
+ node: this.node
1585
+ });
1586
+ Step.assignIdsToNodes(result, this.node.stepId);
1587
+ Step.assert(this.node.stepId);
1588
+ return result;
1589
+ }
1590
+ /**
1591
+ * 向前滚动节点
1592
+ * @returns 是否滚动成功
1593
+ */
1594
+ async scrollForward() {
1595
+ Step.assert(this.node.stepId);
1596
+ const response = await AssistsXAsync.scrollForward(this.node);
1597
+ Step.assert(this.node.stepId);
1598
+ return response;
1599
+ }
1600
+ /**
1601
+ * 向后滚动节点
1602
+ * @returns 是否滚动成功
1603
+ */
1604
+ async scrollBackward() {
1605
+ Step.assert(this.node.stepId);
1606
+ const response = await AssistsXAsync.scrollBackward(this.node);
1607
+ Step.assert(this.node.stepId);
1608
+ return response;
1609
+ }
1610
+ /**
1611
+ * 检查节点是否可见
1612
+ * @param compareNode 比较节点
1613
+ * @param isFullyByCompareNode 是否完全可见
1614
+ * @returns 是否可见
1615
+ */
1616
+ async isVisible({
1617
+ compareNode,
1618
+ isFullyByCompareNode
1619
+ } = {}) {
1620
+ Step.assert(this.node.stepId);
1621
+ const response = await AssistsXAsync.isVisible(this.node, {
1622
+ compareNode,
1623
+ isFullyByCompareNode
1624
+ });
1625
+ Step.assert(this.node.stepId);
1626
+ return response;
1627
+ }
1628
+ /**
1629
+ * 对节点进行截图
1630
+ * @param overlayHiddenScreenshotDelayMillis 截图延迟时间(毫秒)
1631
+ * @returns 截图路径
1632
+ */
1633
+ async takeScreenshot(overlayHiddenScreenshotDelayMillis = 250) {
1634
+ Step.assert(this.node.stepId);
1635
+ const result = await AssistsXAsync.takeScreenshotNodes(
1636
+ [this.node],
1637
+ overlayHiddenScreenshotDelayMillis
1638
+ );
1639
+ Step.assert(this.node.stepId);
1640
+ return result[0];
1641
+ }
1642
+ /**
1643
+ * 设置节点文本
1644
+ * @param text 要设置的文本
1645
+ * @returns 是否设置成功
1646
+ */
1647
+ async setNodeText(text) {
1648
+ Step.assert(this.node.stepId);
1649
+ const result = await AssistsXAsync.setNodeText(this.node, text);
1650
+ Step.assert(this.node.stepId);
1651
+ return result;
1652
+ }
1653
+ async paste(text) {
1654
+ Step.assert(this.node.stepId);
1655
+ const result = await AssistsXAsync.paste(this.node, text);
1656
+ Step.assert(this.node.stepId);
1657
+ return result;
1658
+ }
1659
+ async focus() {
1660
+ Step.assert(this.node.stepId);
1661
+ const result = await AssistsXAsync.focus(this.node);
1662
+ Step.assert(this.node.stepId);
1663
+ return result;
1664
+ }
1665
+ /**
1666
+ * 点击节点
1667
+ * @returns 是否点击成功
1668
+ */
1669
+ async click() {
1670
+ Step.assert(this.node.stepId);
1671
+ const result = await AssistsXAsync.click(this.node);
1672
+ Step.assert(this.node.stepId);
1673
+ return result;
1674
+ }
1675
+ /**
1676
+ * 长按节点
1677
+ * @returns 是否长按成功
1678
+ */
1679
+ async longClick() {
1680
+ Step.assert(this.node.stepId);
1681
+ const result = await AssistsXAsync.longClick(this.node);
1682
+ Step.assert(this.node.stepId);
1683
+ return result;
1684
+ }
1685
+ /**
1686
+ * 查找第一个可点击的父节点
1687
+ * @returns 可点击的父节点
1688
+ */
1689
+ async findFirstParentClickable() {
1690
+ Step.assert(this.node.stepId);
1691
+ const result = await AssistsXAsync.findFirstParentClickable(this.node);
1692
+ Step.assert(this.node.stepId);
1693
+ Step.assignIdsToNodes([result], this.node.stepId);
1694
+ return result;
1695
+ }
1696
+ /**
1697
+ * 获取节点在屏幕中的边界
1698
+ * @returns 边界对象
1699
+ */
1700
+ async getBoundsInScreen() {
1701
+ Step.assert(this.node.stepId);
1702
+ const result = await AssistsXAsync.getBoundsInScreen(this.node);
1703
+ Step.assert(this.node.stepId);
1704
+ return result;
1705
+ }
1706
+ /**
1707
+ * 获取节点的所有子节点
1708
+ * @returns 子节点数组
1709
+ */
1710
+ async getNodes() {
1711
+ Step.assert(this.node.stepId);
1712
+ const result = await AssistsXAsync.getNodes(this.node);
1713
+ Step.assert(this.node.stepId);
1714
+ Step.assignIdsToNodes(result, this.node.stepId);
1715
+ return result;
1716
+ }
1717
+ /**
1718
+ * 获取节点的直接子节点
1719
+ * @returns 子节点数组
1720
+ */
1721
+ async getChildren() {
1722
+ Step.assert(this.node.stepId);
1723
+ const result = await AssistsXAsync.getChildren(this.node);
1724
+ Step.assert(this.node.stepId);
1725
+ Step.assignIdsToNodes(result, this.node.stepId);
1726
+ return result;
1727
+ }
1728
+ /**
1729
+ * 从JSON字符串创建节点实例
1730
+ * @param json JSON字符串
1731
+ * @returns 节点实例
1732
+ */
1733
+ static fromJSON(json) {
1734
+ const data = JSON.parse(json);
1735
+ return new Node(data);
1736
+ }
1737
+ /**
1738
+ * 从普通对象创建节点实例
1739
+ * @param data 对象数据
1740
+ * @returns 节点实例
1741
+ */
1742
+ static from(data) {
1743
+ return new Node(data);
1744
+ }
1745
+ /**
1746
+ * JSON.parse的reviver函数,用于将解析的JSON对象转换为Node实例
1747
+ * @param key 属性键
1748
+ * @param value 属性值
1749
+ * @returns 转换后的值
1750
+ */
1751
+ static reviver(key, value) {
1752
+ return key === "" ? new Node(value) : value;
1753
+ }
1754
+ /**
1755
+ * 创建新的节点实例
1756
+ * @param params 节点参数对象
1757
+ * @returns 节点实例
1758
+ */
1759
+ static create(params) {
1760
+ return new Node(params);
1761
+ }
1762
+ /**
1763
+ * 从JSON数组创建节点数组
1764
+ * @param array JSON数组
1765
+ * @returns 节点数组
1766
+ */
1767
+ static fromJSONArray(array) {
1768
+ if (!Array.isArray(array)) {
1769
+ throw new Error(
1770
+ `NodeAsync.fromJSONArray: Expected array, but got ${typeof array}. Value: ${JSON.stringify(array)}`
1771
+ );
1772
+ }
1773
+ return array.map((data) => new Node(data));
1774
+ }
1775
+ };
1776
+
1777
+ // src/node.ts
1778
+ var Node = class _Node {
1779
+ /**
1780
+ * 节点在屏幕中的边界
1781
+ * @deprecated 请使用 bounds 字段替代
1782
+ */
1783
+ get boundsInScreen() {
1784
+ return this.bounds;
1785
+ }
1786
+ /**
1787
+ * 构造函数
1788
+ * @param params 节点参数对象
1789
+ */
1790
+ constructor(params) {
1791
+ var _a2;
1792
+ this.nodeId = params.nodeId;
1793
+ this.text = params.text;
1794
+ this.des = params.des;
1795
+ this.viewId = params.viewId;
1796
+ this.className = params.className;
1797
+ this.isScrollable = params.isScrollable;
1798
+ this.isClickable = params.isClickable;
1799
+ this.isEnabled = params.isEnabled;
1800
+ this.stepId = params.stepId;
1801
+ this.hintText = params.hintText;
1802
+ this.isCheckable = params.isCheckable;
1803
+ this.isChecked = params.isChecked;
1804
+ this.isFocusable = params.isFocusable;
1805
+ this.isFocused = params.isFocused;
1806
+ this.isLongClickable = params.isLongClickable;
1807
+ this.isPassword = params.isPassword;
1808
+ this.isSelected = params.isSelected;
1809
+ this.isVisibleToUser = params.isVisibleToUser;
1810
+ this.drawingOrder = params.drawingOrder;
1811
+ const rawBounds = (_a2 = params.bounds) != null ? _a2 : params.boundsInScreen;
1812
+ this.bounds = rawBounds instanceof Bounds ? rawBounds : Bounds.fromData(rawBounds);
1813
+ }
1814
+ get async() {
1815
+ return new NodeAsync(this);
1816
+ }
1817
+ /**
1818
+ * 查找第一个匹配标签的父节点
1819
+ * @param className 类名
1820
+ * @returns 父节点
1821
+ */
1822
+ findFirstParentByTags(className) {
1823
+ Step.assert(this.stepId);
1824
+ const node = AssistsX2.findFirstParentByTags(this, className);
1825
+ Step.assert(this.stepId);
1826
+ return node;
1827
+ }
1828
+ /**
1829
+ * 对节点执行点击手势
1830
+ * @param offsetX X轴偏移
1831
+ * @param offsetY Y轴偏移
1832
+ * @param switchWindowIntervalDelay 窗口切换延迟
1833
+ * @param clickDuration 点击持续时间
1834
+ * @returns 是否点击成功
1835
+ */
1836
+ async clickNodeByGesture({
1837
+ offsetX,
1838
+ offsetY,
1839
+ switchWindowIntervalDelay,
1840
+ clickDuration
1841
+ } = {}) {
1842
+ Step.assert(this.stepId);
1843
+ const result = await AssistsX2.clickNodeByGesture(this, {
1844
+ offsetX,
1845
+ offsetY,
1846
+ switchWindowIntervalDelay,
1847
+ clickDuration
1848
+ });
1849
+ Step.assert(this.stepId);
1850
+ return result;
1851
+ }
1852
+ /**
1853
+ * 对节点执行双击手势
1854
+ * @param offsetX X轴偏移
1855
+ * @param offsetY Y轴偏移
1856
+ * @param switchWindowIntervalDelay 窗口切换延迟
1857
+ * @param clickDuration 点击持续时间
1858
+ * @param clickInterval 点击间隔
1859
+ * @returns 是否双击成功
1860
+ */
1861
+ async doubleClickNodeByGesture({
1862
+ offsetX,
1863
+ offsetY,
1864
+ switchWindowIntervalDelay,
1865
+ clickDuration,
1866
+ clickInterval
1867
+ } = {}) {
1868
+ Step.assert(this.stepId);
1869
+ const result = await AssistsX2.doubleClickNodeByGesture(this, {
1870
+ offsetX,
1871
+ offsetY,
1872
+ switchWindowIntervalDelay,
1873
+ clickDuration,
1874
+ clickInterval
1875
+ });
1876
+ Step.assert(this.stepId);
1877
+ return result;
1878
+ }
1879
+ async longPressNodeByGestureAutoPaste(text, {
1880
+ matchedPackageName,
1881
+ matchedText,
1882
+ timeoutMillis,
1883
+ longPressDuration
1884
+ } = { matchedText: "\u7C98\u8D34", timeoutMillis: 1500, longPressDuration: 600 }) {
1885
+ Step.assert(this.stepId);
1886
+ const result = await AssistsX2.longPressNodeByGestureAutoPaste(this, text, {
1887
+ matchedPackageName,
1888
+ matchedText,
1889
+ timeoutMillis,
1890
+ longPressDuration
1891
+ });
1892
+ Step.assert(this.stepId);
1893
+ return result;
1894
+ }
1895
+ /**
1896
+ * 在当前节点范围内通过标签查找节点
1897
+ * @param className 类名
1898
+ * @param filterText 文本过滤
1899
+ * @param filterViewId 视图ID过滤
1900
+ * @param filterDes 描述过滤
1901
+ * @returns 节点数组
1902
+ */
1903
+ findByTags(className, {
1904
+ filterText,
1905
+ filterViewId,
1906
+ filterDes
1907
+ } = {}) {
1908
+ Step.assert(this.stepId);
1909
+ const result = AssistsX2.findByTags(className, {
1910
+ filterText,
1911
+ filterViewId,
1912
+ filterDes,
1913
+ node: this
1914
+ });
1915
+ Step.assignIdsToNodes(result, this.stepId);
1916
+ Step.assert(this.stepId);
1917
+ return result;
1918
+ }
1919
+ /**
1920
+ * 在当前节点范围内通过ID查找节点
1921
+ * @param id 节点ID
1922
+ * @param filterClass 类名过滤
1923
+ * @param filterText 文本过滤
1924
+ * @param filterDes 描述过滤
1925
+ * @returns 节点数组
1926
+ */
1927
+ findById(id, {
1928
+ filterClass,
1929
+ filterText,
1930
+ filterDes
1931
+ } = {}) {
1932
+ Step.assert(this.stepId);
1933
+ const result = AssistsX2.findById(id, {
1934
+ filterClass,
1935
+ filterText,
1936
+ filterDes,
1937
+ node: this
1938
+ });
1939
+ Step.assignIdsToNodes(result, this.stepId);
1940
+ Step.assert(this.stepId);
1941
+ return result;
1942
+ }
1943
+ /**
1944
+ * 在当前节点范围内通过文本查找节点
1945
+ * @param text 要查找的文本
1946
+ * @param filterClass 类名过滤
1947
+ * @param filterViewId 视图ID过滤
1948
+ * @param filterDes 描述过滤
1949
+ * @returns 节点数组
1950
+ */
1951
+ findByText(text, {
1952
+ filterClass,
1953
+ filterViewId,
1954
+ filterDes
1955
+ } = {}) {
1956
+ Step.assert(this.stepId);
1957
+ const result = AssistsX2.findByText(text, {
1958
+ filterClass,
1959
+ filterViewId,
1960
+ filterDes,
1961
+ node: this
1962
+ });
1963
+ Step.assignIdsToNodes(result, this.stepId);
1964
+ Step.assert(this.stepId);
1965
+ return result;
1966
+ }
1967
+ /**
1968
+ * 向前滚动节点
1969
+ * @returns 是否滚动成功
1970
+ */
1971
+ scrollForward() {
1972
+ Step.assert(this.stepId);
1973
+ const response = AssistsX2.scrollForward(this);
1974
+ Step.assert(this.stepId);
1975
+ return response;
1976
+ }
1977
+ /**
1978
+ * 向后滚动节点
1979
+ * @returns 是否滚动成功
1980
+ */
1981
+ scrollBackward() {
1982
+ Step.assert(this.stepId);
1983
+ const response = AssistsX2.scrollBackward(this);
1984
+ Step.assert(this.stepId);
1985
+ return response;
1986
+ }
1987
+ /**
1988
+ * 检查节点是否可见
1989
+ * @param compareNode 比较节点
1990
+ * @param isFullyByCompareNode 是否完全可见
1991
+ * @returns 是否可见
1992
+ */
1993
+ isVisible({
1994
+ compareNode,
1995
+ isFullyByCompareNode
1996
+ } = {}) {
1997
+ Step.assert(this.stepId);
1998
+ const response = AssistsX2.isVisible(this, {
1999
+ compareNode,
2000
+ isFullyByCompareNode
2001
+ });
2002
+ Step.assert(this.stepId);
2003
+ return response;
2004
+ }
2005
+ /**
2006
+ * 对节点进行截图
2007
+ * @param overlayHiddenScreenshotDelayMillis 截图延迟时间(毫秒)
2008
+ * @returns 截图路径
2009
+ */
2010
+ async takeScreenshot(overlayHiddenScreenshotDelayMillis = 250) {
2011
+ Step.assert(this.stepId);
2012
+ const result = await AssistsX2.takeScreenshotNodes(
2013
+ [this],
2014
+ overlayHiddenScreenshotDelayMillis
2015
+ );
2016
+ Step.assert(this.stepId);
2017
+ return result[0];
2018
+ }
2019
+ /**
2020
+ * 保存节点截图到文件
2021
+ * @param options 截图保存选项
2022
+ * @param options.filePath 文件路径(可选,不提供则自动生成)
2023
+ * @param options.format 图片格式,支持 "PNG"、"JPEG"、"JPG"、"WEBP",默认为 "PNG"
2024
+ * @param options.overlayHiddenScreenshotDelayMillis 截图延迟时间(毫秒),默认为 250
2025
+ * @returns 保存的文件路径
2026
+ */
2027
+ async takeScreenshotToFile(options = {}) {
2028
+ Step.assert(this.stepId);
2029
+ const result = await AssistsXAsync.takeScreenshotToFile({
2030
+ nodes: [this],
2031
+ ...options
2032
+ });
2033
+ Step.assert(this.stepId);
2034
+ return result[0];
2035
+ }
2036
+ /**
2037
+ * 设置节点文本
2038
+ * @param text 要设置的文本
2039
+ * @returns 是否设置成功
2040
+ */
2041
+ setNodeText(text) {
2042
+ Step.assert(this.stepId);
2043
+ const result = AssistsX2.setNodeText(this, text);
2044
+ Step.assert(this.stepId);
2045
+ return result;
2046
+ }
2047
+ paste(text) {
2048
+ Step.assert(this.stepId);
2049
+ const result = AssistsX2.paste(this, text);
2050
+ Step.assert(this.stepId);
2051
+ return result;
2052
+ }
2053
+ focus() {
2054
+ Step.assert(this.stepId);
2055
+ const result = AssistsX2.focus(this);
2056
+ Step.assert(this.stepId);
2057
+ return result;
2058
+ }
2059
+ /**
2060
+ * 点击节点
2061
+ * @returns 是否点击成功
2062
+ */
2063
+ click() {
2064
+ Step.assert(this.stepId);
2065
+ const result = AssistsX2.click(this);
2066
+ Step.assert(this.stepId);
2067
+ return result;
2068
+ }
2069
+ /**
2070
+ * 长按节点
2071
+ * @returns 是否长按成功
2072
+ */
2073
+ longClick() {
2074
+ Step.assert(this.stepId);
2075
+ const result = AssistsX2.longClick(this);
2076
+ Step.assert(this.stepId);
2077
+ return result;
2078
+ }
2079
+ /**
2080
+ * 查找第一个可点击的父节点
2081
+ * @returns 可点击的父节点
2082
+ */
2083
+ findFirstParentClickable() {
2084
+ Step.assert(this.stepId);
2085
+ const result = AssistsX2.findFirstParentClickable(this);
2086
+ Step.assert(this.stepId);
2087
+ Step.assignIdsToNodes([result], this.stepId);
2088
+ return result;
2089
+ }
2090
+ /**
2091
+ * 获取节点在屏幕中的边界
2092
+ * @returns 边界对象
2093
+ */
2094
+ getBoundsInScreen() {
2095
+ Step.assert(this.stepId);
2096
+ const result = AssistsX2.getBoundsInScreen(this);
2097
+ Step.assert(this.stepId);
2098
+ return result;
2099
+ }
2100
+ /**
2101
+ * 获取节点的所有子节点
2102
+ * @returns 子节点数组
2103
+ */
2104
+ getNodes() {
2105
+ Step.assert(this.stepId);
2106
+ const result = AssistsX2.getNodes(this);
2107
+ Step.assert(this.stepId);
2108
+ Step.assignIdsToNodes(result, this.stepId);
2109
+ return result;
2110
+ }
2111
+ /**
2112
+ * 获取节点的直接子节点
2113
+ * @returns 子节点数组
2114
+ */
2115
+ getChildren() {
2116
+ Step.assert(this.stepId);
2117
+ const result = AssistsX2.getChildren(this);
2118
+ Step.assert(this.stepId);
2119
+ Step.assignIdsToNodes(result, this.stepId);
2120
+ return result;
2121
+ }
2122
+ /**
2123
+ * 从JSON字符串创建节点实例
2124
+ * @param json JSON字符串
2125
+ * @returns 节点实例
2126
+ */
2127
+ static fromJSON(json) {
2128
+ const data = JSON.parse(json);
2129
+ return new _Node(data);
2130
+ }
2131
+ /**
2132
+ * 从普通对象创建节点实例
2133
+ * @param data 对象数据
2134
+ * @returns 节点实例
2135
+ */
2136
+ static from(data) {
2137
+ return new _Node(data);
2138
+ }
2139
+ /**
2140
+ * JSON.parse的reviver函数,用于将解析的JSON对象转换为Node实例
2141
+ * @param key 属性键
2142
+ * @param value 属性值
2143
+ * @returns 转换后的值
2144
+ */
2145
+ static reviver(key, value) {
2146
+ return key === "" ? new _Node(value) : value;
2147
+ }
2148
+ /**
2149
+ * 创建新的节点实例
2150
+ * @param params 节点参数对象
2151
+ * @returns 节点实例
2152
+ */
2153
+ static create(params) {
2154
+ return new _Node(params);
2155
+ }
2156
+ /**
2157
+ * 从JSON数组创建节点数组
2158
+ * @param array JSON数组
2159
+ * @returns 节点数组
2160
+ */
2161
+ static fromJSONArray(array) {
2162
+ if (!Array.isArray(array)) {
2163
+ throw new Error(
2164
+ `Node.fromJSONArray: Expected array, but got ${typeof array}. Value: ${JSON.stringify(array)}`
2165
+ );
2166
+ }
2167
+ return array.map((data) => new _Node(data));
2168
+ }
2169
+ };
2170
+
2171
+ // src/assistsx.ts
2172
+ var callbacks = /* @__PURE__ */ new Map();
2173
+ var accessibilityEventListeners = [];
2174
+ var screen;
2175
+ if (typeof window !== "undefined" && !window.assistsxCallback) {
2176
+ window.assistsxCallback = (data) => {
2177
+ let callbackId;
2178
+ try {
2179
+ const json = decodeBase64UTF8(data);
2180
+ const response = JSON.parse(json);
2181
+ callbackId = response.callbackId;
2182
+ if (callbackId) {
2183
+ const callback = callbacks.get(callbackId);
2184
+ if (callback) {
2185
+ callback(json);
2186
+ }
2187
+ }
2188
+ } catch (e) {
2189
+ console.log(e);
2190
+ } finally {
2191
+ if (callbackId) {
2192
+ callbacks.delete(callbackId);
2193
+ }
2194
+ }
2195
+ };
2196
+ }
2197
+ if (typeof window !== "undefined" && !window.onAccessibilityEvent) {
2198
+ window.onAccessibilityEvent = (event) => {
2199
+ accessibilityEventListeners.forEach((listener) => {
2200
+ try {
2201
+ const decodedEvent = decodeBase64UTF8(event);
2202
+ const parsedEvent = JSON.parse(decodedEvent);
2203
+ listener(parsedEvent);
2204
+ } catch (error) {
2205
+ console.error("Accessibility event listener error:", error);
2206
+ }
2207
+ });
2208
+ };
2209
+ }
2210
+ var AssistsX2 = class {
2211
+ /**
2212
+ * 屏幕尺寸(与全局变量 screen 同源)
2213
+ * @deprecated 已过时,请使用全局变量 {@link screen}
2214
+ */
2215
+ static get screenSize() {
2216
+ if (screen == null) return null;
2217
+ return {
2218
+ width: screen.width,
2219
+ height: screen.height,
2220
+ screenWidth: screen.width,
2221
+ screenHeight: screen.height
2222
+ };
2223
+ }
2224
+ /**
2225
+ * 执行同步调用
2226
+ * @param method 方法名
2227
+ * @param args 参数对象
2228
+ * @returns 调用响应
2229
+ */
2230
+ static call(method, { args, node } = {}) {
2231
+ const params = {
2232
+ method,
2233
+ arguments: args ? args : void 0,
2234
+ node: node ? node : void 0
2235
+ };
2236
+ const result = window.assistsx.call(JSON.stringify(params));
2237
+ if (typeof result === "string") {
2238
+ const responseData = JSON.parse(result);
2239
+ const response = new CallResponse(
2240
+ responseData.code,
2241
+ responseData.data,
2242
+ responseData.callbackId
2243
+ );
2244
+ return response;
2245
+ }
2246
+ throw new Error("Call failed");
2247
+ }
2248
+ /**
2249
+ * 执行异步调用
2250
+ * @param method 方法名
2251
+ * @param args 参数对象
2252
+ * @param timeout 超时时间(秒),默认30秒
2253
+ * @returns Promise<调用响应>
2254
+ */
2255
+ static async asyncCall(method, {
2256
+ args,
2257
+ node,
2258
+ nodes,
2259
+ timeout = 30
2260
+ } = {}) {
2261
+ const uuid = generateUUID();
2262
+ const params = {
2263
+ method,
2264
+ arguments: args ? args : void 0,
2265
+ node: node ? node : void 0,
2266
+ nodes: nodes ? nodes : void 0,
2267
+ callbackId: uuid
2268
+ };
2269
+ const promise = new Promise((resolve) => {
2270
+ callbacks.set(uuid, (data) => {
2271
+ resolve(data);
2272
+ });
2273
+ setTimeout(() => {
2274
+ callbacks.delete(uuid);
2275
+ resolve(new CallResponse(0, null, uuid));
2276
+ }, timeout * 1e3);
2277
+ });
2278
+ const result = window.assistsx.call(JSON.stringify(params));
2279
+ const promiseResult = await promise;
2280
+ if (typeof promiseResult === "string") {
2281
+ const responseData = JSON.parse(promiseResult);
2282
+ const response = new CallResponse(
2283
+ responseData.code,
2284
+ responseData.data,
2285
+ responseData.callbackId
2286
+ );
2287
+ return response;
2288
+ }
2289
+ throw new Error("Call failed");
2290
+ }
2291
+ /**
2292
+ * 设置悬浮窗标志
2293
+ * @param flags 标志
2294
+ * @returns 是否设置成功
2295
+ */
2296
+ static setOverlayFlags(flags) {
2297
+ const response = this.call(CallMethod.setOverlayFlags, {
2298
+ args: { flags }
2299
+ });
2300
+ return response.getDataOrDefault(false);
2301
+ }
2302
+ /**
2303
+ * 设置悬浮窗标志
2304
+ * @param flags 标志
2305
+ * @returns 是否设置成功
2306
+ */
2307
+ static setOverlayFlagList(flags) {
2308
+ const response = this.call(CallMethod.setOverlayFlags, {
2309
+ args: { flags }
2310
+ });
2311
+ return response.getDataOrDefault(false);
2312
+ }
2313
+ /**
2314
+ * 获取所有符合条件的节点
2315
+ * @param filterClass 类名过滤
2316
+ * @param filterViewId 视图ID过滤
2317
+ * @param filterDes 描述过滤
2318
+ * @param filterText 文本过滤
2319
+ * @returns 节点数组
2320
+ */
2321
+ static getAllNodes({
2322
+ filterClass,
2323
+ filterViewId,
2324
+ filterDes,
2325
+ filterText,
2326
+ scope
2327
+ } = {}) {
2328
+ const response = this.call(CallMethod.getAllNodes, {
2329
+ args: {
2330
+ filterClass,
2331
+ filterViewId,
2332
+ filterDes,
2333
+ filterText,
2334
+ ...scope !== void 0 ? { scope } : {}
2335
+ }
2336
+ });
2337
+ const data = response.getDataOrDefault([]);
2338
+ if (!Array.isArray(data)) {
2339
+ throw new Error(
2340
+ `AssistsX.getAllNodes: Expected array, but got ${typeof data}. Value: ${JSON.stringify(data)}`
2341
+ );
2342
+ }
2343
+ return Node.fromJSONArray(data);
2344
+ }
2345
+ /**
2346
+ * 设置节点文本
2347
+ * @param node 目标节点
2348
+ * @param text 要设置的文本
2349
+ * @returns 是否设置成功
2350
+ */
2351
+ static setNodeText(node, text) {
2352
+ const response = this.call(CallMethod.setNodeText, {
2353
+ args: { text },
2354
+ node
2355
+ });
2356
+ return response.getDataOrDefault(false);
2357
+ }
2358
+ /**
2359
+ * 获取剪贴板最新文本
2360
+ * @returns 剪贴板最新文本
2361
+ */
2362
+ static getClipboardLatestText() {
2363
+ const response = this.call(CallMethod.getClipboardLatestText);
2364
+ return response.getDataOrDefault({});
2365
+ }
2366
+ /**
2367
+ * 获取剪贴板文本内容(异步)
2368
+ * @param timeout 超时时间(秒),默认30秒
2369
+ * @returns 剪贴板文本内容,如果获取失败则返回空字符串
2370
+ */
2371
+ static async getClipboardText(timeout) {
2372
+ const response = await this.asyncCall(CallMethod.getClipboardText, {
2373
+ timeout
2374
+ });
2375
+ const data = response.getDataOrDefault({ text: "" });
2376
+ return data.text || "";
2377
+ }
2378
+ /**
2379
+ * 在浏览器中打开URL
2380
+ * @param url 要打开的URL
2381
+ * @returns 是否成功打开
2382
+ */
2383
+ static openUrlInBrowser(url) {
2384
+ const response = this.call(CallMethod.openUrlInBrowser, {
2385
+ args: { url }
2386
+ });
2387
+ return response.getDataOrDefault(false);
2388
+ }
2389
+ /**
2390
+ * 保持屏幕常亮
2391
+ * @param tip 提示文本
2392
+ * @returns 是否保持屏幕常亮成功
2393
+ */
2394
+ static keepScreenOn(tip) {
2395
+ const response = this.call(CallMethod.keepScreenOn, {
2396
+ args: { tip }
2397
+ });
2398
+ return response.getDataOrDefault(false);
2399
+ }
2400
+ static clearKeepScreenOn() {
2401
+ const response = this.call(CallMethod.clearKeepScreenOn, {});
2402
+ return response.getDataOrDefault(false);
2403
+ }
2404
+ static isAppInstalled(packageName) {
2405
+ const response = this.call(CallMethod.isAppInstalled, {
2406
+ args: { packageName }
2407
+ });
2408
+ return response.getDataOrDefault(false);
2409
+ }
2410
+ /**
2411
+ * 对指定节点进行截图
2412
+ * @param nodes 要截图的节点数组
2413
+ * @param overlayHiddenScreenshotDelayMillis 截图延迟时间(毫秒)
2414
+ * @param timeout 超时时间(秒),默认30秒
2415
+ * @returns 截图路径数组
2416
+ */
2417
+ static async takeScreenshotNodes(nodes, overlayHiddenScreenshotDelayMillis = 250, timeout) {
2418
+ const response = await this.asyncCall(CallMethod.takeScreenshot, {
2419
+ nodes,
2420
+ args: { overlayHiddenScreenshotDelayMillis },
2421
+ timeout
2422
+ });
2423
+ const data = response.getDataOrDefault({ images: [] });
2424
+ return data.images;
2425
+ }
2426
+ static async scanQR(timeout) {
2427
+ const response = await this.asyncCall(CallMethod.scanQR, { timeout });
2428
+ const data = response.getDataOrDefault({ value: "" });
2429
+ return data.value;
2430
+ }
2431
+ static async loadWebViewOverlay(url, options = {}) {
2432
+ const {
2433
+ initialWidth,
2434
+ initialHeight,
2435
+ initialX,
2436
+ initialY,
2437
+ minWidth,
2438
+ minHeight,
2439
+ maxWidth,
2440
+ maxHeight,
2441
+ initialCenter,
2442
+ showTopOperationArea,
2443
+ showBottomOperationArea,
2444
+ backgroundColor,
2445
+ timeout
2446
+ } = options;
2447
+ const response = await this.asyncCall(CallMethod.loadWebViewOverlay, {
2448
+ args: {
2449
+ url,
2450
+ initialWidth,
2451
+ initialHeight,
2452
+ initialX,
2453
+ initialY,
2454
+ minWidth,
2455
+ minHeight,
2456
+ maxWidth,
2457
+ maxHeight,
2458
+ initialCenter,
2459
+ showTopOperationArea,
2460
+ showBottomOperationArea,
2461
+ backgroundColor
2462
+ },
2463
+ timeout
2464
+ });
2465
+ const data = response.getDataOrDefault({});
2466
+ return data;
2467
+ }
2468
+ /**
2469
+ * 点击节点
2470
+ * @param node 要点击的节点
2471
+ * @returns 是否点击成功
2472
+ */
2473
+ static click(node) {
2474
+ const response = this.call(CallMethod.click, { node });
2475
+ return response.getDataOrDefault(false);
2476
+ }
2477
+ /**
2478
+ * 长按节点
2479
+ * @param node 要长按的节点
2480
+ * @returns 是否长按成功
2481
+ */
2482
+ static longClick(node) {
2483
+ const response = this.call(CallMethod.longClick, { node });
2484
+ return response.getDataOrDefault(false);
2485
+ }
2486
+ /**
2487
+ * 启动应用
2488
+ * @param packageName 应用包名
2489
+ * @returns 是否启动成功
2490
+ */
2491
+ static launchApp(packageName) {
2492
+ const response = this.call(CallMethod.launchApp, { args: { packageName } });
2493
+ return response.getDataOrDefault(false);
2494
+ }
2495
+ /**
2496
+ * 获取当前应用包名
2497
+ * @returns 包名
2498
+ */
2499
+ static getPackageName(options = {}) {
2500
+ const { scope } = options;
2501
+ const response = this.call(
2502
+ CallMethod.getPackageName,
2503
+ scope !== void 0 ? { args: { scope } } : {}
2504
+ );
2505
+ return response.getDataOrDefault("");
2506
+ }
2507
+ /**
2508
+ * 显示悬浮提示
2509
+ * @param text 提示文本
2510
+ * @param delay 显示时长(毫秒)
2511
+ * @returns 是否显示成功
2512
+ */
2513
+ static overlayToast(text, delay = 2e3) {
2514
+ const response = this.call(CallMethod.overlayToast, {
2515
+ args: { text, delay }
2516
+ });
2517
+ return response.getDataOrDefault(false);
2518
+ }
2519
+ /**
2520
+ * 通过ID查找节点
2521
+ * @param id 节点ID
2522
+ * @param filterClass 类名过滤
2523
+ * @param filterText 文本过滤
2524
+ * @param filterDes 描述过滤
2525
+ * @param node 父节点范围
2526
+ * @returns 节点数组
2527
+ */
2528
+ static findById(id, {
2529
+ filterClass,
2530
+ filterText,
2531
+ filterDes,
2532
+ node,
2533
+ scope
2534
+ } = {}) {
2535
+ const response = this.call(CallMethod.findById, {
2536
+ args: {
2537
+ id,
2538
+ filterClass,
2539
+ filterText,
2540
+ filterDes,
2541
+ ...scope !== void 0 ? { scope } : {}
2542
+ },
2543
+ node
2544
+ });
2545
+ const data = response.getDataOrDefault([]);
2546
+ if (!Array.isArray(data)) {
2547
+ throw new Error(
2548
+ `AssistsX.findById: Expected array, but got ${typeof data}. Value: ${JSON.stringify(data)}`
2549
+ );
2550
+ }
2551
+ return Node.fromJSONArray(data);
2552
+ }
2553
+ /**
2554
+ * 通过文本查找节点
2555
+ * @param text 要查找的文本
2556
+ * @param filterClass 类名过滤
2557
+ * @param filterViewId 视图ID过滤
2558
+ * @param filterDes 描述过滤
2559
+ * @param node 父节点范围
2560
+ * @returns 节点数组
2561
+ */
2562
+ static findByText(text, {
2563
+ filterClass,
2564
+ filterViewId,
2565
+ filterDes,
2566
+ node,
2567
+ scope
2568
+ } = {}) {
2569
+ const response = this.call(CallMethod.findByText, {
2570
+ args: {
2571
+ text,
2572
+ filterClass,
2573
+ filterViewId,
2574
+ filterDes,
2575
+ ...scope !== void 0 ? { scope } : {}
2576
+ },
2577
+ node
2578
+ });
2579
+ const data = response.getDataOrDefault([]);
2580
+ if (!Array.isArray(data)) {
2581
+ throw new Error(
2582
+ `AssistsX.findByText: Expected array, but got ${typeof data}. Value: ${JSON.stringify(data)}`
2583
+ );
2584
+ }
2585
+ return Node.fromJSONArray(data);
2586
+ }
2587
+ /**
2588
+ * 通过标签查找节点
2589
+ * @param className 类名
2590
+ * @param filterText 文本过滤
2591
+ * @param filterViewId 视图ID过滤
2592
+ * @param filterDes 描述过滤
2593
+ * @param node 父节点范围
2594
+ * @returns 节点数组
2595
+ */
2596
+ static findByTags(className, {
2597
+ filterText,
2598
+ filterViewId,
2599
+ filterDes,
2600
+ node,
2601
+ scope
2602
+ } = {}) {
2603
+ const response = this.call(CallMethod.findByTags, {
2604
+ args: {
2605
+ className,
2606
+ filterText,
2607
+ filterViewId,
2608
+ filterDes,
2609
+ ...scope !== void 0 ? { scope } : {}
2610
+ },
2611
+ node
2612
+ });
2613
+ const data = response.getDataOrDefault([]);
2614
+ if (!Array.isArray(data)) {
2615
+ throw new Error(
2616
+ `AssistsX.findByTags: Expected array, but got ${typeof data}. Value: ${JSON.stringify(data)}`
2617
+ );
2618
+ }
2619
+ return Node.fromJSONArray(data);
2620
+ }
2621
+ /**
2622
+ * 查找所有匹配文本的节点
2623
+ * @param text 要查找的文本
2624
+ * @param options.scope 节点查找范围(可选)
2625
+ */
2626
+ static findByTextAllMatch(text, { scope } = {}) {
2627
+ const response = this.call(CallMethod.findByTextAllMatch, {
2628
+ args: {
2629
+ text,
2630
+ ...scope !== void 0 ? { scope } : {}
2631
+ }
2632
+ });
2633
+ const data = response.getDataOrDefault([]);
2634
+ if (!Array.isArray(data)) {
2635
+ throw new Error(
2636
+ `AssistsX.findByTextAllMatch: Expected array, but got ${typeof data}. Value: ${JSON.stringify(data)}`
2637
+ );
2638
+ }
2639
+ return Node.fromJSONArray(data);
2640
+ }
2641
+ /**
2642
+ * 检查是否包含指定文本
2643
+ * @param text 要检查的文本
2644
+ * @returns 是否包含
2645
+ */
2646
+ static containsText(text) {
2647
+ const response = this.call(CallMethod.containsText, { args: { text } });
2648
+ return response.getDataOrDefault(false);
2649
+ }
2650
+ /**
2651
+ * 获取所有文本
2652
+ * @returns 文本数组
2653
+ */
2654
+ static getAllText() {
2655
+ const response = this.call(CallMethod.getAllText);
2656
+ const data = response.getDataOrDefault([]);
2657
+ if (!Array.isArray(data)) {
2658
+ throw new Error(
2659
+ `AssistsX.getAllText: Expected array, but got ${typeof data}. Value: ${JSON.stringify(data)}`
2660
+ );
2661
+ }
2662
+ return data;
2663
+ }
2664
+ /**
2665
+ * 查找第一个匹配标签的父节点
2666
+ * @param className 类名
2667
+ * @returns 父节点
2668
+ */
2669
+ static findFirstParentByTags(node, className) {
2670
+ const response = this.call(CallMethod.findFirstParentByTags, {
2671
+ args: { className },
2672
+ node
2673
+ });
2674
+ return Node.create(response.getDataOrDefault({}));
2675
+ }
2676
+ /**
2677
+ * 获取节点的所有子节点
2678
+ * @param node 父节点
2679
+ * @returns 子节点数组
2680
+ */
2681
+ static getNodes(node) {
2682
+ const response = this.call(CallMethod.getNodes, { node });
2683
+ const data = response.getDataOrDefault([]);
2684
+ if (!Array.isArray(data)) {
2685
+ throw new Error(
2686
+ `AssistsX.getNodes: Expected array, but got ${typeof data}. Value: ${JSON.stringify(data)}`
2687
+ );
2688
+ }
2689
+ return Node.fromJSONArray(data);
2690
+ }
2691
+ /**
2692
+ * 获取节点的直接子节点
2693
+ * @param node 父节点
2694
+ * @returns 子节点数组
2695
+ */
2696
+ static getChildren(node) {
2697
+ const response = this.call(CallMethod.getChildren, { node });
2698
+ const data = response.getDataOrDefault([]);
2699
+ if (!Array.isArray(data)) {
2700
+ throw new Error(
2701
+ `AssistsX.getChildren: Expected array, but got ${typeof data}. Value: ${JSON.stringify(data)}`
2702
+ );
2703
+ }
2704
+ return Node.fromJSONArray(data);
2705
+ }
2706
+ /**
2707
+ * 查找第一个可点击的父节点
2708
+ * @param node 起始节点
2709
+ * @returns 可点击的父节点
2710
+ */
2711
+ static findFirstParentClickable(node) {
2712
+ const response = this.call(CallMethod.findFirstParentClickable, { node });
2713
+ return Node.create(response.getDataOrDefault({}));
2714
+ }
2715
+ /**
2716
+ * 获取节点在屏幕中的边界
2717
+ * @param node 目标节点
2718
+ * @returns 边界对象
2719
+ */
2720
+ static getBoundsInScreen(node) {
2721
+ const response = this.call(CallMethod.getBoundsInScreen, { node });
2722
+ return Bounds.fromData(response.getDataOrDefault({}));
2723
+ }
2724
+ /**
2725
+ * 检查节点是否可见
2726
+ * @param node 目标节点
2727
+ * @param compareNode 比较节点
2728
+ * @param isFullyByCompareNode 是否完全可见
2729
+ * @returns 是否可见
2730
+ */
2731
+ static isVisible(node, {
2732
+ compareNode,
2733
+ isFullyByCompareNode
2734
+ } = {}) {
2735
+ const response = this.call(CallMethod.isVisible, {
2736
+ node,
2737
+ args: { compareNode, isFullyByCompareNode }
2738
+ });
2739
+ return response.getDataOrDefault(false);
2740
+ }
2741
+ /**
2742
+ * 执行点击手势
2743
+ * @param x 横坐标
2744
+ * @param y 纵坐标
2745
+ * @param duration 持续时间
2746
+ * @param timeout 超时时间(秒),默认30秒
2747
+ * @returns 是否成功
2748
+ */
2749
+ static async clickByGesture(x, y, duration, timeout) {
2750
+ const response = await this.asyncCall(CallMethod.clickByGesture, {
2751
+ args: { x, y, duration },
2752
+ timeout
2753
+ });
2754
+ return response.getDataOrDefault(false);
2755
+ }
2756
+ /**
2757
+ * 返回操作
2758
+ * @returns 是否成功
2759
+ */
2760
+ static back() {
2761
+ const response = this.call(CallMethod.back);
2762
+ return response.getDataOrDefault(false);
2763
+ }
2764
+ /**
2765
+ * 回到主页
2766
+ * @returns 是否成功
2767
+ */
2768
+ static home() {
2769
+ const response = this.call(CallMethod.home);
2770
+ return response.getDataOrDefault(false);
2771
+ }
2772
+ /**
2773
+ * 打开通知栏
2774
+ * @returns 是否成功
2775
+ */
2776
+ static notifications() {
2777
+ const response = this.call(CallMethod.notifications);
2778
+ return response.getDataOrDefault(false);
2779
+ }
2780
+ /**
2781
+ * 显示最近应用
2782
+ * @returns 是否成功
2783
+ */
2784
+ static recentApps() {
2785
+ const response = this.call(CallMethod.recentApps);
2786
+ return response.getDataOrDefault(false);
2787
+ }
2788
+ /**
2789
+ * 在节点中粘贴文本
2790
+ * @param node 目标节点
2791
+ * @param text 要粘贴的文本
2792
+ * @returns 是否成功
2793
+ */
2794
+ static paste(node, text) {
2795
+ const response = this.call(CallMethod.paste, { args: { text }, node });
2796
+ return response.getDataOrDefault(false);
2797
+ }
2798
+ static focus(node) {
2799
+ const response = this.call(CallMethod.focus, { node });
2800
+ return response.getDataOrDefault(false);
2801
+ }
2802
+ /**
2803
+ * 选择文本
2804
+ * @param node 目标节点
2805
+ * @param selectionStart 选择起始位置
2806
+ * @param selectionEnd 选择结束位置
2807
+ * @returns 是否成功
2808
+ */
2809
+ static selectionText(node, selectionStart, selectionEnd) {
2810
+ const response = this.call(CallMethod.selectionText, {
2811
+ args: { selectionStart, selectionEnd },
2812
+ node
2813
+ });
2814
+ return response.getDataOrDefault(false);
2815
+ }
2816
+ /**
2817
+ * 向前滚动
2818
+ * @param node 可滚动节点
2819
+ * @returns 是否成功
2820
+ */
2821
+ static scrollForward(node) {
2822
+ const response = this.call(CallMethod.scrollForward, { node });
2823
+ return response.getDataOrDefault(false);
2824
+ }
2825
+ /**
2826
+ * 向后滚动
2827
+ * @param node 可滚动节点
2828
+ * @returns 是否成功
2829
+ */
2830
+ static scrollBackward(node) {
2831
+ const response = this.call(CallMethod.scrollBackward, { node });
2832
+ return response.getDataOrDefault(false);
2833
+ }
2834
+ /**
2835
+ * 对节点执行点击手势
2836
+ * @param node 目标节点
2837
+ * @param offsetX X轴偏移
2838
+ * @param offsetY Y轴偏移
2839
+ * @param switchWindowIntervalDelay 窗口切换延迟
2840
+ * @param clickDuration 点击持续时间
2841
+ * @param timeout 超时时间(秒),默认30秒
2842
+ * @returns 是否成功
2843
+ */
2844
+ static async clickNodeByGesture(node, {
2845
+ offsetX,
2846
+ offsetY,
2847
+ switchWindowIntervalDelay,
2848
+ clickDuration,
2849
+ timeout
2850
+ } = {}) {
2851
+ const response = await this.asyncCall(CallMethod.clickNodeByGesture, {
2852
+ node,
2853
+ args: { offsetX, offsetY, switchWindowIntervalDelay, clickDuration },
2854
+ timeout
2855
+ });
2856
+ return response.getDataOrDefault(false);
2857
+ }
2858
+ /**
2859
+ * 对节点执行双击手势
2860
+ * @param node 目标节点
2861
+ * @param offsetX X轴偏移
2862
+ * @param offsetY Y轴偏移
2863
+ * @param switchWindowIntervalDelay 窗口切换延迟
2864
+ * @param clickDuration 点击持续时间
2865
+ * @param clickInterval 点击间隔
2866
+ * @param timeout 超时时间(秒),默认30秒
2867
+ * @returns 是否成功
2868
+ */
2869
+ static async doubleClickNodeByGesture(node, {
2870
+ offsetX,
2871
+ offsetY,
2872
+ switchWindowIntervalDelay,
2873
+ clickDuration,
2874
+ clickInterval,
2875
+ timeout
2876
+ } = {}) {
2877
+ const response = await this.asyncCall(CallMethod.doubleClickNodeByGesture, {
2878
+ node,
2879
+ args: {
2880
+ offsetX,
2881
+ offsetY,
2882
+ switchWindowIntervalDelay,
2883
+ clickDuration,
2884
+ clickInterval
2885
+ },
2886
+ timeout
2887
+ });
2888
+ return response.getDataOrDefault(false);
2889
+ }
2890
+ /**
2891
+ * 执行线型手势
2892
+ * @param startPoint
2893
+ * @param endPoint
2894
+ * @param param2
2895
+ * @param timeout 超时时间(秒),默认30秒
2896
+ * @returns
2897
+ */
2898
+ static async performLinearGesture(startPoint, endPoint, { duration, timeout } = {}) {
2899
+ const response = await this.asyncCall(CallMethod.performLinearGesture, {
2900
+ args: { startPoint, endPoint, duration },
2901
+ timeout
2902
+ });
2903
+ return response.getDataOrDefault(false);
2904
+ }
2905
+ static async longPressNodeByGestureAutoPaste(node, text, {
2906
+ matchedPackageName,
2907
+ matchedText,
2908
+ timeoutMillis,
2909
+ longPressDuration,
2910
+ timeout
2911
+ } = { matchedText: "\u7C98\u8D34", timeoutMillis: 1500, longPressDuration: 600 }) {
2912
+ const response = await this.asyncCall(
2913
+ CallMethod.longPressGestureAutoPaste,
2914
+ {
2915
+ node,
2916
+ args: {
2917
+ text,
2918
+ matchedPackageName,
2919
+ matchedText,
2920
+ timeoutMillis,
2921
+ longPressDuration
2922
+ },
2923
+ timeout
2924
+ }
2925
+ );
2926
+ return response.getDataOrDefault(false);
2927
+ }
2928
+ static async longPressGestureAutoPaste(point, text, {
2929
+ matchedPackageName,
2930
+ matchedText,
2931
+ timeoutMillis,
2932
+ longPressDuration,
2933
+ timeout
2934
+ } = { matchedText: "\u7C98\u8D34", timeoutMillis: 1500, longPressDuration: 600 }) {
2935
+ const response = await this.asyncCall(
2936
+ CallMethod.longPressGestureAutoPaste,
2937
+ {
2938
+ args: {
2939
+ point,
2940
+ text,
2941
+ matchedPackageName,
2942
+ matchedText,
2943
+ timeoutMillis,
2944
+ longPressDuration
2945
+ },
2946
+ timeout
2947
+ }
2948
+ );
2949
+ return response.getDataOrDefault(false);
2950
+ }
2951
+ static async getAppInfo(packageName, timeout) {
2952
+ const response = await this.asyncCall(CallMethod.getAppInfo, {
2953
+ args: { packageName },
2954
+ timeout
2955
+ });
2956
+ return AppInfo.fromJSON(response.getDataOrDefault({}));
2957
+ }
2958
+ static getUniqueDeviceId() {
2959
+ const response = this.call(CallMethod.getUniqueDeviceId);
2960
+ return response.getDataOrDefault("");
2961
+ }
2962
+ static getAndroidID() {
2963
+ const response = this.call(CallMethod.getAndroidID);
2964
+ return response.getDataOrDefault("");
2965
+ }
2966
+ static async getMacAddress(timeout) {
2967
+ const response = await this.asyncCall(CallMethod.getMacAddress, {
2968
+ timeout
2969
+ });
2970
+ return response.getDataOrDefault({});
2971
+ }
2972
+ static async getDeviceInfo(timeout) {
2973
+ const response = await this.asyncCall(CallMethod.getDeviceInfo, {
2974
+ timeout
2975
+ });
2976
+ return DeviceInfo.fromJSON(response.getDataOrDefault({}));
2977
+ }
2978
+ static async getNetworkType(timeout) {
2979
+ const response = await this.asyncCall(CallMethod.getNetworkType, {
2980
+ timeout
2981
+ });
2982
+ return response.getDataOrDefault({});
2983
+ }
2984
+ /**
2985
+ * 播放系统电话铃声
2986
+ * @param timeout 超时时间(秒),默认30秒
2987
+ * @returns 播放结果消息
2988
+ */
2989
+ static async audioPlayRingtone(timeout) {
2990
+ const response = await this.asyncCall(CallMethod.audioPlayRingtone, {
2991
+ timeout
2992
+ });
2993
+ return response.getDataOrDefault("");
2994
+ }
2995
+ /**
2996
+ * 停止播放系统电话铃声
2997
+ * @param timeout 超时时间(秒),默认30秒
2998
+ * @returns 停止结果消息
2999
+ */
3000
+ static async audioStopRingtone(timeout) {
3001
+ const response = await this.asyncCall(CallMethod.audioStopRingtone, {
3002
+ timeout
3003
+ });
3004
+ return response.getDataOrDefault("");
3005
+ }
3006
+ static async setAccessibilityEventFilters(value) {
3007
+ const response = this.call(CallMethod.setAccessibilityEventFilters, {
3008
+ args: { value }
3009
+ });
3010
+ return response.getDataOrDefault({});
3011
+ }
3012
+ static async addAccessibilityEventFilter(value) {
3013
+ const response = this.call(CallMethod.addAccessibilityEventFilter, {
3014
+ args: { value }
3015
+ });
3016
+ return response.getDataOrDefault({});
3017
+ }
3018
+ /**
3019
+ * 获取屏幕尺寸
3020
+ * @returns 屏幕尺寸对象(width, height)
3021
+ */
3022
+ static getScreenSize() {
3023
+ const response = this.call(CallMethod.getScreenSize);
3024
+ const data = response.getDataOrDefault({});
3025
+ return normalizeScreen(data);
3026
+ }
3027
+ /**
3028
+ * 获取应用窗口尺寸
3029
+ * @returns 应用窗口尺寸对象
3030
+ */
3031
+ static getAppScreenSize() {
3032
+ const response = this.call(CallMethod.getAppScreenSize);
3033
+ return response.getDataOrDefault({});
3034
+ }
3035
+ /**
3036
+ * 添加无障碍事件监听器
3037
+ * @param listener 监听器函数
3038
+ */
3039
+ static addAccessibilityEventListener(listener) {
3040
+ accessibilityEventListeners.push(listener);
3041
+ }
3042
+ /**
3043
+ * 判断是否包含无障碍事件监听器
3044
+ * @param listener 监听器函数
3045
+ * @returns 是否包含
3046
+ */
3047
+ static containsAccessibilityEventListener(listener) {
3048
+ return accessibilityEventListeners.indexOf(listener) > -1;
3049
+ }
3050
+ /**
3051
+ * 移除无障碍事件监听器
3052
+ * @param listener 要移除的监听器函数
3053
+ * @returns 是否移除成功
3054
+ */
3055
+ static removeAccessibilityEventListener(listener) {
3056
+ const index = accessibilityEventListeners.indexOf(listener);
3057
+ if (index > -1) {
3058
+ accessibilityEventListeners.splice(index, 1);
3059
+ return true;
3060
+ }
3061
+ return false;
3062
+ }
3063
+ /**
3064
+ * 移除所有无障碍事件监听器
3065
+ */
3066
+ static removeAllAccessibilityEventListeners() {
3067
+ accessibilityEventListeners.length = 0;
3068
+ }
3069
+ /**
3070
+ * 获取当前注册的无障碍事件监听器数量
3071
+ * @returns 监听器数量
3072
+ */
3073
+ static getAccessibilityEventListenerCount() {
3074
+ return accessibilityEventListeners.length;
3075
+ }
3076
+ };
3077
+ function normalizeScreen(data) {
3078
+ if (data == null) return null;
3079
+ const w = typeof data.width === "number" ? data.width : data.screenWidth;
3080
+ const h = typeof data.height === "number" ? data.height : data.screenHeight;
3081
+ if (typeof w !== "number" || typeof h !== "number") return null;
3082
+ return { width: Math.floor(w), height: Math.floor(h) };
3083
+ }
3084
+ var _a;
3085
+ if (typeof window !== "undefined") {
3086
+ try {
3087
+ if (window.assistsx && typeof window.assistsx.call === "function") {
3088
+ screen = (_a = AssistsX2.getScreenSize()) != null ? _a : { width: 0, height: 0 };
3089
+ }
3090
+ } catch (e) {
3091
+ console.log("Failed to initialize screen size:", e);
3092
+ }
3093
+ }
3094
+
3095
+ // src/step-state-store.ts
3096
+ import { defineStore } from "pinia";
3097
+ var useStepStore = defineStore("step", {
3098
+ state: () => ({
3099
+ status: "idle",
3100
+ stepId: void 0,
3101
+ tag: void 0,
3102
+ data: void 0,
3103
+ error: void 0
3104
+ }),
3105
+ actions: {
3106
+ // 开始执行步骤
3107
+ startStep(stepId, tag, data) {
3108
+ this.status = "running";
3109
+ this.stepId = stepId;
3110
+ this.tag = tag;
3111
+ this.data = data;
3112
+ this.error = void 0;
3113
+ },
3114
+ // 完成步骤
3115
+ completeStep() {
3116
+ this.status = "completed";
3117
+ },
3118
+ // 步骤出错
3119
+ setError(error) {
3120
+ this.status = "error";
3121
+ this.error = error;
3122
+ },
3123
+ // 重置状态
3124
+ reset() {
3125
+ this.status = "idle";
3126
+ this.stepId = void 0;
3127
+ this.tag = void 0;
3128
+ this.data = void 0;
3129
+ this.error = void 0;
3130
+ }
3131
+ }
3132
+ });
3133
+
3134
+ // src/pinia-ensure.ts
3135
+ import { createPinia, getActivePinia, setActivePinia } from "pinia";
3136
+ var fallbackPinia = null;
3137
+ function ensureAssistsXPinia() {
3138
+ if (getActivePinia() !== void 0) return;
3139
+ if (fallbackPinia === null) {
3140
+ fallbackPinia = createPinia();
3141
+ }
3142
+ setActivePinia(fallbackPinia);
3143
+ }
3144
+
3145
+ // src/step-error.ts
3146
+ var StepError = class extends Error {
3147
+ constructor(message, data, impl, tag, originalError, currentStep) {
3148
+ super(message);
3149
+ this.name = "StepError";
3150
+ this.data = data;
3151
+ this.impl = impl;
3152
+ this.tag = tag;
3153
+ this.originalError = originalError;
3154
+ this.currentStep = currentStep;
3155
+ }
3156
+ };
3157
+ var StepStopError = class extends StepError {
3158
+ constructor(message, data) {
3159
+ super(message || "\u4E3B\u52A8\u4E2D\u65AD\u6B65\u9AA4", data);
3160
+ this.name = "StepStopError";
3161
+ }
3162
+ };
3163
+
3164
+ // src/step-async.ts
3165
+ var StepAsync = class {
3166
+ /**
3167
+ * 构造函数
3168
+ * @param step Step实例
3169
+ */
3170
+ constructor(step) {
3171
+ this.step = step;
3172
+ }
3173
+ /**
3174
+ * 对单个节点进行截图
3175
+ * @param node 目标节点
3176
+ * @param overlayHiddenScreenshotDelayMillis 截图延迟时间(毫秒)
3177
+ * @returns 截图路径
3178
+ */
3179
+ async takeScreenshotByNode(node, overlayHiddenScreenshotDelayMillis = 250) {
3180
+ Step.assert(this.step.stepId);
3181
+ const result = await AssistsXAsync.takeScreenshotNodes(
3182
+ [node],
3183
+ overlayHiddenScreenshotDelayMillis
3184
+ );
3185
+ Step.assert(this.step.stepId);
3186
+ return result[0];
3187
+ }
3188
+ /**
3189
+ * 对多个节点进行截图
3190
+ * @param nodes 目标节点数组
3191
+ * @param overlayHiddenScreenshotDelayMillis 截图延迟时间(毫秒)
3192
+ * @returns 截图路径数组
3193
+ */
3194
+ async takeScreenshotNodes(nodes, overlayHiddenScreenshotDelayMillis = 250) {
3195
+ Step.assert(this.step.stepId);
3196
+ const result = await AssistsXAsync.takeScreenshotNodes(
3197
+ nodes,
3198
+ overlayHiddenScreenshotDelayMillis
3199
+ );
3200
+ Step.assert(this.step.stepId);
3201
+ return result;
3202
+ }
3203
+ /**
3204
+ * 获取所有符合条件的节点
3205
+ * @param filterClass 类名过滤
3206
+ * @param filterViewId 视图ID过滤
3207
+ * @param filterDes 描述过滤
3208
+ * @param filterText 文本过滤
3209
+ * @returns 节点数组
3210
+ */
3211
+ async getAllNodes({
3212
+ filterClass,
3213
+ filterViewId,
3214
+ filterDes,
3215
+ filterText,
3216
+ scope
3217
+ } = {}) {
3218
+ Step.assert(this.step.stepId);
3219
+ const nodes = await AssistsXAsync.getAllNodes({
3220
+ filterClass,
3221
+ filterViewId,
3222
+ filterDes,
3223
+ filterText,
3224
+ scope
3225
+ });
3226
+ Step.assert(this.step.stepId);
3227
+ Step.assignIdsToNodes(nodes, this.step.stepId);
3228
+ return nodes;
3229
+ }
3230
+ /**
3231
+ * 启动应用
3232
+ * @param packageName 应用包名
3233
+ * @returns 是否启动成功
3234
+ */
3235
+ async launchApp(packageName) {
3236
+ Step.assert(this.step.stepId);
3237
+ const result = await AssistsXAsync.launchApp(packageName);
3238
+ Step.assert(this.step.stepId);
3239
+ return result;
3240
+ }
3241
+ async getPackageName(timeoutOrOptions) {
3242
+ Step.assert(this.step.stepId);
3243
+ const result = typeof timeoutOrOptions === "number" ? await AssistsXAsync.getPackageName(timeoutOrOptions) : await AssistsXAsync.getPackageName(timeoutOrOptions != null ? timeoutOrOptions : {});
3244
+ Step.assert(this.step.stepId);
3245
+ return result;
3246
+ }
3247
+ /**
3248
+ * 通过ID查找节点
3249
+ * @param id 节点ID
3250
+ * @param filterClass 类名过滤
3251
+ * @param filterText 文本过滤
3252
+ * @param filterDes 描述过滤
3253
+ * @returns 节点数组
3254
+ */
3255
+ async findById(id, {
3256
+ filterClass,
3257
+ filterText,
3258
+ filterDes,
3259
+ scope
3260
+ } = {}) {
3261
+ Step.assert(this.step.stepId);
3262
+ const nodes = await AssistsXAsync.findById(id, {
3263
+ filterClass,
3264
+ filterText,
3265
+ filterDes,
3266
+ scope
3267
+ });
3268
+ Step.assert(this.step.stepId);
3269
+ Step.assignIdsToNodes(nodes, this.step.stepId);
3270
+ return nodes;
3271
+ }
3272
+ /**
3273
+ * 通过文本查找节点
3274
+ * @param text 要查找的文本
3275
+ * @param filterClass 类名过滤
3276
+ * @param filterViewId 视图ID过滤
3277
+ * @param filterDes 描述过滤
3278
+ * @returns 节点数组
3279
+ */
3280
+ async findByText(text, {
3281
+ filterClass,
3282
+ filterViewId,
3283
+ filterDes,
3284
+ scope
3285
+ } = {}) {
3286
+ Step.assert(this.step.stepId);
3287
+ const nodes = await AssistsXAsync.findByText(text, {
3288
+ filterClass,
3289
+ filterViewId,
3290
+ filterDes,
3291
+ scope
3292
+ });
3293
+ Step.assert(this.step.stepId);
3294
+ Step.assignIdsToNodes(nodes, this.step.stepId);
3295
+ return nodes;
3296
+ }
3297
+ /**
3298
+ * 通过标签查找节点
3299
+ * @param className 类名
3300
+ * @param filterText 文本过滤
3301
+ * @param filterViewId 视图ID过滤
3302
+ * @param filterDes 描述过滤
3303
+ * @returns 节点数组
3304
+ */
3305
+ async findByTags(className, {
3306
+ filterText,
3307
+ filterViewId,
3308
+ filterDes,
3309
+ scope
3310
+ } = {}) {
3311
+ Step.assert(this.step.stepId);
3312
+ const nodes = await AssistsXAsync.findByTags(className, {
3313
+ filterText,
3314
+ filterViewId,
3315
+ filterDes,
3316
+ scope
3317
+ });
3318
+ Step.assert(this.step.stepId);
3319
+ Step.assignIdsToNodes(nodes, this.step.stepId);
3320
+ return nodes;
3321
+ }
3322
+ async findByTextAllMatch(text, timeoutOrOptions) {
3323
+ Step.assert(this.step.stepId);
3324
+ const nodes = typeof timeoutOrOptions === "number" ? await AssistsXAsync.findByTextAllMatch(text, timeoutOrOptions) : timeoutOrOptions !== void 0 ? await AssistsXAsync.findByTextAllMatch(text, timeoutOrOptions) : await AssistsXAsync.findByTextAllMatch(text);
3325
+ Step.assert(this.step.stepId);
3326
+ Step.assignIdsToNodes(nodes, this.step.stepId);
3327
+ return nodes;
3328
+ }
3329
+ /**
3330
+ * 检查是否包含指定文本
3331
+ * @param text 要检查的文本
3332
+ * @returns 是否包含
3333
+ */
3334
+ async containsText(text) {
3335
+ Step.assert(this.step.stepId);
3336
+ const result = await AssistsXAsync.containsText(text);
3337
+ Step.assert(this.step.stepId);
3338
+ return result;
3339
+ }
3340
+ /**
3341
+ * 获取所有文本
3342
+ * @returns 文本数组
3343
+ */
3344
+ async getAllText() {
3345
+ Step.assert(this.step.stepId);
3346
+ const texts = await AssistsXAsync.getAllText();
3347
+ Step.assert(this.step.stepId);
3348
+ return texts;
3349
+ }
3350
+ /**
3351
+ * 执行点击手势
3352
+ * @param x 横坐标
3353
+ * @param y 纵坐标
3354
+ * @param duration 持续时间(毫秒)
3355
+ * @returns 是否成功
3356
+ */
3357
+ async clickByGesture(x, y, duration) {
3358
+ Step.assert(this.step.stepId);
3359
+ const result = await AssistsXAsync.clickByGesture(x, y, duration);
3360
+ Step.assert(this.step.stepId);
3361
+ return result;
3362
+ }
3363
+ async longPressGestureAutoPaste(point, text, {
3364
+ matchedPackageName,
3365
+ matchedText,
3366
+ timeoutMillis,
3367
+ longPressDuration
3368
+ } = { matchedText: "\u7C98\u8D34", timeoutMillis: 1500, longPressDuration: 600 }) {
3369
+ Step.assert(this.step.stepId);
3370
+ const result = await AssistsXAsync.longPressGestureAutoPaste(point, text, {
3371
+ matchedPackageName,
3372
+ matchedText,
3373
+ timeoutMillis,
3374
+ longPressDuration
3375
+ });
3376
+ Step.assert(this.step.stepId);
3377
+ return result;
3378
+ }
3379
+ async getAppInfo(packageName) {
3380
+ Step.assert(this.step.stepId);
3381
+ const result = await AssistsXAsync.getAppInfo(packageName);
3382
+ Step.assert(this.step.stepId);
3383
+ return result;
3384
+ }
3385
+ async performLinearGesture(startPoint, endPoint, { duration } = {}) {
3386
+ Step.assert(this.step.stepId);
3387
+ const result = await AssistsXAsync.performLinearGesture(
3388
+ startPoint,
3389
+ endPoint,
3390
+ {
3391
+ duration
3392
+ }
3393
+ );
3394
+ Step.assert(this.step.stepId);
3395
+ return result;
3396
+ }
3397
+ /**
3398
+ * 返回操作
3399
+ * @returns 是否成功
3400
+ */
3401
+ async back() {
3402
+ Step.assert(this.step.stepId);
3403
+ const result = await AssistsXAsync.back();
3404
+ Step.assert(this.step.stepId);
3405
+ return result;
3406
+ }
3407
+ /**
3408
+ * 回到主页
3409
+ * @returns 是否成功
3410
+ */
3411
+ async home() {
3412
+ Step.assert(this.step.stepId);
3413
+ const result = await AssistsXAsync.home();
3414
+ Step.assert(this.step.stepId);
3415
+ return result;
3416
+ }
3417
+ /**
3418
+ * 打开通知栏
3419
+ * @returns 是否成功
3420
+ */
3421
+ async notifications() {
3422
+ Step.assert(this.step.stepId);
3423
+ const result = await AssistsXAsync.notifications();
3424
+ Step.assert(this.step.stepId);
3425
+ return result;
3426
+ }
3427
+ /**
3428
+ * 显示最近应用
3429
+ * @returns 是否成功
3430
+ */
3431
+ async recentApps() {
3432
+ Step.assert(this.step.stepId);
3433
+ const result = await AssistsXAsync.recentApps();
3434
+ Step.assert(this.step.stepId);
3435
+ return result;
3436
+ }
3437
+ /**
3438
+ * 获取屏幕尺寸
3439
+ * @returns 屏幕尺寸对象
3440
+ */
3441
+ async getScreenSize() {
3442
+ Step.assert(this.step.stepId);
3443
+ const data = await AssistsXAsync.getScreenSize();
3444
+ Step.assert(this.step.stepId);
3445
+ return data;
3446
+ }
3447
+ /**
3448
+ * 获取应用窗口尺寸
3449
+ * @returns 应用窗口尺寸对象
3450
+ */
3451
+ async getAppScreenSize() {
3452
+ Step.assert(this.step.stepId);
3453
+ const data = await AssistsXAsync.getAppScreenSize();
3454
+ Step.assert(this.step.stepId);
3455
+ return data;
3456
+ }
3457
+ };
3458
+
3459
+ // src/step.ts
3460
+ var _Step = class _Step {
3461
+ /**
3462
+ * 构造函数
3463
+ * @param stepId 步骤ID
3464
+ * @param impl 步骤实现函数
3465
+ * @param tag 步骤标签
3466
+ * @param data 步骤数据
3467
+ * @param delayMs 步骤延迟时间(毫秒)
3468
+ */
3469
+ constructor({
3470
+ stepId,
3471
+ impl,
3472
+ tag,
3473
+ data,
3474
+ delayMs = _Step.delayMsDefault,
3475
+ repeatCountMax = _Step.repeatCountMaxDefault,
3476
+ exceptionRetryCountMax = _Step.exceptionRetryCountMaxDefault,
3477
+ isEnd = false
3478
+ }) {
3479
+ /**
3480
+ * 步骤ID
3481
+ */
3482
+ this.stepId = "";
3483
+ /**
3484
+ * 步骤重复执行次数
3485
+ */
3486
+ this.repeatCount = 0;
3487
+ /**
3488
+ * 步骤重复执行最大次数,默认15次
3489
+ */
3490
+ this.repeatCountMax = _Step.repeatCountMaxDefault;
3491
+ /**
3492
+ * 异常重试次数
3493
+ */
3494
+ this.exceptionRetryCount = 0;
3495
+ /**
3496
+ * 异常重试最大次数,默认3次
3497
+ */
3498
+ this.exceptionRetryCountMax = _Step.exceptionRetryCountMaxDefault;
3499
+ this.isEnd = false;
3500
+ /**
3501
+ * 步骤延迟时间(毫秒)
3502
+ */
3503
+ this.delayMs = _Step.delayMsDefault;
3504
+ this.tag = tag;
3505
+ this.stepId = stepId;
3506
+ this.data = _Step.resolveStepData(data);
3507
+ this.impl = impl;
3508
+ this.delayMs = delayMs;
3509
+ this.repeatCountMax = repeatCountMax;
3510
+ this.exceptionRetryCountMax = exceptionRetryCountMax;
3511
+ this.isEnd = isEnd;
3512
+ }
3513
+ /**
3514
+ * 判断步骤数据是否有效(非空且为普通对象)
3515
+ */
3516
+ static isValidStepData(data) {
3517
+ return data !== null && data !== void 0 && typeof data === "object" && !Array.isArray(data);
3518
+ }
3519
+ /**
3520
+ * 解析步骤数据:优先使用传入值,否则使用当前值,均无效时返回空对象
3521
+ */
3522
+ static resolveStepData(provided, fallback) {
3523
+ if (provided !== void 0 && _Step.isValidStepData(provided)) {
3524
+ return provided;
3525
+ }
3526
+ if (fallback !== void 0 && _Step.isValidStepData(fallback)) {
3527
+ return fallback;
3528
+ }
3529
+ return {};
3530
+ }
3531
+ /**
3532
+ * 运行步骤实现
3533
+ * @param impl 步骤实现函数
3534
+ * @param tag 步骤标签
3535
+ * @param data 步骤数据
3536
+ * @param delayMs 步骤延迟时间(毫秒)
3537
+ */
3538
+ static async run(impl, {
3539
+ stepId,
3540
+ tag,
3541
+ data,
3542
+ delayMs = _Step.delayMsDefault,
3543
+ exceptionRetryCountMax = _Step.exceptionRetryCountMaxDefault
3544
+ } = {}) {
3545
+ var _a2, _b, _c, _d, _e, _f;
3546
+ this.exception = void 0;
3547
+ ensureAssistsXPinia();
3548
+ const stepStore = useStepStore();
3549
+ const resolvedData = _Step.resolveStepData(data);
3550
+ let implnName = impl.name;
3551
+ let currentStep;
3552
+ let nextStep;
3553
+ try {
3554
+ if (stepId) {
3555
+ this._stepId = stepId;
3556
+ if (_Step.showLog) {
3557
+ console.log(`\u4F7F\u7528\u4F20\u5165\u6B65\u9AA4ID: ${this._stepId}`);
3558
+ }
3559
+ } else {
3560
+ this._stepId = generateUUID();
3561
+ if (_Step.showLog) {
3562
+ console.log(`\u751F\u6210\u6B65\u9AA4ID: ${this._stepId}`);
3563
+ }
3564
+ }
3565
+ stepStore.startStep(this._stepId, tag, resolvedData);
3566
+ currentStep = new _Step({
3567
+ stepId: this._stepId,
3568
+ impl,
3569
+ tag,
3570
+ data: resolvedData,
3571
+ delayMs,
3572
+ exceptionRetryCountMax
3573
+ });
3574
+ while (true) {
3575
+ let interceptedStep = void 0;
3576
+ let stepForRetry = currentStep;
3577
+ try {
3578
+ if (currentStep.delayMs) {
3579
+ if (_Step.showLog) {
3580
+ console.log(`\u5EF6\u8FDF${currentStep.delayMs}\u6BEB\u79D2`);
3581
+ }
3582
+ await currentStep.delay(currentStep.delayMs);
3583
+ _Step.assert(currentStep.stepId);
3584
+ }
3585
+ implnName = (_b = (_a2 = currentStep.impl) == null ? void 0 : _a2.name) != null ? _b : "undefined";
3586
+ if (_Step.showLog) {
3587
+ console.log(
3588
+ `\u6267\u884C\u6B65\u9AA4${implnName}\uFF0C\u91CD\u590D\u6B21\u6570${currentStep.repeatCount}`
3589
+ );
3590
+ }
3591
+ for (const interceptor of this._interceptors) {
3592
+ try {
3593
+ const result = await interceptor(currentStep);
3594
+ if (result) {
3595
+ interceptedStep = result;
3596
+ if (_Step.showLog) {
3597
+ console.log(`\u6B65\u9AA4${implnName}\u88AB\u62E6\u622A\u5668\u62E6\u622A\uFF0C\u6267\u884C\u62E6\u622A\u540E\u7684\u6B65\u9AA4`);
3598
+ }
3599
+ break;
3600
+ }
3601
+ } catch (e) {
3602
+ if (_Step.showLog) {
3603
+ console.error(`\u62E6\u622A\u5668\u6267\u884C\u51FA\u9519`, e);
3604
+ }
3605
+ }
3606
+ }
3607
+ stepForRetry = currentStep;
3608
+ if (interceptedStep !== void 0) {
3609
+ const stepToExecute = interceptedStep;
3610
+ stepForRetry = stepToExecute;
3611
+ if (stepToExecute.delayMs) {
3612
+ if (_Step.showLog) {
3613
+ console.log(`\u62E6\u622A\u6B65\u9AA4\u5EF6\u8FDF${stepToExecute.delayMs}\u6BEB\u79D2`);
3614
+ }
3615
+ await stepToExecute.delay(stepToExecute.delayMs);
3616
+ _Step.assert(stepToExecute.stepId);
3617
+ }
3618
+ const interceptedImplName = (_c = stepToExecute.impl) == null ? void 0 : _c.name;
3619
+ if (_Step.showLog) {
3620
+ console.log(
3621
+ `\u6267\u884C\u62E6\u622A\u6B65\u9AA4${interceptedImplName}\uFF0C\u91CD\u590D\u6B21\u6570${stepToExecute.repeatCount}`
3622
+ );
3623
+ }
3624
+ nextStep = await ((_d = stepToExecute.impl) == null ? void 0 : _d.call(stepToExecute, stepToExecute));
3625
+ } else {
3626
+ nextStep = await ((_e = currentStep.impl) == null ? void 0 : _e.call(currentStep, currentStep));
3627
+ }
3628
+ if (currentStep.repeatCountMax > _Step.repeatCountInfinite && currentStep.repeatCount >= currentStep.repeatCountMax) {
3629
+ if (_Step.showLog) {
3630
+ console.log(
3631
+ `\u91CD\u590D\u6B21\u6570${currentStep.repeatCount}\u8D85\u8FC7\u6700\u5927\u6B21\u6570${currentStep.repeatCountMax}\uFF0C\u505C\u6B62\u6267\u884C`
3632
+ );
3633
+ }
3634
+ throw new StepError("\u6B65\u9AA4\u91CD\u590D\u6B21\u6570\u8FBE\u5230\u6700\u5927\u6B21\u6570", { stepId: currentStep.stepId, repeatCount: currentStep.repeatCount, repeatCountMax: currentStep.repeatCountMax });
3635
+ }
3636
+ _Step.assert(currentStep.stepId);
3637
+ stepForRetry.exceptionRetryCount = 0;
3638
+ if (nextStep) {
3639
+ currentStep = nextStep;
3640
+ if (currentStep.isEnd) {
3641
+ if (_Step.showLog) {
3642
+ console.log(`\u6B65\u9AA4${implnName}\u7ED3\u675F`);
3643
+ }
3644
+ break;
3645
+ }
3646
+ } else {
3647
+ break;
3648
+ }
3649
+ } catch (e) {
3650
+ if ((e == null ? void 0 : e.message) === "\u6B65\u9AA4\u91CD\u590D\u6B21\u6570\u8FBE\u5230\u6700\u5927\u6B21\u6570") {
3651
+ throw e;
3652
+ }
3653
+ stepForRetry.exceptionRetryCount++;
3654
+ if (stepForRetry.exceptionRetryCount < stepForRetry.exceptionRetryCountMax) {
3655
+ if (_Step.showLog) {
3656
+ console.warn(
3657
+ `\u6B65\u9AA4${implnName}\u6267\u884C\u5F02\u5E38\uFF0C\u91CD\u8BD5\u7B2C${stepForRetry.exceptionRetryCount}\u6B21\uFF0C\u6700\u5927\u91CD\u8BD5\u6B21\u6570${stepForRetry.exceptionRetryCountMax}`,
3658
+ e
3659
+ );
3660
+ }
3661
+ continue;
3662
+ } else {
3663
+ if (_Step.showLog) {
3664
+ console.error(
3665
+ `\u6B65\u9AA4${implnName}\u6267\u884C\u5F02\u5E38\uFF0C\u5DF2\u8FBE\u5230\u6700\u5927\u91CD\u8BD5\u6B21\u6570${stepForRetry.exceptionRetryCountMax}\uFF0C\u505C\u6B62\u91CD\u8BD5`,
3666
+ e
3667
+ );
3668
+ }
3669
+ throw e;
3670
+ }
3671
+ }
3672
+ }
3673
+ stepStore.completeStep();
3674
+ } catch (e) {
3675
+ console.error(`\u6B65\u9AA4${implnName}\u6267\u884C\u51FA\u9519`, e);
3676
+ const errorMsg = JSON.stringify({
3677
+ impl: implnName,
3678
+ tag,
3679
+ data: resolvedData,
3680
+ error: (_f = e == null ? void 0 : e.message) != null ? _f : String(e)
3681
+ });
3682
+ stepStore.setError(errorMsg);
3683
+ throw e;
3684
+ }
3685
+ return currentStep;
3686
+ }
3687
+ /**
3688
+ * 获取当前步骤ID
3689
+ */
3690
+ static get stepId() {
3691
+ return this._stepId;
3692
+ }
3693
+ /**
3694
+ * 验证步骤ID是否匹配,如果不匹配则表示停止
3695
+ * @param stepId 要验证的步骤ID
3696
+ */
3697
+ static assert(stepId) {
3698
+ if (_Step.exception) {
3699
+ throw _Step.exception;
3700
+ }
3701
+ if (stepId && _Step.stepId != stepId) {
3702
+ throw new StepError("StepId mismatch", { stepId, currentStepId: _Step.stepId });
3703
+ }
3704
+ }
3705
+ /**
3706
+ * 为节点数组分配步骤ID
3707
+ * @param nodes 节点数组
3708
+ * @param stepId 步骤ID
3709
+ */
3710
+ static assignIdsToNodes(nodes, stepId) {
3711
+ if (stepId) {
3712
+ nodes.forEach((node) => {
3713
+ node.stepId = stepId;
3714
+ });
3715
+ }
3716
+ }
3717
+ /**
3718
+ * 停止当前步骤执行
3719
+ * @param exception 可选的异常对象,如果传入则使用该异常,否则使用默认的StepStopError
3720
+ */
3721
+ static stop(exception) {
3722
+ this._stepId = "STEP_STOP";
3723
+ if (exception) {
3724
+ this.exception = exception;
3725
+ } else {
3726
+ this.exception = new StepStopError("\u4E3B\u52A8\u4E2D\u65AD\u6B65\u9AA4", { stepId: this._stepId });
3727
+ }
3728
+ }
3729
+ /**
3730
+ * 添加步骤拦截器
3731
+ * @param interceptor 拦截器函数
3732
+ */
3733
+ static addInterceptor(interceptor) {
3734
+ this._interceptors.push(interceptor);
3735
+ }
3736
+ /**
3737
+ * 移除步骤拦截器
3738
+ * @param interceptor 要移除的拦截器函数
3739
+ * @returns 是否成功删除
3740
+ */
3741
+ static removeInterceptor(interceptor) {
3742
+ const index = this._interceptors.indexOf(interceptor);
3743
+ if (index > -1) {
3744
+ this._interceptors.splice(index, 1);
3745
+ return true;
3746
+ }
3747
+ return false;
3748
+ }
3749
+ /**
3750
+ * 按索引移除步骤拦截器
3751
+ * @param index 要移除的拦截器索引
3752
+ * @returns 是否成功删除
3753
+ */
3754
+ static removeInterceptorByIndex(index) {
3755
+ if (index >= 0 && index < this._interceptors.length) {
3756
+ this._interceptors.splice(index, 1);
3757
+ return true;
3758
+ }
3759
+ return false;
3760
+ }
3761
+ /**
3762
+ * 移除所有匹配的步骤拦截器
3763
+ * @param interceptor 要移除的拦截器函数
3764
+ * @returns 删除的拦截器数量
3765
+ */
3766
+ static removeAllInterceptors(interceptor) {
3767
+ let removedCount = 0;
3768
+ for (let i = this._interceptors.length - 1; i >= 0; i--) {
3769
+ if (this._interceptors[i] === interceptor) {
3770
+ this._interceptors.splice(i, 1);
3771
+ removedCount++;
3772
+ }
3773
+ }
3774
+ return removedCount;
3775
+ }
3776
+ /**
3777
+ * 按条件移除步骤拦截器
3778
+ * @param predicate 判断是否删除的条件函数
3779
+ * @returns 删除的拦截器数量
3780
+ */
3781
+ static removeInterceptorByPredicate(predicate) {
3782
+ let removedCount = 0;
3783
+ for (let i = this._interceptors.length - 1; i >= 0; i--) {
3784
+ if (predicate(this._interceptors[i], i)) {
3785
+ this._interceptors.splice(i, 1);
3786
+ removedCount++;
3787
+ }
3788
+ }
3789
+ return removedCount;
3790
+ }
3791
+ /**
3792
+ * 清空所有拦截器
3793
+ */
3794
+ static clearInterceptors() {
3795
+ this._interceptors = [];
3796
+ }
3797
+ /**
3798
+ * 获取所有拦截器
3799
+ * @returns 拦截器数组
3800
+ */
3801
+ static getInterceptors() {
3802
+ return [...this._interceptors];
3803
+ }
3804
+ get async() {
3805
+ return new StepAsync(this);
3806
+ }
3807
+ /**
3808
+ * 创建下一个步骤
3809
+ * @param impl 下一步骤实现函数
3810
+ * @param tag 步骤标签
3811
+ * @param data 步骤数据
3812
+ * @param delayMs 步骤延迟时间(毫秒)
3813
+ * @returns 新的步骤实例
3814
+ */
3815
+ next(impl, {
3816
+ tag,
3817
+ data,
3818
+ delayMs = _Step.delayMsDefault,
3819
+ repeatCountMax = _Step.repeatCountMaxDefault,
3820
+ exceptionRetryCountMax = _Step.exceptionRetryCountMaxDefault
3821
+ } = {}) {
3822
+ _Step.assert(this.stepId);
3823
+ return new _Step({
3824
+ stepId: this.stepId,
3825
+ impl,
3826
+ tag,
3827
+ data: _Step.resolveStepData(data, this.data),
3828
+ delayMs,
3829
+ repeatCountMax,
3830
+ exceptionRetryCountMax
3831
+ });
3832
+ }
3833
+ end({
3834
+ tag,
3835
+ data,
3836
+ delayMs = _Step.delayMsDefault,
3837
+ repeatCountMax = _Step.repeatCountMaxDefault,
3838
+ exceptionRetryCountMax = _Step.exceptionRetryCountMaxDefault
3839
+ } = {}) {
3840
+ _Step.assert(this.stepId);
3841
+ return new _Step({
3842
+ stepId: this.stepId,
3843
+ impl: void 0,
3844
+ tag,
3845
+ data: _Step.resolveStepData(data, this.data),
3846
+ delayMs,
3847
+ repeatCountMax,
3848
+ exceptionRetryCountMax,
3849
+ isEnd: true
3850
+ });
3851
+ }
3852
+ /**
3853
+ * 重复当前步骤
3854
+ * @param stepId 步骤ID
3855
+ * @param tag 步骤标签
3856
+ * @param data 步骤数据
3857
+ * @param delayMs 步骤延迟时间(毫秒)
3858
+ * @returns 当前步骤实例
3859
+ */
3860
+ repeat({
3861
+ stepId = this.stepId,
3862
+ tag = this.tag,
3863
+ data,
3864
+ delayMs = this.delayMs,
3865
+ repeatCountMax = this.repeatCountMax,
3866
+ exceptionRetryCountMax = this.exceptionRetryCountMax
3867
+ } = {}) {
3868
+ _Step.assert(this.stepId);
3869
+ this.repeatCount++;
3870
+ this.stepId = stepId;
3871
+ this.tag = tag;
3872
+ this.data = _Step.resolveStepData(data, this.data);
3873
+ this.delayMs = delayMs;
3874
+ this.repeatCountMax = repeatCountMax;
3875
+ this.exceptionRetryCountMax = exceptionRetryCountMax;
3876
+ this.exceptionRetryCount = 0;
3877
+ return this;
3878
+ }
3879
+ /**
3880
+ * 延迟执行
3881
+ * @param ms 延迟时间(毫秒)
3882
+ * @returns Promise
3883
+ */
3884
+ async delay(ms) {
3885
+ while (true) {
3886
+ ms -= 100;
3887
+ if (ms <= 0) {
3888
+ break;
3889
+ }
3890
+ await new Promise((resolve) => setTimeout(resolve, 100));
3891
+ _Step.assert(this.stepId);
3892
+ }
3893
+ }
3894
+ /**
3895
+ * 等待异步方法执行完成
3896
+ * @param method 异步方法
3897
+ * @returns Promise<T>
3898
+ */
3899
+ async await(method) {
3900
+ _Step.assert(this.stepId);
3901
+ const result = await method();
3902
+ _Step.assert(this.stepId);
3903
+ return result;
3904
+ }
3905
+ /**
3906
+ * 对单个节点进行截图
3907
+ * @param node 目标节点
3908
+ * @param overlayHiddenScreenshotDelayMillis 截图延迟时间(毫秒)
3909
+ * @returns 截图路径
3910
+ */
3911
+ async takeScreenshotByNode(node, overlayHiddenScreenshotDelayMillis = 250) {
3912
+ _Step.assert(this.stepId);
3913
+ const result = await AssistsX2.takeScreenshotNodes(
3914
+ [node],
3915
+ overlayHiddenScreenshotDelayMillis
3916
+ );
3917
+ _Step.assert(this.stepId);
3918
+ return result[0];
3919
+ }
3920
+ /**
3921
+ * 对多个节点进行截图
3922
+ * @param nodes 目标节点数组
3923
+ * @param overlayHiddenScreenshotDelayMillis 截图延迟时间(毫秒)
3924
+ * @returns 截图路径数组
3925
+ */
3926
+ async takeScreenshotNodes(nodes, overlayHiddenScreenshotDelayMillis = 250) {
3927
+ _Step.assert(this.stepId);
3928
+ const result = await AssistsX2.takeScreenshotNodes(
3929
+ nodes,
3930
+ overlayHiddenScreenshotDelayMillis
3931
+ );
3932
+ _Step.assert(this.stepId);
3933
+ return result;
3934
+ }
3935
+ /**
3936
+ * 获取所有符合条件的节点
3937
+ * @param filterClass 类名过滤
3938
+ * @param filterViewId 视图ID过滤
3939
+ * @param filterDes 描述过滤
3940
+ * @param filterText 文本过滤
3941
+ * @returns 节点数组
3942
+ */
3943
+ getAllNodes({
3944
+ filterClass,
3945
+ filterViewId,
3946
+ filterDes,
3947
+ filterText,
3948
+ scope
3949
+ } = {}) {
3950
+ _Step.assert(this.stepId);
3951
+ const nodes = AssistsX2.getAllNodes({
3952
+ filterClass,
3953
+ filterViewId,
3954
+ filterDes,
3955
+ filterText,
3956
+ scope
3957
+ });
3958
+ _Step.assert(this.stepId);
3959
+ _Step.assignIdsToNodes(nodes, this.stepId);
3960
+ return nodes;
3961
+ }
3962
+ /**
3963
+ * 启动应用
3964
+ * @param packageName 应用包名
3965
+ * @returns 是否启动成功
3966
+ */
3967
+ launchApp(packageName) {
3968
+ _Step.assert(this.stepId);
3969
+ const result = AssistsX2.launchApp(packageName);
3970
+ _Step.assert(this.stepId);
3971
+ return result;
3972
+ }
3973
+ /**
3974
+ * 获取当前应用包名
3975
+ * @param options.scope 节点查找范围(可选)
3976
+ */
3977
+ getPackageName(options = {}) {
3978
+ _Step.assert(this.stepId);
3979
+ const result = AssistsX2.getPackageName(options);
3980
+ _Step.assert(this.stepId);
3981
+ return result;
3982
+ }
3983
+ /**
3984
+ * 通过ID查找节点
3985
+ * @param id 节点ID
3986
+ * @param filterClass 类名过滤
3987
+ * @param filterText 文本过滤
3988
+ * @param filterDes 描述过滤
3989
+ * @returns 节点数组
3990
+ */
3991
+ findById(id, {
3992
+ filterClass,
3993
+ filterText,
3994
+ filterDes,
3995
+ scope
3996
+ } = {}) {
3997
+ _Step.assert(this.stepId);
3998
+ const nodes = AssistsX2.findById(id, {
3999
+ filterClass,
4000
+ filterText,
4001
+ filterDes,
4002
+ scope
4003
+ });
4004
+ _Step.assert(this.stepId);
4005
+ _Step.assignIdsToNodes(nodes, this.stepId);
4006
+ return nodes;
4007
+ }
4008
+ /**
4009
+ * 通过文本查找节点
4010
+ * @param text 要查找的文本
4011
+ * @param filterClass 类名过滤
4012
+ * @param filterViewId 视图ID过滤
4013
+ * @param filterDes 描述过滤
4014
+ * @returns 节点数组
4015
+ */
4016
+ findByText(text, {
4017
+ filterClass,
4018
+ filterViewId,
4019
+ filterDes,
4020
+ scope
4021
+ } = {}) {
4022
+ _Step.assert(this.stepId);
4023
+ const nodes = AssistsX2.findByText(text, {
4024
+ filterClass,
4025
+ filterViewId,
4026
+ filterDes,
4027
+ scope
4028
+ });
4029
+ _Step.assert(this.stepId);
4030
+ _Step.assignIdsToNodes(nodes, this.stepId);
4031
+ return nodes;
4032
+ }
4033
+ /**
4034
+ * 通过标签查找节点
4035
+ * @param className 类名
4036
+ * @param filterText 文本过滤
4037
+ * @param filterViewId 视图ID过滤
4038
+ * @param filterDes 描述过滤
4039
+ * @returns 节点数组
4040
+ */
4041
+ findByTags(className, {
4042
+ filterText,
4043
+ filterViewId,
4044
+ filterDes,
4045
+ scope
4046
+ } = {}) {
4047
+ _Step.assert(this.stepId);
4048
+ const nodes = AssistsX2.findByTags(className, {
4049
+ filterText,
4050
+ filterViewId,
4051
+ filterDes,
4052
+ scope
4053
+ });
4054
+ _Step.assert(this.stepId);
4055
+ _Step.assignIdsToNodes(nodes, this.stepId);
4056
+ return nodes;
4057
+ }
4058
+ /**
4059
+ * 查找所有匹配文本的节点
4060
+ * @param text 要查找的文本
4061
+ * @param options.scope 节点查找范围(可选)
4062
+ */
4063
+ findByTextAllMatch(text, { scope } = {}) {
4064
+ _Step.assert(this.stepId);
4065
+ const nodes = AssistsX2.findByTextAllMatch(text, { scope });
4066
+ _Step.assert(this.stepId);
4067
+ _Step.assignIdsToNodes(nodes, this.stepId);
4068
+ return nodes;
4069
+ }
4070
+ /**
4071
+ * 检查是否包含指定文本
4072
+ * @param text 要检查的文本
4073
+ * @returns 是否包含
4074
+ */
4075
+ containsText(text) {
4076
+ _Step.assert(this.stepId);
4077
+ const result = AssistsX2.containsText(text);
4078
+ _Step.assert(this.stepId);
4079
+ return result;
4080
+ }
4081
+ /**
4082
+ * 获取所有文本
4083
+ * @returns 文本数组
4084
+ */
4085
+ getAllText() {
4086
+ _Step.assert(this.stepId);
4087
+ const texts = AssistsX2.getAllText();
4088
+ _Step.assert(this.stepId);
4089
+ return texts;
4090
+ }
4091
+ /**
4092
+ * 执行点击手势
4093
+ * @param x 横坐标
4094
+ * @param y 纵坐标
4095
+ * @param duration 持续时间(毫秒)
4096
+ * @returns 是否成功
4097
+ */
4098
+ async clickByGesture(x, y, duration) {
4099
+ _Step.assert(this.stepId);
4100
+ const result = await AssistsX2.clickByGesture(x, y, duration);
4101
+ _Step.assert(this.stepId);
4102
+ return result;
4103
+ }
4104
+ async longPressGestureAutoPaste(point, text, {
4105
+ matchedPackageName,
4106
+ matchedText,
4107
+ timeoutMillis,
4108
+ longPressDuration
4109
+ } = { matchedText: "\u7C98\u8D34", timeoutMillis: 1500, longPressDuration: 600 }) {
4110
+ _Step.assert(this.stepId);
4111
+ const result = await AssistsX2.longPressGestureAutoPaste(point, text, {
4112
+ matchedPackageName,
4113
+ matchedText,
4114
+ timeoutMillis,
4115
+ longPressDuration
4116
+ });
4117
+ _Step.assert(this.stepId);
4118
+ return result;
4119
+ }
4120
+ async getAppInfo(packageName) {
4121
+ _Step.assert(this.stepId);
4122
+ const result = await AssistsX2.getAppInfo(packageName);
4123
+ _Step.assert(this.stepId);
4124
+ return result;
4125
+ }
4126
+ async performLinearGesture(startPoint, endPoint, { duration } = {}) {
4127
+ _Step.assert(this.stepId);
4128
+ const result = await AssistsX2.performLinearGesture(startPoint, endPoint, {
4129
+ duration
4130
+ });
4131
+ _Step.assert(this.stepId);
4132
+ return result;
4133
+ }
4134
+ /**
4135
+ * 返回操作
4136
+ * @returns 是否成功
4137
+ */
4138
+ back() {
4139
+ _Step.assert(this.stepId);
4140
+ const result = AssistsX2.back();
4141
+ _Step.assert(this.stepId);
4142
+ return result;
4143
+ }
4144
+ /**
4145
+ * 回到主页
4146
+ * @returns 是否成功
4147
+ */
4148
+ home() {
4149
+ _Step.assert(this.stepId);
4150
+ const result = AssistsX2.home();
4151
+ _Step.assert(this.stepId);
4152
+ return result;
4153
+ }
4154
+ /**
4155
+ * 打开通知栏
4156
+ * @returns 是否成功
4157
+ */
4158
+ notifications() {
4159
+ _Step.assert(this.stepId);
4160
+ const result = AssistsX2.notifications();
4161
+ _Step.assert(this.stepId);
4162
+ return result;
4163
+ }
4164
+ /**
4165
+ * 显示最近应用
4166
+ * @returns 是否成功
4167
+ */
4168
+ recentApps() {
4169
+ _Step.assert(this.stepId);
4170
+ const result = AssistsX2.recentApps();
4171
+ _Step.assert(this.stepId);
4172
+ return result;
4173
+ }
4174
+ /**
4175
+ * 获取屏幕尺寸
4176
+ * @returns 屏幕尺寸对象
4177
+ */
4178
+ getScreenSize() {
4179
+ _Step.assert(this.stepId);
4180
+ const data = AssistsX2.getScreenSize();
4181
+ _Step.assert(this.stepId);
4182
+ return data;
4183
+ }
4184
+ /**
4185
+ * 获取应用窗口尺寸
4186
+ * @returns 应用窗口尺寸对象
4187
+ */
4188
+ getAppScreenSize() {
4189
+ _Step.assert(this.stepId);
4190
+ const data = AssistsX2.getAppScreenSize();
4191
+ _Step.assert(this.stepId);
4192
+ return data;
4193
+ }
4194
+ };
4195
+ _Step.delayMsDefault = 1e3;
4196
+ _Step.repeatCountInfinite = -1;
4197
+ _Step.repeatCountMaxDefault = 15;
4198
+ _Step.showLog = false;
4199
+ _Step.exceptionRetryCountMaxDefault = 3;
4200
+ /**
4201
+ * 当前执行步骤的ID
4202
+ */
4203
+ _Step._stepId = void 0;
4204
+ /**
4205
+ * 步骤拦截器列表
4206
+ */
4207
+ _Step._interceptors = [];
4208
+ /**
4209
+ * 步骤异常变量,默认为空
4210
+ */
4211
+ _Step.exception = void 0;
4212
+ var Step = _Step;
4213
+
4214
+ // src/step-flow/runner.ts
4215
+ function ensureFlowMeta(step, config) {
4216
+ const data = step.data;
4217
+ if (!data.__flow) {
4218
+ data.__flow = { id: config.id, state: config.initial };
4219
+ }
4220
+ }
4221
+ function setFlowState(step, state, config) {
4222
+ const data = step.data;
4223
+ if (!data.__flow) {
4224
+ data.__flow = { id: config.id, state };
4225
+ } else {
4226
+ data.__flow.state = state;
4227
+ }
4228
+ }
4229
+ function resolveOutcome(config, currentState, outcome) {
4230
+ if (outcome.type === "end") {
4231
+ return void 0;
4232
+ }
4233
+ if (outcome.type === "repeat") {
4234
+ return null;
4235
+ }
4236
+ if (outcome.type === "legacy") {
4237
+ return "legacy";
4238
+ }
4239
+ const stateDef = config.states[currentState];
4240
+ if (!stateDef) {
4241
+ throw new StepError(`StepFlow: unknown state "${currentState}"`, {
4242
+ flowId: config.id,
4243
+ state: currentState
4244
+ });
4245
+ }
4246
+ const nextState = stateDef.on[outcome.name];
4247
+ if (!nextState) {
4248
+ throw new StepError(
4249
+ `StepFlow: no transition for event "${outcome.name}" in state "${currentState}"`,
4250
+ { flowId: config.id, state: currentState, event: outcome.name }
4251
+ );
4252
+ }
4253
+ return nextState;
4254
+ }
4255
+ function createDispatcher(config) {
4256
+ const dispatcher = async (step) => {
4257
+ ensureFlowMeta(step, config);
4258
+ const data = step.data;
4259
+ const currentState = data.__flow.state;
4260
+ const stateDef = config.states[currentState];
4261
+ if (!stateDef) {
4262
+ throw new StepError(`StepFlow: unknown state "${currentState}"`, {
4263
+ flowId: config.id,
4264
+ state: currentState
4265
+ });
4266
+ }
4267
+ const outcome = await stateDef.run(step);
4268
+ const resolved = resolveOutcome(config, currentState, outcome);
4269
+ if (resolved === void 0) {
4270
+ return void 0;
4271
+ }
4272
+ if (resolved === null) {
4273
+ return step.repeat();
4274
+ }
4275
+ if (resolved === "legacy") {
4276
+ if (outcome.type !== "legacy") {
4277
+ throw new StepError("StepFlow: internal legacy outcome mismatch");
4278
+ }
4279
+ return step.next(outcome.impl);
4280
+ }
4281
+ setFlowState(step, resolved, config);
4282
+ return step.next(dispatcher);
4283
+ };
4284
+ return dispatcher;
4285
+ }
4286
+ function createFlowDispatcher(config) {
4287
+ return createDispatcher(config);
4288
+ }
4289
+ function buildFlowInitialData(config) {
4290
+ var _a2;
4291
+ return {
4292
+ payload: (_a2 = config.data) != null ? _a2 : {},
4293
+ __flow: {
4294
+ id: config.id,
4295
+ state: config.initial
4296
+ }
4297
+ };
4298
+ }
4299
+ var StepFlow = class {
4300
+ /**
4301
+ * 按状态机配置运行流程,内部复用 Step.run 与现有步骤循环。
4302
+ */
4303
+ static async run(config, options) {
4304
+ var _a2;
4305
+ if (!config.states[config.initial]) {
4306
+ throw new StepError(
4307
+ `StepFlow: initial state "${config.initial}" is not defined`,
4308
+ { flowId: config.id }
4309
+ );
4310
+ }
4311
+ const dispatcher = createDispatcher(config);
4312
+ return Step.run(dispatcher, {
4313
+ ...options,
4314
+ tag: (_a2 = options == null ? void 0 : options.tag) != null ? _a2 : config.id,
4315
+ data: buildFlowInitialData(config)
4316
+ });
4317
+ }
4318
+ };
4319
+ export {
4320
+ StepFlow,
4321
+ assignFlowPayload,
4322
+ buildFlowInitialData,
4323
+ createFinishHandoff,
4324
+ createFlowDispatcher,
4325
+ createLaunchState,
4326
+ flowEnd,
4327
+ flowEvent,
4328
+ flowRepeat,
4329
+ getFlowPayload
4330
+ };
4331
+ //# sourceMappingURL=index.js.map