Socket
Socket
Sign inDemoInstall

@vscode/test-electron

Package Overview
Dependencies
Maintainers
7
Versions
29
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@vscode/test-electron - npm Package Compare versions

Comparing version 2.2.0 to 2.2.1

pipeline.yml

6

CHANGELOG.md
# Changelog
### 2.1.4 | 2022-06-27
### 2.2.1 | 2022-12-06
- Add an idle `timeout` for downloads
### 2.1.5 | 2022-06-27
- Automatically retry if VS Code download fails

@@ -6,0 +10,0 @@

@@ -15,2 +15,3 @@ import { ProgressReporter } from './progress';

readonly extractSync?: boolean;
readonly timeout?: number;
}

@@ -17,0 +18,0 @@ export declare const defaultCachePath: string;

44

out/download.js

@@ -23,4 +23,4 @@ "use strict";

const DOWNLOAD_ATTEMPTS = 3;
async function fetchLatestStableVersion() {
const versions = await request.getJSON(vscodeStableReleasesAPI);
async function fetchLatestStableVersion(timeout) {
const versions = await request.getJSON(vscodeStableReleasesAPI, timeout);
if (!versions || !Array.isArray(versions) || !versions[0]) {

@@ -31,11 +31,11 @@ throw Error('Failed to get latest VS Code version');

}
async function isValidVersion(version, platform) {
async function isValidVersion(version, platform, timeout) {
if (version === 'insiders') {
return true;
}
const stableVersionNumbers = await request.getJSON(vscodeStableReleasesAPI);
const stableVersionNumbers = await request.getJSON(vscodeStableReleasesAPI, timeout);
if (stableVersionNumbers.includes(version)) {
return true;
}
const insiderCommits = await request.getJSON(vscodeInsiderCommitsAPI(platform));
const insiderCommits = await request.getJSON(vscodeInsiderCommitsAPI(platform), timeout);
if (insiderCommits.includes(version)) {

@@ -57,5 +57,6 @@ return true;

}
const timeout = options.timeout;
const downloadUrl = util_2.getVSCodeDownloadUrl(options.version, options.platform);
(_a = options.reporter) === null || _a === void 0 ? void 0 : _a.report({ stage: progress_1.ProgressReportStage.ResolvingCDNLocation, url: downloadUrl });
const res = await request.getStream(downloadUrl);
const res = await request.getStream(downloadUrl, timeout);
if (res.statusCode !== 302) {

@@ -69,6 +70,7 @@ throw 'Failed to get VS Code archive location';

res.destroy();
const download = await request.getStream(url);
const download = await request.getStream(url, timeout);
const totalBytes = Number(download.headers['content-length']);
const contentType = download.headers['content-type'];
const isZip = contentType ? contentType === 'application/zip' : url.endsWith('.zip');
const timeoutCtrl = new request.TimeoutController(timeout);
(_b = options.reporter) === null || _b === void 0 ? void 0 : _b.report({ stage: progress_1.ProgressReportStage.Downloading, url, bytesSoFar: 0, totalBytes });

@@ -79,2 +81,3 @@ let bytesSoFar = 0;

bytesSoFar += chunk.length;
timeoutCtrl.touch();
(_a = options.reporter) === null || _a === void 0 ? void 0 : _a.report({ stage: progress_1.ProgressReportStage.Downloading, url, bytesSoFar, totalBytes });

@@ -84,4 +87,9 @@ });

var _a;
timeoutCtrl.dispose();
(_a = options.reporter) === null || _a === void 0 ? void 0 : _a.report({ stage: progress_1.ProgressReportStage.Downloading, url, bytesSoFar: totalBytes, totalBytes });
});
timeoutCtrl.signal.addEventListener('abort', () => {
download.emit('error', new request.TimeoutError(timeout));
download.destroy();
});
return { stream: download, format: isZip ? 'zip' : 'tgz' };

@@ -117,2 +125,3 @@ }

await new Promise((resolve, reject) => stream
.on('error', reject)
.pipe(unzipper_1.Extract({ path: extractDir }))

@@ -142,7 +151,10 @@ .on('close', resolve)

function spawnDecompressorChild(command, args, input) {
const child = cp.spawn(command, args, { stdio: 'pipe' });
input === null || input === void 0 ? void 0 : input.pipe(child.stdin);
child.stderr.pipe(process.stderr);
child.stdout.pipe(process.stdout);
return new Promise((resolve, reject) => {
const child = cp.spawn(command, args, { stdio: 'pipe' });
if (input) {
input.on('error', reject);
input.pipe(child.stdin);
}
child.stderr.pipe(process.stderr);
child.stdout.pipe(process.stdout);
child.on('error', reject);

@@ -159,6 +171,6 @@ child.on('exit', code => code === 0 ? resolve() : reject(new Error(`Failed to unzip archive, exited with ${code}`)));

let version = options === null || options === void 0 ? void 0 : options.version;
const { platform = util_2.systemDefaultPlatform, cachePath = exports.defaultCachePath, reporter = new progress_1.ConsoleReporter(process.stdout.isTTY), extractSync = false, } = options;
const { platform = util_2.systemDefaultPlatform, cachePath = exports.defaultCachePath, reporter = new progress_1.ConsoleReporter(process.stdout.isTTY), extractSync = false, timeout = 15000, } = options;
if (version) {
if (version === 'stable') {
version = await fetchLatestStableVersion();
version = await fetchLatestStableVersion(timeout);
}

@@ -170,3 +182,3 @@ else {

if (!fs.existsSync(path.resolve(cachePath, `vscode-${platform}-${version}`))) {
if (!(await isValidVersion(version, platform))) {
if (!(await isValidVersion(version, platform, timeout))) {
throw Error(`Invalid version ${version}`);

@@ -178,3 +190,3 @@ }

else {
version = await fetchLatestStableVersion();
version = await fetchLatestStableVersion(timeout);
}

@@ -221,3 +233,3 @@ reporter.report({ stage: progress_1.ProgressReportStage.ResolvedVersion, version });

try {
const { stream, format } = await downloadVSCodeArchive({ version, platform, cachePath, reporter });
const { stream, format } = await downloadVSCodeArchive({ version, platform, cachePath, reporter, timeout });
await unzipVSCode(reporter, downloadedPath, extractSync, stream, format);

@@ -224,0 +236,0 @@ reporter.report({ stage: progress_1.ProgressReportStage.NewInstallComplete, downloadedPath });

/// <reference types="node" />
import { IncomingMessage } from 'http';
export declare function getStream(api: string): Promise<IncomingMessage>;
export declare function getJSON<T>(api: string): Promise<T>;
export declare function getStream(api: string, timeout: number): Promise<IncomingMessage>;
export declare function getJSON<T>(api: string, timeout: number): Promise<T>;
export declare class TimeoutController {
private readonly timeout;
private handle;
private readonly ctrl;
get signal(): AbortSignal;
constructor(timeout: number);
touch(): void;
dispose(): void;
private readonly reject;
}
export declare class TimeoutError extends Error {
constructor(duration: number);
}

@@ -7,14 +7,25 @@ "use strict";

Object.defineProperty(exports, "__esModule", { value: true });
exports.getJSON = exports.getStream = void 0;
exports.TimeoutError = exports.TimeoutController = exports.getJSON = exports.getStream = void 0;
const https = require("https");
const util_1 = require("./util");
async function getStream(api) {
async function getStream(api, timeout) {
const ctrl = new TimeoutController(timeout);
return new Promise((resolve, reject) => {
https.get(api, util_1.urlToOptions(api), res => resolve(res)).on('error', reject);
});
ctrl.signal.addEventListener('abort', () => {
reject(new TimeoutError(timeout));
req.destroy();
});
const req = https.get(api, util_1.urlToOptions(api), (res) => resolve(res)).on('error', reject);
}).finally(() => ctrl.dispose());
}
exports.getStream = getStream;
async function getJSON(api) {
async function getJSON(api, timeout) {
const ctrl = new TimeoutController(timeout);
return new Promise((resolve, reject) => {
https.get(api, util_1.urlToOptions(api), res => {
ctrl.signal.addEventListener('abort', () => {
reject(new TimeoutError(timeout));
req.destroy();
});
const req = https
.get(api, util_1.urlToOptions(api), (res) => {
if (res.statusCode !== 200) {

@@ -24,6 +35,8 @@ reject('Failed to get JSON');

let data = '';
res.on('data', chunk => {
res.on('data', (chunk) => {
ctrl.touch();
data += chunk;
});
res.on('end', () => {
ctrl.dispose();
try {

@@ -39,5 +52,33 @@ const jsonData = JSON.parse(data);

res.on('error', reject);
}).on('error', reject);
});
})
.on('error', reject);
}).finally(() => ctrl.dispose());
}
exports.getJSON = getJSON;
class TimeoutController {
constructor(timeout) {
this.timeout = timeout;
this.ctrl = new AbortController();
this.reject = () => {
this.ctrl.abort();
};
this.handle = setTimeout(this.reject, timeout);
}
get signal() {
return this.ctrl.signal;
}
touch() {
clearTimeout(this.handle);
this.handle = setTimeout(this.reject, this.timeout);
}
dispose() {
clearTimeout(this.handle);
}
}
exports.TimeoutController = TimeoutController;
class TimeoutError extends Error {
constructor(duration) {
super(`@vscode/test-electron request timeout out after ${duration}ms`);
}
}
exports.TimeoutError = TimeoutError;

@@ -92,2 +92,8 @@ import { DownloadVersion, DownloadPlatform } from './download';

extractSync?: boolean;
/**
* Number of milliseconds after which to time out if no data is received from
* the remote when downloading VS Code. Note that this is an 'idle' timeout
* and does not enforce the total time VS Code may take to download.
*/
timeout?: number;
}

@@ -94,0 +100,0 @@ /**

@@ -116,3 +116,3 @@ "use strict";

const remoteUrl = `https://update.code.visualstudio.com/api/update/${platform}/insider/latest`;
return await request.getJSON(remoteUrl);
return await request.getJSON(remoteUrl, 30000);
}

@@ -119,0 +119,0 @@ exports.getLatestInsidersMetadata = getLatestInsidersMetadata;

{
"name": "@vscode/test-electron",
"version": "2.2.0",
"version": "2.2.1",
"scripts": {

@@ -12,3 +12,3 @@ "compile": "tsc -p ./",

"engines": {
"node": ">=8.9.3"
"node": ">=16"
},

@@ -22,3 +22,3 @@ "dependencies": {

"devDependencies": {
"@types/node": "^12",
"@types/node": "^18",
"@types/rimraf": "^3.0.0",

@@ -25,0 +25,0 @@ "@types/unzipper": "^0.10.3",

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc