From 42366c573d25063ffac97eb5d7034c2d43fb3f8e Mon Sep 17 00:00:00 2001 From: Raz Luvaton <16746759+rluvaton@users.noreply.github.com> Date: Sun, 21 Apr 2024 00:08:39 +0300 Subject: [PATCH 1/5] find node version in path --- package-lock.json | 83 ++++++++++++++++++++++++++++++++++++++--------- package.json | 2 ++ src/extension.ts | 17 +++++++--- src/find-node.ts | 54 ++++++++++++++++++++++++++++++ 4 files changed, 135 insertions(+), 21 deletions(-) create mode 100644 src/find-node.ts diff --git a/package-lock.json b/package-lock.json index 7ab0a4d..e233157 100644 --- a/package-lock.json +++ b/package-lock.json @@ -24,6 +24,7 @@ "pretty-format": "^29.7.0", "split2": "^4.2.0", "stacktrace-parser": "^0.1.10", + "which": "^4.0.0", "ws": "^8.16.0" }, "devDependencies": { @@ -37,6 +38,7 @@ "@types/sinon": "^17.0.3", "@types/split2": "^4.2.3", "@types/vscode": "^1.86.0", + "@types/which": "^3.0.3", "@types/ws": "^8.5.10", "@vscode/test-electron": "^2.3.9", "acorn": "^8.11.3", @@ -1059,6 +1061,12 @@ "integrity": "sha512-DnIXf2ftWv+9LWOB5OJeIeaLigLHF7fdXF6atfc7X5g2w/wVZBgk0amP7b+ub5xAuW1q7qP5YcFvOcit/DtyCQ==", "dev": true }, + "node_modules/@types/which": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/@types/which/-/which-3.0.3.tgz", + "integrity": "sha512-2C1+XoY0huExTbs8MQv1DuS5FS86+SEjdM9F/+GS61gg5Hqbtj8ZiDSx8MfWcyei907fIPbfPGCOrNUTnVHY1g==", + "dev": true + }, "node_modules/@types/ws": { "version": "8.5.10", "resolved": "https://registry.npmjs.org/@types/ws/-/ws-8.5.10.tgz", @@ -1557,6 +1565,25 @@ "node": ">= 8" } }, + "node_modules/cross-spawn/node_modules/isexe": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", + "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==" + }, + "node_modules/cross-spawn/node_modules/which": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", + "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", + "dependencies": { + "isexe": "^2.0.0" + }, + "bin": { + "node-which": "bin/node-which" + }, + "engines": { + "node": ">= 8" + } + }, "node_modules/data-uri-to-buffer": { "version": "6.0.2", "resolved": "https://registry.npmjs.org/data-uri-to-buffer/-/data-uri-to-buffer-6.0.2.tgz", @@ -2055,9 +2082,12 @@ "dev": true }, "node_modules/isexe": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", - "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==" + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-3.1.1.tgz", + "integrity": "sha512-LpB/54B+/2J5hqQ7imZHfdU31OlgQqx7ZicVlkm9kzg9/w8GKLEcFfJl/t7DCEDueOyBAD6zCCwTO6Fzs0NoEQ==", + "engines": { + "node": ">=16" + } }, "node_modules/istanbul-lib-coverage": { "version": "3.2.2", @@ -4291,17 +4321,17 @@ } }, "node_modules/which": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", - "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/which/-/which-4.0.0.tgz", + "integrity": "sha512-GlaYyEb07DPxYCKhKzplCWBJtvxZcZMrL+4UkrTSJHHPyZU4mYYTv3qaOe77H7EODLSSopAUFAc6W8U4yqvscg==", "dependencies": { - "isexe": "^2.0.0" + "isexe": "^3.1.1" }, "bin": { - "node-which": "bin/node-which" + "node-which": "bin/which.js" }, "engines": { - "node": ">= 8" + "node": "^16.13.0 || >=18.0.0" } }, "node_modules/why-is-node-running": { @@ -5126,6 +5156,12 @@ "integrity": "sha512-DnIXf2ftWv+9LWOB5OJeIeaLigLHF7fdXF6atfc7X5g2w/wVZBgk0amP7b+ub5xAuW1q7qP5YcFvOcit/DtyCQ==", "dev": true }, + "@types/which": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/@types/which/-/which-3.0.3.tgz", + "integrity": "sha512-2C1+XoY0huExTbs8MQv1DuS5FS86+SEjdM9F/+GS61gg5Hqbtj8ZiDSx8MfWcyei907fIPbfPGCOrNUTnVHY1g==", + "dev": true + }, "@types/ws": { "version": "8.5.10", "resolved": "https://registry.npmjs.org/@types/ws/-/ws-8.5.10.tgz", @@ -5496,6 +5532,21 @@ "path-key": "^3.1.0", "shebang-command": "^2.0.0", "which": "^2.0.1" + }, + "dependencies": { + "isexe": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", + "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==" + }, + "which": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", + "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", + "requires": { + "isexe": "^2.0.0" + } + } } }, "data-uri-to-buffer": { @@ -5842,9 +5893,9 @@ "dev": true }, "isexe": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", - "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==" + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-3.1.1.tgz", + "integrity": "sha512-LpB/54B+/2J5hqQ7imZHfdU31OlgQqx7ZicVlkm9kzg9/w8GKLEcFfJl/t7DCEDueOyBAD6zCCwTO6Fzs0NoEQ==" }, "istanbul-lib-coverage": { "version": "3.2.2", @@ -7222,11 +7273,11 @@ } }, "which": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", - "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/which/-/which-4.0.0.tgz", + "integrity": "sha512-GlaYyEb07DPxYCKhKzplCWBJtvxZcZMrL+4UkrTSJHHPyZU4mYYTv3qaOe77H7EODLSSopAUFAc6W8U4yqvscg==", "requires": { - "isexe": "^2.0.0" + "isexe": "^3.1.1" } }, "why-is-node-running": { diff --git a/package.json b/package.json index 0d42e4a..e764a7e 100644 --- a/package.json +++ b/package.json @@ -195,6 +195,7 @@ "@types/sinon": "^17.0.3", "@types/split2": "^4.2.3", "@types/vscode": "^1.86.0", + "@types/which": "^3.0.3", "@types/ws": "^8.5.10", "@vscode/test-electron": "^2.3.9", "acorn": "^8.11.3", @@ -228,6 +229,7 @@ "pretty-format": "^29.7.0", "split2": "^4.2.0", "stacktrace-parser": "^0.1.10", + "which": "^4.0.0", "ws": "^8.16.0" } } diff --git a/src/extension.ts b/src/extension.ts index a2a7f28..e493a64 100644 --- a/src/extension.ts +++ b/src/extension.ts @@ -5,6 +5,7 @@ import { Pretest } from "./pretest"; import { TestRunner } from "./runner"; import { SourceMapStore } from "./source-map-store"; import { Style } from "./styles"; +import { findNode } from "./find-node"; export async function activate(context: vscode.ExtensionContext) { const smStore = new SourceMapStore(); @@ -18,15 +19,15 @@ export async function activate(context: vscode.ExtensionContext) { ]); const ctrls = new Map(); - const refreshFolders = () => { + const refreshFolders = async () => { for (const ctrl of ctrls.values()) { ctrl.dispose(); } ctrls.clear(); - syncWorkspaceFolders(); + await syncWorkspaceFolders(); }; - const syncWorkspaceFolders = () => { + const syncWorkspaceFolders = async () => { if (!extensions.value?.length) { const msg = "nodejs-testing.extensions array is empty. Please remove the setting 'nodejs-testing.extensions' or define at least one element."; @@ -36,10 +37,16 @@ export async function activate(context: vscode.ExtensionContext) { const folders = vscode.workspace.workspaceFolders ?? []; for (const folder of folders) { if (!ctrls.has(folder)) { + + const nodeJsPath = await findNode(folder.uri.fsPath).catch((e) => { + vscode.window.showErrorMessage('nodejs-testing failed to find node path: ' + e.message); + return 'node'; + }); + const runner = new TestRunner( smStore, new ConfigValue("concurrency", 0, folder), - new ConfigValue("nodejsPath", "node", folder), + new ConfigValue("nodejsPath", nodeJsPath || 'node', folder), new ConfigValue("verbose", false, folder), new ConfigValue("style", Style.Spec, folder), context.extensionUri.fsPath, @@ -110,7 +117,7 @@ export async function activate(context: vscode.ExtensionContext) { new vscode.Disposable(() => ctrls.forEach((c) => c.dispose())), ); - syncWorkspaceFolders(); + await syncWorkspaceFolders(); for (const editor of vscode.window.visibleTextEditors) { syncTextDocument(editor.document); } diff --git a/src/find-node.ts b/src/find-node.ts new file mode 100644 index 0000000..03c40b6 --- /dev/null +++ b/src/find-node.ts @@ -0,0 +1,54 @@ +import { spawn } from 'node:child_process' +import * as vscode from 'vscode' +import which from 'which' + +export function noop() { } + +const cwdToNodeJs = new Map(); + +// based on https://github.com/microsoft/playwright-vscode/blob/main/src/utils.ts#L144 +export async function findNode(cwd: string): Promise { + if (cwdToNodeJs.has(cwd)) + return cwdToNodeJs.get(cwd)! + + // Stage 1: Try to find Node.js via process.env.PATH + let node = await which('node').catch(() => undefined) + // Stage 2: When extension host boots, it does not have the right env set, so we might need to wait. + for (let i = 0; i < 5 && !node; ++i) { + await new Promise(f => setTimeout(f, 200)) + node = await which('node').catch(() => undefined) + } + // Stage 3: If we still haven't found Node.js, try to find it via a subprocess. + // This evaluates shell rc/profile files and makes nvm work. + node ??= await findNodeViaShell(cwd) + if (!node) + throw new Error(`Unable to find 'node' executable.\nMake sure to have Node.js installed and available in your PATH.\nCurrent PATH: '${process.env.PATH}'.`) + cwdToNodeJs.set(cwd, node); + return node +} + +async function findNodeViaShell(cwd: string): Promise { + if (process.platform === 'win32') + return undefined + return new Promise((resolve) => { + const startToken = '___START_SHELL__' + const endToken = '___END_SHELL__' + const childProcess = spawn(`${vscode.env.shell} -i -c 'echo ${startToken} && which node && echo ${endToken}'`, { + stdio: 'pipe', + shell: true, + cwd, + }) + let output = '' + childProcess.stdout.on('data', data => output += data.toString()) + childProcess.on('error', () => resolve(undefined)) + childProcess.on('exit', (exitCode) => { + if (exitCode !== 0) + return resolve(undefined) + const start = output.indexOf(startToken) + const end = output.indexOf(endToken) + if (start === -1 || end === -1) + return resolve(undefined) + return resolve(output.substring(start + startToken.length, end).trim()) + }) + }) +} \ No newline at end of file From 340592b1a0f978c2d378aa9ac3d8b3ff6f20d5fa Mon Sep 17 00:00:00 2001 From: Raz Luvaton <16746759+rluvaton@users.noreply.github.com> Date: Sun, 21 Apr 2024 00:27:30 +0300 Subject: [PATCH 2/5] change default value of nodejs path to null to pick the code default value --- package.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/package.json b/package.json index e764a7e..acb5f97 100644 --- a/package.json +++ b/package.json @@ -27,8 +27,8 @@ "properties": { "nodejs-testing.nodejsPath": { "type": "string", - "default": "node", - "description": "Path to the Node.js binary used to run tests" + "default": null, + "description": "Path to the Node.js binary used to run tests (default is the one on the PATH in the workspace directory)." }, "nodejs-testing.nodejsParameters": { "type": "array", From 0e594d621774a01822c76800a4cef2f6501c7981 Mon Sep 17 00:00:00 2001 From: Raz Luvaton <16746759+rluvaton@users.noreply.github.com> Date: Sun, 21 Apr 2024 00:28:15 +0300 Subject: [PATCH 3/5] add empty line --- src/find-node.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/find-node.ts b/src/find-node.ts index 03c40b6..58127e0 100644 --- a/src/find-node.ts +++ b/src/find-node.ts @@ -51,4 +51,4 @@ async function findNodeViaShell(cwd: string): Promise { return resolve(output.substring(start + startToken.length, end).trim()) }) }) -} \ No newline at end of file +} From ddd72cabee3f97a7477157773628f133c34a315c Mon Sep 17 00:00:00 2001 From: Raz Luvaton <16746759+rluvaton@users.noreply.github.com> Date: Sun, 21 Apr 2024 00:31:20 +0300 Subject: [PATCH 4/5] cleanup --- src/extension.ts | 4 ++-- src/find-node.ts | 58 ++++++++++++++++++++++++------------------------ 2 files changed, 31 insertions(+), 31 deletions(-) diff --git a/src/extension.ts b/src/extension.ts index e493a64..9caf71f 100644 --- a/src/extension.ts +++ b/src/extension.ts @@ -39,14 +39,14 @@ export async function activate(context: vscode.ExtensionContext) { if (!ctrls.has(folder)) { const nodeJsPath = await findNode(folder.uri.fsPath).catch((e) => { - vscode.window.showErrorMessage('nodejs-testing failed to find node path: ' + e.message); + vscode.window.showErrorMessage("nodejs-testing failed to find node path: " + e.message); return 'node'; }); const runner = new TestRunner( smStore, new ConfigValue("concurrency", 0, folder), - new ConfigValue("nodejsPath", nodeJsPath || 'node', folder), + new ConfigValue("nodejsPath", nodeJsPath || "node", folder), new ConfigValue("verbose", false, folder), new ConfigValue("style", Style.Spec, folder), context.extensionUri.fsPath, diff --git a/src/find-node.ts b/src/find-node.ts index 58127e0..c24a527 100644 --- a/src/find-node.ts +++ b/src/find-node.ts @@ -1,54 +1,54 @@ -import { spawn } from 'node:child_process' -import * as vscode from 'vscode' -import which from 'which' - -export function noop() { } +import { spawn } from "node:child_process"; +import * as vscode from "vscode"; +import which from "which"; const cwdToNodeJs = new Map(); // based on https://github.com/microsoft/playwright-vscode/blob/main/src/utils.ts#L144 export async function findNode(cwd: string): Promise { if (cwdToNodeJs.has(cwd)) - return cwdToNodeJs.get(cwd)! + return cwdToNodeJs.get(cwd)!; // Stage 1: Try to find Node.js via process.env.PATH - let node = await which('node').catch(() => undefined) + let node = await which("node").catch(() => undefined); // Stage 2: When extension host boots, it does not have the right env set, so we might need to wait. for (let i = 0; i < 5 && !node; ++i) { - await new Promise(f => setTimeout(f, 200)) - node = await which('node').catch(() => undefined) + await new Promise(f => setTimeout(f, 200)); + node = await which("node").catch(() => undefined); } // Stage 3: If we still haven't found Node.js, try to find it via a subprocess. // This evaluates shell rc/profile files and makes nvm work. - node ??= await findNodeViaShell(cwd) + node ??= await findNodeViaShell(cwd); if (!node) - throw new Error(`Unable to find 'node' executable.\nMake sure to have Node.js installed and available in your PATH.\nCurrent PATH: '${process.env.PATH}'.`) + throw new Error(`Unable to find 'node' executable.\nMake sure to have Node.js installed and available in your PATH.\nCurrent PATH: '${process.env.PATH}'.`); + cwdToNodeJs.set(cwd, node); - return node + return node; } async function findNodeViaShell(cwd: string): Promise { - if (process.platform === 'win32') - return undefined + if (process.platform === "win32") + return undefined; + return new Promise((resolve) => { - const startToken = '___START_SHELL__' - const endToken = '___END_SHELL__' + const startToken = "___START_SHELL__"; + const endToken = "___END_SHELL__"; const childProcess = spawn(`${vscode.env.shell} -i -c 'echo ${startToken} && which node && echo ${endToken}'`, { - stdio: 'pipe', + stdio: "pipe", shell: true, cwd, - }) - let output = '' - childProcess.stdout.on('data', data => output += data.toString()) - childProcess.on('error', () => resolve(undefined)) - childProcess.on('exit', (exitCode) => { + }); + let output = ''; + childProcess.stdout.on("data", data => output += data.toString()); + childProcess.on("error", () => resolve(undefined)); + childProcess.on("exit", (exitCode) => { if (exitCode !== 0) - return resolve(undefined) - const start = output.indexOf(startToken) - const end = output.indexOf(endToken) + return resolve(undefined); + const start = output.indexOf(startToken); + const end = output.indexOf(endToken); if (start === -1 || end === -1) - return resolve(undefined) - return resolve(output.substring(start + startToken.length, end).trim()) - }) - }) + return resolve(undefined); + return resolve(output.substring(start + startToken.length, end).trim()); + }); + }); } From 1b1a0013403e53b74c2c59b019ec29fb182b3d59 Mon Sep 17 00:00:00 2001 From: Raz Luvaton <16746759+rluvaton@users.noreply.github.com> Date: Tue, 30 Apr 2024 14:16:25 +0300 Subject: [PATCH 5/5] align package lock --- package-lock.json | 83 ++++++++++++++++++++++++++++++++++++++--------- 1 file changed, 67 insertions(+), 16 deletions(-) diff --git a/package-lock.json b/package-lock.json index 3a5c44a..841fef0 100644 --- a/package-lock.json +++ b/package-lock.json @@ -24,6 +24,7 @@ "pretty-format": "^29.7.0", "split2": "^4.2.0", "stacktrace-parser": "^0.1.10", + "which": "^4.0.0", "ws": "^8.16.0" }, "devDependencies": { @@ -37,6 +38,7 @@ "@types/sinon": "^17.0.3", "@types/split2": "^4.2.3", "@types/vscode": "^1.88.0", + "@types/which": "^3.0.3", "@types/ws": "^8.5.10", "@vscode/test-electron": "^2.3.9", "acorn": "^8.11.3", @@ -1059,6 +1061,12 @@ "integrity": "sha512-rWY+Bs6j/f1lvr8jqZTyp5arRMfovdxolcqGi+//+cPDOh8SBvzXH90e7BiSXct5HJ9HGW6jATchbRTpTJpEkw==", "dev": true }, + "node_modules/@types/which": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/@types/which/-/which-3.0.3.tgz", + "integrity": "sha512-2C1+XoY0huExTbs8MQv1DuS5FS86+SEjdM9F/+GS61gg5Hqbtj8ZiDSx8MfWcyei907fIPbfPGCOrNUTnVHY1g==", + "dev": true + }, "node_modules/@types/ws": { "version": "8.5.10", "resolved": "https://registry.npmjs.org/@types/ws/-/ws-8.5.10.tgz", @@ -1557,6 +1565,25 @@ "node": ">= 8" } }, + "node_modules/cross-spawn/node_modules/isexe": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", + "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==" + }, + "node_modules/cross-spawn/node_modules/which": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", + "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", + "dependencies": { + "isexe": "^2.0.0" + }, + "bin": { + "node-which": "bin/node-which" + }, + "engines": { + "node": ">= 8" + } + }, "node_modules/data-uri-to-buffer": { "version": "6.0.2", "resolved": "https://registry.npmjs.org/data-uri-to-buffer/-/data-uri-to-buffer-6.0.2.tgz", @@ -2055,9 +2082,12 @@ "dev": true }, "node_modules/isexe": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", - "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==" + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-3.1.1.tgz", + "integrity": "sha512-LpB/54B+/2J5hqQ7imZHfdU31OlgQqx7ZicVlkm9kzg9/w8GKLEcFfJl/t7DCEDueOyBAD6zCCwTO6Fzs0NoEQ==", + "engines": { + "node": ">=16" + } }, "node_modules/istanbul-lib-coverage": { "version": "3.2.2", @@ -4291,17 +4321,17 @@ } }, "node_modules/which": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", - "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/which/-/which-4.0.0.tgz", + "integrity": "sha512-GlaYyEb07DPxYCKhKzplCWBJtvxZcZMrL+4UkrTSJHHPyZU4mYYTv3qaOe77H7EODLSSopAUFAc6W8U4yqvscg==", "dependencies": { - "isexe": "^2.0.0" + "isexe": "^3.1.1" }, "bin": { - "node-which": "bin/node-which" + "node-which": "bin/which.js" }, "engines": { - "node": ">= 8" + "node": "^16.13.0 || >=18.0.0" } }, "node_modules/why-is-node-running": { @@ -5126,6 +5156,12 @@ "integrity": "sha512-rWY+Bs6j/f1lvr8jqZTyp5arRMfovdxolcqGi+//+cPDOh8SBvzXH90e7BiSXct5HJ9HGW6jATchbRTpTJpEkw==", "dev": true }, + "@types/which": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/@types/which/-/which-3.0.3.tgz", + "integrity": "sha512-2C1+XoY0huExTbs8MQv1DuS5FS86+SEjdM9F/+GS61gg5Hqbtj8ZiDSx8MfWcyei907fIPbfPGCOrNUTnVHY1g==", + "dev": true + }, "@types/ws": { "version": "8.5.10", "resolved": "https://registry.npmjs.org/@types/ws/-/ws-8.5.10.tgz", @@ -5496,6 +5532,21 @@ "path-key": "^3.1.0", "shebang-command": "^2.0.0", "which": "^2.0.1" + }, + "dependencies": { + "isexe": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", + "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==" + }, + "which": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", + "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", + "requires": { + "isexe": "^2.0.0" + } + } } }, "data-uri-to-buffer": { @@ -5842,9 +5893,9 @@ "dev": true }, "isexe": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", - "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==" + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-3.1.1.tgz", + "integrity": "sha512-LpB/54B+/2J5hqQ7imZHfdU31OlgQqx7ZicVlkm9kzg9/w8GKLEcFfJl/t7DCEDueOyBAD6zCCwTO6Fzs0NoEQ==" }, "istanbul-lib-coverage": { "version": "3.2.2", @@ -7222,11 +7273,11 @@ } }, "which": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", - "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/which/-/which-4.0.0.tgz", + "integrity": "sha512-GlaYyEb07DPxYCKhKzplCWBJtvxZcZMrL+4UkrTSJHHPyZU4mYYTv3qaOe77H7EODLSSopAUFAc6W8U4yqvscg==", "requires": { - "isexe": "^2.0.0" + "isexe": "^3.1.1" } }, "why-is-node-running": {