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.3 to 2.3.0

.husky/pre-commit

29

CHANGELOG.md
# Changelog
### 2.3.0 | 2022-02-27
- Automatically use the most recent version matching `engines.vscode` in extensions' package.json
- Allow insiders `version`s to be specified, such as `version: "1.76.0-insider"`
- Reduce the likelihood of 'broken' installations on interrupted downloads
- Remove dependency on outdated `unzipper` module
### 2.2.4 | 2022-02-19
- Use existing downloads if internet is inaccessible
### 2.2.3 | 2022-01-30

@@ -120,3 +131,3 @@

- Add `resolveCliPathFromVSCodeExecutablePath` that would resolve `vscodeExecutablePath` to VS Code CLI path, which can be used
for extension management features such as `--install-extension` and `--uninstall-extension`. [#31](https://github.com/microsoft/vscode-test/issues/31).
for extension management features such as `--install-extension` and `--uninstall-extension`. [#31](https://github.com/microsoft/vscode-test/issues/31).

@@ -144,9 +155,9 @@ ### 1.0.2 | 2019-07-17

- Updated API:
- One single set of options.
- `extensionPath` => `extensionDevelopmentPath` to align with VS Code launch flags
- `testRunnerPath` => `extensionTestsPath` to align with VS Code launch flags
- `testRunnerEnv` => `extensionTestsEnv` to align with VS Code launch flags
- `additionalLaunchArgs` => `launchArgs`
- `testWorkspace` removed. Pass path to file/folder/workspace as first argument to `launchArgs` instead.
- `locale` removed. Pass `--locale` to `launchArgs` instead.
- One single set of options.
- `extensionPath` => `extensionDevelopmentPath` to align with VS Code launch flags
- `testRunnerPath` => `extensionTestsPath` to align with VS Code launch flags
- `testRunnerEnv` => `extensionTestsEnv` to align with VS Code launch flags
- `additionalLaunchArgs` => `launchArgs`
- `testWorkspace` removed. Pass path to file/folder/workspace as first argument to `launchArgs` instead.
- `locale` removed. Pass `--locale` to `launchArgs` instead.

@@ -164,3 +175,3 @@ ### 0.4.3 | 2019-05-30

- Fix Linux crash because `testRunnerEnv` is not merged with `process.env` for spawning the
testing process. [#14](https://github.com/Microsoft/vscode-test/issues/14c).
testing process. [#14](https://github.com/Microsoft/vscode-test/issues/14c).

@@ -167,0 +178,0 @@ ### 0.4.0 | 2019-04-18

import { ProgressReporter } from './progress';
interface IFetchStableOptions {
timeout: number;
cachePath: string;
platform: string;
}
interface IFetchInferredOptions extends IFetchStableOptions {
extensionsDevelopmentPath?: string | string[];
}
export declare const fetchStableVersions: (timeout: number) => Promise<string[]>;
export declare const fetchInsiderVersions: (timeout: number) => Promise<string[]>;
export declare function fetchTargetInferredVersion(options: IFetchInferredOptions): Promise<string>;
/**

@@ -6,3 +17,3 @@ * Adapted from https://github.com/microsoft/TypeScript/issues/29729

*/
declare type StringLiteralUnion<T extends U, U = string> = T | (U & {});
declare type StringLiteralUnion<T extends string> = T | (string & {});
export declare type DownloadVersion = StringLiteralUnion<'insiders' | 'stable'>;

@@ -14,2 +25,3 @@ export declare type DownloadPlatform = StringLiteralUnion<'darwin' | 'darwin-arm64' | 'win32-archive' | 'win32-x64-archive' | 'linux-x64' | 'linux-arm64' | 'linux-armhf'>;

readonly platform: DownloadPlatform;
readonly extensionDevelopmentPath?: string | string[];
readonly reporter?: ProgressReporter;

@@ -16,0 +28,0 @@ readonly extractSync?: boolean;

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

Object.defineProperty(exports, "__esModule", { value: true });
exports.downloadAndUnzipVSCode = exports.download = exports.defaultCachePath = void 0;
exports.downloadAndUnzipVSCode = exports.download = exports.defaultCachePath = exports.fetchTargetInferredVersion = exports.fetchInsiderVersions = exports.fetchStableVersions = void 0;
const cp = require("child_process");

@@ -14,27 +14,105 @@ const fs = require("fs");

const stream_1 = require("stream");
const unzipper_1 = require("unzipper");
const util_1 = require("util");
const del = require("./del");
const progress_1 = require("./progress");
const request = require("./request");
const semver = require("semver");
const util_2 = require("./util");
const extensionRoot = process.cwd();
const pipelineAsync = util_1.promisify(stream_1.pipeline);
const vscodeStableReleasesAPI = `https://update.code.visualstudio.com/api/releases/stable`;
const vscodeInsiderReleasesAPI = `https://update.code.visualstudio.com/api/releases/insider`;
const vscodeInsiderCommitsAPI = (platform) => `https://update.code.visualstudio.com/api/commits/insider/${platform}`;
const downloadDirNameFormat = /^vscode-(?<platform>[a-z]+)-(?<version>[0-9.]+)$/;
const makeDownloadDirName = (platform, version) => `vscode-${platform}-${version}`;
const DOWNLOAD_ATTEMPTS = 3;
async function fetchLatestStableVersion(timeout) {
const versions = await request.getJSON(vscodeStableReleasesAPI, timeout);
if (!versions || !Array.isArray(versions) || !versions[0]) {
throw Error('Failed to get latest VS Code version');
exports.fetchStableVersions = util_2.onceWithoutRejections((timeout) => request.getJSON(vscodeStableReleasesAPI, timeout));
exports.fetchInsiderVersions = util_2.onceWithoutRejections((timeout) => request.getJSON(vscodeInsiderReleasesAPI, timeout));
/**
* Returns the stable version to run tests against. Attempts to get the latest
* version from the update sverice, but falls back to local installs if
* not available (e.g. if the machine is offline).
*/
async function fetchTargetStableVersion({ timeout, cachePath, platform }) {
try {
const versions = await exports.fetchStableVersions(timeout);
return versions[0];
}
return versions[0];
catch (e) {
return fallbackToLocalEntries(cachePath, platform, e);
}
}
async function fetchTargetInferredVersion(options) {
if (!options.extensionsDevelopmentPath) {
return fetchTargetStableVersion(options);
}
// load all engines versions from all development paths. Then, get the latest
// stable version (or, latest Insiders version) that satisfies all
// `engines.vscode` constraints.
const extPaths = Array.isArray(options.extensionsDevelopmentPath)
? options.extensionsDevelopmentPath
: [options.extensionsDevelopmentPath];
const maybeExtVersions = await Promise.all(extPaths.map(getEngineVersionFromExtension));
const extVersions = maybeExtVersions.filter(util_2.isDefined);
const matches = (v) => !extVersions.some((range) => !semver.satisfies(v, range, { includePrerelease: true }));
try {
const stable = await exports.fetchStableVersions(options.timeout);
const found1 = stable.find(matches);
if (found1) {
return found1;
}
const insiders = await exports.fetchInsiderVersions(options.timeout);
const found2 = insiders.find(matches);
if (found2) {
return found2;
}
const v = extVersions.join(', ');
console.warn(`No version of VS Code satisfies all extension engine constraints (${v}). Falling back to stable.`);
return stable[0]; // 🤷
}
catch (e) {
return fallbackToLocalEntries(options.cachePath, options.platform, e);
}
}
exports.fetchTargetInferredVersion = fetchTargetInferredVersion;
async function getEngineVersionFromExtension(extensionPath) {
var _a;
try {
const packageContents = await fs.promises.readFile(path.join(extensionPath, 'package.json'), 'utf8');
const packageJson = JSON.parse(packageContents);
return (_a = packageJson === null || packageJson === void 0 ? void 0 : packageJson.engines) === null || _a === void 0 ? void 0 : _a.vscode;
}
catch {
return undefined;
}
}
async function fallbackToLocalEntries(cachePath, platform, fromError) {
const entries = await fs.promises.readdir(cachePath).catch(() => []);
const [fallbackTo] = entries
.map((e) => downloadDirNameFormat.exec(e))
.filter(util_2.isDefined)
.filter((e) => e.groups.platform === platform)
.map((e) => e.groups.version)
.sort((a, b) => Number(b) - Number(a));
if (fallbackTo) {
console.warn(`Error retrieving VS Code versions, using already-installed version ${fallbackTo}`, fromError);
return fallbackTo;
}
throw fromError;
}
async function isValidVersion(version, platform, timeout) {
if (version === 'insiders') {
if (version === 'insiders' || version === 'stable') {
return true;
}
const stableVersionNumbers = await request.getJSON(vscodeStableReleasesAPI, timeout);
if (stableVersionNumbers.includes(version)) {
return true;
if (util_2.isStableVersionIdentifier(version)) {
const stableVersionNumbers = await exports.fetchStableVersions(timeout);
if (stableVersionNumbers.includes(version)) {
return true;
}
}
if (util_2.isInsiderVersionIdentifier(version)) {
const insiderVersionNumbers = await exports.fetchInsiderVersions(timeout);
if (insiderVersionNumbers.includes(version)) {
return true;
}
}
const insiderCommits = await request.getJSON(vscodeInsiderCommitsAPI(platform), timeout);

@@ -74,9 +152,19 @@ if (insiderCommits.includes(version)) {

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 });
(_b = options.reporter) === null || _b === void 0 ? void 0 : _b.report({
stage: progress_1.ProgressReportStage.Downloading,
url,
bytesSoFar: 0,
totalBytes,
});
let bytesSoFar = 0;
download.on('data', chunk => {
download.on('data', (chunk) => {
var _a;
bytesSoFar += chunk.length;
timeoutCtrl.touch();
(_a = options.reporter) === null || _a === void 0 ? void 0 : _a.report({ stage: progress_1.ProgressReportStage.Downloading, url, bytesSoFar, totalBytes });
(_a = options.reporter) === null || _a === void 0 ? void 0 : _a.report({
stage: progress_1.ProgressReportStage.Downloading,
url,
bytesSoFar,
totalBytes,
});
});

@@ -86,3 +174,8 @@ download.on('end', () => {

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

@@ -101,39 +194,36 @@ timeoutCtrl.signal.addEventListener('abort', () => {

if (format === 'zip') {
// note: this used to use Expand-Archive, but this caused a failure
// on longer file paths on windows. Instead use unzipper, which does
// not have this limitation.
//
// However it has problems that prevent it working on OSX:
// - https://github.com/ZJONSSON/node-unzipper/issues/216 (avoidable)
// - https://github.com/ZJONSSON/node-unzipper/issues/115 (not avoidable)
if (process.platform === 'win32' && extractSync) {
try {
await util_1.promisify(stream_1.pipeline)(stream, fs.createWriteStream(stagingFile));
reporter.report({ stage: progress_1.ProgressReportStage.ExtractingSynchonrously });
await spawnDecompressorChild('powershell.exe', [
'-NoProfile', '-ExecutionPolicy', 'Bypass', '-NonInteractive', '-NoLogo',
'-Command', `Microsoft.PowerShell.Archive\\Expand-Archive -Path "${stagingFile}" -DestinationPath "${extractDir}"`
]);
try {
reporter.report({ stage: progress_1.ProgressReportStage.ExtractingSynchonrously });
// note: this used to use Expand-Archive, but this caused a failure
// on longer file paths on windows. And we used to use the streaming
// "unzipper", but the module was very outdated and a bit buggy.
// Instead, use jszip. It's well-used and actually 8x faster than
// Expand-Archive on my machine.
if (process.platform === 'win32') {
const [buffer, JSZip] = await Promise.all([util_2.streamToBuffer(stream), Promise.resolve().then(() => require('jszip'))]);
const content = await JSZip.loadAsync(buffer);
// extract file with jszip
for (const filename of Object.keys(content.files)) {
const file = content.files[filename];
const filepath = path.join(extractDir, filename);
if (file.dir) {
continue;
}
// vscode update zips are trusted, but check for zip slip anyway.
if (!util_2.isSubdirectory(extractDir, filepath)) {
throw new Error(`Invalid zip file: ${filename}`);
}
await fs.promises.mkdir(path.dirname(filepath), { recursive: true });
await pipelineAsync(file.nodeStream(), fs.createWriteStream(filepath));
}
}
finally {
fs.unlink(stagingFile, () => undefined);
else {
// darwin or *nix sync
await pipelineAsync(stream, fs.createWriteStream(stagingFile));
await spawnDecompressorChild('unzip', ['-q', stagingFile, '-d', extractDir]);
}
}
else if (process.platform !== 'darwin' && !extractSync) {
await new Promise((resolve, reject) => stream
.on('error', reject)
.pipe(unzipper_1.Extract({ path: extractDir }))
.on('close', resolve)
.on('error', reject));
finally {
fs.unlink(stagingFile, () => undefined);
}
else { // darwin or *nix sync
try {
await util_1.promisify(stream_1.pipeline)(stream, fs.createWriteStream(stagingFile));
reporter.report({ stage: progress_1.ProgressReportStage.ExtractingSynchonrously });
await spawnDecompressorChild('unzip', ['-q', stagingFile, '-d', extractDir]);
}
finally {
fs.unlink(stagingFile, () => undefined);
}
}
}

@@ -158,3 +248,3 @@ else {

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

@@ -170,14 +260,12 @@ }

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(timeout);
}
else {
/**
* Only validate version against server when no local download that matches version exists
*/
if (!fs.existsSync(path.resolve(cachePath, `vscode-${platform}-${version}`))) {
if (!(await isValidVersion(version, platform, timeout))) {
throw Error(`Invalid version ${version}`);
}
if (version === 'stable') {
version = await fetchTargetStableVersion({ timeout, cachePath, platform });
}
else if (version) {
/**
* Only validate version against server when no local download that matches version exists
*/
if (!fs.existsSync(path.resolve(cachePath, `vscode-${platform}-${version}`))) {
if (!(await isValidVersion(version, platform, timeout))) {
throw Error(`Invalid version ${version}`);
}

@@ -187,11 +275,18 @@ }

else {
version = await fetchLatestStableVersion(timeout);
version = await fetchTargetInferredVersion({
timeout,
cachePath,
platform,
extensionsDevelopmentPath: options.extensionDevelopmentPath,
});
}
reporter.report({ stage: progress_1.ProgressReportStage.ResolvedVersion, version });
const downloadedPath = path.resolve(cachePath, `vscode-${platform}-${version}`);
const downloadedPath = path.resolve(cachePath, makeDownloadDirName(platform, version));
if (fs.existsSync(downloadedPath)) {
if (version === 'insiders') {
if (util_2.isInsiderVersionIdentifier(version)) {
reporter.report({ stage: progress_1.ProgressReportStage.FetchingInsidersMetadata });
const { version: currentHash, date: currentDate } = util_2.insidersDownloadDirMetadata(downloadedPath, platform);
const { version: latestHash, timestamp: latestTimestamp } = await util_2.getLatestInsidersMetadata(util_2.systemDefaultPlatform);
const { version: latestHash, timestamp: latestTimestamp } = version === 'insiders'
? await util_2.getLatestInsidersMetadata(util_2.systemDefaultPlatform)
: await util_2.getInsidersVersionMetadata(util_2.systemDefaultPlatform, version);
if (currentHash === latestHash) {

@@ -211,3 +306,3 @@ reporter.report({ stage: progress_1.ProgressReportStage.FoundMatchingInstall, downloadedPath });

});
await del.rmdir(downloadedPath);
await fs.promises.rm(downloadedPath, { force: true, recursive: true });
}

@@ -231,4 +326,17 @@ catch (err) {

try {
const { stream, format } = await downloadVSCodeArchive({ version, platform, cachePath, reporter, timeout });
await unzipVSCode(reporter, downloadedPath, extractSync, stream, format);
// Use a staging directory and rename after unzipping so partially-
// downloaded/unzipped files aren't "stuck" being used.
const downloadStaging = `${downloadedPath}.tmp`;
await fs.promises.rm(downloadStaging, { recursive: true, force: true });
const { stream, format } = await downloadVSCodeArchive({
version,
platform,
cachePath,
reporter,
timeout,
});
// important! do not put anything async here, since unzipVSCode will need
// to start consuming the stream immediately.
await unzipVSCode(reporter, downloadStaging, extractSync, stream, format);
await fs.promises.rename(downloadStaging, downloadedPath);
reporter.report({ stage: progress_1.ProgressReportStage.NewInstallComplete, downloadedPath });

@@ -239,3 +347,8 @@ break;

if (i++ < DOWNLOAD_ATTEMPTS) {
reporter.report({ stage: progress_1.ProgressReportStage.Retrying, attempt: i, error: error, totalAttempts: DOWNLOAD_ATTEMPTS });
reporter.report({
stage: progress_1.ProgressReportStage.Retrying,
attempt: i,
error: error,
totalAttempts: DOWNLOAD_ATTEMPTS,
});
}

@@ -242,0 +355,0 @@ else {

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

const util_1 = require("./util");
const platforms = ['darwin', 'darwin-arm64', 'win32-archive', 'win32-x64-archive', 'linux-x64', 'linux-arm64', 'linux-armhf'];
const platforms = [
'darwin',
'darwin-arm64',
'win32-archive',
'win32-x64-archive',
'linux-x64',
'linux-arm64',
'linux-armhf',
];
vitest_1.describe('sane downloads', () => {

@@ -49,1 +57,63 @@ const testTempDir = path_1.join(os_1.tmpdir(), 'vscode-test-download');

});
vitest_1.describe('fetchTargetInferredVersion', () => {
let stable;
let insiders;
let extensionsDevelopmentPath = path_1.join(os_1.tmpdir(), 'vscode-test-tmp-workspace');
vitest_1.beforeAll(async () => {
[stable, insiders] = await Promise.all([download_1.fetchStableVersions(5000), download_1.fetchInsiderVersions(5000)]);
});
vitest_1.afterEach(async () => {
await fs_1.promises.rm(extensionsDevelopmentPath, { recursive: true, force: true });
});
const writeJSON = async (path, contents) => {
const target = path_1.join(extensionsDevelopmentPath, path);
await fs_1.promises.mkdir(path_1.dirname(target), { recursive: true });
await fs_1.promises.writeFile(target, JSON.stringify(contents));
};
const doFetch = (paths = ['./']) => download_1.fetchTargetInferredVersion({
cachePath: path_1.join(extensionsDevelopmentPath, '.cache'),
platform: 'win32-archive',
timeout: 5000,
extensionsDevelopmentPath: paths.map((p) => path_1.join(extensionsDevelopmentPath, p)),
});
vitest_1.test('matches stable if no workspace', async () => {
const version = await doFetch();
vitest_1.expect(version).to.equal(stable[0]);
});
vitest_1.test('matches stable by default', async () => {
await writeJSON('package.json', {});
const version = await doFetch();
vitest_1.expect(version).to.equal(stable[0]);
});
vitest_1.test('matches if stable is defined', async () => {
await writeJSON('package.json', { engines: { vscode: '^1.50.0' } });
const version = await doFetch();
vitest_1.expect(version).to.equal(stable[0]);
});
vitest_1.test('matches best', async () => {
await writeJSON('package.json', { engines: { vscode: '<=1.60.5' } });
const version = await doFetch();
vitest_1.expect(version).to.equal('1.60.2');
});
vitest_1.test('matches multiple workspaces', async () => {
await writeJSON('a/package.json', { engines: { vscode: '<=1.60.5' } });
await writeJSON('b/package.json', { engines: { vscode: '<=1.55.5' } });
const version = await doFetch(['a', 'b']);
vitest_1.expect(version).to.equal('1.55.2');
});
vitest_1.test('matches insiders to better stable if there is one', async () => {
await writeJSON('package.json', { engines: { vscode: '^1.60.0-insider' } });
const version = await doFetch();
vitest_1.expect(version).to.equal(stable[0]);
});
vitest_1.test('matches current insiders', async () => {
await writeJSON('package.json', { engines: { vscode: `^${insiders[0]}` } });
const version = await doFetch();
vitest_1.expect(version).to.equal(insiders[0]);
});
vitest_1.test('matches insiders to exact', async () => {
await writeJSON('package.json', { engines: { vscode: '1.60.0-insider' } });
const version = await doFetch();
vitest_1.expect(version).to.equal('1.60.0-insider');
});
});

@@ -28,6 +28,6 @@ "use strict";

'--disable-workspace-trust',
'--extensionTestsPath=' + options.extensionTestsPath
'--extensionTestsPath=' + options.extensionTestsPath,
];
if (Array.isArray(options.extensionDevelopmentPath)) {
args.push(...options.extensionDevelopmentPath.map(devPath => `--extensionDevelopmentPath=${devPath}`));
args.push(...options.extensionDevelopmentPath.map((devPath) => `--extensionDevelopmentPath=${devPath}`));
}

@@ -59,3 +59,3 @@ else {

function hasArg(argName, argList) {
return argList.some(a => a === `--${argName}` || a.startsWith(`--${argName}=`));
return argList.some((a) => a === `--${argName}` || a.startsWith(`--${argName}=`));
}

@@ -66,4 +66,4 @@ async function innerRunTests(executable, args, testRunnerEnv) {

const cmd = cp.spawn(executable, args, { env: fullEnv });
cmd.stdout.on('data', d => process.stdout.write(d));
cmd.stderr.on('data', d => process.stderr.write(d));
cmd.stdout.on('data', (d) => process.stdout.write(d));
cmd.stderr.on('data', (d) => process.stderr.write(d));
cmd.on('error', function (data) {

@@ -70,0 +70,0 @@ console.log('Test error: ' + data.toString());

@@ -6,2 +6,3 @@ /// <reference types="node" />

export declare let systemDefaultPlatform: DownloadPlatform;
export declare function isInsiderVersionIdentifier(version: string): boolean;
export declare function isStableVersionIdentifier(version: string): boolean;

@@ -26,2 +27,3 @@ export declare function getVSCodeDownloadUrl(version: string, platform?: DownloadPlatform): string;

}
export declare function getInsidersVersionMetadata(platform: string, version: string): Promise<IUpdateMetadata>;
export declare function getLatestInsidersMetadata(platform: string): Promise<IUpdateMetadata>;

@@ -52,1 +54,12 @@ /**

export declare function resolveCliArgsFromVSCodeExecutablePath(vscodeExecutablePath: string, options?: Pick<TestOptions, 'reuseMachineInstall' | 'platform'>): string[];
/** Predicates whether arg is undefined or null */
export declare function isDefined<T>(arg: T | undefined | null): arg is T;
/** Gets a Buffer from a Node.js stream */
export declare function streamToBuffer(readable: NodeJS.ReadableStream): Promise<Buffer>;
/** Gets whether child is a subdirectory of the parent */
export declare function isSubdirectory(parent: string, child: string): boolean;
/**
* Wraps a function so that it's called once, and never again, memoizing
* the result unless it rejects.
*/
export declare function onceWithoutRejections<T, Args extends unknown[]>(fn: (...args: Args) => Promise<T>): (...args: Args) => Promise<T>;

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

Object.defineProperty(exports, "__esModule", { value: true });
exports.resolveCliArgsFromVSCodeExecutablePath = exports.resolveCliPathFromVSCodeExecutablePath = exports.getLatestInsidersMetadata = exports.insidersDownloadDirMetadata = exports.insidersDownloadDirToExecutablePath = exports.downloadDirToExecutablePath = exports.urlToOptions = exports.getVSCodeDownloadUrl = exports.isStableVersionIdentifier = exports.systemDefaultPlatform = void 0;
exports.onceWithoutRejections = exports.isSubdirectory = exports.streamToBuffer = exports.isDefined = exports.resolveCliArgsFromVSCodeExecutablePath = exports.resolveCliPathFromVSCodeExecutablePath = exports.getLatestInsidersMetadata = exports.getInsidersVersionMetadata = exports.insidersDownloadDirMetadata = exports.insidersDownloadDirToExecutablePath = exports.downloadDirToExecutablePath = exports.urlToOptions = exports.getVSCodeDownloadUrl = exports.isStableVersionIdentifier = exports.isInsiderVersionIdentifier = exports.systemDefaultPlatform = void 0;
const path = require("path");

@@ -23,17 +23,19 @@ const url_1 = require("url");

case 'win32':
exports.systemDefaultPlatform = process.arch === 'arm64'
? 'win32-arm64-archive'
: process.arch === 'ia32'
? 'win32-archive'
: 'win32-x64-archive';
exports.systemDefaultPlatform =
process.arch === 'arm64'
? 'win32-arm64-archive'
: process.arch === 'ia32'
? 'win32-archive'
: 'win32-x64-archive';
break;
default:
exports.systemDefaultPlatform = process.arch === 'arm64'
? 'linux-arm64'
: process.arch === 'arm'
? 'linux-armhf'
: 'linux-x64';
exports.systemDefaultPlatform =
process.arch === 'arm64' ? 'linux-arm64' : process.arch === 'arm' ? 'linux-armhf' : 'linux-x64';
}
function isInsiderVersionIdentifier(version) {
return version === 'insider' || version.endsWith('-insider'); // insider or 1.2.3-insider version string
}
exports.isInsiderVersionIdentifier = isInsiderVersionIdentifier;
function isStableVersionIdentifier(version) {
return version === 'stable' || version.includes('.'); // stable or 1.2.3 version string
return version === 'stable' || /^[0-9]+\.[0-9]+\.[0-9]$/.test(version); // stable or 1.2.3 version string
}

@@ -45,6 +47,10 @@ exports.isStableVersionIdentifier = isStableVersionIdentifier;

}
else if (isInsiderVersionIdentifier(version)) {
return `https://update.code.visualstudio.com/${version}/${platform}/insider`;
}
else if (isStableVersionIdentifier(version)) {
return `https://update.code.visualstudio.com/${version}/${platform}/stable`;
}
else { // insiders commit hash
else {
// insiders commit hash
return `https://update.code.visualstudio.com/commit:${version}/${platform}/insider`;

@@ -113,6 +119,11 @@ }

version: productJson.commit,
date: new Date(productJson.date)
date: new Date(productJson.date),
};
}
exports.insidersDownloadDirMetadata = insidersDownloadDirMetadata;
async function getInsidersVersionMetadata(platform, version) {
const remoteUrl = `https://update.code.visualstudio.com/api/versions/${version}/${platform}/insider`;
return await request.getJSON(remoteUrl, 30000);
}
exports.getInsidersVersionMetadata = getInsidersVersionMetadata;
async function getLatestInsidersMetadata(platform) {

@@ -169,3 +180,5 @@ const remoteUrl = `https://update.code.visualstudio.com/api/update/${platform}/insider/latest`;

var _a;
const args = [resolveCliPathFromVSCodeExecutablePath(vscodeExecutablePath, (_a = options === null || options === void 0 ? void 0 : options.platform) !== null && _a !== void 0 ? _a : exports.systemDefaultPlatform)];
const args = [
resolveCliPathFromVSCodeExecutablePath(vscodeExecutablePath, (_a = options === null || options === void 0 ? void 0 : options.platform) !== null && _a !== void 0 ? _a : exports.systemDefaultPlatform),
];
if (!(options === null || options === void 0 ? void 0 : options.reuseMachineInstall)) {

@@ -177,1 +190,39 @@ args.push(...runTest_1.getProfileArguments(args));

exports.resolveCliArgsFromVSCodeExecutablePath = resolveCliArgsFromVSCodeExecutablePath;
/** Predicates whether arg is undefined or null */
function isDefined(arg) {
return arg != null;
}
exports.isDefined = isDefined;
/** Gets a Buffer from a Node.js stream */
function streamToBuffer(readable) {
return new Promise((resolve, reject) => {
const chunks = [];
readable.on('data', (chunk) => chunks.push(chunk));
readable.on('error', reject);
readable.on('end', () => resolve(Buffer.concat(chunks)));
});
}
exports.streamToBuffer = streamToBuffer;
/** Gets whether child is a subdirectory of the parent */
function isSubdirectory(parent, child) {
const relative = path.relative(parent, child);
return !relative.startsWith('..') && !path.isAbsolute(relative);
}
exports.isSubdirectory = isSubdirectory;
/**
* Wraps a function so that it's called once, and never again, memoizing
* the result unless it rejects.
*/
function onceWithoutRejections(fn) {
let value;
return (...args) => {
if (!value) {
value = fn(...args).catch((err) => {
value = undefined;
throw err;
});
}
return value;
};
}
exports.onceWithoutRejections = onceWithoutRejections;
{
"name": "@vscode/test-electron",
"version": "2.2.3",
"version": "2.3.0",
"scripts": {

@@ -8,4 +8,15 @@ "compile": "tsc -p ./",

"prepublish": "tsc -p ./",
"test": "eslint lib --ext ts && vitest && tsc --noEmit"
"fmt": "prettier --write \"lib/**/*.ts\" \"*.md\"",
"test": "eslint lib --ext ts && vitest && tsc --noEmit",
"prepare": "husky install"
},
"lint-staged": {
"*.ts": [
"eslint --fix",
"prettier --write"
],
"*.md": [
"prettier --write"
]
},
"main": "./out/index.js",

@@ -18,4 +29,4 @@ "engines": {

"https-proxy-agent": "^5.0.0",
"rimraf": "^3.0.2",
"unzipper": "^0.10.11"
"jszip": "^3.10.1",
"semver": "^7.3.8"
},

@@ -25,3 +36,3 @@ "devDependencies": {

"@types/rimraf": "^3.0.0",
"@types/unzipper": "^0.10.3",
"@types/semver": "^7.3.13",
"@typescript-eslint/eslint-plugin": "^4.13.0",

@@ -31,2 +42,5 @@ "@typescript-eslint/parser": "^4.13.0",

"eslint-plugin-header": "^3.1.0",
"husky": "^8.0.3",
"lint-staged": "^13.1.2",
"prettier": "^2.8.4",
"typescript": "^4.3.5",

@@ -33,0 +47,0 @@ "vitest": "^0.10.2"

@@ -23,4 +23,4 @@ # vscode-test

try {
const extensionDevelopmentPath = path.resolve(__dirname, '../../../')
const extensionTestsPath = path.resolve(__dirname, './suite')
const extensionDevelopmentPath = path.resolve(__dirname, '../../../');
const extensionTestsPath = path.resolve(__dirname, './suite');

@@ -32,7 +32,7 @@ /**

extensionDevelopmentPath,
extensionTestsPath
})
extensionTestsPath,
});
const extensionTestsPath2 = path.resolve(__dirname, './suite2')
const testWorkspace = path.resolve(__dirname, '../../../test-fixtures/fixture1')
const extensionTestsPath2 = path.resolve(__dirname, './suite2');
const testWorkspace = path.resolve(__dirname, '../../../test-fixtures/fixture1');

@@ -45,4 +45,4 @@ /**

extensionTestsPath: extensionTestsPath2,
launchArgs: [testWorkspace]
})
launchArgs: [testWorkspace],
});

@@ -56,4 +56,4 @@ /**

extensionTestsPath,
launchArgs: [testWorkspace]
})
launchArgs: [testWorkspace],
});

@@ -67,4 +67,4 @@ /**

extensionTestsPath,
launchArgs: [testWorkspace]
})
launchArgs: [testWorkspace],
});

@@ -74,3 +74,3 @@ /**

*/
await downloadAndUnzipVSCode('1.36.1')
await downloadAndUnzipVSCode('1.36.1');

@@ -80,3 +80,3 @@ /**

*/
const vscodeExecutablePath = await downloadAndUnzipVSCode('1.35.0')
const vscodeExecutablePath = await downloadAndUnzipVSCode('1.35.0');
await runTests({

@@ -86,4 +86,4 @@ vscodeExecutablePath,

extensionTestsPath,
launchArgs: [testWorkspace]
})
launchArgs: [testWorkspace],
});

@@ -96,3 +96,3 @@ /**

encoding: 'utf-8',
stdio: 'inherit'
stdio: 'inherit',
});

@@ -111,7 +111,7 @@

// This disables all extensions except the one being tested
'--disable-extensions'
'--disable-extensions',
],
// Custom environment variables for extension test script
extensionTestsEnv: { foo: 'bar' }
})
extensionTestsEnv: { foo: 'bar' },
});

@@ -126,13 +126,12 @@ /**

version: '1.40.0',
platform: 'win32-x64-archive'
platform: 'win32-x64-archive',
});
}
} catch (err) {
console.error('Failed to run tests')
process.exit(1)
console.error('Failed to run tests');
process.exit(1);
}
}
go()
go();
```

@@ -139,0 +138,0 @@

@@ -15,15 +15,15 @@ <!-- BEGIN MICROSOFT SECURITY.MD V0.0.7 BLOCK -->

If you prefer to submit without logging in, send email to [secure@microsoft.com](mailto:secure@microsoft.com). If possible, encrypt your message with our PGP key; please download it from the [Microsoft Security Response Center PGP Key page](https://aka.ms/opensource/security/pgpkey).
If you prefer to submit without logging in, send email to [secure@microsoft.com](mailto:secure@microsoft.com). If possible, encrypt your message with our PGP key; please download it from the [Microsoft Security Response Center PGP Key page](https://aka.ms/opensource/security/pgpkey).
You should receive a response within 24 hours. If for some reason you do not, please follow up via email to ensure we received your original message. Additional information can be found at [microsoft.com/msrc](https://aka.ms/opensource/security/msrc).
You should receive a response within 24 hours. If for some reason you do not, please follow up via email to ensure we received your original message. Additional information can be found at [microsoft.com/msrc](https://aka.ms/opensource/security/msrc).
Please include the requested information listed below (as much as you can provide) to help us better understand the nature and scope of the possible issue:
* Type of issue (e.g. buffer overflow, SQL injection, cross-site scripting, etc.)
* Full paths of source file(s) related to the manifestation of the issue
* The location of the affected source code (tag/branch/commit or direct URL)
* Any special configuration required to reproduce the issue
* Step-by-step instructions to reproduce the issue
* Proof-of-concept or exploit code (if possible)
* Impact of the issue, including how an attacker might exploit the issue
- Type of issue (e.g. buffer overflow, SQL injection, cross-site scripting, etc.)
- Full paths of source file(s) related to the manifestation of the issue
- The location of the affected source code (tag/branch/commit or direct URL)
- Any special configuration required to reproduce the issue
- Step-by-step instructions to reproduce the issue
- Proof-of-concept or exploit code (if possible)
- Impact of the issue, including how an attacker might exploit the issue

@@ -30,0 +30,0 @@ This information will help us triage your report more quickly.

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