diff --git a/.husky/pre-commit b/.husky/pre-commit new file mode 100644 index 0000000..0100eae --- /dev/null +++ b/.husky/pre-commit @@ -0,0 +1 @@ +npm run lint-staged diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 8fcc5a0..b3602ba 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -13,9 +13,11 @@ When reporting bugs, please include the following: Example bug report: Title: PixelSearch coordinates are offset by the horizontal resolution + Description: When using PixelSearch, the coordinates are offset by the horizontal resolution of the screen. For example, if I search for a blue pixel located at (700, 500), the function returns (2620, 500) on a 1920x1080 screen. + Code: ```typescript diff --git a/README.md b/README.md index e5b57c2..c1751ba 100644 --- a/README.md +++ b/README.md @@ -1,9 +1,9 @@ # AutoIt JS -Node.js bindings for AutoItX3.dll. -
+Node.js bindings for AutoItX3.dll. + ![NPM Version](https://img.shields.io/npm/v/%40ahmic%2Fautoit-js) ![GitHub License](https://img.shields.io/github/license/KasimAhmic/autoit-js) ![GitHub Actions Workflow Status](https://img.shields.io/github/actions/workflow/status/KasimAhmic/autoit-js/build.yml) @@ -15,24 +15,51 @@ Node.js bindings for AutoItX3.dll. ## What is AutoIt JS? -AutoIt is a Windows automation tool that can be used to automate tasks on Windows. AutoIt provides its own scripting language however, it can be difficult to work with if you need to integrate Windows automation into an existing test suite. +AutoIt is a Windows automation tool that can be used to automate tasks on Windows. AutoIt provides its own +scripting language however, it can be difficult to work with if you need to integrate Windows automation into +an existing test suite. Enter AutoIt JS. -AutoIt JS wraps the AutoItX3.dll library using [Koffi](https://koffi.dev/) to provide a simple to use interface for AutoIt. It allows you to take your existing JavaScript/TypeScript test suite powered by PlayWright/Cypress/Puppeteer/etc. and automate Windows programs with ease. +AutoIt JS wraps the AutoItX3.dll library using [Koffi](https://koffi.dev/) to provide a simple to use +interface for AutoIt. It allows you to take your existing JavaScript/TypeScript test suite powered by +Playwright/Cypress/Puppeteer/etc. and automate Windows programs with ease. ## Example Usage +### New Asynchronous API in v2 + +You can use the new asynchronous API in async contexts like Playwright and Cypress tests to avoid blocking the +event loop and slowing down your tests. + ```typescript import { Init, Run, Send, WinClose, WinWaitActive, autoit } from '@ahmic/autoit-js'; autoit.load(); -Init(); -Run('notepad.exe'); -WinWaitActive('[CLASS:Notepad]'); -Send('Hello, World!'); -WinClose('[CLASS:Notepad]'); +await Init(); +await Run('notepad.exe'); +await WinWaitActive('[CLASS:Notepad]'); +await Send('Hello, World!'); +await WinClose('[CLASS:Notepad]'); + +autoit.unload(); +``` + +### Synchronous API + +For simple scripting tasks, the synchronous API is the preferred way to use AutoIt JS. + +```typescript +import { InitSync, RunSync, SendSync, WinCloseSync, WinWaitActiveSync, autoit } from '@ahmic/autoit-js'; + +autoit.load(); + +InitSync(); +RunSync('notepad.exe'); +WinWaitActiveSync('[CLASS:Notepad]'); +SendSync('Hello, World!'); +WinCloseSync('[CLASS:Notepad]'); autoit.unload(); ``` diff --git a/TestApp/CMakeLists.txt b/TestApp/CMakeLists.txt index fb4747f..93f6c47 100644 --- a/TestApp/CMakeLists.txt +++ b/TestApp/CMakeLists.txt @@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 3.28) project(TestApp) enable_language(RC) -set(CMAKE_CXX_STANDARD 17) +set(CMAKE_CXX_STANDARD 20) set(RESOURCES "src/resources/TestApp.rc") diff --git a/TestApp/src/include/handles.h b/TestApp/src/include/handles.h index fa79c2f..d9f36f3 100644 --- a/TestApp/src/include/handles.h +++ b/TestApp/src/include/handles.h @@ -13,5 +13,6 @@ inline HWND cancelButtonHandle; inline HWND treeListViewHandle; inline HWND listViewHandle; inline HWND statusBarHandle; +inline HWND eventHandle; inline HFONT fontHandle; inline HBRUSH brushHandle; diff --git a/TestApp/src/include/util.h b/TestApp/src/include/util.h index 77b7ecd..5abe592 100644 --- a/TestApp/src/include/util.h +++ b/TestApp/src/include/util.h @@ -1,5 +1,6 @@ #pragma once +#include #include #include @@ -251,3 +252,22 @@ inline VOID SetTheme(HWND handle) { logger->warn("Failed to set theme on window. Reason: " + result); } } + +inline VOID UpdateLastEvent(UINT event, WPARAM wParam) { + const std::wstring name = [&] { + switch (event) { + case WM_MOUSEMOVE: return std::wstring(L"Mouse Move"); + case WM_LBUTTONDOWN: return std::wstring(L"Mouse Left Click"); + case WM_RBUTTONDOWN: return std::wstring(L"Mouse Right Click"); + case WM_LBUTTONDBLCLK: return std::wstring(L"Mouse Left Double Click"); + case WM_RBUTTONDBLCLK: return std::wstring(L"Mouse Right Double Click"); + case WM_MOUSEWHEEL: { + const wchar_t *dir = GET_WHEEL_DELTA_WPARAM(wParam) < 0 ? L"Down" : L"Up"; + return std::format(L"Mouse Wheel {}", dir); + } + default: return std::wstring(); + } + }(); + + SetWindowTextW(eventHandle, std::format(L"Last Event: {}", name).c_str()); +} diff --git a/TestApp/src/main.cpp b/TestApp/src/main.cpp index 01b13ad..559e643 100644 --- a/TestApp/src/main.cpp +++ b/TestApp/src/main.cpp @@ -253,7 +253,7 @@ LRESULT CALLBACK WndProc(HWND windowHandle, const UINT message, const WPARAM wPa FORM_INPUT_WIDTH, 30); - CreateCheckBox( + HWND checkBoxThree = CreateCheckBox( windowHandle, L"Check Box 3", PADDING, @@ -293,6 +293,14 @@ LRESULT CALLBACK WndProc(HWND windowHandle, const UINT message, const WPARAM wPa 155, MAX_CLIENT_HEIGHT - GetRectRelativeToParent(listViewHandle, windowHandle).bottom); + eventHandle = CreateStaticText( + windowHandle, + L"Last Event: ", + GetRectRelativeToParent(checkBoxOne, windowHandle).left, + GetRectRelativeToParent(checkBoxThree, windowHandle).bottom + PADDING + 5, + 300, + 20); + statusBarHandle = CreateWindowEx( 0, STATUSCLASSNAME, @@ -315,9 +323,9 @@ LRESULT CALLBACK WndProc(HWND windowHandle, const UINT message, const WPARAM wPa SetTheme(listViewHandle); SetTheme(treeListViewHandle); - } - break; + break; + } case WM_COMMAND: { switch (LOWORD(wParam)) { @@ -340,8 +348,19 @@ LRESULT CALLBACK WndProc(HWND windowHandle, const UINT message, const WPARAM wPa default: return DefWindowProc(windowHandle, message, wParam, lParam); } + + break; + } + + case WM_MOUSEMOVE: + case WM_LBUTTONDOWN: + case WM_RBUTTONDOWN: + case WM_LBUTTONDBLCLK: + case WM_RBUTTONDBLCLK: + case WM_MOUSEWHEEL: { + UpdateLastEvent(message, wParam); + break; } - break; case WM_PAINT: { PAINTSTRUCT ps; @@ -400,12 +419,14 @@ LRESULT CALLBACK WndProc(HWND windowHandle, const UINT message, const WPARAM wPa break; } - case WM_DESTROY: + case WM_DESTROY: { PostQuitMessage(0); break; + } - default: + default: { return DefWindowProc(windowHandle, message, wParam, lParam); + } } return 0; } diff --git a/bin/TestApp.exe b/bin/TestApp.exe index b446724..df18296 100644 Binary files a/bin/TestApp.exe and b/bin/TestApp.exe differ diff --git a/docs/Basic Usage.md b/docs/Basic Usage.md index f35fd46..6ccfd73 100644 --- a/docs/Basic Usage.md +++ b/docs/Basic Usage.md @@ -2,6 +2,64 @@ Using AutoIt JS is as straightforward as it gets; import function, call function, use result. +## Synchronous Example + +You can use the synchronous API for simple scripting tasks if you don't want to deal with promises. + +```typescript +import { + ControlClickByHandleSync, + ControlGetHandleSync, + InitSync, + RunSync, + SendSync, + WinCloseSync, + WinGetHandleSync, + WinWaitActiveSync, + WinWaitSync, + autoit, +} from '@ahmic/autoit-js'; + +// An instance of the AutoIt class is created automatically, you need only call load() to initialize it +autoit.load(); + +// Initialize AutoIt +InitSync(); + +// Run Notepad +RunSync('notepad.exe'); + +// Wait for Notepad to be active +WinWaitActiveSync('[CLASS:Notepad]'); + +// Type into Notepad +SendSync('Hello, World!'); + +// Close Notepad +WinCloseSync('[CLASS:Notepad]'); + +// Wait for the Save dialog to appear +WinWaitSync('Notepad', '&Save'); + +// Get the handle of the Save dialog +const dialogHandle = WinGetHandleSync('Notepad', '&Save'); + +// Get the handle of the Don't Save button +const buttonHandle = ControlGetHandleSync(dialogHandle, 'Button2'); + +// Click the Don't Save button +ControlClickByHandleSync(dialogHandle, buttonHandle); + +// Unload AutoIt +autoit.unload(); +``` + +## Asynchronous Example + +When in asynchronous contexts like in Cypress and Playwright, you can use the asynchronous API to avoid +blocking the event loop. The API is largely the same except that you need to `await` the functions and use the +non `Sync` versions. + ```typescript import { ControlClickByHandle, @@ -20,31 +78,31 @@ import { autoit.load(); // Initialize AutoIt -Init(); +await Init(); // Run Notepad -Run('notepad.exe'); +await Run('notepad.exe'); // Wait for Notepad to be active -WinWaitActive('[CLASS:Notepad]'); +await WinWaitActive('[CLASS:Notepad]'); // Type into Notepad -Send('Hello, World!'); +await Send('Hello, World!'); // Close Notepad -WinClose('[CLASS:Notepad]'); +await WinClose('[CLASS:Notepad]'); // Wait for the Save dialog to appear -WinWait('Notepad', '&Save'); +await WinWait('Notepad', '&Save'); // Get the handle of the Save dialog -const dialogHandle = WinGetHandle('Notepad', '&Save'); +const dialogHandle = await WinGetHandle('Notepad', '&Save'); // Get the handle of the Don't Save button -const buttonHandle = ControlGetHandle(dialogHandle, 'Button2'); +const buttonHandle = await ControlGetHandle(dialogHandle, 'Button2'); // Click the Don't Save button -ControlClickByHandle(dialogHandle, buttonHandle); +await ControlClickByHandle(dialogHandle, buttonHandle); // Unload AutoIt autoit.unload(); diff --git a/package-lock.json b/package-lock.json index c3cffa7..71df967 100644 --- a/package-lock.json +++ b/package-lock.json @@ -9,31 +9,37 @@ "version": "1.0.0", "license": "MIT", "dependencies": { - "koffi": "^2.12.0" + "koffi": "^2.13.0" }, "devDependencies": { - "@eslint/js": "^9.29.0", - "@rollup/plugin-typescript": "^12.1.3", + "@commitlint/cz-commitlint": "^19.8.1", + "@eslint/js": "^9.32.0", + "@rollup/plugin-typescript": "^12.1.4", "@semantic-release/changelog": "^6.0.3", "@semantic-release/git": "^10.0.1", "@semantic-release/github": "^11.0.3", - "@semantic-release/npm": "^12.0.1", + "@semantic-release/npm": "^12.0.2", "@trivago/prettier-plugin-sort-imports": "^5.2.2", - "@types/node": "^24.0.3", + "@types/node": "^24.2.0", "@vitest/coverage-v8": "^3.2.4", "@vitest/ui": "^3.2.4", - "eslint": "^9.29.0", - "prettier": "^3.5.3", + "commitizen": "^4.3.1", + "cz-conventional-changelog": "^3.3.0", + "eslint": "^9.32.0", + "husky": "^9.1.7", + "inquirer": "^9.3.7", + "lint-staged": "^16.1.2", + "prettier": "^3.6.2", "rimraf": "^6.0.1", - "rollup": "^4.44.0", + "rollup": "^4.46.2", "segfault-handler": "^1.3.0", - "semantic-release": "^24.2.5", + "semantic-release": "^24.2.7", "tslib": "^2.8.1", "tsx": "^4.20.3", - "typedoc": "^0.28.5", + "typedoc": "^0.28.9", "typedoc-material-theme": "^1.4.0", - "typescript": "^5.8.3", - "typescript-eslint": "^8.34.1", + "typescript": "^5.9.2", + "typescript-eslint": "^8.39.0", "vitest": "^3.2.4" } }, @@ -188,10 +194,201 @@ "node": ">=0.1.90" } }, + "node_modules/@commitlint/config-validator": { + "version": "19.8.1", + "resolved": "https://registry.npmjs.org/@commitlint/config-validator/-/config-validator-19.8.1.tgz", + "integrity": "sha512-0jvJ4u+eqGPBIzzSdqKNX1rvdbSU1lPNYlfQQRIFnBgLy26BtC0cFnr7c/AyuzExMxWsMOte6MkTi9I3SQ3iGQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@commitlint/types": "^19.8.1", + "ajv": "^8.11.0" + }, + "engines": { + "node": ">=v18" + } + }, + "node_modules/@commitlint/config-validator/node_modules/ajv": { + "version": "8.17.1", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.17.1.tgz", + "integrity": "sha512-B/gBuNg5SiMTrPkC+A2+cW0RszwxYmn6VYxB/inlBStS5nx6xHIt/ehKRhIMhqusl7a8LjQoZnjCs5vhwxOQ1g==", + "dev": true, + "license": "MIT", + "dependencies": { + "fast-deep-equal": "^3.1.3", + "fast-uri": "^3.0.1", + "json-schema-traverse": "^1.0.0", + "require-from-string": "^2.0.2" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" + } + }, + "node_modules/@commitlint/config-validator/node_modules/json-schema-traverse": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", + "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==", + "dev": true, + "license": "MIT" + }, + "node_modules/@commitlint/cz-commitlint": { + "version": "19.8.1", + "resolved": "https://registry.npmjs.org/@commitlint/cz-commitlint/-/cz-commitlint-19.8.1.tgz", + "integrity": "sha512-GndsziRLYQbmDSukwgQSp8G/cTlhJNn2U8nKZaNG9NiBxv17uMTI69u7c9RJTcAQCjVNOWWB4+CT/aPFxcbzSQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@commitlint/ensure": "^19.8.1", + "@commitlint/load": "^19.8.1", + "@commitlint/types": "^19.8.1", + "chalk": "^5.3.0", + "lodash.isplainobject": "^4.0.6", + "word-wrap": "^1.2.5" + }, + "engines": { + "node": ">=v18" + }, + "peerDependencies": { + "commitizen": "^4.0.3", + "inquirer": "^9.0.0" + } + }, + "node_modules/@commitlint/cz-commitlint/node_modules/chalk": { + "version": "5.4.1", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-5.4.1.tgz", + "integrity": "sha512-zgVZuo2WcZgfUEmsn6eO3kINexW8RAE4maiQ8QNs8CtpPCSyMiYsULR3HQYkm3w8FIA3SberyMJMSldGsW+U3w==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^12.17.0 || ^14.13 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/@commitlint/ensure": { + "version": "19.8.1", + "resolved": "https://registry.npmjs.org/@commitlint/ensure/-/ensure-19.8.1.tgz", + "integrity": "sha512-mXDnlJdvDzSObafjYrOSvZBwkD01cqB4gbnnFuVyNpGUM5ijwU/r/6uqUmBXAAOKRfyEjpkGVZxaDsCVnHAgyw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@commitlint/types": "^19.8.1", + "lodash.camelcase": "^4.3.0", + "lodash.kebabcase": "^4.1.1", + "lodash.snakecase": "^4.1.1", + "lodash.startcase": "^4.4.0", + "lodash.upperfirst": "^4.3.1" + }, + "engines": { + "node": ">=v18" + } + }, + "node_modules/@commitlint/execute-rule": { + "version": "19.8.1", + "resolved": "https://registry.npmjs.org/@commitlint/execute-rule/-/execute-rule-19.8.1.tgz", + "integrity": "sha512-YfJyIqIKWI64Mgvn/sE7FXvVMQER/Cd+s3hZke6cI1xgNT/f6ZAz5heND0QtffH+KbcqAwXDEE1/5niYayYaQA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=v18" + } + }, + "node_modules/@commitlint/load": { + "version": "19.8.1", + "resolved": "https://registry.npmjs.org/@commitlint/load/-/load-19.8.1.tgz", + "integrity": "sha512-9V99EKG3u7z+FEoe4ikgq7YGRCSukAcvmKQuTtUyiYPnOd9a2/H9Ak1J9nJA1HChRQp9OA/sIKPugGS+FK/k1A==", + "dev": true, + "license": "MIT", + "dependencies": { + "@commitlint/config-validator": "^19.8.1", + "@commitlint/execute-rule": "^19.8.1", + "@commitlint/resolve-extends": "^19.8.1", + "@commitlint/types": "^19.8.1", + "chalk": "^5.3.0", + "cosmiconfig": "^9.0.0", + "cosmiconfig-typescript-loader": "^6.1.0", + "lodash.isplainobject": "^4.0.6", + "lodash.merge": "^4.6.2", + "lodash.uniq": "^4.5.0" + }, + "engines": { + "node": ">=v18" + } + }, + "node_modules/@commitlint/load/node_modules/chalk": { + "version": "5.4.1", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-5.4.1.tgz", + "integrity": "sha512-zgVZuo2WcZgfUEmsn6eO3kINexW8RAE4maiQ8QNs8CtpPCSyMiYsULR3HQYkm3w8FIA3SberyMJMSldGsW+U3w==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^12.17.0 || ^14.13 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/@commitlint/resolve-extends": { + "version": "19.8.1", + "resolved": "https://registry.npmjs.org/@commitlint/resolve-extends/-/resolve-extends-19.8.1.tgz", + "integrity": "sha512-GM0mAhFk49I+T/5UCYns5ayGStkTt4XFFrjjf0L4S26xoMTSkdCf9ZRO8en1kuopC4isDFuEm7ZOm/WRVeElVg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@commitlint/config-validator": "^19.8.1", + "@commitlint/types": "^19.8.1", + "global-directory": "^4.0.1", + "import-meta-resolve": "^4.0.0", + "lodash.mergewith": "^4.6.2", + "resolve-from": "^5.0.0" + }, + "engines": { + "node": ">=v18" + } + }, + "node_modules/@commitlint/resolve-extends/node_modules/resolve-from": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz", + "integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/@commitlint/types": { + "version": "19.8.1", + "resolved": "https://registry.npmjs.org/@commitlint/types/-/types-19.8.1.tgz", + "integrity": "sha512-/yCrWGCoA1SVKOks25EGadP9Pnj0oAIHGpl2wH2M2Y46dPM2ueb8wyCVOD7O3WCTkaJ0IkKvzhl1JY7+uCT2Dw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/conventional-commits-parser": "^5.0.0", + "chalk": "^5.3.0" + }, + "engines": { + "node": ">=v18" + } + }, + "node_modules/@commitlint/types/node_modules/chalk": { + "version": "5.4.1", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-5.4.1.tgz", + "integrity": "sha512-zgVZuo2WcZgfUEmsn6eO3kINexW8RAE4maiQ8QNs8CtpPCSyMiYsULR3HQYkm3w8FIA3SberyMJMSldGsW+U3w==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^12.17.0 || ^14.13 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, "node_modules/@esbuild/aix-ppc64": { - "version": "0.25.5", - "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.25.5.tgz", - "integrity": "sha512-9o3TMmpmftaCMepOdA5k/yDw8SfInyzWWTjYTFCX3kPSDJMROQTb8jg+h9Cnwnmm1vOzvxN7gIfB5V2ewpjtGA==", + "version": "0.25.8", + "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.25.8.tgz", + "integrity": "sha512-urAvrUedIqEiFR3FYSLTWQgLu5tb+m0qZw0NBEasUeo6wuqatkMDaRT+1uABiGXEu5vqgPd7FGE1BhsAIy9QVA==", "cpu": [ "ppc64" ], @@ -206,9 +403,9 @@ } }, "node_modules/@esbuild/android-arm": { - "version": "0.25.5", - "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.25.5.tgz", - "integrity": "sha512-AdJKSPeEHgi7/ZhuIPtcQKr5RQdo6OO2IL87JkianiMYMPbCtot9fxPbrMiBADOWWm3T2si9stAiVsGbTQFkbA==", + "version": "0.25.8", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.25.8.tgz", + "integrity": "sha512-RONsAvGCz5oWyePVnLdZY/HHwA++nxYWIX1atInlaW6SEkwq6XkP3+cb825EUcRs5Vss/lGh/2YxAb5xqc07Uw==", "cpu": [ "arm" ], @@ -223,9 +420,9 @@ } }, "node_modules/@esbuild/android-arm64": { - "version": "0.25.5", - "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.25.5.tgz", - "integrity": "sha512-VGzGhj4lJO+TVGV1v8ntCZWJktV7SGCs3Pn1GRWI1SBFtRALoomm8k5E9Pmwg3HOAal2VDc2F9+PM/rEY6oIDg==", + "version": "0.25.8", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.25.8.tgz", + "integrity": "sha512-OD3p7LYzWpLhZEyATcTSJ67qB5D+20vbtr6vHlHWSQYhKtzUYrETuWThmzFpZtFsBIxRvhO07+UgVA9m0i/O1w==", "cpu": [ "arm64" ], @@ -240,9 +437,9 @@ } }, "node_modules/@esbuild/android-x64": { - "version": "0.25.5", - "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.25.5.tgz", - "integrity": "sha512-D2GyJT1kjvO//drbRT3Hib9XPwQeWd9vZoBJn+bu/lVsOZ13cqNdDeqIF/xQ5/VmWvMduP6AmXvylO/PIc2isw==", + "version": "0.25.8", + "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.25.8.tgz", + "integrity": "sha512-yJAVPklM5+4+9dTeKwHOaA+LQkmrKFX96BM0A/2zQrbS6ENCmxc4OVoBs5dPkCCak2roAD+jKCdnmOqKszPkjA==", "cpu": [ "x64" ], @@ -257,9 +454,9 @@ } }, "node_modules/@esbuild/darwin-arm64": { - "version": "0.25.5", - "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.25.5.tgz", - "integrity": "sha512-GtaBgammVvdF7aPIgH2jxMDdivezgFu6iKpmT+48+F8Hhg5J/sfnDieg0aeG/jfSvkYQU2/pceFPDKlqZzwnfQ==", + "version": "0.25.8", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.25.8.tgz", + "integrity": "sha512-Jw0mxgIaYX6R8ODrdkLLPwBqHTtYHJSmzzd+QeytSugzQ0Vg4c5rDky5VgkoowbZQahCbsv1rT1KW72MPIkevw==", "cpu": [ "arm64" ], @@ -274,9 +471,9 @@ } }, "node_modules/@esbuild/darwin-x64": { - "version": "0.25.5", - "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.25.5.tgz", - "integrity": "sha512-1iT4FVL0dJ76/q1wd7XDsXrSW+oLoquptvh4CLR4kITDtqi2e/xwXwdCVH8hVHU43wgJdsq7Gxuzcs6Iq/7bxQ==", + "version": "0.25.8", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.25.8.tgz", + "integrity": "sha512-Vh2gLxxHnuoQ+GjPNvDSDRpoBCUzY4Pu0kBqMBDlK4fuWbKgGtmDIeEC081xi26PPjn+1tct+Bh8FjyLlw1Zlg==", "cpu": [ "x64" ], @@ -291,9 +488,9 @@ } }, "node_modules/@esbuild/freebsd-arm64": { - "version": "0.25.5", - "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.25.5.tgz", - "integrity": "sha512-nk4tGP3JThz4La38Uy/gzyXtpkPW8zSAmoUhK9xKKXdBCzKODMc2adkB2+8om9BDYugz+uGV7sLmpTYzvmz6Sw==", + "version": "0.25.8", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.25.8.tgz", + "integrity": "sha512-YPJ7hDQ9DnNe5vxOm6jaie9QsTwcKedPvizTVlqWG9GBSq+BuyWEDazlGaDTC5NGU4QJd666V0yqCBL2oWKPfA==", "cpu": [ "arm64" ], @@ -308,9 +505,9 @@ } }, "node_modules/@esbuild/freebsd-x64": { - "version": "0.25.5", - "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.25.5.tgz", - "integrity": "sha512-PrikaNjiXdR2laW6OIjlbeuCPrPaAl0IwPIaRv+SMV8CiM8i2LqVUHFC1+8eORgWyY7yhQY+2U2fA55mBzReaw==", + "version": "0.25.8", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.25.8.tgz", + "integrity": "sha512-MmaEXxQRdXNFsRN/KcIimLnSJrk2r5H8v+WVafRWz5xdSVmWLoITZQXcgehI2ZE6gioE6HirAEToM/RvFBeuhw==", "cpu": [ "x64" ], @@ -325,9 +522,9 @@ } }, "node_modules/@esbuild/linux-arm": { - "version": "0.25.5", - "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.25.5.tgz", - "integrity": "sha512-cPzojwW2okgh7ZlRpcBEtsX7WBuqbLrNXqLU89GxWbNt6uIg78ET82qifUy3W6OVww6ZWobWub5oqZOVtwolfw==", + "version": "0.25.8", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.25.8.tgz", + "integrity": "sha512-FuzEP9BixzZohl1kLf76KEVOsxtIBFwCaLupVuk4eFVnOZfU+Wsn+x5Ryam7nILV2pkq2TqQM9EZPsOBuMC+kg==", "cpu": [ "arm" ], @@ -342,9 +539,9 @@ } }, "node_modules/@esbuild/linux-arm64": { - "version": "0.25.5", - "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.25.5.tgz", - "integrity": "sha512-Z9kfb1v6ZlGbWj8EJk9T6czVEjjq2ntSYLY2cw6pAZl4oKtfgQuS4HOq41M/BcoLPzrUbNd+R4BXFyH//nHxVg==", + "version": "0.25.8", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.25.8.tgz", + "integrity": "sha512-WIgg00ARWv/uYLU7lsuDK00d/hHSfES5BzdWAdAig1ioV5kaFNrtK8EqGcUBJhYqotlUByUKz5Qo6u8tt7iD/w==", "cpu": [ "arm64" ], @@ -359,9 +556,9 @@ } }, "node_modules/@esbuild/linux-ia32": { - "version": "0.25.5", - "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.25.5.tgz", - "integrity": "sha512-sQ7l00M8bSv36GLV95BVAdhJ2QsIbCuCjh/uYrWiMQSUuV+LpXwIqhgJDcvMTj+VsQmqAHL2yYaasENvJ7CDKA==", + "version": "0.25.8", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.25.8.tgz", + "integrity": "sha512-A1D9YzRX1i+1AJZuFFUMP1E9fMaYY+GnSQil9Tlw05utlE86EKTUA7RjwHDkEitmLYiFsRd9HwKBPEftNdBfjg==", "cpu": [ "ia32" ], @@ -376,9 +573,9 @@ } }, "node_modules/@esbuild/linux-loong64": { - "version": "0.25.5", - "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.25.5.tgz", - "integrity": "sha512-0ur7ae16hDUC4OL5iEnDb0tZHDxYmuQyhKhsPBV8f99f6Z9KQM02g33f93rNH5A30agMS46u2HP6qTdEt6Q1kg==", + "version": "0.25.8", + "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.25.8.tgz", + "integrity": "sha512-O7k1J/dwHkY1RMVvglFHl1HzutGEFFZ3kNiDMSOyUrB7WcoHGf96Sh+64nTRT26l3GMbCW01Ekh/ThKM5iI7hQ==", "cpu": [ "loong64" ], @@ -393,9 +590,9 @@ } }, "node_modules/@esbuild/linux-mips64el": { - "version": "0.25.5", - "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.25.5.tgz", - "integrity": "sha512-kB/66P1OsHO5zLz0i6X0RxlQ+3cu0mkxS3TKFvkb5lin6uwZ/ttOkP3Z8lfR9mJOBk14ZwZ9182SIIWFGNmqmg==", + "version": "0.25.8", + "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.25.8.tgz", + "integrity": "sha512-uv+dqfRazte3BzfMp8PAQXmdGHQt2oC/y2ovwpTteqrMx2lwaksiFZ/bdkXJC19ttTvNXBuWH53zy/aTj1FgGw==", "cpu": [ "mips64el" ], @@ -410,9 +607,9 @@ } }, "node_modules/@esbuild/linux-ppc64": { - "version": "0.25.5", - "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.25.5.tgz", - "integrity": "sha512-UZCmJ7r9X2fe2D6jBmkLBMQetXPXIsZjQJCjgwpVDz+YMcS6oFR27alkgGv3Oqkv07bxdvw7fyB71/olceJhkQ==", + "version": "0.25.8", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.25.8.tgz", + "integrity": "sha512-GyG0KcMi1GBavP5JgAkkstMGyMholMDybAf8wF5A70CALlDM2p/f7YFE7H92eDeH/VBtFJA5MT4nRPDGg4JuzQ==", "cpu": [ "ppc64" ], @@ -427,9 +624,9 @@ } }, "node_modules/@esbuild/linux-riscv64": { - "version": "0.25.5", - "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.25.5.tgz", - "integrity": "sha512-kTxwu4mLyeOlsVIFPfQo+fQJAV9mh24xL+y+Bm6ej067sYANjyEw1dNHmvoqxJUCMnkBdKpvOn0Ahql6+4VyeA==", + "version": "0.25.8", + "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.25.8.tgz", + "integrity": "sha512-rAqDYFv3yzMrq7GIcen3XP7TUEG/4LK86LUPMIz6RT8A6pRIDn0sDcvjudVZBiiTcZCY9y2SgYX2lgK3AF+1eg==", "cpu": [ "riscv64" ], @@ -444,9 +641,9 @@ } }, "node_modules/@esbuild/linux-s390x": { - "version": "0.25.5", - "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.25.5.tgz", - "integrity": "sha512-K2dSKTKfmdh78uJ3NcWFiqyRrimfdinS5ErLSn3vluHNeHVnBAFWC8a4X5N+7FgVE1EjXS1QDZbpqZBjfrqMTQ==", + "version": "0.25.8", + "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.25.8.tgz", + "integrity": "sha512-Xutvh6VjlbcHpsIIbwY8GVRbwoviWT19tFhgdA7DlenLGC/mbc3lBoVb7jxj9Z+eyGqvcnSyIltYUrkKzWqSvg==", "cpu": [ "s390x" ], @@ -461,9 +658,9 @@ } }, "node_modules/@esbuild/linux-x64": { - "version": "0.25.5", - "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.25.5.tgz", - "integrity": "sha512-uhj8N2obKTE6pSZ+aMUbqq+1nXxNjZIIjCjGLfsWvVpy7gKCOL6rsY1MhRh9zLtUtAI7vpgLMK6DxjO8Qm9lJw==", + "version": "0.25.8", + "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.25.8.tgz", + "integrity": "sha512-ASFQhgY4ElXh3nDcOMTkQero4b1lgubskNlhIfJrsH5OKZXDpUAKBlNS0Kx81jwOBp+HCeZqmoJuihTv57/jvQ==", "cpu": [ "x64" ], @@ -478,9 +675,9 @@ } }, "node_modules/@esbuild/netbsd-arm64": { - "version": "0.25.5", - "resolved": "https://registry.npmjs.org/@esbuild/netbsd-arm64/-/netbsd-arm64-0.25.5.tgz", - "integrity": "sha512-pwHtMP9viAy1oHPvgxtOv+OkduK5ugofNTVDilIzBLpoWAM16r7b/mxBvfpuQDpRQFMfuVr5aLcn4yveGvBZvw==", + "version": "0.25.8", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-arm64/-/netbsd-arm64-0.25.8.tgz", + "integrity": "sha512-d1KfruIeohqAi6SA+gENMuObDbEjn22olAR7egqnkCD9DGBG0wsEARotkLgXDu6c4ncgWTZJtN5vcgxzWRMzcw==", "cpu": [ "arm64" ], @@ -495,9 +692,9 @@ } }, "node_modules/@esbuild/netbsd-x64": { - "version": "0.25.5", - "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.25.5.tgz", - "integrity": "sha512-WOb5fKrvVTRMfWFNCroYWWklbnXH0Q5rZppjq0vQIdlsQKuw6mdSihwSo4RV/YdQ5UCKKvBy7/0ZZYLBZKIbwQ==", + "version": "0.25.8", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.25.8.tgz", + "integrity": "sha512-nVDCkrvx2ua+XQNyfrujIG38+YGyuy2Ru9kKVNyh5jAys6n+l44tTtToqHjino2My8VAY6Lw9H7RI73XFi66Cg==", "cpu": [ "x64" ], @@ -512,9 +709,9 @@ } }, "node_modules/@esbuild/openbsd-arm64": { - "version": "0.25.5", - "resolved": "https://registry.npmjs.org/@esbuild/openbsd-arm64/-/openbsd-arm64-0.25.5.tgz", - "integrity": "sha512-7A208+uQKgTxHd0G0uqZO8UjK2R0DDb4fDmERtARjSHWxqMTye4Erz4zZafx7Di9Cv+lNHYuncAkiGFySoD+Mw==", + "version": "0.25.8", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-arm64/-/openbsd-arm64-0.25.8.tgz", + "integrity": "sha512-j8HgrDuSJFAujkivSMSfPQSAa5Fxbvk4rgNAS5i3K+r8s1X0p1uOO2Hl2xNsGFppOeHOLAVgYwDVlmxhq5h+SQ==", "cpu": [ "arm64" ], @@ -529,9 +726,9 @@ } }, "node_modules/@esbuild/openbsd-x64": { - "version": "0.25.5", - "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.25.5.tgz", - "integrity": "sha512-G4hE405ErTWraiZ8UiSoesH8DaCsMm0Cay4fsFWOOUcz8b8rC6uCvnagr+gnioEjWn0wC+o1/TAHt+It+MpIMg==", + "version": "0.25.8", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.25.8.tgz", + "integrity": "sha512-1h8MUAwa0VhNCDp6Af0HToI2TJFAn1uqT9Al6DJVzdIBAd21m/G0Yfc77KDM3uF3T/YaOgQq3qTJHPbTOInaIQ==", "cpu": [ "x64" ], @@ -545,10 +742,27 @@ "node": ">=18" } }, + "node_modules/@esbuild/openharmony-arm64": { + "version": "0.25.8", + "resolved": "https://registry.npmjs.org/@esbuild/openharmony-arm64/-/openharmony-arm64-0.25.8.tgz", + "integrity": "sha512-r2nVa5SIK9tSWd0kJd9HCffnDHKchTGikb//9c7HX+r+wHYCpQrSgxhlY6KWV1nFo1l4KFbsMlHk+L6fekLsUg==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "openharmony" + ], + "engines": { + "node": ">=18" + } + }, "node_modules/@esbuild/sunos-x64": { - "version": "0.25.5", - "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.25.5.tgz", - "integrity": "sha512-l+azKShMy7FxzY0Rj4RCt5VD/q8mG/e+mDivgspo+yL8zW7qEwctQ6YqKX34DTEleFAvCIUviCFX1SDZRSyMQA==", + "version": "0.25.8", + "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.25.8.tgz", + "integrity": "sha512-zUlaP2S12YhQ2UzUfcCuMDHQFJyKABkAjvO5YSndMiIkMimPmxA+BYSBikWgsRpvyxuRnow4nS5NPnf9fpv41w==", "cpu": [ "x64" ], @@ -563,9 +777,9 @@ } }, "node_modules/@esbuild/win32-arm64": { - "version": "0.25.5", - "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.25.5.tgz", - "integrity": "sha512-O2S7SNZzdcFG7eFKgvwUEZ2VG9D/sn/eIiz8XRZ1Q/DO5a3s76Xv0mdBzVM5j5R639lXQmPmSo0iRpHqUUrsxw==", + "version": "0.25.8", + "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.25.8.tgz", + "integrity": "sha512-YEGFFWESlPva8hGL+zvj2z/SaK+pH0SwOM0Nc/d+rVnW7GSTFlLBGzZkuSU9kFIGIo8q9X3ucpZhu8PDN5A2sQ==", "cpu": [ "arm64" ], @@ -580,9 +794,9 @@ } }, "node_modules/@esbuild/win32-ia32": { - "version": "0.25.5", - "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.25.5.tgz", - "integrity": "sha512-onOJ02pqs9h1iMJ1PQphR+VZv8qBMQ77Klcsqv9CNW2w6yLqoURLcgERAIurY6QE63bbLuqgP9ATqajFLK5AMQ==", + "version": "0.25.8", + "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.25.8.tgz", + "integrity": "sha512-hiGgGC6KZ5LZz58OL/+qVVoZiuZlUYlYHNAmczOm7bs2oE1XriPFi5ZHHrS8ACpV5EjySrnoCKmcbQMN+ojnHg==", "cpu": [ "ia32" ], @@ -597,9 +811,9 @@ } }, "node_modules/@esbuild/win32-x64": { - "version": "0.25.5", - "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.25.5.tgz", - "integrity": "sha512-TXv6YnJ8ZMVdX+SXWVBo/0p8LTcrUYngpWjvm91TMjjBQii7Oz11Lw5lbDV5Y0TzuhSJHwiH4hEtC1I42mMS0g==", + "version": "0.25.8", + "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.25.8.tgz", + "integrity": "sha512-cn3Yr7+OaaZq1c+2pe+8yxC8E144SReCQjN6/2ynubzYjvyqZjTXfQJpAcQpsdJq3My7XADANiYGHoFC69pLQw==", "cpu": [ "x64" ], @@ -656,9 +870,9 @@ } }, "node_modules/@eslint/config-array": { - "version": "0.20.1", - "resolved": "https://registry.npmjs.org/@eslint/config-array/-/config-array-0.20.1.tgz", - "integrity": "sha512-OL0RJzC/CBzli0DrrR31qzj6d6i6Mm3HByuhflhl4LOBiWxN+3i6/t/ZQQNii4tjksXi8r2CRW1wMpWA2ULUEw==", + "version": "0.21.0", + "resolved": "https://registry.npmjs.org/@eslint/config-array/-/config-array-0.21.0.tgz", + "integrity": "sha512-ENIdc4iLu0d93HeYirvKmrzshzofPw6VkZRKQGe9Nv46ZnWUzcF1xV01dcvEg/1wXUR61OmmlSfyeyO7EvjLxQ==", "dev": true, "license": "Apache-2.0", "dependencies": { @@ -671,9 +885,9 @@ } }, "node_modules/@eslint/config-helpers": { - "version": "0.2.3", - "resolved": "https://registry.npmjs.org/@eslint/config-helpers/-/config-helpers-0.2.3.tgz", - "integrity": "sha512-u180qk2Um1le4yf0ruXH3PYFeEZeYC3p/4wCTKrr2U1CmGdzGi3KtY0nuPDH48UJxlKCC5RDzbcbh4X0XlqgHg==", + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/@eslint/config-helpers/-/config-helpers-0.3.1.tgz", + "integrity": "sha512-xR93k9WhrDYpXHORXpxVL5oHj3Era7wo6k/Wd8/IsQNnZUTzkGS29lyn3nAT05v6ltUuTFVCCYDEGfy2Or/sPA==", "dev": true, "license": "Apache-2.0", "engines": { @@ -681,9 +895,9 @@ } }, "node_modules/@eslint/core": { - "version": "0.14.0", - "resolved": "https://registry.npmjs.org/@eslint/core/-/core-0.14.0.tgz", - "integrity": "sha512-qIbV0/JZr7iSDjqAc60IqbLdsj9GDt16xQtWD+B78d/HAlvysGdZZ6rpJHGAc2T0FQx1X6thsSPdnoiGKdNtdg==", + "version": "0.15.2", + "resolved": "https://registry.npmjs.org/@eslint/core/-/core-0.15.2.tgz", + "integrity": "sha512-78Md3/Rrxh83gCxoUc0EiciuOHsIITzLy53m3d9UyiW8y9Dj2D29FeETqyKA+BRK76tnTp6RXWb3pCay8Oyomg==", "dev": true, "license": "Apache-2.0", "dependencies": { @@ -731,9 +945,9 @@ } }, "node_modules/@eslint/js": { - "version": "9.29.0", - "resolved": "https://registry.npmjs.org/@eslint/js/-/js-9.29.0.tgz", - "integrity": "sha512-3PIF4cBw/y+1u2EazflInpV+lYsSG0aByVIQzAgb1m1MhHFSbqTyNqtBKHgWf/9Ykud+DhILS9EGkmekVhbKoQ==", + "version": "9.32.0", + "resolved": "https://registry.npmjs.org/@eslint/js/-/js-9.32.0.tgz", + "integrity": "sha512-BBpRFZK3eX6uMLKz8WxFOBIFFcGFJ/g8XuwjTHCqHROSIsopI+ddn/d5Cfh36+7+e5edVS8dbSHnBNhrLEX0zg==", "dev": true, "license": "MIT", "engines": { @@ -754,43 +968,30 @@ } }, "node_modules/@eslint/plugin-kit": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/@eslint/plugin-kit/-/plugin-kit-0.3.2.tgz", - "integrity": "sha512-4SaFZCNfJqvk/kenHpI8xvN42DMaoycy4PzKc5otHxRswww1kAt82OlBuwRVLofCACCTZEcla2Ydxv8scMXaTg==", + "version": "0.3.5", + "resolved": "https://registry.npmjs.org/@eslint/plugin-kit/-/plugin-kit-0.3.5.tgz", + "integrity": "sha512-Z5kJ+wU3oA7MMIqVR9tyZRtjYPr4OC004Q4Rw7pgOKUOKkJfZ3O24nz3WYfGRpMDNmcOi3TwQOmgm7B7Tpii0w==", "dev": true, "license": "Apache-2.0", "dependencies": { - "@eslint/core": "^0.15.0", + "@eslint/core": "^0.15.2", "levn": "^0.4.1" }, "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" } }, - "node_modules/@eslint/plugin-kit/node_modules/@eslint/core": { - "version": "0.15.0", - "resolved": "https://registry.npmjs.org/@eslint/core/-/core-0.15.0.tgz", - "integrity": "sha512-b7ePw78tEWWkpgZCDYkbqDOP8dmM6qe+AOC6iuJqlq1R/0ahMAeH3qynpnqKFGkMltrp44ohV4ubGyvLX28tzw==", - "dev": true, - "license": "Apache-2.0", - "dependencies": { - "@types/json-schema": "^7.0.15" - }, - "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" - } - }, "node_modules/@gerrit0/mini-shiki": { - "version": "3.6.0", - "resolved": "https://registry.npmjs.org/@gerrit0/mini-shiki/-/mini-shiki-3.6.0.tgz", - "integrity": "sha512-KaeJvPNofTEZR9EzVNp/GQzbQqkGfjiu6k3CXKvhVTX+8OoAKSX/k7qxLKOX3B0yh2XqVAc93rsOu48CGt2Qug==", + "version": "3.9.2", + "resolved": "https://registry.npmjs.org/@gerrit0/mini-shiki/-/mini-shiki-3.9.2.tgz", + "integrity": "sha512-Tvsj+AOO4Z8xLRJK900WkyfxHsZQu+Zm1//oT1w443PO6RiYMoq/4NGOhaNuZoUMYsjKIAPVQ6eOFMddj6yphQ==", "dev": true, "license": "MIT", "dependencies": { - "@shikijs/engine-oniguruma": "^3.6.0", - "@shikijs/langs": "^3.6.0", - "@shikijs/themes": "^3.6.0", - "@shikijs/types": "^3.6.0", + "@shikijs/engine-oniguruma": "^3.9.2", + "@shikijs/langs": "^3.9.2", + "@shikijs/themes": "^3.9.2", + "@shikijs/types": "^3.9.2", "@shikijs/vscode-textmate": "^10.0.2" } }, @@ -860,6 +1061,16 @@ "url": "https://github.com/sponsors/nzakas" } }, + "node_modules/@inquirer/figures": { + "version": "1.0.13", + "resolved": "https://registry.npmjs.org/@inquirer/figures/-/figures-1.0.13.tgz", + "integrity": "sha512-lGPVU3yO9ZNqA7vTYz26jny41lE7yoQansmqdMLBEfqaGsmdg7V3W9mK9Pvb5IL4EVZ9GnSDGMO/cJXud5dMaw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18" + } + }, "node_modules/@isaacs/cliui": { "version": "8.0.2", "resolved": "https://registry.npmjs.org/@isaacs/cliui/-/cliui-8.0.2.tgz", @@ -931,9 +1142,9 @@ "license": "MIT" }, "node_modules/@jridgewell/trace-mapping": { - "version": "0.3.25", - "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.25.tgz", - "integrity": "sha512-vNk6aEwybGtawWmy/PzwnGDOjCkLWSD2wqvjGGAgOAwCGWySYXfYoxt00IJkTF+8Lb57DwOb3Aa0o9CApepiYQ==", + "version": "0.3.29", + "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.29.tgz", + "integrity": "sha512-uw6guiW/gcAGPDhLmd77/6lW8QLeiV5RUTsAX46Db6oLhGaVj4lhnPwb184s1bkc8kdVg/+h988dro8GRDpmYQ==", "dev": true, "license": "MIT", "dependencies": { @@ -1206,9 +1417,9 @@ "license": "MIT" }, "node_modules/@rollup/plugin-typescript": { - "version": "12.1.3", - "resolved": "https://registry.npmjs.org/@rollup/plugin-typescript/-/plugin-typescript-12.1.3.tgz", - "integrity": "sha512-gAx0AYwkyjqOw4JrZV34N/abvAobLhczyLkZ7FVL2UXPrO4zv8oqTfYT3DLBRan1EXasp4SUuEJXqPTk0gnJzw==", + "version": "12.1.4", + "resolved": "https://registry.npmjs.org/@rollup/plugin-typescript/-/plugin-typescript-12.1.4.tgz", + "integrity": "sha512-s5Hx+EtN60LMlDBvl5f04bEiFZmAepk27Q+mr85L/00zPDn1jtzlTV6FWn81MaIwqfWzKxmOJrBWHU6vtQyedQ==", "dev": true, "license": "MIT", "dependencies": { @@ -1256,9 +1467,9 @@ } }, "node_modules/@rollup/rollup-android-arm-eabi": { - "version": "4.44.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.44.0.tgz", - "integrity": "sha512-xEiEE5oDW6tK4jXCAyliuntGR+amEMO7HLtdSshVuhFnKTYoeYMyXQK7pLouAJJj5KHdwdn87bfHAR2nSdNAUA==", + "version": "4.46.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.46.2.tgz", + "integrity": "sha512-Zj3Hl6sN34xJtMv7Anwb5Gu01yujyE/cLBDB2gnHTAHaWS1Z38L7kuSG+oAh0giZMqG060f/YBStXtMH6FvPMA==", "cpu": [ "arm" ], @@ -1270,9 +1481,9 @@ ] }, "node_modules/@rollup/rollup-android-arm64": { - "version": "4.44.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.44.0.tgz", - "integrity": "sha512-uNSk/TgvMbskcHxXYHzqwiyBlJ/lGcv8DaUfcnNwict8ba9GTTNxfn3/FAoFZYgkaXXAdrAA+SLyKplyi349Jw==", + "version": "4.46.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.46.2.tgz", + "integrity": "sha512-nTeCWY83kN64oQ5MGz3CgtPx8NSOhC5lWtsjTs+8JAJNLcP3QbLCtDDgUKQc/Ro/frpMq4SHUaHN6AMltcEoLQ==", "cpu": [ "arm64" ], @@ -1284,9 +1495,9 @@ ] }, "node_modules/@rollup/rollup-darwin-arm64": { - "version": "4.44.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.44.0.tgz", - "integrity": "sha512-VGF3wy0Eq1gcEIkSCr8Ke03CWT+Pm2yveKLaDvq51pPpZza3JX/ClxXOCmTYYq3us5MvEuNRTaeyFThCKRQhOA==", + "version": "4.46.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.46.2.tgz", + "integrity": "sha512-HV7bW2Fb/F5KPdM/9bApunQh68YVDU8sO8BvcW9OngQVN3HHHkw99wFupuUJfGR9pYLLAjcAOA6iO+evsbBaPQ==", "cpu": [ "arm64" ], @@ -1298,9 +1509,9 @@ ] }, "node_modules/@rollup/rollup-darwin-x64": { - "version": "4.44.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.44.0.tgz", - "integrity": "sha512-fBkyrDhwquRvrTxSGH/qqt3/T0w5Rg0L7ZIDypvBPc1/gzjJle6acCpZ36blwuwcKD/u6oCE/sRWlUAcxLWQbQ==", + "version": "4.46.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.46.2.tgz", + "integrity": "sha512-SSj8TlYV5nJixSsm/y3QXfhspSiLYP11zpfwp6G/YDXctf3Xkdnk4woJIF5VQe0of2OjzTt8EsxnJDCdHd2xMA==", "cpu": [ "x64" ], @@ -1312,9 +1523,9 @@ ] }, "node_modules/@rollup/rollup-freebsd-arm64": { - "version": "4.44.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-arm64/-/rollup-freebsd-arm64-4.44.0.tgz", - "integrity": "sha512-u5AZzdQJYJXByB8giQ+r4VyfZP+walV+xHWdaFx/1VxsOn6eWJhK2Vl2eElvDJFKQBo/hcYIBg/jaKS8ZmKeNQ==", + "version": "4.46.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-arm64/-/rollup-freebsd-arm64-4.46.2.tgz", + "integrity": "sha512-ZyrsG4TIT9xnOlLsSSi9w/X29tCbK1yegE49RYm3tu3wF1L/B6LVMqnEWyDB26d9Ecx9zrmXCiPmIabVuLmNSg==", "cpu": [ "arm64" ], @@ -1326,9 +1537,9 @@ ] }, "node_modules/@rollup/rollup-freebsd-x64": { - "version": "4.44.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-x64/-/rollup-freebsd-x64-4.44.0.tgz", - "integrity": "sha512-qC0kS48c/s3EtdArkimctY7h3nHicQeEUdjJzYVJYR3ct3kWSafmn6jkNCA8InbUdge6PVx6keqjk5lVGJf99g==", + "version": "4.46.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-x64/-/rollup-freebsd-x64-4.46.2.tgz", + "integrity": "sha512-pCgHFoOECwVCJ5GFq8+gR8SBKnMO+xe5UEqbemxBpCKYQddRQMgomv1104RnLSg7nNvgKy05sLsY51+OVRyiVw==", "cpu": [ "x64" ], @@ -1340,9 +1551,9 @@ ] }, "node_modules/@rollup/rollup-linux-arm-gnueabihf": { - "version": "4.44.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.44.0.tgz", - "integrity": "sha512-x+e/Z9H0RAWckn4V2OZZl6EmV0L2diuX3QB0uM1r6BvhUIv6xBPL5mrAX2E3e8N8rEHVPwFfz/ETUbV4oW9+lQ==", + "version": "4.46.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.46.2.tgz", + "integrity": "sha512-EtP8aquZ0xQg0ETFcxUbU71MZlHaw9MChwrQzatiE8U/bvi5uv/oChExXC4mWhjiqK7azGJBqU0tt5H123SzVA==", "cpu": [ "arm" ], @@ -1354,9 +1565,9 @@ ] }, "node_modules/@rollup/rollup-linux-arm-musleabihf": { - "version": "4.44.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.44.0.tgz", - "integrity": "sha512-1exwiBFf4PU/8HvI8s80icyCcnAIB86MCBdst51fwFmH5dyeoWVPVgmQPcKrMtBQ0W5pAs7jBCWuRXgEpRzSCg==", + "version": "4.46.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.46.2.tgz", + "integrity": "sha512-qO7F7U3u1nfxYRPM8HqFtLd+raev2K137dsV08q/LRKRLEc7RsiDWihUnrINdsWQxPR9jqZ8DIIZ1zJJAm5PjQ==", "cpu": [ "arm" ], @@ -1368,9 +1579,9 @@ ] }, "node_modules/@rollup/rollup-linux-arm64-gnu": { - "version": "4.44.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.44.0.tgz", - "integrity": "sha512-ZTR2mxBHb4tK4wGf9b8SYg0Y6KQPjGpR4UWwTFdnmjB4qRtoATZ5dWn3KsDwGa5Z2ZBOE7K52L36J9LueKBdOQ==", + "version": "4.46.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.46.2.tgz", + "integrity": "sha512-3dRaqLfcOXYsfvw5xMrxAk9Lb1f395gkoBYzSFcc/scgRFptRXL9DOaDpMiehf9CO8ZDRJW2z45b6fpU5nwjng==", "cpu": [ "arm64" ], @@ -1382,9 +1593,9 @@ ] }, "node_modules/@rollup/rollup-linux-arm64-musl": { - "version": "4.44.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.44.0.tgz", - "integrity": "sha512-GFWfAhVhWGd4r6UxmnKRTBwP1qmModHtd5gkraeW2G490BpFOZkFtem8yuX2NyafIP/mGpRJgTJ2PwohQkUY/Q==", + "version": "4.46.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.46.2.tgz", + "integrity": "sha512-fhHFTutA7SM+IrR6lIfiHskxmpmPTJUXpWIsBXpeEwNgZzZZSg/q4i6FU4J8qOGyJ0TR+wXBwx/L7Ho9z0+uDg==", "cpu": [ "arm64" ], @@ -1396,9 +1607,9 @@ ] }, "node_modules/@rollup/rollup-linux-loongarch64-gnu": { - "version": "4.44.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-loongarch64-gnu/-/rollup-linux-loongarch64-gnu-4.44.0.tgz", - "integrity": "sha512-xw+FTGcov/ejdusVOqKgMGW3c4+AgqrfvzWEVXcNP6zq2ue+lsYUgJ+5Rtn/OTJf7e2CbgTFvzLW2j0YAtj0Gg==", + "version": "4.46.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-loongarch64-gnu/-/rollup-linux-loongarch64-gnu-4.46.2.tgz", + "integrity": "sha512-i7wfGFXu8x4+FRqPymzjD+Hyav8l95UIZ773j7J7zRYc3Xsxy2wIn4x+llpunexXe6laaO72iEjeeGyUFmjKeA==", "cpu": [ "loong64" ], @@ -1409,10 +1620,10 @@ "linux" ] }, - "node_modules/@rollup/rollup-linux-powerpc64le-gnu": { - "version": "4.44.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-powerpc64le-gnu/-/rollup-linux-powerpc64le-gnu-4.44.0.tgz", - "integrity": "sha512-bKGibTr9IdF0zr21kMvkZT4K6NV+jjRnBoVMt2uNMG0BYWm3qOVmYnXKzx7UhwrviKnmK46IKMByMgvpdQlyJQ==", + "node_modules/@rollup/rollup-linux-ppc64-gnu": { + "version": "4.46.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-ppc64-gnu/-/rollup-linux-ppc64-gnu-4.46.2.tgz", + "integrity": "sha512-B/l0dFcHVUnqcGZWKcWBSV2PF01YUt0Rvlurci5P+neqY/yMKchGU8ullZvIv5e8Y1C6wOn+U03mrDylP5q9Yw==", "cpu": [ "ppc64" ], @@ -1424,9 +1635,9 @@ ] }, "node_modules/@rollup/rollup-linux-riscv64-gnu": { - "version": "4.44.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.44.0.tgz", - "integrity": "sha512-vV3cL48U5kDaKZtXrti12YRa7TyxgKAIDoYdqSIOMOFBXqFj2XbChHAtXquEn2+n78ciFgr4KIqEbydEGPxXgA==", + "version": "4.46.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.46.2.tgz", + "integrity": "sha512-32k4ENb5ygtkMwPMucAb8MtV8olkPT03oiTxJbgkJa7lJ7dZMr0GCFJlyvy+K8iq7F/iuOr41ZdUHaOiqyR3iQ==", "cpu": [ "riscv64" ], @@ -1438,9 +1649,9 @@ ] }, "node_modules/@rollup/rollup-linux-riscv64-musl": { - "version": "4.44.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-musl/-/rollup-linux-riscv64-musl-4.44.0.tgz", - "integrity": "sha512-TDKO8KlHJuvTEdfw5YYFBjhFts2TR0VpZsnLLSYmB7AaohJhM8ctDSdDnUGq77hUh4m/djRafw+9zQpkOanE2Q==", + "version": "4.46.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-musl/-/rollup-linux-riscv64-musl-4.46.2.tgz", + "integrity": "sha512-t5B2loThlFEauloaQkZg9gxV05BYeITLvLkWOkRXogP4qHXLkWSbSHKM9S6H1schf/0YGP/qNKtiISlxvfmmZw==", "cpu": [ "riscv64" ], @@ -1452,9 +1663,9 @@ ] }, "node_modules/@rollup/rollup-linux-s390x-gnu": { - "version": "4.44.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.44.0.tgz", - "integrity": "sha512-8541GEyktXaw4lvnGp9m84KENcxInhAt6vPWJ9RodsB/iGjHoMB2Pp5MVBCiKIRxrxzJhGCxmNzdu+oDQ7kwRA==", + "version": "4.46.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.46.2.tgz", + "integrity": "sha512-YKjekwTEKgbB7n17gmODSmJVUIvj8CX7q5442/CK80L8nqOUbMtf8b01QkG3jOqyr1rotrAnW6B/qiHwfcuWQA==", "cpu": [ "s390x" ], @@ -1466,9 +1677,9 @@ ] }, "node_modules/@rollup/rollup-linux-x64-gnu": { - "version": "4.44.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.44.0.tgz", - "integrity": "sha512-iUVJc3c0o8l9Sa/qlDL2Z9UP92UZZW1+EmQ4xfjTc1akr0iUFZNfxrXJ/R1T90h/ILm9iXEY6+iPrmYB3pXKjw==", + "version": "4.46.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.46.2.tgz", + "integrity": "sha512-Jj5a9RUoe5ra+MEyERkDKLwTXVu6s3aACP51nkfnK9wJTraCC8IMe3snOfALkrjTYd2G1ViE1hICj0fZ7ALBPA==", "cpu": [ "x64" ], @@ -1480,9 +1691,9 @@ ] }, "node_modules/@rollup/rollup-linux-x64-musl": { - "version": "4.44.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.44.0.tgz", - "integrity": "sha512-PQUobbhLTQT5yz/SPg116VJBgz+XOtXt8D1ck+sfJJhuEsMj2jSej5yTdp8CvWBSceu+WW+ibVL6dm0ptG5fcA==", + "version": "4.46.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.46.2.tgz", + "integrity": "sha512-7kX69DIrBeD7yNp4A5b81izs8BqoZkCIaxQaOpumcJ1S/kmqNFjPhDu1LHeVXv0SexfHQv5cqHsxLOjETuqDuA==", "cpu": [ "x64" ], @@ -1494,9 +1705,9 @@ ] }, "node_modules/@rollup/rollup-win32-arm64-msvc": { - "version": "4.44.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.44.0.tgz", - "integrity": "sha512-M0CpcHf8TWn+4oTxJfh7LQuTuaYeXGbk0eageVjQCKzYLsajWS/lFC94qlRqOlyC2KvRT90ZrfXULYmukeIy7w==", + "version": "4.46.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.46.2.tgz", + "integrity": "sha512-wiJWMIpeaak/jsbaq2HMh/rzZxHVW1rU6coyeNNpMwk5isiPjSTx0a4YLSlYDwBH/WBvLz+EtsNqQScZTLJy3g==", "cpu": [ "arm64" ], @@ -1508,9 +1719,9 @@ ] }, "node_modules/@rollup/rollup-win32-ia32-msvc": { - "version": "4.44.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.44.0.tgz", - "integrity": "sha512-3XJ0NQtMAXTWFW8FqZKcw3gOQwBtVWP/u8TpHP3CRPXD7Pd6s8lLdH3sHWh8vqKCyyiI8xW5ltJScQmBU9j7WA==", + "version": "4.46.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.46.2.tgz", + "integrity": "sha512-gBgaUDESVzMgWZhcyjfs9QFK16D8K6QZpwAaVNJxYDLHWayOta4ZMjGm/vsAEy3hvlS2GosVFlBlP9/Wb85DqQ==", "cpu": [ "ia32" ], @@ -1522,9 +1733,9 @@ ] }, "node_modules/@rollup/rollup-win32-x64-msvc": { - "version": "4.44.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.44.0.tgz", - "integrity": "sha512-Q2Mgwt+D8hd5FIPUuPDsvPR7Bguza6yTkJxspDGkZj7tBRn2y4KSWYuIXpftFSjBra76TbKerCV7rgFPQrn+wQ==", + "version": "4.46.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.46.2.tgz", + "integrity": "sha512-CvUo2ixeIQGtF6WvuB87XWqPQkoFAFqW+HUo/WzHwuHDvIwZCtjdWXoYCcr06iKGydiqTclC4jU/TNObC/xKZg==", "cpu": [ "x64" ], @@ -1718,9 +1929,9 @@ } }, "node_modules/@semantic-release/npm": { - "version": "12.0.1", - "resolved": "https://registry.npmjs.org/@semantic-release/npm/-/npm-12.0.1.tgz", - "integrity": "sha512-/6nntGSUGK2aTOI0rHPwY3ZjgY9FkXmEHbW9Kr+62NVOsyqpKKeP0lrCH+tphv+EsNdJNmqqwijTEnVWUMQ2Nw==", + "version": "12.0.2", + "resolved": "https://registry.npmjs.org/@semantic-release/npm/-/npm-12.0.2.tgz", + "integrity": "sha512-+M9/Lb35IgnlUO6OSJ40Ie+hUsZLuph2fqXC/qrKn0fMvUU/jiCjpoL6zEm69vzcmaZJ8yNKtMBEKHWN49WBbQ==", "dev": true, "license": "MIT", "dependencies": { @@ -1731,7 +1942,7 @@ "lodash-es": "^4.17.21", "nerf-dart": "^1.0.0", "normalize-url": "^8.0.0", - "npm": "^10.5.0", + "npm": "^10.9.3", "rc": "^1.2.8", "read-pkg": "^9.0.0", "registry-auth-token": "^5.0.0", @@ -1976,40 +2187,40 @@ } }, "node_modules/@shikijs/engine-oniguruma": { - "version": "3.7.0", - "resolved": "https://registry.npmjs.org/@shikijs/engine-oniguruma/-/engine-oniguruma-3.7.0.tgz", - "integrity": "sha512-5BxcD6LjVWsGu4xyaBC5bu8LdNgPCVBnAkWTtOCs/CZxcB22L8rcoWfv7Hh/3WooVjBZmFtyxhgvkQFedPGnFw==", + "version": "3.9.2", + "resolved": "https://registry.npmjs.org/@shikijs/engine-oniguruma/-/engine-oniguruma-3.9.2.tgz", + "integrity": "sha512-Vn/w5oyQ6TUgTVDIC/BrpXwIlfK6V6kGWDVVz2eRkF2v13YoENUvaNwxMsQU/t6oCuZKzqp9vqtEtEzKl9VegA==", "dev": true, "license": "MIT", "dependencies": { - "@shikijs/types": "3.7.0", + "@shikijs/types": "3.9.2", "@shikijs/vscode-textmate": "^10.0.2" } }, "node_modules/@shikijs/langs": { - "version": "3.7.0", - "resolved": "https://registry.npmjs.org/@shikijs/langs/-/langs-3.7.0.tgz", - "integrity": "sha512-1zYtdfXLr9xDKLTGy5kb7O0zDQsxXiIsw1iIBcNOO8Yi5/Y1qDbJ+0VsFoqTlzdmneO8Ij35g7QKF8kcLyznCQ==", + "version": "3.9.2", + "resolved": "https://registry.npmjs.org/@shikijs/langs/-/langs-3.9.2.tgz", + "integrity": "sha512-X1Q6wRRQXY7HqAuX3I8WjMscjeGjqXCg/Sve7J2GWFORXkSrXud23UECqTBIdCSNKJioFtmUGJQNKtlMMZMn0w==", "dev": true, "license": "MIT", "dependencies": { - "@shikijs/types": "3.7.0" + "@shikijs/types": "3.9.2" } }, "node_modules/@shikijs/themes": { - "version": "3.7.0", - "resolved": "https://registry.npmjs.org/@shikijs/themes/-/themes-3.7.0.tgz", - "integrity": "sha512-VJx8497iZPy5zLiiCTSIaOChIcKQwR0FebwE9S3rcN0+J/GTWwQ1v/bqhTbpbY3zybPKeO8wdammqkpXc4NVjQ==", + "version": "3.9.2", + "resolved": "https://registry.npmjs.org/@shikijs/themes/-/themes-3.9.2.tgz", + "integrity": "sha512-6z5lBPBMRfLyyEsgf6uJDHPa6NAGVzFJqH4EAZ+03+7sedYir2yJBRu2uPZOKmj43GyhVHWHvyduLDAwJQfDjA==", "dev": true, "license": "MIT", "dependencies": { - "@shikijs/types": "3.7.0" + "@shikijs/types": "3.9.2" } }, "node_modules/@shikijs/types": { - "version": "3.7.0", - "resolved": "https://registry.npmjs.org/@shikijs/types/-/types-3.7.0.tgz", - "integrity": "sha512-MGaLeaRlSWpnP0XSAum3kP3a8vtcTsITqoEPYdt3lQG3YCdQH4DnEhodkYcNMcU0uW0RffhoD1O3e0vG5eSBBg==", + "version": "3.9.2", + "resolved": "https://registry.npmjs.org/@shikijs/types/-/types-3.9.2.tgz", + "integrity": "sha512-/M5L0Uc2ljyn2jKvj4Yiah7ow/W+DJSglVafvWAJ/b8AZDeeRAdMu3c2riDzB7N42VD+jSnWxeP9AKtd4TfYVw==", "dev": true, "license": "MIT", "dependencies": { @@ -2095,6 +2306,16 @@ "@types/deep-eql": "*" } }, + "node_modules/@types/conventional-commits-parser": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/@types/conventional-commits-parser/-/conventional-commits-parser-5.0.1.tgz", + "integrity": "sha512-7uz5EHdzz2TqoMfV7ee61Egf5y6NkcO4FB/1iCCQnbeiI1F3xzv3vK5dBCXUCLQgGYS+mUeigK1iKQzvED+QnQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/node": "*" + } + }, "node_modules/@types/deep-eql": { "version": "4.0.2", "resolved": "https://registry.npmjs.org/@types/deep-eql/-/deep-eql-4.0.2.tgz", @@ -2127,13 +2348,13 @@ "license": "MIT" }, "node_modules/@types/node": { - "version": "24.0.3", - "resolved": "https://registry.npmjs.org/@types/node/-/node-24.0.3.tgz", - "integrity": "sha512-R4I/kzCYAdRLzfiCabn9hxWfbuHS573x+r0dJMkkzThEa7pbrcDWK+9zu3e7aBOouf+rQAciqPFMnxwr0aWgKg==", + "version": "24.2.0", + "resolved": "https://registry.npmjs.org/@types/node/-/node-24.2.0.tgz", + "integrity": "sha512-3xyG3pMCq3oYCNg7/ZP+E1ooTaGB4cG8JWRsqqOYQdbWNY4zbaV0Ennrd7stjiJEFZCaybcIgpTjJWHRfBSIDw==", "dev": true, "license": "MIT", "dependencies": { - "undici-types": "~7.8.0" + "undici-types": "~7.10.0" } }, "node_modules/@types/normalize-package-data": { @@ -2151,17 +2372,17 @@ "license": "MIT" }, "node_modules/@typescript-eslint/eslint-plugin": { - "version": "8.34.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-8.34.1.tgz", - "integrity": "sha512-STXcN6ebF6li4PxwNeFnqF8/2BNDvBupf2OPx2yWNzr6mKNGF7q49VM00Pz5FaomJyqvbXpY6PhO+T9w139YEQ==", + "version": "8.39.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-8.39.0.tgz", + "integrity": "sha512-bhEz6OZeUR+O/6yx9Jk6ohX6H9JSFTaiY0v9/PuKT3oGK0rn0jNplLmyFUGV+a9gfYnVNwGDwS/UkLIuXNb2Rw==", "dev": true, "license": "MIT", "dependencies": { "@eslint-community/regexpp": "^4.10.0", - "@typescript-eslint/scope-manager": "8.34.1", - "@typescript-eslint/type-utils": "8.34.1", - "@typescript-eslint/utils": "8.34.1", - "@typescript-eslint/visitor-keys": "8.34.1", + "@typescript-eslint/scope-manager": "8.39.0", + "@typescript-eslint/type-utils": "8.39.0", + "@typescript-eslint/utils": "8.39.0", + "@typescript-eslint/visitor-keys": "8.39.0", "graphemer": "^1.4.0", "ignore": "^7.0.0", "natural-compare": "^1.4.0", @@ -2175,9 +2396,9 @@ "url": "https://opencollective.com/typescript-eslint" }, "peerDependencies": { - "@typescript-eslint/parser": "^8.34.1", + "@typescript-eslint/parser": "^8.39.0", "eslint": "^8.57.0 || ^9.0.0", - "typescript": ">=4.8.4 <5.9.0" + "typescript": ">=4.8.4 <6.0.0" } }, "node_modules/@typescript-eslint/eslint-plugin/node_modules/ignore": { @@ -2191,16 +2412,16 @@ } }, "node_modules/@typescript-eslint/parser": { - "version": "8.34.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-8.34.1.tgz", - "integrity": "sha512-4O3idHxhyzjClSMJ0a29AcoK0+YwnEqzI6oz3vlRf3xw0zbzt15MzXwItOlnr5nIth6zlY2RENLsOPvhyrKAQA==", + "version": "8.39.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-8.39.0.tgz", + "integrity": "sha512-g3WpVQHngx0aLXn6kfIYCZxM6rRJlWzEkVpqEFLT3SgEDsp9cpCbxxgwnE504q4H+ruSDh/VGS6nqZIDynP+vg==", "dev": true, "license": "MIT", "dependencies": { - "@typescript-eslint/scope-manager": "8.34.1", - "@typescript-eslint/types": "8.34.1", - "@typescript-eslint/typescript-estree": "8.34.1", - "@typescript-eslint/visitor-keys": "8.34.1", + "@typescript-eslint/scope-manager": "8.39.0", + "@typescript-eslint/types": "8.39.0", + "@typescript-eslint/typescript-estree": "8.39.0", + "@typescript-eslint/visitor-keys": "8.39.0", "debug": "^4.3.4" }, "engines": { @@ -2212,18 +2433,18 @@ }, "peerDependencies": { "eslint": "^8.57.0 || ^9.0.0", - "typescript": ">=4.8.4 <5.9.0" + "typescript": ">=4.8.4 <6.0.0" } }, "node_modules/@typescript-eslint/project-service": { - "version": "8.34.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/project-service/-/project-service-8.34.1.tgz", - "integrity": "sha512-nuHlOmFZfuRwLJKDGQOVc0xnQrAmuq1Mj/ISou5044y1ajGNp2BNliIqp7F2LPQ5sForz8lempMFCovfeS1XoA==", + "version": "8.39.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/project-service/-/project-service-8.39.0.tgz", + "integrity": "sha512-CTzJqaSq30V/Z2Og9jogzZt8lJRR5TKlAdXmWgdu4hgcC9Kww5flQ+xFvMxIBWVNdxJO7OifgdOK4PokMIWPew==", "dev": true, "license": "MIT", "dependencies": { - "@typescript-eslint/tsconfig-utils": "^8.34.1", - "@typescript-eslint/types": "^8.34.1", + "@typescript-eslint/tsconfig-utils": "^8.39.0", + "@typescript-eslint/types": "^8.39.0", "debug": "^4.3.4" }, "engines": { @@ -2234,18 +2455,18 @@ "url": "https://opencollective.com/typescript-eslint" }, "peerDependencies": { - "typescript": ">=4.8.4 <5.9.0" + "typescript": ">=4.8.4 <6.0.0" } }, "node_modules/@typescript-eslint/scope-manager": { - "version": "8.34.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-8.34.1.tgz", - "integrity": "sha512-beu6o6QY4hJAgL1E8RaXNC071G4Kso2MGmJskCFQhRhg8VOH/FDbC8soP8NHN7e/Hdphwp8G8cE6OBzC8o41ZA==", + "version": "8.39.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-8.39.0.tgz", + "integrity": "sha512-8QOzff9UKxOh6npZQ/4FQu4mjdOCGSdO3p44ww0hk8Vu+IGbg0tB/H1LcTARRDzGCC8pDGbh2rissBuuoPgH8A==", "dev": true, "license": "MIT", "dependencies": { - "@typescript-eslint/types": "8.34.1", - "@typescript-eslint/visitor-keys": "8.34.1" + "@typescript-eslint/types": "8.39.0", + "@typescript-eslint/visitor-keys": "8.39.0" }, "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" @@ -2256,9 +2477,9 @@ } }, "node_modules/@typescript-eslint/tsconfig-utils": { - "version": "8.34.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/tsconfig-utils/-/tsconfig-utils-8.34.1.tgz", - "integrity": "sha512-K4Sjdo4/xF9NEeA2khOb7Y5nY6NSXBnod87uniVYW9kHP+hNlDV8trUSFeynA2uxWam4gIWgWoygPrv9VMWrYg==", + "version": "8.39.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/tsconfig-utils/-/tsconfig-utils-8.39.0.tgz", + "integrity": "sha512-Fd3/QjmFV2sKmvv3Mrj8r6N8CryYiCS8Wdb/6/rgOXAWGcFuc+VkQuG28uk/4kVNVZBQuuDHEDUpo/pQ32zsIQ==", "dev": true, "license": "MIT", "engines": { @@ -2269,18 +2490,19 @@ "url": "https://opencollective.com/typescript-eslint" }, "peerDependencies": { - "typescript": ">=4.8.4 <5.9.0" + "typescript": ">=4.8.4 <6.0.0" } }, "node_modules/@typescript-eslint/type-utils": { - "version": "8.34.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-8.34.1.tgz", - "integrity": "sha512-Tv7tCCr6e5m8hP4+xFugcrwTOucB8lshffJ6zf1mF1TbU67R+ntCc6DzLNKM+s/uzDyv8gLq7tufaAhIBYeV8g==", + "version": "8.39.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-8.39.0.tgz", + "integrity": "sha512-6B3z0c1DXVT2vYA9+z9axjtc09rqKUPRmijD5m9iv8iQpHBRYRMBcgxSiKTZKm6FwWw1/cI4v6em35OsKCiN5Q==", "dev": true, "license": "MIT", "dependencies": { - "@typescript-eslint/typescript-estree": "8.34.1", - "@typescript-eslint/utils": "8.34.1", + "@typescript-eslint/types": "8.39.0", + "@typescript-eslint/typescript-estree": "8.39.0", + "@typescript-eslint/utils": "8.39.0", "debug": "^4.3.4", "ts-api-utils": "^2.1.0" }, @@ -2293,13 +2515,13 @@ }, "peerDependencies": { "eslint": "^8.57.0 || ^9.0.0", - "typescript": ">=4.8.4 <5.9.0" + "typescript": ">=4.8.4 <6.0.0" } }, "node_modules/@typescript-eslint/types": { - "version": "8.34.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.34.1.tgz", - "integrity": "sha512-rjLVbmE7HR18kDsjNIZQHxmv9RZwlgzavryL5Lnj2ujIRTeXlKtILHgRNmQ3j4daw7zd+mQgy+uyt6Zo6I0IGA==", + "version": "8.39.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.39.0.tgz", + "integrity": "sha512-ArDdaOllnCj3yn/lzKn9s0pBQYmmyme/v1HbGIGB0GB/knFI3fWMHloC+oYTJW46tVbYnGKTMDK4ah1sC2v0Kg==", "dev": true, "license": "MIT", "engines": { @@ -2311,16 +2533,16 @@ } }, "node_modules/@typescript-eslint/typescript-estree": { - "version": "8.34.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-8.34.1.tgz", - "integrity": "sha512-rjCNqqYPuMUF5ODD+hWBNmOitjBWghkGKJg6hiCHzUvXRy6rK22Jd3rwbP2Xi+R7oYVvIKhokHVhH41BxPV5mA==", + "version": "8.39.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-8.39.0.tgz", + "integrity": "sha512-ndWdiflRMvfIgQRpckQQLiB5qAKQ7w++V4LlCHwp62eym1HLB/kw7D9f2e8ytONls/jt89TEasgvb+VwnRprsw==", "dev": true, "license": "MIT", "dependencies": { - "@typescript-eslint/project-service": "8.34.1", - "@typescript-eslint/tsconfig-utils": "8.34.1", - "@typescript-eslint/types": "8.34.1", - "@typescript-eslint/visitor-keys": "8.34.1", + "@typescript-eslint/project-service": "8.39.0", + "@typescript-eslint/tsconfig-utils": "8.39.0", + "@typescript-eslint/types": "8.39.0", + "@typescript-eslint/visitor-keys": "8.39.0", "debug": "^4.3.4", "fast-glob": "^3.3.2", "is-glob": "^4.0.3", @@ -2336,7 +2558,7 @@ "url": "https://opencollective.com/typescript-eslint" }, "peerDependencies": { - "typescript": ">=4.8.4 <5.9.0" + "typescript": ">=4.8.4 <6.0.0" } }, "node_modules/@typescript-eslint/typescript-estree/node_modules/minimatch": { @@ -2356,16 +2578,16 @@ } }, "node_modules/@typescript-eslint/utils": { - "version": "8.34.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-8.34.1.tgz", - "integrity": "sha512-mqOwUdZ3KjtGk7xJJnLbHxTuWVn3GO2WZZuM+Slhkun4+qthLdXx32C8xIXbO1kfCECb3jIs3eoxK3eryk7aoQ==", + "version": "8.39.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-8.39.0.tgz", + "integrity": "sha512-4GVSvNA0Vx1Ktwvf4sFE+exxJ3QGUorQG1/A5mRfRNZtkBT2xrA/BCO2H0eALx/PnvCS6/vmYwRdDA41EoffkQ==", "dev": true, "license": "MIT", "dependencies": { "@eslint-community/eslint-utils": "^4.7.0", - "@typescript-eslint/scope-manager": "8.34.1", - "@typescript-eslint/types": "8.34.1", - "@typescript-eslint/typescript-estree": "8.34.1" + "@typescript-eslint/scope-manager": "8.39.0", + "@typescript-eslint/types": "8.39.0", + "@typescript-eslint/typescript-estree": "8.39.0" }, "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" @@ -2376,17 +2598,17 @@ }, "peerDependencies": { "eslint": "^8.57.0 || ^9.0.0", - "typescript": ">=4.8.4 <5.9.0" + "typescript": ">=4.8.4 <6.0.0" } }, "node_modules/@typescript-eslint/visitor-keys": { - "version": "8.34.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.34.1.tgz", - "integrity": "sha512-xoh5rJ+tgsRKoXnkBPFRLZ7rjKM0AfVbC68UZ/ECXoDbfggb9RbEySN359acY1vS3qZ0jVTVWzbtfapwm5ztxw==", + "version": "8.39.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.39.0.tgz", + "integrity": "sha512-ldgiJ+VAhQCfIjeOgu8Kj5nSxds0ktPOSO9p4+0VDH2R2pLvQraaM5Oen2d7NxzMCm+Sn/vJT+mv2H5u6b/3fA==", "dev": true, "license": "MIT", "dependencies": { - "@typescript-eslint/types": "8.34.1", + "@typescript-eslint/types": "8.39.0", "eslint-visitor-keys": "^4.2.1" }, "engines": { @@ -2723,13 +2945,13 @@ } }, "node_modules/ast-v8-to-istanbul": { - "version": "0.3.3", - "resolved": "https://registry.npmjs.org/ast-v8-to-istanbul/-/ast-v8-to-istanbul-0.3.3.tgz", - "integrity": "sha512-MuXMrSLVVoA6sYN/6Hke18vMzrT4TZNbZIj/hvh0fnYFpO+/kFXcLIaiPwXXWaQUPg4yJD8fj+lfJ7/1EBconw==", + "version": "0.3.4", + "resolved": "https://registry.npmjs.org/ast-v8-to-istanbul/-/ast-v8-to-istanbul-0.3.4.tgz", + "integrity": "sha512-cxrAnZNLBnQwBPByK4CeDaw5sWZtMilJE/Q3iDA0aamgaIVNDF9T6K2/8DfYDZEejZ2jNnDrG9m8MY72HFd0KA==", "dev": true, "license": "MIT", "dependencies": { - "@jridgewell/trace-mapping": "^0.3.25", + "@jridgewell/trace-mapping": "^0.3.29", "estree-walker": "^3.0.3", "js-tokens": "^9.0.1" } @@ -2751,6 +2973,16 @@ "dev": true, "license": "MIT" }, + "node_modules/at-least-node": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/at-least-node/-/at-least-node-1.0.0.tgz", + "integrity": "sha512-+q/t7Ekv1EDY2l6Gda6LLiX14rU9TV20Wa3ofeQmwPFZbOMo9DXrLbOjFaaclkXKWidIaopwAObQDqwWtGUjqg==", + "dev": true, + "license": "ISC", + "engines": { + "node": ">= 4.0.0" + } + }, "node_modules/balanced-match": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", @@ -2758,6 +2990,27 @@ "dev": true, "license": "MIT" }, + "node_modules/base64-js": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz", + "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "MIT" + }, "node_modules/before-after-hook": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/before-after-hook/-/before-after-hook-4.0.0.tgz", @@ -2775,6 +3028,33 @@ "file-uri-to-path": "1.0.0" } }, + "node_modules/bl": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/bl/-/bl-4.1.0.tgz", + "integrity": "sha512-1W07cM9gS6DcLperZfFSj+bWLtaPGSOHWhPiGzXmvVJbRLdG82sH/Kn8EtW1VqWVA54AKf2h5k5BbnIbwF3h6w==", + "dev": true, + "license": "MIT", + "dependencies": { + "buffer": "^5.5.0", + "inherits": "^2.0.4", + "readable-stream": "^3.4.0" + } + }, + "node_modules/bl/node_modules/readable-stream": { + "version": "3.6.2", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz", + "integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==", + "dev": true, + "license": "MIT", + "dependencies": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + }, + "engines": { + "node": ">= 6" + } + }, "node_modules/bottleneck": { "version": "2.19.5", "resolved": "https://registry.npmjs.org/bottleneck/-/bottleneck-2.19.5.tgz", @@ -2805,6 +3085,31 @@ "node": ">=8" } }, + "node_modules/buffer": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.7.1.tgz", + "integrity": "sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "MIT", + "dependencies": { + "base64-js": "^1.3.1", + "ieee754": "^1.1.13" + } + }, "node_modules/cac": { "version": "6.7.14", "resolved": "https://registry.npmjs.org/cac/-/cac-6.7.14.tgz", @@ -2815,6 +3120,16 @@ "node": ">=8" } }, + "node_modules/cachedir": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/cachedir/-/cachedir-2.3.0.tgz", + "integrity": "sha512-A+Fezp4zxnit6FanDmv9EqXNAi3vt9DWp51/71UEhXukb7QUuvtv9344h91dyAxuTLoSYJFU299qzR3tzwPAhw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, "node_modules/callsites": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", @@ -2826,9 +3141,9 @@ } }, "node_modules/chai": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/chai/-/chai-5.2.0.tgz", - "integrity": "sha512-mCuXncKXk5iCLhfhwTc0izo0gtEmpz5CtG2y8GiOINBlMVS6v8TMRc5TaLWKS6692m9+dVVfzgeVxR5UxWHTYw==", + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/chai/-/chai-5.2.1.tgz", + "integrity": "sha512-5nFxhUrX0PqtyogoYOA8IPswy5sZFTOsBFl/9bNsmDLgsxYTzSZQJDPppDnZPTQbzSEm0hqGjWPzRemQCYbD6A==", "dev": true, "license": "MIT", "dependencies": { @@ -2839,7 +3154,7 @@ "pathval": "^2.0.0" }, "engines": { - "node": ">=12" + "node": ">=18" } }, "node_modules/chalk": { @@ -2885,6 +3200,13 @@ "node": ">=10" } }, + "node_modules/chardet": { + "version": "0.7.0", + "resolved": "https://registry.npmjs.org/chardet/-/chardet-0.7.0.tgz", + "integrity": "sha512-mT8iDcrh03qDGRRmoA2hmBJnxpllMR+0/0qlzjqZES6NdiWDcZkCNAk4rPFZ9Q85r27unkiNNg8ZOiwZXBHwcA==", + "dev": true, + "license": "MIT" + }, "node_modules/check-error": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/check-error/-/check-error-2.1.1.tgz", @@ -2905,6 +3227,19 @@ "node": ">=6" } }, + "node_modules/cli-cursor": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-3.1.0.tgz", + "integrity": "sha512-I/zHAwsKf9FqGoXM4WWRACob9+SNukZTd94DWF57E4toouRulbCxcUh6RKUEOQlYTHJnzkPMySvPNaaSLNfLZw==", + "dev": true, + "license": "MIT", + "dependencies": { + "restore-cursor": "^3.1.0" + }, + "engines": { + "node": ">=8" + } + }, "node_modules/cli-highlight": { "version": "2.1.11", "resolved": "https://registry.npmjs.org/cli-highlight/-/cli-highlight-2.1.11.tgz", @@ -3047,6 +3382,19 @@ "node": ">=10" } }, + "node_modules/cli-spinners": { + "version": "2.9.2", + "resolved": "https://registry.npmjs.org/cli-spinners/-/cli-spinners-2.9.2.tgz", + "integrity": "sha512-ywqV+5MmyL4E7ybXgKys4DugZbX0FC6LnwrhjuykIjnK9k8OQacQ7axGKnjDXWNhns0xot3bZI5h55H8yo9cJg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/cli-table3": { "version": "0.6.5", "resolved": "https://registry.npmjs.org/cli-table3/-/cli-table3-0.6.5.tgz", @@ -3108,22 +3456,74 @@ "node": ">=8" } }, - "node_modules/cliui": { - "version": "8.0.1", - "resolved": "https://registry.npmjs.org/cliui/-/cliui-8.0.1.tgz", - "integrity": "sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==", + "node_modules/cli-truncate": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/cli-truncate/-/cli-truncate-4.0.0.tgz", + "integrity": "sha512-nPdaFdQ0h/GEigbPClz11D0v/ZJEwxmeVZGeMo3Z5StPtUTkA9o1lD6QwoirYiSDzbcwn2XcjwmCp68W1IS4TA==", "dev": true, - "license": "ISC", + "license": "MIT", "dependencies": { - "string-width": "^4.2.0", - "strip-ansi": "^6.0.1", - "wrap-ansi": "^7.0.0" + "slice-ansi": "^5.0.0", + "string-width": "^7.0.0" }, "engines": { - "node": ">=12" + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/cliui/node_modules/ansi-regex": { + "node_modules/cli-truncate/node_modules/emoji-regex": { + "version": "10.4.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-10.4.0.tgz", + "integrity": "sha512-EC+0oUMY1Rqm4O6LLrgjtYDvcVYTy7chDnM4Q7030tP4Kwj3u/pR6gP9ygnp2CJMK5Gq+9Q2oqmrFJAz01DXjw==", + "dev": true, + "license": "MIT" + }, + "node_modules/cli-truncate/node_modules/string-width": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-7.2.0.tgz", + "integrity": "sha512-tsaTIkKW9b4N+AEj+SVA+WhJzV7/zMhcSu78mLKWSk7cXMOSHsBKFWUs0fWwq8QyK3MgJBQRX6Gbi4kYbdvGkQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "emoji-regex": "^10.3.0", + "get-east-asian-width": "^1.0.0", + "strip-ansi": "^7.1.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/cli-width": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/cli-width/-/cli-width-4.1.0.tgz", + "integrity": "sha512-ouuZd4/dm2Sw5Gmqy6bGyNNNe1qt9RpmxveLSO7KcgsTnU7RXfsw+/bukWGo1abgBiMAic068rclZsO4IWmmxQ==", + "dev": true, + "license": "ISC", + "engines": { + "node": ">= 12" + } + }, + "node_modules/cliui": { + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-8.0.1.tgz", + "integrity": "sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==", + "dev": true, + "license": "ISC", + "dependencies": { + "string-width": "^4.2.0", + "strip-ansi": "^6.0.1", + "wrap-ansi": "^7.0.0" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/cliui/node_modules/ansi-regex": { "version": "5.0.1", "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", @@ -3202,6 +3602,16 @@ "url": "https://github.com/chalk/wrap-ansi?sponsor=1" } }, + "node_modules/clone": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/clone/-/clone-1.0.4.tgz", + "integrity": "sha512-JQHZ2QMW6l3aH/j6xCqQThY/9OH4D/9ls34cgkUBiEeocRTU04tHfKPBsUK1PqZCUQM7GiA0IIXJSuXHI64Kbg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.8" + } + }, "node_modules/color-convert": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", @@ -3222,6 +3632,300 @@ "dev": true, "license": "MIT" }, + "node_modules/colorette": { + "version": "2.0.20", + "resolved": "https://registry.npmjs.org/colorette/-/colorette-2.0.20.tgz", + "integrity": "sha512-IfEDxwoWIjkeXL1eXcDiow4UbKjhLdq6/EuSVR9GMN7KVH3r9gQ83e73hsz1Nd1T3ijd5xv1wcWRYO+D6kCI2w==", + "dev": true, + "license": "MIT" + }, + "node_modules/commander": { + "version": "14.0.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-14.0.0.tgz", + "integrity": "sha512-2uM9rYjPvyq39NwLRqaiLtWHyDC1FvryJDa2ATTVims5YAS4PupsEQsDvP14FqhFr0P49CYDugi59xaxJlTXRA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=20" + } + }, + "node_modules/commitizen": { + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/commitizen/-/commitizen-4.3.1.tgz", + "integrity": "sha512-gwAPAVTy/j5YcOOebcCRIijn+mSjWJC+IYKivTu6aG8Ei/scoXgfsMRnuAk6b0GRste2J4NGxVdMN3ZpfNaVaw==", + "dev": true, + "license": "MIT", + "dependencies": { + "cachedir": "2.3.0", + "cz-conventional-changelog": "3.3.0", + "dedent": "0.7.0", + "detect-indent": "6.1.0", + "find-node-modules": "^2.1.2", + "find-root": "1.1.0", + "fs-extra": "9.1.0", + "glob": "7.2.3", + "inquirer": "8.2.5", + "is-utf8": "^0.2.1", + "lodash": "4.17.21", + "minimist": "1.2.7", + "strip-bom": "4.0.0", + "strip-json-comments": "3.1.1" + }, + "bin": { + "commitizen": "bin/commitizen", + "cz": "bin/git-cz", + "git-cz": "bin/git-cz" + }, + "engines": { + "node": ">= 12" + } + }, + "node_modules/commitizen/node_modules/ansi-escapes": { + "version": "4.3.2", + "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-4.3.2.tgz", + "integrity": "sha512-gKXj5ALrKWQLsYG9jlTRmR/xKluxHV+Z9QEwNIgCfM1/uwPMCuzVVnh5mwTd+OuBZcwSIMbqssNWRm1lE51QaQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "type-fest": "^0.21.3" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/commitizen/node_modules/ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/commitizen/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "license": "MIT", + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/commitizen/node_modules/cli-width": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/cli-width/-/cli-width-3.0.0.tgz", + "integrity": "sha512-FxqpkPPwu1HjuN93Omfm4h8uIanXofW0RxVEW3k5RKx+mJJYSthzNhp32Kzxxy3YAEZ/Dc/EWN1vZRY0+kOhbw==", + "dev": true, + "license": "ISC", + "engines": { + "node": ">= 10" + } + }, + "node_modules/commitizen/node_modules/emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "dev": true, + "license": "MIT" + }, + "node_modules/commitizen/node_modules/escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/commitizen/node_modules/figures": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/figures/-/figures-3.2.0.tgz", + "integrity": "sha512-yaduQFRKLXYOGgEn6AZau90j3ggSOyiqXU0F9JZfeXYhNa+Jk4X+s45A2zg5jns87GAFa34BBm2kXw4XpNcbdg==", + "dev": true, + "license": "MIT", + "dependencies": { + "escape-string-regexp": "^1.0.5" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/commitizen/node_modules/fs-extra": { + "version": "9.1.0", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-9.1.0.tgz", + "integrity": "sha512-hcg3ZmepS30/7BSFqRvoo3DOMQu7IjqxO5nCDt+zM9XWjb33Wg7ziNT+Qvqbuc3+gWpzO02JubVyk2G4Zvo1OQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "at-least-node": "^1.0.0", + "graceful-fs": "^4.2.0", + "jsonfile": "^6.0.1", + "universalify": "^2.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/commitizen/node_modules/glob": { + "version": "7.2.3", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", + "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", + "deprecated": "Glob versions prior to v9 are no longer supported", + "dev": true, + "license": "ISC", + "dependencies": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.1.1", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + }, + "engines": { + "node": "*" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/commitizen/node_modules/inquirer": { + "version": "8.2.5", + "resolved": "https://registry.npmjs.org/inquirer/-/inquirer-8.2.5.tgz", + "integrity": "sha512-QAgPDQMEgrDssk1XiwwHoOGYF9BAbUcc1+j+FhEvaOt8/cKRqyLn0U5qA6F74fGhTMGxf92pOvPBeh29jQJDTQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-escapes": "^4.2.1", + "chalk": "^4.1.1", + "cli-cursor": "^3.1.0", + "cli-width": "^3.0.0", + "external-editor": "^3.0.3", + "figures": "^3.0.0", + "lodash": "^4.17.21", + "mute-stream": "0.0.8", + "ora": "^5.4.1", + "run-async": "^2.4.0", + "rxjs": "^7.5.5", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0", + "through": "^2.3.6", + "wrap-ansi": "^7.0.0" + }, + "engines": { + "node": ">=12.0.0" + } + }, + "node_modules/commitizen/node_modules/minimist": { + "version": "1.2.7", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.7.tgz", + "integrity": "sha512-bzfL1YUZsP41gmu/qjrEk0Q6i2ix/cVeAhbCbqH9u3zYutS1cLg00qhrD0M2MVdCcx4Sc0UpP2eBWo9rotpq6g==", + "dev": true, + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/commitizen/node_modules/mute-stream": { + "version": "0.0.8", + "resolved": "https://registry.npmjs.org/mute-stream/-/mute-stream-0.0.8.tgz", + "integrity": "sha512-nnbWWOkoWyUsTjKrhgD0dcz22mdkSnpYqbEjIm2nhwhuxlSkpywJmBo8h0ZqJdkp73mb90SssHkN4rsRaBAfAA==", + "dev": true, + "license": "ISC" + }, + "node_modules/commitizen/node_modules/run-async": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/run-async/-/run-async-2.4.1.tgz", + "integrity": "sha512-tvVnVv01b8c1RrA6Ep7JkStj85Guv/YrMcwqYQnwjsAS2cTmmPGBBjAjpCW7RrSodNSoE2/qg9O4bceNvUuDgQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.12.0" + } + }, + "node_modules/commitizen/node_modules/string-width": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "dev": true, + "license": "MIT", + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/commitizen/node_modules/strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/commitizen/node_modules/strip-bom": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-4.0.0.tgz", + "integrity": "sha512-3xurFv5tEgii33Zi8Jtp55wEIILR9eh34FAW00PZf+JnSsTmV/ioewSgQl97JHvgjoRGwPShsWm+IdrxB35d0w==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/commitizen/node_modules/type-fest": { + "version": "0.21.3", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.21.3.tgz", + "integrity": "sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w==", + "dev": true, + "license": "(MIT OR CC0-1.0)", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/commitizen/node_modules/wrap-ansi": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", + "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + } + }, "node_modules/compare-func": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/compare-func/-/compare-func-2.0.0.tgz", @@ -3283,6 +3987,13 @@ "node": ">=18" } }, + "node_modules/conventional-commit-types": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/conventional-commit-types/-/conventional-commit-types-3.0.0.tgz", + "integrity": "sha512-SmmCYnOniSsAa9GqWOeLqc179lfr5TRu5b4QFDkbsrJ5TZjPJx85wtOr3zn+1dbeNiXDKGPbZ72IKbPhLXh/Lg==", + "dev": true, + "license": "ISC" + }, "node_modules/conventional-commits-filter": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/conventional-commits-filter/-/conventional-commits-filter-5.0.0.tgz", @@ -3356,6 +4067,24 @@ } } }, + "node_modules/cosmiconfig-typescript-loader": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/cosmiconfig-typescript-loader/-/cosmiconfig-typescript-loader-6.1.0.tgz", + "integrity": "sha512-tJ1w35ZRUiM5FeTzT7DtYWAFFv37ZLqSRkGi2oeCK1gPhvaWjkAtfXvLmvE1pRfxxp9aQo6ba/Pvg1dKj05D4g==", + "dev": true, + "license": "MIT", + "dependencies": { + "jiti": "^2.4.1" + }, + "engines": { + "node": ">=v18" + }, + "peerDependencies": { + "@types/node": "*", + "cosmiconfig": ">=9", + "typescript": ">=5" + } + }, "node_modules/cosmiconfig/node_modules/parse-json": { "version": "5.2.0", "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.2.0.tgz", @@ -3419,6 +4148,105 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/cz-conventional-changelog": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/cz-conventional-changelog/-/cz-conventional-changelog-3.3.0.tgz", + "integrity": "sha512-U466fIzU5U22eES5lTNiNbZ+d8dfcHcssH4o7QsdWaCcRs/feIPCxKYSWkYBNs5mny7MvEfwpTLWjvbm94hecw==", + "dev": true, + "license": "MIT", + "dependencies": { + "chalk": "^2.4.1", + "commitizen": "^4.0.3", + "conventional-commit-types": "^3.0.0", + "lodash.map": "^4.5.1", + "longest": "^2.0.1", + "word-wrap": "^1.0.3" + }, + "engines": { + "node": ">= 10" + }, + "optionalDependencies": { + "@commitlint/load": ">6.1.1" + } + }, + "node_modules/cz-conventional-changelog/node_modules/ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "dev": true, + "license": "MIT", + "dependencies": { + "color-convert": "^1.9.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/cz-conventional-changelog/node_modules/chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/cz-conventional-changelog/node_modules/color-convert": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", + "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "dev": true, + "license": "MIT", + "dependencies": { + "color-name": "1.1.3" + } + }, + "node_modules/cz-conventional-changelog/node_modules/color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==", + "dev": true, + "license": "MIT" + }, + "node_modules/cz-conventional-changelog/node_modules/escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/cz-conventional-changelog/node_modules/has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/cz-conventional-changelog/node_modules/supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "dev": true, + "license": "MIT", + "dependencies": { + "has-flag": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, "node_modules/debug": { "version": "4.4.1", "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.1.tgz", @@ -3437,6 +4265,13 @@ } } }, + "node_modules/dedent": { + "version": "0.7.0", + "resolved": "https://registry.npmjs.org/dedent/-/dedent-0.7.0.tgz", + "integrity": "sha512-Q6fKUPqnAHAyhiUgFU7BUzLiv0kd8saH9al7tnu5Q/okj6dnupxyTgFIBjVzJATdfIAm9NAsvXNzjaKa+bxVyA==", + "dev": true, + "license": "MIT" + }, "node_modules/deep-eql": { "version": "5.0.2", "resolved": "https://registry.npmjs.org/deep-eql/-/deep-eql-5.0.2.tgz", @@ -3464,6 +4299,39 @@ "dev": true, "license": "MIT" }, + "node_modules/defaults": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/defaults/-/defaults-1.0.4.tgz", + "integrity": "sha512-eFuaLoy/Rxalv2kr+lqMlUnrDWV+3j4pljOIJgLIhI058IQfWJ7vXhyEIHu+HtC738klGALYxOKDO0bQP3tg8A==", + "dev": true, + "license": "MIT", + "dependencies": { + "clone": "^1.0.2" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/detect-file": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/detect-file/-/detect-file-1.0.0.tgz", + "integrity": "sha512-DtCOLG98P007x7wiiOmfI0fi3eIKyWiLTGJ2MDnVi/E04lWGbf+JzrRHMm0rgIIZJGtHpKpbVgLWHrv8xXpc3Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/detect-indent": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/detect-indent/-/detect-indent-6.1.0.tgz", + "integrity": "sha512-reYkTUJAZb9gUuZ2RvVCNhVHdg62RHnJ7WJl8ftMi4diZ6NWlciOzQN88pUhSELEwflJht4oQDv0F0BMlwaYtA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, "node_modules/dir-glob": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz", @@ -3720,9 +4588,9 @@ "license": "MIT" }, "node_modules/esbuild": { - "version": "0.25.5", - "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.25.5.tgz", - "integrity": "sha512-P8OtKZRv/5J5hhz0cUAdu/cLuPIKXpQl1R9pZtvmHWQvrAUVd0UNIPT4IB4W3rNOqVO0rlqHmCIbSwxh/c9yUQ==", + "version": "0.25.8", + "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.25.8.tgz", + "integrity": "sha512-vVC0USHGtMi8+R4Kz8rt6JhEWLxsv9Rnu/lGYbPR8u47B+DCBksq9JarW0zOO7bs37hyOK1l2/oqtbciutL5+Q==", "dev": true, "hasInstallScript": true, "license": "MIT", @@ -3733,31 +4601,32 @@ "node": ">=18" }, "optionalDependencies": { - "@esbuild/aix-ppc64": "0.25.5", - "@esbuild/android-arm": "0.25.5", - "@esbuild/android-arm64": "0.25.5", - "@esbuild/android-x64": "0.25.5", - "@esbuild/darwin-arm64": "0.25.5", - "@esbuild/darwin-x64": "0.25.5", - "@esbuild/freebsd-arm64": "0.25.5", - "@esbuild/freebsd-x64": "0.25.5", - "@esbuild/linux-arm": "0.25.5", - "@esbuild/linux-arm64": "0.25.5", - "@esbuild/linux-ia32": "0.25.5", - "@esbuild/linux-loong64": "0.25.5", - "@esbuild/linux-mips64el": "0.25.5", - "@esbuild/linux-ppc64": "0.25.5", - "@esbuild/linux-riscv64": "0.25.5", - "@esbuild/linux-s390x": "0.25.5", - "@esbuild/linux-x64": "0.25.5", - "@esbuild/netbsd-arm64": "0.25.5", - "@esbuild/netbsd-x64": "0.25.5", - "@esbuild/openbsd-arm64": "0.25.5", - "@esbuild/openbsd-x64": "0.25.5", - "@esbuild/sunos-x64": "0.25.5", - "@esbuild/win32-arm64": "0.25.5", - "@esbuild/win32-ia32": "0.25.5", - "@esbuild/win32-x64": "0.25.5" + "@esbuild/aix-ppc64": "0.25.8", + "@esbuild/android-arm": "0.25.8", + "@esbuild/android-arm64": "0.25.8", + "@esbuild/android-x64": "0.25.8", + "@esbuild/darwin-arm64": "0.25.8", + "@esbuild/darwin-x64": "0.25.8", + "@esbuild/freebsd-arm64": "0.25.8", + "@esbuild/freebsd-x64": "0.25.8", + "@esbuild/linux-arm": "0.25.8", + "@esbuild/linux-arm64": "0.25.8", + "@esbuild/linux-ia32": "0.25.8", + "@esbuild/linux-loong64": "0.25.8", + "@esbuild/linux-mips64el": "0.25.8", + "@esbuild/linux-ppc64": "0.25.8", + "@esbuild/linux-riscv64": "0.25.8", + "@esbuild/linux-s390x": "0.25.8", + "@esbuild/linux-x64": "0.25.8", + "@esbuild/netbsd-arm64": "0.25.8", + "@esbuild/netbsd-x64": "0.25.8", + "@esbuild/openbsd-arm64": "0.25.8", + "@esbuild/openbsd-x64": "0.25.8", + "@esbuild/openharmony-arm64": "0.25.8", + "@esbuild/sunos-x64": "0.25.8", + "@esbuild/win32-arm64": "0.25.8", + "@esbuild/win32-ia32": "0.25.8", + "@esbuild/win32-x64": "0.25.8" } }, "node_modules/escalade": { @@ -3784,20 +4653,20 @@ } }, "node_modules/eslint": { - "version": "9.29.0", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-9.29.0.tgz", - "integrity": "sha512-GsGizj2Y1rCWDu6XoEekL3RLilp0voSePurjZIkxL3wlm5o5EC9VpgaP7lrCvjnkuLvzFBQWB3vWB3K5KQTveQ==", + "version": "9.32.0", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-9.32.0.tgz", + "integrity": "sha512-LSehfdpgMeWcTZkWZVIJl+tkZ2nuSkyyB9C27MZqFWXuph7DvaowgcTvKqxvpLW1JZIk8PN7hFY3Rj9LQ7m7lg==", "dev": true, "license": "MIT", "dependencies": { "@eslint-community/eslint-utils": "^4.2.0", "@eslint-community/regexpp": "^4.12.1", - "@eslint/config-array": "^0.20.1", - "@eslint/config-helpers": "^0.2.1", - "@eslint/core": "^0.14.0", + "@eslint/config-array": "^0.21.0", + "@eslint/config-helpers": "^0.3.0", + "@eslint/core": "^0.15.0", "@eslint/eslintrc": "^3.3.1", - "@eslint/js": "9.29.0", - "@eslint/plugin-kit": "^0.3.1", + "@eslint/js": "9.32.0", + "@eslint/plugin-kit": "^0.3.4", "@humanfs/node": "^0.16.6", "@humanwhocodes/module-importer": "^1.0.1", "@humanwhocodes/retry": "^0.4.2", @@ -3945,6 +4814,13 @@ "node": ">=0.10.0" } }, + "node_modules/eventemitter3": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-5.0.1.tgz", + "integrity": "sha512-GWkBvjiSZK87ELrYOSESUYeVIc9mvLLf/nXalMOS5dYrgZq9o5OVkbZAVM06CVxYsCwH9BDZFPlQTlPA1j4ahA==", + "dev": true, + "license": "MIT" + }, "node_modules/execa": { "version": "5.1.1", "resolved": "https://registry.npmjs.org/execa/-/execa-5.1.1.tgz", @@ -3976,16 +4852,44 @@ "dev": true, "license": "ISC" }, + "node_modules/expand-tilde": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/expand-tilde/-/expand-tilde-2.0.2.tgz", + "integrity": "sha512-A5EmesHW6rfnZ9ysHQjPdJRni0SRar0tjtG5MNtm9n5TUvsYU8oozprtRD4AqHxcZWWlVuAmQo2nWKfN9oyjTw==", + "dev": true, + "license": "MIT", + "dependencies": { + "homedir-polyfill": "^1.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/expect-type": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/expect-type/-/expect-type-1.2.1.tgz", - "integrity": "sha512-/kP8CAwxzLVEeFrMm4kMmy4CCDlpipyA7MYLVrdJIkV0fYF0UaigQHRsxHiuY/GEea+bh4KSv3TIlgr+2UL6bw==", + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/expect-type/-/expect-type-1.2.2.tgz", + "integrity": "sha512-JhFGDVJ7tmDJItKhYgJCGLOWjuK9vPxiXoUFLwLDc99NlmklilbiQJwoctZtt13+xMw91MCk/REan6MWHqDjyA==", "dev": true, "license": "Apache-2.0", "engines": { "node": ">=12.0.0" } }, + "node_modules/external-editor": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/external-editor/-/external-editor-3.1.0.tgz", + "integrity": "sha512-hMQ4CX1p1izmuLYyZqLMO/qGNw10wSv9QDCPfzXfyFrOaCSSoRfqE1Kf1s5an66J5JZC62NewG+mK49jOCtQew==", + "dev": true, + "license": "MIT", + "dependencies": { + "chardet": "^0.7.0", + "iconv-lite": "^0.4.24", + "tmp": "^0.0.33" + }, + "engines": { + "node": ">=4" + } + }, "node_modules/fast-content-type-parse": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/fast-content-type-parse/-/fast-content-type-parse-3.0.0.tgz", @@ -4054,6 +4958,23 @@ "dev": true, "license": "MIT" }, + "node_modules/fast-uri": { + "version": "3.0.6", + "resolved": "https://registry.npmjs.org/fast-uri/-/fast-uri-3.0.6.tgz", + "integrity": "sha512-Atfo14OibSv5wAp4VWNsFYE1AchQRTv9cBGWET4pZWHzYshFSS9NQI6I57rdKn9croWVMbYFbLhJ+yJvmZIIHw==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/fastify" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/fastify" + } + ], + "license": "BSD-3-Clause" + }, "node_modules/fastq": { "version": "1.19.0", "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.19.0.tgz", @@ -4135,6 +5056,24 @@ "node": ">=8" } }, + "node_modules/find-node-modules": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/find-node-modules/-/find-node-modules-2.1.3.tgz", + "integrity": "sha512-UC2I2+nx1ZuOBclWVNdcnbDR5dlrOdVb7xNjmT/lHE+LsgztWks3dG7boJ37yTS/venXw84B/mAW9uHVoC5QRg==", + "dev": true, + "license": "MIT", + "dependencies": { + "findup-sync": "^4.0.0", + "merge": "^2.1.1" + } + }, + "node_modules/find-root": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/find-root/-/find-root-1.1.0.tgz", + "integrity": "sha512-NKfW6bec6GfKc0SGx1e07QZY9PE99u0Bft/0rzSD5k3sO/vwkVUpDUKVm5Gpp5Ue3YfShPFTX2070tDs5kB9Ng==", + "dev": true, + "license": "MIT" + }, "node_modules/find-up": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz", @@ -4182,6 +5121,22 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/findup-sync": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/findup-sync/-/findup-sync-4.0.0.tgz", + "integrity": "sha512-6jvvn/12IC4quLBL1KNokxC7wWTvYncaVUYSoxWw7YykPLuRrnv4qdHcSOywOI5RpkOVGeQRtWM8/q+G6W6qfQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "detect-file": "^1.0.0", + "is-glob": "^4.0.0", + "micromatch": "^4.0.2", + "resolve-dir": "^1.0.1" + }, + "engines": { + "node": ">= 8" + } + }, "node_modules/flat-cache": { "version": "4.0.1", "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-4.0.1.tgz", @@ -4246,6 +5201,13 @@ "node": ">=14.14" } }, + "node_modules/fs.realpath": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", + "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==", + "dev": true, + "license": "ISC" + }, "node_modules/fsevents": { "version": "2.3.3", "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", @@ -4294,6 +5256,19 @@ "node": "6.* || 8.* || >= 10.*" } }, + "node_modules/get-east-asian-width": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/get-east-asian-width/-/get-east-asian-width-1.3.0.tgz", + "integrity": "sha512-vpeMIQKxczTD/0s2CdEWHcb0eeJe6TFjxb+J5xgX7hScxqrGuyjmv4c1D4A/gelKfyox0gJJwIHF+fLjeaM8kQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/get-stream": { "version": "6.0.1", "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-6.0.1.tgz", @@ -4385,6 +5360,77 @@ "url": "https://github.com/sponsors/isaacs" } }, + "node_modules/global-directory": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/global-directory/-/global-directory-4.0.1.tgz", + "integrity": "sha512-wHTUcDUoZ1H5/0iVqEudYW4/kAlN5cZ3j/bXn0Dpbizl9iaUVeWSHqiOjsgk6OW2bkLclbBjzewBz6weQ1zA2Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "ini": "4.1.1" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/global-directory/node_modules/ini": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/ini/-/ini-4.1.1.tgz", + "integrity": "sha512-QQnnxNyfvmHFIsj7gkPcYymR8Jdw/o7mp5ZFihxn6h8Ci6fh3Dx4E1gPjpQEpIuPo9XVNY/ZUwh4BPMjGyL01g==", + "dev": true, + "license": "ISC", + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/global-modules": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/global-modules/-/global-modules-1.0.0.tgz", + "integrity": "sha512-sKzpEkf11GpOFuw0Zzjzmt4B4UZwjOcG757PPvrfhxcLFbq0wpsgpOqxpxtxFiCG4DtG93M6XRVbF2oGdev7bg==", + "dev": true, + "license": "MIT", + "dependencies": { + "global-prefix": "^1.0.1", + "is-windows": "^1.0.1", + "resolve-dir": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/global-prefix": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/global-prefix/-/global-prefix-1.0.2.tgz", + "integrity": "sha512-5lsx1NUDHtSjfg0eHlmYvZKv8/nVqX4ckFbM+FrGcQ+04KWcWFo9P5MxPZYSzUvyzmdTbI7Eix8Q4IbELDqzKg==", + "dev": true, + "license": "MIT", + "dependencies": { + "expand-tilde": "^2.0.2", + "homedir-polyfill": "^1.0.1", + "ini": "^1.3.4", + "is-windows": "^1.0.1", + "which": "^1.2.14" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/global-prefix/node_modules/which": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", + "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", + "dev": true, + "license": "ISC", + "dependencies": { + "isexe": "^2.0.0" + }, + "bin": { + "which": "bin/which" + } + }, "node_modules/globals": { "version": "11.12.0", "resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz", @@ -4508,6 +5554,19 @@ "node": "*" } }, + "node_modules/homedir-polyfill": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/homedir-polyfill/-/homedir-polyfill-1.0.3.tgz", + "integrity": "sha512-eSmmWE5bZTK2Nou4g0AI3zZ9rswp7GRKoKXS1BLUkvPviOqs4YTN1djQIqrXy9k5gEtdLPy86JjRwsNM9tnDcA==", + "dev": true, + "license": "MIT", + "dependencies": { + "parse-passwd": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/hook-std": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/hook-std/-/hook-std-3.0.0.tgz", @@ -4579,6 +5638,56 @@ "node": ">=10.17.0" } }, + "node_modules/husky": { + "version": "9.1.7", + "resolved": "https://registry.npmjs.org/husky/-/husky-9.1.7.tgz", + "integrity": "sha512-5gs5ytaNjBrh5Ow3zrvdUUY+0VxIuWVL4i9irt6friV+BqdCfmV11CQTWMiBYWHbXhco+J1kHfTOUkePhCDvMA==", + "dev": true, + "license": "MIT", + "bin": { + "husky": "bin.js" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/typicode" + } + }, + "node_modules/iconv-lite": { + "version": "0.4.24", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", + "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", + "dev": true, + "license": "MIT", + "dependencies": { + "safer-buffer": ">= 2.1.2 < 3" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/ieee754": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz", + "integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "BSD-3-Clause" + }, "node_modules/ignore": { "version": "5.3.2", "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.2.tgz", @@ -4664,6 +5773,18 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/inflight": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", + "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==", + "deprecated": "This module is not supported, and leaks memory. Do not use it. Check out lru-cache if you want a good and tested way to coalesce async requests by a key value, which is much more comprehensive and powerful.", + "dev": true, + "license": "ISC", + "dependencies": { + "once": "^1.3.0", + "wrappy": "1" + } + }, "node_modules/inherits": { "version": "2.0.4", "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", @@ -4678,6 +5799,135 @@ "dev": true, "license": "ISC" }, + "node_modules/inquirer": { + "version": "9.3.7", + "resolved": "https://registry.npmjs.org/inquirer/-/inquirer-9.3.7.tgz", + "integrity": "sha512-LJKFHCSeIRq9hanN14IlOtPSTe3lNES7TYDTE2xxdAy1LS5rYphajK1qtwvj3YmQXvvk0U2Vbmcni8P9EIQW9w==", + "dev": true, + "license": "MIT", + "dependencies": { + "@inquirer/figures": "^1.0.3", + "ansi-escapes": "^4.3.2", + "cli-width": "^4.1.0", + "external-editor": "^3.1.0", + "mute-stream": "1.0.0", + "ora": "^5.4.1", + "run-async": "^3.0.0", + "rxjs": "^7.8.1", + "string-width": "^4.2.3", + "strip-ansi": "^6.0.1", + "wrap-ansi": "^6.2.0", + "yoctocolors-cjs": "^2.1.2" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/inquirer/node_modules/ansi-escapes": { + "version": "4.3.2", + "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-4.3.2.tgz", + "integrity": "sha512-gKXj5ALrKWQLsYG9jlTRmR/xKluxHV+Z9QEwNIgCfM1/uwPMCuzVVnh5mwTd+OuBZcwSIMbqssNWRm1lE51QaQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "type-fest": "^0.21.3" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/inquirer/node_modules/ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/inquirer/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "license": "MIT", + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/inquirer/node_modules/emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "dev": true, + "license": "MIT" + }, + "node_modules/inquirer/node_modules/string-width": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "dev": true, + "license": "MIT", + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/inquirer/node_modules/strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/inquirer/node_modules/type-fest": { + "version": "0.21.3", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.21.3.tgz", + "integrity": "sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w==", + "dev": true, + "license": "(MIT OR CC0-1.0)", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/inquirer/node_modules/wrap-ansi": { + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-6.2.0.tgz", + "integrity": "sha512-r6lPcBGxZXlIcymEu7InxDMhdW0KDxpLgoFLcguasxCaJ/SOIZwINatK9KY/tf+ZrlywOKU0UDj3ATXUBfxJXA==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": ">=8" + } + }, "node_modules/into-stream": { "version": "7.0.0", "resolved": "https://registry.npmjs.org/into-stream/-/into-stream-7.0.0.tgz", @@ -4751,6 +6001,16 @@ "node": ">=0.10.0" } }, + "node_modules/is-interactive": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-interactive/-/is-interactive-1.0.0.tgz", + "integrity": "sha512-2HvIEKRoqS62guEC+qBjpvRubdX910WCMuJTZ+I9yvqKU2/12eSL549HMwtabb4oupdj2sMP50k+XJfB/8JE6w==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, "node_modules/is-number": { "version": "7.0.0", "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", @@ -4804,10 +6064,27 @@ "dev": true, "license": "MIT", "engines": { - "node": ">=18" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/is-utf8": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/is-utf8/-/is-utf8-0.2.1.tgz", + "integrity": "sha512-rMYPYvCzsXywIsldgLaSoPlw5PfoB/ssr7hY4pLfcodrA5M/eArza1a9VmTiNIBNMjOGr1Ow9mTyU2o69U6U9Q==", + "dev": true, + "license": "MIT" + }, + "node_modules/is-windows": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-windows/-/is-windows-1.0.2.tgz", + "integrity": "sha512-eXK1UInq2bPmjyX6e3VHIzMLobc4J94i4AWn+Hpq3OU5KkrRC96OAcR3PRJ/pGu6m8TRnBHP9dkXQVsT/COVIA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" } }, "node_modules/isarray": { @@ -4928,6 +6205,16 @@ "dev": true, "license": "MIT" }, + "node_modules/jiti": { + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/jiti/-/jiti-2.5.1.tgz", + "integrity": "sha512-twQoecYPiVA5K/h6SxtORw/Bs3ar+mLUtoPSc7iMXzQzK8d7eJ/R09wmTwAjiamETn1cXYPGfNnu7DMoHgu12w==", + "dev": true, + "license": "MIT", + "bin": { + "jiti": "lib/jiti-cli.mjs" + } + }, "node_modules/js-tokens": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", @@ -5020,9 +6307,9 @@ } }, "node_modules/koffi": { - "version": "2.12.0", - "resolved": "https://registry.npmjs.org/koffi/-/koffi-2.12.0.tgz", - "integrity": "sha512-J886y/bvoGG4ZhMVstB2Nh6/q9tzAYn0kaH7Ss8DWavGIxP5jOLzUY9IZzw9pMuXArj0SLSpl0MYsKRURPAv7g==", + "version": "2.13.0", + "resolved": "https://registry.npmjs.org/koffi/-/koffi-2.13.0.tgz", + "integrity": "sha512-VqQzBC7XBVJHXA4DkmY68HbH8VTYVaBKq3MFlziI+pdJXIpd/lO4LeXKo2YpIhuTkLgXYra+dDjJOo2+yT1Tsg==", "hasInstallScript": true, "license": "MIT" }, @@ -5040,6 +6327,19 @@ "node": ">= 0.8.0" } }, + "node_modules/lilconfig": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/lilconfig/-/lilconfig-3.1.3.tgz", + "integrity": "sha512-/vlFKAoH5Cgt3Ie+JLhRbwOsCQePABiU3tJ1egGvyQ+33R/vcwM2Zl2QR/LzjsBeItPt3oSVXapn+m4nQDvpzw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/antonk52" + } + }, "node_modules/lines-and-columns": { "version": "1.2.4", "resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.2.4.tgz", @@ -5057,6 +6357,108 @@ "uc.micro": "^2.0.0" } }, + "node_modules/lint-staged": { + "version": "16.1.2", + "resolved": "https://registry.npmjs.org/lint-staged/-/lint-staged-16.1.2.tgz", + "integrity": "sha512-sQKw2Si2g9KUZNY3XNvRuDq4UJqpHwF0/FQzZR2M7I5MvtpWvibikCjUVJzZdGE0ByurEl3KQNvsGetd1ty1/Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "chalk": "^5.4.1", + "commander": "^14.0.0", + "debug": "^4.4.1", + "lilconfig": "^3.1.3", + "listr2": "^8.3.3", + "micromatch": "^4.0.8", + "nano-spawn": "^1.0.2", + "pidtree": "^0.6.0", + "string-argv": "^0.3.2", + "yaml": "^2.8.0" + }, + "bin": { + "lint-staged": "bin/lint-staged.js" + }, + "engines": { + "node": ">=20.17" + }, + "funding": { + "url": "https://opencollective.com/lint-staged" + } + }, + "node_modules/lint-staged/node_modules/chalk": { + "version": "5.4.1", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-5.4.1.tgz", + "integrity": "sha512-zgVZuo2WcZgfUEmsn6eO3kINexW8RAE4maiQ8QNs8CtpPCSyMiYsULR3HQYkm3w8FIA3SberyMJMSldGsW+U3w==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^12.17.0 || ^14.13 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/listr2": { + "version": "8.3.3", + "resolved": "https://registry.npmjs.org/listr2/-/listr2-8.3.3.tgz", + "integrity": "sha512-LWzX2KsqcB1wqQ4AHgYb4RsDXauQiqhjLk+6hjbaeHG4zpjjVAB6wC/gz6X0l+Du1cN3pUB5ZlrvTbhGSNnUQQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "cli-truncate": "^4.0.0", + "colorette": "^2.0.20", + "eventemitter3": "^5.0.1", + "log-update": "^6.1.0", + "rfdc": "^1.4.1", + "wrap-ansi": "^9.0.0" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/listr2/node_modules/emoji-regex": { + "version": "10.4.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-10.4.0.tgz", + "integrity": "sha512-EC+0oUMY1Rqm4O6LLrgjtYDvcVYTy7chDnM4Q7030tP4Kwj3u/pR6gP9ygnp2CJMK5Gq+9Q2oqmrFJAz01DXjw==", + "dev": true, + "license": "MIT" + }, + "node_modules/listr2/node_modules/string-width": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-7.2.0.tgz", + "integrity": "sha512-tsaTIkKW9b4N+AEj+SVA+WhJzV7/zMhcSu78mLKWSk7cXMOSHsBKFWUs0fWwq8QyK3MgJBQRX6Gbi4kYbdvGkQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "emoji-regex": "^10.3.0", + "get-east-asian-width": "^1.0.0", + "strip-ansi": "^7.1.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/listr2/node_modules/wrap-ansi": { + "version": "9.0.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-9.0.0.tgz", + "integrity": "sha512-G8ura3S+3Z2G+mkgNRq8dqaFZAuxfsxpBB8OCTGRTCtp+l/v9nbFNmCUP1BZMts3G1142MsZfn6eeUKrr4PD1Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-styles": "^6.2.1", + "string-width": "^7.0.0", + "strip-ansi": "^7.1.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + } + }, "node_modules/load-json-file": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-4.0.0.tgz", @@ -5117,6 +6519,13 @@ "dev": true, "license": "MIT" }, + "node_modules/lodash.camelcase": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/lodash.camelcase/-/lodash.camelcase-4.3.0.tgz", + "integrity": "sha512-TwuEnCnxbc3rAvhf/LbG7tJUDzhqXyFnv3dtzLOPgCG/hODL7WFnsbwktkD7yUV0RrreP/l1PALq/YSg6VvjlA==", + "dev": true, + "license": "MIT" + }, "node_modules/lodash.capitalize": { "version": "4.2.1", "resolved": "https://registry.npmjs.org/lodash.capitalize/-/lodash.capitalize-4.2.1.tgz", @@ -5145,6 +6554,20 @@ "dev": true, "license": "MIT" }, + "node_modules/lodash.kebabcase": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/lodash.kebabcase/-/lodash.kebabcase-4.1.1.tgz", + "integrity": "sha512-N8XRTIMMqqDgSy4VLKPnJ/+hpGZN+PHQiJnSenYqPaVV/NCqEogTnAdZLQiGKhxX+JCs8waWq2t1XHWKOmlY8g==", + "dev": true, + "license": "MIT" + }, + "node_modules/lodash.map": { + "version": "4.6.0", + "resolved": "https://registry.npmjs.org/lodash.map/-/lodash.map-4.6.0.tgz", + "integrity": "sha512-worNHGKLDetmcEYDvh2stPCrrQRkP20E4l0iIS7F8EvzMqBBi7ltvFN5m1HvTf1P7Jk1txKhvFcmYsCr8O2F1Q==", + "dev": true, + "license": "MIT" + }, "node_modules/lodash.merge": { "version": "4.6.2", "resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz", @@ -5152,6 +6575,34 @@ "dev": true, "license": "MIT" }, + "node_modules/lodash.mergewith": { + "version": "4.6.2", + "resolved": "https://registry.npmjs.org/lodash.mergewith/-/lodash.mergewith-4.6.2.tgz", + "integrity": "sha512-GK3g5RPZWTRSeLSpgP8Xhra+pnjBC56q9FZYe1d5RN3TJ35dbkGy3YqBSMbyCrlbi+CM9Z3Jk5yTL7RCsqboyQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/lodash.snakecase": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/lodash.snakecase/-/lodash.snakecase-4.1.1.tgz", + "integrity": "sha512-QZ1d4xoBHYUeuouhEq3lk3Uq7ldgyFXGBhg04+oRLnIz8o9T65Eh+8YdroUwn846zchkA9yDsDl5CVVaV2nqYw==", + "dev": true, + "license": "MIT" + }, + "node_modules/lodash.startcase": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/lodash.startcase/-/lodash.startcase-4.4.0.tgz", + "integrity": "sha512-+WKqsK294HMSc2jEbNgpHpd0JfIBhp7rEV4aqXWqFr6AlXov+SlcgB1Fv01y2kGe3Gc8nMW7VA0SrGuSkRfIEg==", + "dev": true, + "license": "MIT" + }, + "node_modules/lodash.uniq": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/lodash.uniq/-/lodash.uniq-4.5.0.tgz", + "integrity": "sha512-xfBaXQd9ryd9dlSDvnvI0lvxfLJlYAZzXomUYzLKtUeOQvOP5piqAWuGtrhWeqaXK9hhoM/iyJc5AV+XfsX3HQ==", + "dev": true, + "license": "MIT" + }, "node_modules/lodash.uniqby": { "version": "4.7.0", "resolved": "https://registry.npmjs.org/lodash.uniqby/-/lodash.uniqby-4.7.0.tgz", @@ -5159,10 +6610,202 @@ "dev": true, "license": "MIT" }, + "node_modules/lodash.upperfirst": { + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/lodash.upperfirst/-/lodash.upperfirst-4.3.1.tgz", + "integrity": "sha512-sReKOYJIJf74dhJONhU4e0/shzi1trVbSWDOhKYE5XV2O+H7Sb2Dihwuc7xWxVl+DgFPyTqIN3zMfT9cq5iWDg==", + "dev": true, + "license": "MIT" + }, + "node_modules/log-symbols": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-4.1.0.tgz", + "integrity": "sha512-8XPvpAA8uyhfteu8pIvQxpJZ7SYYdpUivZpGy6sFsBuKRY/7rQGavedeB8aK+Zkyq6upMFVL/9AW6vOYzfRyLg==", + "dev": true, + "license": "MIT", + "dependencies": { + "chalk": "^4.1.0", + "is-unicode-supported": "^0.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/log-symbols/node_modules/is-unicode-supported": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/is-unicode-supported/-/is-unicode-supported-0.1.0.tgz", + "integrity": "sha512-knxG2q4UC3u8stRGyAVJCOdxFmv5DZiRcdlIaAQXAbSfJya+OhopNotLQrstBhququ4ZpuKbDc/8S6mgXgPFPw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/log-update": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/log-update/-/log-update-6.1.0.tgz", + "integrity": "sha512-9ie8ItPR6tjY5uYJh8K/Zrv/RMZ5VOlOWvtZdEHYSTFKZfIBPQa9tOAEeAWhd+AnIneLJ22w5fjOYtoutpWq5w==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-escapes": "^7.0.0", + "cli-cursor": "^5.0.0", + "slice-ansi": "^7.1.0", + "strip-ansi": "^7.1.0", + "wrap-ansi": "^9.0.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/log-update/node_modules/cli-cursor": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-5.0.0.tgz", + "integrity": "sha512-aCj4O5wKyszjMmDT4tZj93kxyydN/K5zPWSCe6/0AV/AA1pqe5ZBIw0a2ZfPQV7lL5/yb5HsUreJ6UFAF1tEQw==", + "dev": true, + "license": "MIT", + "dependencies": { + "restore-cursor": "^5.0.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/log-update/node_modules/emoji-regex": { + "version": "10.4.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-10.4.0.tgz", + "integrity": "sha512-EC+0oUMY1Rqm4O6LLrgjtYDvcVYTy7chDnM4Q7030tP4Kwj3u/pR6gP9ygnp2CJMK5Gq+9Q2oqmrFJAz01DXjw==", + "dev": true, + "license": "MIT" + }, + "node_modules/log-update/node_modules/is-fullwidth-code-point": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-5.0.0.tgz", + "integrity": "sha512-OVa3u9kkBbw7b8Xw5F9P+D/T9X+Z4+JruYVNapTjPYZYUznQ5YfWeFkOj606XYYW8yugTfC8Pj0hYqvi4ryAhA==", + "dev": true, + "license": "MIT", + "dependencies": { + "get-east-asian-width": "^1.0.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/log-update/node_modules/onetime": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/onetime/-/onetime-7.0.0.tgz", + "integrity": "sha512-VXJjc87FScF88uafS3JllDgvAm+c/Slfz06lorj2uAY34rlUu0Nt+v8wreiImcrgAjjIHp1rXpTDlLOGw29WwQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "mimic-function": "^5.0.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/log-update/node_modules/restore-cursor": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-5.1.0.tgz", + "integrity": "sha512-oMA2dcrw6u0YfxJQXm342bFKX/E4sG9rbTzO9ptUcR/e8A33cHuvStiYOwH7fszkZlZ1z/ta9AAoPk2F4qIOHA==", + "dev": true, + "license": "MIT", + "dependencies": { + "onetime": "^7.0.0", + "signal-exit": "^4.1.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/log-update/node_modules/slice-ansi": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-7.1.0.tgz", + "integrity": "sha512-bSiSngZ/jWeX93BqeIAbImyTbEihizcwNjFoRUIY/T1wWQsfsm2Vw1agPKylXvQTU7iASGdHhyqRlqQzfz+Htg==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-styles": "^6.2.1", + "is-fullwidth-code-point": "^5.0.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/chalk/slice-ansi?sponsor=1" + } + }, + "node_modules/log-update/node_modules/string-width": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-7.2.0.tgz", + "integrity": "sha512-tsaTIkKW9b4N+AEj+SVA+WhJzV7/zMhcSu78mLKWSk7cXMOSHsBKFWUs0fWwq8QyK3MgJBQRX6Gbi4kYbdvGkQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "emoji-regex": "^10.3.0", + "get-east-asian-width": "^1.0.0", + "strip-ansi": "^7.1.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/log-update/node_modules/wrap-ansi": { + "version": "9.0.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-9.0.0.tgz", + "integrity": "sha512-G8ura3S+3Z2G+mkgNRq8dqaFZAuxfsxpBB8OCTGRTCtp+l/v9nbFNmCUP1BZMts3G1142MsZfn6eeUKrr4PD1Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-styles": "^6.2.1", + "string-width": "^7.0.0", + "strip-ansi": "^7.1.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + } + }, + "node_modules/longest": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/longest/-/longest-2.0.1.tgz", + "integrity": "sha512-Ajzxb8CM6WAnFjgiloPsI3bF+WCxcvhdIG3KNA2KN962+tdBsHcuQ4k4qX/EcS/2CRkcc0iAkR956Nib6aXU/Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/loupe": { - "version": "3.1.4", - "resolved": "https://registry.npmjs.org/loupe/-/loupe-3.1.4.tgz", - "integrity": "sha512-wJzkKwJrheKtknCOKNEtDK4iqg/MxmZheEMtSTYvnzRdEYaZzmgH976nenp8WdJRdx5Vc1X/9MO0Oszl6ezeXg==", + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/loupe/-/loupe-3.2.0.tgz", + "integrity": "sha512-2NCfZcT5VGVNX9mSZIxLRkEAegDGBpuQZBy13desuHeVORmBDyAET4TkJr4SjqQy3A8JDofMN6LpkK8Xcm/dlw==", "dev": true, "license": "MIT" }, @@ -5304,6 +6947,13 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/merge": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/merge/-/merge-2.1.1.tgz", + "integrity": "sha512-jz+Cfrg9GWOZbQAnDQ4hlVnQky+341Yk5ru8bZSe6sIDTCIg8n9i/u7hSQGSVOF3C7lH6mGtqjkiT9G4wFLL0w==", + "dev": true, + "license": "MIT" + }, "node_modules/merge-stream": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz", @@ -5374,6 +7024,19 @@ "node": ">=6" } }, + "node_modules/mimic-function": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/mimic-function/-/mimic-function-5.0.1.tgz", + "integrity": "sha512-VP79XUPxV2CigYP3jWwAUFSku2aKqBH7uTAapFWCBqutsbmDo96KY5o8uh6U+/YSIn5OxJnXp73beVkpqMIGhA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/minimatch": { "version": "3.1.2", "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", @@ -5435,6 +7098,16 @@ "dev": true, "license": "MIT" }, + "node_modules/mute-stream": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/mute-stream/-/mute-stream-1.0.0.tgz", + "integrity": "sha512-avsJQhyd+680gKXyG/sQc0nXaC6rBkPOfyHYcFb9+hdkqQkR9bdnkJ0AMZhke0oesPqIO+mFFJ+IdBc7mst4IA==", + "dev": true, + "license": "ISC", + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, "node_modules/mz": { "version": "2.7.0", "resolved": "https://registry.npmjs.org/mz/-/mz-2.7.0.tgz", @@ -5454,6 +7127,19 @@ "dev": true, "license": "MIT" }, + "node_modules/nano-spawn": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/nano-spawn/-/nano-spawn-1.0.2.tgz", + "integrity": "sha512-21t+ozMQDAL/UGgQVBbZ/xXvNO10++ZPuTmKRO8k9V3AClVRht49ahtDjfY8l1q6nSHOrE5ASfthzH3ol6R/hg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=20.17" + }, + "funding": { + "url": "https://github.com/sindresorhus/nano-spawn?sponsor=1" + } + }, "node_modules/nanoid": { "version": "3.3.11", "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.11.tgz", @@ -5539,9 +7225,9 @@ } }, "node_modules/npm": { - "version": "10.9.2", - "resolved": "https://registry.npmjs.org/npm/-/npm-10.9.2.tgz", - "integrity": "sha512-iriPEPIkoMYUy3F6f3wwSZAU93E0Eg6cHwIR6jzzOXWSy+SD/rOODEs74cVONHKSx2obXtuUoyidVEhISrisgQ==", + "version": "10.9.3", + "resolved": "https://registry.npmjs.org/npm/-/npm-10.9.3.tgz", + "integrity": "sha512-6Eh1u5Q+kIVXeA8e7l2c/HpnFFcwrkt37xDMujD5be1gloWa9p6j3Fsv3mByXXmqJHy+2cElRMML8opNT7xIJQ==", "bundleDependencies": [ "@isaacs/string-locale-compare", "@npmcli/arborist", @@ -5623,37 +7309,37 @@ ], "dependencies": { "@isaacs/string-locale-compare": "^1.1.0", - "@npmcli/arborist": "^8.0.0", + "@npmcli/arborist": "^8.0.1", "@npmcli/config": "^9.0.0", "@npmcli/fs": "^4.0.0", "@npmcli/map-workspaces": "^4.0.2", - "@npmcli/package-json": "^6.1.0", + "@npmcli/package-json": "^6.2.0", "@npmcli/promise-spawn": "^8.0.2", - "@npmcli/redact": "^3.0.0", - "@npmcli/run-script": "^9.0.1", - "@sigstore/tuf": "^3.0.0", - "abbrev": "^3.0.0", + "@npmcli/redact": "^3.2.2", + "@npmcli/run-script": "^9.1.0", + "@sigstore/tuf": "^3.1.1", + "abbrev": "^3.0.1", "archy": "~1.0.0", "cacache": "^19.0.1", - "chalk": "^5.3.0", - "ci-info": "^4.1.0", + "chalk": "^5.4.1", + "ci-info": "^4.2.0", "cli-columns": "^4.0.0", "fastest-levenshtein": "^1.0.16", "fs-minipass": "^3.0.3", "glob": "^10.4.5", "graceful-fs": "^4.2.11", - "hosted-git-info": "^8.0.2", + "hosted-git-info": "^8.1.0", "ini": "^5.0.0", "init-package-json": "^7.0.2", - "is-cidr": "^5.1.0", + "is-cidr": "^5.1.1", "json-parse-even-better-errors": "^4.0.0", "libnpmaccess": "^9.0.0", - "libnpmdiff": "^7.0.0", - "libnpmexec": "^9.0.0", - "libnpmfund": "^6.0.0", + "libnpmdiff": "^7.0.1", + "libnpmexec": "^9.0.1", + "libnpmfund": "^6.0.1", "libnpmhook": "^11.0.0", "libnpmorg": "^7.0.0", - "libnpmpack": "^8.0.0", + "libnpmpack": "^8.0.1", "libnpmpublish": "^10.0.1", "libnpmsearch": "^8.0.0", "libnpmteam": "^7.0.0", @@ -5663,23 +7349,23 @@ "minipass": "^7.1.1", "minipass-pipeline": "^1.2.4", "ms": "^2.1.2", - "node-gyp": "^11.0.0", - "nopt": "^8.0.0", + "node-gyp": "^11.2.0", + "nopt": "^8.1.0", "normalize-package-data": "^7.0.0", "npm-audit-report": "^6.0.0", "npm-install-checks": "^7.1.1", - "npm-package-arg": "^12.0.0", + "npm-package-arg": "^12.0.2", "npm-pick-manifest": "^10.0.0", "npm-profile": "^11.0.1", "npm-registry-fetch": "^18.0.2", "npm-user-validate": "^3.0.0", - "p-map": "^4.0.0", + "p-map": "^7.0.3", "pacote": "^19.0.1", "parse-conflict-json": "^4.0.0", "proc-log": "^5.0.0", "qrcode-terminal": "^0.12.0", - "read": "^4.0.0", - "semver": "^7.6.3", + "read": "^4.1.0", + "semver": "^7.7.2", "spdx-expression-parse": "^4.0.0", "ssri": "^12.0.0", "supports-color": "^9.4.0", @@ -5687,7 +7373,7 @@ "text-table": "~0.2.0", "tiny-relative-date": "^1.3.0", "treeverse": "^3.0.0", - "validate-npm-package-name": "^6.0.0", + "validate-npm-package-name": "^6.0.1", "which": "^5.0.0", "write-file-atomic": "^6.0.0" }, @@ -5814,7 +7500,7 @@ } }, "node_modules/npm/node_modules/@npmcli/arborist": { - "version": "8.0.0", + "version": "8.0.1", "dev": true, "inBundle": true, "license": "ISC", @@ -5894,7 +7580,7 @@ } }, "node_modules/npm/node_modules/@npmcli/git": { - "version": "6.0.1", + "version": "6.0.3", "dev": true, "inBundle": true, "license": "ISC", @@ -5904,7 +7590,6 @@ "lru-cache": "^10.0.1", "npm-pick-manifest": "^10.0.0", "proc-log": "^5.0.0", - "promise-inflight": "^1.0.1", "promise-retry": "^2.0.1", "semver": "^7.3.5", "which": "^5.0.0" @@ -6010,7 +7695,7 @@ } }, "node_modules/npm/node_modules/@npmcli/package-json": { - "version": "6.1.0", + "version": "6.2.0", "dev": true, "inBundle": true, "license": "ISC", @@ -6019,9 +7704,9 @@ "glob": "^10.2.2", "hosted-git-info": "^8.0.0", "json-parse-even-better-errors": "^4.0.0", - "normalize-package-data": "^7.0.0", "proc-log": "^5.0.0", - "semver": "^7.5.3" + "semver": "^7.5.3", + "validate-npm-package-license": "^3.0.4" }, "engines": { "node": "^18.17.0 || >=20.5.0" @@ -6040,19 +7725,19 @@ } }, "node_modules/npm/node_modules/@npmcli/query": { - "version": "4.0.0", + "version": "4.0.1", "dev": true, "inBundle": true, "license": "ISC", "dependencies": { - "postcss-selector-parser": "^6.1.2" + "postcss-selector-parser": "^7.0.0" }, "engines": { "node": "^18.17.0 || >=20.5.0" } }, "node_modules/npm/node_modules/@npmcli/redact": { - "version": "3.0.0", + "version": "3.2.2", "dev": true, "inBundle": true, "license": "ISC", @@ -6061,7 +7746,7 @@ } }, "node_modules/npm/node_modules/@npmcli/run-script": { - "version": "9.0.2", + "version": "9.1.0", "dev": true, "inBundle": true, "license": "ISC", @@ -6088,21 +7773,21 @@ } }, "node_modules/npm/node_modules/@sigstore/protobuf-specs": { - "version": "0.3.2", + "version": "0.4.3", "dev": true, "inBundle": true, "license": "Apache-2.0", "engines": { - "node": "^16.14.0 || >=18.0.0" + "node": "^18.17.0 || >=20.5.0" } }, "node_modules/npm/node_modules/@sigstore/tuf": { - "version": "3.0.0", + "version": "3.1.1", "dev": true, "inBundle": true, "license": "Apache-2.0", "dependencies": { - "@sigstore/protobuf-specs": "^0.3.2", + "@sigstore/protobuf-specs": "^0.4.1", "tuf-js": "^3.0.1" }, "engines": { @@ -6119,7 +7804,7 @@ } }, "node_modules/npm/node_modules/abbrev": { - "version": "3.0.0", + "version": "3.0.1", "dev": true, "inBundle": true, "license": "ISC", @@ -6128,30 +7813,14 @@ } }, "node_modules/npm/node_modules/agent-base": { - "version": "7.1.1", + "version": "7.1.3", "dev": true, "inBundle": true, "license": "MIT", - "dependencies": { - "debug": "^4.3.4" - }, "engines": { "node": ">= 14" } }, - "node_modules/npm/node_modules/aggregate-error": { - "version": "3.1.0", - "dev": true, - "inBundle": true, - "license": "MIT", - "dependencies": { - "clean-stack": "^2.0.0", - "indent-string": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, "node_modules/npm/node_modules/ansi-regex": { "version": "5.0.1", "dev": true, @@ -6220,7 +7889,7 @@ } }, "node_modules/npm/node_modules/brace-expansion": { - "version": "2.0.1", + "version": "2.0.2", "dev": true, "inBundle": true, "license": "MIT", @@ -6260,19 +7929,6 @@ "node": ">=18" } }, - "node_modules/npm/node_modules/cacache/node_modules/minizlib": { - "version": "3.0.1", - "dev": true, - "inBundle": true, - "license": "MIT", - "dependencies": { - "minipass": "^7.0.4", - "rimraf": "^5.0.5" - }, - "engines": { - "node": ">= 18" - } - }, "node_modules/npm/node_modules/cacache/node_modules/mkdirp": { "version": "3.0.1", "dev": true, @@ -6288,18 +7944,6 @@ "url": "https://github.com/sponsors/isaacs" } }, - "node_modules/npm/node_modules/cacache/node_modules/p-map": { - "version": "7.0.2", - "dev": true, - "inBundle": true, - "license": "MIT", - "engines": { - "node": ">=18" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, "node_modules/npm/node_modules/cacache/node_modules/tar": { "version": "7.4.3", "dev": true, @@ -6327,7 +7971,7 @@ } }, "node_modules/npm/node_modules/chalk": { - "version": "5.3.0", + "version": "5.4.1", "dev": true, "inBundle": true, "license": "MIT", @@ -6348,7 +7992,7 @@ } }, "node_modules/npm/node_modules/ci-info": { - "version": "4.1.0", + "version": "4.2.0", "dev": true, "funding": [ { @@ -6363,7 +8007,7 @@ } }, "node_modules/npm/node_modules/cidr-regex": { - "version": "4.1.1", + "version": "4.1.3", "dev": true, "inBundle": true, "license": "BSD-2-Clause", @@ -6374,15 +8018,6 @@ "node": ">=14" } }, - "node_modules/npm/node_modules/clean-stack": { - "version": "2.2.0", - "dev": true, - "inBundle": true, - "license": "MIT", - "engines": { - "node": ">=6" - } - }, "node_modules/npm/node_modules/cli-columns": { "version": "4.0.0", "dev": true, @@ -6471,7 +8106,7 @@ } }, "node_modules/npm/node_modules/debug": { - "version": "4.3.7", + "version": "4.4.1", "dev": true, "inBundle": true, "license": "MIT", @@ -6534,7 +8169,7 @@ "license": "MIT" }, "node_modules/npm/node_modules/exponential-backoff": { - "version": "3.1.1", + "version": "3.1.2", "dev": true, "inBundle": true, "license": "Apache-2.0" @@ -6549,12 +8184,12 @@ } }, "node_modules/npm/node_modules/foreground-child": { - "version": "3.3.0", + "version": "3.3.1", "dev": true, "inBundle": true, "license": "ISC", "dependencies": { - "cross-spawn": "^7.0.0", + "cross-spawn": "^7.0.6", "signal-exit": "^4.0.1" }, "engines": { @@ -6603,7 +8238,7 @@ "license": "ISC" }, "node_modules/npm/node_modules/hosted-git-info": { - "version": "8.0.2", + "version": "8.1.0", "dev": true, "inBundle": true, "license": "ISC", @@ -6615,7 +8250,7 @@ } }, "node_modules/npm/node_modules/http-cache-semantics": { - "version": "4.1.1", + "version": "4.2.0", "dev": true, "inBundle": true, "license": "BSD-2-Clause" @@ -6634,12 +8269,12 @@ } }, "node_modules/npm/node_modules/https-proxy-agent": { - "version": "7.0.5", + "version": "7.0.6", "dev": true, "inBundle": true, "license": "MIT", "dependencies": { - "agent-base": "^7.0.2", + "agent-base": "^7.1.2", "debug": "4" }, "engines": { @@ -6680,15 +8315,6 @@ "node": ">=0.8.19" } }, - "node_modules/npm/node_modules/indent-string": { - "version": "4.0.0", - "dev": true, - "inBundle": true, - "license": "MIT", - "engines": { - "node": ">=8" - } - }, "node_modules/npm/node_modules/ini": { "version": "5.0.0", "dev": true, @@ -6742,7 +8368,7 @@ } }, "node_modules/npm/node_modules/is-cidr": { - "version": "5.1.0", + "version": "5.1.1", "dev": true, "inBundle": true, "license": "BSD-2-Clause", @@ -6842,12 +8468,12 @@ } }, "node_modules/npm/node_modules/libnpmdiff": { - "version": "7.0.0", + "version": "7.0.1", "dev": true, "inBundle": true, "license": "ISC", "dependencies": { - "@npmcli/arborist": "^8.0.0", + "@npmcli/arborist": "^8.0.1", "@npmcli/installed-package-contents": "^3.0.0", "binary-extensions": "^2.3.0", "diff": "^5.1.0", @@ -6861,12 +8487,12 @@ } }, "node_modules/npm/node_modules/libnpmexec": { - "version": "9.0.0", + "version": "9.0.1", "dev": true, "inBundle": true, "license": "ISC", "dependencies": { - "@npmcli/arborist": "^8.0.0", + "@npmcli/arborist": "^8.0.1", "@npmcli/run-script": "^9.0.1", "ci-info": "^4.0.0", "npm-package-arg": "^12.0.0", @@ -6882,12 +8508,12 @@ } }, "node_modules/npm/node_modules/libnpmfund": { - "version": "6.0.0", + "version": "6.0.1", "dev": true, "inBundle": true, "license": "ISC", "dependencies": { - "@npmcli/arborist": "^8.0.0" + "@npmcli/arborist": "^8.0.1" }, "engines": { "node": "^18.17.0 || >=20.5.0" @@ -6920,12 +8546,12 @@ } }, "node_modules/npm/node_modules/libnpmpack": { - "version": "8.0.0", + "version": "8.0.1", "dev": true, "inBundle": true, "license": "ISC", "dependencies": { - "@npmcli/arborist": "^8.0.0", + "@npmcli/arborist": "^8.0.1", "@npmcli/run-script": "^9.0.1", "npm-package-arg": "^12.0.0", "pacote": "^19.0.0" @@ -7068,7 +8694,7 @@ } }, "node_modules/npm/node_modules/minipass-fetch": { - "version": "4.0.0", + "version": "4.0.1", "dev": true, "inBundle": true, "license": "MIT", @@ -7084,19 +8710,6 @@ "encoding": "^0.1.13" } }, - "node_modules/npm/node_modules/minipass-fetch/node_modules/minizlib": { - "version": "3.0.1", - "dev": true, - "inBundle": true, - "license": "MIT", - "dependencies": { - "minipass": "^7.0.4", - "rimraf": "^5.0.5" - }, - "engines": { - "node": ">= 18" - } - }, "node_modules/npm/node_modules/minipass-flush": { "version": "1.0.5", "dev": true, @@ -7170,28 +8783,15 @@ } }, "node_modules/npm/node_modules/minizlib": { - "version": "2.1.2", + "version": "3.0.2", "dev": true, "inBundle": true, "license": "MIT", "dependencies": { - "minipass": "^3.0.0", - "yallist": "^4.0.0" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/npm/node_modules/minizlib/node_modules/minipass": { - "version": "3.3.6", - "dev": true, - "inBundle": true, - "license": "ISC", - "dependencies": { - "yallist": "^4.0.0" + "minipass": "^7.1.2" }, "engines": { - "node": ">=8" + "node": ">= 18" } }, "node_modules/npm/node_modules/mkdirp": { @@ -7222,20 +8822,20 @@ } }, "node_modules/npm/node_modules/node-gyp": { - "version": "11.0.0", + "version": "11.2.0", "dev": true, "inBundle": true, "license": "MIT", "dependencies": { "env-paths": "^2.2.0", "exponential-backoff": "^3.1.1", - "glob": "^10.3.10", "graceful-fs": "^4.2.6", "make-fetch-happen": "^14.0.3", "nopt": "^8.0.0", "proc-log": "^5.0.0", "semver": "^7.3.5", "tar": "^7.4.3", + "tinyglobby": "^0.2.12", "which": "^5.0.0" }, "bin": { @@ -7254,19 +8854,6 @@ "node": ">=18" } }, - "node_modules/npm/node_modules/node-gyp/node_modules/minizlib": { - "version": "3.0.1", - "dev": true, - "inBundle": true, - "license": "MIT", - "dependencies": { - "minipass": "^7.0.4", - "rimraf": "^5.0.5" - }, - "engines": { - "node": ">= 18" - } - }, "node_modules/npm/node_modules/node-gyp/node_modules/mkdirp": { "version": "3.0.1", "dev": true, @@ -7309,12 +8896,12 @@ } }, "node_modules/npm/node_modules/nopt": { - "version": "8.0.0", + "version": "8.1.0", "dev": true, "inBundle": true, "license": "ISC", "dependencies": { - "abbrev": "^2.0.0" + "abbrev": "^3.0.0" }, "bin": { "nopt": "bin/nopt.js" @@ -7323,15 +8910,6 @@ "node": "^18.17.0 || >=20.5.0" } }, - "node_modules/npm/node_modules/nopt/node_modules/abbrev": { - "version": "2.0.0", - "dev": true, - "inBundle": true, - "license": "ISC", - "engines": { - "node": "^14.17.0 || ^16.13.0 || >=18.0.0" - } - }, "node_modules/npm/node_modules/normalize-package-data": { "version": "7.0.0", "dev": true, @@ -7389,7 +8967,7 @@ } }, "node_modules/npm/node_modules/npm-package-arg": { - "version": "12.0.0", + "version": "12.0.2", "dev": true, "inBundle": true, "license": "ISC", @@ -7462,19 +9040,6 @@ "node": "^18.17.0 || >=20.5.0" } }, - "node_modules/npm/node_modules/npm-registry-fetch/node_modules/minizlib": { - "version": "3.0.1", - "dev": true, - "inBundle": true, - "license": "MIT", - "dependencies": { - "minipass": "^7.0.4", - "rimraf": "^5.0.5" - }, - "engines": { - "node": ">= 18" - } - }, "node_modules/npm/node_modules/npm-user-validate": { "version": "3.0.0", "dev": true, @@ -7485,15 +9050,12 @@ } }, "node_modules/npm/node_modules/p-map": { - "version": "4.0.0", + "version": "7.0.3", "dev": true, "inBundle": true, "license": "MIT", - "dependencies": { - "aggregate-error": "^3.0.0" - }, "engines": { - "node": ">=10" + "node": ">=18" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" @@ -7576,7 +9138,7 @@ } }, "node_modules/npm/node_modules/postcss-selector-parser": { - "version": "6.1.2", + "version": "7.1.0", "dev": true, "inBundle": true, "license": "MIT", @@ -7624,12 +9186,6 @@ "url": "https://github.com/sponsors/isaacs" } }, - "node_modules/npm/node_modules/promise-inflight": { - "version": "1.0.1", - "dev": true, - "inBundle": true, - "license": "ISC" - }, "node_modules/npm/node_modules/promise-retry": { "version": "2.0.1", "dev": true, @@ -7664,7 +9220,7 @@ } }, "node_modules/npm/node_modules/read": { - "version": "4.0.0", + "version": "4.1.0", "dev": true, "inBundle": true, "license": "ISC", @@ -7706,21 +9262,6 @@ "node": ">= 4" } }, - "node_modules/npm/node_modules/rimraf": { - "version": "5.0.10", - "dev": true, - "inBundle": true, - "license": "ISC", - "dependencies": { - "glob": "^10.3.7" - }, - "bin": { - "rimraf": "dist/esm/bin.mjs" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, "node_modules/npm/node_modules/safer-buffer": { "version": "2.1.2", "dev": true, @@ -7729,7 +9270,7 @@ "optional": true }, "node_modules/npm/node_modules/semver": { - "version": "7.6.3", + "version": "7.7.2", "dev": true, "inBundle": true, "license": "ISC", @@ -7774,29 +9315,29 @@ } }, "node_modules/npm/node_modules/sigstore": { - "version": "3.0.0", + "version": "3.1.0", "dev": true, "inBundle": true, "license": "Apache-2.0", "dependencies": { - "@sigstore/bundle": "^3.0.0", + "@sigstore/bundle": "^3.1.0", "@sigstore/core": "^2.0.0", - "@sigstore/protobuf-specs": "^0.3.2", - "@sigstore/sign": "^3.0.0", - "@sigstore/tuf": "^3.0.0", - "@sigstore/verify": "^2.0.0" + "@sigstore/protobuf-specs": "^0.4.0", + "@sigstore/sign": "^3.1.0", + "@sigstore/tuf": "^3.1.0", + "@sigstore/verify": "^2.1.0" }, "engines": { "node": "^18.17.0 || >=20.5.0" } }, "node_modules/npm/node_modules/sigstore/node_modules/@sigstore/bundle": { - "version": "3.0.0", + "version": "3.1.0", "dev": true, "inBundle": true, "license": "Apache-2.0", "dependencies": { - "@sigstore/protobuf-specs": "^0.3.2" + "@sigstore/protobuf-specs": "^0.4.0" }, "engines": { "node": "^18.17.0 || >=20.5.0" @@ -7812,15 +9353,15 @@ } }, "node_modules/npm/node_modules/sigstore/node_modules/@sigstore/sign": { - "version": "3.0.0", + "version": "3.1.0", "dev": true, "inBundle": true, "license": "Apache-2.0", "dependencies": { - "@sigstore/bundle": "^3.0.0", + "@sigstore/bundle": "^3.1.0", "@sigstore/core": "^2.0.0", - "@sigstore/protobuf-specs": "^0.3.2", - "make-fetch-happen": "^14.0.1", + "@sigstore/protobuf-specs": "^0.4.0", + "make-fetch-happen": "^14.0.2", "proc-log": "^5.0.0", "promise-retry": "^2.0.1" }, @@ -7829,14 +9370,14 @@ } }, "node_modules/npm/node_modules/sigstore/node_modules/@sigstore/verify": { - "version": "2.0.0", + "version": "2.1.1", "dev": true, "inBundle": true, "license": "Apache-2.0", "dependencies": { - "@sigstore/bundle": "^3.0.0", + "@sigstore/bundle": "^3.1.0", "@sigstore/core": "^2.0.0", - "@sigstore/protobuf-specs": "^0.3.2" + "@sigstore/protobuf-specs": "^0.4.1" }, "engines": { "node": "^18.17.0 || >=20.5.0" @@ -7853,7 +9394,7 @@ } }, "node_modules/npm/node_modules/socks": { - "version": "2.8.3", + "version": "2.8.5", "dev": true, "inBundle": true, "license": "MIT", @@ -7867,12 +9408,12 @@ } }, "node_modules/npm/node_modules/socks-proxy-agent": { - "version": "8.0.4", + "version": "8.0.5", "dev": true, "inBundle": true, "license": "MIT", "dependencies": { - "agent-base": "^7.1.1", + "agent-base": "^7.1.2", "debug": "^4.3.4", "socks": "^2.8.3" }, @@ -7917,7 +9458,7 @@ } }, "node_modules/npm/node_modules/spdx-license-ids": { - "version": "3.0.20", + "version": "3.0.21", "dev": true, "inBundle": true, "license": "CC0-1.0" @@ -8027,15 +9568,49 @@ "version": "2.1.0", "dev": true, "inBundle": true, - "license": "ISC", + "license": "ISC", + "dependencies": { + "minipass": "^3.0.0" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/npm/node_modules/tar/node_modules/fs-minipass/node_modules/minipass": { + "version": "3.3.6", + "dev": true, + "inBundle": true, + "license": "ISC", + "dependencies": { + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/npm/node_modules/tar/node_modules/minipass": { + "version": "5.0.0", + "dev": true, + "inBundle": true, + "license": "ISC", + "engines": { + "node": ">=8" + } + }, + "node_modules/npm/node_modules/tar/node_modules/minizlib": { + "version": "2.1.2", + "dev": true, + "inBundle": true, + "license": "MIT", "dependencies": { - "minipass": "^3.0.0" + "minipass": "^3.0.0", + "yallist": "^4.0.0" }, "engines": { "node": ">= 8" } }, - "node_modules/npm/node_modules/tar/node_modules/fs-minipass/node_modules/minipass": { + "node_modules/npm/node_modules/tar/node_modules/minizlib/node_modules/minipass": { "version": "3.3.6", "dev": true, "inBundle": true, @@ -8047,15 +9622,6 @@ "node": ">=8" } }, - "node_modules/npm/node_modules/tar/node_modules/minipass": { - "version": "5.0.0", - "dev": true, - "inBundle": true, - "license": "ISC", - "engines": { - "node": ">=8" - } - }, "node_modules/npm/node_modules/text-table": { "version": "0.2.0", "dev": true, @@ -8068,6 +9634,48 @@ "inBundle": true, "license": "MIT" }, + "node_modules/npm/node_modules/tinyglobby": { + "version": "0.2.14", + "dev": true, + "inBundle": true, + "license": "MIT", + "dependencies": { + "fdir": "^6.4.4", + "picomatch": "^4.0.2" + }, + "engines": { + "node": ">=12.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/SuperchupuDev" + } + }, + "node_modules/npm/node_modules/tinyglobby/node_modules/fdir": { + "version": "6.4.6", + "dev": true, + "inBundle": true, + "license": "MIT", + "peerDependencies": { + "picomatch": "^3 || ^4" + }, + "peerDependenciesMeta": { + "picomatch": { + "optional": true + } + } + }, + "node_modules/npm/node_modules/tinyglobby/node_modules/picomatch": { + "version": "4.0.2", + "dev": true, + "inBundle": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, "node_modules/npm/node_modules/treeverse": { "version": "3.0.0", "dev": true, @@ -8155,7 +9763,7 @@ } }, "node_modules/npm/node_modules/validate-npm-package-name": { - "version": "6.0.0", + "version": "6.0.1", "dev": true, "inBundle": true, "license": "ISC", @@ -8322,6 +9930,16 @@ "node": ">=0.10.0" } }, + "node_modules/once": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", + "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", + "dev": true, + "license": "ISC", + "dependencies": { + "wrappy": "1" + } + }, "node_modules/onetime": { "version": "5.1.2", "resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.2.tgz", @@ -8356,6 +9974,76 @@ "node": ">= 0.8.0" } }, + "node_modules/ora": { + "version": "5.4.1", + "resolved": "https://registry.npmjs.org/ora/-/ora-5.4.1.tgz", + "integrity": "sha512-5b6Y85tPxZZ7QytO+BQzysW31HJku27cRIlkbAXaNx+BdcVi+LlRFmVXzeF6a7JCwJpyw5c4b+YSVImQIrBpuQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "bl": "^4.1.0", + "chalk": "^4.1.0", + "cli-cursor": "^3.1.0", + "cli-spinners": "^2.5.0", + "is-interactive": "^1.0.0", + "is-unicode-supported": "^0.1.0", + "log-symbols": "^4.1.0", + "strip-ansi": "^6.0.0", + "wcwidth": "^1.0.1" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/ora/node_modules/ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/ora/node_modules/is-unicode-supported": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/is-unicode-supported/-/is-unicode-supported-0.1.0.tgz", + "integrity": "sha512-knxG2q4UC3u8stRGyAVJCOdxFmv5DZiRcdlIaAQXAbSfJya+OhopNotLQrstBhququ4ZpuKbDc/8S6mgXgPFPw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/ora/node_modules/strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/os-tmpdir": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz", + "integrity": "sha512-D2FR03Vir7FIu45XBY20mTb+/ZSWB00sjU9jdQXt83gDrI4Ztz5Fs7/yy74g2N5SVQY4xY1qDr4rNddwYRVX0g==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/p-each-series": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/p-each-series/-/p-each-series-3.0.0.tgz", @@ -8511,6 +10199,16 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/parse-passwd": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/parse-passwd/-/parse-passwd-1.0.0.tgz", + "integrity": "sha512-1Y1A//QUXEZK7YKz+rD9WydcE1+EuPr6ZBgKecAB8tmoW6UFv0NREVJe1p+jRxtThkcbbKkfwIbWJe/IeE6m2Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/parse5": { "version": "5.1.1", "resolved": "https://registry.npmjs.org/parse5/-/parse5-5.1.1.tgz", @@ -8545,6 +10243,16 @@ "node": ">=8" } }, + "node_modules/path-is-absolute": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", + "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/path-key": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", @@ -8597,9 +10305,9 @@ "license": "MIT" }, "node_modules/pathval": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/pathval/-/pathval-2.0.0.tgz", - "integrity": "sha512-vE7JKRyES09KiunauX7nd2Q9/L7lhok4smP9RZTDeD4MVs72Dp2qNFVz39Nz5a0FVEW0BJR6C0DYrq6unoziZA==", + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/pathval/-/pathval-2.0.1.tgz", + "integrity": "sha512-//nshmD55c46FuFw26xV/xFAaB5HF9Xdap7HJBBnrKdAd6/GxDBaNA1870O79+9ueg61cZLSVc+OaFlfmObYVQ==", "dev": true, "license": "MIT", "engines": { @@ -8614,9 +10322,9 @@ "license": "ISC" }, "node_modules/picomatch": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.2.tgz", - "integrity": "sha512-M7BAV6Rlcy5u+m6oPhAPFgJTzAioX/6B0DxyvDlo9l8+T3nLKbrczg2WLUyzd45L8RqfUMyGPzekbMvX2Ldkwg==", + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.3.tgz", + "integrity": "sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==", "dev": true, "license": "MIT", "engines": { @@ -8626,6 +10334,19 @@ "url": "https://github.com/sponsors/jonschlinkert" } }, + "node_modules/pidtree": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/pidtree/-/pidtree-0.6.0.tgz", + "integrity": "sha512-eG2dWTVw5bzqGRztnHExczNxt5VGsE6OwTeCG3fdUf9KBsZzO3R5OIIIzWR+iZA0NtZ+RDVdaoE2dK1cn6jH4g==", + "dev": true, + "license": "MIT", + "bin": { + "pidtree": "bin/pidtree.js" + }, + "engines": { + "node": ">=0.10" + } + }, "node_modules/pify": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz", @@ -8753,9 +10474,9 @@ } }, "node_modules/prettier": { - "version": "3.5.3", - "resolved": "https://registry.npmjs.org/prettier/-/prettier-3.5.3.tgz", - "integrity": "sha512-QQtaxnoDJeAkDvDKWCLiwIXkTgRhwYDEQCghU9Z6q03iyek/rxRh/2lC3HB7P8sWT2xC/y5JDctPLBIGzHKbhw==", + "version": "3.6.2", + "resolved": "https://registry.npmjs.org/prettier/-/prettier-3.6.2.tgz", + "integrity": "sha512-I7AIg5boAr5R0FFtJ6rCfD+LFsWHp81dolrFD8S79U9tb8Az2nGrJncnMSnys+bpQJfRUzqs9hnA81OAA3hCuQ==", "dev": true, "license": "MIT", "bin": { @@ -8955,6 +10676,16 @@ "node": ">=0.10.0" } }, + "node_modules/require-from-string": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/require-from-string/-/require-from-string-2.0.2.tgz", + "integrity": "sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/resolve": { "version": "1.22.10", "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.10.tgz", @@ -8976,6 +10707,20 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/resolve-dir": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/resolve-dir/-/resolve-dir-1.0.1.tgz", + "integrity": "sha512-R7uiTjECzvOsWSfdM0QKFNBVFcK27aHOUwdvK53BcW8zqnGdYp0Fbj82cy54+2A4P2tFM22J5kRfe1R+lM/1yg==", + "dev": true, + "license": "MIT", + "dependencies": { + "expand-tilde": "^2.0.0", + "global-modules": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/resolve-from": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", @@ -8996,6 +10741,27 @@ "url": "https://github.com/privatenumber/resolve-pkg-maps?sponsor=1" } }, + "node_modules/restore-cursor": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-3.1.0.tgz", + "integrity": "sha512-l+sSefzHpj5qimhFSE5a8nufZYAM3sBSVMAPtYkmC+4EH2anSGaEMXSD0izRQbu9nfyQ9y5JrVmp7E8oZrUjvA==", + "dev": true, + "license": "MIT", + "dependencies": { + "onetime": "^5.1.0", + "signal-exit": "^3.0.2" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/restore-cursor/node_modules/signal-exit": { + "version": "3.0.7", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz", + "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==", + "dev": true, + "license": "ISC" + }, "node_modules/reusify": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz", @@ -9007,6 +10773,13 @@ "node": ">=0.10.0" } }, + "node_modules/rfdc": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/rfdc/-/rfdc-1.4.1.tgz", + "integrity": "sha512-q1b3N5QkRUWUl7iyylaaj3kOpIT0N2i9MqIEQXP73GVsN9cw3fdx8X63cEmWhJGi2PPCF23Ijp7ktmd39rawIA==", + "dev": true, + "license": "MIT" + }, "node_modules/rimraf": { "version": "6.0.1", "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-6.0.1.tgz", @@ -9111,9 +10884,9 @@ } }, "node_modules/rollup": { - "version": "4.44.0", - "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.44.0.tgz", - "integrity": "sha512-qHcdEzLCiktQIfwBq420pn2dP+30uzqYxv9ETm91wdt2R9AFcWfjNAmje4NWlnCIQ5RMTzVf0ZyisOKqHR6RwA==", + "version": "4.46.2", + "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.46.2.tgz", + "integrity": "sha512-WMmLFI+Boh6xbop+OAGo9cQ3OgX9MIg7xOQjn+pTCwOkk+FNDAeAemXkJ3HzDJrVXleLOFVa1ipuc1AmEx1Dwg==", "dev": true, "license": "MIT", "dependencies": { @@ -9127,29 +10900,39 @@ "npm": ">=8.0.0" }, "optionalDependencies": { - "@rollup/rollup-android-arm-eabi": "4.44.0", - "@rollup/rollup-android-arm64": "4.44.0", - "@rollup/rollup-darwin-arm64": "4.44.0", - "@rollup/rollup-darwin-x64": "4.44.0", - "@rollup/rollup-freebsd-arm64": "4.44.0", - "@rollup/rollup-freebsd-x64": "4.44.0", - "@rollup/rollup-linux-arm-gnueabihf": "4.44.0", - "@rollup/rollup-linux-arm-musleabihf": "4.44.0", - "@rollup/rollup-linux-arm64-gnu": "4.44.0", - "@rollup/rollup-linux-arm64-musl": "4.44.0", - "@rollup/rollup-linux-loongarch64-gnu": "4.44.0", - "@rollup/rollup-linux-powerpc64le-gnu": "4.44.0", - "@rollup/rollup-linux-riscv64-gnu": "4.44.0", - "@rollup/rollup-linux-riscv64-musl": "4.44.0", - "@rollup/rollup-linux-s390x-gnu": "4.44.0", - "@rollup/rollup-linux-x64-gnu": "4.44.0", - "@rollup/rollup-linux-x64-musl": "4.44.0", - "@rollup/rollup-win32-arm64-msvc": "4.44.0", - "@rollup/rollup-win32-ia32-msvc": "4.44.0", - "@rollup/rollup-win32-x64-msvc": "4.44.0", + "@rollup/rollup-android-arm-eabi": "4.46.2", + "@rollup/rollup-android-arm64": "4.46.2", + "@rollup/rollup-darwin-arm64": "4.46.2", + "@rollup/rollup-darwin-x64": "4.46.2", + "@rollup/rollup-freebsd-arm64": "4.46.2", + "@rollup/rollup-freebsd-x64": "4.46.2", + "@rollup/rollup-linux-arm-gnueabihf": "4.46.2", + "@rollup/rollup-linux-arm-musleabihf": "4.46.2", + "@rollup/rollup-linux-arm64-gnu": "4.46.2", + "@rollup/rollup-linux-arm64-musl": "4.46.2", + "@rollup/rollup-linux-loongarch64-gnu": "4.46.2", + "@rollup/rollup-linux-ppc64-gnu": "4.46.2", + "@rollup/rollup-linux-riscv64-gnu": "4.46.2", + "@rollup/rollup-linux-riscv64-musl": "4.46.2", + "@rollup/rollup-linux-s390x-gnu": "4.46.2", + "@rollup/rollup-linux-x64-gnu": "4.46.2", + "@rollup/rollup-linux-x64-musl": "4.46.2", + "@rollup/rollup-win32-arm64-msvc": "4.46.2", + "@rollup/rollup-win32-ia32-msvc": "4.46.2", + "@rollup/rollup-win32-x64-msvc": "4.46.2", "fsevents": "~2.3.2" } }, + "node_modules/run-async": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/run-async/-/run-async-3.0.0.tgz", + "integrity": "sha512-540WwVDOMxA6dN6We19EcT9sc3hkXPw5mzRNGM3FkdN/vtE9NFvj5lFAPNwUDmJjXidm3v7TC1cTE7t17Ulm1Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.12.0" + } + }, "node_modules/run-parallel": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz", @@ -9174,6 +10957,16 @@ "queue-microtask": "^1.2.2" } }, + "node_modules/rxjs": { + "version": "7.8.2", + "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-7.8.2.tgz", + "integrity": "sha512-dhKf903U/PQZY6boNNtAGdWbG85WAbjT/1xYoZIC7FAY0yWapOBQVsVrDl58W86//e1VpMNBtRV4MaXfdMySFA==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "tslib": "^2.1.0" + } + }, "node_modules/safe-buffer": { "version": "5.1.2", "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", @@ -9181,6 +10974,13 @@ "dev": true, "license": "MIT" }, + "node_modules/safer-buffer": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", + "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==", + "dev": true, + "license": "MIT" + }, "node_modules/segfault-handler": { "version": "1.3.0", "resolved": "https://registry.npmjs.org/segfault-handler/-/segfault-handler-1.3.0.tgz", @@ -9194,16 +10994,16 @@ } }, "node_modules/semantic-release": { - "version": "24.2.5", - "resolved": "https://registry.npmjs.org/semantic-release/-/semantic-release-24.2.5.tgz", - "integrity": "sha512-9xV49HNY8C0/WmPWxTlaNleiXhWb//qfMzG2c5X8/k7tuWcu8RssbuS+sujb/h7PiWSXv53mrQvV9hrO9b7vuQ==", + "version": "24.2.7", + "resolved": "https://registry.npmjs.org/semantic-release/-/semantic-release-24.2.7.tgz", + "integrity": "sha512-g7RssbTAbir1k/S7uSwSVZFfFXwpomUB9Oas0+xi9KStSCmeDXcA7rNhiskjLqvUe/Evhx8fVCT16OSa34eM5g==", "dev": true, "license": "MIT", "dependencies": { "@semantic-release/commit-analyzer": "^13.0.0-beta.1", "@semantic-release/error": "^4.0.0", "@semantic-release/github": "^11.0.0", - "@semantic-release/npm": "^12.0.0", + "@semantic-release/npm": "^12.0.2", "@semantic-release/release-notes-generator": "^14.0.0-beta.1", "aggregate-error": "^5.0.0", "cosmiconfig": "^9.0.0", @@ -9697,6 +11497,36 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/slice-ansi": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-5.0.0.tgz", + "integrity": "sha512-FC+lgizVPfie0kkhqUScwRu1O/lF6NOgJmlCgK+/LYxDCTk8sGelYaHDhFcDN+Sn3Cv+3VSa4Byeo+IMCzpMgQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-styles": "^6.0.0", + "is-fullwidth-code-point": "^4.0.0" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/slice-ansi?sponsor=1" + } + }, + "node_modules/slice-ansi/node_modules/is-fullwidth-code-point": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-4.0.0.tgz", + "integrity": "sha512-O4L094N2/dZ7xqVdrXhh9r1KODPJpFms8B5sGdJLPy664AgvXsreZUyCQQNItZRDlYug4xStLjNp/sz3HvBowQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/source-map": { "version": "0.6.1", "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", @@ -9805,6 +11635,16 @@ "safe-buffer": "~5.1.0" } }, + "node_modules/string-argv": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/string-argv/-/string-argv-0.3.2.tgz", + "integrity": "sha512-aqD2Q0144Z+/RqG52NeHEkZauTAUWJO8c6yTftGJKO3Tja5tUgIfmIl6kExvhtxSDP7fXB6DvzkfMpCd/F3G+Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.6.19" + } + }, "node_modules/string-width": { "version": "5.1.2", "resolved": "https://registry.npmjs.org/string-width/-/string-width-5.1.2.tgz", @@ -10131,6 +11971,13 @@ "node": ">=0.8" } }, + "node_modules/through": { + "version": "2.3.8", + "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz", + "integrity": "sha512-w89qg7PI8wAdvX60bMDP+bFoD5Dvhm9oLheFp5O4a2QF0cSBGsBX4qZmadPMvVqlLJBBci+WqGGOAPvcDeNSVg==", + "dev": true, + "license": "MIT" + }, "node_modules/through2": { "version": "2.0.5", "resolved": "https://registry.npmjs.org/through2/-/through2-2.0.5.tgz", @@ -10219,6 +12066,19 @@ "node": ">=14.0.0" } }, + "node_modules/tmp": { + "version": "0.0.33", + "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.0.33.tgz", + "integrity": "sha512-jRCJlojKnZ3addtTOjdIqoRuPEKBvNXcGYqzO6zWZX8KfKEpnGY5jfggJQ3EjKuu8D4bJRr0y+cYJFmYbImXGw==", + "dev": true, + "license": "MIT", + "dependencies": { + "os-tmpdir": "~1.0.2" + }, + "engines": { + "node": ">=0.6.0" + } + }, "node_modules/to-regex-range": { "version": "5.0.1", "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", @@ -10322,17 +12182,17 @@ } }, "node_modules/typedoc": { - "version": "0.28.5", - "resolved": "https://registry.npmjs.org/typedoc/-/typedoc-0.28.5.tgz", - "integrity": "sha512-5PzUddaA9FbaarUzIsEc4wNXCiO4Ot3bJNeMF2qKpYlTmM9TTaSHQ7162w756ERCkXER/+o2purRG6YOAv6EMA==", + "version": "0.28.9", + "resolved": "https://registry.npmjs.org/typedoc/-/typedoc-0.28.9.tgz", + "integrity": "sha512-aw45vwtwOl3QkUAmWCnLV9QW1xY+FSX2zzlit4MAfE99wX+Jij4ycnpbAWgBXsRrxmfs9LaYktg/eX5Bpthd3g==", "dev": true, "license": "Apache-2.0", "dependencies": { - "@gerrit0/mini-shiki": "^3.2.2", + "@gerrit0/mini-shiki": "^3.9.0", "lunr": "^2.3.9", "markdown-it": "^14.1.0", "minimatch": "^9.0.5", - "yaml": "^2.7.1" + "yaml": "^2.8.0" }, "bin": { "typedoc": "bin/typedoc" @@ -10342,7 +12202,7 @@ "pnpm": ">= 10" }, "peerDependencies": { - "typescript": "5.0.x || 5.1.x || 5.2.x || 5.3.x || 5.4.x || 5.5.x || 5.6.x || 5.7.x || 5.8.x" + "typescript": "5.0.x || 5.1.x || 5.2.x || 5.3.x || 5.4.x || 5.5.x || 5.6.x || 5.7.x || 5.8.x || 5.9.x" } }, "node_modules/typedoc-material-theme": { @@ -10389,9 +12249,9 @@ } }, "node_modules/typescript": { - "version": "5.8.3", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.8.3.tgz", - "integrity": "sha512-p1diW6TqL9L07nNxvRMM7hMMw4c5XOo/1ibL4aAIGmSAt9slTE1Xgw5KWuof2uTOvCg9BY7ZRi+GaF+7sfgPeQ==", + "version": "5.9.2", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.9.2.tgz", + "integrity": "sha512-CWBzXQrc/qOkhidw1OzBTQuYRbfyxDXJMVJ1XNwUHGROVmuaeiEm3OslpZ1RV96d7SKKjZKrSJu3+t/xlw3R9A==", "dev": true, "license": "Apache-2.0", "bin": { @@ -10403,15 +12263,16 @@ } }, "node_modules/typescript-eslint": { - "version": "8.34.1", - "resolved": "https://registry.npmjs.org/typescript-eslint/-/typescript-eslint-8.34.1.tgz", - "integrity": "sha512-XjS+b6Vg9oT1BaIUfkW3M3LvqZE++rbzAMEHuccCfO/YkP43ha6w3jTEMilQxMF92nVOYCcdjv1ZUhAa1D/0ow==", + "version": "8.39.0", + "resolved": "https://registry.npmjs.org/typescript-eslint/-/typescript-eslint-8.39.0.tgz", + "integrity": "sha512-lH8FvtdtzcHJCkMOKnN73LIn6SLTpoojgJqDAxPm1jCR14eWSGPX8ul/gggBdPMk/d5+u9V854vTYQ8T5jF/1Q==", "dev": true, "license": "MIT", "dependencies": { - "@typescript-eslint/eslint-plugin": "8.34.1", - "@typescript-eslint/parser": "8.34.1", - "@typescript-eslint/utils": "8.34.1" + "@typescript-eslint/eslint-plugin": "8.39.0", + "@typescript-eslint/parser": "8.39.0", + "@typescript-eslint/typescript-estree": "8.39.0", + "@typescript-eslint/utils": "8.39.0" }, "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" @@ -10422,7 +12283,7 @@ }, "peerDependencies": { "eslint": "^8.57.0 || ^9.0.0", - "typescript": ">=4.8.4 <5.9.0" + "typescript": ">=4.8.4 <6.0.0" } }, "node_modules/uc.micro": { @@ -10447,9 +12308,9 @@ } }, "node_modules/undici-types": { - "version": "7.8.0", - "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-7.8.0.tgz", - "integrity": "sha512-9UJ2xGDvQ43tYyVMpuHlsgApydB8ZKfVYTsLDhXkFL/6gfkp+U8xTGdh8pMJv1SpZna0zxG1DwsKZsreLbXBxw==", + "version": "7.10.0", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-7.10.0.tgz", + "integrity": "sha512-t5Fy/nfn+14LuOc2KNYg75vZqClpAiqscVvMygNnlsHBFpSXdJaYtXMcdNLpl/Qvc3P2cB3s6lOV51nqsFq4ag==", "dev": true, "license": "MIT" }, @@ -10548,24 +12409,24 @@ } }, "node_modules/vite": { - "version": "6.3.5", - "resolved": "https://registry.npmjs.org/vite/-/vite-6.3.5.tgz", - "integrity": "sha512-cZn6NDFE7wdTpINgs++ZJ4N49W2vRp8LCKrn3Ob1kYNtOo21vfDoaV5GzBfLU4MovSAB8uNRm4jgzVQZ+mBzPQ==", + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/vite/-/vite-7.1.1.tgz", + "integrity": "sha512-yJ+Mp7OyV+4S+afWo+QyoL9jFWD11QFH0i5i7JypnfTcA1rmgxCbiA8WwAICDEtZ1Z1hzrVhN8R8rGTqkTY8ZQ==", "dev": true, "license": "MIT", "dependencies": { "esbuild": "^0.25.0", - "fdir": "^6.4.4", - "picomatch": "^4.0.2", - "postcss": "^8.5.3", - "rollup": "^4.34.9", - "tinyglobby": "^0.2.13" + "fdir": "^6.4.6", + "picomatch": "^4.0.3", + "postcss": "^8.5.6", + "rollup": "^4.43.0", + "tinyglobby": "^0.2.14" }, "bin": { "vite": "bin/vite.js" }, "engines": { - "node": "^18.0.0 || ^20.0.0 || >=22.0.0" + "node": "^20.19.0 || >=22.12.0" }, "funding": { "url": "https://github.com/vitejs/vite?sponsor=1" @@ -10574,14 +12435,14 @@ "fsevents": "~2.3.3" }, "peerDependencies": { - "@types/node": "^18.0.0 || ^20.0.0 || >=22.0.0", + "@types/node": "^20.19.0 || >=22.12.0", "jiti": ">=1.21.0", - "less": "*", + "less": "^4.0.0", "lightningcss": "^1.21.0", - "sass": "*", - "sass-embedded": "*", - "stylus": "*", - "sugarss": "*", + "sass": "^1.70.0", + "sass-embedded": "^1.70.0", + "stylus": ">=0.54.8", + "sugarss": "^5.0.0", "terser": "^5.16.0", "tsx": "^4.8.1", "yaml": "^2.4.2" @@ -10718,6 +12579,16 @@ } } }, + "node_modules/wcwidth": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/wcwidth/-/wcwidth-1.0.1.tgz", + "integrity": "sha512-XHPEwS0q6TaxcvG85+8EYkbiCux2XtWG2mkc47Ng2A77BQu9+DqIOJldST4HgPkuea7dvKSj5VgX3P1d4rW8Tg==", + "dev": true, + "license": "MIT", + "dependencies": { + "defaults": "^1.0.3" + } + }, "node_modules/which": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", @@ -10866,6 +12737,13 @@ "node": ">=8" } }, + "node_modules/wrappy": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", + "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==", + "dev": true, + "license": "ISC" + }, "node_modules/xtend": { "version": "4.0.2", "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz", @@ -10998,6 +12876,19 @@ "funding": { "url": "https://github.com/sponsors/sindresorhus" } + }, + "node_modules/yoctocolors-cjs": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/yoctocolors-cjs/-/yoctocolors-cjs-2.1.2.tgz", + "integrity": "sha512-cYVsTjKl8b+FrnidjibDWskAv7UKOfcwaVZdp/it9n1s9fU3IkgDbhdIRKCW4JDsAlECJY0ytoVPT3sK6kideA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } } } } diff --git a/package.json b/package.json index 53f20f5..48da4be 100644 --- a/package.json +++ b/package.json @@ -11,6 +11,7 @@ "scripts": { "test": "vitest", "test:ui": "vitest --ui", + "test:debug": "vitest --ui --debug", "format": "prettier --write src/", "lint": "eslint src", "prebuild": "rimraf dist", @@ -18,7 +19,10 @@ "postbuild": "cp src/lib/AutoItX3* dist/lib && cp src/lib/LICENSE dist/lib", "release": "semantic-release", "docs": "typedoc", - "reset": "rimraf node_modules dist coverage && npm install" + "reset": "rimraf node_modules dist coverage .rollup.cache .docs && npm install", + "commit": "cz", + "prepare": "husky", + "lint-staged": "lint-staged" }, "repository": { "type": "git", @@ -38,32 +42,35 @@ "url": "https://github.com/KasimAhmic/autoit-js/issues" }, "homepage": "https://github.com/KasimAhmic/autoit-js#readme", - "dependencies": { - "koffi": "^2.12.0" - }, "devDependencies": { - "@eslint/js": "^9.29.0", - "@rollup/plugin-typescript": "^12.1.3", + "@commitlint/cz-commitlint": "^19.8.1", + "@eslint/js": "^9.32.0", + "@rollup/plugin-typescript": "^12.1.4", "@semantic-release/changelog": "^6.0.3", "@semantic-release/git": "^10.0.1", "@semantic-release/github": "^11.0.3", - "@semantic-release/npm": "^12.0.1", + "@semantic-release/npm": "^12.0.2", "@trivago/prettier-plugin-sort-imports": "^5.2.2", - "@types/node": "^24.0.3", + "@types/node": "^24.2.0", "@vitest/coverage-v8": "^3.2.4", "@vitest/ui": "^3.2.4", - "eslint": "^9.29.0", - "prettier": "^3.5.3", + "commitizen": "^4.3.1", + "cz-conventional-changelog": "^3.3.0", + "eslint": "^9.32.0", + "husky": "^9.1.7", + "inquirer": "^9.3.7", + "lint-staged": "^16.1.2", + "prettier": "^3.6.2", "rimraf": "^6.0.1", - "rollup": "^4.44.0", + "rollup": "^4.46.2", "segfault-handler": "^1.3.0", - "semantic-release": "^24.2.5", + "semantic-release": "^24.2.7", "tslib": "^2.8.1", "tsx": "^4.20.3", - "typedoc": "^0.28.5", + "typedoc": "^0.28.9", "typedoc-material-theme": "^1.4.0", - "typescript": "^5.8.3", - "typescript-eslint": "^8.34.1", + "typescript": "^5.9.2", + "typescript-eslint": "^8.39.0", "vitest": "^3.2.4" }, "files": [ @@ -74,5 +81,23 @@ ], "publishConfig": { "access": "public" + }, + "config": { + "commitizen": { + "path": "./node_modules/cz-conventional-changelog", + "disableSubjectLowerCase": true + } + }, + "lint-staged": { + "src/**/*.ts": [ + "prettier --write", + "eslint" + ], + "*.{md,json}": [ + "prettier --write" + ] + }, + "dependencies": { + "koffi": "^2.13.0" } } diff --git a/rollup.config.js b/rollup.config.js index 14608db..fd48b88 100644 --- a/rollup.config.js +++ b/rollup.config.js @@ -13,6 +13,9 @@ const options = { external: ['node:os', 'node:path', 'node:url', 'node:util', 'koffi'], plugins: [ typescript({ + // Let tsc create the declaration files and leave the comments there. Strip it out in the JS code. + declaration: false, + removeComments: true, exclude: 'src/**/*.test.*', }), ], diff --git a/src/@testing/test-constants.ts b/src/@testing/test-constants.ts new file mode 100644 index 0000000..c565b85 --- /dev/null +++ b/src/@testing/test-constants.ts @@ -0,0 +1,18 @@ +import { join } from 'node:path'; + +export const TEST_APP_PATH = join(__dirname, '..', '..', 'bin', 'TestApp.exe'); + +export const APP_TITLE = 'TestApp'; +export const PROCESS_NAME = 'TestApp.exe'; +export const FIRST_NAME_EDIT = 'Edit1'; +export const LAST_NAME_EDIT = 'Edit2'; +export const ABOUT_EDIT = 'Edit3'; +export const TREE_VIEW = 'SysTreeView321'; +export const OK_BUTTON = 'Button1'; +export const CANCEL_BUTTON = 'Button2'; +export const LIST_VIEW = 'SysListView321'; +export const STATIC_LABEL = 'Static1'; +export const EVENT_LABEL = 'Static2'; +export const OK_TITLE = 'OK'; +export const CANCEL_TITLE = 'Cancel'; +export const POPUP_BUTTON = 'Button1'; diff --git a/src/@types/kernel32.ts b/src/@types/kernel32.ts deleted file mode 100644 index e7420ea..0000000 --- a/src/@types/kernel32.ts +++ /dev/null @@ -1,13 +0,0 @@ -import koffi from 'koffi'; - -import { DWORD, DoubleWord, VOID } from './win32'; - -const kernel32 = koffi.load('kernel32.dll'); - -// Named WinSleep to avoid name collisions with AutoIt's Sleep function. -export const WinSleep: koffi.KoffiFunc<(milliseconds: DoubleWord) => void> = kernel32.func( - '__stdcall', - 'Sleep', - VOID, - [DWORD], -); diff --git a/src/@types/tool-info.ts b/src/@types/tool-info.ts index f87245b..b91b315 100644 --- a/src/@types/tool-info.ts +++ b/src/@types/tool-info.ts @@ -6,7 +6,6 @@ import { HWND, InstanceHandle, LPARAM, - LPVOID, LPWSTR, LongParam, LongPointerToWideString, @@ -38,11 +37,9 @@ export class ToolInfoW implements IToolInfoW { hinst?: InstanceHandle | null; lpszText: LongPointerToWideString | null; lParam?: LongParam; - readonly lpReserved: null; - constructor(options?: Partial>) { - // TODO: This is wrong. TOOLINFOW has a size of 72 bytes but it refuses to work when setting it to 72. - this.cbSize = 40; + constructor(options?: Partial>) { + this.cbSize = koffi.sizeof(TOOLINFOW); this.uFlags = options?.uFlags; this.hwnd = options?.hwnd; this.uId = options?.uId; @@ -50,11 +47,10 @@ export class ToolInfoW implements IToolInfoW { this.hinst = options?.hinst; this.lpszText = options?.lpszText ?? ''; this.lParam = options?.lParam; - this.lpReserved = null; } } -export const TOOLINFOW = koffi.pack('TOOLINFOW', { +export const TOOLINFOW = koffi.struct('TOOLINFOW', { cbSize: UINT, uFlags: UINT, hwnd: HWND, @@ -63,7 +59,6 @@ export const TOOLINFOW = koffi.pack('TOOLINFOW', { hinst: HINSTANCE, lpszText: LPWSTR, lParam: LPARAM, - lpReserved: LPVOID, }); export const LPTOOLINFOW = koffi.pointer('LPTOOLINFOW', TOOLINFOW); diff --git a/src/auto-it-set-option.ts b/src/auto-it-set-option.ts index a3c35a7..2a88d92 100644 --- a/src/auto-it-set-option.ts +++ b/src/auto-it-set-option.ts @@ -4,7 +4,7 @@ import { AutoItOption } from './opt'; /** * Changes the operation of various AutoIt functions/parameters. This function can be used interchangeably - * with {@linkcode Opt}. + * with {@linkcode OptSync}. * * @param option The option to change. See {@linkcode AutoItOption} for details. * @param value The value to assign to the option. It varies depending on the option being set. @@ -13,13 +13,35 @@ import { AutoItOption } from './opt'; * * @example * ```typescript - * import { AutoItSetOption, AutoItOption } from '@ahmic/autoit-js'; + * import { AutoItSetOptionSync, AutoItOption } from '@ahmic/autoit-js'; * - * AutoItSetOption(AutoItOption.AutoItWinTitleMatchMode, 2); + * AutoItSetOptionSync(AutoItOption.AutoItWinTitleMatchMode, 2); * ``` * * @see https://www.autoitscript.com/autoit3/docs/functions/AutoItSetOption.htm */ -export function AutoItSetOption(option: AutoItOption, value: number): number { +export function AutoItSetOptionSync(option: AutoItOption, value: number): number { return autoit.invoke('AU3_AutoItSetOption', INT, [LPCWSTR, INT], [option, value]); } + +/** + * Changes the operation of various AutoIt functions/parameters. This function can be used interchangeably + * with {@linkcode Opt}. + * + * @param option The option to change. See {@linkcode AutoItOption} for details. + * @param value The value to assign to the option. It varies depending on the option being set. + * + * @returns A promise that resolves to the previous setting of the option. + * + * @example + * ```typescript + * import { AutoItSetOption, AutoItOption } from '@ahmic/autoit-js'; + * + * await AutoItSetOption(AutoItOption.AutoItWinTitleMatchMode, 2); + * ``` + * + * @see https://www.autoitscript.com/autoit3/docs/functions/AutoItSetOption.htm + */ +export function AutoItSetOption(option: AutoItOption, value: number): Promise { + return autoit.invokeAsync('AU3_AutoItSetOption', INT, [LPCWSTR, INT], [option, value]); +} diff --git a/src/autoit-async.test.ts b/src/autoit-async.test.ts new file mode 100644 index 0000000..02a3d5f --- /dev/null +++ b/src/autoit-async.test.ts @@ -0,0 +1,545 @@ +import { randomUUID } from 'node:crypto'; +import { statSync } from 'node:fs'; +import { join } from 'node:path'; + +import { EVENT_LABEL, PROCESS_NAME } from './@testing/test-constants'; +import { ClipGet } from './clip-get'; +import { ClipPut } from './clip-put'; +import { ControlClick } from './control-click'; +import { ControlClickByHandle } from './control-click-by-handle'; +import { ControlDisable } from './control-disable'; +import { ControlDisableByHandle } from './control-disable-by-handle'; +import { ControlEnable } from './control-enable'; +import { ControlEnableByHandle } from './control-enable-by-handle'; +import { ControlFocus } from './control-focus'; +import { ControlFocusByHandle } from './control-focus-by-handle'; +import { ControlGetFocus } from './control-get-focus'; +import { ControlGetFocusByHandle } from './control-get-focus-by-handle'; +import { ControlGetHandle } from './control-get-handle'; +import { ControlGetHandleAsText } from './control-get-handle-as-text'; +import { ControlGetPos } from './control-get-pos'; +import { ControlGetPosByHandle } from './control-get-pos-by-handle'; +import { ControlGetText } from './control-get-text'; +import { ControlGetTextByHandle } from './control-get-text-by-handle'; +import { ControlHide } from './control-hide'; +import { ControlHideByHandle } from './control-hide-by-handle'; +import { ControlListView, ListViewCommand } from './control-list-view'; +import { ControlListViewByHandle } from './control-list-view-by-handles'; +import { ControlMove } from './control-move'; +import { ControlMoveByHandle } from './control-move-by-handle'; +import { ControlSetText } from './control-set-text'; +import { ControlSetTextByHandle } from './control-set-text-by-handle'; +import { ControlShow } from './control-show'; +import { ControlShowByHandle } from './control-show-by-handle'; +import { ControlTreeView, TreeViewCommand } from './control-tree-view'; +import { ControlTreeViewByHandle } from './control-tree-view-by-handle'; +import { autoit } from './lib/autoit'; +import * as gdi32 from './lib/gdi32'; +import { MouseButton, MouseClick } from './mouse-click'; +import { MouseClickDrag } from './mouse-click-drag'; +import { MouseDown } from './mouse-down'; +import { Cursor, MouseGetCursor } from './mouse-get-cursor'; +import { MouseGetPos } from './mouse-get-pos'; +import { MouseMove } from './mouse-move'; +import { MouseUp } from './mouse-up'; +import { MouseWheel, ScrollDirection } from './mouse-wheel'; +import { PixelGetColor } from './pixel-get-color'; +import { PixelSearch } from './pixel-search'; +import { ProcessClose } from './process-close'; +import { Priority, ProcessSetPriority } from './process-set-priority'; +import { Run } from './run'; +import { StatusbarGetText } from './statusbar-get-text'; +import { StatusbarGetTextByHandle } from './statusbar-get-text-by-handle'; +import { WinActivate } from './win-activate'; +import { WinGetClassList } from './win-get-class-list'; +import { WinGetClassListByHandle } from './win-get-class-list-by-handle'; +import { WinGetClientSize } from './win-get-client-size'; +import { WinGetClientSizeByHandle } from './win-get-client-size-by-handle'; +import { WinGetHandle } from './win-get-handle'; +import { WinGetHandleAsText } from './win-get-handle-as-text'; +import { WinGetPos } from './win-get-pos'; +import { WinGetPosByHandle } from './win-get-pos-by-handle'; +import { WinGetProcess } from './win-get-process'; +import { WinGetProcessByHandle } from './win-get-process-by-handle'; +import { WinGetState } from './win-get-state'; +import { WinGetStateByHandle } from './win-get-state-by-handle'; +import { WinGetText } from './win-get-text'; +import { WinGetTextByHandle } from './win-get-text-by-handle'; +import { WinGetTitle } from './win-get-title'; +import { WinGetTitleByHandle } from './win-get-title-by-handle'; +import { WinMenuSelectItem } from './win-menu-select-item'; +import { WinMenuSelectItemByHandle } from './win-menu-select-item-by-handle'; +import { WinMinimizeAll } from './win-minimize-all'; +import { WinMinimizeAllUndo } from './win-minimize-all-undo'; +import { WinMove } from './win-move'; +import { WinMoveByHandle } from './win-move-by-handle'; +import { WinSetOnTop } from './win-set-on-top'; +import { StateFlag, WinSetState } from './win-set-state'; +import { WinSetStateByHandle } from './win-set-state-by-handle'; +import { WinSetTitle } from './win-set-title'; +import { WinSetTitleByHandle } from './win-set-title-by-handle'; +import { WinSetTrans } from './win-set-trans'; +import { WinSetTransByHandle } from './win-set-trans-by-handle'; +import { WinWait } from './win-wait'; +import { WinWaitClose } from './win-wait-close'; + +describe.sequential('AutoIt JS Asynchronous API @full', () => { + let windowHandle: bigint; + + const APP_TITLE = 'TestApp'; + const FIRST_NAME_EDIT = 'Edit1'; + const LAST_NAME_EDIT = 'Edit2'; + const ABOUT_EDIT = 'Edit3'; + const TREE_VIEW = 'SysTreeView321'; + const OK_BUTTON = 'Button1'; + const CANCEL_BUTTON = 'Button2'; + const LIST_VIEW = 'SysListView321'; + const STATIC_LABEL = 'Static1'; + const OK_TITLE = 'OK'; + const CANCEL_TITLE = 'Cancel'; + const POPUP_BUTTON = 'Button1'; + + beforeAll(async () => { + autoit.load(); + await ProcessClose('TestApp.exe'); + + const testAppPath = join(__dirname, '..', 'bin', 'TestApp.exe'); + expect(statSync(testAppPath).isFile()).toBe(true); + + expect(await Run(testAppPath)).toBeGreaterThan(0); + expect(await WinWait(APP_TITLE, '', 10)).toBeGreaterThan(0); + expect(await WinSetOnTop(APP_TITLE, '', true)).toBe(1); + + windowHandle = await WinGetHandle(APP_TITLE, ''); + }); + + afterAll(async () => { + await ProcessClose('TestApp.exe'); + autoit.unload(); + }); + + it('logs a warning if the library is loaded twice', () => { + // @ts-expect-error Testing private member + const loggerWarnSpy = vi.spyOn(autoit.logger, 'warn'); + + autoit.load(); + + expect(loggerWarnSpy).toHaveBeenCalledTimes(1); + expect(loggerWarnSpy).toHaveBeenCalledWith('AutoIt is already loaded'); + }); + + it('hides and shows the first name edit', async () => { + const handle = await ControlGetHandle(windowHandle, FIRST_NAME_EDIT); + + expect(await ControlHide(APP_TITLE, '', FIRST_NAME_EDIT)).toBe(1); + expect((await WinGetStateByHandle(handle)).visible).toBe(false); + + expect(await ControlShow(APP_TITLE, '', FIRST_NAME_EDIT)).toBe(1); + expect((await WinGetStateByHandle(handle)).visible).toBe(true); + + expect(await ControlHideByHandle(windowHandle, handle)).toBe(1); + expect((await WinGetStateByHandle(handle)).visible).toBe(false); + + expect(await ControlShowByHandle(windowHandle, handle)).toBe(1); + expect((await WinGetStateByHandle(handle)).visible).toBe(true); + }); + + it('disables and enables the last name edit', async () => { + const handle = await ControlGetHandle(windowHandle, LAST_NAME_EDIT); + + expect(await ControlDisable(APP_TITLE, '', LAST_NAME_EDIT)).toBe(1); + expect((await WinGetStateByHandle(handle)).enabled).toBe(false); + + expect(await ControlEnable(APP_TITLE, '', LAST_NAME_EDIT)).toBe(1); + expect((await WinGetStateByHandle(handle)).enabled).toBe(true); + + expect(await ControlDisableByHandle(windowHandle, handle)).toBe(1); + expect((await WinGetStateByHandle(handle)).enabled).toBe(false); + + expect(await ControlEnableByHandle(windowHandle, handle)).toBe(1); + expect((await WinGetStateByHandle(handle)).enabled).toBe(true); + }); + + it('moves and resizes the about edit', async () => { + const handle = await ControlGetHandle(windowHandle, ABOUT_EDIT); + const originalPos = await ControlGetPos(APP_TITLE, '', ABOUT_EDIT); + + expect(await ControlMove(APP_TITLE, '', ABOUT_EDIT, 100, 100, 20, 20)).toBe(1); + + expect(await ControlGetPos(APP_TITLE, '', ABOUT_EDIT)).toEqual({ + left: 100, + top: 100, + right: 120, + bottom: 120, + }); + + expect( + await ControlMoveByHandle( + windowHandle, + handle, + originalPos.left, + originalPos.top, + originalPos.right - originalPos.left, + originalPos.bottom - originalPos.top, + ), + ).toBe(1); + + expect( + await ControlGetPosByHandle(windowHandle, await ControlGetHandle(windowHandle, ABOUT_EDIT)), + ).toEqual(originalPos); + }); + + it('reads from and writes to the clipboard', async () => { + const uuid = randomUUID(); + + await ClipPut(uuid); + + expect(await ClipGet()).toBe(uuid); + expect(await ClipGet(2)).toBe(uuid.slice(0, 2)); + }); + + it('focuses a control', async () => { + const controlHandle = await ControlGetHandle(windowHandle, LAST_NAME_EDIT); + + expect(await ControlFocus(APP_TITLE, '', FIRST_NAME_EDIT)).toBe(1); + expect(await ControlGetFocus(APP_TITLE)).toBe(FIRST_NAME_EDIT); + expect(await ControlFocusByHandle(windowHandle, controlHandle)).toBe(1); + expect(await ControlGetFocusByHandle(windowHandle)).toBe(LAST_NAME_EDIT); + }); + + it('clicks a button', async () => { + expect(await ControlClick(APP_TITLE, '', OK_BUTTON)).toBe(1); + expect(await WinWait(OK_TITLE, '', 1)).toBeGreaterThan(0); + + expect(await ControlClick(OK_TITLE, '', POPUP_BUTTON)).toBe(1); + expect(await WinWaitClose(OK_TITLE, '', 1)).toBe(1); + + expect( + await ControlClickByHandle(windowHandle, await ControlGetHandle(windowHandle, CANCEL_BUTTON)), + ).toBe(1); + expect(await WinWait(CANCEL_TITLE, '', 1)).toBeGreaterThan(0); + + const cancelPopup = await WinGetHandle(CANCEL_TITLE); + + expect(await ControlClickByHandle(cancelPopup, await ControlGetHandle(cancelPopup, POPUP_BUTTON))).toBe( + 1, + ); + expect(await WinWaitClose(CANCEL_TITLE, '', 1)).toBe(1); + }); + + it('changes the window state', async () => { + await WinSetState(APP_TITLE, '', StateFlag.Minimize); + expect((await WinGetState(APP_TITLE, '')).minimized).toBe(true); + + await WinSetStateByHandle(windowHandle, StateFlag.Restore); + expect((await WinGetStateByHandle(windowHandle)).minimized).toBe(false); + + await WinSetStateByHandle(windowHandle, StateFlag.Hide); + expect((await WinGetStateByHandle(windowHandle)).visible).toBe(false); + + await WinSetStateByHandle(windowHandle, StateFlag.Show); + expect((await WinGetStateByHandle(windowHandle)).visible).toBe(true); + + await WinSetStateByHandle(windowHandle, StateFlag.Maximize); + expect((await WinGetStateByHandle(windowHandle)).maximized).toBe(true); + + await WinSetStateByHandle(windowHandle, StateFlag.Restore); + expect((await WinGetStateByHandle(windowHandle)).maximized).toBe(false); + }); + + it('gets the handle as text', async () => { + const handle = await ControlGetHandle(windowHandle, TREE_VIEW); + const handleText = await ControlGetHandleAsText(APP_TITLE, '', TREE_VIEW); + + expect(handleText).toBe('0x' + handle.toString(16).padStart(16, '0').toUpperCase()); + expect(parseInt(handleText, 16)).toBe(Number(handle)); + }); + + it('sets the text of a control', async () => { + expect(await ControlSetText(APP_TITLE, '', STATIC_LABEL, 'Test Label')).toBe(1); + expect(await ControlGetText(APP_TITLE, '', STATIC_LABEL)).toBe('Test Label'); + + const control = await ControlGetHandle(windowHandle, STATIC_LABEL); + + expect(await ControlSetTextByHandle(windowHandle, control, 'Static Label 1')).toBe(1); + expect(await ControlGetTextByHandle(windowHandle, control)).toBe('Static Label 1'); + }); + + it('interacts with a list view', async () => { + expect(await ControlListView(APP_TITLE, '', LIST_VIEW, ListViewCommand.GetItemCount)).toBe('50'); + expect(await ControlListView(APP_TITLE, '', LIST_VIEW, ListViewCommand.GetSubItemCount, '1')).toBe('4'); + + expect(await ControlListView(APP_TITLE, '', LIST_VIEW, ListViewCommand.SelectAll)).toBe('1'); + expect(await ControlListView(APP_TITLE, '', LIST_VIEW, ListViewCommand.GetSelectedCount)).toBe('50'); + + expect(await ControlListView(APP_TITLE, '', LIST_VIEW, ListViewCommand.SelectClear)).toBe('1'); + expect(await ControlListView(APP_TITLE, '', LIST_VIEW, ListViewCommand.GetSelectedCount)).toBe('0'); + + const handle = await ControlGetHandle(windowHandle, LIST_VIEW); + + expect(await ControlListViewByHandle(windowHandle, handle, ListViewCommand.Select, '1')).toBe('1'); + expect(await ControlListViewByHandle(windowHandle, handle, ListViewCommand.IsSelected, '1')).toBe('1'); + expect(await ControlListViewByHandle(windowHandle, handle, ListViewCommand.IsSelected, '2')).toBe('0'); + expect(await ControlListViewByHandle(windowHandle, handle, ListViewCommand.SelectInvert)).toBe('1'); + expect(await ControlListViewByHandle(windowHandle, handle, ListViewCommand.GetSelectedCount)).toBe('49'); + + expect(await ControlListViewByHandle(windowHandle, handle, ListViewCommand.DeSelect, '0', '50')).toBe( + '1', + ); + expect(await ControlListViewByHandle(windowHandle, handle, ListViewCommand.GetSelectedCount)).toBe('0'); + + expect(await ControlListViewByHandle(windowHandle, handle, ListViewCommand.Select, '1', '20')).toBe('1'); + expect(await ControlListViewByHandle(windowHandle, handle, ListViewCommand.GetSelected)).toBe('1'); + expect(await ControlListViewByHandle(windowHandle, handle, ListViewCommand.GetSelected, '1')).toBe( + new Array(20) + .fill(0) + .map((_, i) => i + 1) + .join('|'), + ); + + expect(await ControlListView(APP_TITLE, '', LIST_VIEW, ListViewCommand.FindItem, 'unknown')).toBe('-1'); + expect(await ControlListView(APP_TITLE, '', LIST_VIEW, ListViewCommand.FindItem, 'R10 C1')).toBe('9'); + + // TODO: Figure out how to validate this + // expect(ControlListView(APP_TITLE, '', LIST_VIEW, ListViewCommand.ViewChange, 'details')).toBe('1'); + }); + + it('sets the title', async () => { + const title = await WinGetTitle(APP_TITLE); + + expect(title).toBe(APP_TITLE); + expect(await WinSetTitle(APP_TITLE, '', 'Testing')).toBe(1); + + expect(await WinSetTitleByHandle(windowHandle, 'TestApp')).toBe(1); + expect(await WinGetTitleByHandle(windowHandle)).toBe('TestApp'); + + expect(await WinSetTitleByHandle(windowHandle, APP_TITLE)).toBe(1); + }); + + it('moves the window', async () => { + expect(await WinMove(APP_TITLE, '', 100, 100)).toBe(1); + + const pos = await WinGetPos(APP_TITLE); + + expect(pos.left).toBe(100); + expect(pos.top).toBe(100); + + expect(await WinMoveByHandle(windowHandle, 200, 200)).toBe(1); + + const newPos = await WinGetPosByHandle(windowHandle); + + expect(newPos.left).toBe(200); + expect(newPos.top).toBe(200); + }); + + it('selects a menu option', async () => { + expect(await WinMenuSelectItem(APP_TITLE, '', '&Help', '&About')).toBe(1); + expect(await WinWait('About TestApp', '', 1)).toBeGreaterThan(0); + expect(await ControlClick('About TestApp', '', 'Button1')).toBe(1); + + expect(await WinMenuSelectItemByHandle(windowHandle, '&Help', '&About')).toBe(1); + expect(await WinWait('About TestApp', '', 1)).toBeGreaterThan(0); + expect(await ControlClick('About TestApp', '', 'Button1')).toBe(1); + }); + + it('gets the status bar text', async () => { + expect(await StatusbarGetText(APP_TITLE, '', 2)).toBe(' Status 1'); + expect(await StatusbarGetTextByHandle(windowHandle, 3)).toBe(' Status 2'); + }); + + it('gets the color of a pixel', async () => { + expect(await WinActivate(APP_TITLE)).toBe(1); + const rect = await WinGetPos(APP_TITLE); + + expect(await PixelGetColor(rect.right - 25, rect.bottom - 45)).toBe(0xfeb800); + }); + + it('sets the transparency of the window', async () => { + expect(await WinSetTrans(APP_TITLE, '', 127)).toBe(1); + expect(await WinSetTransByHandle(windowHandle, 255)).toBe(1); + }); + + it('gets the text of the window', async () => { + const windowText = await WinGetText(APP_TITLE); + + expect(windowText.length).toBeGreaterThan(100); + expect(await WinGetTextByHandle(windowHandle)).toBe(windowText); + expect(await WinGetText(APP_TITLE, '', 100)).toBe(windowText.slice(0, 100)); + expect(await WinGetTextByHandle(windowHandle, 100)).toBe(windowText.slice(0, 100)); + }); + + it('sets the process priority', async () => { + expect(await ProcessSetPriority(PROCESS_NAME, Priority.High)).toBe(1); + expect(await ProcessSetPriority(PROCESS_NAME, Priority.Normal)).toBe(1); + }); + + it('gets the process ID of the window', async () => { + const processId = await WinGetProcess(APP_TITLE); + expect(processId).toBeGreaterThan(0); + expect(await WinGetProcessByHandle(windowHandle)).toBe(processId); + }); + + it('gets the window handle', async () => { + const handle = await WinGetHandle(APP_TITLE); + const textHandle = await WinGetHandleAsText(APP_TITLE); + + expect(handle).toBe(windowHandle); + expect(parseInt(textHandle, 16)).toBe(Number(windowHandle)); + }); + + it('gets the client size', async () => { + const rect = await WinGetClientSize(APP_TITLE); + + expect(rect).toEqual(await WinGetClientSizeByHandle(windowHandle)); + }); + + it('minimizes and restores all windows', async () => { + expect(await WinMinimizeAll()).toBe(undefined); + expect(await WinMinimizeAllUndo()).toBe(undefined); + }); + + it('gets the class list of the window', async () => { + const classList = await WinGetClassList(APP_TITLE); + expect(await WinGetClassListByHandle(windowHandle)).toBe(classList); + }); + + it('interacts with a tree view', async () => { + expect(await ControlTreeView(APP_TITLE, '', TREE_VIEW, TreeViewCommand.GetItemCount)).toBe('1'); + expect(await ControlTreeView(APP_TITLE, '', TREE_VIEW, TreeViewCommand.Exists, 'Root|Child 1')).toBe('1'); + expect(await ControlTreeView(APP_TITLE, '', TREE_VIEW, TreeViewCommand.Expand, 'Root|Child 2')).toBe('1'); + expect( + await ControlTreeView(APP_TITLE, '', TREE_VIEW, TreeViewCommand.GetItemCount, 'Root|Child 2'), + ).toBe('3'); + + const handle = await ControlGetHandle(windowHandle, TREE_VIEW); + + expect( + await ControlTreeViewByHandle(windowHandle, handle, TreeViewCommand.Select, 'Root|Child 2|Child 2.2'), + ).toBe('1'); + expect(await ControlTreeViewByHandle(windowHandle, handle, TreeViewCommand.GetSelected, '')).toBe( + 'Root|Child 2|Child 2.2', + ); + expect( + await ControlTreeViewByHandle(windowHandle, handle, TreeViewCommand.GetText, 'Root|Child 2|Child 2.2'), + ).toBe('Child 2.2'); + }); + + it('uses the mouse', async () => { + const handle = await ControlGetHandle(windowHandle, OK_BUTTON); + const windowRect = await WinGetPos(APP_TITLE); + const buttonRect = await ControlGetPosByHandle(windowHandle, handle); + + const x = windowRect.left + buttonRect.left + 10; + const y = windowRect.top + buttonRect.top + 10 + 43; // title bar height + menu height = 43 + + // Mouse move + expect(await MouseMove(x, y)).toBe(1); + expect(await MouseGetPos()).toEqual({ x, y }); + + // Mouse down/up + await MouseDown(MouseButton.Left); + await MouseUp(MouseButton.Left); + + expect(await WinWait(OK_TITLE, '', 1)).toBeGreaterThan(0); + expect(await ControlClick(OK_TITLE, '', POPUP_BUTTON)).toBe(1); + expect(await WinWaitClose(OK_TITLE, '', 1)).toBe(1); + + // Mouse click + expect(await MouseClick(MouseButton.Left, x, y)).toBe(1); + + expect(await WinWait(OK_TITLE, '', 1)).toBeGreaterThan(0); + expect(await ControlClick(OK_TITLE, '', POPUP_BUTTON)).toBe(1); + expect(await WinWaitClose(OK_TITLE, '', 1)).toBe(1); + + // Mouse drag + const pos = await MouseGetPos(); + + expect(await MouseClickDrag(MouseButton.Left, pos.x, pos.y, pos.x + 10, pos.y + 10)).toBe(1); + expect(await MouseGetPos()).toEqual({ x: pos.x + 10, y: pos.y + 10 }); + + expect(await WinWait(OK_TITLE, '', 1)).toBeGreaterThan(0); + expect(await ControlClick(OK_TITLE, '', POPUP_BUTTON)).toBe(1); + expect(await WinWaitClose(OK_TITLE, '', 1)).toBe(1); + + // Mouse wheel + await MouseWheel(ScrollDirection.Down, 20); + expect(await ControlGetText(APP_TITLE, '', EVENT_LABEL)).toContain('Mouse Wheel Down'); + + await MouseWheel(ScrollDirection.Up, 20); + expect(await ControlGetText(APP_TITLE, '', EVENT_LABEL)).toContain('Mouse Wheel Up'); + + // Mouse cursor + expect(await MouseGetCursor()).toBe(Cursor.Arrow); + }); + + it('finds a pixel on the screen', async () => { + expect(await WinActivate(APP_TITLE)).toBe(1); + const rect = await WinGetPos(APP_TITLE); + + expect(await PixelSearch(rect.left, rect.top, rect.right, rect.bottom, 0xf14f21, 0, 1)).toEqual({ + x: rect.left + 395, + y: rect.top + 546, + }); + + expect(await PixelSearch(rect.left, rect.top, rect.right, rect.bottom, 0x7fba00, 0, 1)).toEqual({ + x: rect.left + 420, + y: rect.top + 546, + }); + + expect(await PixelSearch(rect.left, rect.top, rect.right, rect.bottom, 0x00a3ee, 0, 1)).toEqual({ + x: rect.left + 395, + y: rect.top + 571, + }); + + expect(await PixelSearch(rect.left, rect.top, rect.right, rect.bottom, 0xfeb800, 0, 1)).toEqual({ + x: rect.left + 420, + y: rect.top + 571, + }); + + expect(await PixelSearch(rect.left, rect.top, rect.right, rect.bottom, 0x123456, 0, 1)).toEqual({ + x: -1, + y: -1, + }); + }); + + it('handles errors when searching for pixels', async () => { + expect(await WinActivate(APP_TITLE)).toBe(1); + const rect = await WinGetPos(APP_TITLE); + + const mockSelectObject = vi.spyOn(gdi32, 'SelectObject').mockResolvedValue(0n); + expect(await PixelSearch(rect.left, rect.top, rect.right, rect.bottom, 0xf14f21, 0, 1)).toEqual({ + x: -1, + y: -1, + }); + mockSelectObject.mockRestore(); + + const mockBitBlt = vi.spyOn(gdi32, 'BitBlt').mockResolvedValue(false); + expect(await PixelSearch(rect.left, rect.top, rect.right, rect.bottom, 0x7fba00, 0, 1)).toEqual({ + x: -1, + y: -1, + }); + mockBitBlt.mockRestore(); + + const mockGetDIBits = vi.spyOn(gdi32, 'GetDIBits').mockResolvedValue(0); + expect(await PixelSearch(rect.left, rect.top, rect.right, rect.bottom, 0x00a3ee, 0, 1)).toEqual({ + x: -1, + y: -1, + }); + mockGetDIBits.mockRestore(); + }); + + // TODO: Re-enable once async Tooltip is fixed + // it('displays a tooltip', async () => { + // expect(await Tooltip('Test Tooltip', 100, 100, 20, 500)).toBe(true); + // }); + + // it('handles errors when displaying a tooltip', async () => { + // const mockSendMessageW = vi.spyOn(user32, 'SendMessageW').mockResolvedValueOnce(0); + // expect(await Tooltip('Test Tooltip', 100, 100, 20, 500)).toBe(false); + // mockSendMessageW.mockRestore(); + + // const mockDestroyWindow = vi.spyOn(user32, 'DestroyWindow').mockResolvedValueOnce(false); + // expect(await Tooltip('Test Tooltip', 100, 100, 20, 500)).toBe(false); + // mockDestroyWindow.mockRestore(); + // }); +}); diff --git a/src/autoit-open-close.test.ts b/src/autoit-open-close.test.ts new file mode 100644 index 0000000..c23934b --- /dev/null +++ b/src/autoit-open-close.test.ts @@ -0,0 +1,153 @@ +import { statSync } from 'node:fs'; + +import { APP_TITLE, PROCESS_NAME, TEST_APP_PATH } from './@testing/test-constants'; +import { autoit } from './lib/autoit'; +import { ProcessClose, ProcessCloseSync } from './process-close'; +import { ProcessExists, ProcessExistsSync } from './process-exists'; +import { ProcessWait, ProcessWaitSync } from './process-wait'; +import { ProcessWaitClose, ProcessWaitCloseSync } from './process-wait-close'; +import { Run, RunSync } from './run'; +import { WinClose, WinCloseSync } from './win-close'; +import { WinCloseByHandle, WinCloseByHandleSync } from './win-close-by-handle'; +import { WinExists, WinExistsSync } from './win-exists'; +import { WinExistsByHandle, WinExistsByHandleSync } from './win-exists-by-handle'; +import { WinGetHandle, WinGetHandleSync } from './win-get-handle'; +import { WinKill, WinKillSync } from './win-kill'; +import { WinKillByHandle, WinKillByHandleSync } from './win-kill-by-handle'; +import { WinSetOnTop, WinSetOnTopSync } from './win-set-on-top'; +import { WinSetOnTopByHandle, WinSetOnTopByHandleSync } from './win-set-on-top-by-handle'; +import { WinWait, WinWaitSync } from './win-wait'; +import { WinWaitCloseByHandle, WinWaitCloseByHandleSync } from './win-wait-close-by-handle'; + +describe.sequential('AutoIt Open/Close @full', () => { + beforeAll(() => { + expect(statSync(TEST_APP_PATH).isFile()).toBe(true); + + autoit.load(); + }); + + afterAll(() => { + ProcessCloseSync('TestApp.exe'); + autoit.unload(); + }); + + it('runs and closes the program (sync)', () => { + RunSync(TEST_APP_PATH); + expect(WinWaitSync(APP_TITLE, '', 500)).toBe(1); + expect(WinCloseSync(APP_TITLE)).toBe(1); + expect(WinExistsSync(APP_TITLE)).toBe(false); + }); + + it('runs and closes the program by handle (sync)', () => { + RunSync(TEST_APP_PATH); + expect(WinWaitSync(APP_TITLE, '', 500)).toBe(1); + + const handle = WinGetHandleSync(APP_TITLE); + + expect(WinCloseByHandleSync(handle)).toBe(1); + expect(WinWaitCloseByHandleSync(handle)).toBe(1); + expect(WinExistsByHandleSync(handle)).toBe(false); + }); + + it('runs and kills the program (sync)', () => { + RunSync(TEST_APP_PATH); + expect(WinWaitSync(APP_TITLE, '', 500)).toBe(1); + expect(WinKillSync(APP_TITLE)).toBe(1); + expect(WinExistsSync(APP_TITLE)).toBe(false); + }); + + it('runs and kills the program by handle (sync)', () => { + RunSync(TEST_APP_PATH); + expect(WinWaitSync(APP_TITLE, '', 500)).toBe(1); + + const handle = WinGetHandleSync(APP_TITLE); + + expect(WinKillByHandleSync(handle)).toBe(1); + expect(WinExistsSync(APP_TITLE)).toBe(false); + }); + + it('runs and closes the process (sync)', () => { + RunSync(TEST_APP_PATH); + expect(ProcessWaitSync(PROCESS_NAME, 500)).toBe(1); + expect(ProcessExistsSync(PROCESS_NAME)).toBe(true); + expect(ProcessCloseSync(PROCESS_NAME)).toBe(1); + expect(ProcessWaitCloseSync(PROCESS_NAME)).toBe(1); + expect(ProcessExistsSync(PROCESS_NAME)).toBe(false); + }); + + it('sets the window on top (sync)', () => { + RunSync(TEST_APP_PATH); + expect(WinWaitSync(APP_TITLE, '', 500)).toBe(1); + + expect(WinSetOnTopSync(APP_TITLE, '', true)).toBe(1); + expect(WinSetOnTopSync(APP_TITLE, '', false)).toBe(1); + + const handle = WinGetHandleSync(APP_TITLE); + + expect(WinSetOnTopByHandleSync(handle, true)).toBe(1); + expect(WinSetOnTopByHandleSync(handle, false)).toBe(1); + + expect(WinCloseSync(APP_TITLE)).toBe(1); + expect(WinExistsSync(APP_TITLE)).toBe(false); + }); + + it('runs and closes the program (async)', async () => { + await Run(TEST_APP_PATH); + expect(await WinWait(APP_TITLE, '', 500)).toBe(1); + expect(await WinClose(APP_TITLE)).toBe(1); + expect(await WinExists(APP_TITLE)).toBe(false); + }); + + it('runs and closes the program (async) by handle', async () => { + await Run(TEST_APP_PATH); + expect(await WinWait(APP_TITLE, '', 500)).toBe(1); + + const handle = await WinGetHandle(APP_TITLE); + + expect(await WinCloseByHandle(handle)).toBe(1); + expect(await WinWaitCloseByHandle(handle)).toBe(1); + expect(await WinExistsByHandle(handle)).toBe(false); + }); + + it('runs and kills the program (async)', async () => { + await Run(TEST_APP_PATH); + expect(await WinWait(APP_TITLE, '', 500)).toBe(1); + expect(await WinKill(APP_TITLE)).toBe(1); + expect(await WinExists(APP_TITLE)).toBe(false); + }); + + it('runs and kills the program by handle (async)', async () => { + await Run(TEST_APP_PATH); + expect(await WinWait(APP_TITLE, '', 500)).toBe(1); + + const handle = await WinGetHandle(APP_TITLE); + + expect(await WinKillByHandle(handle)).toBe(1); + expect(await WinExists(APP_TITLE)).toBe(false); + }); + + it('runs and closes the process (async)', async () => { + await Run(TEST_APP_PATH); + expect(await ProcessWait(PROCESS_NAME, 500)).toBe(1); + expect(await ProcessExists(PROCESS_NAME)).toBe(true); + expect(await ProcessClose(PROCESS_NAME)).toBe(1); + expect(await ProcessWaitClose(PROCESS_NAME)).toBe(1); + expect(await ProcessExists(PROCESS_NAME)).toBe(false); + }); + + it('sets the window on top (async)', async () => { + RunSync(TEST_APP_PATH); + expect(await WinWait(APP_TITLE, '', 500)).toBe(1); + + expect(await WinSetOnTop(APP_TITLE, '', true)).toBe(1); + expect(await WinSetOnTop(APP_TITLE, '', false)).toBe(1); + + const handle = await WinGetHandle(APP_TITLE); + + expect(await WinSetOnTopByHandle(handle, true)).toBe(1); + expect(await WinSetOnTopByHandle(handle, false)).toBe(1); + + expect(await WinClose(APP_TITLE)).toBe(1); + expect(await WinExists(APP_TITLE)).toBe(false); + }); +}); diff --git a/src/autoit-sync.test.ts b/src/autoit-sync.test.ts new file mode 100644 index 0000000..d944c74 --- /dev/null +++ b/src/autoit-sync.test.ts @@ -0,0 +1,541 @@ +import { randomUUID } from 'node:crypto'; +import { statSync } from 'node:fs'; + +import { + ABOUT_EDIT, + APP_TITLE, + CANCEL_BUTTON, + CANCEL_TITLE, + EVENT_LABEL, + FIRST_NAME_EDIT, + LAST_NAME_EDIT, + LIST_VIEW, + OK_BUTTON, + OK_TITLE, + POPUP_BUTTON, + PROCESS_NAME, + STATIC_LABEL, + TEST_APP_PATH, + TREE_VIEW, +} from './@testing/test-constants'; +import { ClipGetSync } from './clip-get'; +import { ClipPutSync } from './clip-put'; +import { ControlClickSync } from './control-click'; +import { ControlClickByHandleSync } from './control-click-by-handle'; +import { ControlDisableSync } from './control-disable'; +import { ControlDisableByHandleSync } from './control-disable-by-handle'; +import { ControlEnableSync } from './control-enable'; +import { ControlEnableByHandleSync } from './control-enable-by-handle'; +import { ControlFocusSync } from './control-focus'; +import { ControlFocusByHandleSync } from './control-focus-by-handle'; +import { ControlGetFocusSync } from './control-get-focus'; +import { ControlGetFocusByHandleSync } from './control-get-focus-by-handle'; +import { ControlGetHandleSync } from './control-get-handle'; +import { ControlGetHandleAsTextSync } from './control-get-handle-as-text'; +import { ControlGetPosSync } from './control-get-pos'; +import { ControlGetPosByHandleSync } from './control-get-pos-by-handle'; +import { ControlGetTextSync } from './control-get-text'; +import { ControlGetTextByHandleSync } from './control-get-text-by-handle'; +import { ControlHideSync } from './control-hide'; +import { ControlHideByHandleSync } from './control-hide-by-handle'; +import { ControlListViewSync, ListViewCommand } from './control-list-view'; +import { ControlListViewByHandleSync } from './control-list-view-by-handles'; +import { ControlMoveSync } from './control-move'; +import { ControlMoveByHandleSync } from './control-move-by-handle'; +import { ControlSetTextSync } from './control-set-text'; +import { ControlSetTextByHandleSync } from './control-set-text-by-handle'; +import { ControlShowSync } from './control-show'; +import { ControlShowByHandleSync } from './control-show-by-handle'; +import { ControlTreeViewSync, TreeViewCommand } from './control-tree-view'; +import { ControlTreeViewByHandleSync } from './control-tree-view-by-handle'; +import { autoit } from './lib/autoit'; +import * as gdi32 from './lib/gdi32'; +import * as user32 from './lib/user32'; +import { MouseButton, MouseClickSync } from './mouse-click'; +import { MouseClickDragSync } from './mouse-click-drag'; +import { MouseDownSync } from './mouse-down'; +import { Cursor, MouseGetCursorSync } from './mouse-get-cursor'; +import { MouseGetPosSync } from './mouse-get-pos'; +import { MouseMoveSync } from './mouse-move'; +import { MouseUpSync } from './mouse-up'; +import { MouseWheelSync, ScrollDirection } from './mouse-wheel'; +import { PixelGetColorSync } from './pixel-get-color'; +import { PixelSearchSync } from './pixel-search'; +import { ProcessCloseSync } from './process-close'; +import { Priority, ProcessSetPrioritySync } from './process-set-priority'; +import { RunSync } from './run'; +import { StatusbarGetTextSync } from './statusbar-get-text'; +import { StatusbarGetTextByHandleSync } from './statusbar-get-text-by-handle'; +import { TooltipSync } from './tooltip'; +import { WinActivateSync } from './win-activate'; +import { WinGetClassListSync } from './win-get-class-list'; +import { WinGetClassListByHandleSync } from './win-get-class-list-by-handle'; +import { WinGetClientSizeSync } from './win-get-client-size'; +import { WinGetClientSizeByHandleSync } from './win-get-client-size-by-handle'; +import { WinGetHandleSync } from './win-get-handle'; +import { WinGetHandleAsTextSync } from './win-get-handle-as-text'; +import { WinGetPosSync } from './win-get-pos'; +import { WinGetPosByHandleSync } from './win-get-pos-by-handle'; +import { WinGetProcessSync } from './win-get-process'; +import { WinGetProcessByHandleSync } from './win-get-process-by-handle'; +import { WinGetStateSync } from './win-get-state'; +import { WinGetStateByHandleSync } from './win-get-state-by-handle'; +import { WinGetTextSync } from './win-get-text'; +import { WinGetTextByHandleSync } from './win-get-text-by-handle'; +import { WinGetTitleSync } from './win-get-title'; +import { WinGetTitleByHandleSync } from './win-get-title-by-handle'; +import { WinMenuSelectItemSync } from './win-menu-select-item'; +import { WinMenuSelectItemByHandleSync } from './win-menu-select-item-by-handle'; +import { WinMinimizeAllSync } from './win-minimize-all'; +import { WinMinimizeAllUndoSync } from './win-minimize-all-undo'; +import { WinMoveSync } from './win-move'; +import { WinMoveByHandleSync } from './win-move-by-handle'; +import { WinSetOnTopSync } from './win-set-on-top'; +import { StateFlag, WinSetStateSync } from './win-set-state'; +import { WinSetStateByHandleSync } from './win-set-state-by-handle'; +import { WinSetTitleSync } from './win-set-title'; +import { WinSetTitleByHandleSync } from './win-set-title-by-handle'; +import { WinSetTransSync } from './win-set-trans'; +import { WinSetTransByHandleSync } from './win-set-trans-by-handle'; +import { WinWaitSync } from './win-wait'; +import { WinWaitCloseSync } from './win-wait-close'; + +describe.sequential('AutoIt JS Synchronous API @full', () => { + let windowHandle: bigint; + + beforeAll(() => { + autoit.load(); + ProcessCloseSync('TestApp.exe'); + + expect(statSync(TEST_APP_PATH).isFile()).toBe(true); + + expect(RunSync(TEST_APP_PATH)).toBeGreaterThan(0); + expect(WinWaitSync(APP_TITLE, '', 10)).toBeGreaterThan(0); + expect(WinSetOnTopSync(APP_TITLE, '', true)).toBe(1); + + windowHandle = WinGetHandleSync(APP_TITLE, ''); + }); + + afterAll(() => { + ProcessCloseSync('TestApp.exe'); + autoit.unload(); + }); + + it('logs a warning if the library is loaded twice', () => { + // @ts-expect-error Testing private member + const loggerWarnSpy = vi.spyOn(autoit.logger, 'warn'); + + autoit.load(); + + expect(loggerWarnSpy).toHaveBeenCalledTimes(1); + expect(loggerWarnSpy).toHaveBeenCalledWith('AutoIt is already loaded'); + }); + + it('hides and shows the first name edit', () => { + const handle = ControlGetHandleSync(windowHandle, FIRST_NAME_EDIT); + + expect(ControlHideSync(APP_TITLE, '', FIRST_NAME_EDIT)).toBe(1); + expect(WinGetStateByHandleSync(handle).visible).toBe(false); + + expect(ControlShowSync(APP_TITLE, '', FIRST_NAME_EDIT)).toBe(1); + expect(WinGetStateByHandleSync(handle).visible).toBe(true); + + expect(ControlHideByHandleSync(windowHandle, handle)).toBe(1); + expect(WinGetStateByHandleSync(handle).visible).toBe(false); + + expect(ControlShowByHandleSync(windowHandle, handle)).toBe(1); + expect(WinGetStateByHandleSync(handle).visible).toBe(true); + }); + + it('disables and enables the last name edit', () => { + const handle = ControlGetHandleSync(windowHandle, LAST_NAME_EDIT); + + expect(ControlDisableSync(APP_TITLE, '', LAST_NAME_EDIT)).toBe(1); + expect(WinGetStateByHandleSync(handle).enabled).toBe(false); + + expect(ControlEnableSync(APP_TITLE, '', LAST_NAME_EDIT)).toBe(1); + expect(WinGetStateByHandleSync(handle).enabled).toBe(true); + + expect(ControlDisableByHandleSync(windowHandle, handle)).toBe(1); + expect(WinGetStateByHandleSync(handle).enabled).toBe(false); + + expect(ControlEnableByHandleSync(windowHandle, handle)).toBe(1); + expect(WinGetStateByHandleSync(handle).enabled).toBe(true); + }); + + it('moves and resizes the about edit', () => { + const handle = ControlGetHandleSync(windowHandle, ABOUT_EDIT); + const originalPos = ControlGetPosSync(APP_TITLE, '', ABOUT_EDIT); + + expect(ControlMoveSync(APP_TITLE, '', ABOUT_EDIT, 100, 100, 20, 20)).toBe(1); + + expect(ControlGetPosSync(APP_TITLE, '', ABOUT_EDIT)).toEqual({ + left: 100, + top: 100, + right: 120, + bottom: 120, + }); + + expect( + ControlMoveByHandleSync( + windowHandle, + handle, + originalPos.left, + originalPos.top, + originalPos.right - originalPos.left, + originalPos.bottom - originalPos.top, + ), + ).toBe(1); + + expect(ControlGetPosByHandleSync(windowHandle, ControlGetHandleSync(windowHandle, ABOUT_EDIT))).toEqual( + originalPos, + ); + }); + + it('reads from and writes to the clipboard', () => { + const uuid = randomUUID(); + + ClipPutSync(uuid); + + expect(ClipGetSync()).toBe(uuid); + expect(ClipGetSync(2)).toBe(uuid.slice(0, 2)); + }); + + it('focuses a control', () => { + const controlHandle = ControlGetHandleSync(windowHandle, LAST_NAME_EDIT); + + expect(ControlFocusSync(APP_TITLE, '', FIRST_NAME_EDIT)).toBe(1); + expect(ControlGetFocusSync(APP_TITLE)).toBe(FIRST_NAME_EDIT); + expect(ControlFocusByHandleSync(windowHandle, controlHandle)).toBe(1); + expect(ControlGetFocusByHandleSync(windowHandle)).toBe(LAST_NAME_EDIT); + }); + + it('clicks a button', () => { + expect(ControlClickSync(APP_TITLE, '', OK_BUTTON)).toBe(1); + expect(WinWaitSync(OK_TITLE, '', 1)).toBeGreaterThan(0); + + expect(ControlClickSync(OK_TITLE, '', POPUP_BUTTON)).toBe(1); + expect(WinWaitCloseSync(OK_TITLE, '', 1)).toBe(1); + + expect(ControlClickByHandleSync(windowHandle, ControlGetHandleSync(windowHandle, CANCEL_BUTTON))).toBe(1); + expect(WinWaitSync(CANCEL_TITLE, '', 1)).toBeGreaterThan(0); + + const cancelPopup = WinGetHandleSync(CANCEL_TITLE); + + expect(ControlClickByHandleSync(cancelPopup, ControlGetHandleSync(cancelPopup, POPUP_BUTTON))).toBe(1); + expect(WinWaitCloseSync(CANCEL_TITLE, '', 1)).toBe(1); + }); + + it('changes the window state', () => { + WinSetStateSync(APP_TITLE, '', StateFlag.Minimize); + expect(WinGetStateSync(APP_TITLE, '').minimized).toBe(true); + + WinSetStateByHandleSync(windowHandle, StateFlag.Restore); + expect(WinGetStateByHandleSync(windowHandle).minimized).toBe(false); + + WinSetStateByHandleSync(windowHandle, StateFlag.Hide); + expect(WinGetStateByHandleSync(windowHandle).visible).toBe(false); + + WinSetStateByHandleSync(windowHandle, StateFlag.Show); + expect(WinGetStateByHandleSync(windowHandle).visible).toBe(true); + + WinSetStateByHandleSync(windowHandle, StateFlag.Maximize); + expect(WinGetStateByHandleSync(windowHandle).maximized).toBe(true); + + WinSetStateByHandleSync(windowHandle, StateFlag.Restore); + expect(WinGetStateByHandleSync(windowHandle).maximized).toBe(false); + }); + + it('gets the handle as text', () => { + const handle = ControlGetHandleSync(windowHandle, TREE_VIEW); + const handleText = ControlGetHandleAsTextSync(APP_TITLE, '', TREE_VIEW); + + expect(handleText).toBe('0x' + handle.toString(16).padStart(16, '0').toUpperCase()); + expect(parseInt(handleText, 16)).toBe(Number(handle)); + }); + + it('sets the text of a control', () => { + expect(ControlSetTextSync(APP_TITLE, '', STATIC_LABEL, 'Test Label')).toBe(1); + expect(ControlGetTextSync(APP_TITLE, '', STATIC_LABEL)).toBe('Test Label'); + + const control = ControlGetHandleSync(windowHandle, STATIC_LABEL); + + expect(ControlSetTextByHandleSync(windowHandle, control, 'Static Label 1')).toBe(1); + expect(ControlGetTextByHandleSync(windowHandle, control)).toBe('Static Label 1'); + }); + + it('interacts with a list view', () => { + expect(ControlListViewSync(APP_TITLE, '', LIST_VIEW, ListViewCommand.GetItemCount)).toBe('50'); + expect(ControlListViewSync(APP_TITLE, '', LIST_VIEW, ListViewCommand.GetSubItemCount, '1')).toBe('4'); + + expect(ControlListViewSync(APP_TITLE, '', LIST_VIEW, ListViewCommand.SelectAll)).toBe('1'); + expect(ControlListViewSync(APP_TITLE, '', LIST_VIEW, ListViewCommand.GetSelectedCount)).toBe('50'); + + expect(ControlListViewSync(APP_TITLE, '', LIST_VIEW, ListViewCommand.SelectClear)).toBe('1'); + expect(ControlListViewSync(APP_TITLE, '', LIST_VIEW, ListViewCommand.GetSelectedCount)).toBe('0'); + + const handle = ControlGetHandleSync(windowHandle, LIST_VIEW); + + expect(ControlListViewByHandleSync(windowHandle, handle, ListViewCommand.Select, '1')).toBe('1'); + expect(ControlListViewByHandleSync(windowHandle, handle, ListViewCommand.IsSelected, '1')).toBe('1'); + expect(ControlListViewByHandleSync(windowHandle, handle, ListViewCommand.IsSelected, '2')).toBe('0'); + expect(ControlListViewByHandleSync(windowHandle, handle, ListViewCommand.SelectInvert)).toBe('1'); + expect(ControlListViewByHandleSync(windowHandle, handle, ListViewCommand.GetSelectedCount)).toBe('49'); + + expect(ControlListViewByHandleSync(windowHandle, handle, ListViewCommand.DeSelect, '0', '50')).toBe('1'); + expect(ControlListViewByHandleSync(windowHandle, handle, ListViewCommand.GetSelectedCount)).toBe('0'); + + expect(ControlListViewByHandleSync(windowHandle, handle, ListViewCommand.Select, '1', '20')).toBe('1'); + expect(ControlListViewByHandleSync(windowHandle, handle, ListViewCommand.GetSelected)).toBe('1'); + expect(ControlListViewByHandleSync(windowHandle, handle, ListViewCommand.GetSelected, '1')).toBe( + new Array(20) + .fill(0) + .map((_, i) => i + 1) + .join('|'), + ); + + expect(ControlListViewSync(APP_TITLE, '', LIST_VIEW, ListViewCommand.FindItem, 'unknown')).toBe('-1'); + expect(ControlListViewSync(APP_TITLE, '', LIST_VIEW, ListViewCommand.FindItem, 'R10 C1')).toBe('9'); + + // TODO: Figure out how to validate this + // expect(ControlListView(APP_TITLE, '', LIST_VIEW, ListViewCommand.ViewChange, 'details')).toBe('1'); + }); + + it('sets the title', () => { + const title = WinGetTitleSync(APP_TITLE); + + expect(title).toBe(APP_TITLE); + expect(WinSetTitleSync(APP_TITLE, '', 'Testing')).toBe(1); + + expect(WinSetTitleByHandleSync(windowHandle, 'TestApp')).toBe(1); + expect(WinGetTitleByHandleSync(windowHandle)).toBe('TestApp'); + + expect(WinSetTitleByHandleSync(windowHandle, APP_TITLE)).toBe(1); + }); + + it('moves the window', () => { + expect(WinMoveSync(APP_TITLE, '', 100, 100)).toBe(1); + + const pos = WinGetPosSync(APP_TITLE); + + expect(pos.left).toBe(100); + expect(pos.top).toBe(100); + + expect(WinMoveByHandleSync(windowHandle, 200, 200)).toBe(1); + + const newPos = WinGetPosByHandleSync(windowHandle); + + expect(newPos.left).toBe(200); + expect(newPos.top).toBe(200); + }); + + it('selects a menu option', () => { + expect(WinMenuSelectItemSync(APP_TITLE, '', '&Help', '&About')).toBe(1); + expect(WinWaitSync('About TestApp', '', 1)).toBeGreaterThan(0); + expect(ControlClickSync('About TestApp', '', 'Button1')).toBe(1); + + expect(WinMenuSelectItemByHandleSync(windowHandle, '&Help', '&About')).toBe(1); + expect(WinWaitSync('About TestApp', '', 1)).toBeGreaterThan(0); + expect(ControlClickSync('About TestApp', '', 'Button1')).toBe(1); + }); + + it('gets the status bar text', () => { + expect(StatusbarGetTextSync(APP_TITLE, '', 2)).toBe(' Status 1'); + expect(StatusbarGetTextByHandleSync(windowHandle, 3)).toBe(' Status 2'); + }); + + it('gets the color of a pixel', () => { + expect(WinActivateSync(APP_TITLE)).toBe(1); + const rect = WinGetPosSync(APP_TITLE); + + expect(PixelGetColorSync(rect.right - 25, rect.bottom - 45)).toBe(0xfeb800); + }); + + it('sets the transparency of the window', () => { + expect(WinSetTransSync(APP_TITLE, '', 127)).toBe(1); + expect(WinSetTransByHandleSync(windowHandle, 255)).toBe(1); + }); + + it('gets the text of the window', () => { + const windowText = WinGetTextSync(APP_TITLE); + + expect(windowText.length).toBeGreaterThan(100); + expect(WinGetTextByHandleSync(windowHandle)).toBe(windowText); + expect(WinGetTextSync(APP_TITLE, '', 100)).toBe(windowText.slice(0, 100)); + expect(WinGetTextByHandleSync(windowHandle, 100)).toBe(windowText.slice(0, 100)); + }); + + it('sets the process priority', () => { + expect(ProcessSetPrioritySync(PROCESS_NAME, Priority.High)).toBe(1); + expect(ProcessSetPrioritySync(PROCESS_NAME, Priority.Normal)).toBe(1); + }); + + it('gets the process ID of the window', () => { + const processId = WinGetProcessSync(APP_TITLE); + expect(processId).toBeGreaterThan(0); + expect(WinGetProcessByHandleSync(windowHandle)).toBe(processId); + }); + + it('gets the window handle', () => { + const handle = WinGetHandleSync(APP_TITLE); + const textHandle = WinGetHandleAsTextSync(APP_TITLE); + + expect(handle).toBe(windowHandle); + expect(parseInt(textHandle, 16)).toBe(Number(windowHandle)); + }); + + it('gets the client size', () => { + const rect = WinGetClientSizeSync(APP_TITLE); + + expect(rect).toEqual(WinGetClientSizeByHandleSync(windowHandle)); + }); + + it('minimizes and restores all windows', () => { + expect(WinMinimizeAllSync()).toBe(undefined); + expect(WinMinimizeAllUndoSync()).toBe(undefined); + }); + + it('gets the class list of the window', () => { + const classList = WinGetClassListSync(APP_TITLE); + expect(WinGetClassListByHandleSync(windowHandle)).toBe(classList); + }); + + it('interacts with a tree view', () => { + expect(ControlTreeViewSync(APP_TITLE, '', TREE_VIEW, TreeViewCommand.GetItemCount)).toBe('1'); + expect(ControlTreeViewSync(APP_TITLE, '', TREE_VIEW, TreeViewCommand.Exists, 'Root|Child 1')).toBe('1'); + expect(ControlTreeViewSync(APP_TITLE, '', TREE_VIEW, TreeViewCommand.Expand, 'Root|Child 2')).toBe('1'); + expect(ControlTreeViewSync(APP_TITLE, '', TREE_VIEW, TreeViewCommand.GetItemCount, 'Root|Child 2')).toBe( + '3', + ); + + const handle = ControlGetHandleSync(windowHandle, TREE_VIEW); + + expect( + ControlTreeViewByHandleSync(windowHandle, handle, TreeViewCommand.Select, 'Root|Child 2|Child 2.2'), + ).toBe('1'); + expect(ControlTreeViewByHandleSync(windowHandle, handle, TreeViewCommand.GetSelected, '')).toBe( + 'Root|Child 2|Child 2.2', + ); + expect( + ControlTreeViewByHandleSync(windowHandle, handle, TreeViewCommand.GetText, 'Root|Child 2|Child 2.2'), + ).toBe('Child 2.2'); + }); + + it('uses the mouse', () => { + const handle = ControlGetHandleSync(windowHandle, OK_BUTTON); + const windowRect = WinGetPosSync(APP_TITLE); + const buttonRect = ControlGetPosByHandleSync(windowHandle, handle); + + const x = windowRect.left + buttonRect.left + 10; + const y = windowRect.top + buttonRect.top + 10 + 43; // title bar height + menu height = 43 + + // Mouse move + expect(MouseMoveSync(x, y)).toBe(1); + expect(MouseGetPosSync()).toEqual({ x, y }); + + // Mouse down/up + MouseDownSync(MouseButton.Left); + MouseUpSync(MouseButton.Left); + + expect(WinWaitSync(OK_TITLE, '', 1)).toBeGreaterThan(0); + expect(ControlClickSync(OK_TITLE, '', POPUP_BUTTON)).toBe(1); + expect(WinWaitCloseSync(OK_TITLE, '', 1)).toBe(1); + + // Mouse click + expect(MouseClickSync(MouseButton.Left, x, y)).toBe(1); + + expect(WinWaitSync(OK_TITLE, '', 1)).toBeGreaterThan(0); + expect(ControlClickSync(OK_TITLE, '', POPUP_BUTTON)).toBe(1); + expect(WinWaitCloseSync(OK_TITLE, '', 1)).toBe(1); + + // Mouse drag + const pos = MouseGetPosSync(); + + expect(MouseClickDragSync(MouseButton.Left, pos.x, pos.y, pos.x + 10, pos.y + 10)).toBe(1); + expect(MouseGetPosSync()).toEqual({ x: pos.x + 10, y: pos.y + 10 }); + + expect(WinWaitSync(OK_TITLE, '', 1)).toBeGreaterThan(0); + expect(ControlClickSync(OK_TITLE, '', POPUP_BUTTON)).toBe(1); + expect(WinWaitCloseSync(OK_TITLE, '', 1)).toBe(1); + + // Mouse wheel + MouseWheelSync(ScrollDirection.Down, 20); + expect(ControlGetTextSync(APP_TITLE, '', EVENT_LABEL)).toContain('Mouse Wheel Down'); + + MouseWheelSync(ScrollDirection.Up, 20); + expect(ControlGetTextSync(APP_TITLE, '', EVENT_LABEL)).toContain('Mouse Wheel Up'); + + // Mouse cursor + expect(MouseGetCursorSync()).toBe(Cursor.Arrow); + }); + + it('finds a pixel on the screen', () => { + expect(WinActivateSync(APP_TITLE)).toBe(1); + const rect = WinGetPosSync(APP_TITLE); + + expect(PixelSearchSync(rect.left, rect.top, rect.right, rect.bottom, 0xf14f21, 0, 1)).toEqual({ + x: rect.left + 395, + y: rect.top + 546, + }); + + expect(PixelSearchSync(rect.left, rect.top, rect.right, rect.bottom, 0x7fba00, 0, 1)).toEqual({ + x: rect.left + 420, + y: rect.top + 546, + }); + + expect(PixelSearchSync(rect.left, rect.top, rect.right, rect.bottom, 0x00a3ee, 0, 1)).toEqual({ + x: rect.left + 395, + y: rect.top + 571, + }); + + expect(PixelSearchSync(rect.left, rect.top, rect.right, rect.bottom, 0xfeb800, 0, 1)).toEqual({ + x: rect.left + 420, + y: rect.top + 571, + }); + + expect(PixelSearchSync(rect.left, rect.top, rect.right, rect.bottom, 0x123456, 0, 1)).toEqual({ + x: -1, + y: -1, + }); + }); + + it('handles errors when searching for pixels', () => { + expect(WinActivateSync(APP_TITLE)).toBe(1); + const rect = WinGetPosSync(APP_TITLE); + + const mockSelectObjectSync = vi.spyOn(gdi32, 'SelectObjectSync').mockReturnValue(0n); + expect(PixelSearchSync(rect.left, rect.top, rect.right, rect.bottom, 0xf14f21, 0, 1)).toEqual({ + x: -1, + y: -1, + }); + mockSelectObjectSync.mockRestore(); + + const mockBitBltSync = vi.spyOn(gdi32, 'BitBltSync').mockReturnValue(false); + expect(PixelSearchSync(rect.left, rect.top, rect.right, rect.bottom, 0x7fba00, 0, 1)).toEqual({ + x: -1, + y: -1, + }); + mockBitBltSync.mockRestore(); + + const mockGetDIBitsSync = vi.spyOn(gdi32, 'GetDIBitsSync').mockReturnValue(0); + expect(PixelSearchSync(rect.left, rect.top, rect.right, rect.bottom, 0x00a3ee, 0, 1)).toEqual({ + x: -1, + y: -1, + }); + mockGetDIBitsSync.mockRestore(); + }); + + it('displays a tooltip', () => { + expect(TooltipSync('Test Tooltip', 100, 100, 20, 500)).toBe(true); + }); + + it('handles errors when displaying a tooltip', () => { + const mockSendMessageWSync = vi.spyOn(user32, 'SendMessageWSync').mockReturnValueOnce(0); + expect(TooltipSync('Test Tooltip', 100, 100, 20, 500)).toBe(false); + mockSendMessageWSync.mockRestore(); + + const mockDestroyWindowSync = vi.spyOn(user32, 'DestroyWindowSync').mockReturnValueOnce(false); + expect(TooltipSync('Test Tooltip', 100, 100, 20, 500)).toBe(false); + mockDestroyWindowSync.mockRestore(); + }); +}); diff --git a/src/autoit.test.ts b/src/autoit.test.ts deleted file mode 100644 index 28bbe0a..0000000 --- a/src/autoit.test.ts +++ /dev/null @@ -1,327 +0,0 @@ -import { randomUUID } from 'node:crypto'; -import { statSync } from 'node:fs'; -import { join } from 'node:path'; - -import { ClipGet } from './clip-get'; -import { ClipPut } from './clip-put'; -import { ControlClick } from './control-click'; -import { ControlClickByHandle } from './control-click-by-handle'; -import { ControlDisable } from './control-disable'; -import { ControlDisableByHandle } from './control-disable-by-handle'; -import { ControlEnable } from './control-enable'; -import { ControlEnableByHandle } from './control-enable-by-handle'; -import { ControlFocus } from './control-focus'; -import { ControlFocusByHandle } from './control-focus-by-handle'; -import { ControlGetFocus } from './control-get-focus'; -import { ControlGetFocusByHandle } from './control-get-focus-by-handle'; -import { ControlGetHandle } from './control-get-handle'; -import { ControlGetHandleAsText } from './control-get-handle-as-text'; -import { ControlGetPos } from './control-get-pos'; -import { ControlGetPosByHandle } from './control-get-pos-by-handle'; -import { ControlGetText } from './control-get-text'; -import { ControlGetTextByHandle } from './control-get-text-by-handle'; -import { ControlHide } from './control-hide'; -import { ControlHideByHandle } from './control-hide-by-handle'; -import { ControlListView, ListViewCommand } from './control-list-view'; -import { ControlMove } from './control-move'; -import { ControlMoveByHandle } from './control-move-by-handle'; -import { ControlSetText } from './control-set-text'; -import { ControlSetTextByHandle } from './control-set-text-by-handle'; -import { ControlShow } from './control-show'; -import { ControlShowByHandle } from './control-show-by-handle'; -import { autoit } from './lib/autoit'; -import { PixelGetColor } from './pixel-get-color'; -import { ProcessClose } from './process-close'; -import { Run } from './run'; -import { StatusbarGetText } from './statusbar-get-text'; -import { StatusbarGetTextByHandle } from './statusbar-get-text-by-handle'; -import { WinActivate } from './win-activate'; -import { WinGetHandle } from './win-get-handle'; -import { WinGetPos } from './win-get-pos'; -import { WinGetPosByHandle } from './win-get-pos-by-handle'; -import { WinGetState } from './win-get-state'; -import { WinGetStateByHandle } from './win-get-state-by-handle'; -import { WinGetTitle } from './win-get-title'; -import { WinGetTitleByHandle } from './win-get-title-by-handle'; -import { WinMenuSelectItem } from './win-menu-select-item'; -import { WinMenuSelectItemByHandle } from './win-menu-select-item-by-handle'; -import { WinMove } from './win-move'; -import { WinMoveByHandle } from './win-move-by-handle'; -import { WinSetTitleByHandle } from './win-set-new-title-by-handle'; -import { WinSetOnTop } from './win-set-on-top'; -import { StateFlag, WinSetState } from './win-set-state'; -import { WinSetStateByHandle } from './win-set-state-by-handle'; -import { WinSetTitle } from './win-set-title'; -import { WinSetTrans } from './win-set-trans'; -import { WinSetTransByHandle } from './win-set-trans-by-handle'; -import { WinWait } from './win-wait'; -import { WinWaitClose } from './win-wait-close'; - -describe.sequential('AutoIt JS @full', () => { - let windowHandle: bigint; - - const APP_TITLE = 'TestApp'; - const FIRST_NAME_EDIT = 'Edit1'; - const LAST_NAME_EDIT = 'Edit2'; - const ABOUT_EDIT = 'Edit3'; - const TREE_VIEW = 'SysTreeView321'; - const OK_BUTTON = 'Button1'; - const CANCEL_BUTTON = 'Button2'; - const LIST_VIEW = 'SysListView321'; - const STATIC_LABEL = 'Static1'; - const OK_TITLE = 'OK'; - const CANCEL_TITLE = 'Cancel'; - const POPUP_BUTTON = 'Button1'; - - beforeAll(() => { - autoit.load(); - ProcessClose('TestApp.exe'); - - const testAppPath = join(__dirname, '..', 'bin', 'TestApp.exe'); - expect(statSync(testAppPath).isFile()).toBe(true); - - expect(Run(testAppPath)).toBeGreaterThan(0); - expect(WinWait(APP_TITLE, '', 10)).toBeGreaterThan(0); - expect(WinSetOnTop(APP_TITLE, '', true)).toBe(1); - - windowHandle = WinGetHandle(APP_TITLE, ''); - }); - - afterAll(() => { - ProcessClose('TestApp.exe'); - autoit.unload(); - }); - - it('logs a warning if the library is loaded twice', () => { - // @ts-expect-error Testing private member - const loggerWarnSpy = vi.spyOn(autoit.logger, 'warn'); - - autoit.load(); - - expect(loggerWarnSpy).toHaveBeenCalledTimes(1); - expect(loggerWarnSpy).toHaveBeenCalledWith('AutoIt is already loaded'); - }); - - it('hides and shows the first name edit', () => { - const handle = ControlGetHandle(windowHandle, FIRST_NAME_EDIT); - - expect(ControlHide(APP_TITLE, '', FIRST_NAME_EDIT)).toBe(1); - expect(WinGetStateByHandle(handle).visible).toBe(false); - - expect(ControlShow(APP_TITLE, '', FIRST_NAME_EDIT)).toBe(1); - expect(WinGetStateByHandle(handle).visible).toBe(true); - - expect(ControlHideByHandle(windowHandle, handle)).toBe(1); - expect(WinGetStateByHandle(handle).visible).toBe(false); - - expect(ControlShowByHandle(windowHandle, handle)).toBe(1); - expect(WinGetStateByHandle(handle).visible).toBe(true); - }); - - it('disables and enables the last name edit', () => { - const handle = ControlGetHandle(windowHandle, LAST_NAME_EDIT); - - expect(ControlDisable(APP_TITLE, '', LAST_NAME_EDIT)).toBe(1); - expect(WinGetStateByHandle(handle).enabled).toBe(false); - - expect(ControlEnable(APP_TITLE, '', LAST_NAME_EDIT)).toBe(1); - expect(WinGetStateByHandle(handle).enabled).toBe(true); - - expect(ControlDisableByHandle(windowHandle, handle)).toBe(1); - expect(WinGetStateByHandle(handle).enabled).toBe(false); - - expect(ControlEnableByHandle(windowHandle, handle)).toBe(1); - expect(WinGetStateByHandle(handle).enabled).toBe(true); - }); - - it('moves and resizes the about edit', () => { - const handle = ControlGetHandle(windowHandle, ABOUT_EDIT); - const originalPos = ControlGetPos(APP_TITLE, '', ABOUT_EDIT); - - expect(ControlMove(APP_TITLE, '', ABOUT_EDIT, 100, 100, 20, 20)).toBe(1); - - expect(ControlGetPos(APP_TITLE, '', ABOUT_EDIT)).toEqual({ - left: 100, - top: 100, - right: 120, - bottom: 120, - }); - - expect( - ControlMoveByHandle( - windowHandle, - handle, - originalPos.left, - originalPos.top, - originalPos.right - originalPos.left, - originalPos.bottom - originalPos.top, - ), - ).toBe(1); - - expect(ControlGetPosByHandle(windowHandle, ControlGetHandle(windowHandle, ABOUT_EDIT))).toEqual( - originalPos, - ); - }); - - it('reads from and writes to the clipboard', () => { - const uuid = randomUUID(); - - ClipPut(uuid); - - expect(ClipGet()).toBe(uuid); - expect(ClipGet(2)).toBe(uuid.slice(0, 2)); - }); - - it('focuses a control', () => { - const controlHandle = ControlGetHandle(windowHandle, LAST_NAME_EDIT); - - expect(ControlFocus(APP_TITLE, '', FIRST_NAME_EDIT)).toBe(1); - expect(ControlGetFocus(APP_TITLE)).toBe(FIRST_NAME_EDIT); - expect(ControlFocusByHandle(windowHandle, controlHandle)).toBe(1); - expect(ControlGetFocusByHandle(windowHandle)).toBe(LAST_NAME_EDIT); - }); - - it('clicks a button', () => { - expect(ControlClick(APP_TITLE, '', OK_BUTTON)).toBe(1); - expect(WinWait(OK_TITLE, '', 1)).toBeGreaterThan(0); - - expect(ControlClick(OK_TITLE, '', POPUP_BUTTON)).toBe(1); - expect(WinWaitClose(OK_TITLE, '', 1)).toBe(1); - - expect(ControlClickByHandle(windowHandle, ControlGetHandle(windowHandle, CANCEL_BUTTON))).toBe(1); - expect(WinWait(CANCEL_TITLE, '', 1)).toBeGreaterThan(0); - - const cancelPopup = WinGetHandle(CANCEL_TITLE); - - expect(ControlClickByHandle(cancelPopup, ControlGetHandle(cancelPopup, POPUP_BUTTON))).toBe(1); - expect(WinWaitClose(CANCEL_TITLE, '', 1)).toBe(1); - }); - - it('changes the window state', () => { - WinSetState(APP_TITLE, '', StateFlag.Minimize); - expect(WinGetState(APP_TITLE, '').minimized).toBe(true); - - WinSetStateByHandle(windowHandle, StateFlag.Restore); - expect(WinGetStateByHandle(windowHandle).minimized).toBe(false); - - WinSetStateByHandle(windowHandle, StateFlag.Hide); - expect(WinGetStateByHandle(windowHandle).visible).toBe(false); - - WinSetStateByHandle(windowHandle, StateFlag.Show); - expect(WinGetStateByHandle(windowHandle).visible).toBe(true); - - WinSetStateByHandle(windowHandle, StateFlag.Maximize); - expect(WinGetStateByHandle(windowHandle).maximized).toBe(true); - - WinSetStateByHandle(windowHandle, StateFlag.Restore); - expect(WinGetStateByHandle(windowHandle).maximized).toBe(false); - }); - - it('gets the handle as text', () => { - const handle = ControlGetHandle(windowHandle, TREE_VIEW); - const handleText = ControlGetHandleAsText(APP_TITLE, '', TREE_VIEW); - - expect(handleText).toBe('0x' + handle.toString(16).padStart(16, '0').toUpperCase()); - expect(parseInt(handleText, 16)).toBe(Number(handle)); - }); - - it('sets the text of a control', () => { - expect(ControlSetText(APP_TITLE, '', STATIC_LABEL, 'Test Label')).toBe(1); - expect(ControlGetText(APP_TITLE, '', STATIC_LABEL)).toBe('Test Label'); - - const control = ControlGetHandle(windowHandle, STATIC_LABEL); - - expect(ControlSetTextByHandle(windowHandle, control, 'Static Label 1')).toBe(1); - expect(ControlGetTextByHandle(windowHandle, control)).toBe('Static Label 1'); - }); - - it('interacts with a list view', () => { - expect(ControlListView(APP_TITLE, '', LIST_VIEW, ListViewCommand.GetItemCount)).toBe('50'); - expect(ControlListView(APP_TITLE, '', LIST_VIEW, ListViewCommand.GetSubItemCount, '1')).toBe('4'); - - expect(ControlListView(APP_TITLE, '', LIST_VIEW, ListViewCommand.SelectAll)).toBe('1'); - expect(ControlListView(APP_TITLE, '', LIST_VIEW, ListViewCommand.GetSelectedCount)).toBe('50'); - - expect(ControlListView(APP_TITLE, '', LIST_VIEW, ListViewCommand.SelectClear)).toBe('1'); - expect(ControlListView(APP_TITLE, '', LIST_VIEW, ListViewCommand.GetSelectedCount)).toBe('0'); - - expect(ControlListView(APP_TITLE, '', LIST_VIEW, ListViewCommand.Select, '1')).toBe('1'); - expect(ControlListView(APP_TITLE, '', LIST_VIEW, ListViewCommand.IsSelected, '1')).toBe('1'); - expect(ControlListView(APP_TITLE, '', LIST_VIEW, ListViewCommand.IsSelected, '2')).toBe('0'); - expect(ControlListView(APP_TITLE, '', LIST_VIEW, ListViewCommand.SelectInvert)).toBe('1'); - expect(ControlListView(APP_TITLE, '', LIST_VIEW, ListViewCommand.GetSelectedCount)).toBe('49'); - - expect(ControlListView(APP_TITLE, '', LIST_VIEW, ListViewCommand.DeSelect, '0', '50')).toBe('1'); - expect(ControlListView(APP_TITLE, '', LIST_VIEW, ListViewCommand.GetSelectedCount)).toBe('0'); - - expect(ControlListView(APP_TITLE, '', LIST_VIEW, ListViewCommand.Select, '1', '20')).toBe('1'); - expect(ControlListView(APP_TITLE, '', LIST_VIEW, ListViewCommand.GetSelected)).toBe('1'); - expect(ControlListView(APP_TITLE, '', LIST_VIEW, ListViewCommand.GetSelected, '1')).toBe( - new Array(20) - .fill(0) - .map((_, i) => i + 1) - .join('|'), - ); - - expect(ControlListView(APP_TITLE, '', LIST_VIEW, ListViewCommand.FindItem, 'unknown')).toBe('-1'); - expect(ControlListView(APP_TITLE, '', LIST_VIEW, ListViewCommand.FindItem, 'R10 C1')).toBe('9'); - - // TODO: Figure out how to validate this - // expect(ControlListView(APP_TITLE, '', LIST_VIEW, ListViewCommand.ViewChange, 'details')).toBe('1'); - }); - - it('sets the title', () => { - const title = WinGetTitle(APP_TITLE); - - expect(title).toBe(APP_TITLE); - expect(WinSetTitle(APP_TITLE, '', 'Testing')).toBe(1); - - expect(WinSetTitleByHandle(windowHandle, 'TestApp')).toBe(1); - expect(WinGetTitleByHandle(windowHandle)).toBe('TestApp'); - - expect(WinSetTitleByHandle(windowHandle, APP_TITLE)).toBe(1); - }); - - it('moves the window', () => { - expect(WinMove(APP_TITLE, '', 100, 100)).toBe(1); - - const pos = WinGetPos(APP_TITLE); - - expect(pos.left).toBe(100); - expect(pos.top).toBe(100); - - expect(WinMoveByHandle(windowHandle, 200, 200)).toBe(1); - - const newPos = WinGetPosByHandle(windowHandle); - - expect(newPos.left).toBe(200); - expect(newPos.top).toBe(200); - }); - - it('selects a menu option', () => { - expect(WinMenuSelectItem(APP_TITLE, '', '&Help', '&About')).toBe(1); - expect(WinWait('About TestApp', '', 1)).toBeGreaterThan(0); - expect(ControlClick('About TestApp', '', 'Button1')).toBe(1); - - expect(WinMenuSelectItemByHandle(windowHandle, '&Help', '&About')).toBe(1); - expect(WinWait('About TestApp', '', 1)).toBeGreaterThan(0); - expect(ControlClick('About TestApp', '', 'Button1')).toBe(1); - }); - - it('gets the status bar text', () => { - expect(StatusbarGetText(APP_TITLE, '', 2)).toBe(' Status 1'); - expect(StatusbarGetTextByHandle(windowHandle, 3)).toBe(' Status 2'); - }); - - it('gets the color of a pixel', () => { - expect(WinActivate(APP_TITLE)).toBe(1); - const rect = WinGetPos(APP_TITLE); - - expect(PixelGetColor(rect.right - 25, rect.bottom - 45)).toBe(0xfeb800); - }); - - it('sets the transparency of the window', () => { - expect(WinSetTrans(APP_TITLE, '', 127)).toBe(1); - expect(WinSetTransByHandle(windowHandle, 255)).toBe(1); - }); -}); diff --git a/src/clip-get.ts b/src/clip-get.ts index ad6d777..ea212da 100644 --- a/src/clip-get.ts +++ b/src/clip-get.ts @@ -11,12 +11,12 @@ import { createUnicodeBuffer, unicodeBufferToString } from './util/buffer.util'; * * @example * ```typescript - * import { ClipGet } from '@ahmic/autoit-js'; + * import { ClipGetSync } from '@ahmic/autoit-js'; * * // Assuming the text "Hello" is in the clipboard * * for (let i = 0; i < 5; i++) { - * console.log(ClipGet(i + 1)); + * console.log(ClipGetSync(i + 1)); * } * * // Output: @@ -29,10 +29,45 @@ import { createUnicodeBuffer, unicodeBufferToString } from './util/buffer.util'; * * @see https://www.autoitscript.com/autoit3/docs/functions/ClipGet.htm */ -export function ClipGet(characterCount: number = 2048): string { +export function ClipGetSync(characterCount: number = 2048): string { const [buffer, length] = createUnicodeBuffer(characterCount); autoit.invoke('AU3_ClipGet', VOID, [LPWSTR, INT], [buffer, length]); return unicodeBufferToString(buffer); } + +/** + * Retrieves text from the clipboard. + * + * @param characterCount The maximum number of characters to retrieve. Default is 2048. + * + * @returns A promise that resolves to the text from the clipboard. + * + * @example + * ```typescript + * import { ClipGet } from '@ahmic/autoit-js'; + * + * // Assuming the text "Hello" is in the clipboard + * + * for (let i = 0; i < 5; i++) { + * console.log(await ClipGet(i + 1)); + * } + * + * // Output: + * // H + * // He + * // Hel + * // Hell + * // Hello + * ``` + * + * @see https://www.autoitscript.com/autoit3/docs/functions/ClipGet.htm + */ +export async function ClipGet(characterCount: number = 2048): Promise { + const [buffer, length] = createUnicodeBuffer(characterCount); + + await autoit.invokeAsync('AU3_ClipGet', VOID, [LPWSTR, INT], [buffer, length]); + + return unicodeBufferToString(buffer); +} diff --git a/src/clip-put.ts b/src/clip-put.ts index b0c7474..e5f52f1 100644 --- a/src/clip-put.ts +++ b/src/clip-put.ts @@ -1,6 +1,26 @@ import { LPCWSTR, VOID } from './@types'; import { autoit } from './lib/autoit'; +/** + * Writes text to the clipboard. + * + * @param value The text to put in the clipboard. + * + * @example + * ```typescript + * import { ClipPutSync, ClipGetSync } from '@ahmic/autoit-js'; + * + * ClipPutSync('Hello'); + * + * console.log(ClipGetSync()); // Outputs: Hello + * ``` + * + * @see https://www.autoitscript.com/autoit3/docs/functions/ClipPut.htm + */ +export function ClipPutSync(value: string): void { + return autoit.invoke('AU3_ClipPut', VOID, [LPCWSTR], [value]); +} + /** * Writes text to the clipboard. * @@ -17,6 +37,6 @@ import { autoit } from './lib/autoit'; * * @see https://www.autoitscript.com/autoit3/docs/functions/ClipPut.htm */ -export function ClipPut(value: string): void { - return autoit.invoke('AU3_ClipPut', VOID, [LPCWSTR], [value]); +export function ClipPut(value: string): Promise { + return autoit.invokeAsync('AU3_ClipPut', VOID, [LPCWSTR], [value]); } diff --git a/src/control-click-by-handle.ts b/src/control-click-by-handle.ts index ec6b4a4..1d4ca93 100644 --- a/src/control-click-by-handle.ts +++ b/src/control-click-by-handle.ts @@ -3,6 +3,62 @@ import { autoit } from './lib/autoit'; import { MouseButton } from './mouse-click'; import { AU3_INTDEFAULT } from './util/constants'; +/** + * Simulates a mouse click on a control. Unlike {@linkcode MouseClickSync}, `ControlClickByHandle` won't move + * the mouse cursor but is capable of clicking on controls that may be obscured by other windows. + * + * Where possible, you should prefer using this function over {@linkcode ControlClickSync} to avoid potential + * issues with ambiguous window and control titles. + * + * @param windowHandle The handle of the window to access. + * @param controlHandle The handle of the control to interact with. + * @param button The mouse button to click. Default is {@linkcode MouseButton.Left}. + * @param clicks The number of times to click the mouse. Default is 1. + * @param x The x position to click within the control. Default is the center. + * @param y The y position to click within the control. Default is the center. + * + * @returns 1 if success, 0 if failed. + * + * @example + * ```typescript + * import { + * ControlClickByHandleSync, + * ControlGetHandleSync, + * MouseButton, + * WinGetHandleSync, + * } from '@ahmic/autoit-js'; + * + * const windowHandle = WinGetHandleSync('Untitled - Notepad'); + * const controlHandle = ControlGetHandleSync(windowHandle, 'Edit1'); + * + * // Click the Notepad window's edit control. + * ControlClickByHandleSync(windowHandle, controlHandle); + * + * // Right click the Notepad window's edit control. + * ControlClickByHandleSync(windowHandle, controlHandle, MouseButton.Right); + * + * // Double click the Notepad window's edit control. + * ControlClickByHandleSync(windowHandle, controlHandle, MouseButton.Left, 2); + * ``` + * + * @see https://www.autoitscript.com/autoit3/docs/functions/ControlClick.htm + */ +export function ControlClickByHandleSync( + windowHandle: bigint, + controlHandle: bigint, + button: MouseButton = MouseButton.Left, + clicks: number = 1, + x: number = AU3_INTDEFAULT, + y: number = AU3_INTDEFAULT, +): number { + return autoit.invoke( + 'AU3_ControlClickByHandle', + INT, + [HWND, HWND, LPCWSTR, INT, INT, INT], + [windowHandle, controlHandle, button, clicks, x, y], + ); +} + /** * Simulates a mouse click on a control. Unlike {@linkcode MouseClick}, `ControlClickByHandle` won't move the * mouse cursor but is capable of clicking on controls that may be obscured by other windows. @@ -17,7 +73,7 @@ import { AU3_INTDEFAULT } from './util/constants'; * @param x The x position to click within the control. Default is the center. * @param y The y position to click within the control. Default is the center. * - * @returns 1 if success, 0 if failed. + * @returns A promise that resolves to 1 if success, or 0 if failed. * * @example * ```typescript @@ -45,8 +101,8 @@ export function ControlClickByHandle( clicks: number = 1, x: number = AU3_INTDEFAULT, y: number = AU3_INTDEFAULT, -): number { - return autoit.invoke( +): Promise { + return autoit.invokeAsync( 'AU3_ControlClickByHandle', INT, [HWND, HWND, LPCWSTR, INT, INT, INT], diff --git a/src/control-click.ts b/src/control-click.ts index 627aeb3..dc0a0b4 100644 --- a/src/control-click.ts +++ b/src/control-click.ts @@ -3,6 +3,56 @@ import { autoit } from './lib/autoit'; import { MouseButton } from './mouse-click'; import { AU3_INTDEFAULT } from './util/constants'; +/** + * Simulates a mouse click on a control. Unlike {@linkcode MouseClickSync}, `ControlClickSync` won't move the + * mouse cursor but is capable of clicking on controls that may be obscured by other windows. + * + * Where possible, you should prefer using {@linkcode ControlClickByHandleSync} to avoid potential issues + * with ambiguous window and control titles. + * + * @param windowTitle The title of the window to access. + * @param windowText Optional text found in the window. + * @param controlId The control to interact with. + * @param button The mouse button to click. Default is {@linkcode MouseButton.Left}. + * @param clicks The number of times to click the mouse. Default is 1. + * @param x The x position to click within the control. Default is the center. + * @param y The y position to click within the control. Default is the center. + * + * @returns 1 if success, 0 if failed. + * + * @example + * ```typescript + * import { ControlClickSync } from '@ahmic/autoit-js'; + * + * // Click the Notepad window's edit control. + * ControlClickSync('Untitled - Notepad', '', 'Edit1'); + * + * // Right click the Notepad window's edit control. + * ControlClickSync('Untitled - Notepad', '', 'Edit1', MouseButton.Right); + * + * // Double click the Notepad window's edit control. + * ControlClickSync('Untitled - Notepad', '', 'Edit1', MouseButton.Left, 2); + * ``` + * + * @see https://www.autoitscript.com/autoit3/docs/functions/ControlClick.htm + */ +export function ControlClickSync( + windowTitle: string, + windowText: string, + controlId: string, + button: MouseButton = MouseButton.Left, + clicks: number = 1, + x: number = AU3_INTDEFAULT, + y: number = AU3_INTDEFAULT, +): number { + return autoit.invoke( + 'AU3_ControlClick', + INT, + [LPCWSTR, LPCWSTR, LPCWSTR, LPCWSTR, INT, INT, INT], + [windowTitle, windowText, controlId, button, clicks, x, y], + ); +} + /** * Simulates a mouse click on a control. Unlike {@linkcode MouseClick}, `ControlClick` won't move the mouse * cursor but is capable of clicking on controls that may be obscured by other windows. @@ -18,20 +68,20 @@ import { AU3_INTDEFAULT } from './util/constants'; * @param x The x position to click within the control. Default is the center. * @param y The y position to click within the control. Default is the center. * - * @returns 1 if success, 0 if failed. + * @returns A promise that resolves to 1 if success, 0 if failed. * * @example * ```typescript * import { ControlClick } from '@ahmic/autoit-js'; * * // Click the Notepad window's edit control. - * ControlClick('Untitled - Notepad', '', 'Edit1'); + * await ControlClick('Untitled - Notepad', '', 'Edit1'); * * // Right click the Notepad window's edit control. - * ControlClick('Untitled - Notepad', '', 'Edit1', MouseButton.Right); + * await ControlClick('Untitled - Notepad', '', 'Edit1', MouseButton.Right); * * // Double click the Notepad window's edit control. - * ControlClick('Untitled - Notepad', '', 'Edit1', MouseButton.Left, 2); + * await ControlClick('Untitled - Notepad', '', 'Edit1', MouseButton.Left, 2); * ``` * * @see https://www.autoitscript.com/autoit3/docs/functions/ControlClick.htm @@ -44,8 +94,8 @@ export function ControlClick( clicks: number = 1, x: number = AU3_INTDEFAULT, y: number = AU3_INTDEFAULT, -): number { - return autoit.invoke( +): Promise { + return autoit.invokeAsync( 'AU3_ControlClick', INT, [LPCWSTR, LPCWSTR, LPCWSTR, LPCWSTR, INT, INT, INT], diff --git a/src/control-command-by-handle.ts b/src/control-command-by-handle.ts index 6d9d492..cff6189 100644 --- a/src/control-command-by-handle.ts +++ b/src/control-command-by-handle.ts @@ -16,18 +16,18 @@ import { createUnicodeBuffer, unicodeBufferToString } from './util'; * * @example * ```typescript - * import { ControlCommandByHandle, WinGetHandle, ControlGetHandle } from '@ahmic/autoit-js'; + * import { ControlCommandByHandleSync, WinGetHandleSync, ControlGetHandleSync } from '@ahmic/autoit-js'; * - * const windowHandle = WinGetHandle('Untitled - Notepad'); - * const controlHandle = ControlGetHandle(windowHandle, 'Edit1'); - * const result = ControlCommandByHandle(windowHandle, controlHandle, 'IsVisible'); + * const windowHandle = WinGetHandleSync('Untitled - Notepad'); + * const controlHandle = ControlGetHandleSync(windowHandle, 'Edit1'); + * const result = ControlCommandByHandleSync(windowHandle, controlHandle, 'IsVisible'); * * console.log(result); // Output: "1" if visible, "0" otherwise * ``` * * @see https://www.autoitscript.com/autoit3/docs/functions/ControlCommand.htm */ -export function ControlCommandByHandle( +export function ControlCommandByHandleSync( windowHandle: bigint, controlHandle: bigint, command: Command, @@ -45,3 +45,46 @@ export function ControlCommandByHandle( return unicodeBufferToString(buffer); } + +/** + * Sends a command to a control in a window. + * + * @param windowHandle The handle of the window to access. + * @param controlHandle The handle of the control to send the command to. + * @param command The command to send to the control. + * @param option Optional additional parameter for the command. + * @param characterCount The size of the buffer to store the result. + * + * @returns A promise that resolves to the result of the command as a string. + * + * @example + * ```typescript + * import { ControlCommandByHandle, WinGetHandle, ControlGetHandle } from '@ahmic/autoit-js'; + * + * const windowHandle = await WinGetHandle('Untitled - Notepad'); + * const controlHandle = await ControlGetHandle(windowHandle, 'Edit1'); + * const result = await ControlCommandByHandle(windowHandle, controlHandle, 'IsVisible'); + * + * console.log(result); // Output: "1" if visible, "0" otherwise + * ``` + * + * @see https://www.autoitscript.com/autoit3/docs/functions/ControlCommand.htm + */ +export async function ControlCommandByHandle( + windowHandle: bigint, + controlHandle: bigint, + command: Command, + option: string = '', + characterCount: number = 1024, +): Promise { + const [buffer, length] = createUnicodeBuffer(characterCount); + + await autoit.invokeAsync( + 'AU3_ControlCommandByHandle', + VOID, + [HWND, HWND, LPCWSTR, LPCWSTR, LPWSTR, INT], + [windowHandle, controlHandle, command, option, buffer, length], + ); + + return unicodeBufferToString(buffer); +} diff --git a/src/control-command.ts b/src/control-command.ts index 63b61f9..e643c1f 100644 --- a/src/control-command.ts +++ b/src/control-command.ts @@ -93,16 +93,16 @@ export enum Command { * * @example * ```typescript - * import { ControlCommand } from '@ahmic/autoit-js'; + * import { ControlCommandSync } from '@ahmic/autoit-js'; * - * const result = ControlCommand('Untitled - Notepad', '', 'Edit1', 'IsVisible'); + * const result = ControlCommandSync('Untitled - Notepad', '', 'Edit1', 'IsVisible'); * * console.log(result); // Output: "1" if visible, "0" otherwise * ``` * * @see https://www.autoitscript.com/autoit3/docs/functions/ControlCommand.htm */ -export function ControlCommand( +export function ControlCommandSync( windowTitle: string, windowText: string, controlId: string, @@ -122,6 +122,51 @@ export function ControlCommand( return unicodeBufferToString(buffer); } +/** + * Sends a command to a control in a window. + * + * @param windowTitle The title of the window to access. + * @param windowText Optional text found in the window. + * @param controlId The ID of the control to send the command to. + * @param command The command to send to the control. + * @param option Optional additional parameter for the command. + * @param characterCount The size of the buffer to store the result. + * + * @returns A promise that resolves to the result of the command as a string. + * + * @example + * ```typescript + * import { ControlCommand } from '@ahmic/autoit-js'; + * + * const result = await ControlCommand('Untitled - Notepad', '', 'Edit1', 'IsVisible'); + * + * console.log(result); // Output: "1" if visible, "0" otherwise + * ``` + * + * @see https://www.autoitscript.com/autoit3/docs/functions/ControlCommand.htm + */ +export async function ControlCommand( + windowTitle: string, + windowText: string, + controlId: string, + command: Command, + option: string = '', + characterCount: number = 1024, +): Promise { + const [buffer, length] = createUnicodeBuffer(characterCount); + + await autoit.invokeAsync( + 'AU3_ControlCommand', + VOID, + [LPCWSTR, LPCWSTR, LPCWSTR, LPCWSTR, LPCWSTR, LPWSTR, INT], + [windowTitle, windowText, controlId, command, option, buffer, length], + ); + + return unicodeBufferToString(buffer); +} + +// TODO: Don't remember this would've even worked considering the return is a string, but I don't wanna remove +// it cause it looks cool. // TODO: See if we want to improve the return type of ControlCommand and parse the result in a more // user-friendly way. For example, for `ControlCommand.IsVisible`, we could return a boolean instead of // a number. diff --git a/src/control-disable-by-handle.ts b/src/control-disable-by-handle.ts index bf44c58..1e0ef4b 100644 --- a/src/control-disable-by-handle.ts +++ b/src/control-disable-by-handle.ts @@ -11,16 +11,40 @@ import { autoit } from './lib/autoit'; * * @example * ```typescript - * import { ControlDisableByHandle, ControlGetHandle, WinGetHandle } from '@ahmic/autoit-js'; + * import { ControlDisableByHandleSync, ControlGetHandleSync, WinGetHandleSync } from '@ahmic/autoit-js'; * - * const windowHandle = WinGetHandle('Untitled - Notepad'); - * const controlHandle = ControlGetHandle(windowHandle, 'Edit1'); + * const windowHandle = WinGetHandleSync('Untitled - Notepad'); + * const controlHandle = ControlGetHandleSync(windowHandle, 'Edit1'); * - * ControlDisableByHandle(windowHandle, controlHandle); + * ControlDisableByHandleSync(windowHandle, controlHandle); * ``` * * @see https://www.autoitscript.com/autoit3/docs/functions/ControlDisable.htm */ -export function ControlDisableByHandle(windowHandle: bigint, controlHandle: bigint): number { +export function ControlDisableByHandleSync(windowHandle: bigint, controlHandle: bigint): number { return autoit.invoke('AU3_ControlDisableByHandle', INT, [HWND, HWND], [windowHandle, controlHandle]); } + +/** + * Disables a control in a window. + * + * @param windowHandle The handle of the window to access. + * @param controlHandle The handle of the control to disable. + * + * @returns A promise that resolves to 1 if success, or 0 if failure. + * + * @example + * ```typescript + * import { ControlDisableByHandle, ControlGetHandle, WinGetHandle } from '@ahmic/autoit-js'; + * + * const windowHandle = await WinGetHandle('Untitled - Notepad'); + * const controlHandle = await ControlGetHandle(windowHandle, 'Edit1'); + * + * await ControlDisableByHandle(windowHandle, controlHandle); + * ``` + * + * @see https://www.autoitscript.com/autoit3/docs/functions/ControlDisable.htm + */ +export function ControlDisableByHandle(windowHandle: bigint, controlHandle: bigint): Promise { + return autoit.invokeAsync('AU3_ControlDisableByHandle', INT, [HWND, HWND], [windowHandle, controlHandle]); +} diff --git a/src/control-disable.ts b/src/control-disable.ts index 4f73f36..f9dca0c 100644 --- a/src/control-disable.ts +++ b/src/control-disable.ts @@ -12,14 +12,14 @@ import { autoit } from './lib/autoit'; * * @example * ```typescript - * import { ControlDisable } from '@ahmic/autoit-js'; + * import { ControlDisableSync } from '@ahmic/autoit-js'; * - * ControlDisable('Untitled - Notepad', 'Edit1'); + * ControlDisableSync('Untitled - Notepad', 'Edit1'); * ``` * * @see https://www.autoitscript.com/autoit3/docs/functions/ControlDisable.htm */ -export function ControlDisable(windowTitle: string, windowText: string, controlId: string): number { +export function ControlDisableSync(windowTitle: string, windowText: string, controlId: string): number { return autoit.invoke( 'AU3_ControlDisable', INT, @@ -27,3 +27,30 @@ export function ControlDisable(windowTitle: string, windowText: string, controlI [windowTitle, windowText, controlId], ); } + +/** + * Disables a control in a window. + * + * @param windowTitle The title of the window to access. + * @param windowText Optional text found in the window. + * @param controlId The ID of the control to disable. + * + * @returns A promise that resolves to 1 if success, or 0 if failure. + * + * @example + * ```typescript + * import { ControlDisable } from '@ahmic/autoit-js'; + * + * await ControlDisable('Untitled - Notepad', 'Edit1'); + * ``` + * + * @see https://www.autoitscript.com/autoit3/docs/functions/ControlDisable.htm + */ +export function ControlDisable(windowTitle: string, windowText: string, controlId: string): Promise { + return autoit.invokeAsync( + 'AU3_ControlDisable', + INT, + [LPCWSTR, LPCWSTR, LPCWSTR], + [windowTitle, windowText, controlId], + ); +} diff --git a/src/control-enable-by-handle.ts b/src/control-enable-by-handle.ts index 7132613..fd9cf5f 100644 --- a/src/control-enable-by-handle.ts +++ b/src/control-enable-by-handle.ts @@ -11,16 +11,54 @@ import { autoit } from './lib/autoit'; * * @example * ```typescript - * import { ControlDisableByHandle, ControlEnableByHandle, ControlGetHandle, WinGetHandle } from '@ahmic/autoit-js'; + * import { + * ControlDisableByHandleSync, + * ControlEnableByHandleSync, + * ControlGetHandleSync, + * WinGetHandleSync, + * } from '@ahmic/autoit-js'; * - * const windowHandle = WinGetHandle('Untitled - Notepad'); - * const controlHandle = ControlGetHandle(windowHandle, 'Edit1'); + * const windowHandle = WinGetHandleSync('Untitled - Notepad'); + * const controlHandle = ControlGetHandleSync(windowHandle, 'Edit1'); * * // Disable the Notepad window's edit control. - * ControlDisableByHandle(windowHandle, controlHandle); + * ControlDisableByHandleSync(windowHandle, controlHandle); * * // Enable the Notepad window's edit control. - * ControlEnableByHandle(windowHandle, controlHandle); + * ControlEnableByHandleSync(windowHandle, controlHandle); + * ``` + * + * @see https://www.autoitscript.com/autoit3/docs/functions/ControlEnable.htm + */ +export function ControlEnableByHandleSync(windowHandle: bigint, controlHandle: bigint): number { + return autoit.invoke('AU3_ControlEnableByHandle', INT, [HWND, HWND], [windowHandle, controlHandle]); +} + +/** + * Enables a control in a window. + * + * @param windowHandle The handle of the window to access. + * @param controlHandle The handle of the control to enable. + * + * @returns A promise that resolves to 1 if success, or 0 if failure. + * + * @example + * ```typescript + * import { + * ControlDisableByHandle, + * ControlEnableByHandle, + * ControlGetHandle, + * WinGetHandle, + * } from '@ahmic/autoit-js'; + * + * const windowHandle = await WinGetHandle('Untitled - Notepad'); + * const controlHandle = await ControlGetHandle(windowHandle, 'Edit1'); + * + * // Disable the Notepad window's edit control. + * await ControlDisableByHandle(windowHandle, controlHandle); + * + * // Enable the Notepad window's edit control. + * await ControlEnableByHandle(windowHandle, controlHandle); * ``` * * @see https://www.autoitscript.com/autoit3/docs/functions/ControlEnable.htm diff --git a/src/control-enable.ts b/src/control-enable.ts index 6fe42e3..df932bd 100644 --- a/src/control-enable.ts +++ b/src/control-enable.ts @@ -12,18 +12,18 @@ import { autoit } from './lib/autoit'; * * @example * ```typescript - * import { ControlEnable, ControlDisable } from '@ahmic/autoit-js'; + * import { ControlEnableSync, ControlDisableSync } from '@ahmic/autoit-js'; * * // Disable the Notepad window's edit control. - * ControlDisable('Untitled - Notepad', 'Edit1'); + * ControlDisableSync('Untitled - Notepad', 'Edit1'); * * // Enable the Notepad window's edit control. - * ControlEnable('Untitled - Notepad', 'Edit1'); + * ControlEnableSync('Untitled - Notepad', 'Edit1'); * ``` * * @see https://www.autoitscript.com/autoit3/docs/functions/ControlEnable.htm */ -export function ControlEnable(windowTitle: string, windowText: string, controlId: string): number { +export function ControlEnableSync(windowTitle: string, windowText: string, controlId: string): number { return autoit.invoke( 'AU3_ControlEnable', INT, @@ -31,3 +31,34 @@ export function ControlEnable(windowTitle: string, windowText: string, controlId [windowTitle, windowText, controlId], ); } + +/** + * Enables a control in a window. + * + * @param windowTitle The title of the window to access. + * @param windowText Optional text found in the window. + * @param controlId The control to enable. + * + * @returns A promise that resolves to 1 if success, or 0 if failure. + * + * @example + * ```typescript + * import { ControlEnable, ControlDisable } from '@ahmic/autoit-js'; + * + * // Disable the Notepad window's edit control. + * await ControlDisable('Untitled - Notepad', 'Edit1'); + * + * // Enable the Notepad window's edit control. + * await ControlEnable('Untitled - Notepad', 'Edit1'); + * ``` + * + * @see https://www.autoitscript.com/autoit3/docs/functions/ControlEnable.htm + */ +export function ControlEnable(windowTitle: string, windowText: string, controlId: string): Promise { + return autoit.invokeAsync( + 'AU3_ControlEnable', + INT, + [LPCWSTR, LPCWSTR, LPCWSTR], + [windowTitle, windowText, controlId], + ); +} diff --git a/src/control-focus-by-handle.ts b/src/control-focus-by-handle.ts index 8f2f9e0..83c54af 100644 --- a/src/control-focus-by-handle.ts +++ b/src/control-focus-by-handle.ts @@ -11,16 +11,40 @@ import { autoit } from './lib/autoit'; * * @example * ```typescript - * import { ControlFocusByHandle, ControlGetHandle, WinGetHandle } from '@ahmic/autoit-js'; + * import { ControlFocusByHandleSync, ControlGetHandleSync, WinGetHandleSync } from '@ahmic/autoit-js'; * - * const windowHandle = WinGetHandle('Untitled - Notepad'); - * const controlHandle = ControlGetHandle(windowHandle, 'Edit1'); + * const windowHandle = WinGetHandleSync('Untitled - Notepad'); + * const controlHandle = ControlGetHandleSync(windowHandle, 'Edit1'); * - * ControlFocusByHandle(windowHandle, controlHandle); + * ControlFocusByHandleSync(windowHandle, controlHandle); * ``` * * @see https://www.autoitscript.com/autoit3/docs/functions/ControlFocus.htm */ -export function ControlFocusByHandle(windowHandle: bigint, controlHandle: bigint): number { +export function ControlFocusByHandleSync(windowHandle: bigint, controlHandle: bigint): number { return autoit.invoke('AU3_ControlFocusByHandle', INT, [HWND, HWND], [windowHandle, controlHandle]); } + +/** + * Sets the focus to a control in a window. + * + * @param windowHandle The handle of the window to access. + * @param controlHandle The handle of the control to focus. + * + * @returns A promise that resolves to 1 if success, or 0 if failure. + * + * @example + * ```typescript + * import { ControlFocusByHandle, ControlGetHandle, WinGetHandle } from '@ahmic/autoit-js'; + * + * const windowHandle = await WinGetHandle('Untitled - Notepad'); + * const controlHandle = await ControlGetHandle(windowHandle, 'Edit1'); + * + * await ControlFocusByHandle(windowHandle, controlHandle); + * ``` + * + * @see https://www.autoitscript.com/autoit3/docs/functions/ControlFocus.htm + */ +export function ControlFocusByHandle(windowHandle: bigint, controlHandle: bigint): Promise { + return autoit.invokeAsync('AU3_ControlFocusByHandle', INT, [HWND, HWND], [windowHandle, controlHandle]); +} diff --git a/src/control-focus.ts b/src/control-focus.ts index b52531a..b32834f 100644 --- a/src/control-focus.ts +++ b/src/control-focus.ts @@ -12,14 +12,14 @@ import { autoit } from './lib/autoit'; * * @example * ```typescript - * import { ControlFocus } from '@ahmic/autoit-js'; + * import { ControlFocusSync } from '@ahmic/autoit-js'; * - * ControlFocus('Untitled - Notepad', '', 'Edit1'); + * ControlFocusSync('Untitled - Notepad', '', 'Edit1'); * ``` * * @see https://www.autoitscript.com/autoit3/docs/functions/ControlFocus.htm */ -export function ControlFocus(windowTitle: string, windowText: string, controlId: string): number { +export function ControlFocusSync(windowTitle: string, windowText: string, controlId: string): number { return autoit.invoke( 'AU3_ControlFocus', INT, @@ -27,3 +27,30 @@ export function ControlFocus(windowTitle: string, windowText: string, controlId: [windowTitle, windowText, controlId], ); } + +/** + * Sets the keyboard focus to a control in a window. + * + * @param windowTitle The title of the window to access. + * @param windowText Optional text found in the window. + * @param controlId The ID of the control to focus. + * + * @return A promise that resolves to 1 if success, or 0 if failure. + * + * @example + * ```typescript + * import { ControlFocus } from '@ahmic/autoit-js'; + * + * await ControlFocus('Untitled - Notepad', '', 'Edit1'); + * ``` + * + * @see https://www.autoitscript.com/autoit3/docs/functions/ControlFocus.htm + */ +export function ControlFocus(windowTitle: string, windowText: string, controlId: string): Promise { + return autoit.invokeAsync( + 'AU3_ControlFocus', + INT, + [LPCWSTR, LPCWSTR, LPCWSTR], + [windowTitle, windowText, controlId], + ); +} diff --git a/src/control-get-focus-by-handle.ts b/src/control-get-focus-by-handle.ts index 9e76cf5..17767d9 100644 --- a/src/control-get-focus-by-handle.ts +++ b/src/control-get-focus-by-handle.ts @@ -11,21 +11,54 @@ import { createUnicodeBuffer, unicodeBufferToString } from './util'; * * @example * ```typescript - * import { ControlGetFocusByHandle, WinGetHandle } from '@ahmic/autoit-js'; + * import { ControlGetFocusByHandleSync, WinGetHandleSync } from '@ahmic/autoit-js'; * - * const windowHandle = WinGetHandle('Untitled - Notepad'); + * const windowHandle = WinGetHandleSync('Untitled - Notepad'); * - * const id = ControlGetFocusByHandle(windowHandle); + * const id = ControlGetFocusByHandleSync(windowHandle); * * console.log(id); // Output: "Edit1" * ``` * * @see https://www.autoitscript.com/autoit3/docs/functions/ControlGetFocus.htm */ -export function ControlGetFocusByHandle(windowHandle: bigint): string { +export function ControlGetFocusByHandleSync(windowHandle: bigint): string { const [buffer, length] = createUnicodeBuffer(1024); autoit.invoke('AU3_ControlGetFocusByHandle', VOID, [HWND, LPWSTR, INT], [windowHandle, buffer, length]); return unicodeBufferToString(buffer); } + +/** + * Gets the ID of the control that has keyboard focus in a window. + * + * @param windowHandle The handle of the window to access. + * + * @returns A promise that resolves to the ID of the control that has keyboard focus. + * + * @example + * ```typescript + * import { ControlGetFocusByHandle, WinGetHandle } from '@ahmic/autoit-js'; + * + * const windowHandle = await WinGetHandle('Untitled - Notepad'); + * + * const id = await ControlGetFocusByHandle(windowHandle); + * + * console.log(id); // Output: "Edit1" + * ``` + * + * @see https://www.autoitscript.com/autoit3/docs/functions/ControlGetFocus.htm + */ +export async function ControlGetFocusByHandle(windowHandle: bigint): Promise { + const [buffer, length] = createUnicodeBuffer(1024); + + await autoit.invokeAsync( + 'AU3_ControlGetFocusByHandle', + VOID, + [HWND, LPWSTR, INT], + [windowHandle, buffer, length], + ); + + return unicodeBufferToString(buffer); +} diff --git a/src/control-get-focus.ts b/src/control-get-focus.ts index e5ebee7..6c3cd14 100644 --- a/src/control-get-focus.ts +++ b/src/control-get-focus.ts @@ -12,16 +12,16 @@ import { createUnicodeBuffer, unicodeBufferToString } from './util'; * * @example * ```typescript - * import { ControlGetFocus } from '@ahmic/autoit-js'; + * import { ControlGetFocusSync } from '@ahmic/autoit-js'; * - * const className = ControlGetFocus('Untitled - Notepad'); + * const className = ControlGetFocusSync('Untitled - Notepad'); * * console.log(className); // Output: "Edit1" * ``` * * @see https://www.autoitscript.com/autoit3/docs/functions/ControlGetFocus.htm */ -export function ControlGetFocus(windowTitle: string, windowText: string = ''): string { +export function ControlGetFocusSync(windowTitle: string, windowText: string = ''): string { const [buffer, length] = createUnicodeBuffer(1024); autoit.invoke( @@ -33,3 +33,35 @@ export function ControlGetFocus(windowTitle: string, windowText: string = ''): s return unicodeBufferToString(buffer); } + +/** + * Gets the ID of the control that has keyboard focus in a window. + * + * @param windowTitle The title of the window to access. + * @param windowText Optional text found in the window. + * + * @returns A promise that resolves to the ID of the control that has keyboard focus. + * + * @example + * ```typescript + * import { ControlGetFocus } from '@ahmic/autoit-js'; + * + * const className = await ControlGetFocus('Untitled - Notepad'); + * + * console.log(className); // Output: "Edit1" + * ``` + * + * @see https://www.autoitscript.com/autoit3/docs/functions/ControlGetFocus.htm + */ +export async function ControlGetFocus(windowTitle: string, windowText: string = ''): Promise { + const [buffer, length] = createUnicodeBuffer(1024); + + await autoit.invokeAsync( + 'AU3_ControlGetFocus', + VOID, + [LPCWSTR, LPCWSTR, LPWSTR, INT], + [windowTitle, windowText, buffer, length], + ); + + return unicodeBufferToString(buffer); +} diff --git a/src/control-get-handle-as-text.ts b/src/control-get-handle-as-text.ts index 21eb60f..8ed9e63 100644 --- a/src/control-get-handle-as-text.ts +++ b/src/control-get-handle-as-text.ts @@ -14,16 +14,16 @@ import { HWND_HEX_SIZE } from './util/constants'; * * @example * ```typescript - * import { ControlGetHandleAsText } from '@ahmic/autoit-js'; + * import { ControlGetHandleAsTextSync } from '@ahmic/autoit-js'; * - * const handle = ControlGetHandleAsText('Untitled - Notepad', '', 'Edit1'); + * const handle = ControlGetHandleAsTextSync('Untitled - Notepad', '', 'Edit1'); * * console.log(handle); // Output: "0x0000000000000001" * ``` * * @see https://www.autoitscript.com/autoit3/docs/functions/ControlGetHandle.htm */ -export function ControlGetHandleAsText( +export function ControlGetHandleAsTextSync( windowTitle: string, windowText: string = '', controlId: string, @@ -39,3 +39,40 @@ export function ControlGetHandleAsText( return unicodeBufferToString(buffer); } + +/** + * Gets the handle of a control in a window as a hexadecimal string. + * + * @param windowTitle The title of the window to access. + * @param windowText Optional text found in the window. + * @param controlId The control to get the handle for. + * + * @returns A promise that resolves to the handle of the control as a hexadecimal string. + * + * @example + * ```typescript + * import { ControlGetHandleAsText } from '@ahmic/autoit-js'; + * + * const handle = await ControlGetHandleAsText('Untitled - Notepad', '', 'Edit1'); + * + * console.log(handle); // Output: "0x0000000000000001" + * ``` + * + * @see https://www.autoitscript.com/autoit3/docs/functions/ControlGetHandle.htm + */ +export async function ControlGetHandleAsText( + windowTitle: string, + windowText: string = '', + controlId: string, +): Promise { + const [buffer, length] = createUnicodeBuffer(HWND_HEX_SIZE); + + await autoit.invokeAsync( + 'AU3_ControlGetHandleAsText', + VOID, + [LPCWSTR, LPCWSTR, LPCWSTR, LPWSTR, INT], + [windowTitle, windowText, controlId, buffer, length], + ); + + return unicodeBufferToString(buffer); +} diff --git a/src/control-get-handle.ts b/src/control-get-handle.ts index 5fe889b..ba35efe 100644 --- a/src/control-get-handle.ts +++ b/src/control-get-handle.ts @@ -13,18 +13,49 @@ import { autoit } from './lib/autoit'; * * @example * ```typescript - * import { ControlGetHandle, WinGetHandle } from '@ahmic/autoit-js'; + * import { ControlGetHandleSync, WinGetHandleSync } from '@ahmic/autoit-js'; * - * const windowHandle = WinGetHandle('Untitled - Notepad'); - * const controlHandle = ControlGetHandle(windowHandle, 'Edit1'); + * const windowHandle = WinGetHandleSync('Untitled - Notepad'); + * const controlHandle = ControlGetHandleSync(windowHandle, 'Edit1'); * * console.log(controlHandle); // Output: 0x0000000000000001 * ``` * * @see https://www.autoitscript.com/autoit3/docs/functions/ControlGetHandle.htm */ -export function ControlGetHandle(windowHandle: bigint, controlId: string): bigint { +export function ControlGetHandleSync(windowHandle: bigint, controlId: string): bigint { const handleRef = autoit.invoke('AU3_ControlGetHandle', HWND, [HWND, LPCWSTR], [windowHandle, controlId]); return koffi.address(handleRef); } + +/** + * Gets the handle of a control in a window. + * + * @param windowHandle The handle of the window to access. + * @param controlId The control to get the handle of. + * + * @returns A promise that resolves to the handle of the control. + * + * @example + * ```typescript + * import { ControlGetHandle, WinGetHandle } from '@ahmic/autoit-js'; + * + * const windowHandle = await WinGetHandle('Untitled - Notepad'); + * const controlHandle = await ControlGetHandle(windowHandle, 'Edit1'); + * + * console.log(controlHandle); // Output: 0x0000000000000001 + * ``` + * + * @see https://www.autoitscript.com/autoit3/docs/functions/ControlGetHandle.htm + */ +export async function ControlGetHandle(windowHandle: bigint, controlId: string): Promise { + const handleRef = await autoit.invokeAsync( + 'AU3_ControlGetHandle', + HWND, + [HWND, LPCWSTR], + [windowHandle, controlId], + ); + + return koffi.address(handleRef); +} diff --git a/src/control-get-pos-by-handle.ts b/src/control-get-pos-by-handle.ts index 321c3c2..f1a949b 100644 --- a/src/control-get-pos-by-handle.ts +++ b/src/control-get-pos-by-handle.ts @@ -1,6 +1,6 @@ import koffi from 'koffi'; -import { HWND, INT, LPRECT, Rect } from './@types'; +import { HWND, INT, IRect, LPRECT, Rect } from './@types'; import { autoit } from './lib/autoit'; /** @@ -13,19 +13,19 @@ import { autoit } from './lib/autoit'; * * @example * ```typescript - * import { ControlGetPosByHandle, ControlGetHandle, WinGetHandle } from '@ahmic/autoit-js'; + * import { ControlGetPosByHandleSync, ControlGetHandleSync, WinGetHandleSync } from '@ahmic/autoit-js'; * - * const windowHandle = WinGetHandle('Untitled - Notepad'); - * const controlHandle = ControlGetHandle(windowHandle, 'Edit1'); + * const windowHandle = WinGetHandleSync('Untitled - Notepad'); + * const controlHandle = ControlGetHandleSync(windowHandle, 'Edit1'); * - * const rect = ControlGetPosByHandle(windowHandle, controlHandle); + * const rect = ControlGetPosByHandleSync(windowHandle, controlHandle); * * console.log(rect); // Output: { left: 10, top: 10, right: 100, bottom: 100 } * ``` * * @see https://www.autoitscript.com/autoit3/docs/functions/ControlGetPos.htm */ -export function ControlGetPosByHandle(windowHandle: bigint, controlHandle: bigint): Rect { +export function ControlGetPosByHandleSync(windowHandle: bigint, controlHandle: bigint): IRect { const rect = new Rect(); autoit.invoke( @@ -37,3 +37,38 @@ export function ControlGetPosByHandle(windowHandle: bigint, controlHandle: bigin return rect; } + +/** + * Gets the position of a control in a window, relative to the window itself. + * + * @param windowHandle The handle of the window to access. + * @param controlHandle The handle of the control to get the position for. + * + * @returns A promise that resolves to the position of the control as a {@linkcode Rect} object. + * + * @example + * ```typescript + * import { ControlGetPosByHandle, ControlGetHandle, WinGetHandle } from '@ahmic/autoit-js'; + * + * const windowHandle = await WinGetHandle('Untitled - Notepad'); + * const controlHandle = await ControlGetHandle(windowHandle, 'Edit1'); + * + * const rect = await ControlGetPosByHandle(windowHandle, controlHandle); + * + * console.log(rect); // Output: { left: 10, top: 10, right: 100, bottom: 100 } + * ``` + * + * @see https://www.autoitscript.com/autoit3/docs/functions/ControlGetPos.htm + */ +export async function ControlGetPosByHandle(windowHandle: bigint, controlHandle: bigint): Promise { + const rect = new Rect(); + + await autoit.invokeAsync( + 'AU3_ControlGetPosByHandle', + INT, + [HWND, HWND, koffi.out(LPRECT)], + [windowHandle, controlHandle, rect], + ); + + return rect; +} diff --git a/src/control-get-pos.ts b/src/control-get-pos.ts index e167aff..ec1ca75 100644 --- a/src/control-get-pos.ts +++ b/src/control-get-pos.ts @@ -1,6 +1,6 @@ import koffi from 'koffi'; -import { INT, LPCWSTR, LPRECT, Rect } from './@types'; +import { INT, IRect, LPCWSTR, LPRECT, Rect } from './@types'; import { autoit } from './lib/autoit'; /** @@ -14,16 +14,16 @@ import { autoit } from './lib/autoit'; * * @example * ```typescript - * import { ControlGetPos } from '@ahmic/autoit-js'; + * import { ControlGetPosSync } from '@ahmic/autoit-js'; * - * const rect = ControlGetPos('Untitled - Notepad', '', 'Edit1'); + * const rect = ControlGetPosSync('Untitled - Notepad', '', 'Edit1'); * * console.log(rect); // Output: { left: 0, top: 0, right: 100, bottom: 100 } * ``` * * @see https://www.autoitscript.com/autoit3/docs/functions/ControlGetPos.htm */ -export function ControlGetPos(windowTitle: string, windowText: string, controlId: string): Rect { +export function ControlGetPosSync(windowTitle: string, windowText: string, controlId: string): IRect { const rect = new Rect(); autoit.invoke( @@ -35,3 +35,40 @@ export function ControlGetPos(windowTitle: string, windowText: string, controlId return rect; } + +/** + * Gets the position of a control in a window, relative to the window itself. + * + * @param windowTitle The title of the window to access. + * @param windowText Optional text found in the window. + * @param controlId The control to get the position for. + * + * @returns A promise that resolves to the position of the control as a {@linkcode Rect} object. + * + * @example + * ```typescript + * import { ControlGetPos } from '@ahmic/autoit-js'; + * + * const rect = await ControlGetPos('Untitled - Notepad', '', 'Edit1'); + * + * console.log(rect); // Output: { left: 0, top: 0, right: 100, bottom: 100 } + * ``` + * + * @see https://www.autoitscript.com/autoit3/docs/functions/ControlGetPos.htm + */ +export async function ControlGetPos( + windowTitle: string, + windowText: string, + controlId: string, +): Promise { + const rect = new Rect(); + + await autoit.invokeAsync( + 'AU3_ControlGetPos', + INT, + [LPCWSTR, LPCWSTR, LPCWSTR, koffi.out(LPRECT)], + [windowTitle, windowText, controlId, rect], + ); + + return rect; +} diff --git a/src/control-get-text-by-handle.ts b/src/control-get-text-by-handle.ts index 4aa94a0..9cb864e 100644 --- a/src/control-get-text-by-handle.ts +++ b/src/control-get-text-by-handle.ts @@ -13,26 +13,66 @@ import { createUnicodeBuffer, unicodeBufferToString } from './util'; * * @example * ```typescript + * import { ControlGetTextByHandleSync, ControlGetHandleSync, WinGetHandleSync } from '@ahmic/autoit-js'; + * + * const windowHandle = WinGetHandleSync('Untitled - Notepad'); + * const controlHandle = ControlGetHandleSync(windowHandle, 'Edit1'); + * + * const text = ControlGetTextByHandleSync(windowHandle, controlHandle); + * + * console.log(text); // Output: "Sample text" + * ``` + * + * @see https://www.autoitscript.com/autoit3/docs/functions/ControlGetText.htm + */ +export function ControlGetTextByHandleSync( + windowHandle: bigint, + controlHandle: bigint, + characterCount: number = 1024, +): string { + const [buffer, length] = createUnicodeBuffer(characterCount); + + autoit.invoke( + 'AU3_ControlGetTextByHandle', + VOID, + [HWND, HWND, LPWSTR, INT], + [windowHandle, controlHandle, buffer, length], + ); + + return unicodeBufferToString(buffer); +} + +/** + * Retrieves the text from a control in a window. + * + * @param windowHandle The handle of the window to access. + * @param controlHandle The handle of the control to retrieve text from. + * @param characterCount The maximum number of characters to retrieve. Default is 1024. + * + * @returns A promise that resolves to the text of the control. + * + * @example + * ```typescript * import { ControlGetTextByHandle, ControlGetHandle, WinGetHandle } from '@ahmic/autoit-js'; * * const windowHandle = WinGetHandle('Untitled - Notepad'); * const controlHandle = ControlGetHandle(windowHandle, 'Edit1'); * - * const text = ControlGetTextByHandle(windowHandle, controlHandle); + * const text = await ControlGetTextByHandle(windowHandle, controlHandle); * * console.log(text); // Output: "Sample text" * ``` * * @see https://www.autoitscript.com/autoit3/docs/functions/ControlGetText.htm */ -export function ControlGetTextByHandle( +export async function ControlGetTextByHandle( windowHandle: bigint, controlHandle: bigint, characterCount: number = 1024, -): string { +): Promise { const [buffer, length] = createUnicodeBuffer(characterCount); - autoit.invoke( + await autoit.invokeAsync( 'AU3_ControlGetTextByHandle', VOID, [HWND, HWND, LPWSTR, INT], diff --git a/src/control-get-text.ts b/src/control-get-text.ts index ce1fc15..b106d96 100644 --- a/src/control-get-text.ts +++ b/src/control-get-text.ts @@ -14,16 +14,16 @@ import { createUnicodeBuffer, unicodeBufferToString } from './util'; * * @example * ```typescript - * import { ControlGetText } from '@ahmic/autoit-js'; + * import { ControlGetTextSync } from '@ahmic/autoit-js'; * - * const text = ControlGetText('Untitled - Notepad', '', 'Edit1'); + * const text = ControlGetTextSync('Untitled - Notepad', '', 'Edit1'); * * console.log(text); // Output: "Sample text" * ``` * * @see https://www.autoitscript.com/autoit3/docs/functions/ControlGetText.htm */ -export function ControlGetText( +export function ControlGetTextSync( windowTitle: string, windowText: string, controlId: string, @@ -40,3 +40,42 @@ export function ControlGetText( return unicodeBufferToString(buffer); } + +/** + * Retrieves the text from a control in a window. + * + * @param windowTitle The title of the window to access. + * @param windowText Optional text found in the window. + * @param controlId The ID of the control to retrieve text from. + * @param characterCount The maximum number of characters to retrieve. Default is 1024. + * + * @returns A promise that resolves to the text of the control. + * + * @example + * ```typescript + * import { ControlGetText } from '@ahmic/autoit-js'; + * + * const text = await ControlGetText('Untitled - Notepad', '', 'Edit1'); + * + * console.log(text); // Output: "Sample text" + * ``` + * + * @see https://www.autoitscript.com/autoit3/docs/functions/ControlGetText.htm + */ +export async function ControlGetText( + windowTitle: string, + windowText: string, + controlId: string, + characterCount: number = 1024, +): Promise { + const [buffer, length] = createUnicodeBuffer(characterCount); + + await autoit.invokeAsync( + 'AU3_ControlGetText', + VOID, + [LPCWSTR, LPCWSTR, LPCWSTR, LPWSTR, INT], + [windowTitle, windowText, controlId, buffer, length], + ); + + return unicodeBufferToString(buffer); +} diff --git a/src/control-hide-by-handle.ts b/src/control-hide-by-handle.ts index 6dc5d15..0a02d9f 100644 --- a/src/control-hide-by-handle.ts +++ b/src/control-hide-by-handle.ts @@ -11,16 +11,40 @@ import { autoit } from './lib/autoit'; * * @example * ```typescript - * import { ControlHideByHandle, ControlGetHandle, WinGetHandle } from '@ahmic/autoit-js'; + * import { ControlHideByHandleSync, ControlGetHandleSync, WinGetHandleSync } from '@ahmic/autoit-js'; * - * const windowHandle = WinGetHandle('Untitled - Notepad'); - * const controlHandle = ControlGetHandle(windowHandle, 'Edit1'); + * const windowHandle = WinGetHandleSync('Untitled - Notepad'); + * const controlHandle = ControlGetHandleSync(windowHandle, 'Edit1'); * - * ControlHideByHandle(windowHandle, controlHandle); + * ControlHideByHandleSync(windowHandle, controlHandle); * ``` * * @see https://www.autoitscript.com/autoit3/docs/functions/ControlHide.htm */ -export function ControlHideByHandle(windowHandle: bigint, controlHandle: bigint): number { +export function ControlHideByHandleSync(windowHandle: bigint, controlHandle: bigint): number { return autoit.invoke('AU3_ControlHideByHandle', INT, [HWND, HWND], [windowHandle, controlHandle]); } + +/** + * Hides a control in a window. + * + * @param windowHandle The handle of the window to access. + * @param controlHandle The handle of the control to hide. + * + * @returns A promise that resolves to 1 if success, 0 if failure. + * + * @example + * ```typescript + * import { ControlHideByHandle, ControlGetHandle, WinGetHandle } from '@ahmic/autoit-js'; + * + * const windowHandle = await WinGetHandle('Untitled - Notepad'); + * const controlHandle = await ControlGetHandle(windowHandle, 'Edit1'); + * + * await ControlHideByHandle(windowHandle, controlHandle); + * ``` + * + * @see https://www.autoitscript.com/autoit3/docs/functions/ControlHide.htm + */ +export function ControlHideByHandle(windowHandle: bigint, controlHandle: bigint): Promise { + return autoit.invokeAsync('AU3_ControlHideByHandle', INT, [HWND, HWND], [windowHandle, controlHandle]); +} diff --git a/src/control-hide.ts b/src/control-hide.ts index 01e0381..a125da6 100644 --- a/src/control-hide.ts +++ b/src/control-hide.ts @@ -12,14 +12,14 @@ import { autoit } from './lib/autoit'; * * @example * ```typescript - * import { ControlHide } from '@ahmic/autoit-js'; + * import { ControlHideSync } from '@ahmic/autoit-js'; * - * ControlHide('Untitled - Notepad', '', 'Edit1'); + * ControlHideSync('Untitled - Notepad', '', 'Edit1'); * ``` * * @see https://www.autoitscript.com/autoit3/docs/functions/ControlHide.htm */ -export function ControlHide(windowTitle: string, windowText: string, controlId: string): number { +export function ControlHideSync(windowTitle: string, windowText: string, controlId: string): number { return autoit.invoke( 'AU3_ControlHide', INT, @@ -27,3 +27,30 @@ export function ControlHide(windowTitle: string, windowText: string, controlId: [windowTitle, windowText, controlId], ); } + +/** + * Hides a control in a window. + * + * @param windowTitle The title of the window to search for. + * @param windowText Optional text found in the window. + * @param controlId The ID of the control to hide. + * + * @returns A promise that resolves to 1 if successful, or 0 otherwise. + * + * @example + * ```typescript + * import { ControlHide } from '@ahmic/autoit-js'; + * + * await ControlHide('Untitled - Notepad', '', 'Edit1'); + * ``` + * + * @see https://www.autoitscript.com/autoit3/docs/functions/ControlHide.htm + */ +export function ControlHide(windowTitle: string, windowText: string, controlId: string): Promise { + return autoit.invokeAsync( + 'AU3_ControlHide', + INT, + [LPCWSTR, LPCWSTR, LPCWSTR], + [windowTitle, windowText, controlId], + ); +} diff --git a/src/control-list-view-by-handles.ts b/src/control-list-view-by-handles.ts index 771e20f..c6f34c6 100644 --- a/src/control-list-view-by-handles.ts +++ b/src/control-list-view-by-handles.ts @@ -17,19 +17,24 @@ import { createUnicodeBuffer, unicodeBufferToString } from './util'; * * @example * ```typescript - * import { ControlListViewByHandle, ListViewCommand, ControlGetHandle, WinGetHandle } from '@ahmic/autoit-js'; + * import { + * ControlListViewByHandleSync, + * ListViewCommand, + * ControlGetHandleSync, + * WinGetHandleSync, + * } from '@ahmic/autoit-js'; * - * const windowHandle = WinGetHandle('Untitled - Notepad'); - * const controlHandle = ControlGetHandle(windowHandle, 'SysListView32'); + * const windowHandle = WinGetHandleSync('Untitled - Notepad'); + * const controlHandle = ControlGetHandleSync(windowHandle, 'SysListView32'); * - * const itemCount = ControlListViewByHandle(windowHandle, controlHandle, ListViewCommand.GetItemCount); + * const itemCount = ControlListViewByHandleSync(windowHandle, controlHandle, ListViewCommand.GetItemCount); * * console.log(itemCount); // Output: "5" * ``` * * @see https://www.autoitscript.com/autoit3/docs/functions/ControlListView.htm */ -export function ControlListViewByHandle( +export function ControlListViewByHandleSync( windowHandle: bigint, controlHandle: bigint, command: ListViewCommand, @@ -48,3 +53,49 @@ export function ControlListViewByHandle( return unicodeBufferToString(buffer); } + +/** + * Interacts with a ListView control in a window. + * + * @param windowHandle The handle of the window to access. + * @param controlHandle The handle of the ListView control to interact with. + * @param command The command to execute on the ListView control. See {@linkcode ListViewCommand} for details. + * @param option1 Optional parameter for the command. + * @param option2 Optional parameter for the command. + * @param characterCount The maximum number of characters to retrieve. Default is 1024. + * + * @returns A promise that resolves to the result of the command as a string. + * + * @example + * ```typescript + * import { ControlListViewByHandle, ListViewCommand, ControlGetHandle, WinGetHandle } from '@ahmic/autoit-js'; + * + * const windowHandle = await WinGetHandle('Untitled - Notepad'); + * const controlHandle = await ControlGetHandle(windowHandle, 'SysListView32'); + * + * const itemCount = await ControlListViewByHandle(windowHandle, controlHandle, ListViewCommand.GetItemCount); + * + * console.log(itemCount); // Output: "5" + * ``` + * + * @see https://www.autoitscript.com/autoit3/docs/functions/ControlListView.htm + */ +export async function ControlListViewByHandle( + windowHandle: bigint, + controlHandle: bigint, + command: ListViewCommand, + option1: string = '', + option2: string = '', + characterCount: number = 1024, +): Promise { + const [buffer, length] = createUnicodeBuffer(characterCount); + + await autoit.invokeAsync( + 'AU3_ControlListViewByHandle', + VOID, + [HWND, HWND, LPCWSTR, LPCWSTR, LPCWSTR, LPWSTR, INT], + [windowHandle, controlHandle, command, option1, option2, buffer, length], + ); + + return unicodeBufferToString(buffer); +} diff --git a/src/control-list-view.ts b/src/control-list-view.ts index 2ec0a2e..6d684f1 100644 --- a/src/control-list-view.ts +++ b/src/control-list-view.ts @@ -89,16 +89,21 @@ export enum ListViewCommand { * * @example * ```typescript - * import { ControlListView, ListViewCommand } from '@ahmic/autoit-js'; + * import { ControlListViewSync, ListViewCommand } from '@ahmic/autoit-js'; * - * const itemCount = ControlListView('Untitled - Notepad', '', 'SysListView32', ListViewCommand.GetItemCount); + * const itemCount = ControlListViewSync( + * 'Untitled - Notepad', + * '', + * 'SysListView32', + * ListViewCommand.GetItemCount, + * ); * * console.log(itemCount); // Output: "5" * ``` * * @see https://www.autoitscript.com/autoit3/docs/functions/ControlListView.htm */ -export function ControlListView( +export function ControlListViewSync( windowTitle: string, windowText: string, controlId: string, @@ -118,3 +123,53 @@ export function ControlListView( return unicodeBufferToString(buffer); } + +/** + * Interacts with a ListView control in a window. + * + * @param windowTitle The title of the window to access. + * @param windowText Optional text found in the window. + * @param controlId The ID of the ListView control to interact with. + * @param command The command to execute on the ListView control. See {@linkcode ListViewCommand} for details. + * @param option1 Optional parameter for the command. + * @param option2 Optional parameter for the command. + * @param characters The maximum number of characters to retrieve. Default is 1024. + * + * @returns A promise that resolves to the result of the command as a string. + * + * @example + * ```typescript + * import { ControlListView, ListViewCommand } from '@ahmic/autoit-js'; + * + * const itemCount = await ControlListView( + * 'Untitled - Notepad', + * '', + * 'SysListView32', + * ListViewCommand.GetItemCount, + * ); + * + * console.log(itemCount); // Output: "5" + * ``` + * + * @see https://www.autoitscript.com/autoit3/docs/functions/ControlListView.htm + */ +export async function ControlListView( + windowTitle: string, + windowText: string, + controlId: string, + command: ListViewCommand, + option1: string = '', + option2: string = '', + characters: number = 1024, +): Promise { + const [buffer, length] = createUnicodeBuffer(characters); + + await autoit.invokeAsync( + 'AU3_ControlListView', + VOID, + [LPCWSTR, LPCWSTR, LPCWSTR, LPCWSTR, LPCWSTR, LPCWSTR, LPWSTR, INT], + [windowTitle, windowText, controlId, command, option1, option2, buffer, length], + ); + + return unicodeBufferToString(buffer); +} diff --git a/src/control-move-by-handle.ts b/src/control-move-by-handle.ts index 9b07f60..e000864 100644 --- a/src/control-move-by-handle.ts +++ b/src/control-move-by-handle.ts @@ -15,17 +15,17 @@ import { autoit } from './lib/autoit'; * * @example * ```typescript - * import { ControlMoveByHandle, ControlGetHandle, WinGetHandle } from '@ahmic/autoit-js'; + * import { ControlMoveByHandleSync, ControlGetHandleSync, WinGetHandleSync } from '@ahmic/autoit-js'; * - * const windowHandle = WinGetHandle('Untitled - Notepad'); - * const controlHandle = ControlGetHandle(windowHandle, 'Edit1'); + * const windowHandle = WinGetHandleSync('Untitled - Notepad'); + * const controlHandle = ControlGetHandleSync(windowHandle, 'Edit1'); * - * ControlMoveByHandle(windowHandle, controlHandle, 100, 100, 200, 50); + * ControlMoveByHandleSync(windowHandle, controlHandle, 100, 100, 200, 50); * ``` * * @see https://www.autoitscript.com/autoit3/docs/functions/ControlMove.htm */ -export function ControlMoveByHandle( +export function ControlMoveByHandleSync( windowHandle: bigint, controlHandle: bigint, x: number, @@ -40,3 +40,43 @@ export function ControlMoveByHandle( [windowHandle, controlHandle, x, y, width, height], ); } + +/** + * Moves and resizes a control in a window. + * + * @param windowHandle The handle of the window to access. + * @param controlHandle The handle of the control to move or resize. + * @param x The new X coordinate of the control. + * @param y The new Y coordinate of the control. + * @param width The new width of the control. Default is -1 (no change). + * @param height The new height of the control. Default is -1 (no change). + * + * @returns A promise that resolves to 1 if successful, or 0 otherwise. + * + * @example + * ```typescript + * import { ControlMoveByHandle, ControlGetHandle, WinGetHandle } from '@ahmic/autoit-js'; + * + * const windowHandle = await WinGetHandle('Untitled - Notepad'); + * const controlHandle = await ControlGetHandle(windowHandle, 'Edit1'); + * + * await ControlMoveByHandle(windowHandle, controlHandle, 100, 100, 200, 50); + * ``` + * + * @see https://www.autoitscript.com/autoit3/docs/functions/ControlMove.htm + */ +export function ControlMoveByHandle( + windowHandle: bigint, + controlHandle: bigint, + x: number, + y: number, + width: number = -1, + height: number = -1, +): Promise { + return autoit.invokeAsync( + 'AU3_ControlMoveByHandle', + INT, + [HWND, HWND, INT, INT, INT, INT], + [windowHandle, controlHandle, x, y, width, height], + ); +} diff --git a/src/control-move.ts b/src/control-move.ts index b0d0004..b4f9019 100644 --- a/src/control-move.ts +++ b/src/control-move.ts @@ -16,14 +16,14 @@ import { autoit } from './lib/autoit'; * * @example * ```typescript - * import { ControlMove } from '@ahmic/autoit-js'; + * import { ControlMoveSync } from '@ahmic/autoit-js'; * - * ControlMove('Untitled - Notepad', '', 'Edit1', 100, 100, 200, 50); + * ControlMoveSync('Untitled - Notepad', '', 'Edit1', 100, 100, 200, 50); * ``` * * @see https://www.autoitscript.com/autoit3/docs/functions/ControlMove.htm */ -export function ControlMove( +export function ControlMoveSync( windowTitle: string, windowText: string, controlId: string, @@ -40,3 +40,43 @@ export function ControlMove( [windowTitle, windowText, controlId, x, y, width, height], ); } + +/** + * Moves and resizes a control in a window. + * + * @param windowTitle The title of the window to access. + * @param windowText Optional text found in the window. + * @param controlId The ID of the control to move or resize. + * @param x The new X coordinate of the control. + * @param y The new Y coordinate of the control. + * @param width The new width of the control. Default is -1 (no change). + * @param height The new height of the control. Default is -1 (no change). + * + * @returns A promise that resolves to 1 if successful, or 0 otherwise. + * + * @example + * ```typescript + * import { ControlMove } from '@ahmic/autoit-js'; + * + * await ControlMove('Untitled - Notepad', '', 'Edit1', 100, 100, 200, 50); + * ``` + * + * @see https://www.autoitscript.com/autoit3/docs/functions/ControlMove.htm + */ +export function ControlMove( + windowTitle: string, + windowText: string, + controlId: string, + x: number, + y: number, + width: number = -1, + height: number = -1, +): Promise { + // TODO: Add an overload that allows someone to pass a Rect object + return autoit.invokeAsync( + 'AU3_ControlMove', + INT, + [LPCWSTR, LPCWSTR, LPCWSTR, INT, INT, INT, INT], + [windowTitle, windowText, controlId, x, y, width, height], + ); +} diff --git a/src/control-send-by-handle.ts b/src/control-send-by-handle.ts index ba80471..5e3f94b 100644 --- a/src/control-send-by-handle.ts +++ b/src/control-send-by-handle.ts @@ -14,17 +14,17 @@ import { SendMode } from './send'; * * @example * ```typescript - * import { ControlGetHandle, ControlSendByHandle, SendMode, WinGetHandle } from '@ahmic/autoit-js'; + * import { ControlGetHandleSync, ControlSendByHandleSync, SendMode, WinGetHandleSync } from '@ahmic/autoit-js'; * - * const windowHandle = WinGetHandle('Untitled - Notepad'); - * const controlHandle = ControlGetHandle(windowHandle, 'Edit1'); + * const windowHandle = WinGetHandleSync('Untitled - Notepad'); + * const controlHandle = ControlGetHandleSync(windowHandle, 'Edit1'); * - * ControlSendByHandle(windowHandle, controlHandle, 'Hello, World!', SendMode.Default); + * ControlSendByHandleSync(windowHandle, controlHandle, 'Hello, World!', SendMode.Default); * ``` * * @see https://www.autoitscript.com/autoit3/docs/functions/ControlSend.htm */ -export function ControlSendByHandle( +export function ControlSendByHandleSync( windowHandle: bigint, controlHandle: bigint, value: string, @@ -37,3 +37,39 @@ export function ControlSendByHandle( [windowHandle, controlHandle, value, mode], ); } + +/** + * Sends a string of text to a control in a window. + * + * @param windowHandle The handle of the window to access. + * @param controlHandle The handle of the control to interact with. + * @param value The string of text to send. + * @param mode The send mode to use. See {@linkcode SendMode} for details. Default is {@linkcode SendMode.Default}. + * + * @returns A promise that resolves to 1 if successful, or 0 otherwise. + * + * @example + * ```typescript + * import { ControlGetHandle, ControlSendByHandle, SendMode, WinGetHandle } from '@ahmic/autoit-js'; + * + * const windowHandle = await WinGetHandle('Untitled - Notepad'); + * const controlHandle = await ControlGetHandle(windowHandle, 'Edit1'); + * + * await ControlSendByHandle(windowHandle, controlHandle, 'Hello, World!', SendMode.Default); + * ``` + * + * @see https://www.autoitscript.com/autoit3/docs/functions/ControlSend.htm + */ +export function ControlSendByHandle( + windowHandle: bigint, + controlHandle: bigint, + value: string, + mode: SendMode = SendMode.Default, +): Promise { + return autoit.invokeAsync( + 'AU3_ControlSendByHandle', + INT, + [HWND, HWND, LPCWSTR, INT], + [windowHandle, controlHandle, value, mode], + ); +} diff --git a/src/control-send.ts b/src/control-send.ts index efbf980..29fc039 100644 --- a/src/control-send.ts +++ b/src/control-send.ts @@ -15,14 +15,14 @@ import { SendMode } from './send'; * * @example * ```typescript - * import { ControlSend, SendMode } from '@ahmic/autoit-js'; + * import { ControlSendSync, SendMode } from '@ahmic/autoit-js'; * - * ControlSend('Untitled - Notepad', '', 'Edit1', 'Hello, World!', SendMode.Default); + * ControlSendSync('Untitled - Notepad', '', 'Edit1', 'Hello, World!', SendMode.Default); * ``` * * @see https://www.autoitscript.com/autoit3/docs/functions/ControlSend.htm */ -export function ControlSend( +export function ControlSendSync( windowTitle: string, windowText: string, controlId: string, @@ -36,3 +36,38 @@ export function ControlSend( [windowTitle, windowText, controlId, value, mode], ); } + +/** + * Sends a string of text to a control in a window. + * + * @param windowTitle The title of the window to access. + * @param windowText Optional text found in the window. + * @param controlId The ID of the control to send text to. + * @param value The string of text to send. + * @param mode The send mode to use. See {@linkcode SendMode} for details. Default is {@linkcode SendMode.Default}. + * + * @returns A promise that resolves to 1 if successful, or 0 otherwise. + * + * @example + * ```typescript + * import { ControlSend, SendMode } from '@ahmic/autoit-js'; + * + * await ControlSend('Untitled - Notepad', '', 'Edit1', 'Hello, World!', SendMode.Default); + * ``` + * + * @see https://www.autoitscript.com/autoit3/docs/functions/ControlSend.htm + */ +export function ControlSend( + windowTitle: string, + windowText: string, + controlId: string, + value: string, + mode: SendMode = SendMode.Default, +): Promise { + return autoit.invokeAsync( + 'AU3_ControlSend', + INT, + [LPCWSTR, LPCWSTR, LPCWSTR, LPCWSTR, INT], + [windowTitle, windowText, controlId, value, mode], + ); +} diff --git a/src/control-set-text-by-handle.ts b/src/control-set-text-by-handle.ts index ff4b73a..ba8d9d4 100644 --- a/src/control-set-text-by-handle.ts +++ b/src/control-set-text-by-handle.ts @@ -12,15 +12,19 @@ import { autoit } from './lib/autoit'; * * @example * ```typescript - * import { ControlSetTextByHandle, ControlGetHandle } from '@ahmic/autoit-js'; + * import { ControlSetTextByHandleSync, ControlGetHandleSync } from '@ahmic/autoit-js'; * - * const controlHandle = ControlGetHandle(windowHandle, 'Edit1'); - * ControlSetTextByHandle(windowHandle, controlHandle, 'Hello, World!'); + * const controlHandle = ControlGetHandleSync(windowHandle, 'Edit1'); + * ControlSetTextByHandleSync(windowHandle, controlHandle, 'Hello, World!'); * ``` * * @see https://www.autoitscript.com/autoit3/docs/functions/ControlSetText.htm */ -export function ControlSetTextByHandle(windowHandle: bigint, controlHandle: bigint, value: string): number { +export function ControlSetTextByHandleSync( + windowHandle: bigint, + controlHandle: bigint, + value: string, +): number { return autoit.invoke( 'AU3_ControlSetTextByHandle', INT, @@ -28,3 +32,35 @@ export function ControlSetTextByHandle(windowHandle: bigint, controlHandle: bigi [windowHandle, controlHandle, value], ); } + +/** + * Sets the text of a control in a window. + * + * @param windowHandle The handle of the window to access. + * @param controlHandle The handle of the control to set text for. + * @param value The text to set for the control. + * + * @returns A promise that resolves to 1 if successful, or 0 otherwise. + * + * @example + * ```typescript + * import { ControlSetTextByHandle, ControlGetHandle } from '@ahmic/autoit-js'; + * + * const controlHandle = await ControlGetHandle(windowHandle, 'Edit1'); + * await ControlSetTextByHandle(windowHandle, controlHandle, 'Hello, World!'); + * ``` + * + * @see https://www.autoitscript.com/autoit3/docs/functions/ControlSetText.htm + */ +export function ControlSetTextByHandle( + windowHandle: bigint, + controlHandle: bigint, + value: string, +): Promise { + return autoit.invokeAsync( + 'AU3_ControlSetTextByHandle', + INT, + [HWND, HWND, LPCWSTR], + [windowHandle, controlHandle, value], + ); +} diff --git a/src/control-set-text.ts b/src/control-set-text.ts index 6cb9640..f44a182 100644 --- a/src/control-set-text.ts +++ b/src/control-set-text.ts @@ -13,14 +13,14 @@ import { autoit } from './lib/autoit'; * * @example * ```typescript - * import { ControlSetText } from '@ahmic/autoit-js'; + * import { ControlSetTextSync } from '@ahmic/autoit-js'; * - * ControlSetText('Untitled - Notepad', '', 'Edit1', 'Hello, World!'); + * ControlSetTextSync('Untitled - Notepad', '', 'Edit1', 'Hello, World!'); * ``` * * @see https://www.autoitscript.com/autoit3/docs/functions/ControlSetText.htm */ -export function ControlSetText( +export function ControlSetTextSync( windowTitle: string, windowText: string, controlId: string, @@ -33,3 +33,36 @@ export function ControlSetText( [windowTitle, windowText, controlId, value], ); } + +/** + * Sets the text of a control in a window. + * + * @param windowTitle The title of the window to search for. + * @param windowText Optional text found in the window. + * @param controlId The ID of the control to set text for. + * @param value The text to set for the control. + * + * @returns A promise that resolves to 1 if successful, or 0 otherwise. + * + * @example + * ```typescript + * import { ControlSetText } from '@ahmic/autoit-js'; + * + * await ControlSetText('Untitled - Notepad', '', 'Edit1', 'Hello, World!'); + * ``` + * + * @see https://www.autoitscript.com/autoit3/docs/functions/ControlSetText.htm + */ +export function ControlSetText( + windowTitle: string, + windowText: string, + controlId: string, + value: string, +): Promise { + return autoit.invokeAsync( + 'AU3_ControlSetText', + INT, + [LPCWSTR, LPCWSTR, LPCWSTR, LPCWSTR], + [windowTitle, windowText, controlId, value], + ); +} diff --git a/src/control-show-by-handle.ts b/src/control-show-by-handle.ts index 9a007fa..d815f17 100644 --- a/src/control-show-by-handle.ts +++ b/src/control-show-by-handle.ts @@ -11,16 +11,40 @@ import { autoit } from './lib/autoit'; * * @example * ```typescript - * import { ControlShowByHandle, ControlGetHandle, WinGetHandle } from '@ahmic/autoit-js'; + * import { ControlShowByHandleSync, ControlGetHandleSync, WinGetHandleSync } from '@ahmic/autoit-js'; * - * const windowHandle = WinGetHandle('Untitled - Notepad'); - * const controlHandle = ControlGetHandle(windowHandle, 'Edit1'); + * const windowHandle = WinGetHandleSync('Untitled - Notepad'); + * const controlHandle = ControlGetHandleSync(windowHandle, 'Edit1'); * - * ControlShowByHandle(windowHandle, controlHandle); + * ControlShowByHandleSync(windowHandle, controlHandle); * ``` * * @see https://www.autoitscript.com/autoit3/docs/functions/ControlShow.htm */ -export function ControlShowByHandle(windowHandle: bigint, controlHandle: bigint): number { +export function ControlShowByHandleSync(windowHandle: bigint, controlHandle: bigint): number { return autoit.invoke('AU3_ControlShowByHandle', INT, [HWND, HWND], [windowHandle, controlHandle]); } + +/** + * Shows a control in a window. + * + * @param windowHandle The handle of the window to access. + * @param controlHandle The handle of the control to show. + * + * @returns A promise that resolves to 1 if successful, or 0 otherwise. + * + * @example + * ```typescript + * import { ControlShowByHandle, ControlGetHandle, WinGetHandle } from '@ahmic/autoit-js'; + * + * const windowHandle = await WinGetHandle('Untitled - Notepad'); + * const controlHandle = await ControlGetHandle(windowHandle, 'Edit1'); + * + * await ControlShowByHandle(windowHandle, controlHandle); + * ``` + * + * @see https://www.autoitscript.com/autoit3/docs/functions/ControlShow.htm + */ +export function ControlShowByHandle(windowHandle: bigint, controlHandle: bigint): Promise { + return autoit.invokeAsync('AU3_ControlShowByHandle', INT, [HWND, HWND], [windowHandle, controlHandle]); +} diff --git a/src/control-show.ts b/src/control-show.ts index d04d8cf..7974c0e 100644 --- a/src/control-show.ts +++ b/src/control-show.ts @@ -12,14 +12,14 @@ import { autoit } from './lib/autoit'; * * @example * ```typescript - * import { ControlShow } from '@ahmic/autoit-js'; + * import { ControlShowSync } from '@ahmic/autoit-js'; * - * ControlShow('Untitled - Notepad', '', 'Edit1'); + * ControlShowSync('Untitled - Notepad', '', 'Edit1'); * ``` * * @see https://www.autoitscript.com/autoit3/docs/functions/ControlShow.htm */ -export function ControlShow(windowTitle: string, windowText: string, controlId: string): number { +export function ControlShowSync(windowTitle: string, windowText: string, controlId: string): number { return autoit.invoke( 'AU3_ControlShow', INT, @@ -27,3 +27,30 @@ export function ControlShow(windowTitle: string, windowText: string, controlId: [windowTitle, windowText, controlId], ); } + +/** + * Shows a control in a window. + * + * @param windowTitle The title of the window to search for. + * @param windowText Optional text found in the window. + * @param controlId The ID of the control to show. + * + * @returns A promise that resolves to 1 if successful, or 0 otherwise. + * + * @example + * ```typescript + * import { ControlShow } from '@ahmic/autoit-js'; + * + * await ControlShow('Untitled - Notepad', '', 'Edit1'); + * ``` + * + * @see https://www.autoitscript.com/autoit3/docs/functions/ControlShow.htm + */ +export function ControlShow(windowTitle: string, windowText: string, controlId: string): Promise { + return autoit.invokeAsync( + 'AU3_ControlShow', + INT, + [LPCWSTR, LPCWSTR, LPCWSTR], + [windowTitle, windowText, controlId], + ); +} diff --git a/src/control-tree-view-by-handle.ts b/src/control-tree-view-by-handle.ts index ba00575..580242c 100644 --- a/src/control-tree-view-by-handle.ts +++ b/src/control-tree-view-by-handle.ts @@ -16,18 +16,18 @@ import { createUnicodeBuffer, unicodeBufferToString } from './util'; * * @example * ```typescript - * import { ControlTreeViewByHandle, WinGetHandle, ControlGetHandle } from '@ahmic/autoit-js'; + * import { ControlTreeViewByHandleSync, WinGetHandleSync, ControlGetHandleSync } from '@ahmic/autoit-js'; * - * const windowHandle = WinGetHandle('Untitled - Notepad'); - * const controlHandle = ControlGetHandle(windowHandle, 'SysTreeView32'); - * const result = ControlTreeViewByHandle(windowHandle, controlHandle, 'GetItemCount'); + * const windowHandle = WinGetHandleSync('Untitled - Notepad'); + * const controlHandle = ControlGetHandleSync(windowHandle, 'SysTreeView32'); + * const result = ControlTreeViewByHandleSync(windowHandle, controlHandle, 'GetItemCount'); * * console.log(result); // Output: "5" * ``` * * @see https://www.autoitscript.com/autoit3/docs/functions/ControlTreeView.htm */ -export function ControlTreeViewByHandle( +export function ControlTreeViewByHandleSync( windowHandle: bigint, controlHandle: bigint, command: TreeViewCommand, @@ -46,3 +46,47 @@ export function ControlTreeViewByHandle( return unicodeBufferToString(buffer); } + +/** + * Interacts with a tree view control in a window. + * + * @param windowHandle The handle of the window to access. + * @param controlHandle The handle of the tree view control to interact with. + * @param command The command to send to the tree view control. + * @param option1 Optional parameter for the command. + * @param option2 Optional parameter for the command. + * + * @returns A promise that resolves to the result of the command as a string. + * + * @example + * ```typescript + * import { ControlTreeViewByHandle, WinGetHandle, ControlGetHandle } from '@ahmic/autoit-js'; + * + * const windowHandle = await WinGetHandle('Untitled - Notepad'); + * const controlHandle = await ControlGetHandle(windowHandle, 'SysTreeView32'); + * const result = await ControlTreeViewByHandle(windowHandle, controlHandle, 'GetItemCount'); + * + * console.log(result); // Output: "5" + * ``` + * + * @see https://www.autoitscript.com/autoit3/docs/functions/ControlTreeView.htm + */ +export async function ControlTreeViewByHandle( + windowHandle: bigint, + controlHandle: bigint, + command: TreeViewCommand, + option1: string = '', + option2: string = '', + characterCount: number = 1024, +): Promise { + const [buffer, length] = createUnicodeBuffer(characterCount); + + await autoit.invokeAsync( + 'AU3_ControlTreeViewByHandle', + VOID, + [HWND, HWND, LPCWSTR, LPCWSTR, LPCWSTR, LPWSTR, INT], + [windowHandle, controlHandle, command, option1, option2, buffer, length], + ); + + return unicodeBufferToString(buffer); +} diff --git a/src/control-tree-view.ts b/src/control-tree-view.ts index 9f13279..2a50ee7 100644 --- a/src/control-tree-view.ts +++ b/src/control-tree-view.ts @@ -34,6 +34,11 @@ export enum TreeViewCommand { /** * Returns the item reference of the current selection using the text reference of the item (or index * reference if UseIndex is set to 1). + * + * | UseIndex | Result | Example | + * |----------|-----------------|---------| + * | `''` | Text reference | Child 2 | + * | `'1'` | Index reference | #2 | */ GetSelected = 'GetSelected', @@ -78,16 +83,16 @@ export enum TreeViewCommand { * * @example * ```typescript - * import { ControlTreeView } from '@ahmic/autoit-js'; + * import { ControlTreeViewSync } from '@ahmic/autoit-js'; * - * const result = ControlTreeView('Untitled - Notepad', '', 'SysTreeView32', 'GetItemCount'); + * const result = ControlTreeViewSync('Untitled - Notepad', '', 'SysTreeView32', 'GetItemCount'); * * console.log(result); // Output: "5" * ``` * * @see https://www.autoitscript.com/autoit3/docs/functions/ControlTreeView.htm */ -export function ControlTreeView( +export function ControlTreeViewSync( windowTitle: string, windowText: string, controlId: string, @@ -107,3 +112,47 @@ export function ControlTreeView( return unicodeBufferToString(buffer); } + +/** + * Interacts with a tree view control in a window. + * + * @param windowTitle The title of the window to access. + * @param windowText Optional text found in the window. + * @param controlId The ID of the tree view control to interact with. + * @param command The command to send to the tree view control. + * @param option1 Optional parameter for the command. + * @param option2 Optional parameter for the command. + * + * @returns A promise that resolves to the result of the command as a string. + * + * @example + * ```typescript + * import { ControlTreeView } from '@ahmic/autoit-js'; + * + * const result = await ControlTreeView('Untitled - Notepad', '', 'SysTreeView32', 'GetItemCount'); + * + * console.log(result); // Output: "5" + * ``` + * + * @see https://www.autoitscript.com/autoit3/docs/functions/ControlTreeView.htm + */ +export async function ControlTreeView( + windowTitle: string, + windowText: string, + controlId: string, + command: TreeViewCommand, + option1: string = '', + option2: string = '', + characterCount: number = 1024, +): Promise { + const [buffer, length] = createUnicodeBuffer(characterCount); + + await autoit.invokeAsync( + 'AU3_ControlTreeView', + VOID, + [LPCWSTR, LPCWSTR, LPCWSTR, LPCWSTR, LPCWSTR, LPCWSTR, LPWSTR, INT], + [windowTitle, windowText, controlId, command, option1, option2, buffer, length], + ); + + return unicodeBufferToString(buffer); +} diff --git a/src/drive-map-add.ts b/src/drive-map-add.ts index 1d3d1df..909ba46 100644 --- a/src/drive-map-add.ts +++ b/src/drive-map-add.ts @@ -29,14 +29,14 @@ export enum DriveMapFlag { * * @example * ```typescript - * import { DriveMapAdd, DriveMapFlag } from '@ahmic/autoit-js'; + * import { DriveMapAddSync, DriveMapFlag } from '@ahmic/autoit-js'; * - * DriveMapAdd('Z:', '\\server\share', DriveMapFlag.Authentication, 'user', 'password'); + * DriveMapAddSync('Z:', '\\server\share', DriveMapFlag.Authentication, 'user', 'password'); * ``` * * @see https://www.autoitscript.com/autoit3/docs/functions/DriveMapAdd.htm */ -export function DriveMapAdd( +export function DriveMapAddSync( device: string, share: string, flags: DriveMapFlag = DriveMapFlag.Default, @@ -54,3 +54,42 @@ export function DriveMapAdd( return unicodeBufferToString(buffer); } + +/** + * Maps a network drive to a local drive letter. + * + * @param device The local drive letter to map. + * @param share The network share to map to. + * @param flags Optional flags to control the mapping behavior. + * @param username Optional username for authentication. + * @param password Optional password for authentication. + * + * @returns A promise that resolves to "1" if successful, "0" if failed. + * + * @example + * ```typescript + * import { DriveMapAdd, DriveMapFlag } from '@ahmic/autoit-js'; + * + * await DriveMapAdd('Z:', '\\server\share', DriveMapFlag.Authentication, 'user', 'password'); + * ``` + * + * @see https://www.autoitscript.com/autoit3/docs/functions/DriveMapAdd.htm + */ +export async function DriveMapAdd( + device: string, + share: string, + flags: DriveMapFlag = DriveMapFlag.Default, + username: string = '', + password: string = '', +): Promise { + const [buffer, length] = createUnicodeBuffer(1024); + + await autoit.invokeAsync( + 'AU3_DriveMapAdd', + VOID, + [LPCWSTR, LPCWSTR, INT, LPCWSTR, LPCWSTR, LPWSTR, INT], + [device, share, flags, username, password, buffer, length], + ); + + return unicodeBufferToString(buffer); +} diff --git a/src/drive-map-del.ts b/src/drive-map-del.ts index b29e70e..3e96274 100644 --- a/src/drive-map-del.ts +++ b/src/drive-map-del.ts @@ -10,13 +10,33 @@ import { autoit } from './lib/autoit'; * * @example * ```typescript - * import { DriveMapDel } from '@ahmic/autoit-js'; + * import { DriveMapDelSync } from '@ahmic/autoit-js'; * - * DriveMapDel('Z:'); + * DriveMapDelSync('Z:'); * ``` * * @see https://www.autoitscript.com/autoit3/docs/functions/DriveMapDel.htm */ -export function DriveMapDel(device: string): number { +export function DriveMapDelSync(device: string): number { return autoit.invoke('AU3_DriveMapDel', INT, [LPCWSTR], [device]); } + +/** + * Removes a mapped network drive. + * + * @param device The local drive letter to unmap (e.g., 'Z:'). + * + * @returns A promise that resolves to 1 if successful, 0 otherwise. + * + * @example + * ```typescript + * import { DriveMapDel } from '@ahmic/autoit-js'; + * + * await DriveMapDel('Z:'); + * ``` + * + * @see https://www.autoitscript.com/autoit3/docs/functions/DriveMapDel.htm + */ +export function DriveMapDel(device: string): Promise { + return autoit.invokeAsync('AU3_DriveMapDel', INT, [LPCWSTR], [device]); +} diff --git a/src/drive-map-get.ts b/src/drive-map-get.ts index 2cf2cd9..0da16c4 100644 --- a/src/drive-map-get.ts +++ b/src/drive-map-get.ts @@ -12,6 +12,34 @@ import { createUnicodeBuffer, unicodeBufferToString } from './util'; * * @example * ```typescript + * import { DriveMapGetSync } from '@ahmic/autoit-js'; + * + * const networkShare = DriveMapGetSync('Z:'); + * + * console.log(networkShare); // Output: "\\server\share" + * ``` + * + * @see https://www.autoitscript.com/autoit3/docs/functions/DriveMapGet.htm + */ +export function DriveMapGetSync(device: string, characterCount: number = 1024): string { + const [buffer, length] = createUnicodeBuffer(characterCount); + + autoit.invoke('AU3_DriveMapGet', VOID, [LPCWSTR, LPWSTR, INT], [device, buffer, length]); + + return unicodeBufferToString(buffer); +} + +/** + * Retrieves the network share associated with a local drive letter. + * + * @param device The local drive letter to query. + * @param characterCount The maximum number of characters to retrieve (default is 1024). + * + * @returns A promise that resolves to the network share associated with the local drive letter, or an empty + * string if not found. + * + * @example + * ```typescript * import { DriveMapGet } from '@ahmic/autoit-js'; * * const networkShare = DriveMapGet('Z:'); @@ -21,10 +49,10 @@ import { createUnicodeBuffer, unicodeBufferToString } from './util'; * * @see https://www.autoitscript.com/autoit3/docs/functions/DriveMapGet.htm */ -export function DriveMapGet(device: string, characterCount: number = 1024): string { +export async function DriveMapGet(device: string, characterCount: number = 1024): Promise { const [buffer, length] = createUnicodeBuffer(characterCount); - autoit.invoke('AU3_DriveMapGet', VOID, [LPCWSTR, LPWSTR, INT], [device, buffer, length]); + await autoit.invokeAsync('AU3_DriveMapGet', VOID, [LPCWSTR, LPWSTR, INT], [device, buffer, length]); return unicodeBufferToString(buffer); } diff --git a/src/error.ts b/src/error.ts index 2d219f7..e9ef925 100644 --- a/src/error.ts +++ b/src/error.ts @@ -7,12 +7,36 @@ import { autoit } from './lib/autoit'; * @returns The error code. * * @example - * const result = error(); + * ```typescript + * import { errorSync } from '@ahmic/autoit-js'; + * + * const result = errorSync(); * * console.log(result); // Output: 1 (example output, actual value depends on the last AutoIt function call) + * ``` * * @see https://www.autoitscript.com/autoit3/docs/functions/SetError.htm */ -export function error(): number { +export function errorSync(): number { return autoit.invoke('AU3_error', INT, [], []); } + +/** + * Retrieves the error code set by the last AutoIt function call. + * + * @returns A promise that resolves to the error code. + * + * @example + * ```typescript + * import { error } from '@ahmic/autoit-js'; + * + * const result = await error(); + * + * console.log(result); // Output: 1 (example output, actual value depends on the last AutoIt function call) + * ``` + * + * @see https://www.autoitscript.com/autoit3/docs/functions/SetError.htm + */ +export function error(): Promise { + return autoit.invokeAsync('AU3_error', INT, [], []); +} diff --git a/src/index.ts b/src/index.ts index 2f5312d..6eed466 100644 --- a/src/index.ts +++ b/src/index.ts @@ -103,11 +103,11 @@ export * from './win-minimize-all-undo'; export * from './win-minimize-all'; export * from './win-move-by-handle'; export * from './win-move'; -export * from './win-set-new-title-by-handle'; export * from './win-set-on-top-by-handle'; export * from './win-set-on-top'; export * from './win-set-state-by-handle'; export * from './win-set-state'; +export * from './win-set-title-by-handle'; export * from './win-set-title'; export * from './win-set-trans-by-handle'; export * from './win-set-trans'; diff --git a/src/init.ts b/src/init.ts index 2cd7d9a..49fa700 100644 --- a/src/init.ts +++ b/src/init.ts @@ -6,11 +6,25 @@ import { autoit } from './lib/autoit'; * * @example * ```typescript - * import { Init } from '@ahmic/autoit-js'; + * import { InitSync } from '@ahmic/autoit-js'; * - * Init(); + * InitSync(); * ``` */ -export function Init(): void { +export function InitSync(): void { return autoit.invoke('AU3_Init', VOID, [], []); } + +/** + * Initializes the AutoIt library. + * + * @example + * ```typescript + * import { Init } from '@ahmic/autoit-js'; + * + * await Init(); + * ``` + */ +export function Init(): Promise { + return autoit.invokeAsync('AU3_Init', VOID, [], []); +} diff --git a/src/is-admin.ts b/src/is-admin.ts index 2612e09..78ab59e 100644 --- a/src/is-admin.ts +++ b/src/is-admin.ts @@ -8,15 +8,37 @@ import { autoit } from './lib/autoit'; * * @example * ```typescript - * import { IsAdmin } from '@ahmic/autoit-js'; + * import { IsAdminSync } from '@ahmic/autoit-js'; * - * const isAdmin = IsAdmin(); + * const isAdmin = IsAdminSync(); * * console.log(isAdmin); // Output: true * ``` * * @see https://www.autoitscript.com/autoit3/docs/functions/IsAdmin.htm */ -export function IsAdmin(): boolean { +export function IsAdminSync(): boolean { return autoit.invoke('AU3_IsAdmin', INT, [], []) === 1; } + +/** + * Checks if the current user has administrative privileges. + * + * @returns A promise that resolves to `true` if the user has administrative privileges, `false` otherwise. + * + * @example + * ```typescript + * import { IsAdmin } from '@ahmic/autoit-js'; + * + * const isAdmin = await IsAdmin(); + * + * console.log(isAdmin); // Output: true + * ``` + * + * @see https://www.autoitscript.com/autoit3/docs/functions/IsAdmin.htm + */ +export async function IsAdmin(): Promise { + const isAdmin = await autoit.invokeAsync('AU3_IsAdmin', INT, [], []); + + return isAdmin === 1; +} diff --git a/src/lib/autoit.ts b/src/lib/autoit.ts index d3261c5..1050dc5 100644 --- a/src/lib/autoit.ts +++ b/src/lib/autoit.ts @@ -74,7 +74,7 @@ export class AutoIt { } /** - * Invokes a function from the AutoItX3 DLL. + * Invokes a function from the AutoItX3 DLL synchronously. * * @param functionName The name of the function to invoke. * @param functionReturnType The return type of the function. @@ -92,6 +92,68 @@ export class AutoIt { functionArgumentTypes: FunctionArgumentTypes, functionArguments: unknown[], ): NonNullable { + const func = this.getFunction(functionName, functionReturnType, functionArgumentTypes); + + const output = func(...functionArguments); + + this.logger.logFunctionCall(functionName, functionArguments, output); + + return output; + } + + /** + * Invokes a function from the AutoItX3 DLL asynchronously. + * + * @param functionName The name of the function to invoke. + * @param functionReturnType The return type of the function. + * @param functionArgumentTypes The argument types of the function. + * @param functionArguments The arguments to pass to the function. + * + * @returns A promise that resolves with the result of the function call. + */ + invokeAsync< + FunctionReturnType extends Win32Type>, + const FunctionArgumentTypes extends Win32Type>[], + >( + functionName: string, + functionReturnType: FunctionReturnType, + functionArgumentTypes: FunctionArgumentTypes, + functionArguments: unknown[], + ) { + return new Promise>((resolve, reject) => { + let func: KoffiFunction; + + try { + func = this.getFunction(functionName, functionReturnType, functionArgumentTypes); + } catch (error) { + reject(error); + return; + } + + func.async( + ...functionArguments, + (error: Error, result: NonNullable) => { + if (error) { + reject(error); + return; + } + + this.logger.logFunctionCall(functionName, functionArguments, result); + + resolve(result); + }, + ); + }); + } + + private getFunction< + FunctionReturnType extends Win32Type>, + const FunctionArgumentTypes extends Win32Type>[], + >( + functionName: string, + functionReturnType: FunctionReturnType, + functionArgumentTypes: FunctionArgumentTypes, + ): KoffiFunction { if (!this.lib) { throw new Error('You must call load() before invoking functions'); } @@ -104,32 +166,8 @@ export class AutoIt { this.functionCache[functionName] = func; } - const output = func(...functionArguments); - - this.logger.logFunctionCall(functionName, functionArguments, output); - - return output; + return func; } - - // TODO: Implement async function invocation - // invokeAsync< - // FunctionReturnType extends Win32Type>, - // const FunctionArgumentTypes extends Win32Type>[], - // >( - // functionName: string, - // functionReturnType: FunctionReturnType, - // functionArgumentTypes: FunctionArgumentTypes, - // functionArguments: unknown[], - // callback: (result: NonNullable) => void, - // ) { - // if (!this.lib) { - // throw new Error('You must call load() before invoking functions'); - // } - - // const func = this.lib.func('__stdcall', functionName, functionReturnType, functionArgumentTypes); - - // func.async(...functionArguments, callback); - // } } /** diff --git a/src/lib/gdi32.ts b/src/lib/gdi32.ts index 04d22d4..1d71173 100644 --- a/src/lib/gdi32.ts +++ b/src/lib/gdi32.ts @@ -17,10 +17,11 @@ import { UnsignedInt, } from '../@types'; import { IBitmapInfo, LPBITMAPINFO } from '../@types/bitmap-info'; +import { typedPromisify } from '../util'; const gdi32 = koffi.load('gdi32.dll'); -export const BitBlt: koffi.KoffiFunc< +export const BitBltSync: koffi.KoffiFunc< ( hdc: DeviceContextHandle, x: Int, @@ -34,15 +35,15 @@ export const BitBlt: koffi.KoffiFunc< ) => boolean > = gdi32.func('__stdcall', 'BitBlt', BOOL, [HDC, INT, INT, INT, INT, HDC, INT, INT, DWORD]); -export const CreateCompatibleDC: koffi.KoffiFunc< +export const CreateCompatibleDCSync: koffi.KoffiFunc< (deviceContextHandle: DeviceContextHandle) => DeviceContextHandle > = gdi32.func('__stdcall', 'CreateCompatibleDC', HDC, [HDC]); -export const CreateCompatibleBitmap: koffi.KoffiFunc< +export const CreateCompatibleBitmapSync: koffi.KoffiFunc< (deviceContextHandle: DeviceContextHandle, width: Int, height: Int) => BitmapHandle > = gdi32.func('__stdcall', 'CreateCompatibleBitmap', HBITMAP, [HDC, INT, INT]); -export const GetDIBits: koffi.KoffiFunc< +export const GetDIBitsSync: koffi.KoffiFunc< ( hdc: DeviceContextHandle, hbitmap: BitmapHandle, @@ -62,20 +63,28 @@ export const GetDIBits: koffi.KoffiFunc< UINT, ]); -export const SelectObject: koffi.KoffiFunc< +export const SelectObjectSync: koffi.KoffiFunc< (deviceContextHandle: DeviceContextHandle, bitmapHandle: BitmapHandle) => BitmapHandle > = gdi32.func('__stdcall', 'SelectObject', HBITMAP, [HDC, HBITMAP]); -export const DeleteObject: koffi.KoffiFunc<(bitmapHandle: BitmapHandle) => Bool> = gdi32.func( +export const DeleteObjectSync: koffi.KoffiFunc<(bitmapHandle: BitmapHandle) => Bool> = gdi32.func( '__stdcall', 'DeleteObject', BOOL, [HBITMAP], ); -export const DeleteDC: koffi.KoffiFunc<(deviceContextHandle: DeviceContextHandle) => Bool> = gdi32.func( +export const DeleteDCSync: koffi.KoffiFunc<(deviceContextHandle: DeviceContextHandle) => Bool> = gdi32.func( '__stdcall', 'DeleteDC', BOOL, [HDC], ); + +export const BitBlt = typedPromisify(BitBltSync.async); +export const CreateCompatibleDC = typedPromisify(CreateCompatibleDCSync.async); +export const CreateCompatibleBitmap = typedPromisify(CreateCompatibleBitmapSync.async); +export const GetDIBits = typedPromisify(GetDIBitsSync.async); +export const SelectObject = typedPromisify(SelectObjectSync.async); +export const DeleteObject = typedPromisify(DeleteObjectSync.async); +export const DeleteDC = typedPromisify(DeleteDCSync.async); diff --git a/src/lib/kernel32.ts b/src/lib/kernel32.ts new file mode 100644 index 0000000..48f5b54 --- /dev/null +++ b/src/lib/kernel32.ts @@ -0,0 +1,16 @@ +import koffi from 'koffi'; + +import { DWORD, DoubleWord, VOID } from '../@types/win32'; +import { typedPromisify } from '../util'; + +const kernel32 = koffi.load('kernel32.dll'); + +// Named WinSleep to avoid name collisions with AutoIt's Sleep function. +export const WinSleepSync: koffi.KoffiFunc<(milliseconds: DoubleWord) => void> = kernel32.func( + '__stdcall', + 'Sleep', + VOID, + [DWORD], +); + +export const WinSleep = typedPromisify(WinSleepSync.async); diff --git a/src/lib/user32.ts b/src/lib/user32.ts index 638e4e9..b74fad9 100644 --- a/src/lib/user32.ts +++ b/src/lib/user32.ts @@ -28,6 +28,7 @@ import { WindowHandle, WordParam, } from '../@types'; +import { typedPromisify } from '../util'; const user32 = koffi.load('user32.dll'); @@ -35,18 +36,21 @@ export function MAKELPARAM(low: number, high: number): number { return (low & 0xffff) | ((high & 0xffff) << 16); } -export const GetDC: koffi.KoffiFunc<(windowHandle: WindowHandle | null) => DeviceContextHandle> = user32.func( +export const GetDesktopWindowSync: koffi.KoffiFunc<() => WindowHandle> = user32.func( '__stdcall', - 'GetDC', - HDC, - [HWND], + 'GetDesktopWindow', + HWND, + [], ); -export const ReleaseDC: koffi.KoffiFunc< +export const GetDCSync: koffi.KoffiFunc<(windowHandle: WindowHandle | null) => DeviceContextHandle> = + user32.func('__stdcall', 'GetDC', HDC, [HWND]); + +export const ReleaseDCSync: koffi.KoffiFunc< (windowHandle: WindowHandle | null, deviceContextHandle: DeviceContextHandle) => Int > = user32.func('__stdcall', 'ReleaseDC', INT, [HWND, HDC]); -export const CreateWindowExW: koffi.KoffiFunc< +export const CreateWindowExWSync: koffi.KoffiFunc< ( extendedWindowStyle: DoubleWord, className: LongPointerToConstantWideString | null, @@ -76,13 +80,20 @@ export const CreateWindowExW: koffi.KoffiFunc< LPVOID, ]); -export const SendMessageW: koffi.KoffiFunc< +export const SendMessageWSync: koffi.KoffiFunc< (windowHandle: WindowHandle, message: UnsignedInt, wParam: WordParam, lParam: LongParam) => LongResult > = user32.func('__stdcall', 'SendMessageW', LRESULT, [HWND, UINT, WPARAM, LPARAM]); -export const DestroyWindow: koffi.KoffiFunc<(windowHandle: WindowHandle) => Bool> = user32.func( +export const DestroyWindowSync: koffi.KoffiFunc<(windowHandle: WindowHandle) => Bool> = user32.func( '__stdcall', 'DestroyWindow', BOOL, [HWND], ); + +export const GetDesktopWindow = typedPromisify(GetDesktopWindowSync.async); +export const GetDC = typedPromisify(GetDCSync.async); +export const ReleaseDC = typedPromisify(ReleaseDCSync.async); +export const CreateWindowExW = typedPromisify(CreateWindowExWSync.async); +export const SendMessageW = typedPromisify(SendMessageWSync.async); +export const DestroyWindow = typedPromisify(DestroyWindowSync.async); diff --git a/src/mouse-click-drag.ts b/src/mouse-click-drag.ts index ec11eec..4e0aee0 100644 --- a/src/mouse-click-drag.ts +++ b/src/mouse-click-drag.ts @@ -12,16 +12,18 @@ import { MouseButton } from './mouse-click'; * @param endY The ending Y coordinate. * @param speed The speed of the drag (1 is fast, 100 is slow). * + * @returns 1 if successful, 0 otherwise. + * * @example * ```typescript - * import { MouseClickDrag } from '@ahmic/autoit-js'; + * import { MouseClickDragSync, MouseButton } from '@ahmic/autoit-js'; * - * MouseClickDrag('left', 100, 100, 200, 200, 10); + * MouseClickDragSync(MouseButton.Left, 100, 100, 200, 200, 10); * ``` * * @see https://www.autoitscript.com/autoit3/docs/functions/MouseClickDrag.htm */ -export function MouseClickDrag( +export function MouseClickDragSync( button: MouseButton, startX: number, startY: number, @@ -36,3 +38,40 @@ export function MouseClickDrag( [button, startX, startY, endX, endY, speed], ); } + +/** + * Drags the mouse from a start position to an end position. + * + * @param button The mouse button to use. See {@linkcode MouseButton} for details. + * @param startX The starting X coordinate. + * @param startY The starting Y coordinate. + * @param endX The ending X coordinate. + * @param endY The ending Y coordinate. + * @param speed The speed of the drag (1 is fast, 100 is slow). + * + * @returns A promise that resolves to 1 if successful, or 0 otherwise. + * + * @example + * ```typescript + * import { MouseClickDrag, MouseButton } from '@ahmic/autoit-js'; + * + * await MouseClickDrag(MouseButton.Left, 100, 100, 200, 200, 10); + * ``` + * + * @see https://www.autoitscript.com/autoit3/docs/functions/MouseClickDrag.htm + */ +export function MouseClickDrag( + button: MouseButton, + startX: number, + startY: number, + endX: number, + endY: number, + speed: number = -1, +): Promise { + return autoit.invokeAsync( + 'AU3_MouseClickDrag', + INT, + [LPCWSTR, INT, INT, INT, INT, INT], + [button, startX, startY, endX, endY, speed], + ); +} diff --git a/src/mouse-click.ts b/src/mouse-click.ts index 3552e39..c828559 100644 --- a/src/mouse-click.ts +++ b/src/mouse-click.ts @@ -36,16 +36,18 @@ export enum MouseButton { * @param clicks The number of times to click. * @param speed The speed of the click (1 is fast, 100 is slow). * + * @returns 1 if successful, 0 otherwise + * * @example * ```typescript - * import { MouseClick } from '@ahmic/autoit-js'; + * import { MouseClickSync, MouseButton } from '@ahmic/autoit-js'; * - * MouseClick('left', 150, 150, 2, 10); + * MouseClickSync(MouseButton.Left, 150, 150, 2, 10); * ``` * * @see https://www.autoitscript.com/autoit3/docs/functions/MouseClick.htm */ -export function MouseClick( +export function MouseClickSync( button: MouseButton = MouseButton.Left, x: number = AU3_INTDEFAULT, y: number = AU3_INTDEFAULT, @@ -54,3 +56,38 @@ export function MouseClick( ): number { return autoit.invoke('AU3_MouseClick', INT, [LPCWSTR, INT, INT, INT, INT], [button, x, y, clicks, speed]); } + +/** + * Simulates a mouse click at the specified coordinates. + * + * @param button The mouse button to click. See {@linkcode MouseButton} for details. + * @param x The X coordinate to click at. + * @param y The Y coordinate to click at. + * @param clicks The number of times to click. + * @param speed The speed of the click (1 is fast, 100 is slow). + * + * @returns A promise that resolves to 1 if successful, or 0 otherwise. + * + * @example + * ```typescript + * import { MouseClick, MouseButton } from '@ahmic/autoit-js'; + * + * await MouseClick(MouseButton.Left, 150, 150, 2, 10); + * ``` + * + * @see https://www.autoitscript.com/autoit3/docs/functions/MouseClick.htm + */ +export function MouseClick( + button: MouseButton = MouseButton.Left, + x: number = AU3_INTDEFAULT, + y: number = AU3_INTDEFAULT, + clicks: number = 1, + speed: number = -1, +): Promise { + return autoit.invokeAsync( + 'AU3_MouseClick', + INT, + [LPCWSTR, INT, INT, INT, INT], + [button, x, y, clicks, speed], + ); +} diff --git a/src/mouse-down.ts b/src/mouse-down.ts index 4151892..5afabc3 100644 --- a/src/mouse-down.ts +++ b/src/mouse-down.ts @@ -9,13 +9,31 @@ import { MouseButton } from './mouse-click'; * * @example * ```typescript - * import { MouseDown } from '@ahmic/autoit-js'; + * import { MouseDownSync, MouseButton } from '@ahmic/autoit-js'; * - * MouseDown('left'); + * MouseDownSync(MouseButton.Left); * ``` * * @see https://www.autoitscript.com/autoit3/docs/functions/MouseDown.htm */ -export function MouseDown(button: MouseButton = MouseButton.Left): void { +export function MouseDownSync(button: MouseButton = MouseButton.Left): void { return autoit.invoke('AU3_MouseDown', VOID, [LPCWSTR], [button]); } + +/** + * Simulates holding down a mouse button. + * + * @param button The mouse button to hold down. See {@linkcode MouseButton} for details. + * + * @example + * ```typescript + * import { MouseDown, MouseButton } from '@ahmic/autoit-js'; + * + * await MouseDown(MouseButton.Left); + * ``` + * + * @see https://www.autoitscript.com/autoit3/docs/functions/MouseDown.htm + */ +export function MouseDown(button: MouseButton = MouseButton.Left): Promise { + return autoit.invokeAsync('AU3_MouseDown', VOID, [LPCWSTR], [button]); +} diff --git a/src/mouse-get-cursor.ts b/src/mouse-get-cursor.ts index f48d874..36f9ac3 100644 --- a/src/mouse-get-cursor.ts +++ b/src/mouse-get-cursor.ts @@ -77,15 +77,35 @@ export enum Cursor { * * @example * ```typescript - * import { MouseGetCursor } from '@ahmic/autoit-js'; + * import { MouseGetCursorSync } from '@ahmic/autoit-js'; * - * const cursorId = MouseGetCursor(); + * const cursorId = MouseGetCursorSync(); * * console.log(cursorId); // Output: 2 * ``` * * @see https://www.autoitscript.com/autoit3/docs/functions/MouseGetCursor.htm */ -export function MouseGetCursor(): Cursor { +export function MouseGetCursorSync(): Cursor { return autoit.invoke('AU3_MouseGetCursor', INT, [], []); } + +/** + * Retrieves the current mouse cursor ID. + * + * @returns A promise that resolves to the ID of the current mouse cursor. + * + * @example + * ```typescript + * import { MouseGetCursor } from '@ahmic/autoit-js'; + * + * const cursorId = await MouseGetCursor(); + * + * console.log(cursorId); // Output: 2 + * ``` + * + * @see https://www.autoitscript.com/autoit3/docs/functions/MouseGetCursor.htm + */ +export function MouseGetCursor(): Promise { + return autoit.invokeAsync('AU3_MouseGetCursor', INT, [], []); +} diff --git a/src/mouse-get-pos.ts b/src/mouse-get-pos.ts index f77ee8f..67c7c1d 100644 --- a/src/mouse-get-pos.ts +++ b/src/mouse-get-pos.ts @@ -10,19 +10,44 @@ import { autoit } from './lib/autoit'; * * @example * ```typescript - * import { MouseGetPos } from '@ahmic/autoit-js'; + * import { MouseGetPosSync } from '@ahmic/autoit-js'; * - * const position = MouseGetPos(); + * const position = MouseGetPosSync(); * * console.log(position); // Output: { x: 100, y: 200 } * ``` * * @see https://www.autoitscript.com/autoit3/docs/functions/MouseGetPos.htm */ -export function MouseGetPos(): Point { +export function MouseGetPosSync(): Point { const point = new Point(); autoit.invoke('AU3_MouseGetPos', VOID, [koffi.out(LPPOINT)], [point]); return point; } + +/** + * Retrieves the current position of the mouse cursor. + * + * @returns A promise that resolves to a {@link Point} object containing the x and y coordinates of the mouse + * cursor. + * + * @example + * ```typescript + * import { MouseGetPos } from '@ahmic/autoit-js'; + * + * const position = await MouseGetPos(); + * + * console.log(position); // Output: { x: 100, y: 200 } + * ``` + * + * @see https://www.autoitscript.com/autoit3/docs/functions/MouseGetPos.htm + */ +export async function MouseGetPos(): Promise { + const point = new Point(); + + await autoit.invokeAsync('AU3_MouseGetPos', VOID, [koffi.out(LPPOINT)], [point]); + + return point; +} diff --git a/src/mouse-move.ts b/src/mouse-move.ts index 67ae83f..53d9f2b 100644 --- a/src/mouse-move.ts +++ b/src/mouse-move.ts @@ -12,13 +12,35 @@ import { autoit } from './lib/autoit'; * * @example * ```typescript - * import { MouseMove } from '@ahmic/autoit-js'; + * import { MouseMoveSync } from '@ahmic/autoit-js'; * - * MouseMove(100, 200, 50); + * MouseMoveSync(100, 200, 50); * ``` * * @see https://www.autoitscript.com/autoit3/docs/functions/MouseMove.htm */ -export function MouseMove(x: number, y: number, speed: number = -1): number { +export function MouseMoveSync(x: number, y: number, speed: number = -1): number { return autoit.invoke('AU3_MouseMove', INT, [INT, INT, INT], [x, y, speed]); } + +/** + * Moves the mouse pointer to a specified location on the screen. + * + * @param x The x-coordinate to move the mouse to. + * @param y The y-coordinate to move the mouse to. + * @param speed Optional speed of the mouse movement (1 is slow, 100 is fast, -1 is instant). + * + * @returns A promise that resolves to 1 if successful, or 0 otherwise. + * + * @example + * ```typescript + * import { MouseMove } from '@ahmic/autoit-js'; + * + * await MouseMove(100, 200, 50); + * ``` + * + * @see https://www.autoitscript.com/autoit3/docs/functions/MouseMove.htm + */ +export function MouseMove(x: number, y: number, speed: number = -1): Promise { + return autoit.invokeAsync('AU3_MouseMove', INT, [INT, INT, INT], [x, y, speed]); +} diff --git a/src/mouse-up.ts b/src/mouse-up.ts index 5fb79e7..5d18423 100644 --- a/src/mouse-up.ts +++ b/src/mouse-up.ts @@ -9,13 +9,31 @@ import { MouseButton } from './mouse-click'; * * @example * ```typescript - * import { MouseUp } from '@ahmic/autoit-js'; + * import { MouseUpSync, MouseButton } from '@ahmic/autoit-js'; * - * MouseUp('left'); + * MouseUpSync(MouseButton.Left); * ``` * * @see https://www.autoitscript.com/autoit3/docs/functions/MouseUp.htm */ -export function MouseUp(button: MouseButton = MouseButton.Left): void { +export function MouseUpSync(button: MouseButton = MouseButton.Left): void { return autoit.invoke('AU3_MouseUp', VOID, [LPCWSTR], [button]); } + +/** + * Simulates releasing a mouse button. + * + * @param button The mouse button to release. See {@linkcode MouseButton} for details. + * + * @example + * ```typescript + * import { MouseUp, MouseButton } from '@ahmic/autoit-js'; + * + * await MouseUp(MouseButton.Left); + * ``` + * + * @see https://www.autoitscript.com/autoit3/docs/functions/MouseUp.htm + */ +export function MouseUp(button: MouseButton = MouseButton.Left): Promise { + return autoit.invokeAsync('AU3_MouseUp', VOID, [LPCWSTR], [button]); +} diff --git a/src/mouse-wheel.ts b/src/mouse-wheel.ts index 5649d52..f3c5907 100644 --- a/src/mouse-wheel.ts +++ b/src/mouse-wheel.ts @@ -16,6 +16,26 @@ export enum ScrollDirection { Down = 'down', } +/** + * Scrolls the mouse wheel. + * + * @param direction The direction to scroll (up or down). + * @param clicks The number of clicks to scroll. Defaults to 1. + * + * @example + * ```typescript + * import { MouseWheelSync, ScrollDirection } from '@ahmic/autoit-js'; + * + * MouseWheelSync(ScrollDirection.Up, 3); + * MouseWheelSync(ScrollDirection.Down, 2); + * ``` + * + * @see https://www.autoitscript.com/autoit3/docs/functions/MouseWheel.htm + */ +export function MouseWheelSync(direction: ScrollDirection, clicks: number = 1): void { + return autoit.invoke('AU3_MouseWheel', VOID, [LPCWSTR, INT], [direction, clicks]); +} + /** * Scrolls the mouse wheel. * @@ -26,12 +46,12 @@ export enum ScrollDirection { * ```typescript * import { MouseWheel, ScrollDirection } from '@ahmic/autoit-js'; * - * MouseWheel(ScrollDirection.Up, 3); - * MouseWheel(ScrollDirection.Down, 2); + * await MouseWheel(ScrollDirection.Up, 3); + * await MouseWheel(ScrollDirection.Down, 2); * ``` * * @see https://www.autoitscript.com/autoit3/docs/functions/MouseWheel.htm */ -export function MouseWheel(direction: ScrollDirection, clicks: number = 1): void { - autoit.invoke('AU3_MouseWheel', VOID, [LPCWSTR, INT], [direction, clicks]); +export function MouseWheel(direction: ScrollDirection, clicks: number = 1): Promise { + return autoit.invokeAsync('AU3_MouseWheel', VOID, [LPCWSTR, INT], [direction, clicks]); } diff --git a/src/opt.ts b/src/opt.ts index fd317c3..9e91ba3 100644 --- a/src/opt.ts +++ b/src/opt.ts @@ -350,7 +350,7 @@ export enum AutoItOption { /** * Changes the operation of various AutoIt functions/parameters. This function can be used interchangeably - * with {@linkcode AutoItSetOption}. + * with {@linkcode AutoItSetOptionSync}. * * @param option The option to change. See {@linkcode AutoItOption} for details. * @param value The value to assign to the option. It varies depending on the option being set. @@ -359,13 +359,35 @@ export enum AutoItOption { * * @example * ```typescript - * import { Opt, AutoItOption } from '@ahmic/autoit-js'; + * import { OptSync, AutoItOption } from '@ahmic/autoit-js'; * - * Opt(AutoItOption.MouseCoordMode, 1); + * OptSync(AutoItOption.MouseCoordMode, 1); * ``` * * @see https://www.autoitscript.com/autoit3/docs/functions/Opt.htm */ -export function Opt(option: AutoItOption, value: number = -1): number { +export function OptSync(option: AutoItOption, value: number = -1): number { return autoit.invoke('AU3_Opt', INT, [LPCWSTR, INT], [option, value]); } + +/** + * Changes the operation of various AutoIt functions/parameters. This function can be used interchangeably + * with {@linkcode AutoItSetOption}. + * + * @param option The option to change. See {@linkcode AutoItOption} for details. + * @param value The value to assign to the option. It varies depending on the option being set. + * + * @returns A promise that resolves to the previous setting of the option. + * + * @example + * ```typescript + * import { Opt, AutoItOption } from '@ahmic/autoit-js'; + * + * await Opt(AutoItOption.MouseCoordMode, 1); + * ``` + * + * @see https://www.autoitscript.com/autoit3/docs/functions/Opt.htm + */ +export function Opt(option: AutoItOption, value: number = -1): Promise { + return autoit.invokeAsync('AU3_Opt', INT, [LPCWSTR, INT], [option, value]); +} diff --git a/src/pixel-checksum.ts b/src/pixel-checksum.ts index a04b13d..00a8e41 100644 --- a/src/pixel-checksum.ts +++ b/src/pixel-checksum.ts @@ -16,16 +16,16 @@ import { autoit } from './lib/autoit'; * * @example * ```typescript - * import { PixelChecksum } from '@ahmic/autoit-js'; + * import { PixelChecksumSync } from '@ahmic/autoit-js'; * - * const checksum = PixelChecksum(0, 0, 100, 100); + * const checksum = PixelChecksumSync(0, 0, 100, 100); * * console.log(checksum); // Output: 123456 * ``` * * @see https://www.autoitscript.com/autoit3/docs/functions/PixelChecksum.htm */ -export function PixelChecksum( +export function PixelChecksumSync( left: number, top: number, right: number, @@ -36,3 +36,37 @@ export function PixelChecksum( return autoit.invoke('AU3_PixelChecksum', UINT, [koffi.inout(LPRECT), INT], [rect, step]); } + +/** + * Calculates a checksum for a rectangular region of pixels. + * + * @param left The X coordinate of the left edge of the rectangle. + * @param top The Y coordinate of the top edge of the rectangle. + * @param right The X coordinate of the right edge of the rectangle. + * @param bottom The Y coordinate of the bottom edge of the rectangle. + * @param step The step value for the calculation (default is 1). + * + * @returns A promise that resolves to the checksum value as a number. + * + * @example + * ```typescript + * import { PixelChecksum } from '@ahmic/autoit-js'; + * + * const checksum = await PixelChecksum(0, 0, 100, 100); + * + * console.log(checksum); // Output: 123456 + * ``` + * + * @see https://www.autoitscript.com/autoit3/docs/functions/PixelChecksum.htm + */ +export function PixelChecksum( + left: number, + top: number, + right: number, + bottom: number, + step: number = 1, +): Promise { + const rect = new Rect({ left, top, right, bottom }); + + return autoit.invokeAsync('AU3_PixelChecksum', UINT, [koffi.inout(LPRECT), INT], [rect, step]); +} diff --git a/src/pixel-get-color.ts b/src/pixel-get-color.ts index 9d6ea1e..d68bc86 100644 --- a/src/pixel-get-color.ts +++ b/src/pixel-get-color.ts @@ -11,16 +11,38 @@ import { autoit } from './lib/autoit'; * * @example * ```typescript - * import { PixelGetColor } from '@ahmic/autoit-js'; + * import { PixelGetColorSync } from '@ahmic/autoit-js'; * - * const color = PixelGetColor(50, 50); + * const color = PixelGetColorSync(50, 50); * * console.log(color.toString(16)); // Output: "ff00ff" * ``` * * @see https://www.autoitscript.com/autoit3/docs/functions/PixelGetColor.htm */ -// TODO: Implement offsets when checking the color of a particular window -export function PixelGetColor(x: number, y: number): number { +export function PixelGetColorSync(x: number, y: number): number { return autoit.invoke('AU3_PixelGetColor', INT, [INT, INT], [x, y]); } + +/** + * Retrieves the color of a pixel at the specified screen coordinates. + * + * @param x The X coordinate of the pixel. + * @param y The Y coordinate of the pixel. + * + * @returns A promise that resolves to the color of the pixel as a hexadecimal number. + * + * @example + * ```typescript + * import { PixelGetColor } from '@ahmic/autoit-js'; + * + * const color = await PixelGetColor(50, 50); + * + * console.log(color.toString(16)); // Output: "ff00ff" + * ``` + * + * @see https://www.autoitscript.com/autoit3/docs/functions/PixelGetColor.htm + */ +export function PixelGetColor(x: number, y: number): Promise { + return autoit.invokeAsync('AU3_PixelGetColor', INT, [INT, INT], [x, y]); +} diff --git a/src/pixel-search.ts b/src/pixel-search.ts index 9b067b0..e8a5d6c 100644 --- a/src/pixel-search.ts +++ b/src/pixel-search.ts @@ -3,14 +3,21 @@ import { BitmapInfo } from './@types/bitmap-info'; import { BitmapInfoHeader } from './@types/bitmap-info-header'; import { BitBlt, + BitBltSync, CreateCompatibleBitmap, + CreateCompatibleBitmapSync, CreateCompatibleDC, + CreateCompatibleDCSync, DeleteDC, + DeleteDCSync, DeleteObject, + DeleteObjectSync, GetDIBits, + GetDIBitsSync, SelectObject, + SelectObjectSync, } from './lib/gdi32'; -import { GetDC, ReleaseDC } from './lib/user32'; +import { GetDC, GetDCSync, ReleaseDC, ReleaseDCSync } from './lib/user32'; const SRCCOPY = 0x00cc0020; const CAPTUREBLT = 0x40000000; @@ -18,10 +25,6 @@ const BI_RGB = 0x00000000; const NOT_FOUND = new Point({ x: -1, y: -1 }); -function withinTolerance(component: number, target: number, shadeVariation: number): boolean { - return Math.abs(component - target) <= shadeVariation; -} - /** * Searchs for a given pixel within the specified region. * @@ -31,17 +34,27 @@ function withinTolerance(component: number, target: number, shadeVariation: numb * @see https://www.autoitscript.com/forum/topic/210967-autoitx-au3_pixelsearch-access-violation/ * @see https://www.autoitscript.com/forum/topic/210967-autoitx-au3_pixelsearch-access-violation/#comment-1525551 * - * @param left - * @param top - * @param right - * @param bottom - * @param color - * @param shadeVariation - * @param step + * @param left The X coordinate of the left edge of the rectangle. + * @param top The Y coordinate of the top edge of the rectangle. + * @param right The X coordinate of the right edge of the rectangle. + * @param bottom The Y coordinate of the bottom edge of the rectangle. + * @param color The color to search for, in `0xRRGGBB` format. + * @param shadeVariation The allowed variation in color shades (default is 0). + * @param step The step value for the search (default is 1). + * + * @returns An {@linkcode IPoint} object with the coordinates of the found pixel. If the pixel is not found, + * returns a point with coordinates (-1, -1). * - * @returns + * @example + * ```typescript + * import { PixelSearchSync } from '@ahmic/autoit-js'; + * + * const result = PixelSearchSync(0, 0, 100, 100, 0xFF0000); + * + * console.log(result); // Output: { x: 50, y: 50 } + * ``` */ -export function PixelSearch( +export function PixelSearchSync( left: number, top: number, right: number, @@ -53,27 +66,37 @@ export function PixelSearch( const width = right - left; const height = bottom - top; - const screenDeviceContext = GetDC(null); - const memoryDeviceContext = CreateCompatibleDC(screenDeviceContext); - const bitmap = CreateCompatibleBitmap(screenDeviceContext, width, height); + const screenDeviceContext = GetDCSync(null); + const memoryDeviceContext = CreateCompatibleDCSync(screenDeviceContext); + const bitmap = CreateCompatibleBitmapSync(screenDeviceContext, width, height); function cleanup() { - DeleteObject(bitmap); - DeleteDC(memoryDeviceContext); - ReleaseDC(null, screenDeviceContext); + DeleteObjectSync(bitmap); + DeleteDCSync(memoryDeviceContext); + ReleaseDCSync(null, screenDeviceContext); } - if (!SelectObject(memoryDeviceContext, bitmap)) { - console.warn('SelectObject failed'); + if (!SelectObjectSync(memoryDeviceContext, bitmap)) { + console.warn('SelectObjectSync failed'); cleanup(); return NOT_FOUND; } if ( - !BitBlt(memoryDeviceContext, 0, 0, width, height, screenDeviceContext, left, top, SRCCOPY | CAPTUREBLT) + !BitBltSync( + memoryDeviceContext, + 0, + 0, + width, + height, + screenDeviceContext, + left, + top, + SRCCOPY | CAPTUREBLT, + ) ) { - console.warn('BitBlt failed'); + console.warn('BitBltSync failed'); cleanup(); return NOT_FOUND; @@ -97,15 +120,147 @@ export function PixelSearch( const pixels = new Uint8Array(imageSize); - const rows = GetDIBits(memoryDeviceContext, bitmap, 0, height, pixels, bitmapInfo, 0); + const rows = GetDIBitsSync(memoryDeviceContext, bitmap, 0, height, pixels, bitmapInfo, 0); if (rows === 0) { - console.warn('GetDIBits failed'); + console.warn('GetDIBitsSync failed'); cleanup(); return NOT_FOUND; } + const result = search(color, left, top, width, height, step, shadeVariation, pixels); + + cleanup(); + + return result; +} + +/** + * Searchs for a given pixel within the specified region. + * + * The actual `AU3_PixelSearch` function from AutoIt appears to be broken so it has been reimplemented here + * using Windows GDI32 and User32 libraries. + * + * @see https://www.autoitscript.com/forum/topic/210967-autoitx-au3_pixelsearch-access-violation/ + * @see https://www.autoitscript.com/forum/topic/210967-autoitx-au3_pixelsearch-access-violation/#comment-1525551 + * + * @param left The X coordinate of the left edge of the rectangle. + * @param top The Y coordinate of the top edge of the rectangle. + * @param right The X coordinate of the right edge of the rectangle. + * @param bottom The Y coordinate of the bottom edge of the rectangle. + * @param color The color to search for, in `0xRRGGBB` format. + * @param shadeVariation The allowed variation in color shades (default is 0). + * @param step The step value for the search (default is 1). + * + * @returns A promise that resolves to an {@linkcode IPoint} object with the coordinates of the found pixel. + * If the pixel is not found, the promise resolves to a point with coordinates (-1, -1). + * + * @example + * ```typescript + * import { PixelSearch } from '@ahmic/autoit-js'; + * + * const result = await PixelSearch(0, 0, 100, 100, 0xFF0000); + * + * console.log(result); // Output: { x: 50, y: 50 } + * ``` + */ +export async function PixelSearch( + left: number, + top: number, + right: number, + bottom: number, + color: number, + shadeVariation: number = 0, + step: number = 1, +): Promise { + const width = right - left; + const height = bottom - top; + + const screenDeviceContext = await GetDC(null); + const memoryDeviceContext = await CreateCompatibleDC(screenDeviceContext); + const bitmap = await CreateCompatibleBitmap(screenDeviceContext, width, height); + + async function cleanup() { + await DeleteObject(bitmap); + await DeleteDC(memoryDeviceContext); + await ReleaseDC(null, screenDeviceContext); + } + + if (!(await SelectObject(memoryDeviceContext, bitmap))) { + console.warn('SelectObject failed'); + await cleanup(); + + return NOT_FOUND; + } + + if ( + !(await BitBlt( + memoryDeviceContext, + 0, + 0, + width, + height, + screenDeviceContext, + left, + top, + SRCCOPY | CAPTUREBLT, + )) + ) { + console.warn('BitBlt failed'); + await cleanup(); + + return NOT_FOUND; + } + + const imageSize = width * height * 4; + + const bitmapInfoHeader = new BitmapInfoHeader({ + biWidth: width, + biHeight: -height, + biPlanes: 1, + biBitCount: 32, + biCompression: BI_RGB, + biSizeImage: imageSize, + }); + + const bitmapInfo = new BitmapInfo({ + bmiHeader: bitmapInfoHeader, + bmiColors: [{}], + }); + + const pixels = new Uint8Array(imageSize); + + const rows = await GetDIBits(memoryDeviceContext, bitmap, 0, height, pixels, bitmapInfo, 0); + + if (rows === 0) { + console.warn('GetDIBits failed'); + await cleanup(); + + return NOT_FOUND; + } + + const result = search(color, left, top, width, height, step, shadeVariation, pixels); + + await cleanup(); + + return result; +} + +function withinTolerance(color: number, target: number, shadeVariation: number): boolean { + return Math.abs(color - target) <= shadeVariation; +} + +function search( + color: number, + left: number, + top: number, + width: number, + height: number, + step: number, + shadeVariation: number, + pixels: Uint8Array, +): IPoint { const targetR = (color >> 16) & 0xff; const targetG = (color >> 8) & 0xff; const targetB = color & 0xff; @@ -125,14 +280,10 @@ export function PixelSearch( withinTolerance(g, targetG, shadeVariation) && withinTolerance(b, targetB, shadeVariation) ) { - cleanup(); - return new Point({ x: col + left, y: row + top }); } } } - cleanup(); - return NOT_FOUND; } diff --git a/src/process-close.ts b/src/process-close.ts index 4f14aa7..f1b40be 100644 --- a/src/process-close.ts +++ b/src/process-close.ts @@ -10,13 +10,33 @@ import { autoit } from './lib/autoit'; * * @example * ```typescript - * import { ProcessClose } from '@ahmic/autoit-js'; + * import { ProcessCloseSync } from '@ahmic/autoit-js'; * - * ProcessClose('notepad.exe'); + * ProcessCloseSync('notepad.exe'); * ``` * * @see https://www.autoitscript.com/autoit3/docs/functions/ProcessClose.htm */ -export function ProcessClose(process: string): number { +export function ProcessCloseSync(process: string): number { return autoit.invoke('AU3_ProcessClose', INT, [LPCWSTR], [process]); } + +/** + * Closes a process. + * + * @param process The name of the process to close (e.g., 'notepad.exe'). + * + * @returns A promise that resolves to 1 if successful, or 0 otherwise. + * + * @example + * ```typescript + * import { ProcessClose } from '@ahmic/autoit-js'; + * + * await ProcessClose('notepad.exe'); + * ``` + * + * @see https://www.autoitscript.com/autoit3/docs/functions/ProcessClose.htm + */ +export function ProcessClose(process: string): Promise { + return autoit.invokeAsync('AU3_ProcessClose', INT, [LPCWSTR], [process]); +} diff --git a/src/process-exists.ts b/src/process-exists.ts index 08c27ba..3a78248 100644 --- a/src/process-exists.ts +++ b/src/process-exists.ts @@ -10,15 +10,39 @@ import { autoit } from './lib/autoit'; * * @example * ```typescript - * import { ProcessExists } from '@ahmic/autoit-js'; + * import { ProcessExistsSync } from '@ahmic/autoit-js'; * - * const exists = ProcessExists('notepad.exe'); + * const exists = ProcessExistsSync('notepad.exe'); * * console.log(exists); // Output: true * ``` * * @see https://www.autoitscript.com/autoit3/docs/functions/ProcessExists.htm */ -export function ProcessExists(process: string): boolean { +export function ProcessExistsSync(process: string): boolean { return autoit.invoke('AU3_ProcessExists', INT, [LPCWSTR], [process]) !== 0; } + +/** + * Checks if a process exists. + * + * @param process The name of the process to check (e.g., 'notepad.exe'). + * + * @returns A promise that resolves to true if the process exists, false otherwise. + * + * @example + * ```typescript + * import { ProcessExists } from '@ahmic/autoit-js'; + * + * const exists = await ProcessExists('notepad.exe'); + * + * console.log(exists); // Output: true + * ``` + * + * @see https://www.autoitscript.com/autoit3/docs/functions/ProcessExists.htm + */ +export async function ProcessExists(process: string): Promise { + const processExists = await autoit.invokeAsync('AU3_ProcessExists', INT, [LPCWSTR], [process]); + + return processExists !== 0; +} diff --git a/src/process-set-priority.ts b/src/process-set-priority.ts index e8c7d2f..5964132 100644 --- a/src/process-set-priority.ts +++ b/src/process-set-priority.ts @@ -36,14 +36,36 @@ export enum Priority { * * @example * ```typescript - * import { ProcessSetPriority } from '@ahmic/autoit-js'; + * import { ProcessSetPrioritySync } from '@ahmic/autoit-js'; * - * const result = ProcessSetPriority('notepad.exe', 1); + * const result = ProcessSetPrioritySync('notepad.exe', 1); * console.log(result); // Output: 1 if successful, 0 otherwise * ``` * * @see https://www.autoitscript.com/autoit3/docs/functions/ProcessSetPriority.htm */ -export function ProcessSetPriority(process: string, priority: Priority): number { +export function ProcessSetPrioritySync(process: string, priority: Priority): number { return autoit.invoke('AU3_ProcessSetPriority', INT, [LPCWSTR, INT], [process, priority]); } + +/** + * Sets the priority of a process. + * + * @param process The name or PID of the process. + * @param priority The priority level to set. See {@linkcode Priority} for details. + * + * @returns A promise that resolves to 1 if successful, or 0 otherwise. + * + * @example + * ```typescript + * import { ProcessSetPriority } from '@ahmic/autoit-js'; + * + * const result = await ProcessSetPriority('notepad.exe', 1); + * console.log(result); // Output: 1 if successful, 0 otherwise + * ``` + * + * @see https://www.autoitscript.com/autoit3/docs/functions/ProcessSetPriority.htm + */ +export function ProcessSetPriority(process: string, priority: Priority): Promise { + return autoit.invokeAsync('AU3_ProcessSetPriority', INT, [LPCWSTR, INT], [process, priority]); +} diff --git a/src/process-wait-close.ts b/src/process-wait-close.ts index cd78773..ca12154 100644 --- a/src/process-wait-close.ts +++ b/src/process-wait-close.ts @@ -11,13 +11,34 @@ import { autoit } from './lib/autoit'; * * @example * ```typescript - * import { ProcessWaitClose } from '@ahmic/autoit-js'; + * import { ProcessWaitCloseSync } from '@ahmic/autoit-js'; * - * ProcessWaitClose('notepad.exe', 10); + * ProcessWaitCloseSync('notepad.exe', 10); * ``` * * @see https://www.autoitscript.com/autoit3/docs/functions/ProcessWaitClose.htm */ -export function ProcessWaitClose(process: string, timeout: number = 0): number { +export function ProcessWaitCloseSync(process: string, timeout: number = 0): number { return autoit.invoke('AU3_ProcessWaitClose', INT, [LPCWSTR, INT], [process, timeout]); } + +/** + * Waits for a process to close. + * + * @param process The name of the process to wait for. + * @param timeout The timeout in seconds. Default is 0 (wait indefinitely). + * + * @returns A promise that resolves to 1 if the process closes, or 0 if the timeout is reached. + * + * @example + * ```typescript + * import { ProcessWaitClose } from '@ahmic/autoit-js'; + * + * await ProcessWaitClose('notepad.exe', 10); + * ``` + * + * @see https://www.autoitscript.com/autoit3/docs/functions/ProcessWaitClose.htm + */ +export function ProcessWaitClose(process: string, timeout: number = 0): Promise { + return autoit.invokeAsync('AU3_ProcessWaitClose', INT, [LPCWSTR, INT], [process, timeout]); +} diff --git a/src/process-wait.ts b/src/process-wait.ts index 2132909..5620926 100644 --- a/src/process-wait.ts +++ b/src/process-wait.ts @@ -11,13 +11,34 @@ import { autoit } from './lib/autoit'; * * @example * ```typescript - * import { ProcessWait } from '@ahmic/autoit-js'; + * import { ProcessWaitSync } from '@ahmic/autoit-js'; * - * ProcessWait('notepad.exe', 10); + * ProcessWaitSync('notepad.exe', 10); * ``` * * @see https://www.autoitscript.com/autoit3/docs/functions/ProcessWait.htm */ -export function ProcessWait(process: string, timeout: number = 0): number { +export function ProcessWaitSync(process: string, timeout: number = 0): number { return autoit.invoke('AU3_ProcessWait', INT, [LPCWSTR, INT], [process, timeout]); } + +/** + * Waits for a process to exist. + * + * @param process The name of the process to wait for. + * @param timeout The timeout in seconds. Default is 0 (wait indefinitely). + * + * @returns A promise that resolves to 1 if the process exists, or 0 if the timeout is reached. + * + * @example + * ```typescript + * import { ProcessWait } from '@ahmic/autoit-js'; + * + * await ProcessWait('notepad.exe', 10); + * ``` + * + * @see https://www.autoitscript.com/autoit3/docs/functions/ProcessWait.htm + */ +export function ProcessWait(process: string, timeout: number = 0): Promise { + return autoit.invokeAsync('AU3_ProcessWait', INT, [LPCWSTR, INT], [process, timeout]); +} diff --git a/src/run-as-wait.ts b/src/run-as-wait.ts index 7ec2078..2e21081 100644 --- a/src/run-as-wait.ts +++ b/src/run-as-wait.ts @@ -18,16 +18,16 @@ import { LogonFlag } from './run-as'; * * @example * ```typescript - * import { RunAsWait, LogonFlag } from '@ahmic/autoit-js'; + * import { RunAsWaitSync, LogonFlag } from '@ahmic/autoit-js'; * - * const exitCode = RunAsWait('admin', 'DOMAIN', 'password', LogonFlag.Profile, 'notepad.exe'); + * const exitCode = RunAsWaitSync('admin', 'DOMAIN', 'password', LogonFlag.Profile, 'notepad.exe'); * * console.log(exitCode); // Output: 0 * ``` * * @see https://www.autoitscript.com/autoit3/docs/functions/RunAsWait.htm */ -export function RunAsWait( +export function RunAsWaitSync( username: string, domain: string, password: string, @@ -43,3 +43,44 @@ export function RunAsWait( [username, domain, password, logonFlag, program, directory, showFlag], ); } + +/** + * Runs a program under a different user account and waits for it to close before continuing. + * + * @param username The username to run the program as. + * @param domain The domain of the user account. + * @param password The password of the user account. + * @param logonFlag The logon flag to control the behavior of the logon. + * @param program The name of the program to run. + * @param directory Optional working directory for the program. + * @param showFlag Optional flag to control how the program's window is shown. + * + * @returns A promise that resolves to the exit code of the program. + * + * @example + * ```typescript + * import { RunAsWait, LogonFlag } from '@ahmic/autoit-js'; + * + * const exitCode = await RunAsWait('admin', 'DOMAIN', 'password', LogonFlag.Profile, 'notepad.exe'); + * + * console.log(exitCode); // Output: 0 + * ``` + * + * @see https://www.autoitscript.com/autoit3/docs/functions/RunAsWait.htm + */ +export function RunAsWait( + username: string, + domain: string, + password: string, + logonFlag: LogonFlag, + program: string, + directory: string = '', + showFlag: number = ShowWindowFlag.SHOWNORMAL, +): Promise { + return autoit.invokeAsync( + 'AU3_RunAsWait', + INT, + [LPCWSTR, LPCWSTR, LPCWSTR, INT, LPCWSTR, LPCWSTR, INT], + [username, domain, password, logonFlag, program, directory, showFlag], + ); +} diff --git a/src/run-as.ts b/src/run-as.ts index c7c5bb8..d9a0786 100644 --- a/src/run-as.ts +++ b/src/run-as.ts @@ -34,16 +34,16 @@ export enum LogonFlag { * * @example * ```typescript - * import { RunAs, LogonFlag } from '@ahmic/autoit-js'; + * import { RunAsSync, LogonFlag } from '@ahmic/autoit-js'; * - * const pid = RunAs('admin', 'DOMAIN', 'password', LogonFlag.Profile, 'notepad.exe'); + * const pid = RunAsSync('admin', 'DOMAIN', 'password', LogonFlag.Profile, 'notepad.exe'); * * console.log(pid); // Output: 123 * ``` * * @see https://www.autoitscript.com/autoit3/docs/functions/RunAs.htm */ -export function RunAs( +export function RunAsSync( username: string, domain: string, password: string, @@ -59,3 +59,44 @@ export function RunAs( [username, domain, password, logonFlag, program, directory, showFlag], ); } + +/** + * Runs a program under a different user account. + * + * @param username The username to run the program as. + * @param domain The domain of the user account. + * @param password The password of the user account. + * @param logonFlag The logon flag to control the behavior of the logon. + * @param program The name of the program to run. + * @param directory Optional working directory for the program. + * @param showFlag Optional flag to control how the program's window is shown. + * + * @returns A promise that resolves to the PID of the started process if successful, or 0 if failed. + * + * @example + * ```typescript + * import { RunAs, LogonFlag } from '@ahmic/autoit-js'; + * + * const pid = await RunAs('admin', 'DOMAIN', 'password', LogonFlag.Profile, 'notepad.exe'); + * + * console.log(pid); // Output: 123 + * ``` + * + * @see https://www.autoitscript.com/autoit3/docs/functions/RunAs.htm + */ +export function RunAs( + username: string, + domain: string, + password: string, + logonFlag: LogonFlag, + program: string, + directory: string = '', + showFlag: number = ShowWindowFlag.SHOWNORMAL, +): Promise { + return autoit.invokeAsync( + 'AU3_RunAs', + INT, + [LPCWSTR, LPCWSTR, LPCWSTR, INT, LPCWSTR, LPCWSTR, INT], + [username, domain, password, logonFlag, program, directory, showFlag], + ); +} diff --git a/src/run-wait.ts b/src/run-wait.ts index f7d5d46..6339eaa 100644 --- a/src/run-wait.ts +++ b/src/run-wait.ts @@ -13,19 +13,47 @@ import { ShowWindowFlag } from './run'; * * @example * ```typescript - * import { RunWait } from '@ahmic/autoit-js'; + * import { RunWaitSync } from '@ahmic/autoit-js'; * - * const exitCode = RunWait('notepad.exe'); + * const exitCode = RunWaitSync('notepad.exe'); * * console.log(exitCode); // Output: 0 * ``` * * @see https://www.autoitscript.com/autoit3/docs/functions/RunWait.htm */ -export function RunWait( +export function RunWaitSync( program: string, directory: string = '', showFlag: number = ShowWindowFlag.SHOWNORMAL, ): number { return autoit.invoke('AU3_RunWait', INT, [LPCWSTR, LPCWSTR, INT], [program, directory, showFlag]); } + +/** + * Runs a program and waits for it to close before continuing. + * + * @param program The name of the program to run. + * @param directory Optional working directory for the program. + * @param showFlag Optional flag to control how the program's window is shown. + * + * @returns A promise that resolves to the exit code of the program. + * + * @example + * ```typescript + * import { RunWait } from '@ahmic/autoit-js'; + * + * const exitCode = await RunWait('notepad.exe'); + * + * console.log(exitCode); // Output: 0 + * ``` + * + * @see https://www.autoitscript.com/autoit3/docs/functions/RunWait.htm + */ +export function RunWait( + program: string, + directory: string = '', + showFlag: number = ShowWindowFlag.SHOWNORMAL, +): Promise { + return autoit.invokeAsync('AU3_RunWait', INT, [LPCWSTR, LPCWSTR, INT], [program, directory, showFlag]); +} diff --git a/src/run.ts b/src/run.ts index f62b5af..0451b17 100644 --- a/src/run.ts +++ b/src/run.ts @@ -80,19 +80,47 @@ export enum ShowWindowFlag { * * @example * ```typescript - * import { Run } from '@ahmic/autoit-js'; + * import { RunSync } from '@ahmic/autoit-js'; * - * const pid = Run('notepad.exe'); + * const pid = RunSync('notepad.exe'); * * console.log(pid); // Output: 1234 * ``` * * @see https://www.autoitscript.com/autoit3/docs/functions/Run.htm */ -export function Run( +export function RunSync( program: string, workingDir: string = '', showFlag: number = ShowWindowFlag.SHOWNORMAL, ): number { return autoit.invoke('AU3_Run', INT, [LPCWSTR, LPCWSTR, INT], [program, workingDir, showFlag]); } + +/** + * Runs an external program. + * + * @param program The path to the program to run. + * @param workingDir Optional working directory for the program. + * @param showFlag Optional flag to control how the program window is shown. See {@linkcode ShowWindowFlag} for details. + * + * @returns A promise that resolves to the PID of the process if successful, or 0 if failed. + * + * @example + * ```typescript + * import { Run } from '@ahmic/autoit-js'; + * + * const pid = await Run('notepad.exe'); + * + * console.log(pid); // Output: 1234 + * ``` + * + * @see https://www.autoitscript.com/autoit3/docs/functions/Run.htm + */ +export function Run( + program: string, + workingDir: string = '', + showFlag: number = ShowWindowFlag.SHOWNORMAL, +): Promise { + return autoit.invokeAsync('AU3_Run', INT, [LPCWSTR, LPCWSTR, INT], [program, workingDir, showFlag]); +} diff --git a/src/send.ts b/src/send.ts index 8935d3f..9ca16c5 100644 --- a/src/send.ts +++ b/src/send.ts @@ -22,13 +22,32 @@ export enum SendMode { * * @example * ```typescript - * import { Send } from '@ahmic/autoit-js'; + * import { SendSync } from '@ahmic/autoit-js'; * - * Send('Hello, world!'); + * SendSync('Hello, world!'); * ``` * * @see https://www.autoitscript.com/autoit3/docs/functions/Send.htm */ -export function Send(value: string, mode: SendMode = SendMode.Default): void { +export function SendSync(value: string, mode: SendMode = SendMode.Default): void { return autoit.invoke('AU3_Send', VOID, [LPCWSTR, INT], [value, mode]); } + +/** + * Sends simulated keystrokes to the active window. + * + * @param value The string of keys to send. + * @param mode The mode to use for sending keys. See {@linkcode SendMode} for details. + * + * @example + * ```typescript + * import { Send } from '@ahmic/autoit-js'; + * + * await Send('Hello, world!'); + * ``` + * + * @see https://www.autoitscript.com/autoit3/docs/functions/Send.htm + */ +export function Send(value: string, mode: SendMode = SendMode.Default): Promise { + return autoit.invokeAsync('AU3_Send', VOID, [LPCWSTR, INT], [value, mode]); +} diff --git a/src/shutdown.ts b/src/shutdown.ts index b17b71d..8f04867 100644 --- a/src/shutdown.ts +++ b/src/shutdown.ts @@ -39,16 +39,39 @@ export enum ShutdownFlag { * * @example * ```typescript - * import { Shutdown, ShutdownFlag } from '@ahmic/autoit-js'; + * import { ShutdownSync, ShutdownFlag } from '@ahmic/autoit-js'; * - * Shutdown(ShutdownFlag.Reboot); + * ShutdownSync(ShutdownFlag.Reboot); * * // Use bitwise OR to combine flags - * Shutdown(ShutdownFlag.Shutdown | ShutdownFlag.Force); + * ShutdownSync(ShutdownFlag.Shutdown | ShutdownFlag.Force); * ``` * * @see https://www.autoitscript.com/autoit3/docs/functions/Shutdown.htm */ -export function Shutdown(flags: ShutdownFlag): number { +export function ShutdownSync(flags: ShutdownFlag): number { return autoit.invoke('AU3_Shutdown', INT, [INT], [flags]); } + +/** + * Shuts down or restarts the system based on the specified flags. + * + * @param flags The shutdown flags to control the behavior (e.g., Shutdown, Reboot, Hibernate). + * + * @returns A promise that resolves to 1 if successful, or 0 otherwise. + * + * @example + * ```typescript + * import { Shutdown, ShutdownFlag } from '@ahmic/autoit-js'; + * + * await Shutdown(ShutdownFlag.Reboot); + * + * // Use bitwise OR to combine flags + * await Shutdown(ShutdownFlag.Shutdown | ShutdownFlag.Force); + * ``` + * + * @see https://www.autoitscript.com/autoit3/docs/functions/Shutdown.htm + */ +export function Shutdown(flags: ShutdownFlag): Promise { + return autoit.invokeAsync('AU3_Shutdown', INT, [INT], [flags]); +} diff --git a/src/sleep.ts b/src/sleep.ts index 0d39642..80ee87c 100644 --- a/src/sleep.ts +++ b/src/sleep.ts @@ -8,13 +8,31 @@ import { autoit } from './lib/autoit'; * * @example * ```typescript - * import { Sleep } from '@ahmic/autoit-js'; + * import { SleepSync } from '@ahmic/autoit-js'; * - * Sleep(1000); // Pauses for 1 second + * SleepSync(1000); // Pauses for 1 second * ``` * * @see https://www.autoitscript.com/autoit3/docs/functions/Sleep.htm */ -export function Sleep(milliseconds: number): void { +export function SleepSync(milliseconds: number): void { return autoit.invoke('AU3_Sleep', VOID, [INT], [milliseconds]); } + +/** + * Pauses the script execution for a specified amount of time. + * + * @param milliseconds The number of milliseconds to pause. + * + * @example + * ```typescript + * import { Sleep } from '@ahmic/autoit-js'; + * + * await Sleep(1000); // Pauses for 1 second + * ``` + * + * @see https://www.autoitscript.com/autoit3/docs/functions/Sleep.htm + */ +export function Sleep(milliseconds: number): Promise { + return autoit.invokeAsync('AU3_Sleep', VOID, [INT], [milliseconds]); +} diff --git a/src/statusbar-get-text-by-handle.ts b/src/statusbar-get-text-by-handle.ts index baf3bdd..a052662 100644 --- a/src/statusbar-get-text-by-handle.ts +++ b/src/statusbar-get-text-by-handle.ts @@ -14,16 +14,16 @@ import { createUnicodeBuffer, unicodeBufferToString } from './util'; * * @example * ```typescript - * import { StatusbarGetText, WinGetHandle } from '@ahmic/autoit-js'; + * import { StatusbarGetTextSync, WinGetHandleSync } from '@ahmic/autoit-js'; * - * const windowHandle = WinGetHandle('Untitled - Notepad'); + * const windowHandle = WinGetHandleSync('Untitled - Notepad'); * * // The first part of Notepad's status bar is empty - * const empty = StatusbarGetText(windowHandle, 1); - * const position = StatusbarGetText(windowHandle, 2); - * const zoom = StatusbarGetText(windowHandle, 3); - * const lingEndings = StatusbarGetText(windowHandle, 4); - * const encoding = StatusbarGetText(windowHandle, 5); + * const empty = StatusbarGetTextSync(windowHandle, 1); + * const position = StatusbarGetTextSync(windowHandle, 2); + * const zoom = StatusbarGetTextSync(windowHandle, 3); + * const lingEndings = StatusbarGetTextSync(windowHandle, 4); + * const encoding = StatusbarGetTextSync(windowHandle, 5); * * console.log(empty) // "" * console.log(position) // " Ln 1, Col 1" @@ -34,7 +34,7 @@ import { createUnicodeBuffer, unicodeBufferToString } from './util'; * * @see https://www.autoitscript.com/autoit3/docs/functions/StatusbarGetText.htm */ -export function StatusbarGetTextByHandle( +export function StatusbarGetTextByHandleSync( windowHandle: bigint, part: number = 1, characterCount: number = 1024, @@ -50,3 +50,52 @@ export function StatusbarGetTextByHandle( return unicodeBufferToString(buffer); } + +/** + * Retrieves the text from a specified part of a status bar in a window. Note that the status bar parts use + * 1-based indexing. + * + * @param windowHandle The handle of the window containing the status bar. + * @param part The part of the status bar to retrieve text from (default is 1). + * @param characterCount The maximum number of characters to retrieve (default is 1024). + * + * @returns A promise that resolves to the text of the specified part of the status bar. + * + * @example + * ```typescript + * import { StatusbarGetText, WinGetHandle } from '@ahmic/autoit-js'; + * + * const windowHandle = await WinGetHandle('Untitled - Notepad'); + * + * // The first part of Notepad's status bar is empty + * const empty = await StatusbarGetText(windowHandle, 1); + * const position = await StatusbarGetText(windowHandle, 2); + * const zoom = await StatusbarGetText(windowHandle, 3); + * const lingEndings = await StatusbarGetText(windowHandle, 4); + * const encoding = await StatusbarGetText(windowHandle, 5); + * + * console.log(empty) // "" + * console.log(position) // " Ln 1, Col 1" + * console.log(zoom) // " 100%" + * console.log(lingEndings) // " Windows (CRLF)" + * console.log(encoding) // " UTF-8" + * ``` + * + * @see https://www.autoitscript.com/autoit3/docs/functions/StatusbarGetText.htm + */ +export async function StatusbarGetTextByHandle( + windowHandle: bigint, + part: number = 1, + characterCount: number = 1024, +): Promise { + const [buffer, length] = createUnicodeBuffer(characterCount); + + await autoit.invokeAsync( + 'AU3_StatusbarGetTextByHandle', + INT, + [HWND, INT, LPWSTR, INT], + [windowHandle, part, buffer, length], + ); + + return unicodeBufferToString(buffer); +} diff --git a/src/statusbar-get-text.ts b/src/statusbar-get-text.ts index 95e6720..3f93a74 100644 --- a/src/statusbar-get-text.ts +++ b/src/statusbar-get-text.ts @@ -15,14 +15,14 @@ import { createUnicodeBuffer, unicodeBufferToString } from './util'; * * @example * ```typescript - * import { StatusbarGetText } from '@ahmic/autoit-js'; + * import { StatusbarGetTextSync } from '@ahmic/autoit-js'; * * // The first part of Notepad's status bar is empty - * const empty = StatusbarGetText('Untitled - Notepad', '', 1); - * const position = StatusbarGetText('Untitled - Notepad', '', 2); - * const zoom = StatusbarGetText('Untitled - Notepad', '', 3); - * const lingEndings = StatusbarGetText('Untitled - Notepad', '', 4); - * const encoding = StatusbarGetText('Untitled - Notepad', '', 5); + * const empty = StatusbarGetTextSync('Untitled - Notepad', '', 1); + * const position = StatusbarGetTextSync('Untitled - Notepad', '', 2); + * const zoom = StatusbarGetTextSync('Untitled - Notepad', '', 3); + * const lingEndings = StatusbarGetTextSync('Untitled - Notepad', '', 4); + * const encoding = StatusbarGetTextSync('Untitled - Notepad', '', 5); * * console.log(empty) // "" * console.log(position) // " Ln 1, Col 1" @@ -33,7 +33,7 @@ import { createUnicodeBuffer, unicodeBufferToString } from './util'; * * @see https://www.autoitscript.com/autoit3/docs/functions/StatusbarGetText.htm */ -export function StatusbarGetText( +export function StatusbarGetTextSync( windowTitle: string, windowText: string = '', part: number = 1, @@ -50,3 +50,52 @@ export function StatusbarGetText( return unicodeBufferToString(buffer); } + +/** + * Retrieves the text from a specified part of a status bar in a window. Note that the status bar parts use + * 1-based indexing. + * + * @param windowTitle The title of the window containing the status bar. + * @param windowText Optional text found in the window. + * @param part The part of the status bar to retrieve text from (default is 1). + * @param characterCount The maximum number of characters to retrieve (default is 1024). + * + * @returns A promise that resolves to the text of the specified part of the status bar. + * + * @example + * ```typescript + * import { StatusbarGetText } from '@ahmic/autoit-js'; + * + * // The first part of Notepad's status bar is empty + * const empty = await StatusbarGetText('Untitled - Notepad', '', 1); + * const position = await StatusbarGetText('Untitled - Notepad', '', 2); + * const zoom = await StatusbarGetText('Untitled - Notepad', '', 3); + * const lingEndings = await StatusbarGetText('Untitled - Notepad', '', 4); + * const encoding = await StatusbarGetText('Untitled - Notepad', '', 5); + * + * console.log(empty) // "" + * console.log(position) // " Ln 1, Col 1" + * console.log(zoom) // " 100%" + * console.log(lingEndings) // " Windows (CRLF)" + * console.log(encoding) // " UTF-8" + * ``` + * + * @see https://www.autoitscript.com/autoit3/docs/functions/StatusbarGetText.htm + */ +export async function StatusbarGetText( + windowTitle: string, + windowText: string = '', + part: number = 1, + characterCount: number = 1024, +): Promise { + const [buffer, length] = createUnicodeBuffer(characterCount); + + await autoit.invokeAsync( + 'AU3_StatusbarGetText', + INT, + [LPCWSTR, LPCWSTR, INT, LPWSTR, INT], + [windowTitle, windowText, part, buffer, length], + ); + + return unicodeBufferToString(buffer); +} diff --git a/src/tooltip.ts b/src/tooltip.ts index 88c15bc..c51e88d 100644 --- a/src/tooltip.ts +++ b/src/tooltip.ts @@ -1,8 +1,14 @@ import koffi from 'koffi'; -import { WinSleep } from './@types/kernel32'; import { TOOLINFOW, ToolInfoW } from './@types/tool-info'; -import { CreateWindowExW, DestroyWindow, MAKELPARAM, SendMessageW } from './lib/user32'; +import { WinSleepSync } from './lib/kernel32'; +import { + CreateWindowExWSync, + DestroyWindowSync, + GetDesktopWindowSync, + MAKELPARAM, + SendMessageWSync, +} from './lib/user32'; const CW_USEDEFAULT = 0x80000000; @@ -23,6 +29,17 @@ const TTM_TRACKACTIVATE = WM_USER + 17; const TTM_TRACKPOSITION = WM_USER + 18; const TTM_SETMAXTIPWIDTH = WM_USER + 24; +/** + * SendMessageW return values for specific messages. + * + * | Message | Return Value | + * |:---------------------|:-----------------------------| + * | `TTM_ADDTOOLW` | 1 if successful, otherwise 0 | + * | `TTM_SETMAXTIPWIDTH` | Previous width | + * | `TTM_TRACKPOSITION` | Unused | + * | `TTM_TRACKACTIVATE` | Unused | + */ + /** * Display a tooltip with the specified value at the specified position. * @@ -32,26 +49,28 @@ const TTM_SETMAXTIPWIDTH = WM_USER + 24; * @param value The text to display in the tooltip. * @param x The x-coordinate of the tooltip position. Default is 0. * @param y The y-coordinate of the tooltip position. Default is 0. - * @param characterWidth The maximum width of the tooltip in characters. Default is 200. + * @param width The maximum width of the tooltip in pixels. Default is 400. * @param timeout The duration in milliseconds to display the tooltip. Default is 2000. * + * @returns True if the tooltip was displayed successfully, otherwise false. + * * @example * ```typescript - * import { Tooltip } from '@ahmic/autoit-js'; + * import { TooltipSync } from '@ahmic/autoit-js'; * - * Tooltip('Hello, World!', 100, 200, 50, 3000); + * TooltipSync('Hello, World!', 100, 200, 20, 3000); * ``` * * @see https://www.autoitscript.com/autoit3/docs/functions/ToolTip.htm */ -export function Tooltip( +export function TooltipSync( value: string, x: number = 0, y: number = 0, - characterWidth: number = 200, + width: number = 400, timeout: number = 2000, -): void { - const tooltipHandle = CreateWindowExW( +): boolean { + const tooltipHandle = CreateWindowExWSync( WS_EX_TOPMOST, 'tooltips_class32', null, @@ -68,19 +87,126 @@ export function Tooltip( const toolInfo = koffi.alloc(TOOLINFOW, koffi.sizeof(TOOLINFOW)); - koffi.encode(toolInfo, 0, TOOLINFOW, new ToolInfoW({ uFlags: TTF_TRACK | TTF_ABSOLUTE, lpszText: value })); + koffi.encode( + toolInfo, + 0, + TOOLINFOW, + new ToolInfoW({ + uId: 1, + hwnd: GetDesktopWindowSync(), + uFlags: TTF_TRACK | TTF_ABSOLUTE, + lpszText: value, + }), + ); const toolInfoPointer = koffi.address(toolInfo); - SendMessageW(tooltipHandle, TTM_ADDTOOLW, 0, toolInfoPointer); - SendMessageW(tooltipHandle, TTM_SETMAXTIPWIDTH, 0, characterWidth); - SendMessageW(tooltipHandle, TTM_TRACKPOSITION, 0, MAKELPARAM(x, y)); - SendMessageW(tooltipHandle, TTM_TRACKACTIVATE, 1, toolInfoPointer); + const addTooltipSuccess = SendMessageWSync(tooltipHandle, TTM_ADDTOOLW, 0, toolInfoPointer); + + if (!addTooltipSuccess) { + DestroyWindowSync(tooltipHandle); + koffi.free(toolInfo); + return false; + } + + SendMessageWSync(tooltipHandle, TTM_SETMAXTIPWIDTH, 0, width); + SendMessageWSync(tooltipHandle, TTM_TRACKPOSITION, 0, MAKELPARAM(x, y)); + SendMessageWSync(tooltipHandle, TTM_TRACKACTIVATE, 1, toolInfoPointer); - WinSleep(timeout); + WinSleepSync(timeout); - SendMessageW(tooltipHandle, TTM_TRACKACTIVATE, 0, toolInfoPointer); - DestroyWindow(tooltipHandle); + SendMessageWSync(tooltipHandle, TTM_TRACKACTIVATE, 0, toolInfoPointer); + const destroyWindowSuccess = DestroyWindowSync(tooltipHandle); + + if (!destroyWindowSuccess) { + koffi.free(toolInfo); + return false; + } koffi.free(toolInfo); + + return true; } + +/** + * Display a tooltip with the specified value at the specified position. + * + * The actual `AU3_Tooltip` function from AutoIt appears to be broken so it has been reimplemented here using + * the Windows User32 library. + * + * @param value The text to display in the tooltip. + * @param x The x-coordinate of the tooltip position. Default is 0. + * @param y The y-coordinate of the tooltip position. Default is 0. + * @param width The maximum width of the tooltip in pixels. Default is 400. + * @param timeout The duration in milliseconds to display the tooltip. Default is 2000. + * + * @example + * ```typescript + * import { Tooltip } from '@ahmic/autoit-js'; + * + * await Tooltip('Hello, World!', 100, 200, 20, 3000); + * ``` + * + * @see https://www.autoitscript.com/autoit3/docs/functions/ToolTip.htm + */ +// TODO: The async variant of Tooltip is broken. It just hangs after the first SendMessageW call. Will look +// into it later. +// export async function Tooltip( +// value: string, +// x: number = 0, +// y: number = 0, +// width: number = 400, +// timeout: number = 2000, +// ): Promise { +// const tooltipHandle = await CreateWindowExW( +// WS_EX_TOPMOST, +// 'tooltips_class32', +// null, +// WS_POPUP | TTS_NOPREFIX | TTS_ALWAYSTIP | TTS_BALLOON, +// CW_USEDEFAULT, +// CW_USEDEFAULT, +// CW_USEDEFAULT, +// CW_USEDEFAULT, +// null, +// null, +// null, +// null, +// ); + +// const toolInfo = koffi.alloc(TOOLINFOW, koffi.sizeof(TOOLINFOW)); + +// koffi.encode( +// toolInfo, +// 0, +// TOOLINFOW, +// new ToolInfoW({ +// uId: 1, +// hwnd: await GetDesktopWindow(), +// uFlags: TTF_TRACK | TTF_ABSOLUTE, +// lpszText: value, +// }), +// ); + +// const toolInfoPointer = koffi.address(toolInfo); + +// const addToolResult = await SendMessageW(tooltipHandle, TTM_ADDTOOLW, 0, toolInfoPointer); + +// if (!addToolResult) { +// await DestroyWindow(tooltipHandle); +// koffi.free(toolInfo); +// return false; +// } + +// await SendMessageW(tooltipHandle, TTM_SETMAXTIPWIDTH, 0, width); +// await SendMessageW(tooltipHandle, TTM_TRACKPOSITION, 0, MAKELPARAM(x, y)); +// await SendMessageW(tooltipHandle, TTM_TRACKACTIVATE, 1, toolInfoPointer); + +// await WinSleep(timeout); + +// await SendMessageW(tooltipHandle, TTM_TRACKACTIVATE, 0, toolInfoPointer); +// const destryoWindowResult = await DestroyWindow(tooltipHandle); + +// koffi.free(toolInfo); + +// return !!destryoWindowResult; +// } diff --git a/src/util/index.ts b/src/util/index.ts index e55b779..04b6b40 100644 --- a/src/util/index.ts +++ b/src/util/index.ts @@ -1,3 +1,4 @@ export * from './buffer.util'; export * from './color.util'; export * from './constants'; +export * from './typed-promisify'; diff --git a/src/util/logger.ts b/src/util/logger.ts index ed62dc6..488cd05 100644 --- a/src/util/logger.ts +++ b/src/util/logger.ts @@ -49,18 +49,16 @@ type Message = export class Logger { readonly logLevel: LogLevel; - private readonly applicationName: string; private readonly pid: string; private readonly useColors: boolean; - private readonly name: string; + private readonly context: string; - constructor(name: string) { - this.applicationName = 'AutoIt JS'; + constructor(context: string) { this.pid = process.pid.toString().padEnd(5, ' '); this.useColors = process.env.NO_COLOR !== '1'; - const envLogLevel = process.env.AIT_LOG_LEVEL?.padStart(5, ' ')?.toUpperCase() ?? 'INFO'; + const envLogLevel = process.env.AIT_LOG_LEVEL?.padStart(5, ' ')?.toUpperCase() ?? labels[LogLevel.Info]; switch (envLogLevel) { case labels[LogLevel.Debug]: @@ -87,7 +85,7 @@ export class Logger { this.logLevel = LogLevel.Info; } - this.name = name; + this.context = context; } debug(...values: Message[]): boolean { @@ -150,16 +148,13 @@ export class Logger { return false; } - const applicationName = this.colorize(logLevel, `[${this.applicationName}]`); const pid = this.colorize(logLevel, this.pid); const timestamp = new Date().toLocaleString('en-US'); const logLevelLabel = this.colorize(logLevel, labels[logLevel]); - const loggerName = this.colorize(LogLevel.Warn, `[${this.name}]`); + const loggerName = this.colorize(LogLevel.Warn, `[${this.context}]`); const messages = this.colorize(logLevel, values.map(this.formatValue).join(' ')); - const logMessage = `${applicationName} ${pid} - ${timestamp} ${logLevelLabel} ${loggerName} ${messages}\n`; - - process.stdout.write(logMessage); + process.stdout.write(`${pid} - ${timestamp} ${logLevelLabel} ${loggerName} ${messages}\n`); return true; } diff --git a/src/util/typed-promisify.test.ts b/src/util/typed-promisify.test.ts new file mode 100644 index 0000000..0636140 --- /dev/null +++ b/src/util/typed-promisify.test.ts @@ -0,0 +1,12 @@ +import { typedPromisify } from './'; + +describe('typedPromisify @quick', () => { + it('promisifies a synchronous function', async () => { + const syncFunction = (a: number, b: number, cb: (err: Error | null, val: unknown) => void): void => + cb(null, a + b); + const asyncFunction = typedPromisify(syncFunction); + + const result = await asyncFunction(2, 3); + expect(result).toBe(5); + }); +}); diff --git a/src/util/typed-promisify.ts b/src/util/typed-promisify.ts new file mode 100644 index 0000000..2d8a5fe --- /dev/null +++ b/src/util/typed-promisify.ts @@ -0,0 +1,14 @@ +import { promisify } from 'node:util'; + +/** + * Node's promisify function, but with better type safety for functions with more than 5 arguments. + * + * @param fn The function to promisify. + * + * @returns A function that returns a promise. + */ +export function typedPromisify( + fn: (...args: [...TArguments, (err: Error | null, result?: TResult) => void]) => void, +): (...args: TArguments) => Promise { + return promisify(fn) as (...args: TArguments) => Promise; +} diff --git a/src/win-activate-by-handle.ts b/src/win-activate-by-handle.ts index e1fc409..d731389 100644 --- a/src/win-activate-by-handle.ts +++ b/src/win-activate-by-handle.ts @@ -10,14 +10,35 @@ import { autoit } from './lib/autoit'; * * @example * ```typescript - * import { WinActivateByHandle, WinGetHandle } from '@ahmic/autoit-js'; + * import { WinActivateByHandleSync, WinGetHandleSync } from '@ahmic/autoit-js'; * - * const handle = WinGetHandle('Untitled - Notepad'); - * WinActivateByHandle(handle); + * const handle = WinGetHandleSync('Untitled - Notepad'); + * WinActivateByHandleSync(handle); * ``` * * @see https://www.autoitscript.com/autoit3/docs/functions/WinActivate.htm */ -export function WinActivateByHandle(windowHandle: bigint): number { +export function WinActivateByHandleSync(windowHandle: bigint): number { return autoit.invoke('AU3_WinActivateByHandle', INT, [HWND], [windowHandle]); } + +/** + * Activates a window. + * + * @param windowHandle The handle of the window to activate. + * + * @returns A promise that resolves to 1 if successful, or 0 otherwise. + * + * @example + * ```typescript + * import { WinActivateByHandle, WinGetHandle } from '@ahmic/autoit-js'; + * + * const handle = await WinGetHandle('Untitled - Notepad'); + * await WinActivateByHandle(handle); + * ``` + * + * @see https://www.autoitscript.com/autoit3/docs/functions/WinActivate.htm + */ +export function WinActivateByHandle(windowHandle: bigint): Promise { + return autoit.invokeAsync('AU3_WinActivateByHandle', INT, [HWND], [windowHandle]); +} diff --git a/src/win-activate.ts b/src/win-activate.ts index 325ecf4..eb9abb6 100644 --- a/src/win-activate.ts +++ b/src/win-activate.ts @@ -11,13 +11,34 @@ import { autoit } from './lib/autoit'; * * @example * ```typescript - * import { WinActivate } from '@ahmic/autoit-js'; + * import { WinActivateSync } from '@ahmic/autoit-js'; * - * WinActivate('Untitled - Notepad'); + * WinActivateSync('Untitled - Notepad'); * ``` * * @see https://www.autoitscript.com/autoit3/docs/functions/WinActivate.htm */ -export function WinActivate(windowTitle: string, windowText: string = ''): number { +export function WinActivateSync(windowTitle: string, windowText: string = ''): number { return autoit.invoke('AU3_WinActivate', INT, [LPCWSTR, LPCWSTR], [windowTitle, windowText]); } + +/** + * Activates a window. + * + * @param windowTitle The title of the window to activate. + * @param windowText Optional text found in the window. + * + * @returns A promise that resolves to 1 if successful, or 0 otherwise. + * + * @example + * ```typescript + * import { WinActivate } from '@ahmic/autoit-js'; + * + * await WinActivate('Untitled - Notepad'); + * ``` + * + * @see https://www.autoitscript.com/autoit3/docs/functions/WinActivate.htm + */ +export function WinActivate(windowTitle: string, windowText: string = ''): Promise { + return autoit.invokeAsync('AU3_WinActivate', INT, [LPCWSTR, LPCWSTR], [windowTitle, windowText]); +} diff --git a/src/win-active-by-handle.ts b/src/win-active-by-handle.ts index bc07aad..8d62fd4 100644 --- a/src/win-active-by-handle.ts +++ b/src/win-active-by-handle.ts @@ -10,16 +10,39 @@ import { autoit } from './lib/autoit'; * * @example * ```typescript - * import { WinActiveByHandle, WinGetHandle } from '@ahmic/autoit-js'; + * import { WinActiveByHandleSync, WinGetHandleSync } from '@ahmic/autoit-js'; * - * const windowHandle = WinGetHandle('Untitled - Notepad'); - * const isActive = WinActiveByHandle(windowHandle); + * const windowHandle = WinGetHandleSync('Untitled - Notepad'); + * const isActive = WinActiveByHandleSync(windowHandle); * * console.log(isActive); // Output: 1 * ``` * * @see https://www.autoitscript.com/autoit3/docs/functions/WinActive.htm */ -export function WinActiveByHandle(windowHandle: bigint): number { +export function WinActiveByHandleSync(windowHandle: bigint): number { return autoit.invoke('AU3_WinActiveByHandle', INT, [HWND], [windowHandle]); } + +/** + * Checks if a window is currently active. + * + * @param windowHandle The handle of the window to check. + * + * @returns A promise that resolves to 1 if the window is active, or 0 otherwise. + * + * @example + * ```typescript + * import { WinActiveByHandle, WinGetHandle } from '@ahmic/autoit-js'; + * + * const windowHandle = await WinGetHandle('Untitled - Notepad'); + * const isActive = await WinActiveByHandle(windowHandle); + * + * console.log(isActive); // Output: 1 + * ``` + * + * @see https://www.autoitscript.com/autoit3/docs/functions/WinActive.htm + */ +export function WinActiveByHandle(windowHandle: bigint): Promise { + return autoit.invokeAsync('AU3_WinActiveByHandle', INT, [HWND], [windowHandle]); +} diff --git a/src/win-active.ts b/src/win-active.ts index 8ed4be7..57d5d96 100644 --- a/src/win-active.ts +++ b/src/win-active.ts @@ -11,15 +11,38 @@ import { autoit } from './lib/autoit'; * * @example * ```typescript - * import { WinActive } from '@ahmic/autoit-js'; + * import { WinActiveSync } from '@ahmic/autoit-js'; * - * const isActive = WinActive('Untitled - Notepad'); + * const isActive = WinActiveSync('Untitled - Notepad'); * * console.log(isActive); // Output: 1 * ``` * * @see https://www.autoitscript.com/autoit3/docs/functions/WinActive.htm */ -export function WinActive(windowTitle: string, windowText: string = ''): number { +export function WinActiveSync(windowTitle: string, windowText: string = ''): number { return autoit.invoke('AU3_WinActive', INT, [LPCWSTR, LPCWSTR], [windowTitle, windowText]); } + +/** + * Checks if a window is currently active. + * + * @param windowTitle The title of the window to check. + * @param windowText Optional text found in the window. + * + * @returns A promise that resolves to 1 if the window is active, or 0 otherwise. + * + * @example + * ```typescript + * import { WinActive } from '@ahmic/autoit-js'; + * + * const isActive = await WinActive('Untitled - Notepad'); + * + * console.log(isActive); // Output: 1 + * ``` + * + * @see https://www.autoitscript.com/autoit3/docs/functions/WinActive.htm + */ +export function WinActive(windowTitle: string, windowText: string = ''): Promise { + return autoit.invokeAsync('AU3_WinActive', INT, [LPCWSTR, LPCWSTR], [windowTitle, windowText]); +} diff --git a/src/win-close-by-handle.ts b/src/win-close-by-handle.ts index bdc773a..96e53b8 100644 --- a/src/win-close-by-handle.ts +++ b/src/win-close-by-handle.ts @@ -10,14 +10,35 @@ import { autoit } from './lib/autoit'; * * @example * ```typescript - * import { WinCloseByHandle, WinGetHandle } from '@ahmic/autoit-js'; + * import { WinCloseByHandleSync, WinGetHandleSync } from '@ahmic/autoit-js'; * - * const handle = WinGetHandle('Untitled - Notepad'); - * WinCloseByHandle(handle); + * const handle = WinGetHandleSync('Untitled - Notepad'); + * WinCloseByHandleSync(handle); * ``` * * @see https://www.autoitscript.com/autoit3/docs/functions/WinClose.htm */ -export function WinCloseByHandle(windowHandle: bigint): number { +export function WinCloseByHandleSync(windowHandle: bigint): number { return autoit.invoke('AU3_WinCloseByHandle', INT, [HWND], [windowHandle]); } + +/** + * Closes a window. + * + * @param windowHandle The handle of the window to close. + * + * @returns A promise that resolves to 1 if successful, or 0 otherwise. + * + * @example + * ```typescript + * import { WinCloseByHandle, WinGetHandle } from '@ahmic/autoit-js'; + * + * const handle = await WinGetHandle('Untitled - Notepad'); + * await WinCloseByHandle(handle); + * ``` + * + * @see https://www.autoitscript.com/autoit3/docs/functions/WinClose.htm + */ +export function WinCloseByHandle(windowHandle: bigint): Promise { + return autoit.invokeAsync('AU3_WinCloseByHandle', INT, [HWND], [windowHandle]); +} diff --git a/src/win-close.ts b/src/win-close.ts index 05bc622..3cf9129 100644 --- a/src/win-close.ts +++ b/src/win-close.ts @@ -11,13 +11,34 @@ import { autoit } from './lib/autoit'; * * @example * ```typescript - * import { WinClose } from '@ahmic/autoit-js'; + * import { WinCloseSync } from '@ahmic/autoit-js'; * - * WinClose('Untitled - Notepad'); + * WinCloseSync('Untitled - Notepad'); * ``` * * @see https://www.autoitscript.com/autoit3/docs/functions/WinClose.htm */ -export function WinClose(windowTitle: string, windowText: string = ''): number { +export function WinCloseSync(windowTitle: string, windowText: string = ''): number { return autoit.invoke('AU3_WinClose', INT, [LPCWSTR, LPCWSTR], [windowTitle, windowText]); } + +/** + * Closes a window. + * + * @param windowTitle The title of the window to close. + * @param windowText Optional text found in the window. + * + * @returns A promise that resolves to 1 if successful, or 0 otherwise. + * + * @example + * ```typescript + * import { WinClose } from '@ahmic/autoit-js'; + * + * await WinClose('Untitled - Notepad'); + * ``` + * + * @see https://www.autoitscript.com/autoit3/docs/functions/WinClose.htm + */ +export function WinClose(windowTitle: string, windowText: string = ''): Promise { + return autoit.invokeAsync('AU3_WinClose', INT, [LPCWSTR, LPCWSTR], [windowTitle, windowText]); +} diff --git a/src/win-exists-by-handle.ts b/src/win-exists-by-handle.ts index 85851d6..4160118 100644 --- a/src/win-exists-by-handle.ts +++ b/src/win-exists-by-handle.ts @@ -10,16 +10,41 @@ import { autoit } from './lib/autoit'; * * @example * ```typescript - * import { WinExistsByHandle, WinGetHandle } from '@ahmic/autoit-js'; + * import { WinExistsByHandleSync, WinGetHandleSync } from '@ahmic/autoit-js'; * - * const handle = WinGetHandle('Untitled - Notepad'); - * const exists = WinExistsByHandle(handle); + * const handle = WinGetHandleSync('Untitled - Notepad'); + * const exists = WinExistsByHandleSync(handle); * * console.log(exists); // Output: true or false * ``` * * @see https://www.autoitscript.com/autoit3/docs/functions/WinExists.htm */ -export function WinExistsByHandle(windowHandle: bigint): boolean { +export function WinExistsByHandleSync(windowHandle: bigint): boolean { return autoit.invoke('AU3_WinExistsByHandle', INT, [HWND], [windowHandle]) === 1; } + +/** + * Checks if a window exists. + * + * @param windowHandle The handle of the window to search for. + * + * @returns A promise that resolves to true if the window exists, or false otherwise. + * + * @example + * ```typescript + * import { WinExistsByHandle, WinGetHandle } from '@ahmic/autoit-js'; + * + * const handle = await WinGetHandle('Untitled - Notepad'); + * const exists = await WinExistsByHandle(handle); + * + * console.log(exists); // Output: true or false + * ``` + * + * @see https://www.autoitscript.com/autoit3/docs/functions/WinExists.htm + */ +export async function WinExistsByHandle(windowHandle: bigint): Promise { + const result = await autoit.invokeAsync('AU3_WinExistsByHandle', INT, [HWND], [windowHandle]); + + return result === 1; +} diff --git a/src/win-exists.ts b/src/win-exists.ts index e68775e..16f940f 100644 --- a/src/win-exists.ts +++ b/src/win-exists.ts @@ -11,14 +11,43 @@ import { autoit } from './lib/autoit'; * * @example * ```typescript - * import { WinExists } from '@ahmic/autoit-js'; + * import { WinExistsSync } from '@ahmic/autoit-js'; * - * const exists = WinExists('Untitled - Notepad'); + * const exists = WinExistsSync('Untitled - Notepad'); * console.log(exists); // Output: true or false * ``` * * @see https://www.autoitscript.com/autoit3/docs/functions/WinExists.htm */ -export function WinExists(windowTitle: string, windowText: string = ''): boolean { +export function WinExistsSync(windowTitle: string, windowText: string = ''): boolean { return autoit.invoke('AU3_WinExists', INT, [LPCWSTR, LPCWSTR], [windowTitle, windowText]) === 1; } + +/** + * Checks if a window exists. + * + * @param windowTitle The title of the window to search for. + * @param windowText Optional text found in the window. + * + * @returns A promise that resolves to true if the window exists, or false otherwise. + * + * @example + * ```typescript + * import { WinExists } from '@ahmic/autoit-js'; + * + * const exists = await WinExists('Untitled - Notepad'); + * console.log(exists); // Output: true or false + * ``` + * + * @see https://www.autoitscript.com/autoit3/docs/functions/WinExists.htm + */ +export async function WinExists(windowTitle: string, windowText: string = ''): Promise { + const result = await autoit.invokeAsync( + 'AU3_WinExists', + INT, + [LPCWSTR, LPCWSTR], + [windowTitle, windowText], + ); + + return result === 1; +} diff --git a/src/win-get-caret-pos.ts b/src/win-get-caret-pos.ts index e34643d..371b058 100644 --- a/src/win-get-caret-pos.ts +++ b/src/win-get-caret-pos.ts @@ -1,28 +1,53 @@ import koffi from 'koffi'; -import { INT, LPPOINT, Point } from './@types'; +import { INT, IPoint, LPPOINT, Point } from './@types'; import { autoit } from './lib/autoit'; /** * Retrieves the position of the caret in the active window. * - * @returns An object containing the x and y coordinates of the caret. + * @returns An {@linkcode IPoint} object containing the x and y coordinates of the caret. * * @example * ```typescript - * import { WinGetCaretPos } from '@ahmic/autoit-js'; + * import { WinGetCaretPosSync } from '@ahmic/autoit-js'; * - * const caretPos = WinGetCaretPos(); + * const caretPos = WinGetCaretPosSync(); * * console.log(caretPos); // Output: { x: 10, y: 20 } * ``` * * @see https://www.autoitscript.com/autoit3/docs/functions/WinGetCaretPos.htm */ -export function WinGetCaretPos(): Point { +export function WinGetCaretPosSync(): Point { const point = new Point(); autoit.invoke('AU3_WinGetCaretPos', INT, [koffi.out(LPPOINT)], [point]); return point; } + +/** + * Retrieves the position of the caret in the active window. + * + * @returns A promise that resolves to an {@linkcode IPoint} object containing the x and y coordinates of the + * caret. + * + * @example + * ```typescript + * import { WinGetCaretPos } from '@ahmic/autoit-js'; + * + * const caretPos = await WinGetCaretPos(); + * + * console.log(caretPos); // Output: { x: 10, y: 20 } + * ``` + * + * @see https://www.autoitscript.com/autoit3/docs/functions/WinGetCaretPos.htm + */ +export async function WinGetCaretPos(): Promise { + const point = new Point(); + + await autoit.invokeAsync('AU3_WinGetCaretPos', INT, [koffi.out(LPPOINT)], [point]); + + return point; +} diff --git a/src/win-get-class-list-by-handle.ts b/src/win-get-class-list-by-handle.ts index 9a38678..6562093 100644 --- a/src/win-get-class-list-by-handle.ts +++ b/src/win-get-class-list-by-handle.ts @@ -12,20 +12,56 @@ import { createUnicodeBuffer, unicodeBufferToString } from './util'; * * @example * ```typescript - * import { WinGetClassListByHandle, WinGetHandle } from '@ahmic/autoit-js'; + * import { WinGetClassListByHandleSync, WinGetHandleSync } from '@ahmic/autoit-js'; * - * const windowHandle = WinGetHandle('Untitled - Notepad'); - * const classList = WinGetClassListByHandle(windowHandle); + * const windowHandle = WinGetHandleSync('Untitled - Notepad'); + * const classList = WinGetClassListByHandleSync(windowHandle); * * console.log(classList); // Output: "Edit\nButton" * ``` * * @see https://www.autoitscript.com/autoit3/docs/functions/WinGetClassList.htm */ -export function WinGetClassListByHandle(windowHandle: bigint, characterCount: number = 1024): string { +export function WinGetClassListByHandleSync(windowHandle: bigint, characterCount: number = 1024): string { const [buffer, length] = createUnicodeBuffer(characterCount); autoit.invoke('AU3_WinGetClassListByHandle', VOID, [HWND, LPWSTR, INT], [windowHandle, buffer, length]); return unicodeBufferToString(buffer); } + +/** + * Retrieves the class list of a window. + * + * @param windowHandle The handle of the window to access. + * @param characterCount The maximum number of characters to retrieve. Default is 1024. + * + * @returns A promise that resolves to the class list of the window as a string. + * + * @example + * ```typescript + * import { WinGetClassListByHandle, WinGetHandle } from '@ahmic/autoit-js'; + * + * const windowHandle = await WinGetHandle('Untitled - Notepad'); + * const classList = await WinGetClassListByHandle(windowHandle); + * + * console.log(classList); // Output: "Edit\nButton" + * ``` + * + * @see https://www.autoitscript.com/autoit3/docs/functions/WinGetClassList.htm + */ +export async function WinGetClassListByHandle( + windowHandle: bigint, + characterCount: number = 1024, +): Promise { + const [buffer, length] = createUnicodeBuffer(characterCount); + + await autoit.invokeAsync( + 'AU3_WinGetClassListByHandle', + VOID, + [HWND, LPWSTR, INT], + [windowHandle, buffer, length], + ); + + return unicodeBufferToString(buffer); +} diff --git a/src/win-get-class-list.ts b/src/win-get-class-list.ts index a5ce0dc..f230a4e 100644 --- a/src/win-get-class-list.ts +++ b/src/win-get-class-list.ts @@ -13,16 +13,16 @@ import { createUnicodeBuffer, unicodeBufferToString } from './util'; * * @example * ```typescript - * import { WinGetClassList } from '@ahmic/autoit-js'; + * import { WinGetClassListSync } from '@ahmic/autoit-js'; * - * const classList = WinGetClassList('Untitled - Notepad'); + * const classList = WinGetClassListSync('Untitled - Notepad'); * * console.log(classList); // Output: "Edit\nButton" * ``` * * @see https://www.autoitscript.com/autoit3/docs/functions/WinGetClassList.htm */ -export function WinGetClassList( +export function WinGetClassListSync( windowTitle: string, windowText: string = '', characterCount: number = 1024, @@ -38,3 +38,40 @@ export function WinGetClassList( return unicodeBufferToString(buffer); } + +/** + * Retrieves the class list of a window. + * + * @param windowTitle The title of the window to access. + * @param windowText Optional text found in the window. + * @param characterCount The size of the buffer to store the result. + * + * @returns A promise that resolves to the class list of the window as a string. + * + * @example + * ```typescript + * import { WinGetClassList } from '@ahmic/autoit-js'; + * + * const classList = await WinGetClassList('Untitled - Notepad'); + * + * console.log(classList); // Output: "Edit\nButton" + * ``` + * + * @see https://www.autoitscript.com/autoit3/docs/functions/WinGetClassList.htm + */ +export async function WinGetClassList( + windowTitle: string, + windowText: string = '', + characterCount: number = 1024, +): Promise { + const [buffer, length] = createUnicodeBuffer(characterCount); + + await autoit.invokeAsync( + 'AU3_WinGetClassList', + VOID, + [LPCWSTR, LPCWSTR, LPWSTR, INT], + [windowTitle, windowText, buffer, length], + ); + + return unicodeBufferToString(buffer); +} diff --git a/src/win-get-client-size-by-handle.ts b/src/win-get-client-size-by-handle.ts index 61abf0d..5119b7b 100644 --- a/src/win-get-client-size-by-handle.ts +++ b/src/win-get-client-size-by-handle.ts @@ -1,6 +1,6 @@ import koffi from 'koffi'; -import { HWND, INT, LPRECT, Rect } from './@types'; +import { HWND, INT, IRect, LPRECT, Rect } from './@types'; import { autoit } from './lib/autoit'; /** @@ -8,24 +8,57 @@ import { autoit } from './lib/autoit'; * * @param windowHandle The handle of the window to access. * - * @returns An object containing the width and height of the client area. + * @returns An {@linkcode IRect} object containing the width and height of the client area. * * @example * ```typescript - * import { WinGetClientSizeByHandle, WinGetHandle } from '@ahmic/autoit-js'; + * import { WinGetClientSizeByHandleSync, WinGetHandleSync } from '@ahmic/autoit-js'; * - * const windowHandle = WinGetHandle('Untitled - Notepad'); - * const clientSize = WinGetClientSizeByHandle(windowHandle); + * const windowHandle = WinGetHandleSync('Untitled - Notepad'); + * const clientSize = WinGetClientSizeByHandleSync(windowHandle); * * console.log(clientSize); // Output: { width: 800, height: 600 } * ``` * * @see https://www.autoitscript.com/autoit3/docs/functions/WinGetClientSize.htm */ -export function WinGetClientSizeByHandle(windowHandle: bigint): Rect { +export function WinGetClientSizeByHandleSync(windowHandle: bigint): IRect { const rect = new Rect(); autoit.invoke('AU3_WinGetClientSizeByHandle', INT, [HWND, koffi.out(LPRECT)], [windowHandle, rect]); return rect; } + +/** + * Retrieves the client area dimensions of a window. + * + * @param windowHandle The handle of the window to access. + * + * @returns A promise that resolves to an {@linkcode IRect} object containing the width and height of the + * client area. + * + * @example + * ```typescript + * import { WinGetClientSizeByHandle, WinGetHandle } from '@ahmic/autoit-js'; + * + * const windowHandle = await WinGetHandle('Untitled - Notepad'); + * const clientSize = await WinGetClientSizeByHandle(windowHandle); + * + * console.log(clientSize); // Output: { width: 800, height: 600 } + * ``` + * + * @see https://www.autoitscript.com/autoit3/docs/functions/WinGetClientSize.htm + */ +export async function WinGetClientSizeByHandle(windowHandle: bigint): Promise { + const rect = new Rect(); + + await autoit.invokeAsync( + 'AU3_WinGetClientSizeByHandle', + INT, + [HWND, koffi.out(LPRECT)], + [windowHandle, rect], + ); + + return rect; +} diff --git a/src/win-get-client-size.ts b/src/win-get-client-size.ts index fbafc10..ed158d7 100644 --- a/src/win-get-client-size.ts +++ b/src/win-get-client-size.ts @@ -9,20 +9,20 @@ import { autoit } from './lib/autoit'; * @param windowTitle The title of the window to access. * @param windowText Optional text found in the window. * - * @returns An object containing the width and height of the client area. + * @returns An {@linkcode IRect} object containing the width and height of the client area. * * @example * ```typescript - * import { WinGetClientSize } from '@ahmic/autoit-js'; + * import { WinGetClientSizeSync } from '@ahmic/autoit-js'; * - * const clientSize = WinGetClientSize('Untitled - Notepad'); + * const clientSize = WinGetClientSizeSync('Untitled - Notepad'); * * console.log(clientSize); // Output: { width: 800, height: 600 } * ``` * * @see https://www.autoitscript.com/autoit3/docs/functions/WinGetClientSize.htm */ -export function WinGetClientSize(windowTitle: string, windowText: string = ''): IRect { +export function WinGetClientSizeSync(windowTitle: string, windowText: string = ''): IRect { const rect = new Rect(); autoit.invoke( @@ -34,3 +34,36 @@ export function WinGetClientSize(windowTitle: string, windowText: string = ''): return rect; } + +/** + * Retrieves the client area dimensions of a window. + * + * @param windowTitle The title of the window to access. + * @param windowText Optional text found in the window. + * + * @returns A promise that resolves to an {@linkcode IRect} object containing the width and height of the + * client area. + * + * @example + * ```typescript + * import { WinGetClientSize } from '@ahmic/autoit-js'; + * + * const clientSize = await WinGetClientSize('Untitled - Notepad'); + * + * console.log(clientSize); // Output: { width: 800, height: 600 } + * ``` + * + * @see https://www.autoitscript.com/autoit3/docs/functions/WinGetClientSize.htm + */ +export async function WinGetClientSize(windowTitle: string, windowText: string = ''): Promise { + const rect = new Rect(); + + await autoit.invokeAsync( + 'AU3_WinGetClientSize', + INT, + [LPCWSTR, LPCWSTR, koffi.out(LPRECT)], + [windowTitle, windowText, rect], + ); + + return rect; +} diff --git a/src/win-get-handle-as-text.ts b/src/win-get-handle-as-text.ts index 3cd0bd1..47c14d6 100644 --- a/src/win-get-handle-as-text.ts +++ b/src/win-get-handle-as-text.ts @@ -13,16 +13,16 @@ import { HWND_HEX_SIZE } from './util/constants'; * * @example * ```typescript - * import { WinGetHandleAsText } from '@ahmic/autoit-js'; + * import { WinGetHandleAsTextSync } from '@ahmic/autoit-js'; * - * const handleText = WinGetHandleAsText('Untitled - Notepad'); + * const handleText = WinGetHandleAsTextSync('Untitled - Notepad'); * * console.log(handleText); // Output: "0x00123456" (example output) * ``` * * @see https://www.autoitscript.com/autoit3/docs/functions/WinGetHandle.htm */ -export function WinGetHandleAsText(windowTitle: string, windowText: string = ''): string { +export function WinGetHandleAsTextSync(windowTitle: string, windowText: string = ''): string { const [buffer, length] = createUnicodeBuffer(HWND_HEX_SIZE); autoit.invoke( @@ -34,3 +34,35 @@ export function WinGetHandleAsText(windowTitle: string, windowText: string = '') return unicodeBufferToString(buffer); } + +/** + * Retrieves the handle of a window as a string. + * + * @param windowTitle The title of the window to access. + * @param windowText Optional text found in the window. + * + * @returns A promise that resolves to the handle of the window as a string. + * + * @example + * ```typescript + * import { WinGetHandleAsText } from '@ahmic/autoit-js'; + * + * const handleText = await WinGetHandleAsText('Untitled - Notepad'); + * + * console.log(handleText); // Output: "0x00123456" (example output) + * ``` + * + * @see https://www.autoitscript.com/autoit3/docs/functions/WinGetHandle.htm + */ +export async function WinGetHandleAsText(windowTitle: string, windowText: string = ''): Promise { + const [buffer, length] = createUnicodeBuffer(HWND_HEX_SIZE); + + await autoit.invokeAsync( + 'AU3_WinGetHandleAsText', + VOID, + [LPCWSTR, LPCWSTR, LPWSTR, INT], + [windowTitle, windowText, buffer, length], + ); + + return unicodeBufferToString(buffer); +} diff --git a/src/win-get-handle.ts b/src/win-get-handle.ts index c6668d1..1a7df6c 100644 --- a/src/win-get-handle.ts +++ b/src/win-get-handle.ts @@ -13,17 +13,47 @@ import { autoit } from './lib/autoit'; * * @example * ```typescript - * import { WinGetHandle } from '@ahmic/autoit-js'; + * import { WinGetHandleSync } from '@ahmic/autoit-js'; * - * const handle = WinGetHandle('Untitled - Notepad'); + * const handle = WinGetHandleSync('Untitled - Notepad'); * * console.log(handle); // Output: 123456n * ``` * * @see https://www.autoitscript.com/autoit3/docs/functions/WinGetHandle.htm */ -export function WinGetHandle(windowTitle: string, windowText: string = ''): bigint { +export function WinGetHandleSync(windowTitle: string, windowText: string = ''): bigint { const handleRef = autoit.invoke('AU3_WinGetHandle', HWND, [LPCWSTR, LPCWSTR], [windowTitle, windowText]); return koffi.address(handleRef); } + +/** + * Retrieves the handle of a window. + * + * @param windowTitle The title of the window to access. + * @param windowText Optional text found in the window. + * + * @returns A promise that resolves to the handle of the window as a bigint. + * + * @example + * ```typescript + * import { WinGetHandle } from '@ahmic/autoit-js'; + * + * const handle = await WinGetHandle('Untitled - Notepad'); + * + * console.log(handle); // Output: 123456n + * ``` + * + * @see https://www.autoitscript.com/autoit3/docs/functions/WinGetHandle.htm + */ +export async function WinGetHandle(windowTitle: string, windowText: string = ''): Promise { + const handleRef = await autoit.invokeAsync( + 'AU3_WinGetHandle', + HWND, + [LPCWSTR, LPCWSTR], + [windowTitle, windowText], + ); + + return koffi.address(handleRef); +} diff --git a/src/win-get-pos-by-handle.ts b/src/win-get-pos-by-handle.ts index 77fa27e..ad0021a 100644 --- a/src/win-get-pos-by-handle.ts +++ b/src/win-get-pos-by-handle.ts @@ -8,25 +8,52 @@ import { autoit } from './lib/autoit'; * * @param windowHandle The handle of the window. * - * @returns The position and size of the window as a {@linkcode IRect} object. + * @returns An {@linkcode IRect} object containing the position and size of the window. * * @example * ```typescript - * import { WinGetHandle, WinGetPosByHandle } from '@ahmic/autoit-js'; - * - * const windowHandle = WinGetHandle('Untitled - Notepad'); + * import { WinGetHandleSync, WinGetPosByHandleSync } from '@ahmic/autoit-js'; * - * const rect = WinGetPosByHandle(windowHandle); + * const windowHandle = WinGetHandleSync('Untitled - Notepad'); + * const rect = WinGetPosByHandleSync(windowHandle); * * console.log(rect); // Output: { left: 100, top: 100, right: 200, bottom: 200 } * ``` * * @see https://www.autoitscript.com/autoit3/docs/functions/WinGetPos.htm */ -export function WinGetPosByHandle(windowHandle: bigint): IRect { +export function WinGetPosByHandleSync(windowHandle: bigint): IRect { const rect = new Rect(); autoit.invoke('AU3_WinGetPosByHandle', INT, [HWND, koffi.out(LPRECT)], [windowHandle, rect]); return rect; } + +/** + * Retrieves the position and size of a window. + * + * @param windowHandle The handle of the window. + * + * @returns A promise that resolves to an {@linkcode IRect} object containing the position and size of the + * window. + * + * @example + * ```typescript + * import { WinGetHandle, WinGetPosByHandle } from '@ahmic/autoit-js'; + * + * const windowHandle = await WinGetHandle('Untitled - Notepad'); + * const rect = await WinGetPosByHandle(windowHandle); + * + * console.log(rect); // Output: { left: 100, top: 100, right: 200, bottom: 200 } + * ``` + * + * @see https://www.autoitscript.com/autoit3/docs/functions/WinGetPos.htm + */ +export async function WinGetPosByHandle(windowHandle: bigint): Promise { + const rect = new Rect(); + + await autoit.invokeAsync('AU3_WinGetPosByHandle', INT, [HWND, koffi.out(LPRECT)], [windowHandle, rect]); + + return rect; +} diff --git a/src/win-get-pos.ts b/src/win-get-pos.ts index 9dbcc4d..e8735ad 100644 --- a/src/win-get-pos.ts +++ b/src/win-get-pos.ts @@ -9,23 +9,56 @@ import { autoit } from './lib/autoit'; * @param windowTitle The title of the window. * @param windowText Optional text found in the window. * - * @returns The position and size of the window as a {@linkcode IRect} object. + * @returns An {@linkcode IRect} object containing the position and size of the window. * * @example * ```typescript - * import { WinGetPos } from '@ahmic/autoit-js'; + * import { WinGetPosSync } from '@ahmic/autoit-js'; * - * const rect = WinGetPos('Untitled - Notepad'); + * const rect = WinGetPosSync('Untitled - Notepad'); * * console.log(rect); // Output: { left: 100, top: 100, right: 200, bottom: 200 } * ``` * * @see https://www.autoitscript.com/autoit3/docs/functions/WinGetPos.htm */ -export function WinGetPos(windowTitle: string, windowText: string = ''): IRect { +export function WinGetPosSync(windowTitle: string, windowText: string = ''): IRect { const rect = new Rect(); autoit.invoke('AU3_WinGetPos', INT, [LPCWSTR, LPCWSTR, koffi.out(LPRECT)], [windowTitle, windowText, rect]); return rect; } + +/** + * Retrieves the position and size of a window. + * + * @param windowTitle The title of the window. + * @param windowText Optional text found in the window. + * + * @returns A promise that resolves to an {@linkcode IRect} object containing the position and size of the + * window. + * + * @example + * ```typescript + * import { WinGetPos } from '@ahmic/autoit-js'; + * + * const rect = await WinGetPos('Untitled - Notepad'); + * + * console.log(rect); // Output: { left: 100, top: 100, right: 200, bottom: 200 } + * ``` + * + * @see https://www.autoitscript.com/autoit3/docs/functions/WinGetPos.htm + */ +export async function WinGetPos(windowTitle: string, windowText: string = ''): Promise { + const rect = new Rect(); + + await autoit.invokeAsync( + 'AU3_WinGetPos', + INT, + [LPCWSTR, LPCWSTR, koffi.out(LPRECT)], + [windowTitle, windowText, rect], + ); + + return rect; +} diff --git a/src/win-get-process-by-handle.ts b/src/win-get-process-by-handle.ts index 36494f7..aaf1cb0 100644 --- a/src/win-get-process-by-handle.ts +++ b/src/win-get-process-by-handle.ts @@ -10,16 +10,39 @@ import { autoit } from './lib/autoit'; * * @example * ```typescript - * import { WinGetProcessByHandle, WinGetHandle } from '@ahmic/autoit-js'; + * import { WinGetProcessByHandleSync, WinGetHandleSync } from '@ahmic/autoit-js'; * - * const windowHandle = WinGetHandle('Untitled - Notepad'); - * const processId = WinGetProcessByHandle(windowHandle); + * const windowHandle = WinGetHandleSync('Untitled - Notepad'); + * const processId = WinGetProcessByHandleSync(windowHandle); * * console.log(processId); // Output: 1234 * ``` * * @see https://www.autoitscript.com/autoit3/docs/functions/WinGetProcess.htm */ -export function WinGetProcessByHandle(windowHandle: bigint): number { +export function WinGetProcessByHandleSync(windowHandle: bigint): number { return autoit.invoke('AU3_WinGetProcessByHandle', DWORD, [HWND], [windowHandle]); } + +/** + * Retrieves the process ID associated with a window handle. + * + * @param windowHandle The handle of the window to access. + * + * @returns A promise that resolves to the process ID as a number. + * + * @example + * ```typescript + * import { WinGetProcessByHandle, WinGetHandle } from '@ahmic/autoit-js'; + * + * const windowHandle = await WinGetHandle('Untitled - Notepad'); + * const processId = await WinGetProcessByHandle(windowHandle); + * + * console.log(processId); // Output: 1234 + * ``` + * + * @see https://www.autoitscript.com/autoit3/docs/functions/WinGetProcess.htm + */ +export function WinGetProcessByHandle(windowHandle: bigint): Promise { + return autoit.invokeAsync('AU3_WinGetProcessByHandle', DWORD, [HWND], [windowHandle]); +} diff --git a/src/win-get-process.ts b/src/win-get-process.ts index fa0296f..c133cbe 100644 --- a/src/win-get-process.ts +++ b/src/win-get-process.ts @@ -11,15 +11,38 @@ import { autoit } from './lib/autoit'; * * @example * ```typescript - * import { WinGetProcess } from '@ahmic/autoit-js'; + * import { WinGetProcessSync } from '@ahmic/autoit-js'; * - * const processId = WinGetProcess('Untitled - Notepad'); + * const processId = WinGetProcessSync('Untitled - Notepad'); * * console.log(processId); // Output: 1234 * ``` * * @see https://www.autoitscript.com/autoit3/docs/functions/WinGetProcess.htm */ -export function WinGetProcess(windowTitle: string, windowText: string = ''): number { +export function WinGetProcessSync(windowTitle: string, windowText: string = ''): number { return autoit.invoke('AU3_WinGetProcess', DWORD, [LPCWSTR, LPCWSTR], [windowTitle, windowText]); } + +/** + * Retrieves the process ID associated with a window. + * + * @param windowTitle The title of the window to access. + * @param windowText Optional text found in the window. + * + * @returns A promise that resolves to the process ID as a number. + * + * @example + * ```typescript + * import { WinGetProcess } from '@ahmic/autoit-js'; + * + * const processId = await WinGetProcess('Untitled - Notepad'); + * + * console.log(processId); // Output: 1234 + * ``` + * + * @see https://www.autoitscript.com/autoit3/docs/functions/WinGetProcess.htm + */ +export function WinGetProcess(windowTitle: string, windowText: string = ''): Promise { + return autoit.invokeAsync('AU3_WinGetProcess', DWORD, [LPCWSTR, LPCWSTR], [windowTitle, windowText]); +} diff --git a/src/win-get-state-by-handle.ts b/src/win-get-state-by-handle.ts index b1700a6..54d2979 100644 --- a/src/win-get-state-by-handle.ts +++ b/src/win-get-state-by-handle.ts @@ -10,14 +10,14 @@ import { WindowProperty, WindowState } from './win-get-state'; * * @param windowHandle The handle of the window to check. * - * @returns An object containing the state of the window. + * @returns A {@linkcode WindowState} object containing the state of the window. * * @example * ```typescript - * import { WinGetStateByHandle, WinGetHandle } from '@ahmic/autoit-js'; + * import { WinGetStateByHandleSync, WinGetHandleSync } from '@ahmic/autoit-js'; * - * const windowHandle = WinGetHandle('Untitled - Notepad'); - * const state = WinGetStateByHandle(windowHandle); + * const windowHandle = WinGetHandleSync('Untitled - Notepad'); + * const state = WinGetStateByHandleSync(windowHandle); * * console.log(state.exists); // true if the window exists * console.log(state.visible); // true if the window is visible @@ -25,7 +25,7 @@ import { WindowProperty, WindowState } from './win-get-state'; * * @see https://www.autoitscript.com/autoit3/docs/func/WinGetState.htm */ -export function WinGetStateByHandle(windowHandle: bigint): WindowState { +export function WinGetStateByHandleSync(windowHandle: bigint): WindowState { const state = autoit.invoke('AU3_WinGetStateByHandle', INT, [HWND], [windowHandle]); return { @@ -37,3 +37,39 @@ export function WinGetStateByHandle(windowHandle: bigint): WindowState { maximized: (state & WindowProperty.Maximized) === WindowProperty.Maximized, }; } + +/** + * Returns the state of a window. + * + * Though the original AutoIt function returns a bitmask, this function returns an object with boolean + * properties for each state for ease of use. + * + * @param windowHandle The handle of the window to check. + * + * @returns A promise that resolves to a {@linkcode WindowState} object containing the state of the window. + * + * @example + * ```typescript + * import { WinGetStateByHandle, WinGetHandle } from '@ahmic/autoit-js'; + * + * const windowHandle = await WinGetHandle('Untitled - Notepad'); + * const state = await WinGetStateByHandle(windowHandle); + * + * console.log(state.exists); // true if the window exists + * console.log(state.visible); // true if the window is visible + * ``` + * + * @see https://www.autoitscript.com/autoit3/docs/func/WinGetState.htm + */ +export async function WinGetStateByHandle(windowHandle: bigint): Promise { + const state = await autoit.invokeAsync('AU3_WinGetStateByHandle', INT, [HWND], [windowHandle]); + + return { + exists: (state & WindowProperty.Exists) === WindowProperty.Exists, + visible: (state & WindowProperty.Visible) === WindowProperty.Visible, + enabled: (state & WindowProperty.Enabled) === WindowProperty.Enabled, + active: (state & WindowProperty.Active) === WindowProperty.Active, + minimized: (state & WindowProperty.Minimized) === WindowProperty.Minimized, + maximized: (state & WindowProperty.Maximized) === WindowProperty.Maximized, + }; +} diff --git a/src/win-get-state.ts b/src/win-get-state.ts index 620ca3f..27c4db0 100644 --- a/src/win-get-state.ts +++ b/src/win-get-state.ts @@ -56,13 +56,13 @@ export type WindowState = { * @param windowTitle The title of the window to check. * @param windowText Optional text found in the window. * - * @returns An object containing the state of the window. + * @returns A {@linkcode WindowState} object containing the state of the window. * * @example * ```typescript - * import { WinGetState } from '@ahmic/autoit-js'; + * import { WinGetStateSync } from '@ahmic/autoit-js'; * - * const state = WinGetState('Untitled - Notepad'); + * const state = WinGetStateSync('Untitled - Notepad'); * * console.log(state.exists); // true if the window exists * console.log(state.visible); // true if the window is visible @@ -70,7 +70,7 @@ export type WindowState = { * * @see https://www.autoitscript.com/autoit3/docs/func/WinGetState.htm */ -export function WinGetState(windowTitle: string, windowText: string = ''): WindowState { +export function WinGetStateSync(windowTitle: string, windowText: string = ''): WindowState { const state = autoit.invoke('AU3_WinGetState', INT, [LPCWSTR, LPCWSTR], [windowTitle, windowText]); return { @@ -82,3 +82,44 @@ export function WinGetState(windowTitle: string, windowText: string = ''): Windo maximized: (state & WindowProperty.Maximized) === WindowProperty.Maximized, }; } + +/** + * Returns the state of a window. + * + * Though the original AutoIt function returns a bitmask, this function returns an object with boolean + * properties for each state for ease of use. + * + * @param windowTitle The title of the window to check. + * @param windowText Optional text found in the window. + * + * @returns A promise that resolves to a {@linkcode WindowState} object containing the state of the window. + * + * @example + * ```typescript + * import { WinGetState } from '@ahmic/autoit-js'; + * + * const state = await WinGetState('Untitled - Notepad'); + * + * console.log(state.exists); // true if the window exists + * console.log(state.visible); // true if the window is visible + * ``` + * + * @see https://www.autoitscript.com/autoit3/docs/func/WinGetState.htm + */ +export async function WinGetState(windowTitle: string, windowText: string = ''): Promise { + const state = await autoit.invokeAsync( + 'AU3_WinGetState', + INT, + [LPCWSTR, LPCWSTR], + [windowTitle, windowText], + ); + + return { + exists: (state & WindowProperty.Exists) === WindowProperty.Exists, + visible: (state & WindowProperty.Visible) === WindowProperty.Visible, + enabled: (state & WindowProperty.Enabled) === WindowProperty.Enabled, + active: (state & WindowProperty.Active) === WindowProperty.Active, + minimized: (state & WindowProperty.Minimized) === WindowProperty.Minimized, + maximized: (state & WindowProperty.Maximized) === WindowProperty.Maximized, + }; +} diff --git a/src/win-get-text-by-handle.ts b/src/win-get-text-by-handle.ts index 67ef8fe..3c84e73 100644 --- a/src/win-get-text-by-handle.ts +++ b/src/win-get-text-by-handle.ts @@ -12,20 +12,56 @@ import { createUnicodeBuffer, unicodeBufferToString } from './util'; * * @example * ```typescript - * import { WinGetTextByHandle, WinGetHandle } from '@ahmic/autoit-js'; + * import { WinGetTextByHandleSync, WinGetHandleSync } from '@ahmic/autoit-js'; * - * const windowHandle = WinGetHandle('Untitled - Notepad'); - * const text = WinGetTextByHandle(windowHandle); + * const windowHandle = WinGetHandleSync('Untitled - Notepad'); + * const text = WinGetTextByHandleSync(windowHandle); * * console.log(text); // Output: "Example text" * ``` * * @see https://www.autoitscript.com/autoit3/docs/functions/WinGetText.htm */ -export function WinGetTextByHandle(windowHandle: bigint, characterCount: number = 1024): string { +export function WinGetTextByHandleSync(windowHandle: bigint, characterCount: number = 1024): string { const [buffer, length] = createUnicodeBuffer(characterCount); autoit.invoke('AU3_WinGetTextByHandle', VOID, [HWND, LPWSTR, INT], [windowHandle, buffer, length]); return unicodeBufferToString(buffer); } + +/** + * Retrieves the text from a window. + * + * @param windowHandle The handle of the window to access. + * @param characterCount The maximum number of characters to retrieve. Default is 1024. + * + * @returns A promise that resolves to the text of the window as a string. + * + * @example + * ```typescript + * import { WinGetTextByHandle, WinGetHandle } from '@ahmic/autoit-js'; + * + * const windowHandle = await WinGetHandle('Untitled - Notepad'); + * const text = await WinGetTextByHandle(windowHandle); + * + * console.log(text); // Output: "Example text" + * ``` + * + * @see https://www.autoitscript.com/autoit3/docs/functions/WinGetText.htm + */ +export async function WinGetTextByHandle( + windowHandle: bigint, + characterCount: number = 1024, +): Promise { + const [buffer, length] = createUnicodeBuffer(characterCount); + + await autoit.invokeAsync( + 'AU3_WinGetTextByHandle', + VOID, + [HWND, LPWSTR, INT], + [windowHandle, buffer, length], + ); + + return unicodeBufferToString(buffer); +} diff --git a/src/win-get-text.ts b/src/win-get-text.ts index 1e5645d..51a8efe 100644 --- a/src/win-get-text.ts +++ b/src/win-get-text.ts @@ -13,16 +13,16 @@ import { createUnicodeBuffer, unicodeBufferToString } from './util'; * * @example * ```typescript - * import { WinGetText } from '@ahmic/autoit-js'; + * import { WinGetTextSync } from '@ahmic/autoit-js'; * - * const text = WinGetText('Untitled - Notepad'); + * const text = WinGetTextSync('Untitled - Notepad'); * * console.log(text); // Output: "Example text" * ``` * * @see https://www.autoitscript.com/autoit3/docs/functions/WinGetText.htm */ -export function WinGetText( +export function WinGetTextSync( windowTitle: string, windowText: string = '', characterCount: number = 1024, @@ -38,3 +38,40 @@ export function WinGetText( return unicodeBufferToString(buffer); } + +/** + * Retrieves the text from a window. + * + * @param windowTitle The title of the window to access. + * @param windowText Optional text found in the window. + * @param characterCount The maximum number of characters to retrieve. Default is 1024. + * + * @returns A promise that resolves to the text of the window as a string. + * + * @example + * ```typescript + * import { WinGetText } from '@ahmic/autoit-js'; + * + * const text = await WinGetText('Untitled - Notepad'); + * + * console.log(text); // Output: "Example text" + * ``` + * + * @see https://www.autoitscript.com/autoit3/docs/functions/WinGetText.htm + */ +export async function WinGetText( + windowTitle: string, + windowText: string = '', + characterCount: number = 1024, +): Promise { + const [buffer, length] = createUnicodeBuffer(characterCount); + + await autoit.invokeAsync( + 'AU3_WinGetText', + VOID, + [LPCWSTR, LPCWSTR, LPWSTR, INT], + [windowTitle, windowText, buffer, length], + ); + + return unicodeBufferToString(buffer); +} diff --git a/src/win-get-title-by-handle.ts b/src/win-get-title-by-handle.ts index 0b9954a..4efebe9 100644 --- a/src/win-get-title-by-handle.ts +++ b/src/win-get-title-by-handle.ts @@ -6,25 +6,62 @@ import { createUnicodeBuffer, unicodeBufferToString } from './util'; * Retrieves the title of a window. * * @param windowHandle The handle of the window to search for. + * @param characterCount The number of characters to read from the window title buffer (default is 1024). * * @returns The title of the window if found, or an empty string if not found. * * @example * ```typescript - * import { WinGetTitleByHandle, WinGetHandle } from '@ahmic/autoit-js'; + * import { WinGetTitleByHandleSync, WinGetHandleSync } from '@ahmic/autoit-js'; * - * const handle = WinGetHandle('Untitled - Notepad'); - * const title = WinGetTitleByHandle(handle); + * const handle = WinGetHandleSync('Untitled - Notepad'); + * const title = WinGetTitleByHandleSync(handle); * * console.log(title); // Output: "Untitled - Notepad" * ``` * * @see https://www.autoitscript.com/autoit3/docs/functions/WinGetTitle.htm */ -export function WinGetTitleByHandle(windowHandle: bigint, characterCount: number = 1024): string { +export function WinGetTitleByHandleSync(windowHandle: bigint, characterCount: number = 1024): string { const [buffer, length] = createUnicodeBuffer(characterCount); autoit.invoke('AU3_WinGetTitleByHandle', VOID, [HWND, LPWSTR, INT], [windowHandle, buffer, length]); return unicodeBufferToString(buffer); } + +/** + * Retrieves the title of a window. + * + * @param windowHandle The handle of the window to search for. + * @param characterCount The number of characters to read from the window title buffer (default is 1024). + * + * @returns A promise that resolves to the title of the window if found, or an empty string if not found. + * + * @example + * ```typescript + * import { WinGetTitleByHandle, WinGetHandle } from '@ahmic/autoit-js'; + * + * const handle = await WinGetHandle('Untitled - Notepad'); + * const title = await WinGetTitleByHandle(handle); + * + * console.log(title); // Output: "Untitled - Notepad" + * ``` + * + * @see https://www.autoitscript.com/autoit3/docs/functions/WinGetTitle.htm + */ +export async function WinGetTitleByHandle( + windowHandle: bigint, + characterCount: number = 1024, +): Promise { + const [buffer, length] = createUnicodeBuffer(characterCount); + + await autoit.invokeAsync( + 'AU3_WinGetTitleByHandle', + VOID, + [HWND, LPWSTR, INT], + [windowHandle, buffer, length], + ); + + return unicodeBufferToString(buffer); +} diff --git a/src/win-get-title.ts b/src/win-get-title.ts index af79d16..6d884d3 100644 --- a/src/win-get-title.ts +++ b/src/win-get-title.ts @@ -12,16 +12,16 @@ import { createUnicodeBuffer, unicodeBufferToString } from './util'; * * @example * ```typescript - * import { WinGetTitle } from '@ahmic/autoit-js'; + * import { WinGetTitleSync } from '@ahmic/autoit-js'; * - * const title = WinGetTitle('Untitled - Notepad'); + * const title = WinGetTitleSync('Untitled - Notepad'); * * console.log(title); // Output: "Untitled - Notepad" * ``` * * @see https://www.autoitscript.com/autoit3/docs/functions/WinGetTitle.htm */ -export function WinGetTitle( +export function WinGetTitleSync( windowTitle: string, windowText: string = '', characterCount: number = 1024, @@ -37,3 +37,39 @@ export function WinGetTitle( return unicodeBufferToString(buffer); } + +/** + * Retrieves the title of a window. + * + * @param windowTitle The title of the window to search for. + * @param windowText Optional text found in the window. + * + * @returns A promise that resolves to the title of the window if found, or an empty string if not found. + * + * @example + * ```typescript + * import { WinGetTitle } from '@ahmic/autoit-js'; + * + * const title = await WinGetTitle('Untitled - Notepad'); + * + * console.log(title); // Output: "Untitled - Notepad" + * ``` + * + * @see https://www.autoitscript.com/autoit3/docs/functions/WinGetTitle.htm + */ +export async function WinGetTitle( + windowTitle: string, + windowText: string = '', + characterCount: number = 1024, +): Promise { + const [buffer, length] = createUnicodeBuffer(characterCount); + + await autoit.invokeAsync( + 'AU3_WinGetTitle', + VOID, + [LPCWSTR, LPCWSTR, LPWSTR, INT], + [windowTitle, windowText, buffer, length], + ); + + return unicodeBufferToString(buffer); +} diff --git a/src/win-kill-by-handle.ts b/src/win-kill-by-handle.ts index 7335256..9c0ddb5 100644 --- a/src/win-kill-by-handle.ts +++ b/src/win-kill-by-handle.ts @@ -10,14 +10,35 @@ import { autoit } from './lib/autoit'; * * @example * ```typescript - * import { WinKillByHandle, WinGetHandle } from '@ahmic/autoit-js'; + * import { WinKillByHandleSync, WinGetHandleSync } from '@ahmic/autoit-js'; * - * const handle = WinGetHandle('Untitled - Notepad'); - * WinKillByHandle(handle); + * const handle = WinGetHandleSync('Untitled - Notepad'); + * WinKillByHandleSync(handle); * ``` * * @see https://www.autoitscript.com/autoit3/docs/functions/WinKill.htm */ -export function WinKillByHandle(windowHandle: bigint): number { +export function WinKillByHandleSync(windowHandle: bigint): number { return autoit.invoke('AU3_WinKillByHandle', INT, [HWND], [windowHandle]); } + +/** + * Forces a window to close. + * + * @param windowHandle The handle of the window to close. + * + * @returns A promise that resolves to 1 if successful, or 0 otherwise. + * + * @example + * ```typescript + * import { WinKillByHandle, WinGetHandle } from '@ahmic/autoit-js'; + * + * const handle = await WinGetHandle('Untitled - Notepad'); + * await WinKillByHandle(handle); + * ``` + * + * @see https://www.autoitscript.com/autoit3/docs/functions/WinKill.htm + */ +export function WinKillByHandle(windowHandle: bigint): Promise { + return autoit.invokeAsync('AU3_WinKillByHandle', INT, [HWND], [windowHandle]); +} diff --git a/src/win-kill.ts b/src/win-kill.ts index 30b616f..201c7e9 100644 --- a/src/win-kill.ts +++ b/src/win-kill.ts @@ -11,13 +11,34 @@ import { autoit } from './lib/autoit'; * * @example * ```typescript - * import { WinKill } from '@ahmic/autoit-js'; + * import { WinKillSync } from '@ahmic/autoit-js'; * - * WinKill('Untitled - Notepad'); + * WinKillSync('Untitled - Notepad'); * ``` * * @see https://www.autoitscript.com/autoit3/docs/functions/WinKill.htm */ -export function WinKill(windowTitle: string, windowText: string = ''): number { +export function WinKillSync(windowTitle: string, windowText: string = ''): number { return autoit.invoke('AU3_WinKill', INT, [LPCWSTR, LPCWSTR], [windowTitle, windowText]); } + +/** + * Forces a window to close. + * + * @param windowTitle The title of the window to close. + * @param windowText Optional text found in the window. + * + * @returns A promise that resolves to 1 if successful, or 0 otherwise. + * + * @example + * ```typescript + * import { WinKill } from '@ahmic/autoit-js'; + * + * await WinKill('Untitled - Notepad'); + * ``` + * + * @see https://www.autoitscript.com/autoit3/docs/functions/WinKill.htm + */ +export function WinKill(windowTitle: string, windowText: string = ''): Promise { + return autoit.invokeAsync('AU3_WinKill', INT, [LPCWSTR, LPCWSTR], [windowTitle, windowText]); +} diff --git a/src/win-menu-select-item-by-handle.ts b/src/win-menu-select-item-by-handle.ts index 23684cd..e252159 100644 --- a/src/win-menu-select-item-by-handle.ts +++ b/src/win-menu-select-item-by-handle.ts @@ -21,16 +21,16 @@ import { autoit } from './lib/autoit'; * * @example * ```typescript - * import { WinMenuSelectItemByHandle, WinGetHandle } from '@ahmic/autoit-js'; + * import { WinMenuSelectItemByHandleSync, WinGetHandleSync } from '@ahmic/autoit-js'; * - * const windowHandle = WinGetHandle('Untitled - Notepad'); + * const windowHandle = WinGetHandleSync('Untitled - Notepad'); * - * WinMenuSelectItemByHandle(windowHandle, 'File', 'Open'); + * WinMenuSelectItemByHandleSync(windowHandle, 'File', 'Open'); * ``` * * @see https://www.autoitscript.com/autoit3/docs/functions/WinMenuSelectItem.htm */ -export function WinMenuSelectItemByHandle( +export function WinMenuSelectItemByHandleSync( windowHandle: bigint, item1: string, item2: string = '', @@ -48,3 +48,51 @@ export function WinMenuSelectItemByHandle( [windowHandle, item1, item2, item3, item4, item5, item6, item7, item8], ); } + +/** + * Selects a menu item in a window. + * + * Underlined items in the menu must be selected using the `&` prefix. For example, if you're following the + * sequence `File -> Open`, you would use `&File` and `&Open` in the parameters. + * + * @param windowHandle The handle of the window containing the menu. + * @param item1 The text of the first-level menu item. + * @param item2 Optional text of the second-level menu item. + * @param item3 Optional text of the third-level menu item. + * @param item4 Optional text of the fourth-level menu item. + * @param item5 Optional text of the fifth-level menu item. + * @param item6 Optional text of the sixth-level menu item. + * @param item7 Optional text of the seventh-level menu item. + * @param item8 Optional text of the eighth-level menu item. + * + * @returns A promise that resolves to 1 if successful, or 0 otherwise. + * + * @example + * ```typescript + * import { WinMenuSelectItemByHandle, WinGetHandle } from '@ahmic/autoit-js'; + * + * const windowHandle = await WinGetHandle('Untitled - Notepad'); + * + * await WinMenuSelectItemByHandle(windowHandle, 'File', 'Open'); + * ``` + * + * @see https://www.autoitscript.com/autoit3/docs/functions/WinMenuSelectItem.htm + */ +export function WinMenuSelectItemByHandle( + windowHandle: bigint, + item1: string, + item2: string = '', + item3: string = '', + item4: string = '', + item5: string = '', + item6: string = '', + item7: string = '', + item8: string = '', +): Promise { + return autoit.invokeAsync( + 'AU3_WinMenuSelectItemByHandle', + INT, + [HWND, LPCWSTR, LPCWSTR, LPCWSTR, LPCWSTR, LPCWSTR, LPCWSTR, LPCWSTR, LPCWSTR], + [windowHandle, item1, item2, item3, item4, item5, item6, item7, item8], + ); +} diff --git a/src/win-menu-select-item.ts b/src/win-menu-select-item.ts index 5ec93e1..e76018a 100644 --- a/src/win-menu-select-item.ts +++ b/src/win-menu-select-item.ts @@ -22,14 +22,14 @@ import { autoit } from './lib/autoit'; * * @example * ```typescript - * import { WinMenuSelectItem } from '@ahmic/autoit-js'; + * import { WinMenuSelectItemSync } from '@ahmic/autoit-js'; * - * WinMenuSelectItem('Untitled - Notepad', '', '&File', '&Open'); + * WinMenuSelectItemSync('Untitled - Notepad', '', '&File', '&Open'); * ``` * * @see https://www.autoitscript.com/autoit3/docs/functions/WinMenuSelectItem.htm */ -export function WinMenuSelectItem( +export function WinMenuSelectItemSync( windowTitle: string, windowText: string = '', item1: string, @@ -48,3 +48,51 @@ export function WinMenuSelectItem( [windowTitle, windowText, item1, item2, item3, item4, item5, item6, item7, item8], ); } + +/** + * Selects a menu item in a window. + * + * Underlined items in the menu must be selected using the `&` prefix. For example, if you're following the + * sequence `File -> Open`, you would use `&File` and `&Open` in the parameters. + * + * @param windowTitle The title of the window to search for. + * @param windowText Optional text found in the window. + * @param item1 The text of the first-level menu item. + * @param item2 Optional text of the second-level menu item. + * @param item3 Optional text of the third-level menu item. + * @param item4 Optional text of the fourth-level menu item. + * @param item5 Optional text of the fifth-level menu item. + * @param item6 Optional text of the sixth-level menu item. + * @param item7 Optional text of the seventh-level menu item. + * @param item8 Optional text of the eighth-level menu item. + * + * @returns A promise that resolves to 1 if successful, or 0 otherwise. + * + * @example + * ```typescript + * import { WinMenuSelectItem } from '@ahmic/autoit-js'; + * + * await WinMenuSelectItem('Untitled - Notepad', '', '&File', '&Open'); + * ``` + * + * @see https://www.autoitscript.com/autoit3/docs/functions/WinMenuSelectItem.htm + */ +export function WinMenuSelectItem( + windowTitle: string, + windowText: string = '', + item1: string, + item2: string = '', + item3: string = '', + item4: string = '', + item5: string = '', + item6: string = '', + item7: string = '', + item8: string = '', +): Promise { + return autoit.invokeAsync( + 'AU3_WinMenuSelectItem', + INT, + [LPCWSTR, LPCWSTR, LPCWSTR, LPCWSTR, LPCWSTR, LPCWSTR, LPCWSTR, LPCWSTR, LPCWSTR, LPCWSTR], + [windowTitle, windowText, item1, item2, item3, item4, item5, item6, item7, item8], + ); +} diff --git a/src/win-minimize-all-undo.ts b/src/win-minimize-all-undo.ts index cbca3b0..d5d3411 100644 --- a/src/win-minimize-all-undo.ts +++ b/src/win-minimize-all-undo.ts @@ -1,6 +1,22 @@ import { VOID } from './@types'; import { autoit } from './lib/autoit'; +/** + * Undoes the minimize all action, restoring all minimized windows. + * + * @example + * ```typescript + * import { WinMinimizeAllUndoSync } from '@ahmic/autoit-js'; + * + * WinMinimizeAllUndoSync(); + * ``` + * + * @see https://www.autoitscript.com/autoit3/docs/functions/WinMinimizeAllUndo.htm + */ +export function WinMinimizeAllUndoSync(): void { + return autoit.invoke('AU3_WinMinimizeAllUndo', VOID, [], []); +} + /** * Undoes the minimize all action, restoring all minimized windows. * @@ -8,11 +24,11 @@ import { autoit } from './lib/autoit'; * ```typescript * import { WinMinimizeAllUndo } from '@ahmic/autoit-js'; * - * WinMinimizeAllUndo(); + * await WinMinimizeAllUndo(); * ``` * * @see https://www.autoitscript.com/autoit3/docs/functions/WinMinimizeAllUndo.htm */ -export function WinMinimizeAllUndo(): void { - autoit.invoke('AU3_WinMinimizeAllUndo', VOID, [], []); +export function WinMinimizeAllUndo(): Promise { + return autoit.invokeAsync('AU3_WinMinimizeAllUndo', VOID, [], []); } diff --git a/src/win-minimize-all.ts b/src/win-minimize-all.ts index 53b8a84..4aaa967 100644 --- a/src/win-minimize-all.ts +++ b/src/win-minimize-all.ts @@ -1,6 +1,22 @@ import { VOID } from './@types'; import { autoit } from './lib/autoit'; +/** + * Minimizes all windows. + * + * @example + * ```typescript + * import { WinMinimizeAllSync } from '@ahmic/autoit-js'; + * + * WinMinimizeAllSync(); + * ``` + * + * @see https://www.autoitscript.com/autoit3/docs/functions/WinMinimizeAll.htm + */ +export function WinMinimizeAllSync(): void { + return autoit.invoke('AU3_WinMinimizeAll', VOID, [], []); +} + /** * Minimizes all windows. * @@ -8,11 +24,11 @@ import { autoit } from './lib/autoit'; * ```typescript * import { WinMinimizeAll } from '@ahmic/autoit-js'; * - * WinMinimizeAll(); + * await WinMinimizeAll(); * ``` * * @see https://www.autoitscript.com/autoit3/docs/functions/WinMinimizeAll.htm */ -export function WinMinimizeAll(): void { - autoit.invoke('AU3_WinMinimizeAll', VOID, [], []); +export function WinMinimizeAll(): Promise { + return autoit.invokeAsync('AU3_WinMinimizeAll', VOID, [], []); } diff --git a/src/win-move-by-handle.ts b/src/win-move-by-handle.ts index 91cba47..ededa66 100644 --- a/src/win-move-by-handle.ts +++ b/src/win-move-by-handle.ts @@ -14,16 +14,16 @@ import { autoit } from './lib/autoit'; * * @example * ```typescript - * import { WinMoveByHandle, WinGetHandle } from '@ahmic/autoit-js'; + * import { WinMoveByHandleSync, WinGetHandleSync } from '@ahmic/autoit-js'; * - * const windowHandle = WinGetHandle('Untitled - Notepad'); + * const windowHandle = WinGetHandleSync('Untitled - Notepad'); * - * WinMoveByHandle(windowHandle, 100, 100, 800, 600); + * WinMoveByHandleSync(windowHandle, 100, 100, 800, 600); * ``` * * @see https://www.autoitscript.com/autoit3/docs/functions/WinMove.htm */ -export function WinMoveByHandle( +export function WinMoveByHandleSync( windowHandle: bigint, x: number, y: number, @@ -37,3 +37,40 @@ export function WinMoveByHandle( [windowHandle, x, y, width, height], ); } + +/** + * Moves a window to a specified position and resizes it. + * + * @param windowHandle The handle of the window to move. + * @param x The X coordinate of the new position. + * @param y The Y coordinate of the new position. + * @param width The new width of the window. + * @param height The new height of the window. + * + * @returns A promise that resolves to 1 if successful, or 0 otherwise. + * + * @example + * ```typescript + * import { WinMoveByHandle, WinGetHandle } from '@ahmic/autoit-js'; + * + * const windowHandle = await WinGetHandle('Untitled - Notepad'); + * + * await WinMoveByHandle(windowHandle, 100, 100, 800, 600); + * ``` + * + * @see https://www.autoitscript.com/autoit3/docs/functions/WinMove.htm + */ +export function WinMoveByHandle( + windowHandle: bigint, + x: number, + y: number, + width: number = -1, + height: number = -1, +): Promise { + return autoit.invokeAsync( + 'AU3_WinMoveByHandle', + INT, + [HWND, INT, INT, INT, INT], + [windowHandle, x, y, width, height], + ); +} diff --git a/src/win-move.ts b/src/win-move.ts index bb28f49..70bcc7c 100644 --- a/src/win-move.ts +++ b/src/win-move.ts @@ -15,14 +15,14 @@ import { autoit } from './lib/autoit'; * * @example * ```typescript - * import { WinMove } from '@ahmic/autoit-js'; + * import { WinMoveSync } from '@ahmic/autoit-js'; * - * WinMove('Untitled - Notepad', '', 100, 100, 800, 600); + * WinMoveSync('Untitled - Notepad', '', 100, 100, 800, 600); * ``` * * @see https://www.autoitscript.com/autoit3/docs/functions/WinMove.htm */ -export function WinMove( +export function WinMoveSync( windowTitle: string, windowText: string = '', x: number, @@ -37,3 +37,40 @@ export function WinMove( [windowTitle, windowText, x, y, width, height], ); } + +/** + * Moves a window to a specified position and resizes it. + * + * @param windowTitle The title of the window to move. + * @param windowText Optional text found in the window. + * @param x The X coordinate of the new position. + * @param y The Y coordinate of the new position. + * @param width The new width of the window. + * @param height The new height of the window. + * + * @returns A promise that resolves to 1 if successful, or 0 otherwise. + * + * @example + * ```typescript + * import { WinMove } from '@ahmic/autoit-js'; + * + * await WinMove('Untitled - Notepad', '', 100, 100, 800, 600); + * ``` + * + * @see https://www.autoitscript.com/autoit3/docs/functions/WinMove.htm + */ +export function WinMove( + windowTitle: string, + windowText: string = '', + x: number, + y: number, + width: number = -1, + height: number = -1, +): Promise { + return autoit.invokeAsync( + 'AU3_WinMove', + INT, + [LPCWSTR, LPCWSTR, INT, INT, INT, INT], + [windowTitle, windowText, x, y, width, height], + ); +} diff --git a/src/win-set-new-title-by-handle.ts b/src/win-set-new-title-by-handle.ts deleted file mode 100644 index 8d5caf9..0000000 --- a/src/win-set-new-title-by-handle.ts +++ /dev/null @@ -1,25 +0,0 @@ -import { HWND, INT, LPCWSTR } from './@types'; -import { autoit } from './lib/autoit'; - -/** - * Changes the title of a window. - * - * @param windowHandle The handle of the window to modify. - * @param newTitle The new title to set for the window. - * - * @returns 1 if successful, 0 otherwise. - * - * @example - * ```typescript - * import { WinSetTitleByHandle, WinGetHandle } from '@ahmic/autoit-js'; - * - * const windowHandle = WinGetHandle('Untitled - Notepad'); - * - * WinSetTitleByHandle(windowHandle, 'New Title'); - * ``` - * - * @see https://www.autoitscript.com/autoit3/docs/functions/WinSetTitle.htm - */ -export function WinSetTitleByHandle(windowHandle: bigint, newTitle: string): number { - return autoit.invoke('AU3_WinSetTitleByHandle', INT, [HWND, LPCWSTR], [windowHandle, newTitle]); -} diff --git a/src/win-set-on-top-by-handle.ts b/src/win-set-on-top-by-handle.ts index 35927e1..0f79d64 100644 --- a/src/win-set-on-top-by-handle.ts +++ b/src/win-set-on-top-by-handle.ts @@ -11,15 +11,38 @@ import { autoit } from './lib/autoit'; * * @example * ```typescript - * import { WinSetOnTopByHandle, WinGetHandle } from '@ahmic/autoit-js'; + * import { WinSetOnTopByHandleSync, WinGetHandleSync } from '@ahmic/autoit-js'; * - * const windowHandle = WinGetHandle('Untitled - Notepad'); + * const windowHandle = WinGetHandleSync('Untitled - Notepad'); * - * WinSetOnTopByHandle(windowHandle, true); + * WinSetOnTopByHandleSync(windowHandle, true); * ``` * * @see https://www.autoitscript.com/autoit3/docs/functions/WinSetOnTop.htm */ -export function WinSetOnTopByHandle(windowHandle: bigint, onTop: boolean): number { +export function WinSetOnTopByHandleSync(windowHandle: bigint, onTop: boolean): number { return autoit.invoke('AU3_WinSetOnTopByHandle', INT, [HWND, INT], [windowHandle, onTop ? 1 : 0]); } + +/** + * Sets whether a window is on top of all other windows. + * + * @param windowHandle The handle of the window to set on top. + * @param onTop Whether to set the window on top or not. + * + * @returns A promise that resolves to 1 if the operation was successful, or 0 otherwise. + * + * @example + * ```typescript + * import { WinSetOnTopByHandle, WinGetHandle } from '@ahmic/autoit-js'; + * + * const windowHandle = await WinGetHandle('Untitled - Notepad'); + * + * await WinSetOnTopByHandle(windowHandle, true); + * ``` + * + * @see https://www.autoitscript.com/autoit3/docs/functions/WinSetOnTop.htm + */ +export function WinSetOnTopByHandle(windowHandle: bigint, onTop: boolean): Promise { + return autoit.invokeAsync('AU3_WinSetOnTopByHandle', INT, [HWND, INT], [windowHandle, onTop ? 1 : 0]); +} diff --git a/src/win-set-on-top.ts b/src/win-set-on-top.ts index 174400a..75ebbd3 100644 --- a/src/win-set-on-top.ts +++ b/src/win-set-on-top.ts @@ -12,14 +12,14 @@ import { autoit } from './lib/autoit'; * * @example * ```typescript - * import { WinSetOnTop } from '@ahmic/autoit-js'; + * import { WinSetOnTopSync } from '@ahmic/autoit-js'; * - * WinSetOnTop('Untitled - Notepad', '', true); + * WinSetOnTopSync('Untitled - Notepad', '', true); * ``` * * @see https://www.autoitscript.com/autoit3/docs/functions/WinSetOnTop.htm */ -export function WinSetOnTop(windowTitle: string, windowText: string = '', onTop: boolean): number { +export function WinSetOnTopSync(windowTitle: string, windowText: string = '', onTop: boolean): number { return autoit.invoke( 'AU3_WinSetOnTop', INT, @@ -27,3 +27,30 @@ export function WinSetOnTop(windowTitle: string, windowText: string = '', onTop: [windowTitle, windowText, onTop ? 1 : 0], ); } + +/** + * Sets whether a window is on top of all other windows. + * + * @param windowTitle The title of the window to set on top. + * @param windowText Optional text found in the window. + * @param onTop Whether to set the window on top or not. + * + * @returns A promise that resolves to 1 if the operation was successful, or 0 otherwise. + * + * @example + * ```typescript + * import { WinSetOnTop } from '@ahmic/autoit-js'; + * + * await WinSetOnTop('Untitled - Notepad', '', true); + * ``` + * + * @see https://www.autoitscript.com/autoit3/docs/functions/WinSetOnTop.htm + */ +export function WinSetOnTop(windowTitle: string, windowText: string = '', onTop: boolean): Promise { + return autoit.invokeAsync( + 'AU3_WinSetOnTop', + INT, + [LPCWSTR, LPCWSTR, INT], + [windowTitle, windowText, onTop ? 1 : 0], + ); +} diff --git a/src/win-set-state-by-handle.ts b/src/win-set-state-by-handle.ts index 07620cd..5dd2e63 100644 --- a/src/win-set-state-by-handle.ts +++ b/src/win-set-state-by-handle.ts @@ -12,15 +12,38 @@ import { StateFlag } from './win-set-state'; * * @example * ```typescript - * import { WinSetStateByHandle, StateFlag, WinGetHandle } from '@ahmic/autoit-js'; + * import { WinSetStateByHandleSync, StateFlag, WinGetHandleSync } from '@ahmic/autoit-js'; * - * const windowHandle = WinGetHandle('Untitled - Notepad'); + * const windowHandle = WinGetHandleSync('Untitled - Notepad'); * - * WinSetStateByHandle(windowHandle, StateFlag.Minimize); + * WinSetStateByHandleSync(windowHandle, StateFlag.Minimize); * ``` * * @see https://www.autoitscript.com/autoit3/docs/functions/WinSetState.htm */ -export function WinSetStateByHandle(windowHandle: bigint, flags: StateFlag): number { +export function WinSetStateByHandleSync(windowHandle: bigint, flags: StateFlag): number { return autoit.invoke('AU3_WinSetStateByHandle', INT, [HWND, INT], [windowHandle, flags]); } + +/** + * Changes the state of a window. + * + * @param windowHandle The handle of the window. + * @param flags The state flags to apply. See {@linkcode StateFlag} for details. + * + * @returns A promise that resolves to 1 if successful, or 0 otherwise. + * + * @example + * ```typescript + * import { WinSetStateByHandle, StateFlag, WinGetHandle } from '@ahmic/autoit-js'; + * + * const windowHandle = await WinGetHandle('Untitled - Notepad'); + * + * await WinSetStateByHandle(windowHandle, StateFlag.Minimize); + * ``` + * + * @see https://www.autoitscript.com/autoit3/docs/functions/WinSetState.htm + */ +export function WinSetStateByHandle(windowHandle: bigint, flags: StateFlag): Promise { + return autoit.invokeAsync('AU3_WinSetStateByHandle', INT, [HWND, INT], [windowHandle, flags]); +} diff --git a/src/win-set-state.ts b/src/win-set-state.ts index 22d21de..6dfe308 100644 --- a/src/win-set-state.ts +++ b/src/win-set-state.ts @@ -44,13 +44,40 @@ export enum StateFlag { * * @example * ```typescript - * import { WinSetState, StateFlag } from '@ahmic/autoit-js'; + * import { WinSetStateSync, StateFlag } from '@ahmic/autoit-js'; * - * WinSetState('Untitled - Notepad', '', StateFlag.Minimize); + * WinSetStateSync('Untitled - Notepad', '', StateFlag.Minimize); * ``` * * @see https://www.autoitscript.com/autoit3/docs/functions/WinSetState.htm */ -export function WinSetState(windowTitle: string, windowText: string = '', flags: StateFlag): number { +export function WinSetStateSync(windowTitle: string, windowText: string = '', flags: StateFlag): number { return autoit.invoke('AU3_WinSetState', INT, [LPCWSTR, LPCWSTR, INT], [windowTitle, windowText, flags]); } + +/** + * Changes the state of a window. + * + * @param windowTitle The title of the window. + * @param windowText Optional text found in the window. + * @param flags The state flags to apply. See {@linkcode StateFlag} for details. + * + * @returns A promise that resolves to 1 if successful, or 0 otherwise. + * + * @example + * ```typescript + * import { WinSetState, StateFlag } from '@ahmic/autoit-js'; + * + * await WinSetState('Untitled - Notepad', '', StateFlag.Minimize); + * ``` + * + * @see https://www.autoitscript.com/autoit3/docs/functions/WinSetState.htm + */ +export function WinSetState(windowTitle: string, windowText: string = '', flags: StateFlag): Promise { + return autoit.invokeAsync( + 'AU3_WinSetState', + INT, + [LPCWSTR, LPCWSTR, INT], + [windowTitle, windowText, flags], + ); +} diff --git a/src/win-set-title-by-handle.ts b/src/win-set-title-by-handle.ts new file mode 100644 index 0000000..695e9fe --- /dev/null +++ b/src/win-set-title-by-handle.ts @@ -0,0 +1,48 @@ +import { HWND, INT, LPCWSTR } from './@types'; +import { autoit } from './lib/autoit'; + +/** + * Changes the title of a window. + * + * @param windowHandle The handle of the window to modify. + * @param newTitle The new title to set for the window. + * + * @returns 1 if successful, 0 otherwise. + * + * @example + * ```typescript + * import { WinSetTitleByHandleSync, WinGetHandleSync } from '@ahmic/autoit-js'; + * + * const windowHandle = WinGetHandleSync('Untitled - Notepad'); + * + * WinSetTitleByHandleSync(windowHandle, 'New Title'); + * ``` + * + * @see https://www.autoitscript.com/autoit3/docs/functions/WinSetTitle.htm + */ +export function WinSetTitleByHandleSync(windowHandle: bigint, newTitle: string): number { + return autoit.invoke('AU3_WinSetTitleByHandle', INT, [HWND, LPCWSTR], [windowHandle, newTitle]); +} + +/** + * Changes the title of a window. + * + * @param windowHandle The handle of the window to modify. + * @param newTitle The new title to set for the window. + * + * @returns A promise that resolves to 1 if successful, or 0 otherwise. + * + * @example + * ```typescript + * import { WinSetTitleByHandle, WinGetHandle } from '@ahmic/autoit-js'; + * + * const windowHandle = await WinGetHandle('Untitled - Notepad'); + * + * await WinSetTitleByHandle(windowHandle, 'New Title'); + * ``` + * + * @see https://www.autoitscript.com/autoit3/docs/functions/WinSetTitle.htm + */ +export function WinSetTitleByHandle(windowHandle: bigint, newTitle: string): Promise { + return autoit.invokeAsync('AU3_WinSetTitleByHandle', INT, [HWND, LPCWSTR], [windowHandle, newTitle]); +} diff --git a/src/win-set-title.ts b/src/win-set-title.ts index c223fd0..f71a771 100644 --- a/src/win-set-title.ts +++ b/src/win-set-title.ts @@ -12,14 +12,14 @@ import { autoit } from './lib/autoit'; * * @example * ```typescript - * import { WinSetTitle } from '@ahmic/autoit-js'; + * import { WinSetTitleSync } from '@ahmic/autoit-js'; * - * WinSetTitle('Untitled - Notepad', '', 'New Title'); + * WinSetTitleSync('Untitled - Notepad', '', 'New Title'); * ``` * * @see https://www.autoitscript.com/autoit3/docs/functions/WinSetTitle.htm */ -export function WinSetTitle(windowTitle: string, windowText: string = '', newTitle: string): number { +export function WinSetTitleSync(windowTitle: string, windowText: string = '', newTitle: string): number { return autoit.invoke( 'AU3_WinSetTitle', INT, @@ -27,3 +27,30 @@ export function WinSetTitle(windowTitle: string, windowText: string = '', newTit [windowTitle, windowText, newTitle], ); } + +/** + * Changes the title of a window. + * + * @param windowTitle The title of the window to modify. + * @param windowText Optional text found in the window. + * @param newTitle The new title to set for the window. + * + * @returns A promise that resolves to 1 if successful, or 0 otherwise. + * + * @example + * ```typescript + * import { WinSetTitle } from '@ahmic/autoit-js'; + * + * await WinSetTitle('Untitled - Notepad', '', 'New Title'); + * ``` + * + * @see https://www.autoitscript.com/autoit3/docs/functions/WinSetTitle.htm + */ +export function WinSetTitle(windowTitle: string, windowText: string = '', newTitle: string): Promise { + return autoit.invokeAsync( + 'AU3_WinSetTitle', + INT, + [LPCWSTR, LPCWSTR, LPCWSTR], + [windowTitle, windowText, newTitle], + ); +} diff --git a/src/win-set-trans-by-handle.ts b/src/win-set-trans-by-handle.ts index 3fb7d2d..655b460 100644 --- a/src/win-set-trans-by-handle.ts +++ b/src/win-set-trans-by-handle.ts @@ -11,15 +11,38 @@ import { autoit } from './lib/autoit'; * * @example * ```typescript - * import { WinSetTransByHandle, WinGetHandle } from '@ahmic/autoit-js'; + * import { WinSetTransByHandleSync, WinGetHandleSync } from '@ahmic/autoit-js'; * - * const windowHandle = WinGetHandle('Untitled - Notepad'); + * const windowHandle = WinGetHandleSync('Untitled - Notepad'); * - * WinSetTransByHandle(windowHandle, 128); + * WinSetTransByHandleSync(windowHandle, 128); * ``` * * @see https://www.autoitscript.com/autoit3/docs/functions/WinSetTrans.htm */ -export function WinSetTransByHandle(windowHandle: bigint, transparency: number): number { +export function WinSetTransByHandleSync(windowHandle: bigint, transparency: number): number { return autoit.invoke('AU3_WinSetTransByHandle', INT, [HWND, INT], [windowHandle, transparency]); } + +/** + * Sets the transparency level of a window. 0 is fully transparent, 255 is fully opaque. + * + * @param windowHandle The handle of the window. + * @param transparency The transparency level (0-255). + * + * @returns A promise that resolves to 1 if successful, or 0 otherwise. + * + * @example + * ```typescript + * import { WinSetTransByHandle, WinGetHandle } from '@ahmic/autoit-js'; + * + * const windowHandle = await WinGetHandle('Untitled - Notepad'); + * + * await WinSetTransByHandle(windowHandle, 128); + * ``` + * + * @see https://www.autoitscript.com/autoit3/docs/functions/WinSetTrans.htm + */ +export function WinSetTransByHandle(windowHandle: bigint, transparency: number): Promise { + return autoit.invokeAsync('AU3_WinSetTransByHandle', INT, [HWND, INT], [windowHandle, transparency]); +} diff --git a/src/win-set-trans.ts b/src/win-set-trans.ts index 8cfaf15..46c94bc 100644 --- a/src/win-set-trans.ts +++ b/src/win-set-trans.ts @@ -12,14 +12,14 @@ import { autoit } from './lib/autoit'; * * @example * ```typescript - * import { WinSetTrans } from '@ahmic/autoit-js'; + * import { WinSetTransSync } from '@ahmic/autoit-js'; * - * WinSetTrans('Untitled - Notepad', '', 128); + * WinSetTransSync('Untitled - Notepad', '', 128); * ``` * * @see https://www.autoitscript.com/autoit3/docs/functions/WinSetTrans.htm */ -export function WinSetTrans(windowTitle: string, windowText: string = '', transparency: number): number { +export function WinSetTransSync(windowTitle: string, windowText: string = '', transparency: number): number { return autoit.invoke( 'AU3_WinSetTrans', INT, @@ -27,3 +27,34 @@ export function WinSetTrans(windowTitle: string, windowText: string = '', transp [windowTitle, windowText, transparency], ); } + +/** + * Sets the transparency level of a window. 0 is fully transparent, 255 is fully opaque. + * + * @param windowTitle The title of the window. + * @param windowText Optional text found in the window. + * @param transparency The transparency level (0-255). + * + * @returns A promise that resolves to 1 if successful, or 0 otherwise. + * + * @example + * ```typescript + * import { WinSetTrans } from '@ahmic/autoit-js'; + * + * await WinSetTrans('Untitled - Notepad', '', 128); + * ``` + * + * @see https://www.autoitscript.com/autoit3/docs/functions/WinSetTrans.htm + */ +export function WinSetTrans( + windowTitle: string, + windowText: string = '', + transparency: number, +): Promise { + return autoit.invokeAsync( + 'AU3_WinSetTrans', + INT, + [LPCWSTR, LPCWSTR, INT], + [windowTitle, windowText, transparency], + ); +} diff --git a/src/win-wait-active-by-handle.ts b/src/win-wait-active-by-handle.ts index 0986e23..1d61358 100644 --- a/src/win-wait-active-by-handle.ts +++ b/src/win-wait-active-by-handle.ts @@ -11,14 +11,36 @@ import { autoit } from './lib/autoit'; * * @example * ```typescript - * import { WinWaitActiveByHandle, WinGetHandle } from '@ahmic/autoit-js'; + * import { WinWaitActiveByHandleSync, WinGetHandleSync } from '@ahmic/autoit-js'; * - * const windowHandle = WinGetHandle('Untitled - Notepad'); - * WinWaitActiveByHandle(windowHandle, 10); + * const windowHandle = WinGetHandleSync('Untitled - Notepad'); + * WinWaitActiveByHandleSync(windowHandle, 10); * ``` * * @see https://www.autoitscript.com/autoit3/docs/functions/WinWaitActive.htm */ -export function WinWaitActiveByHandle(windowHandle: bigint, timeout: number = 0): number { +export function WinWaitActiveByHandleSync(windowHandle: bigint, timeout: number = 0): number { return autoit.invoke('AU3_WinWaitActiveByHandle', INT, [HWND, INT], [windowHandle, timeout]); } + +/** + * Waits for a window to become active. + * + * @param windowHandle The handle of the window to wait for. + * @param timeout The timeout in seconds. Defaults to 0 (wait indefinitely). + * + * @returns A promise that resolves to 1 if the window becomes active, or 0 if the timeout is reached. + * + * @example + * ```typescript + * import { WinWaitActiveByHandle, WinGetHandle } from '@ahmic/autoit-js'; + * + * const windowHandle = await WinGetHandle('Untitled - Notepad'); + * await WinWaitActiveByHandle(windowHandle, 10); + * ``` + * + * @see https://www.autoitscript.com/autoit3/docs/functions/WinWaitActive.htm + */ +export function WinWaitActiveByHandle(windowHandle: bigint, timeout: number = 0): Promise { + return autoit.invokeAsync('AU3_WinWaitActiveByHandle', INT, [HWND, INT], [windowHandle, timeout]); +} diff --git a/src/win-wait-active.ts b/src/win-wait-active.ts index 81aeb10..c9ece33 100644 --- a/src/win-wait-active.ts +++ b/src/win-wait-active.ts @@ -12,13 +12,44 @@ import { autoit } from './lib/autoit'; * * @example * ```typescript - * import { WinWaitActive } from '@ahmic/autoit-js'; + * import { WinWaitActiveSync } from '@ahmic/autoit-js'; * - * WinWaitActive('Untitled - Notepad', '', 10); + * WinWaitActiveSync('Untitled - Notepad', '', 10); * ``` * * @see https://www.autoitscript.com/autoit3/docs/functions/WinWaitActive.htm */ -export function WinWaitActive(windowTitle: string, windowText: string = '', timeout: number = 0): number { +export function WinWaitActiveSync(windowTitle: string, windowText: string = '', timeout: number = 0): number { return autoit.invoke('AU3_WinWaitActive', INT, [LPCWSTR, LPCWSTR, INT], [windowTitle, windowText, timeout]); } + +/** + * Waits for a window to become active. + * + * @param windowTitle The title of the window to wait for. + * @param windowText Optional text found in the window. + * @param timeout The timeout in seconds. Defaults to 0 (wait indefinitely). + * + * @returns A promise that resolves to 1 if the window becomes active, or 0 if the timeout is reached. + * + * @example + * ```typescript + * import { WinWaitActive } from '@ahmic/autoit-js'; + * + * await WinWaitActive('Untitled - Notepad', '', 10); + * ``` + * + * @see https://www.autoitscript.com/autoit3/docs/functions/WinWaitActive.htm + */ +export function WinWaitActive( + windowTitle: string, + windowText: string = '', + timeout: number = 0, +): Promise { + return autoit.invokeAsync( + 'AU3_WinWaitActive', + INT, + [LPCWSTR, LPCWSTR, INT], + [windowTitle, windowText, timeout], + ); +} diff --git a/src/win-wait-by-handle.ts b/src/win-wait-by-handle.ts index 46d912c..9cba85c 100644 --- a/src/win-wait-by-handle.ts +++ b/src/win-wait-by-handle.ts @@ -11,14 +11,36 @@ import { autoit } from './lib/autoit'; * * @example * ```typescript - * import { WinWaitByHandle, WinGetHandle } from '@ahmic/autoit-js'; + * import { WinWaitByHandleSync, WinGetHandleSync } from '@ahmic/autoit-js'; * - * const handle = WinGetHandle('Untitled - Notepad'); - * WinWaitByHandle(handle, 10); + * const handle = WinGetHandleSync('Untitled - Notepad'); + * WinWaitByHandleSync(handle, 10); * ``` * * @see https://www.autoitscript.com/autoit3/docs/functions/WinWait.htm */ -export function WinWaitByHandle(windowHandle: bigint, timeout: number = 0): number { +export function WinWaitByHandleSync(windowHandle: bigint, timeout: number = 0): number { return autoit.invoke('AU3_WinWaitByHandle', INT, [HWND, INT], [windowHandle, timeout]); } + +/** + * Waits for a window to exist. + * + * @param windowHandle The handle of the window to wait for. + * @param timeout The timeout in seconds. Default is 0 (wait indefinitely). + * + * @returns A promise that resolves to 1 if the window exists, or 0 if the timeout is reached. + * + * @example + * ```typescript + * import { WinWaitByHandle, WinGetHandle } from '@ahmic/autoit-js'; + * + * const handle = await WinGetHandle('Untitled - Notepad'); + * await WinWaitByHandle(handle, 10); + * ``` + * + * @see https://www.autoitscript.com/autoit3/docs/functions/WinWait.htm + */ +export function WinWaitByHandle(windowHandle: bigint, timeout: number = 0): Promise { + return autoit.invokeAsync('AU3_WinWaitByHandle', INT, [HWND, INT], [windowHandle, timeout]); +} diff --git a/src/win-wait-close-by-handle.ts b/src/win-wait-close-by-handle.ts index 6dbec9f..3d3c422 100644 --- a/src/win-wait-close-by-handle.ts +++ b/src/win-wait-close-by-handle.ts @@ -11,14 +11,36 @@ import { autoit } from './lib/autoit'; * * @example * ```typescript - * import { WinWaitCloseByHandle, WinGetHandle } from '@ahmic/autoit-js'; + * import { WinWaitCloseByHandleSync, WinGetHandleSync } from '@ahmic/autoit-js'; * - * const handle = WinGetHandle('Untitled - Notepad'); - * WinWaitCloseByHandle(handle, 10); + * const handle = WinGetHandleSync('Untitled - Notepad'); + * WinWaitCloseByHandleSync(handle, 10); * ``` * * @see https://www.autoitscript.com/autoit3/docs/functions/WinWaitClose.htm */ -export function WinWaitCloseByHandle(windowHandle: bigint, timeout: number = 0): number { +export function WinWaitCloseByHandleSync(windowHandle: bigint, timeout: number = 0): number { return autoit.invoke('AU3_WinWaitCloseByHandle', INT, [HWND, INT], [windowHandle, timeout]); } + +/** + * Waits for a window to close. + * + * @param windowHandle The handle of the window to wait for. + * @param timeout The timeout in seconds. Default is 0 (wait indefinitely). + * + * @returns A promise that resolves to 1 if the window closes, or 0 if the timeout is reached. + * + * @example + * ```typescript + * import { WinWaitCloseByHandle, WinGetHandle } from '@ahmic/autoit-js'; + * + * const handle = await WinGetHandle('Untitled - Notepad'); + * await WinWaitCloseByHandle(handle, 10); + * ``` + * + * @see https://www.autoitscript.com/autoit3/docs/functions/WinWaitClose.htm + */ +export function WinWaitCloseByHandle(windowHandle: bigint, timeout: number = 0): Promise { + return autoit.invokeAsync('AU3_WinWaitCloseByHandle', INT, [HWND, INT], [windowHandle, timeout]); +} diff --git a/src/win-wait-close.ts b/src/win-wait-close.ts index a1ea9b6..02d60ff 100644 --- a/src/win-wait-close.ts +++ b/src/win-wait-close.ts @@ -12,13 +12,44 @@ import { autoit } from './lib/autoit'; * * @example * ```typescript - * import { WinWaitClose } from '@ahmic/autoit-js'; + * import { WinWaitCloseSync } from '@ahmic/autoit-js'; * - * WinWaitClose('Untitled - Notepad', '', 10); + * WinWaitCloseSync('Untitled - Notepad', '', 10); * ``` * * @see https://www.autoitscript.com/autoit3/docs/functions/WinWaitClose.htm */ -export function WinWaitClose(windowTitle: string, windowText: string = '', timeout: number = 0): number { +export function WinWaitCloseSync(windowTitle: string, windowText: string = '', timeout: number = 0): number { return autoit.invoke('AU3_WinWaitClose', INT, [LPCWSTR, LPCWSTR, INT], [windowTitle, windowText, timeout]); } + +/** + * Waits for a window to close. + * + * @param windowTitle The title of the window to wait for. + * @param windowText Optional text found in the window. + * @param timeout The timeout in seconds. Default is 0 (wait indefinitely). + * + * @returns A promise that resolves to 1 if the window closes, 0 if the timeout is reached. + * + * @example + * ```typescript + * import { WinWaitClose } from '@ahmic/autoit-js'; + * + * await WinWaitClose('Untitled - Notepad', '', 10); + * ``` + * + * @see https://www.autoitscript.com/autoit3/docs/functions/WinWaitClose.htm + */ +export function WinWaitClose( + windowTitle: string, + windowText: string = '', + timeout: number = 0, +): Promise { + return autoit.invokeAsync( + 'AU3_WinWaitClose', + INT, + [LPCWSTR, LPCWSTR, INT], + [windowTitle, windowText, timeout], + ); +} diff --git a/src/win-wait-not-active-by-handle.ts b/src/win-wait-not-active-by-handle.ts index 6601c05..a86dc78 100644 --- a/src/win-wait-not-active-by-handle.ts +++ b/src/win-wait-not-active-by-handle.ts @@ -11,15 +11,38 @@ import { autoit } from './lib/autoit'; * * @example * ```typescript - * import { WinWaitNotActiveByHandle, WinGetHandle } from '@ahmic/autoit-js'; + * import { WinWaitNotActiveByHandleSync, WinGetHandleSync } from '@ahmic/autoit-js'; * - * const windowHandle = WinGetHandle('Untitled - Notepad'); + * const windowHandle = WinGetHandleSync('Untitled - Notepad'); * - * WinWaitNotActiveByHandle(windowHandle, 10); + * WinWaitNotActiveByHandleSync(windowHandle, 10); * ``` * * @see https://www.autoitscript.com/autoit3/docs/functions/WinWaitNotActive.htm */ -export function WinWaitNotActiveByHandle(windowHandle: bigint, timeout: number = 0): number { +export function WinWaitNotActiveByHandleSync(windowHandle: bigint, timeout: number = 0): number { return autoit.invoke('AU3_WinWaitNotActiveByHandle', INT, [HWND, INT], [windowHandle, timeout]); } + +/** + * Waits for a window to become inactive. + * + * @param windowHandle The handle of the window to wait for. + * @param timeout The timeout in seconds. Defaults to 0 (wait indefinitely). + * + * @returns 1 if the window becomes inactive, 0 if the timeout is reached. + * + * @example + * ```typescript + * import { WinWaitNotActiveByHandle, WinGetHandle } from '@ahmic/autoit-js'; + * + * const windowHandle = await WinGetHandle('Untitled - Notepad'); + * + * await WinWaitNotActiveByHandle(windowHandle, 10); + * ``` + * + * @see https://www.autoitscript.com/autoit3/docs/functions/WinWaitNotActive.htm + */ +export function WinWaitNotActiveByHandle(windowHandle: bigint, timeout: number = 0): Promise { + return autoit.invokeAsync('AU3_WinWaitNotActiveByHandle', INT, [HWND, INT], [windowHandle, timeout]); +} diff --git a/src/win-wait-not-active.ts b/src/win-wait-not-active.ts index f7cd8d5..1d70242 100644 --- a/src/win-wait-not-active.ts +++ b/src/win-wait-not-active.ts @@ -12,14 +12,18 @@ import { autoit } from './lib/autoit'; * * @example * ```typescript - * import { WinWaitNotActive } from '@ahmic/autoit-js'; + * import { WinWaitNotActiveSync } from '@ahmic/autoit-js'; * - * WinWaitNotActive('Untitled - Notepad', '', 10); + * WinWaitNotActiveSync('Untitled - Notepad', '', 10); * ``` * * @see https://www.autoitscript.com/autoit3/docs/functions/WinWaitNotActive.htm */ -export function WinWaitNotActive(windowTitle: string, windowText: string = '', timeout: number = 0): number { +export function WinWaitNotActiveSync( + windowTitle: string, + windowText: string = '', + timeout: number = 0, +): number { return autoit.invoke( 'AU3_WinWaitNotActive', INT, @@ -27,3 +31,34 @@ export function WinWaitNotActive(windowTitle: string, windowText: string = '', t [windowTitle, windowText, timeout], ); } + +/** + * Waits for a window to become inactive. + * + * @param windowTitle The title of the window to wait for. + * @param windowText Optional text found in the window. + * @param timeout The timeout in seconds. Defaults to 0 (wait indefinitely). + * + * @returns A promise that resolves to 1 if the window becomes inactive, 0 if the timeout is reached. + * + * @example + * ```typescript + * import { WinWaitNotActive } from '@ahmic/autoit-js'; + * + * await WinWaitNotActive('Untitled - Notepad', '', 10); + * ``` + * + * @see https://www.autoitscript.com/autoit3/docs/functions/WinWaitNotActive.htm + */ +export function WinWaitNotActive( + windowTitle: string, + windowText: string = '', + timeout: number = 0, +): Promise { + return autoit.invokeAsync( + 'AU3_WinWaitNotActive', + INT, + [LPCWSTR, LPCWSTR, INT], + [windowTitle, windowText, timeout], + ); +} diff --git a/src/win-wait.ts b/src/win-wait.ts index 5c817bb..5297691 100644 --- a/src/win-wait.ts +++ b/src/win-wait.ts @@ -12,13 +12,35 @@ import { autoit } from './lib/autoit'; * * @example * ```typescript - * import { WinWait } from '@ahmic/autoit-js'; + * import { WinWaitSync } from '@ahmic/autoit-js'; * - * WinWait('Untitled - Notepad', '', 10); + * WinWaitSync('Untitled - Notepad', '', 10); * ``` * * @see https://www.autoitscript.com/autoit3/docs/functions/WinWait.htm */ -export function WinWait(windowTitle: string, windowText: string = '', timeout: number = 0): number { +export function WinWaitSync(windowTitle: string, windowText: string = '', timeout: number = 0): number { return autoit.invoke('AU3_WinWait', INT, [LPCWSTR, LPCWSTR, INT], [windowTitle, windowText, timeout]); } + +/** + * Waits for a window to exist. + * + * @param windowTitle The title of the window to wait for. + * @param windowText Optional text found in the window. + * @param timeout The timeout in seconds. Default is 0 (wait indefinitely). + * + * @returns A promise that resolves to 1 if the window exists, 0 if the timeout is reached. + * + * @example + * ```typescript + * import { WinWait } from '@ahmic/autoit-js'; + * + * await WinWait('Untitled - Notepad', '', 10); + * ``` + * + * @see https://www.autoitscript.com/autoit3/docs/functions/WinWait.htm + */ +export function WinWait(windowTitle: string, windowText: string = '', timeout: number = 0): Promise { + return autoit.invokeAsync('AU3_WinWait', INT, [LPCWSTR, LPCWSTR, INT], [windowTitle, windowText, timeout]); +} diff --git a/tsconfig.json b/tsconfig.json index dc6c311..c429a24 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -6,7 +6,7 @@ "target": "ES2023", "esModuleInterop": true, "declaration": true, - "removeComments": true, + "removeComments": false, "emitDecoratorMetadata": true, "experimentalDecorators": true, "emitDeclarationOnly": true, diff --git a/vitest.config.ts b/vitest.config.ts index 8f20081..a4d117a 100644 --- a/vitest.config.ts +++ b/vitest.config.ts @@ -1,9 +1,13 @@ +import { platform } from 'node:os'; + import { defineConfig } from 'vitest/config'; export default defineConfig({ test: { api: 9527, globals: true, + maxWorkers: 1, + exclude: platform() !== 'win32' ? ['**/node_modules/**', '**/autoit-*.test.ts'] : [], coverage: { all: true, enabled: true,