@aspiresys/visor 1.3.4 → 1.4.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/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");
@@ -14,6 +14,8 @@ const path_1 = require("./path");
14
14
  const display_1 = require("./display");
15
15
  const logger_1 = require("./logger");
16
16
  const console_1 = require("console");
17
+ const templateMetadata_1 = require("./templateMetadata");
18
+ const version_1 = require("./version");
17
19
  class Visor {
18
20
  constructor() {
19
21
  this.mouse = nut_js_1.mouse;
@@ -28,138 +30,154 @@ class Visor {
28
30
  }
29
31
  const missing = [];
30
32
  if (!config_1.visorConfig.imagePath) {
31
- missing.push("imagePath");
33
+ missing.push('imagePath');
32
34
  }
33
35
  if (!config_1.visorConfig.outputPath) {
34
- missing.push("outputPath");
36
+ missing.push('outputPath');
35
37
  }
36
38
  if (missing.length > 0) {
37
39
  (0, console_1.warn)(`[VISOR] Configuration incomplete.\n` +
38
- `Missing: ${missing.join(", ")}\n\n` +
40
+ `Missing: ${missing.join(', ')}\n\n` +
39
41
  `Relative paths may not work correctly.\n` +
40
42
  `Use visor.loadConfig(...) or provide absolute paths directly to functions.`);
41
43
  }
42
44
  if (!config_1.visorConfig.initialized) {
43
45
  config_1.visorConfig.scaleFactor = (0, display_1.getWindowsScaleFactor)();
44
- (0, console_1.warn)(`[VISOR] Configuration not loaded.\n` +
45
- `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`);
46
47
  }
47
48
  if (missing.length > 0 || !config_1.visorConfig.initialized) {
48
49
  this.configWarningShown = true;
49
50
  }
50
51
  }
51
52
  /**
52
- * Moves the mouse cursor to the
53
- * center of a specific screen region.
54
- *
55
- * Region coordinates typically come from:
56
- * - visor.find()
57
- * - visor.findAll()
58
- * - OCR text matching
59
- * - Visor Inspector
60
- *
61
- * Display scaling is automatically
62
- * applied using the configured
63
- * scale factor.
64
- *
65
- * @param region Screen region coordinates.
66
- * @param offset Offset coords.
67
- *
68
- * @example
69
- * await visor.moveToRegion({
70
- * x: 100,
71
- * y: 200,
72
- * width: 150,
73
- * height: 50
74
- * });
75
- */
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
+ */
76
94
  async moveToRegion(region, offset) {
77
95
  await (0, mouse_1.moveToRegion)(region, offset);
78
96
  }
79
97
  /**
80
- * Performs a left mouse click at the
81
- * center of a specific screen region.
82
- *
83
- * Region coordinates typically come from:
84
- * - visor.find()
85
- * - visor.findAll()
86
- * - OCR text matching
87
- * - Visor Inspector
88
- *
89
- * Display scaling is automatically
90
- * applied using the configured
91
- * scale factor.
92
- *
93
- * @param region Screen region coordinates.
94
- * @param offset Offset coords.
95
- *
96
- * @example
97
- * await visor.clickRegion({
98
- * x: 100,
99
- * y: 200,
100
- * width: 150,
101
- * height: 50
102
- * });
103
- */
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
+ */
104
122
  async clickRegion(region, offset) {
105
123
  await (0, mouse_1.moveToRegion)(region, offset);
106
124
  await this.mouse.click(this.Button.LEFT);
107
125
  }
108
126
  /**
109
- * Performs a double left mouse click
110
- * at the center of a specific
111
- * screen region.
112
- *
113
- * Region coordinates typically come from:
114
- * - visor.find()
115
- * - visor.findAll()
116
- * - OCR text matching
117
- * - Visor Inspector
118
- *
119
- * Display scaling is automatically
120
- * applied using the configured
121
- * scale factor.
122
- *
123
- * @param region Screen region coordinates.
124
- * @param offset Offset coords.
125
- *
126
- * @example
127
- * await visor.doubleClickRegion({
128
- * x: 100,
129
- * y: 200,
130
- * width: 150,
131
- * height: 50
132
- * });
133
- */
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
+ */
134
152
  async doubleClickRegion(region, offset) {
135
153
  await (0, mouse_1.moveToRegion)(region, offset);
136
154
  await this.mouse.doubleClick(this.Button.LEFT);
137
155
  }
138
156
  /**
139
- * Performs a right mouse click at the
140
- * center of a specific screen region.
141
- *
142
- * Region coordinates typically come from:
143
- * - visor.find()
144
- * - visor.findAll()
145
- * - OCR text matching
146
- * - Visor Inspector
147
- *
148
- * Display scaling is automatically
149
- * applied using the configured
150
- * scale factor.
151
- *
152
- * @param region Screen region coordinates.
153
- * @param offset Offset coords.
154
- *
155
- * @example
156
- * await visor.rightClickRegion({
157
- * x: 100,
158
- * y: 200,
159
- * width: 150,
160
- * height: 50
161
- * });
162
- */
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
+ */
163
181
  async rightClickRegion(region, offset) {
164
182
  await (0, mouse_1.moveToRegion)(region, offset);
165
183
  await this.mouse.click(this.Button.RIGHT);
@@ -198,14 +216,14 @@ class Visor {
198
216
  this.checkConfig();
199
217
  if (!image) {
200
218
  await this.mouse.click(this.Button.LEFT);
201
- (0, logger_1.log)("[MOUSE] Left click completed");
219
+ (0, logger_1.log)('[MOUSE] Left click completed');
202
220
  return;
203
221
  }
204
222
  const region = await this.find(image, confidence);
205
223
  if (!region) {
206
224
  throw new Error(`Image not found: ${image}`);
207
225
  }
208
- (0, logger_1.log)("[CV] Match found:", region);
226
+ (0, logger_1.log)('[CV] Match found:', region);
209
227
  await (0, mouse_1.clickRegion)(region, offset);
210
228
  }
211
229
  /**
@@ -242,7 +260,7 @@ class Visor {
242
260
  await (0, mouse_1.moveToRegion)(region, offset);
243
261
  }
244
262
  await this.mouse.click(this.Button.RIGHT);
245
- (0, logger_1.log)("[MOUSE] Right click completed");
263
+ (0, logger_1.log)('[MOUSE] Right click completed');
246
264
  }
247
265
  /**
248
266
  * Performs a double left mouse click.
@@ -279,7 +297,7 @@ class Visor {
279
297
  await (0, mouse_1.moveToRegion)(region, offset);
280
298
  }
281
299
  await this.mouse.doubleClick(this.Button.LEFT);
282
- (0, logger_1.log)("[MOUSE] Double click completed");
300
+ (0, logger_1.log)('[MOUSE] Double click completed');
283
301
  }
284
302
  /**
285
303
  * Finds the best matching image on screen
@@ -316,8 +334,9 @@ class Visor {
316
334
  const screen = await (0, screen_1.captureScreen)();
317
335
  const template = await (0, matcher_1.loadTemplate)((0, path_1.resolveImagePath)(image));
318
336
  const scaleFactor = config_1.visorConfig.scaleFactor;
337
+ const metadata = (0, templateMetadata_1.loadTemplateMetadata)((0, path_1.resolveImagePath)(image));
319
338
  try {
320
- const result = (0, matcher_1.matchTemplate)(screen, template, confidence);
339
+ const result = (0, matcher_1.matchTemplate)(screen, template, confidence, metadata);
321
340
  if (result) {
322
341
  (0, logger_1.log)(`[FIND] Actual coords: (${Math.floor(result.x * scaleFactor)}, ${Math.floor(result.y * scaleFactor)})`);
323
342
  }
@@ -411,14 +430,14 @@ class Visor {
411
430
  async previewMatches(image, confidence = 0.8) {
412
431
  this.checkConfig();
413
432
  const matches = await this.findAll(image, confidence);
414
- (0, logger_1.log)("\n=== MATCH PREVIEW ===\n");
433
+ (0, logger_1.log)('\n=== MATCH PREVIEW ===\n');
415
434
  matches.forEach((m, i) => {
416
- (0, logger_1.log)(`#${i + 1}
417
- X:${m.x}
418
- Y:${m.y}
419
- W:${m.width}
420
- H:${m.height}
421
- CONF:${m.confidence.toFixed(3)}
435
+ (0, logger_1.log)(`#${i + 1}
436
+ X:${m.x}
437
+ Y:${m.y}
438
+ W:${m.width}
439
+ H:${m.height}
440
+ CONF:${m.confidence.toFixed(3)}
422
441
  `);
423
442
  });
424
443
  return matches;
@@ -707,10 +726,10 @@ CONF:${m.confidence.toFixed(3)}
707
726
  */
708
727
  async captureScreenshot(path) {
709
728
  this.checkConfig();
710
- path = config_1.visorConfig.outputPath + "/" + path;
729
+ path = config_1.visorConfig.outputPath + '/' + path;
711
730
  (0, logger_1.log)(`[VISOR] Saving screenshot: ${path}`);
712
731
  await (0, screen_1.saveScreenshot)(path);
713
- (0, logger_1.log)("[VISOR] Screenshot saved");
732
+ (0, logger_1.log)('[VISOR] Screenshot saved');
714
733
  }
715
734
  /**
716
735
  * Opens a desktop application,
@@ -771,13 +790,13 @@ CONF:${m.confidence.toFixed(3)}
771
790
  const src = await this.find(source, confidence);
772
791
  const dst = await this.find(target, confidence);
773
792
  if (!src || !dst) {
774
- throw new Error("Source or target not found");
793
+ throw new Error('Source or target not found');
775
794
  }
776
795
  await (0, mouse_1.moveToRegion)(src);
777
796
  await this.mouse.pressButton(this.Button.LEFT);
778
797
  await (0, mouse_1.moveToRegion)(dst);
779
798
  await this.mouse.releaseButton(this.Button.LEFT);
780
- (0, logger_1.log)("[MOUSE] Drag and drop completed");
799
+ (0, logger_1.log)('[MOUSE] Drag and drop completed');
781
800
  }
782
801
  /**
783
802
  * Moves the mouse cursor to the
@@ -805,7 +824,7 @@ CONF:${m.confidence.toFixed(3)}
805
824
  throw new Error(`Image not found: ${image}`);
806
825
  }
807
826
  await (0, mouse_1.moveToRegion)(region, offset);
808
- (0, logger_1.log)("[MOUSE] Hover completed");
827
+ (0, logger_1.log)('[MOUSE] Hover completed');
809
828
  }
810
829
  /**
811
830
  * Scrolls the mouse wheel downward.
@@ -1024,6 +1043,19 @@ CONF:${m.confidence.toFixed(3)}
1024
1043
  getImagePath() {
1025
1044
  return config_1.visorConfig.imagePath;
1026
1045
  }
1046
+ showConfig() {
1047
+ console.log(`
1048
+ === VISOR CONFIG ===
1049
+
1050
+ Scale Factor : ${config_1.visorConfig.scaleFactor}
1051
+ Image Path : ${config_1.visorConfig.imagePath}
1052
+ Output Path : ${config_1.visorConfig.outputPath}
1053
+ Debug : ${config_1.visorConfig.debug}
1054
+ Initialized : ${config_1.visorConfig.initialized}
1055
+
1056
+ ====================
1057
+ `);
1058
+ }
1027
1059
  /**
1028
1060
  * Sets the default output path
1029
1061
  * used for visual automation APIs.
@@ -1106,7 +1138,7 @@ CONF:${m.confidence.toFixed(3)}
1106
1138
  this.setDebug(config.debug);
1107
1139
  }
1108
1140
  config_1.visorConfig.initialized = true;
1109
- (0, logger_1.log)("[VISOR] Config loaded");
1141
+ (0, logger_1.log)('[VISOR] Config loaded');
1110
1142
  }
1111
1143
  /**
1112
1144
  * Finds the first matching image
@@ -1302,7 +1334,7 @@ CONF:${m.confidence.toFixed(3)}
1302
1334
  }
1303
1335
  await this.sleep(interval);
1304
1336
  }
1305
- throw new Error("Timeout waiting for images");
1337
+ throw new Error('Timeout waiting for images');
1306
1338
  }
1307
1339
  /**
1308
1340
  * Terminates shared OCR worker.
@@ -1321,24 +1353,24 @@ CONF:${m.confidence.toFixed(3)}
1321
1353
  await (0, ocr_1.terminateOCR)();
1322
1354
  }
1323
1355
  /**
1324
- * Executes a command and returns output.
1325
- *
1326
- * @example
1327
- * const output =
1328
- * await visor.exec("ipconfig");
1329
- */
1356
+ * Executes a command and returns output.
1357
+ *
1358
+ * @example
1359
+ * const output =
1360
+ * await visor.exec("ipconfig");
1361
+ */
1330
1362
  async exec(command) {
1331
1363
  return await (0, app_1.execCommand)(command);
1332
1364
  }
1333
1365
  /**
1334
- * Starts a command without waiting
1335
- * for completion.
1336
- *
1337
- * @example
1338
- * await visor.execDetached(
1339
- * "notepad"
1340
- * );
1341
- */
1366
+ * Starts a command without waiting
1367
+ * for completion.
1368
+ *
1369
+ * @example
1370
+ * await visor.execDetached(
1371
+ * "notepad"
1372
+ * );
1373
+ */
1342
1374
  async execDetached(command) {
1343
1375
  await (0, app_1.execDetached)(command);
1344
1376
  }
@@ -1356,42 +1388,44 @@ CONF:${m.confidence.toFixed(3)}
1356
1388
  await this.press(nut_js_1.Key.LeftControl, nut_js_1.Key.V);
1357
1389
  }
1358
1390
  /**
1359
- * Generates a alert box.
1360
- *
1361
- * @param message Text to display.
1362
- * @param title Title of the alert.
1363
- *
1364
- * @example
1365
- * await visor.alert("Execution Completed");
1366
- */
1367
- async alert(message, title = "Visor") {
1391
+ * Generates a alert box.
1392
+ *
1393
+ * @param message Text to display.
1394
+ * @param title Title of the alert.
1395
+ *
1396
+ * @example
1397
+ * await visor.alert("Execution Completed");
1398
+ */
1399
+ async alert(message, title = 'Visor') {
1368
1400
  await (0, dialog_1.alert)(message, title);
1369
1401
  }
1370
1402
  /**
1371
- * Generates a conform box with Yes/No.
1372
- *
1373
- * @param message Text to display.
1374
- * @param title Title of the window.
1375
- *
1376
- * @example
1377
- * await visor.conform("Continue Execution?");
1378
- */
1379
- async confirm(message, title = "Visor") {
1403
+ * Generates a conform box with Yes/No.
1404
+ *
1405
+ * @param message Text to display.
1406
+ * @param title Title of the window.
1407
+ *
1408
+ * @example
1409
+ * await visor.conform("Continue Execution?");
1410
+ */
1411
+ async confirm(message, title = 'Visor') {
1380
1412
  return await (0, dialog_1.confirm)(message, title);
1381
1413
  }
1382
1414
  /**
1383
- * Generates a input box.
1384
- *
1385
- * @param message Text to display.
1386
- * @param title Title of the window.
1387
- *
1388
- * @example
1389
- * await visor.input("Enter Email");
1390
- */
1391
- async input(message, title = "Visor") {
1415
+ * Generates a input box.
1416
+ *
1417
+ * @param message Text to display.
1418
+ * @param title Title of the window.
1419
+ *
1420
+ * @example
1421
+ * await visor.input("Enter Email");
1422
+ */
1423
+ async input(message, title = 'Visor') {
1392
1424
  return await (0, dialog_1.prompt)(message, title);
1393
1425
  }
1394
1426
  }
1395
1427
  exports.visor = new Visor();
1396
1428
  var types_1 = require("./types");
1397
1429
  Object.defineProperty(exports, "Region", { enumerable: true, get: function () { return types_1.Region; } });
1430
+ var ocr_2 = require("./ocr");
1431
+ 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,7 +1,7 @@
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
- export declare function matchTemplate(screen: any, template: any, confidence?: number): Region | null;
4
+ export declare function matchTemplate(screen: any, template: any, confidence?: number, metadata?: any): Region | null;
5
5
  export declare function findAllMatches(screen: any, template: any, confidence?: number): Region[];
6
6
  export declare function findAllInspectorMatches(screen: any, template: any, confidence?: number): Region[];
7
7
  export declare function matchInspectorTemplate(screen: any, template: any, confidence?: number, multiScale?: boolean): Region | null;