@epsilon-asi/actors 0.0.22 → 0.0.33
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/browser/RuntimeConfig.d.ts +26 -0
- package/dist/browser/RuntimeConfig.d.ts.map +1 -1
- package/dist/browser/RuntimeConfig.js +29 -1
- package/dist/browser/RuntimeConfig.js.map +1 -1
- package/dist/core/ActorContext.d.ts +2 -0
- package/dist/core/ActorContext.d.ts.map +1 -1
- package/dist/core/ActorRunner.d.ts +3 -0
- package/dist/core/ActorRunner.d.ts.map +1 -1
- package/dist/core/ActorRunner.js +11 -1
- package/dist/core/ActorRunner.js.map +1 -1
- package/dist/index.d.ts +2 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2 -0
- package/dist/index.js.map +1 -1
- package/dist/native/CompositeNativeWindowDriver.d.ts +11 -0
- package/dist/native/CompositeNativeWindowDriver.d.ts.map +1 -0
- package/dist/native/CompositeNativeWindowDriver.js +31 -0
- package/dist/native/CompositeNativeWindowDriver.js.map +1 -0
- package/dist/native/NativeActionRegistry.d.ts +14 -0
- package/dist/native/NativeActionRegistry.d.ts.map +1 -0
- package/dist/native/NativeActionRegistry.js +101 -0
- package/dist/native/NativeActionRegistry.js.map +1 -0
- package/dist/native/NativeAutomation.d.ts +3 -0
- package/dist/native/NativeAutomation.d.ts.map +1 -0
- package/dist/native/NativeAutomation.js +12 -0
- package/dist/native/NativeAutomation.js.map +1 -0
- package/dist/native/NativeCoordinateMapper.d.ts +23 -0
- package/dist/native/NativeCoordinateMapper.d.ts.map +1 -0
- package/dist/native/NativeCoordinateMapper.js +201 -0
- package/dist/native/NativeCoordinateMapper.js.map +1 -0
- package/dist/native/NativeFileDialogService.d.ts +26 -0
- package/dist/native/NativeFileDialogService.d.ts.map +1 -0
- package/dist/native/NativeFileDialogService.js +121 -0
- package/dist/native/NativeFileDialogService.js.map +1 -0
- package/dist/native/NativeImageFinder.d.ts +12 -0
- package/dist/native/NativeImageFinder.d.ts.map +1 -0
- package/dist/native/NativeImageFinder.js +29 -0
- package/dist/native/NativeImageFinder.js.map +1 -0
- package/dist/native/NativeKeyboard.d.ts +10 -0
- package/dist/native/NativeKeyboard.d.ts.map +1 -0
- package/dist/native/NativeKeyboard.js +16 -0
- package/dist/native/NativeKeyboard.js.map +1 -0
- package/dist/native/NativeMouse.d.ts +38 -0
- package/dist/native/NativeMouse.d.ts.map +1 -0
- package/dist/native/NativeMouse.js +82 -0
- package/dist/native/NativeMouse.js.map +1 -0
- package/dist/native/NativeWindowService.d.ts +31 -0
- package/dist/native/NativeWindowService.d.ts.map +1 -0
- package/dist/native/NativeWindowService.js +183 -0
- package/dist/native/NativeWindowService.js.map +1 -0
- package/dist/native/UnsupportedNativeAutomation.d.ts +4 -0
- package/dist/native/UnsupportedNativeAutomation.d.ts.map +1 -0
- package/dist/native/UnsupportedNativeAutomation.js +77 -0
- package/dist/native/UnsupportedNativeAutomation.js.map +1 -0
- package/dist/native/WindowMatcher.d.ts +4 -0
- package/dist/native/WindowMatcher.d.ts.map +1 -0
- package/dist/native/WindowMatcher.js +39 -0
- package/dist/native/WindowMatcher.js.map +1 -0
- package/dist/native/drivers.d.ts +37 -0
- package/dist/native/drivers.d.ts.map +1 -0
- package/dist/native/drivers.js +2 -0
- package/dist/native/drivers.js.map +1 -0
- package/dist/native/errors.d.ts +23 -0
- package/dist/native/errors.d.ts.map +1 -0
- package/dist/native/errors.js +45 -0
- package/dist/native/errors.js.map +1 -0
- package/dist/native/index.d.ts +13 -0
- package/dist/native/index.d.ts.map +1 -0
- package/dist/native/index.js +13 -0
- package/dist/native/index.js.map +1 -0
- package/dist/native/macos/MacOSAccessibilityWindowDriver.d.ts +11 -0
- package/dist/native/macos/MacOSAccessibilityWindowDriver.d.ts.map +1 -0
- package/dist/native/macos/MacOSAccessibilityWindowDriver.js +180 -0
- package/dist/native/macos/MacOSAccessibilityWindowDriver.js.map +1 -0
- package/dist/native/macos/MacOSAppleScriptClient.d.ts +24 -0
- package/dist/native/macos/MacOSAppleScriptClient.d.ts.map +1 -0
- package/dist/native/macos/MacOSAppleScriptClient.js +163 -0
- package/dist/native/macos/MacOSAppleScriptClient.js.map +1 -0
- package/dist/native/macos/MacOSFileDialogAccessibilityStrategy.d.ts +10 -0
- package/dist/native/macos/MacOSFileDialogAccessibilityStrategy.d.ts.map +1 -0
- package/dist/native/macos/MacOSFileDialogAccessibilityStrategy.js +12 -0
- package/dist/native/macos/MacOSFileDialogAccessibilityStrategy.js.map +1 -0
- package/dist/native/macos/MacOSNativeAutomation.d.ts +3 -0
- package/dist/native/macos/MacOSNativeAutomation.d.ts.map +1 -0
- package/dist/native/macos/MacOSNativeAutomation.js +88 -0
- package/dist/native/macos/MacOSNativeAutomation.js.map +1 -0
- package/dist/native/nut/NutNativeImageFinder.d.ts +17 -0
- package/dist/native/nut/NutNativeImageFinder.d.ts.map +1 -0
- package/dist/native/nut/NutNativeImageFinder.js +84 -0
- package/dist/native/nut/NutNativeImageFinder.js.map +1 -0
- package/dist/native/nut/NutNativeKeyboardDriver.d.ts +8 -0
- package/dist/native/nut/NutNativeKeyboardDriver.d.ts.map +1 -0
- package/dist/native/nut/NutNativeKeyboardDriver.js +39 -0
- package/dist/native/nut/NutNativeKeyboardDriver.js.map +1 -0
- package/dist/native/nut/NutNativeMouseDriver.d.ts +8 -0
- package/dist/native/nut/NutNativeMouseDriver.d.ts.map +1 -0
- package/dist/native/nut/NutNativeMouseDriver.js +24 -0
- package/dist/native/nut/NutNativeMouseDriver.js.map +1 -0
- package/dist/native/nut/NutNativeScreenDriver.d.ts +6 -0
- package/dist/native/nut/NutNativeScreenDriver.d.ts.map +1 -0
- package/dist/native/nut/NutNativeScreenDriver.js +12 -0
- package/dist/native/nut/NutNativeScreenDriver.js.map +1 -0
- package/dist/native/nut/NutNativeWindowDriver.d.ts +6 -0
- package/dist/native/nut/NutNativeWindowDriver.d.ts.map +1 -0
- package/dist/native/nut/NutNativeWindowDriver.js +53 -0
- package/dist/native/nut/NutNativeWindowDriver.js.map +1 -0
- package/dist/native/nut/loadNut.d.ts +58 -0
- package/dist/native/nut/loadNut.d.ts.map +1 -0
- package/dist/native/nut/loadNut.js +25 -0
- package/dist/native/nut/loadNut.js.map +1 -0
- package/dist/native/types.d.ts +194 -0
- package/dist/native/types.d.ts.map +1 -0
- package/dist/native/types.js +2 -0
- package/dist/native/types.js.map +1 -0
- package/dist/native/utils/appleScriptEscape.d.ts +7 -0
- package/dist/native/utils/appleScriptEscape.d.ts.map +1 -0
- package/dist/native/utils/appleScriptEscape.js +11 -0
- package/dist/native/utils/appleScriptEscape.js.map +1 -0
- package/dist/native/utils/geometry.d.ts +12 -0
- package/dist/native/utils/geometry.d.ts.map +1 -0
- package/dist/native/utils/geometry.js +77 -0
- package/dist/native/utils/geometry.js.map +1 -0
- package/dist/native/utils/redactNative.d.ts +2 -0
- package/dist/native/utils/redactNative.d.ts.map +1 -0
- package/dist/native/utils/redactNative.js +7 -0
- package/dist/native/utils/redactNative.js.map +1 -0
- package/dist/native/utils/waitFor.d.ts +7 -0
- package/dist/native/utils/waitFor.d.ts.map +1 -0
- package/dist/native/utils/waitFor.js +17 -0
- package/dist/native/utils/waitFor.js.map +1 -0
- package/dist/sites/upwork-com/upwork-com.actor.d.ts +4 -1
- package/dist/sites/upwork-com/upwork-com.actor.d.ts.map +1 -1
- package/dist/sites/upwork-com/upwork-com.actor.js +31 -11
- package/dist/sites/upwork-com/upwork-com.actor.js.map +1 -1
- package/dist/sites/upwork-com/upwork-com.types.d.ts +3 -1
- package/dist/sites/upwork-com/upwork-com.types.d.ts.map +1 -1
- package/dist/sites/upwork-com/upwork-com.types.js.map +1 -1
- package/dist/sites/upwork-com/util/parseJobApplicationDetails.d.ts +70 -0
- package/dist/sites/upwork-com/util/parseJobApplicationDetails.d.ts.map +1 -0
- package/dist/sites/upwork-com/util/parseJobApplicationDetails.js +334 -0
- package/dist/sites/upwork-com/util/parseJobApplicationDetails.js.map +1 -0
- package/npmrc +5 -0
- package/package.json +5 -1
- package/src/browser/RuntimeConfig.ts +57 -1
- package/src/core/ActorContext.ts +2 -0
- package/src/core/ActorRunner.ts +13 -1
- package/src/index.ts +2 -0
- package/src/native/CompositeNativeWindowDriver.ts +30 -0
- package/src/native/NativeActionRegistry.ts +114 -0
- package/src/native/NativeAutomation.ts +15 -0
- package/src/native/NativeCoordinateMapper.ts +258 -0
- package/src/native/NativeFileDialogService.ts +138 -0
- package/src/native/NativeImageFinder.ts +33 -0
- package/src/native/NativeKeyboard.ts +18 -0
- package/src/native/NativeMouse.ts +116 -0
- package/src/native/NativeWindowService.ts +229 -0
- package/src/native/UnsupportedNativeAutomation.ts +92 -0
- package/src/native/WindowMatcher.ts +31 -0
- package/src/native/drivers.ts +38 -0
- package/src/native/errors.ts +51 -0
- package/src/native/index.ts +12 -0
- package/src/native/macos/MacOSAccessibilityWindowDriver.ts +183 -0
- package/src/native/macos/MacOSAppleScriptClient.ts +182 -0
- package/src/native/macos/MacOSFileDialogAccessibilityStrategy.ts +11 -0
- package/src/native/macos/MacOSNativeAutomation.ts +86 -0
- package/src/native/nut/NutNativeImageFinder.ts +98 -0
- package/src/native/nut/NutNativeKeyboardDriver.ts +38 -0
- package/src/native/nut/NutNativeMouseDriver.ts +27 -0
- package/src/native/nut/NutNativeScreenDriver.ts +14 -0
- package/src/native/nut/NutNativeWindowDriver.ts +61 -0
- package/src/native/nut/loadNut.ts +86 -0
- package/src/native/types.ts +224 -0
- package/src/native/utils/appleScriptEscape.ts +11 -0
- package/src/native/utils/geometry.ts +88 -0
- package/src/native/utils/redactNative.ts +6 -0
- package/src/native/utils/waitFor.ts +25 -0
- package/src/sites/upwork-com/upwork-com.actor.ts +47 -14
- package/src/sites/upwork-com/upwork-com.types.ts +4 -1
- package/src/sites/upwork-com/util/parseJobApplicationDetails.ts +622 -0
- package/tests/fixtures/makeContext.ts +7 -2
- package/tests/fixtures/native/FakeNativeAutomation.ts +138 -0
- package/tests/unit/browser/RuntimeConfig.native.test.ts +63 -0
- package/tests/unit/core/ActorRunner.native.test.ts +69 -0
- package/tests/unit/native/MacOSAppleScriptClient.test.ts +35 -0
- package/tests/unit/native/NativeActionRegistry.test.ts +34 -0
- package/tests/unit/native/NativeCoordinateMapper.test.ts +92 -0
- package/tests/unit/native/NativeFileDialogService.test.ts +91 -0
- package/tests/unit/native/NativeMouse.test.ts +91 -0
- package/tests/unit/native/NativeWindowService.test.ts +87 -0
- package/tests/unit/native/WindowMatcher.test.ts +32 -0
- package/tests/unit/native/appleScriptEscape.test.ts +9 -0
- package/tests/unit/sites/myvistage-com.login.test.ts +1 -1
- package/tests/unit/sites/myvistage-com.postComment.test.ts +0 -1
- package/tests/unit/sites/upwork-com.login.test.ts +1 -1
|
@@ -0,0 +1,180 @@
|
|
|
1
|
+
import { appleScriptString } from '../utils/appleScriptEscape.js';
|
|
2
|
+
const FIELD_SEPARATOR = '\u001f';
|
|
3
|
+
const ROW_SEPARATOR = '\u001e';
|
|
4
|
+
function parseBoolean(value) {
|
|
5
|
+
if (value === 'true')
|
|
6
|
+
return true;
|
|
7
|
+
if (value === 'false')
|
|
8
|
+
return false;
|
|
9
|
+
return undefined;
|
|
10
|
+
}
|
|
11
|
+
function parseNumber(value) {
|
|
12
|
+
const parsed = Number(value);
|
|
13
|
+
return Number.isFinite(parsed) ? parsed : 0;
|
|
14
|
+
}
|
|
15
|
+
class MacOSAccessibilityWindowHandle {
|
|
16
|
+
client;
|
|
17
|
+
currentInfo;
|
|
18
|
+
constructor(client, currentInfo) {
|
|
19
|
+
this.client = client;
|
|
20
|
+
this.currentInfo = currentInfo;
|
|
21
|
+
}
|
|
22
|
+
async info() {
|
|
23
|
+
return this.currentInfo;
|
|
24
|
+
}
|
|
25
|
+
async focus() {
|
|
26
|
+
await this.client.focusWindow(this.matcher(), this.currentInfo.appName ?? 'Google Chrome');
|
|
27
|
+
this.currentInfo = { ...this.currentInfo, isFocused: true };
|
|
28
|
+
}
|
|
29
|
+
async minimize() {
|
|
30
|
+
await this.client.minimize(this.matcher(), this.currentInfo.appName ?? 'Google Chrome');
|
|
31
|
+
this.currentInfo = { ...this.currentInfo, isMinimized: true };
|
|
32
|
+
}
|
|
33
|
+
async restore() {
|
|
34
|
+
await this.executeOnWindow(`set value of attribute "AXMinimized" of candidateWindow to false`);
|
|
35
|
+
this.currentInfo = { ...this.currentInfo, isMinimized: false };
|
|
36
|
+
}
|
|
37
|
+
async move(point) {
|
|
38
|
+
await this.executeOnWindow(`set position of candidateWindow to {${Math.round(point.x)}, ${Math.round(point.y)}}`);
|
|
39
|
+
this.currentInfo = {
|
|
40
|
+
...this.currentInfo,
|
|
41
|
+
region: { ...this.currentInfo.region, x: Math.round(point.x), y: Math.round(point.y) }
|
|
42
|
+
};
|
|
43
|
+
}
|
|
44
|
+
async resize(size) {
|
|
45
|
+
await this.executeOnWindow(`set size of candidateWindow to {${Math.round(size.width)}, ${Math.round(size.height)}}`);
|
|
46
|
+
this.currentInfo = {
|
|
47
|
+
...this.currentInfo,
|
|
48
|
+
region: { ...this.currentInfo.region, width: Math.round(size.width), height: Math.round(size.height) }
|
|
49
|
+
};
|
|
50
|
+
}
|
|
51
|
+
async setFullscreen(fullscreen) {
|
|
52
|
+
await this.client.setFullscreen(this.matcher(), fullscreen, this.currentInfo.appName ?? 'Google Chrome');
|
|
53
|
+
this.currentInfo = { ...this.currentInfo, isFullscreen: fullscreen };
|
|
54
|
+
}
|
|
55
|
+
async toggleFullscreen() {
|
|
56
|
+
await this.client.toggleFullscreen(this.matcher(), this.currentInfo.appName ?? 'Google Chrome');
|
|
57
|
+
if (this.currentInfo.isFullscreen === undefined) {
|
|
58
|
+
this.currentInfo = { ...this.currentInfo };
|
|
59
|
+
}
|
|
60
|
+
else {
|
|
61
|
+
this.currentInfo = { ...this.currentInfo, isFullscreen: !this.currentInfo.isFullscreen };
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
matcher() {
|
|
65
|
+
const matcher = {};
|
|
66
|
+
if (this.currentInfo.appName !== undefined)
|
|
67
|
+
matcher.appName = this.currentInfo.appName;
|
|
68
|
+
matcher.title = this.currentInfo.title;
|
|
69
|
+
return matcher;
|
|
70
|
+
}
|
|
71
|
+
async executeOnWindow(action) {
|
|
72
|
+
const appName = this.currentInfo.appName ?? 'Google Chrome';
|
|
73
|
+
const title = this.currentInfo.title;
|
|
74
|
+
const script = `
|
|
75
|
+
tell application "System Events"
|
|
76
|
+
tell process ${appleScriptString(appName)}
|
|
77
|
+
repeat with candidateWindow in windows
|
|
78
|
+
if name of candidateWindow is ${appleScriptString(title)} then
|
|
79
|
+
${action}
|
|
80
|
+
return
|
|
81
|
+
end if
|
|
82
|
+
end repeat
|
|
83
|
+
end tell
|
|
84
|
+
end tell
|
|
85
|
+
`;
|
|
86
|
+
await this.client.execute(script);
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
export class MacOSAccessibilityWindowDriver {
|
|
90
|
+
client;
|
|
91
|
+
logger;
|
|
92
|
+
constructor(client, logger) {
|
|
93
|
+
this.client = client;
|
|
94
|
+
this.logger = logger;
|
|
95
|
+
}
|
|
96
|
+
async list() {
|
|
97
|
+
const script = `
|
|
98
|
+
set fieldSeparator to ASCII character 31
|
|
99
|
+
set rowSeparator to ASCII character 30
|
|
100
|
+
set rows to {}
|
|
101
|
+
tell application "System Events"
|
|
102
|
+
repeat with appProcess in application processes
|
|
103
|
+
set appName to name of appProcess
|
|
104
|
+
repeat with candidateWindow in windows of appProcess
|
|
105
|
+
set windowTitle to ""
|
|
106
|
+
set px to 0
|
|
107
|
+
set py to 0
|
|
108
|
+
set windowWidth to 0
|
|
109
|
+
set windowHeight to 0
|
|
110
|
+
set minimizedValue to ""
|
|
111
|
+
set fullscreenValue to ""
|
|
112
|
+
try
|
|
113
|
+
set windowTitle to name of candidateWindow
|
|
114
|
+
end try
|
|
115
|
+
try
|
|
116
|
+
set windowPosition to position of candidateWindow
|
|
117
|
+
set px to item 1 of windowPosition
|
|
118
|
+
set py to item 2 of windowPosition
|
|
119
|
+
end try
|
|
120
|
+
try
|
|
121
|
+
set windowSize to size of candidateWindow
|
|
122
|
+
set windowWidth to item 1 of windowSize
|
|
123
|
+
set windowHeight to item 2 of windowSize
|
|
124
|
+
end try
|
|
125
|
+
try
|
|
126
|
+
set minimizedValue to (value of attribute "AXMinimized" of candidateWindow) as text
|
|
127
|
+
end try
|
|
128
|
+
try
|
|
129
|
+
set fullscreenValue to (value of attribute "AXFullScreen" of candidateWindow) as text
|
|
130
|
+
end try
|
|
131
|
+
copy (appName & fieldSeparator & windowTitle & fieldSeparator & px & fieldSeparator & py & fieldSeparator & windowWidth & fieldSeparator & windowHeight & fieldSeparator & minimizedValue & fieldSeparator & fullscreenValue) to end of rows
|
|
132
|
+
end repeat
|
|
133
|
+
end repeat
|
|
134
|
+
end tell
|
|
135
|
+
set AppleScript's text item delimiters to rowSeparator
|
|
136
|
+
return rows as text
|
|
137
|
+
`;
|
|
138
|
+
try {
|
|
139
|
+
const output = await this.client.execute(script);
|
|
140
|
+
if (output.length === 0)
|
|
141
|
+
return [];
|
|
142
|
+
return output.split(ROW_SEPARATOR)
|
|
143
|
+
.map(row => this.parseRow(row))
|
|
144
|
+
.filter((info) => info !== null)
|
|
145
|
+
.map(info => new MacOSAccessibilityWindowHandle(this.client, info));
|
|
146
|
+
}
|
|
147
|
+
catch (error) {
|
|
148
|
+
this.logger?.debug('Failed to list windows through macOS Accessibility.', { error });
|
|
149
|
+
throw error;
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
parseRow(row) {
|
|
153
|
+
const fields = row.split(FIELD_SEPARATOR);
|
|
154
|
+
if (fields.length < 8)
|
|
155
|
+
return null;
|
|
156
|
+
const [appName, title, xRaw, yRaw, widthRaw, heightRaw, minimizedRaw, fullscreenRaw] = fields;
|
|
157
|
+
if (appName === undefined || title === undefined || xRaw === undefined || yRaw === undefined || widthRaw === undefined || heightRaw === undefined) {
|
|
158
|
+
return null;
|
|
159
|
+
}
|
|
160
|
+
const region = {
|
|
161
|
+
x: parseNumber(xRaw),
|
|
162
|
+
y: parseNumber(yRaw),
|
|
163
|
+
width: parseNumber(widthRaw),
|
|
164
|
+
height: parseNumber(heightRaw)
|
|
165
|
+
};
|
|
166
|
+
const info = {
|
|
167
|
+
appName,
|
|
168
|
+
title,
|
|
169
|
+
region
|
|
170
|
+
};
|
|
171
|
+
const isMinimized = parseBoolean(minimizedRaw ?? '');
|
|
172
|
+
const isFullscreen = parseBoolean(fullscreenRaw ?? '');
|
|
173
|
+
if (isMinimized !== undefined)
|
|
174
|
+
info.isMinimized = isMinimized;
|
|
175
|
+
if (isFullscreen !== undefined)
|
|
176
|
+
info.isFullscreen = isFullscreen;
|
|
177
|
+
return info;
|
|
178
|
+
}
|
|
179
|
+
}
|
|
180
|
+
//# sourceMappingURL=MacOSAccessibilityWindowDriver.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"MacOSAccessibilityWindowDriver.js","sourceRoot":"","sources":["../../../src/native/macos/MacOSAccessibilityWindowDriver.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import type { AppleScriptExecutor } from '../drivers.js';
|
|
2
|
+
import type { WindowMatcher } from '../types.js';
|
|
3
|
+
export declare class OsaScriptExecutor implements AppleScriptExecutor {
|
|
4
|
+
execute(script: string, options?: {
|
|
5
|
+
timeoutMs?: number;
|
|
6
|
+
}): Promise<string>;
|
|
7
|
+
}
|
|
8
|
+
export interface MacOSAppleScriptClientOptions {
|
|
9
|
+
executor?: AppleScriptExecutor;
|
|
10
|
+
timeoutMs?: number;
|
|
11
|
+
}
|
|
12
|
+
export declare class MacOSAppleScriptClient {
|
|
13
|
+
private readonly executor;
|
|
14
|
+
private readonly timeoutMs;
|
|
15
|
+
constructor(options?: MacOSAppleScriptClientOptions);
|
|
16
|
+
execute(script: string, timeoutMs?: number): Promise<string>;
|
|
17
|
+
isWindowOpen(matcher: WindowMatcher, fallbackAppName?: string): Promise<boolean>;
|
|
18
|
+
focusWindow(matcher: WindowMatcher, fallbackAppName?: string): Promise<void>;
|
|
19
|
+
setFullscreen(matcher: WindowMatcher, fullscreen: boolean, fallbackAppName?: string): Promise<void>;
|
|
20
|
+
toggleFullscreen(matcher: WindowMatcher, fallbackAppName?: string): Promise<void>;
|
|
21
|
+
minimize(matcher: WindowMatcher, fallbackAppName?: string): Promise<void>;
|
|
22
|
+
selectFileInOpenDialog(filePath: string, appName?: string, timeoutMs?: number): Promise<void>;
|
|
23
|
+
}
|
|
24
|
+
//# sourceMappingURL=MacOSAppleScriptClient.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"MacOSAppleScriptClient.d.ts","sourceRoot":"","sources":["../../../src/native/macos/MacOSAppleScriptClient.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,eAAe,CAAC;AACzD,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAKjD,qBAAa,iBAAkB,YAAW,mBAAmB;IACrD,OAAO,CAAC,MAAM,EAAE,MAAM,EAAE,OAAO,GAAE;QAAE,SAAS,CAAC,EAAE,MAAM,CAAA;KAAO,GAAG,OAAO,CAAC,MAAM,CAAC;CAOrF;AAED,MAAM,WAAW,6BAA6B;IAC5C,QAAQ,CAAC,EAAE,mBAAmB,CAAC;IAC/B,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAoBD,qBAAa,sBAAsB;IACjC,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAsB;IAC/C,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAS;gBAEvB,OAAO,GAAE,6BAAkC;IAKjD,OAAO,CAAC,MAAM,EAAE,MAAM,EAAE,SAAS,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;IAI5D,YAAY,CAAC,OAAO,EAAE,aAAa,EAAE,eAAe,SAAkB,GAAG,OAAO,CAAC,OAAO,CAAC;IAezF,WAAW,CAAC,OAAO,EAAE,aAAa,EAAE,eAAe,SAAkB,GAAG,OAAO,CAAC,IAAI,CAAC;IAiBrF,aAAa,CAAC,OAAO,EAAE,aAAa,EAAE,UAAU,EAAE,OAAO,EAAE,eAAe,SAAkB,GAAG,OAAO,CAAC,IAAI,CAAC;IA4B5G,gBAAgB,CAAC,OAAO,EAAE,aAAa,EAAE,eAAe,SAAkB,GAAG,OAAO,CAAC,IAAI,CAAC;IAqB1F,QAAQ,CAAC,OAAO,EAAE,aAAa,EAAE,eAAe,SAAkB,GAAG,OAAO,CAAC,IAAI,CAAC;IAoBlF,sBAAsB,CAAC,QAAQ,EAAE,MAAM,EAAE,OAAO,SAAkB,EAAE,SAAS,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;CA0B7G"}
|
|
@@ -0,0 +1,163 @@
|
|
|
1
|
+
import { execFile } from 'node:child_process';
|
|
2
|
+
import { promisify } from 'node:util';
|
|
3
|
+
import { appleScriptString } from '../utils/appleScriptEscape.js';
|
|
4
|
+
const execFileAsync = promisify(execFile);
|
|
5
|
+
export class OsaScriptExecutor {
|
|
6
|
+
async execute(script, options = {}) {
|
|
7
|
+
const { stdout } = await execFileAsync('osascript', ['-l', 'AppleScript', '-e', script], {
|
|
8
|
+
timeout: options.timeoutMs ?? 15_000,
|
|
9
|
+
maxBuffer: 1024 * 1024
|
|
10
|
+
});
|
|
11
|
+
return stdout.trim();
|
|
12
|
+
}
|
|
13
|
+
}
|
|
14
|
+
function matcherCondition(matcher) {
|
|
15
|
+
const conditions = [];
|
|
16
|
+
if (matcher.title !== undefined) {
|
|
17
|
+
conditions.push(`name of candidateWindow is ${appleScriptString(matcher.title)}`);
|
|
18
|
+
}
|
|
19
|
+
if (matcher.titleIncludes !== undefined) {
|
|
20
|
+
conditions.push(`name of candidateWindow contains ${appleScriptString(matcher.titleIncludes)}`);
|
|
21
|
+
}
|
|
22
|
+
if (matcher.role !== undefined) {
|
|
23
|
+
conditions.push(`role of candidateWindow is ${appleScriptString(matcher.role)}`);
|
|
24
|
+
}
|
|
25
|
+
return conditions.length === 0 ? 'true' : conditions.join(' and ');
|
|
26
|
+
}
|
|
27
|
+
function processTarget(matcher, fallbackAppName) {
|
|
28
|
+
return appleScriptString(matcher.appName ?? fallbackAppName);
|
|
29
|
+
}
|
|
30
|
+
export class MacOSAppleScriptClient {
|
|
31
|
+
executor;
|
|
32
|
+
timeoutMs;
|
|
33
|
+
constructor(options = {}) {
|
|
34
|
+
this.executor = options.executor ?? new OsaScriptExecutor();
|
|
35
|
+
this.timeoutMs = options.timeoutMs ?? 15_000;
|
|
36
|
+
}
|
|
37
|
+
async execute(script, timeoutMs) {
|
|
38
|
+
return this.executor.execute(script, { timeoutMs: timeoutMs ?? this.timeoutMs });
|
|
39
|
+
}
|
|
40
|
+
async isWindowOpen(matcher, fallbackAppName = 'Google Chrome') {
|
|
41
|
+
const script = `
|
|
42
|
+
tell application "System Events"
|
|
43
|
+
if not (exists process ${processTarget(matcher, fallbackAppName)}) then return "false"
|
|
44
|
+
tell process ${processTarget(matcher, fallbackAppName)}
|
|
45
|
+
repeat with candidateWindow in windows
|
|
46
|
+
if ${matcherCondition(matcher)} then return "true"
|
|
47
|
+
end repeat
|
|
48
|
+
end tell
|
|
49
|
+
end tell
|
|
50
|
+
return "false"
|
|
51
|
+
`;
|
|
52
|
+
return (await this.execute(script)) === 'true';
|
|
53
|
+
}
|
|
54
|
+
async focusWindow(matcher, fallbackAppName = 'Google Chrome') {
|
|
55
|
+
const script = `
|
|
56
|
+
tell application ${processTarget(matcher, fallbackAppName)} to activate
|
|
57
|
+
tell application "System Events"
|
|
58
|
+
tell process ${processTarget(matcher, fallbackAppName)}
|
|
59
|
+
repeat with candidateWindow in windows
|
|
60
|
+
if ${matcherCondition(matcher)} then
|
|
61
|
+
perform action "AXRaise" of candidateWindow
|
|
62
|
+
return
|
|
63
|
+
end if
|
|
64
|
+
end repeat
|
|
65
|
+
end tell
|
|
66
|
+
end tell
|
|
67
|
+
`;
|
|
68
|
+
await this.execute(script);
|
|
69
|
+
}
|
|
70
|
+
async setFullscreen(matcher, fullscreen, fallbackAppName = 'Google Chrome') {
|
|
71
|
+
const desired = fullscreen ? 'true' : 'false';
|
|
72
|
+
const script = `
|
|
73
|
+
tell application ${processTarget(matcher, fallbackAppName)} to activate
|
|
74
|
+
tell application "System Events"
|
|
75
|
+
tell process ${processTarget(matcher, fallbackAppName)}
|
|
76
|
+
repeat with candidateWindow in windows
|
|
77
|
+
if ${matcherCondition(matcher)} then
|
|
78
|
+
set currentFullscreen to false
|
|
79
|
+
try
|
|
80
|
+
set currentFullscreen to value of attribute "AXFullScreen" of candidateWindow
|
|
81
|
+
end try
|
|
82
|
+
if currentFullscreen is not ${desired} then
|
|
83
|
+
try
|
|
84
|
+
perform action "AXPress" of (first button of candidateWindow whose subrole is "AXFullScreenButton")
|
|
85
|
+
on error
|
|
86
|
+
click (first button of candidateWindow whose subrole is "AXFullScreenButton")
|
|
87
|
+
end try
|
|
88
|
+
end if
|
|
89
|
+
return
|
|
90
|
+
end if
|
|
91
|
+
end repeat
|
|
92
|
+
end tell
|
|
93
|
+
end tell
|
|
94
|
+
`;
|
|
95
|
+
await this.execute(script);
|
|
96
|
+
}
|
|
97
|
+
async toggleFullscreen(matcher, fallbackAppName = 'Google Chrome') {
|
|
98
|
+
const script = `
|
|
99
|
+
tell application ${processTarget(matcher, fallbackAppName)} to activate
|
|
100
|
+
tell application "System Events"
|
|
101
|
+
tell process ${processTarget(matcher, fallbackAppName)}
|
|
102
|
+
repeat with candidateWindow in windows
|
|
103
|
+
if ${matcherCondition(matcher)} then
|
|
104
|
+
try
|
|
105
|
+
perform action "AXPress" of (first button of candidateWindow whose subrole is "AXFullScreenButton")
|
|
106
|
+
on error
|
|
107
|
+
click (first button of candidateWindow whose subrole is "AXFullScreenButton")
|
|
108
|
+
end try
|
|
109
|
+
return
|
|
110
|
+
end if
|
|
111
|
+
end repeat
|
|
112
|
+
end tell
|
|
113
|
+
end tell
|
|
114
|
+
`;
|
|
115
|
+
await this.execute(script);
|
|
116
|
+
}
|
|
117
|
+
async minimize(matcher, fallbackAppName = 'Google Chrome') {
|
|
118
|
+
const script = `
|
|
119
|
+
tell application "System Events"
|
|
120
|
+
tell process ${processTarget(matcher, fallbackAppName)}
|
|
121
|
+
repeat with candidateWindow in windows
|
|
122
|
+
if ${matcherCondition(matcher)} then
|
|
123
|
+
try
|
|
124
|
+
perform action "AXPress" of (first button of candidateWindow whose subrole is "AXMinimizeButton")
|
|
125
|
+
on error
|
|
126
|
+
set value of attribute "AXMinimized" of candidateWindow to true
|
|
127
|
+
end try
|
|
128
|
+
return
|
|
129
|
+
end if
|
|
130
|
+
end repeat
|
|
131
|
+
end tell
|
|
132
|
+
end tell
|
|
133
|
+
`;
|
|
134
|
+
await this.execute(script);
|
|
135
|
+
}
|
|
136
|
+
async selectFileInOpenDialog(filePath, appName = 'Google Chrome', timeoutMs) {
|
|
137
|
+
const script = `
|
|
138
|
+
set targetPath to ${appleScriptString(filePath)}
|
|
139
|
+
tell application ${appleScriptString(appName)} to activate
|
|
140
|
+
tell application "System Events"
|
|
141
|
+
tell process ${appleScriptString(appName)}
|
|
142
|
+
set frontmost to true
|
|
143
|
+
set waited to 0
|
|
144
|
+
repeat while waited < 100
|
|
145
|
+
if (exists window 1) then exit repeat
|
|
146
|
+
delay 0.1
|
|
147
|
+
set waited to waited + 1
|
|
148
|
+
end repeat
|
|
149
|
+
keystroke "g" using {command down, shift down}
|
|
150
|
+
delay 0.2
|
|
151
|
+
set the clipboard to targetPath
|
|
152
|
+
keystroke "v" using {command down}
|
|
153
|
+
delay 0.1
|
|
154
|
+
key code 36
|
|
155
|
+
delay 0.2
|
|
156
|
+
key code 36
|
|
157
|
+
end tell
|
|
158
|
+
end tell
|
|
159
|
+
`;
|
|
160
|
+
await this.execute(script, timeoutMs);
|
|
161
|
+
}
|
|
162
|
+
}
|
|
163
|
+
//# sourceMappingURL=MacOSAppleScriptClient.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"MacOSAppleScriptClient.js","sourceRoot":"","sources":["../../../src/native/macos/MacOSAppleScriptClient.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import type { SelectFileOptions } from '../types.js';
|
|
2
|
+
import type { FileDialogAccessibilityStrategy } from '../NativeFileDialogService.js';
|
|
3
|
+
import { MacOSAppleScriptClient } from './MacOSAppleScriptClient.js';
|
|
4
|
+
export declare class MacOSFileDialogAccessibilityStrategy implements FileDialogAccessibilityStrategy {
|
|
5
|
+
private readonly client;
|
|
6
|
+
private readonly defaultAppName;
|
|
7
|
+
constructor(client: MacOSAppleScriptClient, defaultAppName?: string);
|
|
8
|
+
selectFile(filePath: string, options: SelectFileOptions): Promise<void>;
|
|
9
|
+
}
|
|
10
|
+
//# sourceMappingURL=MacOSFileDialogAccessibilityStrategy.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"MacOSFileDialogAccessibilityStrategy.d.ts","sourceRoot":"","sources":["../../../src/native/macos/MacOSFileDialogAccessibilityStrategy.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,aAAa,CAAC;AACrD,OAAO,KAAK,EAAE,+BAA+B,EAAE,MAAM,+BAA+B,CAAC;AACrF,OAAO,EAAE,sBAAsB,EAAE,MAAM,6BAA6B,CAAC;AAErE,qBAAa,oCAAqC,YAAW,+BAA+B;IAC9E,OAAO,CAAC,QAAQ,CAAC,MAAM;IAA0B,OAAO,CAAC,QAAQ,CAAC,cAAc;gBAA/D,MAAM,EAAE,sBAAsB,EAAmB,cAAc,SAAkB;IAExG,UAAU,CAAC,QAAQ,EAAE,MAAM,EAAE,OAAO,EAAE,iBAAiB,GAAG,OAAO,CAAC,IAAI,CAAC;CAG9E"}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
export class MacOSFileDialogAccessibilityStrategy {
|
|
2
|
+
client;
|
|
3
|
+
defaultAppName;
|
|
4
|
+
constructor(client, defaultAppName = 'Google Chrome') {
|
|
5
|
+
this.client = client;
|
|
6
|
+
this.defaultAppName = defaultAppName;
|
|
7
|
+
}
|
|
8
|
+
async selectFile(filePath, options) {
|
|
9
|
+
await this.client.selectFileInOpenDialog(filePath, options.appName ?? this.defaultAppName, options.timeoutMs);
|
|
10
|
+
}
|
|
11
|
+
}
|
|
12
|
+
//# sourceMappingURL=MacOSFileDialogAccessibilityStrategy.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"MacOSFileDialogAccessibilityStrategy.js","sourceRoot":"","sources":["../../../src/native/macos/MacOSFileDialogAccessibilityStrategy.ts"],"names":[],"mappings":"AAIA,MAAM,OAAO,oCAAoC;IAClB;IAAiD;IAA9E,YAA6B,MAA8B,EAAmB,iBAAiB,eAAe;QAAjF,WAAM,GAAN,MAAM,CAAwB;QAAmB,mBAAc,GAAd,cAAc,CAAkB;IAAG,CAAC;IAElH,KAAK,CAAC,UAAU,CAAC,QAAgB,EAAE,OAA0B;QAC3D,MAAM,IAAI,CAAC,MAAM,CAAC,sBAAsB,CAAC,QAAQ,EAAE,OAAO,CAAC,OAAO,IAAI,IAAI,CAAC,cAAc,EAAE,OAAO,CAAC,SAAS,CAAC,CAAC;IAChH,CAAC;CACF"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"MacOSNativeAutomation.d.ts","sourceRoot":"","sources":["../../../src/native/macos/MacOSNativeAutomation.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,gBAAgB,EAAE,2BAA2B,EAAE,MAAM,aAAa,CAAC;AAkBjF,wBAAgB,2BAA2B,CAAC,IAAI,EAAE,2BAA2B,GAAG,gBAAgB,CAmE/F"}
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
import { DefaultNativeActionRegistry, registerDefaultNativeActions } from '../NativeActionRegistry.js';
|
|
2
|
+
import { HumanizedNativeMouse } from '../NativeMouse.js';
|
|
3
|
+
import { DefaultNativeKeyboard } from '../NativeKeyboard.js';
|
|
4
|
+
import { DefaultNativeWindowService } from '../NativeWindowService.js';
|
|
5
|
+
import { DefaultNativeImageFinder } from '../NativeImageFinder.js';
|
|
6
|
+
import { ImageBasedCoordinateMapper } from '../NativeCoordinateMapper.js';
|
|
7
|
+
import { DefaultNativeFileDialogService } from '../NativeFileDialogService.js';
|
|
8
|
+
import { NutNativeMouseDriver } from '../nut/NutNativeMouseDriver.js';
|
|
9
|
+
import { NutNativeKeyboardDriver } from '../nut/NutNativeKeyboardDriver.js';
|
|
10
|
+
import { NutNativeScreenDriver } from '../nut/NutNativeScreenDriver.js';
|
|
11
|
+
import { NutNativeWindowDriver } from '../nut/NutNativeWindowDriver.js';
|
|
12
|
+
import { FallbackNativeWindowDriver } from '../CompositeNativeWindowDriver.js';
|
|
13
|
+
import { MacOSAccessibilityWindowDriver } from './MacOSAccessibilityWindowDriver.js';
|
|
14
|
+
import { NutNativeImageFinderDriver } from '../nut/NutNativeImageFinder.js';
|
|
15
|
+
import { MacOSAppleScriptClient } from './MacOSAppleScriptClient.js';
|
|
16
|
+
import { MacOSFileDialogAccessibilityStrategy } from './MacOSFileDialogAccessibilityStrategy.js';
|
|
17
|
+
export function createMacOSNativeAutomation(args) {
|
|
18
|
+
const nativeConfig = args.config.native;
|
|
19
|
+
const mouseDriver = new NutNativeMouseDriver();
|
|
20
|
+
const keyboardDriver = new NutNativeKeyboardDriver();
|
|
21
|
+
const screenDriver = new NutNativeScreenDriver();
|
|
22
|
+
const appleScriptOptions = {};
|
|
23
|
+
const osascriptTimeoutMs = nativeConfig?.macos?.osascriptTimeoutMs ?? args.config.defaultTimeoutMs;
|
|
24
|
+
if (osascriptTimeoutMs !== undefined)
|
|
25
|
+
appleScriptOptions.timeoutMs = osascriptTimeoutMs;
|
|
26
|
+
const appleScriptClient = new MacOSAppleScriptClient(appleScriptOptions);
|
|
27
|
+
const windowDriver = new FallbackNativeWindowDriver(new MacOSAccessibilityWindowDriver(appleScriptClient, args.logger), new NutNativeWindowDriver(), args.logger);
|
|
28
|
+
const keyboard = new DefaultNativeKeyboard(keyboardDriver);
|
|
29
|
+
const imageDriverOptions = { enableNlMatcher: true };
|
|
30
|
+
if (nativeConfig?.templatesDir !== undefined)
|
|
31
|
+
imageDriverOptions.templatesDir = nativeConfig.templatesDir;
|
|
32
|
+
if (nativeConfig?.imageConfidence !== undefined)
|
|
33
|
+
imageDriverOptions.confidence = nativeConfig.imageConfidence;
|
|
34
|
+
const imageDriver = new NutNativeImageFinderDriver(imageDriverOptions);
|
|
35
|
+
const images = new DefaultNativeImageFinder(imageDriver, args.config.defaultTimeoutMs);
|
|
36
|
+
const coordinateOptions = {
|
|
37
|
+
images,
|
|
38
|
+
logger: args.logger
|
|
39
|
+
};
|
|
40
|
+
const coordinateTimeoutMs = nativeConfig?.coordinateCalibration?.timeoutMs ?? args.config.defaultTimeoutMs;
|
|
41
|
+
if (coordinateTimeoutMs !== undefined)
|
|
42
|
+
coordinateOptions.defaultTimeoutMs = coordinateTimeoutMs;
|
|
43
|
+
if (nativeConfig?.coordinateCalibration?.cacheTtlMs !== undefined) {
|
|
44
|
+
coordinateOptions.defaultCacheTtlMs = nativeConfig.coordinateCalibration.cacheTtlMs;
|
|
45
|
+
}
|
|
46
|
+
const coordinates = new ImageBasedCoordinateMapper(coordinateOptions);
|
|
47
|
+
const mouseOptions = { coordinateMapper: coordinates };
|
|
48
|
+
if (nativeConfig?.mouse?.jitterPixels !== undefined)
|
|
49
|
+
mouseOptions.jitterPixels = nativeConfig.mouse.jitterPixels;
|
|
50
|
+
if (nativeConfig?.mouse?.minJitterPixels !== undefined)
|
|
51
|
+
mouseOptions.minJitterPixels = nativeConfig.mouse.minJitterPixels;
|
|
52
|
+
if (nativeConfig?.mouse?.moveSpeed !== undefined)
|
|
53
|
+
mouseOptions.moveSpeed = nativeConfig.mouse.moveSpeed;
|
|
54
|
+
const mouse = new HumanizedNativeMouse(mouseDriver, mouseOptions);
|
|
55
|
+
const windowOptions = {
|
|
56
|
+
driver: windowDriver,
|
|
57
|
+
screen: screenDriver,
|
|
58
|
+
mouse,
|
|
59
|
+
images,
|
|
60
|
+
logger: args.logger
|
|
61
|
+
};
|
|
62
|
+
if (args.config.defaultTimeoutMs !== undefined)
|
|
63
|
+
windowOptions.defaultTimeoutMs = args.config.defaultTimeoutMs;
|
|
64
|
+
const windows = new DefaultNativeWindowService(windowOptions);
|
|
65
|
+
const fileDialogOptions = {
|
|
66
|
+
keyboard,
|
|
67
|
+
mouse,
|
|
68
|
+
images,
|
|
69
|
+
accessibility: new MacOSFileDialogAccessibilityStrategy(appleScriptClient, nativeConfig?.macos?.targetApplicationName ?? 'Google Chrome'),
|
|
70
|
+
logger: args.logger
|
|
71
|
+
};
|
|
72
|
+
if (args.config.defaultTimeoutMs !== undefined)
|
|
73
|
+
fileDialogOptions.defaultTimeoutMs = args.config.defaultTimeoutMs;
|
|
74
|
+
const fileDialogs = new DefaultNativeFileDialogService(fileDialogOptions);
|
|
75
|
+
const automation = {
|
|
76
|
+
windows,
|
|
77
|
+
fileDialogs,
|
|
78
|
+
mouse,
|
|
79
|
+
keyboard,
|
|
80
|
+
coordinates,
|
|
81
|
+
images,
|
|
82
|
+
actions: undefined
|
|
83
|
+
};
|
|
84
|
+
const registry = new DefaultNativeActionRegistry(() => ({ automation, logger: args.logger }));
|
|
85
|
+
automation.actions = registerDefaultNativeActions(registry, automation, args.logger);
|
|
86
|
+
return automation;
|
|
87
|
+
}
|
|
88
|
+
//# sourceMappingURL=MacOSNativeAutomation.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"MacOSNativeAutomation.js","sourceRoot":"","sources":["../../../src/native/macos/MacOSNativeAutomation.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import type { NativeImageFinderDriver } from '../NativeImageFinder.js';
|
|
2
|
+
import type { NativeImageMatch, NativeImageSearchOptions, NativeTemplateRef } from '../types.js';
|
|
3
|
+
export interface NutNativeImageFinderOptions {
|
|
4
|
+
templatesDir?: string;
|
|
5
|
+
confidence?: number;
|
|
6
|
+
enableNlMatcher?: boolean;
|
|
7
|
+
}
|
|
8
|
+
export declare class NutNativeImageFinderDriver implements NativeImageFinderDriver {
|
|
9
|
+
private readonly options;
|
|
10
|
+
private initialized;
|
|
11
|
+
constructor(options?: NutNativeImageFinderOptions);
|
|
12
|
+
findTemplate(template: string | NativeTemplateRef, options?: NativeImageSearchOptions): Promise<NativeImageMatch | null>;
|
|
13
|
+
private initialize;
|
|
14
|
+
private buildSearchOptions;
|
|
15
|
+
private materializeTemplate;
|
|
16
|
+
}
|
|
17
|
+
//# sourceMappingURL=NutNativeImageFinder.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"NutNativeImageFinder.d.ts","sourceRoot":"","sources":["../../../src/native/nut/NutNativeImageFinder.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,uBAAuB,EAAE,MAAM,yBAAyB,CAAC;AACvE,OAAO,KAAK,EAAE,gBAAgB,EAAE,wBAAwB,EAAgB,iBAAiB,EAAE,MAAM,aAAa,CAAC;AAG/G,MAAM,WAAW,2BAA2B;IAC1C,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,eAAe,CAAC,EAAE,OAAO,CAAC;CAC3B;AAeD,qBAAa,0BAA2B,YAAW,uBAAuB;IAG5D,OAAO,CAAC,QAAQ,CAAC,OAAO;IAFpC,OAAO,CAAC,WAAW,CAAS;gBAEC,OAAO,GAAE,2BAAgC;IAEhE,YAAY,CAAC,QAAQ,EAAE,MAAM,GAAG,iBAAiB,EAAE,OAAO,GAAE,wBAA6B,GAAG,OAAO,CAAC,gBAAgB,GAAG,IAAI,CAAC;YAmBpH,UAAU;IAiBxB,OAAO,CAAC,kBAAkB;YAgBZ,mBAAmB;CAclC"}
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
import fs from 'node:fs/promises';
|
|
2
|
+
import os from 'node:os';
|
|
3
|
+
import path from 'node:path';
|
|
4
|
+
import { loadNlMatcher, loadNut } from './loadNut.js';
|
|
5
|
+
function toRegion(region) {
|
|
6
|
+
return {
|
|
7
|
+
x: region.left ?? region.x ?? 0,
|
|
8
|
+
y: region.top ?? region.y ?? 0,
|
|
9
|
+
width: region.width,
|
|
10
|
+
height: region.height
|
|
11
|
+
};
|
|
12
|
+
}
|
|
13
|
+
function templateName(template) {
|
|
14
|
+
return typeof template === 'string' ? template : template.name;
|
|
15
|
+
}
|
|
16
|
+
export class NutNativeImageFinderDriver {
|
|
17
|
+
options;
|
|
18
|
+
initialized = false;
|
|
19
|
+
constructor(options = {}) {
|
|
20
|
+
this.options = options;
|
|
21
|
+
}
|
|
22
|
+
async findTemplate(template, options = {}) {
|
|
23
|
+
const nut = await this.initialize();
|
|
24
|
+
if (nut.screen.find === undefined || nut.imageResource === undefined) {
|
|
25
|
+
return null;
|
|
26
|
+
}
|
|
27
|
+
const resourcePath = await this.materializeTemplate(template);
|
|
28
|
+
const searchOptions = this.buildSearchOptions(options);
|
|
29
|
+
try {
|
|
30
|
+
const region = await nut.screen.find(nut.imageResource(resourcePath), searchOptions);
|
|
31
|
+
const match = { region: toRegion(region) };
|
|
32
|
+
if (options.confidence !== undefined)
|
|
33
|
+
match.confidence = options.confidence;
|
|
34
|
+
return match;
|
|
35
|
+
}
|
|
36
|
+
catch {
|
|
37
|
+
return null;
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
async initialize() {
|
|
41
|
+
const nut = await loadNut();
|
|
42
|
+
if (!this.initialized) {
|
|
43
|
+
if (this.options.enableNlMatcher ?? true) {
|
|
44
|
+
await loadNlMatcher();
|
|
45
|
+
}
|
|
46
|
+
if (this.options.templatesDir !== undefined && nut.screen.config !== undefined) {
|
|
47
|
+
nut.screen.config.resourceDirectory = this.options.templatesDir;
|
|
48
|
+
}
|
|
49
|
+
if (this.options.confidence !== undefined && nut.screen.config !== undefined) {
|
|
50
|
+
nut.screen.config.confidence = this.options.confidence;
|
|
51
|
+
}
|
|
52
|
+
this.initialized = true;
|
|
53
|
+
}
|
|
54
|
+
return nut;
|
|
55
|
+
}
|
|
56
|
+
buildSearchOptions(options) {
|
|
57
|
+
const searchOptions = {};
|
|
58
|
+
if (options.searchRegion !== undefined) {
|
|
59
|
+
searchOptions.searchRegion = {
|
|
60
|
+
left: options.searchRegion.x,
|
|
61
|
+
top: options.searchRegion.y,
|
|
62
|
+
width: options.searchRegion.width,
|
|
63
|
+
height: options.searchRegion.height
|
|
64
|
+
};
|
|
65
|
+
}
|
|
66
|
+
if (options.confidence !== undefined) {
|
|
67
|
+
searchOptions.confidence = options.confidence;
|
|
68
|
+
}
|
|
69
|
+
return Object.keys(searchOptions).length === 0 ? undefined : searchOptions;
|
|
70
|
+
}
|
|
71
|
+
async materializeTemplate(template) {
|
|
72
|
+
if (typeof template === 'string') {
|
|
73
|
+
return this.options.templatesDir === undefined ? template : path.join(this.options.templatesDir, template);
|
|
74
|
+
}
|
|
75
|
+
if (template.buffer === undefined) {
|
|
76
|
+
return this.options.templatesDir === undefined ? template.name : path.join(this.options.templatesDir, template.name);
|
|
77
|
+
}
|
|
78
|
+
const fileName = `${template.name.replace(/[^a-z0-9._-]/gi, '_')}`;
|
|
79
|
+
const filePath = path.join(os.tmpdir(), fileName);
|
|
80
|
+
await fs.writeFile(filePath, template.buffer);
|
|
81
|
+
return filePath;
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
//# sourceMappingURL=NutNativeImageFinder.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"NutNativeImageFinder.js","sourceRoot":"","sources":["../../../src/native/nut/NutNativeImageFinder.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,kBAAkB,CAAC;AAClC,OAAO,EAAE,MAAM,SAAS,CAAC;AACzB,OAAO,IAAI,MAAM,WAAW,CAAC;AAG7B,OAAO,EAAE,aAAa,EAAE,OAAO,EAAkB,MAAM,cAAc,CAAC;AAQtE,SAAS,QAAQ,CAAC,MAAiB;IACjC,OAAO;QACL,CAAC,EAAE,MAAM,CAAC,IAAI,IAAI,MAAM,CAAC,CAAC,IAAI,CAAC;QAC/B,CAAC,EAAE,MAAM,CAAC,GAAG,IAAI,MAAM,CAAC,CAAC,IAAI,CAAC;QAC9B,KAAK,EAAE,MAAM,CAAC,KAAK;QACnB,MAAM,EAAE,MAAM,CAAC,MAAM;KACtB,CAAC;AACJ,CAAC;AAED,SAAS,YAAY,CAAC,QAAoC;IACxD,OAAO,OAAO,QAAQ,KAAK,QAAQ,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,QAAQ,CAAC,IAAI,CAAC;AACjE,CAAC;AAED,MAAM,OAAO,0BAA0B;IAGR;IAFrB,WAAW,GAAG,KAAK,CAAC;IAE5B,YAA6B,UAAuC,EAAE;QAAzC,YAAO,GAAP,OAAO,CAAkC;IAAG,CAAC;IAE1E,KAAK,CAAC,YAAY,CAAC,QAAoC,EAAE,UAAoC,EAAE;QAC7F,MAAM,GAAG,GAAG,MAAM,IAAI,CAAC,UAAU,EAAE,CAAC;QACpC,IAAI,GAAG,CAAC,MAAM,CAAC,IAAI,KAAK,SAAS,IAAI,GAAG,CAAC,aAAa,KAAK,SAAS,EAAE,CAAC;YACrE,OAAO,IAAI,CAAC;QACd,CAAC;QAED,MAAM,YAAY,GAAG,MAAM,IAAI,CAAC,mBAAmB,CAAC,QAAQ,CAAC,CAAC;QAC9D,MAAM,aAAa,GAAG,IAAI,CAAC,kBAAkB,CAAC,OAAO,CAAC,CAAC;QAEvD,IAAI,CAAC;YACH,MAAM,MAAM,GAAG,MAAM,GAAG,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,aAAa,CAAC,YAAY,CAAC,EAAE,aAAa,CAAC,CAAC;YACrF,MAAM,KAAK,GAAqB,EAAE,MAAM,EAAE,QAAQ,CAAC,MAAM,CAAC,EAAE,CAAC;YAC7D,IAAI,OAAO,CAAC,UAAU,KAAK,SAAS;gBAAE,KAAK,CAAC,UAAU,GAAG,OAAO,CAAC,UAAU,CAAC;YAC5E,OAAO,KAAK,CAAC;QACf,CAAC;QAAC,MAAM,CAAC;YACP,OAAO,IAAI,CAAC;QACd,CAAC;IACH,CAAC;IAEO,KAAK,CAAC,UAAU;QACtB,MAAM,GAAG,GAAG,MAAM,OAAO,EAAE,CAAC;QAC5B,IAAI,CAAC,IAAI,CAAC,WAAW,EAAE,CAAC;YACtB,IAAI,IAAI,CAAC,OAAO,CAAC,eAAe,IAAI,IAAI,EAAE,CAAC;gBACzC,MAAM,aAAa,EAAE,CAAC;YACxB,CAAC;YACD,IAAI,IAAI,CAAC,OAAO,CAAC,YAAY,KAAK,SAAS,IAAI,GAAG,CAAC,MAAM,CAAC,MAAM,KAAK,SAAS,EAAE,CAAC;gBAC/E,GAAG,CAAC,MAAM,CAAC,MAAM,CAAC,iBAAiB,GAAG,IAAI,CAAC,OAAO,CAAC,YAAY,CAAC;YAClE,CAAC;YACD,IAAI,IAAI,CAAC,OAAO,CAAC,UAAU,KAAK,SAAS,IAAI,GAAG,CAAC,MAAM,CAAC,MAAM,KAAK,SAAS,EAAE,CAAC;gBAC7E,GAAG,CAAC,MAAM,CAAC,MAAM,CAAC,UAAU,GAAG,IAAI,CAAC,OAAO,CAAC,UAAU,CAAC;YACzD,CAAC;YACD,IAAI,CAAC,WAAW,GAAG,IAAI,CAAC;QAC1B,CAAC;QACD,OAAO,GAAG,CAAC;IACb,CAAC;IAEO,kBAAkB,CAAC,OAAiC;QAC1D,MAAM,aAAa,GAA4B,EAAE,CAAC;QAClD,IAAI,OAAO,CAAC,YAAY,KAAK,SAAS,EAAE,CAAC;YACvC,aAAa,CAAC,YAAY,GAAG;gBAC3B,IAAI,EAAE,OAAO,CAAC,YAAY,CAAC,CAAC;gBAC5B,GAAG,EAAE,OAAO,CAAC,YAAY,CAAC,CAAC;gBAC3B,KAAK,EAAE,OAAO,CAAC,YAAY,CAAC,KAAK;gBACjC,MAAM,EAAE,OAAO,CAAC,YAAY,CAAC,MAAM;aACpC,CAAC;QACJ,CAAC;QACD,IAAI,OAAO,CAAC,UAAU,KAAK,SAAS,EAAE,CAAC;YACrC,aAAa,CAAC,UAAU,GAAG,OAAO,CAAC,UAAU,CAAC;QAChD,CAAC;QACD,OAAO,MAAM,CAAC,IAAI,CAAC,aAAa,CAAC,CAAC,MAAM,KAAK,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,aAAa,CAAC;IAC7E,CAAC;IAEO,KAAK,CAAC,mBAAmB,CAAC,QAAoC;QACpE,IAAI,OAAO,QAAQ,KAAK,QAAQ,EAAE,CAAC;YACjC,OAAO,IAAI,CAAC,OAAO,CAAC,YAAY,KAAK,SAAS,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,YAAY,EAAE,QAAQ,CAAC,CAAC;QAC7G,CAAC;QAED,IAAI,QAAQ,CAAC,MAAM,KAAK,SAAS,EAAE,CAAC;YAClC,OAAO,IAAI,CAAC,OAAO,CAAC,YAAY,KAAK,SAAS,CAAC,CAAC,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,YAAY,EAAE,QAAQ,CAAC,IAAI,CAAC,CAAC;QACvH,CAAC;QAED,MAAM,QAAQ,GAAG,GAAG,QAAQ,CAAC,IAAI,CAAC,OAAO,CAAC,gBAAgB,EAAE,GAAG,CAAC,EAAE,CAAC;QACnE,MAAM,QAAQ,GAAG,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,MAAM,EAAE,EAAE,QAAQ,CAAC,CAAC;QAClD,MAAM,EAAE,CAAC,SAAS,CAAC,QAAQ,EAAE,QAAQ,CAAC,MAAM,CAAC,CAAC;QAC9C,OAAO,QAAQ,CAAC;IAClB,CAAC;CACF"}
|