@spotterjs/node 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +69 -0
- package/README.md +50 -0
- package/index.d.ts +209 -0
- package/index.js +387 -0
- package/index.win32-x64-msvc.node +0 -0
- package/package.json +47 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
spotterjs License 1.0
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 spotterjs Contributors
|
|
4
|
+
|
|
5
|
+
Permission is granted, free of charge, to any person obtaining a copy of this
|
|
6
|
+
software and associated documentation files (the "Software"), to use the
|
|
7
|
+
Software subject to the terms below.
|
|
8
|
+
|
|
9
|
+
1. Permitted Use Without Commercial Authorization
|
|
10
|
+
|
|
11
|
+
You may use, copy, modify, and distribute the Software without prior written
|
|
12
|
+
approval from the copyright holder for the following non-commercial purposes
|
|
13
|
+
only:
|
|
14
|
+
|
|
15
|
+
(a) Personal learning and skill development;
|
|
16
|
+
(b) Classroom teaching and academic coursework;
|
|
17
|
+
(c) Non-commercial research, experimentation, and evaluation;
|
|
18
|
+
(d) Contributing to or developing the Software in a public source repository,
|
|
19
|
+
provided such use remains non-commercial.
|
|
20
|
+
|
|
21
|
+
2. Commercial Use Requires Authorization
|
|
22
|
+
|
|
23
|
+
"Commercial Use" means any use of the Software (including incorporation,
|
|
24
|
+
distribution, or operation) in connection with activities intended to generate
|
|
25
|
+
revenue or commercial advantage, including but not limited to:
|
|
26
|
+
|
|
27
|
+
(a) Products or services offered for a fee;
|
|
28
|
+
(b) Software-as-a-Service (SaaS) or hosted automation offerings;
|
|
29
|
+
(c) Internal production or operational systems of a for-profit entity;
|
|
30
|
+
(d) Delivery of automation solutions to paying clients or customers;
|
|
31
|
+
(e) Sublicensing the Software for a fee.
|
|
32
|
+
|
|
33
|
+
Commercial Use is permitted only after obtaining explicit written authorization
|
|
34
|
+
from the copyright holder. Until such authorization is granted, Commercial Use
|
|
35
|
+
is not permitted.
|
|
36
|
+
|
|
37
|
+
To request commercial authorization, contact:
|
|
38
|
+
|
|
39
|
+
Email: ypl123698745@qq.com
|
|
40
|
+
Gitee Issues: https://gitee.com/ypl0lpy/spotterjs/issues
|
|
41
|
+
|
|
42
|
+
3. Redistribution
|
|
43
|
+
|
|
44
|
+
You may redistribute unmodified or modified copies of the Software only for
|
|
45
|
+
Permitted Use under Section 1, or for Commercial Use that has been authorized
|
|
46
|
+
under Section 2. Redistributions must include a copy of this license and retain
|
|
47
|
+
copyright notices.
|
|
48
|
+
|
|
49
|
+
4. Reserved Rights
|
|
50
|
+
|
|
51
|
+
The copyright holder reserves all rights not expressly granted herein,
|
|
52
|
+
including rights in trademarks and branding associated with "spotterjs". No
|
|
53
|
+
patent rights are granted by this license.
|
|
54
|
+
|
|
55
|
+
5. Disclaimer
|
|
56
|
+
|
|
57
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
58
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
59
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
60
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
61
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
62
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
63
|
+
SOFTWARE.
|
|
64
|
+
|
|
65
|
+
6. License Updates
|
|
66
|
+
|
|
67
|
+
New versions of this license apply to Software obtained after the license
|
|
68
|
+
update is published. Commercial authorizations granted under a prior version
|
|
69
|
+
remain valid according to the terms agreed at the time of authorization.
|
package/README.md
ADDED
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
# @spotterjs/node
|
|
2
|
+
|
|
3
|
+
spotterjs
|
|
4
|
+
|
|
5
|
+
Node.js native addon (napi-rs) for Spotter. TypeScript definitions are **auto-generated** (`index.d.ts` via `npm run build`).
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
## Capabilities
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
| Area | N-API examples |
|
|
14
|
+
|
|
15
|
+
|------|----------------|
|
|
16
|
+
|
|
17
|
+
| Screen | `getScreenSize`, `captureScreen`, `captureWindow` |
|
|
18
|
+
|
|
19
|
+
| Match | spotterjsmplate(path, needleBuffer?, opts?)`, `findAllTemplates`, `waitForTemplate`, `findTemplateBuffers` |
|
|
20
|
+
|
|
21
|
+
| Window match | `findTemplateInWindow`, `findAllTemplatesInWindow` (optional `needleBuffer`) |
|
|
22
|
+
|
|
23
|
+
| Window | `listWindows`, `getActiveWindow`, `focusWindow`, `moveWindow`, `resizeWindow`, … |
|
|
24
|
+
|
|
25
|
+
| Desktop apps | `listDesktopApps`, `findDesktopApps`, `findWindowsByTitle`, `waitForWindowByTitle` |
|
|
26
|
+
|
|
27
|
+
| Input | `mouseMove`, `mouseClick`, `setMouseConfig`, `keyboardTypeText`, `clipboardGet`, … |
|
|
28
|
+
|
|
29
|
+
| Accessibility | `accessibilityEnable`, `accessibilityFind`, `accessibilityInvoke`, … |
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
|
|
33
|
+
Platforms (prebuilt on publish): `x86_64-pc-windows-msvc`, `x86_64-unknown-linux-gnu`.
|
|
34
|
+
|
|
35
|
+
|
|
36
|
+
|
|
37
|
+
Prefer [`@spotterjs/core`](../../packages/core) (`screen`, `mouse`, `windowApi`, …) over calling this package directly.
|
|
38
|
+
|
|
39
|
+
|
|
40
|
+
|
|
41
|
+
See [docs/MATCHING.md](../../docs/MATCHING.md) for template matching usage.
|
|
42
|
+
|
|
43
|
+
|
|
44
|
+
|
|
45
|
+
## License
|
|
46
|
+
|
|
47
|
+
|
|
48
|
+
|
|
49
|
+
See [LICENSE](../../LICENSE).
|
|
50
|
+
|
package/index.d.ts
ADDED
|
@@ -0,0 +1,209 @@
|
|
|
1
|
+
/* tslint:disable */
|
|
2
|
+
/* eslint-disable */
|
|
3
|
+
|
|
4
|
+
/* auto-generated by NAPI-RS */
|
|
5
|
+
|
|
6
|
+
export interface JsRegion {
|
|
7
|
+
left: number
|
|
8
|
+
top: number
|
|
9
|
+
width: number
|
|
10
|
+
height: number
|
|
11
|
+
}
|
|
12
|
+
export interface JsCaptureImage {
|
|
13
|
+
data: Buffer
|
|
14
|
+
width: number
|
|
15
|
+
height: number
|
|
16
|
+
}
|
|
17
|
+
export interface JsMatchOptions {
|
|
18
|
+
confidence?: number
|
|
19
|
+
searchRegion?: JsRegion
|
|
20
|
+
multiScale?: boolean
|
|
21
|
+
scaleMin?: number
|
|
22
|
+
scaleMax?: number
|
|
23
|
+
scaleStep?: number
|
|
24
|
+
}
|
|
25
|
+
export interface JsPoint {
|
|
26
|
+
x: number
|
|
27
|
+
y: number
|
|
28
|
+
}
|
|
29
|
+
export interface JsWindowInfo {
|
|
30
|
+
id: string
|
|
31
|
+
idHex: string
|
|
32
|
+
title: string
|
|
33
|
+
region: JsRegion
|
|
34
|
+
processId: number
|
|
35
|
+
processName: string
|
|
36
|
+
exePath?: string
|
|
37
|
+
isMinimized: boolean
|
|
38
|
+
isForeground: boolean
|
|
39
|
+
}
|
|
40
|
+
export interface JsDesktopApp {
|
|
41
|
+
processId: number
|
|
42
|
+
processName: string
|
|
43
|
+
exePath?: string
|
|
44
|
+
windows: Array<JsWindowInfo>
|
|
45
|
+
isForeground: boolean
|
|
46
|
+
}
|
|
47
|
+
export interface JsScreenSize {
|
|
48
|
+
width: number
|
|
49
|
+
height: number
|
|
50
|
+
}
|
|
51
|
+
export interface JsMouseConfig {
|
|
52
|
+
autoDelayMs?: number
|
|
53
|
+
mouseSpeed?: number
|
|
54
|
+
}
|
|
55
|
+
export interface JsKeyboardConfig {
|
|
56
|
+
autoDelayMs?: number
|
|
57
|
+
}
|
|
58
|
+
export declare function version(): string
|
|
59
|
+
export declare function getScreenSize(): JsScreenSize
|
|
60
|
+
export declare function getScreenWidth(): number
|
|
61
|
+
export declare function getScreenHeight(): number
|
|
62
|
+
export declare function captureScreen(region?: JsRegion | undefined | null): JsCaptureImage
|
|
63
|
+
export declare function captureWindow(id: string): JsCaptureImage
|
|
64
|
+
export interface JsImageSize {
|
|
65
|
+
width: number
|
|
66
|
+
height: number
|
|
67
|
+
}
|
|
68
|
+
export declare function loadImageFromPath(path: string): JsCaptureImage
|
|
69
|
+
export declare function getImageSize(path: string): JsImageSize
|
|
70
|
+
export declare function encodeCapturePng(capture: JsCaptureImage): Buffer
|
|
71
|
+
export declare function encodeCapturePngBase64(capture: JsCaptureImage): string
|
|
72
|
+
export declare function listWindows(): Array<JsWindowInfo>
|
|
73
|
+
export declare function getActiveWindow(): JsWindowInfo
|
|
74
|
+
export declare function focusWindow(id: string): boolean
|
|
75
|
+
export declare function getWindowRegion(id: string): JsRegion
|
|
76
|
+
export declare function getWindowRegionClamped(id: string): JsRegion
|
|
77
|
+
export declare function getWindowClientOrigin(id: string): JsPoint
|
|
78
|
+
export declare function moveWindow(id: string, x: number, y: number): void
|
|
79
|
+
export declare function resizeWindow(id: string, width: number, height: number): void
|
|
80
|
+
export declare function minimizeWindow(id: string): void
|
|
81
|
+
export declare function restoreWindow(id: string): void
|
|
82
|
+
export declare function listDesktopApps(): Array<JsDesktopApp>
|
|
83
|
+
export declare function findDesktopApps(substring: string): Array<JsDesktopApp>
|
|
84
|
+
export declare function findWindowsByTitle(substring: string): Array<JsWindowInfo>
|
|
85
|
+
export declare function waitForWindowByTitle(substring: string, timeoutMs: number, pollMs?: number | undefined | null): JsWindowInfo
|
|
86
|
+
export declare function getForegroundApp(): JsDesktopApp
|
|
87
|
+
export declare function findTemplate(path: string, needleBuffer?: Buffer | undefined | null, opts?: JsMatchOptions | undefined | null): JsRegion
|
|
88
|
+
export declare function findAllTemplates(path: string, needleBuffer?: Buffer | undefined | null, opts?: JsMatchOptions | undefined | null): Array<JsRegion>
|
|
89
|
+
export declare function findTemplateInWindow(id: string, path: string, needleBuffer?: Buffer | undefined | null, opts?: JsMatchOptions | undefined | null): JsRegion
|
|
90
|
+
export declare function findAllTemplatesInWindow(id: string, path: string, needleBuffer?: Buffer | undefined | null, opts?: JsMatchOptions | undefined | null): Array<JsRegion>
|
|
91
|
+
export declare function waitForTemplate(path: string, needleBuffer: Buffer | undefined | null, timeoutMs: number, opts?: JsMatchOptions | undefined | null, intervalMs?: number | undefined | null): JsRegion
|
|
92
|
+
export declare function findTemplateBuffers(haystack: JsCaptureImage, needle: JsCaptureImage, opts?: JsMatchOptions | undefined | null): JsRegion
|
|
93
|
+
export declare function findAllTemplateBuffers(haystack: JsCaptureImage, needle: JsCaptureImage, opts?: JsMatchOptions | undefined | null): Array<JsRegion>
|
|
94
|
+
export declare function waitForTemplateBuffers(haystack: JsCaptureImage, needle: JsCaptureImage, timeoutMs: number, opts?: JsMatchOptions | undefined | null, intervalMs?: number | undefined | null): JsRegion
|
|
95
|
+
export declare function setMouseConfig(config: JsMouseConfig): void
|
|
96
|
+
export declare function getPosition(): JsPoint
|
|
97
|
+
export declare function mouseMove(x: number, y: number): void
|
|
98
|
+
export declare function mouseMovePath(points: Array<JsPoint>): void
|
|
99
|
+
export declare function mouseMoveStraight(x: number, y: number): void
|
|
100
|
+
export declare function mouseClick(button?: string | undefined | null): void
|
|
101
|
+
export declare function mouseDoubleClick(button?: string | undefined | null): void
|
|
102
|
+
export declare function mousePress(button?: string | undefined | null): void
|
|
103
|
+
export declare function mouseRelease(button?: string | undefined | null): void
|
|
104
|
+
export declare function mouseDrag(x: number, y: number, button?: string | undefined | null): void
|
|
105
|
+
export declare function mouseScrollUp(amount: number): void
|
|
106
|
+
export declare function mouseScrollDown(amount: number): void
|
|
107
|
+
export declare function mouseScrollLeft(amount: number): void
|
|
108
|
+
export declare function mouseScrollRight(amount: number): void
|
|
109
|
+
export declare function tapAt(x: number, y: number, button?: string | undefined | null): void
|
|
110
|
+
export declare function setKeyboardConfig(config: JsKeyboardConfig): void
|
|
111
|
+
export declare function keyboardTypeText(text: string): void
|
|
112
|
+
export declare function keyboardPressKeys(keys: Array<string>): void
|
|
113
|
+
export declare function keyboardReleaseKeys(keys: Array<string>): void
|
|
114
|
+
export declare function keyboardTypeKey(key: string): void
|
|
115
|
+
export declare function keyboardShortcut(keys: Array<string>): void
|
|
116
|
+
export declare function clipboardSet(text: string): void
|
|
117
|
+
export declare function clipboardGet(): string
|
|
118
|
+
export interface JsA11YConfig {
|
|
119
|
+
attachDelayMs?: number
|
|
120
|
+
eventSubscription?: boolean
|
|
121
|
+
treeWaitTimeoutMs?: number
|
|
122
|
+
treeWaitPollMs?: number
|
|
123
|
+
minListItemCount?: number
|
|
124
|
+
treeView?: string
|
|
125
|
+
}
|
|
126
|
+
export interface JsAttachCandidate {
|
|
127
|
+
hwnd: string
|
|
128
|
+
className: string
|
|
129
|
+
totalNodes: number
|
|
130
|
+
listItemCount: number
|
|
131
|
+
editCount: number
|
|
132
|
+
chosen: boolean
|
|
133
|
+
}
|
|
134
|
+
export interface JsAttachReport {
|
|
135
|
+
elementId: string
|
|
136
|
+
clientMode: boolean
|
|
137
|
+
eventHandlerRegistered: boolean
|
|
138
|
+
structureChangedEvents: number
|
|
139
|
+
healthInitial: JsTreeHealth
|
|
140
|
+
healthFinal: JsTreeHealth
|
|
141
|
+
treeWaitMs: number
|
|
142
|
+
attachStrategy: string
|
|
143
|
+
attachedHwnd: string
|
|
144
|
+
treeView: string
|
|
145
|
+
candidates: Array<JsAttachCandidate>
|
|
146
|
+
diagnosis: Array<string>
|
|
147
|
+
}
|
|
148
|
+
export interface JsA11YBounds {
|
|
149
|
+
left: number
|
|
150
|
+
top: number
|
|
151
|
+
width: number
|
|
152
|
+
height: number
|
|
153
|
+
}
|
|
154
|
+
export interface JsElementInfo {
|
|
155
|
+
name: string
|
|
156
|
+
controlType: string
|
|
157
|
+
automationId: string
|
|
158
|
+
className: string
|
|
159
|
+
frameworkId: string
|
|
160
|
+
runtimeId: string
|
|
161
|
+
isOffscreen: boolean
|
|
162
|
+
patterns: Array<string>
|
|
163
|
+
bounds?: JsA11YBounds
|
|
164
|
+
}
|
|
165
|
+
export interface JsTreeNodeDump {
|
|
166
|
+
depth: number
|
|
167
|
+
name: string
|
|
168
|
+
controlType: string
|
|
169
|
+
automationId: string
|
|
170
|
+
className: string
|
|
171
|
+
frameworkId: string
|
|
172
|
+
runtimeId: string
|
|
173
|
+
isOffscreen: boolean
|
|
174
|
+
patterns: Array<string>
|
|
175
|
+
bounds?: JsA11YBounds
|
|
176
|
+
children?: Array<JsTreeNodeDump>
|
|
177
|
+
}
|
|
178
|
+
export interface JsA11YQuery {
|
|
179
|
+
name?: string
|
|
180
|
+
nameContains?: string
|
|
181
|
+
controlType?: string
|
|
182
|
+
automationId?: string
|
|
183
|
+
matchMode?: string
|
|
184
|
+
}
|
|
185
|
+
export interface JsTreeHealth {
|
|
186
|
+
maxDepth: number
|
|
187
|
+
totalNodes: number
|
|
188
|
+
listItemCount: number
|
|
189
|
+
editCount: number
|
|
190
|
+
buttonCount: number
|
|
191
|
+
controlTypeCounts: Record<string, number>
|
|
192
|
+
}
|
|
193
|
+
export declare function accessibilityEnable(config?: JsA11YConfig | undefined | null): void
|
|
194
|
+
export declare function accessibilityDisable(): void
|
|
195
|
+
export declare function accessibilityIsEnabled(): boolean
|
|
196
|
+
export declare function accessibilityAttachWindow(windowId: string): string
|
|
197
|
+
export declare function accessibilityAttachWindowReport(windowId: string, maxDepth?: number | undefined | null): JsAttachReport
|
|
198
|
+
export declare function accessibilityAttachActive(): string
|
|
199
|
+
export declare function accessibilityFind(rootId: string, query: JsA11YQuery, maxDepth?: number | undefined | null): string
|
|
200
|
+
export declare function accessibilityWaitFor(rootId: string, query: JsA11YQuery, timeoutMs: number, maxDepth?: number | undefined | null, pollMs?: number | undefined | null): string
|
|
201
|
+
export declare function accessibilityGetBounds(elementId: string): JsRegion
|
|
202
|
+
export declare function accessibilityInvoke(elementId: string): void
|
|
203
|
+
export declare function accessibilitySetValue(elementId: string, text: string): void
|
|
204
|
+
export declare function accessibilityDumpTree(rootId: string, maxDepth?: number | undefined | null, treeView?: string | undefined | null): string
|
|
205
|
+
export declare function accessibilityDumpTreeObject(rootId: string, maxDepth?: number | undefined | null, treeView?: string | undefined | null): JsTreeNodeDump
|
|
206
|
+
export declare function accessibilityGetElementInfo(elementId: string): JsElementInfo
|
|
207
|
+
export declare function accessibilityRefreshRoot(elementId: string): void
|
|
208
|
+
export declare function accessibilityTreeHealth(rootId: string, maxDepth?: number | undefined | null, treeView?: string | undefined | null): JsTreeHealth
|
|
209
|
+
export declare function accessibilityCheckTreeHealth(rootId: string, maxDepth: number | undefined | null, minListItems: number): JsTreeHealth
|
package/index.js
ADDED
|
@@ -0,0 +1,387 @@
|
|
|
1
|
+
/* tslint:disable */
|
|
2
|
+
/* eslint-disable */
|
|
3
|
+
/* prettier-ignore */
|
|
4
|
+
|
|
5
|
+
/* auto-generated by NAPI-RS */
|
|
6
|
+
|
|
7
|
+
const { existsSync, readFileSync } = require('fs')
|
|
8
|
+
const { join } = require('path')
|
|
9
|
+
|
|
10
|
+
const { platform, arch } = process
|
|
11
|
+
|
|
12
|
+
let nativeBinding = null
|
|
13
|
+
let localFileExisted = false
|
|
14
|
+
let loadError = null
|
|
15
|
+
|
|
16
|
+
function isMusl() {
|
|
17
|
+
// For Node 10
|
|
18
|
+
if (!process.report || typeof process.report.getReport !== 'function') {
|
|
19
|
+
try {
|
|
20
|
+
const lddPath = require('child_process').execSync('which ldd').toString().trim()
|
|
21
|
+
return readFileSync(lddPath, 'utf8').includes('musl')
|
|
22
|
+
} catch (e) {
|
|
23
|
+
return true
|
|
24
|
+
}
|
|
25
|
+
} else {
|
|
26
|
+
const { glibcVersionRuntime } = process.report.getReport().header
|
|
27
|
+
return !glibcVersionRuntime
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
switch (platform) {
|
|
32
|
+
case 'android':
|
|
33
|
+
switch (arch) {
|
|
34
|
+
case 'arm64':
|
|
35
|
+
localFileExisted = existsSync(join(__dirname, 'index.android-arm64.node'))
|
|
36
|
+
try {
|
|
37
|
+
if (localFileExisted) {
|
|
38
|
+
nativeBinding = require('./index.android-arm64.node')
|
|
39
|
+
} else {
|
|
40
|
+
nativeBinding = require('@spotterjs/node-android-arm64')
|
|
41
|
+
}
|
|
42
|
+
} catch (e) {
|
|
43
|
+
loadError = e
|
|
44
|
+
}
|
|
45
|
+
break
|
|
46
|
+
case 'arm':
|
|
47
|
+
localFileExisted = existsSync(join(__dirname, 'index.android-arm-eabi.node'))
|
|
48
|
+
try {
|
|
49
|
+
if (localFileExisted) {
|
|
50
|
+
nativeBinding = require('./index.android-arm-eabi.node')
|
|
51
|
+
} else {
|
|
52
|
+
nativeBinding = require('@spotterjs/node-android-arm-eabi')
|
|
53
|
+
}
|
|
54
|
+
} catch (e) {
|
|
55
|
+
loadError = e
|
|
56
|
+
}
|
|
57
|
+
break
|
|
58
|
+
default:
|
|
59
|
+
throw new Error(`Unsupported architecture on Android ${arch}`)
|
|
60
|
+
}
|
|
61
|
+
break
|
|
62
|
+
case 'win32':
|
|
63
|
+
switch (arch) {
|
|
64
|
+
case 'x64':
|
|
65
|
+
localFileExisted = existsSync(
|
|
66
|
+
join(__dirname, 'index.win32-x64-msvc.node')
|
|
67
|
+
)
|
|
68
|
+
try {
|
|
69
|
+
if (localFileExisted) {
|
|
70
|
+
nativeBinding = require('./index.win32-x64-msvc.node')
|
|
71
|
+
} else {
|
|
72
|
+
nativeBinding = require('@spotterjs/node-win32-x64-msvc')
|
|
73
|
+
}
|
|
74
|
+
} catch (e) {
|
|
75
|
+
loadError = e
|
|
76
|
+
}
|
|
77
|
+
break
|
|
78
|
+
case 'ia32':
|
|
79
|
+
localFileExisted = existsSync(
|
|
80
|
+
join(__dirname, 'index.win32-ia32-msvc.node')
|
|
81
|
+
)
|
|
82
|
+
try {
|
|
83
|
+
if (localFileExisted) {
|
|
84
|
+
nativeBinding = require('./index.win32-ia32-msvc.node')
|
|
85
|
+
} else {
|
|
86
|
+
nativeBinding = require('@spotterjs/node-win32-ia32-msvc')
|
|
87
|
+
}
|
|
88
|
+
} catch (e) {
|
|
89
|
+
loadError = e
|
|
90
|
+
}
|
|
91
|
+
break
|
|
92
|
+
case 'arm64':
|
|
93
|
+
localFileExisted = existsSync(
|
|
94
|
+
join(__dirname, 'index.win32-arm64-msvc.node')
|
|
95
|
+
)
|
|
96
|
+
try {
|
|
97
|
+
if (localFileExisted) {
|
|
98
|
+
nativeBinding = require('./index.win32-arm64-msvc.node')
|
|
99
|
+
} else {
|
|
100
|
+
nativeBinding = require('@spotterjs/node-win32-arm64-msvc')
|
|
101
|
+
}
|
|
102
|
+
} catch (e) {
|
|
103
|
+
loadError = e
|
|
104
|
+
}
|
|
105
|
+
break
|
|
106
|
+
default:
|
|
107
|
+
throw new Error(`Unsupported architecture on Windows: ${arch}`)
|
|
108
|
+
}
|
|
109
|
+
break
|
|
110
|
+
case 'darwin':
|
|
111
|
+
localFileExisted = existsSync(join(__dirname, 'index.darwin-universal.node'))
|
|
112
|
+
try {
|
|
113
|
+
if (localFileExisted) {
|
|
114
|
+
nativeBinding = require('./index.darwin-universal.node')
|
|
115
|
+
} else {
|
|
116
|
+
nativeBinding = require('@spotterjs/node-darwin-universal')
|
|
117
|
+
}
|
|
118
|
+
break
|
|
119
|
+
} catch {}
|
|
120
|
+
switch (arch) {
|
|
121
|
+
case 'x64':
|
|
122
|
+
localFileExisted = existsSync(join(__dirname, 'index.darwin-x64.node'))
|
|
123
|
+
try {
|
|
124
|
+
if (localFileExisted) {
|
|
125
|
+
nativeBinding = require('./index.darwin-x64.node')
|
|
126
|
+
} else {
|
|
127
|
+
nativeBinding = require('@spotterjs/node-darwin-x64')
|
|
128
|
+
}
|
|
129
|
+
} catch (e) {
|
|
130
|
+
loadError = e
|
|
131
|
+
}
|
|
132
|
+
break
|
|
133
|
+
case 'arm64':
|
|
134
|
+
localFileExisted = existsSync(
|
|
135
|
+
join(__dirname, 'index.darwin-arm64.node')
|
|
136
|
+
)
|
|
137
|
+
try {
|
|
138
|
+
if (localFileExisted) {
|
|
139
|
+
nativeBinding = require('./index.darwin-arm64.node')
|
|
140
|
+
} else {
|
|
141
|
+
nativeBinding = require('@spotterjs/node-darwin-arm64')
|
|
142
|
+
}
|
|
143
|
+
} catch (e) {
|
|
144
|
+
loadError = e
|
|
145
|
+
}
|
|
146
|
+
break
|
|
147
|
+
default:
|
|
148
|
+
throw new Error(`Unsupported architecture on macOS: ${arch}`)
|
|
149
|
+
}
|
|
150
|
+
break
|
|
151
|
+
case 'freebsd':
|
|
152
|
+
if (arch !== 'x64') {
|
|
153
|
+
throw new Error(`Unsupported architecture on FreeBSD: ${arch}`)
|
|
154
|
+
}
|
|
155
|
+
localFileExisted = existsSync(join(__dirname, 'index.freebsd-x64.node'))
|
|
156
|
+
try {
|
|
157
|
+
if (localFileExisted) {
|
|
158
|
+
nativeBinding = require('./index.freebsd-x64.node')
|
|
159
|
+
} else {
|
|
160
|
+
nativeBinding = require('@spotterjs/node-freebsd-x64')
|
|
161
|
+
}
|
|
162
|
+
} catch (e) {
|
|
163
|
+
loadError = e
|
|
164
|
+
}
|
|
165
|
+
break
|
|
166
|
+
case 'linux':
|
|
167
|
+
switch (arch) {
|
|
168
|
+
case 'x64':
|
|
169
|
+
if (isMusl()) {
|
|
170
|
+
localFileExisted = existsSync(
|
|
171
|
+
join(__dirname, 'index.linux-x64-musl.node')
|
|
172
|
+
)
|
|
173
|
+
try {
|
|
174
|
+
if (localFileExisted) {
|
|
175
|
+
nativeBinding = require('./index.linux-x64-musl.node')
|
|
176
|
+
} else {
|
|
177
|
+
nativeBinding = require('@spotterjs/node-linux-x64-musl')
|
|
178
|
+
}
|
|
179
|
+
} catch (e) {
|
|
180
|
+
loadError = e
|
|
181
|
+
}
|
|
182
|
+
} else {
|
|
183
|
+
localFileExisted = existsSync(
|
|
184
|
+
join(__dirname, 'index.linux-x64-gnu.node')
|
|
185
|
+
)
|
|
186
|
+
try {
|
|
187
|
+
if (localFileExisted) {
|
|
188
|
+
nativeBinding = require('./index.linux-x64-gnu.node')
|
|
189
|
+
} else {
|
|
190
|
+
nativeBinding = require('@spotterjs/node-linux-x64-gnu')
|
|
191
|
+
}
|
|
192
|
+
} catch (e) {
|
|
193
|
+
loadError = e
|
|
194
|
+
}
|
|
195
|
+
}
|
|
196
|
+
break
|
|
197
|
+
case 'arm64':
|
|
198
|
+
if (isMusl()) {
|
|
199
|
+
localFileExisted = existsSync(
|
|
200
|
+
join(__dirname, 'index.linux-arm64-musl.node')
|
|
201
|
+
)
|
|
202
|
+
try {
|
|
203
|
+
if (localFileExisted) {
|
|
204
|
+
nativeBinding = require('./index.linux-arm64-musl.node')
|
|
205
|
+
} else {
|
|
206
|
+
nativeBinding = require('@spotterjs/node-linux-arm64-musl')
|
|
207
|
+
}
|
|
208
|
+
} catch (e) {
|
|
209
|
+
loadError = e
|
|
210
|
+
}
|
|
211
|
+
} else {
|
|
212
|
+
localFileExisted = existsSync(
|
|
213
|
+
join(__dirname, 'index.linux-arm64-gnu.node')
|
|
214
|
+
)
|
|
215
|
+
try {
|
|
216
|
+
if (localFileExisted) {
|
|
217
|
+
nativeBinding = require('./index.linux-arm64-gnu.node')
|
|
218
|
+
} else {
|
|
219
|
+
nativeBinding = require('@spotterjs/node-linux-arm64-gnu')
|
|
220
|
+
}
|
|
221
|
+
} catch (e) {
|
|
222
|
+
loadError = e
|
|
223
|
+
}
|
|
224
|
+
}
|
|
225
|
+
break
|
|
226
|
+
case 'arm':
|
|
227
|
+
if (isMusl()) {
|
|
228
|
+
localFileExisted = existsSync(
|
|
229
|
+
join(__dirname, 'index.linux-arm-musleabihf.node')
|
|
230
|
+
)
|
|
231
|
+
try {
|
|
232
|
+
if (localFileExisted) {
|
|
233
|
+
nativeBinding = require('./index.linux-arm-musleabihf.node')
|
|
234
|
+
} else {
|
|
235
|
+
nativeBinding = require('@spotterjs/node-linux-arm-musleabihf')
|
|
236
|
+
}
|
|
237
|
+
} catch (e) {
|
|
238
|
+
loadError = e
|
|
239
|
+
}
|
|
240
|
+
} else {
|
|
241
|
+
localFileExisted = existsSync(
|
|
242
|
+
join(__dirname, 'index.linux-arm-gnueabihf.node')
|
|
243
|
+
)
|
|
244
|
+
try {
|
|
245
|
+
if (localFileExisted) {
|
|
246
|
+
nativeBinding = require('./index.linux-arm-gnueabihf.node')
|
|
247
|
+
} else {
|
|
248
|
+
nativeBinding = require('@spotterjs/node-linux-arm-gnueabihf')
|
|
249
|
+
}
|
|
250
|
+
} catch (e) {
|
|
251
|
+
loadError = e
|
|
252
|
+
}
|
|
253
|
+
}
|
|
254
|
+
break
|
|
255
|
+
case 'riscv64':
|
|
256
|
+
if (isMusl()) {
|
|
257
|
+
localFileExisted = existsSync(
|
|
258
|
+
join(__dirname, 'index.linux-riscv64-musl.node')
|
|
259
|
+
)
|
|
260
|
+
try {
|
|
261
|
+
if (localFileExisted) {
|
|
262
|
+
nativeBinding = require('./index.linux-riscv64-musl.node')
|
|
263
|
+
} else {
|
|
264
|
+
nativeBinding = require('@spotterjs/node-linux-riscv64-musl')
|
|
265
|
+
}
|
|
266
|
+
} catch (e) {
|
|
267
|
+
loadError = e
|
|
268
|
+
}
|
|
269
|
+
} else {
|
|
270
|
+
localFileExisted = existsSync(
|
|
271
|
+
join(__dirname, 'index.linux-riscv64-gnu.node')
|
|
272
|
+
)
|
|
273
|
+
try {
|
|
274
|
+
if (localFileExisted) {
|
|
275
|
+
nativeBinding = require('./index.linux-riscv64-gnu.node')
|
|
276
|
+
} else {
|
|
277
|
+
nativeBinding = require('@spotterjs/node-linux-riscv64-gnu')
|
|
278
|
+
}
|
|
279
|
+
} catch (e) {
|
|
280
|
+
loadError = e
|
|
281
|
+
}
|
|
282
|
+
}
|
|
283
|
+
break
|
|
284
|
+
case 's390x':
|
|
285
|
+
localFileExisted = existsSync(
|
|
286
|
+
join(__dirname, 'index.linux-s390x-gnu.node')
|
|
287
|
+
)
|
|
288
|
+
try {
|
|
289
|
+
if (localFileExisted) {
|
|
290
|
+
nativeBinding = require('./index.linux-s390x-gnu.node')
|
|
291
|
+
} else {
|
|
292
|
+
nativeBinding = require('@spotterjs/node-linux-s390x-gnu')
|
|
293
|
+
}
|
|
294
|
+
} catch (e) {
|
|
295
|
+
loadError = e
|
|
296
|
+
}
|
|
297
|
+
break
|
|
298
|
+
default:
|
|
299
|
+
throw new Error(`Unsupported architecture on Linux: ${arch}`)
|
|
300
|
+
}
|
|
301
|
+
break
|
|
302
|
+
default:
|
|
303
|
+
throw new Error(`Unsupported OS: ${platform}, architecture: ${arch}`)
|
|
304
|
+
}
|
|
305
|
+
|
|
306
|
+
if (!nativeBinding) {
|
|
307
|
+
if (loadError) {
|
|
308
|
+
throw loadError
|
|
309
|
+
}
|
|
310
|
+
throw new Error(`Failed to load native binding`)
|
|
311
|
+
}
|
|
312
|
+
|
|
313
|
+
const { version, getScreenSize, getScreenWidth, getScreenHeight, captureScreen, captureWindow, loadImageFromPath, getImageSize, encodeCapturePng, encodeCapturePngBase64, listWindows, getActiveWindow, focusWindow, getWindowRegion, getWindowRegionClamped, getWindowClientOrigin, moveWindow, resizeWindow, minimizeWindow, restoreWindow, listDesktopApps, findDesktopApps, findWindowsByTitle, waitForWindowByTitle, getForegroundApp, findTemplate, findAllTemplates, findTemplateInWindow, findAllTemplatesInWindow, waitForTemplate, findTemplateBuffers, findAllTemplateBuffers, waitForTemplateBuffers, setMouseConfig, getPosition, mouseMove, mouseMovePath, mouseMoveStraight, mouseClick, mouseDoubleClick, mousePress, mouseRelease, mouseDrag, mouseScrollUp, mouseScrollDown, mouseScrollLeft, mouseScrollRight, tapAt, setKeyboardConfig, keyboardTypeText, keyboardPressKeys, keyboardReleaseKeys, keyboardTypeKey, keyboardShortcut, clipboardSet, clipboardGet, accessibilityEnable, accessibilityDisable, accessibilityIsEnabled, accessibilityAttachWindow, accessibilityAttachWindowReport, accessibilityAttachActive, accessibilityFind, accessibilityWaitFor, accessibilityGetBounds, accessibilityInvoke, accessibilitySetValue, accessibilityDumpTree, accessibilityDumpTreeObject, accessibilityGetElementInfo, accessibilityRefreshRoot, accessibilityTreeHealth, accessibilityCheckTreeHealth } = nativeBinding
|
|
314
|
+
|
|
315
|
+
module.exports.version = version
|
|
316
|
+
module.exports.getScreenSize = getScreenSize
|
|
317
|
+
module.exports.getScreenWidth = getScreenWidth
|
|
318
|
+
module.exports.getScreenHeight = getScreenHeight
|
|
319
|
+
module.exports.captureScreen = captureScreen
|
|
320
|
+
module.exports.captureWindow = captureWindow
|
|
321
|
+
module.exports.loadImageFromPath = loadImageFromPath
|
|
322
|
+
module.exports.getImageSize = getImageSize
|
|
323
|
+
module.exports.encodeCapturePng = encodeCapturePng
|
|
324
|
+
module.exports.encodeCapturePngBase64 = encodeCapturePngBase64
|
|
325
|
+
module.exports.listWindows = listWindows
|
|
326
|
+
module.exports.getActiveWindow = getActiveWindow
|
|
327
|
+
module.exports.focusWindow = focusWindow
|
|
328
|
+
module.exports.getWindowRegion = getWindowRegion
|
|
329
|
+
module.exports.getWindowRegionClamped = getWindowRegionClamped
|
|
330
|
+
module.exports.getWindowClientOrigin = getWindowClientOrigin
|
|
331
|
+
module.exports.moveWindow = moveWindow
|
|
332
|
+
module.exports.resizeWindow = resizeWindow
|
|
333
|
+
module.exports.minimizeWindow = minimizeWindow
|
|
334
|
+
module.exports.restoreWindow = restoreWindow
|
|
335
|
+
module.exports.listDesktopApps = listDesktopApps
|
|
336
|
+
module.exports.findDesktopApps = findDesktopApps
|
|
337
|
+
module.exports.findWindowsByTitle = findWindowsByTitle
|
|
338
|
+
module.exports.waitForWindowByTitle = waitForWindowByTitle
|
|
339
|
+
module.exports.getForegroundApp = getForegroundApp
|
|
340
|
+
module.exports.findTemplate = findTemplate
|
|
341
|
+
module.exports.findAllTemplates = findAllTemplates
|
|
342
|
+
module.exports.findTemplateInWindow = findTemplateInWindow
|
|
343
|
+
module.exports.findAllTemplatesInWindow = findAllTemplatesInWindow
|
|
344
|
+
module.exports.waitForTemplate = waitForTemplate
|
|
345
|
+
module.exports.findTemplateBuffers = findTemplateBuffers
|
|
346
|
+
module.exports.findAllTemplateBuffers = findAllTemplateBuffers
|
|
347
|
+
module.exports.waitForTemplateBuffers = waitForTemplateBuffers
|
|
348
|
+
module.exports.setMouseConfig = setMouseConfig
|
|
349
|
+
module.exports.getPosition = getPosition
|
|
350
|
+
module.exports.mouseMove = mouseMove
|
|
351
|
+
module.exports.mouseMovePath = mouseMovePath
|
|
352
|
+
module.exports.mouseMoveStraight = mouseMoveStraight
|
|
353
|
+
module.exports.mouseClick = mouseClick
|
|
354
|
+
module.exports.mouseDoubleClick = mouseDoubleClick
|
|
355
|
+
module.exports.mousePress = mousePress
|
|
356
|
+
module.exports.mouseRelease = mouseRelease
|
|
357
|
+
module.exports.mouseDrag = mouseDrag
|
|
358
|
+
module.exports.mouseScrollUp = mouseScrollUp
|
|
359
|
+
module.exports.mouseScrollDown = mouseScrollDown
|
|
360
|
+
module.exports.mouseScrollLeft = mouseScrollLeft
|
|
361
|
+
module.exports.mouseScrollRight = mouseScrollRight
|
|
362
|
+
module.exports.tapAt = tapAt
|
|
363
|
+
module.exports.setKeyboardConfig = setKeyboardConfig
|
|
364
|
+
module.exports.keyboardTypeText = keyboardTypeText
|
|
365
|
+
module.exports.keyboardPressKeys = keyboardPressKeys
|
|
366
|
+
module.exports.keyboardReleaseKeys = keyboardReleaseKeys
|
|
367
|
+
module.exports.keyboardTypeKey = keyboardTypeKey
|
|
368
|
+
module.exports.keyboardShortcut = keyboardShortcut
|
|
369
|
+
module.exports.clipboardSet = clipboardSet
|
|
370
|
+
module.exports.clipboardGet = clipboardGet
|
|
371
|
+
module.exports.accessibilityEnable = accessibilityEnable
|
|
372
|
+
module.exports.accessibilityDisable = accessibilityDisable
|
|
373
|
+
module.exports.accessibilityIsEnabled = accessibilityIsEnabled
|
|
374
|
+
module.exports.accessibilityAttachWindow = accessibilityAttachWindow
|
|
375
|
+
module.exports.accessibilityAttachWindowReport = accessibilityAttachWindowReport
|
|
376
|
+
module.exports.accessibilityAttachActive = accessibilityAttachActive
|
|
377
|
+
module.exports.accessibilityFind = accessibilityFind
|
|
378
|
+
module.exports.accessibilityWaitFor = accessibilityWaitFor
|
|
379
|
+
module.exports.accessibilityGetBounds = accessibilityGetBounds
|
|
380
|
+
module.exports.accessibilityInvoke = accessibilityInvoke
|
|
381
|
+
module.exports.accessibilitySetValue = accessibilitySetValue
|
|
382
|
+
module.exports.accessibilityDumpTree = accessibilityDumpTree
|
|
383
|
+
module.exports.accessibilityDumpTreeObject = accessibilityDumpTreeObject
|
|
384
|
+
module.exports.accessibilityGetElementInfo = accessibilityGetElementInfo
|
|
385
|
+
module.exports.accessibilityRefreshRoot = accessibilityRefreshRoot
|
|
386
|
+
module.exports.accessibilityTreeHealth = accessibilityTreeHealth
|
|
387
|
+
module.exports.accessibilityCheckTreeHealth = accessibilityCheckTreeHealth
|
|
Binary file
|
package/package.json
ADDED
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@spotterjs/node",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "spotterjs desktop automation for Node.js",
|
|
5
|
+
"main": "index.js",
|
|
6
|
+
"types": "index.d.ts",
|
|
7
|
+
"license": "SEE LICENSE IN LICENSE",
|
|
8
|
+
"repository": {
|
|
9
|
+
"type": "git",
|
|
10
|
+
"url": "https://gitee.com/ypl0lpy/spotterjs.git",
|
|
11
|
+
"directory": "crates/spotterjs-node"
|
|
12
|
+
},
|
|
13
|
+
"publishConfig": {
|
|
14
|
+
"access": "public",
|
|
15
|
+
"registry": "https://registry.npmjs.org/"
|
|
16
|
+
},
|
|
17
|
+
"bugs": {
|
|
18
|
+
"url": "https://gitee.com/ypl0lpy/spotterjs/issues"
|
|
19
|
+
},
|
|
20
|
+
"homepage": "https://gitee.com/ypl0lpy/spotterjs#readme",
|
|
21
|
+
"files": [
|
|
22
|
+
"index.js",
|
|
23
|
+
"index.d.ts",
|
|
24
|
+
"index.*.node",
|
|
25
|
+
"LICENSE",
|
|
26
|
+
"README.md"
|
|
27
|
+
],
|
|
28
|
+
"engines": {
|
|
29
|
+
"node": ">=18"
|
|
30
|
+
},
|
|
31
|
+
"napi": {
|
|
32
|
+
"binaryName": "spotterjs-node",
|
|
33
|
+
"targets": [
|
|
34
|
+
"x86_64-pc-windows-msvc",
|
|
35
|
+
"x86_64-unknown-linux-gnu"
|
|
36
|
+
]
|
|
37
|
+
},
|
|
38
|
+
"scripts": {
|
|
39
|
+
"build": "napi build --platform --release --dts index.d.ts",
|
|
40
|
+
"build:linux": "napi build --platform --release --features linux-x11 --dts index.d.ts",
|
|
41
|
+
"build:debug": "napi build --platform --dts index.d.ts",
|
|
42
|
+
"prepublishOnly": "npm run build && node ../../scripts/sync-license.mjs"
|
|
43
|
+
},
|
|
44
|
+
"devDependencies": {
|
|
45
|
+
"@napi-rs/cli": "^2.18.0"
|
|
46
|
+
}
|
|
47
|
+
}
|