diff --git a/fix-cov.ts b/fix-cov.ts deleted file mode 100644 index 7e02ca9..0000000 --- a/fix-cov.ts +++ /dev/null @@ -1,10 +0,0 @@ -/* -This file is used to fix the coverage path for github actions. -No need to call this file. -*/ - -let cov = await Deno.readTextFile("./lcov.info"); -cov = cov.replaceAll("C:\\git\\deno\\denopilot\\src\\", "/github/workspace/src/") -cov = cov.replaceAll("\\", "/") -await Deno.writeTextFile("./lcov.info", cov) -console.info("Cov path fixed.") \ No newline at end of file diff --git a/lcov.info b/lcov.info deleted file mode 100644 index 4a28b2f..0000000 --- a/lcov.info +++ /dev/null @@ -1,294 +0,0 @@ -SF:/github/workspace/src/bin/nircmd.ts -FNF:0 -FNH:0 -BRF:0 -BRH:0 -DA:1,4 -DA:1592,4 -LH:2 -LF:2 -end_of_record -SF:/github/workspace/src/models/OSModel.ts -FNF:0 -FNH:0 -BRF:0 -BRH:0 -DA:1,8 -LH:1 -LF:1 -end_of_record -SF:/github/workspace/src/nirCmd.ts -FN:16,runNirCmd -FN:39,validateNotBlank -FN:45,getOS -FN:49,getNir -FN:61,getDenoDir -FN:86,isBlank -FN:90,isDebug -FNDA:0,runNirCmd -FNDA:56,validateNotBlank -FNDA:0,getOS -FNDA:0,getNir -FNDA:0,getDenoDir -FNDA:56,isBlank -FNDA:0,isDebug -FNF:7 -FNH:2 -BRDA:40,2,0,20 -BRDA:87,6,0,44 -BRF:2 -BRH:2 -DA:1,4 -DA:2,4 -DA:3,4 -DA:4,4 -DA:5,4 -DA:6,4 -DA:8,1 -DA:16,0 -DA:17,0 -DA:18,0 -DA:19,0 -DA:20,0 -DA:21,0 -DA:23,0 -DA:24,0 -DA:25,0 -DA:26,0 -DA:27,0 -DA:28,0 -DA:29,0 -DA:30,0 -DA:31,0 -DA:32,0 -DA:33,0 -DA:34,0 -DA:35,0 -DA:36,0 -DA:37,0 -DA:39,4 -DA:40,60 -DA:41,80 -DA:42,80 -DA:43,60 -DA:45,0 -DA:46,0 -DA:47,0 -DA:49,0 -DA:50,0 -DA:51,0 -DA:52,0 -DA:53,0 -DA:54,0 -DA:55,0 -DA:56,0 -DA:57,0 -DA:58,0 -DA:59,0 -DA:61,0 -DA:62,0 -DA:63,0 -DA:64,0 -DA:65,0 -DA:67,0 -DA:68,0 -DA:69,0 -DA:70,0 -DA:71,0 -DA:72,0 -DA:73,0 -DA:74,0 -DA:75,0 -DA:76,0 -DA:77,0 -DA:79,0 -DA:80,0 -DA:81,0 -DA:82,0 -DA:83,0 -DA:84,0 -DA:86,4 -DA:87,60 -DA:88,60 -DA:90,0 -DA:91,0 -DA:92,0 -DA:93,0 -LH:15 -LF:76 -end_of_record -SF:/github/workspace/src/tsToCmd.ts -FN:3,createNirBin -FNDA:0,createNirBin -FNF:1 -FNH:0 -BRF:0 -BRH:0 -DA:1,4 -DA:3,0 -DA:4,0 -DA:5,0 -DA:7,0 -DA:8,0 -DA:9,0 -DA:10,0 -DA:12,0 -DA:13,0 -LH:1 -LF:10 -end_of_record -SF:/github/workspace/src/utils.ts -FN:13,getNirArgs -FN:13,getNirArgs -FN:51,getWindowArgs -FN:65,getWindowArgs -FN:98,matchConvert -FN:1,matchConvert -FNDA:18,getNirArgs -FNDA:51,getNirArgs -FNDA:48,getWindowArgs -FNDA:16,getWindowArgs -FNDA:15,matchConvert -FNDA:5,matchConvert -FNF:6 -FNH:6 -BRDA:25,2,0,15 -BRDA:25,2,1,3 -BRDA:25,2,2,15 -BRDA:25,2,3,3 -BRDA:25,2,4,1 -BRDA:35,2,5,17 -BRDA:39,2,6,13 -BRDA:41,2,7,12 -BRDA:42,2,8,10 -BRDA:43,2,9,7 -BRDA:44,2,10,1 -BRDA:48,2,11,16 -BRDA:55,2,12,2 -BRDA:55,2,13,2 -BRDA:65,2,14,11 -BRDA:21,3,0,45 -BRDA:21,3,1,6 -BRDA:25,3,2,39 -BRDA:25,3,3,36 -BRDA:25,3,4,30 -BRDA:25,3,5,21 -BRDA:25,3,6,3 -BRDA:33,3,7,48 -BRDA:41,3,8,6 -BRDA:46,3,9,33 -BRDA:54,4,0,12 -BRDA:58,4,1,36 -BRDA:60,4,2,3 -BRDA:63,4,3,33 -BRDA:65,4,4,6 -BRDA:72,4,5,27 -BRDA:74,4,6,18 -BRDA:82,4,7,9 -BRDA:84,4,8,0 -BRDA:86,4,9,9 -BRDA:88,4,10,3 -BRDA:91,4,11,6 -BRDA:66,5,0,4 -BRDA:75,5,1,12 -BRDA:75,5,2,1 -BRDA:79,5,3,11 -BRDA:80,5,4,2 -BRDA:85,5,5,9 -BRDA:88,5,6,6 -BRDA:94,5,7,3 -BRDA:98,5,8,0 -BRDA:101,5,9,3 -BRDA:103,5,10,1 -BRDA:106,5,11,2 -BRDA:100,6,0,3 -BRDA:102,6,1,6 -BRDA:104,6,2,3 -BRDA:106,6,3,3 -BRDA:1,7,0,1 -BRDA:1,7,1,2 -BRDA:1,7,2,1 -BRDA:1,7,3,1 -BRF:57 -BRH:55 -DA:4,4 -DA:6,1 -DA:13,4 -DA:14,4 -DA:15,4 -DA:16,4 -DA:18,4 -DA:21,73 -DA:24,73 -DA:25,73 -DA:26,73 -DA:27,73 -DA:28,73 -DA:29,73 -DA:30,80 -DA:31,80 -DA:33,80 -DA:35,121 -DA:36,138 -DA:38,138 -DA:39,121 -DA:41,73 -DA:42,79 -DA:43,79 -DA:44,79 -DA:45,80 -DA:46,80 -DA:48,106 -DA:49,89 -DA:51,38 -DA:52,86 -DA:54,86 -DA:55,82 -DA:56,84 -DA:57,84 -DA:58,84 -DA:60,72 -DA:61,75 -DA:62,75 -DA:63,75 -DA:65,52 -DA:66,74 -DA:67,74 -DA:68,74 -DA:70,78 -DA:71,78 -DA:72,78 -DA:74,72 -DA:75,86 -DA:76,86 -DA:77,86 -DA:79,86 -DA:80,86 -DA:81,88 -DA:82,88 -DA:84,0 -DA:85,0 -DA:86,0 -DA:88,68 -DA:89,77 -DA:90,77 -DA:91,77 -DA:93,80 -DA:94,74 -DA:95,77 -DA:96,71 -DA:98,0 -DA:99,0 -DA:100,0 -DA:101,0 -DA:102,38 -DA:103,41 -DA:104,36 -DA:105,39 -DA:106,35 -DA:107,40 -DA:108,37 -DA:109,37 -LH:71 -LF:78 -end_of_record diff --git a/mod_clipboard.ts b/mod_clipboard.ts index 116860c..0f0bae6 100644 --- a/mod_clipboard.ts +++ b/mod_clipboard.ts @@ -1 +1 @@ -export { setText } from "./src/clipboardActions.ts" \ No newline at end of file +export { setText, clear } from "./src/clipboard-actions.ts" \ No newline at end of file diff --git a/mod_keyboard.ts b/mod_keyboard.ts index f360e6b..de2939e 100644 --- a/mod_keyboard.ts +++ b/mod_keyboard.ts @@ -1,2 +1,2 @@ -export {sendKey, typing, copy, cut, paste, selectAll} from "./src/keyboardActions.ts" -export { Key } from "./src/models/Keys.ts"; +export {sendKey, typing, copy, cut, paste, selectAll} from "./src/keyboard-actions.ts" +export { Key } from "./src/models/keyboard.ts"; diff --git a/mod_mouse.ts b/mod_mouse.ts index be07bf3..43095c4 100644 --- a/mod_mouse.ts +++ b/mod_mouse.ts @@ -1 +1 @@ -export {left, right, middle, setCursor} from "./src/mouseActions.ts" \ No newline at end of file +export {left, right, middle, setCursor} from "./src/mouse-actions.ts" \ No newline at end of file diff --git a/mod_window.ts b/mod_window.ts index ec7ccdb..ab02cf2 100644 --- a/mod_window.ts +++ b/mod_window.ts @@ -1 +1,9 @@ -export {byProcessId, byProcessName, byTitleContains, byTitleEndsWith, byTitleExact, byTitleStartsWith} from "./src/windowActions.ts" \ No newline at end of file +export { + byProcessId, + byProcessName, + byTitleContains, + byTitleEndsWith, + byTitleExact, + byTitleStartsWith, + activeWindow, +} from "./src/window-actions.ts"; diff --git a/src/clipboardActions.ts b/src/clipboard-actions.ts similarity index 100% rename from src/clipboardActions.ts rename to src/clipboard-actions.ts diff --git a/src/keyboardActions.ts b/src/keyboard-actions.ts similarity index 98% rename from src/keyboardActions.ts rename to src/keyboard-actions.ts index d9d38c0..657f9c2 100644 --- a/src/keyboardActions.ts +++ b/src/keyboard-actions.ts @@ -1,7 +1,6 @@ -import { ASCII_VCODE, Key } from "./models/Keys.ts"; +import { ASCII_VCODE, Key } from "./models/keyboard.ts"; import * as nirCmd from "./nirCmd.ts"; - /** * Sends keyboard input. * @date 12/26/2023 - 4:30:08 PM @@ -42,7 +41,6 @@ export async function sendKey( return res; } - /** * Type an input string using sendKeys * @date 12/26/2023 - 4:35:03 PM @@ -68,7 +66,6 @@ export async function typing(text: string): Promise { } } - /** * Simulate Ctrl + X: Cut * @date 12/27/2023 - 9:38:36 PM diff --git a/src/models/AsciiVCodeModel.ts b/src/models/AsciiVCodeModel.ts deleted file mode 100644 index f5d6260..0000000 --- a/src/models/AsciiVCodeModel.ts +++ /dev/null @@ -1,6 +0,0 @@ -export interface AsciiVCode { - ascii: number - vCode: number - shift: boolean - desc: string -} \ No newline at end of file diff --git a/src/models/MouseButton.ts b/src/models/MouseButton.ts deleted file mode 100644 index cdb6e5b..0000000 --- a/src/models/MouseButton.ts +++ /dev/null @@ -1,31 +0,0 @@ -import * as mouse from "../mouseActions.ts" -import { ButtonActions, MouseButtons } from "./Types.ts"; - -export * as mouse from "../mouseActions.ts" -export class MouseButton { - private button: MouseButtons - - constructor(button: MouseButtons) { - this.button = button; - } - - private async doAction(action: ButtonActions) { - await mouse.button({button: this.button, action: action}) - } - - public async click() { - await this.doAction("click") - } - - public async down() { - await this.doAction("down") - } - - public async up() { - await this.doAction("up") - } - - public async doubleClick() { - await this.doAction("dblclick") - } -} \ No newline at end of file diff --git a/src/models/OSModel.ts b/src/models/OSModel.ts deleted file mode 100644 index dece64e..0000000 --- a/src/models/OSModel.ts +++ /dev/null @@ -1,10 +0,0 @@ -export enum OS { - windows = "windows", - linux = "linux", - darwin = "darwin", - freebsd = "freebsd", - netbsd = "netbsd", - aix = "aix", - solaris = "solaris", - illumos = "illumos", -} \ No newline at end of file diff --git a/src/models/Types.ts b/src/models/Types.ts deleted file mode 100644 index 96fcab1..0000000 --- a/src/models/Types.ts +++ /dev/null @@ -1,13 +0,0 @@ -export type ButtonActions = "down" | "up" | "click" | "dblclick"; -export type MouseButtons = "right" | "left" | "middle"; -export type WindowActions = - | "close" - | "activate" - | "flash" - | "max" - | "min" - | "normal" - | "togglemin" - | "togglemax" - | "center" - | "focus"; diff --git a/src/models/WindowActionModel.ts b/src/models/WindowActionModel.ts deleted file mode 100644 index fa1a793..0000000 --- a/src/models/WindowActionModel.ts +++ /dev/null @@ -1,9 +0,0 @@ -export interface IWindowAction { - action: "setsize" | "move" - size: { - x: number; - y: number; - width: number; - height: number; - }; -} diff --git a/src/models/WindowFindModel.ts b/src/models/WindowFindModel.ts deleted file mode 100644 index 984562c..0000000 --- a/src/models/WindowFindModel.ts +++ /dev/null @@ -1,9 +0,0 @@ -export interface WindowFind { - active?: boolean - className?: string - title?: { - value: string - match: 'exact' | 'startsWith' | 'endsWith' | 'contains' - } - process?: number | string -} \ No newline at end of file diff --git a/src/models/WindowFinder.ts b/src/models/WindowFinder.ts deleted file mode 100644 index fc728c9..0000000 --- a/src/models/WindowFinder.ts +++ /dev/null @@ -1,96 +0,0 @@ -import { windowActions } from "../windowActions.ts"; -import { WindowActions } from "./Types.ts"; -import { IWindowAction } from "./WindowActionModel.ts"; -import { WindowFind } from "./WindowFindModel.ts"; - -export class WindowFinder { - private wf: WindowFind; - - public constructor(wf: WindowFind) { - this.wf = wf; - } - - private async doAction( - action: - | IWindowAction - | WindowActions, - ): Promise { - return await windowActions({ window: this.wf, action: action }); - } - - async flash(): Promise { - return await this.doAction("flash"); - } - - async min(): Promise { - return await this.doAction("min"); - } - - async max(): Promise { - return await this.doAction("max"); - } - - async activate(): Promise { - return await this.doAction("activate"); - } - - async center(): Promise { - return await this.doAction("center"); - } - - async close(): Promise { - return await this.doAction("close"); - } - - async focus(): Promise { - return await this.doAction("focus"); - } - - async normal(): Promise { - return await this.doAction("normal"); - } - - async toggleMax(): Promise { - return await this.doAction("togglemax"); - } - - async toggleMin(): Promise { - return await this.doAction("togglemin"); - } - - async setSize( - x: number, - y: number, - width: number, - height: number, - ): Promise { - const action: IWindowAction = { - action: "setsize", - size: { - x: x, - y: y, - width: width, - height: height, - }, - }; - return await this.doAction(action); - } - - async moveBy( - x: number, - y: number, - width: number, - height: number, - ): Promise { - const action: IWindowAction = { - action: "move", - size: { - x: x, - y: y, - width: width, - height: height, - }, - }; - return await this.doAction(action); - } -} diff --git a/src/models/Keys.ts b/src/models/keyboard.ts similarity index 98% rename from src/models/Keys.ts rename to src/models/keyboard.ts index 3b1954d..9b5de6a 100644 --- a/src/models/Keys.ts +++ b/src/models/keyboard.ts @@ -1,4 +1,9 @@ -import { AsciiVCode } from "./AsciiVCodeModel.ts"; +export interface AsciiVCode { + ascii: number + vCode: number + shift: boolean + desc: string +} export enum Key { Backspace = 8, @@ -252,4 +257,4 @@ export const ASCII_VCODE: Array = [ { ascii: 124, vCode: 220, shift: true, desc: "Vertical bar" }, { ascii: 125, vCode: 221, shift: true, desc: "Closing brace" }, { ascii: 126, vCode: 192, shift: true, desc: "Equivalency sign - tilde" }, -]; +] diff --git a/src/models/mouse.ts b/src/models/mouse.ts new file mode 100644 index 0000000..bf79eb3 --- /dev/null +++ b/src/models/mouse.ts @@ -0,0 +1,2 @@ +export type ButtonActions = "down" | "up" | "click" | "dblclick" +export type MouseButtons = "right" | "left" | "middle" \ No newline at end of file diff --git a/src/models/window.ts b/src/models/window.ts new file mode 100644 index 0000000..c654df7 --- /dev/null +++ b/src/models/window.ts @@ -0,0 +1,33 @@ +export type WindowActions = + | "close" + | "activate" + | "flash" + | "max" + | "min" + | "normal" + | "togglemin" + | "togglemax" + | "center" + | "focus" + +export type MatchType = 'exact' | 'startsWith' | 'endsWith' | 'contains' + +export interface IWindowAction { + action: "setsize" | "move" + size: { + x: number; + y: number; + width: number; + height: number; + }; +} + +export interface WindowFind { + active?: boolean + className?: string + title?: { + value: string + match: MatchType + } + process?: number | string +} diff --git a/src/mouseActions.ts b/src/mouse-actions.ts similarity index 67% rename from src/mouseActions.ts rename to src/mouse-actions.ts index 83e8fe8..dff8b1c 100644 --- a/src/mouseActions.ts +++ b/src/mouse-actions.ts @@ -1,8 +1,6 @@ -import { MouseButton } from "./models/MouseButton.ts"; -import { ButtonActions, MouseButtons } from "./models/Types.ts"; +import { ButtonActions, MouseButtons } from "./models/mouse.ts"; import * as nirCmd from "./nirCmd.ts"; - /** * Set cursor position * @date 12/26/2023 - 4:51:31 PM @@ -21,27 +19,33 @@ export async function setCursor(x: number, y: number): Promise { return res; } -/** - * Description placeholder - * @date 12/26/2023 - 4:51:37 PM - * - * @export - * @async - * @param {({ button: MouseButtons; action: ButtonActions; })} param0 - * @param {(MouseButtons)} param0.button - * @param {(ButtonActions)} param0.action - * @returns {Promise} - */ -export async function button( -{ button, action }: { button: MouseButtons; action: ButtonActions; }, -): Promise { - const args: Array = ["sendmouse"]; - args.push(button); - args.push(action); - const res = await nirCmd.runNirCmd(args); - return res; -} +export class MouseButton { + private button: MouseButtons + + constructor(button: MouseButtons) { + this.button = button + } + private async doAction(action: ButtonActions) { + await button({button: this.button, action: action}) + } + + public async click() { + await this.doAction("click") + } + + public async down() { + await this.doAction("down") + } + + public async up() { + await this.doAction("up") + } + + public async doubleClick() { + await this.doAction("dblclick") + } +} /** * Returns the left mouse button to perform actions (click, down, up, double click) @@ -94,3 +98,24 @@ export function middle(): MouseButton { return rtnVal } +/** + * Access to mouse buttons + * @date 12/26/2023 - 4:51:37 PM + * + * @export + * @async + * @param {({ button: MouseButtons; action: ButtonActions; })} param0 + * @param {(MouseButtons)} param0.button + * @param {(ButtonActions)} param0.action + * @returns {Promise} + */ +async function button( + { button, action }: { button: MouseButtons; action: ButtonActions; }, + ): Promise { + const args: Array = ["sendmouse"]; + args.push(button); + args.push(action); + const res = await nirCmd.runNirCmd(args); + return res; + } + \ No newline at end of file diff --git a/src/nirCmd.ts b/src/nirCmd.ts index 0f53048..332840e 100644 --- a/src/nirCmd.ts +++ b/src/nirCmd.ts @@ -1,9 +1,8 @@ -import { join } from "https://deno.land/std@0.210.0/path/mod.ts"; -import { ensureDir } from "https://deno.land/std@0.210.0/fs/ensure_dir.ts"; -import { exists } from "https://deno.land/std@0.210.0/fs/exists.ts"; -import * as create from "./tsToCmd.ts"; -import { OS } from "./models/OSModel.ts"; -import { parseArgs } from "https://deno.land/std@0.210.0/cli/parse_args.ts"; +import { join } from "https://deno.land/std@0.210.0/path/mod.ts" +import { ensureDir } from "https://deno.land/std@0.210.0/fs/ensure_dir.ts" +import { exists } from "https://deno.land/std@0.210.0/fs/exists.ts" +import { parseArgs } from "https://deno.land/std@0.210.0/cli/parse_args.ts" +import { bin as nirBin } from "./bin/nircmd.ts" /** * Run nircmd @@ -42,23 +41,27 @@ export function validateNotBlank(value: string, errorMessage: string): void { } } -export function getOS(): OS { +export function isBlank(str: string) { + return (!str || /^\s*$/.test(str)); +} + +function getOS(): OS { return OS[Deno.build.os]; } -export async function getNir(): Promise { +async function getNir(): Promise { const denoPilotFolder = join(getDenoDir(), "bin/denopilot/"); const nirPath = join(denoPilotFolder, "nircmd.exe"); const ex = await exists(nirPath); if (!ex) { // Ensure directory await ensureDir(denoPilotFolder); - await create.createNirBin(nirPath); + await createNirBin(nirPath); } return nirPath; } -export function getDenoDir(): string { +function getDenoDir(): string { const os = getOS(); const homeKey: string = os === OS.windows ? "USERPROFILE" : "HOME"; const homeDir = Deno.env.get(homeKey); @@ -83,11 +86,30 @@ export function getDenoDir(): string { } } -export function isBlank(str: string) { - return (!str || /^\s*$/.test(str)); -} - function isDebug(): boolean { const parsedArgs = parseArgs(Deno.args); return parsedArgs.debug +} + +enum OS { + windows = "windows", + linux = "linux", + darwin = "darwin", + freebsd = "freebsd", + netbsd = "netbsd", + aix = "aix", + solaris = "solaris", + illumos = "illumos", +} + +async function createNirBin(nirPath: string) { + const binContent = atob(nirBin) + const binArray = new Uint8Array(binContent.length); + + let ctn = 0; + binContent.split("").forEach(char => { + binArray[ctn++] = char.charCodeAt(0); + }); + + await Deno.writeFile(nirPath, binArray) } \ No newline at end of file diff --git a/src/nirCmd_test.ts b/src/nirCmd_test.ts deleted file mode 100644 index e69de29..0000000 diff --git a/src/tsToCmd.ts b/src/tsToCmd.ts deleted file mode 100644 index 963406e..0000000 --- a/src/tsToCmd.ts +++ /dev/null @@ -1,13 +0,0 @@ -import { bin as nirBin } from "./bin/nircmd.ts" - -export async function createNirBin(nirPath: string) { - const binContent = atob(nirBin) - const binArray = new Uint8Array(binContent.length); - - let ctn = 0; - binContent.split("").forEach(char => { - binArray[ctn++] = char.charCodeAt(0); - }); - - await Deno.writeFile(nirPath, binArray) -} \ No newline at end of file diff --git a/src/utils.ts b/src/utils.ts deleted file mode 100644 index ef5c679..0000000 --- a/src/utils.ts +++ /dev/null @@ -1,110 +0,0 @@ -import { WindowActions } from "./models/Types.ts"; -import { IWindowAction } from "./models/WindowActionModel.ts"; -import { WindowFind } from "./models/WindowFindModel.ts"; -import { validateNotBlank } from "./nirCmd.ts"; - -/** - * Generate NirCmd arguments - * @date 12/23/2023 - 10:37:21 PM - * - * @export - * @param {(WindowFind | string)} window - * @param {(IWindowAction | string)} action - */ -export function getNirArgs( - window: WindowFind | string, - action: - | IWindowAction - | WindowActions, - ): Array { - - const act = typeof action === "string" ? action : action.action; - - - //Assert that at least one window find option is passed - if ( - typeof window !== "string" && window.active === undefined && - window.className === undefined && window.process === undefined && - window.title === undefined - ) { - throw new Error( - "Parameter window should be valid: title, active, class or process", - ); - } - - const args: Array = []; - args.push(act); - - const winArgs = getWindowArgs(window); - args.push(...winArgs); - - if (typeof action !== "string") { - args.push(action.size.x.toString()); - args.push(action.size.y.toString()); - args.push(action.size.width.toString()); - args.push(action.size.height.toString()); - } - - return args; - } - - export function getWindowArgs(window: WindowFind | string): Array { - const args: Array = []; - - if (typeof window === "string") { - validateNotBlank(window, "Parameter window should be valid: window"); - args.push("title", `${window}`); - return args; - } - - if (window.active !== undefined) { - args.push("active"); - return args; - } - - if (window.className !== undefined) { - validateNotBlank( - window.className, - "Parameter window should be valid: className", - ); - args.push("class", `${window.className}`); - return args; - } - - if (window.title !== undefined) { - validateNotBlank( - window.title.value, - "Parameter window should be valid: value", - ); - const match = matchConvert(window.title.match); - args.push(`${match}`, `${window.title.value}`); - return args; - } - - if (window.process === undefined) { - throw new Error("Parameter window should be valid: process"); - } - - if (typeof window.process === "number") { - args.push("process", `/${window.process}`); - return args; - } - - validateNotBlank(window.process, "Parameter window should be valid: process"); - args.push("process", `${window.process}`); - return args; - } - - function matchConvert(match: "exact" | "startsWith" | "endsWith" | "contains") { - switch (match) { - case "exact": - return "title"; - case "contains": - return "ititle"; - case "endsWith": - return "etitle"; - case "startsWith": - return "stitle"; - } - } - \ No newline at end of file diff --git a/src/utils_test.ts b/src/utils_test.ts deleted file mode 100644 index aa50776..0000000 --- a/src/utils_test.ts +++ /dev/null @@ -1,227 +0,0 @@ -import { - assertEquals, - assertThrows, - } from "https://deno.land/std@0.182.0/testing/asserts.ts"; - import { getNirArgs } from "./utils.ts"; - - Deno.test({ - name: "Test-getNirArgs-string", - fn(): void { - const res = getNirArgs("notepad", "min"); - const expectedRes: Array = ["min", "title", 'notepad']; - assertEquals(res, expectedRes); - }, - }); - - Deno.test({ - name: "Test-getNirArgs-active", - fn(): void { - const res = getNirArgs({ active: true }, "min"); - const expectedRes: Array = ["min", "active"]; - assertEquals(res, expectedRes); - }, - }); - - Deno.test({ - name: "Test-getNirArgs-className", - fn(): void { - const res = getNirArgs({ className: "HD" }, "min"); - const expectedRes: Array = ["min", "class", 'HD']; - assertEquals(res, expectedRes); - }, - }); - - Deno.test({ - name: "Test-getNirArgs-process-number", - fn(): void { - const res = getNirArgs({ process: 12 }, "min"); - const expectedRes: Array = ["min", "process", "/12"]; - assertEquals(res, expectedRes); - }, - }); - - Deno.test({ - name: "Test-getNirArgs-process-string", - fn(): void { - const res = getNirArgs({ process: "p.exe" }, "min"); - const expectedRes: Array = ["min", "process", "p.exe"]; - assertEquals(res, expectedRes); - }, - }); - - Deno.test({ - name: "Test-getNirArgs-title-contains", - fn(): void { - const res = getNirArgs({ - title: { value: "notepad", match: "contains" }, - }, "min"); - const expectedRes: Array = ["min", "ititle", 'notepad']; - assertEquals(res, expectedRes); - }, - }); - - Deno.test({ - name: "Test-getNirArgs-title-endswith", - fn(): void { - const res = getNirArgs({ - title: { value: "notepad", match: "endsWith" }, - }, "min"); - const expectedRes: Array = ["min", "etitle", 'notepad']; - assertEquals(res, expectedRes); - }, - }); - - Deno.test({ - name: "Test-getNirArgs-title-startswith", - fn(): void { - const res = getNirArgs({ - title: { value: "notepad", match: "startsWith" }, - }, "min"); - const expectedRes: Array = ["min", "stitle", 'notepad']; - assertEquals(res, expectedRes); - }, - }); - - Deno.test({ - name: "Test-getNirArgs-title-exact", - fn(): void { - const res = getNirArgs({ - title: { value: "notepad", match: "exact" }, - }, "min"); - const expectedRes: Array = ["min", "title", 'notepad']; - assertEquals(res, expectedRes); - }, - }); - // - Deno.test({ - name: "Test-getNirArgs-setsize", - fn(): void { - const res = getNirArgs("notepad", { - action: "setsize", - size: { - x: 1, - y: 2, - width: 3, - height: 4, - }, - }); - const expectedRes: Array = [ - "setsize", - "title", - 'notepad', - '1', - '2', - '3', - '4', - ]; - assertEquals(res, expectedRes); - }, - }); - - Deno.test({ - name: "Test-getNirArgs-all", - fn(): void { - const res = getNirArgs({ - title: { - match: "contains", - value: "notepad", - }, - }, { - action: "setsize", - size: { - x: 1, - y: 2, - width: 3, - height: 4, - }, - }); - const expectedRes: Array = [ - "setsize", - "ititle", - 'notepad', - '1', - '2', - '3', - '4', - ]; - assertEquals(res, expectedRes); - }, - }); - - Deno.test({ - name: "Test-getNirArgs-exception-window-1", - fn(): void { - assertThrows( - () => { - getNirArgs({}, "min"); - }, - Error, - "Parameter window should be valid", - ); - }, - }); - Deno.test({ - name: "Test-getNirArgs-exception-window-2", - fn(): void { - assertThrows( - () => { - getNirArgs("", "min"); - }, - Error, - "Parameter window should be valid: window", - ); - }, - }); - - Deno.test({ - name: "Test-getNirArgs-exception-window-3", - fn(): void { - assertThrows( - () => { - getNirArgs(" ", "min"); - }, - Error, - "Parameter window should be valid: window", - ); - }, - }); - - Deno.test({ - name: "Test-getNirArgs-exception-window-3", - fn(): void { - assertThrows( - () => { - getNirArgs({ className: "" }, "min"); - }, - Error, - "Parameter window should be valid: className", - ); - }, - }); - - Deno.test({ - name: "Test-getNirArgs-exception-window-4", - fn(): void { - assertThrows( - () => { - getNirArgs({ process: "" }, "min"); - }, - Error, - "Parameter window should be valid: process", - ); - }, - }); - - Deno.test({ - name: "Test-getNirArgs-exception-window-5", - fn(): void { - assertThrows( - () => { - getNirArgs({ title: { value: " ", match: "contains" } }, "min"); - }, - Error, - "Parameter window should be valid: value", - ); - }, - }); - \ No newline at end of file diff --git a/src/windowActions.ts b/src/window-actions.ts similarity index 51% rename from src/windowActions.ts rename to src/window-actions.ts index c156d9e..446c28a 100644 --- a/src/windowActions.ts +++ b/src/window-actions.ts @@ -1,89 +1,6 @@ -import { WindowFind } from "./models/WindowFindModel.ts"; -import { IWindowAction } from "./models/WindowActionModel.ts"; -import { getNirArgs } from "./utils.ts"; -import { runNirCmd } from "./nirCmd.ts"; -import { WindowFinder } from "./models/WindowFinder.ts"; -import { WindowActions } from "./models/Types.ts"; - - -/** - * Window Actions - * @date 12/25/2023 - 6:57:44 PM - * - * @export - * @async - * - * @example - * ```ts - * import * as win from "./src/windowActions.ts"; - * //Activate the window with exact title "myfile.txt - Notepad" - * win.windowActions({ window: "myfile.txt - Notepad", action: "activate" }); - * ``` - * - * @example - * ```ts - * import * as win from "./src/windowActions.ts"; - * //Maximize all windows with title contains "myfile" - * win.windowActions({ window: {title: {value: "myfile", match:"contains"}}, action: "max" }); - * ``` - * - * @example - * ```ts - * import * as win from "./src/windowActions.ts"; - * //Minimize all windows with process name notepad.exe (notepad) - * win.windowActions({ window: {process: "notepad.exe"}, action: "min" }); - * ``` - * - * @example - * ```ts - * import * as win from "./src/windowActions.ts"; - * //Close the window by process id - * win.windowActions({ window: {process: 1234}, action: "close" }); - * ``` - * - * @example - * ```ts - * import * as win from "./src/windowActions.ts"; - * //Move the window to 1, 1 and set the size to 100, 100 - * win.windowActions({ - * window: "myfile.txt - Notepad", - * action: { action: "setsize", size: { x: 1, y: 1, width: 100, height: 100 } }, - * }); - * ``` - * - * @param {{ - * window: - * WindowFind | string; - * action: IWindowAction | - * "close" | - * "activate" | - * "flash" | - * "max" | - * "min" | - * "normal" | - * "togglemin" | - * "togglemax" | - * "center" | - * "focus"; - * }} param0 - * @param {*} param0.window - * @param {*} param0.action - * @returns {Promise} process exit code. - */ -export async function windowActions( - { window, action }: { - window: WindowFind | string; - action: - | IWindowAction - | WindowActions; - }, -): Promise { - const args = getNirArgs(window, action); - args.unshift("win"); - const res = await runNirCmd(args); - return res; -} - +import { IWindowAction, WindowFind } from "./models/window.ts"; +import { runNirCmd, validateNotBlank } from "./nirCmd.ts"; +import { WindowActions } from "./models/window.ts"; /** * Find window by exact title to execute an action @@ -229,7 +146,6 @@ export function byProcessId(processId: number): WindowFinder { return rtnVal } - /** * Finds the active window to execute an action. * @date 12/26/2023 - 4:23:33 PM @@ -245,3 +161,277 @@ export function activeWindow(): WindowFinder { return rtnVal } +export class WindowFinder { + private wf: WindowFind; + + public constructor(wf: WindowFind) { + this.wf = wf; + } + + private async doAction( + action: + | IWindowAction + | WindowActions, + ): Promise { + return await windowActions({ window: this.wf, action: action }); + } + + async flash(): Promise { + return await this.doAction("flash"); + } + + async min(): Promise { + return await this.doAction("min"); + } + + async max(): Promise { + return await this.doAction("max"); + } + + async activate(): Promise { + return await this.doAction("activate"); + } + + async center(): Promise { + return await this.doAction("center"); + } + + async close(): Promise { + return await this.doAction("close"); + } + + async focus(): Promise { + return await this.doAction("focus"); + } + + async normal(): Promise { + return await this.doAction("normal"); + } + + async toggleMax(): Promise { + return await this.doAction("togglemax"); + } + + async toggleMin(): Promise { + return await this.doAction("togglemin"); + } + + async setSize( + x: number, + y: number, + width: number, + height: number, + ): Promise { + const action: IWindowAction = { + action: "setsize", + size: { + x: x, + y: y, + width: width, + height: height, + }, + }; + return await this.doAction(action); + } + + async moveBy( + x: number, + y: number, + width: number, + height: number, + ): Promise { + const action: IWindowAction = { + action: "move", + size: { + x: x, + y: y, + width: width, + height: height, + }, + }; + return await this.doAction(action); + } +} + +/** + * Window Actions + * @date 12/25/2023 - 6:57:44 PM + * + * @export + * @async + * + * @example + * ```ts + * import * as win from "./src/windowActions.ts"; + * //Activate the window with exact title "myfile.txt - Notepad" + * win.windowActions({ window: "myfile.txt - Notepad", action: "activate" }); + * ``` + * + * @example + * ```ts + * import * as win from "./src/windowActions.ts"; + * //Maximize all windows with title contains "myfile" + * win.windowActions({ window: {title: {value: "myfile", match:"contains"}}, action: "max" }); + * ``` + * + * @example + * ```ts + * import * as win from "./src/windowActions.ts"; + * //Minimize all windows with process name notepad.exe (notepad) + * win.windowActions({ window: {process: "notepad.exe"}, action: "min" }); + * ``` + * + * @example + * ```ts + * import * as win from "./src/windowActions.ts"; + * //Close the window by process id + * win.windowActions({ window: {process: 1234}, action: "close" }); + * ``` + * + * @example + * ```ts + * import * as win from "./src/windowActions.ts"; + * //Move the window to 1, 1 and set the size to 100, 100 + * win.windowActions({ + * window: "myfile.txt - Notepad", + * action: { action: "setsize", size: { x: 1, y: 1, width: 100, height: 100 } }, + * }); + * ``` + * + * @param {{ +* window: +* WindowFind | string; +* action: IWindowAction | +* "close" | +* "activate" | +* "flash" | +* "max" | +* "min" | +* "normal" | +* "togglemin" | +* "togglemax" | +* "center" | +* "focus"; +* }} param0 +* @param {*} param0.window +* @param {*} param0.action +* @returns {Promise} process exit code. +*/ +async function windowActions( + { window, action }: { + window: WindowFind | string; + action: + | IWindowAction + | WindowActions; + }, +): Promise { + const args = getNirArgs(window, action); + args.unshift("win"); + const res = await runNirCmd(args); + return res; +} + +/** + * Generate NirCmd arguments + * @date 12/23/2023 - 10:37:21 PM + * + * @export + * @param {(WindowFind | string)} window + * @param {(IWindowAction | string)} action + */ +function getNirArgs( + window: WindowFind | string, + action: + | IWindowAction + | WindowActions, +): Array { + + const act = typeof action === "string" ? action : action.action; + + + //Assert that at least one window find option is passed + if ( + typeof window !== "string" && window.active === undefined && + window.className === undefined && window.process === undefined && + window.title === undefined + ) { + throw new Error( + "Parameter window should be valid: title, active, class or process", + ); + } + + const args: Array = []; + args.push(act); + + const winArgs = getWindowArgs(window); + args.push(...winArgs); + + if (typeof action !== "string") { + args.push(action.size.x.toString()); + args.push(action.size.y.toString()); + args.push(action.size.width.toString()); + args.push(action.size.height.toString()); + } + + return args; +} + +function getWindowArgs(window: WindowFind | string): Array { + const args: Array = []; + + if (typeof window === "string") { + validateNotBlank(window, "Parameter window should be valid: window"); + args.push("title", `${window}`); + return args; + } + + if (window.active !== undefined) { + args.push("active"); + return args; + } + + if (window.className !== undefined) { + validateNotBlank( + window.className, + "Parameter window should be valid: className", + ); + args.push("class", `${window.className}`); + return args; + } + + if (window.title !== undefined) { + validateNotBlank( + window.title.value, + "Parameter window should be valid: value", + ); + const match = matchConvert(window.title.match); + args.push(`${match}`, `${window.title.value}`); + return args; + } + + if (window.process === undefined) { + throw new Error("Parameter window should be valid: process"); + } + + if (typeof window.process === "number") { + args.push("process", `/${window.process}`); + return args; + } + + validateNotBlank(window.process, "Parameter window should be valid: process"); + args.push("process", `${window.process}`); + return args; +} + +function matchConvert(match: "exact" | "startsWith" | "endsWith" | "contains") { + switch (match) { + case "exact": + return "title"; + case "contains": + return "ititle"; + case "endsWith": + return "etitle"; + case "startsWith": + return "stitle"; + } +} diff --git a/src/windowActions_test.ts b/src/windowActions_test.ts deleted file mode 100644 index e69de29..0000000