@aspiresys/visor 1.3.5 → 1.4.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.Region = exports.visor = void 0;
3
+ exports.initializeOCR = exports.Region = exports.visor = void 0;
4
4
  const screen_1 = require("./screen");
5
5
  const matcher_1 = require("./matcher");
6
6
  const mouse_1 = require("./mouse");
@@ -15,6 +15,7 @@ const display_1 = require("./display");
15
15
  const logger_1 = require("./logger");
16
16
  const console_1 = require("console");
17
17
  const templateMetadata_1 = require("./templateMetadata");
18
+ const version_1 = require("./version");
18
19
  class Visor {
19
20
  constructor() {
20
21
  this.mouse = nut_js_1.mouse;
@@ -29,138 +30,154 @@ class Visor {
29
30
  }
30
31
  const missing = [];
31
32
  if (!config_1.visorConfig.imagePath) {
32
- missing.push("imagePath");
33
+ missing.push('imagePath');
33
34
  }
34
35
  if (!config_1.visorConfig.outputPath) {
35
- missing.push("outputPath");
36
+ missing.push('outputPath');
36
37
  }
37
38
  if (missing.length > 0) {
38
39
  (0, console_1.warn)(`[VISOR] Configuration incomplete.\n` +
39
- `Missing: ${missing.join(", ")}\n\n` +
40
+ `Missing: ${missing.join(', ')}\n\n` +
40
41
  `Relative paths may not work correctly.\n` +
41
42
  `Use visor.loadConfig(...) or provide absolute paths directly to functions.`);
42
43
  }
43
44
  if (!config_1.visorConfig.initialized) {
44
45
  config_1.visorConfig.scaleFactor = (0, display_1.getWindowsScaleFactor)();
45
- (0, console_1.warn)(`[VISOR] Configuration not loaded.\n` +
46
- `Auto-detected scaleFactor=${config_1.visorConfig.scaleFactor}.\n`);
46
+ (0, console_1.warn)(`[VISOR] Configuration not loaded.\n` + `Auto-detected scaleFactor=${config_1.visorConfig.scaleFactor}.\n`);
47
47
  }
48
48
  if (missing.length > 0 || !config_1.visorConfig.initialized) {
49
49
  this.configWarningShown = true;
50
50
  }
51
51
  }
52
52
  /**
53
- * Moves the mouse cursor to the
54
- * center of a specific screen region.
55
- *
56
- * Region coordinates typically come from:
57
- * - visor.find()
58
- * - visor.findAll()
59
- * - OCR text matching
60
- * - Visor Inspector
61
- *
62
- * Display scaling is automatically
63
- * applied using the configured
64
- * scale factor.
65
- *
66
- * @param region Screen region coordinates.
67
- * @param offset Offset coords.
68
- *
69
- * @example
70
- * await visor.moveToRegion({
71
- * x: 100,
72
- * y: 200,
73
- * width: 150,
74
- * height: 50
75
- * });
76
- */
53
+ * Returns the currently installed
54
+ * Visor package version.
55
+ *
56
+ * Useful for:
57
+ * - debugging
58
+ * - support tickets
59
+ * - framework validation
60
+ *
61
+ * @returns Package version string.
62
+ *
63
+ * @example
64
+ * console.log(visor.version());
65
+ */
66
+ version() {
67
+ return (0, version_1.getVersion)();
68
+ }
69
+ /**
70
+ * Moves the mouse cursor to the
71
+ * center of a specific screen region.
72
+ *
73
+ * Region coordinates typically come from:
74
+ * - visor.find()
75
+ * - visor.findAll()
76
+ * - OCR text matching
77
+ * - Visor Inspector
78
+ *
79
+ * Display scaling is automatically
80
+ * applied using the configured
81
+ * scale factor.
82
+ *
83
+ * @param region Screen region coordinates.
84
+ * @param offset Offset coords.
85
+ *
86
+ * @example
87
+ * await visor.moveToRegion({
88
+ * x: 100,
89
+ * y: 200,
90
+ * width: 150,
91
+ * height: 50
92
+ * });
93
+ */
77
94
  async moveToRegion(region, offset) {
78
95
  await (0, mouse_1.moveToRegion)(region, offset);
79
96
  }
80
97
  /**
81
- * Performs a left mouse click at the
82
- * center of a specific screen region.
83
- *
84
- * Region coordinates typically come from:
85
- * - visor.find()
86
- * - visor.findAll()
87
- * - OCR text matching
88
- * - Visor Inspector
89
- *
90
- * Display scaling is automatically
91
- * applied using the configured
92
- * scale factor.
93
- *
94
- * @param region Screen region coordinates.
95
- * @param offset Offset coords.
96
- *
97
- * @example
98
- * await visor.clickRegion({
99
- * x: 100,
100
- * y: 200,
101
- * width: 150,
102
- * height: 50
103
- * });
104
- */
98
+ * Performs a left mouse click at the
99
+ * center of a specific screen region.
100
+ *
101
+ * Region coordinates typically come from:
102
+ * - visor.find()
103
+ * - visor.findAll()
104
+ * - OCR text matching
105
+ * - Visor Inspector
106
+ *
107
+ * Display scaling is automatically
108
+ * applied using the configured
109
+ * scale factor.
110
+ *
111
+ * @param region Screen region coordinates.
112
+ * @param offset Offset coords.
113
+ *
114
+ * @example
115
+ * await visor.clickRegion({
116
+ * x: 100,
117
+ * y: 200,
118
+ * width: 150,
119
+ * height: 50
120
+ * });
121
+ */
105
122
  async clickRegion(region, offset) {
106
123
  await (0, mouse_1.moveToRegion)(region, offset);
107
124
  await this.mouse.click(this.Button.LEFT);
108
125
  }
109
126
  /**
110
- * Performs a double left mouse click
111
- * at the center of a specific
112
- * screen region.
113
- *
114
- * Region coordinates typically come from:
115
- * - visor.find()
116
- * - visor.findAll()
117
- * - OCR text matching
118
- * - Visor Inspector
119
- *
120
- * Display scaling is automatically
121
- * applied using the configured
122
- * scale factor.
123
- *
124
- * @param region Screen region coordinates.
125
- * @param offset Offset coords.
126
- *
127
- * @example
128
- * await visor.doubleClickRegion({
129
- * x: 100,
130
- * y: 200,
131
- * width: 150,
132
- * height: 50
133
- * });
134
- */
127
+ * Performs a double left mouse click
128
+ * at the center of a specific
129
+ * screen region.
130
+ *
131
+ * Region coordinates typically come from:
132
+ * - visor.find()
133
+ * - visor.findAll()
134
+ * - OCR text matching
135
+ * - Visor Inspector
136
+ *
137
+ * Display scaling is automatically
138
+ * applied using the configured
139
+ * scale factor.
140
+ *
141
+ * @param region Screen region coordinates.
142
+ * @param offset Offset coords.
143
+ *
144
+ * @example
145
+ * await visor.doubleClickRegion({
146
+ * x: 100,
147
+ * y: 200,
148
+ * width: 150,
149
+ * height: 50
150
+ * });
151
+ */
135
152
  async doubleClickRegion(region, offset) {
136
153
  await (0, mouse_1.moveToRegion)(region, offset);
137
154
  await this.mouse.doubleClick(this.Button.LEFT);
138
155
  }
139
156
  /**
140
- * Performs a right mouse click at the
141
- * center of a specific screen region.
142
- *
143
- * Region coordinates typically come from:
144
- * - visor.find()
145
- * - visor.findAll()
146
- * - OCR text matching
147
- * - Visor Inspector
148
- *
149
- * Display scaling is automatically
150
- * applied using the configured
151
- * scale factor.
152
- *
153
- * @param region Screen region coordinates.
154
- * @param offset Offset coords.
155
- *
156
- * @example
157
- * await visor.rightClickRegion({
158
- * x: 100,
159
- * y: 200,
160
- * width: 150,
161
- * height: 50
162
- * });
163
- */
157
+ * Performs a right mouse click at the
158
+ * center of a specific screen region.
159
+ *
160
+ * Region coordinates typically come from:
161
+ * - visor.find()
162
+ * - visor.findAll()
163
+ * - OCR text matching
164
+ * - Visor Inspector
165
+ *
166
+ * Display scaling is automatically
167
+ * applied using the configured
168
+ * scale factor.
169
+ *
170
+ * @param region Screen region coordinates.
171
+ * @param offset Offset coords.
172
+ *
173
+ * @example
174
+ * await visor.rightClickRegion({
175
+ * x: 100,
176
+ * y: 200,
177
+ * width: 150,
178
+ * height: 50
179
+ * });
180
+ */
164
181
  async rightClickRegion(region, offset) {
165
182
  await (0, mouse_1.moveToRegion)(region, offset);
166
183
  await this.mouse.click(this.Button.RIGHT);
@@ -199,14 +216,14 @@ class Visor {
199
216
  this.checkConfig();
200
217
  if (!image) {
201
218
  await this.mouse.click(this.Button.LEFT);
202
- (0, logger_1.log)("[MOUSE] Left click completed");
219
+ (0, logger_1.log)('[MOUSE] Left click completed');
203
220
  return;
204
221
  }
205
222
  const region = await this.find(image, confidence);
206
223
  if (!region) {
207
224
  throw new Error(`Image not found: ${image}`);
208
225
  }
209
- (0, logger_1.log)("[CV] Match found:", region);
226
+ (0, logger_1.log)('[CV] Match found:', region);
210
227
  await (0, mouse_1.clickRegion)(region, offset);
211
228
  }
212
229
  /**
@@ -243,7 +260,7 @@ class Visor {
243
260
  await (0, mouse_1.moveToRegion)(region, offset);
244
261
  }
245
262
  await this.mouse.click(this.Button.RIGHT);
246
- (0, logger_1.log)("[MOUSE] Right click completed");
263
+ (0, logger_1.log)('[MOUSE] Right click completed');
247
264
  }
248
265
  /**
249
266
  * Performs a double left mouse click.
@@ -280,7 +297,7 @@ class Visor {
280
297
  await (0, mouse_1.moveToRegion)(region, offset);
281
298
  }
282
299
  await this.mouse.doubleClick(this.Button.LEFT);
283
- (0, logger_1.log)("[MOUSE] Double click completed");
300
+ (0, logger_1.log)('[MOUSE] Double click completed');
284
301
  }
285
302
  /**
286
303
  * Finds the best matching image on screen
@@ -316,12 +333,17 @@ class Visor {
316
333
  const start = Date.now();
317
334
  const screen = await (0, screen_1.captureScreen)();
318
335
  const template = await (0, matcher_1.loadTemplate)((0, path_1.resolveImagePath)(image));
319
- const scaleFactor = config_1.visorConfig.scaleFactor;
320
336
  const metadata = (0, templateMetadata_1.loadTemplateMetadata)((0, path_1.resolveImagePath)(image));
337
+ if (metadata) {
338
+ metadata.currentResolution = {
339
+ width: screen.cols,
340
+ height: screen.rows,
341
+ };
342
+ }
321
343
  try {
322
344
  const result = (0, matcher_1.matchTemplate)(screen, template, confidence, metadata);
323
345
  if (result) {
324
- (0, logger_1.log)(`[FIND] Actual coords: (${Math.floor(result.x * scaleFactor)}, ${Math.floor(result.y * scaleFactor)})`);
346
+ (0, logger_1.log)(`[FIND] Match: x=${result.x}, y=${result.y}, w=${result.width}, h=${result.height}, conf=${result.confidence.toFixed(2)}`);
325
347
  }
326
348
  (0, logger_1.log)(`[FIND] Total: ${Date.now() - start} ms`);
327
349
  return result;
@@ -413,14 +435,14 @@ class Visor {
413
435
  async previewMatches(image, confidence = 0.8) {
414
436
  this.checkConfig();
415
437
  const matches = await this.findAll(image, confidence);
416
- (0, logger_1.log)("\n=== MATCH PREVIEW ===\n");
438
+ (0, logger_1.log)('\n=== MATCH PREVIEW ===\n');
417
439
  matches.forEach((m, i) => {
418
- (0, logger_1.log)(`#${i + 1}
419
- X:${m.x}
420
- Y:${m.y}
421
- W:${m.width}
422
- H:${m.height}
423
- CONF:${m.confidence.toFixed(3)}
440
+ (0, logger_1.log)(`#${i + 1}
441
+ X:${m.x}
442
+ Y:${m.y}
443
+ W:${m.width}
444
+ H:${m.height}
445
+ CONF:${m.confidence.toFixed(3)}
424
446
  `);
425
447
  });
426
448
  return matches;
@@ -709,10 +731,10 @@ CONF:${m.confidence.toFixed(3)}
709
731
  */
710
732
  async captureScreenshot(path) {
711
733
  this.checkConfig();
712
- path = config_1.visorConfig.outputPath + "/" + path;
734
+ path = config_1.visorConfig.outputPath + '/' + path;
713
735
  (0, logger_1.log)(`[VISOR] Saving screenshot: ${path}`);
714
736
  await (0, screen_1.saveScreenshot)(path);
715
- (0, logger_1.log)("[VISOR] Screenshot saved");
737
+ (0, logger_1.log)('[VISOR] Screenshot saved');
716
738
  }
717
739
  /**
718
740
  * Opens a desktop application,
@@ -773,13 +795,13 @@ CONF:${m.confidence.toFixed(3)}
773
795
  const src = await this.find(source, confidence);
774
796
  const dst = await this.find(target, confidence);
775
797
  if (!src || !dst) {
776
- throw new Error("Source or target not found");
798
+ throw new Error('Source or target not found');
777
799
  }
778
800
  await (0, mouse_1.moveToRegion)(src);
779
801
  await this.mouse.pressButton(this.Button.LEFT);
780
802
  await (0, mouse_1.moveToRegion)(dst);
781
803
  await this.mouse.releaseButton(this.Button.LEFT);
782
- (0, logger_1.log)("[MOUSE] Drag and drop completed");
804
+ (0, logger_1.log)('[MOUSE] Drag and drop completed');
783
805
  }
784
806
  /**
785
807
  * Moves the mouse cursor to the
@@ -807,7 +829,7 @@ CONF:${m.confidence.toFixed(3)}
807
829
  throw new Error(`Image not found: ${image}`);
808
830
  }
809
831
  await (0, mouse_1.moveToRegion)(region, offset);
810
- (0, logger_1.log)("[MOUSE] Hover completed");
832
+ (0, logger_1.log)('[MOUSE] Hover completed');
811
833
  }
812
834
  /**
813
835
  * Scrolls the mouse wheel downward.
@@ -1026,6 +1048,19 @@ CONF:${m.confidence.toFixed(3)}
1026
1048
  getImagePath() {
1027
1049
  return config_1.visorConfig.imagePath;
1028
1050
  }
1051
+ showConfig() {
1052
+ console.log(`
1053
+ === VISOR CONFIG ===
1054
+
1055
+ Scale Factor : ${config_1.visorConfig.scaleFactor}
1056
+ Image Path : ${config_1.visorConfig.imagePath}
1057
+ Output Path : ${config_1.visorConfig.outputPath}
1058
+ Debug : ${config_1.visorConfig.debug}
1059
+ Initialized : ${config_1.visorConfig.initialized}
1060
+
1061
+ ====================
1062
+ `);
1063
+ }
1029
1064
  /**
1030
1065
  * Sets the default output path
1031
1066
  * used for visual automation APIs.
@@ -1108,7 +1143,7 @@ CONF:${m.confidence.toFixed(3)}
1108
1143
  this.setDebug(config.debug);
1109
1144
  }
1110
1145
  config_1.visorConfig.initialized = true;
1111
- (0, logger_1.log)("[VISOR] Config loaded");
1146
+ (0, logger_1.log)('[VISOR] Config loaded');
1112
1147
  }
1113
1148
  /**
1114
1149
  * Finds the first matching image
@@ -1304,7 +1339,7 @@ CONF:${m.confidence.toFixed(3)}
1304
1339
  }
1305
1340
  await this.sleep(interval);
1306
1341
  }
1307
- throw new Error("Timeout waiting for images");
1342
+ throw new Error('Timeout waiting for images');
1308
1343
  }
1309
1344
  /**
1310
1345
  * Terminates shared OCR worker.
@@ -1323,24 +1358,24 @@ CONF:${m.confidence.toFixed(3)}
1323
1358
  await (0, ocr_1.terminateOCR)();
1324
1359
  }
1325
1360
  /**
1326
- * Executes a command and returns output.
1327
- *
1328
- * @example
1329
- * const output =
1330
- * await visor.exec("ipconfig");
1331
- */
1361
+ * Executes a command and returns output.
1362
+ *
1363
+ * @example
1364
+ * const output =
1365
+ * await visor.exec("ipconfig");
1366
+ */
1332
1367
  async exec(command) {
1333
1368
  return await (0, app_1.execCommand)(command);
1334
1369
  }
1335
1370
  /**
1336
- * Starts a command without waiting
1337
- * for completion.
1338
- *
1339
- * @example
1340
- * await visor.execDetached(
1341
- * "notepad"
1342
- * );
1343
- */
1371
+ * Starts a command without waiting
1372
+ * for completion.
1373
+ *
1374
+ * @example
1375
+ * await visor.execDetached(
1376
+ * "notepad"
1377
+ * );
1378
+ */
1344
1379
  async execDetached(command) {
1345
1380
  await (0, app_1.execDetached)(command);
1346
1381
  }
@@ -1358,42 +1393,44 @@ CONF:${m.confidence.toFixed(3)}
1358
1393
  await this.press(nut_js_1.Key.LeftControl, nut_js_1.Key.V);
1359
1394
  }
1360
1395
  /**
1361
- * Generates a alert box.
1362
- *
1363
- * @param message Text to display.
1364
- * @param title Title of the alert.
1365
- *
1366
- * @example
1367
- * await visor.alert("Execution Completed");
1368
- */
1369
- async alert(message, title = "Visor") {
1396
+ * Generates a alert box.
1397
+ *
1398
+ * @param message Text to display.
1399
+ * @param title Title of the alert.
1400
+ *
1401
+ * @example
1402
+ * await visor.alert("Execution Completed");
1403
+ */
1404
+ async alert(message, title = 'Visor') {
1370
1405
  await (0, dialog_1.alert)(message, title);
1371
1406
  }
1372
1407
  /**
1373
- * Generates a conform box with Yes/No.
1374
- *
1375
- * @param message Text to display.
1376
- * @param title Title of the window.
1377
- *
1378
- * @example
1379
- * await visor.conform("Continue Execution?");
1380
- */
1381
- async confirm(message, title = "Visor") {
1408
+ * Generates a conform box with Yes/No.
1409
+ *
1410
+ * @param message Text to display.
1411
+ * @param title Title of the window.
1412
+ *
1413
+ * @example
1414
+ * await visor.conform("Continue Execution?");
1415
+ */
1416
+ async confirm(message, title = 'Visor') {
1382
1417
  return await (0, dialog_1.confirm)(message, title);
1383
1418
  }
1384
1419
  /**
1385
- * Generates a input box.
1386
- *
1387
- * @param message Text to display.
1388
- * @param title Title of the window.
1389
- *
1390
- * @example
1391
- * await visor.input("Enter Email");
1392
- */
1393
- async input(message, title = "Visor") {
1420
+ * Generates a input box.
1421
+ *
1422
+ * @param message Text to display.
1423
+ * @param title Title of the window.
1424
+ *
1425
+ * @example
1426
+ * await visor.input("Enter Email");
1427
+ */
1428
+ async input(message, title = 'Visor') {
1394
1429
  return await (0, dialog_1.prompt)(message, title);
1395
1430
  }
1396
1431
  }
1397
1432
  exports.visor = new Visor();
1398
1433
  var types_1 = require("./types");
1399
1434
  Object.defineProperty(exports, "Region", { enumerable: true, get: function () { return types_1.Region; } });
1435
+ var ocr_2 = require("./ocr");
1436
+ Object.defineProperty(exports, "initializeOCR", { enumerable: true, get: function () { return ocr_2.initializeOCR; } });
@@ -1,11 +1,13 @@
1
- "use strict";
2
- var __importDefault = (this && this.__importDefault) || function (mod) {
3
- return (mod && mod.__esModule) ? mod : { "default": mod };
4
- };
5
- Object.defineProperty(exports, "__esModule", { value: true });
6
- const express_1 = __importDefault(require("express"));
7
- const path_1 = __importDefault(require("path"));
8
- const app_1 = require("../app");
1
+ 'use strict';
2
+ var __importDefault =
3
+ (this && this.__importDefault) ||
4
+ function (mod) {
5
+ return mod && mod.__esModule ? mod : { default: mod };
6
+ };
7
+ Object.defineProperty(exports, '__esModule', { value: true });
8
+ const express_1 = __importDefault(require('express'));
9
+ const path_1 = __importDefault(require('path'));
10
+ const app_1 = require('../app');
9
11
  const app = (0, express_1.default)();
10
12
  const PORT = 3000;
11
13
  app.use(express_1.default.static(path_1.default.join(__dirname)));
package/dist/matcher.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- import { Region } from "./types";
1
+ import { Region } from './types';
2
2
  export declare function loadTemplate(path: string): Promise<any>;
3
3
  export declare function loadScreen(path: string): Promise<any>;
4
4
  export declare function matchTemplate(screen: any, template: any, confidence?: number, metadata?: any): Region | null;