diff --git a/package-lock.json b/package-lock.json index 276d64f..696ca10 100644 --- a/package-lock.json +++ b/package-lock.json @@ -55,6 +55,7 @@ "split2": "^4.2.0", "stacktrace-parser": "^0.1.10", "supports-color": "^9.4.0", + "tar": "^7.4.3", "ts-node": "^10.9.2", "tsx": "^4.19.1", "typescript": "^5.6.2", @@ -952,6 +953,18 @@ "node": ">=12" } }, + "node_modules/@isaacs/fs-minipass": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/@isaacs/fs-minipass/-/fs-minipass-4.0.1.tgz", + "integrity": "sha512-wgm9Ehl2jpeqP3zw/7mo3kRHFp5MEDhqAdwy1fTGkHAwnkGOVsgpvQhL8B5n1qlb01jV3n/bI0ZfZp5lWA1k4w==", + "dev": true, + "dependencies": { + "minipass": "^7.0.4" + }, + "engines": { + "node": ">=18.0.0" + } + }, "node_modules/@istanbuljs/schema": { "version": "0.1.3", "resolved": "https://registry.npmjs.org/@istanbuljs/schema/-/schema-0.1.3.tgz", @@ -5040,6 +5053,121 @@ "node": ">=16 || 14 >=14.17" } }, + "node_modules/minizlib": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/minizlib/-/minizlib-3.0.1.tgz", + "integrity": "sha512-umcy022ILvb5/3Djuu8LWeqUa8D68JaBzlttKeMWen48SjabqS3iY5w/vzeMzMUNhLDifyhbOwKDSznB1vvrwg==", + "dev": true, + "dependencies": { + "minipass": "^7.0.4", + "rimraf": "^5.0.5" + }, + "engines": { + "node": ">= 18" + } + }, + "node_modules/minizlib/node_modules/glob": { + "version": "10.4.5", + "resolved": "https://registry.npmjs.org/glob/-/glob-10.4.5.tgz", + "integrity": "sha512-7Bv8RF0k6xjo7d4A/PxYLbUCfb6c+Vpd2/mB2yRDlew7Jb5hEXiCD9ibfO7wpk8i4sevK6DFny9h7EYbM3/sHg==", + "dev": true, + "dependencies": { + "foreground-child": "^3.1.0", + "jackspeak": "^3.1.2", + "minimatch": "^9.0.4", + "minipass": "^7.1.2", + "package-json-from-dist": "^1.0.0", + "path-scurry": "^1.11.1" + }, + "bin": { + "glob": "dist/esm/bin.mjs" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/minizlib/node_modules/jackspeak": { + "version": "3.4.3", + "resolved": "https://registry.npmjs.org/jackspeak/-/jackspeak-3.4.3.tgz", + "integrity": "sha512-OGlZQpz2yfahA/Rd1Y8Cd9SIEsqvXkLVoSw/cgwhnhFMDbsQFeZYoJJ7bIZBS9BcamUW96asq/npPWugM+RQBw==", + "dev": true, + "dependencies": { + "@isaacs/cliui": "^8.0.2" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + }, + "optionalDependencies": { + "@pkgjs/parseargs": "^0.11.0" + } + }, + "node_modules/minizlib/node_modules/lru-cache": { + "version": "10.4.3", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.4.3.tgz", + "integrity": "sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==", + "dev": true + }, + "node_modules/minizlib/node_modules/minimatch": { + "version": "9.0.5", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz", + "integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==", + "dev": true, + "dependencies": { + "brace-expansion": "^2.0.1" + }, + "engines": { + "node": ">=16 || 14 >=14.17" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/minizlib/node_modules/path-scurry": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-1.11.1.tgz", + "integrity": "sha512-Xa4Nw17FS9ApQFJ9umLiJS4orGjm7ZzwUrwamcGQuHSzDyth9boKDaycYdDcZDuqYATXw4HFXgaqWTctW/v1HA==", + "dev": true, + "dependencies": { + "lru-cache": "^10.2.0", + "minipass": "^5.0.0 || ^6.0.2 || ^7.0.0" + }, + "engines": { + "node": ">=16 || 14 >=14.18" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/minizlib/node_modules/rimraf": { + "version": "5.0.10", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-5.0.10.tgz", + "integrity": "sha512-l0OE8wL34P4nJH/H2ffoaniAokM2qSmrtXHmlpvYr5AVVX8msAyW0l8NVJFDxlSK4u3Uh/f41cQheDVdnYijwQ==", + "dev": true, + "dependencies": { + "glob": "^10.3.7" + }, + "bin": { + "rimraf": "dist/esm/bin.mjs" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/mkdirp": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-3.0.1.tgz", + "integrity": "sha512-+NsyUUAZDmo6YVHzL/stxSu3t9YS1iljliy3BSDrXJ/dkn1KYdmtZODGGjLcc9XLgVVpH4KshHB8XmZgMhaBXg==", + "dev": true, + "bin": { + "mkdirp": "dist/cjs/src/bin.js" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, "node_modules/mkdirp-classic": { "version": "0.5.3", "resolved": "https://registry.npmjs.org/mkdirp-classic/-/mkdirp-classic-0.5.3.tgz", @@ -7259,6 +7387,23 @@ "node": ">=6" } }, + "node_modules/tar": { + "version": "7.4.3", + "resolved": "https://registry.npmjs.org/tar/-/tar-7.4.3.tgz", + "integrity": "sha512-5S7Va8hKfV7W5U6g3aYxXmlPoZVAwUMy9AOKyF2fVuZa2UD3qZjg578OrLRt8PcNN1PleVaL/5/yYATNL0ICUw==", + "dev": true, + "dependencies": { + "@isaacs/fs-minipass": "^4.0.0", + "chownr": "^3.0.0", + "minipass": "^7.1.2", + "minizlib": "^3.0.1", + "mkdirp": "^3.0.1", + "yallist": "^5.0.0" + }, + "engines": { + "node": ">=18" + } + }, "node_modules/tar-fs": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/tar-fs/-/tar-fs-2.1.1.tgz", @@ -7304,6 +7449,24 @@ "node": ">= 6" } }, + "node_modules/tar/node_modules/chownr": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/chownr/-/chownr-3.0.0.tgz", + "integrity": "sha512-+IxzY9BZOQd/XuYPRmrvEVjF/nqj5kgT4kEq7VofrDoM1MxoRjEWkrCC3EtLi59TVawxTAn+orJwFQcrqEN1+g==", + "dev": true, + "engines": { + "node": ">=18" + } + }, + "node_modules/tar/node_modules/yallist": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-5.0.0.tgz", + "integrity": "sha512-YgvUTfwqyc7UXVMrB+SImsVYSmTS8X/tSrtdNZMImM+n7+QTriRXyXim0mBrTXNeqzVF0KWGgHPeiyViFFrNDw==", + "dev": true, + "engines": { + "node": ">=18" + } + }, "node_modules/test-exclude": { "version": "6.0.0", "resolved": "https://registry.npmjs.org/test-exclude/-/test-exclude-6.0.0.tgz", diff --git a/package.json b/package.json index 2de57ce..4430722 100644 --- a/package.json +++ b/package.json @@ -3,7 +3,7 @@ "displayName": "Mocha for VS Code", "description": "Run and debug Mocha tests right within VS Code.", "publisher": "coderline", - "version": "1.2.1", + "version": "1.2.2", "icon": "icon.png", "engines": { "vscode": "^1.83.0" @@ -132,6 +132,7 @@ }, "devDependencies": { "@eslint/js": "^9.9.1", + "@jridgewell/trace-mapping": "^0.3.25", "@types/chai": "^4.3.17", "@types/eslint__js": "^8.42.3", "@types/estree": "^1.0.5", @@ -141,43 +142,43 @@ "@types/picomatch": "^3.0.1", "@types/sinon": "^17.0.3", "@types/split2": "^4.2.3", + "@types/which": "^3.0.4", "@types/yargs": "^17.0.33", "@typescript-eslint/eslint-plugin": "^8.8.0", "@typescript-eslint/parser": "^8.6.0", + "@typescript-eslint/typescript-estree": "^8.7.0", "@vscode/dts": "^0.4.1", "@vscode/test-cli": "^0.0.10", "@vscode/test-electron": "^2.4.1", "@vscode/vsce": "^3.1.1", "acorn": "^8.12.1", + "acorn-loose": "^8.4.0", + "ansi-colors": "^4.1.3", "chai": "^4.4.1", + "data-uri-to-buffer": "^6.0.2", + "enhanced-resolve": "^5.17.1", + "error-stack-parser": "^2.1.4", "eslint": "^9.11.0", "eslint-config-prettier": "^9.1.0", "eslint-plugin-license-header": "^0.6.1", "eslint-plugin-prettier": "^5.2.1", + "eslint-visitor-keys": "^4.1.0", + "glob": "^11.0.0", + "minimatch": "^10.0.1", "mocha": "^10.7.3", "prettier": "^3.3.3", "prettier-eslint": "^16.3.0", "prettier-eslint-cli": "^8.0.1", "prettier-plugin-organize-imports": "^4.1.0", "sinon": "^19.0.2", + "split2": "^4.2.0", + "stacktrace-parser": "^0.1.10", + "supports-color": "^9.4.0", + "tar": "^7.4.3", "ts-node": "^10.9.2", "tsx": "^4.19.1", "typescript": "^5.6.2", "typescript-eslint": "^8.6.0", - "@jridgewell/trace-mapping": "^0.3.25", - "@types/which": "^3.0.4", - "@typescript-eslint/typescript-estree": "^8.7.0", - "acorn-loose": "^8.4.0", - "ansi-colors": "^4.1.3", - "data-uri-to-buffer": "^6.0.2", - "enhanced-resolve": "^5.17.1", - "error-stack-parser": "^2.1.4", - "eslint-visitor-keys": "^4.1.0", - "glob": "^11.0.0", - "minimatch": "^10.0.1", - "split2": "^4.2.0", - "stacktrace-parser": "^0.1.10", - "supports-color": "^9.4.0", "which": "^5.0.0" }, "dependencies": { diff --git a/src/esbuild.ts b/src/esbuild.ts index c97f53d..447b3f6 100644 --- a/src/esbuild.ts +++ b/src/esbuild.ts @@ -11,6 +11,7 @@ import { exec } from 'node:child_process'; import fs from 'node:fs'; import os from 'node:os'; import path from 'node:path'; +import * as tar from 'tar'; import * as vscode from 'vscode'; // this logic is aligned with the ESBuild install script, unfortunately we cannot use pkgAndSubpathForCurrentPlatform directly @@ -90,6 +91,7 @@ export async function initESBuild( let platformPackageAndVersion: string; try { logChannel.debug('Determining ESBuild platform package and version'); + const packageJson = JSON.parse( await fs.promises.readFile( path.join(context.extensionPath, 'node_modules', 'esbuild', 'package.json'), @@ -135,23 +137,17 @@ export async function initESBuild( return; } - const args = [ - 'install', - '--no-save', - '--omit=dev', - '--omit=optional', - '--omit=peer', - '--prefer-offline', - '--no-audit', - '--progress=false', - platformPackageAndVersion, - ]; - logChannel.debug(`Running npm install ${args.join(' ')}`); + const temp = path.join(context.extensionPath, 'tmp'); + await fs.promises.rm(temp, { recursive: true, force: true }); + await fs.promises.mkdir(temp); + + const cmd = ['npm', 'pack', platformPackageAndVersion]; + logChannel.debug(`Downloading npm package via ${cmd.join(' ')}`); await new Promise((resolve, reject) => { exec( - `npm ${args.join(' ')}`, + cmd.join(' '), { - cwd: context.extensionPath, + cwd: temp, env: { ...process.env, ELECTRON_RUN_AS_NODE: '1', @@ -174,4 +170,21 @@ export async function initESBuild( }, ); }); + + const tgzPath = ( + await fs.promises.readdir(temp, { + withFileTypes: true, + recursive: false, + }) + )[0]; + logChannel.debug(`Extracting ${tgzPath.name}`); + await tar.extract({ + file: path.join(temp, tgzPath.name), + cwd: temp, + }); + + const targetPath = path.join(context.extensionPath, 'node_modules', platformPackageName); + logChannel.debug(`Moving files to ${targetPath}`); + await fs.promises.rm(targetPath, { recursive: true, force: true }); + await fs.promises.rename(path.join(temp, 'package'), targetPath); }