mirror of
https://github.com/microsoft/vscode.git
synced 2026-05-08 17:19:48 +01:00
Merge branch 'master' of github.com:microsoft/vscode
This commit is contained in:
+3
-3
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"name": "code-oss-dev",
|
||||
"version": "1.37.0",
|
||||
"distro": "40f61fd7e131c62473197b6505a3168a6bce1bc6",
|
||||
"distro": "dc5129c59a3e10c61d732b82f158f39ff306f984",
|
||||
"author": {
|
||||
"name": "Microsoft Corporation"
|
||||
},
|
||||
@@ -52,7 +52,7 @@
|
||||
"vscode-ripgrep": "^1.3.1",
|
||||
"vscode-sqlite3": "4.0.8",
|
||||
"vscode-textmate": "^4.1.1",
|
||||
"xterm": "3.15.0-beta70",
|
||||
"xterm": "3.15.0-beta71",
|
||||
"xterm-addon-search": "0.2.0-beta2",
|
||||
"xterm-addon-web-links": "0.1.0-beta10",
|
||||
"yauzl": "^2.9.2",
|
||||
@@ -154,6 +154,6 @@
|
||||
"vscode-windows-registry": "1.0.1",
|
||||
"windows-foreground-love": "0.1.0",
|
||||
"windows-mutex": "0.2.1",
|
||||
"windows-process-tree": "0.2.3"
|
||||
"windows-process-tree": "0.2.4"
|
||||
}
|
||||
}
|
||||
|
||||
+1
-1
@@ -21,7 +21,7 @@
|
||||
"vscode-proxy-agent": "0.4.0",
|
||||
"vscode-ripgrep": "^1.3.1",
|
||||
"vscode-textmate": "^4.1.1",
|
||||
"xterm": "3.15.0-beta70",
|
||||
"xterm": "3.15.0-beta71",
|
||||
"xterm-addon-search": "0.2.0-beta2",
|
||||
"xterm-addon-web-links": "0.1.0-beta10",
|
||||
"yauzl": "^2.9.2",
|
||||
|
||||
+4
-4
@@ -1554,10 +1554,10 @@ xterm-addon-web-links@0.1.0-beta10:
|
||||
resolved "https://registry.yarnpkg.com/xterm-addon-web-links/-/xterm-addon-web-links-0.1.0-beta10.tgz#610fa9773a2a5ccd41c1c83ba0e2dd2c9eb66a23"
|
||||
integrity sha512-xfpjy0V6bB4BR44qIgZQPoCMVakxb65gMscPkHpO//QxvUxKzabV3dxOsIbeZRFkUGsWTFlvz2OoaBLoNtv5gg==
|
||||
|
||||
xterm@3.15.0-beta70:
|
||||
version "3.15.0-beta70"
|
||||
resolved "https://registry.yarnpkg.com/xterm/-/xterm-3.15.0-beta70.tgz#3e81f32e8cd7147f9a0764fbe2599c277c697a74"
|
||||
integrity sha512-VXhEbWwaxrs9Ac2KuTCmGX7Ktd0V+rVF5sdjXBsq/KBCtnUdwNzKnEjamNPsoNTDUv9y93INEbq82X7iBs1Gwg==
|
||||
xterm@3.15.0-beta71:
|
||||
version "3.15.0-beta71"
|
||||
resolved "https://registry.yarnpkg.com/xterm/-/xterm-3.15.0-beta71.tgz#2728c9800ca3b08423e835e9504bd1f4b5de6253"
|
||||
integrity sha512-8M/cLaxZ+iDopRxLPdPfKuDGaNNyYTdCeytdxjMSH0N7dZzbx6fbaEygQdCrV5pO9cGnT92MefSjVPGRXRiBLA==
|
||||
|
||||
yauzl@^2.9.2:
|
||||
version "2.10.0"
|
||||
|
||||
@@ -164,23 +164,27 @@ export interface ReadableStream<T> {
|
||||
/**
|
||||
* Stops emitting any events until resume() is called.
|
||||
*/
|
||||
pause(): void;
|
||||
pause?(): void;
|
||||
|
||||
/**
|
||||
* Starts emitting events again after pause() was called.
|
||||
*/
|
||||
resume(): void;
|
||||
resume?(): void;
|
||||
|
||||
/**
|
||||
* Destroys the stream and stops emitting any event.
|
||||
*/
|
||||
destroy(): void;
|
||||
destroy?(): void;
|
||||
}
|
||||
|
||||
/**
|
||||
* A readable stream that sends data via VSBuffer.
|
||||
*/
|
||||
export interface VSBufferReadableStream extends ReadableStream<VSBuffer> { }
|
||||
export interface VSBufferReadableStream extends ReadableStream<VSBuffer> {
|
||||
pause(): void;
|
||||
resume(): void;
|
||||
destroy(): void;
|
||||
}
|
||||
|
||||
export function isVSBufferReadableStream(obj: any): obj is VSBufferReadableStream {
|
||||
const candidate: VSBufferReadableStream = obj;
|
||||
@@ -248,10 +252,10 @@ export function bufferToStream(buffer: VSBuffer): VSBufferReadableStream {
|
||||
/**
|
||||
* Helper to create a VSBufferStream from a Uint8Array stream.
|
||||
*/
|
||||
export function toVSBufferReadableStream(stream: ReadableStream<Uint8Array>): VSBufferReadableStream {
|
||||
export function toVSBufferReadableStream(stream: ReadableStream<Uint8Array | string>): VSBufferReadableStream {
|
||||
const vsbufferStream = writeableBufferStream();
|
||||
|
||||
stream.on('data', data => vsbufferStream.write(VSBuffer.wrap(data)));
|
||||
stream.on('data', data => vsbufferStream.write(typeof data === 'string' ? VSBuffer.fromString(data) : VSBuffer.wrap(data)));
|
||||
stream.on('end', () => vsbufferStream.end());
|
||||
stream.on('error', error => vsbufferStream.error(error));
|
||||
|
||||
|
||||
@@ -1,183 +0,0 @@
|
||||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the MIT License. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import { isBoolean, isNumber } from 'vs/base/common/types';
|
||||
import * as https from 'https';
|
||||
import * as http from 'http';
|
||||
import { Stream } from 'stream';
|
||||
import { parse as parseUrl } from 'url';
|
||||
import { createWriteStream } from 'fs';
|
||||
import { assign } from 'vs/base/common/objects';
|
||||
import { createGunzip } from 'zlib';
|
||||
import { CancellationToken } from 'vs/base/common/cancellation';
|
||||
import { canceled } from 'vs/base/common/errors';
|
||||
|
||||
export type Agent = any;
|
||||
|
||||
export interface IRawRequestFunction {
|
||||
(options: http.RequestOptions, callback?: (res: http.IncomingMessage) => void): http.ClientRequest;
|
||||
}
|
||||
|
||||
export interface IRequestOptions {
|
||||
type?: string;
|
||||
url?: string;
|
||||
user?: string;
|
||||
password?: string;
|
||||
headers?: any;
|
||||
timeout?: number;
|
||||
data?: string | Stream;
|
||||
agent?: Agent;
|
||||
followRedirects?: number;
|
||||
strictSSL?: boolean;
|
||||
getRawRequest?(options: IRequestOptions): IRawRequestFunction;
|
||||
}
|
||||
|
||||
export interface IRequestContext {
|
||||
// req: http.ClientRequest;
|
||||
// res: http.ClientResponse;
|
||||
res: {
|
||||
headers: { [n: string]: string };
|
||||
statusCode?: number;
|
||||
};
|
||||
stream: Stream;
|
||||
}
|
||||
|
||||
export interface IRequestFunction {
|
||||
(options: IRequestOptions, token: CancellationToken): Promise<IRequestContext>;
|
||||
}
|
||||
|
||||
async function getNodeRequest(options: IRequestOptions): Promise<IRawRequestFunction> {
|
||||
const endpoint = parseUrl(options.url!);
|
||||
const module = endpoint.protocol === 'https:' ? await import('https') : await import('http');
|
||||
return module.request;
|
||||
}
|
||||
|
||||
export function request(options: IRequestOptions, token: CancellationToken): Promise<IRequestContext> {
|
||||
let req: http.ClientRequest;
|
||||
|
||||
const rawRequestPromise = options.getRawRequest
|
||||
? Promise.resolve(options.getRawRequest(options))
|
||||
: Promise.resolve(getNodeRequest(options));
|
||||
|
||||
return rawRequestPromise.then(rawRequest => {
|
||||
|
||||
return new Promise<IRequestContext>((c, e) => {
|
||||
const endpoint = parseUrl(options.url!);
|
||||
|
||||
const opts: https.RequestOptions = {
|
||||
hostname: endpoint.hostname,
|
||||
port: endpoint.port ? parseInt(endpoint.port) : (endpoint.protocol === 'https:' ? 443 : 80),
|
||||
protocol: endpoint.protocol,
|
||||
path: endpoint.path,
|
||||
method: options.type || 'GET',
|
||||
headers: options.headers,
|
||||
agent: options.agent,
|
||||
rejectUnauthorized: isBoolean(options.strictSSL) ? options.strictSSL : true
|
||||
};
|
||||
|
||||
if (options.user && options.password) {
|
||||
opts.auth = options.user + ':' + options.password;
|
||||
}
|
||||
|
||||
req = rawRequest(opts, (res: http.IncomingMessage) => {
|
||||
const followRedirects: number = isNumber(options.followRedirects) ? options.followRedirects : 3;
|
||||
if (res.statusCode && res.statusCode >= 300 && res.statusCode < 400 && followRedirects > 0 && res.headers['location']) {
|
||||
request(assign({}, options, {
|
||||
url: res.headers['location'],
|
||||
followRedirects: followRedirects - 1
|
||||
}), token).then(c, e);
|
||||
} else {
|
||||
let stream: Stream = res;
|
||||
|
||||
if (res.headers['content-encoding'] === 'gzip') {
|
||||
stream = stream.pipe(createGunzip());
|
||||
}
|
||||
|
||||
c({ res, stream } as IRequestContext);
|
||||
}
|
||||
});
|
||||
|
||||
req.on('error', e);
|
||||
|
||||
if (options.timeout) {
|
||||
req.setTimeout(options.timeout);
|
||||
}
|
||||
|
||||
if (options.data) {
|
||||
if (typeof options.data === 'string') {
|
||||
req.write(options.data);
|
||||
} else {
|
||||
options.data.pipe(req);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
req.end();
|
||||
|
||||
token.onCancellationRequested(() => {
|
||||
req.abort();
|
||||
e(canceled());
|
||||
});
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
function isSuccess(context: IRequestContext): boolean {
|
||||
return (context.res.statusCode && context.res.statusCode >= 200 && context.res.statusCode < 300) || context.res.statusCode === 1223;
|
||||
}
|
||||
|
||||
function hasNoContent(context: IRequestContext): boolean {
|
||||
return context.res.statusCode === 204;
|
||||
}
|
||||
|
||||
export function download(filePath: string, context: IRequestContext): Promise<void> {
|
||||
return new Promise<void>((c, e) => {
|
||||
const out = createWriteStream(filePath);
|
||||
|
||||
out.once('finish', () => c(undefined));
|
||||
context.stream.once('error', e);
|
||||
context.stream.pipe(out);
|
||||
});
|
||||
}
|
||||
|
||||
export function asText(context: IRequestContext): Promise<string | null> {
|
||||
return new Promise((c, e) => {
|
||||
if (!isSuccess(context)) {
|
||||
return e('Server returned ' + context.res.statusCode);
|
||||
}
|
||||
|
||||
if (hasNoContent(context)) {
|
||||
return c(null);
|
||||
}
|
||||
|
||||
const buffer: string[] = [];
|
||||
context.stream.on('data', (d: string) => buffer.push(d));
|
||||
context.stream.on('end', () => c(buffer.join('')));
|
||||
context.stream.on('error', e);
|
||||
});
|
||||
}
|
||||
|
||||
export function asJson<T = {}>(context: IRequestContext): Promise<T | null> {
|
||||
return new Promise((c, e) => {
|
||||
if (!isSuccess(context)) {
|
||||
return e('Server returned ' + context.res.statusCode);
|
||||
}
|
||||
|
||||
if (hasNoContent(context)) {
|
||||
return c(null);
|
||||
}
|
||||
|
||||
const buffer: string[] = [];
|
||||
context.stream.on('data', (d: string) => buffer.push(d));
|
||||
context.stream.on('end', () => {
|
||||
try {
|
||||
c(JSON.parse(buffer.join('')));
|
||||
} catch (err) {
|
||||
e(err);
|
||||
}
|
||||
});
|
||||
context.stream.on('error', e);
|
||||
});
|
||||
}
|
||||
@@ -19,8 +19,8 @@ import { ExtensionManagementService } from 'vs/platform/extensionManagement/node
|
||||
import { ExtensionGalleryService } from 'vs/platform/extensionManagement/node/extensionGalleryService';
|
||||
import { IConfigurationService } from 'vs/platform/configuration/common/configuration';
|
||||
import { ConfigurationService } from 'vs/platform/configuration/node/configurationService';
|
||||
import { IRequestService } from 'vs/platform/request/node/request';
|
||||
import { RequestService } from 'vs/platform/request/electron-browser/requestService';
|
||||
import { IRequestService } from 'vs/platform/request/common/request';
|
||||
import { RequestService } from 'vs/platform/request/browser/requestService';
|
||||
import { ITelemetryService } from 'vs/platform/telemetry/common/telemetry';
|
||||
import { combinedAppender, NullTelemetryService, ITelemetryAppender, NullAppender, LogAppender } from 'vs/platform/telemetry/common/telemetryUtils';
|
||||
import { resolveCommonProperties } from 'vs/platform/telemetry/node/commonProperties';
|
||||
@@ -51,6 +51,10 @@ import { SpdLogService } from 'vs/platform/log/node/spdlogService';
|
||||
import { DiagnosticsService } from 'vs/platform/diagnostics/node/diagnosticsService';
|
||||
import { IDiagnosticsService } from 'vs/platform/diagnostics/common/diagnosticsService';
|
||||
import { DiagnosticsChannel } from 'vs/platform/diagnostics/node/diagnosticsIpc';
|
||||
import { FileService } from 'vs/platform/files/common/fileService';
|
||||
import { IFileService } from 'vs/platform/files/common/files';
|
||||
import { DiskFileSystemProvider } from 'vs/platform/files/electron-browser/diskFileSystemProvider';
|
||||
import { Schemas } from 'vs/base/common/network';
|
||||
|
||||
export interface ISharedProcessConfiguration {
|
||||
readonly machineId: string;
|
||||
@@ -122,6 +126,15 @@ async function main(server: Server, initData: ISharedProcessInitData, configurat
|
||||
const dialogChannel = server.getChannel('dialog', activeWindowRouter);
|
||||
services.set(IDialogService, new DialogChannelClient(dialogChannel));
|
||||
|
||||
// Files
|
||||
const fileService = new FileService(logService);
|
||||
services.set(IFileService, fileService);
|
||||
disposables.add(fileService);
|
||||
|
||||
const diskFileSystemProvider = new DiskFileSystemProvider(logService);
|
||||
disposables.add(diskFileSystemProvider);
|
||||
fileService.registerProvider(Schemas.file, diskFileSystemProvider);
|
||||
|
||||
const instantiationService = new InstantiationService(services);
|
||||
|
||||
let telemetryService: ITelemetryService;
|
||||
|
||||
@@ -83,6 +83,9 @@ import { statSync } from 'fs';
|
||||
import { ISignService } from 'vs/platform/sign/common/sign';
|
||||
import { IDiagnosticsService } from 'vs/platform/diagnostics/common/diagnosticsService';
|
||||
import { DiagnosticsService } from 'vs/platform/diagnostics/node/diagnosticsIpc';
|
||||
import { FileService } from 'vs/platform/files/common/fileService';
|
||||
import { IFileService } from 'vs/platform/files/common/files';
|
||||
import { DiskFileSystemProvider } from 'vs/platform/files/node/diskFileSystemProvider';
|
||||
|
||||
export class CodeApplication extends Disposable {
|
||||
|
||||
@@ -418,6 +421,13 @@ export class CodeApplication extends Disposable {
|
||||
private async createServices(machineId: string, sharedProcess: SharedProcess, sharedProcessClient: Promise<Client<string>>): Promise<IInstantiationService> {
|
||||
const services = new ServiceCollection();
|
||||
|
||||
// Files
|
||||
const fileService = this._register(new FileService(this.logService));
|
||||
services.set(IFileService, fileService);
|
||||
|
||||
const diskFileSystemProvider = this._register(new DiskFileSystemProvider(this.logService));
|
||||
fileService.registerProvider(Schemas.file, diskFileSystemProvider);
|
||||
|
||||
switch (process.platform) {
|
||||
case 'win32':
|
||||
services.set(IUpdateService, new SyncDescriptor(Win32UpdateService));
|
||||
|
||||
@@ -26,7 +26,7 @@ import { IEnvironmentService, ParsedArgs } from 'vs/platform/environment/common/
|
||||
import { EnvironmentService } from 'vs/platform/environment/node/environmentService';
|
||||
import { IConfigurationService } from 'vs/platform/configuration/common/configuration';
|
||||
import { ConfigurationService } from 'vs/platform/configuration/node/configurationService';
|
||||
import { IRequestService } from 'vs/platform/request/node/request';
|
||||
import { IRequestService } from 'vs/platform/request/common/request';
|
||||
import { RequestService } from 'vs/platform/request/electron-main/requestService';
|
||||
import * as fs from 'fs';
|
||||
import { CodeApplication } from 'vs/code/electron-main/app';
|
||||
|
||||
@@ -22,7 +22,7 @@ import { ITelemetryService } from 'vs/platform/telemetry/common/telemetry';
|
||||
import { combinedAppender, NullTelemetryService } from 'vs/platform/telemetry/common/telemetryUtils';
|
||||
import { TelemetryService, ITelemetryServiceConfig } from 'vs/platform/telemetry/common/telemetryService';
|
||||
import { resolveCommonProperties } from 'vs/platform/telemetry/node/commonProperties';
|
||||
import { IRequestService } from 'vs/platform/request/node/request';
|
||||
import { IRequestService } from 'vs/platform/request/common/request';
|
||||
import { RequestService } from 'vs/platform/request/node/requestService';
|
||||
import { IConfigurationService } from 'vs/platform/configuration/common/configuration';
|
||||
import { ConfigurationService } from 'vs/platform/configuration/node/configurationService';
|
||||
@@ -42,6 +42,10 @@ import { LocalizationsService } from 'vs/platform/localizations/node/localizatio
|
||||
import { Schemas } from 'vs/base/common/network';
|
||||
import { SpdLogService } from 'vs/platform/log/node/spdlogService';
|
||||
import { buildTelemetryMessage } from 'vs/platform/telemetry/node/telemetry';
|
||||
import { FileService } from 'vs/platform/files/common/fileService';
|
||||
import { IFileService } from 'vs/platform/files/common/files';
|
||||
import { DiskFileSystemProvider } from 'vs/platform/files/node/diskFileSystemProvider';
|
||||
import { DisposableStore } from 'vs/base/common/lifecycle';
|
||||
|
||||
const notFound = (id: string) => localize('notFound', "Extension '{0}' not found.", id);
|
||||
const notInstalled = (id: string) => localize('notInstalled', "Extension '{0}' is not installed.", id);
|
||||
@@ -280,6 +284,7 @@ const eventPrefix = 'monacoworkbench';
|
||||
|
||||
export async function main(argv: ParsedArgs): Promise<void> {
|
||||
const services = new ServiceCollection();
|
||||
const disposables = new DisposableStore();
|
||||
|
||||
const environmentService = new EnvironmentService(argv, process.execPath);
|
||||
const logService: ILogService = new SpdLogService('cli', environmentService.logsPath, getLogLevel(environmentService));
|
||||
@@ -289,6 +294,7 @@ export async function main(argv: ParsedArgs): Promise<void> {
|
||||
await Promise.all([environmentService.appSettingsHome.fsPath, environmentService.extensionsPath].map(p => mkdirp(p)));
|
||||
|
||||
const configurationService = new ConfigurationService(environmentService.settingsResource);
|
||||
disposables.add(configurationService);
|
||||
await configurationService.initialize();
|
||||
|
||||
services.set(IEnvironmentService, environmentService);
|
||||
@@ -296,15 +302,26 @@ export async function main(argv: ParsedArgs): Promise<void> {
|
||||
services.set(IConfigurationService, configurationService);
|
||||
services.set(IStateService, new SyncDescriptor(StateService));
|
||||
|
||||
// Files
|
||||
const fileService = new FileService(logService);
|
||||
disposables.add(fileService);
|
||||
services.set(IFileService, fileService);
|
||||
|
||||
const diskFileSystemProvider = new DiskFileSystemProvider(logService);
|
||||
disposables.add(diskFileSystemProvider);
|
||||
fileService.registerProvider(Schemas.file, diskFileSystemProvider);
|
||||
|
||||
const instantiationService: IInstantiationService = new InstantiationService(services);
|
||||
|
||||
return instantiationService.invokeFunction(accessor => {
|
||||
return instantiationService.invokeFunction(async accessor => {
|
||||
const envService = accessor.get(IEnvironmentService);
|
||||
const stateService = accessor.get(IStateService);
|
||||
|
||||
const { appRoot, extensionsPath, extensionDevelopmentLocationURI: extensionDevelopmentLocationURI, isBuilt, installSourcePath } = envService;
|
||||
|
||||
const services = new ServiceCollection();
|
||||
|
||||
|
||||
services.set(IRequestService, new SyncDescriptor(RequestService));
|
||||
services.set(IExtensionManagementService, new SyncDescriptor(ExtensionManagementService));
|
||||
services.set(IExtensionGalleryService, new SyncDescriptor(ExtensionGalleryService));
|
||||
@@ -323,6 +340,9 @@ export async function main(argv: ParsedArgs): Promise<void> {
|
||||
};
|
||||
|
||||
services.set(ITelemetryService, new SyncDescriptor(TelemetryService, [config]));
|
||||
|
||||
// Dispose the AI adapter so that remaining data gets flushed.
|
||||
disposables.add(combinedAppender(...appenders));
|
||||
} else {
|
||||
services.set(ITelemetryService, NullTelemetryService);
|
||||
}
|
||||
@@ -330,9 +350,10 @@ export async function main(argv: ParsedArgs): Promise<void> {
|
||||
const instantiationService2 = instantiationService.createChild(services);
|
||||
const main = instantiationService2.createInstance(Main);
|
||||
|
||||
return main.run(argv).then(() => {
|
||||
// Dispose the AI adapter so that remaining data gets flushed.
|
||||
return combinedAppender(...appenders).dispose();
|
||||
});
|
||||
try {
|
||||
await main.run(argv);
|
||||
} finally {
|
||||
disposables.dispose();
|
||||
}
|
||||
});
|
||||
}
|
||||
@@ -7,19 +7,20 @@ import { IDownloadService } from 'vs/platform/download/common/download';
|
||||
import { URI } from 'vs/base/common/uri';
|
||||
import { Schemas } from 'vs/base/common/network';
|
||||
import { copy } from 'vs/base/node/pfs';
|
||||
import { IRequestService } from 'vs/platform/request/node/request';
|
||||
import { asText, download } from 'vs/base/node/request';
|
||||
import { IRequestService, asText } from 'vs/platform/request/common/request';
|
||||
import { CancellationToken } from 'vs/base/common/cancellation';
|
||||
import { join } from 'vs/base/common/path';
|
||||
import { tmpdir } from 'os';
|
||||
import { generateUuid } from 'vs/base/common/uuid';
|
||||
import { IFileService } from 'vs/platform/files/common/files';
|
||||
|
||||
export class DownloadService implements IDownloadService {
|
||||
|
||||
_serviceBrand: any;
|
||||
|
||||
constructor(
|
||||
@IRequestService private readonly requestService: IRequestService
|
||||
@IRequestService private readonly requestService: IRequestService,
|
||||
@IFileService private readonly fileService: IFileService
|
||||
) { }
|
||||
|
||||
download(uri: URI, target: string = join(tmpdir(), generateUuid()), cancellationToken: CancellationToken = CancellationToken.None): Promise<string> {
|
||||
@@ -30,7 +31,7 @@ export class DownloadService implements IDownloadService {
|
||||
return this.requestService.request(options, cancellationToken)
|
||||
.then(context => {
|
||||
if (context.res.statusCode === 200) {
|
||||
return download(target, context).then(() => target);
|
||||
return this.fileService.writeFile(URI.file(target), context.stream).then(() => target);
|
||||
}
|
||||
return asText(context)
|
||||
.then(message => Promise.reject(new Error(`Expected 200, got back ${context.res.statusCode} instead.\n\n${message}`)));
|
||||
|
||||
@@ -9,10 +9,9 @@ import { getErrorMessage, isPromiseCanceledError, canceled } from 'vs/base/commo
|
||||
import { StatisticType, IGalleryExtension, IExtensionGalleryService, IGalleryExtensionAsset, IQueryOptions, SortBy, SortOrder, IExtensionIdentifier, IReportedExtension, InstallOperation, ITranslation, IGalleryExtensionVersion, IGalleryExtensionAssets, isIExtensionIdentifier } from 'vs/platform/extensionManagement/common/extensionManagement';
|
||||
import { getGalleryExtensionId, getGalleryExtensionTelemetryData, adoptToGalleryExtensionId } from 'vs/platform/extensionManagement/common/extensionManagementUtil';
|
||||
import { assign, getOrDefault } from 'vs/base/common/objects';
|
||||
import { IRequestService } from 'vs/platform/request/node/request';
|
||||
import { ITelemetryService } from 'vs/platform/telemetry/common/telemetry';
|
||||
import { IPager } from 'vs/base/common/paging';
|
||||
import { IRequestOptions, IRequestContext, download, asJson, asText } from 'vs/base/node/request';
|
||||
import { IRequestService, IRequestOptions, IRequestContext, asJson, asText } from 'vs/platform/request/common/request';
|
||||
import pkg from 'vs/platform/product/node/package';
|
||||
import product from 'vs/platform/product/node/product';
|
||||
import { isEngineValid } from 'vs/platform/extensions/node/extensionValidator';
|
||||
@@ -23,6 +22,8 @@ import { values } from 'vs/base/common/map';
|
||||
import { CancellationToken } from 'vs/base/common/cancellation';
|
||||
import { ILogService } from 'vs/platform/log/common/log';
|
||||
import { IExtensionManifest } from 'vs/platform/extensions/common/extensions';
|
||||
import { IFileService } from 'vs/platform/files/common/files';
|
||||
import { URI } from 'vs/base/common/uri';
|
||||
|
||||
interface IRawGalleryExtensionFile {
|
||||
assetType: string;
|
||||
@@ -336,7 +337,8 @@ export class ExtensionGalleryService implements IExtensionGalleryService {
|
||||
@IRequestService private readonly requestService: IRequestService,
|
||||
@ILogService private readonly logService: ILogService,
|
||||
@IEnvironmentService private readonly environmentService: IEnvironmentService,
|
||||
@ITelemetryService private readonly telemetryService: ITelemetryService
|
||||
@ITelemetryService private readonly telemetryService: ITelemetryService,
|
||||
@IFileService private readonly fileService: IFileService,
|
||||
) {
|
||||
const config = product.extensionsGallery;
|
||||
this.extensionsGalleryUrl = config && config.serviceUrl;
|
||||
@@ -555,7 +557,7 @@ export class ExtensionGalleryService implements IExtensionGalleryService {
|
||||
} : extension.assets.download;
|
||||
|
||||
return this.getAsset(downloadAsset)
|
||||
.then(context => download(zipPath, context))
|
||||
.then(context => this.fileService.writeFile(URI.file(zipPath), context.stream))
|
||||
.then(() => log(new Date().getTime() - startTime))
|
||||
.then(() => zipPath);
|
||||
}
|
||||
|
||||
@@ -9,14 +9,9 @@ import { FileDeleteOptions, FileSystemProviderCapabilities } from 'vs/platform/f
|
||||
import { isWindows } from 'vs/base/common/platform';
|
||||
import { localize } from 'vs/nls';
|
||||
import { basename } from 'vs/base/common/path';
|
||||
import { ILogService } from 'vs/platform/log/common/log';
|
||||
|
||||
export class DiskFileSystemProvider extends NodeDiskFileSystemProvider {
|
||||
|
||||
constructor(logService: ILogService) {
|
||||
super(logService);
|
||||
}
|
||||
|
||||
get capabilities(): FileSystemProviderCapabilities {
|
||||
if (!this._capabilities) {
|
||||
this._capabilities = super.capabilities | FileSystemProviderCapabilities.Trash;
|
||||
|
||||
@@ -0,0 +1,96 @@
|
||||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the MIT License. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import { IRequestOptions, IRequestContext } from 'vs/platform/request/common/request';
|
||||
import { CancellationToken } from 'vs/base/common/cancellation';
|
||||
import { canceled } from 'vs/base/common/errors';
|
||||
import { IConfigurationService } from 'vs/platform/configuration/common/configuration';
|
||||
import { ILogService } from 'vs/platform/log/common/log';
|
||||
import { assign } from 'vs/base/common/objects';
|
||||
import { VSBuffer, bufferToStream } from 'vs/base/common/buffer';
|
||||
|
||||
/**
|
||||
* This service exposes the `request` API, while using the global
|
||||
* or configured proxy settings.
|
||||
*/
|
||||
export class RequestService {
|
||||
|
||||
_serviceBrand: any;
|
||||
|
||||
constructor(
|
||||
@IConfigurationService private readonly configurationService: IConfigurationService,
|
||||
@ILogService private readonly logService: ILogService
|
||||
) {
|
||||
}
|
||||
|
||||
request(options: IRequestOptions, token: CancellationToken): Promise<IRequestContext> {
|
||||
this.logService.trace('RequestService#request', options.url);
|
||||
|
||||
const authorization = this.configurationService.getValue<string>('http.proxyAuthorization');
|
||||
if (authorization) {
|
||||
options.headers = assign(options.headers || {}, { 'Proxy-Authorization': authorization });
|
||||
}
|
||||
|
||||
const xhr = new XMLHttpRequest();
|
||||
return new Promise<IRequestContext>((resolve, reject) => {
|
||||
|
||||
xhr.open(options.type || 'GET', options.url || '', true, options.user, options.password);
|
||||
this.setRequestHeaders(xhr, options);
|
||||
|
||||
xhr.responseType = 'arraybuffer';
|
||||
xhr.onerror = e => reject(new Error(xhr.statusText && ('XHR failed: ' + xhr.statusText)));
|
||||
xhr.onload = (e) => {
|
||||
resolve({
|
||||
res: {
|
||||
statusCode: xhr.status,
|
||||
headers: this.getResponseHeaders(xhr)
|
||||
},
|
||||
stream: bufferToStream(VSBuffer.wrap(new Uint8Array(xhr.response)))
|
||||
});
|
||||
};
|
||||
xhr.ontimeout = e => reject(new Error(`XHR timeout: ${options.timeout}ms`));
|
||||
|
||||
if (options.timeout) {
|
||||
xhr.timeout = options.timeout;
|
||||
}
|
||||
|
||||
xhr.send(options.data);
|
||||
|
||||
// cancel
|
||||
token.onCancellationRequested(() => {
|
||||
xhr.abort();
|
||||
reject(canceled());
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
private setRequestHeaders(xhr: XMLHttpRequest, options: IRequestOptions): void {
|
||||
if (options.headers) {
|
||||
outer: for (let k in options.headers) {
|
||||
switch (k) {
|
||||
case 'User-Agent':
|
||||
case 'Accept-Encoding':
|
||||
case 'Content-Length':
|
||||
// unsafe headers
|
||||
continue outer;
|
||||
}
|
||||
xhr.setRequestHeader(k, options.headers[k]);
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private getResponseHeaders(xhr: XMLHttpRequest): { [name: string]: string } {
|
||||
const headers: { [name: string]: string } = Object.create(null);
|
||||
for (const line of xhr.getAllResponseHeaders().split(/\r\n|\n|\r/g)) {
|
||||
if (line) {
|
||||
const idx = line.indexOf(':');
|
||||
headers[line.substr(0, idx).trim().toLowerCase()] = line.substr(idx + 1).trim();
|
||||
}
|
||||
}
|
||||
return headers;
|
||||
}
|
||||
|
||||
}
|
||||
+54
-2
@@ -4,20 +4,72 @@
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import { localize } from 'vs/nls';
|
||||
import { CancellationToken } from 'vs/base/common/cancellation';
|
||||
import { createDecorator } from 'vs/platform/instantiation/common/instantiation';
|
||||
import { IRequestOptions, IRequestContext } from 'vs/base/node/request';
|
||||
import { IConfigurationRegistry, Extensions } from 'vs/platform/configuration/common/configurationRegistry';
|
||||
import { Registry } from 'vs/platform/registry/common/platform';
|
||||
import { CancellationToken } from 'vs/base/common/cancellation';
|
||||
import { VSBufferReadableStream, streamToBuffer } from 'vs/base/common/buffer';
|
||||
|
||||
export const IRequestService = createDecorator<IRequestService>('requestService');
|
||||
|
||||
export interface IRequestOptions {
|
||||
type?: string;
|
||||
url?: string;
|
||||
user?: string;
|
||||
password?: string;
|
||||
headers?: any;
|
||||
timeout?: number;
|
||||
data?: string;
|
||||
followRedirects?: number;
|
||||
}
|
||||
|
||||
export interface IRequestContext {
|
||||
// req: http.ClientRequest;
|
||||
// res: http.ClientResponse;
|
||||
res: {
|
||||
headers: { [n: string]: string };
|
||||
statusCode?: number;
|
||||
};
|
||||
stream: VSBufferReadableStream;
|
||||
}
|
||||
|
||||
export interface IRequestService {
|
||||
_serviceBrand: any;
|
||||
|
||||
request(options: IRequestOptions, token: CancellationToken): Promise<IRequestContext>;
|
||||
}
|
||||
|
||||
function isSuccess(context: IRequestContext): boolean {
|
||||
return (context.res.statusCode && context.res.statusCode >= 200 && context.res.statusCode < 300) || context.res.statusCode === 1223;
|
||||
}
|
||||
|
||||
function hasNoContent(context: IRequestContext): boolean {
|
||||
return context.res.statusCode === 204;
|
||||
}
|
||||
|
||||
export async function asText(context: IRequestContext): Promise<string | null> {
|
||||
if (!isSuccess(context)) {
|
||||
throw new Error('Server returned ' + context.res.statusCode);
|
||||
}
|
||||
if (hasNoContent(context)) {
|
||||
return null;
|
||||
}
|
||||
const buffer = await streamToBuffer(context.stream);
|
||||
return buffer.toString();
|
||||
}
|
||||
|
||||
export async function asJson<T = {}>(context: IRequestContext): Promise<T | null> {
|
||||
if (!isSuccess(context)) {
|
||||
throw new Error('Server returned ' + context.res.statusCode);
|
||||
}
|
||||
if (hasNoContent(context)) {
|
||||
return null;
|
||||
}
|
||||
const buffer = await streamToBuffer(context.stream);
|
||||
return JSON.parse(buffer.toString());
|
||||
}
|
||||
|
||||
|
||||
export interface IHTTPConfiguration {
|
||||
http?: {
|
||||
proxy?: string;
|
||||
@@ -1,105 +0,0 @@
|
||||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the MIT License. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import { IRequestOptions, IRequestContext, IRequestFunction } from 'vs/base/node/request';
|
||||
import { Readable } from 'stream';
|
||||
import { RequestService as NodeRequestService } from 'vs/platform/request/node/requestService';
|
||||
import { CancellationToken } from 'vs/base/common/cancellation';
|
||||
import { canceled } from 'vs/base/common/errors';
|
||||
|
||||
/**
|
||||
* This service exposes the `request` API, while using the global
|
||||
* or configured proxy settings.
|
||||
*/
|
||||
export class RequestService extends NodeRequestService {
|
||||
request(options: IRequestOptions, token: CancellationToken): Promise<IRequestContext> {
|
||||
return super.request(options, token, xhrRequest);
|
||||
}
|
||||
}
|
||||
|
||||
export const xhrRequest: IRequestFunction = (options: IRequestOptions, token: CancellationToken): Promise<IRequestContext> => {
|
||||
|
||||
const xhr = new XMLHttpRequest();
|
||||
return new Promise<IRequestContext>((resolve, reject) => {
|
||||
|
||||
xhr.open(options.type || 'GET', options.url || '', true, options.user, options.password);
|
||||
setRequestHeaders(xhr, options);
|
||||
|
||||
xhr.responseType = 'arraybuffer';
|
||||
xhr.onerror = e => reject(new Error(xhr.statusText && ('XHR failed: ' + xhr.statusText)));
|
||||
xhr.onload = (e) => {
|
||||
resolve({
|
||||
res: {
|
||||
statusCode: xhr.status,
|
||||
headers: getResponseHeaders(xhr)
|
||||
},
|
||||
stream: new class ArrayBufferStream extends Readable {
|
||||
|
||||
private _buffer: Buffer;
|
||||
private _offset: number;
|
||||
private _length: number;
|
||||
|
||||
constructor(arraybuffer: ArrayBuffer) {
|
||||
super();
|
||||
this._buffer = Buffer.from(new Uint8Array(arraybuffer));
|
||||
this._offset = 0;
|
||||
this._length = this._buffer.length;
|
||||
}
|
||||
|
||||
_read(size: number) {
|
||||
if (this._offset < this._length) {
|
||||
this.push(this._buffer.slice(this._offset, (this._offset + size)));
|
||||
this._offset += size;
|
||||
} else {
|
||||
this.push(null);
|
||||
}
|
||||
}
|
||||
|
||||
}(xhr.response)
|
||||
});
|
||||
};
|
||||
xhr.ontimeout = e => reject(new Error(`XHR timeout: ${options.timeout}ms`));
|
||||
|
||||
if (options.timeout) {
|
||||
xhr.timeout = options.timeout;
|
||||
}
|
||||
|
||||
// TODO: remove any
|
||||
xhr.send(options.data as any);
|
||||
|
||||
// cancel
|
||||
token.onCancellationRequested(() => {
|
||||
xhr.abort();
|
||||
reject(canceled());
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
function setRequestHeaders(xhr: XMLHttpRequest, options: IRequestOptions): void {
|
||||
if (options.headers) {
|
||||
outer: for (let k in options.headers) {
|
||||
switch (k) {
|
||||
case 'User-Agent':
|
||||
case 'Accept-Encoding':
|
||||
case 'Content-Length':
|
||||
// unsafe headers
|
||||
continue outer;
|
||||
}
|
||||
xhr.setRequestHeader(k, options.headers[k]);
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function getResponseHeaders(xhr: XMLHttpRequest): { [name: string]: string } {
|
||||
const headers: { [name: string]: string } = Object.create(null);
|
||||
for (const line of xhr.getAllResponseHeaders().split(/\r\n|\n|\r/g)) {
|
||||
if (line) {
|
||||
const idx = line.indexOf(':');
|
||||
headers[line.substr(0, idx).trim().toLowerCase()] = line.substr(idx + 1).trim();
|
||||
}
|
||||
}
|
||||
return headers;
|
||||
}
|
||||
@@ -3,8 +3,8 @@
|
||||
* Licensed under the MIT License. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import { IRequestOptions, IRequestContext, request, IRawRequestFunction } from 'vs/base/node/request';
|
||||
import { RequestService as NodeRequestService } from 'vs/platform/request/node/requestService';
|
||||
import { IRequestOptions, IRequestContext } from 'vs/platform/request/common/request';
|
||||
import { RequestService as NodeRequestService, IRawRequestFunction } from 'vs/platform/request/node/requestService';
|
||||
import { assign } from 'vs/base/common/objects';
|
||||
import { net } from 'electron';
|
||||
import { CancellationToken } from 'vs/base/common/cancellation';
|
||||
@@ -16,6 +16,6 @@ function getRawRequest(options: IRequestOptions): IRawRequestFunction {
|
||||
export class RequestService extends NodeRequestService {
|
||||
|
||||
request(options: IRequestOptions, token: CancellationToken): Promise<IRequestContext> {
|
||||
return super.request(options, token, options => request(assign({}, options || {}, { getRawRequest }), token));
|
||||
return super.request(assign({}, options || {}, { getRawRequest }), token);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5,7 +5,8 @@
|
||||
|
||||
import { Url, parse as parseUrl } from 'url';
|
||||
import { isBoolean } from 'vs/base/common/types';
|
||||
import { Agent } from './request';
|
||||
|
||||
export type Agent = any;
|
||||
|
||||
function getSystemProxyURI(requestURL: Url): string | null {
|
||||
if (requestURL.protocol === 'http:') {
|
||||
@@ -3,14 +3,31 @@
|
||||
* Licensed under the MIT License. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import * as https from 'https';
|
||||
import * as http from 'http';
|
||||
import { Stream } from 'stream';
|
||||
import { createGunzip } from 'zlib';
|
||||
import { parse as parseUrl } from 'url';
|
||||
import { Disposable } from 'vs/base/common/lifecycle';
|
||||
import { assign } from 'vs/base/common/objects';
|
||||
import { IRequestOptions, IRequestContext, IRequestFunction, request } from 'vs/base/node/request';
|
||||
import { getProxyAgent } from 'vs/base/node/proxy';
|
||||
import { IRequestService, IHTTPConfiguration } from 'vs/platform/request/node/request';
|
||||
import { isBoolean, isNumber } from 'vs/base/common/types';
|
||||
import { canceled } from 'vs/base/common/errors';
|
||||
import { CancellationToken } from 'vs/base/common/cancellation';
|
||||
import { IRequestOptions, IRequestContext, IRequestService, IHTTPConfiguration } from 'vs/platform/request/common/request';
|
||||
import { getProxyAgent, Agent } from 'vs/platform/request/node/proxy';
|
||||
import { IConfigurationService } from 'vs/platform/configuration/common/configuration';
|
||||
import { ILogService } from 'vs/platform/log/common/log';
|
||||
import { CancellationToken } from 'vs/base/common/cancellation';
|
||||
import { toVSBufferReadableStream } from 'vs/base/common/buffer';
|
||||
|
||||
export interface IRawRequestFunction {
|
||||
(options: http.RequestOptions, callback?: (res: http.IncomingMessage) => void): http.ClientRequest;
|
||||
}
|
||||
|
||||
export interface NodeRequestOptions extends IRequestOptions {
|
||||
agent?: Agent;
|
||||
strictSSL?: boolean;
|
||||
getRawRequest?(options: IRequestOptions): IRawRequestFunction;
|
||||
}
|
||||
|
||||
/**
|
||||
* This service exposes the `request` API, while using the global
|
||||
@@ -39,21 +56,91 @@ export class RequestService extends Disposable implements IRequestService {
|
||||
this.authorization = config.http && config.http.proxyAuthorization;
|
||||
}
|
||||
|
||||
request(options: IRequestOptions, token: CancellationToken, requestFn: IRequestFunction = request): Promise<IRequestContext> {
|
||||
async request(options: NodeRequestOptions, token: CancellationToken): Promise<IRequestContext> {
|
||||
this.logService.trace('RequestService#request', options.url);
|
||||
|
||||
const { proxyUrl, strictSSL } = this;
|
||||
const agentPromise = options.agent ? Promise.resolve(options.agent) : Promise.resolve(getProxyAgent(options.url || '', { proxyUrl, strictSSL }));
|
||||
const agent = options.agent ? options.agent : await getProxyAgent(options.url || '', { proxyUrl, strictSSL });
|
||||
|
||||
return agentPromise.then(agent => {
|
||||
options.agent = agent;
|
||||
options.strictSSL = strictSSL;
|
||||
options.agent = agent;
|
||||
options.strictSSL = strictSSL;
|
||||
|
||||
if (this.authorization) {
|
||||
options.headers = assign(options.headers || {}, { 'Proxy-Authorization': this.authorization });
|
||||
if (this.authorization) {
|
||||
options.headers = assign(options.headers || {}, { 'Proxy-Authorization': this.authorization });
|
||||
}
|
||||
|
||||
return this._request(options, token);
|
||||
}
|
||||
|
||||
private async getNodeRequest(options: IRequestOptions): Promise<IRawRequestFunction> {
|
||||
const endpoint = parseUrl(options.url!);
|
||||
const module = endpoint.protocol === 'https:' ? await import('https') : await import('http');
|
||||
return module.request;
|
||||
}
|
||||
|
||||
private _request(options: NodeRequestOptions, token: CancellationToken): Promise<IRequestContext> {
|
||||
|
||||
return new Promise<IRequestContext>(async (c, e) => {
|
||||
let req: http.ClientRequest;
|
||||
|
||||
const endpoint = parseUrl(options.url!);
|
||||
const rawRequest = options.getRawRequest
|
||||
? options.getRawRequest(options)
|
||||
: await this.getNodeRequest(options);
|
||||
|
||||
const opts: https.RequestOptions = {
|
||||
hostname: endpoint.hostname,
|
||||
port: endpoint.port ? parseInt(endpoint.port) : (endpoint.protocol === 'https:' ? 443 : 80),
|
||||
protocol: endpoint.protocol,
|
||||
path: endpoint.path,
|
||||
method: options.type || 'GET',
|
||||
headers: options.headers,
|
||||
agent: options.agent,
|
||||
rejectUnauthorized: isBoolean(options.strictSSL) ? options.strictSSL : true
|
||||
};
|
||||
|
||||
if (options.user && options.password) {
|
||||
opts.auth = options.user + ':' + options.password;
|
||||
}
|
||||
|
||||
return requestFn(options, token);
|
||||
req = rawRequest(opts, (res: http.IncomingMessage) => {
|
||||
const followRedirects: number = isNumber(options.followRedirects) ? options.followRedirects : 3;
|
||||
if (res.statusCode && res.statusCode >= 300 && res.statusCode < 400 && followRedirects > 0 && res.headers['location']) {
|
||||
this._request(assign({}, options, {
|
||||
url: res.headers['location'],
|
||||
followRedirects: followRedirects - 1
|
||||
}), token).then(c, e);
|
||||
} else {
|
||||
let stream: Stream = res;
|
||||
|
||||
if (res.headers['content-encoding'] === 'gzip') {
|
||||
stream = stream.pipe(createGunzip());
|
||||
}
|
||||
|
||||
c({ res, stream: toVSBufferReadableStream(stream) } as IRequestContext);
|
||||
}
|
||||
});
|
||||
|
||||
req.on('error', e);
|
||||
|
||||
if (options.timeout) {
|
||||
req.setTimeout(options.timeout);
|
||||
}
|
||||
|
||||
if (options.data) {
|
||||
if (typeof options.data === 'string') {
|
||||
req.write(options.data);
|
||||
}
|
||||
}
|
||||
|
||||
req.end();
|
||||
|
||||
token.onCancellationRequested(() => {
|
||||
req.abort();
|
||||
e(canceled());
|
||||
});
|
||||
});
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -11,7 +11,7 @@ import product from 'vs/platform/product/node/product';
|
||||
import { IUpdateService, State, StateType, AvailableForDownload, UpdateType } from 'vs/platform/update/common/update';
|
||||
import { IEnvironmentService } from 'vs/platform/environment/common/environment';
|
||||
import { ILogService } from 'vs/platform/log/common/log';
|
||||
import { IRequestService } from 'vs/platform/request/node/request';
|
||||
import { IRequestService } from 'vs/platform/request/common/request';
|
||||
import { CancellationToken } from 'vs/base/common/cancellation';
|
||||
|
||||
export function createUpdateURL(platform: string, quality: string): string {
|
||||
|
||||
@@ -14,7 +14,7 @@ import { ITelemetryService } from 'vs/platform/telemetry/common/telemetry';
|
||||
import { IEnvironmentService } from 'vs/platform/environment/common/environment';
|
||||
import { ILogService } from 'vs/platform/log/common/log';
|
||||
import { AbstractUpdateService, createUpdateURL } from 'vs/platform/update/electron-main/abstractUpdateService';
|
||||
import { IRequestService } from 'vs/platform/request/node/request';
|
||||
import { IRequestService } from 'vs/platform/request/common/request';
|
||||
|
||||
export class DarwinUpdateService extends AbstractUpdateService {
|
||||
|
||||
|
||||
@@ -6,13 +6,12 @@
|
||||
import product from 'vs/platform/product/node/product';
|
||||
import { IConfigurationService } from 'vs/platform/configuration/common/configuration';
|
||||
import { ILifecycleService } from 'vs/platform/lifecycle/electron-main/lifecycleMain';
|
||||
import { IRequestService } from 'vs/platform/request/node/request';
|
||||
import { State, IUpdate, AvailableForDownload, UpdateType } from 'vs/platform/update/common/update';
|
||||
import { ITelemetryService } from 'vs/platform/telemetry/common/telemetry';
|
||||
import { IEnvironmentService } from 'vs/platform/environment/common/environment';
|
||||
import { ILogService } from 'vs/platform/log/common/log';
|
||||
import { createUpdateURL, AbstractUpdateService } from 'vs/platform/update/electron-main/abstractUpdateService';
|
||||
import { asJson } from 'vs/base/node/request';
|
||||
import { IRequestService, asJson } from 'vs/platform/request/common/request';
|
||||
import { shell } from 'electron';
|
||||
import { CancellationToken } from 'vs/base/common/cancellation';
|
||||
|
||||
|
||||
@@ -9,20 +9,21 @@ import * as pfs from 'vs/base/node/pfs';
|
||||
import { memoize } from 'vs/base/common/decorators';
|
||||
import { IConfigurationService } from 'vs/platform/configuration/common/configuration';
|
||||
import { ILifecycleService } from 'vs/platform/lifecycle/electron-main/lifecycleMain';
|
||||
import { IRequestService } from 'vs/platform/request/node/request';
|
||||
import product from 'vs/platform/product/node/product';
|
||||
import { State, IUpdate, StateType, AvailableForDownload, UpdateType } from 'vs/platform/update/common/update';
|
||||
import { ITelemetryService } from 'vs/platform/telemetry/common/telemetry';
|
||||
import { IEnvironmentService } from 'vs/platform/environment/common/environment';
|
||||
import { ILogService } from 'vs/platform/log/common/log';
|
||||
import { createUpdateURL, AbstractUpdateService } from 'vs/platform/update/electron-main/abstractUpdateService';
|
||||
import { download, asJson } from 'vs/base/node/request';
|
||||
import { IRequestService, asJson } from 'vs/platform/request/common/request';
|
||||
import { checksum } from 'vs/base/node/crypto';
|
||||
import { tmpdir } from 'os';
|
||||
import { spawn } from 'child_process';
|
||||
import { shell } from 'electron';
|
||||
import { CancellationToken } from 'vs/base/common/cancellation';
|
||||
import { timeout } from 'vs/base/common/async';
|
||||
import { IFileService } from 'vs/platform/files/common/files';
|
||||
import { URI } from 'vs/base/common/uri';
|
||||
|
||||
async function pollUntil(fn: () => boolean, millis = 1000): Promise<void> {
|
||||
while (!fn()) {
|
||||
@@ -64,7 +65,8 @@ export class Win32UpdateService extends AbstractUpdateService {
|
||||
@ITelemetryService private readonly telemetryService: ITelemetryService,
|
||||
@IEnvironmentService environmentService: IEnvironmentService,
|
||||
@IRequestService requestService: IRequestService,
|
||||
@ILogService logService: ILogService
|
||||
@ILogService logService: ILogService,
|
||||
@IFileService private readonly fileService: IFileService
|
||||
) {
|
||||
super(lifecycleService, configurationService, environmentService, requestService, logService);
|
||||
|
||||
@@ -142,7 +144,7 @@ export class Win32UpdateService extends AbstractUpdateService {
|
||||
const downloadPath = `${updatePackagePath}.tmp`;
|
||||
|
||||
return this.requestService.request({ url }, CancellationToken.None)
|
||||
.then(context => download(downloadPath, context))
|
||||
.then(context => this.fileService.writeFile(URI.file(downloadPath), context.stream))
|
||||
.then(hash ? () => checksum(downloadPath, update.hash) : () => undefined)
|
||||
.then(() => pfs.rename(downloadPath, updatePackagePath))
|
||||
.then(() => updatePackagePath);
|
||||
|
||||
Vendored
+2
-1
@@ -1031,7 +1031,8 @@ declare module 'vscode' {
|
||||
|
||||
/**
|
||||
* An event that when fired will exit the process with an exit code, this will behave the
|
||||
* same for a virtual process as when a regular process exits with an exit code.
|
||||
* same for a virtual process as when a regular process exits with an exit code. Note that
|
||||
* exit codes must be positive numbers, when negative the exit code will be forced to `1`.
|
||||
*
|
||||
* **Example:** Exit with an exit code of `0` if the y key is pressed, otherwise `1`.
|
||||
* ```typescript
|
||||
|
||||
@@ -788,7 +788,10 @@ class ExtHostVirtualProcess implements ITerminalChildProcess {
|
||||
// Attach the real listeners
|
||||
this._virtualProcess.onDidWrite(e => this._onProcessData.fire(e));
|
||||
if (this._virtualProcess.onDidExit) {
|
||||
this._virtualProcess.onDidExit(e => this._onProcessExit.fire(e));
|
||||
this._virtualProcess.onDidExit(e => {
|
||||
// Ensure only positive exit codes are returned
|
||||
this._onProcessExit.fire(e >= 0 ? e : 1);
|
||||
});
|
||||
}
|
||||
if (this._virtualProcess.onDidOverrideDimensions) {
|
||||
this._virtualProcess.onDidOverrideDimensions(e => this._onProcessOverrideDimensions.fire(e ? { cols: e.columns, rows: e.rows } : e));
|
||||
|
||||
@@ -364,27 +364,6 @@ export class SimpleMultiExtensionsManagementService implements IExtensionManagem
|
||||
|
||||
//#endregion
|
||||
|
||||
//#region Request
|
||||
|
||||
export const IRequestService = createDecorator<IRequestService>('requestService');
|
||||
|
||||
export interface IRequestService {
|
||||
_serviceBrand: any;
|
||||
|
||||
request(options: any, token: CancellationToken): Promise<object>;
|
||||
}
|
||||
|
||||
export class SimpleRequestService implements IRequestService {
|
||||
|
||||
_serviceBrand: any;
|
||||
|
||||
request(options: any, token: CancellationToken): Promise<object> {
|
||||
return Promise.resolve(Object.create(null));
|
||||
}
|
||||
}
|
||||
|
||||
//#endregion
|
||||
|
||||
//#region Telemetry
|
||||
|
||||
export class SimpleTelemetryService implements ITelemetryService {
|
||||
|
||||
@@ -12,11 +12,10 @@ import { ITelemetryService } from 'vs/platform/telemetry/common/telemetry';
|
||||
import { ILifecycleService, LifecyclePhase } from 'vs/platform/lifecycle/common/lifecycle';
|
||||
import { IConfigurationService } from 'vs/platform/configuration/common/configuration';
|
||||
import { IExtensionManagementService } from 'vs/platform/extensionManagement/common/extensionManagement';
|
||||
import { IRequestService } from 'vs/platform/request/node/request';
|
||||
import { language } from 'vs/base/common/platform';
|
||||
import { Disposable, IDisposable, dispose } from 'vs/base/common/lifecycle';
|
||||
import { match } from 'vs/base/common/glob';
|
||||
import { asJson } from 'vs/base/node/request';
|
||||
import { IRequestService, asJson } from 'vs/platform/request/common/request';
|
||||
import { Emitter, Event } from 'vs/base/common/event';
|
||||
import { ITextFileService, StateChange } from 'vs/workbench/services/textfile/common/textfiles';
|
||||
import { WorkspaceStats } from 'vs/workbench/contrib/stats/electron-browser/workspaceStats';
|
||||
|
||||
@@ -32,8 +32,7 @@ import { IEnvironmentService } from 'vs/platform/environment/common/environment'
|
||||
import { guessMimeTypes, MIME_UNKNOWN } from 'vs/base/common/mime';
|
||||
import { IExtensionService } from 'vs/workbench/services/extensions/common/extensions';
|
||||
import { getHashedRemotesFromUri } from 'vs/workbench/contrib/stats/electron-browser/workspaceStats';
|
||||
import { IRequestService } from 'vs/platform/request/node/request';
|
||||
import { asJson } from 'vs/base/node/request';
|
||||
import { IRequestService, asJson } from 'vs/platform/request/common/request';
|
||||
import { isNumber } from 'vs/base/common/types';
|
||||
import { IViewletService } from 'vs/workbench/services/viewlet/browser/viewlet';
|
||||
import { INotificationService } from 'vs/platform/notification/common/notification';
|
||||
|
||||
@@ -11,9 +11,8 @@ import { URI } from 'vs/base/common/uri';
|
||||
import { IExtensionHostProfile } from 'vs/workbench/services/extensions/common/extensions';
|
||||
import { IInstantiationService, ServicesAccessor } from 'vs/platform/instantiation/common/instantiation';
|
||||
import { localize } from 'vs/nls';
|
||||
import { IRequestService } from 'vs/platform/request/node/request';
|
||||
import { CancellationToken } from 'vs/base/common/cancellation';
|
||||
import { asText } from 'vs/base/node/request';
|
||||
import { IRequestService, asText } from 'vs/platform/request/common/request';
|
||||
import { join } from 'vs/base/common/path';
|
||||
import { onUnexpectedError } from 'vs/base/common/errors';
|
||||
import { IDialogService } from 'vs/platform/dialogs/common/dialogs';
|
||||
|
||||
@@ -42,15 +42,37 @@ CommandsRegistry.registerCommand({
|
||||
// Always use integrated terminal when using a remote
|
||||
const useIntegratedTerminal = remoteAgentService.getConnection() || configurationService.getValue<IExternalTerminalConfiguration>().terminal.explorerKind === 'integrated';
|
||||
if (useIntegratedTerminal) {
|
||||
distinct(targets.map(({ stat }) => stat!.isDirectory ? stat!.resource.path : paths.dirname(stat!.resource.path))).map(cwd => {
|
||||
|
||||
|
||||
// TODO: Use uri for cwd in createterminal
|
||||
|
||||
|
||||
const opened: { [path: string]: boolean } = {};
|
||||
targets.map(({ stat }) => {
|
||||
const resource = stat!.resource;
|
||||
if (stat!.isDirectory) {
|
||||
return resource;
|
||||
}
|
||||
return URI.from({
|
||||
scheme: resource.scheme,
|
||||
authority: resource.authority,
|
||||
fragment: resource.fragment,
|
||||
query: resource.query,
|
||||
path: paths.dirname(resource.path)
|
||||
});
|
||||
}).forEach(cwd => {
|
||||
if (opened[cwd.path]) {
|
||||
return;
|
||||
}
|
||||
opened[cwd.path] = true;
|
||||
const instance = integratedTerminalService.createTerminal({ cwd });
|
||||
if (instance && (resources.length === 1 || !resource || cwd === resource.path || cwd === paths.dirname(resource.path))) {
|
||||
if (instance && (resources.length === 1 || !resource || cwd.path === resource.path || cwd.path === paths.dirname(resource.path))) {
|
||||
integratedTerminalService.setActiveInstance(instance);
|
||||
integratedTerminalService.showPanel(true);
|
||||
}
|
||||
});
|
||||
} else {
|
||||
distinct(targets.map(({ stat }) => stat!.isDirectory ? stat!.resource.fsPath : paths.dirname(stat!.resource.fsPath))).map(cwd => {
|
||||
distinct(targets.map(({ stat }) => stat!.isDirectory ? stat!.resource.fsPath : paths.dirname(stat!.resource.fsPath))).forEach(cwd => {
|
||||
terminalService!.openTerminal(cwd);
|
||||
});
|
||||
}
|
||||
|
||||
@@ -8,8 +8,7 @@ import { top } from 'vs/base/common/arrays';
|
||||
import * as strings from 'vs/base/common/strings';
|
||||
import { IEnvironmentService } from 'vs/platform/environment/common/environment';
|
||||
import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation';
|
||||
import { IRequestService } from 'vs/platform/request/node/request';
|
||||
import { asJson } from 'vs/base/node/request';
|
||||
import { IRequestService, asJson } from 'vs/platform/request/common/request';
|
||||
import { IExtensionManagementService, ILocalExtension, IExtensionEnablementService } from 'vs/platform/extensionManagement/common/extensionManagement';
|
||||
import { ILogService } from 'vs/platform/log/common/log';
|
||||
import { IPreferencesSearchService, ISearchProvider, IWorkbenchSettingsConfiguration } from 'vs/workbench/contrib/preferences/common/preferences';
|
||||
|
||||
@@ -7,7 +7,6 @@ import { onUnexpectedError } from 'vs/base/common/errors';
|
||||
import * as marked from 'vs/base/common/marked/marked';
|
||||
import { OS } from 'vs/base/common/platform';
|
||||
import { URI } from 'vs/base/common/uri';
|
||||
import { asText } from 'vs/base/node/request';
|
||||
import { TokenizationRegistry, ITokenizationSupport } from 'vs/editor/common/modes';
|
||||
import { generateTokensCSSForColorMap } from 'vs/editor/common/modes/supports/tokenization';
|
||||
import { tokenizeToString } from 'vs/editor/common/modes/textToHtmlTokenizer';
|
||||
@@ -17,7 +16,7 @@ import { IEnvironmentService } from 'vs/platform/environment/common/environment'
|
||||
import { ServicesAccessor } from 'vs/platform/instantiation/common/instantiation';
|
||||
import { IKeybindingService } from 'vs/platform/keybinding/common/keybinding';
|
||||
import { IOpenerService } from 'vs/platform/opener/common/opener';
|
||||
import { IRequestService } from 'vs/platform/request/node/request';
|
||||
import { IRequestService, asText } from 'vs/platform/request/common/request';
|
||||
import { ITelemetryService } from 'vs/platform/telemetry/common/telemetry';
|
||||
import { addGAParameters } from 'vs/platform/telemetry/node/telemetryNodeUtils';
|
||||
import { IWebviewEditorService } from 'vs/workbench/contrib/webview/browser/webviewEditorService';
|
||||
|
||||
@@ -12,12 +12,15 @@ import { debugExceptionWidgetBackground } from 'vs/workbench/contrib/debug/brows
|
||||
import { debugToolBarBackground } from 'vs/workbench/contrib/debug/browser/debugToolBar';
|
||||
import { buttonBackground } from 'vs/workbench/contrib/welcome/page/browser/welcomePage';
|
||||
import { embeddedEditorBackground } from 'vs/workbench/contrib/welcome/walkThrough/browser/walkThroughPart';
|
||||
import { request, asText } from 'vs/base/node/request';
|
||||
import { asText } from 'vs/platform/request/common/request';
|
||||
import * as pfs from 'vs/base/node/pfs';
|
||||
import * as path from 'vs/base/common/path';
|
||||
import * as assert from 'assert';
|
||||
import { getPathFromAmdModule } from 'vs/base/common/amd';
|
||||
import { CancellationToken } from 'vs/base/common/cancellation';
|
||||
import { RequestService } from 'vs/platform/request/node/requestService';
|
||||
import { TestConfigurationService } from 'vs/platform/configuration/test/common/testConfigurationService';
|
||||
import { NullLogService } from 'vs/platform/log/common/log';
|
||||
|
||||
|
||||
interface ColorInfo {
|
||||
@@ -40,7 +43,7 @@ export const experimental: string[] = []; // 'settings.modifiedItemForeground',
|
||||
suite('Color Registry', function () {
|
||||
|
||||
test('all colors documented', async function () {
|
||||
const reqContext = await request({ url: 'https://raw.githubusercontent.com/Microsoft/vscode-docs/vnext/docs/getstarted/theme-color-reference.md' }, CancellationToken.None);
|
||||
const reqContext = await new RequestService(new TestConfigurationService(), new NullLogService()).request({ url: 'https://raw.githubusercontent.com/Microsoft/vscode-docs/vnext/docs/getstarted/theme-color-reference.md' }, CancellationToken.None);
|
||||
const content = (await asText(reqContext))!;
|
||||
|
||||
const expression = /\-\s*\`([\w\.]+)\`: (.*)/g;
|
||||
|
||||
@@ -68,8 +68,8 @@ import { IExtensionGalleryService } from 'vs/platform/extensionManagement/common
|
||||
import { IContextViewService } from 'vs/platform/contextview/browser/contextView';
|
||||
import { ContextViewService } from 'vs/platform/contextview/browser/contextViewService';
|
||||
import { ExtensionGalleryService } from 'vs/platform/extensionManagement/node/extensionGalleryService';
|
||||
import { IRequestService } from 'vs/platform/request/node/request';
|
||||
import { RequestService } from 'vs/platform/request/electron-browser/requestService';
|
||||
import { IRequestService } from 'vs/platform/request/common/request';
|
||||
import { RequestService } from 'vs/platform/request/browser/requestService';
|
||||
import { LifecycleService } from 'vs/platform/lifecycle/electron-browser/lifecycleService';
|
||||
import { ILifecycleService } from 'vs/platform/lifecycle/common/lifecycle';
|
||||
import { ILocalizationsService } from 'vs/platform/localizations/common/localizations';
|
||||
|
||||
@@ -66,8 +66,8 @@ import { BrowserAccessibilityService } from 'vs/platform/accessibility/common/ac
|
||||
// import { IExtensionGalleryService } from 'vs/platform/extensionManagement/common/extensionManagement';
|
||||
import { ContextViewService } from 'vs/platform/contextview/browser/contextViewService';
|
||||
// import { ExtensionGalleryService } from 'vs/platform/extensionManagement/node/extensionGalleryService';
|
||||
// import { IRequestService } from 'vs/platform/request/node/request';
|
||||
// import { RequestService } from 'vs/platform/request/electron-browser/requestService';
|
||||
import { IRequestService } from 'vs/platform/request/common/request';
|
||||
import { RequestService } from 'vs/platform/request/browser/requestService';
|
||||
import { BrowserLifecycleService } from 'vs/platform/lifecycle/browser/lifecycleService';
|
||||
import { ILifecycleService } from 'vs/platform/lifecycle/common/lifecycle';
|
||||
import { IDialogService } from 'vs/platform/dialogs/common/dialogs';
|
||||
@@ -156,7 +156,7 @@ registerSingleton(ITextResourceConfigurationService, TextResourceConfigurationSe
|
||||
registerSingleton(IAccessibilityService, BrowserAccessibilityService, true);
|
||||
registerSingleton(IContextViewService, ContextViewService, true);
|
||||
// registerSingleton(IExtensionGalleryService, ExtensionGalleryService, true);
|
||||
// registerSingleton(IRequestService, RequestService, true);
|
||||
registerSingleton(IRequestService, RequestService, true);
|
||||
registerSingleton(ILifecycleService, BrowserLifecycleService);
|
||||
// registerSingleton(ILocalizationsService, LocalizationsService);
|
||||
// registerSingleton(ISharedProcessService, SharedProcessService, true);
|
||||
|
||||
@@ -9822,12 +9822,12 @@ windows-mutex@0.2.1:
|
||||
bindings "^1.2.1"
|
||||
nan "^2.10.0"
|
||||
|
||||
windows-process-tree@0.2.3:
|
||||
version "0.2.3"
|
||||
resolved "https://registry.yarnpkg.com/windows-process-tree/-/windows-process-tree-0.2.3.tgz#6b781f0a320e8a0d6434c9399add4389c709cf6e"
|
||||
integrity sha512-SzPJSubVVsToz1g5lr2P+4mQT70gvJ9u/nlnpfkOeQcAhOuhKz5DiO1TARgR0OnVsv21LPzxbA2m/4JQkGh1wA==
|
||||
windows-process-tree@0.2.4:
|
||||
version "0.2.4"
|
||||
resolved "https://registry.yarnpkg.com/windows-process-tree/-/windows-process-tree-0.2.4.tgz#747af587b54cc6c996f2be0836cc8a8fd0dc038f"
|
||||
integrity sha512-9gag9AHm3Iin/4YC1EwoIfZlqW/rG2eV7rJZ4Fy5NnAMGdewmnwsie5Rz+CJo2vSolqzzfw7hPeu3oOdniNejg==
|
||||
dependencies:
|
||||
nan "^2.10.0"
|
||||
nan "^2.13.2"
|
||||
|
||||
wordwrap@0.0.2:
|
||||
version "0.0.2"
|
||||
@@ -9961,10 +9961,10 @@ xterm-addon-web-links@0.1.0-beta10:
|
||||
resolved "https://registry.yarnpkg.com/xterm-addon-web-links/-/xterm-addon-web-links-0.1.0-beta10.tgz#610fa9773a2a5ccd41c1c83ba0e2dd2c9eb66a23"
|
||||
integrity sha512-xfpjy0V6bB4BR44qIgZQPoCMVakxb65gMscPkHpO//QxvUxKzabV3dxOsIbeZRFkUGsWTFlvz2OoaBLoNtv5gg==
|
||||
|
||||
xterm@3.15.0-beta70:
|
||||
version "3.15.0-beta70"
|
||||
resolved "https://registry.yarnpkg.com/xterm/-/xterm-3.15.0-beta70.tgz#3e81f32e8cd7147f9a0764fbe2599c277c697a74"
|
||||
integrity sha512-VXhEbWwaxrs9Ac2KuTCmGX7Ktd0V+rVF5sdjXBsq/KBCtnUdwNzKnEjamNPsoNTDUv9y93INEbq82X7iBs1Gwg==
|
||||
xterm@3.15.0-beta71:
|
||||
version "3.15.0-beta71"
|
||||
resolved "https://registry.yarnpkg.com/xterm/-/xterm-3.15.0-beta71.tgz#2728c9800ca3b08423e835e9504bd1f4b5de6253"
|
||||
integrity sha512-8M/cLaxZ+iDopRxLPdPfKuDGaNNyYTdCeytdxjMSH0N7dZzbx6fbaEygQdCrV5pO9cGnT92MefSjVPGRXRiBLA==
|
||||
|
||||
y18n@^3.2.1:
|
||||
version "3.2.1"
|
||||
|
||||
Reference in New Issue
Block a user