Merge branch 'develop'

This commit is contained in:
Simon Hofmann
2023-06-06 15:23:56 +02:00
10 changed files with 335 additions and 297 deletions
+8
View File
@@ -2,6 +2,14 @@
All notable changes to this project will be documented in this file.
## 3.1.2
- Bugfix: Screen capture broken on macOS 13 [(#469)](https://github.com/nut-tree/nut.js/issues/469)
- Enhancement: Enable newly introduced keys to be used as modifiers [(#490)](https://github.com/nut-tree/nut.js/issues/490)
- Enhancement: Extend move API to handle single point case [(#499)](https://github.com/nut-tree/nut.js/issues/499)
- Feature: Add color queries to search for pixels of a certain color [(#500)](https://github.com/nut-tree/nut.js/issues/500)
- Bugfix: screen.highlight closes Electron window [(#505)](https://github.com/nut-tree/nut.js/issues/505)
## 3.1.1
- Bugfix: Fix mouse drift on Windows [(nut-tree/libnut-core#126)](https://github.com/nut-tree/libnut-core/issues/126)
+44 -52
View File
@@ -49,32 +49,30 @@ export class KeyboardClass {
*
* @param input Sequence of {@link String} or {@link Key} to type
*/
public type(...input: StringOrKey): Promise<KeyboardClass> {
return new Promise<KeyboardClass>(async (resolve, reject) => {
try {
if (inputIsString(input)) {
for (const char of input.join(" ")) {
await sleep(this.config.autoDelayMs);
await this.providerRegistry.getKeyboard().type(char);
this.providerRegistry.getLogProvider().debug(`Tapped ${char}`);
}
this.providerRegistry.getLogProvider().info(`Typed string ${input}`);
} else {
await this.providerRegistry.getKeyboard().click(...(input as Key[]));
const key = input[input.length - 1];
const modifiers = input.slice(0, -1);
const keyName = Key[key];
const modifierNames = modifiers.map((modifier) => Key[modifier]);
this.providerRegistry
.getLogProvider()
.info(`Tapped key ${keyName} with modifiers ${modifierNames}`);
public async type(...input: StringOrKey): Promise<KeyboardClass> {
try {
if (inputIsString(input)) {
for (const char of input.join(" ")) {
await sleep(this.config.autoDelayMs);
await this.providerRegistry.getKeyboard().type(char);
this.providerRegistry.getLogProvider().debug(`Tapped ${char}`);
}
resolve(this);
} catch (e) {
this.providerRegistry.getLogProvider().error(e as Error);
reject(e);
this.providerRegistry.getLogProvider().info(`Typed string ${input}`);
} else {
await this.providerRegistry.getKeyboard().click(...(input as Key[]));
const key = input[input.length - 1];
const modifiers = input.slice(0, -1);
const keyName = Key[key];
const modifierNames = modifiers.map((modifier) => Key[modifier]);
this.providerRegistry
.getLogProvider()
.info(`Tapped key ${keyName} with modifiers ${modifierNames}`);
}
});
return this;
} catch (e) {
this.providerRegistry.getLogProvider().error(e as Error);
throw e;
}
}
/**
@@ -88,19 +86,17 @@ export class KeyboardClass {
*
* @param keys Array of {@link Key}s to press and hold
*/
public pressKey(...keys: Key[]): Promise<KeyboardClass> {
return new Promise<KeyboardClass>(async (resolve, reject) => {
try {
await sleep(this.config.autoDelayMs);
await this.providerRegistry.getKeyboard().pressKey(...keys);
const keyNames = keys.map((key) => Key[key]);
this.providerRegistry.getLogProvider().info(`Pressed keys ${keyNames}`);
resolve(this);
} catch (e) {
this.providerRegistry.getLogProvider().error(e as Error);
reject(e);
}
});
public async pressKey(...keys: Key[]): Promise<KeyboardClass> {
try {
await sleep(this.config.autoDelayMs);
await this.providerRegistry.getKeyboard().pressKey(...keys);
const keyNames = keys.map((key) => Key[key]);
this.providerRegistry.getLogProvider().info(`Pressed keys ${keyNames}`);
return this;
} catch (e) {
this.providerRegistry.getLogProvider().error(e as Error);
throw e;
}
}
/**
@@ -114,20 +110,16 @@ export class KeyboardClass {
*
* @param keys Array of {@link Key}s to release
*/
public releaseKey(...keys: Key[]): Promise<KeyboardClass> {
return new Promise<KeyboardClass>(async (resolve, reject) => {
try {
await sleep(this.config.autoDelayMs);
await this.providerRegistry.getKeyboard().releaseKey(...keys);
const keyNames = keys.map((key) => Key[key]);
this.providerRegistry
.getLogProvider()
.info(`Released keys ${keyNames}`);
resolve(this);
} catch (e) {
this.providerRegistry.getLogProvider().error(e as Error);
reject(e);
}
});
public async releaseKey(...keys: Key[]): Promise<KeyboardClass> {
try {
await sleep(this.config.autoDelayMs);
await this.providerRegistry.getKeyboard().releaseKey(...keys);
const keyNames = keys.map((key) => Key[key]);
this.providerRegistry.getLogProvider().info(`Released keys ${keyNames}`);
return this;
} catch (e) {
this.providerRegistry.getLogProvider().error(e as Error);
throw e;
}
}
}
+136 -162
View File
@@ -55,15 +55,13 @@ export class MouseClass {
this.providerRegistry
.getLogProvider()
.trace("Setting mouse position", target);
return new Promise<MouseClass>(async (resolve, reject) => {
try {
await this.providerRegistry.getMouse().setMousePosition(target);
resolve(this);
} catch (e) {
this.providerRegistry.getLogProvider().error(e as Error);
reject(e);
}
});
try {
await this.providerRegistry.getMouse().setMousePosition(target);
return this;
} catch (e) {
this.providerRegistry.getLogProvider().error(e as Error);
throw e;
}
}
/**
@@ -88,34 +86,32 @@ export class MouseClass {
path: Point[] | Promise<Point[]>,
movementType: EasingFunction = linear
): Promise<MouseClass> {
return new Promise<MouseClass>(async (resolve, reject) => {
try {
let pathSteps = await path;
if (!Array.isArray(pathSteps)) {
pathSteps = [pathSteps];
}
this.providerRegistry
.getLogProvider()
.info(
`Moving mouse to target point ${pathSteps[pathSteps.length - 1]}`
);
const timeSteps = calculateMovementTimesteps(
pathSteps.length,
this.config.mouseSpeed,
movementType
);
for (let idx = 0; idx < pathSteps.length; ++idx) {
const node = pathSteps[idx];
const minTime = timeSteps[idx];
await busyWaitForNanoSeconds(minTime);
await this.setPosition(node);
}
resolve(this);
} catch (e) {
this.providerRegistry.getLogProvider().error(e as Error);
reject(e);
try {
let pathSteps = await path;
if (!Array.isArray(pathSteps)) {
pathSteps = [pathSteps];
}
});
this.providerRegistry
.getLogProvider()
.info(
`Moving mouse to target point ${pathSteps[pathSteps.length - 1]}`
);
const timeSteps = calculateMovementTimesteps(
pathSteps.length,
this.config.mouseSpeed,
movementType
);
for (let idx = 0; idx < pathSteps.length; ++idx) {
const node = pathSteps[idx];
const minTime = timeSteps[idx];
await busyWaitForNanoSeconds(minTime);
await this.setPosition(node);
}
return this;
} catch (e) {
this.providerRegistry.getLogProvider().error(e as Error);
throw e;
}
}
/**
@@ -138,19 +134,17 @@ export class MouseClass {
* @param amount The amount of "steps" to scroll
*/
public async scrollDown(amount: number): Promise<MouseClass> {
return new Promise<MouseClass>(async (resolve, reject) => {
try {
await sleep(this.config.autoDelayMs);
await this.providerRegistry.getMouse().scrollDown(amount);
this.providerRegistry
.getLogProvider()
.info(`Scrolled down ${amount} steps`);
resolve(this);
} catch (e) {
this.providerRegistry.getLogProvider().error(e as Error);
reject(e);
}
});
try {
await sleep(this.config.autoDelayMs);
await this.providerRegistry.getMouse().scrollDown(amount);
this.providerRegistry
.getLogProvider()
.info(`Scrolled down ${amount} steps`);
return this;
} catch (e) {
this.providerRegistry.getLogProvider().error(e as Error);
throw e;
}
}
/**
@@ -159,19 +153,17 @@ export class MouseClass {
* @param amount The amount of "steps" to scroll
*/
public async scrollUp(amount: number): Promise<MouseClass> {
return new Promise<MouseClass>(async (resolve, reject) => {
try {
await sleep(this.config.autoDelayMs);
await this.providerRegistry.getMouse().scrollUp(amount);
this.providerRegistry
.getLogProvider()
.info(`Scrolled up ${amount} steps`);
resolve(this);
} catch (e) {
this.providerRegistry.getLogProvider().error(e as Error);
reject(e);
}
});
try {
await sleep(this.config.autoDelayMs);
await this.providerRegistry.getMouse().scrollUp(amount);
this.providerRegistry
.getLogProvider()
.info(`Scrolled up ${amount} steps`);
return this;
} catch (e) {
this.providerRegistry.getLogProvider().error(e as Error);
throw e;
}
}
/**
@@ -180,19 +172,17 @@ export class MouseClass {
* @param amount The amount of "steps" to scroll
*/
public async scrollLeft(amount: number): Promise<MouseClass> {
return new Promise<MouseClass>(async (resolve, reject) => {
try {
await sleep(this.config.autoDelayMs);
await this.providerRegistry.getMouse().scrollLeft(amount);
this.providerRegistry
.getLogProvider()
.info(`Scrolled left ${amount} steps`);
resolve(this);
} catch (e) {
this.providerRegistry.getLogProvider().error(e as Error);
reject(e);
}
});
try {
await sleep(this.config.autoDelayMs);
await this.providerRegistry.getMouse().scrollLeft(amount);
this.providerRegistry
.getLogProvider()
.info(`Scrolled left ${amount} steps`);
return this;
} catch (e) {
this.providerRegistry.getLogProvider().error(e as Error);
throw e;
}
}
/**
@@ -201,19 +191,17 @@ export class MouseClass {
* @param amount The amount of "steps" to scroll
*/
public async scrollRight(amount: number): Promise<MouseClass> {
return new Promise<MouseClass>(async (resolve, reject) => {
try {
await sleep(this.config.autoDelayMs);
await this.providerRegistry.getMouse().scrollRight(amount);
this.providerRegistry
.getLogProvider()
.info(`Scrolled right ${amount} steps`);
resolve(this);
} catch (e) {
this.providerRegistry.getLogProvider().error(e as Error);
reject(e);
}
});
try {
await sleep(this.config.autoDelayMs);
await this.providerRegistry.getMouse().scrollRight(amount);
this.providerRegistry
.getLogProvider()
.info(`Scrolled right ${amount} steps`);
return this;
} catch (e) {
this.providerRegistry.getLogProvider().error(e as Error);
throw e;
}
}
/**
@@ -222,24 +210,18 @@ export class MouseClass {
* @param path The path of {@link Point}s to drag along
*/
public async drag(path: Point[] | Promise<Point[]>): Promise<MouseClass> {
return new Promise<MouseClass>(async (resolve, reject) => {
try {
await sleep(this.config.autoDelayMs);
await this.providerRegistry.getMouse().pressButton(Button.LEFT);
this.providerRegistry
.getLogProvider()
.info("Pressed left mouse button");
await this.move(path);
await this.providerRegistry.getMouse().releaseButton(Button.LEFT);
this.providerRegistry
.getLogProvider()
.info("Released left mouse button");
resolve(this);
} catch (e) {
this.providerRegistry.getLogProvider().error(e as Error);
reject(e);
}
});
try {
await sleep(this.config.autoDelayMs);
await this.providerRegistry.getMouse().pressButton(Button.LEFT);
this.providerRegistry.getLogProvider().info("Pressed left mouse button");
await this.move(path);
await this.providerRegistry.getMouse().releaseButton(Button.LEFT);
this.providerRegistry.getLogProvider().info("Released left mouse button");
return this;
} catch (e) {
this.providerRegistry.getLogProvider().error(e as Error);
throw e;
}
}
/**
@@ -247,20 +229,18 @@ export class MouseClass {
* @param btn The {@link Button} to press and hold
*/
public async pressButton(btn: Button): Promise<MouseClass> {
return new Promise<MouseClass>(async (resolve, reject) => {
try {
await sleep(this.config.autoDelayMs);
await this.providerRegistry.getMouse().pressButton(btn);
const btnName = Button[btn];
this.providerRegistry
.getLogProvider()
.info(`Pressed ${btnName} mouse button`);
resolve(this);
} catch (e) {
this.providerRegistry.getLogProvider().error(e as Error);
reject(e);
}
});
try {
await sleep(this.config.autoDelayMs);
await this.providerRegistry.getMouse().pressButton(btn);
const btnName = Button[btn];
this.providerRegistry
.getLogProvider()
.info(`Pressed ${btnName} mouse button`);
return this;
} catch (e) {
this.providerRegistry.getLogProvider().error(e as Error);
throw e;
}
}
/**
@@ -268,20 +248,18 @@ export class MouseClass {
* @param btn The {@link Button} to release
*/
public async releaseButton(btn: Button): Promise<MouseClass> {
return new Promise<MouseClass>(async (resolve, reject) => {
try {
await sleep(this.config.autoDelayMs);
await this.providerRegistry.getMouse().releaseButton(btn);
const btnName = Button[btn];
this.providerRegistry
.getLogProvider()
.info(`Pressed ${btnName} mouse button`);
resolve(this);
} catch (e) {
this.providerRegistry.getLogProvider().error(e as Error);
reject(e);
}
});
try {
await sleep(this.config.autoDelayMs);
await this.providerRegistry.getMouse().releaseButton(btn);
const btnName = Button[btn];
this.providerRegistry
.getLogProvider()
.info(`Pressed ${btnName} mouse button`);
return this;
} catch (e) {
this.providerRegistry.getLogProvider().error(e as Error);
throw e;
}
}
/**
@@ -289,20 +267,18 @@ export class MouseClass {
* @param btn The {@link Button} to click
*/
public async click(btn: Button): Promise<MouseClass> {
return new Promise<MouseClass>(async (resolve, reject) => {
try {
await sleep(this.config.autoDelayMs);
await this.providerRegistry.getMouse().click(btn);
const btnName = Button[btn];
this.providerRegistry
.getLogProvider()
.info(`Pressed ${btnName} mouse button`);
resolve(this);
} catch (e) {
this.providerRegistry.getLogProvider().error(e as Error);
reject(e);
}
});
try {
await sleep(this.config.autoDelayMs);
await this.providerRegistry.getMouse().click(btn);
const btnName = Button[btn];
this.providerRegistry
.getLogProvider()
.info(`Pressed ${btnName} mouse button`);
return this;
} catch (e) {
this.providerRegistry.getLogProvider().error(e as Error);
throw e;
}
}
/**
@@ -310,19 +286,17 @@ export class MouseClass {
* @param btn The {@link Button} to click
*/
public async doubleClick(btn: Button): Promise<MouseClass> {
return new Promise<MouseClass>(async (resolve, reject) => {
try {
await sleep(this.config.autoDelayMs);
await this.providerRegistry.getMouse().doubleClick(btn);
const btnName = Button[btn];
this.providerRegistry
.getLogProvider()
.info(`Pressed ${btnName} mouse button`);
resolve(this);
} catch (e) {
this.providerRegistry.getLogProvider().error(e as Error);
reject(e);
}
});
try {
await sleep(this.config.autoDelayMs);
await this.providerRegistry.getMouse().doubleClick(btn);
const btnName = Button[btn];
this.providerRegistry
.getLogProvider()
.info(`Pressed ${btnName} mouse button`);
return this;
} catch (e) {
this.providerRegistry.getLogProvider().error(e as Error);
throw e;
}
}
}
@@ -25,7 +25,7 @@ describe("JimpImageProcessor", () => {
const result = SUT.colorAt(inputImage, outOfBoundsPoint);
// THEN
await expect(result).rejects.toBe(
await expect(result).rejects.toThrowError(
`Query location out of bounds. Should be in range 0 <= x < image.width, is ${outOfBoundsPoint.x}`
);
}
@@ -52,7 +52,7 @@ describe("JimpImageProcessor", () => {
const result = SUT.colorAt(inputImage, outOfBoundsPoint);
// THEN
await expect(result).rejects.toBe(
await expect(result).rejects.toThrowError(
`Query location out of bounds. Should be in range 0 <= y < image.height, is ${outOfBoundsPoint.y}`
);
}
@@ -6,30 +6,26 @@ import { imageToJimp } from "../io/imageToJimp.function";
import { RGBA } from "../../rgba.class";
export default class implements ImageProcessor {
colorAt(
async colorAt(
image: Image | Promise<Image>,
point: Point | Promise<Point>
): Promise<RGBA> {
return new Promise<RGBA>(async (resolve, reject) => {
const location = await point;
const img = await image;
if (location.x < 0 || location.x >= img.width) {
reject(
`Query location out of bounds. Should be in range 0 <= x < image.width, is ${location.x}`
);
return;
}
if (location.y < 0 || location.y >= img.height) {
reject(
`Query location out of bounds. Should be in range 0 <= y < image.height, is ${location.y}`
);
return;
}
const jimpImage = imageToJimp(img);
const rgba = Jimp.intToRGBA(
jimpImage.getPixelColor(location.x, location.y)
const location = await point;
const img = await image;
if (location.x < 0 || location.x >= img.width) {
throw Error(
`Query location out of bounds. Should be in range 0 <= x < image.width, is ${location.x}`
);
resolve(new RGBA(rgba.r, rgba.g, rgba.b, rgba.a));
});
}
if (location.y < 0 || location.y >= img.height) {
throw Error(
`Query location out of bounds. Should be in range 0 <= y < image.height, is ${location.y}`
);
}
const jimpImage = imageToJimp(img);
const rgba = Jimp.intToRGBA(
jimpImage.getPixelColor(location.x, location.y)
);
return new RGBA(rgba.r, rgba.g, rgba.b, rgba.a);
}
}
@@ -22,7 +22,7 @@ jest.mock("jimp", () => {
afterEach(() => jest.resetAllMocks());
describe("Jimp image writer", () => {
it("should reject on writing failures", async () => {
it("should resolve on writing", async () => {
// GIVEN
const outputFileName = "/does/not/compute.png";
const outputFile = new Image(
@@ -48,4 +48,28 @@ describe("Jimp image writer", () => {
expect(writeMock).toHaveBeenCalledTimes(1);
expect(writeMock).toHaveBeenCalledWith(outputFileName);
});
it("should reject on writing failures", () => {
// GIVEN
const outputFileName = "/does/not/compute.png";
const outputFile = new Image(
100,
200,
Buffer.from([]),
3,
outputFileName,
4,
100 * 4
);
const writeMock = jest.fn(() => Promise.reject("write error"));
Jimp.prototype.scan = jest.fn();
Jimp.prototype.writeAsync = writeMock;
const SUT = new ImageWriter();
// WHEN
const result = SUT.store({ image: outputFile, path: outputFileName });
// THEN
expect(result).rejects.toBe("write error");
});
});
+45 -3
View File
@@ -11,6 +11,7 @@ import {
ImageFinderInterface,
ImageWriter,
ImageWriterParameters,
LogProviderInterface,
ScreenProviderInterface,
} from "./provider";
import { OptionalSearchParameters } from "./optionalsearchparameters.class";
@@ -25,8 +26,17 @@ import { Point } from "./point.class";
jest.mock("jimp", () => {});
const searchRegion = new Region(0, 0, 1000, 1000);
const loggingMock = mockPartial<LogProviderInterface>({
debug: jest.fn(),
info: jest.fn(),
warn: jest.fn(),
error: jest.fn(),
});
const providerRegistryMock = mockPartial<ProviderRegistry>({
getLogProvider(): LogProviderInterface {
return loggingMock;
},
getScreen(): ScreenProviderInterface {
return mockPartial<ScreenProviderInterface>({
grabScreenRegion(): Promise<Image> {
@@ -45,6 +55,12 @@ const providerRegistryMock = mockPartial<ProviderRegistry>({
screenSize(): Promise<Region> {
return Promise.resolve(searchRegion);
},
screenWidth(): Promise<number> {
return Promise.resolve(searchRegion.width);
},
screenHeight(): Promise<number> {
return Promise.resolve(searchRegion.height);
},
});
},
});
@@ -54,6 +70,32 @@ beforeEach(() => {
});
describe("Screen.", () => {
describe("dimensions", () => {
it("should return the screen width", async () => {
// GIVEN
const SUT = new ScreenClass(providerRegistryMock);
// WHEN
const width = await SUT.width();
// THEN
expect(width).toEqual(searchRegion.width);
expect(loggingMock.debug).toHaveBeenCalledTimes(1);
});
it("should return the screen height", async () => {
// GIVEN
const SUT = new ScreenClass(providerRegistryMock);
// WHEN
const height = await SUT.height();
// THEN
expect(height).toEqual(searchRegion.height);
expect(loggingMock.debug).toHaveBeenCalledTimes(1);
});
});
describe("find", () => {
describe("queries", () => {
it("should choose the correct finder implementation for images", async () => {
@@ -639,16 +681,16 @@ describe("Screen.", () => {
},
};
const findMatchMock = jest.fn(() => Promise.resolve(matchResult));
const findMatchMock = jest.fn(() => Promise.resolve([matchResult]));
providerRegistryMock.getColorFinder = jest.fn(() =>
mockPartial<ColorFinderInterface>({
findMatch: findMatchMock,
findMatches: findMatchMock,
})
);
providerRegistryMock.getLogProvider = () => new NoopLogProvider();
// WHEN
await SUT.find(needle);
await SUT.findAll(needle);
// THEN
expect(findMatchMock).toHaveBeenCalledTimes(1);
+3 -1
View File
@@ -425,7 +425,9 @@ export class ScreenClass {
.debug(`Autohighlight is enabled`);
resultRegions.forEach((region) => {
if (isRegion(region)) {
this.highlight(region);
this.highlight(region).catch((e) => {
this.providerRegistry.getLogProvider().error(e);
});
}
});
return resultRegions;
+52 -52
View File
@@ -1,12 +1,12 @@
{
"name": "@nut-tree/nut-js",
"version": "3.1.1",
"version": "3.1.2",
"lockfileVersion": 2,
"requires": true,
"packages": {
"": {
"name": "@nut-tree/nut-js",
"version": "3.1.1",
"version": "3.1.2",
"cpu": [
"x64",
"arm64"
@@ -18,9 +18,9 @@
"win32"
],
"dependencies": {
"@nut-tree/libnut": "2.5.1",
"@nut-tree/libnut": "2.5.2",
"clipboardy": "2.3.0",
"jimp": "0.16.2",
"jimp": "0.16.13",
"node-abort-controller": "2.0.0"
},
"devDependencies": {
@@ -1898,22 +1898,22 @@
}
},
"node_modules/@nut-tree/libnut": {
"version": "2.5.1",
"resolved": "https://registry.npmjs.org/@nut-tree/libnut/-/libnut-2.5.1.tgz",
"integrity": "sha512-W41FRAuA2fT7Y44+9A59NWzYhNA6Qibuvxgx9Sf5bQ5QrLIAyKGWjRpW/doUXaTAwUOvcqg7TC2w7jrn9nwkAA==",
"version": "2.5.2",
"resolved": "https://registry.npmjs.org/@nut-tree/libnut/-/libnut-2.5.2.tgz",
"integrity": "sha512-IwlGgalGQjjCrbPq52HTLtsR6MRsGJ6c4GhgHmgwJPD/yBVCzsU5EA2rwDgjKSgK+jiLOpykySDZQ+owhyd1zw==",
"dependencies": {
"@nut-tree/libnut-darwin": "2.5.1",
"@nut-tree/libnut-linux": "2.5.1",
"@nut-tree/libnut-win32": "2.5.1"
"@nut-tree/libnut-darwin": "2.5.2",
"@nut-tree/libnut-linux": "2.5.2",
"@nut-tree/libnut-win32": "2.5.2"
},
"engines": {
"node": ">=10.15.3"
}
},
"node_modules/@nut-tree/libnut-darwin": {
"version": "2.5.1",
"resolved": "https://registry.npmjs.org/@nut-tree/libnut-darwin/-/libnut-darwin-2.5.1.tgz",
"integrity": "sha512-JIr5Plmm9n5aoOAmwjghCtbmOY4FzOTypRN/mlb5N+68aX+w5RpgOV2HXmcQPbtqYTTOoSEGRBdzK8M36KHRsw==",
"version": "2.5.2",
"resolved": "https://registry.npmjs.org/@nut-tree/libnut-darwin/-/libnut-darwin-2.5.2.tgz",
"integrity": "sha512-OKqCgpBbZj2oNQkLM+mM7TyiLBAQsRyN7Q5UXVKbyXnzcQTU1FZBJ1mLGvdfzzspajznL3Mkl08AQE+xYYbTMw==",
"cpu": [
"x64",
"arm64"
@@ -1934,9 +1934,9 @@
}
},
"node_modules/@nut-tree/libnut-linux": {
"version": "2.5.1",
"resolved": "https://registry.npmjs.org/@nut-tree/libnut-linux/-/libnut-linux-2.5.1.tgz",
"integrity": "sha512-2rXZsOpx5U6cJE1zGfrDa6fGaAr1cQFJInsmpV55vg93/k0X5RY6iXLNbBXot/NBJKrTcQRIHeKpffLRk8fKPg==",
"version": "2.5.2",
"resolved": "https://registry.npmjs.org/@nut-tree/libnut-linux/-/libnut-linux-2.5.2.tgz",
"integrity": "sha512-uY6XDuNE8soYRUhV23g6KQN5BRR43MYNLyPnrrQa5Wtfgm6oW9kBRu6JtkWz6Fn6trAWrVAKnbPoTiEgHuGz9w==",
"cpu": [
"x64",
"arm64"
@@ -1957,9 +1957,9 @@
}
},
"node_modules/@nut-tree/libnut-win32": {
"version": "2.5.1",
"resolved": "https://registry.npmjs.org/@nut-tree/libnut-win32/-/libnut-win32-2.5.1.tgz",
"integrity": "sha512-Y95nMNM6WeioPrfzsGjvzUxtIQGYXfooFjSEUaGOA3pxP6bQlmfhVPYZrxwYtFr7mDoxHE9/PrDg1qiYtYhZkw==",
"version": "2.5.2",
"resolved": "https://registry.npmjs.org/@nut-tree/libnut-win32/-/libnut-win32-2.5.2.tgz",
"integrity": "sha512-cnNAQ0pzUMH7hrSjTWRiFfXid3sbSZ78jpv1rA154dlka3wqo6m1OtaX4PLVQK4irZl5REz74iPdHcjeTy9rtg==",
"cpu": [
"x64",
"arm64"
@@ -5783,14 +5783,14 @@
}
},
"node_modules/jimp": {
"version": "0.16.2",
"resolved": "https://registry.npmjs.org/jimp/-/jimp-0.16.2.tgz",
"integrity": "sha512-UpItBk81a92f8oEyoGYbO3YK4QcM0hoIyuGHmShoF9Ov63P5Qo7Q/X2xsAgnODmSuDJFOtrPtJd5GSWW4LKdOQ==",
"version": "0.16.13",
"resolved": "https://registry.npmjs.org/jimp/-/jimp-0.16.13.tgz",
"integrity": "sha512-Bxz8q7V4rnCky9A0ktTNGA9SkNFVWRHodddI/DaAWZJzF7sVUlFYKQ60y9JGqrKpi48ECA/TnfMzzc5C70VByA==",
"dependencies": {
"@babel/runtime": "^7.7.2",
"@jimp/custom": "^0.16.2",
"@jimp/plugins": "^0.16.2",
"@jimp/types": "^0.16.2",
"@jimp/custom": "^0.16.13",
"@jimp/plugins": "^0.16.13",
"@jimp/types": "^0.16.13",
"regenerator-runtime": "^0.13.3"
}
},
@@ -8660,9 +8660,9 @@
"dev": true
},
"node_modules/yaml": {
"version": "2.1.3",
"resolved": "https://registry.npmjs.org/yaml/-/yaml-2.1.3.tgz",
"integrity": "sha512-AacA8nRULjKMX2DvWvOAdBZMOfQlypSFkjcOcu9FalllIDJ1kvlREzcdIZmidQUqqeMv7jorHjq2HlLv/+c2lg==",
"version": "2.3.1",
"resolved": "https://registry.npmjs.org/yaml/-/yaml-2.3.1.tgz",
"integrity": "sha512-2eHWfjaoXgTBC2jNM1LRef62VQa0umtvRiDSk6HSzW7RvS5YtkabJrwYLLEKWBc8a5U2PTSCs+dJjUTJdlHsWQ==",
"dev": true,
"engines": {
"node": ">= 14"
@@ -10197,37 +10197,37 @@
}
},
"@nut-tree/libnut": {
"version": "2.5.1",
"resolved": "https://registry.npmjs.org/@nut-tree/libnut/-/libnut-2.5.1.tgz",
"integrity": "sha512-W41FRAuA2fT7Y44+9A59NWzYhNA6Qibuvxgx9Sf5bQ5QrLIAyKGWjRpW/doUXaTAwUOvcqg7TC2w7jrn9nwkAA==",
"version": "2.5.2",
"resolved": "https://registry.npmjs.org/@nut-tree/libnut/-/libnut-2.5.2.tgz",
"integrity": "sha512-IwlGgalGQjjCrbPq52HTLtsR6MRsGJ6c4GhgHmgwJPD/yBVCzsU5EA2rwDgjKSgK+jiLOpykySDZQ+owhyd1zw==",
"requires": {
"@nut-tree/libnut-darwin": "2.5.1",
"@nut-tree/libnut-linux": "2.5.1",
"@nut-tree/libnut-win32": "2.5.1"
"@nut-tree/libnut-darwin": "2.5.2",
"@nut-tree/libnut-linux": "2.5.2",
"@nut-tree/libnut-win32": "2.5.2"
}
},
"@nut-tree/libnut-darwin": {
"version": "2.5.1",
"resolved": "https://registry.npmjs.org/@nut-tree/libnut-darwin/-/libnut-darwin-2.5.1.tgz",
"integrity": "sha512-JIr5Plmm9n5aoOAmwjghCtbmOY4FzOTypRN/mlb5N+68aX+w5RpgOV2HXmcQPbtqYTTOoSEGRBdzK8M36KHRsw==",
"version": "2.5.2",
"resolved": "https://registry.npmjs.org/@nut-tree/libnut-darwin/-/libnut-darwin-2.5.2.tgz",
"integrity": "sha512-OKqCgpBbZj2oNQkLM+mM7TyiLBAQsRyN7Q5UXVKbyXnzcQTU1FZBJ1mLGvdfzzspajznL3Mkl08AQE+xYYbTMw==",
"requires": {
"@nut-tree/node-mac-permissions": "2.2.1",
"bindings": "1.5.0"
}
},
"@nut-tree/libnut-linux": {
"version": "2.5.1",
"resolved": "https://registry.npmjs.org/@nut-tree/libnut-linux/-/libnut-linux-2.5.1.tgz",
"integrity": "sha512-2rXZsOpx5U6cJE1zGfrDa6fGaAr1cQFJInsmpV55vg93/k0X5RY6iXLNbBXot/NBJKrTcQRIHeKpffLRk8fKPg==",
"version": "2.5.2",
"resolved": "https://registry.npmjs.org/@nut-tree/libnut-linux/-/libnut-linux-2.5.2.tgz",
"integrity": "sha512-uY6XDuNE8soYRUhV23g6KQN5BRR43MYNLyPnrrQa5Wtfgm6oW9kBRu6JtkWz6Fn6trAWrVAKnbPoTiEgHuGz9w==",
"requires": {
"@nut-tree/node-mac-permissions": "2.2.1",
"bindings": "1.5.0"
}
},
"@nut-tree/libnut-win32": {
"version": "2.5.1",
"resolved": "https://registry.npmjs.org/@nut-tree/libnut-win32/-/libnut-win32-2.5.1.tgz",
"integrity": "sha512-Y95nMNM6WeioPrfzsGjvzUxtIQGYXfooFjSEUaGOA3pxP6bQlmfhVPYZrxwYtFr7mDoxHE9/PrDg1qiYtYhZkw==",
"version": "2.5.2",
"resolved": "https://registry.npmjs.org/@nut-tree/libnut-win32/-/libnut-win32-2.5.2.tgz",
"integrity": "sha512-cnNAQ0pzUMH7hrSjTWRiFfXid3sbSZ78jpv1rA154dlka3wqo6m1OtaX4PLVQK4irZl5REz74iPdHcjeTy9rtg==",
"requires": {
"@nut-tree/node-mac-permissions": "2.2.1",
"bindings": "1.5.0"
@@ -13142,14 +13142,14 @@
}
},
"jimp": {
"version": "0.16.2",
"resolved": "https://registry.npmjs.org/jimp/-/jimp-0.16.2.tgz",
"integrity": "sha512-UpItBk81a92f8oEyoGYbO3YK4QcM0hoIyuGHmShoF9Ov63P5Qo7Q/X2xsAgnODmSuDJFOtrPtJd5GSWW4LKdOQ==",
"version": "0.16.13",
"resolved": "https://registry.npmjs.org/jimp/-/jimp-0.16.13.tgz",
"integrity": "sha512-Bxz8q7V4rnCky9A0ktTNGA9SkNFVWRHodddI/DaAWZJzF7sVUlFYKQ60y9JGqrKpi48ECA/TnfMzzc5C70VByA==",
"requires": {
"@babel/runtime": "^7.7.2",
"@jimp/custom": "^0.16.2",
"@jimp/plugins": "^0.16.2",
"@jimp/types": "^0.16.2",
"@jimp/custom": "^0.16.13",
"@jimp/plugins": "^0.16.13",
"@jimp/types": "^0.16.13",
"regenerator-runtime": "^0.13.3"
}
},
@@ -15275,9 +15275,9 @@
"dev": true
},
"yaml": {
"version": "2.1.3",
"resolved": "https://registry.npmjs.org/yaml/-/yaml-2.1.3.tgz",
"integrity": "sha512-AacA8nRULjKMX2DvWvOAdBZMOfQlypSFkjcOcu9FalllIDJ1kvlREzcdIZmidQUqqeMv7jorHjq2HlLv/+c2lg==",
"version": "2.3.1",
"resolved": "https://registry.npmjs.org/yaml/-/yaml-2.3.1.tgz",
"integrity": "sha512-2eHWfjaoXgTBC2jNM1LRef62VQa0umtvRiDSk6HSzW7RvS5YtkabJrwYLLEKWBc8a5U2PTSCs+dJjUTJdlHsWQ==",
"dev": true
},
"yargs": {
+3 -3
View File
@@ -1,6 +1,6 @@
{
"name": "@nut-tree/nut-js",
"version": "3.1.1",
"version": "3.1.2",
"license": "Apache-2.0",
"main": "dist/index",
"typings": "dist/index",
@@ -62,9 +62,9 @@
"prepare": "husky install"
},
"dependencies": {
"@nut-tree/libnut": "2.5.1",
"@nut-tree/libnut": "2.5.2",
"clipboardy": "2.3.0",
"jimp": "0.16.2",
"jimp": "0.16.13",
"node-abort-controller": "2.0.0"
},
"devDependencies": {